From 8b65900066854ff496998194a0a3ee9dbd044127 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Sun, 21 Oct 2018 20:21:43 +0200 Subject: [PATCH] Dual demosaic: Add auto threshold checkbox and show used value in ui, #4866 --- rtdata/languages/default | 4 ++- rtengine/dual_demosaic_RT.cc | 7 ++-- rtengine/improccoordinator.cc | 13 ++++++-- rtengine/improccoordinator.h | 12 +++++++ rtengine/ipsharpen.cc | 18 ++++++---- rtengine/procparams.cc | 20 +++++++++++ rtengine/procparams.h | 2 ++ rtengine/rt_algo.cc | 15 ++++----- rtengine/rt_algo.h | 2 +- rtengine/rtengine.h | 9 +++++ rtgui/bayerprocess.cc | 63 +++++++++++++++++++++++------------ rtgui/bayerprocess.h | 6 +++- rtgui/paramsedited.cc | 16 +++++++-- rtgui/paramsedited.h | 2 ++ rtgui/ppversion.h | 4 ++- rtgui/toolpanelcoord.cc | 2 ++ rtgui/toolpanelcoord.h | 2 ++ rtgui/xtransprocess.cc | 44 ++++++++++++++++++++++++ rtgui/xtransprocess.h | 9 ++++- 19 files changed, 201 insertions(+), 49 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 4ac12a093..72a76a75a 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -728,7 +728,8 @@ HISTORY_MSG_492;RGB Curves HISTORY_MSG_493;L*a*b* Adjustments HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction -HISTORY_MSG_DUALDEMOSAIC_CONTRAST;AMaZE+VNG4 - Contrast threshold +HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold HISTORY_MSG_HISTMATCHING;Auto-matched tone curve HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1815,6 +1816,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_DUALDEMOSAICAUTOCONTRAST;Auto threshold 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 862516416..1498f600c 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.0 && !autoContrast) { + if (contrast == 0.f) { // contrast == 0.0 means only first demosaicer will be used if(isBayer) { if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEVNG4) ) { @@ -100,7 +100,10 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const RAWParams &raw, int wi } // calculate contrast based blend factors to use vng4 in regions with low contrast JaggedArray blend(winw, winh); - buildBlendMask(L, blend, winw, winh, contrast / 100.f, 1.f, true); + float contrastf = contrast / 100.f; + + buildBlendMask(L, blend, winw, winh, contrastf, 1.f, autoContrast); + contrast = contrastf * 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 diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 832d193a2..f81aabd30 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -93,7 +93,7 @@ ImProcCoordinator::ImProcCoordinator() fw(0), fh(0), tr(0), fullw(1), fullh(1), pW(-1), pH(-1), - plistener(nullptr), imageListener(nullptr), aeListener(nullptr), acListener(nullptr), abwListener(nullptr), awbListener(nullptr), frameCountListener(nullptr), imageTypeListener(nullptr), actListener(nullptr), adnListener(nullptr), awavListener(nullptr), dehaListener(nullptr), hListener(nullptr), + plistener(nullptr), imageListener(nullptr), aeListener(nullptr), acListener(nullptr), abwListener(nullptr), awbListener(nullptr), bayerAutoContrastListener(nullptr), xtransAutoContrastListener(nullptr), frameCountListener(nullptr), imageTypeListener(nullptr), actListener(nullptr), adnListener(nullptr), awavListener(nullptr), dehaListener(nullptr), hListener(nullptr), resultValid(false), lastOutputProfile("BADFOOD"), lastOutputIntent(RI__COUNT), lastOutputBPC(false), thread(nullptr), changeSinceLast(0), updaterRunning(false), destroying(false), utili(false), autili(false), butili(false), ccutili(false), cclutili(false), clcutili(false), opautili(false), wavcontlutili(false), colourToningSatLimit(0.f), colourToningSatLimitOpacity(0.f), highQualityComputed(false) {} @@ -239,10 +239,17 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) imgsrc->setBorder(std::max(params.raw.bayersensor.border, 2)); } } - bool autoContrast = false; - double contrastThreshold = 0.f; + bool autoContrast = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicAutoContrast : params.raw.xtranssensor.dualDemosaicAutoContrast; + double contrastThreshold = params.raw.bayersensor.dualDemosaicContrast; imgsrc->demosaic(rp, autoContrast, contrastThreshold); //enabled demosaic + if (imgsrc->getSensorType() == ST_BAYER && bayerAutoContrastListener) { + bayerAutoContrastListener->autoContrastChanged(autoContrast ? contrastThreshold : -1.0); + } + if (imgsrc->getSensorType() == ST_FUJI_XTRANS && xtransAutoContrastListener) { + xtransAutoContrastListener->autoContrastChanged(autoContrast ? contrastThreshold : -1.0); + } + // if a demosaic happened we should also call getimage later, so we need to set the M_INIT flag todo |= M_INIT; diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index dba12cdd7..1c87ff4cd 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -158,6 +158,8 @@ protected: AutoCamListener* acListener; AutoBWListener* abwListener; AutoWBListener* awbListener; + AutoContrastListener *bayerAutoContrastListener; + AutoContrastListener *xtransAutoContrastListener; FrameCountListener *frameCountListener; ImageTypeListener *imageTypeListener; @@ -344,6 +346,16 @@ public: frameCountListener = fcl; } + void setBayerAutoContrastListener (AutoContrastListener* acl) + { + bayerAutoContrastListener = acl; + } + + void setXtransAutoContrastListener (AutoContrastListener* acl) + { + xtransAutoContrastListener = acl; + } + void setImageTypeListener (ImageTypeListener* itl) { imageTypeListener = itl; diff --git a/rtengine/ipsharpen.cc b/rtengine/ipsharpen.cc index eaf0db732..a84132a4c 100644 --- a/rtengine/ipsharpen.cc +++ b/rtengine/ipsharpen.cc @@ -176,7 +176,8 @@ BENCHFUN // calculate contrast based blend factors to reduce sharpening in regions with low contrast JaggedArray blend(W, H); - buildBlendMask(luminance, blend, W, H, sharpenParam.contrast / 100.f, sharpenParam.deconvamount / 100.0); + float contrast = sharpenParam.contrast / 100.f; + buildBlendMask(luminance, blend, W, H, contrast, sharpenParam.deconvamount / 100.0); const float damping = sharpenParam.deconvdamping / 5.0; const bool needdamp = sharpenParam.deconvdamping > 0; @@ -222,7 +223,8 @@ void ImProcFunctions::sharpening (LabImage* lab, const SharpeningParams &sharpen if(showMask) { // calculate contrast based blend factors to reduce sharpening in regions with low contrast JaggedArray blend(W, H); - buildBlendMask(lab->L, blend, W, H, sharpenParam.contrast / 100.f, sharpenParam.method == "rld" ? sharpenParam.deconvamount / 100.0 : 1.f); + float contrast = sharpenParam.contrast / 100.f; + buildBlendMask(lab->L, blend, W, H, contrast, sharpenParam.method == "rld" ? sharpenParam.deconvamount / 100.0 : 1.f); #ifdef _OPENMP #pragma omp parallel for #endif @@ -256,7 +258,8 @@ BENCHFUN // calculate contrast based blend factors to reduce sharpening in regions with low contrast JaggedArray blend(W, H); - buildBlendMask(lab->L, blend, W, H, sharpenParam.contrast / 100.f); + float contrast = sharpenParam.contrast / 100.f; + buildBlendMask(lab->L, blend, W, H, contrast); #ifdef _OPENMP #pragma omp parallel @@ -610,7 +613,8 @@ BENCHFUN // calculate contrast based blend factors to reduce sharpening in regions with low contrast JaggedArray blend(W, H); - buildBlendMask(luminance, blend, W, H, params->sharpenMicro.contrast / 100.f); + float contrast = params->sharpenMicro.contrast / 100.f; + buildBlendMask(luminance, blend, W, H, contrast); #ifdef _OPENMP #pragma omp parallel @@ -819,7 +823,8 @@ void ImProcFunctions::sharpeningcam (CieImage* ncie, float** b2, bool showMask) if(showMask) { // calculate contrast based blend factors to reduce sharpening in regions with low contrast JaggedArray blend(W, H); - buildBlendMask(ncie->sh_p, blend, W, H, params->sharpening.contrast / 100.f); + float contrast = params->sharpening.contrast / 100.f; + buildBlendMask(ncie->sh_p, blend, W, H, contrast); #ifdef _OPENMP #pragma omp parallel for #endif @@ -852,7 +857,8 @@ void ImProcFunctions::sharpeningcam (CieImage* ncie, float** b2, bool showMask) // calculate contrast based blend factors to reduce sharpening in regions with low contrast JaggedArray blend(W, H); - buildBlendMask(ncie->sh_p, blend, W, H, params->sharpening.contrast / 100.f); + float contrast = params->sharpening.contrast / 100.f; + buildBlendMask(ncie->sh_p, blend, W, H, contrast); #ifdef _OPENMP #pragma omp parallel diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index d8d6aee33..f8df8ee63 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2388,6 +2388,7 @@ RAWParams::BayerSensor::BayerSensor() : greenthresh(0), dcb_iterations(2), lmmse_iterations(2), + dualDemosaicAutoContrast(true), dualDemosaicContrast(20), pixelShiftMotionCorrectionMethod(PSMotionCorrectionMethod::AUTO), pixelShiftEperIso(0.0), @@ -2425,6 +2426,7 @@ bool RAWParams::BayerSensor::operator ==(const BayerSensor& other) const && greenthresh == other.greenthresh && dcb_iterations == other.dcb_iterations && lmmse_iterations == other.lmmse_iterations + && dualDemosaicAutoContrast == other.dualDemosaicAutoContrast && dualDemosaicContrast == other.dualDemosaicContrast && pixelShiftMotionCorrectionMethod == other.pixelShiftMotionCorrectionMethod && pixelShiftEperIso == other.pixelShiftEperIso @@ -2512,6 +2514,7 @@ Glib::ustring RAWParams::BayerSensor::getPSDemosaicMethodString(PSDemosaicMethod RAWParams::XTransSensor::XTransSensor() : method(getMethodString(Method::THREE_PASS)), + dualDemosaicAutoContrast(true), dualDemosaicContrast(20), ccSteps(0), blackred(0.0), @@ -2524,6 +2527,7 @@ bool RAWParams::XTransSensor::operator ==(const XTransSensor& other) const { return method == other.method + && dualDemosaicAutoContrast == other.dualDemosaicAutoContrast && dualDemosaicContrast == other.dualDemosaicContrast && ccSteps == other.ccSteps && blackred == other.blackred @@ -3409,6 +3413,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.dualDemosaicAutoContrast, "RAW Bayer", "DualDemosaicAutoContrast", raw.bayersensor.dualDemosaicAutoContrast, 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); @@ -3426,6 +3431,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftDemosaicMethod, "RAW Bayer", "pixelShiftDemosaicMethod", raw.bayersensor.pixelShiftDemosaicMethod, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pdafLinesFilter, "RAW Bayer", "PDAFLinesFilter", raw.bayersensor.pdafLinesFilter, keyFile); saveToKeyfile(!pedited || pedited->raw.xtranssensor.method, "RAW X-Trans", "Method", raw.xtranssensor.method, keyFile); + saveToKeyfile(!pedited || pedited->raw.xtranssensor.dualDemosaicAutoContrast, "RAW X-Trans", "DualDemosaicAutoContrast", raw.xtranssensor.dualDemosaicAutoContrast, keyFile); saveToKeyfile(!pedited || pedited->raw.xtranssensor.dualDemosaicContrast, "RAW X-Trans", "DualDemosaicContrast", raw.xtranssensor.dualDemosaicContrast, keyFile); saveToKeyfile(!pedited || pedited->raw.xtranssensor.ccSteps, "RAW X-Trans", "CcSteps", raw.xtranssensor.ccSteps, keyFile); saveToKeyfile(!pedited || pedited->raw.xtranssensor.exBlackRed, "RAW X-Trans", "PreBlackRed", raw.xtranssensor.blackred, keyFile); @@ -4836,6 +4842,13 @@ 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", "DualDemosaicAutoContrast", pedited, raw.bayersensor.dualDemosaicAutoContrast, pedited->raw.bayersensor.dualDemosaicAutoContrast); + if (ppVersion < 344) { + raw.bayersensor.dualDemosaicAutoContrast = false; + if (pedited) { + pedited->raw.bayersensor.dualDemosaicAutoContrast = true; + } + } assignFromKeyfile(keyFile, "RAW Bayer", "DualDemosaicContrast", pedited, raw.bayersensor.dualDemosaicContrast, pedited->raw.bayersensor.dualDemosaicContrast); if (keyFile.has_key("RAW Bayer", "PixelShiftMotionCorrectionMethod")) { @@ -4883,6 +4896,13 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) if (keyFile.has_group("RAW X-Trans")) { assignFromKeyfile(keyFile, "RAW X-Trans", "Method", pedited, raw.xtranssensor.method, pedited->raw.xtranssensor.method); + assignFromKeyfile(keyFile, "RAW X-Trans", "DualDemosaicAutoContrast", pedited, raw.xtranssensor.dualDemosaicAutoContrast, pedited->raw.xtranssensor.dualDemosaicAutoContrast); + if (ppVersion < 344) { + raw.xtranssensor.dualDemosaicAutoContrast = false; + if (pedited) { + pedited->raw.xtranssensor.dualDemosaicAutoContrast = true; + } + } assignFromKeyfile(keyFile, "RAW X-Trans", "DualDemosaicContrast", pedited, raw.xtranssensor.dualDemosaicContrast, pedited->raw.xtranssensor.dualDemosaicContrast); assignFromKeyfile(keyFile, "RAW X-Trans", "CcSteps", pedited, raw.xtranssensor.ccSteps, pedited->raw.xtranssensor.ccSteps); assignFromKeyfile(keyFile, "RAW X-Trans", "PreBlackRed", pedited, raw.xtranssensor.blackred, pedited->raw.xtranssensor.exBlackRed); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 0b8b5ba56..d8fa89a64 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1285,6 +1285,7 @@ struct RAWParams { int greenthresh; int dcb_iterations; int lmmse_iterations; + bool dualDemosaicAutoContrast; double dualDemosaicContrast; PSMotionCorrectionMethod pixelShiftMotionCorrectionMethod; double pixelShiftEperIso; @@ -1332,6 +1333,7 @@ struct RAWParams { }; Glib::ustring method; + bool dualDemosaicAutoContrast; double dualDemosaicContrast; int ccSteps; double blackred; diff --git a/rtengine/rt_algo.cc b/rtengine/rt_algo.cc index 71fa4fa6f..975b08374 100644 --- a/rtengine/rt_algo.cc +++ b/rtengine/rt_algo.cc @@ -34,7 +34,7 @@ #include "rt_math.h" #include "sleef.c" #include "jaggedarray.h" -#include "StopWatch.h" + namespace { float calcBlendFactor(float val, float threshold) { // sigmoid function @@ -192,7 +192,7 @@ void findMinMaxPercentile(const float* data, size_t size, float minPrct, float& maxOut += minVal; } -void buildBlendMask(float** luminance, float **blend, int W, int H, float contrastThreshold, float amount, bool autoContrast) { +void buildBlendMask(float** luminance, float **blend, int W, int H, float &contrastThreshold, float amount, bool autoContrast) { if(contrastThreshold == 0.f) { for(int j = 0; j < H; ++j) { @@ -203,7 +203,6 @@ void buildBlendMask(float** luminance, float **blend, int W, int H, float contra } else { constexpr float scale = 0.0625f / 327.68f; if (autoContrast) { - StopWatch StopC("calculate dual demosaic auto contrast threshold"); for (int pass = 0; pass < 2; ++pass) { const int tilesize = 80 / (pass + 1); const int numTilesW = W / tilesize; @@ -269,9 +268,8 @@ void buildBlendMask(float** luminance, float **blend, int W, int H, float contra const int minY = tilesize * minI; const int minX = tilesize * minJ; - std::cout << "minvar : " << minvar << std::endl; -// if (minvar <= 1.f || pass == 1) { + if (minvar <= 1.f || pass == 1) { // a variance <= 1 means we already found a flat region and can skip second pass JaggedArray Lum(tilesize, tilesize); JaggedArray Blend(tilesize, tilesize); @@ -281,9 +279,9 @@ void buildBlendMask(float** luminance, float **blend, int W, int H, float contra } } - /*contrastThreshold = */calcContrastThreshold(Lum, Blend, tilesize, tilesize);// / 100.f; -// break; -// } + contrastThreshold = std::min(contrastThreshold, calcContrastThreshold(Lum, Blend, tilesize, tilesize) / 100.f); + break; + } } } @@ -404,7 +402,6 @@ int calcContrastThreshold(float** luminance, float **blend, int W, int H) { break; } } - std::cout << "dual demosaic auto contrast threshold : " << c << std::endl; return c; } diff --git a/rtengine/rt_algo.h b/rtengine/rt_algo.h index 3a91c327b..0207e6f57 100644 --- a/rtengine/rt_algo.h +++ b/rtengine/rt_algo.h @@ -24,6 +24,6 @@ namespace rtengine { void findMinMaxPercentile(const float* data, size_t size, float minPrct, float& minOut, float maxPrct, float& maxOut, bool multiThread = true); -void buildBlendMask(float** luminance, float **blend, int W, int H, float contrastThreshold, float amount = 1.f, bool autoContrast = false); +void buildBlendMask(float** luminance, float **blend, int W, int H, float &contrastThreshold, float amount = 1.f, bool autoContrast = false); int calcContrastThreshold(float** luminance, float **blend, int W, int H); } diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index d26d82396..fcb00457a 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -365,6 +365,13 @@ public : virtual void imageTypeChanged (bool isRaw, bool isBayer, bool isXtrans, bool is_Mono = false) = 0; }; +class AutoContrastListener +{ +public : + virtual ~AutoContrastListener() = default; + virtual void autoContrastChanged (double autoContrast) = 0; +}; + class WaveletListener { public : @@ -470,6 +477,8 @@ public: virtual void setPreviewImageListener (PreviewImageListener* l) = 0; virtual void setAutoCamListener (AutoCamListener* l) = 0; virtual void setFrameCountListener (FrameCountListener* l) = 0; + virtual void setBayerAutoContrastListener (AutoContrastListener* l) = 0; + virtual void setXtransAutoContrastListener (AutoContrastListener* l) = 0; virtual void setAutoBWListener (AutoBWListener* l) = 0; virtual void setAutoWBListener (AutoWBListener* l) = 0; virtual void setAutoColorTonListener (AutoColorTonListener* l) = 0; diff --git a/rtgui/bayerprocess.cc b/rtgui/bayerprocess.cc index d68f5c2d3..ed9f86ab6 100644 --- a/rtgui/bayerprocess.cc +++ b/rtgui/bayerprocess.cc @@ -30,6 +30,7 @@ BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RA auto m = ProcEventMapper::getInstance(); EvDemosaicBorder = m->newEvent(DEMOSAIC, "HISTORY_MSG_RAW_BORDER"); EvDemosaicContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_DUALDEMOSAIC_CONTRAST"); + EvDemosaicAutoContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST"); EvDemosaicPixelshiftDemosaicMethod = m->newEvent(DEMOSAIC, "HISTORY_MSG_PIXELSHIFT_DEMOSAIC"); Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ()); @@ -46,17 +47,26 @@ BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RA hb1->pack_end (*method, Gtk::PACK_EXPAND_WIDGET, 4); pack_start( *hb1, Gtk::PACK_SHRINK, 4); + dualDemosaicOptions = Gtk::manage(new Gtk::VBox()); + Gtk::HBox* hbAutoContrast = Gtk::manage(new Gtk::HBox()); - dualDemosaicOptions = Gtk::manage (new Gtk::VBox ()); + dualDemosaicAutoContrast = Gtk::manage(new CheckBox(M("TP_RAW_DUALDEMOSAICAUTOCONTRAST"), multiImage)); + dualDemosaicAutoContrast->setCheckBoxListener(this); - dualDemosaicContrast = Gtk::manage(new Adjuster (M("TP_RAW_DUALDEMOSAICCONTRAST"), 0, 100, 1, 20)); - dualDemosaicContrast->setAdjusterListener (this); + dualDemosaicLabel = Gtk::manage(new Gtk::Label("")); + + dualDemosaicContrast = Gtk::manage(new Adjuster(M("TP_RAW_DUALDEMOSAICCONTRAST"), 0, 100, 1, 20)); + dualDemosaicContrast->setAdjusterListener(this); 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); @@ -300,6 +310,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); + dualDemosaicAutoContrast->setValue (pp->raw.bayersensor.dualDemosaicAutoContrast); dualDemosaicContrast->setValue (pp->raw.bayersensor.dualDemosaicContrast); pixelShiftMotionMethod->set_active ((int)pp->raw.bayersensor.pixelShiftMotionCorrectionMethod); pixelShiftEperIso->setValue (pp->raw.bayersensor.pixelShiftEperIso); @@ -324,6 +335,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); + dualDemosaicAutoContrast->setEdited ( pedited->raw.bayersensor.dualDemosaicAutoContrast ? 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); @@ -385,6 +397,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.dualDemosaicContrast = dualDemosaicContrast->getValue(); pp->raw.bayersensor.pixelShiftMotionCorrectionMethod = (RAWParams::BayerSensor::PSMotionCorrectionMethod)pixelShiftMotionMethod->get_active_row_number(); pp->raw.bayersensor.pixelShiftEperIso = pixelShiftEperIso->getValue(); @@ -425,6 +438,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.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"); @@ -603,7 +617,11 @@ void BayerProcess::imageNumberChanged () void BayerProcess::checkBoxToggled (CheckBox* c, CheckValue newval) { - if (c == dcbEnhance) { + if (c == dualDemosaicAutoContrast) { + if (listener) { + listener->panelChanged (EvDemosaicAutoContrast, dualDemosaicAutoContrast->getValueAsStr ()); + } + } else if (c == dcbEnhance) { if (listener) { listener->panelChanged (EvDemosaicDCBEnhanced, dcbEnhance->getValueAsStr ()); } @@ -711,23 +729,24 @@ void BayerProcess::FrameCountChanged(int n, int frameNum) }; idle_register.add(func, new Data { this, n, frameNum }); - - // GThreadLock lock; - // imageNumber->block (true); - - // imageNumber->remove_all(); - // imageNumber->append("1"); - // for(int i = 2; i <= std::min(n, 4); ++i) { - // std::ostringstream entry; - // entry << i; - // imageNumber->append(entry.str()); - // } - // imageNumber->set_active(std::min(frameNum, n - 1)); - // if(n == 1) { - // imageNumberBox->hide(); - // } else { - // imageNumberBox->show(); - // } - // imageNumber->block (false); } +void BayerProcess::autoContrastChanged (double autoContrast) +{ + struct Data { + BayerProcess *me; + 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)); + } + return FALSE; + }; + + idle_register.add(func, new Data { this, autoContrast }); +} diff --git a/rtgui/bayerprocess.h b/rtgui/bayerprocess.h index cfd063ca9..fe7163ffc 100644 --- a/rtgui/bayerprocess.h +++ b/rtgui/bayerprocess.h @@ -25,7 +25,7 @@ #include "guiutils.h" #include "toolpanel.h" -class BayerProcess : public ToolParamBlock, public AdjusterListener, public CheckBoxListener, public FoldableToolPanel, public rtengine::FrameCountListener +class BayerProcess : public ToolParamBlock, public AdjusterListener, public CheckBoxListener, public FoldableToolPanel, public rtengine::FrameCountListener, public rtengine::AutoContrastListener { protected: @@ -59,11 +59,14 @@ protected: Adjuster* pixelShiftSigma; Gtk::VBox *dualDemosaicOptions; Adjuster* dualDemosaicContrast; + CheckBox* dualDemosaicAutoContrast; + Gtk::Label* dualDemosaicLabel; int oldMethod; IdleRegister idle_register; rtengine::ProcEvent EvDemosaicBorder; + rtengine::ProcEvent EvDemosaicAutoContrast; rtengine::ProcEvent EvDemosaicContrast; rtengine::ProcEvent EvDemosaicPixelshiftDemosaicMethod; public: @@ -83,6 +86,7 @@ public: void checkBoxToggled(CheckBox* c, CheckValue newval); void pixelShiftMotionMethodChanged(); void pixelShiftDemosaicMethodChanged(); + void autoContrastChanged (double autoContrast); void FrameCountChanged(int n, int frameNum); }; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 2ccb62f65..04b8363f3 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -405,6 +405,7 @@ void ParamsEdited::set(bool v) raw.bayersensor.dcbEnhance = v; //raw.bayersensor.allEnhance = v; raw.bayersensor.lmmseIterations = v; + raw.bayersensor.dualDemosaicAutoContrast = v; raw.bayersensor.dualDemosaicContrast = v; raw.bayersensor.pixelShiftMotionCorrectionMethod = v; raw.bayersensor.pixelShiftEperIso = v; @@ -425,6 +426,7 @@ void ParamsEdited::set(bool v) raw.bayersensor.linenoiseDirection = v; raw.bayersensor.pdafLinesFilter = v; raw.xtranssensor.method = v; + raw.xtranssensor.dualDemosaicAutoContrast = v; raw.xtranssensor.dualDemosaicContrast = v; raw.xtranssensor.ccSteps = v; raw.xtranssensor.exBlackRed = v; @@ -962,6 +964,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.dualDemosaicAutoContrast = raw.bayersensor.dualDemosaicAutoContrast && p.raw.bayersensor.dualDemosaicAutoContrast == other.raw.bayersensor.dualDemosaicAutoContrast; 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; @@ -982,6 +985,7 @@ void ParamsEdited::initFrom(const std::vector& raw.bayersensor.linenoiseDirection = raw.bayersensor.linenoiseDirection && p.raw.bayersensor.linenoiseDirection == other.raw.bayersensor.linenoiseDirection; raw.bayersensor.pdafLinesFilter = raw.bayersensor.pdafLinesFilter && p.raw.bayersensor.pdafLinesFilter == other.raw.bayersensor.pdafLinesFilter; raw.xtranssensor.method = raw.xtranssensor.method && p.raw.xtranssensor.method == other.raw.xtranssensor.method; + raw.xtranssensor.dualDemosaicAutoContrast = raw.xtranssensor.dualDemosaicAutoContrast && p.raw.xtranssensor.dualDemosaicAutoContrast == other.raw.xtranssensor.dualDemosaicAutoContrast; raw.xtranssensor.dualDemosaicContrast = raw.xtranssensor.dualDemosaicContrast && p.raw.xtranssensor.dualDemosaicContrast == other.raw.xtranssensor.dualDemosaicContrast; raw.xtranssensor.ccSteps = raw.xtranssensor.ccSteps && p.raw.xtranssensor.ccSteps == other.raw.xtranssensor.ccSteps; raw.xtranssensor.exBlackRed = raw.xtranssensor.exBlackRed && p.raw.xtranssensor.blackred == other.raw.xtranssensor.blackred; @@ -2526,6 +2530,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.raw.bayersensor.lmmse_iterations = mods.raw.bayersensor.lmmse_iterations; } + if (raw.bayersensor.dualDemosaicAutoContrast) { + toEdit.raw.bayersensor.dualDemosaicAutoContrast = mods.raw.bayersensor.dualDemosaicAutoContrast; + } + if (raw.bayersensor.dualDemosaicContrast) { toEdit.raw.bayersensor.dualDemosaicContrast = mods.raw.bayersensor.dualDemosaicContrast; } @@ -2606,6 +2614,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.raw.xtranssensor.method = mods.raw.xtranssensor.method; } + if (raw.xtranssensor.dualDemosaicAutoContrast) { + toEdit.raw.xtranssensor.dualDemosaicAutoContrast = mods.raw.xtranssensor.dualDemosaicAutoContrast; + } + if (raw.xtranssensor.dualDemosaicContrast) { toEdit.raw.xtranssensor.dualDemosaicContrast = mods.raw.xtranssensor.dualDemosaicContrast; } @@ -3126,7 +3138,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng bool RAWParamsEdited::BayerSensor::isUnchanged() const { - return method && border && imageNum && dcbIterations && dcbEnhance && lmmseIterations && dualDemosaicContrast /*&& allEnhance*/ && greenEq + return method && border && imageNum && dcbIterations && dcbEnhance && lmmseIterations && dualDemosaicAutoContrast && dualDemosaicContrast /*&& allEnhance*/ && greenEq && pixelShiftMotionCorrectionMethod && pixelShiftEperIso && pixelShiftSigma && pixelShiftShowMotion && pixelShiftShowMotionMaskOnly && pixelShiftHoleFill && pixelShiftMedian && pixelShiftNonGreenCross && pixelShiftDemosaicMethod && pixelShiftGreen && pixelShiftBlur && pixelShiftSmooth && pixelShiftEqualBright && pixelShiftEqualBrightChannel && linenoise && linenoiseDirection && pdafLinesFilter && exBlack0 && exBlack1 && exBlack2 && exBlack3 && exTwoGreen; @@ -3134,7 +3146,7 @@ bool RAWParamsEdited::BayerSensor::isUnchanged() const bool RAWParamsEdited::XTransSensor::isUnchanged() const { - return method && exBlackRed && exBlackGreen && exBlackBlue; + return method && exBlackRed && exBlackGreen && exBlackBlue && dualDemosaicAutoContrast && dualDemosaicContrast; } bool RAWParamsEdited::isUnchanged() const diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 0a795696c..faa3a6c8e 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -744,6 +744,7 @@ public: bool dcbIterations; bool dcbEnhance; bool lmmseIterations; + bool dualDemosaicAutoContrast; bool dualDemosaicContrast; bool pixelShiftMotionCorrectionMethod; bool pixelShiftEperIso; @@ -774,6 +775,7 @@ public: public: bool method; + bool dualDemosaicAutoContrast; bool dualDemosaicContrast; bool ccSteps; bool exBlackRed; diff --git a/rtgui/ppversion.h b/rtgui/ppversion.h index 050c4c653..417171197 100644 --- a/rtgui/ppversion.h +++ b/rtgui/ppversion.h @@ -1,11 +1,13 @@ #pragma once // This number has to be incremented whenever the PP3 file format is modified or the behaviour of a tool changes -#define PPVERSION 343 +#define PPVERSION 344 #define PPVERSION_AEXP 301 //value of PPVERSION when auto exposure algorithm was modified /* Log of version changes + 344 2018-10-21 + dual demosaic auto contrast threshold 343 2018-09-06 raw auto ca correction avoid colour shift 342 2018-09-05 diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index deecb7682..6e8e80cf2 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -517,6 +517,8 @@ void ToolPanelCoordinator::initImage (rtengine::StagedImageProcessor* ipc_, bool ipc->setAutoCamListener (colorappearance); ipc->setAutoBWListener (blackwhite); ipc->setFrameCountListener (bayerprocess); + ipc->setBayerAutoContrastListener (bayerprocess); + ipc->setXtransAutoContrastListener (xtransprocess); ipc->setAutoWBListener (whitebalance); ipc->setAutoColorTonListener (colortoning); ipc->setAutoChromaListener (dirpyrdenoise); diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 1c46ee54e..866efafa5 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -220,6 +220,8 @@ public: void panelChanged (rtengine::ProcEvent event, const Glib::ustring& descr); void imageTypeChanged (bool isRaw, bool isBayer, bool isXtrans, bool isMono = false); + +// void autoContrastChanged (double autoContrast); // profilechangelistener interface void profileChange (const rtengine::procparams::PartialProfile* nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited = nullptr, bool fromLastSave = false); void setDefaults (rtengine::procparams::ProcParams* defparams); diff --git a/rtgui/xtransprocess.cc b/rtgui/xtransprocess.cc index 27b5810c4..df771d8ca 100644 --- a/rtgui/xtransprocess.cc +++ b/rtgui/xtransprocess.cc @@ -28,6 +28,7 @@ XTransProcess::XTransProcess () : FoldableToolPanel(this, "xtransprocess", M("TP { auto m = ProcEventMapper::getInstance(); EvDemosaicContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_DUALDEMOSAIC_CONTRAST"); + EvDemosaicAutoContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_DUALDEMOSAIC_AUTO_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); @@ -68,6 +69,12 @@ 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); @@ -76,7 +83,11 @@ XTransProcess::XTransProcess () : FoldableToolPanel(this, "xtransprocess", M("TP 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); @@ -108,6 +119,7 @@ void XTransProcess::read(const rtengine::procparams::ProcParams* pp, const Param } if(pedited ) { + dualDemosaicAutoContrast->setEdited ( pedited->raw.xtranssensor.dualDemosaicAutoContrast ? Edited : UnEdited); dualDemosaicContrast->setEditedState ( pedited->raw.xtranssensor.dualDemosaicContrast ? Edited : UnEdited); ccSteps->setEditedState (pedited->raw.xtranssensor.ccSteps ? Edited : UnEdited); @@ -115,6 +127,7 @@ void XTransProcess::read(const rtengine::procparams::ProcParams* pp, const Param method->set_active_text(M("GENERAL_UNCHANGED")); } } + dualDemosaicAutoContrast->setValue (pp->raw.xtranssensor.dualDemosaicAutoContrast); dualDemosaicContrast->setValue (pp->raw.xtranssensor.dualDemosaicContrast); ccSteps->setValue (pp->raw.xtranssensor.ccSteps); if (!batchMode) { @@ -129,6 +142,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.dualDemosaicContrast = dualDemosaicContrast->getValue(); pp->raw.xtranssensor.ccSteps = ccSteps->getIntValue(); @@ -140,6 +154,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.dualDemosaicContrast = dualDemosaicContrast->getEditedState (); pedited->raw.xtranssensor.ccSteps = ccSteps->getEditedState (); } @@ -185,6 +200,15 @@ 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::methodChanged () { const int curSelection = method->get_active_row_number(); @@ -207,3 +231,23 @@ void XTransProcess::methodChanged () : EvDemosaicMethod, method->get_active_text()); } } + +void XTransProcess::autoContrastChanged (double autoContrast) +{ + struct Data { + XTransProcess *me; + 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)); + } + return FALSE; + }; + + idle_register.add(func, new Data { this, autoContrast }); +} diff --git a/rtgui/xtransprocess.h b/rtgui/xtransprocess.h index edc0965b8..af3f25596 100644 --- a/rtgui/xtransprocess.h +++ b/rtgui/xtransprocess.h @@ -21,11 +21,12 @@ #include #include "adjuster.h" +#include "checkbox.h" #include "guiutils.h" #include "toolpanel.h" -class XTransProcess : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class XTransProcess : public ToolParamBlock, public AdjusterListener, public CheckBoxListener, public FoldableToolPanel, public rtengine::AutoContrastListener { protected: @@ -34,9 +35,13 @@ protected: Adjuster* ccSteps; Gtk::VBox *dualDemosaicOptions; Adjuster* dualDemosaicContrast; + CheckBox* dualDemosaicAutoContrast; + Gtk::Label* dualDemosaicLabel; int oldSelection; sigc::connection methodconn; + IdleRegister idle_register; + rtengine::ProcEvent EvDemosaicAutoContrast; rtengine::ProcEvent EvDemosaicContrast; public: @@ -50,7 +55,9 @@ public: void setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr); void methodChanged(); + void autoContrastChanged (double autoContrast); void adjusterChanged(Adjuster* a, double newval); + void checkBoxToggled(CheckBox* c, CheckValue newval); }; #endif