From d39eded269b732fc7cb98905f73c7dc51af40130 Mon Sep 17 00:00:00 2001 From: Desmis Date: Fri, 9 Aug 2019 18:32:09 +0200 Subject: [PATCH] enabled simple mask for Color and light inverse --- rtengine/dcrop.cc | 4 +- rtengine/improccoordinator.cc | 5 +- rtengine/improccoordinator.h | 4 +- rtengine/improcfun.h | 4 +- rtengine/iplocallab.cc | 445 ++++++++++++++++++++++------------ rtengine/procevents.h | 1 + rtengine/refreshmap.cc | 3 +- rtengine/rtengine.h | 2 +- rtengine/simpleprocess.cc | 2 +- rtgui/locallab.cc | 71 +++++- rtgui/locallab.h | 4 + rtgui/toolpanelcoord.cc | 6 +- 12 files changed, 375 insertions(+), 176 deletions(-) diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index e1e1d13bc..270a7c42b 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -1016,7 +1016,7 @@ void Crop::update(int todo) locccmasblCurve, lcmasblutili, locllmasblCurve, llmasblutili, lochhmasblCurve, lhmasblutili, locwavCurve, LHutili, HHutili, cclocalcurve2, localcutili, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, lightCurveloc2, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, - parent->locallColorMask, parent->locallExpMask, parent->locallSHMask, parent->locallcbMask, parent->locallretiMask, parent->locallsoftMask, parent->localltmMask, parent->locallblMask); + parent->locallColorMask, parent->locallColorMaskinv, parent->locallExpMask, parent->locallSHMask, parent->locallcbMask, parent->locallretiMask, parent->locallsoftMask, parent->localltmMask, parent->locallblMask); } else { parent->ipf.Lab_Local(1, sp, (float**)shbuffer, labnCrop, labnCrop, reservCrop, cropx / skip, cropy / skip, skips(parent->fw, skip), skips(parent->fh, skip), skip, locRETgainCurve, lllocalcurve2,locallutili, loclhCurve, lochhCurve, locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, @@ -1026,7 +1026,7 @@ void Crop::update(int todo) locccmastmCurve, lcmastmutili, locllmastmCurve, llmastmutili, lochhmastmCurve, lhmastmutili, locccmasblCurve, lcmasblutili, locllmasblCurve, llmasblutili, lochhmasblCurve, lhmasblutili, locwavCurve, - LHutili, HHutili, cclocalcurve2, localcutili, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, lightCurveloc2, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, 0, 0, 0, 0, 0, 0, 0, 0); + LHutili, HHutili, cclocalcurve2, localcutili, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, lightCurveloc2, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, 0, 0, 0, 0, 0, 0, 0, 0, 0); } lllocalcurve2.clear(); lightCurveloc2.clear(); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 91a0e516d..11a448f4b 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -203,6 +203,7 @@ ImProcCoordinator::ImProcCoordinator() : avg(0), lastspotdup(false), locallColorMask(0), + locallColorMaskinv(0), locallExpMask(0), locallSHMask(0), locallcbMask(0), @@ -986,7 +987,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) locccmasblCurve, lcmasblutili, locllmasblCurve, llmasblutili, lochhmasblCurve, lhmasblutili, locwavCurve, LHutili, HHutili, cclocalcurve, localcutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerblu, chromarblu, lumarblu, huer, chromar, lumar, sobeler, - locallColorMask, locallExpMask, locallSHMask, locallcbMask, locallretiMask, locallsoftMask, localltmMask, locallblMask); + locallColorMask, locallColorMaskinv, locallExpMask, locallSHMask, locallcbMask, locallretiMask, locallsoftMask, localltmMask, locallblMask); } else { ipf.Lab_Local(3, sp, (float**)shbuffer, nprevl, nprevl, reserv, 0, 0, pW, pH, scale, locRETgainCurve, lllocalcurve, locallutili, loclhCurve, lochhCurve, locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, locccmasSHCurve, lcmasSHutili, locllmasSHCurve, llmasSHutili, lochhmasSHCurve, lhmasSHutili, @@ -995,7 +996,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) locccmastmCurve, lcmastmutili, locllmastmCurve, llmastmutili, lochhmastmCurve, lhmastmutili, locccmasblCurve, lcmasblutili, locllmasblCurve, llmasblutili, lochhmasblCurve, lhmasblutili, locwavCurve, - LHutili, HHutili, cclocalcurve, localcutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerblu, chromarblu, lumarblu, huer, chromar, lumar, sobeler, 0, 0, 0, 0, 0, 0, 0, 0); + LHutili, HHutili, cclocalcurve, localcutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerblu, chromarblu, lumarblu, huer, chromar, lumar, sobeler, 0, 0, 0, 0, 0, 0, 0, 0, 0); } //recalculate references after if (params->locallab.spots.at(sp).spotMethod == "exc") { diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 4b58cab04..f7db252a9 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -297,6 +297,7 @@ protected: float avg; bool lastspotdup; int locallColorMask; + int locallColorMaskinv; int locallExpMask; int locallSHMask; int locallcbMask; @@ -373,9 +374,10 @@ public: updaterThreadStart.unlock(); } - void setLocallabMaskVisibility (int locallColorMask, int locallExpMask, int locallSHMask, int locallcbMask, int locallretiMask, int locallsoftMask, int localltmMask, int locallblMask) override + void setLocallabMaskVisibility (int locallColorMask, int locallColorMaskinv, int locallExpMask, int locallSHMask, int locallcbMask, int locallretiMask, int locallsoftMask, int localltmMask, int locallblMask) override { this->locallColorMask = locallColorMask; + this->locallColorMaskinv = locallColorMaskinv; this->locallExpMask = locallExpMask; this->locallSHMask = locallSHMask; this->locallcbMask = locallcbMask; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index c1791598b..e85208baf 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -317,7 +317,7 @@ public: const LocCCmasktmCurve & locccmastmCurve, bool &lcmastmutili, const LocLLmasktmCurve & locllmastmCurve, bool &llmastmutili, const LocHHmasktmCurve & lochhmastmCurve, bool & lhmastmutili, const LocCCmaskblCurve & locccmasblCurve, bool &lcmasblutili, const LocLLmaskblCurve & locllmasblCurve, bool &llmasblutili, const LocHHmaskblCurve & lochhmasblCurve, bool & lhmasblutili, const LocwavCurve & locwavCurve, - bool &LHutili, bool &HHutili, LUTf & cclocalcurve, bool & localcutili, bool & localexutili, LUTf & exlocalcurve, LUTf & hltonecurveloc, LUTf & shtonecurveloc, LUTf & tonecurveloc, LUTf & lightCurveloc, double & huerefblur, double &chromarefblur, double & lumarefblur, double &hueref, double &chromaref, double &lumaref, double &sobelref, int llColorMask, + bool &LHutili, bool &HHutili, LUTf & cclocalcurve, bool & localcutili, bool & localexutili, LUTf & exlocalcurve, LUTf & hltonecurveloc, LUTf & shtonecurveloc, LUTf & tonecurveloc, LUTf & lightCurveloc, double & huerefblur, double &chromarefblur, double & lumarefblur, double &hueref, double &chromaref, double &lumaref, double &sobelref, int llColorMask, int llColorMaskinv, int llExpMask, int llSHMask, int llcbMask, int llretiMask, int llsoftMask, int lltmMask, int llblMask); void addGaNoise(LabImage *lab, LabImage *dst, const float mean, const float variance, const int sk); void BlurNoise_Localold(int call, const struct local_params& lp, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy); @@ -338,7 +338,7 @@ public: void fftw_denoise(int GW, int GH, int max_numblox_W, int min_numblox_W, float **tmp1, array2D *Lin, int numThreads, const struct local_params & lp, int chrom); void ColorLight_Local(float moddE, float powdE, int call, LabImage * bufcolorig, LabImage * originalmask, float **buflight, float **bufchro, float **bufchroslid, float ** bufhh, float ** buflightslid, bool &LHutili, bool &HHutili, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, float sobelref, float ** blend2, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, LUTf & lightCurveloc, const local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy, int sk); - void InverseColorLight_Local(int sp, int senstype, const struct local_params& lp, LUTf & lightCurveloc, LUTf & hltonecurveloc, LUTf & shtonecurveloc, LUTf & tonecurveloc, LUTf & exlocalcurve, LUTf & cclocalcurve, float adjustr, bool localcutili, LUTf & lllocalcurve, bool locallutili, LabImage* original, LabImage* transformed, int cx, int cy, const float hueref, const float chromaref, const float lumaref, int sk); + void InverseColorLight_Local(int sp, int senstype, const struct local_params& lp, LabImage * originalmask, LUTf & lightCurveloc, LUTf & hltonecurveloc, LUTf & shtonecurveloc, LUTf & tonecurveloc, LUTf & exlocalcurve, LUTf & cclocalcurve, float adjustr, bool localcutili, LUTf & lllocalcurve, bool locallutili, LabImage* original, LabImage* transformed, int cx, int cy, const float hueref, const float chromaref, const float lumaref, int sk); void Sharp_Local(int call, float **loctemp, int senstype, const float hueref, const float chromaref, const float lumaref, const local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk); // void Sharp_Local(int call, float **loctemp, int senstype, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy, int sk); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 739cfc44e..771d259bd 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -270,6 +270,7 @@ struct local_params { int qualcurvemet; int gridmet; int showmaskcolmet; + int showmaskcolmetinv; int showmaskexpmet; int showmaskSHmet; int showmaskcbmet; @@ -332,6 +333,7 @@ struct local_params { float adjch; int shapmet; bool enaColorMask; + bool enaColorMaskinv; bool enaExpMask; bool enaSHMask; bool enacbMask; @@ -432,7 +434,7 @@ static void SobelCannyLuma(float **sobelL, float **luma, int bfw, int bfh, float -static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locallab, struct local_params& lp, int llColorMask, int llExpMask, int llSHMask, int llcbMask, int llretiMask, int llsoftMask, int lltmMask, int llblMask) +static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locallab, struct local_params& lp, int llColorMask, int llColorMaskinv, int llExpMask, int llSHMask, int llcbMask, int llretiMask, int llsoftMask, int lltmMask, int llblMask) { int w = oW; int h = oH; @@ -510,6 +512,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.linear = locallab.spots.at(sp).linear; lp.showmaskcolmet = llColorMask; + lp.showmaskcolmetinv = llColorMaskinv; lp.showmaskexpmet = llExpMask; lp.showmaskSHmet = llSHMask; lp.showmaskcbmet = llcbMask; @@ -518,6 +521,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.showmasktmmet = lltmMask; lp.showmaskblmet = llblMask; lp.enaColorMask = locallab.spots.at(sp).enaColorMask && llColorMask == 0 && llExpMask == 0 && llSHMask == 0 && llcbMask == 0 && llretiMask == 0 && lltmMask == 0 && llblMask == 0;// Exposure mask is deactivated if Color & Light mask is visible + lp.enaColorMaskinv = locallab.spots.at(sp).enaColorMask && llColorMaskinv == 0 && llExpMask == 0 && llSHMask == 0 && llcbMask == 0 && llretiMask == 0 && lltmMask == 0 && llblMask == 0;// Exposure mask is deactivated if Color & Light mask is visible lp.enaExpMask = locallab.spots.at(sp).enaExpMask && llExpMask == 0 && llColorMask == 0 && llSHMask == 0 && llcbMask == 0 && llretiMask == 0 && lltmMask == 0 && llblMask == 0;// Exposure mask is deactivated if Color & Light mask is visible lp.enaSHMask = locallab.spots.at(sp).enaSHMask && llSHMask == 0 && llColorMask == 0 && llExpMask == 0 && llcbMask == 0 && llretiMask == 0 && lltmMask == 0 && llblMask == 0 ; lp.enacbMask = locallab.spots.at(sp).enacbMask && llcbMask == 0 && llColorMask == 0 && llExpMask == 0 && llSHMask == 0 && llretiMask == 0 && lltmMask == 0 && llblMask == 0; @@ -836,8 +840,8 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.threshol = thresho; lp.chromacb = chromcbdl; lp.colorena = locallab.spots.at(sp).expcolor && llExpMask == 0 && llSHMask == 0 && llcbMask == 0 && llretiMask == 0; // Color & Light tool is deactivated if Exposure mask is visible or SHMask - lp.blurena = locallab.spots.at(sp).expblur; - lp.tonemapena = locallab.spots.at(sp).exptonemap; + lp.blurena = locallab.spots.at(sp).expblur && llExpMask == 0 && llSHMask == 0 && llcbMask == 0 && llretiMask == 0 && llColorMask == 0; + lp.tonemapena = locallab.spots.at(sp).exptonemap && llExpMask == 0 && llSHMask == 0 && llcbMask == 0 && llretiMask == 0 && llColorMask == 0; lp.retiena = locallab.spots.at(sp).expreti && llExpMask == 0 && llSHMask == 0 && llcbMask == 0 && llColorMask == 0; lp.sharpena = locallab.spots.at(sp).expsharp; lp.lcena = locallab.spots.at(sp).expcontrast; @@ -2316,6 +2320,138 @@ static void showmask(const local_params& lp, int xstart, int ystart, int cx, int } } +void maskcalccol(int bfw, int bfh, int xstart, int ystart, int sk, int cx, int cy, LabImage* bufcolorig, LabImage* bufmaskblurcol, LabImage* originalmaskcol, LabImage* original, LabImage * transformed, int inv, const struct local_params & lp, + const LocCCmaskCurve & locccmasCurve, bool & lcmasutili, const LocLLmaskCurve & locllmasCurve, bool & llmasutili, const LocHHmaskCurve & lochhmasCurve, bool &lhmasutili, bool multiThread, + bool enaMask, bool showmaske, bool deltaE, bool modmask, bool zero, bool modif) +{ + array2D ble(bfw, bfh); + array2D guid(bfw, bfh); + float meanfab, fab; + mean_fab(xstart, ystart, bfw, bfh, bufcolorig, original, fab, meanfab, lp.chromacol); + + if (deltaE || modmask || enaMask || showmaske) { + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int y = 0; y < bfh; y++) { + for (int x = 0; x < bfw; x++) { + bufmaskblurcol->L[y][x] = original->L[y + ystart][x + xstart]; + bufmaskblurcol->a[y][x] = original->a[y + ystart][x + xstart]; + bufmaskblurcol->b[y][x] = original->b[y + ystart][x + xstart]; + } + } + +#ifdef _OPENMP + #pragma omp parallel +#endif + { +#ifdef __SSE2__ + float atan2Buffer[bfw] ALIGNED64; +#endif +#ifdef _OPENMP + #pragma omp for schedule(dynamic, 16) +#endif + + for (int ir = 0; ir < bfh; ir++) { +#ifdef __SSE2__ + + if (lochhmasCurve && lhmasutili) { + int i = 0; + + for (; i < bfw - 3; i += 4) { + STVF(atan2Buffer[i], xatan2f(LVFU(bufcolorig->b[ir][i]), LVFU(bufcolorig->a[ir][i]))); + } + + for (; i < bfw; i++) { + atan2Buffer[i] = xatan2f(bufcolorig->b[ir][i], bufcolorig->a[ir][i]); + } + } + +#endif + + for (int jr = 0; jr < bfw; jr++) { + float kmaskL = 0.f; + float kmaskC = 0.f; + float kmaskHL = 0.f; + float kmaskH = 0.f; + + if (locllmasCurve && llmasutili) { + kmaskL = 32768.f * LIM01(1.f - locllmasCurve[(500.f / 32768.f) * bufcolorig->L[ir][jr]]); + } + + if (!deltaE && locccmasCurve && lcmasutili) { + kmaskC = LIM01(1.f - locccmasCurve[500.f * (0.0001f + sqrt(SQR(bufcolorig->a[ir][jr]) + SQR(bufcolorig->b[ir][jr])) / fab)]); + } + + if (lochhmasCurve && lhmasutili) { +#ifdef __SSE2__ + const float huema = atan2Buffer[jr]; +#else + const float huema = xatan2f(bufcolorig->b[ir][jr], bufcolorig->a[ir][jr]); +#endif + float h = Color::huelab_to_huehsv2(huema); + h += 1.f / 6.f; + + if (h > 1.f) { + h -= 1.f; + } + + const float valHH = LIM01(1.f - lochhmasCurve[500.f * h]); + + if (!deltaE) { + kmaskH = valHH; + } + + kmaskHL = 32768.f * valHH; + } + + bufmaskblurcol->L[ir][jr] = CLIPLOC(kmaskL + kmaskHL); + bufmaskblurcol->a[ir][jr] = CLIPC(kmaskC + kmaskH); + bufmaskblurcol->b[ir][jr] = CLIPC(kmaskC + kmaskH); + ble[ir][jr] = bufmaskblurcol->L[ir][jr] / 32768.f; + guid[ir][jr] = bufcolorig->L[ir][jr] / 32768.f; + } + } + } + + if (lp.radmacol > 0.f) { + guidedFilter(guid, ble, ble, lp.radmacol * 10.f / sk, 0.001, multiThread, 4); + } + + LUTf lutTonemaskexp(65536); + calcGammaLut(lp.gammacol, lp.slomacol, lutTonemaskexp); + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int ir = 0; ir < bfh; ir++) { + for (int jr = 0; jr < bfw; jr++) { + bufmaskblurcol->L[ir][jr] = lutTonemaskexp[LIM01(ble[ir][jr]) * 65536.f]; + } + } + } + + const float radiusb = 1.f / sk; + + if (deltaE || modmask || enaMask || showmaske) { +#ifdef _OPENMP + #pragma omp parallel +#endif + { + gaussianBlur(bufmaskblurcol->L, bufmaskblurcol->L, bfw, bfh, radiusb); + gaussianBlur(bufmaskblurcol->a, bufmaskblurcol->a, bfw, bfh, 1.f + (0.5f * lp.radmacol) / sk); + gaussianBlur(bufmaskblurcol->b, bufmaskblurcol->b, bfw, bfh, 1.f + (0.5f * lp.radmacol) / sk); + } + + if (zero || modif || modmask || deltaE || enaMask) { + originalmaskcol->CopyFrom(transformed); + blendmask(lp, xstart, ystart, cx, cy, bfw, bfh, bufcolorig, original, bufmaskblurcol, originalmaskcol, lp.blendmacol, inv); + } + } +} void ImProcFunctions::InverseSharp_Local(float **loctemp, const float hueref, const float lumaref, const float chromaref, const local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk) { @@ -2406,7 +2542,7 @@ void ImProcFunctions::InverseSharp_Local(float **loctemp, const float hueref, co } -void ImProcFunctions::Sharp_Local(int call, float **loctemp, int senstype, const float hueref, const float chromaref, const float lumaref, const local_params &lp, LabImage *original, LabImage *transformed, int cx, int cy, int sk) +void ImProcFunctions::Sharp_Local(int call, float **loctemp, int senstype, const float hueref, const float chromaref, const float lumaref, const local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk) { BENCHFUN const float ach = lp.trans / 100.f; @@ -2819,7 +2955,7 @@ void ImProcFunctions::transit_shapedetect_retinex(int senstype, LabImage * bufex } -void ImProcFunctions::transit_shapedetect(int senstype, const LabImage *bufexporig, LabImage * originalmask, float **buflight, float **bufchro, float **buf_a_cat, float ** buf_b_cat, float ** bufhh, bool HHutili, const float hueref, const float chromaref, const float lumaref, float sobelref, float meansobel, float ** blend2, const struct local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk) +void ImProcFunctions::transit_shapedetect(int senstype, const LabImage * bufexporig, LabImage * originalmask, float **buflight, float **bufchro, float **buf_a_cat, float ** buf_b_cat, float ** bufhh, bool HHutili, const float hueref, const float chromaref, const float lumaref, float sobelref, float meansobel, float ** blend2, const struct local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk) { BENCHFUN { @@ -3358,7 +3494,7 @@ void ImProcFunctions::transit_shapedetect(int senstype, const LabImage *bufexpor } } -void ImProcFunctions::InverseColorLight_Local(int sp, int senstype, const struct local_params & lp, LUTf & lightCurveloc, LUTf & hltonecurveloc, LUTf & shtonecurveloc, LUTf & tonecurveloc, LUTf & exlocalcurve, LUTf & cclocalcurve, float adjustr, bool localcutili, LUTf & lllocalcurve, bool locallutili, LabImage * original, LabImage * transformed, int cx, int cy, const float hueref, const float chromaref, const float lumaref, int sk) +void ImProcFunctions::InverseColorLight_Local(int sp, int senstype, const struct local_params & lp, LabImage * originalmask, LUTf & lightCurveloc, LUTf & hltonecurveloc, LUTf & shtonecurveloc, LUTf & tonecurveloc, LUTf & exlocalcurve, LUTf & cclocalcurve, float adjustr, bool localcutili, LUTf & lllocalcurve, bool locallutili, LabImage * original, LabImage * transformed, int cx, int cy, const float hueref, const float chromaref, const float lumaref, int sk) { // BENCHFUN float ach = (float)lp.trans / 100.f; @@ -3525,10 +3661,25 @@ void ImProcFunctions::InverseColorLight_Local(int sp, int senstype, const struct float kab = 1.f; balancedeltaE(kL, kab); - LabImage *origblur = new LabImage(GW, GH); + std::unique_ptr origblur(new LabImage(GW, GH)); + std::unique_ptr origblurmask; + const bool usemaskcol = (lp.enaColorMaskinv) && senstype == 0; + const bool usemaskall = (usemaskcol); float radius = 3.f / sk; + if (usemaskall) { + origblurmask.reset(new LabImage(GW, GH)); + +#ifdef _OPENMP + #pragma omp parallel if (multiThread) +#endif + { + gaussianBlur(originalmask->L, origblurmask->L, GW, GH, radius); + gaussianBlur(originalmask->a, origblurmask->a, GW, GH, radius); + gaussianBlur(originalmask->b, origblurmask->b, GW, GH, radius); + } + } if (senstype == 1) { radius = (2.f + 0.2f * lp.blurexp) / sk; @@ -3556,6 +3707,7 @@ void ImProcFunctions::InverseColorLight_Local(int sp, int senstype, const struct #pragma omp parallel if (multiThread) #endif { + const LabImage *maskptr = usemaskall ? origblurmask.get() : origblur.get(); const int limscope = 80; const float mindE = 2.f + MINSCOPE * varsens * lp.thr; const float maxdE = 5.f + MAXSCOPE * varsens * (1 + 0.1f * lp.thr); @@ -3587,7 +3739,8 @@ void ImProcFunctions::InverseColorLight_Local(int sp, int senstype, const struct origblur->b[y][x] = 0.01f; } - float dE = sqrt(kab * SQR(refa - origblur->a[y][x] / 327.68f) + kab * SQR(refb - origblur->b[y][x] / 327.68f) + kL * SQR(lumaref - rL)); + // float dE = sqrt(kab * SQR(refa - origblur->a[y][x] / 327.68f) + kab * SQR(refb - origblur->b[y][x] / 327.68f) + kL * SQR(lumaref - rL)); + float dE = sqrt(kab * SQR(refa - maskptr->a[y][x] / 327.68f) + kab * SQR(refb - maskptr->b[y][x] / 327.68f) + kL * SQR(lumaref - maskptr->L[y][x] / 327.68f)); float reducdE = 0.f; calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, varsens, reducdE); @@ -3755,7 +3908,6 @@ void ImProcFunctions::InverseColorLight_Local(int sp, int senstype, const struct } } } - delete origblur; if (senstype == 1 || senstype == 2) { delete temp; @@ -3767,12 +3919,12 @@ void ImProcFunctions::InverseColorLight_Local(int sp, int senstype, const struct } -void ImProcFunctions::calc_ref(int sp, LabImage * original, LabImage * transformed, int cx, int cy, int oW, int oH, int sk, double & huerefblur, double & chromarefblur, double & lumarefblur, double & hueref, double & chromaref, double & lumaref, double & sobelref, float &avg) +void ImProcFunctions::calc_ref(int sp, LabImage * original, LabImage * transformed, int cx, int cy, int oW, int oH, int sk, double & huerefblur, double & chromarefblur, double & lumarefblur, double & hueref, double & chromaref, double & lumaref, double & sobelref, float & avg) { if (params->locallab.enabled) { //always calculate hueref, chromaref, lumaref before others operations use in normal mode for all modules exceprt denoise struct local_params lp; - calcLocalParams(sp, oW, oH, params->locallab, lp, 0, 0, 0, 0, 0, 0, 0, 0); + calcLocalParams(sp, oW, oH, params->locallab, lp, 0, 0, 0, 0, 0, 0, 0, 0, 0); int begy = lp.yc - lp.lyT; int begx = lp.xc - lp.lxL; int yEn = lp.yc + lp.ly; @@ -4025,7 +4177,7 @@ static double *cos_table(size_t size) return table; } -static void mean_dt(const float *data, size_t size, double *mean_p, double *dt_p) +static void mean_dt(const float * data, size_t size, double * mean_p, double * dt_p) { double mean, dt; const float *ptr_data; @@ -4052,7 +4204,7 @@ static void mean_dt(const float *data, size_t size, double *mean_p, double *dt_p return; } -void ImProcFunctions::normalize_mean_dt(float *data, const float *ref, size_t size, float mod) +void ImProcFunctions::normalize_mean_dt(float * data, const float * ref, size_t size, float mod) { /* * Copyright 2009-2011 IPOL Image Processing On Line http://www.ipol.im/ @@ -4096,7 +4248,7 @@ void ImProcFunctions::normalize_mean_dt(float *data, const float *ref, size_t si return; } -static float *rex_poisson_dct(float *data, size_t nx, size_t ny, double m) +static float *rex_poisson_dct(float * data, size_t nx, size_t ny, double m) { /* * Copyright 2009-2011 IPOL Image Processing On Line http://www.ipol.im/ @@ -4152,7 +4304,7 @@ static float *rex_poisson_dct(float *data, size_t nx, size_t ny, double m) -static float *discrete_laplacian_threshold(float *data_out, const float *data_in, size_t nx, size_t ny, float t) +static float *discrete_laplacian_threshold(float * data_out, const float * data_in, size_t nx, size_t ny, float t) { BENCHFUN @@ -4231,7 +4383,7 @@ static float *discrete_laplacian_threshold(float *data_out, const float *data_in return data_out; } -void ImProcFunctions::retinex_pde(float *datain, float * dataout, int bfw, int bfh, float thresh, float multy, float *dE, int show) +void ImProcFunctions::retinex_pde(float * datain, float * dataout, int bfw, int bfh, float thresh, float multy, float * dE, int show) { /* * Copyright 2009-2011 IPOL Image Processing On Line http://www.ipol.im/ @@ -4385,7 +4537,7 @@ void ImProcFunctions::retinex_pde(float *datain, float * dataout, int bfw, int b -void ImProcFunctions::exposure_pde(float *dataor, float *datain, float * dataout, int bfw, int bfh, float thresh, float mod) +void ImProcFunctions::exposure_pde(float * dataor, float * datain, float * dataout, int bfw, int bfh, float thresh, float mod) /* Jacques Desmis July 2019 ** adapted from Ipol Copyright 2009-2011 IPOL Image Processing On Line http://www.ipol.im/ */ @@ -4456,7 +4608,7 @@ void ImProcFunctions::exposure_pde(float *dataor, float *datain, float * dataout } -void ImProcFunctions::fftw_convol_blur(float *input, float *output, int bfw, int bfh, float radius, int fftkern, int algo) +void ImProcFunctions::fftw_convol_blur(float * input, float * output, int bfw, int bfh, float radius, int fftkern, int algo) { /* ** Jacques Desmis june 2019 - inspired by Copyright 2013 IPOL Image Processing On Line http://www.ipol.im/ @@ -5092,14 +5244,14 @@ void ImProcFunctions::fftw_denoise(int GW, int GH, int max_numblox_W, int min_nu } void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * original, LabImage * transformed, LabImage * reserved, int cx, int cy, int oW, int oH, int sk, - const LocretigainCurve & locRETgainCcurve, LUTf & lllocalcurve, bool & locallutili, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, const LocCCmaskCurve & locccmasCurve, bool & lcmasutili, const LocLLmaskCurve & locllmasCurve, bool & llmasutili, const LocHHmaskCurve & lochhmasCurve, bool &lhmasutili, const LocCCmaskexpCurve & locccmasexpCurve, bool &lcmasexputili, const LocLLmaskexpCurve & locllmasexpCurve, bool &llmasexputili, const LocHHmaskexpCurve & lochhmasexpCurve, bool & lhmasexputili, - const LocCCmaskSHCurve & locccmasSHCurve, bool &lcmasSHutili, const LocLLmaskSHCurve & locllmasSHCurve, bool &llmasSHutili, const LocHHmaskSHCurve & lochhmasSHCurve, bool & lhmasSHutili, - const LocCCmaskcbCurve & locccmascbCurve, bool &lcmascbutili, const LocLLmaskcbCurve & locllmascbCurve, bool &llmascbutili, const LocHHmaskcbCurve & lochhmascbCurve, bool & lhmascbutili, - const LocCCmaskretiCurve & locccmasretiCurve, bool &lcmasretiutili, const LocLLmaskretiCurve & locllmasretiCurve, bool &llmasretiutili, const LocHHmaskretiCurve & lochhmasretiCurve, bool & lhmasretiutili, - const LocCCmasktmCurve & locccmastmCurve, bool &lcmastmutili, const LocLLmasktmCurve & locllmastmCurve, bool &llmastmutili, const LocHHmasktmCurve & lochhmastmCurve, bool & lhmastmutili, - const LocCCmaskblCurve & locccmasblCurve, bool &lcmasblutili, const LocLLmaskblCurve & locllmasblCurve, bool &llmasblutili, const LocHHmaskblCurve & lochhmasblCurve, bool & lhmasblutili, + const LocretigainCurve & locRETgainCcurve, LUTf & lllocalcurve, bool & locallutili, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, const LocCCmaskCurve & locccmasCurve, bool & lcmasutili, const LocLLmaskCurve & locllmasCurve, bool & llmasutili, const LocHHmaskCurve & lochhmasCurve, bool & lhmasutili, const LocCCmaskexpCurve & locccmasexpCurve, bool & lcmasexputili, const LocLLmaskexpCurve & locllmasexpCurve, bool & llmasexputili, const LocHHmaskexpCurve & lochhmasexpCurve, bool & lhmasexputili, + const LocCCmaskSHCurve & locccmasSHCurve, bool & lcmasSHutili, const LocLLmaskSHCurve & locllmasSHCurve, bool & llmasSHutili, const LocHHmaskSHCurve & lochhmasSHCurve, bool & lhmasSHutili, + const LocCCmaskcbCurve & locccmascbCurve, bool & lcmascbutili, const LocLLmaskcbCurve & locllmascbCurve, bool & llmascbutili, const LocHHmaskcbCurve & lochhmascbCurve, bool & lhmascbutili, + const LocCCmaskretiCurve & locccmasretiCurve, bool & lcmasretiutili, const LocLLmaskretiCurve & locllmasretiCurve, bool & llmasretiutili, const LocHHmaskretiCurve & lochhmasretiCurve, bool & lhmasretiutili, + const LocCCmasktmCurve & locccmastmCurve, bool & lcmastmutili, const LocLLmasktmCurve & locllmastmCurve, bool & llmastmutili, const LocHHmasktmCurve & lochhmastmCurve, bool & lhmastmutili, + const LocCCmaskblCurve & locccmasblCurve, bool & lcmasblutili, const LocLLmaskblCurve & locllmasblCurve, bool & llmasblutili, const LocHHmaskblCurve & lochhmasblCurve, bool & lhmasblutili, const LocwavCurve & locwavCurve, - bool & LHutili, bool & HHutili, LUTf & cclocalcurve, bool & localcutili, bool & localexutili, LUTf & exlocalcurve, LUTf & hltonecurveloc, LUTf & shtonecurveloc, LUTf & tonecurveloc, LUTf & lightCurveloc, double & huerefblur, double &chromarefblur, double & lumarefblur, double & hueref, double & chromaref, double & lumaref, double & sobelref, int llColorMask, + bool & LHutili, bool & HHutili, LUTf & cclocalcurve, bool & localcutili, bool & localexutili, LUTf & exlocalcurve, LUTf & hltonecurveloc, LUTf & shtonecurveloc, LUTf & tonecurveloc, LUTf & lightCurveloc, double & huerefblur, double & chromarefblur, double & lumarefblur, double & hueref, double & chromaref, double & lumaref, double & sobelref, int llColorMask, int llColorMaskinv, int llExpMask, int llSHMask, int llcbMask, int llretiMask, int llsoftMask, int lltmMask, int llblMask) { /* comment on processus deltaE @@ -5130,7 +5282,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o int del = 3; // to avoid crash with [loy - begy] and [lox - begx] and bfh bfw // with gtk2 [loy - begy-1] [lox - begx -1 ] and del = 1 struct local_params lp; - calcLocalParams(sp, oW, oH, params->locallab, lp, llColorMask, llExpMask, llSHMask, llcbMask, llretiMask, llsoftMask, lltmMask, llblMask); + calcLocalParams(sp, oW, oH, params->locallab, lp, llColorMask, llColorMaskinv, llExpMask, llSHMask, llcbMask, llretiMask, llsoftMask, lltmMask, llblMask); const float radius = lp.rad / (sk * 1.4f); //0 to 70 ==> see skip int strred = 1;//(lp.strucc - 1); @@ -7327,7 +7479,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o } else if (lp.invsh && (lp.highlihs > 0.f || lp.shadowhs > 0.f) && call < 3 && lp.hsena) { float adjustr = 2.f; - InverseColorLight_Local(sp, 2, lp, lightCurveloc, hltonecurveloc, shtonecurveloc, tonecurveloc, exlocalcurve, cclocalcurve, adjustr, localcutili, lllocalcurve, locallutili, original, transformed, cx, cy, hueref, chromaref, lumaref, sk); + InverseColorLight_Local(sp, 2, lp, nullptr, lightCurveloc, hltonecurveloc, shtonecurveloc, tonecurveloc, exlocalcurve, cclocalcurve, adjustr, localcutili, lllocalcurve, locallutili, original, transformed, cx, cy, hueref, chromaref, lumaref, sk); } @@ -8774,7 +8926,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o //inverse else if (lp.invex && (lp.expcomp != 0.0 || lp.war != 0 || (exlocalcurve && localexutili)) && lp.exposena) { float adjustr = 2.f; - InverseColorLight_Local(sp, 1, lp, lightCurveloc, hltonecurveloc, shtonecurveloc, tonecurveloc, exlocalcurve, cclocalcurve, adjustr, localcutili, lllocalcurve, locallutili, original, transformed, cx, cy, hueref, chromaref, lumaref, sk); + InverseColorLight_Local(sp, 1, lp, nullptr, lightCurveloc, hltonecurveloc, shtonecurveloc, tonecurveloc, exlocalcurve, cclocalcurve, adjustr, localcutili, lllocalcurve, locallutili, original, transformed, cx, cy, hueref, chromaref, lumaref, sk); } @@ -8939,148 +9091,71 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o for (int y = ystart; y < yend ; y++) { for (int x = xstart; x < xend; x++) { - transformed->L[y][x] = blend2[y - ystart][x - xstart]; - transformed->a[y][x] = 0.f; - transformed->b[y][x] = 0.f; + const int lox = cx + x; + const int loy = cy + y; + int zone = 0; + float localFactor = 1.f; + const float achm = lp.trans / 100.f; + + if (lp.shapmet == 0) { + calcTransition(lox, loy, achm, lp, zone, localFactor); + } else if (lp.shapmet == 1) { + calcTransitionrect(lox, loy, achm, lp, zone, localFactor); + } + + if (zone > 0) { + transformed->L[y][x] = CLIP(blend2[y - ystart][x - xstart]); + transformed->a[y][x] = 0.f; + transformed->b[y][x] = 0.f; + } } } return; } + } - array2D ble(bfw, bfh); - array2D guid(bfw, bfh); - float meanfab, fab; + int inv = 0; + bool showmaske = false; + bool enaMask = false; + bool deltaE = false; + bool modmask = false; + bool zero = false; + bool modif = false; - mean_fab(xstart, ystart, bfw, bfh, bufcolorig.get(), original, fab, meanfab, lp.chromacol); - - if (lp.showmaskcolmet == 2 || lp.enaColorMask || lp.showmaskcolmet == 3 || lp.showmaskcolmet == 5) { - -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) -#endif - - for (int y = 0; y < bfh; y++) { - for (int x = 0; x < bfw; x++) { - bufmaskblurcol->L[y][x] = original->L[y + ystart][x + xstart]; - bufmaskblurcol->a[y][x] = original->a[y + ystart][x + xstart]; - bufmaskblurcol->b[y][x] = original->b[y + ystart][x + xstart]; - } - } - -#ifdef _OPENMP - #pragma omp parallel -#endif - { -#ifdef __SSE2__ - float atan2Buffer[bfw] ALIGNED64; -#endif -#ifdef _OPENMP - #pragma omp for schedule(dynamic, 16) -#endif - - for (int ir = 0; ir < bfh; ir++) { -#ifdef __SSE2__ - - if (lochhmasCurve && lhmasutili) { - int i = 0; - - for (; i < bfw - 3; i += 4) { - STVF(atan2Buffer[i], xatan2f(LVFU(bufcolorig->b[ir][i]), LVFU(bufcolorig->a[ir][i]))); - } - - for (; i < bfw; i++) { - atan2Buffer[i] = xatan2f(bufcolorig->b[ir][i], bufcolorig->a[ir][i]); - } - } - -#endif - - for (int jr = 0; jr < bfw; jr++) { - float kmaskL = 0.f; - float kmaskC = 0.f; - float kmaskHL = 0.f; - float kmaskH = 0.f; - - if (locllmasCurve && llmasutili) { - kmaskL = 32768.f * LIM01(1.f - locllmasCurve[(500.f / 32768.f) * bufcolorig->L[ir][jr]]); - } - - if (lp.showmaskcolmet != 5 && locccmasCurve && lcmasutili) { - kmaskC = LIM01(1.f - locccmasCurve[500.f * (0.0001f + sqrt(SQR(bufcolorig->a[ir][jr]) + SQR(bufcolorig->b[ir][jr])) / fab)]); - } - - if (lochhmasCurve && lhmasutili) { -#ifdef __SSE2__ - const float huema = atan2Buffer[jr]; -#else - const float huema = xatan2f(bufcolorig->b[ir][jr], bufcolorig->a[ir][jr]); -#endif - float h = Color::huelab_to_huehsv2(huema); - h += 1.f / 6.f; - - if (h > 1.f) { - h -= 1.f; - } - - const float valHH = LIM01(1.f - lochhmasCurve[500.f * h]); - - if (lp.showmaskcolmet != 5) { - kmaskH = valHH; - } - - kmaskHL = 32768.f * valHH; - } - - bufmaskblurcol->L[ir][jr] = CLIPLOC(kmaskL + kmaskHL); - bufmaskblurcol->a[ir][jr] = CLIPC(kmaskC + kmaskH); - bufmaskblurcol->b[ir][jr] = CLIPC(kmaskC + kmaskH); - ble[ir][jr] = bufmaskblurcol->L[ir][jr] / 32768.f; - guid[ir][jr] = bufcolorig->L[ir][jr] / 32768.f; - } - } - } - - if (lp.radmacol > 0.f) { - guidedFilter(guid, ble, ble, lp.radmacol * 10.f / sk, 0.001, multiThread, 4); - } - - LUTf lutTonemaskexp(65536); - calcGammaLut(lp.gammacol, lp.slomacol, lutTonemaskexp); - -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) -#endif - - for (int ir = 0; ir < bfh; ir++) { - for (int jr = 0; jr < bfw; jr++) { - bufmaskblurcol->L[ir][jr] = lutTonemaskexp[LIM01(ble[ir][jr]) * 65536.f]; - } - } + if (lp.showmaskcolmet == 3) { + showmaske = true; } - const float radiusb = 1.f / sk; + if (lp.enaColorMask) { + enaMask = true; + } - if (lp.showmaskcolmet == 2 || lp.enaColorMask || lp.showmaskcolmet == 3 || lp.showmaskcolmet == 5) { -#ifdef _OPENMP - #pragma omp parallel -#endif - { - gaussianBlur(bufmaskblurcol->L, bufmaskblurcol->L, bfw, bfh, radiusb); - gaussianBlur(bufmaskblurcol->a, bufmaskblurcol->a, bfw, bfh, 1.f + (0.5f * lp.radmacol) / sk); - gaussianBlur(bufmaskblurcol->b, bufmaskblurcol->b, bfw, bfh, 1.f + (0.5f * lp.radmacol) / sk); - } + if (lp.showmaskcolmet == 5) { + deltaE = true; + } - if (lp.showmaskcolmet == 0 || lp.showmaskcolmet == 1 || lp.showmaskcolmet == 2 || lp.showmaskcolmet == 4 || lp.showmaskcolmet == 5 || lp.enaColorMask) { - originalmaskcol->CopyFrom(transformed); - blendmask(lp, xstart, ystart, cx, cy, bfw, bfh, bufcolorig.get(), original, bufmaskblurcol.get(), originalmaskcol.get(), lp.blendmacol, 0); - } else if (lp.showmaskcolmet == 3) { - showmask(lp, xstart, ystart, cx, cy, bfw, bfh, bufcolorig.get(), transformed, bufmaskblurcol.get(), 0); + if (lp.showmaskcolmet == 2) { + modmask = true; + } - return; + if (lp.showmaskcolmet == 1) { + modif = true; + } - } + if (lp.showmaskcolmet == 0) { + zero = true; + } + + maskcalccol(bfw, bfh, xstart, ystart, sk, cx, cy, bufcolorig.get(), bufmaskblurcol.get(), originalmaskcol.get(), original, transformed, inv, lp, + locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, multiThread, + enaMask, showmaske, deltaE, modmask, zero, modif); + + if (lp.showmaskcolmet == 3) { + showmask(lp, xstart, ystart, cx, cy, bfw, bfh, bufcolorig.get(), transformed, bufmaskblurcol.get(), 0); + + return; } if (lp.showmaskcolmet == 4) { @@ -9225,7 +9300,63 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o adjustr = 1.8f; } - InverseColorLight_Local(sp, 0, lp, lightCurveloc, hltonecurveloc, shtonecurveloc, tonecurveloc, exlocalcurve, cclocalcurve, adjustr, localcutili, lllocalcurve, locallutili, original, transformed, cx, cy, hueref, chromaref, lumaref, sk); + std::unique_ptr bufmaskblurcol; + std::unique_ptr originalmaskcol; + std::unique_ptr bufcolorig; + int GW = transformed->W; + int GH = transformed->H; + bufcolorig.reset(new LabImage(GW, GH)); + + if (lp.enaColorMaskinv || lp.showmaskcolmetinv == 1) { + bufmaskblurcol.reset(new LabImage(GW, GH, true)); + originalmaskcol.reset(new LabImage(GW, GH)); + } + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int y = 0; y < GH ; y++) { + for (int x = 0; x < GW; x++) { + bufcolorig->L[y][x] = original->L[y][x]; + } + } + + int inv = 1; + bool showmaske = false; + bool enaMask = false; + bool deltaE = false; + bool modmask = false; + bool zero = false; + bool modif = false; + + // printf("showmaskcolmetinv=%i\n", lp.showmaskcolmetinv); + if (lp.showmaskcolmetinv == 1) { + showmaske = true; + } + + if (lp.enaColorMaskinv) { + enaMask = true; + } + + if (lp.showmaskcolmetinv == 0) { + zero = true; + } + + maskcalccol(GW, GH, 0, 0, sk, cx, cy, bufcolorig.get(), bufmaskblurcol.get(), originalmaskcol.get(), original, transformed, inv, lp, + locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, multiThread, + enaMask, showmaske, deltaE, modmask, zero, modif); + + + if (lp.showmaskcolmetinv == 1) { + showmask(lp, 0, 0, cx, cy, GW, GH, bufcolorig.get(), transformed, bufmaskblurcol.get(), inv); + + return; + } + + if (lp.showmaskcolmetinv == 0 || lp.enaColorMaskinv) { + InverseColorLight_Local(sp, 0, lp, originalmaskcol.get(), lightCurveloc, hltonecurveloc, shtonecurveloc, tonecurveloc, exlocalcurve, cclocalcurve, adjustr, localcutili, lllocalcurve, locallutili, original, transformed, cx, cy, hueref, chromaref, lumaref, sk); + } } // Gamut and Munsell control - very important do not desactivated to avoid crash diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 17d8cb80a..74a652592 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -761,6 +761,7 @@ enum ProcEventCode { Evlocallabitera = 731, Evlocallabguidbl = 732, Evlocallabepsbl = 733, + EvlocallabshowmaskcolMethodinv = 734, NUMOFEVENTS }; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 006942df8..959d55237 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -760,7 +760,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, // EvlocallabmedMethod LUMINANCECURVE, // Evlocallabitera LUMINANCECURVE, // Evlocallabguidbl - LUMINANCECURVE // Evlocallabepsbl + LUMINANCECURVE, // Evlocallabepsbl + LUMINANCECURVE // EvlocallabshowmaskcolMethodinv }; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 9a8ad9cc7..fe2a589e3 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -507,7 +507,7 @@ public: virtual void updateUnLock() = 0; - virtual void setLocallabMaskVisibility(int locallColorMask, int locallExpMask, int locallSHMask, int locallcbMask, int locallretiMask, int locallsoftMask, int localltmMask, int locallblMask) = 0; + virtual void setLocallabMaskVisibility(int locallColorMask, int locallColorMaskinv, int locallExpMask, int locallSHMask, int locallcbMask, int locallretiMask, int locallsoftMask, int localltmMask, int locallblMask) = 0; /** Creates and returns a Crop instance that acts as a window on the image * @param editDataProvider pointer to the EditDataProvider that communicates with the EditSubscriber diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 95e930ad5..3dcc4c252 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1217,7 +1217,7 @@ private: locccmastmCurve, lcmastmutili, locllmastmCurve, llmastmutili, lochhmastmCurve, lhmastmutili, locccmasblCurve, lcmasblutili, locllmasblCurve, llmasblutili, lochhmasblCurve, lhmasblutili, locwavCurve, - LHutili, HHutili, cclocalcurve, localcutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, 0, 0, 0, 0, 0, 0, 0, 0); + LHutili, HHutili, cclocalcurve, localcutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, 0, 0, 0, 0, 0, 0, 0, 0, 0); // Clear local curves diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index f8dcfe8eb..cf47848dd 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -361,6 +361,7 @@ Locallab::Locallab(): qualitycurveMethod(Gtk::manage(new MyComboBoxText())), gridMethod(Gtk::manage(new MyComboBoxText())), showmaskcolMethod(Gtk::manage(new MyComboBoxText())), + showmaskcolMethodinv(Gtk::manage(new MyComboBoxText())), //Exposure showmaskexpMethod(Gtk::manage(new MyComboBoxText())), expMethod(Gtk::manage(new MyComboBoxText())), @@ -556,6 +557,18 @@ Locallab::Locallab(): showmaskcolMethodConn = showmaskcolMethod->signal_changed().connect(sigc::mem_fun(*this, &Locallab::showmaskcolMethodChanged)); + showmaskcolMethodinv->append(M("TP_LOCALLAB_SHOWMNONE")); + showmaskcolMethodinv->append(M("TP_LOCALLAB_SHOWMASK")); + + showmaskcolMethodinv->set_active(0); + + if (showtooltip) { + showmaskcolMethodinv->set_tooltip_markup(M("TP_LOCALLAB_SHOWMASKCOL_TOOLTIP")); + } + + showmaskcolMethodConninv = showmaskcolMethodinv->signal_changed().connect(sigc::mem_fun(*this, &Locallab::showmaskcolMethodChangedinv)); + + enaColorMaskConn = enaColorMask->signal_toggled().connect(sigc::mem_fun(*this, &Locallab::enaColorMaskChanged)); maskCurveEditorG->setCurveListener(this); @@ -629,6 +642,7 @@ Locallab::Locallab(): colorBox->pack_start(*invers); ToolParamBlock* const maskcolBox = Gtk::manage(new ToolParamBlock()); maskcolBox->pack_start(*showmaskcolMethod, Gtk::PACK_SHRINK, 4); + maskcolBox->pack_start(*showmaskcolMethodinv, Gtk::PACK_SHRINK, 4); maskcolBox->pack_start(*enaColorMask, Gtk::PACK_SHRINK, 0); maskcolBox->pack_start(*maskCurveEditorG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor maskcolBox->pack_start(*blendmaskcol, Gtk::PACK_SHRINK, 0); @@ -1053,7 +1067,7 @@ Locallab::Locallab(): BLTitleHBox->pack_end(*BLImage, Gtk::PACK_SHRINK, 0); expblur->setLabel(BLTitleHBox); - + expblur->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Locallab::foldAllButMe), expblur)); enableblurConn = expblur->signal_enabled_toggled().connect(sigc::bind(sigc::mem_fun(this, &Locallab::enableToggled), expblur)); @@ -3949,12 +3963,35 @@ void Locallab::showmaskcolMethodChanged() } } +void Locallab::showmaskcolMethodChangedinv() +{ + // printf("showmaskcolMethodChanged\n"); + + // When one mask state is changed, other masks are deactivated + disableListener(); + showmaskcolMethod->set_active(0); + showmaskexpMethod->set_active(0); + showmaskSHMethod->set_active(0); + showmaskcbMethod->set_active(0); + showmaskretiMethod->set_active(0); + showmasksoftMethod->set_active(0); + showmasktmMethod->set_active(0); + showmaskblMethod->set_active(0); + enableListener(); + + if (listener) { + listener->panelChanged(EvlocallabshowmaskcolMethodinv, ""); + } +} + + void Locallab::showmaskexpMethodChanged() { // printf("showmaskexpMethodChanged\n"); // When one mask state is changed, other masks are deactivated disableListener(); + showmaskcolMethodinv->set_active(0); showmaskcolMethod->set_active(0); showmaskcbMethod->set_active(0); showmaskSHMethod->set_active(0); @@ -4002,6 +4039,7 @@ void Locallab::showmaskSHMethodChanged() // When one mask state is changed, other masks are deactivated disableListener(); + showmaskcolMethodinv->set_active(0); showmaskcolMethod->set_active(0); showmaskexpMethod->set_active(0); showmaskcbMethod->set_active(0); @@ -4022,6 +4060,7 @@ void Locallab::showmaskcbMethodChanged() // When one mask state is changed, other masks are deactivated disableListener(); + showmaskcolMethodinv->set_active(0); showmaskcolMethod->set_active(0); showmaskSHMethod->set_active(0); showmaskexpMethod->set_active(0); @@ -4042,6 +4081,7 @@ void Locallab::showmaskblMethodChanged() // When one mask state is changed, other masks are deactivated disableListener(); + showmaskcolMethodinv->set_active(0); showmaskcolMethod->set_active(0); showmaskSHMethod->set_active(0); showmaskexpMethod->set_active(0); @@ -4064,6 +4104,7 @@ void Locallab::showmasktmMethodChanged() // When one mask state is changed, other masks are deactivated disableListener(); + showmaskcolMethodinv->set_active(0); showmaskcolMethod->set_active(0); showmaskSHMethod->set_active(0); showmaskexpMethod->set_active(0); @@ -4084,6 +4125,7 @@ void Locallab::showmaskretiMethodChanged() // When one mask state is changed, other masks are deactivated disableListener(); + showmaskcolMethodinv->set_active(0); showmaskcolMethod->set_active(0); showmaskSHMethod->set_active(0); showmaskexpMethod->set_active(0); @@ -4103,6 +4145,7 @@ void Locallab::showmasksoftMethodChanged() // When one mask state is changed, other masks are deactivated disableListener(); + showmaskcolMethodinv->set_active(0); showmaskcolMethod->set_active(0); showmaskexpMethod->set_active(0); showmaskSHMethod->set_active(0); @@ -4121,6 +4164,7 @@ void Locallab::resetMaskVisibility() // printf("resetMaskVisibility\n"); disableListener(); + showmaskcolMethodinv->set_active(0); showmaskcolMethod->set_active(0); showmaskexpMethod->set_active(0); showmaskSHMethod->set_active(0); @@ -4134,6 +4178,7 @@ void Locallab::resetMaskVisibility() Locallab::llMaskVisibility* Locallab::getMaskVisibility() { llMaskVisibility* maskStruct = new llMaskVisibility(); + maskStruct->colorMaskinv = showmaskcolMethodinv->get_active_row_number(); maskStruct->colorMask = showmaskcolMethod->get_active_row_number(); maskStruct->expMask = showmaskexpMethod->get_active_row_number(); maskStruct->SHMask = showmaskSHMethod->get_active_row_number(); @@ -4366,8 +4411,9 @@ void Locallab::inversChanged() strengthgrid->hide(); blurcolde->show(); softradiuscol->show(); - showmaskcolMethod->hide(); // Being able to change Color & Light mask visibility is useless in batch mode + showmaskcolMethod->show(); // Being able to change Color & Light mask visibility is useless in batch mode gridFrame->hide(); + showmaskcolMethodinv->hide(); // Being able to change Color & Light mask visibility is useless in batch mode } else if (invers->get_active()) { sensi->show(); llCurveEditorG->show(); @@ -4375,13 +4421,14 @@ void Locallab::inversChanged() curvactiv->hide(); qualitycurveMethod->hide(); labqualcurv->hide(); - expmaskcol->hide(); + expmaskcol->show(); structcol->hide(); blurcolde->show(); gridFrame->hide(); strengthgrid->hide(); softradiuscol->hide(); - + showmaskcolMethod->hide(); + showmaskcolMethodinv->show(); } else { sensi->show(); llCurveEditorG->show(); @@ -4394,9 +4441,12 @@ void Locallab::inversChanged() blurcolde->show(); gridFrame->show(); softradiuscol->show(); + showmaskcolMethodinv->hide(); + showmaskcolMethod->show(); if (batchMode) { showmaskcolMethod->hide(); // Being able to change Color & Light mask visibility is useless in batch mode + showmaskcolMethodinv->hide(); // Being able to change Color & Light mask visibility is useless in batch mode } } @@ -6402,6 +6452,7 @@ void Locallab::setBatchMode(bool batchMode) // In batch mode, being able to change mask visibility is useless showmaskcolMethod->hide(); + showmaskcolMethodinv->hide(); showmaskexpMethod->hide(); showmaskSHMethod->hide(); showmaskcbMethod->hide(); @@ -6550,6 +6601,7 @@ void Locallab::enableListener() gridMethodConn.block(false); inversConn.block(false); showmaskcolMethodConn.block(false); + showmaskcolMethodConninv.block(false); enaColorMaskConn.block(false); // Exposure enableexposeConn.block(false); @@ -6620,6 +6672,7 @@ void Locallab::disableListener() gridMethodConn.block(true); inversConn.block(true); showmaskcolMethodConn.block(true); + showmaskcolMethodConninv.block(true); enaColorMaskConn.block(true); // Exposure enableexposeConn.block(true); @@ -7309,16 +7362,19 @@ void Locallab::updateSpecificGUIState() expmaskcol->show(); structcol->show(); softradiuscol->show(); - showmaskcolMethod->hide(); // Being able to change Color & Light mask visibility is useless in batch mode + showmaskcolMethod->show(); // Being able to change Color & Light mask visibility is useless in batch mode + showmaskcolMethodinv->hide(); gridFrame->hide(); } else if (invers->get_active()) { HCurveEditorG->hide(); qualitycurveMethod->hide(); labqualcurv->hide(); - expmaskcol->hide(); + expmaskcol->show(); softradiuscol->hide(); structcol->hide(); gridFrame->hide(); + showmaskcolMethod->hide(); // Being able to change Color & Light mask visibility is useless in batch mode + showmaskcolMethodinv->show(); } else { HCurveEditorG->show(); qualitycurveMethod->show(); @@ -7327,9 +7383,12 @@ void Locallab::updateSpecificGUIState() structcol->show(); gridFrame->show(); softradiuscol->show(); + showmaskcolMethod->show(); // Being able to change Color & Light mask visibility is useless in batch mode + showmaskcolMethodinv->hide(); if (batchMode) { showmaskcolMethod->hide(); // Being able to change Color & Light mask visibility is useless in batch mode + showmaskcolMethodinv->hide(); // Being able to change Color & Light mask visibility is useless in batch mode } } diff --git a/rtgui/locallab.h b/rtgui/locallab.h index a56ce37a2..26f862aff 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -332,6 +332,8 @@ private: sigc::connection gridMethodConn; MyComboBoxText* const showmaskcolMethod; sigc::connection showmaskcolMethodConn; + MyComboBoxText* const showmaskcolMethodinv; + sigc::connection showmaskcolMethodConninv; //Exposure MyComboBoxText* const showmaskexpMethod; sigc::connection showmaskexpMethodConn; @@ -443,6 +445,7 @@ private: void qualitycurveMethodChanged(); void gridMethodChanged(); void showmaskcolMethodChanged(); + void showmaskcolMethodChangedinv(); //Exposure void showmaskexpMethodChanged(); void expMethodChanged(); @@ -498,6 +501,7 @@ public: // Mask visibility management functions struct llMaskVisibility { int colorMask; + int colorMaskinv; int expMask; int SHMask; int cbMask; diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index c83b0d13d..c9a778cd0 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -474,10 +474,10 @@ void ToolPanelCoordinator::panelChanged(const rtengine::ProcEvent& event, const } // Manage Locallab mask visibility - if (event == rtengine::EvlocallabshowmaskcolMethod || event == rtengine::EvlocallabshowmaskexpMethod || event == rtengine::EvlocallabshowmaskSHMethod || event == rtengine::EvlocallabshowmasksoftMethod + if (event == rtengine::EvlocallabshowmaskcolMethod || event == rtengine::EvlocallabshowmaskcolMethodinv ||event == rtengine::EvlocallabshowmaskexpMethod || event == rtengine::EvlocallabshowmaskSHMethod || event == rtengine::EvlocallabshowmasksoftMethod || event == rtengine::EvlocallabshowmaskcbMethod || event == rtengine::EvlocallabshowmaskretiMethod || event == rtengine::EvlocallabshowmasktmMethod || event == rtengine::EvlocallabshowmaskblMethod) { Locallab::llMaskVisibility* maskStruc = locallab->getMaskVisibility(); - ipc->setLocallabMaskVisibility(maskStruc->colorMask, maskStruc->expMask, maskStruc->SHMask, maskStruc->cbMask, maskStruc->retiMask, maskStruc->softMask, maskStruc->tmMask, maskStruc->blMask); + ipc->setLocallabMaskVisibility(maskStruc->colorMask, maskStruc->colorMaskinv, maskStruc->expMask, maskStruc->SHMask, maskStruc->cbMask, maskStruc->retiMask, maskStruc->softMask, maskStruc->tmMask, maskStruc->blMask); } ipc->endUpdateParams(changeFlags); // starts the IPC processing @@ -585,7 +585,7 @@ void ToolPanelCoordinator::profileChange( // Reset Locallab mask visibility when a picture is loaded if (event == rtengine::EvPhotoLoaded) { locallab->resetMaskVisibility(); - ipc->setLocallabMaskVisibility(0, 0, 0, 0, 0, 0, 0, 0); + ipc->setLocallabMaskVisibility(0, 0, 0, 0, 0, 0, 0, 0, 0); } // start the IPC processing