merge with dev

This commit is contained in:
U-PC-BUREAU\jacques 2018-10-26 09:00:29 +02:00
commit 21292f6db5
34 changed files with 503 additions and 164 deletions

View File

@ -842,7 +842,8 @@ HISTORY_MSG_591;Local - Avoid color shift
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
@ -2046,6 +2047,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

View File

@ -1225,6 +1225,11 @@ Camera constants:
} }
}, },
{ // Quality C
"make_model": "DJI FC6310",
"ranges": { "white": 64886 }
},
{ // Quality B { // Quality B
"make_model": "FUJIFILM GFX 50S", "make_model": "FUJIFILM GFX 50S",
"dcraw_matrix": [ 11756,-4754,-874,-3056,11045,2305,-381,1457,6006 ], // DNGv9.9 D65 "dcraw_matrix": [ 11756,-4754,-874,-3056,11045,2305,-381,1457,6006 ], // DNGv9.9 D65
@ -1338,13 +1343,13 @@ Camera constants:
"make_model": "LG mobile LG-H815", "make_model": "LG mobile LG-H815",
"dcraw_matrix": [ 5859,547,-1250,-6484,15547,547,-2422,5625,3906 ], // DNG D65 "dcraw_matrix": [ 5859,547,-1250,-6484,15547,547,-2422,5625,3906 ], // DNG D65
//"dcraw_matrix": [ 11563,-2891,-3203,-5313,15625,625,-781,2813,5625 ], // DNG A //"dcraw_matrix": [ 11563,-2891,-3203,-5313,15625,625,-781,2813,5625 ], // DNG A
"ranges": { "white_max": 1000 } "ranges": { "white": 1000 }
}, },
{ // Quality C { // Quality C
"make_model": "LG mobile LG-H850", "make_model": "LG mobile LG-H850",
//"dcraw_matrix": [ 10000,-2188,-2813,-5156,15469,625,-703,2734,5078 ], // DNG A //"dcraw_matrix": [ 10000,-2188,-2813,-5156,15469,625,-703,2734,5078 ], // DNG A
"dcraw_matrix": [ 5313,1016,-1172,-6250,15391,547,-2344,5547,3359 ], // DNG D65 "dcraw_matrix": [ 5313,1016,-1172,-6250,15391,547,-2344,5547,3359 ], // DNG D65
"ranges": { "white_max": 1000 } "ranges": { "white": 1000 }
}, },
{ // Quality A { // Quality A
@ -1578,6 +1583,13 @@ Camera constants:
"ranges": { "white": 3980 } // 12-bit files. "ranges": { "white": 3980 } // 12-bit files.
}, },
{ // Quality C, only colour matrix and PDAF lines info
"make_model" : "Nikon Z 7",
"dcraw_matrix" : [10405,-3755,-1270,-5461,13787,1793,-1040,2015,6785], // Adobe DNG Converter 11.0 ColorMatrix2
"pdaf_pattern" : [0, 12],
"pdaf_offset" : 29
},
{ // Quality B, 16Mp and 64Mp raw frames { // Quality B, 16Mp and 64Mp raw frames
"make_model": "OLYMPUS E-M5MarkII", "make_model": "OLYMPUS E-M5MarkII",
"dcraw_matrix": [ 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 ], // DNG_v8.8 D65 "dcraw_matrix": [ 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 ], // DNG_v8.8 D65

View File

@ -6462,7 +6462,9 @@ guess_cfa_pc:
unsigned oldOrder = order; unsigned oldOrder = order;
order = 0x4d4d; // always big endian per definition in https://www.adobe.com/content/dam/acom/en/products/photoshop/pdfs/dng_spec_1.4.0.0.pdf chapter 7 order = 0x4d4d; // always big endian per definition in https://www.adobe.com/content/dam/acom/en/products/photoshop/pdfs/dng_spec_1.4.0.0.pdf chapter 7
unsigned ntags = get4(); // read the number of opcodes unsigned ntags = get4(); // read the number of opcodes
while (ntags--) {
if (ntags < ifp->size / 12) { // rough check for wrong value (happens for example with DNG files from DJI FC6310)
while (ntags-- && !ifp->eof) {
unsigned opcode = get4(); unsigned opcode = get4();
fseek (ifp, 8, SEEK_CUR); // skip 8 bytes as they don't interest us currently fseek (ifp, 8, SEEK_CUR); // skip 8 bytes as they don't interest us currently
if (opcode == 4) { // FixBadPixelsConstant if (opcode == 4) { // FixBadPixelsConstant
@ -6474,6 +6476,7 @@ guess_cfa_pc:
fseek (ifp, get4(), SEEK_CUR); fseek (ifp, get4(), SEEK_CUR);
} }
} }
}
order = oldOrder; order = oldOrder;
break; break;
} }
@ -10062,6 +10065,10 @@ dng_skip:
adobe_coeff (make, model); adobe_coeff (make, model);
if((!strncmp(make, "XIAOYI", 6) || !strncmp(make, "YI", 2)) && !strncmp(model, "M1",2)) if((!strncmp(make, "XIAOYI", 6) || !strncmp(make, "YI", 2)) && !strncmp(model, "M1",2))
adobe_coeff (make, model); adobe_coeff (make, model);
if(!strncmp(make, "DJI", 3) && !strncmp(model, "FC6310", 6)) // DNG files from this camera have wrong (too high) white level
adobe_coeff (make, model);
if (!strncmp(make, "LG", 2) && (!strncmp(model, "LG-H850",7) || !strncmp(model, "LG-H815",7)))
adobe_coeff (make, model);
if (raw_color) adobe_coeff (make, model); if (raw_color) adobe_coeff (make, model);
if (load_raw == &CLASS kodak_radc_load_raw) if (load_raw == &CLASS kodak_radc_load_raw)
if (raw_color) adobe_coeff ("Apple","Quicktake"); if (raw_color) adobe_coeff ("Apple","Quicktake");

