diff --git a/rtdata/languages/default b/rtdata/languages/default index ff72a0b4e..b656e3f8c 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -941,6 +941,7 @@ HISTORY_MSG_694;Local - Retinex Laplacian threshold HISTORY_MSG_695;Local - Soft method HISTORY_MSG_696;Local - Retinex Normalize HISTORY_MSG_697;Local - TM Normalize +HISTORY_MSG_698;Local - Local contrast Fast Fourier HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -2029,6 +2030,7 @@ TP_LOCALLAB_LIGHTRETI;Lightness TP_LOCALLAB_THRESRETI;Threshold TP_LOCALLAB_DENOIS;Denoise TP_LOCALLAB_DEHAZ;Dehaze +TP_LOCALLAB_FFTW;Use Fast Fourier TP_LOCALLAB_GRIDONE;Color Toning TP_LOCALLAB_GRIDTWO;Direct TP_LOCALLAB_LUM;Curves LC diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index c1d7de34f..3040e7c50 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -1202,7 +1202,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if (crops[i]->hasListener() && (panningRelatedChange || (highDetailNeeded && options.prevdemo != PD_Sidecar) || (todo & (M_MONITOR | M_RGBCURVE | M_LUMACURVE)) || crops[i]->get_skip() == 1)) { crops[i]->update(todo); // may call ourselves } - if (panningRelatedChange || (todo & M_MONITOR)) { progress("Conversion to RGB...", 100 * readyphase / numofphases); diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 04a0db0ae..f43567024 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -3688,7 +3688,7 @@ void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer if (params->localContrast.enabled) { // Alberto's local contrast - localContrast(lab, lab->L, params->localContrast, scale); + localContrast(lab, lab->L, params->localContrast, false, scale); } } diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 47a058fe1..5da444e75 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -301,6 +301,7 @@ public: void normalize_mean_dt(float *data, const float *ref, size_t size); void retinex_pde(float *datain, float * dataout, int bfw, int bfh, float thresh, float multy, float *dE); void fftw_convol_blur(float *input, float *output, int bfw, int bfh, float radius, int fftkern); + void fftw_convol_blur2(float **input2, float **output2, int bfw, int bfh, float radius, int fftkern); void fftw_tile_blur(int GW, int GH, int tilssize , int max_numblox_W, int min_numblox_W, float **tmp1, int numThreads, double radius); void MSRLocal(int sp, int lum, LabImage * bufreti, LabImage * bufmask, LabImage * buforig, LabImage * buforigmas, float** luminance, float** templ, const float* const *originalLuminance, const int width, const int height, const procparams::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, @@ -413,7 +414,7 @@ public: void dehaze(Imagefloat *rgb, const DehazeParams &dehazeParams); void ToneMapFattal02(Imagefloat *rgb); - void localContrast(LabImage *lab, float **destination, const LocalContrastParams &localContrastParams, double scale); + void localContrast(LabImage *lab, float **destination, const LocalContrastParams &localContrastParams, bool fftwlc, double scale); void colorToningLabGrid(LabImage *lab, int xstart, int xend, int ystart, int yend, bool MultiThread); // void shadowsHighlights(LabImage *lab); void shadowsHighlights(LabImage *lab, bool ena, int labmode, int hightli, int shado, int rad, int scal, int hltonal, int shtonal); diff --git a/rtengine/iplocalcontrast.cc b/rtengine/iplocalcontrast.cc index 1ca24799d..fdc5fb61f 100644 --- a/rtengine/iplocalcontrast.cc +++ b/rtengine/iplocalcontrast.cc @@ -33,8 +33,9 @@ namespace rtengine { + LocallabParams locallab; ///< Local lab parameters -void ImProcFunctions::localContrast(LabImage *lab, float **destination, const LocalContrastParams &localContrastParams, double scale) +void ImProcFunctions::localContrast(LabImage *lab, float **destination, const LocalContrastParams &localContrastParams, bool fftwlc, double scale) { if (!localContrastParams.enabled) { return; @@ -46,13 +47,17 @@ void ImProcFunctions::localContrast(LabImage *lab, float **destination, const Lo const float dark = localContrastParams.darkness; const float light = localContrastParams.lightness; array2D buf(width, height); - const float sigma = localContrastParams.radius / scale; + float sigma = localContrastParams.radius / scale; //printf("wi%i he=%i am=%f da=%f li=%f si=%f\n", width, height, a, dark, light, sigma); + if(!fftwlc) { #ifdef _OPENMP - #pragma omp parallel if(multiThread) + #pragma omp parallel if(multiThread) #endif - gaussianBlur(lab->L, buf, width, height, sigma); - + gaussianBlur(lab->L, buf, width, height, sigma); + } else { + sigma *= 50.f;//approximation to convert sigma "gaussianBlur" to FFTW blur + ImProcFunctions::fftw_convol_blur2(lab->L, buf, width, height, sigma, 0); + } #ifdef _OPENMP #pragma omp parallel for if(multiThread) #endif diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 8212c7dac..fdfb0ec60 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -63,6 +63,7 @@ #define CLIP04(x) LIM(x, 0.f, 4.f) #define CLIP42_35(x) LIM(x, 0.42, 3.5) #define CLIP2_30(x) LIM(x, 0.2, 3.) +#define CLIPMAX(x) LIM(x,0.f,500000.f) #pragma GCC diagnostic warning "-Wall" #pragma GCC diagnostic warning "-Wextra" @@ -4004,10 +4005,10 @@ void ImProcFunctions::fftw_convol_blur(float *input, float *output, int bfw, int ** Gaussian blur is given by G(x,y) = (1/2*PI*sigma) * exp(-(x2 + y2) / 2* sigma2) */ BENCHFUN - + #ifdef _OPENMP if (multiThread) { - fftwf_init_threads(); + fftwf_init_threads(); fftwf_plan_with_nthreads ( omp_get_max_threads() ); } #endif @@ -4016,10 +4017,10 @@ void ImProcFunctions::fftw_convol_blur(float *input, float *output, int bfw, int float *out; //for FFT datas float *kern = nullptr;//for kernel gauss float *outkern = nullptr;//for FFT kernel - - fftwf_plan p, pkern;//plan for FFT + fftwf_plan p; + fftwf_plan pkern;//plan for FFT int image_size, image_sizechange; - double n_x, n_y;//relative coordonates for kernel Gauss + float n_x, n_y;//relative coordonates for kernel Gauss out = (float*) fftwf_malloc(sizeof(float) * (bfw * bfh));//allocate real datas for FFT @@ -4031,16 +4032,19 @@ void ImProcFunctions::fftw_convol_blur(float *input, float *output, int bfw, int /*compute the Fourier transform of the input data*/ p = fftwf_plan_r2r_2d(bfh, bfw, input, out, FFTW_REDFT10, FFTW_REDFT10, FFTW_ESTIMATE);//FFT 2 dimensions forward FFTW_MEASURE FFTW_ESTIMATE + // p = fftwf_plan_r2r_2d(bfh, bfw, input, out, FFTW_REDFT10, FFTW_REDFT10, FFTW_ESTIMATE | FFTW_DESTROY_INPUT); + fftwf_execute(p); fftwf_destroy_plan(p); - /*define the gaussian constants for the convolution kernel*/ - n_x = rtengine::RT_PI/(double) bfw; - n_y = rtengine::RT_PI/(double) bfh; + // n_x = rtengine::RT_PI/(double) bfw;//ipol + // n_y = rtengine::RT_PI/(double) bfh; + n_x = 1.f/(float) bfw;//gauss + n_y = 1.f/(float) bfh; n_x = n_x * n_x; n_y = n_y * n_y; - + float radsig = 1.f / (2.f * rtengine::RT_PI * radius * radius);//gauss image_size = bfw * bfh; image_sizechange = 4 * image_size; @@ -4051,9 +4055,9 @@ void ImProcFunctions::fftw_convol_blur(float *input, float *output, int bfw, int for(int j = 0; j < bfh; j++){ int index = j * bfw; for(int i = 0; i < bfw; i++) - kern[ i+ index] = exp((float)(-radius)*(n_x * i * i + n_y * j * j));//calculate Gauss kernel + // kern[ i+ index] = exp((float)(-radius)*(n_x * i * i + n_y * j * j));//calculate Gauss kernel Ipol formula + kern[ i+ index] = radsig * exp((float)(-(n_x * i * i + n_y * j * j)/ (2.f * radius * radius)));//calculate Gauss kernel with Gauss formula } - /*compute the Fourier transform of the kernel data*/ pkern = fftwf_plan_r2r_2d(bfh, bfw, kern, outkern, FFTW_REDFT10, FFTW_REDFT10,FFTW_ESTIMATE);//FFT 2 dimensions forward fftwf_execute(pkern); @@ -4087,7 +4091,7 @@ void ImProcFunctions::fftw_convol_blur(float *input, float *output, int bfw, int for(int index = 0; index < image_size; index++) {//restore datas output[index] /= image_sizechange; - output[index] = CLIPLOC(output[index]); + // output[index] = CLIPMAX(output[index]); } fftwf_destroy_plan(p); @@ -4097,6 +4101,46 @@ void ImProcFunctions::fftw_convol_blur(float *input, float *output, int bfw, int } } +void ImProcFunctions::fftw_convol_blur2(float **input2, float **output2, int bfw, int bfh, float radius, int fftkern) +{ + MyMutex::MyLock lock(*fftwMutex); + + float *input = nullptr; + if (NULL == (input = (float *) fftwf_malloc(sizeof(float) * bfw * bfh))) { + fprintf(stderr, "allocation error\n"); + abort(); + } + + float *output = nullptr; + if (NULL == (output = (float *) fftwf_malloc(sizeof(float) * bfw * bfh))) { + fprintf(stderr, "allocation error\n"); + abort(); + } + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + for (int y = 0; y < bfh; y++) { + for (int x = 0; x < bfw; x++) { + input[y * bfw + x] = input2[y][x]; + } + } + ImProcFunctions::fftw_convol_blur(input, output, bfw, bfh, radius, fftkern); + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + for (int y = 0; y < bfh; y++) { + for (int x = 0; x < bfw; x++) { + output2[y][x] = output[y * bfw + x]; + } + } + fftwf_free(input); + fftwf_free(output); + +} + + void ImProcFunctions::fftw_tile_blur(int GW, int GH, int tilssize, int max_numblox_W, int min_numblox_W, float **tmp1, int numThreads, double radius) { BENCHFUN @@ -6313,7 +6357,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o -// soft light and Retinex_pde +// soft light and if (lp.strng > 0.f && call <= 3 && lp.sfena) { 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); @@ -6487,12 +6531,15 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o } LocalContrastParams localContrastParams; + LocallabParams locallabparams; localContrastParams.enabled = true; localContrastParams.radius = params->locallab.spots.at(sp).lcradius; localContrastParams.amount = params->locallab.spots.at(sp).lcamount; localContrastParams.darkness = params->locallab.spots.at(sp).lcdarkness; localContrastParams.lightness = params->locallab.spots.at(sp).lightness; - ImProcFunctions::localContrast(tmp1.get(), tmp1->L, localContrastParams, sk); + bool fftwlc = false; + if(params->locallab.spots.at(sp).fftwlc) fftwlc = true; + ImProcFunctions::localContrast(tmp1.get(), tmp1->L, localContrastParams, fftwlc, sk); float minL = tmp1->L[0][0] - bufgb->L[0][0]; float maxL = minL; diff --git a/rtengine/ipretinex.cc b/rtengine/ipretinex.cc index 71e2b2e33..3341eba74 100644 --- a/rtengine/ipretinex.cc +++ b/rtengine/ipretinex.cc @@ -54,9 +54,11 @@ #define clipretinex( val, minv, maxv ) (( val = (val < minv ? minv : val ) ) > maxv ? maxv : val ) #define CLIPLOC(x) LIM(x,0.f,32767.f) #define CLIPC(a) LIM(a, -42000.f, 42000.f) // limit a and b to 130 probably enough ? +#define CLIPMAX(x) LIM(x,0.f,500000.f) namespace { + void calcGammaLut(double gamma, double ts, LUTf &gammaLut) { double pwr = 1.0 / gamma; @@ -922,6 +924,10 @@ void ImProcFunctions::MSRLocal(int sp, int lum, LabImage * bufreti, LabImage * b const int H_L = height; const int W_L = width; + + // array2D src(W_L, H_L); + // array2D out(W_L, H_L); + float *src[H_L] ALIGNED16; float *srcBuffer = new float[H_L * W_L]; @@ -959,16 +965,19 @@ void ImProcFunctions::MSRLocal(int sp, int lum, LabImage * bufreti, LabImage * b for (int scale = scal - 1; scale >= 0; scale--) { printf("retscale=%f scale=%i \n", RetinexScales[scale], scale); #ifdef _OPENMP - #pragma omp parallel + #pragma omp parallel //disabled with FFTW #endif { if (scale == scal - 1) { gaussianBlur(src, out, W_L, H_L, RetinexScales[scale], buffer); + //ImProcFunctions::fftw_convol_blur2(src, out, W_L, H_L, RetinexScales[scale], 0); } else // reuse result of last iteration { // out was modified in last iteration => restore it + + // ImProcFunctions::fftw_convol_blur2(out, out, W_L, H_L,sqrtf(SQR(RetinexScales[scale]) - SQR(RetinexScales[scale + 1])), 0); gaussianBlur(out, out, W_L, H_L, sqrtf(SQR(RetinexScales[scale]) - SQR(RetinexScales[scale + 1])), buffer); } @@ -1184,7 +1193,6 @@ void ImProcFunctions::MSRLocal(int sp, int lum, LabImage * bufreti, LabImage * b vfloat pondv = F2V(pond); vfloat limMinv = F2V(ilimD); vfloat limMaxv = F2V(limD); - #endif #ifdef _OPENMP #pragma omp parallel for @@ -1217,6 +1225,7 @@ void ImProcFunctions::MSRLocal(int sp, int lum, LabImage * bufreti, LabImage * b } } } + } if (scal != 1) { @@ -1400,11 +1409,13 @@ void ImProcFunctions::MSRLocal(int sp, int lum, LabImage * bufreti, LabImage * b } delete [] buffer; +// src(0,0); +// out(0,0); delete [] outBuffer; outBuffer = nullptr; delete [] srcBuffer; srcBuffer = nullptr; - + float str = strength * (chrome == 0 ? 1.f : 0.8f * (chrT - 0.4f)); const float maxclip = (chrome == 0 ? 32768.f : 50000.f); @@ -1413,7 +1424,7 @@ void ImProcFunctions::MSRLocal(int sp, int lum, LabImage * bufreti, LabImage * b stddv = 0.f; mean_stddv2(luminance, mean, stddv, W_L, H_L, maxtr, mintr); - // printf("mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", mean, stddv, delta, maxtr, mintr); + // printf("mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", mean, stddv, delta, maxtr, mintr); float epsil = 0.1f; @@ -1430,7 +1441,7 @@ void ImProcFunctions::MSRLocal(int sp, int lum, LabImage * bufreti, LabImage * b } delta = maxi - mini; - // printf("maxi=%f mini=%f mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", maxi, mini, mean, stddv, delta, maxtr, mintr); + // printf("maxi=%f mini=%f mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", maxi, mini, mean, stddv, delta, maxtr, mintr); if (!delta) { delta = 1.0f; @@ -1474,6 +1485,7 @@ void ImProcFunctions::MSRLocal(int sp, int lum, LabImage * bufreti, LabImage * b bmin *= 500.f; cdfactor *= 2.f; } + #ifdef _OPENMP #pragma omp parallel @@ -1489,6 +1501,7 @@ void ImProcFunctions::MSRLocal(int sp, int lum, LabImage * bufreti, LabImage * b for (int i = 0; i < H_L; i ++) for (int j = 0; j < W_L; j++) { + if (hasRetGainCurve) { float absciss; @@ -1502,12 +1515,12 @@ void ImProcFunctions::MSRLocal(int sp, int lum, LabImage * bufreti, LabImage * b gan = locRETgainCcurve[absciss]; //new gain function transmission } - + float cd = gan * cdfactor * luminance[i][j] + offse; cdmax = cd > cdmax ? cd : cdmax; cdmin = cd < cdmin ? cd : cdmin; - luminance[i][j] = LIM(cd, 0.f, maxclip) * str + (1.f - str) * originalLuminance[i][j]; + luminance[i][j] = CLIPMAX(LIM(cd, 0.f, maxclip) * str + (1.f - str) * originalLuminance[i][j]); } diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 2e74f229a..a7693b5f7 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -724,6 +724,7 @@ enum ProcEventCode { EvlocallabsoftMethod = 694, Evlocallabequilret = 695, Evlocallabequiltm = 696, + Evlocallabfftwlc = 697, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index fdc0c6ffc..bd53fdd81 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2513,6 +2513,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : lcdarkness(1.0), lclightness(1.0), sensilc(19), + fftwlc(false), // Contrast by detail levels expcbdl(false), mult{1.0, 1.0, 1.0, 1.0, 1.0, 1.0}, @@ -2730,6 +2731,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && lcdarkness == other.lcdarkness && lclightness == other.lclightness && sensilc == other.sensilc + && fftwlc == other.fftwlc // Constrast by detail levels && expcbdl == other.expcbdl && [this, &other]()->bool { @@ -3904,6 +3906,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->locallab.spots.at(i).lcradius, "Locallab", "Lcdarkness_" + std::to_string(i), spot.lcdarkness, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).lcradius, "Locallab", "Lclightness_" + std::to_string(i), spot.lclightness, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).sensilc, "Locallab", "Sensilc_" + std::to_string(i), spot.sensilc, keyFile); + saveToKeyfile(!pedited || pedited->locallab.spots.at(i).fftwlc, "Locallab", "Fftwlc_" + std::to_string(i), spot.fftwlc, keyFile); // Contrast by detail levels saveToKeyfile(!pedited || pedited->locallab.spots.at(i).expcbdl, "Locallab", "Expcbdl_" + std::to_string(i), spot.expcbdl, keyFile); @@ -5218,6 +5221,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Lcdarkness_" + std::to_string(i), pedited, spot.lcdarkness, spotEdited.lcdarkness); assignFromKeyfile(keyFile, "Locallab", "Lclightness_" + std::to_string(i), pedited, spot.lclightness, spotEdited.lclightness); assignFromKeyfile(keyFile, "Locallab", "Sensilc_" + std::to_string(i), pedited, spot.sensilc, spotEdited.sensilc); + assignFromKeyfile(keyFile, "Locallab", "Fftwlc_" + std::to_string(i), pedited, spot.fftwlc, spotEdited.fftwlc); // Contrast by detail levels assignFromKeyfile(keyFile, "Locallab", "Expcbdl_" + std::to_string(i), pedited, spot.expcbdl, spotEdited.expcbdl); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 2d50ab1e0..b8b855c78 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1114,6 +1114,7 @@ struct LocallabParams { double lcdarkness; double lclightness; int sensilc; + bool fftwlc; // Contrast by detail levels bool expcbdl; double mult[6]; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index e86043029..d6bbf9d16 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -723,7 +723,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, //Evlocallablaplace LUMINANCECURVE, //EvlocallabsoftMethod LUMINANCECURVE, // Evlocallabequilret - LUMINANCECURVE // Evlocallabequiltm + LUMINANCECURVE, // Evlocallabequiltm + LUMINANCECURVE // Evlocallabfftwlc }; diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 4147a7c5b..13147b6c8 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -175,7 +175,7 @@ Locallab::Locallab(): sharblur(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SHARBLUR"), 0.2, 2.0, 0.05, 0.2))), sensisha(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSIS"), 0, 100, 1, 19))), // Local Contrast - lcradius(Gtk::manage(new Adjuster(M("TP_LOCALCONTRAST_RADIUS"), 20, 200, 1, 80))), + lcradius(Gtk::manage(new Adjuster(M("TP_LOCALCONTRAST_RADIUS"), 20, 400, 1, 80))), lcamount(Gtk::manage(new Adjuster(M("TP_LOCALCONTRAST_AMOUNT"), 0, 1.0, 0.01, 0))), lcdarkness(Gtk::manage(new Adjuster(M("TP_LOCALCONTRAST_DARKNESS"), 0, 3.0, 0.01, 1.0))), lclightness(Gtk::manage(new Adjuster(M("TP_LOCALCONTRAST_LIGHTNESS"), 0, 3.0, 0.01, 1.0))), @@ -233,6 +233,8 @@ Locallab::Locallab(): enaretiMasktmap(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_TM_MASK")))), // Sharpening inverssha(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_INVERS")))), + // Local contrast + fftwlc(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_FFTW")))), //CBDL enacbMask(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ENABLE_MASK")))), @@ -1016,6 +1018,7 @@ Locallab::Locallab(): // Local Contrast expcontrast->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Locallab::foldAllButMe), expcontrast)); enablecontrastConn = expcontrast->signal_enabled_toggled().connect(sigc::bind(sigc::mem_fun(this, &Locallab::enableToggled), expcontrast)); + fftwlcConn = fftwlc->signal_toggled().connect(sigc::mem_fun(*this, &Locallab::fftwlcChanged)); lcradius->setAdjusterListener(this); @@ -1033,6 +1036,7 @@ Locallab::Locallab(): contrastBox->pack_start(*lcdarkness); contrastBox->pack_start(*lclightness); contrastBox->pack_start(*sensilc); + contrastBox->pack_start(*fftwlc); expcontrast->add(*contrastBox, false); expcontrast->setLevel(2); @@ -2200,6 +2204,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pp->locallab.spots.at(pp->locallab.selspot).lcdarkness = lcdarkness->getValue(); pp->locallab.spots.at(pp->locallab.selspot).lclightness = lclightness->getValue(); pp->locallab.spots.at(pp->locallab.selspot).sensilc = sensilc->getIntValue(); + pp->locallab.spots.at(pp->locallab.selspot).fftwlc = fftwlc->get_active(); // Contrast by detail levels pp->locallab.spots.at(pp->locallab.selspot).expcbdl = expcbdl->getEnabled(); @@ -2419,6 +2424,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pe->locallab.spots.at(pp->locallab.selspot).lcdarkness = pe->locallab.spots.at(pp->locallab.selspot).lcdarkness || lcdarkness->getEditedState(); pe->locallab.spots.at(pp->locallab.selspot).lclightness = pe->locallab.spots.at(pp->locallab.selspot).lclightness || lclightness->getEditedState(); pe->locallab.spots.at(pp->locallab.selspot).sensilc = pe->locallab.spots.at(pp->locallab.selspot).sensilc || sensilc->getEditedState(); + pe->locallab.spots.at(pp->locallab.selspot).fftwlc = pe->locallab.spots.at(pp->locallab.selspot).fftwlc || !fftwlc->get_inconsistent(); // Contrast by detail levels pe->locallab.spots.at(pp->locallab.selspot).expcbdl = pe->locallab.spots.at(pp->locallab.selspot).expcbdl || !expcbdl->get_inconsistent(); @@ -2642,6 +2648,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pedited->locallab.spots.at(pp->locallab.selspot).lcdarkness = pedited->locallab.spots.at(pp->locallab.selspot).lcdarkness || lcdarkness->getEditedState(); pedited->locallab.spots.at(pp->locallab.selspot).lclightness = pedited->locallab.spots.at(pp->locallab.selspot).lclightness || lclightness->getEditedState(); pedited->locallab.spots.at(pp->locallab.selspot).sensilc = pedited->locallab.spots.at(pp->locallab.selspot).sensilc || sensilc->getEditedState(); + pedited->locallab.spots.at(pp->locallab.selspot).fftwlc = pedited->locallab.spots.at(pp->locallab.selspot).fftwlc || !fftwlc->get_inconsistent(); // Contrast by detail levels pedited->locallab.spots.at(pp->locallab.selspot).expcbdl = pedited->locallab.spots.at(pp->locallab.selspot).expcbdl || !expcbdl->get_inconsistent(); @@ -3477,6 +3484,31 @@ void Locallab::activlumChanged() } } +void Locallab::fftwlcChanged() +{ + // printf("fftwlcChanged\n"); + + if (multiImage) { + if (fftwlc->get_inconsistent()) { + fftwlc->set_inconsistent(false); + fftwlcConn.block(true); + fftwlc->set_active(false); + fftwlcConn.block(false); + } + } + + if (getEnabled() && expcontrast->getEnabled()) { + if (listener) { + if (fftwlc->get_active()) { + listener->panelChanged(Evlocallabfftwlc, M("GENERAL_ENABLED")); + } else { + listener->panelChanged(Evlocallabfftwlc, M("GENERAL_DISABLED")); + } + } + } +} + + void Locallab::inversshaChanged() { // printf("inversshaChanged\n"); @@ -5215,6 +5247,7 @@ void Locallab::enableListener() inversshaConn.block(false); // Local Contrast enablecontrastConn.block(false); + fftwlcConn.block(false); // Contrast by detail levels enablecbdlConn.block(false); enacbMaskConn.block(false); @@ -5274,6 +5307,7 @@ void Locallab::disableListener() inversshaConn.block(true); // Local Contrast enablecontrastConn.block(true); + fftwlcConn.block(true); // Contrast by detail levels enablecbdlConn.block(true); enacbMaskConn.block(true); @@ -5487,6 +5521,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con lcdarkness->setValue(pp->locallab.spots.at(index).lcdarkness); lclightness->setValue(pp->locallab.spots.at(index).lclightness); sensilc->setValue(pp->locallab.spots.at(index).sensilc); + fftwlc->set_active(pp->locallab.spots.at(index).fftwlc); // Contrast by detail levels expcbdl->setEnabled(pp->locallab.spots.at(index).expcbdl); @@ -5742,6 +5777,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con lcdarkness->setEditedState(spotState->lcdarkness ? Edited : UnEdited); lclightness->setEditedState(spotState->lclightness ? Edited : UnEdited); sensilc->setEditedState(spotState->sensilc ? Edited : UnEdited); + fftwlc->set_inconsistent(multiImage && !spotState->fftwlc); // Contrast by detail levels expcbdl->set_inconsistent(!spotState->expcbdl); diff --git a/rtgui/locallab.h b/rtgui/locallab.h index f1b2c7601..071fa274b 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -275,6 +275,10 @@ private: // Sharpening Gtk::CheckButton* const inverssha; sigc::connection inversshaConn; + //local contrast + Gtk::CheckButton* const fftwlc; + sigc::connection fftwlcConn; + //CBDL Gtk::CheckButton* const enacbMask; sigc::connection enacbMaskConn; @@ -367,6 +371,8 @@ private: void enaretiMasktmapChanged(); // Sharpening void inversshaChanged(); + // local contrast + void fftwlcChanged(); //CBDL void enacbMaskChanged(); // ComboBox event functions diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index cfd75f93c..bea8df75a 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1103,6 +1103,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).lcdarkness = locallab.spots.at(j).lcdarkness && pSpot.lcdarkness == otherSpot.lcdarkness; locallab.spots.at(j).lclightness = locallab.spots.at(j).lclightness && pSpot.lclightness == otherSpot.lclightness; locallab.spots.at(j).sensilc = locallab.spots.at(j).sensilc && pSpot.sensilc == otherSpot.sensilc; + locallab.spots.at(j).fftwlc = locallab.spots.at(j).fftwlc && pSpot.fftwlc == otherSpot.fftwlc; // Contrast by detail levels locallab.spots.at(j).expcbdl = locallab.spots.at(j).expcbdl && pSpot.expcbdl == otherSpot.expcbdl; @@ -3236,6 +3237,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).sensilc = mods.locallab.spots.at(i).sensilc; } + if (locallab.spots.at(i).fftwlc) { + toEdit.locallab.spots.at(i).fftwlc = mods.locallab.spots.at(i).fftwlc; + } + // Contrast by detail levels if (locallab.spots.at(i).expcbdl) { toEdit.locallab.spots.at(i).expcbdl = mods.locallab.spots.at(i).expcbdl; @@ -4481,6 +4486,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : lcdarkness(v), lclightness(v), sensilc(v), + fftwlc(v), // Contrast by detail levels expcbdl(v), mult{v, v, v, v, v, v}, @@ -4695,6 +4701,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) lcdarkness = v; lclightness = v; sensilc = v; + fftwlc = v; // Contrast by detail levels expcbdl = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 712cea64c..483dce085 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -530,6 +530,7 @@ public: bool lcdarkness; bool lclightness; bool sensilc; + bool fftwlc; // Contrast by detail levels bool expcbdl; bool mult[6];