diff --git a/rtdata/languages/default b/rtdata/languages/default index 856201db6..55f987422 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -844,6 +844,7 @@ HISTORY_MSG_595;Local - Noise Scope HISTORY_MSG_597;Local L*a*b* HISTORY_MSG_598;Local - Bottom HISTORY_MSG_599;Local - Noise bilateral +HISTORY_MSG_600;Local - Noise Equal. Black-White HISTORY_MSG_LOCALCONTRAST_AMOUNT;Local Contrast - Amount HISTORY_MSG_LOCALCONTRAST_DARKNESS;Local Contrast - Darkness HISTORY_MSG_LOCALCONTRAST_ENABLED;Local Contrast @@ -1854,6 +1855,7 @@ TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To be active, you must check button 'Enable curves' TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) has the same algorithm than slider lightness.\n'Super' the curve L=f(L) has an new improved algorithm, which can leeds in some cases to artifacts. TP_LOCALLAB_EXCLUF;Excluding +TP_LOCALLAB_EXCLUF_TOOLTIP;Can be used to exclude this part of datas - move Scope to extend color.\n You can apply all settings to this RT-spot. TP_LOCALLAB_SENSIDEN;Scope TP_LOCALLAB_SENSIEXCLU;Scope TP_LOCALLAB_SENSIEXCLU_TOOLTIP;Adjust color to include in exclusion! @@ -1866,9 +1868,11 @@ TP_LOCALLAB_EXPOSE;Exposure TP_LOCALLAB_NOISELUMFINE;Luminance fine (Wav) TP_LOCALLAB_NOISELUMCOARSE;Luminance coarse (Wav) TP_LOCALLAB_NOISELUMDETAIL;Luminance detail (DCT) +TP_LOCALLAB_NOISELEQUAL;Equalizer black-white TP_LOCALLAB_NOISECHROFINE;Chroma fine (Wav) TP_LOCALLAB_NOISECHROCOARSE;Chroma coarse (Wav) TP_LOCALLAB_NOISECHRODETAIL;Chroma detail (DCT) +TP_LOCALLAB_NOISECHROC_TOOLTIP;If superior to zero, high quality algorithm is enabled.\nCoarse is for slider >=2 TP_LOCALLAB_QUAL_METHOD;Global quality TP_LOCALLAB_QUALCURV_METHOD;Curves type TP_LOCALLAB_GAM;Gamma diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index 25c5a506a..7ded3bf25 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -782,6 +782,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #ifdef _RT_NESTED_OPENMP denoiseNestedLevels = omp_get_max_threads() / numthreads; bool oldNested = omp_get_nested(); + if (denoiseNestedLevels < 2) { denoiseNestedLevels = 1; } else { @@ -1193,7 +1194,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef memoryAllocationFailed = true; } } else { /*if (nrQuality==QUALITY_HIGH)*/ - if (!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb)) { //enhance mode + if (!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, nullptr, 0, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb, denoiseNestedLevels)) { //enhance mode memoryAllocationFailed = true; } @@ -1230,7 +1231,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef memoryAllocationFailed = true; } } else { /*if (nrQuality==QUALITY_HIGH)*/ - if (!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb)) { //enhance mode + if (!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, nullptr, 0, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb, denoiseNestedLevels)) { //enhance mode memoryAllocationFailed = true; } @@ -1266,7 +1267,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef memoryAllocationFailed = true; } } else { /*if (nrQuality==QUALITY_HIGH)*/ - if (!WaveletDenoiseAll_BiShrinkL(*Ldecomp, noisevarlum, madL)) { //enhance mode + if (!WaveletDenoiseAll_BiShrinkL(*Ldecomp, noisevarlum, madL, nullptr, edge, denoiseNestedLevels)) { //enhance mode memoryAllocationFailed = true; } @@ -2043,7 +2044,6 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef SSEFUNCTION void ImProcFunctions::RGBtile_denoise(float * fLblox, int hblproc, float noisevar_Ldetail, float * nbrwt, float * blurbuffer) //for DCT { int blkstart = hblproc * TS * TS; - boxabsblur(fLblox + blkstart, nbrwt, 3, 3, TS, TS, blurbuffer); //blur neighbor weights for more robust estimation //for DCT #ifdef __SSE2__ @@ -2251,11 +2251,19 @@ void ImProcFunctions::Noise_residualAB(wavelet_decomposition &WaveletCoeffs_ab, chmaxresid = maxresid; } -SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3]) +SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge, int denoiseNestedLevels) { int maxlvl = min(WaveletCoeffs_L.maxlevel(), 5); const float eps = 0.01f; + if (edge == 1 || edge == 3) { + maxlvl = 4; //for refine denoise edge wavelet + } + + if (edge == 2) { + maxlvl = 7; //for locallab denoise + } + int maxWL = 0, maxHL = 0; for (int lvl = 0; lvl < maxlvl; ++lvl) { @@ -2266,6 +2274,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit if (WaveletCoeffs_L.level_H(lvl) > maxHL) { maxHL = WaveletCoeffs_L.level_H(lvl); } + } bool memoryAllocationFailed = false; @@ -2273,12 +2282,13 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit #pragma omp parallel num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif { - float *buffer[3]; + float *buffer[4]; buffer[0] = new (std::nothrow) float[maxWL * maxHL + 32]; buffer[1] = new (std::nothrow) float[maxWL * maxHL + 64]; buffer[2] = new (std::nothrow) float[maxWL * maxHL + 96]; + buffer[3] = new (std::nothrow) float[maxWL * maxHL + 128]; - if (buffer[0] == nullptr || buffer[1] == nullptr || buffer[2] == nullptr) { + if (buffer[0] == nullptr || buffer[1] == nullptr || buffer[2] == nullptr || buffer[3] == nullptr) { memoryAllocationFailed = true; } @@ -2296,15 +2306,54 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); if (lvl == maxlvl - 1) { - int edge = 0; - ShrinkAllL(WaveletCoeffs_L, buffer, lvl, dir, noisevarlum, madL[lvl], nullptr, edge); - } else { + // int edge = 0; + ShrinkAllL(WaveletCoeffs_L, buffer, lvl, dir, noisevarlum, madL[lvl], vari, edge); + } else { //simple wavelet shrinkage float * sfave = buffer[0] + 32; - float * sfaved = buffer[2] + 96; - float * blurBuffer = buffer[1] + 64; + float * sfaved = buffer[1] + 64; + float * blurBuffer = buffer[2] + 96; float mad_Lr = madL[lvl][dir - 1]; + /* + if ((edge == 1 || edge == 2 || edge == 3) && vari) { + noisevarlum = blurBuffer; // we need one buffer, but fortunately we don't have to allocate a new one because we can use blurBuffer + + for (int i = 0; i < Wlvl_L * Hlvl_L; ++i) { + noisevarlum[i] = vari[lvl]; + } + } + */ + float *nvl = nullptr; + nvl = new float[Hlvl_L * Wlvl_L]; + + for (int i = 0; i < Hlvl_L * Wlvl_L; ++i) { + nvl[i] = 0.f; + } + + if ((edge == 1 || edge == 2 || edge == 3) && vari) { + // nvl = blurBuffer; // we need one buffer, but fortunately we don't have to allocate a new one because we can use blurBuffer + if ((edge == 1 || edge == 3)) { + for (int i = 0; i < Hlvl_L * Wlvl_L; ++i) { + nvl[i] = vari[lvl]; + } + } + + if (edge == 2) { + for (int i = 0; i < Hlvl_L * Wlvl_L; ++i) { + nvl[i] = vari[lvl] * SQR(noisevarlum[i]); + } + } + + } + + else { + for (int i = 0; i < Hlvl_L * Wlvl_L; ++i) { + nvl[i] = noisevarlum[i]; + } + + } + float levelFactor = mad_Lr * 5.f / (lvl + 1); #ifdef __SSE2__ @@ -2316,14 +2365,14 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit int coeffloc_L; for (coeffloc_L = 0; coeffloc_L < Hlvl_L * Wlvl_L - 3; coeffloc_L += 4) { - mad_Lv = LVFU(noisevarlum[coeffloc_L]) * levelFactorv; + mad_Lv = LVFU(nvl[coeffloc_L]) * levelFactorv; mag_Lv = SQRV(LVFU(WavCoeffs_L[dir][coeffloc_L])); _mm_storeu_ps(&sfave[coeffloc_L], mag_Lv / (mag_Lv + mad_Lv * xexpf(-mag_Lv / (mad_Lv * ninev)) + epsv)); } for (; coeffloc_L < Hlvl_L * Wlvl_L; ++coeffloc_L) { float mag_L = SQR(WavCoeffs_L[dir][coeffloc_L]); - sfave[coeffloc_L] = mag_L / (mag_L + levelFactor * noisevarlum[coeffloc_L] * xexpf(-mag_L / (9.f * levelFactor * noisevarlum[coeffloc_L])) + eps); + sfave[coeffloc_L] = mag_L / (mag_L + levelFactor * nvl[coeffloc_L] * xexpf(-mag_L / (9.f * levelFactor * nvl[coeffloc_L])) + eps); } #else @@ -2333,7 +2382,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit int coeffloc_L = i * Wlvl_L + j; float mag_L = SQR(WavCoeffs_L[dir][coeffloc_L]); - sfave[coeffloc_L] = mag_L / (mag_L + levelFactor * noisevarlum[coeffloc_L] * xexpf(-mag_L / (9.f * levelFactor * noisevarlum[coeffloc_L])) + eps); + sfave[coeffloc_L] = mag_L / (mag_L + levelFactor * nvl[coeffloc_L] * xexpf(-mag_L / (9.f * levelFactor * nvl[coeffloc_L])) + eps); } } @@ -2369,12 +2418,14 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit } #endif + delete [] nvl; } + } } } - for (int i = 2; i >= 0; i--) { + for (int i = 3; i >= 0; i--) { if (buffer[i] != nullptr) { delete[] buffer[i]; } @@ -2384,11 +2435,20 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit return (!memoryAllocationFailed); } -SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, - float *noisevarchrom, float madL[8][3], float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb) + +SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels) + { int maxlvl = WaveletCoeffs_L.maxlevel(); + if (local == 2) { + maxlvl = 7; //for local denoise + } + + if (local == 3) { + maxlvl = 4; //for shape detection + } + if (autoch && noisevar_ab <= 0.001f) { noisevar_ab = 0.02f; } @@ -2459,11 +2519,33 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi ShrinkAllAB(WaveletCoeffs_L, WaveletCoeffs_ab, buffer, lvl, dir, noisevarchrom, noisevar_ab, useNoiseCCurve, autoch, denoiseMethodRgb, madL[lvl], nullptr, 0, madab[lvl], true); } else { //simple wavelet shrinkage + float noisevarfc; float mad_Lr = madL[lvl][dir - 1]; - float mad_abr = useNoiseCCurve ? noisevar_ab * madab[lvl][dir - 1] : SQR(noisevar_ab) * madab[lvl][dir - 1]; + float *nvc = nullptr; + nvc = new float[Hlvl_ab * Wlvl_ab]; - if (noisevar_ab > 0.001f) { + if ((local == 2 || local == 3) && variC && useNoiseCCurve) { + noisevarfc = variC[lvl]; + + for (int p = 0; p < Hlvl_ab * Wlvl_ab; p++) { + nvc[p] = 10.f * sqrt(variC[lvl]) * SQR(1.f + 4.f * noisevarchrom[p]); + } + + } else { + noisevarfc = noisevar_ab; + + for (int p = 0; p < Hlvl_ab * Wlvl_ab; p++) { + nvc[p] = noisevarchrom[p]; + } + + } + + + // float mad_abr = useNoiseCCurve ? noisevar_ab * madab[lvl][dir - 1] : SQR(noisevar_ab) * madab[lvl][dir - 1]; + float mad_abr = useNoiseCCurve ? noisevarfc * madab[lvl][dir - 1] : SQR(noisevarfc) * madab[lvl][dir - 1]; + + if (noisevarfc > 0.001f) { #ifdef __SSE2__ __m128 onev = _mm_set1_ps(1.f); @@ -2475,7 +2557,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi int coeffloc_ab; for (coeffloc_ab = 0; coeffloc_ab < Hlvl_ab * Wlvl_ab - 3; coeffloc_ab += 4) { - mad_abv = LVFU(noisevarchrom[coeffloc_ab]) * mad_abrv; + mad_abv = LVFU(nvc[coeffloc_ab]) * mad_abrv; tempabv = LVFU(WavCoeffs_ab[dir][coeffloc_ab]); mag_Lv = LVFU(WavCoeffs_L[dir][coeffloc_ab]); @@ -2488,7 +2570,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi for (; coeffloc_ab < Hlvl_ab * Wlvl_ab; ++coeffloc_ab) { float mag_L = SQR(WavCoeffs_L[dir][coeffloc_ab ]); float mag_ab = SQR(WavCoeffs_ab[dir][coeffloc_ab]); - WavCoeffs_ab[dir][coeffloc_ab] *= SQR(1.f - xexpf(-(mag_ab / (noisevarchrom[coeffloc_ab] * mad_abr)) - (mag_L / (9.f * mad_Lr)))/*satfactor_a*/); + WavCoeffs_ab[dir][coeffloc_ab] *= SQR(1.f - xexpf(-(mag_ab / (nvc[coeffloc_ab] * mad_abr)) - (mag_L / (9.f * mad_Lr)))/*satfactor_a*/); }//now chrominance coefficients are denoised #else @@ -2500,7 +2582,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi float mag_L = SQR(WavCoeffs_L[dir][coeffloc_ab ]); float mag_ab = SQR(WavCoeffs_ab[dir][coeffloc_ab]); - WavCoeffs_ab[dir][coeffloc_ab] *= SQR(1.f - xexpf(-(mag_ab / (noisevarchrom[coeffloc_ab] * mad_abr)) - (mag_L / (9.f * mad_Lr)))/*satfactor_a*/); + WavCoeffs_ab[dir][coeffloc_ab] *= SQR(1.f - xexpf(-(mag_ab / (nvc[coeffloc_ab] * mad_abr)) - (mag_L / (9.f * mad_Lr)))/*satfactor_a*/); } }//now chrominance coefficients are denoised @@ -2508,9 +2590,12 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi #endif } + delete [] nvc; + } } } + } for (int i = 2; i >= 0; i--) { @@ -2668,17 +2753,66 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeff int H_L = WaveletCoeffs_L.level_H(level); float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(level); -// printf("OK lev=%d\n",level); float mad_L = madL[dir - 1] ; - if ((edge == 1 || edge == 2 || edge == 3) && vari) { - noisevarlum = blurBuffer; // we need one buffer, but fortunately we don't have to allocate a new one because we can use blurBuffer + float *nvl = nullptr; + nvl = new float[ H_L * W_L]; - for (int i = 0; i < W_L * H_L; ++i) { - noisevarlum[i] = vari[level]; - } + for (int i = 0; i < W_L * H_L; ++i) { + nvl[i] = 0.f; } + if ((edge == 1 || edge == 2 || edge == 3) && vari) { + // nvl = blurBuffer; // we need one buffer, but fortunately we don't have to allocate a new one because we can use blurBuffer + if ((edge == 1 || edge == 3)) { + for (int i = 0; i < W_L * H_L; ++i) { + nvl[i] = vari[level]; //* SQR(1.f + 4.f * noisevarchrom[p]); + } + } + + if (edge == 2) { + for (int i = 0; i < W_L * H_L; ++i) { + nvl[i] = vari[level] * SQR(noisevarlum[i]); + } + } + + } + + else { + for (int i = 0; i < W_L * H_L; ++i) { + nvl[i] = noisevarlum[i]; + } + + } + + /* + float kinterm = epsi + noiseLCurve[xdivf(LLum, 15) * 500.f]; + kinterm *= 100.f; + kinterm += noiseluma; + lumcalc[ii][jj] = SQR((kinterm / 125.f) * (1.f + kinterm / 25.f)); + + //TO DO perhaps needs ci=urve for L ?? ==> same as in shrinkallab + float noisevarfc; + + float *nvc = nullptr; + nvc = new float[ H_ab * W_ab]; + + if ((local == 2 || local == 3) && variC && useNoiseCCurve) { + noisevarfc = variC[level]; + + for (int p = 0; p < H_ab * W_ab; p++) { + nvc[p] = 10.f * sqrt(variC[level]) * SQR(1.f + 4.f * noisevarchrom[p]); + } + + } else { + noisevarfc = noisevar_ab; + + for (int p = 0; p < H_ab * W_ab; p++) { + nvc[p] = noisevarchrom[p]; + } + + } + */ float levelFactor = mad_L * 5.f / static_cast(level + 1); #ifdef __SSE2__ __m128 magv; @@ -2689,7 +2823,7 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeff int i; for (i = 0; i < W_L * H_L - 3; i += 4) { - mad_Lv = LVFU(noisevarlum[i]) * levelFactorv; + mad_Lv = LVFU(nvl[i]) * levelFactorv; magv = SQRV(LVFU(WavCoeffs_L[dir][i])); _mm_storeu_ps(&sfave[i], magv / (magv + mad_Lv * xexpf(-magv / (ninev * mad_Lv)) + epsv)); } @@ -2697,7 +2831,7 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeff // few remaining pixels for (; i < W_L * H_L; ++i) { float mag = SQR(WavCoeffs_L[dir][i]); - sfave[i] = mag / (mag + levelFactor * noisevarlum[i] * xexpf(-mag / (9 * levelFactor * noisevarlum[i])) + eps); + sfave[i] = mag / (mag + levelFactor * nvl[i] * xexpf(-mag / (9 * levelFactor * nvl[i])) + eps); } #else @@ -2705,12 +2839,13 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeff for (int i = 0; i < W_L * H_L; ++i) { float mag = SQR(WavCoeffs_L[dir][i]); - float shrinkfactor = mag / (mag + levelFactor * noisevarlum[i] * xexpf(-mag / (9 * levelFactor * noisevarlum[i])) + eps); + float shrinkfactor = mag / (mag + levelFactor * nvl[i] * xexpf(-mag / (9 * levelFactor * nvl[i])) + eps); sfave[i] = shrinkfactor; } #endif boxblur(sfave, sfaved, blurBuffer, level + 2, level + 2, W_L, H_L); //increase smoothness by locally averaging shrinkage + delete [] nvl; #ifdef __SSE2__ __m128 sfv; @@ -2743,8 +2878,8 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeff } -SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float **buffer, int level, int dir, - float *noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, +SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition & WaveletCoeffs_L, wavelet_decomposition & WaveletCoeffs_ab, float **buffer, int level, int dir, + float * noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, float * madL, float * variC, int local, float * madaab, bool madCalculated) { @@ -2780,18 +2915,26 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoef float noisevarfc; + float *nvc = nullptr; + nvc = new float[ H_ab * W_ab]; if ((local == 2 || local == 3) && variC && useNoiseCCurve) { noisevarfc = variC[level]; for (int p = 0; p < H_ab * W_ab; p++) { - noisevarchrom[p] = variC[level] * SQR(1.f + 4.f * noisevarchrom[p]); + nvc[p] = 10.f * sqrt(variC[level]) * SQR(1.f + 4.f * noisevarchrom[p]); } } else { noisevarfc = noisevar_ab; + + for (int p = 0; p < H_ab * W_ab; p++) { + nvc[p] = noisevarchrom[p]; + } + } +// printf("varfc=%f nvc0=%f nvc1=%f nvc2=%f\n", noisevarfc, nvc[10], nvc[H_ab * W_ab /3], nvc[H_ab * W_ab /2]); if (noisevarfc > 0.001f) {//noisevar_ab //madab = useNoiseCCurve ? madab : madab * noisevar_ab; madab = useNoiseCCurve ? madab : madab * noisevarfc; @@ -2805,7 +2948,7 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoef int coeffloc_ab; for (coeffloc_ab = 0; coeffloc_ab < H_ab * W_ab - 3; coeffloc_ab += 4) { - mad_abv = LVFU(noisevarchrom[coeffloc_ab]) * mad_abrv; + mad_abv = LVFU(nvc[coeffloc_ab]) * mad_abrv; mag_Lv = LVFU(WavCoeffs_L[dir][coeffloc_ab]); mag_abv = SQRV(LVFU(WavCoeffs_ab[dir][coeffloc_ab])); @@ -2817,7 +2960,7 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoef for (; coeffloc_ab < H_ab * W_ab; ++coeffloc_ab) { float mag_L = SQR(WavCoeffs_L[dir][coeffloc_ab]); float mag_ab = SQR(WavCoeffs_ab[dir][coeffloc_ab]); - sfaveab[coeffloc_ab] = (1.f - xexpf(-(mag_ab / (noisevarchrom[coeffloc_ab] * madab)) - (mag_L / (9.f * mad_L)))); + sfaveab[coeffloc_ab] = (1.f - xexpf(-(mag_ab / (nvc[coeffloc_ab] * madab)) - (mag_L / (9.f * mad_L)))); }//now chrominance coefficients are denoised #else @@ -2827,7 +2970,7 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoef int coeffloc_ab = i * W_ab + j; float mag_L = SQR(WavCoeffs_L[dir][coeffloc_ab]); float mag_ab = SQR(WavCoeffs_ab[dir][coeffloc_ab]); - sfaveab[coeffloc_ab] = (1.f - xexpf(-(mag_ab / (noisevarchrom[coeffloc_ab] * madab)) - (mag_L / (9.f * mad_L)))); + sfaveab[coeffloc_ab] = (1.f - xexpf(-(mag_ab / (nvc[coeffloc_ab] * madab)) - (mag_L / (9.f * mad_L)))); } }//now chrominance coefficients are denoised @@ -2871,12 +3014,13 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoef #endif } + delete [] nvc; } SSEFUNCTION void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** WavCoeffs_b, - int W_ab, int H_ab, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, - float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, int schoice, int lvl, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, - float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb) + int W_ab, int H_ab, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float & chaut, int &Nb, float & redaut, float & blueaut, + float & maxredaut, float & maxblueaut, float & minredaut, float & minblueaut, int schoice, int lvl, float & chromina, float & sigma, float & lumema, float & sigma_L, float & redyel, float & skinc, float & nsknc, + float & maxchred, float & maxchblue, float & minchred, float & minchblue, int &nb, float & chau, float & chred, float & chblue, bool denoiseMethodRgb) { //simple wavelet shrinkage @@ -2991,9 +3135,9 @@ SSEFUNCTION void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** } -void ImProcFunctions::WaveletDenoiseAll_info(int levwav, wavelet_decomposition &WaveletCoeffs_a, - wavelet_decomposition &WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, int schoice, - float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb) +void ImProcFunctions::WaveletDenoiseAll_info(int levwav, wavelet_decomposition & WaveletCoeffs_a, + wavelet_decomposition & WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float & chaut, int &Nb, float & redaut, float & blueaut, float & maxredaut, float & maxblueaut, float & minredaut, float & minblueaut, int schoice, + float & chromina, float & sigma, float & lumema, float & sigma_L, float & redyel, float & skinc, float & nsknc, float & maxchred, float & maxchblue, float & minchred, float & minchblue, int &nb, float & chau, float & chred, float & chblue, bool denoiseMethodRgb) { int maxlvl = levwav; @@ -3013,7 +3157,7 @@ void ImProcFunctions::WaveletDenoiseAll_info(int levwav, wavelet_decomposition & } } -SSEFUNCTION void ImProcFunctions::RGB_denoise_infoGamCurve(const procparams::DirPyrDenoiseParams & dnparams, bool isRAW, LUTf &gamcurve, float &gam, float &gamthresh, float &gamslope) +SSEFUNCTION void ImProcFunctions::RGB_denoise_infoGamCurve(const procparams::DirPyrDenoiseParams & dnparams, bool isRAW, LUTf & gamcurve, float & gam, float & gamthresh, float & gamslope) { gam = dnparams.gamma; gamthresh = 0.001f; @@ -3036,7 +3180,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_infoGamCurve(const procparams::Dir } } -void ImProcFunctions::calcautodn_info(float &chaut, float &delta, int Nb, int levaut, float maxmax, float lumema, float chromina, int mode, int lissage, float redyel, float skinc, float nsknc) +void ImProcFunctions::calcautodn_info(float & chaut, float & delta, int Nb, int levaut, float maxmax, float lumema, float chromina, int mode, int lissage, float redyel, float skinc, float nsknc) { float reducdelta = 1.f; @@ -3178,7 +3322,7 @@ void ImProcFunctions::calcautodn_info(float &chaut, float &delta, int Nb, int le } -SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat * provicalc, const bool isRAW, LUTf &gamcurve, float gam, float gamthresh, float gamslope, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, bool multiThread) +SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat * provicalc, const bool isRAW, LUTf & gamcurve, float gam, float gamthresh, float gamslope, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, float & chaut, int &Nb, float & redaut, float & blueaut, float & maxredaut, float & maxblueaut, float & minredaut, float & minblueaut, float & chromina, float & sigma, float & lumema, float & sigma_L, float & redyel, float & skinc, float & nsknc, bool multiThread) { if ((settings->leveldnautsimpl == 1 && dnparams.Cmethod == "MAN") || (settings->leveldnautsimpl == 0 && dnparams.C2method == "MANU")) { //nothing to do diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index a2f94185c..0d5cc1c64 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -1206,6 +1206,7 @@ void Crop::update(int todo) } params.locallab.bilateral = parent->bilaterals[sp]; + params.locallab.noiselequal = parent->noiselequals[sp]; std::vector cretie; @@ -1681,6 +1682,7 @@ void Crop::update(int todo) } parent->bilaterals[sp] = params.locallab.bilateral = parent->bilaterals[0]; + parent->noiselequals[sp] = params.locallab.noiselequal = parent->noiselequals[0]; std::vector ccret; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 03e81266f..551629c0c 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -156,6 +156,7 @@ ImProcCoordinator::ImProcCoordinator() noiselumfs(500, -10000), noiselumcs(500, -10000), noiselumdetails(500, -10000), + noiselequals(500, -10000), noisechrodetails(500, -10000), bilaterals(500, -10000), sensidens(500, -10000), @@ -874,7 +875,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) }; - int maxdata = 100; //99 10021 // 90 10020 //88 10019//87 10018 //86 10017 //85 10016;// 82 10015//78;//73 for 10011 + int maxdata = 101; //100 10022 //99 10021 // 90 10020 //88 10019//87 10018 //86 10017 //85 10016;// 82 10015//78;//73 for 10011 if (fic0) { //find current version mip @@ -918,7 +919,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) //initilize newues when first utilisation of Locallab. Prepare creation of Mip files for (int sp = 1; sp < maxspot; sp++) { // spots default int t_sp = sp; - int t_mipversion = 10022;//new value for each change + int t_mipversion = 10023;//new value for each change int t_circrad = 18; int t_locX = 250; int t_locY = 250; @@ -1060,6 +1061,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) int t_expsharp = 0; int t_expcbdl = 0; int t_expexpose = 0; + //10023 + int t_noiselequal = 7; //all variables except locRETgainCurve 'coomon for all) fic << "Mipversion=" << t_mipversion << '@' << endl; @@ -1168,6 +1171,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) fic << "Expexpose=" << t_expexpose << '@' << endl; fic << "Bilateral=" << t_bilateral << '@' << endl; + fic << "Noiselequal=" << t_noiselequal << '@' << endl; fic << "curveReti=" << t_curvret << '@' << endl; fic << "curveLL=" << t_curvll << '@' << endl; @@ -1479,6 +1483,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) } dataspot[94][0] = bilaterals[0] = params.locallab.bilateral; + dataspot[95][0] = noiselequals[0] = params.locallab.noiselequal; // for all curves work around - I do not know how to do with params curves... //curve Reti local @@ -1785,6 +1790,10 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) maxind = 92; } + if (versionmip == 10022) { + maxind = 93; + } + while (getline(fich, line)) { spotline = line; std::size_t pos = spotline.find("="); @@ -2045,6 +2054,13 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) } } + if (versionmip <= 10022) {// + for (int sp = 1; sp < maxspot; sp++) { // spots default + dataspot[95][sp] = 7; + + } + } + //here we change the number of spot if (ns < (maxspot - 1)) { @@ -2053,7 +2069,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) for (int sp = ns + 1 ; sp < maxspot; sp++) { // spots default int t_sp = sp; - int t_mipversion = 10022; + int t_mipversion = 10023; int t_circrad = 18; int t_locX = 250; int t_locY = 250; @@ -2188,6 +2204,9 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) //10022 int t_bilateral = 0; + //10023 + int t_noiselequal = 7; + fic << "Mipversion=" << t_mipversion << '@' << endl; fic << "Spot=" << t_sp << '@' << endl; fic << "Circrad=" << t_circrad << '@' << endl; @@ -2291,6 +2310,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) fic << "Expexpose=" << t_expexpose << '@' << endl; fic << "Bilateral=" << t_bilateral << '@' << endl; + fic << "Noiselequal=" << t_noiselequal << '@' << endl; fic << "curveReti=" << t_curvret << '@' << endl; fic << "curveLL=" << t_curvll << '@' << endl; @@ -2718,6 +2738,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) } params.locallab.bilateral = bilaterals[sp] = dataspot[94][sp]; + params.locallab.noiselequal = noiselequals[sp] = dataspot[95][sp]; int *s_datc; s_datc = new int[70]; @@ -3358,6 +3379,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) } dataspot[94][sp] = bilaterals[sp] = params.locallab.bilateral = dataspot[94][0]; + dataspot[95][sp] = noiselequals[sp] = params.locallab.noiselequal = dataspot[95][0]; int *s_datc; s_datc = new int[70]; @@ -3598,7 +3620,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) for (int spe = 1; spe < maxspot; spe++) { int t_sp = spe; - int t_mipversion = 10022; + int t_mipversion = 10023; int t_circrad = dataspot[2][spe]; int t_locX = dataspot[3][spe]; int t_locY = dataspot[4][spe]; @@ -3701,6 +3723,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) int t_expexpose = dataspot[93][spe]; int t_bilateral = dataspot[94][spe]; + int t_noiselequal = dataspot[95][spe]; int t_huerefblur = dataspot[maxdata - 5][spe]; int t_hueref = dataspot[maxdata - 4][spe]; @@ -3822,6 +3845,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, Crop* cropCall) fou << "Expexpose=" << t_expexpose << '@' << endl; fou << "Bilateral=" << t_bilateral << '@' << endl; + fou << "Noiselequal=" << t_noiselequal << '@' << endl; fou << "huerefblur=" << t_huerefblur << '@' << endl; fou << "hueref=" << t_hueref << '@' << endl; diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index bd91316d9..7f20d60c8 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -307,6 +307,7 @@ protected: LUTi noiselumfs; LUTi noiselumcs; LUTi noiselumdetails; + LUTi noiselequals; LUTi noisechrodetails; LUTi bilaterals; LUTi sensidens; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 1a2abce58..1055a5241 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -367,13 +367,13 @@ public: void RGBoutput_tile_row(float *bloxrow_L, float ** Ldetail, float ** tilemask_out, int height, int width, int top); bool WaveletDenoiseAllL(wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge, int denoiseNestedLevels); bool WaveletDenoiseAllAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels); + bool WaveletDenoiseAll_BiShrinkAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels); + void WaveletDenoiseAll_info(int levwav, wavelet_decomposition &WaveletCoeffs_a, wavelet_decomposition &WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float & minblueaut, int schoice, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb); - bool WaveletDenoiseAll_BiShrinkL(wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3]); - bool WaveletDenoiseAll_BiShrinkAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, - const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb); + bool WaveletDenoiseAll_BiShrinkL(wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge, int denoiseNestedLevels); void ShrinkAllL(wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madL, float * vari, int edge); void ShrinkAllAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float **buffer, int level, int dir, float *noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, float * madL, float * variC, int local, float * madaab = nullptr, bool madCalculated = false); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index abe1433e6..4940c8ed6 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -50,7 +50,7 @@ #define cliploc( val, minv, maxv ) (( val = (val < minv ? minv : val ) ) > maxv ? maxv : val ) -#define TSD 64 // Tile size +#define TS 64 // Tile size #define offset 25 // shift between tiles #define fTS ((TS/2+1)) // second dimension of Fourier tiles #define blkrad 1 // radius of block averaging @@ -66,6 +66,8 @@ #define CLIPRET(x) LIM(x,-99.5f, 99.5f) #define CLIP1(x) LIM(x, 0.f, 1.f) #pragma GCC diagnostic warning "-Wextra" + + namespace { @@ -107,7 +109,12 @@ float calcLocalFactorinv (const float lox, const float loy, const float lcx, con } namespace rtengine + + { +extern MyMutex *fftwMutex; + + using namespace procparams; @@ -144,6 +151,7 @@ struct local_params { int blurmet; float noiself; float noiseldetail; + int noiselequal; float noisechrodetail; float bilat; float noiselc; @@ -379,14 +387,15 @@ static void calcLocalParams(int oW, int oH, const LocallabParams& locallab, stru lp.excmet = 1; } - float local_noiself = locallab.noiselumf; - float local_noiselc = locallab.noiselumc; + float local_noiself = (float)locallab.noiselumf; + float local_noiselc = (float)locallab.noiselumc; float local_noiseldetail = locallab.noiselumdetail; + int local_noiselequal = locallab.noiselequal; float local_noisechrodetail = locallab.noisechrodetail; int local_sensiden = locallab.sensiden; - float local_noisecf = locallab.noisechrof; - float local_noisecc = locallab.noisechroc; + float local_noisecf = ((float)locallab.noisechrof) / 10.f; + float local_noisecc = ((float)locallab.noisechroc) / 10.f; float multi[5]; for (int y = 0; y < 5; y++) { @@ -468,6 +477,7 @@ static void calcLocalParams(int oW, int oH, const LocallabParams& locallab, stru lp.thr = thre; lp.noiself = local_noiself; lp.noiseldetail = local_noiseldetail; + lp.noiselequal = local_noiselequal; lp.noisechrodetail = local_noisechrodetail; lp.noiselc = local_noiselc; lp.noisecf = local_noisecf; @@ -1667,7 +1677,7 @@ void ImProcFunctions::exlabLocal(const local_params& lp, int bfh, int bfw, LabIm const float hlrange = maxran - shoulder; -#define TS 112 +#define TSE 112 #ifdef _OPENMP #pragma omp parallel if (multiThread) @@ -1675,13 +1685,13 @@ void ImProcFunctions::exlabLocal(const local_params& lp, int bfh, int bfw, LabIm { char *buffer; - buffer = (char *) malloc(3 * sizeof(float) * TS * TS + 20 * 64 + 63); + buffer = (char *) malloc(3 * sizeof(float) * TSE * TSE + 20 * 64 + 63); char *data; data = (char*)((uintptr_t (buffer) + uintptr_t (63)) / 64 * 64); float *Ltemp = (float (*))data; - float *atemp = (float (*))((char*)Ltemp + sizeof(float) * TS * TS + 4 * 64); - float *btemp = (float (*))((char*)atemp + sizeof(float) * TS * TS + 8 * 64); + float *atemp = (float (*))((char*)Ltemp + sizeof(float) * TSE * TSE + 4 * 64); + float *btemp = (float (*))((char*)atemp + sizeof(float) * TSE * TSE + 8 * 64); int istart; int jstart; int tW; @@ -1691,20 +1701,20 @@ void ImProcFunctions::exlabLocal(const local_params& lp, int bfh, int bfw, LabIm #pragma omp for schedule(dynamic) collapse(2) #endif - for (int ii = 0; ii < bfh; ii += TS) - for (int jj = 0; jj < bfw; jj += TS) { + for (int ii = 0; ii < bfh; ii += TSE) + for (int jj = 0; jj < bfw; jj += TSE) { istart = ii; jstart = jj; - tH = min(ii + TS, bfh); - tW = min(jj + TS, bfw); + tH = min(ii + TSE, bfh); + tW = min(jj + TSE, bfw); for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { - Ltemp[ti * TS + tj] = 2.f * bufexporig->L[i][j]; - atemp[ti * TS + tj] = bufexporig->a[i][j]; - btemp[ti * TS + tj] = bufexporig->b[i][j];; + Ltemp[ti * TSE + tj] = 2.f * bufexporig->L[i][j]; + atemp[ti * TSE + tj] = bufexporig->a[i][j]; + btemp[ti * TSE + tj] = bufexporig->b[i][j];; } } @@ -1714,25 +1724,25 @@ void ImProcFunctions::exlabLocal(const local_params& lp, int bfh, int bfw, LabIm for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { - float L = Ltemp[ti * TS + tj]; + float L = Ltemp[ti * TSE + tj]; // float a = atemp[ti * TS + tj]; // float b = btemp[ti * TS + tj]; float tonefactor = (L < MAXVALF ? hltonecurve[L] : CurveFactory::hlcurveloc(exp_scale, comp, hlrange, L, niv)); - Ltemp[ti * TS + tj] = L * tonefactor; + Ltemp[ti * TSE + tj] = L * tonefactor; } } for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { - float L = Ltemp[ti * TS + tj]; + float L = Ltemp[ti * TSE + tj]; // float a = atemp[ti * TS + tj]; // float b = btemp[ti * TS + tj]; //shadow tone curve float Y = L; float tonefactor = shtonecurve[Y]; - Ltemp[ti * TS + tj] = Ltemp[ti * TS + tj] * tonefactor; + Ltemp[ti * TSE + tj] = Ltemp[ti * TSE + tj] * tonefactor; } } @@ -1740,7 +1750,7 @@ void ImProcFunctions::exlabLocal(const local_params& lp, int bfh, int bfw, LabIm for (int j = jstart, tj = 0; j < tW; j++, tj++) { //brightness/contrast - Ltemp[ti * TS + tj] = tonecurve[Ltemp[ti * TS + tj] ]; + Ltemp[ti * TSE + tj] = tonecurve[Ltemp[ti * TSE + tj] ]; } } @@ -1766,11 +1776,11 @@ void ImProcFunctions::exlabLocal(const local_params& lp, int bfh, int bfw, LabIm float satby100 = lp.chro / 100.f; // float L = 2.f * Ltemp[ti * TS + tj]; - float a = atemp[ti * TS + tj]; - float b = btemp[ti * TS + tj]; + float a = atemp[ti * TSE + tj]; + float b = btemp[ti * TSE + tj]; - atemp[ti * TS + tj] = a * (1.f + satby100); - btemp[ti * TS + tj] = b * (1.f + satby100); + atemp[ti * TSE + tj] = a * (1.f + satby100); + btemp[ti * TSE + tj] = b * (1.f + satby100); } } } @@ -1783,9 +1793,9 @@ void ImProcFunctions::exlabLocal(const local_params& lp, int bfh, int bfw, LabIm for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { - lab->L[i][j] = 0.5f * Ltemp[ti * TS + tj]; - lab->a[i][j] = atemp[ti * TS + tj]; - lab->b[i][j] = btemp[ti * TS + tj]; + lab->L[i][j] = 0.5f * Ltemp[ti * TSE + tj]; + lab->a[i][j] = atemp[ti * TSE + tj]; + lab->b[i][j] = btemp[ti * TSE + tj]; } } } @@ -2272,7 +2282,7 @@ void ImProcFunctions::DeNoise_Local(int call, const struct local_params& lp, in float factorx = localFactor; float difL, difa, difb; - if (call == 2) { //simpleprocess + if (call == 2 /*|| call == 1 || call == 3 */) { //simpleprocess difL = tmp1.L[loy - begy][lox - begx] - original->L[y][x]; difa = tmp1.a[loy - begy][lox - begx] - original->a[y][x]; difb = tmp1.b[loy - begy][lox - begx] - original->b[y][x]; @@ -2295,7 +2305,7 @@ void ImProcFunctions::DeNoise_Local(int call, const struct local_params& lp, in case 2: { // inside selection => full effect, no transition float difL, difa, difb; - if (call == 2) { //simpleprocess + if (call == 2 /*|| call == 1 || call == 3 */) { //simpleprocess difL = tmp1.L[loy - begy][lox - begx] - original->L[y][x]; difa = tmp1.a[loy - begy][lox - begx] - original->a[y][x]; difb = tmp1.b[loy - begy][lox - begx] - original->b[y][x]; @@ -8065,7 +8075,6 @@ void ImProcFunctions::fftw_denoise(int GW, int GH, int max_numblox_W, int min_nu plan_backward_blox[1] = fftwf_plan_many_r2r(2, nfwd, min_numblox_W, fLbloxtmp, nullptr, 1, TS * TS, Lbloxtmp, nullptr, 1, TS * TS, bwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT); fftwf_free(Lbloxtmp); fftwf_free(fLbloxtmp); - const int border = MAX(2, TS / 16); for (int i = 0; i < TS; ++i) { @@ -8191,14 +8200,17 @@ void ImProcFunctions::fftw_denoise(int GW, int GH, int max_numblox_W, int min_nu // now process the vblk row of blocks for noise reduction float params_Ldetail = 0.f; + float noisevar_Ldetail = 1.f; if (chrom == 0) { params_Ldetail = min(float(lp.noiseldetail), 99.9f); // max out to avoid div by zero when using noisevar_Ldetail as divisor + noisevar_Ldetail = SQR(static_cast(SQR(100. - params_Ldetail) + 50.*(100. - params_Ldetail)) * TS * 0.5f); } else if (chrom == 1) { params_Ldetail = min(float(lp.noisechrodetail), 99.9f); + noisevar_Ldetail = 100.f * pow((static_cast(SQR(100. - params_Ldetail) + 50.*(100. - params_Ldetail)) * TS * 0.5f), 2);//to test ??? } - float noisevar_Ldetail = SQR(static_cast(SQR(100. - params_Ldetail) + 50.*(100. - params_Ldetail)) * TS * 0.5f); + // float noisevar_Ldetail = SQR(static_cast(SQR(100. - params_Ldetail) + 50.*(100. - params_Ldetail)) * TS * 0.5f); @@ -8240,13 +8252,9 @@ void ImProcFunctions::fftw_denoise(int GW, int GH, int max_numblox_W, int min_nu } } -// } delete Lin; -// } - -// if ((lp.noiself > 0.1f || lp.noiselc > 0.1f) && levred == 7) { for (int i = 0; i < numThreads; ++i) { fftwf_free(LbloxArray[i]); @@ -9462,8 +9470,9 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, if (((lp.noiself > 0.f || lp.noiselc > 0.f || lp.noisecf > 0.f || lp.noisecc > 0.f) && lp.denoiena) || execdenoi) { // sk == 1 ?? StopWatch Stop1("locallab Denoise called"); + MyMutex::MyLock lock(*fftwMutex); - if (lp.noisecf > 0.1f || lp.noisecc > 0.1f) { + if (lp.noisecf >= 0.1f || lp.noisecc >= 0.1f) { noiscfactiv = false; levred = 7; } @@ -9487,7 +9496,11 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, #endif if (call == 1) { + //printf("OK sk=1\n"); LabImage tmp1(transformed->W, transformed->H); + LabImage tmp2(transformed->W, transformed->H); + tmp2.clear(); + array2D *Lin = nullptr; array2D *Ain = nullptr; array2D *Bin = nullptr; @@ -9517,7 +9530,6 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, wavelet_decomposition bdecomp(tmp1.b[0], tmp1.W, tmp1.H, levwavL, 1, skip, numThreads, DaubLen); float madL[8][3]; - // float madC[8][3]; int edge = 2; if (!Ldecomp.memoryAllocationFailed) { @@ -9555,7 +9567,7 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, } - if ((lp.noiself > 0.1f || lp.noiselc > 0.1f)) { + if ((lp.noiself >= 0.1f || lp.noiselc >= 0.1f)) { float kr3 = 0.f; float kr4 = 0.f; float kr5 = 0.f; @@ -9589,9 +9601,47 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, vari[6] = max(0.0001f, kr5 * vari[6]); } - float* noisevarlum = nullptr; // we need a dummy to pass it to WaveletDenoiseAllL + float* noisevarlum = new float[GH * GW]; + int GW2 = (GW + 1) / 2; + + 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 - lp.noiselequal; + float ac = (nvlh[i] - nvll[i]) / (seuillow - seuilhigh); + float bc = nvlh[i] - seuillow * ac; + //ac and bc for transition +#ifdef _OPENMP + #pragma omp parallel for + +#endif + + for (int ir = 0; ir < GH; ir++) + for (int jr = 0; jr < GW; jr++) { + float lN = tmp1.L[ir][jr]; + + if (lN < seuillow) { + noisevarlum[(ir >> 1)*GW2 + (jr >> 1)] = nvlh[i]; + } else if (lN < seuilhigh) { + noisevarlum[(ir >> 1)*GW2 + (jr >> 1)] = ac * lN + bc; + } else { + noisevarlum[(ir >> 1)*GW2 + (jr >> 1)] = nvll[i]; + } + } + + // float* noisevarlum = nullptr; // we need a dummy to pass it to WaveletDenoiseAllL + + if (lp.noiselc < 1.f) { + WaveletDenoiseAllL(Ldecomp, noisevarlum, madL, vari, edge, numThreads); + } else { + WaveletDenoiseAll_BiShrinkL(Ldecomp, noisevarlum, madL, vari, edge, numThreads); + WaveletDenoiseAllL(Ldecomp, noisevarlum, madL, vari, edge, numThreads); + } + + delete[] noisevarlum; - WaveletDenoiseAllL(Ldecomp, noisevarlum, madL, vari, edge, numThreads); } } @@ -9636,23 +9686,23 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, if (levred == 7) { edge = 2; - variC[0] = SQR(noisecfr / 10.0); - variC[1] = SQR(noisecfr / 10.0); - variC[2] = SQR(noisecfr / 10.0); + variC[0] = SQR(noisecfr); + variC[1] = SQR(noisecfr); + variC[2] = SQR(noisecfr); - variC[3] = SQR(noisecfr / 10.0); - variC[4] = SQR(noisecfr / 10.0); - variC[5] = SQR(noiseccr / 10.0); - variC[6] = SQR(noiseccr / 10.0); + variC[3] = SQR(noisecfr); + variC[4] = SQR(noisecfr); + variC[5] = SQR(noiseccr); + variC[6] = SQR(noiseccr); - variCb[0] = SQR(noisecfb / 10.0); - variCb[1] = SQR(noisecfb / 10.0); - variCb[2] = SQR(noisecfb / 10.0); + variCb[0] = SQR(noisecfb); + variCb[1] = SQR(noisecfb); + variCb[2] = SQR(noisecfb); - variCb[3] = SQR(noisecfb / 10.0); - variCb[4] = SQR(noisecfb / 10.0); - variCb[5] = SQR(noiseccb / 10.0); - variCb[6] = SQR(noiseccb / 10.0); + variCb[3] = SQR(noisecfb); + variCb[4] = SQR(noisecfb); + variCb[5] = SQR(noiseccb); + variCb[6] = SQR(noiseccb); } else if (levred == 4) { edge = 3; @@ -9669,8 +9719,7 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, } -//lp.adjch - if ((lp.noisecf > 0.1f || lp.noisecc > 0.1f || noiscfactiv)) { + if ((lp.noisecf >= 0.1f || lp.noisecc >= 0.1f || noiscfactiv)) { float minic = 0.0001f; if (noiscfactiv) { @@ -9681,23 +9730,55 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, float k2 = 0.f; float k3 = 0.f; - if (lp.noisecf < 0.3f) { + if (lp.noisecf < 0.2f) { k1 = 0.f; k2 = 0.f; k3 = 0.f; + } else if (lp.noisecf < 0.3f) { + k1 = 0.1f; + k2 = 0.0f; + k3 = 0.f; + } else if (lp.noisecf < 0.5f) { + k1 = 0.2f; + k2 = 0.1f; + k3 = 0.f; + } else if (lp.noisecf < 0.8f) { + k1 = 0.3f; + k2 = 0.25f; + k3 = 0.f; } else if (lp.noisecf < 1.f) { k1 = 0.4f; - k2 = 0.2f; - k3 = 0.f; - + k2 = 0.25f; + k3 = 0.1f; + } else if (lp.noisecf < 2.f) { + k1 = 0.5f; + k2 = 0.3f; + k3 = 0.15f; } else if (lp.noisecf < 3.f) { k1 = 0.6f; k2 = 0.45f; k3 = 0.3f; + } else if (lp.noisecf < 4.f) { + k1 = 0.7f; + k2 = 0.5f; + k3 = 0.4f; } else if (lp.noisecf < 5.f) { k1 = 0.8f; k2 = 0.6f; k3 = 0.5f; + } else if (lp.noisecf < 10.f) { + k1 = 0.85f; + k2 = 0.7f; + k3 = 0.6f; + } else if (lp.noisecf < 20.f) { + k1 = 0.9f; + k2 = 0.8f; + k3 = 0.7f; + } else if (lp.noisecf < 50.f) { + k1 = 1.f; + k2 = 1.f; + k3 = 0.9f; + } else { k1 = 1.f; k2 = 1.f; @@ -9719,30 +9800,27 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, float k5 = 0.f; float k6 = 0.f; - if (lp.noisecc < 0.3f) { + if (lp.noisecc == 0.1f) { + k4 = 0.f; + k5 = 0.0f; + } else if (lp.noisecc < 0.2f) { k4 = 0.1f; k5 = 0.0f; + } else if (lp.noisecc < 0.5f) { + k4 = 0.15f; + k5 = 0.0f; } else if (lp.noisecc < 1.f) { k4 = 0.15f; k5 = 0.1f; - } else if (lp.noisecc < 4.f) { + } else if (lp.noisecc < 3.f) { k4 = 0.3f; k5 = 0.15f; - } else if (lp.noisecc < 8.f) { - k4 = 0.4f; - k5 = 0.2f; - } else if (lp.noisecc < 20.f) { - k4 = 0.45f; - k5 = 0.3f; - } else if (lp.noisecc < 40.f) { + } else if (lp.noisecc < 4.f) { k4 = 0.6f; k5 = 0.4f; - } else if (lp.noisecc < 70.f) { - k4 = 0.7f; - k5 = 0.5f; - } else if (lp.noisecc < 80.f) { + } else if (lp.noisecc < 6.f) { k4 = 0.8f; - k5 = 0.7f; + k5 = 0.6f; } else { k4 = 1.f; k5 = 1.f; @@ -9754,14 +9832,12 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, variCb[4] = max(0.0001f, k4 * variCb[4]); variCb[5] = max(0.0001f, k5 * variCb[5]); - if (lp.noisecc < 10.f) { + if (lp.noisecc < 4.f) { k6 = 0.f; - } else if (lp.noisecc < 15.f) { - k6 = 0.2f; - } else if (lp.noisecc < 30.f) { + } else if (lp.noisecc < 5.f) { k6 = 0.4f; - } else if (lp.noisecc < 70.f) { - k6 = 0.6f; + } else if (lp.noisecc < 6.f) { + k6 = 0.7f; } else { k6 = 1.f; } @@ -9774,10 +9850,16 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, float* noisevarchrom = new float[GH * GW]; //noisevarchrom in function chroma int GW2 = (GW + 1) / 2; - float nvch = 0.5f;//high value - float nvcl = 0.05f;//low value - float seuil = 3000.f;//low - float seuil2 = 10000.f;//high + float nvch = 0.6f;//high value + float nvcl = 0.1f;//low value + + if (lp.noisecf > 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; @@ -9801,8 +9883,18 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, float noisevarab_r = 100.f; //SQR(lp.noisecc / 10.0); - WaveletDenoiseAllAB(Ldecomp, adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, numThreads); - WaveletDenoiseAllAB(Ldecomp, bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, numThreads); + + if (lp.noisecc < 0.1f) { + WaveletDenoiseAllAB(Ldecomp, adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, numThreads); + WaveletDenoiseAllAB(Ldecomp, bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, numThreads); + } else { + WaveletDenoiseAll_BiShrinkAB(Ldecomp, adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, numThreads); + WaveletDenoiseAllAB(Ldecomp, adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, numThreads); + + WaveletDenoiseAll_BiShrinkAB(Ldecomp, bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, numThreads); + WaveletDenoiseAllAB(Ldecomp, bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, numThreads); + } + delete[] noisevarchrom; } @@ -9825,7 +9917,7 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, } if (!Ldecomp.memoryAllocationFailed) { - if ((lp.noiself > 0.1f || lp.noiselc > 0.1f) && levred == 7) { + if ((lp.noiself >= 0.1f || lp.noiselc >= 0.1f) && levred == 7) { fftw_denoise(GW, GH, max_numblox_W, min_numblox_W, tmp1.L, Lin, numThreads, lp, 0); } } @@ -9848,13 +9940,20 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, if (!adecomp.memoryAllocationFailed) { - if ((lp.noisecf > 0.1f || lp.noisecc > 0.1f)) { - fftw_denoise(GW, GH, max_numblox_W, min_numblox_W, tmp1.a, Ain, numThreads, lp, 1); + if ((lp.noisecf >= 0.1f || lp.noisecc >= 0.1f)) { + if (lp.noisechrodetail > 1000) { //to avoid all utilisation + fftw_denoise(GW, GH, max_numblox_W, min_numblox_W, tmp1.a, Ain, numThreads, lp, 1); + } } + + + + } if (!bdecomp.memoryAllocationFailed) { + Bin = new array2D(GW, GH); #ifdef _OPENMP #pragma omp parallel for @@ -9872,24 +9971,27 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, if (!bdecomp.memoryAllocationFailed) { - if ((lp.noisecf > 0.1f || lp.noisecc > 0.1f)) { - fftw_denoise(GW, GH, max_numblox_W, min_numblox_W, tmp1.b, Bin, numThreads, lp, 1); + if ((lp.noisecf >= 0.1f || lp.noisecc >= 0.1f)) { + if (lp.noisechrodetail > 1000) {//to avoid all utilisation + + fftw_denoise(GW, GH, max_numblox_W, min_numblox_W, tmp1.b, Bin, numThreads, lp, 1); + } } + } - // printf("huere=%f dhueden=%f huplus=%f huemoin=%f\n", hueref, dhueden, hueplus, huemoins); DeNoise_Local(call, lp, levred, hueplus, huemoins, huerefblur, dhueden, original, transformed, tmp1, cx, cy, sk); - } else if (call == 2) { //simpleprocess + } else if (call == 2 /* || call == 1 || call == 3 */) { //simpleprocess int bfh = int (lp.ly + lp.lyT) + del; //bfw bfh real size of square zone int bfw = int (lp.lx + lp.lxL) + del; LabImage bufwv(bfw, bfh); bufwv.clear(true); array2D *Lin = nullptr; - array2D *Ain = nullptr; - array2D *Bin = nullptr; + // array2D *Ain = nullptr; + // array2D *Bin = nullptr; int max_numblox_W = ceil((static_cast(bfw)) / (offset)) + 2 * blkrad; // calculate min size of numblox_W. @@ -9966,7 +10068,7 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, } - if ((lp.noiself > 0.1f || lp.noiselc > 0.1f)) { + if ((lp.noiself >= 0.1f || lp.noiselc >= 0.1f)) { float kr3 = 0.f; float kr4 = 0.f; float kr5 = 0.f; @@ -10000,9 +10102,46 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, vari[6] = max(0.0001f, kr5 * vari[6]); } - float* noisevarlum = nullptr; // we need a dummy to pass it to WaveletDenoiseAllL + // float* noisevarlum = nullptr; // we need a dummy to pass it to WaveletDenoiseAllL + float* noisevarlum = new float[bfh * bfw]; + int bfw2 = (bfw + 1) / 2; + + 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 - lp.noiselequal; + float ac = (nvlh[i] - nvll[i]) / (seuillow - seuilhigh); + float bc = nvlh[i] - seuillow * ac; + //ac and bc for transition +#ifdef _OPENMP + #pragma omp parallel for + +#endif + + for (int ir = 0; ir < bfh; ir++) + for (int jr = 0; jr < bfw; jr++) { + float lN = bufwv.L[ir][jr]; + + if (lN < seuillow) { + noisevarlum[(ir >> 1)*bfw2 + (jr >> 1)] = nvlh[i]; + } else if (lN < seuilhigh) { + noisevarlum[(ir >> 1)*bfw2 + (jr >> 1)] = ac * lN + bc; + } else { + noisevarlum[(ir >> 1)*bfw2 + (jr >> 1)] = nvll[i]; + } + } + + if (lp.noiselc < 1.f) { + WaveletDenoiseAllL(Ldecomp, noisevarlum, madL, vari, edge, numThreads); + } else { + WaveletDenoiseAll_BiShrinkL(Ldecomp, noisevarlum, madL, vari, edge, numThreads); + WaveletDenoiseAllL(Ldecomp, noisevarlum, madL, vari, edge, numThreads); + } + + delete [] noisevarlum; - WaveletDenoiseAllL(Ldecomp, noisevarlum, madL, vari, edge, numThreads); } } @@ -10048,23 +10187,23 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, if (levred == 7) { edge = 2; - variC[0] = SQR(noisecfr / 10.0); - variC[1] = SQR(noisecfr / 10.0); - variC[2] = SQR(noisecfr / 10.0); + variC[0] = SQR(noisecfr); + variC[1] = SQR(noisecfr); + variC[2] = SQR(noisecfr); - variC[3] = SQR(noisecfr / 10.0); - variC[4] = SQR(noisecfr / 10.0); - variC[5] = SQR(noiseccr / 10.0); - variC[6] = SQR(noiseccr / 10.0); + variC[3] = SQR(noisecfr); + variC[4] = SQR(noisecfr); + variC[5] = SQR(noiseccr); + variC[6] = SQR(noiseccr); - variCb[0] = SQR(noisecfb / 10.0); - variCb[1] = SQR(noisecfb / 10.0); - variCb[2] = SQR(noisecfb / 10.0); + variCb[0] = SQR(noisecfb); + variCb[1] = SQR(noisecfb); + variCb[2] = SQR(noisecfb); - variCb[3] = SQR(noisecfb / 10.0); - variCb[4] = SQR(noisecfb / 10.0); - variCb[5] = SQR(noiseccb / 10.0); - variCb[6] = SQR(noiseccb / 10.0); + variCb[3] = SQR(noisecfb); + variCb[4] = SQR(noisecfb); + variCb[5] = SQR(noiseccb); + variCb[6] = SQR(noiseccb); } else if (levred == 4) { edge = 3; @@ -10081,8 +10220,8 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, } -//lp.adjch - if ((lp.noisecf > 0.1f || lp.noisecc > 0.1f || noiscfactiv)) { + + if ((lp.noisecf >= 0.1f || lp.noisecc >= 0.1f || noiscfactiv)) { float minic = 0.0001f; if (noiscfactiv) { @@ -10093,23 +10232,55 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, float k2 = 0.f; float k3 = 0.f; - if (lp.noisecf < 0.3f) { + if (lp.noisecf < 0.2f) { k1 = 0.f; k2 = 0.f; k3 = 0.f; + } else if (lp.noisecf < 0.3f) { + k1 = 0.1f; + k2 = 0.0f; + k3 = 0.f; + } else if (lp.noisecf < 0.5f) { + k1 = 0.2f; + k2 = 0.1f; + k3 = 0.f; + } else if (lp.noisecf < 0.8f) { + k1 = 0.3f; + k2 = 0.25f; + k3 = 0.f; } else if (lp.noisecf < 1.f) { k1 = 0.4f; - k2 = 0.2f; - k3 = 0.f; - + k2 = 0.25f; + k3 = 0.1f; + } else if (lp.noisecf < 2.f) { + k1 = 0.5f; + k2 = 0.3f; + k3 = 0.15f; } else if (lp.noisecf < 3.f) { k1 = 0.6f; k2 = 0.45f; k3 = 0.3f; + } else if (lp.noisecf < 4.f) { + k1 = 0.7f; + k2 = 0.5f; + k3 = 0.4f; } else if (lp.noisecf < 5.f) { k1 = 0.8f; k2 = 0.6f; k3 = 0.5f; + } else if (lp.noisecf < 10.f) { + k1 = 0.85f; + k2 = 0.7f; + k3 = 0.6f; + } else if (lp.noisecf < 20.f) { + k1 = 0.9f; + k2 = 0.8f; + k3 = 0.7f; + } else if (lp.noisecf < 50.f) { + k1 = 1.f; + k2 = 1.f; + k3 = 0.9f; + } else { k1 = 1.f; k2 = 1.f; @@ -10131,30 +10302,27 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, float k5 = 0.f; float k6 = 0.f; - if (lp.noisecc < 0.3f) { + if (lp.noisecc == 0.1f) { + k4 = 0.f; + k5 = 0.0f; + } else if (lp.noisecc < 0.2f) { k4 = 0.1f; k5 = 0.0f; + } else if (lp.noisecc < 0.5f) { + k4 = 0.15f; + k5 = 0.0f; } else if (lp.noisecc < 1.f) { k4 = 0.15f; k5 = 0.1f; - } else if (lp.noisecc < 4.f) { + } else if (lp.noisecc < 3.f) { k4 = 0.3f; k5 = 0.15f; - } else if (lp.noisecc < 8.f) { - k4 = 0.4f; - k5 = 0.2f; - } else if (lp.noisecc < 20.f) { - k4 = 0.45f; - k5 = 0.3f; - } else if (lp.noisecc < 40.f) { + } else if (lp.noisecc < 4.f) { k4 = 0.6f; k5 = 0.4f; - } else if (lp.noisecc < 70.f) { - k4 = 0.7f; - k5 = 0.5f; - } else if (lp.noisecc < 80.f) { + } else if (lp.noisecc < 6.f) { k4 = 0.8f; - k5 = 0.7f; + k5 = 0.6f; } else { k4 = 1.f; k5 = 1.f; @@ -10166,31 +10334,32 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, variCb[4] = max(0.0001f, k4 * variCb[4]); variCb[5] = max(0.0001f, k5 * variCb[5]); - if (lp.noisecc < 10.f) { + if (lp.noisecc < 4.f) { k6 = 0.f; - } else if (lp.noisecc < 15.f) { - k6 = 0.2f; - } else if (lp.noisecc < 30.f) { + } else if (lp.noisecc < 5.f) { k6 = 0.4f; - } else if (lp.noisecc < 70.f) { - k6 = 0.6f; + } else if (lp.noisecc < 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* noisevarchrom = new float[bfh * bfw]; int bfw2 = (bfw + 1) / 2; - float nvch = 0.5f;//high value - float nvcl = 0.05f;//low value - float seuil = 3000.f;//low - float seuil2 = 10000.f;//high + float nvch = 0.6f;//high value + float nvcl = 0.1f;//low value + + if (lp.noisecf > 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; @@ -10213,8 +10382,19 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, } float noisevarab_r = 100.f; //SQR(lp.noisecc / 10.0); - WaveletDenoiseAllAB(Ldecomp, adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, numThreads); - WaveletDenoiseAllAB(Ldecomp, bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, numThreads); + + + if (lp.noisecc < 0.1f) { + WaveletDenoiseAllAB(Ldecomp, adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, numThreads); + WaveletDenoiseAllAB(Ldecomp, bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, numThreads); + } else { + WaveletDenoiseAll_BiShrinkAB(Ldecomp, adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, numThreads); + WaveletDenoiseAllAB(Ldecomp, adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, numThreads); + + WaveletDenoiseAll_BiShrinkAB(Ldecomp, bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, numThreads); + WaveletDenoiseAllAB(Ldecomp, bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, numThreads); + } + delete[] noisevarchrom; } } @@ -10240,61 +10420,65 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original, if (!Ldecomp.memoryAllocationFailed) { - if ((lp.noiself > 0.1f || lp.noiselc > 0.1f) && levred == 7) { + if ((lp.noiself >= 0.1f || lp.noiselc >= 0.1f) && levred == 7) { fftw_denoise(bfw, bfh, max_numblox_W, min_numblox_W, bufwv.L, Lin, numThreads, lp, 0); } } if (!adecomp.memoryAllocationFailed) { - Ain = new array2D(bfw, bfh); -#ifdef _OPENMP + /* + // Ain = new array2D(bfw, bfh); + #ifdef _OPENMP #pragma omp parallel for -#endif + #endif for (int i = 0; i < bfh; ++i) { for (int j = 0; j < bfw; ++j) { (*Ain)[i][j] = bufwv.a[i][j]; } } - + */ adecomp.reconstruct(bufwv.a[0]); } - if (!adecomp.memoryAllocationFailed) { + /* + if (!adecomp.memoryAllocationFailed) { - if ((lp.noisecf > 0.1f || lp.noisecc > 0.1f)) { - fftw_denoise(bfw, bfh, max_numblox_W, min_numblox_W, bufwv.a, Ain, numThreads, lp, 1); - - } - } + if ((lp.noisecf >= 0.1f || lp.noisecc >= 0.1f)) { + // fftw_denoise(bfw, bfh, max_numblox_W, min_numblox_W, bufwv.a, Ain, numThreads, lp, 1); + } + } + */ if (!bdecomp.memoryAllocationFailed) { - Bin = new array2D(bfw, bfh); -#ifdef _OPENMP + /* + // Bin = new array2D(bfw, bfh); + #ifdef _OPENMP #pragma omp parallel for -#endif + #endif for (int i = 0; i < bfh; ++i) { for (int j = 0; j < bfw; ++j) { (*Bin)[i][j] = bufwv.b[i][j]; } } - + */ bdecomp.reconstruct(bufwv.b[0]); } - if (!bdecomp.memoryAllocationFailed) { - if ((lp.noisecf > 0.1f || lp.noisecc > 0.1f)) { - fftw_denoise(bfw, bfh, max_numblox_W, min_numblox_W, bufwv.b, Bin, numThreads, lp, 1); - - } - } + /* + if (!bdecomp.memoryAllocationFailed) { + if ((lp.noisecf >= 0.1f || lp.noisecc >= 0.1f)) { + // fftw_denoise(bfw, bfh, max_numblox_W, min_numblox_W, bufwv.b, Bin, numThreads, lp, 1); + } + } + */ DeNoise_Local(call, lp, levred, hueplus, huemoins, huerefblur, dhueden, original, transformed, bufwv, cx, cy, sk); } diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 6420d180e..84efdb34b 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -626,6 +626,8 @@ enum ProcEventCode { EvlocallabEnabled = 596, EvlocallablocY = 597, Evlocallabbilateral = 598, + Evlocallabnoiselequal = 599, + NUMOFEVENTS diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 481e2467b..2cc134da7 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2403,6 +2403,7 @@ sensiv(19), noiselumf(0), noiselumc(0), noiselumdetail(0), +noiselequal(7), noisechrodetail(0), bilateral(0), sensiden(30), @@ -2540,6 +2541,7 @@ bool LocallabParams::operator ==(const LocallabParams& other) const && noiselumf == other.noiselumf && noiselumc == other.noiselumc && noiselumdetail == other.noiselumdetail + && noiselequal == other.noiselequal && noisechrodetail == other.noisechrodetail && bilateral == other.bilateral && sensiden == other.sensiden @@ -3532,6 +3534,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->locallab.noiselumf, "Locallab", "noiselumf", locallab.noiselumf, keyFile); saveToKeyfile(!pedited || pedited->locallab.noiselumc, "Locallab", "noiselumc", locallab.noiselumc, keyFile); saveToKeyfile(!pedited || pedited->locallab.noiselumdetail, "Locallab", "noiselumdetail", locallab.noiselumdetail, keyFile); + saveToKeyfile(!pedited || pedited->locallab.noiselequal, "Locallab", "noiselequal", locallab.noiselequal, keyFile); saveToKeyfile(!pedited || pedited->locallab.noisechrodetail, "Locallab", "noisechrodetail", locallab.noisechrodetail, keyFile); saveToKeyfile(!pedited || pedited->locallab.bilateral, "Locallab", "Bilateral", locallab.bilateral, keyFile); saveToKeyfile(!pedited || pedited->locallab.sensiden, "Locallab", "Sensiden", locallab.sensiden, keyFile); @@ -4427,17 +4430,23 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Shadows & Highlights", "Shadows", pedited, sh.shadows, pedited->sh.shadows); assignFromKeyfile(keyFile, "Shadows & Highlights", "ShadowTonalWidth", pedited, sh.stonalwidth, pedited->sh.stonalwidth); assignFromKeyfile(keyFile, "Shadows & Highlights", "Radius", pedited, sh.radius, pedited->sh.radius); + if (keyFile.has_key("Shadows & Highlights", "LocalContrast") && ppVersion < 329) { int lc = keyFile.get_integer("Shadows & Highlights", "LocalContrast"); localContrast.amount = float(lc) / (sh.hq ? 500.0 : 30.); + if (pedited) { pedited->localContrast.amount = true; } + localContrast.enabled = sh.enabled; + if (pedited) { pedited->localContrast.enabled = true; } + localContrast.radius = sh.radius; + if (pedited) { pedited->localContrast.radius = true; } @@ -4623,6 +4632,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "noiselumf", pedited, locallab.noiselumf, pedited->locallab.noiselumf); assignFromKeyfile(keyFile, "Locallab", "noiselumc", pedited, locallab.noiselumc, pedited->locallab.noiselumc); assignFromKeyfile(keyFile, "Locallab", "noiselumdetail", pedited, locallab.noiselumdetail, pedited->locallab.noiselumdetail); + assignFromKeyfile(keyFile, "Locallab", "noiselequal", pedited, locallab.noiselequal, pedited->locallab.noiselequal); assignFromKeyfile(keyFile, "Locallab", "noisechrodetail", pedited, locallab.noisechrodetail, pedited->locallab.noisechrodetail); assignFromKeyfile(keyFile, "Locallab", "Bilateral", pedited, locallab.bilateral, pedited->locallab.bilateral); assignFromKeyfile(keyFile, "Locallab", "Sensiden", pedited, locallab.sensiden, pedited->locallab.sensiden); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index d3245fdc5..f9e9e9689 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -933,6 +933,7 @@ struct LocallabParams { int noiselumf; int noiselumc; int noiselumdetail; + int noiselequal; int noisechrodetail; int bilateral; int sensiden; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 9c3626e6f..019a580e8 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -625,7 +625,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, // Evlocallabhuerefblur LUMINANCECURVE, // EvlocallabEnabled LUMINANCECURVE, // EvlocallablocY - LUMINANCECURVE // Evlocallabbilateral + LUMINANCECURVE, // Evlocallabbilateral + LUMINANCECURVE // Evlocallabnoiselequal }; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index e6a5c5151..8a62ad150 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1103,7 +1103,7 @@ private: } ifstream fich(datalab, ios::in); - int maxdata = 100; //99 10021 // 91 10021 //88 10019 //87 10018//86 10017//85 10016 //82;//78;//73 10011 + int maxdata = 101; //100 10022 //99 10021 // 91 10021 //88 10019 //87 10018//86 10017//85 10016 //82;//78;//73 10011 if (fich && versionmip != 0) { std::string inser; @@ -1397,6 +1397,7 @@ private: } dataspots[94][0] = params.locallab.bilateral; + dataspots[95][0] = params.locallab.noiselequal; dataspots[maxdata - 5][0] = 100.f * params.locallab.huerefblur; dataspots[maxdata - 4][0] = 100.f * params.locallab.hueref; @@ -1927,6 +1928,7 @@ private: } params.locallab.bilateral = dataspots[94][sp]; + params.locallab.noiselequal = dataspots[95][sp]; params.locallab.huerefblur = ((float) dataspots[maxdata - 5][sp]) / 100.f; diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 45c6908e8..a2e459f67 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -33,28 +33,28 @@ #include "../rtengine/improcfun.h" #define MINCHRO 0. -#define MAXCHRO 100 +#define MAXCHRO 150 #define CENTERCHRO 10 +#define MAXCHROCC 100 using namespace rtengine; using namespace rtengine::procparams; extern Options options; +/* static double dnSlider2chro(double sval) { - // slider range: 0 - 10000 double chro; + double coef = CENTERCHRO; - if (sval <= 10) { - // linear below center-temp - chro = MINCHRO + (sval / 10.0) * (CENTERCHRO - MINCHRO); + if (sval <= coef) { + chro = MINCHRO + (sval / coef) * (CENTERCHRO - MINCHRO); } else { const double slope = (double)(CENTERCHRO - MINCHRO) / (MAXCHRO - CENTERCHRO); - double x = (sval - 10) / 10; // x 0..1 + double x = (sval - coef) / coef; // x 0..1 double y = x * slope + (1.0 - slope) * pow(x, 4.0); - //double y = pow(x, 4.0); chro = CENTERCHRO + y * (MAXCHRO - CENTERCHRO); } @@ -69,13 +69,40 @@ static double dnSlider2chro(double sval) return chro; } +static double dnSlider2chroCC(double sval) +{ + + double chro; + double coef = CENTERCHRO; + + if (sval <= coef) { + chro = MINCHRO + (sval / coef) * (CENTERCHRO - MINCHRO); + } else { + const double slope = (double)(CENTERCHRO - MINCHRO) / (MAXCHROCC - CENTERCHRO); + double x = (sval - coef) / coef; // x 0..1 + double y = x * slope + (1.0 - slope) * pow(x, 4.0); + chro = CENTERCHRO + y * (MAXCHROCC - CENTERCHRO); + } + + if (chro < MINCHRO) { + chro = MINCHRO; + } + + if (chro > MAXCHROCC) { + chro = MAXCHROCC; + } + + return chro; +} + static double dnchro2Slider(double noisechrof) { double sval; + double coef = CENTERCHRO; if (noisechrof <= CENTERCHRO) { - sval = ((noisechrof - MINCHRO) / (CENTERCHRO - MINCHRO)) * 10.0; + sval = ((noisechrof - MINCHRO) / (CENTERCHRO - MINCHRO)) * coef; } else { const double slope = (double)(CENTERCHRO - MINCHRO) / (MAXCHRO - CENTERCHRO); const double y = (noisechrof - CENTERCHRO) / (MAXCHRO - CENTERCHRO); @@ -83,12 +110,10 @@ static double dnchro2Slider(double noisechrof) double k = 0.1; bool add = true; - // the y=f(x) function is a mess to invert, therefore we have this trial-refinement loop instead. - // from tests, worst case is about 20 iterations, ie no problem for (;;) { double y1 = x * slope + (1.0 - slope) * pow(x, 4.0); - if (10 * fabs(y1 - y) < 0.1) { + if (coef * fabs(y1 - y) < 0.1) { break; } @@ -109,23 +134,76 @@ static double dnchro2Slider(double noisechrof) } } - sval = 10.0 + x * 10.0; + sval = coef + x * coef; } if (sval < 0) { sval = 0; } - if (sval > 100) { - sval = 100; + if (sval > MAXCHRO) { + sval = MAXCHRO; } return sval; } +static double dnchroCC2Slider(double noisechroc) +{ + + double sval; + double coef = CENTERCHRO; + + if (noisechroc <= CENTERCHRO) { + sval = ((noisechroc - MINCHRO) / (CENTERCHRO - MINCHRO)) * coef; + } else { + const double slope = (double)(CENTERCHRO - MINCHRO) / (MAXCHROCC - CENTERCHRO); + const double y = (noisechroc - CENTERCHRO) / (MAXCHROCC - CENTERCHRO); + double x = pow(y, 0.25); // rough guess of x, will be a little lower + double k = 0.1; + bool add = true; + + for (;;) { + double y1 = x * slope + (1.0 - slope) * pow(x, 4.0); + + if (coef * fabs(y1 - y) < 0.1) { + break; + } + + if (y1 < y) { + if (!add) { + k /= 2; + } + + x += k; + add = true; + } else { + if (add) { + k /= 2; + } + + x -= k; + add = false; + } + } + + sval = coef + x * coef; + } + + if (sval < 0) { + sval = 0; + } + + if (sval > MAXCHROCC) { + sval = MAXCHROCC; + } + + return sval; +} +*/ Locallab::Locallab(): - FoldableToolPanel(this, "locallab", M("TP_LOCALLAB_LABEL"), true, true), + FoldableToolPanel(this, "locallab", M("TP_LOCALLAB_LABEL"), false, true), EditSubscriber(ET_OBJECTS), lastObject(-1), expcolor(new MyExpander(true, M("TP_LOCALLAB_COFR"))), expexpose(new MyExpander(true, M("TP_LOCALLAB_EXPOSE"))), @@ -190,16 +268,10 @@ Locallab::Locallab(): shardamping(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SHARDAMPING"), 0, 100, 1, 75))), shariter(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SHARITER"), 5, 100, 1, 30))), sensisha(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSIS"), 0, 100, 1, 19))), - noiselumf(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELUMFINE"), 0, 100, 1, 0))), - noiselumc(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELUMCOARSE"), 0, 100, 1, 0))), - noiselumdetail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELUMDETAIL"), 0, 100, 1, 50))), - noisechrodetail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISECHRODETAIL"), 0, 100, 1, 50))), + noiselumdetail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELUMDETAIL"), 0, 100, 1, 0))), + noisechrodetail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISECHRODETAIL"), 0, 100, 1, 0))), bilateral(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BILATERAL"), 0, 100, 1, 0))), sensiden(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSIDEN"), 0, 100, 1, 30))), -// noisechrof(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISECHROFINE"), 0, 100, 0.1, 0))), - noisechrof(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISECHROFINE"), MINCHRO, MAXCHRO, 0.1, 0, NULL, NULL, &dnSlider2chro, &dnchro2Slider))), -// noisechroc(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISECHROCOARSE"), 0, 100, 0.1, 0))), - noisechroc(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISECHROCOARSE"), MINCHRO, MAXCHRO, 0.1, 0, NULL, NULL, &dnSlider2chro, &dnchro2Slider))), hueref(Gtk::manage(new Adjuster(M("TP_LOCALLAB_HUEREF"), -3.15, 3.15, 0.01, 0))), huerefblur(Gtk::manage(new Adjuster(M("TP_LOCALLAB_HUEREFBLUR"), -3.15, 3.15, 0.01, 0))), chromaref(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CHROMAREF"), 0, 200, 0.01, 0))), @@ -207,7 +279,6 @@ Locallab::Locallab(): sobelref(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOBELREF"), 0, 100, 0.01, 0))), centerXbuf(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CENTERBUF_X"), -1000, 1000, 1, 0))), centerYbuf(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CENTERBUF_Y"), -1000, 1000, 1, 0))), -// adjblur(Gtk::manage(new Adjuster(M("TP_LOCALLAB_ADJBLUR"), -100, 100, 1, 0))), Smethod(Gtk::manage(new MyComboBoxText())), Exclumethod(Gtk::manage(new MyComboBoxText())), @@ -474,11 +545,6 @@ Locallab::Locallab(): warm = Gtk::manage(new Adjuster(M("TP_LOCALLAB_WARM"), -100., 100., 1., 0., iblueredL, iblueredR)); warm->setAdjusterListener(this); - Gtk::Image* iblueredL1 = Gtk::manage(new RTImage("ajd-wb-bluered1.png")); - Gtk::Image* iblueredR1 = Gtk::manage(new RTImage("ajd-wb-bluered2.png")); - - adjblur = Gtk::manage(new Adjuster(M("TP_LOCALLAB_ADJ"), -100., 100., 1., 0., iblueredL1, iblueredR1)); - adjblur->setAdjusterListener(this); //chroma->set_tooltip_text (M("TP_LOCALLAB_CHROMA_TOOLTIP")); chroma->setAdjusterListener(this); @@ -739,28 +805,108 @@ Locallab::Locallab(): sharpBox->pack_start(*sensisha); sharpBox->pack_start(*inverssha); + /* + noiselumf = Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELUMFINE"), MINCHRO, MAXCHRO, 1, 0, NULL, NULL, &dnSlider2chro, &dnchro2Slider)); + noiselumc = Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELUMCOARSE"), MINCHRO, MAXCHROCC, 1, 0, NULL, NULL, &dnSlider2chroCC, &dnchroCC2Slider)); + + noisechrof = Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISECHROFINE"), MINCHRO, MAXCHRO, 1, 0, NULL, NULL, &dnSlider2chro, &dnchro2Slider)); + noisechroc = Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISECHROCOARSE"), MINCHRO, MAXCHROCC, 1, 0, NULL, NULL, &dnSlider2chroCC, &dnchroCC2Slider)); + */ + noiselumf = Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELUMFINE"), MINCHRO, MAXCHRO, 1, 0)); + noiselumc = Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELUMCOARSE"), MINCHRO, MAXCHROCC, 1, 0)); + + noisechrof = Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISECHROFINE"), MINCHRO, MAXCHRO, 1, 0)); + noisechroc = Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISECHROCOARSE"), MINCHRO, MAXCHROCC, 1, 0)); + + + Gtk::Image* iblueredL1 = Gtk::manage(new RTImage("ajd-wb-bluered1.png")); + Gtk::Image* iblueredR1 = Gtk::manage(new RTImage("ajd-wb-bluered2.png")); + + adjblur = Gtk::manage(new Adjuster(M("TP_LOCALLAB_ADJ"), -100., 100., 1., 0., iblueredL1, iblueredR1)); + adjblur->setAdjusterListener(this); + + Gtk::Image* bleq = Gtk::manage(new RTImage("previewmodeBC1-on.png")); + Gtk::Image* wheq = Gtk::manage(new RTImage("previewmodeBC2-on.png")); + + noiselequal = Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELEQUAL"), -2, 10, 1, 7, wheq, bleq)); + noiselequal->setAdjusterListener(this); + + if (noiselequal->delay < 200) { + noiselequal->delay = 200; + } + noiselumf->setAdjusterListener(this); + if (noiselumf->delay < 200) { + noiselumf->delay = 200; + } + + noiselumc->setAdjusterListener(this); + + if (noiselumc->delay < 200) { + noiselumc->delay = 200; + } + + noiselumc->set_tooltip_text(M("TP_LOCALLAB_NOISECHROC_TOOLTIP")); + + noiselumdetail->setAdjusterListener(this); + + if (noiselumdetail->delay < 200) { + noiselumdetail->delay = 200; + } + + + noisechrodetail->setAdjusterListener(this); + + if (noisechrodetail->delay < 200) { + noisechrodetail->delay = 200; + } + + bilateral->setAdjusterListener(this); + + if (bilateral->delay < 200) { + bilateral->delay = 200; + } + + sensiden->setAdjusterListener(this); + if (sensiden->delay < 200) { + sensiden->delay = 200; + } + + noisechrof->setAdjusterListener(this); + if (noisechrof->delay < 200) { + noisechrof->delay = 200; + } + + noisechroc->setAdjusterListener(this); + if (noisechroc->delay < 200) { + noisechroc->delay = 200; + } + + + noisechroc->set_tooltip_text(M("TP_LOCALLAB_NOISECHROC_TOOLTIP")); + ToolParamBlock* const denoisBox = Gtk::manage(new ToolParamBlock()); ToolParamBlock* const wavBox = Gtk::manage(new ToolParamBlock()); wavBox->pack_start(*noiselumf); wavBox->pack_start(*noiselumc); wavBox->pack_start(*noiselumdetail); + wavBox->pack_start(*noiselequal); wavBox->pack_start(*noisechrof); wavBox->pack_start(*noisechroc); - wavBox->pack_start(*noisechrodetail); + //wavBox->pack_start(*noisechrodetail); wavBox->pack_start(*adjblur); @@ -1422,6 +1568,7 @@ void Locallab::neutral_pressed() noiselumf->resetValue(false); noiselumc->resetValue(false); noiselumdetail->resetValue(false); + noiselequal->resetValue(false); noisechrof->resetValue(false); noisechroc->resetValue(false); noisechrodetail->resetValue(false); @@ -1990,15 +2137,16 @@ bool Locallab::localComputed_() } bilateral->setValue(nextdatasp[94]); + noiselequal->setValue(nextdatasp[95]); - double intermedblur = 0.01 * (double) nextdatasp[95]; + double intermedblur = 0.01 * (double) nextdatasp[96]; huerefblur->setValue(intermedblur); - double intermed = 0.01 * (double) nextdatasp[96]; + double intermed = 0.01 * (double) nextdatasp[97]; hueref->setValue(intermed); - chromaref->setValue(nextdatasp[97]); - lumaref->setValue(nextdatasp[98]); - sobelref->setValue(nextdatasp[99]); + chromaref->setValue(nextdatasp[98]); + lumaref->setValue(nextdatasp[99]); + sobelref->setValue(nextdatasp[100]); int *s_datc; s_datc = new int[70]; @@ -2315,7 +2463,7 @@ bool Locallab::localComputed_() void Locallab::localChanged(int **datasp, std::string datastr, std::string ll_str, std::string lh_str, std::string cc_str, std::string hh_str, std::string sk_str, std::string ps_str, std::string ex_str, int sp, int maxdat) { - for (int i = 2; i < 100; i++) { + for (int i = 2; i < 101; i++) { nextdatasp[i] = datasp[i][sp]; } @@ -2403,6 +2551,7 @@ void Locallab::read(const ProcParams* pp, const ParamsEdited* pedited) noiselumf->setEditedState(pedited->locallab.noiselumf ? Edited : UnEdited); noiselumc->setEditedState(pedited->locallab.noiselumc ? Edited : UnEdited); noiselumdetail->setEditedState(pedited->locallab.noiselumdetail ? Edited : UnEdited); + noiselequal->setEditedState(pedited->locallab.noiselequal ? Edited : UnEdited); noisechrof->setEditedState(pedited->locallab.noisechrof ? Edited : UnEdited); noisechroc->setEditedState(pedited->locallab.noisechroc ? Edited : UnEdited); noisechrodetail->setEditedState(pedited->locallab.noisechrodetail ? Edited : UnEdited); @@ -2618,6 +2767,7 @@ void Locallab::read(const ProcParams* pp, const ParamsEdited* pedited) noiselumf->setValue(pp->locallab.noiselumf); noiselumc->setValue(pp->locallab.noiselumc); noiselumdetail->setValue(pp->locallab.noiselumdetail); + noiselequal->setValue(pp->locallab.noiselequal); noisechrof->setValue(pp->locallab.noisechrof); noisechroc->setValue(pp->locallab.noisechroc); noisechrodetail->setValue(pp->locallab.noisechrodetail); @@ -3048,6 +3198,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pp->locallab.shcompr = (int)shcompr->getValue(); pp->locallab.noiselumc = noiselumc->getIntValue(); pp->locallab.noiselumdetail = noiselumdetail->getIntValue(); + pp->locallab.noiselequal = noiselequal->getIntValue(); pp->locallab.noisechrodetail = noisechrodetail->getIntValue(); pp->locallab.bilateral = bilateral->getIntValue(); pp->locallab.sensiden = sensiden->getIntValue(); @@ -3165,6 +3316,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pedited->locallab.noiselumf = noiselumf->getEditedState(); pedited->locallab.noiselumc = noiselumc->getEditedState(); pedited->locallab.noiselumdetail = noiselumdetail->getEditedState(); + pedited->locallab.noiselequal = noiselequal->getEditedState(); pedited->locallab.noisechrodetail = noisechrodetail->getEditedState(); pedited->locallab.bilateral = bilateral->getEditedState(); pedited->locallab.sensiden = sensiden->getEditedState(); @@ -3941,6 +4093,7 @@ void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pe noiselumf->setDefault(defParams->locallab.noiselumf); noiselumc->setDefault(defParams->locallab.noiselumc); noiselumdetail->setDefault(defParams->locallab.noiselumdetail); + noiselequal->setDefault(defParams->locallab.noiselequal); noisechrodetail->setDefault(defParams->locallab.noisechrodetail); bilateral->setDefault(defParams->locallab.bilateral); sensiden->setDefault(defParams->locallab.sensiden); @@ -4020,6 +4173,7 @@ void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pe noiselumf->setDefaultEditedState(pedited->locallab.noiselumf ? Edited : UnEdited); noiselumc->setDefaultEditedState(pedited->locallab.noiselumc ? Edited : UnEdited); noiselumdetail->setDefaultEditedState(pedited->locallab.noiselumdetail ? Edited : UnEdited); + noiselequal->setDefaultEditedState(pedited->locallab.noiselequal ? Edited : UnEdited); noisechrodetail->setDefaultEditedState(pedited->locallab.noisechrodetail ? Edited : UnEdited); bilateral->setDefaultEditedState(pedited->locallab.bilateral ? Edited : UnEdited); sensiden->setDefaultEditedState(pedited->locallab.sensiden ? Edited : UnEdited); @@ -4098,6 +4252,7 @@ void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pe noiselumf->setDefaultEditedState(Irrelevant); noiselumc->setDefaultEditedState(Irrelevant); noiselumdetail->setDefaultEditedState(Irrelevant); + noiselequal->setDefaultEditedState(Irrelevant); noisechrodetail->setDefaultEditedState(Irrelevant); bilateral->setDefaultEditedState(Irrelevant); sensiden->setDefaultEditedState(Irrelevant); @@ -4278,6 +4433,8 @@ void Locallab::adjusterChanged(Adjuster * a, double newval) listener->panelChanged(Evlocallabnoiselumc, noiselumc->getTextValue()); } else if (a == noiselumdetail) { listener->panelChanged(Evlocallabnoiselumdetail, noiselumdetail->getTextValue()); + } else if (a == noiselequal) { + listener->panelChanged(Evlocallabnoiselequal, noiselequal->getTextValue()); } else if (a == noisechrodetail) { listener->panelChanged(Evlocallabnoisechrodetail, noisechrodetail->getTextValue()); } else if (a == bilateral) { @@ -4474,6 +4631,7 @@ void Locallab::trimValues(rtengine::procparams::ProcParams * pp) noiselumf->trimValue(pp->locallab.noiselumf); noiselumc->trimValue(pp->locallab.noiselumc); noiselumdetail->trimValue(pp->locallab.noiselumdetail); + noiselequal->trimValue(pp->locallab.noiselequal); noisechrodetail->trimValue(pp->locallab.noisechrodetail); bilateral->trimValue(pp->locallab.bilateral); sensiden->trimValue(pp->locallab.sensiden); @@ -4564,6 +4722,7 @@ void Locallab::setBatchMode(bool batchMode) noiselumf->showEditedCB(); noiselumc->showEditedCB(); noiselumdetail->showEditedCB(); + noiselequal->showEditedCB(); noisechrodetail->showEditedCB(); bilateral->showEditedCB(); sensiden->showEditedCB(); diff --git a/rtgui/locallab.h b/rtgui/locallab.h index 725a617e1..ebf9cf935 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -113,15 +113,15 @@ private: Adjuster* const shardamping; Adjuster* const shariter; Adjuster* const sensisha; - Adjuster* const noiselumf; - Adjuster* const noiselumc; +// Adjuster* const noiselumf; +// Adjuster* const noiselumc; Adjuster* const noiselumdetail; Adjuster* const noisechrodetail; Adjuster* const bilateral; Adjuster* const sensiden; - Adjuster* const noisechrof; - Adjuster* const noisechroc; +// Adjuster* const noisechrof; +// Adjuster* const noisechroc; Adjuster* const hueref; Adjuster* const huerefblur; Adjuster* const chromaref; @@ -205,6 +205,11 @@ private: Adjuster* saturated; Adjuster* warm; Adjuster* adjblur; + Adjuster* noiselequal; + Adjuster* noiselumf; + Adjuster* noiselumc; + Adjuster* noisechrof; + Adjuster* noisechroc; ThresholdAdjuster* psThreshold; Gtk::CheckButton* protectSkins; @@ -239,7 +244,7 @@ private: - int nextdatasp[100]; + int nextdatasp[101]; int nextlength; std::string nextstr; std::string nextstr2; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 484eac483..91c986b2b 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -353,6 +353,7 @@ void ParamsEdited::set(bool v) locallab.noiselumf = v; locallab.noiselumc = v; locallab.noiselumdetail = v; + locallab.noiselequal = v; locallab.noisechrodetail = v; locallab.bilateral = v; locallab.sensiden = v; @@ -1029,6 +1030,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.noiselumf = locallab.noiselumf && p.locallab.noiselumf == other.locallab.noiselumf; locallab.noiselumc = locallab.noiselumc && p.locallab.noiselumc == other.locallab.noiselumc; locallab.noiselumdetail = locallab.noiselumdetail && p.locallab.noiselumdetail == other.locallab.noiselumdetail; + locallab.noiselequal = locallab.noiselequal && p.locallab.noiselequal == other.locallab.noiselequal; locallab.noisechrodetail = locallab.noisechrodetail && p.locallab.noisechrodetail == other.locallab.noisechrodetail; locallab.bilateral = locallab.bilateral && p.locallab.bilateral == other.locallab.bilateral; locallab.sensiden = locallab.sensiden && p.locallab.sensiden == other.locallab.sensiden; @@ -2664,6 +2666,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.noiselumdetail = mods.locallab.noiselumdetail; } + if (locallab.noiselequal) { + toEdit.locallab.noiselequal = mods.locallab.noiselequal; + } + if (locallab.noisechrodetail) { toEdit.locallab.noisechrodetail = mods.locallab.noisechrodetail; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 966631669..edc5f146d 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -477,6 +477,7 @@ public: bool noiselumf; bool noiselumc; bool noiselumdetail; + bool noiselequal; bool noisechrodetail; bool bilateral; bool sensiden;