View File

@ -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>

View File

@ -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

View File

@ -83,6 +83,7 @@ public:
virtual void setBorder (unsigned int border) {} virtual void setBorder (unsigned int border) {}
virtual void setCurrentFrame (unsigned int frameNum) = 0; virtual void setCurrentFrame (unsigned int frameNum) = 0;
virtual int getFrameCount () = 0; virtual int getFrameCount () = 0;
virtual int getFlatFieldAutoClipValue () = 0;
// use right after demosaicing image, add coarse transformation and put the result in the provided Imagefloat* // use right after demosaicing image, add coarse transformation and put the result in the provided Imagefloat*

View File

@ -101,7 +101,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), flatFieldAutoClipListener(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), butili(false), ccutili(false), cclutili(false), clcutili(false), opautili(false), wavcontlutili(false),
locallutili(false), localcutili(false), localskutili(false), localexutili(false), LHutili(false), HHutili(false), locallutili(false), localcutili(false), localskutili(false), localexutili(false), LHutili(false), HHutili(false),
@ -228,6 +228,9 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
imgsrc->setCurrentFrame(params.raw.bayersensor.imageNum); imgsrc->setCurrentFrame(params.raw.bayersensor.imageNum);
imgsrc->preprocess(rp, params.lensProf, params.coarse); imgsrc->preprocess(rp, params.lensProf, params.coarse);
if (flatFieldAutoClipListener && rp.ff_AutoClipControl) {
flatFieldAutoClipListener->flatFieldAutoClipValueChanged(imgsrc->getFlatFieldAutoClipValue());
}
imgsrc->getRAWHistogram(histRedRaw, histGreenRaw, histBlueRaw); imgsrc->getRAWHistogram(histRedRaw, histGreenRaw, histBlueRaw);
highDetailPreprocessComputed = highDetailNeeded; highDetailPreprocessComputed = highDetailNeeded;
@ -268,10 +271,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;
@ -1022,7 +1032,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
// process crop, if needed // process crop, if needed
for (size_t i = 0; i < crops.size(); i++) for (size_t i = 0; i < crops.size(); i++)
if (crops[i]->hasListener() && (panningRelatedChange || (todo & (M_MONITOR | M_RGBCURVE | M_LUMACURVE)) || crops[i]->get_skip() == 1)) { if (crops[i]->hasListener() && (panningRelatedChange || (highDetailNeeded && options.prevdemo != PD_Sidecar) || (todo & (M_MONITOR | M_RGBCURVE | M_LUMACURVE)) || crops[i]->get_skip() == 1)) {
crops[i]->update(todo); // may call ourselves crops[i]->update(todo); // may call ourselves
} }

