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:
parent
f8e7db3d86
commit
69b311b5b4
2
.github/workflows/appimage.yml
vendored
2
.github/workflows/appimage.yml
vendored
@ -15,7 +15,7 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
publish_pre_dev_labels: '[]'
|
||||
publish_pre_dev_labels: '["Beep6581:avoidneg"]'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
2
.github/workflows/windows.yml
vendored
2
.github/workflows/windows.yml
vendored
@ -15,7 +15,7 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
publish_pre_dev_labels: '[]'
|
||||
publish_pre_dev_labels: '["Beep6581:avoidneg"]'
|
||||
|
||||
|
||||
jobs:
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -1118,6 +1118,7 @@ struct LocallabParams {
|
||||
double transitgrad;
|
||||
bool hishow;
|
||||
bool activ;
|
||||
bool avoidneg;
|
||||
bool blwh;
|
||||
bool recurs;
|
||||
bool laplac;
|
||||
|
@ -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);
|
||||
|
@ -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_;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -458,6 +458,7 @@ public:
|
||||
bool transitgrad;
|
||||
bool hishow;
|
||||
bool activ;
|
||||
bool avoidneg;
|
||||
bool blwh;
|
||||
bool recurs;
|
||||
bool laplac;
|
||||
|
Loading…
x
Reference in New Issue
Block a user