From 200e6dd882603c0caf761a8258add299c425045e Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 7 Mar 2017 17:38:32 +0100 Subject: [PATCH 01/33] experimental hacks on simpleprocess.cc --- rtengine/simpleprocess.cc | 2486 ++++++++++++++++++++----------------- 1 file changed, 1373 insertions(+), 1113 deletions(-) diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 9f1ca3c5c..e027968a5 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -35,641 +35,729 @@ namespace rtengine { extern const Settings* settings; -IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* pl, bool tunnelMetaData, bool flush) -{ +namespace { - errorCode = 0; - - ProcessingJobImpl* job = static_cast(pjob); - - if (pl) { - pl->setProgressStr ("PROGRESSBAR_PROCESSING"); - pl->setProgress (0.0); +class ImageProcessor { +public: + ImageProcessor(ProcessingJob* pjob, int& errorCode, + ProgressListener* pl, bool tunnelMetaData, bool flush): + pjob(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) + { } - InitialImage* ii = job->initialImage; + Image16 *operator()(bool fast) + { + if (!fast) { + return normal_pipeline(); + } else { + return fast_pipeline(); + } + } - if (!ii) { - ii = InitialImage::load (job->fname, job->isRaw, &errorCode); - - if (errorCode) { - delete job; +private: + Image16 *normal_pipeline() + { + if (!stage_1()) { return nullptr; } + stage_calc_denoise(); + stage_2(); + stage_3(); + stage_4(); + stage_5(); + stage_6(); + return stage_7(); } - procparams::ProcParams& params = job->pparams; + Image16 *fast_pipeline() + { + ProcessingJobImpl* job = static_cast(pjob); + if (!job->pparams.resize.enabled) { + return normal_pipeline(); + } + + if (!stage_1()) { + return nullptr; + } + stage_2(); + stage_4(); + stage_early_resize(); + stage_calc_denoise(); + stage_3(); + stage_5(); + stage_6(); + return stage_7(); + } - // acquire image from imagesource - ImageSource* imgsrc = ii->getImageSource (); + bool stage_1() + { + errorCode = 0; - int tr = getCoarseBitMask(params.coarse); - int fw, fh; - imgsrc->getFullSize (fw, fh, tr); + ProcessingJobImpl* job = static_cast(pjob); - // check the crop params - if (params.crop.x > fw || params.crop.y > fh) { - // the crop is completely out of the image, so we disable the crop - params.crop.enabled = false; - // and we set the values to the defaults - params.crop.x = 0; - params.crop.y = 0; - params.crop.w = fw; - params.crop.h = fh; - } else { - if (params.crop.x < 0) { + if (pl) { + pl->setProgressStr ("PROGRESSBAR_PROCESSING"); + pl->setProgress (0.0); + } + + ii = job->initialImage; + + if (!ii) { + ii = InitialImage::load (job->fname, job->isRaw, &errorCode); + + if (errorCode) { + delete job; + return false; //return nullptr; + } + } + + procparams::ProcParams& params = job->pparams; + + // acquire image from imagesource + imgsrc = ii->getImageSource (); + + tr = getCoarseBitMask(params.coarse); + imgsrc->getFullSize (fw, fh, tr); + + // check the crop params + if (params.crop.x > fw || params.crop.y > fh) { + // the crop is completely out of the image, so we disable the crop + params.crop.enabled = false; + // and we set the values to the defaults params.crop.x = 0; - } - - if (params.crop.y < 0) { params.crop.y = 0; - } + params.crop.w = fw; + params.crop.h = fh; + } else { + if (params.crop.x < 0) { + params.crop.x = 0; + } - if ((params.crop.x + params.crop.w) > fw) { - // crop overflow in the width dimension ; we trim it - params.crop.w = fw - params.crop.x; - } + if (params.crop.y < 0) { + params.crop.y = 0; + } - if ((params.crop.y + params.crop.h) > fh) { - // crop overflow in the height dimension ; we trim it - params.crop.h = fh - params.crop.y; + if ((params.crop.x + params.crop.w) > fw) { + // crop overflow in the width dimension ; we trim it + params.crop.w = fw - params.crop.x; + } + + if ((params.crop.y + params.crop.h) > fh) { + // crop overflow in the height dimension ; we trim it + params.crop.h = fh - params.crop.y; + } } - } // MyTime t1,t2; // t1.set(); - ImProcFunctions ipf (¶ms, true); + ImProcFunctions ipf (¶ms, true); - PreviewProps pp (0, 0, fw, fh, 1); - imgsrc->preprocess( params.raw, params.lensProf, params.coarse, params.dirpyrDenoise.enabled); + pp = PreviewProps(0, 0, fw, fh, 1); + imgsrc->preprocess( params.raw, params.lensProf, params.coarse, params.dirpyrDenoise.enabled); - if (params.toneCurve.autoexp) {// this enabled HLRecovery - LUTu histRedRaw(256), histGreenRaw(256), histBlueRaw(256); - imgsrc->getRAWHistogram(histRedRaw, histGreenRaw, histBlueRaw); + if (params.toneCurve.autoexp) {// this enabled HLRecovery + LUTu histRedRaw(256), histGreenRaw(256), histBlueRaw(256); + imgsrc->getRAWHistogram(histRedRaw, histGreenRaw, histBlueRaw); - if (ToneCurveParams::HLReconstructionNecessary(histRedRaw, histGreenRaw, histBlueRaw) && !params.toneCurve.hrenabled) { - params.toneCurve.hrenabled = true; - // WARNING: Highlight Reconstruction is being forced 'on', should we force a method here too? + if (ToneCurveParams::HLReconstructionNecessary(histRedRaw, histGreenRaw, histBlueRaw) && !params.toneCurve.hrenabled) { + params.toneCurve.hrenabled = true; + // WARNING: Highlight Reconstruction is being forced 'on', should we force a method here too? + } } - } - if (pl) { - pl->setProgress (0.20); - } + if (pl) { + pl->setProgress (0.20); + } - imgsrc->demosaic( params.raw); + imgsrc->demosaic( params.raw); - if (pl) { - pl->setProgress (0.30); - } + if (pl) { + pl->setProgress (0.30); + } - if(params.retinex.enabled) { //enabled Retinex - LUTf cdcurve (65536, 0); - LUTf mapcurve (65536, 0); - LUTu dummy; - RetinextransmissionCurve dehatransmissionCurve; - RetinexgaintransmissionCurve dehagaintransmissionCurve; - bool dehacontlutili = false; - bool mapcontlutili = false; - bool useHsl = false; + if(params.retinex.enabled) { //enabled Retinex + LUTf cdcurve (65536, 0); + LUTf mapcurve (65536, 0); + LUTu dummy; + RetinextransmissionCurve dehatransmissionCurve; + RetinexgaintransmissionCurve dehagaintransmissionCurve; + bool dehacontlutili = false; + bool mapcontlutili = false; + bool useHsl = false; // multi_array2D conversionBuffer(1, 1); - multi_array2D conversionBuffer(1, 1); - imgsrc->retinexPrepareBuffers(params.icm, params.retinex, conversionBuffer, dummy); - imgsrc->retinexPrepareCurves(params.retinex, cdcurve, mapcurve, dehatransmissionCurve, dehagaintransmissionCurve, dehacontlutili, mapcontlutili, useHsl, dummy, dummy ); - float minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax; - imgsrc->retinex( params.icm, params.retinex, params.toneCurve, cdcurve, mapcurve, dehatransmissionCurve, dehagaintransmissionCurve, conversionBuffer, dehacontlutili, mapcontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, dummy); - } - - if (pl) { - pl->setProgress (0.40); - } - - imgsrc->HLRecovery_Global( params.toneCurve ); - - - if (pl) { - pl->setProgress (0.45); - } - - // set the color temperature - ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.equal, params.wb.method); - - if (params.wb.method == "Camera") { - currWB = imgsrc->getWB (); - } else if (params.wb.method == "Auto") { - double rm, gm, bm; - imgsrc->getAutoWBMultipliers(rm, gm, bm); - currWB.update(rm, gm, bm, params.wb.equal, params.wb.tempBias); - } - - NoiseCurve noiseLCurve; - NoiseCurve noiseCCurve; - Imagefloat *calclum = nullptr ; - params.dirpyrDenoise.getCurves(noiseLCurve, noiseCCurve); - float autoNR = (float) settings->nrauto;// - float autoNRmax = (float) settings->nrautomax;// - int tilesize; - int overlap; - - if(settings->leveldnti == 0) { - tilesize = 1024; - overlap = 128; - } - - if(settings->leveldnti == 1) { - tilesize = 768; - overlap = 96; - } - - // const int tilesize = 768; - // const int overlap = 96; - int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip; - ipf.Tile_calc (tilesize, overlap, 2, fw, fh, numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip); - int nbtl = numtiles_W * numtiles_H; - - if((settings->leveldnautsimpl == 1 && params.dirpyrDenoise.Cmethod == "AUT") || (settings->leveldnautsimpl == 0 && params.dirpyrDenoise.C2method == "AUTO")) { - nbtl = 9; - } - - float *ch_M = new float [nbtl];//allocate memory - float *max_r = new float [nbtl]; - float *max_b = new float [nbtl]; - float *min_b = new float [9]; - float *min_r = new float [9]; - float *lumL = new float [nbtl]; - float *chromC = new float [nbtl]; - float *ry = new float [nbtl]; - float *sk = new float [nbtl]; - float *pcsk = new float [nbtl]; - - // printf("expert=%d\n",settings->leveldnautsimpl); - if(settings->leveldnautsimpl == 1 && params.dirpyrDenoise.Cmethod == "PON") { - MyTime t1pone, t2pone; - t1pone.set(); - int crW, crH; - - if(settings->leveldnv == 0) { - crW = 100; - crH = 100; + multi_array2D conversionBuffer(1, 1); + imgsrc->retinexPrepareBuffers(params.icm, params.retinex, conversionBuffer, dummy); + imgsrc->retinexPrepareCurves(params.retinex, cdcurve, mapcurve, dehatransmissionCurve, dehagaintransmissionCurve, dehacontlutili, mapcontlutili, useHsl, dummy, dummy ); + float minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax; + imgsrc->retinex( params.icm, params.retinex, params.toneCurve, cdcurve, mapcurve, dehatransmissionCurve, dehagaintransmissionCurve, conversionBuffer, dehacontlutili, mapcontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, dummy); } - if(settings->leveldnv == 1) { - crW = 250; - crH = 250; + if (pl) { + pl->setProgress (0.40); } - if(settings->leveldnv == 2) { - crW = int(tileWskip / 2); - crH = int(tileHskip / 2); + imgsrc->HLRecovery_Global( params.toneCurve ); + + + if (pl) { + pl->setProgress (0.45); } - // if(settings->leveldnv ==2) {crW=int(tileWskip/2);crH=int(1.15f*(tileWskip/2));}//adapted to scale of preview - if(settings->leveldnv == 3) { - crW = tileWskip - 10; - crH = tileHskip - 10; + // set the color temperature + currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.equal, params.wb.method); + + if (params.wb.method == "Camera") { + currWB = imgsrc->getWB (); + } else if (params.wb.method == "Auto") { + double rm, gm, bm; + imgsrc->getAutoWBMultipliers(rm, gm, bm); + currWB.update(rm, gm, bm, params.wb.equal, params.wb.tempBias); } - float lowdenoise = 1.f; - int levaut = settings->leveldnaut; + // // AG begin + // baseImg = new Imagefloat (fw, fh); + // imgsrc->getImage (currWB, tr, baseImg, pp, params.toneCurve, params.icm, params.raw); + // // AG end - if(levaut == 1) { //Standard - lowdenoise = 0.7f; + return true; + } + + void stage_calc_denoise() + { + ProcessingJobImpl* job = static_cast(pjob); + procparams::ProcParams& params = job->pparams; + ImProcFunctions ipf (¶ms, true); + + calclum = nullptr ; + params.dirpyrDenoise.getCurves(noiseLCurve, noiseCCurve); + autoNR = (float) settings->nrauto;// + autoNRmax = (float) settings->nrautomax;// + + if(settings->leveldnti == 0) { + tilesize = 1024; + overlap = 128; } - // int crW=tileWskip-10;//crop noise width - // int crH=tileHskip-10;//crop noise height + if(settings->leveldnti == 1) { + tilesize = 768; + overlap = 96; + } + + // const int tilesize = 768; + // const int overlap = 96; + int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip; + ipf.Tile_calc (tilesize, overlap, 2, fw, fh, numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip); + int nbtl = numtiles_W * numtiles_H; + + if((settings->leveldnautsimpl == 1 && params.dirpyrDenoise.Cmethod == "AUT") || (settings->leveldnautsimpl == 0 && params.dirpyrDenoise.C2method == "AUTO")) { + nbtl = 9; + } + + ch_M = new float [nbtl];//allocate memory + max_r = new float [nbtl]; + max_b = new float [nbtl]; + min_b = new float [9]; + min_r = new float [9]; + lumL = new float [nbtl]; + chromC = new float [nbtl]; + ry = new float [nbtl]; + sk = new float [nbtl]; + pcsk = new float [nbtl]; + + // printf("expert=%d\n",settings->leveldnautsimpl); + if(settings->leveldnautsimpl == 1 && params.dirpyrDenoise.Cmethod == "PON") { + MyTime t1pone, t2pone; + t1pone.set(); + int crW, crH; + + if(settings->leveldnv == 0) { + crW = 100; + crH = 100; + } + + if(settings->leveldnv == 1) { + crW = 250; + crH = 250; + } + + if(settings->leveldnv == 2) { + crW = int(tileWskip / 2); + crH = int(tileHskip / 2); + } + + // if(settings->leveldnv ==2) {crW=int(tileWskip/2);crH=int(1.15f*(tileWskip/2));}//adapted to scale of preview + if(settings->leveldnv == 3) { + crW = tileWskip - 10; + crH = tileHskip - 10; + } + + float lowdenoise = 1.f; + int levaut = settings->leveldnaut; + + if(levaut == 1) { //Standard + lowdenoise = 0.7f; + } + + // int crW=tileWskip-10;//crop noise width + // int crH=tileHskip-10;//crop noise height // Imagefloat *origCropPart;//init auto noise // origCropPart = new Imagefloat (crW, crH);//allocate memory - if (params.dirpyrDenoise.enabled) {//evaluate Noise - LUTf gamcurve(65536, 0); - float gam, gamthresh, gamslope; - ipf.RGB_denoise_infoGamCurve(params.dirpyrDenoise, imgsrc->isRAW(), gamcurve, gam, gamthresh, gamslope); - #pragma omp parallel - { - Imagefloat *origCropPart;//init auto noise - origCropPart = new Imagefloat (crW, crH);//allocate memory - Imagefloat *provicalc = new Imagefloat ((crW + 1) / 2, (crH + 1) / 2); //for denoise curves - int skipP = 1; - #pragma omp for schedule(dynamic) collapse(2) nowait + if (params.dirpyrDenoise.enabled) {//evaluate Noise + LUTf gamcurve(65536, 0); + float gam, gamthresh, gamslope; + ipf.RGB_denoise_infoGamCurve(params.dirpyrDenoise, imgsrc->isRAW(), gamcurve, gam, gamthresh, gamslope); +#pragma omp parallel + { + Imagefloat *origCropPart;//init auto noise + origCropPart = new Imagefloat (crW, crH);//allocate memory + Imagefloat *provicalc = new Imagefloat ((crW + 1) / 2, (crH + 1) / 2); //for denoise curves + int skipP = 1; +#pragma omp for schedule(dynamic) collapse(2) nowait - for(int wcr = 0; wcr < numtiles_W; wcr++) { - for(int hcr = 0; hcr < numtiles_H; hcr++) { - int beg_tileW = wcr * tileWskip + tileWskip / 2.f - crW / 2.f; - int beg_tileH = hcr * tileHskip + tileHskip / 2.f - crH / 2.f; - PreviewProps ppP (beg_tileW , beg_tileH, crW, crH, skipP); - imgsrc->getImage (currWB, tr, origCropPart, ppP, params.toneCurve, params.icm, params.raw ); + for(int wcr = 0; wcr < numtiles_W; wcr++) { + for(int hcr = 0; hcr < numtiles_H; hcr++) { + int beg_tileW = wcr * tileWskip + tileWskip / 2.f - crW / 2.f; + int beg_tileH = hcr * tileHskip + tileHskip / 2.f - crH / 2.f; + PreviewProps ppP (beg_tileW , beg_tileH, crW, crH, skipP); + 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 - for(int ii = 0; ii < crH; ii += 2) { - for(int jj = 0; jj < crW; jj += 2) { - provicalc->r(ii >> 1, jj >> 1) = origCropPart->r(ii, jj); - provicalc->g(ii >> 1, jj >> 1) = origCropPart->g(ii, jj); - provicalc->b(ii >> 1, jj >> 1) = origCropPart->b(ii, jj); + // we only need image reduced to 1/4 here + for(int ii = 0; ii < crH; ii += 2) { + for(int jj = 0; jj < crW; jj += 2) { + provicalc->r(ii >> 1, jj >> 1) = origCropPart->r(ii, jj); + provicalc->g(ii >> 1, jj >> 1) = origCropPart->g(ii, jj); + provicalc->b(ii >> 1, jj >> 1) = origCropPart->b(ii, jj); + } } - } - imgsrc->convertColorSpace(provicalc, params.icm, currWB);//for denoise luminance curve - float maxr = 0.f; - float maxb = 0.f; - float pondcorrec = 1.0f; - float chaut, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc; - int Nb; - chaut = 0.f; - redaut = 0.f; - blueaut = 0.f; - maxredaut = 0.f; - maxblueaut = 0.f; - chromina = 0.f; - sigma = 0.f; - ipf.RGB_denoise_info(origCropPart, provicalc, imgsrc->isRAW(), gamcurve, gam, gamthresh, gamslope, params.dirpyrDenoise, imgsrc->getDirPyrDenoiseExpComp(), chaut, Nb, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc); - float multip = 1.f; - float adjustr = 1.f; + imgsrc->convertColorSpace(provicalc, params.icm, currWB);//for denoise luminance curve + float maxr = 0.f; + float maxb = 0.f; + float pondcorrec = 1.0f; + float chaut, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc; + int Nb; + chaut = 0.f; + redaut = 0.f; + blueaut = 0.f; + maxredaut = 0.f; + maxblueaut = 0.f; + chromina = 0.f; + sigma = 0.f; + ipf.RGB_denoise_info(origCropPart, provicalc, imgsrc->isRAW(), gamcurve, gam, gamthresh, gamslope, params.dirpyrDenoise, imgsrc->getDirPyrDenoiseExpComp(), chaut, Nb, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc); + float multip = 1.f; + float adjustr = 1.f; - if (params.icm.working == "ProPhoto") { - adjustr = 1.f; // - } else if (params.icm.working == "Adobe RGB") { - adjustr = 1.f / 1.3f; - } else if (params.icm.working == "sRGB") { - adjustr = 1.f / 1.3f; - } else if (params.icm.working == "WideGamut") { - adjustr = 1.f / 1.1f; - } else if (params.icm.working == "Rec2020") { - adjustr = 1.f / 1.1f; - } else if (params.icm.working == "Beta RGB") { - adjustr = 1.f / 1.2f; - } else if (params.icm.working == "BestRGB") { - adjustr = 1.f / 1.2f; - } else if (params.icm.working == "BruceRGB") { - adjustr = 1.f / 1.2f; - } - - if(!imgsrc->isRAW()) { - multip = 2.f; //take into account gamma for TIF / JPG approximate value...not good fot gamma=1 - } - - float maxmax = max(maxredaut, maxblueaut); - float delta; - int mode = 2; - int lissage = settings->leveldnliss; - ipf.calcautodn_info (chaut, delta, Nb, levaut, maxmax, lumema, chromina, mode, lissage, redyel, skinc, nsknc); - - // printf("PROCESS cha=%f red=%f bl=%f redM=%f bluM=%f chrom=%f sigm=%f lum=%f sigL=%f\n",chaut,redaut,blueaut, maxredaut, maxblueaut, chromina, sigma, lumema, sigma_L); - if(maxredaut > maxblueaut) { - maxr = (delta) / ((autoNRmax * multip * adjustr * lowdenoise) / 2.f); - - if(minblueaut <= minredaut && minblueaut < chaut) { - maxb = (-chaut + minblueaut) / (autoNRmax * multip * adjustr * lowdenoise); + if (params.icm.working == "ProPhoto") { + adjustr = 1.f; // + } else if (params.icm.working == "Adobe RGB") { + adjustr = 1.f / 1.3f; + } else if (params.icm.working == "sRGB") { + adjustr = 1.f / 1.3f; + } else if (params.icm.working == "WideGamut") { + adjustr = 1.f / 1.1f; + } else if (params.icm.working == "Rec2020") { + adjustr = 1.f / 1.1f; + } else if (params.icm.working == "Beta RGB") { + adjustr = 1.f / 1.2f; + } else if (params.icm.working == "BestRGB") { + adjustr = 1.f / 1.2f; + } else if (params.icm.working == "BruceRGB") { + adjustr = 1.f / 1.2f; } + + if(!imgsrc->isRAW()) { + multip = 2.f; //take into account gamma for TIF / JPG approximate value...not good fot gamma=1 + } + + float maxmax = max(maxredaut, maxblueaut); + float delta; + int mode = 2; + int lissage = settings->leveldnliss; + ipf.calcautodn_info (chaut, delta, Nb, levaut, maxmax, lumema, chromina, mode, lissage, redyel, skinc, nsknc); + + // printf("PROCESS cha=%f red=%f bl=%f redM=%f bluM=%f chrom=%f sigm=%f lum=%f sigL=%f\n",chaut,redaut,blueaut, maxredaut, maxblueaut, chromina, sigma, lumema, sigma_L); + if(maxredaut > maxblueaut) { + maxr = (delta) / ((autoNRmax * multip * adjustr * lowdenoise) / 2.f); + + if(minblueaut <= minredaut && minblueaut < chaut) { + maxb = (-chaut + minblueaut) / (autoNRmax * multip * adjustr * lowdenoise); + } + } else { + maxb = (delta) / ((autoNRmax * multip * adjustr * lowdenoise) / 2.f); + + if(minredaut <= minblueaut && minredaut < chaut) { + maxr = (-chaut + minredaut) / (autoNRmax * multip * adjustr * lowdenoise); + } + }//maxb mxr - empirical evaluation red / blue + + ch_M[hcr * numtiles_W + wcr] = pondcorrec * chaut / (autoNR * multip * adjustr * lowdenoise); + max_r[hcr * numtiles_W + wcr] = pondcorrec * maxr; + max_b[hcr * numtiles_W + wcr] = pondcorrec * maxb; + lumL[hcr * numtiles_W + wcr] = lumema; + chromC[hcr * numtiles_W + wcr] = chromina; + ry[hcr * numtiles_W + wcr] = redyel; + sk[hcr * numtiles_W + wcr] = skinc; + pcsk[hcr * numtiles_W + wcr] = nsknc; + + } + } + + delete provicalc; + delete origCropPart; + } + + int liss = settings->leveldnliss; //smooth result around mean + + if(liss == 2 || liss == 3) { + // I smooth only mean and not delta (max) + float nchm = 0.f; + float koef = 0.4f; //between 0.1 to 0.9 + + if(liss == 3) { + koef = 0.0f; //quasi auto for mean Ch + } + + for(int wcr = 0; wcr < numtiles_W; wcr++) { + for(int hcr = 0; hcr < numtiles_H; hcr++) { + nchm += ch_M[hcr * numtiles_W + wcr]; + } + } + + nchm /= (numtiles_H * numtiles_W); + + for(int wcr = 0; wcr < numtiles_W; wcr++) { + for(int hcr = 0; hcr < numtiles_H; hcr++) { + ch_M[hcr * numtiles_W + wcr] = nchm + (ch_M[hcr * numtiles_W + wcr] - nchm) * koef; + } + } + } + + if(liss == 3) { //same as auto but with much cells + float MaxR = 0.f; + float MaxB = 0.f; + float MaxRMoy = 0.f; + float MaxBMoy = 0.f; + + for(int k = 0; k < nbtl; k++) { + MaxBMoy += max_b[k]; + MaxRMoy += max_r[k]; + + if(max_r[k] > MaxR) { + MaxR = max_r[k]; + } + + if(max_b[k] > MaxB) { + MaxB = max_b[k]; + } + + } + + MaxBMoy /= nbtl; + MaxRMoy /= nbtl; + + for(int k = 0; k < nbtl; k++) { + if(MaxR > MaxB) { + max_r[k] = MaxRMoy + (MaxR - MaxRMoy) * 0.66f; //#std Dev + //max_b[k]=MinB; + max_b[k] = MaxBMoy + (MaxB - MaxBMoy) * 0.66f; + } else { - maxb = (delta) / ((autoNRmax * multip * adjustr * lowdenoise) / 2.f); + max_b[k] = MaxBMoy + (MaxB - MaxBMoy) * 0.66f; + //max_r[k]=MinR; + max_r[k] = MaxRMoy + (MaxR - MaxRMoy) * 0.66f; - if(minredaut <= minblueaut && minredaut < chaut) { - maxr = (-chaut + minredaut) / (autoNRmax * multip * adjustr * lowdenoise); + } + } + } + + if (settings->verbose) { + t2pone.set(); + printf("Info denoise ponderated performed in %d usec:\n", t2pone.etime(t1pone)); + } + + } + } + + + if((settings->leveldnautsimpl == 1 && params.dirpyrDenoise.Cmethod == "AUT") || (settings->leveldnautsimpl == 0 && params.dirpyrDenoise.C2method == "AUTO")) { + MyTime t1aue, t2aue; + t1aue.set(); + int crW, crH; + + if(settings->leveldnv == 0) { + crW = 100; + crH = 100; + } + + if(settings->leveldnv == 1) { + crW = 250; + crH = 250; + } + + if(settings->leveldnv == 2) { + crW = int(tileWskip / 2); + crH = int(tileHskip / 2); + } + + // if(settings->leveldnv ==2) {crW=int(tileWskip/2);crH=int(1.15f*(tileWskip/2));}//adapted to scale of preview + if(settings->leveldnv == 3) { + crW = tileWskip - 10; + crH = tileHskip - 10; + } + + float lowdenoise = 1.f; + int levaut = settings->leveldnaut; + + if(levaut == 1) { //Standard + lowdenoise = 0.7f; + } + + if (params.dirpyrDenoise.enabled) {//evaluate Noise + LUTf gamcurve(65536, 0); + float gam, gamthresh, gamslope; + ipf.RGB_denoise_infoGamCurve(params.dirpyrDenoise, imgsrc->isRAW(), gamcurve, gam, gamthresh, gamslope); + int Nb[9]; + int coordW[3];//coordonate of part of image to mesure noise + int coordH[3]; + int begW = 50; + int begH = 50; + coordW[0] = begW; + coordW[1] = fw / 2 - crW / 2; + coordW[2] = fw - crW - begW; + coordH[0] = begH; + coordH[1] = fh / 2 - crH / 2; + coordH[2] = fh - crH - begH; +#pragma omp parallel + { + Imagefloat *origCropPart;//init auto noise + origCropPart = new Imagefloat (crW, crH);//allocate memory + Imagefloat *provicalc = new Imagefloat ((crW + 1) / 2, (crH + 1) / 2); //for denoise curves + +#pragma omp for schedule(dynamic) collapse(2) nowait + + for(int wcr = 0; wcr <= 2; wcr++) { + for(int hcr = 0; hcr <= 2; hcr++) { + PreviewProps ppP (coordW[wcr] , coordH[hcr], crW, crH, 1); + 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 + for(int ii = 0; ii < crH; ii += 2) { + for(int jj = 0; jj < crW; jj += 2) { + provicalc->r(ii >> 1, jj >> 1) = origCropPart->r(ii, jj); + provicalc->g(ii >> 1, jj >> 1) = origCropPart->g(ii, jj); + provicalc->b(ii >> 1, jj >> 1) = origCropPart->b(ii, jj); + } } - }//maxb mxr - empirical evaluation red / blue - - ch_M[hcr * numtiles_W + wcr] = pondcorrec * chaut / (autoNR * multip * adjustr * lowdenoise); - max_r[hcr * numtiles_W + wcr] = pondcorrec * maxr; - max_b[hcr * numtiles_W + wcr] = pondcorrec * maxb; - lumL[hcr * numtiles_W + wcr] = lumema; - chromC[hcr * numtiles_W + wcr] = chromina; - ry[hcr * numtiles_W + wcr] = redyel; - sk[hcr * numtiles_W + wcr] = skinc; - pcsk[hcr * numtiles_W + wcr] = nsknc; + imgsrc->convertColorSpace(provicalc, params.icm, currWB);//for denoise luminance curve + int nb = 0; + float chaut = 0.f, redaut = 0.f, blueaut = 0.f, maxredaut = 0.f, maxblueaut = 0.f, minredaut = 0.f, minblueaut = 0.f, chromina = 0.f, sigma = 0.f, lumema = 0.f, sigma_L = 0.f, redyel = 0.f, skinc = 0.f, nsknc = 0.f; + ipf.RGB_denoise_info(origCropPart, provicalc, imgsrc->isRAW(), gamcurve, gam, gamthresh, gamslope, params.dirpyrDenoise, imgsrc->getDirPyrDenoiseExpComp(), chaut, nb, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc); + Nb[hcr * 3 + wcr] = nb; + ch_M[hcr * 3 + wcr] = chaut; + max_r[hcr * 3 + wcr] = maxredaut; + max_b[hcr * 3 + wcr] = maxblueaut; + min_r[hcr * 3 + wcr] = minredaut; + min_b[hcr * 3 + wcr] = minblueaut; + lumL[hcr * 3 + wcr] = lumema; + chromC[hcr * 3 + wcr] = chromina; + ry[hcr * 3 + wcr] = redyel; + sk[hcr * 3 + wcr] = skinc; + pcsk[hcr * 3 + wcr] = nsknc; + } } + + delete provicalc; + delete origCropPart; } - - delete provicalc; - delete origCropPart; - } - - int liss = settings->leveldnliss; //smooth result around mean - - if(liss == 2 || liss == 3) { - // I smooth only mean and not delta (max) - float nchm = 0.f; - float koef = 0.4f; //between 0.1 to 0.9 - - if(liss == 3) { - koef = 0.0f; //quasi auto for mean Ch - } - - for(int wcr = 0; wcr < numtiles_W; wcr++) { - for(int hcr = 0; hcr < numtiles_H; hcr++) { - nchm += ch_M[hcr * numtiles_W + wcr]; - } - } - - nchm /= (numtiles_H * numtiles_W); - - for(int wcr = 0; wcr < numtiles_W; wcr++) { - for(int hcr = 0; hcr < numtiles_H; hcr++) { - ch_M[hcr * numtiles_W + wcr] = nchm + (ch_M[hcr * numtiles_W + wcr] - nchm) * koef; - } - } - } - - if(liss == 3) { //same as auto but with much cells + float chM = 0.f; float MaxR = 0.f; float MaxB = 0.f; + float MinR = 100000000.f; + float MinB = 100000000.f; + float maxr = 0.f; + float maxb = 0.f; + float multip = 1.f; + float adjustr = 1.f; + float Max_R[9] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; + float Max_B[9] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; + float Min_R[9]; + float Min_B[9]; float MaxRMoy = 0.f; float MaxBMoy = 0.f; + float MinRMoy = 0.f; + float MinBMoy = 0.f; - for(int k = 0; k < nbtl; k++) { - MaxBMoy += max_b[k]; - MaxRMoy += max_r[k]; - - if(max_r[k] > MaxR) { - MaxR = max_r[k]; - } - - if(max_b[k] > MaxB) { - MaxB = max_b[k]; - } - + if (params.icm.working == "ProPhoto") { + adjustr = 1.f; + } else if (params.icm.working == "Adobe RGB") { + adjustr = 1.f / 1.3f; + } else if (params.icm.working == "sRGB") { + adjustr = 1.f / 1.3f; + } else if (params.icm.working == "WideGamut") { + adjustr = 1.f / 1.1f; + } else if (params.icm.working == "Rec2020") { + adjustr = 1.f / 1.1f; + } else if (params.icm.working == "Beta RGB") { + adjustr = 1.f / 1.2f; + } else if (params.icm.working == "BestRGB") { + adjustr = 1.f / 1.2f; + } else if (params.icm.working == "BruceRGB") { + adjustr = 1.f / 1.2f; } - MaxBMoy /= nbtl; - MaxRMoy /= nbtl; + if(!imgsrc->isRAW()) { + multip = 2.f; //take into account gamma for TIF / JPG approximate value...not good fot gamma=1 + } - for(int k = 0; k < nbtl; k++) { - if(MaxR > MaxB) { - max_r[k] = MaxRMoy + (MaxR - MaxRMoy) * 0.66f; //#std Dev - //max_b[k]=MinB; - max_b[k] = MaxBMoy + (MaxB - MaxBMoy) * 0.66f; + float delta[9]; + int mode = 1; + int lissage = settings->leveldnliss; + for(int k = 0; k < 9; k++) { + float maxmax = max(max_r[k], max_b[k]); + ipf.calcautodn_info (ch_M[k], delta[k], Nb[k], levaut, maxmax, lumL[k], chromC[k], mode, lissage, ry[k], sk[k], pcsk[k] ); + // printf("ch_M=%f delta=%f\n",ch_M[k], delta[k]); + } + + for(int k = 0; k < 9; k++) { + if(max_r[k] > max_b[k]) { + //printf("R delta=%f koef=%f\n",delta[k],autoNRmax*multip*adjustr*lowdenoise); + Max_R[k] = (delta[k]) / ((autoNRmax * multip * adjustr * lowdenoise) / 2.f); + Min_B[k] = -(ch_M[k] - min_b[k]) / (autoNRmax * multip * adjustr * lowdenoise); + Max_B[k] = 0.f; + Min_R[k] = 0.f; } else { - max_b[k] = MaxBMoy + (MaxB - MaxBMoy) * 0.66f; - //max_r[k]=MinR; - max_r[k] = MaxRMoy + (MaxR - MaxRMoy) * 0.66f; - - } - } - } - - if (settings->verbose) { - t2pone.set(); - printf("Info denoise ponderated performed in %d usec:\n", t2pone.etime(t1pone)); - } - - } - } - - - if((settings->leveldnautsimpl == 1 && params.dirpyrDenoise.Cmethod == "AUT") || (settings->leveldnautsimpl == 0 && params.dirpyrDenoise.C2method == "AUTO")) { - MyTime t1aue, t2aue; - t1aue.set(); - int crW, crH; - - if(settings->leveldnv == 0) { - crW = 100; - crH = 100; - } - - if(settings->leveldnv == 1) { - crW = 250; - crH = 250; - } - - if(settings->leveldnv == 2) { - crW = int(tileWskip / 2); - crH = int(tileHskip / 2); - } - - // if(settings->leveldnv ==2) {crW=int(tileWskip/2);crH=int(1.15f*(tileWskip/2));}//adapted to scale of preview - if(settings->leveldnv == 3) { - crW = tileWskip - 10; - crH = tileHskip - 10; - } - - float lowdenoise = 1.f; - int levaut = settings->leveldnaut; - - if(levaut == 1) { //Standard - lowdenoise = 0.7f; - } - - if (params.dirpyrDenoise.enabled) {//evaluate Noise - LUTf gamcurve(65536, 0); - float gam, gamthresh, gamslope; - ipf.RGB_denoise_infoGamCurve(params.dirpyrDenoise, imgsrc->isRAW(), gamcurve, gam, gamthresh, gamslope); - int Nb[9]; - int coordW[3];//coordonate of part of image to mesure noise - int coordH[3]; - int begW = 50; - int begH = 50; - coordW[0] = begW; - coordW[1] = fw / 2 - crW / 2; - coordW[2] = fw - crW - begW; - coordH[0] = begH; - coordH[1] = fh / 2 - crH / 2; - coordH[2] = fh - crH - begH; - #pragma omp parallel - { - Imagefloat *origCropPart;//init auto noise - origCropPart = new Imagefloat (crW, crH);//allocate memory - Imagefloat *provicalc = new Imagefloat ((crW + 1) / 2, (crH + 1) / 2); //for denoise curves - - #pragma omp for schedule(dynamic) collapse(2) nowait - - for(int wcr = 0; wcr <= 2; wcr++) { - for(int hcr = 0; hcr <= 2; hcr++) { - PreviewProps ppP (coordW[wcr] , coordH[hcr], crW, crH, 1); - imgsrc->getImage (currWB, tr, origCropPart, ppP, params.toneCurve, params.icm, params.raw); - - // we only need image reduced to 1/4 here - for(int ii = 0; ii < crH; ii += 2) { - for(int jj = 0; jj < crW; jj += 2) { - provicalc->r(ii >> 1, jj >> 1) = origCropPart->r(ii, jj); - provicalc->g(ii >> 1, jj >> 1) = origCropPart->g(ii, jj); - provicalc->b(ii >> 1, jj >> 1) = origCropPart->b(ii, jj); - } - } - - imgsrc->convertColorSpace(provicalc, params.icm, currWB);//for denoise luminance curve - int nb = 0; - float chaut = 0.f, redaut = 0.f, blueaut = 0.f, maxredaut = 0.f, maxblueaut = 0.f, minredaut = 0.f, minblueaut = 0.f, chromina = 0.f, sigma = 0.f, lumema = 0.f, sigma_L = 0.f, redyel = 0.f, skinc = 0.f, nsknc = 0.f; - ipf.RGB_denoise_info(origCropPart, provicalc, imgsrc->isRAW(), gamcurve, gam, gamthresh, gamslope, params.dirpyrDenoise, imgsrc->getDirPyrDenoiseExpComp(), chaut, nb, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc); - Nb[hcr * 3 + wcr] = nb; - ch_M[hcr * 3 + wcr] = chaut; - max_r[hcr * 3 + wcr] = maxredaut; - max_b[hcr * 3 + wcr] = maxblueaut; - min_r[hcr * 3 + wcr] = minredaut; - min_b[hcr * 3 + wcr] = minblueaut; - lumL[hcr * 3 + wcr] = lumema; - chromC[hcr * 3 + wcr] = chromina; - ry[hcr * 3 + wcr] = redyel; - sk[hcr * 3 + wcr] = skinc; - pcsk[hcr * 3 + wcr] = nsknc; + //printf("B delta=%f koef=%f\n",delta[k],autoNRmax*multip*adjustr*lowdenoise); + Max_B[k] = (delta[k]) / ((autoNRmax * multip * adjustr * lowdenoise) / 2.f); + Min_R[k] = - (ch_M[k] - min_r[k]) / (autoNRmax * multip * adjustr * lowdenoise); + Min_B[k] = 0.f; + Max_R[k] = 0.f; } } - delete provicalc; - delete origCropPart; - } - float chM = 0.f; - float MaxR = 0.f; - float MaxB = 0.f; - float MinR = 100000000.f; - float MinB = 100000000.f; - float maxr = 0.f; - float maxb = 0.f; - float multip = 1.f; - float adjustr = 1.f; - float Max_R[9] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; - float Max_B[9] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; - float Min_R[9]; - float Min_B[9]; - float MaxRMoy = 0.f; - float MaxBMoy = 0.f; - float MinRMoy = 0.f; - float MinBMoy = 0.f; + for(int k = 0; k < 9; k++) { + // printf("ch_M= %f Max_R=%f Max_B=%f min_r=%f min_b=%f\n",ch_M[k],Max_R[k], Max_B[k],Min_R[k], Min_B[k]); + chM += ch_M[k]; + MaxBMoy += Max_B[k]; + MaxRMoy += Max_R[k]; + MinRMoy += Min_R[k]; + MinBMoy += Min_B[k]; - if (params.icm.working == "ProPhoto") { - adjustr = 1.f; - } else if (params.icm.working == "Adobe RGB") { - adjustr = 1.f / 1.3f; - } else if (params.icm.working == "sRGB") { - adjustr = 1.f / 1.3f; - } else if (params.icm.working == "WideGamut") { - adjustr = 1.f / 1.1f; - } else if (params.icm.working == "Rec2020") { - adjustr = 1.f / 1.1f; - } else if (params.icm.working == "Beta RGB") { - adjustr = 1.f / 1.2f; - } else if (params.icm.working == "BestRGB") { - adjustr = 1.f / 1.2f; - } else if (params.icm.working == "BruceRGB") { - adjustr = 1.f / 1.2f; - } + if(Max_R[k] > MaxR) { + MaxR = Max_R[k]; + } - if(!imgsrc->isRAW()) { - multip = 2.f; //take into account gamma for TIF / JPG approximate value...not good fot gamma=1 - } + if(Max_B[k] > MaxB) { + MaxB = Max_B[k]; + } - float delta[9]; - int mode = 1; - int lissage = settings->leveldnliss; + if(Min_R[k] < MinR) { + MinR = Min_R[k]; + } - for(int k = 0; k < 9; k++) { - float maxmax = max(max_r[k], max_b[k]); - ipf.calcautodn_info (ch_M[k], delta[k], Nb[k], levaut, maxmax, lumL[k], chromC[k], mode, lissage, ry[k], sk[k], pcsk[k] ); - // printf("ch_M=%f delta=%f\n",ch_M[k], delta[k]); - } + if(Min_B[k] < MinB) { + MinB = Min_B[k]; + } + + } + + chM /= 9; + MaxBMoy /= 9; + MaxRMoy /= 9; + MinBMoy /= 9; + MinRMoy /= 9; + + if(MaxR > MaxB) { + maxr = MaxRMoy + (MaxR - MaxRMoy) * 0.66f; //#std Dev + // maxb=MinB; + maxb = MinBMoy + (MinB - MinBMoy) * 0.66f; - for(int k = 0; k < 9; k++) { - if(max_r[k] > max_b[k]) { - //printf("R delta=%f koef=%f\n",delta[k],autoNRmax*multip*adjustr*lowdenoise); - Max_R[k] = (delta[k]) / ((autoNRmax * multip * adjustr * lowdenoise) / 2.f); - Min_B[k] = -(ch_M[k] - min_b[k]) / (autoNRmax * multip * adjustr * lowdenoise); - Max_B[k] = 0.f; - Min_R[k] = 0.f; } else { - //printf("B delta=%f koef=%f\n",delta[k],autoNRmax*multip*adjustr*lowdenoise); - Max_B[k] = (delta[k]) / ((autoNRmax * multip * adjustr * lowdenoise) / 2.f); - Min_R[k] = - (ch_M[k] - min_r[k]) / (autoNRmax * multip * adjustr * lowdenoise); - Min_B[k] = 0.f; - Max_R[k] = 0.f; + maxb = MaxBMoy + (MaxB - MaxBMoy) * 0.66f; + // maxr=MinR; + maxr = MinRMoy + (MinR - MinRMoy) * 0.66f; + } - } - - for(int k = 0; k < 9; k++) { - // printf("ch_M= %f Max_R=%f Max_B=%f min_r=%f min_b=%f\n",ch_M[k],Max_R[k], Max_B[k],Min_R[k], Min_B[k]); - chM += ch_M[k]; - MaxBMoy += Max_B[k]; - MaxRMoy += Max_R[k]; - MinRMoy += Min_R[k]; - MinBMoy += Min_B[k]; - - if(Max_R[k] > MaxR) { - MaxR = Max_R[k]; - } - - if(Max_B[k] > MaxB) { - MaxB = Max_B[k]; - } - - if(Min_R[k] < MinR) { - MinR = Min_R[k]; - } - - if(Min_B[k] < MinB) { - MinB = Min_B[k]; - } - - } - - chM /= 9; - MaxBMoy /= 9; - MaxRMoy /= 9; - MinBMoy /= 9; - MinRMoy /= 9; - - if(MaxR > MaxB) { - maxr = MaxRMoy + (MaxR - MaxRMoy) * 0.66f; //#std Dev - // maxb=MinB; - maxb = MinBMoy + (MinB - MinBMoy) * 0.66f; - - } else { - maxb = MaxBMoy + (MaxB - MaxBMoy) * 0.66f; - // maxr=MinR; - maxr = MinRMoy + (MinR - MinRMoy) * 0.66f; - - } // printf("SIMPL cha=%f red=%f bl=%f \n",chM,maxr,maxb); - params.dirpyrDenoise.chroma = chM / (autoNR * multip * adjustr); - params.dirpyrDenoise.redchro = maxr; - params.dirpyrDenoise.bluechro = maxb; + params.dirpyrDenoise.chroma = chM / (autoNR * multip * adjustr); + params.dirpyrDenoise.redchro = maxr; + params.dirpyrDenoise.bluechro = maxb; + } + + if (settings->verbose) { + t2aue.set(); + printf("Info denoise auto performed in %d usec:\n", t2aue.etime(t1aue)); + } + + //end evaluate noise } - if (settings->verbose) { - t2aue.set(); - printf("Info denoise auto performed in %d usec:\n", t2aue.etime(t1aue)); + // return true; + } + + void stage_2() + { + ProcessingJobImpl* job = static_cast(pjob); + procparams::ProcParams& params = job->pparams; + ImProcFunctions ipf (¶ms, true); + + baseImg = new Imagefloat (fw, fh); + imgsrc->getImage (currWB, tr, baseImg, pp, params.toneCurve, params.icm, params.raw); + + if (pl) { + pl->setProgress (0.50); } - //end evaluate noise - } - - - - - - Imagefloat* baseImg = new Imagefloat (fw, fh); - imgsrc->getImage (currWB, tr, baseImg, pp, params.toneCurve, params.icm, params.raw); - - if (pl) { - pl->setProgress (0.50); - } - // LUTf Noisecurve (65536,0); //!!!// auto exposure!!! - double expcomp = params.toneCurve.expcomp; - int bright = params.toneCurve.brightness; - int contr = params.toneCurve.contrast; - int black = params.toneCurve.black; - int hlcompr = params.toneCurve.hlcompr; - int hlcomprthresh = params.toneCurve.hlcomprthresh; + expcomp = params.toneCurve.expcomp; + bright = params.toneCurve.brightness; + contr = params.toneCurve.contrast; + black = params.toneCurve.black; + hlcompr = params.toneCurve.hlcompr; + hlcomprthresh = params.toneCurve.hlcomprthresh; - if (params.toneCurve.autoexp) { - LUTu aehist; - int aehistcompr; - imgsrc->getAutoExpHistogram (aehist, aehistcompr); - ipf.getAutoExp (aehist, aehistcompr, imgsrc->getDefGain(), params.toneCurve.clip, expcomp, bright, contr, black, hlcompr, hlcomprthresh); + + if (params.toneCurve.autoexp) { + LUTu aehist; + int aehistcompr; + imgsrc->getAutoExpHistogram (aehist, aehistcompr); + ipf.getAutoExp (aehist, aehistcompr, imgsrc->getDefGain(), params.toneCurve.clip, expcomp, bright, contr, black, hlcompr, hlcomprthresh); + } + + // at this stage, we can flush the raw data to free up quite an important amount of memory + // commented out because it makes the application crash when batch processing... + // TODO: find a better place to flush rawData and rawRGB + if(flush) { + imgsrc->flushRawData(); + imgsrc->flushRGB(); + } } - // at this stage, we can flush the raw data to free up quite an important amount of memory - // commented out because it makes the application crash when batch processing... - // TODO: find a better place to flush rawData and rawRGB - if(flush) { - imgsrc->flushRawData(); - imgsrc->flushRGB(); - } - - // perform luma/chroma denoise + void stage_3() + { + ProcessingJobImpl* job = static_cast(pjob); + procparams::ProcParams& params = job->pparams; + ImProcFunctions ipf (¶ms, true); + + // perform luma/chroma denoise // CieImage *cieView; // NoisCurve noiseLCurve; // bool lldenoiseutili=false; @@ -677,604 +765,776 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p // params.dirpyrDenoise.getCurves(noiseLCurve, lldenoiseutili); // if (params.dirpyrDenoise.enabled && lldenoiseutili) { - DirPyrDenoiseParams denoiseParams = params.dirpyrDenoise; // make a copy because we cheat here + DirPyrDenoiseParams denoiseParams = params.dirpyrDenoise; // make a copy because we cheat here - if(denoiseParams.Lmethod == "CUR") { - if(noiseLCurve) { - denoiseParams.luma = 0.5f; - } else { - denoiseParams.luma = 0.0f; + if(denoiseParams.Lmethod == "CUR") { + if(noiseLCurve) { + denoiseParams.luma = 0.5f; + } else { + denoiseParams.luma = 0.0f; + } + } else if(denoiseParams.Lmethod == "SLI") { + noiseLCurve.Reset(); } - } else if(denoiseParams.Lmethod == "SLI") { - noiseLCurve.Reset(); + + if (denoiseParams.enabled && (noiseLCurve || noiseCCurve )) { + // we only need image reduced to 1/4 here + calclum = new Imagefloat ((fw + 1) / 2, (fh + 1) / 2); //for luminance denoise curve +#pragma omp parallel for + + for(int ii = 0; ii < fh; ii += 2) { + for(int jj = 0; jj < fw; jj += 2) { + calclum->r(ii >> 1, jj >> 1) = baseImg->r(ii, jj); + calclum->g(ii >> 1, jj >> 1) = baseImg->g(ii, jj); + calclum->b(ii >> 1, jj >> 1) = baseImg->b(ii, jj); + } + } + + imgsrc->convertColorSpace(calclum, params.icm, currWB); + } + + if (denoiseParams.enabled) { + // CurveFactory::denoiseLL(lldenoiseutili, denoiseParams.lcurve, Noisecurve,1); + //denoiseParams.getCurves(noiseLCurve); +// ipf.RGB_denoise(baseImg, baseImg, calclum, imgsrc->isRAW(), denoiseParams, params.defringe, imgsrc->getDirPyrDenoiseExpComp(), noiseLCurve, lldenoiseutili); + float chaut, redaut, blueaut, maxredaut, maxblueaut, nresi, highresi; + int kall = 2; + ipf.RGB_denoise(kall, baseImg, baseImg, calclum, ch_M, max_r, max_b, imgsrc->isRAW(), denoiseParams, imgsrc->getDirPyrDenoiseExpComp(), noiseLCurve, noiseCCurve, chaut, redaut, blueaut, maxredaut, maxblueaut, nresi, highresi); + + } + +// delete calclum; + delete [] ch_M; + delete [] max_r; + delete [] max_b; + delete [] min_r; + delete [] min_b; + delete [] lumL; + delete [] chromC; + delete [] ry; + delete [] sk; + delete [] pcsk; + + // imgsrc->convertColorSpace(baseImg, params.icm, currWB); + + // // perform first analysis + // hist16 (65536); + + // ipf.firstAnalysis (baseImg, params, hist16); } - if (denoiseParams.enabled && (noiseLCurve || noiseCCurve )) { - // we only need image reduced to 1/4 here - calclum = new Imagefloat ((fw + 1) / 2, (fh + 1) / 2); //for luminance denoise curve - #pragma omp parallel for - for(int ii = 0; ii < fh; ii += 2) { - for(int jj = 0; jj < fw; jj += 2) { - calclum->r(ii >> 1, jj >> 1) = baseImg->r(ii, jj); - calclum->g(ii >> 1, jj >> 1) = baseImg->g(ii, jj); - calclum->b(ii >> 1, jj >> 1) = baseImg->b(ii, jj); + void stage_4() + { + ProcessingJobImpl* job = static_cast(pjob); + procparams::ProcParams& params = job->pparams; + ImProcFunctions ipf (¶ms, true); + + imgsrc->convertColorSpace(baseImg, params.icm, currWB); + + // perform first analysis + hist16 (65536); + + ipf.firstAnalysis (baseImg, params, hist16); + + // perform transform (excepted resizing) + if (ipf.needsTransform()) { + Imagefloat* trImg = new Imagefloat (fw, fh); + ipf.transform (baseImg, trImg, 0, 0, 0, 0, fw, fh, fw, fh, imgsrc->getMetaData()->getFocalLen(), imgsrc->getMetaData()->getFocalLen35mm(), + imgsrc->getMetaData()->getFocusDist(), imgsrc->getRotateDegree(), true); + delete baseImg; + baseImg = trImg; + } + } + + void stage_5() + { + ProcessingJobImpl* job = static_cast(pjob); + procparams::ProcParams& params = job->pparams; + ImProcFunctions ipf (¶ms, true); + + if (params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) { + const int W = baseImg->getWidth(); + const int H = baseImg->getHeight(); + LabImage labcbdl(W, H); + ipf.rgb2lab(*baseImg, labcbdl, params.icm.working); + ipf.dirpyrequalizer (&labcbdl, 1); + ipf.lab2rgb(labcbdl, *baseImg, params.icm.working); + } + + // update blurmap + SHMap* shmap = nullptr; + + if (params.sh.enabled) { + shmap = new SHMap (fw, fh, true); + double radius = sqrt (double(fw * fw + fh * fh)) / 2.0; + double shradius = params.sh.radius; + + if (!params.sh.hq) { + shradius *= radius / 1800.0; + } + + shmap->update (baseImg, shradius, ipf.lumimul, params.sh.hq, 1); + } + + // RGB processing + + curve1(65536); + curve2(65536); + curve(65536, 0); + satcurve(65536, 0); + lhskcurve(65536, 0); + lumacurve(32770, 0); // lumacurve[32768] and lumacurve[32769] will be set to 32768 and 32769 later to allow linear interpolation + clcurve(65536, 0); + wavclCurve(65536, 0); + + //if(params.blackwhite.enabled) params.toneCurve.hrenabled=false; + + CurveFactory::complexCurve (expcomp, black / 65535.0, hlcompr, hlcomprthresh, params.toneCurve.shcompr, bright, contr, + params.toneCurve.curveMode, params.toneCurve.curve, params.toneCurve.curveMode2, params.toneCurve.curve2, + hist16, curve1, curve2, curve, dummy, customToneCurve1, customToneCurve2 ); + + CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, 1); + CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, 1); + CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, 1); + + bool opautili = false; + + if(params.colorToning.enabled) { + TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); + double wp[3][3] = { + {wprof[0][0], wprof[0][1], wprof[0][2]}, + {wprof[1][0], wprof[1][1], wprof[1][2]}, + {wprof[2][0], wprof[2][1], wprof[2][2]} + }; + TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working); + double wip[3][3] = { + {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, + {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, + {wiprof[2][0], wiprof[2][1], wiprof[2][2]} + }; + params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); + clToningcurve (65536, 0); + CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, 1); + cl2Toningcurve (65536, 0); + CurveFactory::curveToning(params.colorToning.cl2curve, cl2Toningcurve, 1); + } + + labView = new LabImage (fw, fh); + + if(params.blackwhite.enabled) { + CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 1); + } + + double rrm, ggm, bbm; + float autor, autog, autob; + float satLimit = float(params.colorToning.satProtectionThreshold) / 100.f * 0.7f + 0.3f; + float satLimitOpacity = 1.f - (float(params.colorToning.saturatedOpacity) / 100.f); + + if(params.colorToning.enabled && params.colorToning.autosat) { //for colortoning evaluation of saturation settings + float moyS = 0.f; + float eqty = 0.f; + ipf.moyeqt (baseImg, moyS, eqty);//return image : mean saturation and standard dev of saturation + float satp = ((moyS + 1.5f * eqty) - 0.3f) / 0.7f; //1.5 sigma ==> 93% pixels with high saturation -0.3 / 0.7 convert to Hombre scale + + if(satp >= 0.92f) { + satp = 0.92f; //avoid values too high (out of gamut) + } + + if(satp <= 0.15f) { + satp = 0.15f; //avoid too low values + } + + satLimit = 100.f * satp; + + satLimitOpacity = 100.f * (moyS - 0.85f * eqty); //-0.85 sigma==>20% pixels with low saturation + } + + autor = -9000.f; // This will ask to compute the "auto" values for the B&W tool (have to be inferior to -5000) + DCPProfile::ApplyState as; + DCPProfile *dcpProf = imgsrc->getDCP(params.icm, currWB, as); + + LUTu histToneCurve; + + ipf.rgbProc (baseImg, labView, nullptr, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, satLimit , satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh, dcpProf, as, histToneCurve); + + if (settings->verbose) { + printf("Output image / Auto B&W coefs: R=%.2f G=%.2f B=%.2f\n", autor, autog, autob); + } + + // if clut was used and size of clut cache == 1 we free the memory used by the clutstore (default clut cache size = 1 for 32 bit OS) + if ( params.filmSimulation.enabled && !params.filmSimulation.clutFilename.empty() && options.clutCacheSize == 1) { + CLUTStore::getInstance().clearCache(); + } + + // freeing up some memory + customToneCurve1.Reset(); + customToneCurve2.Reset(); + ctColorCurve.Reset(); + ctOpacityCurve.Reset(); + noiseLCurve.Reset(); + noiseCCurve.Reset(); + customToneCurvebw1.Reset(); + customToneCurvebw2.Reset(); + + // Freeing baseImg because not used anymore + delete baseImg; + baseImg = nullptr; + + if (shmap) { + delete shmap; + } + + shmap = nullptr; + + if (pl) { + pl->setProgress (0.55); + } + } + + void stage_6() + { + ProcessingJobImpl* job = static_cast(pjob); + procparams::ProcParams& params = job->pparams; + ImProcFunctions ipf (¶ms, true); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // start tile processing...??? + + + if(params.labCurve.contrast != 0) { //only use hist16 for contrast + hist16.clear(); + +#ifdef _OPENMP +#pragma omp parallel +#endif + { + LUTu hist16thr (hist16.getSize()); // one temporary lookup table per thread + hist16thr.clear(); +#ifdef _OPENMP +#pragma omp for schedule(static) nowait +#endif + + for (int i = 0; i < fh; i++) + for (int j = 0; j < fw; j++) { + hist16thr[(int)((labView->L[i][j]))]++; + } + +#pragma omp critical + { + hist16 += hist16thr; + } } } - imgsrc->convertColorSpace(calclum, params.icm, currWB); - } + bool utili; + CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, hist16, lumacurve, dummy, 1, utili); - if (denoiseParams.enabled) { - // CurveFactory::denoiseLL(lldenoiseutili, denoiseParams.lcurve, Noisecurve,1); - //denoiseParams.getCurves(noiseLCurve); -// ipf.RGB_denoise(baseImg, baseImg, calclum, imgsrc->isRAW(), denoiseParams, params.defringe, imgsrc->getDirPyrDenoiseExpComp(), noiseLCurve, lldenoiseutili); - float chaut, redaut, blueaut, maxredaut, maxblueaut, nresi, highresi; - int kall = 2; - ipf.RGB_denoise(kall, baseImg, baseImg, calclum, ch_M, max_r, max_b, imgsrc->isRAW(), denoiseParams, imgsrc->getDirPyrDenoiseExpComp(), noiseLCurve, noiseCCurve, chaut, redaut, blueaut, maxredaut, maxblueaut, nresi, highresi); + bool clcutili; + CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, 1); - } + bool ccutili, cclutili; + CurveFactory::complexsgnCurve (autili, butili, ccutili, cclutili, params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve, + params.labCurve.lccurve, curve1, curve2, satcurve, lhskcurve, 1); -// delete calclum; - delete [] ch_M; - delete [] max_r; - delete [] max_b; - delete [] min_r; - delete [] min_b; - delete [] lumL; - delete [] chromC; - delete [] ry; - delete [] sk; - delete [] pcsk; + ipf.chromiLuminanceCurve (nullptr, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy); - imgsrc->convertColorSpace(baseImg, params.icm, currWB); - - // perform first analysis - LUTu hist16 (65536); - - ipf.firstAnalysis (baseImg, params, hist16); - - // perform transform (excepted resizing) - if (ipf.needsTransform()) { - Imagefloat* trImg = new Imagefloat (fw, fh); - ipf.transform (baseImg, trImg, 0, 0, 0, 0, fw, fh, fw, fh, imgsrc->getMetaData()->getFocalLen(), imgsrc->getMetaData()->getFocalLen35mm(), - imgsrc->getMetaData()->getFocusDist(), imgsrc->getRotateDegree(), true); - delete baseImg; - baseImg = trImg; - } - - - if (params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) { - const int W = baseImg->getWidth(); - const int H = baseImg->getHeight(); - LabImage labcbdl(W, H); - ipf.rgb2lab(*baseImg, labcbdl, params.icm.working); - ipf.dirpyrequalizer (&labcbdl, 1); - ipf.lab2rgb(labcbdl, *baseImg, params.icm.working); - } - - // update blurmap - SHMap* shmap = nullptr; - - if (params.sh.enabled) { - shmap = new SHMap (fw, fh, true); - double radius = sqrt (double(fw * fw + fh * fh)) / 2.0; - double shradius = params.sh.radius; - - if (!params.sh.hq) { - shradius *= radius / 1800.0; + if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) { + ipf.EPDToneMap(labView, 5, 1); } - shmap->update (baseImg, shradius, ipf.lumimul, params.sh.hq, 1); + + ipf.vibrance(labView); + + if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { + ipf.impulsedenoise (labView); + } + + // for all treatments Defringe, Sharpening, Contrast detail ,Microcontrast they are activated if "CIECAM" function are disabled + + if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { + ipf.defringe (labView); + } + + if (params.sharpenEdge.enabled) { + ipf.MLsharpen(labView); + } + + if (params.sharpenMicro.enabled) { + if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { + ipf.MLmicrocontrast (labView); //!params.colorappearance.sharpcie + } + } + + if(((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) && params.sharpening.enabled) { + + float **buffer = new float*[fh]; + + for (int i = 0; i < fh; i++) { + buffer[i] = new float[fw]; + } + + ipf.sharpening (labView, (float**)buffer, params.sharpening); + + for (int i = 0; i < fh; i++) { + delete [] buffer[i]; + } + + delete [] buffer; + } + + WaveletParams WaveParams = params.wavelet; + WavCurve wavCLVCurve; + WavOpacityCurveRG waOpacityCurveRG; + WavOpacityCurveBY waOpacityCurveBY; + WavOpacityCurveW waOpacityCurveW; + WavOpacityCurveWL waOpacityCurveWL; + + params.wavelet.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL ); + + + // directional pyramid wavelet + if(params.dirpyrequalizer.cbdlMethod == "aft") { + if((params.colorappearance.enabled && !settings->autocielab) || !params.colorappearance.enabled) { + ipf.dirpyrequalizer (labView, 1); //TODO: this is the luminance tonecurve, not the RGB one + } + } + + bool wavcontlutili = false; + + CurveFactory::curveWavContL(wavcontlutili, params.wavelet.wavclCurve, wavclCurve,/* hist16C, dummy,*/ 1); + + if(params.wavelet.enabled) { + ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, wavcontlutili, 1); + } + + wavCLVCurve.Reset(); + + //Colorappearance and tone-mapping associated + + int f_w = 1, f_h = 1; + int begh = 0, endh = fh; + + if(params.colorappearance.tonecie || params.colorappearance.enabled) { + f_w = fw; + f_h = fh; + } + + CieImage *cieView = new CieImage (f_w, (f_h)); + begh = 0; + endh = fh; + CurveFactory::curveLightBrightColor ( + params.colorappearance.curve, + params.colorappearance.curve2, + params.colorappearance.curve3, + hist16, dummy, + dummy, dummy, + customColCurve1, + customColCurve2, + customColCurve3, + 1); + + if(params.colorappearance.enabled) { + double adap; + float fnum = imgsrc->getMetaData()->getFNumber ();// F number + float fiso = imgsrc->getMetaData()->getISOSpeed () ;// ISO + float fspeed = imgsrc->getMetaData()->getShutterSpeed () ;//speed + float fcomp = imgsrc->getMetaData()->getExpComp ();//compensation + - + + if(fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f) { + adap = 2000.; + }//if no exif data or wrong + else { + float E_V = fcomp + log2 ((fnum * fnum) / fspeed / (fiso / 100.f)); + E_V += params.toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV + E_V += log2(params.raw.expos);// exposure raw white point ; log2 ==> linear to EV + adap = powf(2.f, E_V - 3.f); //cd / m2 + } + + LUTf CAMBrightCurveJ; + LUTf CAMBrightCurveQ; + float CAMMean = NAN; + + if (params.sharpening.enabled) { + if(settings->ciecamfloat) { + float d; + ipf.ciecam_02float (cieView, float(adap), begh, endh, 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, d, 1, 1); + } else { + double dd; + ipf.ciecam_02 (cieView, adap, begh, endh, 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, dd, 1, 1); + } + } else { + if(settings->ciecamfloat) { + float d; + ipf.ciecam_02float (cieView, float(adap), begh, endh, 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, d, 1, 1); + } else { + double dd; + ipf.ciecam_02 (cieView, adap, begh, endh, 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, dd, 1, 1); + } + } + } + + delete cieView; + cieView = nullptr; + + + + + // end tile processing...??? + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + if (pl) { + pl->setProgress (0.60); + } } - // RGB processing + Image16 *stage_7() + { + ProcessingJobImpl* job = static_cast(pjob); + procparams::ProcParams& params = job->pparams; + ImProcFunctions ipf (¶ms, true); + + int imw, imh; + double tmpScale = ipf.resizeScale(¶ms, fw, fh, imw, imh); + bool labResize = params.resize.enabled && params.resize.method != "Nearest" && tmpScale != 1.0; + LabImage *tmplab; - LUTf curve1 (65536); - LUTf curve2 (65536); - LUTf curve (65536, 0); - LUTf satcurve (65536, 0); - LUTf lhskcurve (65536, 0); - LUTf lumacurve(32770, 0); // lumacurve[32768] and lumacurve[32769] will be set to 32768 and 32769 later to allow linear interpolation - LUTf clcurve (65536, 0); + // crop and convert to rgb16 + int cx = 0, cy = 0, cw = labView->W, ch = labView->H; + + if (params.crop.enabled) { + cx = params.crop.x; + cy = params.crop.y; + cw = params.crop.w; + ch = params.crop.h; + + if(labResize) { // crop lab data + tmplab = new LabImage(cw, ch); + + for(int row = 0; row < ch; row++) { + for(int col = 0; col < cw; col++) { + tmplab->L[row][col] = labView->L[row + cy][col + cx]; + tmplab->a[row][col] = labView->a[row + cy][col + cx]; + tmplab->b[row][col] = labView->b[row + cy][col + cx]; + } + } + + delete labView; + labView = tmplab; + cx = 0; + cy = 0; + } + } + + if (labResize) { // resize lab data + // resize image + tmplab = new LabImage(imw, imh); + ipf.Lanczos (labView, tmplab, tmpScale); + delete labView; + labView = tmplab; + cw = labView->W; + ch = labView->H; + + if(params.prsharpening.enabled) { + for(int i = 0; i < ch; i++) + for(int j = 0; j < cw; j++) { + labView->L[i][j] = labView->L[i][j] < 0.f ? 0.f : labView->L[i][j]; + } + + float **buffer = new float*[ch]; + + for (int i = 0; i < ch; i++) { + buffer[i] = new float[cw]; + } + + ipf.sharpening (labView, (float**)buffer, params.prsharpening); + + for (int i = 0; i < ch; i++) { + delete [] buffer[i]; + } + + delete [] buffer; + } + } + + Image16* readyImg = nullptr; + cmsHPROFILE jprof = nullptr; + bool customGamma = false; + bool useLCMS = false; + bool bwonly = params.blackwhite.enabled && !params.colorToning.enabled && !autili && !butili ; + + if(params.icm.gamma != "default" || params.icm.freegamma) { // if select gamma output between BT709, sRGB, linear, low, high, 2.2 , 1.8 + + GammaValues ga; + // if(params.blackwhite.enabled) params.toneCurve.hrenabled=false; + readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm, bwonly, &ga); + customGamma = true; + + //or selected Free gamma + useLCMS = false; + + if ((jprof = iccStore->createCustomGammaOutputProfile (params.icm, ga)) == nullptr) { + useLCMS = true; + } + + } else { + // if Default gamma mode: we use the profile selected in the "Output profile" combobox; + // gamma come from the selected profile, otherwise it comes from "Free gamma" tool + + readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm, bwonly); + + if (settings->verbose) { + printf("Output profile_: \"%s\"\n", params.icm.output.c_str()); + } + } + + delete labView; + labView = nullptr; + + + + if(bwonly) { //force BW r=g=b + if (settings->verbose) { + printf("Force BW\n"); + } + + for (int ccw = 0; ccw < cw; ccw++) { + for (int cch = 0; cch < ch; cch++) { + readyImg->r(cch, ccw) = readyImg->g(cch, ccw); + readyImg->b(cch, ccw) = readyImg->g(cch, ccw); + } + } + } + + if (pl) { + pl->setProgress (0.70); + } + + if (tmpScale != 1.0 && params.resize.method == "Nearest") { // resize rgb data (gamma applied) + Image16* tempImage = new Image16 (imw, imh); + ipf.resize (readyImg, tempImage, tmpScale); + delete readyImg; + readyImg = tempImage; + } + + if (tunnelMetaData) { + readyImg->setMetadata (ii->getMetaData()->getExifData ()); + } else { + readyImg->setMetadata (ii->getMetaData()->getExifData (), params.exif, params.iptc); + } + + + // Setting the output curve to readyImg + if (customGamma) { + if (!useLCMS) { + // use corrected sRGB profile in order to apply a good TRC if present, otherwise use LCMS2 profile generated by lab2rgb16 w/ gamma + ProfileContent pc(jprof); + readyImg->setOutputProfile (pc.data, pc.length); + } + } else { + // use the selected output profile if present, otherwise use LCMS2 profile generate by lab2rgb16 w/ gamma + + if (params.icm.output != "" && params.icm.output != ColorManagementParams::NoICMString) { + + // if iccStore->getProfile send back an object, then iccStore->getContent will do too + cmsHPROFILE jprof = iccStore->getProfile(params.icm.output); //get outProfile + + if (jprof == nullptr) { + if (settings->verbose) { + printf("\"%s\" ICC output profile not found!\n - use LCMS2 substitution\n", params.icm.output.c_str()); + } + } else { + if (settings->verbose) { + printf("Using \"%s\" output profile\n", params.icm.output.c_str()); + } + + ProfileContent pc = iccStore->getContent (params.icm.output); + readyImg->setOutputProfile (pc.data, pc.length); + } + } else { + // No ICM + readyImg->setOutputProfile (nullptr, 0); + } + } + +// t2.set(); +// if( settings->verbose ) +// printf("Total:- %d usec\n", t2.etime(t1)); + + if (!job->initialImage) { + ii->decreaseRef (); + } + + delete job; + + if (pl) { + pl->setProgress (0.75); + } + + /* curve1.reset();curve2.reset(); + curve.reset(); + satcurve.reset(); + lhskcurve.reset(); + + rCurve.reset(); + gCurve.reset(); + bCurve.reset(); + hist16.reset(); + hist16C.reset(); + */ + return readyImg; + } + + void stage_early_resize() + { + ProcessingJobImpl* job = static_cast(pjob); + procparams::ProcParams& params = job->pparams; + ImProcFunctions ipf (¶ms, true); + + int imw, imh; + double tmpScale = ipf.resizeScale(¶ms, fw, fh, imw, imh); + // bool resize = params.resize.enabled; + + LabImage *tmplab = new LabImage(fw, fh); + ipf.rgb2lab(*baseImg, *tmplab, params.icm.working); + + // crop and convert to rgb16 + int cx = 0, cy = 0, cw = fw, ch = fh; + + if (params.crop.enabled) { + cx = params.crop.x; + cy = params.crop.y; + cw = params.crop.w; + ch = params.crop.h; + + 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]; + } + } + + delete tmplab; + tmplab = cropped; + cx = 0; + cy = 0; + + params.crop.enabled = false; + } + + if (params.resize.enabled) { + // resize image + LabImage *resized = new LabImage(imw, imh); + ipf.Lanczos(tmplab, resized, tmpScale); + delete tmplab; + tmplab = resized; + params.resize.enabled = false; + + if (params.prsharpening.enabled) { + params.sharpening = params.prsharpening; + } + + params.wavelet.strength = + int(float(params.wavelet.strength) * tmpScale); + params.dirpyrDenoise.luma *= tmpScale; + // params.dirpyrDenoise.smethod = "shal"; + + fw = imw; + fh = imh; + } + + delete baseImg; + baseImg = new Imagefloat(fw, fh); + ipf.lab2rgb(*tmplab, *baseImg, params.icm.working); + delete tmplab; + } + +private: + ProcessingJob* pjob; + 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 (65536, 0); + 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; - //if(params.blackwhite.enabled) params.toneCurve.hrenabled=false; - CurveFactory::complexCurve (expcomp, black / 65535.0, hlcompr, hlcomprthresh, params.toneCurve.shcompr, bright, contr, - params.toneCurve.curveMode, params.toneCurve.curve, params.toneCurve.curveMode2, params.toneCurve.curve2, - hist16, curve1, curve2, curve, dummy, customToneCurve1, customToneCurve2 ); + bool autili, butili; +}; - CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, 1); - CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, 1); - CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, 1); +} // namespace - bool opautili = false; - if(params.colorToning.enabled) { - TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); - double wp[3][3] = { - {wprof[0][0], wprof[0][1], wprof[0][2]}, - {wprof[1][0], wprof[1][1], wprof[1][2]}, - {wprof[2][0], wprof[2][1], wprof[2][2]} - }; - TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working); - double wip[3][3] = { - {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, - {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, - {wiprof[2][0], wiprof[2][1], wiprof[2][2]} - }; - params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); - clToningcurve (65536, 0); - CurveFactory::curveToning(params.colorToning.clcurve, clToningcurve, 1); - cl2Toningcurve (65536, 0); - CurveFactory::curveToning(params.colorToning.cl2curve, cl2Toningcurve, 1); - } - - LabImage* labView = new LabImage (fw, fh); - - if(params.blackwhite.enabled) { - CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 1); - } - - double rrm, ggm, bbm; - float autor, autog, autob; - float satLimit = float(params.colorToning.satProtectionThreshold) / 100.f * 0.7f + 0.3f; - float satLimitOpacity = 1.f - (float(params.colorToning.saturatedOpacity) / 100.f); - - if(params.colorToning.enabled && params.colorToning.autosat) { //for colortoning evaluation of saturation settings - float moyS = 0.f; - float eqty = 0.f; - ipf.moyeqt (baseImg, moyS, eqty);//return image : mean saturation and standard dev of saturation - float satp = ((moyS + 1.5f * eqty) - 0.3f) / 0.7f; //1.5 sigma ==> 93% pixels with high saturation -0.3 / 0.7 convert to Hombre scale - - if(satp >= 0.92f) { - satp = 0.92f; //avoid values too high (out of gamut) - } - - if(satp <= 0.15f) { - satp = 0.15f; //avoid too low values - } - - satLimit = 100.f * satp; - - satLimitOpacity = 100.f * (moyS - 0.85f * eqty); //-0.85 sigma==>20% pixels with low saturation - } - - autor = -9000.f; // This will ask to compute the "auto" values for the B&W tool (have to be inferior to -5000) - DCPProfile::ApplyState as; - DCPProfile *dcpProf = imgsrc->getDCP(params.icm, currWB, as); - - LUTu histToneCurve; - - ipf.rgbProc (baseImg, labView, nullptr, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, satLimit , satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh, dcpProf, as, histToneCurve); - - if (settings->verbose) { - printf("Output image / Auto B&W coefs: R=%.2f G=%.2f B=%.2f\n", autor, autog, autob); - } - - // if clut was used and size of clut cache == 1 we free the memory used by the clutstore (default clut cache size = 1 for 32 bit OS) - if ( params.filmSimulation.enabled && !params.filmSimulation.clutFilename.empty() && options.clutCacheSize == 1) { - CLUTStore::getInstance().clearCache(); - } - - // freeing up some memory - customToneCurve1.Reset(); - customToneCurve2.Reset(); - ctColorCurve.Reset(); - ctOpacityCurve.Reset(); - noiseLCurve.Reset(); - noiseCCurve.Reset(); - customToneCurvebw1.Reset(); - customToneCurvebw2.Reset(); - - // Freeing baseImg because not used anymore - delete baseImg; - baseImg = nullptr; - - if (shmap) { - delete shmap; - } - - shmap = nullptr; - - if (pl) { - pl->setProgress (0.55); - } - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - // start tile processing...??? - - - if(params.labCurve.contrast != 0) { //only use hist16 for contrast - hist16.clear(); - -#ifdef _OPENMP - #pragma omp parallel -#endif - { - LUTu hist16thr (hist16.getSize()); // one temporary lookup table per thread - hist16thr.clear(); -#ifdef _OPENMP - #pragma omp for schedule(static) nowait -#endif - - for (int i = 0; i < fh; i++) - for (int j = 0; j < fw; j++) { - hist16thr[(int)((labView->L[i][j]))]++; - } - - #pragma omp critical - { - hist16 += hist16thr; - } - } - } - - bool utili; - CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, hist16, lumacurve, dummy, 1, utili); - - bool clcutili; - CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, 1); - - bool autili, butili, ccutili, cclutili; - CurveFactory::complexsgnCurve (autili, butili, ccutili, cclutili, params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve, - params.labCurve.lccurve, curve1, curve2, satcurve, lhskcurve, 1); - - ipf.chromiLuminanceCurve (nullptr, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy); - - if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) { - ipf.EPDToneMap(labView, 5, 1); - } - - - ipf.vibrance(labView); - - if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { - ipf.impulsedenoise (labView); - } - - // for all treatments Defringe, Sharpening, Contrast detail ,Microcontrast they are activated if "CIECAM" function are disabled - - if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { - ipf.defringe (labView); - } - - if (params.sharpenEdge.enabled) { - ipf.MLsharpen(labView); - } - - if (params.sharpenMicro.enabled) { - if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { - ipf.MLmicrocontrast (labView); //!params.colorappearance.sharpcie - } - } - - if(((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) && params.sharpening.enabled) { - - float **buffer = new float*[fh]; - - for (int i = 0; i < fh; i++) { - buffer[i] = new float[fw]; - } - - ipf.sharpening (labView, (float**)buffer, params.sharpening); - - for (int i = 0; i < fh; i++) { - delete [] buffer[i]; - } - - delete [] buffer; - } - - WaveletParams WaveParams = params.wavelet; - WavCurve wavCLVCurve; - WavOpacityCurveRG waOpacityCurveRG; - WavOpacityCurveBY waOpacityCurveBY; - WavOpacityCurveW waOpacityCurveW; - WavOpacityCurveWL waOpacityCurveWL; - - params.wavelet.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL ); - - - // directional pyramid wavelet - if(params.dirpyrequalizer.cbdlMethod == "aft") { - if((params.colorappearance.enabled && !settings->autocielab) || !params.colorappearance.enabled) { - ipf.dirpyrequalizer (labView, 1); //TODO: this is the luminance tonecurve, not the RGB one - } - } - - bool wavcontlutili = false; - - CurveFactory::curveWavContL(wavcontlutili, params.wavelet.wavclCurve, wavclCurve,/* hist16C, dummy,*/ 1); - - if(params.wavelet.enabled) { - ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, wavcontlutili, 1); - } - - wavCLVCurve.Reset(); - - //Colorappearance and tone-mapping associated - - int f_w = 1, f_h = 1; - int begh = 0, endh = fh; - - if(params.colorappearance.tonecie || params.colorappearance.enabled) { - f_w = fw; - f_h = fh; - } - - CieImage *cieView = new CieImage (f_w, (f_h)); - begh = 0; - endh = fh; - CurveFactory::curveLightBrightColor ( - params.colorappearance.curve, - params.colorappearance.curve2, - params.colorappearance.curve3, - hist16, dummy, - dummy, dummy, - customColCurve1, - customColCurve2, - customColCurve3, - 1); - - if(params.colorappearance.enabled) { - double adap; - float fnum = imgsrc->getMetaData()->getFNumber ();// F number - float fiso = imgsrc->getMetaData()->getISOSpeed () ;// ISO - float fspeed = imgsrc->getMetaData()->getShutterSpeed () ;//speed - float fcomp = imgsrc->getMetaData()->getExpComp ();//compensation + - - - if(fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f) { - adap = 2000.; - }//if no exif data or wrong - else { - float E_V = fcomp + log2 ((fnum * fnum) / fspeed / (fiso / 100.f)); - E_V += params.toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV - E_V += log2(params.raw.expos);// exposure raw white point ; log2 ==> linear to EV - adap = powf(2.f, E_V - 3.f); //cd / m2 - } - - LUTf CAMBrightCurveJ; - LUTf CAMBrightCurveQ; - float CAMMean = NAN; - - if (params.sharpening.enabled) { - if(settings->ciecamfloat) { - float d; - ipf.ciecam_02float (cieView, float(adap), begh, endh, 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, d, 1, 1); - } else { - double dd; - ipf.ciecam_02 (cieView, adap, begh, endh, 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, dd, 1, 1); - } - } else { - if(settings->ciecamfloat) { - float d; - ipf.ciecam_02float (cieView, float(adap), begh, endh, 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, d, 1, 1); - } else { - double dd; - ipf.ciecam_02 (cieView, adap, begh, endh, 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, dd, 1, 1); - } - } - } - - delete cieView; - cieView = nullptr; - - - - - // end tile processing...??? - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - if (pl) { - pl->setProgress (0.60); - } - - int imw, imh; - double tmpScale = ipf.resizeScale(¶ms, fw, fh, imw, imh); - bool labResize = params.resize.enabled && params.resize.method != "Nearest" && tmpScale != 1.0; - LabImage *tmplab; - - // crop and convert to rgb16 - int cx = 0, cy = 0, cw = labView->W, ch = labView->H; - - if (params.crop.enabled) { - cx = params.crop.x; - cy = params.crop.y; - cw = params.crop.w; - ch = params.crop.h; - - if(labResize) { // crop lab data - tmplab = new LabImage(cw, ch); - - for(int row = 0; row < ch; row++) { - for(int col = 0; col < cw; col++) { - tmplab->L[row][col] = labView->L[row + cy][col + cx]; - tmplab->a[row][col] = labView->a[row + cy][col + cx]; - tmplab->b[row][col] = labView->b[row + cy][col + cx]; - } - } - - delete labView; - labView = tmplab; - cx = 0; - cy = 0; - } - } - - if (labResize) { // resize lab data - // resize image - tmplab = new LabImage(imw, imh); - ipf.Lanczos (labView, tmplab, tmpScale); - delete labView; - labView = tmplab; - cw = labView->W; - ch = labView->H; - - if(params.prsharpening.enabled) { - for(int i = 0; i < ch; i++) - for(int j = 0; j < cw; j++) { - labView->L[i][j] = labView->L[i][j] < 0.f ? 0.f : labView->L[i][j]; - } - - float **buffer = new float*[ch]; - - for (int i = 0; i < ch; i++) { - buffer[i] = new float[cw]; - } - - ipf.sharpening (labView, (float**)buffer, params.prsharpening); - - for (int i = 0; i < ch; i++) { - delete [] buffer[i]; - } - - delete [] buffer; - } - } - - Image16* readyImg = nullptr; - cmsHPROFILE jprof = nullptr; - bool customGamma = false; - bool useLCMS = false; - bool bwonly = params.blackwhite.enabled && !params.colorToning.enabled && !autili && !butili ; - - if(params.icm.gamma != "default" || params.icm.freegamma) { // if select gamma output between BT709, sRGB, linear, low, high, 2.2 , 1.8 - - GammaValues ga; - // if(params.blackwhite.enabled) params.toneCurve.hrenabled=false; - readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm, bwonly, &ga); - customGamma = true; - - //or selected Free gamma - useLCMS = false; - - if ((jprof = iccStore->createCustomGammaOutputProfile (params.icm, ga)) == nullptr) { - useLCMS = true; - } - - } else { - // if Default gamma mode: we use the profile selected in the "Output profile" combobox; - // gamma come from the selected profile, otherwise it comes from "Free gamma" tool - - readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm, bwonly); - - if (settings->verbose) { - printf("Output profile_: \"%s\"\n", params.icm.output.c_str()); - } - } - - delete labView; - labView = nullptr; - - - - if(bwonly) { //force BW r=g=b - if (settings->verbose) { - printf("Force BW\n"); - } - - for (int ccw = 0; ccw < cw; ccw++) { - for (int cch = 0; cch < ch; cch++) { - readyImg->r(cch, ccw) = readyImg->g(cch, ccw); - readyImg->b(cch, ccw) = readyImg->g(cch, ccw); - } - } - } - - if (pl) { - pl->setProgress (0.70); - } - - if (tmpScale != 1.0 && params.resize.method == "Nearest") { // resize rgb data (gamma applied) - Image16* tempImage = new Image16 (imw, imh); - ipf.resize (readyImg, tempImage, tmpScale); - delete readyImg; - readyImg = tempImage; - } - - if (tunnelMetaData) { - readyImg->setMetadata (ii->getMetaData()->getExifData ()); - } else { - readyImg->setMetadata (ii->getMetaData()->getExifData (), params.exif, params.iptc); - } - - - // Setting the output curve to readyImg - if (customGamma) { - if (!useLCMS) { - // use corrected sRGB profile in order to apply a good TRC if present, otherwise use LCMS2 profile generated by lab2rgb16 w/ gamma - ProfileContent pc(jprof); - readyImg->setOutputProfile (pc.data, pc.length); - } - } else { - // use the selected output profile if present, otherwise use LCMS2 profile generate by lab2rgb16 w/ gamma - - if (params.icm.output != "" && params.icm.output != ColorManagementParams::NoICMString) { - - // if iccStore->getProfile send back an object, then iccStore->getContent will do too - cmsHPROFILE jprof = iccStore->getProfile(params.icm.output); //get outProfile - - if (jprof == nullptr) { - if (settings->verbose) { - printf("\"%s\" ICC output profile not found!\n - use LCMS2 substitution\n", params.icm.output.c_str()); - } - } else { - if (settings->verbose) { - printf("Using \"%s\" output profile\n", params.icm.output.c_str()); - } - - ProfileContent pc = iccStore->getContent (params.icm.output); - readyImg->setOutputProfile (pc.data, pc.length); - } - } else { - // No ICM - readyImg->setOutputProfile (nullptr, 0); - } - } - -// t2.set(); -// if( settings->verbose ) -// printf("Total:- %d usec\n", t2.etime(t1)); - - if (!job->initialImage) { - ii->decreaseRef (); - } - - delete job; - - if (pl) { - pl->setProgress (0.75); - } - - /* curve1.reset();curve2.reset(); - curve.reset(); - satcurve.reset(); - lhskcurve.reset(); - - rCurve.reset(); - gCurve.reset(); - bCurve.reset(); - hist16.reset(); - hist16C.reset(); - */ - return readyImg; +IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* pl, bool tunnelMetaData, bool flush) +{ + ImageProcessor proc(pjob, errorCode, pl, tunnelMetaData, flush); + return proc(true); } void batchProcessingThread (ProcessingJob* job, BatchProcessingListener* bpl, bool tunnelMetaData) From 93296cff17d93b14b033ee63164a68eb72632bbd Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 8 Mar 2017 00:50:50 +0100 Subject: [PATCH 02/33] continuing with my experiments on an alternative "fast export" --- rtengine/processingjob.cc | 8 ++++---- rtengine/processingjob.h | 9 ++++---- rtengine/rtengine.h | 4 ++-- rtengine/simpleprocess.cc | 43 +++++++++++++++++++-------------------- rtgui/batchqueue.cc | 9 ++++++-- rtgui/filebrowser.cc | 6 +++++- rtgui/filecatalog.cc | 4 ++-- rtgui/main.cc | 8 +++++++- 8 files changed, 53 insertions(+), 38 deletions(-) diff --git a/rtengine/processingjob.cc b/rtengine/processingjob.cc index 612edc2a2..a377e3963 100644 --- a/rtengine/processingjob.cc +++ b/rtengine/processingjob.cc @@ -21,16 +21,16 @@ 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) diff --git a/rtengine/processingjob.h b/rtengine/processingjob.h index 2de426a31..fd3fe82a8 100644 --- a/rtengine/processingjob.h +++ b/rtengine/processingjob.h @@ -32,12 +32,13 @@ public: bool isRaw; InitialImage* initialImage; procparams::ProcParams pparams; + bool fast; - ProcessingJobImpl (const Glib::ustring& fn, bool iR, const procparams::ProcParams& pp) - : fname(fn), isRaw(iR), initialImage(nullptr), pparams(pp) {} + ProcessingJobImpl (const Glib::ustring& fn, bool iR, const procparams::ProcParams& pp, bool ff) + : fname(fn), isRaw(iR), initialImage(nullptr), pparams(pp), fast(ff) {} - ProcessingJobImpl (InitialImage* iImage, const procparams::ProcParams& pp) - : fname(""), isRaw(true), initialImage(iImage), pparams(pp) + ProcessingJobImpl (InitialImage* iImage, const procparams::ProcParams& pp, bool ff) + : fname(""), isRaw(true), initialImage(iImage), pparams(pp), fast(ff) { iImage->increaseRef(); } diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index fc793dd71..4cb672e15 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -468,7 +468,7 @@ public: * @param isRaw shall be true if it is a raw file * @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. */ - 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 * the image thus it returns immediately. This function increases the reference count of the initialImage. If you decide not the process the image you @@ -477,7 +477,7 @@ public: * @param initialImage is a loaded and pre-processed initial image * @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. */ - 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 * gets invalid, you must not use it any more. Dont call this function while the job is being processed. diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index e027968a5..677f912fc 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -41,7 +41,7 @@ class ImageProcessor { public: ImageProcessor(ProcessingJob* pjob, int& errorCode, ProgressListener* pl, bool tunnelMetaData, bool flush): - pjob(pjob), + job(static_cast(pjob)), errorCode(errorCode), pl(pl), tunnelMetaData(tunnelMetaData), @@ -55,9 +55,9 @@ public: { } - Image16 *operator()(bool fast) + Image16 *operator()() { - if (!fast) { + if (!job->fast) { return normal_pipeline(); } else { return fast_pipeline(); @@ -81,21 +81,28 @@ private: Image16 *fast_pipeline() { - ProcessingJobImpl* job = static_cast(pjob); if (!job->pparams.resize.enabled) { return normal_pipeline(); } + + pl = nullptr; if (!stage_1()) { return nullptr; } + stage_calc_denoise(); + printf("after calc denoise\n"); fflush(stdout); stage_2(); stage_4(); + printf("after 4\n"); fflush(stdout); stage_early_resize(); - stage_calc_denoise(); + printf("after early resize\n"); fflush(stdout); stage_3(); + printf("after 3\n"); fflush(stdout); stage_5(); + printf("after 5\n"); fflush(stdout); stage_6(); + printf("after 6\n"); fflush(stdout); return stage_7(); } @@ -103,8 +110,6 @@ private: { errorCode = 0; - ProcessingJobImpl* job = static_cast(pjob); - if (pl) { pl->setProgressStr ("PROGRESSBAR_PROCESSING"); pl->setProgress (0.0); @@ -235,7 +240,6 @@ private: void stage_calc_denoise() { - ProcessingJobImpl* job = static_cast(pjob); procparams::ProcParams& params = job->pparams; ImProcFunctions ipf (¶ms, true); @@ -714,7 +718,6 @@ private: void stage_2() { - ProcessingJobImpl* job = static_cast(pjob); procparams::ProcParams& params = job->pparams; ImProcFunctions ipf (¶ms, true); @@ -753,7 +756,6 @@ private: void stage_3() { - ProcessingJobImpl* job = static_cast(pjob); procparams::ProcParams& params = job->pparams; ImProcFunctions ipf (¶ms, true); @@ -826,7 +828,6 @@ private: void stage_4() { - ProcessingJobImpl* job = static_cast(pjob); procparams::ProcParams& params = job->pparams; ImProcFunctions ipf (¶ms, true); @@ -849,7 +850,6 @@ private: void stage_5() { - ProcessingJobImpl* job = static_cast(pjob); procparams::ProcParams& params = job->pparams; ImProcFunctions ipf (¶ms, true); @@ -994,7 +994,6 @@ private: void stage_6() { - ProcessingJobImpl* job = static_cast(pjob); procparams::ProcParams& params = job->pparams; ImProcFunctions ipf (¶ms, true); @@ -1192,7 +1191,6 @@ private: Image16 *stage_7() { - ProcessingJobImpl* job = static_cast(pjob); procparams::ProcParams& params = job->pparams; ImProcFunctions ipf (¶ms, true); @@ -1389,7 +1387,6 @@ private: void stage_early_resize() { - ProcessingJobImpl* job = static_cast(pjob); procparams::ProcParams& params = job->pparams; ImProcFunctions ipf (¶ms, true); @@ -1435,14 +1432,16 @@ private: tmplab = resized; params.resize.enabled = false; - if (params.prsharpening.enabled) { - params.sharpening = params.prsharpening; - } - + params.sharpening = params.prsharpening; params.wavelet.strength = int(float(params.wavelet.strength) * tmpScale); params.dirpyrDenoise.luma *= tmpScale; - // params.dirpyrDenoise.smethod = "shal"; + params.dirpyrDenoise.smethod = "shal"; + + for (int i = 0; i < 6; ++i) { + auto &n = params.dirpyrequalizer.mult[i]; + n = 1.0 + (n - 1.0) * tmpScale; + } fw = imw; fh = imh; @@ -1455,7 +1454,7 @@ private: } private: - ProcessingJob* pjob; + ProcessingJobImpl* job; int& errorCode; ProgressListener* pl; bool tunnelMetaData; @@ -1534,7 +1533,7 @@ private: IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* pl, bool tunnelMetaData, bool flush) { ImageProcessor proc(pjob, errorCode, pl, tunnelMetaData, flush); - return proc(true); + return proc(); } void batchProcessingThread (ProcessingJob* job, BatchProcessingListener* bpl, bool tunnelMetaData) diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 7bd53c444..1f2dac51d 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -34,6 +34,9 @@ #include "guiutils.h" #include "rtimage.h" #include + +#include "../rtengine/processingjob.h" + using namespace std; using namespace rtengine; @@ -227,7 +230,7 @@ bool BatchQueue::saveBatchQueue () // 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|" - << "png bit depth|png compression|tiff bit depth|uncompressed tiff|save output params|force format options|" + << "png bit depth|png compression|tiff bit depth|uncompressed tiff|save output params|force format options|fast export|" << std::endl; // method is already running with entryLock, so no need to lock again @@ -242,6 +245,7 @@ bool BatchQueue::saveBatchQueue () << saveFormat.pngBits << '|' << saveFormat.pngCompression << '|' << saveFormat.tiffBits << '|' << saveFormat.tiffUncompressed << '|' << saveFormat.saveParams << '|' << entry->forceFormatOpts << '|' + << static_cast(entry->job)->fast << '|' << std::endl; } } @@ -308,6 +312,7 @@ bool BatchQueue::loadBatchQueue () const auto tiffUncompressed = nextIntOr (options.saveFormat.tiffUncompressed); const auto saveParams = nextIntOr (options.saveFormat.saveParams); const auto forceFormatOpts = nextIntOr (options.forceFormatOpts); + const auto fast = nextIntOr(false); rtengine::procparams::ProcParams pparams; @@ -319,7 +324,7 @@ bool BatchQueue::loadBatchQueue () if (!thumb) 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 prevw = prevh; diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 5cbb5255b..24d1d8541 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -389,6 +389,7 @@ FileBrowser::FileBrowser () 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); 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); 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); @@ -1139,9 +1140,12 @@ bool FileBrowser::keyPressed (GdkEventKey* event) } else if (event->keyval == GDK_KEY_Delete && shift) { menuItemActivated (untrash); 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); 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) { menuItemActivated (selall); return true; diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index a876dd54e..99c190cde 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -1094,7 +1094,7 @@ void FileCatalog::developRequested (std::vector tbe, bool fas // controlling time and resource consuming tasks // and also those which effect is not pronounced after reducing the image size // TODO!!! could expose selections below via preferences - if (fastmode) { + if (fastmode && false) { if (options.fastexport_bypass_sharpening ) { params.sharpening.enabled = false; } @@ -1187,7 +1187,7 @@ void FileCatalog::developRequested (std::vector tbe, bool fas params.resize.height = options.fastexport_resize_height ; } - rtengine::ProcessingJob* pjob = rtengine::ProcessingJob::create (fbe->filename, th->getType() == FT_Raw, params); + rtengine::ProcessingJob* pjob = rtengine::ProcessingJob::create (fbe->filename, th->getType() == FT_Raw, params, fastmode); int pw; int ph = BatchQueue::calcMaxThumbnailHeight(); diff --git a/rtgui/main.cc b/rtgui/main.cc index ee3d3210e..7e11825a2 100644 --- a/rtgui/main.cc +++ b/rtgui/main.cc @@ -83,6 +83,8 @@ Glib::ustring fname_to_utf8 (const char* fname) #endif } +bool fast_export = false; + } // This recursive mutex will be used by gdk_threads_enter/leave instead of a simple mutex @@ -537,6 +539,10 @@ int processLineParams( int argc, char **argv ) compression = -1; break; + case 'f': + fast_export = true; + break; + case 'c': // MUST be last option while (iArg + 1 < argc) { iArg++; @@ -845,7 +851,7 @@ int processLineParams( int argc, char **argv ) continue; } - job = rtengine::ProcessingJob::create (ii, currentParams); + job = rtengine::ProcessingJob::create (ii, currentParams, fast_export); if( !job ) { errors++; From 44505ccb0844a6ef9823cdbd82cca2ca299161fc Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 8 Mar 2017 22:55:08 +0100 Subject: [PATCH 03/33] some enhancements of the Fast Export functionality - remember fast export options across RT sessions - added option to use a dedicated "Fast Export" pipeline, trading speed for quality (resizes early instead of at the end) --- rtdata/languages/default | 2 + rtengine/processingjob.h | 2 + rtengine/rtengine.h | 2 + rtengine/simpleprocess.cc | 86 ++++++++------------------------------- rtgui/batchqueue.cc | 4 +- rtgui/exportpanel.cc | 64 +++++++++++++++++++---------- rtgui/exportpanel.h | 1 + rtgui/filecatalog.cc | 8 ++-- rtgui/options.cc | 5 +++ rtgui/options.h | 1 + 10 files changed, 76 insertions(+), 99 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 31b14aa2f..f47d09e5d 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -80,6 +80,8 @@ EXPORT_BYPASS_SHARPENEDGE;Bypass Edge Sharpening EXPORT_BYPASS_SHARPENING;Bypass Sharpening EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast EXPORT_BYPASS_SH_HQ;Bypass Sharp Mask Shadows/Highlights +EXPORT_USE_FAST_PIPELINE;Enable Special "Fast-Export" Processing Pipeline +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;Fast Export Options 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: diff --git a/rtengine/processingjob.h b/rtengine/processingjob.h index fd3fe82a8..c7f49192e 100644 --- a/rtengine/processingjob.h +++ b/rtengine/processingjob.h @@ -49,6 +49,8 @@ public: initialImage->decreaseRef(); } } + + bool fastPipeline() const { return fast; } }; } diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 4cb672e15..7449dbd0d 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -483,6 +483,8 @@ public: * 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 */ 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. diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 677f912fc..3b450c492 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -67,16 +67,12 @@ public: private: Image16 *normal_pipeline() { - if (!stage_1()) { + if (!stage_init()) { return nullptr; } - stage_calc_denoise(); - stage_2(); - stage_3(); - stage_4(); - stage_5(); - stage_6(); - return stage_7(); + stage_denoise(); + stage_transform(); + return stage_finish(); } Image16 *fast_pipeline() @@ -87,26 +83,16 @@ private: pl = nullptr; - if (!stage_1()) { + if (!stage_init()) { return nullptr; } - stage_calc_denoise(); - printf("after calc denoise\n"); fflush(stdout); - stage_2(); - stage_4(); - printf("after 4\n"); fflush(stdout); + stage_transform(); stage_early_resize(); - printf("after early resize\n"); fflush(stdout); - stage_3(); - printf("after 3\n"); fflush(stdout); - stage_5(); - printf("after 5\n"); fflush(stdout); - stage_6(); - printf("after 6\n"); fflush(stdout); - return stage_7(); + stage_denoise(); + return stage_finish(); } - bool stage_1() + bool stage_init() { errorCode = 0; @@ -230,19 +216,6 @@ private: currWB.update(rm, gm, bm, params.wb.equal, params.wb.tempBias); } - // // AG begin - // baseImg = new Imagefloat (fw, fh); - // imgsrc->getImage (currWB, tr, baseImg, pp, params.toneCurve, params.icm, params.raw); - // // AG end - - return true; - } - - void stage_calc_denoise() - { - procparams::ProcParams& params = job->pparams; - ImProcFunctions ipf (¶ms, true); - calclum = nullptr ; params.dirpyrDenoise.getCurves(noiseLCurve, noiseCCurve); autoNR = (float) settings->nrauto;// @@ -713,14 +686,6 @@ private: //end evaluate noise } - // return true; - } - - void stage_2() - { - procparams::ProcParams& params = job->pparams; - ImProcFunctions ipf (¶ms, true); - baseImg = new Imagefloat (fw, fh); imgsrc->getImage (currWB, tr, baseImg, pp, params.toneCurve, params.icm, params.raw); @@ -752,9 +717,11 @@ private: imgsrc->flushRawData(); imgsrc->flushRGB(); } + + return true; } - void stage_3() + void stage_denoise() { procparams::ProcParams& params = job->pparams; ImProcFunctions ipf (¶ms, true); @@ -816,17 +783,9 @@ private: delete [] ry; delete [] sk; delete [] pcsk; - - // imgsrc->convertColorSpace(baseImg, params.icm, currWB); - - // // perform first analysis - // hist16 (65536); - - // ipf.firstAnalysis (baseImg, params, hist16); } - - void stage_4() + void stage_transform() { procparams::ProcParams& params = job->pparams; ImProcFunctions ipf (¶ms, true); @@ -848,7 +807,7 @@ private: } } - void stage_5() + Image16 *stage_finish() { procparams::ProcParams& params = job->pparams; ImProcFunctions ipf (¶ms, true); @@ -990,13 +949,7 @@ private: if (pl) { pl->setProgress (0.55); } - } - void stage_6() - { - procparams::ProcParams& params = job->pparams; - ImProcFunctions ipf (¶ms, true); - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // start tile processing...??? @@ -1187,13 +1140,7 @@ private: if (pl) { pl->setProgress (0.60); } - } - Image16 *stage_7() - { - procparams::ProcParams& params = job->pparams; - ImProcFunctions ipf (¶ms, true); - int imw, imh; double tmpScale = ipf.resizeScale(¶ms, fw, fh, imw, imh); bool labResize = params.resize.enabled && params.resize.method != "Nearest" && tmpScale != 1.0; @@ -1392,12 +1339,10 @@ private: int imw, imh; double tmpScale = ipf.resizeScale(¶ms, fw, fh, imw, imh); - // bool resize = params.resize.enabled; LabImage *tmplab = new LabImage(fw, fh); ipf.rgb2lab(*baseImg, *tmplab, params.icm.working); - // crop and convert to rgb16 int cx = 0, cy = 0, cw = fw, ch = fh; if (params.crop.enabled) { @@ -1438,9 +1383,10 @@ private: params.dirpyrDenoise.luma *= tmpScale; params.dirpyrDenoise.smethod = "shal"; + const double dirpyreq_scale = min(tmpScale * 1.5, 1.0); for (int i = 0; i < 6; ++i) { auto &n = params.dirpyrequalizer.mult[i]; - n = 1.0 + (n - 1.0) * tmpScale; + n = 1.0 + (n - 1.0) * dirpyreq_scale; } fw = imw; diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 1f2dac51d..a02046e01 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -35,8 +35,6 @@ #include "rtimage.h" #include -#include "../rtengine/processingjob.h" - using namespace std; using namespace rtengine; @@ -245,7 +243,7 @@ bool BatchQueue::saveBatchQueue () << saveFormat.pngBits << '|' << saveFormat.pngCompression << '|' << saveFormat.tiffBits << '|' << saveFormat.tiffUncompressed << '|' << saveFormat.saveParams << '|' << entry->forceFormatOpts << '|' - << static_cast(entry->job)->fast << '|' + << entry->job->fastPipeline() << '|' << std::endl; } } diff --git a/rtgui/exportpanel.cc b/rtgui/exportpanel.cc index 3f7be7ab4..fe18cdef7 100644 --- a/rtgui/exportpanel.cc +++ b/rtgui/exportpanel.cc @@ -39,6 +39,8 @@ ExportPanel::ExportPanel () : listener (nullptr) pack_start(*labExportTitle, Gtk::PACK_SHRINK, 4); bypass_ALL = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_ALL"))); + use_fast_pipeline = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_USE_FAST_PIPELINE"))); + use_fast_pipeline->set_tooltip_text(M("EXPORT_USE_FAST_PIPELINE_TIP")); bypass_sharpening = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_SHARPENING"))); bypass_sharpenEdge = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_SHARPENEDGE"))); bypass_sharpenMicro = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_SHARPENMICRO"))); @@ -96,6 +98,7 @@ ExportPanel::ExportPanel () : listener (nullptr) // ---------------------------------------------------------------- // start global packing + pack_start(*use_fast_pipeline , Gtk::PACK_SHRINK, 4); pack_start(*bypass_ALL , Gtk::PACK_SHRINK, 4); pack_start(*Gtk::manage(new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 4); pack_start(*bypass_sharpening , Gtk::PACK_SHRINK, 4); @@ -224,40 +227,48 @@ void ExportPanel::FastExportPressed () 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 - options.fastexport_bypass_sharpening = bypass_sharpening->get_active (); - options.fastexport_bypass_sharpenEdge = bypass_sharpenEdge->get_active (); - options.fastexport_bypass_sharpenMicro = bypass_sharpenMicro->get_active (); + FE_OPT_STORE_(options.fastexport_bypass_sharpening, bypass_sharpening->get_active ()); + FE_OPT_STORE_(options.fastexport_bypass_sharpenEdge, bypass_sharpenEdge->get_active ()); + FE_OPT_STORE_(options.fastexport_bypass_sharpenMicro, bypass_sharpenMicro->get_active ()); //options.fastexport_bypass_lumaDenoise = bypass_lumaDenoise->get_active (); //options.fastexport_bypass_colorDenoise = bypass_colorDenoise->get_active (); - options.fastexport_bypass_defringe = bypass_defringe->get_active (); - options.fastexport_bypass_dirpyrDenoise = bypass_dirpyrDenoise->get_active (); - options.fastexport_bypass_sh_hq = bypass_sh_hq->get_active (); - options.fastexport_bypass_dirpyrequalizer = bypass_dirpyrequalizer->get_active (); - options.fastexport_bypass_wavelet = bypass_wavelet->get_active (); + FE_OPT_STORE_(options.fastexport_bypass_defringe, bypass_defringe->get_active ()); + FE_OPT_STORE_(options.fastexport_bypass_dirpyrDenoise, bypass_dirpyrDenoise->get_active ()); + FE_OPT_STORE_(options.fastexport_bypass_sh_hq, bypass_sh_hq->get_active ()); + FE_OPT_STORE_(options.fastexport_bypass_dirpyrequalizer, bypass_dirpyrequalizer->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_dcb_iterations = bypass_raw_bayer_dcb_iterations->get_active (); - 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(); - options.fastexport_bypass_raw_bayer_linenoise = bypass_raw_bayer_linenoise->get_active (); - options.fastexport_bypass_raw_bayer_greenthresh = bypass_raw_bayer_greenthresh->get_active (); - options.fastexport_bypass_raw_ccSteps = bypass_raw_ccSteps->get_active (); - options.fastexport_bypass_raw_ca = bypass_raw_ca->get_active (); - 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_bayer_dcb_iterations, bypass_raw_bayer_dcb_iterations->get_active ()); + FE_OPT_STORE_(options.fastexport_bypass_raw_bayer_dcb_enhance, bypass_raw_bayer_dcb_enhance->get_active ()); + FE_OPT_STORE_(options.fastexport_bypass_raw_bayer_lmmse_iterations, bypass_raw_bayer_lmmse_iterations->get_active()); + FE_OPT_STORE_(options.fastexport_bypass_raw_bayer_linenoise, bypass_raw_bayer_linenoise->get_active ()); + FE_OPT_STORE_(options.fastexport_bypass_raw_bayer_greenthresh, bypass_raw_bayer_greenthresh->get_active ()); + FE_OPT_STORE_(options.fastexport_bypass_raw_ccSteps, bypass_raw_ccSteps->get_active ()); + FE_OPT_STORE_(options.fastexport_bypass_raw_ca, bypass_raw_ca->get_active ()); + FE_OPT_STORE_(options.fastexport_bypass_raw_df, bypass_raw_df->get_active ()); + FE_OPT_STORE_(options.fastexport_bypass_raw_ff, bypass_raw_ff->get_active ()); //saving Bayer demosaic_method int currentRow = raw_bayer_method->get_active_row_number(); 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 currentRow = raw_xtrans_method->get_active_row_number(); 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 ; @@ -269,9 +280,16 @@ void ExportPanel::SaveSettingsAsDefault() // options.fastexport_resize_appliesTo = resize_appliesTo; // options.fastexport_resize_dataspec = resize_dataspec ; - options.fastexport_resize_method = "Lanczos"; - options.fastexport_resize_width = MaxWidth->get_value_as_int (); - options.fastexport_resize_height = MaxHeight->get_value_as_int (); + FE_OPT_STORE_(options.fastexport_resize_method, "Lanczos"); + FE_OPT_STORE_(options.fastexport_resize_width, MaxWidth->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() @@ -327,6 +345,8 @@ void ExportPanel::LoadDefaultSettings() MaxWidth->set_value(options.fastexport_resize_width); MaxHeight->set_value(options.fastexport_resize_height); + + use_fast_pipeline->set_active(options.fastexport_use_fast_pipeline); } void ExportPanel::LoadSettings() diff --git a/rtgui/exportpanel.h b/rtgui/exportpanel.h index 840a4638d..ce7639921 100644 --- a/rtgui/exportpanel.h +++ b/rtgui/exportpanel.h @@ -38,6 +38,7 @@ protected: //Gtk::CheckButton* enabled; Gtk::CheckButton* bypass_ALL; + Gtk::CheckButton* use_fast_pipeline; Gtk::CheckButton* bypass_sharpenEdge; Gtk::CheckButton* bypass_sharpenMicro; Gtk::CheckButton* bypass_sharpening; diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index 99c190cde..68219d745 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -1094,7 +1094,7 @@ void FileCatalog::developRequested (std::vector tbe, bool fas // controlling time and resource consuming tasks // and also those which effect is not pronounced after reducing the image size // TODO!!! could expose selections below via preferences - if (fastmode && false) { + if (fastmode) { if (options.fastexport_bypass_sharpening ) { params.sharpening.enabled = false; } @@ -1183,11 +1183,11 @@ void FileCatalog::developRequested (std::vector tbe, bool fas 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 ; + params.resize.width = rtengine::min(params.resize.width, options.fastexport_resize_width) ; + params.resize.height = rtengine::min(params.resize.height, options.fastexport_resize_height) ; } - rtengine::ProcessingJob* pjob = rtengine::ProcessingJob::create (fbe->filename, th->getType() == FT_Raw, params, fastmode); + rtengine::ProcessingJob* pjob = rtengine::ProcessingJob::create (fbe->filename, th->getType() == FT_Raw, params, fastmode && options.fastexport_use_fast_pipeline); int pw; int ph = BatchQueue::calcMaxThumbnailHeight(); diff --git a/rtgui/options.cc b/rtgui/options.cc index 2f71a7106..9a8b5e08b 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -480,6 +480,7 @@ void Options::setDefaults () fastexport_resize_dataspec = 3; fastexport_resize_width = 900; fastexport_resize_height = 900; + fastexport_use_fast_pipeline = false; clutsDir = "./cluts"; @@ -1784,6 +1785,9 @@ int Options::readFromFile (Glib::ustring fname) if (keyFile.has_key ("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")) { @@ -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_width", fastexport_resize_width ); 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", "LastDarkframeDir", lastDarkframeDir); diff --git a/rtgui/options.h b/rtgui/options.h index efc649417..b853c07f6 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -279,6 +279,7 @@ public: int fastexport_resize_dataspec; int fastexport_resize_width; int fastexport_resize_height; + bool fastexport_use_fast_pipeline; // Dialog settings Glib::ustring lastIccDir; From 64661e1a2711ce38ef7c85baea49d81f2892ada1 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Thu, 9 Mar 2017 00:05:27 +0100 Subject: [PATCH 04/33] set dirpyrDenoise.median=false in the fast export pipeline --- rtengine/simpleprocess.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 3b450c492..774ee6c5c 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1382,6 +1382,7 @@ private: int(float(params.wavelet.strength) * tmpScale); params.dirpyrDenoise.luma *= tmpScale; params.dirpyrDenoise.smethod = "shal"; + params.dirpyrDenoise.median = false; const double dirpyreq_scale = min(tmpScale * 1.5, 1.0); for (int i = 0; i < 6; ++i) { From 359b4136b52f90c431665ccd36fdfcb98ef9edcc Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Fri, 10 Mar 2017 10:53:10 +0100 Subject: [PATCH 05/33] do not use the hard-coded (i.e. not user-selectable) fast export options if the new fast pipeline is selected --- rtengine/simpleprocess.cc | 2 +- rtgui/filecatalog.cc | 52 ++++++++++++++++++++++----------------- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 774ee6c5c..f10378a07 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1381,8 +1381,8 @@ private: params.wavelet.strength = int(float(params.wavelet.strength) * tmpScale); params.dirpyrDenoise.luma *= tmpScale; + params.dirpyrDenoise.smethod = "shal"; - params.dirpyrDenoise.median = false; const double dirpyreq_scale = min(tmpScale * 1.5, 1.0); for (int i = 0; i < 6; ++i) { diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index 68219d745..a5b3cdb85 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -1129,25 +1129,27 @@ void FileCatalog::developRequested (std::vector tbe, bool fas params.wavelet.enabled = false; } - //if (options.fastexport_bypass_raw_bayer_all_enhance ) params.raw.bayersensor.all_enhance = false; - if (options.fastexport_bypass_raw_bayer_dcb_iterations ) { - params.raw.bayersensor.dcb_iterations = 0; - } + if (!options.fastexport_use_fast_pipeline) { + //if (options.fastexport_bypass_raw_bayer_all_enhance ) params.raw.bayersensor.all_enhance = false; + if (options.fastexport_bypass_raw_bayer_dcb_iterations ) { + params.raw.bayersensor.dcb_iterations = 0; + } - if (options.fastexport_bypass_raw_bayer_dcb_enhance ) { - params.raw.bayersensor.dcb_enhance = false; - } + if (options.fastexport_bypass_raw_bayer_dcb_enhance ) { + params.raw.bayersensor.dcb_enhance = false; + } - if (options.fastexport_bypass_raw_bayer_lmmse_iterations) { - params.raw.bayersensor.lmmse_iterations = 0; - } + if (options.fastexport_bypass_raw_bayer_lmmse_iterations) { + params.raw.bayersensor.lmmse_iterations = 0; + } - if (options.fastexport_bypass_raw_bayer_linenoise ) { - params.raw.bayersensor.linenoise = 0; - } + if (options.fastexport_bypass_raw_bayer_linenoise ) { + params.raw.bayersensor.linenoise = 0; + } - if (options.fastexport_bypass_raw_bayer_greenthresh ) { - params.raw.bayersensor.greenthresh = 0; + if (options.fastexport_bypass_raw_bayer_greenthresh ) { + params.raw.bayersensor.greenthresh = 0; + } } if (options.fastexport_bypass_raw_ccSteps ) { @@ -1170,14 +1172,18 @@ void FileCatalog::developRequested (std::vector tbe, bool fas params.raw.ff_file = ""; } - params.raw.bayersensor.method = options.fastexport_raw_bayer_method ; - params.raw.xtranssensor.method = options.fastexport_raw_xtrans_method; - params.icm.input = options.fastexport_icm_input ; - params.icm.working = options.fastexport_icm_working ; - params.icm.output = options.fastexport_icm_output ; - params.icm.outputIntent = options.fastexport_icm_outputIntent ; - params.icm.outputBPC = options.fastexport_icm_outputBPC ; - params.icm.gamma = options.fastexport_icm_gamma ; + + if (!options.fastexport_use_fast_pipeline) { + params.raw.bayersensor.method = options.fastexport_raw_bayer_method ; + params.raw.xtranssensor.method = options.fastexport_raw_xtrans_method; + params.icm.input = options.fastexport_icm_input ; + params.icm.working = options.fastexport_icm_working ; + params.icm.output = options.fastexport_icm_output ; + params.icm.outputIntent = options.fastexport_icm_outputIntent ; + params.icm.outputBPC = options.fastexport_icm_outputBPC ; + 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 ; From f42710f594a9cd545865e100e802b98c4be4d7e5 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sun, 12 Mar 2017 20:52:32 +0100 Subject: [PATCH 06/33] properly rescale the impulseDenoise settings in the fast pipeline --- rtengine/simpleprocess.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index f10378a07..c0e0c05bd 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1378,10 +1378,14 @@ private: params.resize.enabled = false; params.sharpening = params.prsharpening; + params.impulseDenoise.thresh = + int(float(params.impulseDenoise.thresh) * tmpScale); + if (tmpScale < 0.5) { + params.impulseDenoise.enabled = false; + } params.wavelet.strength = int(float(params.wavelet.strength) * tmpScale); params.dirpyrDenoise.luma *= tmpScale; - params.dirpyrDenoise.smethod = "shal"; const double dirpyreq_scale = min(tmpScale * 1.5, 1.0); From 5a38d0610d92a24331c7d489e6cf38b15854bd2a Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sun, 12 Mar 2017 21:03:49 +0100 Subject: [PATCH 07/33] fix for resizing bug in fast-export mode --- rtgui/filecatalog.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index a5b3cdb85..b9818a839 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -1183,14 +1183,20 @@ void FileCatalog::developRequested (std::vector tbe, bool fas params.icm.outputBPC = options.fastexport_icm_outputBPC ; params.icm.gamma = options.fastexport_icm_gamma ; } + + 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 ; - params.resize.width = rtengine::min(params.resize.width, options.fastexport_resize_width) ; - params.resize.height = rtengine::min(params.resize.height, options.fastexport_resize_height) ; } rtengine::ProcessingJob* pjob = rtengine::ProcessingJob::create (fbe->filename, th->getType() == FT_Raw, params, fastmode && options.fastexport_use_fast_pipeline); From d18ce59132fb630f267f54aabbb84dca20cc51b8 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sun, 12 Mar 2017 21:13:54 +0100 Subject: [PATCH 08/33] some further tweaks to the fast pipeline --- rtengine/simpleprocess.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index c0e0c05bd..06f25d512 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1386,7 +1386,7 @@ private: params.wavelet.strength = int(float(params.wavelet.strength) * tmpScale); params.dirpyrDenoise.luma *= tmpScale; - params.dirpyrDenoise.smethod = "shal"; + //params.dirpyrDenoise.smethod = "shal"; const double dirpyreq_scale = min(tmpScale * 1.5, 1.0); for (int i = 0; i < 6; ++i) { From 6f08233c6f95ff0d66a9abae4daaa8cd710c9633 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Mon, 13 Mar 2017 14:00:37 +0100 Subject: [PATCH 09/33] further adjustments of processing parameters for the fast export pipeline --- rtengine/simpleprocess.cc | 84 +++++++++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 25 deletions(-) diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 06f25d512..50dbedbd0 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1369,34 +1369,18 @@ private: params.crop.enabled = false; } - if (params.resize.enabled) { - // resize image - LabImage *resized = new LabImage(imw, imh); - ipf.Lanczos(tmplab, resized, tmpScale); - delete tmplab; - tmplab = resized; - params.resize.enabled = false; + assert(params.resize.enabled); - params.sharpening = params.prsharpening; - params.impulseDenoise.thresh = - int(float(params.impulseDenoise.thresh) * tmpScale); - if (tmpScale < 0.5) { - params.impulseDenoise.enabled = false; - } - params.wavelet.strength = - int(float(params.wavelet.strength) * tmpScale); - params.dirpyrDenoise.luma *= tmpScale; - //params.dirpyrDenoise.smethod = "shal"; + // resize image + LabImage *resized = new LabImage(imw, imh); + ipf.Lanczos(tmplab, resized, tmpScale); + delete tmplab; + tmplab = resized; - const double dirpyreq_scale = min(tmpScale * 1.5, 1.0); - for (int i = 0; i < 6; ++i) { - auto &n = params.dirpyrequalizer.mult[i]; - n = 1.0 + (n - 1.0) * dirpyreq_scale; - } + adjust_procparams(tmpScale); - fw = imw; - fh = imh; - } + fw = imw; + fh = imh; delete baseImg; baseImg = new Imagefloat(fw, fh); @@ -1404,6 +1388,56 @@ private: delete tmplab; } + void adjust_procparams(double scale_factor) + { + procparams::ProcParams& params = job->pparams; + procparams::ProcParams defaultparams; + +#define ADJUST_RADIUS_(n, f) \ + do { \ + auto delta = (params. n - defaultparams. n) * f; \ + params. n = defaultparams. n + delta; \ + } while (false) + + params.resize.enabled = false; + + if (params.prsharpening.enabled) { + params.sharpening = params.prsharpening; + } else { + ADJUST_RADIUS_(sharpening.radius, scale_factor); + } + params.impulseDenoise.thresh = + int(float(params.impulseDenoise.thresh) * scale_factor); + if (scale_factor < 0.5) { + params.impulseDenoise.enabled = false; + } + params.wavelet.strength = + int(float(params.wavelet.strength) * scale_factor); + params.dirpyrDenoise.luma *= scale_factor; + //params.dirpyrDenoise.smethod = "shal"; + for (auto &p : params.dirpyrDenoise.lcurve) { + p *= scale_factor; + } + for (auto &p : params.dirpyrDenoise.cccurve) { + 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_(dirpyrequalizer.mult[i], dirpyreq_scale); + // auto &n = params.dirpyrequalizer.mult[i]; + // n = 1.0 + (n - 1.0) * dirpyreq_scale; + } + + ADJUST_RADIUS_(defringe.radius, scale_factor); + ADJUST_RADIUS_(sh.radius, scale_factor); + +#undef ADJUST_RADIUS_ + } + private: ProcessingJobImpl* job; int& errorCode; From 7a69ff84a476539b533254d3d69b1754cb49f8d0 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Mon, 13 Mar 2017 15:12:00 +0100 Subject: [PATCH 10/33] use 1-pass method for X-trans demosaic in the fast pipeline As suggested by @heckflosse --- rtengine/simpleprocess.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 50dbedbd0..fd06df66b 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1435,6 +1435,14 @@ private: ADJUST_RADIUS_(defringe.radius, scale_factor); ADJUST_RADIUS_(sh.radius, scale_factor); + 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]; + } + #undef ADJUST_RADIUS_ } From f99da0c1ef5fe45a875402e6bc7c5f09047ec4d0 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Mon, 13 Mar 2017 16:39:10 +0100 Subject: [PATCH 11/33] use radio buttons to select between normal and custom pipeline for Fast Export as suggested by @michaelezra --- rtdata/languages/default | 5 +- rtgui/exportpanel.cc | 51 ++++++++++++++------ rtgui/exportpanel.h | 5 +- rtgui/filecatalog.cc | 102 +++++++++++++++++++-------------------- 4 files changed, 94 insertions(+), 69 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 7ae4d2165..35a10b6d7 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -89,7 +89,10 @@ EXPORT_BYPASS_SHARPENEDGE;Bypass Edge Sharpening EXPORT_BYPASS_SHARPENING;Bypass Sharpening EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast EXPORT_BYPASS_SH_HQ;Bypass Sharp Mask Shadows/Highlights -EXPORT_USE_FAST_PIPELINE;Enable Special "Fast-Export" Processing Pipeline +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;Fast Export Options 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. diff --git a/rtgui/exportpanel.cc b/rtgui/exportpanel.cc index fe18cdef7..53d93f8ba 100644 --- a/rtgui/exportpanel.cc +++ b/rtgui/exportpanel.cc @@ -38,8 +38,11 @@ ExportPanel::ExportPanel () : listener (nullptr) labExportTitle->set_alignment(Gtk::ALIGN_START); 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"))); - use_fast_pipeline = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_USE_FAST_PIPELINE"))); use_fast_pipeline->set_tooltip_text(M("EXPORT_USE_FAST_PIPELINE_TIP")); bypass_sharpening = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_SHARPENING"))); bypass_sharpenEdge = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_SHARPENEDGE"))); @@ -98,19 +101,28 @@ ExportPanel::ExportPanel () : listener (nullptr) // ---------------------------------------------------------------- // start global packing + Gtk::HBox* lblbox = Gtk::manage (new Gtk::HBox ()); + lblbox->pack_start (*Gtk::manage (new Gtk::Label (M("EXPORT_PIPELINE"))), Gtk::PACK_SHRINK, 4); + pack_start (*lblbox, Gtk::PACK_SHRINK, 4); pack_start(*use_fast_pipeline , Gtk::PACK_SHRINK, 4); - pack_start(*bypass_ALL , Gtk::PACK_SHRINK, 4); - pack_start(*Gtk::manage(new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 4); - pack_start(*bypass_sharpening , Gtk::PACK_SHRINK, 4); - pack_start(*bypass_sharpenEdge , 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_colorDenoise , Gtk::PACK_SHRINK, 4); - pack_start(*bypass_defringe , Gtk::PACK_SHRINK, 4); - pack_start(*bypass_dirpyrDenoise, Gtk::PACK_SHRINK, 4); - pack_start(*bypass_sh_hq , Gtk::PACK_SHRINK, 4); - pack_start(*bypass_dirpyrequalizer , Gtk::PACK_SHRINK, 4); - pack_start(*bypass_wavelet , Gtk::PACK_SHRINK, 4); + bypass_box->pack_start(*bypass_defringe , Gtk::PACK_SHRINK, 4); + bypass_box->pack_start(*bypass_dirpyrDenoise, Gtk::PACK_SHRINK, 4); + bypass_box->pack_start(*bypass_sh_hq , Gtk::PACK_SHRINK, 4); + bypass_box->pack_start(*bypass_dirpyrequalizer , 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(*bypass_raw_all_enhance , Gtk::PACK_SHRINK, 4); @@ -124,12 +136,14 @@ ExportPanel::ExportPanel () : listener (nullptr) xtransFrameVBox->pack_start(*hb_raw_xtrans_method, Gtk::PACK_SHRINK, 4); xtransFrame->add(*xtransFrameVBox); - pack_start(*bypass_raw_ccSteps , Gtk::PACK_SHRINK, 4); - pack_start(*bypass_raw_ca , Gtk::PACK_SHRINK, 4); + bypass_box->pack_start(*bypass_raw_ccSteps , Gtk::PACK_SHRINK, 4); + bypass_box->pack_start(*bypass_raw_ca , Gtk::PACK_SHRINK, 4); - pack_start(*bypass_raw_df , Gtk::PACK_SHRINK, 4); - pack_start(*bypass_raw_ff , Gtk::PACK_SHRINK, 4); + bypass_box->pack_start(*bypass_raw_df , 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); // Resize options @@ -179,6 +193,7 @@ ExportPanel::ExportPanel () : listener (nullptr) 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) ); //btnExportLoadSettings->signal_clicked().connect( sigc::mem_fun(*this, &ExportPanel::LoadSettings) ); //btnExportSaveSettings->signal_clicked().connect( sigc::mem_fun(*this, &ExportPanel::SaveSettings) ); @@ -347,6 +362,7 @@ void ExportPanel::LoadDefaultSettings() MaxHeight->set_value(options.fastexport_resize_height); use_fast_pipeline->set_active(options.fastexport_use_fast_pipeline); + bypass_box->set_sensitive(!options.fastexport_use_fast_pipeline); } void ExportPanel::LoadSettings() @@ -428,6 +444,11 @@ void ExportPanel::bypassALL_Toggled() 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_sharpenEdge diff --git a/rtgui/exportpanel.h b/rtgui/exportpanel.h index ce7639921..db4431ca5 100644 --- a/rtgui/exportpanel.h +++ b/rtgui/exportpanel.h @@ -36,9 +36,11 @@ class ExportPanel : public Gtk::VBox protected: + Gtk::VBox *bypass_box; //Gtk::CheckButton* enabled; + Gtk::RadioButton* use_fast_pipeline; + Gtk::RadioButton* use_normal_pipeline; Gtk::CheckButton* bypass_ALL; - Gtk::CheckButton* use_fast_pipeline; Gtk::CheckButton* bypass_sharpenEdge; Gtk::CheckButton* bypass_sharpenMicro; Gtk::CheckButton* bypass_sharpening; @@ -106,6 +108,7 @@ protected: ExportPanelListener* listener; void bypassALL_Toggled(); + void use_fast_pipeline_toggled(); void SaveSettingsAsDefault(); void LoadDefaultSettings(); void LoadSettings(); diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index b9818a839..cdba10316 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -1095,41 +1095,41 @@ void FileCatalog::developRequested (std::vector tbe, bool fas // and also those which effect is not pronounced after reducing the image size // TODO!!! could expose selections below via preferences if (fastmode) { - if (options.fastexport_bypass_sharpening ) { - params.sharpening.enabled = false; - } - - if (options.fastexport_bypass_sharpenEdge ) { - params.sharpenEdge.enabled = false; - } - - if (options.fastexport_bypass_sharpenMicro ) { - params.sharpenMicro.enabled = false; - } - - //if (options.fastexport_bypass_lumaDenoise ) params.lumaDenoise.enabled = false; - //if (options.fastexport_bypass_colorDenoise ) params.colorDenoise.enabled = false; - if (options.fastexport_bypass_defringe ) { - params.defringe.enabled = false; - } - - if (options.fastexport_bypass_dirpyrDenoise ) { - params.dirpyrDenoise.enabled = false; - } - - if (options.fastexport_bypass_sh_hq ) { - params.sh.hq = false; - } - - if (options.fastexport_bypass_dirpyrequalizer ) { - params.dirpyrequalizer.enabled = false; - } - - if (options.fastexport_bypass_wavelet ) { - params.wavelet.enabled = false; - } - if (!options.fastexport_use_fast_pipeline) { + if (options.fastexport_bypass_sharpening ) { + params.sharpening.enabled = false; + } + + if (options.fastexport_bypass_sharpenEdge ) { + params.sharpenEdge.enabled = false; + } + + if (options.fastexport_bypass_sharpenMicro ) { + params.sharpenMicro.enabled = false; + } + + //if (options.fastexport_bypass_lumaDenoise ) params.lumaDenoise.enabled = false; + //if (options.fastexport_bypass_colorDenoise ) params.colorDenoise.enabled = false; + if (options.fastexport_bypass_defringe ) { + params.defringe.enabled = false; + } + + if (options.fastexport_bypass_dirpyrDenoise ) { + params.dirpyrDenoise.enabled = false; + } + + if (options.fastexport_bypass_sh_hq ) { + params.sh.hq = false; + } + + if (options.fastexport_bypass_dirpyrequalizer ) { + params.dirpyrequalizer.enabled = false; + } + + if (options.fastexport_bypass_wavelet ) { + params.wavelet.enabled = false; + } + //if (options.fastexport_bypass_raw_bayer_all_enhance ) params.raw.bayersensor.all_enhance = false; if (options.fastexport_bypass_raw_bayer_dcb_iterations ) { params.raw.bayersensor.dcb_iterations = 0; @@ -1150,30 +1150,28 @@ void FileCatalog::developRequested (std::vector tbe, bool fas if (options.fastexport_bypass_raw_bayer_greenthresh ) { params.raw.bayersensor.greenthresh = 0; } - } - if (options.fastexport_bypass_raw_ccSteps ) { - params.raw.bayersensor.ccSteps = params.raw.xtranssensor.ccSteps = 0; - } + if (options.fastexport_bypass_raw_ccSteps ) { + params.raw.bayersensor.ccSteps = params.raw.xtranssensor.ccSteps = 0; + } - if (options.fastexport_bypass_raw_ca ) { - params.raw.ca_autocorrect = false; - params.raw.cared = 0; - params.raw.cablue = 0; - } + if (options.fastexport_bypass_raw_ca ) { + params.raw.ca_autocorrect = false; + params.raw.cared = 0; + params.raw.cablue = 0; + } - if (options.fastexport_bypass_raw_df ) { - params.raw.df_autoselect = false; - params.raw.dark_frame = ""; - } + if (options.fastexport_bypass_raw_df ) { + params.raw.df_autoselect = false; + params.raw.dark_frame = ""; + } - if (options.fastexport_bypass_raw_ff ) { - params.raw.ff_AutoSelect = false; - params.raw.ff_file = ""; - } + if (options.fastexport_bypass_raw_ff ) { + params.raw.ff_AutoSelect = false; + params.raw.ff_file = ""; + } - if (!options.fastexport_use_fast_pipeline) { params.raw.bayersensor.method = options.fastexport_raw_bayer_method ; params.raw.xtranssensor.method = options.fastexport_raw_xtrans_method; params.icm.input = options.fastexport_icm_input ; From e0d9090420d2463a4a56ff75f4947a51481aff5b Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Mon, 13 Mar 2017 23:24:12 +0100 Subject: [PATCH 12/33] Changed "Processing profile operations -> Custom Profile Builder" to "Reset to default profile" The behaviour has changed slightly, so that clicking the menu item now resets to the default processing profile specified in the preferences. If this involves calling the custom profile builder, the behaviour is the same as before. But this is a bit more general, in that it might also simply reapply the static default profile, or regenerate the dynamic one (depending on the user's settings) --- rtdata/languages/default | 2 +- rtgui/filebrowser.cc | 8 ++++---- rtgui/filebrowser.h | 2 +- rtgui/thumbnail.cc | 13 +++++++++---- rtgui/thumbnail.h | 2 +- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index ec61230ff..9eba08b80 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -117,7 +117,7 @@ FILEBROWSER_DELETEDLGMSG;Are you sure you want to delete the selected %1 FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? FILEBROWSER_EMPTYTRASH;Empty trash FILEBROWSER_EMPTYTRASHHINT;Permanently delete the files from trash. -FILEBROWSER_EXEC_CPB;Custom Profile Builder +FILEBROWSER_RESETDEFAULTPROFILE;Reset to default FILEBROWSER_EXTPROGMENU;Open with FILEBROWSER_FLATFIELD;Flat-Field FILEBROWSER_MOVETODARKFDIR;Move to dark-frames directory diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 5cbb5255b..3e8b2e7cf 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -340,7 +340,7 @@ FileBrowser::FileBrowser () p++; submenuProfileOperations->attach (*Gtk::manage(applypartprof = new Gtk::MenuItem (M("FILEBROWSER_APPLYPROFILE_PARTIAL"))), 0, 1, p, p + 1); p++; - submenuProfileOperations->attach (*Gtk::manage(execcustprof = new Gtk::MenuItem (M("FILEBROWSER_EXEC_CPB"))), 0, 1, p, p + 1); + submenuProfileOperations->attach (*Gtk::manage(resetdefaultprof = new Gtk::MenuItem (M("FILEBROWSER_RESETDEFAULTPROFILE"))), 0, 1, p, p + 1); p++; submenuProfileOperations->attach (*Gtk::manage(clearprof = new Gtk::MenuItem (M("FILEBROWSER_CLEARPROFILE"))), 0, 1, p, p + 1); p++; @@ -358,7 +358,7 @@ FileBrowser::FileBrowser () p++; pmenu->attach (*Gtk::manage(applypartprof = new Gtk::MenuItem (M("FILEBROWSER_APPLYPROFILE_PARTIAL"))), 0, 1, p, p + 1); p++; - pmenu->attach (*Gtk::manage(execcustprof = new Gtk::MenuItem (M("FILEBROWSER_EXEC_CPB"))), 0, 1, p, p + 1); + pmenu->attach (*Gtk::manage(resetdefaultprof = new Gtk::MenuItem (M("FILEBROWSER_RESETDEFAULTPROFILE"))), 0, 1, p, p + 1); p++; pmenu->attach (*Gtk::manage(clearprof = new Gtk::MenuItem (M("FILEBROWSER_CLEARPROFILE"))), 0, 1, p, p + 1); p++; @@ -427,7 +427,7 @@ FileBrowser::FileBrowser () partpasteprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), partpasteprof)); applyprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), applyprof)); applypartprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), applypartprof)); - execcustprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), execcustprof)); + resetdefaultprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), resetdefaultprof)); clearprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), clearprof)); cachemenu->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), cachemenu)); @@ -960,7 +960,7 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m) } queue_draw (); - } else if (m == execcustprof) { + } else if (m == resetdefaultprof) { if (!mselected.empty() && bppcl) { bppcl->beginBatchPParamsChange(mselected.size()); } diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h index fdb08ba24..a7474d989 100644 --- a/rtgui/filebrowser.h +++ b/rtgui/filebrowser.h @@ -110,7 +110,7 @@ protected: Gtk::MenuItem* partpasteprof; Gtk::MenuItem* applyprof; Gtk::MenuItem* applypartprof; - Gtk::MenuItem* execcustprof; + Gtk::MenuItem* resetdefaultprof; Gtk::MenuItem* clearprof; Gtk::MenuItem* cachemenu; Gtk::MenuItem* clearFromCache; diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 62f543d4a..16f03761b 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -198,14 +198,13 @@ const ProcParams& Thumbnail::getProcParamsU () * The loaded profile may be partial, but it return a complete ProcParams (i.e. without ParamsEdited) * * @param returnParams Ask to return a pointer to a ProcParams object if true - * @param forceCPB True if the Custom Profile Builder has to be invoked, False if the CPB has to be invoked if the profile doesn't - * exist yet. It depends on other conditions too + * @param force True if the profile has to be re-generated even if it already exists * @param flaggingMode True if the ProcParams will be created because the file browser is being flagging an image * (rang, to trash, color labels). This parameter is passed to the CPB. * * @return Return a pointer to a ProcPamas structure to be updated if returnParams is true and if everything went fine, NULL otherwise. */ -rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool returnParams, bool forceCPB, bool flaggingMode) +rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool returnParams, bool force, bool flaggingMode) { static int index = 0; // Will act as unique identifier during the session @@ -217,7 +216,7 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu const CacheImageData* cfs = getCacheImageData(); Glib::ustring defaultPparamsPath = options.findProfilePath(defProf); - const bool create = (!hasProcParams() || forceCPB); + const bool create = (!hasProcParams() || force); const Glib::ustring outFName = (options.paramsLoadLocation == PLL_Input) ? @@ -239,6 +238,12 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu if (!err) { loadProcParams(); } + } else if (create && + defProf != DEFPROFILE_DYNAMIC && defProf != DEFPROFILE_INTERNAL){ + const PartialProfile *p = profileStore.getProfile(defProf); + if (p && !p->pparams->save(outFName)) { + loadProcParams(); + } } if (!options.CPBPath.empty() && !defaultPparamsPath.empty() && create && cfs && cfs->exifValid) { diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index 8c7691ed2..e5b6a72b2 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -87,7 +87,7 @@ public: const rtengine::procparams::ProcParams& getProcParamsU (); // Unprotected version // Use this to create params on demand for update ; if flaggingMode=true, the procparams is created for a file being flagged (inTrash, rank, colorLabel) - rtengine::procparams::ProcParams* createProcParamsForUpdate (bool returnParams, bool forceCPB, bool flaggingMode = false); + rtengine::procparams::ProcParams* createProcParamsForUpdate (bool returnParams, bool force, bool flaggingMode = false); void setProcParams (const rtengine::procparams::ProcParams& pp, ParamsEdited* pe = nullptr, int whoChangedIt = -1, bool updateCacheNow = true); void clearProcParams (int whoClearedIt = -1); From a3adf8fb07fdd2dd46f5e1b4ea65427f9c968a46 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 14 Mar 2017 11:48:51 +0100 Subject: [PATCH 13/33] code cleanup after feedback by @Floessie --- rtengine/rtengine.h | 1 + rtengine/simpleprocess.cc | 71 +++++++++++++--------------- rtgui/filecatalog.cc | 97 +++++++++++++++++++-------------------- 3 files changed, 81 insertions(+), 88 deletions(-) diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 7449dbd0d..4a87414b8 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -461,6 +461,7 @@ class ProcessingJob { 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 * the image thus it returns immediately. diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index fd06df66b..4a6c7a695 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -37,6 +37,14 @@ extern const Settings* settings; namespace { +template +void adjust_radius(const T &default_param, double scale_factor, T ¶m) +{ + const double delta = (param - default_param) * scale_factor; + param = default_param + delta; +} + + class ImageProcessor { public: ImageProcessor(ProcessingJob* pjob, int& errorCode, @@ -1338,20 +1346,18 @@ private: ImProcFunctions ipf (¶ms, true); int imw, imh; - double tmpScale = ipf.resizeScale(¶ms, fw, fh, imw, imh); + double scale_factor = ipf.resizeScale(¶ms, fw, fh, imw, imh); - LabImage *tmplab = new LabImage(fw, fh); + std::unique_ptr tmplab(new LabImage(fw, fh)); ipf.rgb2lab(*baseImg, *tmplab, params.icm.working); - int cx = 0, cy = 0, cw = fw, ch = fh; - if (params.crop.enabled) { - cx = params.crop.x; - cy = params.crop.y; - cw = params.crop.w; - ch = params.crop.h; + int cx = params.crop.x; + int cy = params.crop.y; + int cw = params.crop.w; + int ch = params.crop.h; - LabImage *cropped = new LabImage(cw, ch); + std::unique_ptr cropped(new LabImage(cw, ch)); for(int row = 0; row < ch; row++) { for(int col = 0; col < cw; col++) { @@ -1361,23 +1367,20 @@ private: } } - delete tmplab; - tmplab = cropped; - cx = 0; - cy = 0; - + tmplab.swap(cropped); params.crop.enabled = false; } assert(params.resize.enabled); // resize image - LabImage *resized = new LabImage(imw, imh); - ipf.Lanczos(tmplab, resized, tmpScale); - delete tmplab; - tmplab = resized; + { + std::unique_ptr resized(new LabImage(imw, imh)); + ipf.Lanczos(tmplab.get(), resized.get(), scale_factor); + tmplab.swap(resized); + } - adjust_procparams(tmpScale); + adjust_procparams(scale_factor); fw = imw; fh = imh; @@ -1385,34 +1388,26 @@ private: delete baseImg; baseImg = new Imagefloat(fw, fh); ipf.lab2rgb(*tmplab, *baseImg, params.icm.working); - delete tmplab; } void adjust_procparams(double scale_factor) { - procparams::ProcParams& params = job->pparams; + procparams::ProcParams ¶ms = job->pparams; procparams::ProcParams defaultparams; -#define ADJUST_RADIUS_(n, f) \ - do { \ - auto delta = (params. n - defaultparams. n) * f; \ - params. n = defaultparams. n + delta; \ - } while (false) - params.resize.enabled = false; if (params.prsharpening.enabled) { params.sharpening = params.prsharpening; } else { - ADJUST_RADIUS_(sharpening.radius, scale_factor); + adjust_radius(defaultparams.sharpening.radius, scale_factor, + params.sharpening.radius); } - params.impulseDenoise.thresh = - int(float(params.impulseDenoise.thresh) * scale_factor); + params.impulseDenoise.thresh *= scale_factor; if (scale_factor < 0.5) { params.impulseDenoise.enabled = false; } - params.wavelet.strength = - int(float(params.wavelet.strength) * scale_factor); + params.wavelet.strength *= scale_factor; params.dirpyrDenoise.luma *= scale_factor; //params.dirpyrDenoise.smethod = "shal"; for (auto &p : params.dirpyrDenoise.lcurve) { @@ -1427,13 +1422,13 @@ private: const double dirpyreq_scale = min(scale_factor * 1.5, 1.0); for (int i = 0; i < 6; ++i) { - ADJUST_RADIUS_(dirpyrequalizer.mult[i], dirpyreq_scale); - // auto &n = params.dirpyrequalizer.mult[i]; - // n = 1.0 + (n - 1.0) * dirpyreq_scale; + adjust_radius(defaultparams.dirpyrequalizer.mult[i], dirpyreq_scale, + params.dirpyrequalizer.mult[i]); } - ADJUST_RADIUS_(defringe.radius, scale_factor); - ADJUST_RADIUS_(sh.radius, scale_factor); + 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[ @@ -1442,8 +1437,6 @@ private: procparams::RAWParams::XTransSensor::methodstring[ procparams::RAWParams::XTransSensor::onePass]; } - -#undef ADJUST_RADIUS_ } private: diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index cdba10316..96a04ba0b 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -1096,105 +1096,104 @@ void FileCatalog::developRequested (std::vector tbe, bool fas // TODO!!! could expose selections below via preferences if (fastmode) { if (!options.fastexport_use_fast_pipeline) { - if (options.fastexport_bypass_sharpening ) { - params.sharpening.enabled = false; + if (options.fastexport_bypass_sharpening) { + params.sharpening.enabled = false; } - if (options.fastexport_bypass_sharpenEdge ) { - params.sharpenEdge.enabled = false; + if (options.fastexport_bypass_sharpenEdge) { + params.sharpenEdge.enabled = false; } - if (options.fastexport_bypass_sharpenMicro ) { - params.sharpenMicro.enabled = false; + if (options.fastexport_bypass_sharpenMicro) { + params.sharpenMicro.enabled = false; } - //if (options.fastexport_bypass_lumaDenoise ) params.lumaDenoise.enabled = false; - //if (options.fastexport_bypass_colorDenoise ) params.colorDenoise.enabled = false; - if (options.fastexport_bypass_defringe ) { - params.defringe.enabled = false; + //if (options.fastexport_bypass_lumaDenoise) params.lumaDenoise.enabled = false; + //if (options.fastexport_bypass_colorDenoise) params.colorDenoise.enabled = false; + if (options.fastexport_bypass_defringe) { + params.defringe.enabled = false; } - if (options.fastexport_bypass_dirpyrDenoise ) { - params.dirpyrDenoise.enabled = false; + if (options.fastexport_bypass_dirpyrDenoise) { + params.dirpyrDenoise.enabled = false; } - if (options.fastexport_bypass_sh_hq ) { - params.sh.hq = false; + if (options.fastexport_bypass_sh_hq) { + params.sh.hq = false; } - if (options.fastexport_bypass_dirpyrequalizer ) { - params.dirpyrequalizer.enabled = false; + if (options.fastexport_bypass_dirpyrequalizer) { + params.dirpyrequalizer.enabled = false; } - if (options.fastexport_bypass_wavelet ) { - params.wavelet.enabled = false; + if (options.fastexport_bypass_wavelet) { + params.wavelet.enabled = false; } - //if (options.fastexport_bypass_raw_bayer_all_enhance ) params.raw.bayersensor.all_enhance = false; - if (options.fastexport_bypass_raw_bayer_dcb_iterations ) { - params.raw.bayersensor.dcb_iterations = 0; + //if (options.fastexport_bypass_raw_bayer_all_enhance) params.raw.bayersensor.all_enhance = false; + if (options.fastexport_bypass_raw_bayer_dcb_iterations) { + params.raw.bayersensor.dcb_iterations = 0; } - if (options.fastexport_bypass_raw_bayer_dcb_enhance ) { - params.raw.bayersensor.dcb_enhance = false; + if (options.fastexport_bypass_raw_bayer_dcb_enhance) { + params.raw.bayersensor.dcb_enhance = false; } if (options.fastexport_bypass_raw_bayer_lmmse_iterations) { - params.raw.bayersensor.lmmse_iterations = 0; + params.raw.bayersensor.lmmse_iterations = 0; } - if (options.fastexport_bypass_raw_bayer_linenoise ) { - params.raw.bayersensor.linenoise = 0; + if (options.fastexport_bypass_raw_bayer_linenoise) { + params.raw.bayersensor.linenoise = 0; } - if (options.fastexport_bypass_raw_bayer_greenthresh ) { - params.raw.bayersensor.greenthresh = 0; + if (options.fastexport_bypass_raw_bayer_greenthresh) { + 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; } - if (options.fastexport_bypass_raw_ca ) { + if (options.fastexport_bypass_raw_ca) { params.raw.ca_autocorrect = false; params.raw.cared = 0; params.raw.cablue = 0; } - if (options.fastexport_bypass_raw_df ) { - params.raw.df_autoselect = false; + if (options.fastexport_bypass_raw_df) { + params.raw.df_autoselect = false; params.raw.dark_frame = ""; } - if (options.fastexport_bypass_raw_ff ) { - params.raw.ff_AutoSelect = false; + if (options.fastexport_bypass_raw_ff) { + params.raw.ff_AutoSelect = false; 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.icm.input = options.fastexport_icm_input ; - params.icm.working = options.fastexport_icm_working ; - params.icm.output = options.fastexport_icm_output ; - params.icm.outputIntent = options.fastexport_icm_outputIntent ; - params.icm.outputBPC = options.fastexport_icm_outputBPC ; - params.icm.gamma = options.fastexport_icm_gamma ; + params.icm.input = options.fastexport_icm_input; + params.icm.working = options.fastexport_icm_working; + params.icm.output = options.fastexport_icm_output; + params.icm.outputIntent = options.fastexport_icm_outputIntent; + params.icm.outputBPC = options.fastexport_icm_outputBPC; + params.icm.gamma = options.fastexport_icm_gamma; } 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) ; + 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 ; + 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); From 656fe0a022700bffacff26991da1f386799617e5 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 14 Mar 2017 15:13:16 +0100 Subject: [PATCH 14/33] use move assignment instead of std::unique_ptr::swap (better readability) --- rtengine/simpleprocess.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 4a6c7a695..1315fb061 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1367,7 +1367,7 @@ private: } } - tmplab.swap(cropped); + tmplab = std::move(cropped); params.crop.enabled = false; } @@ -1377,7 +1377,7 @@ private: { std::unique_ptr resized(new LabImage(imw, imh)); ipf.Lanczos(tmplab.get(), resized.get(), scale_factor); - tmplab.swap(resized); + tmplab = std::move(resized); } adjust_procparams(scale_factor); From 416fc6c92f8fea41fc9f2a12e0805c0b13b0251d Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 15 Mar 2017 09:12:09 +0100 Subject: [PATCH 15/33] move all procparams tweaks to adjust_procparams `params.crop.enabled=false` was still in `stage_early_resize` --- rtengine/simpleprocess.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 1315fb061..9fe4ca731 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1368,7 +1368,6 @@ private: } tmplab = std::move(cropped); - params.crop.enabled = false; } assert(params.resize.enabled); @@ -1396,6 +1395,7 @@ private: procparams::ProcParams defaultparams; params.resize.enabled = false; + params.crop.enabled = false; if (params.prsharpening.enabled) { params.sharpening = params.prsharpening; From 83c6453b4492187ee0aeb1897f52d5c2e556dc4f Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Wed, 15 Mar 2017 14:04:03 +0100 Subject: [PATCH 16/33] minor tweaking to the tonemapping procparams in fast export mode --- rtengine/simpleprocess.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 9fe4ca731..bd8dc0e23 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1418,7 +1418,7 @@ private: } params.epd.scale *= scale_factor; - params.epd.edgeStopping *= 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) { From c8a6253e432c3f5c8d1a58a51ff628d12c4d82aa Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Thu, 16 Mar 2017 09:06:47 +0100 Subject: [PATCH 17/33] save fast export options also when clicking on the "fast export" menu item --- rtgui/filebrowser.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 24d1d8541..70c019942 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -768,6 +768,12 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m) else if (m == develop) { tbl->developRequested (mselected, false); } else if (m == developfast) { + if (exportPanel) { + // force saving export panel settings + exportPanel->setExportPanelListener(nullptr); + exportPanel->FastExportPressed(); + exportPanel->setExportPanelListener(this); + } tbl->developRequested (mselected, true); } From f5798946ef708e0f4b35cd8e09882da257e4f1ce Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Thu, 16 Mar 2017 11:43:37 +0100 Subject: [PATCH 18/33] fixed bug in disabling the "bypass" checkboxes when fast export is selected --- rtgui/exportpanel.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rtgui/exportpanel.cc b/rtgui/exportpanel.cc index 53d93f8ba..72cf30fdd 100644 --- a/rtgui/exportpanel.cc +++ b/rtgui/exportpanel.cc @@ -361,8 +361,12 @@ void ExportPanel::LoadDefaultSettings() MaxWidth->set_value(options.fastexport_resize_width); MaxHeight->set_value(options.fastexport_resize_height); - use_fast_pipeline->set_active(options.fastexport_use_fast_pipeline); - bypass_box->set_sensitive(!options.fastexport_use_fast_pipeline); + 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() From fa433648cd9f5bc4078b530c994d43c22f021261 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Fri, 24 Mar 2017 14:52:31 +0100 Subject: [PATCH 19/33] make "Processing profiles -> Reset to default" work also when the default is "(Neutral)" --- rtgui/thumbnail.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 658721ebc..0bbefa298 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -238,8 +238,7 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu if (!err) { loadProcParams(); } - } else if (create && - defProf != DEFPROFILE_DYNAMIC && defProf != DEFPROFILE_INTERNAL){ + } else if (create && defProf != DEFPROFILE_DYNAMIC) { const PartialProfile *p = profileStore.getProfile(defProf); if (p && !p->pparams->save(outFName)) { loadProcParams(); From dc4b62e2537d84a734140ceaedcef299ddb56125 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Sun, 26 Mar 2017 19:20:36 +0200 Subject: [PATCH 20/33] fix bug in preview when LCP distortion correction is on and the image is flipped Candidate fix for #3778 --- rtengine/dcrop.cc | 41 ++++++++++++++++++++++---------------- rtengine/rawimagesource.cc | 8 ++++---- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 4e944d9fd..7b4862ea0 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -1079,8 +1079,11 @@ void Crop::freeAll () namespace { -bool check_need_larger_crop_for_lcp_distortion(const ProcParams ¶ms) +bool check_need_larger_crop_for_lcp_distortion(int fw, int fh, int x, int y, int w, int h, const ProcParams ¶ms) { + if (x == 0 && y == 0 && w == fw && h == fh) { + return false; + } return (params.lensProf.lcpFile.length() > 0 && params.lensProf.useDist); } @@ -1134,29 +1137,33 @@ bool Crop::setCropSizes (int rcx, int rcy, int rcw, int rch, int skip, bool inte // determine which part of the source image is required to compute the crop rectangle int orx, ory, orw, orh; + orx = bx1; + ory = by1; + orw = bw; + orh = bh; ProcParams& params = parent->params; + parent->ipf.transCoord (parent->fw, parent->fh, bx1, by1, bw, bh, orx, ory, orw, orh); + + if (check_need_larger_crop_for_lcp_distortion(parent->fw, parent->fh, orx, ory, orw, orh, parent->params)) { + double dW = double(parent->fw) * 0.15 / skip; // TODO - this is hardcoded ATM! + double dH = double(parent->fh) * 0.15 / skip; // this is an estimate of the max + // distortion relative to the image + // size. BUT IS 15% REALLY ENOUGH? + // In fact, is there a better way?? + orw = min(int(orw + dW), parent->fw); + orh = min(int(orh + dH), parent->fh); + orx = max(int(orx - dW/2.0), 0); + ory = max(int(ory - dH/2.0), 0); + } + PreviewProps cp (orx, ory, orw, orh, skip); int orW, orH; parent->imgsrc->getSize (cp, orW, orH); - if (check_need_larger_crop_for_lcp_distortion(parent->params)) { - int fW, fH; - parent->imgsrc->getFullSize(fW, fH); - double dW = double(fW) * 0.15; // TODO - this is hardcoded ATM! - double dH = double(fH) * 0.15; // this is an estimate of the max - // distortion relative to the image - // size. BUT IS 15% REALLY ENOUGH? - // In fact, is there a better way?? - orW = min(int(orW + dW), fW); - orH = min(int(orH + dH), fH); - trafx = max(int(orx - dW/2.0), 0); - trafy = max(int(ory - dH/2.0), 0); - } else { - trafx = orx; - trafy = ory; - } + trafx = orx; + trafy = ory; int cw = skips(bw, skip); int ch = skips(bh, skip); diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index df14ddcb2..4aaacd4b0 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -543,17 +543,17 @@ void RawImageSource::transformRect (PreviewProps pp, int tran, int &ssx1, int &s int ppx = pp_x, ppy = pp_y; if (tran & TR_HFLIP) { - ppx = sw - pp_x - pp_width; + ppx = max(sw - pp_x - pp_width, 0); } if (tran & TR_VFLIP) { - ppy = sh - pp_y - pp_height; + ppy = max(sh - pp_y - pp_height, 0); } int sx1 = ppx; // assuming it's >=0 int sy1 = ppy; // assuming it's >=0 - int sx2 = max(ppx + pp_width, w - 1); - int sy2 = max(ppy + pp_height, h - 1); + int sx2 = min(ppx + pp_width, w - 1); + int sy2 = min(ppy + pp_height, h - 1); if ((tran & TR_ROT) == TR_R180) { sx1 = max(w - ppx - pp_width, 0); From 1dedefda2a71f05f16a03b6787f0d7d82ba8e252 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Sun, 26 Mar 2017 23:04:36 +0200 Subject: [PATCH 21/33] Don't use camconst.json for already demosaiced DNG files from some Pentax cameras (files have been generated by DxO) --- rtengine/dcraw.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index c1d2e670a..ec54b9fcf 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -9492,7 +9492,7 @@ dng_skip: adobe_coeff (make, model); if(!strncmp(make, "Samsung", 7) && !strncmp(model, "NX1",3)) adobe_coeff (make, model); - if(!strncmp(make, "Pentax", 6) && (!strncmp(model, "K10D",4) || !strncmp(model, "K-70",4) || !strncmp(model, "K-1",3))) + if((!strncmp(make, "Pentax", 6) && (!strncmp(model, "K10D",4) || !strncmp(model, "K-70",4) || !strncmp(model, "K-1",3))) && filters != 0) adobe_coeff (make, model); if(!strncmp(make, "Leica", 5) && !strncmp(model, "Q",1)) adobe_coeff (make, model); From 52e8668aee35e028b009e3e0f97be9bf116f4a15 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Mon, 27 Mar 2017 15:31:32 +0200 Subject: [PATCH 22/33] Hide some raw tools for predemosaiced raw files (mraw, sraw, predemosaiced DNG) --- rtgui/toolpanelcoord.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 43393d90b..cacbee99d 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -317,9 +317,18 @@ void ToolPanelCoordinator::imageTypeChanged(bool isRaw, bool isBayer, bool isXtr if (isBayer) { sensorxtrans->FoldableToolPanel::hide(); sensorbayer->FoldableToolPanel::show(); + preprocess->FoldableToolPanel::show(); + flatfield->FoldableToolPanel::show(); } else if (isXtrans) { sensorxtrans->FoldableToolPanel::show(); sensorbayer->FoldableToolPanel::hide(); + preprocess->FoldableToolPanel::show(); + flatfield->FoldableToolPanel::show(); + } else { + sensorbayer->FoldableToolPanel::hide(); + sensorxtrans->FoldableToolPanel::hide(); + preprocess->FoldableToolPanel::hide(); + flatfield->FoldableToolPanel::hide(); } } else { rawPanelSW->set_sensitive(false); From d4f0aa559668e42826dfeacff83194dfb3e00408 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Mon, 27 Mar 2017 20:42:04 +0200 Subject: [PATCH 23/33] Set EPD tone mapping Scale to 0.1 to better match preview to output. --- rtgui/epd.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/epd.cc b/rtgui/epd.cc index 15f15f607..995da43a4 100644 --- a/rtgui/epd.cc +++ b/rtgui/epd.cc @@ -31,7 +31,7 @@ EdgePreservingDecompositionUI::EdgePreservingDecompositionUI () : FoldableToolPa strength = Gtk::manage(new Adjuster (M("TP_EPD_STRENGTH"), -1.0, 2.0, 0.01, 0.5)); gamma = Gtk::manage(new Adjuster (M("TP_EPD_GAMMA"), 0.8, 1.5, 0.01, 1.)); edgeStopping = Gtk::manage(new Adjuster (M("TP_EPD_EDGESTOPPING"), 0.1, 4.0, 0.01, 1.4)); - scale = Gtk::manage(new Adjuster (M("TP_EPD_SCALE"), 0.1, 10.0, 0.01, 0.3)); + scale = Gtk::manage(new Adjuster (M("TP_EPD_SCALE"), 0.1, 10.0, 0.01, 0.1)); reweightingIterates = Gtk::manage(new Adjuster (M("TP_EPD_REWEIGHTINGITERATES"), 0, 9, 1, 0)); strength->setAdjusterListener(this); From 68b19868369f3188132996eaafcff49dd7bc971b Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Mon, 27 Mar 2017 20:58:39 +0200 Subject: [PATCH 24/33] Set EPD tone mapping Edge Stopping to 0.5 to better match preview to output. --- rtgui/epd.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/epd.cc b/rtgui/epd.cc index 995da43a4..d7848aee0 100644 --- a/rtgui/epd.cc +++ b/rtgui/epd.cc @@ -30,7 +30,7 @@ EdgePreservingDecompositionUI::EdgePreservingDecompositionUI () : FoldableToolPa strength = Gtk::manage(new Adjuster (M("TP_EPD_STRENGTH"), -1.0, 2.0, 0.01, 0.5)); gamma = Gtk::manage(new Adjuster (M("TP_EPD_GAMMA"), 0.8, 1.5, 0.01, 1.)); - edgeStopping = Gtk::manage(new Adjuster (M("TP_EPD_EDGESTOPPING"), 0.1, 4.0, 0.01, 1.4)); + edgeStopping = Gtk::manage(new Adjuster (M("TP_EPD_EDGESTOPPING"), 0.1, 4.0, 0.01, 0.5)); scale = Gtk::manage(new Adjuster (M("TP_EPD_SCALE"), 0.1, 10.0, 0.01, 0.1)); reweightingIterates = Gtk::manage(new Adjuster (M("TP_EPD_REWEIGHTINGITERATES"), 0, 9, 1, 0)); From 76f16eb3a77f7e2497212e9bdfbdf7bbad190437 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Mon, 27 Mar 2017 21:37:07 +0200 Subject: [PATCH 25/33] Set EPD tone mapping Edge Stopping and Scale to better match preview to output. Third time lucky. --- rtengine/procparams.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 9da09998d..8edf53f8c 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1168,8 +1168,8 @@ void ProcParams::setDefaults () epd.enabled = false; epd.strength = 0.5; epd.gamma = 1.0; - epd.edgeStopping = 1.4; - epd.scale = 0.3; + epd.edgeStopping = 0.5; + epd.scale = 0.1; epd.reweightingIterates = 0; sh.enabled = false; From 209ea3533b3176444848314b1ce468dd30db938a Mon Sep 17 00:00:00 2001 From: Hombre Date: Tue, 28 Mar 2017 00:02:10 +0200 Subject: [PATCH 26/33] Adding PixelShift to PartialPaste window + small bugfixs (issue #3489) --- rtdata/languages/Francais | 7 ++-- rtdata/languages/default | 5 +-- rtengine/pixelshift.cc | 6 ++-- rtengine/procparams.cc | 24 +++++++------- rtengine/procparams.h | 4 +-- rtgui/bayerprocess.cc | 18 +++++----- rtgui/paramsedited.cc | 18 +++++----- rtgui/paramsedited.h | 4 +-- rtgui/partialpastedlg.cc | 69 ++++++++++++++++++++++++++++++--------- rtgui/partialpastedlg.h | 6 ++-- rtgui/profilepanel.cc | 2 ++ 11 files changed, 104 insertions(+), 59 deletions(-) diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais index c8f1c8891..b0fdf3c0d 100644 --- a/rtdata/languages/Francais +++ b/rtdata/languages/Francais @@ -853,8 +853,8 @@ PARTIALPASTE_PREPROCESS_HOTPIXFILT;Filtrage des pixels chauds PARTIALPASTE_PREPROCESS_LINEDENOISE;Filtre de bruit de ligne PARTIALPASTE_PRSHARPENING;Netteté post-redim. PARTIALPASTE_RAWCACORR_AUTO;Corr. auto. de l'aberr. chromatique -PARTIALPASTE_RAWCACORR_CABLUE;Aberr. chromatique bleu -PARTIALPASTE_RAWCACORR_CARED;Aberr. chromatique rouge +PARTIALPASTE_RAWCACORR_CAAUTOSTRENGTH;Force aberr. chromatique auto +PARTIALPASTE_RAWCACORR_CAREDBLUE;Aberr. chromatique rouge et bleu PARTIALPASTE_RAWEXPOS_BLACK;Niveaux de noir PARTIALPASTE_RAWEXPOS_LINEAR;Correction du point blanc PARTIALPASTE_RAWEXPOS_PRESER;Préservation des hautes humières @@ -864,6 +864,7 @@ PARTIALPASTE_RAW_DCBITERATIONS;Nombre d'itération de DCB PARTIALPASTE_RAW_DMETHOD;Algorithme de dématriçage PARTIALPASTE_RAW_FALSECOLOR;Nbr d'itération des fausses couleurs PARTIALPASTE_RAW_LMMSEITERATIONS;Niveau d'amélioration LMMSE +PARTIALPASTE_RAW_PIXELSHIFT;PixelShift PARTIALPASTE_RESIZE;Redimentionnement PARTIALPASTE_RETINEX;Retinex PARTIALPASTE_RGBCURVES;Courbes RVB @@ -1629,7 +1630,7 @@ TP_PRSHARPENING_TOOLTIP;Augmente la netteté de l'image après le redimentionnem TP_RAWCACORR_AUTO;Correction automatique TP_RAWCACORR_CABLUE;Bleu TP_RAWCACORR_CARED;Rouge -TP_RAWCACORR_CASTR;force +TP_RAWCACORR_CASTR;Force TP_RAWEXPOS_BLACKS;Niveaux de noir TP_RAWEXPOS_BLACK_0;Vert 1 (maître) TP_RAWEXPOS_BLACK_1;Rouge diff --git a/rtdata/languages/default b/rtdata/languages/default index 849d9a66b..1ca41739a 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -895,8 +895,8 @@ PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter PARTIALPASTE_PREPROCESS_LINEDENOISE;Line noise filter PARTIALPASTE_PRSHARPENING;Post-resize sharpening PARTIALPASTE_RAWCACORR_AUTO;CA auto-correction -PARTIALPASTE_RAWCACORR_CABLUE;CA blue -PARTIALPASTE_RAWCACORR_CARED;CA red +PARTIALPASTE_RAWCACORR_CAAUTOSTRENGTH;CA auto-correction strength +PARTIALPASTE_RAWCACORR_CAREDBLUE;CA red & blue PARTIALPASTE_RAWEXPOS_BLACK;Black levels PARTIALPASTE_RAWEXPOS_LINEAR;White point correction PARTIALPASTE_RAWEXPOS_PRESER;Highlight preservation @@ -907,6 +907,7 @@ PARTIALPASTE_RAW_DMETHOD;Demosaic method PARTIALPASTE_RAW_FALSECOLOR;False color suppression PARTIALPASTE_RAW_IMAGENUM;Sub-image PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +PARTIALPASTE_RAW_PIXELSHIFT;PixelShift PARTIALPASTE_RESIZE;Resize PARTIALPASTE_RETINEX;Retinex PARTIALPASTE_RGBCURVES;RGB curves diff --git a/rtengine/pixelshift.cc b/rtengine/pixelshift.cc index 0986844f5..44e765e41 100644 --- a/rtengine/pixelshift.cc +++ b/rtengine/pixelshift.cc @@ -332,7 +332,7 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA } else if(bayerParams.pixelShiftMotionCorrectionMethod == RAWParams::BayerSensor::Off) { bayerParams.pixelShiftMotion = 0; bayerParams.pixelShiftAutomatic = false; - bayerParams.pixelshiftShowMotion = false; + bayerParams.pixelShiftShowMotion = false; } if((bayerParams.pixelShiftMotion > 0 || bayerParams.pixelShiftAutomatic)) { @@ -454,8 +454,8 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA } const int motion = bayerParams.pixelShiftMotion; - const bool showMotion = bayerParams.pixelshiftShowMotion; - const bool showOnlyMask = bayerParams.pixelshiftShowMotionMaskOnly && showMotion; + const bool showMotion = bayerParams.pixelShiftShowMotion; + const bool showOnlyMask = bayerParams.pixelShiftShowMotionMaskOnly && showMotion; const RAWParams::BayerSensor::ePSMotionCorrection gridSize_ = bayerParams.pixelShiftMotionCorrection; const bool adaptive = bayerParams.pixelShiftAutomatic; #ifdef PIXELSHIFTDEV diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 8edf53f8c..35d690eb4 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -945,8 +945,8 @@ void RAWParams::setDefaults() deadPixelFilter = false; hotdeadpix_thresh = 100; bayersensor.setPixelShiftDefaults(); - bayersensor.pixelshiftShowMotion = false; - bayersensor.pixelshiftShowMotionMaskOnly = false; + bayersensor.pixelShiftShowMotion = false; + bayersensor.pixelShiftShowMotionMaskOnly = false; } @@ -3451,12 +3451,12 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b keyFile.set_double ("RAW Bayer", "PixelShiftRedBlueWeight", raw.bayersensor.pixelShiftRedBlueWeight ); } - if (!pedited || pedited->raw.bayersensor.pixelshiftShowMotion) { - keyFile.set_boolean ("RAW Bayer", "PixelShiftShowMotion", raw.bayersensor.pixelshiftShowMotion ); + if (!pedited || pedited->raw.bayersensor.pixelShiftShowMotion) { + keyFile.set_boolean ("RAW Bayer", "PixelShiftShowMotion", raw.bayersensor.pixelShiftShowMotion ); } - if (!pedited || pedited->raw.bayersensor.pixelshiftShowMotionMaskOnly) { - keyFile.set_boolean ("RAW Bayer", "PixelShiftShowMotionMaskOnly", raw.bayersensor.pixelshiftShowMotionMaskOnly ); + if (!pedited || pedited->raw.bayersensor.pixelShiftShowMotionMaskOnly) { + keyFile.set_boolean ("RAW Bayer", "PixelShiftShowMotionMaskOnly", raw.bayersensor.pixelShiftShowMotionMaskOnly ); } if (!pedited || pedited->raw.bayersensor.pixelShiftAutomatic) { @@ -7680,18 +7680,18 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) } if (keyFile.has_key ("RAW Bayer", "PixelShiftShowMotion")) { - raw.bayersensor.pixelshiftShowMotion = keyFile.get_boolean("RAW Bayer", "PixelShiftShowMotion"); + raw.bayersensor.pixelShiftShowMotion = keyFile.get_boolean("RAW Bayer", "PixelShiftShowMotion"); if (pedited) { - pedited->raw.bayersensor.pixelshiftShowMotion = true; + pedited->raw.bayersensor.pixelShiftShowMotion = true; } } if (keyFile.has_key ("RAW Bayer", "PixelShiftShowMotionMaskOnly")) { - raw.bayersensor.pixelshiftShowMotionMaskOnly = keyFile.get_boolean("RAW Bayer", "PixelShiftShowMotionMaskOnly"); + raw.bayersensor.pixelShiftShowMotionMaskOnly = keyFile.get_boolean("RAW Bayer", "PixelShiftShowMotionMaskOnly"); if (pedited) { - pedited->raw.bayersensor.pixelshiftShowMotionMaskOnly = true; + pedited->raw.bayersensor.pixelShiftShowMotionMaskOnly = true; } } @@ -8264,8 +8264,8 @@ bool ProcParams::operator== (const ProcParams& other) && raw.bayersensor.pixelShiftSigma == other.raw.bayersensor.pixelShiftSigma && raw.bayersensor.pixelShiftSum == other.raw.bayersensor.pixelShiftSum && raw.bayersensor.pixelShiftRedBlueWeight == other.raw.bayersensor.pixelShiftRedBlueWeight - && raw.bayersensor.pixelshiftShowMotion == other.raw.bayersensor.pixelshiftShowMotion - && raw.bayersensor.pixelshiftShowMotionMaskOnly == other.raw.bayersensor.pixelshiftShowMotionMaskOnly + && raw.bayersensor.pixelShiftShowMotion == other.raw.bayersensor.pixelShiftShowMotion + && raw.bayersensor.pixelShiftShowMotionMaskOnly == other.raw.bayersensor.pixelShiftShowMotionMaskOnly && raw.bayersensor.pixelShiftAutomatic == other.raw.bayersensor.pixelShiftAutomatic && raw.bayersensor.pixelShiftNonGreenHorizontal == other.raw.bayersensor.pixelShiftNonGreenHorizontal && raw.bayersensor.pixelShiftNonGreenVertical == other.raw.bayersensor.pixelShiftNonGreenVertical diff --git a/rtengine/procparams.h b/rtengine/procparams.h index c83856870..a2c2bf5a4 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1221,8 +1221,8 @@ public: double pixelShiftSigma; double pixelShiftSum; double pixelShiftRedBlueWeight; - bool pixelshiftShowMotion; - bool pixelshiftShowMotionMaskOnly; + bool pixelShiftShowMotion; + bool pixelShiftShowMotionMaskOnly; bool pixelShiftAutomatic; bool pixelShiftNonGreenHorizontal; bool pixelShiftNonGreenVertical; diff --git a/rtgui/bayerprocess.cc b/rtgui/bayerprocess.cc index ba7cfa8e8..bc2809971 100644 --- a/rtgui/bayerprocess.cc +++ b/rtgui/bayerprocess.cc @@ -357,11 +357,11 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params dcbIterations->setValue (pp->raw.bayersensor.dcb_iterations); dcbEnhance->setValue (pp->raw.bayersensor.dcb_enhance); - pixelShiftShowMotion->setValue (pp->raw.bayersensor.pixelshiftShowMotion); + pixelShiftShowMotion->setValue (pp->raw.bayersensor.pixelShiftShowMotion); if (!batchMode) { - pixelShiftShowMotionMaskOnly->set_sensitive (pp->raw.bayersensor.pixelshiftShowMotion); + pixelShiftShowMotionMaskOnly->set_sensitive (pp->raw.bayersensor.pixelShiftShowMotion); } - pixelShiftShowMotionMaskOnly->setValue (pp->raw.bayersensor.pixelshiftShowMotionMaskOnly); + pixelShiftShowMotionMaskOnly->setValue (pp->raw.bayersensor.pixelShiftShowMotionMaskOnly); pixelShiftHoleFill->setValue (pp->raw.bayersensor.pixelShiftHoleFill); pixelShiftMedian->setValue (pp->raw.bayersensor.pixelShiftMedian); pixelShiftGreen->setValue (pp->raw.bayersensor.pixelShiftGreen); @@ -412,8 +412,8 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params ccSteps->setEditedState (pedited->raw.bayersensor.ccSteps ? Edited : UnEdited); dcbIterations->setEditedState ( pedited->raw.bayersensor.dcbIterations ? Edited : UnEdited); dcbEnhance->setEdited (pedited->raw.bayersensor.dcbEnhance); - pixelShiftShowMotion->setEdited (pedited->raw.bayersensor.pixelshiftShowMotion); - pixelShiftShowMotionMaskOnly->setEdited (pedited->raw.bayersensor.pixelshiftShowMotionMaskOnly); + pixelShiftShowMotion->setEdited (pedited->raw.bayersensor.pixelShiftShowMotion); + pixelShiftShowMotionMaskOnly->setEdited (pedited->raw.bayersensor.pixelShiftShowMotionMaskOnly); pixelShiftHoleFill->setEdited (pedited->raw.bayersensor.pixelShiftHoleFill); pixelShiftMedian->setEdited(pedited->raw.bayersensor.pixelShiftMedian); pixelShiftGreen->setEdited (pedited->raw.bayersensor.pixelShiftGreen); @@ -515,8 +515,8 @@ void BayerProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pe pp->raw.bayersensor.pixelShiftMotionCorrectionMethod = (RAWParams::BayerSensor::ePSMotionCorrectionMethod)pixelShiftMotionMethod->get_active_row_number(); pp->raw.bayersensor.pixelShiftEperIso = pixelShiftEperIso->getValue(); pp->raw.bayersensor.pixelShiftSigma = pixelShiftSigma->getValue(); - pp->raw.bayersensor.pixelshiftShowMotion = pixelShiftShowMotion->getLastActive (); - pp->raw.bayersensor.pixelshiftShowMotionMaskOnly = pixelShiftShowMotionMaskOnly->getLastActive (); + pp->raw.bayersensor.pixelShiftShowMotion = pixelShiftShowMotion->getLastActive (); + pp->raw.bayersensor.pixelShiftShowMotionMaskOnly = pixelShiftShowMotionMaskOnly->getLastActive (); pp->raw.bayersensor.pixelShiftHoleFill = pixelShiftHoleFill->getLastActive (); pp->raw.bayersensor.pixelShiftMedian = pixelShiftMedian->getLastActive (); pp->raw.bayersensor.pixelShiftGreen = pixelShiftGreen->getLastActive (); @@ -566,8 +566,8 @@ void BayerProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pe pedited->raw.bayersensor.pixelShiftMotionCorrectionMethod = pixelShiftMotionMethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->raw.bayersensor.pixelShiftEperIso = pixelShiftEperIso->getEditedState (); pedited->raw.bayersensor.pixelShiftSigma = pixelShiftSigma->getEditedState (); - pedited->raw.bayersensor.pixelshiftShowMotion = !pixelShiftShowMotion->get_inconsistent(); - pedited->raw.bayersensor.pixelshiftShowMotionMaskOnly = !pixelShiftShowMotionMaskOnly->get_inconsistent(); + pedited->raw.bayersensor.pixelShiftShowMotion = !pixelShiftShowMotion->get_inconsistent(); + pedited->raw.bayersensor.pixelShiftShowMotionMaskOnly = !pixelShiftShowMotionMaskOnly->get_inconsistent(); pedited->raw.bayersensor.pixelShiftHoleFill = !pixelShiftHoleFill->get_inconsistent(); pedited->raw.bayersensor.pixelShiftMedian = !pixelShiftMedian->get_inconsistent(); pedited->raw.bayersensor.pixelShiftGreen = !pixelShiftGreen->get_inconsistent(); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 4d05158c0..7afcc43d3 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -383,8 +383,8 @@ void ParamsEdited::set (bool v) raw.bayersensor.pixelShiftSigma = v; raw.bayersensor.pixelShiftSum = v; raw.bayersensor.pixelShiftRedBlueWeight = v; - raw.bayersensor.pixelshiftShowMotion = v; - raw.bayersensor.pixelshiftShowMotionMaskOnly = v; + raw.bayersensor.pixelShiftShowMotion = v; + raw.bayersensor.pixelShiftShowMotionMaskOnly = v; raw.bayersensor.pixelShiftAutomatic = v; raw.bayersensor.pixelShiftNonGreenHorizontal = v; raw.bayersensor.pixelShiftNonGreenVertical = v; @@ -909,8 +909,8 @@ void ParamsEdited::initFrom (const std::vector raw.bayersensor.pixelShiftSigma = raw.bayersensor.pixelShiftSigma && p.raw.bayersensor.pixelShiftSigma == other.raw.bayersensor.pixelShiftSigma; raw.bayersensor.pixelShiftSum = raw.bayersensor.pixelShiftSum && p.raw.bayersensor.pixelShiftSum == other.raw.bayersensor.pixelShiftSum; raw.bayersensor.pixelShiftRedBlueWeight = raw.bayersensor.pixelShiftRedBlueWeight && p.raw.bayersensor.pixelShiftRedBlueWeight == other.raw.bayersensor.pixelShiftRedBlueWeight; - raw.bayersensor.pixelshiftShowMotion = raw.bayersensor.pixelshiftShowMotion && p.raw.bayersensor.pixelshiftShowMotion == other.raw.bayersensor.pixelshiftShowMotion; - raw.bayersensor.pixelshiftShowMotionMaskOnly = raw.bayersensor.pixelshiftShowMotionMaskOnly && p.raw.bayersensor.pixelshiftShowMotionMaskOnly == other.raw.bayersensor.pixelshiftShowMotionMaskOnly; + raw.bayersensor.pixelShiftShowMotion = raw.bayersensor.pixelShiftShowMotion && p.raw.bayersensor.pixelShiftShowMotion == other.raw.bayersensor.pixelShiftShowMotion; + raw.bayersensor.pixelShiftShowMotionMaskOnly = raw.bayersensor.pixelShiftShowMotionMaskOnly && p.raw.bayersensor.pixelShiftShowMotionMaskOnly == other.raw.bayersensor.pixelShiftShowMotionMaskOnly; raw.bayersensor.pixelShiftAutomatic = raw.bayersensor.pixelShiftAutomatic && p.raw.bayersensor.pixelShiftAutomatic == other.raw.bayersensor.pixelShiftAutomatic; raw.bayersensor.pixelShiftNonGreenHorizontal = raw.bayersensor.pixelShiftNonGreenHorizontal && p.raw.bayersensor.pixelShiftNonGreenHorizontal == other.raw.bayersensor.pixelShiftNonGreenHorizontal; raw.bayersensor.pixelShiftNonGreenVertical = raw.bayersensor.pixelShiftNonGreenVertical && p.raw.bayersensor.pixelShiftNonGreenVertical == other.raw.bayersensor.pixelShiftNonGreenVertical; @@ -2390,12 +2390,12 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.raw.bayersensor.pixelShiftRedBlueWeight = mods.raw.bayersensor.pixelShiftRedBlueWeight; } - if (raw.bayersensor.pixelshiftShowMotion) { - toEdit.raw.bayersensor.pixelshiftShowMotion = mods.raw.bayersensor.pixelshiftShowMotion; + if (raw.bayersensor.pixelShiftShowMotion) { + toEdit.raw.bayersensor.pixelShiftShowMotion = mods.raw.bayersensor.pixelShiftShowMotion; } - if (raw.bayersensor.pixelshiftShowMotionMaskOnly) { - toEdit.raw.bayersensor.pixelshiftShowMotionMaskOnly = mods.raw.bayersensor.pixelshiftShowMotionMaskOnly; + if (raw.bayersensor.pixelShiftShowMotionMaskOnly) { + toEdit.raw.bayersensor.pixelShiftShowMotionMaskOnly = mods.raw.bayersensor.pixelShiftShowMotionMaskOnly; } if (raw.bayersensor.pixelShiftAutomatic) { @@ -2969,7 +2969,7 @@ bool RAWParamsEdited::BayerSensor::isUnchanged() const { return method && imageNum && dcbIterations && dcbEnhance && lmmseIterations/*&& allEnhance*/ && greenEq && pixelShiftMotion && pixelShiftMotionCorrection && pixelShiftMotionCorrectionMethod && pixelShiftStddevFactorGreen && pixelShiftStddevFactorRed && pixelShiftStddevFactorBlue && pixelShiftEperIso - && pixelShiftNreadIso && pixelShiftPrnu && pixelShiftSigma && pixelShiftSum && pixelShiftRedBlueWeight && pixelshiftShowMotion && pixelshiftShowMotionMaskOnly + && pixelShiftNreadIso && pixelShiftPrnu && pixelShiftSigma && pixelShiftSum && pixelShiftRedBlueWeight && pixelShiftShowMotion && pixelShiftShowMotionMaskOnly && pixelShiftAutomatic && pixelShiftNonGreenHorizontal && pixelShiftNonGreenVertical && pixelShiftHoleFill && pixelShiftMedian && pixelShiftMedian3 && pixelShiftNonGreenCross && pixelShiftNonGreenCross2 && pixelShiftNonGreenAmaze && pixelShiftGreen && pixelShiftBlur && pixelShiftSmooth && pixelShiftExp0 && pixelShiftLmmse && pixelShiftEqualBright && linenoise && exBlack0 && exBlack1 && exBlack2 && exBlack3 && exTwoGreen; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index fc69a1e48..0840f7aa1 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -704,8 +704,8 @@ public: bool pixelShiftSigma; bool pixelShiftSum; bool pixelShiftRedBlueWeight; - bool pixelshiftShowMotion; - bool pixelshiftShowMotionMaskOnly; + bool pixelShiftShowMotion; + bool pixelShiftShowMotionMaskOnly; bool pixelShiftAutomatic; bool pixelShiftNonGreenHorizontal; bool pixelShiftNonGreenVertical; diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc index 7cf7de15e..13f91fc7b 100644 --- a/rtgui/partialpastedlg.cc +++ b/rtgui/partialpastedlg.cc @@ -104,14 +104,15 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren raw_preser = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWEXPOS_PRESER"))); raw_black = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWEXPOS_BLACK"))); raw_ca_autocorrect = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_AUTO"))); - raw_cared = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_CARED"))); - raw_cablue = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_CABLUE"))); + raw_caredblue = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_CAREDBLUE"))); + raw_caautostrength = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_CAAUTOSTRENGTH"))); raw_hotpix_filt = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_HOTPIXFILT"))); raw_deadpix_filt = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_DEADPIXFILT"))); raw_linenoise = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_LINEDENOISE"))); raw_greenthresh = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_GREENEQUIL"))); raw_method = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAW_DMETHOD"))); raw_imagenum = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAW_IMAGENUM"))); + raw_pixelshift = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAW_PIXELSHIFT"))); raw_ccSteps = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAW_FALSECOLOR"))); raw_dcb_iterations = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAW_DCBITERATIONS"))); raw_dcb_enhance = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAW_DCBENHANCE"))); @@ -202,6 +203,7 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren vboxes[6]->pack_start (*hseps[6], Gtk::PACK_SHRINK, 2); vboxes[6]->pack_start (*raw_method, Gtk::PACK_SHRINK, 2); vboxes[6]->pack_start (*raw_imagenum, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*raw_pixelshift, Gtk::PACK_SHRINK, 2); vboxes[6]->pack_start (*raw_ccSteps, Gtk::PACK_SHRINK, 2); vboxes[6]->pack_start (*raw_dcb_iterations, Gtk::PACK_SHRINK, 2); vboxes[6]->pack_start (*raw_dcb_enhance, Gtk::PACK_SHRINK, 2); @@ -227,8 +229,8 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren vboxes[6]->pack_start (*ff_ClipControl, Gtk::PACK_SHRINK, 2); vboxes[6]->pack_start (*Gtk::manage (new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 0); vboxes[6]->pack_start (*raw_ca_autocorrect, Gtk::PACK_SHRINK, 2); - vboxes[6]->pack_start (*raw_cared, Gtk::PACK_SHRINK, 2); - vboxes[6]->pack_start (*raw_cablue, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*raw_caredblue, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*raw_caautostrength, Gtk::PACK_SHRINK, 2); //META vboxes[7]->pack_start (*meta, Gtk::PACK_SHRINK, 2); @@ -347,13 +349,14 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren raw_dcb_enhanceConn = raw_dcb_enhance->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); //raw_all_enhanceConn = raw_all_enhance->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); raw_lmmse_iterationsConn = raw_lmmse_iterations->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + raw_pixelshiftConn = raw_pixelshift->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); raw_exposConn = raw_expos->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); raw_preserConn = raw_preser->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); raw_blackConn = raw_black->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); raw_ca_autocorrectConn = raw_ca_autocorrect->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); - raw_caredConn = raw_cared->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); - raw_cablueConn = raw_cablue->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + raw_caredblueConn = raw_caredblue->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + raw_caautostrengthConn = raw_caautostrength->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); raw_hotpix_filtConn = raw_hotpix_filt->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); raw_deadpix_filtConn = raw_deadpix_filt->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); raw_linenoiseConn = raw_linenoise->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); @@ -427,12 +430,13 @@ void PartialPasteDlg::rawToggled () raw_dcb_enhanceConn.block (true); //raw_all_enhanceConn.block (true); raw_lmmse_iterationsConn.block (true); + raw_pixelshiftConn.block (true); raw_exposConn.block (true); raw_preserConn.block (true); raw_blackConn.block (true); raw_ca_autocorrectConn.block (true); - raw_caredConn.block (true); - raw_cablueConn.block (true); + raw_caredblueConn.block (true); + raw_caautostrengthConn.block (true); raw_hotpix_filtConn.block (true); raw_deadpix_filtConn.block (true); raw_linenoiseConn.block (true); @@ -453,13 +457,14 @@ void PartialPasteDlg::rawToggled () raw_dcb_iterations->set_active (raw->get_active ()); raw_dcb_enhance->set_active (raw->get_active ()); raw_lmmse_iterations->set_active (raw->get_active ()); + raw_pixelshift->set_active (raw->get_active ()); //raw_all_enhance->set_active (raw->get_active ()); raw_expos->set_active (raw->get_active ()); raw_preser->set_active (raw->get_active ()); raw_black->set_active (raw->get_active ()); raw_ca_autocorrect->set_active (raw->get_active ()); - raw_cared->set_active (raw->get_active ()); - raw_cablue->set_active (raw->get_active ()); + raw_caredblue->set_active (raw->get_active ()); + raw_caautostrength->set_active (raw->get_active ()); raw_hotpix_filt->set_active (raw->get_active ()); raw_deadpix_filt->set_active (raw->get_active ()); raw_linenoise->set_active (raw->get_active ()); @@ -478,13 +483,14 @@ void PartialPasteDlg::rawToggled () raw_dcb_iterationsConn.block (false); raw_dcb_enhanceConn.block (false); //raw_all_enhanceConn.block (false); + raw_pixelshiftConn.block (false); raw_lmmse_iterationsConn.block (false); raw_exposConn.block (false); raw_preserConn.block (false); raw_blackConn.block (false); raw_ca_autocorrectConn.block (false); - raw_caredConn.block (false); - raw_cablueConn.block (false); + raw_caredblueConn.block (false); + raw_caautostrengthConn.block (false); raw_hotpix_filtConn.block (false); raw_deadpix_filtConn.block (false); raw_linenoiseConn.block (false); @@ -886,6 +892,38 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param filterPE.raw.xtranssensor.exBlackBlue = falsePE.raw.xtranssensor.exBlackBlue; } + if (!raw_pixelshift->get_active ()) { + filterPE.raw.bayersensor.pixelShiftAutomatic = falsePE.raw.bayersensor.pixelShiftAutomatic; + filterPE.raw.bayersensor.pixelShiftBlur = falsePE.raw.bayersensor.pixelShiftBlur; + filterPE.raw.bayersensor.pixelShiftEperIso = falsePE.raw.bayersensor.pixelShiftEperIso; + filterPE.raw.bayersensor.pixelShiftEqualBright = falsePE.raw.bayersensor.pixelShiftEqualBright; + filterPE.raw.bayersensor.pixelShiftExp0 = falsePE.raw.bayersensor.pixelShiftExp0; + filterPE.raw.bayersensor.pixelShiftGreen = falsePE.raw.bayersensor.pixelShiftGreen; + filterPE.raw.bayersensor.pixelShiftHoleFill = falsePE.raw.bayersensor.pixelShiftHoleFill; + filterPE.raw.bayersensor.pixelShiftLmmse = falsePE.raw.bayersensor.pixelShiftLmmse; + filterPE.raw.bayersensor.pixelShiftMedian = falsePE.raw.bayersensor.pixelShiftMedian; + filterPE.raw.bayersensor.pixelShiftMedian3 = falsePE.raw.bayersensor.pixelShiftMedian3; + filterPE.raw.bayersensor.pixelShiftMotion = falsePE.raw.bayersensor.pixelShiftMotion; + filterPE.raw.bayersensor.pixelShiftMotionCorrection = falsePE.raw.bayersensor.pixelShiftMotionCorrection; + filterPE.raw.bayersensor.pixelShiftMotionCorrectionMethod = falsePE.raw.bayersensor.pixelShiftMotionCorrectionMethod; + filterPE.raw.bayersensor.pixelShiftNonGreenAmaze = falsePE.raw.bayersensor.pixelShiftNonGreenAmaze; + filterPE.raw.bayersensor.pixelShiftNonGreenCross = falsePE.raw.bayersensor.pixelShiftNonGreenCross; + filterPE.raw.bayersensor.pixelShiftNonGreenCross2 = falsePE.raw.bayersensor.pixelShiftNonGreenCross2; + filterPE.raw.bayersensor.pixelShiftNonGreenHorizontal = falsePE.raw.bayersensor.pixelShiftNonGreenHorizontal; + filterPE.raw.bayersensor.pixelShiftNonGreenVertical = falsePE.raw.bayersensor.pixelShiftNonGreenVertical; + filterPE.raw.bayersensor.pixelShiftNreadIso = falsePE.raw.bayersensor.pixelShiftNreadIso; + filterPE.raw.bayersensor.pixelShiftPrnu = falsePE.raw.bayersensor.pixelShiftPrnu; + filterPE.raw.bayersensor.pixelShiftRedBlueWeight = falsePE.raw.bayersensor.pixelShiftRedBlueWeight; + filterPE.raw.bayersensor.pixelShiftSigma = falsePE.raw.bayersensor.pixelShiftSigma; + filterPE.raw.bayersensor.pixelShiftSmooth = falsePE.raw.bayersensor.pixelShiftSmooth; + filterPE.raw.bayersensor.pixelShiftStddevFactorBlue = falsePE.raw.bayersensor.pixelShiftStddevFactorBlue; + filterPE.raw.bayersensor.pixelShiftStddevFactorGreen = falsePE.raw.bayersensor.pixelShiftStddevFactorGreen; + filterPE.raw.bayersensor.pixelShiftStddevFactorRed = falsePE.raw.bayersensor.pixelShiftStddevFactorRed; + filterPE.raw.bayersensor.pixelShiftSum = falsePE.raw.bayersensor.pixelShiftSum; + filterPE.raw.bayersensor.pixelShiftShowMotion = falsePE.raw.bayersensor.pixelShiftShowMotion; + filterPE.raw.bayersensor.pixelShiftShowMotionMaskOnly = falsePE.raw.bayersensor.pixelShiftShowMotionMaskOnly; + } + if (!raw_linenoise->get_active ()) { filterPE.raw.bayersensor.linenoise = falsePE.raw.bayersensor.linenoise; } @@ -906,12 +944,13 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param filterPE.raw.caCorrection = falsePE.raw.caCorrection; } - if (!raw_cared->get_active ()) { + if (!raw_caredblue->get_active ()) { filterPE.raw.caRed = falsePE.raw.caRed; + filterPE.raw.caBlue = falsePE.raw.caBlue; } - if (!raw_cablue->get_active ()) { - filterPE.raw.caBlue = falsePE.raw.caBlue; + if (!raw_caautostrength->get_active ()) { + filterPE.raw.caAutoStrength = falsePE.raw.caAutoStrength; } if (!raw_hotpix_filt->get_active ()) { diff --git a/rtgui/partialpastedlg.h b/rtgui/partialpastedlg.h index 177b0b720..438744863 100644 --- a/rtgui/partialpastedlg.h +++ b/rtgui/partialpastedlg.h @@ -100,8 +100,9 @@ public: Gtk::CheckButton* raw_preser; Gtk::CheckButton* raw_black; Gtk::CheckButton* raw_ca_autocorrect; - Gtk::CheckButton* raw_cared; + Gtk::CheckButton* raw_caredblue; Gtk::CheckButton* raw_cablue; + Gtk::CheckButton* raw_caautostrength; Gtk::CheckButton* raw_hotpix_filt; Gtk::CheckButton* raw_deadpix_filt; Gtk::CheckButton* raw_linenoise; @@ -112,6 +113,7 @@ public: Gtk::CheckButton* raw_dcb_iterations; Gtk::CheckButton* raw_dcb_enhance; Gtk::CheckButton* raw_lmmse_iterations; + Gtk::CheckButton* raw_pixelshift; Gtk::CheckButton* df_file; Gtk::CheckButton* df_AutoSelect; @@ -130,7 +132,7 @@ public: sigc::connection coarserotConn, finerotConn, cropConn, resizeConn, prsharpeningConn, perspectiveConn, commonTransConn; sigc::connection exifchConn, iptcConn, icmConn; sigc::connection df_fileConn, df_AutoSelectConn, ff_fileConn, ff_AutoSelectConn, ff_BlurRadiusConn, ff_BlurTypeConn, ff_ClipControlConn; - sigc::connection raw_caredConn, raw_cablueConn, raw_ca_autocorrectConn, raw_hotpix_filtConn, raw_deadpix_filtConn, raw_linenoiseConn, raw_greenthreshConn, raw_ccStepsConn, raw_methodConn, raw_imagenumConn, raw_dcb_iterationsConn, raw_lmmse_iterationsConn, raw_dcb_enhanceConn, raw_exposConn, raw_preserConn, raw_blackConn; + sigc::connection raw_caredblueConn, raw_caautostrengthConn, raw_ca_autocorrectConn, raw_hotpix_filtConn, raw_deadpix_filtConn, raw_linenoiseConn, raw_greenthreshConn, raw_ccStepsConn, raw_methodConn, raw_imagenumConn, raw_dcb_iterationsConn, raw_lmmse_iterationsConn, raw_pixelshiftConn, raw_dcb_enhanceConn, raw_exposConn, raw_preserConn, raw_blackConn; public: PartialPasteDlg (const Glib::ustring &title, Gtk::Window* parent); diff --git a/rtgui/profilepanel.cc b/rtgui/profilepanel.cc index 939739805..b988418f0 100644 --- a/rtgui/profilepanel.cc +++ b/rtgui/profilepanel.cc @@ -295,6 +295,8 @@ void ProfilePanel::save_clicked (GdkEventButton* event) do { if (dialog.run() == Gtk::RESPONSE_OK) { + dialog.hide(); + std::string fname = dialog.get_filename(); Glib::ustring ext = getExtension (fname); From 8bfe14da09b68e83264bdbb75e33e6a952bc7c64 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Tue, 28 Mar 2017 08:35:06 +0200 Subject: [PATCH 27/33] do not touch the chroma denoise curve in the fast export pipeline (no need to) --- rtengine/simpleprocess.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 360b892c4..c49535a3c 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1414,9 +1414,6 @@ private: for (auto &p : params.dirpyrDenoise.lcurve) { p *= scale_factor; } - for (auto &p : params.dirpyrDenoise.cccurve) { - p *= scale_factor; - } params.epd.scale *= scale_factor; //params.epd.edgeStopping *= scale_factor; From 45a66e980f01c760928e370314b4bb0bf815fc01 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Tue, 28 Mar 2017 14:01:19 +0200 Subject: [PATCH 28/33] Fix some uninitialized variables found by valgrind; also fixes #3786 --- rtgui/dirpyrdenoise.cc | 2 +- rtgui/lensprofile.cc | 2 +- rtgui/partialpastedlg.cc | 10 ---------- rtgui/retinex.cc | 2 +- 4 files changed, 3 insertions(+), 13 deletions(-) diff --git a/rtgui/dirpyrdenoise.cc b/rtgui/dirpyrdenoise.cc index bd673e5c3..1fe86c2ca 100644 --- a/rtgui/dirpyrdenoise.cc +++ b/rtgui/dirpyrdenoise.cc @@ -26,7 +26,7 @@ using namespace rtengine; using namespace rtengine::procparams; extern Options options; -DirPyrDenoise::DirPyrDenoise () : FoldableToolPanel(this, "dirpyrdenoise", M("TP_DIRPYRDENOISE_LABEL"), true, true), lastenhance(false) +DirPyrDenoise::DirPyrDenoise () : FoldableToolPanel(this, "dirpyrdenoise", M("TP_DIRPYRDENOISE_LABEL"), true, true), lastenhance(false), lastmedian(false), lastautochroma(false) { std::vector milestones; CurveListener::setMulti(true); diff --git a/rtgui/lensprofile.cc b/rtgui/lensprofile.cc index 71c54e2b5..2f4526cad 100644 --- a/rtgui/lensprofile.cc +++ b/rtgui/lensprofile.cc @@ -26,7 +26,7 @@ using namespace rtengine; using namespace rtengine::procparams; -LensProfilePanel::LensProfilePanel () : FoldableToolPanel(this, "lensprof", M("TP_LENSPROFILE_LABEL")) +LensProfilePanel::LensProfilePanel () : FoldableToolPanel(this, "lensprof", M("TP_LENSPROFILE_LABEL")), isRaw(true) { hbLCPFile = Gtk::manage(new Gtk::HBox()); diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc index 13f91fc7b..90a168066 100644 --- a/rtgui/partialpastedlg.cc +++ b/rtgui/partialpastedlg.cc @@ -105,7 +105,6 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren raw_black = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWEXPOS_BLACK"))); raw_ca_autocorrect = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_AUTO"))); raw_caredblue = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_CAREDBLUE"))); - raw_caautostrength = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_CAAUTOSTRENGTH"))); raw_hotpix_filt = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_HOTPIXFILT"))); raw_deadpix_filt = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_DEADPIXFILT"))); raw_linenoise = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_LINEDENOISE"))); @@ -230,7 +229,6 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren vboxes[6]->pack_start (*Gtk::manage (new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 0); vboxes[6]->pack_start (*raw_ca_autocorrect, Gtk::PACK_SHRINK, 2); vboxes[6]->pack_start (*raw_caredblue, Gtk::PACK_SHRINK, 2); - vboxes[6]->pack_start (*raw_caautostrength, Gtk::PACK_SHRINK, 2); //META vboxes[7]->pack_start (*meta, Gtk::PACK_SHRINK, 2); @@ -356,7 +354,6 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren raw_blackConn = raw_black->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); raw_ca_autocorrectConn = raw_ca_autocorrect->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); raw_caredblueConn = raw_caredblue->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); - raw_caautostrengthConn = raw_caautostrength->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); raw_hotpix_filtConn = raw_hotpix_filt->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); raw_deadpix_filtConn = raw_deadpix_filt->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); raw_linenoiseConn = raw_linenoise->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); @@ -436,7 +433,6 @@ void PartialPasteDlg::rawToggled () raw_blackConn.block (true); raw_ca_autocorrectConn.block (true); raw_caredblueConn.block (true); - raw_caautostrengthConn.block (true); raw_hotpix_filtConn.block (true); raw_deadpix_filtConn.block (true); raw_linenoiseConn.block (true); @@ -464,7 +460,6 @@ void PartialPasteDlg::rawToggled () raw_black->set_active (raw->get_active ()); raw_ca_autocorrect->set_active (raw->get_active ()); raw_caredblue->set_active (raw->get_active ()); - raw_caautostrength->set_active (raw->get_active ()); raw_hotpix_filt->set_active (raw->get_active ()); raw_deadpix_filt->set_active (raw->get_active ()); raw_linenoise->set_active (raw->get_active ()); @@ -490,7 +485,6 @@ void PartialPasteDlg::rawToggled () raw_blackConn.block (false); raw_ca_autocorrectConn.block (false); raw_caredblueConn.block (false); - raw_caautostrengthConn.block (false); raw_hotpix_filtConn.block (false); raw_deadpix_filtConn.block (false); raw_linenoiseConn.block (false); @@ -949,10 +943,6 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param filterPE.raw.caBlue = falsePE.raw.caBlue; } - if (!raw_caautostrength->get_active ()) { - filterPE.raw.caAutoStrength = falsePE.raw.caAutoStrength; - } - if (!raw_hotpix_filt->get_active ()) { filterPE.raw.hotPixelFilter = falsePE.raw.hotPixelFilter; } diff --git a/rtgui/retinex.cc b/rtgui/retinex.cc index b81e8f579..4686e325e 100644 --- a/rtgui/retinex.cc +++ b/rtgui/retinex.cc @@ -8,7 +8,7 @@ using namespace rtengine; using namespace rtengine::procparams; -Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), false, true) +Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), false, true), lastmedianmap(false) { CurveListener::setMulti(true); std::vector defaultCurve; From d003a9e81f67e24980feedd00039538da0aba99b Mon Sep 17 00:00:00 2001 From: heckflosse Date: Thu, 30 Mar 2017 01:09:01 +0200 Subject: [PATCH 29/33] Fix compile warnings in pixelshift.cc --- rtengine/pixelshift.cc | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/rtengine/pixelshift.cc b/rtengine/pixelshift.cc index 44e765e41..744950ba8 100644 --- a/rtengine/pixelshift.cc +++ b/rtengine/pixelshift.cc @@ -456,9 +456,9 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA const int motion = bayerParams.pixelShiftMotion; const bool showMotion = bayerParams.pixelShiftShowMotion; const bool showOnlyMask = bayerParams.pixelShiftShowMotionMaskOnly && showMotion; - const RAWParams::BayerSensor::ePSMotionCorrection gridSize_ = bayerParams.pixelShiftMotionCorrection; const bool adaptive = bayerParams.pixelShiftAutomatic; #ifdef PIXELSHIFTDEV + const RAWParams::BayerSensor::ePSMotionCorrection gridSize_ = bayerParams.pixelShiftMotionCorrection; const bool detectMotion = bayerParams.pixelShiftMotion > 0; float stddevFactorGreen = bayerParams.pixelShiftStddevFactorGreen; float stddevFactorRed = bayerParams.pixelShiftStddevFactorRed; @@ -475,25 +475,25 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA const float redBlueWeight = 0.7f + 1.f; #endif float eperIso = bayerParams.pixelShiftEperIso; - const bool checkNonGreenHorizontal = bayerParams.pixelShiftNonGreenHorizontal; - const bool checkNonGreenVertical = bayerParams.pixelShiftNonGreenVertical; const bool checkNonGreenCross = bayerParams.pixelShiftNonGreenCross; - const bool checkNonGreenAmaze = bayerParams.pixelShiftNonGreenAmaze; - const bool checkNonGreenCross2 = bayerParams.pixelShiftNonGreenCross2; const bool checkGreen = bayerParams.pixelShiftGreen; const float greenWeight = 2.f; const bool blurMap = bayerParams.pixelShiftBlur; const float sigma = bayerParams.pixelShiftSigma; #ifdef PIXELSHIFTDEV + const bool checkNonGreenHorizontal = bayerParams.pixelShiftNonGreenHorizontal; + const bool checkNonGreenVertical = bayerParams.pixelShiftNonGreenVertical; + const bool checkNonGreenAmaze = bayerParams.pixelShiftNonGreenAmaze; + const bool checkNonGreenCross2 = bayerParams.pixelShiftNonGreenCross2; const float threshold = bayerParams.pixelShiftSum + 9.f; + const bool experimental0 = bayerParams.pixelShiftExp0; + const bool automatic = bayerParams.pixelShiftMotionCorrectionMethod == RAWParams::BayerSensor::Automatic; #else constexpr float threshold = 3.f + 9.f; #endif - const bool experimental0 = bayerParams.pixelShiftExp0; const bool holeFill = bayerParams.pixelShiftHoleFill; const bool equalBrightness = bayerParams.pixelShiftEqualBright; const bool smoothTransitions = blurMap && bayerParams.pixelShiftSmoothFactor > 0. && !showOnlyMask; - const bool automatic = bayerParams.pixelShiftMotionCorrectionMethod == RAWParams::BayerSensor::Automatic; const float smoothFactor = 1.0 - bayerParams.pixelShiftSmoothFactor; static const float nReadK3II[] = { 3.4f, // ISO 100 @@ -606,8 +606,10 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA } +#ifdef PIXELSHIFTDEV const bool skip = (gridSize_ == RAWParams::BayerSensor::ePSMotionCorrection::Grid1x2); int gridSize = 1; + bool nOf3x3 = false; switch (gridSize_) { @@ -632,6 +634,9 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA gridSize = 1; nOf3x3 = true; } +#else + const bool nOf3x3 = true; +#endif if(adaptive && blurMap && nOf3x3 && smoothFactor == 0.f && !showMotion) { if(plistener) { @@ -707,9 +712,10 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA // If the values of two corresponding green pixels differ my more then motionThreshold %, the pixel will be treated as a badGreen pixel const float motionThreshold = 1.f - (motion / 100.f); // For shades of green motion indicators +#ifdef PIXELSHIFTDEV const float blendFactor = ((adaptive || motion == 0.f) ? 1.f : 1.f / (1.f - motionThreshold)); - - unsigned int offsX = 0, offsY = 0; +#endif + int offsX = 0, offsY = 0; if(!bayerParams.pixelShiftMedian || !adaptive) { // We have to adjust the offsets for the selected subframe we use for areas with motion @@ -860,9 +866,11 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA #endif for(int i = winy + border - offsY; i < winh - (border + offsY); ++i) { +#ifdef PIXELSHIFTDEV float *greenDest = green[i + offsY]; float *redDest = red[i + offsY]; float *blueDest = blue[i + offsY]; +#endif int j = winx + border - offsX; #ifdef PIXELSHIFTDEV From 08c1066e1aa107503ca2b8d043de4b4fb975777f Mon Sep 17 00:00:00 2001 From: heckflosse Date: Thu, 30 Mar 2017 17:21:27 +0200 Subject: [PATCH 30/33] Fix all warnings in curves.cc --- rtengine/LUT.h | 2 +- rtengine/curves.cc | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/rtengine/LUT.h b/rtengine/LUT.h index d83a431ca..eb22ff7f9 100644 --- a/rtengine/LUT.h +++ b/rtengine/LUT.h @@ -579,7 +579,7 @@ public: numVals = std::min(numVals, passThrough.getSize()); float mult = dest.size - 1; - for (int i = 0; i < numVals; i++) { + for (unsigned int i = 0; i < numVals; i++) { int hi = (int)(mult * passThrough[i]); dest[hi] += this->data[i] ; } diff --git a/rtengine/curves.cc b/rtengine/curves.cc index 8f2aa03d3..3096f19f4 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -45,7 +45,7 @@ using namespace std; namespace rtengine { -Curve::Curve () : N(0), ppn(0), x(nullptr), y(nullptr), mc(0.0), mfc(0.0), msc(0.0), mhc(0.0), ypp(nullptr), x1(0.0), y1(0.0), x2(0.0), y2(0.0), x3(0.0), y3(0.0), firstPointIncluded(false), increment(0.0), nbr_points(0), hashSize(1000 /* has to be initialized to the maximum value */) {} +Curve::Curve () : N(0), ppn(0), x(nullptr), y(nullptr), mc(0.0), mfc(0.0), msc(0.0), mhc(0.0), hashSize(1000 /* has to be initialized to the maximum value */), ypp(nullptr), x1(0.0), y1(0.0), x2(0.0), y2(0.0), x3(0.0), y3(0.0), firstPointIncluded(false), increment(0.0), nbr_points(0) {} void Curve::AddPolygons () { @@ -104,7 +104,7 @@ void Curve::fillHash() milestone = 0.; polyIter = 0; - for (unsigned int i = 0; i < (hashSize + 1);) { + for (unsigned int i = 0; i < hashSize + 1u;) { while(poly_x[polyIter] < (milestone + increment)) { ++polyIter; } @@ -1376,7 +1376,7 @@ void ColorGradientCurve::SetXYZ(const Curve *pCurve, const double xyz_rgb[3][3], } float r, g, b, xx, yy, zz; - float lr1, lr2; + float lr1, lr2 = 0.f; int upperBound = lut1.getUpperBound(); if (pCurve->isIdentity()) { @@ -1765,7 +1765,7 @@ float PerceptualToneCurve::get_curve_val(float x, float range[2], float lut[], s int idx = (int)xm; - if (idx >= lut_size - 1) { + if (idx >= static_cast(lut_size) - 1) { return lut[lut_size - 1]; } @@ -1790,7 +1790,7 @@ float PerceptualToneCurve::calculateToneCurveContrastValue() const const float xd = 0.07; const float tx[] = { 0.30, 0.35, 0.40, 0.45 }; // we only look in the midtone range - for (int i = 0; i < sizeof(tx) / sizeof(tx[0]); i++) { + for (size_t i = 0; i < sizeof(tx) / sizeof(tx[0]); i++) { float x0 = tx[i] - xd; float y0 = CurveFactory::gamma2(lutToneCurve[CurveFactory::igamma2(x0) * 65535.f] / 65535.f) - k * x0; float x1 = tx[i] + xd; @@ -1807,7 +1807,7 @@ float PerceptualToneCurve::calculateToneCurveContrastValue() const { const float tx[] = { 0.20, 0.25, 0.50, 0.55 }; // we only look in the midtone range - for (int i = 0; i < sizeof(tx) / sizeof(tx[0]); i++) { + for (size_t i = 0; i < sizeof(tx) / sizeof(tx[0]); i++) { float x0 = tx[i] - xd; float y0 = CurveFactory::gamma2(lutToneCurve[CurveFactory::igamma2(x0) * 65535.f] / 65535.f) - k * x0; float x1 = tx[i] + xd; From 0c536e26601eae225970ebecfba88ff00175e99e Mon Sep 17 00:00:00 2001 From: heckflosse Date: Thu, 30 Mar 2017 17:33:05 +0200 Subject: [PATCH 31/33] Fix all warnings in diagonalcurves.cc --- rtengine/diagonalcurves.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtengine/diagonalcurves.cc b/rtengine/diagonalcurves.cc index 2178e3dac..9ab17a0f4 100644 --- a/rtengine/diagonalcurves.cc +++ b/rtengine/diagonalcurves.cc @@ -241,8 +241,8 @@ void DiagonalCurve::NURBS_set () nbr_points = (int)(((double)(ppn + N - 2) * sc_length[i / 3] ) / total_length); if (nbr_points < 0) { - for(size_t it = 0; it < sc_x.size(); it += 3) { - printf("sc_length[%zu/3]=%f \n", it, sc_length[it / 3]); + for(unsigned int it = 0; it < sc_x.size(); it += 3) { // used unsigned int instead of size_t to avoid %zu in printf + printf("sc_length[%u/3]=%f \n", it, sc_length[it / 3]); } printf("NURBS diagonal curve: error detected!\n i=%u nbr_points=%d ppn=%d N=%d sc_length[i/3]=%f total_length=%f", i, nbr_points, ppn, N, sc_length[i / 3], total_length); From 348b393583f5f010193f13ac47c685915127203b Mon Sep 17 00:00:00 2001 From: heckflosse Date: Thu, 30 Mar 2017 17:46:00 +0200 Subject: [PATCH 32/33] Fix all warnings in color.cc --- rtengine/color.cc | 35 +++-------------------------------- 1 file changed, 3 insertions(+), 32 deletions(-) diff --git a/rtengine/color.cc b/rtengine/color.cc index 5cf1d45b1..b67343b82 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -1530,18 +1530,8 @@ void Color::interpolateRGBColor (float realL, float iplow, float iphigh, int alg int toDo, const double xyz_rgb[3][3], const double rgb_xyz[3][3], float &ro, float &go, float &bo) { float X1, Y1, Z1, X2, Y2, Z2, X, Y, Z, XL, YL, ZL; - float L1, L2, LL, a_1, b_1, a_2, b_2, a, b, a_L, b_L; - float c1, c2, h1, h2, cL, hL; - float RR, GG, BB; - float Lr; - float slc = 0.f; - float hh = 0.f; - float ll = 0.f; - float sh = 0.f; - bool LCH = false; + float L1, L2, LL, a_1 = 0.f, b_1 = 0.f, a_2, b_2, a_L, b_L; - float ha, hb, hc, ba; - float c_1, h_1; // converting color 1 to Lab (image) Color::rgbxyz(r1, g1, b1, X1, Y1, Z1, xyz_rgb); @@ -1566,19 +1556,16 @@ void Color::interpolateRGBColor (float realL, float iplow, float iphigh, int alg X2 = x2; Y2 = y2; Z2 = z2; - float c_2, h_2; if(algm == 1 ) { Color::XYZ2Lab(X2, Y2, Z2, L2, a_2, b_2); //Color::Lab2Lch(a_2, b_2, c_2, h_2) ; } - float bal, balH, cal, calH, calm; - bal = balH = balance; + float cal, calH, calm; cal = calH = calm = 1.f - chromat; float med = 1.f; float medH = 0.f; - float medL = (iphigh + iplow) / 2.f; float calan; calan = chromat; @@ -1589,19 +1576,6 @@ void Color::interpolateRGBColor (float realL, float iplow, float iphigh, int alg if(twoc == 0) { // 2 colours calan = chromat; - //calculate new balance in function of (arbitrary) "med".. I hope no error !! - if (realL > iplow && realL <= med) { - bal = realL * balance / (iplow - med) - med * balance / (iplow - med); - } else if (realL <= iplow) { - bal = realL * balance / iplow; - } - - if (realL > medH && realL <= iphigh) { - balH = realL * balance / (iphigh - medH) - medH * balance / (iphigh - medH); - } else if (realL > iphigh) { - balH = realL * balance * (iphigh - 1.f) - balance * (iphigh - 1.f); - } - //calculate new balance chroma if (realL > iplow && realL <= med) { cal = realL * calan / (iplow - med) - med * calan / (iplow - med); @@ -1616,8 +1590,7 @@ void Color::interpolateRGBColor (float realL, float iplow, float iphigh, int alg } } - float hX = 0.f; - float hLL, hH, ccL, ccH, llH, aaH, bbH; + float aaH, bbH; if(algm <= 1) { if(twoc == 0 && metchrom == 3) { // 2 colours only with special "ab" @@ -1639,8 +1612,6 @@ void Color::interpolateRGBColor (float realL, float iplow, float iphigh, int alg b_1 = b_1 + (b_2 - b_1) * calby * balance; } } - } else { - h1 = hX; } Color::Lab2XYZ(L1, a_1, b_1, X, Y, Z); From f0b7547cbb1295489277587702a5c085aed0550e Mon Sep 17 00:00:00 2001 From: heckflosse Date: Thu, 30 Mar 2017 18:23:18 +0200 Subject: [PATCH 33/33] Fix all warnings in rawimage.cc --- rtengine/rawimage.cc | 48 ++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index 2cd1abf5f..f3252b06b 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -25,9 +25,9 @@ RawImage::RawImage( const Glib::ustring &name ) : data(nullptr) , prefilters(0) , filename(name) + , rotate_deg(0) , profile_data(nullptr) , allocation(nullptr) - , rotate_deg(0) { memset(maximum_c4, 0, sizeof(maximum_c4)); RT_matrix_from_constant = 0; @@ -84,9 +84,9 @@ eSensorType RawImage::getSensorType() */ void RawImage::get_colorsCoeff( float *pre_mul_, float *scale_mul_, float *cblack_, bool forceAutoWB) { - unsigned row, col, x, y, c, sum[8]; - unsigned W = this->get_width(); - unsigned H = this->get_height(); + unsigned sum[8], c; + unsigned W = this->get_width(); + unsigned H = this->get_height(); float val; double dsum[8], dmin, dmax; @@ -118,7 +118,7 @@ void RawImage::get_colorsCoeff( float *pre_mul_, float *scale_mul_, float *cblac dsum[FC(1, 0) + 4] += (int)(((W + 1) / 2) * (H / 2)); dsum[FC(1, 1) + 4] += (int)((W / 2) * (H / 2)); - #pragma omp parallel private(val,row,col,x,y) + #pragma omp parallel private(val) { double dsumthr[8]; memset(dsumthr, 0, sizeof dsumthr); @@ -135,15 +135,15 @@ void RawImage::get_colorsCoeff( float *pre_mul_, float *scale_mul_, float *cblac float *tempdata = data[0]; #pragma omp for nowait - for (row = 0; row < H; row += 8) { - int ymax = row + 8 < H ? row + 8 : H; + for (size_t row = 0; row < H; row += 8) { + size_t ymax = row + 8 < H ? row + 8 : H; - for (col = 0; col < W ; col += 8) { - int xmax = col + 8 < W ? col + 8 : W; + for (size_t col = 0; col < W ; col += 8) { + size_t xmax = col + 8 < W ? col + 8 : W; memset(sum, 0, sizeof sum); - for (y = row; y < ymax; y++) - for (x = col; x < xmax; x++) { + for (size_t y = row; y < ymax; y++) + for (size_t x = col; x < xmax; x++) { int c = FC(y, x); val = tempdata[y * W + x]; @@ -204,13 +204,13 @@ skip_block2: #pragma omp for nowait - for (int row = 0; row < H; row += 8) - for (int col = 0; col < W ; col += 8) + for (size_t row = 0; row < H; row += 8) + for (size_t col = 0; col < W ; col += 8) { memset(sum, 0, sizeof sum); - for (int y = row; y < row + 8 && y < H; y++) - for (int x = col; x < col + 8 && x < W; x++) { + for (size_t y = row; y < row + 8 && y < H; y++) + for (size_t x = col; x < col + 8 && x < W; x++) { int c = XTRANSFC(y, x); float val = data[y][x]; @@ -248,12 +248,12 @@ skip_block3: pre_mul_[c] = 1; } } else { - for (row = 0; row < H; row += 8) - for (col = 0; col < W ; col += 8) { + for (size_t row = 0; row < H; row += 8) + for (size_t col = 0; col < W ; col += 8) { memset(sum, 0, sizeof sum); - for (y = row; y < row + 8 && y < H; y++) - for (x = col; x < col + 8 && x < W; x++) + for (size_t y = row; y < row + 8 && y < H; y++) + for (size_t x = col; x < col + 8 && x < W; x++) for (int c = 0; c < 3; c++) { if (this->isBayer()) { c = FC(y, x); @@ -294,8 +294,8 @@ skip_block: } else { memset(sum, 0, sizeof sum); - for (row = 0; row < 8; row++) - for (col = 0; col < 8; col++) { + for (size_t row = 0; row < 8; row++) + for (size_t col = 0; col < 8; col++) { int c = FC(row, col); if ((val = white[row][col] - cblack_[c]) > 0) { @@ -604,7 +604,7 @@ int RawImage::loadRaw (bool loadData, unsigned int imageNum, bool closeFile, Pro if(tiff_bps > 0 && maximum_c4[i] > 0 && !isFoveon()) { unsigned compare = ((uint64_t)1 << tiff_bps) - 1; // use uint64_t to avoid overflow if tiff_bps == 32 - while(maximum_c4[i] > compare) { + while(static_cast(maximum_c4[i]) > compare) { maximum_c4[i] >>= 1; } } @@ -632,7 +632,7 @@ int RawImage::loadRaw (bool loadData, unsigned int imageNum, bool closeFile, Pro } for (int c = 0; c < 4; c++) { - if (cblack[c] < black_c4[c]) { + if (static_cast(cblack[c]) < black_c4[c]) { cblack[c] = black_c4[c]; } } @@ -1074,7 +1074,7 @@ DCraw::dcraw_coeff_overrides(const char make[], const char model[], const int is char name[strlen(make) + strlen(model) + 32]; sprintf(name, "%s %s", make, model); - for (int i = 0; i < sizeof table / sizeof(table[0]); i++) { + for (size_t i = 0; i < sizeof table / sizeof(table[0]); i++) { if (strcasecmp(name, table[i].prefix) == 0) { *black_level = table[i].black_level; *white_level = table[i].white_level;