diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 818d4d8bb..8bcd1e6a3 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -715,6 +715,13 @@ void Crop::update (int todo) transCrop = nullptr; } + std::unique_ptr fattalCrop; + if ((todo & M_RGBCURVE) && params.fattal.enabled) { + fattalCrop.reset(baseCrop->copy()); + parent->ipf.ToneMapFattal02(fattalCrop.get()); + baseCrop = fattalCrop.get(); + } + if ((todo & (M_TRANSFORM | M_RGBCURVE)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) { const int W = baseCrop->getWidth(); @@ -808,10 +815,6 @@ void Crop::update (int todo) parent->ipf.chromiLuminanceCurve (this, 1, labnCrop, labnCrop, parent->chroma_acurve, parent->chroma_bcurve, parent->satcurve, parent->lhskcurve, parent->clcurve, parent->lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy); parent->ipf.vibrance (labnCrop); - if (params.fattal.enabled) { - parent->ipf.ToneMapFattal02(labnCrop, 3); - } - if ((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) { parent->ipf.EPDToneMap (labnCrop, 5, skip); } diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index e3ff874b6..dffd9572e 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -407,6 +407,15 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) } } + if ((todo & M_RGBCURVE) && params.fattal.enabled) { + Imagefloat *fattalprev = oprevi->copy(); + ipf.ToneMapFattal02(fattalprev); + if (oprevi != orig_prev) { + delete oprevi; + } + oprevi = fattalprev; + } + if ((todo & (M_TRANSFORM | M_RGBCURVE)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) { const int W = oprevi->getWidth(); const int H = oprevi->getHeight(); @@ -636,10 +645,6 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) ipf.chromiLuminanceCurve (nullptr, pW, nprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, histCCurve, histLCurve); ipf.vibrance (nprevl); - if (params.fattal.enabled) { - ipf.ToneMapFattal02(nprevl, 3); - } - if ((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) { ipf.EPDToneMap (nprevl, 5, scale); } diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index c1e4a1e35..46ad670fa 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -347,7 +347,7 @@ public: void Badpixelscam (CieImage * src, CieImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom, int hotbad); void BadpixelsLab (LabImage * src, LabImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom); - void ToneMapFattal02(LabImage *lab, int detail_level); + void ToneMapFattal02(Imagefloat *rgb); Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm); Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, bool bw, GammaValues *ga = nullptr); diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 6cc50a6a8..efe5d7868 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -1102,6 +1102,10 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT baseImg = trImg; } + if (params.fattal.enabled) { + ipf.ToneMapFattal02(baseImg); + } + // update blurmap SHMap* shmap = nullptr; @@ -1275,10 +1279,6 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT ipf.vibrance (labView); - if (params.fattal.enabled) { - ipf.ToneMapFattal02(labView, 0); - } - if ((params.colorappearance.enabled && !params.colorappearance.tonecie) || !params.colorappearance.enabled) { ipf.EPDToneMap (labView, 5, 6); } diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index de57386dd..c8d45acf8 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -833,6 +833,10 @@ private: //ImProcFunctions ipf (¶ms, true); ImProcFunctions &ipf = * (ipf_p.get()); + if (params.fattal.enabled) { + ipf.ToneMapFattal02(baseImg); + } + if (params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) { const int W = baseImg->getWidth(); const int H = baseImg->getHeight(); @@ -1013,10 +1017,6 @@ private: ipf.chromiLuminanceCurve (nullptr, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy); - if (params.fattal.enabled) { - ipf.ToneMapFattal02(labView, 3); - } - if ((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) { ipf.EPDToneMap (labView, 5, 1); } diff --git a/rtengine/tmo_fattal02.cc b/rtengine/tmo_fattal02.cc index 9d015dfdb..768a296b2 100644 --- a/rtengine/tmo_fattal02.cc +++ b/rtengine/tmo_fattal02.cc @@ -1030,7 +1030,9 @@ void rescale_bilinear(const Array2Df &src, Array2Df &dst, bool multithread) float col_scale = float(src.getCols())/float(dst.getCols()); float row_scale = float(src.getRows())/float(dst.getRows()); +#ifdef _OPENMP #pragma omp parallel for if (multithread) +#endif for (int x = 0; x < dst.getCols(); ++x) { for (int y = 0; y < dst.getRows(); ++y) { dst(x, y) = get_bilinear_value(src, x * col_scale, y * row_scale); @@ -1047,17 +1049,17 @@ void tmo_fattal02_RT(Imagefloat *rgb, float alpha, float beta, int detail_level, Array2Df Yr(w, h); Array2Df L(w, h); - rgb->normalizeFloatTo1(); - + const float epsilon = 1e-4f; + +#ifdef _OPENMP #pragma omp parallel for if (multiThread) +#endif for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { - Yr(x, y) = Color::rgbLuminance(rgb->r(y, x), rgb->g(y, x), rgb->b(y, x)); + Yr(x, y) = std::max(Color::rgbLuminance(rgb->r(y, x), rgb->g(y, x), rgb->b(y, x)), epsilon); // clip really black pixels, otherwise it doesn't work at all (not sure why...) } } - // float alpha = params->fattal.alpha; - // float beta = params->fattal.beta; float noise = alpha * 0.01f; if (settings->verbose) { @@ -1067,10 +1069,9 @@ void tmo_fattal02_RT(Imagefloat *rgb, float alpha, float beta, int detail_level, tmo_fattal02(w, h, Yr, L, alpha, beta, noise, detail_level, multiThread); - const float epsilon = 1e-4f; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { - float Y = std::max(Yr(x, y), epsilon); + float Y = Yr(x, y); float l = std::max(L(x, y), epsilon); rgb->r(y, x) = std::max(rgb->r(y, x)/Y, 0.f) * l; rgb->g(y, x) = std::max(rgb->g(y, x)/Y, 0.f) * l; @@ -1084,12 +1085,11 @@ void tmo_fattal02_RT(Imagefloat *rgb, float alpha, float beta, int detail_level, } // namespace -void ImProcFunctions::ToneMapFattal02(LabImage *lab, int detail_level) +void ImProcFunctions::ToneMapFattal02(Imagefloat *rgb) { - Imagefloat tmp(lab->W, lab->H); - lab2rgb(*lab, tmp, params->icm.working); - tmo_fattal02_RT(&tmp, params->fattal.alpha, params->fattal.beta, detail_level, multiThread); - rgb2lab(tmp, *lab, params->icm.working); + const int detail_level = 3; + tmo_fattal02_RT(rgb, params->fattal.alpha, params->fattal.beta, detail_level, multiThread); } + } // namespace rtengine