From cc0e941652b7d0057411ad04299a21203fc3e2bb Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 28 Jul 2024 07:13:58 +0200 Subject: [PATCH] Selective editing - modifies the activation of the Laplacian according to the spots with Dehaze (#7122) * Disable Laplace when others Spot with dehaze * Disable Laplace when others Spot with dehaze * appimage and widows yml with drexpos * Compatibility 5.10 contrast attenuator * Change control out of boud when using Contrast attenuator * Comment code * Comment code * Comment code and fixed * Clip original retinex to avoid crash in some cases * Change tooltip * Clip only Lapalacian if expose or soft enabled * Various improvment to avoid crash * Tonecurve hsv colortoning chmixer not allow negative RGB * Fattal and black need clip issue 7151 * Disable Fattal * Clean code * Disable appimage and windows yml --- rtengine/iplocallab.cc | 71 +++++++++++++++++++++++++++++++++++++++--- rtengine/procparams.cc | 8 ++++- rtgui/locallabtools.cc | 12 +++++-- 3 files changed, 83 insertions(+), 8 deletions(-) diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 9cf83d9cb..13f974d1a 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -85,6 +85,12 @@ constexpr float clipDE(float x) return rtengine::LIM(x, 0.3f, 1.f); } +constexpr float clipR(float x) +{ + return rtengine::LIM(x, 0.f, 65535.f);//used when Laplacian Contrast attenuator +} + + constexpr float clipC(float x) { return rtengine::LIM(x, -100000.f, 100000.f);//increase LIM from 42000 to 1000000 to avoid clip and also imaginaries colors @@ -18000,8 +18006,6 @@ void ImProcFunctions::Lab_Local( } } - - if (exlocalcurve && localexutili) {// L=f(L) curve enhanced #ifdef _OPENMP @@ -18104,8 +18108,8 @@ void ImProcFunctions::Lab_Local( } - if (lp.laplacexp > 0.1f) { - + if (lp.laplacexp > 0.1f) {//don't use if an other spot use Dehaze. + //printf("EXEC ATTENUATOR\n"); MyMutex::MyLock lock(*fftwMutex); std::unique_ptr datain(new float[bfwr * bfhr]); std::unique_ptr dataout(new float[bfwr * bfhr]); @@ -20521,6 +20525,65 @@ void ImProcFunctions::Lab_Local( } } } + int bw = transformed->W; + int bh = transformed->H; + bool notzero = false; //verify that RGB values are > 0.f issue 7121 to avoid crash. Could perhaps be used in other cases as RGB curves (main) + bool notlaplacian = false;//no use of strong Laplacian + + float epsi = 0.000001f; + + + if((lp.laplacexp > 1.f && lp.exposena) || (lp.strng > 2.f && lp.sfena)){//strong Laplacian + notlaplacian = true; + } + + if(((lp.laplacexp > 0.f && lp.laplacexp <= 1.f) && lp.exposena && lp.blac == 0.f)) { // use Laplacian with very small values + notzero = true; + } else if ((lp.laplacexp > 0.f && lp.laplacexp <= 1.f) && lp.exposena && lp.blac != 0.f) {//for curvelocal simplebasecurve with black + notlaplacian = true; + } + + ToneCurveMode curveMode = params->toneCurve.curveMode;//Tone curve does not allow negative values + if((curveMode == ToneCurveMode::PERCEPTUAL) || (curveMode == ToneCurveMode::STD) || (curveMode == ToneCurveMode::WEIGHTEDSTD) || (curveMode == ToneCurveMode::FILMLIKE) || (curveMode == ToneCurveMode::SATANDVALBLENDING) || (curveMode == ToneCurveMode::LUMINANCE)) { + notzero = true; + } + + ToneCurveMode curveMode2 = params->toneCurve.curveMode2;//Tone curve does not allow negative values + if((curveMode2 == ToneCurveMode::PERCEPTUAL) || (curveMode2 == ToneCurveMode::STD) || (curveMode2 == ToneCurveMode::WEIGHTEDSTD) || (curveMode2 == ToneCurveMode::FILMLIKE) || (curveMode2 == ToneCurveMode::SATANDVALBLENDING) || (curveMode2 == ToneCurveMode::LUMINANCE)) { + notzero = true; + } + + if(params->rgbCurves.enabled || params->hsvequalizer.enabled || params->chmixer.enabled || params->colorToning.enabled ) {//rgb curves, HSV, Channel mixer, Color Toning does not allow negative values. Perhaps others cases ? + notzero = true; + } + + if(notlaplacian || notzero) {//allows memory and conversion labrgb only in these cases + const std::unique_ptr prov1(new Imagefloat(bw, bh)); + lab2rgb(*transformed, *prov1, params->icm.workingProfile); + + if(notlaplacian) {//clip value above 65535.f and > epsilon when Contrast attenuator with high values Laplacian or Original Retinex +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int i = 0; i < bh; ++i) + for (int j = 0; j < bw; ++j) { + prov1->r(i, j) = clipR(rtengine::max(prov1->r(i, j), epsi)); + prov1->g(i, j) = clipR(rtengine::max(prov1->g(i, j), epsi)); + prov1->b(i, j) = clipR(rtengine::max(prov1->b(i, j), epsi)); + } + } else if(notzero) {//standard case only with small values Laplace no clip +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int i = 0; i < bh; ++i) + for (int j = 0; j < bw; ++j) { + prov1->r(i, j) = rtengine::max(prov1->r(i, j), epsi); + prov1->g(i, j) = rtengine::max(prov1->g(i, j), epsi); + prov1->b(i, j) = rtengine::max(prov1->b(i, j), epsi); + } + } + rgb2lab(*prov1, *transformed, params->icm.workingProfile); + } // Gamut and Munsell control - very important do not deactivated to avoid crash diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index e1a56a533..8041ab298 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -9235,7 +9235,13 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) spotEdited.visiexpose = true; } + assignFromKeyfile(keyFile, "Locallab", "Laplacexp_" + index_str, spot.laplacexp, spotEdited.laplacexp); assignFromKeyfile(keyFile, "Locallab", "Complexexpose_" + index_str, spot.complexexpose, spotEdited.complexexpose); + if (ppVersion <= 350 && spot.laplacexp > 0.f) { // Contrast attenuator moved to "advanced" after 5.10. Set complexity to "advanced" if Contrast attenuator is in use. + spot.complexexpose = 0; + spotEdited.complexexpose = true; + } + assignFromKeyfile(keyFile, "Locallab", "Expcomp_" + index_str, spot.expcomp, spotEdited.expcomp); assignFromKeyfile(keyFile, "Locallab", "Hlcompr_" + index_str, spot.hlcompr, spotEdited.hlcompr); assignFromKeyfile(keyFile, "Locallab", "Hlcomprthresh_" + index_str, spot.hlcomprthresh, spotEdited.hlcomprthresh); @@ -9277,7 +9283,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "LmaskexpCurve_" + index_str, spot.Lmaskexpcurve, spotEdited.Lmaskexpcurve); assignFromKeyfile(keyFile, "Locallab", "ExpMethod_" + index_str, spot.expMethod, spotEdited.expMethod); assignFromKeyfile(keyFile, "Locallab", "ExnoiseMethod_" + index_str, spot.exnoiseMethod, spotEdited.exnoiseMethod); - assignFromKeyfile(keyFile, "Locallab", "Laplacexp_" + index_str, spot.laplacexp, spotEdited.laplacexp); + // assignFromKeyfile(keyFile, "Locallab", "Laplacexp_" + index_str, spot.laplacexp, spotEdited.laplacexp); assignFromKeyfile(keyFile, "Locallab", "Reparexp_" + index_str, spot.reparexp, spotEdited.reparexp); assignFromKeyfile(keyFile, "Locallab", "Balanexp_" + index_str, spot.balanexp, spotEdited.balanexp); assignFromKeyfile(keyFile, "Locallab", "Linearexp_" + index_str, spot.linear, spotEdited.linear); diff --git a/rtgui/locallabtools.cc b/rtgui/locallabtools.cc index 4c68b004e..7fa0b608c 100644 --- a/rtgui/locallabtools.cc +++ b/rtgui/locallabtools.cc @@ -3796,7 +3796,7 @@ void LocallabExposure::convertParamToNormal() // Disable all listeners disableListener(); gamex->setValue(defSpot.gamex); - + laplacexp->setValue(defSpot.laplacexp); // Set hidden GUI widgets in Normal mode to default spot values structexp->setValue((double)defSpot.structexp); blurexpde->setValue((double)defSpot.blurexpde); @@ -3819,6 +3819,7 @@ void LocallabExposure::convertParamToSimple() // Disable all listeners disableListener(); + laplacexp->setValue(defSpot.laplacexp); fatlevel->setValue(defSpot.fatlevel); fatanchor->setValue(defSpot.fatanchor); norm->set_active(false); @@ -3865,7 +3866,7 @@ void LocallabExposure::updateGUIToMode(const modeType new_type) fatlevel->hide(); fatanchor->hide(); gamex->hide(); - + exppde->hide(); break; case Normal: @@ -3893,6 +3894,7 @@ void LocallabExposure::updateGUIToMode(const modeType new_type) // Specific Simple mode widgets are shown in Normal mode softradiusexp->hide(); blurexpde->hide(); + exppde->hide(); if (!inversex->get_active()) { // Keep widget hidden when invers is toggled expgradexp->show(); @@ -3937,6 +3939,7 @@ void LocallabExposure::updateGUIToMode(const modeType new_type) maskusablee->hide(); maskunusablee->show(); } + exppde->show(); expmaskexp->show(); lapmaskexp->show(); @@ -4192,13 +4195,15 @@ void LocallabExposure::updateExposureGUI3() expcomp->setLabel(M("TP_LOCALLAB_EXPCOMP")); gamex->hide(); expfat->show(); - exppde->show(); + exppde->hide(); if (mode == Normal) { // Keep widgets hidden in Simple mode softradiusexp->show(); expgradexp->show(); exprecove->show(); blurexpde->show(); + exppde->hide(); + } if (mode == Expert) { // Keep widgets hidden in Simple mode softradiusexp->show(); @@ -4207,6 +4212,7 @@ void LocallabExposure::updateExposureGUI3() structexp->show(); blurexpde->show(); gamex->show(); + exppde->show(); }