diff --git a/rtdata/languages/default b/rtdata/languages/default index 243bfa079..fdf1ca707 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1449,6 +1449,7 @@ HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Local Contrast - Lightness HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift +HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation HISTORY_MSG_METADATA_MODE;Metadata copy mode HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold @@ -2958,6 +2959,7 @@ TP_LOCALLAB_EXP_TOOLNAME;Dynamic Range & Exposure TP_LOCALLAB_FATAMOUNT;Amount TP_LOCALLAB_FATANCHOR;Anchor TP_LOCALLAB_FATDETAIL;Detail +TP_LOCALLAB_FATSAT;Saturation control TP_LOCALLAB_FATFRA;Dynamic Range Compression ƒ TP_LOCALLAB_FATFRAME_TOOLTIP;PDE Fattal – uses the Fattal Tone-mapping algorithm. TP_LOCALLAB_FATLEVEL;Sigma diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 6abfc7aba..85661edd3 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -781,7 +781,7 @@ void Crop::update(int todo) if (need_fattal) { parent->ipf.dehaze(f, params.dehaze); - parent->ipf.ToneMapFattal02(f, params.fattal, 3, 0, nullptr, 0, 0, 0); + parent->ipf.ToneMapFattal02(f, params.fattal, 3, 0, nullptr, 0, 0, 0, false); } // crop back to the size expected by the rest of the pipeline diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 5a5dd12af..5358f2880 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -849,7 +849,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } ipf.dehaze(orig_prev, params->dehaze); - ipf.ToneMapFattal02(orig_prev, params->fattal, 3, 0, nullptr, 0, 0, 0); + ipf.ToneMapFattal02(orig_prev, params->fattal, 3, 0, nullptr, 0, 0, 0, false); if (oprevi != orig_prev) { delete oprevi; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index ea11e40bd..19d8b0a03 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -490,7 +490,7 @@ enum class BlurType { void dehaze(Imagefloat *rgb, const procparams::DehazeParams &dehazeParams); void dehazeloc(Imagefloat *rgb, const procparams::DehazeParams &dehazeParams); - void ToneMapFattal02(Imagefloat *rgb, const procparams::FattalToneMappingParams &fatParams, int detail_level, int Lalone, float **Lum, int WW, int HH, int algo); + void ToneMapFattal02(Imagefloat *rgb, const procparams::FattalToneMappingParams &fatParams, int detail_level, int Lalone, float **Lum, int WW, int HH, int algo, bool sat); void localContrast(LabImage *lab, float **destination, const procparams::LocalContrastParams &localContrastParams, bool fftwlc, double scale); void colorToningLabGrid(LabImage *lab, int xstart, int xend, int ystart, int yend, bool MultiThread); //void shadowsHighlights(LabImage *lab); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 75bb03267..5c7959225 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -6562,7 +6562,7 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int Imagefloat *tmpImagefat = nullptr; tmpImagefat = new Imagefloat(bfw, bfh); lab2rgb(*bufmaskblurcol, *tmpImagefat, params->icm.workingProfile); - ToneMapFattal02(tmpImagefat, fatParams, nlev, 0, nullptr, 0, 0, 0); + ToneMapFattal02(tmpImagefat, fatParams, nlev, 0, nullptr, 0, 0, 0, false); rgb2lab(*tmpImagefat, *bufmaskblurcol, params->icm.workingProfile); delete tmpImagefat; } @@ -8671,8 +8671,10 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in const float dE = rsob + std::sqrt(kab * (kch * chrodelta2 + kH * huedelta2) + kL * SQR(refL - maskptr->L[y][x])); //reduction action with deltaE - const float reducdE = calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, varsens); - + float reducdE = calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, varsens); + if(varsens == 100.f) { + reducdE = 1.f; + } float cli = (bufexpfin->L[y][x] - bufexporig->L[y][x]); float cla = (bufexpfin->a[y][x] - bufexporig->a[y][x]); float clb = (bufexpfin->b[y][x] - bufexporig->b[y][x]); @@ -17026,7 +17028,11 @@ void ImProcFunctions::Lab_Local( if(fatParams.anchor == 50.f) { alg = 1; } - ToneMapFattal02(tmpImagefat.get(), fatParams, 3, 0, nullptr, 0, 0, alg);//last parameter = 1 ==>ART algorithm + bool satu = false; + if(params->locallab.spots.at(sp).fatsatur) { + satu = true; + } + ToneMapFattal02(tmpImagefat.get(), fatParams, 3, 0, nullptr, 0, 0, alg, satu);//last parameter alg = 1 ==>ART algorithm rgb2lab(*tmpImagefat, *bufexpfin, params->icm.workingProfile); if (params->locallab.spots.at(sp).expcie && params->locallab.spots.at(sp).modecie == "dr") { bool HHcurvejz = false, CHcurvejz = false, LHcurvejz = false; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index f520c6507..72ee30a64 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -3348,6 +3348,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : gamm(0.4), fatamount(1.0), fatdetail(40.0), + fatsatur(false), fatanchor(50.0), fatlevel(1.), recothrese(1.), @@ -4827,6 +4828,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && gamm == other.gamm && fatamount == other.fatamount && fatdetail == other.fatdetail + && fatsatur == other.fatsatur && fatanchor == other.fatanchor && fatlevel == other.fatlevel && recothrese == other.recothrese @@ -6712,6 +6714,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->gamm, "Locallab", "Gamm_" + index_str, spot.gamm, keyFile); saveToKeyfile(!pedited || spot_edited->fatamount, "Locallab", "Fatamount_" + index_str, spot.fatamount, keyFile); saveToKeyfile(!pedited || spot_edited->fatdetail, "Locallab", "Fatdetail_" + index_str, spot.fatdetail, keyFile); + saveToKeyfile(!pedited || spot_edited->fatsatur, "Locallab", "Fatsatur_" + index_str, spot.fatsatur, keyFile); saveToKeyfile(!pedited || spot_edited->fatanchor, "Locallab", "Fatanchor_" + index_str, spot.fatanchor, keyFile); saveToKeyfile(!pedited || spot_edited->fatlevel, "Locallab", "Fatlevel_" + index_str, spot.fatlevel, keyFile); saveToKeyfile(!pedited || spot_edited->recothrese, "Locallab", "Recothrese_" + index_str, spot.recothrese, keyFile); @@ -8904,6 +8907,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Gamm_" + index_str, spot.gamm, spotEdited.gamm); assignFromKeyfile(keyFile, "Locallab", "Fatamount_" + index_str, spot.fatamount, spotEdited.fatamount); assignFromKeyfile(keyFile, "Locallab", "Fatdetail_" + index_str, spot.fatdetail, spotEdited.fatdetail); + assignFromKeyfile(keyFile, "Locallab", "Fatsatur_" + index_str, spot.fatsatur, spotEdited.fatsatur); assignFromKeyfile(keyFile, "Locallab", "Fatanchor_" + index_str, spot.fatanchor, spotEdited.fatanchor); assignFromKeyfile(keyFile, "Locallab", "Fatlevel_" + index_str, spot.fatlevel, spotEdited.fatlevel); assignFromKeyfile(keyFile, "Locallab", "Recothrese_" + index_str, spot.recothrese, spotEdited.recothrese); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 6e733e761..864937dc0 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1211,6 +1211,7 @@ struct LocallabParams { double gamm; double fatamount; double fatdetail; + bool fatsatur; double fatanchor; double fatlevel; double recothrese; diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 4337477da..95b1a24c9 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -1343,7 +1343,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT ipf.firstAnalysis (baseImg, params, hist16); ipf.dehaze(baseImg, params.dehaze); - ipf.ToneMapFattal02(baseImg, params.fattal, 3, 0, nullptr, 0, 0, 0); + ipf.ToneMapFattal02(baseImg, params.fattal, 3, 0, nullptr, 0, 0, 0, false); // perform transform int origFW; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index b82c7fe79..ad0ce9cc0 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -967,7 +967,7 @@ private: ipf.firstAnalysis(baseImg, params, hist16); ipf.dehaze(baseImg, params.dehaze); - ipf.ToneMapFattal02(baseImg, params.fattal, 3, 0, nullptr, 0, 0, 0); + ipf.ToneMapFattal02(baseImg, params.fattal, 3, 0, nullptr, 0, 0, 0, false); // perform transform (excepted resizing) if (ipf.needsTransform(fw, fh, imgsrc->getRotateDegree(), imgsrc->getMetaData())) { diff --git a/rtengine/tmo_fattal02.cc b/rtengine/tmo_fattal02.cc index f49fe9c53..50b795f61 100644 --- a/rtengine/tmo_fattal02.cc +++ b/rtengine/tmo_fattal02.cc @@ -84,7 +84,6 @@ namespace rtengine /****************************************************************************** * RT code ******************************************************************************/ - extern MyMutex *fftwMutex; using namespace std; @@ -310,7 +309,7 @@ float calculateGradients(Array2Df* H, Array2Df* G, int k, bool multithread) // however, the impact is not visible so we ignore this here (*G)(x, y) = sqrt(gx * gx + gy * gy) / divider; - avgGrad += static_cast((*G) (x, y)); + avgGrad += (*G) (x, y); } } @@ -378,6 +377,7 @@ void calculateFiMatrix(Array2Df* FI, Array2Df* gradients[], // only apply gradients to levels>=detail_level but at least to the coarsest if ((k >= detail_level || k == nlevels - 1) && beta != 1.f) { + const float a = alfa * avgGrad[k]; //DEBUG_STR << "calculateFiMatrix: apply gradient to level " << k << endl; #ifdef _OPENMP #pragma omp parallel for shared(fi,avgGrad) if(multithread) @@ -385,8 +385,7 @@ void calculateFiMatrix(Array2Df* FI, Array2Df* gradients[], for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { - float grad = ((*gradients[k]) (x, y) < 1e-4f) ? 1e-4f : (*gradients[k]) (x, y); - float a = alfa * avgGrad[k]; + float grad = ((*gradients[k]) (x, y) < 1e-4f) ? 1e-4 : (*gradients[k]) (x, y); float value = pow((grad + noise) / a, beta - 1.0f); (*fi[k])(x, y) *= value; @@ -470,7 +469,7 @@ void tmo_fattal02(size_t width, //paramet // find max value, normalize to range 0..100 and take logarithm // float minLum = Y (0, 0); - float maxLum = Y(0, 0); + float maxLum = Y(0, 0); #ifdef _OPENMP #pragma omp parallel for reduction(max:maxLum) if(multithread) @@ -482,7 +481,7 @@ void tmo_fattal02(size_t width, Array2Df* H = new Array2Df(width, height); float temp = 100.f / maxLum; - + float eps = 1e-4f; if (algo == 1) { temp = 1.f; } @@ -491,7 +490,6 @@ void tmo_fattal02(size_t width, #pragma omp parallel if(multithread) #endif { - const float eps = 1e-4f; #ifdef __SSE2__ const vfloat epsv = F2V(eps); const vfloat tempv = F2V(temp); @@ -567,9 +565,9 @@ void tmo_fattal02(size_t width, gradients[k] = new Array2Df(pyramids[k]->getCols(), pyramids[k]->getRows()); avgGrad[k] = calculateGradients(pyramids[k], gradients[k], k, multithread); - if (k != 0) { // pyramids[0] is H. Will be deleted later + if (k != 0) // pyramids[0] is H. Will be deleted later delete pyramids[k]; - } + } @@ -615,8 +613,8 @@ void tmo_fattal02(size_t width, // sets index+1 based on the boundary assumption H(N+1)=H(N-1) unsigned int xp1 = (x + 1 >= width ? width - 2 : x + 1); // forward differences in H, so need to use between-points approx of FI - (*Gx) (x, y) = ((*H) (xp1, y) - (*H) (x, y)) * 0.5f * ((*FI) (xp1, y) + (*FI) (x, y)); - (*Gy) (x, y) = ((*H) (x, yp1) - (*H) (x, y)) * 0.5f * ((*FI) (x, yp1) + (*FI) (x, y)); + (*Gx) (x, y) = ((*H) (xp1, y) - (*H) (x, y)) * 0.5 * ((*FI) (xp1, y) + (*FI) (x, y)); + (*Gy) (x, y) = ((*H) (x, yp1) - (*H) (x, y)) * 0.5 * ((*FI) (x, yp1) + (*FI) (x, y)); } } @@ -759,7 +757,7 @@ void transform_ev2normal(Array2Df *A, Array2Df *T, bool multithread) } for (int y = 1 ; y < height - 1 ; y++) { - (*A) (0, y) *= 0.5f; + (*A) (0, y) *= 0.5; (*A)(width - 1, y) *= 0.5f; } @@ -889,7 +887,7 @@ void solve_pde_fft(Array2Df *F, Array2Df *U, Array2Df *buf, bool multithread, in if (multithread) { fftwf_init_threads(); - fftwf_plan_with_nthreads(omp_get_max_threads()); + fftwf_plan_with_nthreads(omp_get_num_procs()); } // #else @@ -924,7 +922,7 @@ void solve_pde_fft(Array2Df *F, Array2Df *U, Array2Df *buf, bool multithread, in for (int y = 0 ; y < height ; y++) { for (int x = 0 ; x < width ; x++) { - (*F_tr) (x, y) = static_cast((*F_tr) (x, y)) / (l1[y] + l2[x]); + (*F_tr) (x, y) = (*F_tr) (x, y) / (l1[y] + l2[x]); } } @@ -932,7 +930,7 @@ void solve_pde_fft(Array2Df *F, Array2Df *U, Array2Df *buf, bool multithread, in // transforms F_tr back to the normal space transform_ev2normal(F_tr, U, multithread); - +/* // the solution U as calculated will satisfy something like int U = 0 // since for any constant c, U-c is also a solution and we are mainly // working in the logspace of (0,1) data we prefer to have @@ -957,6 +955,8 @@ void solve_pde_fft(Array2Df *F, Array2Df *U, Array2Df *buf, bool multithread, in (*U)(i) -= maxVal; } } + + */ } @@ -1064,7 +1064,7 @@ inline int find_fast_dim(int dim) } // namespace -void ImProcFunctions::ToneMapFattal02(Imagefloat *rgb, const FattalToneMappingParams &fatParams, int detail_level, int Lalone, float **Lum, int WW, int HH, int algo) +void ImProcFunctions::ToneMapFattal02(Imagefloat *rgb, const FattalToneMappingParams &fatParams, int detail_level, int Lalone, float **Lum, int WW, int HH, int algo, bool sat) //algo allows to use ART algorithme algo = 0 RT, algo = 1 ART //Lalone allows to use L without RGB values in RT mode { @@ -1073,7 +1073,7 @@ void ImProcFunctions::ToneMapFattal02(Imagefloat *rgb, const FattalToneMappingPa } BENCHFUN -// const int detail_level = 3; + // const int detail_level = 3; float alpha = 1.f; @@ -1137,7 +1137,7 @@ void ImProcFunctions::ToneMapFattal02(Imagefloat *rgb, const FattalToneMappingPa Array2Df L(w2, h2); { #ifdef _OPENMP - int num_threads = multiThread ? omp_get_max_threads() : 1; + int num_threads = multiThread ? omp_get_num_procs() : 1; #else int num_threads = 1; #endif @@ -1224,16 +1224,18 @@ void ImProcFunctions::ToneMapFattal02(Imagefloat *rgb, const FattalToneMappingPa } + const bool satcontrol = sat; + #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if(multiThread) #endif for (int y = 0; y < h; y++) { - int yy = y * hr + 1; + int yy = std::min(int(y * hr + 1), h2-1); for (int x = 0; x < w; x++) { - int xx = x * wr + 1; + int xx = std::min(int(x * wr + 1), w2-1); float Y = std::max(Yr(x, y), epsilon); float l = std::max(L(xx, yy), epsilon) * (scale / Y); @@ -1242,15 +1244,33 @@ void ImProcFunctions::ToneMapFattal02(Imagefloat *rgb, const FattalToneMappingPa float &r = rgb->r(y, x); float &g = rgb->g(y, x); float &b = rgb->b(y, x); + float s = 1.f; if(l > 1.f) { r = max(r * l - offset, r); g = max(g * l - offset, g); b = max(b * l - offset, b); + if (satcontrol) { + s = pow_F(1.f / l, 0.3f); + } } else { r *= l; g *= l; b *= l; + if (satcontrol) { + s = pow_F(l, 0.3f); + } } + + if (satcontrol && s != 1.f) { + float ll = luminance(r, g, b, ws); + float rl = r - ll; + float gl = g - ll; + float bl = b - ll; + r = ll + s * rl; + g = ll + s * gl; + b = ll + s * bl; + } + assert(std::isfinite(rgb->r(y, x))); assert(std::isfinite(rgb->g(y, x))); assert(std::isfinite(rgb->b(y, x))); diff --git a/rtgui/locallabtools.cc b/rtgui/locallabtools.cc index 562cbf674..f659d3dfd 100644 --- a/rtgui/locallabtools.cc +++ b/rtgui/locallabtools.cc @@ -2568,6 +2568,7 @@ LocallabExposure::LocallabExposure(): expfat(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_FATFRA")))), fatamount(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FATAMOUNT"), 1., 100., 1., 1.))), fatdetail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FATDETAIL"), -100., 300., 1., 0.))), + fatsatur(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_FATSAT")))), norm(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_EQUIL")))), fatlevel(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FATLEVEL"), 0.5, 2.0, 0.01, 1.))), fatanchor(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FATANCHOR"), 0.1, 100.0, 0.01, 50., Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), @@ -2617,7 +2618,9 @@ LocallabExposure::LocallabExposure(): strmaskexp(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADSTR"), -2., 2., 0.05, 0.))), angmaskexp(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADANG"), -180., 180., 0.1, 0.))), mask2expCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK2"))), - Lmaskexpshape(static_cast(mask2expCurveEditorG->addCurve(CT_Diagonal, "L(L)"))) + Lmaskexpshape(static_cast(mask2expCurveEditorG->addCurve(CT_Diagonal, "L(L)"))), + Evlocallabtmosatur(ProcEventMapper::getInstance()->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_TMO_SATUR")) + { set_orientation(Gtk::ORIENTATION_VERTICAL); @@ -2705,6 +2708,7 @@ LocallabExposure::LocallabExposure(): decaye->setAdjusterListener(this); setExpandAlignProperties(exprecove, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); normConn = norm->signal_toggled().connect(sigc::mem_fun(*this, &LocallabExposure::normChanged)); + fatsaturConn = fatsatur->signal_toggled().connect(sigc::mem_fun(*this, &LocallabExposure::fatsaturChanged)); inversexConn = inversex->signal_toggled().connect(sigc::mem_fun(*this, &LocallabExposure::inversexChanged)); inversex->set_tooltip_text(M("TP_LOCALLAB_INVERS_TOOLTIP")); @@ -2799,6 +2803,7 @@ LocallabExposure::LocallabExposure(): // fatBox->pack_start(*norm); // fatBox->pack_start(*fatlevel); fatBox->pack_start(*fatanchor); + fatBox->pack_start(*fatsatur); // fatFrame->add(*fatBox); expfat->add(*fatBox, false); // pack_start(*fatFrame); @@ -2985,6 +2990,7 @@ void LocallabExposure::disableListener() exnoiseMethodConn.block(true); inversexConn.block(true); normConn.block(true); + fatsaturConn.block(true); showmaskexpMethodConn.block(true); showmaskexpMethodConninv.block(true); enaExpMaskConn.block(true); @@ -2999,6 +3005,7 @@ void LocallabExposure::enableListener() exnoiseMethodConn.block(false); inversexConn.block(false); normConn.block(false); + fatsaturConn.block(false); showmaskexpMethodConn.block(false); showmaskexpMethodConninv.block(false); enaExpMaskConn.block(false); @@ -3084,6 +3091,7 @@ void LocallabExposure::read(const rtengine::procparams::ProcParams* pp, const Pa angexp->setValue(spot.angexp); softradiusexp->setValue(spot.softradiusexp); norm->set_active(spot.norm); + fatsatur->set_active(spot.fatsatur); inversex->set_active(spot.inversex); enaExpMask->set_active(spot.enaExpMask); enaExpMaskaft->set_active(spot.enaExpMaskaft); @@ -3175,6 +3183,7 @@ void LocallabExposure::write(rtengine::procparams::ProcParams* pp, ParamsEdited* spot.softradiusexp = softradiusexp->getValue(); spot.inversex = inversex->get_active(); spot.norm = norm->get_active(); + spot.fatsatur = fatsatur->get_active(); spot.enaExpMask = enaExpMask->get_active(); spot.enaExpMaskaft = enaExpMaskaft->get_active(); spot.CCmaskexpcurve = CCmaskexpshape->getCurve(); @@ -3780,6 +3789,21 @@ void LocallabExposure::normChanged() } } +void LocallabExposure::fatsaturChanged() +{ + + if (isLocActivated && exp->getEnabled()) { + if (listener) { + if (fatsatur->get_active()) { + listener->panelChanged(Evlocallabtmosatur, + M("GENERAL_ENABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } else { + listener->panelChanged(Evlocallabtmosatur, + M("GENERAL_DISABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + } +} void LocallabExposure::inversexChanged() { diff --git a/rtgui/locallabtools.h b/rtgui/locallabtools.h index 1664d1839..f98007e84 100644 --- a/rtgui/locallabtools.h +++ b/rtgui/locallabtools.h @@ -345,6 +345,7 @@ private: MyExpander* const expfat; Adjuster* const fatamount; Adjuster* const fatdetail; + Gtk::CheckButton* const fatsatur; Gtk::CheckButton* const norm; Adjuster* const fatlevel; Adjuster* const fatanchor; @@ -395,8 +396,9 @@ private: Adjuster* const angmaskexp; CurveEditorGroup* const mask2expCurveEditorG; DiagonalCurveEditor* const Lmaskexpshape; + rtengine::ProcEvent Evlocallabtmosatur; - sigc::connection expMethodConn, exnoiseMethodConn, inversexConn, normConn, showmaskexpMethodConn, showmaskexpMethodConninv, enaExpMaskConn, enaExpMaskaftConn; + sigc::connection expMethodConn, exnoiseMethodConn, inversexConn, normConn, fatsaturConn, showmaskexpMethodConn, showmaskexpMethodConninv, enaExpMaskConn, enaExpMaskaftConn; public: LocallabExposure(); @@ -429,6 +431,7 @@ private: void exnoiseMethodChanged(); void inversexChanged(); void normChanged(); + void fatsaturChanged(); void showmaskexpMethodChanged(); void showmaskexpMethodChangedinv(); void enaExpMaskChanged(); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 9b039eb66..6a68e36ca 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1265,6 +1265,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).gamm = locallab.spots.at(j).gamm && pSpot.gamm == otherSpot.gamm; locallab.spots.at(j).fatamount = locallab.spots.at(j).fatamount && pSpot.fatamount == otherSpot.fatamount; locallab.spots.at(j).fatdetail = locallab.spots.at(j).fatdetail && pSpot.fatdetail == otherSpot.fatdetail; + locallab.spots.at(j).fatsatur = locallab.spots.at(j).fatsatur && pSpot.fatsatur == otherSpot.fatsatur; locallab.spots.at(j).fatanchor = locallab.spots.at(j).fatanchor && pSpot.fatanchor == otherSpot.fatanchor; locallab.spots.at(j).fatlevel = locallab.spots.at(j).fatlevel && pSpot.fatlevel == otherSpot.fatlevel; locallab.spots.at(j).recothrese = locallab.spots.at(j).recothrese && pSpot.recothrese == otherSpot.recothrese; @@ -4108,6 +4109,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).fatdetail = mods.locallab.spots.at(i).fatdetail; } + if (locallab.spots.at(i).fatsatur) { + toEdit.locallab.spots.at(i).fatsatur = mods.locallab.spots.at(i).fatsatur; + } + if (locallab.spots.at(i).fatanchor) { toEdit.locallab.spots.at(i).fatanchor = mods.locallab.spots.at(i).fatanchor; } @@ -7665,6 +7670,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : fatdetail(v), fatanchor(v), fatlevel(v), + fatsatur(v), recothrese(v), lowthrese(v), higthrese(v), @@ -8355,6 +8361,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) gamm = v; fatamount = v; fatdetail = v; + fatsatur = v; fatanchor = v; fatlevel = v; recothrese = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index d5b082a90..00ace3b3e 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -567,6 +567,7 @@ public: bool fatdetail; bool fatanchor; bool fatlevel; + bool fatsatur; bool recothrese; bool lowthrese; bool higthrese;