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:
parent
2101b846c3
commit
8d29d361a8
@ -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
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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
43
rtengine/dnggainmap.h
Normal 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;
|
||||||
|
};
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user