diff --git a/rtdata/languages/default b/rtdata/languages/default
index 2cca1b81d..9a26ee856 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -1210,7 +1210,8 @@ HISTORY_MSG_SOFTLIGHT_STRENGTH;Soft light - Strength
HISTORY_MSG_TEMPOUT;CAM02 automatic temperature
HISTORY_MSG_TM_FATTAL_ANCHOR;DRC - Anchor
HISTORY_MSG_TRANS_Method;Geometry - Method
-HISTORY_MSG_WAVBALCHROM;Balance chroma
+HISTORY_MSG_WAVBALCHROM;Equalizer chrominance
+HISTORY_MSG_WAVBALLUM;Equalizer luminance
HISTORY_MSG_WAVCHROMFI;Chroma fine
HISTORY_MSG_WAVCHROMCO;Chroma coarse
HISTORY_MSG_WAVCLARI;Clarity
@@ -1233,7 +1234,7 @@ HISTORY_MSG_BLSHAPE;Blur by level
HISTORY_MSG_WAVBL;Blur levels
HISTORY_MSG_BLURWAV;Blur luminance
HISTORY_MSG_BLURCWAV;Blur chroma
-HISTORY_MSG_EDGEFFECT;Edge Effect
+HISTORY_MSG_EDGEFFECT;Edge Damper
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s
HISTORY_SNAPSHOT;Snapshot
@@ -3040,9 +3041,10 @@ TP_WAVELET_BACKGROUND;Background
TP_WAVELET_BACUR;Curve
TP_WAVELET_BALANCE;Contrast balance d/v-h
TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chroma or residual tone mapping are activated, the effect due to balance is amplified.
-TP_WAVELET_BALCHRO;Chroma balance
+TP_WAVELET_BALCHRO;Chrominance balance
TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chroma balance.
-TP_WAVELET_BALCHROM;Chroma balance
+TP_WAVELET_BALCHROM;Denoise Equalizer Blue-Red
+TP_WAVELET_BALLUM;Denoise Equalizer White-Black
TP_WAVELET_BANONE;None
TP_WAVELET_BASLI;Slider
TP_WAVELET_BATYPE;Contrast balance method
@@ -3058,10 +3060,10 @@ TP_WAVELET_CH3;Link contrast levels
TP_WAVELET_CHCU;Curve
TP_WAVELET_CHR;Chroma-contrast link strength
TP_WAVELET_CHRO;Saturated/pastel threshold
-TP_WAVELET_CHROFRAME;Denoise Chroma
+TP_WAVELET_CHROFRAME;Denoise Chrominance
TP_WAVELET_CHROMAFRAME;Chroma
-TP_WAVELET_CHROMCO;Chroma Coarse
-TP_WAVELET_CHROMFI;Chroma Fine
+TP_WAVELET_CHROMCO;Chrominance Coarse
+TP_WAVELET_CHROMFI;Chrominance Fine
TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored.
TP_WAVELET_CHR_TOOLTIP;Adjusts chroma as a function of "contrast levels" and "chroma-contrast link strength"
TP_WAVELET_CHRWAV;Blur chroma
@@ -3205,7 +3207,7 @@ TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will b
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_TILESBIG;Tiles
TP_WAVELET_TILESFULL;Full image
TP_WAVELET_TILESIZE;Tiling method
TP_WAVELET_TILESLIT;Little tiles
@@ -3224,7 +3226,7 @@ TP_WAVELET_USHARP_TOOLTIP;Origin : the source file is the file before Wavelet.\n
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_WAVLOWTHR;Low contrast threshold
TP_WAVELET_WAVOFFSET;Offset
-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_WAVELET_OFFSET_TOOLTIP;Offset modifies the balance between shadows and highlights.\nHigh values here will amplify the contrast change of the highlights, whereas low values will amplify the contrast change of the shadows.\nAlong with a low Damper value you will able to select 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/FTblockDN.cc b/rtengine/FTblockDN.cc
index 34e7351b8..894c72ce2 100644
--- a/rtengine/FTblockDN.cc
+++ b/rtengine/FTblockDN.cc
@@ -2214,7 +2214,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &W
int maxlvl = min(WaveletCoeffs_L.maxlevel(), 5);
const float eps = 0.01f;
- if (edge == 1 || edge == 3) {
+ if (edge == 1 || edge == 3 || edge == 4) {
maxlvl = 4; //for refine denoise edge wavelet
}
@@ -2294,7 +2294,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &W
}
}
- if (edge == 2) {
+ if (edge == 2 || edge == 4) {
for (int i = 0; i < Hlvl_L * Wlvl_L; ++i) {
nvl[i] = vari[lvl] * SQR(noisevarlum[i]);
}
@@ -2721,7 +2721,7 @@ void ImProcFunctions::ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, f
}
}
- if (edge == 2) {
+ if (edge == 2 || edge == 4) {
for (int i = 0; i < W_L * H_L; ++i) {
nvl[i] = vari[level] * SQR(noisevarlum[i]);
}
diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc
index b509c6fe9..30b4289e2 100644
--- a/rtengine/ipwavelet.cc
+++ b/rtengine/ipwavelet.cc
@@ -138,6 +138,7 @@ struct cont_params {
float edgampl;
int neigh;
bool lipp;
+ float ballum;
float balchrom;
float chromfi;
float chromco;
@@ -399,8 +400,9 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
cp.til = waparams.edgthresh;
cp.eff = waparams.edgeffect;
cp.balchrom = waparams.balchrom;
- cp.chromfi = waparams.chromfi;
- cp.chromco = waparams.chromco;
+ cp.chromfi = 0.1f * waparams.chromfi;
+ cp.chromco = 0.1f * waparams.chromco;
+ cp.ballum = waparams.ballum;
cp.conres = waparams.rescon;
cp.conresH = waparams.resconH;
@@ -523,10 +525,11 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
realtile = 22;
}
- if (params->wavelet.Tilesmethod == "lit") {
- realtile = 12;
- }
-
+ /*
+ if (params->wavelet.Tilesmethod == "lit") {
+ realtile = 12;
+ }
+ */
int tilesize = 128 * realtile;
int overlap = (int) tilesize * 0.125f;
int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip;
@@ -667,6 +670,8 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
varhue[i] = new float[tilewidth];
}
+
+
#ifdef _OPENMP
#pragma omp for schedule(dynamic) collapse(2)
#endif
@@ -819,27 +824,58 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
ref0 = true;
}
- if (cp.contrast == 0.f && !cp.tonemap && cp.conres == 0.f && cp.conresH == 0.f && cp.val == 0 && !ref0 && params->wavelet.CLmethod == "all") { // no processing of residual L or edge=> we probably can reduce the number of levels
+ bool wavcurvecomp = false;//not enable if 0.75
+
+ if (wavblcurve) {
+ for (int i = 0; i < 500; i++) {
+ if (wavblcurve[i] != 0.) {
+ wavcurvecomp = true;
+ }
+ }
+ }
+
+ bool exblurL = cp.blena && wavcurvecomp;
+
+ if (exblurL) {
+ if (cp.mul[0] == 0.f) {
+ cp.mul[0] = 0.01f;//to always enable WaveletcontAllL if no contrast is nead
+ }
+ }
+
+ if (!exblurL && cp.contrast == 0.f && cp.blurres == 0.f && !cp.tonemap && cp.conres == 0.f && cp.conresH == 0.f && cp.val == 0 && !ref0 && params->wavelet.CLmethod == "all") { // no processing of residual L or edge=> we probably can reduce the number of levels
while (levwavL > 0 && cp.mul[levwavL - 1] == 0.f) { // cp.mul[level] == 0.f means no changes to level
levwavL--;
}
}
+ if (cp.chromfi > 0.f || cp.chromco > 0.f) {
+ if (levwavL < 7) {
+ levwavL = 7;
+ }
+ }
+
if (levwavL < 4) {
levwavL = 4; //to allow edge => I always allocate 3 (4) levels..because if user select wavelet it is to do something !!
}
+ if (settings->verbose) {
+ printf("Level decomp L=%i\n", levwavL);
+ }
+
+ bool usechrom = cp.chromfi > 0.f || cp.chromco > 0.f;
+
if (levwavL > 0) {
const std::unique_ptr Ldecomp(new wavelet_decomposition(labco->data, labco->W, labco->H, levwavL, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen));
+ float madL[8][3];
if (!Ldecomp->memoryAllocationFailed) {
- float madL[8][3];
+ // float madL[8][3];
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic) collapse(2) num_threads(wavNestedLevels) if(wavNestedLevels>1)
#endif
- for (int lvl = 0; lvl < 4; lvl++) {
+ for (int lvl = 0; lvl < levwavL; lvl++) {
for (int dir = 1; dir < 4; dir++) {
int Wlvl_L = Ldecomp->level_W(lvl);
int Hlvl_L = Ldecomp->level_H(lvl);
@@ -875,17 +911,64 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
vari[1] = 8.f * SQR((cp.lev1n / 125.f) * (1.f + cp.lev1n / 25.f));
vari[2] = 8.f * SQR((cp.lev2n / 125.f) * (1.f + cp.lev2n / 25.f));
vari[3] = 8.f * SQR((cp.lev3n / 125.f) * (1.f + cp.lev3n / 25.f));
+ float kr3 = 1.f;
+
+ if (cp.lev3n < 10.f) {
+ kr3 = 0.f;
+ } else if (cp.lev3n < 30.f) {
+ kr3 = 0.5f;
+ } else if (cp.lev3n < 70.f) {
+ kr3 = 0.7f;
+ } else {
+ kr3 = 1.f;
+ }
if ((cp.lev0n > 0.1f || cp.lev1n > 0.1f || cp.lev2n > 0.1f || cp.lev3n > 0.1f) && cp.noiseena) {
- int edge = 1;
+ int edge = 4;
vari[0] = rtengine::max(0.0001f, vari[0]);
vari[1] = rtengine::max(0.0001f, vari[1]);
vari[2] = rtengine::max(0.0001f, vari[2]);
- vari[3] = rtengine::max(0.0001f, vari[3]);
- float* noisevarlum = nullptr; // we need a dummy to pass it to WaveletDenoiseAllL
+ vari[3] = rtengine::max(0.0001f, kr3 * vari[3]);
+ // float* noisevarlum = nullptr; // we need a dummy to pass it to WaveletDenoiseAllL
+ int GWL = labco->W;
+ int GHL = labco->H;
+ float* noisevarlum = new float[GHL * GWL];
+ int GW2L = (GWL + 1) / 2;
- WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, vari, edge, 1);
- // WaveletDenoiseAllL (*Ldecomp, noisevarlum, madL, vari, edge, 1);
+ float nvlh[13] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 0.7f, 0.5f}; //high value
+ float nvll[13] = {0.1f, 0.15f, 0.2f, 0.25f, 0.3f, 0.35f, 0.4f, 0.45f, 0.7f, 0.8f, 1.f, 1.f, 1.f}; //low value
+
+ float seuillow = 3000.f;//low
+ float seuilhigh = 18000.f;//high
+ int i = 10 - cp.ballum;
+ float ac = (nvlh[i] - nvll[i]) / (seuillow - seuilhigh);
+ float bc = nvlh[i] - seuillow * ac;
+
+#ifdef _OPENMP
+ #pragma omp parallel for
+
+#endif
+
+ for (int ir = 0; ir < GHL; ir++)
+ for (int jr = 0; jr < GWL; jr++) {
+ float lN = labco->L[ir][jr];
+
+ if (lN < seuillow) {
+ noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] = nvlh[i];
+ } else if (lN < seuilhigh) {
+ noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] = ac * lN + bc;
+ } else {
+ noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] = nvll[i];
+ }
+ }
+
+ if (cp.lev3n < 0.5f) {
+ WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, vari, edge, 1);
+ } else {
+ WaveletDenoiseAll_BiShrinkL(*Ldecomp, noisevarlum, madL, vari, edge, 1);
+
+ WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, vari, edge, 1);
+ }
}
//Flat curve for Contrast=f(H) in levels
@@ -908,300 +991,363 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
}
WaveletcontAllLfinal(*Ldecomp, cp, mean, sigma, MaxP, waOpacityCurveWL);
+
//Evaluate2(*Ldecomp, cp, ind, mean, meanN, sigma, sigmaN, MaxP, MaxN, madL);
-
- Ldecomp->reconstruct(labco->data, cp.strength);
- }
- }
-
-
- /*
- float variC[7];
- float variCb[7];
-
- float noisecfr = cp.chromfi;
- 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);
- }
-
- 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);
- }
-
-
- if (noisecfr < 0.f) {
- noisecfr = 0.0001f;
- }
-
- if (noiseccr < 0.f) {
- noiseccr = 0.0001f;
- }
-
- if (noisecfb < 0.f) {
- noisecfb = 0.0001f;
- }
-
- if (noiseccb < 0.f) {
- noiseccb = 0.0001f;
- }
-
- int edge = 2;
- variC[0] = SQR(noisecfr);
- variC[1] = SQR(noisecfr);
- variC[2] = SQR(noisecfr);
-
- variC[3] = SQR(noisecfr);
- variC[4] = SQR(noisecfr);
- variC[5] = SQR(noiseccr);
- variC[6] = SQR(noiseccr);
-
- variCb[0] = SQR(noisecfb);
- variCb[1] = SQR(noisecfb);
- variCb[2] = SQR(noisecfb);
-
- variCb[3] = SQR(noisecfb);
- variCb[4] = SQR(noisecfb);
- variCb[5] = SQR(noiseccb);
- variCb[6] = SQR(noiseccb);
-
- float k1 = 0.f;
- float k2 = 0.f;
- float k3 = 0.f;
-
- if (cp.chromfi) {
- k1 = 0.f;
- k2 = 0.f;
- k3 = 0.f;
- } else if (cp.chromfi < 0.3f) {
- k1 = 0.1f;
- k2 = 0.0f;
- k3 = 0.f;
- } else if (cp.chromfi < 0.5f) {
- k1 = 0.2f;
- k2 = 0.1f;
- k3 = 0.f;
- } else if (cp.chromfi < 0.8f) {
- k1 = 0.3f;
- k2 = 0.25f;
- k3 = 0.f;
- } else if (cp.chromfi < 1.f) {
- k1 = 0.4f;
- k2 = 0.25f;
- k3 = 0.1f;
- } else if (cp.chromfi < 2.f) {
- k1 = 0.5f;
- k2 = 0.3f;
- k3 = 0.15f;
- } else if (cp.chromfi < 3.f) {
- k1 = 0.6f;
- k2 = 0.45f;
- k3 = 0.3f;
- } else if (cp.chromfi < 4.f) {
- k1 = 0.7f;
- k2 = 0.5f;
- k3 = 0.4f;
- } else if (cp.chromfi < 5.f) {
- k1 = 0.8f;
- k2 = 0.6f;
- k3 = 0.5f;
- } else if (cp.chromfi < 10.f) {
- k1 = 0.85f;
- k2 = 0.7f;
- k3 = 0.6f;
- } else if (cp.chromfi < 20.f) {
- k1 = 0.9f;
- k2 = 0.8f;
- k3 = 0.7f;
- } else if (cp.chromfi < 50.f) {
- k1 = 1.f;
- k2 = 1.f;
- k3 = 0.9f;
-
- } else {
- k1 = 1.f;
- k2 = 1.f;
- k3 = 1.f;
- }
-
- float minic = 0.0001f;
- variC[0] = max(minic, variC[0]);
- variC[1] = max(minic, k1 * variC[1]);
- variC[2] = max(minic, k2 * variC[2]);
- variC[3] = max(minic, k3 * variC[3]);
-
- variCb[0] = max(minic, variCb[0]);
- variCb[1] = max(minic, k1 * variCb[1]);
- variCb[2] = max(minic, k2 * variCb[2]);
- variCb[3] = max(minic, k3 * variCb[3]);
-
- float k4 = 0.f;
- float k5 = 0.f;
- float k6 = 0.f;
-
- if (cp.chromco == 0.01f) {
- k4 = 0.f;
- k5 = 0.0f;
- } else if (cp.chromco < 0.2f) {
- k4 = 0.1f;
- k5 = 0.0f;
- } else if (cp.chromco < 0.5f) {
- k4 = 0.15f;
- k5 = 0.0f;
- } else if (cp.chromco < 1.f) {
- k4 = 0.15f;
- k5 = 0.1f;
- } else if (cp.chromco < 3.f) {
- k4 = 0.3f;
- k5 = 0.15f;
- } else if (cp.chromco < 4.f) {
- k4 = 0.6f;
- k5 = 0.4f;
- } else if (cp.chromco < 6.f) {
- k4 = 0.8f;
- k5 = 0.6f;
- } else {
- k4 = 1.f;
- k5 = 1.f;
- }
-
- variC[4] = max(0.0001f, k4 * variC[4]);
- variC[5] = max(0.0001f, k5 * variC[5]);
- variCb[4] = max(0.0001f, k4 * variCb[4]);
- variCb[5] = max(0.0001f, k5 * variCb[5]);
-
- if (cp.chromco < 4.f) {
- k6 = 0.f;
- } else if (cp.chromco < 5.f) {
- k6 = 0.4f;
- } else if (cp.chromco < 6.f) {
- k6 = 0.7f;
- } else {
- k6 = 1.f;
- }
-
- variC[6] = max(0.0001f, k6 * variC[6]);
- variCb[6] = max(0.0001f, k6 * variCb[6]);
- float nvch = 0.6f;//high value
- float nvcl = 0.1f;//low value
-
- if (cp.chromco > 100.f) {
- nvch = 0.8f;
- nvcl = 0.4f;
- }
-
- float seuil = 4000.f;//low
- float seuil2 = 15000.f;//high
- //ac and bc for transition
- float ac = (nvch - nvcl) / (seuil - seuil2);
- float bc = nvch - seuil * ac;
- int GW = labco->W;
- int GH = labco->H;
- float* noisevarchrom = new float[GH * GW];
- //noisevarchrom in function chroma
- int GW2 = (GW + 1) / 2;
- float noisevarab_r = 100.f; //SQR(lp.noisecc / 10.0);
- for (int ir = 0; ir < GH; ir++)
- for (int jr = 0; jr < GW; jr++) {
- float cN = sqrt(SQR(labco->a[ir][jr]) + SQR(labco->b[ir][jr]));
-
- if (cN < seuil) {
- noisevarchrom[(ir >> 1)*GW2 + (jr >> 1)] = nvch;
- } else if (cN < seuil2) {
- noisevarchrom[(ir >> 1)*GW2 + (jr >> 1)] = ac * cN + bc;
- } else {
- noisevarchrom[(ir >> 1)*GW2 + (jr >> 1)] = nvcl;
- }
+ /*
+ Ldecomp->reconstruct(labco->data, cp.strength);
}
- */
+ }
+ */
+ if (!usechrom) {
+ Ldecomp->reconstruct(labco->data, cp.strength);
+ }
- //Flat curve for H=f(H) in residual image
- FlatCurve* hhCurve = new FlatCurve(params->wavelet.hhcurve); //curve H=f(H)
- bool hhutili = false;
+ float variC[7];
+ float variCb[7];
- if (!hhCurve || hhCurve->isIdentity()) {
- if (hhCurve) {
- delete hhCurve;
- hhCurve = nullptr;
- }
- } else {
- hhutili = true;
- }
+ float noisecfr = cp.chromfi;
+ 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);
+ }
+
+ 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);
+ }
- if (!hhutili) { //always a or b
- int levwava = levwav;
+ if (noisecfr < 0.f) {
+ noisecfr = 0.0001f;
+ }
- 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--;
+ if (noiseccr < 0.f) {
+ noiseccr = 0.0001f;
+ }
+
+ if (noisecfb < 0.f) {
+ noisecfb = 0.0001f;
+ }
+
+ if (noiseccb < 0.f) {
+ noiseccb = 0.0001f;
+ }
+
+ int edge = 2;
+ variC[0] = SQR(noisecfr);
+ variC[1] = SQR(noisecfr);
+ variC[2] = SQR(noisecfr);
+
+ variC[3] = SQR(noisecfr);
+ variC[4] = SQR(noisecfr);
+ variC[5] = SQR(noiseccr);
+ variC[6] = SQR(noiseccr);
+
+ variCb[0] = SQR(noisecfb);
+ variCb[1] = SQR(noisecfb);
+ variCb[2] = SQR(noisecfb);
+
+ variCb[3] = SQR(noisecfb);
+ variCb[4] = SQR(noisecfb);
+ variCb[5] = SQR(noiseccb);
+ variCb[6] = SQR(noiseccb);
+
+ float k1 = 0.f;
+ float k2 = 0.f;
+ float k3 = 0.f;
+
+ if (cp.chromfi < 0.2f) {
+ k1 = 0.f;
+ k2 = 0.f;
+ k3 = 0.f;
+ } else if (cp.chromfi < 0.3f) {
+ k1 = 0.1f;
+ k2 = 0.0f;
+ k3 = 0.f;
+ } else if (cp.chromfi < 0.5f) {
+ k1 = 0.2f;
+ k2 = 0.1f;
+ k3 = 0.f;
+ } else if (cp.chromfi < 0.8f) {
+ k1 = 0.3f;
+ k2 = 0.25f;
+ k3 = 0.f;
+ } else if (cp.chromfi < 1.f) {
+ k1 = 0.4f;
+ k2 = 0.25f;
+ k3 = 0.1f;
+ } else if (cp.chromfi < 2.f) {
+ k1 = 0.5f;
+ k2 = 0.3f;
+ k3 = 0.15f;
+ } else if (cp.chromfi < 3.f) {
+ k1 = 0.6f;
+ k2 = 0.45f;
+ k3 = 0.3f;
+ } else if (cp.chromfi < 4.f) {
+ k1 = 0.7f;
+ k2 = 0.5f;
+ k3 = 0.4f;
+ } else if (cp.chromfi < 5.f) {
+ k1 = 0.8f;
+ k2 = 0.6f;
+ k3 = 0.5f;
+ } else if (cp.chromfi < 6.f) {
+ k1 = 0.85f;
+ k2 = 0.7f;
+ k3 = 0.6f;
+ } else if (cp.chromfi < 8.f) {
+ k1 = 0.9f;
+ k2 = 0.8f;
+ k3 = 0.7f;
+ } else if (cp.chromfi < 10.f) {
+ k1 = 1.f;
+ k2 = 1.f;
+ k3 = 0.9f;
+
+ } else {
+ k1 = 1.f;
+ k2 = 1.f;
+ k3 = 1.f;
+ }
+
+ float minic = 0.0001f;
+ variC[0] = max(minic, variC[0]);
+ variC[1] = max(minic, k1 * variC[1]);
+ variC[2] = max(minic, k2 * variC[2]);
+ variC[3] = max(minic, k3 * variC[3]);
+
+ variCb[0] = max(minic, variCb[0]);
+ variCb[1] = max(minic, k1 * variCb[1]);
+ variCb[2] = max(minic, k2 * variCb[2]);
+ variCb[3] = max(minic, k3 * variCb[3]);
+
+ float k4 = 0.f;
+ float k5 = 0.f;
+ float k6 = 0.f;
+
+ if (cp.chromco == 0.01f) {
+ k4 = 0.f;
+ k5 = 0.0f;
+ } else if (cp.chromco < 0.2f) {
+ k4 = 0.1f;
+ k5 = 0.0f;
+ } else if (cp.chromco < 0.5f) {
+ k4 = 0.15f;
+ k5 = 0.0f;
+ } else if (cp.chromco < 1.f) {
+ k4 = 0.15f;
+ k5 = 0.1f;
+ } else if (cp.chromco < 3.f) {
+ k4 = 0.3f;
+ k5 = 0.15f;
+ } else if (cp.chromco < 4.f) {
+ k4 = 0.6f;
+ k5 = 0.4f;
+ } else if (cp.chromco < 6.f) {
+ k4 = 0.8f;
+ k5 = 0.6f;
+ } else {
+ k4 = 1.f;
+ k5 = 1.f;
+ }
+
+ variC[4] = max(0.0001f, k4 * variC[4]);
+ variC[5] = max(0.0001f, k5 * variC[5]);
+ variCb[4] = max(0.0001f, k4 * variCb[4]);
+ variCb[5] = max(0.0001f, k5 * variCb[5]);
+
+ if (cp.chromco < 4.f) {
+ k6 = 0.f;
+ } else if (cp.chromco < 5.f) {
+ k6 = 0.4f;
+ } else if (cp.chromco < 6.f) {
+ k6 = 0.7f;
+ } else {
+ k6 = 1.f;
+ }
+
+ variC[6] = max(0.0001f, k6 * variC[6]);
+ variCb[6] = max(0.0001f, k6 * variCb[6]);
+ /*
+ for (int y = 0; y < 7; y++) {
+ printf("y=%i madL=%f varia=%f variab=%f\n", y, madL[y][1], variC[y], variCb[y]);
+ }
+ */
+ float nvch = 0.6f;//high value
+ float nvcl = 0.1f;//low value
+
+ if (cp.chromco > 30.f) {
+ nvch = 0.8f;
+ nvcl = 0.4f;
+ }
+
+ float seuil = 4000.f;//low
+ float seuil2 = 15000.f;//high
+ //ac and bc for transition
+ float ac = (nvch - nvcl) / (seuil - seuil2);
+ float bc = nvch - seuil * ac;
+ int GW = labco->W;
+ int GH = labco->H;
+ float* noisevarchrom = new float[GH * GW];
+ //noisevarchrom in function chroma
+ int GW2 = (GW + 1) / 2;
+ float noisevarab_r = 100.f;
+
+ for (int ir = 0; ir < GH; ir++)
+ for (int jr = 0; jr < GW; jr++) {
+ float cN = sqrt(SQR(labco->a[ir][jr]) + SQR(labco->b[ir][jr]));
+
+ if (cN < seuil) {
+ noisevarchrom[(ir >> 1)*GW2 + (jr >> 1)] = nvch;
+ } else if (cN < seuil2) {
+ noisevarchrom[(ir >> 1)*GW2 + (jr >> 1)] = ac * cN + bc;
+ } else {
+ noisevarchrom[(ir >> 1)*GW2 + (jr >> 1)] = nvcl;
+ }
+ }
+
+
+ //Flat curve for H=f(H) in residual image
+ FlatCurve* hhCurve = new FlatCurve(params->wavelet.hhcurve); //curve H=f(H)
+ bool hhutili = false;
+
+ if (!hhCurve || hhCurve->isIdentity()) {
+ if (hhCurve) {
+ delete hhCurve;
+ hhCurve = nullptr;
+ }
+ } else {
+ hhutili = true;
+ }
+
+ bool exblurab = cp.chrwav > 0.f && exblurL;
+
+ if (!hhutili) { //always a or b
+ int levwava = levwav;
+
+ if (!exblurab && cp.chrores == 0.f && cp.blurcres == 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--;
+ }
+ }
+
+ if (cp.chromfi > 0.f || cp.chromco > 0.f) {
+ if (levwava < 7) {
+ levwava = 7;
+ }
+ }
+
+ if (settings->verbose) {
+ printf("Leval decomp a=%i\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));
+
+ if (!adecomp->memoryAllocationFailed) {
+ if (cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.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);
+ adecomp->reconstruct(labco->data + datalen, cp.strength);
+ }
+ }
+
+ int levwavb = levwav;
+
+ if (!exblurab && cp.chrores == 0.f && cp.blurcres == 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--;
+ }
+ }
+
+ if (cp.chromfi > 0.f || cp.chromco > 0.f) {
+ if (levwavb < 7) {
+ levwavb = 7;
+ }
+ }
+
+ if (settings->verbose) {
+ printf("Leval decomp b=%i\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));
+
+ if (!bdecomp->memoryAllocationFailed) {
+ if (cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.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);
+ }
+
+ Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab);
+ WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab);
+ bdecomp->reconstruct(labco->data + 2 * datalen, cp.strength);
+ }
+ }
+ } else {// a and b
+ int levwavab = levwav;
+
+ if (!exblurab && cp.chrores == 0.f && cp.blurcres == 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--;
+ }
+ }
+
+ if (cp.chromfi > 0.f || cp.chromco > 0.f) {
+ if (levwavab < 7) {
+ levwavab = 7;
+ }
+ }
+
+ 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));
+
+ if (!adecomp->memoryAllocationFailed && !bdecomp->memoryAllocationFailed) {
+ if (cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.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.chromfi > 0.f)) {
+ 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);
+
+ }
+ }
+ }
+
+ delete[] noisevarchrom;
+
+ if (hhCurve) {
+ delete hhCurve;
+ }
+
+ if (usechrom) {
+ Ldecomp->reconstruct(labco->data, cp.strength);
}
}
-
- 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));
-
- if (!adecomp->memoryAllocationFailed) {
- Evaluate2(*adecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab);
- WaveletcontAllAB(labco, varhue, varchro, *adecomp, wavblcurve, waOpacityCurveW, cp, true, skip, meanab, sigmaab);
- adecomp->reconstruct(labco->data + datalen, cp.strength);
- }
- }
-
- int levwavb = levwav;
-
- 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--;
- }
- }
-
- 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));
-
- if (!bdecomp->memoryAllocationFailed) {
- Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab);
- WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab);
- bdecomp->reconstruct(labco->data + 2 * datalen, cp.strength);
- }
- }
- } else {// a and b
- int levwavab = levwav;
-
- 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--;
- }
- }
-
- 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));
-
- if (!adecomp->memoryAllocationFailed && !bdecomp->memoryAllocationFailed) {
- Evaluate2(*adecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab);
- WaveletcontAllAB(labco, varhue, varchro, *adecomp, wavblcurve, waOpacityCurveW, cp, true, skip, meanab, sigmaab);
- Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab);
- 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);
-
- }
- }
- }
-
- // delete[] noisevarchrom;
-
- if (hhCurve) {
- delete hhCurve;
}
if (numtiles > 1 || (numtiles == 1 /*&& cp.avoi*/)) { //in all case since I add contrast curve
@@ -1430,10 +1576,10 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
}
}
- constexpr double epsilmax = 0.001;
- constexpr double epsilmin = 0.0001;
- constexpr double aepsil = (epsilmax - epsilmin) / 90.f;
- constexpr double bepsil = epsilmax - 100.f * aepsil;
+ constexpr double epsilmax = 0.002;
+ constexpr double epsilmin = 0.0005;
+ constexpr double aepsil = 0.01f * (epsilmax - epsilmin);
+ constexpr double bepsil = epsilmin;
const double epsil = aepsil * waparams.softradend + bepsil;
const float blur = 10.f / scale * (0.001f + 0.8f * waparams.softradend);
@@ -2249,6 +2395,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float *
float klev = 1.f;
if (wavblcurve && wavcurvecomp && cp.blena) {
+ // printf("Blur level L\n");
float mea[10];
float effect = cp.bluwav;
float beta = 0.f;
@@ -2308,14 +2455,10 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float *
if (settings->verbose) {
printf("lvl=%i n0=%i n32=%i n1=%i n2=%i n3=%i n4=%i n5=%i n6=%i n7=%i n8=%i n9=%i n10=%i\n", lvl, n0, n0 - n32, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10);
}
+
klev = (wavblcurve[lvl * 55.5f]);
- float lvr = lvl;
- if (lvr == 0) {
- lvr = 1;
- }
-
- klev *= beta * lvr * 100.f / skip;
+ klev *= beta * 100.f / skip;
boxblur(bef, aft, klev, Wlvl_L, Hlvl_L, false);
for (int co = 0; co < Hlvl_L * Wlvl_L; co++) {
@@ -2541,8 +2684,8 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float
WavCoeffs_ab0[i] = aft[i];
}
- delete[] bef;
- delete[] aft;
+ delete[] bef;
+ delete[] aft;
}
@@ -2570,6 +2713,7 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float
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 mea[10];
float effect = cp.bluwav;
float beta = 0.f;
@@ -2613,13 +2757,8 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float
}
klev = (wavblcurve[lvl * 55.5f]);
- float lvr = lvl;
- if (lvr == 0) {
- lvr = 1;
- }
-
- klev *= beta * cp.chrwav * lvr * 200.f / skip;
+ klev *= beta * cp.chrwav * 100.f / skip;
boxblur(bef, aft, klev, Wlvl_ab, Hlvl_ab, false);
diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc
index cadb0857d..12784d3e7 100644
--- a/rtengine/procparams.cc
+++ b/rtengine/procparams.cc
@@ -2248,6 +2248,7 @@ WaveletParams::WaveletParams() :
bluemed(0),
greenhigh(0),
bluehigh(0),
+ ballum(7.),
balchrom(0.),
chromfi(0.),
chromco(0.),
@@ -2361,6 +2362,7 @@ bool WaveletParams::operator ==(const WaveletParams& other) const
&& bluemed == other.bluemed
&& greenhigh == other.greenhigh
&& bluehigh == other.bluehigh
+ && ballum == other.ballum
&& balchrom == other.balchrom
&& chromfi == other.chromfi
&& chromco == other.chromco
@@ -4883,6 +4885,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
saveToKeyfile(!pedited || pedited->wavelet.bluehigh, "Wavelet", "CBbluehigh", wavelet.bluehigh, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.bluemed, "Wavelet", "CBbluemed", wavelet.bluemed, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.bluelow, "Wavelet", "CBbluelow", wavelet.bluelow, keyFile);
+ saveToKeyfile(!pedited || pedited->wavelet.ballum, "Wavelet", "Ballum", wavelet.ballum, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.balchrom, "Wavelet", "Balchrom", wavelet.balchrom, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.chromfi, "Wavelet", "Chromfine", wavelet.chromfi, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.chromco, "Wavelet", "Chromcoarse", wavelet.chromco, keyFile);
@@ -6564,6 +6567,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
assignFromKeyfile(keyFile, "Wavelet", "CBbluehigh", pedited, wavelet.bluehigh, pedited->wavelet.bluehigh);
assignFromKeyfile(keyFile, "Wavelet", "CBbluemed", pedited, wavelet.bluemed, pedited->wavelet.bluemed);
assignFromKeyfile(keyFile, "Wavelet", "CBbluelow", pedited, wavelet.bluelow, pedited->wavelet.bluelow);
+ assignFromKeyfile(keyFile, "Wavelet", "Ballum", pedited, wavelet.ballum, pedited->wavelet.ballum);
assignFromKeyfile(keyFile, "Wavelet", "Balchrom", pedited, wavelet.balchrom, pedited->wavelet.balchrom);
assignFromKeyfile(keyFile, "Wavelet", "Chromfine", pedited, wavelet.chromfi, pedited->wavelet.chromfi);
assignFromKeyfile(keyFile, "Wavelet", "Chromcoarse", pedited, wavelet.chromco, pedited->wavelet.chromco);
diff --git a/rtengine/procparams.h b/rtengine/procparams.h
index 4a04f9028..6cb15030f 100644
--- a/rtengine/procparams.h
+++ b/rtengine/procparams.h
@@ -1673,6 +1673,7 @@ struct WaveletParams {
int bluemed;
int greenhigh;
int bluehigh;
+ double ballum;
double balchrom;
double chromfi;
double chromco;
diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc
index e9e05b45b..584f0263a 100644
--- a/rtgui/paramsedited.cc
+++ b/rtgui/paramsedited.cc
@@ -496,6 +496,7 @@ void ParamsEdited::set(bool v)
wavelet.bluemed = v;
wavelet.bluelow = v;
wavelet.lipst = v;
+ wavelet.ballum = v;
wavelet.balchrom = v;
wavelet.chromfi = v;
wavelet.chromco = v;
@@ -1558,6 +1559,7 @@ void ParamsEdited::initFrom(const std::vector&
wavelet.bluelow = wavelet.bluelow && p.wavelet.bluelow == other.wavelet.bluelow;
wavelet.lipst = wavelet.lipst && p.wavelet.lipst == other.wavelet.lipst;
wavelet.bluehigh = wavelet.bluehigh && p.wavelet.bluehigh == other.wavelet.bluehigh;
+ wavelet.ballum = wavelet.ballum && p.wavelet.ballum == other.wavelet.ballum;
wavelet.balchrom = wavelet.balchrom && p.wavelet.balchrom == other.wavelet.balchrom;
wavelet.chromfi = wavelet.chromfi && p.wavelet.chromfi == other.wavelet.chromfi;
wavelet.chromco = wavelet.chromco && p.wavelet.chromco == other.wavelet.chromco;
@@ -5074,6 +5076,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
toEdit.wavelet.bluelow = mods.wavelet.bluelow;
}
+ if (wavelet.ballum) {
+ toEdit.wavelet.ballum = mods.wavelet.ballum;
+ }
+
if (wavelet.balchrom) {
toEdit.wavelet.balchrom = mods.wavelet.balchrom;
}
diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h
index 14265a0f8..78ee6aa69 100644
--- a/rtgui/paramsedited.h
+++ b/rtgui/paramsedited.h
@@ -1027,6 +1027,7 @@ struct WaveletParamsEdited {
bool bluemed;
bool greenhigh;
bool bluehigh;
+ bool ballum;
bool balchrom;
bool chromfi;
bool chromco;
diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc
index bc99d0d57..af159d480 100644
--- a/rtgui/wavelet.cc
+++ b/rtgui/wavelet.cc
@@ -130,14 +130,15 @@ Wavelet::Wavelet() :
edgedetectthr2(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGEDETECTTHR2"), -10, 100, 1, 0))),
edgesensi(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGESENSI"), 0, 100, 1, 60))),
edgeampli(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGEAMPLI"), 0, 100, 1, 10))),
+ ballum(Gtk::manage(new Adjuster(M("TP_WAVELET_BALLUM"), -2., 10., 0.5, 7., Gtk::manage(new RTImage("circle-white-small.png")), Gtk::manage(new RTImage("circle-black-small.png"))))),
balchrom(Gtk::manage(new Adjuster(M("TP_WAVELET_BALCHROM"), -100., 100., 1., 0., Gtk::manage(new RTImage("circle-blue-small.png")), Gtk::manage(new RTImage("circle-red-small.png"))))),
- chromfi(Gtk::manage(new Adjuster(M("TP_WAVELET_CHROMFI"), 0, 100, 1, 0))),
- chromco(Gtk::manage(new Adjuster(M("TP_WAVELET_CHROMCO"), 0, 100, 1, 0))),
+ chromfi(Gtk::manage(new Adjuster(M("TP_WAVELET_CHROMFI"), 0.0, 150., 0.01, 0.))),
+ chromco(Gtk::manage(new Adjuster(M("TP_WAVELET_CHROMCO"), 0, 100., 0.01, 0.))),
mergeL(Gtk::manage(new Adjuster(M("TP_WAVELET_MERGEL"), -50, 100, 1, 40))),
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.))),
- chrwav(Gtk::manage(new Adjuster(M("TP_WAVELET_CHRWAV"), 0., 100., 0., 0.))),
+ chrwav(Gtk::manage(new Adjuster(M("TP_WAVELET_CHRWAV"), 0., 100., 0.5, 0.))),
Lmethod(Gtk::manage(new MyComboBoxText())),
CHmethod(Gtk::manage(new MyComboBoxText())),
CHSLmethod(Gtk::manage(new MyComboBoxText())),
@@ -183,6 +184,7 @@ Wavelet::Wavelet() :
auto m = ProcEventMapper::getInstance();
EvWavenaclari = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVCLARI");
EvWavushamet = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVUSHAMET");
+ EvWavballum = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVBALLUM");
EvWavbalchrom = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVBALCHROM");
EvWavchromfi = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVCHROMFI");
EvWavchromco = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVCHROMCO");
@@ -246,7 +248,7 @@ Wavelet::Wavelet() :
Tilesmethod->append(M("TP_WAVELET_TILESFULL"));
Tilesmethod->append(M("TP_WAVELET_TILESBIG"));
- Tilesmethod->append(M("TP_WAVELET_TILESLIT"));
+// Tilesmethod->append(M("TP_WAVELET_TILESLIT"));
Tilesmethodconn = Tilesmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::TilesmethodChanged));
Tilesmethod->set_tooltip_text(M("TP_WAVELET_TILES_TOOLTIP"));
Gtk::HBox* const tilesizeHBox = Gtk::manage(new Gtk::HBox());
@@ -524,7 +526,9 @@ Wavelet::Wavelet() :
level3noise->setAdjusterListener(this);
level3noise->setUpdatePolicy(RTUP_DYNAMIC);
+ ballum->setAdjusterListener(this);
+ noiseBox->pack_start(*ballum);
noiseBox->pack_start(*level0noise, Gtk::PACK_SHRINK, 0);
noiseBox->pack_start(*level1noise, Gtk::PACK_SHRINK, 0);
noiseBox->pack_start(*level2noise, Gtk::PACK_SHRINK, 0);
@@ -540,7 +544,7 @@ Wavelet::Wavelet() :
chroBox->pack_start(*chromfi);
chroBox->pack_start(*chromco);
chroFrame->add(*chroBox);
-// noiseBox->pack_start(*chroFrame);
+ noiseBox->pack_start(*chroFrame);
//Clarity
@@ -1257,8 +1261,8 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited)
Tilesmethod->set_active(0);
} else if (pp->wavelet.Tilesmethod == "big") {
Tilesmethod->set_active(1);
- } else if (pp->wavelet.Tilesmethod == "lit") {
- Tilesmethod->set_active(2);
+// } else if (pp->wavelet.Tilesmethod == "lit") {
+// Tilesmethod->set_active(2);
}
//daubcoeffmethod->set_active (4);
@@ -1403,6 +1407,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited)
softrad->setValue(pp->wavelet.softrad);
softradend->setValue(pp->wavelet.softradend);
+ ballum->setValue(pp->wavelet.ballum);
balchrom->setValue(pp->wavelet.balchrom);
chromfi->setValue(pp->wavelet.chromfi);
chromco->setValue(pp->wavelet.chromco);
@@ -1551,6 +1556,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited)
softrad->setEditedState(pedited->wavelet.softrad ? Edited : UnEdited);
softradend->setEditedState(pedited->wavelet.softradend ? Edited : UnEdited);
+ ballum->setEditedState(pedited->wavelet.ballum ? Edited : UnEdited);
balchrom->setEditedState(pedited->wavelet.balchrom ? Edited : UnEdited);
chromfi->setEditedState(pedited->wavelet.chromfi ? Edited : UnEdited);
chromco->setEditedState(pedited->wavelet.chromco ? Edited : UnEdited);
@@ -1774,6 +1780,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited)
pp->wavelet.strength = (int) strength->getValue();
pp->wavelet.balance = (int) balance->getValue();
pp->wavelet.balchrom = balchrom->getValue();
+ pp->wavelet.ballum = ballum->getValue();
pp->wavelet.chromfi = chromfi->getValue();
pp->wavelet.chromco = chromco->getValue();
@@ -1895,6 +1902,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited)
pedited->wavelet.bluemed = bluemed->getEditedState();
pedited->wavelet.greenhigh = greenhigh->getEditedState();
pedited->wavelet.bluehigh = bluehigh->getEditedState();
+ pedited->wavelet.ballum = ballum->getEditedState();
pedited->wavelet.balchrom = balchrom->getEditedState();
pedited->wavelet.chromfi = chromfi->getEditedState();
pedited->wavelet.chromco = chromco->getEditedState();
@@ -2015,8 +2023,8 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited)
pp->wavelet.Tilesmethod = "full";
} else if (Tilesmethod->get_active_row_number() == 1) {
pp->wavelet.Tilesmethod = "big";
- } else if (Tilesmethod->get_active_row_number() == 2) {
- pp->wavelet.Tilesmethod = "lit";
+// } else if (Tilesmethod->get_active_row_number() == 2) {
+// pp->wavelet.Tilesmethod = "lit";
}
if (daubcoeffmethod->get_active_row_number() == 0) {
@@ -2129,6 +2137,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit
level1noise->setDefault (defParams->wavelet.level1noise);
level2noise->setDefault (defParams->wavelet.level2noise);
level3noise->setDefault (defParams->wavelet.level3noise);
+ ballum->setDefault(defParams->wavelet.ballum);
balchrom->setDefault(defParams->wavelet.balchrom);
chromfi->setDefault(defParams->wavelet.chromfi);
chromco->setDefault(defParams->wavelet.chromco);
@@ -2155,6 +2164,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit
mergeC->setDefaultEditedState(pedited->wavelet.mergeC ? Edited : UnEdited);
softrad->setDefaultEditedState(pedited->wavelet.softrad ? Edited : UnEdited);
softradend->setDefaultEditedState(pedited->wavelet.softradend ? Edited : UnEdited);
+ ballum->setDefaultEditedState(pedited->wavelet.ballum ? Edited : UnEdited);
balchrom->setDefaultEditedState(pedited->wavelet.balchrom ? Edited : UnEdited);
chromfi->setDefaultEditedState(pedited->wavelet.chromfi ? Edited : UnEdited);
chromco->setDefaultEditedState(pedited->wavelet.chromco ? Edited : UnEdited);
@@ -2951,6 +2961,8 @@ void Wavelet::adjusterChanged(Adjuster* a, double newval)
listener->panelChanged(EvWavgreenhigh, greenhigh->getTextValue());
} else if (a == bluehigh) {
listener->panelChanged(EvWavbluehigh, bluehigh->getTextValue());
+ } else if (a == ballum) {
+ listener->panelChanged(EvWavballum, ballum->getTextValue());
} else if (a == balchrom) {
listener->panelChanged(EvWavbalchrom, balchrom->getTextValue());
} else if (a == chromfi) {
diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h
index 07d2432ac..d1b4bb7c3 100644
--- a/rtgui/wavelet.h
+++ b/rtgui/wavelet.h
@@ -70,6 +70,7 @@ public:
private:
rtengine::ProcEvent EvWavenaclari;
rtengine::ProcEvent EvWavushamet;
+ rtengine::ProcEvent EvWavballum;
rtengine::ProcEvent EvWavbalchrom;
rtengine::ProcEvent EvWavchromfi;
rtengine::ProcEvent EvWavchromco;
@@ -244,6 +245,7 @@ private:
Adjuster* const edgedetectthr2;
Adjuster* const edgesensi;
Adjuster* const edgeampli;
+ Adjuster* const ballum;
Adjuster* const balchrom;
Adjuster* const chromfi;
Adjuster* const chromco;