diff --git a/rtdata/languages/default b/rtdata/languages/default index c408ce3ee..9e96f7ef6 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -885,6 +885,7 @@ HISTORY_MSG_630;Local - SH Shadows HISTORY_MSG_631;Local - SH S tonalwidth HISTORY_MSG_632;Local - SH radius HISTORY_MSG_633;Local - SH Scope +HISTORY_MSG_634;Local - radius color HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -2032,6 +2033,7 @@ TP_LOCALLAB_LIGHTNESS;Lightness TP_LOCALLAB_MASK;Mask: TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. TP_LOCALLAB_RADIUS;Radius +TP_LOCALLAB_RADMASKCOL;Radius TP_LOCALLAB_RETI;Retinex TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain TP_LOCALLAB_STREN;Strength diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 5ab32e3c8..c3f0c8543 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -144,6 +144,7 @@ struct local_params { float strengrid; float struexc; float blendmacol; + float radmacol; float blendmaexp; float struexp; float blurexp; @@ -464,6 +465,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall float structcolor = (float) locallab.spots.at(sp).structcol; float blendmaskcolor = ((float) locallab.spots.at(sp).blendmaskcol) / 100.f ; + float radmaskcolor = ((float) locallab.spots.at(sp).radmaskcol); float blendmaskexpo = ((float) locallab.spots.at(sp).blendmaskexp) / 100.f ; float structexpo = (float) locallab.spots.at(sp).structexp; float blurexpo = (float) locallab.spots.at(sp).blurexpde; @@ -512,6 +514,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.struco = structcolor; lp.strengrid = strengthgrid; lp.blendmacol = blendmaskcolor; + lp.radmacol = radmaskcolor; lp.struexc = structexclude; lp.blendmaexp = blendmaskexpo; lp.struexp = structexpo; @@ -7846,6 +7849,9 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o } + array2D ble(bfw, bfh); + array2D guid(bfw, bfh); + #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif @@ -7917,13 +7923,32 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o bufmaskblurcol->L[loy - begy][lox - begx] = CLIPLOC(kmaskL + kmaskHL); bufmaskblurcol->a[loy - begy][lox - begx] = CLIPC(kmaskCa + kmaskHa); bufmaskblurcol->b[loy - begy][lox - begx] = CLIPC(kmaskCb + kmaskHb); - - + ble[loy - begy][lox - begx] = bufmaskblurcol->L[loy - begy][lox - begx] / 32768.f; + guid[loy - begy][lox - begx] = bufcolorig->L[loy - begy][lox - begx] / 32768.f; } } } - float radiusb = 3.f / sk; + if ((lp.showmaskcolmet == 2 || lp.enaColorMask || lp.showmaskcolmet == 3) && lp.radmacol > 0.f) { + + guidedFilter(guid, ble, ble, lp.radmacol * 10.f / sk, 0.075, multiThread, 4); + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int y = 0; y < transformed->H ; y++) //{ + for (int x = 0; x < transformed->W; x++) { + int lox = cx + x; + int loy = cy + y; + + if (lox >= begx && lox < xEn && loy >= begy && loy < yEn) { + bufmaskblurcol->L[loy - begy][lox - begx] = ble[loy - begy][lox - begx] * 32768.f; + } + } + } + + float radiusb = 1.f / sk; if (lp.showmaskcolmet == 2 || lp.enaColorMask || lp.showmaskcolmet == 3) { #ifdef _OPENMP @@ -7931,8 +7956,8 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o #endif { gaussianBlur(bufmaskblurcol->L, bufmaskorigcol->L, bfw, bfh, radiusb); - gaussianBlur(bufmaskblurcol->a, bufmaskorigcol->a, bfw, bfh, radiusb); - gaussianBlur(bufmaskblurcol->b, bufmaskorigcol->b, bfw, bfh, radiusb); + gaussianBlur(bufmaskblurcol->a, bufmaskorigcol->a, bfw, bfh, 1.f + (0.2f * lp.radmacol) / sk); + gaussianBlur(bufmaskblurcol->b, bufmaskorigcol->b, bfw, bfh, 1.f + (0.2f * lp.radmacol) / sk); } delete bufmaskblurcol; diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 3be067389..0b92f4748 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -660,6 +660,7 @@ enum ProcEventCode { Evlocallabs_tonalwidth = 630, Evlocallabsh_radius = 631, Evlocallabsensihs = 632, + Evlocallabradmaskcol = 633, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 989688044..b8670c4f5 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2372,6 +2372,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : structcol(0), blurcolde(5), blendmaskcol(0), + radmaskcol(10.0), qualitycurveMethod("none"), gridMethod("one"), llcurve{(double)DCT_NURBS, 0.0, 0.0, 1.0, 1.0}, @@ -2528,6 +2529,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && sensi == other.sensi && structcol == other.structcol && blendmaskcol == other.blendmaskcol + && radmaskcol == other.radmaskcol && qualitycurveMethod == other.qualitycurveMethod && gridMethod == other.gridMethod && llcurve == other.llcurve @@ -3641,6 +3643,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->locallab.spots.at(i).structcol, "Locallab", "Structcol_" + std::to_string(i), spot.structcol, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).blurcolde, "Locallab", "Blurcolde_" + std::to_string(i), spot.blurcolde, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).blendmaskcol, "Locallab", "Blendmaskcol_" + std::to_string(i), spot.blendmaskcol, keyFile); + saveToKeyfile(!pedited || pedited->locallab.spots.at(i).radmaskcol, "Locallab", "Radmaskcol_" + std::to_string(i), spot.radmaskcol, 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).llcurve, "Locallab", "LLCurve_" + std::to_string(i), spot.llcurve, keyFile); @@ -4882,6 +4885,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Structcol_" + std::to_string(i), pedited, spot.structcol, spotEdited.structcol); assignFromKeyfile(keyFile, "Locallab", "Blurcolde_" + std::to_string(i), pedited, spot.blurcolde, spotEdited.blurcolde); assignFromKeyfile(keyFile, "Locallab", "Blendmaskcol_" + std::to_string(i), pedited, spot.blendmaskcol, spotEdited.blendmaskcol); + assignFromKeyfile(keyFile, "Locallab", "Radmaskcol_" + std::to_string(i), pedited, spot.radmaskcol, spotEdited.radmaskcol); 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", "LLCurve_" + std::to_string(i), pedited, spot.llcurve, spotEdited.llcurve); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 4b24f4e37..c3bd2bf96 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -972,6 +972,7 @@ struct LocallabParams { int structcol; int blurcolde; int blendmaskcol; + double radmaskcol; Glib::ustring qualitycurveMethod; Glib::ustring gridMethod; std::vector llcurve; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index f592c0e13..c30159f17 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -659,7 +659,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, //EvLocallabshadows LUMINANCECURVE, //EvLocallabs_tonalwidth LUMINANCECURVE, //EvLocallabsh_radius - LUMINANCECURVE //EvLocallabsensihs + LUMINANCECURVE, //EvLocallabsensihs + LUMINANCECURVE //Evlocallabradmaskcol }; diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 4d77b2fbf..e8a035ede 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -83,6 +83,7 @@ Locallab::Locallab(): structcol(Gtk::manage(new Adjuster(M("TP_LOCALLAB_STRUCCOL"), 0, 100, 1, 0))), blurcolde(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BLURDE"), 2, 100, 1, 5))), blendmaskcol(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BLENDMASKCOL"), -100, 100, 1, 0))), + radmaskcol(Gtk::manage(new Adjuster(M("TP_LOCALLAB_RADMASKCOL"), 0.0, 100.0, 0.1, 10.))), // Exposure expcomp(Gtk::manage(new Adjuster(M("TP_EXPOSURE_EXPCOMP"), -2.0, 4.0, 0.05, 0.0))), hlcompr(Gtk::manage(new Adjuster(M("TP_EXPOSURE_COMPRHIGHLIGHTS"), 0, 500, 1, 60))), @@ -248,6 +249,7 @@ Locallab::Locallab(): blurcolde->setAdjusterListener(this); blendmaskcol->setAdjusterListener(this); + radmaskcol->setAdjusterListener(this); qualitycurveMethod->append(M("TP_LOCALLAB_CURVNONE")); qualitycurveMethod->append(M("TP_LOCALLAB_CURVCURR")); @@ -391,6 +393,7 @@ Locallab::Locallab(): maskcolBox->pack_start(*enaColorMask, Gtk::PACK_SHRINK, 0); maskcolBox->pack_start(*maskCurveEditorG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor maskcolBox->pack_start(*blendmaskcol, Gtk::PACK_SHRINK, 0); + maskcolBox->pack_start(*radmaskcol, Gtk::PACK_SHRINK, 0); maskcolFrame->add(*maskcolBox); colorBox->pack_start(*maskcolFrame); @@ -1585,6 +1588,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) 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).blendmaskcol = blendmaskcol->getIntValue(); + pp->locallab.spots.at(pp->locallab.selspot).radmaskcol = radmaskcol->getValue(); // Exposure pp->locallab.spots.at(pp->locallab.selspot).expexpose = expexpose->getEnabled(); pp->locallab.spots.at(pp->locallab.selspot).expcomp = expcomp->getValue(); @@ -1758,6 +1762,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) 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).blurcolde = pe->locallab.spots.at(pp->locallab.selspot).blurcolde || blurcolde->getEditedState(); pe->locallab.spots.at(pp->locallab.selspot).blendmaskcol = pe->locallab.spots.at(pp->locallab.selspot).blendmaskcol || blendmaskcol->getEditedState(); + pe->locallab.spots.at(pp->locallab.selspot).radmaskcol = pe->locallab.spots.at(pp->locallab.selspot).radmaskcol || radmaskcol->getEditedState(); // Exposure pe->locallab.spots.at(pp->locallab.selspot).expexpose = pe->locallab.spots.at(pp->locallab.selspot).expexpose || !expexpose->get_inconsistent(); pe->locallab.spots.at(pp->locallab.selspot).expcomp = pe->locallab.spots.at(pp->locallab.selspot).expcomp || expcomp->getEditedState(); @@ -1916,6 +1921,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) 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).blurcolde = pedited->locallab.spots.at(pp->locallab.selspot).blurcolde || blurcolde->getEditedState(); pedited->locallab.spots.at(pp->locallab.selspot).blendmaskcol = pedited->locallab.spots.at(pp->locallab.selspot).blendmaskcol || blendmaskcol->getEditedState(); + pedited->locallab.spots.at(pp->locallab.selspot).radmaskcol = pedited->locallab.spots.at(pp->locallab.selspot).radmaskcol || radmaskcol->getEditedState(); // Exposure pedited->locallab.spots.at(pp->locallab.selspot).expexpose = pedited->locallab.spots.at(pp->locallab.selspot).expexpose || !expexpose->get_inconsistent(); pedited->locallab.spots.at(pp->locallab.selspot).expcomp = pedited->locallab.spots.at(pp->locallab.selspot).expcomp || expcomp->getEditedState(); @@ -2689,8 +2695,8 @@ void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pe structcol->setDefault((double)defSpot->structcol); blurcolde->setDefault((double)defSpot->blurcolde); blendmaskcol->setDefault((double)defSpot->blendmaskcol); + radmaskcol->setDefault(defSpot->radmaskcol); // Exposure -// expcomp->setDefault((double)defSpot->expcomp); expcomp->setDefault(defSpot->expcomp); hlcompr->setDefault((double)defSpot->hlcompr); hlcomprthresh->setDefault((double)defSpot->hlcomprthresh); @@ -2782,6 +2788,7 @@ void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pe strengthgrid->setDefault((double)defSpot->strengthgrid); blurcolde->setDefaultEditedState(Irrelevant); blendmaskcol->setDefaultEditedState(Irrelevant); + radmaskcol->setDefaultEditedState(Irrelevant); // Exposure expcomp->setDefaultEditedState(Irrelevant); hlcompr->setDefaultEditedState(Irrelevant); @@ -2878,6 +2885,7 @@ void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pe strengthgrid->setDefaultEditedState(defSpotState->strengthgrid ? Edited : UnEdited); blurcolde->setDefaultEditedState(defSpotState->blurcolde ? Edited : UnEdited); blendmaskcol->setDefaultEditedState(defSpotState->blendmaskcol ? Edited : UnEdited); + radmaskcol->setDefaultEditedState(defSpotState->radmaskcol ? Edited : UnEdited); // Exposure expcomp->setDefaultEditedState(defSpotState->expcomp ? Edited : UnEdited); hlcompr->setDefaultEditedState(defSpotState->hlcompr ? Edited : UnEdited); @@ -3049,6 +3057,12 @@ void Locallab::adjusterChanged(Adjuster * a, double newval) } } + if (a == radmaskcol) { + if (listener) { + listener->panelChanged(Evlocallabradmaskcol, radmaskcol->getTextValue()); + } + } + } // Exposure @@ -3545,6 +3559,7 @@ void Locallab::setBatchMode(bool batchMode) strengthgrid->showEditedCB(); blurcolde->showEditedCB(); blendmaskcol->showEditedCB(); + radmaskcol->showEditedCB(); // Exposure expcomp->showEditedCB(); hlcompr->showEditedCB(); @@ -3902,6 +3917,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con HHmaskshape->setCurve(pp->locallab.spots.at(index).HHmaskcurve); blurcolde->setValue(pp->locallab.spots.at(index).blurcolde); blendmaskcol->setValue(pp->locallab.spots.at(index).blendmaskcol); + radmaskcol->setValue(pp->locallab.spots.at(index).radmaskcol); // Exposure expexpose->setEnabled(pp->locallab.spots.at(index).expexpose); @@ -4103,6 +4119,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con HHmaskshape->setUnChanged(!spotState->HHmaskcurve); blurcolde->setEditedState(spotState->blurcolde ? Edited : UnEdited); blendmaskcol->setEditedState(spotState->blendmaskcol ? Edited : UnEdited); + radmaskcol->setEditedState(spotState->radmaskcol ? Edited : UnEdited); // Exposure expexpose->set_inconsistent(!spotState->expexpose); diff --git a/rtgui/locallab.h b/rtgui/locallab.h index fe94bc274..415fa5459 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -98,6 +98,7 @@ private: Adjuster* const structcol; Adjuster* const blurcolde; Adjuster* const blendmaskcol; + Adjuster* const radmaskcol; // Exposure Adjuster* const expcomp; Adjuster* const hlcompr; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index f5a2b18a2..146503ac1 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -956,6 +956,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).structcol = locallab.spots.at(j).structcol && pSpot.structcol == otherSpot.structcol; locallab.spots.at(j).blurcolde = locallab.spots.at(j).blurcolde && pSpot.blurcolde == otherSpot.blurcolde; locallab.spots.at(j).blendmaskcol = locallab.spots.at(j).blendmaskcol && pSpot.blendmaskcol == otherSpot.blendmaskcol; + locallab.spots.at(j).radmaskcol = locallab.spots.at(j).radmaskcol && pSpot.radmaskcol == otherSpot.radmaskcol; 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).llcurve = locallab.spots.at(j).llcurve && pSpot.llcurve == otherSpot.llcurve; @@ -2628,6 +2629,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).blendmaskcol = mods.locallab.spots.at(i).blendmaskcol; } + if (locallab.spots.at(i).radmaskcol) { + toEdit.locallab.spots.at(i).radmaskcol = mods.locallab.spots.at(i).radmaskcol; + } + if (locallab.spots.at(i).qualitycurveMethod) { toEdit.locallab.spots.at(i).qualitycurveMethod = mods.locallab.spots.at(i).qualitycurveMethod; } @@ -4022,6 +4027,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : structcol(v), blurcolde(v), blendmaskcol(v), + radmaskcol(v), qualitycurveMethod(v), gridMethod(v), llcurve(v), @@ -4176,6 +4182,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) structcol = v; blurcolde = v; blendmaskcol = v; + radmaskcol = v; qualitycurveMethod = v; gridMethod = v; llcurve = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 66a8d92c1..1f3ea1252 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -496,6 +496,7 @@ public: bool structcol; bool blurcolde; bool blendmaskcol; + bool radmaskcol; bool qualitycurveMethod; bool gridMethod; bool llcurve;