[babl] babl: add icc generator



commit a7dd7103b14a2fd342835b4ca119e89b93cb6969
Author: Øyvind Kolås <pippin gimp org>
Date:   Tue Aug 22 12:23:02 2017 +0200

    babl: add icc generator
    
    Add API to generate concise ICC profiles in memory from babl-spaces, seems
    complete apart for tRCs.

 babl/babl-icc.c      |  378 ++++++++++++++++++++++++++++++++++++++++----------
 babl/babl-internal.h |    1 +
 babl/babl-space.c    |   69 ++++-----
 babl/babl-space.h    |    2 +-
 babl/babl.h          |    1 +
 tools/Makefile.am    |    2 +-
 6 files changed, 340 insertions(+), 113 deletions(-)
---
diff --git a/babl/babl-icc.c b/babl/babl-icc.c
index 2bc15b6..b978753 100644
--- a/babl/babl-icc.c
+++ b/babl/babl-icc.c
@@ -34,7 +34,28 @@ typedef struct {
   uint16_t fraction;
 } u8f8_t;
 
-static int load_u8 (const char *icc, int length, int offset)
+typedef struct {
+  char str[5];
+} sign_t;
+
+#define icc_write(type, offset, value)  write_##type(icc,length,offset,value)
+#define icc_read(type, offset)          read_##type(icc,length,offset)
+
+static void write_u8 (char *icc, int length, int offset, uint8_t value)
+{
+  if (offset < 0 || offset > length)
+    return;
+  *(uint8_t*) (&icc[offset]) = value;
+}
+
+static void write_s8 (char *icc, int length, int offset, int8_t value)
+{
+  if (offset < 0 || offset > length)
+    return;
+  *(int8_t*) (&icc[offset]) = value;
+}
+
+static int read_u8 (const char *icc, int length, int offset)
 {
 /* all reading functions take both the char *pointer and the length of the
  * buffer, and all reads thus gets protected by this condition.
@@ -45,7 +66,7 @@ static int load_u8 (const char *icc, int length, int offset)
   return *(uint8_t*) (&icc[offset]);
 }
 
-static int load_s8 (const char *icc, int length, int offset)
+static int read_s8 (const char *icc, int length, int offset)
 {
   if (offset < 0 || offset > length)
     return 0;
@@ -53,29 +74,55 @@ static int load_s8 (const char *icc, int length, int offset)
   return *(int8_t*) (&icc[offset]);
 }
 
-static int16_t load_u1f15 (const char *icc, int length, int offset)
+static void write_s16 (char *icc, int length, int offset, int16_t value)
+{
+  write_s8 (icc, length, offset + 0, value >> 8);
+  write_u8 (icc, length, offset + 1, value & 0xff);
+}
+
+static int16_t read_s16 (const char *icc, int length, int offset)
+{
+  return icc_read (u8, offset + 1) +
+         (read_s8 (icc, length, offset + 0) << 8);
+}
+
+static uint16_t read_u16 (const char *icc, int length, int offset)
 {
-  return load_u8 (icc, length, offset + 1) +
-         (load_s8 (icc, length, offset + 0) << 8);
+  return icc_read (u8, offset + 1) +
+         (icc_read (u8, offset + 0) << 8);
 }
 
-static uint16_t load_u16 (const char *icc, int length, int offset)
+static void write_u16 (char *icc, int length, int offset, uint16_t value)
 {
-  return load_u8 (icc, length, offset + 1) +
-         (load_u8 (icc, length, offset + 0) << 8);
+  write_u8 (icc, length, offset + 0, value >> 8);
+  write_u8 (icc, length, offset + 1, value & 0xff);
 }
 
-static u8f8_t load_u8f8_ (const char *icc, int length, int offset)
+static u8f8_t read_u8f8_ (const char *icc, int length, int offset)
 {
-  u8f8_t ret ={load_u8 (icc, length, offset),
-               load_u8 (icc, length, offset + 1)};
+  u8f8_t ret ={icc_read (u8, offset),
+               icc_read (u8, offset + 1)};
   return ret;
 }
 
-static s15f16_t load_s15f16_ (const char *icc, int length, int offset)
+static s15f16_t read_s15f16_ (const char *icc, int length, int offset)
 {
-  s15f16_t ret ={load_u1f15 (icc, length, offset),
-                 load_u16 (icc, length, offset + 2)};
+  s15f16_t ret ={icc_read (s16, offset),
+                 icc_read (u16, offset + 2)};
+  return ret;
+}
+
+static void write_s15f16_ (char *icc, int length, int offset, s15f16_t val)
+{
+  icc_write (s16, offset, val.integer),
+  icc_write (u16, offset + 2, val.fraction);
+}
+
+static s15f16_t d_to_s15f16 (double value)
+{
+  s15f16_t ret;
+  ret.integer = floor (value);
+  ret.fraction = fmod(value, 1.0) * 65535.999;
   return ret;
 }
 
@@ -89,14 +136,19 @@ static double u8f8_to_d (u8f8_t fix)
   return fix.integer + fix.fraction / 255.0;
 }
 
-static double load_s15f16 (const char *icc, int length, int offset)
+static void write_s15f16 (char *icc, int length, int offset, double value)
+{
+   write_s15f16_ (icc, length, offset, d_to_s15f16 (value));
+}
+
+static double read_s15f16 (const char *icc, int length, int offset)
 {
-  return s15f16_to_d (load_s15f16_ (icc, length, offset));
+  return s15f16_to_d (read_s15f16_ (icc, length, offset));
 }
 
-static double load_u8f8 (const char *icc, int length, int offset)
+static double read_u8f8 (const char *icc, int length, int offset)
 {
-  return u8f8_to_d (load_u8f8_ (icc, length, offset));
+  return u8f8_to_d (read_u8f8_ (icc, length, offset));
 }
 
 static inline void print_u8f8 (u8f8_t fix)
@@ -143,22 +195,47 @@ static inline void print_s15f16 (s15f16_t fix)
   }
 }
 
-static uint32_t load_u32 (const char *icc, int length, int offset)
+static void write_u32 (char *icc,
+                      int length,
+                      int offset,
+                      uint32_t value)
+{
+  int i;
+  for (i = 0; i < 4; i ++)
+  {
+    write_u8 (icc, length, offset + i,
+                  (value & 0xff000000) >> 24
+                  );
+    value <<= 8;
+  }
+}
+
+static uint32_t read_u32 (const char *icc, int length, int offset)
 {
-  return load_u8 (icc, length, offset + 3) +
-         (load_u8 (icc, length, offset + 2) << 8) +
-         (load_u8 (icc, length, offset + 1) << 16) +
-         (load_u8 (icc, length, offset + 0) << 24);
+  return icc_read (u8, offset + 3) +
+         (icc_read (u8, offset + 2) << 8) +
+         (icc_read (u8, offset + 1) << 16) +
+         (icc_read (u8, offset + 0) << 24);
 }
 
-static void load_sign (const char *icc, int length,
+static sign_t read_sign (const char *icc, int length,
+                         int offset)
+{
+  sign_t ret;
+  ret.str[0]=icc_read (u8, offset);
+  ret.str[1]=icc_read (u8, offset + 1);
+  ret.str[2]=icc_read (u8, offset + 2);
+  ret.str[3]=icc_read (u8, offset + 3);
+  ret.str[4]=0;
+  return ret;
+}
+
+static void write_sign (char *icc, int length,
                        int offset, char *sign)
 {
-  sign[0]=load_u8(icc, length, offset);
-  sign[1]=load_u8(icc, length, offset + 1);
-  sign[2]=load_u8(icc, length, offset + 2);
-  sign[3]=load_u8(icc, length, offset + 3);
-  sign[4]=0;
+  int i;
+  for (i = 0; i < 4; i ++)
+    icc_write (u8, offset + i, sign[i]);
 }
 
 /* looks up offset and length for a specific icc tag
@@ -166,19 +243,18 @@ static void load_sign (const char *icc, int length,
 static int icc_tag (const char *icc, int length,
                     const char *tag, int *offset, int *el_length)
 {
-  int tag_count = load_u32 (icc, length, TAG_COUNT_OFF);
+  int tag_count = icc_read (u32, TAG_COUNT_OFF);
   int t;
 
   for (t =  0; t < tag_count; t++)
   {
-     char tag_signature[5];
-     load_sign (icc, length, TAG_COUNT_OFF + 4 + 12 * t, tag_signature);
-     if (!strcmp (tag_signature, tag))
+     sign_t sign = icc_read (sign, TAG_COUNT_OFF + 4 + 12 * t);
+     if (!strcmp (sign.str, tag))
      {
         if (offset)
-          *offset = load_u32 (icc, length, TAG_COUNT_OFF + 4 + 12* t + 4);
+          *offset = icc_read (u32, TAG_COUNT_OFF + 4 + 12* t + 4);
         if (el_length)
-          *el_length = load_u32 (icc, length, TAG_COUNT_OFF + 4 + 12* t + 4*2);
+          *el_length = icc_read (u32, TAG_COUNT_OFF + 4 + 12* t + 4*2);
         return 1;
      }
   }
@@ -191,7 +267,7 @@ static const Babl *babl_trc_from_icc (const char *icc,
 {
   int offset = 0;
   {
-    int count = load_u32 (icc, length, offset + 8);
+    int count = icc_read (u32, offset + 8);
     int i;
     {
       if (count == 0)
@@ -200,7 +276,7 @@ static const Babl *babl_trc_from_icc (const char *icc,
       }
       else if (count == 1)
       {
-        return babl_trc_gamma (load_u8f8 (icc, length, offset + 12));
+        return babl_trc_gamma (icc_read (u8f8, offset + 12));
       }
       else
       {
@@ -211,8 +287,7 @@ static const Babl *babl_trc_from_icc (const char *icc,
 
         for (i = 0; i < count && i < 10; i ++)
         {
-          fprintf (stdout, "%i=%i ", i, load_u16 (icc, length,
-                                                  offset + 12 + i * 2));
+          fprintf (stdout, "%i=%i ", i, icc_read (u16, offset + 12 + i * 2));
           if (i % 7 == 0)
             fprintf (stdout, "\n");
         }
@@ -222,15 +297,167 @@ static const Babl *babl_trc_from_icc (const char *icc,
   return NULL;
 }
 
-const char *babl_space_rgb_to_icc (const Babl *space, int *ret_length);
-const char *babl_space_rgb_to_icc (const Babl *space, int *ret_length)
+
+const char *babl_space_rgb_to_icc (const Babl *babl, int *ret_length)
 {
-  static char icc[4096];
-  int length=0;
+  const BablSpace *space = &babl->space;
+  static char icc[8192];
+  int length=4095;
   icc[length]=0;
 
+#if 1
+  icc_write (s8, 8,-2);
+  assert (icc_read (s8, 8) == -2);
+  icc_write (s8, 8, 3);     // ICC verison
+  assert (icc_read (s8, 8) == 3);
+
+  icc_write (u8, 8, 2);     // ICC verison
+  assert (icc_read (u8, 8) == 2);
+
+  icc_write (u16, 8, 3);     // ICC verison
+  assert (icc_read (u16, 8) == 3);
+
+  icc_write (s16, 8, -3);     // ICC verison
+  assert (icc_read (s16, 8) == -3);
+
+  icc_write (s16, 8, 9);     // ICC verison
+  assert (icc_read (s16, 8) == 9);
+
+  icc_write (u32, 8, 4);     // ICC verison
+  assert (icc_read (u32, 8) == 4);
+#endif
+
+  icc_write (sign, 4, "babl");     // ICC verison
+  icc_write (u8, 8, 2);     // ICC verison
+  icc_write (u8, 9, 0x20);  // 2.2 for now..
+  icc_write (u32,64, 0);    // rendering intent
+
+  icc_write (s15f16,68, 0.96421); // Illuminant
+  icc_write (s15f16,72, 1.0);
+  icc_write (s15f16,76, 0.82491);
+
+  icc_write (sign, 80, "babl"); // creator
+
+  icc_write (sign, 12, "mntr");
+  icc_write (sign, 16, "RGB ");
+  icc_write (sign, 20, "XYZ ");
+
+  icc_write (u16, 24, 2017); // babl profiles
+  icc_write (u16, 26, 8);    // should
+  icc_write (u16, 28, 21);   // use a fixed
+  icc_write (u16, 30, 2);    // date
+  icc_write (u16, 32, 25);   // that gets updated
+  icc_write (u16, 34, 23);   // when the generator
+  icc_write (u16, 34, 23);   // when the generator
+
+  icc_write (sign, 36, "acsp"); // changes
 
 
+  {
+    int headpos = 0;
+    int tags;
+    int o, no;
+    int p = 0;
+    int psize = 0;
+
+    tags = 10;
+    no = o = 128 + 4 + 12 * tags;
+
+    icc_write (u32,  128, tags);
+#define ALLOC(tag, size) \
+    no+=((4-o)%4);o = no;psize = size;\
+    icc_write (sign, 128 + 4 + 4 * headpos++, tag);\
+    icc_write (u32,  128 + 4 + 4 * headpos++, o);\
+    icc_write (u32,  128 + 4 + 4 * headpos++, size);\
+    p = no;\
+    no+=size;
+#define REALLOC(tag) \
+    icc_write (sign, 128 + 4 + 4 * headpos++, tag);\
+    icc_write (u32,  128 + 4 + 4 * headpos++, p); \
+    icc_write (u32,  128 + 4 + 4 * headpos++, psize);
+
+    ALLOC("wtpt", 20);
+    icc_write (sign,o, "XYZ ");
+    icc_write (u32, o + 4, 0);
+    icc_write (s15f16, o + 8, space->whitepoint[0]);
+    icc_write (s15f16, o + 12, space->whitepoint[1]);
+    icc_write (s15f16, o + 16, space->whitepoint[2]);
+
+    ALLOC("rXYZ", 20);
+    icc_write (sign,o, "XYZ ");
+    icc_write (u32, o + 4, 0);
+    icc_write (s15f16, o + 8,  space->RGBtoXYZ[0]);
+    icc_write (s15f16, o + 12, space->RGBtoXYZ[3]);
+    icc_write (s15f16, o + 16, space->RGBtoXYZ[6]);
+
+    ALLOC("gXYZ", 20);
+    icc_write (sign,o, "XYZ ");
+    icc_write (u32, o + 4, 0);
+    icc_write (s15f16, o + 8,  space->RGBtoXYZ[1]);
+    icc_write (s15f16, o + 12, space->RGBtoXYZ[4]);
+    icc_write (s15f16, o + 16, space->RGBtoXYZ[7]);
+
+    ALLOC("bXYZ", 20);
+    icc_write (sign,o, "XYZ ");
+    icc_write (u32, o + 4, 0);
+    icc_write (s15f16, o + 8,  space->RGBtoXYZ[2]);
+    icc_write (s15f16, o + 12, space->RGBtoXYZ[5]);
+    icc_write (s15f16, o + 16, space->RGBtoXYZ[8]);
+
+    ALLOC("rTRC", 14);
+    icc_write (sign,o, "curv");
+    icc_write (u32, o + 4, 0);
+    icc_write (u32, o + 8, 1);
+    icc_write (u16, o + 12, 334);
+
+    if (space->trc[0] == space->trc[1] &&
+        space->trc[0] == space->trc[2])
+    {
+      REALLOC("gTRC");
+      REALLOC("bTRC");
+    }
+    else
+    {
+      ALLOC("gTRC", 14);
+      icc_write (sign,o, "curv");
+      icc_write (u32, o + 4, 0);
+      icc_write (u32, o + 8, 1); /* forcing a linear curve */
+      ALLOC("bTRC", 14);
+      icc_write (sign,o, "curv");
+      icc_write (u32, o + 4, 0);
+      icc_write (u32, o + 8, 1); /* forcing a linear curve */
+    }
+
+    {
+      char str[128];
+      int i;
+      sprintf (str, "babl");
+      ALLOC("desc", 30 + strlen (str) + 1);
+      icc_write (sign,o,"desc");
+      icc_write (u32, o + 4, 0);
+      icc_write (u32, o + 8, strlen(str));
+      for (i = 0; str[i]; i++)
+        icc_write (u8, o + 12 + i, str[i]);
+      icc_write (u8, o + 12 + i, 0);
+
+      REALLOC("dmnd");
+    }
+
+    {
+      char str[128];
+      int i;
+      sprintf (str, "CC0/public domain");
+      ALLOC("cprt", 8 + strlen (str) + 1);
+      icc_write (sign,o, "text");
+      icc_write (u32, o + 4, 0);
+      for (i = 0; str[i]; i++)
+        icc_write (u8, o + 8 + i, str[i]);
+    }
+
+    icc_write (u32, 0, no + 3);
+    length = no + 3;
+  }
+
   if (ret_length)
     *ret_length = length;
   return icc;
