Improve Dehaze for Raw files - Raw black point (#7133)

* Show min raw values in console, #5769

* Speedup

* outsourced calculation of raw min values

* First try GUI

* Improve GUI

* Clean code

* Change behavior GUI

* First step GUI Xtrans

* Second step GUI Xtrans

* Last step X-trans black dehaze

* Appimage and windows yml poordeha

* disabled sliders R G B when dehaze enabled

* Remove idle_register autoblackchanged

* Changes suggested by Lawrence37 to improve double processing

* Remove yml appaimage windows

---------

Co-authored-by: Ingo Weyrich <heckflosse67@gmx.de>
This commit is contained in:
Desmis 2024-09-17 08:29:21 +02:00 committed by GitHub
parent 40dccc3fcf
commit 348c8e8894
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 410 additions and 34 deletions

View File

@ -1404,6 +1404,8 @@ HISTORY_MSG_COLORTONING_LABREGION_SHOWMASK;CT - region show mask
HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - region slope
HISTORY_MSG_COMPLEX;Wavelet complexity
HISTORY_MSG_COMPLEXRETI;Retinex complexity
HISTORY_MSG_DEHABLACK;Dehaze Bayer Black
HISTORY_MSG_DEHABLACKX;Dehaze X-Trans Black
HISTORY_MSG_DEHAZE_DEPTH;Dehaze - Depth
HISTORY_MSG_DEHAZE_ENABLED;Haze Removal
HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation
@ -3782,6 +3784,7 @@ TP_RAWEXPOS_BLACK_3;Green 2
TP_RAWEXPOS_BLACK_BLUE;Blue
TP_RAWEXPOS_BLACK_GREEN;Green
TP_RAWEXPOS_BLACK_RED;Red
TP_RAWEXPOS_DEHA;Dehaze
TP_RAWEXPOS_LINEAR;White-point correction
TP_RAWEXPOS_RGB;Red, Green, Blue
TP_RAWEXPOS_TWOGREEN;Link greens

View File

@ -91,7 +91,7 @@ public:
~ImageSource () override {}
virtual int load (const Glib::ustring &fname) = 0;
virtual void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, bool prepareDenoise = true) {};
virtual void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, float &reddeha, float &greendeha, float &bluedeha, bool prepareDenoise = true) {};
virtual void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold, bool cache = false) {};
virtual void retinex (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &deh, const procparams::ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D<float, 4> &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) {};
virtual void retinexPrepareCurves (const procparams::RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) {};

View File

