From d4fc4dc083b59165f5ae731099472406dc734105 Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Mon, 24 Feb 2020 21:00:51 +0100 Subject: [PATCH 01/28] Added new "Preprocess WB" parameter in the Raw toolpanel, just below "Raw White Points" tool. Allows to choose between "Camera" and "Auto" (average-based) raw channel multipliers, and to apply custom compesation factors. Fixes #5616 --- rtdata/languages/default | 9 +++ rtengine/procparams.cc | 40 ++++++++++ rtengine/procparams.h | 18 +++++ rtengine/rawimagesource.cc | 45 +++++++---- rtgui/CMakeLists.txt | 1 + rtgui/paramsedited.cc | 23 ++++++ rtgui/paramsedited.h | 10 +++ rtgui/partialpastedlg.cc | 13 +++ rtgui/partialpastedlg.h | 2 + rtgui/preprocesswb.cc | 158 +++++++++++++++++++++++++++++++++++++ rtgui/preprocesswb.h | 52 ++++++++++++ rtgui/toolpanelcoord.cc | 5 ++ rtgui/toolpanelcoord.h | 2 + 13 files changed, 361 insertions(+), 17 deletions(-) create mode 100644 rtgui/preprocesswb.cc create mode 100644 rtgui/preprocesswb.h diff --git a/rtdata/languages/default b/rtdata/languages/default index 922c50c51..0682cc902 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -776,6 +776,8 @@ HISTORY_MSG_PDSHARPEN_RADIUS_BOOST;CS - Corner radius boost HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demosaic method for motion HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter +HISTORY_MSG_PREPROCWB_MODE;Preprocess WB Mode +HISTORY_MSG_PREPROCWB_MULTS;Preprocess WB Comp. HISTORY_MSG_PRSHARPEN_CONTRAST;PRS - Contrast threshold HISTORY_MSG_RAWCACORR_AUTOIT;Raw CA Correction - Iterations HISTORY_MSG_RAWCACORR_COLORSHIFT;Raw CA Correction - Avoid color shift @@ -1020,6 +1022,7 @@ PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter PARTIALPASTE_PREPROCESS_LINEDENOISE;Line noise filter PARTIALPASTE_PREPROCESS_PDAFLINESFILTER;PDAF lines filter +PARTIALPASTE_PREPROCWB;Preprocess White Balance PARTIALPASTE_PRSHARPENING;Post-resize sharpening PARTIALPASTE_RAWCACORR_AUTO;CA auto-correction PARTIALPASTE_RAWCACORR_AVOIDCOLORSHIFT;CA avoid color shift @@ -1826,6 +1829,12 @@ TP_PREPROCESS_LINEDENOISE_DIRECTION_PDAF_LINES;Horizontal only on PDAF rows TP_PREPROCESS_LINEDENOISE_DIRECTION_VERTICAL;Vertical TP_PREPROCESS_NO_FOUND;None found TP_PREPROCESS_PDAFLINESFILTER;PDAF lines filter +TP_PREPROCWB_BLUE;Blue compensation +TP_PREPROCWB_LABEL;Preprocess White Balance +TP_PREPROCWB_MODE;Mode +TP_PREPROCWB_MODE_AUTO;Auto +TP_PREPROCWB_MODE_CAMERA;Camera +TP_PREPROCWB_RED;Red compensation TP_PRSHARPENING_LABEL;Post-Resize Sharpening TP_PRSHARPENING_TOOLTIP;Sharpens the image after resizing. Only works when the "Lanczos" resizing method is used. It is impossible to preview the effects of this tool. See RawPedia for usage instructions. TP_RAWCACORR_AUTO;Auto-correction diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index f6b139550..4cabe59af 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2735,6 +2735,28 @@ Glib::ustring RAWParams::XTransSensor::getMethodString(Method method) return getMethodStrings()[toUnderlying(method)]; } + +RAWParams::PreprocessWB::PreprocessWB() : + mode(Mode::AUTO), + red(1.0), + blue(1.0) +{ +} + +bool RAWParams::PreprocessWB::operator ==(const PreprocessWB& other) const +{ + return + mode == other.mode + && red == other.red + && blue == other.blue; +} + +bool RAWParams::PreprocessWB::operator !=(const PreprocessWB& other) const +{ + return !(*this == other); +} + + RAWParams::RAWParams() : df_autoselect(false), ff_AutoSelect(false), @@ -2773,6 +2795,7 @@ bool RAWParams::operator ==(const RAWParams& other) const && cared == other.cared && cablue == other.cablue && expos == other.expos + && preprocessWB == other.preprocessWB && hotPixelFilter == other.hotPixelFilter && deadPixelFilter == other.deadPixelFilter && hotdeadpix_thresh == other.hotdeadpix_thresh; @@ -3691,6 +3714,11 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->filmNegative.greenExp, "Film Negative", "GreenExponent", filmNegative.greenExp, keyFile); saveToKeyfile(!pedited || pedited->filmNegative.blueRatio, "Film Negative", "BlueRatio", filmNegative.blueRatio, keyFile); +// Preprocess WB + saveToKeyfile(!pedited || pedited->raw.preprocessWB.mode, "RAW Preprocess WB", "Mode", toUnderlying(raw.preprocessWB.mode), keyFile); + saveToKeyfile(!pedited || pedited->raw.preprocessWB.red, "RAW Preprocess WB", "RedMult", raw.preprocessWB.red, keyFile); + saveToKeyfile(!pedited || pedited->raw.preprocessWB.blue, "RAW Preprocess WB", "BlueMult", raw.preprocessWB.blue, keyFile); + // EXIF change list if (!pedited || pedited->exif) { for (ExifPairs::const_iterator i = exif.begin(); i != exif.end(); ++i) { @@ -5259,6 +5287,18 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Film Negative", "BlueRatio", pedited, filmNegative.blueRatio, pedited->filmNegative.blueRatio); } + if (keyFile.has_group("RAW Preprocess WB")) { + if (keyFile.has_key("RAW Preprocess WB", "Mode")) { + raw.preprocessWB.mode = RAWParams::PreprocessWB::Mode(keyFile.get_integer("RAW Preprocess WB", "Mode")); + + if (pedited) { + pedited->raw.preprocessWB.mode = true; + } + } + assignFromKeyfile(keyFile, "RAW Preprocess WB", "Red" , pedited, raw.preprocessWB.red, pedited->raw.preprocessWB.red); + assignFromKeyfile(keyFile, "RAW Preprocess WB", "Blue" , pedited, raw.preprocessWB.blue, pedited->raw.preprocessWB.blue); + } + if (keyFile.has_group("MetaData")) { int mode = int(MetaDataParams::TUNNEL); assignFromKeyfile(keyFile, "MetaData", "Mode", pedited, mode, pedited->metadata.mode); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 0b6b2dc46..6a60c48be 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1507,6 +1507,24 @@ struct RAWParams { // exposure before interpolation double expos; + struct PreprocessWB { + enum class Mode { + CAMERA = 0, + AUTO + }; + + Mode mode; + double red; + double blue; + + PreprocessWB(); + + bool operator ==(const PreprocessWB& other) const; + bool operator !=(const PreprocessWB& other) const; + }; + + PreprocessWB preprocessWB; + bool hotPixelFilter; bool deadPixelFilter; int hotdeadpix_thresh; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index fcc85f2c6..a029f0797 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -1161,25 +1161,8 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) double cam_b = imatrices.rgb_cam[2][0] * camwb_red + imatrices.rgb_cam[2][1] * camwb_green + imatrices.rgb_cam[2][2] * camwb_blue; camera_wb = ColorTemp (cam_r, cam_g, cam_b, 1.); // as shot WB - ColorTemp ReferenceWB; - double ref_r, ref_g, ref_b; - { - // ...then we re-get the constants but now with auto which gives us better demosaicing and CA auto-correct - // performance for strange white balance settings (such as UniWB) - ri->get_colorsCoeff( ref_pre_mul, scale_mul, c_black, true); - refwb_red = ri->get_pre_mul(0) / ref_pre_mul[0]; - refwb_green = ri->get_pre_mul(1) / ref_pre_mul[1]; - refwb_blue = ri->get_pre_mul(2) / ref_pre_mul[2]; - initialGain = max(scale_mul[0], scale_mul[1], scale_mul[2], scale_mul[3]) / min(scale_mul[0], scale_mul[1], scale_mul[2], scale_mul[3]); - ref_r = imatrices.rgb_cam[0][0] * refwb_red + imatrices.rgb_cam[0][1] * refwb_green + imatrices.rgb_cam[0][2] * refwb_blue; - ref_g = imatrices.rgb_cam[1][0] * refwb_red + imatrices.rgb_cam[1][1] * refwb_green + imatrices.rgb_cam[1][2] * refwb_blue; - ref_b = imatrices.rgb_cam[2][0] * refwb_red + imatrices.rgb_cam[2][1] * refwb_green + imatrices.rgb_cam[2][2] * refwb_blue; - ReferenceWB = ColorTemp (ref_r, ref_g, ref_b, 1.); - } - if (settings->verbose) { printf("Raw As Shot White balance: temp %f, tint %f\n", camera_wb.getTemp(), camera_wb.getGreen()); - printf("Raw Reference (auto) white balance: temp %f, tint %f, multipliers [%f %f %f | %f %f %f]\n", ReferenceWB.getTemp(), ReferenceWB.getGreen(), ref_r, ref_g, ref_b, refwb_red, refwb_blue, refwb_green); } /*{ @@ -1249,6 +1232,34 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le MyTime t1, t2; t1.set(); + { + // Recalculate the scaling coefficients, using auto WB if selected in the Preprocess WB param. + // Auto WB gives us better demosaicing and CA auto-correct performance for strange white balance settings (such as UniWB) + ri->get_colorsCoeff( ref_pre_mul, scale_mul, c_black, raw.preprocessWB.mode == RAWParams::PreprocessWB::Mode::AUTO); + + // Apply custom compensation factors as specified in params + const auto ppwb = raw.preprocessWB; + ref_pre_mul[0] *= ppwb.red; + ref_pre_mul[2] *= ppwb.blue; + scale_mul[0] *= ppwb.red; + scale_mul[2] *= ppwb.blue; + + refwb_red = ri->get_pre_mul(0) / ref_pre_mul[0]; + refwb_green = ri->get_pre_mul(1) / ref_pre_mul[1]; + refwb_blue = ri->get_pre_mul(2) / ref_pre_mul[2]; + initialGain = max(scale_mul[0], scale_mul[1], scale_mul[2], scale_mul[3]) / min(scale_mul[0], scale_mul[1], scale_mul[2], scale_mul[3]); + + const double ref_r = imatrices.rgb_cam[0][0] * refwb_red + imatrices.rgb_cam[0][1] * refwb_green + imatrices.rgb_cam[0][2] * refwb_blue; + const double ref_g = imatrices.rgb_cam[1][0] * refwb_red + imatrices.rgb_cam[1][1] * refwb_green + imatrices.rgb_cam[1][2] * refwb_blue; + const double ref_b = imatrices.rgb_cam[2][0] * refwb_red + imatrices.rgb_cam[2][1] * refwb_green + imatrices.rgb_cam[2][2] * refwb_blue; + const ColorTemp ReferenceWB = ColorTemp (ref_r, ref_g, ref_b, 1.); + + if (settings->verbose) { + printf("Raw Reference white balance: temp %f, tint %f, multipliers [%f %f %f | %f %f %f]\n", ReferenceWB.getTemp(), ReferenceWB.getGreen(), ref_r, ref_g, ref_b, refwb_red, refwb_blue, refwb_green); + } + } + + Glib::ustring newDF = raw.dark_frame; RawImage *rid = nullptr; diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index 4b21ce421..56c3dc461 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -113,6 +113,7 @@ set(NONCLISOURCEFILES popuptogglebutton.cc preferences.cc preprocess.cc + preprocesswb.cc previewhandler.cc previewloader.cc previewmodepanel.cc diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index d41bd472c..c824eaaa5 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -595,6 +595,9 @@ void ParamsEdited::set(bool v) filmNegative.redRatio = v; filmNegative.greenExp = v; filmNegative.blueRatio = v; + raw.preprocessWB.mode = v; + raw.preprocessWB.red = v; + raw.preprocessWB.blue = v; exif = v; iptc = v; @@ -1169,6 +1172,9 @@ void ParamsEdited::initFrom(const std::vector& filmNegative.redRatio = filmNegative.redRatio && p.filmNegative.redRatio == other.filmNegative.redRatio; filmNegative.greenExp = filmNegative.greenExp && p.filmNegative.greenExp == other.filmNegative.greenExp; filmNegative.blueRatio = filmNegative.blueRatio && p.filmNegative.blueRatio == other.filmNegative.blueRatio; + raw.preprocessWB.mode = raw.preprocessWB.mode && p.raw.preprocessWB.mode == other.raw.preprocessWB.mode; + raw.preprocessWB.red = raw.preprocessWB.red && p.raw.preprocessWB.red == other.raw.preprocessWB.red; + raw.preprocessWB.blue = raw.preprocessWB.blue && p.raw.preprocessWB.blue == other.raw.preprocessWB.blue; // How the hell can we handle that??? // exif = exif && p.exif==other.exif @@ -3262,6 +3268,18 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.filmNegative.blueRatio = mods.filmNegative.blueRatio; } + if (raw.preprocessWB.mode) { + toEdit.raw.preprocessWB.mode = mods.raw.preprocessWB.mode; + } + + if (raw.preprocessWB.red) { + toEdit.raw.preprocessWB.red = mods.raw.preprocessWB.red; + } + + if (raw.preprocessWB.blue) { + toEdit.raw.preprocessWB.blue = mods.raw.preprocessWB.blue; + } + // Exif changes are added to the existing ones if (exif) { for (procparams::ExifPairs::const_iterator i = mods.exif.begin(); i != mods.exif.end(); ++i) { @@ -3314,4 +3332,9 @@ bool FilmNegativeParamsEdited::isUnchanged() const bool CaptureSharpeningParamsEdited::isUnchanged() const { return enabled && contrast && autoContrast && autoRadius && deconvradius && deconvradiusOffset && deconviter && deconvitercheck; +} + +bool RAWParamsEdited::PreprocessWBParamsEdited::isUnchanged() const +{ + return mode && red && blue; } \ No newline at end of file diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 153dd7bb6..1cdaf83d5 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -686,6 +686,16 @@ struct RAWParamsEdited { bool ff_clipControl; bool exPos; + struct PreprocessWBParamsEdited { + bool mode; + bool red; + bool blue; + + bool isUnchanged() const; + }; + + PreprocessWBParamsEdited preprocessWB; + bool isUnchanged() const; }; diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc index 22f608ae4..f74d40e4e 100644 --- a/rtgui/partialpastedlg.cc +++ b/rtgui/partialpastedlg.cc @@ -138,6 +138,8 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren filmNegative = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FILMNEGATIVE")) ); //--- captureSharpening = Gtk::manage (new Gtk::CheckButton (M("TP_PDSHARPENING_LABEL")) ); + //--- + raw_preprocwb = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCWB"))); Gtk::VBox* vboxes[8]; Gtk::HSeparator* hseps[8]; @@ -240,6 +242,7 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren vboxes[7]->pack_start (*Gtk::manage (new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 0); vboxes[7]->pack_start (*raw_expos, Gtk::PACK_SHRINK, 2); vboxes[7]->pack_start (*raw_black, Gtk::PACK_SHRINK, 2); + vboxes[7]->pack_start (*raw_preprocwb, Gtk::PACK_SHRINK, 2); vboxes[7]->pack_start (*Gtk::manage (new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 0); vboxes[7]->pack_start (*df_file, Gtk::PACK_SHRINK, 2); vboxes[7]->pack_start (*df_AutoSelect, Gtk::PACK_SHRINK, 2); @@ -407,6 +410,8 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren filmNegativeConn = filmNegative->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); //--- captureSharpeningConn = captureSharpening->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + //--- + raw_preprocwbConn = raw_preprocwb->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); add_button (M("GENERAL_OK"), Gtk::RESPONSE_OK); add_button (M("GENERAL_CANCEL"), Gtk::RESPONSE_CANCEL); @@ -480,6 +485,7 @@ void PartialPasteDlg::rawToggled () ConnectionBlocker raw_ca_avoid_colourshiftBlocker(raw_ca_avoid_colourshiftconn); ConnectionBlocker filmNegativeBlocker(filmNegativeConn); ConnectionBlocker captureSharpeningBlocker(captureSharpeningConn); + ConnectionBlocker raw_preprocwbBlocker(raw_preprocwbConn); raw->set_inconsistent (false); @@ -510,6 +516,7 @@ void PartialPasteDlg::rawToggled () raw_ca_avoid_colourshift->set_active (raw->get_active ()); filmNegative->set_active (raw->get_active()); captureSharpening->set_active (raw->get_active()); + raw_preprocwb->set_active (raw->get_active()); } void PartialPasteDlg::basicToggled () @@ -999,6 +1006,12 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param filterPE.pdsharpening.deconvitercheck = falsePE.pdsharpening.deconvitercheck; } + if (!raw_preprocwb->get_active ()) { + filterPE.raw.preprocessWB.mode = falsePE.raw.preprocessWB.mode; + filterPE.raw.preprocessWB.red = falsePE.raw.preprocessWB.red; + filterPE.raw.preprocessWB.blue = falsePE.raw.preprocessWB.blue; + } + if (dstPE) { *dstPE = filterPE; } diff --git a/rtgui/partialpastedlg.h b/rtgui/partialpastedlg.h index 75e18e83c..e835ec779 100644 --- a/rtgui/partialpastedlg.h +++ b/rtgui/partialpastedlg.h @@ -142,6 +142,7 @@ public: Gtk::CheckButton* filmNegative; Gtk::CheckButton* captureSharpening; + Gtk::CheckButton* raw_preprocwb; sigc::connection everythingConn, basicConn, detailConn, colorConn, lensConn, compositionConn, metaConn, rawConn, advancedConn; @@ -155,6 +156,7 @@ public: sigc::connection raw_caredblueConn, raw_ca_autocorrectConn, raw_ca_avoid_colourshiftconn, raw_hotpix_filtConn, raw_deadpix_filtConn, raw_pdaf_lines_filterConn, raw_linenoiseConn, raw_greenthreshConn, raw_ccStepsConn, raw_methodConn, raw_borderConn, raw_imagenumConn, raw_dcb_iterationsConn, raw_lmmse_iterationsConn, raw_pixelshiftConn, raw_dcb_enhanceConn, raw_exposConn, raw_blackConn; sigc::connection filmNegativeConn; sigc::connection captureSharpeningConn; + sigc::connection raw_preprocwbConn; public: PartialPasteDlg (const Glib::ustring &title, Gtk::Window* parent); diff --git a/rtgui/preprocesswb.cc b/rtgui/preprocesswb.cc new file mode 100644 index 000000000..1f54f7672 --- /dev/null +++ b/rtgui/preprocesswb.cc @@ -0,0 +1,158 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2020 Alberto Romei + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include + +#include "preprocesswb.h" +#include "eventmapper.h" + +#include "guiutils.h" +#include "options.h" + +#include "../rtengine/procparams.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +PreprocessWB::PreprocessWB() : + FoldableToolPanel(this, "preprocesswb", M("TP_PREPROCWB_LABEL")), + evPreprocessWBMode(ProcEventMapper::getInstance()->newEvent(FIRST, "HISTORY_MSG_PREPROCWB_MODE")), + evPreprocessWBMults(ProcEventMapper::getInstance()->newEvent(FIRST, "HISTORY_MSG_PREPROCWB_MULTS")), + mode(Gtk::manage(new MyComboBoxText())), + red(Gtk::manage(new Adjuster(M("TP_PREPROCWB_RED"), 0.05, 20.0, 0.01, 1))), + blue(Gtk::manage(new Adjuster(M("TP_PREPROCWB_BLUE"), 0.05, 20.0, 0.01, 1))) +{ + Gtk::HBox *hb = Gtk::manage(new Gtk::HBox()); + hb->pack_start(*Gtk::manage(new Gtk::Label(M("TP_PREPROCWB_MODE") + ": ")), Gtk::PACK_SHRINK, 0); + + mode->append(M("TP_PREPROCWB_MODE_CAMERA")); + mode->append(M("TP_PREPROCWB_MODE_AUTO")); + + hb->pack_start(*mode); + + mode->set_active(0); + mode->signal_changed().connect(sigc::mem_fun(*this, &PreprocessWB::modeChanged)); + + red->setAdjusterListener(this); + blue->setAdjusterListener(this); + + red->setLogScale(8, 1, true); + blue->setLogScale(8, 1, true); + + if (red->delay < options.adjusterMaxDelay) { + red->delay = options.adjusterMaxDelay; + } + + if (blue->delay < options.adjusterMaxDelay) { + blue->delay = options.adjusterMaxDelay; + } + + mode->show(); + red->show(); + blue->show(); + + pack_start(*hb, Gtk::PACK_SHRINK, 4); + pack_start(*red, Gtk::PACK_SHRINK, 4); + pack_start(*blue, Gtk::PACK_SHRINK, 4); +} + +void PreprocessWB::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener(); + + if (pedited) { + red->setEditedState(pedited->raw.preprocessWB.red ? Edited : UnEdited); + blue->setEditedState(pedited->raw.preprocessWB.blue ? Edited : UnEdited); + } + + mode->set_active(int(pp->raw.preprocessWB.mode)); + red->setValue(pp->raw.preprocessWB.red); + blue->setValue(pp->raw.preprocessWB.blue); + + enableListener(); +} + +void PreprocessWB::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) +{ + if (mode->get_active_row_number() != 2) { + pp->raw.preprocessWB.mode = RAWParams::PreprocessWB::Mode(mode->get_active_row_number()); + } + + pp->raw.preprocessWB.red = red->getValue(); + pp->raw.preprocessWB.blue = blue->getValue(); + + if (pedited) { + pedited->raw.preprocessWB.mode = mode->get_active_row_number() != 2; // UNCHANGED entry, see setBatchMode + pedited->raw.preprocessWB.red = red->getEditedState(); + pedited->raw.preprocessWB.blue = blue->getEditedState(); + } + +} + +void PreprocessWB::adjusterChanged(Adjuster* a, double newval) +{ + if (listener) { + listener->panelChanged(evPreprocessWBMults, Glib::ustring::compose( + "R/G=%1 ; B/G=%2", red->getValue(), blue->getValue())); + } +} + +void PreprocessWB::setBatchMode(bool batchMode) +{ + ToolPanel::setBatchMode(batchMode); + + if (batchMode) { + mode->append(M("GENERAL_UNCHANGED")); + mode->set_active_text(M("GENERAL_UNCHANGED")); + red->showEditedCB(); + blue->showEditedCB(); + } +} + +void PreprocessWB::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) +{ + red->setDefault(defParams->raw.preprocessWB.red); + blue->setDefault(defParams->raw.preprocessWB.blue); + + if (pedited) { + red->setDefaultEditedState(pedited->raw.preprocessWB.red ? Edited : UnEdited); + blue->setDefaultEditedState(pedited->raw.preprocessWB.blue ? Edited : UnEdited); + } else { + red->setDefaultEditedState(Irrelevant); + blue->setDefaultEditedState(Irrelevant); + } +} + +void PreprocessWB::setAdjusterBehavior(bool add) +{ + red->setAddMode(add); + blue->setAddMode(add); +} + +void PreprocessWB::trimValues(rtengine::procparams::ProcParams* pp) +{ + red->trimValue(pp->raw.preprocessWB.red); + blue->trimValue(pp->raw.preprocessWB.blue); +} + +void PreprocessWB::modeChanged() +{ + if (listener) { + listener->panelChanged(evPreprocessWBMode, mode->get_active_text()); + } +} diff --git a/rtgui/preprocesswb.h b/rtgui/preprocesswb.h new file mode 100644 index 000000000..2aabf13d8 --- /dev/null +++ b/rtgui/preprocesswb.h @@ -0,0 +1,52 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2020 Alberto Romei + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#pragma once + +#include + +#include "adjuster.h" +#include "toolpanel.h" + +class PreprocessWB final: + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel +{ + +private: + const rtengine::ProcEvent evPreprocessWBMode, evPreprocessWBMults; + + MyComboBoxText* mode; + + Adjuster* red; + Adjuster* blue; + +public: + + PreprocessWB(); + + void read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override; + void write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr) override; + void setBatchMode(bool batchMode) override; + void setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; + void adjusterChanged(Adjuster* a, double newval) override; + void setAdjusterBehavior(bool add); + void trimValues(rtengine::procparams::ProcParams* pp) override; + void modeChanged(); +}; diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 00ad96328..8e7ed8071 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -92,6 +92,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit flatfield = Gtk::manage (new FlatField ()); rawcacorrection = Gtk::manage (new RAWCACorr ()); rawexposure = Gtk::manage (new RAWExposure ()); + preprocessWB = Gtk::manage (new PreprocessWB ()); bayerrawexposure = Gtk::manage (new BayerRAWExposure ()); xtransrawexposure = Gtk::manage (new XTransRAWExposure ()); fattal = Gtk::manage (new FattalToneMapping ()); @@ -155,6 +156,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit addfavoritePanel (sensorxtrans->getPackBox(), xtransprocess, 2); addfavoritePanel (sensorxtrans->getPackBox(), xtransrawexposure, 2); addfavoritePanel (rawPanel, rawexposure); + addfavoritePanel (rawPanel, preprocessWB); addfavoritePanel (rawPanel, preprocess); addfavoritePanel (rawPanel, darkframe); addfavoritePanel (rawPanel, flatfield); @@ -357,6 +359,7 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt sensorxtrans->FoldableToolPanel::hide(); xtransprocess->FoldableToolPanel::hide(); xtransrawexposure->FoldableToolPanel::hide(); + preprocessWB->FoldableToolPanel::hide(); preprocess->FoldableToolPanel::hide(); flatfield->FoldableToolPanel::show(); filmNegative->FoldableToolPanel::hide(); @@ -377,6 +380,7 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt sensorxtrans->FoldableToolPanel::hide(); xtransprocess->FoldableToolPanel::hide(); xtransrawexposure->FoldableToolPanel::hide(); + preprocessWB->FoldableToolPanel::hide(); preprocess->FoldableToolPanel::hide(); flatfield->FoldableToolPanel::hide(); filmNegative->FoldableToolPanel::hide(); @@ -398,6 +402,7 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt sensorxtrans->FoldableToolPanel::hide(); xtransprocess->FoldableToolPanel::hide(); xtransrawexposure->FoldableToolPanel::hide(); + preprocessWB->FoldableToolPanel::hide(); preprocess->FoldableToolPanel::hide(); flatfield->FoldableToolPanel::hide(); filmNegative->FoldableToolPanel::hide(); diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 0fc1a9070..e61d1a12e 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -59,6 +59,7 @@ #include "perspective.h" #include "pparamschangelistener.h" #include "preprocess.h" +#include "preprocesswb.h" #include "profilechangelistener.h" #include "prsharpening.h" #include "rawcacorrection.h" @@ -155,6 +156,7 @@ protected: FlatField* flatfield; RAWCACorr* rawcacorrection; RAWExposure* rawexposure; + PreprocessWB* preprocessWB; BayerRAWExposure* bayerrawexposure; XTransRAWExposure* xtransrawexposure; FattalToneMapping *fattal; From fb023e7ba88e8d15dc0ea28cfb73e34736cc6f2d Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Sun, 15 Mar 2020 17:01:40 +0100 Subject: [PATCH 02/28] Removed channel compensation adjusters --- rtdata/languages/default | 3 -- rtengine/procparams.cc | 13 ++------ rtengine/procparams.h | 2 -- rtengine/rawimagesource.cc | 7 ----- rtgui/paramsedited.cc | 14 +-------- rtgui/paramsedited.h | 2 -- rtgui/partialpastedlg.cc | 2 -- rtgui/preprocesswb.cc | 63 +------------------------------------- rtgui/preprocesswb.h | 7 +---- 9 files changed, 5 insertions(+), 108 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index de394ac15..a6abadaa6 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -778,7 +778,6 @@ HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demosaic method for motion HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter HISTORY_MSG_PREPROCWB_MODE;Preprocess WB Mode -HISTORY_MSG_PREPROCWB_MULTS;Preprocess WB Comp. HISTORY_MSG_PRSHARPEN_CONTRAST;PRS - Contrast threshold HISTORY_MSG_RAWCACORR_AUTOIT;Raw CA Correction - Iterations HISTORY_MSG_RAWCACORR_COLORSHIFT;Raw CA Correction - Avoid color shift @@ -1845,12 +1844,10 @@ TP_PREPROCESS_LINEDENOISE_DIRECTION_PDAF_LINES;Horizontal only on PDAF rows TP_PREPROCESS_LINEDENOISE_DIRECTION_VERTICAL;Vertical TP_PREPROCESS_NO_FOUND;None found TP_PREPROCESS_PDAFLINESFILTER;PDAF lines filter -TP_PREPROCWB_BLUE;Blue compensation TP_PREPROCWB_LABEL;Preprocess White Balance TP_PREPROCWB_MODE;Mode TP_PREPROCWB_MODE_AUTO;Auto TP_PREPROCWB_MODE_CAMERA;Camera -TP_PREPROCWB_RED;Red compensation TP_PRSHARPENING_LABEL;Post-Resize Sharpening TP_PRSHARPENING_TOOLTIP;Sharpens the image after resizing. Only works when the "Lanczos" resizing method is used. It is impossible to preview the effects of this tool. See RawPedia for usage instructions. TP_RAWCACORR_AUTO;Auto-correction diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index b7d122f83..97dfc2fe7 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2765,18 +2765,13 @@ Glib::ustring RAWParams::XTransSensor::getMethodString(Method method) RAWParams::PreprocessWB::PreprocessWB() : - mode(Mode::AUTO), - red(1.0), - blue(1.0) + mode(Mode::AUTO) { } bool RAWParams::PreprocessWB::operator ==(const PreprocessWB& other) const { - return - mode == other.mode - && red == other.red - && blue == other.blue; + return mode == other.mode; } bool RAWParams::PreprocessWB::operator !=(const PreprocessWB& other) const @@ -3757,8 +3752,6 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo // Preprocess WB saveToKeyfile(!pedited || pedited->raw.preprocessWB.mode, "RAW Preprocess WB", "Mode", toUnderlying(raw.preprocessWB.mode), keyFile); - saveToKeyfile(!pedited || pedited->raw.preprocessWB.red, "RAW Preprocess WB", "RedMult", raw.preprocessWB.red, keyFile); - saveToKeyfile(!pedited || pedited->raw.preprocessWB.blue, "RAW Preprocess WB", "BlueMult", raw.preprocessWB.blue, keyFile); // EXIF change list if (!pedited || pedited->exif) { @@ -5351,8 +5344,6 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) pedited->raw.preprocessWB.mode = true; } } - assignFromKeyfile(keyFile, "RAW Preprocess WB", "Red" , pedited, raw.preprocessWB.red, pedited->raw.preprocessWB.red); - assignFromKeyfile(keyFile, "RAW Preprocess WB", "Blue" , pedited, raw.preprocessWB.blue, pedited->raw.preprocessWB.blue); } if (keyFile.has_group("MetaData")) { diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 50d48733a..a737d5776 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1527,8 +1527,6 @@ struct RAWParams { }; Mode mode; - double red; - double blue; PreprocessWB(); diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 7f7fd1543..a37e94c62 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -1237,13 +1237,6 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le // Auto WB gives us better demosaicing and CA auto-correct performance for strange white balance settings (such as UniWB) ri->get_colorsCoeff( ref_pre_mul, scale_mul, c_black, raw.preprocessWB.mode == RAWParams::PreprocessWB::Mode::AUTO); - // Apply custom compensation factors as specified in params - const auto ppwb = raw.preprocessWB; - ref_pre_mul[0] *= ppwb.red; - ref_pre_mul[2] *= ppwb.blue; - scale_mul[0] *= ppwb.red; - scale_mul[2] *= ppwb.blue; - refwb_red = ri->get_pre_mul(0) / ref_pre_mul[0]; refwb_green = ri->get_pre_mul(1) / ref_pre_mul[1]; refwb_blue = ri->get_pre_mul(2) / ref_pre_mul[2]; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index fdc3cbe52..c7ab5f1c5 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -609,8 +609,6 @@ void ParamsEdited::set(bool v) filmNegative.greenExp = v; filmNegative.blueRatio = v; raw.preprocessWB.mode = v; - raw.preprocessWB.red = v; - raw.preprocessWB.blue = v; exif = v; iptc = v; @@ -1199,8 +1197,6 @@ void ParamsEdited::initFrom(const std::vector& filmNegative.greenExp = filmNegative.greenExp && p.filmNegative.greenExp == other.filmNegative.greenExp; filmNegative.blueRatio = filmNegative.blueRatio && p.filmNegative.blueRatio == other.filmNegative.blueRatio; raw.preprocessWB.mode = raw.preprocessWB.mode && p.raw.preprocessWB.mode == other.raw.preprocessWB.mode; - raw.preprocessWB.red = raw.preprocessWB.red && p.raw.preprocessWB.red == other.raw.preprocessWB.red; - raw.preprocessWB.blue = raw.preprocessWB.blue && p.raw.preprocessWB.blue == other.raw.preprocessWB.blue; // How the hell can we handle that??? // exif = exif && p.exif==other.exif @@ -3350,14 +3346,6 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.raw.preprocessWB.mode = mods.raw.preprocessWB.mode; } - if (raw.preprocessWB.red) { - toEdit.raw.preprocessWB.red = mods.raw.preprocessWB.red; - } - - if (raw.preprocessWB.blue) { - toEdit.raw.preprocessWB.blue = mods.raw.preprocessWB.blue; - } - // Exif changes are added to the existing ones if (exif) { for (procparams::ExifPairs::const_iterator i = mods.exif.begin(); i != mods.exif.end(); ++i) { @@ -3414,5 +3402,5 @@ bool CaptureSharpeningParamsEdited::isUnchanged() const bool RAWParamsEdited::PreprocessWBParamsEdited::isUnchanged() const { - return mode && red && blue; + return mode; } \ No newline at end of file diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index c63119e25..8b4cf1241 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -701,8 +701,6 @@ struct RAWParamsEdited { struct PreprocessWBParamsEdited { bool mode; - bool red; - bool blue; bool isUnchanged() const; }; diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc index f74d40e4e..8c49323c5 100644 --- a/rtgui/partialpastedlg.cc +++ b/rtgui/partialpastedlg.cc @@ -1008,8 +1008,6 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param if (!raw_preprocwb->get_active ()) { filterPE.raw.preprocessWB.mode = falsePE.raw.preprocessWB.mode; - filterPE.raw.preprocessWB.red = falsePE.raw.preprocessWB.red; - filterPE.raw.preprocessWB.blue = falsePE.raw.preprocessWB.blue; } if (dstPE) { diff --git a/rtgui/preprocesswb.cc b/rtgui/preprocesswb.cc index 1f54f7672..170371318 100644 --- a/rtgui/preprocesswb.cc +++ b/rtgui/preprocesswb.cc @@ -32,10 +32,7 @@ using namespace rtengine::procparams; PreprocessWB::PreprocessWB() : FoldableToolPanel(this, "preprocesswb", M("TP_PREPROCWB_LABEL")), evPreprocessWBMode(ProcEventMapper::getInstance()->newEvent(FIRST, "HISTORY_MSG_PREPROCWB_MODE")), - evPreprocessWBMults(ProcEventMapper::getInstance()->newEvent(FIRST, "HISTORY_MSG_PREPROCWB_MULTS")), - mode(Gtk::manage(new MyComboBoxText())), - red(Gtk::manage(new Adjuster(M("TP_PREPROCWB_RED"), 0.05, 20.0, 0.01, 1))), - blue(Gtk::manage(new Adjuster(M("TP_PREPROCWB_BLUE"), 0.05, 20.0, 0.01, 1))) + mode(Gtk::manage(new MyComboBoxText())) { Gtk::HBox *hb = Gtk::manage(new Gtk::HBox()); hb->pack_start(*Gtk::manage(new Gtk::Label(M("TP_PREPROCWB_MODE") + ": ")), Gtk::PACK_SHRINK, 0); @@ -48,41 +45,16 @@ PreprocessWB::PreprocessWB() : mode->set_active(0); mode->signal_changed().connect(sigc::mem_fun(*this, &PreprocessWB::modeChanged)); - red->setAdjusterListener(this); - blue->setAdjusterListener(this); - - red->setLogScale(8, 1, true); - blue->setLogScale(8, 1, true); - - if (red->delay < options.adjusterMaxDelay) { - red->delay = options.adjusterMaxDelay; - } - - if (blue->delay < options.adjusterMaxDelay) { - blue->delay = options.adjusterMaxDelay; - } - mode->show(); - red->show(); - blue->show(); pack_start(*hb, Gtk::PACK_SHRINK, 4); - pack_start(*red, Gtk::PACK_SHRINK, 4); - pack_start(*blue, Gtk::PACK_SHRINK, 4); } void PreprocessWB::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) { disableListener(); - if (pedited) { - red->setEditedState(pedited->raw.preprocessWB.red ? Edited : UnEdited); - blue->setEditedState(pedited->raw.preprocessWB.blue ? Edited : UnEdited); - } - mode->set_active(int(pp->raw.preprocessWB.mode)); - red->setValue(pp->raw.preprocessWB.red); - blue->setValue(pp->raw.preprocessWB.blue); enableListener(); } @@ -93,25 +65,12 @@ void PreprocessWB::write(rtengine::procparams::ProcParams* pp, ParamsEdited* ped pp->raw.preprocessWB.mode = RAWParams::PreprocessWB::Mode(mode->get_active_row_number()); } - pp->raw.preprocessWB.red = red->getValue(); - pp->raw.preprocessWB.blue = blue->getValue(); - if (pedited) { pedited->raw.preprocessWB.mode = mode->get_active_row_number() != 2; // UNCHANGED entry, see setBatchMode - pedited->raw.preprocessWB.red = red->getEditedState(); - pedited->raw.preprocessWB.blue = blue->getEditedState(); } } -void PreprocessWB::adjusterChanged(Adjuster* a, double newval) -{ - if (listener) { - listener->panelChanged(evPreprocessWBMults, Glib::ustring::compose( - "R/G=%1 ; B/G=%2", red->getValue(), blue->getValue())); - } -} - void PreprocessWB::setBatchMode(bool batchMode) { ToolPanel::setBatchMode(batchMode); @@ -119,35 +78,15 @@ void PreprocessWB::setBatchMode(bool batchMode) if (batchMode) { mode->append(M("GENERAL_UNCHANGED")); mode->set_active_text(M("GENERAL_UNCHANGED")); - red->showEditedCB(); - blue->showEditedCB(); } } void PreprocessWB::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) { - red->setDefault(defParams->raw.preprocessWB.red); - blue->setDefault(defParams->raw.preprocessWB.blue); - - if (pedited) { - red->setDefaultEditedState(pedited->raw.preprocessWB.red ? Edited : UnEdited); - blue->setDefaultEditedState(pedited->raw.preprocessWB.blue ? Edited : UnEdited); - } else { - red->setDefaultEditedState(Irrelevant); - blue->setDefaultEditedState(Irrelevant); - } -} - -void PreprocessWB::setAdjusterBehavior(bool add) -{ - red->setAddMode(add); - blue->setAddMode(add); } void PreprocessWB::trimValues(rtengine::procparams::ProcParams* pp) { - red->trimValue(pp->raw.preprocessWB.red); - blue->trimValue(pp->raw.preprocessWB.blue); } void PreprocessWB::modeChanged() diff --git a/rtgui/preprocesswb.h b/rtgui/preprocesswb.h index 2aabf13d8..343d2e9e9 100644 --- a/rtgui/preprocesswb.h +++ b/rtgui/preprocesswb.h @@ -25,18 +25,14 @@ class PreprocessWB final: public ToolParamBlock, - public AdjusterListener, public FoldableToolPanel { private: - const rtengine::ProcEvent evPreprocessWBMode, evPreprocessWBMults; + const rtengine::ProcEvent evPreprocessWBMode; MyComboBoxText* mode; - Adjuster* red; - Adjuster* blue; - public: PreprocessWB(); @@ -45,7 +41,6 @@ public: void write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr) override; void setBatchMode(bool batchMode) override; void setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; - void adjusterChanged(Adjuster* a, double newval) override; void setAdjusterBehavior(bool add); void trimValues(rtengine::procparams::ProcParams* pp) override; void modeChanged(); From c2fae0ce87cfed13e32eb43a518d3e5bdf08bcaa Mon Sep 17 00:00:00 2001 From: Desmis Date: Fri, 10 Apr 2020 09:20:31 +0200 Subject: [PATCH 03/28] Change sensitivity sliders wavelet levels denoise --- rtengine/FTblockDN.cc | 2 +- rtengine/ipwavelet.cc | 53 +++++++++++++++++++++++-------------------- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index 894c72ce2..ab06f92f2 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -549,7 +549,7 @@ BENCHFUN const float noisevarL = (useNoiseLCurve && (denoiseMethodRgb || !isRAW)) ? SQR(((noiseluma + 1.f) / 125.f) * (10.f + (noiseluma + 1.f) / 25.f)) : SQR((noiseluma / 125.f) * (1.f + noiseluma / 25.f)); const bool denoiseLuminance = (noisevarL > 0.00001f); - //printf("NL=%f \n",noisevarL); +// printf("NL=%f \n",noisevarL); if (useNoiseLCurve || useNoiseCCurve) { int hei = calclum->getHeight(); int wid = calclum->getWidth(); diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index f415c9c8e..264b5df6d 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -907,10 +907,10 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const //init for edge and denoise float vari[4]; - vari[0] = 8.f * SQR((cp.lev0n / 125.f) * (1.f + cp.lev0n / 25.f)); - vari[1] = 8.f * SQR((cp.lev1n / 125.f) * (1.f + cp.lev1n / 25.f)); - vari[2] = 8.f * SQR((cp.lev2n / 125.f) * (1.f + cp.lev2n / 25.f)); - vari[3] = 8.f * SQR((cp.lev3n / 125.f) * (1.f + cp.lev3n / 25.f)); + vari[0] = 0.8f * SQR((cp.lev0n / 125.f) * (1.f + cp.lev0n / 25.f)); + vari[1] = 0.8f * SQR((cp.lev1n / 125.f) * (1.f + cp.lev1n / 25.f)); + vari[2] = 0.8f * SQR((cp.lev2n / 125.f) * (1.f + cp.lev2n / 25.f)); + vari[3] = 0.8f * SQR((cp.lev3n / 125.f) * (1.f + cp.lev3n / 25.f)); float kr3 = 1.f; if (cp.lev3n < 10.f) { @@ -925,10 +925,13 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if ((cp.lev0n > 0.1f || cp.lev1n > 0.1f || cp.lev2n > 0.1f || cp.lev3n > 0.1f) && cp.noiseena) { int edge = 4; - vari[0] = rtengine::max(0.0001f, vari[0]); - vari[1] = rtengine::max(0.0001f, vari[1]); - vari[2] = rtengine::max(0.0001f, vari[2]); - vari[3] = rtengine::max(0.0001f, kr3 * vari[3]); + vari[0] = rtengine::max(0.000001f, vari[0]); + vari[1] = rtengine::max(0.000001f, vari[1]); + vari[2] = rtengine::max(0.000001f, vari[2]); + vari[3] = rtengine::max(0.000001f, kr3 * vari[3]); + if (settings->verbose) { + printf("LUM var0=%f var1=%f var2=%f var3=%f\n",vari[0], vari[1], vari[2], vari[3]); + } // float* noisevarlum = nullptr; // we need a dummy to pass it to WaveletDenoiseAllL int GWL = labco->W; int GHL = labco->H; @@ -1023,15 +1026,15 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if (noisecfr < 0.f) { - noisecfr = 0.0001f; + noisecfr = 0.00001f; } if (noiseccr < 0.f) { - noiseccr = 0.0001f; + noiseccr = 0.00001f; } if (noisecfb < 0.f) { - noisecfb = 0.0001f; + noisecfb = 0.00001f; } if (noiseccb < 0.f) { @@ -1062,7 +1065,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const float k3 = 0.f; if (cp.chromfi < 0.2f) { - k1 = 0.f; + k1 = 0.05f; k2 = 0.f; k3 = 0.f; } else if (cp.chromfi < 0.3f) { @@ -1116,7 +1119,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const k3 = 1.f; } - float minic = 0.0001f; + float minic = 0.000001f; variC[0] = max(minic, variC[0]); variC[1] = max(minic, k1 * variC[1]); variC[2] = max(minic, k2 * variC[2]); @@ -1131,15 +1134,12 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const float k5 = 0.f; float k6 = 0.f; - if (cp.chromco == 0.01f) { - k4 = 0.f; - k5 = 0.0f; - } else if (cp.chromco < 0.2f) { + if (cp.chromco < 0.2f) { k4 = 0.1f; - k5 = 0.0f; + k5 = 0.02f; } else if (cp.chromco < 0.5f) { k4 = 0.15f; - k5 = 0.0f; + k5 = 0.05f; } else if (cp.chromco < 1.f) { k4 = 0.15f; k5 = 0.1f; @@ -1157,10 +1157,10 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const k5 = 1.f; } - variC[4] = max(0.0001f, k4 * variC[4]); - variC[5] = max(0.0001f, k5 * variC[5]); - variCb[4] = max(0.0001f, k4 * variCb[4]); - variCb[5] = max(0.0001f, k5 * variCb[5]); + variC[4] = max(0.000001f, k4 * variC[4]); + variC[5] = max(0.000001f, k5 * variC[5]); + variCb[4] = max(0.000001f, k4 * variCb[4]); + variCb[5] = max(0.000001f, k5 * variCb[5]); if (cp.chromco < 4.f) { k6 = 0.f; @@ -1172,8 +1172,11 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const k6 = 1.f; } - variC[6] = max(0.0001f, k6 * variC[6]); - variCb[6] = max(0.0001f, k6 * variCb[6]); + variC[6] = max(0.00001f, k6 * variC[6]); + variCb[6] = max(0.00001f, k6 * variCb[6]); + if (settings->verbose) { + printf("CHRO var0=%f va1=%f va2=%f va3=%f va4=%f val5=%f va6=%f\n", variC[0], variC[1], variC[2], variC[3],variC[4],variC[5], variC[6]); + } /* for (int y = 0; y < 7; y++) { printf("y=%i madL=%f varia=%f variab=%f\n", y, madL[y][1], variC[y], variCb[y]); From 60bb7b520b2222d127a258a8305d1fedcacbd5d5 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 12 Apr 2020 14:08:06 +0200 Subject: [PATCH 04/28] Wavelet - Fixed crash when blur residual high and zoom high --- rtdata/languages/default | 1 + rtengine/ipwavelet.cc | 64 +++++++++++++++++++++++----------------- rtgui/wavelet.cc | 2 ++ 3 files changed, 40 insertions(+), 27 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 64af97689..b200a2ad7 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2283,6 +2283,7 @@ TP_WAVELET_RE2;Unchanged TP_WAVELET_RE3;Reduced TP_WAVELET_RESBLUR;Blur Luminance TP_WAVELET_RESBLURC;Blur Chroma +TP_WAVELET_RESBLUR_TOOLTIP;Disabled if zoom > about 500% TP_WAVELET_RESCHRO;Intensity TP_WAVELET_RESCON;Shadows TP_WAVELET_RESCONH;Highlights diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 264b5df6d..948b76f2b 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -2201,22 +2201,27 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * //Blur luma if (cp.blurres != 0.f && cp.resena) { - float rad = 0.7f * cp.blurres / skip; - float * bef = new float[W_L * H_L]; - float * aft = new float[W_L * H_L]; + int minWL = min(W_L, H_L); + float k = 0.5f; + //printf("skip=%i WL=%i HL=%i min=%i\n", skip, W_L, H_L, minWL); + if(minWL > 140) {//disabled if too low windows + float rad = k * cp.blurres / skip; + float * bef = new float[W_L * H_L]; + float * aft = new float[W_L * H_L]; + + for (int i = 0; i < H_L * W_L; i++) { + bef[i] = WavCoeffs_L0[i]; + } - for (int i = 0; i < H_L * W_L; i++) { - bef[i] = WavCoeffs_L0[i]; - } + boxblur(bef, aft, rad, W_L, H_L, false); - boxblur(bef, aft, rad, W_L, H_L, false); + for (int i = 0; i < H_L * W_L; i++) { + WavCoeffs_L0[i] = aft[i]; + } - for (int i = 0; i < H_L * W_L; i++) { - WavCoeffs_L0[i] = aft[i]; - } - - delete[] bef; - delete[] aft; + delete[] bef; + delete[] aft; + } } // @@ -2670,22 +2675,27 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float //Blur chroma if (cp.blurcres != 0.f && cp.resena) { - float rad = 0.7f * cp.blurcres / skip; - float * bef = new float[W_L * H_L]; - float * aft = new float[W_L * H_L]; + int minWL = min(W_L, H_L); + float k = 0.5f; + //printf("skip=%i WL=%i HL=%i min=%i\n", skip, W_L, H_L, minWL); + if(minWL > 140) {//disabled if too low windows + float rad = k * cp.blurcres / skip; + float * bef = new float[W_L * H_L]; + float * aft = new float[W_L * H_L]; - for (int i = 0; i < H_L * W_L; i++) { - bef[i] = WavCoeffs_ab0[i]; + for (int i = 0; i < H_L * W_L; i++) { + bef[i] = WavCoeffs_ab0[i]; + } + + boxblur(bef, aft, rad, W_L, H_L, false); + + for (int i = 0; i < H_L * W_L; i++) { + WavCoeffs_ab0[i] = aft[i]; + } + + delete[] bef; + delete[] aft; } - - boxblur(bef, aft, rad, W_L, H_L, false); - - for (int i = 0; i < H_L * W_L; i++) { - WavCoeffs_ab0[i] = aft[i]; - } - - delete[] bef; - delete[] aft; } diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index af159d480..17689be50 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -800,6 +800,8 @@ Wavelet::Wavelet() : blurBox->pack_start(*resblur); blurBox->pack_start(*resblurc); blurFrame->add(*blurBox); + resblur->set_tooltip_text(M("TP_WAVELET_RESBLUR_TOOLTIP")); + resblurc->set_tooltip_text(M("TP_WAVELET_RESBLUR_TOOLTIP")); chromaFrame->set_label_align(0.025, 0.5); ToolParamBlock* const chromaBox = Gtk::manage(new ToolParamBlock()); From 71da91c85f5bf9986dfb1d0d32e1aeea19dbab16 Mon Sep 17 00:00:00 2001 From: Desmis Date: Mon, 13 Apr 2020 09:04:38 +0200 Subject: [PATCH 05/28] Wavelet levels - Added Damper to local contrast final --- rtdata/languages/default | 5 ++++- rtengine/ipwavelet.cc | 8 +++++--- rtengine/procparams.cc | 4 ++++ rtengine/procparams.h | 1 + rtgui/paramsedited.cc | 6 ++++++ rtgui/paramsedited.h | 1 + rtgui/wavelet.cc | 31 +++++++++++++++++++++++++++---- rtgui/wavelet.h | 3 +++ 8 files changed, 51 insertions(+), 8 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index b200a2ad7..a5cd7746e 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -816,6 +816,7 @@ HISTORY_MSG_WAVBL;Blur levels HISTORY_MSG_BLURWAV;Blur luminance HISTORY_MSG_BLURCWAV;Blur chroma HISTORY_MSG_EDGEFFECT;Edge Damper +HISTORY_MSG_SIGMAFIN;Final contrast Damper HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOT;Snapshot @@ -2227,6 +2228,7 @@ TP_WAVELET_EDSL;Threshold Sliders TP_WAVELET_EDTYPE;Local contrast method TP_WAVELET_EDVAL;Strength TP_WAVELET_FINAL;Final Touchup +TP_WAVELET_FINCFRAME;Final Local Contrast TP_WAVELET_FINEST;Finest TP_WAVELET_HIGHLIGHT;Highlight luminance range TP_WAVELET_HS1;Whole luminance range @@ -2273,7 +2275,7 @@ TP_WAVELET_NPTYPE_TOOLTIP;This algorithm uses the proximity of a pixel and eight TP_WAVELET_OLDSH;Algorithm using negatives values TP_WAVELET_OPACITY;Opacity Blue-Yellow TP_WAVELET_OPACITYW;Contrast balance d/v-h curve -TP_WAVELET_OPACITYWL;Final local contrast +TP_WAVELET_OPACITYWL;Local contrast TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. TP_WAVELET_PASTEL;Pastel chroma TP_WAVELET_PROC;Process @@ -2294,6 +2296,7 @@ TP_WAVELET_SHA;Sharp mask TP_WAVELET_SHFRAME;Shadows/Highlights TP_WAVELET_SHOWMASK;Show wavelet 'mask' TP_WAVELET_SIGMA;Damper +TP_WAVELET_SIGMAFIN;Damper TP_WAVELET_SIGMA_TOOLTIP;The effect of the contrast sliders is stronger in medium contrast details, and weaker in high and low contrast details.\n With this slider you can control how quickly the effect dampens towards the extreme contrasts.\n The higher the slider is set, the wider the range of contrasts which will get a strong change, and the higher the risk to generate artifacts.\n The lower it is, the more pinpoint will the effect be applied to a narrow range of contrast values. TP_WAVELET_SKIN;Skin targetting/protection TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 948b76f2b..157fb6239 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -113,6 +113,7 @@ struct cont_params { int TMmeth; float tmstrength; float balan; + float sigmafin; int ite; int contmet; bool opaW; @@ -191,6 +192,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.ite = params->wavelet.iter; cp.tonemap = params->wavelet.tmrs != 0; cp.bam = false; + cp.sigmafin = params->wavelet.sigmafin; if (params->wavelet.TMmethod == "cont") { cp.contmet = 1; @@ -2955,11 +2957,11 @@ void ImProcFunctions::finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0, if (cp.diagcurv && cp.finena && MaxP[level] > 0.f && mean[level] != 0.f && sigma[level] != 0.f) { //curve float insigma = 0.666f; //SD float logmax = log(MaxP[level]); //log Max - float rapX = (mean[level] + sigma[level]) / MaxP[level]; //rapport between sD / max + float rapX = (mean[level] + cp.sigmafin * sigma[level]) / MaxP[level]; //rapport between sD / max float inx = log(insigma); float iny = log(rapX); float rap = inx / iny; //koef - float asig = 0.166f / sigma[level]; + float asig = 0.166f / (sigma[level] * cp.sigmafin); float bsig = 0.5f - asig * mean[level]; float amean = 0.5f / mean[level]; @@ -2970,7 +2972,7 @@ void ImProcFunctions::finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0, for (int i = 0; i < W_L * H_L; i++) { float absciss; - if (std::fabs(WavCoeffs_L[dir][i]) >= (mean[level] + sigma[level])) { //for max + if (std::fabs(WavCoeffs_L[dir][i]) >= (mean[level] + cp.sigmafin * sigma[level])) { //for max float valcour = xlogf(std::fabs(WavCoeffs_L[dir][i])); float valc = valcour - logmax; float vald = valc * rap; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index b02f1970c..0d8324d4e 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2263,6 +2263,7 @@ WaveletParams::WaveletParams() : tmr(false), strength(100), balance(0), + sigmafin(1.0), iter(0), expcontrast(false), expchroma(false), @@ -2377,6 +2378,7 @@ bool WaveletParams::operator ==(const WaveletParams& other) const && tmr == other.tmr && strength == other.strength && balance == other.balance + && sigmafin == other.sigmafin && iter == other.iter && expcontrast == other.expcontrast && expchroma == other.expchroma @@ -3514,6 +3516,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.enabled, "Wavelet", "Enabled", wavelet.enabled, keyFile); saveToKeyfile(!pedited || pedited->wavelet.strength, "Wavelet", "Strength", wavelet.strength, keyFile); saveToKeyfile(!pedited || pedited->wavelet.balance, "Wavelet", "Balance", wavelet.balance, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.sigmafin, "Wavelet", "Sigmafin", wavelet.sigmafin, keyFile); saveToKeyfile(!pedited || pedited->wavelet.iter, "Wavelet", "Iter", wavelet.iter, keyFile); saveToKeyfile(!pedited || pedited->wavelet.thres, "Wavelet", "MaxLev", wavelet.thres, keyFile); saveToKeyfile(!pedited || pedited->wavelet.Tilesmethod, "Wavelet", "TilesMethod", wavelet.Tilesmethod, keyFile); @@ -4691,6 +4694,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Wavelet", "Enabled", pedited, wavelet.enabled, pedited->wavelet.enabled); assignFromKeyfile(keyFile, "Wavelet", "Strength", pedited, wavelet.strength, pedited->wavelet.strength); assignFromKeyfile(keyFile, "Wavelet", "Balance", pedited, wavelet.balance, pedited->wavelet.balance); + assignFromKeyfile(keyFile, "Wavelet", "Sigmafin", pedited, wavelet.sigmafin, pedited->wavelet.sigmafin); assignFromKeyfile(keyFile, "Wavelet", "Iter", pedited, wavelet.iter, pedited->wavelet.iter); assignFromKeyfile(keyFile, "Wavelet", "Median", pedited, wavelet.median, pedited->wavelet.median); assignFromKeyfile(keyFile, "Wavelet", "Medianlev", pedited, wavelet.medianlev, pedited->wavelet.medianlev); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 4e2b0c275..c26b02de4 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1221,6 +1221,7 @@ struct WaveletParams { bool tmr; int strength; int balance; + double sigmafin; int iter; bool expcontrast; bool expchroma; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 0faee0fd3..9eff3c4ce 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -475,6 +475,7 @@ void ParamsEdited::set(bool v) wavelet.strength = v; wavelet.balance = v; wavelet.iter = v; + wavelet.sigmafin = v; wavelet.median = v; wavelet.medianlev = v; wavelet.linkedg = v; @@ -1085,6 +1086,7 @@ void ParamsEdited::initFrom(const std::vector& wavelet.strength = wavelet.strength && p.wavelet.strength == other.wavelet.strength; wavelet.balance = wavelet.balance && p.wavelet.balance == other.wavelet.balance; wavelet.iter = wavelet.iter && p.wavelet.iter == other.wavelet.iter; + wavelet.sigmafin = wavelet.sigmafin && p.wavelet.sigmafin == other.wavelet.sigmafin; wavelet.median = wavelet.median && p.wavelet.median == other.wavelet.median; wavelet.medianlev = wavelet.medianlev && p.wavelet.medianlev == other.wavelet.medianlev; wavelet.linkedg = wavelet.linkedg && p.wavelet.linkedg == other.wavelet.linkedg; @@ -2893,6 +2895,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.balance = mods.wavelet.balance; } + if (wavelet.sigmafin) { + toEdit.wavelet.sigmafin = mods.wavelet.sigmafin; + } + if (wavelet.iter) { toEdit.wavelet.iter = mods.wavelet.iter; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index d1be2c57e..351096a7e 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -499,6 +499,7 @@ struct WaveletParamsEdited { bool strength; bool balance; bool iter; + bool sigmafin; bool median; bool medianlev; bool linkedg; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 17689be50..c12e216cf 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -112,6 +112,7 @@ Wavelet::Wavelet() : strength(Gtk::manage(new Adjuster(M("TP_WAVELET_STRENGTH"), 0, 100, 1, 100))), balance(Gtk::manage(new Adjuster(M("TP_WAVELET_BALANCE"), -30, 100, 1, 0))), iter(Gtk::manage(new Adjuster(M("TP_WAVELET_ITER"), -3, 3, 1, 0))), + sigmafin(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMAFIN"), 0.025, 2.5, 0.01, 1.))), hueskin(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_HUESKIN"), -314., 314., -5., 25., 170., 120., 0, false))), hueskin2(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_HUESKY"), -314., 314., -260., -250, -130., -140., 0, false))), hllev(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_HIGHLIGHT"), 0., 100., 50., 75., 100., 98., 0, false))), @@ -162,6 +163,7 @@ Wavelet::Wavelet() : blurFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_BLURFRAME")))), chromaFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_CHROMAFRAME")))), chroFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_CHROFRAME")))), + fincFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_FINCFRAME")))), wavLabels(Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER))), labmC(Gtk::manage(new Gtk::Label(M("TP_WAVELET_CTYPE") + ":"))), labmNP(Gtk::manage(new Gtk::Label(M("TP_WAVELET_NPTYPE") + ":"))), @@ -207,6 +209,8 @@ Wavelet::Wavelet() : EvWavresblur = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLURWAV"); EvWavresblurc = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLURCWAV"); EvWavedgeffect = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_EDGEFFECT"); + EvWavsigmafin = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_SIGMAFIN"); + expsettings->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expsettings)); expcontrast->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expcontrast)); @@ -978,7 +982,7 @@ Wavelet::Wavelet() : iter->setAdjusterListener(this); iter->set_tooltip_text(M("TP_WAVELET_ITER_TOOLTIP")); - Gtk::HSeparator* const separatorbalend = Gtk::manage(new Gtk::HSeparator()); +// Gtk::HSeparator* const separatorbalend = Gtk::manage(new Gtk::HSeparator()); opacityCurveEditorWL->setCurveListener(this); @@ -986,6 +990,7 @@ Wavelet::Wavelet() : opacityShapeWL->setIdentityValue(0.); opacityShapeWL->setResetCurve(FlatCurveType(default_params.opacityCurveWL.at(0)), default_params.opacityCurveWL); opacityShapeWL->setTooltip(M("TP_WAVELET_OPACITYWL_TOOLTIP")); + sigmafin->setAdjusterListener(this); // This will add the reset button at the end of the curveType buttons opacityCurveEditorWL->curveListComplete(); @@ -1004,6 +1009,13 @@ Wavelet::Wavelet() : tmr->set_tooltip_text(M("TP_WAVELET_BALCHRO_TOOLTIP")); tmrConn = tmr->signal_toggled().connect(sigc::mem_fun(*this, &Wavelet::tmrToggled)); + fincFrame->set_label_align(0.025, 0.5); + ToolParamBlock* const fincBox = Gtk::manage(new ToolParamBlock()); + fincBox->pack_start(*opacityCurveEditorWL, Gtk::PACK_SHRINK, 2); + fincBox->pack_start(*sigmafin); + fincFrame->add(*fincBox); + + ToolParamBlock* const finalBox = Gtk::manage(new ToolParamBlock()); finalBox->pack_start(*ctboxBA); @@ -1014,9 +1026,10 @@ Wavelet::Wavelet() : finalBox->pack_start(*iter); finalBox->pack_start(*tmr); - finalBox->pack_start(*separatorbalend, Gtk::PACK_SHRINK, 2); - finalBox->pack_start(*opacityCurveEditorWL, Gtk::PACK_SHRINK, 2); - +// finalBox->pack_start(*separatorbalend, Gtk::PACK_SHRINK, 2); +// finalBox->pack_start(*opacityCurveEditorWL, Gtk::PACK_SHRINK, 2); +// finalBox->pack_start(*sigmafin); + finalBox->pack_start(*fincFrame); finalBox->pack_start(*curveEditorG, Gtk::PACK_SHRINK, 4); finalBox->pack_start(*softradend); @@ -1420,6 +1433,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) strength->setValue(pp->wavelet.strength); balance->setValue(pp->wavelet.balance); iter->setValue(pp->wavelet.iter); + sigmafin->setValue(pp->wavelet.sigmafin); for (int i = 0; i < 9; i++) { correction[i]->setValue(pp->wavelet.c[i]); @@ -1537,6 +1551,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) thres->setEditedState(pedited->wavelet.thres ? Edited : UnEdited); balance->setEditedState(pedited->wavelet.balance ? Edited : UnEdited); iter->setEditedState(pedited->wavelet.iter ? Edited : UnEdited); + sigmafin->setEditedState(pedited->wavelet.sigmafin ? Edited : UnEdited); threshold->setEditedState(pedited->wavelet.threshold ? Edited : UnEdited); threshold2->setEditedState(pedited->wavelet.threshold2 ? Edited : UnEdited); edgedetect->setEditedState(pedited->wavelet.edgedetect ? Edited : UnEdited); @@ -1808,6 +1823,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pp->wavelet.iter = (int) iter->getValue(); pp->wavelet.wavclCurve = clshape->getCurve(); + pp->wavelet.sigmafin = sigmafin->getValue(); for (int i = 0; i < 9; i++) { pp->wavelet.c[i] = (int) correction[i]->getValue(); @@ -1914,6 +1930,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.softradend = softradend->getEditedState(); pedited->wavelet.balance = balance->getEditedState(); pedited->wavelet.iter = iter->getEditedState(); + pedited->wavelet.sigmafin = sigmafin->getEditedState(); pedited->wavelet.wavclCurve = !clshape->isUnChanged(); pedited->wavelet.expcontrast = !expcontrast->get_inconsistent(); pedited->wavelet.expchroma = !expchroma->get_inconsistent(); @@ -2094,6 +2111,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit strength->setDefault(defParams->wavelet.strength); balance->setDefault(defParams->wavelet.balance); iter->setDefault(defParams->wavelet.iter); + sigmafin->setDefault(defParams->wavelet.sigmafin); sigma->setDefault(defParams->wavelet.sigma); offset->setDefault(defParams->wavelet.offset); lowthr->setDefault(defParams->wavelet.lowthr); @@ -2216,6 +2234,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit strength->setDefaultEditedState(pedited->wavelet.strength ? Edited : UnEdited); balance->setDefaultEditedState(pedited->wavelet.balance ? Edited : UnEdited); iter->setDefaultEditedState(pedited->wavelet.iter ? Edited : UnEdited); + sigmafin->setDefaultEditedState(pedited->wavelet.sigmafin ? Edited : UnEdited); level0noise->setDefaultEditedState(pedited->wavelet.level0noise ? Edited : UnEdited); level1noise->setDefaultEditedState(pedited->wavelet.level1noise ? Edited : UnEdited); level2noise->setDefaultEditedState(pedited->wavelet.level2noise ? Edited : UnEdited); @@ -2278,6 +2297,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit strength->setDefaultEditedState(Irrelevant); balance->setDefaultEditedState(Irrelevant); iter->setDefaultEditedState(Irrelevant); + sigmafin->setDefaultEditedState(Irrelevant); for (int i = 0; i < 9; i++) { correction[i]->setDefaultEditedState(Irrelevant); @@ -2810,6 +2830,7 @@ void Wavelet::setBatchMode(bool batchMode) strength->showEditedCB(); balance->showEditedCB(); iter->showEditedCB(); + sigmafin->showEditedCB(); level0noise->showEditedCB(); level1noise->showEditedCB(); level2noise->showEditedCB(); @@ -2959,6 +2980,8 @@ void Wavelet::adjusterChanged(Adjuster* a, double newval) listener->panelChanged(EvWavbalance, balance->getTextValue()); } else if (a == iter) { listener->panelChanged(EvWaviter, iter->getTextValue()); + } else if (a == sigmafin) { + listener->panelChanged(EvWavsigmafin, sigmafin->getTextValue()); } else if (a == greenhigh) { listener->panelChanged(EvWavgreenhigh, greenhigh->getTextValue()); } else if (a == bluehigh) { diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index d1b4bb7c3..271aea5b2 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -93,6 +93,7 @@ private: rtengine::ProcEvent EvWavresblur; rtengine::ProcEvent EvWavresblurc; rtengine::ProcEvent EvWavedgeffect; + rtengine::ProcEvent EvWavsigmafin; void foldAllButMe(GdkEventButton* event, MyExpander *expander); @@ -218,6 +219,7 @@ private: Adjuster* const strength; Adjuster* const balance; Adjuster* const iter; + Adjuster* const sigmafin; Adjuster* greenlow; Adjuster* bluelow; @@ -294,6 +296,7 @@ private: Gtk::Frame* const blurFrame; Gtk::Frame* const chromaFrame; Gtk::Frame* const chroFrame; + Gtk::Frame* const fincFrame; Gtk::Label* const wavLabels; Gtk::Label* const labmC; From 25513c85bce07ebc0f2ff15f4688fa02cee5e31a Mon Sep 17 00:00:00 2001 From: Desmis Date: Mon, 13 Apr 2020 17:52:56 +0200 Subject: [PATCH 06/28] Improve toning with meanab sigmaab and damper --- rtdata/languages/default | 1 + rtengine/improcfun.h | 2 +- rtengine/ipwavelet.cc | 92 ++++++++++++++++++++++++++++------------ rtengine/procparams.cc | 4 ++ rtengine/procparams.h | 1 + rtgui/paramsedited.cc | 6 +++ rtgui/paramsedited.h | 1 + rtgui/wavelet.cc | 15 ++++++- rtgui/wavelet.h | 2 + 9 files changed, 96 insertions(+), 28 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index a5cd7746e..7dd47e154 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -817,6 +817,7 @@ HISTORY_MSG_BLURWAV;Blur luminance HISTORY_MSG_BLURCWAV;Blur chroma HISTORY_MSG_EDGEFFECT;Edge Damper HISTORY_MSG_SIGMAFIN;Final contrast Damper +HISTORY_MSG_SIGMATON;Toning Damper HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOT;Snapshot diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index d003df644..9d4a0235c 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -216,7 +216,7 @@ public: void finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, const cont_params &cp, int W_L, int H_L, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL); void ContAllAB(LabImage * lab, int maxlvl, float **varhue, float **varchrom, float ** WavCoeffs_a, float * WavCoeffs_a0, int level, int dir, const WavOpacityCurveW & waOpacityCurveW, struct cont_params &cp, - int W_ab, int H_ab, const bool useChannelA); + int W_ab, int H_ab, const bool useChannelA, float *meanab, float *sigmaab); void Evaluate2(const wavelet_decomposition &WaveletCoeffs_L, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN); void Eval2(float ** WavCoeffs_L, int level, diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 157fb6239..9d50dedff 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -114,6 +114,7 @@ struct cont_params { float tmstrength; float balan; float sigmafin; + float sigmaton; int ite; int contmet; bool opaW; @@ -193,6 +194,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.tonemap = params->wavelet.tmrs != 0; cp.bam = false; cp.sigmafin = params->wavelet.sigmafin; + cp.sigmaton = params->wavelet.sigmaton; if (params->wavelet.TMmethod == "cont") { cp.contmet = 1; @@ -931,9 +933,11 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const vari[1] = rtengine::max(0.000001f, vari[1]); vari[2] = rtengine::max(0.000001f, vari[2]); vari[3] = rtengine::max(0.000001f, kr3 * vari[3]); + if (settings->verbose) { - printf("LUM var0=%f var1=%f var2=%f var3=%f\n",vari[0], vari[1], vari[2], vari[3]); + printf("LUM var0=%f var1=%f var2=%f var3=%f\n", vari[0], vari[1], vari[2], vari[3]); } + // float* noisevarlum = nullptr; // we need a dummy to pass it to WaveletDenoiseAllL int GWL = labco->W; int GHL = labco->H; @@ -1176,9 +1180,11 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const variC[6] = max(0.00001f, k6 * variC[6]); variCb[6] = max(0.00001f, k6 * variCb[6]); + if (settings->verbose) { - printf("CHRO var0=%f va1=%f va2=%f va3=%f va4=%f val5=%f va6=%f\n", variC[0], variC[1], variC[2], variC[3],variC[4],variC[5], variC[6]); + printf("CHRO var0=%f va1=%f va2=%f va3=%f va4=%f val5=%f va6=%f\n", variC[0], variC[1], variC[2], variC[3], variC[4], variC[5], variC[6]); } + /* for (int y = 0; y < 7; y++) { printf("y=%i madL=%f varia=%f variab=%f\n", y, madL[y][1], variC[y], variCb[y]); @@ -2203,27 +2209,28 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * //Blur luma if (cp.blurres != 0.f && cp.resena) { - int minWL = min(W_L, H_L); - float k = 0.5f; - //printf("skip=%i WL=%i HL=%i min=%i\n", skip, W_L, H_L, minWL); - if(minWL > 140) {//disabled if too low windows - float rad = k * cp.blurres / skip; - float * bef = new float[W_L * H_L]; - float * aft = new float[W_L * H_L]; - - for (int i = 0; i < H_L * W_L; i++) { - bef[i] = WavCoeffs_L0[i]; - } + int minWL = min(W_L, H_L); + float k = 0.5f; - boxblur(bef, aft, rad, W_L, H_L, false); + //printf("skip=%i WL=%i HL=%i min=%i\n", skip, W_L, H_L, minWL); + if (minWL > 140) { //disabled if too low windows + float rad = k * cp.blurres / skip; + float * bef = new float[W_L * H_L]; + float * aft = new float[W_L * H_L]; - for (int i = 0; i < H_L * W_L; i++) { - WavCoeffs_L0[i] = aft[i]; - } - - delete[] bef; - delete[] aft; + for (int i = 0; i < H_L * W_L; i++) { + bef[i] = WavCoeffs_L0[i]; } + + boxblur(bef, aft, rad, W_L, H_L, false); + + for (int i = 0; i < H_L * W_L; i++) { + WavCoeffs_L0[i] = aft[i]; + } + + delete[] bef; + delete[] aft; + } } // @@ -2679,8 +2686,9 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float if (cp.blurcres != 0.f && cp.resena) { int minWL = min(W_L, H_L); float k = 0.5f; + //printf("skip=%i WL=%i HL=%i min=%i\n", skip, W_L, H_L, minWL); - if(minWL > 140) {//disabled if too low windows + if (minWL > 140) { //disabled if too low windows float rad = k * cp.blurcres / skip; float * bef = new float[W_L * H_L]; float * aft = new float[W_L * H_L]; @@ -2722,7 +2730,7 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float int Hlvl_ab = WaveletCoeffs_ab.level_H(lvl); float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); - ContAllAB(labco, maxlvl, varhue, varchrom, WavCoeffs_ab, WavCoeffs_ab0, lvl, dir, waOpacityCurveW, cp, Wlvl_ab, Hlvl_ab, useChannelA); + ContAllAB(labco, maxlvl, varhue, varchrom, WavCoeffs_ab, WavCoeffs_ab0, lvl, dir, waOpacityCurveW, cp, Wlvl_ab, Hlvl_ab, useChannelA, meanab, sigmaab); if (wavblcurve && wavcurvecomp && cp.blena && cp.chrwav > 0.f) { @@ -3846,7 +3854,7 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz } void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, float **varchrom, float ** WavCoeffs_ab, float * WavCoeffs_ab0, int level, int dir, const WavOpacityCurveW & waOpacityCurveW, struct cont_params &cp, - int W_ab, int H_ab, const bool useChannelA) + int W_ab, int H_ab, const bool useChannelA, float *meanab, float *sigmaab) { float cpMul = cp.mul[level]; @@ -3981,15 +3989,47 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f } if ((useOpacity && level < 9 && mulOpacity != 0.f) && cp.toningena) { //toning + float mea[10]; + float effect = cp.sigmaton; + float betaab = 0.f; + float offs = 1.f; - float beta = (1024.f + 20.f * mulOpacity) / 1024.f ; + calceffect(level, meanab, sigmaab, mea, effect, offs); + + for (int co = 0; co < W_ab * H_ab; co++) { + float WavCab = std::fabs(WavCoeffs_ab[dir][co]); + + if (WavCab < mea[0]) { + betaab = 0.05f; + } else if (WavCab < mea[1]) { + betaab = 0.2f; + } else if (WavCab < mea[2]) { + betaab = 0.7f; + } else if (WavCab < mea[3]) { + betaab = 1.f; //standard + } else if (WavCab < mea[4]) { + betaab = 1.f; + } else if (WavCab < mea[5]) { + betaab = 0.8f; //+sigma + } else if (WavCab < mea[6]) { + betaab = 0.6f; + } else if (WavCab < mea[7]) { + betaab = 0.4f; + } else if (WavCab < mea[8]) { + betaab = 0.2f; // + 2 sigma + } else if (WavCab < mea[9]) { + betaab = 0.1f; + } else { + betaab = 0.0f; + } + } + + float beta = (1024.f + 50.f * mulOpacity * betaab) / 1024.f ; - //float beta = (1000.f * mulOpacity); for (int i = 0; i < W_ab * H_ab; i++) { WavCoeffs_ab[dir][i] *= beta; } - // WavCoeffs_ab[dir][i] += beta; } if (waOpacityCurveW) { diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 0d8324d4e..bac9e86ff 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2264,6 +2264,7 @@ WaveletParams::WaveletParams() : strength(100), balance(0), sigmafin(1.0), + sigmaton(1.0), iter(0), expcontrast(false), expchroma(false), @@ -2379,6 +2380,7 @@ bool WaveletParams::operator ==(const WaveletParams& other) const && strength == other.strength && balance == other.balance && sigmafin == other.sigmafin + && sigmaton == other.sigmaton && iter == other.iter && expcontrast == other.expcontrast && expchroma == other.expchroma @@ -3517,6 +3519,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.strength, "Wavelet", "Strength", wavelet.strength, keyFile); saveToKeyfile(!pedited || pedited->wavelet.balance, "Wavelet", "Balance", wavelet.balance, keyFile); saveToKeyfile(!pedited || pedited->wavelet.sigmafin, "Wavelet", "Sigmafin", wavelet.sigmafin, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.sigmaton, "Wavelet", "Sigmaton", wavelet.sigmaton, keyFile); saveToKeyfile(!pedited || pedited->wavelet.iter, "Wavelet", "Iter", wavelet.iter, keyFile); saveToKeyfile(!pedited || pedited->wavelet.thres, "Wavelet", "MaxLev", wavelet.thres, keyFile); saveToKeyfile(!pedited || pedited->wavelet.Tilesmethod, "Wavelet", "TilesMethod", wavelet.Tilesmethod, keyFile); @@ -4695,6 +4698,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Wavelet", "Strength", pedited, wavelet.strength, pedited->wavelet.strength); assignFromKeyfile(keyFile, "Wavelet", "Balance", pedited, wavelet.balance, pedited->wavelet.balance); assignFromKeyfile(keyFile, "Wavelet", "Sigmafin", pedited, wavelet.sigmafin, pedited->wavelet.sigmafin); + assignFromKeyfile(keyFile, "Wavelet", "Sigmaton", pedited, wavelet.sigmaton, pedited->wavelet.sigmaton); assignFromKeyfile(keyFile, "Wavelet", "Iter", pedited, wavelet.iter, pedited->wavelet.iter); assignFromKeyfile(keyFile, "Wavelet", "Median", pedited, wavelet.median, pedited->wavelet.median); assignFromKeyfile(keyFile, "Wavelet", "Medianlev", pedited, wavelet.medianlev, pedited->wavelet.medianlev); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index c26b02de4..e5ac570af 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1222,6 +1222,7 @@ struct WaveletParams { int strength; int balance; double sigmafin; + double sigmaton; int iter; bool expcontrast; bool expchroma; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 9eff3c4ce..e83e74bc9 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -476,6 +476,7 @@ void ParamsEdited::set(bool v) wavelet.balance = v; wavelet.iter = v; wavelet.sigmafin = v; + wavelet.sigmaton = v; wavelet.median = v; wavelet.medianlev = v; wavelet.linkedg = v; @@ -1087,6 +1088,7 @@ void ParamsEdited::initFrom(const std::vector& wavelet.balance = wavelet.balance && p.wavelet.balance == other.wavelet.balance; wavelet.iter = wavelet.iter && p.wavelet.iter == other.wavelet.iter; wavelet.sigmafin = wavelet.sigmafin && p.wavelet.sigmafin == other.wavelet.sigmafin; + wavelet.sigmaton = wavelet.sigmaton && p.wavelet.sigmaton == other.wavelet.sigmaton; wavelet.median = wavelet.median && p.wavelet.median == other.wavelet.median; wavelet.medianlev = wavelet.medianlev && p.wavelet.medianlev == other.wavelet.medianlev; wavelet.linkedg = wavelet.linkedg && p.wavelet.linkedg == other.wavelet.linkedg; @@ -2899,6 +2901,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.sigmafin = mods.wavelet.sigmafin; } + if (wavelet.sigmaton) { + toEdit.wavelet.sigmaton = mods.wavelet.sigmaton; + } + if (wavelet.iter) { toEdit.wavelet.iter = mods.wavelet.iter; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 351096a7e..773f5592d 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -500,6 +500,7 @@ struct WaveletParamsEdited { bool balance; bool iter; bool sigmafin; + bool sigmaton; bool median; bool medianlev; bool linkedg; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index c12e216cf..db3687b3e 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -113,6 +113,7 @@ Wavelet::Wavelet() : balance(Gtk::manage(new Adjuster(M("TP_WAVELET_BALANCE"), -30, 100, 1, 0))), iter(Gtk::manage(new Adjuster(M("TP_WAVELET_ITER"), -3, 3, 1, 0))), sigmafin(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMAFIN"), 0.025, 2.5, 0.01, 1.))), + sigmaton(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMAFIN"), 0.025, 2.5, 0.01, 1.))), hueskin(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_HUESKIN"), -314., 314., -5., 25., 170., 120., 0, false))), hueskin2(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_HUESKY"), -314., 314., -260., -250, -130., -140., 0, false))), hllev(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_HIGHLIGHT"), 0., 100., 50., 75., 100., 98., 0, false))), @@ -210,6 +211,7 @@ Wavelet::Wavelet() : EvWavresblurc = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLURCWAV"); EvWavedgeffect = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_EDGEFFECT"); EvWavsigmafin = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_SIGMAFIN"); + EvWavsigmaton = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_SIGMATON"); expsettings->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expsettings)); @@ -487,6 +489,7 @@ Wavelet::Wavelet() : // Toning ToolParamBlock* const tonBox = Gtk::manage(new ToolParamBlock()); + sigmaton->setAdjusterListener(this); opaCurveEditorG->setCurveListener(this); @@ -498,7 +501,7 @@ Wavelet::Wavelet() : opaCurveEditorG->curveListComplete(); opaCurveEditorG->show(); - + tonBox->pack_start(*sigmaton); tonBox->pack_start(*opaCurveEditorG, Gtk::PACK_SHRINK, 2); opacityCurveEditorG->setCurveListener(this); @@ -1434,6 +1437,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) balance->setValue(pp->wavelet.balance); iter->setValue(pp->wavelet.iter); sigmafin->setValue(pp->wavelet.sigmafin); + sigmaton->setValue(pp->wavelet.sigmaton); for (int i = 0; i < 9; i++) { correction[i]->setValue(pp->wavelet.c[i]); @@ -1552,6 +1556,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) balance->setEditedState(pedited->wavelet.balance ? Edited : UnEdited); iter->setEditedState(pedited->wavelet.iter ? Edited : UnEdited); sigmafin->setEditedState(pedited->wavelet.sigmafin ? Edited : UnEdited); + sigmaton->setEditedState(pedited->wavelet.sigmaton ? Edited : UnEdited); threshold->setEditedState(pedited->wavelet.threshold ? Edited : UnEdited); threshold2->setEditedState(pedited->wavelet.threshold2 ? Edited : UnEdited); edgedetect->setEditedState(pedited->wavelet.edgedetect ? Edited : UnEdited); @@ -1824,6 +1829,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pp->wavelet.iter = (int) iter->getValue(); pp->wavelet.wavclCurve = clshape->getCurve(); pp->wavelet.sigmafin = sigmafin->getValue(); + pp->wavelet.sigmaton = sigmaton->getValue(); for (int i = 0; i < 9; i++) { pp->wavelet.c[i] = (int) correction[i]->getValue(); @@ -1931,6 +1937,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.balance = balance->getEditedState(); pedited->wavelet.iter = iter->getEditedState(); pedited->wavelet.sigmafin = sigmafin->getEditedState(); + pedited->wavelet.sigmaton = sigmaton->getEditedState(); pedited->wavelet.wavclCurve = !clshape->isUnChanged(); pedited->wavelet.expcontrast = !expcontrast->get_inconsistent(); pedited->wavelet.expchroma = !expchroma->get_inconsistent(); @@ -2112,6 +2119,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit balance->setDefault(defParams->wavelet.balance); iter->setDefault(defParams->wavelet.iter); sigmafin->setDefault(defParams->wavelet.sigmafin); + sigmaton->setDefault(defParams->wavelet.sigmaton); sigma->setDefault(defParams->wavelet.sigma); offset->setDefault(defParams->wavelet.offset); lowthr->setDefault(defParams->wavelet.lowthr); @@ -2235,6 +2243,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit balance->setDefaultEditedState(pedited->wavelet.balance ? Edited : UnEdited); iter->setDefaultEditedState(pedited->wavelet.iter ? Edited : UnEdited); sigmafin->setDefaultEditedState(pedited->wavelet.sigmafin ? Edited : UnEdited); + sigmaton->setDefaultEditedState(pedited->wavelet.sigmaton ? Edited : UnEdited); level0noise->setDefaultEditedState(pedited->wavelet.level0noise ? Edited : UnEdited); level1noise->setDefaultEditedState(pedited->wavelet.level1noise ? Edited : UnEdited); level2noise->setDefaultEditedState(pedited->wavelet.level2noise ? Edited : UnEdited); @@ -2298,6 +2307,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit balance->setDefaultEditedState(Irrelevant); iter->setDefaultEditedState(Irrelevant); sigmafin->setDefaultEditedState(Irrelevant); + sigmaton->setDefaultEditedState(Irrelevant); for (int i = 0; i < 9; i++) { correction[i]->setDefaultEditedState(Irrelevant); @@ -2831,6 +2841,7 @@ void Wavelet::setBatchMode(bool batchMode) balance->showEditedCB(); iter->showEditedCB(); sigmafin->showEditedCB(); + sigmaton->showEditedCB(); level0noise->showEditedCB(); level1noise->showEditedCB(); level2noise->showEditedCB(); @@ -2982,6 +2993,8 @@ void Wavelet::adjusterChanged(Adjuster* a, double newval) listener->panelChanged(EvWaviter, iter->getTextValue()); } else if (a == sigmafin) { listener->panelChanged(EvWavsigmafin, sigmafin->getTextValue()); + } else if (a == sigmaton) { + listener->panelChanged(EvWavsigmaton, sigmaton->getTextValue()); } else if (a == greenhigh) { listener->panelChanged(EvWavgreenhigh, greenhigh->getTextValue()); } else if (a == bluehigh) { diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index 271aea5b2..e8154b680 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -94,6 +94,7 @@ private: rtengine::ProcEvent EvWavresblurc; rtengine::ProcEvent EvWavedgeffect; rtengine::ProcEvent EvWavsigmafin; + rtengine::ProcEvent EvWavsigmaton; void foldAllButMe(GdkEventButton* event, MyExpander *expander); @@ -220,6 +221,7 @@ private: Adjuster* const balance; Adjuster* const iter; Adjuster* const sigmafin; + Adjuster* const sigmaton; Adjuster* greenlow; Adjuster* bluelow; From 2c3c658171d2fa831b3355fa5db532fb70d18a7d Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 14 Apr 2020 08:36:51 +0200 Subject: [PATCH 07/28] Wavelet - added meanab sigmaab damper to chroma -Fixed bug in toning --- rtdata/languages/default | 1 + rtengine/ipwavelet.cc | 50 ++++++++++++++++++++++++++++++++++++---- rtengine/procparams.cc | 4 ++++ rtengine/procparams.h | 1 + rtgui/paramsedited.cc | 6 +++++ rtgui/paramsedited.h | 1 + rtgui/wavelet.cc | 19 ++++++++++++++- rtgui/wavelet.h | 2 ++ 8 files changed, 78 insertions(+), 6 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 5832406de..8d4472f04 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -819,6 +819,7 @@ HISTORY_MSG_BLURCWAV;Blur chroma HISTORY_MSG_EDGEFFECT;Edge Damper HISTORY_MSG_SIGMAFIN;Final contrast Damper HISTORY_MSG_SIGMATON;Toning Damper +HISTORY_MSG_SIGMACOL;Chroma Damper HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOT;Snapshot diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 9d50dedff..6fe88c209 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -115,6 +115,7 @@ struct cont_params { float balan; float sigmafin; float sigmaton; + float sigmacol; int ite; int contmet; bool opaW; @@ -195,6 +196,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.bam = false; cp.sigmafin = params->wavelet.sigmafin; cp.sigmaton = params->wavelet.sigmaton; + cp.sigmacol = params->wavelet.sigmacol; if (params->wavelet.TMmethod == "cont") { cp.contmet = 1; @@ -3866,6 +3868,11 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f //to adjust increase contrast with local contrast bool useSkinControl = (skinprot != 0.f); + + + + + float alphaC = (1024.f + 15.f * cpMul * cpChrom / 50.f) / 1024.f ; for (int i = 0; i < W_ab * H_ab; i++) { @@ -3903,7 +3910,41 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f const float factorHard = (1.f - skinprotneg / 100.f); bool useSkinControl = (skinprot != 0.f); + + float mea[10]; + float effect = cp.sigmacol; + float betaab = 0.f; + float offs = 1.f; + + calceffect(level, meanab, sigmaab, mea, effect, offs); + for (int i = 0; i < W_ab * H_ab; i++) { + float WavCab = std::fabs(WavCoeffs_ab[dir][i]); + + if (WavCab < mea[0]) { + betaab = 0.05f; + } else if (WavCab < mea[1]) { + betaab = 0.2f; + } else if (WavCab < mea[2]) { + betaab = 0.7f; + } else if (WavCab < mea[3]) { + betaab = 1.f; //standard + } else if (WavCab < mea[4]) { + betaab = 1.f; + } else if (WavCab < mea[5]) { + betaab = 0.8f; //+sigma + } else if (WavCab < mea[6]) { + betaab = 0.6f; + } else if (WavCab < mea[7]) { + betaab = 0.4f; + } else if (WavCab < mea[8]) { + betaab = 0.2f; // + 2 sigma + } else if (WavCab < mea[9]) { + betaab = 0.1f; + } else { + betaab = 0.0f; + } + int ii = i / W_ab; int jj = i - ii * W_ab; //WL and W_ab are identical @@ -3923,7 +3964,7 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f } } - float beta = (1024.f + 20.f * cpMulC * scale) / 1024.f ; + float beta = (1024.f + 20.f * cpMulC * scale * betaab) / 1024.f ; if (beta < 0.02f) { beta = 0.02f; @@ -4022,12 +4063,11 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f } else { betaab = 0.0f; } - } - float beta = (1024.f + 50.f * mulOpacity * betaab) / 1024.f ; - for (int i = 0; i < W_ab * H_ab; i++) { - WavCoeffs_ab[dir][i] *= beta; + float beta = (1024.f + 50.f * mulOpacity * betaab) / 1024.f ; + + WavCoeffs_ab[dir][co] *= beta; } } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 8306f9a55..7b6a8f123 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2265,6 +2265,7 @@ WaveletParams::WaveletParams() : balance(0), sigmafin(1.0), sigmaton(1.0), + sigmacol(1.0), iter(0), expcontrast(false), expchroma(false), @@ -2381,6 +2382,7 @@ bool WaveletParams::operator ==(const WaveletParams& other) const && balance == other.balance && sigmafin == other.sigmafin && sigmaton == other.sigmaton + && sigmacol == other.sigmacol && iter == other.iter && expcontrast == other.expcontrast && expchroma == other.expchroma @@ -3526,6 +3528,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.balance, "Wavelet", "Balance", wavelet.balance, keyFile); saveToKeyfile(!pedited || pedited->wavelet.sigmafin, "Wavelet", "Sigmafin", wavelet.sigmafin, keyFile); saveToKeyfile(!pedited || pedited->wavelet.sigmaton, "Wavelet", "Sigmaton", wavelet.sigmaton, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.sigmacol, "Wavelet", "Sigmacol", wavelet.sigmacol, keyFile); saveToKeyfile(!pedited || pedited->wavelet.iter, "Wavelet", "Iter", wavelet.iter, keyFile); saveToKeyfile(!pedited || pedited->wavelet.thres, "Wavelet", "MaxLev", wavelet.thres, keyFile); saveToKeyfile(!pedited || pedited->wavelet.Tilesmethod, "Wavelet", "TilesMethod", wavelet.Tilesmethod, keyFile); @@ -4708,6 +4711,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Wavelet", "Balance", pedited, wavelet.balance, pedited->wavelet.balance); assignFromKeyfile(keyFile, "Wavelet", "Sigmafin", pedited, wavelet.sigmafin, pedited->wavelet.sigmafin); assignFromKeyfile(keyFile, "Wavelet", "Sigmaton", pedited, wavelet.sigmaton, pedited->wavelet.sigmaton); + assignFromKeyfile(keyFile, "Wavelet", "Sigmacol", pedited, wavelet.sigmacol, pedited->wavelet.sigmacol); assignFromKeyfile(keyFile, "Wavelet", "Iter", pedited, wavelet.iter, pedited->wavelet.iter); assignFromKeyfile(keyFile, "Wavelet", "Median", pedited, wavelet.median, pedited->wavelet.median); assignFromKeyfile(keyFile, "Wavelet", "Medianlev", pedited, wavelet.medianlev, pedited->wavelet.medianlev); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 38883110b..536f260bc 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1223,6 +1223,7 @@ struct WaveletParams { int balance; double sigmafin; double sigmaton; + double sigmacol; int iter; bool expcontrast; bool expchroma; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index f6cfb78f9..8a97681e4 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -477,6 +477,7 @@ void ParamsEdited::set(bool v) wavelet.iter = v; wavelet.sigmafin = v; wavelet.sigmaton = v; + wavelet.sigmacol = v; wavelet.median = v; wavelet.medianlev = v; wavelet.linkedg = v; @@ -1090,6 +1091,7 @@ void ParamsEdited::initFrom(const std::vector& wavelet.iter = wavelet.iter && p.wavelet.iter == other.wavelet.iter; wavelet.sigmafin = wavelet.sigmafin && p.wavelet.sigmafin == other.wavelet.sigmafin; wavelet.sigmaton = wavelet.sigmaton && p.wavelet.sigmaton == other.wavelet.sigmaton; + wavelet.sigmacol = wavelet.sigmacol && p.wavelet.sigmacol == other.wavelet.sigmacol; wavelet.median = wavelet.median && p.wavelet.median == other.wavelet.median; wavelet.medianlev = wavelet.medianlev && p.wavelet.medianlev == other.wavelet.medianlev; wavelet.linkedg = wavelet.linkedg && p.wavelet.linkedg == other.wavelet.linkedg; @@ -2909,6 +2911,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.sigmaton = mods.wavelet.sigmaton; } + if (wavelet.sigmacol) { + toEdit.wavelet.sigmacol = mods.wavelet.sigmacol; + } + if (wavelet.iter) { toEdit.wavelet.iter = mods.wavelet.iter; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index f602c04f1..c17ea52c7 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -501,6 +501,7 @@ struct WaveletParamsEdited { bool iter; bool sigmafin; bool sigmaton; + bool sigmacol; bool median; bool medianlev; bool linkedg; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index db3687b3e..475c6d866 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -114,6 +114,7 @@ Wavelet::Wavelet() : iter(Gtk::manage(new Adjuster(M("TP_WAVELET_ITER"), -3, 3, 1, 0))), sigmafin(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMAFIN"), 0.025, 2.5, 0.01, 1.))), sigmaton(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMAFIN"), 0.025, 2.5, 0.01, 1.))), + sigmacol(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMAFIN"), 0.025, 2.5, 0.01, 1.))), hueskin(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_HUESKIN"), -314., 314., -5., 25., 170., 120., 0, false))), hueskin2(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_HUESKY"), -314., 314., -260., -250, -130., -140., 0, false))), hllev(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_HIGHLIGHT"), 0., 100., 50., 75., 100., 98., 0, false))), @@ -212,6 +213,7 @@ Wavelet::Wavelet() : EvWavedgeffect = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_EDGEFFECT"); EvWavsigmafin = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_SIGMAFIN"); EvWavsigmaton = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_SIGMATON"); + EvWavsigmacol = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_SIGMACOL"); expsettings->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expsettings)); @@ -456,8 +458,10 @@ Wavelet::Wavelet() : chBox->pack_start(*satlev); chro->set_tooltip_text(M("TP_WAVELET_CHR_TOOLTIP")); - chBox->pack_start(*chro); chro->setAdjusterListener(this); + sigmacol->setAdjusterListener(this); + chBox->pack_start(*chro); + chBox->pack_start(*sigmacol); Gtk::HBox* const buttonchBox = Gtk::manage(new Gtk::HBox(true, 10)); neutralchPressedConn = neutralchButton->signal_pressed().connect(sigc::mem_fun(*this, &Wavelet::neutralchPressed)); @@ -1438,6 +1442,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) iter->setValue(pp->wavelet.iter); sigmafin->setValue(pp->wavelet.sigmafin); sigmaton->setValue(pp->wavelet.sigmaton); + sigmacol->setValue(pp->wavelet.sigmacol); for (int i = 0; i < 9; i++) { correction[i]->setValue(pp->wavelet.c[i]); @@ -1557,6 +1562,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) iter->setEditedState(pedited->wavelet.iter ? Edited : UnEdited); sigmafin->setEditedState(pedited->wavelet.sigmafin ? Edited : UnEdited); sigmaton->setEditedState(pedited->wavelet.sigmaton ? Edited : UnEdited); + sigmacol->setEditedState(pedited->wavelet.sigmacol ? Edited : UnEdited); threshold->setEditedState(pedited->wavelet.threshold ? Edited : UnEdited); threshold2->setEditedState(pedited->wavelet.threshold2 ? Edited : UnEdited); edgedetect->setEditedState(pedited->wavelet.edgedetect ? Edited : UnEdited); @@ -1830,6 +1836,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pp->wavelet.wavclCurve = clshape->getCurve(); pp->wavelet.sigmafin = sigmafin->getValue(); pp->wavelet.sigmaton = sigmaton->getValue(); + pp->wavelet.sigmacol = sigmacol->getValue(); for (int i = 0; i < 9; i++) { pp->wavelet.c[i] = (int) correction[i]->getValue(); @@ -1938,6 +1945,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.iter = iter->getEditedState(); pedited->wavelet.sigmafin = sigmafin->getEditedState(); pedited->wavelet.sigmaton = sigmaton->getEditedState(); + pedited->wavelet.sigmacol = sigmacol->getEditedState(); pedited->wavelet.wavclCurve = !clshape->isUnChanged(); pedited->wavelet.expcontrast = !expcontrast->get_inconsistent(); pedited->wavelet.expchroma = !expchroma->get_inconsistent(); @@ -2120,6 +2128,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit iter->setDefault(defParams->wavelet.iter); sigmafin->setDefault(defParams->wavelet.sigmafin); sigmaton->setDefault(defParams->wavelet.sigmaton); + sigmacol->setDefault(defParams->wavelet.sigmacol); sigma->setDefault(defParams->wavelet.sigma); offset->setDefault(defParams->wavelet.offset); lowthr->setDefault(defParams->wavelet.lowthr); @@ -2244,6 +2253,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit iter->setDefaultEditedState(pedited->wavelet.iter ? Edited : UnEdited); sigmafin->setDefaultEditedState(pedited->wavelet.sigmafin ? Edited : UnEdited); sigmaton->setDefaultEditedState(pedited->wavelet.sigmaton ? Edited : UnEdited); + sigmacol->setDefaultEditedState(pedited->wavelet.sigmacol ? Edited : UnEdited); level0noise->setDefaultEditedState(pedited->wavelet.level0noise ? Edited : UnEdited); level1noise->setDefaultEditedState(pedited->wavelet.level1noise ? Edited : UnEdited); level2noise->setDefaultEditedState(pedited->wavelet.level2noise ? Edited : UnEdited); @@ -2308,6 +2318,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit iter->setDefaultEditedState(Irrelevant); sigmafin->setDefaultEditedState(Irrelevant); sigmaton->setDefaultEditedState(Irrelevant); + sigmacol->setDefaultEditedState(Irrelevant); for (int i = 0; i < 9; i++) { correction[i]->setDefaultEditedState(Irrelevant); @@ -2403,6 +2414,7 @@ void Wavelet::CHmethodUpdateUI() if (!batchMode) { if (CHmethod->get_active_row_number() == 0) { CHSLmethod->show(); + sigmacol->show(); pastlev->hide(); satlev->hide(); chroma->hide(); @@ -2422,6 +2434,7 @@ void Wavelet::CHmethodUpdateUI() } } else if (CHmethod->get_active_row_number() == 1) { CHSLmethod->show(); + sigmacol->show(); pastlev->show(); satlev->show(); chroma->show(); @@ -2441,6 +2454,7 @@ void Wavelet::CHmethodUpdateUI() } } else { chro->show(); + sigmacol->hide(); pastlev->hide(); satlev->hide(); chroma->hide(); @@ -2842,6 +2856,7 @@ void Wavelet::setBatchMode(bool batchMode) iter->showEditedCB(); sigmafin->showEditedCB(); sigmaton->showEditedCB(); + sigmacol->showEditedCB(); level0noise->showEditedCB(); level1noise->showEditedCB(); level2noise->showEditedCB(); @@ -2995,6 +3010,8 @@ void Wavelet::adjusterChanged(Adjuster* a, double newval) listener->panelChanged(EvWavsigmafin, sigmafin->getTextValue()); } else if (a == sigmaton) { listener->panelChanged(EvWavsigmaton, sigmaton->getTextValue()); + } else if (a == sigmacol) { + listener->panelChanged(EvWavsigmacol, sigmacol->getTextValue()); } else if (a == greenhigh) { listener->panelChanged(EvWavgreenhigh, greenhigh->getTextValue()); } else if (a == bluehigh) { diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index e8154b680..4a4947b2a 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -95,6 +95,7 @@ private: rtengine::ProcEvent EvWavedgeffect; rtengine::ProcEvent EvWavsigmafin; rtengine::ProcEvent EvWavsigmaton; + rtengine::ProcEvent EvWavsigmacol; void foldAllButMe(GdkEventButton* event, MyExpander *expander); @@ -222,6 +223,7 @@ private: Adjuster* const iter; Adjuster* const sigmafin; Adjuster* const sigmaton; + Adjuster* const sigmacol; Adjuster* greenlow; Adjuster* bluelow; From e3c802f6106a3679826f9c98c46238b42df218d5 Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 14 Apr 2020 09:11:32 +0200 Subject: [PATCH 08/28] Wavelet levels - Fixed bad behavior edge sharpness with damper --- rtengine/ipwavelet.cc | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 6fe88c209..38c873824 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -3141,7 +3141,12 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz constexpr float bedstr = 1.f - 10.f * aedstr; float mea[10]; - float beta = 1.f; + // float beta = 1.f; + float * beta = new float[W_L * H_L]; + + for (int co = 0; co < H_L * W_L; co++) { + beta[co] = 1.f; + } if (cp.eff < 2.5f) { float effect = cp.eff; @@ -3153,27 +3158,27 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz float WavCL = std::fabs(WavCoeffs_L[dir][co]); if (WavCL < mea[0]) { - beta = 0.05f; + beta[co] = 0.05f; } else if (WavCL < mea[1]) { - beta = 0.2f; + beta[co] = 0.2f; } else if (WavCL < mea[2]) { - beta = 0.7f; + beta[co] = 0.7f; } else if (WavCL < mea[3]) { - beta = 1.f; //standard + beta[co] = 1.f; //standard } else if (WavCL < mea[4]) { - beta = 1.f; + beta[co] = 1.f; } else if (WavCL < mea[5]) { - beta = 0.8f; //+sigma + beta[co] = 0.8f; //+sigma } else if (WavCL < mea[6]) { - beta = 0.6f; + beta[co] = 0.6f; } else if (WavCL < mea[7]) { - beta = 0.4f; + beta[co] = 0.4f; } else if (WavCL < mea[8]) { - beta = 0.2f; // + 2 sigma + beta[co] = 0.2f; // + 2 sigma } else if (WavCL < mea[9]) { - beta = 0.1f; + beta[co] = 0.1f; } else { - beta = 0.0f; + beta[co] = 0.0f; } } @@ -3272,7 +3277,7 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz value *= (atten01234 * scaleskip[1]); //for zoom < 100% reduce strength...I choose level 1...but!! } - value *= beta; + // value *= beta; float edge = 1.f; float lim0 = 20.f; //arbitrary limit for low radius and level between 2 or 3 to 30 maxi float lev = float (level); @@ -3432,7 +3437,7 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz edge = rtengine::max(edge, 1.f); } - WavCoeffs_L[dir][k] *= edge; + WavCoeffs_L[dir][k] *= (1.f + (edge - 1.f) * beta[k]); } } } else if (cp.EDmet == 1) { //threshold adjuster @@ -3549,7 +3554,7 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz } } - WavCoeffs_L[dir][k] *= edge; + WavCoeffs_L[dir][k] *= (1.f + (edge - 1.f) * beta[k]); } } } @@ -3557,6 +3562,8 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz if (!lipschitz) { delete [] koe; } + + delete[] beta; } From cb700cc67642c2c1462bd2257f3125cf38f8a57b Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 14 Apr 2020 09:38:05 +0200 Subject: [PATCH 09/28] Fixed bad behavior blur levels damper --- rtengine/ipwavelet.cc | 63 +++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 38c873824..92fe16f98 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -2414,8 +2414,11 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * // printf("Blur level L\n"); float mea[10]; float effect = cp.bluwav; - float beta = 0.f; float offs = 1.f; + float * beta = new float[Wlvl_L * Hlvl_L]; + for (int co = 0; co < Hlvl_L * Wlvl_L; co++) { + beta[co] = 1.f; + } calceffect(lvl, mean, sigma, mea, effect, offs); @@ -2427,41 +2430,41 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * float WavCL = std::fabs(WavCoeffs_L[dir][co]); if (WavCL < mea[0]) { - beta = 0.05f; + beta[co] = 0.05f; n0++; if (WavCL < 32.7) { n32++; } } else if (WavCL < mea[1]) { - beta = 0.2f; + beta[co] = 0.2f; n1++; } else if (WavCL < mea[2]) { - beta = 0.7f; + beta[co] = 0.7f; n2++; } else if (WavCL < mea[3]) { - beta = 1.f; //standard + beta[co] = 1.f; //standard n3++; } else if (WavCL < mea[4]) { - beta = 1.f; + beta[co] = 1.f; n4++; } else if (WavCL < mea[5]) { - beta = 0.8f; //+sigma + beta[co] = 0.8f; //+sigma n5++; } else if (WavCL < mea[6]) { - beta = 0.6f; + beta[co] = 0.6f; n6++; } else if (WavCL < mea[7]) { - beta = 0.4f; + beta[co] = 0.4f; n7++; } else if (WavCL < mea[8]) { - beta = 0.2f; // + 2 sigma + beta[co] = 0.2f; // + 2 sigma n8++; } else if (WavCL < mea[9]) { - beta = 0.1f; + beta[co] = 0.1f; n9++; } else { - beta = 0.01f; + beta[co] = 0.01f; n10++; } @@ -2474,15 +2477,18 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * klev = (wavblcurve[lvl * 55.5f]); - klev *= beta * 100.f / skip; + // klev *= beta * 100.f / skip; + klev *= 100.f / skip; boxblur(bef, aft, klev, Wlvl_L, Hlvl_L, false); for (int co = 0; co < Hlvl_L * Wlvl_L; co++) { + aft[co] = bef[co] * (1.f - beta[co]) + aft[co] * beta[co]; WavCoeffs_L[dir][co] = aft[co]; } delete[] bef; delete[] aft; + delete[] beta; } } } @@ -2738,8 +2744,11 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float float mea[10]; float effect = cp.bluwav; - float beta = 0.f; float offs = 1.f; + float * beta = new float[Wlvl_ab * Hlvl_ab]; + for (int co = 0; co < Wlvl_ab * Hlvl_ab; co++) { + beta[co] = 1.f; + } calceffect(lvl, meanab, sigmaab, mea, effect, offs); @@ -2752,27 +2761,27 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float float WavCab = std::fabs(WavCoeffs_ab[dir][co]); if (WavCab < mea[0]) { - beta = 0.05f; + beta[co] = 0.05f; } else if (WavCab < mea[1]) { - beta = 0.2f; + beta[co] = 0.2f; } else if (WavCab < mea[2]) { - beta = 0.7f; + beta[co] = 0.7f; } else if (WavCab < mea[3]) { - beta = 1.f; //standard + beta[co] = 1.f; //standard } else if (WavCab < mea[4]) { - beta = 1.f; + beta[co] = 1.f; } else if (WavCab < mea[5]) { - beta = 0.8f; //+sigma + beta[co] = 0.8f; //+sigma } else if (WavCab < mea[6]) { - beta = 0.6f; + beta[co] = 0.6f; } else if (WavCab < mea[7]) { - beta = 0.4f; + beta[co] = 0.4f; } else if (WavCab < mea[8]) { - beta = 0.2f; // + 2 sigma + beta[co] = 0.2f; // + 2 sigma } else if (WavCab < mea[9]) { - beta = 0.1f; + beta[co] = 0.1f; } else { - beta = 0.0f; + beta[co] = 0.0f; } @@ -2780,16 +2789,18 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float klev = (wavblcurve[lvl * 55.5f]); - klev *= beta * cp.chrwav * 100.f / skip; + klev *= cp.chrwav * 100.f / skip; boxblur(bef, aft, klev, Wlvl_ab, Hlvl_ab, false); for (int co = 0; co < Hlvl_ab * Wlvl_ab; co++) { + aft[co] = bef[co] * (1.f - beta[co]) + aft[co] * beta[co]; WavCoeffs_ab[dir][co] = aft[co]; } delete[] bef; delete[] aft; + delete[] beta; } From 62fd0a0401e779c896e4e1b1453dfdfe49b3dda2 Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 14 Apr 2020 10:18:10 +0200 Subject: [PATCH 10/28] Wavelet - Add colored left bar to toning curve --- rtgui/wavelet.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 475c6d866..1d4ad8315 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -502,6 +502,12 @@ Wavelet::Wavelet() : opacityShapeRG = static_cast(opaCurveEditorG->addCurve(CT_Flat, "", nullptr, false, false)); opacityShapeRG->setIdentityValue(0.); opacityShapeRG->setResetCurve(FlatCurveType(default_params.opacityCurveRG.at(0)), default_params.opacityCurveRG); + //from green to magenta + std::vector mileston = { + GradientMilestone(0., 0., 1., 0.), + GradientMilestone(1., 1., 0., 1.) + }; + opacityShapeRG->setLeftBarBgGradient(mileston); opaCurveEditorG->curveListComplete(); opaCurveEditorG->show(); @@ -513,6 +519,12 @@ Wavelet::Wavelet() : opacityShapeBY = static_cast(opacityCurveEditorG->addCurve(CT_Flat, "", nullptr, false, false)); opacityShapeBY->setIdentityValue(0.); opacityShapeBY->setResetCurve(FlatCurveType(default_params.opacityCurveBY.at(0)), default_params.opacityCurveBY); + //from blue to yellow + mileston = { + GradientMilestone(0., 0., 0., 1.), + GradientMilestone(1., 1., 1., 0.) + }; + opacityShapeBY->setLeftBarBgGradient(mileston); opacityCurveEditorG->curveListComplete(); opacityCurveEditorG->show(); From ad207e003caeba2dc5dae90e9968ede5cc7d3528 Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 14 Apr 2020 13:08:02 +0200 Subject: [PATCH 11/28] Wavelet Improve Chroma with link contrast levels --- rtengine/ipwavelet.cc | 46 ++++++++++++++++++++++++++++++++++++------- rtgui/wavelet.cc | 6 +++--- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 92fe16f98..f6055a3e1 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -2416,6 +2416,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * float effect = cp.bluwav; float offs = 1.f; float * beta = new float[Wlvl_L * Hlvl_L]; + for (int co = 0; co < Hlvl_L * Wlvl_L; co++) { beta[co] = 1.f; } @@ -2477,7 +2478,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * klev = (wavblcurve[lvl * 55.5f]); - // klev *= beta * 100.f / skip; + // klev *= beta * 100.f / skip; klev *= 100.f / skip; boxblur(bef, aft, klev, Wlvl_L, Hlvl_L, false); @@ -2746,6 +2747,7 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float float effect = cp.bluwav; float offs = 1.f; float * beta = new float[Wlvl_ab * Hlvl_ab]; + for (int co = 0; co < Wlvl_ab * Hlvl_ab; co++) { beta[co] = 1.f; } @@ -3887,13 +3889,43 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f //to adjust increase contrast with local contrast bool useSkinControl = (skinprot != 0.f); + float mea[10]; + float effect = cp.sigmacol; + float betaab = 1.f; + float offs = 1.f; + float alphaC = 1.f; - - - - float alphaC = (1024.f + 15.f * cpMul * cpChrom / 50.f) / 1024.f ; + calceffect(level, meanab, sigmaab, mea, effect, offs); for (int i = 0; i < W_ab * H_ab; i++) { + float WavCab = std::fabs(WavCoeffs_ab[dir][i]); + + if (WavCab < mea[0]) { + betaab = 0.05f; + } else if (WavCab < mea[1]) { + betaab = 0.2f; + } else if (WavCab < mea[2]) { + betaab = 0.7f; + } else if (WavCab < mea[3]) { + betaab = 1.f; //standard + } else if (WavCab < mea[4]) { + betaab = 1.f; + } else if (WavCab < mea[5]) { + betaab = 0.8f; //+sigma + } else if (WavCab < mea[6]) { + betaab = 0.6f; + } else if (WavCab < mea[7]) { + betaab = 0.4f; + } else if (WavCab < mea[8]) { + betaab = 0.2f; // + 2 sigma + } else if (WavCab < mea[9]) { + betaab = 0.1f; + } else { + betaab = 0.0f; + } + + float scale = 1.f; + if (useSkinControl) { int ii = i / W_ab; int jj = i - ii * W_ab; @@ -3901,7 +3933,6 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f float modhue = varhue[ii][jj]; float modchro = varchrom[ii * 2][jj * 2]; // hue chroma skin with initial lab data - float scale = 1.f; if (skinprot > 0.f) { Color::SkinSatCbdl2(LL100, modhue, modchro, skinprot, scale, true, cp.b_l, cp.t_l, cp.t_r, cp.b_r, 0); //0 for skin and extand @@ -3910,9 +3941,10 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f scale = (scale == 1.f) ? factorHard : 1.f; } - alphaC = (1024.f + 15.f * cpMul * cpChrom * scale / 50.f) / 1024.f ; } + alphaC = (1024.f + 15.f * cpMul * cpChrom * betaab * scale / 50.f) / 1024.f ; + WavCoeffs_ab[dir][i] *= alphaC; } } diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 1d4ad8315..d84277693 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -2426,7 +2426,7 @@ void Wavelet::CHmethodUpdateUI() if (!batchMode) { if (CHmethod->get_active_row_number() == 0) { CHSLmethod->show(); - sigmacol->show(); + // sigmacol->show(); pastlev->hide(); satlev->hide(); chroma->hide(); @@ -2446,7 +2446,7 @@ void Wavelet::CHmethodUpdateUI() } } else if (CHmethod->get_active_row_number() == 1) { CHSLmethod->show(); - sigmacol->show(); + // sigmacol->show(); pastlev->show(); satlev->show(); chroma->show(); @@ -2466,7 +2466,7 @@ void Wavelet::CHmethodUpdateUI() } } else { chro->show(); - sigmacol->hide(); + // sigmacol->hide(); pastlev->hide(); satlev->hide(); chroma->hide(); From feb2c7c77f78d59c9cf12c11c95d81097190b16f Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 14 Apr 2020 16:20:15 +0200 Subject: [PATCH 12/28] Improve GUI final Touchup --- rtdata/languages/default | 1 + rtgui/wavelet.cc | 24 +++++++++++++----------- rtgui/wavelet.h | 1 + 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 8d4472f04..10fb47e89 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2209,6 +2209,7 @@ TP_WAVELET_DAUB6;D6 - standard plus TP_WAVELET_DAUB10;D10 - medium TP_WAVELET_DAUB14;D14 - high TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +TP_WAVELET_DIRFRAME;Directional contrast TP_WAVELET_DONE;Vertical TP_WAVELET_DTHR;Diagonal TP_WAVELET_DTWO;Horizontal diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index d84277693..1649b0afe 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -166,6 +166,7 @@ Wavelet::Wavelet() : chromaFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_CHROMAFRAME")))), chroFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_CHROFRAME")))), fincFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_FINCFRAME")))), + dirFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_DIRFRAME")))), wavLabels(Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER))), labmC(Gtk::manage(new Gtk::Label(M("TP_WAVELET_CTYPE") + ":"))), labmNP(Gtk::manage(new Gtk::Label(M("TP_WAVELET_NPTYPE") + ":"))), @@ -1034,20 +1035,18 @@ Wavelet::Wavelet() : fincBox->pack_start(*sigmafin); fincFrame->add(*fincBox); + dirFrame->set_label_align(0.025, 0.5); + ToolParamBlock* const dirBox = Gtk::manage(new ToolParamBlock()); + dirBox->pack_start(*ctboxBA); + dirBox->pack_start(*balance); + dirBox->pack_start(*opacityCurveEditorW, Gtk::PACK_SHRINK, 2); + dirBox->pack_start(*iter); + dirBox->pack_start(*tmr); + dirFrame->add(*dirBox); ToolParamBlock* const finalBox = Gtk::manage(new ToolParamBlock()); + finalBox->pack_start(*dirFrame); - finalBox->pack_start(*ctboxBA); - finalBox->pack_start(*balance); - - finalBox->pack_start(*opacityCurveEditorW, Gtk::PACK_SHRINK, 2); - - finalBox->pack_start(*iter); - - finalBox->pack_start(*tmr); -// finalBox->pack_start(*separatorbalend, Gtk::PACK_SHRINK, 2); -// finalBox->pack_start(*opacityCurveEditorWL, Gtk::PACK_SHRINK, 2); -// finalBox->pack_start(*sigmafin); finalBox->pack_start(*fincFrame); finalBox->pack_start(*curveEditorG, Gtk::PACK_SHRINK, 4); finalBox->pack_start(*softradend); @@ -2568,15 +2567,18 @@ void Wavelet::BAmethodUpdateUI() balance->hide(); opacityCurveEditorW->hide(); iter->hide(); + tmr->hide(); } else if (BAmethod->get_active_row_number() == 1) { //sli opacityCurveEditorW->hide(); balance->show(); iter->show(); + tmr->show(); } else if (BAmethod->get_active_row_number() == 2) { //CU opacityCurveEditorW->show(); balance->hide(); iter->show(); + tmr->show(); } } } diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index 4a4947b2a..644d8f6b9 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -301,6 +301,7 @@ private: Gtk::Frame* const chromaFrame; Gtk::Frame* const chroFrame; Gtk::Frame* const fincFrame; + Gtk::Frame* const dirFrame; Gtk::Label* const wavLabels; Gtk::Label* const labmC; From b0f73d7cd3329d2fbcc5a5d6699bf4e6d4ca1eb9 Mon Sep 17 00:00:00 2001 From: Desmis Date: Wed, 15 Apr 2020 08:48:18 +0200 Subject: [PATCH 13/28] Wavelet - added damper to directionnal contrast --- rtdata/languages/default | 1 + rtengine/ipwavelet.cc | 53 +++++++++++++++++++++++++++++++++++++--- rtengine/procparams.cc | 4 +++ rtengine/procparams.h | 1 + rtgui/paramsedited.cc | 6 +++++ rtgui/paramsedited.h | 1 + rtgui/wavelet.cc | 14 +++++++++++ rtgui/wavelet.h | 2 ++ 8 files changed, 79 insertions(+), 3 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 10fb47e89..21b3da555 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -820,6 +820,7 @@ HISTORY_MSG_EDGEFFECT;Edge Damper HISTORY_MSG_SIGMAFIN;Final contrast Damper HISTORY_MSG_SIGMATON;Toning Damper HISTORY_MSG_SIGMACOL;Chroma Damper +HISTORY_MSG_SIGMADIR;Dir Damper HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOT;Snapshot diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index f6055a3e1..f53ad083f 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -116,6 +116,7 @@ struct cont_params { float sigmafin; float sigmaton; float sigmacol; + float sigmadir; int ite; int contmet; bool opaW; @@ -197,6 +198,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.sigmafin = params->wavelet.sigmafin; cp.sigmaton = params->wavelet.sigmaton; cp.sigmacol = params->wavelet.sigmacol; + cp.sigmadir = params->wavelet.sigmadir; if (params->wavelet.TMmethod == "cont") { cp.contmet = 1; @@ -3768,7 +3770,52 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz } if (cp.bam && cp.finena) { + float effect = cp.sigmadir; + float offs = 1.f; + float mea[10]; + float * beta = new float[W_L * H_L]; + + for (int co = 0; co < H_L * W_L; co++) { + beta[co] = 1.f; + } + + calceffect(level, mean, sigma, mea, effect, offs); + + + for (int co = 0; co < H_L * W_L; co++) { + float WavCL = std::fabs(WavCoeffs_L[dir][co]); + + if (WavCL < mea[0]) { + beta[co] = 0.05f; + } else if (WavCL < mea[1]) { + beta[co] = 0.2f; + } else if (WavCL < mea[2]) { + beta[co] = 0.7f; + } else if (WavCL < mea[3]) { + beta[co] = 1.f; //standard + } else if (WavCL < mea[4]) { + beta[co] = 1.f; + } else if (WavCL < mea[5]) { + beta[co] = 0.8f; //+sigma + } else if (WavCL < mea[6]) { + beta[co] = 0.6f; + } else if (WavCL < mea[7]) { + beta[co] = 0.4f; + } else if (WavCL < mea[8]) { + beta[co] = 0.2f; // + 2 sigma + } else if (WavCL < mea[9]) { + beta[co] = 0.1f; + } else { + beta[co] = 0.01f; + } + } + + if (cp.opaW && cp.BAmet == 2) { + + + + int iteration = cp.ite; int itplus = 7 + iteration; int itmoins = 7 - iteration; @@ -3804,7 +3851,7 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz kba = 1.f - k2; } - WavCoeffs_L[dir][i] *= (kba); + WavCoeffs_L[dir][i] *= (1.f + (kba -1.f) * beta[i]); } } } @@ -3863,11 +3910,11 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz kba = 1.f - bal / k2; } - WavCoeffs_L[dir][i] *= (kba); + WavCoeffs_L[dir][i] *= (1.f + (kba -1.f) * beta[i]); } } } - + delete[] beta; } // to see each level of wavelet ...level from 0 to 8 diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 7b6a8f123..110d9368f 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2266,6 +2266,7 @@ WaveletParams::WaveletParams() : sigmafin(1.0), sigmaton(1.0), sigmacol(1.0), + sigmadir(1.0), iter(0), expcontrast(false), expchroma(false), @@ -2383,6 +2384,7 @@ bool WaveletParams::operator ==(const WaveletParams& other) const && sigmafin == other.sigmafin && sigmaton == other.sigmaton && sigmacol == other.sigmacol + && sigmadir == other.sigmadir && iter == other.iter && expcontrast == other.expcontrast && expchroma == other.expchroma @@ -3529,6 +3531,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.sigmafin, "Wavelet", "Sigmafin", wavelet.sigmafin, keyFile); saveToKeyfile(!pedited || pedited->wavelet.sigmaton, "Wavelet", "Sigmaton", wavelet.sigmaton, keyFile); saveToKeyfile(!pedited || pedited->wavelet.sigmacol, "Wavelet", "Sigmacol", wavelet.sigmacol, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.sigmadir, "Wavelet", "Sigmadir", wavelet.sigmadir, keyFile); saveToKeyfile(!pedited || pedited->wavelet.iter, "Wavelet", "Iter", wavelet.iter, keyFile); saveToKeyfile(!pedited || pedited->wavelet.thres, "Wavelet", "MaxLev", wavelet.thres, keyFile); saveToKeyfile(!pedited || pedited->wavelet.Tilesmethod, "Wavelet", "TilesMethod", wavelet.Tilesmethod, keyFile); @@ -4712,6 +4715,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Wavelet", "Sigmafin", pedited, wavelet.sigmafin, pedited->wavelet.sigmafin); assignFromKeyfile(keyFile, "Wavelet", "Sigmaton", pedited, wavelet.sigmaton, pedited->wavelet.sigmaton); assignFromKeyfile(keyFile, "Wavelet", "Sigmacol", pedited, wavelet.sigmacol, pedited->wavelet.sigmacol); + assignFromKeyfile(keyFile, "Wavelet", "Sigmadir", pedited, wavelet.sigmadir, pedited->wavelet.sigmadir); assignFromKeyfile(keyFile, "Wavelet", "Iter", pedited, wavelet.iter, pedited->wavelet.iter); assignFromKeyfile(keyFile, "Wavelet", "Median", pedited, wavelet.median, pedited->wavelet.median); assignFromKeyfile(keyFile, "Wavelet", "Medianlev", pedited, wavelet.medianlev, pedited->wavelet.medianlev); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 536f260bc..cd09c2e6d 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1224,6 +1224,7 @@ struct WaveletParams { double sigmafin; double sigmaton; double sigmacol; + double sigmadir; int iter; bool expcontrast; bool expchroma; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 8a97681e4..a367b3db4 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -478,6 +478,7 @@ void ParamsEdited::set(bool v) wavelet.sigmafin = v; wavelet.sigmaton = v; wavelet.sigmacol = v; + wavelet.sigmadir = v; wavelet.median = v; wavelet.medianlev = v; wavelet.linkedg = v; @@ -1092,6 +1093,7 @@ void ParamsEdited::initFrom(const std::vector& wavelet.sigmafin = wavelet.sigmafin && p.wavelet.sigmafin == other.wavelet.sigmafin; wavelet.sigmaton = wavelet.sigmaton && p.wavelet.sigmaton == other.wavelet.sigmaton; wavelet.sigmacol = wavelet.sigmacol && p.wavelet.sigmacol == other.wavelet.sigmacol; + wavelet.sigmadir = wavelet.sigmadir && p.wavelet.sigmadir == other.wavelet.sigmadir; wavelet.median = wavelet.median && p.wavelet.median == other.wavelet.median; wavelet.medianlev = wavelet.medianlev && p.wavelet.medianlev == other.wavelet.medianlev; wavelet.linkedg = wavelet.linkedg && p.wavelet.linkedg == other.wavelet.linkedg; @@ -2915,6 +2917,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.sigmacol = mods.wavelet.sigmacol; } + if (wavelet.sigmadir) { + toEdit.wavelet.sigmadir = mods.wavelet.sigmadir; + } + if (wavelet.iter) { toEdit.wavelet.iter = mods.wavelet.iter; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index c17ea52c7..2cb4aa943 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -502,6 +502,7 @@ struct WaveletParamsEdited { bool sigmafin; bool sigmaton; bool sigmacol; + bool sigmadir; bool median; bool medianlev; bool linkedg; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 1649b0afe..3805ed4c6 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -115,6 +115,7 @@ Wavelet::Wavelet() : sigmafin(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMAFIN"), 0.025, 2.5, 0.01, 1.))), sigmaton(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMAFIN"), 0.025, 2.5, 0.01, 1.))), sigmacol(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMAFIN"), 0.025, 2.5, 0.01, 1.))), + sigmadir(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMAFIN"), 0.025, 2.5, 0.01, 1.))), hueskin(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_HUESKIN"), -314., 314., -5., 25., 170., 120., 0, false))), hueskin2(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_HUESKY"), -314., 314., -260., -250, -130., -140., 0, false))), hllev(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_HIGHLIGHT"), 0., 100., 50., 75., 100., 98., 0, false))), @@ -215,6 +216,7 @@ Wavelet::Wavelet() : EvWavsigmafin = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_SIGMAFIN"); EvWavsigmaton = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_SIGMATON"); EvWavsigmacol = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_SIGMACOL"); + EvWavsigmadir = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_SIGMADIR"); expsettings->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expsettings)); @@ -1001,6 +1003,7 @@ Wavelet::Wavelet() : iter->setAdjusterListener(this); iter->set_tooltip_text(M("TP_WAVELET_ITER_TOOLTIP")); + sigmadir->setAdjusterListener(this); // Gtk::HSeparator* const separatorbalend = Gtk::manage(new Gtk::HSeparator()); @@ -1041,6 +1044,7 @@ Wavelet::Wavelet() : dirBox->pack_start(*balance); dirBox->pack_start(*opacityCurveEditorW, Gtk::PACK_SHRINK, 2); dirBox->pack_start(*iter); + dirBox->pack_start(*sigmadir); dirBox->pack_start(*tmr); dirFrame->add(*dirBox); @@ -1454,6 +1458,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) sigmafin->setValue(pp->wavelet.sigmafin); sigmaton->setValue(pp->wavelet.sigmaton); sigmacol->setValue(pp->wavelet.sigmacol); + sigmadir->setValue(pp->wavelet.sigmadir); for (int i = 0; i < 9; i++) { correction[i]->setValue(pp->wavelet.c[i]); @@ -1574,6 +1579,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) sigmafin->setEditedState(pedited->wavelet.sigmafin ? Edited : UnEdited); sigmaton->setEditedState(pedited->wavelet.sigmaton ? Edited : UnEdited); sigmacol->setEditedState(pedited->wavelet.sigmacol ? Edited : UnEdited); + sigmadir->setEditedState(pedited->wavelet.sigmadir ? Edited : UnEdited); threshold->setEditedState(pedited->wavelet.threshold ? Edited : UnEdited); threshold2->setEditedState(pedited->wavelet.threshold2 ? Edited : UnEdited); edgedetect->setEditedState(pedited->wavelet.edgedetect ? Edited : UnEdited); @@ -1848,6 +1854,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pp->wavelet.sigmafin = sigmafin->getValue(); pp->wavelet.sigmaton = sigmaton->getValue(); pp->wavelet.sigmacol = sigmacol->getValue(); + pp->wavelet.sigmadir = sigmadir->getValue(); for (int i = 0; i < 9; i++) { pp->wavelet.c[i] = (int) correction[i]->getValue(); @@ -1957,6 +1964,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.sigmafin = sigmafin->getEditedState(); pedited->wavelet.sigmaton = sigmaton->getEditedState(); pedited->wavelet.sigmacol = sigmacol->getEditedState(); + pedited->wavelet.sigmadir = sigmadir->getEditedState(); pedited->wavelet.wavclCurve = !clshape->isUnChanged(); pedited->wavelet.expcontrast = !expcontrast->get_inconsistent(); pedited->wavelet.expchroma = !expchroma->get_inconsistent(); @@ -2140,6 +2148,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit sigmafin->setDefault(defParams->wavelet.sigmafin); sigmaton->setDefault(defParams->wavelet.sigmaton); sigmacol->setDefault(defParams->wavelet.sigmacol); + sigmadir->setDefault(defParams->wavelet.sigmadir); sigma->setDefault(defParams->wavelet.sigma); offset->setDefault(defParams->wavelet.offset); lowthr->setDefault(defParams->wavelet.lowthr); @@ -2265,6 +2274,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit sigmafin->setDefaultEditedState(pedited->wavelet.sigmafin ? Edited : UnEdited); sigmaton->setDefaultEditedState(pedited->wavelet.sigmaton ? Edited : UnEdited); sigmacol->setDefaultEditedState(pedited->wavelet.sigmacol ? Edited : UnEdited); + sigmadir->setDefaultEditedState(pedited->wavelet.sigmadir ? Edited : UnEdited); level0noise->setDefaultEditedState(pedited->wavelet.level0noise ? Edited : UnEdited); level1noise->setDefaultEditedState(pedited->wavelet.level1noise ? Edited : UnEdited); level2noise->setDefaultEditedState(pedited->wavelet.level2noise ? Edited : UnEdited); @@ -2330,6 +2340,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit sigmafin->setDefaultEditedState(Irrelevant); sigmaton->setDefaultEditedState(Irrelevant); sigmacol->setDefaultEditedState(Irrelevant); + sigmadir->setDefaultEditedState(Irrelevant); for (int i = 0; i < 9; i++) { correction[i]->setDefaultEditedState(Irrelevant); @@ -2871,6 +2882,7 @@ void Wavelet::setBatchMode(bool batchMode) sigmafin->showEditedCB(); sigmaton->showEditedCB(); sigmacol->showEditedCB(); + sigmadir->showEditedCB(); level0noise->showEditedCB(); level1noise->showEditedCB(); level2noise->showEditedCB(); @@ -3026,6 +3038,8 @@ void Wavelet::adjusterChanged(Adjuster* a, double newval) listener->panelChanged(EvWavsigmaton, sigmaton->getTextValue()); } else if (a == sigmacol) { listener->panelChanged(EvWavsigmacol, sigmacol->getTextValue()); + } else if (a == sigmadir) { + listener->panelChanged(EvWavsigmadir, sigmadir->getTextValue()); } else if (a == greenhigh) { listener->panelChanged(EvWavgreenhigh, greenhigh->getTextValue()); } else if (a == bluehigh) { diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index 644d8f6b9..b235cde47 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -96,6 +96,7 @@ private: rtengine::ProcEvent EvWavsigmafin; rtengine::ProcEvent EvWavsigmaton; rtengine::ProcEvent EvWavsigmacol; + rtengine::ProcEvent EvWavsigmadir; void foldAllButMe(GdkEventButton* event, MyExpander *expander); @@ -224,6 +225,7 @@ private: Adjuster* const sigmafin; Adjuster* const sigmaton; Adjuster* const sigmacol; + Adjuster* const sigmadir; Adjuster* greenlow; Adjuster* bluelow; From a481b18e94cad95a380db0b19c43b6545191b717 Mon Sep 17 00:00:00 2001 From: Desmis Date: Wed, 15 Apr 2020 15:37:13 +0200 Subject: [PATCH 14/28] Save provisory work on toning --- rtdata/languages/default | 4 +++ rtengine/ipwavelet.cc | 75 ++++++++++++++++++++++++++++++++++++++-- rtengine/procparams.cc | 28 +++++++++++++++ rtengine/procparams.h | 10 +++++- rtgui/paramsedited.cc | 36 +++++++++++++++++++ rtgui/paramsedited.h | 7 ++++ rtgui/wavelet.cc | 58 +++++++++++++++++++++++++++++++ rtgui/wavelet.h | 12 ++++++- 8 files changed, 225 insertions(+), 5 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 21b3da555..5627dab4c 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -821,6 +821,8 @@ HISTORY_MSG_SIGMAFIN;Final contrast Damper HISTORY_MSG_SIGMATON;Toning Damper HISTORY_MSG_SIGMACOL;Chroma Damper HISTORY_MSG_SIGMADIR;Dir Damper +HISTORY_MSG_RANGEAB;Range ab +HISTORY_MSG_PROTAB;Protection HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOT;Snapshot @@ -2287,7 +2289,9 @@ TP_WAVELET_OPACITYWL;Local contrast TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. TP_WAVELET_PASTEL;Pastel chroma TP_WAVELET_PROC;Process +TP_WAVELET_PROTAB;Protection TP_WAVELET_RADIUS;Radius Shadows - Highlight +TP_WAVELET_RANGEAB;Range a and b % TP_WAVELET_RE1;Reinforced TP_WAVELET_RE2;Unchanged TP_WAVELET_RE3;Reduced diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index f53ad083f..5b170ff9b 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -146,6 +146,19 @@ struct cont_params { float balchrom; float chromfi; float chromco; + float factor; + float scaling; + float scaledirect; + float a_scale; + float a_base; + float b_scale; + float b_base; + float a_high; + float a_low; + float b_high; + float b_low; + float rangeab; + float protab; }; int wavNestedLevels = 1; @@ -318,6 +331,20 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.mulC[m] = waparams.ch[m]; } + cp.factor = WaveletParams::LABGRID_CORR_MAX * 3.276f; + cp.scaling = WaveletParams::LABGRID_CORR_SCALE; + cp.scaledirect = WaveletParams::LABGRIDL_DIRECT_SCALE; + cp.a_scale = (params->wavelet.labgridAHigh - params->wavelet.labgridALow) / cp.factor / cp.scaling; + cp.a_base = params->wavelet.labgridALow / cp.scaling; + cp.b_scale = (params->wavelet.labgridBHigh - params->wavelet.labgridBLow) / cp.factor / cp.scaling; + cp.b_base = params->wavelet.labgridBLow / cp.scaling; + cp.a_high = 3.276f * params->wavelet.labgridAHigh; + cp.a_low = 3.276f * params->wavelet.labgridALow; + cp.b_high = 3.276f * params->wavelet.labgridBHigh; + cp.b_low = 3.276f * params->wavelet.labgridBLow; + cp.rangeab = params->wavelet.rangeab; + cp.protab = params->wavelet.protab; + if (waOpacityCurveRG) { cp.opaRG = true; } @@ -3851,7 +3878,7 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz kba = 1.f - k2; } - WavCoeffs_L[dir][i] *= (1.f + (kba -1.f) * beta[i]); + WavCoeffs_L[dir][i] *= (1.f + (kba - 1.f) * beta[i]); } } } @@ -3910,10 +3937,11 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz kba = 1.f - bal / k2; } - WavCoeffs_L[dir][i] *= (1.f + (kba -1.f) * beta[i]); + WavCoeffs_L[dir][i] *= (1.f + (kba - 1.f) * beta[i]); } } } + delete[] beta; } @@ -4131,6 +4159,25 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f float effect = cp.sigmaton; float betaab = 0.f; float offs = 1.f; + float protec = 0.01f * cp.protab; + // printf("rangeab=%f \n", 0.01f * cp.rangeab); + // printf("protab=%f \n", 0.01f * cp.protab); + float aref1 = cp.a_high; + float bref1 = cp.b_high; + float aref2 = cp.a_low; + float bref2 = cp.b_low; + // printf("a1=%f b1=%f a2=%f b2=%f\n", aref1, bref1, aref2, bref2); + + float arefplus1 = aref1 * (1.f + 0.1f * cp.rangeab); + float arefmoins1 = aref1 * (1.f - 0.1f * cp.rangeab); + float brefplus1 = bref1 * (1.f + 0.1f * cp.rangeab); + float brefmoins1 = bref1 * (1.f - 0.1f * cp.rangeab); + // printf("a1+=%f a1-=%f b+=%f b-=%f\n", arefplus1, arefmoins1, brefplus1, brefmoins1); + + float arefplus2 = aref2 * (1.f + 0.1f * cp.rangeab); + float arefmoins2 = aref2 * (1.f - 0.1f * cp.rangeab); + float brefplus2 = bref2 * (1.f + 0.1f * cp.rangeab); + float brefmoins2 = bref2 * (1.f - 0.1f * cp.rangeab); calceffect(level, meanab, sigmaab, mea, effect, offs); @@ -4161,8 +4208,30 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f betaab = 0.0f; } + float kreduc1 = 1.f; + float kreduc2 = 1.f; + int ii = co / W_ab; + int jj = co - ii * W_ab; + cp.protab = 0.f;// always disabled provisory... + if (cp.protab > 0.f) { - float beta = (1024.f + 50.f * mulOpacity * betaab) / 1024.f ; + if ((labco->a[ii * 2][jj * 2] > arefmoins1) && (labco->a[ii * 2][jj * 2] < arefplus1) + && (labco->b[ii * 2][jj * 2] > brefmoins1) && (labco->b[ii * 2][jj * 2] < brefplus1)) { + kreduc1 = protec; + // printf("p "); + } + + if ((labco->a[ii * 2][jj * 2] > arefmoins2) && (labco->a[ii * 2][jj * 2] < arefplus2) + && (labco->b[ii * 2][jj * 2] > brefmoins2) && (labco->b[ii * 2][jj * 2] < brefplus2)) { + kreduc2 = protec; + // printf("P "); + } + + + // printf("pa1=%f pa2=%f\n", kreduc1, kredu2); + } + + float beta = (1024.f + 50.f * mulOpacity * betaab * kreduc1 * kreduc2) / 1024.f ; WavCoeffs_ab[dir][co] *= beta; } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 110d9368f..e1765a5f0 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2148,6 +2148,10 @@ bool ColorManagementParams::operator !=(const ColorManagementParams& other) cons return !(*this == other); } +const double WaveletParams::LABGRID_CORR_MAX = 12800.f; +const double WaveletParams::LABGRID_CORR_SCALE = 3.276f; +const double WaveletParams::LABGRIDL_DIRECT_SCALE = 41950.; + WaveletParams::WaveletParams() : ccwcurve{ static_cast(FCT_MinMaxCPoints), @@ -2267,6 +2271,8 @@ WaveletParams::WaveletParams() : sigmaton(1.0), sigmacol(1.0), sigmadir(1.0), + rangeab(20.0), + protab(0.0), iter(0), expcontrast(false), expchroma(false), @@ -2279,6 +2285,10 @@ WaveletParams::WaveletParams() : exptoning(false), expnoise(false), expclari(false), + labgridALow(0.0), + labgridBLow(0.0), + labgridAHigh(0.0), + labgridBHigh(0.0), Lmethod(4), CLmethod("all"), Backmethod("grey"), @@ -2385,7 +2395,13 @@ bool WaveletParams::operator ==(const WaveletParams& other) const && sigmaton == other.sigmaton && sigmacol == other.sigmacol && sigmadir == other.sigmadir + && rangeab == other.rangeab + && protab == other.protab && iter == other.iter + && labgridALow == other.labgridALow + && labgridBLow == other.labgridBLow + && labgridAHigh == other.labgridAHigh + && labgridBHigh == other.labgridBHigh && expcontrast == other.expcontrast && expchroma == other.expchroma && [this, &other]() -> bool @@ -3532,6 +3548,8 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.sigmaton, "Wavelet", "Sigmaton", wavelet.sigmaton, keyFile); saveToKeyfile(!pedited || pedited->wavelet.sigmacol, "Wavelet", "Sigmacol", wavelet.sigmacol, keyFile); saveToKeyfile(!pedited || pedited->wavelet.sigmadir, "Wavelet", "Sigmadir", wavelet.sigmadir, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.rangeab, "Wavelet", "Rangeab", wavelet.rangeab, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.protab, "Wavelet", "Protab", wavelet.protab, keyFile); saveToKeyfile(!pedited || pedited->wavelet.iter, "Wavelet", "Iter", wavelet.iter, keyFile); saveToKeyfile(!pedited || pedited->wavelet.thres, "Wavelet", "MaxLev", wavelet.thres, keyFile); saveToKeyfile(!pedited || pedited->wavelet.Tilesmethod, "Wavelet", "TilesMethod", wavelet.Tilesmethod, keyFile); @@ -3563,6 +3581,10 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.exptoning, "Wavelet", "Exptoning", wavelet.exptoning, keyFile); saveToKeyfile(!pedited || pedited->wavelet.expnoise, "Wavelet", "Expnoise", wavelet.expnoise, keyFile); saveToKeyfile(!pedited || pedited->wavelet.expclari, "Wavelet", "Expclari", wavelet.expclari, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.labgridALow, "Wavelet", "LabGridALow", wavelet.labgridALow, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.labgridBLow, "Wavelet", "LabGridBLow", wavelet.labgridBLow, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.labgridAHigh, "Wavelet", "LabGridAHigh", wavelet.labgridAHigh, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.labgridBHigh, "Wavelet", "LabGridBHigh", wavelet.labgridBHigh, keyFile); for (int i = 0; i < 9; i++) { std::stringstream ss; @@ -4716,6 +4738,8 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Wavelet", "Sigmaton", pedited, wavelet.sigmaton, pedited->wavelet.sigmaton); assignFromKeyfile(keyFile, "Wavelet", "Sigmacol", pedited, wavelet.sigmacol, pedited->wavelet.sigmacol); assignFromKeyfile(keyFile, "Wavelet", "Sigmadir", pedited, wavelet.sigmadir, pedited->wavelet.sigmadir); + assignFromKeyfile(keyFile, "Wavelet", "Rangeab", pedited, wavelet.rangeab, pedited->wavelet.rangeab); + assignFromKeyfile(keyFile, "Wavelet", "Protab", pedited, wavelet.protab, pedited->wavelet.protab); assignFromKeyfile(keyFile, "Wavelet", "Iter", pedited, wavelet.iter, pedited->wavelet.iter); assignFromKeyfile(keyFile, "Wavelet", "Median", pedited, wavelet.median, pedited->wavelet.median); assignFromKeyfile(keyFile, "Wavelet", "Medianlev", pedited, wavelet.medianlev, pedited->wavelet.medianlev); @@ -4740,6 +4764,10 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Wavelet", "Showmask", pedited, wavelet.showmask, pedited->wavelet.showmask); assignFromKeyfile(keyFile, "Wavelet", "Oldsh", pedited, wavelet.oldsh, pedited->wavelet.oldsh); assignFromKeyfile(keyFile, "Wavelet", "TMr", pedited, wavelet.tmr, pedited->wavelet.tmr); + assignFromKeyfile(keyFile, "Wavelet", "LabGridALow", pedited, wavelet.labgridALow, pedited->wavelet.labgridALow); + assignFromKeyfile(keyFile, "Wavelet", "LabGridBLow", pedited, wavelet.labgridBLow, pedited->wavelet.labgridBLow); + assignFromKeyfile(keyFile, "Wavelet", "LabGridAHigh", pedited, wavelet.labgridAHigh, pedited->wavelet.labgridAHigh); + assignFromKeyfile(keyFile, "Wavelet", "LabGridBHigh", pedited, wavelet.labgridBHigh, pedited->wavelet.labgridBHigh); if (ppVersion < 331) { // wavelet.Lmethod was a string before version 331 Glib::ustring temp; diff --git a/rtengine/procparams.h b/rtengine/procparams.h index cd09c2e6d..24995525d 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1225,6 +1225,8 @@ struct WaveletParams { double sigmaton; double sigmacol; double sigmadir; + double rangeab; + double protab; int iter; bool expcontrast; bool expchroma; @@ -1237,7 +1239,13 @@ struct WaveletParams { bool exptoning; bool expnoise; bool expclari; - + double labgridALow; + double labgridBLow; + double labgridAHigh; + double labgridBHigh; + static const double LABGRID_CORR_MAX; + static const double LABGRID_CORR_SCALE; + static const double LABGRIDL_DIRECT_SCALE; int Lmethod; Glib::ustring CLmethod; Glib::ustring Backmethod; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index a367b3db4..85119fe80 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -479,6 +479,8 @@ void ParamsEdited::set(bool v) wavelet.sigmaton = v; wavelet.sigmacol = v; wavelet.sigmadir = v; + wavelet.rangeab = v; + wavelet.protab = v; wavelet.median = v; wavelet.medianlev = v; wavelet.linkedg = v; @@ -586,6 +588,10 @@ void ParamsEdited::set(bool v) wavelet.expresid = v; wavelet.exptoning = v; wavelet.expnoise = v; + wavelet.labgridALow = v; + wavelet.labgridBLow = v; + wavelet.labgridAHigh = v; + wavelet.labgridBHigh = v; for (int i = 0; i < 9; i++) { wavelet.c[i] = v; @@ -1094,6 +1100,8 @@ void ParamsEdited::initFrom(const std::vector& wavelet.sigmaton = wavelet.sigmaton && p.wavelet.sigmaton == other.wavelet.sigmaton; wavelet.sigmacol = wavelet.sigmacol && p.wavelet.sigmacol == other.wavelet.sigmacol; wavelet.sigmadir = wavelet.sigmadir && p.wavelet.sigmadir == other.wavelet.sigmadir; + wavelet.rangeab = wavelet.rangeab && p.wavelet.rangeab == other.wavelet.rangeab; + wavelet.protab = wavelet.protab && p.wavelet.protab == other.wavelet.protab; wavelet.median = wavelet.median && p.wavelet.median == other.wavelet.median; wavelet.medianlev = wavelet.medianlev && p.wavelet.medianlev == other.wavelet.medianlev; wavelet.linkedg = wavelet.linkedg && p.wavelet.linkedg == other.wavelet.linkedg; @@ -1197,6 +1205,10 @@ void ParamsEdited::initFrom(const std::vector& wavelet.exptoning = wavelet.exptoning && p.wavelet.exptoning == other.wavelet.exptoning; wavelet.expnoise = wavelet.expnoise && p.wavelet.expnoise == other.wavelet.expnoise; wavelet.expclari = wavelet.expclari && p.wavelet.expclari == other.wavelet.expclari; + wavelet.labgridALow = wavelet.labgridALow && p.wavelet.labgridALow == other.wavelet.labgridALow; + wavelet.labgridBLow = wavelet.labgridBLow && p.wavelet.labgridBLow == other.wavelet.labgridBLow; + wavelet.labgridAHigh = wavelet.labgridAHigh && p.wavelet.labgridAHigh == other.wavelet.labgridAHigh; + wavelet.labgridBHigh = wavelet.labgridBHigh && p.wavelet.labgridBHigh == other.wavelet.labgridBHigh; for (int level = 0; level < 9; ++level) { wavelet.c[level] = wavelet.c[level] && p.wavelet.c[level] == other.wavelet.c[level]; @@ -2897,6 +2909,22 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.enabled = mods.wavelet.enabled; } + if (wavelet.labgridALow) { + toEdit.wavelet.labgridALow = mods.wavelet.labgridALow; + } + + if (wavelet.labgridBLow) { + toEdit.wavelet.labgridBLow = mods.wavelet.labgridBLow; + } + + if (wavelet.labgridAHigh) { + toEdit.wavelet.labgridAHigh = mods.wavelet.labgridAHigh; + } + + if (wavelet.labgridBHigh) { + toEdit.wavelet.labgridBHigh = mods.wavelet.labgridBHigh; + } + if (wavelet.strength) { toEdit.wavelet.strength = mods.wavelet.strength; } @@ -2921,6 +2949,14 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.sigmadir = mods.wavelet.sigmadir; } + if (wavelet.rangeab) { + toEdit.wavelet.rangeab = mods.wavelet.rangeab; + } + + if (wavelet.protab) { + toEdit.wavelet.protab = mods.wavelet.protab; + } + if (wavelet.iter) { toEdit.wavelet.iter = mods.wavelet.iter; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 2cb4aa943..68340309d 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -503,6 +503,8 @@ struct WaveletParamsEdited { bool sigmaton; bool sigmacol; bool sigmadir; + bool rangeab; + bool protab; bool median; bool medianlev; bool linkedg; @@ -607,6 +609,11 @@ struct WaveletParamsEdited { bool exptoning; bool expnoise; bool expclari; + bool labgridALow; + bool labgridBLow; + bool labgridAHigh; + bool labgridBHigh; + }; struct DirPyrEqualizerParamsEdited { diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 3805ed4c6..08c4d6f4c 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -27,6 +27,7 @@ #include "rtimage.h" #include "options.h" #include "eventmapper.h" +#include "labgrid.h" #include "../rtengine/color.h" using namespace rtengine; @@ -116,6 +117,8 @@ Wavelet::Wavelet() : sigmaton(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMAFIN"), 0.025, 2.5, 0.01, 1.))), sigmacol(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMAFIN"), 0.025, 2.5, 0.01, 1.))), sigmadir(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMAFIN"), 0.025, 2.5, 0.01, 1.))), + rangeab(Gtk::manage(new Adjuster(M("TP_WAVELET_RANGEAB"), 0., 100., 0.1, 20.))), + protab(Gtk::manage(new Adjuster(M("TP_WAVELET_PROTAB"), 0., 100., 0.5, 0.))), hueskin(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_HUESKIN"), -314., 314., -5., 25., 170., 120., 0, false))), hueskin2(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_HUESKY"), -314., 314., -260., -250, -130., -140., 0, false))), hllev(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_HIGHLIGHT"), 0., 100., 50., 75., 100., 98., 0, false))), @@ -168,6 +171,7 @@ Wavelet::Wavelet() : chroFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_CHROFRAME")))), fincFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_FINCFRAME")))), dirFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_DIRFRAME")))), + tonFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_TONFRAME")))), wavLabels(Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER))), labmC(Gtk::manage(new Gtk::Label(M("TP_WAVELET_CTYPE") + ":"))), labmNP(Gtk::manage(new Gtk::Label(M("TP_WAVELET_NPTYPE") + ":"))), @@ -217,6 +221,11 @@ Wavelet::Wavelet() : EvWavsigmaton = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_SIGMATON"); EvWavsigmacol = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_SIGMACOL"); EvWavsigmadir = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_SIGMADIR"); + EvWavLabGridValue = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVLABGRID_VALUE"); + EvWavrangeab = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_RANGEAB"); + EvWavprotab = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_PROTAB"); + + labgrid = Gtk::manage(new LabGrid(EvWavLabGridValue, M("TP_WAVELET_LABGRID_VALUES"))); expsettings->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expsettings)); @@ -497,6 +506,8 @@ Wavelet::Wavelet() : // Toning ToolParamBlock* const tonBox = Gtk::manage(new ToolParamBlock()); sigmaton->setAdjusterListener(this); + rangeab->setAdjusterListener(this); + protab->setAdjusterListener(this); opaCurveEditorG->setCurveListener(this); @@ -515,6 +526,15 @@ Wavelet::Wavelet() : opaCurveEditorG->curveListComplete(); opaCurveEditorG->show(); tonBox->pack_start(*sigmaton); + + tonFrame->set_label_align(0.025, 0.5); + ToolParamBlock* const ton2Box = Gtk::manage(new ToolParamBlock()); + ton2Box->pack_start(*labgrid, Gtk::PACK_EXPAND_WIDGET, 2); + ton2Box->pack_start(*rangeab); + ton2Box->pack_start(*protab); + tonFrame->add(*ton2Box); +// tonBox->pack_start(*tonFrame); + tonBox->pack_start(*opaCurveEditorG, Gtk::PACK_SHRINK, 2); opacityCurveEditorG->setCurveListener(this); @@ -1157,6 +1177,13 @@ void Wavelet::neutral_pressed() } } +void Wavelet::setListener(ToolPanelListener *tpl) +{ + ToolPanel::setListener(tpl); + labgrid->setListener(tpl); +} + + void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) { @@ -1443,6 +1470,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) mergeC->setValue(pp->wavelet.mergeC); softrad->setValue(pp->wavelet.softrad); softradend->setValue(pp->wavelet.softradend); + labgrid->setParams(pp->wavelet.labgridALow / WaveletParams::LABGRID_CORR_MAX, pp->wavelet.labgridBLow / WaveletParams::LABGRID_CORR_MAX, pp->wavelet.labgridAHigh / WaveletParams::LABGRID_CORR_MAX, pp->wavelet.labgridBHigh / WaveletParams::LABGRID_CORR_MAX, false); ballum->setValue(pp->wavelet.ballum); balchrom->setValue(pp->wavelet.balchrom); @@ -1459,6 +1487,8 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) sigmaton->setValue(pp->wavelet.sigmaton); sigmacol->setValue(pp->wavelet.sigmacol); sigmadir->setValue(pp->wavelet.sigmadir); + rangeab->setValue(pp->wavelet.rangeab); + protab->setValue(pp->wavelet.protab); for (int i = 0; i < 9; i++) { correction[i]->setValue(pp->wavelet.c[i]); @@ -1534,6 +1564,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) if (!pedited->wavelet.ushamethod) { ushamethod->set_active_text(M("GENERAL_UNCHANGED")); } + labgrid->setEdited(pedited->wavelet.labgridALow || pedited->wavelet.labgridBLow || pedited->wavelet.labgridAHigh || pedited->wavelet.labgridBHigh); set_inconsistent(multiImage && !pedited->wavelet.enabled); ccshape->setUnChanged(!pedited->wavelet.ccwcurve); @@ -1580,6 +1611,8 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) sigmaton->setEditedState(pedited->wavelet.sigmaton ? Edited : UnEdited); sigmacol->setEditedState(pedited->wavelet.sigmacol ? Edited : UnEdited); sigmadir->setEditedState(pedited->wavelet.sigmadir ? Edited : UnEdited); + rangeab->setEditedState(pedited->wavelet.rangeab ? Edited : UnEdited); + protab->setEditedState(pedited->wavelet.protab ? Edited : UnEdited); threshold->setEditedState(pedited->wavelet.threshold ? Edited : UnEdited); threshold2->setEditedState(pedited->wavelet.threshold2 ? Edited : UnEdited); edgedetect->setEditedState(pedited->wavelet.edgedetect ? Edited : UnEdited); @@ -1828,6 +1861,11 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pp->wavelet.ballum = ballum->getValue(); pp->wavelet.chromfi = chromfi->getValue(); pp->wavelet.chromco = chromco->getValue(); + labgrid->getParams(pp->wavelet.labgridALow, pp->wavelet.labgridBLow, pp->wavelet.labgridAHigh, pp->wavelet.labgridBHigh); + pp->wavelet.labgridALow *= WaveletParams::LABGRID_CORR_MAX; + pp->wavelet.labgridAHigh *= WaveletParams::LABGRID_CORR_MAX; + pp->wavelet.labgridBLow *= WaveletParams::LABGRID_CORR_MAX; + pp->wavelet.labgridBHigh *= WaveletParams::LABGRID_CORR_MAX; pp->wavelet.greenlow = greenlow->getValue(); pp->wavelet.bluelow = bluelow->getValue(); @@ -1855,6 +1893,8 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pp->wavelet.sigmaton = sigmaton->getValue(); pp->wavelet.sigmacol = sigmacol->getValue(); pp->wavelet.sigmadir = sigmadir->getValue(); + pp->wavelet.rangeab = rangeab->getValue(); + pp->wavelet.protab = protab->getValue(); for (int i = 0; i < 9; i++) { pp->wavelet.c[i] = (int) correction[i]->getValue(); @@ -1965,6 +2005,8 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.sigmaton = sigmaton->getEditedState(); pedited->wavelet.sigmacol = sigmacol->getEditedState(); pedited->wavelet.sigmadir = sigmadir->getEditedState(); + pedited->wavelet.rangeab = rangeab->getEditedState(); + pedited->wavelet.protab = protab->getEditedState(); pedited->wavelet.wavclCurve = !clshape->isUnChanged(); pedited->wavelet.expcontrast = !expcontrast->get_inconsistent(); pedited->wavelet.expchroma = !expchroma->get_inconsistent(); @@ -1975,6 +2017,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.exptoning = !exptoning->get_inconsistent(); pedited->wavelet.expnoise = !expnoise->get_inconsistent(); pedited->wavelet.expclari = !expclari->get_inconsistent(); + pedited->wavelet.labgridALow = pedited->wavelet.labgridBLow = pedited->wavelet.labgridAHigh = pedited->wavelet.labgridBHigh = labgrid->getEdited(); for (int i = 0; i < 9; i++) { pedited->wavelet.c[i] = correction[i]->getEditedState(); @@ -2150,6 +2193,8 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit sigmacol->setDefault(defParams->wavelet.sigmacol); sigmadir->setDefault(defParams->wavelet.sigmadir); sigma->setDefault(defParams->wavelet.sigma); + rangeab->setDefault(defParams->wavelet.rangeab); + protab->setDefault(defParams->wavelet.protab); offset->setDefault(defParams->wavelet.offset); lowthr->setDefault(defParams->wavelet.lowthr); rescon->setDefault(defParams->wavelet.rescon); @@ -2198,6 +2243,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit balchrom->setDefault(defParams->wavelet.balchrom); chromfi->setDefault(defParams->wavelet.chromfi); chromco->setDefault(defParams->wavelet.chromco); + labgrid->setDefault(defParams->wavelet.labgridALow / WaveletParams::LABGRID_CORR_MAX, defParams->wavelet.labgridBLow / WaveletParams::LABGRID_CORR_MAX, defParams->wavelet.labgridAHigh / WaveletParams::LABGRID_CORR_MAX, defParams->wavelet.labgridBHigh / WaveletParams::LABGRID_CORR_MAX); greenlow->setDefault(defParams->wavelet.greenlow); bluelow->setDefault(defParams->wavelet.bluelow); @@ -2225,6 +2271,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit balchrom->setDefaultEditedState(pedited->wavelet.balchrom ? Edited : UnEdited); chromfi->setDefaultEditedState(pedited->wavelet.chromfi ? Edited : UnEdited); chromco->setDefaultEditedState(pedited->wavelet.chromco ? Edited : UnEdited); + labgrid->setEdited((pedited->wavelet.labgridALow || pedited->wavelet.labgridBLow || pedited->wavelet.labgridAHigh || pedited->wavelet.labgridBHigh) ? Edited : UnEdited); sigma->setDefault(defParams->wavelet.sigma); offset->setDefault(defParams->wavelet.offset); @@ -2275,6 +2322,8 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit sigmaton->setDefaultEditedState(pedited->wavelet.sigmaton ? Edited : UnEdited); sigmacol->setDefaultEditedState(pedited->wavelet.sigmacol ? Edited : UnEdited); sigmadir->setDefaultEditedState(pedited->wavelet.sigmadir ? Edited : UnEdited); + rangeab->setDefaultEditedState(pedited->wavelet.rangeab ? Edited : UnEdited); + protab->setDefaultEditedState(pedited->wavelet.protab ? Edited : UnEdited); level0noise->setDefaultEditedState(pedited->wavelet.level0noise ? Edited : UnEdited); level1noise->setDefaultEditedState(pedited->wavelet.level1noise ? Edited : UnEdited); level2noise->setDefaultEditedState(pedited->wavelet.level2noise ? Edited : UnEdited); @@ -2341,6 +2390,9 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit sigmaton->setDefaultEditedState(Irrelevant); sigmacol->setDefaultEditedState(Irrelevant); sigmadir->setDefaultEditedState(Irrelevant); + rangeab->setDefaultEditedState(Irrelevant); + protab->setDefaultEditedState(Irrelevant); + labgrid->setEdited(Edited); for (int i = 0; i < 9; i++) { correction[i]->setDefaultEditedState(Irrelevant); @@ -2883,6 +2935,8 @@ void Wavelet::setBatchMode(bool batchMode) sigmaton->showEditedCB(); sigmacol->showEditedCB(); sigmadir->showEditedCB(); + rangeab->showEditedCB(); + protab->showEditedCB(); level0noise->showEditedCB(); level1noise->showEditedCB(); level2noise->showEditedCB(); @@ -3036,6 +3090,10 @@ void Wavelet::adjusterChanged(Adjuster* a, double newval) listener->panelChanged(EvWavsigmafin, sigmafin->getTextValue()); } else if (a == sigmaton) { listener->panelChanged(EvWavsigmaton, sigmaton->getTextValue()); + } else if (a == rangeab) { + listener->panelChanged(EvWavrangeab, rangeab->getTextValue()); + } else if (a == protab) { + listener->panelChanged(EvWavprotab, protab->getTextValue()); } else if (a == sigmacol) { listener->panelChanged(EvWavsigmacol, sigmacol->getTextValue()); } else if (a == sigmadir) { diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index b235cde47..c9cd3dc4c 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -33,6 +33,7 @@ class CurveEditorGroup; class DiagonalCurveEditor; class EditDataProvider; class FlatCurveEditor; +class LabGrid; class Wavelet final : public ToolParamBlock, @@ -97,8 +98,14 @@ private: rtengine::ProcEvent EvWavsigmaton; rtengine::ProcEvent EvWavsigmacol; rtengine::ProcEvent EvWavsigmadir; + rtengine::ProcEvent EvWavLabGridValue; + rtengine::ProcEvent EvWavrangeab; + rtengine::ProcEvent EvWavprotab; + + LabGrid *labgrid; void foldAllButMe(GdkEventButton* event, MyExpander *expander); + void setListener(ToolPanelListener *tpl) override; void colorForValue(double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller) override; void BAmethodChanged(); @@ -226,7 +233,9 @@ private: Adjuster* const sigmaton; Adjuster* const sigmacol; Adjuster* const sigmadir; - + Adjuster* const rangeab; + Adjuster* const protab; + Adjuster* greenlow; Adjuster* bluelow; Adjuster* greenmed; @@ -304,6 +313,7 @@ private: Gtk::Frame* const chroFrame; Gtk::Frame* const fincFrame; Gtk::Frame* const dirFrame; + Gtk::Frame* const tonFrame; Gtk::Label* const wavLabels; Gtk::Label* const labmC; From c46eb298755bb58b468bfc95dac4530be9176ac7 Mon Sep 17 00:00:00 2001 From: Desmis Date: Thu, 16 Apr 2020 08:43:25 +0200 Subject: [PATCH 15/28] Improve toning level (disabled) - add information verbose --- rtdata/languages/default | 1 + rtengine/ipwavelet.cc | 59 ++++++++++++++++++++++++---------------- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 5627dab4c..5f8906b3d 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2337,6 +2337,7 @@ TP_WAVELET_TMSTRENGTH;Compression strength TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. TP_WAVELET_TMEDGS;Edge stopping TP_WAVELET_TON;Toning +TP_WAVELET_TONFRAME;Excluded Colors TP_WAVELET_TMTYPE;Compression method TP_WAVELET_USH;None TP_WAVELET_USHARP;Clarity method diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 5b170ff9b..8bc1d056a 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -918,6 +918,10 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const float ** WavCoeffs_L = Ldecomp->level_coeffs(lvl); madL[lvl][dir - 1] = SQR(Mad(WavCoeffs_L[dir], Wlvl_L * Hlvl_L)); + + if (settings->verbose) { + printf("sqrt madL=%f lvl=%i dir=%i\n", sqrt(madL[lvl][dir - 1]), lvl, dir - 1); + } } } @@ -4159,25 +4163,22 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f float effect = cp.sigmaton; float betaab = 0.f; float offs = 1.f; - float protec = 0.01f * cp.protab; - // printf("rangeab=%f \n", 0.01f * cp.rangeab); - // printf("protab=%f \n", 0.01f * cp.protab); + float protec = 0.01f * (100.f - cp.protab); float aref1 = cp.a_high; float bref1 = cp.b_high; float aref2 = cp.a_low; float bref2 = cp.b_low; - // printf("a1=%f b1=%f a2=%f b2=%f\n", aref1, bref1, aref2, bref2); - float arefplus1 = aref1 * (1.f + 0.1f * cp.rangeab); - float arefmoins1 = aref1 * (1.f - 0.1f * cp.rangeab); - float brefplus1 = bref1 * (1.f + 0.1f * cp.rangeab); - float brefmoins1 = bref1 * (1.f - 0.1f * cp.rangeab); - // printf("a1+=%f a1-=%f b+=%f b-=%f\n", arefplus1, arefmoins1, brefplus1, brefmoins1); + float kk = 100.f; + float arefplus1 = aref1 + cp.rangeab * kk; + float arefmoins1 = aref1 - cp.rangeab * kk; + float brefplus1 = bref1 + cp.rangeab * kk; + float brefmoins1 = bref1 - cp.rangeab * kk; - float arefplus2 = aref2 * (1.f + 0.1f * cp.rangeab); - float arefmoins2 = aref2 * (1.f - 0.1f * cp.rangeab); - float brefplus2 = bref2 * (1.f + 0.1f * cp.rangeab); - float brefmoins2 = bref2 * (1.f - 0.1f * cp.rangeab); + float arefplus2 = aref2 + cp.rangeab * kk; + float arefmoins2 = aref2 - cp.rangeab * kk; + float brefplus2 = bref2 + cp.rangeab * kk; + float brefmoins2 = bref2 - cp.rangeab * kk; calceffect(level, meanab, sigmaab, mea, effect, offs); @@ -4212,25 +4213,35 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f float kreduc2 = 1.f; int ii = co / W_ab; int jj = co - ii * W_ab; + cp.protab = 0.f;// always disabled provisory... if (cp.protab > 0.f) { - - if ((labco->a[ii * 2][jj * 2] > arefmoins1) && (labco->a[ii * 2][jj * 2] < arefplus1) - && (labco->b[ii * 2][jj * 2] > brefmoins1) && (labco->b[ii * 2][jj * 2] < brefplus1)) { - kreduc1 = protec; - // printf("p "); + if (useChannelA) { + if ((labco->a[ii * 2][jj * 2] > arefmoins1) && (labco->a[ii * 2][jj * 2] < arefplus1)) { + kreduc1 = protec; + } + } else { + if ((labco->b[ii * 2][jj * 2] > brefmoins1) && (labco->b[ii * 2][jj * 2] < brefplus1)) { + kreduc1 = protec; + } } - if ((labco->a[ii * 2][jj * 2] > arefmoins2) && (labco->a[ii * 2][jj * 2] < arefplus2) - && (labco->b[ii * 2][jj * 2] > brefmoins2) && (labco->b[ii * 2][jj * 2] < brefplus2)) { - kreduc2 = protec; - // printf("P "); + if (useChannelA) { + if ((labco->a[ii * 2][jj * 2] > arefmoins2) && (labco->a[ii * 2][jj * 2] < arefplus2)) { + kreduc2 = protec; + } + } else { + if ((labco->b[ii * 2][jj * 2] > brefmoins2) && (labco->b[ii * 2][jj * 2] < brefplus2)) { + kreduc2 = protec; + } } - - // printf("pa1=%f pa2=%f\n", kreduc1, kredu2); } + + // printf("pa1=%f pa2=%f\n", kreduc1, kredu2); + + float beta = (1024.f + 50.f * mulOpacity * betaab * kreduc1 * kreduc2) / 1024.f ; WavCoeffs_ab[dir][co] *= beta; From a70691caf1227f75e76ac18a9fddb99d6bd8884a Mon Sep 17 00:00:00 2001 From: Desmis Date: Thu, 16 Apr 2020 10:57:52 +0200 Subject: [PATCH 16/28] Enabled Toning excluded colors - to test --- rtengine/ipwavelet.cc | 28 +++++++++++++++++++++++----- rtgui/wavelet.cc | 2 +- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 8bc1d056a..3b00d8aaf 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -4214,25 +4214,43 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f int ii = co / W_ab; int jj = co - ii * W_ab; - cp.protab = 0.f;// always disabled provisory... + // cp.protab = 0.f;// always disabled provisory... if (cp.protab > 0.f) { if (useChannelA) { if ((labco->a[ii * 2][jj * 2] > arefmoins1) && (labco->a[ii * 2][jj * 2] < arefplus1)) { - kreduc1 = protec; + kreduc1 = 0.5f * protec; + + if ((labco->a[ii * 2][jj * 2] > 0.8f * arefmoins1) && (labco->a[ii * 2][jj * 2] < 0.8f * arefplus1)) { + kreduc1 = protec; + } } + } else { if ((labco->b[ii * 2][jj * 2] > brefmoins1) && (labco->b[ii * 2][jj * 2] < brefplus1)) { - kreduc1 = protec; + kreduc1 = 0.5f * protec; + + if ((labco->b[ii * 2][jj * 2] > 0.8f * brefmoins1) && (labco->b[ii * 2][jj * 2] < 0.8f * brefplus1)) { + kreduc1 = protec; + } } } if (useChannelA) { if ((labco->a[ii * 2][jj * 2] > arefmoins2) && (labco->a[ii * 2][jj * 2] < arefplus2)) { - kreduc2 = protec; + kreduc2 = 0.5f * protec; + + if ((labco->a[ii * 2][jj * 2] > 0.8f * arefmoins2) && (labco->a[ii * 2][jj * 2] < 0.8f * arefplus2)) { + kreduc2 = protec; + } + } } else { if ((labco->b[ii * 2][jj * 2] > brefmoins2) && (labco->b[ii * 2][jj * 2] < brefplus2)) { - kreduc2 = protec; + kreduc2 = 0.5f * protec; + + if ((labco->b[ii * 2][jj * 2] > brefmoins2) && (labco->b[ii * 2][jj * 2] < brefplus2)) { + kreduc2 = protec; + } } } diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 08c4d6f4c..1f4714452 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -533,7 +533,7 @@ Wavelet::Wavelet() : ton2Box->pack_start(*rangeab); ton2Box->pack_start(*protab); tonFrame->add(*ton2Box); -// tonBox->pack_start(*tonFrame); + tonBox->pack_start(*tonFrame); tonBox->pack_start(*opaCurveEditorG, Gtk::PACK_SHRINK, 2); From cec79084296570fb5b4a076d3f9a3c1fbad3ed04 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 3 May 2020 17:06:16 +0300 Subject: [PATCH 17/28] rtexif: Fix conversion from RATIONAL to int, double or string RATIONAL tags are defined as a ratio of two LONG, themselves defined as 32-bit unsigned integers. The value is misinterpreted when converting to an int, double or string, as the numerator and the denominator are interpreted as signed values. The problem has been noticed with the ExposureTime tag generated by libtiff, which sets the denominator to 0xffffffff for exposure times lower than 1. Fix it. Signed-off-by: Laurent Pinchart --- rtexif/rtexif.cc | 26 ++++++++++++++++++-------- rtexif/rtexif.h | 22 +++++++++++++++------- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index 06604ade5..95b46c2b9 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -1510,8 +1510,6 @@ int Tag::toInt (int ofs, TagType astype) const return attrib->interpreter->toInt (this, ofs, astype); } - int a; - if (astype == INVALID) { astype = type; } @@ -1537,10 +1535,15 @@ int Tag::toInt (int ofs, TagType astype) const case LONG: return (int)sget4 (value + ofs, getOrder()); - case SRATIONAL: - case RATIONAL: - a = (int)sget4 (value + ofs + 4, getOrder()); + case SRATIONAL: { + int a = (int)sget4 (value + ofs + 4, getOrder()); return a == 0 ? 0 : (int)sget4 (value + ofs, getOrder()) / a; + } + + case RATIONAL: { + uint32_t a = (uint32_t)sget4 (value + ofs + 4, getOrder()); + return a == 0 ? 0 : (uint32_t)sget4 (value + ofs, getOrder()) / a; + } case FLOAT: return (int)toDouble (ofs); @@ -1589,10 +1592,14 @@ double Tag::toDouble (int ofs) const return (double) ((int)sget4 (value + ofs, getOrder())); case SRATIONAL: - case RATIONAL: ud = (int)sget4 (value + ofs, getOrder()); dd = (int)sget4 (value + ofs + 4, getOrder()); - return dd == 0. ? 0. : (double)ud / (double)dd; + return dd == 0. ? 0. : ud / dd; + + case RATIONAL: + ud = (uint32_t)sget4 (value + ofs, getOrder()); + dd = (uint32_t)sget4 (value + ofs + 4, getOrder()); + return dd == 0. ? 0. : ud / dd; case FLOAT: conv.i = sget4 (value + ofs, getOrder()); @@ -1735,10 +1742,13 @@ void Tag::toString (char* buffer, int ofs) const break; case SRATIONAL: - case RATIONAL: sprintf (b, "%d/%d", (int)sget4 (value + 8 * i + ofs, getOrder()), (int)sget4 (value + 8 * i + ofs + 4, getOrder())); break; + case RATIONAL: + sprintf (b, "%u/%u", (uint32_t)sget4 (value + 8 * i + ofs, getOrder()), (uint32_t)sget4 (value + 8 * i + ofs + 4, getOrder())); + break; + case FLOAT: sprintf (b, "%g", toDouble (8 * i + ofs)); break; diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h index 1a956a4a5..5084f70de 100644 --- a/rtexif/rtexif.h +++ b/rtexif/rtexif.h @@ -434,13 +434,18 @@ public: case LONG: return (double) ((int)sget4 (t->getValue() + ofs, t->getOrder())); - case SRATIONAL: - case RATIONAL: { + case SRATIONAL: { const double dividend = (int)sget4 (t->getValue() + ofs, t->getOrder()); const double divisor = (int)sget4 (t->getValue() + ofs + 4, t->getOrder()); return divisor == 0. ? 0. : dividend / divisor; } + case RATIONAL: { + const double dividend = (uint32_t)sget4 (t->getValue() + ofs, t->getOrder()); + const double divisor = (uint32_t)sget4 (t->getValue() + ofs + 4, t->getOrder()); + return divisor == 0. ? 0. : dividend / divisor; + } + case FLOAT: return double (sget4 (t->getValue() + ofs, t->getOrder())); @@ -454,8 +459,6 @@ public: // Get the value as an int virtual int toInt (const Tag* t, int ofs = 0, TagType astype = INVALID) { - int a; - if (astype == INVALID || astype == AUTO) { astype = t->getType(); } @@ -480,10 +483,15 @@ public: case LONG: return (int)sget4 (t->getValue() + ofs, t->getOrder()); - case SRATIONAL: - case RATIONAL: - a = (int)sget4 (t->getValue() + ofs + 4, t->getOrder()); + case SRATIONAL: { + int a = (int)sget4 (t->getValue() + ofs + 4, t->getOrder()); return a == 0 ? 0 : (int)sget4 (t->getValue() + ofs, t->getOrder()) / a; + } + + case RATIONAL: { + uint32_t a = (uint32_t)sget4 (t->getValue() + ofs + 4, t->getOrder()); + return a == 0 ? 0 : (uint32_t)sget4 (t->getValue() + ofs, t->getOrder()) / a; + } case FLOAT: return (int)toDouble (t, ofs); From 8581799a7a4e1adc6f4b93264bfa20cdd41f92c0 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 11 May 2020 22:33:43 +0200 Subject: [PATCH 18/28] make ipwavelets.cc cppcheck clean --- rtengine/improcfun.h | 4 - rtengine/ipwavelet.cc | 401 ++++++++---------------------------------- 2 files changed, 72 insertions(+), 333 deletions(-) diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 9d4a0235c..b2df86112 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -188,7 +188,6 @@ public: void EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params& cp, int W_L, int H_L, float max0, float min0); void CompressDR(float *Source, int W_L, int H_L, float Compression, float DetailBoost); - void Compresslevels2(float **Source, int W_L, int H_L, float compression, float detailattenuator, float thres, float mean, float maxp, float meanN, float maxN, float madL); void ContrastResid(float * WavCoeffs_L0, struct cont_params &cp, int W_L, int H_L, float max0, float min0); void EPDToneMap(LabImage *lab, unsigned int Iterates = 0, int skip = 1); @@ -228,9 +227,6 @@ public: void Sigma(float * HH_Coeffs, int datalen, float averagePlus, float averageNeg, float &sigmaPlus, float &sigmaNeg); void calckoe(float ** WavCoeffs_LL, const cont_params& cp, float ** koeLi, int level, int dir, int W_L, int H_L, float edd, float *maxkoeLi, float **tmC = nullptr); - void softproc2(const LabImage* bufcolorig, const LabImage* bufcolfin, float rad, int bfh, int bfw, double epsilmax, double epsilmin, float thres, int sk, bool multiThread, int flag); - - void Median_Denoise(float **src, float **dst, int width, int height, Median medianType, int iterations, int numThreads, float **buffer = nullptr); void Median_Denoise(float **src, float **dst, float upperBound, int width, int height, Median medianType, int iterations, int numThreads, float **buffer = nullptr); void RGB_denoise(int kall, Imagefloat * src, Imagefloat * dst, Imagefloat * calclum, float * ch_M, float *max_r, float *max_b, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, const NoiseCurve & noiseLCurve, const NoiseCurve & noiseCCurve, float &nresi, float &highresi); diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index f67e82c77..445cfdd06 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -164,7 +164,7 @@ struct cont_params { int wavNestedLevels = 1; -void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const Wavblcurve & wavblcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, const LUTf &wavclCurve, int skip) +void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const Wavblcurve & wavblcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, const LUTf &wavclCurve, int skip) { @@ -540,11 +540,6 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const levwav = rtengine::min(maxlevelcrop, levwav); - // determine number of levels to process. - // for(levwav=rtengine::min(maxlevelcrop,levwav);levwav>0;levwav--) - // if(cp.mul[levwav-1]!=0.f || cp.curv) - // if(cp.mul[levwav-1]!=0.f) - // break; // I suppress this fonctionality ==> crash for level < 3 if (levwav < 1) { return; // nothing to do @@ -740,7 +735,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } #ifdef _OPENMP - #pragma omp parallel for num_threads(wavNestedLevels) if(wavNestedLevels>1) + #pragma omp parallel for num_threads(wavNestedLevels) if (wavNestedLevels>1) #endif for (int i = tiletop; i < tilebottom; i++) { @@ -799,7 +794,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } #ifdef _OPENMP - #pragma omp parallel for num_threads(wavNestedLevels) if(wavNestedLevels>1) + #pragma omp parallel for num_threads(wavNestedLevels) if (wavNestedLevels>1) #endif for (int i = 1; i < hei - 1; i++) { @@ -901,13 +896,13 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if (levwavL > 0) { const std::unique_ptr Ldecomp(new wavelet_decomposition(labco->data, labco->W, labco->H, levwavL, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); - float madL[10][3]; if (!Ldecomp->memoryAllocationFailed) { + float madL[10][3]; // float madL[8][3]; #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic) collapse(2) num_threads(wavNestedLevels) if(wavNestedLevels>1) + #pragma omp parallel for schedule(dynamic) collapse(2) num_threads(wavNestedLevels) if (wavNestedLevels>1) #endif for (int lvl = 0; lvl < levwavL; lvl++) { @@ -1297,7 +1292,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const const std::unique_ptr adecomp(new wavelet_decomposition(labco->data + datalen, labco->W, labco->H, levwava, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!adecomp->memoryAllocationFailed) { - if (cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.f)) { + if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) { WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); } @@ -1331,7 +1326,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavb, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!bdecomp->memoryAllocationFailed) { - if (cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.f)) { + if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) { WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); } @@ -1361,18 +1356,18 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavab, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!adecomp->memoryAllocationFailed && !bdecomp->memoryAllocationFailed) { - if (cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.f)) { + if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) { WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); } Evaluate2(*adecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); - WaveletcontAllAB(labco, varhue, varchro, *adecomp, wavblcurve, waOpacityCurveW, cp, true, skip, meanab, sigmaab); + WaveletcontAllAB(labco, varhue, varchro, *adecomp, wavblcurve, waOpacityCurveW, cp, true, skip, meanab, sigmaab); WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); - if (cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.f)) { + if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) { WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab); WaveletAandBAllAB(*adecomp, *bdecomp, cp, hhCurve, hhutili); } @@ -1434,7 +1429,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const bool highlight = params->toneCurve.hrenabled; #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) num_threads(wavNestedLevels) if(wavNestedLevels>1) + #pragma omp parallel for schedule(dynamic,16) num_threads(wavNestedLevels) if (wavNestedLevels>1) #endif for (int i = tiletop; i < tilebottom; i++) { @@ -1661,7 +1656,7 @@ void ImProcFunctions::Aver(float * RESTRICT DataList, int datalen, float &averag max = 0.f; min = RT_INFINITY_F; #ifdef _OPENMP - #pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1) + #pragma omp parallel num_threads(wavNestedLevels) if (wavNestedLevels>1) #endif { float lmax = 0.f, lmin = 0.f; @@ -1712,7 +1707,7 @@ void ImProcFunctions::Sigma(float * RESTRICT DataList, int datalen, float avera float thres = 32.7f;//different fom zero to take into account only data large enough 32.7 = 0.1 in range 0..100 #ifdef _OPENMP - #pragma omp parallel for reduction(+:variP,variN,countP,countN) num_threads(wavNestedLevels) if(wavNestedLevels>1) + #pragma omp parallel for reduction(+:variP,variN,countP,countN) num_threads(wavNestedLevels) if (wavNestedLevels>1) #endif for (int i = 0; i < datalen; i++) { @@ -1819,7 +1814,7 @@ void ImProcFunctions::Eval2(float ** WavCoeffs_L, int level, float AvL, AvN, SL, SN, maxLP, maxLN; for (int dir = 1; dir < 4; dir++) { - Aver(WavCoeffs_L[dir], W_L * H_L, avLP[dir], avLN[dir], maxL[dir], minL[dir]); + Aver(WavCoeffs_L[dir], W_L * H_L, avLP[dir], avLN[dir], maxL[dir], minL[dir]); Sigma(WavCoeffs_L[dir], W_L * H_L, avLP[dir], avLN[dir], sigP[dir], sigN[dir]); } @@ -1956,7 +1951,7 @@ void ImProcFunctions::ContrastResid(float * WavCoeffs_L0, struct cont_params &cp -void ImProcFunctions::EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params& cp, int W_L, int H_L, float max0, float min0) +void ImProcFunctions::EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params& cp, int W_L, int H_L, float max0, float min0) { @@ -2041,7 +2036,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * if (contrast != 0.f || (cp.tonemap && cp.resena)) { // contrast = 0.f means that all will be multiplied by 1.f, so we can skip this step #ifdef _OPENMP - #pragma omp parallel for reduction(+:avedbl) num_threads(wavNestedLevels) if(wavNestedLevels>1) + #pragma omp parallel for reduction(+:avedbl) num_threads(wavNestedLevels) if (wavNestedLevels>1) #endif for (int i = 0; i < W_L * H_L; i++) { @@ -2049,7 +2044,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * } #ifdef _OPENMP - #pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1) + #pragma omp parallel num_threads(wavNestedLevels) if (wavNestedLevels>1) #endif { float lminL = FLT_MAX; @@ -2134,7 +2129,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * #ifdef _OPENMP - #pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1) + #pragma omp parallel num_threads(wavNestedLevels) if (wavNestedLevels>1) #endif { if (contrast != 0.f && cp.resena && max0 > 0.f) { // contrast = 0.f means that all will be multiplied by 1.f, so we can skip this step @@ -2209,13 +2204,13 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * float LL100 = LL / 327.68f; float tran = 5.f;//transition //shadow - float alp = 3.f; //increase contrast sahdow in lowlights between 1 and ?? if (cp.th > (100.f - tran)) { tran = 100.f - cp.th; } if (LL100 < cp.th) { + constexpr float alp = 3.f; //increase contrast sahdow in lowlights between 1 and ?? float aalp = (1.f - alp) / cp.th; //no changes for LL100 = cp.th float kk = aalp * LL100 + alp; WavCoeffs_L0[i] *= (1.f + kk * cp.conres / 200.f); @@ -2245,10 +2240,10 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * //Blur luma if (cp.blurres != 0.f && cp.resena) { int minWL = min(W_L, H_L); - float k = 0.5f; //printf("skip=%i WL=%i HL=%i min=%i\n", skip, W_L, H_L, minWL); if (minWL > 140) { //disabled if too low windows + constexpr float k = 0.5f; float rad = k * cp.blurres / skip; float * bef = new float[W_L * H_L]; float * aft = new float[W_L * H_L]; @@ -2273,7 +2268,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * n0 = n1 = n2 = n3 = n4 = n5 = n6 = n7 = n8 = n9 = n10 = n32 = 0; #ifdef _OPENMP - #pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1) + #pragma omp parallel num_threads(wavNestedLevels) if (wavNestedLevels>1) #endif { //enabled Lipschitz..replace simple by complex edge detection @@ -2374,12 +2369,10 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * //if not no edge or reduction float bet = 1.f; - //if(cp.lip3) {//enhance algorithm if (alph > eddlipinfl && beta < 0.85f * eddlipinfl) { //0.85 arbitrary value ==> eliminate from edge if H V D too different bet = beta; } - //} float AmpLip = 1.f; if (alph > eddlipinfl) { @@ -2390,16 +2383,6 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * kampli = AmpLip / aamp; } - // comparison betwwen pixel and neighbours to do ==> I think 3 dir above is better - /* if(cp.lip3){ - koeLi[lvl*3][i*W_L + j] = (koeLi[lvl*3][i*W_L + j] + koeLi[lvl*3][(i-1)*W_L + j] + koeLi[lvl*3][(i+1)*W_L + j] - + koeLi[lvl*3][i*W_L + j+1] + koeLi[lvl*3][i*W_L + j-1] + koeLi[lvl*3][(i-1)*W_L + j-1] - + koeLi[lvl*3][(i-1)*W_L + j+1] +koeLi[lvl*3][(i+1)*W_L + j-1] +koeLi[lvl*3][(i+1)*W_L + j+1])/9.f; - } - */ - // apply to each direction Wavelet level : horizontal / vertiacle / diagonal - //interm += SQR(koeLi[lvl*3 + dir-1][i*W_L + j]); - interm *= kampli; if (interm < cp.eddetthr / eddlow) { @@ -2439,21 +2422,15 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); - ContAllL(koeLi, maxkoeLi, true, maxlvl, labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili); - //blur level - float klev = 1.f; + ContAllL(koeLi, maxkoeLi, true, maxlvl, labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili); if (wavblcurve && wavcurvecomp && cp.blena) { // printf("Blur level L\n"); float mea[10]; - float effect = cp.bluwav; - float offs = 1.f; + const float effect = cp.bluwav; + constexpr float offs = 1.f; float * beta = new float[Wlvl_L * Hlvl_L]; - for (int co = 0; co < Hlvl_L * Wlvl_L; co++) { - beta[co] = 1.f; - } - calceffect(lvl, mean, sigma, mea, effect, offs); float * bef = new float[Wlvl_L * Hlvl_L]; @@ -2509,8 +2486,9 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * printf("lvl=%i n0=%i n32=%i n1=%i n2=%i n3=%i n4=%i n5=%i n6=%i n7=%i n8=%i n9=%i n10=%i\n", lvl, n0, n0 - n32, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10); } - klev = (wavblcurve[lvl * 55.5f]); + float klev = (wavblcurve[lvl * 55.5f]); + //blur level // klev *= beta * 100.f / skip; klev *= 100.f / skip; boxblur(bef, aft, klev, Wlvl_L, Hlvl_L, false); @@ -2545,7 +2523,7 @@ void ImProcFunctions::WaveletAandBAllAB(const wavelet_decomposition &WaveletCoef float * WavCoeffs_a0 = WaveletCoeffs_a.coeff0; float * WavCoeffs_b0 = WaveletCoeffs_b.coeff0; #ifdef _OPENMP - #pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1) + #pragma omp parallel num_threads(wavNestedLevels) if (wavNestedLevels>1) #endif { #ifdef __SSE2__ @@ -2611,7 +2589,7 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float float * WavCoeffs_ab0 = WaveletCoeffs_ab.coeff0; #ifdef _OPENMP - #pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1) + #pragma omp parallel num_threads(wavNestedLevels) if (wavNestedLevels>1) #endif { if (cp.chrores != 0.f && cp.resena) { // cp.chrores == 0.f means all will be multiplied by 1.f, so we can skip the processing of residual @@ -2646,20 +2624,6 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float if ((modhue > cp.t_ry || modhue < cp.t_ly)) { scale = (100.f + cp.sky) / 100.1f; } - - /* else if((modhue >= cp.t_ry && modhue < cp.b_ry)) { - scale=(100.f+cp.sky)/100.1f; - float ar=(scale-1.f)/(cp.t_ry- cp.b_ry); - float br=scale-cp.t_ry*ar; - scale=ar*modhue+br; - } - else if((modhue > cp.b_ly && modhue < cp.t_ly)) { - scale=(100.f+cp.sky)/100.1f; - float al=(scale-1.f)/(-cp.b_ly + cp.t_ly); - float bl=scale-cp.t_ly*al; - scale=al*modhue+bl; - } - */ } WavCoeffs_ab0[i] *= (1.f + cp.chrores * (scale) / 100.f); @@ -2727,10 +2691,10 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float //Blur chroma if (cp.blurcres != 0.f && cp.resena) { int minWL = min(W_L, H_L); - float k = 0.5f; //printf("skip=%i WL=%i HL=%i min=%i\n", skip, W_L, H_L, minWL); if (minWL > 140) { //disabled if too low windows + constexpr float k = 0.5f; float rad = k * cp.blurcres / skip; float * bef = new float[W_L * H_L]; float * aft = new float[W_L * H_L]; @@ -2772,7 +2736,7 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float int Hlvl_ab = WaveletCoeffs_ab.level_H(lvl); float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); - ContAllAB(labco, maxlvl, varhue, varchrom, WavCoeffs_ab, WavCoeffs_ab0, lvl, dir, waOpacityCurveW, cp, Wlvl_ab, Hlvl_ab, useChannelA, meanab, sigmaab); + ContAllAB(labco, maxlvl, varhue, varchrom, WavCoeffs_ab, WavCoeffs_ab0, lvl, dir, waOpacityCurveW, cp, Wlvl_ab, Hlvl_ab, useChannelA, meanab, sigmaab); if (wavblcurve && wavcurvecomp && cp.blena && cp.chrwav > 0.f) { @@ -2859,8 +2823,8 @@ void ImProcFunctions::calckoe(float ** WavCoeffs_LL, const cont_params& cp, floa // I calculate coefficients with r size matrix 3x3 r=1 ; 5x5 r=2; 7x7 r=3 /* float k[2*r][2*r]; - for(int i=1;i<=(2*r+1);i++) { - for(int j=1;j<=(2*r+1);j++) { + for (int i=1;i<=(2*r+1);i++) { + for (int j=1;j<=(2*r+1);j++) { k[i][j]=(1.f/6.283*sigma*sigma)*exp(-SQR(i-r-1)+SQR(j-r-1)/2.f*SQR(sigma)); } } @@ -2908,9 +2872,7 @@ void ImProcFunctions::calckoe(float ** WavCoeffs_LL, const cont_params& cp, floa else if (cp.eddetthr >= 75.f) { borderL = 2; - //if(cp.lip3 && level > 1) { if (level > 1) { // do not activate 5x5 if level 0 or 1 - for (int i = 2; i < H_L - 2; i++) { for (int j = 2; j < W_L - 2; j++) { // Gaussian 1.1 @@ -2958,21 +2920,6 @@ void ImProcFunctions::calckoe(float ** WavCoeffs_LL, const cont_params& cp, floa } - - /* - // I suppress these 2 convolutions ==> lees good results==> probably because structure data different and also I compare to original value which have + and - - for(int i = borderL; i < H_L-borderL; i++ ) {//[-1 0 1] x==>j - for(int j = borderL; j < W_L-borderL; j++) { - tmC[i][j]=- WavCoeffs_LL[dir][(i)*W_L + j-1] + WavCoeffs_LL[dir][(i)*W_L + j+1]; - } - } - for(int i = borderL; i < H_L-borderL; i++ ) {//[1 0 -1] y==>i - for(int j = borderL; j < W_L-borderL; j++) { - tmC[i][j]= - WavCoeffs_LL[dir][(i-1)*W_L + j] + WavCoeffs_LL[dir][(i+1)*W_L + j]; - } - } - */ - float thr = 40.f; //avoid artifact eg. noise...to test float thr2 = 1.5f * edd; //edd can be modified in option ed_detect thr2 += cp.eddet / 30.f; //to test @@ -2988,9 +2935,6 @@ void ImProcFunctions::calckoe(float ** WavCoeffs_LL, const cont_params& cp, floa for (int j = borderL; j < W_L - borderL; j++) { // my own algo : probably a little false, but simpler as Lipschitz ! // Thr2 = maximum of the function ==> Lipsitch says = probably edge -// float temp = WavCoeffs_LL[dir][i*W_L + j]; -// if(temp>=0.f && temp < thr) temp = thr; -// if(temp < 0.f && temp > -thr) temp = -thr; float temp = rtengine::max(std::fabs(WavCoeffs_LL[dir][i * W_L + j]), thr); koeLi[level * 3 + dir - 1][i * W_L + j] = rtengine::min(thr2, std::fabs(tmC[i][j] / temp)); // limit maxi @@ -3022,7 +2966,7 @@ void ImProcFunctions::finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0, float amean = 0.5f / mean[level]; #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic, W_L * 16) num_threads(wavNestedLevels) if(wavNestedLevels>1) + #pragma omp parallel for schedule(dynamic, W_L * 16) num_threads(wavNestedLevels) if (wavNestedLevels>1) #endif for (int i = 0; i < W_L * H_L; i++) { @@ -3186,9 +3130,7 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz constexpr float aedstr = (eddstrength - 1.f) / 90.f; constexpr float bedstr = 1.f - 10.f * aedstr; - float mea[10]; - // float beta = 1.f; - float * beta = new float[W_L * H_L]; + std::unique_ptr beta(new float[W_L * H_L]); for (int co = 0; co < H_L * W_L; co++) { beta[co] = 1.f; @@ -3197,6 +3139,7 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz if (cp.eff < 2.5f) { float effect = cp.eff; float offs = 1.f; + float mea[10]; calceffect(level, mean, sigma, mea, effect, offs); @@ -3388,7 +3331,7 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz float edgePrecalc = 1.f + refin; //estimate edge "pseudo variance" if (cp.EDmet == 2 && MaxP[level] > 0.f) { //curve - // if(exa) {//curve + // if (exa) {//curve float insigma = 0.666f; //SD float logmax = log(MaxP[level]); //log Max float rapX = (mean[level] + sigma[level]) / MaxP[level]; //rapport between sD / max @@ -3608,8 +3551,9 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz if (!lipschitz) { delete [] koe; } - - delete[] beta; + if (!(cp.bam && cp.finena)) { + beta.reset(); + } } @@ -3649,7 +3593,7 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz const float lowthr = params->wavelet.lowthr; float mea[10]; float effect = cp.sigm; - float beta; + float lbeta; calceffect(level, mean, sigma, mea, effect, offs); @@ -3664,34 +3608,34 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz float kLlev = 1.f; if (cpMul < 0.f) { - beta = 1.f; // disabled for negatives values "less contrast" + lbeta = 1.f; // disabled for negatives values "less contrast" } else { float WavCL = std::fabs(WavCoeffs_L[dir][i]); //reduction amplification: max action between mean / 2 and mean + sigma // arbitrary coefficient, we can add a slider !! if (WavCL < mea[0]) { - beta = 0.4f * red0;//preserve very low contrast (sky...) + lbeta = 0.4f * red0;//preserve very low contrast (sky...) } else if (WavCL < mea[1]) { - beta = 0.5f * red1; + lbeta = 0.5f * red1; } else if (WavCL < mea[2]) { - beta = 0.7f * red2; + lbeta = 0.7f * red2; } else if (WavCL < mea[3]) { - beta = 1.f; //standard + lbeta = 1.f; //standard } else if (WavCL < mea[4]) { - beta = 1.f; + lbeta = 1.f; } else if (WavCL < mea[5]) { - beta = 0.8f; //+sigma + lbeta = 0.8f; //+sigma } else if (WavCL < mea[6]) { - beta = 0.6f; + lbeta = 0.6f; } else if (WavCL < mea[7]) { - beta = 0.4f; + lbeta = 0.4f; } else if (WavCL < mea[8]) { - beta = 0.2f; // + 2 sigma + lbeta = 0.2f; // + 2 sigma } else if (WavCL < mea[9]) { - beta = 0.1f; + lbeta = 0.1f; } else { - beta = 0.0f; + lbeta = 0.0f; } } @@ -3751,7 +3695,7 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz //linear transition HL float diagacc = 1.f; - float alpha = (1024.f + 15.f * (float) cpMul * scale * scale2 * beta * diagacc) / 1024.f ; + float alpha = (1024.f + 15.f * (float) cpMul * scale * scale2 * lbeta * diagacc) / 1024.f ; if (cp.HSmet && cp.contena) { float aaal = (1.f - alpha) / ((cp.b_lhl - cp.t_lhl) * kH[level]); @@ -3801,18 +3745,12 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz } if (cp.bam && cp.finena) { - float effect = cp.sigmadir; - float offs = 1.f; + const float effect = cp.sigmadir; + constexpr float offs = 1.f; float mea[10]; - float * beta = new float[W_L * H_L]; - - for (int co = 0; co < H_L * W_L; co++) { - beta[co] = 1.f; - } calceffect(level, mean, sigma, mea, effect, offs); - for (int co = 0; co < H_L * W_L; co++) { float WavCL = std::fabs(WavCoeffs_L[dir][co]); @@ -3841,12 +3779,7 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz } } - if (cp.opaW && cp.BAmet == 2) { - - - - int iteration = cp.ite; int itplus = 7 + iteration; int itmoins = 7 - iteration; @@ -3857,7 +3790,7 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz it = itmoins; } else if (level == med) { it = 7; - } else { /*if(level > med)*/ + } else { /*if (level > med)*/ it = itplus; } @@ -3865,8 +3798,8 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz //float bal = cp.balan;//-100 +100 float kba = 1.f; - // if(dir <3) kba= 1.f + bal/600.f; - // if(dir==3) kba = 1.f - bal/300.f; + // if (dir <3) kba= 1.f + bal/600.f; + // if (dir==3) kba = 1.f - bal/300.f; for (int i = 0; i < W_L * H_L; i++) { int ii = i / W_L; int jj = i - ii * W_L; @@ -3898,7 +3831,7 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz it = itmoins; } else if (level == med) { it = 7; - } else { /*if(level > med)*/ + } else { /*if (level > med)*/ it = itplus; } @@ -3906,8 +3839,8 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz float bal = cp.balan;//-100 +100 float kba = 1.f; - // if(dir <3) kba= 1.f + bal/600.f; - // if(dir==3) kba = 1.f - bal/300.f; + // if (dir <3) kba= 1.f + bal/600.f; + // if (dir==3) kba = 1.f - bal/300.f; for (int i = 0; i < W_L * H_L; i++) { int ii = i / W_L; int jj = i - ii * W_L; @@ -3945,8 +3878,6 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz } } } - - delete[] beta; } // to see each level of wavelet ...level from 0 to 8 @@ -3970,9 +3901,8 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f float mea[10]; float effect = cp.sigmacol; - float betaab = 1.f; + float betaab; float offs = 1.f; - float alphaC = 1.f; calceffect(level, meanab, sigmaab, mea, effect, offs); @@ -4022,7 +3952,7 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f } - alphaC = (1024.f + 15.f * cpMul * cpChrom * betaab * scale / 50.f) / 1024.f ; + const float alphaC = (1024.f + 15.f * cpMul * cpChrom * betaab * scale / 50.f) / 1024.f ; WavCoeffs_ab[dir][i] *= alphaC; } @@ -4032,7 +3962,7 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f float cpMulC = cp.mulC[level]; - // if( (cp.curv || cp.CHSLmet==1) && cp.CHmet!=2 && level < 9 && cpMulC != 0.f) { // cpMulC == 0.f means all will be multiplied by 1.f, so we can skip + // if ( (cp.curv || cp.CHSLmet==1) && cp.CHmet!=2 && level < 9 && cpMulC != 0.f) { // cpMulC == 0.f means all will be multiplied by 1.f, so we can skip if (cp.CHmet != 2 && level < 9 && cpMulC != 0.f && cp.chromena) { // cpMulC == 0.f means all will be multiplied by 1.f, so we can skip const float skinprot = params->wavelet.skinprotect; const float skinprotneg = -skinprot; @@ -4042,7 +3972,7 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f float mea[10]; float effect = cp.sigmacol; - float betaab = 0.f; + float betaab; float offs = 1.f; calceffect(level, meanab, sigmaab, mea, effect, offs); @@ -4161,7 +4091,7 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f if ((useOpacity && level < 9 && mulOpacity != 0.f) && cp.toningena) { //toning float mea[10]; float effect = cp.sigmaton; - float betaab = 0.f; + float betaab; float offs = 1.f; float protec = 0.01f * (100.f - cp.protab); float aref1 = cp.a_high; @@ -4283,7 +4213,7 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f it = itmoins; } else if (level == med) { it = 7; - } else { /*if(level > med)*/ + } else { /*if (level > med)*/ it = itplus; } @@ -4291,8 +4221,8 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f //float bal = cp.balan;//-100 +100 float kba = 1.f; - // if(dir <3) kba= 1.f + bal/600.f; - // if(dir==3) kba = 1.f - bal/300.f; + // if (dir <3) kba= 1.f + bal/600.f; + // if (dir==3) kba = 1.f - bal/300.f; for (int i = 0; i < W_ab * H_ab; i++) { int ii = i / W_ab; int jj = i - ii * W_ab; @@ -4324,7 +4254,7 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f it = itmoins; } else if (level == med) { it = 7; - } else { /*if(level > med)*/ + } else { /*if (level > med)*/ it = itplus; } @@ -4332,8 +4262,8 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f float bal = cp.balan;//-100 +100 float kba = 1.f; - // if(dir <3) kba= 1.f + bal/600.f; - // if(dir==3) kba = 1.f - bal/300.f; + // if (dir <3) kba= 1.f + bal/600.f; + // if (dir==3) kba = 1.f - bal/300.f; for (int i = 0; i < W_ab * H_ab; i++) { int ii = i / W_ab; int jj = i - ii * W_ab; @@ -4477,191 +4407,4 @@ void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, f } } -void ImProcFunctions::softproc2(const LabImage* bufcolorig, const LabImage* bufcolfin, float rad, int bfh, int bfw, double epsilmax, double epsilmin, float thres, int sk, bool multiThread, int flag) -{ - if (flag == 0) { - if (rad > 0.f) { - array2D ble(bfw, bfh); - array2D guid(bfw, bfh); - Imagefloat *tmpImage = nullptr; - tmpImage = new Imagefloat(bfw, bfh); - -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int ir = 0; ir < bfh; ir++) - for (int jr = 0; jr < bfw; jr++) { - - float X, Y, Z; - float L = bufcolorig->L[ir][jr]; - float a = bufcolorig->a[ir][jr]; - float b = bufcolorig->b[ir][jr]; - Color::Lab2XYZ(L, a, b, X, Y, Z); - - guid[ir][jr] = Y / 32768.f; - float La = bufcolfin->L[ir][jr]; - float aa = bufcolfin->a[ir][jr]; - float ba = bufcolfin->b[ir][jr]; - Color::Lab2XYZ(La, aa, ba, X, Y, Z); - tmpImage->r(ir, jr) = X; - tmpImage->g(ir, jr) = Y; - tmpImage->b(ir, jr) = Z; - - ble[ir][jr] = Y / 32768.f; - } - - double aepsil = (epsilmax - epsilmin) / 90.f; - double bepsil = epsilmax - 100.f * aepsil; - double epsil = aepsil * 0.1 * rad + bepsil; - - float blur = 10.f / sk * (thres + 0.8f * rad); - rtengine::guidedFilter(guid, ble, ble, blur, epsil, multiThread, 4); - - - -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int ir = 0; ir < bfh; ir++) - for (int jr = 0; jr < bfw; jr++) { - float X = tmpImage->r(ir, jr); - float Y = 32768.f * ble[ir][jr]; - float Z = tmpImage->b(ir, jr); - float L, a, b; - Color::XYZ2Lab(X, Y, Z, L, a, b); - bufcolfin->L[ir][jr] = L; - } - - delete tmpImage; - } - } else if (flag == 1) { - if (rad > 0.f) { - array2D ble(bfw, bfh); - array2D blechro(bfw, bfh); - array2D hue(bfw, bfh); - array2D guid(bfw, bfh); - -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int ir = 0; ir < bfh; ir++) - for (int jr = 0; jr < bfw; jr++) { -// hue[ir][jr] = xatan2f(bufcolfin->b[ir][jr], bufcolfin->a[ir][jr]); -// float chromah = sqrt(SQR(bufcolfin->b[ir][jr]) + SQR(bufcolfin->a[ir][jr])); - - ble[ir][jr] = (bufcolfin->L[ir][jr]) / 32768.f; -// blechro[ir][jr] = chromah / 32768.f; - guid[ir][jr] = bufcolorig->L[ir][jr] / 32768.f; - } - - double aepsil = (epsilmax - epsilmin) / 90.f; - double bepsil = epsilmax - 100.f * aepsil; - double epsil = aepsil * 0.1 * rad + bepsil; - - if (rad != 0.f) { - float blur = rad; - blur = blur < 0.f ? -1.f / blur : 1.f + blur; - // int r1 = max(int(4 / sk * blur + 0.5), 1); - int r2 = max(int(25 / sk * blur + 0.5), 1); - - if (rad < 0.f) { - epsil = 0.0001; - } - - rtengine::guidedFilter(guid, ble, ble, r2, epsil, multiThread); -// rtengine::guidedFilter(guid, blechro, blechro, r1, 0.5 * epsil, multiThread); - } - - - -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int ir = 0; ir < bfh; ir++) - for (int jr = 0; jr < bfw; jr++) { - // float2 sincosval = xsincosf(hue[ir][jr]); - - bufcolfin->L[ir][jr] = 32768.f * ble[ir][jr]; - // bufcolfin->a[ir][jr] = 32768.f * sincosval.y * blechro[ir][jr]; - // bufcolfin->b[ir][jr] = 32768.f * sincosval.x * blechro[ir][jr]; - } - } - - } -} - - -void ImProcFunctions::Compresslevels2(float **Source, int W_L, int H_L, float compression, float detailattenuator, float thres, float mean, float maxp, float meanN, float maxN, float madL) -{ - //J.Desmis 12-2019 - - float exponent; - - if (detailattenuator > 0.f && detailattenuator < 0.05f) { - float betemp = expf(-(2.f - detailattenuator + 0.693147f)) - 1.f; //0.69315 = log(2) - exponent = 1.2f * xlogf(-betemp); - exponent /= 20.f; - } else if (detailattenuator >= 0.05f && detailattenuator < 0.25f) { - float betemp = expf(-(2.f - detailattenuator + 0.693147f)) - 1.f; - exponent = 1.2f * xlogf(-betemp); - exponent /= (-75.f * detailattenuator + 23.75f); - } else if (detailattenuator >= 0.25f) { - float betemp = expf(-(2.f - detailattenuator + 0.693147f)) - 1.f; - exponent = 1.2f * xlogf(-betemp); - exponent /= (-2.f * detailattenuator + 5.5f); - } else { - exponent = (compression - 1.0f) / 20.f; - } - - exponent += 1.f; - - - float ap = (thres - 1.f) / (maxp - mean); - float bp = 1.f - ap * mean; - - float a0 = (1.33f * thres - 1.f) / (1.f - mean); - float b0 = 1.f - a0 * mean; - - float apn = (thres - 1.f) / (maxN - meanN); - float bpn = 1.f - apn * meanN; - - float a0n = (1.33f * thres - 1.f) / (1.f - meanN); - float b0n = 1.f - a0n * meanN; - - -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int y = 0; y < H_L; y++) { - for (int x = 0; x < W_L; x++) { - float expone = 1.f; - - if (Source[y][x] >= 0.f) { - - if (Source[y][x] > mean) { - expone = 1.f + (exponent - 1.f) * (ap * Source[y][x] + bp); - } else { - expone = 1.f + (exponent - 1.f) * (a0 * Source[y][x] + b0); - } - - Source[y][x] = xexpf(xlogf(Source[y][x] + 0.05f * madL) * expone); - } else if (Source[y][x] < 0.f) { - if (-Source[y][x] > mean) { - expone = 1.f + (exponent - 1.f) * (apn * -Source[y][x] + bpn); - } else { - expone = 1.f + (exponent - 1.f) * (a0n * -Source[y][x] + b0n); - } - - Source[y][x] = -xexpf(xlogf(-Source[y][x] + 0.05f * madL) * expone); - } - } - } - -} - } From e25f5aa455198a7bbaa89bb33170f74e80c11af5 Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 12 May 2020 09:11:16 +0200 Subject: [PATCH 19/28] Rebuild wavtm with curve finerCoraser - language - various chnages to denoise --- rtdata/languages/default | 32 ++++++----- rtengine/curves.cc | 37 ++++++++++++ rtengine/curves.h | 26 +++++++++ rtengine/dcrop.cc | 8 ++- rtengine/improccoordinator.cc | 9 ++- rtengine/improccoordinator.h | 1 + rtengine/improcfun.h | 14 +++-- rtengine/ipwavelet.cc | 103 +++++++++++++++++++++++----------- rtengine/procparams.cc | 26 ++++++++- rtengine/procparams.h | 7 ++- rtengine/simpleprocess.cc | 10 +++- rtgui/paramsedited.cc | 6 ++ rtgui/paramsedited.h | 1 + rtgui/wavelet.cc | 44 ++++++++++++--- rtgui/wavelet.h | 3 + 15 files changed, 255 insertions(+), 72 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 5f8906b3d..69b7449e3 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -567,10 +567,10 @@ HISTORY_MSG_314;W - Gamut - Reduce artifacts HISTORY_MSG_315;W - Residual - Contrast HISTORY_MSG_316;W - Gamut - Skin tar/prot HISTORY_MSG_317;W - Gamut - Skin hue -HISTORY_MSG_318;W - Contrast - Highlight levels -HISTORY_MSG_319;W - Contrast - Highlight range -HISTORY_MSG_320;W - Contrast - Shadow range -HISTORY_MSG_321;W - Contrast - Shadow levels +HISTORY_MSG_318;W - Contrast - Fine levels +HISTORY_MSG_319;W - Contrast - Fine range +HISTORY_MSG_320;W - Contrast - Coarse range +HISTORY_MSG_321;W - Contrast - Coarse levels HISTORY_MSG_322;W - Gamut - Avoid color shift HISTORY_MSG_323;W - ES - Local contrast HISTORY_MSG_324;W - Chroma - Pastel @@ -2193,6 +2193,7 @@ TP_WAVELET_CONTEDIT;'After' contrast curve TP_WAVELET_CONTFRAME;Contrast - Compression TP_WAVELET_CONTR;Gamut TP_WAVELET_CONTRA;Contrast +TP_WAVELET_CONTRASTEDIT;Finer - Coarser levels TP_WAVELET_CONTRAST_MINUS;Contrast - TP_WAVELET_CONTRAST_PLUS;Contrast + TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. @@ -2240,9 +2241,10 @@ TP_WAVELET_EDVAL;Strength TP_WAVELET_FINAL;Final Touchup TP_WAVELET_FINCFRAME;Final Local Contrast TP_WAVELET_FINEST;Finest -TP_WAVELET_HIGHLIGHT;Highlight luminance range +TP_WAVELET_HIGHLIGHT;Finer levels luminance range +TP_WAVELET_FINCOAR_TOOLTIP;The left (positive) part of the curve acts on the finer levels (increase).\nThe 2 points on the abscissa represent the respective action limits of finer and coarser levels 5 and 6 (default).\nThe right (negative) part of the curve acts on the coarser levels (increase).\nAvoid moving the left part of the curve with negative values. Avoid moving the right part of the curve with positives values TP_WAVELET_HS1;Whole luminance range -TP_WAVELET_HS2;Shadows/Highlights +TP_WAVELET_HS2;Selective luminance range TP_WAVELET_HUESKIN;Skin hue TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. TP_WAVELET_HUESKY;Sky hue @@ -2252,8 +2254,8 @@ TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight TP_WAVELET_LABEL;Wavelet Levels TP_WAVELET_LARGEST;Coarsest TP_WAVELET_LEVCH;Chroma -TP_WAVELET_LEVDIR_ALL;All levels in all directions -TP_WAVELET_LEVDIR_INF;Below or equal the level +TP_WAVELET_LEVDIR_ALL;All levels, in all directions +TP_WAVELET_LEVDIR_INF;Finer details levels, with selected level TP_WAVELET_LEVDIR_ONE;One level TP_WAVELET_LEVDIR_SUP;Above the level TP_WAVELET_LEVELS;Wavelet levels @@ -2266,7 +2268,7 @@ TP_WAVELET_LEVTWO;Level 3 TP_WAVELET_LEVZERO;Level 1 TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength TP_WAVELET_LIPST;Enhanced algoritm -TP_WAVELET_LOWLIGHT;Shadow luminance range +TP_WAVELET_LOWLIGHT;Coarser levels luminance range TP_WAVELET_LOWTHR_TOOLTIP;Prevents amplification of fine textures and noise TP_WAVELET_MEDGREINF;First level TP_WAVELET_MEDI;Reduce artifacts in blue sky @@ -2277,6 +2279,7 @@ TP_WAVELET_MERGEL;Merge Luma TP_WAVELET_NEUTRAL;Neutral TP_WAVELET_NOIS;Denoise TP_WAVELET_NOISE;Denoise and Refine +TP_WAVELET_NOISE_TOOLTIP;If level 4 luminance denoise superior to 20, mode Agressive is used.\nIf chrominance coarse superior to 20, mode Agressive is used. TP_WAVELET_NPHIGH;High TP_WAVELET_NPLOW;Low TP_WAVELET_NPNONE;None @@ -2318,11 +2321,12 @@ TP_WAVELET_SOFTRAD;Soft Radius TP_WAVELET_STREN;Strength TP_WAVELET_STRENGTH;Strength TP_WAVELET_SUPE;Extra -TP_WAVELET_THR;Shadows threshold -TP_WAVELET_THRESHOLD;Highlight levels -TP_WAVELET_THRESHOLD2;Shadow levels -TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). -TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +TP_WAVELET_THRESHOLD;Finer levels +TP_WAVELET_THRESHOLD2;Coarser levels +//TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +//TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. : All levels from level 1 up to the chosen value will only be affected within the Finer levels luminance range.\nAll other levels will have the whole range of luminances affected, unless the Coarser levels setting limits it.\nThe chosen value in this slider becomes the minimum possible value of the Coarser levels. +TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). : Only levels between the chosen value and level 9/Extra will be affected by the Coarser levels luminance range.\nAll other levels will have the whole range of luminances affected, unless the Finer levels setting limits it.\nThe lower level possible that will be considered by the algorithm is limited by the Finer levels value. TP_WAVELET_THRESWAV;Balance Threshold TP_WAVELET_THRH;Highlights threshold TP_WAVELET_TILESBIG;Tiles diff --git a/rtengine/curves.cc b/rtengine/curves.cc index 14711c730..ebb23e754 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -1278,6 +1278,43 @@ void WavOpacityCurveRG::Set(const std::vector &curvePoints) } +WavOpacityCurveSH::WavOpacityCurveSH() {} + +void WavOpacityCurveSH::Reset() +{ + lutOpacityCurveSH.reset(); +} + +void WavOpacityCurveSH::Set(const Curve &pCurve) +{ + if (pCurve.isIdentity()) { + Reset(); // raise this value if the quality suffers from this number of samples + return; + } + + lutOpacityCurveSH(501); // raise this value if the quality suffers from this number of samples + + for (int i = 0; i < 501; i++) { + lutOpacityCurveSH[i] = pCurve.getVal(double(i) / 500.); + } +} + +void WavOpacityCurveSH::Set(const std::vector &curvePoints) +{ + if (!curvePoints.empty() && curvePoints[0] > FCT_Linear && curvePoints[0] < FCT_Unchanged) { + FlatCurve tcurve(curvePoints, false, CURVES_MIN_POLY_POINTS / 2); + tcurve.setIdentityValue(0.); + Set(tcurve); + } else { + Reset(); + } + +} + + + + + WavOpacityCurveBY::WavOpacityCurveBY() {} void WavOpacityCurveBY::Reset() diff --git a/rtengine/curves.h b/rtengine/curves.h index 03fa3e812..0fb58cc9e 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -673,6 +673,32 @@ public: return lutOpacityCurveRG; } }; + +class WavOpacityCurveSH +{ +private: + LUTf lutOpacityCurveSH; // 0xffff range + void Set(const Curve &pCurve); +public: + virtual ~WavOpacityCurveSH() {}; + WavOpacityCurveSH(); + + void Reset(); + // void Set(const std::vector &curvePoints, bool &opautili); + void Set(const std::vector &curvePoints); + float operator[](float index) const + { + return lutOpacityCurveSH[index]; + } + + operator bool (void) const + { + return lutOpacityCurveSH; + } +}; + + + class WavOpacityCurveBY { private: diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 11bf19edf..f58f2e4c9 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -969,12 +969,13 @@ void Crop::update(int todo) WavCurve wavCLVCurve; Wavblcurve wavblcurve; WavOpacityCurveRG waOpacityCurveRG; + WavOpacityCurveSH waOpacityCurveSH; WavOpacityCurveBY waOpacityCurveBY; WavOpacityCurveW waOpacityCurveW; WavOpacityCurveWL waOpacityCurveWL; LUTf wavclCurve; - params.wavelet.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); + params.wavelet.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); LabImage *unshar = nullptr; Glib::ustring provis; LabImage *provradius = nullptr; @@ -1003,7 +1004,7 @@ void Crop::update(int todo) unshar = new LabImage(labnCrop->W, labnCrop->H); provis = params.wavelet.CLmethod; params.wavelet.CLmethod = "all"; - parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip); + parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip); unshar->CopyFrom(labnCrop); params.wavelet.CLmethod = provis; @@ -1016,7 +1017,8 @@ void Crop::update(int todo) WaveParams.expnoise = false; } - parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip); + // parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip); + parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip); if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { WaveParams.expcontrast = procont; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index f68616b96..f7f8756d2 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -891,7 +891,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if ((params->wavelet.enabled)) { WaveletParams WaveParams = params->wavelet; - WaveParams.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); +// WaveParams.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); + WaveParams.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); int kall = 0; LabImage *unshar = nullptr; Glib::ustring provis; @@ -920,7 +921,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) unshar = new LabImage(pW, pH); provis = params->wavelet.CLmethod; params->wavelet.CLmethod = "all"; - ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); + ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); +// ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); unshar->CopyFrom(nprevl); @@ -934,7 +936,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) WaveParams.expnoise = false; } - ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); +// ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); + ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index e17d88183..e4858c76b 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -141,6 +141,7 @@ protected: WavCurve wavCLVCurve; Wavblcurve wavblcurve; WavOpacityCurveRG waOpacityCurveRG; + WavOpacityCurveSH waOpacityCurveSH; WavOpacityCurveBY waOpacityCurveBY; WavOpacityCurveW waOpacityCurveW; WavOpacityCurveWL waOpacityCurveWL; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index b2df86112..f4a452dcc 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -55,6 +55,7 @@ class ToneCurve; class WavCurve; class Wavblcurve; class WavOpacityCurveBY; +class WavOpacityCurveSH; class WavOpacityCurveRG; class WavOpacityCurveW; class WavOpacityCurveWL; @@ -201,19 +202,22 @@ public: int pitch, int scale, const int luma, const int chroma/*, LUTf & Lcurve, LUTf & abcurve*/); void Tile_calc(int tilesize, int overlap, int kall, int imwidth, int imheight, int &numtiles_W, int &numtiles_H, int &tilewidth, int &tileheight, int &tileWskip, int &tileHskip); - void ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const Wavblcurve & wavblcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, const LUTf &wavclCurve, int skip); +// void ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const Wavblcurve & wavblcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, const LUTf &wavclCurve, int skip); + void ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const Wavblcurve & wavblcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveSH & waOpacityCurveSH, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, const LUTf &wavclCurve, int skip); void WaveletcontAllL(LabImage * lab, float **varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_L, const Wavblcurve & wavblcurve, - struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili); +// struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili); + struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveSH & waOpacityCurveSH, FlatCurve* ChCurve, bool Chutili); void WaveletcontAllLfinal(const wavelet_decomposition &WaveletCoeffs_L, const cont_params &cp, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL); void WaveletcontAllAB(LabImage * lab, float **varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_a, const Wavblcurve & wavblcurve, const WavOpacityCurveW & waOpacityCurveW, struct cont_params &cp, const bool useChannelA, int skip, float *meanab, float *sigmaab); void WaveletAandBAllAB(const wavelet_decomposition &WaveletCoeffs_a, const wavelet_decomposition &WaveletCoeffs_b, const cont_params &cp, FlatCurve* hhcurve, bool hhutili); void ContAllL(float **koeLi, float *maxkoeLi, bool lipschitz, int maxlvl, LabImage * lab, float **varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp, - int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili); - void finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, const cont_params &cp, - int W_L, int H_L, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL); + // int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili); + int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveSH & waOpacityCurveSH, FlatCurve* ChCurve, bool Chutili); + void finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, const cont_params &cp, + int W_L, int H_L, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL); void ContAllAB(LabImage * lab, int maxlvl, float **varhue, float **varchrom, float ** WavCoeffs_a, float * WavCoeffs_a0, int level, int dir, const WavOpacityCurveW & waOpacityCurveW, struct cont_params &cp, int W_ab, int H_ab, const bool useChannelA, float *meanab, float *sigmaab); void Evaluate2(const wavelet_decomposition &WaveletCoeffs_L, diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 445cfdd06..373ea6ef0 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -164,7 +164,8 @@ struct cont_params { int wavNestedLevels = 1; -void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const Wavblcurve & wavblcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, const LUTf &wavclCurve, int skip) +//void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const Wavblcurve & wavblcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, const LUTf &wavclCurve, int skip) +void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const Wavblcurve & wavblcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveSH & waOpacityCurveSH, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, const LUTf &wavclCurve, int skip) { @@ -469,9 +470,12 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.t_lsl = static_cast(params->wavelet.bllev.getTopLeft()); cp.b_rsl = static_cast(params->wavelet.bllev.getBottomRight()); cp.t_rsl = static_cast(params->wavelet.bllev.getTopRight()); - cp.numlevS = params->wavelet.threshold2; - int maxlevS = 9 - cp.numlevH; - cp.numlevS = rtengine::min(cp.numlevS, maxlevS); +// cp.numlevS = params->wavelet.threshold2; +// int maxlevS = 9 - cp.numlevH; +// cp.numlevS = rtengine::min(cp.numlevS, maxlevS); + cp.numlevS = 9 - params->wavelet.threshold2; + int maxlevS = cp.numlevH; + cp.numlevS = rtengine::max(cp.numlevS, maxlevS); //highlight cp.b_lhl = static_cast(params->wavelet.hllev.getBottomLeft()); cp.t_lhl = static_cast(params->wavelet.hllev.getTopLeft()); @@ -958,7 +962,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } if ((cp.lev0n > 0.1f || cp.lev1n > 0.1f || cp.lev2n > 0.1f || cp.lev3n > 0.1f) && cp.noiseena) { - int edge = 4; + int edge = 1; vari[0] = rtengine::max(0.000001f, vari[0]); vari[1] = rtengine::max(0.000001f, vari[1]); vari[2] = rtengine::max(0.000001f, vari[2]); @@ -1001,7 +1005,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } } - if (cp.lev3n < 0.5f) { + if (cp.lev3n < 20.f) { WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, vari, edge, 1); } else { WaveletDenoiseAll_BiShrinkL(*Ldecomp, noisevarlum, madL, vari, edge, 1); @@ -1023,7 +1027,8 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const Chutili = true; } - WaveletcontAllL(labco, varhue, varchro, *Ldecomp, wavblcurve, cp, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili); +// WaveletcontAllL(labco, varhue, varchro, *Ldecomp, wavblcurve, cp, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili); + WaveletcontAllL(labco, varhue, varchro, *Ldecomp, wavblcurve, cp, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, waOpacityCurveSH, ChCurve, Chutili); if (cp.val > 0 || ref || contr || cp.diagcurv) { //edge Evaluate2(*Ldecomp, mean, meanN, sigma, sigmaN, MaxP, MaxN); @@ -1048,16 +1053,16 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const float noiseccr = cp.chromco; if (cp.balchrom > 0.f) { - noisecfr = cp.chromfi * ((100.f + cp.balchrom) / 10.f); - noiseccr = cp.chromco + ((100.f + cp.balchrom) / 10.f); + noisecfr = cp.chromfi + 0.1f * cp.balchrom; + noiseccr = cp.chromco + 0.1f * cp.balchrom; } float noisecfb = cp.chromfi; float noiseccb = cp.chromco; if (cp.balchrom < 0.f) { - noisecfb = cp.chromfi * ((100.f - cp.balchrom) / 10.f); - noiseccb = cp.chromco * ((100.f - cp.balchrom) / 10.f); + noisecfb = cp.chromfi - 0.1f * cp.balchrom; + noiseccb = cp.chromco - 0.1f * cp.balchrom; } @@ -1292,7 +1297,11 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const const std::unique_ptr adecomp(new wavelet_decomposition(labco->data + datalen, labco->W, labco->H, levwava, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!adecomp->memoryAllocationFailed) { - if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) { +// if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) { + if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.chromco < 2.f )) { + WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); + } else if (cp.chromfi > 0.f && cp.chromco >= 2.f){ + WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); } @@ -1326,7 +1335,10 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavb, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!bdecomp->memoryAllocationFailed) { - if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) { +// if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) { + if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.chromco < 2.f )) { + WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); + } else if (cp.chromfi > 0.f && cp.chromco >= 2.f){ WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); } @@ -1356,21 +1368,34 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavab, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!adecomp->memoryAllocationFailed && !bdecomp->memoryAllocationFailed) { - if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) { +// if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) { + if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.chromco < 2.f)) { + WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); + } else if (cp.chromfi > 0.f && cp.chromco >= 2.f){ WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); } Evaluate2(*adecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); WaveletcontAllAB(labco, varhue, varchro, *adecomp, wavblcurve, waOpacityCurveW, cp, true, skip, meanab, sigmaab); - WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); - WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); - Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); + if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.chromco < 2.f)) { + WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); + } else if (cp.chromfi > 0.f && cp.chromco >= 2.f){ + WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); + WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); + } +// WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); +// WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); + Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); +/* if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) { WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab); WaveletAandBAllAB(*adecomp, *bdecomp, cp, hhCurve, hhutili); } + */ + WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab); + WaveletAandBAllAB(*adecomp, *bdecomp, cp, hhCurve, hhutili); adecomp->reconstruct(labco->data + datalen, cp.strength); bdecomp->reconstruct(labco->data + 2 * datalen, cp.strength); @@ -2022,7 +2047,8 @@ void ImProcFunctions::WaveletcontAllLfinal(const wavelet_decomposition &WaveletC void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_L, const Wavblcurve & wavblcurve, - struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili) +// struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili) + struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveSH & waOpacityCurveSH, FlatCurve* ChCurve, bool Chutili) { const int maxlvl = WaveletCoeffs_L.maxlevel(); const int W_L = WaveletCoeffs_L.level_W(0); @@ -2422,7 +2448,8 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); - ContAllL(koeLi, maxkoeLi, true, maxlvl, labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili); +// ContAllL(koeLi, maxkoeLi, true, maxlvl, labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili); + ContAllL(koeLi, maxkoeLi, true, maxlvl, labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, waOpacityCurveSH, ChCurve, Chutili); if (wavblcurve && wavcurvecomp && cp.blena) { // printf("Blur level L\n"); @@ -3106,7 +3133,8 @@ void ImProcFunctions::finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0, } void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz, int maxlvl, LabImage * labco, float ** varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp, - int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili) +// int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili) + int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveSH & waOpacityCurveSH, FlatCurve* ChCurve, bool Chutili) { assert(level >= 0); assert(maxlvl > level); @@ -3605,7 +3633,8 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz float red2 = 0.011f * (110.f - lowthr); for (int i = 0; i < W_L * H_L; i++) { - float kLlev = 1.f; + float kLlevH = 1.f; + float kLlevS = 1.f; if (cpMul < 0.f) { lbeta = 1.f; // disabled for negatives values "less contrast" @@ -3697,7 +3726,8 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz float diagacc = 1.f; float alpha = (1024.f + 15.f * (float) cpMul * scale * scale2 * lbeta * diagacc) / 1024.f ; - if (cp.HSmet && cp.contena) { + // if (cp.HSmet && cp.contena) { + if (cp.HSmet && cp.contena && waOpacityCurveSH) { float aaal = (1.f - alpha) / ((cp.b_lhl - cp.t_lhl) * kH[level]); float bbal = 1.f - aaal * cp.b_lhl * kH[level]; float aaar = (alpha - 1.f) / (cp.t_rhl - cp.b_rhl) * kH[level]; @@ -3708,35 +3738,40 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz float aaarS = (alpha - 1.f) / (cp.t_rsl - cp.b_rsl); float bbbrS = 1.f - cp.b_rsl * aaarS; - if (level <= cp.numlevH) { //in function of levels +// if (level <= cp.numlevH) { //in function of levels + float klevred = 2.f * (waOpacityCurveSH[level * 55.5f] - 0.5f); + if(klevred > 0.f && level <= 6) {// level < 6 to avoid bad use of the curve if user put negative values positives if ((LL100 > cp.t_lhl * kH[level] && LL100 < cp.t_rhl * kH[level])) { - kLlev = alpha; + kLlevH = alpha; } else if ((LL100 > cp.b_lhl * kH[level] && LL100 <= cp.t_lhl * kH[level])) { - kLlev = aaal * LL100 + bbal; + kLlevH = aaal * LL100 + bbal; } else if ((LL100 > cp.t_rhl * kH[level] && LL100 <= cp.b_rhl * kH[level])) { - kLlev = aaar * LL100 + bbbr; + kLlevH = aaar * LL100 + bbbr; } else { - kLlev = 1.f; + kLlevH = 1.f; } + kLlevH = 1.f + (kLlevH - 1.f) * klevred; } - if (level >= (9 - cp.numlevS)) { + // if (level >= (9 - cp.numlevS)) { + if(klevred < 0.f && level >= 3) {//level > 3 to avoid bad use of the curve if user put positives values negatives if ((LL100 > cp.t_lsl && LL100 < cp.t_rsl)) { - kLlev = alpha; + kLlevS = alpha; } else if ((LL100 > cp.b_lsl && LL100 <= cp.t_lsl)) { - kLlev = aaalS * LL100 + bbalS; + kLlevS = aaalS * LL100 + bbalS; } else if ((LL100 > cp.t_rsl && LL100 <= cp.b_rsl)) { - kLlev = aaarS * LL100 + bbbrS; + kLlevS = aaarS * LL100 + bbbrS; } else { - kLlev = 1.f; + kLlevS = 1.f; } + kLlevS = 1.f - (kLlevS - 1.f) * klevred; } } else { - kLlev = alpha; + kLlevH = kLlevS = alpha; } - WavCoeffs_L[dir][i] *= (kLlev); + WavCoeffs_L[dir][i] *= (kLlevH * kLlevS); } } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index e1765a5f0..4df201503 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2191,6 +2191,25 @@ WaveletParams::WaveletParams() : 0.35, 0.35 }, + opacityCurveSH{ + static_cast(FCT_MinMaxCPoints), + 0.0, + 1., + 0.35, + 0.35, + 0.4, + 0.5, + 0.35, + 0.35, + 0.5, + 0.5, + 0.35, + 0.35, + 1., + 0., + 0.35, + 0.35 + }, opacityCurveBY{ static_cast(FCT_MinMaxCPoints), 0.0, @@ -2322,7 +2341,7 @@ WaveletParams::WaveletParams() : chroma(5), chro(0), threshold(5), - threshold2(4), + threshold2(5), edgedetect(90), edgedetectthr(20), edgedetectthr2(0), @@ -2359,6 +2378,7 @@ bool WaveletParams::operator ==(const WaveletParams& other) const ccwcurve == other.ccwcurve && blcurve == other.blcurve && opacityCurveRG == other.opacityCurveRG + && opacityCurveSH == other.opacityCurveSH && opacityCurveBY == other.opacityCurveBY && opacityCurveW == other.opacityCurveW && opacityCurveWL == other.opacityCurveWL @@ -2492,6 +2512,7 @@ void WaveletParams::getCurves( WavCurve& cCurve, Wavblcurve& tCurve, WavOpacityCurveRG& opacityCurveLUTRG, + WavOpacityCurveSH& opacityCurveLUTSH, WavOpacityCurveBY& opacityCurveLUTBY, WavOpacityCurveW& opacityCurveLUTW, WavOpacityCurveWL& opacityCurveLUTWL @@ -2500,6 +2521,7 @@ void WaveletParams::getCurves( cCurve.Set(this->ccwcurve); tCurve.Set(this->blcurve); opacityCurveLUTRG.Set(this->opacityCurveRG); + opacityCurveLUTSH.Set(this->opacityCurveSH); opacityCurveLUTBY.Set(this->opacityCurveBY); opacityCurveLUTW.Set(this->opacityCurveW); opacityCurveLUTWL.Set(this->opacityCurveWL); @@ -3631,6 +3653,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.pastlev, "Wavelet", "Pastlev", wavelet.pastlev.toVector(), keyFile); saveToKeyfile(!pedited || pedited->wavelet.satlev, "Wavelet", "Satlev", wavelet.satlev.toVector(), keyFile); saveToKeyfile(!pedited || pedited->wavelet.opacityCurveRG, "Wavelet", "OpacityCurveRG", wavelet.opacityCurveRG, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.opacityCurveSH, "Wavelet", "Levalshc", wavelet.opacityCurveSH, keyFile); saveToKeyfile(!pedited || pedited->wavelet.opacityCurveBY, "Wavelet", "OpacityCurveBY", wavelet.opacityCurveBY, keyFile); saveToKeyfile(!pedited || pedited->wavelet.opacityCurveW, "Wavelet", "OpacityCurveW", wavelet.opacityCurveW, keyFile); saveToKeyfile(!pedited || pedited->wavelet.opacityCurveWL, "Wavelet", "OpacityCurveWL", wavelet.opacityCurveWL, keyFile); @@ -4830,6 +4853,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Wavelet", "ContrastCurve", pedited, wavelet.ccwcurve, pedited->wavelet.ccwcurve); assignFromKeyfile(keyFile, "Wavelet", "blcurve", pedited, wavelet.blcurve, pedited->wavelet.blcurve); assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveRG", pedited, wavelet.opacityCurveRG, pedited->wavelet.opacityCurveRG); + assignFromKeyfile(keyFile, "Wavelet", "Levelshc", pedited, wavelet.opacityCurveSH, pedited->wavelet.opacityCurveSH); assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveBY", pedited, wavelet.opacityCurveBY, pedited->wavelet.opacityCurveBY); assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveW", pedited, wavelet.opacityCurveW, pedited->wavelet.opacityCurveW); assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveWL", pedited, wavelet.opacityCurveWL, pedited->wavelet.opacityCurveWL); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 24995525d..8e3ff5b6c 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -42,6 +42,7 @@ class RetinextransmissionCurve; class WavCurve; class Wavblcurve; class WavOpacityCurveBY; +class WavOpacityCurveSH; class WavOpacityCurveRG; class WavOpacityCurveW; class WavOpacityCurveWL; @@ -1187,7 +1188,9 @@ private: struct WaveletParams { std::vector ccwcurve; std::vector blcurve; + std::vector levelshc; std::vector opacityCurveRG; + std::vector opacityCurveSH; std::vector opacityCurveBY; std::vector opacityCurveW; std::vector opacityCurveWL; @@ -1316,8 +1319,8 @@ struct WaveletParams { void getCurves( WavCurve& cCurve, Wavblcurve& tCurve, - WavOpacityCurveRG& - opacityCurveLUTRG, + WavOpacityCurveRG& opacityCurveLUTRG, + WavOpacityCurveSH& opacityCurveLUTSH, WavOpacityCurveBY& opacityCurveLUTBY, WavOpacityCurveW& opacityCurveLUTW, WavOpacityCurveWL& opacityCurveLUTWL diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 14a594ac2..92a3d7f29 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1127,6 +1127,7 @@ private: WavCurve wavCLVCurve; Wavblcurve wavblcurve; WavOpacityCurveRG waOpacityCurveRG; + WavOpacityCurveSH waOpacityCurveSH; WavOpacityCurveBY waOpacityCurveBY; WavOpacityCurveW waOpacityCurveW; WavOpacityCurveWL waOpacityCurveWL; @@ -1149,7 +1150,8 @@ private: provradius->CopyFrom(labView); } - params.wavelet.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); +// params.wavelet.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); + params.wavelet.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); CurveFactory::curveWavContL(wavcontlutili, params.wavelet.wavclCurve, wavclCurve,/* hist16C, dummy,*/ 1); @@ -1157,7 +1159,8 @@ private: unshar = new LabImage(fw, fh); provis = params.wavelet.CLmethod; params.wavelet.CLmethod = "all"; - ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); +// ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); + ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); unshar->CopyFrom(labView); params.wavelet.CLmethod = provis; @@ -1169,7 +1172,8 @@ private: WaveParams.expnoise = false; } - ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); +// ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); + ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { WaveParams.expcontrast = procont; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 85119fe80..b9f7d4791 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -565,6 +565,7 @@ void ParamsEdited::set(bool v) wavelet.level3noise = v; wavelet.ccwcurve = v; wavelet.blcurve = v; + wavelet.opacityCurveSH = v; wavelet.opacityCurveRG = v; wavelet.opacityCurveBY = v; wavelet.opacityCurveW = v; @@ -1187,6 +1188,7 @@ void ParamsEdited::initFrom(const std::vector& wavelet.satlev = wavelet.satlev && p.wavelet.satlev == other.wavelet.satlev; wavelet.ccwcurve = wavelet.ccwcurve && p.wavelet.ccwcurve == other.wavelet.ccwcurve; wavelet.blcurve = wavelet.blcurve && p.wavelet.blcurve == other.wavelet.blcurve; + wavelet.opacityCurveSH = wavelet.opacityCurveSH && p.wavelet.opacityCurveSH == other.wavelet.opacityCurveSH; wavelet.opacityCurveRG = wavelet.opacityCurveRG && p.wavelet.opacityCurveRG == other.wavelet.opacityCurveRG; wavelet.opacityCurveBY = wavelet.opacityCurveBY && p.wavelet.opacityCurveBY == other.wavelet.opacityCurveBY; wavelet.opacityCurveW = wavelet.opacityCurveW && p.wavelet.opacityCurveW == other.wavelet.opacityCurveW; @@ -3189,6 +3191,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.blcurve = mods.wavelet.blcurve; } + if (wavelet.opacityCurveSH) { + toEdit.wavelet.opacityCurveSH = mods.wavelet.opacityCurveSH; + } + if (wavelet.opacityCurveRG) { toEdit.wavelet.opacityCurveRG = mods.wavelet.opacityCurveRG; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 68340309d..6655bbcda 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -577,6 +577,7 @@ struct WaveletParamsEdited { bool level3noise; bool ccwcurve; bool blcurve; + bool opacityCurveSH; bool opacityCurveBY; bool opacityCurveRG; bool opacityCurveW; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 1f4714452..53c7ef90b 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -63,6 +63,7 @@ std::vector makeWholeHueRange() Wavelet::Wavelet() : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), true, true), curveEditorG(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_CONTEDIT"))), + curveEditorC(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_CONTRASTEDIT"))), CCWcurveEditorG(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_CCURVE"))), curveEditorbl(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_BLCURVE"))), curveEditorRES(new CurveEditorGroup(options.lastWaveletCurvesDir)), @@ -131,7 +132,8 @@ Wavelet::Wavelet() : level2noise(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_LEVTWO"), -30., 100., 0., M("TP_WAVELET_STREN"), 1., 0., 100., 0., M("TP_WAVELET_NOIS"), 1., nullptr, false))), level3noise(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_LEVTHRE"), -30., 100., 0., M("TP_WAVELET_STREN"), 1., 0., 100., 0., M("TP_WAVELET_NOIS"), 1., nullptr, false))), threshold(Gtk::manage(new Adjuster(M("TP_WAVELET_THRESHOLD"), 1, 9, 1, 5))), - threshold2(Gtk::manage(new Adjuster(M("TP_WAVELET_THRESHOLD2"), 1, 9, 1, 4))), + // threshold2(Gtk::manage(new Adjuster(M("TP_WAVELET_THRESHOLD2"), 1, 9, 1, 4))), + threshold2(Gtk::manage(new Adjuster(M("TP_WAVELET_THRESHOLD2"), 1, 9, 1, 5))), edgedetect(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGEDETECT"), 0, 100, 1, 90))), edgedetectthr(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGEDETECTTHR"), 0, 100, 1, 20))), edgedetectthr2(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGEDETECTTHR2"), -10, 100, 1, 0))), @@ -224,6 +226,7 @@ Wavelet::Wavelet() : EvWavLabGridValue = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVLABGRID_VALUE"); EvWavrangeab = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_RANGEAB"); EvWavprotab = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_PROTAB"); + EvWavlevelshc = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_LEVELSHC"); labgrid = Gtk::manage(new LabGrid(EvWavLabGridValue, M("TP_WAVELET_LABGRID_VALUES"))); @@ -422,11 +425,25 @@ Wavelet::Wavelet() : threshold2->setAdjusterListener(this); threshold2->set_tooltip_text(M("TP_WAVELET_THRESHOLD2_TOOLTIP")); + const WaveletParams default_params; + + curveEditorC->setCurveListener(this); + curveEditorC->set_tooltip_text(M("TP_WAVELET_FINCOAR_TOOLTIP")); + + + opacityShapeSH = static_cast(curveEditorC->addCurve(CT_Flat, "", nullptr, false, false)); + opacityShapeSH->setIdentityValue(0.); + opacityShapeSH->setResetCurve(FlatCurveType(default_params.opacityCurveSH.at(0)), default_params.opacityCurveSH); + + curveEditorC->curveListComplete(); + curveEditorC->show(); + contrastSHVBox->pack_start(*HSmethod); contrastSHVBox->pack_start(*hllev); - contrastSHVBox->pack_start(*threshold); + // contrastSHVBox->pack_start(*threshold); contrastSHVBox->pack_start(*bllev); - contrastSHVBox->pack_start(*threshold2); +// contrastSHVBox->pack_start(*threshold2); + contrastSHVBox->pack_start(*curveEditorC); Gtk::Frame* const contrastSHFrame = Gtk::manage(new Gtk::Frame(M("TP_WAVELET_APPLYTO"))); contrastSHFrame->add(*contrastSHVBox); levBox->pack_start(*contrastSHFrame); @@ -511,7 +528,7 @@ Wavelet::Wavelet() : opaCurveEditorG->setCurveListener(this); - const WaveletParams default_params; +// const WaveletParams default_params; opacityShapeRG = static_cast(opaCurveEditorG->addCurve(CT_Flat, "", nullptr, false, false)); opacityShapeRG->setIdentityValue(0.); @@ -591,6 +608,7 @@ Wavelet::Wavelet() : chroBox->pack_start(*chromco); chroFrame->add(*chroBox); noiseBox->pack_start(*chroFrame); + noiseBox->set_tooltip_text(M("TP_WAVELET_NOISE_TOOLTIP")); //Clarity @@ -617,13 +635,13 @@ Wavelet::Wavelet() : // Edge Sharpness ToolParamBlock* const edgBox = Gtk::manage(new ToolParamBlock()); - edgeffect->setAdjusterListener(this); - edgBox->pack_start(*edgeffect); - edgeffect->set_tooltip_markup(M("TP_WAVELET_EDEFFECT_TOOLTIP")); edgval->setAdjusterListener(this); edgBox->pack_start(*edgval); + edgeffect->setAdjusterListener(this); + edgBox->pack_start(*edgeffect); + edgeffect->set_tooltip_markup(M("TP_WAVELET_EDEFFECT_TOOLTIP")); edgrad->setAdjusterListener(this); edgBox->pack_start(*edgrad); @@ -1033,6 +1051,7 @@ Wavelet::Wavelet() : opacityShapeWL->setIdentityValue(0.); opacityShapeWL->setResetCurve(FlatCurveType(default_params.opacityCurveWL.at(0)), default_params.opacityCurveWL); opacityShapeWL->setTooltip(M("TP_WAVELET_OPACITYWL_TOOLTIP")); + opacityShapeWL->setBottomBarBgGradient({{0., 0., 0., 0.}, {1., 1., 1., 1.}}); sigmafin->setAdjusterListener(this); // This will add the reset button at the end of the curveType buttons @@ -1130,6 +1149,7 @@ Wavelet::~Wavelet() idle_register.destroy(); delete opaCurveEditorG; + delete curveEditorC; delete opacityCurveEditorG; delete curveEditorbl; delete CCWcurveEditorG; @@ -1359,6 +1379,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) ccshape->setCurve(pp->wavelet.ccwcurve); blshape->setCurve(pp->wavelet.blcurve); opacityShapeRG->setCurve(pp->wavelet.opacityCurveRG); + opacityShapeSH->setCurve(pp->wavelet.opacityCurveSH); opacityShapeBY->setCurve(pp->wavelet.opacityCurveBY); opacityShape->setCurve(pp->wavelet.opacityCurveW); opacityShapeWL->setCurve(pp->wavelet.opacityCurveWL); @@ -1579,6 +1600,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) exptoning->set_inconsistent(!pedited->wavelet.exptoning); expnoise->set_inconsistent(!pedited->wavelet.expnoise); opacityShapeRG->setCurve(pp->wavelet.opacityCurveRG); + opacityShapeSH->setCurve(pp->wavelet.opacityCurveSH); opacityShapeBY->setCurve(pp->wavelet.opacityCurveBY); opacityShape->setCurve(pp->wavelet.opacityCurveW); opacityShapeWL->setCurve(pp->wavelet.opacityCurveWL); @@ -1771,6 +1793,7 @@ void Wavelet::setEditProvider(EditDataProvider *provider) ccshape->setEditProvider(provider); blshape->setEditProvider(provider); opacityShapeRG->setEditProvider(provider); + opacityShapeSH->setEditProvider(provider); opacityShapeBY->setEditProvider(provider); opacityShape->setEditProvider(provider); opacityShapeWL->setEditProvider(provider); @@ -1848,6 +1871,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pp->wavelet.ccwcurve = ccshape->getCurve(); pp->wavelet.blcurve = blshape->getCurve(); pp->wavelet.opacityCurveRG = opacityShapeRG->getCurve(); + pp->wavelet.opacityCurveSH = opacityShapeSH->getCurve(); pp->wavelet.opacityCurveBY = opacityShapeBY->getCurve(); pp->wavelet.opacityCurveW = opacityShape->getCurve(); pp->wavelet.opacityCurveWL = opacityShapeWL->getCurve(); @@ -1976,6 +2000,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.level2noise = level2noise->getEditedState(); pedited->wavelet.level3noise = level3noise->getEditedState(); pedited->wavelet.opacityCurveRG = !opacityShapeRG->isUnChanged(); + pedited->wavelet.opacityCurveSH = !opacityShapeSH->isUnChanged(); pedited->wavelet.opacityCurveBY = !opacityShapeBY->isUnChanged(); pedited->wavelet.opacityCurveW = !opacityShape->isUnChanged(); pedited->wavelet.opacityCurveWL = !opacityShapeWL->isUnChanged(); @@ -2158,6 +2183,8 @@ void Wavelet::curveChanged(CurveEditor* ce) listener->panelChanged(EvWavblshape, M("HISTORY_CUSTOMCURVE")); } else if (ce == opacityShapeRG) { listener->panelChanged(EvWavColor, M("HISTORY_CUSTOMCURVE")); + } else if (ce == opacityShapeSH) { + listener->panelChanged(EvWavlevelshc, M("HISTORY_CUSTOMCURVE")); } else if (ce == opacityShapeBY) { listener->panelChanged(EvWavOpac, M("HISTORY_CUSTOMCURVE")); } else if (ce == opacityShape) { @@ -2465,11 +2492,13 @@ void Wavelet::HSmethodUpdateUI() bllev->hide(); threshold->hide(); threshold2->hide(); + curveEditorC->hide(); } else { //with hllev->show(); bllev->show(); threshold->show(); threshold2->show(); + curveEditorC->show(); } } } @@ -2880,6 +2909,7 @@ void Wavelet::setBatchMode(bool batchMode) Dirmethod->append(M("GENERAL_UNCHANGED")); CCWcurveEditorG->setBatchMode(batchMode); opaCurveEditorG->setBatchMode(batchMode); + curveEditorC->setBatchMode(batchMode); opacityCurveEditorG->setBatchMode(batchMode); opacityCurveEditorW->setBatchMode(batchMode); opacityCurveEditorWL->setBatchMode(batchMode); diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index c9cd3dc4c..c6a0a6b85 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -101,6 +101,7 @@ private: rtengine::ProcEvent EvWavLabGridValue; rtengine::ProcEvent EvWavrangeab; rtengine::ProcEvent EvWavprotab; + rtengine::ProcEvent EvWavlevelshc; LabGrid *labgrid; @@ -164,6 +165,8 @@ private: void enableToggled(MyExpander* expander); CurveEditorGroup* const curveEditorG; + CurveEditorGroup* const curveEditorC; + FlatCurveEditor* opacityShapeSH; CurveEditorGroup* const CCWcurveEditorG; CurveEditorGroup* const curveEditorbl; From c27cd841e412b138b36d010afd5616a1681e5207 Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 12 May 2020 09:20:59 +0200 Subject: [PATCH 20/28] Forgotten label Residual --- rtdata/languages/default | 1 + 1 file changed, 1 insertion(+) diff --git a/rtdata/languages/default b/rtdata/languages/default index 69b7449e3..30d86c097 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2321,6 +2321,7 @@ TP_WAVELET_SOFTRAD;Soft Radius TP_WAVELET_STREN;Strength TP_WAVELET_STRENGTH;Strength TP_WAVELET_SUPE;Extra +TP_WAVELET_THR;Shadows threshold TP_WAVELET_THRESHOLD;Finer levels TP_WAVELET_THRESHOLD2;Coarser levels //TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). From 65f1b4c3d9a976d90f41853b915f79bf98ac2864 Mon Sep 17 00:00:00 2001 From: Benitoite Date: Tue, 12 May 2020 05:17:53 -0700 Subject: [PATCH 21/28] Update macOS packaging for 10.15.4 Several smaller fixes to provide an improved handling of installing/using RT on macOS. * mac: update entitlements for 10.15.4 * mac: fix the CLI. Provides an un-codesigned rawtherapee-cli outside the app bundle for use on the terminal command line, using the app bundle's 3rd-party libraries. * How to install RawTherapee.app and rawtherapee-cli for macOS --- CMakeLists.txt | 9 ++++++++- tools/INSTALL.readme | 3 +++ tools/osx/macosx_bundle.sh | 36 +++++++++++++++++++++++------------- tools/osx/rt.entitlements | 31 ++++++++++++++----------------- 4 files changed, 48 insertions(+), 31 deletions(-) create mode 100644 tools/INSTALL.readme diff --git a/CMakeLists.txt b/CMakeLists.txt index cbddde251..7d66109e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -669,7 +669,14 @@ if(WIN32) elseif(APPLE) set( ABOUT_COMMAND_WITH_ARGS - cmake -DPROJECT_SOURCE_DIR:STRING=${PROJECT_SOURCE_DIR} -P ${PROJECT_SOURCE_DIR}/UpdateInfo.cmake -DSYSTEM:STRING=Apple -DCXX_FLAGS:STRING=${CXX_FLAGS} -DLFLAGS:STRING=${LFLAGS} -DCOMPILER_INFO:STRING=${COMPILER_INFO} -DCACHE_NAME_SUFFIX:STRING=${CACHE_NAME_SUFFIX}) + cmake + -DPROJECT_SOURCE_DIR:STRING=${PROJECT_SOURCE_DIR} + -DCACHE_NAME_SUFFIX:STRING=${CACHE_NAME_SUFFIX} + -P ${PROJECT_SOURCE_DIR}/UpdateInfo.cmake + -DSYSTEM:STRING=Apple + -DCXX_FLAGS:STRING=${CXX_FLAGS} + -DLFLAGS:STRING=${LFLAGS} + -DCOMPILER_INFO:STRING=${COMPILER_INFO}) else() list(APPEND ABOUT_COMMAND_WITH_ARGS -DSYSTEM:STRING=Linux -DCXX_FLAGS:STRING=${CXX_FLAGS} -DLFLAGS:STRING=${LFLAGS} diff --git a/tools/INSTALL.readme b/tools/INSTALL.readme new file mode 100644 index 000000000..a4f19ec3c --- /dev/null +++ b/tools/INSTALL.readme @@ -0,0 +1,3 @@ +To install the RawTherapee application, open the .dmg and drag the RawTherapee app onto the /Applications folder. + +To use the optional rawtherapee-cli command line interface, move rawtherapee-cli into a folder in your $PATH and install the RawTherapee app as above. diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index 9258810c0..bc1a2dc3b 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -236,6 +236,11 @@ ditto {"${LOCAL_PREFIX}/local","${RESOURCES}"}/share/icons/Adwaita/index.theme "${LOCAL_PREFIX}/local/bin/gtk-update-icon-cache" "${RESOURCES}/share/icons/Adwaita" ditto "${LOCAL_PREFIX}/local/share/icons/hicolor" "${RESOURCES}/share/icons/hicolor" +# fix libfreetype install name +for lib in "${LIB}"/*; do + install_name_tool -change libfreetype.6.dylib "${LIB}"/libfreetype.6.dylib "${lib}" +done + # pixbuf loaders & immodules msg "Build GTK3 databases:" "${LOCAL_PREFIX}"/local/bin/gdk-pixbuf-query-loaders "${LIB}"/libpix*.so > "${ETC}"/gtk-3.0/gdk-pixbuf.loaders @@ -259,11 +264,11 @@ ditto "${PROJECT_SOURCE_DIR}/rtdata/fonts" "${ETC}/fonts" ditto "${PROJECT_SOURCE_DATA_DIR}/"{rawtherapee,profile}.icns "${RESOURCES}" ditto "${PROJECT_SOURCE_DATA_DIR}/PkgInfo" "${CONTENTS}" install -m 0644 "${PROJECT_SOURCE_DATA_DIR}/Info.plist.in" "${CONTENTS}/Info.plist" +install -m 0644 "${PROJECT_SOURCE_DATA_DIR}/cliInfo.plist.in" "${LIB}/Info.plist" sed -i "" -e "s|@version@|${PROJECT_FULL_VERSION}| s|@shortVersion@|${PROJECT_VERSION}| s|@arch@|${arch}|" \ "${CONTENTS}/Info.plist" -plutil -convert binary1 "${CONTENTS}/Info.plist" update-mime-database -V "${RESOURCES}/share/mime" msg "Build glib database:" @@ -279,23 +284,25 @@ ModifyInstallNames # fix @rpath in Frameworks msg "Registering @rpath in Frameworks folder." -for frameworklibs in "${LIB}"/*{dylib,so}; do +for frameworklibs in "${LIB}"/*{dylib,so,cli}; do install_name_tool -delete_rpath ${LOCAL_PREFIX}/local/lib "${frameworklibs}" install_name_tool -add_rpath /Applications/"${LIB}" "${frameworklibs}" done install_name_tool -delete_rpath RawTherapee.app/Contents/Frameworks "${EXECUTABLE}"-cli -install_name_tool -add_rpath @executable_path "${EXECUTABLE}"-cli +install_name_tool -add_rpath /Applications/"${LIB}" "${EXECUTABLE}"-cli +ditto "${EXECUTABLE}"-cli "${APP}"/.. # Codesign the app if [[ -n $CODESIGNID ]]; then msg "Codesigning Application." - install -m 0644 "${PROJECT_SOURCE_DATA_DIR}"/rt.entitlements "${CMAKE_BUILD_TYPE}"/rt.entitlements - plutil -convert binary1 "${CMAKE_BUILD_TYPE}"/rt.entitlements + iconv -f UTF-8 -t ASCII "${PROJECT_SOURCE_DATA_DIR}"/rt.entitlements > "${CMAKE_BUILD_TYPE}"/rt.entitlements + iconv -f UTF-8 -t ASCII "${PROJECT_SOURCE_DATA_DIR}"/rt-cli.entitlements > "${CMAKE_BUILD_TYPE}"/rt-cli.entitlements mv "${EXECUTABLE}"-cli "${LIB}" - for frameworklibs in "${LIB}"/*; do - codesign -v -s "${CODESIGNID}" -i com.rawtherapee.RawTherapee --force --verbose -o runtime --timestamp "${frameworklibs}" + for frameworklibs in "${LIB}"/*{dylib,so}; do + codesign -v -s "${CODESIGNID}" -i com.rawtherapee.RawTherapee --force --verbose -o runtime --timestamp --entitlements "${CMAKE_BUILD_TYPE}"/rt.entitlements "${frameworklibs}" done - codesign --timestamp --strict -v -s "${CODESIGNID}" -i com.rawtherapee.RawTherapee -o runtime --entitlements "${CMAKE_BUILD_TYPE}"/rt.entitlements "${APP}" + codesign --force -v -s "${CODESIGNID}" -i com.rawtherapee.RawTherapee -o runtime --entitlements "${CMAKE_BUILD_TYPE}"/rt-cli.entitlements "${LIB}"/rawtherapee-cli + codesign --deep --timestamp --strict -v -s "${CODESIGNID}" -i com.rawtherapee.RawTherapee -o runtime --entitlements "${CMAKE_BUILD_TYPE}"/rt.entitlements "${APP}" spctl -a -vvvv "${APP}" fi @@ -345,7 +352,7 @@ function CreateDmg { CreateWebloc 'Report Bug' 'https://github.com/Beep6581/RawTherapee/issues/new' # Disk image name - dmg_name="${PROJECT_NAME// /_}_OSX_${MINIMUM_SYSTEM_VERSION}_${PROC_BIT_DEPTH}_${PROJECT_FULL_VERSION}" + dmg_name="${PROJECT_NAME}_OSX_${MINIMUM_SYSTEM_VERSION}_${PROC_BIT_DEPTH}_${PROJECT_FULL_VERSION}" lower_build_type="$(tr '[:upper:]' '[:lower:]' <<< "$CMAKE_BUILD_TYPE")" if [[ $lower_build_type != release ]]; then dmg_name="${dmg_name}_${lower_build_type}" @@ -390,6 +397,7 @@ function CreateDmg { xcrun stapler staple "${dmg_name}.dmg" # staple the ticket xcrun stapler validate -v "${dmg_name}.dmg" echo "dmg Notarization success" + rm *dmg.zip break elif [[ $status1 = "in" ]]; then echo "dmg Notarization still in progress, sleeping for 15 seconds and trying again" @@ -404,10 +412,12 @@ function CreateDmg { # Zip disk image for redistribution msg "Zipping disk image for redistribution:" - zip "${dmg_name}.zip" "${dmg_name}.dmg" - rm "${dmg_name}.dmg" - msg "Removing disk image caches:" - rm -rf "${srcDir}" + mkdir "${PROJECT_NAME}_OSX_${MINIMUM_SYSTEM_VERSION}_${PROC_BIT_DEPTH}_${PROJECT_FULL_VERSION}_folder" + ditto {"${PROJECT_NAME}_OSX_${MINIMUM_SYSTEM_VERSION}_${PROC_BIT_DEPTH}_${PROJECT_FULL_VERSION}.dmg","rawtherapee-cli","${PROJECT_SOURCE_DATA_DIR}/INSTALL.readme.rtf"} "${PROJECT_NAME}_OSX_${MINIMUM_SYSTEM_VERSION}_${PROC_BIT_DEPTH}_${PROJECT_FULL_VERSION}_folder" + zip -r "${PROJECT_NAME}_OSX_${MINIMUM_SYSTEM_VERSION}_${PROC_BIT_DEPTH}_${PROJECT_FULL_VERSION}.zip" "${PROJECT_NAME}_OSX_${MINIMUM_SYSTEM_VERSION}_${PROC_BIT_DEPTH}_${PROJECT_FULL_VERSION}_folder/" + # rm "${dmg_name}.dmg" + # msg "Removing disk image caches:" + # rm -rf "${srcDir}" } CreateDmg msg "Finishing build:" diff --git a/tools/osx/rt.entitlements b/tools/osx/rt.entitlements index c571f1f41..8fc97c7da 100644 --- a/tools/osx/rt.entitlements +++ b/tools/osx/rt.entitlements @@ -1,19 +1,16 @@ + - - application-identifier - com.rawtherapee.RawTherapee - com.apple.security.temporary-exception.files.absolute-path.read-write - - / - - com.apple.security.cs.allow-dyld-environment-variables - - com.apple.security.files.user-selected.read-write - - com.apple.security.app-sandbox - - com.apple.security.files.downloads.read-write - - - \ No newline at end of file + + com.apple.application-identifier + com.rawtherapee.RawTherapee + com.apple.security.app-sandbox + + com.apple.security.cs.allow-dyld-environment-variables + + com.apple.security.temporary-exception.files.absolute-path.read-write + + / + + + From 99fd6162f840dd389618c944ec457905ceafe01a Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 12 May 2020 16:28:17 +0200 Subject: [PATCH 22/28] Clean code --- rtdata/languages/default | 2 -- rtengine/dcrop.cc | 1 - rtengine/improccoordinator.cc | 3 --- rtengine/improcfun.h | 19 ++++++++----------- rtengine/ipwavelet.cc | 23 +++-------------------- rtengine/procparams.cc | 21 ++++++++++++--------- rtengine/simpleprocess.cc | 3 --- 7 files changed, 23 insertions(+), 49 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 30d86c097..f28fcbdc2 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2324,8 +2324,6 @@ TP_WAVELET_SUPE;Extra TP_WAVELET_THR;Shadows threshold TP_WAVELET_THRESHOLD;Finer levels TP_WAVELET_THRESHOLD2;Coarser levels -//TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). -//TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. : All levels from level 1 up to the chosen value will only be affected within the Finer levels luminance range.\nAll other levels will have the whole range of luminances affected, unless the Coarser levels setting limits it.\nThe chosen value in this slider becomes the minimum possible value of the Coarser levels. TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). : Only levels between the chosen value and level 9/Extra will be affected by the Coarser levels luminance range.\nAll other levels will have the whole range of luminances affected, unless the Finer levels setting limits it.\nThe lower level possible that will be considered by the algorithm is limited by the Finer levels value. TP_WAVELET_THRESWAV;Balance Threshold diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index f58f2e4c9..8bf27b53d 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -1017,7 +1017,6 @@ void Crop::update(int todo) WaveParams.expnoise = false; } - // parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip); parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip); if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index f7f8756d2..5261675a0 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -891,7 +891,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if ((params->wavelet.enabled)) { WaveletParams WaveParams = params->wavelet; -// WaveParams.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); WaveParams.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); int kall = 0; LabImage *unshar = nullptr; @@ -922,7 +921,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) provis = params->wavelet.CLmethod; params->wavelet.CLmethod = "all"; ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); -// ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); unshar->CopyFrom(nprevl); @@ -936,7 +934,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) WaveParams.expnoise = false; } -// ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index f4a452dcc..b7d7c41e5 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -202,28 +202,25 @@ public: int pitch, int scale, const int luma, const int chroma/*, LUTf & Lcurve, LUTf & abcurve*/); void Tile_calc(int tilesize, int overlap, int kall, int imwidth, int imheight, int &numtiles_W, int &numtiles_H, int &tilewidth, int &tileheight, int &tileWskip, int &tileHskip); -// void ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const Wavblcurve & wavblcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, const LUTf &wavclCurve, int skip); void ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const Wavblcurve & wavblcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveSH & waOpacityCurveSH, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, const LUTf &wavclCurve, int skip); void WaveletcontAllL(LabImage * lab, float **varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_L, const Wavblcurve & wavblcurve, -// struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili); - struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveSH & waOpacityCurveSH, FlatCurve* ChCurve, bool Chutili); + struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveSH & waOpacityCurveSH, FlatCurve* ChCurve, bool Chutili); void WaveletcontAllLfinal(const wavelet_decomposition &WaveletCoeffs_L, const cont_params &cp, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL); void WaveletcontAllAB(LabImage * lab, float **varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_a, const Wavblcurve & wavblcurve, const WavOpacityCurveW & waOpacityCurveW, - struct cont_params &cp, const bool useChannelA, int skip, float *meanab, float *sigmaab); + struct cont_params &cp, const bool useChannelA, int skip, float *meanab, float *sigmaab); void WaveletAandBAllAB(const wavelet_decomposition &WaveletCoeffs_a, const wavelet_decomposition &WaveletCoeffs_b, - const cont_params &cp, FlatCurve* hhcurve, bool hhutili); + const cont_params &cp, FlatCurve* hhcurve, bool hhutili); void ContAllL(float **koeLi, float *maxkoeLi, bool lipschitz, int maxlvl, LabImage * lab, float **varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp, - // int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili); - int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveSH & waOpacityCurveSH, FlatCurve* ChCurve, bool Chutili); + int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveSH & waOpacityCurveSH, FlatCurve* ChCurve, bool Chutili); void finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, const cont_params &cp, - int W_L, int H_L, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL); + int W_L, int H_L, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL); void ContAllAB(LabImage * lab, int maxlvl, float **varhue, float **varchrom, float ** WavCoeffs_a, float * WavCoeffs_a0, int level, int dir, const WavOpacityCurveW & waOpacityCurveW, struct cont_params &cp, - int W_ab, int H_ab, const bool useChannelA, float *meanab, float *sigmaab); + int W_ab, int H_ab, const bool useChannelA, float *meanab, float *sigmaab); void Evaluate2(const wavelet_decomposition &WaveletCoeffs_L, - float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN); + float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN); void Eval2(float ** WavCoeffs_L, int level, - int W_L, int H_L, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN); + int W_L, int H_L, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN); void calceffect(int level, float *mean, float *sigma, float *mea, float effect, float offs); diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 373ea6ef0..0fc947aea 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -164,7 +164,6 @@ struct cont_params { int wavNestedLevels = 1; -//void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const Wavblcurve & wavblcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, const LUTf &wavclCurve, int skip) void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const Wavblcurve & wavblcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveSH & waOpacityCurveSH, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, const LUTf &wavclCurve, int skip) @@ -470,9 +469,6 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.t_lsl = static_cast(params->wavelet.bllev.getTopLeft()); cp.b_rsl = static_cast(params->wavelet.bllev.getBottomRight()); cp.t_rsl = static_cast(params->wavelet.bllev.getTopRight()); -// cp.numlevS = params->wavelet.threshold2; -// int maxlevS = 9 - cp.numlevH; -// cp.numlevS = rtengine::min(cp.numlevS, maxlevS); cp.numlevS = 9 - params->wavelet.threshold2; int maxlevS = cp.numlevH; cp.numlevS = rtengine::max(cp.numlevS, maxlevS); @@ -1027,7 +1023,6 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const Chutili = true; } -// WaveletcontAllL(labco, varhue, varchro, *Ldecomp, wavblcurve, cp, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili); WaveletcontAllL(labco, varhue, varchro, *Ldecomp, wavblcurve, cp, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, waOpacityCurveSH, ChCurve, Chutili); if (cp.val > 0 || ref || contr || cp.diagcurv) { //edge @@ -1297,7 +1292,6 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const const std::unique_ptr adecomp(new wavelet_decomposition(labco->data + datalen, labco->W, labco->H, levwava, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!adecomp->memoryAllocationFailed) { -// if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) { if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.chromco < 2.f )) { WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); } else if (cp.chromfi > 0.f && cp.chromco >= 2.f){ @@ -1335,7 +1329,6 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavb, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!bdecomp->memoryAllocationFailed) { -// if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) { if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.chromco < 2.f )) { WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); } else if (cp.chromfi > 0.f && cp.chromco >= 2.f){ @@ -1368,7 +1361,6 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavab, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!adecomp->memoryAllocationFailed && !bdecomp->memoryAllocationFailed) { -// if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) { if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.chromco < 2.f)) { WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); } else if (cp.chromfi > 0.f && cp.chromco >= 2.f){ @@ -1385,15 +1377,8 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); } -// WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); -// WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); -/* - if (cp.noiseena && (cp.chromfi > 0.f || cp.chromco > 0.f)) { - WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab); - WaveletAandBAllAB(*adecomp, *bdecomp, cp, hhCurve, hhutili); - } - */ + WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab); WaveletAandBAllAB(*adecomp, *bdecomp, cp, hhCurve, hhutili); @@ -2047,8 +2032,7 @@ void ImProcFunctions::WaveletcontAllLfinal(const wavelet_decomposition &WaveletC void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_L, const Wavblcurve & wavblcurve, -// struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili) - struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveSH & waOpacityCurveSH, FlatCurve* ChCurve, bool Chutili) + struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveSH & waOpacityCurveSH, FlatCurve* ChCurve, bool Chutili) { const int maxlvl = WaveletCoeffs_L.maxlevel(); const int W_L = WaveletCoeffs_L.level_W(0); @@ -2606,7 +2590,7 @@ void ImProcFunctions::WaveletAandBAllAB(const wavelet_decomposition &WaveletCoef } void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_ab, const Wavblcurve & wavblcurve, const WavOpacityCurveW & waOpacityCurveW, - struct cont_params &cp, const bool useChannelA, int skip, float *meanab, float *sigmaab) + struct cont_params &cp, const bool useChannelA, int skip, float *meanab, float *sigmaab) { int maxlvl = WaveletCoeffs_ab.maxlevel(); @@ -3133,7 +3117,6 @@ void ImProcFunctions::finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0, } void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz, int maxlvl, LabImage * labco, float ** varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp, -// int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili) int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveSH & waOpacityCurveSH, FlatCurve* ChCurve, bool Chutili) { assert(level >= 0); diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 4df201503..0829ddbb0 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2170,15 +2170,18 @@ WaveletParams::WaveletParams() : }, blcurve{ static_cast(FCT_MinMaxCPoints), -0.0, 0.0, 0.0, 0.35, 0.5, 0., 0.35, 0.35, 1.0, 0.0, 0.35, 0.35 -/* 0.0, - 0.75, - 0.35, - 0.35, - 1.0, - 0.75, - 0.35, - 0.35*/ + 0.0, + 0.0, + 0.0, + 0.35, + 0.5, + 0., + 0.35, + 0.35, + 1.0, + 0.0, + 0.35, + 0.35 }, opacityCurveRG{ static_cast(FCT_MinMaxCPoints), diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 92a3d7f29..a53902737 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1150,7 +1150,6 @@ private: provradius->CopyFrom(labView); } -// params.wavelet.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); params.wavelet.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); CurveFactory::curveWavContL(wavcontlutili, params.wavelet.wavclCurve, wavclCurve,/* hist16C, dummy,*/ 1); @@ -1159,7 +1158,6 @@ private: unshar = new LabImage(fw, fh); provis = params.wavelet.CLmethod; params.wavelet.CLmethod = "all"; -// ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); unshar->CopyFrom(labView); params.wavelet.CLmethod = provis; @@ -1172,7 +1170,6 @@ private: WaveParams.expnoise = false; } -// ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { From 5db57952ed0d445027196d8a64ffcd23fc2d6170 Mon Sep 17 00:00:00 2001 From: Desmis Date: Wed, 13 May 2020 14:27:08 +0200 Subject: [PATCH 23/28] Change label wavelet levels --- rtdata/languages/default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index f28fcbdc2..f10f98c6e 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2257,7 +2257,7 @@ TP_WAVELET_LEVCH;Chroma TP_WAVELET_LEVDIR_ALL;All levels, in all directions TP_WAVELET_LEVDIR_INF;Finer details levels, with selected level TP_WAVELET_LEVDIR_ONE;One level -TP_WAVELET_LEVDIR_SUP;Above the level +TP_WAVELET_LEVDIR_SUP;Coarser details levels, without selected level TP_WAVELET_LEVELS;Wavelet levels TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. TP_WAVELET_LEVF;Contrast From 464556b8743a80a1f53e3cff66400fabe367012a Mon Sep 17 00:00:00 2001 From: Thanatomanic <6567747+Thanatomanic@users.noreply.github.com> Date: Fri, 15 May 2020 09:58:14 +0200 Subject: [PATCH 24/28] Naming changes for itcwb GUI elements (#5735) Some naming changes for itcwb GUI elements --- rtdata/languages/default | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 9d9e841a2..a524ae1b8 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2356,9 +2356,9 @@ TP_WAVELET_WAVLOWTHR;Low contrast threshold TP_WAVELET_WAVOFFSET;Offset TP_WAVELET_OFFSET_TOOLTIP;Offset modifies the balance between shadows and highlights.\nHigh values here will amplify the contrast change of the highlights, whereas low values will amplify the contrast change of the shadows.\nAlong with a low Damper value you will able to select the contrasts that will be enhanced. TP_WBALANCE_AUTO;Auto -TP_WBALANCE_AUTOITCGREEN;Auto iterate temperature correlation -TP_WBALANCE_AUTOOLD;Auto RGB grey -TP_WBALANCE_AUTO_HEADER;Autos +TP_WBALANCE_AUTOITCGREEN;Temperature correlation +TP_WBALANCE_AUTOOLD;RGB grey +TP_WBALANCE_AUTO_HEADER;Automatic TP_WBALANCE_CAMERA;Camera TP_WBALANCE_CLOUDY;Cloudy TP_WBALANCE_CUSTOM;Custom @@ -2400,8 +2400,8 @@ TP_WBALANCE_SOLUX41;Solux 4100K TP_WBALANCE_SOLUX47;Solux 4700K (vendor) TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) TP_WBALANCE_SPOTWB;Use the pipette to pick the white balance from a neutral patch in the preview. -TP_WBALANCE_STUDLABEL;Student Itcwb: %1 -TP_WBALANCE_STUDLABEL_TOOLTIP;Display calculated Student correlation\nThe lower the student value, the better the correlation\nValues below 0.002 are excellent\nValues below 0.005 are very good\nValues below 0.01 are good\nValues below 0.05 are good enough\nValues above 0.5 are poor\nVery good Student test results does not mean that the WB is good, if the illuminant is non-standard the results are erratic.\nStudent=1000 means the calculations were not restarted but results are probably goods, use previous results +TP_WBALANCE_STUDLABEL;Correlation factor: %1 +TP_WBALANCE_STUDLABEL_TOOLTIP;Display calculated Student correlation.\nLower values are better, where <0.005 is excellent,\n<0.01 is good, and >0.5 is poor.\nLow values do not mean that the white balance is good:\nif the illuminant is non-standard the results can be erratic.\nA value of 1000 means previous calculations are used and\nthe resultsare probably good. TP_WBALANCE_TEMPBIAS;AWB temperature bias TP_WBALANCE_TEMPBIAS_TOOLTIP;Allows to alter the computation of the "auto white balance"\nby biasing it towards warmer or cooler temperatures. The bias\nis expressed as a percentage of the computed temperature,\nso that the result is given by "computedTemp + computedTemp * bias". TP_WBALANCE_TEMPERATURE;Temperature From 6cae1c55d4dcfb81c376902033f7e020e9d9226d Mon Sep 17 00:00:00 2001 From: Desmis Date: Sat, 16 May 2020 11:15:25 +0200 Subject: [PATCH 25/28] Fixed crash in wavelet level blur when preview is too small --- rtdata/languages/default | 1 + rtengine/ipwavelet.cc | 246 ++++++++++++++++++++------------------- rtgui/wavelet.cc | 2 +- 3 files changed, 127 insertions(+), 122 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index a524ae1b8..c822e1ebe 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2204,6 +2204,7 @@ TP_WAVELET_CONTRAST_MINUS;Contrast - TP_WAVELET_CONTRAST_PLUS;Contrast + TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. TP_WAVELET_CTYPE;Chrominance control +TP_WAVELET_CURVEEDITOR_BL_TOOLTIP;Disabled if zoom > about 300% TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (abscissa).\nLow abscissa values represent small local contrast (real values about 10..20).\n50% abscissa represents average local contrast (real value about 100..300).\n66% abscissa represents standard deviation of local contrast (real value about 300..800).\n100% abscissa represents maximum local contrast (real value about 3000..8000). TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function of hue.\nTake care not to overwrite changes made with the Gamut sub-tool's hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 0fc947aea..47882fab8 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -2434,84 +2434,86 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * // ContAllL(koeLi, maxkoeLi, true, maxlvl, labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili); ContAllL(koeLi, maxkoeLi, true, maxlvl, labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, waOpacityCurveSH, ChCurve, Chutili); + int minWL = min(Wlvl_L, Hlvl_L); - if (wavblcurve && wavcurvecomp && cp.blena) { - // printf("Blur level L\n"); - float mea[10]; - const float effect = cp.bluwav; - constexpr float offs = 1.f; - float * beta = new float[Wlvl_L * Hlvl_L]; + if(minWL > 180) { + if (wavblcurve && wavcurvecomp && cp.blena) { + // printf("Blur level L\n"); + float mea[10]; + const float effect = cp.bluwav; + constexpr float offs = 1.f; + float * beta = new float[Wlvl_L * Hlvl_L]; - calceffect(lvl, mean, sigma, mea, effect, offs); + calceffect(lvl, mean, sigma, mea, effect, offs); - float * bef = new float[Wlvl_L * Hlvl_L]; - float * aft = new float[Wlvl_L * Hlvl_L]; + float * bef = new float[Wlvl_L * Hlvl_L]; + float * aft = new float[Wlvl_L * Hlvl_L]; - for (int co = 0; co < Hlvl_L * Wlvl_L; co++) { - bef[co] = WavCoeffs_L[dir][co]; - float WavCL = std::fabs(WavCoeffs_L[dir][co]); + for (int co = 0; co < Hlvl_L * Wlvl_L; co++) { + bef[co] = WavCoeffs_L[dir][co]; + float WavCL = std::fabs(WavCoeffs_L[dir][co]); - if (WavCL < mea[0]) { - beta[co] = 0.05f; - n0++; + if (WavCL < mea[0]) { + beta[co] = 0.05f; + n0++; - if (WavCL < 32.7) { - n32++; + if (WavCL < 32.7) { + n32++; + } + } else if (WavCL < mea[1]) { + beta[co] = 0.2f; + n1++; + } else if (WavCL < mea[2]) { + beta[co] = 0.7f; + n2++; + } else if (WavCL < mea[3]) { + beta[co] = 1.f; //standard + n3++; + } else if (WavCL < mea[4]) { + beta[co] = 1.f; + n4++; + } else if (WavCL < mea[5]) { + beta[co] = 0.8f; //+sigma + n5++; + } else if (WavCL < mea[6]) { + beta[co] = 0.6f; + n6++; + } else if (WavCL < mea[7]) { + beta[co] = 0.4f; + n7++; + } else if (WavCL < mea[8]) { + beta[co] = 0.2f; // + 2 sigma + n8++; + } else if (WavCL < mea[9]) { + beta[co] = 0.1f; + n9++; + } else { + beta[co] = 0.01f; + n10++; } - } else if (WavCL < mea[1]) { - beta[co] = 0.2f; - n1++; - } else if (WavCL < mea[2]) { - beta[co] = 0.7f; - n2++; - } else if (WavCL < mea[3]) { - beta[co] = 1.f; //standard - n3++; - } else if (WavCL < mea[4]) { - beta[co] = 1.f; - n4++; - } else if (WavCL < mea[5]) { - beta[co] = 0.8f; //+sigma - n5++; - } else if (WavCL < mea[6]) { - beta[co] = 0.6f; - n6++; - } else if (WavCL < mea[7]) { - beta[co] = 0.4f; - n7++; - } else if (WavCL < mea[8]) { - beta[co] = 0.2f; // + 2 sigma - n8++; - } else if (WavCL < mea[9]) { - beta[co] = 0.1f; - n9++; - } else { - beta[co] = 0.01f; - n10++; + + } + if (settings->verbose) { + printf("lvl=%i n0=%i n32=%i n1=%i n2=%i n3=%i n4=%i n5=%i n6=%i n7=%i n8=%i n9=%i n10=%i\n", lvl, n0, n0 - n32, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10); + } - } - - if (settings->verbose) { - printf("lvl=%i n0=%i n32=%i n1=%i n2=%i n3=%i n4=%i n5=%i n6=%i n7=%i n8=%i n9=%i n10=%i\n", lvl, n0, n0 - n32, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10); - } - - float klev = (wavblcurve[lvl * 55.5f]); + float klev = (wavblcurve[lvl * 55.5f]); //blur level - // klev *= beta * 100.f / skip; - klev *= 100.f / skip; - boxblur(bef, aft, klev, Wlvl_L, Hlvl_L, false); + klev *= 80.f / skip; + boxblur(bef, aft, klev, Wlvl_L, Hlvl_L, false); - for (int co = 0; co < Hlvl_L * Wlvl_L; co++) { - aft[co] = bef[co] * (1.f - beta[co]) + aft[co] * beta[co]; - WavCoeffs_L[dir][co] = aft[co]; + for (int co = 0; co < Hlvl_L * Wlvl_L; co++) { + aft[co] = bef[co] * (1.f - beta[co]) + aft[co] * beta[co]; + WavCoeffs_L[dir][co] = aft[co]; + } + + delete[] bef; + delete[] aft; + delete[] beta; } - - delete[] bef; - delete[] aft; - delete[] beta; } } } @@ -2748,72 +2750,74 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); ContAllAB(labco, maxlvl, varhue, varchrom, WavCoeffs_ab, WavCoeffs_ab0, lvl, dir, waOpacityCurveW, cp, Wlvl_ab, Hlvl_ab, useChannelA, meanab, sigmaab); + int minWL = min(Wlvl_ab, Hlvl_ab); + + if(minWL > 180) { + if (wavblcurve && wavcurvecomp && cp.blena && cp.chrwav > 0.f) { - if (wavblcurve && wavcurvecomp && cp.blena && cp.chrwav > 0.f) { + float mea[10]; + float effect = cp.bluwav; + float offs = 1.f; + float * beta = new float[Wlvl_ab * Hlvl_ab]; - float mea[10]; - float effect = cp.bluwav; - float offs = 1.f; - float * beta = new float[Wlvl_ab * Hlvl_ab]; - - for (int co = 0; co < Wlvl_ab * Hlvl_ab; co++) { - beta[co] = 1.f; - } - - calceffect(lvl, meanab, sigmaab, mea, effect, offs); - - float * bef = new float[Wlvl_ab * Hlvl_ab]; - float * aft = new float[Wlvl_ab * Hlvl_ab]; - float klev; - - for (int co = 0; co < Hlvl_ab * Wlvl_ab; co++) { - bef[co] = WavCoeffs_ab[dir][co]; - float WavCab = std::fabs(WavCoeffs_ab[dir][co]); - - if (WavCab < mea[0]) { - beta[co] = 0.05f; - } else if (WavCab < mea[1]) { - beta[co] = 0.2f; - } else if (WavCab < mea[2]) { - beta[co] = 0.7f; - } else if (WavCab < mea[3]) { - beta[co] = 1.f; //standard - } else if (WavCab < mea[4]) { + for (int co = 0; co < Wlvl_ab * Hlvl_ab; co++) { beta[co] = 1.f; - } else if (WavCab < mea[5]) { - beta[co] = 0.8f; //+sigma - } else if (WavCab < mea[6]) { - beta[co] = 0.6f; - } else if (WavCab < mea[7]) { - beta[co] = 0.4f; - } else if (WavCab < mea[8]) { - beta[co] = 0.2f; // + 2 sigma - } else if (WavCab < mea[9]) { - beta[co] = 0.1f; - } else { - beta[co] = 0.0f; } + calceffect(lvl, meanab, sigmaab, mea, effect, offs); + float * bef = new float[Wlvl_ab * Hlvl_ab]; + float * aft = new float[Wlvl_ab * Hlvl_ab]; + float klev; + + for (int co = 0; co < Hlvl_ab * Wlvl_ab; co++) { + bef[co] = WavCoeffs_ab[dir][co]; + float WavCab = std::fabs(WavCoeffs_ab[dir][co]); + + if (WavCab < mea[0]) { + beta[co] = 0.05f; + } else if (WavCab < mea[1]) { + beta[co] = 0.2f; + } else if (WavCab < mea[2]) { + beta[co] = 0.7f; + } else if (WavCab < mea[3]) { + beta[co] = 1.f; //standard + } else if (WavCab < mea[4]) { + beta[co] = 1.f; + } else if (WavCab < mea[5]) { + beta[co] = 0.8f; //+sigma + } else if (WavCab < mea[6]) { + beta[co] = 0.6f; + } else if (WavCab < mea[7]) { + beta[co] = 0.4f; + } else if (WavCab < mea[8]) { + beta[co] = 0.2f; // + 2 sigma + } else if (WavCab < mea[9]) { + beta[co] = 0.1f; + } else { + beta[co] = 0.0f; + } + + + } + + klev = (wavblcurve[lvl * 55.5f]); + + klev *= cp.chrwav * 80.f / skip; + + boxblur(bef, aft, klev, Wlvl_ab, Hlvl_ab, false); + + for (int co = 0; co < Hlvl_ab * Wlvl_ab; co++) { + aft[co] = bef[co] * (1.f - beta[co]) + aft[co] * beta[co]; + WavCoeffs_ab[dir][co] = aft[co]; + } + + delete[] bef; + delete[] aft; + delete[] beta; } - - klev = (wavblcurve[lvl * 55.5f]); - - klev *= cp.chrwav * 100.f / skip; - - boxblur(bef, aft, klev, Wlvl_ab, Hlvl_ab, false); - - for (int co = 0; co < Hlvl_ab * Wlvl_ab; co++) { - aft[co] = bef[co] * (1.f - beta[co]) + aft[co] * beta[co]; - WavCoeffs_ab[dir][co] = aft[co]; - } - - delete[] bef; - delete[] aft; - delete[] beta; } - } } diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 53c7ef90b..2dc4aa05c 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -758,7 +758,7 @@ Wavelet::Wavelet() : blshape->setIdentityValue(0.); blshape->setResetCurve(FlatCurveType(default_params.blcurve.at(0)), default_params.blcurve); - blshape->setTooltip(M("TP_WAVELET_CURVEEDITOR_CC_TOOLTIP")); + blshape->setTooltip(M("TP_WAVELET_CURVEEDITOR_BL_TOOLTIP")); curveEditorbl->curveListComplete(); curveEditorbl->show(); From 1d66bdc002b19982a760b14c74938518c5a239eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Sun, 17 May 2020 09:55:41 +0200 Subject: [PATCH 26/28] Fix leak in `crxFreeImageData()` (by Danny Heijl), fixes #5758 --- rtengine/canon_cr3_decoder.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rtengine/canon_cr3_decoder.cc b/rtengine/canon_cr3_decoder.cc index d9a10900c..f9850189c 100644 --- a/rtengine/canon_cr3_decoder.cc +++ b/rtengine/canon_cr3_decoder.cc @@ -3042,11 +3042,11 @@ bool crxSetupImageData( void crxFreeImageData(CrxImage* img) { - CrxTile* tile = img->tiles; - const int nTiles = img->tileRows * img->tileCols; - if (img->tiles) { - for (std::int32_t curTile = 0; curTile < nTiles; curTile++, tile++) { + CrxTile* const tile = img->tiles; + const int nTiles = img->tileRows * img->tileCols; + + for (std::int32_t curTile = 0; curTile < nTiles; ++curTile) { if (tile[curTile].comps) { for (std::int32_t curPlane = 0; curPlane < img->nPlanes; ++curPlane) { crxFreeSubbandData(img, tile[curTile].comps + curPlane); From 90180a7d1f794397d03935fa5ab33447829ebaf0 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 17 May 2020 14:07:54 +0200 Subject: [PATCH 27/28] Improve denoise equalizer wavelet levels --- rtengine/FTblockDN.cc | 12 ++++++------ rtengine/ipwavelet.cc | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index ab06f92f2..89e4c1b8d 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -2214,7 +2214,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &W int maxlvl = min(WaveletCoeffs_L.maxlevel(), 5); const float eps = 0.01f; - if (edge == 1 || edge == 3 || edge == 4) { + if (edge == 1 || edge == 3 || edge == 4 || edge == 5) { maxlvl = 4; //for refine denoise edge wavelet } @@ -2286,7 +2286,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &W for (int i = 0; i < Hlvl_L * Wlvl_L; ++i) { nvl[i] = 0.f; } - if ((edge == 1 || edge == 2 || edge == 3) && vari) { + if ((edge == 1 || edge == 2 || edge == 3 || edge == 5) && vari) { // nvl = blurBuffer; // we need one buffer, but fortunately we don't have to allocate a new one because we can use blurBuffer if ((edge == 1 || edge == 3)) { for (int i = 0; i < Hlvl_L * Wlvl_L; ++i) { @@ -2294,7 +2294,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &W } } - if (edge == 2 || edge == 4) { + if (edge == 2 || edge == 4 || edge == 5) { for (int i = 0; i < Hlvl_L * Wlvl_L; ++i) { nvl[i] = vari[lvl] * SQR(noisevarlum[i]); } @@ -2569,7 +2569,7 @@ bool ImProcFunctions::WaveletDenoiseAllL(const wavelet_decomposition &WaveletCoe int maxlvl = min(WaveletCoeffs_L.maxlevel(), 5); - if (edge == 1 || edge == 3) { + if (edge == 1 || edge == 3 || edge == 5) { maxlvl = 4; //for refine denoise edge wavelet } @@ -2713,7 +2713,7 @@ void ImProcFunctions::ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, f nvl[i] = 0.f; } - if ((edge == 1 || edge == 2 || edge == 3) && vari) { + if ((edge == 1 || edge == 2 || edge == 3 || edge == 5) && vari) { // nvl = blurBuffer; // we need one buffer, but fortunately we don't have to allocate a new one because we can use blurBuffer if ((edge == 1 || edge == 3)) { for (int i = 0; i < W_L * H_L; ++i) { @@ -2721,7 +2721,7 @@ void ImProcFunctions::ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, f } } - if (edge == 2 || edge == 4) { + if (edge == 2 || edge == 4 || edge == 5) { for (int i = 0; i < W_L * H_L; ++i) { nvl[i] = vari[level] * SQR(noisevarlum[i]); } diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 47882fab8..47bd0f08a 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -958,7 +958,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } if ((cp.lev0n > 0.1f || cp.lev1n > 0.1f || cp.lev2n > 0.1f || cp.lev3n > 0.1f) && cp.noiseena) { - int edge = 1; + int edge = 5; vari[0] = rtengine::max(0.000001f, vari[0]); vari[1] = rtengine::max(0.000001f, vari[1]); vari[2] = rtengine::max(0.000001f, vari[2]); From f0720ff34c0e905ce819712068b5dfd8a8bd306a Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Wed, 20 May 2020 08:29:19 +0200 Subject: [PATCH 28/28] Avoid overwriting `c_black` from inside `::preprocess` when re-computing multipliers according to selected preprocess WB mode. Fixes #5765. --- rtengine/rawimagesource.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index f94070f2d..77a5ff9fc 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -1235,7 +1235,8 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le { // Recalculate the scaling coefficients, using auto WB if selected in the Preprocess WB param. // Auto WB gives us better demosaicing and CA auto-correct performance for strange white balance settings (such as UniWB) - ri->get_colorsCoeff( ref_pre_mul, scale_mul, c_black, raw.preprocessWB.mode == RAWParams::PreprocessWB::Mode::AUTO); + float dummy_cblk[4] = { 0.f }; // Avoid overwriting c_black, see issue #5676 + ri->get_colorsCoeff( ref_pre_mul, scale_mul, dummy_cblk, raw.preprocessWB.mode == RAWParams::PreprocessWB::Mode::AUTO); refwb_red = ri->get_pre_mul(0) / ref_pre_mul[0]; refwb_green = ri->get_pre_mul(1) / ref_pre_mul[1];