View File

@ -182,6 +182,9 @@ protected:
AutoCamListener* acListener; AutoCamListener* acListener;
AutoBWListener* abwListener; AutoBWListener* abwListener;
AutoWBListener* awbListener; AutoWBListener* awbListener;
FlatFieldAutoClipListener *flatFieldAutoClipListener;
AutoContrastListener *bayerAutoContrastListener;
AutoContrastListener *xtransAutoContrastListener;
FrameCountListener *frameCountListener; FrameCountListener *frameCountListener;
ImageTypeListener *imageTypeListener; ImageTypeListener *imageTypeListener;
AutoColorTonListener* actListener; AutoColorTonListener* actListener;
@ -407,6 +410,20 @@ public:
frameCountListener = fcl; frameCountListener = fcl;
} }
void setFlatFieldAutoClipListener (FlatFieldAutoClipListener* ffacl)
{
flatFieldAutoClipListener = ffacl;
}
void setBayerAutoContrastListener (AutoContrastListener* acl)
{
bayerAutoContrastListener = acl;
}
void setXtransAutoContrastListener (AutoContrastListener* acl)
{
xtransAutoContrastListener = acl;
}
void setImageTypeListener(ImageTypeListener* itl) void setImageTypeListener(ImageTypeListener* itl)
{ {
imageTypeListener = itl; imageTypeListener = itl;

View File

@ -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;
@ -292,7 +293,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
@ -326,7 +328,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
@ -680,7 +683,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
@ -889,7 +893,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
@ -922,7 +927,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

View File

@ -2635,6 +2635,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),
@ -2672,6 +2673,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
@ -2759,6 +2761,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),
@ -2771,6 +2774,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
@ -3776,6 +3780,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);
@ -3793,6 +3798,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);
@ -5458,6 +5464,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")) {
@ -5509,6 +5522,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);

View File

@ -1416,6 +1416,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;
@ -1463,6 +1464,7 @@ struct RAWParams {
}; };
Glib::ustring method; Glib::ustring method;
bool dualDemosaicAutoContrast;
double dualDemosaicContrast; double dualDemosaicContrast;
int ccSteps; int ccSteps;
double blackred; double blackred;

View File