@ -153,6 +153,7 @@ ImProcCoordinator::ImProcCoordinator() :
imageListener(nullptr),
aeListener(nullptr),
acListener(nullptr),
ablListener(nullptr),
abwListener(nullptr),
awbListener(nullptr),
flatFieldAutoClipListener(nullptr),
@ -383,11 +384,26 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
}
// raw auto CA is bypassed if no high detail is needed, so we have to compute it when high detail is needed
float reddeha = 0.f;//initialize black red, blue, green for dehaze
float greendeha = 0.f;
float bluedeha = 0.f;
if ((todo & M_PREPROC) || (!highDetailPreprocessComputed && highDetailNeeded)) {
imgsrc->setCurrentFrame(params->raw.bayersensor.imageNum);
imgsrc->preprocess(rp, params->lensProf, params->coarse);
imgsrc->preprocess(rp, params->lensProf, params->coarse, reddeha, greendeha, bluedeha, true);
if(imgsrc->getSensorType() == ST_BAYER) {//Bayer
if (ablListener) {
if(rp.bayersensor.Dehablack) {
ablListener->autoBlackChanged(reddeha, greendeha, bluedeha);
}
}
} else if(imgsrc->getSensorType() == ST_FUJI_XTRANS) {//X trans
if (ablxListener) {
if(rp.xtranssensor.Dehablackx) {
ablxListener->autoBlackxChanged(reddeha, greendeha, bluedeha);
}
}
}
if (flatFieldAutoClipListener && rp.ff_AutoClipControl) {
flatFieldAutoClipListener->flatFieldAutoClipValueChanged(imgsrc->getFlatFieldAutoClipValue());
}
@ -3038,7 +3054,10 @@ void ImProcCoordinator::saveInputICCReference(const Glib::ustring& fname, bool a
ppar.toneCurve.hrenabled = false;
ppar.icm.inputProfile = "(none)";
Imagefloat* im = new Imagefloat(fW, fH);
imgsrc->preprocess(ppar.raw, ppar.lensProf, ppar.coarse);
float reddeha = 0.f;
float greendeha = 0.f;
float bluedeha = 0.f;
imgsrc->preprocess(ppar.raw, ppar.lensProf, ppar.coarse,reddeha, greendeha, bluedeha, true);
double dummy = 0.0;
imgsrc->demosaic(ppar.raw, false, dummy);
ColorTemp currWB = ColorTemp(validParams->wb.temperature, validParams->wb.green, validParams->wb.equal, validParams->wb.method, validParams->wb.observer);

View File

@ -182,6 +182,8 @@ protected:
PreviewImageListener* imageListener;
AutoExpListener* aeListener;
AutoCamListener* acListener;
AutoBlackListener* ablListener;
AutoBlackxListener* ablxListener;
AutoBWListener* abwListener;
AutoWBListener* awbListener;
FlatFieldAutoClipListener *flatFieldAutoClipListener;
@ -518,6 +520,15 @@ public:
{
acListener = acl;
}
void setAutoBlackListener (AutoBlackListener* abl) override
{
ablListener = abl;
}
void setAutoBlackxListener (AutoBlackxListener* ablx) override
{
ablxListener = ablx;
}
void setAutoBWListener (AutoBWListener* abw) override
{
abwListener = abw;

View File

@ -116,7 +116,10 @@ PreviewImage::PreviewImage (const Glib::ustring &fname, const Glib::ustring &ext
params.raw.deadPixelFilter = false;
params.raw.ca_autocorrect = false;
params.raw.xtranssensor.method = RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FAST);
rawImage.preprocess(params.raw, params.lensProf, params.coarse);
float reddeha = 0.f;
float greendeha = 0.f;
float bluedeha = 0.f;
rawImage.preprocess(params.raw, params.lensProf, params.coarse, reddeha, greendeha, bluedeha, true);
double contrastThresholdDummy = 0.0;
rawImage.demosaic(params.raw, false, contrastThresholdDummy);
Imagefloat image(fw, fh);

View File

@ -5810,6 +5810,7 @@ RAWParams::BayerSensor::BayerSensor() :
black2(0.0),
black3(0.0),
twogreen(true),
Dehablack(false),
linenoise(0),
linenoiseDirection(LineNoiseDirection::BOTH),
greenthresh(0),
@ -5849,6 +5850,7 @@ bool RAWParams::BayerSensor::operator ==(const BayerSensor& other) const
&& black2 == other.black2
&& black3 == other.black3
&& twogreen == other.twogreen
&& Dehablack == other.Dehablack
&& linenoise == other.linenoise
&& linenoiseDirection == other.linenoiseDirection
&& greenthresh == other.greenthresh
@ -5952,7 +5954,9 @@ RAWParams::XTransSensor::XTransSensor() :
ccSteps(0),
blackred(0.0),
blackgreen(0.0),
blackblue(0.0)
blackblue(0.0),
Dehablackx(false)
{
}
@ -5966,7 +5970,8 @@ bool RAWParams::XTransSensor::operator ==(const XTransSensor& other) const
&& ccSteps == other.ccSteps
&& blackred == other.blackred
&& blackgreen == other.blackgreen
&& blackblue == other.blackblue;
&& blackblue == other.blackblue
&& Dehablackx == other.Dehablackx;
}
bool RAWParams::XTransSensor::operator !=(const XTransSensor& other) const
@ -8080,6 +8085,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
saveToKeyfile(!pedited || pedited->raw.bayersensor.exBlack2, "RAW Bayer", "PreBlack2", raw.bayersensor.black2, keyFile);
saveToKeyfile(!pedited || pedited->raw.bayersensor.exBlack3, "RAW Bayer", "PreBlack3", raw.bayersensor.black3, keyFile);
saveToKeyfile(!pedited || pedited->raw.bayersensor.exTwoGreen, "RAW Bayer", "PreTwoGreen", raw.bayersensor.twogreen, keyFile);
saveToKeyfile(!pedited || pedited->raw.bayersensor.Dehablack, "RAW Bayer", "Dehablack", raw.bayersensor.Dehablack, keyFile);
saveToKeyfile(!pedited || pedited->raw.bayersensor.linenoise, "RAW Bayer", "LineDenoise", raw.bayersensor.linenoise, keyFile);
saveToKeyfile(!pedited || pedited->raw.bayersensor.linenoise, "RAW Bayer", "LineDenoiseDirection", toUnderlying(raw.bayersensor.linenoiseDirection), keyFile);
saveToKeyfile(!pedited || pedited->raw.bayersensor.greenEq, "RAW Bayer", "GreenEqThreshold", raw.bayersensor.greenthresh, keyFile);
@ -8112,6 +8118,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
saveToKeyfile(!pedited || pedited->raw.xtranssensor.exBlackRed, "RAW X-Trans", "PreBlackRed", raw.xtranssensor.blackred, keyFile);
saveToKeyfile(!pedited || pedited->raw.xtranssensor.exBlackGreen, "RAW X-Trans", "PreBlackGreen", raw.xtranssensor.blackgreen, keyFile);
saveToKeyfile(!pedited || pedited->raw.xtranssensor.exBlackBlue, "RAW X-Trans", "PreBlackBlue", raw.xtranssensor.blackblue, keyFile);
saveToKeyfile(!pedited || pedited->raw.xtranssensor.Dehablackx, "RAW X-Trans", "Dehablackx", raw.xtranssensor.Dehablackx, keyFile);
// Raw exposition
saveToKeyfile(!pedited || pedited->raw.exPos, "RAW", "PreExposure", raw.expos, keyFile);
@ -11099,6 +11106,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
assignFromKeyfile(keyFile, "RAW Bayer", "PreBlack2", raw.bayersensor.black2, pedited->raw.bayersensor.exBlack2);
assignFromKeyfile(keyFile, "RAW Bayer", "PreBlack3", raw.bayersensor.black3, pedited->raw.bayersensor.exBlack3);
assignFromKeyfile(keyFile, "RAW Bayer", "PreTwoGreen", raw.bayersensor.twogreen, pedited->raw.bayersensor.exTwoGreen);
assignFromKeyfile(keyFile, "RAW Bayer", "Dehablack", raw.bayersensor.Dehablack, pedited->raw.bayersensor.Dehablack);
assignFromKeyfile(keyFile, "RAW Bayer", "LineDenoise", raw.bayersensor.linenoise, pedited->raw.bayersensor.linenoise);
if (keyFile.has_key("RAW Bayer", "LineDenoiseDirection")) {
@ -11185,6 +11193,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
assignFromKeyfile(keyFile, "RAW X-Trans", "PreBlackRed", raw.xtranssensor.blackred, pedited->raw.xtranssensor.exBlackRed);
assignFromKeyfile(keyFile, "RAW X-Trans", "PreBlackGreen", raw.xtranssensor.blackgreen, pedited->raw.xtranssensor.exBlackGreen);
assignFromKeyfile(keyFile, "RAW X-Trans", "PreBlackBlue", raw.xtranssensor.blackblue, pedited->raw.xtranssensor.exBlackBlue);
assignFromKeyfile(keyFile, "RAW X-Trans", "Dehablackx", raw.xtranssensor.Dehablackx, pedited->raw.xtranssensor.Dehablackx);
}
if (keyFile.has_group("Film Negative")) {

View File

@ -2517,6 +2517,7 @@ struct RAWParams {
double black2;
double black3;
bool twogreen;
bool Dehablack;
int linenoise;
enum class LineNoiseDirection {
HORIZONTAL = 1,
@ -2584,6 +2585,7 @@ struct RAWParams {
double blackred;
double blackgreen;
double blackblue;
bool Dehablackx;
XTransSensor();

View File

@ -1432,7 +1432,7 @@ int RawImageSource::load(const Glib::ustring &fname, bool firstFrameOnly)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse, bool prepareDenoise)
void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse, float &reddeha, float &greendeha, float &bluedeha, bool prepareDenoise)
{
// BENCHFUN
MyTime t1, t2;
@ -1510,7 +1510,7 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens
for (unsigned int i = 0; i < 4; ++i) {
if (i == currFrame) {
copyOriginalPixels(raw, ri, rid, rif, rawData);
copyOriginalPixels(raw, ri, rid, rif, rawData, reddeha, greendeha, bluedeha);
rawDataFrames[i] = &rawData;
} else {
if (!rawDataBuffer[bufferNumber]) {
@ -1519,7 +1519,7 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens
rawDataFrames[i] = rawDataBuffer[bufferNumber];
++bufferNumber;
copyOriginalPixels(raw, riFrames[i], rid, rif, *rawDataFrames[i]);
copyOriginalPixels(raw, riFrames[i], rid, rif, *rawDataFrames[i], reddeha, greendeha, bluedeha);
}
}
} else if (numFrames == 2 && currFrame == 2) { // average the frames
@ -1528,8 +1528,8 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens
}
rawDataFrames[1] = rawDataBuffer[0];
copyOriginalPixels(raw, riFrames[1], rid, rif, *rawDataFrames[1]);
copyOriginalPixels(raw, ri, rid, rif, rawData);
copyOriginalPixels(raw, riFrames[1], rid, rif, *rawDataFrames[1], reddeha, greendeha, bluedeha);
copyOriginalPixels(raw, ri, rid, rif, rawData, reddeha, greendeha, bluedeha);
for (int i = 0; i < H; ++i) {
for (int j = 0; j < W; ++j) {
@ -1537,7 +1537,7 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens
}
}
} else {
copyOriginalPixels(raw, ri, rid, rif, rawData);
copyOriginalPixels(raw, ri, rid, rif, rawData, reddeha, greendeha, bluedeha);
}
//FLATFIELD end
@ -2634,8 +2634,9 @@ void RawImageSource::HLRecovery_Global(const ToneCurveParams &hrp)
/* Copy original pixel data and
* subtract dark frame (if present) from current image and apply flat field correction (if present)
*/
void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, const RawImage *riDark, RawImage *riFlatFile, array2D<float> &rawData)
void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, const RawImage *riDark, RawImage *riFlatFile, array2D<float> &rawData, float &reddeha, float &greendeha, float &bluedeha)
{
minVals[0] = minVals[1] = minVals[2] = std::numeric_limits<float>::max();
const auto tmpfilters = ri->get_filters();
ri->set_filters(ri->prefilters); // we need 4 blacks for bayer processing
float black[4];
@ -2681,8 +2682,19 @@ void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, con
}
}
}
/*
Copyright (c) Ingo Weyrich 2020 (heckflosse67@gmx.de)
*/
if (ri->getSensorType() == ST_BAYER) {
getMinValsBayer(ri->zeroIsBad());
} else {
getMinValsXtrans();
}
//
reddeha = minVals[0];
greendeha = minVals[1];
bluedeha = minVals[2];
if (riFlatFile && W == riFlatFile->get_width() && H == riFlatFile->get_height()) {
processFlatField(raw, riFlatFile, rawData, black);
} // flatfield
@ -2749,18 +2761,32 @@ void RawImageSource::scaleColors(int winx, int winy, int winw, int winh, const R
if (getSensorType() == ST_BAYER || getSensorType() == ST_FOVEON) {
if (raw.bayersensor.Dehablack) {
black_lev[0] = minVals[0];
black_lev[1] = minVals[1];
black_lev[2] = minVals[2];
black_lev[3] = minVals[1];
} else {
black_lev[0] = raw.bayersensor.black1; //R
black_lev[1] = raw.bayersensor.black0; //G1
black_lev[2] = raw.bayersensor.black2; //B
black_lev[3] = raw.bayersensor.black3; //G2
}
isMono = RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::MONO) == raw.bayersensor.method;
} else if (getSensorType() == ST_FUJI_XTRANS) {
if (raw.xtranssensor.Dehablackx) {
black_lev[0] = minVals[0];
black_lev[1] = minVals[1];
black_lev[2] = minVals[2];
black_lev[3] = minVals[1];
} else {
black_lev[0] = raw.xtranssensor.blackred; //R
black_lev[1] = raw.xtranssensor.blackgreen; //G1
black_lev[2] = raw.xtranssensor.blackblue; //B
black_lev[3] = raw.xtranssensor.blackgreen; //G2 (set, only used with a Bayer filter)
}
isMono = RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::MONO) == raw.xtranssensor.method;
}
@ -8352,6 +8378,54 @@ void RawImageSource::getRawValues(int x, int y, int rotate, int &R, int &G, int
B = 0;
}
}
/*
Copyright (c) Ingo Weyrich 2020 (heckflosse67@gmx.de)
*/
void RawImageSource::getMinValsXtrans() {
#ifdef _OPENMP
#pragma omp parallel for reduction (min:minVals)
#endif
for (int row = 0; row < H; ++row) {
const int c0 = ri->XTRANSFC(row, 0);
const int c1 = ri->XTRANSFC(row, 1);
const int c2 = ri->XTRANSFC(row, 2);
const int c3 = ri->XTRANSFC(row, 3);
const int c4 = ri->XTRANSFC(row, 4);
const int c5 = ri->XTRANSFC(row, 5);
const float cb0 = c_black[c0];
const float cb1 = c_black[c1];
const float cb2 = c_black[c2];
const float cb3 = c_black[c3];
const float cb4 = c_black[c4];
const float cb5 = c_black[c5];
float m0 = minVals[c0];
float m1 = minVals[c1];
float m2 = minVals[c2];
float m3 = minVals[c3];
float m4 = minVals[c4];
float m5 = minVals[c5];
int col = 0;
for (; col < W - 5; col += 6) {
m0 = rtengine::min(m0, rawData[row][col] - cb0);
m1 = rtengine::min(m1, rawData[row][col + 1] - cb1);
m2 = rtengine::min(m2, rawData[row][col + 2] - cb2);
m3 = rtengine::min(m3, rawData[row][col + 3] - cb3);
m4 = rtengine::min(m4, rawData[row][col + 4] - cb4);
m5 = rtengine::min(m5, rawData[row][col + 5] - cb5);
}
for (; col < W; ++col) {
const int c = ri->XTRANSFC(row,col);
minVals[c] = rtengine::min(minVals[c], rawData[row][col] - c_black[c]);
}
minVals[c0] = rtengine::min(m0, minVals[c0]);
minVals[c1] = rtengine::min(m1, minVals[c1]);
minVals[c2] = rtengine::min(m2, minVals[c2]);
minVals[c3] = rtengine::min(m3, minVals[c3]);
minVals[c4] = rtengine::min(m4, minVals[c4]);
minVals[c5] = rtengine::min(m5, minVals[c5]);
}
}
bool RawImageSource::isGainMapSupported() const
{
@ -8450,6 +8524,61 @@ void RawImageSource::applyDngGainMap(const float black[4], const std::vector<Gai
}
}
}
/*
Copyright (c) Ingo Weyrich 2020 (heckflosse67@gmx.de)
*/
void RawImageSource::getMinValsBayer(bool zeroIsBad) {
BENCHFUN
if (!zeroIsBad) {
#ifdef _OPENMP
#pragma omp parallel for reduction(min:minVals)
#endif
for (int row = 0; row < H; ++row) {
const int c0 = FC(row, 0);
const int c1 = FC(row, 1);
const float cb0 = c_black[c0];
const float cb1 = c_black[c1];
float m0 = minVals[c0];
float m1 = minVals[c1];
int col = 0;
for (; col < W - 1; col += 2) {
m0 = rtengine::min(m0, rawData[row][col] - cb0);
m1 = rtengine::min(m1, rawData[row][col + 1] - cb1);
}
if (col < W) {
m0 = rtengine::min(m0, rawData[row][col] - cb0);
}
minVals[c0] = m0;
minVals[c1] = m1;
}
} else {
#ifdef _OPENMP
#pragma omp parallel for reduction(min:minVals) schedule(dynamic,16)
#endif
for (int row = 0; row < H; ++row) {
const int c0 = FC(row, 0);
const int c1 = FC(row, 1);
const float cb0 = c_black[c0];
const float cb1 = c_black[c1];
float m0 = minVals[c0];
float m1 = minVals[c1];
int col = 0;
for (; col < W - 1; col += 2) {
if (LIKELY(rawData[row][col] > 0.f)) {
m0 = rtengine::min(m0, rawData[row][col] - cb0);
}
if (LIKELY(rawData[row][col + 1] > 0.f)) {
m1 = rtengine::min(m1, rawData[row][col + 1] - cb1);
}
}
if (col < W && LIKELY(rawData[row][col] > 0.f)) {
m0 = rtengine::min(m0, rawData[row][col] - cb0);
}
minVals[c0] = m0;
minVals[c1] = m1;
}
}
}
void RawImageSource::cleanup()
{

View File

@ -107,6 +107,7 @@ protected:
std::vector<double> histMatchingCache;
const std::unique_ptr<procparams::ColorManagementParams> histMatchingParams;
float minVals[3];
void processFalseColorCorrectionThread(Imagefloat* im, array2D<float> &rbconv_Y, array2D<float> &rbconv_I, array2D<float> &rbconv_Q, array2D<float> &rbout_I, array2D<float> &rbout_Q, const int row_from, const int row_to);
void hlRecovery(const std::string &method, float* red, float* green, float* blue, int width, float* hlmax);
@ -124,7 +125,7 @@ public:
int load(const Glib::ustring &fname) override { return load(fname, false); }
int load(const Glib::ustring &fname, bool firstFrameOnly);
void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, bool prepareDenoise = true) override;
void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, float &reddeha, float &greendeha, float &bluedeha, bool prepareDenoise = true) override;
void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold, bool cache = false) override;
void retinex (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &deh, const procparams::ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D<float, 4> &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) override;
void retinexPrepareCurves (const procparams::RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) override;
@ -139,7 +140,7 @@ public:
}
void processFlatField(const procparams::RAWParams &raw, RawImage *riFlatFile, array2D<float> &rawData, const float black[4]);
void copyOriginalPixels(const procparams::RAWParams &raw, RawImage *ri, const RawImage *riDark, RawImage *riFlatFile, array2D<float> &rawData );
void copyOriginalPixels(const procparams::RAWParams &raw, RawImage *ri, const RawImage *riDark, RawImage *riFlatFile, array2D<float> &rawData, float &reddeha, float &greendeha, float &bluedeha);
void scaleColors (int winx, int winy, int winw, int winh, const procparams::RAWParams &raw, array2D<float> &rawData); // raw for cblack
void WBauto(bool extra, double &tempref, double &greenref, array2D<float> &redloc, array2D<float> &greenloc, array2D<float> &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, double &tempitc, double &greenitc, float &temp0, float &delta, int &bia, int &dread, int &kcam, int &nocam, float &studgood, float &minchrom, int &kmin, float &minhist, float &maxhist, bool &twotimes, const procparams::WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::ToneCurveParams &hrp) override;
void getAutoWBMultipliersitc(bool extra, double &tempref, double &greenref, double &tempitc, double &greenitc, float &temp0, float &delta, int &bia, int &dread, int &kcam, int &nocam, float &studgood, float &minchrom, int &kmin, float &minhist, float &maxhist, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double &rm, double &gm, double &bm, const procparams::WBParams & wbpar, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::ToneCurveParams &hrp) override;
@ -308,6 +309,8 @@ protected:
void vflip (Imagefloat* im);
void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override;
void captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold, double &radius) override;
void getMinValsXtrans();
void getMinValsBayer(bool zeroIsBad);
void applyDngGainMap(const float black[4], const std::vector<GainMap> &gainMaps);
public:
void wbMul2Camera(double &rm, double &gm, double &bm) override;

