Support dnggainmap (embedded correction) for Bayer files (#6382)

* dng gainmap support, #6379
* dng GainMap: control sensitivity of checkbox, #6379
* dng GainMap: partial paste
* dng GainMap: moved isGainMapSupported() from dcraw.h to dcraw.cc
* RawImageSource::applyDngGainMap: small speedup
* Change GUI to separate gainmap from other flat-field; also reorder checkbox

Co-authored-by: Thanatomanic <6567747+Thanatomanic@users.noreply.github.com>
This commit is contained in:
Ingo Weyrich 2023-01-02 21:30:06 +01:00 committed by GitHub
parent 2101b846c3
commit 8d29d361a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 299 additions and 21 deletions

View File

@ -1406,6 +1406,7 @@ HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength
HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold
HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold
HISTORY_MSG_EDGEFFECT;Edge Attenuation response HISTORY_MSG_EDGEFFECT;Edge Attenuation response
HISTORY_MSG_FF_FROMMETADATA;Flat-Field - From Metadata
HISTORY_MSG_FILMNEGATIVE_BALANCE;FN - Reference output HISTORY_MSG_FILMNEGATIVE_BALANCE;FN - Reference output
HISTORY_MSG_FILMNEGATIVE_COLORSPACE;Film negative color space HISTORY_MSG_FILMNEGATIVE_COLORSPACE;Film negative color space
HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative
@ -1736,6 +1737,7 @@ PARTIALPASTE_EXPOSURE;Exposure
PARTIALPASTE_FILMNEGATIVE;Film negative PARTIALPASTE_FILMNEGATIVE;Film negative
PARTIALPASTE_FILMSIMULATION;Film simulation PARTIALPASTE_FILMSIMULATION;Film simulation
PARTIALPASTE_FLATFIELDAUTOSELECT;Flat-field auto-selection PARTIALPASTE_FLATFIELDAUTOSELECT;Flat-field auto-selection
PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata
PARTIALPASTE_FLATFIELDBLURRADIUS;Flat-field blur radius PARTIALPASTE_FLATFIELDBLURRADIUS;Flat-field blur radius
PARTIALPASTE_FLATFIELDBLURTYPE;Flat-field blur type PARTIALPASTE_FLATFIELDBLURTYPE;Flat-field blur type
PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control
@ -2481,6 +2483,7 @@ TP_FLATFIELD_BT_VERTHORIZ;Vertical + Horizontal
TP_FLATFIELD_BT_VERTICAL;Vertical TP_FLATFIELD_BT_VERTICAL;Vertical
TP_FLATFIELD_CLIPCONTROL;Clip control TP_FLATFIELD_CLIPCONTROL;Clip control
TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, value 0 is used. TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, value 0 is used.
TP_FLATFIELD_FROMMETADATA;From Metadata
TP_FLATFIELD_LABEL;Flat-Field TP_FLATFIELD_LABEL;Flat-Field
TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1.
TP_GRADIENT_CENTER;Center TP_GRADIENT_CENTER;Center

View File

@ -248,6 +248,14 @@ public:
return *this; return *this;
} }
// import from flat data
void operator()(std::size_t w, std::size_t h, const T* const copy)
{
ar_realloc(w, h);
for (std::size_t y = 0; y < h; ++y) {
std::copy(copy + y * w, copy + y * w + w, rows.data()[y]);
}
}
int getWidth() const int getWidth() const
{ {

View File

@ -6938,7 +6938,6 @@ it under the terms of the one of two licenses as you choose:
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
if (ntags < ifp->size / 12) { // rough check for wrong value (happens for example with DNG files from DJI FC6310) if (ntags < ifp->size / 12) { // rough check for wrong value (happens for example with DNG files from DJI FC6310)
while (ntags-- && !ifp->eof) { while (ntags-- && !ifp->eof) {
unsigned opcode = get4(); unsigned opcode = get4();
@ -6957,8 +6956,48 @@ it under the terms of the one of two licenses as you choose:
break; break;
} }
case 51009: /* OpcodeList2 */ case 51009: /* OpcodeList2 */
meta_offset = ftell(ifp); {
break; meta_offset = ftell(ifp);
const 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
unsigned ntags = get4(); // read the number of opcodes
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();
if (opcode == 9 && gainMaps.size() < 4) {
fseek(ifp, 4, SEEK_CUR); // skip 4 bytes as we know that the opcode 4 takes 4 byte
fseek(ifp, 8, SEEK_CUR); // skip 8 bytes as they don't interest us currently
GainMap gainMap;
gainMap.Top = get4();
gainMap.Left = get4();
gainMap.Bottom = get4();
gainMap.Right = get4();
gainMap.Plane = get4();
gainMap.Planes = get4();
gainMap.RowPitch = get4();
gainMap.ColPitch = get4();
gainMap.MapPointsV = get4();
gainMap.MapPointsH = get4();
gainMap.MapSpacingV = getreal(12);
gainMap.MapSpacingH = getreal(12);
gainMap.MapOriginV = getreal(12);
gainMap.MapOriginH = getreal(12);
gainMap.MapPlanes = get4();
const std::size_t n = static_cast<std::size_t>(gainMap.MapPointsV) * static_cast<std::size_t>(gainMap.MapPointsH) * static_cast<std::size_t>(gainMap.MapPlanes);
gainMap.MapGain.reserve(n);
for (std::size_t i = 0; i < n; ++i) {
gainMap.MapGain.push_back(getreal(11));
}
gainMaps.push_back(std::move(gainMap));
} else {
fseek(ifp, 8, SEEK_CUR); // skip 8 bytes as they don't interest us currently
fseek(ifp, get4(), SEEK_CUR);
}
}
}
order = oldOrder;
break;
}
case 64772: /* Kodak P-series */ case 64772: /* Kodak P-series */
if (len < 13) break; if (len < 13) break;
fseek (ifp, 16, SEEK_CUR); fseek (ifp, 16, SEEK_CUR);
@ -11079,6 +11118,70 @@ void CLASS nikon_14bit_load_raw()
free(buf); free(buf);
} }
bool CLASS isGainMapSupported() const {
if (!(dng_version && isBayer())) {
return false;
}
const auto n = gainMaps.size();
if (n != 4) { // we need 4 gainmaps for bayer files
if (rtengine::settings->verbose) {
std::cout << "GainMap has " << n << " maps, but 4 are needed" << std::endl;
}
return false;
}
unsigned int check = 0;
bool noOp = true;
for (const auto &m : gainMaps) {
if (m.MapGain.size() < 1) {
if (rtengine::settings->verbose) {
std::cout << "GainMap has invalid size of " << m.MapGain.size() << std::endl;
}
return false;
}
if (m.MapGain.size() != static_cast<std::size_t>(m.MapPointsV) * static_cast<std::size_t>(m.MapPointsH) * static_cast<std::size_t>(m.MapPlanes)) {
if (rtengine::settings->verbose) {
std::cout << "GainMap has size of " << m.MapGain.size() << ", but needs " << m.MapPointsV * m.MapPointsH * m.MapPlanes << std::endl;
}
return false;
}
if (m.RowPitch != 2 || m.ColPitch != 2) {
if (rtengine::settings->verbose) {
std::cout << "GainMap needs Row/ColPitch of 2/2, but has " << m.RowPitch << "/" << m.ColPitch << std::endl;
}
return false;
}
if (m.Top == 0){
if (m.Left == 0) {
check += 1;
} else if (m.Left == 1) {
check += 2;
}
} else if (m.Top == 1) {
if (m.Left == 0) {
check += 4;
} else if (m.Left == 1) {
check += 8;
}
}
for (size_t i = 0; noOp && i < m.MapGain.size(); ++i) {
if (m.MapGain[i] != 1.f) { // we have at least one value != 1.f => map is not a nop
noOp = false;
}
}
}
if (noOp || check != 15) { // all maps are nops or the structure of the combination of 4 maps is not correct
if (rtengine::settings->verbose) {
if (noOp) {
std::cout << "GainMap is a nop" << std::endl;
} else {
std::cout << "GainMap has unsupported type : " << check << std::endl;
}
}
return false;
}
return true;
}
/* RT: Delete from here */ /* RT: Delete from here */
/*RT*/#undef SQR /*RT*/#undef SQR
/*RT*/#undef MAX /*RT*/#undef MAX

