diff --git a/rtdata/languages/default b/rtdata/languages/default index 0d87f7677..cc978ce92 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1818,6 +1818,7 @@ TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look.\nPixel Shift is for Pentax/Sony Pixel Shift files. It falls back to AMaZE for non-Pixel Shift files. TP_RAW_DUALDEMOSAICAUTOCONTRAST;Auto threshold +TP_RAW_DUALDEMOSAICAUTOCONTRAST_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value based on flat regions in the image.\nIf there is no flat region in the image or the image is too noisy, the value will be set to 0.\nTo set the value manually, uncheck the check-box first (reasonable values depend on the image). TP_RAW_DUALDEMOSAICCONTRAST;Contrast threshold TP_RAW_EAHD;EAHD TP_RAW_FALSECOLOR;False color suppression steps diff --git a/rtengine/dual_demosaic_RT.cc b/rtengine/dual_demosaic_RT.cc index 1498f600c..4ffac9296 100644 --- a/rtengine/dual_demosaic_RT.cc +++ b/rtengine/dual_demosaic_RT.cc @@ -40,7 +40,7 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const RAWParams &raw, int wi { BENCHFUN - if (contrast == 0.f) { + if (contrast == 0.f && !autoContrast) { // contrast == 0.0 means only first demosaicer will be used if(isBayer) { if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEVNG4) ) { diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 6547c37b6..78c1a6a09 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -240,13 +240,13 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } } bool autoContrast = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicAutoContrast : params.raw.xtranssensor.dualDemosaicAutoContrast; - double contrastThreshold = params.raw.bayersensor.dualDemosaicContrast; + double contrastThreshold = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicContrast : params.raw.xtranssensor.dualDemosaicContrast; imgsrc->demosaic(rp, autoContrast, contrastThreshold); //enabled demosaic - if (imgsrc->getSensorType() == ST_BAYER && bayerAutoContrastListener) { + if (imgsrc->getSensorType() == ST_BAYER && bayerAutoContrastListener && autoContrast) { bayerAutoContrastListener->autoContrastChanged(autoContrast ? contrastThreshold : -1.0); } - if (imgsrc->getSensorType() == ST_FUJI_XTRANS && xtransAutoContrastListener) { + if (imgsrc->getSensorType() == ST_FUJI_XTRANS && xtransAutoContrastListener && autoContrast) { xtransAutoContrastListener->autoContrastChanged(autoContrast ? contrastThreshold : -1.0); } diff --git a/rtengine/rt_algo.cc b/rtengine/rt_algo.cc index 4bdcc88a3..ae385508a 100644 --- a/rtengine/rt_algo.cc +++ b/rtengine/rt_algo.cc @@ -194,7 +194,7 @@ void findMinMaxPercentile(const float* data, size_t size, float minPrct, float& void buildBlendMask(float** luminance, float **blend, int W, int H, float &contrastThreshold, float amount, bool autoContrast) { - if(contrastThreshold == 0.f) { + if(contrastThreshold == 0.f && !autoContrast) { for(int j = 0; j < H; ++j) { for(int i = 0; i < W; ++i) { blend[j][i] = amount; diff --git a/rtgui/bayerprocess.cc b/rtgui/bayerprocess.cc index f9b6ef9e5..3648c8f89 100644 --- a/rtgui/bayerprocess.cc +++ b/rtgui/bayerprocess.cc @@ -48,25 +48,16 @@ BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RA pack_start( *hb1, Gtk::PACK_SHRINK, 4); dualDemosaicOptions = Gtk::manage(new Gtk::VBox()); - Gtk::HBox* hbAutoContrast = Gtk::manage(new Gtk::HBox()); - - dualDemosaicAutoContrast = Gtk::manage(new CheckBox(M("TP_RAW_DUALDEMOSAICAUTOCONTRAST"), multiImage)); - dualDemosaicAutoContrast->setCheckBoxListener(this); - - dualDemosaicLabel = Gtk::manage(new Gtk::Label("")); dualDemosaicContrast = Gtk::manage(new Adjuster(M("TP_RAW_DUALDEMOSAICCONTRAST"), 0, 100, 1, 20)); dualDemosaicContrast->setAdjusterListener(this); - + dualDemosaicContrast->addAutoButton(M("TP_RAW_DUALDEMOSAICAUTOCONTRAST_TOOLTIP")); + dualDemosaicContrast->setAutoValue(true); if (dualDemosaicContrast->delay < options.adjusterMaxDelay) { dualDemosaicContrast->delay = options.adjusterMaxDelay; } - dualDemosaicAutoContrast->show(); dualDemosaicContrast->show(); - hbAutoContrast->pack_start(*dualDemosaicAutoContrast); - hbAutoContrast->pack_start(*dualDemosaicLabel); - dualDemosaicOptions->pack_start(*hbAutoContrast); dualDemosaicOptions->pack_start(*dualDemosaicContrast); pack_start( *dualDemosaicOptions, Gtk::PACK_SHRINK, 4); @@ -310,11 +301,9 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params pixelShiftNonGreenCross->setValue (pp->raw.bayersensor.pixelShiftNonGreenCross); ccSteps->setValue (pp->raw.bayersensor.ccSteps); lmmseIterations->setValue (pp->raw.bayersensor.lmmse_iterations); - dualDemosaicAutoContrast->setValue (pp->raw.bayersensor.dualDemosaicAutoContrast); + dualDemosaicContrast->setAutoValue(pp->raw.bayersensor.dualDemosaicAutoContrast); dualDemosaicContrast->setValue (pp->raw.bayersensor.dualDemosaicContrast); - if (!batchMode) { - dualDemosaicContrast->set_sensitive(!pp->raw.bayersensor.dualDemosaicAutoContrast); - } + pixelShiftMotionMethod->set_active ((int)pp->raw.bayersensor.pixelShiftMotionCorrectionMethod); pixelShiftEperIso->setValue (pp->raw.bayersensor.pixelShiftEperIso); pixelShiftSigma->setValue (pp->raw.bayersensor.pixelShiftSigma); @@ -338,8 +327,8 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params pixelShiftEqualBrightChannel->setEdited (pedited->raw.bayersensor.pixelShiftEqualBrightChannel); pixelShiftNonGreenCross->setEdited (pedited->raw.bayersensor.pixelShiftNonGreenCross); lmmseIterations->setEditedState ( pedited->raw.bayersensor.lmmseIterations ? Edited : UnEdited); - dualDemosaicAutoContrast->setEdited ( pedited->raw.bayersensor.dualDemosaicAutoContrast ? Edited : UnEdited); dualDemosaicContrast->setEditedState ( pedited->raw.bayersensor.dualDemosaicContrast ? Edited : UnEdited); + dualDemosaicContrast->setAutoInconsistent (multiImage && !pedited->raw.bayersensor.dualDemosaicAutoContrast); pixelShiftEperIso->setEditedState ( pedited->raw.bayersensor.pixelShiftEperIso ? Edited : UnEdited); pixelShiftSigma->setEditedState ( pedited->raw.bayersensor.pixelShiftSigma ? Edited : UnEdited); @@ -360,6 +349,7 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params } } + lastAutoContrast = pp->raw.bayersensor.dualDemosaicAutoContrast; if (!batchMode) { dcbOptions->set_visible(pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::DCB) || pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::DCBVNG4)); @@ -400,7 +390,7 @@ void BayerProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pe pp->raw.bayersensor.dcb_enhance = dcbEnhance->getLastActive (); pp->raw.bayersensor.border = border->getIntValue(); pp->raw.bayersensor.lmmse_iterations = lmmseIterations->getIntValue(); - pp->raw.bayersensor.dualDemosaicAutoContrast = dualDemosaicAutoContrast->getLastActive (); + pp->raw.bayersensor.dualDemosaicAutoContrast = dualDemosaicContrast->getAutoValue(); pp->raw.bayersensor.dualDemosaicContrast = dualDemosaicContrast->getValue(); pp->raw.bayersensor.pixelShiftMotionCorrectionMethod = (RAWParams::BayerSensor::PSMotionCorrectionMethod)pixelShiftMotionMethod->get_active_row_number(); pp->raw.bayersensor.pixelShiftEperIso = pixelShiftEperIso->getValue(); @@ -441,7 +431,7 @@ void BayerProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pe pedited->raw.bayersensor.dcbEnhance = !dcbEnhance->get_inconsistent(); //pedited->raw.bayersensor.allEnhance = !allEnhance->get_inconsistent(); pedited->raw.bayersensor.lmmseIterations = lmmseIterations->getEditedState (); - pedited->raw.bayersensor.dualDemosaicAutoContrast = !dualDemosaicAutoContrast->get_inconsistent(); + pedited->raw.bayersensor.dualDemosaicAutoContrast = !dualDemosaicContrast->getAutoInconsistent (); pedited->raw.bayersensor.dualDemosaicContrast = dualDemosaicContrast->getEditedState (); pedited->raw.bayersensor.pixelShiftMotionCorrectionMethod = pixelShiftMotionMethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->raw.bayersensor.pixelShiftDemosaicMethod = pixelShiftDemosaicMethod->get_active_text() != M("GENERAL_UNCHANGED"); @@ -556,10 +546,6 @@ void BayerProcess::adjusterChanged (Adjuster* a, double newval) } } -void BayerProcess::adjusterAutoToggled(Adjuster* a, bool newval) -{ -} - void BayerProcess::methodChanged () { const int currentSelection = method->get_active_row_number(); @@ -624,14 +610,7 @@ void BayerProcess::imageNumberChanged () void BayerProcess::checkBoxToggled (CheckBox* c, CheckValue newval) { - if (c == dualDemosaicAutoContrast) { - if (!batchMode) { - dualDemosaicContrast->set_sensitive(newval == CheckValue::off); - } - if (listener) { - listener->panelChanged (EvDemosaicAutoContrast, dualDemosaicAutoContrast->getValueAsStr ()); - } - } else if (c == dcbEnhance) { + if (c == dcbEnhance) { if (listener) { listener->panelChanged (EvDemosaicDCBEnhanced, dcbEnhance->getValueAsStr ()); } @@ -684,6 +663,33 @@ void BayerProcess::checkBoxToggled (CheckBox* c, CheckValue newval) } } +void BayerProcess::adjusterAutoToggled(Adjuster* a, bool newval) +{ + if (multiImage) { + if (dualDemosaicContrast->getAutoInconsistent()) { + dualDemosaicContrast->setAutoInconsistent (false); + dualDemosaicContrast->setAutoValue (false); + } else if (lastAutoContrast) { + dualDemosaicContrast->setAutoInconsistent (true); + } + + lastAutoContrast = dualDemosaicContrast->getAutoValue(); + } + + if (listener) { + + if (a == dualDemosaicContrast) { + if (dualDemosaicContrast->getAutoInconsistent()) { + listener->panelChanged (EvDemosaicAutoContrast, M ("GENERAL_UNCHANGED")); + } else if (dualDemosaicContrast->getAutoValue()) { + listener->panelChanged (EvDemosaicAutoContrast, M ("GENERAL_ENABLED")); + } else { + listener->panelChanged (EvDemosaicAutoContrast, M ("GENERAL_DISABLED")); + } + } + } +} + void BayerProcess::pixelShiftMotionMethodChanged () { if (!batchMode) { @@ -750,11 +756,9 @@ void BayerProcess::autoContrastChanged (double autoContrast) const auto func = [](gpointer data) -> gboolean { Data *d = static_cast(data); BayerProcess *me = d->me; - if (d->autoContrast == -1.0) { - me->dualDemosaicLabel->set_text(""); - } else { - me->dualDemosaicLabel->set_text(Glib::ustring::format(std::fixed, std::setprecision(0), d->autoContrast)); - } + me->disableListener(); + me->dualDemosaicContrast->setValue(d->autoContrast); + me->enableListener(); return FALSE; }; diff --git a/rtgui/bayerprocess.h b/rtgui/bayerprocess.h index cde3270bb..d72d82cc4 100644 --- a/rtgui/bayerprocess.h +++ b/rtgui/bayerprocess.h @@ -59,10 +59,8 @@ protected: Adjuster* pixelShiftSigma; Gtk::VBox *dualDemosaicOptions; Adjuster* dualDemosaicContrast; - CheckBox* dualDemosaicAutoContrast; - Gtk::Label* dualDemosaicLabel; int oldMethod; - + bool lastAutoContrast; IdleRegister idle_register; rtengine::ProcEvent EvDemosaicBorder; diff --git a/rtgui/xtransprocess.cc b/rtgui/xtransprocess.cc index 670ddccf3..1707b84ff 100644 --- a/rtgui/xtransprocess.cc +++ b/rtgui/xtransprocess.cc @@ -69,25 +69,17 @@ XTransProcess::XTransProcess () : FoldableToolPanel(this, "xtransprocess", M("TP pack_start( *hb1, Gtk::PACK_SHRINK, 4); dualDemosaicOptions = Gtk::manage (new Gtk::VBox ()); - Gtk::HBox* hbAutoContrast = Gtk::manage(new Gtk::HBox()); - - dualDemosaicAutoContrast = Gtk::manage(new CheckBox(M("TP_RAW_DUALDEMOSAICAUTOCONTRAST"), multiImage)); - dualDemosaicAutoContrast->setCheckBoxListener(this); - - dualDemosaicLabel = Gtk::manage(new Gtk::Label("")); dualDemosaicContrast = Gtk::manage(new Adjuster (M("TP_RAW_DUALDEMOSAICCONTRAST"), 0, 100, 1, 20)); dualDemosaicContrast->setAdjusterListener (this); + dualDemosaicContrast->addAutoButton(M("TP_RAW_DUALDEMOSAICAUTOCONTRAST_TOOLTIP")); + dualDemosaicContrast->setAutoValue(true); if (dualDemosaicContrast->delay < options.adjusterMaxDelay) { dualDemosaicContrast->delay = options.adjusterMaxDelay; } - dualDemosaicAutoContrast->show(); dualDemosaicContrast->show(); - hbAutoContrast->pack_start(*dualDemosaicAutoContrast); - hbAutoContrast->pack_start(*dualDemosaicLabel); - dualDemosaicOptions->pack_start(*hbAutoContrast); dualDemosaicOptions->pack_start(*dualDemosaicContrast); pack_start( *dualDemosaicOptions, Gtk::PACK_SHRINK, 4); @@ -119,7 +111,7 @@ void XTransProcess::read(const rtengine::procparams::ProcParams* pp, const Param } if(pedited ) { - dualDemosaicAutoContrast->setEdited ( pedited->raw.xtranssensor.dualDemosaicAutoContrast ? Edited : UnEdited); + dualDemosaicContrast->setAutoInconsistent (multiImage && !pedited->raw.xtranssensor.dualDemosaicAutoContrast); dualDemosaicContrast->setEditedState ( pedited->raw.xtranssensor.dualDemosaicContrast ? Edited : UnEdited); ccSteps->setEditedState (pedited->raw.xtranssensor.ccSteps ? Edited : UnEdited); @@ -127,9 +119,12 @@ void XTransProcess::read(const rtengine::procparams::ProcParams* pp, const Param method->set_active_text(M("GENERAL_UNCHANGED")); } } - dualDemosaicAutoContrast->setValue (pp->raw.xtranssensor.dualDemosaicAutoContrast); + dualDemosaicContrast->setAutoValue(pp->raw.xtranssensor.dualDemosaicAutoContrast); dualDemosaicContrast->setValue (pp->raw.xtranssensor.dualDemosaicContrast); ccSteps->setValue (pp->raw.xtranssensor.ccSteps); + + lastAutoContrast = pp->raw.bayersensor.dualDemosaicAutoContrast; + if (!batchMode) { dualDemosaicOptions->set_visible(pp->raw.xtranssensor.method == procparams::RAWParams::XTransSensor::getMethodString(procparams::RAWParams::XTransSensor::Method::FOUR_PASS) || pp->raw.xtranssensor.method == procparams::RAWParams::XTransSensor::getMethodString(procparams::RAWParams::XTransSensor::Method::TWO_PASS)); @@ -142,7 +137,7 @@ void XTransProcess::read(const rtengine::procparams::ProcParams* pp, const Param void XTransProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) { - pp->raw.xtranssensor.dualDemosaicAutoContrast = dualDemosaicAutoContrast->getLastActive (); + pp->raw.xtranssensor.dualDemosaicAutoContrast = dualDemosaicContrast->getAutoValue(); pp->raw.xtranssensor.dualDemosaicContrast = dualDemosaicContrast->getValue(); pp->raw.xtranssensor.ccSteps = ccSteps->getIntValue(); @@ -154,7 +149,7 @@ void XTransProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* p if (pedited) { pedited->raw.xtranssensor.method = method->get_active_text() != M("GENERAL_UNCHANGED"); - pedited->raw.xtranssensor.dualDemosaicAutoContrast = !dualDemosaicAutoContrast->get_inconsistent(); + pedited->raw.xtranssensor.dualDemosaicAutoContrast = !dualDemosaicContrast->getAutoInconsistent (); pedited->raw.xtranssensor.dualDemosaicContrast = dualDemosaicContrast->getEditedState (); pedited->raw.xtranssensor.ccSteps = ccSteps->getEditedState (); } @@ -200,17 +195,31 @@ void XTransProcess::adjusterChanged(Adjuster* a, double newval) } } -void XTransProcess::checkBoxToggled (CheckBox* c, CheckValue newval) -{ - if (c == dualDemosaicAutoContrast) { - if (listener) { - listener->panelChanged (EvDemosaicAutoContrast, dualDemosaicAutoContrast->getValueAsStr ()); - } - } -} - void XTransProcess::adjusterAutoToggled(Adjuster* a, bool newval) { + if (multiImage) { + if (dualDemosaicContrast->getAutoInconsistent()) { + dualDemosaicContrast->setAutoInconsistent (false); + dualDemosaicContrast->setAutoValue (false); + } else if (lastAutoContrast) { + dualDemosaicContrast->setAutoInconsistent (true); + } + + lastAutoContrast = dualDemosaicContrast->getAutoValue(); + } + + if (listener) { + + if (a == dualDemosaicContrast) { + if (dualDemosaicContrast->getAutoInconsistent()) { + listener->panelChanged (EvDemosaicAutoContrast, M ("GENERAL_UNCHANGED")); + } else if (dualDemosaicContrast->getAutoValue()) { + listener->panelChanged (EvDemosaicAutoContrast, M ("GENERAL_ENABLED")); + } else { + listener->panelChanged (EvDemosaicAutoContrast, M ("GENERAL_DISABLED")); + } + } + } } void XTransProcess::methodChanged () @@ -236,6 +245,10 @@ void XTransProcess::methodChanged () } } +void XTransProcess::checkBoxToggled (CheckBox* c, CheckValue newval) +{ +} + void XTransProcess::autoContrastChanged (double autoContrast) { struct Data { @@ -245,11 +258,9 @@ void XTransProcess::autoContrastChanged (double autoContrast) const auto func = [](gpointer data) -> gboolean { Data *d = static_cast(data); XTransProcess *me = d->me; - if (d->autoContrast == -1.0) { - me->dualDemosaicLabel->set_text(""); - } else { - me->dualDemosaicLabel->set_text(Glib::ustring::format(std::fixed, std::setprecision(0), d->autoContrast)); - } + me->disableListener(); + me->dualDemosaicContrast->setValue(d->autoContrast); + me->enableListener(); return FALSE; }; diff --git a/rtgui/xtransprocess.h b/rtgui/xtransprocess.h index a90a97326..9c958a10c 100644 --- a/rtgui/xtransprocess.h +++ b/rtgui/xtransprocess.h @@ -35,8 +35,7 @@ protected: Adjuster* ccSteps; Gtk::VBox *dualDemosaicOptions; Adjuster* dualDemosaicContrast; - CheckBox* dualDemosaicAutoContrast; - Gtk::Label* dualDemosaicLabel; + bool lastAutoContrast; int oldSelection; sigc::connection methodconn;