merge 'simpleprocess-fast-export-test' into dev

This commit is contained in:
Alberto Griggio 2017-03-28 15:02:10 +02:00
commit 518d51e839
13 changed files with 1588 additions and 1251 deletions

View File

@ -89,6 +89,11 @@ EXPORT_BYPASS_SHARPENEDGE;Bypass Edge Sharpening
EXPORT_BYPASS_SHARPENING;Bypass Sharpening EXPORT_BYPASS_SHARPENING;Bypass Sharpening
EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast
EXPORT_BYPASS_SH_HQ;Bypass Sharp Mask Shadows/Highlights EXPORT_BYPASS_SH_HQ;Bypass Sharp Mask Shadows/Highlights
EXPORT_PIPELINE;Processing pipeline
EXPORT_BYPASS;Processing steps to bypass
EXPORT_USE_NORMAL_PIPELINE;Standard (bypass some steps, resize at the end)
EXPORT_USE_FAST_PIPELINE;Dedicated (full processing on resized image)
EXPORT_USE_FAST_PIPELINE_TIP;Use a dedicated processing pipeline for images in Fast Export mode, that trades speed for quality. Resizing of the image is done as early as possible, instead of doing it at the end like in the normal pipeline. The speedup can be significant, but be prepared to see artifacts and a general degradation of output quality.
EXPORT_FASTEXPORTOPTIONS;<b>Fast Export Options</b> EXPORT_FASTEXPORTOPTIONS;<b>Fast Export Options</b>
EXPORT_INSTRUCTIONS;Fast Export options provide overrides to bypass time and resource consuming development settings and to run queue processing using the fast export settings instead. This method is recommended for quicker generation of lower resolution images when speed is a priority or when resized output is desired for one or many images without making modifications to their saved development parameters. EXPORT_INSTRUCTIONS;Fast Export options provide overrides to bypass time and resource consuming development settings and to run queue processing using the fast export settings instead. This method is recommended for quicker generation of lower resolution images when speed is a priority or when resized output is desired for one or many images without making modifications to their saved development parameters.
EXPORT_MAXHEIGHT;Maximum height: EXPORT_MAXHEIGHT;Maximum height:

View File

@ -21,16 +21,16 @@
namespace rtengine namespace rtengine
{ {
ProcessingJob* ProcessingJob::create (const Glib::ustring& fname, bool isRaw, const procparams::ProcParams& pparams) ProcessingJob* ProcessingJob::create (const Glib::ustring& fname, bool isRaw, const procparams::ProcParams& pparams, bool fast)
{ {
return new ProcessingJobImpl (fname, isRaw, pparams); return new ProcessingJobImpl (fname, isRaw, pparams, fast);
} }
ProcessingJob* ProcessingJob::create (InitialImage* initialImage, const procparams::ProcParams& pparams) ProcessingJob* ProcessingJob::create (InitialImage* initialImage, const procparams::ProcParams& pparams, bool fast)
{ {
return new ProcessingJobImpl (initialImage, pparams); return new ProcessingJobImpl (initialImage, pparams, fast);
} }
void ProcessingJob::destroy (ProcessingJob* job) void ProcessingJob::destroy (ProcessingJob* job)

View File

@ -32,12 +32,13 @@ public:
bool isRaw; bool isRaw;
InitialImage* initialImage; InitialImage* initialImage;
procparams::ProcParams pparams; procparams::ProcParams pparams;
bool fast;
ProcessingJobImpl (const Glib::ustring& fn, bool iR, const procparams::ProcParams& pp) ProcessingJobImpl (const Glib::ustring& fn, bool iR, const procparams::ProcParams& pp, bool ff)
: fname(fn), isRaw(iR), initialImage(nullptr), pparams(pp) {} : fname(fn), isRaw(iR), initialImage(nullptr), pparams(pp), fast(ff) {}
ProcessingJobImpl (InitialImage* iImage, const procparams::ProcParams& pp) ProcessingJobImpl (InitialImage* iImage, const procparams::ProcParams& pp, bool ff)
: fname(""), isRaw(true), initialImage(iImage), pparams(pp) : fname(""), isRaw(true), initialImage(iImage), pparams(pp), fast(ff)
{ {
iImage->increaseRef(); iImage->increaseRef();
} }
@ -48,6 +49,8 @@ public:
initialImage->decreaseRef(); initialImage->decreaseRef();
} }
} }
bool fastPipeline() const { return fast; }
}; };
} }

View File

