diff --git a/rtdata/languages/default b/rtdata/languages/default
index a5cd7746e..7dd47e154 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -817,6 +817,7 @@ HISTORY_MSG_BLURWAV;Blur luminance
HISTORY_MSG_BLURCWAV;Blur chroma
HISTORY_MSG_EDGEFFECT;Edge Damper
HISTORY_MSG_SIGMAFIN;Final contrast Damper
+HISTORY_MSG_SIGMATON;Toning Damper
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s
HISTORY_SNAPSHOT;Snapshot
diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h
index d003df644..9d4a0235c 100644
--- a/rtengine/improcfun.h
+++ b/rtengine/improcfun.h
@@ -216,7 +216,7 @@ public:
void finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, const cont_params &cp,
int W_L, int H_L, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL);
void ContAllAB(LabImage * lab, int maxlvl, float **varhue, float **varchrom, float ** WavCoeffs_a, float * WavCoeffs_a0, int level, int dir, const WavOpacityCurveW & waOpacityCurveW, struct cont_params &cp,
- int W_ab, int H_ab, const bool useChannelA);
+ int W_ab, int H_ab, const bool useChannelA, float *meanab, float *sigmaab);
void Evaluate2(const wavelet_decomposition &WaveletCoeffs_L,
float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN);
void Eval2(float ** WavCoeffs_L, int level,
diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc
index 157fb6239..9d50dedff 100644
--- a/rtengine/ipwavelet.cc
+++ b/rtengine/ipwavelet.cc
@@ -114,6 +114,7 @@ struct cont_params {
float tmstrength;
float balan;
float sigmafin;
+ float sigmaton;
int ite;
int contmet;
bool opaW;
@@ -193,6 +194,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
cp.tonemap = params->wavelet.tmrs != 0;
cp.bam = false;
cp.sigmafin = params->wavelet.sigmafin;
+ cp.sigmaton = params->wavelet.sigmaton;
if (params->wavelet.TMmethod == "cont") {
cp.contmet = 1;
@@ -931,9 +933,11 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
vari[1] = rtengine::max(0.000001f, vari[1]);
vari[2] = rtengine::max(0.000001f, vari[2]);
vari[3] = rtengine::max(0.000001f, kr3 * vari[3]);
+
if (settings->verbose) {
- printf("LUM var0=%f var1=%f var2=%f var3=%f\n",vari[0], vari[1], vari[2], vari[3]);
+ printf("LUM var0=%f var1=%f var2=%f var3=%f\n", vari[0], vari[1], vari[2], vari[3]);
}
+
// float* noisevarlum = nullptr; // we need a dummy to pass it to WaveletDenoiseAllL
int GWL = labco->W;
int GHL = labco->H;
@@ -1176,9 +1180,11 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
variC[6] = max(0.00001f, k6 * variC[6]);
variCb[6] = max(0.00001f, k6 * variCb[6]);
+
if (settings->verbose) {
- printf("CHRO var0=%f va1=%f va2=%f va3=%f va4=%f val5=%f va6=%f\n", variC[0], variC[1], variC[2], variC[3],variC[4],variC[5], variC[6]);
+ printf("CHRO var0=%f va1=%f va2=%f va3=%f va4=%f val5=%f va6=%f\n", variC[0], variC[1], variC[2], variC[3], variC[4], variC[5], variC[6]);
}
+
/*
for (int y = 0; y < 7; y++) {
printf("y=%i madL=%f varia=%f variab=%f\n", y, madL[y][1], variC[y], variCb[y]);
@@ -2203,27 +2209,28 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float *
//Blur luma
if (cp.blurres != 0.f && cp.resena) {
- int minWL = min(W_L, H_L);
- float k = 0.5f;
- //printf("skip=%i WL=%i HL=%i min=%i\n", skip, W_L, H_L, minWL);
- if(minWL > 140) {//disabled if too low windows
- float rad = k * 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];
- }
+ int minWL = min(W_L, H_L);
+ float k = 0.5f;
- boxblur(bef, aft, rad, W_L, H_L, false);
+ //printf("skip=%i WL=%i HL=%i min=%i\n", skip, W_L, H_L, minWL);
+ if (minWL > 140) { //disabled if too low windows
+ float rad = k * 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++) {
- WavCoeffs_L0[i] = aft[i];
- }
-
- delete[] bef;
- delete[] aft;
+ 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;
+ }
}
//
@@ -2679,8 +2686,9 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float
if (cp.blurcres != 0.f && cp.resena) {
int minWL = min(W_L, H_L);
float k = 0.5f;
+
//printf("skip=%i WL=%i HL=%i min=%i\n", skip, W_L, H_L, minWL);
- if(minWL > 140) {//disabled if too low windows
+ if (minWL > 140) { //disabled if too low windows
float rad = k * cp.blurcres / skip;
float * bef = new float[W_L * H_L];
float * aft = new float[W_L * H_L];
@@ -2722,7 +2730,7 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float
int Hlvl_ab = WaveletCoeffs_ab.level_H(lvl);
float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl);
- ContAllAB(labco, maxlvl, varhue, varchrom, WavCoeffs_ab, WavCoeffs_ab0, lvl, dir, waOpacityCurveW, cp, Wlvl_ab, Hlvl_ab, useChannelA);
+ ContAllAB(labco, maxlvl, varhue, varchrom, WavCoeffs_ab, WavCoeffs_ab0, lvl, dir, waOpacityCurveW, cp, Wlvl_ab, Hlvl_ab, useChannelA, meanab, sigmaab);
if (wavblcurve && wavcurvecomp && cp.blena && cp.chrwav > 0.f) {
@@ -3846,7 +3854,7 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz
}
void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, float **varchrom, float ** WavCoeffs_ab, float * WavCoeffs_ab0, int level, int dir, const WavOpacityCurveW & waOpacityCurveW, struct cont_params &cp,
- int W_ab, int H_ab, const bool useChannelA)
+ int W_ab, int H_ab, const bool useChannelA, float *meanab, float *sigmaab)
{
float cpMul = cp.mul[level];
@@ -3981,15 +3989,47 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f
}
if ((useOpacity && level < 9 && mulOpacity != 0.f) && cp.toningena) { //toning
+ float mea[10];
+ float effect = cp.sigmaton;
+ float betaab = 0.f;
+ float offs = 1.f;
- float beta = (1024.f + 20.f * mulOpacity) / 1024.f ;
+ calceffect(level, meanab, sigmaab, mea, effect, offs);
+
+ for (int co = 0; co < W_ab * H_ab; co++) {
+ float WavCab = std::fabs(WavCoeffs_ab[dir][co]);
+
+ if (WavCab < mea[0]) {
+ betaab = 0.05f;
+ } else if (WavCab < mea[1]) {
+ betaab = 0.2f;
+ } else if (WavCab < mea[2]) {
+ betaab = 0.7f;
+ } else if (WavCab < mea[3]) {
+ betaab = 1.f; //standard
+ } else if (WavCab < mea[4]) {
+ betaab = 1.f;
+ } else if (WavCab < mea[5]) {
+ betaab = 0.8f; //+sigma
+ } else if (WavCab < mea[6]) {
+ betaab = 0.6f;
+ } else if (WavCab < mea[7]) {
+ betaab = 0.4f;
+ } else if (WavCab < mea[8]) {
+ betaab = 0.2f; // + 2 sigma
+ } else if (WavCab < mea[9]) {
+ betaab = 0.1f;
+ } else {
+ betaab = 0.0f;
+ }
+ }
+
+ float beta = (1024.f + 50.f * mulOpacity * betaab) / 1024.f ;
- //float beta = (1000.f * mulOpacity);
for (int i = 0; i < W_ab * H_ab; i++) {
WavCoeffs_ab[dir][i] *= beta;
}
- // WavCoeffs_ab[dir][i] += beta;
}
if (waOpacityCurveW) {
diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc
index 0d8324d4e..bac9e86ff 100644
--- a/rtengine/procparams.cc
+++ b/rtengine/procparams.cc
@@ -2264,6 +2264,7 @@ WaveletParams::WaveletParams() :
strength(100),
balance(0),
sigmafin(1.0),
+ sigmaton(1.0),
iter(0),
expcontrast(false),
expchroma(false),
@@ -2379,6 +2380,7 @@ bool WaveletParams::operator ==(const WaveletParams& other) const
&& strength == other.strength
&& balance == other.balance
&& sigmafin == other.sigmafin
+ && sigmaton == other.sigmaton
&& iter == other.iter
&& expcontrast == other.expcontrast
&& expchroma == other.expchroma
@@ -3517,6 +3519,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
saveToKeyfile(!pedited || pedited->wavelet.strength, "Wavelet", "Strength", wavelet.strength, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.balance, "Wavelet", "Balance", wavelet.balance, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.sigmafin, "Wavelet", "Sigmafin", wavelet.sigmafin, keyFile);
+ saveToKeyfile(!pedited || pedited->wavelet.sigmaton, "Wavelet", "Sigmaton", wavelet.sigmaton, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.iter, "Wavelet", "Iter", wavelet.iter, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.thres, "Wavelet", "MaxLev", wavelet.thres, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.Tilesmethod, "Wavelet", "TilesMethod", wavelet.Tilesmethod, keyFile);
@@ -4695,6 +4698,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
assignFromKeyfile(keyFile, "Wavelet", "Strength", pedited, wavelet.strength, pedited->wavelet.strength);
assignFromKeyfile(keyFile, "Wavelet", "Balance", pedited, wavelet.balance, pedited->wavelet.balance);
assignFromKeyfile(keyFile, "Wavelet", "Sigmafin", pedited, wavelet.sigmafin, pedited->wavelet.sigmafin);
+ assignFromKeyfile(keyFile, "Wavelet", "Sigmaton", pedited, wavelet.sigmaton, pedited->wavelet.sigmaton);
assignFromKeyfile(keyFile, "Wavelet", "Iter", pedited, wavelet.iter, pedited->wavelet.iter);
assignFromKeyfile(keyFile, "Wavelet", "Median", pedited, wavelet.median, pedited->wavelet.median);
assignFromKeyfile(keyFile, "Wavelet", "Medianlev", pedited, wavelet.medianlev, pedited->wavelet.medianlev);
diff --git a/rtengine/procparams.h b/rtengine/procparams.h
index c26b02de4..e5ac570af 100644
--- a/rtengine/procparams.h
+++ b/rtengine/procparams.h
@@ -1222,6 +1222,7 @@ struct WaveletParams {
int strength;
int balance;
double sigmafin;
+ double sigmaton;
int iter;
bool expcontrast;
bool expchroma;
diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc
index 9eff3c4ce..e83e74bc9 100644
--- a/rtgui/paramsedited.cc
+++ b/rtgui/paramsedited.cc
@@ -476,6 +476,7 @@ void ParamsEdited::set(bool v)
wavelet.balance = v;
wavelet.iter = v;
wavelet.sigmafin = v;
+ wavelet.sigmaton = v;
wavelet.median = v;
wavelet.medianlev = v;
wavelet.linkedg = v;
@@ -1087,6 +1088,7 @@ void ParamsEdited::initFrom(const std::vector&
wavelet.balance = wavelet.balance && p.wavelet.balance == other.wavelet.balance;
wavelet.iter = wavelet.iter && p.wavelet.iter == other.wavelet.iter;
wavelet.sigmafin = wavelet.sigmafin && p.wavelet.sigmafin == other.wavelet.sigmafin;
+ wavelet.sigmaton = wavelet.sigmaton && p.wavelet.sigmaton == other.wavelet.sigmaton;
wavelet.median = wavelet.median && p.wavelet.median == other.wavelet.median;
wavelet.medianlev = wavelet.medianlev && p.wavelet.medianlev == other.wavelet.medianlev;
wavelet.linkedg = wavelet.linkedg && p.wavelet.linkedg == other.wavelet.linkedg;
@@ -2899,6 +2901,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
toEdit.wavelet.sigmafin = mods.wavelet.sigmafin;
}
+ if (wavelet.sigmaton) {
+ toEdit.wavelet.sigmaton = mods.wavelet.sigmaton;
+ }
+
if (wavelet.iter) {
toEdit.wavelet.iter = mods.wavelet.iter;
}
diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h
index 351096a7e..773f5592d 100644
--- a/rtgui/paramsedited.h
+++ b/rtgui/paramsedited.h
@@ -500,6 +500,7 @@ struct WaveletParamsEdited {
bool balance;
bool iter;
bool sigmafin;
+ bool sigmaton;
bool median;
bool medianlev;
bool linkedg;
diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc
index c12e216cf..db3687b3e 100644
--- a/rtgui/wavelet.cc
+++ b/rtgui/wavelet.cc
@@ -113,6 +113,7 @@ Wavelet::Wavelet() :
balance(Gtk::manage(new Adjuster(M("TP_WAVELET_BALANCE"), -30, 100, 1, 0))),
iter(Gtk::manage(new Adjuster(M("TP_WAVELET_ITER"), -3, 3, 1, 0))),
sigmafin(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMAFIN"), 0.025, 2.5, 0.01, 1.))),
+ sigmaton(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMAFIN"), 0.025, 2.5, 0.01, 1.))),
hueskin(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_HUESKIN"), -314., 314., -5., 25., 170., 120., 0, false))),
hueskin2(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_HUESKY"), -314., 314., -260., -250, -130., -140., 0, false))),
hllev(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_HIGHLIGHT"), 0., 100., 50., 75., 100., 98., 0, false))),
@@ -210,6 +211,7 @@ Wavelet::Wavelet() :
EvWavresblurc = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLURCWAV");
EvWavedgeffect = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_EDGEFFECT");
EvWavsigmafin = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_SIGMAFIN");
+ EvWavsigmaton = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_SIGMATON");
expsettings->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expsettings));
@@ -487,6 +489,7 @@ Wavelet::Wavelet() :
// Toning
ToolParamBlock* const tonBox = Gtk::manage(new ToolParamBlock());
+ sigmaton->setAdjusterListener(this);
opaCurveEditorG->setCurveListener(this);
@@ -498,7 +501,7 @@ Wavelet::Wavelet() :
opaCurveEditorG->curveListComplete();
opaCurveEditorG->show();
-
+ tonBox->pack_start(*sigmaton);
tonBox->pack_start(*opaCurveEditorG, Gtk::PACK_SHRINK, 2);
opacityCurveEditorG->setCurveListener(this);
@@ -1434,6 +1437,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited)
balance->setValue(pp->wavelet.balance);
iter->setValue(pp->wavelet.iter);
sigmafin->setValue(pp->wavelet.sigmafin);
+ sigmaton->setValue(pp->wavelet.sigmaton);
for (int i = 0; i < 9; i++) {
correction[i]->setValue(pp->wavelet.c[i]);
@@ -1552,6 +1556,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited)
balance->setEditedState(pedited->wavelet.balance ? Edited : UnEdited);
iter->setEditedState(pedited->wavelet.iter ? Edited : UnEdited);
sigmafin->setEditedState(pedited->wavelet.sigmafin ? Edited : UnEdited);
+ sigmaton->setEditedState(pedited->wavelet.sigmaton ? Edited : UnEdited);
threshold->setEditedState(pedited->wavelet.threshold ? Edited : UnEdited);
threshold2->setEditedState(pedited->wavelet.threshold2 ? Edited : UnEdited);
edgedetect->setEditedState(pedited->wavelet.edgedetect ? Edited : UnEdited);
@@ -1824,6 +1829,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited)
pp->wavelet.iter = (int) iter->getValue();
pp->wavelet.wavclCurve = clshape->getCurve();
pp->wavelet.sigmafin = sigmafin->getValue();
+ pp->wavelet.sigmaton = sigmaton->getValue();
for (int i = 0; i < 9; i++) {
pp->wavelet.c[i] = (int) correction[i]->getValue();
@@ -1931,6 +1937,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited)
pedited->wavelet.balance = balance->getEditedState();
pedited->wavelet.iter = iter->getEditedState();
pedited->wavelet.sigmafin = sigmafin->getEditedState();
+ pedited->wavelet.sigmaton = sigmaton->getEditedState();
pedited->wavelet.wavclCurve = !clshape->isUnChanged();
pedited->wavelet.expcontrast = !expcontrast->get_inconsistent();
pedited->wavelet.expchroma = !expchroma->get_inconsistent();
@@ -2112,6 +2119,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit
balance->setDefault(defParams->wavelet.balance);
iter->setDefault(defParams->wavelet.iter);
sigmafin->setDefault(defParams->wavelet.sigmafin);
+ sigmaton->setDefault(defParams->wavelet.sigmaton);
sigma->setDefault(defParams->wavelet.sigma);
offset->setDefault(defParams->wavelet.offset);
lowthr->setDefault(defParams->wavelet.lowthr);
@@ -2235,6 +2243,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit
balance->setDefaultEditedState(pedited->wavelet.balance ? Edited : UnEdited);
iter->setDefaultEditedState(pedited->wavelet.iter ? Edited : UnEdited);
sigmafin->setDefaultEditedState(pedited->wavelet.sigmafin ? Edited : UnEdited);
+ sigmaton->setDefaultEditedState(pedited->wavelet.sigmaton ? Edited : UnEdited);
level0noise->setDefaultEditedState(pedited->wavelet.level0noise ? Edited : UnEdited);
level1noise->setDefaultEditedState(pedited->wavelet.level1noise ? Edited : UnEdited);
level2noise->setDefaultEditedState(pedited->wavelet.level2noise ? Edited : UnEdited);
@@ -2298,6 +2307,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit
balance->setDefaultEditedState(Irrelevant);
iter->setDefaultEditedState(Irrelevant);
sigmafin->setDefaultEditedState(Irrelevant);
+ sigmaton->setDefaultEditedState(Irrelevant);
for (int i = 0; i < 9; i++) {
correction[i]->setDefaultEditedState(Irrelevant);
@@ -2831,6 +2841,7 @@ void Wavelet::setBatchMode(bool batchMode)
balance->showEditedCB();
iter->showEditedCB();
sigmafin->showEditedCB();
+ sigmaton->showEditedCB();
level0noise->showEditedCB();
level1noise->showEditedCB();
level2noise->showEditedCB();
@@ -2982,6 +2993,8 @@ void Wavelet::adjusterChanged(Adjuster* a, double newval)
listener->panelChanged(EvWaviter, iter->getTextValue());
} else if (a == sigmafin) {
listener->panelChanged(EvWavsigmafin, sigmafin->getTextValue());
+ } else if (a == sigmaton) {
+ listener->panelChanged(EvWavsigmaton, sigmaton->getTextValue());
} else if (a == greenhigh) {
listener->panelChanged(EvWavgreenhigh, greenhigh->getTextValue());
} else if (a == bluehigh) {
diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h
index 271aea5b2..e8154b680 100644
--- a/rtgui/wavelet.h
+++ b/rtgui/wavelet.h
@@ -94,6 +94,7 @@ private:
rtengine::ProcEvent EvWavresblurc;
rtengine::ProcEvent EvWavedgeffect;
rtengine::ProcEvent EvWavsigmafin;
+ rtengine::ProcEvent EvWavsigmaton;
void foldAllButMe(GdkEventButton* event, MyExpander *expander);
@@ -220,6 +221,7 @@ private:
Adjuster* const balance;
Adjuster* const iter;
Adjuster* const sigmafin;
+ Adjuster* const sigmaton;
Adjuster* greenlow;
Adjuster* bluelow;