diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 71030f35b..513039ad6 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -696,37 +696,48 @@ void Crop::update (int todo) int fw = skips(parent->fw, skip); int fh = skips(parent->fh, skip); bool need_cropping = false; + bool need_fattal = true; if (trafx || trafy || trafw != fw || trafh != fh) { need_cropping = true; // fattal needs to work on the full image. So here we get the full // image from imgsrc, and replace the denoised crop in case - f = new Imagefloat(fw, fh); - fattalCrop.reset(f); - PreviewProps pp (0, 0, parent->fw, parent->fh, skip); - int tr = getCoarseBitMask(params.coarse); - parent->imgsrc->getImage(parent->currWB, tr, f, pp, params.toneCurve, params.icm, params.raw); - parent->imgsrc->convertColorSpace(f, params.icm, parent->currWB); + if (!params.dirpyrDenoise.enabled && skip == 1 && parent->fattal_11_dcrop_cache) { + f = parent->fattal_11_dcrop_cache; + need_fattal = false; + } else { + f = new Imagefloat(fw, fh); + fattalCrop.reset(f); + PreviewProps pp (0, 0, parent->fw, parent->fh, skip); + int tr = getCoarseBitMask(params.coarse); + parent->imgsrc->getImage(parent->currWB, tr, f, pp, params.toneCurve, params.icm, params.raw); + parent->imgsrc->convertColorSpace(f, params.icm, parent->currWB); - if (params.dirpyrDenoise.enabled) { - // copy the denoised crop - int oy = trafy / skip; - int ox = trafx / skip; + if (params.dirpyrDenoise.enabled) { + // copy the denoised crop + int oy = trafy / skip; + int ox = trafx / skip; #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel for #endif - for (int y = 0; y < baseCrop->getHeight(); ++y) { - int dy = oy + y; - for (int x = 0; x < baseCrop->getWidth(); ++x) { - int dx = ox + x; - f->r(dy, dx) = baseCrop->r(y, x); - f->g(dy, dx) = baseCrop->g(y, x); - f->b(dy, dx) = baseCrop->b(y, x); + for (int y = 0; y < baseCrop->getHeight(); ++y) { + int dy = oy + y; + for (int x = 0; x < baseCrop->getWidth(); ++x) { + int dx = ox + x; + f->r(dy, dx) = baseCrop->r(y, x); + f->g(dy, dx) = baseCrop->g(y, x); + f->b(dy, dx) = baseCrop->b(y, x); + } } + } else if (skip == 1) { + parent->fattal_11_dcrop_cache = f; // cache this globally + fattalCrop.release(); } } } - parent->ipf.ToneMapFattal02(f); + if (need_fattal) { + parent->ipf.ToneMapFattal02(f); + } // crop back to the size expected by the rest of the pipeline if (need_cropping) { @@ -735,7 +746,7 @@ void Crop::update (int todo) int oy = trafy / skip; int ox = trafx / skip; #ifdef _OPENMP -#pragma omp parallel for + #pragma omp parallel for #endif for (int y = 0; y < trafh; ++y) { int cy = y + oy; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 9172fbf96..532068eee 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -33,7 +33,7 @@ namespace rtengine extern const Settings* settings; ImProcCoordinator::ImProcCoordinator () - : orig_prev (nullptr), oprevi (nullptr), oprevl (nullptr), nprevl (nullptr), previmg (nullptr), workimg (nullptr), + : orig_prev (nullptr), oprevi (nullptr), oprevl (nullptr), nprevl (nullptr), fattal_11_dcrop_cache(nullptr), previmg (nullptr), workimg (nullptr), ncie (nullptr), imgsrc (nullptr), shmap (nullptr), lastAwbEqual (0.), lastAwbTempBias (0.0), ipf (¶ms, true), monitorIntent (RI_RELATIVE), softProof (false), gamutCheck (false), scale (10), highDetailPreprocessComputed (false), highDetailRawComputed (false), allocated (false), bwAutoR (-9000.f), bwAutoG (-9000.f), bwAutoB (-9000.f), CAMMean (NAN), @@ -111,6 +111,10 @@ ImProcCoordinator::~ImProcCoordinator () mProcessing.lock(); mProcessing.unlock(); freeAll (); + if (fattal_11_dcrop_cache) { + delete fattal_11_dcrop_cache; + fattal_11_dcrop_cache = nullptr; + } std::vector toDel = crops; @@ -386,6 +390,10 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) readyphase++; if ((todo & M_HDR) && params.fattal.enabled) { + if (fattal_11_dcrop_cache) { + delete fattal_11_dcrop_cache; + fattal_11_dcrop_cache = nullptr; + } ipf.ToneMapFattal02(orig_prev); if (oprevi != orig_prev) { delete oprevi; diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 41b901e93..2f5fe52e5 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -57,6 +57,7 @@ protected: Imagefloat *oprevi; LabImage *oprevl; LabImage *nprevl; + Imagefloat *fattal_11_dcrop_cache; // global cache for ToneMapFattal02 used in 1:1 detail windows (except when denoise is active) Image8 *previmg; // displayed image in monitor color space, showing the output profile as well (soft-proofing enabled, which then correspond to workimg) or not Image8 *workimg; // internal image in output color space for analysis CieImage *ncie;