diff --git a/rtdata/languages/default b/rtdata/languages/default index bebed7ff5..ed8756b21 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1042,6 +1042,7 @@ HISTORY_MSG_801;Local - Color ToneCurve Special HISTORY_MSG_802;Local - Contrast threshold HISTORY_MSG_803;Local - Color Merge HISTORY_MSG_804;Local - Color mask Structure +HISTORY_MSG_805;Local - Blur Noise mask Structure 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/iplocallab.cc b/rtengine/iplocallab.cc index d68ca69b2..95e7f5e00 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -7649,6 +7649,20 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o } if (lp.showmaskblmet == 2 || lp.enablMask || lp.showmaskblmet == 3 || lp.showmaskblmet == 4) { + JaggedArray blendstru(GW, GH); + float strumask = 0.01f * (float) params->locallab.spots.at(sp).strumaskbl; + + if(strumask > 0.f){ + buildBlendMask(bufgb->L, blendstru, GW, GH, strumask, 1.f); + float radblur = 0.02f * lp.radmabl; + float rm = radblur / sk; + + if (rm > 0) { + float **mb = blendstru; + gaussianBlur(mb, mb, GW, GH, rm); + } + } + #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif @@ -7657,6 +7671,11 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o for (int jr = 0; jr < GW; jr++) { float kmaskLexp = 0; float kmaskCH = 0; + float kmasstru = 0.f; + + if(strumask > 0.f){ + kmasstru = bufgb->L[ir][jr]* blendstru[ir][jr]; + } if (locllmasblCurve && llmasblutili) { float ligh = bufgb->L[ir][jr] / 32768.f; @@ -7688,7 +7707,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o kmaskLexp += 32768.f * valHH; } - bufmaskblurbl->L[ir][jr] = CLIPLOC(kmaskLexp); + bufmaskblurbl->L[ir][jr] = CLIPLOC(kmaskLexp + kmasstru); bufmaskblurbl->a[ir][jr] = kmaskCH; bufmaskblurbl->b[ir][jr] = kmaskCH; ble[ir][jr] = bufmaskblurbl->L[ir][jr] / 32768.f; @@ -12572,6 +12591,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o int sco = params->locallab.spots.at(sp).scopemask; int shortcu = lp.mergemet; //params->locallab.spots.at(sp).shortc; int lumask = params->locallab.spots.at(sp).lumask; + float strumask = 0.01f *(float) params->locallab.spots.at(sp).strumaskcol; const int limscope = 80; const float mindE = 2.f + MINSCOPE * sco * lp.thr; @@ -12582,7 +12602,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o float anchorcd = 50.f; maskcalccol(false, pde, GW, GH, 0, 0, sk, cx, cy, bufcolorig.get(), bufmaskblurcol.get(), originalmaskcol.get(), original, inv, lp, - 0.f, + strumask, locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, multiThread, enaMask, showmaske, deltaE, modmask, zero, modif, chrom, rad, lap, gamma, slope, blendm, shado, amountcd, anchorcd, lmasklocalcurve, localmaskutili, loclmasCurvecolwav, lmasutilicolwav, level_bl, level_hl, level_br, level_hr, diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 1b33e1dcb..a18087bab 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -828,6 +828,7 @@ enum ProcEventCode { Evlocallabconthrcol = 801, EvLocallabmerMethod = 802, Evlocallabstrumaskcol = 803, + Evlocallabstrumaskbl = 804, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 85cfdb287..351827128 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2598,6 +2598,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : slomaskbl(0.0), lapmaskbl(0.0), shadmaskbl(0), + strumaskbl(0), Lmaskblcurve{(double)DCT_NURBS, 0.0, 0.0, 1.0, 1.0}, LLmaskblcurvewav{(double)FCT_MinMaxCPoints, 0.0, 0.5, 0.35, 0.35, 1., 0.5, 0.35, 0.35}, csthresholdblur(0, 0, 6, 5, false), @@ -2925,6 +2926,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && slomaskbl == other.slomaskbl && lapmaskbl == other.lapmaskbl && shadmaskbl == other.shadmaskbl + && strumaskbl == other.strumaskbl && Lmaskblcurve == other.Lmaskblcurve && LLmaskblcurvewav == other.LLmaskblcurvewav && csthresholdblur == other.csthresholdblur @@ -4231,6 +4233,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->locallab.spots.at(i).slomaskbl, "Locallab", "Slomaskbl_" + std::to_string(i), spot.slomaskbl, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).lapmaskbl, "Locallab", "Lapmaskbl_" + std::to_string(i), spot.lapmaskbl, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).shadmaskbl, "Locallab", "shadmaskbl_" + std::to_string(i), spot.shadmaskbl, keyFile); + saveToKeyfile(!pedited || pedited->locallab.spots.at(i).strumaskbl, "Locallab", "strumaskbl_" + std::to_string(i), spot.strumaskbl, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).Lmaskblcurve, "Locallab", "LmaskblCurve_" + std::to_string(i), spot.Lmaskblcurve, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).LLmaskblcurvewav, "Locallab", "LLmaskblCurvewav_" + std::to_string(i), spot.LLmaskblcurvewav, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).csthresholdblur, "Locallab", "CSThresholdblur_" + std::to_string(i), spot.csthresholdblur.toVector(), keyFile); @@ -5675,6 +5678,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Slomaskbl_" + std::to_string(i), pedited, spot.slomaskbl, spotEdited.slomaskbl); assignFromKeyfile(keyFile, "Locallab", "Lapmaskbl_" + std::to_string(i), pedited, spot.lapmaskbl, spotEdited.lapmaskbl); assignFromKeyfile(keyFile, "Locallab", "shadmaskbl_" + std::to_string(i), pedited, spot.shadmaskbl, spotEdited.shadmaskbl); + assignFromKeyfile(keyFile, "Locallab", "strumaskbl_" + std::to_string(i), pedited, spot.strumaskbl, spotEdited.strumaskbl); assignFromKeyfile(keyFile, "Locallab", "LmaskblCurve_" + std::to_string(i), pedited, spot.Lmaskblcurve, spotEdited.Lmaskblcurve); assignFromKeyfile(keyFile, "Locallab", "LLmaskblCurvewav_" + std::to_string(i), pedited, spot.LLmaskblcurvewav, spotEdited.LLmaskblcurvewav); if (keyFile.has_key("Locallab", "CSThresholdblur_" + std::to_string(i))) { diff --git a/rtengine/procparams.h b/rtengine/procparams.h index b6a092fec..3827c4b0a 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1142,6 +1142,7 @@ struct LocallabParams { double slomaskbl; double lapmaskbl; int shadmaskbl; + int strumaskbl; std::vector Lmaskblcurve; std::vector LLmaskblcurvewav; Threshold csthresholdblur; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 77554aa49..0b7245c8a 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -831,7 +831,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, // EvLocallabspecial LUMINANCECURVE, //EvLocallabconthrcol LUMINANCECURVE, //EvLocallabmerMethod - LUMINANCECURVE //EvLocallabstrumaskcol + LUMINANCECURVE, //EvLocallabstrumaskcol + LUMINANCECURVE //EvLocallabstrumaskbl }; namespace rtengine diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index a46c44829..73316654c 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -359,6 +359,7 @@ shadmaskbl(Gtk::manage(new Adjuster(M("TP_LOCALLAB_HIGHMASKCOL"), 0, 100, 1, 0)) isogr(Gtk::manage(new Adjuster(M("TP_LOCALLAB_ISOGR"), 20, 6400, 1, 400))), strengr(Gtk::manage(new Adjuster(M("TP_LOCALLAB_STRENGR"), 0, 100, 1, 0))), scalegr(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SCALEGR"), 0, 100, 1, 100))), +strumaskbl(Gtk::manage(new Adjuster(M("TP_LOCALLAB_STRUMASKCOL"), 0, 100, 1, 0))), // Tone Mapping stren(Gtk::manage(new Adjuster(M("TP_LOCALLAB_STREN"), -0.5, 2.0, 0.01, 0.5))), gamma(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GAM"), 0.4, 4.0, 0.11, 1.0))), @@ -2431,11 +2432,15 @@ pe(nullptr) slomaskbl->setAdjusterListener(this); lapmaskbl->setAdjusterListener(this); shadmaskbl->setAdjusterListener(this); + strumaskbl->setAdjusterListener(this); + Gtk::HSeparator* const separatorstrubl = Gtk::manage(new Gtk::HSeparator()); ToolParamBlock* const maskblBox = Gtk::manage(new ToolParamBlock()); maskblBox->pack_start(*showmaskblMethod, Gtk::PACK_SHRINK, 4); maskblBox->pack_start(*enablMask, Gtk::PACK_SHRINK, 0); maskblBox->pack_start(*maskblCurveEditorG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor + maskblBox->pack_start(*strumaskbl, Gtk::PACK_SHRINK, 0); + maskblBox->pack_start(*separatorstrubl, Gtk::PACK_SHRINK, 2); maskblBox->pack_start(*blendmaskbl, Gtk::PACK_SHRINK, 0); maskblBox->pack_start(*radmaskbl, Gtk::PACK_SHRINK, 0); maskblBox->pack_start(*lapmaskbl, Gtk::PACK_SHRINK, 0); @@ -3876,6 +3881,7 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited pp->locallab.spots.at(pp->locallab.selspot).slomaskbl = slomaskbl->getValue(); pp->locallab.spots.at(pp->locallab.selspot).lapmaskbl = lapmaskbl->getValue(); pp->locallab.spots.at(pp->locallab.selspot).shadmaskbl = shadmaskbl->getIntValue(); + pp->locallab.spots.at(pp->locallab.selspot).strumaskbl = strumaskbl->getIntValue(); pp->locallab.spots.at(pp->locallab.selspot).fftwbl = fftwbl->get_active(); pp->locallab.spots.at(pp->locallab.selspot).Lmaskblcurve = Lmaskblshape->getCurve(); pp->locallab.spots.at(pp->locallab.selspot).LLmaskblcurvewav = LLmaskblshapewav->getCurve(); @@ -4216,6 +4222,7 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited pe->locallab.spots.at(pp->locallab.selspot).slomaskbl = pe->locallab.spots.at(pp->locallab.selspot).slomaskbl || slomaskbl->getEditedState(); pe->locallab.spots.at(pp->locallab.selspot).lapmaskbl = pe->locallab.spots.at(pp->locallab.selspot).lapmaskbl || lapmaskbl->getEditedState(); pe->locallab.spots.at(pp->locallab.selspot).shadmaskbl = pe->locallab.spots.at(pp->locallab.selspot).shadmaskbl || shadmaskbl->getEditedState(); + pe->locallab.spots.at(pp->locallab.selspot).strumaskbl = pe->locallab.spots.at(pp->locallab.selspot).strumaskbl || strumaskbl->getEditedState(); pe->locallab.spots.at(pp->locallab.selspot).fftwbl = pe->locallab.spots.at(pp->locallab.selspot).fftwbl || !fftwbl->get_inconsistent(); pe->locallab.spots.at(pp->locallab.selspot).Lmaskblcurve = pe->locallab.spots.at(pp->locallab.selspot).Lmaskblcurve || !Lmaskblshape->isUnChanged(); pe->locallab.spots.at(pp->locallab.selspot).LLmaskblcurvewav = pe->locallab.spots.at(pp->locallab.selspot).LLmaskblcurvewav || !LLmaskblshapewav->isUnChanged(); @@ -4543,6 +4550,7 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited pedited->locallab.spots.at(pp->locallab.selspot).slomaskbl = pedited->locallab.spots.at(pp->locallab.selspot).slomaskbl || slomaskbl->getEditedState(); pedited->locallab.spots.at(pp->locallab.selspot).lapmaskbl = pedited->locallab.spots.at(pp->locallab.selspot).lapmaskbl || lapmaskbl->getEditedState(); pedited->locallab.spots.at(pp->locallab.selspot).shadmaskbl = pedited->locallab.spots.at(pp->locallab.selspot).shadmaskbl || shadmaskbl->getEditedState(); + pedited->locallab.spots.at(pp->locallab.selspot).strumaskbl = pedited->locallab.spots.at(pp->locallab.selspot).strumaskbl || strumaskbl->getEditedState(); pedited->locallab.spots.at(pp->locallab.selspot).fftwbl = pedited->locallab.spots.at(pp->locallab.selspot).fftwbl || !fftwbl->get_inconsistent(); pedited->locallab.spots.at(pp->locallab.selspot).Lmaskblcurve = pedited->locallab.spots.at(pp->locallab.selspot).Lmaskblcurve || !Lmaskblshape->isUnChanged(); pedited->locallab.spots.at(pp->locallab.selspot).LLmaskblcurvewav = pedited->locallab.spots.at(pp->locallab.selspot).LLmaskblcurvewav || !LLmaskblshapewav->isUnChanged(); @@ -6620,6 +6628,7 @@ void Locallab::setDefaults(const rtengine::procparams::ProcParams * defParams, c slomaskbl->setDefault(defSpot->slomaskbl); lapmaskbl->setDefault(defSpot->lapmaskbl); shadmaskbl->setDefault(defSpot->shadmaskbl); + strumaskbl->setDefault(defSpot->strumaskbl); csThresholdblur->setDefault(defSpot->csthresholdblur); // Tone Mapping stren->setDefault(defSpot->stren); @@ -6815,6 +6824,7 @@ void Locallab::setDefaults(const rtengine::procparams::ProcParams * defParams, c slomaskbl->setDefaultEditedState(Irrelevant); lapmaskbl->setDefaultEditedState(Irrelevant); shadmaskbl->setDefaultEditedState(Irrelevant); + strumaskbl->setDefaultEditedState(Irrelevant); csThresholdblur->setDefaultEditedState(Irrelevant); // Tone Mapping stren->setDefaultEditedState(Irrelevant); @@ -7014,6 +7024,7 @@ void Locallab::setDefaults(const rtengine::procparams::ProcParams * defParams, c slomaskbl->setDefaultEditedState(defSpotState->slomaskbl ? Edited : UnEdited); lapmaskbl->setDefaultEditedState(defSpotState->lapmaskbl ? Edited : UnEdited); shadmaskbl->setDefaultEditedState(defSpotState->shadmaskbl ? Edited : UnEdited); + strumaskbl->setDefaultEditedState(defSpotState->strumaskbl ? Edited : UnEdited); csThresholdblur->setDefaultEditedState(defSpotState->csthresholdblur ? Edited : UnEdited); // Tone Mapping stren->setDefaultEditedState(defSpotState->stren ? Edited : UnEdited); @@ -7731,6 +7742,12 @@ void Locallab::adjusterChanged(Adjuster * a, double newval) } } + if (a == strumaskbl) { + if (listener) { + listener->panelChanged(Evlocallabstrumaskbl, strumaskbl->getTextValue()); + } + } + } // Tone Mapping @@ -8393,6 +8410,7 @@ void Locallab::setBatchMode(bool batchMode) slomaskbl->showEditedCB(); lapmaskbl->showEditedCB(); shadmaskbl->showEditedCB(); + strumaskbl->showEditedCB(); csThresholdblur->showEditedCB(); // Tone Mapping stren->showEditedCB(); @@ -9106,6 +9124,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con slomaskbl->setValue(pp->locallab.spots.at(index).slomaskbl); lapmaskbl->setValue(pp->locallab.spots.at(index).lapmaskbl); shadmaskbl->setValue(pp->locallab.spots.at(index).shadmaskbl); + strumaskbl->setValue(pp->locallab.spots.at(index).strumaskbl); fftwbl->set_active(pp->locallab.spots.at(index).fftwbl); Lmaskblshape->setCurve(pp->locallab.spots.at(index).Lmaskblcurve); LLmaskblshapewav->setCurve(pp->locallab.spots.at(index).LLmaskblcurvewav); @@ -9502,6 +9521,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con slomaskbl->setEditedState(spotState->slomaskbl ? Edited : UnEdited); lapmaskbl->setEditedState(spotState->lapmaskbl ? Edited : UnEdited); shadmaskbl->setEditedState(spotState->shadmaskbl ? Edited : UnEdited); + strumaskbl->setEditedState(spotState->strumaskbl ? Edited : UnEdited); fftwbl->set_inconsistent(multiImage && !spotState->fftwbl); Lmaskblshape->setUnChanged(!spotState->Lmaskblcurve); LLmaskblshapewav->setUnChanged(!spotState->LLmaskblcurvewav); diff --git a/rtgui/locallab.h b/rtgui/locallab.h index 06481c6f6..4203ce1c9 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -241,6 +241,7 @@ private: Adjuster* const isogr; Adjuster* const strengr; Adjuster* const scalegr; + Adjuster* const strumaskbl; // Tone Mapping Adjuster* const stren; Adjuster* const gamma; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 9e0ef2713..1cf336fa2 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1134,6 +1134,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).slomaskbl = locallab.spots.at(j).slomaskbl && pSpot.slomaskbl == otherSpot.slomaskbl; locallab.spots.at(j).lapmaskbl = locallab.spots.at(j).lapmaskbl && pSpot.lapmaskbl == otherSpot.lapmaskbl; locallab.spots.at(j).shadmaskbl = locallab.spots.at(j).shadmaskbl && pSpot.shadmaskbl == otherSpot.shadmaskbl; + locallab.spots.at(j).strumaskbl = locallab.spots.at(j).strumaskbl && pSpot.strumaskbl == otherSpot.strumaskbl; locallab.spots.at(j).fftwbl = locallab.spots.at(j).fftwbl && pSpot.fftwbl == otherSpot.fftwbl; locallab.spots.at(j).Lmaskblcurve = locallab.spots.at(j).Lmaskblcurve && pSpot.Lmaskblcurve == otherSpot.Lmaskblcurve; locallab.spots.at(j).LLmaskblcurvewav = locallab.spots.at(j).LLmaskblcurvewav && pSpot.LLmaskblcurvewav == otherSpot.LLmaskblcurvewav; @@ -3446,6 +3447,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).shadmaskbl = mods.locallab.spots.at(i).shadmaskbl; } + if (locallab.spots.at(i).strumaskbl) { + toEdit.locallab.spots.at(i).strumaskbl = mods.locallab.spots.at(i).strumaskbl; + } + if (locallab.spots.at(i).Lmaskblcurve) { toEdit.locallab.spots.at(i).Lmaskblcurve = mods.locallab.spots.at(i).Lmaskblcurve; } @@ -5086,6 +5091,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : slomaskbl(v), lapmaskbl(v), shadmaskbl(v), + strumaskbl(v), Lmaskblcurve(v), LLmaskblcurvewav(v), csthresholdblur(v), @@ -5403,6 +5409,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) slomaskbl = v; lapmaskbl = v; shadmaskbl = v; + strumaskbl = v; Lmaskblcurve = v; LLmaskblcurvewav = v; csthresholdblur = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 6df4199a0..427e8f130 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -564,6 +564,7 @@ public: bool slomaskbl; bool lapmaskbl; bool shadmaskbl; + bool strumaskbl; bool Lmaskblcurve; bool LLmaskblcurvewav; bool csthresholdblur;