@ -2086,7 +2086,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);
@ -2119,7 +2119,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);
@ -2883,8 +2883,6 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
float limitFactor = 1.f; float limitFactor = 1.f;
if (raw.ff_AutoClipControl) { if (raw.ff_AutoClipControl) {
// int clipControlGui = 0;
for (int m = 0; m < 2; m++) for (int m = 0; m < 2; m++)
for (int n = 0; n < 2; n++) { for (int n = 0; n < 2; n++) {
float maxval = 0.f; float maxval = 0.f;
@ -2928,7 +2926,7 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
} }
} }
// clipControlGui = (1.f - limitFactor) * 100.f; // this value can be used to set the clip control slider in gui flatFieldAutoClipValue = (1.f - limitFactor) * 100.f; // this value can be used to set the clip control slider in gui
} else { } else {
limitFactor = max((float)(100 - raw.ff_clipControl) / 100.f, 0.01f); limitFactor = max((float)(100 - raw.ff_clipControl) / 100.f, 0.01f);
} }
@ -3014,7 +3012,6 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
if (raw.ff_AutoClipControl) { if (raw.ff_AutoClipControl) {
// determine maximum calculated value to avoid clipping // determine maximum calculated value to avoid clipping
// int clipControlGui = 0;
float maxval = 0.f; float maxval = 0.f;
// xtrans files have only one black level actually, so we can simplify the code a bit // xtrans files have only one black level actually, so we can simplify the code a bit
#ifdef _OPENMP #ifdef _OPENMP
@ -3049,7 +3046,7 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
// there's only one white level for xtrans // there's only one white level for xtrans
if (maxval + black[0] > ri->get_white(0)) { if (maxval + black[0] > ri->get_white(0)) {
limitFactor = ri->get_white(0) / (maxval + black[0]); limitFactor = ri->get_white(0) / (maxval + black[0]);
// clipControlGui = (1.f - limitFactor) * 100.f; // this value can be used to set the clip control slider in gui flatFieldAutoClipValue = (1.f - limitFactor) * 100.f; // this value can be used to set the clip control slider in gui
} }
} else { } else {
limitFactor = max((float)(100 - raw.ff_clipControl) / 100.f, 0.01f); limitFactor = max((float)(100 - raw.ff_clipControl) / 100.f, 0.01f);

View File

@ -74,7 +74,7 @@ protected:
RawImage* riFrames[4] = {nullptr}; RawImage* riFrames[4] = {nullptr};
unsigned int currFrame = 0; unsigned int currFrame = 0;
unsigned int numFrames = 0; unsigned int numFrames = 0;
int flatFieldAutoClipValue = 0;
array2D<float> rawData; // holds preprocessed pixel values, rowData[i][j] corresponds to the ith row and jth column array2D<float> rawData; // holds preprocessed pixel values, rowData[i][j] corresponds to the ith row and jth column
array2D<float> *rawDataFrames[4] = {nullptr}; array2D<float> *rawDataFrames[4] = {nullptr};
array2D<float> *rawDataBuffer[3] = {nullptr}; array2D<float> *rawDataBuffer[3] = {nullptr};
@ -212,10 +212,9 @@ public:
currFrame = std::min(numFrames - 1, frameNum); currFrame = std::min(numFrames - 1, frameNum);
ri = riFrames[currFrame]; ri = riFrames[currFrame];
} }
int getFrameCount() int getFrameCount(){return numFrames;}
{ int getFlatFieldAutoClipValue() {return flatFieldAutoClipValue;}
return numFrames;
}
class GreenEqulibrateThreshold { class GreenEqulibrateThreshold {
public: public:
@ -278,7 +277,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();

View File

@ -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,9 +192,99 @@ 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) {
if(contrastThreshold == 0.f && !autoContrast) {
for(int j = 0; j < H; ++j) {
for(int i = 0; i < W; ++i) {
blend[j][i] = amount;
}
}
} else {
constexpr float scale = 0.0625f / 327.68f; constexpr float scale = 0.0625f / 327.68f;
if (autoContrast) {
for (int pass = 0; pass < 2; ++pass) {
const int tilesize = 80 / (pass + 1);
const int numTilesW = W / tilesize;
const int numTilesH = H / tilesize;
std::vector<std::vector<std::pair<float, float>>> variances(numTilesH, std::vector<std::pair<float, float>>(numTilesW));
#pragma omp parallel for
for (int i = 0; i < numTilesH; ++i) {
int tileY = i * tilesize;
for (int j = 0; j < numTilesW; ++j) {
int tileX = j * tilesize;
#ifdef __SSE2__
vfloat avgv = ZEROV;
for (int y = tileY; y < tileY + tilesize; ++y) {
for (int x = tileX; x < tileX + tilesize; x += 4) {
avgv += LVFU(luminance[y][x]);
}
}
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;
}
}
float minvar = RT_INFINITY_F;
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;
}
}
}
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) { if(contrastThreshold == 0.f) {
for(int j = 0; j < H; ++j) { for(int j = 0; j < H; ++j) {
@ -261,6 +353,7 @@ void buildBlendMask(float** luminance, float **blend, int W, int H, float contra
gaussianBlur(blend, blend, W, H, 2.0); gaussianBlur(blend, blend, W, H, 2.0);
} }
} }
}
} }
int calcContrastThreshold(float** luminance, float **blend, int W, int H) { int calcContrastThreshold(float** luminance, float **blend, int W, int H) {
@ -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;
} }
} }

View File

@ -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);
} }

View File