@@ -241,13 +468,12 @@ babl_space_rgb_icc (const char *icc,
                     int         length,
                     char      **error)
 {
-  int  profile_size     = load_u32 (icc, length, 0);
-  int  icc_ver_major    = load_u8 (icc, length, 8);
+  int  profile_size     = icc_read (u32, 0);
+  int  icc_ver_major    = icc_read (u8, 8);
   const Babl *trc_red   = NULL;
   const Babl *trc_green = NULL;
   const Babl *trc_blue  = NULL;
-  char profile_class[5];
-  char color_space[5];
+  sign_t profile_class, color_space;
 
   if (profile_size != length)
   {
@@ -259,14 +485,14 @@ babl_space_rgb_icc (const char *icc,
     *error = "only ICC v2 profiles supported";
     return NULL;
   }
-  load_sign (icc, length, 12, profile_class);
-  if (strcmp (profile_class, "mntr"))
+  profile_class = icc_read (sign, 12);
+  if (strcmp (profile_class.str, "mntr"))
   {
     *error = "not a monitor-class profile";
     return NULL;
   }
-  load_sign (icc, length, 16, color_space);
-  if (strcmp (color_space, "RGB "))
+  color_space = icc_read (sign, 16);
+  if (strcmp (color_space.str, "RGB "))
   {
     *error = "not defining an RGB space";
     return NULL;
@@ -304,8 +530,8 @@ babl_space_rgb_icc (const char *icc,
      int channels, phosporant;
 
      icc_tag (icc, length, "chrm", &offset, &element_size);
-     channels   = load_u16 (icc, length, offset + 8);
-     phosporant = load_u16 (icc, length, offset + 10);
+     channels   = icc_read (u16, offset + 8);
+     phosporant = icc_read (u16, offset + 10);
 
      if (phosporant != 0)
      {
@@ -318,18 +544,18 @@ babl_space_rgb_icc (const char *icc,
        return NULL;
      }
 
-     red_x   = load_s15f16 (icc, length, offset + 12);
-     red_y   = load_s15f16 (icc, length, offset + 12 + 4);
-     green_x = load_s15f16 (icc, length, offset + 20);
-     green_y = load_s15f16 (icc, length, offset + 20 + 4);
-     blue_x  = load_s15f16 (icc, length, offset + 28);
-     blue_y  = load_s15f16 (icc, length, offset + 28 + 4);
+     red_x   = icc_read (s15f16, offset + 12);
+     red_y   = icc_read (s15f16, offset + 12 + 4);
+     green_x = icc_read (s15f16, offset + 20);
+     green_y = icc_read (s15f16, offset + 20 + 4);
+     blue_x  = icc_read (s15f16, offset + 28);
+     blue_y  = icc_read (s15f16, offset + 28 + 4);
 
      icc_tag (icc, length, "wtpt", &offset, &element_size);
      {
-       double wX = load_s15f16 (icc, length, offset + 8);
-       double wY = load_s15f16 (icc, length, offset + 8 + 4);
-       double wZ = load_s15f16 (icc, length, offset + 8 + 4 * 2);
+       double wX = icc_read (s15f16, offset + 8);
+       double wY = icc_read (s15f16, offset + 8 + 4);
+       double wZ = icc_read (s15f16, offset + 8 + 4 * 2);
 
        return babl_space_rgb_chromaticities (NULL,
                        wX / (wX + wY + wZ),
@@ -343,27 +569,35 @@ babl_space_rgb_icc (const char *icc,
   }
   else if (icc_tag (icc, length, "rXYZ", NULL, NULL) &&
            icc_tag (icc, length, "gXYZ", NULL, NULL) &&
-           icc_tag (icc, length, "bXYZ", NULL, NULL))
+           icc_tag (icc, length, "bXYZ", NULL, NULL) &&
+           icc_tag (icc, length, "wtpt", NULL, NULL))
   {
      int offset, element_size;
      double rx, gx, bx;
      double ry, gy, by;
      double rz, gz, bz;
 
+     double wX, wY, wZ;
+
      icc_tag (icc, length, "rXYZ", &offset, &element_size);
-     rx = load_s15f16 (icc, length, offset + 8 + 4 * 0);
-     ry = load_s15f16 (icc, length, offset + 8 + 4 * 1);
-     rz = load_s15f16 (icc, length, offset + 8 + 4 * 2);
+     rx = icc_read (s15f16, offset + 8 + 4 * 0);
+     ry = icc_read (s15f16, offset + 8 + 4 * 1);
+     rz = icc_read (s15f16, offset + 8 + 4 * 2);
      icc_tag (icc, length, "gXYZ", &offset, &element_size);
-     gx = load_s15f16 (icc, length, offset + 8 + 4 * 0);
-     gy = load_s15f16 (icc, length, offset + 8 + 4 * 1);
-     gz = load_s15f16 (icc, length, offset + 8 + 4 * 2);
+     gx = icc_read (s15f16, offset + 8 + 4 * 0);
+     gy = icc_read (s15f16, offset + 8 + 4 * 1);
+     gz = icc_read (s15f16, offset + 8 + 4 * 2);
      icc_tag (icc, length, "bXYZ", &offset, &element_size);
-     bx = load_s15f16 (icc, length, offset + 8 + 4 * 0);
-     by = load_s15f16 (icc, length, offset + 8 + 4 * 1);
-     bz = load_s15f16 (icc, length, offset + 8 + 4 * 2);
+     bx = icc_read (s15f16, offset + 8 + 4 * 0);
+     by = icc_read (s15f16, offset + 8 + 4 * 1);
+     bz = icc_read (s15f16, offset + 8 + 4 * 2);
+     icc_tag (icc, length, "wtpt", &offset, &element_size);
+     wX = icc_read (s15f16, offset + 8);
+     wY = icc_read (s15f16, offset + 8 + 4);
+     wZ = icc_read (s15f16, offset + 8 + 4 * 2);
 
      return babl_space_rgb_matrix (NULL,
+                wX, wY, wZ,
                 rx, gx, bx,
                 ry, gy, by,
                 rz, gz, bz,
diff --git a/babl/babl-internal.h b/babl/babl-internal.h
index 33132e6..b9c287e 100644
--- a/babl/babl-internal.h
+++ b/babl/babl-internal.h
@@ -396,5 +396,6 @@ const Babl *babl_space_from_icc (const char *icc,
                                  int         length,
                                  char      **error);
 
+const char *babl_space_rgb_to_icc (const Babl *space, int *ret_length);
 
 #endif
diff --git a/babl/babl-space.c b/babl/babl-space.c
index a4d695c..1512dad 100644
--- a/babl/babl-space.c
+++ b/babl/babl-space.c
@@ -145,6 +145,7 @@ babl_space (const char *name)
 
 const Babl *
 babl_space_rgb_matrix (const char *name,
+                       double wx, double wy, double wz,
                        double rx, double gx, double bx,
                        double ry, double gy, double by,
                        double rz, double gz, double bz,
@@ -166,6 +167,11 @@ babl_space_rgb_matrix (const char *name,
   space.xw = rz;
   space.yw = gz;
   space.pad = bz;
+
+  space.whitepoint[0] = wx;
+  space.whitepoint[1] = wy;
+  space.whitepoint[2] = wz;
+
   space.trc[0] = trc_red;
   space.trc[1] = trc_green?trc_green:trc_red;
   space.trc[2] = trc_blue?trc_blue:trc_red;
@@ -185,9 +191,17 @@ babl_space_rgb_matrix (const char *name,
     babl_log ("too many BablSpaces");
     return NULL;
   }
-  /* transplany matrixes */
-  babl_space_compute_matrices (&space_db[i]);
-  memcpy (space.RGBtoXYZ, &space.xr, sizeof (space.RGBtoXYZ));
+  /* transplant matrixes */
+  //babl_space_compute_matrices (&space_db[i]);
+  space.RGBtoXYZ[0] = rx;
+  space.RGBtoXYZ[1] = gx;
+  space.RGBtoXYZ[2] = bx;
+  space.RGBtoXYZ[3] = ry;
+  space.RGBtoXYZ[4] = gy;
+  space.RGBtoXYZ[5] = by;
+  space.RGBtoXYZ[6] = rz;
+  space.RGBtoXYZ[7] = gz;
+  space.RGBtoXYZ[8] = bz;
   babl_matrix_invert (space.RGBtoXYZ, space.XYZtoRGB);
 
   space_db[i]=space;
@@ -234,6 +248,10 @@ babl_space_rgb_chromaticities (const char *name,
   space.trc[1] = trc_green?trc_green:trc_red;
   space.trc[2] = trc_blue?trc_blue:trc_red;
 
+  space.whitepoint[0] = wx / wy;
+  space.whitepoint[1] = 1.0;
+  space.whitepoint[2] = (1.0 - wx - wy) / wy;
+
   for (i = 0; space_db[i].instance.class_type; i++)
   {
     int offset = ((char*)&space_db[i].xr) - (char*)(&space_db[i]);
@@ -277,42 +295,12 @@ babl_space_class_for_each (BablEachFunction each_fun,
 void
 babl_space_class_init (void)
 {
-  if (getenv ("BABL_RGB_OVERRIDE"))
-  {
-     /* added to be able to easily have the behavior of Elle Stones CCH fork of babl,
-      * configuring the working space through an environment variable should be easier
-      * than keeping compiled versions of CCH GIMP for different spaces.
-      */
-
-     char *override = getenv ("BABL_RGB_OVERRIDE");
-     if (strlen (override) < 5)
-       {
-          babl_space_rgb_chromaticities ("sRGB",
-                  0.3127,  0.3290, /* D65 */
-                  0.6400,  0.3300,
-                  0.3000,  0.6000,
-                  0.1500,  0.0600,
-                  babl_trc("linear"), NULL, NULL);
-       }
-     else
-     {
-       float xr=0.6400, yr=0.3300, xg=0.3000,  yg=0.6000,  xb=0.1500, yb=0.0600, wx=0.3127, wy=0.3290, 
gamma=2.2;
-       sscanf (override, "%f %f %f %f %f %f %f %f %f", &xr, &yr, &xg, &yg, &xb, &yb, &wx, &wy, &gamma);
-       fprintf (stderr, "overriding babl default RGB space with: r=%f %f g=%f %f b=%f %f w=%f %f gamma=%f\n",
-                xr, yr, xg, yg, xb, yb, wx, wy, gamma);
-       babl_space_rgb_chromaticities ("sRGB",
-            wx, wy, xr, yr, xg, yg, xb, yb, babl_trc_gamma (gamma), NULL, NULL);
-     }
-  }
-  else
-  {
-     babl_space_rgb_chromaticities ("sRGB",
-                  0.3127,  0.3290, /* D65 */
-                  0.6400,  0.3300,
-                  0.3000,  0.6000,
-                  0.1500,  0.0600,
-                  babl_trc("sRGB"), NULL, NULL);
-  }
+  babl_space_rgb_chromaticities ("sRGB",
+               0.3127,  0.3290, /* D65 */
+               0.6400,  0.3300,
+               0.3000,  0.6000,
+               0.1500,  0.0600,
+               babl_trc("sRGB"), NULL, NULL);
 
   babl_space_rgb_chromaticities (
       "Adobe",
@@ -401,6 +389,9 @@ babl_space_class_init (void)
      0.1150,  0.8260,
      0.1570,  0.0180,
      babl_trc("2.2"), NULL, NULL);
+
+
+  babl_space_rgb_to_icc (babl_space("sRGB"), NULL);
 }
 
 void babl_space_to_xyz (const Babl *space, const double *rgb, double *xyz)
diff --git a/babl/babl-space.h b/babl/babl-space.h
index 2b2a883..902a685 100644
--- a/babl/babl-space.h
+++ b/babl/babl-space.h
@@ -44,7 +44,7 @@ typedef struct
 
   const Babl      *trc[3];
   char             name[128];
-
+  double whitepoint[3]; /* CIE XYZ whitepoint */
   double RGBtoXYZ[9]; /* matrices for conversions */
   double XYZtoRGB[9];
 
diff --git a/babl/babl.h b/babl/babl.h
index 4edec9a..b601615 100644
--- a/babl/babl.h
+++ b/babl/babl.h
@@ -130,6 +130,7 @@ const Babl * babl_space_rgb_chromaticities (const char *name,
  */
 const Babl *
 babl_space_rgb_matrix (const char *name,
+                       double wx, double wy, double wz,
                        double rx, double gx, double bx,
                        double ry, double gy, double by,
                        double rz, double gz, double bz,
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 3cde051..9c59626 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -3,7 +3,7 @@ AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/babl
 LDADD = $(top_builddir)/babl/libbabl-@BABL_API_VERSION@.la \
        $(MATH_LIB) $(THREAD_LIB)
 
-noinst_PROGRAMS = babl-verify babl-benchmark babl-icc-dump
+noinst_PROGRAMS = babl-verify babl-benchmark babl-icc-dump babl-icc-rewrite
 if HAVE_SRANDOM
 noinst_PROGRAMS +=             \
        babl-gen-test-pixels


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