[babl] CIE: Add conversion from "RGB float" to "CIE Lab float" and vice versa
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [babl] CIE: Add conversion from "RGB float" to "CIE Lab float" and vice versa
- Date: Sat, 9 Jan 2016 18:59:08 +0000 (UTC)
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]