diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index 3240f06b1..38cebd17a 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -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(wprof[0][0] / (dx * (normalizeIn ? 65535.0 : 1.0))), //I have suppressed / Color::D50x + static_cast(wprof[0][1] / (dx * (normalizeIn ? 65535.0 : 1.0))), + static_cast(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(wprof[1][0] / (normalizeIn ? 65535.0 : 1.0)), + static_cast(wprof[1][1] / (normalizeIn ? 65535.0 : 1.0)), + static_cast(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(wprof[2][0] / (dz * (normalizeIn ? 65535.0 : 1.0))), //I have suppressed / Color::D50z + static_cast(wprof[2][1] / (dz * (normalizeIn ? 65535.0 : 1.0))), + static_cast(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 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(); } - } }