diff --git a/rtdata/languages/default b/rtdata/languages/default index 790e334de..16322be7a 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1039,6 +1039,7 @@ HISTORY_MSG_798;Local - Merge Original method HISTORY_MSG_799;Local - Opacity HISTORY_MSG_800;Local - Color RGB ToneCurve HISTORY_MSG_801;Local - Color ToneCurve Method +HISTORY_MSG_802;Local - Color ToneCurve Special HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -2219,6 +2220,7 @@ TP_LOCALLAB_LAPLACE;Laplacian threshold deltaE TP_LOCALLAB_LINEAR;Linearity TP_LOCALLAB_HLH;Curves H TP_LOCALLAB_RGB;RGB Tone Curve +TP_LOCALLAB_SPECIAL;Special use of RGB curves TP_LOCALLAB_EQUIL;Normalize Luminance TP_LOCALLAB_CHROMACBDL;Chroma TP_LOCALLAB_CHROMACB_TOOLTIP;Acts as an amplifier-reducer action compare to sliders of luminance.\nUnder 100 reduce, above 100 amplifie diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index b3b81d636..1fcbb8184 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -11580,6 +11580,8 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o const int bfh = yend - ystart; const int bfw = xend - xstart; bool HHcurve = false; + bool usergb = false; + bool spez = params->locallab.spots.at(sp).special; if (bfw >= mSP && bfh >= mSP) { std::unique_ptr bufcolorig; @@ -11776,7 +11778,6 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o //RGB Curves - bool usergb = false; if (rgblocalcurve && localrgbutili && lp.qualcurvemet != 0) { usergb = true; @@ -11885,6 +11886,39 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o // end rgb curves } + + + if (usergb && spez) {//special use of rgb curves ex : negative +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int y = 0; y < bfh; y++) { + const int loy = y + ystart + cy; + + for (int x = 0; x < bfw; x++) { + const int lox = x + xstart + cx; + int zone = 0; + float localFactor = 1.f; + const float achm = (float)lp.trans / 100.f; + + if (lp.shapmet == 0) { + calcTransition(lox, loy, achm, lp, zone, localFactor); + } else if (lp.shapmet == 1) { + calcTransitionrect(lox, loy, achm, lp, zone, localFactor); + } + + if (zone > 0) { + transformed->L[y + ystart][x + xstart] = buftemp->L[y][x] * localFactor + (1.f - localFactor) * original->L[y + ystart][x + xstart]; + transformed->a[y + ystart][x + xstart] = buftemp->a[y][x] * localFactor + (1.f - localFactor) * original->a[y + ystart][x + xstart]; + transformed->b[y + ystart][x + xstart] = buftemp->b[y][x] * localFactor + (1.f - localFactor) * original->b[y + ystart][x + xstart]; + } + } + } + + } + + //others curves float chprosl = 1.f; @@ -12320,7 +12354,9 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o } //bufcolfin add for merge - transit_shapedetect(smerge, bufcolorig.get(), bufcolfin.get(), originalmaskcol.get(), buflight, bufchro, buf_a, buf_b, bufhh, HHcurve, hueref, chromaref, lumaref, sobelref, meansob, temp, lp, original, transformed, cx, cy, sk); + if (!(usergb && spez)) { + transit_shapedetect(smerge, bufcolorig.get(), bufcolfin.get(), originalmaskcol.get(), buflight, bufchro, buf_a, buf_b, bufhh, HHcurve, hueref, chromaref, lumaref, sobelref, meansob, temp, lp, original, transformed, cx, cy, sk); + } if (params->locallab.spots.at(sp).recurs) { original->CopyFrom(transformed); diff --git a/rtengine/procevents.h b/rtengine/procevents.h index e14a69ca5..55ee0de75 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -824,6 +824,7 @@ enum ProcEventCode { Evlocallabopacol = 798, Evlocallabrgbshape = 799, EvLocallabtoneMethod = 800, + EvLocallabspecial = 801, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 01a6f2827..79cb2fc55 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2476,6 +2476,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : LHcurve{(double)FCT_MinMaxCPoints, 0.0, 0.50, 0.35, 0.35, 0.166, 0.50, 0.35, 0.35, 0.333, 0.50, 0.35, 0.35, 0.50, 0.50, 0.35, 0.35, 0.666, 0.50, 0.35, 0.35, 0.833, 0.50, 0.35, 0.35}, HHcurve{(double)FCT_MinMaxCPoints, 0.0, 0.50, 0.35, 0.35, 0.166, 0.50, 0.35, 0.35, 0.333, 0.50, 0.35, 0.35, 0.50, 0.50, 0.35, 0.35, 0.666, 0.50, 0.35, 0.35, 0.833, 0.50, 0.35, 0.35}, invers(false), + special(false), enaColorMask(false), CCmaskcurve{(double)FCT_MinMaxCPoints, 0.0, 1.0, 0.35, 0.35, 0.50, 1.0, 0.35, 0.35, 1.00, 1.0, 0.35, 0.35 }, LLmaskcurve{(double)FCT_MinMaxCPoints, 0.0, 1.0, 0.35, 0.35, 0.50, 1.0, 0.35, 0.35, 1.00, 1.0, 0.35, 0.35 }, @@ -2789,6 +2790,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && LHcurve == other.LHcurve && HHcurve == other.HHcurve && invers == other.invers + && special == other.special && enaColorMask == other.enaColorMask && CCmaskcurve == other.CCmaskcurve && LLmaskcurve == other.LLmaskcurve @@ -4099,6 +4101,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->locallab.spots.at(i).LHcurve, "Locallab", "LHCurve_" + std::to_string(i), spot.LHcurve, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).HHcurve, "Locallab", "HHCurve_" + std::to_string(i), spot.HHcurve, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).invers, "Locallab", "Invers_" + std::to_string(i), spot.invers, keyFile); + saveToKeyfile(!pedited || pedited->locallab.spots.at(i).special, "Locallab", "Special_" + std::to_string(i), spot.special, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).enaColorMask, "Locallab", "EnaColorMask_" + std::to_string(i), spot.enaColorMask, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).CCmaskcurve, "Locallab", "CCmaskCurve_" + std::to_string(i), spot.CCmaskcurve, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).LLmaskcurve, "Locallab", "LLmaskCurve_" + std::to_string(i), spot.LLmaskcurve, keyFile); @@ -5516,6 +5519,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "LHCurve_" + std::to_string(i), pedited, spot.LHcurve, spotEdited.LHcurve); assignFromKeyfile(keyFile, "Locallab", "HHCurve_" + std::to_string(i), pedited, spot.HHcurve, spotEdited.HHcurve); assignFromKeyfile(keyFile, "Locallab", "Invers_" + std::to_string(i), pedited, spot.invers, spotEdited.invers); + assignFromKeyfile(keyFile, "Locallab", "Special_" + std::to_string(i), pedited, spot.special, spotEdited.special); assignFromKeyfile(keyFile, "Locallab", "EnaColorMask_" + std::to_string(i), pedited, spot.enaColorMask, spotEdited.enaColorMask); assignFromKeyfile(keyFile, "Locallab", "CCmaskCurve_" + std::to_string(i), pedited, spot.CCmaskcurve, spotEdited.CCmaskcurve); assignFromKeyfile(keyFile, "Locallab", "LLmaskCurve_" + std::to_string(i), pedited, spot.LLmaskcurve, spotEdited.LLmaskcurve); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index cf9355c62..d03bda484 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1019,6 +1019,7 @@ struct LocallabParams { std::vector LHcurve; std::vector HHcurve; bool invers; + bool special; bool enaColorMask; std::vector CCmaskcurve; std::vector LLmaskcurve; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 33b69fb41..5cdeb664a 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -827,7 +827,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, //EvLocallabmergecolMethod LUMINANCECURVE, //EvLocallabopacol LUMINANCECURVE, //Evlocallabrgbshape - LUMINANCECURVE //EvLocallabtoneMethod + LUMINANCECURVE, //EvLocallabtoneMethod + LUMINANCECURVE // EvLocallabspecial }; namespace rtengine diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index a8583b592..c97c09a26 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -424,6 +424,7 @@ Locallab::Locallab(): // Color & Light curvactiv(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_CURV")))), invers(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_INVERS")))), + special(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_SPECIAL")))), enaColorMask(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ENABLE_MASK")))), // Exposure enaExpMask(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ENABLE_MASK")))), @@ -714,6 +715,7 @@ Locallab::Locallab(): rgbCurveEditorG->curveListComplete(); inversConn = invers->signal_toggled().connect(sigc::mem_fun(*this, &Locallab::inversChanged)); + specialConn = special->signal_toggled().connect(sigc::mem_fun(*this, &Locallab::specialChanged)); mergecolMethod->append(M("TP_LOCALLAB_MERONE")); @@ -854,6 +856,7 @@ Locallab::Locallab(): colorBox->pack_start(*llCurveEditorG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor colorBox->pack_start(*HCurveEditorG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor colorBox->pack_start(*rgbCurveEditorG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor + colorBox->pack_start(*special); colorBox->pack_start(*invers); mergecolFrame->set_label_align(0.025, 0.5); @@ -3588,6 +3591,7 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited pp->locallab.spots.at(pp->locallab.selspot).LHcurve = LHshape->getCurve(); pp->locallab.spots.at(pp->locallab.selspot).HHcurve = HHshape->getCurve(); pp->locallab.spots.at(pp->locallab.selspot).invers = invers->get_active(); + pp->locallab.spots.at(pp->locallab.selspot).special = special->get_active(); pp->locallab.spots.at(pp->locallab.selspot).enaColorMask = enaColorMask->get_active(); pp->locallab.spots.at(pp->locallab.selspot).CCmaskcurve = CCmaskshape->getCurve(); pp->locallab.spots.at(pp->locallab.selspot).LLmaskcurve = LLmaskshape->getCurve(); @@ -3979,6 +3983,7 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited pe->locallab.spots.at(pp->locallab.selspot).LHcurve = pe->locallab.spots.at(pp->locallab.selspot).LHcurve || !LHshape->isUnChanged(); pe->locallab.spots.at(pp->locallab.selspot).HHcurve = pe->locallab.spots.at(pp->locallab.selspot).HHcurve || !HHshape->isUnChanged(); pe->locallab.spots.at(pp->locallab.selspot).invers = pe->locallab.spots.at(pp->locallab.selspot).invers || !invers->get_inconsistent(); + pe->locallab.spots.at(pp->locallab.selspot).special = pe->locallab.spots.at(pp->locallab.selspot).special || !special->get_inconsistent(); pe->locallab.spots.at(pp->locallab.selspot).enaColorMask = pe->locallab.spots.at(pp->locallab.selspot).enaColorMask || !enaColorMask->get_inconsistent(); pe->locallab.spots.at(pp->locallab.selspot).CCmaskcurve = pe->locallab.spots.at(pp->locallab.selspot).CCmaskcurve || !CCmaskshape->isUnChanged(); pe->locallab.spots.at(pp->locallab.selspot).LLmaskcurve = pe->locallab.spots.at(pp->locallab.selspot).LLmaskcurve || !LLmaskshape->isUnChanged(); @@ -4302,6 +4307,7 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited pedited->locallab.spots.at(pp->locallab.selspot).LHcurve = pedited->locallab.spots.at(pp->locallab.selspot).LHcurve || !LHshape->isUnChanged(); pedited->locallab.spots.at(pp->locallab.selspot).HHcurve = pedited->locallab.spots.at(pp->locallab.selspot).HHcurve || !HHshape->isUnChanged(); pedited->locallab.spots.at(pp->locallab.selspot).invers = pedited->locallab.spots.at(pp->locallab.selspot).invers || !invers->get_inconsistent(); + pedited->locallab.spots.at(pp->locallab.selspot).special = pedited->locallab.spots.at(pp->locallab.selspot).special || !special->get_inconsistent(); pedited->locallab.spots.at(pp->locallab.selspot).enaColorMask = pedited->locallab.spots.at(pp->locallab.selspot).enaColorMask || !enaColorMask->get_inconsistent(); pedited->locallab.spots.at(pp->locallab.selspot).CCmaskcurve = pedited->locallab.spots.at(pp->locallab.selspot).CCmaskcurve || !CCmaskshape->isUnChanged(); pedited->locallab.spots.at(pp->locallab.selspot).LLmaskcurve = pedited->locallab.spots.at(pp->locallab.selspot).LLmaskcurve || !LLmaskshape->isUnChanged(); @@ -5523,6 +5529,29 @@ Locallab::llMaskVisibility* Locallab::getMaskVisibility() return maskStruct; } +void Locallab::specialChanged() +{ + + if (multiImage) { + if (special->get_inconsistent()) { + special->set_inconsistent(false); + specialConn.block(true); + special->set_active(false); + specialConn.block(false); + } + } + + if (getEnabled() && expcolor->getEnabled()) { + if (listener) { + if (special->get_active()) { + listener->panelChanged(EvLocallabspecial, M("GENERAL_ENABLED")); + } else { + listener->panelChanged(EvLocallabspecial, M("GENERAL_DISABLED")); + } + } + } +} + void Locallab::enaColorMaskChanged() { // printf("enaColorMaskChanged\n"); @@ -8484,6 +8513,7 @@ void Locallab::enableListener() toneMethodConn.block(false); mergecolMethodConn.block(false); inversConn.block(false); + specialConn.block(false); showmaskcolMethodConn.block(false); showmaskcolMethodConninv.block(false); enaColorMaskConn.block(false); @@ -8566,6 +8596,7 @@ void Locallab::disableListener() toneMethodConn.block(true); mergecolMethodConn.block(true); inversConn.block(true); + specialConn.block(true); showmaskcolMethodConn.block(true); showmaskcolMethodConninv.block(true); enaColorMaskConn.block(true); @@ -8722,6 +8753,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con LHshape->setCurve(pp->locallab.spots.at(index).LHcurve); HHshape->setCurve(pp->locallab.spots.at(index).HHcurve); invers->set_active(pp->locallab.spots.at(index).invers); + special->set_active(pp->locallab.spots.at(index).special); enaColorMask->set_active(pp->locallab.spots.at(index).enaColorMask); CCmaskshape->setCurve(pp->locallab.spots.at(index).CCmaskcurve); LLmaskshape->setCurve(pp->locallab.spots.at(index).LLmaskcurve); @@ -9144,6 +9176,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con LHshape->setUnChanged(!spotState->LHcurve); HHshape->setUnChanged(!spotState->HHcurve); invers->set_inconsistent(multiImage && !spotState->invers); + special->set_inconsistent(multiImage && !spotState->special); enaColorMask->set_inconsistent(multiImage && !spotState->enaColorMask); CCmaskshape->setUnChanged(!spotState->CCmaskcurve); LLmaskshape->setUnChanged(!spotState->LLmaskcurve); diff --git a/rtgui/locallab.h b/rtgui/locallab.h index 6a44e414a..f7b230b79 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -330,8 +330,9 @@ private: // Color & Light Gtk::CheckButton* const curvactiv; Gtk::CheckButton* const invers; + Gtk::CheckButton* const special; Gtk::CheckButton* const enaColorMask; - sigc::connection curvactivConn, inversConn, enaColorMaskConn; + sigc::connection curvactivConn, inversConn, enaColorMaskConn, specialConn; // Exposure Gtk::CheckButton* const enaExpMask; sigc::connection enaExpMaskConn; @@ -516,6 +517,7 @@ private: // Color & Light void curvactivChanged(); void inversChanged(); + void specialChanged(); void enaColorMaskChanged(); // Exposure void enaExpMaskChanged(); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index d75668f63..10c7f765b 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1012,6 +1012,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).LHcurve = locallab.spots.at(j).LHcurve && pSpot.LHcurve == otherSpot.LHcurve; locallab.spots.at(j).HHcurve = locallab.spots.at(j).HHcurve && pSpot.HHcurve == otherSpot.HHcurve; locallab.spots.at(j).invers = locallab.spots.at(j).invers && pSpot.invers == otherSpot.invers; + locallab.spots.at(j).special = locallab.spots.at(j).special && pSpot.special == otherSpot.special; locallab.spots.at(j).enaColorMask = locallab.spots.at(j).enaColorMask && pSpot.enaColorMask == otherSpot.enaColorMask; locallab.spots.at(j).CCmaskcurve = locallab.spots.at(j).CCmaskcurve && pSpot.CCmaskcurve == otherSpot.CCmaskcurve; locallab.spots.at(j).LLmaskcurve = locallab.spots.at(j).LLmaskcurve && pSpot.LLmaskcurve == otherSpot.LLmaskcurve; @@ -2970,6 +2971,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).invers = mods.locallab.spots.at(i).invers; } + if (locallab.spots.at(i).special) { + toEdit.locallab.spots.at(i).special = mods.locallab.spots.at(i).special; + } + if (locallab.spots.at(i).enaColorMask) { toEdit.locallab.spots.at(i).enaColorMask = mods.locallab.spots.at(i).enaColorMask; } @@ -4944,6 +4949,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : LHcurve(v), HHcurve(v), invers(v), + special(v), enaColorMask(v), CCmaskcurve(v), LLmaskcurve(v), @@ -5255,6 +5261,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) LHcurve = v; HHcurve = v; invers = v; + special = v; enaColorMask = v; CCmaskcurve = v; LLmaskcurve = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 8bf5cec1c..bd54f1446 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -442,6 +442,7 @@ public: bool LHcurve; bool HHcurve; bool invers; + bool special; bool enaColorMask; bool CCmaskcurve; bool LLmaskcurve;