From 9ccd282d42855d2c6c767dc36b85a4387fb53aa8 Mon Sep 17 00:00:00 2001 From: Desmis Date: Thu, 5 Dec 2019 14:03:03 +0100 Subject: [PATCH] Add Local Encoding Log 1st - thanks to Alberto - Disabled --- rtdata/languages/default | 10 +- rtengine/improccoordinator.cc | 793 +++++++++++++++++++--------------- rtengine/improcfun.h | 4 +- rtengine/iplocallab.cc | 369 +++++++++++++++- rtengine/procevents.h | 17 +- rtengine/procparams.cc | 2 +- rtengine/refreshmap.cc | 14 +- rtengine/rtengine.h | 1 + rtgui/locallab.cc | 131 +++--- rtgui/locallab.h | 1 + 10 files changed, 904 insertions(+), 438 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 0bf90c6f1..c0e919042 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1083,10 +1083,14 @@ HISTORY_MSG_843;Local - Radius Mask blur HISTORY_MSG_844;Local - Color Mask fftw HISTORY_MSG_845;Local - Encoding log HISTORY_MSG_846;Local - Encoding auto -HISTORY_MSG_847;Local - SourceGray -HISTORY_MSG_848;Local - SourceGray auto +HISTORY_MSG_847;Local - Source Gray +HISTORY_MSG_848;Local - Source Gray auto HISTORY_MSG_849;Local - Auto Grayon -HISTORY_MSG_849;Local - Auto Grayoff +HISTORY_MSG_850;Local - Black Ev +HISTORY_MSG_851;Local - White Ev +HISTORY_MSG_852;Local - Target Gray +HISTORY_MSG_853;Local - Detail +HISTORY_MSG_854;Local - Scope encoding log HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 30ae2f456..c6800956d 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -56,11 +56,11 @@ ImProcCoordinator::ImProcCoordinator() : fattal_11_dcrop_cache(nullptr), previmg(nullptr), workimg(nullptr), - ncie (nullptr), - imgsrc (nullptr), - lastAwbEqual (0.), - lastAwbTempBias (0.0), - monitorIntent (RI_RELATIVE), + ncie(nullptr), + imgsrc(nullptr), + lastAwbEqual(0.), + lastAwbTempBias(0.0), + monitorIntent(RI_RELATIVE), softProof(false), gamutCheck(false), sharpMask(false), @@ -165,7 +165,7 @@ ImProcCoordinator::ImProcCoordinator() : customTransformIn(nullptr), customTransformOut(nullptr), ipf(params.get(), true), - //locallab + //locallab locallListener(nullptr), reserv(nullptr), lastorigimp(nullptr), @@ -188,11 +188,11 @@ ImProcCoordinator::ImProcCoordinator() : lmaskretilocalcurve(65536, 0), lmaskcblocalcurve(65536, 0), lmaskbllocalcurve(65536, 0), - locallutili(false), - localclutili(false), - locallcutili(false), - localcutili(false), - localrgbutili(false), + locallutili(false), + localclutili(false), + locallcutili(false), + localcutili(false), + localrgbutili(false), localexutili(false), llmasutili(false), lhmasutili(false), @@ -211,17 +211,17 @@ ImProcCoordinator::ImProcCoordinator() : llmasexputili(false), lcmasSHutili(false), lhmasSHutili(false), - llmasSHutili(false), + llmasSHutili(false), lcmasvibutili(false), lhmasvibutili(false), - llmasvibutili(false), + llmasvibutili(false), lcmascbutili(false), lhmascbutili(false), llmascbutili(false), locwavutili(false), lmasutiliblwav(false), lmasutilicolwav(false), - LHutili(false), + LHutili(false), HHutili(false), lastsavrests(500, -10000), huerefs(500, -100000.f), @@ -284,12 +284,12 @@ ImProcCoordinator::~ImProcCoordinator() imgsrc->decreaseRef(); - if(customTransformIn) { + if (customTransformIn) { cmsDeleteTransform(customTransformIn); customTransformIn = nullptr; } - if(customTransformOut) { + if (customTransformOut) { cmsDeleteTransform(customTransformOut); customTransformOut = nullptr; } @@ -371,9 +371,11 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) imgsrc->setCurrentFrame(params->raw.bayersensor.imageNum); imgsrc->preprocess(rp, params->lensProf, params->coarse); + if (flatFieldAutoClipListener && rp.ff_AutoClipControl) { flatFieldAutoClipListener->flatFieldAutoClipValueChanged(imgsrc->getFlatFieldAutoClipValue()); } + imgsrc->getRAWHistogram(histRedRaw, histGreenRaw, histBlueRaw); highDetailPreprocessComputed = highDetailNeeded; @@ -419,8 +421,9 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) printf("Demosaic X-Trans image with using method: %s\n", rp.xtranssensor.method.c_str()); } } - if(imgsrc->getSensorType() == ST_BAYER) { - if(params->raw.bayersensor.method != RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::PIXELSHIFT)) { + + if (imgsrc->getSensorType() == ST_BAYER) { + if (params->raw.bayersensor.method != RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::PIXELSHIFT)) { imgsrc->setBorder(params->raw.bayersensor.border); } else { imgsrc->setBorder(std::max(params->raw.bayersensor.border, 2)); @@ -428,6 +431,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } else if (imgsrc->getSensorType() == ST_FUJI_XTRANS) { imgsrc->setBorder(params->raw.xtranssensor.border); } + bool autoContrast = imgsrc->getSensorType() == ST_BAYER ? params->raw.bayersensor.dualDemosaicAutoContrast : params->raw.xtranssensor.dualDemosaicAutoContrast; double contrastThreshold = imgsrc->getSensorType() == ST_BAYER ? params->raw.bayersensor.dualDemosaicContrast : params->raw.xtranssensor.dualDemosaicContrast; imgsrc->demosaic(rp, autoContrast, contrastThreshold, params->pdsharpening.enabled); @@ -437,6 +441,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } else if (imgsrc->getSensorType() == ST_FUJI_XTRANS && xtransAutoContrastListener && autoContrast) { xtransAutoContrastListener->autoContrastChanged(autoContrast ? contrastThreshold : -1.0); } + // if a demosaic happened we should also call getimage later, so we need to set the M_INIT flag todo |= (M_INIT | M_CSHARP); @@ -446,9 +451,11 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) double pdSharpencontrastThreshold = params->pdsharpening.contrast; double pdSharpenRadius = params->pdsharpening.deconvradius; imgsrc->captureSharpening(params->pdsharpening, sharpMask, pdSharpencontrastThreshold, pdSharpenRadius); + if (pdSharpenAutoContrastListener && params->pdsharpening.autoContrast) { pdSharpenAutoContrastListener->autoContrastChanged(pdSharpencontrastThreshold); } + if (pdSharpenAutoRadiusListener && params->pdsharpening.autoRadius) { pdSharpenAutoRadiusListener->autoRadiusChanged(pdSharpenRadius); } @@ -695,9 +702,66 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) aeListener->autoMatchedToneCurveChanged(params->toneCurve.curveMode, params->toneCurve.curve); } } + + //encoding log with locallab + if (params->locallab.enabled) { + int sizespot = (int)params->locallab.spots.size(); + float *sourceg = nullptr; + sourceg = new float[sizespot]; + float *targetg = nullptr; + targetg = new float[sizespot]; + bool *log = nullptr; + log = new bool[sizespot]; + bool *autocomput = nullptr; + autocomput = new bool[sizespot]; + float *blackev = nullptr; + blackev = new float[sizespot]; + float *whiteev = nullptr; + whiteev = new float[sizespot]; + bool *Autogr = nullptr; + Autogr = new bool[sizespot]; + + for (int sp = 0; sp < params->locallab.nbspot && sp < sizespot; sp++) { + log[sp] = params->locallab.spots.at(sp).explog; + autocomput[sp] = params->locallab.spots.at(sp).autocompute; + // sourcegray blackev, whitev + blackev[sp] = params->locallab.spots.at(sp).blackEv; + whiteev[sp] = params->locallab.spots.at(sp).whiteEv; + sourceg[sp] = params->locallab.spots.at(sp).sourceGray; + Autogr[sp] = params->locallab.spots.at(sp).Autogray; + targetg[sp] = params->locallab.spots.at(sp).targetGray; + + if (log[sp] && autocomput[sp]) { + constexpr int SCALE = 10; + int fw, fh, tr = TR_NONE; + imgsrc->getFullSize(fw, fh, tr); + PreviewProps pp(0, 0, fw, fh, SCALE); + + ipf.getAutoLogloc(sp, imgsrc, sourceg, blackev, whiteev, Autogr, fw, fh, SCALE); + params->locallab.spots.at(sp).blackEv = blackev[sp]; + params->locallab.spots.at(sp).whiteEv = whiteev[sp]; + params->locallab.spots.at(sp).sourceGray = sourceg[sp]; + + if (locallListener) { + locallListener->logencodChanged(blackev[sp], whiteev[sp], sourceg[sp], targetg[sp]); + } + + } + } + + delete [] Autogr; + delete [] whiteev; + delete [] blackev; + delete [] targetg; + delete [] sourceg; + delete [] log; + delete [] autocomput; + } + + } - if (todo & (M_AUTOEXP | M_RGBCURVE)) { + if (todo & (M_AUTOEXP | M_RGBCURVE)) { if (params->icm.workingTRC == "Custom") { //exec TRC IN free if (oprevi == orig_prev) { oprevi = new Imagefloat(pW, pH); @@ -709,17 +773,21 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if (profile == "sRGB" || profile == "Adobe RGB" || profile == "ProPhoto" || profile == "WideGamut" || profile == "BruceRGB" || profile == "Beta RGB" || profile == "BestRGB" || profile == "Rec2020" || profile == "ACESp0" || profile == "ACESp1") { const int cw = oprevi->getWidth(); const int ch = oprevi->getHeight(); + // put gamma TRC to 1 - if(customTransformIn) { + if (customTransformIn) { cmsDeleteTransform(customTransformIn); customTransformIn = nullptr; } + ipf.workingtrc(oprevi, oprevi, cw, ch, -5, params->icm.workingProfile, 2.4, 12.92310, customTransformIn, true, false, true); + //adjust TRC - if(customTransformOut) { + if (customTransformOut) { cmsDeleteTransform(customTransformOut); customTransformOut = nullptr; } + ipf.workingtrc(oprevi, oprevi, cw, ch, 5, params->icm.workingProfile, params->icm.workingTRCGamma, params->icm.workingTRCSlope, customTransformOut, false, true, true); } } @@ -727,7 +795,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if ((todo & M_RGBCURVE) || (todo & M_CROP)) { - // if (hListener) oprevi->calcCroppedHistogram(params, scale, histCropped); + // if (hListener) oprevi->calcCroppedHistogram(params, scale, histCropped); //complexCurve also calculated pre-curves histogram depending on crop CurveFactory::complexCurve(params->toneCurve.expcomp, params->toneCurve.black / 65535.0, @@ -821,7 +889,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) DCPProfileApplyState as; DCPProfile *dcpProf = imgsrc->getDCP(params->icm, as); - ipf.rgbProc (oprevi, oprevl, nullptr, hltonecurve, shtonecurve, tonecurve, params->toneCurve.saturation, + ipf.rgbProc(oprevi, oprevl, nullptr, hltonecurve, shtonecurve, tonecurve, params->toneCurve.saturation, rCurve, gCurve, bCurve, colourToningSatLimit, colourToningSatLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, beforeToneCurveBW, afterToneCurveBW, rrm, ggm, bbm, bwAutoR, bwAutoG, bwAutoB, params->toneCurve.expcomp, params->toneCurve.hlcompr, params->toneCurve.hlcomprthresh, dcpProf, as, histToneCurve); if (params->blackwhite.enabled && params->blackwhite.autoc && abwListener) { @@ -839,7 +907,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) // correct GUI black and white with value } - // ipf.Lab_Tile(oprevl, oprevl, scale); + // ipf.Lab_Tile(oprevl, oprevl, scale); // compute L channel histogram int x1, y1, x2, y2; @@ -886,344 +954,354 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) params->labCurve.lccurve, chroma_acurve, chroma_bcurve, satcurve, lhskcurve, scale == 1 ? 1 : 16); } - //scale = 1; - if (todo & (M_LUMINANCE + M_COLOR)) { + //scale = 1; + + if ((todo & (M_LUMINANCE + M_COLOR)) || (todo & M_AUTOEXP)) { nprevl->CopyFrom(oprevl); - reserv->CopyFrom(oprevl); - lastorigimp->CopyFrom(oprevl); + reserv->CopyFrom(oprevl); + lastorigimp->CopyFrom(oprevl); - // int maxspot = 1; - //************************************************************* - // locallab - //************************************************************* + // int maxspot = 1; + //************************************************************* + // locallab + //************************************************************* - if (params->locallab.enabled) { - /* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - * 2017 2018 Jacques Desmis - * 2018 Pierre Cabrera - */ - - float **shbuffer = nullptr; - int sca = 1; - double huere, chromare, lumare, huerefblu, chromarefblu, lumarefblu, sobelre; - // int lastsavee; - float avge; - - for (int sp = 0; sp < params->locallab.nbspot && sp < (int)params->locallab.spots.size(); sp++) { - // Set local curves of current spot to LUT - LHutili = false; - HHutili = false; - locallutili = false; - localclutili = false; - locallcutili = false; - localexutili = false; - localrgbutili = false; - localcutili = false; - llmasutili = false; - lhmasutili = false; - lhhmasutili = false; - lcmasutili = false; - localmaskutili = false; - lcmasexputili = false; - lhmasexputili = false; - llmasexputili = false; - localmaskexputili = false; - localmaskSHutili = false; - localmaskvibutili = false; - localmasktmutili = false; - localmaskretiutili = false; - localmaskcbutili = false; - localmaskblutili = false; - lcmasSHutili = false; - lhmasSHutili = false; - llmasSHutili = false; - lcmasvibutili = false; - lhmasvibutili = false; - llmasvibutili = false; - lcmascbutili = false; - lhmascbutili = false; - llmascbutili = false; - lcmasretiutili = false; - lhmasretiutili = false; - llmasretiutili = false; - lcmastmutili = false; - lhmastmutili = false; - llmastmutili = false; - lcmasblutili = false; - lhmasblutili = false; - llmasblutili = false; - lcmasutili = false; - locwavutili = false; - lmasutiliblwav = false; - lmasutilicolwav = false; - locRETgainCurve.Set(params->locallab.spots.at(sp).localTgaincurve); - locRETtransCurve.Set(params->locallab.spots.at(sp).localTtranscurve); - loclhCurve.Set(params->locallab.spots.at(sp).LHcurve, LHutili); - lochhCurve.Set(params->locallab.spots.at(sp).HHcurve, HHutili); - locccmasCurve.Set(params->locallab.spots.at(sp).CCmaskcurve, lcmasutili); - locllmasCurve.Set(params->locallab.spots.at(sp).LLmaskcurve, llmasutili); - lochhmasCurve.Set(params->locallab.spots.at(sp).HHmaskcurve, lhmasutili); - lochhhmasCurve.Set(params->locallab.spots.at(sp).HHhmaskcurve, lhhmasutili); - locllmasexpCurve.Set(params->locallab.spots.at(sp).LLmaskexpcurve, llmasexputili); - locccmasexpCurve.Set(params->locallab.spots.at(sp).CCmaskexpcurve, lcmasexputili); - lochhmasexpCurve.Set(params->locallab.spots.at(sp).HHmaskexpcurve, lhmasexputili); - locllmasSHCurve.Set(params->locallab.spots.at(sp).LLmaskSHcurve, llmasSHutili); - locccmasSHCurve.Set(params->locallab.spots.at(sp).CCmaskSHcurve, lcmasSHutili); - lochhmasSHCurve.Set(params->locallab.spots.at(sp).HHmaskSHcurve, lhmasSHutili); - locllmasvibCurve.Set(params->locallab.spots.at(sp).LLmaskvibcurve, llmasvibutili); - locccmasvibCurve.Set(params->locallab.spots.at(sp).CCmaskvibcurve, lcmasvibutili); - lochhmasvibCurve.Set(params->locallab.spots.at(sp).HHmaskvibcurve, lhmasvibutili); - locllmascbCurve.Set(params->locallab.spots.at(sp).LLmaskcbcurve, llmascbutili); - locccmascbCurve.Set(params->locallab.spots.at(sp).CCmaskcbcurve, lcmascbutili); - lochhmascbCurve.Set(params->locallab.spots.at(sp).HHmaskcbcurve, lhmascbutili); - locllmasretiCurve.Set(params->locallab.spots.at(sp).LLmaskreticurve, llmasretiutili); - locccmasretiCurve.Set(params->locallab.spots.at(sp).CCmaskreticurve, lcmasretiutili); - lochhmasretiCurve.Set(params->locallab.spots.at(sp).HHmaskreticurve, lhmasretiutili); - locllmastmCurve.Set(params->locallab.spots.at(sp).LLmasktmcurve, llmastmutili); - locccmastmCurve.Set(params->locallab.spots.at(sp).CCmasktmcurve, lcmastmutili); - lochhmastmCurve.Set(params->locallab.spots.at(sp).HHmasktmcurve, lhmastmutili); - locllmasblCurve.Set(params->locallab.spots.at(sp).LLmaskblcurve, llmasblutili); - locccmasblCurve.Set(params->locallab.spots.at(sp).CCmaskblcurve, lcmasblutili); - lochhmasblCurve.Set(params->locallab.spots.at(sp).HHmaskblcurve, lhmasblutili); - loclmasCurveblwav.Set(params->locallab.spots.at(sp).LLmaskblcurvewav, lmasutiliblwav); - loclmasCurvecolwav.Set(params->locallab.spots.at(sp).LLmaskcolcurvewav, lmasutilicolwav); - - locwavCurve.Set(params->locallab.spots.at(sp).locwavcurve, locwavutili); - CurveFactory::curveLocal(locallutili, params->locallab.spots.at(sp).llcurve, lllocalcurve, sca); - CurveFactory::curveLocal(localclutili, params->locallab.spots.at(sp).clcurve, cllocalcurve, sca); - CurveFactory::curveLocal(locallcutili, params->locallab.spots.at(sp).lccurve, lclocalcurve, sca); - CurveFactory::curveCCLocal(localcutili, params->locallab.spots.at(sp).cccurve, cclocalcurve, sca); - CurveFactory::curveLocal(localrgbutili, params->locallab.spots.at(sp).rgbcurve, rgblocalcurve, sca); - CurveFactory::curveexLocal(localexutili, params->locallab.spots.at(sp).excurve, exlocalcurve, sca); - CurveFactory::curvemaskLocal(localmaskutili, params->locallab.spots.at(sp).Lmaskcurve, lmasklocalcurve, sca); - CurveFactory::curvemaskLocal(localmaskexputili, params->locallab.spots.at(sp).Lmaskexpcurve, lmaskexplocalcurve, sca); - CurveFactory::curvemaskLocal(localmaskSHutili, params->locallab.spots.at(sp).LmaskSHcurve, lmaskSHlocalcurve, sca); - CurveFactory::curvemaskLocal(localmaskvibutili, params->locallab.spots.at(sp).Lmaskvibcurve, lmaskviblocalcurve, sca); - CurveFactory::curvemaskLocal(localmasktmutili, params->locallab.spots.at(sp).Lmasktmcurve, lmasktmlocalcurve, sca); - CurveFactory::curvemaskLocal(localmaskretiutili, params->locallab.spots.at(sp).Lmaskreticurve, lmaskretilocalcurve, sca); - CurveFactory::curvemaskLocal(localmaskcbutili, params->locallab.spots.at(sp).Lmaskcbcurve, lmaskcblocalcurve, sca); - CurveFactory::curvemaskLocal(localmaskblutili, params->locallab.spots.at(sp).Lmaskblcurve, lmaskbllocalcurve, sca); - double ecomp = params->locallab.spots.at(sp).expcomp; - double black = params->locallab.spots.at(sp).black; - double hlcompr = params->locallab.spots.at(sp).hlcompr; - double hlcomprthresh = params->locallab.spots.at(sp).hlcomprthresh; - double shcompr = params->locallab.spots.at(sp).shcompr; - double br = params->locallab.spots.at(sp).lightness; - double cont = params->locallab.spots.at(sp).contrast; - if(black < 0. && params->locallab.spots.at(sp).expMethod == "pde" ) { - black *= 1.5; - } - // Reference parameters computation - if (params->locallab.spots.at(sp).spotMethod == "exc") { - ipf.calc_ref(sp, reserv, reserv, 0, 0, pW, pH, scale, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, avge); - } else { - ipf.calc_ref(sp, nprevl, nprevl, 0, 0, pW, pH, scale, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, avge); - } + if (params->locallab.enabled) { /* - printf("lastorig=%i sp=%i\n", lastsavrests[sp], sp); + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + * 2017 2018 Jacques Desmis + * 2018 Pierre Cabrera + */ - if(params->locallab.spots.at(sp).savrest && (lastsavrests[sp] == 0)) { - lastsavrests[sp] = 2;//save image flag=2 - } else if(params->locallab.spots.at(sp).savrest && lastsavrests[sp] == 2){ - lastsavrests[sp] = 1; // let image save with no changes flag = 1 - } else if(!params->locallab.spots.at(sp).savrest && (lastsavrests[sp] == 2 || lastsavrests[sp] == 1)) { - lastsavrests[sp] = -1; // restore image only if image create, set flag -1 - } else if(!params->locallab.spots.at(sp).savrest && (lastsavrests[sp] != 2 && lastsavrests[sp] != 1)) { - lastsavrests[sp] = 0; // does nothing if image was not save - } - lastsav = lastsavrests[sp]; - printf("lastsav=%i sp=%i\n", lastsav, sp); - */ + float **shbuffer = nullptr; + int sca = 1; + double huere, chromare, lumare, huerefblu, chromarefblu, lumarefblu, sobelre; + // int lastsavee; + float avge; + + for (int sp = 0; sp < params->locallab.nbspot && sp < (int)params->locallab.spots.size(); sp++) { + // Set local curves of current spot to LUT + LHutili = false; + HHutili = false; + locallutili = false; + localclutili = false; + locallcutili = false; + localexutili = false; + localrgbutili = false; + localcutili = false; + llmasutili = false; + lhmasutili = false; + lhhmasutili = false; + lcmasutili = false; + localmaskutili = false; + lcmasexputili = false; + lhmasexputili = false; + llmasexputili = false; + localmaskexputili = false; + localmaskSHutili = false; + localmaskvibutili = false; + localmasktmutili = false; + localmaskretiutili = false; + localmaskcbutili = false; + localmaskblutili = false; + lcmasSHutili = false; + lhmasSHutili = false; + llmasSHutili = false; + lcmasvibutili = false; + lhmasvibutili = false; + llmasvibutili = false; + lcmascbutili = false; + lhmascbutili = false; + llmascbutili = false; + lcmasretiutili = false; + lhmasretiutili = false; + llmasretiutili = false; + lcmastmutili = false; + lhmastmutili = false; + llmastmutili = false; + lcmasblutili = false; + lhmasblutili = false; + llmasblutili = false; + lcmasutili = false; + locwavutili = false; + lmasutiliblwav = false; + lmasutilicolwav = false; + locRETgainCurve.Set(params->locallab.spots.at(sp).localTgaincurve); + locRETtransCurve.Set(params->locallab.spots.at(sp).localTtranscurve); + loclhCurve.Set(params->locallab.spots.at(sp).LHcurve, LHutili); + lochhCurve.Set(params->locallab.spots.at(sp).HHcurve, HHutili); + locccmasCurve.Set(params->locallab.spots.at(sp).CCmaskcurve, lcmasutili); + locllmasCurve.Set(params->locallab.spots.at(sp).LLmaskcurve, llmasutili); + lochhmasCurve.Set(params->locallab.spots.at(sp).HHmaskcurve, lhmasutili); + lochhhmasCurve.Set(params->locallab.spots.at(sp).HHhmaskcurve, lhhmasutili); + locllmasexpCurve.Set(params->locallab.spots.at(sp).LLmaskexpcurve, llmasexputili); + locccmasexpCurve.Set(params->locallab.spots.at(sp).CCmaskexpcurve, lcmasexputili); + lochhmasexpCurve.Set(params->locallab.spots.at(sp).HHmaskexpcurve, lhmasexputili); + locllmasSHCurve.Set(params->locallab.spots.at(sp).LLmaskSHcurve, llmasSHutili); + locccmasSHCurve.Set(params->locallab.spots.at(sp).CCmaskSHcurve, lcmasSHutili); + lochhmasSHCurve.Set(params->locallab.spots.at(sp).HHmaskSHcurve, lhmasSHutili); + locllmasvibCurve.Set(params->locallab.spots.at(sp).LLmaskvibcurve, llmasvibutili); + locccmasvibCurve.Set(params->locallab.spots.at(sp).CCmaskvibcurve, lcmasvibutili); + lochhmasvibCurve.Set(params->locallab.spots.at(sp).HHmaskvibcurve, lhmasvibutili); + locllmascbCurve.Set(params->locallab.spots.at(sp).LLmaskcbcurve, llmascbutili); + locccmascbCurve.Set(params->locallab.spots.at(sp).CCmaskcbcurve, lcmascbutili); + lochhmascbCurve.Set(params->locallab.spots.at(sp).HHmaskcbcurve, lhmascbutili); + locllmasretiCurve.Set(params->locallab.spots.at(sp).LLmaskreticurve, llmasretiutili); + locccmasretiCurve.Set(params->locallab.spots.at(sp).CCmaskreticurve, lcmasretiutili); + lochhmasretiCurve.Set(params->locallab.spots.at(sp).HHmaskreticurve, lhmasretiutili); + locllmastmCurve.Set(params->locallab.spots.at(sp).LLmasktmcurve, llmastmutili); + locccmastmCurve.Set(params->locallab.spots.at(sp).CCmasktmcurve, lcmastmutili); + lochhmastmCurve.Set(params->locallab.spots.at(sp).HHmasktmcurve, lhmastmutili); + locllmasblCurve.Set(params->locallab.spots.at(sp).LLmaskblcurve, llmasblutili); + locccmasblCurve.Set(params->locallab.spots.at(sp).CCmaskblcurve, lcmasblutili); + lochhmasblCurve.Set(params->locallab.spots.at(sp).HHmaskblcurve, lhmasblutili); + loclmasCurveblwav.Set(params->locallab.spots.at(sp).LLmaskblcurvewav, lmasutiliblwav); + loclmasCurvecolwav.Set(params->locallab.spots.at(sp).LLmaskcolcurvewav, lmasutilicolwav); + + locwavCurve.Set(params->locallab.spots.at(sp).locwavcurve, locwavutili); + CurveFactory::curveLocal(locallutili, params->locallab.spots.at(sp).llcurve, lllocalcurve, sca); + CurveFactory::curveLocal(localclutili, params->locallab.spots.at(sp).clcurve, cllocalcurve, sca); + CurveFactory::curveLocal(locallcutili, params->locallab.spots.at(sp).lccurve, lclocalcurve, sca); + CurveFactory::curveCCLocal(localcutili, params->locallab.spots.at(sp).cccurve, cclocalcurve, sca); + CurveFactory::curveLocal(localrgbutili, params->locallab.spots.at(sp).rgbcurve, rgblocalcurve, sca); + CurveFactory::curveexLocal(localexutili, params->locallab.spots.at(sp).excurve, exlocalcurve, sca); + CurveFactory::curvemaskLocal(localmaskutili, params->locallab.spots.at(sp).Lmaskcurve, lmasklocalcurve, sca); + CurveFactory::curvemaskLocal(localmaskexputili, params->locallab.spots.at(sp).Lmaskexpcurve, lmaskexplocalcurve, sca); + CurveFactory::curvemaskLocal(localmaskSHutili, params->locallab.spots.at(sp).LmaskSHcurve, lmaskSHlocalcurve, sca); + CurveFactory::curvemaskLocal(localmaskvibutili, params->locallab.spots.at(sp).Lmaskvibcurve, lmaskviblocalcurve, sca); + CurveFactory::curvemaskLocal(localmasktmutili, params->locallab.spots.at(sp).Lmasktmcurve, lmasktmlocalcurve, sca); + CurveFactory::curvemaskLocal(localmaskretiutili, params->locallab.spots.at(sp).Lmaskreticurve, lmaskretilocalcurve, sca); + CurveFactory::curvemaskLocal(localmaskcbutili, params->locallab.spots.at(sp).Lmaskcbcurve, lmaskcblocalcurve, sca); + CurveFactory::curvemaskLocal(localmaskblutili, params->locallab.spots.at(sp).Lmaskblcurve, lmaskbllocalcurve, sca); + double ecomp = params->locallab.spots.at(sp).expcomp; + double black = params->locallab.spots.at(sp).black; + double hlcompr = params->locallab.spots.at(sp).hlcompr; + double hlcomprthresh = params->locallab.spots.at(sp).hlcomprthresh; + double shcompr = params->locallab.spots.at(sp).shcompr; + double br = params->locallab.spots.at(sp).lightness; + double cont = params->locallab.spots.at(sp).contrast; + + if (black < 0. && params->locallab.spots.at(sp).expMethod == "pde") { + black *= 1.5; + } + + // Reference parameters computation + if (params->locallab.spots.at(sp).spotMethod == "exc") { + ipf.calc_ref(sp, reserv, reserv, 0, 0, pW, pH, scale, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, avge); + } else { + ipf.calc_ref(sp, nprevl, nprevl, 0, 0, pW, pH, scale, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, avge); + } + + /* + printf("lastorig=%i sp=%i\n", lastsavrests[sp], sp); + + if(params->locallab.spots.at(sp).savrest && (lastsavrests[sp] == 0)) { + lastsavrests[sp] = 2;//save image flag=2 + } else if(params->locallab.spots.at(sp).savrest && lastsavrests[sp] == 2){ + lastsavrests[sp] = 1; // let image save with no changes flag = 1 + } else if(!params->locallab.spots.at(sp).savrest && (lastsavrests[sp] == 2 || lastsavrests[sp] == 1)) { + lastsavrests[sp] = -1; // restore image only if image create, set flag -1 + } else if(!params->locallab.spots.at(sp).savrest && (lastsavrests[sp] != 2 && lastsavrests[sp] != 1)) { + lastsavrests[sp] = 0; // does nothing if image was not save + } + lastsav = lastsavrests[sp]; + printf("lastsav=%i sp=%i\n", lastsav, sp); + */ // printf("improc avg=%f\n", avg); - huerblu = huerefblurs[sp] = huerefblu; - chromarblu = chromarefblurs[sp] = chromarefblu; - lumarblu = lumarefblurs[sp] = lumarefblu; - huer = huerefs[sp] = huere; - chromar = chromarefs[sp] = chromare; - lumar = lumarefs[sp] = lumare ; - sobeler = sobelrefs[sp] = sobelre; - avg = avgs[sp] = avge; - CurveFactory::complexCurvelocal(ecomp, black / 65535., hlcompr, hlcomprthresh, shcompr, br, cont, lumar, - hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, avg, - sca); + huerblu = huerefblurs[sp] = huerefblu; + chromarblu = chromarefblurs[sp] = chromarefblu; + lumarblu = lumarefblurs[sp] = lumarefblu; + huer = huerefs[sp] = huere; + chromar = chromarefs[sp] = chromare; + lumar = lumarefs[sp] = lumare ; + sobeler = sobelrefs[sp] = sobelre; + avg = avgs[sp] = avge; + CurveFactory::complexCurvelocal(ecomp, black / 65535., hlcompr, hlcomprthresh, shcompr, br, cont, lumar, + hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, avg, + sca); - // Locallab mask curve references are only shown for selected spot - if (sp == params->locallab.selspot) { - if (locallListener) { - locallListener->refChanged(huer, lumar, chromar); + // Locallab mask curve references are only shown for selected spot + if (sp == params->locallab.selspot) { + if (locallListener) { + locallListener->refChanged(huer, lumar, chromar); + } } - } - // Locallab tools computation - /* Notes: - * - shbuffer is used as nullptr - */ - // Locallab mask are only shown for selected spot - float minCD; - float maxCD; - float mini; - float maxi; - float Tmean; - float Tsigma; - float Tmin; - float Tmax; + // Locallab tools computation + /* Notes: + * - shbuffer is used as nullptr + */ + // Locallab mask are only shown for selected spot + float minCD; + float maxCD; + float mini; + float maxi; + float Tmean; + float Tsigma; + float Tmin; + float Tmax; - if (sp == params->locallab.selspot) { - ipf.Lab_Local(3, sp, (float**)shbuffer, nprevl, nprevl, reserv, lastorigimp, 0, 0, pW, pH, scale, locRETgainCurve, locRETtransCurve, - lllocalcurve, locallutili, - cllocalcurve, localclutili, - lclocalcurve, locallcutili, - loclhCurve, lochhCurve, - lmasklocalcurve, localmaskutili, - lmaskexplocalcurve, localmaskexputili, - lmaskSHlocalcurve, localmaskSHutili, - lmaskviblocalcurve, localmaskvibutili, - lmasktmlocalcurve, localmasktmutili, - lmaskretilocalcurve, localmaskretiutili, - lmaskcblocalcurve, localmaskcbutili, - lmaskbllocalcurve, localmaskblutili, - locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, lochhhmasCurve, lhhmasutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, - locccmasSHCurve, lcmasSHutili, locllmasSHCurve, llmasSHutili, lochhmasSHCurve, lhmasSHutili, - locccmasvibCurve, lcmasvibutili, locllmasvibCurve, llmasvibutili, lochhmasvibCurve, lhmasvibutili, - locccmascbCurve, lcmascbutili, locllmascbCurve, llmascbutili, lochhmascbCurve, lhmascbutili, - locccmasretiCurve, lcmasretiutili, locllmasretiCurve, llmasretiutili, lochhmasretiCurve, lhmasretiutili, - locccmastmCurve, lcmastmutili, locllmastmCurve, llmastmutili, lochhmastmCurve, lhmastmutili, - locccmasblCurve, lcmasblutili, locllmasblCurve, llmasblutili, lochhmasblCurve, lhmasblutili, - loclmasCurveblwav,lmasutiliblwav, - loclmasCurvecolwav,lmasutilicolwav, - locwavCurve, locwavutili, - LHutili, HHutili, cclocalcurve, localcutili, rgblocalcurve, localrgbutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, - huerblu, chromarblu, lumarblu, huer, chromar, lumar, sobeler, lastsav, - locallColorMask, locallColorMaskinv, locallExpMask, locallExpMaskinv, locallSHMask, locallSHMaskinv, locallvibMask, locallcbMask, locallretiMask, locallsoftMask, localltmMask, locallblMask, - minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); - if (locallListener) { - locallListener->minmaxChanged(maxCD, minCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); + if (sp == params->locallab.selspot) { + ipf.Lab_Local(3, sp, (float**)shbuffer, nprevl, nprevl, reserv, lastorigimp, 0, 0, pW, pH, scale, locRETgainCurve, locRETtransCurve, + lllocalcurve, locallutili, + cllocalcurve, localclutili, + lclocalcurve, locallcutili, + loclhCurve, lochhCurve, + lmasklocalcurve, localmaskutili, + lmaskexplocalcurve, localmaskexputili, + lmaskSHlocalcurve, localmaskSHutili, + lmaskviblocalcurve, localmaskvibutili, + lmasktmlocalcurve, localmasktmutili, + lmaskretilocalcurve, localmaskretiutili, + lmaskcblocalcurve, localmaskcbutili, + lmaskbllocalcurve, localmaskblutili, + locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, lochhhmasCurve, lhhmasutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, + locccmasSHCurve, lcmasSHutili, locllmasSHCurve, llmasSHutili, lochhmasSHCurve, lhmasSHutili, + locccmasvibCurve, lcmasvibutili, locllmasvibCurve, llmasvibutili, lochhmasvibCurve, lhmasvibutili, + locccmascbCurve, lcmascbutili, locllmascbCurve, llmascbutili, lochhmascbCurve, lhmascbutili, + locccmasretiCurve, lcmasretiutili, locllmasretiCurve, llmasretiutili, lochhmasretiCurve, lhmasretiutili, + locccmastmCurve, lcmastmutili, locllmastmCurve, llmastmutili, lochhmastmCurve, lhmastmutili, + locccmasblCurve, lcmasblutili, locllmasblCurve, llmasblutili, lochhmasblCurve, lhmasblutili, + loclmasCurveblwav, lmasutiliblwav, + loclmasCurvecolwav, lmasutilicolwav, + locwavCurve, locwavutili, + LHutili, HHutili, cclocalcurve, localcutili, rgblocalcurve, localrgbutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, + huerblu, chromarblu, lumarblu, huer, chromar, lumar, sobeler, lastsav, + locallColorMask, locallColorMaskinv, locallExpMask, locallExpMaskinv, locallSHMask, locallSHMaskinv, locallvibMask, locallcbMask, locallretiMask, locallsoftMask, localltmMask, locallblMask, + minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); + + if (locallListener) { + locallListener->minmaxChanged(maxCD, minCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); + } + if (locallListener && params->locallab.spots.at(sp).explog) { + locallListener->logencodChanged(params->locallab.spots.at(sp).blackEv, params->locallab.spots.at(sp).whiteEv, params->locallab.spots.at(sp).sourceGray, params->locallab.spots.at(sp).targetGray); + } + + } else { + ipf.Lab_Local(3, sp, (float**)shbuffer, nprevl, nprevl, reserv, lastorigimp, 0, 0, pW, pH, scale, locRETgainCurve, locRETtransCurve, + lllocalcurve, locallutili, + cllocalcurve, localclutili, + lclocalcurve, locallcutili, + loclhCurve, lochhCurve, + lmasklocalcurve, localmaskutili, + lmaskexplocalcurve, localmaskexputili, + lmaskSHlocalcurve, localmaskSHutili, + lmaskviblocalcurve, localmaskvibutili, + lmasktmlocalcurve, localmasktmutili, + lmaskretilocalcurve, localmaskretiutili, + lmaskcblocalcurve, localmaskcbutili, + lmaskbllocalcurve, localmaskblutili, + locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, lochhhmasCurve, lhhmasutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, + locccmasSHCurve, lcmasSHutili, locllmasSHCurve, llmasSHutili, lochhmasSHCurve, lhmasSHutili, + locccmasvibCurve, lcmasvibutili, locllmasvibCurve, llmasvibutili, lochhmasvibCurve, lhmasvibutili, + locccmascbCurve, lcmascbutili, locllmascbCurve, llmascbutili, lochhmascbCurve, lhmascbutili, + locccmasretiCurve, lcmasretiutili, locllmasretiCurve, llmasretiutili, lochhmasretiCurve, lhmasretiutili, + locccmastmCurve, lcmastmutili, locllmastmCurve, llmastmutili, lochhmastmCurve, lhmastmutili, + locccmasblCurve, lcmasblutili, locllmasblCurve, llmasblutili, lochhmasblCurve, lhmasblutili, + loclmasCurveblwav, lmasutiliblwav, + loclmasCurvecolwav, lmasutilicolwav, + locwavCurve, locwavutili, + LHutili, HHutili, cclocalcurve, localcutili, rgblocalcurve, localrgbutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, + huerblu, chromarblu, lumarblu, huer, chromar, lumar, sobeler, lastsav, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); } - } else { - ipf.Lab_Local(3, sp, (float**)shbuffer, nprevl, nprevl, reserv, lastorigimp, 0, 0, pW, pH, scale, locRETgainCurve, locRETtransCurve, - lllocalcurve, locallutili, - cllocalcurve, localclutili, - lclocalcurve, locallcutili, - loclhCurve, lochhCurve, - lmasklocalcurve, localmaskutili, - lmaskexplocalcurve, localmaskexputili, - lmaskSHlocalcurve, localmaskSHutili, - lmaskviblocalcurve, localmaskvibutili, - lmasktmlocalcurve, localmasktmutili, - lmaskretilocalcurve, localmaskretiutili, - lmaskcblocalcurve, localmaskcbutili, - lmaskbllocalcurve, localmaskblutili, - locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, lochhhmasCurve, lhhmasutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, - locccmasSHCurve, lcmasSHutili, locllmasSHCurve, llmasSHutili, lochhmasSHCurve, lhmasSHutili, - locccmasvibCurve, lcmasvibutili, locllmasvibCurve, llmasvibutili, lochhmasvibCurve, lhmasvibutili, - locccmascbCurve, lcmascbutili, locllmascbCurve, llmascbutili, lochhmascbCurve, lhmascbutili, - locccmasretiCurve, lcmasretiutili, locllmasretiCurve, llmasretiutili, lochhmasretiCurve, lhmasretiutili, - locccmastmCurve, lcmastmutili, locllmastmCurve, llmastmutili, lochhmastmCurve, lhmastmutili, - locccmasblCurve, lcmasblutili, locllmasblCurve, llmasblutili, lochhmasblCurve, lhmasblutili, - loclmasCurveblwav,lmasutiliblwav, - loclmasCurvecolwav,lmasutilicolwav, - locwavCurve, locwavutili, - LHutili, HHutili, cclocalcurve, localcutili, rgblocalcurve, localrgbutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, - huerblu, chromarblu, lumarblu, huer, chromar, lumar, sobeler, lastsav, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); - } - lastorigimp->CopyFrom(nprevl); + lastorigimp->CopyFrom(nprevl); - //recalculate references after - if (params->locallab.spots.at(sp).spotMethod == "exc") { - ipf.calc_ref(sp, reserv, reserv, 0, 0, pW, pH, scale, huerefblu, chromarefblu, lumarefblu, huer, chromar, lumar, sobeler, avg); - } else { - ipf.calc_ref(sp, nprevl, nprevl, 0, 0, pW, pH, scale, huerefblu, chromarefblu, lumarefblu, huer, chromar, lumar, sobeler, avg); - } - - if (sp == params->locallab.selspot && params->locallab.spots.at(sp).recurs) { - if (locallListener) {//change GUI ref for masks - locallListener->refChanged(huer, lumar, chromar); + //recalculate references after + if (params->locallab.spots.at(sp).spotMethod == "exc") { + ipf.calc_ref(sp, reserv, reserv, 0, 0, pW, pH, scale, huerefblu, chromarefblu, lumarefblu, huer, chromar, lumar, sobeler, avg); + } else { + ipf.calc_ref(sp, nprevl, nprevl, 0, 0, pW, pH, scale, huerefblu, chromarefblu, lumarefblu, huer, chromar, lumar, sobeler, avg); } + + if (sp == params->locallab.selspot && params->locallab.spots.at(sp).recurs) { + if (locallListener) {//change GUI ref for masks + locallListener->refChanged(huer, lumar, chromar); + } + } + + /* + //very bad idea : it's the story of the cat biting its tail + // brings big bugs.. + //restore ref values + huerefs[sp] = huer; + chromarefs[sp] = chromar; + lumarefs[sp] = lumar ; + sobelrefs[sp] = sobeler; + */ + lllocalcurve.clear(); + lclocalcurve.clear(); + cllocalcurve.clear(); + lightCurveloc.clear(); + cclocalcurve.clear(); + rgblocalcurve.clear(); + exlocalcurve.clear(); + lmasklocalcurve.clear(); + lmaskexplocalcurve.clear(); + lmaskSHlocalcurve.clear(); + lmaskviblocalcurve.clear(); + lmasktmlocalcurve.clear(); + lmaskretilocalcurve.clear(); + lmaskcblocalcurve.clear(); + lmaskbllocalcurve.clear(); + hltonecurveloc.clear(); + shtonecurveloc.clear(); + tonecurveloc.clear(); + locRETgainCurve.Reset(); + locRETtransCurve.Reset(); + loclhCurve.Reset(); + lochhCurve.Reset(); + locccmasCurve.Reset(); + locllmasCurve.Reset(); + lochhmasCurve.Reset(); + lochhhmasCurve.Reset(); + locllmasexpCurve.Reset(); + locccmasexpCurve.Reset(); + lochhmasexpCurve.Reset(); + locllmasSHCurve.Reset(); + locccmasSHCurve.Reset(); + lochhmasSHCurve.Reset(); + locllmasvibCurve.Reset(); + locccmasvibCurve.Reset(); + lochhmasvibCurve.Reset(); + locllmascbCurve.Reset(); + locccmascbCurve.Reset(); + lochhmascbCurve.Reset(); + locllmasretiCurve.Reset(); + locccmasretiCurve.Reset(); + lochhmasretiCurve.Reset(); + locllmastmCurve.Reset(); + locccmastmCurve.Reset(); + lochhmastmCurve.Reset(); + locllmasblCurve.Reset(); + locccmasblCurve.Reset(); + lochhmasblCurve.Reset(); + locwavCurve.Reset(); + loclmasCurveblwav.Reset(); + loclmasCurvecolwav.Reset(); } -/* -//very bad idea : it's the story of the cat biting its tail -// brings big bugs.. - //restore ref values - huerefs[sp] = huer; - chromarefs[sp] = chromar; - lumarefs[sp] = lumar ; - sobelrefs[sp] = sobeler; -*/ - lllocalcurve.clear(); - lclocalcurve.clear(); - cllocalcurve.clear(); - lightCurveloc.clear(); - cclocalcurve.clear(); - rgblocalcurve.clear(); - exlocalcurve.clear(); - lmasklocalcurve.clear(); - lmaskexplocalcurve.clear(); - lmaskSHlocalcurve.clear(); - lmaskviblocalcurve.clear(); - lmasktmlocalcurve.clear(); - lmaskretilocalcurve.clear(); - lmaskcblocalcurve.clear(); - lmaskbllocalcurve.clear(); - hltonecurveloc.clear(); - shtonecurveloc.clear(); - tonecurveloc.clear(); - locRETgainCurve.Reset(); - locRETtransCurve.Reset(); - loclhCurve.Reset(); - lochhCurve.Reset(); - locccmasCurve.Reset(); - locllmasCurve.Reset(); - lochhmasCurve.Reset(); - lochhhmasCurve.Reset(); - locllmasexpCurve.Reset(); - locccmasexpCurve.Reset(); - lochhmasexpCurve.Reset(); - locllmasSHCurve.Reset(); - locccmasSHCurve.Reset(); - lochhmasSHCurve.Reset(); - locllmasvibCurve.Reset(); - locccmasvibCurve.Reset(); - lochhmasvibCurve.Reset(); - locllmascbCurve.Reset(); - locccmascbCurve.Reset(); - lochhmascbCurve.Reset(); - locllmasretiCurve.Reset(); - locccmasretiCurve.Reset(); - lochhmasretiCurve.Reset(); - locllmastmCurve.Reset(); - locccmastmCurve.Reset(); - lochhmastmCurve.Reset(); - locllmasblCurve.Reset(); - locccmasblCurve.Reset(); - lochhmasblCurve.Reset(); - locwavCurve.Reset(); - loclmasCurveblwav.Reset(); - loclmasCurvecolwav.Reset(); } - } - - //************************************************************* - // end locallab - //************************************************************* + + //************************************************************* + // end locallab + //************************************************************* histCCurve.clear(); histLCurve.clear(); @@ -1326,7 +1404,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) CAMBrightCurveJ.dirty = true; CAMBrightCurveQ.dirty = true; - ipf.ciecam_02float(ncie, float (adap), pW, 2, nprevl, params.get(), customColCurve1, customColCurve2, customColCurve3, histLCAM, histCCAM, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 0 , scale, execsharp, d, dj, yb, 1); + ipf.ciecam_02float(ncie, float (adap), pW, 2, nprevl, params.get(), customColCurve1, customColCurve2, customColCurve3, histLCAM, histCCAM, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 0, scale, execsharp, d, dj, yb, 1); if ((params->colorappearance.autodegree || params->colorappearance.autodegreeout) && acListener && params->colorappearance.enabled) { acListener->autoCamChanged(100.* (double)d, 100.* (double)dj); @@ -1371,6 +1449,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if (crops[i]->hasListener() && (panningRelatedChange || (highDetailNeeded && options.prevdemo != PD_Sidecar) || (todo & (M_MONITOR | M_RGBCURVE | M_LUMACURVE)) || crops[i]->get_skip() == 1)) { crops[i]->update(todo); // may call ourselves } + if (panningRelatedChange || (todo & M_MONITOR)) { if ((todo != CROP && todo != MINUPDATE) || (todo & M_MONITOR)) { MyMutex::MyLock prevImgLock(previmg->getMutex()); @@ -1406,6 +1485,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) hListener->histogramChanged(histRed, histGreen, histBlue, histLuma, histToneCurve, histLCurve, histCCurve, /*histCLurve, histLLCurve,*/ histLCAM, histCCAM, histRedRaw, histGreenRaw, histBlueRaw, histChroma, histLRETI); } } + if (orig_prev != oprevi) { delete oprevi; oprevi = nullptr; @@ -1650,17 +1730,16 @@ bool ImProcCoordinator::getFilmNegativeExponents(int xA, int yA, int xB, int yB, MyMutex::MyLock lock(mProcessing); const auto xlate = - [this](int x, int y) -> Coord2D - { - const std::vector points = {Coord2D(x, y)}; + [this](int x, int y) -> Coord2D { + const std::vector points = {Coord2D(x, y)}; - std::vector red; - std::vector green; - std::vector blue; - ipf.transCoord(fw, fh, points, red, green, blue); + std::vector red; + std::vector green; + std::vector blue; + ipf.transCoord(fw, fh, points, red, green, blue); - return green[0]; - }; + return green[0]; + }; const int tr = getCoarseBitMask(params->coarse); @@ -1727,7 +1806,7 @@ void ImProcCoordinator::getSoftProofing(bool &softProof, bool &gamutCheck) gamutCheck = this->gamutCheck; } -ProcEvent ImProcCoordinator::setSharpMask (bool sharpMask) +ProcEvent ImProcCoordinator::setSharpMask(bool sharpMask) { if (this->sharpMask != sharpMask) { sharpMaskChanged = true; @@ -1904,7 +1983,7 @@ void ImProcCoordinator::process() while (changeSinceLast) { const bool panningRelatedChange = - params->toneCurve.isPanningRelatedChange(nextParams->toneCurve) + params->toneCurve.isPanningRelatedChange(nextParams->toneCurve) || params->labCurve != nextParams->labCurve || params->locallab != nextParams->locallab || params->localContrast != nextParams->localContrast diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 69a4bb1b3..fbf8d96cb 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -25,7 +25,7 @@ #include "jaggedarray.h" #include "pipettebuffer.h" #include "array2D.h" - +#include "imagesource.h" #include template @@ -257,6 +257,8 @@ public: float maxdE, float mindE, float maxdElim, float mindElim, float iterat, float limscope, int scope, float balance, float lumask); void filmGrain(Imagefloat *rgb, int isogr, int strengr, int scalegr, int bfw, int bfh); + void log_encode(Imagefloat *rgb, struct local_params & lp, float scale, bool multiThread); + void getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, float *blackev, float *whiteev, bool *Autogr, int fw, int fh, int SCALE); void MSRLocal(int call, int sp, bool fftw, int lum, float** reducDE, LabImage * bufreti, LabImage * bufmask, LabImage * buforig, LabImage * buforigmas, float** luminance, float** templ, const float* const *originalLuminance, const int width, const int height, int bfwr, int bfhr, const procparams::LocallabParams &loc, const int skip, const LocretigainCurve &locRETgainCcurve, const LocretitransCurve &locRETtransCcurve, diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 1ca725b2e..394670acc 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -40,6 +40,7 @@ #include #endif #include "../rtgui/thresholdselector.h" +#include "imagesource.h" #include "cplx_wavelet_dec.h" #include "ciecam02.h" @@ -54,7 +55,7 @@ #define blkrad 1 // radius of block averaging #define offset2 25 // shift between tiles -#define epsilon 0.001f/(TS*TS) //tolerance +#define epsilonw 0.001f/(TS*TS) //tolerance #define MAXSCOPE 1.25f #define MINSCOPE 0.025f #define mSP 5 //minimum size Spot @@ -355,6 +356,7 @@ struct local_params { bool exposena; bool hsena; bool vibena; + bool logena; bool cut_past; float past; float satur; @@ -396,6 +398,16 @@ struct local_params { float gammareti; float slomareti; int scalereti; + float sourcegray; + float targetgray; + float blackev; + float whiteev; + int detail; + int sensilog; + bool Autogray; + bool autocompute; + + }; static void SobelCannyLuma(float **sobelL, float **luma, int bfw, int bfh, float radius, bool multiThread = false) @@ -847,6 +859,17 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall float gammaskbl = ((float) locallab.spots.at(sp).gammaskbl); float slomaskbl = ((float) locallab.spots.at(sp).slomaskbl); bool fftbl = locallab.spots.at(sp).fftwbl; + + + lp.sourcegray = (float) locallab.spots.at(sp).sourceGray; + lp.targetgray = (float) locallab.spots.at(sp).targetGray; + lp.blackev = (float) locallab.spots.at(sp).blackEv; + lp.whiteev = (float) locallab.spots.at(sp).whiteEv; + lp.detail = locallab.spots.at(sp).detail; + lp.sensilog = locallab.spots.at(sp).sensilog; + lp.Autogray = locallab.spots.at(sp).Autogray; + lp.autocompute = locallab.spots.at(sp).autocompute; + lp.deltaem = locallab.spots.at(sp).deltae; lp.scalereti = scaleret; lp.cir = circr; @@ -1017,6 +1040,8 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.mullocsh[y] = multish[y]; } + lp.logena = locallab.spots.at(sp).explog; + lp.detailsh = locallab.spots.at(sp).detailSH; lp.threshol = thresho; lp.chromacb = chromcbdl; @@ -1159,6 +1184,292 @@ static void calcTransition(const float lox, const float loy, const float ach, co } } + +// Copyright 2018 Alberto Griggio +//J.Desmis 12 2019 - I will try to port a raw process in local adjustements +// I choose this one because, it is "new" +// Perhaps - probably no result, but perhaps ?? + +float find_gray(float source_gray, float target_gray) +{ + // find a base such that log2lin(base, source_gray) = target_gray + // log2lin is (base^source_gray - 1) / (base - 1), so we solve + // + // (base^source_gray - 1) / (base - 1) = target_gray, that is + // + // base^source_gray - 1 - base * target_gray + target_gray = 0 + // + // use a bisection method (maybe later change to Netwon) + + if (source_gray <= 0.f) { + return 0.f; + } + + const auto f = + [ = ](float x) -> float { + return std::pow(x, source_gray) - 1 - target_gray * x + target_gray; + }; + + // first find the interval we are interested in + + float lo = 1.f; + + while (f(lo) <= 0.f) { + lo *= 2.f; + } + + float hi = lo * 2.f; + + while (f(hi) >= 0.f) { + hi *= 2.f; + } + + if (std::isinf(hi)) { + return 0.f; + } + + // now search for a zero + for (int iter = 0; iter < 100; ++iter) { + float mid = lo + (hi - lo) / 2.f; + float v = f(mid); + + if (std::abs(v) < 1e-4f || (hi - lo) / lo <= 1e-4f) { + return mid; + } + + if (v > 0.f) { + lo = mid; + } else { + hi = mid; + } + } + + return 0.f; // not found +} + + +// basic log encoding taken from ACESutil.Lin_to_Log2, from +// https://github.com/ampas/aces-dev +// (as seen on pixls.us) +void ImProcFunctions::log_encode(Imagefloat *rgb, struct local_params & lp, float scale, bool multiThread) +{ + //small adaptations to local adjustemnts J.Desmis 12 2019 + const float gray = lp.sourcegray / 100.f; + const float shadows_range = lp.blackev; + const float dynamic_range = lp.whiteev - lp.blackev; + const float noise = pow_F(2.f, -16.f); + const float log2 = xlogf(2.f); + const float b = lp.targetgray > 1 && lp.targetgray < 100 && dynamic_range > 0 ? find_gray(std::abs(lp.blackev) / dynamic_range, lp.targetgray / 100.f) : 0.f; + const float linbase = max(b, 0.f); + TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); + + const auto apply = + [ = ](float x, bool scale = true) -> float { + if (scale) + { + x /= 65535.f; + } + + x = max(x, noise); + x = max(x / gray, noise); + x = max((xlogf(x) / log2 - shadows_range) / dynamic_range, noise); + assert(x == x); + + if (linbase > 0.f) + { + x = xlog2lin(x, linbase); + } + + if (scale) + { + return x * 65535.f; + } else + { + return x; + } + }; + + const auto norm = + [&](float r, float g, float b) -> float { + return Color::rgbLuminance(r, g, b, ws); + + // other possible alternatives (so far, luminance seems to work + // fine though). See also + // https://discuss.pixls.us/t/finding-a-norm-to-preserve-ratios-across-non-linear-operations + // + // MAX + //return max(r, g, b); + // + // Euclidean + //return std::sqrt(SQR(r) + SQR(g) + SQR(b)); + + // weighted yellow power norm from https://youtu.be/Z0DS7cnAYPk + // float rr = 1.22f * r / 65535.f; + // float gg = 1.20f * g / 65535.f; + // float bb = 0.58f * b / 65535.f; + // float rr4 = SQR(rr) * SQR(rr); + // float gg4 = SQR(gg) * SQR(gg); + // float bb4 = SQR(bb) * SQR(bb); + // float den = (rr4 + gg4 + bb4); + // if (den > 0.f) { + // return 0.8374319f * ((rr4 * rr + gg4 * gg + bb4 * bb) / den) * 65535.f; + // } else { + // return 0.f; + // } + }; + + const int detail = float(max(lp.detail, 0)) / scale + 0.5f; + + if (detail == 0) { +#ifdef _OPENMP + # pragma omp parallel for if (multiThread) +#endif + + for (int y = 0; y < rgb->getHeight(); ++y) { + for (int x = 0; x < rgb->getWidth(); ++x) { + float r = rgb->r(y, x); + float g = rgb->g(y, x); + float b = rgb->b(y, x); + float m = norm(r, g, b); + + if (m > noise) { + float mm = apply(m); + float f = mm / m; + r *= f; + b *= f; + g *= f; + } + + assert(r == r); + assert(g == g); + assert(b == b); + + rgb->r(y, x) = r; + rgb->g(y, x) = g; + rgb->b(y, x) = b; + } + } + } else { + const int W = rgb->getWidth(), H = rgb->getHeight(); + array2D tmp(W, H); +#ifdef _OPENMP + # pragma omp parallel for if (multiThread) +#endif + + for (int y = 0; y < H; ++y) { + for (int x = 0; x < W; ++x) { + tmp[y][x] = norm(rgb->r(y, x), rgb->g(y, x), rgb->b(y, x)) / 65535.f; + } + } + + const float epsilon = 0.01f + 0.002f * max(detail - 3, 0); + guidedFilterLog(10.f, tmp, detail, epsilon, multiThread); + +#ifdef _OPENMP + # pragma omp parallel for if (multiThread) +#endif + + for (int y = 0; y < H; ++y) { + for (int x = 0; x < W; ++x) { + float &r = rgb->r(y, x); + float &g = rgb->g(y, x); + float &b = rgb->b(y, x); + float m = norm(r, g, b); + float t = intp(0.33f, m, tmp[y][x] * 65535.f); + + if (t > noise) { + float c = apply(t); + float f = c / t; + r *= f; + g *= f; + b *= f; + } + } + } + } +} + + + +void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, float *blackev, float *whiteev, bool *Autogr, int fw, int fh, int SCALE) +{ + + PreviewProps pp(0, 0, fw, fh, SCALE); + + Imagefloat img(int(fw / SCALE + 0.5), int(fh / SCALE + 0.5)); + ProcParams neutral; +// neutral.exposure.enabled = true; + imgsrc->getImage(imgsrc->getWB(), TR_NONE, &img, pp, params->toneCurve, neutral.raw); + imgsrc->convertColorSpace(&img, params->icm, imgsrc->getWB()); + + float vmin = RT_INFINITY; + float vmax = -RT_INFINITY; + bool always = true; + const float ec = always ? std::pow(2.f, params->toneCurve.expcomp) : 1.f; + + constexpr float noise = 1e-5; + + for (int y = 0, h = fh / SCALE; y < h; ++y) { + for (int x = 0, w = fw / SCALE; x < w; ++x) { + float r = img.r(y, x), g = img.g(y, x), b = img.b(y, x); + float m = max(0.f, r, g, b) / 65535.f * ec; + + if (m > noise) { + float l = min(r, g, b) / 65535.f * ec; + vmin = min(vmin, l > noise ? l : m); + vmax = max(vmax, m); + } + } + } + + if (vmax > vmin) { + const float log2 = xlogf(2.f); + float dynamic_range = -xlogf(vmin / vmax) / log2; + + if (settings->verbose) { + std::cout << "AutoLog: min = " << vmin << ", max = " << vmax + << ", DR = " << dynamic_range << std::endl; + } + + if (Autogr[sp]) { + double tot = 0.f; + int n = 0; + float gmax = std::min(vmax / 2.f, 0.25f); + float gmin = std::max(vmin * std::pow(2.f, std::max((dynamic_range - 1.f) / 2.f, 1.f)), 0.05f); + + if (settings->verbose) { + std::cout << " gray boundaries: " << gmin << ", " << gmax << std::endl; + } + + for (int y = 0, h = fh / SCALE; y < h; ++y) { + for (int x = 0, w = fw / SCALE; x < w; ++x) { + float l = img.g(y, x) / 65535.f; + + if (l >= gmin && l <= gmax) { + tot += l; + ++n; + } + } + } + + if (n > 0) { + sourceg[sp] = tot / n * 100.f; + + if (settings->verbose) { + std::cout << " computed gray point from " << n << " samples: " << sourceg[sp] << std::endl; + } + } else if (settings->verbose) { + std::cout << " no samples found in range, resorting to default gray point value" << std::endl; + // lp.sourcegray = LogEncodingParams().sourceGray; + } + } + + float gray = float(sourceg[sp]) / 100.f; + whiteev[sp] = xlogf(vmax / gray) / log2; + blackev[sp] = whiteev[sp] - dynamic_range; + } +} + void tone_eq(array2D &R, array2D &G, array2D &B, const struct local_params & lp, const Glib::ustring &workingProfile, double scale, bool multithread) // adapted from the tone equalizer of darktable /* @@ -5645,6 +5956,8 @@ void ImProcFunctions::transit_shapedetect2(int call, int senstype, const LabImag varsens = lp.senstm; } else if (senstype == 10) { //local contrast varsens = lp.senslc; + } else if (senstype == 11) { //encoding log + varsens = lp.sensilog; } bool delt = lp.deltaem; @@ -6561,8 +6874,8 @@ void ImProcFunctions::fftw_denoise(int GW, int GH, int max_numblox_W, int min_nu for (int j = 0; j < TS; ++j) { float j1 = abs((j > TS / 2 ? j - TS + 1 : j)); - tilemask_in[i][j] = (vmask * (j1 < border ? SQR(sin((rtengine::RT_PI_F * j1) / (2 * border))) : 1.0f)) + epsilon; - tilemask_out[i][j] = (vmask2 * (j1 < 2 * border ? SQR(sin((rtengine::RT_PI_F * j1) / (2 * border))) : 1.0f)) + epsilon; + tilemask_in[i][j] = (vmask * (j1 < border ? SQR(sin((rtengine::RT_PI_F * j1) / (2 * border))) : 1.0f)) + epsilonw; + tilemask_out[i][j] = (vmask2 * (j1 < 2 * border ? SQR(sin((rtengine::RT_PI_F * j1) / (2 * border))) : 1.0f)) + epsilonw; } } @@ -8101,6 +8414,54 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o } +//encoding lab at the beginning + if (lp.logena) { + printf("OK log\n"); + int ystart = std::max(static_cast(lp.yc - lp.lyT) - cy, 0); + int yend = std::min(static_cast(lp.yc + lp.ly) - cy, original->H); + int xstart = std::max(static_cast(lp.xc - lp.lxL) - cx, 0); + int xend = std::min(static_cast(lp.xc + lp.lx) - cx, original->W); + int bfh = yend - ystart; + int bfw = xend - xstart; + + if (bfh >= mSP && bfw >= mSP) { + std::unique_ptr bufexporig(new LabImage(bfw, bfh)); //buffer for data in zone limit + std::unique_ptr bufexpfin(new LabImage(bfw, bfh)); //buffer for data in zone limit + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int y = ystart; y < yend; y++) { + for (int x = xstart; x < xend; x++) { + bufexporig->L[y - ystart][x - xstart] = original->L[y][x]; + bufexporig->a[y - ystart][x - xstart] = original->a[y][x]; + bufexporig->b[y - ystart][x - xstart] = original->b[y][x]; + } + } + + bufexpfin->CopyFrom(bufexporig.get()); + Imagefloat *tmpImage = nullptr; + tmpImage = new Imagefloat(bfw, bfh); + lab2rgb(*bufexpfin, *tmpImage, params->icm.workingProfile); + log_encode(tmpImage, lp, float (sk), multiThread); + + rgb2lab(*tmpImage, *bufexpfin, params->icm.workingProfile); + + delete tmpImage; + + transit_shapedetect2(call, 11, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); + + if (params->locallab.spots.at(sp).recurs) { + original->CopyFrom(transformed); + float avge; + calc_ref(sp, original, transformed, 0, 0, original->W, original->H, sk, huerefblur, chromarefblur, lumarefblur, hueref, chromaref, lumaref, sobelref, avge); + } + } + } + + + //Prepare mask for Blur and noise and Denoise bool denoiz = false; @@ -10631,7 +10992,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o tmpl = new LabImage(Wd, Hd); } else { - // + // } // float minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax; diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 2c479774a..dd469cddb 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -872,18 +872,17 @@ enum ProcEventCode { EvLocallabAuto = 845, EvlocallabsourceGray = 846, EvlocallabsourceGrayAuto = 847, - EvlocallabAutoGrayOn = 848, - EvlocallabAutoGrayOff = 849, - EvlocallabAutogray = 850, - EvlocallabblackEv = 851, - EvlocallabwhiteEv = 852, - EvlocallabtargetGray = 853, - Evlocallabdetail = 854, - Evlocallabsensilog = 855, +// EvlocallabAutoGrayOn = 848, +// EvlocallabAutoGrayOff = 849, + EvlocallabAutogray = 848, + EvlocallabblackEv = 849, + EvlocallabwhiteEv = 850, + EvlocallabtargetGray = 851, + Evlocallabdetail = 852, + Evlocallabsensilog = 853, NUMOFEVENTS }; - class ProcEvent { public: diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 607404055..a3fcd6d88 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2777,7 +2777,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : blackEv(-5.0), whiteEv(10.0), detail(1), - sensilog(30) + sensilog(50) { } diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 7ed407dc1..2323f7061 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -872,13 +872,13 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, // Evlocallabblurcol LUMINANCECURVE, // Evlocallabcontcol LUMINANCECURVE, // EvLocallabfftColorMask - LUMINANCECURVE, // EvLocenalog - LUMINANCECURVE, //EvLocallabAuto - LUMINANCECURVE, //EvlocallabsourceGray - LUMINANCECURVE, //EvlocallabsourceGrayAuto - LUMINANCECURVE, //EvlocallabAutoGrayOn - LUMINANCECURVE, //EvlocallabAutoGrayOff - LUMINANCECURVE, //EvlocallabAutoGray + RGBCURVE | M_AUTOEXP, // EvLocenalog + AUTOEXP, //EvLocallabAuto + LUMINANCECURVE, //EvlocallabsourceGray + AUTOEXP, //EvlocallabsourceGrayAuto +// AUTOEXP, //EvlocallabAutoGrayOn +// M_VOID, //EvlocallabAutoGrayOff + AUTOEXP, //EvlocallabAutoGray LUMINANCECURVE, //EvlocallabblackEv LUMINANCECURVE, //EvlocallabwhiteEv LUMINANCECURVE, //EvlocallabtargetGray diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index ebfa47088..eabfea2e3 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -381,6 +381,7 @@ public: virtual ~LocallabListener() = default; virtual void refChanged (double huer, double lumar, double chromar) = 0; virtual void minmaxChanged(double cdma, double cdmin, double mini, double maxi, double Tmean, double Tsigma, double Tmin, double Tmax) = 0; + virtual void logencodChanged (float blackev, float whiteev, float sourceg, float targetg) = 0; }; class AutoColorTonListener diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 719bc1b95..06e2c8efa 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -510,7 +510,7 @@ targetGray(Gtk::manage(new Adjuster(M("TP_LOCALLAB_TARGET_GRAY"), 5.0, 80.0, 0.1 blackEv(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BLACK_EV"), -16.0, 0.0, 0.1, -5.0))), whiteEv(Gtk::manage(new Adjuster(M("TP_LOCALLAB_WHITE_EV"), 0.0, 32.0, 0.1, 10.0))), detail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DETAIL"), 0, 5, 1, 1))), -sensilog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSILOG"), 0, 100, 1, 30))), +sensilog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSILOG"), 0, 100, 1, 50))), // ButtonCheck widgets // Color & Light @@ -3436,12 +3436,12 @@ void Locallab::enableToggled(MyExpander *expander) } else if (expander == expcbdl) { event = EvLocenacbdl; expConn = &enablecbdlConn; - } else if (expander == expdenoi) { - event = EvLocenadenoi; - expConn = &enabledenoiConn; } else if (expander == explog) { event = EvLocenalog; expConn = &enablelogConn; + } else if (expander == expdenoi) { + event = EvLocenadenoi; + expConn = &enabledenoiConn; } else { return; } @@ -3494,6 +3494,24 @@ void Locallab::writeOptions(std::vector &tpOpen) } +void Locallab::logencodChanged(float blackev, float whiteev, float sourceg, float targetg) +{ + GThreadLock lock; + + disableListener(); +// blackEv->setEnabled(true); +// whiteEv->setEnabled(true); + + sourceGray->setValue(sourceg); + targetGray->setValue(targetg); + blackEv->setValue(blackev); + whiteEv->setValue(whiteev); + + enableListener(); + +} + + void Locallab::minmaxChanged(double cdma, double cdmin, double mini, double maxi, double Tmean, double Tsigma, double Tmin, double Tmax) { nextmin = cdmin; @@ -4925,7 +4943,7 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited //log encoding pp->locallab.spots.at(pp->locallab.selspot).explog = explog->getEnabled(); pp->locallab.spots.at(pp->locallab.selspot).autocompute = autocompute->get_active(); - // pp->locallab.spots.at(pp->locallab.selspot).autogray = sourceGray->getAutoValue(); + // pp->locallab.spots.at(pp->locallab.selspot).autogray = sourceGray->getAutoValue(); pp->locallab.spots.at(pp->locallab.selspot).sourceGray = sourceGray->getValue(); pp->locallab.spots.at(pp->locallab.selspot).Autogray = Autogray->get_active(); pp->locallab.spots.at(pp->locallab.selspot).blackEv = blackEv->getValue(); @@ -7007,7 +7025,6 @@ void Locallab::enavibMaskChanged() void Locallab::enablMaskChanged() { - // printf("enablmaskChanged\n"); if (multiImage) { if (enablMask->get_inconsistent()) { @@ -7032,21 +7049,21 @@ void Locallab::enablMaskChanged() void Locallab::autocomputeToggled() { - /* - if (multiImage) { - if (autocompute->get_inconsistent()) { - autocompute->set_inconsistent(false); - autoconn.block(true); - autocompute->set_active(false); - autoconn.block(false); - } - } -*/ + /* + if (multiImage) { + if (autocompute->get_inconsistent()) { + autocompute->set_inconsistent(false); + autoconn.block(true); + autocompute->set_active(false); + autoconn.block(false); + } + } + */ if (listener) { if (autocompute->get_active()) { listener->panelChanged(EvLocallabAuto, M("GENERAL_ENABLED")); - blackEv->setEnabled(false); - whiteEv->setEnabled(false); + //blackEv->setEnabled(false); + //whiteEv->setEnabled(false); //targetGray->setEnabled(false); } else { listener->panelChanged(EvLocallabAuto, M("GENERAL_DISABLED")); @@ -8085,7 +8102,7 @@ void Locallab::setDefaults(const rtengine::procparams::ProcParams * defParams, c bilateral->setDefault((double)defSpot->bilateral); sensiden->setDefault((double)defSpot->sensiden); detailthr->setDefault((double)defSpot->detailthr); - + //log encoding sourceGray->setDefault((double)defSpot->sourceGray); blackEv->setDefault((double)defSpot->blackEv); @@ -9871,14 +9888,14 @@ void Locallab::adjusterChanged(Adjuster * a, double newval) if (getEnabled() && explog->getEnabled()) { if (a != sourceGray && a != targetGray && a != detail) { - // autocompute->set_active(false); + // autocompute->set_active(false); } - - + + if (a == sourceGray) { if (listener) { - // printf("OK 1\n"); - // if(autocompute->get_active()) printf("AUTO\n"); else printf("PAS\n"); + // printf("OK 1\n"); + // if(autocompute->get_active()) printf("AUTO\n"); else printf("PAS\n"); listener->panelChanged(EvlocallabsourceGray, sourceGray->getTextValue()); //listener->panelChanged(autocompute->get_active() ? EvlocallabsourceGrayAuto : EvlocallabsourceGray, a->getTextValue()); } @@ -9915,7 +9932,7 @@ void Locallab::adjusterChanged(Adjuster * a, double newval) } } - + } @@ -10427,8 +10444,9 @@ void Locallab::enableListener() enabledenoiConn.block(false); //encoding log // autoconn.block(false); + enablelogConn.block(false); AutograyConn.block(false); - + } void Locallab::disableListener() @@ -10518,9 +10536,10 @@ void Locallab::disableListener() // Denoise enabledenoiConn.block(true); //encoding log - // autoconn.block(true); +// autoconn.block(true); + enablelogConn.block(true); AutograyConn.block(true); - + } void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited, int index) @@ -11186,7 +11205,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con lcradius->setValue(pp->locallab.spots.at(index).lcradius); if (complexsoft == 2) { - lcradius->setLimits(20, 100, 1, 80); + lcradius->setLimits(20, 100, 1, 80); lcradius->setValue(pp->locallab.spots.at(index).lcradius); } @@ -11194,7 +11213,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con expcbdl->setEnabled(pp->locallab.spots.at(index).expcbdl); for (int i = 0; i < 6; i++) { - multiplier[i]->setValue(pp->locallab.spots.at(index).mult[i]); + multiplier[i]->setValue(pp->locallab.spots.at(index).mult[i]); } chromacbdl->setValue(pp->locallab.spots.at(index).chromacbdl); @@ -11217,13 +11236,13 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con Lmaskcbshape->setCurve(pp->locallab.spots.at(index).Lmaskcbcurve); if (complexsoft == 2) { - for (int i = 0; i < 6; i++) { + for (int i = 0; i < 6; i++) { multiplier[i]->setValue(1.0); } } if (complexsoft > 0) { - lapmaskcb->setValue(0); + lapmaskcb->setValue(0); } // Denoise @@ -11243,7 +11262,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con detailthr->setValue(pp->locallab.spots.at(index).detailthr); if (complexsoft == 2) { - noiselumf->setValue(0); + noiselumf->setValue(0); noiselumf0->setValue(0); noiselumf2->setValue(0); noiselumc->setValue(0); @@ -11266,7 +11285,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con sensilog->setValue(pp->locallab.spots.at(index).sensilog); if (pedited) { - if (index < (int)pedited->locallab.spots.size()) { + if (index < (int)pedited->locallab.spots.size()) { const LocallabParamsEdited::LocallabSpotEdited* spotState = &pedited->locallab.spots.at(index); // Control spot settings @@ -11697,7 +11716,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con explog->set_inconsistent(!spotState->explog); autocompute->set_inconsistent(multiImage && !spotState->autocompute); sourceGray->setEditedState(spotState->sourceGray ? Edited : UnEdited); - // sourceGray->setAutoInconsistent(multiImage && !spotState->autogray); + // sourceGray->setAutoInconsistent(multiImage && !spotState->autogray); Autogray->set_inconsistent(multiImage && !spotState->Autogray); blackEv->setEditedState(spotState->blackEv ? Edited : UnEdited); whiteEv->setEditedState(spotState->whiteEv ? Edited : UnEdited); @@ -12178,9 +12197,9 @@ void Locallab::adjusterAutoToggled(Adjuster* a, bool newval) lastAutogray = sourceGray->getAutoValue(); // (a == sourceGray ? lastAutogray : lastAutoRadius) = a->getAutoValue(); - + } - + if (listener) { const auto event = (a == sourceGray ? EvlocallabAutoGrayOff: EvlocallabAutoGrayOn); if (sourceGray->getAutoInconsistent()) { @@ -12191,26 +12210,26 @@ void Locallab::adjusterAutoToggled(Adjuster* a, bool newval) listener->panelChanged(event, M("GENERAL_DISABLED")); } } -*/ -/* - if (listener) { - if (a == sourceGray) { - if (sourceGray->getAutoInconsistent()) { - listener->panelChanged (EvlocallabAutoGrayOff, M ("GENERAL_UNCHANGED")); - } else if (sourceGray->getAutoValue()) { - listener->panelChanged (EvlocallabAutoGrayOn, M ("GENERAL_ENABLED")); - } else { - listener->panelChanged (EvlocallabAutoGrayOff, M ("GENERAL_DISABLED")); + */ + /* + if (listener) { + if (a == sourceGray) { + if (sourceGray->getAutoInconsistent()) { + listener->panelChanged (EvlocallabAutoGrayOff, M ("GENERAL_UNCHANGED")); + } else if (sourceGray->getAutoValue()) { + listener->panelChanged (EvlocallabAutoGrayOn, M ("GENERAL_ENABLED")); + } else { + listener->panelChanged (EvlocallabAutoGrayOff, M ("GENERAL_DISABLED")); + } } - } -*/ - /* - if (a == sourceGray) { - printf("OK source\n"); - auto e = (!newval) ? EvlocallabAutoGrayOff : EvlocallabAutoGrayOn; - listener->panelChanged(e, newval ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); - } - */ + */ + /* + if (a == sourceGray) { + printf("OK source\n"); + auto e = (!newval) ? EvlocallabAutoGrayOff : EvlocallabAutoGrayOn; + listener->panelChanged(e, newval ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); + } + */ // } } diff --git a/rtgui/locallab.h b/rtgui/locallab.h index 5706fd2ba..f2e19687f 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -715,6 +715,7 @@ public: void updateToolState(std::vector &tpOpen); void refChanged(double huer, double lumar, double chromar); void minmaxChanged(double cdma, double cdmin, double mini, double maxi, double Tmean, double Tsigma, double Tmin, double Tmax) override; + void logencodChanged (float blackev, float whiteev, float sourceg, float targetg); void updateLabel(); void updateTrans();