diff --git a/rtdata/languages/default b/rtdata/languages/default index 7bc855a5d..f842edff5 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -873,6 +873,7 @@ HISTORY_MSG_617;Local - Blur Exp HISTORY_MSG_618;Local - Use Color Mask HISTORY_MSG_619;Local - Use Exp Mask HISTORY_MSG_620;Local - Blur col +HISTORY_MSG_621;Local - Exp inverse 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/improcfun.h b/rtengine/improcfun.h index f9bc1a52f..90915924d 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -308,7 +308,7 @@ public: void fftw_denoise(int GW, int GH, int max_numblox_W, int min_numblox_W, float **tmp1, array2D *Lin, int numThreads, const struct local_params & lp, int chrom); void ColorLight_Local(float moddE, float powdE, int call, LabImage * bufcolorig, LabImage * originalmask, float **buflight, float **bufchro, float **bufchroslid, float ** bufhh, float ** buflightslid, bool &LHutili, bool &HHutili, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, float sobelref, float ** blend2, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, LUTf & lightCurveloc, const local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy, int sk); - void InverseColorLight_Local(const struct local_params& lp, LUTf & lightCurveloc, LabImage* original, LabImage* transformed, int cx, int cy, const float hueref, const float chromaref, const float lumaref, int sk); + void InverseColorLight_Local(int sp, int senstype, const struct local_params& lp, LUTf & lightCurveloc, LUTf & hltonecurveloc, LUTf & shtonecurveloc, LUTf & tonecurveloc, LabImage* original, LabImage* transformed, int cx, int cy, const float hueref, const float chromaref, const float lumaref, int sk); void Sharp_Local(int call, float **loctemp, int senstype, const float hueref, const float chromaref, const float lumaref, const local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk); // void Sharp_Local(int call, float **loctemp, int senstype, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy, int sk); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 6c2333c51..89227f2f5 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -177,6 +177,7 @@ struct local_params { int trans; int dehaze; bool inv; + bool invex; bool curvact; bool invrad; bool invret; @@ -478,6 +479,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall bool acti = locallab.spots.at(sp).activlum; bool cupas = false; // Provision int local_sensisf = locallab.spots.at(sp).sensisf; + bool inverseex = locallab.spots.at(sp).inversex; bool inverserad = false; // Provision bool inverseret = locallab.spots.at(sp).inversret; @@ -525,6 +527,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.senslc = local_sensilc; lp.lcamount = lcamount; lp.inv = inverse; + lp.invex = inverseex; lp.curvact = curvacti; lp.invrad = inverserad; lp.invret = inverseret; @@ -4081,17 +4084,38 @@ void ImProcFunctions::transit_shapedetect(int senstype, LabImage * bufexporig, L } } -void ImProcFunctions::InverseColorLight_Local(const struct local_params & lp, LUTf & lightCurveloc, LabImage * original, LabImage * transformed, int cx, int cy, const float hueref, const float chromaref, const float lumaref, int sk) +void ImProcFunctions::InverseColorLight_Local(int sp, int senstype, const struct local_params & lp, LUTf & lightCurveloc, LUTf & hltonecurveloc, LUTf & shtonecurveloc, LUTf & tonecurveloc, LabImage * original, LabImage * transformed, int cx, int cy, const float hueref, const float chromaref, const float lumaref, int sk) { // BENCHFUN float ach = (float)lp.trans / 100.f; const float facc = (100.f + lp.chro) / 100.f; //chroma factor transition + // ImProcFunctions::exlabLocal(lp, bfh, bfw, bufexptemp, bufexpfin, hltonecurveloc, shtonecurveloc, tonecurveloc); + float varsens = lp.sens; + + if (senstype == 0) { //Color and Light + varsens = lp.sens; + } + + if (senstype == 1) { //exposure + varsens = lp.sensex; + } + + LabImage *temp = nullptr; int GW = transformed->W; int GH = transformed->H; float refa = chromaref * cos(hueref); float refb = chromaref * sin(hueref); + if (senstype == 1) { //exposure + temp = new LabImage(GW, GH); + ImProcFunctions::exlabLocal(lp, GH, GW, original, temp, hltonecurveloc, shtonecurveloc, tonecurveloc); + + if (lp.war != 0) { + ImProcFunctions::ciecamloc_02float(sp, temp, temp); + } + } + LabImage *origblur = nullptr; origblur = new LabImage(GW, GH); @@ -4176,8 +4200,8 @@ void ImProcFunctions::InverseColorLight_Local(const struct local_params & lp, LU dE = sqrt(SQR(refa - origblur->a[y][x] / 327.68f) + SQR(refb - origblur->b[y][x] / 327.68f) + SQR(lumaref - rL)); float reducdE = 0.f; - float mindE = 2.f + minscope * lp.sens * lp.thr; - float maxdE = 5.f + maxscope * lp.sens * (1 + 0.1f * lp.thr); + float mindE = 2.f + minscope * varsens * lp.thr; + float maxdE = 5.f + maxscope * varsens * (1 + 0.1f * lp.thr); float ar = 1.f / (mindE - maxdE); @@ -4214,45 +4238,63 @@ void ImProcFunctions::InverseColorLight_Local(const struct local_params & lp, LU } case 1: { // inside transition zone - float lumnew = original->L[y][x]; + float diflc = 0.f; + float difa = 0.f; + float difb = 0.f; + float factorx = 1.f - localFactor; + float fac = 1.f; - if (lp.sens < 75.f) { - float lightcont; - - if ((lp.ligh != 0.f || lp.cont != 0)) { - calclight(lumnew, lp.ligh, lumnew, lightCurveloc); //replace L-curve - lightcont = lumnew; - - } else { - lightcont = lumnew; - } - - float factorx = 1.f - localFactor; - float fac = (100.f + factorx * lp.chro * reducdE) / 100.f; //chroma factor transition - float diflc = (lightcont - original->L[y][x]) * reducdE; - - diflc *= factorx; //transition lightness - transformed->L[y][x] = CLIP(1.f * (original->L[y][x] + diflc)); - - transformed->a[y][x] = CLIPC(original->a[y][x] * fac) ; - transformed->b[y][x] = CLIPC(original->b[y][x] * fac); - } else { - float factorx = 1.f - localFactor; - float fac = (100.f + factorx * lp.chro) / 100.f; //chroma factor transition + if (senstype == 0) { float lumnew = original->L[y][x]; - if ((lp.ligh != 0.f || lp.cont != 0)) { - calclight(original->L[y][x], lp.ligh, lumnew, lightCurveloc); + if (lp.sens < 75.f) { + float lightcont; + + if ((lp.ligh != 0.f || lp.cont != 0)) { + calclight(lumnew, lp.ligh, lumnew, lightCurveloc); //replace L-curve + lightcont = lumnew; + + } else { + lightcont = lumnew; + } + + fac = (100.f + factorx * lp.chro * reducdE) / 100.f; //chroma factor transition + diflc = (lightcont - original->L[y][x]) * reducdE; + + diflc *= factorx; //transition lightness + transformed->L[y][x] = CLIP(1.f * (original->L[y][x] + diflc)); + + transformed->a[y][x] = CLIPC(original->a[y][x] * fac) ; + transformed->b[y][x] = CLIPC(original->b[y][x] * fac); + } else { + float factorx = 1.f - localFactor; + float fac = (100.f + factorx * lp.chro) / 100.f; //chroma factor transition + float lumnew = original->L[y][x]; + + if ((lp.ligh != 0.f || lp.cont != 0)) { + calclight(original->L[y][x], lp.ligh, lumnew, lightCurveloc); + } + + float lightcont = lumnew ; //apply lightness + + float diflc = lightcont - original->L[y][x]; + diflc *= factorx; + transformed->L[y][x] = CLIP(original->L[y][x] + diflc); + transformed->a[y][x] = CLIPC(original->a[y][x] * fac); + transformed->b[y][x] = CLIPC(original->b[y][x] * fac); + + } - - float lightcont = lumnew ; //apply lightness - - float diflc = lightcont - original->L[y][x]; + } else if (senstype == 1) { + diflc = (temp->L[y][x] - original->L[y][x]) * reducdE; diflc *= factorx; + difa = (temp->a[y][x] - original->a[y][x]) * reducdE; + difb = (temp->b[y][x] - original->b[y][x]) * reducdE; + difa *= factorx; + difb *= factorx; transformed->L[y][x] = CLIP(original->L[y][x] + diflc); - transformed->a[y][x] = CLIPC(original->a[y][x] * fac); - transformed->b[y][x] = CLIPC(original->b[y][x] * fac); - + transformed->a[y][x] = CLIPC(original->a[y][x] + difa) ; + transformed->b[y][x] = CLIPC(original->b[y][x] + difb); } @@ -4260,42 +4302,59 @@ void ImProcFunctions::InverseColorLight_Local(const struct local_params & lp, LU } case 0: { // inside selection => full effect, no transition - float lumnew = original->L[y][x]; + float diflc = 0.f; + float difa = 0.f; + float difb = 0.f; + float fac = 1.f; - if (lp.sens < 75.f) { + if (senstype == 0) { + float lumnew = original->L[y][x]; - float lightcont; + if (lp.sens < 75.f) { + + float lightcont; + + if ((lp.ligh != 0.f || lp.cont != 0)) { + calclight(lumnew, lp.ligh, lumnew, lightCurveloc); //replace L-curve + lightcont = lumnew; + + } else { + lightcont = lumnew; + } + + fac = (100.f + lp.chro * reducdE) / 100.f; //chroma factor transition + diflc = (lightcont - original->L[y][x]) * reducdE; + + transformed->L[y][x] = CLIP(1.f * (original->L[y][x] + diflc)); + + transformed->a[y][x] = CLIPC(original->a[y][x] * fac) ; + transformed->b[y][x] = CLIPC(original->b[y][x] * fac); - if ((lp.ligh != 0.f || lp.cont != 0)) { - calclight(lumnew, lp.ligh, lumnew, lightCurveloc); //replace L-curve - lightcont = lumnew; } else { - lightcont = lumnew; + if ((lp.ligh != 0.f || lp.cont != 0)) { + calclight(original->L[y][x], lp.ligh, lumnew, lightCurveloc); + } + + float lightcont = lumnew ; + transformed->L[y][x] = CLIP(lightcont); + transformed->a[y][x] = CLIPC(original->a[y][x] * facc); + transformed->b[y][x] = CLIPC(original->b[y][x] * facc); + } + } else if (senstype == 1) { - float fac = (100.f + lp.chro * reducdE) / 100.f; //chroma factor transition - float diflc = (lightcont - original->L[y][x]) * reducdE; - - transformed->L[y][x] = CLIP(1.f * (original->L[y][x] + diflc)); - - transformed->a[y][x] = CLIPC(original->a[y][x] * fac) ; - transformed->b[y][x] = CLIPC(original->b[y][x] * fac); - - - } else { - if ((lp.ligh != 0.f || lp.cont != 0)) { - calclight(original->L[y][x], lp.ligh, lumnew, lightCurveloc); - } - - float lightcont = lumnew ; - transformed->L[y][x] = CLIP(lightcont); - transformed->a[y][x] = CLIPC(original->a[y][x] * facc); - transformed->b[y][x] = CLIPC(original->b[y][x] * facc); - + diflc = (temp->L[y][x] - original->L[y][x]) * reducdE; + difa = (temp->a[y][x] - original->a[y][x]) * reducdE; + difb = (temp->b[y][x] - original->b[y][x]) * reducdE; + transformed->L[y][x] = CLIP(original->L[y][x] + diflc); + transformed->a[y][x] = CLIPC(original->a[y][x] + difa) ; + transformed->b[y][x] = CLIPC(original->b[y][x] + difb); } + } } + } } @@ -4303,6 +4362,10 @@ void ImProcFunctions::InverseColorLight_Local(const struct local_params & lp, LU } delete origblur; + if (senstype == 1) { + delete temp; + } + } void ImProcFunctions::calc_ref(int befend, int sp, LabImage * original, LabImage * transformed, int cx, int cy, int oW, int oH, int sk, double & huerefblur, double & chromarefblur, double & lumarefblur, double & hueref, double & chromaref, double & lumaref, double & sobelref, float &avg) @@ -4779,7 +4842,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o noiscfactiv = false; } - if (lp.inv || lp.invret) { //exterior || lp.curvact + if (lp.inv || lp.invret || lp.invex) { //exterior || lp.curvact ave = 0.f; n = 0; #pragma omp parallel for reduction(+:ave,n) @@ -7087,7 +7150,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o } - if (lp.exposena && (lp.expcomp != 0.f || lp.war != 0 || lp.showmaskexpmet == 2 || lp.enaExpMask || lp.showmaskexpmet == 3 || lp.showmaskexpmet == 4 || (exlocalcurve && localexutili))) { //interior ellipse renforced lightness and chroma //locallutili + if (!lp.invex && (lp.exposena && (lp.expcomp != 0.f || lp.war != 0 || lp.showmaskexpmet == 2 || lp.enaExpMask || lp.showmaskexpmet == 3 || lp.showmaskexpmet == 4 || (exlocalcurve && localexutili)))) { //interior ellipse renforced lightness and chroma //locallutili LabImage *bufexporig = nullptr; LabImage *bufexpfin = nullptr; LabImage *bufexptemp = nullptr; @@ -7619,6 +7682,11 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o } } +//inverse + else if (lp.invex && (lp.expcomp != 0 || lp.war != 0) && lp.exposena) { + + InverseColorLight_Local(sp, 1, lp, lightCurveloc, hltonecurveloc, shtonecurveloc, tonecurveloc, original, transformed, cx, cy, hueref, chromaref, lumaref, sk); + } //local color and light @@ -8159,7 +8227,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o //inverse else if (lp.inv && (lp.chro != 0 || lp.ligh != 0) && lp.colorena) { - InverseColorLight_Local(lp, lightCurveloc, original, transformed, cx, cy, hueref, chromaref, lumaref, sk); + InverseColorLight_Local(sp, 0, lp, lightCurveloc, hltonecurveloc, shtonecurveloc, tonecurveloc, original, transformed, cx, cy, hueref, chromaref, lumaref, sk); } // Gamut and Munsell control - very important do not desactivated to avoid crash diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 2b321324b..3b01efa0d 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -647,6 +647,7 @@ enum ProcEventCode { EvLocallabEnaColorMask = 617, EvLocallabEnaExpMask = 618, Evlocallabblurcolde = 619, + Evlocallabinversex = 620, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 84daf4b8d..317c2df06 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2387,6 +2387,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : structexp(0), blurexpde(5), excurve{(double)DCT_NURBS, 0.0, 0.0, 1.0, 1.0}, + inversex(false), enaExpMask(false), CCmaskexpcurve{(double)FCT_MinMaxCPoints,0.0, 1.0, 0.35, 0.35, 0.50, 1.0, 0.35, 0.35, 1.0, 1.0, 0.35, 0.35 }, LLmaskexpcurve{(double)FCT_MinMaxCPoints, 0.0, 1.0, 0.35, 0.35, 0.50, 1.0, 0.35, 0.35, 1.0, 1.0, 0.35, 0.35}, @@ -2529,6 +2530,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && structexp == other.structexp && blurexpde == other.blurexpde && excurve == other.excurve + && inversex == other.inversex && enaExpMask == other.enaExpMask && CCmaskexpcurve == other.CCmaskexpcurve && LLmaskexpcurve == other.LLmaskexpcurve @@ -3624,6 +3626,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->locallab.spots.at(i).structexp, "Locallab", "Structexp_" + std::to_string(i), spot.structexp, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).blurexpde, "Locallab", "Blurexpde_" + std::to_string(i), spot.blurexpde, 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).inversex, "Locallab", "Inversex_" + std::to_string(i), spot.inversex, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).enaExpMask, "Locallab", "EnaExpMask_" + std::to_string(i), spot.enaExpMask, 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); @@ -4851,6 +4854,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Structexp_" + std::to_string(i), pedited, spot.structexp, spotEdited.structexp); assignFromKeyfile(keyFile, "Locallab", "Blurexpde_" + std::to_string(i), pedited, spot.blurexpde, spotEdited.blurexpde); assignFromKeyfile(keyFile, "Locallab", "ExCurve_" + std::to_string(i), pedited, spot.excurve, spotEdited.excurve); + assignFromKeyfile(keyFile, "Locallab", "Inversex_" + std::to_string(i), pedited, spot.inversex, spotEdited.inversex); assignFromKeyfile(keyFile, "Locallab", "EnaExpMask_" + std::to_string(i), pedited, spot.enaExpMask, spotEdited.enaExpMask); 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); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 91eb31c11..0c8eefbc1 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -987,6 +987,7 @@ struct LocallabParams { int structexp; int blurexpde; std::vector excurve; + bool inversex; bool enaExpMask; std::vector CCmaskexpcurve; std::vector LLmaskexpcurve; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index fd6d966e0..a8d4c46e2 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -646,7 +646,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, // Evlocallabblurexpde LUMINANCECURVE, // EvLocallabEnaColorMask LUMINANCECURVE, // EvLocallabEnaExpMask - LUMINANCECURVE // Evlocallabblurcolde + LUMINANCECURVE, // Evlocallabblurcolde + LUMINANCECURVE // Evlocallabinversex }; diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 8668313cd..6d5057f37 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -152,6 +152,7 @@ Locallab::Locallab(): enaColorMask(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ENABLE_MASK")))), // Exposure enaExpMask(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ENABLE_MASK")))), + inversex(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_INVERS")))), // Vibrance protectSkins(Gtk::manage(new Gtk::CheckButton(M("TP_VIBRANCE_PROTECTSKINS")))), avoidColorShift(Gtk::manage(new Gtk::CheckButton(M("TP_VIBRANCE_AVOIDCOLORSHIFT")))), @@ -188,6 +189,7 @@ Locallab::Locallab(): transLabels(Gtk::manage (new Gtk::Label ("---"))), transLabels2(Gtk::manage (new Gtk::Label ("---"))), maskcolFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_SHOW")))), + maskexpFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_SHOW")))), // Others defparams(nullptr), @@ -390,6 +392,7 @@ Locallab::Locallab(): sensiex->set_tooltip_text(M("TP_LOCALLAB_SENSI_TOOLTIP")); sensiex->setAdjusterListener(this); + inversexConn = inversex->signal_toggled().connect(sigc::mem_fun(*this, &Locallab::inversexChanged)); structexp->setAdjusterListener(this); @@ -456,7 +459,8 @@ Locallab::Locallab(): exposeBox->pack_start(*structexp); exposeBox->pack_start(*blurexpde); exposeBox->pack_start(*curveEditorG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor - Gtk::Frame* const maskexpFrame = Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_SHOW"))); + exposeBox->pack_start(*inversex); +// Gtk::Frame* const 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(*transLabels2, Gtk::PACK_SHRINK, 4); @@ -1546,6 +1550,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pp->locallab.spots.at(pp->locallab.selspot).structexp = structexp->getIntValue(); pp->locallab.spots.at(pp->locallab.selspot).blurexpde = blurexpde->getIntValue(); pp->locallab.spots.at(pp->locallab.selspot).excurve = shapeexpos->getCurve(); + pp->locallab.spots.at(pp->locallab.selspot).inversex = inversex->get_active(); pp->locallab.spots.at(pp->locallab.selspot).enaExpMask = enaExpMask->get_active(); pp->locallab.spots.at(pp->locallab.selspot).LLmaskexpcurve = LLmaskexpshape->getCurve(); pp->locallab.spots.at(pp->locallab.selspot).CCmaskexpcurve = CCmaskexpshape->getCurve(); @@ -1706,6 +1711,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pe->locallab.spots.at(pp->locallab.selspot).structexp = pe->locallab.spots.at(pp->locallab.selspot).structexp || structexp->getEditedState(); pe->locallab.spots.at(pp->locallab.selspot).blurexpde = pe->locallab.spots.at(pp->locallab.selspot).blurexpde || blurexpde->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).inversex = pe->locallab.spots.at(pp->locallab.selspot).inversex || !inversex->get_inconsistent(); pe->locallab.spots.at(pp->locallab.selspot).enaExpMask = pe->locallab.spots.at(pp->locallab.selspot).enaExpMask || !enaExpMask->get_inconsistent(); 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(); @@ -1853,6 +1859,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pedited->locallab.spots.at(pp->locallab.selspot).structexp = pedited->locallab.spots.at(pp->locallab.selspot).structexp || structexp->getEditedState(); pedited->locallab.spots.at(pp->locallab.selspot).blurexpde = pedited->locallab.spots.at(pp->locallab.selspot).blurexpde || blurexpde->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).inversex = pedited->locallab.spots.at(pp->locallab.selspot).inversex || !inversex->get_inconsistent(); pedited->locallab.spots.at(pp->locallab.selspot).enaExpMask = pedited->locallab.spots.at(pp->locallab.selspot).enaExpMask || !enaExpMask->get_inconsistent(); 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(); @@ -2337,6 +2344,58 @@ void Locallab::inversChanged() } } + +void Locallab::inversexChanged() +{ + // printf("inversChanged\n"); + + if (multiImage) { + if (inversex->get_inconsistent()) { + inversex->set_inconsistent(false); + inversexConn.block(true); + inversex->set_active(false); + inversexConn.block(false); + } + } + + // Update Color & Light GUI according to invers button state (to be compliant with updateSpecificGUIState function) + if (multiImage && inversex->get_inconsistent()) { + sensiex->show(); + curveEditorG->show(); + maskexpFrame->show(); + structexp->show(); + blurexpde->show(); + showmaskexpMethod->hide(); // Being able to change Color & Light mask visibility is useless in batch mode + } else if (inversex->get_active()) { + sensiex->show(); + curveEditorG->hide(); + maskexpFrame->hide(); + structexp->hide(); + blurexpde->hide(); + + } else { + sensiex->show(); + curveEditorG->show(); + maskexpFrame->show(); + structexp->show(); + blurexpde->show(); + + if (batchMode) { + showmaskexpMethod->hide(); // Being able to change Color & Light mask visibility is useless in batch mode + } + } + + if (getEnabled() && expexpose->getEnabled()) { + if (listener) { + if (inversex->get_active()) { + listener->panelChanged(Evlocallabinversex, M("GENERAL_ENABLED")); + } else { + listener->panelChanged(Evlocallabinversex, M("GENERAL_DISABLED")); + } + } + } +} + void Locallab::curvactivChanged() { // printf("curvactivChanged\n"); @@ -3533,6 +3592,7 @@ void Locallab::enableListener() enaColorMaskConn.block(false); // Exposure enableexposeConn.block(false); + inversexConn.block(false); showmaskexpMethodConn.block(false); enaExpMaskConn.block(false); // Vibrance @@ -3580,6 +3640,7 @@ void Locallab::disableListener() enaColorMaskConn.block(true); // Exposure enableexposeConn.block(true); + inversexConn.block(true); showmaskexpMethodConn.block(true); enaExpMaskConn.block(true); // Vibrance @@ -3658,6 +3719,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con structexp->setValue(pp->locallab.spots.at(index).structexp); blurexpde->setValue(pp->locallab.spots.at(index).blurexpde); shapeexpos->setCurve(pp->locallab.spots.at(index).excurve); + inversex->set_active(pp->locallab.spots.at(index).inversex); enaExpMask->set_active(pp->locallab.spots.at(index).enaExpMask); CCmaskexpshape->setCurve(pp->locallab.spots.at(index).CCmaskexpcurve); LLmaskexpshape->setCurve(pp->locallab.spots.at(index).LLmaskexpcurve); @@ -3845,6 +3907,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con structexp->setEditedState(spotState->structexp ? Edited : UnEdited); blurexpde->setEditedState(spotState->blurexpde ? Edited : UnEdited); shapeexpos->setUnChanged(!spotState->excurve); + inversex->set_inconsistent(multiImage && !spotState->inversex); enaExpMask->set_inconsistent(multiImage && !spotState->enaExpMask); CCmaskexpshape->setUnChanged(!spotState->CCmaskexpcurve); LLmaskexpshape->setUnChanged(!spotState->LLmaskexpcurve); @@ -3993,6 +4056,32 @@ void Locallab::updateSpecificGUIState() } // Update Exposure GUI according to black adjuster state (to be compliant with adjusterChanged function) + if (multiImage && inversex->get_inconsistent()) { + sensiex->show(); + curveEditorG->show(); + maskexpFrame->show(); + structexp->show(); + blurexpde->show(); + showmaskexpMethod->hide(); // Being able to change Color & Light mask visibility is useless in batch mode + } else if (inversex->get_active()) { + sensiex->show(); + curveEditorG->hide(); + maskexpFrame->hide(); + structexp->hide(); + blurexpde->hide(); + } else { + sensiex->show(); + curveEditorG->show(); + maskexpFrame->show(); + structexp->show(); + blurexpde->show(); + if (batchMode) { + showmaskexpMethod->hide(); // Being able to change Color & Light mask visibility is useless in batch mode + } + } + + + if (multiImage && black->getEditedState() != Edited) { shcompr->set_sensitive(true); } else { diff --git a/rtgui/locallab.h b/rtgui/locallab.h index 87f535653..e215e34c2 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -171,6 +171,8 @@ private: // Exposure Gtk::CheckButton* const enaExpMask; sigc::connection enaExpMaskConn; + Gtk::CheckButton* const inversex; + sigc::connection inversexConn; // Vibrance Gtk::CheckButton* const protectSkins; Gtk::CheckButton* const avoidColorShift; @@ -218,6 +220,7 @@ private: Gtk::Label* transLabels; Gtk::Label* transLabels2; Gtk::Frame* maskcolFrame; + Gtk::Frame* maskexpFrame; // Others /** @@ -247,6 +250,7 @@ private: void enaColorMaskChanged(); // Exposure void enaExpMaskChanged(); + void inversexChanged(); // Vibrance void protectskins_toggled(); void avoidcolorshift_toggled(); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index a2b0e9f03..70bfe534a 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -973,6 +973,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).structexp = locallab.spots.at(j).structexp && pSpot.structexp == otherSpot.structexp; locallab.spots.at(j).blurexpde = locallab.spots.at(j).blurexpde && pSpot.blurexpde == otherSpot.blurexpde; locallab.spots.at(j).excurve = locallab.spots.at(j).excurve && pSpot.excurve == otherSpot.excurve; + locallab.spots.at(j).inversex = locallab.spots.at(j).inversex && pSpot.invers == otherSpot.inversex; locallab.spots.at(j).enaExpMask = locallab.spots.at(j).enaExpMask && pSpot.enaExpMask == otherSpot.enaExpMask; 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; @@ -2679,6 +2680,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).excurve = mods.locallab.spots.at(i).excurve; } + if (locallab.spots.at(i).inversex) { + toEdit.locallab.spots.at(i).inversex = mods.locallab.spots.at(i).inversex; + } + if (locallab.spots.at(i).enaExpMask) { toEdit.locallab.spots.at(i).enaExpMask = mods.locallab.spots.at(i).enaExpMask; } @@ -3975,6 +3980,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : structexp(v), blurexpde(v), excurve(v), + inversex(v), enaExpMask(v), CCmaskexpcurve(v), LLmaskexpcurve(v), @@ -4114,6 +4120,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) structexp = v; blurexpde = v; excurve = v; + inversex = v; enaExpMask = v; CCmaskexpcurve = v; LLmaskexpcurve = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 77825b262..4b3d2d6ef 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -512,6 +512,7 @@ public: bool structexp; bool blurexpde; bool excurve; + bool inversex; bool enaExpMask; bool CCmaskexpcurve; bool LLmaskexpcurve;