diff --git a/rtdata/languages/default b/rtdata/languages/default index dda7f0a2f..790e334de 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1037,6 +1037,8 @@ HISTORY_MSG_796;Local - Recursive references HISTORY_MSG_797;Local - Merge and Masks method HISTORY_MSG_798;Local - Merge Original method HISTORY_MSG_799;Local - Opacity +HISTORY_MSG_800;Local - Color RGB ToneCurve +HISTORY_MSG_801;Local - Color ToneCurve Method HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -2216,6 +2218,7 @@ TP_LOCALLAB_LUM;Curves LC TP_LOCALLAB_LAPLACE;Laplacian threshold deltaE TP_LOCALLAB_LINEAR;Linearity TP_LOCALLAB_HLH;Curves H +TP_LOCALLAB_RGB;RGB Tone Curve TP_LOCALLAB_EQUIL;Normalize Luminance TP_LOCALLAB_CHROMACBDL;Chroma TP_LOCALLAB_CHROMACB_TOOLTIP;Acts as an amplifier-reducer action compare to sliders of luminance.\nUnder 100 reduce, above 100 amplifie diff --git a/rtengine/curves.h b/rtengine/curves.h index 3b9b8d65f..76b79b020 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -1755,6 +1755,7 @@ inline void StandardToneCurve::Apply(float& r, float& g, float& b) const curves::setLutVal(lutToneCurve, r, g, b); } + inline void StandardToneCurve::BatchApply( const size_t start, const size_t end, float *r, float *g, float *b) const diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 4bd7a9576..0c952a954 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -880,6 +880,8 @@ void Crop::update(int todo) LUTf lllocalcurve2(65536, 0); bool localcutili = parent->locallutili; LUTf cclocalcurve2(65536, 0); + bool localrgbutili = parent->localrgbutili; + LUTf rgblocalcurve2(65536, 0); bool localexutili = parent->localexutili; LUTf exlocalcurve2(65536, 0); bool localmaskutili = parent->localmaskutili; @@ -999,8 +1001,11 @@ void Crop::update(int todo) locwavCurve.Set(params.locallab.spots.at(sp).locwavcurve, locwavutili); locallutili = false; CurveFactory::curveLocal(locallutili, params.locallab.spots.at(sp).llcurve, lllocalcurve2, sca); + localrgbutili = false; + CurveFactory::curveLocal(localrgbutili, params.locallab.spots.at(sp).rgbcurve, rgblocalcurve2, sca); localcutili = false; CurveFactory::curveCCLocal(localcutili, params.locallab.spots.at(sp).cccurve, cclocalcurve2, sca); + localexutili = false; CurveFactory::curveexLocal(localexutili, params.locallab.spots.at(sp).excurve, exlocalcurve2, sca); localmaskutili = false; CurveFactory::curvemaskLocal(localmaskutili, params.locallab.spots.at(sp).Lmaskcurve, lmasklocalcurve2, sca); @@ -1074,7 +1079,7 @@ void Crop::update(int todo) loclmasCurveblwav,lmasutiliblwav, loclmasCurvecolwav,lmasutilicolwav, locwavCurve, locwavutili, - LHutili, HHutili, cclocalcurve2, localcutili, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, lightCurveloc2, + LHutili, HHutili, cclocalcurve2, localcutili, rgblocalcurve2, localrgbutili, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, lightCurveloc2, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, lastsav, parent->locallColorMask, parent->locallColorMaskinv, parent->locallExpMask, parent->locallExpMaskinv, parent->locallSHMask, parent->locallSHMaskinv, parent->locallcbMask, parent->locallretiMask, parent->locallsoftMask, parent->localltmMask, parent->locallblMask, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); @@ -1100,12 +1105,13 @@ void Crop::update(int todo) loclmasCurveblwav,lmasutiliblwav, loclmasCurvecolwav,lmasutilicolwav, locwavCurve, locwavutili, - LHutili, HHutili, cclocalcurve2, localcutili, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, lightCurveloc2, + LHutili, HHutili, cclocalcurve2, localcutili, rgblocalcurve2, localrgbutili, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, lightCurveloc2, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, lastsav, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); } lllocalcurve2.clear(); lightCurveloc2.clear(); + rgblocalcurve2.clear(); cclocalcurve2.clear(); exlocalcurve2.clear(); lmasklocalcurve2.clear(); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 4632b93c2..62d7a0cba 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -172,6 +172,7 @@ ImProcCoordinator::ImProcCoordinator() : coordX(0), coordY(0), localX(0), localY(0), lllocalcurve(65536, 0), cclocalcurve(65536, 0), + rgblocalcurve(65536, 0), exlocalcurve(65536, 0), hltonecurveloc(65536, 0), //32768 shtonecurveloc(65536, 0), @@ -186,6 +187,7 @@ ImProcCoordinator::ImProcCoordinator() : lmaskbllocalcurve(65536, 0), locallutili(false), localcutili(false), + localrgbutili(false), localexutili(false), llmasutili(false), lhmasutili(false), @@ -936,6 +938,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) HHutili = false; locallutili = false; localexutili = false; + localrgbutili = false; localcutili = false; llmasutili = false; lhmasutili = false; @@ -1001,6 +1004,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) locwavCurve.Set(params->locallab.spots.at(sp).locwavcurve, locwavutili); CurveFactory::curveLocal(locallutili, params->locallab.spots.at(sp).llcurve, lllocalcurve, sca); CurveFactory::curveCCLocal(localcutili, params->locallab.spots.at(sp).cccurve, cclocalcurve, sca); + CurveFactory::curveLocal(localrgbutili, params->locallab.spots.at(sp).rgbcurve, rgblocalcurve, sca); CurveFactory::curveexLocal(localexutili, params->locallab.spots.at(sp).excurve, exlocalcurve, sca); CurveFactory::curvemaskLocal(localmaskutili, params->locallab.spots.at(sp).Lmaskcurve, lmasklocalcurve, sca); CurveFactory::curvemaskLocal(localmaskexputili, params->locallab.spots.at(sp).Lmaskexpcurve, lmaskexplocalcurve, sca); @@ -1093,7 +1097,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) loclmasCurveblwav,lmasutiliblwav, loclmasCurvecolwav,lmasutilicolwav, locwavCurve, locwavutili, - LHutili, HHutili, cclocalcurve, localcutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, + LHutili, HHutili, cclocalcurve, localcutili, rgblocalcurve, localrgbutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerblu, chromarblu, lumarblu, huer, chromar, lumar, sobeler, lastsav, locallColorMask, locallColorMaskinv, locallExpMask, locallExpMaskinv, locallSHMask, locallSHMaskinv, locallcbMask, locallretiMask, locallsoftMask, localltmMask, locallblMask, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); @@ -1118,7 +1122,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) loclmasCurveblwav,lmasutiliblwav, loclmasCurvecolwav,lmasutilicolwav, locwavCurve, locwavutili, - LHutili, HHutili, cclocalcurve, localcutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, + LHutili, HHutili, cclocalcurve, localcutili, rgblocalcurve, localrgbutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerblu, chromarblu, lumarblu, huer, chromar, lumar, sobeler, lastsav, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); } @@ -1143,6 +1147,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) lllocalcurve.clear(); lightCurveloc.clear(); cclocalcurve.clear(); + rgblocalcurve.clear(); exlocalcurve.clear(); lmasklocalcurve.clear(); lmaskexplocalcurve.clear(); diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 1c89567f7..4139064f9 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -234,6 +234,7 @@ protected: int coordX, coordY, localX, localY; LUTf lllocalcurve; LUTf cclocalcurve; + LUTf rgblocalcurve; LUTf exlocalcurve; LUTf hltonecurveloc; LUTf shtonecurveloc; @@ -279,6 +280,7 @@ protected: bool locallutili; bool localcutili; + bool localrgbutili; bool localexutili; bool llmasutili; bool lhmasutili; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 6824b9f37..115a3fb0b 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -280,7 +280,7 @@ public: const LocwavCurve & loclmasCurveblwav, bool & lmasutiliblwav, const LocwavCurve & loclmasCurvecolwav, bool & lmasutilicolwav, const LocwavCurve & locwavCurve, bool & locwavutili, - bool &LHutili, bool &HHutili, LUTf & cclocalcurve, bool & localcutili, bool & localexutili, LUTf & exlocalcurve, LUTf & hltonecurveloc, LUTf & shtonecurveloc, LUTf & tonecurveloc, LUTf & lightCurveloc, + bool &LHutili, bool &HHutili, LUTf & cclocalcurve, bool & localcutili, LUTf & rgblocalcurve, bool & localrgbutili, bool & localexutili, LUTf & exlocalcurve, LUTf & hltonecurveloc, LUTf & shtonecurveloc, LUTf & tonecurveloc, LUTf & lightCurveloc, double & huerefblur, double &chromarefblur, double & lumarefblur, double &hueref, double &chromaref, double &lumaref, double &sobelref, int &lastsav, int llColorMask, int llColorMaskinv, int llExpMask, int llExpMaskinv, int llSHMask, int llSHMaskinv, int llcbMask, int llretiMask, int llsoftMask, int lltmMask, int llblMask, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index cad205068..6461cbf26 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -7396,6 +7396,25 @@ void ImProcFunctions::DeNoise(int call, int del, float * slidL, float * slida, f } +float triangle(float a, float a1, float b) +{ + if (a != b) { + float b1; + float a2 = a1 - a; + + if (b < a) { + b1 = b + a2 * b / a ; + } else { + b1 = b + a2 * (65535.f - b) / (65535.f - a); + } + + return b1; + } + + return a1; +} + + void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * original, LabImage * transformed, LabImage * reserved, int cx, int cy, int oW, int oH, int sk, const LocretigainCurve & locRETgainCcurve, const LocretitransCurve & locRETtransCcurve, LUTf & lllocalcurve, bool & locallutili, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, @@ -7416,7 +7435,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o const LocwavCurve & loclmasCurveblwav, bool & lmasutiliblwav, const LocwavCurve & loclmasCurvecolwav, bool & lmasutilicolwav, const LocwavCurve & locwavCurve, bool & locwavutili, - bool & LHutili, bool & HHutili, LUTf & cclocalcurve, bool & localcutili, bool & localexutili, LUTf & exlocalcurve, LUTf & hltonecurveloc, LUTf & shtonecurveloc, LUTf & tonecurveloc, LUTf & lightCurveloc, + bool & LHutili, bool & HHutili, LUTf & cclocalcurve, bool & localcutili, LUTf & rgblocalcurve, bool & localrgbutili, bool & localexutili, LUTf & exlocalcurve, LUTf & hltonecurveloc, LUTf & shtonecurveloc, LUTf & tonecurveloc, LUTf & lightCurveloc, double & huerefblur, double & chromarefblur, double & lumarefblur, double & hueref, double & chromaref, double & lumaref, double & sobelref, int &lastsav, int llColorMask, int llColorMaskinv, int llExpMask, int llExpMaskinv, int llSHMask, int llSHMaskinv, int llcbMask, int llretiMask, int llsoftMask, int lltmMask, int llblMask, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax) @@ -11699,6 +11718,15 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o int level_hr = params->locallab.spots.at(sp).csthresholdcol.getTopRight(); int shortcu = lp.mergemet; //params->locallab.spots.at(sp).shortc; int lumask = params->locallab.spots.at(sp).lumask; + int tonemod = 0; + + if (params->locallab.spots.at(sp).toneMethod == "one") { + tonemod = 0; + } else if (params->locallab.spots.at(sp).toneMethod == "two") { + tonemod = 1; + } else if (params->locallab.spots.at(sp).toneMethod == "thr") { + tonemod = 2; + } const int limscope = 80; const float mindE = 2.f + MINSCOPE * sco * lp.thr; @@ -11817,6 +11845,85 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o } + //RGB Curves + Imagefloat *tmpImage = nullptr; + tmpImage = new Imagefloat(bfw, bfh); + + float *rtemp = new float[bfw * bfh]; + float *gtemp = new float[bfw * bfh]; + float *btemp = new float[bfw * bfh]; + + lab2rgb(*bufcolfin, *tmpImage, params->icm.workingProfile); +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int y = 0; y < bfh; y++) + for (int x = 0; x < bfw; x++) { + rtemp[y * bfw + x] = tmpImage->r(y, x); + gtemp[y * bfw + x] = tmpImage->g(y, x); + btemp[y * bfw + x] = tmpImage->b(y, x); + + if (rgblocalcurve && localrgbutili && lp.qualcurvemet != 0) { + assert(rgblocalcurve); + + //std + if (tonemod == 0) { + curves::setLutVal(rgblocalcurve, rtemp[y * bfw + x], gtemp[y * bfw + x], btemp[y * bfw + x]); + } else { + float r = CLIP(rtemp[y * bfw + x]); + float g = CLIP(gtemp[y * bfw + x]); + float b = CLIP(btemp[y * bfw + x]); + + //Luminance + if (tonemod == 2) { + float currLuminance = r * 0.2126729f + g * 0.7151521f + b * 0.0721750f; + + const float newLuminance = rgblocalcurve[currLuminance]; + currLuminance = currLuminance == 0.f ? 0.00001f : currLuminance; + const float coef = newLuminance / currLuminance; + r = LIM (r * coef, 0.f, 65535.f); + g = LIM (g * coef, 0.f, 65535.f); + b = LIM (b * coef, 0.f, 65535.f); + } + + //weightstd + if (tonemod == 1) { + float r1 = rgblocalcurve[r]; + float g1 = triangle(r, r1, g); + float b1 = triangle(r, r1, b); + + float g2 = rgblocalcurve[g]; + float r2 = triangle(g, g2, r); + float b2 = triangle(g, g2, b); + + float b3 = rgblocalcurve[b]; + float r3 = triangle(b, b3, r); + float g3 = triangle(b, b3, g); + r = CLIP(r1 * 0.50f + r2 * 0.25f + r3 * 0.25f); + g = CLIP (g1 * 0.25f + g2 * 0.50f + g3 * 0.25f); + b = CLIP (b1 * 0.25f + b2 * 0.25f + b3 * 0.50f); + } + + setUnlessOOG(rtemp[y * bfw + x], gtemp[y * bfw + x], btemp[y * bfw + x], r, g, b); + } + } + + tmpImage->r(y, x) = rtemp[y * bfw + x]; + tmpImage->g(y, x) = gtemp[y * bfw + x]; + tmpImage->b(y, x) = btemp[y * bfw + x]; + } + + rgb2lab(*tmpImage, *bufcolfin, params->icm.workingProfile); + + delete tmpImage; + delete [] rtemp; + delete [] gtemp; + delete [] btemp; + + + // + if (lp.mergemet >= 2) { //merge result with original bufcolreserv.reset(new LabImage(bfw, bfh)); #ifdef _OPENMP diff --git a/rtengine/procevents.h b/rtengine/procevents.h index a25123a3b..e14a69ca5 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -822,6 +822,8 @@ enum ProcEventCode { EvLocallabSpotmergeMethod = 796, EvLocallabmergecolMethod = 797, Evlocallabopacol = 798, + Evlocallabrgbshape = 799, + EvLocallabtoneMethod = 800, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 74d6bbf15..60a5f634f 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2468,9 +2468,11 @@ LocallabParams::LocallabSpot::LocallabSpot() : lapmaskcol(0.0), qualitycurveMethod("none"), gridMethod("one"), + toneMethod("one"), mergecolMethod("one"), llcurve{(double)DCT_NURBS, 0.0, 0.0, 1.0, 1.0}, cccurve{(double)DCT_NURBS, 0.0, 0.0, 1.0, 1.0}, + rgbcurve{(double)DCT_NURBS, 0.0, 0.0, 1.0, 1.0}, LHcurve{(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}, 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}, invers(false), @@ -2779,9 +2781,11 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && lapmaskcol == other.lapmaskcol && qualitycurveMethod == other.qualitycurveMethod && gridMethod == other.gridMethod + && toneMethod == other.toneMethod && mergecolMethod == other.mergecolMethod && llcurve == other.llcurve && cccurve == other.cccurve + && rgbcurve == other.rgbcurve && LHcurve == other.LHcurve && HHcurve == other.HHcurve && invers == other.invers @@ -4087,9 +4091,11 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->locallab.spots.at(i).lapmaskcol, "Locallab", "Lapmaskcol_" + std::to_string(i), spot.lapmaskcol, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).qualitycurveMethod, "Locallab", "QualityCurveMethod_" + std::to_string(i), spot.qualitycurveMethod, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).gridMethod, "Locallab", "gridMethod_" + std::to_string(i), spot.gridMethod, keyFile); + saveToKeyfile(!pedited || pedited->locallab.spots.at(i).toneMethod, "Locallab", "ToneMethod_" + std::to_string(i), spot.toneMethod, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).mergecolMethod, "Locallab", "mergecolMethod_" + std::to_string(i), spot.mergecolMethod, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).llcurve, "Locallab", "LLCurve_" + std::to_string(i), spot.llcurve, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).cccurve, "Locallab", "CCCurve_" + std::to_string(i), spot.cccurve, keyFile); + saveToKeyfile(!pedited || pedited->locallab.spots.at(i).rgbcurve, "Locallab", "RGBCurve_" + std::to_string(i), spot.rgbcurve, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).LHcurve, "Locallab", "LHCurve_" + std::to_string(i), spot.LHcurve, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).HHcurve, "Locallab", "HHCurve_" + std::to_string(i), spot.HHcurve, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).invers, "Locallab", "Invers_" + std::to_string(i), spot.invers, keyFile); @@ -5502,9 +5508,11 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Lapmaskcol_" + std::to_string(i), pedited, spot.lapmaskcol, spotEdited.lapmaskcol); assignFromKeyfile(keyFile, "Locallab", "QualityCurveMethod_" + std::to_string(i), pedited, spot.qualitycurveMethod, spotEdited.qualitycurveMethod); assignFromKeyfile(keyFile, "Locallab", "gridMethod_" + std::to_string(i), pedited, spot.gridMethod, spotEdited.gridMethod); + assignFromKeyfile(keyFile, "Locallab", "ToneMethod_" + std::to_string(i), pedited, spot.toneMethod, spotEdited.toneMethod); assignFromKeyfile(keyFile, "Locallab", "mergecolMethod_" + std::to_string(i), pedited, spot.mergecolMethod, spotEdited.mergecolMethod); assignFromKeyfile(keyFile, "Locallab", "LLCurve_" + std::to_string(i), pedited, spot.llcurve, spotEdited.llcurve); assignFromKeyfile(keyFile, "Locallab", "CCCurve_" + std::to_string(i), pedited, spot.cccurve, spotEdited.cccurve); + assignFromKeyfile(keyFile, "Locallab", "RGBCurve_" + std::to_string(i), pedited, spot.rgbcurve, spotEdited.rgbcurve); assignFromKeyfile(keyFile, "Locallab", "LHCurve_" + std::to_string(i), pedited, spot.LHcurve, spotEdited.LHcurve); assignFromKeyfile(keyFile, "Locallab", "HHCurve_" + std::to_string(i), pedited, spot.HHcurve, spotEdited.HHcurve); assignFromKeyfile(keyFile, "Locallab", "Invers_" + std::to_string(i), pedited, spot.invers, spotEdited.invers); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index e99a0434c..cf9355c62 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1011,9 +1011,11 @@ struct LocallabParams { double lapmaskcol; Glib::ustring qualitycurveMethod; Glib::ustring gridMethod; + Glib::ustring toneMethod; Glib::ustring mergecolMethod; std::vector llcurve; std::vector cccurve; + std::vector rgbcurve; std::vector LHcurve; std::vector HHcurve; bool invers; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 4bba6a86e..33b69fb41 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -823,9 +823,11 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, //EvlocallabsloSH LUMINANCECURVE, //Evlocallabsavrest LUMINANCECURVE, //Evlocallabrecurs - LUMINANCECURVE, // EvLocallabSpotmergeMethod - LUMINANCECURVE, //EvLocallabmergecolMethod - LUMINANCECURVE, //EvLocallabopacol + LUMINANCECURVE, // EvLocallabSpotmergeMethod + LUMINANCECURVE, //EvLocallabmergecolMethod + LUMINANCECURVE, //EvLocallabopacol + LUMINANCECURVE, //Evlocallabrgbshape + LUMINANCECURVE //EvLocallabtoneMethod }; namespace rtengine diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 4f139b617..3e707f2df 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1124,6 +1124,7 @@ private: LocwavCurve locwavCurve; LUTf lllocalcurve(65536, 0); LUTf cclocalcurve(65536, 0); + LUTf rgblocalcurve(65536, 0); LUTf hltonecurveloc(65536, 0); LUTf shtonecurveloc(65536, 0); LUTf tonecurveloc(65536, 0); @@ -1154,6 +1155,7 @@ private: bool HHutili = false; bool locallutili = false; bool localcutili = false; + bool localrgbutili = false; bool localexutili = false; bool llmasutili = false; bool lhmasutili = false; @@ -1217,6 +1219,7 @@ private: locwavCurve.Set(params.locallab.spots.at(sp).locwavcurve, locwavutili); CurveFactory::curveLocal(locallutili, params.locallab.spots.at(sp).llcurve, lllocalcurve, 1); CurveFactory::curveCCLocal(localcutili, params.locallab.spots.at(sp).cccurve, cclocalcurve, 1); + CurveFactory::curveLocal(localrgbutili, params.locallab.spots.at(sp).rgbcurve, rgblocalcurve, 1); CurveFactory::curveexLocal(localexutili, params.locallab.spots.at(sp).excurve, exlocalcurve, 1); CurveFactory::curvemaskLocal(localmaskutili, params.locallab.spots.at(sp).Lmaskcurve, lmasklocalcurve, 1); CurveFactory::curvemaskLocal(localmaskexputili, params.locallab.spots.at(sp).Lmaskexpcurve, lmaskexplocalcurve, 1); @@ -1276,7 +1279,7 @@ private: loclmasCurveblwav,lmasutiliblwav, loclmasCurvecolwav,lmasutilicolwav, locwavCurve, locwavutili, - LHutili, HHutili, cclocalcurve, localcutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, + LHutili, HHutili, cclocalcurve, localcutili, rgblocalcurve, localrgbutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, lastsav, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); @@ -1290,6 +1293,7 @@ private: // Clear local curves lllocalcurve.clear(); cclocalcurve.clear(); + rgblocalcurve.clear(); exlocalcurve.clear(); hltonecurveloc.clear(); lmasklocalcurve.clear(); diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 9cb97b994..f72817bd6 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -156,6 +156,7 @@ Locallab::Locallab(): // Color & Light llCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_LUM"))), HCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_HLH"))), + rgbCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_RGB"))), maskCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK"))), mask2CurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK2"))), mask2CurveEditorGwav(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_WAVMASK"))), @@ -406,6 +407,7 @@ Locallab::Locallab(): // Color & Light qualitycurveMethod(Gtk::manage(new MyComboBoxText())), gridMethod(Gtk::manage(new MyComboBoxText())), + toneMethod(Gtk::manage(new MyComboBoxText())), showmaskcolMethod(Gtk::manage(new MyComboBoxText())), showmaskcolMethodinv(Gtk::manage(new MyComboBoxText())), mergecolMethod(Gtk::manage(new MyComboBoxText())), @@ -556,6 +558,12 @@ Locallab::Locallab(): gridMethod->set_active(0); gridMethodConn = gridMethod->signal_changed().connect(sigc::mem_fun(*this, &Locallab::gridMethodChanged)); + toneMethod->append(M("TP_EXPOSURE_TCMODE_STANDARD")); + toneMethod->append(M("TP_EXPOSURE_TCMODE_WEIGHTEDSTD")); + toneMethod->append(M("TP_EXPOSURE_TCMODE_LUMINANCE")); + toneMethod->set_active(0); + toneMethodConn = toneMethod->signal_changed().connect(sigc::mem_fun(*this, &Locallab::toneMethodChanged)); + llCurveEditorG->setCurveListener(this); llshape = static_cast(llCurveEditorG->addCurve(CT_Diagonal, "L(L)")); llshape->setResetCurve(DiagonalCurveType(defSpot.llcurve.at(0)), defSpot.llcurve); @@ -628,6 +636,22 @@ Locallab::Locallab(): HCurveEditorG->curveListComplete(); + + rgbCurveEditorG->setCurveListener(this); + rgbshape = static_cast(rgbCurveEditorG->addCurve(CT_Diagonal,"",toneMethod)); + rgbshape->setResetCurve(DiagonalCurveType(defSpot.rgbcurve.at(0)), defSpot.rgbcurve); + + if (showtooltip) { + rgbshape->setTooltip(M("TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP")); + } + + std::vector mrgbshape; + mrgbshape.push_back(GradientMilestone(0., 0., 0., 0.)); + mrgbshape.push_back(GradientMilestone(1., 1., 1., 1.)); + rgbshape->setBottomBarBgGradient(mrgbshape); + rgbshape->setLeftBarBgGradient(mrgbshape); + rgbCurveEditorG->curveListComplete(); + inversConn = invers->signal_toggled().connect(sigc::mem_fun(*this, &Locallab::inversChanged)); @@ -777,6 +801,7 @@ Locallab::Locallab(): colorBox->pack_start(*qualcurvbox); colorBox->pack_start(*llCurveEditorG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor colorBox->pack_start(*HCurveEditorG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor + colorBox->pack_start(*rgbCurveEditorG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor colorBox->pack_start(*invers); mergecolFrame->set_label_align(0.025, 0.5); @@ -2502,6 +2527,7 @@ Locallab::~Locallab() delete llCurveEditorG; delete HCurveEditorG; + delete rgbCurveEditorG; delete maskCurveEditorG; delete mask2CurveEditorG; delete mask2CurveEditorGwav; @@ -3510,6 +3536,14 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited pp->locallab.spots.at(pp->locallab.selspot).gridMethod = "two"; } + if (toneMethod->get_active_row_number() == 0) { + pp->locallab.spots.at(pp->locallab.selspot).toneMethod = "one"; + } else if (toneMethod->get_active_row_number() == 1) { + pp->locallab.spots.at(pp->locallab.selspot).toneMethod = "two"; + } else if (toneMethod->get_active_row_number() == 2) { + pp->locallab.spots.at(pp->locallab.selspot).toneMethod = "thr"; + } + if (mergecolMethod->get_active_row_number() == 0) { pp->locallab.spots.at(pp->locallab.selspot).mergecolMethod = "one"; } else if (mergecolMethod->get_active_row_number() == 1) { @@ -3540,6 +3574,7 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited pp->locallab.spots.at(pp->locallab.selspot).llcurve = llshape->getCurve(); pp->locallab.spots.at(pp->locallab.selspot).cccurve = ccshape->getCurve(); + pp->locallab.spots.at(pp->locallab.selspot).rgbcurve = rgbshape->getCurve(); pp->locallab.spots.at(pp->locallab.selspot).LHcurve = LHshape->getCurve(); pp->locallab.spots.at(pp->locallab.selspot).HHcurve = HHshape->getCurve(); pp->locallab.spots.at(pp->locallab.selspot).invers = invers->get_active(); @@ -3926,8 +3961,10 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited pe->locallab.spots.at(pp->locallab.selspot).structcol = pe->locallab.spots.at(pp->locallab.selspot).structcol || structcol->getEditedState(); pe->locallab.spots.at(pp->locallab.selspot).qualitycurveMethod = pe->locallab.spots.at(pp->locallab.selspot).qualitycurveMethod || qualitycurveMethod->get_active_text() != M("GENERAL_UNCHANGED"); pe->locallab.spots.at(pp->locallab.selspot).gridMethod = pe->locallab.spots.at(pp->locallab.selspot).gridMethod || gridMethod->get_active_text() != M("GENERAL_UNCHANGED"); + pe->locallab.spots.at(pp->locallab.selspot).toneMethod = pe->locallab.spots.at(pp->locallab.selspot).toneMethod || toneMethod->get_active_text() != M("GENERAL_UNCHANGED"); pe->locallab.spots.at(pp->locallab.selspot).mergecolMethod = pe->locallab.spots.at(pp->locallab.selspot).mergecolMethod || mergecolMethod->get_active_text() != M("GENERAL_UNCHANGED"); pe->locallab.spots.at(pp->locallab.selspot).llcurve = pe->locallab.spots.at(pp->locallab.selspot).llcurve || !llshape->isUnChanged(); + pe->locallab.spots.at(pp->locallab.selspot).rgbcurve = pe->locallab.spots.at(pp->locallab.selspot).rgbcurve || !rgbshape->isUnChanged(); pe->locallab.spots.at(pp->locallab.selspot).cccurve = pe->locallab.spots.at(pp->locallab.selspot).cccurve || !ccshape->isUnChanged(); pe->locallab.spots.at(pp->locallab.selspot).LHcurve = pe->locallab.spots.at(pp->locallab.selspot).LHcurve || !LHshape->isUnChanged(); pe->locallab.spots.at(pp->locallab.selspot).HHcurve = pe->locallab.spots.at(pp->locallab.selspot).HHcurve || !HHshape->isUnChanged(); @@ -4247,8 +4284,10 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited pedited->locallab.spots.at(pp->locallab.selspot).structcol = pedited->locallab.spots.at(pp->locallab.selspot).structcol || structcol->getEditedState(); pedited->locallab.spots.at(pp->locallab.selspot).qualitycurveMethod = pedited->locallab.spots.at(pp->locallab.selspot).qualitycurveMethod || qualitycurveMethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->locallab.spots.at(pp->locallab.selspot).gridMethod = pedited->locallab.spots.at(pp->locallab.selspot).gridMethod || gridMethod->get_active_text() != M("GENERAL_UNCHANGED"); + pedited->locallab.spots.at(pp->locallab.selspot).toneMethod = pedited->locallab.spots.at(pp->locallab.selspot).toneMethod || toneMethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->locallab.spots.at(pp->locallab.selspot).mergecolMethod = pedited->locallab.spots.at(pp->locallab.selspot).mergecolMethod || mergecolMethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->locallab.spots.at(pp->locallab.selspot).llcurve = pedited->locallab.spots.at(pp->locallab.selspot).llcurve || !llshape->isUnChanged(); + pedited->locallab.spots.at(pp->locallab.selspot).rgbcurve = pedited->locallab.spots.at(pp->locallab.selspot).rgbcurve || !rgbshape->isUnChanged(); pedited->locallab.spots.at(pp->locallab.selspot).cccurve = pedited->locallab.spots.at(pp->locallab.selspot).cccurve || !ccshape->isUnChanged(); pedited->locallab.spots.at(pp->locallab.selspot).LHcurve = pedited->locallab.spots.at(pp->locallab.selspot).LHcurve || !LHshape->isUnChanged(); pedited->locallab.spots.at(pp->locallab.selspot).HHcurve = pedited->locallab.spots.at(pp->locallab.selspot).HHcurve || !HHshape->isUnChanged(); @@ -4633,6 +4672,12 @@ void Locallab::curveChanged(CurveEditor* ce) } } + if (ce == rgbshape) { + if (listener) { + listener->panelChanged(Evlocallabrgbshape, M("HISTORY_CUSTOMCURVE")); + } + } + if (ce == LHshape) { if (listener) { listener->panelChanged(EvlocallabLHshape, M("HISTORY_CUSTOMCURVE")); @@ -5064,6 +5109,16 @@ void Locallab::gridMethodChanged() } } +void Locallab::toneMethodChanged() +{ + // printf("qualitycurveMethodChanged\n"); + + if (getEnabled() && expcolor->getEnabled()) { + if (listener) { + listener->panelChanged(EvLocallabtoneMethod, toneMethod->get_active_text()); + } + } +} void Locallab::mergecolMethodChanged() { @@ -8247,6 +8302,7 @@ void Locallab::setBatchMode(bool batchMode) // Color & Light qualitycurveMethod->append(M("GENERAL_UNCHANGED")); gridMethod->append(M("GENERAL_UNCHANGED")); + toneMethod->append(M("GENERAL_UNCHANGED")); mergecolMethod->append(M("GENERAL_UNCHANGED")); //exposure expMethod->append(M("GENERAL_UNCHANGED")); @@ -8415,6 +8471,7 @@ void Locallab::enableListener() curvactivConn.block(false); qualitycurveMethodConn.block(false); gridMethodConn.block(false); + toneMethodConn.block(false); mergecolMethodConn.block(false); inversConn.block(false); showmaskcolMethodConn.block(false); @@ -8496,6 +8553,7 @@ void Locallab::disableListener() curvactivConn.block(true); qualitycurveMethodConn.block(true); gridMethodConn.block(true); + toneMethodConn.block(true); mergecolMethodConn.block(true); inversConn.block(true); showmaskcolMethodConn.block(true); @@ -8596,6 +8654,14 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con gridMethod->set_active(1); } + if (pp->locallab.spots.at(index).toneMethod == "one") { + toneMethod->set_active(0); + } else if (pp->locallab.spots.at(index).toneMethod == "two") { + toneMethod->set_active(1); + } else if (pp->locallab.spots.at(index).toneMethod == "thr") { + toneMethod->set_active(2); + } + if (pp->locallab.spots.at(index).mergecolMethod == "one") { mergecolMethod->set_active(0); } else if (pp->locallab.spots.at(index).mergecolMethod == "two") { @@ -8640,6 +8706,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con llshape->setCurve(pp->locallab.spots.at(index).llcurve); ccshape->setCurve(pp->locallab.spots.at(index).cccurve); + rgbshape->setCurve(pp->locallab.spots.at(index).rgbcurve); LHshape->setCurve(pp->locallab.spots.at(index).LHcurve); HHshape->setCurve(pp->locallab.spots.at(index).HHcurve); invers->set_active(pp->locallab.spots.at(index).invers); @@ -9051,12 +9118,17 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con gridMethod->set_active_text(M("GENERAL_UNCHANGED")); } - if (!spotState->gridMethod) { + if (!spotState->toneMethod) { + toneMethod->set_active_text(M("GENERAL_UNCHANGED")); + } + + if (!spotState->mergecolMethod) { mergecolMethod->set_active_text(M("GENERAL_UNCHANGED")); } llshape->setUnChanged(!spotState->llcurve); ccshape->setUnChanged(!spotState->cccurve); + rgbshape->setUnChanged(!spotState->rgbcurve); LHshape->setUnChanged(!spotState->LHcurve); HHshape->setUnChanged(!spotState->HHcurve); invers->set_inconsistent(multiImage && !spotState->invers); diff --git a/rtgui/locallab.h b/rtgui/locallab.h index eb2c81aed..571479e64 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -73,12 +73,14 @@ private: // Color & Light CurveEditorGroup* const llCurveEditorG; CurveEditorGroup* const HCurveEditorG; + CurveEditorGroup* const rgbCurveEditorG; CurveEditorGroup* const maskCurveEditorG; CurveEditorGroup* const mask2CurveEditorG; CurveEditorGroup* const mask2CurveEditorGwav; DiagonalCurveEditor* Lmaskshape; DiagonalCurveEditor* llshape; DiagonalCurveEditor* ccshape; + DiagonalCurveEditor* rgbshape; FlatCurveEditor* LHshape; FlatCurveEditor* HHshape; FlatCurveEditor* CCmaskshape; @@ -392,6 +394,8 @@ private: sigc::connection qualitycurveMethodConn; MyComboBoxText* const gridMethod; sigc::connection gridMethodConn; + MyComboBoxText* const toneMethod; + sigc::connection toneMethodConn; MyComboBoxText* const showmaskcolMethod; sigc::connection showmaskcolMethodConn; MyComboBoxText* const showmaskcolMethodinv; @@ -549,6 +553,7 @@ private: // Color & Light void qualitycurveMethodChanged(); void gridMethodChanged(); + void toneMethodChanged(); void showmaskcolMethodChanged(); void showmaskcolMethodChangedinv(); void mergecolMethodChanged(); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 5b16a7394..d75668f63 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1004,8 +1004,10 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).lapmaskcol = locallab.spots.at(j).lapmaskcol && pSpot.lapmaskcol == otherSpot.lapmaskcol; locallab.spots.at(j).qualitycurveMethod = locallab.spots.at(j).qualitycurveMethod && pSpot.qualitycurveMethod == otherSpot.qualitycurveMethod; locallab.spots.at(j).gridMethod = locallab.spots.at(j).gridMethod && pSpot.gridMethod == otherSpot.gridMethod; + locallab.spots.at(j).toneMethod = locallab.spots.at(j).toneMethod && pSpot.toneMethod == otherSpot.toneMethod; locallab.spots.at(j).mergecolMethod = locallab.spots.at(j).mergecolMethod && pSpot.mergecolMethod == otherSpot.mergecolMethod; locallab.spots.at(j).llcurve = locallab.spots.at(j).llcurve && pSpot.llcurve == otherSpot.llcurve; + locallab.spots.at(j).rgbcurve = locallab.spots.at(j).llcurve && pSpot.rgbcurve == otherSpot.rgbcurve; locallab.spots.at(j).cccurve = locallab.spots.at(j).cccurve && pSpot.cccurve == otherSpot.cccurve; locallab.spots.at(j).LHcurve = locallab.spots.at(j).LHcurve && pSpot.LHcurve == otherSpot.LHcurve; locallab.spots.at(j).HHcurve = locallab.spots.at(j).HHcurve && pSpot.HHcurve == otherSpot.HHcurve; @@ -2936,6 +2938,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).gridMethod = mods.locallab.spots.at(i).gridMethod; } + if (locallab.spots.at(i).toneMethod) { + toEdit.locallab.spots.at(i).toneMethod = mods.locallab.spots.at(i).toneMethod; + } + if (locallab.spots.at(i).mergecolMethod) { toEdit.locallab.spots.at(i).mergecolMethod = mods.locallab.spots.at(i).mergecolMethod; } @@ -2944,6 +2950,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).llcurve = mods.locallab.spots.at(i).llcurve; } + if (locallab.spots.at(i).rgbcurve) { + toEdit.locallab.spots.at(i).rgbcurve = mods.locallab.spots.at(i).rgbcurve; + } + if (locallab.spots.at(i).cccurve) { toEdit.locallab.spots.at(i).cccurve = mods.locallab.spots.at(i).cccurve; } @@ -4926,9 +4936,11 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : lapmaskcol(v), qualitycurveMethod(v), gridMethod(v), + toneMethod(v), mergecolMethod(v), llcurve(v), cccurve(v), + rgbcurve(v), LHcurve(v), HHcurve(v), invers(v), @@ -5235,9 +5247,11 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) lapmaskcol = v; qualitycurveMethod = v; gridMethod = v; + toneMethod = v; mergecolMethod = v; llcurve = v; cccurve = v; + rgbcurve = v; LHcurve = v; HHcurve = v; invers = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 2e288f1eb..8bf5cec1c 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -434,9 +434,11 @@ public: bool lapmaskcol; bool qualitycurveMethod; bool gridMethod; + bool toneMethod; bool mergecolMethod; bool llcurve; bool cccurve; + bool rgbcurve; bool LHcurve; bool HHcurve; bool invers;