@ -372,6 +372,13 @@ public:
virtual void FrameCountChanged(int n, int frameNum) = 0; virtual void FrameCountChanged(int n, int frameNum) = 0;
}; };
class FlatFieldAutoClipListener
{
public:
virtual ~FlatFieldAutoClipListener() = default;
virtual void flatFieldAutoClipValueChanged(int n) = 0;
};
class ImageTypeListener class ImageTypeListener
{ {
public: public:
@ -379,6 +386,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,7 +496,10 @@ public:
virtual void setHistogramListener (HistogramListener *l) = 0; virtual void setHistogramListener (HistogramListener *l) = 0;
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 setFlatFieldAutoClipListener (FlatFieldAutoClipListener* 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;

View File

@ -214,8 +214,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) {

View File

@ -100,6 +100,7 @@ public:
} }
void setCurrentFrame(unsigned int frameNum) {} void setCurrentFrame(unsigned int frameNum) {}
int getFrameCount() {return 1;} int getFrameCount() {return 1;}
int getFlatFieldAutoClipValue() {return 0;}
void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) { R = G = B = 0;} void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) { R = G = B = 0;}

View File

@ -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);
} }
} }
} }

View File

@ -322,7 +322,7 @@ void BatchQueuePanel::addBatchQueueJobs(const std::vector<BatchQueueEntry*>& ent
bool BatchQueuePanel::canStartNext () bool BatchQueuePanel::canStartNext ()
{ {
// GThreadLock lock;
if (qStartStop->get_active()) { if (qStartStop->get_active()) {
return true; return true;
} else { } else {

View File

@ -385,9 +385,8 @@ void BatchToolPanelCoordinator::initSession ()
} }
} }
void BatchToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib::ustring& descr) void BatchToolPanelCoordinator::panelChanged(const rtengine::ProcEvent& event, const Glib::ustring& descr)
{ {
if (selected.empty()) { if (selected.empty()) {
return; return;
} }
@ -613,9 +612,14 @@ void BatchToolPanelCoordinator::endBatchPParamsChange()
* Using a Profile panel in the batch tool panel editor is actually * Using a Profile panel in the batch tool panel editor is actually
* not supported by BatchToolPanelCoordinator::profileChange! * not supported by BatchToolPanelCoordinator::profileChange!
*/ */
void BatchToolPanelCoordinator::profileChange (const rtengine::procparams::PartialProfile* nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited) void BatchToolPanelCoordinator::profileChange(
const PartialProfile* nparams,
const rtengine::ProcEvent& event,
const Glib::ustring& descr,
const ParamsEdited* paramsEdited,
bool fromLastSave
)
{ {
if (event == rtengine::EvProfileChanged) { if (event == rtengine::EvProfileChanged) {
// a profile has been selected in a hypothetical Profile panel // a profile has been selected in a hypothetical Profile panel
// -> ACTUALLY NOT SUPPORTED // -> ACTUALLY NOT SUPPORTED

View File

@ -51,30 +51,36 @@ public:
explicit BatchToolPanelCoordinator (FilePanel* parent); explicit BatchToolPanelCoordinator (FilePanel* parent);
// FileSelectionChangeListener interface // FileSelectionChangeListener interface
void selectionChanged (const std::vector<Thumbnail*>& selected); void selectionChanged (const std::vector<Thumbnail*>& selected) override;
// toolpanellistener interface // toolpanellistener interface
void panelChanged (rtengine::ProcEvent event, const Glib::ustring& descr); void panelChanged(const rtengine::ProcEvent& event, const Glib::ustring& descr) override;
// profilechangelistener interface // profilechangelistener interface
void profileChange (const rtengine::procparams::PartialProfile* nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited = nullptr); void profileChange(
const rtengine::procparams::PartialProfile* nparams,
const rtengine::ProcEvent& event,
const Glib::ustring& descr,
const ParamsEdited* paramsEdited = nullptr,
bool fromLastSave = false
) override;
// wbprovider interface // wbprovider interface
void getAutoWB (double& temp, double& green, double equal, double tempBias); void getAutoWB (double& temp, double& green, double equal, double tempBias) override;
void getCamWB (double& temp, double& green); void getCamWB (double& temp, double& green);
// thumbnaillistener interface // thumbnaillistener interface
void procParamsChanged (Thumbnail* thm, int whoChangedIt); void procParamsChanged (Thumbnail* thm, int whoChangedIt) override;
// batchpparamschangelistener interface // batchpparamschangelistener interface
void beginBatchPParamsChange(int numberOfEntries); void beginBatchPParamsChange(int numberOfEntries) override;
void endBatchPParamsChange(); void endBatchPParamsChange() override;
// imageareatoollistener interface // imageareatoollistener interface
void spotWBselected (int x, int y, Thumbnail* thm = nullptr); void spotWBselected (int x, int y, Thumbnail* thm = nullptr) override;
void cropSelectionReady (); void cropSelectionReady () override;
void rotateSelectionReady (double rotate_deg, Thumbnail* thm = nullptr); void rotateSelectionReady (double rotate_deg, Thumbnail* thm = nullptr) override;
CropGUIListener* startCropEditing (Thumbnail* thm = nullptr); CropGUIListener* startCropEditing (Thumbnail* thm = nullptr) override;
void optionsChanged (); void optionsChanged ();
}; };

View File

@ -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 });
}

View File

@ -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);
}; };

