Some fixes suggested by @Floessie

This commit is contained in:
Ingo Weyrich 2020-07-16 11:35:41 +02:00
parent 4395a1a0b1
commit 6caf33a589
8 changed files with 33 additions and 115 deletions

View File

@ -1282,7 +1282,7 @@ void Color::computeBWMixerConstants (const Glib::ustring &setting, const Glib::u
koymcp += (prM + pgM + pbM); koymcp += (prM + pgM + pbM);
} }
if(mixerCyan != 33.f) { if (mixerCyan != 33.f) {
float cgM = 0.f; float cgM = 0.f;
if (algo == "SP") { if (algo == "SP") {
cgM = fcompl * (-0.134f * mixerCyan + 4.422f) / 100.f; cgM = fcompl * (-0.134f * mixerCyan + 4.422f) / 100.f;
@ -1460,7 +1460,7 @@ void Color::interpolateRGBColor (float realL, float iplow, float iphigh, int alg
const float xl, const float yl, const float zl, const float x2, const float y2, const float z2, const float xl, const float yl, const float zl, const float x2, const float y2, const float z2,
const double xyz_rgb[3][3], const double rgb_xyz[3][3], float &ro, float &go, float &bo) const double xyz_rgb[3][3], const double rgb_xyz[3][3], float &ro, float &go, float &bo)
{ {
float L1 = 0.f, a_1 = 0.f, b_1 = 0.f, a_2 = 0.f, b_2 = 0.f, a_L, b_L; float L1 = 0.f, a_1 = 0.f, b_1 = 0.f, a_2 = 0.f, b_2 = 0.f, a_L = 0.f, b_L = 0.f;
if (algm == 1) {//use H interpolate if (algm == 1) {//use H interpolate
// converting color 1 to Lab (image) // converting color 1 to Lab (image)
@ -1529,10 +1529,10 @@ void Color::interpolateRGBColor (float realL, float iplow, float iphigh, int alg
Color::xyz2rgb(X, Y, Z, ro, go, bo, rgb_xyz);// ro go bo in gamut Color::xyz2rgb(X, Y, Z, ro, go, bo, rgb_xyz);// ro go bo in gamut
} }
void Color::calcGamma (double pwr, double ts, int mode, GammaValues &gamma) void Color::calcGamma (double pwr, double ts, GammaValues &gamma)
{ {
//from Dcraw (D.Coffin) //from Dcraw (D.Coffin)
double g[6], bnd[2] = {0., 0.}; double g[6], bnd[2] = {};
g[0] = pwr; g[0] = pwr;
g[1] = ts; g[1] = ts;
@ -1563,7 +1563,6 @@ void Color::calcGamma (double pwr, double ts, int mode, GammaValues &gamma)
g[5] = 1. / (g[1] * SQR(g[3]) / 2. + 1. - g[2] - g[3] - g[2] * g[3] * (log(g[3]) - 1.)) - 1.; g[5] = 1. / (g[1] * SQR(g[3]) / 2. + 1. - g[2] - g[3] - g[2] * g[3] * (log(g[3]) - 1.)) - 1.;
} }
if (!mode) {
gamma[0] = g[0]; gamma[0] = g[0];
gamma[1] = g[1]; gamma[1] = g[1];
gamma[2] = g[2]; gamma[2] = g[2];
@ -1571,8 +1570,6 @@ void Color::calcGamma (double pwr, double ts, int mode, GammaValues &gamma)
gamma[4] = g[4]; gamma[4] = g[4];
gamma[5] = g[5]; gamma[5] = g[5];
gamma[6] = 0.; gamma[6] = 0.;
return;
}
} }
void Color::gammaf2lut (LUTf &gammacurve, float gamma, float start, float slope, float divisor, float factor) void Color::gammaf2lut (LUTf &gammacurve, float gamma, float start, float slope, float divisor, float factor)
{ {
@ -2018,91 +2015,28 @@ void Color::gamutmap(float &X, float Y, float &Z, const double p[3][3])
Z = (12 - 3 * u - 20 * v) * Y / (4 * v); Z = (12 - 3 * u - 20 * v) * Y / (4 * v);
} }
void Color::skinred ( double J, double h, double sres, double Sp, float dred, float protect_red, int sk, float rstprotection, float ko, double &s)
{
float HH;
bool doskin = false;
//rough correspondence between h (JC) and H (lab) that has relatively little importance because transitions that blur the correspondence is not linear
if ((float)h > 8.6f && (float)h <= 74.f ) {
HH = (1.15f / 65.4f) * (float)h - 0.0012f; //H > 0.15 H<1.3
doskin = true;
} else if((float)h > 0.f && (float)h <= 8.6f ) {
HH = (0.19f / 8.6f ) * (float)h - 0.04f; //H>-0.04 H < 0.15
doskin = true;
} else if((float)h > 355.f && (float)h <= 360.f) {
HH = (0.11f / 5.0f ) * (float)h - 7.96f; //H>-0.15 <-0.04
doskin = true;
} else if((float)h > 74.f && (float)h < 95.f ) {
HH = (0.30f / 21.0f) * (float)h + 0.24285f; //H>1.3 H<1.6
doskin = true;
}
if(doskin) {
float scale = 100.0f / 100.1f; //reduction in normal zone
float scaleext = 1.0f; //reduction in transition zone
float factorskin;
float chromapro = sres / Sp;
if(sk == 1) { //in C mode to adapt dred to J
if (J < 16.0) {
dred = 40.0f;
} else if(J < 22.0) {
dred = 2.5f * (float)J;
} else if(J < 60.0) {
dred = 55.0f;
} else if(J < 70.0) {
dred = -1.5f * (float)J + 145.0f;
} else {
dred = 40.0f;
}
}
constexpr float deltaHH = 0.3f; //HH value transition : I have choice 0.3 radians
if(chromapro > 0.f) {
Color::scalered ( rstprotection, chromapro, 0.0, HH, deltaHH, scale, scaleext); //Scale factor
}
float factorskinext;
if(chromapro > 1.f) {
const float interm = (chromapro - 1.0f) * 100.0f;
factorskin = 1.0f + (interm * scale) / 100.0f;
factorskinext = 1.0f + (interm * scaleext) / 100.0f;
} else {
factorskin = chromapro ;
factorskinext = chromapro ;
}
float factor = chromapro;
Color::transitred ( HH, s, dred, factorskin, protect_red, factorskinext, deltaHH, chromapro, factor); //transition
s *= factor;
} else {
s = ko * sres;
}
}
void Color::skinredfloat ( float J, float h, float sres, float Sp, float dred, float protect_red, int sk, float rstprotection, float ko, float &s) void Color::skinredfloat ( float J, float h, float sres, float Sp, float dred, float protect_red, int sk, float rstprotection, float ko, float &s)
{ {
float HH; float HH;
bool doskin = false; bool doskin = false;
//rough correspondence between h (JC) and H (lab) that has relatively little importance because transitions that blur the correspondence is not linear //rough correspondence between h (JC) and H (lab) that has relatively little importance because transitions that blur the correspondence is not linear
if ((float)h > 8.6f && (float)h <= 74.f ) { if (h > 8.6f && h <= 74.f) {
HH = (1.15f / 65.4f) * (float)h - 0.0012f; //H > 0.15 H<1.3 HH = (1.15f / 65.4f) * h - 0.0012f; //H > 0.15 H<1.3
doskin = true; doskin = true;
} else if((float)h > 0.f && (float)h <= 8.6f ) { } else if(h > 0.f && h <= 8.6f) {
HH = (0.19f / 8.6f ) * (float)h - 0.04f; //H>-0.04 H < 0.15 HH = (0.19f / 8.6f) * h - 0.04f; //H>-0.04 H < 0.15
doskin = true; doskin = true;
} else if((float)h > 355.f && (float)h <= 360.f) { } else if(h > 355.f && h <= 360.f) {
HH = (0.11f / 5.0f ) * (float)h - 7.96f; //H>-0.15 <-0.04 HH = (0.11f / 5.0f) * h - 7.96f; //H>-0.15 <-0.04
doskin = true; doskin = true;
} else if((float)h > 74.f && (float)h < 95.f ) { } else if(h > 74.f && h < 95.f ) {
HH = (0.30f / 21.0f) * (float)h + 0.24285f; //H>1.3 H<1.6 HH = (0.30f / 21.0f) * h + 0.24285f; //H>1.3 H<1.6
doskin = true; doskin = true;
} }
if(doskin) { if(doskin) {
float factorskin, factorsat, factor, factorskinext; float factorskin, factor, factorskinext;
float deltaHH = 0.3f; //HH value transition : I have choice 0.3 radians float deltaHH = 0.3f; //HH value transition : I have choice 0.3 radians
float chromapro = sres / Sp; float chromapro = sres / Sp;
@ -2124,7 +2058,7 @@ void Color::skinredfloat ( float J, float h, float sres, float Sp, float dred, f
float scale = 0.999000999f; // 100.0f/100.1f; reduction in normal zone float scale = 0.999000999f; // 100.0f/100.1f; reduction in normal zone
float scaleext = 1.0f; //reduction in transition zone float scaleext = 1.0f; //reduction in transition zone
Color::scalered ( rstprotection, chromapro, 0.0, HH, deltaHH, scale, scaleext);//Scale factor Color::scalered ( rstprotection, chromapro, 0.0, HH, deltaHH, scale, scaleext);//Scale factor
float interm = (chromapro - 1.0f); const float interm = chromapro - 1.0f;
factorskin = 1.0f + (interm * scale); factorskin = 1.0f + (interm * scale);
factorskinext = 1.0f + (interm * scaleext); factorskinext = 1.0f + (interm * scaleext);
} else { } else {
@ -2132,21 +2066,14 @@ void Color::skinredfloat ( float J, float h, float sres, float Sp, float dred, f
factorskinext = chromapro ; factorskinext = chromapro ;
} }
factorsat = chromapro; factor = chromapro;
factor = factorsat; Color::transitred ( HH, s, dred, factorskin, protect_red, factorskinext, deltaHH, chromapro, factor); //transition
Color::transitred ( HH, s, dred, factorskin, protect_red, factorskinext, deltaHH, factorsat, factor); //transition
s *= factor; s *= factor;
} else { } else {
s = ko * sres; s = ko * sres;
} }
} }
void Color::scalered ( const float rstprotection, const float param, const float limit, const float HH, const float deltaHH, float &scale, float &scaleext) void Color::scalered ( const float rstprotection, const float param, const float limit, const float HH, const float deltaHH, float &scale, float &scaleext)
{ {
if(rstprotection < 99.9999f) { if(rstprotection < 99.9999f) {

View File

@ -1006,8 +1006,6 @@ public:
* @brief Get the gamma curves' parameters used by LCMS2 * @brief Get the gamma curves' parameters used by LCMS2
* @param pwr gamma value [>1] * @param pwr gamma value [>1]
* @param ts slope [0 ; 20] * @param ts slope [0 ; 20]
* @param mode [always 0]
* @imax imax [always 0]
* @param gamma a pointer to an array of 6 double gamma values: * @param gamma a pointer to an array of 6 double gamma values:
* gamma0 used in ip2Lab2rgb [0 ; 1], usually near 0.5 (return value) * gamma0 used in ip2Lab2rgb [0 ; 1], usually near 0.5 (return value)
* gamma1 used in ip2Lab2rgb [0 ; 20], can be superior to 20, but it's quite unusual(return value) * gamma1 used in ip2Lab2rgb [0 ; 20], can be superior to 20, but it's quite unusual(return value)
@ -1016,7 +1014,7 @@ public:
* gamma4 used in ip2Lab2rgb [0 ; 1], usually near 0.03(return value) * gamma4 used in ip2Lab2rgb [0 ; 1], usually near 0.03(return value)
* gamma5 used in ip2Lab2rgb [0 ; 1], usually near 0.5 (return value) * gamma5 used in ip2Lab2rgb [0 ; 1], usually near 0.5 (return value)
*/ */
static void calcGamma (double pwr, double ts, int mode, GammaValues &gamma); static void calcGamma (double pwr, double ts, GammaValues &gamma);
/** /**
@ -1468,9 +1466,7 @@ public:
static void scalered ( float rstprotection, float param, float limit, float HH, float deltaHH, float &scale, float &scaleext); static void scalered ( float rstprotection, float param, float limit, float HH, float deltaHH, float &scale, float &scaleext);
static void transitred (float HH, float Chprov1, float dred, float factorskin, float protect_red, float factorskinext, float deltaHH, float factorsat, float &factor); static void transitred (float HH, float Chprov1, float dred, float factorskin, float protect_red, float factorskinext, float deltaHH, float factorsat, float &factor);
static void skinred ( double J, double h, double sres, double Sp, float dred, float protect_red, int sk, float rstprotection, float ko, double &s);
static void skinredfloat ( float J, float h, float sres, float Sp, float dred, float protect_red, int sk, float rstprotection, float ko, float &s); static void skinredfloat ( float J, float h, float sres, float Sp, float dred, float protect_red, int sk, float rstprotection, float ko, float &s);
// static void scaleredcdbl ( float skinprot, float param, float limit, float HH, float deltaHH, float &scale,float &scaleext);
static inline void pregamutlab(float lum, float hue, float &chr) //big approximation to limit gamut (Prophoto) before good gamut procedure for locallab chroma, to avoid crash static inline void pregamutlab(float lum, float hue, float &chr) //big approximation to limit gamut (Prophoto) before good gamut procedure for locallab chroma, to avoid crash
{ {
@ -1801,7 +1797,7 @@ public:
/** /**
* @brief Gamut correction in the XYZ color space * @brief Gamut correction in the XYZ color space
* @param X X channel input value and corrected output value [0 ; 65535] * @param X X channel input value and corrected output value [0 ; 65535]
* @param Y Y channel input value and corrected output value [0 ; 65535] * @param Y Y channel input value[0 ; 65535]
* @param Z Z channel input value and corrected output value [0 ; 65535] * @param Z Z channel input value and corrected output value [0 ; 65535]
* @param p working profile * @param p working profile
*/ */

View File

@ -351,7 +351,7 @@ cmsHPROFILE rtengine::ProfileContent::toProfile() const
double slope = slopetag == 0 ? eps : slopetag; double slope = slopetag == 0 ? eps : slopetag;
GammaValues g_b; //gamma parameters GammaValues g_b; //gamma parameters
Color::calcGamma(pwr, ts, 0, g_b); // call to calcGamma with selected gamma and slope : return parameters for LCMS2 Color::calcGamma(pwr, ts, g_b); // call to calcGamma with selected gamma and slope : return parameters for LCMS2
cmsFloat64Number gammaParams[7]; //gamma parameters cmsFloat64Number gammaParams[7]; //gamma parameters
gammaParams[4] = g_b[3] * ts; gammaParams[4] = g_b[3] * ts;
gammaParams[0] = gammatag; gammaParams[0] = gammatag;

View File

@ -485,8 +485,7 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw,
} }
GammaValues g_a; //gamma parameters GammaValues g_a; //gamma parameters
constexpr int mode = 0; Color::calcGamma(pwr, ts, g_a); // call to calcGamma with selected gamma and slope : return parameters for LCMS2
Color::calcGamma(pwr, ts, mode, g_a); // call to calcGamma with selected gamma and slope : return parameters for LCMS2
cmsFloat64Number gammaParams[7]; cmsFloat64Number gammaParams[7];

View File

@ -161,7 +161,7 @@ void calcGammaLut(double gamma, double ts, LUTf &gammaLut)
std::swap(pwr, gamm); std::swap(pwr, gamm);
} }
rtengine::Color::calcGamma(pwr, ts, 0, g_a); // call to calcGamma with selected gamma and slope rtengine::Color::calcGamma(pwr, ts, g_a); // call to calcGamma with selected gamma and slope
const double start = gamm2 < 1. ? g_a[2] : g_a[3]; const double start = gamm2 < 1. ? g_a[2] : g_a[3];
const double add = g_a[4]; const double add = g_a[4];

View File

@ -74,7 +74,7 @@ void calcGammaLut(double gamma, double ts, LUTf &gammaLut)
std::swap(pwr, gamm); std::swap(pwr, gamm);
} }
rtengine::Color::calcGamma(pwr, ts, 0, g_a); // call to calcGamma with selected gamma and slope rtengine::Color::calcGamma(pwr, ts, g_a); // call to calcGamma with selected gamma and slope
const double start = gamm2 < 1. ? g_a[2] : g_a[3]; const double start = gamm2 < 1. ? g_a[2] : g_a[3];
const double add = g_a[4]; const double add = g_a[4];

View File

@ -1717,10 +1717,8 @@ void RawImageSource::retinexPrepareBuffers(const ColorManagementParams& cmp, con
std::swap(pwr, gamm); std::swap(pwr, gamm);
} }
int mode = 0; Color::calcGamma(pwr, ts, g_a); // call to calcGamma with selected gamma and slope
Color::calcGamma(pwr, ts, mode, g_a); // call to calcGamma with selected gamma and slope
// printf("g_a0=%f g_a1=%f g_a2=%f g_a3=%f g_a4=%f\n", g_a0,g_a1,g_a2,g_a3,g_a4);
double start; double start;
double add; double add;
@ -1984,13 +1982,12 @@ void RawImageSource::retinex(const ColorManagementParams& cmp, const RetinexPara
double gamm = deh.gam; double gamm = deh.gam;
double gamm2 = gamm; double gamm2 = gamm;
double ts = deh.slope; double ts = deh.slope;
int mode = 0;
if (gamm2 < 1.) { if (gamm2 < 1.) {
std::swap(pwr, gamm); std::swap(pwr, gamm);
} }
Color::calcGamma(pwr, ts, mode, g_a); // call to calcGamma with selected gamma and slope Color::calcGamma(pwr, ts, g_a); // call to calcGamma with selected gamma and slope
double mul = 1. + g_a[4]; double mul = 1. + g_a[4];
double add; double add;

View File

@ -881,8 +881,7 @@ void ICCProfileCreator::savePressed()
double ts = slope; double ts = slope;
double slope2 = slope == 0 ? eps : slope; double slope2 = slope == 0 ? eps : slope;
int mode = 0; rtengine::Color::calcGamma(pwr, ts, g_a); // call to calcGamma with selected gamma and slope : return parameters for LCMS2
rtengine::Color::calcGamma(pwr, ts, mode, g_a); // call to calcGamma with selected gamma and slope : return parameters for LCMS2
ga[4] = g_a[3] * ts; ga[4] = g_a[3] * ts;
//printf("g_a.gamma0=%f g_a.gamma1=%f g_a.gamma2=%f g_a.gamma3=%f g_a.gamma4=%f\n", g_a.gamma0,g_a.gamma1,g_a.gamma2,g_a.gamma3,g_a.gamma4); //printf("g_a.gamma0=%f g_a.gamma1=%f g_a.gamma2=%f g_a.gamma3=%f g_a.gamma4=%f\n", g_a.gamma0,g_a.gamma1,g_a.gamma2,g_a.gamma3,g_a.gamma4);
ga[0] = gamma; ga[0] = gamma;