From c71d70f0ea4834afff15758fdd5b83dbab7c201b Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 13 Jan 2019 14:49:11 +0100 Subject: [PATCH] Add structure to shape detection for colorlight and exposure --- rtdata/languages/default | 3 + rtengine/dcrop.cc | 2 +- rtengine/improccoordinator.cc | 16 +- rtengine/improcfun.h | 8 +- rtengine/iplocallab.cc | 924 ++++++++-------------------------- rtengine/procevents.h | 2 + rtengine/procparams.cc | 10 +- rtengine/procparams.h | 2 + rtengine/refreshmap.cc | 4 +- rtengine/simpleprocess.cc | 8 +- rtgui/locallab.cc | 37 ++ rtgui/locallab.h | 3 + rtgui/paramsedited.cc | 14 + rtgui/paramsedited.h | 2 + 14 files changed, 301 insertions(+), 734 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index a51999ede..fd1e80cf2 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -864,6 +864,8 @@ HISTORY_MSG_608;Local - Color Mask L HISTORY_MSG_609;Local - Exp Mask C HISTORY_MSG_610;Local - Exp Mask L HISTORY_MSG_611;Local - Color Mask H +HISTORY_MSG_612;Local - Color Structure +HISTORY_MSG_613;Local - Exp Structure HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -2039,6 +2041,7 @@ TP_LOCALLAB_USEMASK;Use mask TP_LOCALLAB_SOFT;Soft Light TP_LOCALLAB_STRENG;Strength TP_LOCALLAB_STRENGTH;Noise +TP_LOCALLAB_STRUCCOL;Structure TP_LOCALLAB_STYPE;Shape method TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. TP_LOCALLAB_SYMSL;Symmetrical (mouse + sliders) diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index cca4fd2ec..b8afd3c7a 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -951,7 +951,7 @@ void Crop::update(int todo) hltonecurveloc2, shtonecurveloc2, tonecurveloc2, lightCurveloc2, sca); - parent->ipf.Lab_Local(1, sp, parent->sobelrefs, (float**)shbuffer, labnCrop, labnCrop, reservCrop, cropx / skip, cropy / skip, skips(parent->fw, skip), skips(parent->fh, skip), skip, locRETgainCurve, lllocalcurve2, + 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, loclhCurve, lochhCurve, locccmasCurve, locllmasCurve, lochhmasCurve, locccmasexpCurve, locllmasexpCurve, LHutili, HHutili, cclocalcurve2, localskutili, sklocalcurve2, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, lightCurveloc2, huerefblu, huere, chromare, lumare, sobelre); lllocalcurve2.clear(); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 267c95aea..fcb09d36a 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -27,6 +27,7 @@ #include #include #include +#include "jaggedarray.h" #include "iccstore.h" #include @@ -772,6 +773,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) float **shbuffer = nullptr; int sca = 1; double huere, chromare, lumare, huerefblu, sobelre; + JaggedArray blend(pW, pH); for (int sp = 0; sp < params.locallab.nbspot && sp < (int)params.locallab.spots.size(); sp++) { // Set local curves of current spot to LUT @@ -805,9 +807,9 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) // Reference parameters computation if (params.locallab.spots.at(sp).spotMethod == "exc") { - ipf.calc_ref(sp, reserv, reserv, 0, 0, pW, pH, scale, huerefblu, huere, chromare, lumare, sobelre, lhist16loc); + ipf.calc_ref(sp, reserv, reserv, blend, 0, 0, pW, pH, scale, huerefblu, huere, chromare, lumare, sobelre, lhist16loc); } else { - ipf.calc_ref(sp, nprevl, nprevl, 0, 0, pW, pH, scale, huerefblu, huere, chromare, lumare, sobelre, lhist16loc); + ipf.calc_ref(sp, nprevl, nprevl, blend, 0, 0, pW, pH, scale, huerefblu, huere, chromare, lumare, sobelre, lhist16loc); } CurveFactory::complexCurvelocal(ecomp, black / 65535., hlcompr, hlcomprthresh, shcompr, br, cont, lhist16loc, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, @@ -830,13 +832,13 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) * - maxspot, huerefs, centerx and centery aren't used in Lab_Local (only for printf) so values aren't important * - shbuffer is used as nullptr */ - ipf.Lab_Local(3, sp, sobelrefs, (float**)shbuffer, nprevl, nprevl, reserv, 0, 0, pW, pH, scale, locRETgainCurve, lllocalcurve, loclhCurve, lochhCurve, locccmasCurve, locllmasCurve, lochhmasCurve, locccmasexpCurve, locllmasexpCurve, + ipf.Lab_Local(3, sp, (float**)shbuffer, nprevl, nprevl, reserv, 0, 0, pW, pH, scale, locRETgainCurve, lllocalcurve, loclhCurve, lochhCurve, locccmasCurve, locllmasCurve, lochhmasCurve, locccmasexpCurve, locllmasexpCurve, LHutili, HHutili, cclocalcurve, localskutili, sklocalcurve, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerblu, huer, chromar, lumar, sobeler); if (params.locallab.spots.at(sp).spotMethod == "exc") { - ipf.calc_ref(sp, reserv, reserv, 0, 0, pW, pH, scale, huerefblu, huere, chromare, lumare, sobelre, lhist16loc); + ipf.calc_ref(sp, reserv, reserv, blend, 0, 0, pW, pH, scale, huerefblu, huere, chromare, lumare, sobelre, lhist16loc); } else { - ipf.calc_ref(sp, nprevl, nprevl, 0, 0, pW, pH, scale, huerefblu, huere, chromare, lumare, sobelre, lhist16loc); + ipf.calc_ref(sp, nprevl, nprevl, blend, 0, 0, pW, pH, scale, huerefblu, huere, chromare, lumare, sobelre, lhist16loc); } // Clear local curves @@ -848,9 +850,9 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) for (int sp = 0; sp < params.locallab.nbspot && sp < (int)params.locallab.spots.size(); sp++) { //update references after threatment if (params.locallab.spots.at(sp).spotMethod == "exc") { - ipf.calc_ref(sp, reserv, reserv, 0, 0, pW, pH, scale, huerefblu, huere, chromare, lumare, sobelre, lhist16loc); + ipf.calc_ref(sp, reserv, reserv, blend, 0, 0, pW, pH, scale, huerefblu, huere, chromare, lumare, sobelre, lhist16loc); } else { - ipf.calc_ref(sp, nprevl, nprevl, 0, 0, pW, pH, scale, huerefblu, huere, chromare, lumare, sobelre, lhist16loc); + ipf.calc_ref(sp, nprevl, nprevl, blend, 0, 0, pW, pH, scale, huerefblu, huere, chromare, lumare, sobelre, lhist16loc); } huerblu = huerefblurs[sp] = huerefblu; huer = huerefs[sp] = huere; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 35adef0d6..bf6d59b11 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -286,10 +286,10 @@ public: //locallab void MSRLocal(int sp, float** luminance, float** templ, const float* const *originalLuminance, const int width, const int height, const LocallabParams &loc, const int skip, const LocretigainCurve &locRETgainCcurve, const int chrome, const int scall, const float krad, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax); // void calc_ref (LabImage* original, LabImage* transformed, int cx, int cy, int oW, int oH, int sk, double &huere, double &chromare, double &lumare, double &sobelref); - void calc_ref(int sp, LabImage* original, LabImage* transformed, int cx, int cy, int oW, int oH, int sk, double &huerefblur, double &huere, double &chromare, double &lumare, double &sobelref, LUTu & histogram); + void calc_ref(int sp, LabImage* original, LabImage* transformed, float **blend, int cx, int cy, int oW, int oH, int sk, double &huerefblur, double &huere, double &chromare, double &lumare, double &sobelref, LUTu & histogram); void copy_ref(LabImage* spotbuffer, LabImage* original, LabImage* transformed, int cx, int cy, int sk, const struct local_params & lp, double &huerefspot, double &chromarefspot, double &lumarefspot); void paste_ref(LabImage* spotbuffer, LabImage* transformed, int cx, int cy, int sk, const struct local_params & lp); - void Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbuffer, LabImage* original, LabImage* transformed, LabImage* reserved, int cx, int cy, int oW, int oH, int sk, const LocretigainCurve & locRETgainCcurve, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, const LocCCmaskCurve & locccmasCurve, const LocLLmaskCurve & locllmasCurve, const LocHHmaskCurve & lochhmasCurve, const LocCCmaskexpCurve & locccmasexpCurve, const LocLLmaskexpCurve & locllmasexpCurve, bool &LHutili, bool &HHutili, LUTf & cclocalcurve, bool & localskutili, LUTf & sklocalcurve, bool & localexutili, LUTf & exlocalcurve, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, LUTf & lightCurveloc, double & huerefblur, double &hueref, double &chromaref, double &lumaref, double &sobelref); + void 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, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, const LocCCmaskCurve & locccmasCurve, const LocLLmaskCurve & locllmasCurve, const LocHHmaskCurve & lochhmasCurve, const LocCCmaskexpCurve & locccmasexpCurve, const LocLLmaskexpCurve & locllmasexpCurve, bool &LHutili, bool &HHutili, LUTf & cclocalcurve, bool & localskutili, LUTf & sklocalcurve, bool & localexutili, LUTf & exlocalcurve, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, LUTf & lightCurveloc, double & huerefblur, double &hueref, double &chromaref, double &lumaref, double &sobelref); 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); void InverseBlurNoise_Local(const struct local_params& lp, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy); @@ -302,7 +302,7 @@ public: void vibrancelocal(int sp, int bfw, int bfh, LabImage* lab, LabImage* dest, bool & localskutili, LUTf & sklocalcurve); // void Expo_vibr_Local(float moddE, float powdE, int senstype, float **buflight, float **bufchro, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const struct local_params & lp, LabImage * original, LabImage * transformed, const LabImage * const tmp1, int cx, int cy, int sk); - void Expo_vibr_Local(float moddE, float powdE, int senstype, LabImage * originalmask, float **buflight, float **bufchro, float **buf_a_cat, float ** buf_b_cat, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const struct local_params & lp, LabImage * original, LabImage * transformed, LabImage * difLab, const LabImage * const tmp1, int cx, int cy, int sk); + void Expo_vibr_Local(float moddE, float powdE, int senstype, LabImage * originalmask, float **buflight, float **bufchro, float **buf_a_cat, float ** buf_b_cat, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, float sobelref, float ** blend2, const struct local_params & lp, LabImage * original, LabImage * transformed, LabImage * difLab, const LabImage * const tmp1, int cx, int cy, int sk); void exlabLocal(const local_params& lp, int bfh, int bfw, LabImage* bufexporig, LabImage* lab, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve); void Exclude_Local(float moddE, float powdE, int sen, float **deltaso, float **buflight, float **bufchro, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const struct local_params & lp, LabImage * original, LabImage * transformed, LabImage * rsv, LabImage * reserv, int cx, int cy, int sk); @@ -311,7 +311,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, 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 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, float ** blendch, 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(const struct local_params& lp, LUTf & lightCurveloc, LabImage* original, LabImage* transformed, int cx, int cy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, 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 09a616ebc..f15db7384 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -157,8 +157,11 @@ struct local_params { float thr; int prox; int chro, cont, sens, sensh, senscb, sensbn, senstm, sensex, sensexclu, sensden, senslc, senssf; + float struco; + float struexp; float ligh; int shamo, shdamp, shiter, senssha, sensv; + float neig; float strng; float lcamount; double shrad; @@ -361,7 +364,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall double local_dyy = locallab.spots.at(sp).iter / 8000.0; float iterati = (float) locallab.spots.at(sp).iter; // double local_dyy = locallab.proxi; - + float neigh = float (locallab.spots.at(sp).neigh); float chromaPastel = float (locallab.spots.at(sp).pastels) / 100.0f; float chromaSatur = float (locallab.spots.at(sp).saturated) / 100.0f; int local_sensiv = locallab.spots.at(sp).sensiv; @@ -465,6 +468,8 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall int local_sensicb = locallab.spots.at(sp).sensicb; int local_contrast = locallab.spots.at(sp).contrast; float local_lightness = (float) locallab.spots.at(sp).lightness; + float structcolor = (float) locallab.spots.at(sp).structcol; + float structexpo = (float) locallab.spots.at(sp).structexp; int local_transit = locallab.spots.at(sp).transit; double radius = (double) locallab.spots.at(sp).radius; double sharradius = ((double) locallab.spots.at(sp).sharradius) / 100. ; @@ -499,6 +504,8 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.lxL = w * local_xL; lp.lyT = h * local_yT; lp.chro = local_chroma; + lp.struco = structcolor; + lp.struexp = structexpo; lp.sens = local_sensi; lp.sensh = local_sensih; lp.dehaze = local_dehaze; @@ -507,7 +514,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.ligh = local_lightness; lp.senssf = local_sensisf; lp.strng = strlight; - + lp.neig = neigh; if (lp.ligh >= -2.f && lp.ligh <= 2.f) { lp.ligh /= 5.f; } @@ -5039,7 +5046,7 @@ void ImProcFunctions::Exclude_Local(float moddE, float powdE, int sen, float **d } -void ImProcFunctions::Expo_vibr_Local(float moddE, float powdE, int senstype, LabImage * originalmask, float **buflight, float **bufchro, float **buf_a_cat, float ** buf_b_cat, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const struct local_params & lp, LabImage * original, LabImage * transformed, LabImage * difLab, const LabImage * const tmp1, int cx, int cy, int sk) +void ImProcFunctions::Expo_vibr_Local(float moddE, float powdE, int senstype, LabImage * originalmask, float **buflight, float **bufchro, float **buf_a_cat, float ** buf_b_cat, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, float sobelref, float ** blend2, const struct local_params & lp, LabImage * original, LabImage * transformed, LabImage * difLab, const LabImage * const tmp1, int cx, int cy, int sk) { //local exposure and vibrance @@ -5068,7 +5075,11 @@ void ImProcFunctions::Expo_vibr_Local(float moddE, float powdE, int senstype, La constexpr float bchsens = 1.f - 20.f * achsens; const float multchro = varsens * achsens + bchsens; - //luma + //sobel + sobelref /= 100.; + if(sobelref > 60.) sobelref = 60.; + sobelref = log(1.f + sobelref); + //skin constexpr float amplchsensskin = 1.6f; @@ -5206,17 +5217,30 @@ void ImProcFunctions::Expo_vibr_Local(float moddE, float powdE, int senstype, La float rchro = sqrt(SQR(origblur->b[y][x]) + SQR(origblur->a[y][x])) / 327.68f; #endif float rL = origblur->L[y][x] / 327.68f; + float csob = 0.f; + float rs = 0.f; + if (senstype == 1){ + csob = (blend2[loy - begy][lox - begx])/100.f ; + if(csob > 60.f) csob = 60.f; + csob = log(1.f + csob); + rs = sobelref / csob; + } float rhuemask = 0.f; float rchromask = 0.f; float rLmask = 0.f; float dE = 0.f; + float rsob = 0.f; + if(lp.struexp > 0.f && rs > 0.f && senstype == 1) { + rsob = 1.1f * lp.struexp * (rs); + } + if (usemask) { rhuemask = xatan2f(origblurmask->b[y][x], origblurmask->a[y][x]); rchromask = sqrt(SQR(origblurmask->b[y][x]) + SQR(origblurmask->a[y][x])) / 327.68f; rLmask = origblurmask->L[y][x] / 327.68f; - dE = sqrt(SQR(refa - origblurmask->a[y][x] / 327.68f) + SQR(refb - origblurmask->b[y][x] / 327.68f) + SQR(lumaref - origblurmask->L[y][x] / 327.68f)); + dE = rsob + sqrt(SQR(refa - origblurmask->a[y][x] / 327.68f) + SQR(refb - origblurmask->b[y][x] / 327.68f) + SQR(lumaref - origblurmask->L[y][x] / 327.68f)); } else { - dE = sqrt(SQR(refa - origblur->a[y][x] / 327.68f) + SQR(refb - origblur->b[y][x] / 327.68f) + SQR(lumaref - rL)); + dE = rsob + sqrt(SQR(refa - origblur->a[y][x] / 327.68f) + SQR(refb - origblur->b[y][x] / 327.68f) + SQR(lumaref - rL)); rhuemask = rhue; rchromask = rchro; rLmask = rL; @@ -5646,7 +5670,7 @@ void ImProcFunctions::Expo_vibr_Local(float moddE, float powdE, int senstype, La } -void ImProcFunctions::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, 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 ImProcFunctions::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, float ** blendch, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, LUTf & lightCurveloc, const local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk) { BENCHFUN // chroma and lightness @@ -5699,7 +5723,9 @@ void ImProcFunctions::ColorLight_Local(float moddE, float powdE, int call, LabIm float refb = chromaref * sin(hueref); // const float moddE = 2.f; - + sobelref /= 100.; + if(sobelref > 60.) sobelref = 60.; + sobelref = log(1.f + sobelref); // constant and variables to prepare shape detection if (lumaref + modlum >= 100.f) { modlum = (100.f - lumaref) / 2.f; @@ -5839,17 +5865,27 @@ void ImProcFunctions::ColorLight_Local(float moddE, float powdE, int call, LabIm if (fabs(origblur->b[y][x]) < 0.01f) { origblur->b[y][x] = 0.01f; } + //Sobel + float csob = (blend2[loy - begy][lox - begx])/100.f ; //+ (blendch[loy - begy][lox - begx])/100.f ; + if(csob > 60.f) csob = 60.f; + csob = log(1.f + csob); + float rs = sobelref / csob; + float dE = 0.f; float rhuemask = 0.f; float rchromask = 0.f; float rLmask = 0.f; + float rsob = 0.f; + if(lp.struco > 0.f && rs > 0.f) { + rsob = 1.1f * lp.struco * (rs); + } if (lp.showmaskcolmet >= 2) { rhuemask = xatan2f(origblurmask->b[y][x], origblurmask->a[y][x]); rchromask = sqrt(SQR(origblurmask->b[y][x]) + SQR(origblurmask->a[y][x])) / 327.68f; rLmask = origblurmask->L[y][x] / 327.68f; - dE = sqrt(SQR(refa - origblurmask->a[y][x] / 327.68f) + SQR(refb - origblurmask->b[y][x] / 327.68f) + SQR(lumaref - origblurmask->L[y][x] / 327.68f)); + dE = rsob + sqrt(SQR(refa - origblurmask->a[y][x] / 327.68f) + SQR(refb - origblurmask->b[y][x] / 327.68f) + SQR(lumaref - origblurmask->L[y][x] / 327.68f)); } else { - dE = sqrt(SQR(refa - origblur->a[y][x] / 327.68f) + SQR(refb - origblur->b[y][x] / 327.68f) + SQR(lumaref - rL)); + dE = rsob + sqrt(SQR(refa - origblur->a[y][x] / 327.68f) + SQR(refb - origblur->b[y][x] / 327.68f) + SQR(lumaref - rL)); rhuemask = rhue; rchromask = rchro; rLmask = rL; @@ -7051,7 +7087,7 @@ void ImProcFunctions::InverseColorLight_Local(const struct local_params & lp, LU } -void ImProcFunctions::calc_ref(int sp, LabImage * original, LabImage * transformed, int cx, int cy, int oW, int oH, int sk, double & huerefblur, double & hueref, double & chromaref, double & lumaref, double & sobelref, LUTu & histogram) +void ImProcFunctions::calc_ref(int sp, LabImage * original, LabImage * transformed, float **blend, int cx, int cy, int oW, int oH, int sk, double & huerefblur, double & hueref, double & chromaref, double & lumaref, double & sobelref, LUTu & histogram) { if (params->locallab.enabled) { //always calculate hueref, chromaref, lumaref before others operations use in normal mode for all modules exceprt denoise @@ -7129,6 +7165,7 @@ void ImProcFunctions::calc_ref(int sp, LabImage * original, LabImage * transform spotSise2 = (spotSi - 1) / 2; + JaggedArray blend3(spotSi, spotSi); origsob = new LabImage(spotSi, spotSi); sobelL = new LabImage(spotSi, spotSi); @@ -7183,13 +7220,14 @@ void ImProcFunctions::calc_ref(int sp, LabImage * original, LabImage * transform aveL += original->L[y - cy][x - cx]; aveA += original->a[y - cy][x - cx]; aveB += original->b[y - cy][x - cx]; + // aveblend += 100.f * blend2[y - cy][x - cx]; aveChro += sqrtf(SQR(original->b[y - cy][x - cx]) + SQR(original->a[y - cy][x - cx])); nab++; } } //ref for sobel - bool toto = false; + bool toto = true; if (toto) { for (int y = max(cy, (int)(lp.yc - spotSise2)); y < min(transformed->H + cy, (int)(lp.yc + spotSise2 + 1)); y++) { @@ -7206,19 +7244,19 @@ void ImProcFunctions::calc_ref(int sp, LabImage * original, LabImage * transform } const float radius = 3.f / (sk * 1.4f); //0 to 70 ==> see skip - SobelCannyLuma(sobelL->L, origsob->L, spotSi, spotSi, radius); - // SobelCannyLuma (sobelL, deltasobelL, origsob, spotSi, spotSi, radius ); + SobelCannyLuma(sobelL->L, origsob->L, spotSi, spotSi, radius); int nbs = 0; for (int y = 0; y < spotSi ; y ++) for (int x = 0; x < spotSi ; x ++) { - avesobel += sobelL->L[y][x]; + avesobel += sobelL->L[y][x]; + // avesobel += blend3[y][x]; nbs++; } sobelref = avesobel / nbs; - // printf ("sobelref=%f \n", sobelref); + printf ("sobelref=%f \n", sobelref); } delete sobelL; @@ -7577,7 +7615,7 @@ void ImProcFunctions::fftw_denoise(int GW, int GH, int max_numblox_W, int min_nu -void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbuffer, LabImage * original, LabImage * transformed, LabImage * reserved, int cx, int cy, int oW, int oH, int sk, +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, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, const LocCCmaskCurve & locccmasCurve, const LocLLmaskCurve & locllmasCurve, const LocHHmaskCurve & lochhmasCurve, const LocCCmaskexpCurve & locccmasexpCurve, const LocLLmaskexpCurve & locllmasexpCurve, bool & LHutili, bool & HHutili, LUTf & cclocalcurve, bool & localskutili, LUTf & sklocalcurve, bool & localexutili, LUTf & exlocalcurve, LUTf & hltonecurveloc, LUTf & shtonecurveloc, LUTf & tonecurveloc, LUTf & lightCurveloc, double & huerefblur, double & hueref, double & chromaref, double & lumaref, double & sobelref) { @@ -7781,700 +7819,6 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu } - - bool titi = false; - - if (titi) { //&& call == 3 - -//actually does not work at all, I make different tests ! - - // if (lp.strucc > 0) { - //change coordonate to XX, YY XX=x, YY=-y to can use easily trigo functions and polar coordonates - // xc yc are XX=0 YY=0 - //at the end we convert inverse - // we have 4 quarter for the area bfw * bfh : TOP, LEFT, BOTTOM, RIGHT - //Cdeltae Ldeltae - deltaE Chroma and Luma in area bfw bfh - //Cdeltaesob Ldeltaesob - Sobel transformed of deltaE Chroma and Luma in area bfw bfh - - //retreive coordonate and values of references around current exclude Spot - - //retrieve datas for hueref, sobelref and centerX Y for all spot around - /* - huerefs[sp]; - sobelrefs[sp]; - centerx[sp]; - centery[sp]; - */ - /* - int currentcenterx = centerx[0]; - int currentcentery = centery[0]; - printf("cuX=%i cuY=%i sp=%i\n", currentcenterx, currentcentery, sp); - - for (int i = 1; i < maxspot; i++) { - printf("i=%i hue=%f sob=%f cex=%i cey=%i\n", i, huerefs[i], sobelrefs[i], centerx[i], centery[i]); - - } - */ - - JaggedArray Cdeltae(bfw, bfh); - JaggedArray Cdeltaesob(bfw, bfh); - JaggedArray Ldeltae(bfw, bfh); - JaggedArray Ldeltaesob(bfw, bfh); - - -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int ir = 0; ir < bfh; ir++) //fill with 0 - for (int jr = 0; jr < bfw; jr++) { - Cdeltae[ir][jr] = 0.f; - Ldeltae[ir][jr] = 0.f; - Cdeltaesob[ir][jr] = 0.f; - Ldeltaesob[ir][jr] = 0.f; - } - -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int ir = 0; ir < bfh; ir++) - for (int jr = 0; jr < bfw; jr++) { - float tempc = SQR(bufreserv->a[ir][jr] - bufexclu->a[ir][jr]) + SQR(bufreserv->b[ir][jr] - bufexclu->b[ir][jr]); - float templ = fabs(bufreserv->L[ir][jr] - bufexclu->L[ir][jr]); - Cdeltae[ir][jr] = sqrt(tempc); - Ldeltae[ir][jr] = templ; - } - - - SobelCannyLuma(Cdeltaesob, Cdeltae, bfw, bfh, 0);//0 or other thing eg radiussob if noise... - SobelCannyLuma(Ldeltaesob, Ldeltae, bfw, bfh, 0); - - int Xo = trunc(-lp.lxL); - int Xe = trunc(lp.lx); - int Yo = trunc(-lp.ly); - int Ye = trunc(lp.lyT); - int ar = 1;//to avoid crash due to round values - //init first quarter top - int XR = max(-Xo, Xe); - - //rr maximum radius to stock data - int rr = sqrt(SQR(XR) + SQR(Ye)) + ar; //+ ar to prevent crash due to round float - //polar coord - JaggedArray val(rr, xEn - begx + ar); - JaggedArray CdE(rr, xEn - begx + ar); - JaggedArray LdE(rr, xEn - begx + ar); - JaggedArray CdEsob(rr, xEn - begx + ar); - JaggedArray LdEsob(rr, xEn - begx + ar); - JaggedArray Soderiv(rr, xEn - begx + ar); - JaggedArray Chderiv(rr, xEn - begx + ar); - JaggedArray Luderiv(rr, xEn - begx + ar); - JaggedArray goodmax(rr, xEn - begx + ar); - JaggedArray Soderiv2(rr, xEn - begx + ar); - JaggedArray Chderiv2(rr, xEn - begx + ar); - JaggedArray Luderiv2(rr, xEn - begx + ar); - JaggedArray Totalderiv2(rr, xEn - begx + ar); - - //cDe and LdE to stock delta E chroma and luma in area top and polar coord - //cDesob and LdEsob Sobel canny of delta E chroma and luma - //Chderiv Luderiv derivative of Sobel deltae Chroma Luma - //Soderiv derivative of sobel - - //good max : find the good max value. This value perhaps is max, but perhaps it is after - on the radius - and before the end - - //keep radius On OFF action - float *rad = nullptr; - rad = new float[xEn - begx + ar]; - - float *maxsob = nullptr; - maxsob = new float[xEn - begx + ar]; - float *meanbef = nullptr; - meanbef = new float[xEn - begx + ar]; - float *meanaft = nullptr; - meanaft = new float[xEn - begx + ar]; - - //radlim maximum radius - float *radlim = nullptr; - radlim = new float[xEn - begx + ar]; - - //init second quarter left - int YL = max(-Yo, Ye); - int rrL = sqrt(SQR(YL) + SQR(Xo)) + ar; - - JaggedArray valL(rrL, yEn - begy + ar); - JaggedArray CdEL(rrL, yEn - begy + ar); - JaggedArray LdEL(rrL, yEn - begy + ar); - JaggedArray CdEsobL(rrL, yEn - begy + ar); - JaggedArray LdEsobL(rrL, yEn - begy + ar); - JaggedArray SoderivL(rrL, yEn - begy + ar); - JaggedArray ChderivL(rrL, yEn - begy + ar); - JaggedArray LuderivL(rrL, yEn - begy + ar); - - float *radL = nullptr; - radL = new float[yEn - begy + ar]; - float *radlimL = nullptr; - radlimL = new float[yEn - begy + ar]; - - - //init third quarter bottom - XR = max(-Xo, Xe); - int rrB = sqrt(SQR(XR) + SQR(Yo)) + ar; - - JaggedArray valB(rrB, xEn - begx + ar); - JaggedArray CdEB(rrB, xEn - begx + ar); - JaggedArray LdEB(rrB, xEn - begx + ar); - JaggedArray CdEsobB(rrB, xEn - begx + ar); - JaggedArray LdEsobB(rrB, xEn - begx + ar); - JaggedArray SoderivB(rrB, xEn - begx + ar); - JaggedArray ChderivB(rrB, xEn - begx + ar); - JaggedArray LuderivB(rrB, xEn - begx + ar); - - float *radB = nullptr; - radB = new float[xEn - begx + ar]; - float *radlimB = nullptr; - radlimB = new float[xEn - begx + ar]; - - - //init fourth quarter right - YL = max(-Yo, Ye); - int rrR = sqrt(SQR(YL) + SQR(Xe)) + ar; - JaggedArray valR(rrR, yEn - begy + ar); - JaggedArray CdER(rrR, yEn - begy + ar); - JaggedArray LdER(rrR, yEn - begy + ar); - JaggedArray CdEsobR(rrR, yEn - begy + ar); - JaggedArray LdEsobR(rrR, yEn - begy + ar); - JaggedArray SoderivR(rrR, yEn - begy + ar); - JaggedArray ChderivR(rrR, yEn - begy + ar); - JaggedArray LuderivR(rrR, yEn - begy + ar); - - float *radR = nullptr; - radR = new float[yEn - begy + ar]; - float *radlimR = nullptr; - radlimR = new float[yEn - begy + ar]; - - //printf("huar=%f sob=%f cx=%i\n", huerefs[2], sobelrefs[2], centerx[1]); - - - for (int w = 0; w < (xEn - begx); w++) { - rad[w] = 0.f; - radlim[w] = 0.f; - radB[w] = 0.f; - radlimB[w] = 0.f; - } - - for (int w = 0; w < (xEn - begx); w++) { - for (int z = 0; z < rr; z++) { - val[w][z] = 0.f; - Soderiv[w][z] = 0.f; - Chderiv[w][z] = 0.f; - Luderiv[w][z] = 0.f; - Soderiv2[w][z] = 0.f; - Chderiv2[w][z] = 0.f; - Luderiv2[w][z] = 0.f; - Totalderiv2[w][z] = 0.f; - CdE[w][z] = 0.f; - LdE[w][z] = 0.f; - CdEsob[w][z] = 0.f; - LdEsob[w][z] = 0.f; - goodmax[w][z] = 0.f; - - } - } - - for (int w = 0; w < (xEn - begx); w++) { - for (int z = 0; z < rrB; z++) { - valB[w][z] = 0.f; - SoderivB[w][z] = 0.f; - ChderivB[w][z] = 0.f; - LuderivB[w][z] = 0.f; - CdEB[w][z] = 0.f; - LdEB[w][z] = 0.f; - CdEsobB[w][z] = 0.f; - LdEsobB[w][z] = 0.f; - } - } - - for (int w = 0; w < (yEn - begy); w++) { - for (int z = 0; z < rrL; z++) { - valL[w][z] = 0.f; - SoderivL[w][z] = 0.f; - ChderivL[w][z] = 0.f; - LuderivL[w][z] = 0.f; - CdEL[w][z] = 0.f; - LdEL[w][z] = 0.f; - CdEsobL[w][z] = 0.f; - LdEsobL[w][z] = 0.f; - } - } - - for (int w = 0; w < (yEn - begy); w++) { - for (int z = 0; z < rrR; z++) { - valR[w][z] = 0.f; - SoderivR[w][z] = 0.f; - ChderivR[w][z] = 0.f; - LuderivR[w][z] = 0.f; - CdER[w][z] = 0.f; - LdER[w][z] = 0.f; - CdEsobR[w][z] = 0.f; - LdEsobR[w][z] = 0.f; - } - } - - for (int w = 0; w < (yEn - begy); w++) { - radL[w] = 0.f; - radlimL[w] = 0.f; - radR[w] = 0.f; - radlimR[w] = 0.f; - } - - float sobelponder = 2.f * sobelref; - float2 sincosval; - - if (sobelponder > 25000.f) { - sobelponder = 25000.f; - } - - //first step : fill val[m][r] with Sobel-Canny datas - //Canny with very smal denoise to keep good datas :radiussob # 1 2 3 - float valm = 0.f; - - for (int XX = Xo; XX < Xe; XX++) { //first quarter superior - int m = trunc(XX - Xo); - - if (m < 0) { - m = 0; - } - - radlim[m] = sqrt(SQR(XX) + SQR(Ye)); - - float tetacur = xatan2f(Ye, XX);//we can probably supprres xatan2f and repace by XX / Ye but I keep it in case of - float valedge = 0.f; - // float maxval = -10000.f; - // float minval = 100000.f; - - for (int r = 1; r < radlim[m] - (ar + 2); r++) { - sincosval = xsincosf(tetacur); - float xcur = r * sincosval.y; - float ycur = r * sincosval.x; - - int xxcur = trunc(lp.xc) + trunc(xcur) - begx; - xxcur = LIM (xxcur, 0, bfw - 1); - - int yycur = trunc(lp.yc) - trunc(ycur) - begy; // - before ceil(ycur) to convert YY ==> y - yycur = LIM (yycur, 0, bfh - 1); - valm = tmpsob->L[yycur][xxcur]; - CdEsob[m][r] = Cdeltaesob[yycur][xxcur]; - LdEsob[m][r] = Ldeltaesob[yycur][xxcur]; - LdE[m][r] = Ldeltae[yycur][xxcur]; - CdE[m][r] = Cdeltae[yycur][xxcur]; - - if (valm > valedge) { - // if(m > maxm) maxm = m; - val[m][r] = valm; - - if (XX == 2) { - // printf("XX=%i m=%i r=%i val=%i CdE=%i LdE=%i\n", XX, m, r, (int) val[m][r], (int)CdE[m][r], (int)LdE[m][r]); - } - } - - } - - - } - - valm = 0.f; - - for (int YY = Yo; YY < Ye; YY++) { //second quarter left - int m = ceil(YY - Yo); - - if (m < 0) { - m = 0; - } - - radlimL[m] = sqrt(SQR(YY) + SQR(Xo)); - - float tetacur = xatan2f(YY, Xo); - float valedge = 00.f; - - for (int r = 0; r < radlimL[m] - (ar + 2); r++) { - sincosval = xsincosf(tetacur); - float xcur = r * sincosval.y; - float ycur = r * sincosval.x; - - int xxcur = ceil(lp.xc) + ceil(xcur) - begx; - xxcur = LIM (xxcur, 0, bfw - 1); - - int yycur = ceil(lp.yc) - ceil(ycur) - begy; - yycur = LIM (yycur, 0, bfh - 1); - valm = tmpsob->L[yycur][xxcur]; - CdEsobL[m][r] = Cdeltaesob[yycur][xxcur]; - LdEsobL[m][r] = Ldeltaesob[yycur][xxcur]; - LdEL[m][r] = Ldeltae[yycur][xxcur]; - CdEL[m][r] = Cdeltae[yycur][xxcur]; - - if (valm > valedge) { - valL[m][r] = valm; - - if (YY == 0) { - // printf ("YYL=%i m=%i r=%i val=%i \n", YY, m, r, (int) valL[m][r]); - } - } - } - } - - valm = 0.f; - - for (int XX = Xo; XX < Xe; XX++) { //third quarter bottom - int m = ceil(XX - Xo); - - if (m < 0) { - m = 0; - } - - radlimB[m] = sqrt(SQR(XX) + SQR(Yo)); - - float tetacur = xatan2f(Yo, XX); - float valedge = 0.f; - - for (int r = 0; r < radlimB[m] - (ar + 2); r++) { - sincosval = xsincosf(tetacur); - float xcur = r * sincosval.y; - float ycur = r * sincosval.x; - - int xxcur = ceil(lp.xc) + ceil(xcur) - begx; - xxcur = LIM (xxcur, 0, bfw - 1); - - int yycur = ceil(lp.yc) - ceil(ycur) - begy; // - before ceil(ycur) to convert YY ==> y - yycur = LIM (yycur, 0, bfh - 1); - valm = tmpsob->L[yycur][xxcur]; - CdEsobB[m][r] = Cdeltaesob[yycur][xxcur]; - LdEsobB[m][r] = Ldeltaesob[yycur][xxcur]; - LdEB[m][r] = Ldeltae[yycur][xxcur]; - CdEB[m][r] = Cdeltae[yycur][xxcur]; - - if (valm > valedge) { - // if(m > maxm) maxm = m; - valB[m][r] = valm; - - if (XX == 0) { - // printf ("XXB=%i m=%i r=%i val=%i \n", XX, m, r, (int) valB[m][r]); - } - } - } - } - - valm = 0.f; - - for (int YY = Yo; YY < Ye; YY++) { //fourth quarter right - int m = ceil(YY - Yo); - - if (m < 0) { - m = 0; - } - - radlimR[m] = sqrt(SQR(YY) + SQR(Xe)); - - float tetacur = xatan2f(YY, Xe); - float valedge = 00.f; - - for (int r = 0; r < radlimR[m] - (ar + 2); r++) { - sincosval = xsincosf(tetacur); - float xcur = r * sincosval.y; - float ycur = r * sincosval.x; - - int xxcur = ceil(lp.xc) + ceil(xcur) - begx; - xxcur = LIM (xxcur, 0, bfw - 1); - - int yycur = ceil(lp.yc) - ceil(ycur) - begy; - yycur = LIM (yycur, 0, bfh - 1); - valm = tmpsob->L[yycur][xxcur]; - CdEsobR[m][r] = Cdeltaesob[yycur][xxcur]; - LdEsobR[m][r] = Ldeltaesob[yycur][xxcur]; - LdER[m][r] = Ldeltae[yycur][xxcur]; - CdER[m][r] = Cdeltae[yycur][xxcur]; - - if (valm > valedge) { - valR[m][r] = valm; - - if (YY == 0) { - // printf ("YYR=%i m=%i r=%i val=%i \n", YY, m, r, (int) valR[m][r]); - } - } - } - } - - - - //second step : moving average to forgot isolate datas - // it seems that most of edge are among 3 or 4 pixels - // average convolution on 3 datas (only 'r' !) - // derivative function - for (int XX = Xo; XX < Xe; XX++) { //first quarter superior - int m = trunc(XX - Xo); - - if (m < 0) { - m = 0; - } - - float maxval = -10000.f; - int rmax = 0; - float maxso = -10000.f; - // int rmaxso = 0; - float maxch = -10000.f; - // int rmaxch = 0; - int rma = 0; - - //average convolution and first max - for (int r = 1; r < radlim[m] - (ar + 3); r++) { - val[m][r] = 0.333f * (val[m][r - 1] + val[m][r] + val[m][r + 1]); - CdE[m][r] = 0.333f * (CdE[m][r - 1] + CdE[m][r] + CdE[m][r + 1]); - LdE[m][r] = 0.333f * (LdE[m][r - 1] + LdE[m][r] + LdE[m][r + 1]); - CdEsob[m][r] = 0.333f * (CdEsob[m][r - 1] + CdEsob[m][r] + CdEsob[m][r + 1]); - LdEsob[m][r] = 0.333f * (LdEsob[m][r - 1] + LdEsob[m][r] + LdEsob[m][r + 1]); - - if (val[m][r] > maxval) { - maxval = val[m][r]; - rmax = r; - } - } - - maxsob[m] = maxval; - - float meanbe = 0.f; - float meanaf = 0.f; - int nbbef = 0; - int nbaft = 0; - - for (int r = 2; r < radlim[m] - (ar + 4); r++) { - if (r < rmax - 1) { - meanbe += val[m][r]; - nbbef ++; - } - - if (r > rmax + 1) { - meanaf += val[m][r]; - nbaft ++; - } - - if (val[m][r] < 0.4f * sobelrefs[1]) { // TODO Locallab Correct ? - rma = r; - break; - } - } - - rad[m] = rma; - - meanbe /= nbbef; - meanaf /= nbaft; - meanbef[m] = meanbe; - meanaft[m] = meanaf; - - if (XX == 0) { - - printf(" maxsob=%i ram=%i meanbef=%i meanaft=%i\n", (int) maxsob[m], rmax, (int) meanbef[m], (int) meanaft[m]); - } - - //derivative function on 2 values - for (int r = 2; r < radlim[m] - (ar + 6); r++) { - Soderiv[m][r] = (val[m][r] - val[m][r + 2]); - Chderiv[m][r] = (CdEsob[m][r] - CdEsob[m][r + 2]); - Luderiv[m][r] = (LdEsob[m][r] - LdEsob[m][r + 2]); - - if (XX == 0) { - - // printf("X=%i m=%i r=%i So=%i Chd=%i Ld=%i Sdri=%i Csodri=%i Lsodri=%i\n", XX, m, r, (int) val[m][r], (int)CdE[m][r], (int)LdE[m][r], (int) Soderiv[m][r], (int) Chderiv[m][r], (int) Luderiv[m][r]); - } - - // if(val[m][r] < 1.5f* sobelrefs[1]) rad[m] = r; - } - - //pseudo second derivative - //find maxi of derivative and also change sign - for (int r = 2; r < radlim[m] - (ar + 6); r++) { - if (r + 4 < radlim[m] - (ar + 6)) { - if (signbit(Chderiv[m][r]) + signbit(Chderiv[m][r + 4]) == 1) { //one is positive and one is negative - Chderiv2[m][r] = fabs(Chderiv[m][r] - Chderiv[m][r + 4]); - } - - if (signbit(Soderiv[m][r]) + signbit(Soderiv[m][r + 4]) == 1) { //one is positive and one is negative - Soderiv2[m][r] = fabs(Soderiv[m][r] - Soderiv[m][r + 4]); - } - - if (signbit(Luderiv[m][r]) + signbit(Luderiv[m][r + 4]) == 1) { //one is positive and one is negative - Luderiv2[m][r] = fabs(Luderiv[m][r] - Luderiv[m][r + 4]); - } - - Totalderiv2[m][r] = Luderiv2[m][r] + Chderiv2[m][r] + Soderiv2[m][r]; - - if (Chderiv2[m][r] > maxch) { - maxch = Chderiv2[m][r]; - // rmaxch = r; - } - - - if (Soderiv2[m][r] > maxso) { - maxso = Soderiv2[m][r]; - // rmaxso = r; - } - - } - - if (XX == 0) { - - // printf("X=%i m=%i r=%i So=%i Chd=%i Ld=%i Sdri2=%i Cdri2=%i Ldri2=%i To=%i\n", XX, m, r, (int) val[m][r], (int)CdE[m][r], (int)LdE[m][r], (int) Soderiv2[m][r], (int) Chderiv2[m][r], (int) Luderiv2[m][r], (int) Totalderiv2[m][r]); - } - - - } - - //we must now calculate rad[m] in function of others criterail - // rad[m] = rmaxch; - // if(val[m][r] < 1.5f* sobelrefs[1]) rad[m] = r; - - - } - - for (int YY = Yo; YY < Ye; YY++) { //second quarter left - int m = ceil(YY - Yo); - - if (m < 0) { - m = 0; - } - - //average convolution and first max - for (int r = 1; r < radlimL[m] - (ar + 3); r++) { - valL[m][r] = 0.333f * (valL[m][r - 1] + valL[m][r] + valL[m][r + 1]); - CdEL[m][r] = 0.333f * (CdEL[m][r - 1] + CdEL[m][r] + CdEL[m][r + 1]); - LdEL[m][r] = 0.333f * (LdEL[m][r - 1] + LdEL[m][r] + LdEL[m][r + 1]); - CdEsobL[m][r] = 0.333f * (CdEsobL[m][r - 1] + CdEsobL[m][r] + CdEsobL[m][r + 1]); - LdEsobL[m][r] = 0.333f * (LdEsobL[m][r - 1] + LdEsobL[m][r] + LdEsobL[m][r + 1]); - } - - //derivative function on 2 values - for (int r = 2; r < radlimL[m] - (ar + 6); r++) { - SoderivL[m][r] = (valL[m][r] - valL[m][r + 2]); - ChderivL[m][r] = (CdEsobL[m][r] - CdEsobL[m][r + 2]); - LuderivL[m][r] = (LdEsobL[m][r] - LdEsobL[m][r + 2]); - - if (YY == 0) { - - // printf("Y=%i m=%i r=%i So=%i Chd=%i Ld=%i Sdri=%i Csodri=%i Lsodri=%i\n", YY, m, r, (int) valL[m][r], (int)CdEL[m][r], (int)LdEL[m][r], (int) SoderivL[m][r], (int) ChderivL[m][r], (int) LuderivL[m][r]); - } - } - } - - - for (int XX = Xo; XX < Xe; XX++) { //third quarter inf - int m = trunc(XX - Xo); - - if (m < 0) { - m = 0; - } - - //average convolution and first max - for (int r = 1; r < radlimB[m] - (ar + 3); r++) { - valB[m][r] = 0.333f * (valB[m][r - 1] + valB[m][r] + valB[m][r + 1]); - CdEB[m][r] = 0.333f * (CdEB[m][r - 1] + CdEB[m][r] + CdEB[m][r + 1]); - LdEB[m][r] = 0.333f * (LdEB[m][r - 1] + LdEB[m][r] + LdEB[m][r + 1]); - CdEsobB[m][r] = 0.333f * (CdEsobB[m][r - 1] + CdEsobB[m][r] + CdEsobB[m][r + 1]); - LdEsobB[m][r] = 0.333f * (LdEsobB[m][r - 1] + LdEsobB[m][r] + LdEsobB[m][r + 1]); - } - - //derivative function on 2 values - for (int r = 2; r < radlimB[m] - (ar + 6); r++) { - SoderivB[m][r] = (valB[m][r] - valB[m][r + 2]); - ChderivB[m][r] = (CdEsobB[m][r] - CdEsobB[m][r + 2]); - LuderivB[m][r] = (LdEsobB[m][r] - LdEsobB[m][r + 2]); - - if (XX == Xe / 2) { - - // printf("X=%i m=%i r=%i So=%i Chd=%i Ld=%i Sdri=%i Csodri=%i Lsodri=%i\n", XX, m, r, (int) valB[m][r], (int)CdEB[m][r], (int)LdEB[m][r], (int) SoderivB[m][r], (int) ChderivB[m][r], (int) LuderivB[m][r]); - } - } - } - - for (int YY = Yo; YY < Ye; YY++) { //second quarter left - int m = ceil(YY - Yo); - - if (m < 0) { - m = 0; - } - - //average convolution and first max - for (int r = 1; r < radlimR[m] - (ar + 3); r++) { - valR[m][r] = 0.333f * (valR[m][r - 1] + valR[m][r] + valR[m][r + 1]); - CdER[m][r] = 0.333f * (CdER[m][r - 1] + CdER[m][r] + CdER[m][r + 1]); - LdER[m][r] = 0.333f * (LdER[m][r - 1] + LdER[m][r] + LdER[m][r + 1]); - CdEsobR[m][r] = 0.333f * (CdEsobR[m][r - 1] + CdEsobR[m][r] + CdEsobR[m][r + 1]); - LdEsobR[m][r] = 0.333f * (LdEsobR[m][r - 1] + LdEsobR[m][r] + LdEsobR[m][r + 1]); - } - - //derivative function on 2 values - for (int r = 2; r < radlimR[m] - (ar + 6); r++) { - SoderivR[m][r] = (valR[m][r] - valR[m][r + 2]); - ChderivR[m][r] = (CdEsobR[m][r] - CdEsobR[m][r + 2]); - LuderivR[m][r] = (LdEsobR[m][r] - LdEsobR[m][r + 2]); - - if (YY == 0) { - - //printf("Y=%i m=%i r=%i So=%i Chd=%i Ld=%i Sdri=%i Csodri=%i Lsodri=%i\n", YY, m, r, (int) valR[m][r], (int)CdER[m][r], (int)LdER[m][r], (int) SoderivR[m][r], (int) ChderivR[m][r], (int) LuderivR[m][r]); - } - } - } - - //real algo to find good radius - - - // put good values in delatasobelL - for (int XX = Xo; XX < Xe; XX++) { //first quarter superior - int m = trunc(XX - Xo); - - if (m < 0) { - m = 0; - } - - radlim[m] = sqrt(SQR(XX) + SQR(Ye)); - - float tetacur = xatan2f(Ye, XX); - // float valedge = 0.f; - - for (int r = 0; r < radlim[m] - (ar + 2); r++) { - sincosval = xsincosf(tetacur); - float xcur = r * sincosval.y; - float ycur = r * sincosval.x; - - int xxcur = trunc(lp.xc) + trunc(xcur) - begx; - xxcur = LIM (xxcur, 0, bfw - 1); - - int yycur = trunc(lp.yc) - trunc(ycur) - begy; // - before ceil(ycur) to convert YY ==> y - yycur = LIM (yycur, 0, bfh - 1); - - if (r > rad[m]) { - deltasobelL->L[yycur][xxcur] = 0.f; - } - - } - } - - delete[] radlimR; - delete[] radR; - - delete[] radlimB; - delete[] radB; - - delete[] radlimL; - delete[] radL; - - delete[] radlim; - delete[] rad; - delete[] maxsob; - delete[] meanaft; - delete[] meanbef; - - - - } - //then restore non modified area //TODO then use instead of others modifications Color and Light, Blur, etc. @@ -9988,7 +9332,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu } } - Expo_vibr_Local(moddE, powdE, 2, nullptr, buflight, bufl_ab, nullptr, nullptr, hueplus, huemoins, hueref, dhuev, chromaref, lumaref, lp, original, transformed, difLab, bufexpfin, cx, cy, sk); + Expo_vibr_Local(moddE, powdE, 2, nullptr, buflight, bufl_ab, nullptr, nullptr, hueplus, huemoins, hueref, dhuev, chromaref, lumaref, sobelref, nullptr, lp, original, transformed, difLab, bufexpfin, cx, cy, sk); //call Expo_vibr_Local with first parameter = 2 for vibrance } @@ -10361,7 +9705,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu } } - Expo_vibr_Local(moddE, powdE, 3, nullptr, buflight, bufl_ab, nullptr, nullptr, hueplus, huemoins, hueref, dhuesf, chromaref, lumaref, lp, original, transformed, difLab, bufexpfin, cx, cy, sk); + Expo_vibr_Local(moddE, powdE, 3, nullptr, buflight, bufl_ab, nullptr, nullptr, hueplus, huemoins, hueref, dhuesf, chromaref, lumaref, sobelref, nullptr, lp, original, transformed, difLab, bufexpfin, cx, cy, sk); } @@ -10802,6 +10146,9 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu JaggedArray buflightslid(bfw, bfh); JaggedArray bufchroslid(bfw, bfh); JaggedArray bufhh(bfw, bfh); + JaggedArray blend2(bfw, bfh); + JaggedArray blendch(bfw, bfh); + JaggedArray buforigchro(bfw, bfh); float adjustr = 1.0f; @@ -10850,7 +10197,81 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu int begx = lp.xc - lp.lxL; int yEn = lp.yc + lp.ly; int xEn = lp.xc + lp.lx; + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + for (int y = 0; y < transformed->H ; y++) //{ + for (int x = 0; x < transformed->W; x++) { + int lox = cx + x; + int loy = cy + y; + if (lox >= begx && lox < xEn && loy >= begy && loy < yEn) { + bufcolorig->L[loy - begy][lox - begx] = original->L[y][x]; + // buforigchro[loy - begy][lox - begx] = sqrt(SQR(original->a[y][x]) + SQR(original->b[y][x])); + } + } + + const float radius = 3.f / (sk * 1.4f); + int spotSi = 1 + 2 * max(1, lp.cir / sk); + if (spotSi < 5) { + spotSi = 5; + } + + if(bfw > 2* spotSi && bfh > 2* spotSi && lp.struco > 0.f) { + SobelCannyLuma(blend2,bufcolorig->L , bfw, bfh, radius); + // SobelCannyLuma(blendch, buforigchro , bfw, bfh, radius); + array2D ble(bfw, bfh); + array2D blec(bfw, bfh); + array2D guid(bfw, bfh); +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int ir = 0; ir < bfh; ir++) + for (int jr = 0; jr < bfw; jr++) { + ble[ir][jr] = blend2[ir][jr] / 32768.f; + // blec[ir][jr] = blendch[ir][jr] / 32768.f; + guid[ir][jr] = bufcolorig->L[ir][jr] / 32768.f; + } + float blur = 25 / sk * (10.f + 1.2f * lp.struco); + printf("Blur=%f \n", blur); + + rtengine::guidedFilter(guid, ble, ble, blur, 0.001, multiThread); + // rtengine::guidedFilter(guid, blec, blec, blur, 0.001, multiThread); + +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int ir = 0; ir < bfh; ir++) + for (int jr = 0; jr < bfw; jr++) { + blend2[ir][jr] = ble[ir][jr] * 32768.f; + // blendch[ir][jr] = ble[ir][jr] * 32768.f; + } + + bool execmedian = true; + int passes = 1; + if (execmedian) + { + float** tmL; + int wid = bfw; + int hei = bfh; + tmL = new float*[hei]; + for (int i = 0; i < hei; ++i) { + tmL[i] = new float[wid]; + } + Median medianTypeL = Median::TYPE_3X3_STRONG; + Median_Denoise(blend2, blend2, wid, hei, medianTypeL, passes, multiThread, tmL); + // Median_Denoise(blendch, blendch, wid, hei, medianTypeL, 1, multiThread, tmL); + + for (int i = 0; i < hei; ++i) { + delete[] tmL[i]; + } + delete[] tmL; + } + + + } + #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif @@ -10884,6 +10305,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu float kmaskHb = 0; if (lp.showmaskcolmet >= 2) { + if (locllmasCurve) { valLL = (float)(locllmasCurve[500.f * (bufcolorig->L[loy - begy][lox - begx]) / 32768.f]); valLL = 1.f - valLL; @@ -10922,6 +10344,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu bufmaskblur->a[loy - begy][lox - begx] = kmaskCa + kmaskHa; bufmaskblur->b[loy - begy][lox - begx] = kmaskCb + kmaskHb; + } } } @@ -11117,7 +10540,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu } } - ColorLight_Local(moddE, powdE, call, bufcolorig, originalmask, buflight, bufchro, bufchroslid, bufhh, buflightslid, LHutili, HHutili, hueplus, huemoins, hueref, dhue, chromaref, lumaref, lllocalcurve, loclhCurve, lochhCurve, lightCurveloc, lp, original, transformed, cx, cy, sk); + ColorLight_Local(moddE, powdE, call, bufcolorig, originalmask, buflight, bufchro, bufchroslid, bufhh, buflightslid, LHutili, HHutili, hueplus, huemoins, hueref, dhue, chromaref, lumaref, sobelref, blend2, blendch, lllocalcurve, loclhCurve, lochhCurve, lightCurveloc, lp, original, transformed, cx, cy, sk); if (call <= 3) { @@ -11179,6 +10602,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu JaggedArray buflightcurv(bfw, bfh); JaggedArray buf_a_cat(bfw, bfh, true); JaggedArray buf_b_cat(bfw, bfh, true); + JaggedArray blend2(bfw, bfh); if (call <= 3) { //simpleprocess, dcrop, improccoordinator @@ -11225,8 +10649,74 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu int begx = lp.xc - lp.lxL; int yEn = lp.yc + lp.ly; int xEn = lp.xc + lp.lx; - - + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + for (int y = 0; y < transformed->H ; y++) //{ + for (int x = 0; x < transformed->W; x++) { + int lox = cx + x; + int loy = cy + y; + + if (lox >= begx && lox < xEn && loy >= begy && loy < yEn) { + bufexporig->L[loy - begy][lox - begx] = original->L[y][x]; + } + } + + const float radius = 3.f / (sk * 1.4f); + int spotSi = 1 + 2 * max(1, lp.cir / sk); + if (spotSi < 5) { + spotSi = 5; + } + + if(bfw > 2* spotSi && bfh > 2* spotSi && lp.struexp > 0.f) { + SobelCannyLuma(blend2,bufexporig->L , bfw, bfh, radius); + array2D ble(bfw, bfh); + array2D guid(bfw, bfh); +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int ir = 0; ir < bfh; ir++) + for (int jr = 0; jr < bfw; jr++) { + ble[ir][jr] = blend2[ir][jr] / 32768.f; + guid[ir][jr] = bufexporig->L[ir][jr] / 32768.f; + } + float blur = 25 / sk * (10.f + 1.2f * lp.struexp); + printf("Blur=%f \n", blur); + + rtengine::guidedFilter(guid, ble, ble, blur, 0.001, multiThread); + +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int ir = 0; ir < bfh; ir++) + for (int jr = 0; jr < bfw; jr++) { + blend2[ir][jr] = ble[ir][jr] * 32768.f; + } + + bool execmedian = true; + int passes = 1; + if (execmedian) + { + float** tmL; + int wid = bfw; + int hei = bfh; + tmL = new float*[hei]; + for (int i = 0; i < hei; ++i) { + tmL[i] = new float[wid]; + } + Median medianTypeL = Median::TYPE_3X3_STRONG; + Median_Denoise(blend2, blend2, wid, hei, medianTypeL, passes, multiThread, tmL); + + for (int i = 0; i < hei; ++i) { + delete[] tmL[i]; + } + delete[] tmL; + } + + + } + #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) @@ -11461,7 +10951,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, LUTf & sobelrefs, float** shbu } } } - Expo_vibr_Local(moddE, powdE, 1, originalmask, buflight, bufl_ab, buf_a_cat, buf_b_cat, hueplus, huemoins, hueref, dhueex, chromaref, lumaref, lp, original, transformed, difLab, bufcat02fin, cx, cy, sk); + Expo_vibr_Local(moddE, powdE, 1, originalmask, buflight, bufl_ab, buf_a_cat, buf_b_cat, hueplus, huemoins, hueref, dhueex, chromaref, lumaref, sobelref, blend2, lp, original, transformed, difLab, bufcat02fin, cx, cy, sk); //view mask } diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 98299dbfd..2df20710d 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -638,6 +638,8 @@ enum ProcEventCode { EvlocallabCCmaskexpshape = 608, EvlocallabLLmaskexpshape = 609, EvlocallabHHmaskshape = 610, + Evlocallabstructcol = 611, + Evlocallabstructexp = 612, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 2a5715401..1aaee5735 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2362,6 +2362,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : contrast(0), chroma(0), sensi(19), + structcol(0), qualitycurveMethod("none"), showmaskcolMethod("none"), llcurve{(double)DCT_NURBS, 0.0, 0.0, 1.0, 1.0}, @@ -2375,12 +2376,13 @@ LocallabParams::LocallabSpot::LocallabSpot() : // Exposure expexpose(false), expcomp(0), - hlcompr(20), + hlcompr(60), hlcomprthresh(33), black(0), shcompr(50), warm(0), sensiex(19), + structexp(0), excurve{(double)DCT_NURBS, 0.0, 0.0, 1.0, 1.0}, showmaskexpMethod("none"), CCmaskexpcurve{(double)FCT_MinMaxCPoints, 0., 1., 0.35, 0.35, 1., 1., 0.35, 0.35}, @@ -2498,6 +2500,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && contrast == other.contrast && chroma == other.chroma && sensi == other.sensi + && structcol == other.structcol && qualitycurveMethod == other.qualitycurveMethod && showmaskcolMethod == other.showmaskcolMethod && llcurve == other.llcurve @@ -2517,6 +2520,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && shcompr == other.shcompr && warm == other.warm && sensiex == other.sensiex + && structexp == other.structexp && excurve == other.excurve && showmaskexpMethod == other.showmaskexpMethod && CCmaskexpcurve == other.CCmaskexpcurve @@ -3586,6 +3590,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->locallab.spots.at(i).contrast, "Locallab", "Contrast_" + std::to_string(i), spot.contrast, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).chroma, "Locallab", "Chroma_" + std::to_string(i), spot.chroma, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).sensi, "Locallab", "Sensi_" + std::to_string(i), spot.sensi, keyFile); + saveToKeyfile(!pedited || pedited->locallab.spots.at(i).structcol, "Locallab", "Structcol_" + std::to_string(i), spot.structcol, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).qualitycurveMethod, "Locallab", "QualityCurveMethod_" + std::to_string(i), spot.qualitycurveMethod, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).showmaskcolMethod, "Locallab", "ShowmaskcolMethod_" + std::to_string(i), spot.showmaskcolMethod, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).llcurve, "Locallab", "LLCurve_" + std::to_string(i), spot.llcurve, keyFile); @@ -3605,6 +3610,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->locallab.spots.at(i).shcompr, "Locallab", "Shcompr_" + std::to_string(i), spot.shcompr, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).warm, "Locallab", "Warm_" + std::to_string(i), spot.warm, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).sensiex, "Locallab", "Sensiex_" + std::to_string(i), spot.sensiex, keyFile); + saveToKeyfile(!pedited || pedited->locallab.spots.at(i).structexp, "Locallab", "Structexp_" + std::to_string(i), spot.structexp, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).excurve, "Locallab", "ExCurve_" + std::to_string(i), spot.excurve, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).showmaskexpMethod, "Locallab", "ShowmaskexpMethod_" + std::to_string(i), spot.showmaskexpMethod, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).CCmaskexpcurve, "Locallab", "CCmaskexpCurve_" + std::to_string(i), spot.CCmaskexpcurve, keyFile); @@ -4801,6 +4807,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Contrast_" + std::to_string(i), pedited, spot.contrast, spotEdited.contrast); assignFromKeyfile(keyFile, "Locallab", "Chroma_" + std::to_string(i), pedited, spot.chroma, spotEdited.chroma); assignFromKeyfile(keyFile, "Locallab", "Sensi_" + std::to_string(i), pedited, spot.sensi, spotEdited.sensi); + assignFromKeyfile(keyFile, "Locallab", "Structcol_" + std::to_string(i), pedited, spot.structcol, spotEdited.structcol); assignFromKeyfile(keyFile, "Locallab", "QualityCurveMethod_" + std::to_string(i), pedited, spot.qualitycurveMethod, spotEdited.qualitycurveMethod); assignFromKeyfile(keyFile, "Locallab", "ShowmaskcolMethod_" + std::to_string(i), pedited, spot.showmaskcolMethod, spotEdited.showmaskcolMethod); assignFromKeyfile(keyFile, "Locallab", "LLCurve_" + std::to_string(i), pedited, spot.llcurve, spotEdited.llcurve); @@ -4820,6 +4827,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Shcompr_" + std::to_string(i), pedited, spot.shcompr, spotEdited.shcompr); assignFromKeyfile(keyFile, "Locallab", "Warm_" + std::to_string(i), pedited, spot.warm, spotEdited.warm); assignFromKeyfile(keyFile, "Locallab", "Sensiex_" + std::to_string(i), pedited, spot.sensiex, spotEdited.sensiex); + assignFromKeyfile(keyFile, "Locallab", "Structexp_" + std::to_string(i), pedited, spot.structexp, spotEdited.structexp); assignFromKeyfile(keyFile, "Locallab", "ExCurve_" + std::to_string(i), pedited, spot.excurve, spotEdited.excurve); assignFromKeyfile(keyFile, "Locallab", "ShowmaskexpMethod_" + std::to_string(i), pedited, spot.showmaskexpMethod, spotEdited.showmaskexpMethod); assignFromKeyfile(keyFile, "Locallab", "CCmaskexpCurve_" + std::to_string(i), pedited, spot.CCmaskexpcurve, spotEdited.CCmaskexpcurve); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index bf8d32af9..b0444edb1 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -959,6 +959,7 @@ struct LocallabParams { int contrast; int chroma; int sensi; + int structcol; Glib::ustring qualitycurveMethod; Glib::ustring showmaskcolMethod; std::vector llcurve; @@ -978,6 +979,7 @@ struct LocallabParams { int shcompr; int warm; int sensiex; + int structexp; std::vector excurve; Glib::ustring showmaskexpMethod; std::vector CCmaskexpcurve; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 089533f53..d4c0cbdf3 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -637,7 +637,9 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, //EvlocallabLLmaskshape LUMINANCECURVE, //EvlocallabCCmaskexpshape LUMINANCECURVE, //EvlocallabLLmaskexpshape - LUMINANCECURVE //EvlocallabHHmaskshape + LUMINANCECURVE, //EvlocallabHHmaskshape + LUMINANCECURVE, //Evlocallabstructcol + LUMINANCECURVE //Evlocallabstructexp }; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 183c995c5..3271ebe48 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -32,6 +32,7 @@ #include #include #include +#include "jaggedarray.h" #undef THREAD_PRIORITY_NORMAL @@ -1091,6 +1092,7 @@ private: // int maxspot = 1; float** shbuffer = nullptr; + JaggedArray blend(fw, fh); for (int sp = 0; sp < params.locallab.nbspot && sp < (int)params.locallab.spots.size(); sp++) { if (params.locallab.spots.at(sp).inverssha) { @@ -1133,15 +1135,15 @@ private: double huere, chromare, lumare, huerefblu, sobelre; if (params.locallab.spots.at(sp).spotMethod == "exc") { - ipf.calc_ref(sp, reservView, reservView, 0, 0, fw, fh, 1, huerefblu, huere, chromare, lumare, sobelre, lhist16loc); + ipf.calc_ref(sp, reservView, reservView, blend, 0, 0, fw, fh, 1, huerefblu, huere, chromare, lumare, sobelre, lhist16loc); } else { - ipf.calc_ref(sp, labView, labView, 0, 0, fw, fh, 1, huerefblu, huere, chromare, lumare, sobelre, lhist16loc); + ipf.calc_ref(sp, labView, labView, blend, 0, 0, fw, fh, 1, huerefblu, huere, chromare, lumare, sobelre, lhist16loc); } CurveFactory::complexCurvelocal(ecomp, black / 65535., hlcompr, hlcomprthresh, shcompr, br, cont, lhist16loc, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, 1); - ipf.Lab_Local(2, sp, sobelrefs, (float**)shbuffer, labView, labView, reservView, 0, 0, fw, fh, 1, locRETgainCurve, lllocalcurve, loclhCurve, lochhCurve, locccmasCurve, locllmasCurve, lochhmasCurve, locccmasexpCurve, locllmasexpCurve, + ipf.Lab_Local(2, sp, (float**)shbuffer, labView, labView, reservView, 0, 0, fw, fh, 1, locRETgainCurve, lllocalcurve, loclhCurve, lochhCurve, locccmasCurve, locllmasCurve, lochhmasCurve, locccmasexpCurve, locllmasexpCurve, LHutili, HHutili, cclocalcurve, localskutili, sklocalcurve, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerefblu, huere, chromare, lumare, sobelre); // Clear local curves diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 055ed98e7..d4c5ffc18 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -76,6 +76,7 @@ Locallab::Locallab(): contrast(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CONTRAST"), -100, 100, 1, 0))), chroma(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CHROMA"), -100, 150, 1, 0))), sensi(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 19))), + structcol(Gtk::manage(new Adjuster(M("TP_LOCALLAB_STRUCCOL"), 0, 100, 1, 0))), // Exposure expcomp(Gtk::manage(new Adjuster(M("TP_EXPOSURE_EXPCOMP"), -200, 200, 5, 0))), hlcompr(Gtk::manage(new Adjuster(M("TP_EXPOSURE_COMPRHIGHLIGHTS"), 0, 500, 1, 60))), @@ -84,6 +85,7 @@ Locallab::Locallab(): shcompr(Gtk::manage(new Adjuster(M("TP_EXPOSURE_COMPRSHADOWS"), 0, 100, 1, 50))), warm(Gtk::manage(new Adjuster(M("TP_LOCALLAB_WARM"), -100., 100., 1., 0., Gtk::manage(new RTImage("circle-blue-small.png")), Gtk::manage(new RTImage("circle-orange-small.png"))))), sensiex(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 19))), + structexp(Gtk::manage(new Adjuster(M("TP_LOCALLAB_STRUCCOL"), 0, 100, 1, 0))), // Vibrance saturated(Gtk::manage(new Adjuster(M("TP_VIBRANCE_SATURATED"), -100., 100., 1., 0.))), pastels(Gtk::manage(new Adjuster(M("TP_VIBRANCE_PASTELS"), -100., 100., 1., 0.))), @@ -214,6 +216,7 @@ Locallab::Locallab(): sensi->set_tooltip_text(M("TP_LOCALLAB_SENSI_TOOLTIP")); sensi->setAdjusterListener(this); + structcol->setAdjusterListener(this); qualitycurveMethod->append(M("TP_LOCALLAB_CURVNONE")); qualitycurveMethod->append(M("TP_LOCALLAB_CURVCURR")); @@ -328,6 +331,7 @@ Locallab::Locallab(): superFrame->add(*superBox); colorBox->pack_start(*superFrame); colorBox->pack_start(*sensi); + colorBox->pack_start(*structcol); Gtk::HBox* const qualcurvbox = Gtk::manage(new Gtk::HBox()); qualcurvbox->pack_start(*labqualcurv, Gtk::PACK_SHRINK, 4); qualcurvbox->pack_start(*qualitycurveMethod); @@ -368,6 +372,7 @@ Locallab::Locallab(): sensiex->set_tooltip_text(M("TP_LOCALLAB_SENSI_TOOLTIP")); sensiex->setAdjusterListener(this); + structexp->setAdjusterListener(this); curveEditorG->setCurveListener(this); @@ -426,6 +431,7 @@ Locallab::Locallab(): exposeBox->pack_start(*shcompr); exposeBox->pack_start(*warm); exposeBox->pack_start(*sensiex); + exposeBox->pack_start(*structexp); exposeBox->pack_start(*curveEditorG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor exposeBox->pack_start(*maskexpFrame); @@ -1475,6 +1481,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pp->locallab.spots.at(pp->locallab.selspot).contrast = contrast->getIntValue(); pp->locallab.spots.at(pp->locallab.selspot).chroma = chroma->getIntValue(); pp->locallab.spots.at(pp->locallab.selspot).sensi = sensi->getIntValue(); + pp->locallab.spots.at(pp->locallab.selspot).structcol = structcol->getIntValue(); if (qualitycurveMethod->get_active_row_number() == 0) { pp->locallab.spots.at(pp->locallab.selspot).qualitycurveMethod = "none"; @@ -1504,6 +1511,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pp->locallab.spots.at(pp->locallab.selspot).LLmaskcurve = LLmaskshape->getCurve(); pp->locallab.spots.at(pp->locallab.selspot).HHmaskcurve = HHmaskshape->getCurve(); pp->locallab.spots.at(pp->locallab.selspot).invers = invers->get_active(); + pp->locallab.spots.at(pp->locallab.selspot).structexp = structexp->getIntValue(); // Exposure pp->locallab.spots.at(pp->locallab.selspot).expexpose = expexpose->getEnabled(); pp->locallab.spots.at(pp->locallab.selspot).expcomp = expcomp->getIntValue(); @@ -1658,6 +1666,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pe->locallab.spots.at(pp->locallab.selspot).contrast = pe->locallab.spots.at(pp->locallab.selspot).contrast || contrast->getEditedState(); pe->locallab.spots.at(pp->locallab.selspot).chroma = pe->locallab.spots.at(pp->locallab.selspot).chroma || chroma->getEditedState(); pe->locallab.spots.at(pp->locallab.selspot).sensi = pe->locallab.spots.at(pp->locallab.selspot).sensi || sensi->getEditedState(); + pe->locallab.spots.at(pp->locallab.selspot).structcol = pe->locallab.spots.at(pp->locallab.selspot).structcol || structcol->getEditedState(); pe->locallab.spots.at(pp->locallab.selspot).qualitycurveMethod = pe->locallab.spots.at(pp->locallab.selspot).qualitycurveMethod || qualitycurveMethod->get_active_text() != M("GENERAL_UNCHANGED"); pe->locallab.spots.at(pp->locallab.selspot).showmaskcolMethod = pe->locallab.spots.at(pp->locallab.selspot).showmaskcolMethod || showmaskcolMethod->get_active_text() != M("GENERAL_UNCHANGED"); pe->locallab.spots.at(pp->locallab.selspot).llcurve = pe->locallab.spots.at(pp->locallab.selspot).llcurve || !llshape->isUnChanged(); @@ -1677,6 +1686,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pe->locallab.spots.at(pp->locallab.selspot).shcompr = pe->locallab.spots.at(pp->locallab.selspot).shcompr || shcompr->getEditedState(); pe->locallab.spots.at(pp->locallab.selspot).warm = pe->locallab.spots.at(pp->locallab.selspot).warm || warm->getEditedState(); pe->locallab.spots.at(pp->locallab.selspot).sensiex = pe->locallab.spots.at(pp->locallab.selspot).sensiex || sensiex->getEditedState(); + pe->locallab.spots.at(pp->locallab.selspot).structexp = pe->locallab.spots.at(pp->locallab.selspot).structexp || structexp->getEditedState(); pe->locallab.spots.at(pp->locallab.selspot).excurve = pe->locallab.spots.at(pp->locallab.selspot).excurve || !shapeexpos->isUnChanged(); pe->locallab.spots.at(pp->locallab.selspot).showmaskexpMethod = pe->locallab.spots.at(pp->locallab.selspot).showmaskexpMethod || showmaskexpMethod->get_active_text() != M("GENERAL_UNCHANGED"); pe->locallab.spots.at(pp->locallab.selspot).CCmaskexpcurve = pe->locallab.spots.at(pp->locallab.selspot).CCmaskexpcurve || !CCmaskexpshape->isUnChanged(); @@ -1798,6 +1808,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pedited->locallab.spots.at(pp->locallab.selspot).contrast = pedited->locallab.spots.at(pp->locallab.selspot).contrast || contrast->getEditedState(); pedited->locallab.spots.at(pp->locallab.selspot).chroma = pedited->locallab.spots.at(pp->locallab.selspot).chroma || chroma->getEditedState(); pedited->locallab.spots.at(pp->locallab.selspot).sensi = pedited->locallab.spots.at(pp->locallab.selspot).sensi || sensi->getEditedState(); + pedited->locallab.spots.at(pp->locallab.selspot).structcol = pedited->locallab.spots.at(pp->locallab.selspot).structcol || structcol->getEditedState(); pedited->locallab.spots.at(pp->locallab.selspot).qualitycurveMethod = pedited->locallab.spots.at(pp->locallab.selspot).qualitycurveMethod || qualitycurveMethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->locallab.spots.at(pp->locallab.selspot).showmaskcolMethod = pedited->locallab.spots.at(pp->locallab.selspot).showmaskcolMethod || showmaskcolMethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->locallab.spots.at(pp->locallab.selspot).llcurve = pedited->locallab.spots.at(pp->locallab.selspot).llcurve || !llshape->isUnChanged(); @@ -1817,6 +1828,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pedited->locallab.spots.at(pp->locallab.selspot).shcompr = pedited->locallab.spots.at(pp->locallab.selspot).shcompr || shcompr->getEditedState(); pedited->locallab.spots.at(pp->locallab.selspot).warm = pedited->locallab.spots.at(pp->locallab.selspot).warm || warm->getEditedState(); pedited->locallab.spots.at(pp->locallab.selspot).sensiex = pedited->locallab.spots.at(pp->locallab.selspot).sensiex || sensiex->getEditedState(); + pedited->locallab.spots.at(pp->locallab.selspot).structexp = pedited->locallab.spots.at(pp->locallab.selspot).structexp || structexp->getEditedState(); pedited->locallab.spots.at(pp->locallab.selspot).excurve = pedited->locallab.spots.at(pp->locallab.selspot).excurve || !shapeexpos->isUnChanged(); pedited->locallab.spots.at(pp->locallab.selspot).showmaskexpMethod = pedited->locallab.spots.at(pp->locallab.selspot).showmaskexpMethod || showmaskexpMethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->locallab.spots.at(pp->locallab.selspot).CCmaskexpcurve = pedited->locallab.spots.at(pp->locallab.selspot).CCmaskexpcurve || !CCmaskexpshape->isUnChanged(); @@ -2412,6 +2424,7 @@ void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pe contrast->setDefault((double)defSpot->contrast); chroma->setDefault((double)defSpot->chroma); sensi->setDefault((double)defSpot->sensi); + structcol->setDefault((double)defSpot->structcol); // Exposure expcomp->setDefault((double)defSpot->expcomp); hlcompr->setDefault((double)defSpot->hlcompr); @@ -2420,6 +2433,7 @@ void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pe shcompr->setDefault((double)defSpot->shcompr); warm->setDefault((double)defSpot->warm); sensiex->setDefault((double)defSpot->sensiex); + structexp->setDefault((double)defSpot->structexp); // Vibrance saturated->setDefault((double)defSpot->saturated); pastels->setDefault((double)defSpot->pastels); @@ -2486,6 +2500,7 @@ void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pe contrast->setDefaultEditedState(Irrelevant); chroma->setDefaultEditedState(Irrelevant); sensi->setDefaultEditedState(Irrelevant); + structcol->setDefaultEditedState(Irrelevant); // Exposure expcomp->setDefaultEditedState(Irrelevant); hlcompr->setDefaultEditedState(Irrelevant); @@ -2494,6 +2509,7 @@ void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pe shcompr->setDefaultEditedState(Irrelevant); warm->setDefaultEditedState(Irrelevant); sensiex->setDefaultEditedState(Irrelevant); + structexp->setDefaultEditedState(Irrelevant); // Vibrance saturated->setDefaultEditedState(Irrelevant); pastels->setDefaultEditedState(Irrelevant); @@ -2564,6 +2580,7 @@ void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pe contrast->setDefaultEditedState(defSpotState->contrast ? Edited : UnEdited); chroma->setDefaultEditedState(defSpotState->chroma ? Edited : UnEdited); sensi->setDefaultEditedState(defSpotState->sensi ? Edited : UnEdited); + structcol->setDefaultEditedState(defSpotState->structcol ? Edited : UnEdited); // Exposure expcomp->setDefaultEditedState(defSpotState->expcomp ? Edited : UnEdited); hlcompr->setDefaultEditedState(defSpotState->hlcompr ? Edited : UnEdited); @@ -2572,6 +2589,7 @@ void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pe shcompr->setDefaultEditedState(defSpotState->shcompr ? Edited : UnEdited); warm->setDefaultEditedState(defSpotState->warm ? Edited : UnEdited); sensiex->setDefaultEditedState(defSpotState->sensiex ? Edited : UnEdited); + structexp->setDefaultEditedState(defSpotState->structexp ? Edited : UnEdited); // Vibrance saturated->setDefaultEditedState(defSpotState->saturated ? Edited : UnEdited); pastels->setDefaultEditedState(defSpotState->pastels ? Edited : UnEdited); @@ -2697,6 +2715,12 @@ void Locallab::adjusterChanged(Adjuster * a, double newval) listener->panelChanged(Evlocallabsensi, sensi->getTextValue()); } } + + if (a == structcol) { + if (listener) { + listener->panelChanged(Evlocallabstructcol, structcol->getTextValue()); + } + } } // Exposure @@ -2751,6 +2775,13 @@ void Locallab::adjusterChanged(Adjuster * a, double newval) listener->panelChanged(Evlocallabsensiex, sensiex->getTextValue()); } } + + if (a == structexp) { + if (listener) { + listener->panelChanged(Evlocallabstructexp, structexp->getTextValue()); + } + } + } // Vibrance @@ -3136,6 +3167,7 @@ void Locallab::setBatchMode(bool batchMode) contrast->showEditedCB(); chroma->showEditedCB(); sensi->showEditedCB(); + structcol->showEditedCB(); // Exposure expcomp->showEditedCB(); hlcompr->showEditedCB(); @@ -3144,6 +3176,7 @@ void Locallab::setBatchMode(bool batchMode) shcompr->showEditedCB(); warm->showEditedCB(); sensiex->showEditedCB(); + structexp->showEditedCB(); // Vibrance saturated->showEditedCB(); pastels->showEditedCB(); @@ -3441,6 +3474,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con contrast->setValue(pp->locallab.spots.at(index).contrast); chroma->setValue(pp->locallab.spots.at(index).chroma); sensi->setValue(pp->locallab.spots.at(index).sensi); + structcol->setValue(pp->locallab.spots.at(index).structcol); if (pp->locallab.spots.at(index).qualitycurveMethod == "none") { qualitycurveMethod->set_active(0); @@ -3485,6 +3519,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con shcompr->setValue(pp->locallab.spots.at(index).shcompr); warm->setValue(pp->locallab.spots.at(index).warm); sensiex->setValue(pp->locallab.spots.at(index).sensiex); + structexp->setValue(pp->locallab.spots.at(index).structexp); shapeexpos->setCurve(pp->locallab.spots.at(index).excurve); if (pp->locallab.spots.at(index).showmaskexpMethod == "none") { showmaskexpMethod->set_active(0); @@ -3651,6 +3686,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con contrast->setEditedState(spotState->contrast ? Edited : UnEdited); chroma->setEditedState(spotState->chroma ? Edited : UnEdited); sensi->setEditedState(spotState->sensi ? Edited : UnEdited); + structcol->setEditedState(spotState->structcol ? Edited : UnEdited); if (!spotState->qualitycurveMethod) { qualitycurveMethod->set_active_text(M("GENERAL_UNCHANGED")); @@ -3677,6 +3713,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con warm->setEditedState(spotState->warm ? Edited : UnEdited); shcompr->setEditedState(spotState->shcompr ? Edited : UnEdited); sensiex->setEditedState(spotState->sensiex ? Edited : UnEdited); + structexp->setEditedState(spotState->structexp ? Edited : UnEdited); shapeexpos->setUnChanged(!spotState->excurve); if (!spotState->showmaskexpMethod) { showmaskexpMethod->set_active_text(M("GENERAL_UNCHANGED")); diff --git a/rtgui/locallab.h b/rtgui/locallab.h index 02489deed..134c55fff 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -92,6 +92,8 @@ private: Adjuster* const contrast; Adjuster* const chroma; Adjuster* const sensi; + Adjuster* const structcol; + // Exposure Adjuster* const expcomp; Adjuster* const hlcompr; @@ -100,6 +102,7 @@ private: Adjuster* const shcompr; Adjuster* const warm; Adjuster* const sensiex; + Adjuster* const structexp; // Vibrance Adjuster* const saturated; Adjuster* const pastels; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 4dd0009cb..d1c8dc4f5 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -948,6 +948,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).contrast = locallab.spots.at(j).contrast && pSpot.contrast == otherSpot.contrast; locallab.spots.at(j).chroma = locallab.spots.at(j).chroma && pSpot.chroma == otherSpot.chroma; locallab.spots.at(j).sensi = locallab.spots.at(j).sensi && pSpot.sensi == otherSpot.sensi; + locallab.spots.at(j).structcol = locallab.spots.at(j).structcol && pSpot.structcol == otherSpot.structcol; locallab.spots.at(j).qualitycurveMethod = locallab.spots.at(j).qualitycurveMethod && pSpot.qualitycurveMethod == otherSpot.qualitycurveMethod; locallab.spots.at(j).showmaskcolMethod = locallab.spots.at(j).showmaskcolMethod && pSpot.showmaskcolMethod == otherSpot.showmaskcolMethod; locallab.spots.at(j).llcurve = locallab.spots.at(j).llcurve && pSpot.llcurve == otherSpot.llcurve; @@ -967,6 +968,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).shcompr = locallab.spots.at(j).shcompr && pSpot.shcompr == otherSpot.shcompr; locallab.spots.at(j).warm = locallab.spots.at(j).warm && pSpot.warm == otherSpot.warm; locallab.spots.at(j).sensiex = locallab.spots.at(j).sensiex && pSpot.sensiex == otherSpot.sensiex; + locallab.spots.at(j).structexp = locallab.spots.at(j).structexp && pSpot.structexp == otherSpot.structexp; locallab.spots.at(j).excurve = locallab.spots.at(j).excurve && pSpot.excurve == otherSpot.excurve; locallab.spots.at(j).showmaskexpMethod = locallab.spots.at(j).showmaskexpMethod && pSpot.showmaskexpMethod == otherSpot.showmaskexpMethod; locallab.spots.at(j).CCmaskexpcurve = locallab.spots.at(j).CCmaskexpcurve && pSpot.CCmaskexpcurve == otherSpot.CCmaskexpcurve; @@ -2575,6 +2577,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).sensi = mods.locallab.spots.at(i).sensi; } + if (locallab.spots.at(i).structcol) { + toEdit.locallab.spots.at(i).structcol = mods.locallab.spots.at(i).structcol; + } + if (locallab.spots.at(i).qualitycurveMethod) { toEdit.locallab.spots.at(i).qualitycurveMethod = mods.locallab.spots.at(i).qualitycurveMethod; } @@ -2648,6 +2654,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).sensiex = mods.locallab.spots.at(i).sensiex; } + if (locallab.spots.at(i).structexp) { + toEdit.locallab.spots.at(i).structexp = mods.locallab.spots.at(i).structexp; + } + if (locallab.spots.at(i).excurve) { toEdit.locallab.spots.at(i).excurve = mods.locallab.spots.at(i).excurve; } @@ -3915,6 +3925,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : contrast(v), chroma(v), sensi(v), + structcol(v), qualitycurveMethod(v), showmaskcolMethod(v), llcurve(v), @@ -3934,6 +3945,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : shcompr(v), warm(v), sensiex(v), + structexp(v), excurve(v), showmaskexpMethod(v), CCmaskexpcurve(v), @@ -4047,6 +4059,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) contrast = v; chroma = v; sensi = v; + structcol = v; qualitycurveMethod = v; showmaskcolMethod = v; llcurve = v; @@ -4066,6 +4079,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) shcompr = v; warm = v; sensiex = v; + structexp = v; excurve = v; showmaskexpMethod = v; CCmaskexpcurve = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 12d688ada..02a6302eb 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -487,6 +487,7 @@ public: bool contrast; bool chroma; bool sensi; + bool structcol; bool qualitycurveMethod; bool showmaskcolMethod; bool llcurve; @@ -506,6 +507,7 @@ public: bool shcompr; bool warm; bool sensiex; + bool structexp; bool excurve; bool showmaskexpMethod; bool CCmaskexpcurve;