From 6937c369ff42f952ce98681c9f727eedb4b19b8b Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 31 Jan 2017 11:29:06 +0100 Subject: [PATCH] Add mode 'super' for curves-lightness-contrast and suppress bug for cbdl --- rtdata/languages/default | 27 +- rtengine/dcrop.cc | 19 + rtengine/dirpyr_equalizer.cc | 87 --- rtengine/improccoordinator.cc | 97 ++- rtengine/improccoordinator.h | 1 + rtengine/improcfun.h | 5 +- rtengine/iplocallab.cc | 1059 +++++++++++++++++++++------------ rtengine/procevents.h | 1 + rtengine/procparams.cc | 18 +- rtengine/procparams.h | 1 + rtengine/refreshmap.cc | 3 +- rtengine/simpleprocess.cc | 36 +- rtgui/locallab.cc | 151 ++++- rtgui/locallab.h | 26 +- rtgui/paramsedited.cc | 6 + rtgui/paramsedited.h | 1 + 16 files changed, 992 insertions(+), 546 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 68a5f29c9..9db59170f 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -711,8 +711,8 @@ HISTORY_MSG_476;Local - Sh Iterations HISTORY_MSG_477;Local - Sh Scope HISTORY_MSG_478;Local - Sh Inverse HISTORY_MSG_479;Local - Spot size -HISTORY_MSG_480;Local - Hue theshold -HISTORY_MSG_481;Local - Hue proximity +HISTORY_MSG_480;Local - artifacts theshold +HISTORY_MSG_481;Local - artifacts iterations HISTORY_MSG_482;Local - Quality HISTORY_MSG_483;Local - Noise lum f HISTORY_MSG_484;Local - Noise lum c @@ -739,7 +739,7 @@ HISTORY_MSG_504;Local - Sharpening HISTORY_MSG_505;Local - CBDL HISTORY_MSG_506;Local - Denoise HISTORY_MSG_507;Local - LH Curve -HISTORY_MSG_508;Local - Enable curve +HISTORY_MSG_508;Local - Enable super HISTORY_MSG_509;Local - CC curve HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s @@ -1676,6 +1676,7 @@ TP_LENSPROFILE_USECA;Chromatic aberration correction TP_LENSPROFILE_USEDIST;Distortion correction TP_LENSPROFILE_USEVIGN;Vignetting correction TP_LOCALLAB_ACTIV;Blur luminance only +TP_LOCALLAB_ARTIF;Reduce artifacts - Improve algoritm TP_LOCALLAB_AVOID;Avoid color shift TP_LOCALLAB_BLUFR;Blur & Noise TP_LOCALLAB_CENTER_X;Center X @@ -1686,14 +1687,20 @@ TP_LOCALLAB_CHRRT;Chroma TP_LOCALLAB_CIRCRADIUS;Spot size TP_LOCALLAB_COFR;Color & Light TP_LOCALLAB_CONTRAST;Contrast -TP_LOCALLAB_CURV;Enable curves +TP_LOCALLAB_CURV;Lightness - Contrast "Super" +TP_LOCALLAB_CURVNONE;Disable curves +TP_LOCALLAB_CURVCURR;Normal +TP_LOCALLAB_CURVENH;Super TP_LOCALLAB_DENOIS;Denoise TP_LOCALLAB_LUM;Curves TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To be active, you must check button 'Enable curves' +TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) has the same algorithm than slider lightness.\n'Super' the curve L=f(L) has an new improved algorithm, which can leeds in some cases to artifacts. TP_LOCALLAB_NOISELUMFINE;Luminance fine TP_LOCALLAB_NOISELUMCOARSE;Luminance coarse TP_LOCALLAB_NOISECHROFINE;Chroma fine TP_LOCALLAB_NOISECHROCOARSE;Chroma coarse +TP_LOCALLAB_QUAL_METHOD;Global quality +TP_LOCALLAB_QUALCURV_METHOD;Curves type TP_LOCALLAB_GAM;Gamma TP_LOCALLAB_ESTOP;Edge stopping TP_LOCALLAB_SCALTM;Scale @@ -1706,15 +1713,15 @@ TP_LOCALLAB_NEUTRAL;Reset TP_LOCALLAB_NEUTRAL_TIP;Reset Current Control point TP_LOCALLAB_NBSPOT;Control points TP_LOCALLAB_NBSPOT_TOOLTIP;Add multiple control points and select -TP_LOCALLAB_STD;Quality Standard -TP_LOCALLAB_ENH;Quality Enhanced -TP_LOCALLAB_ENHDEN;Quality Enhanced + chroma denoise -TP_LOCALLAB_THRES;Hue threshold -TP_LOCALLAB_PROXI;Hue proximity radius +TP_LOCALLAB_STD;Standard +TP_LOCALLAB_ENH;Enhanced +TP_LOCALLAB_ENHDEN;Enhanced + chroma denoise +TP_LOCALLAB_THRES;Threshold chroma +TP_LOCALLAB_PROXI;Iterations TP_LOCALLAB_ANBSPOT;Help to Move Control point TP_LOCALLAB_ANBSPOT_TOOLTIP;Provisory control (I hope somebody can help to manage events!! and suppress this bad function) TP_LOCALLAB_LIGHTNESS;Lightness -TP_LOCALLAB_METHOD_TOOLTIP;Default - standard.\nIf you select Enhanced or enhanced chroma denoise - only for Color Light-Sharpening-Retinex-CBDL in normal mode, algorithm will detect the variations of hue in the select area and improve shape detection.\nHue threshold define since what value is exclude (* 100 radians).\nHue proximity radius define the radius around each point to calculate variations.\nEnhanced and Hue threshold significantly increases processing times. +TP_LOCALLAB_METHOD_TOOLTIP;Default - standard.\nIf you select Enhanced or enhanced chroma denoise - only for Color Light-Sharpening-Retinex-CBDL in normal mode\nEnhanced and chroma denoise significantly increases processing times. TP_LOCALLAB_RADIUS;Radius TP_LOCALLAB_RETI;Retinex TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 2db44d99f..7cbd443ea 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -957,6 +957,14 @@ void Crop::update (int todo) params.locallab.curvactiv = true; } + if (parent->qualitycurves[sp] == 0) { + params.locallab.qualitycurveMethod = "none" ; + } else if (parent->qualitycurves[sp] == 1) { + params.locallab.qualitycurveMethod = "std" ; + } else if (parent->qualitycurves[sp] == 2) { + params.locallab.qualitycurveMethod = "enh" ; + } + std::vector cretie; for (int j = 0; j < parent->sizeretics[sp]; j++) { @@ -1176,6 +1184,17 @@ void Crop::update (int todo) } + if (parent->qualitycurves[sp] == 0) { + params.locallab.qualitycurveMethod = "none" ; + parent->qualitycurves[sp] = 0; + } else if (parent->qualitycurves[sp] == 1) { + params.locallab.qualitycurveMethod = "std" ; + parent->qualitycurves[sp] = 1; + } else if (parent->qualitycurves[sp] == 2) { + params.locallab.qualitycurveMethod = "enh" ; + parent->qualitycurves[sp] = 2; + } + std::vector ccret; for (int j = 0; j < parent->sizeretics[sp]; j++) { diff --git a/rtengine/dirpyr_equalizer.cc b/rtengine/dirpyr_equalizer.cc index dd7211667..e5aced0fc 100644 --- a/rtengine/dirpyr_equalizer.cc +++ b/rtengine/dirpyr_equalizer.cc @@ -360,78 +360,6 @@ SSEFUNCTION void ImProcFunctions :: cbdl_local_temp(float ** src, float ** dst, } float **tmpHue, **tmpChr; - /* - if(skinprot != 0.f) { - // precalculate hue and chroma, use SSE, if available - // by precalculating these values we can greatly reduce the number of calculations in idirpyr_eq_channel() - // but we need two additional buffers for this preprocessing - tmpHue = new float*[srcheight]; - - for (int i = 0; i < srcheight; i++) { - tmpHue[i] = new float[srcwidth]; - } - - #ifdef __SSE2__ - #pragma omp parallel for - - for(int i = 0; i < srcheight; i++) { - int j; - - for(j = 0; j < srcwidth - 3; j += 4) { - _mm_storeu_ps(&tmpHue[i][j], xatan2f(LVFU(l_b[i][j]), LVFU(l_a[i][j]))); - } - - for(; j < srcwidth; j++) { - tmpHue[i][j] = xatan2f(l_b[i][j], l_a[i][j]); - } - } - - #else - #pragma omp parallel for - - for(int i = 0; i < srcheight; i++) { - for(int j = 0; j < srcwidth; j++) { - tmpHue[i][j] = xatan2f(l_b[i][j], l_a[i][j]); - } - } - - #endif - tmpChr = new float*[srcheight]; - - for (int i = 0; i < srcheight; i++) { - tmpChr[i] = new float[srcwidth]; - } - - #ifdef __SSE2__ - #pragma omp parallel - { - __m128 div = _mm_set1_ps(327.68f); - #pragma omp for - - for(int i = 0; i < srcheight; i++) { - int j; - - for(j = 0; j < srcwidth - 3; j += 4) { - _mm_storeu_ps(&tmpChr[i][j], _mm_sqrt_ps(SQRV(LVFU(l_b[i][j])) + SQRV(LVFU(l_a[i][j]))) / div); - } - - for(; j < srcwidth; j++) { - tmpChr[i][j] = sqrtf(SQR((l_b[i][j])) + SQR((l_a[i][j]))) / 327.68f; - } - } - } - #else - #pragma omp parallel for - - for(int i = 0; i < srcheight; i++) { - for(int j = 0; j < srcwidth; j++) { - tmpChr[i][j] = sqrtf(SQR((l_b[i][j])) + SQR((l_a[i][j]))) / 327.68f; - } - } - - #endif - } - */ // with the current implementation of idirpyr_eq_channel we can safely use the buffer from last level as buffer, saves some memory float ** buffer = dirpyrlo[lastlevel - 1]; @@ -442,21 +370,6 @@ SSEFUNCTION void ImProcFunctions :: cbdl_local_temp(float ** src, float ** dst, scale = scalesloc[0]; idirpyr_eq_channel_loc(dirpyrlo[0], dst, loctemp, buffer, srcwidth, srcheight, 0, multi, dirpyrThreshold, tmpHue, tmpChr, skinprot, gamutlab, b_l, t_l, t_r, b_r, choice ); - /* - if(skinprot != 0.f) { - for (int i = 0; i < srcheight; i++) { - delete [] tmpChr[i]; - } - - delete [] tmpChr; - - for (int i = 0; i < srcheight; i++) { - delete [] tmpHue[i]; - } - - delete [] tmpHue; - } - */ //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #pragma omp parallel for diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 0dfad4555..95c530c2f 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -149,6 +149,7 @@ ImProcCoordinator::ImProcCoordinator () sizelhcs (500, -10000), cccurvs (25000, -10000), //allow 500 values for each control point * 500 sizecccs (500, -10000), + qualitycurves (500, -10000), lumarefs (500, -100000.f), chromarefs (500, -100000.f), @@ -821,7 +822,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { for (int sp = 1; sp < maxspot; sp++) { // spots default int t_sp = sp; - int t_mipversion = 10006;//new value for tone mapping + int t_mipversion = 10007;//new value for tone mapping int t_circrad = 18; int t_locX = 250; int t_locY = 250; @@ -855,8 +856,8 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) int t_sensisha = 19; int t_inverssha = 0; int t_qualityMethod = 0; - int t_thres = 50; - int t_proxi = 2; + int t_thres = 18; + int t_proxi = 20; int t_noiselumf = 0; int t_noiselumc = 0; int t_noisechrof = 0; @@ -869,6 +870,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) int t_threshold = 20; int t_sensicb = 19; int t_activlum = 0; + // end versionmip = 10000 //begin versionmip = 10001 Tone mapping @@ -894,6 +896,9 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) //10006 std::string t_curvcc = "3000A0B0C1000D1000E"; //"3000A0B0C499D501E1000F1000G";// "3000A0B0C1000D1000E";//with that it works ! + //10007 + int t_qualitycurveMethod = 0; + //all variables except locRETgainCurve 'coomon for all) fic << "Mipversion=" << t_mipversion << '@' << endl; fic << "Spot=" << t_sp << '@' << endl; @@ -954,6 +959,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) fic << "Retrab=" << t_retrab << '@' << endl; fic << "Curvactiv=" << t_curvactiv << '@' << endl; + fic << "qualitycurveMethod=" << t_qualitycurveMethod << '@' << endl; fic << "curveReti=" << t_curvret << '@' << endl; fic << "curveLL=" << t_curvll << '@' << endl; @@ -977,9 +983,9 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) int realspot = params.locallab.nbspot; std::string inser; - dataspot = new int*[60]; + dataspot = new int*[61]; - for (int i = 0; i < 60; i++) { + for (int i = 0; i < 61; i++) { dataspot[i] = new int[maxspot]; } @@ -1107,6 +1113,14 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) dataspot[56][0] = curvactivs[0] = 1; } + if (params.locallab.qualitycurveMethod == "none") { + dataspot[57][0] = qualitycurves[0] = 0; + } else if (params.locallab.qualitycurveMethod == "std") { + dataspot[57][0] = qualitycurves[0] = 1; + } else if (params.locallab.qualitycurveMethod == "enh") { + dataspot[57][0] = qualitycurves[0] = 2; + } + //curve Reti local int siz = params.locallab.localTgaincurve.size(); @@ -1234,7 +1248,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) std::string line; std::string spotline; int cont = 0; - int maxind = 57; + int maxind = 58; if (versionmip == 10000) { maxind = 49; @@ -1259,6 +1273,10 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) excurvcc = false; } + if (versionmip == 10006) { + maxind = 57; + } + int sizecu; int sizell; int sizelh; @@ -1436,13 +1454,20 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) } } + if (versionmip == 10006) { + + for (int sp = 1; sp < maxspot; sp++) { // spots default + dataspot[57][sp] = 0; //qualitycurveMethod + } + } + if (ns < (maxspot - 1)) { ofstream fic (datal, ios::out | ios::app); // ouverture en écriture avec effacement du fichier ouvert for (int sp = ns + 1 ; sp < maxspot; sp++) { // spots default int t_sp = sp; - int t_mipversion = 10006; + int t_mipversion = 10007; int t_circrad = 18; int t_locX = 250; int t_locY = 250; @@ -1476,8 +1501,8 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) int t_sensisha = 19; int t_inverssha = 0; int t_qualityMethod = 0; - int t_thres = 50; - int t_proxi = 2; + int t_thres = 18; + int t_proxi = 20; int t_noiselumf = 0; int t_noiselumc = 0; int t_noisechrof = 0; @@ -1510,6 +1535,8 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) int t_curvactiv = 0; //10006 std::string t_curvcc = "3000A0B0C1000D1000E"; + //10007 + int t_qualitycurveMethod = 0; fic << "Mipversion=" << t_mipversion << '@' << endl; fic << "Spot=" << t_sp << '@' << endl; @@ -1569,6 +1596,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) fic << "Sensitm=" << t_sensitm << '@' << endl; fic << "Retrab=" << t_retrab << '@' << endl; fic << "Curvactiv=" << t_curvactiv << '@' << endl; + fic << "qualitycurveMethod=" << t_qualitycurveMethod << '@' << endl; fic << "curveReti=" << t_curvret << '@' << endl; fic << "curveLL=" << t_curvll << '@' << endl; @@ -1589,7 +1617,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) std::string spotline2; int cont2 = 0; int ns2; - int maxin = 57; + int maxin = 58; int sizecu2; int sizell2; int sizelh2; @@ -1861,6 +1889,17 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) params.locallab.curvactiv = true; } + if (dataspot[57][sp] == 0) { + qualitycurves[sp] = 0; + params.locallab.qualitycurveMethod = "none" ; + } else if (dataspot[57][sp] == 1) { + qualitycurves[sp] = 1; + params.locallab.qualitycurveMethod = "std" ; + } else if (dataspot[57][sp] == 2) { + qualitycurves[sp] = 2; + params.locallab.qualitycurveMethod = "enh" ; + } + int *s_datc; s_datc = new int[70]; int siz; @@ -1952,9 +1991,9 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) CurveFactory::curveCCLocal (localcutili, params.locallab.cccurve, cclocalcurve, sca); //scale == 1 ? 1 : 16); ipf.Lab_Local (3, sp, (float**)shbuffer, nprevl, nprevl, 0, 0, 0, 0, pW, pH, fw, fh, locutili, scale, locRETgainCurve, locallutili, lllocalcurve, loclhCurve, cclocalcurve, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref); - dataspot[57][sp] = huerefs[sp] = 100.f * params.locallab.hueref; - dataspot[58][sp] = chromarefs[sp] = params.locallab.chromaref; - dataspot[59][sp] = lumarefs[sp] = params.locallab.lumaref; + dataspot[58][sp] = huerefs[sp] = 100.f * params.locallab.hueref; + dataspot[59][sp] = chromarefs[sp] = params.locallab.chromaref; + dataspot[60][sp] = lumarefs[sp] = params.locallab.lumaref; nextParams.locallab.hueref = params.locallab.hueref; nextParams.locallab.chromaref = params.locallab.chromaref; nextParams.locallab.lumaref = params.locallab.lumaref; @@ -2147,6 +2186,20 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) curvactivs[sp] = 1; } + if (dataspot[57][0] == 0) { + params.locallab.qualitycurveMethod = "none" ; + qualitycurves[sp] = 0; + dataspot[57][sp] = 0; + } else if (dataspot[57][0] == 1) { + params.locallab.qualitycurveMethod = "std" ; + qualitycurves[sp] = 1; + dataspot[57][sp] = 1; + } else if (dataspot[57][0] == 2) { + params.locallab.qualitycurveMethod = "enh" ; + qualitycurves[sp] = 2; + dataspot[57][sp] = 2; + } + int *s_datc; s_datc = new int[70]; int siz; @@ -2243,9 +2296,9 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) CurveFactory::curveCCLocal (localcutili, params.locallab.cccurve, cclocalcurve, sca); //scale == 1 ? 1 : 16); ipf.Lab_Local (3, sp, (float**)shbuffer, nprevl, nprevl, 0, 0, 0, 0, pW, pH, fw, fh, locutili, scale, locRETgainCurve, locallutili, lllocalcurve, loclhCurve, cclocalcurve, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref); - dataspot[57][sp] = huerefs[sp] = 100.f * params.locallab.hueref; - dataspot[58][sp] = chromarefs[sp] = params.locallab.chromaref; - dataspot[59][sp] = lumarefs[sp] = params.locallab.lumaref; + dataspot[58][sp] = huerefs[sp] = 100.f * params.locallab.hueref; + dataspot[59][sp] = chromarefs[sp] = params.locallab.chromaref; + dataspot[60][sp] = lumarefs[sp] = params.locallab.lumaref; lllocalcurve.clear(); cclocalcurve.clear(); @@ -2262,7 +2315,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) for (int spe = 1; spe < maxspot; spe++) { int t_sp = spe; - int t_mipversion = 10006; + int t_mipversion = 10007; int t_circrad = dataspot[2][spe]; int t_locX = dataspot[3][spe]; int t_locY = dataspot[4][spe]; @@ -2319,10 +2372,11 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) int t_sensitm = dataspot[54][spe]; int t_retrab = dataspot[55][spe]; int t_curvactiv = dataspot[56][spe]; + int t_qualitycurveMethod = dataspot[57][spe]; - int t_hueref = dataspot[57][spe]; - int t_chromaref = dataspot[58][spe]; - int t_lumaref = dataspot[59][spe]; + int t_hueref = dataspot[58][spe]; + int t_chromaref = dataspot[59][spe]; + int t_lumaref = dataspot[60][spe]; std::string t_curvret = retistr[spe]; std::string t_curvll = llstr[spe]; @@ -2388,6 +2442,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) fou << "Retrab=" << t_retrab << '@' << endl; fou << "Curvactiv=" << t_curvactiv << '@' << endl; + fou << "qualitycurveMethod=" << t_qualitycurveMethod << '@' << endl; fou << "hueref=" << t_hueref << '@' << endl; fou << "chromaref=" << t_chromaref << '@' << endl; @@ -2405,7 +2460,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) - for (int i = 0; i < 60; i++) { + for (int i = 0; i < 61; i++) { delete [] dataspot[i]; } diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 80e72e369..0404ad295 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -279,6 +279,7 @@ protected: LUTi scaltms; LUTi reweis; LUTi sensitms; + LUTi qualitycurves; int versionmip; LUTi sizeretics; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 027715c40..63b280dbe 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -72,6 +72,7 @@ class ImProcFunctions bool needsLCP (); // static cmsUInt8Number* Mempro = NULL; + inline void interpolateTransformCubic (Imagefloat* src, int xs, int ys, double Dx, double Dy, float *r, float *g, float *b, double mul) { const double A = -0.85; @@ -284,7 +285,7 @@ public: void InverseBlurNoise_Local (const struct local_params& lp, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy); void Reti_Local (int call, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const struct local_params& lp, float **deltE, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy, int chro); void InverseReti_Local (const struct local_params& lp, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy, int chro); - void Contrast_Local (int call, float moy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, float pm, struct local_contra &lco, float lumaref, float av, const struct local_params& lp, float **deltE, LabImage* original, LabImage* transformed, int cx, int cy); + void Contrast_Local (int call, LabImage * bufcontorig, float ** buflightc, float moy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, float pm, struct local_contra &lco, float lumaref, float av, const struct local_params& lp, float **deltE, LabImage* original, LabImage* transformed, int cx, int cy); void cbdl_Local (int call, int sp, float **loctemp, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const local_params& lp, float **deltE, LabImage* original, LabImage* transformed, int cx, int cy); void BlurNoise_Local (int call, int sp, LabImage* tmp1, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const local_params& lp, float **deltE, LabImage* original, LabImage* transformed, int cx, int cy); void TM_Local (int call, int sp, LabImage* tmp1, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const local_params& lp, float **deltE, LabImage* original, LabImage* transformed, int cx, int cy); @@ -293,7 +294,7 @@ public: void DeNoise_Local (int call, const struct local_params& lp, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy); - void ColorLight_Local (int call, LabImage * bufcolorig, LabImage * bufcoltra, int sp, float moy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, bool locallutili, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, LUTf & cclocalcurve, float chprov, const local_params& lp, float **deltE, LabImage* original, LabImage* transformed, int cx, int cy); + void ColorLight_Local (int call, LabImage * bufcolorig, LabImage * bufcoltra, float **buflight, float **bufchro, float ** buflightslid, int sp, float moy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, bool locallutili, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, LUTf & cclocalcurve, float chprov, float cligh, const local_params& lp, float **deltE, LabImage* original, LabImage* transformed, int cx, int cy); void InverseColorLight_Local (const struct local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy); void Sharp_Local (int call, int sp, float **loctemp, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const local_params& lp, float **deltE, LabImage* original, LabImage* transformed, int cx, int cy); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 996b943d5..9abb42507 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -45,6 +45,9 @@ #define CLIPC(a) ((a)>-42000?((a)<42000?(a):42000):-42000) // limit a and b to 130 probably enough ? #define CLIPL(x) LIM(x,0.f,40000.f) // limit L to about L=120 probably enough ? #define CLIPLOC(x) LIM(x,0.f,32767.f) +#define CLIPLIG(x) LIM(x,0.f, 100.f) +#define CLIPCHRO(x) LIM(x,0.f, 140.f) + namespace rtengine { using namespace procparams; @@ -56,6 +59,7 @@ struct local_params { float lx, ly; float lxL, lyT; float dxx, dyy; + float iterat; int cir; float thr; int prox; @@ -74,6 +78,7 @@ struct local_params { bool actsp; float str; int qualmet; + int qualcurvemet; float noiself; float noiselc; float noisecf; @@ -115,10 +120,10 @@ static void calcLocalParams (int oW, int oH, const LocallabParams& locallab, str double local_yT = locallab.locYT / 2000.0; double local_center_x = locallab.centerX / 2000.0 + 0.5; double local_center_y = locallab.centerY / 2000.0 + 0.5; -// double local_dxx = locallab.proxi / 8000.0;//for proxi = 2==> # 1 pixel -// double local_dyy = locallab.proxi / 8000.0; - float local_dxx = locallab.proxi; - double local_dyy = locallab.proxi; + double local_dxx = locallab.proxi / 8000.0;//for proxi = 2==> # 1 pixel + double local_dyy = locallab.proxi / 8000.0; + float iterati = (float) locallab.proxi; +// double local_dyy = locallab.proxi; if (locallab.qualityMethod == "std") { lp.qualmet = 0; @@ -128,6 +133,14 @@ static void calcLocalParams (int oW, int oH, const LocallabParams& locallab, str lp.qualmet = 2; } + if (locallab.qualitycurveMethod == "none") { + lp.qualcurvemet = 0; + } else if (locallab.qualitycurveMethod == "std") { + lp.qualcurvemet = 1; + } else if (locallab.qualitycurveMethod == "enh") { + lp.qualcurvemet = 2; + } + float local_noiself = locallab.noiselumf; float local_noiselc = locallab.noiselumc; float local_noisecf = locallab.noisechrof; @@ -197,10 +210,12 @@ static void calcLocalParams (int oW, int oH, const LocallabParams& locallab, str lp.shamo = local_sharamount; lp.shdamp = local_shardamping; lp.shiter = local_shariter; - lp.dxx = local_dxx; + lp.iterat = iterati; + lp.dxx = w * local_dxx; lp.dyy = h * local_dyy; lp.thr = thre; lp.noiself = local_noiself; + lp.noiself = local_noiself; lp.noiselc = local_noiselc; lp.noisecf = local_noisecf; lp.noisecc = local_noisecc; @@ -457,7 +472,7 @@ void ImProcFunctions::DeNoise_Local (int call, const struct local_params& lp, La difa = tmp1->a[loy - begy - 1][lox - begx - 1] - original->a[y][x]; difb = tmp1->b[loy - begy - 1][lox - begx - 1] - original->b[y][x]; } - } else if (call == 1) { //dcrop + } else { //dcrop 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]; @@ -483,7 +498,7 @@ void ImProcFunctions::DeNoise_Local (int call, const struct local_params& lp, La difa = tmp1->a[loy - begy - 1][lox - begx - 1] - original->a[y][x]; difb = tmp1->b[loy - begy - 1][lox - begx - 1] - original->b[y][x]; } - } else if (call == 1) { //dcrop + } else { //dcrop 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]; @@ -672,7 +687,7 @@ void ImProcFunctions::cbdl_Local (int call, int sp, float **loctemp, const float } if (lp.qualmet == 1) { - if (deltE[y][x] > lp.thr) { + if (deltE[y][x] > 10.f * lp.thr) { fach = 1.f; } } else { @@ -704,13 +719,13 @@ void ImProcFunctions::cbdl_Local (int call, int sp, float **loctemp, const float case 1: { // inside transition zone float factorx = localFactor; - float difL; + float difL = 0.f; if (call == 2) { if (lox >= (lp.xc - lp.lxL) && lox < (lp.xc + lp.lx) && loy >= (lp.yc - lp.lyT) && loy < (lp.yc + lp.ly)) { difL = loctemp[loy - begy - 1][lox - begx - 1] - original->L[y][x]; } - } else if (call == 1) { + } else { difL = loctemp[y][x] - original->L[y][x]; } @@ -724,7 +739,7 @@ void ImProcFunctions::cbdl_Local (int call, int sp, float **loctemp, const float case 2: { // inside selection => full effect, no transition // float difL = loctemp[y][x] - original->L[y][x]; - float difL; + float difL = 0.f; if (call == 2) { @@ -732,13 +747,14 @@ void ImProcFunctions::cbdl_Local (int call, int sp, float **loctemp, const float // bufsh[loy - begy - 1][lox - begx - 1] difL = loctemp[loy - begy - 1][lox - begx - 1] - original->L[y][x]; } - } else if (call == 1) { + } else { difL = loctemp[y][x] - original->L[y][x]; } transformed->L[y][x] = original->L[y][x] + difL * kch * fach; } } + } } } @@ -914,7 +930,7 @@ void ImProcFunctions::TM_Local (int call, int sp, LabImage * tmp1, const float h } if (lp.qualmet == 1) { - if (deltE[y][x] > lp.thr) { + if (deltE[y][x] > 10.f * lp.thr) { fach = 1.f; } } else { @@ -1176,7 +1192,7 @@ void ImProcFunctions::BlurNoise_Local (int call, int sp, LabImage * tmp1, const } if (lp.qualmet == 1) { - if (deltE[y][x] > lp.thr) { + if (deltE[y][x] > 10.f * lp.thr) { fach = 1.f; } } else { @@ -1564,7 +1580,7 @@ void ImProcFunctions::Reti_Local (int call, const float hueplus, const float hue } if (lp.qualmet >= 1) { - if (deltE[y][x] > lp.thr) { + if (deltE[y][x] > 10.f * lp.thr) { fach = 1.f; } } else { @@ -1816,7 +1832,7 @@ struct local_contra { float al, bl; }; -void ImProcFunctions::Contrast_Local (int call, float moy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, float pm, struct local_contra & lco, float lumaref, float av, const struct local_params & lp, float **deltE, LabImage * original, LabImage * transformed, int cx, int cy) +void ImProcFunctions::Contrast_Local (int call, LabImage * bufcontorig, float ** buflightc, float moy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, float pm, struct local_contra & lco, float lumaref, float av, const struct local_params & lp, float **deltE, LabImage * original, LabImage * transformed, int cx, int cy) { // BENCHFUN // contrast - perhaps for 4 areas if need @@ -1845,7 +1861,6 @@ void ImProcFunctions::Contrast_Local (int call, float moy, const float hueplus, lco.aDY = realcoy; - constexpr float delhu = 0.1f; //between 0.05 and 0.2 const float apl = (-1.f) / delhu; @@ -1865,8 +1880,10 @@ void ImProcFunctions::Contrast_Local (int call, float moy, const float hueplus, const float vinf = (50.f + localtype / 2.f) / 100.f; ImProcFunctions::secondeg_begin (reducac, vi, lco.aa, lco.bb);//parabolic ImProcFunctions::secondeg_end (reducac, vinf, lco.aaa, lco.bbb, lco.ccc);//parabolic + float maxco = -10000.f; + float minco = +10000.f; - if (call == 2) { + if (call <= 3) { #ifdef _OPENMP #pragma omp parallel if (multiThread) @@ -1918,13 +1935,26 @@ void ImProcFunctions::Contrast_Local (int call, float moy, const float hueplus, int begy = int (lp.yc - lp.lyT); if (lox >= (lp.xc - lp.lxL) && lox < (lp.xc + lp.lx) && loy >= (lp.yc - lp.lyT) && loy < (lp.yc + lp.ly)) { - float localFactor = 1.f; - calcTransition (lox, loy, ach, lp, zone, localFactor); + // float localFactor = 1.f; + // calcTransition (lox, loy, ach, lp, zone, localFactor); //prepare shape detection float khu = 0.f; float kch = 1.f; bool kzon = false; float fach = 1.f; + + float cli = (buflightc[loy - begy - 1][lox - begx - 1]); + //parameters for linear interpolation in function of real hue + float apluscligh = (1.f - cli) / delhu; + float bpluscligh = 1.f - apluscligh * hueplus; + float amoinscligh = (cli - 1.f) / delhu; + float bmoinscligh = 1.f - amoinscligh * huemoins; + + float realcligh = 1.f; + + + + float deltachro = fabs (rchro - chromaref); float deltahue = fabs (rhue - hueref); @@ -1955,10 +1985,16 @@ void ImProcFunctions::Contrast_Local (int call, float moy, const float hueplus, //hue detection if ((hueref + dhue) < M_PI && rhue < hueplus && rhue > huemoins) { //transition are good if (rhue >= hueplus - delhu ) { + realcligh = apluscligh * rhue + bpluscligh; + khu = apl * rhue + bpl; } else if (rhue < huemoins + delhu) { + realcligh = amoinscligh * rhue + bmoinscligh; + khu = amo * rhue + bmo; } else { + realcligh = cli; + khu = 1.f; } @@ -1966,10 +2002,16 @@ void ImProcFunctions::Contrast_Local (int call, float moy, const float hueplus, kzon = true; } else if ((hueref + dhue) >= M_PI && (rhue > huemoins || rhue < hueplus )) { if (rhue >= hueplus - delhu && rhue < hueplus) { + realcligh = apluscligh * rhue + bpluscligh; + khu = apl * rhue + bpl; } else if (rhue >= huemoins && rhue < huemoins + delhu) { + realcligh = amoinscligh * rhue + bmoinscligh; + khu = amo * rhue + bmo; } else { + realcligh = cli; + khu = 1.f; } @@ -1978,20 +2020,31 @@ void ImProcFunctions::Contrast_Local (int call, float moy, const float hueplus, if ((hueref - dhue) > -M_PI && rhue < hueplus && rhue > huemoins ) { if (rhue >= hueplus - delhu && rhue < hueplus) { + realcligh = apluscligh * rhue + bpluscligh; + khu = apl * rhue + bpl; } else if (rhue >= huemoins && rhue < huemoins + delhu) { + realcligh = amoinscligh * rhue + bmoinscligh; khu = amo * rhue + bmo; } else { + realcligh = cli; + khu = 1.f; } kzon = true; } else if ((hueref - dhue) <= -M_PI && (rhue > huemoins || rhue < hueplus )) { if (rhue >= hueplus - delhu && rhue < hueplus) { + realcligh = apluscligh * rhue + bpluscligh; + khu = apl * rhue + bpl; } else if (rhue >= huemoins && rhue < huemoins + delhu) { + realcligh = amoinscligh * rhue + bmoinscligh; + khu = amo * rhue + bmo; } else { + realcligh = cli; + khu = 1.f; } @@ -2011,7 +2064,7 @@ void ImProcFunctions::Contrast_Local (int call, float moy, const float hueplus, } if (lp.qualmet >= 1) { - if (deltE[y][x] > lp.thr) { + if (deltE[y][x] > 10.f * lp.thr) { fach = 1.f; } } else { @@ -2032,6 +2085,18 @@ void ImProcFunctions::Contrast_Local (int call, float moy, const float hueplus, */ } + float kcr = 100.f * lp.thr; + float falL = 1.f; + + if (rchro < kcr && chromaref > kcr) { // reduce artifacts in grey tones near hue spot and improve algorithm + falL *= pow (rchro / kcr, lp.iterat / 10.f); + } + + float localFactor = 1.f; + calcTransition (lox, loy, ach, lp, zone, localFactor); + + float kdiff = 1.f; + if (rL > 0.01f) { //to avoid crash with very low gamut in rare cases ex : L=0.01 a=0.5 b=-0.9 switch (zone) { @@ -2043,332 +2108,114 @@ void ImProcFunctions::Contrast_Local (int call, float moy, const float hueplus, } case 1: { // inside transition zone - if (original->L[y][x] < 32768.f) { - float factorx = localFactor; - float prov100 = original->L[y][x] / 32768.f; - float prov = prov100 * 100.f; - bool contin = true; + if (lp.curvact == false) { + + if (original->L[y][x] < 32768.f) { + float factorx = localFactor; + float prov100 = original->L[y][x] / 32768.f; + float prov = prov100 * 100.f; + bool contin = true; - if (contin) { + if (contin) { - if (prov > localtype) { - if (prov >= localtype && prov < 50.f + localtype / 2.f) { - float core = (lco.alsup2 * prov + lco.blsup2) ; - core *= factorx; + if (prov > localtype) { + if (prov >= localtype && prov < 50.f + localtype / 2.f) { + float core = (lco.alsup2 * prov + lco.blsup2) ; + core *= factorx; - transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * (core) * kch * fach); - } else { - float core = lco.aDY * (lco.aaa * prov100 * prov100 + lco.bbb * prov100 + lco.ccc); + transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * (core) * kch * fach * falL); + } else { + float core = lco.aDY * (lco.aaa * prov100 * prov100 + lco.bbb * prov100 + lco.ccc); - core *= factorx; - transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * (core) * kch * fach); - } - } else { //inferior - if (2.f * prov > localtype && prov < localtype) { - float core = (lco.alsup * prov + lco.blsup) ; - core *= factorx; - transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach); - } else if (2.f * prov <= localtype) { - float core = prov * lco.alinf * (lco.aa * prov100 * prov100 + lco.bb * prov100); + core *= factorx; - core *= factorx; - transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach); + transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * (core) * kch * fach * falL); + } + } else { //inferior + if (2.f * prov > localtype && prov < localtype) { + float core = (lco.alsup * prov + lco.blsup) ; + core *= factorx; + + transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach * falL); + } else if (2.f * prov <= localtype) { + float core = prov * lco.alinf * (lco.aa * prov100 * prov100 + lco.bb * prov100); + + core *= factorx; + + transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach * falL); + } } } + } else { + transformed->L[y][x] = original->L[y][x]; } - } else { - transformed->L[y][x] = original->L[y][x]; - } - break; + break; + } else { + float lumnew = bufcontorig->L[loy - begy - 1][lox - begx - 1]; + + float factorx = localFactor; + float fli = 1.f; + fli = ((100.f + realcligh * falL ) / 100.f);//luma transition + float lightcont = lumnew; + float diflc = lightcont * fli - original->L[y][x]; + kdiff *= fach * kch; + diflc *= kdiff ; + diflc *= factorx; //transition + + transformed->L[y][x] = CLIPL (1.f * (original->L[y][x] + diflc)); + + } } case 2: { // inside selection => full effect, no transition - if (original->L[y][x] < 32768.f) { - float prov100 = original->L[y][x] / 32768.f; - float prov = prov100 * 100.f; + if (lp.curvact == false) { - bool contin = true; + if (original->L[y][x] < 32768.f) { + float prov100 = original->L[y][x] / 32768.f; + float prov = prov100 * 100.f; - if (contin) { + bool contin = true; + + if (contin) { - if (prov > localtype ) { - if (prov >= localtype && prov < 50.f + localtype / 2.f) { - float core = (lco.alsup2 * prov + lco.blsup2) ; - transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * core * kch * fach); - } else { - float core = lco.aDY * (lco.aaa * prov100 * prov100 + lco.bbb * prov100 + lco.ccc); - transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * core * kch * fach); - } - } else { //inferior - if (2.f * prov > localtype && prov < localtype) { - float core = (lco.alsup * prov + lco.blsup) ; - transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach); - } else if (2.f * prov <= localtype) { - float core = prov * lco.alinf * (lco.aa * prov100 * prov100 + lco.bb * prov100); - transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach); + if (prov > localtype ) { + if (prov >= localtype && prov < 50.f + localtype / 2.f) { + float core = (lco.alsup2 * prov + lco.blsup2) ; + transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * core * kch * fach * falL); + } else { + float core = lco.aDY * (lco.aaa * prov100 * prov100 + lco.bbb * prov100 + lco.ccc); + transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * core * kch * fach * falL); + } + } else { //inferior + if (2.f * prov > localtype && prov < localtype) { + float core = (lco.alsup * prov + lco.blsup) ; + transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach * falL); + } else if (2.f * prov <= localtype) { + float core = prov * lco.alinf * (lco.aa * prov100 * prov100 + lco.bb * prov100); + transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach * falL); + } } } - } - } else { - transformed->L[y][x] = original->L[y][x]; - } - } - } - } - } - } - } - } - } else { - -#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++) - { -#ifdef __SSE2__ - int i = 0; - - for (; i < transformed->W - 3; i += 4) { - vfloat av = LVFU (original->a[y][i]); - vfloat bv = LVFU (original->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 (original->b[y][i], original->a[y][i]); - sqrtBuffer[i] = sqrt (SQR (original->b[y][i]) + SQR (original->a[y][i])) / 327.68f; - } - -#endif - - int loy = cy + y; - - for (int x = 0; x < transformed->W; x++) { - int lox = cx + x; -#ifdef __SSE2__ - float rhue = atan2Buffer[x]; - float rchro = sqrtBuffer[x]; -#else - float rhue = xatan2f (original->b[y][x], original->a[y][x]); - float rchro = sqrt (SQR (original->b[y][x]) + SQR (original->a[y][x])) / 327.68f; -#endif - int zone; - 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); - //prepare shape detection - float khu = 0.f; - float kch = 1.f; - bool kzon = false; - float fach = 1.f; - float deltachro = fabs (rchro - chromaref); - float deltahue = fabs (rhue - hueref); - - if (deltahue > M_PI) { - deltahue = - (deltahue - 2.f * M_PI); - } - - float deltaE = 20.f * deltahue + deltachro; //pseudo deltaE between 0 and 280 - float rL = original->L[y][x] / 327.68f; - - //kch to modulate action with chroma - if (deltachro < 160.f * SQR (lp.sens / 100.f)) { - kch = 1.f; - } else { - float ck = 160.f * SQR (lp.sens / 100.f); - float ak = 1.f / (ck - 160.f); - float bk = -160.f * ak; - kch = ak * deltachro + bk; - } - - if (lp.sens < 40.f ) { - kch = pow (kch, pa * lp.sens + pb); //increase under 40 - } - - - // algo with detection of hue ==> artifacts for noisy images ==> denoise before - if (lp.sens < 20.f) { //to try... - //hue detection - if ((hueref + dhue) < M_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 + dhue) >= M_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 - dhue) > -M_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 - dhue) <= -M_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 (deltaE < 2.8f * lp.sens) { - fach = khu; - } else { - fach = khu * (ahu * deltaE + bhu); - } - - float kcr = 10.f; - - if (rchro < kcr) { - fach *= (1.f / (kcr * kcr)) * rchro * rchro; - } - - if (lp.qualmet >= 1) { - if (deltE[y][x] > lp.thr) { - fach = 1.f; - } - } else { - fach = 1.f; - } - - //fach = khu ; - - } else { - /* - float kcr = 8.f; - if(lp.sensh > 30.f){ - if (rchro < kcr) { - fach *= (1.f / (kcr)) * rchro; - - } - } - */ - } - - if (rL > 0.01f) { //to avoid crash with very low gamut in rare cases ex : L=0.01 a=0.5 b=-0.9 - - 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 - if (original->L[y][x] < 32768.f) { - float factorx = localFactor; - float prov100 = original->L[y][x] / 32768.f; - float prov = prov100 * 100.f; - bool contin = true; - - - if (contin) { - - if (prov > localtype) { - if (prov >= localtype && prov < 50.f + localtype / 2.f) { - float core = (lco.alsup2 * prov + lco.blsup2) ; - core *= factorx; - - transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * (core) * kch * fach); - } else { - float core = lco.aDY * (lco.aaa * prov100 * prov100 + lco.bbb * prov100 + lco.ccc); - - core *= factorx; - transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * (core) * kch * fach); - } - } else { //inferior - if (2.f * prov > localtype && prov < localtype) { - float core = (lco.alsup * prov + lco.blsup) ; - core *= factorx; - transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach); - } else if (2.f * prov <= localtype) { - float core = prov * lco.alinf * (lco.aa * prov100 * prov100 + lco.bb * prov100); - - core *= factorx; - transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach); - } + } else { + transformed->L[y][x] = original->L[y][x]; } } - } else { - transformed->L[y][x] = original->L[y][x]; - } - break; - } - - case 2: { // inside selection => full effect, no transition - if (original->L[y][x] < 32768.f) { - float prov100 = original->L[y][x] / 32768.f; - float prov = prov100 * 100.f; - - bool contin = true; - - if (contin) { - - - - if (prov > localtype ) { - if (prov >= localtype && prov < 50.f + localtype / 2.f) { - float core = (lco.alsup2 * prov + lco.blsup2) ; - transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * core * kch * fach); - } else { - float core = lco.aDY * (lco.aaa * prov100 * prov100 + lco.bbb * prov100 + lco.ccc); - transformed->L[y][x] = 327.68f * (prov + pm * (prov - localtype) * core * kch * fach); - } - } else { //inferior - if (2.f * prov > localtype && prov < localtype) { - float core = (lco.alsup * prov + lco.blsup) ; - transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach); - } else if (2.f * prov <= localtype) { - float core = prov * lco.alinf * (lco.aa * prov100 * prov100 + lco.bb * prov100); - transformed->L[y][x] = 327.68f * (prov - pm * (localtype - prov) * core * kch * fach); - } - } + else { + float lumnew = bufcontorig->L[loy - begy - 1][lox - begx - 1]; + float fli = 1.f; + fli = ((100.f + realcligh * falL ) / 100.f);//luma transition + float lightcont = lumnew; + float diflc = lightcont * fli - original->L[y][x]; + kdiff *= fach * kch; + diflc *= kdiff ; + transformed->L[y][x] = CLIPL (1.f * (original->L[y][x] + diflc)); } - } else { - transformed->L[y][x] = original->L[y][x]; + } } } @@ -2656,7 +2503,7 @@ void ImProcFunctions::InverseSharp_Local (int sp, float **loctemp, const float h } if (lp.qualmet >= 1) { - if (deltE[y][x] > lp.thr) { + if (deltE[y][x] > 10.f * lp.thr) { fach = 1.f; } } else { @@ -2876,7 +2723,7 @@ void ImProcFunctions::Sharp_Local (int call, int sp, float **loctemp, const floa } if (lp.qualmet == 1) { - if (deltE[y][x] > lp.thr) { + if (deltE[y][x] > 10.f * lp.thr) { fach = 1.f; } } else { @@ -2914,7 +2761,7 @@ void ImProcFunctions::Sharp_Local (int call, int sp, float **loctemp, const floa if (lox >= (lp.xc - lp.lxL) && lox < (lp.xc + lp.lx) && loy >= (lp.yc - lp.lyT) && loy < (lp.yc + lp.ly)) { difL = loctemp[loy - begy - 1][lox - begx - 1] - original->L[y][x]; } - } else if (call == 1) { + } else { difL = loctemp[y][x] - original->L[y][x]; } @@ -2936,7 +2783,7 @@ void ImProcFunctions::Sharp_Local (int call, int sp, float **loctemp, const floa // bufsh[loy - begy - 1][lox - begx - 1] difL = loctemp[loy - begy - 1][lox - begx - 1] - original->L[y][x]; } - } else if (call == 1) { + } else { difL = loctemp[y][x] - original->L[y][x]; } @@ -2950,7 +2797,7 @@ void ImProcFunctions::Sharp_Local (int call, int sp, float **loctemp, const floa -void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImage * bufcoltra, int sp, float moy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, bool locallutili, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, LUTf & cclocalcurve, float chprov, const local_params & lp, float ** deltE, LabImage * original, LabImage * transformed, int cx, int cy) +void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImage * bufcoltra, float ** buflight, float ** bufchro, float ** buflightslid, int sp, float moy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, bool locallutili, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, LUTf & cclocalcurve, float chprov, float cligh, const local_params & lp, float ** deltE, LabImage * original, LabImage * transformed, int cx, int cy) { // BENCHFUN // chroma and lightness @@ -2975,18 +2822,14 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag const float multchroskin = lp.sens * achsensskin + bchsensskin; //transition = difficult to avoid artifact with scope on flat area (sky...) - constexpr float delhu = 0.1f; //between 0.05 and 0.2 + constexpr float delhu = 0.1f; //between 0.05 and 0.2 ==> minima for scope + //constexpr float delhu2 = 0.03f; //between 0.05 and 0.2 + const float aplus = (1.f - lp.chro) / delhu; const float bplus = 1.f - aplus * hueplus; const float amoins = (lp.chro - 1.f) / delhu; const float bmoins = 1.f - amoins * huemoins; - const float apluscurv = (1.f - chprov) / delhu; - const float bpluscurv = 1.f - apluscurv * hueplus; - const float amoinscurv = (chprov - 1.f) / delhu; - const float bmoinscurv = 1.f - amoinscurv * huemoins; - - const float apl = (-1.f) / delhu; const float bpl = - apl * hueplus; const float amo = 1.f / delhu; @@ -3113,14 +2956,38 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag eps = 0.01f; } + //retriev data curve lightness + float cli = (buflight[loy - begy - 1][lox - begx - 1]); + //parameters for linear interpolation in function of real hue + float apluscligh = (1.f - cli) / delhu; + float bpluscligh = 1.f - apluscligh * hueplus; + float amoinscligh = (cli - 1.f) / delhu; + float bmoinscligh = 1.f - amoinscligh * huemoins; + + float cchro = (bufchro[loy - begy - 1][lox - begx - 1]); + float apluscurv = (1.f - cchro) / delhu; + float bpluscurv = 1.f - apluscurv * hueplus; + float amoinscurv = (cchro - 1.f) / delhu; + float bmoinscurv = 1.f - amoinscurv * huemoins; + + float clisl = (buflightslid[loy - begy - 1][lox - begx - 1]); + //parameters for linear interpolation in function of real hue + float aplusclighsl = (1.f - clisl) / delhu; + float bplusclighsl = 1.f - aplusclighsl * hueplus; + float amoinsclighsl = (clisl - 1.f) / delhu; + float bmoinsclighsl = 1.f - amoinsclighsl * huemoins; float kab = (original->a[y][x] / (original->b[y][x] + eps)); //prepare shape detection -// printf("z"); - //end buf for square + // real... = coefficient to apply at lightness, chroma,... float realchro = 1.f; float realcurv = 1.f; + float realcligh = 1.f; + float realclighsl = 1.f; + float realchrosl = 1.f; + + //evaluate delta Hue and delta Chro float deltachro = fabs (rchro - chromaref); float deltahue = fabs (rhue - hueref); @@ -3129,6 +2996,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag deltahue = - (deltahue - 2.f * M_PI); } + //pseudo deltaE float deltaE = 20.f * deltahue + deltachro; //pseudo deltaE between 0 and 280 float deltaL = fabs (lumaref - rL); //between 0 and 100 @@ -3155,22 +3023,29 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag //transition = difficult to avoid artifact with scope on flat area (sky...) //hue detection + //for each quart calculate realchro, realcligh,... in function of Hue pixel if ((hueref + dhue) < M_PI && rhue < hueplus && rhue > huemoins) { //transition are good if (rhue >= hueplus - delhu) { realchro = aplus * rhue + bplus; realcurv = apluscurv * rhue + bpluscurv; - + realcligh = apluscligh * rhue + bpluscligh; + realclighsl = aplusclighsl * rhue + bplusclighsl; khu = apl * rhue + bpl; } else if (rhue < huemoins + delhu) { realchro = amoins * rhue + bmoins; realcurv = amoinscurv * rhue + bmoinscurv; + realcligh = amoinscligh * rhue + bmoinscligh; + realclighsl = amoinsclighsl * rhue + bmoinsclighsl; khu = amo * rhue + bmo; } else { realchro = lp.chro; - realcurv = chprov; + realcurv = cchro; + realcligh = cli; + realclighsl = clisl; + khu = 1.f; } @@ -3180,18 +3055,25 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag if (rhue >= hueplus - delhu && rhue < hueplus) { realchro = aplus * rhue + bplus; realcurv = apluscurv * rhue + bpluscurv; + realcligh = apluscligh * rhue + bpluscligh; + realclighsl = aplusclighsl * rhue + bplusclighsl; khu = apl * rhue + bpl; } else if (rhue >= huemoins && rhue < huemoins + delhu) { realchro = amoins * rhue + bmoins; realcurv = amoinscurv * rhue + bmoinscurv; + realcligh = amoinscligh * rhue + bmoinscligh; + realclighsl = amoinsclighsl * rhue + bmoinsclighsl; khu = amo * rhue + bmo; } else { realchro = lp.chro; - realcurv = chprov; + + realcurv = cchro; + realcligh = cli; + realclighsl = clisl; khu = 1.f; @@ -3204,17 +3086,25 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag if (rhue >= hueplus - delhu && rhue < hueplus) { realchro = aplus * rhue + bplus; realcurv = apluscurv * rhue + bpluscurv; + realcligh = apluscligh * rhue + bpluscligh; + realclighsl = aplusclighsl * rhue + bplusclighsl; khu = apl * rhue + bpl; } else if (rhue >= huemoins && rhue < huemoins + delhu) { realchro = amoins * rhue + bmoins; realcurv = amoinscurv * rhue + bmoinscurv; + realcligh = amoinscligh * rhue + bmoinscligh; + realclighsl = amoinsclighsl * rhue + bmoinsclighsl; + khu = amo * rhue + bmo; } else { realchro = lp.chro; - realcurv = chprov; + + realcurv = cchro; + realcligh = cli; + realclighsl = clisl; khu = 1.f; @@ -3225,18 +3115,25 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag if (rhue >= hueplus - delhu && rhue < hueplus) { realchro = aplus * rhue + bplus; realcurv = apluscurv * rhue + bpluscurv; + realcligh = apluscligh * rhue + bpluscligh; + realclighsl = aplusclighsl * rhue + bplusclighsl; khu = apl * rhue + bpl; } else if (rhue >= huemoins && rhue < huemoins + delhu) { realchro = amoins * rhue + bmoins; realcurv = amoinscurv * rhue + bmoinscurv; + realcligh = amoinscligh * rhue + bmoinscligh; + realclighsl = amoinsclighsl * rhue + bmoinsclighsl; khu = amo * rhue + bmo; } else { realchro = lp.chro; - realcurv = chprov; + + realcurv = cchro; + realcligh = cli; + realclighsl = clisl; khu = 1.f; @@ -3264,7 +3161,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag //fach = 1.f;//to avoid artifacts in some cases //can be probably improved if (lp.qualmet >= 1) { - if (deltE[y][x] > lp.thr) { + if (deltE[y][x] > 10.f * lp.thr) { fach = 1.f; } } else { @@ -3287,15 +3184,18 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag if ( (rhue > -2.79f && rhue < -1.11f) && (rchro < 35.f * multchro)) { realchro *= 0.9f; realcurv *= 0.9f; + // realcligh *= 0.9f; } else { realchro = 1.f; realcurv = 1.f; + // realcligh = 1.f; } } } else { realchro = lp.chro; - realcurv = chprov; + realcurv = cchro; + // realcligh = cligh; } @@ -3305,16 +3205,19 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag if ( (rhue > -0.09f && rhue < 1.59f) && (rchro < 55.f * multchroskin)) { realchro *= 0.9f; realcurv *= 0.9f; + // realcligh *= 0.9f; } else { realchro = 1.f; realcurv = 1.f; + // realcligh = 1.f; } } } else { realchro = lp.chro; - realcurv = chprov; + realcurv = cchro; + // realcligh = cligh; } } @@ -3373,6 +3276,14 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag } + float kcr = 100.f * lp.thr; + float falL = 1.f; + + if (rchro < kcr && chromaref > kcr) { // reduce artifacts in grey tones near hue spot and improve algorithm + falL *= pow (rchro / kcr, lp.iterat / 10.f); + } + + int zone; float localFactor; calcTransition (lox, loy, ach, lp, zone, localFactor); @@ -3393,11 +3304,12 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag float lightcont; - if (lp.curvact) { + if (lp.qualcurvemet == 1) { + if (lllocalcurve) { float lumprov = lllocalcurve[lumnew * 1.9f]; - float lumred = 0.526316f * lumprov; - lumnew = lumnew + (lumred - lumnew) / 1.5f;//reduce sensibility + float lumred = 0.526316f * lumprov; //0.526316f + lumnew = lumnew + (lumred - lumnew) / 4.f;//reduce sensibility } @@ -3425,7 +3337,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag } - if (lp.ligh != 0.f) { + if (lp.ligh != 0.f && lp.curvact == false) { // calclight (bufcolorig->L[loy - begy - 1][lox - begx - 1], lp.ligh , lumnew, true);//replace L-curve calclight (lumnew, lp.ligh , lumnew, true);//replace L-curve lightcont = lumnew; @@ -3435,15 +3347,31 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag } float factorx = localFactor; + float fli = 1.f; + float flisl = 1.f; - float fac = ((100.f + realcurv * factorx * falu) / 100.f) * (100.f + factorx * realchro * falu) / 100.f; //chroma factor transition - float diflc = lightcont - original->L[y][x]; + if (lp.curvact && lp.ligh != 0.f) { + flisl = ((100.f + realclighsl * falL ) / 100.f);//luma transition + } + + if (lp.qualcurvemet == 2) { + fli = ((100.f + realcligh * falL ) / 100.f);//luma transition + } + + float flicur = 1.f; + + if (lp.qualcurvemet != 0) { + flicur = ((100.f + realcurv * factorx * falu * falL) / 100.f); + } + + float fac = flicur * (100.f + factorx * realchro * falu * falL) / 100.f; //chroma factor transition + float diflc = lightcont * fli * flisl - original->L[y][x]; kdiff *= fach * kch; diflc *= kdiff ; - diflc *= factorx; //transition lightess + diflc *= factorx; //transition lightness // transformed->L[y][x] = CLIPL(bufcolorig->L[loy - begy - 1][lox - begx - 1] + diflc); - transformed->L[y][x] = CLIPL (original->L[y][x] + diflc); + transformed->L[y][x] = CLIPL (1.f * (original->L[y][x] + diflc)); if (fabs (kab) > 1.f) { @@ -3462,11 +3390,12 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag float lumnew = bufcolorig->L[loy - begy - 1][lox - begx - 1]; float lightcont; - if (lp.curvact) { + if (lp.qualcurvemet == 1) { + if (lllocalcurve) { float lumprov = lllocalcurve[lumnew * 1.9f]; - float lumred = 0.526316f * lumprov; - lumnew = lumnew + (lumred - lumnew) / 1.5f;//reduce sensibility + float lumred = 0.526316 * lumprov; // 0.526316f + lumnew = lumnew + (lumred - lumnew) / 4.f;//reduce sensibility } if (loclhCurve) { @@ -3494,7 +3423,7 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag } - if (lp.ligh != 0.f) { + if (lp.ligh != 0.f && lp.curvact == false) { calclight (lumnew, lp.ligh , lumnew, true);//replace L-curve lightcont = lumnew; @@ -3502,13 +3431,30 @@ void ImProcFunctions::ColorLight_Local (int call, LabImage * bufcolorig, LabImag lightcont = lumnew; } - float fac = ((100.f + realcurv * falu) / 100.f) * (100.f + realchro * falu) / 100.f; //chroma factor transition7 + float fli = 1.f; + float flisl = 1.f; - float diflc = lightcont - original->L[y][x]; + if (lp.curvact && lp.ligh != 0.f) { + flisl = ((100.f + realclighsl * falL ) / 100.f);//luma transition + } + + if (lp.qualcurvemet == 2) { + fli = ((100.f + realcligh * falL) / 100.f);//luma transition + } + + float flicur = 1.f; + + if (lp.qualcurvemet != 0) { + flicur = ((100.f + realcurv * falu * falL) / 100.f); + } + + float fac = flicur * (100.f + realchro * falu * falL) / 100.f; //chroma factor transition7 + + float diflc = lightcont * fli * flisl - original->L[y][x]; kdiff *= fach * kch; diflc *= kdiff ; - transformed->L[y][x] = CLIPL (original->L[y][x] + diflc); + transformed->L[y][x] = CLIPL (1.f * (original->L[y][x] + diflc)); if (fabs (kab) > 1.f) { transformed->a[y][x] = CLIPC (original->a[y][x] * fac) ; @@ -3669,7 +3615,109 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage * noiscfactiv = false; } + /* //keep in case of ! + if(lp.qualmet >= 1) { + float maxdh = -10.f; + #ifdef _OPENMP + // #pragma omp parallel ?? + #endif + { + float maxdhu = -10.f; + #ifdef _OPENMP + // #pragma omp for nowait ?? + #endif + + for (int y = lp.dyy; y < transformed->H - lp.dyy; y++) //{ + for (int x = lp.dxx; x < transformed->W - lp.dxx; x++) { + int lox = cx + x; + int loy = cy + y; + + if(lox >= (lp.xc - (lp.lxL - lp.dxx)) && lox < (lp.xc + (lp.lx - lp.dxx)) && loy >= (lp.yc - (lp.lyT - lp.dyy)) && loy < (lp.yc + (lp.ly - lp.dyy))) { + float eps = 0.01f; + + float hur = xatan2f(original->b[y][x], original->a[y][x]); + float maxdhur = -10.f; + + for(int j = x - lp.dxx; j < x + lp.dxx; j++) { + for(int k = y - lp.dyy; k < y + lp.dyy; k++) { + + float hurjk = xatan2f(original->b[k][j], original->a[k][j]); + float dE = fabs(hur - hurjk); + + //evaluate local variation of hue + if(dE > M_PI) { + dE = -(dE - 2.f * M_PI); + } + + maxdhur = dE > maxdhur ? dE : maxdhur; + } + } + + + deltE[y][x] = maxdhur; + + } + } + + #ifdef _OPENMP + // #pragma omp critical + #endif + { + //?? + } + + } + + float maxw = -10.f; + float minw = 10.f; + int n1 = 0; + int n2 = 0; + int n3 = 0; + int n4 = 0; + int n5 = 0; + int n6 = 0; + int n7 = 0; + int n8 = 0; + int n9 = 0; + int n10 = 0; + + for (int y = lp.dyy; y < transformed->H - lp.dyy; y++) //{ + for (int x = lp.dxx; x < transformed->W - lp.dxx; x++) { + int lox = cx + x; + int loy = cy + y; + + if(lox >= (lp.xc - (lp.lxL - lp.dxx)) && lox < (lp.xc + (lp.lx - lp.dxx)) && loy >= (lp.yc - (lp.lyT - lp.dyy)) && loy < (lp.yc + (lp.ly - lp.dyy))) { + if(deltE[y][x] < 0.3f) { + n1++; + } else if(deltE[y][x] < 0.6f) { + n2++; + } else if(deltE[y][x] < 1.f) { + n3++; + } else if(deltE[y][x] < 1.3f) { + n4++; + } else if(deltE[y][x] < 1.6f) { + n5++; + } else if(deltE[y][x] < 2.f) { + n6++; + } else if(deltE[y][x] < 2.4f) { + n7++; + } else if(deltE[y][x] < 2.7f) { + n8++; + } else if(deltE[y][x] < 2.95f) { + n9++; + } else if(deltE[y][x] < 3.16f) { + n10++; + } + } + } + + printf("n1=%i n2=%i n3=%i n4=%i n5=%i n6=%i n7=%i n8=%i n9=%i n10=%i\n", n1, n2, n3, n4, n5, n6, n7, n8, n9, n10); + + + + } + */ if ((!lp.inv || !lp.invret) && hueref == INFINITY && chromaref == INFINITY && lumaref == INFINITY) { @@ -3728,6 +3776,7 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage * avB = aveB / 327.68f; avL = aveL / 327.68f; +//INFINITY to solve crop problem when Ref is outside preview if (hueref == INFINITY) { hueref = xatan2f (avB, avA); //mean hue } @@ -3765,7 +3814,7 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage * lco.dy = 1.f - 1.f / multh; - +//Blur and noise if ((radius >= GAUSS_SKIP || lp.stren > 0.1) && lp.blurena) { // radius < GAUSS_SKIP means no gauss, just copy of original image LabImage *tmp1; LabImage *bufgb; @@ -3875,7 +3924,7 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage * levred = 7; } - if (call == 1) { + if (call != 2) { LabImage *tmp1 = new LabImage (transformed->W, transformed->H); int GW = transformed->W; int GH = transformed->H; @@ -4219,13 +4268,14 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage * } - - if (!lp.inv && (lp.chro != 0 || lp.ligh != 0.f || lp.curvact) && lp.colorena) { // || lllocalcurve)) { //interior ellipse renforced lightness and chroma //locallutili +//local color and light + if (!lp.inv && (lp.chro != 0 || lp.ligh != 0.f || lp.qualcurvemet != 0) && lp.colorena) { // || lllocalcurve)) { //interior ellipse renforced lightness and chroma //locallutili float maxhur = -10.f; float minhur = 10.f; float hueplus = hueref + dhue; float huemoins = hueref - dhue; + //printf("hueplus=%f huemoins=%f dhu=%f\n", hueplus, huemoins, dhue); if (hueplus > M_PI) { hueplus = hueref + dhue - 2.f * M_PI; } @@ -4236,11 +4286,24 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage * LabImage *bufcolorig; float chprov = 1.f; + float chpro = 1.f; + float chp = 1.f; + float cligh = 1.f; + float clighL = 1.f; + float clighmax ; + float clighmin ; LabImage *bufcoltra; + float **buflight; + float **bufchro; + float **buflightslid; + + int bfh, bfw; + float adjustr = 1.0f; + float compadjustr = 1.0f; - +//adapt chroma to working profile if (params->icm.working == "ProPhoto") { adjustr = 1.2f; // 1.2 instead 1.0 because it's very rare to have C>170.. } else if (params->icm.working == "Adobe RGB") { @@ -4260,13 +4323,32 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage * - if (call <= 3) { //simpleprocess + if (call <= 3) { //simpleprocess, dcrop, improccoordinator int GW = transformed->W; int GH = transformed->H; - int bfh = int (lp.ly + lp.lyT) + 1; //bfw bfh real size of square zone - int bfw = int (lp.lx + lp.lxL) + 1; - bufcolorig = new LabImage (bfw, bfh); - // bufcoltra = new LabImage(bfw, bfh); + bfh = int (lp.ly + lp.lyT) + 1; //bfw bfh real size of square zone + bfw = int (lp.lx + lp.lxL) + 1; + bufcolorig = new LabImage (bfw, bfh);//buffer for data in zone limit + // bufcoltra = new LabImage (bfw, bfh);//not used + + buflight = new float*[bfh];//for lightness curve + + for (int i = 0; i < bfh; i++) { + buflight[i] = new float[bfw]; + } + + bufchro = new float*[bfh];//for chroma curve + + for (int i = 0; i < bfh; i++) { + bufchro[i] = new float[bfw]; + } + + buflightslid = new float*[bfh];//for chroma curve + + for (int i = 0; i < bfh; i++) { + buflightslid[i] = new float[bfw]; + } + #ifdef _OPENMP #pragma omp parallel for @@ -4283,6 +4365,8 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage * #ifdef _OPENMP // #pragma omp parallel for #endif + clighmax = 0.f; + clighmin = 100000.f; for (int y = 0; y < transformed->H ; y++) //{ for (int x = 0; x < transformed->W; x++) { @@ -4297,47 +4381,98 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage * bufcolorig->b[loy - begy - 1][lox - begx - 1] = original->b[y][x];//fill square buffer with datas chprov = 0.f; + chpro = 0.f; - if (cclocalcurve && lp.curvact) { + //Chroma curve + if (cclocalcurve && lp.qualcurvemet != 0) { // C=f(C) curve float chromat = sqrt (SQR (bufcolorig->a[loy - begy - 1][lox - begx - 1]) + SQR (bufcolorig->b[loy - begy - 1][lox - begx - 1])); float ch; - float ampli = 12.f; - ch = (cclocalcurve[chromat * adjustr]) / ((chromat + 0.00001f) * adjustr); //ch between 0 and 0 50 or more + float ampli = 25.f; + ch = (cclocalcurve[chromat * adjustr ]) / ((chromat + 0.00001f) * adjustr); //ch between 0 and 0 50 or more if (ch <= 1.f) {//convert data curve near values of slider -100 + 100, to be used after to detection shape - chprov = 100.f * ch - 100.f; + chpro = 100.f * ch - 100.f; } else { - chprov = ampli * ch - ampli;//ampli = 12.f arbitrary empirical coefficient between 5 and 50 + chpro = CLIPCHRO (ampli * ch - ampli); //ampli = 25.f arbitrary empirical coefficient between 5 and 50 } + + bufchro[loy - begy - 1][lox - begx - 1] = chpro; + } + //slider lightness + clighL = 0.f; + + if (lp.ligh != 0.f && lp.curvact) { + float lL; + float lighLnew; + float amplil = 140.f; + float lighL = bufcolorig->L[loy - begy - 1][lox - begx - 1]; + calclight (lighL, lp.ligh , lighLnew, true);//replace L-curve + lL = lighLnew / lighL; + + if (lL <= 1.f) {//convert data curve near values of slider -100 + 100, to be used after to detection shape + clighL = 100.f * lL - 100.f; + } else { + clighL = CLIPLIG (amplil * lL - amplil); //ampli = 25.f arbitrary empirical coefficient between 5 and 150 + } + + buflightslid[loy - begy - 1][lox - begx - 1] = clighL; + + } + + cligh = 0.f; + + //luma curve + if (lllocalcurve && lp.qualcurvemet == 2) {// L=f(L) curve enhanced + float lh; + float amplil = 25.f; + float lighn = bufcolorig->L[loy - begy - 1][lox - begx - 1]; + lh = (lllocalcurve[lighn * 1.9f]) / ((lighn + 0.00001f) * 1.9f) ; // / ((lighn) / 1.9f) / 3.61f; //lh between 0 and 0 50 or more + + if (lh <= 1.f) {//convert data curve near values of slider -100 + 100, to be used after to detection shape + cligh = 0.3f * (100.f * lh - 100.f);//0.3 reduce sensibility + } else { + cligh = CLIPLIG (amplil * lh - amplil); + } + + buflight[loy - begy - 1][lox - begx - 1] = cligh; + + } + } } - } - /* - if(locallutili) printf("Courbe oui\n"); - if(!locallutili) printf("Courbe NON\n"); - */ - /* - if (cclocalcurve) { - printf ("Courbe RE OUI\n"); - } - if (!cclocalcurve) { - printf ("CouRE NON\n"); - } - */ - - ColorLight_Local (call, bufcolorig, bufcoltra, sp, moy, hueplus, huemoins, hueref, dhue, chromaref, lumaref, locallutili, lllocalcurve, loclhCurve, cclocalcurve, chprov, lp, deltE, original, transformed, cx, cy); + ColorLight_Local (call, bufcolorig, bufcoltra, buflight, bufchro, buflightslid, sp, moy, hueplus, huemoins, hueref, dhue, chromaref, lumaref, locallutili, lllocalcurve, loclhCurve, cclocalcurve, chprov, clighmax, lp, deltE, original, transformed, cx, cy); if (call <= 3) { delete bufcolorig; - // delete bufcoltra; + + // delete bufcoltra; + + for (int i = 0; i < bfh; i++) { + delete [] buflight[i]; + } + + delete [] buflight; + + for (int i = 0; i < bfh; i++) { + delete [] bufchro[i]; + } + + delete [] bufchro; + + for (int i = 0; i < bfh; i++) { + delete [] buflightslid[i]; + } + + + delete [] buflightslid; } } //inverse @@ -4360,7 +4495,147 @@ void ImProcFunctions::Lab_Local (int call, int sp, float** shbuffer, LabImage * huemoins = hueref - dhue + 2.f * M_PI; } - Contrast_Local (call, moy, hueplus, huemoins, hueref, dhue, chromaref, pm, lco, lumaref, av, lp, deltE, original, transformed, cx, cy); + LabImage *bufcontorig; + float **buflightc; + int bfh, bfw; + float clighc = 1.f; + const float localtype = lumaref; + float reducac; + + if (lp.sens < 30.f) { + reducac = 0.2f * (lp.sens / 100.f); + } else { + float areduc = 0.6285714f; //0.44f/0.7f; + float breduc = 0.5f - areduc; + reducac = areduc * (lp.sens / 100.f) + breduc; + } + + const float realcox = lco.dx, realcoy = lco.dy; + + lco.alsup = (-realcox) / (localtype / 2.f); + lco.blsup = -lco.alsup * localtype; + lco.alsup2 = (realcoy) / (50.f - localtype / 2.f); + lco.blsup2 = -lco.alsup2 * localtype; + lco.alsup3 = (realcoy) / (localtype / 2.f - 50.f); + lco.blsup3 = -lco.alsup3 * 100.f; + lco.aDY = realcoy; + + lco.alinf = realcox / (localtype / 2.f); + const float vi = (localtype / 2.f) / 100.f; + const float vinf = (50.f + localtype / 2.f) / 100.f; + ImProcFunctions::secondeg_begin (reducac, vi, lco.aa, lco.bb);//parabolic + ImProcFunctions::secondeg_end (reducac, vinf, lco.aaa, lco.bbb, lco.ccc);//parabolic + + + + + if (call <= 3) { //simpleprocess, dcrop, improccoordinator + int GW = transformed->W; + int GH = transformed->H; + bfh = int (lp.ly + lp.lyT) + 1; //bfw bfh real size of square zone + bfw = int (lp.lx + lp.lxL) + 1; + bufcontorig = new LabImage (bfw, bfh);//buffer for data in zone limit + + buflightc = new float*[bfh];//for lightness curve + + for (int i = 0; i < bfh; i++) { + buflightc[i] = new float[bfw]; + } + + + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int ir = 0; ir < bfh; ir++) //fill with 0 + for (int jr = 0; jr < bfw; jr++) { + bufcontorig->L[ir][jr] = 0.f; + bufcontorig->a[ir][jr] = 0.f; + bufcontorig->b[ir][jr] = 0.f; + + } + +#ifdef _OPENMP +// #pragma omp parallel for +#endif + float maxc = -10000.f; + float minc = +10000.f; + float core = 0.f; + + for (int y = 0; y < transformed->H ; y++) //{ + for (int x = 0; x < transformed->W; x++) { + int lox = cx + x; + int loy = cy + y; + int begx = int (lp.xc - lp.lxL); + int begy = int (lp.yc - lp.lyT); + + if (lox >= (lp.xc - lp.lxL) && lox < (lp.xc + lp.lx) && loy >= (lp.yc - lp.lyT) && loy < (lp.yc + lp.ly)) { + bufcontorig->L[loy - begy - 1][lox - begx - 1] = original->L[y][x];//fill square buffer with datas + + //slider contrast + clighc = 0.f; + + if (lp.cont != 0.f && lp.curvact) { + float cL; + float amplil = 10.f; + float prov100 = bufcontorig->L[loy - begy - 1][lox - begx - 1] / 32768.f; + float prov = prov100 * 100.f; + + if (prov > localtype) { + if (prov >= localtype && prov < 50.f + localtype / 2.f) { + core = (lco.alsup2 * prov + lco.blsup2) ; + + } else { + core = lco.aDY * (lco.aaa * prov100 * prov100 + lco.bbb * prov100 + lco.ccc); + + } + } else { + if (2.f * prov > localtype && prov < localtype) { + core = (lco.alsup * prov + lco.blsup) ; + } else if (2.f * prov <= localtype) { + core = prov * lco.alinf * (lco.aa * prov100 * prov100 + lco.bb * prov100); + } + } + + // cL = pm * core; + cL = pm * core; + core = 0.f; + + if (cL > 0.f) { + clighc = 100.f * cL; + + } else { + clighc = 100.f * cL ; + + } + + buflightc[loy - begy - 1][lox - begx - 1] = clighc; + + } + + + } + } + + } + + + Contrast_Local (call, bufcontorig, buflightc, moy, hueplus, huemoins, hueref, dhue, chromaref, pm, lco, lumaref, av, lp, deltE, original, transformed, cx, cy); + + if (call <= 3) { + + delete bufcontorig; + + + for (int i = 0; i < bfh; i++) { + delete [] buflightc[i]; + } + + delete [] buflightc; + } + + } else if (lp.inv && lp.cont != 0 && lp.colorena) { float multL = (float)lp.cont * (maxl - 1.f) / 100.f + 1.f; diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 099148f5a..2b64900d6 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -536,6 +536,7 @@ enum ProcEvent { EvlocallabLHshape = 506, Evlocallabcurvactiv = 507, Evlocallabccshape = 508, + EvlocallabqualitycurveMethod = 509, NUMOFEVENTS diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 2a26991b9..af5922c9f 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -887,8 +887,9 @@ void LocallabParams::setDefaults() centerY = 0; circrad = 18; qualityMethod = "std"; - proxi = 1; - thres = 60; + qualitycurveMethod = "none"; + proxi = 20; + thres = 18; lightness = 0; contrast = 0; chroma = 0; @@ -2753,6 +2754,10 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b keyFile.set_string ("Locallab", "qualityMethod", locallab.qualityMethod); } + if (!pedited || pedited->locallab.qualitycurveMethod) { + keyFile.set_string ("Locallab", "qualitycurveMethod", locallab.qualitycurveMethod); + } + if (!pedited || pedited->locallab.locY) { keyFile.set_integer ("Locallab", "LocY", locallab.locY); } @@ -4351,6 +4356,14 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) } } + if (keyFile.has_key ("Locallab", "qualitycurveMethod")) { + locallab.qualitycurveMethod = keyFile.get_string ("Locallab", "qualitycurveMethod"); + + if (pedited) { + pedited->locallab.qualitycurveMethod = true; + } + } + if (keyFile.has_key ("Locallab", "LocY")) { locallab.locY = keyFile.get_integer ("Locallab", "LocY"); @@ -8845,6 +8858,7 @@ bool ProcParams::operator== (const ProcParams& other) && locallab.Smethod == other.locallab.Smethod && locallab.retinexMethod == other.locallab.retinexMethod && locallab.qualityMethod == other.locallab.qualityMethod + && locallab.qualitycurveMethod == other.locallab.qualitycurveMethod && locallab.locY == other.locallab.locY && locallab.locX == other.locallab.locX && locallab.locYT == other.locallab.locYT diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 47f8b03b7..4e56e0ecb 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -877,6 +877,7 @@ public: int thres; int proxi; Glib::ustring qualityMethod; + Glib::ustring qualitycurveMethod; bool expcolor; bool expblur; bool exptonemap; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 4b267c001..4163a1f6e 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -535,7 +535,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, //Evlocenadenoi LUMINANCECURVE, //EvlocallabLHshape LUMINANCECURVE, //Evlocallabcurvactiv - LUMINANCECURVE //Evlocallabccshape + LUMINANCECURVE, //Evlocallabccshape + LUMINANCECURVE //EvlocallabqualitycurveMethod diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index ea755b3c2..0e61c8086 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1018,9 +1018,9 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p std::string inser; int **dataspots; - dataspots = new int*[60]; + dataspots = new int*[61]; - for (int i = 0; i < 60; i++) { + for (int i = 0; i < 61; i++) { dataspots[i] = new int[maxspot]; } @@ -1154,9 +1154,17 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p dataspots[56][0] = 1; } - dataspots[57][0] = 100.f * params.locallab.hueref; - dataspots[58][0] = params.locallab.chromaref; - dataspots[59][0] = params.locallab.lumaref; + if (params.locallab.qualitycurveMethod == "none") { + dataspots[57][0] = 0; + } else if (params.locallab.qualitycurveMethod == "std") { + dataspots[57][0] = 1; + } else if (params.locallab.qualitycurveMethod == "enh") { + dataspots[57][0] = 2; + } + + dataspots[58][0] = 100.f * params.locallab.hueref; + dataspots[59][0] = params.locallab.chromaref; + dataspots[60][0] = params.locallab.lumaref; //curve Reti local int siz = params.locallab.localTgaincurve.size(); @@ -1294,7 +1302,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p dataspots[16][0] = std::stoi (str3.c_str()); } - if (cont > 16 && cont < 60) { + if (cont > 16 && cont < 61) { dataspots[cont][ns] = std::stoi (str3.c_str()); } @@ -1498,9 +1506,17 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p params.locallab.curvactiv = true; } - params.locallab.hueref = ((float) dataspots[57][sp]) / 100.f; - params.locallab.chromaref = dataspots[58][sp]; - params.locallab.lumaref = dataspots[59][sp]; + if (dataspots[57][sp] == 0) { + params.locallab.qualitycurveMethod = "none" ; + } else if (dataspots[57][sp] == 1) { + params.locallab.qualitycurveMethod = "std" ; + } else if (dataspots[57][sp] == 2) { + params.locallab.qualitycurveMethod = "enh" ; + } + + params.locallab.hueref = ((float) dataspots[58][sp]) / 100.f; + params.locallab.chromaref = dataspots[59][sp]; + params.locallab.lumaref = dataspots[60][sp]; int *s_datc; @@ -1587,7 +1603,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p - for (int i = 0; i < 60; i++) { + for (int i = 0; i < 61; i++) { delete [] dataspots[i]; } diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 5ca28a072..61139b666 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -62,8 +62,8 @@ Locallab::Locallab (): centerX (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_CENTER_X"), -1000, 1000, 1, 0))), centerY (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_CENTER_Y"), -1000, 1000, 1, 0))), circrad (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_CIRCRADIUS"), 4, 100, 1, 18))), - thres (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_THRES"), 1, 315, 1, 60))), - proxi (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_PROXI"), 1, 8, 1, 1))), + thres (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_THRES"), 1, 35, 1, 18))), + proxi (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_PROXI"), 0, 60, 1, 20))), lightness (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_LIGHTNESS"), -100, 100, 1, 0))), contrast (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_CONTRAST"), -100, 100, 1, 0))), chroma (Gtk::manage (new Adjuster (M ("TP_LOCALLAB_CHROMA"), -100, 150, 1, 0))), @@ -99,10 +99,33 @@ Locallab::Locallab (): Smethod (Gtk::manage (new MyComboBoxText ())), qualityMethod (Gtk::manage (new MyComboBoxText ())), retinexMethod (Gtk::manage (new MyComboBoxText ())), + qualitycurveMethod (Gtk::manage (new MyComboBoxText ())), + + shapeFrame (Gtk::manage (new Gtk::Frame (M ("TP_LOCALLAB_SHFR")))), + artifFrame (Gtk::manage (new Gtk::Frame (M ("TP_LOCALLAB_ARTIF")))), + superFrame (Gtk::manage (new Gtk::Frame ())), + + artifVBox (Gtk::manage (new Gtk::VBox ())), + shapeVBox (Gtk::manage (new Gtk::VBox ())), + tmBox (Gtk::manage (new Gtk::VBox())), + retiBox (Gtk::manage (new Gtk::VBox())), + colorVBox (Gtk::manage ( new Gtk::VBox())), + blurrVBox (Gtk::manage ( new Gtk::VBox())), + sharpVBox (Gtk::manage ( new Gtk::VBox())), + cbdlVBox (Gtk::manage ( new Gtk::VBox())), + denoisVBox (Gtk::manage ( new Gtk::VBox())), + superVBox (Gtk::manage (new Gtk::VBox ())), + labmdh (Gtk::manage (new Gtk::Label (M ("TP_LOCRETI_METHOD") + ":"))), + labqual (Gtk::manage (new Gtk::Label (M ("TP_LOCALLAB_QUAL_METHOD") + ":"))), + labqualcurv (Gtk::manage (new Gtk::Label (M ("TP_LOCALLAB_QUALCURV_METHOD") + ":"))), + labmS (Gtk::manage (new Gtk::Label (M ("TP_LOCALLAB_STYPE") + ":"))), + ctboxS (Gtk::manage (new Gtk::HBox ())), dhbox (Gtk::manage (new Gtk::HBox ())), + qualbox (Gtk::manage (new Gtk::HBox ())), + qualcurvbox (Gtk::manage (new Gtk::HBox ())), avoid (Gtk::manage (new Gtk::CheckButton (M ("TP_LOCALLAB_AVOID")))), activlum (Gtk::manage (new Gtk::CheckButton (M ("TP_LOCALLAB_ACTIV")))), @@ -145,8 +168,6 @@ Locallab::Locallab (): anbspot->setAdjusterListener (this); anbspot->set_tooltip_text (M ("TP_LOCALLAB_ANBSPOT_TOOLTIP")); - - Gtk::Frame* shapeFrame = Gtk::manage (new Gtk::Frame (M ("TP_LOCALLAB_SHFR")) ); shapeFrame->set_border_width (0); shapeFrame->set_label_align (0.025, 0.5); @@ -171,11 +192,9 @@ Locallab::Locallab (): expdenoi->signal_button_release_event().connect_notify ( sigc::bind ( sigc::mem_fun (this, &Locallab::foldAllButMe), expdenoi) ); enabledenoiConn = expdenoi->signal_enabled_toggled().connect ( sigc::bind ( sigc::mem_fun (this, &Locallab::enableToggled), expdenoi) ); - Gtk::VBox *shapeVBox = Gtk::manage ( new Gtk::VBox()); shapeVBox->set_spacing (2); shapeVBox->set_border_width (4); - Gtk::Label* labmS = Gtk::manage (new Gtk::Label (M ("TP_LOCALLAB_STYPE") + ":")); ctboxS->pack_start (*labmS, Gtk::PACK_SHRINK, 4); ctboxS->set_tooltip_markup (M ("TP_LOCALLAB_STYPE_TOOLTIP")); @@ -229,6 +248,15 @@ Locallab::Locallab (): irg = Gtk::manage (new RTImage ("Chanmixer-RG.png")); + qualitycurveMethod->append (M ("TP_LOCALLAB_CURVNONE")); + qualitycurveMethod->append (M ("TP_LOCALLAB_CURVCURR")); + qualitycurveMethod->append (M ("TP_LOCALLAB_CURVENH")); + qualitycurveMethod->set_active (0); + qualitycurveMethodConn = qualitycurveMethod->signal_changed().connect ( sigc::mem_fun (*this, &Locallab::qualitycurveMethodChanged) ); + qualitycurveMethod->set_tooltip_markup (M ("TP_LOCALLAB_CURVEMETHOD_TOOLTIP")); + + + llCurveEditorG->setCurveListener (this); rtengine::LocallabParams::getDefaultLLCurve (defaultCurve); @@ -313,7 +341,6 @@ Locallab::Locallab (): inversretConn = inversret->signal_toggled().connect ( sigc::mem_fun (*this, &Locallab::inversretChanged) ); //tone mapping local - Gtk::VBox * tmBox = Gtk::manage (new Gtk::VBox()); tmBox->set_border_width (4); tmBox->set_spacing (2); @@ -334,7 +361,6 @@ Locallab::Locallab (): //retinex local - Gtk::VBox * retiBox = Gtk::manage (new Gtk::VBox()); retiBox->set_border_width (4); retiBox->set_spacing (2); @@ -403,26 +429,24 @@ Locallab::Locallab (): shapeVBox->pack_start (*centerY); shapeVBox->pack_start (*circrad); //shapeVBox->pack_start (*activlum); - shapeVBox->pack_start (*qualityMethod); - // shapeVBox->pack_start (*thres); - // shapeVBox->pack_start (*proxi); + qualbox->pack_start (*labqual, Gtk::PACK_SHRINK, 4); + qualbox->pack_start (*qualityMethod); + shapeVBox->pack_start (*qualbox); +// shapeVBox->pack_start (*thres); +// shapeVBox->pack_start (*proxi); shapeFrame->add (*shapeVBox); pack_start (*shapeFrame); - Gtk::VBox *colorVBox = Gtk::manage ( new Gtk::VBox()); colorVBox->set_spacing (2); colorVBox->set_border_width (4); - Gtk::VBox *blurrVBox = Gtk::manage ( new Gtk::VBox()); blurrVBox->set_spacing (2); blurrVBox->set_border_width (4); - Gtk::VBox *sharpVBox = Gtk::manage ( new Gtk::VBox()); sharpVBox->set_spacing (2); sharpVBox->set_border_width (4); - Gtk::VBox *cbdlVBox = Gtk::manage ( new Gtk::VBox()); cbdlVBox->set_spacing (2); cbdlVBox->set_border_width (4); @@ -490,7 +514,6 @@ Locallab::Locallab (): sharpVBox->pack_start (*sensisha); sharpVBox->pack_start (*inverssha); - Gtk::VBox *denoisVBox = Gtk::manage ( new Gtk::VBox()); denoisVBox->set_spacing (2); denoisVBox->set_border_width (4); @@ -519,16 +542,39 @@ Locallab::Locallab (): neutrHBox1->pack_start (*neutral1); pack_start (*neutrHBox1); + superFrame->set_label_align (0.025, 0.5); + Gtk::VBox *superVBox = Gtk::manage ( new Gtk::VBox()); + superVBox->set_spacing (2); + superFrame->set_label_widget (*curvactiv); - colorVBox->pack_start (*lightness); - colorVBox->pack_start (*contrast); + superVBox->pack_start (*lightness); +// colorVBox->pack_start (*curvactiv); + superVBox->pack_start (*contrast); + superFrame->add (*superVBox); + colorVBox->pack_start (*superFrame); + colorVBox->pack_start (*chroma); colorVBox->pack_start (*sensi); - colorVBox->pack_start (*curvactiv); + + qualcurvbox->pack_start (*labqualcurv, Gtk::PACK_SHRINK, 4); + qualcurvbox->pack_start (*qualitycurveMethod); + + colorVBox->pack_start (*qualcurvbox); + colorVBox->pack_start (*llCurveEditorG, Gtk::PACK_SHRINK, 2); + artifFrame->set_border_width (0); + artifFrame->set_label_align (0.025, 0.5); + artifVBox->set_spacing (2); + artifVBox->set_border_width (4); + + artifVBox->pack_start (*thres); + artifVBox->pack_start (*proxi); + artifFrame->add (*artifVBox); + + colorVBox->pack_start (*artifFrame); colorVBox->pack_start (*invers); expcolor->add (*colorVBox); @@ -759,6 +805,7 @@ void Locallab::neutral_pressed () centerY->resetValue (false); circrad->resetValue (false); qualityMethod->set_active (0); + qualitycurveMethod->set_active (0); thres->resetValue (false); proxi->resetValue (false); lightness->resetValue (false); @@ -1150,6 +1197,14 @@ bool Locallab::localComputed_ () curvactiv->set_active (true); } + if (nextdatasp[57] == 0) { + qualitycurveMethod->set_active (0); + } else if (nextdatasp[57] == 1) { + qualitycurveMethod->set_active (1); + } else if (nextdatasp[57] == 2) { + qualitycurveMethod->set_active (2); + } + int *s_datc; s_datc = new int[70]; int siz; @@ -1291,7 +1346,10 @@ bool Locallab::localComputed_ () if (listener) {//for quality method listener->panelChanged (EvlocallabqualityMethod, qualityMethod->get_active_text ()); + } + if (listener) {//for quality method + listener->panelChanged (EvlocallabqualitycurveMethod, qualitycurveMethod->get_active_text ()); } if (listener) {//for inverse retinex @@ -1331,7 +1389,7 @@ bool Locallab::localComputed_ () void Locallab::localChanged (int **datasp, std::string datastr, std::string ll_str, std::string lh_str, std::string cc_str, int sp, int maxdat) { - for (int i = 2; i < 60; i++) { //58 + for (int i = 2; i < 61; i++) { nextdatasp[i] = datasp[i][sp]; } @@ -1452,6 +1510,10 @@ void Locallab::read (const ProcParams* pp, const ParamsEdited* pedited) qualityMethod->set_active_text (M ("GENERAL_UNCHANGED")); } + if (!pedited->locallab.qualitycurveMethod) { + qualitycurveMethod->set_active_text (M ("GENERAL_UNCHANGED")); + } + } setEnabled (pp->locallab.enabled); @@ -1459,6 +1521,7 @@ void Locallab::read (const ProcParams* pp, const ParamsEdited* pedited) Smethodconn.block (true); retinexMethodConn.block (true); qualityMethodConn.block (true); + qualitycurveMethodConn.block (true); avoidConn.block (true); avoid->set_active (pp->locallab.avoid); @@ -1595,6 +1658,16 @@ void Locallab::read (const ProcParams* pp, const ParamsEdited* pedited) qualityMethodChanged (); qualityMethodConn.block (false); + if (pp->locallab.qualitycurveMethod == "none") { + qualitycurveMethod->set_active (0); + } else if (pp->locallab.qualitycurveMethod == "std") { + qualitycurveMethod->set_active (1); + } else if (pp->locallab.qualitycurveMethod == "enh") { + qualitycurveMethod->set_active (2); + } + + qualitycurveMethodChanged (); + qualitycurveMethodConn.block (false); anbspot->hide(); @@ -1788,6 +1861,7 @@ void Locallab::write (ProcParams* pp, ParamsEdited* pedited) pedited->locallab.Smethod = Smethod->get_active_text() != M ("GENERAL_UNCHANGED"); pedited->locallab.retinexMethod = retinexMethod->get_active_text() != M ("GENERAL_UNCHANGED"); pedited->locallab.qualityMethod = qualityMethod->get_active_text() != M ("GENERAL_UNCHANGED"); + pedited->locallab.qualitycurveMethod = qualitycurveMethod->get_active_text() != M ("GENERAL_UNCHANGED"); pedited->locallab.locY = locY->getEditedState (); pedited->locallab.locX = locX->getEditedState (); pedited->locallab.locYT = locYT->getEditedState (); @@ -1874,6 +1948,14 @@ void Locallab::write (ProcParams* pp, ParamsEdited* pedited) pp->locallab.qualityMethod = "enhden"; } + if (qualitycurveMethod->get_active_row_number() == 0) { + pp->locallab.qualitycurveMethod = "none"; + } else if (qualitycurveMethod->get_active_row_number() == 1) { + pp->locallab.qualitycurveMethod = "std"; + } else if (qualitycurveMethod->get_active_row_number() == 2) { + pp->locallab.qualitycurveMethod = "enh"; + } + if (Smethod->get_active_row_number() == 0) { pp->locallab.Smethod = "IND"; @@ -1980,6 +2062,7 @@ void Locallab::retinexMethodChanged() void Locallab::qualityMethodChanged() { if (!batchMode) { + /* if (qualityMethod->get_active_row_number() == 0) { //STD proxi->hide(); thres->hide(); @@ -1987,6 +2070,7 @@ void Locallab::qualityMethodChanged() proxi->show(); thres->show(); } + */ } if (listener) { @@ -1994,6 +2078,25 @@ void Locallab::qualityMethodChanged() } } +void Locallab::qualitycurveMethodChanged() +{ + if (!batchMode) { + /* + if (qualitycurveMethod->get_active_row_number() == 0 || qualitycurveMethod->get_active_row_number() == 1) { //None or STD + artifFrame->hide(); + } else if (qualitycurveMethod->get_active_row_number() == 0 && qualityMethod->get_active_row_number() >= 1) { + artifFrame->show(); + } else if (qualitycurveMethod->get_active_row_number() == 2){ + artifFrame->show(); + } + */ + } + + if (listener) { + listener->panelChanged (EvlocallabqualitycurveMethod, qualitycurveMethod->get_active_text ()); + } +} + void Locallab::SmethodChanged () { if (!batchMode) { @@ -2078,10 +2181,18 @@ void Locallab::inversChanged () sensi->hide(); llCurveEditorG->hide(); curvactiv->hide(); + qualitycurveMethod->hide(); + artifFrame->hide(); + labqualcurv->hide(); + } else { sensi->show(); llCurveEditorG->show(); curvactiv->show(); + qualitycurveMethod->show(); + artifFrame->show(); + labqualcurv->show(); + } if (listener) { diff --git a/rtgui/locallab.h b/rtgui/locallab.h index 0ff384325..9b56f9ccc 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -100,6 +100,23 @@ private: sigc::connection editConn, avoidConn, inversConn, curvactivConn, activlumConn, inversradConn, inversretConn, inversshaConn, neutralconn, neutralconn1; Gtk::HBox* const ctboxS; + Gtk::HBox* const qualbox; + Gtk::HBox* const qualcurvbox; + + Gtk::Frame* const artifFrame; + Gtk::Frame* const shapeFrame; + Gtk::Frame* const superFrame; + + Gtk::VBox* const artifVBox; + Gtk::VBox* const shapeVBox; + Gtk::VBox* const tmBox; + Gtk::VBox* const retiBox; + Gtk::VBox* const colorVBox; + Gtk::VBox* const blurrVBox; + Gtk::VBox* const sharpVBox; + Gtk::VBox* const cbdlVBox; + Gtk::VBox* const denoisVBox; + Gtk::VBox* const superVBox; Gtk::CheckButton* const avoid; Gtk::CheckButton* const invers; @@ -120,9 +137,15 @@ private: sigc::connection retinexMethodConn; MyComboBoxText* const qualityMethod; sigc::connection qualityMethodConn; + MyComboBoxText* const qualitycurveMethod; + sigc::connection qualitycurveMethodConn; Gtk::Label* const labmdh; + Gtk::Label* const labqual; + Gtk::Label* const labqualcurv; + Gtk::Label* const labmS; + Gtk::HBox* const dhbox; CurveEditorGroup* const LocalcurveEditorgainT; @@ -137,7 +160,7 @@ private: - int nextdatasp[60]; + int nextdatasp[61]; int nextlength; std::string nextstr; std::string nextstr2; @@ -197,6 +220,7 @@ public: void setEditProvider (EditDataProvider* provider); void retinexMethodChanged(); void qualityMethodChanged(); + void qualitycurveMethodChanged(); void lumaneutralPressed (); void lumacontrastPlusPressed (); void lumacontrastMinusPressed (); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 53590db4a..41d70bcb2 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -310,6 +310,7 @@ void ParamsEdited::set (bool v) locallab.thres = v; locallab.proxi = v; locallab.qualityMethod = v; + locallab.qualitycurveMethod = v; locallab.lightness = v; locallab.contrast = v; locallab.chroma = v; @@ -881,6 +882,7 @@ void ParamsEdited::initFrom (const std::vector locallab.thres = locallab.thres && p.locallab.thres == other.locallab.thres; locallab.proxi = locallab.proxi && p.locallab.proxi == other.locallab.proxi; locallab.qualityMethod = locallab.qualityMethod && p.locallab.qualityMethod == other.locallab.qualityMethod; + locallab.qualitycurveMethod = locallab.qualitycurveMethod && p.locallab.qualitycurveMethod == other.locallab.qualitycurveMethod; locallab.lightness = locallab.lightness && p.locallab.lightness == other.locallab.lightness; locallab.contrast = locallab.contrast && p.locallab.contrast == other.locallab.contrast; locallab.chroma = locallab.chroma && p.locallab.chroma == other.locallab.chroma; @@ -2229,6 +2231,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.locallab.qualityMethod = mods.locallab.qualityMethod; } + if (locallab.qualitycurveMethod) { + toEdit.locallab.qualitycurveMethod = mods.locallab.qualitycurveMethod; + } + if (locallab.centerX) { toEdit.locallab.centerX = mods.locallab.centerX; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index f7d5956ac..8544261a9 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -429,6 +429,7 @@ public: bool thres; bool proxi; bool qualityMethod; + bool qualitycurveMethod; bool lightness; bool contrast; bool chroma;