View File

@ -19,9 +19,12 @@
#pragma once #pragma once
#include <iostream>
#include "myfile.h" #include "myfile.h"
#include <csetjmp> #include <csetjmp>
#include "dnggainmap.h"
#include "settings.h"
class DCraw class DCraw
{ {
@ -165,6 +168,8 @@ protected:
PanasonicRW2Info(): bpp(0), encoding(0) {} PanasonicRW2Info(): bpp(0), encoding(0) {}
}; };
PanasonicRW2Info RT_pana_info; PanasonicRW2Info RT_pana_info;
std::vector<GainMap> gainMaps;
public: public:
struct CanonCR3Data { struct CanonCR3Data {
// contents of tag CMP1 for relevant track in CR3 file // contents of tag CMP1 for relevant track in CR3 file
@ -193,6 +198,18 @@ public:
int crx_track_selected; int crx_track_selected;
short CR3_CTMDtag; short CR3_CTMDtag;
}; };
bool isBayer() const
{
return (filters != 0 && filters != 9);
}
const std::vector<GainMap>& getGainMaps() const {
return gainMaps;
}
bool isGainMapSupported() const;
struct CanonLevelsData { struct CanonLevelsData {
unsigned cblack[4]; unsigned cblack[4];
unsigned white; unsigned white;
@ -200,6 +217,7 @@ public:
bool white_ok; bool white_ok;
CanonLevelsData(): cblack{0}, white{0}, black_ok(false), white_ok(false) {} CanonLevelsData(): cblack{0}, white{0}, black_ok(false), white_ok(false) {}
}; };
protected: protected:
CanonCR3Data RT_canon_CR3_data; CanonCR3Data RT_canon_CR3_data;

43
rtengine/dnggainmap.h Normal file
View File

@ -0,0 +1,43 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2021 Ingo Weyrich <heckflosse67@gmx.de>
*
* RawTherapee is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RawTherapee is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <cstdint>
#include <vector>
struct GainMap
{
std::uint32_t Top;
std::uint32_t Left;
std::uint32_t Bottom;
std::uint32_t Right;
std::uint32_t Plane;
std::uint32_t Planes;
std::uint32_t RowPitch;
std::uint32_t ColPitch;
std::uint32_t MapPointsV;
std::uint32_t MapPointsH;
double MapSpacingV;
double MapSpacingH;
double MapOriginV;
double MapOriginH;
std::uint32_t MapPlanes;
std::vector<float> MapGain;
};

View File

