diff --git a/rtdata/languages/default b/rtdata/languages/default index 02ae8aff1..5f16404c2 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -727,6 +727,7 @@ HISTORY_MSG_492;RGB Curves HISTORY_MSG_493;L*a*b* Adjustments HISTORY_MSG_CLAMPOOG;Out-of-gamut color clipping HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction +HISTORY_MSG_DUALDEMOSAIC_CONTRAST;AMaZE+VNG4 - Contrast threshold HISTORY_MSG_HISTMATCHING;Auto-Matched Tone Curve HISTORY_MSG_LOCALCONTRAST_AMOUNT;Local Contrast - Amount HISTORY_MSG_LOCALCONTRAST_DARKNESS;Local Contrast - Darkness @@ -1771,6 +1772,7 @@ TP_RAW_DMETHOD;Method 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_DUALDEMOSAICCONTRAST;Contrast threshold TP_RAW_EAHD;EAHD TP_RAW_FALSECOLOR;False color suppression steps TP_RAW_FAST;Fast diff --git a/rtengine/amaze_vng4_demosaic_RT.cc b/rtengine/amaze_vng4_demosaic_RT.cc index b27c26df0..0dae2c49b 100644 --- a/rtengine/amaze_vng4_demosaic_RT.cc +++ b/rtengine/amaze_vng4_demosaic_RT.cc @@ -1,17 +1,14 @@ //////////////////////////////////////////////////////////////// // -// AMaZE demosaic algorithm -// (Aliasing Minimization and Zipper Elimination) +// combined AMaZE + VNG4 demosaic algorithm // -// copyright (c) 2008-2010 Emil Martinec -// optimized for speed by Ingo Weyrich // -// incorporating ideas of Luis Sanz Rodrigues and Paul Lee +// copyright (c) 2018 Ingo Weyrich // -// code dated: May 27, 2010 -// latest modification: Ingo Weyrich, January 25, 2016 +// blends AMaZE and VNG4 output based on contrast // -// amaze_interpolate_RT.cc is free software: you can redistribute it and/or modify +// +// amaze_vng4_demosaic_RT.cc 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. @@ -38,39 +35,57 @@ using namespace std; namespace rtengine { -void RawImageSource::amaze_vng4_demosaic_RT(int winw, int winh, array2D &rawData, array2D &red, array2D &green, array2D &blue) +void RawImageSource::amaze_vng4_demosaic_RT(int winw, int winh, array2D &rawData, array2D &red, array2D &green, array2D &blue, double contrast) { BENCHFUN - vng4_demosaic (); - array2D redTmp(winw, winh); - array2D greenTmp(winw, winh); - array2D blueTmp(winw, winh); - array2D L(winw, winh); - amaze_demosaic_RT (0, 0, winw, winh, rawData, redTmp, greenTmp, blueTmp); - const float xyz_rgb[3][3] = { // XYZ from RGB - { 0.412453, 0.357580, 0.180423 }, - { 0.212671, 0.715160, 0.072169 }, - { 0.019334, 0.119193, 0.950227 } - }; - #pragma omp parallel - { - #pragma omp for - for(int i = 0; i < winh; ++i) { - Color::RGB2L(redTmp[i], greenTmp[i], blueTmp[i], L[i], xyz_rgb, winw); - } - } - // calculate contrast based blend factors to reduce sharpening in regions with low contrast - JaggedArray blend(winw, winh); - buildBlendMask(L, blend, winw, winh, 20.f / 100.f); - #pragma omp parallel for - for(int i = 0; i < winh; ++i) { - for(int j = 0; j < winw; ++j) { - red[i][j] = intp(blend[i][j], redTmp[i][j], red[i][j]); - green[i][j] = intp(blend[i][j], greenTmp[i][j], green[i][j]); - blue[i][j] = intp(blend[i][j], blueTmp[i][j], blue[i][j]); - } - } + if (contrast == 0.0) { + // contrast == 0.0 means only AMaZE will be used + amaze_demosaic_RT (0, 0, winw, winh, rawData, red, green, blue); + return; + } + + vng4_demosaic (); + array2D redTmp(winw, winh); + array2D greenTmp(winw, winh); + array2D blueTmp(winw, winh); + array2D L(winw, winh); + amaze_demosaic_RT (0, 0, winw, winh, rawData, redTmp, greenTmp, blueTmp); + const float xyz_rgb[3][3] = { // XYZ from RGB + { 0.412453, 0.357580, 0.180423 }, + { 0.212671, 0.715160, 0.072169 }, + { 0.019334, 0.119193, 0.950227 } + }; + #pragma omp parallel + { + #pragma omp for + for(int i = 0; i < winh; ++i) { + Color::RGB2L(redTmp[i], greenTmp[i], blueTmp[i], L[i], xyz_rgb, winw); + } + } + // calculate contrast based blend factors to reduce sharpening in regions with low contrast + JaggedArray blend(winw, winh); + buildBlendMask(L, blend, winw, winh, contrast / 100.f); + + // the following is split into 3 loops intentionally to avoid cache conflicts on CPUs with only 4-way cache + #pragma omp parallel for + for(int i = 0; i < winh; ++i) { + for(int j = 0; j < winw; ++j) { + red[i][j] = intp(blend[i][j], redTmp[i][j], red[i][j]); + } + } + #pragma omp parallel for + for(int i = 0; i < winh; ++i) { + for(int j = 0; j < winw; ++j) { + green[i][j] = intp(blend[i][j], greenTmp[i][j], green[i][j]); + } + } + #pragma omp parallel for + for(int i = 0; i < winh; ++i) { + for(int j = 0; j < winw; ++j) { + blue[i][j] = intp(blend[i][j], blueTmp[i][j], blue[i][j]); + } + } } } diff --git a/rtengine/color.cc b/rtengine/color.cc index 5fb8d27d8..3cedcaaa6 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -1855,7 +1855,7 @@ void Color::RGB2L(float *R, float *G, float *B, float *L, const float wp[3][3], vmask maxMask = vmaskf_gt(yv, maxvalfv); vmask minMask = vmaskf_lt(yv, minvalfv); - if (_mm_movemask_ps((vfloat)maxMask) || _mm_movemask_ps((vfloat)minMask)) { + if (_mm_movemask_ps((vfloat)vorm(maxMask, minMask))) { // take slower code path for all 4 pixels if one of the values is > MAXVALF. Still faster than non SSE2 version for(int k = 0; k < 4; ++k) { float y = yv[k]; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index ec6df6ace..eb47d29db 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2357,6 +2357,7 @@ RAWParams::BayerSensor::BayerSensor() : greenthresh(0), dcb_iterations(2), lmmse_iterations(2), + dualDemosaicContrast(20), pixelShiftMotionCorrectionMethod(PSMotionCorrectionMethod::AUTO), pixelShiftEperIso(0.0), pixelShiftSigma(1.0), @@ -2392,6 +2393,7 @@ bool RAWParams::BayerSensor::operator ==(const BayerSensor& other) const && greenthresh == other.greenthresh && dcb_iterations == other.dcb_iterations && lmmse_iterations == other.lmmse_iterations + && dualDemosaicContrast == other.dualDemosaicContrast && pixelShiftMotionCorrectionMethod == other.pixelShiftMotionCorrectionMethod && pixelShiftEperIso == other.pixelShiftEperIso && pixelShiftSigma == other.pixelShiftSigma @@ -3333,6 +3335,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->raw.bayersensor.dcbIterations, "RAW Bayer", "DCBIterations", raw.bayersensor.dcb_iterations, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.dcbEnhance, "RAW Bayer", "DCBEnhance", raw.bayersensor.dcb_enhance, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.lmmseIterations, "RAW Bayer", "LMMSEIterations", raw.bayersensor.lmmse_iterations, keyFile); + saveToKeyfile(!pedited || pedited->raw.bayersensor.dualDemosaicContrast, "RAW Bayer", "DualDemosaicContrast", raw.bayersensor.dualDemosaicContrast, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftMotionCorrectionMethod, "RAW Bayer", "PixelShiftMotionCorrectionMethod", toUnderlying(raw.bayersensor.pixelShiftMotionCorrectionMethod), keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftEperIso, "RAW Bayer", "PixelShiftEperIso", raw.bayersensor.pixelShiftEperIso, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftSigma, "RAW Bayer", "PixelShiftSigma", raw.bayersensor.pixelShiftSigma, keyFile); @@ -4622,6 +4625,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "RAW", "DCBIterations", pedited, raw.bayersensor.dcb_iterations, pedited->raw.bayersensor.dcbIterations); assignFromKeyfile(keyFile, "RAW", "DCBEnhance", pedited, raw.bayersensor.dcb_enhance, pedited->raw.bayersensor.dcbEnhance); assignFromKeyfile(keyFile, "RAW", "LMMSEIterations", pedited, raw.bayersensor.lmmse_iterations, pedited->raw.bayersensor.lmmseIterations); + assignFromKeyfile(keyFile, "RAW", "DualDemosaicContrast", pedited, raw.bayersensor.dualDemosaicContrast, pedited->raw.bayersensor.dualDemosaicContrast); assignFromKeyfile(keyFile, "RAW", "PreBlackzero", pedited, raw.bayersensor.black0, pedited->raw.bayersensor.exBlack0); assignFromKeyfile(keyFile, "RAW", "PreBlackone", pedited, raw.bayersensor.black1, pedited->raw.bayersensor.exBlack1); assignFromKeyfile(keyFile, "RAW", "PreBlacktwo", pedited, raw.bayersensor.black2, pedited->raw.bayersensor.exBlack2); @@ -4658,6 +4662,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "RAW Bayer", "DCBIterations", pedited, raw.bayersensor.dcb_iterations, pedited->raw.bayersensor.dcbIterations); assignFromKeyfile(keyFile, "RAW Bayer", "DCBEnhance", pedited, raw.bayersensor.dcb_enhance, pedited->raw.bayersensor.dcbEnhance); assignFromKeyfile(keyFile, "RAW Bayer", "LMMSEIterations", pedited, raw.bayersensor.lmmse_iterations, pedited->raw.bayersensor.lmmseIterations); + assignFromKeyfile(keyFile, "RAW Bayer", "DualDemosaicContrast", pedited, raw.bayersensor.dualDemosaicContrast, pedited->raw.bayersensor.dualDemosaicContrast); if (keyFile.has_key ("RAW Bayer", "PixelShiftMotionCorrectionMethod")) { raw.bayersensor.pixelShiftMotionCorrectionMethod = (RAWParams::BayerSensor::PSMotionCorrectionMethod)keyFile.get_integer ("RAW Bayer", "PixelShiftMotionCorrectionMethod"); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index e6a253955..be7784e1b 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1264,6 +1264,7 @@ struct RAWParams { int greenthresh; int dcb_iterations; int lmmse_iterations; + double dualDemosaicContrast; PSMotionCorrectionMethod pixelShiftMotionCorrectionMethod; double pixelShiftEperIso; double pixelShiftSigma; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 9f217e357..ce300bcd7 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -2074,7 +2074,7 @@ void RawImageSource::demosaic(const RAWParams &raw) } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZE) ) { amaze_demosaic_RT (0, 0, W, H, rawData, red, green, blue); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEVNG4) ) { - amaze_vng4_demosaic_RT (W, H, rawData, red, green, blue); + amaze_vng4_demosaic_RT (W, H, rawData, red, green, blue, raw.bayersensor.dualDemosaicContrast); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::PIXELSHIFT) ) { pixelshift(0, 0, W, H, raw.bayersensor, currFrame, ri->get_maker(), ri->get_model(), raw.expos); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::DCB) ) { diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index b188fdd69..e2467dba6 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -268,7 +268,7 @@ protected: void igv_interpolate(int winw, int winh); void lmmse_interpolate_omp(int winw, int winh, array2D &rawData, array2D &red, array2D &green, array2D &blue, int iterations); void amaze_demosaic_RT(int winx, int winy, int winw, int winh, array2D &rawData, array2D &red, array2D &green, array2D &blue);//Emil's code for AMaZE - void amaze_vng4_demosaic_RT(int winw, int winh, array2D &rawData, array2D &red, array2D &green, array2D &blue);//Emil's code for AMaZE + void amaze_vng4_demosaic_RT(int winw, int winh, array2D &rawData, array2D &red, array2D &green, array2D &blue, double contrast = 0.0); void fast_demosaic();//Emil's code for fast demosaicing void dcb_demosaic(int iterations, bool dcb_enhance); void ahd_demosaic(); diff --git a/rtgui/bayerprocess.cc b/rtgui/bayerprocess.cc index 73fea1aa3..d08ec0393 100644 --- a/rtgui/bayerprocess.cc +++ b/rtgui/bayerprocess.cc @@ -17,6 +17,7 @@ * along with RawTherapee. If not, see . */ #include "bayerprocess.h" +#include "eventmapper.h" #include "options.h" #include "guiutils.h" using namespace rtengine; @@ -25,6 +26,10 @@ using namespace rtengine::procparams; BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RAW_LABEL"), true) { + + auto m = ProcEventMapper::getInstance(); + EvDemosaicContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_DUALDEMOSAIC_CONTRAST"); + Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ()); hb1->pack_start (*Gtk::manage (new Gtk::Label ( M("TP_RAW_DMETHOD") + ": ")), Gtk::PACK_SHRINK, 4); method = Gtk::manage (new MyComboBoxText ()); @@ -93,6 +98,20 @@ BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RA lmmseOptions->pack_start(*lmmseIterations); pack_start( *lmmseOptions, Gtk::PACK_SHRINK, 4); + dualDemosaicOptions = Gtk::manage (new Gtk::VBox ()); + + dualDemosaicContrast = Gtk::manage(new Adjuster (M("TP_RAW_DUALDEMOSAICCONTRAST"), 0, 200, 1, 20)); + dualDemosaicContrast->setAdjusterListener (this); +// dualDemosaicContrast->set_tooltip_markup (M("TP_RAW_LMMSE_TOOLTIP")); + + if (dualDemosaicContrast->delay < options.adjusterMaxDelay) { + dualDemosaicContrast->delay = options.adjusterMaxDelay; + } + + dualDemosaicContrast->show(); + dualDemosaicOptions->pack_start(*dualDemosaicContrast); + pack_start( *dualDemosaicOptions, Gtk::PACK_SHRINK, 4); + pixelShiftFrame = Gtk::manage (new Gtk::VBox ()); pixelShiftFrame->set_border_width(0); @@ -248,6 +267,7 @@ 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); + dualDemosaicContrast->setValue (pp->raw.bayersensor.dualDemosaicContrast); pixelShiftMotionMethod->set_active ((int)pp->raw.bayersensor.pixelShiftMotionCorrectionMethod); pixelShiftEperIso->setValue (pp->raw.bayersensor.pixelShiftEperIso); pixelShiftSigma->setValue (pp->raw.bayersensor.pixelShiftSigma); @@ -271,6 +291,7 @@ 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); + dualDemosaicContrast->setEditedState ( pedited->raw.bayersensor.dualDemosaicContrast ? Edited : UnEdited); pixelShiftEperIso->setEditedState ( pedited->raw.bayersensor.pixelShiftEperIso ? Edited : UnEdited); pixelShiftSigma->setEditedState ( pedited->raw.bayersensor.pixelShiftSigma ? Edited : UnEdited); @@ -298,6 +319,12 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params } else { lmmseOptions->hide(); } + if (pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::AMAZEVNG4) || + method->get_active_row_number() == std::numeric_limits::max()) { + dualDemosaicOptions->show(); + } else { + dualDemosaicOptions->hide(); + } if (pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::PIXELSHIFT) || method->get_active_row_number() == std::numeric_limits::max()) { if(pp->raw.bayersensor.pixelShiftMotionCorrectionMethod == RAWParams::BayerSensor::PSMotionCorrectionMethod::CUSTOM) { @@ -335,6 +362,7 @@ void BayerProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pe pp->raw.bayersensor.dcb_enhance = dcbEnhance->getLastActive (); //pp->raw.bayersensor.all_enhance = allEnhance->getLastActive (); pp->raw.bayersensor.lmmse_iterations = lmmseIterations->getIntValue(); + pp->raw.bayersensor.dualDemosaicContrast = dualDemosaicContrast->getValue(); pp->raw.bayersensor.pixelShiftMotionCorrectionMethod = (RAWParams::BayerSensor::PSMotionCorrectionMethod)pixelShiftMotionMethod->get_active_row_number(); pp->raw.bayersensor.pixelShiftEperIso = pixelShiftEperIso->getValue(); pp->raw.bayersensor.pixelShiftSigma = pixelShiftSigma->getValue(); @@ -369,6 +397,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.dualDemosaicContrast = dualDemosaicContrast->getEditedState (); pedited->raw.bayersensor.pixelShiftMotionCorrectionMethod = pixelShiftMotionMethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->raw.bayersensor.pixelShiftEperIso = pixelShiftEperIso->getEditedState (); pedited->raw.bayersensor.pixelShiftSigma = pixelShiftSigma->getEditedState (); @@ -398,6 +427,7 @@ void BayerProcess::setBatchMode(bool batchMode) ccSteps->showEditedCB (); dcbIterations->showEditedCB (); lmmseIterations->showEditedCB (); + dualDemosaicContrast->showEditedCB (); pixelShiftEperIso->showEditedCB (); pixelShiftSigma->showEditedCB (); } @@ -406,6 +436,7 @@ void BayerProcess::setDefaults(const rtengine::procparams::ProcParams* defParams { dcbIterations->setDefault( defParams->raw.bayersensor.dcb_iterations); lmmseIterations->setDefault( defParams->raw.bayersensor.lmmse_iterations); + dualDemosaicContrast->setDefault( defParams->raw.bayersensor.dualDemosaicContrast); pixelShiftEperIso->setDefault( defParams->raw.bayersensor.pixelShiftEperIso); pixelShiftSigma->setDefault( defParams->raw.bayersensor.pixelShiftSigma); ccSteps->setDefault (defParams->raw.bayersensor.ccSteps); @@ -413,12 +444,14 @@ void BayerProcess::setDefaults(const rtengine::procparams::ProcParams* defParams if (pedited) { dcbIterations->setDefaultEditedState( pedited->raw.bayersensor.dcbIterations ? Edited : UnEdited); lmmseIterations->setDefaultEditedState( pedited->raw.bayersensor.lmmseIterations ? Edited : UnEdited); + dualDemosaicContrast->setDefaultEditedState( pedited->raw.bayersensor.dualDemosaicContrast ? Edited : UnEdited); pixelShiftEperIso->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftEperIso ? Edited : UnEdited); pixelShiftSigma->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftSigma ? Edited : UnEdited); ccSteps->setDefaultEditedState(pedited->raw.bayersensor.ccSteps ? Edited : UnEdited); } else { dcbIterations->setDefaultEditedState( Irrelevant ); lmmseIterations->setDefaultEditedState( Irrelevant ); + dualDemosaicContrast->setDefaultEditedState( Irrelevant ); pixelShiftEperIso->setDefaultEditedState( Irrelevant ); pixelShiftSigma->setDefaultEditedState( Irrelevant ); ccSteps->setDefaultEditedState(Irrelevant ); @@ -434,6 +467,8 @@ void BayerProcess::adjusterChanged (Adjuster* a, double newval) listener->panelChanged (EvDemosaicFalseColorIter, a->getTextValue() ); } else if (a == lmmseIterations) { listener->panelChanged (EvDemosaicLMMSEIter, a->getTextValue() ); + } else if (a == dualDemosaicContrast) { + listener->panelChanged (EvDemosaicContrast, a->getTextValue() ); } else if (a == pixelShiftEperIso) { listener->panelChanged (EvPixelShiftEperIso, a->getTextValue() ); } else if (a == pixelShiftSigma) { @@ -462,6 +497,12 @@ void BayerProcess::methodChanged () lmmseOptions->hide(); } + if (method == procparams::RAWParams::BayerSensor::Method::AMAZEVNG4) { + dualDemosaicOptions->show(); + } else { + dualDemosaicOptions->hide(); + } + if (method == procparams::RAWParams::BayerSensor::Method::PIXELSHIFT) { if(pixelShiftMotionMethod->get_active_row_number() == 2) { pixelShiftOptions->show(); diff --git a/rtgui/bayerprocess.h b/rtgui/bayerprocess.h index 48b445d90..84701a52e 100644 --- a/rtgui/bayerprocess.h +++ b/rtgui/bayerprocess.h @@ -55,9 +55,12 @@ protected: Adjuster* pixelShiftSmooth; Adjuster* pixelShiftEperIso; Adjuster* pixelShiftSigma; + Gtk::VBox *dualDemosaicOptions; + Adjuster* dualDemosaicContrast; int oldMethod; IdleRegister idle_register; + rtengine::ProcEvent EvDemosaicContrast; public: BayerProcess (); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 0eebe2e41..bf5a63fa8 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -403,6 +403,7 @@ void ParamsEdited::set (bool v) raw.bayersensor.dcbEnhance = v; //raw.bayersensor.allEnhance = v; raw.bayersensor.lmmseIterations = v; + raw.bayersensor.dualDemosaicContrast = v; raw.bayersensor.pixelShiftMotionCorrectionMethod = v; raw.bayersensor.pixelShiftEperIso = v; raw.bayersensor.pixelShiftSigma = v; @@ -952,6 +953,7 @@ void ParamsEdited::initFrom (const std::vector raw.bayersensor.dcbEnhance = raw.bayersensor.dcbEnhance && p.raw.bayersensor.dcb_enhance == other.raw.bayersensor.dcb_enhance; //raw.bayersensor.allEnhance = raw.bayersensor.allEnhance && p.raw.bayersensor.all_enhance == other.raw.bayersensor.all_enhance; raw.bayersensor.lmmseIterations = raw.bayersensor.lmmseIterations && p.raw.bayersensor.lmmse_iterations == other.raw.bayersensor.lmmse_iterations; + raw.bayersensor.dualDemosaicContrast = raw.bayersensor.dualDemosaicContrast && p.raw.bayersensor.dualDemosaicContrast == other.raw.bayersensor.dualDemosaicContrast; raw.bayersensor.pixelShiftMotionCorrectionMethod = raw.bayersensor.pixelShiftMotionCorrectionMethod && p.raw.bayersensor.pixelShiftMotionCorrectionMethod == other.raw.bayersensor.pixelShiftMotionCorrectionMethod; raw.bayersensor.pixelShiftEperIso = raw.bayersensor.pixelShiftEperIso && p.raw.bayersensor.pixelShiftEperIso == other.raw.bayersensor.pixelShiftEperIso; raw.bayersensor.pixelShiftSigma = raw.bayersensor.pixelShiftSigma && p.raw.bayersensor.pixelShiftSigma == other.raw.bayersensor.pixelShiftSigma; @@ -2496,6 +2498,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.raw.bayersensor.lmmse_iterations = mods.raw.bayersensor.lmmse_iterations; } + if (raw.bayersensor.dualDemosaicContrast) { + toEdit.raw.bayersensor.dualDemosaicContrast = mods.raw.bayersensor.dualDemosaicContrast; + } + if (raw.bayersensor.pixelShiftMotionCorrectionMethod) { toEdit.raw.bayersensor.pixelShiftMotionCorrectionMethod = mods.raw.bayersensor.pixelShiftMotionCorrectionMethod; } @@ -3072,7 +3078,7 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten bool RAWParamsEdited::BayerSensor::isUnchanged() const { - return method && imageNum && dcbIterations && dcbEnhance && lmmseIterations/*&& allEnhance*/ && greenEq + return method && imageNum && dcbIterations && dcbEnhance && lmmseIterations && dualDemosaicContrast /*&& allEnhance*/ && greenEq && pixelShiftMotionCorrectionMethod && pixelShiftEperIso && pixelShiftSigma && pixelShiftShowMotion && pixelShiftShowMotionMaskOnly && pixelShiftHoleFill && pixelShiftMedian && pixelShiftNonGreenCross && pixelShiftGreen && pixelShiftBlur && pixelShiftSmooth && pixelShiftLmmse && pixelShiftEqualBright && pixelShiftEqualBrightChannel && linenoise && linenoiseDirection && pdafLinesFilter && exBlack0 && exBlack1 && exBlack2 && exBlack3 && exTwoGreen; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 47fb70ef0..5b3370b9a 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -731,6 +731,7 @@ public: bool dcbIterations; bool dcbEnhance; bool lmmseIterations; + bool dualDemosaicContrast; bool pixelShiftMotionCorrectionMethod; bool pixelShiftEperIso; bool pixelShiftSigma;