Add "Inpaint opposed" to Highlight reconstruction and improved Itcwb (#6635)

* Essai HL

* Try Inpaint opposed

* Code improvment

* Add file

* Improvment to process inpaint opposed  and color propagation

* Clean code

* Change Blend to Coloropp in Profile pp3

* Enable BENCHFUN hilite_recon

* Clean rtengine cmakelist

* Comment unused code

* Neutralise unused code

* Change bad Exposure in Pop2Lab.pp3

* Try to fix bug when Inpaint Opposed is used and White balance disabled

* Changes to refreshmap

* Change to improccoordinator M_RETINEX

* Clean unused commented code

* Force Inpaint-opposed in rawimagesouce if wb change

* Suppressed message in console

* Change events and limits to 1 the number of calls to inpaint-opposed

* Comment code

* Add gain theshold to inpaint opposed

* fixed typo in procparams.cc

* Change in option.cc itcwb_sort to true

* Change itcw sorted in options and rawimagesource.cc

* Change sampling read datas Itcwb

* Allow or not purple in WB itcwb

* Added option icwb.nopurple to bypass settings

* Added code comment Itcwb

* optimize Itcwb between green and student

* Formated code used by Itcwb with Astylert.bat

* Change color_match - thanks to Lawrence37

* Remove wrong text
This commit is contained in:
Desmis 2023-02-09 07:14:20 +01:00 committed by GitHub
parent a3adbce04b
commit e5d46032ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 1455 additions and 497 deletions

View File

@ -1417,6 +1417,7 @@ HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values
HISTORY_MSG_GAMUTMUNSEL;Gamut-Munsell
HISTORY_MSG_HISTMATCHING;Auto-matched tone curve
HISTORY_MSG_HLBL;Color propagation - blur
HISTORY_MSG_HLTH;Inpaint opposed - gain threshold
HISTORY_MSG_ICL_LABGRIDCIEXY;Cie xy
HISTORY_MSG_ICM_AINTENT;Abstract profile intent
HISTORY_MSG_ICM_BLUX;Primaries Blue X
@ -2518,8 +2519,10 @@ TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops.
TP_HLREC_BLEND;Blend
TP_HLREC_CIELAB;CIELab Blending
TP_HLREC_COLOR;Color Propagation
TP_HLREC_COLOROPP;Inpaint Opposed
TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels.
TP_HLREC_HLBLUR;Blur
TP_HLREC_HLTH;Gain threshold
TP_HLREC_LABEL;Highlight reconstruction
TP_HLREC_LUMINANCE;Luminance Recovery
TP_HLREC_METHOD;Method:

View File

@ -4,7 +4,7 @@ HistogramMatching=true
[HLRecovery]
Enabled=true
Method=Blend
Method=Coloropp
[Directional Pyramid Denoising]
Enabled=true

View File

@ -4,7 +4,7 @@ HistogramMatching=true
[HLRecovery]
Enabled=true
Method=Blend
Method=Coloropp
[LensProfile]
LcMode=lfauto

View File

@ -4,7 +4,7 @@ HistogramMatching=true
[HLRecovery]
Enabled=true
Method=Blend
Method=Coloropp
[Directional Pyramid Denoising]
Enabled=true

View File

@ -11,7 +11,7 @@ Curve2=1;0;0;0.0397505754145333;0.020171771436200074;0.54669745433149319;0.69419
[HLRecovery]
Enabled=false
Method=Blend
Method=Coloropp
[Black & White]
Enabled=true

View File

@ -11,7 +11,7 @@ Curve2=1;0;0;0.0397505754145333;0.020171771436200074;0.54669745433149319;0.69419
[HLRecovery]
Enabled=false
Method=Blend
Method=Coloropp
[Crop]
FixedRatio=false

View File

@ -19,7 +19,7 @@ Curve2=0;
[HLRecovery]
Enabled=true
Method=Blend
Method=Coloropp
[Luminance Curve]
Enabled=true

View File

@ -19,7 +19,7 @@ Curve2=0;
[HLRecovery]
Enabled=true
Method=Blend
Method=Coloropp
[Luminance Curve]
Enabled=true

View File

@ -19,7 +19,7 @@ Curve2=0;
[HLRecovery]
Enabled=true
Method=Blend
Method=Coloropp
[Luminance Curve]
Enabled=true

View File

@ -19,7 +19,7 @@ Curve2=0;
[HLRecovery]
Enabled=true
Method=Blend
Method=Coloropp
[Black & White]
Enabled=true

View File

@ -6,7 +6,7 @@ Curve=1;0;0;0.11;0.089999999999999997;0.32000000000000001;0.42999999999999999;0.
[HLRecovery]
Enabled=true
Method=Blend
Method=Coloropp
[Directional Pyramid Denoising]
Enabled=true

View File

@ -6,7 +6,7 @@ Curve=1;0;0;0.11;0.089999999999999997;0.32000000000000001;0.42999999999999999;0.
[HLRecovery]
Enabled=true
Method=Blend
Method=Coloropp
[LensProfile]
LcMode=lfauto

View File

@ -6,7 +6,7 @@ Curve=1;0;0;0.11;0.089999999999999997;0.32000000000000001;0.42999999999999999;0.
[HLRecovery]
Enabled=true
Method=Blend
Method=Coloropp
[Directional Pyramid Denoising]
Enabled=true

View File

@ -57,7 +57,7 @@ bool loadFile(
rtengine::procparams::ColorManagementParams icm;
icm.workingProfile = working_color_space;
img_src.getImage(curr_wb, TR_NONE, img_float.get(), pp, rtengine::procparams::ToneCurveParams(), rtengine::procparams::RAWParams());
img_src.getImage(curr_wb, TR_NONE, img_float.get(), pp, rtengine::procparams::ToneCurveParams(), rtengine::procparams::RAWParams(), 0);
if (!working_color_space.empty()) {
img_src.convertColorSpace(img_float.get(), icm, curr_wb);

View File

@ -33,7 +33,7 @@
namespace rtengine
{
static double cie_colour_match_jd2[97][3] = {//350nm to 830nm 5 nm J.Desmis 2° Standard Observer.
static const color_match_type cie_colour_match_jd2 = {//350nm to 830nm 5 nm J.Desmis 2° Standard Observer.
{0.0000000, 0.000000, 0.000000}, {0.0000000, 0.000000, 0.000000}, {0.0001299, 0.0003917, 0.0006061},
{0.0002321, 0.000006965, 0.001086}, {0.0004149, 0.00001239, 0.001946}, {0.0007416, 0.00002202, 0.003846},
{0.001368, 0.000039, 0.006450001}, {0.002236, 0.000064, 0.01054999}, {0.004243, 0.000120, 0.02005001},
@ -70,7 +70,7 @@ static double cie_colour_match_jd2[97][3] = {//350nm to 830nm 5 nm J.Desmis 2
};
static const double cie_colour_match_jd[97][3] = {//350nm to 830nm 5 nm J.Desmis 10° Standard Observer.
static const color_match_type cie_colour_match_jd = {//350nm to 830nm 5 nm J.Desmis 10° Standard Observer.
{0.000000000000, 0.000000000000, 0.000000000000},
{0.000000000000, 0.000000000000, 0.000000000000},
{0.000000122200, 0.000000013398, 0.000000535027},
@ -2963,15 +2963,16 @@ void ColorTemp::temp2mulxyz (double temp, const std::string &method, double &Xxy
// We first test for specially handled methods
const auto iterator = spectMap.find(method);
const auto &color_match = (settings->observer10 == true) ? cie_colour_match_jd : cie_colour_match_jd2;
if (iterator != spectMap.end()) {
spectrum_to_xyz_preset(iterator->second, x, y, z);
spectrum_to_xyz_preset(iterator->second, x, y, z, color_match);
} else {
// otherwise we use the Temp+Green generic solution
if (temp <= INITIALBLACKBODY) {
// if temperature is between 2000K and 4000K we use blackbody, because there will be no Daylight reference below 4000K...
// of course, the previous version of RT used the "magical" but wrong formula of U.Fuchs (Ufraw).
spectrum_to_xyz_blackbody(temp, x, y, z);
spectrum_to_xyz_blackbody(temp, x, y, z, color_match);
} else {
// from 4000K up to 25000K: using the D illuminant (daylight) which is standard
double x_D, y_D;
@ -2990,7 +2991,7 @@ void ColorTemp::temp2mulxyz (double temp, const std::string &method, double &Xxy
double interm = 0.0241 + 0.2562 * x_D - 0.734 * y_D;
double m1 = (-1.3515 - 1.7703 * x_D + 5.9114 * y_D) / interm;
double m2 = (0.03 - 31.4424 * x_D + 30.0717 * y_D) / interm;
spectrum_to_xyz_daylight(m1, m2, x, y, z);
spectrum_to_xyz_daylight(m1, m2, x, y, z, color_match);
}
}
@ -3169,17 +3170,19 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul,
float CRI_RT = 0.0, CRI[50];
float CRI_RTs = 0.0, CRIs[8];
const auto &color_match = (settings->observer10 == true) ? cie_colour_match_jd : cie_colour_match_jd2;
for(int i = 0; i < N_c; i++) {
spectrum_to_color_xyz_preset(spec_color[i], spect_illum[illum + 3], XchkLamp[i], YchkLamp[i], ZchkLamp[i]);
spectrum_to_color_xyz_preset(spec_color[i], spect_illum[illum + 3], XchkLamp[i], YchkLamp[i], ZchkLamp[i], color_match);
}
//calculate XYZ for each color : for Blackbody and Daylight at tempw
if(tempw <= INITIALBLACKBODY) {
for(int i = 0; i < N_c; i++) {
spectrum_to_color_xyz_blackbody(spec_color[i], tempw, Xchk[i], Ychk[i], Zchk[i]);
spectrum_to_color_xyz_blackbody(spec_color[i], tempw, Xchk[i], Ychk[i], Zchk[i], color_match);
}
spectrum_to_xyz_blackbody(tempw, x, y, z);//for white point
spectrum_to_xyz_blackbody(tempw, x, y, z, color_match);//for white point
} else { // after 6600K (arbitrary) I use daylight...because ...but there is no lamp...
double m11, m22, x_DD, y_DD, interm2;
@ -3197,10 +3200,10 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul,
m22 = (0.03 - 31.4424 * x_DD + 30.0717 * y_DD) / interm2;
for(int i = 0; i < N_c; i++) {
spectrum_to_color_xyz_daylight(spec_color[i], m11, m22, Xchk[i], Ychk[i], Zchk[i]);
spectrum_to_color_xyz_daylight(spec_color[i], m11, m22, Xchk[i], Ychk[i], Zchk[i], color_match);
}
spectrum_to_xyz_daylight(m11, m22, x, y, z);
spectrum_to_xyz_daylight(m11, m22, x, y, z, color_match);
}
if (settings->verbose) {
@ -3394,16 +3397,16 @@ I have increase precision used by J.Walker and pass to 350nm to 830nm
And also add 10° standard observer
*/
void ColorTemp::spectrum_to_xyz_daylight(double _m1, double _m2, double &x, double &y, double &z)
void ColorTemp::spectrum_to_xyz_daylight(double _m1, double _m2, double &x, double &y, double &z, const color_match_type &color_match)
{
int i;
double lambda, X = 0, Y = 0, Z = 0, XYZ;
for (i = 0, lambda = 350.; lambda < 830.1; i++, lambda += 5.) {
double Me = daylight_spect(lambda, _m1, _m2);
X += Me * cie_colour_match_jd2[i][0];
Y += Me * cie_colour_match_jd2[i][1];
Z += Me * cie_colour_match_jd2[i][2];
X += Me * color_match[i][0];
Y += Me * color_match[i][1];
Z += Me * color_match[i][2];
}
XYZ = (X + Y + Z);
@ -3412,16 +3415,16 @@ void ColorTemp::spectrum_to_xyz_daylight(double _m1, double _m2, double &x, doub
z = Z / XYZ;
}
void ColorTemp::spectrum_to_xyz_blackbody(double _temp, double &x, double &y, double &z)
void ColorTemp::spectrum_to_xyz_blackbody(double _temp, double &x, double &y, double &z, const color_match_type &color_match)
{
int i;
double lambda, X = 0, Y = 0, Z = 0, XYZ;
for (i = 0, lambda = 350.; lambda < 830.1; i++, lambda += 5.) {
double Me = blackbody_spect(lambda, _temp);
X += Me * cie_colour_match_jd2[i][0];
Y += Me * cie_colour_match_jd2[i][1];
Z += Me * cie_colour_match_jd2[i][2];
X += Me * color_match[i][0];
Y += Me * color_match[i][1];
Z += Me * color_match[i][2];
}
XYZ = (X + Y + Z);
@ -3430,7 +3433,7 @@ void ColorTemp::spectrum_to_xyz_blackbody(double _temp, double &x, double &y, do
z = Z / XYZ;
}
void ColorTemp::spectrum_to_xyz_preset(const double* spec_intens, double &x, double &y, double &z)
void ColorTemp::spectrum_to_xyz_preset(const double* spec_intens, double &x, double &y, double &z, const color_match_type &color_match)
{
int i;
double lambda, X = 0, Y = 0, Z = 0, XYZ;
@ -3454,9 +3457,9 @@ void ColorTemp::spectrum_to_xyz_preset(const double* spec_intens, double &x, dou
*/
for (i = 0, lambda = 350.; lambda < 830.1; i++, lambda += 5.) {
double Me = get_spectral_color(lambda, spec_intens);
X += Me * cie_colour_match_jd2[i][0];
Y += Me * cie_colour_match_jd2[i][1];
Z += Me * cie_colour_match_jd2[i][2];
X += Me * color_match[i][0];
Y += Me * color_match[i][1];
Z += Me * color_match[i][2];
}
XYZ = (X + Y + Z);
@ -3466,7 +3469,7 @@ void ColorTemp::spectrum_to_xyz_preset(const double* spec_intens, double &x, dou
}
//calculate XYZ from spectrum data (color) and illuminant : J.Desmis December 2011
void ColorTemp::spectrum_to_color_xyz_preset(const double* spec_color, const double* spec_intens, double &xx, double &yy, double &zz)
void ColorTemp::spectrum_to_color_xyz_preset(const double* spec_color, const double* spec_intens, double &xx, double &yy, double &zz, const color_match_type &color_match)
{
int i;
double lambda, X = 0, Y = 0, Z = 0, Yo = 0;
@ -3478,9 +3481,9 @@ void ColorTemp::spectrum_to_color_xyz_preset(const double* spec_color, const dou
Me = get_spectral_color(lambda, spec_color);
Mc = get_spectral_color(lambda, spec_intens);
X += Mc * cie_colour_match_jd2[i][0] * Me;
Y += Mc * cie_colour_match_jd2[i][1] * Me;
Z += Mc * cie_colour_match_jd2[i][2] * Me;
X += Mc * color_match[i][0] * Me;
Y += Mc * color_match[i][1] * Me;
Z += Mc * color_match[i][2] * Me;
}
for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) {
@ -3488,7 +3491,7 @@ void ColorTemp::spectrum_to_color_xyz_preset(const double* spec_color, const dou
double Ms;
Ms = get_spectral_color(lambda, spec_intens);
Yo += cie_colour_match_jd2[i][1] * Ms;
Yo += color_match[i][1] * Ms;
}
xx = X / Yo;
@ -3497,7 +3500,7 @@ void ColorTemp::spectrum_to_color_xyz_preset(const double* spec_color, const dou
}
//calculate XYZ from spectrum data (color) and illuminant : J.Desmis december 2011
void ColorTemp::spectrum_to_color_xyz_daylight(const double* spec_color, double _m1, double _m2, double &xx, double &yy, double &zz)
void ColorTemp::spectrum_to_color_xyz_daylight(const double* spec_color, double _m1, double _m2, double &xx, double &yy, double &zz, const color_match_type &color_match)
{
int i;
double lambda, X = 0, Y = 0, Z = 0;
@ -3505,9 +3508,9 @@ void ColorTemp::spectrum_to_color_xyz_daylight(const double* spec_color, double
for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) {
const double Me = spec_color[i];
const double Mc = daylight_spect(lambda, _m1, _m2);
X += Mc * cie_colour_match_jd2[i][0] * Me;
Y += Mc * cie_colour_match_jd2[i][1] * Me;
Z += Mc * cie_colour_match_jd2[i][2] * Me;
X += Mc * color_match[i][0] * Me;
Y += Mc * color_match[i][1] * Me;
Z += Mc * color_match[i][2] * Me;
}
xx = X / Y;
@ -3516,7 +3519,7 @@ void ColorTemp::spectrum_to_color_xyz_daylight(const double* spec_color, double
}
//calculate XYZ from spectrum data (color) and illuminant : J.Desmis december 2011
void ColorTemp::spectrum_to_color_xyz_blackbody(const double* spec_color, double _temp, double &xx, double &yy, double &zz)
void ColorTemp::spectrum_to_color_xyz_blackbody(const double* spec_color, double _temp, double &xx, double &yy, double &zz, const color_match_type &color_match)
{
int i;
double lambda, X = 0, Y = 0, Z = 0;
@ -3524,9 +3527,9 @@ void ColorTemp::spectrum_to_color_xyz_blackbody(const double* spec_color, double
for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) {
const double Me = spec_color[i];
const double Mc = blackbody_spect(lambda, _temp);
X += Mc * cie_colour_match_jd2[i][0] * Me;
Y += Mc * cie_colour_match_jd2[i][1] * Me;
Z += Mc * cie_colour_match_jd2[i][2] * Me;
X += Mc * color_match[i][0] * Me;
Y += Mc * color_match[i][1] * Me;
Z += Mc * color_match[i][2] * Me;
}
xx = X / Y;
@ -3762,27 +3765,21 @@ void ColorTemp::tempxy(bool separated, int repref, float **Tx, float **Ty, float
}
if (settings->verbose) {
if (settings->itcwb_stdobserver10 == false) {
if (settings->itcwb_stdobserver10 == false) {//I will try to change settings by main
printf("Use standard observer 2°\n");
} else {
printf("Use standard observer 10°\n");
}
}
if (settings->itcwb_stdobserver10 == true) {
for (int i = 0; i < 97; i++) {
cie_colour_match_jd2[i][0] = cie_colour_match_jd[i][0];
cie_colour_match_jd2[i][1] = cie_colour_match_jd[i][1];;
cie_colour_match_jd2[i][2] = cie_colour_match_jd[i][2];
}
}
const color_match_type &color_match = (settings->itcwb_stdobserver10 == true) ? cie_colour_match_jd : cie_colour_match_jd2;
if (separated) {
const double tempw = Txyz[repref].Tem;
if (tempw <= INITIALBLACKBODY) {
for (int i = 0; i < N_c; i++) {
spectrum_to_color_xyz_blackbody(spec_colorforxcyc[i], tempw, TX[i], TY[i], TZ[i]);
spectrum_to_color_xyz_blackbody(spec_colorforxcyc[i], tempw, TX[i], TY[i], TZ[i], color_match);
}
} else {
double m11, m22, x_DD, y_DD, interm2;
@ -3801,7 +3798,7 @@ void ColorTemp::tempxy(bool separated, int repref, float **Tx, float **Ty, float
m22 = (0.03 - 31.4424 * x_DD + 30.0717 * y_DD) / interm2;
for (int i = 0; i < N_c; i++) {
spectrum_to_color_xyz_daylight(spec_colorforxcyc[i], m11, m22, TX[i], TY[i], TZ[i]);
spectrum_to_color_xyz_daylight(spec_colorforxcyc[i], m11, m22, TX[i], TY[i], TZ[i], color_match);
}
}
} else {
@ -3810,7 +3807,7 @@ void ColorTemp::tempxy(bool separated, int repref, float **Tx, float **Ty, float
if (tempw <= INITIALBLACKBODY) {
for (int i = 0; i < N_c; i++) {
spectrum_to_color_xyz_blackbody(spec_colorforxcyc[i], tempw, Refxyz[i].Xref, Refxyz[i].Yref, Refxyz[i].Zref);
spectrum_to_color_xyz_blackbody(spec_colorforxcyc[i], tempw, Refxyz[i].Xref, Refxyz[i].Yref, Refxyz[i].Zref, color_match);
}
} else {
double x_DD;
@ -3829,7 +3826,7 @@ void ColorTemp::tempxy(bool separated, int repref, float **Tx, float **Ty, float
const double m22 = (0.03 - 31.4424 * x_DD + 30.0717 * y_DD) / interm2;
for (int i = 0; i < N_c; i++) {
spectrum_to_color_xyz_daylight(spec_colorforxcyc[i], m11, m22, Refxyz[i].Xref, Refxyz[i].Yref, Refxyz[i].Zref);
spectrum_to_color_xyz_daylight(spec_colorforxcyc[i], m11, m22, Refxyz[i].Xref, Refxyz[i].Yref, Refxyz[i].Zref, color_match);
}
}

View File

@ -26,6 +26,8 @@
namespace rtengine
{
using color_match_type = double [97][3];
constexpr double MINTEMP = 1500.0;
constexpr double MAXTEMP = 60000.0;
constexpr double MINGREEN = 0.02;
@ -375,13 +377,13 @@ public:
static const double JDC468_greym13_325_spect[97];
static const double JDC468_greyf26_156_spect[97];
*/
static void spectrum_to_xyz_daylight (double _m1, double _m2, double &x, double &y, double &z);
static void spectrum_to_xyz_blackbody (double _temp, double &x, double &y, double &z);
static void spectrum_to_xyz_preset (const double* spec_intens, double &x, double &y, double &z);
static void spectrum_to_xyz_daylight (double _m1, double _m2, double &x, double &y, double &z, const color_match_type &color_match);
static void spectrum_to_xyz_blackbody (double _temp, double &x, double &y, double &z, const color_match_type &color_match);
static void spectrum_to_xyz_preset (const double* spec_intens, double &x, double &y, double &z, const color_match_type &color_match);
static void spectrum_to_color_xyz_daylight (const double* spec_color, double _m1, double _m2, double &xx, double &yy, double &zz);
static void spectrum_to_color_xyz_blackbody (const double* spec_color, double _temp, double &xx, double &yy, double &zz);
static void spectrum_to_color_xyz_preset (const double* spec_color, const double* spec_intens, double &xx, double &yy, double &zz);
static void spectrum_to_color_xyz_daylight (const double* spec_color, double _m1, double _m2, double &xx, double &yy, double &zz, const color_match_type &color_match);
static void spectrum_to_color_xyz_blackbody (const double* spec_color, double _temp, double &xx, double &yy, double &zz, const color_match_type &color_match);
static void spectrum_to_color_xyz_preset (const double* spec_color, const double* spec_intens, double &xx, double &yy, double &zz, const color_match_type &color_match);
};
}

View File

@ -228,18 +228,18 @@ void Crop::update(int todo)
if (settings->leveldnautsimpl == 1) {
if (params.dirpyrDenoise.Cmethod == "MAN" || params.dirpyrDenoise.Cmethod == "PON") {
PreviewProps pp(trafx, trafy, trafw * skip, trafh * skip, skip);
parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw);
parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw, 0);
}
} else {
if (params.dirpyrDenoise.C2method == "MANU") {
PreviewProps pp(trafx, trafy, trafw * skip, trafh * skip, skip);
parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw);
parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw, 0);
}
}
if ((settings->leveldnautsimpl == 1 && params.dirpyrDenoise.Cmethod == "PRE") || (settings->leveldnautsimpl == 0 && params.dirpyrDenoise.C2method == "PREV")) {
PreviewProps pp(trafx, trafy, trafw * skip, trafh * skip, skip);
parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw);
parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw, 0);
if ((!isDetailWindow) && parent->adnListener && skip == 1 && params.dirpyrDenoise.enabled) {
float lowdenoise = 1.f;
@ -451,7 +451,7 @@ void Crop::update(int todo)
for (int wcr = 0; wcr <= 2; wcr++) {
for (int hcr = 0; hcr <= 2; hcr++) {
PreviewProps ppP(coordW[wcr], coordH[hcr], crW, crH, 1);
parent->imgsrc->getImage(parent->currWB, tr, origCropPart, ppP, params.toneCurve, params.raw);
parent->imgsrc->getImage(parent->currWB, tr, origCropPart, ppP, params.toneCurve, params.raw, 0);
// we only need image reduced to 1/4 here
for (int ii = 0; ii < crH; ii += 2) {
@ -613,7 +613,7 @@ void Crop::update(int todo)
// if (params.dirpyrDenoise.Cmethod=="AUT" || params.dirpyrDenoise.Cmethod=="PON") {//reinit origCrop after Auto
if ((settings->leveldnautsimpl == 1 && params.dirpyrDenoise.Cmethod == "AUT") || (settings->leveldnautsimpl == 0 && params.dirpyrDenoise.C2method == "AUTO")) { //reinit origCrop after Auto
PreviewProps pp(trafx, trafy, trafw * skip, trafh * skip, skip);
parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw);
parent->imgsrc->getImage(parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw, 0);
}
if ((todo & M_SPOT) && params.spot.enabled && !params.spot.entries.empty()) {
@ -749,7 +749,7 @@ void Crop::update(int todo)
fattalCrop.reset(f);
PreviewProps pp(0, 0, parent->fw, parent->fh, skip);
int tr = getCoarseBitMask(params.coarse);
parent->imgsrc->getImage(parent->currWB, tr, f, pp, params.toneCurve, params.raw);
parent->imgsrc->getImage(parent->currWB, tr, f, pp, params.toneCurve, params.raw, 0);
parent->imgsrc->convertColorSpace(f, params.icm, parent->currWB);
if (params.dirpyrDenoise.enabled || params.filmNegative.enabled || params.spot.enabled) {

View File

@ -84,7 +84,7 @@ void getSpotAvgMax(ImageSource *imgsrc, ColorTemp currWB, const std::unique_ptr<
}
rtengine::Imagefloat spotImg(spotSize, spotSize);
imgsrc->getImage(currWB, tr, &spotImg, pp, params->toneCurve, params->raw);
imgsrc->getImage(currWB, tr, &spotImg, pp, params->toneCurve, params->raw, 0);
auto avgMax = [spotSize, &spotImg](RGB & avg, RGB & max) -> void {
avg = {};

View File

@ -32,14 +32,15 @@
#include "opthelper.h"
#include "rawimagesource.h"
#include "rt_math.h"
//#define BENCHMARK
//#include "StopWatch.h"
#define BENCHMARK
#include "StopWatch.h"
#include "guidedfilter.h"
#include "settings.h"
#include "gauss.h"
#include "rescale.h"
#include "iccstore.h"
#include "color.h"
#include "linalgebra.h"
namespace
{
@ -301,7 +302,7 @@ using namespace procparams;
void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue, int blur)
{
// BENCHFUN
BENCHFUN
double progress = 0.0;
if (plistener) {
@ -1226,5 +1227,371 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue
}// end of HLReconstruction
//-----------------------------------------------------------------------------
// "inpaint opposed" algorithm taken from darktable
//
// (Very effective, very simple, very neat)
//
// Kudos to the original authors (@jenshannoschwalm from dt, in collaboration
// with @garagecoder and @Iain from gmic).
//
// Copyright and description of the original code follows
//
/*
Copyright (C) 2022 darktable developers.
darktable 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.
darktable 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 darktable. If not, see <http://www.gnu.org/licenses/>.
*/
/* The refavg values are calculated in raw-RGB-cube3 space
We calculate all color channels in the 3x3 photosite area, this can be understaood as a "superpixel",
the "asking" location is in the centre.
As this works for bayer and xtrans sensors we don't have a fixed ratio but calculate the average
for every color channel first.
refavg for one of red, green or blue is defined as means of both other color channels (opposing).
The basic idea / observation for the _process_opposed algorithm is, the refavg is a good estimate
for any clipped color channel in the vast majority of images, working mostly fine both for small specular
highlighted spots and large areas.
The correction via some sort of global chrominance further helps to correct color casts.
The chrominace data are taken from the areas morphologically very close to clipped data.
Failures of the algorithm (color casts) are in most cases related to
a) very large differences between optimal white balance coefficients vs what we have as D65 in the darktable pipeline
b) complicated lightings so the gradients are not well related
c) a wrong whitepoint setting in the rawprepare module.
d) the maths might not be best
*/
//-----------------------------------------------------------------------------
namespace {
constexpr int HL_BORDER = 8;
constexpr float HL_POWERF = 3.0f;
// void border_fill_zero(int *d, int width, int height)
// {
// for (int i = 0; i < HL_BORDER * width; i++) {
// d[i] = 0;
// }
// for (int i = (height - HL_BORDER - 1) * width; i < width*height; i++) {
// d[i] = 0;
// }
// for (int row = HL_BORDER; row < height - HL_BORDER; row++) {
// int *p1 = d + row*width;
// int *p2 = d + (row+1)*width - HL_BORDER;
// for(int i = 0; i < HL_BORDER; i++) {
// p1[i] = p2[i] = 0;
// }
// }
// }
int test_dilate(const int *img, int i, int w1)
{
int retval = 0;
retval = img[i-w1-1] | img[i-w1] | img[i-w1+1] |
img[i-1] | img[i] | img[i+1] |
img[i+w1-1] | img[i+w1] | img[i+w1+1];
if (retval) {
return retval;
}
const size_t w2 = 2*w1;
retval = img[i-w2-1] | img[i-w2] | img[i-w2+1] |
img[i-w1-2] | img[i-w1+2] |
img[i-2] | img[i+2] |
img[i+w1-2] | img[i+w1+2] |
img[i+w2-1] | img[i+w2] | img[i+w2+1];
if (retval) {
return retval;
}
const size_t w3 = 3*w1;
retval = img[i-w3-2] | img[i-w3-1] | img[i-w3] | img[i-w3+1] | img[i-w3+2] |
img[i-w2-3] | img[i-w2-2] | img[i-w2+2] | img[i-w2+3] |
img[i-w1-3] | img[i-w1+3] |
img[i-3] | img[i+3] |
img[i+w1-3] | img[i+w1+3] |
img[i+w2-3] | img[i+w2-2] | img[i+w2+2] | img[i+w2+3] |
img[i+w3-2] | img[i+w3-1] | img[i+w3] | img[i+w3+1] | img[i+w3+2];
return retval;
}
void dilating(const int *img, int *o, int w1, int height)
{
#ifdef _OPENMP
# pragma omp parallel for
#endif
for (int row = HL_BORDER; row < height - HL_BORDER; row++) {
for (int col = HL_BORDER, i = row*w1 + col; col < w1 - HL_BORDER; col++, i++) {
o[i] = test_dilate(img, i, w1);
}
}
}
} // namespace
void RawImageSource::highlight_recovery_opposed(float scale_mul[3], const ColorTemp &wb, float gainth)
{
BENCHFUN
if (settings->verbose) {
std::cout << "Applying Highlight Recovery: Inpaint opposed" << std::endl;
}
if (plistener) {
plistener->setProgressStr("PROGRESSBAR_HLREC");
plistener->setProgress(0);
}
double rr, gg, bb;
wb.getMultipliers(rr, gg, bb);
wbMul2Camera(rr, gg, bb);
float gain = 1.2f * gainth;
float clipval = 0.987f / gain;
const float scalecoeffs[3] = {
scale_mul[0] * float(rr) / 65535.f,
scale_mul[1] * float(gg) / 65535.f,
scale_mul[2] * float(bb) / 65535.f,
};
const float clips[3] = {
clipval * float(rr),
clipval * float(gg),
clipval * float(bb)
};
const float clipdark[3] = {
0.03f * clips[0],
0.125f * clips[1],
0.03f * clips[2]
};
bool anyclipped = false;
float **chan[3] = { red, green, blue };
const float clipscale[3] = {
clips[0] / scalecoeffs[0],
clips[1] / scalecoeffs[1],
clips[2] / scalecoeffs[2]
};
int x1 = W, y1 = H, x2 = 0, y2 = 0;
for (int y = 0; y < H; ++y) {
for (int x = 0; x < W; ++x) {
for (int c = 0; c < 3; ++c) {
if (chan[c][y][x] >= clipscale[c]) {
anyclipped = true;
x1 = std::min(x, x1);
x2 = std::max(x, x2);
y1 = std::min(y, y1);
y2 = std::max(y, y2);
}
}
}
}
if (!anyclipped) {
if (plistener) {
plistener->setProgress(1.0);
}
return;
}
x1 = std::max(x1-1, 0);
x2 = std::min(x2+1, W-1);
y1 = std::max(y1-1, 0);
y2 = std::min(y2+1, H-1);
const int cW = x2 - x1 + 1;
const int cH = y2 - y1 + 1;
#ifdef _OPENMP
# pragma omp parallel for
#endif
for (int y = 0; y < cH; ++y) {
const int yy = y + y1;
for (int x = 0; x < cW; ++x) {
const int xx = x + x1;
for (int c = 0; c < 3; ++c) {
chan[c][yy][xx] *= scalecoeffs[c];
}
}
}
if (plistener) {
plistener->setProgress(0.1);
}
multi_array2D<float, 3> tmp(cW, cH);
const int pwidth = cW + 2 * HL_BORDER;
const int pheight = cH + 2 * HL_BORDER;
const int p_size = pwidth * pheight;
AlignedBuffer<int> mask_vec(4 * p_size);
int *mask_buffer = mask_vec.data;
const auto mask_val =
[&](int c, int y, int x) -> int &
{
return mask_buffer[c * p_size + (HL_BORDER + y) * pwidth + x + HL_BORDER];
};
const auto set_refavg =
[&](int y, int x) -> bool
{
const int yy = y + y1;
const int xx = x + x1;
bool found = false;
for (int c = 0; c < 3 && !found; ++c) {
if (chan[c][yy][xx] >= clips[c]) {
found = true;
}
}
if (!found) {
return false;
}
float mean[3] = { 0.0f, 0.0f, 0.0f };
for (int dy = -1; dy < 2; dy++) {
for (int dx = -1; dx < 2; dx++) {
for (int c = 0; c < 3; ++c) {
mean[c] += std::max(0.0f, chan[c][yy+dy][xx+dx]);
}
}
}
for (int c = 0; c < 3; ++c) {
mean[c] = pow_F(mean[c] / 9.0f, 1.0f / HL_POWERF);
}
const float croot_refavg[3] = {
0.5f * (mean[1] + mean[2]),
0.5f * (mean[0] + mean[2]),
0.5f * (mean[0] + mean[1])
};
for (int c = 0; c < 3; ++c) {
if (chan[c][yy][xx] >= clips[c]) {
tmp[c][y][x] = pow_F(croot_refavg[c], HL_POWERF);
mask_val(c, y, x) = 1;
}
}
return true;
};
#ifdef _OPENMP
# pragma omp parallel for
#endif
for (int y = 0; y < cH; ++y) {
const int yy = y + y1;
for (int x = 0; x < cW; ++x) {
const int xx = x + x1;
for (int c = 0; c < 3; ++c) {
tmp[c][y][x] = std::max(0.f, chan[c][yy][xx]);
}
if ((x > 0) && (x < cW - 1) && (y > 0) && (y < cH - 1)) {
set_refavg(y, x);
}
}
}
if (plistener) {
plistener->setProgress(0.3);
}
for (size_t i = 0; i < 3; i++) {
int *mask = mask_buffer + i * p_size;
int *tmp = mask_buffer + 3 * p_size;
//border_fill_zero(mask, pwidth, pheight);
dilating(mask, tmp, pwidth, pheight);
memcpy(mask, tmp, p_size * sizeof(int));
}
float cr_sum[3] = { 0.f, 0.f, 0.f };
int cr_cnt[3] = { 0, 0, 0 };
#ifdef _OPENMP
# pragma omp parallel for reduction(+ : cr_sum, cr_cnt)
#endif
for (int y = 1; y < cH-1; ++y) {
const int yy = y + y1;
for (int x = 1; x < cW-1; ++x) {
const int xx = x + x1;
for (int c = 0; c < 3; ++c) {
const float inval = std::max(0.0f, chan[c][yy][xx]);
if (mask_val(c, y, x) && (inval > clipdark[c]) && (inval < clips[c])) {
cr_sum[c] += inval - tmp[c][y][x];
++cr_cnt[c];
}
}
}
}
if (plistener) {
plistener->setProgress(0.6);
}
float chrominance[3] = {
cr_sum[0] / std::max(1.f, float(cr_cnt[0])),
cr_sum[1] / std::max(1.f, float(cr_cnt[1])),
cr_sum[2] / std::max(1.f, float(cr_cnt[2]))
};
#ifdef _OPENMP
# pragma omp parallel for
#endif
for (int y = 0; y < cH; ++y) {
const int yy = y + y1;
for (int x = 0; x < cW; ++x) {
const int xx = x + x1;
for (int c = 0; c < 3; ++c) {
const float inval = std::max(0.0f, chan[c][yy][xx]);
if (inval >= clips[c]) {
chan[c][yy][xx] = std::max(inval, tmp[c][y][x] + chrominance[c]);
}
}
}
}
if (plistener) {
plistener->setProgress(0.9);
}
#ifdef _OPENMP
# pragma omp parallel for
#endif
for (int y = 0; y < cH; ++y) {
const int yy = y + y1;
for (int x = 0; x < cW; ++x) {
const int xx = x + x1;
for (int c = 0; c < 3; ++c) {
chan[c][yy][xx] /= scalecoeffs[c];
}
}
}
if (plistener) {
plistener->setProgress(1.0);
}
}
}

View File

@ -111,7 +111,7 @@ public:
{
rm = gm = bm = 1.0;
}
virtual void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double &rm, double &gm, double &bm, const procparams::WBParams & wbpar, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw)
virtual void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double &rm, double &gm, double &bm, const procparams::WBParams & wbpar, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::ToneCurveParams &hrp)
{
rm = gm = bm = 1.0;
}

View File

@ -109,7 +109,7 @@ public:
virtual void getWBMults (const ColorTemp &ctemp, const procparams::RAWParams &raw, std::array<float, 4>& scale_mul, float &autoGainComp, float &rm, float &gm, float &bm) const = 0;
// use right after demosaicing image, add coarse transformation and put the result in the provided Imagefloat*
virtual void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const procparams::ToneCurveParams &hlp, const procparams::RAWParams &raw) = 0;
virtual void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const procparams::ToneCurveParams &hlp, const procparams::RAWParams &raw, int opposed) = 0;
virtual eSensorType getSensorType () const = 0;
virtual bool isMono () const = 0;
// true is ready to provide the AutoWB, i.e. when the image has been demosaiced for RawImageSource
@ -117,10 +117,10 @@ public:
virtual void convertColorSpace (Imagefloat* image, const procparams::ColorManagementParams &cmp, const ColorTemp &wb) = 0; // DIRTY HACK: this method is derived in rawimagesource and strimagesource, but (...,RAWParams raw) will be used ONLY for raw images
virtual void getAutoWBMultipliers (double &rm, double &gm, double &bm) = 0;
virtual void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double & greenitc, float &studgood, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double &rm, double &gm, double &bm, const procparams::WBParams & wbpar, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw) = 0;
virtual void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double & greenitc, float &studgood, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double &rm, double &gm, double &bm, const procparams::WBParams & wbpar, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::ToneCurveParams &hrp) = 0;
virtual ColorTemp getWB () const = 0;
virtual ColorTemp getSpotWB (std::vector<Coord2D> &red, std::vector<Coord2D> &green, std::vector<Coord2D> &blue, int tran, double equal) = 0;
virtual void WBauto(double &tempref, double &greenref, array2D<float> &redloc, array2D<float> &greenloc, array2D<float> &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, double &tempitc, double &greenitc, float &studgood, bool &twotimes, const procparams::WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw) = 0;
virtual void WBauto(double &tempref, double &greenref, array2D<float> &redloc, array2D<float> &greenloc, array2D<float> &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, double &tempitc, double &greenitc, float &studgood, bool &twotimes, const procparams::WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::ToneCurveParams &hrp) = 0;
virtual void getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w) = 0;
virtual double getDefGain () const
@ -195,6 +195,9 @@ public:
}
virtual void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) = 0;
virtual void captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold, double &radius) = 0;
virtual void wbMul2Camera(double &rm, double &gm, double &bm) = 0;
virtual void wbCamera2Mul(double &rm, double &gm, double &bm) = 0;
};
}

View File

@ -409,11 +409,13 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
if (imageTypeListener) {
imageTypeListener->imageTypeChanged(imgsrc->isRAW(), imgsrc->getSensorType() == ST_BAYER, imgsrc->getSensorType() == ST_FUJI_XTRANS, imgsrc->isMono(), imgsrc->isGainMapSupported());
}
bool iscolor = (params->toneCurve.method == "Color");// || params->toneCurve.method == "Coloropp");
if ((todo & M_RAW)
|| (!highDetailRawComputed && highDetailNeeded)
|| (params->toneCurve.hrenabled && params->toneCurve.method != "Color" && imgsrc->isRGBSourceModified())
|| (!params->toneCurve.hrenabled && params->toneCurve.method == "Color" && imgsrc->isRGBSourceModified())) {
// || (params->toneCurve.hrenabled && params->toneCurve.method != "Color" && imgsrc->isRGBSourceModified())
// || (!params->toneCurve.hrenabled && params->toneCurve.method == "Color" && imgsrc->isRGBSourceModified())) {
|| (params->toneCurve.hrenabled && !iscolor && imgsrc->isRGBSourceModified())
|| (!params->toneCurve.hrenabled && iscolor && imgsrc->isRGBSourceModified())) {
if (settings->verbose) {
if (imgsrc->getSensorType() == ST_BAYER) {
@ -466,8 +468,10 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
if ((todo & M_RAW)
|| (!highDetailRawComputed && highDetailNeeded)
|| (params->toneCurve.hrenabled && params->toneCurve.method != "Color" && imgsrc->isRGBSourceModified())
|| (!params->toneCurve.hrenabled && params->toneCurve.method == "Color" && imgsrc->isRGBSourceModified())) {
// || (params->toneCurve.hrenabled && params->toneCurve.method != "Color" && imgsrc->isRGBSourceModified())
// || (!params->toneCurve.hrenabled && params->toneCurve.method == "Color" && imgsrc->isRGBSourceModified())) {
|| (params->toneCurve.hrenabled && !iscolor && imgsrc->isRGBSourceModified())
|| (!params->toneCurve.hrenabled && iscolor && imgsrc->isRGBSourceModified())) {
if (highDetailNeeded) {
highDetailRawComputed = true;
} else {
@ -510,8 +514,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
}
if (todo & (M_INIT | M_LINDENOISE | M_HDR)) {
MyMutex::MyLock initLock(minit); // Also used in crop window
imgsrc->HLRecovery_Global(params->toneCurve); // this handles Color HLRecovery
// imgsrc->HLRecovery_Global(params->toneCurve); // this handles Color HLRecovery
if (settings->verbose) {
@ -538,7 +541,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
printf("tempref=%f greref=%f\n", tempref, greenref);
}
imgsrc->getAutoWBMultipliersitc(tempref, greenref, tempitc, greenitc, studgood, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params->wb, params->icm, params->raw);
imgsrc->getAutoWBMultipliersitc(tempref, greenref, tempitc, greenitc, studgood, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params->wb, params->icm, params->raw, params->toneCurve);
if (params->wb.method == "autitcgreen") {
params->wb.temperature = tempitc;
@ -617,8 +620,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
PreviewProps pp(0, 0, fw, fh, scale);
// Tells to the ImProcFunctions' tools what is the preview scale, which may lead to some simplifications
ipf.setScale(scale);
imgsrc->getImage(currWB, tr, orig_prev, pp, params->toneCurve, params->raw);
int inpaintopposed = 1;//force getimage to use inpaint-opposed if enable, only once
imgsrc->getImage(currWB, tr, orig_prev, pp, params->toneCurve, params->raw, inpaintopposed);
if ((todo & M_SPOT) && params->spot.enabled && !params->spot.entries.empty()) {
spotsDone = true;
@ -2462,7 +2465,7 @@ bool ImProcCoordinator::getAutoWB(double& temp, double& green, double equal, dou
double greenitc = 1.;
float studgood = 1000.f;
double tempref, greenref;
imgsrc->getAutoWBMultipliersitc(tempref, greenref, tempitc, greenitc, studgood, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params->wb, params->icm, params->raw);
imgsrc->getAutoWBMultipliersitc(tempref, greenref, tempitc, greenitc, studgood, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params->wb, params->icm, params->raw, params->toneCurve);
if (rm != -1) {
autoWB.update(rm, gm, bm, equal, tempBias);
@ -2649,7 +2652,7 @@ void ImProcCoordinator::saveInputICCReference(const Glib::ustring& fname, bool a
currWB = ColorTemp(); // = no white balance
}
imgsrc->getImage(currWB, tr, im, pp, ppar.toneCurve, ppar.raw);
imgsrc->getImage(currWB, tr, im, pp, ppar.toneCurve, ppar.raw, 0);
ImProcFunctions ipf(&ppar, true);
if (ipf.needsTransform(fW, fH, imgsrc->getRotateDegree(), imgsrc->getMetaData())) {

View File

@ -2128,7 +2128,7 @@ void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg,
Imagefloat img(int(fw / SCALE + 0.5), int(fh / SCALE + 0.5));
const ProcParams neutral;
imgsrc->getImage(imgsrc->getWB(), TR_NONE, &img, pp, params->toneCurve, neutral.raw);
imgsrc->getImage(imgsrc->getWB(), TR_NONE, &img, pp, params->toneCurve, neutral.raw, 0);
imgsrc->convertColorSpace(&img, params->icm, imgsrc->getWB());
float minVal = RT_INFINITY;
float maxVal = -RT_INFINITY;

275
rtengine/linalgebra.h Normal file
View File

@ -0,0 +1,275 @@
/* -*- C++ -*-
* This file is part of ART
*
* Copyright (c) 2022 Alberto Griggio
*
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <cmath>
namespace rtengine {
template <class T>
class Vec3 {
public:
Vec3() { data_[0] = data_[1] = data_[2] = T(); }
Vec3(T a, T b, T c) { data_[0] = a; data_[1] = b; data_[2] = c; }
template <class T2>
Vec3(T2 const a[3]) { data_[0] = a[0]; data_[1] = a[1]; data_[2] = a[2]; }
Vec3 &operator=(const Vec3 &a) = default;
template <class T2>
Vec3 &operator=(T2 const a[3])
{
data_[0] = a[0]; data_[1] = a[1]; data_[2] = a[2];
return *this;
}
T operator[](int i) const { return data_[i]; }
T &operator[](int i) { return data_[i]; }
operator const T *() const { return data_; }
operator T *() { return data_; }
private:
T data_[3];
};
typedef Vec3<float> Vec3f;
template <class T>
class Mat33 {
public:
Mat33()
{
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
data_[i][j] = T();
}
}
}
Mat33(T a00, T a01, T a02,
T a10, T a11, T a12,
T a20, T a21, T a22)
{
data_[0][0] = a00; data_[0][1] = a01; data_[0][2] = a02;
data_[1][0] = a10; data_[1][1] = a11; data_[1][2] = a12;
data_[2][0] = a20; data_[2][1] = a21; data_[2][2] = a22;
}
template <class T2>
Mat33(const T2 m[3][3])
{
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
data_[i][j] = m[i][j];
}
}
}
Mat33 &operator=(const Mat33 &m) = default;
template <class T2>
Mat33 &operator=(const T2 m[3][3])
{
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
data_[i][j] = m[i][j];
}
}
return *this;
}
T const *operator[](int i) const { return data_[i]; }
T *operator[](int i) { return data_[i]; }
typedef const T(*Data)[3];
operator Data() const { return data_; }
private:
T data_[3][3];
};
typedef Mat33<float> Mat33f;
template <class T>
Mat33<T> identity()
{
return Mat33<T>(1, 0, 0, 0, 1, 0, 0, 0, 1);
}
template <class T>
Mat33<T> diagonal(T a, T b, T c)
{
return Mat33<T>(a, 0, 0, 0, b, 0, 0, 0, c);
}
template <class T>
Mat33<T> transpose(T const m[3][3])
{
return Mat33<T>(m[0][0], m[1][0], m[2][0],
m[0][1], m[1][1], m[2][1],
m[0][2], m[1][2], m[2][2]);
}
template <class T>
Mat33<T> transpose(const Mat33<T> &m)
{
return transpose(static_cast<typename Mat33<T>::Data>(m));
}
template <class T>
bool inverse(T const m[3][3], Mat33<T> &out)
{
const T res00 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
const T res10 = m[2][0] * m[1][2] - m[1][0] * m[2][2];
const T res20 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
const T det = m[0][0] * res00 + m[0][1] * res10 + m[0][2] * res20;
if (std::abs(det) >= 1.0e-10) {
out[0][0] = res00 / det;
out[0][1] = (m[2][1] * m[0][2] - m[0][1] * m[2][2]) / det;
out[0][2] = (m[0][1] * m[1][2] - m[1][1] * m[0][2]) / det;
out[1][0] = res10 / det;
out[1][1] = (m[0][0] * m[2][2] - m[2][0] * m[0][2]) / det;
out[1][2] = (m[1][0] * m[0][2] - m[0][0] * m[1][2]) / det;
out[2][0] = res20 / det;
out[2][1] = (m[2][0] * m[0][1] - m[0][0] * m[2][1]) / det;
out[2][2] = (m[0][0] * m[1][1] - m[1][0] * m[0][1]) / det;
return true;
} else {
return false;
}
}
template <class T>
Mat33<T> inverse(const Mat33<T> &m)
{
Mat33<T> res;
inverse(static_cast<typename Mat33<T>::Data>(m), res);
return res;
}
template <class T>
Mat33<T> inverse(T const m[3][3])
{
Mat33<T> res;
inverse(m, res);
return res;
}
template <class T>
bool inverse(const Mat33<T> &m, Mat33<T> &out)
{
return inverse(static_cast<typename Mat33<T>::Data>(m), out);
}
template <class T>
Mat33<T> dot_product(T const a[3][3], T const b[3][3])
{
Mat33<T> res;
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
res[i][j] = 0;
for (int k = 0; k < 3; ++k) {
res[i][j] += a[i][k] * b[k][j];
}
}
}
return res;
}
template <class T>
Mat33<T> dot_product(const Mat33<T> &a, T const b[3][3])
{
return dot_product(static_cast<typename Mat33<T>::Data>(a), b);
}
template <class T>
Mat33<T> dot_product(T const a[3][3], const Mat33<T> &b)
{
return dot_product(a, static_cast<typename Mat33<T>::Data>(b));
}
template <class T>
Mat33<T> dot_product(const Mat33<T> &a, const Mat33<T> &b)
{
return dot_product(static_cast<typename Mat33<T>::Data>(a), static_cast<typename Mat33<T>::Data>(b));
}
template <class T>
Vec3<T> dot_product(T const a[3][3], T const b[3])
{
Vec3<T> res;
for (int i = 0; i < 3; ++i) {
res[i] = 0;
for (int k = 0; k < 3; ++k) {
res[i] += a[i][k] * b[k];
}
}
return res;
}
template <class T>
Vec3<T> dot_product(const Mat33<T> &a, T const b[3])
{
return dot_product(static_cast<typename Mat33<T>::Data>(a), b);
}
template <class T>
Vec3<T> dot_product(T const a[3][3], const Vec3<T> &b)
{
return dot_product(a, static_cast<T const *>(b));
}
template <class T>
Vec3<T> dot_product(const Mat33<T> &a, const Vec3<T> &b)
{
return dot_product(static_cast<typename Mat33<T>::Data>(a), static_cast<T const *>(b));
}
template <class T>
Mat33<T> operator*(const Mat33<T> &m, T v)
{
return Mat33<T>(m[0][0] * v, m[0][1] * v, m[0][2] * v,
m[1][0] * v, m[1][1] * v, m[1][2] * v,
m[2][0] * v, m[2][1] * v, m[2][2] * v);
}
template <class T>
Vec3<T> operator*(const Vec3<T> &a, T v)
{
return Vec3<T>(a[0] * v, a[1] * v, a[2] * v);
}
} // namespace rtengine

View File

@ -297,7 +297,7 @@ PerspectiveCorrection::Params PerspectiveCorrection::autocompute(ImageSource *sr
neutral.raw.bayersensor.method = RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::FAST);
neutral.raw.xtranssensor.method = RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FAST);
neutral.icm.outputProfile = ColorManagementParams::NoICMString;
src->getImage(src->getWB(), tr, img.get(), pp, neutral.toneCurve, neutral.raw);
src->getImage(src->getWB(), tr, img.get(), pp, neutral.toneCurve, neutral.raw, 0);
src->convertColorSpace(img.get(), pparams->icm, src->getWB());
neutral.commonTrans.autofill = false; // Ensures crop factor is correct.

View File

@ -121,7 +121,7 @@ PreviewImage::PreviewImage (const Glib::ustring &fname, const Glib::ustring &ext
double contrastThresholdDummy = 0.0;
rawImage.demosaic(params.raw, false, contrastThresholdDummy);
Imagefloat image(fw, fh);
rawImage.getImage (wb, TR_NONE, &image, pp, params.toneCurve, params.raw);
rawImage.getImage (wb, TR_NONE, &image, pp, params.toneCurve, params.raw, 0);
rtengine::Image8 output(fw, fh);
rawImage.convertColorSpace(&image, params.icm, wb);
#ifdef _OPENMP

View File

@ -373,7 +373,7 @@ ToneCurveParams::ToneCurveParams() :
autoexp(false),
clip(0.02),
hrenabled(false),
method("Blend"),
method("Coloropp"),
expcomp(0),
curve{
DCT_Linear
@ -390,6 +390,7 @@ ToneCurveParams::ToneCurveParams() :
shcompr(50),
hlcompr(0),
hlbl(0),
hlth(1.0),
hlcomprthresh(0),
histmatching(false),
fromHistMatching(false),
@ -416,6 +417,7 @@ bool ToneCurveParams::isPanningRelatedChange(const ToneCurveParams& other) const
&& shcompr == other.shcompr
&& hlcompr == other.hlcompr
&& hlbl == other.hlbl
&& hlth == other.hlth
&& hlcomprthresh == other.hlcomprthresh
&& histmatching == other.histmatching
&& clampOOG == other.clampOOG);
@ -440,6 +442,7 @@ bool ToneCurveParams::operator ==(const ToneCurveParams& other) const
&& shcompr == other.shcompr
&& hlcompr == other.hlcompr
&& hlbl == other.hlbl
&& hlth == other.hlth
&& hlcomprthresh == other.hlcomprthresh
&& histmatching == other.histmatching
&& fromHistMatching == other.fromHistMatching
@ -5912,6 +5915,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
saveToKeyfile(!pedited || pedited->toneCurve.hrenabled, "HLRecovery", "Enabled", toneCurve.hrenabled, keyFile);
saveToKeyfile(!pedited || pedited->toneCurve.method, "HLRecovery", "Method", toneCurve.method, keyFile);
saveToKeyfile(!pedited || pedited->toneCurve.hlbl, "HLRecovery", "Hlbl", toneCurve.hlbl, keyFile);
saveToKeyfile(!pedited || pedited->toneCurve.hlth, "HLRecovery", "Hlth", toneCurve.hlth, keyFile);
const std::map<ToneCurveMode, const char*> tc_mapping = {
{ToneCurveMode::STD, "Standard"},
@ -7697,6 +7701,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
assignFromKeyfile(keyFile, "HLRecovery", "Enabled", pedited, toneCurve.hrenabled, pedited->toneCurve.hrenabled);
assignFromKeyfile(keyFile, "HLRecovery", "Method", pedited, toneCurve.method, pedited->toneCurve.method);
assignFromKeyfile(keyFile, "HLRecovery", "Hlbl", pedited, toneCurve.hlbl, pedited->toneCurve.hlbl);
assignFromKeyfile(keyFile, "HLRecovery", "Hlth", pedited, toneCurve.hlth, pedited->toneCurve.hlth);
}
if (keyFile.has_group("Channel Mixer")) {

View File

@ -299,6 +299,7 @@ struct ToneCurveParams {
int shcompr;
int hlcompr; // Highlight Recovery's compression
int hlbl; // Highlight Recovery's compression
double hlth; // Highlight Recovery's threshold
int hlcomprthresh; // Highlight Recovery's threshold
bool histmatching; // histogram matching
bool fromHistMatching;

File diff suppressed because it is too large Load Diff

View File

@ -112,7 +112,7 @@ protected:
void hlRecovery(const std::string &method, float* red, float* green, float* blue, int width, float* hlmax);
void transformRect(const PreviewProps &pp, int tran, int &sx1, int &sy1, int &width, int &height, int &fw);
void transformPosition(int x, int y, int tran, int& tx, int& ty);
void ItcWB(bool extra, double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, array2D<float> &redloc, array2D<float> &greenloc, array2D<float> &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::WBParams & wbpar);
void ItcWB(bool extra, double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, array2D<float> &redloc, array2D<float> &greenloc, array2D<float> &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::WBParams & wbpar, const procparams::ToneCurveParams &hrp);
unsigned FC(int row, int col) const;
inline void getRowStartEnd (int x, int &start, int &end);
@ -141,12 +141,12 @@ public:
void processFlatField(const procparams::RAWParams &raw, const RawImage *riFlatFile, array2D<float> &rawData, const float black[4]);
void copyOriginalPixels(const procparams::RAWParams &raw, RawImage *ri, const RawImage *riDark, RawImage *riFlatFile, array2D<float> &rawData );
void scaleColors (int winx, int winy, int winw, int winh, const procparams::RAWParams &raw, array2D<float> &rawData); // raw for cblack
void WBauto(double &tempref, double &greenref, array2D<float> &redloc, array2D<float> &greenloc, array2D<float> &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, double &tempitc, double &greenitc, float &studgood, bool &twotimes, const procparams::WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw) override;
void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double &rm, double &gm, double &bm, const procparams::WBParams & wbpar, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw) override;
void WBauto(double &tempref, double &greenref, array2D<float> &redloc, array2D<float> &greenloc, array2D<float> &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, double &tempitc, double &greenitc, float &studgood, bool &twotimes, const procparams::WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::ToneCurveParams &hrp) override;
void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double &rm, double &gm, double &bm, const procparams::WBParams & wbpar, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::ToneCurveParams &hrp) override;
void getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w) override;
void getWBMults (const ColorTemp &ctemp, const procparams::RAWParams &raw, std::array<float, 4>& scale_mul, float &autoGainComp, float &rm, float &gm, float &bm) const override;
void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const procparams::ToneCurveParams &hrp, const procparams::RAWParams &raw) override;
void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const procparams::ToneCurveParams &hrp, const procparams::RAWParams &raw, int opposed) override;
eSensorType getSensorType () const override;
bool isMono () const override;
ColorTemp getWB () const override
@ -199,7 +199,8 @@ public:
void MSR(float** luminance, float **originalLuminance, float **exLuminance, const LUTf& mapcurve, bool mapcontlutili, int width, int height, const procparams::RetinexParams &deh, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax);
void HLRecovery_inpaint (float** red, float** green, float** blue, int blur);
static void HLRecovery_Luminance (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval);
void highlight_recovery_opposed(float scale_mul[3], const ColorTemp &wb, float gainth);
static void HLRecovery_Luminance (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval);
static void HLRecovery_CIELab (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval, double cam[3][3], double icam[3][3]);
static void HLRecovery_blend (float* rin, float* gin, float* bin, int width, float maxval, float* hlmax);
static void init ();
@ -308,6 +309,9 @@ protected:
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 applyDngGainMap(const float black[4], const std::vector<GainMap> &gainMaps);
public:
void wbMul2Camera(double &rm, double &gm, double &bm) override;
void wbCamera2Mul(double &rm, double &gm, double &bm) override;
};
}

View File

@ -94,7 +94,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
HDR, // EvCACorr,
ALLNORAW, // EvHREnabled,
0, // EvHRAmount : obsolete,
ALLNORAW, // EvHRMethod,
ALLNORAW|M_RAW, // EvHRMethod,
DEMOSAIC, // EvWProfile,
OUTPUTPROFILE, // EvOProfile,
ALLNORAW, // EvIProfile,

View File

@ -349,7 +349,7 @@ Image8 *load_inspector_mode(const Glib::ustring &fname, RawMetaDataLocation &rml
PreviewProps pp(0, 0, w, h, 1);
Imagefloat tmp(w, h);
src.getImage(src.getWB(), TR_NONE, &tmp, pp, neutral.toneCurve, neutral.raw);
src.getImage(src.getWB(), TR_NONE, &tmp, pp, neutral.toneCurve, neutral.raw, 0);
src.convertColorSpace(&tmp, neutral.icm, src.getWB());
Image8 *img = new Image8(w, h);

View File

@ -44,6 +44,7 @@ public:
bool monitorBPC; ///< Black Point Compensation for the Labimage->Monitor transform (directly, i.e. not soft-proofing and no WCS in between)
bool autoMonitorProfile; ///< Try to auto-determine the correct monitor color profile
bool autocielab;
bool observer10;
bool rgbcurveslumamode_gamut;// controls gamut enforcement for RGB curves in lumamode
bool verbose;
Glib::ustring darkFramesPath; ///< The default directory for dark frames
@ -94,7 +95,7 @@ public:
// bool showtooltip;
int itcwb_thres;
bool itcwb_sort;
bool itcwb_sorted;
int itcwb_greenrange;
int itcwb_greendeltatemp;
bool itcwb_forceextra;
@ -102,6 +103,7 @@ public:
int itcwb_delta;
bool itcwb_stdobserver10;
int itcwb_precis;
bool itcwb_nopurple;
//wavelet levels
double edghi;
double edglo;

View File

@ -261,7 +261,7 @@ private:
pl->setProgress(0.40);
}
imgsrc->HLRecovery_Global(params.toneCurve);
// imgsrc->HLRecovery_Global(params.toneCurve);
if (pl) {
@ -372,7 +372,7 @@ private:
int beg_tileW = wcr * tileWskip + tileWskip / 2.f - crW / 2.f;
int beg_tileH = hcr * tileHskip + tileHskip / 2.f - crH / 2.f;
PreviewProps ppP(beg_tileW, beg_tileH, crW, crH, skipP);
imgsrc->getImage(currWB, tr, origCropPart, ppP, params.toneCurve, params.raw);
imgsrc->getImage(currWB, tr, origCropPart, ppP, params.toneCurve, params.raw, 0);
//baseImg->getStdImage(currWB, tr, origCropPart, ppP, true, params.toneCurve);
// we only need image reduced to 1/4 here
@ -596,7 +596,7 @@ private:
for (int wcr = 0; wcr <= 2; wcr++) {
for (int hcr = 0; hcr <= 2; hcr++) {
PreviewProps ppP(coordW[wcr], coordH[hcr], crW, crH, 1);
imgsrc->getImage(currWB, tr, origCropPart, ppP, params.toneCurve, params.raw);
imgsrc->getImage(currWB, tr, origCropPart, ppP, params.toneCurve, params.raw, 0);
//baseImg->getStdImage(currWB, tr, origCropPart, ppP, true, params.toneCurve);
@ -756,7 +756,7 @@ private:
}
baseImg = new Imagefloat(fw, fh);
imgsrc->getImage(currWB, tr, baseImg, pp, params.toneCurve, params.raw);
imgsrc->getImage(currWB, tr, baseImg, pp, params.toneCurve, params.raw, 1);
if (pl) {
pl->setProgress(0.50);

View File

@ -459,7 +459,7 @@ void ImProcFunctions::removeSpots (Imagefloat* img, ImageSource* imgsrc, const s
}
}
imgsrc->getImage(currWB, tr, srcSpotBox->getImage(), spp, params->toneCurve, params->raw);
imgsrc->getImage(currWB, tr, srcSpotBox->getImage(), spp, params->toneCurve, params->raw, 0);
if (cmp) {
imgsrc->convertColorSpace(srcImage, *cmp, currWB);
}
@ -479,7 +479,7 @@ void ImProcFunctions::removeSpots (Imagefloat* img, ImageSource* imgsrc, const s
dstImage->b(y, x) = 60000.f;
}
}
imgsrc->getImage(currWB, tr, dstSpotBox->getImage(), spp, params->toneCurve, params->raw);
imgsrc->getImage(currWB, tr, dstSpotBox->getImage(), spp, params->toneCurve, params->raw, 0);
if (cmp) {
imgsrc->convertColorSpace(dstImage, *cmp, currWB);
}

View File

@ -193,7 +193,7 @@ int StdImageSource::load (const Glib::ustring &fname)
return 0;
}
void StdImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw)
void StdImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw, int opposed)
{
// the code will use OpenMP as of now.
@ -311,11 +311,11 @@ void StdImageSource::getAutoExpHistogram (LUTu & histogram, int& histcompr)
}
}
void StdImageSource::WBauto(double &tempref, double &greenref, array2D<float> &redloc, array2D<float> &greenloc, array2D<float> &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, double &tempitc, double &greenitc, float &studgood, bool &twotimes, const WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const ColorManagementParams &cmp, const RAWParams &raw)
void StdImageSource::WBauto(double &tempref, double &greenref, array2D<float> &redloc, array2D<float> &greenloc, array2D<float> &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, double &tempitc, double &greenitc, float &studgood, bool &twotimes, const WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const ColorManagementParams &cmp, const RAWParams &raw, const ToneCurveParams &hrp)
{
}
void StdImageSource::getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double &rm, double &gm, double &bm, const WBParams & wbpar, const ColorManagementParams &cmp, const RAWParams &raw)
void StdImageSource::getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double &rm, double &gm, double &bm, const WBParams & wbpar, const ColorManagementParams &cmp, const RAWParams &raw, const ToneCurveParams &hrp)
{
if (redAWBMul != -1.) {
rm = redAWBMul;
@ -324,7 +324,7 @@ void StdImageSource::getAutoWBMultipliersitc(double &tempref, double &greenref,
return;
}
img->getAutoWBMultipliersitc(tempref, greenref, tempitc, greenitc,studgood, begx, begy, yEn, xEn, cx, cy, bf_h, bf_w, rm, gm, bm, params->wb, params->icm, params->raw);
img->getAutoWBMultipliersitc(tempref, greenref, tempitc, greenitc,studgood, begx, begy, yEn, xEn, cx, cy, bf_h, bf_w, rm, gm, bm, params->wb, params->icm, params->raw, params->toneCurve);
redAWBMul = rm;
greenAWBMul = gm;
@ -367,6 +367,20 @@ void StdImageSource::flush() {
img->allocate(0, 0);
};
void StdImageSource::wbMul2Camera(double &rm, double &gm, double &bm)
{
rm = 1.0 / rm;
gm = 1.0 / gm;
bm = 1.0 / bm;
}
void StdImageSource::wbCamera2Mul(double &rm, double &gm, double &bm)
{
rm = 1.0 / rm;
gm = 1.0 / gm;
bm = 1.0 / bm;
}
}

View File

@ -58,7 +58,7 @@ public:
int load (const Glib::ustring &fname) override;
void getWBMults (const ColorTemp &ctemp, const procparams::RAWParams &raw, std::array<float, 4>& scale_mul, float &autoGainComp, float &rm, float &gm, float &bm) const override {};
void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const procparams::ToneCurveParams &hrp, const procparams::RAWParams &raw) override;
void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const procparams::ToneCurveParams &hrp, const procparams::RAWParams &raw, int opposed) override;
void getrgbloc (int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w) override {};
ColorTemp getWB () const override
{
@ -66,8 +66,8 @@ public:
}
void getAutoWBMultipliers (double &rm, double &gm, double &bm) override;
ColorTemp getSpotWB (std::vector<Coord2D> &red, std::vector<Coord2D> &green, std::vector<Coord2D> &blue, int tran, double equal) override;
void WBauto(double &tempref, double &greenref, array2D<float> &redloc, array2D<float> &greenloc, array2D<float> &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, double &tempitc, double &greenitc, float &studgood, bool &twotimes, const procparams::WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw) override;
void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double &rm, double &gm, double &bm, const procparams::WBParams & wbpar, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw) override;
void WBauto(double &tempref, double &greenref, array2D<float> &redloc, array2D<float> &greenloc, array2D<float> &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, double &tempitc, double &greenitc, float &studgood, bool &twotimes, const procparams::WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::ToneCurveParams &hrp) override;
void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double &rm, double &gm, double &bm, const procparams::WBParams & wbpar, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::ToneCurveParams &hrp) override;
eSensorType getSensorType() const override {return ST_NONE;}
bool isMono() const override {return false;}
@ -123,6 +123,8 @@ public:
void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override { R = G = B = 0;}
void wbMul2Camera(double &rm, double &gm, double &bm) override;
void wbCamera2Mul(double &rm, double &gm, double &bm) override;
void flush () override;
void captureSharpening(const procparams::CaptureSharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold, double &radius) override {};

View File

@ -594,6 +594,7 @@ void Options::setDefaults()
rtSettings.monitorIntent = rtengine::RI_RELATIVE;
rtSettings.monitorBPC = true;
rtSettings.autocielab = false;
rtSettings.observer10 = false;
rtSettings.autoMonitorProfile = false;
rtSettings.adobe = "RTv2_Medium"; // put the name of yours profiles (here windows)
rtSettings.prophoto = "RTv2_Large"; // these names appear in the menu "output profile"
@ -623,14 +624,15 @@ void Options::setDefaults()
rtSettings.fftwsigma = true; //choice between sigma^2 or empirical formula
rtSettings.itcwb_thres = 34;//between 10 to 55
rtSettings.itcwb_sort = false;
rtSettings.itcwb_sorted = true;
rtSettings.itcwb_greenrange = 0;//between 0 to 2
rtSettings.itcwb_greendeltatemp = 2;//between 0 and 4
rtSettings.itcwb_forceextra = true;
rtSettings.itcwb_sizereference = 3;//between 1 and 5
rtSettings.itcwb_delta = 1;//between 0 and 5
rtSettings.itcwb_stdobserver10 = true;
rtSettings.itcwb_precis = 5;//3 or 5 or 9
rtSettings.itcwb_precis = 3;//3 or 5 or 9
rtSettings.itcwb_nopurple = true;
// end locallab
//wavelet
@ -1760,6 +1762,10 @@ void Options::readFromFile(Glib::ustring fname)
rtSettings.autocielab = keyFile.get_boolean("Color Management", "Autocielab");
}
if (keyFile.has_key("Color Management", "Observer10")) {
rtSettings.observer10 = keyFile.get_boolean("Color Management", "Observer10");
}
if (keyFile.has_key("Color Management", "CRI")) {
rtSettings.CRI_color = keyFile.get_integer("Color Management", "CRI");
}
@ -1795,14 +1801,18 @@ void Options::readFromFile(Glib::ustring fname)
rtSettings.itcwb_thres = keyFile.get_integer("Color Management", "Itcwb_thres");
}
if (keyFile.has_key("Color Management", "Itcwb_sort")) {
rtSettings.itcwb_sort = keyFile.get_boolean("Color Management", "Itcwb_sort");
if (keyFile.has_key("Color Management", "Itcwb_sorted")) {
rtSettings.itcwb_sorted = keyFile.get_boolean("Color Management", "Itcwb_sorted");
}
if (keyFile.has_key("Color Management", "Itcwb_forceextra")) {
rtSettings.itcwb_forceextra = keyFile.get_boolean("Color Management", "Itcwb_forceextra");
}
if (keyFile.has_key("Color Management", "Itcwb_nopurple")) {
rtSettings.itcwb_nopurple = keyFile.get_boolean("Color Management", "Itcwb_nopurple");
}
if (keyFile.has_key("Color Management", "Itcwb_stdobserver10")) {
rtSettings.itcwb_stdobserver10 = keyFile.get_boolean("Color Management", "Itcwb_stdobserver10");
}
@ -2563,6 +2573,7 @@ void Options::saveToFile(Glib::ustring fname)
keyFile.set_string("Color Management", "MonitorProfile", rtSettings.monitorProfile);
keyFile.set_boolean("Color Management", "AutoMonitorProfile", rtSettings.autoMonitorProfile);
keyFile.set_boolean("Color Management", "Autocielab", rtSettings.autocielab);
keyFile.set_boolean("Color Management", "Observer10", rtSettings.observer10);
keyFile.set_boolean("Color Management", "RGBcurvesLumamode_Gamut", rtSettings.rgbcurveslumamode_gamut);
keyFile.set_integer("Color Management", "Intent", rtSettings.monitorIntent);
keyFile.set_boolean("Color Management", "MonitorBPC", rtSettings.monitorBPC);
@ -2596,10 +2607,11 @@ void Options::saveToFile(Glib::ustring fname)
keyFile.set_double("Color Management", "CBDLlevel0", rtSettings.level0_cbdl);
keyFile.set_double("Color Management", "CBDLlevel123", rtSettings.level123_cbdl);
keyFile.set_integer("Color Management", "Itcwb_thres", rtSettings.itcwb_thres);
keyFile.set_boolean("Color Management", "Itcwb_sort", rtSettings.itcwb_sort);
keyFile.set_boolean("Color Management", "Itcwb_sorted", rtSettings.itcwb_sorted);
keyFile.set_integer("Color Management", "Itcwb_greenrange", rtSettings.itcwb_greenrange);
keyFile.set_integer("Color Management", "Itcwb_greendeltatemp", rtSettings.itcwb_greendeltatemp);
keyFile.set_boolean("Color Management", "Itcwb_forceextra", rtSettings.itcwb_forceextra);
keyFile.set_boolean("Color Management", "Itcwb_nopurple", rtSettings.itcwb_nopurple);
keyFile.set_integer("Color Management", "Itcwb_sizereference", rtSettings.itcwb_sizereference);
keyFile.set_integer("Color Management", "Itcwb_delta", rtSettings.itcwb_delta);
keyFile.set_boolean("Color Management", "Itcwb_stdobserver10", rtSettings.itcwb_stdobserver10);

View File

@ -48,6 +48,7 @@ void ParamsEdited::set(bool v)
toneCurve.shcompr = v;
toneCurve.hlcompr = v;
toneCurve.hlbl = v;
toneCurve.hlth = v;
toneCurve.hlcomprthresh = v;
toneCurve.autoexp = v;
toneCurve.clip = v;
@ -749,6 +750,7 @@ void ParamsEdited::initFrom(const std::vector<rtengine::procparams::ProcParams>&
toneCurve.shcompr = toneCurve.shcompr && p.toneCurve.shcompr == other.toneCurve.shcompr;
toneCurve.hlcompr = toneCurve.hlcompr && p.toneCurve.hlcompr == other.toneCurve.hlcompr;
toneCurve.hlbl = toneCurve.hlbl && p.toneCurve.hlbl == other.toneCurve.hlbl;
toneCurve.hlth = toneCurve.hlth && p.toneCurve.hlth == other.toneCurve.hlth;
toneCurve.hlcomprthresh = toneCurve.hlcomprthresh && p.toneCurve.hlcomprthresh == other.toneCurve.hlcomprthresh;
toneCurve.autoexp = toneCurve.autoexp && p.toneCurve.autoexp == other.toneCurve.autoexp;
toneCurve.clip = toneCurve.clip && p.toneCurve.clip == other.toneCurve.clip;
@ -2192,6 +2194,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
toEdit.toneCurve.hlbl = mods.toneCurve.hlbl;
}
if (toneCurve.hlth) {
toEdit.toneCurve.hlth = mods.toneCurve.hlth;
}
if (toneCurve.histmatching) {
toEdit.toneCurve.histmatching = mods.toneCurve.histmatching;
}

View File

@ -52,6 +52,7 @@ struct ToneCurveParamsEdited {
bool shcompr;
bool hlcompr;
bool hlbl;
bool hlth;
bool hlcomprthresh;
bool autoexp;
bool clip;

View File

@ -42,6 +42,7 @@ ToneCurve::ToneCurve() : FoldableToolPanel(this, TOOL_NAME, M("TP_EXPOSURE_LABEL
EvHistMatchingBatch = m->newEvent(M_VOID, "HISTORY_MSG_HISTMATCHING");
EvClampOOG = m->newEvent(DARKFRAME, "HISTORY_MSG_CLAMPOOG");
EvHLbl = m->newEvent(DEMOSAIC, "HISTORY_MSG_HLBL");
EvHLth = m->newEvent(DEMOSAIC, "HISTORY_MSG_HLTH");
CurveListener::setMulti(true);
@ -97,13 +98,14 @@ ToneCurve::ToneCurve() : FoldableToolPanel(this, TOOL_NAME, M("TP_EXPOSURE_LABEL
method = Gtk::manage (new MyComboBoxText ());
method->append (M("TP_HLREC_LUMINANCE"));
method->append (M("TP_HLREC_CIELAB"));
method->append (M("TP_HLREC_COLOR"));
method->append (M("TP_HLREC_BLEND"));
method->append (M("TP_HLREC_COLOR"));
method->append (M("TP_HLREC_COLOROPP"));
Gtk::Box *hrVBox;
hrVBox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL));
hrVBox->set_spacing(2);
method->set_active(0);
method->set_active(4);
Gtk::Frame* const hrFrame = Gtk::manage(new Gtk::Frame());
hrFrame->set_label_align(0.025, 0.5);
hrFrame->set_label_widget(*hrenabled);
@ -113,9 +115,11 @@ ToneCurve::ToneCurve() : FoldableToolPanel(this, TOOL_NAME, M("TP_EXPOSURE_LABEL
hlrbox->pack_start (*lab, Gtk::PACK_SHRINK);
hlrbox->pack_start (*method);
hlbl = Gtk::manage(new Adjuster(M("TP_HLREC_HLBLUR"), 0, 4, 1, 0));
hlth = Gtk::manage(new Adjuster(M("TP_HLREC_HLTH"), 0.25, 1.75, 0.01, 1.));
hrVBox->pack_start(*hlrbox, Gtk::PACK_SHRINK);
hrVBox->pack_start(*hlbl);
hrVBox->pack_start(*hlth);
hrFrame->add(*hrVBox);
pack_start(*hrFrame);
@ -223,6 +227,7 @@ ToneCurve::ToneCurve() : FoldableToolPanel(this, TOOL_NAME, M("TP_EXPOSURE_LABEL
black->setAdjusterListener(this);
hlcompr->setAdjusterListener(this);
hlbl->setAdjusterListener(this);
hlth->setAdjusterListener(this);
hlcomprthresh->setAdjusterListener(this);
shcompr->setAdjusterListener(this);
contrast->setAdjusterListener(this);
@ -254,6 +259,7 @@ void ToneCurve::read(const ProcParams* pp, const ParamsEdited* pedited)
black->setValue(pp->toneCurve.black);
hlcompr->setValue(pp->toneCurve.hlcompr);
hlbl->setValue(pp->toneCurve.hlbl);
hlth->setValue(pp->toneCurve.hlth);
hlcomprthresh->setValue(pp->toneCurve.hlcomprthresh);
shcompr->setValue(pp->toneCurve.shcompr);
@ -283,6 +289,7 @@ void ToneCurve::read(const ProcParams* pp, const ParamsEdited* pedited)
black->setEditedState(pedited->toneCurve.black ? Edited : UnEdited);
hlcompr->setEditedState(pedited->toneCurve.hlcompr ? Edited : UnEdited);
hlbl->setEditedState(pedited->toneCurve.hlbl ? Edited : UnEdited);
hlth->setEditedState(pedited->toneCurve.hlth ? Edited : UnEdited);
hlcomprthresh->setEditedState(pedited->toneCurve.hlcomprthresh ? Edited : UnEdited);
shcompr->setEditedState(pedited->toneCurve.shcompr ? Edited : UnEdited);
brightness->setEditedState(pedited->toneCurve.brightness ? Edited : UnEdited);
@ -310,16 +317,18 @@ void ToneCurve::read(const ProcParams* pp, const ParamsEdited* pedited)
hrenabled->set_active(pp->toneCurve.hrenabled);
enaconn.block(false);
if (pedited && !pedited->toneCurve.method) {
method->set_active(4);
} else if (pp->toneCurve.method == "Luminance") {
if (pedited && !pedited->toneCurve.method) {
method->set_active(5);
} else if (pp->toneCurve.method == "Luminance") {
method->set_active(0);
} else if (pp->toneCurve.method == "CIELab blending") {
method->set_active(1);
} else if (pp->toneCurve.method == "Color") {
method->set_active(2);
} else if (pp->toneCurve.method == "Blend") {
method->set_active(2);
} else if (pp->toneCurve.method == "Color") {
method->set_active(3);
} else if (pp->toneCurve.method == "Coloropp") {
method->set_active(4);
}
hrenabledChanged();
@ -354,6 +363,7 @@ void ToneCurve::write(ProcParams* pp, ParamsEdited* pedited)
pp->toneCurve.black = black->getValue();
pp->toneCurve.hlcompr = hlcompr->getValue();
pp->toneCurve.hlbl = hlbl->getValue();
pp->toneCurve.hlth = hlth->getValue();
pp->toneCurve.hlcomprthresh = hlcomprthresh->getValue();
pp->toneCurve.shcompr = shcompr->getValue();
pp->toneCurve.brightness = brightness->getValue();
@ -403,6 +413,7 @@ void ToneCurve::write(ProcParams* pp, ParamsEdited* pedited)
pedited->toneCurve.black = black->getEditedState();
pedited->toneCurve.hlcompr = hlcompr->getEditedState();
pedited->toneCurve.hlbl = hlbl->getEditedState();
pedited->toneCurve.hlth = hlth->getEditedState();
pedited->toneCurve.hlcomprthresh = hlcomprthresh->getEditedState();
pedited->toneCurve.shcompr = shcompr->getEditedState();
pedited->toneCurve.brightness = brightness->getEditedState();
@ -414,7 +425,7 @@ void ToneCurve::write(ProcParams* pp, ParamsEdited* pedited)
pedited->toneCurve.curve2 = !shape2->isUnChanged();
pedited->toneCurve.curveMode = toneCurveMode->get_active_row_number() != 6;
pedited->toneCurve.curveMode2 = toneCurveMode2->get_active_row_number() != 6;
pedited->toneCurve.method = method->get_active_row_number() != 4;
pedited->toneCurve.method = method->get_active_row_number() != 5;
pedited->toneCurve.hrenabled = !hrenabled->get_inconsistent();
pedited->toneCurve.histmatching = !histmatching->get_inconsistent();
pedited->toneCurve.fromHistMatching = true;
@ -428,9 +439,11 @@ void ToneCurve::write(ProcParams* pp, ParamsEdited* pedited)
} else if (method->get_active_row_number() == 1) {
pp->toneCurve.method = "CIELab blending";
} else if (method->get_active_row_number() == 2) {
pp->toneCurve.method = "Color";
} else if (method->get_active_row_number() == 3) {
pp->toneCurve.method = "Blend";
} else if (method->get_active_row_number() == 3) {
pp->toneCurve.method = "Color";
} else if (method->get_active_row_number() == 4) {
pp->toneCurve.method = "Coloropp";
}
}
@ -454,15 +467,21 @@ void ToneCurve::hrenabledChanged()
if (hrenabled->get_active()) {
hlrbox->show();
hlrbox->set_sensitive(true);
if (method->get_active_row_number() == 2) {
if (method->get_active_row_number() == 3) {
hlbl->show();
hlth->hide();
} else if (method->get_active_row_number() == 4){
hlbl->hide();
hlth->show();
} else {
hlbl->hide();
}
hlth->hide();
}
} else {
hlrbox->show();
hlrbox->set_sensitive(false);
hlbl->hide();
hlth->hide();
}
}
@ -487,11 +506,16 @@ void ToneCurve::hrenabledChanged()
void ToneCurve::methodChanged()
{
if (method->get_active_row_number() == 2) {
if (method->get_active_row_number() == 3) {
hlbl->show();
hlth->hide();
} else if (method->get_active_row_number() == 4){
hlbl->hide();
hlth->show();
} else {
hlbl->hide();
}
hlth->hide();
}
if (listener) {
setHistmatching(false);
if (hrenabled->get_active()) {
@ -513,6 +537,7 @@ void ToneCurve::setRaw(bool raw)
disableListener();
method->set_sensitive(raw);
hlbl->set_sensitive(raw);
hlth->set_sensitive(raw);
hrenabled->set_sensitive(raw);
histmatching->set_sensitive(raw);
enableListener();
@ -526,6 +551,7 @@ void ToneCurve::setDefaults(const ProcParams* defParams, const ParamsEdited* ped
black->setDefault(defParams->toneCurve.black);
hlcompr->setDefault(defParams->toneCurve.hlcompr);
hlbl->setDefault(defParams->toneCurve.hlbl);
hlth->setDefault(defParams->toneCurve.hlth);
hlcomprthresh->setDefault(defParams->toneCurve.hlcomprthresh);
shcompr->setDefault(defParams->toneCurve.shcompr);
contrast->setDefault(defParams->toneCurve.contrast);
@ -536,6 +562,7 @@ void ToneCurve::setDefaults(const ProcParams* defParams, const ParamsEdited* ped
black->setDefaultEditedState(pedited->toneCurve.black ? Edited : UnEdited);
hlcompr->setDefaultEditedState(pedited->toneCurve.hlcompr ? Edited : UnEdited);
hlbl->setDefaultEditedState(pedited->toneCurve.hlbl ? Edited : UnEdited);
hlth->setDefaultEditedState(pedited->toneCurve.hlth ? Edited : UnEdited);
hlcomprthresh->setDefaultEditedState(pedited->toneCurve.hlcomprthresh ? Edited : UnEdited);
shcompr->setDefaultEditedState(pedited->toneCurve.shcompr ? Edited : UnEdited);
brightness->setDefaultEditedState(pedited->toneCurve.brightness ? Edited : UnEdited);
@ -546,6 +573,7 @@ void ToneCurve::setDefaults(const ProcParams* defParams, const ParamsEdited* ped
black->setDefaultEditedState(Irrelevant);
hlcompr->setDefaultEditedState(Irrelevant);
hlbl->setDefaultEditedState(Irrelevant);
hlth->setDefaultEditedState(Irrelevant);
hlcomprthresh->setDefaultEditedState(Irrelevant);
shcompr->setDefaultEditedState(Irrelevant);
brightness->setDefaultEditedState(Irrelevant);
@ -660,6 +688,8 @@ void ToneCurve::adjusterChanged(Adjuster* a, double newval)
listener->panelChanged(EvSaturation, costr);
} else if (a == hlbl) {
listener->panelChanged(EvHLbl, costr);
} else if (a == hlth) {
listener->panelChanged(EvHLth, costr);
} else if (a == hlcompr) {
listener->panelChanged(EvHLCompr, costr);
@ -695,6 +725,7 @@ void ToneCurve::neutral_pressed()
expcomp->setValue(0);
hlcompr->setValue(0);
hlbl->setValue(0);
hlth->setValue(1.0);
hlcomprthresh->setValue(0);
brightness->setValue(0);
black->setValue(0);
@ -707,6 +738,7 @@ void ToneCurve::neutral_pressed()
hlrbox->show();
hlrbox->set_sensitive(false);
hlbl->hide();
hlth->hide();
}
if (!black->getAddMode() && !batchMode) {
@ -841,6 +873,7 @@ void ToneCurve::waitForAutoExp()
hrenabled->set_sensitive(false);
method->set_sensitive(false);
hlbl->set_sensitive(false);
hlth->set_sensitive(false);
histmatching->set_sensitive(false);
}
@ -853,6 +886,7 @@ void ToneCurve::enableAll()
black->setEnabled(true);
hlcompr->setEnabled(true);
hlbl->setEnabled(true);
hlth->setEnabled(true);
hlcomprthresh->setEnabled(true);
shcompr->setEnabled(true);
contrast->setEnabled(true);
@ -864,6 +898,7 @@ void ToneCurve::enableAll()
hrenabled->set_sensitive(true);
method->set_sensitive(true);
hlbl->set_sensitive(true);
hlth->set_sensitive(true);
histmatching->set_sensitive(true);
}
@ -883,6 +918,7 @@ void ToneCurve::setBatchMode(bool batchMode)
black->showEditedCB();
hlcompr->showEditedCB();
hlbl->showEditedCB();
hlth->showEditedCB();
hlcomprthresh->showEditedCB();
shcompr->showEditedCB();
brightness->showEditedCB();
@ -996,16 +1032,22 @@ void ToneCurve::autoExpChanged(double expcomp, int bright, int contr, int black,
if (nextHLRecons) {
hlrbox->show();
hlrbox->set_sensitive(true);
if (method->get_active_row_number() == 2) {
if (method->get_active_row_number() == 3) {
hlbl->show();
} else {
hlth->hide();
} else if (method->get_active_row_number() == 4){
hlbl->hide();
}
hlth->show();
} else {
hlbl->hide();
hlth->hide();
}
} else if (!batchMode) {
hlrbox->show();
hlrbox->set_sensitive(false);
hlbl->hide();
}
hlth->hide();
}
if (!this->black->getAddMode() && !batchMode) {
shcompr->set_sensitive(static_cast<int>(this->black->getValue())); //at black=0 shcompr value has no effect

View File

@ -48,6 +48,7 @@ protected:
sigc::connection enaconn;
bool lasthrEnabled;
Adjuster* hlbl;
Adjuster* hlth;
Gtk::Box* abox;
Gtk::Box* hlrbox;
@ -82,6 +83,7 @@ protected:
rtengine::ProcEvent EvHistMatchingBatch;
rtengine::ProcEvent EvClampOOG;
rtengine::ProcEvent EvHLbl;
rtengine::ProcEvent EvHLth;
// used temporarily in eventing
double nextExpcomp;