diff --git a/rtdata/dcpprofiles/Panasonic DC-S1.dcp b/rtdata/dcpprofiles/Panasonic DC-S1.dcp new file mode 100644 index 000000000..5b9fea8af Binary files /dev/null and b/rtdata/dcpprofiles/Panasonic DC-S1.dcp differ diff --git a/rtdata/languages/default b/rtdata/languages/default index 6fc0a27c4..2561283aa 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1370,6 +1370,7 @@ PREFERENCES_SHOWBASICEXIF;Show basic Exif info PREFERENCES_SHOWDATETIME;Show date and time PREFERENCES_SHOWFILMSTRIPTOOLBAR;Show Filmstrip toolbar PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +PREFERENCES_SHOWTOOLTIP;Show Locallab Tooltips PREFERENCES_SHTHRESHOLD;Threshold for clipped shadows PREFERENCES_SINGLETAB;Single Editor Tab Mode PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 5d1f63aa1..f4efe6fc9 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1224,6 +1224,7 @@ Camera constants: { // Quality C "make_model": "Canon PowerShot SX150 IS", + "dcraw_matrix": [ 13481, -4867, -1063, -2074, 9960, 2472, -170, 1474, 3894 ], // Adobe DNG Converter 11.1 ColorMatrix1 (there is only one matrix and illuminant, and it's for daylight) "raw_crop": [ 26, 10, 4364, 3254 ] // cut 2pix left and right }, @@ -1605,9 +1606,9 @@ Camera constants: "make_model" : "Nikon Z 6", "dcraw_matrix" : [8210, -2534, -683, -5355, 13338, 2212, -1143, 1929, 6464], // Adobe DNG Converter 11.1 Beta ColorMatrix2 "pdaf_pattern" : [0, 12], - "pdaf_offset" : 32 + "pdaf_offset" : 32 }, - + { // Quality B, 16Mp and 64Mp raw frames "make_model": "OLYMPUS E-M5MarkII", "dcraw_matrix": [ 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 ], // DNG_v8.8 D65 diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index fcb7ee235..542bedf6b 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -306,9 +306,9 @@ public: bool &LHutili, bool &HHutili, LUTf & cclocalcurve, bool & localcutili, bool & localexutili, LUTf & exlocalcurve, LUTf & hltonecurveloc, LUTf & shtonecurveloc, LUTf & tonecurveloc, LUTf & lightCurveloc, double & huerefblur, double &chromarefblur, double & lumarefblur, double &hueref, double &chromaref, double &lumaref, double &sobelref, int llColorMask, int llExpMask, int llSHMask); void addGaNoise(LabImage *lab, LabImage *dst, const float mean, const float variance, const int sk); void BlurNoise_Localold(int call, const struct local_params& lp, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy); - void InverseBlurNoise_Local(const struct local_params& lp, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy); + void InverseBlurNoise_Local(const struct local_params& lp, const float hueref, const float chromaref, const float lumaref, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy, int sk); void InverseReti_Local(const struct local_params& lp, const float hueref, const float chromaref, const float lumaref, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy, int chro, int sk); - void BlurNoise_Local(int call, LabImage* tmp1, LabImage* tmp2, float ** buflight, float ** bufchro, const float hueref, const float chromaref, const float lumaref, const local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy, int sk); + void BlurNoise_Local(LabImage* tmp1, const float hueref, const float chromaref, const float lumaref, const local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy, int sk); static void strcurv_data(std::string retistr, int *s_datc, int &siz); void blendstruc(int bfw, int bfh, LabImage* bufcolorig, float radius, float stru, array2D & blend2, int sk, bool multiThread); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index bd0633b9a..d060e24b3 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -422,9 +422,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.blurmet = 0; } else if (locallab.spots.at(sp).blurMethod == "inv") { lp.blurmet = 1; - } else if (locallab.spots.at(sp).blurMethod == "sym") { - lp.blurmet = 2; - } + } if (locallab.spots.at(sp).spotMethod == "norm") { lp.excmet = 0; @@ -1202,6 +1200,33 @@ static void balancedeltaE(float kL, float &kab) kab = abal * kL + bbal; } +static void calcreducdE(float dE, float maxdE, float mindE, float maxdElim, float mindElim, float iterat, float limscope, int scope, float &reducdE) +{ + if (dE > maxdE) { + reducdE = 0.f; + } else if (dE > mindE && dE <= maxdE) { + const float ar = 1.f / (mindE - maxdE); + const float br = - ar * maxdE; + reducdE = pow(ar * dE + br, iterat); + } else { + reducdE = 1.f; + } + + if (scope > limscope) {//80 arbitrary value, if we change we must change limscope + if (dE > maxdElim) { + reducdE = 0.f; + } else if (dE > mindElim && dE <= maxdElim) { + const float arlim = 1.f / (mindElim - maxdElim); + const float brlim = - arlim * maxdElim; + const float reducdElim = pow(arlim * dE + brlim, iterat); + const float aalim = (1.f - reducdElim) / 20.f; + const float bblim = 1.f - 100.f * aalim; + reducdE = aalim * scope + bblim; + } else { + reducdE = 1.f; + } + } +} void ImProcFunctions::DeNoise_Local(int call, const struct local_params& lp, int levred, float hueref, float lumaref, float chromaref, LabImage* original, LabImage* transformed, LabImage &tmp1, int cx, int cy, int sk) { //warning, but I hope used it next @@ -1410,7 +1435,7 @@ void ImProcFunctions::DeNoise_Local(int call, const struct local_params& lp, in } -void ImProcFunctions::BlurNoise_Local(int call, LabImage * tmp1, LabImage * tmp2, float ** buflight, float ** bufchro, const float hueref, const float chromaref, const float lumaref, const local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk) +void ImProcFunctions::BlurNoise_Local(LabImage * tmp1, const float hueref, const float chromaref, const float lumaref, const local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk) { //local BLUR BENCHFUN @@ -1445,10 +1470,13 @@ void ImProcFunctions::BlurNoise_Local(int call, LabImage * tmp1, LabImage * tmp2 #pragma omp parallel if (multiThread) #endif { + const int limscope = 80; const int begy = int (lp.yc - lp.lyT); const int begx = int (lp.xc - lp.lxL); const float mindE = 2.f + MINSCOPE * lp.sensbn * lp.thr; const float maxdE = 5.f + MAXSCOPE * lp.sensbn * (1 + 0.1f * lp.thr); + const float mindElim = 2.f + MINSCOPE * limscope * lp.thr; + const float maxdElim = 5.f + MAXSCOPE * limscope * (1 + 0.1f * lp.thr); #ifdef _OPENMP #pragma omp for schedule(dynamic,16) @@ -1460,16 +1488,6 @@ void ImProcFunctions::BlurNoise_Local(int call, LabImage * tmp1, LabImage * tmp2 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 - if (lp.blurmet == 2) { - for (int x = 0; x < transformed->W; x++) { - transformed->L[y][x] = tmp2->L[y][x]; - if (!lp.actsp) { - transformed->a[y][x] = tmp2->a[y][x]; - transformed->b[y][x] = tmp2->b[y][x]; - } - } - } - continue; } @@ -1485,72 +1503,31 @@ void ImProcFunctions::BlurNoise_Local(int call, LabImage * tmp1, LabImage * tmp2 if (zone == 0) { // outside selection and outside transition zone => no effect, keep original values - if (lp.blurmet == 2) { - transformed->L[y][x] = tmp2->L[y][x]; - if (!lp.actsp) { - transformed->a[y][x] = tmp2->a[y][x]; - transformed->b[y][x] = tmp2->b[y][x]; - } - } - continue; } const float dE = sqrt(kab * (SQR(refa - origblur->a[y][x]) + SQR(refb - origblur->b[y][x])) + kL * SQR(refL - origblur->L[y][x])); float reducdE; - if (lp.sensbn > 99) { - reducdE = 1.f; - } else if (dE > maxdE) { - reducdE = 0.f; - } else if (dE > mindE && dE <= maxdE) { - const float ar = 1.f / (mindE - maxdE); - const float br = - ar * maxdE; - reducdE = pow(ar * dE + br, lp.iterat); - } else /*if (dE <= mindE) */ { - reducdE = 1.f; - } - - const float realstrdE = reducdE * buflight[loy - begy][lox - begx]; - const float realstrchdE = localFactor * (1.f + (reducdE * bufchro[loy - begy][lox - begx]) / 100.f); - + calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, lp.sensbn , reducdE); switch (zone) { case 1: { // inside transition zone float difL, difa, difb; - - if (call <= 3) { 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]; - } else { - difL = tmp1->L[y][x] - original->L[y][x]; - difa = tmp1->a[y][x] - original->a[y][x]; - difb = tmp1->b[y][x] - original->b[y][x]; + difL *= localFactor * reducdE; - - } - - difL *= localFactor * (100.f + realstrdE) / 100.f; - - if (lp.blurmet == 0) { transformed->L[y][x] = CLIP(original->L[y][x] + difL); - } else if (lp.blurmet == 2) { - transformed->L[y][x] = CLIP(tmp2->L[y][x] - difL); - } if (!lp.actsp) { - difa *= realstrchdE; - difb *= realstrchdE; + difa *= localFactor * reducdE; + difb *= localFactor * reducdE; - if (lp.blurmet == 0) { - transformed->a[y][x] = CLIPC(original->a[y][x] + difa); - transformed->b[y][x] = CLIPC(original->b[y][x] + difb); - } else if (lp.blurmet == 2) { - transformed->a[y][x] = CLIPC(tmp2->a[y][x] - difa); - transformed->b[y][x] = CLIPC(tmp2->b[y][x] - difb); - } + transformed->a[y][x] = CLIPC(original->a[y][x] + difa); + transformed->b[y][x] = CLIPC(original->b[y][x] + difb); } break; @@ -1563,25 +1540,16 @@ void ImProcFunctions::BlurNoise_Local(int call, LabImage * tmp1, LabImage * tmp2 difa = tmp1->a[loy - begy][lox - begx] - original->a[y][x]; difb = tmp1->b[loy - begy][lox - begx] - original->b[y][x]; - difL *= (100.f + realstrdE) / 100.f; + difL *= reducdE;//(100.f + realstrdE) / 100.f; - if (lp.blurmet == 0) { - transformed->L[y][x] = CLIP(original->L[y][x] + difL); - } else if (lp.blurmet == 2) { - transformed->L[y][x] = CLIP(tmp2->L[y][x] - difL); - } + transformed->L[y][x] = CLIP(original->L[y][x] + difL); if (!lp.actsp) { - difa *= realstrchdE; - difb *= realstrchdE; + difa *= reducdE; + difb *= reducdE; - if (lp.blurmet == 0) { - transformed->a[y][x] = CLIPC(original->a[y][x] + difa); ; - transformed->b[y][x] = CLIPC(original->b[y][x] + difb); - } else if (lp.blurmet == 2) { - transformed->a[y][x] = CLIPC(tmp2->a[y][x] - difa); - transformed->b[y][x] = CLIPC(tmp2->b[y][x] - difb); - } + transformed->a[y][x] = CLIPC(original->a[y][x] + difa); ; + transformed->b[y][x] = CLIPC(original->b[y][x] + difb); } } } @@ -1590,6 +1558,8 @@ void ImProcFunctions::BlurNoise_Local(int call, LabImage * tmp1, LabImage * tmp2 } } + + void ImProcFunctions::InverseReti_Local(const struct local_params & lp, const float hueref, const float chromaref, const float lumaref, LabImage * original, LabImage * transformed, const LabImage * const tmp1, int cx, int cy, int chro, int sk) { // BENCHFUN @@ -1621,6 +1591,11 @@ void ImProcFunctions::InverseReti_Local(const struct local_params & lp, const fl #pragma omp parallel if (multiThread) #endif { + const int limscope = 80; + const float mindE = 2.f + MINSCOPE * lp.sensh * lp.thr; + const float maxdE = 5.f + MAXSCOPE * lp.sensh * (1 + 0.1f * lp.thr); + const float mindElim = 2.f + MINSCOPE * limscope * lp.thr; + const float maxdElim = 5.f + MAXSCOPE * limscope * (1 + 0.1f * lp.thr); #ifdef _OPENMP #pragma omp for schedule(dynamic,16) @@ -1644,30 +1619,7 @@ void ImProcFunctions::InverseReti_Local(const struct local_params & lp, const fl float rL = origblur->L[y][x] / 327.68f; float reducdE = 0.f; float dE = sqrt(kab * SQR(refa - origblur->a[y][x] / 327.68f) + kab * SQR(refb - origblur->b[y][x] / 327.68f) + kL * SQR(lumaref - rL)); - float mindE = 2.f + MINSCOPE * lp.sensh * lp.thr; - float maxdE = 5.f + MAXSCOPE * lp.sensh * (1 + 0.1f * lp.thr); - - float ar = 1.f / (mindE - maxdE); - - float br = - ar * maxdE; - - if (dE > maxdE) { - reducdE = 0.f; - } - - if (dE > mindE && dE <= maxdE) { - reducdE = ar * dE + br; - } - - if (dE <= mindE) { - reducdE = 1.f; - } - - reducdE = pow(reducdE, lp.iterat); - - if (lp.sensh > 99) { - reducdE = 1.f; - } + calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, lp.sensh , reducdE); switch (zone) { case 0: { // outside selection and outside transition zone => full effect, no transition @@ -1732,13 +1684,46 @@ void ImProcFunctions::InverseReti_Local(const struct local_params & lp, const fl -void ImProcFunctions::InverseBlurNoise_Local(const struct local_params & lp, LabImage * original, LabImage * transformed, const LabImage * const tmp1, int cx, int cy) +void ImProcFunctions::InverseBlurNoise_Local(const struct local_params & lp, const float hueref, const float chromaref, const float lumaref, LabImage * original, LabImage * transformed, const LabImage * const tmp1, int cx, int cy, int sk) { // BENCHFUN //inverse local blur and noise float ach = (float)lp.trans / 100.f; + int GW = transformed->W; + int GH = transformed->H; + float refa = chromaref * cos(hueref); + float refb = chromaref * sin(hueref); - #pragma omp parallel for schedule(dynamic,16) if (multiThread) + //balance deltaE + float kL = lp.balance; + float kab = 1.f; + balancedeltaE(kL, kab); + + LabImage *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); + + } +#ifdef _OPENMP + #pragma omp parallel if (multiThread) +#endif + { + const int limscope = 80; + const float mindE = 2.f + MINSCOPE * lp.sensbn * lp.thr; + const float maxdE = 5.f + MAXSCOPE * lp.sensbn * (1 + 0.1f * lp.thr); + const float mindElim = 2.f + MINSCOPE * limscope * lp.thr; + const float maxdElim = 5.f + MAXSCOPE * limscope * (1 + 0.1f * lp.thr); + +#ifdef _OPENMP + #pragma omp for schedule(dynamic,16) +#endif for (int y = 0; y < transformed->H; y++) { int loy = cy + y; @@ -1755,10 +1740,14 @@ void ImProcFunctions::InverseBlurNoise_Local(const struct local_params & lp, Lab calcTransitionrect(lox, loy, ach, lp, zone, localFactor); } - + float rL = origblur->L[y][x] / 327.68f; + float dE = sqrt(kab * SQR(refa - origblur->a[y][x] / 327.68f) + kab * SQR(refb - origblur->b[y][x] / 327.68f) + kL * SQR(lumaref - rL)); + float reducdE; + calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, lp.sensbn , reducdE); switch (zone) { case 0: { // outside selection and outside transition zone => full effect, no transition - transformed->L[y][x] = CLIP(tmp1->L[y][x]); + float difL = tmp1->L[y][x] - original->L[y][x]; + transformed->L[y][x] = CLIP(original->L[y][x] + difL * reducdE); if (!lp.actsp) { transformed->a[y][x] = CLIPC(tmp1->a[y][x]); @@ -1778,7 +1767,7 @@ void ImProcFunctions::InverseBlurNoise_Local(const struct local_params & lp, Lab difa *= factorx; difb *= factorx; - transformed->L[y][x] = CLIP(original->L[y][x] + difL); + transformed->L[y][x] = CLIP(original->L[y][x] + difL * reducdE); if (!lp.actsp) { @@ -1802,6 +1791,7 @@ void ImProcFunctions::InverseBlurNoise_Local(const struct local_params & lp, Lab } } } +} static void calclight(float lum, float koef, float &lumnew, const LUTf &lightCurveloc) //replace L-curve that does not work in local or bad @@ -2016,6 +2006,11 @@ void ImProcFunctions::InverseSharp_Local(float **loctemp, const float hueref, co #pragma omp parallel if (multiThread) #endif { + const int limscope = 80; + const float mindE = 2.f + MINSCOPE * lp.senssha * lp.thr; + const float maxdE = 5.f + MAXSCOPE * lp.senssha * (1 + 0.1f * lp.thr); + const float mindElim = 2.f + MINSCOPE * limscope * lp.thr; + const float maxdElim = 5.f + MAXSCOPE * limscope * (1 + 0.1f * lp.thr); #ifdef _OPENMP #pragma omp for schedule(dynamic,16) @@ -2038,30 +2033,7 @@ void ImProcFunctions::InverseSharp_Local(float **loctemp, const float hueref, co float rL = origblur->L[y][x] / 327.68f; float reducdE = 0.f; float dE = sqrt(kab * SQR(refa - origblur->a[y][x] / 327.68f) + kab * SQR(refb - origblur->b[y][x] / 327.68f) + kL * SQR(lumaref - rL)); - float mindE = 2.f + MINSCOPE * lp.senssha * lp.thr; - float maxdE = 5.f + MAXSCOPE * lp.senssha * (1 + 0.1f * lp.thr); - - float ar = 1.f / (mindE - maxdE); - - float br = - ar * maxdE; - - if (dE > maxdE) { - reducdE = 0.f; - } - - if (dE > mindE && dE <= maxdE) { - reducdE = ar * dE + br; - } - - if (dE <= mindE) { - reducdE = 1.f; - } - - reducdE = pow(reducdE, lp.iterat); - - if (lp.senssha > 99) { - reducdE = 1.f; - } + calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, lp.senssha , reducdE); switch (zone) { case 0: { // outside selection and outside transition zone => full effect, no transition @@ -2129,8 +2101,11 @@ void ImProcFunctions::Sharp_Local(int call, float **loctemp, int senstype, const { const int begy = int (lp.yc - lp.lyT); const int begx = int (lp.xc - lp.lxL); + const int limscope = 80; const float mindE = 2.f + MINSCOPE * varsens * lp.thr; const float maxdE = 5.f + MAXSCOPE * varsens * (1 + 0.1f * lp.thr); + const float mindElim = 2.f + MINSCOPE * limscope * lp.thr; + const float maxdElim = 5.f + MAXSCOPE * limscope * (1 + 0.1f * lp.thr); #ifdef _OPENMP #pragma omp for schedule(dynamic,16) @@ -2161,20 +2136,8 @@ void ImProcFunctions::Sharp_Local(int call, float **loctemp, int senstype, const const float dE = sqrt(kab * (SQR(refa - origblur->a[y][x]) + SQR(refb - origblur->b[y][x])) + kL * SQR(refL - origblur->L[y][x])); - float reducdE; - - if (varsens > 99) { - reducdE = 1.f; - } else if (dE > maxdE) { - reducdE = 0.f; - } else if (dE > mindE && dE <= maxdE) { - const float ar = 1.f / (mindE - maxdE); - const float br = - ar * maxdE; - reducdE = ar * dE + br; - reducdE = pow(reducdE, lp.iterat); - } else { - reducdE = 1.f; - } + float reducdE = 0.f; + calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, varsens , reducdE); reducdE *= localFactor; float difL; @@ -2197,12 +2160,11 @@ void ImProcFunctions::Exclude_Local(float **deltaso, float hueref, float chromar const float ach = (float)lp.trans / 100.f; const float varsens = lp.sensexclu; + const int limscope = 80; const float mindE = 2.f + MINSCOPE * varsens * lp.thr; const float maxdE = 5.f + MAXSCOPE * varsens * (1 + 0.1f * lp.thr); - - const float ar = 1.f / (mindE - maxdE); - - const float br = -ar * maxdE; + const float mindElim = 2.f + MINSCOPE * limscope * lp.thr; + const float maxdElim = 5.f + MAXSCOPE * limscope * (1 + 0.1f * lp.thr); const int GW = transformed->W; const int GH = transformed->H; @@ -2301,16 +2263,7 @@ void ImProcFunctions::Exclude_Local(float **deltaso, float hueref, float chromar const float dE = sqrt(kab * SQR(refa - origblur->a[y][x]) + kab * SQR(refb - origblur->b[y][x]) + kL * SQR(lumaref - rL)); float reducdE; - - if (varsens > 99) { - reducdE = 1.f; - } else if (dE > maxdE) { - reducdE = 0.f; - } else if (dE > mindE && dE <= maxdE) { - reducdE = pow(ar * dE + br, lp.iterat); - } else { /*if (dE <= mindE)*/ - reducdE = 1.f; - } + calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, varsens , reducdE); const float affde = reducdE; @@ -2399,6 +2352,13 @@ void ImProcFunctions::transit_shapedetect_retinex(int senstype, LabImage * bufex #pragma omp parallel if (multiThread) #endif { + const int limscope = 80; + const float mindE = 2.f + MINSCOPE * varsens * lp.thr; + const float maxdE = 5.f + MAXSCOPE * varsens * (1 + 0.1f * lp.thr); + const float mindElim = 2.f + MINSCOPE * limscope * lp.thr; + const float maxdElim = 5.f + MAXSCOPE * limscope * (1 + 0.1f * lp.thr); + + #ifdef __SSE2__ float atan2Buffer[transformed->W] ALIGNED16; #endif @@ -2480,24 +2440,9 @@ void ImProcFunctions::transit_shapedetect_retinex(int senstype, LabImage * bufex cli = buflight[loy - begy][lox - begx]; clc = bufchro[loy - begy][lox - begx]; - const float mindE = 2.f + MINSCOPE * varsens * lp.thr; - const float maxdE = 5.f + MAXSCOPE * varsens * (1 + 0.1f * lp.thr); - - float reducdE; - if (varsens > 99) { - reducdE = 1.f; - } else if (dE > maxdE) { - reducdE = 0.f; - } else if (dE > mindE && dE <= maxdE) { - float ar = 1.f / (mindE - maxdE); - float br = - ar * maxdE; - reducdE = ar * dE + br; - reducdE = pow(reducdE, lp.iterat); - } else { /*if (dE <= mindE)*/ - reducdE = 1.f; - } + calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, varsens , reducdE); float realstrdE = reducdE * cli; float realstrchdE = reducdE * clc; @@ -2704,7 +2649,7 @@ void ImProcFunctions::transit_shapedetect(int senstype, const LabImage *bufexpor #ifdef _OPENMP #pragma omp parallel if (multiThread) #endif - { + { #ifdef _OPENMP #pragma omp for schedule(dynamic,16) #endif @@ -2725,10 +2670,11 @@ void ImProcFunctions::transit_shapedetect(int senstype, const LabImage *bufexpor } const LabImage *maskptr = usemaskall ? origblurmask.get() : origblur.get(); + const int limscope = 80; const float mindE = 2.f + MINSCOPE * varsens * lp.thr; const float maxdE = 5.f + MAXSCOPE * varsens * (1 + 0.1f * lp.thr); - const float ar = 1.f / (mindE - maxdE); - const float br = - ar * maxdE; + const float mindElim = 2.f + MINSCOPE * limscope * lp.thr; + const float maxdElim = 5.f + MAXSCOPE * limscope * (1 + 0.1f * lp.thr); #ifdef _OPENMP #pragma omp parallel if (multiThread) @@ -2827,16 +2773,7 @@ void ImProcFunctions::transit_shapedetect(int senstype, const LabImage *bufexpor } float reducdE; - - if (varsens > 99) { - reducdE = 1.f; - } else if (dE > maxdE) { - reducdE = 0.f; - } else if (dE > mindE && dE <= maxdE) { - reducdE = pow(ar * dE + br, lp.iterat); - } else { /*if (dE <= mindE)*/ - reducdE = 1.f; - } + calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, varsens , reducdE); const float realstrdE = reducdE * cli; const float realstradE = reducdE * cla; @@ -3266,6 +3203,11 @@ void ImProcFunctions::InverseColorLight_Local(int sp, int senstype, const struct #pragma omp parallel if (multiThread) #endif { + const int limscope = 80; + const float mindE = 2.f + MINSCOPE * varsens * lp.thr; + const float maxdE = 5.f + MAXSCOPE * varsens * (1 + 0.1f * lp.thr); + const float mindElim = 2.f + MINSCOPE * limscope * lp.thr; + const float maxdElim = 5.f + MAXSCOPE * limscope * (1 + 0.1f * lp.thr); #ifdef _OPENMP #pragma omp for schedule(dynamic,16) @@ -3295,31 +3237,7 @@ void ImProcFunctions::InverseColorLight_Local(int sp, int senstype, const struct float dE = sqrt(kab * SQR(refa - origblur->a[y][x] / 327.68f) + kab * SQR(refb - origblur->b[y][x] / 327.68f) + kL * SQR(lumaref - rL)); float reducdE = 0.f; - float mindE = 2.f + MINSCOPE * varsens * lp.thr; - float maxdE = 5.f + MAXSCOPE * varsens * (1 + 0.1f * lp.thr); - - float ar = 1.f / (mindE - maxdE); - - float br = - ar * maxdE; - - if (dE > maxdE) { - reducdE = 0.f; - } - - if (dE > mindE && dE <= maxdE) { - reducdE = ar * dE + br; - } - - if (dE <= mindE) { - reducdE = 1.f; - } - - reducdE = pow(reducdE, lp.iterat); - - if (varsens > 99) { - reducdE = 1.f; - } - + calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, varsens, reducdE); float th_r = 0.01f; if (rL > th_r) { //to avoid crash with very low gamut in rare cases ex : L=0.01 a=0.5 b=-0.9 @@ -4034,15 +3952,12 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o if (((radius >= 1.5 * GAUSS_SKIP && lp.rad > 1.) || lp.stren > 0.1) && lp.blurena) { // radius < GAUSS_SKIP means no gauss, just copy of original image std::unique_ptr tmp1; - std::unique_ptr tmp2; std::unique_ptr bufgb; // LabImage *deltasobelL = nullptr; int GW = transformed->W; int GH = transformed->H; int bfh = int (lp.ly + lp.lyT) + del; //bfw bfh real size of square zone int bfw = int (lp.lx + lp.lxL) + del; - JaggedArray buflight(bfw, bfh); - JaggedArray bufchro(bfw, bfh); if (call <= 3 && lp.blurmet != 1) { bufgb.reset(new LabImage(bfw, bfh, true)); @@ -4071,19 +3986,6 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o } tmp1.reset(new LabImage(bfw, bfh)); - if (lp.blurmet == 2) { - tmp2.reset(new LabImage(transformed->W, transformed->H)); -#ifdef _OPENMP - #pragma omp parallel -#endif - { - gaussianBlur(original->L, tmp2->L, GW, GH, radius); - gaussianBlur(original->a, tmp2->a, GW, GH, radius); - gaussianBlur(original->b, tmp2->b, GW, GH, radius); - } - } - - #ifdef _OPENMP #pragma omp parallel @@ -4118,62 +4020,10 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o } } - if (lp.blurmet != 1) { //blur and noise (center) - float minL = tmp1->L[0][0] - bufgb->L[0][0]; - float maxL = minL; -#ifdef _OPENMP - #pragma omp parallel for reduction(max:maxL) reduction(min:minL) schedule(dynamic,16) -#endif - for (int ir = 0; ir < bfh; ir++) { - for (int jr = 0; jr < bfw; jr++) { - buflight[ir][jr] = tmp1->L[ir][jr] - bufgb->L[ir][jr]; - minL = rtengine::min(minL, buflight[ir][jr]); - maxL = rtengine::max(maxL, buflight[ir][jr]); - } - } - - const float coef = 0.01f * (max(fabs(minL), fabs(maxL))); - -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int ir = 0; ir < bfh; ir++) { - for (int jr = 0; jr < bfw; jr++) { - buflight[ir][jr] /= coef; - } - } - - float minC = sqrt((SQR(tmp1->a[0][0]) + SQR(tmp1->b[0][0]))) - sqrt(SQR(bufgb->a[0][0]) + SQR(bufgb->b[0][0])); - float maxC = minC; -#ifdef _OPENMP - #pragma omp parallel for reduction(max:maxC) reduction(min:minC) schedule(dynamic,16) -#endif - - for (int ir = 0; ir < bfh; ir++) { - for (int jr = 0; jr < bfw; jr++) { - bufchro[ir][jr] = sqrt((SQR(tmp1->a[ir][jr]) + SQR(tmp1->b[ir][jr]))) - sqrt(SQR(bufgb->a[ir][jr]) + SQR(bufgb->b[ir][jr])); - minC = rtengine::min(minC, bufchro[ir][jr]); - maxC = rtengine::max(maxC, bufchro[ir][jr]); - } - } - - const float coefC = 0.01f * (max(fabs(minC), fabs(maxC))); - -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int ir = 0; ir < bfh; ir++) { - for (int jr = 0; jr < bfw; jr++) { - bufchro[ir][jr] /= coefC; - } - } - - BlurNoise_Local(call, tmp1.get(), tmp2.get(), buflight, bufchro, hueref, chromaref, lumaref, lp, original, transformed, cx, cy, sk); + if (lp.blurmet == 0) { //blur and noise (center) + BlurNoise_Local(tmp1.get(), hueref, chromaref, lumaref, lp, original, transformed, cx, cy, sk); } else { - - InverseBlurNoise_Local(lp, original, transformed, tmp1.get(), cx, cy); + InverseBlurNoise_Local(lp, hueref, chromaref, lumaref, original, transformed, tmp1.get(), cx, cy, sk); } } diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index 2995a0de0..1d886a869 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -1977,6 +1977,19 @@ void FileCatalog::updateFBQueryTB (bool singleRow) hbToolBar1->unreference(); } +void FileCatalog::updateShowtooltipVisibility (bool showtooltip) +{ + if (showtooltip) { + showToolBar(); + } else { + hideToolBar(); + } + + refreshHeight(); +} + + + void FileCatalog::updateFBToolBarVisibility (bool showFilmStripToolBar) { if (showFilmStripToolBar) { diff --git a/rtgui/filecatalog.h b/rtgui/filecatalog.h index 8b5b14ed2..908c916e7 100644 --- a/rtgui/filecatalog.h +++ b/rtgui/filecatalog.h @@ -251,6 +251,7 @@ public: bool Query_key_pressed(GdkEventKey *event); void updateFBQueryTB (bool singleRow); void updateFBToolBarVisibility (bool showFilmStripToolBar); + void updateShowtooltipVisibility (bool showtooltip); void tbLeftPanel_1_toggled (); void tbLeftPanel_1_visible (bool visible); diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 6bf03947b..bbeaa4705 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -712,7 +712,6 @@ Locallab::Locallab(): blurMethod->append(M("TP_LOCALLAB_BLNORM")); blurMethod->append(M("TP_LOCALLAB_BLINV")); - blurMethod->append(M("TP_LOCALLAB_BLSYM")); blurMethod->set_active(0); if(showtooltip) blurMethod->set_tooltip_markup(M("TP_LOCALLAB_BLMETHOD_TOOLTIP")); blurMethodConn = blurMethod->signal_changed().connect(sigc::mem_fun(*this, &Locallab::blurMethodChanged)); @@ -1804,9 +1803,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pp->locallab.spots.at(pp->locallab.selspot).blurMethod = "norm"; } else if (blurMethod->get_active_row_number() == 1) { pp->locallab.spots.at(pp->locallab.selspot).blurMethod = "inv"; - } else if (blurMethod->get_active_row_number() == 2) { - pp->locallab.spots.at(pp->locallab.selspot).blurMethod = "sym"; - } + } pp->locallab.spots.at(pp->locallab.selspot).activlum = activlum->get_active(); // Tone Mapping @@ -2475,20 +2472,6 @@ void Locallab::blurMethodChanged() { // printf("blurMethodChanged\n"); - // Update Blur & Noise GUI according to blurMethod combobox (to be compliant with updateSpecificGUIState function) - if (multiImage && blurMethod->get_active_text() == M("GENERAL_UNCHANGED")) { - sensibn->show(); - } else if (blurMethod->get_active_row_number() == 0 || blurMethod->get_active_row_number() == 2) { - sensibn->show(); - } else { - sensibn->hide(); - } - - if (blurMethod->get_active_row_number() == 2) { - strength->hide(); - } else { - strength->show(); - } if (getEnabled() && expblur->getEnabled()) { if (listener) { @@ -4500,8 +4483,6 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con blurMethod->set_active(0); } else if (pp->locallab.spots.at(index).blurMethod == "inv") { blurMethod->set_active(1); - } else { - blurMethod->set_active(2); } activlum->set_active(pp->locallab.spots.at(index).activlum); @@ -4922,20 +4903,6 @@ void Locallab::updateSpecificGUIState() saturated->set_sensitive(true); } - // Update Blur & Noise GUI according to blurMethod combobox (to be compliant with blurMethodChanged function) - if (multiImage && blurMethod->get_active_text() == M("GENERAL_UNCHANGED")) { - sensibn->show(); - } else if (blurMethod->get_active_row_number() == 0 || blurMethod->get_active_row_number() == 2) { - sensibn->show(); - } else { - sensibn->hide(); - } - - if (blurMethod->get_active_row_number() == 2) { - strength->hide(); - } else { - strength->show(); - } // Update Retinex GUI according to inversret button state (to be compliant with inversretChanged function) if (multiImage && inversret->get_inconsistent()) { diff --git a/rtgui/options.cc b/rtgui/options.cc index de7337ad4..01cfe0e10 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -470,6 +470,7 @@ void Options::setDefaults() menuGroupFileOperations = true; menuGroupProfileOperations = true; menuGroupExtProg = true; + showtooltip = true; ICCPC_primariesPreset = "sRGB", ICCPC_redPrimaryX = 0.6400; @@ -649,7 +650,6 @@ void Options::setDefaults() rtSettings.lensfunDbDirectory = ""; // set also in main.cc and main-cli.cc cropGuides = CROP_GUIDE_FULL; cropAutoFit = false; - showtooltip = true; rtSettings.thumbnail_inspector_mode = rtengine::Settings::ThumbnailInspectorMode::JPEG; } @@ -1409,6 +1409,10 @@ void Options::readFromFile(Glib::ustring fname) showFilmStripToolBar = keyFile.get_boolean("GUI", "ShowFilmStripToolBar"); } + if (keyFile.has_key("GUI", "Showtooltip")) {//show tooltip in locallab + showtooltip = keyFile.get_boolean("GUI", "Showtooltip"); + } + if (keyFile.has_key("GUI", "FileBrowserToolbarSingleRow")) { FileBrowserToolbarSingleRow = keyFile.get_boolean("GUI", "FileBrowserToolbarSingleRow"); } @@ -1625,9 +1629,6 @@ void Options::readFromFile(Glib::ustring fname) rtSettings.cbdlsensi = keyFile.get_double("Color Management", "Cbdlsensi"); } - if (keyFile.has_key("Color Management", "Showtooltip")) {//show tooltip in locallab - showtooltip = keyFile.get_boolean("Color Management", "Showtooltip"); - } } @@ -2164,6 +2165,7 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_boolean("GUI", "HideTPVScrollbar", hideTPVScrollbar); keyFile.set_boolean("GUI", "HistogramWorking", rtSettings.HistogramWorking); keyFile.set_integer("GUI", "CurveBBoxPosition", curvebboxpos); + keyFile.set_boolean("GUI", "Showtooltip", showtooltip); //Glib::ArrayHandle crvopen = crvOpen; //keyFile.set_integer_list ("GUI", "CurvePanelsExpanded", crvopen); @@ -2213,7 +2215,6 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_string("Color Management", "ClutsDirectory", clutsDir); keyFile.set_integer("Color Management", "Previewselection", rtSettings.previewselection); keyFile.set_double("Color Management", "Cbdlsensi", rtSettings.cbdlsensi); - keyFile.set_boolean("Color Management", "Showtooltip", showtooltip); keyFile.set_string("ICC Profile Creator", "PimariesPreset", ICCPC_primariesPreset); keyFile.set_double("ICC Profile Creator", "RedPrimaryX", ICCPC_redPrimaryX); diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index f05153ddb..2c08ed408 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -958,6 +958,10 @@ Gtk::Widget* Preferences::getGeneralPanel() }; btnSaveTpOpenNow->signal_clicked().connect(save_tp_open_now); + ckbshowtooltiplocallab = Gtk::manage(new Gtk::CheckButton(M("PREFERENCES_SHOWTOOLTIP"))); + setExpandAlignProperties(ckbshowtooltiplocallab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_START); + workflowGrid->attach(*ckbshowtooltiplocallab,0, 3); + fworklflow->add(*workflowGrid); vbGeneral->attach_next_to (*fworklflow, Gtk::POS_TOP, 2, 1); @@ -1052,6 +1056,7 @@ Gtk::Widget* Preferences::getGeneralPanel() navGuideColorCB->set_use_alpha(true); Gtk::VSeparator *vSep = Gtk::manage(new Gtk::VSeparator()); + appearanceGrid->attach(*themeLbl, 0, 0, 1, 1); appearanceGrid->attach(*themeCBT, 1, 0, 1, 1); @@ -1786,6 +1791,7 @@ void Preferences::storePreferences() moptions.showFilmStripToolBar = ckbShowFilmStripToolBar->get_active(); moptions.hideTPVScrollbar = ckbHideTPVScrollbar->get_active(); moptions.overwriteOutputFile = chOverwriteOutputFile->get_active(); + moptions.showtooltip = ckbshowtooltiplocallab->get_active(); moptions.autoSaveTpOpen = ckbAutoSaveTpOpen->get_active(); @@ -1995,7 +2001,7 @@ void Preferences::fillPreferences() ckbFileBrowserToolbarSingleRow->set_active(moptions.FileBrowserToolbarSingleRow); ckbShowFilmStripToolBar->set_active(moptions.showFilmStripToolBar); ckbHideTPVScrollbar->set_active(moptions.hideTPVScrollbar); - + ckbshowtooltiplocallab->set_active(moptions.showtooltip); ckbAutoSaveTpOpen->set_active(moptions.autoSaveTpOpen); threadsSpinBtn->set_value (moptions.rgbDenoiseThreadLimit); @@ -2391,6 +2397,13 @@ void Preferences::workflowUpdate() parent->updateFBToolBarVisibility(moptions.showFilmStripToolBar); } + if (moptions.showtooltip != options.showtooltip) { + // Update the visibility of tooltip + parent->updateShowtooltipVisibility(moptions.showtooltip); + } + + moptions.showtooltip = ckbshowtooltiplocallab->get_active(); + if (moptions.histogramPosition != options.histogramPosition) { // Update the position of the Histogram parent->updateHistogramPosition(options.histogramPosition, moptions.histogramPosition); diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 6f434c477..fde3c4d06 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -200,6 +200,7 @@ class Preferences : public Gtk::Dialog, public ProfileStoreListener Gtk::CheckButton* ckbFileBrowserToolbarSingleRow; Gtk::CheckButton* ckbShowFilmStripToolBar; Gtk::CheckButton* ckbHideTPVScrollbar; + Gtk::CheckButton* ckbshowtooltiplocallab; Gtk::CheckButton* ckbAutoSaveTpOpen; Gtk::Button* btnSaveTpOpenNow; diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index 0d9017fbd..f5e57cce9 100644 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -1078,6 +1078,11 @@ void RTWindow::updateFBToolBarVisibility (bool showFilmStripToolBar) fpanel->fileCatalog->updateFBToolBarVisibility (showFilmStripToolBar); } +void RTWindow::updateShowtooltipVisibility (bool showtooltip) +{ + fpanel->fileCatalog->updateShowtooltipVisibility (showtooltip); +} + void RTWindow::updateHistogramPosition (int oldPosition, int newPosition) { if (epanel) { diff --git a/rtgui/rtwindow.h b/rtgui/rtwindow.h index 5b58ab0eb..e4ff285c1 100644 --- a/rtgui/rtwindow.h +++ b/rtgui/rtwindow.h @@ -114,6 +114,7 @@ public: void updateHistogramPosition (int oldPosition, int newPosition); void updateFBQueryTB (bool singleRow); void updateFBToolBarVisibility (bool showFilmStripToolBar); + void updateShowtooltipVisibility (bool showtooltip); bool getIsFullscreen() { return is_fullscreen;