[babl] CIE: Add conversion from "RGB float" to "CIE Lab float" and vice versa



commit b4535d6efc205c790c8263ba3f9568f9b442027d
Author: Debarshi Ray <debarshir gnome org>
Date:   Sat Jan 9 19:41:29 2016 +0100

    CIE: Add conversion from "RGB float" to "CIE Lab float" and vice versa
    
    Conversions from "RGB float" to "CIE Lab float" are 10 times slower
    without this. One use case is passing a "RGB float" buffer to a
    saturation operation that works in the "CIE Lab" colour space.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=760310

 extensions/CIE.c |   84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 84 insertions(+), 0 deletions(-)
---
diff --git a/extensions/CIE.c b/extensions/CIE.c
index a09ef06..2e0aca2 100644
--- a/extensions/CIE.c
+++ b/extensions/CIE.c
@@ -468,6 +468,42 @@ Yaf_to_Laf (float *src,
 }
 
 static long
+rgbf_to_Labf (float *src,
+              float *dst,
+              long   samples)
+{
+  long n = samples;
+
+  while (n--)
+    {
+      float r = src[0];
+      float g = src[1];
+      float b = src[2];
+
+      float xr = 0.43603516f / D50_WHITE_REF_X * r + 0.38511658f / D50_WHITE_REF_X * g + 0.14305115f / 
D50_WHITE_REF_X * b;
+      float yr = 0.22248840f / D50_WHITE_REF_Y * r + 0.71690369f / D50_WHITE_REF_Y * g + 0.06060791f / 
D50_WHITE_REF_Y * b;
+      float zr = 0.01391602f / D50_WHITE_REF_Z * r + 0.09706116f / D50_WHITE_REF_Z * g + 0.71392822f / 
D50_WHITE_REF_Z * b;
+
+      float fx = xr > LAB_EPSILON ? cbrtf (xr) : (LAB_KAPPA * xr + 16.0f) / 116.0f;
+      float fy = yr > LAB_EPSILON ? cbrtf (yr) : (LAB_KAPPA * yr + 16.0f) / 116.0f;
+      float fz = zr > LAB_EPSILON ? cbrtf (zr) : (LAB_KAPPA * zr + 16.0f) / 116.0f;
+
+      float L = 116.0f * fy - 16.0f;
+      float A = 500.0f * (fx - fy);
+      float B = 200.0f * (fy - fz);
+
+      dst[0] = L;
+      dst[1] = A;
+      dst[2] = B;
+
+      src += 3;
+      dst += 3;
+    }
+
+  return samples;
+}
+
+static long
 rgbaf_to_Labaf (float *src,
                 float *dst,
                 long   samples)
@@ -506,6 +542,42 @@ rgbaf_to_Labaf (float *src,
 }
 
 static long
+Labf_to_rgbf (float *src,
+                float *dst,
+                long   samples)
+{
+  long n = samples;
+
+  while (n--)
+    {
+      float L = src[0];
+      float A = src[1];
+      float B = src[2];
+
+      float fy = (L + 16.0f) / 116.0f;
+      float fx = fy + A / 500.0f;
+      float fz = fy - B / 200.0f;
+
+      float yr = L > LAB_KAPPA * LAB_EPSILON ? cubef (fy) : L / LAB_KAPPA;
+      float xr = cubef (fx) > LAB_EPSILON ? cubef (fx) : (fx * 116.0f - 16.0f) / LAB_KAPPA;
+      float zr = cubef (fz) > LAB_EPSILON ? cubef (fz) : (fz * 116.0f - 16.0f) / LAB_KAPPA;
+
+      float r =  3.134274799724f * D50_WHITE_REF_X * xr -1.617275708956f * D50_WHITE_REF_Y * yr 
-0.490724283042f * D50_WHITE_REF_Z * zr;
+      float g = -0.978795575994f * D50_WHITE_REF_X * xr +1.916161689117f * D50_WHITE_REF_Y * yr 
+0.033453331711f * D50_WHITE_REF_Z * zr;
+      float b =  0.071976988401f * D50_WHITE_REF_X * xr -0.228984974402f * D50_WHITE_REF_Y * yr 
+1.405718224383f * D50_WHITE_REF_Z * zr;
+
+      dst[0] = r;
+      dst[1] = g;
+      dst[2] = b;
+
+      src += 3;
+      dst += 3;
+    }
+
+  return samples;
+}
+
+static long
 Labaf_to_rgbaf (float *src,
                 float *dst,
                 long   samples)
@@ -571,6 +643,18 @@ conversions (void)
     NULL
   );
   babl_conversion_new (
+    babl_format ("RGB float"),
+    babl_format ("CIE Lab float"),
+    "linear", rgbf_to_Labf,
+    NULL
+  );
+  babl_conversion_new (
+    babl_format ("CIE Lab float"),
+    babl_format ("RGB float"),
+    "linear", Labf_to_rgbf,
+    NULL
+  );
+  babl_conversion_new (
     babl_format ("RGBA float"),
     babl_format ("CIE Lab alpha float"),
     "linear", rgbaf_to_Labaf,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]