@ -471,6 +471,7 @@ class ProcessingJob
{ {
public: public:
virtual ~ProcessingJob() {}
/** Creates a processing job from a file name. This function always succeeds. It only stores the data into the ProcessingJob class, it does not load /** Creates a processing job from a file name. This function always succeeds. It only stores the data into the ProcessingJob class, it does not load
* the image thus it returns immediately. * the image thus it returns immediately.
@ -478,7 +479,7 @@ public:
* @param isRaw shall be true if it is a raw file * @param isRaw shall be true if it is a raw file
* @param pparams is a struct containing the processing parameters * @param pparams is a struct containing the processing parameters
* @return an object containing the data above. It can be passed to the functions that do the actual image processing. */ * @return an object containing the data above. It can be passed to the functions that do the actual image processing. */
static ProcessingJob* create (const Glib::ustring& fname, bool isRaw, const procparams::ProcParams& pparams); static ProcessingJob* create (const Glib::ustring& fname, bool isRaw, const procparams::ProcParams& pparams, bool fast=false);
/** Creates a processing job from a file name. This function always succeeds. It only stores the data into the ProcessingJob class, it does not load /** Creates a processing job from a file name. This function always succeeds. It only stores the data into the ProcessingJob class, it does not load
* the image thus it returns immediately. This function increases the reference count of the initialImage. If you decide not the process the image you * the image thus it returns immediately. This function increases the reference count of the initialImage. If you decide not the process the image you
@ -487,12 +488,14 @@ public:
* @param initialImage is a loaded and pre-processed initial image * @param initialImage is a loaded and pre-processed initial image
* @param pparams is a struct containing the processing parameters * @param pparams is a struct containing the processing parameters
* @return an object containing the data above. It can be passed to the functions that do the actual image processing. */ * @return an object containing the data above. It can be passed to the functions that do the actual image processing. */
static ProcessingJob* create (InitialImage* initialImage, const procparams::ProcParams& pparams); static ProcessingJob* create (InitialImage* initialImage, const procparams::ProcParams& pparams, bool fast=false);
/** Cancels and destroys a processing job. The reference count of the corresponding initialImage (if any) is decreased. After the call of this function the ProcessingJob instance /** Cancels and destroys a processing job. The reference count of the corresponding initialImage (if any) is decreased. After the call of this function the ProcessingJob instance
* gets invalid, you must not use it any more. Dont call this function while the job is being processed. * gets invalid, you must not use it any more. Dont call this function while the job is being processed.
* @param job is the job to destroy */ * @param job is the job to destroy */
static void destroy (ProcessingJob* job); static void destroy (ProcessingJob* job);
virtual bool fastPipeline() const = 0;
}; };
/** This function performs all the image processinf steps corresponding to the given ProcessingJob. It returns when it is ready, so it can be slow. /** This function performs all the image processinf steps corresponding to the given ProcessingJob. It returns when it is ready, so it can be slow.

View File

@ -35,36 +35,97 @@ namespace rtengine
{ {
extern const Settings* settings; extern const Settings* settings;
IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* pl, bool tunnelMetaData, bool flush) namespace {
template <typename T>
void adjust_radius(const T &default_param, double scale_factor, T &param)
{ {
const double delta = (param - default_param) * scale_factor;
param = default_param + delta;
}
class ImageProcessor {
public:
ImageProcessor(ProcessingJob* pjob, int& errorCode,
ProgressListener* pl, bool tunnelMetaData, bool flush):
job(static_cast<ProcessingJobImpl*>(pjob)),
errorCode(errorCode),
pl(pl),
tunnelMetaData(tunnelMetaData),
flush(flush),
// internal state
ii(nullptr),
imgsrc(nullptr),
fw(-1),
fh(-1),
pp(0, 0, 0, 0, 0)
{
}
Image16 *operator()()
{
if (!job->fast) {
return normal_pipeline();
} else {
return fast_pipeline();
}
}
private:
Image16 *normal_pipeline()
{
if (!stage_init()) {
return nullptr;
}
stage_denoise();
stage_transform();
return stage_finish();
}
Image16 *fast_pipeline()
{
if (!job->pparams.resize.enabled) {
return normal_pipeline();
}
pl = nullptr;
if (!stage_init()) {
return nullptr;
}
stage_transform();
stage_early_resize();
stage_denoise();
return stage_finish();
}
bool stage_init()
{
errorCode = 0; errorCode = 0;
ProcessingJobImpl* job = static_cast<ProcessingJobImpl*>(pjob);
if (pl) { if (pl) {
pl->setProgressStr ("PROGRESSBAR_PROCESSING"); pl->setProgressStr ("PROGRESSBAR_PROCESSING");
pl->setProgress (0.0); pl->setProgress (0.0);
} }
InitialImage* ii = job->initialImage; ii = job->initialImage;
if (!ii) { if (!ii) {
ii = InitialImage::load (job->fname, job->isRaw, &errorCode); ii = InitialImage::load (job->fname, job->isRaw, &errorCode);
if (errorCode) { if (errorCode) {
delete job; delete job;
return nullptr; return false; //return nullptr;
} }
} }
procparams::ProcParams& params = job->pparams; procparams::ProcParams& params = job->pparams;
// acquire image from imagesource // acquire image from imagesource
ImageSource* imgsrc = ii->getImageSource (); imgsrc = ii->getImageSource ();
int tr = getCoarseBitMask(params.coarse); tr = getCoarseBitMask(params.coarse);
int fw, fh;
imgsrc->getFullSize (fw, fh, tr); imgsrc->getFullSize (fw, fh, tr);
// check the crop params // check the crop params
@ -101,7 +162,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
ImProcFunctions ipf (&params, true); ImProcFunctions ipf (&params, true);
PreviewProps pp (0, 0, fw, fh, 1); pp = PreviewProps(0, 0, fw, fh, 1);
imgsrc->setCurrentFrame(params.raw.bayersensor.imageNum); imgsrc->setCurrentFrame(params.raw.bayersensor.imageNum);
imgsrc->preprocess( params.raw, params.lensProf, params.coarse, params.dirpyrDenoise.enabled); imgsrc->preprocess( params.raw, params.lensProf, params.coarse, params.dirpyrDenoise.enabled);
@ -154,7 +215,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
} }
// set the color temperature // set the color temperature
ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.equal, params.wb.method); currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.equal, params.wb.method);
if (params.wb.method == "Camera") { if (params.wb.method == "Camera") {
currWB = imgsrc->getWB (); currWB = imgsrc->getWB ();
@ -164,14 +225,10 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
currWB.update(rm, gm, bm, params.wb.equal, params.wb.tempBias); currWB.update(rm, gm, bm, params.wb.equal, params.wb.tempBias);
} }
NoiseCurve noiseLCurve; calclum = nullptr ;
NoiseCurve noiseCCurve;
Imagefloat *calclum = nullptr ;
params.dirpyrDenoise.getCurves(noiseLCurve, noiseCCurve); params.dirpyrDenoise.getCurves(noiseLCurve, noiseCCurve);
float autoNR = (float) settings->nrauto;// autoNR = (float) settings->nrauto;//
float autoNRmax = (float) settings->nrautomax;// autoNRmax = (float) settings->nrautomax;//
int tilesize;
int overlap;
if(settings->leveldnti == 0) { if(settings->leveldnti == 0) {
tilesize = 1024; tilesize = 1024;
@ -193,16 +250,16 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
nbtl = 9; nbtl = 9;
} }
float *ch_M = new float [nbtl];//allocate memory ch_M = new float [nbtl];//allocate memory
float *max_r = new float [nbtl]; max_r = new float [nbtl];
float *max_b = new float [nbtl]; max_b = new float [nbtl];
float *min_b = new float [9]; min_b = new float [9];
float *min_r = new float [9]; min_r = new float [9];
float *lumL = new float [nbtl]; lumL = new float [nbtl];
float *chromC = new float [nbtl]; chromC = new float [nbtl];
float *ry = new float [nbtl]; ry = new float [nbtl];
float *sk = new float [nbtl]; sk = new float [nbtl];
float *pcsk = new float [nbtl]; pcsk = new float [nbtl];
// printf("expert=%d\n",settings->leveldnautsimpl); // printf("expert=%d\n",settings->leveldnautsimpl);
if(settings->leveldnautsimpl == 1 && params.dirpyrDenoise.Cmethod == "PON") { if(settings->leveldnautsimpl == 1 && params.dirpyrDenoise.Cmethod == "PON") {
@ -246,13 +303,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
LUTf gamcurve(65536, 0); LUTf gamcurve(65536, 0);
float gam, gamthresh, gamslope; float gam, gamthresh, gamslope;
ipf.RGB_denoise_infoGamCurve(params.dirpyrDenoise, imgsrc->isRAW(), gamcurve, gam, gamthresh, gamslope); ipf.RGB_denoise_infoGamCurve(params.dirpyrDenoise, imgsrc->isRAW(), gamcurve, gam, gamthresh, gamslope);
#pragma omp parallel #pragma omp parallel
{ {
Imagefloat *origCropPart;//init auto noise Imagefloat *origCropPart;//init auto noise
origCropPart = new Imagefloat (crW, crH);//allocate memory origCropPart = new Imagefloat (crW, crH);//allocate memory
Imagefloat *provicalc = new Imagefloat ((crW + 1) / 2, (crH + 1) / 2); //for denoise curves Imagefloat *provicalc = new Imagefloat ((crW + 1) / 2, (crH + 1) / 2); //for denoise curves
int skipP = 1; int skipP = 1;
#pragma omp for schedule(dynamic) collapse(2) nowait #pragma omp for schedule(dynamic) collapse(2) nowait
for(int wcr = 0; wcr < numtiles_W; wcr++) { for(int wcr = 0; wcr < numtiles_W; wcr++) {
for(int hcr = 0; hcr < numtiles_H; hcr++) { for(int hcr = 0; hcr < numtiles_H; hcr++) {
@ -260,6 +317,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
int beg_tileH = hcr * tileHskip + tileHskip / 2.f - crH / 2.f; int beg_tileH = hcr * tileHskip + tileHskip / 2.f - crH / 2.f;
PreviewProps ppP (beg_tileW , beg_tileH, crW, crH, skipP); PreviewProps ppP (beg_tileW , beg_tileH, crW, crH, skipP);
imgsrc->getImage (currWB, tr, origCropPart, ppP, params.toneCurve, params.icm, params.raw ); imgsrc->getImage (currWB, tr, origCropPart, ppP, params.toneCurve, params.icm, params.raw );
//baseImg->getStdImage(currWB, tr, origCropPart, ppP, true, params.toneCurve);
// we only need image reduced to 1/4 here // we only need image reduced to 1/4 here
for(int ii = 0; ii < crH; ii += 2) { for(int ii = 0; ii < crH; ii += 2) {
@ -467,18 +525,20 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
coordH[0] = begH; coordH[0] = begH;
coordH[1] = fh / 2 - crH / 2; coordH[1] = fh / 2 - crH / 2;
coordH[2] = fh - crH - begH; coordH[2] = fh - crH - begH;
#pragma omp parallel #pragma omp parallel
{ {
Imagefloat *origCropPart;//init auto noise Imagefloat *origCropPart;//init auto noise
origCropPart = new Imagefloat (crW, crH);//allocate memory origCropPart = new Imagefloat (crW, crH);//allocate memory
Imagefloat *provicalc = new Imagefloat ((crW + 1) / 2, (crH + 1) / 2); //for denoise curves Imagefloat *provicalc = new Imagefloat ((crW + 1) / 2, (crH + 1) / 2); //for denoise curves
#pragma omp for schedule(dynamic) collapse(2) nowait #pragma omp for schedule(dynamic) collapse(2) nowait
for(int wcr = 0; wcr <= 2; wcr++) { for(int wcr = 0; wcr <= 2; wcr++) {
for(int hcr = 0; hcr <= 2; hcr++) { for(int hcr = 0; hcr <= 2; hcr++) {
PreviewProps ppP (coordW[wcr] , coordH[hcr], crW, crH, 1); PreviewProps ppP (coordW[wcr] , coordH[hcr], crW, crH, 1);
imgsrc->getImage (currWB, tr, origCropPart, ppP, params.toneCurve, params.icm, params.raw); imgsrc->getImage (currWB, tr, origCropPart, ppP, params.toneCurve, params.icm, params.raw);
//baseImg->getStdImage(currWB, tr, origCropPart, ppP, true, params.toneCurve);
// we only need image reduced to 1/4 here // we only need image reduced to 1/4 here
for(int ii = 0; ii < crH; ii += 2) { for(int ii = 0; ii < crH; ii += 2) {
@ -635,11 +695,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
//end evaluate noise //end evaluate noise
} }
baseImg = new Imagefloat (fw, fh);
Imagefloat* baseImg = new Imagefloat (fw, fh);
imgsrc->getImage (currWB, tr, baseImg, pp, params.toneCurve, params.icm, params.raw); imgsrc->getImage (currWB, tr, baseImg, pp, params.toneCurve, params.icm, params.raw);
if (pl) { if (pl) {
@ -648,12 +704,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
// LUTf Noisecurve (65536,0); // LUTf Noisecurve (65536,0);
//!!!// auto exposure!!! //!!!// auto exposure!!!
double expcomp = params.toneCurve.expcomp; expcomp = params.toneCurve.expcomp;
int bright = params.toneCurve.brightness; bright = params.toneCurve.brightness;
int contr = params.toneCurve.contrast; contr = params.toneCurve.contrast;
int black = params.toneCurve.black; black = params.toneCurve.black;
int hlcompr = params.toneCurve.hlcompr; hlcompr = params.toneCurve.hlcompr;
int hlcomprthresh = params.toneCurve.hlcomprthresh; hlcomprthresh = params.toneCurve.hlcomprthresh;
if (params.toneCurve.autoexp) { if (params.toneCurve.autoexp) {
LUTu aehist; LUTu aehist;
@ -670,6 +727,14 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
imgsrc->flushRGB(); imgsrc->flushRGB();
} }
return true;
}
void stage_denoise()
{
procparams::ProcParams& params = job->pparams;
ImProcFunctions ipf (&params, true);
// perform luma/chroma denoise // perform luma/chroma denoise
// CieImage *cieView; // CieImage *cieView;
// NoisCurve noiseLCurve; // NoisCurve noiseLCurve;
@ -693,7 +758,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
if (denoiseParams.enabled && (noiseLCurve || noiseCCurve )) { if (denoiseParams.enabled && (noiseLCurve || noiseCCurve )) {
// we only need image reduced to 1/4 here // we only need image reduced to 1/4 here
calclum = new Imagefloat ((fw + 1) / 2, (fh + 1) / 2); //for luminance denoise curve calclum = new Imagefloat ((fw + 1) / 2, (fh + 1) / 2); //for luminance denoise curve
#pragma omp parallel for #pragma omp parallel for
for(int ii = 0; ii < fh; ii += 2) { for(int ii = 0; ii < fh; ii += 2) {
for(int jj = 0; jj < fw; jj += 2) { for(int jj = 0; jj < fw; jj += 2) {
@ -727,11 +792,17 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
delete [] ry; delete [] ry;
delete [] sk; delete [] sk;
delete [] pcsk; delete [] pcsk;
}
void stage_transform()
{
procparams::ProcParams& params = job->pparams;
ImProcFunctions ipf (&params, true);
imgsrc->convertColorSpace(baseImg, params.icm, currWB); imgsrc->convertColorSpace(baseImg, params.icm, currWB);
// perform first analysis // perform first analysis
LUTu hist16 (65536); hist16 (65536);
ipf.firstAnalysis (baseImg, params, hist16); ipf.firstAnalysis (baseImg, params, hist16);
@ -743,7 +814,12 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
delete baseImg; delete baseImg;
baseImg = trImg; baseImg = trImg;
} }
}
Image16 *stage_finish()
{
procparams::ProcParams& params = job->pparams;
ImProcFunctions ipf (&params, true);
if (params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) { if (params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) {
const int W = baseImg->getWidth(); const int W = baseImg->getWidth();
@ -771,28 +847,15 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
// RGB processing // RGB processing
LUTf curve1 (65536); curve1(65536);
LUTf curve2 (65536); curve2(65536);
LUTf curve (65536, 0); curve(65536, 0);
LUTf satcurve (65536, 0); satcurve(65536, 0);
LUTf lhskcurve (65536, 0); lhskcurve(65536, 0);
LUTf lumacurve(32770, 0); // lumacurve[32768] and lumacurve[32769] will be set to 32768 and 32769 later to allow linear interpolation lumacurve(32770, 0); // lumacurve[32768] and lumacurve[32769] will be set to 32768 and 32769 later to allow linear interpolation
LUTf clcurve (65536, 0); clcurve(65536, 0);
LUTf clToningcurve; wavclCurve(65536, 0);
LUTf cl2Toningcurve;
LUTf wavclCurve (65536, 0);
LUTf rCurve;
LUTf gCurve;
LUTf bCurve;
LUTu dummy;
ToneCurve customToneCurve1, customToneCurve2;
ColorGradientCurve ctColorCurve;
OpacityCurve ctOpacityCurve;
ColorAppearance customColCurve1, customColCurve2, customColCurve3 ;
ToneCurve customToneCurvebw1;
ToneCurve customToneCurvebw2;
//if(params.blackwhite.enabled) params.toneCurve.hrenabled=false; //if(params.blackwhite.enabled) params.toneCurve.hrenabled=false;
CurveFactory::complexCurve (expcomp, black / 65535.0, hlcompr, hlcomprthresh, params.toneCurve.shcompr, bright, contr, CurveFactory::complexCurve (expcomp, black / 65535.0, hlcompr, hlcomprthresh, params.toneCurve.shcompr, bright, contr,
@ -825,7 +888,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
CurveFactory::curveToning(params.colorToning.cl2curve, cl2Toningcurve, 1); CurveFactory::curveToning(params.colorToning.cl2curve, cl2Toningcurve, 1);
} }
LabImage* labView = new LabImage (fw, fh); labView = new LabImage (fw, fh);
if(params.blackwhite.enabled) { if(params.blackwhite.enabled) {
CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 1); CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 1);
@ -905,13 +968,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
hist16.clear(); hist16.clear();
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel #pragma omp parallel
#endif #endif
{ {
LUTu hist16thr (hist16.getSize()); // one temporary lookup table per thread LUTu hist16thr (hist16.getSize()); // one temporary lookup table per thread
hist16thr.clear(); hist16thr.clear();
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp for schedule(static) nowait #pragma omp for schedule(static) nowait
#endif #endif
for (int i = 0; i < fh; i++) for (int i = 0; i < fh; i++)
@ -919,7 +982,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
hist16thr[(int)((labView->L[i][j]))]++; hist16thr[(int)((labView->L[i][j]))]++;
} }
#pragma omp critical #pragma omp critical
{ {
hist16 += hist16thr; hist16 += hist16thr;
} }
@ -932,7 +995,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
bool clcutili; bool clcutili;
CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, 1); CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, 1);
bool autili, butili, ccutili, cclutili; bool ccutili, cclutili;
CurveFactory::complexsgnCurve (autili, butili, ccutili, cclutili, params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve, CurveFactory::complexsgnCurve (autili, butili, ccutili, cclutili, params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve,
params.labCurve.lccurve, curve1, curve2, satcurve, lhskcurve, 1); params.labCurve.lccurve, curve1, curve2, satcurve, lhskcurve, 1);
@ -1276,6 +1339,185 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
hist16C.reset(); hist16C.reset();
*/ */
return readyImg; return readyImg;
}
void stage_early_resize()
{
procparams::ProcParams& params = job->pparams;
ImProcFunctions ipf (&params, true);
int imw, imh;
double scale_factor = ipf.resizeScale(&params, fw, fh, imw, imh);
std::unique_ptr<LabImage> tmplab(new LabImage(fw, fh));
ipf.rgb2lab(*baseImg, *tmplab, params.icm.working);
if (params.crop.enabled) {
int cx = params.crop.x;
int cy = params.crop.y;
int cw = params.crop.w;
int ch = params.crop.h;
std::unique_ptr<LabImage> cropped(new LabImage(cw, ch));
for(int row = 0; row < ch; row++) {
for(int col = 0; col < cw; col++) {
cropped->L[row][col] = tmplab->L[row + cy][col + cx];
cropped->a[row][col] = tmplab->a[row + cy][col + cx];
cropped->b[row][col] = tmplab->b[row + cy][col + cx];
}
}
tmplab = std::move(cropped);
}
assert(params.resize.enabled);
// resize image
{
std::unique_ptr<LabImage> resized(new LabImage(imw, imh));
ipf.Lanczos(tmplab.get(), resized.get(), scale_factor);
tmplab = std::move(resized);
}
adjust_procparams(scale_factor);
fw = imw;
fh = imh;
delete baseImg;
baseImg = new Imagefloat(fw, fh);
ipf.lab2rgb(*tmplab, *baseImg, params.icm.working);
}
void adjust_procparams(double scale_factor)
{
procparams::ProcParams &params = job->pparams;
procparams::ProcParams defaultparams;
params.resize.enabled = false;
params.crop.enabled = false;
if (params.prsharpening.enabled) {
params.sharpening = params.prsharpening;
} else {
adjust_radius(defaultparams.sharpening.radius, scale_factor,
params.sharpening.radius);
}
params.impulseDenoise.thresh *= scale_factor;
if (scale_factor < 0.5) {
params.impulseDenoise.enabled = false;
}
params.wavelet.strength *= scale_factor;
params.dirpyrDenoise.luma *= scale_factor;
//params.dirpyrDenoise.smethod = "shal";
for (auto &p : params.dirpyrDenoise.lcurve) {
p *= scale_factor;
}
params.epd.scale *= scale_factor;
//params.epd.edgeStopping *= scale_factor;
const double dirpyreq_scale = min(scale_factor * 1.5, 1.0);
for (int i = 0; i < 6; ++i) {
adjust_radius(defaultparams.dirpyrequalizer.mult[i], dirpyreq_scale,
params.dirpyrequalizer.mult[i]);
}
adjust_radius(defaultparams.defringe.radius, scale_factor,
params.defringe.radius);
adjust_radius(defaultparams.sh.radius, scale_factor, params.sh.radius);
if (params.raw.xtranssensor.method ==
procparams::RAWParams::XTransSensor::methodstring[
procparams::RAWParams::XTransSensor::threePass]) {
params.raw.xtranssensor.method =
procparams::RAWParams::XTransSensor::methodstring[
procparams::RAWParams::XTransSensor::onePass];
}
}
private:
ProcessingJobImpl* job;
int& errorCode;
ProgressListener* pl;
bool tunnelMetaData;
bool flush;
// internal state
InitialImage *ii;
ImageSource *imgsrc;
int fw;
int fh;
int tr;
PreviewProps pp;
NoiseCurve noiseLCurve;
NoiseCurve noiseCCurve;
Imagefloat *calclum;
float autoNR;
float autoNRmax;
int tilesize;
int overlap;
float *ch_M;
float *max_r;
float *max_b;
float *min_b;
float *min_r;
float *lumL;
float *chromC;
float *ry;
float *sk;
float *pcsk;
double expcomp;
int bright;
int contr;
int black;
int hlcompr;
int hlcomprthresh;
ColorTemp currWB;
Imagefloat *baseImg;
LabImage* labView;
LUTu hist16;
LUTf curve1;
LUTf curve2;
LUTf curve;
LUTf satcurve;
LUTf lhskcurve;
LUTf lumacurve;
LUTf clcurve;
LUTf clToningcurve;
LUTf cl2Toningcurve;
LUTf wavclCurve;
LUTf rCurve;
LUTf gCurve;
LUTf bCurve;
LUTu dummy;
ToneCurve customToneCurve1, customToneCurve2;
ColorGradientCurve ctColorCurve;
OpacityCurve ctOpacityCurve;
ColorAppearance customColCurve1, customColCurve2, customColCurve3 ;
ToneCurve customToneCurvebw1;
ToneCurve customToneCurvebw2;
bool autili, butili;
};
} // namespace
IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* pl, bool tunnelMetaData, bool flush)
{
ImageProcessor proc(pjob, errorCode, pl, tunnelMetaData, flush);
return proc();
} }
void batchProcessingThread (ProcessingJob* job, BatchProcessingListener* bpl, bool tunnelMetaData) void batchProcessingThread (ProcessingJob* job, BatchProcessingListener* bpl, bool tunnelMetaData)

