Merge pull request #4890 from Beep6581/dual_demosaic_auto_threshold
Auto-calculate dual-demosaic contrast threshold
This commit is contained in:
commit
7a24a10dba
@ -728,7 +728,8 @@ HISTORY_MSG_492;RGB Curves
|
|||||||
HISTORY_MSG_493;L*a*b* Adjustments
|
HISTORY_MSG_493;L*a*b* Adjustments
|
||||||
HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors
|
HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors
|
||||||
HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction
|
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_HISTMATCHING;Auto-matched tone curve
|
||||||
HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries
|
HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries
|
||||||
HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D
|
HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D
|
||||||
@ -1816,6 +1817,8 @@ TP_RAW_DMETHOD;Method
|
|||||||
TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing...
|
TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing...
|
||||||
TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement...
|
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_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_DUALDEMOSAICCONTRAST;Contrast threshold
|
||||||
TP_RAW_EAHD;EAHD
|
TP_RAW_EAHD;EAHD
|
||||||
TP_RAW_FALSECOLOR;False color suppression steps
|
TP_RAW_FALSECOLOR;False color suppression steps
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
#include "sleef.c"
|
#include "sleef.c"
|
||||||
#include "opthelper.h"
|
#include "opthelper.h"
|
||||||
#include "median.h"
|
#include "median.h"
|
||||||
#define BENCHMARK
|
//#define BENCHMARK
|
||||||
#include "StopWatch.h"
|
#include "StopWatch.h"
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#include <omp.h>
|
#include <omp.h>
|
||||||
|
@ -36,11 +36,11 @@ using namespace std;
|
|||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
|
|
||||||
void RawImageSource::dual_demosaic_RT(bool isBayer, const RAWParams &raw, int winw, int winh, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue, double &contrast, bool autoContrast, int autoX, int autoY)
|
void RawImageSource::dual_demosaic_RT(bool isBayer, const RAWParams &raw, int winw, int winh, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue, double &contrast, bool autoContrast)
|
||||||
{
|
{
|
||||||
BENCHFUN
|
BENCHFUN
|
||||||
|
|
||||||
if (contrast == 0.0 && !autoContrast) {
|
if (contrast == 0.f && !autoContrast) {
|
||||||
// contrast == 0.0 means only first demosaicer will be used
|
// contrast == 0.0 means only first demosaicer will be used
|
||||||
if(isBayer) {
|
if(isBayer) {
|
||||||
if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEVNG4) ) {
|
if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEVNG4) ) {
|
||||||
@ -91,24 +91,6 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const RAWParams &raw, int wi
|
|||||||
{ 0.019334, 0.119193, 0.950227 }
|
{ 0.019334, 0.119193, 0.950227 }
|
||||||
};
|
};
|
||||||
|
|
||||||
if (autoContrast && autoX >= 0 && autoY >= 0) {
|
|
||||||
constexpr int rectSize = 40;
|
|
||||||
const int autoWidth = min(rectSize, winw - autoX);
|
|
||||||
const int autoHeight = min(rectSize, winh - autoY);
|
|
||||||
if (std::min(autoWidth, autoHeight) > 20) {
|
|
||||||
array2D<float> autoL(autoWidth, autoHeight);
|
|
||||||
for(int i = 0; i < autoHeight; ++i) {
|
|
||||||
Color::RGB2L(red[i + autoY] + autoX, green[i + autoY] + autoX, blue[i + autoY] + autoX, autoL[i], xyz_rgb, autoWidth);
|
|
||||||
}
|
|
||||||
// calculate contrast based blend factors to use vng4 in regions with low contrast
|
|
||||||
JaggedArray<float> blend(autoWidth - 2, autoHeight - 2);
|
|
||||||
int c = calcContrastThreshold(autoL, blend, autoWidth, autoHeight);
|
|
||||||
if(c < 100) {
|
|
||||||
contrast = c; // alternative : contrast = c - 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
{
|
{
|
||||||
#pragma omp for
|
#pragma omp for
|
||||||
@ -118,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
|
// calculate contrast based blend factors to use vng4 in regions with low contrast
|
||||||
JaggedArray<float> blend(winw, winh);
|
JaggedArray<float> blend(winw, winh);
|
||||||
buildBlendMask(L, blend, winw, winh, contrast / 100.f);
|
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
|
// the following is split into 3 loops intentionally to avoid cache conflicts on CPUs with only 4-way cache
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
|
@ -93,7 +93,7 @@ ImProcCoordinator::ImProcCoordinator()
|
|||||||
fw(0), fh(0), tr(0),
|
fw(0), fh(0), tr(0),
|
||||||
fullw(1), fullh(1),
|
fullw(1), fullh(1),
|
||||||
pW(-1), pH(-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),
|
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)
|
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));
|
imgsrc->setBorder(std::max(params.raw.bayersensor.border, 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool autoContrast = false;
|
bool autoContrast = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicAutoContrast : params.raw.xtranssensor.dualDemosaicAutoContrast;
|
||||||
double contrastThreshold = 0.f;
|
double contrastThreshold = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicContrast : params.raw.xtranssensor.dualDemosaicContrast;
|
||||||
imgsrc->demosaic(rp, autoContrast, contrastThreshold); //enabled demosaic
|
imgsrc->demosaic(rp, autoContrast, contrastThreshold); //enabled demosaic
|
||||||
|
|
||||||
|
if (imgsrc->getSensorType() == ST_BAYER && bayerAutoContrastListener && autoContrast) {
|
||||||
|
bayerAutoContrastListener->autoContrastChanged(autoContrast ? contrastThreshold : -1.0);
|
||||||
|
}
|
||||||
|
if (imgsrc->getSensorType() == ST_FUJI_XTRANS && xtransAutoContrastListener && autoContrast) {
|
||||||
|
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
|
// if a demosaic happened we should also call getimage later, so we need to set the M_INIT flag
|
||||||
todo |= M_INIT;
|
todo |= M_INIT;
|
||||||
|
|
||||||
|
@ -158,6 +158,8 @@ protected:
|
|||||||
AutoCamListener* acListener;
|
AutoCamListener* acListener;
|
||||||
AutoBWListener* abwListener;
|
AutoBWListener* abwListener;
|
||||||
AutoWBListener* awbListener;
|
AutoWBListener* awbListener;
|
||||||
|
AutoContrastListener *bayerAutoContrastListener;
|
||||||
|
AutoContrastListener *xtransAutoContrastListener;
|
||||||
FrameCountListener *frameCountListener;
|
FrameCountListener *frameCountListener;
|
||||||
ImageTypeListener *imageTypeListener;
|
ImageTypeListener *imageTypeListener;
|
||||||
|
|
||||||
@ -344,6 +346,16 @@ public:
|
|||||||
frameCountListener = fcl;
|
frameCountListener = fcl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setBayerAutoContrastListener (AutoContrastListener* acl)
|
||||||
|
{
|
||||||
|
bayerAutoContrastListener = acl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setXtransAutoContrastListener (AutoContrastListener* acl)
|
||||||
|
{
|
||||||
|
xtransAutoContrastListener = acl;
|
||||||
|
}
|
||||||
|
|
||||||
void setImageTypeListener (ImageTypeListener* itl)
|
void setImageTypeListener (ImageTypeListener* itl)
|
||||||
{
|
{
|
||||||
imageTypeListener = itl;
|
imageTypeListener = itl;
|
||||||
|
@ -176,7 +176,8 @@ BENCHFUN
|
|||||||
|
|
||||||
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
||||||
JaggedArray<float> blend(W, H);
|
JaggedArray<float> 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.f);
|
||||||
|
|
||||||
const float damping = sharpenParam.deconvdamping / 5.0;
|
const float damping = sharpenParam.deconvdamping / 5.0;
|
||||||
const bool needdamp = sharpenParam.deconvdamping > 0;
|
const bool needdamp = sharpenParam.deconvdamping > 0;
|
||||||
@ -222,7 +223,8 @@ void ImProcFunctions::sharpening (LabImage* lab, const SharpeningParams &sharpen
|
|||||||
if(showMask) {
|
if(showMask) {
|
||||||
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
||||||
JaggedArray<float> blend(W, H);
|
JaggedArray<float> 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.f : 1.f);
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
#endif
|
#endif
|
||||||
@ -256,7 +258,8 @@ BENCHFUN
|
|||||||
|
|
||||||
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
||||||
JaggedArray<float> blend(W, H);
|
JaggedArray<float> 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
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
@ -610,7 +613,8 @@ BENCHFUN
|
|||||||
|
|
||||||
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
||||||
JaggedArray<float> blend(W, H);
|
JaggedArray<float> 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
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
@ -819,7 +823,8 @@ void ImProcFunctions::sharpeningcam (CieImage* ncie, float** b2, bool showMask)
|
|||||||
if(showMask) {
|
if(showMask) {
|
||||||
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
||||||
JaggedArray<float> blend(W, H);
|
JaggedArray<float> 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
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
#endif
|
#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
|
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
||||||
JaggedArray<float> blend(W, H);
|
JaggedArray<float> 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
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
|
@ -2390,6 +2390,7 @@ RAWParams::BayerSensor::BayerSensor() :
|
|||||||
greenthresh(0),
|
greenthresh(0),
|
||||||
dcb_iterations(2),
|
dcb_iterations(2),
|
||||||
lmmse_iterations(2),
|
lmmse_iterations(2),
|
||||||
|
dualDemosaicAutoContrast(true),
|
||||||
dualDemosaicContrast(20),
|
dualDemosaicContrast(20),
|
||||||
pixelShiftMotionCorrectionMethod(PSMotionCorrectionMethod::AUTO),
|
pixelShiftMotionCorrectionMethod(PSMotionCorrectionMethod::AUTO),
|
||||||
pixelShiftEperIso(0.0),
|
pixelShiftEperIso(0.0),
|
||||||
@ -2427,6 +2428,7 @@ bool RAWParams::BayerSensor::operator ==(const BayerSensor& other) const
|
|||||||
&& greenthresh == other.greenthresh
|
&& greenthresh == other.greenthresh
|
||||||
&& dcb_iterations == other.dcb_iterations
|
&& dcb_iterations == other.dcb_iterations
|
||||||
&& lmmse_iterations == other.lmmse_iterations
|
&& lmmse_iterations == other.lmmse_iterations
|
||||||
|
&& dualDemosaicAutoContrast == other.dualDemosaicAutoContrast
|
||||||
&& dualDemosaicContrast == other.dualDemosaicContrast
|
&& dualDemosaicContrast == other.dualDemosaicContrast
|
||||||
&& pixelShiftMotionCorrectionMethod == other.pixelShiftMotionCorrectionMethod
|
&& pixelShiftMotionCorrectionMethod == other.pixelShiftMotionCorrectionMethod
|
||||||
&& pixelShiftEperIso == other.pixelShiftEperIso
|
&& pixelShiftEperIso == other.pixelShiftEperIso
|
||||||
@ -2514,6 +2516,7 @@ Glib::ustring RAWParams::BayerSensor::getPSDemosaicMethodString(PSDemosaicMethod
|
|||||||
|
|
||||||
RAWParams::XTransSensor::XTransSensor() :
|
RAWParams::XTransSensor::XTransSensor() :
|
||||||
method(getMethodString(Method::THREE_PASS)),
|
method(getMethodString(Method::THREE_PASS)),
|
||||||
|
dualDemosaicAutoContrast(true),
|
||||||
dualDemosaicContrast(20),
|
dualDemosaicContrast(20),
|
||||||
ccSteps(0),
|
ccSteps(0),
|
||||||
blackred(0.0),
|
blackred(0.0),
|
||||||
@ -2526,6 +2529,7 @@ bool RAWParams::XTransSensor::operator ==(const XTransSensor& other) const
|
|||||||
{
|
{
|
||||||
return
|
return
|
||||||
method == other.method
|
method == other.method
|
||||||
|
&& dualDemosaicAutoContrast == other.dualDemosaicAutoContrast
|
||||||
&& dualDemosaicContrast == other.dualDemosaicContrast
|
&& dualDemosaicContrast == other.dualDemosaicContrast
|
||||||
&& ccSteps == other.ccSteps
|
&& ccSteps == other.ccSteps
|
||||||
&& blackred == other.blackred
|
&& blackred == other.blackred
|
||||||
@ -3412,6 +3416,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.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.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.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.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.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.pixelShiftEperIso, "RAW Bayer", "PixelShiftEperIso", raw.bayersensor.pixelShiftEperIso, keyFile);
|
||||||
@ -3429,6 +3434,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.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.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.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.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.ccSteps, "RAW X-Trans", "CcSteps", raw.xtranssensor.ccSteps, keyFile);
|
||||||
saveToKeyfile(!pedited || pedited->raw.xtranssensor.exBlackRed, "RAW X-Trans", "PreBlackRed", raw.xtranssensor.blackred, keyFile);
|
saveToKeyfile(!pedited || pedited->raw.xtranssensor.exBlackRed, "RAW X-Trans", "PreBlackRed", raw.xtranssensor.blackred, keyFile);
|
||||||
@ -4844,6 +4850,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", "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", "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", "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 < 345) {
|
||||||
|
raw.bayersensor.dualDemosaicAutoContrast = false;
|
||||||
|
if (pedited) {
|
||||||
|
pedited->raw.bayersensor.dualDemosaicAutoContrast = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
assignFromKeyfile(keyFile, "RAW Bayer", "DualDemosaicContrast", pedited, raw.bayersensor.dualDemosaicContrast, pedited->raw.bayersensor.dualDemosaicContrast);
|
assignFromKeyfile(keyFile, "RAW Bayer", "DualDemosaicContrast", pedited, raw.bayersensor.dualDemosaicContrast, pedited->raw.bayersensor.dualDemosaicContrast);
|
||||||
|
|
||||||
if (keyFile.has_key("RAW Bayer", "PixelShiftMotionCorrectionMethod")) {
|
if (keyFile.has_key("RAW Bayer", "PixelShiftMotionCorrectionMethod")) {
|
||||||
@ -4891,6 +4904,13 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
|
|||||||
|
|
||||||
if (keyFile.has_group("RAW X-Trans")) {
|
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", "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 < 345) {
|
||||||
|
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", "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", "CcSteps", pedited, raw.xtranssensor.ccSteps, pedited->raw.xtranssensor.ccSteps);
|
||||||
assignFromKeyfile(keyFile, "RAW X-Trans", "PreBlackRed", pedited, raw.xtranssensor.blackred, pedited->raw.xtranssensor.exBlackRed);
|
assignFromKeyfile(keyFile, "RAW X-Trans", "PreBlackRed", pedited, raw.xtranssensor.blackred, pedited->raw.xtranssensor.exBlackRed);
|
||||||
|
@ -1286,6 +1286,7 @@ struct RAWParams {
|
|||||||
int greenthresh;
|
int greenthresh;
|
||||||
int dcb_iterations;
|
int dcb_iterations;
|
||||||
int lmmse_iterations;
|
int lmmse_iterations;
|
||||||
|
bool dualDemosaicAutoContrast;
|
||||||
double dualDemosaicContrast;
|
double dualDemosaicContrast;
|
||||||
PSMotionCorrectionMethod pixelShiftMotionCorrectionMethod;
|
PSMotionCorrectionMethod pixelShiftMotionCorrectionMethod;
|
||||||
double pixelShiftEperIso;
|
double pixelShiftEperIso;
|
||||||
@ -1333,6 +1334,7 @@ struct RAWParams {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Glib::ustring method;
|
Glib::ustring method;
|
||||||
|
bool dualDemosaicAutoContrast;
|
||||||
double dualDemosaicContrast;
|
double dualDemosaicContrast;
|
||||||
int ccSteps;
|
int ccSteps;
|
||||||
double blackred;
|
double blackred;
|
||||||
|
@ -2074,7 +2074,7 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c
|
|||||||
double threshold = raw.bayersensor.dualDemosaicContrast;
|
double threshold = raw.bayersensor.dualDemosaicContrast;
|
||||||
dual_demosaic_RT (true, raw, W, H, rawData, red, green, blue, threshold, false);
|
dual_demosaic_RT (true, raw, W, H, rawData, red, green, blue, threshold, false);
|
||||||
} else {
|
} else {
|
||||||
dual_demosaic_RT (true, raw, W, H, rawData, red, green, blue, contrastThreshold, true, 0, 0);
|
dual_demosaic_RT (true, raw, W, H, rawData, red, green, blue, contrastThreshold, true);
|
||||||
}
|
}
|
||||||
} else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::PIXELSHIFT) ) {
|
} else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::PIXELSHIFT) ) {
|
||||||
pixelshift(0, 0, W, H, raw, currFrame, ri->get_maker(), ri->get_model(), raw.expos);
|
pixelshift(0, 0, W, H, raw, currFrame, ri->get_maker(), ri->get_model(), raw.expos);
|
||||||
@ -2107,7 +2107,7 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c
|
|||||||
double threshold = raw.xtranssensor.dualDemosaicContrast;
|
double threshold = raw.xtranssensor.dualDemosaicContrast;
|
||||||
dual_demosaic_RT (false, raw, W, H, rawData, red, green, blue, threshold, false);
|
dual_demosaic_RT (false, raw, W, H, rawData, red, green, blue, threshold, false);
|
||||||
} else {
|
} else {
|
||||||
dual_demosaic_RT (false, raw, W, H, rawData, red, green, blue, contrastThreshold, true, 0, 0);
|
dual_demosaic_RT (false, raw, W, H, rawData, red, green, blue, contrastThreshold, true);
|
||||||
}
|
}
|
||||||
} else if(raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::MONO) ) {
|
} else if(raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::MONO) ) {
|
||||||
nodemosaic(true);
|
nodemosaic(true);
|
||||||
|
@ -274,7 +274,7 @@ protected:
|
|||||||
void igv_interpolate(int winw, int winh);
|
void igv_interpolate(int winw, int winh);
|
||||||
void lmmse_interpolate_omp(int winw, int winh, array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue, int iterations);
|
void lmmse_interpolate_omp(int winw, int winh, array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue, int iterations);
|
||||||
void amaze_demosaic_RT(int winx, int winy, int winw, int winh, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue);//Emil's code for AMaZE
|
void amaze_demosaic_RT(int winx, int winy, int winw, int winh, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue);//Emil's code for AMaZE
|
||||||
void dual_demosaic_RT(bool isBayer, const RAWParams &raw, int winw, int winh, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue, double &contrast, bool autoContrast = false, int autoX = -1, int autoY = -1);
|
void dual_demosaic_RT(bool isBayer, const RAWParams &raw, int winw, int winh, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue, double &contrast, bool autoContrast = false);
|
||||||
void fast_demosaic();//Emil's code for fast demosaicing
|
void fast_demosaic();//Emil's code for fast demosaicing
|
||||||
void dcb_demosaic(int iterations, bool dcb_enhance);
|
void dcb_demosaic(int iterations, bool dcb_enhance);
|
||||||
void ahd_demosaic();
|
void ahd_demosaic();
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#include <omp.h>
|
#include <omp.h>
|
||||||
#endif
|
#endif
|
||||||
@ -32,6 +33,7 @@
|
|||||||
#include "rt_algo.h"
|
#include "rt_algo.h"
|
||||||
#include "rt_math.h"
|
#include "rt_math.h"
|
||||||
#include "sleef.c"
|
#include "sleef.c"
|
||||||
|
#include "jaggedarray.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
float calcBlendFactor(float val, float threshold) {
|
float calcBlendFactor(float val, float threshold) {
|
||||||
@ -190,75 +192,166 @@ void findMinMaxPercentile(const float* data, size_t size, float minPrct, float&
|
|||||||
maxOut += minVal;
|
maxOut += minVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
void buildBlendMask(float** luminance, float **blend, int W, int H, float contrastThreshold, float amount) {
|
void buildBlendMask(float** luminance, float **blend, int W, int H, float &contrastThreshold, float amount, bool autoContrast) {
|
||||||
|
|
||||||
constexpr float scale = 0.0625f / 327.68f;
|
if(contrastThreshold == 0.f && !autoContrast) {
|
||||||
|
|
||||||
if(contrastThreshold == 0.f) {
|
|
||||||
for(int j = 0; j < H; ++j) {
|
for(int j = 0; j < H; ++j) {
|
||||||
for(int i = 0; i < W; ++i) {
|
for(int i = 0; i < W; ++i) {
|
||||||
blend[j][i] = amount;
|
blend[j][i] = amount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#ifdef _OPENMP
|
constexpr float scale = 0.0625f / 327.68f;
|
||||||
#pragma omp parallel
|
if (autoContrast) {
|
||||||
#endif
|
for (int pass = 0; pass < 2; ++pass) {
|
||||||
{
|
const int tilesize = 80 / (pass + 1);
|
||||||
#ifdef __SSE2__
|
const int numTilesW = W / tilesize;
|
||||||
const vfloat contrastThresholdv = F2V(contrastThreshold);
|
const int numTilesH = H / tilesize;
|
||||||
const vfloat scalev = F2V(scale);
|
std::vector<std::vector<std::pair<float, float>>> variances(numTilesH, std::vector<std::pair<float, float>>(numTilesW));
|
||||||
const vfloat amountv = F2V(amount);
|
|
||||||
#endif
|
|
||||||
#ifdef _OPENMP
|
|
||||||
#pragma omp for schedule(dynamic,16)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for(int j = 2; j < H - 2; ++j) {
|
#pragma omp parallel for
|
||||||
int i = 2;
|
for (int i = 0; i < numTilesH; ++i) {
|
||||||
|
int tileY = i * tilesize;
|
||||||
|
for (int j = 0; j < numTilesW; ++j) {
|
||||||
|
int tileX = j * tilesize;
|
||||||
#ifdef __SSE2__
|
#ifdef __SSE2__
|
||||||
for(; i < W - 5; i += 4) {
|
vfloat avgv = ZEROV;
|
||||||
vfloat contrastv = vsqrtf(SQRV(LVFU(luminance[j][i+1]) - LVFU(luminance[j][i-1])) + SQRV(LVFU(luminance[j+1][i]) - LVFU(luminance[j-1][i])) +
|
for (int y = tileY; y < tileY + tilesize; ++y) {
|
||||||
SQRV(LVFU(luminance[j][i+2]) - LVFU(luminance[j][i-2])) + SQRV(LVFU(luminance[j+2][i]) - LVFU(luminance[j-2][i]))) * scalev;
|
for (int x = tileX; x < tileX + tilesize; x += 4) {
|
||||||
|
avgv += LVFU(luminance[y][x]);
|
||||||
STVFU(blend[j][i], amountv * calcBlendFactor(contrastv, contrastThresholdv));
|
}
|
||||||
|
}
|
||||||
|
float avg = vhadd(avgv);
|
||||||
|
#else
|
||||||
|
float avg = 0.;
|
||||||
|
for (int y = tileY; y < tileY + tilesize; ++y) {
|
||||||
|
for (int x = tileX; x < tileX + tilesize; ++x) {
|
||||||
|
avg += luminance[y][x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
avg /= SQR(tilesize);
|
||||||
|
#ifdef __SSE2__
|
||||||
|
vfloat varv = ZEROV;
|
||||||
|
avgv = F2V(avg);
|
||||||
|
for (int y = tileY; y < tileY + tilesize; ++y) {
|
||||||
|
for (int x = tileX; x < tileX + tilesize; x +=4) {
|
||||||
|
varv += SQRV(LVFU(luminance[y][x]) - avgv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
float var = vhadd(varv);
|
||||||
|
#else
|
||||||
|
float var = 0.0;
|
||||||
|
for (int y = tileY; y < tileY + tilesize; ++y) {
|
||||||
|
for (int x = tileX; x < tileX + tilesize; ++x) {
|
||||||
|
var += SQR(luminance[y][x] - avg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
var /= (SQR(tilesize) * avg);
|
||||||
|
variances[i][j].first = var;
|
||||||
|
variances[i][j].second = avg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
for(; i < W - 2; ++i) {
|
|
||||||
|
|
||||||
float contrast = sqrtf(rtengine::SQR(luminance[j][i+1] - luminance[j][i-1]) + rtengine::SQR(luminance[j+1][i] - luminance[j-1][i]) +
|
float minvar = RT_INFINITY_F;
|
||||||
rtengine::SQR(luminance[j][i+2] - luminance[j][i-2]) + rtengine::SQR(luminance[j+2][i] - luminance[j-2][i])) * scale;
|
int minI = 0, minJ = 0;
|
||||||
|
for (int i = 0; i < numTilesH; ++i) {
|
||||||
|
for (int j = 0; j < numTilesW; ++j) {
|
||||||
|
if (variances[i][j].first < minvar && variances[i][j].second > 2000.f && variances[i][j].second < 20000.f) {
|
||||||
|
minvar = variances[i][j].first;
|
||||||
|
minI = i;
|
||||||
|
minJ = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
blend[j][i] = amount * calcBlendFactor(contrast, contrastThreshold);
|
const int minY = tilesize * minI;
|
||||||
|
const int minX = tilesize * minJ;
|
||||||
|
|
||||||
|
// std::cout << pass << ": minvar : " << minvar << std::endl;
|
||||||
|
if (minvar <= 1.f || pass == 1) {
|
||||||
|
// a variance <= 1 means we already found a flat region and can skip second pass
|
||||||
|
// in second pass we allow a variance of 2
|
||||||
|
JaggedArray<float> Lum(tilesize, tilesize);
|
||||||
|
JaggedArray<float> Blend(tilesize, tilesize);
|
||||||
|
for (int i = 0; i < tilesize; ++i) {
|
||||||
|
for (int j = 0; j < tilesize; ++j) {
|
||||||
|
Lum[i][j] = luminance[i + minY][j + minX];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contrastThreshold = (pass == 0 || minvar <= 2.f) ? calcContrastThreshold(Lum, Blend, tilesize, tilesize) / 100.f : 0.f;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(contrastThreshold == 0.f) {
|
||||||
|
for(int j = 0; j < H; ++j) {
|
||||||
|
for(int i = 0; i < W; ++i) {
|
||||||
|
blend[j][i] = amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp single
|
#pragma omp parallel
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// upper border
|
#ifdef __SSE2__
|
||||||
for(int j = 0; j < 2; ++j) {
|
const vfloat contrastThresholdv = F2V(contrastThreshold);
|
||||||
for(int i = 2; i < W - 2; ++i) {
|
const vfloat scalev = F2V(scale);
|
||||||
blend[j][i] = blend[2][i];
|
const vfloat amountv = F2V(amount);
|
||||||
}
|
#endif
|
||||||
}
|
#ifdef _OPENMP
|
||||||
// lower border
|
#pragma omp for schedule(dynamic,16)
|
||||||
for(int j = H - 2; j < H; ++j) {
|
#endif
|
||||||
for(int i = 2; i < W - 2; ++i) {
|
|
||||||
blend[j][i] = blend[H-3][i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(int j = 0; j < H; ++j) {
|
|
||||||
// left border
|
|
||||||
blend[j][0] = blend[j][1] = blend[j][2];
|
|
||||||
// right border
|
|
||||||
blend[j][W - 2] = blend[j][W - 1] = blend[j][W - 3];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// blur blend mask to smooth transitions
|
for(int j = 2; j < H - 2; ++j) {
|
||||||
gaussianBlur(blend, blend, W, H, 2.0);
|
int i = 2;
|
||||||
|
#ifdef __SSE2__
|
||||||
|
for(; i < W - 5; i += 4) {
|
||||||
|
vfloat contrastv = vsqrtf(SQRV(LVFU(luminance[j][i+1]) - LVFU(luminance[j][i-1])) + SQRV(LVFU(luminance[j+1][i]) - LVFU(luminance[j-1][i])) +
|
||||||
|
SQRV(LVFU(luminance[j][i+2]) - LVFU(luminance[j][i-2])) + SQRV(LVFU(luminance[j+2][i]) - LVFU(luminance[j-2][i]))) * scalev;
|
||||||
|
|
||||||
|
STVFU(blend[j][i], amountv * calcBlendFactor(contrastv, contrastThresholdv));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
for(; i < W - 2; ++i) {
|
||||||
|
|
||||||
|
float contrast = sqrtf(rtengine::SQR(luminance[j][i+1] - luminance[j][i-1]) + rtengine::SQR(luminance[j+1][i] - luminance[j-1][i]) +
|
||||||
|
rtengine::SQR(luminance[j][i+2] - luminance[j][i-2]) + rtengine::SQR(luminance[j+2][i] - luminance[j-2][i])) * scale;
|
||||||
|
|
||||||
|
blend[j][i] = amount * calcBlendFactor(contrast, contrastThreshold);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _OPENMP
|
||||||
|
#pragma omp single
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
// upper border
|
||||||
|
for(int j = 0; j < 2; ++j) {
|
||||||
|
for(int i = 2; i < W - 2; ++i) {
|
||||||
|
blend[j][i] = blend[2][i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// lower border
|
||||||
|
for(int j = H - 2; j < H; ++j) {
|
||||||
|
for(int i = 2; i < W - 2; ++i) {
|
||||||
|
blend[j][i] = blend[H-3][i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int j = 0; j < H; ++j) {
|
||||||
|
// left border
|
||||||
|
blend[j][0] = blend[j][1] = blend[j][2];
|
||||||
|
// right border
|
||||||
|
blend[j][W - 2] = blend[j][W - 1] = blend[j][W - 3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// blur blend mask to smooth transitions
|
||||||
|
gaussianBlur(blend, blend, W, H, 2.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -289,7 +382,7 @@ int calcContrastThreshold(float** luminance, float **blend, int W, int H) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const float limit = (W - 2) * (H - 2) / 100.f;
|
const float limit = (W - 4) * (H - 4) / 100.f;
|
||||||
|
|
||||||
int c;
|
int c;
|
||||||
for (c = 1; c < 100; ++c) {
|
for (c = 1; c < 100; ++c) {
|
||||||
@ -318,6 +411,7 @@ int calcContrastThreshold(float** luminance, float **blend, int W, int H) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,6 @@
|
|||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
void findMinMaxPercentile(const float* data, size_t size, float minPrct, float& minOut, float maxPrct, float& maxOut, bool multiThread = true);
|
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);
|
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);
|
int calcContrastThreshold(float** luminance, float **blend, int W, int H);
|
||||||
}
|
}
|
||||||
|
@ -378,6 +378,13 @@ public:
|
|||||||
virtual void imageTypeChanged(bool isRaw, bool isBayer, bool isXtrans, bool is_Mono = false) = 0;
|
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
|
class WaveletListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -482,6 +489,8 @@ public:
|
|||||||
virtual void setPreviewImageListener (PreviewImageListener* l) = 0;
|
virtual void setPreviewImageListener (PreviewImageListener* l) = 0;
|
||||||
virtual void setAutoCamListener (AutoCamListener* l) = 0;
|
virtual void setAutoCamListener (AutoCamListener* l) = 0;
|
||||||
virtual void setFrameCountListener (FrameCountListener* 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 setAutoBWListener (AutoBWListener* l) = 0;
|
||||||
virtual void setAutoWBListener (AutoWBListener* l) = 0;
|
virtual void setAutoWBListener (AutoWBListener* l) = 0;
|
||||||
virtual void setAutoColorTonListener (AutoColorTonListener* l) = 0;
|
virtual void setAutoColorTonListener (AutoColorTonListener* l) = 0;
|
||||||
|
@ -209,8 +209,10 @@ private:
|
|||||||
if (pl) {
|
if (pl) {
|
||||||
pl->setProgress (0.20);
|
pl->setProgress (0.20);
|
||||||
}
|
}
|
||||||
double contrastThresholdDummy;
|
bool autoContrast = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicAutoContrast : params.raw.xtranssensor.dualDemosaicAutoContrast;
|
||||||
imgsrc->demosaic (params.raw, false, contrastThresholdDummy);
|
double contrastThreshold = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicContrast : params.raw.xtranssensor.dualDemosaicContrast;
|
||||||
|
|
||||||
|
imgsrc->demosaic (params.raw, autoContrast, contrastThreshold);
|
||||||
|
|
||||||
|
|
||||||
if (pl) {
|
if (pl) {
|
||||||
|
@ -239,10 +239,12 @@ void Adjuster::autoToggled ()
|
|||||||
// Disable the slider and spin button
|
// Disable the slider and spin button
|
||||||
spin->set_sensitive(false);
|
spin->set_sensitive(false);
|
||||||
slider->set_sensitive(false);
|
slider->set_sensitive(false);
|
||||||
|
reset->set_sensitive(false);
|
||||||
} else {
|
} else {
|
||||||
// Enable the slider and spin button
|
// Enable the slider and spin button
|
||||||
spin->set_sensitive(true);
|
spin->set_sensitive(true);
|
||||||
slider->set_sensitive(true);
|
slider->set_sensitive(true);
|
||||||
|
reset->set_sensitive(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,10 +473,12 @@ void Adjuster::setAutoValue (bool a)
|
|||||||
// Disable the slider and spin button
|
// Disable the slider and spin button
|
||||||
spin->set_sensitive(false);
|
spin->set_sensitive(false);
|
||||||
slider->set_sensitive(false);
|
slider->set_sensitive(false);
|
||||||
|
reset->set_sensitive(false);
|
||||||
} else {
|
} else {
|
||||||
// Enable the slider and spin button
|
// Enable the slider and spin button
|
||||||
spin->set_sensitive(true);
|
spin->set_sensitive(true);
|
||||||
slider->set_sensitive(true);
|
slider->set_sensitive(true);
|
||||||
|
reset->set_sensitive(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RA
|
|||||||
auto m = ProcEventMapper::getInstance();
|
auto m = ProcEventMapper::getInstance();
|
||||||
EvDemosaicBorder = m->newEvent(DEMOSAIC, "HISTORY_MSG_RAW_BORDER");
|
EvDemosaicBorder = m->newEvent(DEMOSAIC, "HISTORY_MSG_RAW_BORDER");
|
||||||
EvDemosaicContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_DUALDEMOSAIC_CONTRAST");
|
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");
|
EvDemosaicPixelshiftDemosaicMethod = m->newEvent(DEMOSAIC, "HISTORY_MSG_PIXELSHIFT_DEMOSAIC");
|
||||||
|
|
||||||
Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ());
|
Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ());
|
||||||
@ -46,12 +47,12 @@ BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RA
|
|||||||
hb1->pack_end (*method, Gtk::PACK_EXPAND_WIDGET, 4);
|
hb1->pack_end (*method, Gtk::PACK_EXPAND_WIDGET, 4);
|
||||||
pack_start( *hb1, Gtk::PACK_SHRINK, 4);
|
pack_start( *hb1, Gtk::PACK_SHRINK, 4);
|
||||||
|
|
||||||
|
dualDemosaicOptions = Gtk::manage(new Gtk::VBox());
|
||||||
|
|
||||||
dualDemosaicOptions = Gtk::manage (new Gtk::VBox ());
|
dualDemosaicContrast = Gtk::manage(new Adjuster(M("TP_RAW_DUALDEMOSAICCONTRAST"), 0, 100, 1, 20));
|
||||||
|
dualDemosaicContrast->setAdjusterListener(this);
|
||||||
dualDemosaicContrast = Gtk::manage(new Adjuster (M("TP_RAW_DUALDEMOSAICCONTRAST"), 0, 100, 1, 20));
|
dualDemosaicContrast->addAutoButton(M("TP_RAW_DUALDEMOSAICAUTOCONTRAST_TOOLTIP"));
|
||||||
dualDemosaicContrast->setAdjusterListener (this);
|
dualDemosaicContrast->setAutoValue(true);
|
||||||
|
|
||||||
if (dualDemosaicContrast->delay < options.adjusterMaxDelay) {
|
if (dualDemosaicContrast->delay < options.adjusterMaxDelay) {
|
||||||
dualDemosaicContrast->delay = options.adjusterMaxDelay;
|
dualDemosaicContrast->delay = options.adjusterMaxDelay;
|
||||||
}
|
}
|
||||||
@ -250,6 +251,10 @@ BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RA
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BayerProcess::~BayerProcess ()
|
||||||
|
{
|
||||||
|
idle_register.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited)
|
void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited)
|
||||||
{
|
{
|
||||||
@ -300,7 +305,9 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params
|
|||||||
pixelShiftNonGreenCross->setValue (pp->raw.bayersensor.pixelShiftNonGreenCross);
|
pixelShiftNonGreenCross->setValue (pp->raw.bayersensor.pixelShiftNonGreenCross);
|
||||||
ccSteps->setValue (pp->raw.bayersensor.ccSteps);
|
ccSteps->setValue (pp->raw.bayersensor.ccSteps);
|
||||||
lmmseIterations->setValue (pp->raw.bayersensor.lmmse_iterations);
|
lmmseIterations->setValue (pp->raw.bayersensor.lmmse_iterations);
|
||||||
|
dualDemosaicContrast->setAutoValue(pp->raw.bayersensor.dualDemosaicAutoContrast);
|
||||||
dualDemosaicContrast->setValue (pp->raw.bayersensor.dualDemosaicContrast);
|
dualDemosaicContrast->setValue (pp->raw.bayersensor.dualDemosaicContrast);
|
||||||
|
|
||||||
pixelShiftMotionMethod->set_active ((int)pp->raw.bayersensor.pixelShiftMotionCorrectionMethod);
|
pixelShiftMotionMethod->set_active ((int)pp->raw.bayersensor.pixelShiftMotionCorrectionMethod);
|
||||||
pixelShiftEperIso->setValue (pp->raw.bayersensor.pixelShiftEperIso);
|
pixelShiftEperIso->setValue (pp->raw.bayersensor.pixelShiftEperIso);
|
||||||
pixelShiftSigma->setValue (pp->raw.bayersensor.pixelShiftSigma);
|
pixelShiftSigma->setValue (pp->raw.bayersensor.pixelShiftSigma);
|
||||||
@ -325,6 +332,7 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params
|
|||||||
pixelShiftNonGreenCross->setEdited (pedited->raw.bayersensor.pixelShiftNonGreenCross);
|
pixelShiftNonGreenCross->setEdited (pedited->raw.bayersensor.pixelShiftNonGreenCross);
|
||||||
lmmseIterations->setEditedState ( pedited->raw.bayersensor.lmmseIterations ? Edited : UnEdited);
|
lmmseIterations->setEditedState ( pedited->raw.bayersensor.lmmseIterations ? Edited : UnEdited);
|
||||||
dualDemosaicContrast->setEditedState ( pedited->raw.bayersensor.dualDemosaicContrast ? 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);
|
pixelShiftEperIso->setEditedState ( pedited->raw.bayersensor.pixelShiftEperIso ? Edited : UnEdited);
|
||||||
pixelShiftSigma->setEditedState ( pedited->raw.bayersensor.pixelShiftSigma ? Edited : UnEdited);
|
pixelShiftSigma->setEditedState ( pedited->raw.bayersensor.pixelShiftSigma ? Edited : UnEdited);
|
||||||
|
|
||||||
@ -345,6 +353,7 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
lastAutoContrast = pp->raw.bayersensor.dualDemosaicAutoContrast;
|
||||||
|
|
||||||
if (!batchMode) {
|
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));
|
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));
|
||||||
@ -385,6 +394,7 @@ void BayerProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pe
|
|||||||
pp->raw.bayersensor.dcb_enhance = dcbEnhance->getLastActive ();
|
pp->raw.bayersensor.dcb_enhance = dcbEnhance->getLastActive ();
|
||||||
pp->raw.bayersensor.border = border->getIntValue();
|
pp->raw.bayersensor.border = border->getIntValue();
|
||||||
pp->raw.bayersensor.lmmse_iterations = lmmseIterations->getIntValue();
|
pp->raw.bayersensor.lmmse_iterations = lmmseIterations->getIntValue();
|
||||||
|
pp->raw.bayersensor.dualDemosaicAutoContrast = dualDemosaicContrast->getAutoValue();
|
||||||
pp->raw.bayersensor.dualDemosaicContrast = dualDemosaicContrast->getValue();
|
pp->raw.bayersensor.dualDemosaicContrast = dualDemosaicContrast->getValue();
|
||||||
pp->raw.bayersensor.pixelShiftMotionCorrectionMethod = (RAWParams::BayerSensor::PSMotionCorrectionMethod)pixelShiftMotionMethod->get_active_row_number();
|
pp->raw.bayersensor.pixelShiftMotionCorrectionMethod = (RAWParams::BayerSensor::PSMotionCorrectionMethod)pixelShiftMotionMethod->get_active_row_number();
|
||||||
pp->raw.bayersensor.pixelShiftEperIso = pixelShiftEperIso->getValue();
|
pp->raw.bayersensor.pixelShiftEperIso = pixelShiftEperIso->getValue();
|
||||||
@ -425,6 +435,7 @@ void BayerProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pe
|
|||||||
pedited->raw.bayersensor.dcbEnhance = !dcbEnhance->get_inconsistent();
|
pedited->raw.bayersensor.dcbEnhance = !dcbEnhance->get_inconsistent();
|
||||||
//pedited->raw.bayersensor.allEnhance = !allEnhance->get_inconsistent();
|
//pedited->raw.bayersensor.allEnhance = !allEnhance->get_inconsistent();
|
||||||
pedited->raw.bayersensor.lmmseIterations = lmmseIterations->getEditedState ();
|
pedited->raw.bayersensor.lmmseIterations = lmmseIterations->getEditedState ();
|
||||||
|
pedited->raw.bayersensor.dualDemosaicAutoContrast = !dualDemosaicContrast->getAutoInconsistent ();
|
||||||
pedited->raw.bayersensor.dualDemosaicContrast = dualDemosaicContrast->getEditedState ();
|
pedited->raw.bayersensor.dualDemosaicContrast = dualDemosaicContrast->getEditedState ();
|
||||||
pedited->raw.bayersensor.pixelShiftMotionCorrectionMethod = pixelShiftMotionMethod->get_active_text() != M("GENERAL_UNCHANGED");
|
pedited->raw.bayersensor.pixelShiftMotionCorrectionMethod = pixelShiftMotionMethod->get_active_text() != M("GENERAL_UNCHANGED");
|
||||||
pedited->raw.bayersensor.pixelShiftDemosaicMethod = pixelShiftDemosaicMethod->get_active_text() != M("GENERAL_UNCHANGED");
|
pedited->raw.bayersensor.pixelShiftDemosaicMethod = pixelShiftDemosaicMethod->get_active_text() != M("GENERAL_UNCHANGED");
|
||||||
@ -539,10 +550,6 @@ void BayerProcess::adjusterChanged (Adjuster* a, double newval)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BayerProcess::adjusterAutoToggled(Adjuster* a, bool newval)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void BayerProcess::methodChanged ()
|
void BayerProcess::methodChanged ()
|
||||||
{
|
{
|
||||||
const int currentSelection = method->get_active_row_number();
|
const int currentSelection = method->get_active_row_number();
|
||||||
@ -660,6 +667,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 ()
|
void BayerProcess::pixelShiftMotionMethodChanged ()
|
||||||
{
|
{
|
||||||
if (!batchMode) {
|
if (!batchMode) {
|
||||||
@ -715,23 +749,23 @@ void BayerProcess::FrameCountChanged(int n, int frameNum)
|
|||||||
};
|
};
|
||||||
|
|
||||||
idle_register.add(func, new Data { this, n, 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 *>(data);
|
||||||
|
BayerProcess *me = d->me;
|
||||||
|
me->disableListener();
|
||||||
|
me->dualDemosaicContrast->setValue(d->autoContrast);
|
||||||
|
me->enableListener();
|
||||||
|
delete d;
|
||||||
|
return FALSE;
|
||||||
|
};
|
||||||
|
|
||||||
|
idle_register.add(func, new Data { this, autoContrast });
|
||||||
|
}
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "guiutils.h"
|
#include "guiutils.h"
|
||||||
#include "toolpanel.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:
|
protected:
|
||||||
@ -60,15 +60,17 @@ protected:
|
|||||||
Gtk::VBox *dualDemosaicOptions;
|
Gtk::VBox *dualDemosaicOptions;
|
||||||
Adjuster* dualDemosaicContrast;
|
Adjuster* dualDemosaicContrast;
|
||||||
int oldMethod;
|
int oldMethod;
|
||||||
|
bool lastAutoContrast;
|
||||||
IdleRegister idle_register;
|
IdleRegister idle_register;
|
||||||
|
|
||||||
rtengine::ProcEvent EvDemosaicBorder;
|
rtengine::ProcEvent EvDemosaicBorder;
|
||||||
|
rtengine::ProcEvent EvDemosaicAutoContrast;
|
||||||
rtengine::ProcEvent EvDemosaicContrast;
|
rtengine::ProcEvent EvDemosaicContrast;
|
||||||
rtengine::ProcEvent EvDemosaicPixelshiftDemosaicMethod;
|
rtengine::ProcEvent EvDemosaicPixelshiftDemosaicMethod;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
BayerProcess ();
|
BayerProcess ();
|
||||||
|
~BayerProcess ();
|
||||||
|
|
||||||
void read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr);
|
void read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr);
|
||||||
void write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr);
|
void write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr);
|
||||||
@ -84,6 +86,7 @@ public:
|
|||||||
void checkBoxToggled(CheckBox* c, CheckValue newval);
|
void checkBoxToggled(CheckBox* c, CheckValue newval);
|
||||||
void pixelShiftMotionMethodChanged();
|
void pixelShiftMotionMethodChanged();
|
||||||
void pixelShiftDemosaicMethodChanged();
|
void pixelShiftDemosaicMethodChanged();
|
||||||
|
void autoContrastChanged (double autoContrast);
|
||||||
void FrameCountChanged(int n, int frameNum);
|
void FrameCountChanged(int n, int frameNum);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -406,6 +406,7 @@ void ParamsEdited::set(bool v)
|
|||||||
raw.bayersensor.dcbEnhance = v;
|
raw.bayersensor.dcbEnhance = v;
|
||||||
//raw.bayersensor.allEnhance = v;
|
//raw.bayersensor.allEnhance = v;
|
||||||
raw.bayersensor.lmmseIterations = v;
|
raw.bayersensor.lmmseIterations = v;
|
||||||
|
raw.bayersensor.dualDemosaicAutoContrast = v;
|
||||||
raw.bayersensor.dualDemosaicContrast = v;
|
raw.bayersensor.dualDemosaicContrast = v;
|
||||||
raw.bayersensor.pixelShiftMotionCorrectionMethod = v;
|
raw.bayersensor.pixelShiftMotionCorrectionMethod = v;
|
||||||
raw.bayersensor.pixelShiftEperIso = v;
|
raw.bayersensor.pixelShiftEperIso = v;
|
||||||
@ -426,6 +427,7 @@ void ParamsEdited::set(bool v)
|
|||||||
raw.bayersensor.linenoiseDirection = v;
|
raw.bayersensor.linenoiseDirection = v;
|
||||||
raw.bayersensor.pdafLinesFilter = v;
|
raw.bayersensor.pdafLinesFilter = v;
|
||||||
raw.xtranssensor.method = v;
|
raw.xtranssensor.method = v;
|
||||||
|
raw.xtranssensor.dualDemosaicAutoContrast = v;
|
||||||
raw.xtranssensor.dualDemosaicContrast = v;
|
raw.xtranssensor.dualDemosaicContrast = v;
|
||||||
raw.xtranssensor.ccSteps = v;
|
raw.xtranssensor.ccSteps = v;
|
||||||
raw.xtranssensor.exBlackRed = v;
|
raw.xtranssensor.exBlackRed = v;
|
||||||
@ -964,6 +966,7 @@ void ParamsEdited::initFrom(const std::vector<rtengine::procparams::ProcParams>&
|
|||||||
raw.bayersensor.dcbEnhance = raw.bayersensor.dcbEnhance && p.raw.bayersensor.dcb_enhance == other.raw.bayersensor.dcb_enhance;
|
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.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.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.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.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.pixelShiftEperIso = raw.bayersensor.pixelShiftEperIso && p.raw.bayersensor.pixelShiftEperIso == other.raw.bayersensor.pixelShiftEperIso;
|
||||||
@ -984,6 +987,7 @@ void ParamsEdited::initFrom(const std::vector<rtengine::procparams::ProcParams>&
|
|||||||
raw.bayersensor.linenoiseDirection = raw.bayersensor.linenoiseDirection && p.raw.bayersensor.linenoiseDirection == other.raw.bayersensor.linenoiseDirection;
|
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.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.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.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.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;
|
raw.xtranssensor.exBlackRed = raw.xtranssensor.exBlackRed && p.raw.xtranssensor.blackred == other.raw.xtranssensor.blackred;
|
||||||
@ -2532,6 +2536,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
|
|||||||
toEdit.raw.bayersensor.lmmse_iterations = mods.raw.bayersensor.lmmse_iterations;
|
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) {
|
if (raw.bayersensor.dualDemosaicContrast) {
|
||||||
toEdit.raw.bayersensor.dualDemosaicContrast = mods.raw.bayersensor.dualDemosaicContrast;
|
toEdit.raw.bayersensor.dualDemosaicContrast = mods.raw.bayersensor.dualDemosaicContrast;
|
||||||
}
|
}
|
||||||
@ -2612,6 +2620,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
|
|||||||
toEdit.raw.xtranssensor.method = mods.raw.xtranssensor.method;
|
toEdit.raw.xtranssensor.method = mods.raw.xtranssensor.method;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (raw.xtranssensor.dualDemosaicAutoContrast) {
|
||||||
|
toEdit.raw.xtranssensor.dualDemosaicAutoContrast = mods.raw.xtranssensor.dualDemosaicAutoContrast;
|
||||||
|
}
|
||||||
|
|
||||||
if (raw.xtranssensor.dualDemosaicContrast) {
|
if (raw.xtranssensor.dualDemosaicContrast) {
|
||||||
toEdit.raw.xtranssensor.dualDemosaicContrast = mods.raw.xtranssensor.dualDemosaicContrast;
|
toEdit.raw.xtranssensor.dualDemosaicContrast = mods.raw.xtranssensor.dualDemosaicContrast;
|
||||||
}
|
}
|
||||||
@ -3132,7 +3144,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
|
|||||||
|
|
||||||
bool RAWParamsEdited::BayerSensor::isUnchanged() const
|
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
|
&& pixelShiftMotionCorrectionMethod && pixelShiftEperIso && pixelShiftSigma && pixelShiftShowMotion && pixelShiftShowMotionMaskOnly
|
||||||
&& pixelShiftHoleFill && pixelShiftMedian && pixelShiftNonGreenCross && pixelShiftDemosaicMethod && pixelShiftGreen && pixelShiftBlur && pixelShiftSmooth && pixelShiftEqualBright && pixelShiftEqualBrightChannel
|
&& pixelShiftHoleFill && pixelShiftMedian && pixelShiftNonGreenCross && pixelShiftDemosaicMethod && pixelShiftGreen && pixelShiftBlur && pixelShiftSmooth && pixelShiftEqualBright && pixelShiftEqualBrightChannel
|
||||||
&& linenoise && linenoiseDirection && pdafLinesFilter && exBlack0 && exBlack1 && exBlack2 && exBlack3 && exTwoGreen;
|
&& linenoise && linenoiseDirection && pdafLinesFilter && exBlack0 && exBlack1 && exBlack2 && exBlack3 && exTwoGreen;
|
||||||
@ -3140,7 +3152,7 @@ bool RAWParamsEdited::BayerSensor::isUnchanged() const
|
|||||||
|
|
||||||
bool RAWParamsEdited::XTransSensor::isUnchanged() const
|
bool RAWParamsEdited::XTransSensor::isUnchanged() const
|
||||||
{
|
{
|
||||||
return method && exBlackRed && exBlackGreen && exBlackBlue;
|
return method && exBlackRed && exBlackGreen && exBlackBlue && dualDemosaicAutoContrast && dualDemosaicContrast;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RAWParamsEdited::isUnchanged() const
|
bool RAWParamsEdited::isUnchanged() const
|
||||||
|
@ -744,6 +744,7 @@ public:
|
|||||||
bool dcbIterations;
|
bool dcbIterations;
|
||||||
bool dcbEnhance;
|
bool dcbEnhance;
|
||||||
bool lmmseIterations;
|
bool lmmseIterations;
|
||||||
|
bool dualDemosaicAutoContrast;
|
||||||
bool dualDemosaicContrast;
|
bool dualDemosaicContrast;
|
||||||
bool pixelShiftMotionCorrectionMethod;
|
bool pixelShiftMotionCorrectionMethod;
|
||||||
bool pixelShiftEperIso;
|
bool pixelShiftEperIso;
|
||||||
@ -774,6 +775,7 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
bool method;
|
bool method;
|
||||||
|
bool dualDemosaicAutoContrast;
|
||||||
bool dualDemosaicContrast;
|
bool dualDemosaicContrast;
|
||||||
bool ccSteps;
|
bool ccSteps;
|
||||||
bool exBlackRed;
|
bool exBlackRed;
|
||||||
|
@ -828,8 +828,10 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param
|
|||||||
|
|
||||||
if (!raw_method->get_active ()) {
|
if (!raw_method->get_active ()) {
|
||||||
filterPE.raw.bayersensor.method = falsePE.raw.bayersensor.method;
|
filterPE.raw.bayersensor.method = falsePE.raw.bayersensor.method;
|
||||||
|
filterPE.raw.bayersensor.dualDemosaicAutoContrast = falsePE.raw.bayersensor.dualDemosaicAutoContrast;
|
||||||
filterPE.raw.bayersensor.dualDemosaicContrast = falsePE.raw.bayersensor.dualDemosaicContrast;
|
filterPE.raw.bayersensor.dualDemosaicContrast = falsePE.raw.bayersensor.dualDemosaicContrast;
|
||||||
filterPE.raw.xtranssensor.method = falsePE.raw.xtranssensor.method;
|
filterPE.raw.xtranssensor.method = falsePE.raw.xtranssensor.method;
|
||||||
|
filterPE.raw.xtranssensor.dualDemosaicAutoContrast = falsePE.raw.xtranssensor.dualDemosaicAutoContrast;
|
||||||
filterPE.raw.xtranssensor.dualDemosaicContrast = falsePE.raw.xtranssensor.dualDemosaicContrast;
|
filterPE.raw.xtranssensor.dualDemosaicContrast = falsePE.raw.xtranssensor.dualDemosaicContrast;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// This number has to be incremented whenever the PP3 file format is modified or the behaviour of a tool changes
|
// This number has to be incremented whenever the PP3 file format is modified or the behaviour of a tool changes
|
||||||
#define PPVERSION 344
|
#define PPVERSION 345
|
||||||
#define PPVERSION_AEXP 301 //value of PPVERSION when auto exposure algorithm was modified
|
#define PPVERSION_AEXP 301 //value of PPVERSION when auto exposure algorithm was modified
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Log of version changes
|
Log of version changes
|
||||||
|
345 2018-10-21
|
||||||
|
dual demosaic auto contrast threshold
|
||||||
344 2018-10-04
|
344 2018-10-04
|
||||||
added Lab/RGB color space selection for shadows/highlights
|
added Lab/RGB color space selection for shadows/highlights
|
||||||
343 2018-09-06
|
343 2018-09-06
|
||||||
|
@ -521,6 +521,8 @@ void ToolPanelCoordinator::initImage (rtengine::StagedImageProcessor* ipc_, bool
|
|||||||
ipc->setAutoCamListener (colorappearance);
|
ipc->setAutoCamListener (colorappearance);
|
||||||
ipc->setAutoBWListener (blackwhite);
|
ipc->setAutoBWListener (blackwhite);
|
||||||
ipc->setFrameCountListener (bayerprocess);
|
ipc->setFrameCountListener (bayerprocess);
|
||||||
|
ipc->setBayerAutoContrastListener (bayerprocess);
|
||||||
|
ipc->setXtransAutoContrastListener (xtransprocess);
|
||||||
ipc->setAutoWBListener (whitebalance);
|
ipc->setAutoWBListener (whitebalance);
|
||||||
ipc->setAutoColorTonListener (colortoning);
|
ipc->setAutoColorTonListener (colortoning);
|
||||||
ipc->setAutoChromaListener (dirpyrdenoise);
|
ipc->setAutoChromaListener (dirpyrdenoise);
|
||||||
|
@ -229,6 +229,7 @@ public:
|
|||||||
|
|
||||||
void imageTypeChanged (bool isRaw, bool isBayer, bool isXtrans, bool isMono = false);
|
void imageTypeChanged (bool isRaw, bool isBayer, bool isXtrans, bool isMono = false);
|
||||||
|
|
||||||
|
// void autoContrastChanged (double autoContrast);
|
||||||
// profilechangelistener interface
|
// profilechangelistener interface
|
||||||
void profileChange(
|
void profileChange(
|
||||||
const rtengine::procparams::PartialProfile* nparams,
|
const rtengine::procparams::PartialProfile* nparams,
|
||||||
|
@ -28,6 +28,7 @@ XTransProcess::XTransProcess () : FoldableToolPanel(this, "xtransprocess", M("TP
|
|||||||
{
|
{
|
||||||
auto m = ProcEventMapper::getInstance();
|
auto m = ProcEventMapper::getInstance();
|
||||||
EvDemosaicContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_DUALDEMOSAIC_CONTRAST");
|
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 ());
|
Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ());
|
||||||
hb1->pack_start (*Gtk::manage (new Gtk::Label ( M("TP_RAW_DMETHOD") + ": ")), Gtk::PACK_SHRINK, 4);
|
hb1->pack_start (*Gtk::manage (new Gtk::Label ( M("TP_RAW_DMETHOD") + ": ")), Gtk::PACK_SHRINK, 4);
|
||||||
@ -71,6 +72,8 @@ XTransProcess::XTransProcess () : FoldableToolPanel(this, "xtransprocess", M("TP
|
|||||||
|
|
||||||
dualDemosaicContrast = Gtk::manage(new Adjuster (M("TP_RAW_DUALDEMOSAICCONTRAST"), 0, 100, 1, 20));
|
dualDemosaicContrast = Gtk::manage(new Adjuster (M("TP_RAW_DUALDEMOSAICCONTRAST"), 0, 100, 1, 20));
|
||||||
dualDemosaicContrast->setAdjusterListener (this);
|
dualDemosaicContrast->setAdjusterListener (this);
|
||||||
|
dualDemosaicContrast->addAutoButton(M("TP_RAW_DUALDEMOSAICAUTOCONTRAST_TOOLTIP"));
|
||||||
|
dualDemosaicContrast->setAutoValue(true);
|
||||||
|
|
||||||
if (dualDemosaicContrast->delay < options.adjusterMaxDelay) {
|
if (dualDemosaicContrast->delay < options.adjusterMaxDelay) {
|
||||||
dualDemosaicContrast->delay = options.adjusterMaxDelay;
|
dualDemosaicContrast->delay = options.adjusterMaxDelay;
|
||||||
@ -94,6 +97,9 @@ XTransProcess::XTransProcess () : FoldableToolPanel(this, "xtransprocess", M("TP
|
|||||||
methodconn = method->signal_changed().connect( sigc::mem_fun(*this, &XTransProcess::methodChanged) );
|
methodconn = method->signal_changed().connect( sigc::mem_fun(*this, &XTransProcess::methodChanged) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XTransProcess::~XTransProcess () {
|
||||||
|
idle_register.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
void XTransProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited)
|
void XTransProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited)
|
||||||
{
|
{
|
||||||
@ -108,6 +114,7 @@ void XTransProcess::read(const rtengine::procparams::ProcParams* pp, const Param
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(pedited ) {
|
if(pedited ) {
|
||||||
|
dualDemosaicContrast->setAutoInconsistent (multiImage && !pedited->raw.xtranssensor.dualDemosaicAutoContrast);
|
||||||
dualDemosaicContrast->setEditedState ( pedited->raw.xtranssensor.dualDemosaicContrast ? Edited : UnEdited);
|
dualDemosaicContrast->setEditedState ( pedited->raw.xtranssensor.dualDemosaicContrast ? Edited : UnEdited);
|
||||||
ccSteps->setEditedState (pedited->raw.xtranssensor.ccSteps ? Edited : UnEdited);
|
ccSteps->setEditedState (pedited->raw.xtranssensor.ccSteps ? Edited : UnEdited);
|
||||||
|
|
||||||
@ -115,8 +122,12 @@ void XTransProcess::read(const rtengine::procparams::ProcParams* pp, const Param
|
|||||||
method->set_active_text(M("GENERAL_UNCHANGED"));
|
method->set_active_text(M("GENERAL_UNCHANGED"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dualDemosaicContrast->setAutoValue(pp->raw.xtranssensor.dualDemosaicAutoContrast);
|
||||||
dualDemosaicContrast->setValue (pp->raw.xtranssensor.dualDemosaicContrast);
|
dualDemosaicContrast->setValue (pp->raw.xtranssensor.dualDemosaicContrast);
|
||||||
ccSteps->setValue (pp->raw.xtranssensor.ccSteps);
|
ccSteps->setValue (pp->raw.xtranssensor.ccSteps);
|
||||||
|
|
||||||
|
lastAutoContrast = pp->raw.bayersensor.dualDemosaicAutoContrast;
|
||||||
|
|
||||||
if (!batchMode) {
|
if (!batchMode) {
|
||||||
dualDemosaicOptions->set_visible(pp->raw.xtranssensor.method == procparams::RAWParams::XTransSensor::getMethodString(procparams::RAWParams::XTransSensor::Method::FOUR_PASS)
|
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));
|
|| pp->raw.xtranssensor.method == procparams::RAWParams::XTransSensor::getMethodString(procparams::RAWParams::XTransSensor::Method::TWO_PASS));
|
||||||
@ -129,6 +140,7 @@ void XTransProcess::read(const rtengine::procparams::ProcParams* pp, const Param
|
|||||||
|
|
||||||
void XTransProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited)
|
void XTransProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited)
|
||||||
{
|
{
|
||||||
|
pp->raw.xtranssensor.dualDemosaicAutoContrast = dualDemosaicContrast->getAutoValue();
|
||||||
pp->raw.xtranssensor.dualDemosaicContrast = dualDemosaicContrast->getValue();
|
pp->raw.xtranssensor.dualDemosaicContrast = dualDemosaicContrast->getValue();
|
||||||
pp->raw.xtranssensor.ccSteps = ccSteps->getIntValue();
|
pp->raw.xtranssensor.ccSteps = ccSteps->getIntValue();
|
||||||
|
|
||||||
@ -140,6 +152,7 @@ void XTransProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* p
|
|||||||
|
|
||||||
if (pedited) {
|
if (pedited) {
|
||||||
pedited->raw.xtranssensor.method = method->get_active_text() != M("GENERAL_UNCHANGED");
|
pedited->raw.xtranssensor.method = method->get_active_text() != M("GENERAL_UNCHANGED");
|
||||||
|
pedited->raw.xtranssensor.dualDemosaicAutoContrast = !dualDemosaicContrast->getAutoInconsistent ();
|
||||||
pedited->raw.xtranssensor.dualDemosaicContrast = dualDemosaicContrast->getEditedState ();
|
pedited->raw.xtranssensor.dualDemosaicContrast = dualDemosaicContrast->getEditedState ();
|
||||||
pedited->raw.xtranssensor.ccSteps = ccSteps->getEditedState ();
|
pedited->raw.xtranssensor.ccSteps = ccSteps->getEditedState ();
|
||||||
}
|
}
|
||||||
@ -187,6 +200,29 @@ void XTransProcess::adjusterChanged(Adjuster* a, double newval)
|
|||||||
|
|
||||||
void XTransProcess::adjusterAutoToggled(Adjuster* a, bool newval)
|
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 ()
|
void XTransProcess::methodChanged ()
|
||||||
@ -211,3 +247,26 @@ void XTransProcess::methodChanged ()
|
|||||||
: EvDemosaicMethod, method->get_active_text());
|
: EvDemosaicMethod, method->get_active_text());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XTransProcess::checkBoxToggled (CheckBox* c, CheckValue newval)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void XTransProcess::autoContrastChanged (double autoContrast)
|
||||||
|
{
|
||||||
|
struct Data {
|
||||||
|
XTransProcess *me;
|
||||||
|
double autoContrast;
|
||||||
|
};
|
||||||
|
const auto func = [](gpointer data) -> gboolean {
|
||||||
|
Data *d = static_cast<Data *>(data);
|
||||||
|
XTransProcess *me = d->me;
|
||||||
|
me->disableListener();
|
||||||
|
me->dualDemosaicContrast->setValue(d->autoContrast);
|
||||||
|
me->enableListener();
|
||||||
|
delete d;
|
||||||
|
return FALSE;
|
||||||
|
};
|
||||||
|
|
||||||
|
idle_register.add(func, new Data { this, autoContrast });
|
||||||
|
}
|
||||||
|
@ -21,11 +21,12 @@
|
|||||||
|
|
||||||
#include <gtkmm.h>
|
#include <gtkmm.h>
|
||||||
#include "adjuster.h"
|
#include "adjuster.h"
|
||||||
|
#include "checkbox.h"
|
||||||
#include "guiutils.h"
|
#include "guiutils.h"
|
||||||
#include "toolpanel.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:
|
protected:
|
||||||
@ -34,14 +35,18 @@ protected:
|
|||||||
Adjuster* ccSteps;
|
Adjuster* ccSteps;
|
||||||
Gtk::VBox *dualDemosaicOptions;
|
Gtk::VBox *dualDemosaicOptions;
|
||||||
Adjuster* dualDemosaicContrast;
|
Adjuster* dualDemosaicContrast;
|
||||||
|
bool lastAutoContrast;
|
||||||
|
|
||||||
int oldSelection;
|
int oldSelection;
|
||||||
sigc::connection methodconn;
|
sigc::connection methodconn;
|
||||||
|
IdleRegister idle_register;
|
||||||
|
rtengine::ProcEvent EvDemosaicAutoContrast;
|
||||||
rtengine::ProcEvent EvDemosaicContrast;
|
rtengine::ProcEvent EvDemosaicContrast;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
XTransProcess ();
|
XTransProcess ();
|
||||||
|
~XTransProcess ();
|
||||||
|
|
||||||
void read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr);
|
void read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr);
|
||||||
void write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr);
|
void write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr);
|
||||||
@ -50,7 +55,9 @@ public:
|
|||||||
void setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr);
|
void setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr);
|
||||||
|
|
||||||
void methodChanged();
|
void methodChanged();
|
||||||
|
void autoContrastChanged (double autoContrast);
|
||||||
void adjusterChanged(Adjuster* a, double newval);
|
void adjusterChanged(Adjuster* a, double newval);
|
||||||
|
void checkBoxToggled(CheckBox* c, CheckValue newval);
|
||||||
void adjusterAutoToggled(Adjuster* a, bool newval);
|
void adjusterAutoToggled(Adjuster* a, bool newval);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user