From 9713604b12d6978ea168c7d56c7abb85d73e2cab Mon Sep 17 00:00:00 2001 From: Desmis Date: Sat, 23 Dec 2017 09:34:39 +0100 Subject: [PATCH] add bilateral to local denoise and enhanced GUI --- rtdata/languages/default | 2 + rtengine/dcrop.cc | 2 + rtengine/improccoordinator.cc | 38 ++++- rtengine/improccoordinator.h | 1 + rtengine/improcfun.h | 1 + rtengine/iplocallab.cc | 279 +++++++++++++++++++++++++++++++++- rtengine/procevents.h | 39 ++++- rtengine/procparams.cc | 4 + rtengine/procparams.h | 6 +- rtengine/refreshmap.cc | 7 +- rtengine/simpleprocess.cc | 5 +- rtgui/locallab.cc | 52 +++++-- rtgui/locallab.h | 4 +- rtgui/paramsedited.cc | 16 +- rtgui/paramsedited.h | 4 +- 15 files changed, 422 insertions(+), 38 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 06a69f2cf..71aa6aaad 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -843,6 +843,7 @@ HISTORY_MSG_594;Local - Noise chro detail HISTORY_MSG_595;Local - Noise Scope HISTORY_MSG_597;Local L*a*b* HISTORY_MSG_598;Local - Bottom +HISTORY_MSG_599;Local - Noise bilateral HISTORY_MSG_LOCALCONTRAST_AMOUNT;Local Contrast - Amount HISTORY_MSG_LOCALCONTRAST_DARKNESS;Local Contrast - Darkness HISTORY_MSG_LOCALCONTRAST_ENABLED;Local Contrast @@ -1826,6 +1827,7 @@ TP_LOCALLAB_ADJBLUR;Adjust and Blur TP_LOCALLAB_ARTIF;Reduce artifacts - Improve algoritm TP_LOCALLAB_ARTIF_TOOLTIP;Only active for Color-light, Exposure, Retinex, Vibrance, ToneMapping, CBDL. TP_LOCALLAB_AVOID;Avoid color shift +TP_LOCALLAB_BILATERAL;Bilateral filter TP_LOCALLAB_BLMETHOD_TOOLTIP;Normal - direct blur and noise with all settings.\nInverse - Inverse blur and noise without scope and whithout enhanced algorithm.\nSymmetric - inverse blur and noise with all settings. Be careful some results may be curious TP_LOCALLAB_BLUFR;Blur & Noise TP_LOCALLAB_BLNORM;Normal diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 75b0ea546..a2f94185c 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -1205,6 +1205,7 @@ void Crop::update(int todo) params.locallab.expexpose = true; } + params.locallab.bilateral = parent->bilaterals[sp]; std::vector cretie; @@ -1679,6 +1680,7 @@ void Crop::update(int todo) } + parent->bilaterals[sp] = params.locallab.bilateral = parent->bilaterals[0]; std::vector ccret; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index a892207f6..03e81266f 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -157,6 +157,7 @@ ImProcCoordinator::ImProcCoordinator() noiselumcs(500, -10000), noiselumdetails(500, -10000), noisechrodetails(500, -10000), + bilaterals(500, -10000), sensidens(500, -10000), noisechrofs(500, -10000), noisechrocs(500, -10000), @@ -873,7 +874,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) }; - int maxdata = 99; // 90 10020 //88 10019//87 10018 //86 10017 //85 10016;// 82 10015//78;//73 for 10011 + int maxdata = 100; //99 10021 // 90 10020 //88 10019//87 10018 //86 10017 //85 10016;// 82 10015//78;//73 for 10011 if (fic0) { //find current version mip @@ -917,7 +918,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) //initilize newues when first utilisation of Locallab. Prepare creation of Mip files for (int sp = 1; sp < maxspot; sp++) { // spots default int t_sp = sp; - int t_mipversion = 10021;//new value for each change + int t_mipversion = 10022;//new value for each change int t_circrad = 18; int t_locX = 250; int t_locY = 250; @@ -1048,6 +1049,9 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) //10021 int t_expdenoi = 0; + //10022 + int t_bilateral = 0; + int t_expcolor = 0; int t_expvibrance = 0; int t_expblur = 0; @@ -1151,6 +1155,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) fic << "Warm=" << t_warm << '@' << endl; fic << "Noiselumdetail=" << t_noiselumdetail << '@' << endl; fic << "Noisechrodetail=" << t_noisechrodetail << '@' << endl; + fic << "Sensiden=" << t_sensiden << '@' << endl; fic << "Expdenoi=" << t_expdenoi << '@' << endl; fic << "Expcolor=" << t_expcolor << '@' << endl; @@ -1162,6 +1167,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) fic << "Expcbdl=" << t_expcbdl << '@' << endl; fic << "Expexpose=" << t_expexpose << '@' << endl; + fic << "Bilateral=" << t_bilateral << '@' << endl; + fic << "curveReti=" << t_curvret << '@' << endl; fic << "curveLL=" << t_curvll << '@' << endl; fic << "curveLH=" << t_curvlh << '@' << endl; @@ -1471,6 +1478,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) dataspot[93][0] = expexposes[0] = 1; } + dataspot[94][0] = bilaterals[0] = params.locallab.bilateral; // for all curves work around - I do not know how to do with params curves... //curve Reti local @@ -1773,6 +1781,10 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) maxind = 84; } + if (versionmip == 10021) { + maxind = 92; + } + while (getline(fich, line)) { spotline = line; std::size_t pos = spotline.find("="); @@ -2026,7 +2038,12 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) } } + if (versionmip <= 10021) {// + for (int sp = 1; sp < maxspot; sp++) { // spots default + dataspot[94][sp] = 0; + } + } //here we change the number of spot @@ -2036,7 +2053,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) for (int sp = ns + 1 ; sp < maxspot; sp++) { // spots default int t_sp = sp; - int t_mipversion = 10021; + int t_mipversion = 10022; int t_circrad = 18; int t_locX = 250; int t_locY = 250; @@ -2168,6 +2185,9 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) int t_expcbdl = 0; int t_expexpose = 0; + //10022 + int t_bilateral = 0; + fic << "Mipversion=" << t_mipversion << '@' << endl; fic << "Spot=" << t_sp << '@' << endl; fic << "Circrad=" << t_circrad << '@' << endl; @@ -2258,6 +2278,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) fic << "Warm=" << t_warm << '@' << endl; fic << "Noiselumdetail=" << t_noiselumdetail << '@' << endl; fic << "Noisechrodetail=" << t_noisechrodetail << '@' << endl; + fic << "Sensiden=" << t_sensiden << '@' << endl; fic << "Expdenoi=" << t_expdenoi << '@' << endl; fic << "Expcolor=" << t_expcolor << '@' << endl; @@ -2269,6 +2290,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) fic << "Expcbdl=" << t_expcbdl << '@' << endl; fic << "Expexpose=" << t_expexpose << '@' << endl; + fic << "Bilateral=" << t_bilateral << '@' << endl; + fic << "curveReti=" << t_curvret << '@' << endl; fic << "curveLL=" << t_curvll << '@' << endl; fic << "curveLH=" << t_curvlh << '@' << endl; @@ -2694,6 +2717,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) params.locallab.expexpose = true; } + params.locallab.bilateral = bilaterals[sp] = dataspot[94][sp]; int *s_datc; s_datc = new int[70]; @@ -3333,6 +3357,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) expexposes[sp] = 1; } + dataspot[94][sp] = bilaterals[sp] = params.locallab.bilateral = dataspot[94][0]; + int *s_datc; s_datc = new int[70]; int siz; @@ -3572,7 +3598,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) for (int spe = 1; spe < maxspot; spe++) { int t_sp = spe; - int t_mipversion = 10021; + int t_mipversion = 10022; int t_circrad = dataspot[2][spe]; int t_locX = dataspot[3][spe]; int t_locY = dataspot[4][spe]; @@ -3674,6 +3700,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) int t_expcbdl = dataspot[92][spe]; int t_expexpose = dataspot[93][spe]; + int t_bilateral = dataspot[94][spe]; + int t_huerefblur = dataspot[maxdata - 5][spe]; int t_hueref = dataspot[maxdata - 4][spe]; int t_chromaref = dataspot[maxdata - 3][spe]; @@ -3793,6 +3821,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) fou << "Expcbdl=" << t_expcbdl << '@' << endl; fou << "Expexpose=" << t_expexpose << '@' << endl; + fou << "Bilateral=" << t_bilateral << '@' << endl; + fou << "huerefblur=" << t_huerefblur << '@' << endl; fou << "hueref=" << t_hueref << '@' << endl; fou << "chromaref=" << t_chromaref << '@' << endl; diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index b6e73abc3..bd91316d9 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -308,6 +308,7 @@ protected: LUTi noiselumcs; LUTi noiselumdetails; LUTi noisechrodetails; + LUTi bilaterals; LUTi sensidens; LUTi noisechrofs; LUTi noisechrocs; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index e06d6f140..1a2abce58 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -318,6 +318,7 @@ public: //void DeNoise_Local(int call, const struct local_params& lp, LabImage* original, LabImage* transformed, const LabImage &tmp1, int cx, int cy); // void ColorLight_Local(int call, LabImage * bufcolorig, float **buflight, float **bufchro, float **bufchroslid, float ** bufhh, float ** buflightslid, bool &LHutili, bool &HHutili, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, const local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy); void DeNoise_Local(int call, const struct local_params& lp, int levred, float hueplus, float huemoins, float hueref, float dhueden, LabImage* original, LabImage* transformed, const LabImage &tmp1, int cx, int cy, int sk); + void DeNoise_Local_imp(const struct local_params& lp, int levred, float hueplus, float huemoins, float hueref, float dhueden, LabImage* original, LabImage* transformed, LabImage* tmp1, int cx, int cy, int sk); void fftw_denoise(int GW, int GH, int max_numblox_W, int min_numblox_W, float **tmp1, array2D *Lin, int numThreads, const struct local_params & lp, int chrom); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 7d3145c60..e22fc88a8 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -145,6 +145,7 @@ struct local_params { float noiself; float noiseldetail; float noisechrodetail; + float bilat; float noiselc; float noisecf; float noisecc; @@ -471,7 +472,7 @@ static void calcLocalParams(int oW, int oH, const LocallabParams& locallab, stru lp.noisecf = local_noisecf; lp.noisecc = local_noisecc; lp.sensden = local_sensiden; - + lp.bilat = locallab.bilateral; lp.strengt = streng; lp.gamm = gam; @@ -1864,6 +1865,229 @@ void ImProcFunctions::addGaNoise(LabImage *lab, LabImage *dst, const float mean, } } +void ImProcFunctions::DeNoise_Local_imp(const struct local_params& lp, int levred, float hueplus, float huemoins, float hueref, float dhueden, LabImage* original, LabImage* transformed, LabImage* tmp1, int cx, int cy, int sk) +{ + // local denoise + //simple algo , perhaps we can improve as the others, but noise is here and not good for hue detection + // BENCHFUN + const float ach = (float)lp.trans / 100.f; + constexpr float delhu = 0.1f; //between 0.05 and 0.2 + + + float factnoise1 = 1.f + (lp.noisecf) / 500.f; + float factnoise2 = 1.f + (lp.noisecc) / 500.f; + + constexpr float apl = (-1.f) / delhu; + const float bpl = - apl * hueplus; + constexpr float amo = 1.f / delhu; + const float bmo = - amo * huemoins; + /* + constexpr float pb = 4.f; + constexpr float pa = (1.f - pb) / 40.f; + */ + int GW = transformed->W; + int GH = transformed->H; + + LabImage *origblur = nullptr; + + origblur = new LabImage(GW, GH); + + float radius = 3.f / sk; +#ifdef _OPENMP + #pragma omp parallel +#endif + { + gaussianBlur(original->L, origblur->L, GW, GH, radius); + gaussianBlur(original->a, origblur->a, GW, GH, radius); + gaussianBlur(original->b, origblur->b, GW, GH, radius); + + } + + /* + const float ahu = 1.f / (2.8f * lp.sensden - 280.f); + const float bhu = 1.f - ahu * 2.8f * lp.sensden; + */ +#ifdef _OPENMP + #pragma omp parallel if (multiThread) +#endif + { +#ifdef __SSE2__ + float atan2Buffer[transformed->W] ALIGNED16; + float sqrtBuffer[transformed->W] ALIGNED16; + vfloat c327d68v = F2V(327.68f); +#endif + +#ifdef _OPENMP + #pragma omp for schedule(dynamic,16) +#endif + + for (int y = 0; y < transformed->H; y++) { + const int loy = cy + y; + + const bool isZone0 = loy > lp.yc + lp.ly || loy < lp.yc - lp.lyT; // whole line is zone 0 => we can skip a lot of processing + + if (isZone0) { // outside selection and outside transition zone => no effect, keep original values + for (int x = 0; x < transformed->W; x++) { + transformed->L[y][x] = original->L[y][x]; + transformed->a[y][x] = original->a[y][x]; + transformed->b[y][x] = original->b[y][x]; + } + + continue; + } + +#ifdef __SSE2__ + int i = 0; + + for (; i < transformed->W - 3; i += 4) { + vfloat av = LVFU(origblur->a[y][i]); + vfloat bv = LVFU(origblur->b[y][i]); + STVF(atan2Buffer[i], xatan2f(bv, av)); + STVF(sqrtBuffer[i], _mm_sqrt_ps(SQRV(bv) + SQRV(av)) / c327d68v); + } + + for (; i < transformed->W; i++) { + atan2Buffer[i] = xatan2f(origblur->b[y][i], origblur->a[y][i]); + sqrtBuffer[i] = sqrt(SQR(origblur->b[y][i]) + SQR(origblur->a[y][i])) / 327.68f; + } + +#endif + + for (int x = 0, lox = cx + x; x < transformed->W; x++, lox++) { + int zone = 0; + // int lox = cx + x; + int begx = int (lp.xc - lp.lxL); + int begy = int (lp.yc - lp.lyT); + + float localFactor = 1.f; + calcTransition(lox, loy, ach, lp, zone, localFactor); + + if (zone == 0) { // outside selection and outside transition zone => no effect, keep original values + transformed->L[y][x] = original->L[y][x]; + transformed->a[y][x] = original->a[y][x]; + transformed->b[y][x] = original->b[y][x]; + continue; + } + +#ifdef __SSE2__ + const float rhue = atan2Buffer[x]; + // const float rchro = sqrtBuffer[x]; +#else + const float rhue = xatan2f(origblur->b[y][x], origblur->a[y][x]); + // const float rchro = sqrt(SQR(origblur->b[y][x]) + SQR(origblur->a[y][x])) / 327.68f; +#endif + + // float rL = original->L[y][x] / 327.68f; + + float khu = 0.f; + // bool kzon = false; + + // algo with detection of hue ==> artifacts for noisy images ==> denoise before + if (levred == 7 && lp.sensden < 90.f) { // after 90 plein effect + //hue detection + if ((hueref + dhueden) < rtengine::RT_PI && rhue < hueplus && rhue > huemoins) { //transition are good + if (rhue >= hueplus - delhu) { + khu = apl * rhue + bpl; + } else if (rhue < huemoins + delhu) { + khu = amo * rhue + bmo; + } else { + khu = 1.f; + } + + // kzon = true; + + } else if ((hueref + dhueden) >= rtengine::RT_PI && (rhue > huemoins || rhue < hueplus)) { + if (rhue >= hueplus - delhu && rhue < hueplus) { + khu = apl * rhue + bpl; + } else if (rhue >= huemoins && rhue < huemoins + delhu) { + khu = amo * rhue + bmo; + } else { + khu = 1.f; + } + + // kzon = true; + + } + + if ((hueref - dhueden) > -rtengine::RT_PI && rhue < hueplus && rhue > huemoins) { + if (rhue >= hueplus - delhu && rhue < hueplus) { + khu = apl * rhue + bpl; + } else if (rhue >= huemoins && rhue < huemoins + delhu) { + khu = amo * rhue + bmo; + } else { + khu = 1.f; + } + + // kzon = true; + + } else if ((hueref - dhueden) <= -rtengine::RT_PI && (rhue > huemoins || rhue < hueplus)) { + if (rhue >= hueplus - delhu && rhue < hueplus) { + khu = apl * rhue + bpl; + } else if (rhue >= huemoins && rhue < huemoins + delhu) { + khu = amo * rhue + bmo; + } else { + khu = 1.f; + } + + // kzon = true; + + } + } else { + khu = 1.f; + } + + switch (zone) { + case 0: { // outside selection and outside transition zone => no effect, keep original values + transformed->L[y][x] = original->L[y][x]; + transformed->a[y][x] = original->a[y][x]; + transformed->b[y][x] = original->b[y][x]; + break; + } + + case 1: { // inside transition zone + float factorx = localFactor; + float difL, difa, difb; + + difL = tmp1->L[loy - begy][lox - begx] - original->L[y][x]; + difa = tmp1->a[loy - begy][lox - begx] - original->a[y][x]; + difb = tmp1->b[loy - begy][lox - begx] - original->b[y][x]; + + difL *= factorx * khu; + difa *= factorx * khu; + difb *= factorx * khu; + transformed->L[y][x] = original->L[y][x] + difL; + transformed->a[y][x] = (original->a[y][x] + difa) * factnoise1 * factnoise2; + transformed->b[y][x] = (original->b[y][x] + difb) * factnoise1 * factnoise2 ; + break; + } + + case 2: { // inside selection => full effect, no transition + float difL, difa, difb; + + difL = tmp1->L[loy - begy][lox - begx] - original->L[y][x]; + difa = tmp1->a[loy - begy][lox - begx] - original->a[y][x]; + difb = tmp1->b[loy - begy][lox - begx] - original->b[y][x]; + + difL *= khu; + difa *= khu; + difb *= khu; + + transformed->L[y][x] = original->L[y][x] + difL; + transformed->a[y][x] = (original->a[y][x] + difa) * factnoise1 * factnoise2; + transformed->b[y][x] = (original->b[y][x] + difb) * factnoise1 * factnoise2; + } + } + + } + } + } + delete origblur; + +} + + + + void ImProcFunctions::DeNoise_Local(int call, const struct local_params& lp, int levred, float hueplus, float huemoins, float hueref, float dhueden, LabImage* original, LabImage* transformed, const LabImage &tmp1, int cx, int cy, int sk) { // local denoise @@ -9173,6 +9397,59 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, // } + //local impulse + if ((lp.bilat > 0.f) && lp.denoiena) { + int bfh = int (lp.ly + lp.lyT) + del; //bfw bfh real size of square zone + int bfw = int (lp.lx + lp.lxL) + del; + + LabImage *bufwv = nullptr; + + + bufwv = new LabImage(bfw, bfh); //buffer for data in zone limit + + + int begy = lp.yc - lp.lyT; + int begx = lp.xc - lp.lxL; + int yEn = lp.yc + lp.ly; + int xEn = lp.xc + lp.lx; + float hueplus = huerefblur + dhueden; + float huemoins = huerefblur - dhueden; + + if (hueplus > rtengine::RT_PI) { + hueplus = huerefblur + dhueden - 2.f * rtengine::RT_PI; + } + + if (huemoins < -rtengine::RT_PI) { + huemoins = huerefblur - dhueden + 2.f * rtengine::RT_PI; + } + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int y = 0; y < transformed->H ; y++) //{ + for (int x = 0; x < transformed->W; x++) { + int lox = cx + x; + int loy = cy + y; + + if (lox >= begx && lox < xEn && loy >= begy && loy < yEn) { + bufwv->L[loy - begy][lox - begx] = original->L[y][x];//fill square buffer with datas + bufwv->a[loy - begy][lox - begx] = original->a[y][x];//fill square buffer with datas + bufwv->b[loy - begy][lox - begx] = original->b[y][x];//fill square buffer with datas + } + + } + + double thr = (float) lp.bilat / 20.0; + + if (bfh > 8 && bfw > 8) { + ImProcFunctions::impulse_nr(bufwv, thr); + } + + DeNoise_Local_imp(lp, levred, hueplus, huemoins, huerefblur, dhueden, original, transformed, bufwv, cx, cy, sk); + delete bufwv; + } + //local denoise //all these variables are to prevent use of denoise when non necessary // but with qualmet = 2 (default for best quality) we must denoise chroma with little values to prevent artifacts due to variations of Hue diff --git a/rtengine/procevents.h b/rtengine/procevents.h index e8311025d..6420d180e 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -625,30 +625,53 @@ enum ProcEventCode { Evlocallabhuerefblur = 595, EvlocallabEnabled = 596, EvlocallablocY = 597, + Evlocallabbilateral = 598, NUMOFEVENTS }; -class ProcEvent { +class ProcEvent +{ public: ProcEvent(): code_(0) {} ProcEvent(ProcEventCode code): code_(code) {} explicit ProcEvent(int code): code_(code) {} - operator int() { return code_; } + operator int() + { + return code_; + } private: int code_; }; -inline bool operator==(ProcEvent a, ProcEvent b) { return int(a) == int(b); } -inline bool operator==(ProcEvent a, ProcEventCode b) { return int(a) == int(b); } -inline bool operator==(ProcEventCode a, ProcEvent b) { return int(a) == int(b); } -inline bool operator!=(ProcEvent a, ProcEvent b) { return int(a) != int(b); } -inline bool operator!=(ProcEvent a, ProcEventCode b) { return int(a) != int(b); } -inline bool operator!=(ProcEventCode a, ProcEvent b) { return int(a) != int(b); } +inline bool operator==(ProcEvent a, ProcEvent b) +{ + return int(a) == int(b); +} +inline bool operator==(ProcEvent a, ProcEventCode b) +{ + return int(a) == int(b); +} +inline bool operator==(ProcEventCode a, ProcEvent b) +{ + return int(a) == int(b); +} +inline bool operator!=(ProcEvent a, ProcEvent b) +{ + return int(a) != int(b); +} +inline bool operator!=(ProcEvent a, ProcEventCode b) +{ + return int(a) != int(b); +} +inline bool operator!=(ProcEventCode a, ProcEvent b) +{ + return int(a) != int(b); +} } #endif diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 9a7aa66b0..5bde058e5 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2406,6 +2406,7 @@ noiselumf(0), noiselumc(0), noiselumdetail(0), noisechrodetail(0), +bilateral(0), sensiden(30), noisechrof(0), noisechroc(0), @@ -2542,6 +2543,7 @@ bool LocallabParams::operator ==(const LocallabParams& other) const && noiselumc == other.noiselumc && noiselumdetail == other.noiselumdetail && noisechrodetail == other.noisechrodetail + && bilateral == other.bilateral && sensiden == other.sensiden && noisechrof == other.noisechrof && noisechroc == other.noisechroc @@ -3534,6 +3536,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->locallab.noiselumc, "Locallab", "noiselumc", locallab.noiselumc, keyFile); saveToKeyfile(!pedited || pedited->locallab.noiselumdetail, "Locallab", "noiselumdetail", locallab.noiselumdetail, keyFile); saveToKeyfile(!pedited || pedited->locallab.noisechrodetail, "Locallab", "noisechrodetail", locallab.noisechrodetail, keyFile); + saveToKeyfile(!pedited || pedited->locallab.bilateral, "Locallab", "Bilateral", locallab.bilateral, keyFile); saveToKeyfile(!pedited || pedited->locallab.sensiden, "Locallab", "Sensiden", locallab.sensiden, keyFile); saveToKeyfile(!pedited || pedited->locallab.noisechrof, "Locallab", "noisechrof", locallab.noisechrof, keyFile); saveToKeyfile(!pedited || pedited->locallab.noisechroc, "Locallab", "noisechroc", locallab.noisechroc, keyFile); @@ -4610,6 +4613,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "noiselumc", pedited, locallab.noiselumc, pedited->locallab.noiselumc); assignFromKeyfile(keyFile, "Locallab", "noiselumdetail", pedited, locallab.noiselumdetail, pedited->locallab.noiselumdetail); assignFromKeyfile(keyFile, "Locallab", "noisechrodetail", pedited, locallab.noisechrodetail, pedited->locallab.noisechrodetail); + assignFromKeyfile(keyFile, "Locallab", "Bilateral", pedited, locallab.bilateral, pedited->locallab.bilateral); assignFromKeyfile(keyFile, "Locallab", "Sensiden", pedited, locallab.sensiden, pedited->locallab.sensiden); assignFromKeyfile(keyFile, "Locallab", "noisechrof", pedited, locallab.noisechrof, pedited->locallab.noisechrof); assignFromKeyfile(keyFile, "Locallab", "noisechroc", pedited, locallab.noisechroc, pedited->locallab.noisechroc); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 1eab032a7..e6afc4ada 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -343,8 +343,7 @@ struct RetinexParams { /** * Parameters of the luminance curve */ -struct LCurveParams -{ +struct LCurveParams { bool enabled; std::vector lcurve; std::vector acurve; @@ -371,7 +370,7 @@ struct LCurveParams /** * Parameters for local contrast - */ + */ struct LocalContrastParams { bool enabled; int radius; @@ -936,6 +935,7 @@ struct LocallabParams { int noiselumc; int noiselumdetail; int noisechrodetail; + int bilateral; int sensiden; int noisechrof; int noisechroc; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 3038bf6b1..9c3626e6f 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -624,11 +624,13 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, // Evlocallabsensiden LUMINANCECURVE, // Evlocallabhuerefblur LUMINANCECURVE, // EvlocallabEnabled - LUMINANCECURVE // EvlocallablocY + LUMINANCECURVE, // EvlocallablocY + LUMINANCECURVE // Evlocallabbilateral }; -namespace rtengine { +namespace rtengine +{ RefreshMapper::RefreshMapper(): next_event_(rtengine::NUMOFEVENTS) @@ -654,6 +656,7 @@ void RefreshMapper::mapEvent(ProcEvent event, int action) int RefreshMapper::getAction(ProcEvent event) const { auto it = actions_.find(event); + if (it == actions_.end()) { return 0; } else { diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 99dd90099..e6a5c5151 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1103,7 +1103,7 @@ private: } ifstream fich(datalab, ios::in); - int maxdata = 99; // 91 10021 //88 10019 //87 10018//86 10017//85 10016 //82;//78;//73 10011 + int maxdata = 100; //99 10021 // 91 10021 //88 10019 //87 10018//86 10017//85 10016 //82;//78;//73 10011 if (fich && versionmip != 0) { std::string inser; @@ -1396,6 +1396,8 @@ private: dataspots[93][0] = 1; } + dataspots[94][0] = params.locallab.bilateral; + dataspots[maxdata - 5][0] = 100.f * params.locallab.huerefblur; dataspots[maxdata - 4][0] = 100.f * params.locallab.hueref; dataspots[maxdata - 3][0] = params.locallab.chromaref; @@ -1924,6 +1926,7 @@ private: params.locallab.expexpose = true; } + params.locallab.bilateral = dataspots[94][sp]; params.locallab.huerefblur = ((float) dataspots[maxdata - 5][sp]) / 100.f; diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 36e2ae635..e13eede48 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -108,6 +108,7 @@ Locallab::Locallab(): noiselumc(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELUMCOARSE"), 0, 100, 1, 0))), noiselumdetail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELUMDETAIL"), 0, 100, 1, 50))), noisechrodetail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISECHRODETAIL"), 0, 100, 1, 50))), + bilateral(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BILATERAL"), 0, 100, 1, 0))), sensiden(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSIDEN"), 0, 100, 1, 30))), noisechrof(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISECHROFINE"), 0, 100, 1, 0))), noisechroc(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISECHROCOARSE"), 0, 100, 1, 0))), @@ -134,6 +135,7 @@ Locallab::Locallab(): shapeFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_SHFR")))), superFrame(Gtk::manage(new Gtk::Frame())), dustFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_DUST")))), + wavFrame(Gtk::manage(new Gtk::Frame())), // artifVBox (Gtk::manage (new Gtk::VBox ())), // shapeVBox (Gtk::manage (new Gtk::VBox ())), @@ -649,19 +651,27 @@ Locallab::Locallab(): noiselumc->setAdjusterListener(this); noiselumdetail->setAdjusterListener(this); noisechrodetail->setAdjusterListener(this); + bilateral->setAdjusterListener(this); sensiden->setAdjusterListener(this); noisechrof->setAdjusterListener(this); noisechroc->setAdjusterListener(this); - ToolParamBlock* const denoisBox = Gtk::manage(new ToolParamBlock()); - denoisBox->pack_start(*noiselumf); - denoisBox->pack_start(*noiselumc); - denoisBox->pack_start(*noiselumdetail); - denoisBox->pack_start(*noisechrof); - denoisBox->pack_start(*noisechroc); - denoisBox->pack_start(*noisechrodetail); + ToolParamBlock* const denoisBox = Gtk::manage(new ToolParamBlock()); + ToolParamBlock* const wavBox = Gtk::manage(new ToolParamBlock()); + + wavBox->pack_start(*noiselumf); + wavBox->pack_start(*noiselumc); + wavBox->pack_start(*noiselumdetail); + wavBox->pack_start(*noisechrof); + wavBox->pack_start(*noisechroc); + wavBox->pack_start(*noisechrodetail); + + wavFrame->add(*wavBox); + denoisBox->pack_start(*wavFrame); + + denoisBox->pack_start(*bilateral); denoisBox->pack_start(*sensiden); neutrHBox1 = Gtk::manage(new Gtk::HBox()); @@ -692,10 +702,11 @@ Locallab::Locallab(): superBox->pack_start(*lightness); superBox->pack_start(*contrast); + superBox->pack_start(*chroma); + superFrame->add(*superBox); colorBox->pack_start(*superFrame); - colorBox->pack_start(*chroma); colorBox->pack_start(*warm); colorBox->pack_start(*sensi); @@ -1318,6 +1329,7 @@ void Locallab::neutral_pressed() noisechrof->resetValue(false); noisechroc->resetValue(false); noisechrodetail->resetValue(false); + bilateral->resetValue(false); sensiden->resetValue(false); @@ -1881,15 +1893,16 @@ bool Locallab::localComputed_() expexpose->setEnabled(true); } + bilateral->setValue(nextdatasp[94]); - double intermedblur = 0.01 * (double) nextdatasp[94]; + double intermedblur = 0.01 * (double) nextdatasp[95]; huerefblur->setValue(intermedblur); - double intermed = 0.01 * (double) nextdatasp[95]; + double intermed = 0.01 * (double) nextdatasp[96]; hueref->setValue(intermed); - chromaref->setValue(nextdatasp[96]); - lumaref->setValue(nextdatasp[97]); - sobelref->setValue(nextdatasp[98]); + chromaref->setValue(nextdatasp[97]); + lumaref->setValue(nextdatasp[98]); + sobelref->setValue(nextdatasp[99]); int *s_datc; s_datc = new int[70]; @@ -2206,7 +2219,7 @@ bool Locallab::localComputed_() void Locallab::localChanged(int **datasp, std::string datastr, std::string ll_str, std::string lh_str, std::string cc_str, std::string hh_str, std::string sk_str, std::string ps_str, std::string ex_str, int sp, int maxdat) { - for (int i = 2; i < 99; i++) { + for (int i = 2; i < 100; i++) { nextdatasp[i] = datasp[i][sp]; } @@ -2297,6 +2310,7 @@ void Locallab::read(const ProcParams* pp, const ParamsEdited* pedited) noisechrof->setEditedState(pedited->locallab.noisechrof ? Edited : UnEdited); noisechroc->setEditedState(pedited->locallab.noisechroc ? Edited : UnEdited); noisechrodetail->setEditedState(pedited->locallab.noisechrodetail ? Edited : UnEdited); + bilateral->setEditedState(pedited->locallab.bilateral ? Edited : UnEdited); sensiden->setEditedState(pedited->locallab.sensiden ? Edited : UnEdited); pastels->setEditedState(pedited->locallab.pastels ? Edited : UnEdited); @@ -2511,6 +2525,7 @@ void Locallab::read(const ProcParams* pp, const ParamsEdited* pedited) noisechrof->setValue(pp->locallab.noisechrof); noisechroc->setValue(pp->locallab.noisechroc); noisechrodetail->setValue(pp->locallab.noisechrodetail); + bilateral->setValue(pp->locallab.bilateral); sensiden->setValue(pp->locallab.sensiden); expcolor->setEnabled(pp->locallab.expcolor); expexpose->setEnabled(pp->locallab.expexpose); @@ -2938,6 +2953,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pp->locallab.noiselumc = noiselumc->getIntValue(); pp->locallab.noiselumdetail = noiselumdetail->getIntValue(); pp->locallab.noisechrodetail = noisechrodetail->getIntValue(); + pp->locallab.bilateral = bilateral->getIntValue(); pp->locallab.sensiden = sensiden->getIntValue(); pp->locallab.noiselumf = noiselumf->getIntValue(); pp->locallab.noisechrof = noisechrof->getIntValue(); @@ -3054,6 +3070,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pedited->locallab.noiselumc = noiselumc->getEditedState(); pedited->locallab.noiselumdetail = noiselumdetail->getEditedState(); pedited->locallab.noisechrodetail = noisechrodetail->getEditedState(); + pedited->locallab.bilateral = bilateral->getEditedState(); pedited->locallab.sensiden = sensiden->getEditedState(); pedited->locallab.noisechrof = noisechrof->getEditedState(); pedited->locallab.noisechroc = noisechroc->getEditedState(); @@ -3829,6 +3846,7 @@ void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pe noiselumc->setDefault(defParams->locallab.noiselumc); noiselumdetail->setDefault(defParams->locallab.noiselumdetail); noisechrodetail->setDefault(defParams->locallab.noisechrodetail); + bilateral->setDefault(defParams->locallab.bilateral); sensiden->setDefault(defParams->locallab.sensiden); noisechrof->setDefault(defParams->locallab.noisechrof); noisechroc->setDefault(defParams->locallab.noisechroc); @@ -3907,6 +3925,7 @@ void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pe noiselumc->setDefaultEditedState(pedited->locallab.noiselumc ? Edited : UnEdited); noiselumdetail->setDefaultEditedState(pedited->locallab.noiselumdetail ? Edited : UnEdited); noisechrodetail->setDefaultEditedState(pedited->locallab.noisechrodetail ? Edited : UnEdited); + bilateral->setDefaultEditedState(pedited->locallab.bilateral ? Edited : UnEdited); sensiden->setDefaultEditedState(pedited->locallab.sensiden ? Edited : UnEdited); noisechrof->setDefaultEditedState(pedited->locallab.noisechrof ? Edited : UnEdited); noisechroc->setDefaultEditedState(pedited->locallab.noisechroc ? Edited : UnEdited); @@ -3984,6 +4003,7 @@ void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pe noiselumc->setDefaultEditedState(Irrelevant); noiselumdetail->setDefaultEditedState(Irrelevant); noisechrodetail->setDefaultEditedState(Irrelevant); + bilateral->setDefaultEditedState(Irrelevant); sensiden->setDefaultEditedState(Irrelevant); noisechrof->setDefaultEditedState(Irrelevant); noisechroc->setDefaultEditedState(Irrelevant); @@ -4164,6 +4184,8 @@ void Locallab::adjusterChanged(Adjuster * a, double newval) listener->panelChanged(Evlocallabnoiselumdetail, noiselumdetail->getTextValue()); } else if (a == noisechrodetail) { listener->panelChanged(Evlocallabnoisechrodetail, noisechrodetail->getTextValue()); + } else if (a == bilateral) { + listener->panelChanged(Evlocallabbilateral, bilateral->getTextValue()); } else if (a == sensiden) { listener->panelChanged(Evlocallabsensiden, sensiden->getTextValue()); } else if (a == noisechrof) { @@ -4357,6 +4379,7 @@ void Locallab::trimValues(rtengine::procparams::ProcParams * pp) noiselumc->trimValue(pp->locallab.noiselumc); noiselumdetail->trimValue(pp->locallab.noiselumdetail); noisechrodetail->trimValue(pp->locallab.noisechrodetail); + bilateral->trimValue(pp->locallab.bilateral); sensiden->trimValue(pp->locallab.sensiden); noisechrof->trimValue(pp->locallab.noisechrof); noisechroc->trimValue(pp->locallab.noisechroc); @@ -4446,6 +4469,7 @@ void Locallab::setBatchMode(bool batchMode) noiselumc->showEditedCB(); noiselumdetail->showEditedCB(); noisechrodetail->showEditedCB(); + bilateral->showEditedCB(); sensiden->showEditedCB(); noisechroc->showEditedCB(); noiselumf->showEditedCB(); diff --git a/rtgui/locallab.h b/rtgui/locallab.h index 10d2c4f63..3fe2e91e5 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -117,6 +117,7 @@ private: Adjuster* const noiselumc; Adjuster* const noiselumdetail; Adjuster* const noisechrodetail; + Adjuster* const bilateral; Adjuster* const sensiden; Adjuster* const noisechrof; @@ -144,6 +145,7 @@ private: Gtk::Frame* const shapeFrame; Gtk::Frame* const superFrame; Gtk::Frame* const dustFrame; + Gtk::Frame* const wavFrame; Gtk::Label* const labmdh; Gtk::Label* const labqual; @@ -236,7 +238,7 @@ private: - int nextdatasp[99]; + int nextdatasp[100]; int nextlength; std::string nextstr; std::string nextstr2; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index f70f33aa3..36f1b5b5c 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -355,6 +355,7 @@ void ParamsEdited::set(bool v) locallab.noiselumc = v; locallab.noiselumdetail = v; locallab.noisechrodetail = v; + locallab.bilateral = v; locallab.sensiden = v; locallab.noisechrof = v; locallab.noisechroc = v; @@ -763,12 +764,12 @@ void ParamsEdited::initFrom(const std::vector& labCurve.rstprotection = labCurve.rstprotection && p.labCurve.rstprotection == other.labCurve.rstprotection; labCurve.lcredsk = labCurve.lcredsk && p.labCurve.lcredsk == other.labCurve.lcredsk; - localContrast.enabled = localContrast.enabled && p.localContrast.enabled == other.localContrast.enabled; + localContrast.enabled = localContrast.enabled && p.localContrast.enabled == other.localContrast.enabled; localContrast.radius = localContrast.radius && p.localContrast.radius == other.localContrast.radius; localContrast.amount = localContrast.amount && p.localContrast.amount == other.localContrast.amount; localContrast.darkness = localContrast.darkness && p.localContrast.darkness == other.localContrast.darkness; localContrast.lightness = localContrast.lightness && p.localContrast.lightness == other.localContrast.lightness; - + rgbCurves.enabled = rgbCurves.enabled && p.rgbCurves.enabled == other.rgbCurves.enabled; rgbCurves.lumamode = rgbCurves.lumamode && p.rgbCurves.lumamode == other.rgbCurves.lumamode; rgbCurves.rcurve = rgbCurves.rcurve && p.rgbCurves.rcurve == other.rgbCurves.rcurve; @@ -1031,6 +1032,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.noiselumc = locallab.noiselumc && p.locallab.noiselumc == other.locallab.noiselumc; locallab.noiselumdetail = locallab.noiselumdetail && p.locallab.noiselumdetail == other.locallab.noiselumdetail; locallab.noisechrodetail = locallab.noisechrodetail && p.locallab.noisechrodetail == other.locallab.noisechrodetail; + locallab.bilateral = locallab.bilateral && p.locallab.bilateral == other.locallab.bilateral; locallab.sensiden = locallab.sensiden && p.locallab.sensiden == other.locallab.sensiden; locallab.noisechrof = locallab.noisechrof && p.locallab.noisechrof == other.locallab.noisechrof; locallab.noisechroc = locallab.noisechroc && p.locallab.noisechroc == other.locallab.noisechroc; @@ -1548,7 +1550,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng if (labCurve.enabled) { toEdit.labCurve.enabled = mods.labCurve.enabled; } - + if (labCurve.lcurve) { toEdit.labCurve.lcurve = mods.labCurve.lcurve; } @@ -1612,15 +1614,19 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng if (localContrast.enabled) { toEdit.localContrast.enabled = mods.localContrast.enabled; } + if (localContrast.radius) { toEdit.localContrast.radius = mods.localContrast.radius; } + if (localContrast.amount) { toEdit.localContrast.amount = mods.localContrast.amount; } + if (localContrast.darkness) { toEdit.localContrast.darkness = mods.localContrast.darkness; } + if (localContrast.lightness) { toEdit.localContrast.lightness = mods.localContrast.lightness; } @@ -2668,6 +2674,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.noisechrodetail = mods.locallab.noisechrodetail; } + if (locallab.bilateral) { + toEdit.locallab.bilateral = mods.locallab.bilateral; + } + if (locallab.sensiden) { toEdit.locallab.sensiden = mods.locallab.sensiden; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 246b67e91..82f4180c5 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -119,7 +119,8 @@ public: }; -class LocalContrastParamsEdited { +class LocalContrastParamsEdited +{ public: bool enabled; bool radius; @@ -478,6 +479,7 @@ public: bool noiselumc; bool noiselumdetail; bool noisechrodetail; + bool bilateral; bool sensiden; bool noisechrof; bool noisechroc;