@ -137,6 +137,7 @@ public:
virtual ImageMatrices* getImageMatrices () = 0; virtual ImageMatrices* getImageMatrices () = 0;
virtual bool isRAW () const = 0; virtual bool isRAW () const = 0;
virtual bool isGainMapSupported () const = 0;
virtual DCPProfile* getDCP (const procparams::ColorManagementParams &cmp, DCPProfileApplyState &as) virtual DCPProfile* getDCP (const procparams::ColorManagementParams &cmp, DCPProfileApplyState &as)
{ {
return nullptr; return nullptr;

View File

@ -407,7 +407,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
// If high detail (=100%) is newly selected, do a demosaic update, since the last was just with FAST // If high detail (=100%) is newly selected, do a demosaic update, since the last was just with FAST
if (imageTypeListener) { if (imageTypeListener) {
imageTypeListener->imageTypeChanged(imgsrc->isRAW(), imgsrc->getSensorType() == ST_BAYER, imgsrc->getSensorType() == ST_FUJI_XTRANS, imgsrc->isMono()); imageTypeListener->imageTypeChanged(imgsrc->isRAW(), imgsrc->getSensorType() == ST_BAYER, imgsrc->getSensorType() == ST_FUJI_XTRANS, imgsrc->isMono(), imgsrc->isGainMapSupported());
} }
if ((todo & M_RAW) if ((todo & M_RAW)

View File

@ -5633,6 +5633,7 @@ bool RAWParams::PreprocessWB::operator !=(const PreprocessWB& other) const
RAWParams::RAWParams() : RAWParams::RAWParams() :
df_autoselect(false), df_autoselect(false),
ff_AutoSelect(false), ff_AutoSelect(false),
ff_FromMetaData(false),
ff_BlurRadius(32), ff_BlurRadius(32),
ff_BlurType(getFlatFieldBlurTypeString(FlatFieldBlurType::AREA)), ff_BlurType(getFlatFieldBlurTypeString(FlatFieldBlurType::AREA)),
ff_AutoClipControl(false), ff_AutoClipControl(false),
@ -5658,6 +5659,7 @@ bool RAWParams::operator ==(const RAWParams& other) const
&& df_autoselect == other.df_autoselect && df_autoselect == other.df_autoselect
&& ff_file == other.ff_file && ff_file == other.ff_file
&& ff_AutoSelect == other.ff_AutoSelect && ff_AutoSelect == other.ff_AutoSelect
&& ff_FromMetaData == other.ff_FromMetaData
&& ff_BlurRadius == other.ff_BlurRadius && ff_BlurRadius == other.ff_BlurRadius
&& ff_BlurType == other.ff_BlurType && ff_BlurType == other.ff_BlurType
&& ff_AutoClipControl == other.ff_AutoClipControl && ff_AutoClipControl == other.ff_AutoClipControl
@ -7484,6 +7486,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
saveToKeyfile(!pedited || pedited->raw.df_autoselect, "RAW", "DarkFrameAuto", raw.df_autoselect, keyFile); saveToKeyfile(!pedited || pedited->raw.df_autoselect, "RAW", "DarkFrameAuto", raw.df_autoselect, keyFile);
saveToKeyfile(!pedited || pedited->raw.ff_file, "RAW", "FlatFieldFile", relativePathIfInside(fname, fnameAbsolute, raw.ff_file), keyFile); saveToKeyfile(!pedited || pedited->raw.ff_file, "RAW", "FlatFieldFile", relativePathIfInside(fname, fnameAbsolute, raw.ff_file), keyFile);
saveToKeyfile(!pedited || pedited->raw.ff_AutoSelect, "RAW", "FlatFieldAutoSelect", raw.ff_AutoSelect, keyFile); saveToKeyfile(!pedited || pedited->raw.ff_AutoSelect, "RAW", "FlatFieldAutoSelect", raw.ff_AutoSelect, keyFile);
saveToKeyfile(!pedited || pedited->raw.ff_FromMetaData, "RAW", "FlatFieldFromMetaData", raw.ff_FromMetaData, keyFile);
saveToKeyfile(!pedited || pedited->raw.ff_BlurRadius, "RAW", "FlatFieldBlurRadius", raw.ff_BlurRadius, keyFile); saveToKeyfile(!pedited || pedited->raw.ff_BlurRadius, "RAW", "FlatFieldBlurRadius", raw.ff_BlurRadius, keyFile);
saveToKeyfile(!pedited || pedited->raw.ff_BlurType, "RAW", "FlatFieldBlurType", raw.ff_BlurType, keyFile); saveToKeyfile(!pedited || pedited->raw.ff_BlurType, "RAW", "FlatFieldBlurType", raw.ff_BlurType, keyFile);
saveToKeyfile(!pedited || pedited->raw.ff_AutoClipControl, "RAW", "FlatFieldAutoClipControl", raw.ff_AutoClipControl, keyFile); saveToKeyfile(!pedited || pedited->raw.ff_AutoClipControl, "RAW", "FlatFieldAutoClipControl", raw.ff_AutoClipControl, keyFile);
@ -10130,6 +10133,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
} }
assignFromKeyfile(keyFile, "RAW", "FlatFieldAutoSelect", pedited, raw.ff_AutoSelect, pedited->raw.ff_AutoSelect); assignFromKeyfile(keyFile, "RAW", "FlatFieldAutoSelect", pedited, raw.ff_AutoSelect, pedited->raw.ff_AutoSelect);
assignFromKeyfile(keyFile, "RAW", "FlatFieldFromMetaData", pedited, raw.ff_FromMetaData, pedited->raw.ff_FromMetaData);
assignFromKeyfile(keyFile, "RAW", "FlatFieldBlurRadius", pedited, raw.ff_BlurRadius, pedited->raw.ff_BlurRadius); assignFromKeyfile(keyFile, "RAW", "FlatFieldBlurRadius", pedited, raw.ff_BlurRadius, pedited->raw.ff_BlurRadius);
assignFromKeyfile(keyFile, "RAW", "FlatFieldBlurType", pedited, raw.ff_BlurType, pedited->raw.ff_BlurType); assignFromKeyfile(keyFile, "RAW", "FlatFieldBlurType", pedited, raw.ff_BlurType, pedited->raw.ff_BlurType);
assignFromKeyfile(keyFile, "RAW", "FlatFieldAutoClipControl", pedited, raw.ff_AutoClipControl, pedited->raw.ff_AutoClipControl); assignFromKeyfile(keyFile, "RAW", "FlatFieldAutoClipControl", pedited, raw.ff_AutoClipControl, pedited->raw.ff_AutoClipControl);

View File

@ -2440,6 +2440,7 @@ struct RAWParams {
Glib::ustring ff_file; Glib::ustring ff_file;
bool ff_AutoSelect; bool ff_AutoSelect;
bool ff_FromMetaData;
int ff_BlurRadius; int ff_BlurRadius;
Glib::ustring ff_BlurType; Glib::ustring ff_BlurType;
bool ff_AutoClipControl; bool ff_AutoClipControl;

View File

@ -245,11 +245,6 @@ public:
return zero_is_bad == 1; return zero_is_bad == 1;
} }
bool isBayer() const
{
return (filters != 0 && filters != 9);
}
bool isXtrans() const bool isXtrans() const
{ {
return filters == 9; return filters == 9;

View File

@ -39,6 +39,7 @@
#include "rawimage.h" #include "rawimage.h"
#include "rawimagesource_i.h" #include "rawimagesource_i.h"
#include "rawimagesource.h" #include "rawimagesource.h"
#include "rescale.h"
#include "rt_math.h" #include "rt_math.h"
#include "rtengine.h" #include "rtengine.h"
#include "rtlensfun.h" #include "rtlensfun.h"
@ -1347,7 +1348,6 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
rif = ffm.searchFlatField(idata->getMake(), idata->getModel(), idata->getLens(), idata->getFocalLen(), idata->getFNumber(), idata->getDateTimeAsTS()); rif = ffm.searchFlatField(idata->getMake(), idata->getModel(), idata->getLens(), idata->getFocalLen(), idata->getFNumber(), idata->getDateTimeAsTS());
} }
bool hasFlatField = (rif != nullptr); bool hasFlatField = (rif != nullptr);
if (hasFlatField && settings->verbose) { if (hasFlatField && settings->verbose) {
@ -1387,6 +1387,9 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
} }
//FLATFIELD end //FLATFIELD end
if (raw.ff_FromMetaData && isGainMapSupported()) {
applyDngGainMap(c_black, ri->getGainMaps());
}
// Always correct camera badpixels from .badpixels file // Always correct camera badpixels from .badpixels file
const std::vector<badPix> *bp = DFManager::getInstance().getBadPixels(ri->get_maker(), ri->get_model(), idata->getSerialNumber()); const std::vector<badPix> *bp = DFManager::getInstance().getBadPixels(ri->get_maker(), ri->get_model(), idata->getSerialNumber());
@ -6259,6 +6262,36 @@ void RawImageSource::getRawValues(int x, int y, int rotate, int &R, int &G, int
} }
} }
bool RawImageSource::isGainMapSupported() const {
return ri->isGainMapSupported();
}
void RawImageSource::applyDngGainMap(const float black[4], const std::vector<GainMap> &gainMaps) {
// now we can apply each gain map to raw_data
array2D<float> mvals[2][2];
for (auto &m : gainMaps) {
mvals[m.Top & 1][m.Left & 1](m.MapPointsH, m.MapPointsV, m.MapGain.data());
}
// now we assume, col_scale and row scale is the same for all maps
const float col_scale = float(gainMaps[0].MapPointsH-1) / float(W);
const float row_scale = float(gainMaps[0].MapPointsV-1) / float(H);
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic, 16)
#endif
for (std::size_t y = 0; y < static_cast<size_t>(H); ++y) {
const float rowBlack[2] = {black[FC(y,0)], black[FC(y,1)]};
const float ys = y * row_scale;
float xs = 0.f;
for (std::size_t x = 0; x < static_cast<std::size_t>(W); ++x, xs += col_scale) {
const float f = getBilinearValue(mvals[y & 1][x & 1], xs, ys);
const float b = rowBlack[x & 1];
rawData[y][x] = rtengine::max((rawData[y][x] - b) * f + b, 0.f);
}
}
}
void RawImageSource::cleanup () void RawImageSource::cleanup ()
{ {
delete phaseOneIccCurve; delete phaseOneIccCurve;

View File

@ -24,6 +24,7 @@
#include "array2D.h" #include "array2D.h"
#include "colortemp.h" #include "colortemp.h"
#include "dnggainmap.h"
#include "iimage.h" #include "iimage.h"
#include "imagesource.h" #include "imagesource.h"
#include "procparams.h" #include "procparams.h"
@ -177,6 +178,8 @@ public:
return true; return true;
} }
bool isGainMapSupported() const override;
void setProgressListener (ProgressListener* pl) override void setProgressListener (ProgressListener* pl) override
{ {
plistener = pl; plistener = pl;
@ -304,6 +307,7 @@ protected:
void vflip (Imagefloat* im); void vflip (Imagefloat* im);
void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override; 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 captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold, double &radius) override;
void applyDngGainMap(const float black[4], const std::vector<GainMap> &gainMaps);
}; };
} }