View File

@ -104,6 +104,11 @@ FlatField::FlatField () : FoldableToolPanel(this, "flatfield", M("TP_FLATFIELD_L
} }
} }
FlatField::~FlatField ()
{
idle_register.destroy();
}
void FlatField::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) void FlatField::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited)
{ {
disableListener (); disableListener ();
@ -403,3 +408,22 @@ void FlatField::setShortcutPath(const Glib::ustring& path)
} catch (Glib::Error&) {} } catch (Glib::Error&) {}
} }
void FlatField::flatFieldAutoClipValueChanged(int n)
{
struct Data {
FlatField *me;
int n;
};
const auto func = [](gpointer data) -> gboolean {
Data *d = static_cast<Data *>(data);
FlatField *me = d->me;
me->disableListener();
me->flatFieldClipControl->setValue (d->n);
me->enableListener();
delete d;
return FALSE;
};
idle_register.add(func, new Data { this, n });
}

View File

@ -35,7 +35,7 @@ public:
// add other info here // add other info here
}; };
class FlatField : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel class FlatField : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::FlatFieldAutoClipListener
{ {
protected: protected:
@ -58,9 +58,11 @@ protected:
bool b_filter_asCurrent; bool b_filter_asCurrent;
bool israw; bool israw;
IdleRegister idle_register;
public: public:
FlatField (); FlatField ();
~FlatField ();
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);
@ -80,6 +82,7 @@ public:
{ {
ffp = p; ffp = p;
}; };
void flatFieldAutoClipValueChanged(int n = 0);
}; };
#endif #endif

View File

@ -521,6 +521,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;
@ -541,6 +542,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;
@ -1194,6 +1196,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;
@ -1214,6 +1217,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;
@ -3169,6 +3173,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;
} }
@ -3249,6 +3257,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;
} }
@ -3769,7 +3781,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;
@ -3777,7 +3789,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

View File

@ -857,6 +857,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;
@ -887,6 +888,7 @@ public:
public: public:
bool method; bool method;
bool dualDemosaicAutoContrast;
bool dualDemosaicContrast; bool dualDemosaicContrast;
bool ccSteps; bool ccSteps;
bool exBlackRed; bool exBlackRed;

View File

@ -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;
} }

View File

@ -1,13 +1,15 @@
#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 345 #define PPVERSION 346
#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-09-25 346 2018-09-25
Added Locallab tool parameters Added Locallab tool parameters
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

View File

@ -598,6 +598,9 @@ 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->setFlatFieldAutoClipListener (flatfield);
ipc->setBayerAutoContrastListener (bayerprocess);
ipc->setXtransAutoContrastListener (xtransprocess);
ipc->setAutoWBListener(whitebalance); ipc->setAutoWBListener(whitebalance);
ipc->setAutoColorTonListener(colortoning); ipc->setAutoColorTonListener(colortoning);
ipc->setAutoChromaListener(dirpyrdenoise); ipc->setAutoChromaListener(dirpyrdenoise);

View File

@ -237,6 +237,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,

View File

@ -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 });
}

View File

@ -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);
}; };