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;