diff --git a/rtdata/languages/default b/rtdata/languages/default
index 5f8906b3d..69b7449e3 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -567,10 +567,10 @@ HISTORY_MSG_314;W - Gamut - Reduce artifacts
HISTORY_MSG_315;W - Residual - Contrast
HISTORY_MSG_316;W - Gamut - Skin tar/prot
HISTORY_MSG_317;W - Gamut - Skin hue
-HISTORY_MSG_318;W - Contrast - Highlight levels
-HISTORY_MSG_319;W - Contrast - Highlight range
-HISTORY_MSG_320;W - Contrast - Shadow range
-HISTORY_MSG_321;W - Contrast - Shadow levels
+HISTORY_MSG_318;W - Contrast - Fine levels
+HISTORY_MSG_319;W - Contrast - Fine range
+HISTORY_MSG_320;W - Contrast - Coarse range
+HISTORY_MSG_321;W - Contrast - Coarse levels
HISTORY_MSG_322;W - Gamut - Avoid color shift
HISTORY_MSG_323;W - ES - Local contrast
HISTORY_MSG_324;W - Chroma - Pastel
@@ -2193,6 +2193,7 @@ TP_WAVELET_CONTEDIT;'After' contrast curve
TP_WAVELET_CONTFRAME;Contrast - Compression
TP_WAVELET_CONTR;Gamut
TP_WAVELET_CONTRA;Contrast
+TP_WAVELET_CONTRASTEDIT;Finer - Coarser levels
TP_WAVELET_CONTRAST_MINUS;Contrast -
TP_WAVELET_CONTRAST_PLUS;Contrast +
TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image.
@@ -2240,9 +2241,10 @@ TP_WAVELET_EDVAL;Strength
TP_WAVELET_FINAL;Final Touchup
TP_WAVELET_FINCFRAME;Final Local Contrast
TP_WAVELET_FINEST;Finest
-TP_WAVELET_HIGHLIGHT;Highlight luminance range
+TP_WAVELET_HIGHLIGHT;Finer levels luminance range
+TP_WAVELET_FINCOAR_TOOLTIP;The left (positive) part of the curve acts on the finer levels (increase).\nThe 2 points on the abscissa represent the respective action limits of finer and coarser levels 5 and 6 (default).\nThe right (negative) part of the curve acts on the coarser levels (increase).\nAvoid moving the left part of the curve with negative values. Avoid moving the right part of the curve with positives values
TP_WAVELET_HS1;Whole luminance range
-TP_WAVELET_HS2;Shadows/Highlights
+TP_WAVELET_HS2;Selective luminance range
TP_WAVELET_HUESKIN;Skin hue
TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect.
TP_WAVELET_HUESKY;Sky hue
@@ -2252,8 +2254,8 @@ TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight
TP_WAVELET_LABEL;Wavelet Levels
TP_WAVELET_LARGEST;Coarsest
TP_WAVELET_LEVCH;Chroma
-TP_WAVELET_LEVDIR_ALL;All levels in all directions
-TP_WAVELET_LEVDIR_INF;Below or equal the level
+TP_WAVELET_LEVDIR_ALL;All levels, in all directions
+TP_WAVELET_LEVDIR_INF;Finer details levels, with selected level
TP_WAVELET_LEVDIR_ONE;One level
TP_WAVELET_LEVDIR_SUP;Above the level
TP_WAVELET_LEVELS;Wavelet levels
@@ -2266,7 +2268,7 @@ TP_WAVELET_LEVTWO;Level 3
TP_WAVELET_LEVZERO;Level 1
TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength
TP_WAVELET_LIPST;Enhanced algoritm
-TP_WAVELET_LOWLIGHT;Shadow luminance range
+TP_WAVELET_LOWLIGHT;Coarser levels luminance range
TP_WAVELET_LOWTHR_TOOLTIP;Prevents amplification of fine textures and noise
TP_WAVELET_MEDGREINF;First level
TP_WAVELET_MEDI;Reduce artifacts in blue sky
@@ -2277,6 +2279,7 @@ TP_WAVELET_MERGEL;Merge Luma
TP_WAVELET_NEUTRAL;Neutral
TP_WAVELET_NOIS;Denoise
TP_WAVELET_NOISE;Denoise and Refine
+TP_WAVELET_NOISE_TOOLTIP;If level 4 luminance denoise superior to 20, mode Agressive is used.\nIf chrominance coarse superior to 20, mode Agressive is used.
TP_WAVELET_NPHIGH;High
TP_WAVELET_NPLOW;Low
TP_WAVELET_NPNONE;None
@@ -2318,11 +2321,12 @@ TP_WAVELET_SOFTRAD;Soft Radius
TP_WAVELET_STREN;Strength
TP_WAVELET_STRENGTH;Strength
TP_WAVELET_SUPE;Extra
-TP_WAVELET_THR;Shadows threshold
-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_THRESHOLD;Finer levels
+TP_WAVELET_THRESHOLD2;Coarser 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_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. : All levels from level 1 up to the chosen value will only be affected within the Finer levels luminance range.\nAll other levels will have the whole range of luminances affected, unless the Coarser levels setting limits it.\nThe chosen value in this slider becomes the minimum possible value of the Coarser 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). : Only levels between the chosen value and level 9/Extra will be affected by the Coarser levels luminance range.\nAll other levels will have the whole range of luminances affected, unless the Finer levels setting limits it.\nThe lower level possible that will be considered by the algorithm is limited by the Finer levels value.
TP_WAVELET_THRESWAV;Balance Threshold
TP_WAVELET_THRH;Highlights threshold
TP_WAVELET_TILESBIG;Tiles
diff --git a/rtengine/curves.cc b/rtengine/curves.cc
index 14711c730..ebb23e754 100644
--- a/rtengine/curves.cc
+++ b/rtengine/curves.cc
@@ -1278,6 +1278,43 @@ void WavOpacityCurveRG::Set(const std::vector &curvePoints)
}
+WavOpacityCurveSH::WavOpacityCurveSH() {}
+
+void WavOpacityCurveSH::Reset()
+{
+ lutOpacityCurveSH.reset();
+}
+
+void WavOpacityCurveSH::Set(const Curve &pCurve)
+{
+ if (pCurve.isIdentity()) {
+ Reset(); // raise this value if the quality suffers from this number of samples
+ return;
+ }
+
+ lutOpacityCurveSH(501); // raise this value if the quality suffers from this number of samples
+
+ for (int i = 0; i < 501; i++) {
+ lutOpacityCurveSH[i] = pCurve.getVal(double(i) / 500.);
+ }
+}
+
+void WavOpacityCurveSH::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();
+ }
+
+}
+
+
+
+
+
WavOpacityCurveBY::WavOpacityCurveBY() {}
void WavOpacityCurveBY::Reset()
diff --git a/rtengine/curves.h b/rtengine/curves.h
index 03fa3e812..0fb58cc9e 100644
--- a/rtengine/curves.h
+++ b/rtengine/curves.h
@@ -673,6 +673,32 @@ public:
return lutOpacityCurveRG;
}
};
+
+class WavOpacityCurveSH
+{
+private:
+ LUTf lutOpacityCurveSH; // 0xffff range
+ void Set(const Curve &pCurve);
+public:
+ virtual ~WavOpacityCurveSH() {};
+ WavOpacityCurveSH();
+
+ void Reset();
+ // void Set(const std::vector &curvePoints, bool &opautili);
+ void Set(const std::vector &curvePoints);
+ float operator[](float index) const
+ {
+ return lutOpacityCurveSH[index];
+ }
+
+ operator bool (void) const
+ {
+ return lutOpacityCurveSH;
+ }
+};
+
+
+
class WavOpacityCurveBY
{
private:
diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc
index 11bf19edf..f58f2e4c9 100644
--- a/rtengine/dcrop.cc
+++ b/rtengine/dcrop.cc
@@ -969,12 +969,13 @@ void Crop::update(int todo)
WavCurve wavCLVCurve;
Wavblcurve wavblcurve;
WavOpacityCurveRG waOpacityCurveRG;
+ WavOpacityCurveSH waOpacityCurveSH;
WavOpacityCurveBY waOpacityCurveBY;
WavOpacityCurveW waOpacityCurveW;
WavOpacityCurveWL waOpacityCurveWL;
LUTf wavclCurve;
- params.wavelet.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL);
+ params.wavelet.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL);
LabImage *unshar = nullptr;
Glib::ustring provis;
LabImage *provradius = nullptr;
@@ -1003,7 +1004,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, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip);
+ parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip);
unshar->CopyFrom(labnCrop);
params.wavelet.CLmethod = provis;
@@ -1016,7 +1017,8 @@ void Crop::update(int todo)
WaveParams.expnoise = false;
}
- parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip);
+ // parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip);
+ parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, 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 f68616b96..f7f8756d2 100644
--- a/rtengine/improccoordinator.cc
+++ b/rtengine/improccoordinator.cc
@@ -891,7 +891,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
if ((params->wavelet.enabled)) {
WaveletParams WaveParams = params->wavelet;
- WaveParams.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL);
+// WaveParams.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL);
+ WaveParams.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL);
int kall = 0;
LabImage *unshar = nullptr;
Glib::ustring provis;
@@ -920,7 +921,8 @@ 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, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale);
+ ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale);
+// ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale);
unshar->CopyFrom(nprevl);
@@ -934,7 +936,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
WaveParams.expnoise = false;
}
- ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale);
+// ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale);
+ ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale);
if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") {
diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h
index e17d88183..e4858c76b 100644
--- a/rtengine/improccoordinator.h
+++ b/rtengine/improccoordinator.h
@@ -141,6 +141,7 @@ protected:
WavCurve wavCLVCurve;
Wavblcurve wavblcurve;
WavOpacityCurveRG waOpacityCurveRG;
+ WavOpacityCurveSH waOpacityCurveSH;
WavOpacityCurveBY waOpacityCurveBY;
WavOpacityCurveW waOpacityCurveW;
WavOpacityCurveWL waOpacityCurveWL;
diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h
index b2df86112..f4a452dcc 100644
--- a/rtengine/improcfun.h
+++ b/rtengine/improcfun.h
@@ -55,6 +55,7 @@ class ToneCurve;
class WavCurve;
class Wavblcurve;
class WavOpacityCurveBY;
+class WavOpacityCurveSH;
class WavOpacityCurveRG;
class WavOpacityCurveW;
class WavOpacityCurveWL;
@@ -201,19 +202,22 @@ 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 Wavblcurve & wavblcurve, 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 Wavblcurve & wavblcurve, 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 Wavblcurve & wavblcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveSH & waOpacityCurveSH, 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, 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);
+// struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili);
+ struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveSH & waOpacityCurveSH, 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 Wavblcurve & wavblcurve, const WavOpacityCurveW & waOpacityCurveW,
struct cont_params &cp, const bool useChannelA, int skip, float *meanab, float *sigmaab);
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,
- int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili);
- void finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, const cont_params &cp,
- int W_L, int H_L, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL);
+ // int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili);
+ int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveSH & waOpacityCurveSH, FlatCurve* ChCurve, bool Chutili);
+ void finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, const cont_params &cp,
+ int W_L, int H_L, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL);
void ContAllAB(LabImage * lab, int maxlvl, float **varhue, float **varchrom, float ** WavCoeffs_a, float * WavCoeffs_a0, int level, int dir, const WavOpacityCurveW & waOpacityCurveW, struct cont_params &cp,
int W_ab, int H_ab, const bool useChannelA, float *meanab, float *sigmaab);
void Evaluate2(const wavelet_decomposition &WaveletCoeffs_L,
diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc
index 445cfdd06..373ea6ef0 100644
--- a/rtengine/ipwavelet.cc
+++ b/rtengine/ipwavelet.cc
@@ -164,7 +164,8 @@ struct cont_params {
int wavNestedLevels = 1;
-void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const Wavblcurve & wavblcurve, 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 Wavblcurve & wavblcurve, 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 Wavblcurve & wavblcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveSH & waOpacityCurveSH, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, const LUTf &wavclCurve, int skip)
{
@@ -469,9 +470,12 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
cp.t_lsl = static_cast(params->wavelet.bllev.getTopLeft());
cp.b_rsl = static_cast(params->wavelet.bllev.getBottomRight());
cp.t_rsl = static_cast(params->wavelet.bllev.getTopRight());
- cp.numlevS = params->wavelet.threshold2;
- int maxlevS = 9 - cp.numlevH;
- cp.numlevS = rtengine::min(cp.numlevS, maxlevS);
+// cp.numlevS = params->wavelet.threshold2;
+// int maxlevS = 9 - cp.numlevH;
+// cp.numlevS = rtengine::min(cp.numlevS, maxlevS);
+ cp.numlevS = 9 - params->wavelet.threshold2;
+ int maxlevS = cp.numlevH;
+ cp.numlevS = rtengine::max(cp.numlevS, maxlevS);
//highlight
cp.b_lhl = static_cast(params->wavelet.hllev.getBottomLeft());
cp.t_lhl = static_cast(params->wavelet.hllev.getTopLeft());
@@ -958,7 +962,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
}
if ((cp.lev0n > 0.1f || cp.lev1n > 0.1f || cp.lev2n > 0.1f || cp.lev3n > 0.1f) && cp.noiseena) {
- int edge = 4;
+ int edge = 1;
vari[0] = rtengine::max(0.000001f, vari[0]);
vari[1] = rtengine::max(0.000001f, vari[1]);
vari[2] = rtengine::max(0.000001f, vari[2]);
@@ -1001,7 +1005,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
}
}
- if (cp.lev3n < 0.5f) {
+ if (cp.lev3n < 20.f) {
WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, vari, edge, 1);
} else {
WaveletDenoiseAll_BiShrinkL(*Ldecomp, noisevarlum, madL, vari, edge, 1);
@@ -1023,7 +1027,8 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
Chutili = true;
}
- WaveletcontAllL(labco, varhue, varchro, *Ldecomp, wavblcurve, cp, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili);
+// WaveletcontAllL(labco, varhue, varchro, *Ldecomp, wavblcurve, cp, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili);
+ WaveletcontAllL(labco, varhue, varchro, *Ldecomp, wavblcurve, cp, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, waOpacityCurveSH, ChCurve, Chutili);
if (cp.val > 0 || ref || contr || cp.diagcurv) { //edge
Evaluate2(*Ldecomp, mean, meanN, sigma, sigmaN, MaxP, MaxN);
@@ -1048,16 +1053,16 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
float noiseccr = cp.chromco;
if (cp.balchrom > 0.f) {
- noisecfr = cp.chromfi * ((100.f + cp.balchrom) / 10.f);
- noiseccr = cp.chromco + ((100.f + cp.balchrom) / 10.f);
+ noisecfr = cp.chromfi + 0.1f * cp.balchrom;
+ noiseccr = cp.chromco + 0.1f * cp.balchrom;
}
float noisecfb = cp.chromfi;
float noiseccb = cp.chromco;
if (cp.balchrom < 0.f) {
- noisecfb = cp.chromfi * ((100.f - cp.balchrom) / 10.f);
- noiseccb = cp.chromco * ((100.f - cp.balchrom) / 10.f);
+ noisecfb = cp.chromfi - 0.1f * cp.balchrom;
+ noiseccb = cp.chromco - 0.1f * cp.balchrom;
}
@@ -1292,7 +1297,11 @@ 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) {
- if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) {
+// if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) {
+ if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.chromco < 2.f )) {
+ WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1);
+ } else if (cp.chromfi > 0.f && cp.chromco >= 2.f){
+
WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1);
WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1);
}
@@ -1326,7 +1335,10 @@ 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) {
- if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) {
+// if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) {
+ if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.chromco < 2.f )) {
+ WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1);
+ } else if (cp.chromfi > 0.f && cp.chromco >= 2.f){
WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1);
WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1);
}
@@ -1356,21 +1368,34 @@ 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) {
- if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) {
+// if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) {
+ if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.chromco < 2.f)) {
+ WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1);
+ } else if (cp.chromfi > 0.f && cp.chromco >= 2.f){
WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1);
WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1);
}
Evaluate2(*adecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab);
WaveletcontAllAB(labco, varhue, varchro, *adecomp, wavblcurve, waOpacityCurveW, cp, true, skip, meanab, sigmaab);
- WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1);
- WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1);
- Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab);
+ if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.chromco < 2.f)) {
+ WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1);
+ } else if (cp.chromfi > 0.f && cp.chromco >= 2.f){
+ WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1);
+ WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1);
+ }
+// WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1);
+// WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1);
+ Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab);
+/*
if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) {
WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab);
WaveletAandBAllAB(*adecomp, *bdecomp, cp, hhCurve, hhutili);
}
+ */
+ WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab);
+ WaveletAandBAllAB(*adecomp, *bdecomp, cp, hhCurve, hhutili);
adecomp->reconstruct(labco->data + datalen, cp.strength);
bdecomp->reconstruct(labco->data + 2 * datalen, cp.strength);
@@ -2022,7 +2047,8 @@ void ImProcFunctions::WaveletcontAllLfinal(const wavelet_decomposition &WaveletC
void ImProcFunctions::WaveletcontAllL(LabImage * labco, 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)
+// struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili)
+ struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveSH & waOpacityCurveSH, FlatCurve* ChCurve, bool Chutili)
{
const int maxlvl = WaveletCoeffs_L.maxlevel();
const int W_L = WaveletCoeffs_L.level_W(0);
@@ -2422,7 +2448,8 @@ 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);
+// 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);
+ 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, waOpacityCurveSH, ChCurve, Chutili);
if (wavblcurve && wavcurvecomp && cp.blena) {
// printf("Blur level L\n");
@@ -3106,7 +3133,8 @@ void ImProcFunctions::finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0,
}
void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz, int maxlvl, LabImage * labco, float ** varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp,
- int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili)
+// int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili)
+ int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveSH & waOpacityCurveSH, FlatCurve* ChCurve, bool Chutili)
{
assert(level >= 0);
assert(maxlvl > level);
@@ -3605,7 +3633,8 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz
float red2 = 0.011f * (110.f - lowthr);
for (int i = 0; i < W_L * H_L; i++) {
- float kLlev = 1.f;
+ float kLlevH = 1.f;
+ float kLlevS = 1.f;
if (cpMul < 0.f) {
lbeta = 1.f; // disabled for negatives values "less contrast"
@@ -3697,7 +3726,8 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz
float diagacc = 1.f;
float alpha = (1024.f + 15.f * (float) cpMul * scale * scale2 * lbeta * diagacc) / 1024.f ;
- if (cp.HSmet && cp.contena) {
+ // if (cp.HSmet && cp.contena) {
+ if (cp.HSmet && cp.contena && waOpacityCurveSH) {
float aaal = (1.f - alpha) / ((cp.b_lhl - cp.t_lhl) * kH[level]);
float bbal = 1.f - aaal * cp.b_lhl * kH[level];
float aaar = (alpha - 1.f) / (cp.t_rhl - cp.b_rhl) * kH[level];
@@ -3708,35 +3738,40 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz
float aaarS = (alpha - 1.f) / (cp.t_rsl - cp.b_rsl);
float bbbrS = 1.f - cp.b_rsl * aaarS;
- if (level <= cp.numlevH) { //in function of levels
+// if (level <= cp.numlevH) { //in function of levels
+ float klevred = 2.f * (waOpacityCurveSH[level * 55.5f] - 0.5f);
+ if(klevred > 0.f && level <= 6) {// level < 6 to avoid bad use of the curve if user put negative values positives
if ((LL100 > cp.t_lhl * kH[level] && LL100 < cp.t_rhl * kH[level])) {
- kLlev = alpha;
+ kLlevH = alpha;
} else if ((LL100 > cp.b_lhl * kH[level] && LL100 <= cp.t_lhl * kH[level])) {
- kLlev = aaal * LL100 + bbal;
+ kLlevH = aaal * LL100 + bbal;
} else if ((LL100 > cp.t_rhl * kH[level] && LL100 <= cp.b_rhl * kH[level])) {
- kLlev = aaar * LL100 + bbbr;
+ kLlevH = aaar * LL100 + bbbr;
} else {
- kLlev = 1.f;
+ kLlevH = 1.f;
}
+ kLlevH = 1.f + (kLlevH - 1.f) * klevred;
}
- if (level >= (9 - cp.numlevS)) {
+ // if (level >= (9 - cp.numlevS)) {
+ if(klevred < 0.f && level >= 3) {//level > 3 to avoid bad use of the curve if user put positives values negatives
if ((LL100 > cp.t_lsl && LL100 < cp.t_rsl)) {
- kLlev = alpha;
+ kLlevS = alpha;
} else if ((LL100 > cp.b_lsl && LL100 <= cp.t_lsl)) {
- kLlev = aaalS * LL100 + bbalS;
+ kLlevS = aaalS * LL100 + bbalS;
} else if ((LL100 > cp.t_rsl && LL100 <= cp.b_rsl)) {
- kLlev = aaarS * LL100 + bbbrS;
+ kLlevS = aaarS * LL100 + bbbrS;
} else {
- kLlev = 1.f;
+ kLlevS = 1.f;
}
+ kLlevS = 1.f - (kLlevS - 1.f) * klevred;
}
} else {
- kLlev = alpha;
+ kLlevH = kLlevS = alpha;
}
- WavCoeffs_L[dir][i] *= (kLlev);
+ WavCoeffs_L[dir][i] *= (kLlevH * kLlevS);
}
}
diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc
index e1765a5f0..4df201503 100644
--- a/rtengine/procparams.cc
+++ b/rtengine/procparams.cc
@@ -2191,6 +2191,25 @@ WaveletParams::WaveletParams() :
0.35,
0.35
},
+ opacityCurveSH{
+ static_cast(FCT_MinMaxCPoints),
+ 0.0,
+ 1.,
+ 0.35,
+ 0.35,
+ 0.4,
+ 0.5,
+ 0.35,
+ 0.35,
+ 0.5,
+ 0.5,
+ 0.35,
+ 0.35,
+ 1.,
+ 0.,
+ 0.35,
+ 0.35
+ },
opacityCurveBY{
static_cast(FCT_MinMaxCPoints),
0.0,
@@ -2322,7 +2341,7 @@ WaveletParams::WaveletParams() :
chroma(5),
chro(0),
threshold(5),
- threshold2(4),
+ threshold2(5),
edgedetect(90),
edgedetectthr(20),
edgedetectthr2(0),
@@ -2359,6 +2378,7 @@ bool WaveletParams::operator ==(const WaveletParams& other) const
ccwcurve == other.ccwcurve
&& blcurve == other.blcurve
&& opacityCurveRG == other.opacityCurveRG
+ && opacityCurveSH == other.opacityCurveSH
&& opacityCurveBY == other.opacityCurveBY
&& opacityCurveW == other.opacityCurveW
&& opacityCurveWL == other.opacityCurveWL
@@ -2492,6 +2512,7 @@ void WaveletParams::getCurves(
WavCurve& cCurve,
Wavblcurve& tCurve,
WavOpacityCurveRG& opacityCurveLUTRG,
+ WavOpacityCurveSH& opacityCurveLUTSH,
WavOpacityCurveBY& opacityCurveLUTBY,
WavOpacityCurveW& opacityCurveLUTW,
WavOpacityCurveWL& opacityCurveLUTWL
@@ -2500,6 +2521,7 @@ void WaveletParams::getCurves(
cCurve.Set(this->ccwcurve);
tCurve.Set(this->blcurve);
opacityCurveLUTRG.Set(this->opacityCurveRG);
+ opacityCurveLUTSH.Set(this->opacityCurveSH);
opacityCurveLUTBY.Set(this->opacityCurveBY);
opacityCurveLUTW.Set(this->opacityCurveW);
opacityCurveLUTWL.Set(this->opacityCurveWL);
@@ -3631,6 +3653,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
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);
+ saveToKeyfile(!pedited || pedited->wavelet.opacityCurveSH, "Wavelet", "Levalshc", wavelet.opacityCurveSH, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.opacityCurveBY, "Wavelet", "OpacityCurveBY", wavelet.opacityCurveBY, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.opacityCurveW, "Wavelet", "OpacityCurveW", wavelet.opacityCurveW, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.opacityCurveWL, "Wavelet", "OpacityCurveWL", wavelet.opacityCurveWL, keyFile);
@@ -4830,6 +4853,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
assignFromKeyfile(keyFile, "Wavelet", "ContrastCurve", pedited, wavelet.ccwcurve, pedited->wavelet.ccwcurve);
assignFromKeyfile(keyFile, "Wavelet", "blcurve", pedited, wavelet.blcurve, pedited->wavelet.blcurve);
assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveRG", pedited, wavelet.opacityCurveRG, pedited->wavelet.opacityCurveRG);
+ assignFromKeyfile(keyFile, "Wavelet", "Levelshc", pedited, wavelet.opacityCurveSH, pedited->wavelet.opacityCurveSH);
assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveBY", pedited, wavelet.opacityCurveBY, pedited->wavelet.opacityCurveBY);
assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveW", pedited, wavelet.opacityCurveW, pedited->wavelet.opacityCurveW);
assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveWL", pedited, wavelet.opacityCurveWL, pedited->wavelet.opacityCurveWL);
diff --git a/rtengine/procparams.h b/rtengine/procparams.h
index 24995525d..8e3ff5b6c 100644
--- a/rtengine/procparams.h
+++ b/rtengine/procparams.h
@@ -42,6 +42,7 @@ class RetinextransmissionCurve;
class WavCurve;
class Wavblcurve;
class WavOpacityCurveBY;
+class WavOpacityCurveSH;
class WavOpacityCurveRG;
class WavOpacityCurveW;
class WavOpacityCurveWL;
@@ -1187,7 +1188,9 @@ private:
struct WaveletParams {
std::vector ccwcurve;
std::vector blcurve;
+ std::vector levelshc;
std::vector opacityCurveRG;
+ std::vector opacityCurveSH;
std::vector opacityCurveBY;
std::vector opacityCurveW;
std::vector opacityCurveWL;
@@ -1316,8 +1319,8 @@ struct WaveletParams {
void getCurves(
WavCurve& cCurve,
Wavblcurve& tCurve,
- WavOpacityCurveRG&
- opacityCurveLUTRG,
+ WavOpacityCurveRG& opacityCurveLUTRG,
+ WavOpacityCurveSH& opacityCurveLUTSH,
WavOpacityCurveBY& opacityCurveLUTBY,
WavOpacityCurveW& opacityCurveLUTW,
WavOpacityCurveWL& opacityCurveLUTWL
diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc
index 14a594ac2..92a3d7f29 100644
--- a/rtengine/simpleprocess.cc
+++ b/rtengine/simpleprocess.cc
@@ -1127,6 +1127,7 @@ private:
WavCurve wavCLVCurve;
Wavblcurve wavblcurve;
WavOpacityCurveRG waOpacityCurveRG;
+ WavOpacityCurveSH waOpacityCurveSH;
WavOpacityCurveBY waOpacityCurveBY;
WavOpacityCurveW waOpacityCurveW;
WavOpacityCurveWL waOpacityCurveWL;
@@ -1149,7 +1150,8 @@ private:
provradius->CopyFrom(labView);
}
- params.wavelet.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL);
+// params.wavelet.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL);
+ params.wavelet.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL);
CurveFactory::curveWavContL(wavcontlutili, params.wavelet.wavclCurve, wavclCurve,/* hist16C, dummy,*/ 1);
@@ -1157,7 +1159,8 @@ private:
unshar = new LabImage(fw, fh);
provis = params.wavelet.CLmethod;
params.wavelet.CLmethod = "all";
- ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1);
+// ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1);
+ ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1);
unshar->CopyFrom(labView);
params.wavelet.CLmethod = provis;
@@ -1169,7 +1172,8 @@ private:
WaveParams.expnoise = false;
}
- ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1);
+// ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1);
+ ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1);
if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") {
WaveParams.expcontrast = procont;
diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc
index 85119fe80..b9f7d4791 100644
--- a/rtgui/paramsedited.cc
+++ b/rtgui/paramsedited.cc
@@ -565,6 +565,7 @@ void ParamsEdited::set(bool v)
wavelet.level3noise = v;
wavelet.ccwcurve = v;
wavelet.blcurve = v;
+ wavelet.opacityCurveSH = v;
wavelet.opacityCurveRG = v;
wavelet.opacityCurveBY = v;
wavelet.opacityCurveW = v;
@@ -1187,6 +1188,7 @@ void ParamsEdited::initFrom(const std::vector&
wavelet.satlev = wavelet.satlev && p.wavelet.satlev == other.wavelet.satlev;
wavelet.ccwcurve = wavelet.ccwcurve && p.wavelet.ccwcurve == other.wavelet.ccwcurve;
wavelet.blcurve = wavelet.blcurve && p.wavelet.blcurve == other.wavelet.blcurve;
+ wavelet.opacityCurveSH = wavelet.opacityCurveSH && p.wavelet.opacityCurveSH == other.wavelet.opacityCurveSH;
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;
@@ -3189,6 +3191,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
toEdit.wavelet.blcurve = mods.wavelet.blcurve;
}
+ if (wavelet.opacityCurveSH) {
+ toEdit.wavelet.opacityCurveSH = mods.wavelet.opacityCurveSH;
+ }
+
if (wavelet.opacityCurveRG) {
toEdit.wavelet.opacityCurveRG = mods.wavelet.opacityCurveRG;
}
diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h
index 68340309d..6655bbcda 100644
--- a/rtgui/paramsedited.h
+++ b/rtgui/paramsedited.h
@@ -577,6 +577,7 @@ struct WaveletParamsEdited {
bool level3noise;
bool ccwcurve;
bool blcurve;
+ bool opacityCurveSH;
bool opacityCurveBY;
bool opacityCurveRG;
bool opacityCurveW;
diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc
index 1f4714452..53c7ef90b 100644
--- a/rtgui/wavelet.cc
+++ b/rtgui/wavelet.cc
@@ -63,6 +63,7 @@ std::vector makeWholeHueRange()
Wavelet::Wavelet() :
FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), true, true),
curveEditorG(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_CONTEDIT"))),
+ curveEditorC(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_CONTRASTEDIT"))),
CCWcurveEditorG(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_CCURVE"))),
curveEditorbl(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_BLCURVE"))),
curveEditorRES(new CurveEditorGroup(options.lastWaveletCurvesDir)),
@@ -131,7 +132,8 @@ Wavelet::Wavelet() :
level2noise(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_LEVTWO"), -30., 100., 0., M("TP_WAVELET_STREN"), 1., 0., 100., 0., M("TP_WAVELET_NOIS"), 1., nullptr, false))),
level3noise(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_LEVTHRE"), -30., 100., 0., M("TP_WAVELET_STREN"), 1., 0., 100., 0., M("TP_WAVELET_NOIS"), 1., nullptr, false))),
threshold(Gtk::manage(new Adjuster(M("TP_WAVELET_THRESHOLD"), 1, 9, 1, 5))),
- threshold2(Gtk::manage(new Adjuster(M("TP_WAVELET_THRESHOLD2"), 1, 9, 1, 4))),
+ // threshold2(Gtk::manage(new Adjuster(M("TP_WAVELET_THRESHOLD2"), 1, 9, 1, 4))),
+ threshold2(Gtk::manage(new Adjuster(M("TP_WAVELET_THRESHOLD2"), 1, 9, 1, 5))),
edgedetect(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGEDETECT"), 0, 100, 1, 90))),
edgedetectthr(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGEDETECTTHR"), 0, 100, 1, 20))),
edgedetectthr2(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGEDETECTTHR2"), -10, 100, 1, 0))),
@@ -224,6 +226,7 @@ Wavelet::Wavelet() :
EvWavLabGridValue = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVLABGRID_VALUE");
EvWavrangeab = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_RANGEAB");
EvWavprotab = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_PROTAB");
+ EvWavlevelshc = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_LEVELSHC");
labgrid = Gtk::manage(new LabGrid(EvWavLabGridValue, M("TP_WAVELET_LABGRID_VALUES")));
@@ -422,11 +425,25 @@ Wavelet::Wavelet() :
threshold2->setAdjusterListener(this);
threshold2->set_tooltip_text(M("TP_WAVELET_THRESHOLD2_TOOLTIP"));
+ const WaveletParams default_params;
+
+ curveEditorC->setCurveListener(this);
+ curveEditorC->set_tooltip_text(M("TP_WAVELET_FINCOAR_TOOLTIP"));
+
+
+ opacityShapeSH = static_cast(curveEditorC->addCurve(CT_Flat, "", nullptr, false, false));
+ opacityShapeSH->setIdentityValue(0.);
+ opacityShapeSH->setResetCurve(FlatCurveType(default_params.opacityCurveSH.at(0)), default_params.opacityCurveSH);
+
+ curveEditorC->curveListComplete();
+ curveEditorC->show();
+
contrastSHVBox->pack_start(*HSmethod);
contrastSHVBox->pack_start(*hllev);
- contrastSHVBox->pack_start(*threshold);
+ // contrastSHVBox->pack_start(*threshold);
contrastSHVBox->pack_start(*bllev);
- contrastSHVBox->pack_start(*threshold2);
+// contrastSHVBox->pack_start(*threshold2);
+ contrastSHVBox->pack_start(*curveEditorC);
Gtk::Frame* const contrastSHFrame = Gtk::manage(new Gtk::Frame(M("TP_WAVELET_APPLYTO")));
contrastSHFrame->add(*contrastSHVBox);
levBox->pack_start(*contrastSHFrame);
@@ -511,7 +528,7 @@ Wavelet::Wavelet() :
opaCurveEditorG->setCurveListener(this);
- const WaveletParams default_params;
+// const WaveletParams default_params;
opacityShapeRG = static_cast(opaCurveEditorG->addCurve(CT_Flat, "", nullptr, false, false));
opacityShapeRG->setIdentityValue(0.);
@@ -591,6 +608,7 @@ Wavelet::Wavelet() :
chroBox->pack_start(*chromco);
chroFrame->add(*chroBox);
noiseBox->pack_start(*chroFrame);
+ noiseBox->set_tooltip_text(M("TP_WAVELET_NOISE_TOOLTIP"));
//Clarity
@@ -617,13 +635,13 @@ Wavelet::Wavelet() :
// Edge Sharpness
ToolParamBlock* const edgBox = Gtk::manage(new ToolParamBlock());
- edgeffect->setAdjusterListener(this);
- edgBox->pack_start(*edgeffect);
- edgeffect->set_tooltip_markup(M("TP_WAVELET_EDEFFECT_TOOLTIP"));
edgval->setAdjusterListener(this);
edgBox->pack_start(*edgval);
+ edgeffect->setAdjusterListener(this);
+ edgBox->pack_start(*edgeffect);
+ edgeffect->set_tooltip_markup(M("TP_WAVELET_EDEFFECT_TOOLTIP"));
edgrad->setAdjusterListener(this);
edgBox->pack_start(*edgrad);
@@ -1033,6 +1051,7 @@ Wavelet::Wavelet() :
opacityShapeWL->setIdentityValue(0.);
opacityShapeWL->setResetCurve(FlatCurveType(default_params.opacityCurveWL.at(0)), default_params.opacityCurveWL);
opacityShapeWL->setTooltip(M("TP_WAVELET_OPACITYWL_TOOLTIP"));
+ opacityShapeWL->setBottomBarBgGradient({{0., 0., 0., 0.}, {1., 1., 1., 1.}});
sigmafin->setAdjusterListener(this);
// This will add the reset button at the end of the curveType buttons
@@ -1130,6 +1149,7 @@ Wavelet::~Wavelet()
idle_register.destroy();
delete opaCurveEditorG;
+ delete curveEditorC;
delete opacityCurveEditorG;
delete curveEditorbl;
delete CCWcurveEditorG;
@@ -1359,6 +1379,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited)
ccshape->setCurve(pp->wavelet.ccwcurve);
blshape->setCurve(pp->wavelet.blcurve);
opacityShapeRG->setCurve(pp->wavelet.opacityCurveRG);
+ opacityShapeSH->setCurve(pp->wavelet.opacityCurveSH);
opacityShapeBY->setCurve(pp->wavelet.opacityCurveBY);
opacityShape->setCurve(pp->wavelet.opacityCurveW);
opacityShapeWL->setCurve(pp->wavelet.opacityCurveWL);
@@ -1579,6 +1600,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited)
exptoning->set_inconsistent(!pedited->wavelet.exptoning);
expnoise->set_inconsistent(!pedited->wavelet.expnoise);
opacityShapeRG->setCurve(pp->wavelet.opacityCurveRG);
+ opacityShapeSH->setCurve(pp->wavelet.opacityCurveSH);
opacityShapeBY->setCurve(pp->wavelet.opacityCurveBY);
opacityShape->setCurve(pp->wavelet.opacityCurveW);
opacityShapeWL->setCurve(pp->wavelet.opacityCurveWL);
@@ -1771,6 +1793,7 @@ void Wavelet::setEditProvider(EditDataProvider *provider)
ccshape->setEditProvider(provider);
blshape->setEditProvider(provider);
opacityShapeRG->setEditProvider(provider);
+ opacityShapeSH->setEditProvider(provider);
opacityShapeBY->setEditProvider(provider);
opacityShape->setEditProvider(provider);
opacityShapeWL->setEditProvider(provider);
@@ -1848,6 +1871,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited)
pp->wavelet.ccwcurve = ccshape->getCurve();
pp->wavelet.blcurve = blshape->getCurve();
pp->wavelet.opacityCurveRG = opacityShapeRG->getCurve();
+ pp->wavelet.opacityCurveSH = opacityShapeSH->getCurve();
pp->wavelet.opacityCurveBY = opacityShapeBY->getCurve();
pp->wavelet.opacityCurveW = opacityShape->getCurve();
pp->wavelet.opacityCurveWL = opacityShapeWL->getCurve();
@@ -1976,6 +2000,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited)
pedited->wavelet.level2noise = level2noise->getEditedState();
pedited->wavelet.level3noise = level3noise->getEditedState();
pedited->wavelet.opacityCurveRG = !opacityShapeRG->isUnChanged();
+ pedited->wavelet.opacityCurveSH = !opacityShapeSH->isUnChanged();
pedited->wavelet.opacityCurveBY = !opacityShapeBY->isUnChanged();
pedited->wavelet.opacityCurveW = !opacityShape->isUnChanged();
pedited->wavelet.opacityCurveWL = !opacityShapeWL->isUnChanged();
@@ -2158,6 +2183,8 @@ void Wavelet::curveChanged(CurveEditor* ce)
listener->panelChanged(EvWavblshape, M("HISTORY_CUSTOMCURVE"));
} else if (ce == opacityShapeRG) {
listener->panelChanged(EvWavColor, M("HISTORY_CUSTOMCURVE"));
+ } else if (ce == opacityShapeSH) {
+ listener->panelChanged(EvWavlevelshc, M("HISTORY_CUSTOMCURVE"));
} else if (ce == opacityShapeBY) {
listener->panelChanged(EvWavOpac, M("HISTORY_CUSTOMCURVE"));
} else if (ce == opacityShape) {
@@ -2465,11 +2492,13 @@ void Wavelet::HSmethodUpdateUI()
bllev->hide();
threshold->hide();
threshold2->hide();
+ curveEditorC->hide();
} else { //with
hllev->show();
bllev->show();
threshold->show();
threshold2->show();
+ curveEditorC->show();
}
}
}
@@ -2880,6 +2909,7 @@ void Wavelet::setBatchMode(bool batchMode)
Dirmethod->append(M("GENERAL_UNCHANGED"));
CCWcurveEditorG->setBatchMode(batchMode);
opaCurveEditorG->setBatchMode(batchMode);
+ curveEditorC->setBatchMode(batchMode);
opacityCurveEditorG->setBatchMode(batchMode);
opacityCurveEditorW->setBatchMode(batchMode);
opacityCurveEditorWL->setBatchMode(batchMode);
diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h
index c9cd3dc4c..c6a0a6b85 100644
--- a/rtgui/wavelet.h
+++ b/rtgui/wavelet.h
@@ -101,6 +101,7 @@ private:
rtengine::ProcEvent EvWavLabGridValue;
rtengine::ProcEvent EvWavrangeab;
rtengine::ProcEvent EvWavprotab;
+ rtengine::ProcEvent EvWavlevelshc;
LabGrid *labgrid;
@@ -164,6 +165,8 @@ private:
void enableToggled(MyExpander* expander);
CurveEditorGroup* const curveEditorG;
+ CurveEditorGroup* const curveEditorC;
+ FlatCurveEditor* opacityShapeSH;
CurveEditorGroup* const CCWcurveEditorG;
CurveEditorGroup* const curveEditorbl;