View File

@ -493,7 +493,7 @@ class ImageTypeListener
{ {
public: public:
virtual ~ImageTypeListener() = default; virtual ~ImageTypeListener() = default;
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, bool isGainMapSupported = false) = 0;
}; };
class AutoContrastListener class AutoContrastListener

View File

@ -100,6 +100,11 @@ public:
return false; return false;
} }
bool isGainMapSupported() const override
{
return false;
}
void setProgressListener (ProgressListener* pl) override void setProgressListener (ProgressListener* pl) override
{ {
plistener = pl; plistener = pl;

View File

@ -18,6 +18,7 @@
*/ */
#include <sstream> #include <sstream>
#include "eventmapper.h"
#include "flatfield.h" #include "flatfield.h"
#include "guiutils.h" #include "guiutils.h"
@ -32,6 +33,9 @@ using namespace rtengine::procparams;
FlatField::FlatField () : FoldableToolPanel(this, "flatfield", M("TP_FLATFIELD_LABEL")) FlatField::FlatField () : FoldableToolPanel(this, "flatfield", M("TP_FLATFIELD_LABEL"))
{ {
auto m = ProcEventMapper::getInstance();
EvFlatFieldFromMetaData = m->newEvent(DARKFRAME, "HISTORY_MSG_FF_FROMMETADATA");
hbff = Gtk::manage(new Gtk::Box()); hbff = Gtk::manage(new Gtk::Box());
flatFieldFile = Gtk::manage(new MyFileChooserButton(M("TP_FLATFIELD_LABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN)); flatFieldFile = Gtk::manage(new MyFileChooserButton(M("TP_FLATFIELD_LABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN));
bindCurrentFolder (*flatFieldFile, options.lastFlatfieldDir); bindCurrentFolder (*flatFieldFile, options.lastFlatfieldDir);
@ -42,6 +46,8 @@ FlatField::FlatField () : FoldableToolPanel(this, "flatfield", M("TP_FLATFIELD_L
hbff->pack_start(*flatFieldFile); hbff->pack_start(*flatFieldFile);
hbff->pack_start(*flatFieldFileReset, Gtk::PACK_SHRINK); hbff->pack_start(*flatFieldFileReset, Gtk::PACK_SHRINK);
flatFieldAutoSelect = Gtk::manage(new Gtk::CheckButton((M("TP_FLATFIELD_AUTOSELECT")))); flatFieldAutoSelect = Gtk::manage(new Gtk::CheckButton((M("TP_FLATFIELD_AUTOSELECT"))));
flatFieldFromMetaData = Gtk::manage(new CheckBox((M("TP_FLATFIELD_FROMMETADATA")), multiImage));
flatFieldFromMetaData->setCheckBoxListener (this);
ffInfo = Gtk::manage(new Gtk::Label("-")); ffInfo = Gtk::manage(new Gtk::Label("-"));
setExpandAlignProperties(ffInfo, true, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); setExpandAlignProperties(ffInfo, true, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
flatFieldBlurRadius = Gtk::manage(new Adjuster (M("TP_FLATFIELD_BLURRADIUS"), 0, 200, 2, 32)); flatFieldBlurRadius = Gtk::manage(new Adjuster (M("TP_FLATFIELD_BLURRADIUS"), 0, 200, 2, 32));
@ -70,8 +76,10 @@ FlatField::FlatField () : FoldableToolPanel(this, "flatfield", M("TP_FLATFIELD_L
flatFieldClipControl->show(); flatFieldClipControl->show();
flatFieldClipControl->set_tooltip_markup (M("TP_FLATFIELD_CLIPCONTROL_TOOLTIP")); flatFieldClipControl->set_tooltip_markup (M("TP_FLATFIELD_CLIPCONTROL_TOOLTIP"));
pack_start( *hbff, Gtk::PACK_SHRINK); pack_start( *flatFieldFromMetaData, Gtk::PACK_SHRINK);
pack_start( *Gtk::manage( new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)), Gtk::PACK_SHRINK, 0 );
pack_start( *flatFieldAutoSelect, Gtk::PACK_SHRINK); pack_start( *flatFieldAutoSelect, Gtk::PACK_SHRINK);
pack_start( *hbff, Gtk::PACK_SHRINK);
pack_start( *ffInfo, Gtk::PACK_SHRINK); pack_start( *ffInfo, Gtk::PACK_SHRINK);
pack_start( *hbffbt, Gtk::PACK_SHRINK); pack_start( *hbffbt, Gtk::PACK_SHRINK);
pack_start( *flatFieldBlurRadius, Gtk::PACK_SHRINK); pack_start( *flatFieldBlurRadius, Gtk::PACK_SHRINK);
@ -128,12 +136,14 @@ void FlatField::read(const rtengine::procparams::ProcParams* pp, const ParamsEdi
} }
flatFieldAutoSelect->set_active (pp->raw.ff_AutoSelect); flatFieldAutoSelect->set_active (pp->raw.ff_AutoSelect);
flatFieldFromMetaData->set_active (pp->raw.ff_FromMetaData);
flatFieldBlurRadius->setValue (pp->raw.ff_BlurRadius); flatFieldBlurRadius->setValue (pp->raw.ff_BlurRadius);
flatFieldClipControl->setValue (pp->raw.ff_clipControl); flatFieldClipControl->setValue (pp->raw.ff_clipControl);
flatFieldClipControl->setAutoValue (pp->raw.ff_AutoClipControl); flatFieldClipControl->setAutoValue (pp->raw.ff_AutoClipControl);
if(pedited ) { if(pedited ) {
flatFieldAutoSelect->set_inconsistent (!pedited->raw.ff_AutoSelect); flatFieldAutoSelect->set_inconsistent (!pedited->raw.ff_AutoSelect);
flatFieldFromMetaData->set_inconsistent (!pedited->raw.ff_FromMetaData);
flatFieldBlurRadius->setEditedState( pedited->raw.ff_BlurRadius ? Edited : UnEdited ); flatFieldBlurRadius->setEditedState( pedited->raw.ff_BlurRadius ? Edited : UnEdited );
flatFieldClipControl->setEditedState( pedited->raw.ff_clipControl ? Edited : UnEdited ); flatFieldClipControl->setEditedState( pedited->raw.ff_clipControl ? Edited : UnEdited );
flatFieldClipControl->setAutoInconsistent(multiImage && !pedited->raw.ff_AutoClipControl); flatFieldClipControl->setAutoInconsistent(multiImage && !pedited->raw.ff_AutoClipControl);
@ -214,6 +224,7 @@ void FlatField::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedit
{ {
pp->raw.ff_file = flatFieldFile->get_filename(); pp->raw.ff_file = flatFieldFile->get_filename();
pp->raw.ff_AutoSelect = flatFieldAutoSelect->get_active(); pp->raw.ff_AutoSelect = flatFieldAutoSelect->get_active();
pp->raw.ff_FromMetaData = flatFieldFromMetaData->get_active();
pp->raw.ff_BlurRadius = flatFieldBlurRadius->getIntValue(); pp->raw.ff_BlurRadius = flatFieldBlurRadius->getIntValue();
pp->raw.ff_clipControl = flatFieldClipControl->getIntValue(); pp->raw.ff_clipControl = flatFieldClipControl->getIntValue();
pp->raw.ff_AutoClipControl = flatFieldClipControl->getAutoValue(); pp->raw.ff_AutoClipControl = flatFieldClipControl->getAutoValue();
@ -227,6 +238,7 @@ void FlatField::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedit
if (pedited) { if (pedited) {
pedited->raw.ff_file = ffChanged; pedited->raw.ff_file = ffChanged;
pedited->raw.ff_AutoSelect = !flatFieldAutoSelect->get_inconsistent(); pedited->raw.ff_AutoSelect = !flatFieldAutoSelect->get_inconsistent();
pedited->raw.ff_FromMetaData = !flatFieldFromMetaData->get_inconsistent();
pedited->raw.ff_BlurRadius = flatFieldBlurRadius->getEditedState (); pedited->raw.ff_BlurRadius = flatFieldBlurRadius->getEditedState ();
pedited->raw.ff_clipControl = flatFieldClipControl->getEditedState (); pedited->raw.ff_clipControl = flatFieldClipControl->getEditedState ();
pedited->raw.ff_AutoClipControl = !flatFieldClipControl->getAutoInconsistent(); pedited->raw.ff_AutoClipControl = !flatFieldClipControl->getAutoInconsistent();
@ -352,6 +364,13 @@ void FlatField::flatFieldBlurTypeChanged ()
} }
} }
void FlatField::checkBoxToggled (CheckBox* c, CheckValue newval)
{
if (listener && c == flatFieldFromMetaData) {
listener->panelChanged (EvFlatFieldFromMetaData, flatFieldFromMetaData->getLastActive() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED"));
}
}
void FlatField::flatFieldAutoSelectChanged() void FlatField::flatFieldAutoSelectChanged()
{ {
if (batchMode) { if (batchMode) {
@ -419,3 +438,18 @@ void FlatField::flatFieldAutoClipValueChanged(int n)
} }
); );
} }
void FlatField::setGainMap(bool enabled) {
flatFieldFromMetaData->set_sensitive(enabled);
if (!enabled) {
idle_register.add(
[this, enabled]() -> bool
{
disableListener();
flatFieldFromMetaData->setValue(false);
enableListener();
return false;
}
);
}
}

View File

@ -23,6 +23,7 @@
#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"
@ -42,7 +43,7 @@ public:
// add other info here // add other info here
}; };
class FlatField final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::FlatFieldAutoClipListener class FlatField final : public ToolParamBlock, public AdjusterListener, public CheckBoxListener, public FoldableToolPanel, public rtengine::FlatFieldAutoClipListener
{ {
protected: protected:
@ -52,6 +53,7 @@ protected:
Gtk::Label *ffInfo; Gtk::Label *ffInfo;
Gtk::Button *flatFieldFileReset; Gtk::Button *flatFieldFileReset;
Gtk::CheckButton* flatFieldAutoSelect; Gtk::CheckButton* flatFieldAutoSelect;
CheckBox* flatFieldFromMetaData;
Adjuster* flatFieldClipControl; Adjuster* flatFieldClipControl;
Adjuster* flatFieldBlurRadius; Adjuster* flatFieldBlurRadius;
MyComboBoxText* flatFieldBlurType; MyComboBoxText* flatFieldBlurType;
@ -64,8 +66,10 @@ protected:
Glib::ustring lastShortcutPath; Glib::ustring lastShortcutPath;
bool b_filter_asCurrent; bool b_filter_asCurrent;
bool israw; bool israw;
rtengine::ProcEvent EvFlatFieldFromMetaData;
IdleRegister idle_register; IdleRegister idle_register;
public: public:
FlatField (); FlatField ();
@ -90,4 +94,6 @@ public:
ffp = p; ffp = p;
}; };
void flatFieldAutoClipValueChanged(int n = 0) override; void flatFieldAutoClipValueChanged(int n = 0) override;
void checkBoxToggled(CheckBox* c, CheckValue newval) override;
void setGainMap(bool enabled);
}; };

View File

@ -519,6 +519,7 @@ void ParamsEdited::set(bool v)
raw.df_autoselect = v; raw.df_autoselect = v;
raw.ff_file = v; raw.ff_file = v;
raw.ff_AutoSelect = v; raw.ff_AutoSelect = v;
raw.ff_FromMetaData = v;
raw.ff_BlurRadius = v; raw.ff_BlurRadius = v;
raw.ff_BlurType = v; raw.ff_BlurType = v;
raw.ff_AutoClipControl = v; raw.ff_AutoClipControl = v;
@ -1930,6 +1931,7 @@ void ParamsEdited::initFrom(const std::vector<rtengine::procparams::ProcParams>&
raw.df_autoselect = raw.df_autoselect && p.raw.df_autoselect == other.raw.df_autoselect; raw.df_autoselect = raw.df_autoselect && p.raw.df_autoselect == other.raw.df_autoselect;
raw.ff_file = raw.ff_file && p.raw.ff_file == other.raw.ff_file; raw.ff_file = raw.ff_file && p.raw.ff_file == other.raw.ff_file;
raw.ff_AutoSelect = raw.ff_AutoSelect && p.raw.ff_AutoSelect == other.raw.ff_AutoSelect; raw.ff_AutoSelect = raw.ff_AutoSelect && p.raw.ff_AutoSelect == other.raw.ff_AutoSelect;
raw.ff_FromMetaData = raw.ff_FromMetaData && p.raw.ff_FromMetaData == other.raw.ff_FromMetaData;
raw.ff_BlurRadius = raw.ff_BlurRadius && p.raw.ff_BlurRadius == other.raw.ff_BlurRadius; raw.ff_BlurRadius = raw.ff_BlurRadius && p.raw.ff_BlurRadius == other.raw.ff_BlurRadius;
raw.ff_BlurType = raw.ff_BlurType && p.raw.ff_BlurType == other.raw.ff_BlurType; raw.ff_BlurType = raw.ff_BlurType && p.raw.ff_BlurType == other.raw.ff_BlurType;
raw.ff_AutoClipControl = raw.ff_AutoClipControl && p.raw.ff_AutoClipControl == other.raw.ff_AutoClipControl; raw.ff_AutoClipControl = raw.ff_AutoClipControl && p.raw.ff_AutoClipControl == other.raw.ff_AutoClipControl;
@ -6644,6 +6646,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
toEdit.raw.ff_AutoSelect = mods.raw.ff_AutoSelect; toEdit.raw.ff_AutoSelect = mods.raw.ff_AutoSelect;
} }
if (raw.ff_FromMetaData) {
toEdit.raw.ff_FromMetaData = mods.raw.ff_FromMetaData;
}
if (raw.ff_BlurRadius) { if (raw.ff_BlurRadius) {
toEdit.raw.ff_BlurRadius = mods.raw.ff_BlurRadius; toEdit.raw.ff_BlurRadius = mods.raw.ff_BlurRadius;
} }
@ -7375,7 +7381,7 @@ bool RAWParamsEdited::XTransSensor::isUnchanged() const
bool RAWParamsEdited::isUnchanged() const bool RAWParamsEdited::isUnchanged() const
{ {
return bayersensor.isUnchanged() && xtranssensor.isUnchanged() && ca_autocorrect && ca_avoidcolourshift && caautoiterations && cared && cablue && hotPixelFilter && deadPixelFilter && hotdeadpix_thresh && darkFrame return bayersensor.isUnchanged() && xtranssensor.isUnchanged() && ca_autocorrect && ca_avoidcolourshift && caautoiterations && cared && cablue && hotPixelFilter && deadPixelFilter && hotdeadpix_thresh && darkFrame
&& df_autoselect && ff_file && ff_AutoSelect && ff_BlurRadius && ff_BlurType && exPos && ff_AutoClipControl && ff_clipControl; && df_autoselect && ff_file && ff_AutoSelect && ff_FromMetaData && ff_BlurRadius && ff_BlurType && exPos && ff_AutoClipControl && ff_clipControl;
} }
bool LensProfParamsEdited::isUnchanged() const bool LensProfParamsEdited::isUnchanged() const

View File

@ -1489,6 +1489,7 @@ struct RAWParamsEdited {
bool df_autoselect; bool df_autoselect;
bool ff_file; bool ff_file;
bool ff_AutoSelect; bool ff_AutoSelect;
bool ff_FromMetaData;
bool ff_BlurRadius; bool ff_BlurRadius;
bool ff_BlurType; bool ff_BlurType;
bool ff_AutoClipControl; bool ff_AutoClipControl;

View File

@ -301,6 +301,7 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren
//--- //---
ff_file = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDFILE"))); ff_file = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDFILE")));
ff_AutoSelect = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDAUTOSELECT"))); ff_AutoSelect = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDAUTOSELECT")));
ff_FromMetaData = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDFROMMETADATA")));
ff_BlurType = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDBLURTYPE"))); ff_BlurType = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDBLURTYPE")));
ff_BlurRadius = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDBLURRADIUS"))); ff_BlurRadius = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDBLURRADIUS")));
ff_ClipControl = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDCLIPCONTROL"))); ff_ClipControl = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDCLIPCONTROL")));
@ -423,6 +424,7 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren
vboxes[8]->pack_start (*Gtk::manage (new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)), Gtk::PACK_SHRINK, 0); vboxes[8]->pack_start (*Gtk::manage (new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)), Gtk::PACK_SHRINK, 0);
vboxes[8]->pack_start (*ff_file, Gtk::PACK_SHRINK, 2); vboxes[8]->pack_start (*ff_file, Gtk::PACK_SHRINK, 2);
vboxes[8]->pack_start (*ff_AutoSelect, Gtk::PACK_SHRINK, 2); vboxes[8]->pack_start (*ff_AutoSelect, Gtk::PACK_SHRINK, 2);
vboxes[8]->pack_start (*ff_FromMetaData, Gtk::PACK_SHRINK, 2);
vboxes[8]->pack_start (*ff_BlurType, Gtk::PACK_SHRINK, 2); vboxes[8]->pack_start (*ff_BlurType, Gtk::PACK_SHRINK, 2);
vboxes[8]->pack_start (*ff_BlurRadius, Gtk::PACK_SHRINK, 2); vboxes[8]->pack_start (*ff_BlurRadius, Gtk::PACK_SHRINK, 2);
vboxes[8]->pack_start (*ff_ClipControl, Gtk::PACK_SHRINK, 2); vboxes[8]->pack_start (*ff_ClipControl, Gtk::PACK_SHRINK, 2);
@ -574,6 +576,7 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren
//--- //---
ff_fileConn = ff_file->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); ff_fileConn = ff_file->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
ff_AutoSelectConn = ff_AutoSelect->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); ff_AutoSelectConn = ff_AutoSelect->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
ff_FromMetaDataConn = ff_FromMetaData->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
ff_BlurTypeConn = ff_BlurType->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); ff_BlurTypeConn = ff_BlurType->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
ff_BlurRadiusConn = ff_BlurRadius->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); ff_BlurRadiusConn = ff_BlurRadius->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
ff_ClipControlConn = ff_ClipControl->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); ff_ClipControlConn = ff_ClipControl->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
@ -655,6 +658,7 @@ void PartialPasteDlg::rawToggled ()
ConnectionBlocker df_AutoSelectBlocker(df_AutoSelectConn); ConnectionBlocker df_AutoSelectBlocker(df_AutoSelectConn);
ConnectionBlocker ff_fileBlocker(ff_fileConn); ConnectionBlocker ff_fileBlocker(ff_fileConn);
ConnectionBlocker ff_AutoSelectBlocker(ff_AutoSelectConn); ConnectionBlocker ff_AutoSelectBlocker(ff_AutoSelectConn);
ConnectionBlocker ff_FromMetaDataBlocker(ff_FromMetaDataConn);
ConnectionBlocker ff_BlurTypeBlocker(ff_BlurTypeConn); ConnectionBlocker ff_BlurTypeBlocker(ff_BlurTypeConn);
ConnectionBlocker ff_BlurRadiusBlocker(ff_BlurRadiusConn); ConnectionBlocker ff_BlurRadiusBlocker(ff_BlurRadiusConn);
ConnectionBlocker ff_ClipControlBlocker(ff_ClipControlConn); ConnectionBlocker ff_ClipControlBlocker(ff_ClipControlConn);
@ -685,6 +689,7 @@ void PartialPasteDlg::rawToggled ()
df_AutoSelect->set_active (raw->get_active ()); df_AutoSelect->set_active (raw->get_active ());
ff_file->set_active (raw->get_active ()); ff_file->set_active (raw->get_active ());
ff_AutoSelect->set_active (raw->get_active ()); ff_AutoSelect->set_active (raw->get_active ());
ff_FromMetaData->set_active (raw->get_active ());
ff_BlurType->set_active (raw->get_active ()); ff_BlurType->set_active (raw->get_active ());
ff_BlurRadius->set_active (raw->get_active ()); ff_BlurRadius->set_active (raw->get_active ());
ff_ClipControl->set_active (raw->get_active ()); ff_ClipControl->set_active (raw->get_active ());
@ -1173,6 +1178,10 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param
filterPE.raw.ff_AutoSelect = falsePE.raw.ff_AutoSelect; filterPE.raw.ff_AutoSelect = falsePE.raw.ff_AutoSelect;
} }
if (!ff_FromMetaData->get_active ()) {
filterPE.raw.ff_FromMetaData = falsePE.raw.ff_FromMetaData;
}
if (!ff_BlurRadius->get_active ()) { if (!ff_BlurRadius->get_active ()) {
filterPE.raw.ff_BlurRadius = falsePE.raw.ff_BlurRadius; filterPE.raw.ff_BlurRadius = falsePE.raw.ff_BlurRadius;
} }

