From 1f4613cd3b3b396e00a93a3a36b7d1bcdae167f8 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 22 Mar 2020 10:37:21 +0100 Subject: [PATCH 01/16] GUI for TM wavelet --- rtdata/languages/default | 10 +++- rtengine/curves.cc | 35 ++++++++++++++ rtengine/curves.h | 24 ++++++++++ rtengine/dcrop.cc | 3 +- rtengine/improccoordinator.cc | 18 ++++++- rtengine/improccoordinator.h | 1 + rtengine/procparams.cc | 28 +++++++++++ rtengine/procparams.h | 6 +++ rtengine/simpleprocess.cc | 3 +- rtgui/paramsedited.cc | 24 ++++++++++ rtgui/paramsedited.h | 4 ++ rtgui/wavelet.cc | 90 +++++++++++++++++++++++++++++++++-- rtgui/wavelet.h | 12 ++++- 13 files changed, 248 insertions(+), 10 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index fe6ddaa7c..e957a5e2a 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -802,6 +802,10 @@ HISTORY_MSG_WAVSIGMA;Sigma HISTORY_MSG_WAVSOFTRAD;Soft radius clarity HISTORY_MSG_WAVSOFTRADEND;Soft radius final HISTORY_MSG_WAVUSHAMET;Clarity method +HISTORY_MSG_THRESWAV;Balance threshold +HISTORY_MSG_SOFTWAV;Soft radius +HISTORY_MSG_TMSHAPE;Compression by level +HISTORY_MSG_WAVTM;Tone mapping wavelet HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOT;Snapshot @@ -2267,6 +2271,7 @@ TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are tr TP_WAVELET_SKY;Sky targetting/protection TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. TP_WAVELET_SOFTRAD;Soft Radius +TP_WAVELET_SOFWAV;Soft Radius TP_WAVELET_STREN;Strength TP_WAVELET_STRENGTH;Strength TP_WAVELET_SUPE;Extra @@ -2275,17 +2280,20 @@ TP_WAVELET_THRESHOLD;Highlight levels TP_WAVELET_THRESHOLD2;Shadow levels TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +TP_WAVELET_THRESWAV;Balance Threshold TP_WAVELET_THRH;Highlights threshold TP_WAVELET_TILESBIG;Big tiles TP_WAVELET_TILESFULL;Full image TP_WAVELET_TILESIZE;Tiling method TP_WAVELET_TILESLIT;Little tiles TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +TP_WAVELET_TM;Tone mapping wavelet TP_WAVELET_TMEDGS;Edge stopping TP_WAVELET_TMSCALE;Scale TP_WAVELET_TMSTRENGTH;Compression strength TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. -TP_WAVELET_TMTYPE;Compression method +TP_WAVELET_TMEDGS;Edge stopping +TP_WAVELET_TMURVE;(un)Compression by Level TP_WAVELET_TON;Toning TP_WAVELET_USH;None TP_WAVELET_USHARP;Clarity method diff --git a/rtengine/curves.cc b/rtengine/curves.cc index a2b5d1d2b..a3e327dbf 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -1209,6 +1209,41 @@ void WavCurve::Set(const std::vector &curvePoints) } } +WavtmCurve::WavtmCurve() {} + +void WavtmCurve::Reset() +{ + luttmCurve.reset(); +} + +void WavtmCurve::Set(const Curve &pCurve) +{ + if (pCurve.isIdentity()) { + Reset(); // raise this value if the quality suffers from this number of samples + return; + } + + luttmCurve(501); // raise this value if the quality suffers from this number of samples + + for (int i = 0; i < 501; i++) { + luttmCurve[i] = pCurve.getVal(double(i) / 500.); + } +} + +void WavtmCurve::Set(const std::vector &curvePoints) +{ + if (!curvePoints.empty() && curvePoints[0] > FCT_Linear && curvePoints[0] < FCT_Unchanged) { + FlatCurve tcurve(curvePoints, false, CURVES_MIN_POLY_POINTS / 2); + tcurve.setIdentityValue(0.); + Set(tcurve); + } else { + Reset(); + } + +} + + + WavOpacityCurveRG::WavOpacityCurveRG() {} diff --git a/rtengine/curves.h b/rtengine/curves.h index c5bb0c18f..380bad9d6 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -627,6 +627,30 @@ public: } }; +class WavtmCurve +{ +private: + LUTf luttmCurve; // 0xffff range + void Set(const Curve &pCurve); +public: + virtual ~WavtmCurve() {}; + WavtmCurve(); + + void Reset(); + // void Set(const std::vector &curvePoints, bool &opautili); + void Set(const std::vector &curvePoints); + float operator[](float index) const + { + return luttmCurve[index]; + } + + operator bool (void) const + { + return luttmCurve; + } +}; + + class WavOpacityCurveRG { private: diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 640d78b0e..c2de5e0c5 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -967,13 +967,14 @@ void Crop::update(int todo) } WavCurve wavCLVCurve; + WavtmCurve wavtmCurve; WavOpacityCurveRG waOpacityCurveRG; WavOpacityCurveBY waOpacityCurveBY; WavOpacityCurveW waOpacityCurveW; WavOpacityCurveWL waOpacityCurveWL; LUTf wavclCurve; - params.wavelet.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); + params.wavelet.getCurves(wavCLVCurve, wavtmCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); LabImage *unshar = nullptr; Glib::ustring provis; LabImage *provradius = nullptr; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 9bef5b502..682b26410 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -867,7 +867,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if ((params->wavelet.enabled)) { WaveletParams WaveParams = params->wavelet; - WaveParams.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); + WaveParams.getCurves(wavCLVCurve, wavtmCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); int kall = 0; LabImage *unshar = nullptr; Glib::ustring provis; @@ -885,8 +885,10 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } if (WaveParams.softrad > 0.f) { + printf("s1\n"); provradius = new LabImage(pW, pH); provradius->CopyFrom(nprevl); + printf("s2\n"); } @@ -922,10 +924,14 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) WaveParams.expnoise = pronois; if (WaveParams.softrad > 0.f) { + printf("s3\n"); + array2D ble(pW, pH); array2D guid(pW, pH); Imagefloat *tmpImage = nullptr; tmpImage = new Imagefloat(pW, pH); + printf("s4\n"); + #ifdef _OPENMP #pragma omp parallel for #endif @@ -948,6 +954,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) tmpImage->b(ir, jr) = Z; ble[ir][jr] = Y / 32768.f; } + printf("s5\n"); + double epsilmax = 0.0001; double epsilmin = 0.00001; double aepsil = (epsilmax - epsilmin) / 90.f; @@ -957,6 +965,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) float blur = 10.f / scale * (0.0001f + 0.8f * WaveParams.softrad); // rtengine::guidedFilter(guid, ble, ble, blur, 0.001, multiTh); rtengine::guidedFilter(guid, ble, ble, blur, epsil, false); + printf("s6\n"); @@ -973,7 +982,10 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) Color::XYZ2Lab(X, Y, Z, L, a, b); nprevl->L[ir][jr] = L; } + printf("s7\n"); + delete tmpImage; + printf("s8\n"); } @@ -1063,8 +1075,12 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } */ if (WaveParams.softrad > 0.f) { + printf("s9\n"); + delete provradius; provradius = NULL; + printf("s10\n"); + } diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 454294beb..c797986e5 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -139,6 +139,7 @@ protected: NoiseCurve noiseLCurve; NoiseCurve noiseCCurve; WavCurve wavCLVCurve; + WavtmCurve wavtmCurve; WavOpacityCurveRG waOpacityCurveRG; WavOpacityCurveBY waOpacityCurveBY; WavOpacityCurveW waOpacityCurveW; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index e795d9bd9..cf5a693f8 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2164,6 +2164,17 @@ WaveletParams::WaveletParams() : 0.35, 0.35 }, + tmcurve{ + static_cast(FCT_MinMaxCPoints), + 0.0, + 0.75, + 0.35, + 0.35, + 1.0, + 0.75, + 0.35, + 0.35 + }, opacityCurveRG{ static_cast(FCT_MinMaxCPoints), 0.0, @@ -2252,6 +2263,7 @@ WaveletParams::WaveletParams() : c{}, ch{}, expedge(false), + exptm(false), expresid(false), expfinal(false), exptoning(false), @@ -2300,6 +2312,8 @@ WaveletParams::WaveletParams() : thrH(70), radius(40), skinprotect(0.0), + threswav(1.4), + softwav(1.0), hueskin(-5, 25, 170, 120, false), hueskin2(-260, -250, -130, -140, false), hllev(50, 75, 100, 98, false), @@ -2318,6 +2332,7 @@ bool WaveletParams::operator ==(const WaveletParams& other) const { return ccwcurve == other.ccwcurve + && tmcurve == other.tmcurve && opacityCurveRG == other.opacityCurveRG && opacityCurveBY == other.opacityCurveBY && opacityCurveW == other.opacityCurveW @@ -2359,6 +2374,7 @@ bool WaveletParams::operator ==(const WaveletParams& other) const return true; }() && expedge == other.expedge + && exptm == other.exptm && expresid == other.expresid && expfinal == other.expfinal && expclari == other.expclari @@ -2407,6 +2423,8 @@ bool WaveletParams::operator ==(const WaveletParams& other) const && thrH == other.thrH && radius == other.radius && skinprotect == other.skinprotect + && threswav == other.threswav + && softwav == other.softwav && hueskin == other.hueskin && hueskin2 == other.hueskin2 && hllev == other.hllev @@ -2427,6 +2445,7 @@ bool WaveletParams::operator !=(const WaveletParams& other) const void WaveletParams::getCurves( WavCurve& cCurve, + WavtmCurve& tCurve, WavOpacityCurveRG& opacityCurveLUTRG, WavOpacityCurveBY& opacityCurveLUTBY, WavOpacityCurveW& opacityCurveLUTW, @@ -2434,6 +2453,7 @@ void WaveletParams::getCurves( ) const { cCurve.Set(this->ccwcurve); + tCurve.Set(this->tmcurve); opacityCurveLUTRG.Set(this->opacityCurveRG); opacityCurveLUTBY.Set(this->opacityCurveBY); opacityCurveLUTW.Set(this->opacityCurveW); @@ -3494,6 +3514,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.expcontrast, "Wavelet", "Expcontrast", wavelet.expcontrast, keyFile); saveToKeyfile(!pedited || pedited->wavelet.expchroma, "Wavelet", "Expchroma", wavelet.expchroma, keyFile); saveToKeyfile(!pedited || pedited->wavelet.expedge, "Wavelet", "Expedge", wavelet.expedge, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.exptm, "Wavelet", "Exptm", wavelet.exptm, keyFile); saveToKeyfile(!pedited || pedited->wavelet.expresid, "Wavelet", "Expresid", wavelet.expresid, keyFile); saveToKeyfile(!pedited || pedited->wavelet.expfinal, "Wavelet", "Expfinal", wavelet.expfinal, keyFile); saveToKeyfile(!pedited || pedited->wavelet.exptoning, "Wavelet", "Exptoning", wavelet.exptoning, keyFile); @@ -3541,6 +3562,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.TMmethod, "Wavelet", "TMMethod", wavelet.TMmethod, keyFile); saveToKeyfile(!pedited || pedited->wavelet.chro, "Wavelet", "ChromaLink", wavelet.chro, keyFile); saveToKeyfile(!pedited || pedited->wavelet.ccwcurve, "Wavelet", "ContrastCurve", wavelet.ccwcurve, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.tmcurve, "Wavelet", "TMCurve", wavelet.tmcurve, keyFile); saveToKeyfile(!pedited || pedited->wavelet.pastlev, "Wavelet", "Pastlev", wavelet.pastlev.toVector(), keyFile); saveToKeyfile(!pedited || pedited->wavelet.satlev, "Wavelet", "Satlev", wavelet.satlev.toVector(), keyFile); saveToKeyfile(!pedited || pedited->wavelet.opacityCurveRG, "Wavelet", "OpacityCurveRG", wavelet.opacityCurveRG, keyFile); @@ -3556,6 +3578,8 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.cbenab, "Wavelet", "CBenab", wavelet.cbenab, keyFile); saveToKeyfile(!pedited || pedited->wavelet.lipst, "Wavelet", "Lipst", wavelet.lipst, keyFile); saveToKeyfile(!pedited || pedited->wavelet.skinprotect, "Wavelet", "Skinprotect", wavelet.skinprotect, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.threswav, "Wavelet", "Threswav", wavelet.threswav, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.softwav, "Wavelet", "Softwav", wavelet.softwav, keyFile); saveToKeyfile(!pedited || pedited->wavelet.hueskin, "Wavelet", "Hueskin", wavelet.hueskin.toVector(), keyFile); saveToKeyfile(!pedited || pedited->wavelet.edgrad, "Wavelet", "Edgrad", wavelet.edgrad, keyFile); saveToKeyfile(!pedited || pedited->wavelet.edgval, "Wavelet", "Edgval", wavelet.edgval, keyFile); @@ -4710,6 +4734,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Wavelet", "ThresholdResidHighLight", pedited, wavelet.thrH, pedited->wavelet.thrH); assignFromKeyfile(keyFile, "Wavelet", "Residualradius", pedited, wavelet.radius, pedited->wavelet.radius); assignFromKeyfile(keyFile, "Wavelet", "ContrastCurve", pedited, wavelet.ccwcurve, pedited->wavelet.ccwcurve); + assignFromKeyfile(keyFile, "Wavelet", "TMCurve", pedited, wavelet.tmcurve, pedited->wavelet.tmcurve); assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveRG", pedited, wavelet.opacityCurveRG, pedited->wavelet.opacityCurveRG); assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveBY", pedited, wavelet.opacityCurveBY, pedited->wavelet.opacityCurveBY); assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveW", pedited, wavelet.opacityCurveW, pedited->wavelet.opacityCurveW); @@ -4851,6 +4876,8 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } assignFromKeyfile(keyFile, "Wavelet", "Skinprotect", pedited, wavelet.skinprotect, pedited->wavelet.skinprotect); + assignFromKeyfile(keyFile, "Wavelet", "Threswav", pedited, wavelet.threswav, pedited->wavelet.threswav); + assignFromKeyfile(keyFile, "Wavelet", "Softwav", pedited, wavelet.softwav, pedited->wavelet.softwav); assignFromKeyfile(keyFile, "Wavelet", "Expcontrast", pedited, wavelet.expcontrast, pedited->wavelet.expcontrast); assignFromKeyfile(keyFile, "Wavelet", "Expchroma", pedited, wavelet.expchroma, pedited->wavelet.expchroma); @@ -4881,6 +4908,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } assignFromKeyfile(keyFile, "Wavelet", "Expedge", pedited, wavelet.expedge, pedited->wavelet.expedge); + assignFromKeyfile(keyFile, "Wavelet", "Exptm", pedited, wavelet.exptm, pedited->wavelet.exptm); assignFromKeyfile(keyFile, "Wavelet", "Expresid", pedited, wavelet.expresid, pedited->wavelet.expresid); assignFromKeyfile(keyFile, "Wavelet", "Expfinal", pedited, wavelet.expfinal, pedited->wavelet.expfinal); assignFromKeyfile(keyFile, "Wavelet", "Exptoning", pedited, wavelet.exptoning, pedited->wavelet.exptoning); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index aabe1e7ae..9bfdaab13 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -40,6 +40,7 @@ class OpacityCurve; class RetinexgaintransmissionCurve; class RetinextransmissionCurve; class WavCurve; +class WavtmCurve; class WavOpacityCurveBY; class WavOpacityCurveRG; class WavOpacityCurveW; @@ -1185,6 +1186,7 @@ private: struct WaveletParams { std::vector ccwcurve; + std::vector tmcurve; std::vector opacityCurveRG; std::vector opacityCurveBY; std::vector opacityCurveW; @@ -1220,6 +1222,7 @@ struct WaveletParams { int c[9]; int ch[9]; bool expedge; + bool exptm; bool expresid; bool expfinal; bool exptoning; @@ -1269,6 +1272,8 @@ struct WaveletParams { int thrH; int radius; double skinprotect; + double threswav; + double softwav; Threshold hueskin; Threshold hueskin2; Threshold hllev; @@ -1288,6 +1293,7 @@ struct WaveletParams { void getCurves( WavCurve& cCurve, + WavtmCurve& tCurve, WavOpacityCurveRG& opacityCurveLUTRG, WavOpacityCurveBY& opacityCurveLUTBY, diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 6b9d86baf..e519d5a56 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1120,6 +1120,7 @@ private: bool wavcontlutili = false; WaveletParams WaveParams = params.wavelet; WavCurve wavCLVCurve; + WavtmCurve wavtmCurve; WavOpacityCurveRG waOpacityCurveRG; WavOpacityCurveBY waOpacityCurveBY; WavOpacityCurveW waOpacityCurveW; @@ -1143,7 +1144,7 @@ private: provradius->CopyFrom(labView); } - params.wavelet.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); + params.wavelet.getCurves(wavCLVCurve, wavtmCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); CurveFactory::curveWavContL(wavcontlutili, params.wavelet.wavclCurve, wavclCurve,/* hist16C, dummy,*/ 1); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 48ba4c341..f954a171a 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -541,11 +541,14 @@ void ParamsEdited::set(bool v) wavelet.hllev = v; wavelet.bllev = v; wavelet.edgcont = v; + wavelet.threswav = v; + wavelet.softwav = v; wavelet.level0noise = v; wavelet.level1noise = v; wavelet.level2noise = v; wavelet.level3noise = v; wavelet.ccwcurve = v; + wavelet.tmcurve = v; wavelet.opacityCurveRG = v; wavelet.opacityCurveBY = v; wavelet.opacityCurveW = v; @@ -565,6 +568,7 @@ void ParamsEdited::set(bool v) wavelet.expcontrast = v; wavelet.expchroma = v; wavelet.expedge = v; + wavelet.exptm = v; wavelet.expresid = v; wavelet.exptoning = v; wavelet.expnoise = v; @@ -1136,6 +1140,8 @@ void ParamsEdited::initFrom(const std::vector& wavelet.hllev = wavelet.hllev && p.wavelet.hllev == other.wavelet.hllev; wavelet.bllev = wavelet.bllev && p.wavelet.bllev == other.wavelet.bllev; wavelet.edgcont = wavelet.edgcont && p.wavelet.edgcont == other.wavelet.edgcont; + wavelet.threswav = wavelet.threswav && p.wavelet.threswav == other.wavelet.threswav; + wavelet.softwav = wavelet.softwav && p.wavelet.softwav == other.wavelet.softwav; wavelet.level0noise = wavelet.level0noise && p.wavelet.level0noise == other.wavelet.level0noise; wavelet.level1noise = wavelet.level1noise && p.wavelet.level1noise == other.wavelet.level1noise; wavelet.level2noise = wavelet.level2noise && p.wavelet.level2noise == other.wavelet.level2noise; @@ -1143,6 +1149,7 @@ void ParamsEdited::initFrom(const std::vector& wavelet.pastlev = wavelet.pastlev && p.wavelet.pastlev == other.wavelet.pastlev; wavelet.satlev = wavelet.satlev && p.wavelet.satlev == other.wavelet.satlev; wavelet.ccwcurve = wavelet.ccwcurve && p.wavelet.ccwcurve == other.wavelet.ccwcurve; + wavelet.tmcurve = wavelet.tmcurve && p.wavelet.tmcurve == other.wavelet.tmcurve; wavelet.opacityCurveRG = wavelet.opacityCurveRG && p.wavelet.opacityCurveRG == other.wavelet.opacityCurveRG; wavelet.opacityCurveBY = wavelet.opacityCurveBY && p.wavelet.opacityCurveBY == other.wavelet.opacityCurveBY; wavelet.opacityCurveW = wavelet.opacityCurveW && p.wavelet.opacityCurveW == other.wavelet.opacityCurveW; @@ -1155,6 +1162,7 @@ void ParamsEdited::initFrom(const std::vector& wavelet.expcontrast = wavelet.expcontrast && p.wavelet.expcontrast == other.wavelet.expcontrast; wavelet.expchroma = wavelet.expchroma && p.wavelet.expchroma == other.wavelet.expchroma; wavelet.expedge = wavelet.expedge && p.wavelet.expedge == other.wavelet.expedge; + wavelet.exptm = wavelet.exptm && p.wavelet.exptm == other.wavelet.exptm; wavelet.expresid = wavelet.expresid && p.wavelet.expresid == other.wavelet.expresid; wavelet.expfinal = wavelet.expfinal && p.wavelet.expfinal == other.wavelet.expfinal; wavelet.exptoning = wavelet.exptoning && p.wavelet.exptoning == other.wavelet.exptoning; @@ -3037,6 +3045,14 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.edgcont = mods.wavelet.edgcont; } + if (wavelet.threswav) { + toEdit.wavelet.threswav = mods.wavelet.threswav; + } + + if (wavelet.softwav) { + toEdit.wavelet.softwav = mods.wavelet.softwav; + } + if (wavelet.level0noise) { toEdit.wavelet.level0noise = mods.wavelet.level0noise; } @@ -3065,6 +3081,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.ccwcurve = mods.wavelet.ccwcurve; } + if (wavelet.tmcurve) { + toEdit.wavelet.tmcurve = mods.wavelet.tmcurve; + } + if (wavelet.opacityCurveRG) { toEdit.wavelet.opacityCurveRG = mods.wavelet.opacityCurveRG; } @@ -3106,6 +3126,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.expedge = mods.wavelet.expedge; } + if (wavelet.exptm) { + toEdit.wavelet.exptm = mods.wavelet.exptm; + } + if (wavelet.expresid) { toEdit.wavelet.expresid = mods.wavelet.expresid; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index d2707ec11..619521c05 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -557,11 +557,14 @@ struct WaveletParamsEdited { bool hllev; bool bllev; bool edgcont; + bool threswav; + bool softwav; bool level0noise; bool level1noise; bool level2noise; bool level3noise; bool ccwcurve; + bool tmcurve; bool opacityCurveBY; bool opacityCurveRG; bool opacityCurveW; @@ -584,6 +587,7 @@ struct WaveletParamsEdited { bool expcontrast; bool expchroma; bool expedge; + bool exptm; bool expresid; bool expfinal; bool exptoning; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 7d9a65f2a..a65e3c789 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -63,6 +63,7 @@ Wavelet::Wavelet() : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), true, true), curveEditorG(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_CONTEDIT"))), CCWcurveEditorG(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_CCURVE"))), + curveEditortm(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_TMURVE"))), curveEditorRES(new CurveEditorGroup(options.lastWaveletCurvesDir)), curveEditorGAM(new CurveEditorGroup(options.lastWaveletCurvesDir)), separatorNeutral(Gtk::manage(new Gtk::HSeparator())), @@ -126,6 +127,8 @@ Wavelet::Wavelet() : mergeC(Gtk::manage(new Adjuster(M("TP_WAVELET_MERGEC"), -50, 100, 1, 20))), softrad(Gtk::manage(new Adjuster(M("TP_WAVELET_SOFTRAD"), 0.0, 100., 0.5, 0.))), softradend(Gtk::manage(new Adjuster(M("TP_WAVELET_SOFTRAD"), 0.0, 100., 0.5, 0.))), + threswav(Gtk::manage(new Adjuster(M("TP_WAVELET_THRESWAV"), 0.9, 2., 0.01, 1.4))), + softwav(Gtk::manage(new Adjuster(M("TP_WAVELET_SOFWAV"), -10.0, 1000.0, 0.5, 1.))), Lmethod(Gtk::manage(new MyComboBoxText())), CHmethod(Gtk::manage(new MyComboBoxText())), CHSLmethod(Gtk::manage(new MyComboBoxText())), @@ -159,6 +162,7 @@ Wavelet::Wavelet() : expsettings(Gtk::manage(new MyExpander(false, M("TP_WAVELET_SETTINGS")))), exptoning(Gtk::manage(new MyExpander(true, M("TP_WAVELET_TON")))), expclari(Gtk::manage(new MyExpander(true, M("TP_WAVELET_CLARI")))), + exptm(Gtk::manage(new MyExpander(true, M("TP_WAVELET_TM")))), neutrHBox(Gtk::manage(new Gtk::HBox())), usharpHBox(Gtk::manage(new Gtk::HBox())) { @@ -175,6 +179,10 @@ Wavelet::Wavelet() : EvWavscale = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVSCALE"); EvWavradius = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVRADIUS"); EvWavsigma = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVSIGMA"); + EvWavenatm = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVTM"); + EvWavthreswav = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_THRESWAV"); + EvWavsoftwav = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_SOFTWAV"); + EvWavtmshape = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_TMSHAPE"); expsettings->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expsettings)); @@ -193,6 +201,9 @@ Wavelet::Wavelet() : expedge->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expedge)); enableEdgeConn = expedge->signal_enabled_toggled().connect(sigc::bind(sigc::mem_fun(this, &Wavelet::enableToggled), expedge)); + exptm->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), exptm)); + enabletmConn = exptm->signal_enabled_toggled().connect(sigc::bind(sigc::mem_fun(this, &Wavelet::enableToggled), exptm)); + expgamut->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expgamut)); expresid->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expresid)); @@ -623,6 +634,31 @@ Wavelet::Wavelet() : edgBox->pack_start(*ctboxES); +//TM Wavelet + ToolParamBlock* const tmBox = Gtk::manage(new ToolParamBlock()); + + curveEditortm->setCurveListener(this); + + tmshape = static_cast(curveEditortm->addCurve(CT_Flat, "", nullptr, false, false)); + + tmshape->setIdentityValue(0.); + tmshape->setResetCurve(FlatCurveType(default_params.tmcurve.at(0)), default_params.tmcurve); + tmshape->setTooltip(M("TP_WAVELET_CURVEEDITOR_CC_TOOLTIP")); + + curveEditortm->curveListComplete(); + curveEditortm->show(); + + tmBox->pack_start(*curveEditortm, Gtk::PACK_SHRINK, 4); + + + threswav->setAdjusterListener(this); + tmBox->pack_start(*threswav); + + softwav->setLogScale(10, -10); + softwav->setAdjusterListener(this); + tmBox->pack_start(*softwav); + + // Gamut ToolParamBlock* const conBox = Gtk::manage(new ToolParamBlock()); @@ -939,6 +975,10 @@ Wavelet::Wavelet() : expedge->setLevel(2); pack_start(*expedge); + exptm->add(*tmBox, false); + exptm->setLevel(2); + pack_start(*exptm); + expclari->add(*clariBox, false); expclari->setLevel(2); pack_start(*expclari); @@ -959,6 +999,7 @@ Wavelet::~Wavelet() delete opaCurveEditorG; delete opacityCurveEditorG; + delete curveEditortm; delete CCWcurveEditorG; delete curveEditorRES; delete curveEditorGAM; @@ -1177,6 +1218,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) Lmethod->set_active(selectedLevel == -1 ? 4 : selectedLevel); ccshape->setCurve(pp->wavelet.ccwcurve); + tmshape->setCurve(pp->wavelet.tmcurve); opacityShapeRG->setCurve(pp->wavelet.opacityCurveRG); opacityShapeBY->setCurve(pp->wavelet.opacityCurveBY); opacityShape->setCurve(pp->wavelet.opacityCurveW); @@ -1187,6 +1229,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) expcontrast->setEnabled(pp->wavelet.expcontrast); expchroma->setEnabled(pp->wavelet.expchroma); expedge->setEnabled(pp->wavelet.expedge); + exptm->setEnabled(pp->wavelet.exptm); expresid->setEnabled(pp->wavelet.expresid); expfinal->setEnabled(pp->wavelet.expfinal); exptoning->setEnabled(pp->wavelet.exptoning); @@ -1266,6 +1309,8 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) pastlev->setValue(pp->wavelet.pastlev); satlev->setValue(pp->wavelet.satlev); edgcont->setValue(pp->wavelet.edgcont); + threswav->setValue(pp->wavelet.threswav); + softwav->setValue(pp->wavelet.softwav); greenlow->setValue(pp->wavelet.greenlow); bluelow->setValue(pp->wavelet.bluelow); @@ -1363,9 +1408,11 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) set_inconsistent(multiImage && !pedited->wavelet.enabled); ccshape->setUnChanged(!pedited->wavelet.ccwcurve); + tmshape->setUnChanged(!pedited->wavelet.tmcurve); expcontrast->set_inconsistent(!pedited->wavelet.expcontrast); expchroma->set_inconsistent(!pedited->wavelet.expchroma); expedge->set_inconsistent(!pedited->wavelet.expedge); + exptm->set_inconsistent(!pedited->wavelet.exptm); expresid->set_inconsistent(!pedited->wavelet.expresid); expfinal->set_inconsistent(!pedited->wavelet.expfinal); expclari->set_inconsistent(!pedited->wavelet.expclari); @@ -1437,6 +1484,8 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) satlev->setEditedState(pedited->wavelet.satlev ? Edited : UnEdited); strength->setEditedState(pedited->wavelet.strength ? Edited : UnEdited); edgcont->setEditedState(pedited->wavelet.edgcont ? Edited : UnEdited); + threswav->setEditedState(pedited->wavelet.threswav ? Edited : UnEdited); + softwav->setEditedState(pedited->wavelet.softwav ? Edited : UnEdited); level0noise->setEditedState(pedited->wavelet.level0noise ? Edited : UnEdited); level1noise->setEditedState(pedited->wavelet.level1noise ? Edited : UnEdited); level2noise->setEditedState(pedited->wavelet.level2noise ? Edited : UnEdited); @@ -1542,6 +1591,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) void Wavelet::setEditProvider(EditDataProvider *provider) { ccshape->setEditProvider(provider); + tmshape->setEditProvider(provider); opacityShapeRG->setEditProvider(provider); opacityShapeBY->setEditProvider(provider); opacityShape->setEditProvider(provider); @@ -1554,6 +1604,7 @@ void Wavelet::setEditProvider(EditDataProvider *provider) void Wavelet::autoOpenCurve() { ccshape->openIfNonlinear(); + tmshape->openIfNonlinear(); //opacityShapeRG->openIfNonlinear(); //opacityShapeBY->openIfNonlinear(); } @@ -1604,11 +1655,14 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pp->wavelet.hllev = hllev->getValue (); pp->wavelet.bllev = bllev->getValue (); pp->wavelet.edgcont = edgcont->getValue (); + pp->wavelet.threswav = threswav->getValue(); + pp->wavelet.softwav = softwav->getValue(); pp->wavelet.level0noise = level0noise->getValue (); pp->wavelet.level1noise = level1noise->getValue (); pp->wavelet.level2noise = level2noise->getValue (); pp->wavelet.level3noise = level3noise->getValue (); pp->wavelet.ccwcurve = ccshape->getCurve(); + pp->wavelet.tmcurve = tmshape->getCurve(); pp->wavelet.opacityCurveRG = opacityShapeRG->getCurve(); pp->wavelet.opacityCurveBY = opacityShapeBY->getCurve(); pp->wavelet.opacityCurveW = opacityShape->getCurve(); @@ -1633,6 +1687,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pp->wavelet.expcontrast = expcontrast->getEnabled(); pp->wavelet.expchroma = expchroma->getEnabled(); pp->wavelet.expedge = expedge->getEnabled(); + pp->wavelet.exptm = exptm->getEnabled(); pp->wavelet.expresid = expresid->getEnabled(); pp->wavelet.expfinal = expfinal->getEnabled(); pp->wavelet.exptoning = exptoning->getEnabled(); @@ -1707,7 +1762,10 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.skinprotect = skinprotect->getEditedState(); pedited->wavelet.hllev = hllev->getEditedState(); pedited->wavelet.ccwcurve = !ccshape->isUnChanged(); + pedited->wavelet.tmcurve = !tmshape->isUnChanged(); pedited->wavelet.edgcont = edgcont->getEditedState(); + pedited->wavelet.threswav = threswav->getEditedState(); + pedited->wavelet.softwav = softwav->getEditedState(); pedited->wavelet.level0noise = level0noise->getEditedState(); pedited->wavelet.level1noise = level1noise->getEditedState(); pedited->wavelet.level2noise = level2noise->getEditedState(); @@ -1738,6 +1796,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.expcontrast = !expcontrast->get_inconsistent(); pedited->wavelet.expchroma = !expchroma->get_inconsistent(); pedited->wavelet.expedge = !expedge->get_inconsistent(); + pedited->wavelet.exptm = !exptm->get_inconsistent(); pedited->wavelet.expresid = !expresid->get_inconsistent(); pedited->wavelet.expfinal = !expfinal->get_inconsistent(); pedited->wavelet.exptoning = !exptoning->get_inconsistent(); @@ -1879,6 +1938,8 @@ void Wavelet::curveChanged(CurveEditor* ce) if (listener && getEnabled()) { if (ce == ccshape) { listener->panelChanged(EvWavCCCurve, M("HISTORY_CUSTOMCURVE")); + } else if (ce == tmshape) { + listener->panelChanged(EvWavtmshape, M("HISTORY_CUSTOMCURVE")); } else if (ce == opacityShapeRG) { listener->panelChanged(EvWavColor, M("HISTORY_CUSTOMCURVE")); } else if (ce == opacityShapeBY) { @@ -1945,6 +2006,8 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit pastlev->setDefault (defParams->wavelet.pastlev); satlev->setDefault (defParams->wavelet.satlev); edgcont->setDefault (defParams->wavelet.edgcont); + threswav->setDefault(defParams->wavelet.threswav); + softwav->setDefault(defParams->wavelet.softwav); level0noise->setDefault (defParams->wavelet.level0noise); level1noise->setDefault (defParams->wavelet.level1noise); level2noise->setDefault (defParams->wavelet.level2noise); @@ -2008,6 +2071,8 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit pastlev->setDefaultEditedState(pedited->wavelet.pastlev ? Edited : UnEdited); satlev->setDefaultEditedState(pedited->wavelet.satlev ? Edited : UnEdited); edgcont->setDefaultEditedState(pedited->wavelet.edgcont ? Edited : UnEdited); + threswav->setDefaultEditedState(pedited->wavelet.threswav ? Edited : UnEdited); + softwav->setDefaultEditedState(pedited->wavelet.softwav ? Edited : UnEdited); strength->setDefaultEditedState(pedited->wavelet.strength ? Edited : UnEdited); balance->setDefaultEditedState(pedited->wavelet.balance ? Edited : UnEdited); iter->setDefaultEditedState(pedited->wavelet.iter ? Edited : UnEdited); @@ -2057,6 +2122,8 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit hllev->setDefaultEditedState(Irrelevant); bllev->setDefaultEditedState(Irrelevant); edgcont->setDefaultEditedState(Irrelevant); + threswav->setDefaultEditedState(Irrelevant); + softwav->setDefaultEditedState(Irrelevant); level0noise->setDefaultEditedState(Irrelevant); level1noise->setDefaultEditedState(Irrelevant); level2noise->setDefaultEditedState(Irrelevant); @@ -2550,6 +2617,7 @@ void Wavelet::setBatchMode(bool batchMode) opacityCurveEditorG->setBatchMode(batchMode); opacityCurveEditorW->setBatchMode(batchMode); opacityCurveEditorWL->setBatchMode(batchMode); + curveEditortm->setBatchMode(batchMode); curveEditorRES->setBatchMode(batchMode); curveEditorGAM->setBatchMode(batchMode); sigma->showEditedCB(); @@ -2587,6 +2655,8 @@ void Wavelet::setBatchMode(bool batchMode) pastlev->showEditedCB(); satlev->showEditedCB(); edgcont->showEditedCB(); + threswav->showEditedCB(); + softwav->showEditedCB(); strength->showEditedCB(); balance->showEditedCB(); iter->showEditedCB(); @@ -2749,6 +2819,10 @@ void Wavelet::adjusterChanged(Adjuster* a, double newval) listener->panelChanged(EvWavgreenlow, greenlow->getTextValue()); } else if (a == bluelow) { listener->panelChanged(EvWavbluelow, bluelow->getTextValue()); + } else if (a == threswav) { + listener->panelChanged(EvWavthreswav, threswav->getTextValue()); + } else if (a == softwav) { + listener->panelChanged(EvWavsoftwav, softwav->getTextValue()); } if ((a == correction[0] || a == correction[1] || a == correction[2] || a == correction[3] || a == correction[4] || a == correction[5] || a == correction[6] || a == correction[7] || a == correction[8])) { @@ -3270,6 +3344,7 @@ void Wavelet::foldAllButMe(GdkEventButton* event, MyExpander *expander) exptoning->set_expanded(exptoning == expander); expnoise->set_expanded(expnoise == expander); expedge->set_expanded(expedge == expander); + exptm->set_expanded(exptm == expander); expgamut->set_expanded(expgamut == expander); expresid->set_expanded(expresid == expander); expfinal->set_expanded(expfinal == expander); @@ -3292,6 +3367,8 @@ void Wavelet::enableToggled(MyExpander *expander) event = EvWavenanoise; } else if (expander == expedge) { event = EvWavenaedge; + } else if (expander == exptm) { + event = EvWavenatm; } else if (expander == expresid) { event = EvWavenares; } else if (expander == expfinal) { @@ -3354,6 +3431,7 @@ void Wavelet::writeOptions(std::vector &tpOpen) tpOpen.push_back(exptoning->get_expanded()); tpOpen.push_back(expnoise->get_expanded()); tpOpen.push_back(expedge->get_expanded()); + tpOpen.push_back(exptm->get_expanded()); tpOpen.push_back(expgamut->get_expanded()); tpOpen.push_back(expresid->get_expanded()); tpOpen.push_back(expfinal->get_expanded()); @@ -3369,6 +3447,7 @@ void Wavelet::updateToolState(const std::vector& tpOpen) exptoning->set_expanded(false); expnoise->set_expanded(false); expedge->set_expanded(false); + exptm->set_expanded(false); expgamut->set_expanded(false); expresid->set_expanded(false); expfinal->set_expanded(false); @@ -3376,17 +3455,18 @@ void Wavelet::updateToolState(const std::vector& tpOpen) return; } - if (tpOpen.size() >= 10) { + if (tpOpen.size() >= 11) { expsettings->set_expanded(tpOpen[0]); expcontrast->set_expanded(tpOpen[1]); expchroma->set_expanded(tpOpen[2]); exptoning->set_expanded(tpOpen[3]); expnoise->set_expanded(tpOpen[4]); expedge->set_expanded(tpOpen[5]); - expgamut->set_expanded(tpOpen[6]); - expresid->set_expanded(tpOpen[7]); - expfinal->set_expanded(tpOpen[8]); - expclari->set_expanded(tpOpen.at(9)); + exptm->set_expanded(tpOpen[6]); + expgamut->set_expanded(tpOpen[7]); + expresid->set_expanded(tpOpen[8]); + expfinal->set_expanded(tpOpen[9]); + expclari->set_expanded(tpOpen[10]); } } diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index d3b66657e..356241fa0 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -79,6 +79,10 @@ private: rtengine::ProcEvent EvWavscale; rtengine::ProcEvent EvWavradius; rtengine::ProcEvent EvWavsigma; + rtengine::ProcEvent EvWavenatm; + rtengine::ProcEvent EvWavthreswav; + rtengine::ProcEvent EvWavsoftwav; + rtengine::ProcEvent EvWavtmshape; void foldAllButMe(GdkEventButton* event, MyExpander *expander); @@ -140,6 +144,7 @@ private: CurveEditorGroup* const curveEditorG; CurveEditorGroup* const CCWcurveEditorG; + CurveEditorGroup* const curveEditortm; CurveEditorGroup* const curveEditorRES; CurveEditorGroup* const curveEditorGAM; Gtk::HSeparator* const separatorNeutral; @@ -158,6 +163,7 @@ private: DiagonalCurveEditor* clshape; FlatCurveEditor* ccshape; + FlatCurveEditor* tmshape; Gtk::CheckButton* const median; Gtk::CheckButton* const medianlev; Gtk::CheckButton* const linkedg; @@ -194,6 +200,7 @@ private: Adjuster* const strength; Adjuster* const balance; Adjuster* const iter; + Adjuster* greenlow; Adjuster* bluelow; Adjuster* greenmed; @@ -224,6 +231,8 @@ private: Adjuster* const mergeC; Adjuster* const softrad; Adjuster* const softradend; + Adjuster* const threswav; + Adjuster* const softwav; MyComboBoxText* const Lmethod; sigc::connection Lmethodconn; @@ -275,11 +284,12 @@ private: MyExpander* const expsettings; MyExpander* const exptoning; MyExpander* const expclari; + MyExpander* const exptm; Gtk::HBox* const neutrHBox; Gtk::HBox* const usharpHBox; - sigc::connection enableChromaConn, enableContrastConn, enableEdgeConn, enableFinalConn, enableclariConn; + sigc::connection enableChromaConn, enableContrastConn, enableEdgeConn, enabletmConn, enableFinalConn, enableclariConn; sigc::connection enableNoiseConn, enableResidConn, enableToningConn; sigc::connection medianConn, avoidConn, tmrConn, medianlevConn, linkedgConn, lipstConn, cbenabConn, neutralconn, showmaskConn; sigc::connection neutralPressedConn; From 0ffa61748d9acb2abdb97605cd0a05a7dd2e2c14 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 22 Mar 2020 15:31:36 +0100 Subject: [PATCH 02/16] Prepare ipwavelet and periph to TM --- rtengine/dcrop.cc | 4 ++-- rtengine/improccoordinator.cc | 4 ++-- rtengine/improcfun.h | 3 ++- rtengine/ipwavelet.cc | 2 +- rtengine/simpleprocess.cc | 4 ++-- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index c2de5e0c5..8c3f4f140 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -1003,7 +1003,7 @@ void Crop::update(int todo) unshar = new LabImage(labnCrop->W, labnCrop->H); provis = params.wavelet.CLmethod; params.wavelet.CLmethod = "all"; - parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip); + parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, wavtmCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip); unshar->CopyFrom(labnCrop); params.wavelet.CLmethod = provis; @@ -1016,7 +1016,7 @@ void Crop::update(int todo) WaveParams.expnoise = false; } - parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip); + parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, wavtmCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip); if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { WaveParams.expcontrast = procont; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 682b26410..1ad3a0be1 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -898,7 +898,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) unshar = new LabImage(pW, pH); provis = params->wavelet.CLmethod; params->wavelet.CLmethod = "all"; - ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); + ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavtmCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); unshar->CopyFrom(nprevl); @@ -912,7 +912,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) WaveParams.expnoise = false; } - ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); + ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavtmCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index a06670b72..bb7588513 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -53,6 +53,7 @@ class OpacityCurve; class PipetteBuffer; class ToneCurve; class WavCurve; +class WavtmCurve; class WavOpacityCurveBY; class WavOpacityCurveRG; class WavOpacityCurveW; @@ -200,7 +201,7 @@ public: int pitch, int scale, const int luma, const int chroma/*, LUTf & Lcurve, LUTf & abcurve*/); void Tile_calc(int tilesize, int overlap, int kall, int imwidth, int imheight, int &numtiles_W, int &numtiles_H, int &tilewidth, int &tileheight, int &tileWskip, int &tileHskip); - void ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, const LUTf &wavclCurve, int skip); + void ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const WavtmCurve & wavtmCurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, const LUTf &wavclCurve, int skip); void WaveletcontAllL(LabImage * lab, float **varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_L, struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili); diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 758a9147b..4207eb6d9 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -133,7 +133,7 @@ struct cont_params { int wavNestedLevels = 1; -void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, const LUTf &wavclCurve, int skip) +void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const WavtmCurve & wavtmCurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, const LUTf &wavclCurve, int skip) { diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index e519d5a56..f5bfd81df 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1152,7 +1152,7 @@ private: unshar = new LabImage(fw, fh); provis = params.wavelet.CLmethod; params.wavelet.CLmethod = "all"; - ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); + ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavtmCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); unshar->CopyFrom(labView); params.wavelet.CLmethod = provis; @@ -1164,7 +1164,7 @@ private: WaveParams.expnoise = false; } - ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); + ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavtmCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { WaveParams.expcontrast = procont; From 5bba83f5213d9092697cf5fd4655e05471bd0eed Mon Sep 17 00:00:00 2001 From: Desmis Date: Mon, 23 Mar 2020 10:32:29 +0100 Subject: [PATCH 03/16] Prepare 2 - to TM wavelet --- rtengine/improcfun.h | 2 + rtengine/ipwavelet.cc | 193 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 195 insertions(+) diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index bb7588513..caad76a4f 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -188,6 +188,7 @@ public: void EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params& cp, int W_L, int H_L, float max0, float min0); void CompressDR(float *Source, int W_L, int H_L, float Compression, float DetailBoost); + void Compresslevels2(float **Source, int W_L, int H_L, float compression, float detailattenuator, float thres, float mean, float maxp, float meanN, float maxN, float madL); void ContrastResid(float * WavCoeffs_L0, struct cont_params &cp, int W_L, int H_L, float max0, float min0); void EPDToneMap(LabImage *lab, unsigned int Iterates = 0, int skip = 1); @@ -225,6 +226,7 @@ public: void Sigma(float * HH_Coeffs, int datalen, float averagePlus, float averageNeg, float &sigmaPlus, float &sigmaNeg); void calckoe(float ** WavCoeffs_LL, const cont_params& cp, float ** koeLi, int level, int dir, int W_L, int H_L, float edd, float *maxkoeLi, float **tmC = nullptr); + void softproc2(const LabImage* bufcolorig, const LabImage* bufcolfin, float rad, int bfh, int bfw, double epsilmax, double epsilmin, float thres, int sk, bool multiThread, int flag); void Median_Denoise(float **src, float **dst, int width, int height, Median medianType, int iterations, int numThreads, float **buffer = nullptr); diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 4207eb6d9..ff8efb543 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -32,6 +32,7 @@ #include "EdgePreservingDecomposition.h" #include "iccstore.h" #include "improcfun.h" +#include "imagefloat.h" #include "labimage.h" #include "LUT.h" #include "median.h" @@ -845,6 +846,9 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const Evaluate2(*Ldecomp, mean, meanN, sigma, sigmaN, MaxP, MaxN); } +//here TM wavelet....big memory + + //init for edge and denoise float vari[4]; @@ -3481,4 +3485,193 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f } } } + +void ImProcFunctions::softproc2(const LabImage* bufcolorig, const LabImage* bufcolfin, float rad, int bfh, int bfw, double epsilmax, double epsilmin, float thres, int sk, bool multiThread, int flag) +{ + if (flag == 0) { + if (rad > 0.f) { + array2D ble(bfw, bfh); + array2D guid(bfw, bfh); + Imagefloat *tmpImage = nullptr; + tmpImage = new Imagefloat(bfw, bfh); + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int ir = 0; ir < bfh; ir++) + for (int jr = 0; jr < bfw; jr++) { + + float X, Y, Z; + float L = bufcolorig->L[ir][jr]; + float a = bufcolorig->a[ir][jr]; + float b = bufcolorig->b[ir][jr]; + Color::Lab2XYZ(L, a, b, X, Y, Z); + + guid[ir][jr] = Y / 32768.f; + float La = bufcolfin->L[ir][jr]; + float aa = bufcolfin->a[ir][jr]; + float ba = bufcolfin->b[ir][jr]; + Color::Lab2XYZ(La, aa, ba, X, Y, Z); + tmpImage->r(ir, jr) = X; + tmpImage->g(ir, jr) = Y; + tmpImage->b(ir, jr) = Z; + + ble[ir][jr] = Y / 32768.f; + } + + double aepsil = (epsilmax - epsilmin) / 90.f; + double bepsil = epsilmax - 100.f * aepsil; + double epsil = aepsil * 0.1 * rad + bepsil; + + float blur = 10.f / sk * (thres + 0.8f * rad); + rtengine::guidedFilter(guid, ble, ble, blur, epsil, multiThread, 4); + + + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int ir = 0; ir < bfh; ir++) + for (int jr = 0; jr < bfw; jr++) { + float X = tmpImage->r(ir, jr); + float Y = 32768.f * ble[ir][jr]; + float Z = tmpImage->b(ir, jr); + float L, a, b; + Color::XYZ2Lab(X, Y, Z, L, a, b); + bufcolfin->L[ir][jr] = L; + } + + delete tmpImage; + } + } else if (flag == 1) { + if (rad > 0.f) { + array2D ble(bfw, bfh); + array2D blechro(bfw, bfh); + array2D hue(bfw, bfh); + array2D guid(bfw, bfh); + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int ir = 0; ir < bfh; ir++) + for (int jr = 0; jr < bfw; jr++) { +// hue[ir][jr] = xatan2f(bufcolfin->b[ir][jr], bufcolfin->a[ir][jr]); +// float chromah = sqrt(SQR(bufcolfin->b[ir][jr]) + SQR(bufcolfin->a[ir][jr])); + + ble[ir][jr] = (bufcolfin->L[ir][jr]) / 32768.f; +// blechro[ir][jr] = chromah / 32768.f; + guid[ir][jr] = bufcolorig->L[ir][jr] / 32768.f; + } + + double aepsil = (epsilmax - epsilmin) / 90.f; + double bepsil = epsilmax - 100.f * aepsil; + double epsil = aepsil * 0.1 * rad + bepsil; + + if (rad != 0.f) { + float blur = rad; + blur = blur < 0.f ? -1.f / blur : 1.f + blur; + // int r1 = max(int(4 / sk * blur + 0.5), 1); + int r2 = max(int(25 / sk * blur + 0.5), 1); + + if (rad < 0.f) { + epsil = 0.0001; + } + + rtengine::guidedFilter(guid, ble, ble, r2, epsil, multiThread); +// rtengine::guidedFilter(guid, blechro, blechro, r1, 0.5 * epsil, multiThread); + } + + + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int ir = 0; ir < bfh; ir++) + for (int jr = 0; jr < bfw; jr++) { + // float2 sincosval = xsincosf(hue[ir][jr]); + + bufcolfin->L[ir][jr] = 32768.f * ble[ir][jr]; + // bufcolfin->a[ir][jr] = 32768.f * sincosval.y * blechro[ir][jr]; + // bufcolfin->b[ir][jr] = 32768.f * sincosval.x * blechro[ir][jr]; + } + } + + } +} + + +void ImProcFunctions::Compresslevels2(float **Source, int W_L, int H_L, float compression, float detailattenuator, float thres, float mean, float maxp, float meanN, float maxN, float madL) +{ + //J.Desmis 12-2019 + + float exponent; + + // printf("maxp=%f maxn=%f\n", maxp, maxn); + if (detailattenuator > 0.f && detailattenuator < 0.05f) { + float betemp = expf(-(2.f - detailattenuator + 0.693147f)) - 1.f; //0.69315 = log(2) + exponent = 1.2f * xlogf(-betemp); + exponent /= 20.f; + } else if (detailattenuator >= 0.05f && detailattenuator < 0.25f) { + float betemp = expf(-(2.f - detailattenuator + 0.693147f)) - 1.f; + exponent = 1.2f * xlogf(-betemp); + exponent /= (-75.f * detailattenuator + 23.75f); + } else if (detailattenuator >= 0.25f) { + float betemp = expf(-(2.f - detailattenuator + 0.693147f)) - 1.f; + exponent = 1.2f * xlogf(-betemp); + exponent /= (-2.f * detailattenuator + 5.5f); + } else { + exponent = (compression - 1.0f) / 20.f; + } + + exponent += 1.f; + + + float ap = (thres - 1.f) / (maxp - mean); + float bp = 1.f - ap * mean; + + float a0 = (1.33f * thres - 1.f) / (1.f - mean); + float b0 = 1.f - a0 * mean; + + float apn = (thres - 1.f) / (maxN - meanN); + float bpn = 1.f - apn * meanN; + + float a0n = (1.33f * thres - 1.f) / (1.f - meanN); + float b0n = 1.f - a0n * meanN; + + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int y = 0; y < H_L; y++) { + for (int x = 0; x < W_L; x++) { + float expone = 1.f; + + if (Source[y][x] >= 0.f) { + + if (Source[y][x] > mean) { + expone = 1.f + (exponent - 1.f) * (ap * Source[y][x] + bp); + } else { + expone = 1.f + (exponent - 1.f) * (a0 * Source[y][x] + b0); + } + + Source[y][x] = xexpf(xlogf(Source[y][x] + 0.05f * madL) * expone); + } else if (Source[y][x] < 0.f) { + if (-Source[y][x] > mean) { + expone = 1.f + (exponent - 1.f) * (apn * -Source[y][x] + bpn); + } else { + expone = 1.f + (exponent - 1.f) * (a0n * -Source[y][x] + b0n); + } + + Source[y][x] = -xexpf(xlogf(-Source[y][x] + 0.05f * madL) * expone); + } + } + } + +} + } From e0d36fb41bd7855cee7f7a4b456ffca710798ea8 Mon Sep 17 00:00:00 2001 From: Desmis Date: Mon, 23 Mar 2020 18:10:59 +0100 Subject: [PATCH 04/16] First algo TM wavelet --- rtengine/ipwavelet.cc | 136 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 135 insertions(+), 1 deletion(-) diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index ff8efb543..9d5237273 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -124,6 +124,7 @@ struct cont_params { bool finena; bool toningena; bool noiseena; + bool tmena; int maxilev; float edgsens; float edgampl; @@ -204,6 +205,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.finena = params->wavelet.expfinal; cp.toningena = params->wavelet.exptoning; cp.noiseena = params->wavelet.expnoise; + cp.tmena = params->wavelet.exptm; if (params->wavelet.Backmethod == "black") { cp.backm = 0; @@ -846,7 +848,139 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const Evaluate2(*Ldecomp, mean, meanN, sigma, sigmaN, MaxP, MaxN); } -//here TM wavelet....big memory + //here TM wavelet + if(cp.tmena ){ + float mean2[10]; + float meanN2[10]; + float sigma2[10]; + float sigmaN2[10]; + float MaxP2[10]; + float MaxN2[10]; + //calculate mean, amx, etc. + Evaluate2(*Ldecomp, mean2, meanN2, sigma2, sigmaN2, MaxP2, MaxN2); + + int leve = levwavL; + int dir = 3; + int WW = labco->W; + int HH = labco->H; + float ****templevel = nullptr; + templevel = new float***[dir]; + + //allocate memory for 3 DIR n levels, HH, WW + for (int d = 0; d < dir; d++) { + templevel[d] = new float**[leve]; + + for (int k = 0; k < leve; k++) { + templevel[d][k] = new float*[HH]; + + for (int i = 0; i < HH; i++) { + templevel[d][k][i] = new float[WW]; + } + } + } + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + //fill templevel with decomp for each level, each dir,X Y + for (int dir = 1; dir < 4; dir++) { + for (int level = 0; level < levwavL; ++level) { + int W_L = Ldecomp->level_W(level); + int H_L = Ldecomp->level_H(level); + float **wav_L = Ldecomp->level_coeffs(level); + madL[level][dir - 1] = Mad(wav_L[dir], W_L * H_L);//evaluate noise by level + + for (int y = 0; y < H_L; y++) { + for (int x = 0; x < W_L; x++) { + float val = wav_L[dir][y * W_L + x]; + templevel[dir - 1][level][y][x] = val; + } + } + } + } + + + float thres = params->wavelet.threswav; + + bool wavcurvecomp = false;//not enable if 0.75 + + if (wavtmCurve) { + for (int i = 0; i < 500; i++) { + if (wavtmCurve[i] != 0.75) { + wavcurvecomp = true; + } + } + } + + //for each level, dir calculate templevel with compression + for (int dir = 1; dir < 4; dir++) { + for (int level = 0; level < levwavL; ++level) { + int W_L = Ldecomp->level_W(level); + int H_L = Ldecomp->level_H(level); + + if (wavtmCurve && wavcurvecomp) { + float klev = (wavtmCurve[level * 55.5f] - 0.75f); + + if (klev < 0.f) { + klev *= 2.6666f;//compression increase contraste + } else { + klev *= 4.f;//dilatation reduce contraste - detailattenuator + } + + float compression = expf(-klev); + float detailattenuator = klev; + + if (klev < 0.0f) { + detailattenuator = 0.0f; + } + Compresslevels2(templevel[dir - 1][level], W_L, H_L, compression, detailattenuator, thres, mean2[level], MaxP2[level], meanN2[level], MaxN2[level], madL[level][dir - 1]); + } + } + } + + //retrieve decomp +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int dir = 1; dir < 4; dir++) { + for (int level = 0; level < levwavL ; ++level) { + int W_L = Ldecomp->level_W(level); + int H_L = Ldecomp->level_H(level); + float **wav_L = Ldecomp->level_coeffs(level); + + for (int y = 0; y < H_L; y++) { + for (int x = 0; x < W_L; x++) { + wav_L[dir][y * W_L + x] = templevel[dir - 1][level][y][x]; + } + } + } + } + + + //free memory + for (int i = 0; i < dir; i++) { + for (int j = 0; j < leve; j++) { + for (int l = 0; l < HH; l++) { + delete [] templevel[i][j][l]; + } + } + } + + for (int i = 0; i < dir; i++) { + for (int j = 0; j < leve; j++) { + delete [] templevel[i][j]; + } + } + + for (int i = 0; i < dir; i++) { + delete [] templevel[i]; + } + + delete [] templevel; + + } + // end TM wavelet //init for edge and denoise From ea56e57ec2bcb2be47a36fd62e8fb26e33429544 Mon Sep 17 00:00:00 2001 From: Desmis Date: Thu, 26 Mar 2020 07:19:54 +0100 Subject: [PATCH 05/16] First version blur by level --- rtdata/languages/default | 4 ++-- rtengine/improcfun.h | 4 ++-- rtengine/ipwavelet.cc | 51 +++++++++++++++++++++++++++++++++------- rtgui/wavelet.cc | 18 +++++++------- rtgui/wavelet.h | 2 +- 5 files changed, 57 insertions(+), 22 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 313f7055a..bf260961f 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -806,7 +806,7 @@ HISTORY_MSG_THRESWAV;Balance threshold HISTORY_MSG_SOFTWAV;Soft radius HISTORY_MSG_WAVOLDSH;Old algorithm HISTORY_MSG_WAVOFFSET;Offset -HISTORY_MSG_TMSHAPE;Compression by level +HISTORY_MSG_BLSHAPE;Blur by level HISTORY_MSG_WAVBL;Blur levels HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s @@ -2141,6 +2141,7 @@ TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider al TP_WAVELET_BANONE;None TP_WAVELET_BASLI;Slider TP_WAVELET_BATYPE;Contrast balance method +TP_WAVELET_BLCURVE;Blur by levels 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 @@ -2297,7 +2298,6 @@ TP_WAVELET_TMSCALE;Scale 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_TMURVE;(un)Compression by Level TP_WAVELET_TON;Toning TP_WAVELET_USH;None TP_WAVELET_USHARP;Clarity method diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index d896342d5..424084b8c 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -207,8 +207,8 @@ public: void WaveletcontAllL(LabImage * lab, float **varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_L, const Wavblcurve & wavblcurve, struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili); void WaveletcontAllLfinal(const wavelet_decomposition &WaveletCoeffs_L, const cont_params &cp, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL); - void WaveletcontAllAB(LabImage * lab, float **varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_a, const WavOpacityCurveW & waOpacityCurveW, - struct cont_params &cp, const bool useChannelA); + void WaveletcontAllAB(LabImage * lab, float **varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_a, const Wavblcurve & wavblcurve, const WavOpacityCurveW & waOpacityCurveW, + struct cont_params &cp, const bool useChannelA, int skip); void WaveletAandBAllAB(const wavelet_decomposition &WaveletCoeffs_a, const wavelet_decomposition &WaveletCoeffs_b, const cont_params &cp, FlatCurve* hhcurve, bool hhutili); void ContAllL(float **koeLi, float *maxkoeLi, bool lipschitz, int maxlvl, LabImage * lab, float **varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp, diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 456a3bd1e..4600f14ec 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -59,6 +59,7 @@ struct cont_params { float sigm; int chrom; int chro; + float chrwav; int contrast; float th; float thH; @@ -209,6 +210,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.toningena = params->wavelet.exptoning; cp.noiseena = params->wavelet.expnoise; cp.blena = params->wavelet.expbl; + cp.chrwav = 0.01f * params->wavelet.chrwav; if (params->wavelet.Backmethod == "black") { cp.backm = 0; @@ -1061,7 +1063,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const const std::unique_ptr adecomp(new wavelet_decomposition(labco->data + datalen, labco->W, labco->H, levwava, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!adecomp->memoryAllocationFailed) { - WaveletcontAllAB(labco, varhue, varchro, *adecomp, waOpacityCurveW, cp, true); + WaveletcontAllAB(labco, varhue, varchro, *adecomp, wavblcurve, waOpacityCurveW, cp, true, skip); adecomp->reconstruct(labco->data + datalen, cp.strength); } } @@ -1080,7 +1082,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavb, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!bdecomp->memoryAllocationFailed) { - WaveletcontAllAB(labco, varhue, varchro, *bdecomp, waOpacityCurveW, cp, false); + WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip); bdecomp->reconstruct(labco->data + 2 * datalen, cp.strength); } } @@ -1100,8 +1102,8 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavab, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!adecomp->memoryAllocationFailed && !bdecomp->memoryAllocationFailed) { - WaveletcontAllAB(labco, varhue, varchro, *adecomp, waOpacityCurveW, cp, true); - WaveletcontAllAB(labco, varhue, varchro, *bdecomp, waOpacityCurveW, cp, false); + WaveletcontAllAB(labco, varhue, varchro, *adecomp,wavblcurve, waOpacityCurveW, cp, true, skip); + WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip); WaveletAandBAllAB(*adecomp, *bdecomp, cp, hhCurve, hhutili); adecomp->reconstruct(labco->data + datalen, cp.strength); @@ -2085,9 +2087,9 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * for (int co = 0; co < Hlvl_L * Wlvl_L; co++) { bef[co] = WavCoeffs_L[dir][co]; } - klev = 0.25f * (wavblcurve[lvl * 55.5f]); + klev = (wavblcurve[lvl * 55.5f]); - klev *= 50.f / skip; + klev *= lvl * 50.f / skip; boxblur(bef, aft, klev, Wlvl_L, Hlvl_L, false); for (int co = 0; co < Hlvl_L * Wlvl_L; co++) { @@ -2173,8 +2175,8 @@ void ImProcFunctions::WaveletAandBAllAB(const wavelet_decomposition &WaveletCoef } -void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_ab, const WavOpacityCurveW & waOpacityCurveW, - struct cont_params &cp, const bool useChannelA) +void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_ab, const Wavblcurve & wavblcurve, const WavOpacityCurveW & waOpacityCurveW, + struct cont_params &cp, const bool useChannelA, int skip) { int maxlvl = WaveletCoeffs_ab.maxlevel(); @@ -2297,6 +2299,16 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float } } + 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) #endif @@ -2309,6 +2321,29 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float 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); + + if(wavblcurve && wavcurvecomp && cp.blena && cp.chrwav > 0.f) { + float * bef = new float[Wlvl_ab * Hlvl_ab]; + float * aft = new float[Wlvl_ab * Hlvl_ab]; + float klev; + for (int co = 0; co < Hlvl_ab * Wlvl_ab; co++) { + bef[co] = WavCoeffs_ab[dir][co]; + } + klev = (wavblcurve[lvl * 55.5f]); + + klev *= cp.chrwav * lvl * 100.f / skip; + + boxblur(bef, aft, klev, Wlvl_ab, Hlvl_ab, false); + + for (int co = 0; co < Hlvl_ab * Wlvl_ab; co++) { + WavCoeffs_ab[dir][co] = aft[co]; + } + + delete bef; + delete aft; + } + + } } diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 1bea8a3fa..d5c5e55e8 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -63,7 +63,7 @@ Wavelet::Wavelet() : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), true, true), curveEditorG(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_CONTEDIT"))), CCWcurveEditorG(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_CCURVE"))), - curveEditortm(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_TMURVE"))), + curveEditorbl(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_BLCURVE"))), curveEditorRES(new CurveEditorGroup(options.lastWaveletCurvesDir)), curveEditorGAM(new CurveEditorGroup(options.lastWaveletCurvesDir)), separatorNeutral(Gtk::manage(new Gtk::HSeparator())), @@ -186,7 +186,7 @@ Wavelet::Wavelet() : EvWavoldsh = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVOLDSH"); EvWavoffset = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVOFFSET"); EvWavsoftwav = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_SOFTWAV"); - EvWavblshape = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_blshape"); + EvWavblshape = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLSHAPE"); expsettings->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expsettings)); @@ -643,18 +643,18 @@ Wavelet::Wavelet() : //Blur Wavelet ToolParamBlock* const blBox = Gtk::manage(new ToolParamBlock()); - curveEditortm->setCurveListener(this); + curveEditorbl->setCurveListener(this); - blshape = static_cast(curveEditortm->addCurve(CT_Flat, "", nullptr, false, false)); + blshape = static_cast(curveEditorbl->addCurve(CT_Flat, "", nullptr, false, false)); blshape->setIdentityValue(0.); blshape->setResetCurve(FlatCurveType(default_params.blcurve.at(0)), default_params.blcurve); blshape->setTooltip(M("TP_WAVELET_CURVEEDITOR_CC_TOOLTIP")); - curveEditortm->curveListComplete(); - curveEditortm->show(); + curveEditorbl->curveListComplete(); + curveEditorbl->show(); - blBox->pack_start(*curveEditortm, Gtk::PACK_SHRINK, 4); + blBox->pack_start(*curveEditorbl, Gtk::PACK_SHRINK, 4); chrwav->setAdjusterListener(this); @@ -1008,7 +1008,7 @@ Wavelet::~Wavelet() delete opaCurveEditorG; delete opacityCurveEditorG; - delete curveEditortm; + delete curveEditorbl; delete CCWcurveEditorG; delete curveEditorRES; delete curveEditorGAM; @@ -2640,7 +2640,7 @@ void Wavelet::setBatchMode(bool batchMode) opacityCurveEditorG->setBatchMode(batchMode); opacityCurveEditorW->setBatchMode(batchMode); opacityCurveEditorWL->setBatchMode(batchMode); - curveEditortm->setBatchMode(batchMode); + curveEditorbl->setBatchMode(batchMode); curveEditorRES->setBatchMode(batchMode); curveEditorGAM->setBatchMode(batchMode); sigma->showEditedCB(); diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index 15ad773fc..0d9081660 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -147,7 +147,7 @@ private: CurveEditorGroup* const curveEditorG; CurveEditorGroup* const CCWcurveEditorG; - CurveEditorGroup* const curveEditortm; + CurveEditorGroup* const curveEditorbl; CurveEditorGroup* const curveEditorRES; CurveEditorGroup* const curveEditorGAM; Gtk::HSeparator* const separatorNeutral; From c836376766dd210eafb38584f36bbfc62fa39503 Mon Sep 17 00:00:00 2001 From: Desmis Date: Thu, 26 Mar 2020 09:34:38 +0100 Subject: [PATCH 06/16] Blur residual luma and chroma --- rtdata/languages/default | 6 ++++ rtengine/ipwavelet.cc | 74 +++++++++++++++++++++++++++++++--------- rtengine/procparams.cc | 8 +++++ rtengine/procparams.h | 2 ++ rtgui/paramsedited.cc | 12 +++++++ rtgui/paramsedited.h | 2 ++ rtgui/wavelet.cc | 36 ++++++++++++++++++- rtgui/wavelet.h | 5 +++ 8 files changed, 128 insertions(+), 17 deletions(-) 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; From ac83695645396b9e185e9c5a4272c80cb8b7f2ba Mon Sep 17 00:00:00 2001 From: Desmis Date: Fri, 27 Mar 2020 09:27:43 +0100 Subject: [PATCH 07/16] Suppress warning and add tooltips --- rtdata/languages/default | 2 ++ rtengine/improccoordinator.cc | 10 ---------- rtgui/wavelet.cc | 4 +++- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 282327ba5..cac1f6f12 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2276,6 +2276,7 @@ TP_WAVELET_SETTINGS;Wavelet Settings TP_WAVELET_SHA;Sharp mask TP_WAVELET_SHOWMASK;Show wavelet 'mask' TP_WAVELET_SIGMA;Sigma +TP_WAVELET_SIGMA_TOOLTIP;Sigma acts on the relative amplitude of the signal width. The higher it is, the more the effect will be maximum and the more the unsightly effects will appear.\nLow values are recommended for creating tone-mapping in conjonction with usage Shadows/Highlights below TP_WAVELET_SKIN;Skin targetting/protection TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. TP_WAVELET_SKY;Sky targetting/protection @@ -2310,6 +2311,7 @@ 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 TP_WAVELET_USH_TOOLTIP;If you select Sharp-mask, wavelet settings will be automatically positioned :\nBackground=black, Process=below, level=3...you can change level between 1 and 4.\n\nIf you select Clarity, wavelet settings will be automatically positioned :\nBackground=residual, Process=above, level=7..you can change level between 5 and 10 and wavelet levels. TP_WAVELET_WAVOFFSET;Offset +TP_WAVELET_OFFSET_TOOLTIP;Offset acts on mean of signal.\nHigh values will favor action on the contrast of the highlights.\nLow values will favor action on the contrast of shadows TP_WBALANCE_AUTO;Auto TP_WBALANCE_AUTOITCGREEN;Auto iterate temperature correlation TP_WBALANCE_AUTOOLD;Auto RGB grey diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 45f9f2e56..6374cb837 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -885,10 +885,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } if (WaveParams.softrad > 0.f) { - printf("s1\n"); provradius = new LabImage(pW, pH); provradius->CopyFrom(nprevl); - printf("s2\n"); } @@ -924,13 +922,11 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) WaveParams.expnoise = pronois; if (WaveParams.softrad > 0.f) { - printf("s3\n"); array2D ble(pW, pH); array2D guid(pW, pH); Imagefloat *tmpImage = nullptr; tmpImage = new Imagefloat(pW, pH); - printf("s4\n"); #ifdef _OPENMP #pragma omp parallel for @@ -954,7 +950,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) tmpImage->b(ir, jr) = Z; ble[ir][jr] = Y / 32768.f; } - printf("s5\n"); double epsilmax = 0.0001; double epsilmin = 0.00001; @@ -965,7 +960,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) float blur = 10.f / scale * (0.0001f + 0.8f * WaveParams.softrad); // rtengine::guidedFilter(guid, ble, ble, blur, 0.001, multiTh); rtengine::guidedFilter(guid, ble, ble, blur, epsil, false); - printf("s6\n"); @@ -982,10 +976,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) Color::XYZ2Lab(X, Y, Z, L, a, b); nprevl->L[ir][jr] = L; } - printf("s7\n"); delete tmpImage; - printf("s8\n"); } @@ -1075,11 +1067,9 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } */ if (WaveParams.softrad > 0.f) { - printf("s9\n"); delete provradius; provradius = NULL; - printf("s10\n"); } diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index cc53a45a2..336aad4d5 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -82,7 +82,7 @@ Wavelet::Wavelet() : showmask(Gtk::manage(new Gtk::CheckButton(M("TP_WAVELET_SHOWMASK")))), oldsh(Gtk::manage(new Gtk::CheckButton(M("TP_WAVELET_OLDSH")))), neutralchButton(Gtk::manage(new Gtk::Button(M("TP_WAVELET_NEUTRAL")))), - sigma(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMA"), 0.2, 2.5, 0.01, 1.))), + sigma(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMA"), 0.05, 2.5, 0.01, 1.))), offset(Gtk::manage(new Adjuster(M("TP_WAVELET_WAVOFFSET"), 0.33, 1.66, 0.01, 1., Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), 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))), @@ -351,6 +351,8 @@ Wavelet::Wavelet() : levBox->pack_start(*sigma, Gtk::PACK_SHRINK); offset->setAdjusterListener(this); levBox->pack_start(*offset, Gtk::PACK_SHRINK); + sigma->set_tooltip_text(M("TP_WAVELET_SIGMA_TOOLTIP")); + offset->set_tooltip_text(M("TP_WAVELET_OFFSET_TOOLTIP")); levBox->pack_start(*sup); sup->setAdjusterListener(this); From 95d40e72192096d90efbfa550e85d87603158b6f Mon Sep 17 00:00:00 2001 From: Desmis Date: Fri, 27 Mar 2020 13:31:46 +0100 Subject: [PATCH 08/16] Clean code ipwavelet --- rtengine/ipwavelet.cc | 155 +----------------------------------------- 1 file changed, 1 insertion(+), 154 deletions(-) diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 461bdc7ac..ede980ee6 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -17,7 +17,7 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see . -// * 2014 - 2019 Jacques Desmis +// * 2014 - 2019 2020 - Jacques Desmis // * 2014 Ingo Weyrich // @@ -369,7 +369,6 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } } -// if(settings->verbose) printf("Wav mul 0=%f 1=%f 2=%f 3=%f 4=%f 5=%f 6=%f 7=%f 8=%f 9=%f\n",cp.mul[0],cp.mul[1],cp.mul[2],cp.mul[3],cp.mul[4],cp.mul[5],cp.mul[6],cp.mul[7],cp.mul[8],cp.mul[9]); for (int sc = 0; sc < 9; sc++) { //reduce strength if zoom < 100% for chroma and tuning if (sc == 0) { if (scaleskip[sc] < 1.f) { @@ -425,13 +424,11 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.numlevS = params->wavelet.threshold2; int maxlevS = 9 - cp.numlevH; cp.numlevS = rtengine::min(cp.numlevS, maxlevS); - //printf("levHigh=%d levShad=%d\n",cp.numlevH,cp.numlevS); //highlight cp.b_lhl = static_cast(params->wavelet.hllev.getBottomLeft()); cp.t_lhl = static_cast(params->wavelet.hllev.getTopLeft()); cp.b_rhl = static_cast(params->wavelet.hllev.getBottomRight()); cp.t_rhl = static_cast(params->wavelet.hllev.getTopRight()); - //printf("BL=%f TL=%f BR=%f TR=%f\n",cp.b_lhl,cp.t_lhl,cp.b_rhl,cp.t_rhl); //pastel cp.b_lpast = static_cast(params->wavelet.pastlev.getBottomLeft()); cp.t_lpast = static_cast(params->wavelet.pastlev.getTopLeft()); @@ -458,7 +455,6 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.lev3n = static_cast(params->wavelet.level3noise.getTop()); cp.detectedge = params->wavelet.medianlev; - //printf("low=%f mean=%f sd=%f max=%f\n",cp.edg_low,cp.edg_mean,cp.edg_sd,cp.edg_max); int minwin = rtengine::min(imwidth, imheight); int maxlevelcrop = 9; @@ -487,7 +483,6 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const maxlevelcrop = 5; } - // printf("minwin=%d maxcrop=%d\n",minwin, maxlevelcrop); int levwav = params->wavelet.thres; @@ -567,7 +562,6 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const levwav = rtengine::min(maxlev2, levwav); - //printf("levwav = %d\n",levwav); #ifdef _OPENMP int numthreads = 1; int maxnumberofthreadsforwavelet = 0; @@ -594,7 +588,6 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const maxnumberofthreadsforwavelet = 8; } - //printf("maxNRT=%d\n",maxnumberofthreadsforwavelet); if ((maxnumberofthreadsforwavelet == 6 || maxnumberofthreadsforwavelet == 8) && levwav == 10) { maxnumberofthreadsforwavelet -= 2; } @@ -604,7 +597,6 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } } - //printf("maxthre=%d\n",maxnumberofthreadsforwavelet); // Calculate number of tiles. If less than omp_get_max_threads(), then limit num_threads to number of tiles @@ -857,141 +849,6 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if (cp.val > 0 || ref || contr) { //edge Evaluate2(*Ldecomp, mean, meanN, sigma, sigmaN, MaxP, MaxN); } -/* - //here TM wavelet - if(cp.tmena ){ - float mean2[10]; - float meanN2[10]; - float sigma2[10]; - float sigmaN2[10]; - float MaxP2[10]; - float MaxN2[10]; - //calculate mean, amx, etc. - Evaluate2(*Ldecomp, mean2, meanN2, sigma2, sigmaN2, MaxP2, MaxN2); - - int leve = levwavL; - int dir = 3; - int WW = labco->W; - int HH = labco->H; - float ****templevel = nullptr; - templevel = new float***[dir]; - - //allocate memory for 3 DIR n levels, HH, WW - for (int d = 0; d < dir; d++) { - templevel[d] = new float**[leve]; - - for (int k = 0; k < leve; k++) { - templevel[d][k] = new float*[HH]; - - for (int i = 0; i < HH; i++) { - templevel[d][k][i] = new float[WW]; - } - } - } - -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) -#endif - //fill templevel with decomp for each level, each dir,X Y - for (int dir = 1; dir < 4; dir++) { - for (int level = 0; level < levwavL; ++level) { - int W_L = Ldecomp->level_W(level); - int H_L = Ldecomp->level_H(level); - float **wav_L = Ldecomp->level_coeffs(level); - madL[level][dir - 1] = Mad(wav_L[dir], W_L * H_L);//evaluate noise by level - - for (int y = 0; y < H_L; y++) { - for (int x = 0; x < W_L; x++) { - float val = wav_L[dir][y * W_L + x]; - templevel[dir - 1][level][y][x] = val; - } - } - } - } - - - float thres = params->wavelet.threswav; - - bool wavcurvecomp = false;//not enable if 0.75 - - if (wavtmCurve) { - for (int i = 0; i < 500; i++) { - if (wavtmCurve[i] != 0.75) { - wavcurvecomp = true; - } - } - } - - //for each level, dir calculate templevel with compression - for (int dir = 1; dir < 4; dir++) { - for (int level = 0; level < levwavL; ++level) { - int W_L = Ldecomp->level_W(level); - int H_L = Ldecomp->level_H(level); - - if (wavtmCurve && wavcurvecomp) { - float klev = (wavtmCurve[level * 55.5f] - 0.75f); - - if (klev < 0.f) { - klev *= 2.6666f;//compression increase contraste - } else { - klev *= 4.f;//dilatation reduce contraste - detailattenuator - } - - float compression = expf(-klev); - float detailattenuator = klev; - - if (klev < 0.0f) { - detailattenuator = 0.0f; - } - Compresslevels2(templevel[dir - 1][level], W_L, H_L, compression, detailattenuator, thres, mean2[level], MaxP2[level], meanN2[level], MaxN2[level], madL[level][dir - 1]); - } - } - } - - //retrieve decomp -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) -#endif - - for (int dir = 1; dir < 4; dir++) { - for (int level = 0; level < levwavL ; ++level) { - int W_L = Ldecomp->level_W(level); - int H_L = Ldecomp->level_H(level); - float **wav_L = Ldecomp->level_coeffs(level); - - for (int y = 0; y < H_L; y++) { - for (int x = 0; x < W_L; x++) { - wav_L[dir][y * W_L + x] = templevel[dir - 1][level][y][x]; - } - } - } - } - - - //free memory - for (int i = 0; i < dir; i++) { - for (int j = 0; j < leve; j++) { - for (int l = 0; l < HH; l++) { - delete [] templevel[i][j][l]; - } - } - } - - for (int i = 0; i < dir; i++) { - for (int j = 0; j < leve; j++) { - delete [] templevel[i][j]; - } - } - - for (int i = 0; i < dir; i++) { - delete [] templevel[i]; - } - - delete [] templevel; - - } - // end TM wavelet -*/ //init for edge and denoise float vari[4]; @@ -1055,14 +912,12 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if (!hhutili) { //always a or b int levwava = levwav; - // printf("Levwava before: %d\n",levwava); if (cp.chrores == 0.f && params->wavelet.CLmethod == "all" && !cp.cbena) { // no processing of residual ab => we probably can reduce the number of levels while (levwava > 0 && !cp.diag && (((cp.CHmet == 2 && (cp.chro == 0.f || cp.mul[levwava - 1] == 0.f)) || (cp.CHmet != 2 && (levwava == 10 || (!cp.curv || cp.mulC[levwava - 1] == 0.f))))) && (!cp.opaRG || levwava == 10 || (cp.opaRG && cp.mulopaRG[levwava - 1] == 0.f)) && ((levwava == 10 || (cp.CHSLmet == 1 && cp.mulC[levwava - 1] == 0.f)))) { levwava--; } } - //printf("Levwava after: %d\n",levwava); if (levwava > 0) { const std::unique_ptr adecomp(new wavelet_decomposition(labco->data + datalen, labco->W, labco->H, levwava, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); @@ -1074,14 +929,12 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const int levwavb = levwav; - //printf("Levwavb before: %d\n",levwavb); if (cp.chrores == 0.f && params->wavelet.CLmethod == "all" && !cp.cbena) { // no processing of residual ab => we probably can reduce the number of levels while (levwavb > 0 && !cp.diag && (((cp.CHmet == 2 && (cp.chro == 0.f || cp.mul[levwavb - 1] == 0.f)) || (cp.CHmet != 2 && (levwavb == 10 || (!cp.curv || cp.mulC[levwavb - 1] == 0.f))))) && (!cp.opaBY || levwavb == 10 || (cp.opaBY && cp.mulopaBY[levwavb - 1] == 0.f)) && ((levwavb == 10 || (cp.CHSLmet == 1 && cp.mulC[levwavb - 1] == 0.f)))) { levwavb--; } } - // printf("Levwavb after: %d\n",levwavb); if (levwavb > 0) { const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavb, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); @@ -1093,14 +946,12 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } else {// a and b int levwavab = levwav; - // printf("Levwavab before: %d\n",levwavab); if (cp.chrores == 0.f && !hhutili && params->wavelet.CLmethod == "all") { // no processing of residual ab => we probably can reduce the number of levels while (levwavab > 0 && (((cp.CHmet == 2 && (cp.chro == 0.f || cp.mul[levwavab - 1] == 0.f)) || (cp.CHmet != 2 && (levwavab == 10 || (!cp.curv || cp.mulC[levwavab - 1] == 0.f))))) && (!cp.opaRG || levwavab == 10 || (cp.opaRG && cp.mulopaRG[levwavab - 1] == 0.f)) && ((levwavab == 10 || (cp.CHSLmet == 1 && cp.mulC[levwavab - 1] == 0.f)))) { levwavab--; } } - // printf("Levwavab after: %d\n",levwavab); if (levwavab > 0) { const std::unique_ptr adecomp(new wavelet_decomposition(labco->data + datalen, labco->W, labco->H, levwavab, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavab, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); @@ -1758,7 +1609,6 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * } - // printf("MAXmax0=%f MINmin0=%f\n",max0,min0); //tone mapping if (cp.tonemap && cp.contmet == 2 && cp.resena) { @@ -2400,7 +2250,6 @@ void ImProcFunctions::calckoe(float ** WavCoeffs_LL, const cont_params& cp, floa { int borderL = 2; -// printf("cpedth=%f\n",cp.eddetthr); if (cp.eddetthr < 30.f) { borderL = 1; @@ -3571,7 +3420,6 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f } if (cp.bam && cp.diag) { -//printf("OK Chroma\n"); if (cp.opaW && cp.BAmet == 2) { int iteration = cp.ite; int itplus = 7 + iteration; @@ -3901,7 +3749,6 @@ void ImProcFunctions::Compresslevels2(float **Source, int W_L, int H_L, float co float exponent; - // printf("maxp=%f maxn=%f\n", maxp, maxn); if (detailattenuator > 0.f && detailattenuator < 0.05f) { float betemp = expf(-(2.f - detailattenuator + 0.693147f)) - 1.f; //0.69315 = log(2) exponent = 1.2f * xlogf(-betemp); From d10ff9e816f6ad38d3fe7b6712576ca3ef627976 Mon Sep 17 00:00:00 2001 From: Desmis Date: Fri, 27 Mar 2020 16:21:17 +0100 Subject: [PATCH 09/16] Wavelet Improvment to GUI Residual --- rtdata/languages/default | 4 +++- rtgui/wavelet.cc | 48 ++++++++++++++++++++++++++-------------- rtgui/wavelet.h | 2 ++ 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index cac1f6f12..5c29a9bd0 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2168,6 +2168,7 @@ TP_WAVELET_COMPGAMMA;Compression gamma TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allows you to equilibrate the data and histogram. TP_WAVELET_COMPTM;Tone mapping TP_WAVELET_CONTEDIT;'After' contrast curve +TP_WAVELET_CONTFRAME;Contrast - Compression TP_WAVELET_CONTR;Gamut TP_WAVELET_CONTRA;Contrast TP_WAVELET_CONTRAST_MINUS;Contrast - @@ -2254,7 +2255,7 @@ TP_WAVELET_NPLOW;Low TP_WAVELET_NPNONE;None TP_WAVELET_NPTYPE;Neighboring pixels TP_WAVELET_NPTYPE_TOOLTIP;This algorithm uses the proximity of a pixel and eight of its neighbors. If less difference, edges are reinforced. -TP_WAVELET_OLDSH;Old algorithm using negatives values +TP_WAVELET_OLDSH;Algorithm using negatives values TP_WAVELET_OPACITY;Opacity Blue-Yellow TP_WAVELET_OPACITYW;Contrast balance d/v-h curve TP_WAVELET_OPACITYWL;Final local contrast @@ -2274,6 +2275,7 @@ TP_WAVELET_RESID;Residual Image TP_WAVELET_SAT;Saturated chroma TP_WAVELET_SETTINGS;Wavelet Settings TP_WAVELET_SHA;Sharp mask +TP_WAVELET_SHFRAME;Shadows/Highlights TP_WAVELET_SHOWMASK;Show wavelet 'mask' TP_WAVELET_SIGMA;Sigma TP_WAVELET_SIGMA_TOOLTIP;Sigma acts on the relative amplitude of the signal width. The higher it is, the more the effect will be maximum and the more the unsightly effects will appear.\nLow values are recommended for creating tone-mapping in conjonction with usage Shadows/Highlights below diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 336aad4d5..5ad6fda55 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -151,6 +151,8 @@ 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")))), + shFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_SHFRAME")))), + contFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_CONTFRAME")))), 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))), @@ -726,26 +728,33 @@ Wavelet::Wavelet() : ToolParamBlock* const resBox = Gtk::manage(new ToolParamBlock()); oldsh->set_active(true); oldshConn = oldsh->signal_toggled().connect(sigc::mem_fun(*this, &Wavelet::oldshToggled)); - resBox->pack_start(*oldsh); + rescon->setAdjusterListener(this); - resBox->pack_start(*rescon, Gtk::PACK_SHRINK); - resBox->pack_start(*thr); thr->setAdjusterListener(this); resconH->setAdjusterListener(this); - resBox->pack_start(*resconH, Gtk::PACK_SHRINK); thrH->setAdjusterListener(this); - resBox->pack_start(*thrH, Gtk::PACK_SHRINK); radius->setAdjusterListener(this); - resBox->pack_start(*radius, Gtk::PACK_SHRINK); + radius->hide(); + + shFrame->set_label_align(0.025, 0.5); + ToolParamBlock* const shBox = Gtk::manage(new ToolParamBlock()); + shBox->pack_start(*oldsh); + shBox->pack_start(*rescon, Gtk::PACK_SHRINK); + shBox->pack_start(*thr); + shBox->pack_start(*resconH, Gtk::PACK_SHRINK); + shBox->pack_start(*thrH, Gtk::PACK_SHRINK); + shBox->pack_start(*radius, Gtk::PACK_SHRINK); + shFrame->add(*shBox); + resBox->pack_start(*shFrame); + contrast->set_tooltip_text(M("TP_WAVELET_CONTRA_TOOLTIP")); contrast->setAdjusterListener(this); - resBox->pack_start(*contrast); //keep the possibility to reinstall reschro->setAdjusterListener(this); resblur->setAdjusterListener(this); @@ -768,36 +777,42 @@ Wavelet::Wavelet() : Gtk::HBox* const ctboxTM = Gtk::manage(new Gtk::HBox()); ctboxTM->pack_start(*labmTM, Gtk::PACK_SHRINK, 1); - Gtk::HSeparator* const separatorR0 = Gtk::manage(new Gtk::HSeparator()); - resBox->pack_start(*separatorR0, Gtk::PACK_SHRINK, 2); +// Gtk::HSeparator* const separatorR0 = Gtk::manage(new Gtk::HSeparator()); +// resBox->pack_start(*separatorR0, Gtk::PACK_SHRINK, 2); TMmethod->append(M("TP_WAVELET_COMPCONT")); TMmethod->append(M("TP_WAVELET_COMPTM")); TMmethodconn = TMmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::TMmethodChanged)); ctboxTM->pack_start(*TMmethod); - resBox->pack_start(*ctboxTM); tmrs->set_tooltip_text(M("TP_WAVELET_TMSTRENGTH_TOOLTIP")); - resBox->pack_start(*tmrs); tmrs->setAdjusterListener(this); gamma->set_tooltip_text(M("TP_WAVELET_COMPGAMMA_TOOLTIP")); - resBox->pack_start(*gamma); gamma->setAdjusterListener(this); //edgs->set_tooltip_text(M("TP_WAVELET_TMEDGS_TOOLTIP")); - resBox->pack_start(*edgs); edgs->setAdjusterListener(this); //scale->set_tooltip_text(M("TP_WAVELET_TMSCALE_TOOLTIP")); - resBox->pack_start(*scale); scale->setAdjusterListener(this); - Gtk::HSeparator* const separatorR1 = Gtk::manage(new Gtk::HSeparator()); - resBox->pack_start(*separatorR1, Gtk::PACK_SHRINK, 2); + contFrame->set_label_align(0.025, 0.5); + ToolParamBlock* const contBox = Gtk::manage(new ToolParamBlock()); + contBox->pack_start(*contrast); //keep the possibility to reinstall + contBox->pack_start(*ctboxTM); + contBox->pack_start(*tmrs); + contBox->pack_start(*gamma); + contBox->pack_start(*edgs); + contBox->pack_start(*scale); + contFrame->add(*contBox); + resBox->pack_start(*contFrame); + +// Gtk::HSeparator* const separatorR1 = Gtk::manage(new Gtk::HSeparator()); +// resBox->pack_start(*separatorR1, Gtk::PACK_SHRINK, 2); hueskin2->set_tooltip_markup(M("TP_WAVELET_HUESKY_TOOLTIP")); hueskin2->setBgGradient(milestones); @@ -1577,6 +1592,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) //BackmethodUpdateUI(); CLmethodUpdateUI(); lipstUpdateUI(); + oldshToggled(); //TilesmethodUpdateUI(); //daubcoeffmethodUpdateUI(); //DirmethodUpdateUI(); diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index 15ac97a84..635d8c7a7 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -277,6 +277,8 @@ private: Gtk::Frame* const chanMixerHLFrame; Gtk::Frame* const chanMixerMidFrame; Gtk::Frame* const chanMixerShadowsFrame; + Gtk::Frame* const shFrame; + Gtk::Frame* const contFrame; Gtk::Frame* const blurFrame; Gtk::Frame* const chromaFrame; From a61463447ab90b6602f89050125030870ef75865 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sat, 28 Mar 2020 08:35:00 +0100 Subject: [PATCH 10/16] Improvment to Blur levels --- rtdata/languages/default | 6 +++--- rtengine/ipwavelet.cc | 16 +++++++++------- rtengine/procparams.cc | 8 ++++---- rtengine/procparams.h | 2 +- rtgui/paramsedited.cc | 8 ++++---- rtgui/paramsedited.h | 2 +- rtgui/wavelet.cc | 29 ++++++++++++++--------------- rtgui/wavelet.h | 4 ++-- 8 files changed, 38 insertions(+), 37 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 5c29a9bd0..a46f09a88 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -803,7 +803,7 @@ HISTORY_MSG_WAVSOFTRAD;Soft radius clarity HISTORY_MSG_WAVSOFTRADEND;Soft radius final HISTORY_MSG_WAVUSHAMET;Clarity method HISTORY_MSG_THRESWAV;Balance threshold -HISTORY_MSG_SOFTWAV;Soft radius +HISTORY_MSG_BLUWAV;Maximum blur HISTORY_MSG_WAVOLDSH;Old algorithm HISTORY_MSG_WAVOFFSET;Offset HISTORY_MSG_BLSHAPE;Blur by level @@ -2145,6 +2145,7 @@ TP_WAVELET_BASLI;Slider TP_WAVELET_BATYPE;Contrast balance method TP_WAVELET_BLCURVE;Blur by levels TP_WAVELET_BLURFRAME;Blur +TP_WAVELET_BLUWAV;Maximum 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 @@ -2284,7 +2285,6 @@ TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are tr TP_WAVELET_SKY;Sky targetting/protection TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. TP_WAVELET_SOFTRAD;Soft Radius -TP_WAVELET_SOFWAV;Soft Radius TP_WAVELET_STREN;Strength TP_WAVELET_STRENGTH;Strength TP_WAVELET_SUPE;Extra @@ -2313,7 +2313,7 @@ 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 TP_WAVELET_USH_TOOLTIP;If you select Sharp-mask, wavelet settings will be automatically positioned :\nBackground=black, Process=below, level=3...you can change level between 1 and 4.\n\nIf you select Clarity, wavelet settings will be automatically positioned :\nBackground=residual, Process=above, level=7..you can change level between 5 and 10 and wavelet levels. TP_WAVELET_WAVOFFSET;Offset -TP_WAVELET_OFFSET_TOOLTIP;Offset acts on mean of signal.\nHigh values will favor action on the contrast of the highlights.\nLow values will favor action on the contrast of shadows +TP_WAVELET_OFFSET_TOOLTIP;Offset modifies the balance between shadows and highlights.\n High values will amplify the contrast increase of the highlights, while low values will amplify the contrast increase of the shadows. TP_WBALANCE_AUTO;Auto TP_WBALANCE_AUTOITCGREEN;Auto iterate temperature correlation TP_WBALANCE_AUTOOLD;Auto RGB grey diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index ede980ee6..99b915c65 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -67,6 +67,7 @@ struct cont_params { float conresH; float blurres; float blurcres; + float bluwav; float radius; float chrores; bool oldsh; @@ -399,6 +400,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.oldsh = waparams.oldsh; cp.blurres = waparams.resblur; cp.blurcres = waparams.resblurc; + cp.bluwav = 0.01f * waparams.bluwav; //cp.hueres=waparams.reshue; cp.hueres = 2.f; cp.th = float(waparams.thr); @@ -1766,7 +1768,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * //Blur luma if(cp.blurres != 0.f && cp.resena) { - float rad = cp.blurres / skip; + float rad = 0.7f * cp.blurres / skip; float * bef = new float[W_L * H_L]; float * aft = new float[W_L * H_L]; @@ -1951,7 +1953,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * ContAllL(koeLi, maxkoeLi, true, maxlvl, labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili); //blur levels float klev = 1.f; - if(wavblcurve && wavcurvecomp && cp.blena) { + if(wavblcurve && wavcurvecomp && cp.blena && cp.bluwav > 0.f) { float * bef = new float[Wlvl_L * Hlvl_L]; float * aft = new float[Wlvl_L * Hlvl_L]; @@ -1961,7 +1963,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * } klev = (wavblcurve[lvl * 55.5f]); - klev *= lvl * 50.f / skip; + klev *= cp.bluwav * lvl * 15.f / skip; boxblur(bef, aft, klev, Wlvl_L, Hlvl_L, false); for (int co = 0; co < Hlvl_L * Wlvl_L; co++) { @@ -2173,7 +2175,7 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float //Blur chroma if(cp.blurcres != 0.f && cp.resena) { - float rad = cp.blurcres / skip; + float rad = 0.7f * cp.blurcres / skip; float * bef = new float[W_L * H_L]; float * aft = new float[W_L * H_L]; @@ -2204,7 +2206,7 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float #ifdef _OPENMP #pragma omp for schedule(dynamic) collapse(2) #endif - + for (int dir = 1; dir < 4; dir++) { for (int lvl = 0; lvl < maxlvl; lvl++) { @@ -2214,7 +2216,7 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float 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); - if(wavblcurve && wavcurvecomp && cp.blena && cp.chrwav > 0.f) { + if(wavblcurve && wavcurvecomp && cp.blena && cp.chrwav > 0.f && cp.bluwav > 0.f) { float * bef = new float[Wlvl_ab * Hlvl_ab]; float * aft = new float[Wlvl_ab * Hlvl_ab]; float klev; @@ -2223,7 +2225,7 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float } klev = (wavblcurve[lvl * 55.5f]); - klev *= cp.chrwav * lvl * 100.f / skip; + klev *= cp.bluwav * cp.chrwav * lvl * 25.f / skip; boxblur(bef, aft, klev, Wlvl_ab, Hlvl_ab, false); diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 574e4f3a2..20ae540f5 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2318,7 +2318,7 @@ WaveletParams::WaveletParams() : radius(40), skinprotect(0.0), chrwav(0.), - softwav(1.0), + bluwav(50.0), hueskin(-5, 25, 170, 120, false), hueskin2(-260, -250, -130, -140, false), hllev(50, 75, 100, 98, false), @@ -2433,7 +2433,7 @@ bool WaveletParams::operator ==(const WaveletParams& other) const && radius == other.radius && skinprotect == other.skinprotect && chrwav == other.chrwav - && softwav == other.softwav + && bluwav == other.bluwav && hueskin == other.hueskin && hueskin2 == other.hueskin2 && hllev == other.hllev @@ -3588,7 +3588,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.lipst, "Wavelet", "Lipst", wavelet.lipst, keyFile); saveToKeyfile(!pedited || pedited->wavelet.skinprotect, "Wavelet", "Skinprotect", wavelet.skinprotect, keyFile); saveToKeyfile(!pedited || pedited->wavelet.chrwav, "Wavelet", "chrwav", wavelet.chrwav, keyFile); - saveToKeyfile(!pedited || pedited->wavelet.softwav, "Wavelet", "Softwav", wavelet.softwav, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.bluwav, "Wavelet", "bluwav", wavelet.bluwav, keyFile); saveToKeyfile(!pedited || pedited->wavelet.hueskin, "Wavelet", "Hueskin", wavelet.hueskin.toVector(), keyFile); saveToKeyfile(!pedited || pedited->wavelet.edgrad, "Wavelet", "Edgrad", wavelet.edgrad, keyFile); saveToKeyfile(!pedited || pedited->wavelet.edgval, "Wavelet", "Edgval", wavelet.edgval, keyFile); @@ -4894,7 +4894,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Wavelet", "Skinprotect", pedited, wavelet.skinprotect, pedited->wavelet.skinprotect); assignFromKeyfile(keyFile, "Wavelet", "chrwav", pedited, wavelet.chrwav, pedited->wavelet.chrwav); - assignFromKeyfile(keyFile, "Wavelet", "Softwav", pedited, wavelet.softwav, pedited->wavelet.softwav); + assignFromKeyfile(keyFile, "Wavelet", "bluwav", pedited, wavelet.bluwav, pedited->wavelet.bluwav); assignFromKeyfile(keyFile, "Wavelet", "Expcontrast", pedited, wavelet.expcontrast, pedited->wavelet.expcontrast); assignFromKeyfile(keyFile, "Wavelet", "Expchroma", pedited, wavelet.expchroma, pedited->wavelet.expchroma); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 62ca88690..8ca3e5c29 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1277,7 +1277,7 @@ struct WaveletParams { int radius; double skinprotect; double chrwav; - double softwav; + double bluwav; Threshold hueskin; Threshold hueskin2; Threshold hllev; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 4dc81fc5f..b3c2b64d7 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -546,7 +546,7 @@ void ParamsEdited::set(bool v) wavelet.bllev = v; wavelet.edgcont = v; wavelet.chrwav = v; - wavelet.softwav = v; + wavelet.bluwav = v; wavelet.level0noise = v; wavelet.level1noise = v; wavelet.level2noise = v; @@ -1149,7 +1149,7 @@ void ParamsEdited::initFrom(const std::vector& wavelet.bllev = wavelet.bllev && p.wavelet.bllev == other.wavelet.bllev; wavelet.edgcont = wavelet.edgcont && p.wavelet.edgcont == other.wavelet.edgcont; wavelet.chrwav = wavelet.chrwav && p.wavelet.chrwav == other.wavelet.chrwav; - wavelet.softwav = wavelet.softwav && p.wavelet.softwav == other.wavelet.softwav; + wavelet.bluwav = wavelet.bluwav && p.wavelet.bluwav == other.wavelet.bluwav; wavelet.level0noise = wavelet.level0noise && p.wavelet.level0noise == other.wavelet.level0noise; wavelet.level1noise = wavelet.level1noise && p.wavelet.level1noise == other.wavelet.level1noise; wavelet.level2noise = wavelet.level2noise && p.wavelet.level2noise == other.wavelet.level2noise; @@ -3061,8 +3061,8 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.chrwav = mods.wavelet.chrwav; } - if (wavelet.softwav) { - toEdit.wavelet.softwav = mods.wavelet.softwav; + if (wavelet.bluwav) { + toEdit.wavelet.bluwav = mods.wavelet.bluwav; } if (wavelet.level0noise) { diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index de688d856..43254b015 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -562,7 +562,7 @@ struct WaveletParamsEdited { bool bllev; bool edgcont; bool chrwav; - bool softwav; + bool bluwav; bool level0noise; bool level1noise; bool level2noise; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 5ad6fda55..be7c74015 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -89,6 +89,7 @@ Wavelet::Wavelet() : 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))), + bluwav(Gtk::manage(new Adjuster(M("TP_WAVELET_BLUWAV"), 0.0, 100.0, 0.5, 50.))), 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))), @@ -132,7 +133,6 @@ Wavelet::Wavelet() : softrad(Gtk::manage(new Adjuster(M("TP_WAVELET_SOFTRAD"), 0.0, 100., 0.5, 0.))), softradend(Gtk::manage(new Adjuster(M("TP_WAVELET_SOFTRAD"), 0.0, 100., 0.5, 0.))), chrwav(Gtk::manage(new Adjuster(M("TP_WAVELET_CHRWAV"), 0., 100., 0., 0.))), - softwav(Gtk::manage(new Adjuster(M("TP_WAVELET_SOFWAV"), -10.0, 1000.0, 0.5, 1.))), Lmethod(Gtk::manage(new MyComboBoxText())), CHmethod(Gtk::manage(new MyComboBoxText())), CHSLmethod(Gtk::manage(new MyComboBoxText())), @@ -190,7 +190,7 @@ Wavelet::Wavelet() : EvWavchrwav = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_chrwav"); EvWavoldsh = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVOLDSH"); EvWavoffset = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVOFFSET"); - EvWavsoftwav = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_SOFTWAV"); + EvWavbluwav = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLUWAV"); EvWavblshape = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLSHAPE"); EvWavresblur = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLURWAV"); EvWavresblurc = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLURCWAV"); @@ -663,15 +663,14 @@ Wavelet::Wavelet() : curveEditorbl->curveListComplete(); curveEditorbl->show(); + blBox->pack_start(*bluwav); + bluwav->setAdjusterListener(this); blBox->pack_start(*curveEditorbl, Gtk::PACK_SHRINK, 4); chrwav->setAdjusterListener(this); blBox->pack_start(*chrwav); - softwav->setLogScale(10, -10); - softwav->setAdjusterListener(this); -// blBox->pack_start(*softwav); // Gamut @@ -1357,7 +1356,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) satlev->setValue(pp->wavelet.satlev); edgcont->setValue(pp->wavelet.edgcont); chrwav->setValue(pp->wavelet.chrwav); - softwav->setValue(pp->wavelet.softwav); + bluwav->setValue(pp->wavelet.bluwav); greenlow->setValue(pp->wavelet.greenlow); bluelow->setValue(pp->wavelet.bluelow); @@ -1536,7 +1535,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) strength->setEditedState(pedited->wavelet.strength ? Edited : UnEdited); edgcont->setEditedState(pedited->wavelet.edgcont ? Edited : UnEdited); chrwav->setEditedState(pedited->wavelet.chrwav ? Edited : UnEdited); - softwav->setEditedState(pedited->wavelet.softwav ? Edited : UnEdited); + bluwav->setEditedState(pedited->wavelet.bluwav ? Edited : UnEdited); level0noise->setEditedState(pedited->wavelet.level0noise ? Edited : UnEdited); level1noise->setEditedState(pedited->wavelet.level1noise ? Edited : UnEdited); level2noise->setEditedState(pedited->wavelet.level2noise ? Edited : UnEdited); @@ -1712,7 +1711,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pp->wavelet.bllev = bllev->getValue (); pp->wavelet.edgcont = edgcont->getValue (); pp->wavelet.chrwav = chrwav->getValue(); - pp->wavelet.softwav = softwav->getValue(); + pp->wavelet.bluwav = bluwav->getValue(); pp->wavelet.level0noise = level0noise->getValue (); pp->wavelet.level1noise = level1noise->getValue (); pp->wavelet.level2noise = level2noise->getValue (); @@ -1825,7 +1824,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.blcurve = !blshape->isUnChanged(); pedited->wavelet.edgcont = edgcont->getEditedState(); pedited->wavelet.chrwav = chrwav->getEditedState(); - pedited->wavelet.softwav = softwav->getEditedState(); + pedited->wavelet.bluwav = bluwav->getEditedState(); pedited->wavelet.level0noise = level0noise->getEditedState(); pedited->wavelet.level1noise = level1noise->getEditedState(); pedited->wavelet.level2noise = level2noise->getEditedState(); @@ -2070,7 +2069,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit satlev->setDefault (defParams->wavelet.satlev); edgcont->setDefault (defParams->wavelet.edgcont); chrwav->setDefault(defParams->wavelet.chrwav); - softwav->setDefault(defParams->wavelet.softwav); + bluwav->setDefault(defParams->wavelet.bluwav); level0noise->setDefault (defParams->wavelet.level0noise); level1noise->setDefault (defParams->wavelet.level1noise); level2noise->setDefault (defParams->wavelet.level2noise); @@ -2138,7 +2137,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit satlev->setDefaultEditedState(pedited->wavelet.satlev ? Edited : UnEdited); edgcont->setDefaultEditedState(pedited->wavelet.edgcont ? Edited : UnEdited); chrwav->setDefaultEditedState(pedited->wavelet.chrwav ? Edited : UnEdited); - softwav->setDefaultEditedState(pedited->wavelet.softwav ? Edited : UnEdited); + bluwav->setDefaultEditedState(pedited->wavelet.bluwav ? Edited : UnEdited); strength->setDefaultEditedState(pedited->wavelet.strength ? Edited : UnEdited); balance->setDefaultEditedState(pedited->wavelet.balance ? Edited : UnEdited); iter->setDefaultEditedState(pedited->wavelet.iter ? Edited : UnEdited); @@ -2192,7 +2191,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit bllev->setDefaultEditedState(Irrelevant); edgcont->setDefaultEditedState(Irrelevant); chrwav->setDefaultEditedState(Irrelevant); - softwav->setDefaultEditedState(Irrelevant); + bluwav->setDefaultEditedState(Irrelevant); level0noise->setDefaultEditedState(Irrelevant); level1noise->setDefaultEditedState(Irrelevant); level2noise->setDefaultEditedState(Irrelevant); @@ -2728,7 +2727,7 @@ void Wavelet::setBatchMode(bool batchMode) satlev->showEditedCB(); edgcont->showEditedCB(); chrwav->showEditedCB(); - softwav->showEditedCB(); + bluwav->showEditedCB(); strength->showEditedCB(); balance->showEditedCB(); iter->showEditedCB(); @@ -2899,8 +2898,8 @@ void Wavelet::adjusterChanged(Adjuster* a, double newval) listener->panelChanged(EvWavbluelow, bluelow->getTextValue()); } else if (a == chrwav) { listener->panelChanged(EvWavchrwav, chrwav->getTextValue()); - } else if (a == softwav) { - listener->panelChanged(EvWavsoftwav, softwav->getTextValue()); + } else if (a == bluwav) { + listener->panelChanged(EvWavbluwav, bluwav->getTextValue()); } if ((a == correction[0] || a == correction[1] || a == correction[2] || a == correction[3] || a == correction[4] || a == correction[5] || a == correction[6] || a == correction[7] || a == correction[8])) { diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index 635d8c7a7..67a45b5ac 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -83,7 +83,7 @@ private: rtengine::ProcEvent EvWavchrwav; rtengine::ProcEvent EvWavoldsh; rtengine::ProcEvent EvWavoffset; - rtengine::ProcEvent EvWavsoftwav; + rtengine::ProcEvent EvWavbluwav; rtengine::ProcEvent EvWavblshape; rtengine::ProcEvent EvWavresblur; rtengine::ProcEvent EvWavresblurc; @@ -189,6 +189,7 @@ private: Adjuster* const reschro; Adjuster* const resblur; Adjuster* const resblurc; + Adjuster* const bluwav; Adjuster* const tmrs; Adjuster* const edgs; Adjuster* const scale; @@ -241,7 +242,6 @@ private: Adjuster* const softrad; Adjuster* const softradend; Adjuster* const chrwav; - Adjuster* const softwav; MyComboBoxText* const Lmethod; sigc::connection Lmethodconn; From fcc6306f9ea54dfadb5da6309f3b3d4aaf7e5666 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sat, 28 Mar 2020 14:28:08 +0100 Subject: [PATCH 11/16] dcraw_matrix for FUJIFILM X100V --- rtengine/camconst.json | 1 + 1 file changed, 1 insertion(+) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 44e01ea99..73699b632 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1297,6 +1297,7 @@ Camera constants: { // Quality C "make_model": [ "FUJIFILM X100V" ], + "dcraw_matrix": [ 13426,-6334,-1177,-4244,12136,2371,-580,1303,5980 ], // DNG_v12.2 D65 "raw_crop": [ 0, 5, 6252, 4140 ] }, From 15204fa9bd4cee1a77e1b408245bbb08912f38ac Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sat, 28 Mar 2020 16:34:10 +0100 Subject: [PATCH 12/16] dcraw_matrix for FUJIFILM X-T4 --- rtengine/camconst.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 73699b632..8bed22437 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1296,7 +1296,7 @@ Camera constants: }, { // Quality C - "make_model": [ "FUJIFILM X100V" ], + "make_model": [ "FUJIFILM X100V", "FUJIFILM X-T4" ], "dcraw_matrix": [ 13426,-6334,-1177,-4244,12136,2371,-580,1303,5980 ], // DNG_v12.2 D65 "raw_crop": [ 0, 5, 6252, 4140 ] }, @@ -1389,11 +1389,6 @@ Camera constants: "raw_crop": [ 0, 5, 6252, 4176] }, - { // Quality C, only raw crop - "make_model": [ "FUJIFILM X-T4" ], - "raw_crop": [ 0, 5, 6252, 4140] - }, - { // Quality B "make_model": "FUJIFILM X30", "dcraw_matrix": [ 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 ], // DNG_v8.7 D65 From 7d333198937102dbf6c7e437ecf9368b9d28eedd Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 29 Mar 2020 08:00:48 +0200 Subject: [PATCH 13/16] small change to blur - change label and tooltip --- rtdata/languages/default | 6 +++--- rtengine/ipwavelet.cc | 15 +++++++++++---- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index a46f09a88..d4fb356e0 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2278,8 +2278,8 @@ TP_WAVELET_SETTINGS;Wavelet Settings TP_WAVELET_SHA;Sharp mask TP_WAVELET_SHFRAME;Shadows/Highlights TP_WAVELET_SHOWMASK;Show wavelet 'mask' -TP_WAVELET_SIGMA;Sigma -TP_WAVELET_SIGMA_TOOLTIP;Sigma acts on the relative amplitude of the signal width. The higher it is, the more the effect will be maximum and the more the unsightly effects will appear.\nLow values are recommended for creating tone-mapping in conjonction with usage Shadows/Highlights below +TP_WAVELET_SIGMA;Effects +TP_WAVELET_SIGMA_TOOLTIP;This slider controls how wide the range of contrast values are that receive the maximum effect from the tool.\n The higher it is, the more contrast values will be strongly modified and the higher the risk to generate artifacts. The lower it is, the more pinpoint will the effect be applied to a certain range of contrast values TP_WAVELET_SKIN;Skin targetting/protection TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. TP_WAVELET_SKY;Sky targetting/protection @@ -2313,7 +2313,7 @@ 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 TP_WAVELET_USH_TOOLTIP;If you select Sharp-mask, wavelet settings will be automatically positioned :\nBackground=black, Process=below, level=3...you can change level between 1 and 4.\n\nIf you select Clarity, wavelet settings will be automatically positioned :\nBackground=residual, Process=above, level=7..you can change level between 5 and 10 and wavelet levels. TP_WAVELET_WAVOFFSET;Offset -TP_WAVELET_OFFSET_TOOLTIP;Offset modifies the balance between shadows and highlights.\n High values will amplify the contrast increase of the highlights, while low values will amplify the contrast increase of the shadows. +TP_WAVELET_OFFSET_TOOLTIP;Offset modifies the balance between shadows and highlights.\n High values will amplify the contrast enhancement of the highlights, while low values will amplify the contrast enhancement of the shadows. Along with a low Max. effect value will help you selecting the contrasts that will be enhanced TP_WBALANCE_AUTO;Auto TP_WBALANCE_AUTOITCGREEN;Auto iterate temperature correlation TP_WBALANCE_AUTOOLD;Auto RGB grey diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 99b915c65..125808336 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -1951,7 +1951,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); ContAllL(koeLi, maxkoeLi, true, maxlvl, labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili); - //blur levels + //blur level float klev = 1.f; if(wavblcurve && wavcurvecomp && cp.blena && cp.bluwav > 0.f) { @@ -1962,8 +1962,11 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * bef[co] = WavCoeffs_L[dir][co]; } klev = (wavblcurve[lvl * 55.5f]); - - klev *= cp.bluwav * lvl * 15.f / skip; + float lvr = lvl; + if(lvr == 0) { + lvr = 1; + } + klev *= cp.bluwav * lvr * 10.f / skip; boxblur(bef, aft, klev, Wlvl_L, Hlvl_L, false); for (int co = 0; co < Hlvl_L * Wlvl_L; co++) { @@ -2224,8 +2227,12 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float bef[co] = WavCoeffs_ab[dir][co]; } klev = (wavblcurve[lvl * 55.5f]); + float lvr = lvl; + if(lvr == 0) { + lvr = 1; + } - klev *= cp.bluwav * cp.chrwav * lvl * 25.f / skip; + klev *= cp.bluwav * cp.chrwav * lvr * 20.f / skip; boxblur(bef, aft, klev, Wlvl_ab, Hlvl_ab, false); From 3f6ab0622227249f2c7b030d418a7f766f2dbfd4 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 29 Mar 2020 10:29:40 +0200 Subject: [PATCH 14/16] Change threshold from 5 to 32.7 in aver and sigma --- rtengine/ipwavelet.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 125808336..8c15f51c5 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -851,7 +851,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if (cp.val > 0 || ref || contr) { //edge Evaluate2(*Ldecomp, mean, meanN, sigma, sigmaN, MaxP, MaxN); } - + //init for edge and denoise float vari[4]; @@ -1234,7 +1234,7 @@ void ImProcFunctions::Aver(float * RESTRICT DataList, int datalen, float &averag int countP = 0, countN = 0; double averaP = 0.0, averaN = 0.0; // use double precision for large summations - constexpr float thres = 5.f;//different fom zero to take into account only data large enough + constexpr float thres = 32.7f;//different fom zero to take into account only data large enough 32.7 = 0.1 in range 0..100 very low value max = 0.f; min = RT_INFINITY_F; #ifdef _OPENMP @@ -1286,7 +1286,7 @@ void ImProcFunctions::Sigma(float * RESTRICT DataList, int datalen, float avera { int countP = 0, countN = 0; double variP = 0.0, variN = 0.0; // use double precision for large summations - float thres = 5.f;//different fom zero to take into account only data large enough + float thres = 32.7f;//different fom zero to take into account only data large enough 32.7 = 0.1 in range 0..100 #ifdef _OPENMP #pragma omp parallel for reduction(+:variP,variN,countP,countN) num_threads(wavNestedLevels) if(wavNestedLevels>1) @@ -2580,6 +2580,10 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz scaleskip[sc] = scales[sc] / skip; } + if (settings->verbose) { + printf("level=%i mean=%f sigma=%f maxp=%f\n", level, mean[level], sigma[level], MaxP[level]); + } + constexpr float t_r = 40.f; constexpr float t_l = 10.f; constexpr float b_r = 75.f; From bdb7409d11a77b164f3a42e7fb18fdb93436094d Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 29 Mar 2020 13:29:37 +0200 Subject: [PATCH 15/16] Change extra slider in GUI --- rtgui/wavelet.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index be7c74015..2e444ff3d 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -348,6 +348,10 @@ Wavelet::Wavelet() : correction[i]->setAdjusterListener(this); levBox->pack_start(*correction[i]); } + levBox->pack_start(*sup); + sup->setAdjusterListener(this); + Gtk::HSeparator* const separatorcont = Gtk::manage(new Gtk::HSeparator()); + levBox->pack_start(*separatorcont); sigma->setAdjusterListener(this); levBox->pack_start(*sigma, Gtk::PACK_SHRINK); @@ -356,8 +360,6 @@ Wavelet::Wavelet() : sigma->set_tooltip_text(M("TP_WAVELET_SIGMA_TOOLTIP")); offset->set_tooltip_text(M("TP_WAVELET_OFFSET_TOOLTIP")); - levBox->pack_start(*sup); - sup->setAdjusterListener(this); wavLabels->show(); levBox->pack_start(*wavLabels); From bae1897b444b805a27be94745ff01fdbfed21014 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 29 Mar 2020 17:42:48 +0200 Subject: [PATCH 16/16] Fix segfault when using Colour Toning/Lab blending on very dark images --- rtengine/improcfun.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 9fe16769c..aa5515e79 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -1989,8 +1989,8 @@ void ImProcFunctions::moyeqt (Imagefloat* working, float &moyS, float &eqty) { BENCHFUN - int tHh = working->getHeight(); - int tWw = working->getWidth(); + const int height = working->getHeight(); + const int width = working->getWidth(); double moy = 0.0; double sqrs = 0.0; @@ -1998,17 +1998,17 @@ void ImProcFunctions::moyeqt (Imagefloat* working, float &moyS, float &eqty) #pragma omp parallel for reduction(+:moy,sqrs) schedule(dynamic,16) #endif - for (int i = 0; i < tHh; i++) { - for (int j = 0; j < tWw; j++) { - double s = Color::rgb2s (CLIP (working->r (i, j)), CLIP (working->g (i, j)), CLIP (working->b (i, j))); + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + const double s = Color::rgb2s(CLIP(working->r (i, j)), CLIP(working->g (i, j)), CLIP(working->b (i, j))); moy += s; sqrs += SQR(s); } } - moy /= (tHh * tWw); - sqrs /= (tHh * tWw); - eqty = sqrt (sqrs - SQR (moy)); + moy /= (height * width); + sqrs /= (height * width); + eqty = std::sqrt(std::max(sqrs - SQR(moy), 0.0)); moyS = moy; }