Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mm2/Little-CMS.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarti Maria <marti.maria@littlecms.com>2022-09-20 18:46:04 +0300
committerMarti Maria <marti.maria@littlecms.com>2022-09-20 18:46:04 +0300
commit7ec90142c2cf63e99fb6d9f0993ddf6a30addf12 (patch)
treeb0d31fdcd5a692f218338cd867e52e483ca8143e
parentbe25a63be953dbfeef41cfec42550739ba74ea63 (diff)
Added a faster 32-bit float to 32-bit float RGB to Lab conversion
Another special case
-rw-r--r--plugins/fast_float/src/fast_float_tethra.c21
-rw-r--r--plugins/fast_float/testbed/fast_float_testbed.c128
2 files changed, 107 insertions, 42 deletions
diff --git a/plugins/fast_float/src/fast_float_tethra.c b/plugins/fast_float/src/fast_float_tethra.c
index ef4fccf..64e011a 100644
--- a/plugins/fast_float/src/fast_float_tethra.c
+++ b/plugins/fast_float/src/fast_float_tethra.c
@@ -254,10 +254,9 @@ cmsBool OptimizeCLUTRGBTransform(_cmsTransform2Fn* TransformFn,
if (T_BYTES(*InputFormat) != sizeof(cmsFloat32Number) ||
T_BYTES(*OutputFormat) != sizeof(cmsFloat32Number)) return FALSE;
- // Input has to be RGB, Output may be any but Lab
+ // Input has to be RGB
if (T_COLORSPACE(*InputFormat) != PT_RGB) return FALSE;
- if (T_COLORSPACE(*OutputFormat) == PT_Lab) return FALSE;
-
+
OriginalLut = *Lut;
ContextID = cmsGetPipelineContextID(OriginalLut);
@@ -286,6 +285,22 @@ cmsBool OptimizeCLUTRGBTransform(_cmsTransform2Fn* TransformFn,
cmsPipelineInsertStage(OriginalLut, cmsAT_END, percent);
}
+ else
+ // If output is Lab, add a conversion stage to get Lab values
+ if (T_COLORSPACE(*OutputFormat) == PT_Lab) {
+
+ static const cmsFloat64Number mat[] = { 100.0, 0, 0,
+ 0, 255.0, 0,
+ 0, 0, 255.0 };
+
+ static const cmsFloat64Number off[] = { 0, -128.0, -128.0 };
+
+ cmsStage* lab_fix = cmsStageAllocMatrix(ContextID, 3, 3, mat, off);
+ if (lab_fix == NULL) goto Error;
+
+ cmsPipelineInsertStage(OriginalLut, cmsAT_END, lab_fix);
+ }
+
// Resample the LUT
if (!cmsStageSampleCLutFloat(OptimizedCLUTmpe, XFormSampler, (void*)OriginalLut, 0)) goto Error;
diff --git a/plugins/fast_float/testbed/fast_float_testbed.c b/plugins/fast_float/testbed/fast_float_testbed.c
index b501151..f07c885 100644
--- a/plugins/fast_float/testbed/fast_float_testbed.c
+++ b/plugins/fast_float/testbed/fast_float_testbed.c
@@ -725,6 +725,55 @@ void CheckToFloatLab(void)
}
+
+
+static
+void CheckFloatToFloatLab(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_FLT, hLab, TYPE_Lab_FLT, INTENT_PERCEPTUAL, 0);
+ cmsHTRANSFORM xform = cmsCreateTransformTHR(Raw, hsRGB, TYPE_RGB_FLT, hLab, TYPE_Lab_FLT, INTENT_PERCEPTUAL, 0);
+
+ int r, g, b;
+ cmsCIELab Lab1, Lab2;
+ cmsFloat32Number rgb[3];
+ cmsFloat32Number Lab[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] = (cmsFloat32Number)r / 255.0f;
+ rgb[1] = (cmsFloat32Number)g / 255.0f;
+ rgb[2] = (cmsFloat32Number)b / 255.0f;
+
+ cmsDoTransform(xform_plugin, rgb, Lab, 1);
+ Lab1.L = Lab[0]; Lab1.a = Lab[1]; Lab1.b = Lab[2];
+ cmsDoTransform(xform, rgb, Lab, 1);
+ Lab2.L = Lab[0]; Lab2.a = Lab[1]; Lab2.b = Lab[2];
+
+ err = cmsDeltaE(&Lab1, &Lab2);
+ if (err > 0.5)
+ {
+ 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); cmsDeleteTransform(xform_plugin);
+ cmsCloseProfile(hsRGB); cmsCloseProfile(hLab);
+ cmsDeleteContext(Raw);
+ cmsDeleteContext(Plugin);
+
+}
// --------------------------------------------------------------------------------------------------
// A C C U R A C Y C H E C K S
// --------------------------------------------------------------------------------------------------
@@ -1093,45 +1142,46 @@ void CheckLab2Roundtrip(void)
static
void CheckConversionFloat(void)
{
- trace("Crash test.");
- TryAllValuesFloatAlpha(cmsOpenProfileFromFile("test5.icc", "r"), cmsOpenProfileFromFile("test0.icc", "r"), INTENT_PERCEPTUAL, FALSE);
-
- trace("..");
- TryAllValuesFloatAlpha(cmsOpenProfileFromFile("test5.icc", "r"), cmsOpenProfileFromFile("test0.icc", "r"), INTENT_PERCEPTUAL, TRUE);
- trace("Ok\n");
-
- trace("Crash (II) test.");
- TryAllValuesFloatAlpha(cmsOpenProfileFromFile("test0.icc", "r"), cmsOpenProfileFromFile("test0.icc", "r"), INTENT_PERCEPTUAL, FALSE);
- trace("..");
- TryAllValuesFloatAlpha(cmsOpenProfileFromFile("test0.icc", "r"), cmsOpenProfileFromFile("test0.icc", "r"), INTENT_PERCEPTUAL, TRUE);
- trace("Ok\n");
-
- 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...");
- TryAllValuesFloat(cmsOpenProfileFromFile("test5.icc", "r"), cmsOpenProfileFromFile("test0.icc", "r"), INTENT_PERCEPTUAL);
- trace("Ok\n");
-
- // CLUT should be as 16 bits or better
- trace("Checking accuracy of CLUT...");
- TryAllValuesFloatVs16(cmsOpenProfileFromFile("test5.icc", "r"), cmsOpenProfileFromFile("test3.icc", "r"), INTENT_PERCEPTUAL);
- trace("Ok\n");
-
- // Same profile should give same values (we test both methods)
- trace("Checking accuracy on same profile ...");
- TryAllValuesFloatVs16(cmsOpenProfileFromFile("test0.icc", "r"), cmsOpenProfileFromFile("test0.icc", "r"), INTENT_PERCEPTUAL);
- TryAllValuesFloat(cmsOpenProfileFromFile("test0.icc", "r"), cmsOpenProfileFromFile("test0.icc", "r"), INTENT_PERCEPTUAL);
- trace("Ok\n");
+ trace("Crash test.");
+ TryAllValuesFloatAlpha(cmsOpenProfileFromFile("test5.icc", "r"), cmsOpenProfileFromFile("test0.icc", "r"), INTENT_PERCEPTUAL, FALSE);
+
+ trace("..");
+ TryAllValuesFloatAlpha(cmsOpenProfileFromFile("test5.icc", "r"), cmsOpenProfileFromFile("test0.icc", "r"), INTENT_PERCEPTUAL, TRUE);
+ trace("Ok\n");
+
+ trace("Crash (II) test.");
+ TryAllValuesFloatAlpha(cmsOpenProfileFromFile("test0.icc", "r"), cmsOpenProfileFromFile("test0.icc", "r"), INTENT_PERCEPTUAL, FALSE);
+ trace("..");
+ TryAllValuesFloatAlpha(cmsOpenProfileFromFile("test0.icc", "r"), cmsOpenProfileFromFile("test0.icc", "r"), INTENT_PERCEPTUAL, TRUE);
+ trace("Ok\n");
+
+ 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();
+ CheckFloatToFloatLab();
+ trace("Ok\n");
+
+ // Matrix-shaper should be accurate
+ trace("Checking accuracy on Matrix-shaper...");
+ TryAllValuesFloat(cmsOpenProfileFromFile("test5.icc", "r"), cmsOpenProfileFromFile("test0.icc", "r"), INTENT_PERCEPTUAL);
+ trace("Ok\n");
+
+ // CLUT should be as 16 bits or better
+ trace("Checking accuracy of CLUT...");
+ TryAllValuesFloatVs16(cmsOpenProfileFromFile("test5.icc", "r"), cmsOpenProfileFromFile("test3.icc", "r"), INTENT_PERCEPTUAL);
+ trace("Ok\n");
+
+ // Same profile should give same values (we test both methods)
+ trace("Checking accuracy on same profile ...");
+ TryAllValuesFloatVs16(cmsOpenProfileFromFile("test0.icc", "r"), cmsOpenProfileFromFile("test0.icc", "r"), INTENT_PERCEPTUAL);
+ TryAllValuesFloat(cmsOpenProfileFromFile("test0.icc", "r"), cmsOpenProfileFromFile("test0.icc", "r"), INTENT_PERCEPTUAL);
+ trace("Ok\n");
}