View File

@ -214,6 +214,7 @@ public:
Gtk::CheckButton* df_AutoSelect; Gtk::CheckButton* df_AutoSelect;
Gtk::CheckButton* ff_file; Gtk::CheckButton* ff_file;
Gtk::CheckButton* ff_AutoSelect; Gtk::CheckButton* ff_AutoSelect;
Gtk::CheckButton* ff_FromMetaData;
Gtk::CheckButton* ff_BlurRadius; Gtk::CheckButton* ff_BlurRadius;
Gtk::CheckButton* ff_BlurType; Gtk::CheckButton* ff_BlurType;
Gtk::CheckButton* ff_ClipControl; Gtk::CheckButton* ff_ClipControl;
@ -230,7 +231,7 @@ public:
sigc::connection distortionConn, cacorrConn, vignettingConn, lcpConn; sigc::connection distortionConn, cacorrConn, vignettingConn, lcpConn;
sigc::connection coarserotConn, finerotConn, cropConn, resizeConn, prsharpeningConn, perspectiveConn, commonTransConn; sigc::connection coarserotConn, finerotConn, cropConn, resizeConn, prsharpeningConn, perspectiveConn, commonTransConn;
sigc::connection metadataConn, exifchConn, iptcConn, icmConn; sigc::connection metadataConn, exifchConn, iptcConn, icmConn;
sigc::connection df_fileConn, df_AutoSelectConn, ff_fileConn, ff_AutoSelectConn, ff_BlurRadiusConn, ff_BlurTypeConn, ff_ClipControlConn; sigc::connection df_fileConn, df_AutoSelectConn, ff_fileConn, ff_AutoSelectConn, ff_FromMetaDataConn, ff_BlurRadiusConn, ff_BlurTypeConn, ff_ClipControlConn;
sigc::connection raw_caredblueConn, raw_ca_autocorrectConn, raw_ca_avoid_colourshiftconn, raw_hotpix_filtConn, raw_deadpix_filtConn, raw_pdaf_lines_filterConn, raw_linenoiseConn, raw_greenthreshConn, raw_ccStepsConn, raw_methodConn, raw_borderConn, raw_imagenumConn, raw_dcb_iterationsConn, raw_lmmse_iterationsConn, raw_pixelshiftConn, raw_dcb_enhanceConn, raw_exposConn, raw_blackConn; sigc::connection raw_caredblueConn, raw_ca_autocorrectConn, raw_ca_avoid_colourshiftconn, raw_hotpix_filtConn, raw_deadpix_filtConn, raw_pdaf_lines_filterConn, raw_linenoiseConn, raw_greenthreshConn, raw_ccStepsConn, raw_methodConn, raw_borderConn, raw_imagenumConn, raw_dcb_iterationsConn, raw_lmmse_iterationsConn, raw_pixelshiftConn, raw_dcb_enhanceConn, raw_exposConn, raw_blackConn;
sigc::connection filmNegativeConn; sigc::connection filmNegativeConn;
sigc::connection captureSharpeningConn; sigc::connection captureSharpeningConn;

