diff --git a/rtdata/languages/default b/rtdata/languages/default index c76d5da54..96582515d 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1019,6 +1019,7 @@ HISTORY_MSG_778;Local - Blur Mask Wavelet level HISTORY_MSG_779;Local - Color Mask local contrast curve HISTORY_MSG_780;Local - Color Mask Wavelet level HISTORY_MSG_781;Local - Local contrast Wavelet level +HISTORY_MSG_782;Local - Blur Denoise Mask Wavelet levels HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -2123,6 +2124,7 @@ TP_LOCALLAB_GAMMASKCOL;Gamma mask TP_LOCALLAB_SLOMASKCOL;Slope mask TP_LOCALLAB_LAPMASKCOL;Laplacian threshold mask TP_LOCALLAB_WAMASKCOL;Mask Wavelet level +TP_LOCALLAB_CSTHRESHOLDBLUR;Mask Wavelet level TP_LOCALLAB_LAPLACC;Mask Laplacian solve PDE TP_LOCALLAB_CHRRT;Chroma TP_LOCALLAB_CIRCRADIUS;Spot size diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index d937bbed4..37da58669 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -7310,15 +7310,20 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o } } - if (wavcurvemask) { + if (wavcurvemask && (lp.enablMask || lp.showmaskblmet == 3)) { #ifdef _OPENMP const int numThreads = omp_get_max_threads(); #else const int numThreads = 1; #endif + int level_bl = params->locallab.spots.at(sp).csthresholdblur.getBottomLeft(); + int level_hl = params->locallab.spots.at(sp).csthresholdblur.getTopLeft(); + int level_br = params->locallab.spots.at(sp).csthresholdblur.getBottomRight(); + int level_hr = params->locallab.spots.at(sp).csthresholdblur.getTopRight(); - wavcontrast(bufmaskblurbl->L, contrast, GW, GH, wavelet_level, sk, numThreads, loclmasCurveblwav, lmasutiliblwav, maxlvl); + + wavcontrast4(bufmaskblurbl->L, contrast, GW, GH, level_bl, level_hl, level_br, level_hr, sk, numThreads, loclmasCurveblwav, lmasutiliblwav, maxlvl); } float lap = params->locallab.spots.at(sp).lapmaskbl; diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 94e2f0f14..40f3f7c6e 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -808,6 +808,7 @@ enum ProcEventCode { EvlocallabLLmaskcolshapewav = 778, Evlocallabwavmaskcol = 779, EvlocallabcsThreshold = 780, + EvlocallabcsThresholdblur = 781, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 538479862..a9b07bbc8 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2572,6 +2572,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : wavmaskbl(5), 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(1, 1, 5, 5, false), // Tone Mapping exptonemap(false), stren(0.5), @@ -2866,7 +2867,8 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && wavmaskbl == other.wavmaskbl && Lmaskblcurve == other.Lmaskblcurve && LLmaskblcurvewav == other.LLmaskblcurvewav - // Tone Mapping + && csthresholdblur == other.csthresholdblur + // Tone Mapping && exptonemap == other.exptonemap && stren == other.stren && gamma == other.gamma @@ -4146,6 +4148,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->locallab.spots.at(i).wavmaskbl, "Locallab", "Wavmaskbllevel_" + std::to_string(i), spot.wavmaskbl, 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); // Tone Mapping saveToKeyfile(!pedited || pedited->locallab.spots.at(i).exptonemap, "Locallab", "Exptonemap_" + std::to_string(i), spot.exptonemap, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).stren, "Locallab", "Stren_" + std::to_string(i), spot.stren, keyFile); @@ -5553,6 +5556,18 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Wavmaskbllevel_" + std::to_string(i), pedited, spot.wavmaskbl, spotEdited.wavmaskbl); 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))) { + + const std::vector thresh = keyFile.get_integer_list("Locallab", "CSThresholdblur_" + std::to_string(i)); + + if (thresh.size() >= 4) { + spot.csthresholdblur.setValues(thresh[0], thresh[1], min(thresh[2], 10), min(thresh[3], 10)); + } + + if (pedited) { + spotEdited.csthresholdblur = true; + } + } // Tone Mapping assignFromKeyfile(keyFile, "Locallab", "Exptonemap_" + std::to_string(i), pedited, spot.exptonemap, spotEdited.exptonemap); assignFromKeyfile(keyFile, "Locallab", "Stren_" + std::to_string(i), pedited, spot.stren, spotEdited.stren); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index ed6a196e8..1d4fa4609 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1121,6 +1121,7 @@ struct LocallabParams { int wavmaskbl; std::vector Lmaskblcurve; std::vector LLmaskblcurvewav; + Threshold csthresholdblur; // Tone Mapping bool exptonemap; double stren; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index c8570ed0a..f8a233a1c 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -807,7 +807,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, //Evlocallabwavmaskbl LUMINANCECURVE, //EvlocallabLLmaskcolshapewav LUMINANCECURVE, //Evlocallabwavmaskcol - LUMINANCECURVE //EvlocallabcsThreshold + LUMINANCECURVE, //EvlocallabcsThreshold + LUMINANCECURVE //EvlocallabcsThresholdblur }; namespace rtengine diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 41f6fa9f8..64f42bedc 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -417,6 +417,7 @@ Locallab::Locallab(): blMethod(Gtk::manage(new MyComboBoxText())), medMethod(Gtk::manage(new MyComboBoxText())), showmaskblMethod(Gtk::manage(new MyComboBoxText())), + csThresholdblur(Gtk::manage(new ThresholdAdjuster(M("TP_LOCALLAB_CSTHRESHOLDBLUR"), 1, 9, 1, 1, 5, 5, 0, false))), //TM showmasktmMethod(Gtk::manage(new MyComboBoxText())), // Retinex @@ -2162,6 +2163,7 @@ Locallab::Locallab(): Lmaskblshape->setBottomBarBgGradient(mLmaskblshape); Lmaskblshape->setLeftBarBgGradient(mLmaskblshape); mask2blCurveEditorG->curveListComplete(); + csThresholdblur->setAdjusterListener(this); mask2blCurveEditorGwav->setCurveListener(this); LLmaskblshapewav = static_cast(mask2blCurveEditorGwav->addCurve(CT_Flat, "L(L)", nullptr, false, false)); @@ -2247,7 +2249,10 @@ Locallab::Locallab(): maskblBox->pack_start(*slomaskbl, Gtk::PACK_SHRINK, 0); maskblBox->pack_start(*mask2blCurveEditorG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor maskblBox->pack_start(*mask2blCurveEditorGwav, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor - maskblBox->pack_start(*wavmaskbl, Gtk::PACK_SHRINK, 0); +// maskblBox->pack_start(*wavmaskbl, Gtk::PACK_SHRINK, 0); + maskblBox->pack_start(*csThresholdblur, Gtk::PACK_SHRINK, 0); + + expmaskbl->add(*maskblBox, false); panel->pack_start(*expmaskbl); @@ -3461,6 +3466,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) 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(); + pp->locallab.spots.at(pp->locallab.selspot).csthresholdblur = csThresholdblur->getValue(); // Tone Mapping pp->locallab.spots.at(pp->locallab.selspot).exptonemap = exptonemap->getEnabled(); @@ -3772,6 +3778,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) 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(); + pe->locallab.spots.at(pp->locallab.selspot).csthresholdblur = pe->locallab.spots.at(pp->locallab.selspot).csthresholdblur || csThresholdblur->getEditedState(); // Tone Mapping pe->locallab.spots.at(pp->locallab.selspot).exptonemap = pe->locallab.spots.at(pp->locallab.selspot).activlum || !exptonemap->get_inconsistent(); pe->locallab.spots.at(pp->locallab.selspot).stren = pe->locallab.spots.at(pp->locallab.selspot).stren || stren->getEditedState(); @@ -4070,6 +4077,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) 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(); + pedited->locallab.spots.at(pp->locallab.selspot).csthresholdblur = pedited->locallab.spots.at(pp->locallab.selspot).csthresholdblur || csThresholdblur->getEditedState(); // Tone Mapping pedited->locallab.spots.at(pp->locallab.selspot).exptonemap = pedited->locallab.spots.at(pp->locallab.selspot).exptonemap || !exptonemap->get_inconsistent(); pedited->locallab.spots.at(pp->locallab.selspot).stren = pedited->locallab.spots.at(pp->locallab.selspot).stren || stren->getEditedState(); @@ -6005,6 +6013,7 @@ void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pe slomaskbl->setDefault(defSpot->slomaskbl); lapmaskbl->setDefault(defSpot->lapmaskbl); wavmaskbl->setDefault(defSpot->wavmaskbl); + csThresholdblur->setDefault(defSpot->csthresholdblur); // Tone Mapping stren->setDefault(defSpot->stren); gamma->setDefault(defSpot->gamma); @@ -6184,6 +6193,7 @@ void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pe slomaskbl->setDefaultEditedState(Irrelevant); lapmaskbl->setDefaultEditedState(Irrelevant); wavmaskbl->setDefaultEditedState(Irrelevant); + csThresholdblur->setDefaultEditedState(Irrelevant); // Tone Mapping stren->setDefaultEditedState(Irrelevant); gamma->setDefaultEditedState(Irrelevant); @@ -6367,6 +6377,7 @@ void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pe slomaskbl->setDefaultEditedState(defSpotState->slomaskbl ? Edited : UnEdited); lapmaskbl->setDefaultEditedState(defSpotState->lapmaskbl ? Edited : UnEdited); wavmaskbl->setDefaultEditedState(defSpotState->wavmaskbl ? Edited : UnEdited); + csThresholdblur->setDefaultEditedState(defSpotState->csthresholdblur ? Edited : UnEdited); // Tone Mapping stren->setDefaultEditedState(defSpotState->stren ? Edited : UnEdited); gamma->setDefaultEditedState(defSpotState->gamma ? Edited : UnEdited); @@ -6490,6 +6501,12 @@ void Locallab::adjusterChanged2(ThresholdAdjuster* a, int newBottomL, int newTop } } + if (getEnabled() && expblur->getEnabled()) { + if (listener) { + listener->panelChanged(EvlocallabcsThresholdblur, csThresholdblur->getHistoryString()); + } + } + } void Locallab::adjusterChanged(ThresholdAdjuster* a, int newBottom, int newTop) @@ -7656,6 +7673,7 @@ void Locallab::setBatchMode(bool batchMode) slomaskbl->showEditedCB(); lapmaskbl->showEditedCB(); wavmaskbl->showEditedCB(); + csThresholdblur->showEditedCB(); // Tone Mapping stren->showEditedCB(); gamma->showEditedCB(); @@ -8287,6 +8305,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con 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); + csThresholdblur->setValue(pp->locallab.spots.at(index).csthresholdblur); // Tone Mapping exptonemap->setEnabled(pp->locallab.spots.at(index).exptonemap); @@ -8643,6 +8662,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con fftwbl->set_inconsistent(multiImage && !spotState->fftwbl); Lmaskblshape->setUnChanged(!spotState->Lmaskblcurve); LLmaskblshapewav->setUnChanged(!spotState->LLmaskblcurvewav); + csThresholdblur->setEditedState(spotState->csthresholdblur ? Edited : UnEdited); // Tone Mapping exptonemap->set_inconsistent(!spotState->exptonemap); diff --git a/rtgui/locallab.h b/rtgui/locallab.h index cf7c009af..e6e13904c 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -418,6 +418,7 @@ private: sigc::connection medMethodConn; MyComboBoxText* const showmaskblMethod; sigc::connection showmaskblMethodConn; + ThresholdAdjuster* const csThresholdblur; //TM MyComboBoxText* const showmasktmMethod; sigc::connection showmasktmMethodConn; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index f5d9ebd35..862004674 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1112,6 +1112,7 @@ void ParamsEdited::initFrom(const std::vector& 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; + locallab.spots.at(j).csthresholdblur = locallab.spots.at(j).csthresholdblur && pSpot.csthresholdblur == otherSpot.csthresholdblur; // Tone Mapping locallab.spots.at(j).exptonemap = locallab.spots.at(j).exptonemap && pSpot.exptonemap == otherSpot.exptonemap; locallab.spots.at(j).stren = locallab.spots.at(j).stren && pSpot.stren == otherSpot.stren; @@ -3333,6 +3334,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).LLmaskblcurvewav = mods.locallab.spots.at(i).LLmaskblcurvewav; } + if (locallab.spots.at(i).csthresholdblur) { + toEdit.locallab.spots.at(i).csthresholdblur = mods.locallab.spots.at(i).csthresholdblur; + } + // Tone Mapping if (locallab.spots.at(i).exptonemap) { toEdit.locallab.spots.at(i).exptonemap = mods.locallab.spots.at(i).exptonemap; @@ -4940,6 +4945,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : wavmaskbl(v), Lmaskblcurve(v), LLmaskblcurvewav(v), + csthresholdblur(v), // Tone Mapping exptonemap(v), stren(v), @@ -5231,6 +5237,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) wavmaskbl = v; Lmaskblcurve = v; LLmaskblcurvewav = v; + csthresholdblur = v; // Tone Mapping exptonemap = v; stren = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 4229ea49c..5cc35ff67 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -531,6 +531,7 @@ public: bool wavmaskbl; bool Lmaskblcurve; bool LLmaskblcurvewav; + bool csthresholdblur; // Tone Mapping bool exptonemap; bool stren;