From c07b7e363cd4ea188876b6aa8f0357c0f0b8d0cb Mon Sep 17 00:00:00 2001 From: Marti Maria Date: Tue, 7 Sep 2021 09:30:55 +0200 Subject: fix for bug #272 Lab8 is not suitable to be handled by a 8 bits tetrahedral interpolation due to its encoding. Added a check to prevent this optimization. Added test cases in test bed. --- plugins/fast_float/src/fast_8_tethra.c | 3 + plugins/fast_float/testbed/fast_float_testbed.c | 116 ++++++++++++++++++++++-- 2 files changed, 111 insertions(+), 8 deletions(-) (limited to 'plugins') diff --git a/plugins/fast_float/src/fast_8_tethra.c b/plugins/fast_float/src/fast_8_tethra.c index 048b43e..76091d4 100644 --- a/plugins/fast_float/src/fast_8_tethra.c +++ b/plugins/fast_float/src/fast_8_tethra.c @@ -364,6 +364,9 @@ cmsBool Optimize8BitRGBTransform(_cmsTransform2Fn* TransformFn, // Only on RGB if (T_COLORSPACE(*InputFormat) != PT_RGB) return FALSE; + // Lab8 is not suitable due to the encoding + if (T_COLORSPACE(*OutputFormat) == PT_Lab) return FALSE; + OriginalLut = *Lut; ContextID = cmsGetPipelineContextID(OriginalLut); diff --git a/plugins/fast_float/testbed/fast_float_testbed.c b/plugins/fast_float/testbed/fast_float_testbed.c index ff936b9..79b2276 100644 --- a/plugins/fast_float/testbed/fast_float_testbed.c +++ b/plugins/fast_float/testbed/fast_float_testbed.c @@ -621,6 +621,106 @@ void CheckUncommonValues(cmsHPROFILE hlcmsProfileIn, cmsHPROFILE hlcmsProfileOut } +static +void lab8toLab(cmsUInt8Number lab8[3], cmsCIELab* Lab) +{ + cmsUInt16Number lab16[3]; + + lab16[0] = FROM_8_TO_16(lab8[0]); + lab16[1] = FROM_8_TO_16(lab8[1]); + lab16[2] = FROM_8_TO_16(lab8[2]); + + cmsLabEncoded2Float(Lab, lab16); +} + +static +void CheckToEncodedLab(void) +{ + cmsContext Plugin = cmsCreateContext(cmsFastFloatExtensions(), NULL); + cmsContext Raw = cmsCreateContext(NULL, NULL); + + cmsHPROFILE hsRGB = cmsCreate_sRGBProfile(); + cmsHPROFILE hLab = cmsCreateLab4Profile(NULL); + + cmsHTRANSFORM xform_plugin = cmsCreateTransformTHR(Plugin, hsRGB, TYPE_RGB_8, hLab, TYPE_Lab_8, INTENT_PERCEPTUAL, 0); + cmsHTRANSFORM xform = cmsCreateTransformTHR(Raw, hsRGB, TYPE_RGB_8, hLab, TYPE_Lab_8, INTENT_PERCEPTUAL, 0); + + int r, g, b; + cmsCIELab Lab1, Lab2; + cmsUInt8Number rgb[3], lab1[3], lab2[3]; + double err; + + for (r=0; r < 256; r += 5) + for (g = 0; g < 256; g += 5) + for (b = 0; b < 256; b += 5) + { + rgb[0] = (cmsUInt8Number) r; rgb[1] = (cmsUInt8Number) g; rgb[2] = (cmsUInt8Number) b; + + cmsDoTransform(xform_plugin, rgb, lab1, 1); + cmsDoTransform(xform, rgb, lab2, 1); + + lab8toLab(lab1, &Lab1); + lab8toLab(lab2, &Lab2); + + err = cmsDeltaE(&Lab1, &Lab2); + if (err > 0.1) + { + trace("Error on lab encoded (%f, %f, %f) <> (% f, % f, % f)\n", + Lab1.L, Lab1.a, Lab1.b, Lab2.L, Lab2.a, Lab2.b); + } + } + + + cmsDeleteTransform(xform); + cmsCloseProfile(hsRGB); cmsCloseProfile(hLab); + cmsDeleteContext(Raw); + cmsDeleteContext(Plugin); + +} + + +static +void CheckToFloatLab(void) +{ + cmsContext Plugin = cmsCreateContext(cmsFastFloatExtensions(), NULL); + cmsContext Raw = cmsCreateContext(NULL, NULL); + + cmsHPROFILE hsRGB = cmsCreate_sRGBProfile(); + cmsHPROFILE hLab = cmsCreateLab4Profile(NULL); + + cmsHTRANSFORM xform_plugin = cmsCreateTransformTHR(Plugin, hsRGB, TYPE_RGB_8, hLab, TYPE_Lab_DBL, INTENT_PERCEPTUAL, 0); + cmsHTRANSFORM xform = cmsCreateTransformTHR(Raw, hsRGB, TYPE_RGB_8, hLab, TYPE_Lab_DBL, INTENT_PERCEPTUAL, 0); + + int r, g, b; + cmsCIELab Lab1, Lab2; + cmsUInt8Number rgb[3]; + double err; + + for (r = 0; r < 256; r += 10) + for (g = 0; g < 256; g += 10) + for (b = 0; b < 256; b += 10) + { + rgb[0] = (cmsUInt8Number)r; rgb[1] = (cmsUInt8Number)g; rgb[2] = (cmsUInt8Number)b; + + cmsDoTransform(xform_plugin, rgb, &Lab1, 1); + cmsDoTransform(xform, rgb, &Lab2, 1); + + err = cmsDeltaE(&Lab1, &Lab2); + if (err > 0.1) + { + trace("Error on lab encoded (%f, %f, %f) <> (% f, % f, % f)\n", + Lab1.L, Lab1.a, Lab1.b, Lab2.L, Lab2.a, Lab2.b); + } + } + + + cmsDeleteTransform(xform); + cmsCloseProfile(hsRGB); cmsCloseProfile(hLab); + cmsDeleteContext(Raw); + cmsDeleteContext(Plugin); + +} + // -------------------------------------------------------------------------------------------------- // A C C U R A C Y C H E C K S // -------------------------------------------------------------------------------------------------- @@ -1001,16 +1101,17 @@ void CheckConversionFloat(void) TryAllValuesFloatAlpha(cmsOpenProfileFromFile("test0.icc", "r"), cmsOpenProfileFromFile("test0.icc", "r"), INTENT_PERCEPTUAL, TRUE); trace("Ok\n"); - - /* - * FIXME!! - */ + trace("Crash (III) test."); CheckUncommonValues(cmsOpenProfileFromFile("test5.icc", "r"), cmsOpenProfileFromFile("test3.icc", "r"), INTENT_PERCEPTUAL); trace(".."); CheckUncommonValues(cmsOpenProfileFromFile("test5.icc", "r"), cmsOpenProfileFromFile("test0.icc", "r"), INTENT_PERCEPTUAL); trace("Ok\n"); - + + trace("Checking conversion to Lab..."); + CheckToEncodedLab(); + CheckToFloatLab(); + trace("Ok\n"); // Matrix-shaper should be accurate trace("Checking accuracy on Matrix-shaper..."); @@ -2224,8 +2325,8 @@ void TestGrayTransformPerformance1() // The harness test int main() { - trace("FastFloating point extensions testbed - 1.3\n"); - trace("Copyright (c) 1998-2020 Marti Maria Saguer, all rights reserved\n"); + trace("FastFloating point extensions testbed - 1.4\n"); + trace("Copyright (c) 1998-2021 Marti Maria Saguer, all rights reserved\n"); trace("\nInstalling error logger ... "); cmsSetLogErrorHandler(FatalErrorQuit); @@ -2235,7 +2336,6 @@ int main() cmsPlugin(cmsFastFloatExtensions()); trace("done.\n\n"); - CheckComputeIncrements(); // 15 bit functionality -- cgit v1.2.3