Dynamic Range Compression Improvement (5.10) (#6943)

* Improve Dynamic Range Compression - for some images with very high DR

* Clean code

* Improve TM fattal with saturation control in LA

* Saturation control fattal in LA

* Re-order paramsedit

* Change history_msg_tmo_satur with saturation

---------

Co-authored-by: U-PCSPECIALIST01\jdesm <jdesmis@gmail.com>
This commit is contained in:
Lawrence37 2024-02-04 15:38:04 -08:00 committed by GitHub
parent f06e756c20
commit 0d0834cbe7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 99 additions and 31 deletions

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -1211,6 +1211,7 @@ struct LocallabParams {
double gamm;
double fatamount;
double fatdetail;
bool fatsatur;
double fatanchor;
double fatlevel;
double recothrese;

View File

@ -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;

View File

@ -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())) {

View File

@ -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<double>((*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;
@ -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<double>((*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
{
@ -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)));

View File

@ -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<DiagonalCurveEditor*>(mask2expCurveEditorG->addCurve(CT_Diagonal, "L(L)")))
Lmaskexpshape(static_cast<DiagonalCurveEditor*>(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()
{

View File

@ -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();

View File

@ -1265,6 +1265,7 @@ void ParamsEdited::initFrom(const std::vector<rtengine::procparams::ProcParams>&
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;

View File

@ -567,6 +567,7 @@ public:
bool fatdetail;
bool fatanchor;
bool fatlevel;
bool fatsatur;
bool recothrese;
bool lowthrese;
bool higthrese;