diff --git a/rtdata/languages/default b/rtdata/languages/default index 185191bcd..403fccdf0 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1408,6 +1408,7 @@ HISTORY_MSG_DEHAZE_ENABLED;Haze Removal HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength +HISTORY_MSG_DIRPYRDENOISE_GAIN;NR - Compensate for lightness HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold HISTORY_MSG_EDGEFFECT;Edge Attenuation response @@ -2447,6 +2448,8 @@ TP_DIRPYRDENOISE_LUMINANCE_CURVE;Luminance curve TP_DIRPYRDENOISE_LUMINANCE_DETAIL;Detail recovery TP_DIRPYRDENOISE_LUMINANCE_FRAME;Luminance TP_DIRPYRDENOISE_LUMINANCE_SMOOTHING;Luminance +TP_DIRPYRDENOISE_MAIN_AUTO_GAIN;Compensate for lightness +TP_DIRPYRDENOISE_MAIN_AUTO_GAIN_TOOLTIP;Alter the noise reduction strength based on the image lightness. Strength is reduced for dark images and increased for bright images. TP_DIRPYRDENOISE_MAIN_COLORSPACE;Color space TP_DIRPYRDENOISE_MAIN_COLORSPACE_LAB;L*a*b* TP_DIRPYRDENOISE_MAIN_COLORSPACE_RGB;RGB diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index d187bee93..4d8750929 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -665,7 +665,7 @@ BENCHFUN Color::gammanf2lut(igamcurve, igam, 32768.f, 65535.f); } - const float gain = std::pow(2.0, expcomp); + const float gain = dnparams.autoGain ? static_cast(std::pow(2.0, expcomp)) : 1.f; const double params_Ldetail = std::min(dnparams.Ldetail, 99.9); // max out to avoid div by zero when using noisevar_Ldetail as divisor const float noisevar_Ldetail = SQR((SQR(100. - params_Ldetail) + 50.0 * (100.0 - params_Ldetail)) * TS * 0.5); @@ -3290,7 +3290,7 @@ void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat * provicalc, bool denoiseMethodRgb = (dnparams.dmethod == "RGB"); - const float gain = pow(2.0f, float(expcomp)); + const float gain = dnparams.autoGain ? pow(2.0f, float(expcomp)) : 1.f; int tilesize = 0; int overlap = 0; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index f029b88b0..e9101a5aa 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1712,6 +1712,7 @@ DirPyrDenoiseParams::DirPyrDenoiseParams() : chroma(15), redchro(0), bluechro(0), + autoGain(true), gamma(1.7), dmethod("Lab"), Lmethod("SLI"), @@ -1739,6 +1740,7 @@ bool DirPyrDenoiseParams::operator ==(const DirPyrDenoiseParams& other) const && chroma == other.chroma && redchro == other.redchro && bluechro == other.bluechro + && autoGain == other.autoGain && gamma == other.gamma && dmethod == other.dmethod && Lmethod == other.Lmethod @@ -6422,6 +6424,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->dirpyrDenoise.methodmed, "Directional Pyramid Denoising", "MethodMed", dirpyrDenoise.methodmed, keyFile); saveToKeyfile(!pedited || pedited->dirpyrDenoise.redchro, "Directional Pyramid Denoising", "Redchro", dirpyrDenoise.redchro, keyFile); saveToKeyfile(!pedited || pedited->dirpyrDenoise.bluechro, "Directional Pyramid Denoising", "Bluechro", dirpyrDenoise.bluechro, keyFile); + saveToKeyfile(!pedited || pedited->dirpyrDenoise.gain, "Directional Pyramid Denoising", "AutoGain", dirpyrDenoise.autoGain, keyFile); saveToKeyfile(!pedited || pedited->dirpyrDenoise.gamma, "Directional Pyramid Denoising", "Gamma", dirpyrDenoise.gamma, keyFile); saveToKeyfile(!pedited || pedited->dirpyrDenoise.passes, "Directional Pyramid Denoising", "Passes", dirpyrDenoise.passes, keyFile); saveToKeyfile(!pedited || pedited->dirpyrDenoise.lcurve, "Directional Pyramid Denoising", "LCurve", dirpyrDenoise.lcurve, keyFile); @@ -8458,6 +8461,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Redchro", dirpyrDenoise.redchro, pedited->dirpyrDenoise.redchro); assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Bluechro", dirpyrDenoise.bluechro, pedited->dirpyrDenoise.bluechro); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "AutoGain", dirpyrDenoise.autoGain, pedited->dirpyrDenoise.gain); assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Gamma", dirpyrDenoise.gamma, pedited->dirpyrDenoise.gamma); assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Passes", dirpyrDenoise.passes, pedited->dirpyrDenoise.passes); } diff --git a/rtengine/procparams.h b/rtengine/procparams.h index f2c63ea2d..b748a7027 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -772,6 +772,7 @@ struct DirPyrDenoiseParams { double chroma; double redchro; double bluechro; + bool autoGain; double gamma; Glib::ustring dmethod; Glib::ustring Lmethod; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index eabeb2fc9..738ba4e71 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -1722,7 +1722,7 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens } } - if (prepareDenoise && dirpyrdenoiseExpComp == RT_INFINITY) { + if (prepareDenoise) { LUTu aehist; int aehistcompr; double clip = 0; diff --git a/rtgui/dirpyrdenoise.cc b/rtgui/dirpyrdenoise.cc index f2b780eba..4e487b184 100644 --- a/rtgui/dirpyrdenoise.cc +++ b/rtgui/dirpyrdenoise.cc @@ -26,9 +26,11 @@ #include "editbuffer.h" #include "guiutils.h" #include "options.h" +#include "eventmapper.h" #include "../rtengine/color.h" #include "../rtengine/procparams.h" +#include "../rtengine/refreshmap.h" using namespace rtengine; using namespace rtengine::procparams; @@ -37,6 +39,9 @@ const Glib::ustring DirPyrDenoise::TOOL_NAME = "dirpyrdenoise"; DirPyrDenoise::DirPyrDenoise () : FoldableToolPanel(this, TOOL_NAME, M("TP_DIRPYRDENOISE_LABEL"), true, true), lastmedian(false) { + const auto procEventMapper = ProcEventMapper::getInstance(); + EvDPDNGain = procEventMapper->newEvent(ALLNORAW, "HISTORY_MSG_DIRPYRDENOISE_GAIN"); + std::vector milestones; CurveListener::setMulti(true); nextnresid = 0.; @@ -229,6 +234,11 @@ DirPyrDenoise::DirPyrDenoise () : FoldableToolPanel(this, TOOL_NAME, M("TP_DIRPY pack_start( *hb11, Gtk::PACK_SHRINK, 1); smethodconn = smethod->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrDenoise::smethodChanged) ); + autoGain = Gtk::manage(new CheckBox(M("TP_DIRPYRDENOISE_MAIN_AUTO_GAIN"), multiImage)); + autoGain->set_tooltip_text(M("TP_DIRPYRDENOISE_MAIN_AUTO_GAIN_TOOLTIP")); + autoGain->setCheckBoxListener(this); + pack_start(*autoGain, Gtk::PACK_SHRINK, 0); + gamma = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_MAIN_GAMMA"), 1.0, 3.0, 0.01, 1.7)); gamma->set_tooltip_text (M("TP_DIRPYRDENOISE_MAIN_GAMMA_TOOLTIP")); gamma->setAdjusterListener (this); @@ -570,6 +580,7 @@ void DirPyrDenoise::read (const ProcParams* pp, const ParamsEdited* pedited) redchro->setEditedState (pedited->dirpyrDenoise.redchro ? Edited : UnEdited); bluechro->setEditedState (pedited->dirpyrDenoise.bluechro ? Edited : UnEdited); + autoGain->set_inconsistent(!pedited->dirpyrDenoise.gain); gamma->setEditedState (pedited->dirpyrDenoise.gamma ? Edited : UnEdited); passes->setEditedState (pedited->dirpyrDenoise.passes ? Edited : UnEdited); set_inconsistent (multiImage && !pedited->dirpyrDenoise.enabled); @@ -593,6 +604,7 @@ void DirPyrDenoise::read (const ProcParams* pp, const ParamsEdited* pedited) redchro->setValue (pp->dirpyrDenoise.redchro); bluechro->setValue (pp->dirpyrDenoise.bluechro); + autoGain->setValue(pp->dirpyrDenoise.autoGain); gamma->setValue (pp->dirpyrDenoise.gamma); passes->setValue (pp->dirpyrDenoise.passes); lshape->setCurve (pp->dirpyrDenoise.lcurve); @@ -631,6 +643,7 @@ void DirPyrDenoise::write (ProcParams* pp, ParamsEdited* pedited) pp->dirpyrDenoise.chroma = chroma->getValue (); pp->dirpyrDenoise.redchro = redchro->getValue (); pp->dirpyrDenoise.bluechro = bluechro->getValue (); + pp->dirpyrDenoise.autoGain = autoGain->get_active(); pp->dirpyrDenoise.gamma = gamma->getValue (); pp->dirpyrDenoise.passes = passes->getValue (); pp->dirpyrDenoise.enabled = getEnabled(); @@ -653,6 +666,7 @@ void DirPyrDenoise::write (ProcParams* pp, ParamsEdited* pedited) pedited->dirpyrDenoise.chroma = chroma->getEditedState (); pedited->dirpyrDenoise.redchro = redchro->getEditedState (); pedited->dirpyrDenoise.bluechro = bluechro->getEditedState (); + pedited->dirpyrDenoise.gain = !autoGain->get_inconsistent(); pedited->dirpyrDenoise.gamma = gamma->getEditedState (); pedited->dirpyrDenoise.passes = passes->getEditedState (); pedited->dirpyrDenoise.enabled = !get_inconsistent(); @@ -992,6 +1006,13 @@ void DirPyrDenoise::adjusterChanged(Adjuster* a, double newval) } } +void DirPyrDenoise::checkBoxToggled(CheckBox* c, CheckValue newval) +{ + if (c == autoGain) { + listener->panelChanged(EvDPDNGain, c->getValueAsStr()); + } +} + void DirPyrDenoise::enabledChanged () { diff --git a/rtgui/dirpyrdenoise.h b/rtgui/dirpyrdenoise.h index dadd96988..6e4e250d4 100644 --- a/rtgui/dirpyrdenoise.h +++ b/rtgui/dirpyrdenoise.h @@ -21,6 +21,7 @@ #include #include "adjuster.h" +#include "checkbox.h" #include "colorprovider.h" #include "curvelistener.h" #include "guiutils.h" @@ -34,6 +35,7 @@ class EditDataProvider; class DirPyrDenoise final : public ToolParamBlock, public AdjusterListener, + public CheckBoxListener, public FoldableToolPanel, public rtengine::AutoChromaListener, public CurveListener, @@ -54,6 +56,7 @@ public: void autoOpenCurve () override; void adjusterChanged (Adjuster* a, double newval) override; + void checkBoxToggled(CheckBox* c, CheckValue newval) override; void enabledChanged () override; void medianChanged (); void chromaChanged (double autchroma, double autred, double autblue) override; @@ -83,6 +86,7 @@ public: Glib::ustring getSettingString (); private: + rtengine::ProcEvent EvDPDNGain; CurveEditorGroup* NoiscurveEditorG; CurveEditorGroup* CCcurveEditorG; Adjuster* luma; @@ -90,6 +94,7 @@ private: Adjuster* chroma; Adjuster* redchro; Adjuster* bluechro; + CheckBox* autoGain; Adjuster* gamma; Adjuster* passes; FlatCurveEditor* lshape; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index fe88b70c7..ea7c4adc2 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -297,6 +297,7 @@ void ParamsEdited::set(bool v) dirpyrDenoise.chroma = v; dirpyrDenoise.redchro = v; dirpyrDenoise.bluechro = v; + dirpyrDenoise.gain = v; dirpyrDenoise.gamma = v; dirpyrDenoise.passes = v; dirpyrDenoise.dmethod = v; @@ -1013,6 +1014,7 @@ void ParamsEdited::initFrom(const std::vector& dirpyrDenoise.chroma = dirpyrDenoise.chroma && p.dirpyrDenoise.chroma == other.dirpyrDenoise.chroma; dirpyrDenoise.redchro = dirpyrDenoise.redchro && p.dirpyrDenoise.redchro == other.dirpyrDenoise.redchro; dirpyrDenoise.bluechro = dirpyrDenoise.bluechro && p.dirpyrDenoise.bluechro == other.dirpyrDenoise.bluechro; + dirpyrDenoise.gain = dirpyrDenoise.gain && p.dirpyrDenoise.autoGain == other.dirpyrDenoise.autoGain; dirpyrDenoise.gamma = dirpyrDenoise.gamma && p.dirpyrDenoise.gamma == other.dirpyrDenoise.gamma; dirpyrDenoise.passes = dirpyrDenoise.passes && p.dirpyrDenoise.passes == other.dirpyrDenoise.passes; dirpyrDenoise.dmethod = dirpyrDenoise.dmethod && p.dirpyrDenoise.dmethod == other.dirpyrDenoise.dmethod; @@ -3146,6 +3148,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.dirpyrDenoise.bluechro = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_CHROMABLUE] ? toEdit.dirpyrDenoise.bluechro + mods.dirpyrDenoise.bluechro : mods.dirpyrDenoise.bluechro; } + if (dirpyrDenoise.gain) { + toEdit.dirpyrDenoise.autoGain = mods.dirpyrDenoise.autoGain; + } + if (dirpyrDenoise.gamma) { toEdit.dirpyrDenoise.gamma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_GAMMA] ? toEdit.dirpyrDenoise.gamma + mods.dirpyrDenoise.gamma : mods.dirpyrDenoise.gamma; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 2a776f87b..9f9e4f620 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -326,6 +326,7 @@ struct DirPyrDenoiseParamsEdited { bool chroma; bool redchro; bool bluechro; + bool gain; bool gamma; bool lcurve; bool cccurve;