View File

@ -34,6 +34,7 @@
#include "guiutils.h" #include "guiutils.h"
#include "rtimage.h" #include "rtimage.h"
#include <sys/time.h> #include <sys/time.h>
using namespace std; using namespace std;
using namespace rtengine; using namespace rtengine;
@ -227,7 +228,7 @@ bool BatchQueue::saveBatchQueue ()
// The column's header is mandatory (the first line will be skipped when loaded) // The column's header is mandatory (the first line will be skipped when loaded)
file << "input image full path|param file full path|output image full path|file format|jpeg quality|jpeg subsampling|" file << "input image full path|param file full path|output image full path|file format|jpeg quality|jpeg subsampling|"
<< "png bit depth|png compression|tiff bit depth|uncompressed tiff|save output params|force format options|<end of line>" << "png bit depth|png compression|tiff bit depth|uncompressed tiff|save output params|force format options|fast export|<end of line>"
<< std::endl; << std::endl;
// method is already running with entryLock, so no need to lock again // method is already running with entryLock, so no need to lock again
@ -242,6 +243,7 @@ bool BatchQueue::saveBatchQueue ()
<< saveFormat.pngBits << '|' << saveFormat.pngCompression << '|' << saveFormat.pngBits << '|' << saveFormat.pngCompression << '|'
<< saveFormat.tiffBits << '|' << saveFormat.tiffUncompressed << '|' << saveFormat.tiffBits << '|' << saveFormat.tiffUncompressed << '|'
<< saveFormat.saveParams << '|' << entry->forceFormatOpts << '|' << saveFormat.saveParams << '|' << entry->forceFormatOpts << '|'
<< entry->job->fastPipeline() << '|'
<< std::endl; << std::endl;
} }
} }
@ -308,6 +310,7 @@ bool BatchQueue::loadBatchQueue ()
const auto tiffUncompressed = nextIntOr (options.saveFormat.tiffUncompressed); const auto tiffUncompressed = nextIntOr (options.saveFormat.tiffUncompressed);
const auto saveParams = nextIntOr (options.saveFormat.saveParams); const auto saveParams = nextIntOr (options.saveFormat.saveParams);
const auto forceFormatOpts = nextIntOr (options.forceFormatOpts); const auto forceFormatOpts = nextIntOr (options.forceFormatOpts);
const auto fast = nextIntOr(false);
rtengine::procparams::ProcParams pparams; rtengine::procparams::ProcParams pparams;
@ -319,7 +322,7 @@ bool BatchQueue::loadBatchQueue ()
if (!thumb) if (!thumb)
continue; continue;
auto job = rtengine::ProcessingJob::create (source, thumb->getType () == FT_Raw, pparams); auto job = rtengine::ProcessingJob::create (source, thumb->getType () == FT_Raw, pparams, fast);
auto prevh = getMaxThumbnailHeight (); auto prevh = getMaxThumbnailHeight ();
auto prevw = prevh; auto prevw = prevh;

