diff --git a/rtdata/languages/default b/rtdata/languages/default index ae48a0156..a51999ede 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -863,6 +863,7 @@ 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_611;Local - Color Mask H HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -1974,7 +1975,7 @@ TP_LOCALLAB_EXNORM;Normal spot TP_LOCALLAB_EXECLU;Excluding spot TP_LOCALLAB_EXPOSE;Exposure TP_LOCALLAB_LOC_CONTRAST;Local contrast -TP_LOCALLAB_REFLABEL;Reference (0..1) Chroma=%1 Luma=%2 +TP_LOCALLAB_REFLABEL;Ref. (0..1) Chroma=%1 Luma=%2 Hue=%3 TP_LOCALLAB_NOISELUMFINE;Luminance fine (Wav) TP_LOCALLAB_NOISELUMCOARSE;Luminance coarse (Wav) TP_LOCALLAB_NOISELUMDETAIL;Luminance detail (DCT) diff --git a/rtengine/curves.cc b/rtengine/curves.cc index 96fcfea0f..dbd07db70 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -1663,6 +1663,55 @@ void LocCCmaskexpCurve::Set(const std::vector &curvePoints) } } +LocHHmaskCurve::LocHHmaskCurve() : sum(0.f) {}; + +void LocHHmaskCurve::Reset() +{ + lutLocHHmaskCurve.reset(); + sum = 0.f; +} + + +void LocHHmaskCurve::Set(const Curve &pCurve) +{ + if (pCurve.isIdentity()) { + Reset(); // raise this value if the quality suffers from this number of samples + return; + } + + lutLocHHmaskCurve(501); // raise this value if the quality suffers from this number of samples + sum = 0.f; + + for (int i = 0; i < 501; i++) { + lutLocHHmaskCurve[i] = pCurve.getVal(double (i) / 500.); + + if (lutLocHHmaskCurve[i] < 0.02f) { + lutLocHHmaskCurve[i] = 0.02f; + } + + sum += lutLocHHmaskCurve[i]; + } + + //lutLocHHCurve.dump("wav"); +} + + + +void LocHHmaskCurve::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) {}; void LocCCmaskCurve::Reset() diff --git a/rtengine/curves.h b/rtengine/curves.h index ca2d1040d..b078d4e68 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -688,6 +688,33 @@ public: } }; +class LocHHmaskCurve +{ +private: + LUTf lutLocHHmaskCurve; // 0xffff range + void Set(const Curve &pCurve); + +public: + float sum; + + virtual ~LocHHmaskCurve() {}; + LocHHmaskCurve(); + void Reset(); + void Set(const std::vector &curvePoints); + float getSum() const + { + return sum; + } + + float operator[](float index) const + { + return lutLocHHmaskCurve[index]; + } + operator bool (void) const + { + return lutLocHHmaskCurve; + } +}; class LocCCmaskCurve diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index f097d0246..cca4fd2ec 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -902,6 +902,7 @@ void Crop::update(int todo) LocHHCurve lochhCurve; LocCCmaskCurve locccmasCurve; LocLLmaskCurve locllmasCurve; + LocHHmaskCurve lochhmasCurve; LocCCmaskexpCurve locccmasexpCurve; LocLLmaskexpCurve locllmasexpCurve; @@ -919,6 +920,7 @@ void Crop::update(int todo) lochhCurve.Set(params.locallab.spots.at(sp).HHcurve, HHutili); locccmasCurve.Set(params.locallab.spots.at(sp).CCmaskcurve); locllmasCurve.Set(params.locallab.spots.at(sp).LLmaskcurve); + lochhmasCurve.Set(params.locallab.spots.at(sp).HHmaskcurve); locccmasexpCurve.Set(params.locallab.spots.at(sp).CCmaskexpcurve); locllmasexpCurve.Set(params.locallab.spots.at(sp).LLmaskexpcurve); locallutili = false; @@ -950,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, locccmasexpCurve, locllmasexpCurve, LHutili, HHutili, cclocalcurve2, localskutili, sklocalcurve2, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, lightCurveloc2, huerefblu, huere, chromare, lumare, sobelre); + loclhCurve, lochhCurve, locccmasCurve, locllmasCurve, lochhmasCurve, locccmasexpCurve, locllmasexpCurve, 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 73473a16f..267c95aea 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -786,6 +786,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) lochhCurve.Set(params.locallab.spots.at(sp).HHcurve, HHutili); locccmasCurve.Set(params.locallab.spots.at(sp).CCmaskcurve); locllmasCurve.Set(params.locallab.spots.at(sp).LLmaskcurve); + lochhmasCurve.Set(params.locallab.spots.at(sp).HHmaskcurve); 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); @@ -829,7 +830,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, locccmasexpCurve, locllmasexpCurve, + ipf.Lab_Local(3, sp, sobelrefs, (float**)shbuffer, nprevl, nprevl, reserv, 0, 0, pW, pH, scale, locRETgainCurve, lllocalcurve, loclhCurve, lochhCurve, locccmasCurve, locllmasCurve, lochhmasCurve, locccmasexpCurve, locllmasexpCurve, 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 e8d186dc4..d835e5100 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -237,6 +237,7 @@ protected: LocHHCurve lochhCurve; LocCCmaskCurve locccmasCurve; LocLLmaskCurve locllmasCurve; + LocHHmaskCurve lochhmasCurve; LocCCmaskexpCurve locccmasexpCurve; LocLLmaskexpCurve locllmasexpCurve; ProcParams nextParams2; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index d0ca88019..35adef0d6 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, const LocCCmaskexpCurve & locccmasexpCurve, const LocLLmaskexpCurve & locllmasexpCurve, 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 LocHHmaskCurve & lochhmasCurve, const LocCCmaskexpCurve & locccmasexpCurve, const LocLLmaskexpCurve & locllmasexpCurve, 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); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index fc60f6b08..09a616ebc 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -7578,7 +7578,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, const LocCCmaskexpCurve & locccmasexpCurve, const LocLLmaskexpCurve & locllmasexpCurve, + const LocretigainCurve & locRETgainCcurve, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, const LocCCmaskCurve & locccmasCurve, const LocLLmaskCurve & locllmasCurve, const LocHHmaskCurve & lochhmasCurve, const LocCCmaskexpCurve & locccmasexpCurve, const LocLLmaskexpCurve & locllmasexpCurve, 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 @@ -10873,13 +10873,21 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu float valLL = 0.f; float valCC = 0.f; + float valHH = 0.f; float2 sincosval; + float kmaskL = 0; + float kmaskCa = 0; + float kmaskCb = 0; + + float kmaskHL = 0; + float kmaskHa = 0; + float kmaskHb = 0; if (lp.showmaskcolmet >= 2) { if (locllmasCurve) { valLL = (float)(locllmasCurve[500.f * (bufcolorig->L[loy - begy][lox - begx]) / 32768.f]); valLL = 1.f - valLL; - bufmaskblur->L[loy - begy][lox - begx] = 32768.f * valLL; + kmaskL = 32768.f * valLL; } if (locccmasCurve) { @@ -10889,9 +10897,31 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu valCC = 1.f - valCC; sincosval.y = (bufcolorig->a[loy - begy][lox - begx]) / chromask; sincosval.x = (bufcolorig->b[loy - begy][lox - begx]) / chromask; - bufmaskblur->a[loy - begy][lox - begx] = 45000.f * valCC * sincosval.y; - bufmaskblur->b[loy - begy][lox - begx] = 45000.f * valCC * sincosval.x; + kmaskCa = 45000.f * valCC * sincosval.y; + kmaskCb = 45000.f * valCC * sincosval.x; } + + if (lochhmasCurve) { + float huema= xatan2f(bufcolorig->b[loy - begy][lox - begx], bufcolorig->a[loy - begy][lox - begx]); + float h = Color::huelab_to_huehsv2(huema); + h += 1.f/6.f; + if (h > 1.f) { + h -= 1.f; + } + float chromask = (sqrt(SQR(bufcolorig->a[loy - begy][lox - begx]) + SQR(bufcolorig->b[loy - begy][lox - begx]))); + valHH = float (lochhmasCurve[500.f * h]); + valHH = 1.f - valHH; + sincosval.y = (bufcolorig->a[loy - begy][lox - begx]) / chromask; + sincosval.x = (bufcolorig->b[loy - begy][lox - begx]) / chromask; + kmaskHa = 45000.f * valHH * sincosval.y; + kmaskHb = 45000.f * valHH * sincosval.x; + kmaskHL = 32768.f * valHH; + } + + bufmaskblur->L[loy - begy][lox - begx] = kmaskL + kmaskHL; + bufmaskblur->a[loy - begy][lox - begx] = kmaskCa + kmaskHa; + bufmaskblur->b[loy - begy][lox - begx] = kmaskCb + kmaskHb; + } } } diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 93ae4b7a8..98299dbfd 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -637,6 +637,7 @@ enum ProcEventCode { EvlocallabLLmaskshape = 607, EvlocallabCCmaskexpshape = 608, EvlocallabLLmaskexpshape = 609, + EvlocallabHHmaskshape = 610, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index e4b199f1c..2a5715401 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2370,6 +2370,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : HHcurve{(double)FCT_MinMaxCPoints, 0.0, 0.50, 0.35, 0.35, 0.166, 0.50, 0.35, 0.35, 0.333, 0.50, 0.35, 0.35, 0.50, 0.50, 0.35, 0.35, 0.666, 0.50, 0.35, 0.35, 0.833, 0.50, 0.35, 0.35}, CCmaskcurve{(double)FCT_MinMaxCPoints, 0., 1., 0.35, 0.35, 1., 1., 0.35, 0.35}, LLmaskcurve{(double)FCT_MinMaxCPoints, 0., 1., 0.35, 0.35, 1., 1., 0.35, 0.35}, + HHmaskcurve{(double)FCT_MinMaxCPoints, 0., 1., 0.35, 0.35, 1., 1., 0.35, 0.35}, invers(false), // Exposure expexpose(false), @@ -2505,6 +2506,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && HHcurve == other.HHcurve && CCmaskcurve == other.CCmaskcurve && LLmaskcurve == other.LLmaskcurve + && HHmaskcurve == other.HHmaskcurve && invers == other.invers // Exposure && expexpose == other.expexpose @@ -3592,6 +3594,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->locallab.spots.at(i).HHcurve, "Locallab", "HHCurve_" + std::to_string(i), spot.HHcurve, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).CCmaskcurve, "Locallab", "CCmaskCurve_" + std::to_string(i), spot.CCmaskcurve, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).LLmaskcurve, "Locallab", "LLmaskCurve_" + std::to_string(i), spot.LLmaskcurve, keyFile); + saveToKeyfile(!pedited || pedited->locallab.spots.at(i).HHmaskcurve, "Locallab", "HHmaskCurve_" + std::to_string(i), spot.HHmaskcurve, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).invers, "Locallab", "Invers_" + std::to_string(i), spot.invers, keyFile); // Exposure saveToKeyfile(!pedited || pedited->locallab.spots.at(i).expexpose, "Locallab", "Expexpose_" + std::to_string(i), spot.expexpose, keyFile); @@ -4806,6 +4809,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "HHCurve_" + std::to_string(i), pedited, spot.HHcurve, spotEdited.HHcurve); assignFromKeyfile(keyFile, "Locallab", "CCmaskCurve_" + std::to_string(i), pedited, spot.CCmaskcurve, spotEdited.CCmaskcurve); assignFromKeyfile(keyFile, "Locallab", "LLmaskCurve_" + std::to_string(i), pedited, spot.LLmaskcurve, spotEdited.LLmaskcurve); + assignFromKeyfile(keyFile, "Locallab", "HHmaskCurve_" + std::to_string(i), pedited, spot.HHmaskcurve, spotEdited.HHmaskcurve); assignFromKeyfile(keyFile, "Locallab", "Invers_" + std::to_string(i), pedited, spot.invers, spotEdited.invers); // Exposure assignFromKeyfile(keyFile, "Locallab", "Expexpose_" + std::to_string(i), pedited, spot.expexpose, spotEdited.expexpose); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index dc6139331..bf8d32af9 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -49,6 +49,7 @@ class LocLHCurve; class LocHHCurve; class LocLLmaskCurve; class LocCCmaskCurve; +class LocHHmaskCurve; enum RenderingIntent { RI_PERCEPTUAL = INTENT_PERCEPTUAL, @@ -966,6 +967,7 @@ struct LocallabParams { std::vector HHcurve; std::vector CCmaskcurve; std::vector LLmaskcurve; + std::vector HHmaskcurve; bool invers; // Exposure bool expexpose; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 52735527d..089533f53 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -636,7 +636,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, //EvlocallabCCmaskshape LUMINANCECURVE, //EvlocallabLLmaskshape LUMINANCECURVE, //EvlocallabCCmaskexpshape - LUMINANCECURVE //EvlocallabLLmaskexpshape + LUMINANCECURVE, //EvlocallabLLmaskexpshape + LUMINANCECURVE //EvlocallabHHmaskshape }; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 052acf0b3..183c995c5 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1076,6 +1076,7 @@ private: LocHHCurve lochhCurve; LocCCmaskCurve locccmasCurve; LocLLmaskCurve locllmasCurve; + LocHHmaskCurve lochhmasCurve; LocCCmaskexpCurve locccmasexpCurve; LocLLmaskexpCurve locllmasexpCurve; LUTf lllocalcurve(65536, 0); @@ -1112,6 +1113,7 @@ private: lochhCurve.Set(params.locallab.spots.at(sp).HHcurve, HHutili); locccmasCurve.Set(params.locallab.spots.at(sp).CCmaskcurve); locllmasCurve.Set(params.locallab.spots.at(sp).LLmaskcurve); + lochhmasCurve.Set(params.locallab.spots.at(sp).HHmaskcurve); locccmasexpCurve.Set(params.locallab.spots.at(sp).CCmaskexpcurve); locllmasexpCurve.Set(params.locallab.spots.at(sp).LLmaskexpcurve); CurveFactory::curveLocal(locallutili, params.locallab.spots.at(sp).llcurve, lllocalcurve, 1); @@ -1139,7 +1141,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, locccmasexpCurve, locllmasexpCurve, + ipf.Lab_Local(2, sp, sobelrefs, (float**)shbuffer, labView, labView, reservView, 0, 0, fw, fh, 1, locRETgainCurve, lllocalcurve, loclhCurve, lochhCurve, locccmasCurve, locllmasCurve, lochhmasCurve, locccmasexpCurve, locllmasexpCurve, 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 84dc4af1f..055ed98e7 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -306,7 +306,14 @@ Locallab::Locallab(): LLmaskshape->setResetCurve(FlatCurveType(defSpot.LLmaskcurve.at(0)), defSpot.LLmaskcurve); LLmaskshape->setTooltip(M("TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP")); LLmaskshape->setBottomBarBgGradient(mllshape); - + LLmaskshape->setTooltip(M("TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP")); + + HHmaskshape = static_cast(maskCurveEditorG->addCurve(CT_Flat, "LC(H)", nullptr, false, true)); + HHmaskshape->setIdentityValue(0.); + HHmaskshape->setResetCurve(FlatCurveType(defSpot.LLmaskcurve.at(0)), defSpot.LLmaskcurve); + HHmaskshape->setTooltip(M("TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP")); + HHmaskshape->setCurveColorProvider(this, 6); + HHmaskshape->setBottomBarColorProvider(this, 6); maskCurveEditorG->curveListComplete(); @@ -907,6 +914,12 @@ void Locallab::refChanged (double huer, double lumar, double chromar) nexthuer = huer; nextlumar = lumar / 100.f; nextchromar = chromar / 137.4f; + float h = Color::huelab_to_huehsv2(nexthuer); + h += 1.f/6.f; + if (h > 1.f) { + h -= 1.f; + } + nexthuer = h; //printf("nh=%f nl=%f nc=%f\n", nexthuer, nextlumar, nextchromar); const auto func = [] (gpointer data) -> gboolean { GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected @@ -930,20 +943,23 @@ bool Locallab::refComputed_ () void Locallab::updateLabel () { if (!batchMode) { - float nX, nY; - + float nX, nY, nZ; + nY = nextlumar; nX = nextchromar; + nZ = nexthuer; { transLabels->set_text ( Glib::ustring::compose (M ("TP_LOCALLAB_REFLABEL"), Glib::ustring::format (std::fixed, std::setprecision (3), nX), - Glib::ustring::format (std::fixed, std::setprecision (3), nY)) + Glib::ustring::format (std::fixed, std::setprecision (3), nY), + Glib::ustring::format (std::fixed, std::setprecision (3), nZ)) ); transLabels2->set_text ( Glib::ustring::compose (M ("TP_LOCALLAB_REFLABEL"), Glib::ustring::format (std::fixed, std::setprecision (3), nX), - Glib::ustring::format (std::fixed, std::setprecision (3), nY)) + Glib::ustring::format (std::fixed, std::setprecision (3), nY), + Glib::ustring::format (std::fixed, std::setprecision (3), nZ)) ); } } @@ -1486,6 +1502,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pp->locallab.spots.at(pp->locallab.selspot).HHcurve = HHshape->getCurve(); pp->locallab.spots.at(pp->locallab.selspot).CCmaskcurve = CCmaskshape->getCurve(); pp->locallab.spots.at(pp->locallab.selspot).LLmaskcurve = LLmaskshape->getCurve(); + pp->locallab.spots.at(pp->locallab.selspot).HHmaskcurve = HHmaskshape->getCurve(); pp->locallab.spots.at(pp->locallab.selspot).invers = invers->get_active(); // Exposure pp->locallab.spots.at(pp->locallab.selspot).expexpose = expexpose->getEnabled(); @@ -1649,6 +1666,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pe->locallab.spots.at(pp->locallab.selspot).HHcurve = pe->locallab.spots.at(pp->locallab.selspot).HHcurve || !HHshape->isUnChanged(); pe->locallab.spots.at(pp->locallab.selspot).CCmaskcurve = pe->locallab.spots.at(pp->locallab.selspot).CCmaskcurve || !CCmaskshape->isUnChanged(); pe->locallab.spots.at(pp->locallab.selspot).LLmaskcurve = pe->locallab.spots.at(pp->locallab.selspot).LLmaskcurve || !LLmaskshape->isUnChanged(); + pe->locallab.spots.at(pp->locallab.selspot).HHmaskcurve = pe->locallab.spots.at(pp->locallab.selspot).HHmaskcurve || !HHmaskshape->isUnChanged(); pe->locallab.spots.at(pp->locallab.selspot).invers = pe->locallab.spots.at(pp->locallab.selspot).invers || !invers->get_inconsistent(); // Exposure pe->locallab.spots.at(pp->locallab.selspot).expexpose = pe->locallab.spots.at(pp->locallab.selspot).expexpose || !expexpose->get_inconsistent(); @@ -1788,6 +1806,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pedited->locallab.spots.at(pp->locallab.selspot).HHcurve = pedited->locallab.spots.at(pp->locallab.selspot).HHcurve || !HHshape->isUnChanged(); pedited->locallab.spots.at(pp->locallab.selspot).CCmaskcurve = pedited->locallab.spots.at(pp->locallab.selspot).CCmaskcurve || !CCmaskshape->isUnChanged(); pedited->locallab.spots.at(pp->locallab.selspot).LLmaskcurve = pedited->locallab.spots.at(pp->locallab.selspot).LLmaskcurve || !LLmaskshape->isUnChanged(); + pedited->locallab.spots.at(pp->locallab.selspot).HHmaskcurve = pedited->locallab.spots.at(pp->locallab.selspot).HHmaskcurve || !HHmaskshape->isUnChanged(); pedited->locallab.spots.at(pp->locallab.selspot).invers = pedited->locallab.spots.at(pp->locallab.selspot).invers || !invers->get_inconsistent(); // Exposure pedited->locallab.spots.at(pp->locallab.selspot).expexpose = pedited->locallab.spots.at(pp->locallab.selspot).expexpose || !expexpose->get_inconsistent(); @@ -2024,6 +2043,12 @@ void Locallab::curveChanged(CurveEditor* ce) } } + if (ce == HHmaskshape) { + if (listener) { + listener->panelChanged(EvlocallabHHmaskshape, M("HISTORY_CUSTOMCURVE")); + } + } + } // Exposure @@ -3448,6 +3473,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con HHshape->setCurve(pp->locallab.spots.at(index).HHcurve); CCmaskshape->setCurve(pp->locallab.spots.at(index).CCmaskcurve); LLmaskshape->setCurve(pp->locallab.spots.at(index).LLmaskcurve); + HHmaskshape->setCurve(pp->locallab.spots.at(index).HHmaskcurve); invers->set_active(pp->locallab.spots.at(index).invers); // Exposure @@ -3639,6 +3665,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con HHshape->setUnChanged(!spotState->HHcurve); CCmaskshape->setUnChanged(!spotState->CCmaskcurve); LLmaskshape->setUnChanged(!spotState->LLmaskcurve); + HHmaskshape->setUnChanged(!spotState->HHmaskcurve); invers->set_inconsistent(multiImage && !spotState->invers); // Exposure @@ -3866,12 +3893,13 @@ void Locallab::autoOpenCurve() // printf("autoOpenCurve\n"); // TODO autoOpenCurve only considers linearity state of selected spot curve - llshape->openIfNonlinear(); - ccshape->openIfNonlinear(); - LHshape->openIfNonlinear(); - HHshape->openIfNonlinear(); - CCmaskshape->openIfNonlinear(); - LLmaskshape->openIfNonlinear(); - CCmaskexpshape->openIfNonlinear(); - LLmaskexpshape->openIfNonlinear(); +// llshape->openIfNonlinear(); +// ccshape->openIfNonlinear(); +// LHshape->openIfNonlinear(); +// HHshape->openIfNonlinear(); +// CCmaskshape->openIfNonlinear(); +// LLmaskshape->openIfNonlinear(); +// HHmaskshape->openIfNonlinear(); +// CCmaskexpshape->openIfNonlinear(); +// LLmaskexpshape->openIfNonlinear(); } diff --git a/rtgui/locallab.h b/rtgui/locallab.h index 0159f4af3..02489deed 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -71,6 +71,7 @@ private: FlatCurveEditor* HHshape; FlatCurveEditor* CCmaskshape; FlatCurveEditor* LLmaskshape; + FlatCurveEditor* HHmaskshape; // Exposure CurveEditorGroup* const curveEditorG; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 2b7e7522a..4dd0009cb 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -956,6 +956,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).HHcurve = locallab.spots.at(j).HHcurve && pSpot.HHcurve == otherSpot.HHcurve; locallab.spots.at(j).CCmaskcurve = locallab.spots.at(j).CCmaskcurve && pSpot.CCmaskcurve == otherSpot.CCmaskcurve; locallab.spots.at(j).LLmaskcurve = locallab.spots.at(j).LLmaskcurve && pSpot.LLmaskcurve == otherSpot.LLmaskcurve; + locallab.spots.at(j).HHmaskcurve = locallab.spots.at(j).HHmaskcurve && pSpot.HHmaskcurve == otherSpot.HHmaskcurve; locallab.spots.at(j).invers = locallab.spots.at(j).invers && pSpot.invers == otherSpot.invers; // Exposure locallab.spots.at(j).expexpose = locallab.spots.at(j).expexpose && pSpot.expexpose == otherSpot.expexpose; @@ -2606,6 +2607,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).LLmaskcurve = mods.locallab.spots.at(i).LLmaskcurve; } + if (locallab.spots.at(i).HHmaskcurve) { + toEdit.locallab.spots.at(i).HHmaskcurve = mods.locallab.spots.at(i).HHmaskcurve; + } + if (locallab.spots.at(i).invers) { toEdit.locallab.spots.at(i).invers = mods.locallab.spots.at(i).invers; } @@ -3918,6 +3923,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : HHcurve(v), CCmaskcurve(v), LLmaskcurve(v), + HHmaskcurve(v), invers(v), // Exposure expexpose(v), @@ -4049,6 +4055,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) HHcurve = v; CCmaskcurve = v; LLmaskcurve = v; + HHmaskcurve = v; invers = v; // Exposure expexpose = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 7436f663d..12d688ada 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -495,6 +495,7 @@ public: bool HHcurve; bool CCmaskcurve; bool LLmaskcurve; + bool HHmaskcurve; bool invers; // Exposure bool expexpose;