custom trc: another small speedup, #5025
This commit is contained in:
@@ -443,29 +443,26 @@ void ImProcFunctions::workingtrc(Imagefloat* src, Imagefloat* dst, int cw, int c
|
||||
{
|
||||
dx = dz = 1.0;
|
||||
}
|
||||
double toxyz[3][3] = {
|
||||
const float toxyz[3][3] = {
|
||||
{
|
||||
(wprof[0][0] / (dx * (normalizeIn ? 65535.0 : 1.0))), //I have suppressed / Color::D50x
|
||||
(wprof[0][1] / (dx * (normalizeIn ? 65535.0 : 1.0))),
|
||||
(wprof[0][2] / (dx * (normalizeIn ? 65535.0 : 1.0)))
|
||||
static_cast<float>(wprof[0][0] / (dx * (normalizeIn ? 65535.0 : 1.0))), //I have suppressed / Color::D50x
|
||||
static_cast<float>(wprof[0][1] / (dx * (normalizeIn ? 65535.0 : 1.0))),
|
||||
static_cast<float>(wprof[0][2] / (dx * (normalizeIn ? 65535.0 : 1.0)))
|
||||
}, {
|
||||
(wprof[1][0] / (normalizeIn ? 65535.0 : 1.0)),
|
||||
(wprof[1][1] / (normalizeIn ? 65535.0 : 1.0)),
|
||||
(wprof[1][2] / (normalizeIn ? 65535.0 : 1.0))
|
||||
static_cast<float>(wprof[1][0] / (normalizeIn ? 65535.0 : 1.0)),
|
||||
static_cast<float>(wprof[1][1] / (normalizeIn ? 65535.0 : 1.0)),
|
||||
static_cast<float>(wprof[1][2] / (normalizeIn ? 65535.0 : 1.0))
|
||||
}, {
|
||||
(wprof[2][0] / (dz * (normalizeIn ? 65535.0 : 1.0))), //I have suppressed / Color::D50z
|
||||
(wprof[2][1] / (dz * (normalizeIn ? 65535.0 : 1.0))),
|
||||
(wprof[2][2] / (dz * (normalizeIn ? 65535.0 : 1.0)))
|
||||
static_cast<float>(wprof[2][0] / (dz * (normalizeIn ? 65535.0 : 1.0))), //I have suppressed / Color::D50z
|
||||
static_cast<float>(wprof[2][1] / (dz * (normalizeIn ? 65535.0 : 1.0))),
|
||||
static_cast<float>(wprof[2][2] / (dz * (normalizeIn ? 65535.0 : 1.0)))
|
||||
}
|
||||
};
|
||||
|
||||
double pwr;
|
||||
double ts;
|
||||
ts = slpos;
|
||||
|
||||
double pwr = 1.0 / gampos;
|
||||
double ts = slpos;
|
||||
int five = mul;
|
||||
|
||||
pwr = 1.0 / gampos;
|
||||
|
||||
if (gampos < 1.0) {
|
||||
pwr = gampos;
|
||||
@@ -474,7 +471,7 @@ void ImProcFunctions::workingtrc(Imagefloat* src, Imagefloat* dst, int cw, int c
|
||||
}
|
||||
|
||||
// int select_temp = 1; //5003K
|
||||
const double eps = 0.000000001; // not divide by zero
|
||||
constexpr double eps = 0.000000001; // not divide by zero
|
||||
|
||||
enum class ColorTemp {
|
||||
D50 = 5003, // for Widegamut, ProPhoto Best, Beta -> D50
|
||||
@@ -484,173 +481,181 @@ void ImProcFunctions::workingtrc(Imagefloat* src, Imagefloat* dst, int cw, int c
|
||||
};
|
||||
ColorTemp temp = ColorTemp::D50;
|
||||
|
||||
cmsHPROFILE oprofdef;
|
||||
float p[6]; //primaries
|
||||
|
||||
if (true) {
|
||||
//primaries for 10 working profiles ==> output profiles
|
||||
if (profile == "WideGamut") {
|
||||
p[0] = 0.7350; //Widegamut primaries
|
||||
p[1] = 0.2650;
|
||||
p[2] = 0.1150;
|
||||
p[3] = 0.8260;
|
||||
p[4] = 0.1570;
|
||||
p[5] = 0.0180;
|
||||
} else if (profile == "Adobe RGB") {
|
||||
p[0] = 0.6400; //Adobe primaries
|
||||
p[1] = 0.3300;
|
||||
p[2] = 0.2100;
|
||||
p[3] = 0.7100;
|
||||
p[4] = 0.1500;
|
||||
p[5] = 0.0600;
|
||||
temp = ColorTemp::D65;
|
||||
} else if (profile == "sRGB") {
|
||||
p[0] = 0.6400; // sRGB primaries
|
||||
p[1] = 0.3300;
|
||||
p[2] = 0.3000;
|
||||
p[3] = 0.6000;
|
||||
p[4] = 0.1500;
|
||||
p[5] = 0.0600;
|
||||
temp = ColorTemp::D65;
|
||||
} else if (profile == "BruceRGB") {
|
||||
p[0] = 0.6400; // Bruce primaries
|
||||
p[1] = 0.3300;
|
||||
p[2] = 0.2800;
|
||||
p[3] = 0.6500;
|
||||
p[4] = 0.1500;
|
||||
p[5] = 0.0600;
|
||||
temp = ColorTemp::D65;
|
||||
} else if (profile == "Beta RGB") {
|
||||
p[0] = 0.6888; // Beta primaries
|
||||
p[1] = 0.3112;
|
||||
p[2] = 0.1986;
|
||||
p[3] = 0.7551;
|
||||
p[4] = 0.1265;
|
||||
p[5] = 0.0352;
|
||||
} else if (profile == "BestRGB") {
|
||||
p[0] = 0.7347; // Best primaries
|
||||
p[1] = 0.2653;
|
||||
p[2] = 0.2150;
|
||||
p[3] = 0.7750;
|
||||
p[4] = 0.1300;
|
||||
p[5] = 0.0350;
|
||||
} else if (profile == "Rec2020") {
|
||||
p[0] = 0.7080; // Rec2020 primaries
|
||||
p[1] = 0.2920;
|
||||
p[2] = 0.1700;
|
||||
p[3] = 0.7970;
|
||||
p[4] = 0.1310;
|
||||
p[5] = 0.0460;
|
||||
temp = ColorTemp::D65;
|
||||
} else if (profile == "ACESp0") {
|
||||
p[0] = 0.7347; // ACES P0 primaries
|
||||
p[1] = 0.2653;
|
||||
p[2] = 0.0000;
|
||||
p[3] = 1.0;
|
||||
p[4] = 0.0001;
|
||||
p[5] = -0.0770;
|
||||
temp = ColorTemp::D60;
|
||||
} else if (profile == "ACESp1") {
|
||||
p[0] = 0.713; // ACES P1 primaries
|
||||
p[1] = 0.293;
|
||||
p[2] = 0.165;
|
||||
p[3] = 0.830;
|
||||
p[4] = 0.128;
|
||||
p[5] = 0.044;
|
||||
temp = ColorTemp::D60;
|
||||
} else if (profile == "ProPhoto") {
|
||||
p[0] = 0.7347; //ProPhoto and default primaries
|
||||
p[1] = 0.2653;
|
||||
p[2] = 0.1596;
|
||||
p[3] = 0.8404;
|
||||
p[4] = 0.0366;
|
||||
p[5] = 0.0001;
|
||||
} else {
|
||||
p[0] = 0.7347; //default primaries always unused
|
||||
p[1] = 0.2653;
|
||||
p[2] = 0.1596;
|
||||
p[3] = 0.8404;
|
||||
p[4] = 0.0366;
|
||||
p[5] = 0.0001;
|
||||
}
|
||||
|
||||
if (slpos == 0) {
|
||||
slpos = eps;
|
||||
}
|
||||
|
||||
GammaValues g_a; //gamma parameters
|
||||
int mode = 0;
|
||||
Color::calcGamma(pwr, ts, mode, g_a); // call to calcGamma with selected gamma and slope : return parameters for LCMS2
|
||||
|
||||
cmsCIExyY xyD;
|
||||
|
||||
cmsCIExyYTRIPLE Primaries = {
|
||||
{p[0], p[1], 1.0}, // red
|
||||
{p[2], p[3], 1.0}, // green
|
||||
{p[4], p[5], 1.0} // blue
|
||||
};
|
||||
|
||||
cmsToneCurve* GammaTRC[3];
|
||||
cmsFloat64Number gammaParams[7];
|
||||
gammaParams[4] = g_a[3] * ts;
|
||||
gammaParams[0] = gampos;
|
||||
gammaParams[1] = 1. / (1.0 + g_a[4]);
|
||||
gammaParams[2] = g_a[4] / (1.0 + g_a[4]);
|
||||
gammaParams[3] = 1. / slpos;
|
||||
gammaParams[5] = 0.0;
|
||||
gammaParams[6] = 0.0;
|
||||
// printf("ga0=%f ga1=%f ga2=%f ga3=%f ga4=%f\n", ga0, ga1, ga2, ga3, ga4);
|
||||
|
||||
// 7 parameters for smoother curves
|
||||
cmsWhitePointFromTemp(&xyD, (double)temp);
|
||||
if (profile == "ACESp0") {
|
||||
xyD = {0.32168, 0.33767, 1.0};//refine white point to avoid differences
|
||||
}
|
||||
|
||||
GammaTRC[0] = GammaTRC[1] = GammaTRC[2] = cmsBuildParametricToneCurve(NULL, five, gammaParams);//5 = more smoother than 4
|
||||
oprofdef = cmsCreateRGBProfile(&xyD, &Primaries, GammaTRC);
|
||||
cmsFreeToneCurve(GammaTRC[0]);
|
||||
//primaries for 10 working profiles ==> output profiles
|
||||
if (profile == "WideGamut") {
|
||||
p[0] = 0.7350; //Widegamut primaries
|
||||
p[1] = 0.2650;
|
||||
p[2] = 0.1150;
|
||||
p[3] = 0.8260;
|
||||
p[4] = 0.1570;
|
||||
p[5] = 0.0180;
|
||||
} else if (profile == "Adobe RGB") {
|
||||
p[0] = 0.6400; //Adobe primaries
|
||||
p[1] = 0.3300;
|
||||
p[2] = 0.2100;
|
||||
p[3] = 0.7100;
|
||||
p[4] = 0.1500;
|
||||
p[5] = 0.0600;
|
||||
temp = ColorTemp::D65;
|
||||
} else if (profile == "sRGB") {
|
||||
p[0] = 0.6400; // sRGB primaries
|
||||
p[1] = 0.3300;
|
||||
p[2] = 0.3000;
|
||||
p[3] = 0.6000;
|
||||
p[4] = 0.1500;
|
||||
p[5] = 0.0600;
|
||||
temp = ColorTemp::D65;
|
||||
} else if (profile == "BruceRGB") {
|
||||
p[0] = 0.6400; // Bruce primaries
|
||||
p[1] = 0.3300;
|
||||
p[2] = 0.2800;
|
||||
p[3] = 0.6500;
|
||||
p[4] = 0.1500;
|
||||
p[5] = 0.0600;
|
||||
temp = ColorTemp::D65;
|
||||
} else if (profile == "Beta RGB") {
|
||||
p[0] = 0.6888; // Beta primaries
|
||||
p[1] = 0.3112;
|
||||
p[2] = 0.1986;
|
||||
p[3] = 0.7551;
|
||||
p[4] = 0.1265;
|
||||
p[5] = 0.0352;
|
||||
} else if (profile == "BestRGB") {
|
||||
p[0] = 0.7347; // Best primaries
|
||||
p[1] = 0.2653;
|
||||
p[2] = 0.2150;
|
||||
p[3] = 0.7750;
|
||||
p[4] = 0.1300;
|
||||
p[5] = 0.0350;
|
||||
} else if (profile == "Rec2020") {
|
||||
p[0] = 0.7080; // Rec2020 primaries
|
||||
p[1] = 0.2920;
|
||||
p[2] = 0.1700;
|
||||
p[3] = 0.7970;
|
||||
p[4] = 0.1310;
|
||||
p[5] = 0.0460;
|
||||
temp = ColorTemp::D65;
|
||||
} else if (profile == "ACESp0") {
|
||||
p[0] = 0.7347; // ACES P0 primaries
|
||||
p[1] = 0.2653;
|
||||
p[2] = 0.0000;
|
||||
p[3] = 1.0;
|
||||
p[4] = 0.0001;
|
||||
p[5] = -0.0770;
|
||||
temp = ColorTemp::D60;
|
||||
} else if (profile == "ACESp1") {
|
||||
p[0] = 0.713; // ACES P1 primaries
|
||||
p[1] = 0.293;
|
||||
p[2] = 0.165;
|
||||
p[3] = 0.830;
|
||||
p[4] = 0.128;
|
||||
p[5] = 0.044;
|
||||
temp = ColorTemp::D60;
|
||||
} else if (profile == "ProPhoto") {
|
||||
p[0] = 0.7347; //ProPhoto and default primaries
|
||||
p[1] = 0.2653;
|
||||
p[2] = 0.1596;
|
||||
p[3] = 0.8404;
|
||||
p[4] = 0.0366;
|
||||
p[5] = 0.0001;
|
||||
} else {
|
||||
p[0] = 0.7347; //default primaries always unused
|
||||
p[1] = 0.2653;
|
||||
p[2] = 0.1596;
|
||||
p[3] = 0.8404;
|
||||
p[4] = 0.0366;
|
||||
p[5] = 0.0001;
|
||||
}
|
||||
|
||||
if (slpos == 0) {
|
||||
slpos = eps;
|
||||
}
|
||||
|
||||
GammaValues g_a; //gamma parameters
|
||||
int mode = 0;
|
||||
Color::calcGamma(pwr, ts, mode, g_a); // call to calcGamma with selected gamma and slope : return parameters for LCMS2
|
||||
|
||||
cmsCIExyY xyD;
|
||||
|
||||
cmsCIExyYTRIPLE Primaries = {
|
||||
{p[0], p[1], 1.0}, // red
|
||||
{p[2], p[3], 1.0}, // green
|
||||
{p[4], p[5], 1.0} // blue
|
||||
};
|
||||
|
||||
cmsToneCurve* GammaTRC[3];
|
||||
cmsFloat64Number gammaParams[7];
|
||||
gammaParams[4] = g_a[3] * ts;
|
||||
gammaParams[0] = gampos;
|
||||
gammaParams[1] = 1. / (1.0 + g_a[4]);
|
||||
gammaParams[2] = g_a[4] / (1.0 + g_a[4]);
|
||||
gammaParams[3] = 1. / slpos;
|
||||
gammaParams[5] = 0.0;
|
||||
gammaParams[6] = 0.0;
|
||||
// printf("ga0=%f ga1=%f ga2=%f ga3=%f ga4=%f\n", ga0, ga1, ga2, ga3, ga4);
|
||||
|
||||
// 7 parameters for smoother curves
|
||||
cmsWhitePointFromTemp(&xyD, (double)temp);
|
||||
if (profile == "ACESp0") {
|
||||
xyD = {0.32168, 0.33767, 1.0};//refine white point to avoid differences
|
||||
}
|
||||
|
||||
GammaTRC[0] = GammaTRC[1] = GammaTRC[2] = cmsBuildParametricToneCurve(NULL, five, gammaParams);//5 = more smoother than 4
|
||||
const cmsHPROFILE oprofdef = cmsCreateRGBProfile(&xyD, &Primaries, GammaTRC);
|
||||
cmsFreeToneCurve(GammaTRC[0]);
|
||||
|
||||
if (oprofdef) {
|
||||
#pragma omp parallel for if (multiThread)
|
||||
|
||||
for (int i = 0; i < ch; i++) {
|
||||
float* rr = src->r(i);
|
||||
float* rg = src->g(i);
|
||||
float* rb = src->b(i);
|
||||
|
||||
float* xa = (float*)dst->r(i);
|
||||
float* ya = (float*)dst->g(i);
|
||||
float* za = (float*)dst->b(i);
|
||||
|
||||
for (int j = 0; j < cw; j++) {
|
||||
float r1 = rr[j];
|
||||
float g1 = rg[j];
|
||||
float b1 = rb[j];
|
||||
|
||||
xa[j] = toxyz[0][0] * r1 + toxyz[0][1] * g1 + toxyz[0][2] * b1;
|
||||
ya[j] = toxyz[1][0] * r1 + toxyz[1][1] * g1 + toxyz[1][2] * b1;
|
||||
za[j] = toxyz[2][0] * r1 + toxyz[2][1] * g1 + toxyz[2][2] * b1;
|
||||
}
|
||||
}
|
||||
|
||||
cmsUInt32Number flags = cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE;
|
||||
|
||||
|
||||
lcmsMutex->lock();
|
||||
cmsHPROFILE iprof = ICCStore::getInstance()->getXYZProfile();
|
||||
lcmsMutex->lock();
|
||||
// cmsHTRANSFORM hTransform = cmsCreateTransform(iprof, TYPE_RGB_16, oprofdef, TYPE_RGB_16, params->icm.outputIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE);
|
||||
cmsHTRANSFORM hTransform = cmsCreateTransform(iprof, TYPE_RGB_FLT, oprofdef, TYPE_RGB_FLT, params->icm.outputIntent, flags);
|
||||
lcmsMutex->unlock();
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel if (multiThread)
|
||||
#endif
|
||||
{
|
||||
AlignedBuffer<float> pBuf(cw * 3);
|
||||
|
||||
dst->ExecCMSTransform(hTransform);
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for schedule(dynamic, 16)
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < ch; i++) {
|
||||
float *p = pBuf.data;
|
||||
float* rr = src->r(i);
|
||||
float* rg = src->g(i);
|
||||
float* rb = src->b(i);
|
||||
|
||||
float* xa = (float*)dst->r(i);
|
||||
float* ya = (float*)dst->g(i);
|
||||
float* za = (float*)dst->b(i);
|
||||
|
||||
for (int j = 0; j < cw; j++) {
|
||||
float r1 = rr[j];
|
||||
float g1 = rg[j];
|
||||
float b1 = rb[j];
|
||||
|
||||
*(p++) = toxyz[0][0] * r1 + toxyz[0][1] * g1 + toxyz[0][2] * b1;
|
||||
*(p++) = toxyz[1][0] * r1 + toxyz[1][1] * g1 + toxyz[1][2] * b1;
|
||||
*(p++) = toxyz[2][0] * r1 + toxyz[2][1] * g1 + toxyz[2][2] * b1;
|
||||
}
|
||||
cmsDoTransform (hTransform, pBuf.data, pBuf.data, cw);
|
||||
p = pBuf.data;
|
||||
for (int x = 0; x < cw; x++) {
|
||||
*(xa++) = *(p++);
|
||||
*(ya++) = *(p++);
|
||||
*(za++) = *(p++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmsDeleteTransform(hTransform);
|
||||
if (normalizeOut) {
|
||||
dst->normalizeFloatTo65535();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user