View File

@ -38,7 +38,12 @@ ExportPanel::ExportPanel () : listener (nullptr)
labExportTitle->set_alignment(Gtk::ALIGN_START); labExportTitle->set_alignment(Gtk::ALIGN_START);
pack_start(*labExportTitle, Gtk::PACK_SHRINK, 4); pack_start(*labExportTitle, Gtk::PACK_SHRINK, 4);
Gtk::RadioButton::Group pipeline_group;
use_fast_pipeline = Gtk::manage ( new Gtk::RadioButton (pipeline_group, M("EXPORT_USE_FAST_PIPELINE")));
use_normal_pipeline = Gtk::manage ( new Gtk::RadioButton (pipeline_group, M("EXPORT_USE_NORMAL_PIPELINE")));
bypass_box = Gtk::manage(new Gtk::VBox());
bypass_ALL = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_ALL"))); bypass_ALL = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_ALL")));
use_fast_pipeline->set_tooltip_text(M("EXPORT_USE_FAST_PIPELINE_TIP"));
bypass_sharpening = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_SHARPENING"))); bypass_sharpening = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_SHARPENING")));
bypass_sharpenEdge = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_SHARPENEDGE"))); bypass_sharpenEdge = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_SHARPENEDGE")));
bypass_sharpenMicro = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_SHARPENMICRO"))); bypass_sharpenMicro = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_SHARPENMICRO")));
@ -96,18 +101,28 @@ ExportPanel::ExportPanel () : listener (nullptr)
// ---------------------------------------------------------------- // ----------------------------------------------------------------
// start global packing // start global packing
pack_start(*bypass_ALL , Gtk::PACK_SHRINK, 4); Gtk::HBox* lblbox = Gtk::manage (new Gtk::HBox ());
pack_start(*Gtk::manage(new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 4); lblbox->pack_start (*Gtk::manage (new Gtk::Label (M("EXPORT_PIPELINE"))), Gtk::PACK_SHRINK, 4);
pack_start(*bypass_sharpening , Gtk::PACK_SHRINK, 4); pack_start (*lblbox, Gtk::PACK_SHRINK, 4);
pack_start(*bypass_sharpenEdge , Gtk::PACK_SHRINK, 4); pack_start(*use_fast_pipeline , Gtk::PACK_SHRINK, 4);
pack_start(*bypass_sharpenMicro , Gtk::PACK_SHRINK, 4); pack_start(*use_normal_pipeline , Gtk::PACK_SHRINK, 4);
bypass_box->pack_start(*Gtk::manage(new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 4);
lblbox = Gtk::manage (new Gtk::HBox ());
lblbox->pack_start (*Gtk::manage (new Gtk::Label (M("EXPORT_BYPASS"))), Gtk::PACK_SHRINK, 4);
bypass_box->pack_start (*lblbox, Gtk::PACK_SHRINK, 4);
bypass_box->pack_start(*bypass_ALL , Gtk::PACK_SHRINK, 4);
// bypass_box->pack_start(*Gtk::manage(new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 4);
bypass_box->pack_start(*bypass_sharpening , Gtk::PACK_SHRINK, 4);
bypass_box->pack_start(*bypass_sharpenEdge , Gtk::PACK_SHRINK, 4);
bypass_box->pack_start(*bypass_sharpenMicro , Gtk::PACK_SHRINK, 4);
//pack_start(*bypass_lumaDenoise , Gtk::PACK_SHRINK, 4); //pack_start(*bypass_lumaDenoise , Gtk::PACK_SHRINK, 4);
//pack_start(*bypass_colorDenoise , Gtk::PACK_SHRINK, 4); //pack_start(*bypass_colorDenoise , Gtk::PACK_SHRINK, 4);
pack_start(*bypass_defringe , Gtk::PACK_SHRINK, 4); bypass_box->pack_start(*bypass_defringe , Gtk::PACK_SHRINK, 4);
pack_start(*bypass_dirpyrDenoise, Gtk::PACK_SHRINK, 4); bypass_box->pack_start(*bypass_dirpyrDenoise, Gtk::PACK_SHRINK, 4);
pack_start(*bypass_sh_hq , Gtk::PACK_SHRINK, 4); bypass_box->pack_start(*bypass_sh_hq , Gtk::PACK_SHRINK, 4);
pack_start(*bypass_dirpyrequalizer , Gtk::PACK_SHRINK, 4); bypass_box->pack_start(*bypass_dirpyrequalizer , Gtk::PACK_SHRINK, 4);
pack_start(*bypass_wavelet , Gtk::PACK_SHRINK, 4); bypass_box->pack_start(*bypass_wavelet , Gtk::PACK_SHRINK, 4);
bayerFrameVBox->pack_start(*hb_raw_bayer_method, Gtk::PACK_SHRINK, 4); bayerFrameVBox->pack_start(*hb_raw_bayer_method, Gtk::PACK_SHRINK, 4);
//bayerFrameVBox->pack_start(*bypass_raw_all_enhance , Gtk::PACK_SHRINK, 4); //bayerFrameVBox->pack_start(*bypass_raw_all_enhance , Gtk::PACK_SHRINK, 4);
@ -121,11 +136,13 @@ ExportPanel::ExportPanel () : listener (nullptr)
xtransFrameVBox->pack_start(*hb_raw_xtrans_method, Gtk::PACK_SHRINK, 4); xtransFrameVBox->pack_start(*hb_raw_xtrans_method, Gtk::PACK_SHRINK, 4);
xtransFrame->add(*xtransFrameVBox); xtransFrame->add(*xtransFrameVBox);
pack_start(*bypass_raw_ccSteps , Gtk::PACK_SHRINK, 4); bypass_box->pack_start(*bypass_raw_ccSteps , Gtk::PACK_SHRINK, 4);
pack_start(*bypass_raw_ca , Gtk::PACK_SHRINK, 4); bypass_box->pack_start(*bypass_raw_ca , Gtk::PACK_SHRINK, 4);
pack_start(*bypass_raw_df , Gtk::PACK_SHRINK, 4); bypass_box->pack_start(*bypass_raw_df , Gtk::PACK_SHRINK, 4);
pack_start(*bypass_raw_ff , Gtk::PACK_SHRINK, 4); bypass_box->pack_start(*bypass_raw_ff , Gtk::PACK_SHRINK, 4);
pack_start(*bypass_box, Gtk::PACK_SHRINK);
pack_start (*Gtk::manage(new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 2); pack_start (*Gtk::manage(new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 2);
@ -176,6 +193,7 @@ ExportPanel::ExportPanel () : listener (nullptr)
pack_start(*vboxpe, Gtk::PACK_SHRINK, 0); pack_start(*vboxpe, Gtk::PACK_SHRINK, 0);
use_fast_pipeline->signal_toggled().connect(sigc::mem_fun(*this, &ExportPanel::use_fast_pipeline_toggled));
btnFastExport->signal_clicked().connect( sigc::mem_fun(*this, &ExportPanel::FastExportPressed) ); btnFastExport->signal_clicked().connect( sigc::mem_fun(*this, &ExportPanel::FastExportPressed) );
//btnExportLoadSettings->signal_clicked().connect( sigc::mem_fun(*this, &ExportPanel::LoadSettings) ); //btnExportLoadSettings->signal_clicked().connect( sigc::mem_fun(*this, &ExportPanel::LoadSettings) );
//btnExportSaveSettings->signal_clicked().connect( sigc::mem_fun(*this, &ExportPanel::SaveSettings) ); //btnExportSaveSettings->signal_clicked().connect( sigc::mem_fun(*this, &ExportPanel::SaveSettings) );
@ -224,40 +242,48 @@ void ExportPanel::FastExportPressed ()
void ExportPanel::SaveSettingsAsDefault() void ExportPanel::SaveSettingsAsDefault()
{ {
bool changed = false;
#define FE_OPT_STORE_(n, v) \
do { \
if (n != v) { \
n = v; \
changed = true; \
} \
} while (false)
// Save fast export settings to options // Save fast export settings to options
options.fastexport_bypass_sharpening = bypass_sharpening->get_active (); FE_OPT_STORE_(options.fastexport_bypass_sharpening, bypass_sharpening->get_active ());
options.fastexport_bypass_sharpenEdge = bypass_sharpenEdge->get_active (); FE_OPT_STORE_(options.fastexport_bypass_sharpenEdge, bypass_sharpenEdge->get_active ());
options.fastexport_bypass_sharpenMicro = bypass_sharpenMicro->get_active (); FE_OPT_STORE_(options.fastexport_bypass_sharpenMicro, bypass_sharpenMicro->get_active ());
//options.fastexport_bypass_lumaDenoise = bypass_lumaDenoise->get_active (); //options.fastexport_bypass_lumaDenoise = bypass_lumaDenoise->get_active ();
//options.fastexport_bypass_colorDenoise = bypass_colorDenoise->get_active (); //options.fastexport_bypass_colorDenoise = bypass_colorDenoise->get_active ();
options.fastexport_bypass_defringe = bypass_defringe->get_active (); FE_OPT_STORE_(options.fastexport_bypass_defringe, bypass_defringe->get_active ());
options.fastexport_bypass_dirpyrDenoise = bypass_dirpyrDenoise->get_active (); FE_OPT_STORE_(options.fastexport_bypass_dirpyrDenoise, bypass_dirpyrDenoise->get_active ());
options.fastexport_bypass_sh_hq = bypass_sh_hq->get_active (); FE_OPT_STORE_(options.fastexport_bypass_sh_hq, bypass_sh_hq->get_active ());
options.fastexport_bypass_dirpyrequalizer = bypass_dirpyrequalizer->get_active (); FE_OPT_STORE_(options.fastexport_bypass_dirpyrequalizer, bypass_dirpyrequalizer->get_active ());
options.fastexport_bypass_wavelet = bypass_wavelet->get_active (); FE_OPT_STORE_(options.fastexport_bypass_wavelet, bypass_wavelet->get_active ());
//options.fastexport_bypass_raw_bayer_all_enhance = bypass_raw_all_enhance->get_active (); //options.fastexport_bypass_raw_bayer_all_enhance = bypass_raw_all_enhance->get_active ();
options.fastexport_bypass_raw_bayer_dcb_iterations = bypass_raw_bayer_dcb_iterations->get_active (); FE_OPT_STORE_(options.fastexport_bypass_raw_bayer_dcb_iterations, bypass_raw_bayer_dcb_iterations->get_active ());
options.fastexport_bypass_raw_bayer_dcb_enhance = bypass_raw_bayer_dcb_enhance->get_active (); FE_OPT_STORE_(options.fastexport_bypass_raw_bayer_dcb_enhance, bypass_raw_bayer_dcb_enhance->get_active ());
options.fastexport_bypass_raw_bayer_lmmse_iterations = bypass_raw_bayer_lmmse_iterations->get_active(); FE_OPT_STORE_(options.fastexport_bypass_raw_bayer_lmmse_iterations, bypass_raw_bayer_lmmse_iterations->get_active());
options.fastexport_bypass_raw_bayer_linenoise = bypass_raw_bayer_linenoise->get_active (); FE_OPT_STORE_(options.fastexport_bypass_raw_bayer_linenoise, bypass_raw_bayer_linenoise->get_active ());
options.fastexport_bypass_raw_bayer_greenthresh = bypass_raw_bayer_greenthresh->get_active (); FE_OPT_STORE_(options.fastexport_bypass_raw_bayer_greenthresh, bypass_raw_bayer_greenthresh->get_active ());
options.fastexport_bypass_raw_ccSteps = bypass_raw_ccSteps->get_active (); FE_OPT_STORE_(options.fastexport_bypass_raw_ccSteps, bypass_raw_ccSteps->get_active ());
options.fastexport_bypass_raw_ca = bypass_raw_ca->get_active (); FE_OPT_STORE_(options.fastexport_bypass_raw_ca, bypass_raw_ca->get_active ());
options.fastexport_bypass_raw_df = bypass_raw_df->get_active (); FE_OPT_STORE_(options.fastexport_bypass_raw_df, bypass_raw_df->get_active ());
options.fastexport_bypass_raw_ff = bypass_raw_ff->get_active (); FE_OPT_STORE_(options.fastexport_bypass_raw_ff, bypass_raw_ff->get_active ());
//saving Bayer demosaic_method //saving Bayer demosaic_method
int currentRow = raw_bayer_method->get_active_row_number(); int currentRow = raw_bayer_method->get_active_row_number();
if( currentRow >= 0 && currentRow < procparams::RAWParams::BayerSensor::numMethods) { if( currentRow >= 0 && currentRow < procparams::RAWParams::BayerSensor::numMethods) {
options.fastexport_raw_bayer_method = procparams::RAWParams::BayerSensor::methodstring[currentRow]; FE_OPT_STORE_(options.fastexport_raw_bayer_method, procparams::RAWParams::BayerSensor::methodstring[currentRow]);
} }
//saving X-Trans demosaic_method //saving X-Trans demosaic_method
currentRow = raw_xtrans_method->get_active_row_number(); currentRow = raw_xtrans_method->get_active_row_number();
if( currentRow >= 0 && currentRow < procparams::RAWParams::XTransSensor::numMethods) { if( currentRow >= 0 && currentRow < procparams::RAWParams::XTransSensor::numMethods) {
options.fastexport_raw_xtrans_method = procparams::RAWParams::XTransSensor::methodstring[currentRow]; FE_OPT_STORE_(options.fastexport_raw_xtrans_method, procparams::RAWParams::XTransSensor::methodstring[currentRow]);
} }
// options.fastexport_icm_input = icm_input ; // options.fastexport_icm_input = icm_input ;
@ -269,9 +295,16 @@ void ExportPanel::SaveSettingsAsDefault()
// options.fastexport_resize_appliesTo = resize_appliesTo; // options.fastexport_resize_appliesTo = resize_appliesTo;
// options.fastexport_resize_dataspec = resize_dataspec ; // options.fastexport_resize_dataspec = resize_dataspec ;
options.fastexport_resize_method = "Lanczos"; FE_OPT_STORE_(options.fastexport_resize_method, "Lanczos");
options.fastexport_resize_width = MaxWidth->get_value_as_int (); FE_OPT_STORE_(options.fastexport_resize_width, MaxWidth->get_value_as_int ());
options.fastexport_resize_height = MaxHeight->get_value_as_int (); FE_OPT_STORE_(options.fastexport_resize_height, MaxHeight->get_value_as_int ());
FE_OPT_STORE_(options.fastexport_use_fast_pipeline, use_fast_pipeline->get_active());
#undef FE_OPT_STORE_
if (changed) {
Options::save();
}
} }
void ExportPanel::LoadDefaultSettings() void ExportPanel::LoadDefaultSettings()
@ -327,6 +360,13 @@ void ExportPanel::LoadDefaultSettings()
MaxWidth->set_value(options.fastexport_resize_width); MaxWidth->set_value(options.fastexport_resize_width);
MaxHeight->set_value(options.fastexport_resize_height); MaxHeight->set_value(options.fastexport_resize_height);
if (options.fastexport_use_fast_pipeline) {
use_fast_pipeline->set_active(true);
bypass_box->set_sensitive(false);
} else {
use_normal_pipeline->set_active(true);
}
} }
void ExportPanel::LoadSettings() void ExportPanel::LoadSettings()
@ -408,6 +448,11 @@ void ExportPanel::bypassALL_Toggled()
bypass_raw_ffConn.block (false); bypass_raw_ffConn.block (false);
} }
void ExportPanel::use_fast_pipeline_toggled()
{
bypass_box->set_sensitive(!use_fast_pipeline->get_active());
}
/* /*
fastexport_bypass_sharpening fastexport_bypass_sharpening
fastexport_bypass_sharpenEdge fastexport_bypass_sharpenEdge

View File

@ -36,7 +36,10 @@ class ExportPanel : public Gtk::VBox
protected: protected:
Gtk::VBox *bypass_box;
//Gtk::CheckButton* enabled; //Gtk::CheckButton* enabled;
Gtk::RadioButton* use_fast_pipeline;
Gtk::RadioButton* use_normal_pipeline;
Gtk::CheckButton* bypass_ALL; Gtk::CheckButton* bypass_ALL;
Gtk::CheckButton* bypass_sharpenEdge; Gtk::CheckButton* bypass_sharpenEdge;
Gtk::CheckButton* bypass_sharpenMicro; Gtk::CheckButton* bypass_sharpenMicro;
@ -105,6 +108,7 @@ protected:
ExportPanelListener* listener; ExportPanelListener* listener;
void bypassALL_Toggled(); void bypassALL_Toggled();
void use_fast_pipeline_toggled();
void SaveSettingsAsDefault(); void SaveSettingsAsDefault();
void LoadDefaultSettings(); void LoadDefaultSettings();
void LoadSettings(); void LoadSettings();

View File

@ -389,6 +389,7 @@ FileBrowser::FileBrowser ()
untrash->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_Delete, Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE); untrash->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_Delete, Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE);
open->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_Return, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE); open->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_Return, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE);
develop->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_B, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); develop->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_B, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE);
developfast->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_B, Gdk::CONTROL_MASK | Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE);
copyprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_C, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); copyprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_C, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE);
pasteprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_V, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); pasteprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_V, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE);
partpasteprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_V, Gdk::CONTROL_MASK | Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE); partpasteprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_V, Gdk::CONTROL_MASK | Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE);
@ -767,6 +768,12 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m)
else if (m == develop) { else if (m == develop) {
tbl->developRequested (mselected, false); tbl->developRequested (mselected, false);
} else if (m == developfast) { } else if (m == developfast) {
if (exportPanel) {
// force saving export panel settings
exportPanel->setExportPanelListener(nullptr);
exportPanel->FastExportPressed();
exportPanel->setExportPanelListener(this);
}
tbl->developRequested (mselected, true); tbl->developRequested (mselected, true);
} }
@ -1139,9 +1146,12 @@ bool FileBrowser::keyPressed (GdkEventKey* event)
} else if (event->keyval == GDK_KEY_Delete && shift) { } else if (event->keyval == GDK_KEY_Delete && shift) {
menuItemActivated (untrash); menuItemActivated (untrash);
return true; return true;
} else if ((event->keyval == GDK_KEY_B || event->keyval == GDK_KEY_b) && ctrl) { } else if ((event->keyval == GDK_KEY_B || event->keyval == GDK_KEY_b) && ctrl && !shift) {
menuItemActivated (develop); menuItemActivated (develop);
return true; return true;
} else if ((event->keyval == GDK_KEY_B || event->keyval == GDK_KEY_b) && ctrl && shift) {
menuItemActivated (developfast);
return true;
} else if ((event->keyval == GDK_KEY_A || event->keyval == GDK_KEY_a) && ctrl) { } else if ((event->keyval == GDK_KEY_A || event->keyval == GDK_KEY_a) && ctrl) {
menuItemActivated (selall); menuItemActivated (selall);
return true; return true;

View File

@ -1095,46 +1095,47 @@ void FileCatalog::developRequested (std::vector<FileBrowserEntry*> tbe, bool fas
// and also those which effect is not pronounced after reducing the image size // and also those which effect is not pronounced after reducing the image size
// TODO!!! could expose selections below via preferences // TODO!!! could expose selections below via preferences
if (fastmode) { if (fastmode) {
if (options.fastexport_bypass_sharpening ) { if (!options.fastexport_use_fast_pipeline) {
if (options.fastexport_bypass_sharpening) {
params.sharpening.enabled = false; params.sharpening.enabled = false;
} }
if (options.fastexport_bypass_sharpenEdge ) { if (options.fastexport_bypass_sharpenEdge) {
params.sharpenEdge.enabled = false; params.sharpenEdge.enabled = false;
} }
if (options.fastexport_bypass_sharpenMicro ) { if (options.fastexport_bypass_sharpenMicro) {
params.sharpenMicro.enabled = false; params.sharpenMicro.enabled = false;
} }
//if (options.fastexport_bypass_lumaDenoise ) params.lumaDenoise.enabled = false; //if (options.fastexport_bypass_lumaDenoise) params.lumaDenoise.enabled = false;
//if (options.fastexport_bypass_colorDenoise ) params.colorDenoise.enabled = false; //if (options.fastexport_bypass_colorDenoise) params.colorDenoise.enabled = false;
if (options.fastexport_bypass_defringe ) { if (options.fastexport_bypass_defringe) {
params.defringe.enabled = false; params.defringe.enabled = false;
} }
if (options.fastexport_bypass_dirpyrDenoise ) { if (options.fastexport_bypass_dirpyrDenoise) {
params.dirpyrDenoise.enabled = false; params.dirpyrDenoise.enabled = false;
} }
if (options.fastexport_bypass_sh_hq ) { if (options.fastexport_bypass_sh_hq) {
params.sh.hq = false; params.sh.hq = false;
} }
if (options.fastexport_bypass_dirpyrequalizer ) { if (options.fastexport_bypass_dirpyrequalizer) {
params.dirpyrequalizer.enabled = false; params.dirpyrequalizer.enabled = false;
} }
if (options.fastexport_bypass_wavelet ) { if (options.fastexport_bypass_wavelet) {
params.wavelet.enabled = false; params.wavelet.enabled = false;
} }
//if (options.fastexport_bypass_raw_bayer_all_enhance ) params.raw.bayersensor.all_enhance = false; //if (options.fastexport_bypass_raw_bayer_all_enhance) params.raw.bayersensor.all_enhance = false;
if (options.fastexport_bypass_raw_bayer_dcb_iterations ) { if (options.fastexport_bypass_raw_bayer_dcb_iterations) {
params.raw.bayersensor.dcb_iterations = 0; params.raw.bayersensor.dcb_iterations = 0;
} }
if (options.fastexport_bypass_raw_bayer_dcb_enhance ) { if (options.fastexport_bypass_raw_bayer_dcb_enhance) {
params.raw.bayersensor.dcb_enhance = false; params.raw.bayersensor.dcb_enhance = false;
} }
@ -1142,52 +1143,60 @@ void FileCatalog::developRequested (std::vector<FileBrowserEntry*> tbe, bool fas
params.raw.bayersensor.lmmse_iterations = 0; params.raw.bayersensor.lmmse_iterations = 0;
} }
if (options.fastexport_bypass_raw_bayer_linenoise ) { if (options.fastexport_bypass_raw_bayer_linenoise) {
params.raw.bayersensor.linenoise = 0; params.raw.bayersensor.linenoise = 0;
} }
if (options.fastexport_bypass_raw_bayer_greenthresh ) { if (options.fastexport_bypass_raw_bayer_greenthresh) {
params.raw.bayersensor.greenthresh = 0; params.raw.bayersensor.greenthresh = 0;
} }
if (options.fastexport_bypass_raw_ccSteps ) { if (options.fastexport_bypass_raw_ccSteps) {
params.raw.bayersensor.ccSteps = params.raw.xtranssensor.ccSteps = 0; params.raw.bayersensor.ccSteps = params.raw.xtranssensor.ccSteps = 0;
} }
if (options.fastexport_bypass_raw_ca ) { if (options.fastexport_bypass_raw_ca) {
params.raw.ca_autocorrect = false; params.raw.ca_autocorrect = false;
params.raw.cared = 0; params.raw.cared = 0;
params.raw.cablue = 0; params.raw.cablue = 0;
} }
if (options.fastexport_bypass_raw_df ) { if (options.fastexport_bypass_raw_df) {
params.raw.df_autoselect = false; params.raw.df_autoselect = false;
params.raw.dark_frame = ""; params.raw.dark_frame = "";
} }
if (options.fastexport_bypass_raw_ff ) { if (options.fastexport_bypass_raw_ff) {
params.raw.ff_AutoSelect = false; params.raw.ff_AutoSelect = false;
params.raw.ff_file = ""; params.raw.ff_file = "";
} }
params.raw.bayersensor.method = options.fastexport_raw_bayer_method ; params.raw.bayersensor.method = options.fastexport_raw_bayer_method;
params.raw.xtranssensor.method = options.fastexport_raw_xtrans_method; params.raw.xtranssensor.method = options.fastexport_raw_xtrans_method;
params.icm.input = options.fastexport_icm_input ; params.icm.input = options.fastexport_icm_input;
params.icm.working = options.fastexport_icm_working ; params.icm.working = options.fastexport_icm_working;
params.icm.output = options.fastexport_icm_output ; params.icm.output = options.fastexport_icm_output;
params.icm.outputIntent = options.fastexport_icm_outputIntent ; params.icm.outputIntent = options.fastexport_icm_outputIntent;
params.icm.outputBPC = options.fastexport_icm_outputBPC ; params.icm.outputBPC = options.fastexport_icm_outputBPC;
params.icm.gamma = options.fastexport_icm_gamma ; params.icm.gamma = options.fastexport_icm_gamma;
params.resize.enabled = options.fastexport_resize_enabled ;
params.resize.scale = options.fastexport_resize_scale ;
params.resize.appliesTo = options.fastexport_resize_appliesTo ;
params.resize.method = options.fastexport_resize_method ;
params.resize.dataspec = options.fastexport_resize_dataspec ;
params.resize.width = options.fastexport_resize_width ;
params.resize.height = options.fastexport_resize_height ;
} }
rtengine::ProcessingJob* pjob = rtengine::ProcessingJob::create (fbe->filename, th->getType() == FT_Raw, params); if (params.resize.enabled) {
params.resize.width = rtengine::min(params.resize.width, options.fastexport_resize_width);
params.resize.height = rtengine::min(params.resize.height, options.fastexport_resize_height);
} else {
params.resize.width = options.fastexport_resize_width;
params.resize.height = options.fastexport_resize_height;
}
params.resize.enabled = options.fastexport_resize_enabled;
params.resize.scale = options.fastexport_resize_scale;
params.resize.appliesTo = options.fastexport_resize_appliesTo;
params.resize.method = options.fastexport_resize_method;
params.resize.dataspec = options.fastexport_resize_dataspec;
}
rtengine::ProcessingJob* pjob = rtengine::ProcessingJob::create (fbe->filename, th->getType() == FT_Raw, params, fastmode && options.fastexport_use_fast_pipeline);
int pw; int pw;
int ph = BatchQueue::calcMaxThumbnailHeight(); int ph = BatchQueue::calcMaxThumbnailHeight();

View File

@ -81,6 +81,8 @@ Glib::ustring fname_to_utf8 (const char* fname)
#endif #endif
} }
bool fast_export = false;
} }
/* Process line command options /* Process line command options
@ -407,6 +409,10 @@ int processLineParams( int argc, char **argv )
compression = -1; compression = -1;
break; break;
case 'f':
fast_export = true;
break;
case 'c': // MUST be last option case 'c': // MUST be last option
while (iArg + 1 < argc) { while (iArg + 1 < argc) {
iArg++; iArg++;
@ -491,7 +497,7 @@ int processLineParams( int argc, char **argv )
std::cout << std::endl; std::cout << std::endl;
#endif #endif
std::cout << "Options:" << std::endl; std::cout << "Options:" << std::endl;
std::cout << " " << Glib::path_get_basename(argv[0]) << " [-o <output>|-O <output>] [-s|-S] [-p <one.pp3> [-p <two.pp3> ...] ] [-d] [ -j[1-100] [-js<1-3>] | [-b<8|16>] [-t[z] | [-n]] ] [-Y] -c <input>" << std::endl; std::cout << " " << Glib::path_get_basename(argv[0]) << " [-o <output>|-O <output>] [-s|-S] [-p <one.pp3> [-p <two.pp3> ...] ] [-d] [ -j[1-100] [-js<1-3>] | [-b<8|16>] [-t[z] | [-n]] ] [-Y] [-f] -c <input>" << std::endl;
std::cout << std::endl; std::cout << std::endl;
std::cout << " -q Quick Start mode : do not load cached files to speedup start time." << std::endl; std::cout << " -q Quick Start mode : do not load cached files to speedup start time." << std::endl;
std::cout << " -c <files> Specify one or more input files." << std::endl; std::cout << " -c <files> Specify one or more input files." << std::endl;
@ -525,6 +531,7 @@ int processLineParams( int argc, char **argv )
std::cout << " -n Specify output to be compressed PNG." << std::endl; std::cout << " -n Specify output to be compressed PNG." << std::endl;
std::cout << " Compression is hard-coded to 6." << std::endl; std::cout << " Compression is hard-coded to 6." << std::endl;
std::cout << " -Y Overwrite output if present." << std::endl; std::cout << " -Y Overwrite output if present." << std::endl;
std::cout << " -f Use the custom fast-export processing pipeline." << std::endl;
std::cout << std::endl; std::cout << std::endl;
std::cout << "Your " << pparamsExt << " files can be incomplete, RawTherapee will build the final values as follows:" << std::endl; std::cout << "Your " << pparamsExt << " files can be incomplete, RawTherapee will build the final values as follows:" << std::endl;
std::cout << " 1- A new processing profile is created using neutral values," << std::endl; std::cout << " 1- A new processing profile is created using neutral values," << std::endl;
@ -714,7 +721,7 @@ int processLineParams( int argc, char **argv )
continue; continue;
} }
job = rtengine::ProcessingJob::create (ii, currentParams); job = rtengine::ProcessingJob::create (ii, currentParams, fast_export);
if( !job ) { if( !job ) {
errors++; errors++;

View File

@ -480,6 +480,7 @@ void Options::setDefaults ()
fastexport_resize_dataspec = 3; fastexport_resize_dataspec = 3;
fastexport_resize_width = 900; fastexport_resize_width = 900;
fastexport_resize_height = 900; fastexport_resize_height = 900;
fastexport_use_fast_pipeline = true;
clutsDir = "./cluts"; clutsDir = "./cluts";
@ -1784,6 +1785,9 @@ int Options::readFromFile (Glib::ustring fname)
if (keyFile.has_key ("Fast Export", "fastexport_resize_height" )) { if (keyFile.has_key ("Fast Export", "fastexport_resize_height" )) {
fastexport_resize_height = keyFile.get_integer ("Fast Export", "fastexport_resize_height" ); fastexport_resize_height = keyFile.get_integer ("Fast Export", "fastexport_resize_height" );
} }
if (keyFile.has_key ("Fast Export", "fastexport_use_fast_pipeline" )) {
fastexport_use_fast_pipeline = keyFile.get_integer ("Fast Export", "fastexport_use_fast_pipeline" );
}
} }
if (keyFile.has_group ("Dialogs")) { if (keyFile.has_group ("Dialogs")) {
@ -2142,6 +2146,7 @@ int Options::saveToFile (Glib::ustring fname)
keyFile.set_integer ("Fast Export", "fastexport_resize_dataspec", fastexport_resize_dataspec ); keyFile.set_integer ("Fast Export", "fastexport_resize_dataspec", fastexport_resize_dataspec );
keyFile.set_integer ("Fast Export", "fastexport_resize_width", fastexport_resize_width ); keyFile.set_integer ("Fast Export", "fastexport_resize_width", fastexport_resize_width );
keyFile.set_integer ("Fast Export", "fastexport_resize_height", fastexport_resize_height ); keyFile.set_integer ("Fast Export", "fastexport_resize_height", fastexport_resize_height );
keyFile.set_integer ("Fast Export", "fastexport_use_fast_pipeline", fastexport_use_fast_pipeline );
keyFile.set_string ("Dialogs", "LastIccDir", lastIccDir); keyFile.set_string ("Dialogs", "LastIccDir", lastIccDir);
keyFile.set_string ("Dialogs", "LastDarkframeDir", lastDarkframeDir); keyFile.set_string ("Dialogs", "LastDarkframeDir", lastDarkframeDir);

View File

@ -288,6 +288,7 @@ public:
int fastexport_resize_dataspec; int fastexport_resize_dataspec;
int fastexport_resize_width; int fastexport_resize_width;
int fastexport_resize_height; int fastexport_resize_height;
bool fastexport_use_fast_pipeline;
// Dialog settings // Dialog settings
Glib::ustring lastIccDir; Glib::ustring lastIccDir;