diff --git a/rtdata/languages/default b/rtdata/languages/default index 52e63ca3a..6a84b78a5 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -861,6 +861,8 @@ HISTORY_MSG_605;Local - Color Modifications HISTORY_MSG_606;Local - Exp Modifications HISTORY_MSG_607;Local - Color Mask C HISTORY_MSG_608;Local - Color Mask L +HISTORY_MSG_609;Local - Exp Mask C +HISTORY_MSG_610;Local - Exp Mask L HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction diff --git a/rtengine/curves.cc b/rtengine/curves.cc index 19ba12505..43071ff02 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -1570,6 +1570,98 @@ void LocretigainCurverab::Set(const std::vector &curvePoints) } } +LocLLmaskexpCurve::LocLLmaskexpCurve() : sum(0.f) {}; + +void LocLLmaskexpCurve::Reset() +{ + lutLocLLmaskexpCurve.reset(); + sum = 0.f; +} + +void LocLLmaskexpCurve::Set(const Curve &pCurve) +{ + if (pCurve.isIdentity()) { + Reset(); // raise this value if the quality suffers from this number of samples + return; + } + + lutLocLLmaskexpCurve(501); // raise this value if the quality suffers from this number of samples + sum = 0.f; + + for (int i = 0; i < 501; i++) { + lutLocLLmaskexpCurve[i] = pCurve.getVal(double (i) / 500.); + + if (lutLocLLmaskexpCurve[i] < 0.02f) { + lutLocLLmaskexpCurve[i] = 0.02f; //avoid 0.f for wavelet : under 0.01f quasi no action for each value + } + + sum += lutLocLLmaskexpCurve[i]; + } + + //lutLocHHCurve.dump("wav"); +} + + + +void LocLLmaskexpCurve::Set(const std::vector &curvePoints) +{ + // if (HHutili && !curvePoints.empty() && curvePoints[0] > FCT_Linear && curvePoints[0] < FCT_Unchanged) { + if (!curvePoints.empty() && curvePoints[0] > FCT_Linear && curvePoints[0] < FCT_Unchanged) { + FlatCurve ttcurve(curvePoints, false, CURVES_MIN_POLY_POINTS / 2); + ttcurve.setIdentityValue(0.); + Set(ttcurve); + } else { + Reset(); + } +} + + + + +LocCCmaskexpCurve::LocCCmaskexpCurve() : sum(0.f) {}; + +void LocCCmaskexpCurve::Reset() +{ + lutLocCCmaskexpCurve.reset(); + sum = 0.f; +} + +void LocCCmaskexpCurve::Set(const Curve &pCurve) +{ + if (pCurve.isIdentity()) { + Reset(); // raise this value if the quality suffers from this number of samples + return; + } + + lutLocCCmaskexpCurve(501); // raise this value if the quality suffers from this number of samples + sum = 0.f; + + for (int i = 0; i < 501; i++) { + lutLocCCmaskexpCurve[i] = pCurve.getVal(double (i) / 500.); + + if (lutLocCCmaskexpCurve[i] < 0.02f) { + lutLocCCmaskexpCurve[i] = 0.02f; //avoid 0.f for wavelet : under 0.01f quasi no action for each value + } + + sum += lutLocCCmaskexpCurve[i]; + } + + //lutLocHHCurve.dump("wav"); +} + + + +void LocCCmaskexpCurve::Set(const std::vector &curvePoints) +{ + // if (HHutili && !curvePoints.empty() && curvePoints[0] > FCT_Linear && curvePoints[0] < FCT_Unchanged) { + if (!curvePoints.empty() && curvePoints[0] > FCT_Linear && curvePoints[0] < FCT_Unchanged) { + FlatCurve ttcurve(curvePoints, false, CURVES_MIN_POLY_POINTS / 2); + ttcurve.setIdentityValue(0.); + Set(ttcurve); + } else { + Reset(); + } +} LocCCmaskCurve::LocCCmaskCurve() : sum(0.f) {}; @@ -1579,6 +1671,7 @@ void LocCCmaskCurve::Reset() sum = 0.f; } + void LocCCmaskCurve::Set(const Curve &pCurve) { if (pCurve.isIdentity()) { diff --git a/rtengine/curves.h b/rtengine/curves.h index a9dc685bb..e51c9b2fa 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -632,6 +632,64 @@ public: } }; +class LocCCmaskexpCurve +{ +private: + LUTf lutLocCCmaskexpCurve; // 0xffff range + void Set(const Curve &pCurve); + +public: + float sum; + + virtual ~LocCCmaskexpCurve() {}; + LocCCmaskexpCurve(); + void Reset(); + void Set(const std::vector &curvePoints); + float getSum() const + { + return sum; + } + + float operator[](float index) const + { + return lutLocCCmaskexpCurve[index]; + } + operator bool (void) const + { + return lutLocCCmaskexpCurve; + } +}; + +class LocLLmaskexpCurve +{ +private: + LUTf lutLocLLmaskexpCurve; // 0xffff range + void Set(const Curve &pCurve); + +public: + float sum; + + virtual ~LocLLmaskexpCurve() {}; + LocLLmaskexpCurve(); + void Reset(); + void Set(const std::vector &curvePoints); + float getSum() const + { + return sum; + } + + float operator[](float index) const + { + return lutLocLLmaskexpCurve[index]; + } + operator bool (void) const + { + return lutLocLLmaskexpCurve; + } +}; + + + class LocCCmaskCurve { private: diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 70e9a7d51..6cf647a11 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -904,6 +904,8 @@ void Crop::update(int todo) LocHHCurve lochhCurve; LocCCmaskCurve locccmasCurve; LocLLmaskCurve locllmasCurve; + LocCCmaskexpCurve locccmasexpCurve; + LocLLmaskexpCurve locllmasexpCurve; LocretigainCurverab locRETgainCurverab; locallutili = false; @@ -919,6 +921,8 @@ void Crop::update(int todo) lochhCurve.Set(params.locallab.spots.at(sp).HHcurve, HHutili); locccmasCurve.Set(params.locallab.spots.at(sp).CCmaskcurve, CCmaskutili); locllmasCurve.Set(params.locallab.spots.at(sp).LLmaskcurve, LLmaskutili); + locccmasexpCurve.Set(params.locallab.spots.at(sp).CCmaskexpcurve); + locllmasexpCurve.Set(params.locallab.spots.at(sp).LLmaskexpcurve); locallutili = false; CurveFactory::curveLocal(locallutili, params.locallab.spots.at(sp).llcurve, lllocalcurve2, sca); localcutili = false; @@ -948,7 +952,7 @@ void Crop::update(int todo) sca); parent->ipf.Lab_Local(1, sp, parent->sobelrefs, (float**)shbuffer, labnCrop, labnCrop, reservCrop, cropx / skip, cropy / skip, skips(parent->fw, skip), skips(parent->fh, skip), skip, locRETgainCurve, lllocalcurve2, - loclhCurve, lochhCurve, locccmasCurve, locllmasCurve, CCmaskutili, LLmaskutili, LHutili, HHutili, cclocalcurve2, localskutili, sklocalcurve2, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, lightCurveloc2, huerefblu, huere, chromare, lumare, sobelre); + loclhCurve, lochhCurve, locccmasCurve, locllmasCurve, locccmasexpCurve, locllmasexpCurve, CCmaskutili, LLmaskutili, LHutili, HHutili, cclocalcurve2, localskutili, sklocalcurve2, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, lightCurveloc2, huerefblu, huere, chromare, lumare, sobelre); lllocalcurve2.clear(); cclocalcurve2.clear(); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 992213ddb..1ef7630d8 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -788,6 +788,9 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) lochhCurve.Set(params.locallab.spots.at(sp).HHcurve, HHutili); locccmasCurve.Set(params.locallab.spots.at(sp).CCmaskcurve, CCmaskutili); locllmasCurve.Set(params.locallab.spots.at(sp).LLmaskcurve, LLmaskutili); + locccmasCurve.Set(params.locallab.spots.at(sp).CCmaskcurve, CCmaskutili); + locllmasexpCurve.Set(params.locallab.spots.at(sp).LLmaskexpcurve); + locccmasexpCurve.Set(params.locallab.spots.at(sp).CCmaskexpcurve); CurveFactory::curveLocal(locallutili, params.locallab.spots.at(sp).llcurve, lllocalcurve, sca); CurveFactory::curveCCLocal(localcutili, params.locallab.spots.at(sp).cccurve, cclocalcurve, sca); CurveFactory::curveskLocal(localskutili, params.locallab.spots.at(sp).skintonescurve, sklocalcurve, sca); @@ -825,7 +828,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) * - maxspot, huerefs, centerx and centery aren't used in Lab_Local (only for printf) so values aren't important * - shbuffer is used as nullptr */ - ipf.Lab_Local(3, sp, sobelrefs, (float**)shbuffer, nprevl, nprevl, reserv, 0, 0, pW, pH, scale, locRETgainCurve, lllocalcurve, loclhCurve, lochhCurve, locccmasCurve, locllmasCurve, CCmaskutili, LLmaskutili, + ipf.Lab_Local(3, sp, sobelrefs, (float**)shbuffer, nprevl, nprevl, reserv, 0, 0, pW, pH, scale, locRETgainCurve, lllocalcurve, loclhCurve, lochhCurve, locccmasCurve, locllmasCurve, locccmasexpCurve, locllmasexpCurve, CCmaskutili, LLmaskutili, LHutili, HHutili, cclocalcurve, localskutili, sklocalcurve, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerblu, huer, chromar, lumar, sobeler); if (params.locallab.spots.at(sp).spotMethod == "exc") { diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index ffa481487..d5cc0e10e 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -236,6 +236,8 @@ protected: LocHHCurve lochhCurve; LocCCmaskCurve locccmasCurve; LocLLmaskCurve locllmasCurve; + LocCCmaskexpCurve locccmasexpCurve; + LocLLmaskexpCurve locllmasexpCurve; ProcParams nextParams2; bool locallutili; bool localcutili; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index f9376832d..5221487d0 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -289,7 +289,7 @@ public: void calc_ref(int sp, LabImage* original, LabImage* transformed, int cx, int cy, int oW, int oH, int sk, double &huerefblur, double &huere, double &chromare, double &lumare, double &sobelref, LUTu & histogram); 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 sp, LUTf & sobelrefs, 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, const LocCCmaskCurve & locccmasCurve, const LocLLmaskCurve & locllmasCurve, bool CCmaskutili, bool LLmaskutili, 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 Lab_Local(int call, int sp, LUTf & sobelrefs, 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, const LocCCmaskCurve & locccmasCurve, const LocLLmaskCurve & locllmasCurve, const LocCCmaskexpCurve & locccmasexpCurve, const LocLLmaskexpCurve & locllmasexpCurve,bool CCmaskutili, bool LLmaskutili, 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); @@ -302,7 +302,7 @@ public: void vibrancelocal(int sp, int bfw, int bfh, LabImage* lab, LabImage* dest, bool & localskutili, LUTf & sklocalcurve); // void Expo_vibr_Local(float moddE, float powdE, int senstype, float **buflight, float **bufchro, 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 Expo_vibr_Local(float moddE, float powdE, int senstype, float **buflight, float **bufchro, 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, LabImage * difLab, const LabImage * const tmp1, int cx, int cy, int sk); + void Expo_vibr_Local(float moddE, float powdE, int senstype, LabImage * originalmask, float **buflight, float **bufchro, 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, LabImage * difLab, const LabImage * const tmp1, int cx, int cy, int sk); void exlabLocal(const local_params& lp, int bfh, int bfw, LabImage* bufexporig, LabImage* lab, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve); void Exclude_Local(float moddE, float powdE, int sen, float **deltaso, float **buflight, float **bufchro, 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, LabImage * rsv, LabImage * reserv, int cx, int cy, int sk); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 572527e13..3588d345a 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -401,6 +401,18 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.showmaskcolmet = 4; } + if (locallab.spots.at(sp).showmaskexpMethod == "none") { + lp.showmaskexpmet = 0; + } else if (locallab.spots.at(sp).showmaskexpMethod == "expo") { + lp.showmaskexpmet = 1; + } else if (locallab.spots.at(sp).showmaskexpMethod == "expomask") { + lp.showmaskexpmet = 2; + } else if (locallab.spots.at(sp).showmaskexpMethod == "mask") { + lp.showmaskexpmet = 3; + } else if (locallab.spots.at(sp).showmaskexpMethod == "showmask") { + lp.showmaskexpmet = 4; + } + if (locallab.spots.at(sp).showmaskexpMethod == "none") { lp.showmaskexpmet = 0; } else if (locallab.spots.at(sp).showmaskexpMethod == "expo") { @@ -5031,7 +5043,7 @@ void ImProcFunctions::Exclude_Local(float moddE, float powdE, int sen, float **d } -void ImProcFunctions::Expo_vibr_Local(float moddE, float powdE, int senstype, float **buflight, float **bufchro, 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, LabImage * difLab, const LabImage * const tmp1, int cx, int cy, int sk) +void ImProcFunctions::Expo_vibr_Local(float moddE, float powdE, int senstype, LabImage * originalmask, float **buflight, float **bufchro, 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, LabImage * difLab, const LabImage * const tmp1, int cx, int cy, int sk) { //local exposure and vibrance @@ -5098,8 +5110,21 @@ void ImProcFunctions::Expo_vibr_Local(float moddE, float powdE, int senstype, fl LabImage *origblur = nullptr; origblur = new LabImage(GW, GH); + LabImage *origblurmask = nullptr; float radius = 3.f / sk; + if (lp.showmaskexpmet >= 2 && senstype == 1) { + origblurmask = new LabImage(GW, GH); + +#ifdef _OPENMP + #pragma omp parallel +#endif + { + gaussianBlur(originalmask->L, origblurmask->L, GW, GH, radius); + gaussianBlur(originalmask->a, origblurmask->a, GW, GH, radius); + gaussianBlur(originalmask->b, origblurmask->b, GW, GH, radius); + } + } #ifdef _OPENMP #pragma omp parallel #endif @@ -5184,7 +5209,13 @@ void ImProcFunctions::Expo_vibr_Local(float moddE, float powdE, int senstype, fl float rchro = sqrt(SQR(origblur->b[y][x]) + SQR(origblur->a[y][x])) / 327.68f; #endif float rL = origblur->L[y][x] / 327.68f; - float dE = sqrt(SQR(refa - origblur->a[y][x] / 327.68f) + SQR(refb - origblur->b[y][x] / 327.68f) + SQR(lumaref - rL)); + + float dE = 0.f; + if (lp.showmaskexpmet >= 2 && senstype == 1) { + dE = sqrt(SQR(refa - origblurmask->a[y][x] / 327.68f) + SQR(refb - origblurmask->b[y][x] / 327.68f) + SQR(lumaref - origblurmask->L[y][x] / 327.68f)); + } else { + dE = sqrt(SQR(refa - origblur->a[y][x] / 327.68f) + SQR(refb - origblur->b[y][x] / 327.68f) + SQR(lumaref - rL)); + } float cli = 1.f; float clc = 1.f; @@ -5516,7 +5547,7 @@ void ImProcFunctions::Expo_vibr_Local(float moddE, float powdE, int senstype, fl transformed->a[y][x] = CLIPC(original->a[y][x] + difLab->a[loy - begy][lox - begx]); transformed->b[y][x] = CLIPC(original->b[y][x] + difLab->b[loy - begy][lox - begx]); - if (lp.showmaskexpmet == 1 && senstype == 1) { + if ((lp.showmaskexpmet == 1 || lp.showmaskexpmet == 2) && senstype == 1) { transformed->a[y][x] = difLab->a[loy - begy][lox - begx]; transformed->b[y][x] = difLab->b[loy - begy][lox - begx]; transformed->L[y][x] = 12000.f + difLab->L[loy - begy][lox - begx]; @@ -5553,7 +5584,7 @@ void ImProcFunctions::Expo_vibr_Local(float moddE, float powdE, int senstype, fl transformed->a[y][x] = CLIPC(original->a[y][x] + difLab->a[loy - begy][lox - begx]); transformed->b[y][x] = CLIPC(original->b[y][x] + difLab->b[loy - begy][lox - begx]); - if (lp.showmaskexpmet == 1 && senstype == 1) { + if ((lp.showmaskexpmet == 1 || lp.showmaskexpmet == 2) && senstype == 1) { transformed->a[y][x] = difLab->a[loy - begy][lox - begx]; transformed->b[y][x] = difLab->b[loy - begy][lox - begx]; transformed->L[y][x] = 12000.f + difLab->L[loy - begy][lox - begx]; @@ -5602,6 +5633,9 @@ void ImProcFunctions::Expo_vibr_Local(float moddE, float powdE, int senstype, fl } delete origblur; + if (lp.showmaskcolmet >= 2 && senstype == 1) { + delete origblurmask; + } } } @@ -7530,7 +7564,7 @@ void ImProcFunctions::fftw_denoise(int GW, int GH, int max_numblox_W, int min_nu void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, 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, const LocCCmaskCurve & locccmasCurve, const LocLLmaskCurve & locllmasCurve, bool CCmaskutili, bool LLmaskutili, + const LocretigainCurve & locRETgainCcurve, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, const LocCCmaskCurve & locccmasCurve, const LocLLmaskCurve & locllmasCurve, const LocCCmaskexpCurve & locccmasexpCurve, const LocLLmaskexpCurve & locllmasexpCurve, bool CCmaskutili, bool LLmaskutili, 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 @@ -9832,196 +9866,6 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu } - /* - if (lp.exposena && (lp.expcomp != 0.f || lp.war != 0 || (exlocalcurve && localexutili))) { //interior ellipse renforced lightness and chroma //locallutili - float hueplus = hueref + dhuev; - float huemoins = hueref - dhuev; - - - if (hueplus > rtengine::RT_PI) { - hueplus = hueref + dhuev - 2.f * rtengine::RT_PI; - } - - if (huemoins < -rtengine::RT_PI) { - huemoins = hueref - dhuev + 2.f * rtengine::RT_PI; - } - - LabImage *bufexporig = nullptr; - LabImage *bufexpfin = nullptr; - LabImage *bufexptemp = nullptr; - LabImage *difLab = nullptr; - LabImage *bufcat02fin = nullptr; - - int bfh = 0.f, bfw = 0.f; - bfh = int (lp.ly + lp.lyT) + del; //bfw bfh real size of square zone - bfw = int (lp.lx + lp.lxL) + del; - JaggedArray buflight(bfw, bfh); - JaggedArray bufl_ab(bfw, bfh); - JaggedArray buflightcurv(bfw, bfh); - JaggedArray buf_a_cat(bfw, bfh, true); - JaggedArray buf_b_cat(bfw, bfh, true); - - - if (call <= 3) { //simpleprocess, dcrop, improccoordinator - - - bufexporig = new LabImage(bfw, bfh); //buffer for data in zone limit - bufexpfin = new LabImage(bfw, bfh); //buffer for data in zone limit - bufexptemp = new LabImage(bfw, bfh); //buffer for data in zone limit - difLab = new LabImage(bfw, bfh); //buffer for data in zone limit - bufcat02fin = new LabImage(bfw, bfh); //buffer for data in zone limit - - - #ifdef _OPENMP - #pragma omp parallel for - #endif - - for (int ir = 0; ir < bfh; ir++) //fill with 0 - for (int jr = 0; jr < bfw; jr++) { - bufexporig->L[ir][jr] = 0.f; - bufexporig->a[ir][jr] = 0.f; - bufexporig->b[ir][jr] = 0.f; - bufexptemp->L[ir][jr] = 0.f; - bufexptemp->a[ir][jr] = 0.f; - bufexptemp->b[ir][jr] = 0.f; - bufexpfin->L[ir][jr] = 0.f; - bufexpfin->a[ir][jr] = 0.f; - bufexpfin->b[ir][jr] = 0.f; - bufcat02fin->L[ir][jr] = 0.f; - bufcat02fin->a[ir][jr] = 0.f; - bufcat02fin->b[ir][jr] = 0.f; - buflight[ir][jr] = 0.f; - bufl_ab[ir][jr] = 0.f; - buflightcurv[ir][jr] = 0.f; - buf_a_cat[ir][jr] = 0.f; - buf_b_cat[ir][jr] = 0.f; - } - - int begy = lp.yc - lp.lyT; - int begx = lp.xc - lp.lxL; - int yEn = lp.yc + lp.ly; - int xEn = lp.xc + lp.lx; - - #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) - #endif - - for (int y = 0; y < transformed->H ; y++) //{ - for (int x = 0; x < transformed->W; x++) { - int lox = cx + x; - int loy = cy + y; - - if (lox >= begx && lox < xEn && loy >= begy && loy < yEn) { - - bufexporig->L[loy - begy][lox - begx] = original->L[y][x];//fill square buffer with datas - bufexporig->a[loy - begy][lox - begx] = original->a[y][x];//fill square buffer with datas - bufexporig->b[loy - begy][lox - begx] = original->b[y][x];//fill square buffer with datas - bufexptemp->L[loy - begy][lox - begx] = original->L[y][x];//fill square buffer with datas - bufexptemp->a[loy - begy][lox - begx] = original->a[y][x];//fill square buffer with datas - bufexptemp->b[loy - begy][lox - begx] = original->b[y][x];//fill square buffer with datas - bufexpfin->L[loy - begy][lox - begx] = original->L[y][x];//fill square buffer with datas - bufexpfin->a[loy - begy][lox - begx] = original->a[y][x];//fill square buffer with datas - bufexpfin->b[loy - begy][lox - begx] = original->b[y][x];//fill square buffer with datas - } - } - - //to do Modulate bufexporig and bufexptemp with blend L, H, C and masks - - - if (exlocalcurve && localexutili) {// L=f(L) curve enhanced - #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) - #endif - - for (int y = 0; y < transformed->H ; y++) //{ - for (int x = 0; x < transformed->W; x++) { - int lox = cx + x; - int loy = cy + y; - - if (lox >= begx && lox < xEn && loy >= begy && loy < yEn) { - - float lighn = bufexporig->L[loy - begy][lox - begx]; - - float lh; - lh = 0.5f * exlocalcurve[2.f * lighn]; // / ((lighn) / 1.9f) / 3.61f; //lh between 0 and 0 50 or more - bufexptemp->L[loy - begy][lox - begx] = lh; - } - } - - if (lp.expcomp == 0.f) { - lp.expcomp = 0.1f; // to enabled - } - - ImProcFunctions::exlabLocal(lp, bfh, bfw, bufexptemp, bufexpfin, hltonecurveloc, shtonecurveloc, tonecurveloc); - - - } else { - - ImProcFunctions::exlabLocal(lp, bfh, bfw, bufexporig, bufexpfin, hltonecurveloc, shtonecurveloc, tonecurveloc); - } - - //cat02 - if (params->locallab.spots.at(sp).warm != 0) { - ImProcFunctions::ciecamloc_02float(sp, bufexpfin, bufcat02fin); - } else { - #ifdef _OPENMP - #pragma omp parallel for - #endif - - for (int ir = 0; ir < bfh; ir++) - for (int jr = 0; jr < bfw; jr++) { - bufcat02fin->L[ir][jr] = bufexpfin->L[ir][jr]; - bufcat02fin->a[ir][jr] = bufexpfin->a[ir][jr]; - bufcat02fin->b[ir][jr] = bufexpfin->b[ir][jr]; - } - } - - - - #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) - #endif - - for (int y = 0; y < transformed->H ; y++) //{ - for (int x = 0; x < transformed->W; x++) { - int lox = cx + x; - int loy = cy + y; - - if (lox >= begx && lox < xEn && loy >= begy && loy < yEn) { - - float rL; - rL = CLIPRET((bufcat02fin->L[loy - begy][lox - begx] - bufexporig->L[loy - begy][lox - begx]) / 328.f); - - buflight[loy - begy][lox - begx] = rL; - float rA; - rA = CLIPRET((bufcat02fin->a[loy - begy][lox - begx] - bufexporig->a[loy - begy][lox - begx]) / 328.f); - buf_a_cat[loy - begy][lox - begx] = rA; - - - float rB; - rB = CLIPRET((bufcat02fin->b[loy - begy][lox - begx] - bufexporig->b[loy - begy][lox - begx]) / 328.f); - buf_b_cat[loy - begy][lox - begx] = rB; - - - } - } - - Expo_vibr_Local(moddE, powdE, 1, buflight, bufl_ab, buf_a_cat, buf_b_cat, hueplus, huemoins, hueref, dhueex, chromaref, lumaref, lp, original, transformed, difLab, bufcat02fin, cx, cy, sk); - //view mask - } - - if (call <= 3) { - - delete bufexporig; - delete bufexpfin; - delete bufexptemp; - delete difLab; - delete bufcat02fin; - } - - } - */ - //vibrance @@ -10130,7 +9974,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu } } - Expo_vibr_Local(moddE, powdE, 2, buflight, bufl_ab, nullptr, nullptr, hueplus, huemoins, hueref, dhuev, chromaref, lumaref, lp, original, transformed, difLab, bufexpfin, cx, cy, sk); + Expo_vibr_Local(moddE, powdE, 2, nullptr, buflight, bufl_ab, nullptr, nullptr, hueplus, huemoins, hueref, dhuev, chromaref, lumaref, lp, original, transformed, difLab, bufexpfin, cx, cy, sk); //call Expo_vibr_Local with first parameter = 2 for vibrance } @@ -10503,7 +10347,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu } } - Expo_vibr_Local(moddE, powdE, 3, buflight, bufl_ab, nullptr, nullptr, hueplus, huemoins, hueref, dhuesf, chromaref, lumaref, lp, original, transformed, difLab, bufexpfin, cx, cy, sk); + Expo_vibr_Local(moddE, powdE, 3, nullptr, buflight, bufl_ab, nullptr, nullptr, hueplus, huemoins, hueref, dhuesf, chromaref, lumaref, lp, original, transformed, difLab, bufexpfin, cx, cy, sk); } @@ -11261,7 +11105,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu - if (lp.exposena && (lp.expcomp != 0.f || lp.war != 0 || (exlocalcurve && localexutili))) { //interior ellipse renforced lightness and chroma //locallutili + if (lp.exposena && (lp.expcomp != 0.f || lp.war != 0 || lp.showmaskexpmet >= 2 || (exlocalcurve && localexutili))) { //interior ellipse renforced lightness and chroma //locallutili float hueplus = hueref + dhuev; float huemoins = hueref - dhuev; @@ -11279,6 +11123,9 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu LabImage *bufexptemp = nullptr; LabImage *difLab = nullptr; LabImage *bufcat02fin = nullptr; + LabImage *bufmaskorig = nullptr; + LabImage *bufmaskblur = nullptr; + LabImage *originalmask = nullptr; int bfh = 0.f, bfw = 0.f; bfh = int (lp.ly + lp.lyT) + del; //bfw bfh real size of square zone @@ -11298,6 +11145,8 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu bufexptemp = new LabImage(bfw, bfh); //buffer for data in zone limit difLab = new LabImage(bfw, bfh); //buffer for data in zone limit bufcat02fin = new LabImage(bfw, bfh); //buffer for data in zone limit + bufmaskorig = new LabImage(bfw, bfh); + bufmaskblur = new LabImage(bfw, bfh); #ifdef _OPENMP @@ -11309,6 +11158,9 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu bufexporig->L[ir][jr] = 0.f; bufexporig->a[ir][jr] = 0.f; bufexporig->b[ir][jr] = 0.f; + bufmaskorig->L[ir][jr] = 0.f; + bufmaskorig->a[ir][jr] = 0.f; + bufmaskorig->b[ir][jr] = 0.f; bufexptemp->L[ir][jr] = 0.f; bufexptemp->a[ir][jr] = 0.f; bufexptemp->b[ir][jr] = 0.f; @@ -11329,6 +11181,137 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu int begx = lp.xc - lp.lxL; int yEn = lp.yc + lp.ly; int xEn = lp.xc + lp.lx; + + + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int y = 0; y < transformed->H ; y++) //{ + for (int x = 0; x < transformed->W; x++) { + int lox = cx + x; + int loy = cy + y; + + if (lox >= begx && lox < xEn && loy >= begy && loy < yEn) { + bufmaskorig->L[loy - begy][lox - begx] = original->L[y][x]; + bufmaskorig->a[loy - begy][lox - begx] = original->a[y][x]; + bufmaskorig->b[loy - begy][lox - begx] = original->b[y][x]; + bufexporig->L[loy - begy][lox - begx] = original->L[y][x]; + bufexporig->a[loy - begy][lox - begx] = original->a[y][x]; + bufexporig->b[loy - begy][lox - begx] = original->b[y][x]; + bufmaskblur->L[loy - begy][lox - begx] = original->L[y][x]; + bufmaskblur->a[loy - begy][lox - begx] = original->a[y][x]; + bufmaskblur->b[loy - begy][lox - begx] = original->b[y][x]; + + float valLL = 0.f; + float valCC = 0.f; + float2 sincosval; + + if (lp.showmaskexpmet >= 2) { + if (locllmasexpCurve) { + valLL = (float)(locllmasexpCurve[500.f * (bufexporig->L[loy - begy][lox - begx]) / 32768.f]); + valLL = 1.f - valLL; + bufmaskblur->L[loy - begy][lox - begx] = 32768.f * valLL; + } + + if (locccmasexpCurve) { + float chromask = (sqrt(SQR(bufexporig->a[loy - begy][lox - begx]) + SQR(bufexporig->b[loy - begy][lox - begx]))); + float chromaskr = chromask / 50000.f; + valCC = float (locccmasexpCurve[500.f * chromaskr]); + valCC = 1.f - valCC; + sincosval.y = (bufexporig->a[loy - begy][lox - begx]) / chromask; + sincosval.x = (bufexporig->b[loy - begy][lox - begx]) / chromask; + bufmaskblur->a[loy - begy][lox - begx] = 50000.f * valCC * sincosval.y; + bufmaskblur->b[loy - begy][lox - begx] = 50000.f * valCC * sincosval.x; + } + } + } + } + + float radiusb = 3.f / sk; + + if (lp.showmaskexpmet >= 2) { + +#ifdef _OPENMP + #pragma omp parallel +#endif + { + gaussianBlur(bufmaskblur->L, bufmaskorig->L, bfw, bfh, radiusb); + gaussianBlur(bufmaskblur->a, bufmaskorig->a, bfw, bfh, radiusb); + gaussianBlur(bufmaskblur->b, bufmaskorig->b, bfw, bfh, radiusb); + } + int GWm = transformed->W; + int GHm = transformed->H; + + + originalmask = new LabImage(GWm, GHm); + + if (lp.showmaskexpmet == 2 || lp.showmaskexpmet == 3) { + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int y = 0; y < transformed->H ; y++) //{ + for (int x = 0; x < transformed->W; x++) { + int lox = cx + x; + int loy = cy + y; + int zone = 0; + + float localFactor = 1.f; + const float achm = (float)lp.trans / 100.f; + + if (lp.shapmet == 0) { + calcTransition(lox, loy, achm, lp, zone, localFactor); + } else if (lp.shapmet == 1) { + calcTransitionrect(lox, loy, achm, lp, zone, localFactor); + } + + if (lox >= begx && lox < xEn && loy >= begy && loy < yEn) { + if(zone > 0) { + bufexporig->L[loy - begy][lox - begx] -= bufmaskorig->L[loy - begy][lox - begx]; + bufexporig->a[loy - begy][lox - begx] -= bufmaskorig->a[loy - begy][lox - begx]; + bufexporig->b[loy - begy][lox - begx] -= bufmaskorig->b[loy - begy][lox - begx]; + originalmask->L[y][x] = bufexporig->L[loy - begy][lox - begx]; + originalmask->a[y][x] = bufexporig->a[loy - begy][lox - begx]; + originalmask->b[y][x] = bufexporig->L[loy - begy][lox - begx]; + } + } + } + } else if (lp.showmaskexpmet == 4) { +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int y = 0; y < transformed->H ; y++) //{ + for (int x = 0; x < transformed->W; x++) { + int lox = cx + x; + int loy = cy + y; + int zone = 0; + float localFactor = 1.f; + const float achm = (float)lp.trans / 100.f; + + if (lp.shapmet == 0) { + calcTransition(lox, loy, achm, lp, zone, localFactor); + } else if (lp.shapmet == 1) { + calcTransitionrect(lox, loy, achm, lp, zone, localFactor); + } + + if (lox >= begx && lox < xEn && loy >= begy && loy < yEn) { + if(zone > 0) { + transformed->L[y][x] = bufmaskorig->L[loy - begy][lox - begx]; + transformed->a[y][x] = bufmaskorig->a[loy - begy][lox - begx]; + transformed->b[y][x] = bufmaskorig->b[loy - begy][lox - begx]; + } + } + } + + } + } + + + if (lp.showmaskexpmet != 4) { #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) @@ -11341,9 +11324,9 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu if (lox >= begx && lox < xEn && loy >= begy && loy < yEn) { - bufexporig->L[loy - begy][lox - begx] = original->L[y][x];//fill square buffer with datas - bufexporig->a[loy - begy][lox - begx] = original->a[y][x];//fill square buffer with datas - bufexporig->b[loy - begy][lox - begx] = original->b[y][x];//fill square buffer with datas + // bufexporig->L[loy - begy][lox - begx] = original->L[y][x];//fill square buffer with datas + // bufexporig->a[loy - begy][lox - begx] = original->a[y][x];//fill square buffer with datas + // bufexporig->b[loy - begy][lox - begx] = original->b[y][x];//fill square buffer with datas bufexptemp->L[loy - begy][lox - begx] = original->L[y][x];//fill square buffer with datas bufexptemp->a[loy - begy][lox - begx] = original->a[y][x];//fill square buffer with datas bufexptemp->b[loy - begy][lox - begx] = original->b[y][x];//fill square buffer with datas @@ -11433,8 +11416,8 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu } } - - Expo_vibr_Local(moddE, powdE, 1, buflight, bufl_ab, buf_a_cat, buf_b_cat, hueplus, huemoins, hueref, dhueex, chromaref, lumaref, lp, original, transformed, difLab, bufcat02fin, cx, cy, sk); + } + Expo_vibr_Local(moddE, powdE, 1, originalmask, buflight, bufl_ab, buf_a_cat, buf_b_cat, hueplus, huemoins, hueref, dhueex, chromaref, lumaref, lp, original, transformed, difLab, bufcat02fin, cx, cy, sk); //view mask } @@ -11445,6 +11428,9 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu delete bufexptemp; delete difLab; delete bufcat02fin; + delete bufmaskorig; + delete bufmaskblur; + delete originalmask; } } diff --git a/rtengine/procevents.h b/rtengine/procevents.h index ea9da6b97..93ae4b7a8 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -635,6 +635,8 @@ enum ProcEventCode { EvlocallabshowmaskexpMethod = 605, EvlocallabCCmaskshape = 606, EvlocallabLLmaskshape = 607, + EvlocallabCCmaskexpshape = 608, + EvlocallabLLmaskexpshape = 609, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index de5450d6f..c886477c0 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2383,6 +2383,9 @@ LocallabParams::LocallabSpot::LocallabSpot() : sensiex(19), excurve{(double)DCT_NURBS, 0.0, 0.0, 1.0, 1.0}, showmaskexpMethod("none"), + CCmaskexpcurve{(double)FCT_MinMaxCPoints, 0., 1., 0.35, 0.35, 1., 1., 0.35, 0.35}, + LLmaskexpcurve{(double)FCT_MinMaxCPoints, 0., 1., 0.35, 0.35, 1., 1., 0.35, 0.35}, + // Vibrance expvibrance(false), saturated(0), @@ -2515,6 +2518,8 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && sensiex == other.sensiex && excurve == other.excurve && showmaskexpMethod == other.showmaskexpMethod + && CCmaskexpcurve == other.CCmaskexpcurve + && LLmaskexpcurve == other.LLmaskexpcurve // Vibrance && expvibrance == other.expvibrance && saturated == other.saturated @@ -3600,6 +3605,8 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->locallab.spots.at(i).sensiex, "Locallab", "Sensiex_" + std::to_string(i), spot.sensiex, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).excurve, "Locallab", "ExCurve_" + std::to_string(i), spot.excurve, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).showmaskexpMethod, "Locallab", "ShowmaskexpMethod_" + std::to_string(i), spot.showmaskexpMethod, keyFile); + saveToKeyfile(!pedited || pedited->locallab.spots.at(i).CCmaskexpcurve, "Locallab", "CCmaskexpCurve_" + std::to_string(i), spot.CCmaskexpcurve, keyFile); + saveToKeyfile(!pedited || pedited->locallab.spots.at(i).LLmaskexpcurve, "Locallab", "LLmaskexpCurve_" + std::to_string(i), spot.LLmaskexpcurve, keyFile); // Vibrance saveToKeyfile(!pedited || pedited->locallab.spots.at(i).expvibrance, "Locallab", "Expvibrance_" + std::to_string(i), spot.expvibrance, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).saturated, "Locallab", "Saturated_" + std::to_string(i), spot.saturated, keyFile); @@ -4812,6 +4819,8 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Sensiex_" + std::to_string(i), pedited, spot.sensiex, spotEdited.sensiex); assignFromKeyfile(keyFile, "Locallab", "ExCurve_" + std::to_string(i), pedited, spot.excurve, spotEdited.excurve); assignFromKeyfile(keyFile, "Locallab", "ShowmaskexpMethod_" + std::to_string(i), pedited, spot.showmaskexpMethod, spotEdited.showmaskexpMethod); + assignFromKeyfile(keyFile, "Locallab", "CCmaskexpCurve_" + std::to_string(i), pedited, spot.CCmaskexpcurve, spotEdited.CCmaskexpcurve); + assignFromKeyfile(keyFile, "Locallab", "LLmaskexpCurve_" + std::to_string(i), pedited, spot.LLmaskexpcurve, spotEdited.LLmaskexpcurve); // Vibrance assignFromKeyfile(keyFile, "Locallab", "Expvibrance_" + std::to_string(i), pedited, spot.expvibrance, spotEdited.expvibrance); assignFromKeyfile(keyFile, "Locallab", "Saturated_" + std::to_string(i), pedited, spot.saturated, spotEdited.saturated); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 94c25a80b..dc6139331 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -978,6 +978,8 @@ struct LocallabParams { int sensiex; std::vector excurve; Glib::ustring showmaskexpMethod; + std::vector CCmaskexpcurve; + std::vector LLmaskexpcurve; // Vibrance bool expvibrance; int saturated; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 50846958d..52735527d 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -634,7 +634,9 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, //EvlocallabshowmaskcolMethod LUMINANCECURVE, //EvlocallabshowmaskexpMethod LUMINANCECURVE, //EvlocallabCCmaskshape - LUMINANCECURVE //EvlocallabLLmaskshape + LUMINANCECURVE, //EvlocallabLLmaskshape + LUMINANCECURVE, //EvlocallabCCmaskexpshape + LUMINANCECURVE //EvlocallabLLmaskexpshape }; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 82b1819b4..4e41fdae6 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1076,6 +1076,8 @@ private: LocHHCurve lochhCurve; LocCCmaskCurve locccmasCurve; LocLLmaskCurve locllmasCurve; + LocCCmaskexpCurve locccmasexpCurve; + LocLLmaskexpCurve locllmasexpCurve; LUTf lllocalcurve(65536, 0); LUTf cclocalcurve(65536, 0); LUTf sklocalcurve(65536, 0); @@ -1137,7 +1139,7 @@ private: hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, 1); - ipf.Lab_Local(2, sp, sobelrefs, (float**)shbuffer, labView, labView, reservView, 0, 0, fw, fh, 1, locRETgainCurve, lllocalcurve, loclhCurve, lochhCurve, locccmasCurve, locllmasCurve, CCmaskutili, LLmaskutili, + ipf.Lab_Local(2, sp, sobelrefs, (float**)shbuffer, labView, labView, reservView, 0, 0, fw, fh, 1, locRETgainCurve, lllocalcurve, loclhCurve, lochhCurve, locccmasCurve, locllmasCurve, locccmasexpCurve, locllmasexpCurve, CCmaskutili, LLmaskutili, LHutili, HHutili, cclocalcurve, localskutili, sklocalcurve, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerefblu, huere, chromare, lumare, sobelre); // Clear local curves diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index be06fd31f..c28e2f935 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -64,6 +64,7 @@ Locallab::Locallab(): maskCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK"))), // Exposure curveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_CURVEEDITOR_TONES_LABEL"))), + maskexpCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK"))), // Vibrance curveEditorGG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL"))), // Retinex @@ -366,17 +367,38 @@ Locallab::Locallab(): shapeexpos->setLeftBarBgGradient(mshapeexpos); curveEditorG->curveListComplete(); + maskexpCurveEditorG->setCurveListener(this); + showmaskexpMethod->append(M("TP_LOCALLAB_SHOWMNONE")); - showmaskexpMethod->append(M("TP_LOCALLAB_SHOWMAK1")); + showmaskexpMethod->append(M("TP_LOCALLAB_SHOWMODIF")); + showmaskexpMethod->append(M("TP_LOCALLAB_SHOWMODIFMASK")); + showmaskexpMethod->append(M("TP_LOCALLAB_USEMASK")); + showmaskexpMethod->append(M("TP_LOCALLAB_SHOWMASK")); showmaskexpMethod->set_active(0); showmaskexpMethod->set_tooltip_markup(M("TP_LOCALLAB_SHOWMASKCOL_TOOLTIP")); showmaskexpMethodConn = showmaskexpMethod->signal_changed().connect(sigc::mem_fun(*this, &Locallab::showmaskexpMethodChanged)); + CCmaskexpshape = static_cast(maskexpCurveEditorG->addCurve(CT_Flat, "C(C)", nullptr, false, false)); + CCmaskexpshape->setIdentityValue(0.); + CCmaskexpshape->setResetCurve(FlatCurveType(defSpot.CCmaskexpcurve.at(0)), defSpot.CCmaskexpcurve); + CCmaskexpshape->setTooltip(M("TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP")); + CCmaskexpshape->setBottomBarColorProvider(this, 7); + + LLmaskexpshape = static_cast(maskexpCurveEditorG->addCurve(CT_Flat, "L(L)", nullptr, false, false)); + LLmaskexpshape->setIdentityValue(0.); + LLmaskexpshape->setResetCurve(FlatCurveType(defSpot.CCmaskexpcurve.at(0)), defSpot.CCmaskexpcurve); + LLmaskexpshape->setTooltip(M("TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP")); + LLmaskexpshape->setBottomBarBgGradient(mllshape); + + maskexpCurveEditorG->curveListComplete(); + + maskexpFrame = Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_SHOW"))); maskexpFrame->set_label_align(0.025, 0.5); ToolParamBlock* const maskexpBox = Gtk::manage(new ToolParamBlock()); maskexpBox->pack_start(*showmaskexpMethod, Gtk::PACK_SHRINK, 0); + maskexpBox->pack_start(*maskexpCurveEditorG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor maskexpFrame->add(*maskexpBox); @@ -1423,7 +1445,15 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pp->locallab.spots.at(pp->locallab.selspot).showmaskexpMethod = "none"; } else if (showmaskexpMethod->get_active_row_number() == 1) { pp->locallab.spots.at(pp->locallab.selspot).showmaskexpMethod = "expo"; + } else if (showmaskexpMethod->get_active_row_number() == 2) { + pp->locallab.spots.at(pp->locallab.selspot).showmaskexpMethod = "expomask"; + } else if (showmaskexpMethod->get_active_row_number() == 3) { + pp->locallab.spots.at(pp->locallab.selspot).showmaskexpMethod = "mask"; + } else if (showmaskexpMethod->get_active_row_number() == 4) { + pp->locallab.spots.at(pp->locallab.selspot).showmaskexpMethod = "showmask"; } + pp->locallab.spots.at(pp->locallab.selspot).LLmaskexpcurve = LLmaskexpshape->getCurve(); + pp->locallab.spots.at(pp->locallab.selspot).CCmaskexpcurve = CCmaskexpshape->getCurve(); // Vibrance pp->locallab.spots.at(pp->locallab.selspot).expvibrance = expvibrance->getEnabled(); @@ -1575,6 +1605,8 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pe->locallab.spots.at(pp->locallab.selspot).sensiex = pe->locallab.spots.at(pp->locallab.selspot).sensiex || sensiex->getEditedState(); pe->locallab.spots.at(pp->locallab.selspot).excurve = pe->locallab.spots.at(pp->locallab.selspot).excurve || !shapeexpos->isUnChanged(); pe->locallab.spots.at(pp->locallab.selspot).showmaskexpMethod = pe->locallab.spots.at(pp->locallab.selspot).showmaskexpMethod || showmaskexpMethod->get_active_text() != M("GENERAL_UNCHANGED"); + pe->locallab.spots.at(pp->locallab.selspot).CCmaskexpcurve = pe->locallab.spots.at(pp->locallab.selspot).CCmaskexpcurve || !CCmaskexpshape->isUnChanged(); + pe->locallab.spots.at(pp->locallab.selspot).LLmaskexpcurve = pe->locallab.spots.at(pp->locallab.selspot).LLmaskexpcurve || !LLmaskexpshape->isUnChanged(); // Vibrance pe->locallab.spots.at(pp->locallab.selspot).expvibrance = pe->locallab.spots.at(pp->locallab.selspot).expvibrance || !expvibrance->get_inconsistent(); pe->locallab.spots.at(pp->locallab.selspot).saturated = pe->locallab.spots.at(pp->locallab.selspot).saturated || saturated->getEditedState(); @@ -1712,6 +1744,8 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pedited->locallab.spots.at(pp->locallab.selspot).sensiex = pedited->locallab.spots.at(pp->locallab.selspot).sensiex || sensiex->getEditedState(); pedited->locallab.spots.at(pp->locallab.selspot).excurve = pedited->locallab.spots.at(pp->locallab.selspot).excurve || !shapeexpos->isUnChanged(); pedited->locallab.spots.at(pp->locallab.selspot).showmaskexpMethod = pedited->locallab.spots.at(pp->locallab.selspot).showmaskexpMethod || showmaskexpMethod->get_active_text() != M("GENERAL_UNCHANGED"); + pedited->locallab.spots.at(pp->locallab.selspot).CCmaskexpcurve = pedited->locallab.spots.at(pp->locallab.selspot).CCmaskexpcurve || !CCmaskexpshape->isUnChanged(); + pedited->locallab.spots.at(pp->locallab.selspot).LLmaskexpcurve = pedited->locallab.spots.at(pp->locallab.selspot).LLmaskexpcurve || !LLmaskexpshape->isUnChanged(); // Vibrance pedited->locallab.spots.at(pp->locallab.selspot).expvibrance = pedited->locallab.spots.at(pp->locallab.selspot).expvibrance || !expvibrance->get_inconsistent(); pedited->locallab.spots.at(pp->locallab.selspot).saturated = pedited->locallab.spots.at(pp->locallab.selspot).saturated || saturated->getEditedState(); @@ -1933,7 +1967,7 @@ void Locallab::curveChanged(CurveEditor* ce) listener->panelChanged(EvlocallabLLmaskshape, M("HISTORY_CUSTOMCURVE")); } } - + } // Exposure @@ -1943,6 +1977,19 @@ void Locallab::curveChanged(CurveEditor* ce) listener->panelChanged(Evlocallabshapeexpos, M("HISTORY_CUSTOMCURVE")); } } + + if (ce == CCmaskexpshape) { + if (listener) { + listener->panelChanged(EvlocallabCCmaskexpshape, M("HISTORY_CUSTOMCURVE")); + } + } + + if (ce == LLmaskexpshape) { + if (listener) { + listener->panelChanged(EvlocallabLLmaskexpshape, M("HISTORY_CUSTOMCURVE")); + } + } + } // Vibrance @@ -3361,7 +3408,15 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con showmaskexpMethod->set_active(0); } else if (pp->locallab.spots.at(index).showmaskexpMethod == "expo") { showmaskexpMethod->set_active(1); + } else if (pp->locallab.spots.at(index).showmaskexpMethod == "expormask") { + showmaskexpMethod->set_active(2); + } else if (pp->locallab.spots.at(index).showmaskexpMethod == "mask") { + showmaskexpMethod->set_active(3); + } else if (pp->locallab.spots.at(index).showmaskexpMethod == "showmask") { + showmaskexpMethod->set_active(4); } + CCmaskexpshape->setCurve(pp->locallab.spots.at(index).CCmaskexpcurve); + LLmaskexpshape->setCurve(pp->locallab.spots.at(index).LLmaskexpcurve); // Vibrance expvibrance->setEnabled(pp->locallab.spots.at(index).expvibrance); @@ -3543,6 +3598,8 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con if (!spotState->showmaskexpMethod) { showmaskexpMethod->set_active_text(M("GENERAL_UNCHANGED")); } + CCmaskexpshape->setUnChanged(!spotState->CCmaskexpcurve); + LLmaskexpshape->setUnChanged(!spotState->LLmaskexpcurve); // Vibrance expvibrance->set_inconsistent(!spotState->expvibrance); @@ -3759,5 +3816,6 @@ void Locallab::autoOpenCurve() HHshape->openIfNonlinear(); CCmaskshape->openIfNonlinear(); LLmaskshape->openIfNonlinear(); - + CCmaskexpshape->openIfNonlinear(); + LLmaskexpshape->openIfNonlinear(); } diff --git a/rtgui/locallab.h b/rtgui/locallab.h index d7d0c84e1..dca7909bc 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -71,7 +71,10 @@ private: // Exposure CurveEditorGroup* const curveEditorG; + CurveEditorGroup* const maskexpCurveEditorG; DiagonalCurveEditor* shapeexpos; + FlatCurveEditor* CCmaskexpshape; + FlatCurveEditor* LLmaskexpshape; // Vibrance CurveEditorGroup* const curveEditorGG; DiagonalCurveEditor* skinTonesCurve; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index de8c81fd7..2b7e7522a 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -968,6 +968,8 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).sensiex = locallab.spots.at(j).sensiex && pSpot.sensiex == otherSpot.sensiex; locallab.spots.at(j).excurve = locallab.spots.at(j).excurve && pSpot.excurve == otherSpot.excurve; locallab.spots.at(j).showmaskexpMethod = locallab.spots.at(j).showmaskexpMethod && pSpot.showmaskexpMethod == otherSpot.showmaskexpMethod; + locallab.spots.at(j).CCmaskexpcurve = locallab.spots.at(j).CCmaskexpcurve && pSpot.CCmaskexpcurve == otherSpot.CCmaskexpcurve; + locallab.spots.at(j).LLmaskexpcurve = locallab.spots.at(j).LLmaskexpcurve && pSpot.LLmaskexpcurve == otherSpot.LLmaskexpcurve; // Vibrance locallab.spots.at(j).expvibrance = locallab.spots.at(j).expvibrance && pSpot.expvibrance == otherSpot.expvibrance; locallab.spots.at(j).saturated = locallab.spots.at(j).saturated && pSpot.saturated == otherSpot.saturated; @@ -2649,6 +2651,14 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).showmaskexpMethod = mods.locallab.spots.at(i).showmaskexpMethod; } + if (locallab.spots.at(i).CCmaskexpcurve) { + toEdit.locallab.spots.at(i).CCmaskexpcurve = mods.locallab.spots.at(i).CCmaskexpcurve; + } + + if (locallab.spots.at(i).LLmaskexpcurve) { + toEdit.locallab.spots.at(i).LLmaskexpcurve = mods.locallab.spots.at(i).LLmaskexpcurve; + } + // Vibrance if (locallab.spots.at(i).expvibrance) { toEdit.locallab.spots.at(i).expvibrance = mods.locallab.spots.at(i).expvibrance; @@ -3920,6 +3930,8 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : sensiex(v), excurve(v), showmaskexpMethod(v), + CCmaskexpcurve(v), + LLmaskexpcurve(v), // Vibrance expvibrance(v), saturated(v), @@ -4049,6 +4061,8 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) sensiex = v; excurve = v; showmaskexpMethod = v; + CCmaskexpcurve = v; + LLmaskexpcurve = v; // Vibrance expvibrance = v; saturated = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 79f638887..7436f663d 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -507,6 +507,8 @@ public: bool sensiex; bool excurve; bool showmaskexpMethod; + bool CCmaskexpcurve; + bool LLmaskexpcurve; // Vibrance bool expvibrance; bool saturated;