View File

@ -343,12 +343,12 @@ ToolPanelCoordinator::~ToolPanelCoordinator ()
delete toolBar; delete toolBar;
} }
void ToolPanelCoordinator::imageTypeChanged(bool isRaw, bool isBayer, bool isXtrans, bool isMono) void ToolPanelCoordinator::imageTypeChanged(bool isRaw, bool isBayer, bool isXtrans, bool isMono, bool isGainMapSupported)
{ {
if (isRaw) { if (isRaw) {
if (isBayer) { if (isBayer) {
idle_register.add( idle_register.add(
[this]() -> bool [this, isGainMapSupported]() -> bool
{ {
rawPanelSW->set_sensitive(true); rawPanelSW->set_sensitive(true);
sensorxtrans->FoldableToolPanel::hide(); sensorxtrans->FoldableToolPanel::hide();
@ -362,6 +362,7 @@ void ToolPanelCoordinator::imageTypeChanged(bool isRaw, bool isBayer, bool isXtr
preprocessWB->FoldableToolPanel::show(); preprocessWB->FoldableToolPanel::show();
preprocess->FoldableToolPanel::show(); preprocess->FoldableToolPanel::show();
flatfield->FoldableToolPanel::show(); flatfield->FoldableToolPanel::show();
flatfield->setGainMap(isGainMapSupported);
pdSharpening->FoldableToolPanel::show(); pdSharpening->FoldableToolPanel::show();
retinex->FoldableToolPanel::setGrayedOut(false); retinex->FoldableToolPanel::setGrayedOut(false);
return false; return false;
@ -369,7 +370,7 @@ void ToolPanelCoordinator::imageTypeChanged(bool isRaw, bool isBayer, bool isXtr
); );
} else if (isXtrans) { } else if (isXtrans) {
idle_register.add( idle_register.add(
[this]() -> bool [this, isGainMapSupported]() -> bool
{ {
rawPanelSW->set_sensitive(true); rawPanelSW->set_sensitive(true);
sensorxtrans->FoldableToolPanel::show(); sensorxtrans->FoldableToolPanel::show();
@ -383,6 +384,7 @@ void ToolPanelCoordinator::imageTypeChanged(bool isRaw, bool isBayer, bool isXtr
preprocessWB->FoldableToolPanel::show(); preprocessWB->FoldableToolPanel::show();
preprocess->FoldableToolPanel::show(); preprocess->FoldableToolPanel::show();
flatfield->FoldableToolPanel::show(); flatfield->FoldableToolPanel::show();
flatfield->setGainMap(isGainMapSupported);
pdSharpening->FoldableToolPanel::show(); pdSharpening->FoldableToolPanel::show();
retinex->FoldableToolPanel::setGrayedOut(false); retinex->FoldableToolPanel::setGrayedOut(false);
return false; return false;
@ -390,7 +392,7 @@ void ToolPanelCoordinator::imageTypeChanged(bool isRaw, bool isBayer, bool isXtr
); );
} else if (isMono) { } else if (isMono) {
idle_register.add( idle_register.add(
[this]() -> bool [this, isGainMapSupported]() -> bool
{ {
rawPanelSW->set_sensitive(true); rawPanelSW->set_sensitive(true);
sensorbayer->FoldableToolPanel::hide(); sensorbayer->FoldableToolPanel::hide();
@ -403,6 +405,7 @@ void ToolPanelCoordinator::imageTypeChanged(bool isRaw, bool isBayer, bool isXtr
preprocessWB->FoldableToolPanel::hide(); preprocessWB->FoldableToolPanel::hide();
preprocess->FoldableToolPanel::hide(); preprocess->FoldableToolPanel::hide();
flatfield->FoldableToolPanel::show(); flatfield->FoldableToolPanel::show();
flatfield->setGainMap(isGainMapSupported);
pdSharpening->FoldableToolPanel::show(); pdSharpening->FoldableToolPanel::show();
retinex->FoldableToolPanel::setGrayedOut(false); retinex->FoldableToolPanel::setGrayedOut(false);
return false; return false;

View File

@ -260,7 +260,7 @@ public:
void unsetTweakOperator (rtengine::TweakOperator *tOperator) override; void unsetTweakOperator (rtengine::TweakOperator *tOperator) override;
// FilmNegProvider interface // FilmNegProvider interface
void imageTypeChanged (bool isRaw, bool isBayer, bool isXtrans, bool isMono = false) override; void imageTypeChanged (bool isRaw, bool isBayer, bool isXtrans, bool isMono = false, bool isGainMapSupported = false) override;
// profilechangelistener interface // profilechangelistener interface
void profileChange( void profileChange(