Selective Editing - Avoid negatives values - see on Pixls.us (#7319)

* Avoid negatives values input SE with CBDL Dehaze and SE Settings

* Change appimage and windows yml with Rawtherapee:avoidneg

* Change Rawtherapee by Beep6581 for yml windows

* Change Rawtherapee by Beep6581 in Appimage yml

* Limits negatives values control to cbdl before

* Changes suggested by Lawrence37

* Change in code, labels and history Avoid zero and negative values to Pre-filter zero and negative values
This commit is contained in:
Desmis 2025-03-02 07:43:18 +01:00 committed by GitHub
parent f8e7db3d86
commit 69b311b5b4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 99 additions and 4 deletions

View File

@ -15,7 +15,7 @@ on:
workflow_dispatch:
env:
publish_pre_dev_labels: '[]'
publish_pre_dev_labels: '["Beep6581:avoidneg"]'
jobs:
build:

View File

@ -15,7 +15,7 @@ on:
workflow_dispatch:
env:
publish_pre_dev_labels: '[]'
publish_pre_dev_labels: '["Beep6581:avoidneg"]'
jobs:

View File

@ -1488,6 +1488,7 @@ HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method
HISTORY_MSG_ICM_WORKING_SLOPE;TRC - Slope
HISTORY_MSG_ICM_WORKING_TRC_METHOD;TRC method
HISTORY_MSG_ILLUM;CAL - SC - Illuminant
HISTORY_MSG_LOCAL_AVOIDNEGATIVE;Local - SC - Pre-filter zero and negative values
HISTORY_MSG_LOCAL_CIE_CONTSIG;Local CIECAM - Sigmoid contrast
HISTORY_MSG_LOCAL_CIE_SKEWSIG;Local CIECAM - Sigmoid skew
HISTORY_MSG_LOCAL_CIE_SMOOTHTH;Local CIECAM - Attenuation threshold
@ -2997,6 +2998,7 @@ TP_LOCALLAB_AVOID;Avoid color shift
TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). Default: Munsell only.\n\nMunsell only: Fixes Lab mode hue drifts due to non-linearity when chromaticity is changed (Uniform Perceptual Lab).\nLab: Applies a gamut control in relative colorimetric. Munsell is then applied.\nXYZ Absolute: Applies gamut control in absolute colorimetric. Munsell is then applied.\nXYZ Relative: Applies gamut control in relative colorimetric. Munsell is then applied. The result is not the same as Lab.
TP_LOCALLAB_AVOIDMUN;Munsell correction only
TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used.
TP_LOCALLAB_AVOIDNEG;Pre-filter zero and negative values
TP_LOCALLAB_AVOIDRAD;Soft radius
TP_LOCALLAB_BALAN;ab-L balance (ΔE)
TP_LOCALLAB_BALANEXP;Laplacian balance

View File

