diff --git a/rtdata/languages/default b/rtdata/languages/default
index bf260961f..282327ba5 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -808,6 +808,8 @@ HISTORY_MSG_WAVOLDSH;Old algorithm
HISTORY_MSG_WAVOFFSET;Offset
HISTORY_MSG_BLSHAPE;Blur by level
HISTORY_MSG_WAVBL;Blur levels
+HISTORY_MSG_BLURWAV;Blur luminance
+HISTORY_MSG_BLURCWAV;Blur chroma
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s
HISTORY_SNAPSHOT;Snapshot
@@ -2142,6 +2144,7 @@ TP_WAVELET_BANONE;None
TP_WAVELET_BASLI;Slider
TP_WAVELET_BATYPE;Contrast balance method
TP_WAVELET_BLCURVE;Blur by levels
+TP_WAVELET_BLURFRAME;Blur
TP_WAVELET_CBENAB;Toning and Color Balance
TP_WAVELET_CB_TOOLTIP;For strong values product color-toning by combining it or not with levels decomposition 'toning'\nFor low values you can change the white balance of the background (sky, ...) without changing that of the front plane, generally more contrasted
TP_WAVELET_CCURVE;Local contrast
@@ -2262,6 +2265,8 @@ TP_WAVELET_RADIUS;Radius Shadows - Highlight
TP_WAVELET_RE1;Reinforced
TP_WAVELET_RE2;Unchanged
TP_WAVELET_RE3;Reduced
+TP_WAVELET_RESBLUR;Blur Luminance
+TP_WAVELET_RESBLURC;Blur Chroma
TP_WAVELET_RESCHRO;Intensity
TP_WAVELET_RESCON;Shadows
TP_WAVELET_RESCONH;Highlights
@@ -2299,6 +2304,7 @@ TP_WAVELET_TMSTRENGTH;Compression strength
TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image.
TP_WAVELET_TMEDGS;Edge stopping
TP_WAVELET_TON;Toning
+TP_WAVELET_TMTYPE;Compression method
TP_WAVELET_USH;None
TP_WAVELET_USHARP;Clarity method
TP_WAVELET_USHARP_TOOLTIP;Origin : the source file is the file before Wavelet.\nWavelet : the source file is the file including wavelet threatment
diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc
index 4600f14ec..461bdc7ac 100644
--- a/rtengine/ipwavelet.cc
+++ b/rtengine/ipwavelet.cc
@@ -65,6 +65,8 @@ struct cont_params {
float thH;
float conres;
float conresH;
+ float blurres;
+ float blurcres;
float radius;
float chrores;
bool oldsh;
@@ -396,6 +398,8 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
cp.radius = waparams.radius;
cp.chrores = waparams.reschro;
cp.oldsh = waparams.oldsh;
+ cp.blurres = waparams.resblur;
+ cp.blurcres = waparams.resblurc;
//cp.hueres=waparams.reshue;
cp.hueres = 2.f;
cp.th = float(waparams.thr);
@@ -1910,7 +1914,25 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float *
}
}
+//Blur luma
+ if(cp.blurres != 0.f && cp.resena) {
+ float rad = cp.blurres / skip;
+ float * bef = new float[W_L * H_L];
+ float * aft = new float[W_L * H_L];
+ for (int i = 0; i < H_L * W_L; i++) {
+ bef[i] = WavCoeffs_L0[i];
+ }
+ boxblur(bef, aft, rad, W_L, H_L, false);
+
+ for (int i = 0; i < H_L * W_L; i++) {
+ WavCoeffs_L0[i] = aft[i];
+ }
+
+ delete bef;
+ delete aft;
+ }
+//
#ifdef _OPENMP
#pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1)
#endif
@@ -2054,15 +2076,15 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float *
// end
}
- bool wavcurvecomp = false;//not enable if 0.75
+ bool wavcurvecomp = false;//not enable if 0.75
- if (wavblcurve) {
- for (int i = 0; i < 500; i++) {
- if (wavblcurve[i] != 0.) {
- wavcurvecomp = true;
- }
- }
- }
+ if (wavblcurve) {
+ for (int i = 0; i < 500; i++) {
+ if (wavblcurve[i] != 0.) {
+ wavcurvecomp = true;
+ }
+ }
+ }
#ifdef _OPENMP
#pragma omp for schedule(dynamic) collapse(2)
@@ -2298,16 +2320,36 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float
}
}
}
+
+//Blur chroma
+ if(cp.blurcres != 0.f && cp.resena) {
+ float rad = cp.blurcres / skip;
+ float * bef = new float[W_L * H_L];
+ float * aft = new float[W_L * H_L];
- bool wavcurvecomp = false;//not enable if 0.75
+ for (int i = 0; i < H_L * W_L; i++) {
+ bef[i] = WavCoeffs_ab0[i];
+ }
+ boxblur(bef, aft, rad, W_L, H_L, false);
- if (wavblcurve) {
- for (int i = 0; i < 500; i++) {
- if (wavblcurve[i] != 0.) {
- wavcurvecomp = true;
- }
- }
- }
+ for (int i = 0; i < H_L * W_L; i++) {
+ WavCoeffs_ab0[i] = aft[i];
+ }
+
+ delete bef;
+ delete aft;
+ }
+
+
+ bool wavcurvecomp = false;//not enable if 0.75
+
+ if (wavblcurve) {
+ for (int i = 0; i < 500; i++) {
+ if (wavblcurve[i] != 0.) {
+ wavcurvecomp = true;
+ }
+ }
+ }
#ifdef _OPENMP
#pragma omp for schedule(dynamic) collapse(2)
diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc
index 0c76e3003..574e4f3a2 100644
--- a/rtengine/procparams.cc
+++ b/rtengine/procparams.cc
@@ -2291,6 +2291,8 @@ WaveletParams::WaveletParams() :
rescon(0),
resconH(0),
reschro(0),
+ resblur(0),
+ resblurc(0),
tmrs(0),
edgs(1.4),
scale(1.),
@@ -2404,6 +2406,8 @@ bool WaveletParams::operator ==(const WaveletParams& other) const
&& rescon == other.rescon
&& resconH == other.resconH
&& reschro == other.reschro
+ && resblur == other.resblur
+ && resblurc == other.resblurc
&& tmrs == other.tmrs
&& edgs == other.edgs
&& scale == other.scale
@@ -3601,6 +3605,8 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
saveToKeyfile(!pedited || pedited->wavelet.thrH, "Wavelet", "ThresholdResidHighLight", wavelet.thrH, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.radius, "Wavelet", "Residualradius", wavelet.radius, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.reschro, "Wavelet", "Residualchroma", wavelet.reschro, keyFile);
+ saveToKeyfile(!pedited || pedited->wavelet.resblur, "Wavelet", "Residualblur", wavelet.resblur, keyFile);
+ saveToKeyfile(!pedited || pedited->wavelet.resblurc, "Wavelet", "Residualblurc", wavelet.resblurc, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.tmrs, "Wavelet", "ResidualTM", wavelet.tmrs, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.edgs, "Wavelet", "ResidualEDGS", wavelet.edgs, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.scale, "Wavelet", "ResidualSCALE", wavelet.scale, keyFile);
@@ -4719,6 +4725,8 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
assignFromKeyfile(keyFile, "Wavelet", "ResidualcontShadow", pedited, wavelet.rescon, pedited->wavelet.rescon);
assignFromKeyfile(keyFile, "Wavelet", "ResidualcontHighlight", pedited, wavelet.resconH, pedited->wavelet.resconH);
assignFromKeyfile(keyFile, "Wavelet", "Residualchroma", pedited, wavelet.reschro, pedited->wavelet.reschro);
+ assignFromKeyfile(keyFile, "Wavelet", "Residualblur", pedited, wavelet.resblur, pedited->wavelet.resblur);
+ assignFromKeyfile(keyFile, "Wavelet", "Residualblurc", pedited, wavelet.resblurc, pedited->wavelet.resblurc);
assignFromKeyfile(keyFile, "Wavelet", "ResidualTM", pedited, wavelet.tmrs, pedited->wavelet.tmrs);
assignFromKeyfile(keyFile, "Wavelet", "ResidualEDGS", pedited, wavelet.edgs, pedited->wavelet.edgs);
assignFromKeyfile(keyFile, "Wavelet", "ResidualSCALE", pedited, wavelet.scale, pedited->wavelet.scale);
diff --git a/rtengine/procparams.h b/rtengine/procparams.h
index e78c8fc47..62ca88690 100644
--- a/rtengine/procparams.h
+++ b/rtengine/procparams.h
@@ -1250,6 +1250,8 @@ struct WaveletParams {
int rescon;
int resconH;
int reschro;
+ int resblur;
+ int resblurc;
double tmrs;
double edgs;
double scale;
diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc
index b568d3b52..4dc81fc5f 100644
--- a/rtgui/paramsedited.cc
+++ b/rtgui/paramsedited.cc
@@ -514,6 +514,8 @@ void ParamsEdited::set(bool v)
wavelet.offset = v;
wavelet.resconH = v;
wavelet.reschro = v;
+ wavelet.resblur = v;
+ wavelet.resblurc = v;
wavelet.tmrs = v;
wavelet.edgs = v;
wavelet.scale = v;
@@ -1116,6 +1118,8 @@ void ParamsEdited::initFrom(const std::vector&
wavelet.rescon = wavelet.rescon && p.wavelet.rescon == other.wavelet.rescon;
wavelet.resconH = wavelet.resconH && p.wavelet.resconH == other.wavelet.resconH;
wavelet.reschro = wavelet.reschro && p.wavelet.reschro == other.wavelet.reschro;
+ wavelet.resblur = wavelet.resblur && p.wavelet.resblur == other.wavelet.resblur;
+ wavelet.resblurc = wavelet.resblurc && p.wavelet.resblurc == other.wavelet.resblurc;
wavelet.tmrs = wavelet.tmrs && p.wavelet.tmrs == other.wavelet.tmrs;
wavelet.edgs = wavelet.edgs && p.wavelet.edgs == other.wavelet.edgs;
wavelet.scale = wavelet.scale && p.wavelet.scale == other.wavelet.scale;
@@ -3198,6 +3202,14 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
toEdit.wavelet.offset = mods.wavelet.offset;
}
+ if (wavelet.resblur) {
+ toEdit.wavelet.resblur = mods.wavelet.resblur;
+ }
+
+ if (wavelet.resblurc) {
+ toEdit.wavelet.resblurc = mods.wavelet.resblurc;
+ }
+
if (wavelet.resconH) {
toEdit.wavelet.resconH = dontforceSet && options.baBehav[ADDSET_WA_RESCONH] ? toEdit.wavelet.resconH + mods.wavelet.resconH : mods.wavelet.resconH;
}
diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h
index 8e02ba58f..de688d856 100644
--- a/rtgui/paramsedited.h
+++ b/rtgui/paramsedited.h
@@ -530,6 +530,8 @@ struct WaveletParamsEdited {
bool rescon;
bool resconH;
bool reschro;
+ bool resblur;
+ bool resblurc;
bool tmrs;
bool edgs;
bool scale;
diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc
index d5c5e55e8..cc53a45a2 100644
--- a/rtgui/wavelet.cc
+++ b/rtgui/wavelet.cc
@@ -87,6 +87,8 @@ Wavelet::Wavelet() :
rescon(Gtk::manage(new Adjuster(M("TP_WAVELET_RESCON"), -100, 100, 1, 0))),
resconH(Gtk::manage(new Adjuster(M("TP_WAVELET_RESCONH"), -100, 100, 1, 0))),
reschro(Gtk::manage(new Adjuster(M("TP_WAVELET_RESCHRO"), -100, 100, 1, 0))),
+ resblur(Gtk::manage(new Adjuster(M("TP_WAVELET_RESBLUR"), 0, 100, 1, 0))),
+ resblurc(Gtk::manage(new Adjuster(M("TP_WAVELET_RESBLURC"), 0, 100, 1, 0))),
tmrs(Gtk::manage(new Adjuster(M("TP_WAVELET_TMSTRENGTH"), -1.0, 2.0, 0.01, 0.0))),
edgs(Gtk::manage(new Adjuster(M("TP_WAVELET_TMEDGS"), 0.1, 4.0, 0.01, 1.4))),
scale(Gtk::manage(new Adjuster(M("TP_WAVELET_TMSCALE"), 0.1, 10.0, 0.01, 1.0))),
@@ -149,6 +151,7 @@ Wavelet::Wavelet() :
chanMixerHLFrame(Gtk::manage(new Gtk::Frame(M("TP_COLORTONING_HIGHLIGHT")))),
chanMixerMidFrame(Gtk::manage(new Gtk::Frame(M("TP_COLORTONING_MIDTONES")))),
chanMixerShadowsFrame(Gtk::manage(new Gtk::Frame(M("TP_COLORTONING_SHADOWS")))),
+ blurFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_BLURFRAME")))),
chromaFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_CHROMAFRAME")))),
wavLabels(Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER))),
labmC(Gtk::manage(new Gtk::Label(M("TP_WAVELET_CTYPE") + ":"))),
@@ -187,6 +190,8 @@ Wavelet::Wavelet() :
EvWavoffset = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVOFFSET");
EvWavsoftwav = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_SOFTWAV");
EvWavblshape = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLSHAPE");
+ EvWavresblur = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLURWAV");
+ EvWavresblurc = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLURCWAV");
expsettings->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expsettings));
@@ -662,7 +667,7 @@ Wavelet::Wavelet() :
softwav->setLogScale(10, -10);
softwav->setAdjusterListener(this);
- blBox->pack_start(*softwav);
+// blBox->pack_start(*softwav);
// Gamut
@@ -741,6 +746,14 @@ Wavelet::Wavelet() :
resBox->pack_start(*contrast); //keep the possibility to reinstall
reschro->setAdjusterListener(this);
+ resblur->setAdjusterListener(this);
+ resblurc->setAdjusterListener(this);
+
+ blurFrame->set_label_align(0.025, 0.5);
+ ToolParamBlock* const blurBox = Gtk::manage(new ToolParamBlock());
+ blurBox->pack_start(*resblur);
+ blurBox->pack_start(*resblurc);
+ blurFrame->add(*blurBox);
chromaFrame->set_label_align(0.025, 0.5);
ToolParamBlock* const chromaBox = Gtk::manage(new ToolParamBlock());
@@ -796,6 +809,7 @@ Wavelet::Wavelet() :
const std::vector milestones3 = makeWholeHueRange();
curveEditorRES->setCurveListener(this);
+ resBox->pack_start(*blurFrame);
resBox->pack_start(*chromaFrame);
hhshape = static_cast(curveEditorRES->addCurve(CT_Flat, M("TP_WAVELET_CURVEEDITOR_HH")));
@@ -1292,6 +1306,8 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited)
rescon->setValue(pp->wavelet.rescon);
resconH->setValue(pp->wavelet.resconH);
reschro->setValue(pp->wavelet.reschro);
+ resblur->setValue(pp->wavelet.resblur);
+ resblurc->setValue(pp->wavelet.resblurc);
tmrs->setValue(pp->wavelet.tmrs);
edgs->setValue(pp->wavelet.edgs);
scale->setValue(pp->wavelet.scale);
@@ -1449,6 +1465,8 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited)
offset->setEditedState(pedited->wavelet.offset ? Edited : UnEdited);
resconH->setEditedState(pedited->wavelet.resconH ? Edited : UnEdited);
reschro->setEditedState(pedited->wavelet.reschro ? Edited : UnEdited);
+ resblur->setEditedState(pedited->wavelet.resblur ? Edited : UnEdited);
+ resblurc->setEditedState(pedited->wavelet.resblurc ? Edited : UnEdited);
tmrs->setEditedState(pedited->wavelet.tmrs ? Edited : UnEdited);
edgs->setEditedState(pedited->wavelet.edgs ? Edited : UnEdited);
scale->setEditedState(pedited->wavelet.scale ? Edited : UnEdited);
@@ -1638,6 +1656,8 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited)
pp->wavelet.rescon = rescon->getValue();
pp->wavelet.resconH = resconH->getValue();
pp->wavelet.reschro = reschro->getValue();
+ pp->wavelet.resblur = resblur->getValue();
+ pp->wavelet.resblurc = resblurc->getValue();
pp->wavelet.tmrs = tmrs->getValue();
pp->wavelet.edgs = edgs->getValue();
pp->wavelet.scale = scale->getValue();
@@ -1755,6 +1775,8 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited)
pedited->wavelet.rescon = rescon->getEditedState();
pedited->wavelet.resconH = resconH->getEditedState();
pedited->wavelet.reschro = reschro->getEditedState();
+ pedited->wavelet.resblur = resblur->getEditedState();
+ pedited->wavelet.resblurc = resblurc->getEditedState();
pedited->wavelet.tmrs = tmrs->getEditedState();
pedited->wavelet.edgs = edgs->getEditedState();
pedited->wavelet.scale = scale->getEditedState();
@@ -1997,6 +2019,8 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit
rescon->setDefault(defParams->wavelet.rescon);
resconH->setDefault(defParams->wavelet.resconH);
reschro->setDefault(defParams->wavelet.reschro);
+ resblur->setDefault(defParams->wavelet.resblur);
+ resblurc->setDefault(defParams->wavelet.resblurc);
tmrs->setDefault(defParams->wavelet.tmrs);
edgs->setDefault(defParams->wavelet.edgs);
scale->setDefault(defParams->wavelet.scale);
@@ -2062,6 +2086,8 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit
rescon->setDefault(defParams->wavelet.rescon);
resconH->setDefault(defParams->wavelet.resconH);
reschro->setDefault(defParams->wavelet.reschro);
+ resblur->setDefault(defParams->wavelet.resblur);
+ resblurc->setDefault(defParams->wavelet.resblurc);
tmrs->setDefault(defParams->wavelet.tmrs);
edgs->setDefault(defParams->wavelet.edgs);
scale->setDefault(defParams->wavelet.scale);
@@ -2116,6 +2142,8 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit
rescon->setDefaultEditedState(Irrelevant);
resconH->setDefaultEditedState(Irrelevant);
reschro->setDefaultEditedState(Irrelevant);
+ resblur->setDefaultEditedState(Irrelevant);
+ resblurc->setDefaultEditedState(Irrelevant);
tmrs->setDefaultEditedState(Irrelevant);
edgs->setDefaultEditedState(Irrelevant);
scale->setDefaultEditedState(Irrelevant);
@@ -2648,6 +2676,8 @@ void Wavelet::setBatchMode(bool batchMode)
rescon->showEditedCB();
resconH->showEditedCB();
reschro->showEditedCB();
+ resblur->showEditedCB();
+ resblurc->showEditedCB();
tmrs->showEditedCB();
edgs->showEditedCB();
scale->showEditedCB();
@@ -2736,6 +2766,10 @@ void Wavelet::adjusterChanged(Adjuster* a, double newval)
listener->panelChanged(EvWavresconH, resconH->getTextValue());
} else if (a == reschro) {
listener->panelChanged(EvWavreschro, reschro->getTextValue());
+ } else if (a == resblur) {
+ listener->panelChanged(EvWavresblur, resblur->getTextValue());
+ } else if (a == resblurc) {
+ listener->panelChanged(EvWavresblurc, resblurc->getTextValue());
} else if (a == tmrs) {
adjusterUpdateUI(a);
listener->panelChanged(EvWavtmrs, tmrs->getTextValue());
diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h
index 0d9081660..15ac97a84 100644
--- a/rtgui/wavelet.h
+++ b/rtgui/wavelet.h
@@ -85,6 +85,8 @@ private:
rtengine::ProcEvent EvWavoffset;
rtengine::ProcEvent EvWavsoftwav;
rtengine::ProcEvent EvWavblshape;
+ rtengine::ProcEvent EvWavresblur;
+ rtengine::ProcEvent EvWavresblurc;
void foldAllButMe(GdkEventButton* event, MyExpander *expander);
@@ -185,6 +187,8 @@ private:
Adjuster* const rescon;
Adjuster* const resconH;
Adjuster* const reschro;
+ Adjuster* const resblur;
+ Adjuster* const resblurc;
Adjuster* const tmrs;
Adjuster* const edgs;
Adjuster* const scale;
@@ -273,6 +277,7 @@ private:
Gtk::Frame* const chanMixerHLFrame;
Gtk::Frame* const chanMixerMidFrame;
Gtk::Frame* const chanMixerShadowsFrame;
+ Gtk::Frame* const blurFrame;
Gtk::Frame* const chromaFrame;
Gtk::Label* const wavLabels;