From 1a91bb60fe47cd4ba434605e8ef884dc9ad92f97 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sat, 10 Mar 2018 18:12:15 +0100 Subject: [PATCH] Improve lightness for color and light and fix crashed with contrast when lightness -100 --- rtengine/curves.cc | 233 +++++++++++++++++++++++++++++++++- rtengine/curves.h | 4 +- rtengine/dcrop.cc | 15 ++- rtengine/improccoordinator.cc | 16 ++- rtengine/improccoordinator.h | 2 + rtengine/improcfun.h | 6 +- rtengine/iplocallab.cc | 49 +++---- rtengine/simpleprocess.cc | 9 +- 8 files changed, 285 insertions(+), 49 deletions(-) diff --git a/rtengine/curves.cc b/rtengine/curves.cc index e0e22c8a8..77c20cc7d 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -756,7 +756,8 @@ void CurveFactory::complexCurve(double ecomp, double black, double hlcompr, doub const float slope = 1.055 * powf(start, 1.0 / gamma_ - 1) - 0.055 / start; const float mul = 1.055; const float add = 0.055; - + + // a: slope of the curve, black: starting point at the x axis const float a = powf(2.0, ecomp); @@ -1016,12 +1017,9 @@ void CurveFactory::complexCurve(double ecomp, double black, double hlcompr, doub //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - void CurveFactory::complexCurvelocal(double ecomp, double black, double hlcompr, double hlcomprthresh, - double shcompr, - LUTf & hlCurve, LUTf & shCurve, LUTf & outCurve, + double shcompr, double br, + LUTf & hlCurve, LUTf & shCurve, LUTf & outCurve, LUTf & lightCurveloc, int skip) { @@ -1036,6 +1034,62 @@ void CurveFactory::complexCurvelocal(double ecomp, double black, double hlcompr, ecomp /= 100.;//for mip files in integer * 100 + // check if brightness curve is needed + if (br > 0.00001 || br < -0.00001) { + // utili = true; + + std::vector brightcurvePoints; + brightcurvePoints.resize(9); + brightcurvePoints.at(0) = double (DCT_NURBS); + + brightcurvePoints.at(1) = 0.; // black point. Value in [0 ; 1] range + brightcurvePoints.at(2) = 0.; // black point. Value in [0 ; 1] range + + if (br > 0) { + brightcurvePoints.at(3) = 0.1; // toe point + brightcurvePoints.at(4) = 0.1 + br / 150.0; //value at toe point + + brightcurvePoints.at(5) = 0.7; // shoulder point + brightcurvePoints.at(6) = min(1.0, 0.7 + br / 300.0); //value at shoulder point + } else { + brightcurvePoints.at(3) = 0.1 - br / 150.0; // toe point + brightcurvePoints.at(4) = 0.1; // value at toe point + + brightcurvePoints.at(5) = min(1.0, 0.7 - br / 300.0); // shoulder point + brightcurvePoints.at(6) = 0.7; // value at shoulder point + } + + brightcurvePoints.at(7) = 1.; // white point + brightcurvePoints.at(8) = 1.; // value at white point + + DiagonalCurve brightcurve(brightcurvePoints, CURVES_MIN_POLY_POINTS / skip); + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + // Applying brightness curve + for (int i = 0; i < 32768; i++) { // L values range up to 32767, higher values are for highlight overflow + + // change to [0,1] range + float val = (float)i / 32767.0; + + // apply brightness curve + val = brightcurve.getVal(val); + + // store result in a temporary array + lightCurveloc[i] = CLIPD(val); + } + lightCurveloc *= 32767.f; + for (int i = 32768; i < 32770; i++) { // set last two elements of lut to 32768 and 32769 to allow linear interpolation + lightCurveloc[i] = (float)i; + } + + + } else { + lightCurveloc.makeIdentity(32767.f); + } + + + + // a: slope of the curve, black: starting point at the x axis const float a = powf(2.0f, ecomp); @@ -1166,6 +1220,173 @@ void CurveFactory::complexCurvelocal(double ecomp, double black, double hlcompr, } + + + + +/* +void CurveFactory::complexCurvelocal(double ecomp, double black, double hlcompr, double hlcomprthresh, + double shcompr, double br, + LUTf & hlCurve, LUTf & shCurve, LUTf & outCurve, + int skip) +{ + float maxran = 65536.f; //65536 + + ecomp /= 100.;//for mip files in integer * 100 + + // a: slope of the curve, black: starting point at the x axis + const float a = powf(2.0f, ecomp); + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // tone curve base. a: slope (from exp.comp.), b: black, def_mul: max. x value (can be>1), hr,sr: highlight,shadow recovery + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + if (br > 0.00001 || br < -0.00001) { + // utili = true; + + std::vector brightcurvePoints; + brightcurvePoints.resize(9); + brightcurvePoints.at(0) = double (DCT_NURBS); + + brightcurvePoints.at(1) = 0.; // black point. Value in [0 ; 1] range + brightcurvePoints.at(2) = 0.; // black point. Value in [0 ; 1] range + + if (br > 0) { + brightcurvePoints.at(3) = 0.1; // toe point + brightcurvePoints.at(4) = 0.1 + br / 150.0; //value at toe point + + brightcurvePoints.at(5) = 0.7; // shoulder point + brightcurvePoints.at(6) = min(1.0, 0.7 + br / 300.0); //value at shoulder point + } else { + brightcurvePoints.at(3) = 0.1 - br / 150.0; // toe point + brightcurvePoints.at(4) = 0.1; // value at toe point + + brightcurvePoints.at(5) = min(1.0, 0.7 - br / 300.0); // shoulder point + brightcurvePoints.at(6) = 0.7; // value at shoulder point + } + + brightcurvePoints.at(7) = 1.; // white point + brightcurvePoints.at(8) = 1.; // value at white point + + DiagonalCurve brightcurve(brightcurvePoints, CURVES_MIN_POLY_POINTS / skip); + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + // Applying brightness curve + for (int i = 0; i < 32768; i++) { // L values range up to 32767, higher values are for highlight overflow + + // change to [0,1] range + float val = (float)i / 32767.0; + + // apply brightness curve + val = brightcurve.getVal(val); + + // store result in a temporary array + outCurve[i] = CLIPD(val); + } + + } else { + outCurve.makeIdentity(32767.f); + } + + + + hlCurve.setClip(LUT_CLIP_BELOW); // used LUT_CLIP_BELOW, because we want to have a baseline of 2^expcomp in this curve. If we don't clip the lut we get wrong values, see Issue 2621 #14 for details + float exp_scale = a; +// float scale = 65536.0; + float scale = maxran; + float comp = (max(0.0, ecomp) + 1.0) * hlcompr / 100.0; + float shoulder = ((scale / max(1.0f, exp_scale)) * (hlcomprthresh / 200.0)) + 0.1; + + if (comp <= 0.0f) { + hlCurve.makeConstant(exp_scale); + } else { + hlCurve.makeConstant(exp_scale, shoulder + 1); + + float scalemshoulder = scale - shoulder; + +#ifdef __SSE2__ + int i = shoulder + 1; + + if (i & 1) { // original formula, slower than optimized formulas below but only used once or none, so I let it as is for reference + // change to [0,1] range + float val = (float)i - shoulder; + float R = val * comp / (scalemshoulder); + hlCurve[i] = xlog(1.0f + R * exp_scale) / R; // don't use xlogf or 1.f here. Leads to errors caused by too low precision + i++; + } + + vdouble onev = _mm_set1_pd(1.0); + vdouble Rv = _mm_set_pd((i + 1 - shoulder) * (double)comp / scalemshoulder, (i - shoulder) * (double)comp / scalemshoulder); + vdouble incrementv = _mm_set1_pd(2.0 * comp / scalemshoulder); + vdouble exp_scalev = _mm_set1_pd(exp_scale); + + // for (; i < 0x10000; i += 2) { + for (; i < maxran; i += 2) { + // change to [0,1] range + vdouble resultv = xlog(onev + Rv * exp_scalev) / Rv; + vfloat resultfv = _mm_cvtpd_ps(resultv); + _mm_store_ss(&hlCurve[i], resultfv); + resultfv = PERMUTEPS(resultfv, _MM_SHUFFLE(1, 1, 1, 1)); + _mm_store_ss(&hlCurve[i + 1], resultfv); + Rv += incrementv; + } + +#else + float R = comp / scalemshoulder; + float increment = R; + + // for (int i = shoulder + 1; i < 0x10000; i++) { + for (int i = shoulder + 1; i < maxran; i++) { + // change to [0,1] range + hlCurve[i] = xlog(1.0f + R * exp_scale) / R; // don't use xlogf or 1.f here. Leads to errors caused by too low precision + R += increment; + } + +#endif + + } + + + // curve without contrast + // LUTf dcurve (0x10000); + LUTf dcurve(maxran); + + //%%%%%%%%%%%%%%%%%%%%%%%%%% + // change to [0,1] range + shCurve.setClip(LUT_CLIP_ABOVE); // used LUT_CLIP_ABOVE, because the curve converges to 1.0 at the upper end and we don't want to exceed this value. + float val = 1.f / (maxran - 1.f); + float val2 = simplebasecurve(val, black, 0.015 * shcompr); + shCurve[0] = CLIPD(val2) / val; + // gamma correction + + val = Color::gammatab_srgb[0] / maxran; + // val = 0.f / maxran; + + // val = Color::gammatab_srgb327[0] / 32767.f; + // store result in a temporary array + dcurve[0] = CLIPD(val); + +// for (int i = 1; i < 0x10000; i++) { +// float val = i / 65535.f; + for (int i = 1; i < maxran; i++) { + float val = i / (maxran - 1.f); + + float val2 = simplebasecurve(val, black, 0.015 * shcompr); + shCurve[i] = val2 / val; + + // gamma correction + val = Color::gammatab_srgb[i] / maxran; + // val = i / maxran; + + // val = Color::gammatab_srgb327[i] / 32767.f; + // store result in a temporary array + dcurve[i] = val; + } + +} +*/ + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% void CurveFactory::complexLCurve(double br, double contr, const std::vector& curvePoints, diff --git a/rtengine/curves.h b/rtengine/curves.h index 1ad8d7ede..82a494100 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -287,8 +287,8 @@ public: int skip = 1); - static void complexCurvelocal(double ecomp, double black, double hlcompr, double hlcomprthresh, double shcompr, - LUTf & hlCurve, LUTf & shCurve, LUTf & outCurve, + static void complexCurvelocal(double ecomp, double black, double hlcompr, double hlcomprthresh, double shcompr, double br, + LUTf & hlCurve, LUTf & shCurve, LUTf & outCurve, LUTf & lightCurveloc, int skip = 1); static void curveBW(const std::vector& curvePointsbw, const std::vector& curvePointsbw2, const LUTu & histogrambw, LUTu & outBeforeCCurveHistogrambw, diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 5ec49b905..84624604f 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -907,6 +907,7 @@ void Crop::update(int todo) LUTf hltonecurveloc2(65536, 0); //65536 LUTf shtonecurveloc2(65536, 0); LUTf tonecurveloc2(65536, 0); + LUTf lightCurveloc2(32770, 0); bool LHutili = parent->LHutili; bool HHutili = parent->HHutili; @@ -1295,9 +1296,10 @@ void Crop::update(int todo) double hlcompr = params.locallab.hlcompr; double hlcomprthresh = params.locallab.hlcomprthresh; double shcompr = params.locallab.shcompr; + double br = params.locallab.lightness; - CurveFactory::complexCurvelocal(ecomp, black / 65535., hlcompr, hlcomprthresh, shcompr, - hltonecurveloc2, shtonecurveloc2, tonecurveloc2, + CurveFactory::complexCurvelocal(ecomp, black / 65535., hlcompr, hlcomprthresh, shcompr, br, + hltonecurveloc2, shtonecurveloc2, tonecurveloc2, lightCurveloc2, sca); params.locallab.huerefblur = (parent->huerefblurs[sp]) / 100.f; @@ -1307,7 +1309,7 @@ void Crop::update(int todo) params.locallab.sobelref = parent->sobelrefs[sp]; parent->ipf.Lab_Local(1, maxspot, sp, parent->huerefs, parent->sobelrefs, parent->centerx, parent->centery, (float**)shbuffer, labnCrop, labnCrop, reservCrop, cropx / skip, cropy / skip, skips(parent->fw, skip), skips(parent->fh, skip), skip, locRETgainCurve, lllocalcurve2, - loclhCurve, lochhCurve, LHutili, HHutili, cclocalcurve2, localskutili, sklocalcurve2, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, params.locallab.huerefblur, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref, params.locallab.sobelref); + loclhCurve, lochhCurve, LHutili, HHutili, cclocalcurve2, localskutili, sklocalcurve2, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, lightCurveloc2, params.locallab.huerefblur, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref, params.locallab.sobelref); lllocalcurve2.clear(); cclocalcurve2.clear(); sklocalcurve2.clear(); @@ -1785,9 +1787,10 @@ void Crop::update(int todo) double hlcompr = params.locallab.hlcompr; double hlcomprthresh = params.locallab.hlcomprthresh; double shcompr = params.locallab.shcompr; + double br = params.locallab.lightness; - CurveFactory::complexCurvelocal(ecomp, black / 65535., hlcompr, hlcomprthresh, shcompr, - hltonecurveloc2, shtonecurveloc2, tonecurveloc2, + CurveFactory::complexCurvelocal(ecomp, black / 65535., hlcompr, hlcomprthresh, shcompr, br, + hltonecurveloc2, shtonecurveloc2, tonecurveloc2,lightCurveloc2, sca); params.locallab.huerefblur = (parent->huerefblurs[sp]) / 100.f; @@ -1796,7 +1799,7 @@ void Crop::update(int todo) params.locallab.lumaref = parent->lumarefs[sp]; params.locallab.sobelref = parent->sobelrefs[sp]; parent->ipf.Lab_Local(1, maxspot, sp, parent->huerefs, parent->sobelrefs, parent->centerx, parent->centery, (float**)shbuffer, labnCrop, labnCrop, reservCrop, cropx / skip, cropy / skip, skips(parent->fw, skip), skips(parent->fh, skip), skip, locRETgainCurve, lllocalcurve2, loclhCurve, lochhCurve, - LHutili, HHutili, cclocalcurve2, localskutili, sklocalcurve2, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, params.locallab.huerefblur, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref, params.locallab.sobelref); + LHutili, HHutili, cclocalcurve2, localskutili, sklocalcurve2, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, lightCurveloc2, params.locallab.huerefblur, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref, params.locallab.sobelref); lllocalcurve2.clear(); cclocalcurve2.clear(); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 3c500e251..378cdbf13 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -64,6 +64,7 @@ ImProcCoordinator::ImProcCoordinator() hltonecurveloc(65536, 0), //32768 shtonecurveloc(65536, 0), tonecurveloc(65536, 0), + lightCurveloc(32770, 0), cl2Toningcurve(65536, 0), Noisecurve(65536, 0), NoiseCCcurve(65536, 0), @@ -2688,9 +2689,9 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) double hlcompr = params.locallab.hlcompr; double hlcomprthresh = params.locallab.hlcomprthresh; double shcompr = params.locallab.shcompr; - - CurveFactory::complexCurvelocal(ecomp, black / 65535., hlcompr, hlcomprthresh, shcompr, - hltonecurveloc, shtonecurveloc, tonecurveloc, + double br = params.locallab.lightness; + CurveFactory::complexCurvelocal(ecomp, black / 65535., hlcompr, hlcomprthresh, shcompr, br, + hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, sca); double huere, chromare, lumare, huerefblu; @@ -2720,7 +2721,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) dataspot[maxdata - 1][sp] = sobelrefs[sp] = params.locallab.sobelref; //printf("sp=%i huerefsp=%f\n", sp, huerefs[sp]); ipf.Lab_Local(3, maxspot, sp, huerefs, sobelrefs, centerx, centery, (float**)shbuffer, nprevl, nprevl, reserv, 0, 0, pW, pH, scale, locRETgainCurve, lllocalcurve, loclhCurve, lochhCurve, - LHutili, HHutili, cclocalcurve, localskutili, sklocalcurve, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, params.locallab.huerefblur, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref, params.locallab.sobelref); + LHutili, HHutili, cclocalcurve, localskutili, sklocalcurve, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, params.locallab.huerefblur, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref, params.locallab.sobelref); lllocalcurve.clear(); cclocalcurve.clear(); sklocalcurve.clear(); @@ -3364,9 +3365,10 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) double hlcompr = params.locallab.hlcompr; double hlcomprthresh = params.locallab.hlcomprthresh; double shcompr = params.locallab.shcompr; + double br = params.locallab.lightness; - CurveFactory::complexCurvelocal(ecomp, black / 65535., hlcompr, hlcomprthresh, shcompr, - hltonecurveloc, shtonecurveloc, tonecurveloc, + CurveFactory::complexCurvelocal(ecomp, black / 65535., hlcompr, hlcomprthresh, shcompr, br, + hltonecurveloc, shtonecurveloc, tonecurveloc,lightCurveloc, sca); CurveFactory::curveLocal(locallutili, params.locallab.llcurve, lllocalcurve, sca); @@ -3380,7 +3382,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) params.locallab.lumaref = lumarefs[sp]; params.locallab.sobelref = sobelrefs[sp]; ipf.Lab_Local(3, maxspot, sp, huerefs, sobelrefs, centerx, centery, (float**)shbuffer, nprevl, nprevl, reserv, 0, 0, pW, pH, scale, locRETgainCurve, lllocalcurve, loclhCurve, lochhCurve, LHutili, HHutili, cclocalcurve, - localskutili, sklocalcurve, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, params.locallab.huerefblur, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref, params.locallab.sobelref); + localskutili, sklocalcurve, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, params.locallab.huerefblur, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref, params.locallab.sobelref); lllocalcurve.clear(); cclocalcurve.clear(); sklocalcurve.clear(); diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index e1a610995..c3666ccc0 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -121,6 +121,8 @@ protected: LUTf hltonecurveloc; LUTf shtonecurveloc; LUTf tonecurveloc; + LUTf lightCurveloc; + // ToneCurve customToneCurve1loc; LUTf cl2Toningcurve; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 08c5fb4d4..48db4ed43 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -297,7 +297,7 @@ public: void calc_ref(LabImage* original, LabImage* transformed, int cx, int cy, int oW, int oH, int sk, double &huerefblur, double &huere, double &chromare, double &lumare, double &sobelref); void copy_ref(LabImage* spotbuffer, LabImage* original, LabImage* transformed, int cx, int cy, int sk, const struct local_params & lp, double &huerefspot, double &chromarefspot, double &lumarefspot); void paste_ref(LabImage* spotbuffer, LabImage* transformed, int cx, int cy, int sk, const struct local_params & lp); - void Lab_Local(int call, int maxspot, int sp, LUTf & huerefs, LUTf & sobelrefs, LUTi & centerx, LUTi & centery, float** shbuffer, LabImage* original, LabImage* transformed, LabImage* reserved, int cx, int cy, int oW, int oH, int sk, const LocretigainCurve & locRETgainCcurve, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, bool &LHutili, bool &HHutili, LUTf & cclocalcurve, bool & localskutili, LUTf & sklocalcurve, bool & localexutili, LUTf & exlocalcurve, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, double & huerefblur, double &hueref, double &chromaref, double &lumaref, double &sobelref); + void Lab_Local(int call, int maxspot, int sp, LUTf & huerefs, LUTf & sobelrefs, LUTi & centerx, LUTi & centery, float** shbuffer, LabImage* original, LabImage* transformed, LabImage* reserved, int cx, int cy, int oW, int oH, int sk, const LocretigainCurve & locRETgainCcurve, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, bool &LHutili, bool &HHutili, LUTf & cclocalcurve, bool & localskutili, LUTf & sklocalcurve, bool & localexutili, LUTf & exlocalcurve, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, LUTf & lightCurveloc, double & huerefblur, double &hueref, double &chromaref, double &lumaref, double &sobelref); 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); @@ -323,8 +323,8 @@ public: void fftw_denoise(int GW, int GH, int max_numblox_W, int min_numblox_W, float **tmp1, array2D *Lin, int numThreads, const struct local_params & lp, int chrom); - void ColorLight_Local(int call, LabImage * bufcolorig, float **buflight, float **bufchro, float **bufchroslid, float ** bufhh, float ** buflightslid, bool &LHutili, bool &HHutili, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, const local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy, int sk); - void InverseColorLight_Local(const struct local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, int sk); + void ColorLight_Local(int call, LabImage * bufcolorig, float **buflight, float **bufchro, float **bufchroslid, float ** bufhh, float ** buflightslid, bool &LHutili, bool &HHutili, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, LUTf & lightCurveloc, const local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy, int sk); + void InverseColorLight_Local(const struct local_params& lp, LUTf & lightCurveloc, LabImage* original, LabImage* transformed, int cx, int cy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, int sk); void cat02_Local(float **buflightcat, float **buf_a_cat, float ** buf_b_cat, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const struct local_params & lp, LabImage * original, LabImage * transformed, const LabImage * const tmp1, int cx, int cy, int sk); void Sharp_Local(int call, float **loctemp, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy, int sk); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index d78f9dd16..8b86fba9d 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -4842,7 +4842,7 @@ void ImProcFunctions::InverseContrast_Local(float ave, struct local_contra & lco delete origblur; } -static void calclight(float lum, float koef, float & lumnew, bool inv) +static void calclight(float lum, float koef, float & lumnew, bool inv, LUTf & lightCurveloc) //replace L-curve that does not work in local or bad { @@ -4857,19 +4857,24 @@ static void calclight(float lum, float koef, float & lumnew, bool inv) } if (koef >= 0.f) { - lumnew = lum + 0.2f * (33000.f - lum) * koef / 100.f; + // lumnew = lum + 0.2f * (33000.f - lum) * koef / 100.f; + lumnew = lightCurveloc[lum]; } if (koef < 0.f) { - lumnew = lum + blac * lum * koef / 100.f;//0.999 instead of 0.2 + lumnew = lightCurveloc[lum]; - if (lumnew < 0.f) { - float kc = lum / (lum - lumnew); - lumnew = lum + kc * 0.2f * lum * koef / 100.f; + /* + lumnew = lum + blac * lum * koef / 100.f;//0.999 instead of 0.2 - } + if (lumnew < 0.f) { + float kc = lum / (lum - lumnew); + lumnew = lum + kc * 0.2f * lum * koef / 100.f; - // if (inv == false && koef == -100.f) { + } + + // if (inv == false && koef == -100.f) { + */ if (koef == -100.f) { lumnew = 0.f; } @@ -6245,7 +6250,7 @@ void ImProcFunctions::Expo_vibr_Local(int senstype, float **buflight, float **bu } -void ImProcFunctions::ColorLight_Local(int call, LabImage * bufcolorig, float ** buflight, float ** bufchro, float ** bufchroslid, float ** bufhh, float ** buflightslid, bool &LHutili, bool &HHutili, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, const local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk) +void ImProcFunctions::ColorLight_Local(int call, LabImage * bufcolorig, float ** buflight, float ** bufchro, float ** bufchroslid, float ** bufhh, float ** buflightslid, bool &LHutili, bool &HHutili, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, LUTf & lightCurveloc, const local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk) { BENCHFUN // chroma and lightness @@ -6834,7 +6839,7 @@ void ImProcFunctions::ColorLight_Local(int call, LabImage * bufcolorig, float ** } if (lp.ligh != 0.f && lp.curvact == false) { - calclight(lumnew, lp.ligh, lumnew, true); //replace L-curve + calclight(lumnew, lp.ligh, lumnew, true, lightCurveloc); //replace L-curve lightcont = lumnew; } else { @@ -6954,7 +6959,7 @@ void ImProcFunctions::ColorLight_Local(int call, LabImage * bufcolorig, float ** if (lp.ligh != 0.f && lp.curvact == false) { - calclight(lumnew, lp.ligh, lumnew, true); //replace L-curve + calclight(lumnew, lp.ligh, lumnew, true, lightCurveloc); //replace L-curve lightcont = lumnew; } else { @@ -7048,7 +7053,7 @@ void ImProcFunctions::ColorLight_Local(int call, LabImage * bufcolorig, float ** } -void ImProcFunctions::InverseColorLight_Local(const struct local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, int sk) +void ImProcFunctions::InverseColorLight_Local(const struct local_params & lp, LUTf & lightCurveloc, LabImage * original, LabImage * transformed, int cx, int cy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, int sk) { // BENCHFUN float ach = (float)lp.trans / 100.f; @@ -7445,7 +7450,7 @@ void ImProcFunctions::InverseColorLight_Local(const struct local_params & lp, La float lightcont; if (lp.ligh != 0.f) { - calclight(lumnew, lp.ligh, lumnew, true); //replace L-curve + calclight(lumnew, lp.ligh, lumnew, true, lightCurveloc); //replace L-curve lightcont = lumnew; } else { @@ -7472,7 +7477,7 @@ void ImProcFunctions::InverseColorLight_Local(const struct local_params & lp, La float lumnew = original->L[y][x]; if (lp.ligh != 0.f) { - calclight(original->L[y][x], lp.ligh, lumnew, false); + calclight(original->L[y][x], lp.ligh, lumnew, false, lightCurveloc); } float lightcont = lumnew ; //apply lightness @@ -7497,7 +7502,7 @@ void ImProcFunctions::InverseColorLight_Local(const struct local_params & lp, La float lightcont; if (lp.ligh != 0.f) { - calclight(lumnew, lp.ligh, lumnew, true); //replace L-curve + calclight(lumnew, lp.ligh, lumnew, true, lightCurveloc); //replace L-curve lightcont = lumnew; } else { @@ -7521,7 +7526,7 @@ void ImProcFunctions::InverseColorLight_Local(const struct local_params & lp, La } else { if (lp.ligh != 0.f) { - calclight(original->L[y][x], lp.ligh, lumnew, false); + calclight(original->L[y][x], lp.ligh, lumnew, false, lightCurveloc); } float lightcont = lumnew ; @@ -8035,7 +8040,7 @@ void ImProcFunctions::fftw_denoise(int GW, int GH, int max_numblox_W, int min_nu void ImProcFunctions::Lab_Local(int call, int maxspot, int sp, LUTf & huerefs, LUTf & sobelrefs, LUTi & centerx, LUTi & centery, float** shbuffer, LabImage * original, LabImage * transformed, LabImage * reserved, int cx, int cy, int oW, int oH, int sk, const LocretigainCurve & locRETgainCcurve, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, - bool & LHutili, bool & HHutili, LUTf & cclocalcurve, bool & localskutili, LUTf & sklocalcurve, bool & localexutili, LUTf & exlocalcurve, LUTf & hltonecurveloc, LUTf & shtonecurveloc, LUTf & tonecurveloc, double & huerefblur, double & hueref, double & chromaref, double & lumaref, double & sobelref) + bool & LHutili, bool & HHutili, LUTf & cclocalcurve, bool & localskutili, LUTf & sklocalcurve, bool & localexutili, LUTf & exlocalcurve, LUTf & hltonecurveloc, LUTf & shtonecurveloc, LUTf & tonecurveloc, LUTf & lightCurveloc, double & huerefblur, double & hueref, double & chromaref, double & lumaref, double & sobelref) { //general call of others functions : important return hueref, chromaref, lumaref if (params->locallab.enabled) { @@ -10544,7 +10549,7 @@ void ImProcFunctions::Lab_Local(int call, int maxspot, int sp, LUTf & huerefs, L float lighLnew; float amplil = 140.f; float lighL = bufcolorig->L[loy - begy][lox - begx]; - calclight(lighL, lp.ligh, lighLnew, true); //replace L-curve + calclight(lighL, lp.ligh, lighLnew, true, lightCurveloc); //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 @@ -10578,7 +10583,7 @@ void ImProcFunctions::Lab_Local(int call, int maxspot, int sp, LUTf & huerefs, L } } - ColorLight_Local(call, bufcolorig, buflight, bufchro, bufchroslid, bufhh, buflightslid, LHutili, HHutili, hueplus, huemoins, hueref, dhue, chromaref, lumaref, lllocalcurve, loclhCurve, lochhCurve, lp, original, transformed, cx, cy, sk); + ColorLight_Local(call, bufcolorig, buflight, bufchro, bufchroslid, bufhh, buflightslid, LHutili, HHutili, hueplus, huemoins, hueref, dhue, chromaref, lumaref, lllocalcurve, loclhCurve, lochhCurve, lightCurveloc, lp, original, transformed, cx, cy, sk); if (call <= 3) { @@ -10603,11 +10608,11 @@ void ImProcFunctions::Lab_Local(int call, int maxspot, int sp, LUTf & huerefs, L huemoins = hueref - dhue + 2.f * rtengine::RT_PI; } - InverseColorLight_Local(lp, original, transformed, cx, cy, hueplus, huemoins, hueref, dhue, chromaref, lumaref, sk); + InverseColorLight_Local(lp, lightCurveloc, original, transformed, cx, cy, hueplus, huemoins, hueref, dhue, chromaref, lumaref, sk); } - if (!lp.inv && lp.cont != 0 && lp.colorena) { //contrast interior ellipse + if (!lp.inv && lp.cont != 0 && lp.colorena && lp.ligh > -99) { //contrast interior ellipse const float pm = lp.cont < 0.f ? -1.f : 1.f; float hueplus = hueref + dhue; float huemoins = hueref - dhue; @@ -10752,7 +10757,7 @@ void ImProcFunctions::Lab_Local(int call, int maxspot, int sp, LUTf & huerefs, L } - } else if (lp.inv && lp.cont != 0 && lp.colorena) { + } else if (lp.inv && lp.cont != 0 && lp.colorena && lp.ligh > -99) { float hueplus = hueref + dhue; float huemoins = hueref - dhue; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index d02e10afa..6cc3c93c2 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1091,6 +1091,7 @@ private: LUTf hltonecurveloc(65536, 0); LUTf shtonecurveloc(65536, 0); LUTf tonecurveloc(65536, 0); + LUTf lightCurveloc(32770, 0); LUTf exlocalcurve(65536, 0); // int realspot = params.locallab.nbspot; int maxspot = settings->nspot + 1; @@ -2156,9 +2157,11 @@ private: double hlcompr = params.locallab.hlcompr; double hlcomprthresh = params.locallab.hlcomprthresh; double shcompr = params.locallab.shcompr; + double br = params.locallab.lightness; + + CurveFactory::complexCurvelocal(ecomp, black / 65535., hlcompr, hlcomprthresh, shcompr, br, + hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, - CurveFactory::complexCurvelocal(ecomp, black / 65535., hlcompr, hlcomprthresh, shcompr, - hltonecurveloc, shtonecurveloc, tonecurveloc, 1); double huere, chromare, lumare, huerefblu; @@ -2180,7 +2183,7 @@ private: //nullptr or dataspot ?? ipf.Lab_Local(2, maxspot, sp, huerefs, sobelrefs, centerx, centery, (float**)shbuffer, labView, labView, reservView, 0, 0, fw, fh, 1, locRETgainCurve, lllocalcurve, loclhCurve, lochhCurve, - LHutili, HHutili, cclocalcurve, localskutili, sklocalcurve, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, params.locallab.huerefblur, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref, params.locallab.sobelref); + LHutili, HHutili, cclocalcurve, localskutili, sklocalcurve, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, params.locallab.huerefblur, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref, params.locallab.sobelref); lllocalcurve.clear(); cclocalcurve.clear(); sklocalcurve.clear();