[babl] extensions: Add "CIE LCH(ab) [alpha] float"
- From: Martin Nordholts <martinn src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [babl] extensions: Add "CIE LCH(ab) [alpha] float"
- Date: Sun, 2 Aug 2009 09:03:49 +0000 (UTC)
commit 12d5cc4c1bcfbf02c2b7d7f53270976df6102093
Author: Martin Nordholts <martinn src gnome org>
Date: Sun Aug 2 10:57:37 2009 +0200
extensions: Add "CIE LCH(ab) [alpha] float"
Add "CIE LCH(ab) float" and "CIE LCH(ab) alpha float" as babl formats
and implement conversions from/to RGBA float.
extensions/CIE.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 209 insertions(+), 0 deletions(-)
---
diff --git a/extensions/CIE.c b/extensions/CIE.c
index 6a8f18d..f6600b1 100644
--- a/extensions/CIE.c
+++ b/extensions/CIE.c
@@ -1,5 +1,6 @@
/* babl - dynamically extendable universal pixel conversion library.
* Copyright (C) 2005, �yvind Kolås.
+ * Copyright (C) 2009, Martin Nordholts
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,6 +24,8 @@
#include "babl.h"
#include "extensions/util.h"
+#define DEGREES_PER_RADIAN (180 / 3.14159265358979323846)
+#define RADIANS_PER_DEGREE (1 / DEGREES_PER_RADIAN)
int init (void);
@@ -49,6 +52,8 @@ components (void)
babl_component_new ("CIE L", NULL);
babl_component_new ("CIE a", "chroma", NULL);
babl_component_new ("CIE b", "chroma", NULL);
+ babl_component_new ("CIE C(ab)", "chroma", NULL);
+ babl_component_new ("CIE H(ab)", "chroma", NULL);
}
static void
@@ -68,6 +73,21 @@ models (void)
babl_component ("CIE b"),
babl_component ("A"),
NULL);
+
+ babl_model_new (
+ "name", "CIE LCH(ab)",
+ babl_component ("CIE L"),
+ babl_component ("CIE C(ab)"),
+ babl_component ("CIE H(ab)"),
+ NULL);
+
+ babl_model_new (
+ "name", "CIE LCH(ab) alpha",
+ babl_component ("CIE L"),
+ babl_component ("CIE C(ab)"),
+ babl_component ("CIE H(ab)"),
+ babl_component ("A"),
+ NULL);
}
/*********** cpercep.h ********* */
@@ -121,6 +141,15 @@ static void cpercep_space_to_rgb (double inr,
double *outg,
double *outb);
+static void ab_to_chab (double a,
+ double b,
+ double *C,
+ double *H);
+
+static void chab_to_ab (double C,
+ double H,
+ double *a,
+ double *b);
static long
@@ -229,6 +258,115 @@ laba_to_rgba (char *src,
return n;
}
+
+
+
+static long
+rgba_to_lchab (char *src,
+ char *dst,
+ long n)
+{
+ while (n--)
+ {
+ double red = ((double *) src)[0];
+ double green = ((double *) src)[1];
+ double blue = ((double *) src)[2];
+ double L, a, b, C, H;
+
+ cpercep_rgb_to_space (red, green, blue, &L, &a, &b);
+ ab_to_chab (a, b, &C, &H);
+
+ ((double *) dst)[0] = L;
+ ((double *) dst)[1] = C;
+ ((double *) dst)[2] = H;
+
+ src += sizeof (double) * 4;
+ dst += sizeof (double) * 3;
+ }
+ return n;
+}
+
+static long
+lchab_to_rgba (char *src,
+ char *dst,
+ long n)
+{
+ while (n--)
+ {
+ double L = ((double *) src)[0];
+ double C = ((double *) src)[1];
+ double H = ((double *) src)[2];
+ double a, b, red, green, blue;
+
+ chab_to_ab (C, H, &a, &b);
+ cpercep_space_to_rgb (L, a, b, &red, &green, &blue);
+
+ ((double *) dst)[0] = red;
+ ((double *) dst)[1] = green;
+ ((double *) dst)[2] = blue;
+ ((double *) dst)[3] = 1.0;
+
+ src += sizeof (double) * 3;
+ dst += sizeof (double) * 4;
+ }
+ return n;
+}
+
+
+static long
+rgba_to_lchaba (char *src,
+ char *dst,
+ long n)
+{
+ while (n--)
+ {
+ double red = ((double *) src)[0];
+ double green = ((double *) src)[1];
+ double blue = ((double *) src)[2];
+ double alpha = ((double *) src)[3];
+ double L, a, b, C, H;
+
+ cpercep_rgb_to_space (red, green, blue, &L, &a, &b);
+ ab_to_chab (a, b, &C, &H);
+
+ ((double *) dst)[0] = L;
+ ((double *) dst)[1] = C;
+ ((double *) dst)[2] = H;
+ ((double *) dst)[3] = alpha;
+
+ src += sizeof (double) * 4;
+ dst += sizeof (double) * 4;
+ }
+ return n;
+}
+
+static long
+lchaba_to_rgba (char *src,
+ char *dst,
+ long n)
+{
+ while (n--)
+ {
+ double L = ((double *) src)[0];
+ double C = ((double *) src)[1];
+ double H = ((double *) src)[2];
+ double alpha = ((double *) src)[3];
+ double a, b, red, green, blue;
+
+ chab_to_ab (C, H, &a, &b);
+ cpercep_space_to_rgb (L, a, b, &red, &green, &blue);
+
+ ((double *) dst)[0] = red;
+ ((double *) dst)[1] = green;
+ ((double *) dst)[2] = blue;
+ ((double *) dst)[3] = alpha;
+
+ src += sizeof (double) * 4;
+ dst += sizeof (double) * 4;
+ }
+ return n;
+}
+
static void
conversions (void)
{
@@ -257,6 +395,31 @@ conversions (void)
NULL
);
+ babl_conversion_new (
+ babl_model ("RGBA"),
+ babl_model ("CIE LCH(ab)"),
+ "linear", rgba_to_lchab,
+ NULL
+ );
+ babl_conversion_new (
+ babl_model ("CIE LCH(ab)"),
+ babl_model ("RGBA"),
+ "linear", lchab_to_rgba,
+ NULL
+ );
+ babl_conversion_new (
+ babl_model ("RGBA"),
+ babl_model ("CIE LCH(ab) alpha"),
+ "linear", rgba_to_lchaba,
+ NULL
+ );
+ babl_conversion_new (
+ babl_model ("CIE LCH(ab) alpha"),
+ babl_model ("RGBA"),
+ "linear", lchaba_to_rgba,
+ NULL
+ );
+
cpercep_init ();
}
@@ -307,6 +470,28 @@ formats (void)
babl_type ("CIE u16 ab"),
babl_component ("CIE b"),
NULL);
+
+
+ babl_format_new (
+ "name", "CIE LCH(ab) float",
+ babl_model ("CIE LCH(ab)"),
+
+ babl_type ("float"),
+ babl_component ("CIE L"),
+ babl_component ("CIE C(ab)"),
+ babl_component ("CIE H(ab)"),
+ NULL);
+
+ babl_format_new (
+ "name", "CIE LCH(ab) alpha float",
+ babl_model ("CIE LCH(ab) alpha"),
+
+ babl_type ("float"),
+ babl_component ("CIE L"),
+ babl_component ("CIE C(ab)"),
+ babl_component ("CIE H(ab)"),
+ babl_component ("A"),
+ NULL);
}
@@ -1107,6 +1292,30 @@ cpercep_space_to_rgb (double inr,
*outb = inb;
}
+static void
+ab_to_chab (double a,
+ double b,
+ double *C,
+ double *H)
+{
+ *C = sqrt (a * a + b * b);
+ *H = atan2 (b, a) * DEGREES_PER_RADIAN;
+
+ /* Keep H within the range 0-360 */
+ if (*H < 0.0)
+ *H += 360;
+}
+
+static void
+chab_to_ab (double C,
+ double H,
+ double *a,
+ double *b)
+{
+ *a = cos (H * RADIANS_PER_DEGREE) * C;
+ *b = sin (H * RADIANS_PER_DEGREE) * C;
+}
+
#if 0
/* EXPERIMENTAL SECTION */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]