View File

@ -383,6 +383,23 @@ public :
};
class AutoBlackListener
{
public :
virtual ~AutoBlackListener() = default;
virtual void autoBlackChanged(double reddeha, double greendeha, double bluedeha) = 0;
};
class AutoBlackxListener
{
public :
virtual ~AutoBlackxListener() = default;
virtual void autoBlackxChanged(double reddeha, double greendeha, double bluedeha) = 0;
};
class AutoChromaListener
{
public :
@ -696,6 +713,8 @@ public:
virtual void setHistogramListener (HistogramListener *l) = 0;
virtual void setPreviewImageListener (PreviewImageListener* l) = 0;
virtual void setAutoCamListener (AutoCamListener* l) = 0;
virtual void setAutoBlackListener (AutoBlackListener* l) = 0;
virtual void setAutoBlackxListener (AutoBlackxListener* l) = 0;
virtual void setFlatFieldAutoClipListener (FlatFieldAutoClipListener* l) = 0;
virtual void setFrameCountListener (FrameCountListener* l) = 0;
virtual void setBayerAutoContrastListener (AutoContrastListener* l) = 0;

View File

@ -422,8 +422,10 @@ Image8 *load_inspector_mode(const Glib::ustring &fname, eSensorType &sensorType,
neutral.raw.xtranssensor.method = RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FAST);
neutral.icm.inputProfile = "(camera)";
neutral.icm.workingProfile = settings->srgb;
src.preprocess(neutral.raw, neutral.lensProf, neutral.coarse, false);
float reddeha = 0.f;
float greendeha = 0.f;
float bluedeha = 0.f;
src.preprocess(neutral.raw, neutral.lensProf, neutral.coarse, reddeha, greendeha, bluedeha, false);
double thresholdDummy = 0.f;
src.demosaic(neutral.raw, false, thresholdDummy);

View File

@ -222,7 +222,10 @@ private:
ImProcFunctions &ipf = * (ipf_p.get());
imgsrc->setCurrentFrame(params.raw.bayersensor.imageNum);
imgsrc->preprocess(params.raw, params.lensProf, params.coarse, params.dirpyrDenoise.enabled);
float reddeha = 0.f;
float greendeha = 0.f;
float bluedeha = 0.f;
imgsrc->preprocess(params.raw, params.lensProf, params.coarse, reddeha, greendeha, bluedeha, params.dirpyrDenoise.enabled);
if (pl) {
pl->setProgress(0.20);

View File

@ -30,6 +30,10 @@ const Glib::ustring BayerRAWExposure::TOOL_NAME = "bayerrawexposure";
BayerRAWExposure::BayerRAWExposure () : FoldableToolPanel(this, TOOL_NAME, M("TP_EXPOS_BLACKPOINT_LABEL"), options.prevdemo != PD_Sidecar)
{
auto m = ProcEventMapper::getInstance();
EvDehablack = m->newEvent(DARKFRAME, "HISTORY_MSG_DEHABLACK");
EvDehablackVoid = m->newEvent(M_VOID, "HISTORY_MSG_DEHABLACK");
PexBlack1 = Gtk::manage(new Adjuster (M("TP_RAWEXPOS_BLACK_1"), -2048, 2048, 1.0, 0)); //black level
PexBlack1->setAdjusterListener (this);
@ -58,11 +62,16 @@ BayerRAWExposure::BayerRAWExposure () : FoldableToolPanel(this, TOOL_NAME, M("TP
PextwoGreen->set_active (true);
PextwoGreen->setCheckBoxListener (this);
Dehablack = Gtk::manage(new CheckBox(M("TP_RAWEXPOS_DEHA"), multiImage));// Black dehaze
Dehablack->set_active (false);
Dehablack->setCheckBoxListener (this);
pack_start( *PexBlack1, Gtk::PACK_SHRINK, 0);//black R
pack_start( *PexBlack0, Gtk::PACK_SHRINK, 0);//black G1
pack_start( *PexBlack3, Gtk::PACK_SHRINK, 0);//black G2
pack_start( *PexBlack2, Gtk::PACK_SHRINK, 0);//black B
pack_start( *PextwoGreen, Gtk::PACK_SHRINK, 0);//black 2 green
pack_start( *Dehablack, Gtk::PACK_SHRINK, 0);//black Dehaze
PexBlack0->setLogScale(100, 0);
PexBlack1->setLogScale(100, 0);
@ -73,7 +82,6 @@ BayerRAWExposure::BayerRAWExposure () : FoldableToolPanel(this, TOOL_NAME, M("TP
void BayerRAWExposure::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited)
{
disableListener ();
if(pedited ) {
PexBlack0->setEditedState( pedited->raw.bayersensor.exBlack0 ? Edited : UnEdited );
PexBlack1->setEditedState( pedited->raw.bayersensor.exBlack1 ? Edited : UnEdited );
@ -82,6 +90,7 @@ void BayerRAWExposure::read(const rtengine::procparams::ProcParams* pp, const Pa
}
PextwoGreen->setValue (pp->raw.bayersensor.twogreen);
Dehablack->setValue (pp->raw.bayersensor.Dehablack);
PexBlack0->setValue (pp->raw.bayersensor.black0);//black
PexBlack1->setValue (pp->raw.bayersensor.black1);//black
@ -92,7 +101,7 @@ void BayerRAWExposure::read(const rtengine::procparams::ProcParams* pp, const Pa
} else {
PexBlack3->setValue (PexBlack0->getValue());
}
checkBoxToggled (Dehablack, CheckValue::on);
enableListener ();
}
@ -102,6 +111,7 @@ void BayerRAWExposure::write( rtengine::procparams::ProcParams* pp, ParamsEdited
pp->raw.bayersensor.black1 = PexBlack1->getValue();// black
pp->raw.bayersensor.black2 = PexBlack2->getValue();// black
pp->raw.bayersensor.twogreen = PextwoGreen->getLastActive();
pp->raw.bayersensor.Dehablack = Dehablack->getLastActive();
if(PextwoGreen->getLastActive()) {
pp->raw.bayersensor.black3 = pp->raw.bayersensor.black0; // active or desactive 2 green together
@ -115,10 +125,50 @@ void BayerRAWExposure::write( rtengine::procparams::ProcParams* pp, ParamsEdited
pedited->raw.bayersensor.exBlack2 = PexBlack2->getEditedState ();//black
pedited->raw.bayersensor.exBlack3 = PexBlack3->getEditedState ();//black
pedited->raw.bayersensor.exTwoGreen = !PextwoGreen->get_inconsistent();
pedited->raw.bayersensor.Dehablack = !Dehablack->get_inconsistent();
}
}
BayerRAWExposure::~BayerRAWExposure()
{
idle_register.destroy();
}
void BayerRAWExposure::autoBlackChanged (double reddeha, double greendeha, double bluedeha)
{
idle_register.add(
[this, reddeha, greendeha, bluedeha]() -> bool
{
if (reddeha != PexBlack1->getValue()) {
disableListener();
PexBlack1->setValue(reddeha);
enableListener();
}
if (greendeha != PexBlack0->getValue()) {
disableListener();
PexBlack0->setValue(greendeha);
enableListener();
}
if (greendeha != PexBlack3->getValue()) {
disableListener();
PexBlack3->setValue(greendeha);
enableListener();
}
if (bluedeha != PexBlack2->getValue()) {
disableListener();
PexBlack2->setValue(bluedeha);
enableListener();
}
return false;
}
);
}
void BayerRAWExposure::adjusterChanged(Adjuster* a, double newval)
{
if (listener) {
@ -155,9 +205,29 @@ void BayerRAWExposure::checkBoxToggled (CheckBox* c, CheckValue newval)
PexBlack3->setValue (PexBlack0->getValue());//two green together
}
}
} else if(c == Dehablack) {
if(Dehablack->getLastActive()) {
PexBlack1->set_sensitive(false);
PexBlack2->set_sensitive(false);
PexBlack3->set_sensitive(false);
PexBlack0->set_sensitive(false);
} else {
PexBlack1->set_sensitive(true);
PexBlack2->set_sensitive(true);
PexBlack3->set_sensitive(true);
PexBlack0->set_sensitive(true);
}
if (listener) {
if (Dehablack->getLastActive()) {
listener->panelChanged (EvDehablack, M("GENERAL_ENABLED"));
} else {
listener->panelChanged (EvDehablackVoid, M("GENERAL_DISABLED"));
}
}
}
}
void BayerRAWExposure::setBatchMode(bool batchMode)
{
ToolPanel::setBatchMode (batchMode);

View File

@ -23,17 +23,20 @@
#include "adjuster.h"
#include "checkbox.h"
#include "toolpanel.h"
#include "eventmapper.h"
class BayerRAWExposure final :
public ToolParamBlock,
public AdjusterListener,
public CheckBoxListener,
public rtengine::AutoBlackListener,
public FoldableToolPanel
{
public:
static const Glib::ustring TOOL_NAME;
BayerRAWExposure ();
~BayerRAWExposure () override;
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override;
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr) override;
@ -43,6 +46,8 @@ public:
void checkBoxToggled (CheckBox* c, CheckValue newval) override;
void setAdjusterBehavior (bool pexblackadd);
void trimValues (rtengine::procparams::ProcParams* pp) override;
void autoBlackChanged (double reddeha, double greendeha, double bluedeha) override;
protected:
Adjuster* PexBlack0;
@ -50,4 +55,8 @@ protected:
Adjuster* PexBlack2;
Adjuster* PexBlack3;
CheckBox* PextwoGreen;
CheckBox* Dehablack;
IdleRegister idle_register;
rtengine::ProcEvent EvDehablack;
rtengine::ProcEvent EvDehablackVoid;
};

View File

@ -498,6 +498,7 @@ void ParamsEdited::set(bool v)
raw.bayersensor.exBlack2 = v;
raw.bayersensor.exBlack3 = v;
raw.bayersensor.exTwoGreen = v;
raw.bayersensor.Dehablack = v;
raw.bayersensor.dcbIterations = v;
raw.bayersensor.dcbEnhance = v;
//raw.bayersensor.allEnhance = v;
@ -531,6 +532,7 @@ void ParamsEdited::set(bool v)
raw.xtranssensor.exBlackRed = v;
raw.xtranssensor.exBlackGreen = v;
raw.xtranssensor.exBlackBlue = v;
raw.xtranssensor.Dehablackx = v;
raw.ca_autocorrect = v;
raw.ca_avoidcolourshift = v;
raw.caautoiterations = v;
@ -2007,6 +2009,7 @@ void ParamsEdited::initFrom(const std::vector<rtengine::procparams::ProcParams>&
raw.bayersensor.exBlack2 = raw.bayersensor.exBlack2 && p.raw.bayersensor.black2 == other.raw.bayersensor.black2;
raw.bayersensor.exBlack3 = raw.bayersensor.exBlack3 && p.raw.bayersensor.black3 == other.raw.bayersensor.black3;
raw.bayersensor.exTwoGreen = raw.bayersensor.exTwoGreen && p.raw.bayersensor.twogreen == other.raw.bayersensor.twogreen;
raw.bayersensor.Dehablack = raw.bayersensor.Dehablack && p.raw.bayersensor.Dehablack == other.raw.bayersensor.Dehablack;
raw.bayersensor.dcbIterations = raw.bayersensor.dcbIterations && p.raw.bayersensor.dcb_iterations == other.raw.bayersensor.dcb_iterations;
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;
@ -2040,6 +2043,7 @@ void ParamsEdited::initFrom(const std::vector<rtengine::procparams::ProcParams>&
raw.xtranssensor.exBlackRed = raw.xtranssensor.exBlackRed && p.raw.xtranssensor.blackred == other.raw.xtranssensor.blackred;
raw.xtranssensor.exBlackGreen = raw.xtranssensor.exBlackGreen && p.raw.xtranssensor.blackgreen == other.raw.xtranssensor.blackgreen;
raw.xtranssensor.exBlackBlue = raw.xtranssensor.exBlackBlue && p.raw.xtranssensor.blackblue == other.raw.xtranssensor.blackblue;
raw.xtranssensor.Dehablackx = raw.xtranssensor.Dehablackx && p.raw.xtranssensor.Dehablackx == other.raw.xtranssensor.Dehablackx;
raw.ca_autocorrect = raw.ca_autocorrect && p.raw.ca_autocorrect == other.raw.ca_autocorrect;
raw.ca_avoidcolourshift = raw.ca_avoidcolourshift && p.raw.ca_avoidcolourshift == other.raw.ca_avoidcolourshift;
raw.caautoiterations = raw.caautoiterations && p.raw.caautoiterations == other.raw.caautoiterations;
@ -6975,6 +6979,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
toEdit.raw.bayersensor.twogreen = mods.raw.bayersensor.twogreen;
}
if (raw.bayersensor.Dehablack) {
toEdit.raw.bayersensor.Dehablack = mods.raw.bayersensor.Dehablack;
}
if (raw.bayersensor.dcbIterations) {
toEdit.raw.bayersensor.dcb_iterations = mods.raw.bayersensor.dcb_iterations;
}
@ -7103,6 +7111,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
toEdit.raw.xtranssensor.blackblue = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.xtranssensor.blackblue + mods.raw.xtranssensor.blackblue : mods.raw.xtranssensor.blackblue;
}
if (raw.xtranssensor.Dehablackx) {
toEdit.raw.xtranssensor.Dehablackx = mods.raw.xtranssensor.Dehablackx;
}
if (raw.ca_autocorrect) {
toEdit.raw.ca_autocorrect = mods.raw.ca_autocorrect;
}
@ -7883,7 +7895,7 @@ bool RAWParamsEdited::BayerSensor::isUnchanged() const
return method && border && imageNum && dcbIterations && dcbEnhance && lmmseIterations && dualDemosaicAutoContrast && dualDemosaicContrast /*&& allEnhance*/ && greenEq
&& pixelShiftMotionCorrectionMethod && pixelShiftEperIso && pixelShiftSigma && pixelShiftShowMotion && pixelShiftShowMotionMaskOnly
&& pixelShiftHoleFill && pixelShiftMedian && pixelShiftAverage && pixelShiftNonGreenCross && pixelShiftDemosaicMethod && pixelShiftGreen && pixelShiftBlur && pixelShiftSmooth && pixelShiftEqualBright && pixelShiftEqualBrightChannel
&& linenoise && linenoiseDirection && pdafLinesFilter && exBlack0 && exBlack1 && exBlack2 && exBlack3 && exTwoGreen;
&& linenoise && linenoiseDirection && pdafLinesFilter && exBlack0 && exBlack1 && exBlack2 && exBlack3 && exTwoGreen && Dehablack;
}
bool RAWParamsEdited::XTransSensor::isUnchanged() const

View File

@ -1531,6 +1531,7 @@ struct RAWParamsEdited {
bool exBlack2;
bool exBlack3;
bool exTwoGreen;
bool Dehablack;
bool dcbIterations;
bool dcbEnhance;
bool lmmseIterations;
@ -1569,6 +1570,7 @@ struct RAWParamsEdited {
bool exBlackRed;
bool exBlackGreen;
bool exBlackBlue;
bool Dehablackx;
bool isUnchanged() const;
};

View File

@ -1311,6 +1311,8 @@ void ToolPanelCoordinator::initImage(rtengine::StagedImageProcessor* ipc_, bool
ipc->setAutoExpListener(toneCurve);
ipc->setAutoCamListener(colorappearance);
ipc->setAutoBlackListener(bayerrawexposure);
ipc->setAutoBlackxListener(xtransrawexposure);
ipc->setAutoBWListener(blackwhite);
ipc->setFrameCountListener(bayerprocess);
ipc->setFlatFieldAutoClipListener (flatfield);

View File

@ -31,6 +31,10 @@ const Glib::ustring XTransRAWExposure::TOOL_NAME = "xtransrawexposure";
XTransRAWExposure::XTransRAWExposure () : FoldableToolPanel(this, TOOL_NAME, M("TP_EXPOS_BLACKPOINT_LABEL"))
{
auto m = ProcEventMapper::getInstance();
EvDehablackx = m->newEvent(DARKFRAME, "HISTORY_MSG_DEHABLACKX");
EvDehablackxVoid = m->newEvent(M_VOID, "HISTORY_MSG_DEHABLACKX");
PexBlackRed = Gtk::manage(new Adjuster (M("TP_RAWEXPOS_BLACK_RED"), -2048, 2048, 1.0, 0)); //black level
PexBlackRed->setAdjusterListener (this);
@ -49,10 +53,14 @@ XTransRAWExposure::XTransRAWExposure () : FoldableToolPanel(this, TOOL_NAME, M("
PexBlackBlue->setDelay(std::max(options.adjusterMinDelay, options.adjusterMaxDelay));
PexBlackBlue->show();
Dehablackx = Gtk::manage(new CheckBox(M("TP_RAWEXPOS_DEHA"), multiImage));// Black dehaze
Dehablackx->set_active (false);
Dehablackx->setCheckBoxListener (this);
pack_start( *PexBlackRed, Gtk::PACK_SHRINK, 0);//black
pack_start( *PexBlackGreen, Gtk::PACK_SHRINK, 0);//black
pack_start( *PexBlackBlue, Gtk::PACK_SHRINK, 0);//black
pack_start( *Dehablackx, Gtk::PACK_SHRINK, 0);//black Dehaze
PexBlackRed->setLogScale(100, 0);
PexBlackGreen->setLogScale(100, 0);
@ -68,10 +76,12 @@ void XTransRAWExposure::read(const rtengine::procparams::ProcParams* pp, const P
PexBlackGreen->setEditedState( pedited->raw.xtranssensor.exBlackGreen ? Edited : UnEdited );
PexBlackBlue->setEditedState( pedited->raw.xtranssensor.exBlackBlue ? Edited : UnEdited );
}
Dehablackx->setValue (pp->raw.xtranssensor.Dehablackx);
PexBlackRed->setValue (pp->raw.xtranssensor.blackred);//black
PexBlackGreen->setValue (pp->raw.xtranssensor.blackgreen);//black
PexBlackBlue->setValue (pp->raw.xtranssensor.blackblue);//black
checkBoxToggled (Dehablackx, CheckValue::on);
enableListener ();
}
@ -81,15 +91,49 @@ void XTransRAWExposure::write( rtengine::procparams::ProcParams* pp, ParamsEdite
pp->raw.xtranssensor.blackred = PexBlackRed->getValue();// black
pp->raw.xtranssensor.blackgreen = PexBlackGreen->getValue();// black
pp->raw.xtranssensor.blackblue = PexBlackBlue->getValue();// black
pp->raw.xtranssensor.Dehablackx = Dehablackx->getLastActive();
if (pedited) {
pedited->raw.xtranssensor.exBlackRed = PexBlackRed->getEditedState ();//black
pedited->raw.xtranssensor.exBlackGreen = PexBlackGreen->getEditedState ();//black
pedited->raw.xtranssensor.exBlackBlue = PexBlackBlue->getEditedState ();//black
pedited->raw.xtranssensor.Dehablackx = !Dehablackx->get_inconsistent();
}
}
XTransRAWExposure::~XTransRAWExposure()
{
idle_register.destroy();
}
void XTransRAWExposure::autoBlackxChanged (double reddeha, double greendeha, double bluedeha)
{
idle_register.add(
[this, reddeha, greendeha, bluedeha]() -> bool
{
if (reddeha != PexBlackRed->getValue()) {
disableListener();
PexBlackRed->setValue(reddeha);
enableListener();
}
if (greendeha != PexBlackGreen->getValue()) {
disableListener();
PexBlackGreen->setValue(greendeha);
enableListener();
}
if (bluedeha != PexBlackBlue->getValue()) {
disableListener();
PexBlackBlue->setValue(bluedeha);
enableListener();
}
return false;
}
);
}
void XTransRAWExposure::adjusterChanged(Adjuster* a, double newval)
{
if (listener) {
@ -105,6 +149,29 @@ void XTransRAWExposure::adjusterChanged(Adjuster* a, double newval)
}
}
void XTransRAWExposure::checkBoxToggled (CheckBox* c, CheckValue newval)
{
if(c == Dehablackx) {
if(Dehablackx->getLastActive()) {
PexBlackRed->set_sensitive(false);
PexBlackGreen->set_sensitive(false);
PexBlackBlue->set_sensitive(false);
} else {
PexBlackRed->set_sensitive(true);
PexBlackGreen->set_sensitive(true);
PexBlackBlue->set_sensitive(true);
}
if (listener) {
if (Dehablackx->getLastActive()) {
listener->panelChanged (EvDehablackx, M("GENERAL_ENABLED"));
} else {
listener->panelChanged (EvDehablackxVoid, M("GENERAL_DISABLED"));
}
}
}
}
void XTransRAWExposure::setBatchMode(bool batchMode)
{
ToolPanel::setBatchMode (batchMode);

View File

@ -21,11 +21,15 @@
#include <gtkmm.h>
#include "adjuster.h"
#include "checkbox.h"
#include "toolpanel.h"
#include "eventmapper.h"
class XTransRAWExposure final :
public ToolParamBlock,
public AdjusterListener,
public CheckBoxListener,
public rtengine::AutoBlackxListener,
public FoldableToolPanel
{
@ -33,6 +37,10 @@ protected:
Adjuster* PexBlackRed;
Adjuster* PexBlackGreen;
Adjuster* PexBlackBlue;
CheckBox* Dehablackx;
IdleRegister idle_register;
rtengine::ProcEvent EvDehablackx;
rtengine::ProcEvent EvDehablackxVoid;
private:
// Gtk::CheckButton* PextwoGreen;
@ -40,12 +48,15 @@ public:
static const Glib::ustring TOOL_NAME;
XTransRAWExposure ();
~XTransRAWExposure () override;
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override;
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr) override;
void setBatchMode (bool batchMode) override;
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override;
void adjusterChanged (Adjuster* a, double newval) override;
void checkBoxToggled (CheckBox* c, CheckValue newval) override;
void setAdjusterBehavior (bool pexblackadd);
void trimValues (rtengine::procparams::ProcParams* pp) override;
void autoBlackxChanged (double reddeha, double greendeha, double bluedeha) override;
};