From 290fa796e821b7d5f3ddec2a3490bb8b4614ec79 Mon Sep 17 00:00:00 2001 From: Desmis Date: Fri, 13 Dec 2019 18:27:54 +0100 Subject: [PATCH] Third commit Wavelet pyramid - Blur level curve by level --- rtdata/languages/default | 8 +- rtengine/dcrop.cc | 6 ++ rtengine/improccoordinator.cc | 6 ++ rtengine/improccoordinator.h | 2 + rtengine/improcfun.h | 3 +- rtengine/iplocallab.cc | 161 ++++++++++++++++++++-------------- rtengine/procevents.h | 1 + rtengine/procparams.cc | 4 + rtengine/procparams.h | 1 + rtengine/refreshmap.cc | 3 +- rtengine/simpleprocess.cc | 4 + rtgui/locallab.cc | 31 +++++++ rtgui/locallab.h | 2 + rtgui/paramsedited.cc | 7 ++ rtgui/paramsedited.h | 1 + 15 files changed, 168 insertions(+), 72 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 50bab5ad8..e599458ae 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1095,7 +1095,8 @@ HISTORY_MSG_855;Local - Entire image HISTORY_MSG_856;Local - Base log HISTORY_MSG_857;Local - Contrast Blur Residual HISTORY_MSG_858;Local - Contrast Luminance only -HISTORY_MSG_859;Local - Contrast Blur levels +HISTORY_MSG_859;Local - Contrast Maximum Blur levels +HISTORY_MSG_860;Local - Contrast Curve Blur levels HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -2190,7 +2191,7 @@ TP_LOCALLAB_BLURCBDL;Blur levels 0-1-2-3-4 TP_LOCALLAB_BLURCOL;Radius Mask Blur TP_LOCALLAB_BLURDE;Blur Shape detection TP_LOCALLAB_BLURLC;Luminance only -TP_LOCALLAB_BLURLEVELFRA;Blur Levels +TP_LOCALLAB_BLURLEVELFRA;Blur Levels TP_LOCALLAB_BLURRESIDFRA;Blur Residual TP_LOCALLAB_BUTTON_ADD;Add TP_LOCALLAB_BUTTON_DEL;Delete @@ -2337,7 +2338,7 @@ TP_LOCALLAB_LAPLACEXP;Laplacian threshold TP_LOCALLAB_LAPMASKCOL;Laplacian threshold mask TP_LOCALLAB_LAPRAD_TOOLTIP;Avoid using Radius and Laplace Threshold simultaneously TP_LOCALLAB_LC_FFTW_TOOLTIP;FFT improve quality and allow big radius, but increases the treatment time.\nThe treatment time depends on the surface to be treated.\nTo be used preferably for large radius.\n\nDimensions can be reduced by a few pixels to optimize FFTW.\nThis optimization can reduce the treatment time by a factor of 1.5 to 10.\n -TP_LOCALLAB_LEVELBLUR;Blur levels +TP_LOCALLAB_LEVELBLUR;Maximum Blur levels TP_LOCALLAB_LEVELWAV;Wavelets Levels TP_LOCALLAB_LEVELWAV_TOOLTIP;The Level is automatically adapted to the size of the spot and the preview.\nFrom level 9 size max 512 to level 1 size max = 4 TP_LOCALLAB_LIGHTNESS;Lightness @@ -2578,6 +2579,7 @@ TP_LOCALLAB_WARM_TOOLTIP;This slider use Ciecam algorithm and acts as White Bala TP_LOCALLAB_WAV;Levels local contrast TP_LOCALLAB_WAVE;Wavelet TP_LOCALLAB_WAVHIGH;Wavelet high +TP_LOCALLAB_WAVLEV;Blur by Level TP_LOCALLAB_WAVLOW;Wavelet low TP_LOCALLAB_WAVMASK;Mask Levels local contrast TP_LOCALLAB_WAVMED;Wavelet normal diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 5c7312a53..2d5ae12a7 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -927,6 +927,7 @@ void Crop::update(int todo) bool lcmasblutili = parent->lcmasblutili; bool llmasblutili = parent->llmasblutili; bool locwavutili = parent->locwavutili; + bool loclevwavutili = parent->loclevwavutili; bool lmasutiliblwav = parent->lmasutiliblwav; bool lmasutilicolwav = parent->lmasutilicolwav; @@ -966,6 +967,7 @@ void Crop::update(int todo) LocwavCurve locwavCurve; LocwavCurve loclmasCurveblwav; LocwavCurve loclmasCurvecolwav; + LocwavCurve loclevwavCurve; LocretigainCurverab locRETgainCurverab; locallutili = false; @@ -1009,6 +1011,7 @@ void Crop::update(int todo) loclmasCurvecolwav.Set(params.locallab.spots.at(sp).LLmaskcolcurvewav, lmasutilicolwav); locwavCurve.Set(params.locallab.spots.at(sp).locwavcurve, locwavutili); + loclevwavCurve.Set(params.locallab.spots.at(sp).loclevwavcurve, loclevwavutili); locallutili = false; CurveFactory::curveLocal(locallutili, params.locallab.spots.at(sp).llcurve, lllocalcurve2, sca); localclutili = false; @@ -1100,6 +1103,7 @@ void Crop::update(int todo) loclmasCurveblwav,lmasutiliblwav, loclmasCurvecolwav,lmasutilicolwav, locwavCurve, locwavutili, + loclevwavCurve, loclevwavutili, LHutili, HHutili, cclocalcurve2, localcutili, rgblocalcurve2, localrgbutili, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, lightCurveloc2, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, lastsav, parent->locallColorMask, parent->locallColorMaskinv, parent->locallExpMask, parent->locallExpMaskinv, parent->locallSHMask, parent->locallSHMaskinv, parent->locallvibMask, parent->locallcbMask, parent->locallretiMask, parent->locallsoftMask, parent->localltmMask, parent->locallblMask, @@ -1131,6 +1135,7 @@ void Crop::update(int todo) loclmasCurveblwav,lmasutiliblwav, loclmasCurvecolwav,lmasutilicolwav, locwavCurve, locwavutili, + loclevwavCurve, loclevwavutili, LHutili, HHutili, cclocalcurve2, localcutili, rgblocalcurve2, localrgbutili, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, lightCurveloc2, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, lastsav, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); @@ -1186,6 +1191,7 @@ void Crop::update(int todo) locccmasblCurve.Reset(); lochhmasblCurve.Reset(); locwavCurve.Reset(); + loclevwavCurve.Reset(); loclmasCurveblwav.Reset(); loclmasCurvecolwav.Reset(); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 4e7bb6b56..4523f585f 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -219,6 +219,7 @@ ImProcCoordinator::ImProcCoordinator() : lhmascbutili(false), llmascbutili(false), locwavutili(false), + loclevwavutili(false), lmasutiliblwav(false), lmasutilicolwav(false), LHutili(false), @@ -1079,6 +1080,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) llmasblutili = false; lcmasutili = false; locwavutili = false; + loclevwavutili = false; lmasutiliblwav = false; lmasutilicolwav = false; locRETgainCurve.Set(params->locallab.spots.at(sp).localTgaincurve); @@ -1114,6 +1116,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) loclmasCurvecolwav.Set(params->locallab.spots.at(sp).LLmaskcolcurvewav, lmasutilicolwav); locwavCurve.Set(params->locallab.spots.at(sp).locwavcurve, locwavutili); + loclevwavCurve.Set(params->locallab.spots.at(sp).loclevwavcurve, loclevwavutili); CurveFactory::curveLocal(locallutili, params->locallab.spots.at(sp).llcurve, lllocalcurve, sca); CurveFactory::curveLocal(localclutili, params->locallab.spots.at(sp).clcurve, cllocalcurve, sca); CurveFactory::curveLocal(locallcutili, params->locallab.spots.at(sp).lccurve, lclocalcurve, sca); @@ -1221,6 +1224,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) loclmasCurveblwav, lmasutiliblwav, loclmasCurvecolwav, lmasutilicolwav, locwavCurve, locwavutili, + loclevwavCurve, loclevwavutili, LHutili, HHutili, cclocalcurve, localcutili, rgblocalcurve, localrgbutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerblu, chromarblu, lumarblu, huer, chromar, lumar, sobeler, lastsav, locallColorMask, locallColorMaskinv, locallExpMask, locallExpMaskinv, locallSHMask, locallSHMaskinv, locallvibMask, locallcbMask, locallretiMask, locallsoftMask, localltmMask, locallblMask, @@ -1257,6 +1261,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) loclmasCurveblwav, lmasutiliblwav, loclmasCurvecolwav, lmasutilicolwav, locwavCurve, locwavutili, + loclevwavCurve, loclevwavutili, LHutili, HHutili, cclocalcurve, localcutili, rgblocalcurve, localrgbutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerblu, chromarblu, lumarblu, huer, chromar, lumar, sobeler, lastsav, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); @@ -1334,6 +1339,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) locccmasblCurve.Reset(); lochhmasblCurve.Reset(); locwavCurve.Reset(); + loclevwavCurve.Reset(); loclmasCurveblwav.Reset(); loclmasCurvecolwav.Reset(); } diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 4c850cfe1..4e059cd9e 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -284,6 +284,7 @@ protected: LocwavCurve locwavCurve; LocwavCurve loclmasCurveblwav; LocwavCurve loclmasCurvecolwav; + LocwavCurve loclevwavCurve; bool locallutili; bool localclutili; @@ -325,6 +326,7 @@ protected: bool lhmasblutili; bool llmasblutili; bool locwavutili; + bool loclevwavutili; bool lmasutiliblwav; bool lmasutilicolwav; bool LHutili; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index f5fb006c7..b1df3fa8e 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -298,6 +298,7 @@ public: const LocwavCurve & loclmasCurveblwav, bool & lmasutiliblwav, const LocwavCurve & loclmasCurvecolwav, bool & lmasutilicolwav, const LocwavCurve & locwavCurve, bool & locwavutili, + const LocwavCurve & loclevwavCurve, bool & loclevwavutili, bool &LHutili, bool &HHutili, LUTf & cclocalcurve, bool & localcutili, LUTf & rgblocalcurve, bool & localrgbutili, 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 &lastsav, int llColorMask, int llColorMaskinv, int llExpMask, int llExpMaskinv, int llSHMask, int llSHMaskinv, int llvibMask, int llcbMask, int llretiMask, int llsoftMask, int lltmMask, int llblMask, @@ -311,7 +312,7 @@ public: static void strcurv_data(std::string retistr, int *s_datc, int &siz); void blendstruc(int bfw, int bfh, LabImage* bufcolorig, float radius, float stru, array2D & blend2, int sk, bool multiThread); - void wavcontrast4(float ** tmp, float contrast, float radblur, float radlevblur, int bfw, int bfh, int level_bl, int level_hl, int level_br, int level_hr, int sk, bool numThreads, const LocwavCurve & locwavCurve, bool & locwavutili, int & maxlvl); + void wavcontrast4(float ** tmp, float contrast, float radblur, float radlevblur, int bfw, int bfh, int level_bl, int level_hl, int level_br, int level_hr, int sk, bool numThreads, const LocwavCurve & locwavCurve, bool & locwavutili, const LocwavCurve & loclevwavCurve, bool & loclevwavutili, bool wavcurvelev, int & maxlvl); void transit_shapedetect2(int call, int senstype, const LabImage * bufexporig, const LabImage * bufexpfin, LabImage * originalmask, const float hueref, const float chromaref, const float lumaref, float sobelref, float meansobel, float ** blend2, struct local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk); void transit_shapedetect_retinex(int call, int senstype, LabImage * bufexporig, LabImage * bufmask, LabImage * buforigmas, float **buflight, float **bufchro, const float hueref, const float chromaref, const float lumaref, const struct local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 554f057d1..bb42900ed 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -3992,7 +3992,10 @@ void ImProcFunctions::maskcalccol(int call, bool invmask, bool pde, int bfw, int const int numThreads = 1; #endif - wavcontrast4(bufmaskblurcol->L, contrast, 0.f, 0.f, bfw, bfh, level_bl, level_hl, level_br, level_hr, sk, numThreads, loclmasCurvecolwav, lmasutilicolwav, maxlvl); + LocwavCurve dummy; + bool loclevwavutili = false; + bool wavcurvelev = false; + wavcontrast4(bufmaskblurcol->L, contrast, 0.f, 0.f, bfw, bfh, level_bl, level_hl, level_br, level_hr, sk, numThreads, loclmasCurvecolwav, lmasutilicolwav, dummy, loclevwavutili, wavcurvelev, maxlvl); } @@ -6729,7 +6732,7 @@ void ImProcFunctions::fftw_tile_blur(int GW, int GH, int tilssize, int max_numbl fftwf_destroy_plan(plan_backward_blox[1]); fftwf_cleanup(); } -void ImProcFunctions::wavcontrast4(float ** tmp, float contrast, float radblur, float radlevblur, int bfw, int bfh, int level_bl, int level_hl, int level_br, int level_hr, int sk, bool numThreads, const LocwavCurve & locwavCurve, bool & locwavutili, int & maxlvl) +void ImProcFunctions::wavcontrast4(float ** tmp, float contrast, float radblur, float radlevblur, int bfw, int bfh, int level_bl, int level_hl, int level_br, int level_hr, int sk, bool numThreads, const LocwavCurve & locwavCurve, bool & locwavutili, const LocwavCurve & loclevwavCurve, bool & loclevwavutili, bool wavcurvelev, int & maxlvl) { wavelet_decomposition *wdspot = new wavelet_decomposition(tmp[0], bfw, bfh, level_br, 1, sk, numThreads, 6); @@ -6843,87 +6846,95 @@ void ImProcFunctions::wavcontrast4(float ** tmp, float contrast, float radblur, int leve = maxlvl; float ****templevel = nullptr; - templevel = new float***[dir]; - //allocate memory for 3 DIR n levels, H_L, W_L - for (int d = 0; d < dir; d++) { - templevel[d] = new float**[leve]; + if (wavcurvelev) { + templevel = new float***[dir]; - for (int k = 0; k < leve; k++) { - templevel[d][k] = new float*[H_L]; + //allocate memory for 3 DIR n levels, H_L, W_L + for (int d = 0; d < dir; d++) { + templevel[d] = new float**[leve]; - for (int i = 0; i < H_L; i++) { - templevel[d][k][i] = new float[W_L]; - } - } - } + for (int k = 0; k < leve; k++) { + templevel[d][k] = new float*[H_L]; - //fill array templevel with wavelet value level dir - for (int dir = 1; dir < 4; dir++) { - for (int level = level_bl; level < maxlvl; ++level) { - int W_L = wdspot->level_W(level); - int H_L = wdspot->level_H(level); - float **wav_L = wdspot->level_coeffs(level); - - for (int y = 0; y < H_L; y++) { - for (int x = 0; x < W_L; x++) { - float val = wav_L[dir][y * W_L + x]; - templevel[dir - 1][level][y][x] = val; + for (int i = 0; i < H_L; i++) { + templevel[d][k][i] = new float[W_L]; } } } - } - //blur level and dir - for (int dir = 1; dir < 4; dir++) { - for (int level = level_bl; level < maxlvl; ++level) { - int W_L = wdspot->level_W(level); - int H_L = wdspot->level_H(level); - #pragma omp parallel - { - gaussianBlur(templevel[dir - 1][level], templevel[dir - 1][level], W_L, H_L, radlevblur); - } - } - } + //fill array templevel with wavelet value level dir + for (int dir = 1; dir < 4; dir++) { + for (int level = level_bl; level < maxlvl; ++level) { + int W_L = wdspot->level_W(level); + int H_L = wdspot->level_H(level); + float **wav_L = wdspot->level_coeffs(level); - //put blur values in wavelet level and dir - for (int dir = 1; dir < 4; dir++) { - for (int level = level_bl; level < maxlvl; ++level) { - int W_L = wdspot->level_W(level); - int H_L = wdspot->level_H(level); - float **wav_L = wdspot->level_coeffs(level); - - for (int y = 0; y < H_L; y++) { - for (int x = 0; x < W_L; x++) { - wav_L[dir][y * W_L + x] = templevel[dir - 1][level][y][x]; + for (int y = 0; y < H_L; y++) { + for (int x = 0; x < W_L; x++) { + float val = wav_L[dir][y * W_L + x]; + templevel[dir - 1][level][y][x] = val; + } } } } - } + //blur level and dir + for (int dir = 1; dir < 4; dir++) { + for (int level = level_bl; level < maxlvl; ++level) { + int W_L = wdspot->level_W(level); + int H_L = wdspot->level_H(level); - //free memory - for (int i = 0; i < dir; i++) { - for (int j = 0; j < leve; j++) { - for (int l = 0; l < H_L; l++) { - delete [] templevel[i][j][l]; + if (loclevwavCurve && loclevwavutili) { + + float klev = (loclevwavCurve[level * 50.f]); + + #pragma omp parallel + { + gaussianBlur(templevel[dir - 1][level], templevel[dir - 1][level], W_L, H_L, radlevblur * klev); + } + } } } - } - for (int i = 0; i < dir; i++) { - for (int j = 0; j < leve; j++) { - delete [] templevel[i][j]; + //put blur values in wavelet level and dir + for (int dir = 1; dir < 4; dir++) { + for (int level = level_bl; level < maxlvl; ++level) { + int W_L = wdspot->level_W(level); + int H_L = wdspot->level_H(level); + float **wav_L = wdspot->level_coeffs(level); + + for (int y = 0; y < H_L; y++) { + for (int x = 0; x < W_L; x++) { + wav_L[dir][y * W_L + x] = templevel[dir - 1][level][y][x]; + } + } + } } + + + //free memory + for (int i = 0; i < dir; i++) { + for (int j = 0; j < leve; j++) { + for (int l = 0; l < H_L; l++) { + delete [] templevel[i][j][l]; + } + } + } + + for (int i = 0; i < dir; i++) { + for (int j = 0; j < leve; j++) { + delete [] templevel[i][j]; + } + } + + for (int i = 0; i < dir; i++) { + delete [] templevel[i]; + } + + delete [] templevel; } - for (int i = 0; i < dir; i++) { - delete [] templevel[i]; - } - - delete [] templevel; - - if (locwavCurve && locwavutili) { for (int dir = 1; dir < 4; dir++) { for (int level = level_bl; level < maxlvl; ++level) { @@ -8468,6 +8479,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o const LocwavCurve & loclmasCurveblwav, bool & lmasutiliblwav, const LocwavCurve & loclmasCurvecolwav, bool & lmasutilicolwav, const LocwavCurve & locwavCurve, bool & locwavutili, + const LocwavCurve & loclevwavCurve, bool & loclevwavutili, bool & LHutili, bool & HHutili, LUTf & cclocalcurve, bool & localcutili, LUTf & rgblocalcurve, bool & localrgbutili, 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 &lastsav, int llColorMask, int llColorMaskinv, int llExpMask, int llExpMaskinv, int llSHMask, int llSHMaskinv, int llvibMask, int llcbMask, int llretiMask, int llsoftMask, int lltmMask, int llblMask, @@ -8862,8 +8874,10 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o int level_br = params->locallab.spots.at(sp).csthresholdblur.getBottomRight(); int level_hr = params->locallab.spots.at(sp).csthresholdblur.getTopRight(); - - wavcontrast4(bufmaskblurbl->L, contrast, 0.f, 0.f, GW, GH, level_bl, level_hl, level_br, level_hr, sk, numThreads, loclmasCurveblwav, lmasutiliblwav, maxlvl); + LocwavCurve dummy; + bool loclevwavutili = false; + bool wavcurvelev = false; + wavcontrast4(bufmaskblurbl->L, contrast, 0.f, 0.f, GW, GH, level_bl, level_hl, level_br, level_hr, sk, numThreads, loclmasCurveblwav, lmasutiliblwav, dummy, loclevwavutili, wavcurvelev, maxlvl); } int shado = params->locallab.spots.at(sp).shadmaskbl; @@ -10530,7 +10544,20 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o } } - if ((lp.lcamount > 0.f || wavcurve || params->locallab.spots.at(sp).residblur > 0.f || params->locallab.spots.at(sp).levelblur > 0.f || params->locallab.spots.at(sp).residcont != 0.f || params->locallab.spots.at(sp).clarilres != 0.f || params->locallab.spots.at(sp).claricres != 0.f) && call < 3 && lp.lcena) { + bool wavcurvelev = false; + + if (loclevwavCurve && loclevwavutili) { + if (lp.locmet == 1) { + for (int i = 0; i < 500; i++) { + if (loclevwavCurve[i] != 0.) { + wavcurvelev = true; + } + } + } + } + + + if ((lp.lcamount > 0.f || wavcurve || wavcurvelev || params->locallab.spots.at(sp).residblur > 0.f || params->locallab.spots.at(sp).levelblur > 0.f || params->locallab.spots.at(sp).residcont != 0.f || params->locallab.spots.at(sp).clarilres != 0.f || params->locallab.spots.at(sp).claricres != 0.f) && call < 3 && lp.lcena) { int ystart = std::max(static_cast(lp.yc - lp.lyT) - cy, 0); int yend = std::min(static_cast(lp.yc + lp.ly) - cy, original->H); int xstart = std::max(static_cast(lp.xc - lp.lxL) - cx, 0); @@ -10777,7 +10804,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o const bool blurlc = params->locallab.spots.at(sp).blurlc; const float radlevblur = (params->locallab.spots.at(sp).levelblur) / sk; - wavcontrast4(tmp1->L, contrast, radblur, radlevblur, tmp1->W, tmp1->H, level_bl, level_hl, level_br, level_hr, sk, numThreads, locwavCurve, locwavutili, maxlvl); + wavcontrast4(tmp1->L, contrast, radblur, radlevblur, tmp1->W, tmp1->H, level_bl, level_hl, level_br, level_hr, sk, numThreads, locwavCurve, locwavutili, loclevwavCurve, loclevwavutili, wavcurvelev, maxlvl); const float satur = params->locallab.spots.at(sp).residchro; diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 7e0da95cc..ee86a59c9 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -885,6 +885,7 @@ enum ProcEventCode { Evlocallabresidblur = 856, Evlocallabblurlc = 857, Evlocallablevelblur = 858, + EvlocallabwavCurvelev = 859, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 581090d88..064b438ff 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2734,6 +2734,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : localcontMethod("loc"), locwavcurve{(double)FCT_MinMaxCPoints, 0.0, 0.5, 0.35, 0.35, 1., 0.5, 0.35, 0.35}, csthreshold(0, 0, 5, 5, false), + loclevwavcurve{(double)FCT_MinMaxCPoints, 0.0, 0.0, 0.0, 0.35, 0.5, 0., 0.35, 0.35, 1.0, 0.0, 0.35, 0.35}, // Contrast by detail levels expcbdl(false), mult{1.0, 1.0, 1.0, 1.0, 1.0, 1.0}, @@ -3120,6 +3121,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && localcontMethod == other.localcontMethod && locwavcurve == other.locwavcurve && csthreshold == other.csthreshold + && loclevwavcurve == other.loclevwavcurve // Constrast by detail levels && expcbdl == other.expcbdl && [this, &other]()->bool { @@ -4485,6 +4487,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->locallab.spots.at(i).blurlc, "Locallab", "Blurlc_" + std::to_string(i), spot.blurlc, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).localcontMethod, "Locallab", "localcontMethod_" + std::to_string(i), spot.localcontMethod, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).locwavcurve, "Locallab", "LocwavCurve_" + std::to_string(i), spot.locwavcurve, keyFile); + saveToKeyfile(!pedited || pedited->locallab.spots.at(i).loclevwavcurve, "Locallab", "LoclevwavCurve_" + std::to_string(i), spot.loclevwavcurve, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).csthreshold, "Locallab", "CSThreshold_" + std::to_string(i), spot.csthreshold.toVector(), keyFile); // Contrast by detail levels saveToKeyfile(!pedited || pedited->locallab.spots.at(i).expcbdl, "Locallab", "Expcbdl_" + std::to_string(i), spot.expcbdl, keyFile); @@ -6000,6 +6003,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Blurlc_" + std::to_string(i), pedited, spot.blurlc, spotEdited.blurlc); assignFromKeyfile(keyFile, "Locallab", "localcontMethod_" + std::to_string(i), pedited, spot.localcontMethod, spotEdited.localcontMethod); assignFromKeyfile(keyFile, "Locallab", "LocwavCurve_" + std::to_string(i), pedited, spot.locwavcurve, spotEdited.locwavcurve); + assignFromKeyfile(keyFile, "Locallab", "LoclevwavCurve_" + std::to_string(i), pedited, spot.loclevwavcurve, spotEdited.loclevwavcurve); if (keyFile.has_key("Locallab", "CSThreshold_" + std::to_string(i))) { const std::vector thresh = keyFile.get_integer_list("Locallab", "CSThreshold_" + std::to_string(i)); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 72139464c..f59bd802e 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1277,6 +1277,7 @@ struct LocallabParams { Glib::ustring localcontMethod; std::vector locwavcurve; Threshold csthreshold; + std::vector loclevwavcurve; // Contrast by detail levels bool expcbdl; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 68f3ce4b8..6fd3280e9 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -888,7 +888,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, //Evlocallabbaselog LUMINANCECURVE, //Evlocallabresidblur LUMINANCECURVE, // Evlocallabblurlc - LUMINANCECURVE //Evlocallablevelblur + LUMINANCECURVE, //Evlocallablevelblur + LUMINANCECURVE //EvlocallabwavCurvelev }; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 5c2a62256..886f28292 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1116,6 +1116,7 @@ private: LocwavCurve loclmasCurveblwav; LocwavCurve loclmasCurvecolwav; LocwavCurve locwavCurve; + LocwavCurve loclevwavCurve; LUTf lllocalcurve(65536, 0); LUTf lclocalcurve(65536, 0); LUTf cllocalcurve(65536, 0); @@ -1190,6 +1191,7 @@ private: bool lhmasblutili = false; bool llmasblutili = false; bool locwavutili = false; + bool loclevwavutili = false; bool lmasutiliblwav = false; bool lmasutilicolwav = false; locRETgainCurve.Set(params.locallab.spots.at(sp).localTgaincurve); @@ -1225,6 +1227,7 @@ private: loclmasCurvecolwav.Set(params.locallab.spots.at(sp).LLmaskcolcurvewav, lmasutilicolwav); locwavCurve.Set(params.locallab.spots.at(sp).locwavcurve, locwavutili); + loclevwavCurve.Set(params.locallab.spots.at(sp).loclevwavcurve, loclevwavutili); CurveFactory::curveLocal(locallutili, params.locallab.spots.at(sp).llcurve, lllocalcurve, 1); CurveFactory::curveLocal(localclutili, params.locallab.spots.at(sp).clcurve, cllocalcurve, 1); CurveFactory::curveLocal(locallcutili, params.locallab.spots.at(sp).lccurve, lclocalcurve, 1); @@ -1296,6 +1299,7 @@ private: loclmasCurveblwav,lmasutiliblwav, loclmasCurvecolwav,lmasutilicolwav, locwavCurve, locwavutili, + loclevwavCurve, loclevwavutili, LHutili, HHutili, cclocalcurve, localcutili, rgblocalcurve, localrgbutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, lastsav, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 70ec6d9fc..889ccae8d 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -345,6 +345,8 @@ Locallab::Locallab(): LocalcurveEditorwav(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_WAV"))), wavshape(static_cast(LocalcurveEditorwav->addCurve(CT_Flat, "", nullptr, false, false))), + LocalcurveEditorwavlev(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_WAVLEV"))), + wavshapelev(static_cast(LocalcurveEditorwavlev->addCurve(CT_Flat, "", nullptr, false, false))), //CBDL maskcbCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK"))), @@ -2784,6 +2786,17 @@ pe(nullptr) LocalcurveEditorwav->curveListComplete(); + LocalcurveEditorwavlev->setCurveListener(this); + + wavshapelev->setIdentityValue(0.); + wavshapelev->setResetCurve(FlatCurveType(defSpot.loclevwavcurve.at(0)), defSpot.loclevwavcurve); + + if (showtooltip) { +// wavshape->setTooltip(M("TP_RETINEX_WAV_TOOLTIP")); + } + + LocalcurveEditorwavlev->curveListComplete(); + localcontMethod->append(M("TP_LOCALLAB_LOCCONT")); localcontMethod->append(M("TP_LOCALLAB_WAVE")); localcontMethod->set_active(0); @@ -2846,6 +2859,7 @@ pe(nullptr) blurlevelFrame->set_label_align(0.025, 0.5); ToolParamBlock* const blurlevcontBox = Gtk::manage(new ToolParamBlock()); blurlevcontBox->pack_start(*levelblur); + blurlevcontBox->pack_start(*LocalcurveEditorwavlev, Gtk::PACK_SHRINK, 4); blurlevelFrame->add(*blurlevcontBox); setExpandAlignProperties(expcontrastpyr, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); @@ -3541,6 +3555,7 @@ Locallab::~Locallab() delete LocalcurveEditortransT; delete LocalcurveEditorgainT; delete LocalcurveEditorwav; + delete LocalcurveEditorwavlev; delete masktmCurveEditorG; delete maskblCurveEditorG; delete mask2blCurveEditorG; @@ -5024,6 +5039,7 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited pp->locallab.spots.at(pp->locallab.selspot).blurlc = blurlc->get_active(); pp->locallab.spots.at(pp->locallab.selspot).locwavcurve = wavshape->getCurve(); pp->locallab.spots.at(pp->locallab.selspot).csthreshold = csThreshold->getValue(); + pp->locallab.spots.at(pp->locallab.selspot).loclevwavcurve = wavshapelev->getCurve(); if (localcontMethod->get_active_row_number() == 0) { pp->locallab.spots.at(pp->locallab.selspot).localcontMethod = "loc"; @@ -5413,6 +5429,7 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited pe->locallab.spots.at(pp->locallab.selspot).blurlc = pe->locallab.spots.at(pp->locallab.selspot).blurlc || !blurlc->get_inconsistent(); pe->locallab.spots.at(pp->locallab.selspot).localcontMethod = pe->locallab.spots.at(pp->locallab.selspot).localcontMethod || localcontMethod->get_active_text() != M("GENERAL_UNCHANGED"); pe->locallab.spots.at(pp->locallab.selspot).locwavcurve = pe->locallab.spots.at(pp->locallab.selspot).locwavcurve || !wavshape->isUnChanged(); + pe->locallab.spots.at(pp->locallab.selspot).loclevwavcurve = pe->locallab.spots.at(pp->locallab.selspot).loclevwavcurve || !wavshapelev->isUnChanged(); pe->locallab.spots.at(pp->locallab.selspot).csthreshold = pe->locallab.spots.at(pp->locallab.selspot).csthreshold || csThreshold->getEditedState(); // Contrast by detail levels pe->locallab.spots.at(pp->locallab.selspot).expcbdl = pe->locallab.spots.at(pp->locallab.selspot).expcbdl || !expcbdl->get_inconsistent(); @@ -5798,6 +5815,7 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited pedited->locallab.spots.at(pp->locallab.selspot).fftwlc = pedited->locallab.spots.at(pp->locallab.selspot).fftwlc || !fftwlc->get_inconsistent(); pedited->locallab.spots.at(pp->locallab.selspot).blurlc = pedited->locallab.spots.at(pp->locallab.selspot).blurlc || !blurlc->get_inconsistent(); pedited->locallab.spots.at(pp->locallab.selspot).locwavcurve = pedited->locallab.spots.at(pp->locallab.selspot).locwavcurve || !wavshape->isUnChanged(); + pedited->locallab.spots.at(pp->locallab.selspot).loclevwavcurve = pedited->locallab.spots.at(pp->locallab.selspot).loclevwavcurve || !wavshapelev->isUnChanged(); pedited->locallab.spots.at(pp->locallab.selspot).csthreshold = pedited->locallab.spots.at(pp->locallab.selspot).csthreshold || csThreshold->getEditedState(); // Contrast by detail levels pedited->locallab.spots.at(pp->locallab.selspot).expcbdl = pedited->locallab.spots.at(pp->locallab.selspot).expcbdl || !expcbdl->get_inconsistent(); @@ -6277,6 +6295,13 @@ void Locallab::curveChanged(CurveEditor* ce) listener->panelChanged(EvlocallabwavCurve, M("HISTORY_CUSTOMCURVE")); } } + + if (ce == wavshapelev) { + if (listener) { + listener->panelChanged(EvlocallabwavCurvelev, M("HISTORY_CUSTOMCURVE")); + } + } + } } @@ -6299,6 +6324,7 @@ void Locallab::localcontMethodChanged() lcdarkness->show(); lclightness->show(); LocalcurveEditorwav->hide(); + LocalcurveEditorwavlev->hide(); fftwlc->show(); blurlc->show(); } else if (localcontMethod->get_active_row_number() == 1) { @@ -6317,6 +6343,7 @@ void Locallab::localcontMethodChanged() lcdarkness->hide(); lclightness->hide(); LocalcurveEditorwav->show(); + LocalcurveEditorwavlev->show(); fftwlc->hide(); blurlc->show(); } @@ -11464,6 +11491,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con } wavshape->setCurve(pp->locallab.spots.at(index).locwavcurve); + wavshapelev->setCurve(pp->locallab.spots.at(index).loclevwavcurve); if (fftwlc->get_active()) { lcradius->setLimits(20, 1000, 1, 80); @@ -11938,6 +11966,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con fftwlc->set_inconsistent(multiImage && !spotState->fftwlc); blurlc->set_inconsistent(multiImage && !spotState->blurlc); wavshape->setUnChanged(!spotState->locwavcurve); + wavshapelev->setUnChanged(!spotState->loclevwavcurve); csThreshold->setEditedState(spotState->csthreshold ? Edited : UnEdited); if (!spotState->retinexMethod) { @@ -12446,6 +12475,7 @@ void Locallab::updateSpecificGUIState() lcdarkness->show(); lclightness->show(); LocalcurveEditorwav->hide(); + LocalcurveEditorwavlev->hide(); fftwlc->show(); blurlc->show(); } else if (localcontMethod->get_active_row_number() == 1) { @@ -12464,6 +12494,7 @@ void Locallab::updateSpecificGUIState() lcdarkness->hide(); lclightness->hide(); LocalcurveEditorwav->show(); + LocalcurveEditorwavlev->show(); fftwlc->hide(); blurlc->show(); } diff --git a/rtgui/locallab.h b/rtgui/locallab.h index d464b7686..c51fa085a 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -166,6 +166,8 @@ private: //local contrast CurveEditorGroup* const LocalcurveEditorwav; FlatCurveEditor* const wavshape; + CurveEditorGroup* const LocalcurveEditorwavlev; + FlatCurveEditor* const wavshapelev; //Cbdl CurveEditorGroup* const maskcbCurveEditorG; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index b5bd5d9b9..1d7a3c4cf 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1269,6 +1269,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).blurlc = locallab.spots.at(j).blurlc && pSpot.blurlc == otherSpot.blurlc; locallab.spots.at(j).localcontMethod = locallab.spots.at(j).localcontMethod && pSpot.localcontMethod == otherSpot.localcontMethod; locallab.spots.at(j).locwavcurve = locallab.spots.at(j).locwavcurve && pSpot.locwavcurve == otherSpot.locwavcurve; + locallab.spots.at(j).loclevwavcurve = locallab.spots.at(j).loclevwavcurve && pSpot.loclevwavcurve == otherSpot.loclevwavcurve; locallab.spots.at(j).csthreshold = locallab.spots.at(j).csthreshold && pSpot.csthreshold == otherSpot.csthreshold; // Contrast by detail levels locallab.spots.at(j).expcbdl = locallab.spots.at(j).expcbdl && pSpot.expcbdl == otherSpot.expcbdl; @@ -4030,6 +4031,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).locwavcurve = mods.locallab.spots.at(i).locwavcurve; } + if (locallab.spots.at(i).loclevwavcurve) { + toEdit.locallab.spots.at(i).loclevwavcurve = mods.locallab.spots.at(i).loclevwavcurve; + } + if (locallab.spots.at(i).csthreshold) { toEdit.locallab.spots.at(i).csthreshold = mods.locallab.spots.at(i).csthreshold; } @@ -5510,6 +5515,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : blurlc(v), localcontMethod(v), locwavcurve(v), + loclevwavcurve(v), csthreshold(v), // Contrast by detail levels expcbdl(v), @@ -5886,6 +5892,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) blurlc = v; localcontMethod = v; locwavcurve = v; + loclevwavcurve = v; csthreshold = v; // Contrast by detail levels expcbdl = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 8edf5df83..227b5ca06 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -702,6 +702,7 @@ public: bool blurlc; bool localcontMethod; bool locwavcurve; + bool loclevwavcurve; bool csthreshold; // Contrast by detail levels bool expcbdl;