@ -843,6 +843,7 @@ struct local_params {
float residhithr;
float residgam;
float residslop;
bool avoidneg;
bool blwh;
bool fftma;
float blurma;
@ -1892,6 +1893,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall
lp.residhithr = locallab.spots.at(sp).residhithr;
lp.residgam = locallab.spots.at(sp).residgam;
lp.residslop = locallab.spots.at(sp).residslop;
lp.avoidneg = locallab.spots.at(sp).avoidneg;
lp.blwh = locallab.spots.at(sp).blwh;
lp.senscolor = (int) locallab.spots.at(sp).colorscope;
//replace scope color vibrance shadows
@ -14276,13 +14278,46 @@ void ImProcFunctions::Lab_Local(
return;
}
//BENCHFUN
constexpr int del = 3; // to avoid crash with [loy - begy] and [lox - begx] and bfh bfw // with gtk2 [loy - begy-1] [lox - begx -1 ] and del = 1
struct local_params lp;
calcLocalParams(sp, oW, oH, params->locallab, lp, prevDeltaE, llColorMask, llColorMaskinv, llExpMask, llExpMaskinv, llSHMask, llSHMaskinv, llvibMask, lllcMask, llsharMask, llcbMask, llretiMask, llsoftMask, lltmMask, llblMask, lllogMask, ll_Mask, llcieMask, locwavCurveden, locwavdenutili);
//avoidcolshi(lp, sp, transformed, reserved, cy, cx, sk);
//BENCHFUN
//Pre-filter zero and negative values RGB then Lab when using before SE CBDL or Dehaze, or processor type...
int bw0 = transformed->W;
int bh0 = transformed->H;
float epsi0 = 0.000001f;
bool nocrash = false;
bool cbdl = false;
if(params->dirpyrequalizer.cbdlMethod == "bef") {//If user choose "after black and white" this function which removes negative values is not used, hence CBDL is best performed, after Selective Editing in Lab mode
cbdl = true;
}
nocrash = (params->dirpyrequalizer.enabled && cbdl) || params->dehaze.enabled || lp.avoidneg;//lp.avoidneg in setting
if(nocrash) {//allows memory and conversion labrgb only in these cases and prevent negative RGB values
const std::unique_ptr<Imagefloat> prov0(new Imagefloat(bw0, bh0));
lab2rgb(*transformed, *prov0, params->icm.workingProfile);
#ifdef _OPENMP
#pragma omp parallel for
#endif
for (int i = 0; i < bh0; ++i)
for (int j = 0; j < bw0; ++j) {
prov0->r(i, j) = (rtengine::max(prov0->r(i, j), epsi0));
prov0->g(i, j) = (rtengine::max(prov0->g(i, j), epsi0));
prov0->b(i, j) = (rtengine::max(prov0->b(i, j), epsi0));
}
rgb2lab(*prov0, *transformed, params->icm.workingProfile);
}
const float radius = lp.rad / (sk * 1.4); //0 to 70 ==> see skip
int levred;
@ -21083,7 +21118,6 @@ void ImProcFunctions::Lab_Local(
float epsi = 0.000001f;
if((lp.laplacexp > 1.f && lp.exposena) || (lp.strng > 2.f && lp.sfena) || (lp.exposena && lp.expcomp != 0.f && params->dirpyrequalizer.enabled)){//strong Laplacian
notlaplacian = true;
}

View File

@ -3317,6 +3317,7 @@ LocallabParams::LocallabSpot::LocallabSpot() :
transitgrad(0.0),
hishow(options.complexity != 2),
activ(true),
avoidneg(true),
blwh(false),
recurs(false),
laplac(true),
@ -5219,6 +5220,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const
&& transitgrad == other.transitgrad
&& hishow == other.hishow
&& activ == other.activ
&& avoidneg == other.avoidneg
&& blwh == other.blwh
&& recurs == other.recurs
&& laplac == other.laplac
@ -7226,6 +7228,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
saveToKeyfile(!pedited || spot_edited->transitgrad, "Locallab", "Transitgrad_" + index_str, spot.transitgrad, keyFile);
saveToKeyfile(!pedited || spot_edited->hishow, "Locallab", "Hishow_" + index_str, spot.hishow, keyFile);
saveToKeyfile(!pedited || spot_edited->activ, "Locallab", "Activ_" + index_str, spot.activ, keyFile);
saveToKeyfile(!pedited || spot_edited->avoidneg, "Locallab", "Avoidneg_" + index_str, spot.avoidneg, keyFile);
saveToKeyfile(!pedited || spot_edited->blwh, "Locallab", "Blwh_" + index_str, spot.blwh, keyFile);
saveToKeyfile(!pedited || spot_edited->recurs, "Locallab", "Recurs_" + index_str, spot.recurs, keyFile);
saveToKeyfile(!pedited || spot_edited->laplac, "Locallab", "Laplac_" + index_str, spot.laplac, keyFile);
@ -9560,6 +9563,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
assignFromKeyfile(keyFile, "Locallab", "Transitgrad_" + index_str, spot.transitgrad, spotEdited.transitgrad);
assignFromKeyfile(keyFile, "Locallab", "Hishow_" + index_str, spot.hishow, spotEdited.hishow);
assignFromKeyfile(keyFile, "Locallab", "Activ_" + index_str, spot.activ, spotEdited.activ);
assignFromKeyfile(keyFile, "Locallab", "Avoidneg_" + index_str, spot.avoidneg, spotEdited.avoidneg);
assignFromKeyfile(keyFile, "Locallab", "Blwh_" + index_str, spot.blwh, spotEdited.blwh);
assignFromKeyfile(keyFile, "Locallab", "Recurs_" + index_str, spot.recurs, spotEdited.recurs);
assignFromKeyfile(keyFile, "Locallab", "Laplac_" + index_str, spot.laplac, spotEdited.laplac);

View File

@ -1118,6 +1118,7 @@ struct LocallabParams {
double transitgrad;
bool hishow;
bool activ;
bool avoidneg;
bool blwh;
bool recurs;
bool laplac;

View File

@ -86,6 +86,7 @@ ControlSpotPanel::ControlSpotPanel():
hishow_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_PREVSHOW")))),
activ_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ACTIVSPOT")))),
avoidneg_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_AVOIDNEG")))),
blwh_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_BLWH")))),
recurs_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_RECURS")))),
laplac_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_LAPLACC")))),
@ -118,6 +119,7 @@ ControlSpotPanel::ControlSpotPanel():
{
auto m = ProcEventMapper::getInstance();
EvLocallabavoidgamutMethod = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_GAMUTMUNSEL");
EvLocallabavoidnegative = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_AVOIDNEGATIVE");
const bool showtooltip = options.showtooltip;
// pack_start(*hishow_);
@ -430,6 +432,8 @@ ControlSpotPanel::ControlSpotPanel():
avFrame->add(*avbox);
specCaseBox->pack_start(*avFrame);
avoidnegConn_ = avoidneg_->signal_toggled().connect(
sigc::mem_fun(*this, &ControlSpotPanel::avoidnegChanged));
blwhConn_ = blwh_->signal_toggled().connect(
sigc::mem_fun(*this, &ControlSpotPanel::blwhChanged));
@ -439,6 +443,7 @@ ControlSpotPanel::ControlSpotPanel():
}
specCaseBox->pack_start(*blwh_);
specCaseBox->pack_start(*avoidneg_);
recursConn_ = recurs_->signal_toggled().connect(
sigc::mem_fun(*this, &ControlSpotPanel::recursChanged));
@ -871,6 +876,7 @@ void ControlSpotPanel::load_ControlSpot_param()
avoidrad_->setValue((double)row[spots_.avoidrad]);
hishow_->set_active(row[spots_.hishow]);
activ_->set_active(row[spots_.activ]);
avoidneg_->set_active(row[spots_.avoidneg]);
blwh_->set_active(row[spots_.blwh]);
recurs_->set_active(row[spots_.recurs]);
// laplac_->set_active(row[spots_.laplac]);
@ -1768,6 +1774,31 @@ void ControlSpotPanel::activChanged()
}
}
void ControlSpotPanel::avoidnegChanged()
{
// Get selected control spot
const auto s = treeview_->get_selection();
if (!s->count_selected_rows()) {
return;
}
const auto iter = s->get_selected();
Gtk::TreeModel::Row row = *iter;
row[spots_.avoidneg] = avoidneg_->get_active();
// Raise event
if (listener) {
if (avoidneg_->get_active()) {
listener->panelChanged(EvLocallabavoidnegative, M("GENERAL_ENABLED"));
} else {
listener->panelChanged(EvLocallabavoidnegative, M("GENERAL_DISABLED"));
}
}
}
void ControlSpotPanel::blwhChanged()
{
@ -1963,6 +1994,7 @@ void ControlSpotPanel::disableParamlistener(bool cond)
avoidrad_->block(cond);
hishowconn_.block(cond);
activConn_.block(cond);
avoidnegConn_.block(cond);
blwhConn_.block(cond);
recursConn_.block(cond);
laplacConn_.block(cond);
@ -2010,6 +2042,7 @@ void ControlSpotPanel::setParamEditable(bool cond)
avoidrad_->set_sensitive(cond);
hishow_->set_sensitive(cond);
activ_->set_sensitive(cond);
avoidneg_->set_sensitive(cond);
blwh_->set_sensitive(cond);
recurs_->set_sensitive(cond);
laplac_->set_sensitive(cond);
@ -2698,6 +2731,7 @@ std::unique_ptr<ControlSpotPanel::SpotRow> ControlSpotPanel::getSpot(const int i
r->lumask = row[spots_.lumask];
r->hishow = row[spots_.hishow];
r->activ = row[spots_.activ];
r->avoidneg = row[spots_.avoidneg];
r->blwh = row[spots_.blwh];
r->recurs = row[spots_.recurs];
r->laplac = row[spots_.laplac];
@ -2830,6 +2864,7 @@ void ControlSpotPanel::addControlSpot(const SpotRow &newSpot)
row[spots_.avoidrad] = newSpot.avoidrad;
row[spots_.hishow] = newSpot.hishow;
row[spots_.activ] = newSpot.activ;
row[spots_.avoidneg] = newSpot.avoidneg;
row[spots_.blwh] = newSpot.blwh;
row[spots_.recurs] = newSpot.recurs;
row[spots_.laplac] = newSpot.laplac;
@ -2999,6 +3034,7 @@ ControlSpotPanel::ControlSpots::ControlSpots()
add(avoidrad);
add(hishow);
add(activ);
add(avoidneg);
add(blwh);
add(recurs);
add(laplac);

View File

@ -82,6 +82,7 @@ public:
double avoidrad;
bool hishow;
bool activ;
bool avoidneg;
bool blwh;
bool recurs;
bool laplac;
@ -261,6 +262,7 @@ private:
void hishowChanged();
void activChanged();
void avoidnegChanged();
void blwhChanged();
void recursChanged();
void laplacChanged();
@ -323,6 +325,7 @@ private:
Gtk::TreeModelColumn<double> avoidrad;
Gtk::TreeModelColumn<bool> hishow;
Gtk::TreeModelColumn<bool> activ;
Gtk::TreeModelColumn<bool> avoidneg;
Gtk::TreeModelColumn<bool> blwh;
Gtk::TreeModelColumn<bool> recurs;
Gtk::TreeModelColumn<bool> laplac;
@ -354,6 +357,7 @@ private:
ControlSpots spots_;
rtengine::ProcEvent EvLocallabavoidgamutMethod;
rtengine::ProcEvent EvLocallabavoidnegative;
// Child widgets
Gtk::ScrolledWindow* const scrolledwindow_;
@ -420,6 +424,8 @@ private:
sigc::connection hishowconn_;
Gtk::CheckButton* const activ_;
sigc::connection activConn_;
Gtk::CheckButton* const avoidneg_;
sigc::connection avoidnegConn_;
Gtk::CheckButton* const blwh_;
sigc::connection blwhConn_;
Gtk::CheckButton* const recurs_;

View File

@ -344,6 +344,7 @@ void Locallab::read(const rtengine::procparams::ProcParams* pp, const ParamsEdit
r.avoidrad = pp->locallab.spots.at(i).avoidrad;
r.hishow = pp->locallab.spots.at(i).hishow;
r.activ = pp->locallab.spots.at(i).activ;
r.avoidneg = pp->locallab.spots.at(i).avoidneg;
r.blwh = pp->locallab.spots.at(i).blwh;
r.recurs = pp->locallab.spots.at(i).recurs;
r.laplac = true; //pp->locallab.spots.at(i).laplac;
@ -539,6 +540,7 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited
r.avoidrad = newSpot->avoidrad;
r.hishow = newSpot->hishow;
r.activ = newSpot->activ;
r.avoidneg = newSpot->avoidneg;
r.blwh = newSpot->blwh;
r.recurs = newSpot->recurs;
r.laplac = newSpot->laplac;
@ -879,6 +881,7 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited
r.avoidrad = newSpot->avoidrad;
r.hishow = newSpot->hishow;
r.activ = newSpot->activ;
r.avoidneg = newSpot->avoidneg;
r.blwh = newSpot->blwh;
r.recurs = newSpot->recurs;
r.laplac = newSpot->laplac;
@ -1051,6 +1054,7 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited
pp->locallab.spots.at(pp->locallab.selspot).avoidrad = r->avoidrad;
pp->locallab.spots.at(pp->locallab.selspot).hishow = r->hishow;
pp->locallab.spots.at(pp->locallab.selspot).activ = r->activ;
pp->locallab.spots.at(pp->locallab.selspot).avoidneg = r->avoidneg;
pp->locallab.spots.at(pp->locallab.selspot).blwh = r->blwh;
pp->locallab.spots.at(pp->locallab.selspot).recurs = r->recurs;
pp->locallab.spots.at(pp->locallab.selspot).laplac = r->laplac;

View File

@ -1317,6 +1317,7 @@ void ParamsEdited::initFrom(const std::vector<rtengine::procparams::ProcParams>&
locallab.spots.at(j).transitgrad = locallab.spots.at(j).transitgrad && pSpot.transitgrad == otherSpot.transitgrad;
locallab.spots.at(j).hishow = locallab.spots.at(j).hishow && pSpot.hishow == otherSpot.hishow;
locallab.spots.at(j).activ = locallab.spots.at(j).activ && pSpot.activ == otherSpot.activ;
locallab.spots.at(j).avoidneg = locallab.spots.at(j).avoidneg && pSpot.avoidneg == otherSpot.avoidneg;
locallab.spots.at(j).blwh = locallab.spots.at(j).blwh && pSpot.blwh == otherSpot.blwh;
locallab.spots.at(j).recurs = locallab.spots.at(j).recurs && pSpot.recurs == otherSpot.recurs;
locallab.spots.at(j).laplac = locallab.spots.at(j).laplac && pSpot.laplac == otherSpot.laplac;
@ -3966,6 +3967,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
toEdit.locallab.spots.at(i).activ = mods.locallab.spots.at(i).activ;
}
if (locallab.spots.at(i).avoidneg) {
toEdit.locallab.spots.at(i).avoidneg = mods.locallab.spots.at(i).avoidneg;
}
if (locallab.spots.at(i).blwh) {
toEdit.locallab.spots.at(i).blwh = mods.locallab.spots.at(i).blwh;
}
@ -8338,6 +8343,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) :
transitgrad(v),
hishow(v),
activ(v),
avoidneg(v),
blwh(v),
recurs(v),
laplac(v),
@ -9123,6 +9129,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v)
transitgrad = v;
hishow = v;
activ = v;
avoidneg = v;
blwh = v;
recurs = v;
laplac = v;

View File

@ -458,6 +458,7 @@ public:
bool transitgrad;
bool hishow;
bool activ;
bool avoidneg;
bool blwh;
bool recurs;
bool laplac;