LA - new tool - Color appearance (Cam16 & JzCzHz) (#6377)
* Gui improvments * Several improvments GUI Jz algo * Change function La for lightess Jz * SH jzazbz first * enable Jz SH * Clean code * Disabled Munsell correction when Jz * Change tooltip and Cam16 Munsell * GUI for CzHz and HzHz curves * Enable curves Hz(Hz) Cz(Hz) * Improve Cz chroma * Jz100 reference refine * Change limit Jz100 * Refine link between jz100 and peak adaptation * Improve GUI * Various improvment PQ PU gamut * Change defaults settings * forgotten PL in gamutjz * Small changes and comment * Change gamujz parameter * disabled gamut Jz too slow * Jzazbz curve Jz(Hz) * reenable gamutjz * small changes * Change tooltip * Change labels tooltips * Jzazbz only on advanced mode * GUI improvments * Change tooltip * Change default values and tooltip * Added tooltip Jz * Disabled Jz gamut * Change gamma color and light - remove exposure * Gamma for exposure and DR * gamma Sharp * Gamma vibrance * gamma optimizations * Change tooltips * Optimization PQ * LA GUI for tone curve Ciecam * LA ciecam Enable curve lightness - brightness * LA ciecam GUI color curve * LA ciecam enable color curve * Change tooltip and default values * Enable Jz curve * Enable Cz(Cz) curve * Enable Cz(Jz) curve * Added Log encoding to ciecam * Improvment algorithm remapping * Reenable forgotten listener logencodchanged * Change Jz tooltips * Reenable dynamic range and exposure * First change GUI auto ciecam * 2nd fixed ciecam auto * Improve GUI maskbackground curves * Enable activspot for la ciecam * set sensitive sliders La ciecam when auto scene conditions * Change internal calculations see comments * Checcbox ForceJz to 1 * Change tool position - change order CAM model * Expander for Jzczhz * Remove unused code * GUI changes * Change labels CAM16 Jzazbz * Change slider brightness parameters * improvment SH jz * Some changes to brightness Jz * Fixed scene conditions auto * Renable forgotten change * Prepare calculation Zcam * Prepare Iz for zcam * First GUI Zcam * Improve GUI Zcam * Calculate Qz white - brightness of the reference white * Prepare for PQ - eventually * Init LUT ZCAMBrightCurveJz and ZCAMBrightCurveQz * prepare zcam achromatic variables * First zcam * Change algo step 5 zcam * Another change original algo * Another change to original algo * first colorfullness * Fixed bad behavior threshold and change c c2 surround parameters * added saturation Zcam * Change parameters surround * Enable chroma zcam * change chroma and lightness formula * disable OMP for 2nd process Zcam * Improvment zcam for some high-light images * Change parameters overflow zcam * Change parmeters high datas * another change to retrieve... * Simplify code matrix conversion xyz-jzazbz * Adjust internam parameters zcam * Change some parameters - clean code * Enable PQCam16 * Enable PQ Cam16 - disable ZCAM * remove warning compilation message * Change GUI jzczhz * Fixed bad behavior remaping jz * Remove forgotten parameter - hide Jz100 - PU adaptation- chnage tooltips * Another change to chroma parameter * Small changes * If verbose display in console Cam16 informations * If verbose display in console source saturation colorfullness * Change to La calculation for ciecam * Change GUI cam16 - jzczhz - remove cam16 and jzczhz * Disable exposure compensation to calculate La for all Ciecam and Log encoding * Change label Cam16 and jzczhz * Improve GUI Jz * Other improvment GUI Jz Cam16 * verify nan Jz and ciecam matrix to avoid crash * Enable La manual for Jz to change PU-adaptation * Improve calculation to avoid crash Jz and Cam16 matrix * Fixed crash with local contrast in cam16 * Clean code loccont * First step GUI Cie mask * GUI part 2 - Cie * Build cieMask * Gui part 3 cie * Valid llcieMask * Valid llcieMask * Pass GUI curves parameters to iplocallab.cc * 2nd pass parameters from GUI to iplocallab.cc * Init first functions modifications * Add expander to cam16 adjustments * First test mask cie * Various improvment GUI - tooltips - process * Take into account Yb cam16 for Jz - reenable warm-cool * Surround source Cam16 before Jz * Improve GUI and process * Fixed bug and bad behavior last commit * Fixed bug chroma mask - improve GUI - Relative luminance for Jz * Increase sensitivity mask chroma * Improve Jz with saturation Z - improve GUI Jzczhz * Small code improvment * Another change mask C and enable mask for Cam16 and Jz * Some changes * Enable denoise chroma mask * Small change LIM01 normchromar * Enable Zcam matrix * Improve chroma curves...mask and boudaries * take into account recursive slider in settings * Change tooltip - improvment to C curve (denoise C - best value in curves - etc.) - remove Zcam button * Change tooltips * First part GUI - local contrast wavelet Jz * Passed parameters GUI local contrast wav jz to rtengine * save config wavelet jz * first try wavelet local contrast Jz * Add tooltips * Simplify code wavelet local contrast * take into account edge wavelet performance in Wavelet Jz * Fixed overflow jz when usig botth contradt and wavelt local jz contrast * Adapt size winGdiHandles in filepanel to avoid crash in Windows multieditor * First GUI part Clarity wavelet Jz * First try wavelet Jz Cz clarity * Added tooltips * Small change to enable wavelet jz * Disabled (commented) all Zcam code * Improve behavior when SH local-contrast and Clarity are use both * Change limit PQremap jz * Clean and optimize code * Reenable mjjz * Change settings guidedfilter wavelet Jz * Fixed crash when revory based on lum mask negative * Change tooltip * Fixed ad behavior auto mean and absolute luminance * Remove warning in console * Fixed bad behavior auto Log encoding - bad behavior curves L(H) Jz * Fixed another bad behavior - reenable curves color and light L(H) C(H) * first transposition Lab Jz for curves H * Change mask boundary for Jz * Various improvment to H curves Jz * Add amountchrom to Hcurve Color and Light * Improve gray boundary curves behavior * reenable Jz curve H(H) - soft radius * Improve guidefilter Jz H curve * Threshold chroma Jz(Hz) * Enable guidedfilter chroma curve H * improve GUI curves Hz * Checkbutton chroma for curve Jz(Hz) * Change event selectspot * Clean and small optimization code * Another clean code * Change calculation Hz references for curves Hz * Clean code * Various changes to GF and GUI * Another change to Chroma for Jz(H) * Change GUI sensitive Jz100 adapdjzcie * Improve code for Jz100 * Change default value skin-protection to 0 instead of 50 * Clean code * Remove BENCHFUN for ciecam * small correction to huejz_to_huehsv2 conversion * Added missing plum parameter for jch2xyz_ciecam02float * another small change to huejz_to_huehsv2 * Improvment to huelab_to_huehsv2 and some double functions * Fixed warning hide parameters in lgtm-com * Fixed ? Missing retuen statement in lgtm-com * Change behavior Log encoding whith PQ Cam16 * Small improvment to Jz PU adaptation * Added forgoten to_one for Cz slider * Replace 0.707... by RT_SQRT1_2 - change some settings chroma * Improvment to getAutoLogloc * Fixed crash with array in getAutoLogloc * First try Jz Log encoding * Forgotten Cz * Various improvment GUI setlogscale - Jz log encoding * Change labels tooltips Jz log * Change wrong clipcz value * Change tooltip auto scene conditions * Fixed bad behavior blackevjz whiteevjz * Small improvment to LA Log encoding std * Avoid bad behavior Jz log when enable Relative luminance * Change sourcegray jz calculation * Revert last change * Clean and comment code * Review tooltips thanks to Wayne - harmonize response La log encoding and Jz Log encoding * Always force Dynamic Range evaluation in full frame mode for Jz log encoding * Remove unused code * Small optimizations sigmoid Cam16 and Jz * Comment code * Change parameters deltaE for HDR * Various improvment to Jz - La - sigmoid - log encoding * Basic support for Sony ILCE-7M4 in camconst.json * German translation Spot Removal (#6388) * Filmnegative German translation (#6389) * (Temporarily) disable `ftree-loop-vectorize` for GCC 11 because of #6384 * Added BlacEv WhiteEv to sigmoidJz * Improve GUI for BlackEv WhiteEv * Change location SigmoidJz in Iplocallab * Improvment GUI and sensitivity sliders strength sigmoid * Change labels Co-authored-by: Thanatomanic <6567747+Thanatomanic@users.noreply.github.com> Co-authored-by: Anna <simonanna@gmx.net>
This commit is contained in:
@@ -25,6 +25,19 @@
|
||||
#undef CLIPD
|
||||
#define CLIPD(a) ((a)>0.f?((a)<1.f?(a):1.f):0.f)
|
||||
#define MAXR(a,b) ((a) > (b) ? (a) : (b))
|
||||
#define Jzazbz_b 1.15
|
||||
#define Jzazbz_g 0.66
|
||||
#define Jzazbz_c1 (3424/4096.0)
|
||||
#define Jzazbz_c2 (2413/128.0)
|
||||
#define Jzazbz_c3 (2392/128.0)
|
||||
#define Jzazbz_n (2610/16384.0)
|
||||
#define Jzazbz_p (1.7*2523/32.0)
|
||||
#define Jzazbz_d (-0.56)
|
||||
#define Jzazbz_d0 (1.6295499532821566e-11)
|
||||
#define Jzazbz_ni (16384.0/2610.0)
|
||||
#define Jzazbz_pi (32.0/4289.1) //4289.1 = 2523 * 1.7
|
||||
|
||||
|
||||
|
||||
namespace rtengine
|
||||
{
|
||||
@@ -67,10 +80,12 @@ void Ciecam02::curveJfloat (float br, float contr, float thr, const LUTu & histo
|
||||
brightcurvePoints[5] = 0.7f; // shoulder point
|
||||
brightcurvePoints[6] = min (1.0f, 0.7f + br / 300.0f); //value at shoulder point
|
||||
} else {
|
||||
brightcurvePoints[3] = 0.1f - br / 150.0f; // toe point
|
||||
brightcurvePoints[3] = max(0.0, 0.1 - (double) br / 150.0); // toe point
|
||||
// brightcurvePoints[3] = 0.1f - br / 150.0f; // toe point
|
||||
brightcurvePoints[4] = 0.1f; // value at toe point
|
||||
|
||||
brightcurvePoints[5] = min (1.0f, 0.7f - br / 300.0f); // shoulder point
|
||||
// brightcurvePoints[5] = min (1.0f, 0.7f - br / 300.0f); // shoulder point
|
||||
brightcurvePoints[5] = 0.7f - br / 300.0f; // shoulder point
|
||||
brightcurvePoints[6] = 0.7f; // value at shoulder point
|
||||
}
|
||||
|
||||
@@ -109,6 +124,7 @@ void Ciecam02::curveJfloat (float br, float contr, float thr, const LUTu & histo
|
||||
}
|
||||
|
||||
avg /= sum;
|
||||
// printf("avg=%f \n", (double) avg);
|
||||
float thrmin = (thr - contr / 250.0f);
|
||||
float thrmax = (thr + contr / 250.0f);
|
||||
|
||||
@@ -184,14 +200,14 @@ float Ciecam02::calculate_fl_from_la_ciecam02float ( float la )
|
||||
return (0.2f * k * la5) + (0.1f * (1.0f - k) * (1.0f - k) * std::cbrt (la5));
|
||||
}
|
||||
|
||||
float Ciecam02::achromatic_response_to_whitefloat ( float x, float y, float z, float d, float fl, float nbb, int c16)
|
||||
float Ciecam02::achromatic_response_to_whitefloat ( float x, float y, float z, float d, float fl, float nbb, int c16, float plum)
|
||||
{
|
||||
float r, g, b;
|
||||
float rc, gc, bc;
|
||||
float rp, gp, bp;
|
||||
float rpa, gpa, bpa;
|
||||
// gamu = 1;
|
||||
xyz_to_cat02float ( r, g, b, x, y, z, c16);
|
||||
xyz_to_cat02float ( r, g, b, x, y, z, c16, plum);
|
||||
|
||||
rc = r * (((y * d) / r) + (1.0f - d));
|
||||
gc = g * (((y * d) / g) + (1.0f - d));
|
||||
@@ -216,71 +232,253 @@ float Ciecam02::achromatic_response_to_whitefloat ( float x, float y, float z, f
|
||||
return ((2.0f * rpa) + gpa + ((1.0f / 20.0f) * bpa) - 0.305f) * nbb;
|
||||
}
|
||||
|
||||
void Ciecam02::xyz_to_cat02float ( float &r, float &g, float &b, float x, float y, float z, int c16)
|
||||
{
|
||||
void Ciecam02::xyz_to_cat02float ( float &r, float &g, float &b, float x, float y, float z, int c16, float plum)
|
||||
{ //I use isnan() because I have tested others solutions with std::max(xxx,0) and in some cases crash
|
||||
//original cat02
|
||||
//r = ( 0.7328 * x) + (0.4296 * y) - (0.1624 * z);
|
||||
//g = (-0.7036 * x) + (1.6975 * y) + (0.0061 * z);
|
||||
//b = ( 0.0000 * x) + (0.0000 * y) + (1.0000 * z);
|
||||
float peakLum = 1.f/ plum;
|
||||
if(c16 == 1) {//cat02
|
||||
r = ( 1.007245f * x) + (0.011136f * y) - (0.018381f * z); //Changjun Li
|
||||
g = (-0.318061f * x) + (1.314589f * y) + (0.003471f * z);
|
||||
b = ( 0.0000f * x) + (0.0000f * y) + (1.0000f * z);
|
||||
} else {//cat16
|
||||
} else if (c16 == 16) {//cat16
|
||||
r = ( 0.401288f * x) + (0.650173f * y) - (0.051461f * z); //cat16
|
||||
g = (-0.250268f * x) + (1.204414f * y) + (0.045854f * z);
|
||||
b = ( -0.002079f * x) + (0.048952f * y) + (0.953127f * z);
|
||||
} else if (c16 == 21) {//cam16 PQ
|
||||
float rp = ( 0.401288f * x) + (0.650173f * y) - (0.051461f * z); //cat16
|
||||
float gp = (-0.250268f * x) + (1.204414f * y) + (0.045854f * z);
|
||||
float bp = ( -0.002079f * x) + (0.048952f * y) + (0.953127f * z);
|
||||
rp *= 0.01f;
|
||||
gp *= 0.01f;
|
||||
bp *= 0.01f;
|
||||
float tmp = pow_F(rp * peakLum, Jzazbz_n);
|
||||
if(std::isnan(tmp)) {//to avoid crash
|
||||
tmp = 0.f;
|
||||
}
|
||||
r = 100.f * pow((Jzazbz_c1 + Jzazbz_c2 * tmp) / (1. + Jzazbz_c3 * tmp), Jzazbz_p);
|
||||
if(std::isnan(r) || r < 0.f) {
|
||||
r = 0.f;
|
||||
}
|
||||
|
||||
tmp = pow_F(gp * peakLum, Jzazbz_n);
|
||||
if(std::isnan(tmp)) {//to avoid crash
|
||||
tmp = 0.f;
|
||||
}
|
||||
g = 100.f * pow((Jzazbz_c1 + Jzazbz_c2 * tmp) / (1. + Jzazbz_c3 * tmp), Jzazbz_p);
|
||||
if(std::isnan(g) || g < 0.f) {
|
||||
g = 0.f;
|
||||
}
|
||||
tmp = pow_F(bp * peakLum, Jzazbz_n);
|
||||
if(std::isnan(tmp)) {//to avoid crash
|
||||
tmp = 0.f;
|
||||
}
|
||||
|
||||
b = 100.f * pow((Jzazbz_c1 + Jzazbz_c2 * tmp) / (1. + Jzazbz_c3 * tmp), Jzazbz_p);
|
||||
if(std::isnan(b) || b < 0.f) {
|
||||
b = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef __SSE2__
|
||||
void Ciecam02::xyz_to_cat02float ( vfloat &r, vfloat &g, vfloat &b, vfloat x, vfloat y, vfloat z, int c16)
|
||||
{
|
||||
void Ciecam02::xyz_to_cat02float ( vfloat &r, vfloat &g, vfloat &b, vfloat x, vfloat y, vfloat z, int c16, vfloat plum)
|
||||
{ //I use isnan() because I have tested others solutions with std::max(xxx,0) and in some cases crash
|
||||
//gamut correction M.H.Brill S.Susstrunk
|
||||
if(c16 == 1) {
|
||||
r = ( F2V (1.007245f) * x) + (F2V (0.011136f) * y) - (F2V (0.018381f) * z); //Changjun Li
|
||||
g = (F2V (-0.318061f) * x) + (F2V (1.314589f) * y) + (F2V (0.003471f) * z);
|
||||
b = z;
|
||||
} else {
|
||||
} else if (c16 == 16) {
|
||||
//cat16
|
||||
r = ( F2V (0.401288f) * x) + (F2V (0.650173f) * y) - (F2V (0.051461f) * z); //Changjun Li
|
||||
r = ( F2V (0.401288f) * x) + (F2V (0.650173f) * y) - (F2V (0.051461f) * z);
|
||||
g = -(F2V (0.250268f) * x) + (F2V (1.204414f) * y) + (F2V (0.045854f) * z);
|
||||
b = -(F2V(0.002079f) * x) + (F2V(0.048952f) * y) + (F2V(0.953127f) * z);
|
||||
} else if (c16 == 21) {
|
||||
vfloat rp = ( F2V (0.401288f) * x) + (F2V (0.650173f) * y) - (F2V (0.051461f) * z);
|
||||
vfloat gp = -(F2V (0.250268f) * x) + (F2V (1.204414f) * y) + (F2V (0.045854f) * z);
|
||||
vfloat bp = -(F2V(0.002079f) * x) + (F2V(0.048952f) * y) + (F2V(0.953127f) * z);
|
||||
vfloat Jzazbz_c1v = F2V(Jzazbz_c1);
|
||||
vfloat Jzazbz_c2v = F2V(Jzazbz_c2);
|
||||
vfloat Jzazbz_nv = F2V(Jzazbz_n);
|
||||
vfloat Jzazbz_c3v = F2V(Jzazbz_c3);
|
||||
vfloat Jzazbz_pv = F2V(Jzazbz_p);
|
||||
vfloat mulone = F2V(0.01f);
|
||||
vfloat mulhund = F2V(100.f);
|
||||
float RR, GG, BB;
|
||||
vfloat one = F2V(1.);
|
||||
vfloat peakLumv = one / plum;
|
||||
rp *= mulone;
|
||||
gp *= mulone;
|
||||
bp *= mulone;
|
||||
vfloat tmp = pow_F(rp * peakLumv, Jzazbz_nv );
|
||||
STVF(RR, tmp);
|
||||
if(std::isnan(RR)) {//to avoid crash
|
||||
tmp = F2V(0.f);;
|
||||
}
|
||||
r = mulhund * pow_F((Jzazbz_c1v + Jzazbz_c2v * tmp) / (one + Jzazbz_c3v * tmp), Jzazbz_pv);
|
||||
STVF(RR, r);
|
||||
if(std::isnan(RR) || RR < 0.f) {//to avoid crash
|
||||
r = F2V(0.f);;
|
||||
}
|
||||
tmp = pow_F(gp * peakLumv, Jzazbz_nv );
|
||||
STVF(RR, tmp);
|
||||
if(std::isnan(RR)) {//to avoid crash
|
||||
tmp = F2V(0.f);;
|
||||
}
|
||||
|
||||
g = mulhund * pow_F((Jzazbz_c1v + Jzazbz_c2v * tmp) / (one + Jzazbz_c3v * tmp), Jzazbz_pv);
|
||||
STVF(GG, g);
|
||||
if(std::isnan(GG) || GG < 0.f) {//to avoid crash
|
||||
g = F2V(0.f);;
|
||||
}
|
||||
|
||||
tmp = pow_F(bp * peakLumv, Jzazbz_nv );
|
||||
STVF(RR, tmp);
|
||||
if(std::isnan(RR)) {//to avoid crash
|
||||
tmp = F2V(0.f);;
|
||||
}
|
||||
|
||||
b = mulhund * pow_F((Jzazbz_c1v + Jzazbz_c2v * tmp) / (one + Jzazbz_c3v * tmp), Jzazbz_pv);
|
||||
STVF(BB, b);
|
||||
if(std::isnan(BB) || BB < 0.f) {//to avoid crash
|
||||
b = F2V(0.f);;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void Ciecam02::cat02_to_xyzfloat ( float &x, float &y, float &z, float r, float g, float b, int c16)
|
||||
{
|
||||
void Ciecam02::cat02_to_xyzfloat ( float &x, float &y, float &z, float r, float g, float b, int c16, float plum)
|
||||
{ //I use isnan() because I have tested others solutions with std::max(xxx,0) and in some cases crash
|
||||
//original cat02
|
||||
//x = ( 1.0978566 * r) - (0.277843 * g) + (0.179987 * b);
|
||||
//y = ( 0.455053 * r) + (0.473938 * g) + (0.0710096* b);
|
||||
//z = ( 0.000000 * r) - (0.000000 * g) + (1.000000 * b);
|
||||
float pl = plum;
|
||||
if(c16 == 1) {
|
||||
x = ( 0.99015849f * r) - (0.00838772f * g) + (0.018229217f * b); //Changjun Li
|
||||
y = ( 0.239565979f * r) + (0.758664642f * g) + (0.001770137f * b);
|
||||
z = ( 0.000000f * r) - (0.000000f * g) + (1.000000f * b);
|
||||
} else {//cat16
|
||||
} else if(c16 == 16){//cat16
|
||||
x = ( 1.86206786f * r) - (1.01125463f * g) + (0.14918677f * b); //Cat16
|
||||
y = ( 0.38752654f * r) + (0.62144744f * g) + (-0.00897398f * b);
|
||||
z = ( -0.0158415f * r) - (0.03412294f * g) + (1.04996444f * b);
|
||||
}else if(c16 == 21){//cam16 PQ
|
||||
float lp = ( 1.86206786f * r) - (1.01125463f * g) + (0.14918677f * b); //Cat16
|
||||
float mp = ( 0.38752654f * r) + (0.62144744f * g) + (-0.00897398f * b);
|
||||
float sp = ( -0.0158415f * r) - (0.03412294f * g) + (1.04996444f * b);
|
||||
lp *= 0.01f;
|
||||
float tmp = pow_F(lp, Jzazbz_pi);
|
||||
if(std::isnan(tmp)) {//to avoid crash
|
||||
tmp = 0.f;
|
||||
}
|
||||
|
||||
float prov = (Jzazbz_c1 - tmp) / ((Jzazbz_c3 * tmp) - Jzazbz_c2);
|
||||
x = pl * pow_F(prov, Jzazbz_ni);
|
||||
if(std::isnan(x)) {//to avoid crash
|
||||
x = 0.f;
|
||||
}
|
||||
x *= 100.f;
|
||||
mp *= 0.01f;
|
||||
tmp = pow_F(mp, Jzazbz_pi);
|
||||
if(std::isnan(tmp)) {//to avoid crash
|
||||
tmp = 0.f;
|
||||
}
|
||||
prov = (Jzazbz_c1 - tmp) / ((Jzazbz_c3 * tmp) - Jzazbz_c2);
|
||||
y = pl * pow_F(prov, Jzazbz_ni);
|
||||
if(std::isnan(y)) {
|
||||
y = 0.f;
|
||||
}
|
||||
y *= 100.f;
|
||||
sp *= 0.01f;
|
||||
tmp = pow_F(sp, Jzazbz_pi);
|
||||
if(std::isnan(tmp)) {//to avoid crash
|
||||
tmp = 0.f;
|
||||
}
|
||||
prov = (Jzazbz_c1 - tmp) / ((Jzazbz_c3 * tmp) - Jzazbz_c2);
|
||||
z = pl * pow_F(prov, Jzazbz_ni);
|
||||
if(std::isnan(z)) {
|
||||
z = 0.;
|
||||
}
|
||||
z *= 100.f;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#ifdef __SSE2__
|
||||
void Ciecam02::cat02_to_xyzfloat ( vfloat &x, vfloat &y, vfloat &z, vfloat r, vfloat g, vfloat b, int c16 )
|
||||
{
|
||||
void Ciecam02::cat02_to_xyzfloat ( vfloat &x, vfloat &y, vfloat &z, vfloat r, vfloat g, vfloat b, int c16, vfloat plum )
|
||||
{ //I use isnan() because I have tested others solutions with std::max(xxx,0) and in some cases crash
|
||||
vfloat plv = plum;
|
||||
//gamut correction M.H.Brill S.Susstrunk
|
||||
if(c16 == 1) {//cat02
|
||||
x = ( F2V (0.99015849f) * r) - (F2V (0.00838772f) * g) + (F2V (0.018229217f) * b); //Changjun Li
|
||||
y = ( F2V (0.239565979f) * r) + (F2V (0.758664642f) * g) + (F2V (0.001770137f) * b);
|
||||
z = b;
|
||||
} else {
|
||||
} else if(c16 == 16) {
|
||||
//cat16
|
||||
x = ( F2V (1.86206786f) * r) - (F2V (1.01125463f) * g) + (F2V (0.14918677f) * b);
|
||||
y = ( F2V (0.38752654f) * r) + (F2V (0.621447744f) * g) - (F2V (0.00897398f) * b);
|
||||
z = -(F2V(0.0158415f) * r) - (F2V(0.03412294f) * g) + (F2V(1.04996444f) * b);
|
||||
}else if(c16 == 21){//cam16 PQ
|
||||
vfloat lp = ( F2V (1.86206786f) * r) - (F2V (1.01125463f) * g) + (F2V (0.14918677f) * b);
|
||||
vfloat mp = ( F2V (0.38752654f) * r) + (F2V (0.621447744f) * g) - (F2V (0.00897398f) * b);
|
||||
vfloat sp = -(F2V(0.0158415f) * r) - (F2V(0.03412294f) * g) + (F2V(1.04996444f) * b);
|
||||
float XX,YY,ZZ;
|
||||
vfloat Jzazbz_c1v = F2V(Jzazbz_c1);
|
||||
vfloat Jzazbz_c2v = F2V(Jzazbz_c2);
|
||||
vfloat Jzazbz_c3v = F2V(Jzazbz_c3);
|
||||
vfloat Jzazbz_piv = F2V(Jzazbz_pi);
|
||||
vfloat Jzazbz_niv = F2V(Jzazbz_ni);
|
||||
vfloat mulone = F2V(0.01f);
|
||||
vfloat mulhund = F2V(100.f);
|
||||
lp *= mulone;
|
||||
float pro;
|
||||
vfloat tmp = pow_F(lp, Jzazbz_piv);
|
||||
STVF(XX, tmp);
|
||||
if(std::isnan(XX)) {//to avoid crash
|
||||
tmp = F2V(0.f);;
|
||||
}
|
||||
vfloat prov = (Jzazbz_c1v - tmp) / ((Jzazbz_c3v * tmp) - Jzazbz_c2v);
|
||||
x = plv * pow_F(prov, Jzazbz_niv);
|
||||
STVF(XX, x);
|
||||
if(std::isnan(XX)) {//to avoid crash
|
||||
x = F2V(0.f);;
|
||||
}
|
||||
x *= mulhund;
|
||||
mp *= mulone;
|
||||
tmp = pow_F(mp, Jzazbz_piv);
|
||||
STVF(YY, tmp);
|
||||
if(std::isnan(YY)) {//to avoid crash
|
||||
tmp = F2V(0.f);;
|
||||
}
|
||||
prov = (Jzazbz_c1v - tmp) / ((Jzazbz_c3v * tmp) - Jzazbz_c2v);
|
||||
y = plv * pow_F(prov, Jzazbz_niv);
|
||||
STVF(YY, y);
|
||||
if(std::isnan(YY)) {//to avoid crash
|
||||
y = F2V(0.f);;
|
||||
}
|
||||
y *= mulhund;
|
||||
sp *= mulone;
|
||||
tmp = pow_F(sp, Jzazbz_piv);
|
||||
STVF(ZZ, tmp);
|
||||
if(std::isnan(ZZ)) {//to avoid crash
|
||||
tmp = F2V(0.f);;
|
||||
}
|
||||
prov = (Jzazbz_c1v - tmp) / ((Jzazbz_c3v * tmp) - Jzazbz_c2v);
|
||||
STVF(pro, prov);
|
||||
z = plv * pow_F(prov, Jzazbz_niv);
|
||||
STVF(ZZ, z);
|
||||
if(std::isnan(ZZ)) {//to avoid crash
|
||||
z = F2V(0.f);;
|
||||
}
|
||||
z *= mulhund;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -429,7 +627,7 @@ void Ciecam02::calculate_abfloat ( vfloat &aa, vfloat &bb, vfloat h, vfloat e, v
|
||||
#endif
|
||||
|
||||
void Ciecam02::initcam1float (float yb, float pilotd, float f, float la, float xw, float yw, float zw, float &n, float &d, float &nbb, float &ncb,
|
||||
float &cz, float &aw, float &wh, float &pfl, float &fl, float c, int c16)
|
||||
float &cz, float &aw, float &wh, float &pfl, float &fl, float c, int c16, float plum)
|
||||
{
|
||||
n = yb / yw;
|
||||
|
||||
@@ -442,13 +640,13 @@ void Ciecam02::initcam1float (float yb, float pilotd, float f, float la, float x
|
||||
fl = calculate_fl_from_la_ciecam02float ( la );
|
||||
nbb = ncb = 0.725f * pow_F ( 1.0f / n, 0.2f );
|
||||
cz = 1.48f + sqrt ( n );
|
||||
aw = achromatic_response_to_whitefloat ( xw, yw, zw, d, fl, nbb, c16);
|
||||
aw = achromatic_response_to_whitefloat ( xw, yw, zw, d, fl, nbb, c16, plum);
|
||||
wh = ( 4.0f / c ) * ( aw + 4.0f ) * pow_F ( fl, 0.25f );
|
||||
pfl = pow_F ( fl, 0.25f );
|
||||
}
|
||||
|
||||
void Ciecam02::initcam2float (float yb, float pilotd, float f, float la, float xw, float yw, float zw, float &n, float &d, float &nbb, float &ncb,
|
||||
float &cz, float &aw, float &fl, int c16)
|
||||
float &cz, float &aw, float &fl, int c16, float plum)
|
||||
{
|
||||
n = yb / yw;
|
||||
|
||||
@@ -462,12 +660,135 @@ void Ciecam02::initcam2float (float yb, float pilotd, float f, float la, float x
|
||||
fl = calculate_fl_from_la_ciecam02float ( la );
|
||||
nbb = ncb = 0.725f * pow_F ( 1.0f / n, 0.2f );
|
||||
cz = 1.48f + sqrt ( n );
|
||||
aw = achromatic_response_to_whitefloat ( xw, yw, zw, d, fl, nbb, c16);
|
||||
aw = achromatic_response_to_whitefloat ( xw, yw, zw, d, fl, nbb, c16, plum);
|
||||
}
|
||||
|
||||
|
||||
void Ciecam02::xyz2jzczhz ( double &Jz, double &az, double &bz, double x, double y, double z, double pl, double &Lp, double &Mp, double &Sp, bool zcam)
|
||||
{ //from various web
|
||||
double Xp, Yp, Zp, L, M, S, Iz;
|
||||
double peakLum = 1. / pl;
|
||||
//I change 10000 for peaklum function of la (absolute luminance)- default 10000
|
||||
Xp = Jzazbz_b * x - ((Jzazbz_b - 1.) * z);
|
||||
Yp = Jzazbz_g * y - ((Jzazbz_g - 1.) * x);
|
||||
Zp = z;
|
||||
|
||||
L = 0.41478972 * Xp + 0.579999 * Yp + 0.0146480 * Zp;
|
||||
M = -0.2015100 * Xp + 1.120649 * Yp + 0.0531008 * Zp;
|
||||
S = -0.0166008 * Xp + 0.264800 * Yp + 0.6684799 * Zp;
|
||||
|
||||
//I use isnan() because I have tested others solutions with std::max(xxx,0) and in some cases crash
|
||||
// Lp = pow((Jzazbz_c1 + Jzazbz_c2 * pow(std::max((L * peakLum), 0.), Jzazbz_n)) / (1. + Jzazbz_c3 * pow((L * peakLum), Jzazbz_n)), Jzazbz_p);
|
||||
// Mp = pow((Jzazbz_c1 + Jzazbz_c2 * pow(std::max((M * peakLum),0.), Jzazbz_n)) / (1. + Jzazbz_c3 * pow((M * peakLum), Jzazbz_n)), Jzazbz_p);
|
||||
// Sp = pow((Jzazbz_c1 + Jzazbz_c2 * pow(std::max((S * peakLum), 0.), Jzazbz_n)) / (1. + Jzazbz_c3 * pow((S * peakLum), Jzazbz_n)), Jzazbz_p);
|
||||
double temp = pow(L * peakLum, Jzazbz_n);
|
||||
if(std::isnan(temp)) {//to avoid crash
|
||||
temp = 0.;
|
||||
}
|
||||
Lp = pow((Jzazbz_c1 + Jzazbz_c2 * temp) / (1. + Jzazbz_c3 * temp), Jzazbz_p);
|
||||
if(std::isnan(Lp)) {//to avoid crash
|
||||
Lp = 0.;
|
||||
}
|
||||
|
||||
temp = pow(M * peakLum, Jzazbz_n);
|
||||
if(std::isnan(temp)) {//to avoid crash
|
||||
temp = 0.;
|
||||
}
|
||||
Mp = pow((Jzazbz_c1 + Jzazbz_c2 * temp) / (1. + Jzazbz_c3 * temp), Jzazbz_p);
|
||||
if(std::isnan(Mp)) {//to avoid crash
|
||||
Mp = 0.;
|
||||
}
|
||||
|
||||
temp = pow(S * peakLum, Jzazbz_n);
|
||||
if(std::isnan(temp)) {//to avoid crash
|
||||
temp = 0.;
|
||||
}
|
||||
Sp = pow((Jzazbz_c1 + Jzazbz_c2 * temp) / (1. + Jzazbz_c3 * temp), Jzazbz_p);
|
||||
if(std::isnan(Sp)) {//to avoid crash
|
||||
Sp = 0.;
|
||||
}
|
||||
|
||||
Iz = 0.5 * Lp + 0.5 * Mp;
|
||||
az = 3.524000 * Lp - 4.066708 * Mp + 0.542708 * Sp;
|
||||
bz = 0.199076 * Lp + 1.096799 * Mp - 1.295875 * Sp;
|
||||
if(!zcam) {
|
||||
Jz = (((1. + Jzazbz_d) * Iz) / (1. + Jzazbz_d * Iz)) - Jzazbz_d0;
|
||||
// Jz = std::max((((1. + Jzazbz_d) * Iz) / (1. + Jzazbz_d * Iz)) - Jzazbz_d0, 0.);
|
||||
} else {
|
||||
//or if we use ZCAM Jz = Mp - Jzazbz_d0
|
||||
Jz = Mp - Jzazbz_d0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Ciecam02::jzczhzxyz (double &x, double &y, double &z, double jz, double az, double bz, double pl, double &L, double &M, double &S, bool zcam)
|
||||
{ //from various web
|
||||
//I use isnan() because I have tested others solutions with std::max(xxx,0) and in some cases crash
|
||||
|
||||
double Xp, Yp, Zp, Lp, Mp, Sp, Iz, tmp;
|
||||
|
||||
if(!zcam) {
|
||||
// Iz = std::max((jz + Jzazbz_d0) / (1. + Jzazbz_d - Jzazbz_d * (jz + Jzazbz_d0)), 0.);
|
||||
Iz = (jz + Jzazbz_d0) / (1. + Jzazbz_d - Jzazbz_d * (jz + Jzazbz_d0));
|
||||
} else {
|
||||
//or if we use ZCAM Iz = Jz + Jzazbz_d0
|
||||
Iz = jz + Jzazbz_d0;
|
||||
}
|
||||
|
||||
Lp = Iz + 0.138605043271539 * az + 0.0580473161561189 * bz;
|
||||
Mp = Iz - 0.138605043271539 * az - 0.0580473161561189 * bz;
|
||||
Sp = Iz - 0.0960192420263189 * az - 0.811891896056039 * bz;
|
||||
//I change optionnaly 10000 for pl function of la(absolute luminance) default 10000
|
||||
|
||||
tmp = pow(Lp, Jzazbz_pi);
|
||||
if(std::isnan(tmp)) {//to avoid crash
|
||||
tmp = 0.;
|
||||
}
|
||||
L = pl * pow((Jzazbz_c1 - tmp) / ((Jzazbz_c3 * tmp) - Jzazbz_c2), Jzazbz_ni);
|
||||
if(std::isnan(L)) {//to avoid crash
|
||||
L = 0.;
|
||||
}
|
||||
|
||||
tmp = pow(Mp, Jzazbz_pi);
|
||||
if(std::isnan(tmp)) {//to avoid crash
|
||||
tmp = 0.;
|
||||
}
|
||||
M = pl * pow((Jzazbz_c1 - tmp) / ((Jzazbz_c3 * tmp) - Jzazbz_c2), Jzazbz_ni);
|
||||
if(std::isnan(M)) {//to avoid crash
|
||||
M = 0.;
|
||||
}
|
||||
|
||||
tmp = pow(Sp, Jzazbz_pi);
|
||||
if(std::isnan(tmp)) {//to avoid crash
|
||||
tmp = 0.;
|
||||
}
|
||||
S = pl * pow((Jzazbz_c1 - tmp) / ((Jzazbz_c3 * tmp) - Jzazbz_c2), Jzazbz_ni);
|
||||
if(std::isnan(S)) {//to avoid crash
|
||||
S = 0.;
|
||||
}
|
||||
|
||||
Xp = 1.9242264357876067 * L - 1.0047923125953657 * M + 0.0376514040306180 * S;
|
||||
Yp = 0.3503167620949991 * L + 0.7264811939316552 * M - 0.0653844229480850 * S;
|
||||
Zp = -0.0909828109828475 * L - 0.3127282905230739 * M + 1.5227665613052603 * S;
|
||||
|
||||
x = (Xp + (Jzazbz_b - 1.) * Zp) / Jzazbz_b;
|
||||
|
||||
if(std::isnan(x)) {//to avoid crash
|
||||
x = 0.;
|
||||
}
|
||||
y = (Yp + (Jzazbz_g - 1.) * x) / Jzazbz_g;
|
||||
if(std::isnan(y)) {
|
||||
y = 0.;
|
||||
}
|
||||
z = Zp;
|
||||
if(std::isnan(z)) {
|
||||
z = 0.;
|
||||
}
|
||||
}
|
||||
|
||||
void Ciecam02::xyz2jchqms_ciecam02float ( float &J, float &C, float &h, float &Q, float &M, float &s, float aw, float fl, float wh,
|
||||
float x, float y, float z, float xw, float yw, float zw,
|
||||
float c, float nc, float pow1, float nbb, float ncb, float pfl, float cz, float d, int c16)
|
||||
float c, float nc, float pow1, float nbb, float ncb, float pfl, float cz, float d, int c16, float plum)
|
||||
|
||||
{
|
||||
float r, g, b;
|
||||
@@ -478,8 +799,8 @@ void Ciecam02::xyz2jchqms_ciecam02float ( float &J, float &C, float &h, float &Q
|
||||
float a, ca, cb;
|
||||
float e, t;
|
||||
float myh;
|
||||
xyz_to_cat02float ( r, g, b, x, y, z, c16);
|
||||
xyz_to_cat02float ( rw, gw, bw, xw, yw, zw, c16);
|
||||
xyz_to_cat02float ( r, g, b, x, y, z, c16, plum);
|
||||
xyz_to_cat02float ( rw, gw, bw, xw, yw, zw, c16, plum);
|
||||
rc = r * (((yw * d) / rw) + (1.f - d));
|
||||
gc = g * (((yw * d) / gw) + (1.f - d));
|
||||
bc = b * (((yw * d) / bw) + (1.f - d));
|
||||
@@ -530,7 +851,7 @@ void Ciecam02::xyz2jchqms_ciecam02float ( float &J, float &C, float &h, float &Q
|
||||
#ifdef __SSE2__
|
||||
void Ciecam02::xyz2jchqms_ciecam02float ( vfloat &J, vfloat &C, vfloat &h, vfloat &Q, vfloat &M, vfloat &s, vfloat aw, vfloat fl, vfloat wh,
|
||||
vfloat x, vfloat y, vfloat z, vfloat xw, vfloat yw, vfloat zw,
|
||||
vfloat c, vfloat nc, vfloat pow1, vfloat nbb, vfloat ncb, vfloat pfl, vfloat cz, vfloat d, int c16)
|
||||
vfloat c, vfloat nc, vfloat pow1, vfloat nbb, vfloat ncb, vfloat pfl, vfloat cz, vfloat d, int c16, vfloat plum)
|
||||
|
||||
{
|
||||
vfloat r, g, b;
|
||||
@@ -541,8 +862,8 @@ void Ciecam02::xyz2jchqms_ciecam02float ( vfloat &J, vfloat &C, vfloat &h, vfloa
|
||||
vfloat a, ca, cb;
|
||||
vfloat e, t;
|
||||
|
||||
xyz_to_cat02float ( r, g, b, x, y, z, c16);
|
||||
xyz_to_cat02float ( rw, gw, bw, xw, yw, zw, c16);
|
||||
xyz_to_cat02float ( r, g, b, x, y, z, c16, plum);
|
||||
xyz_to_cat02float ( rw, gw, bw, xw, yw, zw, c16, plum);
|
||||
vfloat onev = F2V (1.f);
|
||||
rc = r * (((yw * d) / rw) + (onev - d));
|
||||
gc = g * (((yw * d) / gw) + (onev - d));
|
||||
@@ -595,7 +916,7 @@ void Ciecam02::xyz2jchqms_ciecam02float ( vfloat &J, vfloat &C, vfloat &h, vfloa
|
||||
|
||||
void Ciecam02::xyz2jch_ciecam02float ( float &J, float &C, float &h, float aw, float fl,
|
||||
float x, float y, float z, float xw, float yw, float zw,
|
||||
float c, float nc, float pow1, float nbb, float ncb, float cz, float d, int c16)
|
||||
float c, float nc, float pow1, float nbb, float ncb, float cz, float d, int c16, float plum)
|
||||
|
||||
{
|
||||
float r, g, b;
|
||||
@@ -606,8 +927,8 @@ void Ciecam02::xyz2jch_ciecam02float ( float &J, float &C, float &h, float aw, f
|
||||
float a, ca, cb;
|
||||
float e, t;
|
||||
float myh;
|
||||
xyz_to_cat02float ( r, g, b, x, y, z, c16);
|
||||
xyz_to_cat02float ( rw, gw, bw, xw, yw, zw, c16);
|
||||
xyz_to_cat02float ( r, g, b, x, y, z, c16, plum);
|
||||
xyz_to_cat02float ( rw, gw, bw, xw, yw, zw, c16, plum);
|
||||
rc = r * (((yw * d) / rw) + (1.f - d));
|
||||
gc = g * (((yw * d) / gw) + (1.f - d));
|
||||
bc = b * (((yw * d) / bw) + (1.f - d));
|
||||
@@ -664,7 +985,7 @@ void Ciecam02::xyz2jch_ciecam02float ( float &J, float &C, float &h, float aw, f
|
||||
|
||||
void Ciecam02::jch2xyz_ciecam02float ( float &x, float &y, float &z, float J, float C, float h,
|
||||
float xw, float yw, float zw,
|
||||
float c, float nc, float pow1, float nbb, float ncb, float fl, float cz, float d, float aw, int c16)
|
||||
float c, float nc, float pow1, float nbb, float ncb, float fl, float cz, float d, float aw, int c16, float plum)
|
||||
{
|
||||
float r, g, b;
|
||||
float rc, gc, bc;
|
||||
@@ -673,7 +994,7 @@ void Ciecam02::jch2xyz_ciecam02float ( float &x, float &y, float &z, float J, fl
|
||||
float rw, gw, bw;
|
||||
float a, ca, cb;
|
||||
float e, t;
|
||||
xyz_to_cat02float(rw, gw, bw, xw, yw, zw, c16);
|
||||
xyz_to_cat02float(rw, gw, bw, xw, yw, zw, c16, plum);
|
||||
e = ((961.53846f) * nc * ncb) * (xcosf(h * rtengine::RT_PI_F_180 + 2.0f) + 3.8f);
|
||||
|
||||
#ifdef __SSE2__
|
||||
@@ -705,7 +1026,7 @@ void Ciecam02::jch2xyz_ciecam02float ( float &x, float &y, float &z, float J, fl
|
||||
|
||||
if(c16 == 1) {//cat02
|
||||
hpe_to_xyzfloat(x, y, z, rp, gp, bp, c16);
|
||||
xyz_to_cat02float(rc, gc, bc, x, y, z, c16);
|
||||
xyz_to_cat02float(rc, gc, bc, x, y, z, c16, plum);
|
||||
|
||||
r = rc / (((yw * d) / rw) + (1.0f - d));
|
||||
g = gc / (((yw * d) / gw) + (1.0f - d));
|
||||
@@ -716,13 +1037,13 @@ void Ciecam02::jch2xyz_ciecam02float ( float &x, float &y, float &z, float J, fl
|
||||
b = bp / (((yw * d) / bw) + (1.0f - d));
|
||||
}
|
||||
|
||||
cat02_to_xyzfloat(x, y, z, r, g, b, c16);
|
||||
cat02_to_xyzfloat(x, y, z, r, g, b, c16, plum);
|
||||
}
|
||||
|
||||
#ifdef __SSE2__
|
||||
void Ciecam02::jch2xyz_ciecam02float ( vfloat &x, vfloat &y, vfloat &z, vfloat J, vfloat C, vfloat h,
|
||||
vfloat xw, vfloat yw, vfloat zw,
|
||||
vfloat nc, vfloat pow1, vfloat nbb, vfloat ncb, vfloat fl, vfloat d, vfloat aw, vfloat reccmcz, int c16)
|
||||
vfloat nc, vfloat pow1, vfloat nbb, vfloat ncb, vfloat fl, vfloat d, vfloat aw, vfloat reccmcz, int c16, vfloat plum)
|
||||
{
|
||||
vfloat r, g, b;
|
||||
vfloat rc, gc, bc;
|
||||
@@ -731,7 +1052,7 @@ void Ciecam02::jch2xyz_ciecam02float ( vfloat &x, vfloat &y, vfloat &z, vfloat J
|
||||
vfloat rw, gw, bw;
|
||||
vfloat a, ca, cb;
|
||||
vfloat e, t;
|
||||
xyz_to_cat02float ( rw, gw, bw, xw, yw, zw, c16);
|
||||
xyz_to_cat02float ( rw, gw, bw, xw, yw, zw, c16, plum);
|
||||
e = ((F2V (961.53846f)) * nc * ncb) * (xcosf ( ((h * F2V (rtengine::RT_PI)) / F2V (180.0f)) + F2V (2.0f) ) + F2V (3.8f));
|
||||
a = pow_F ( J / F2V (100.0f), reccmcz ) * aw;
|
||||
t = pow_F ( F2V (10.f) * C / (vsqrtf ( J ) * pow1), F2V (1.1111111f) );
|
||||
@@ -745,7 +1066,7 @@ void Ciecam02::jch2xyz_ciecam02float ( vfloat &x, vfloat &y, vfloat &z, vfloat J
|
||||
|
||||
if(c16 == 1) {//cat02
|
||||
hpe_to_xyzfloat ( x, y, z, rp, gp, bp, c16);
|
||||
xyz_to_cat02float ( rc, gc, bc, x, y, z, c16 );
|
||||
xyz_to_cat02float ( rc, gc, bc, x, y, z, c16, plum );
|
||||
|
||||
r = rc / (((yw * d) / rw) + (F2V (1.0f) - d));
|
||||
g = gc / (((yw * d) / gw) + (F2V (1.0f) - d));
|
||||
@@ -756,7 +1077,7 @@ void Ciecam02::jch2xyz_ciecam02float ( vfloat &x, vfloat &y, vfloat &z, vfloat J
|
||||
b = bp / (((yw * d) / bw) + (F2V (1.0f) - d));
|
||||
}
|
||||
|
||||
cat02_to_xyzfloat ( x, y, z, r, g, b, c16 );
|
||||
cat02_to_xyzfloat ( x, y, z, r, g, b, c16, plum );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user