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 1/2] 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 2/2] 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();