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;