[babl] babl: use typedefs and structs for fixed point numbers



commit b017e0d10ab561270626d7ad500ae575a048b9de
Author: Øyvind Kolås <pippin gimp org>
Date:   Mon Aug 21 01:40:25 2017 +0200

    babl: use typedefs and structs for fixed point numbers
    
    also adds code to print exact decimal representations of numbers found in icc
    files, can be useful for tuning constants fed in - our observing differences,
    it turns out that ~6digits of precision is enough for double float and fixed point 32bit to differ in 
values in icc profiles.

 babl/babl-icc.c       |  133 ++++++++++++++++---
 tools/babl-icc-dump.c |  347 +++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 391 insertions(+), 89 deletions(-)
---
diff --git a/babl/babl-icc.c b/babl/babl-icc.c
index 7277f67..2bc15b6 100644
--- a/babl/babl-icc.c
+++ b/babl/babl-icc.c
@@ -24,7 +24,17 @@
 #define ICC_HEADER_LEN 128
 #define TAG_COUNT_OFF  ICC_HEADER_LEN
 
-static int load_byte (const char *icc, int length, int offset)
+typedef struct {
+  int16_t  integer;
+  uint16_t fraction;
+} s15f16_t;
+
+typedef struct {
+  int16_t  integer;
+  uint16_t fraction;
+} u8f8_t;
+
+static int load_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.
@@ -35,7 +45,7 @@ static int load_byte (const char *icc, int length, int offset)
   return *(uint8_t*) (&icc[offset]);
 }
 
-static int load_sbyte (const char *icc, int length, int offset)
+static int load_s8 (const char *icc, int length, int offset)
 {
   if (offset < 0 || offset > length)
     return 0;
@@ -45,37 +55,109 @@ static int load_sbyte (const char *icc, int length, int offset)
 
 static int16_t load_u1f15 (const char *icc, int length, int offset)
 {
-  return load_byte (icc, length, offset + 1) +
-         (load_sbyte (icc, length, offset + 0) << 8);
+  return load_u8 (icc, length, offset + 1) +
+         (load_s8 (icc, length, offset + 0) << 8);
 }
 
 static uint16_t load_u16 (const char *icc, int length, int offset)
 {
-  return load_byte (icc, length, offset + 1) +
-         (load_byte (icc, length, offset + 0) << 8);
+  return load_u8 (icc, length, offset + 1) +
+         (load_u8 (icc, length, offset + 0) << 8);
+}
+
+static u8f8_t load_u8f8_ (const char *icc, int length, int offset)
+{
+  u8f8_t ret ={load_u8 (icc, length, offset),
+               load_u8 (icc, length, offset + 1)};
+  return ret;
+}
+
+static s15f16_t load_s15f16_ (const char *icc, int length, int offset)
+{
+  s15f16_t ret ={load_u1f15 (icc, length, offset),
+                 load_u16 (icc, length, offset + 2)};
+  return ret;
+}
+
+static double s15f16_to_d (s15f16_t fix)
+{
+  return fix.integer + fix.fraction / 65535.0;
+}
+
+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)
 {
-  return load_u1f15 (icc, length, offset) +
-         load_u16 (icc, length, offset + 2) / 65535.0f;
+  return s15f16_to_d (load_s15f16_ (icc, length, offset));
+}
+
+static double load_u8f8 (const char *icc, int length, int offset)
+{
+  return u8f8_to_d (load_u8f8_ (icc, length, offset));
+}
+
+static inline void print_u8f8 (u8f8_t fix)
+{
+  int i;
+  uint32_t foo;
+  foo = fix.fraction;
+  fprintf (stdout, "%i.", fix.integer);
+  for (i = 0; i < 18; i++)
+  {
+    foo *= 10;
+    fprintf (stdout, "%i", (foo / 256) % 10);
+    foo = foo & 0xff;
+  }
+}
+
+static inline void print_s15f16 (s15f16_t fix)
+{
+  int i;
+  uint32_t foo;
+  foo = fix.fraction;
+  if (fix.integer < 0)
+  {
+    if (fix.integer == -1)
+      fprintf (stdout, "-");
+    fprintf (stdout, "%i.", fix.integer + 1);
+    foo = 65535-fix.fraction;
+    for (i = 0; i < 18; i++)
+    {
+      foo *= 10;
+      fprintf (stdout, "%i", (foo / 65536) % 10);
+      foo = foo & 0xffff;
+    }
+  }
+  else
+  {
+  fprintf (stdout, "%i.", fix.integer);
+  for (i = 0; i < 18; i++)
+  {
+    foo *= 10;
+    fprintf (stdout, "%i", (foo / 65536) % 10);
+    foo = foo & 0xffff;
+  }
+  }
 }
 
 static uint32_t load_u32 (const char *icc, int length, int offset)
 {
-  return load_byte (icc, length, offset + 3) +
-         (load_byte (icc, length, offset + 2) << 8) +
-         (load_byte (icc, length, offset + 1) << 16) +
-         (load_byte (icc, length, offset + 0) << 24);
+  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);
 }
 
 static void load_sign (const char *icc, int length,
                        int offset, char *sign)
 {
-  sign[0]=load_byte(icc, length, offset);
-  sign[1]=load_byte(icc, length, offset + 1);
-  sign[2]=load_byte(icc, length, offset + 2);
-  sign[3]=load_byte(icc, length, offset + 3);
+  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;
 }
 
@@ -118,8 +200,7 @@ static const Babl *babl_trc_from_icc (const char *icc,
       }
       else if (count == 1)
       {
-        return babl_trc_gamma (load_byte (icc, length, offset + 12) +
-                               load_byte (icc, length, offset + 12 + 1)/255.0);
+        return babl_trc_gamma (load_u8f8 (icc, length, offset + 12));
       }
       else
       {
@@ -141,13 +222,27 @@ 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)
+{
+  static char icc[4096];
+  int length=0;
+  icc[length]=0;
+
+
+
+  if (ret_length)
+    *ret_length = length;
+  return icc;
+}
+
 const Babl *
 babl_space_rgb_icc (const char *icc,
                     int         length,
                     char      **error)
 {
   int  profile_size     = load_u32 (icc, length, 0);
-  int  icc_ver_major    = load_byte (icc, length, 8);
+  int  icc_ver_major    = load_u8 (icc, length, 8);
   const Babl *trc_red   = NULL;
   const Babl *trc_green = NULL;
   const Babl *trc_blue  = NULL;
diff --git a/tools/babl-icc-dump.c b/tools/babl-icc-dump.c
index 6adb8ff..f28a2de 100644
--- a/tools/babl-icc-dump.c
+++ b/tools/babl-icc-dump.c
@@ -1,7 +1,7 @@
 #include <stdio.h>
 #include <stdlib.h>
-#include "../config.h"
-#include "babl/babl-internal.h"
+#include <stdint.h>
+#include <string.h>
 
 static int
 file_get_contents (const char  *path,
@@ -9,11 +9,20 @@ file_get_contents (const char  *path,
                    long        *length,
                    void        *error);
 
+typedef struct {
+  int16_t  integer;
+  uint16_t fraction;
+} s15f16_t;
+
+typedef struct {
+  int16_t  integer;
+  uint16_t fraction;
+} u8f8_t;
 
 #define ICC_HEADER_LEN 128
 #define TAG_COUNT_OFF  ICC_HEADER_LEN
 
-static int load_byte (const char *icc, int length, int offset)
+static int load_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.
@@ -24,7 +33,7 @@ static int load_byte (const char *icc, int length, int offset)
   return *(uint8_t*) (&icc[offset]);
 }
 
-static int load_sbyte (const char *icc, int length, int offset)
+static int load_s8 (const char *icc, int length, int offset)
 {
   if (offset < 0 || offset > length)
     return 0;
@@ -34,37 +43,109 @@ static int load_sbyte (const char *icc, int length, int offset)
 
 static int16_t load_u1f15 (const char *icc, int length, int offset)
 {
-  return load_byte (icc, length, offset + 1) +
-         (load_sbyte (icc, length, offset + 0) << 8);
+  return load_u8 (icc, length, offset + 1) +
+         (load_s8 (icc, length, offset + 0) << 8);
 }
 
 static uint16_t load_u16 (const char *icc, int length, int offset)
 {
-  return load_byte (icc, length, offset + 1) +
-         (load_byte (icc, length, offset + 0) << 8);
+  return load_u8 (icc, length, offset + 1) +
+         (load_u8 (icc, length, offset + 0) << 8);
+}
+
+static u8f8_t load_u8f8_ (const char *icc, int length, int offset)
+{
+  u8f8_t ret ={load_u8 (icc, length, offset),
+               load_u8 (icc, length, offset + 1)};
+  return ret;
+}
+
+static s15f16_t load_s15f16_ (const char *icc, int length, int offset)
+{
+  s15f16_t ret ={load_u1f15 (icc, length, offset),
+                 load_u16 (icc, length, offset + 2)};
+  return ret;
+}
+
+static double s15f16_to_d (s15f16_t fix)
+{
+  return fix.integer + fix.fraction / 65535.0;
+}
+
+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)
 {
-  return load_u1f15 (icc, length, offset) +
-         load_u16 (icc, length, offset + 2) / 65535.0f;
+  return s15f16_to_d (load_s15f16_ (icc, length, offset));
+}
+
+static double load_u8f8 (const char *icc, int length, int offset)
+{
+  return u8f8_to_d (load_u8f8_ (icc, length, offset));
+}
+
+static void print_u8f8 (u8f8_t fix)
+{
+  int i;
+  uint32_t foo;
+  foo = fix.fraction;
+  fprintf (stdout, "%i.", fix.integer);
+  for (i = 0; i < 18; i++)
+  {
+    foo *= 10;
+    fprintf (stdout, "%i", (foo / 256) % 10);
+    foo = foo & 0xff;
+  }
+}
+
+static void print_s15f16 (s15f16_t fix)
+{
+  int i;
+  uint32_t foo;
+  foo = fix.fraction;
+  if (fix.integer < 0)
+  {
+    if (fix.integer == -1)
+      fprintf (stdout, "-");
+    fprintf (stdout, "%i.", fix.integer + 1);
+    foo = 65535-fix.fraction;
+    for (i = 0; i < 18; i++)
+    {
+      foo *= 10;
+      fprintf (stdout, "%i", (foo / 65536) % 10);
+      foo = foo & 0xffff;
+    }
+  }
+  else
+  {
+  fprintf (stdout, "%i.", fix.integer);
+  for (i = 0; i < 18; i++)
+  {
+    foo *= 10;
+    fprintf (stdout, "%i", (foo / 65536) % 10);
+    foo = foo & 0xffff;
+  }
+  }
 }
 
 static uint32_t load_u32 (const char *icc, int length, int offset)
 {
-  return load_byte (icc, length, offset + 3) +
-         (load_byte (icc, length, offset + 2) << 8) +
-         (load_byte (icc, length, offset + 1) << 16) +
-         (load_byte (icc, length, offset + 0) << 24);
+  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);
 }
 
 static void load_sign (const char *icc, int length,
                        int offset, char *sign)
 {
-  sign[0]=load_byte(icc, length, offset);
-  sign[1]=load_byte(icc, length, offset + 1);
-  sign[2]=load_byte(icc, length, offset + 2);
-  sign[3]=load_byte(icc, length, offset + 3);
+  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;
 }
 
@@ -97,21 +178,21 @@ static int icc_tag (const char *icc, int length,
 #define ICC_HEADER_LEN 128
 #define TAG_COUNT_OFF  ICC_HEADER_LEN
 
-static int load_byte (const char *icc, int offset)
+static int load_u8 (const char *icc, int offset)
 {
   return *(uint8_t*) (&icc[offset]);
 }
 
 static int16_t load_u1Fixed15 (const char *icc, int offset)
 {
-  return load_byte (icc, offset + 1) +
-         (load_byte (icc, offset + 0) << 8);
+  return load_u8 (icc, offset + 1) +
+         (load_u8 (icc, offset + 0) << 8);
 }
 
 static uint16_t load_u16 (const char *icc, int offset)
 {
-  return load_byte (icc, offset + 1) +
-         (load_byte (icc, offset + 0) << 8);
+  return load_u8 (icc, offset + 1) +
+         (load_u8 (icc, offset + 0) << 8);
 }
 
 static double load_s15f16 (const char *icc, int offset)
@@ -126,40 +207,40 @@ static double load_u16f16 (const char *icc, int offset)
 
 static uint32_t load_u32 (const char *icc, int offset)
 {
-  return load_byte (icc, offset + 3) +
-         (load_byte (icc, offset + 2) << 8) +
-         (load_byte (icc, offset + 1) << 16) +
-         (load_byte (icc, offset + 0) << 24);
+  return load_u8 (icc, offset + 3) +
+         (load_u8 (icc, offset + 2) << 8) +
+         (load_u8 (icc, offset + 1) << 16) +
+         (load_u8 (icc, offset + 0) << 24);
 }
 
 static float load_float32 (const char *icc, int offset)
 {
-  char buf[4]={load_byte (icc, offset + 3),
-         load_byte (icc, offset + 2),
-         load_byte (icc, offset + 1),
-         load_byte (icc, offset + 0)};
+  char buf[4]={load_u8 (icc, offset + 3),
+         load_u8 (icc, offset + 2),
+         load_u8 (icc, offset + 1),
+         load_u8 (icc, offset + 0)};
   float *val = (float*)(&buf[0]);
   return *val;
 }
 
 static uint64_t load_uint64 (const char *icc, int offset)
 {
-  return ((uint64_t)load_byte (icc, offset + 7) << (8*0)) +
-         ((uint64_t)load_byte (icc, offset + 6) << (8*1)) +
-         ((uint64_t)load_byte (icc, offset + 5) << (8*2)) +
-         ((uint64_t)load_byte (icc, offset + 4) << (8*3)) +
-         ((uint64_t)load_byte (icc, offset + 3) << (8*4)) +
-         ((uint64_t)load_byte (icc, offset + 2) << (8*5)) +
-         ((uint64_t)load_byte (icc, offset + 1) << (8*6)) +
-         ((uint64_t)load_byte (icc, offset + 0) << (8*7));
+  return ((uint64_t)load_u8 (icc, offset + 7) << (8*0)) +
+         ((uint64_t)load_u8 (icc, offset + 6) << (8*1)) +
+         ((uint64_t)load_u8 (icc, offset + 5) << (8*2)) +
+         ((uint64_t)load_u8 (icc, offset + 4) << (8*3)) +
+         ((uint64_t)load_u8 (icc, offset + 3) << (8*4)) +
+         ((uint64_t)load_u8 (icc, offset + 2) << (8*5)) +
+         ((uint64_t)load_u8 (icc, offset + 1) << (8*6)) +
+         ((uint64_t)load_u8 (icc, offset + 0) << (8*7));
 }
 
 static void load_sign (const char *icc, int offset, char *sign)
 {
-  sign[0]=load_byte(icc, offset);
-  sign[1]=load_byte(icc, offset + 1);
-  sign[2]=load_byte(icc, offset + 2);
-  sign[3]=load_byte(icc, offset + 3);
+  sign[0]=load_u8(icc, offset);
+  sign[1]=load_u8(icc, offset + 1);
+  sign[2]=load_u8(icc, offset + 2);
+  sign[3]=load_u8(icc, offset + 3);
   sign[4]=0;
 }
 
@@ -193,13 +274,15 @@ static int icc_tag (const char *icc, const char *tag, int *offset, int *length)
 }
 #endif
 
+int exact = 0;
+
 static int load_icc_from_memory (const char *icc, long length, char **error)
 {
   int  tag_count         = load_u32 (icc, length, TAG_COUNT_OFF);
   int  profile_size      = load_u32 (icc, length, 0);
-  int  profile_version_major = load_byte (icc, length, 8);
-  int  profile_version_minor = load_byte (icc, length, 9) >> 4;
-  int  profile_version_micro = load_byte (icc, length, 9) & 0xf;
+  int  profile_version_major = load_u8 (icc, length, 8);
+  int  profile_version_minor = load_u8 (icc, length, 9) >> 4;
+  int  profile_version_micro = load_u8 (icc, length, 9) & 0xf;
   char profile_class[5];
   char color_space[5];
   char pcs_space[5];
@@ -232,7 +315,13 @@ static int load_icc_from_memory (const char *icc, long length, char **error)
   {
      int offset, element_size;
      icc_tag (icc, length, "desc", &offset, &element_size);
-     fprintf (stdout, "desc: %s\n", icc + offset + 12);
+     if (!strcmp (icc + offset, "mluc"))
+     {
+       fprintf (stdout, "desc: [babl-icc doesnt decode unicode]\n");
+     }
+     else
+     if (!strcmp (icc + offset, "desc"))
+       fprintf (stdout, "desc: %s\n", icc + offset + 12);
   }
   {
      int offset, element_size;
@@ -247,7 +336,8 @@ static int load_icc_from_memory (const char *icc, long length, char **error)
   fprintf (stdout, "color-space: %s\n", color_space);
   fprintf (stdout, "rendering-intent: %i\n", rendering_intent);
   fprintf (stdout, "pcs-space: %s\n", pcs_space);
-  fprintf (stdout, "byte length: %li\n", length);
+  fprintf (stdout, "length: %li\n", length);
+#if 0
   fprintf (stdout, "tag-count: %i\n", tag_count);
 
   for (t =  0; t < tag_count; t++)
@@ -259,6 +349,7 @@ static int load_icc_from_memory (const char *icc, long length, char **error)
      fprintf (stdout, "tag %i %s %i %i\n", t, tag_signature, offset, element_size);
   }
 #endif
+#endif
   fprintf (stdout, "tags: ");
   for (t =  0; t < tag_count; t++)
   {
@@ -266,9 +357,11 @@ static int load_icc_from_memory (const char *icc, long length, char **error)
      int offset, element_size;
      load_sign (icc, length, TAG_COUNT_OFF + 4 + 12 * t, tag_signature);
      icc_tag (icc, length, tag_signature, &offset, &element_size);
-     fprintf (stdout, "%s ", tag_signature);
+     fprintf (stdout, "%s[%i@%i] ", tag_signature, element_size, offset);
   }
   fprintf (stdout, "\n");
+  fprintf (stdout, "\n");
+
 
   {
      int offset, element_size;
@@ -285,51 +378,135 @@ static int load_icc_from_memory (const char *icc, long length, char **error)
      fprintf (stdout, "chromaticity:\n");
      fprintf (stdout, "  channels: %i\n", channels);
      fprintf (stdout, "  phosphorant: %i\n", phosporant);
-     fprintf (stdout, "  CIE xy red: %f %f\n", redX, redY);
-     fprintf (stdout, "  CIE xy green: %f %f\n", greenX, greenY);
-     fprintf (stdout, "  CIE xy blue: %f %f\n", blueX, blueY);
+     fprintf (stdout, "  CIE xy red:   %.6f %.6f\n", redX, redY);
+     fprintf (stdout, "  CIE xy green: %.6f %.6f\n", greenX, greenY);
+     fprintf (stdout, "  CIE xy blue:  %.6f %.6f\n", blueX, blueY);
+     if (exact)
+     {
+        fprintf (stdout, "  exact:        ");
+        print_s15f16 (load_s15f16_ (icc, length, offset + 12));
+        fprintf (stdout, " ");
+        print_s15f16 (load_s15f16_ (icc, length, offset + 12 + 4));
+        fprintf (stdout, "\n");
+
+        fprintf (stdout, "                ");
+        print_s15f16 (load_s15f16_ (icc, length, offset + 20));
+        fprintf (stdout, " ");
+        print_s15f16 (load_s15f16_ (icc, length, offset + 20 + 4));
+        fprintf (stdout, "\n");
+
+        fprintf (stdout, "                ");
+        print_s15f16 (load_s15f16_ (icc, length, offset + 28));
+        fprintf (stdout, " ");
+        print_s15f16 (load_s15f16_ (icc, length, offset + 28 + 4));
+        fprintf (stdout, "\n");
+     }
+
      }
   }
 
   {
      int offset, element_size;
-     if (icc_tag (icc, length, "wtpt", &offset, &element_size))
+     if (icc_tag (icc, length, "bkpt", &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);
-       fprintf (stdout, "whitepoint CIE xyz: %f %f %f\n", wX, wY, wZ);
+       fprintf (stdout,    "blackpoint CIE XYZ: %.6f %.6f %.6f\n", wX, wY, wZ);
+
+       if (exact)
+       {
+          fprintf (stdout, "exact:              ");
+          print_s15f16 (load_s15f16_ (icc, length, offset + 8));
+          fprintf (stdout, " ");
+          print_s15f16 (load_s15f16_ (icc, length, offset + 8 + 4));
+          fprintf (stdout, " ");
+          print_s15f16 (load_s15f16_ (icc, length, offset + 8 + 4 * 2));
+          fprintf (stdout, "\n");
+       }
      }
+
   }
 
   {
      int offset, element_size;
-     if (icc_tag (icc, length, "rXYZ", &offset, &element_size))
+     if (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);
-       fprintf (stdout, "Red        CIE xyz: %f %f %f\n", wX, wY, wZ);
+       fprintf (stdout,    "whitepoint CIE XYZ: %.6f %.6f %.6f\n", wX, wY, wZ);
+
+       if (exact)
+       {
+          fprintf (stdout, "exact:              ");
+          print_s15f16 (load_s15f16_ (icc, length, offset + 8));
+          fprintf (stdout, " ");
+          print_s15f16 (load_s15f16_ (icc, length, offset + 8 + 4));
+          fprintf (stdout, " ");
+          print_s15f16 (load_s15f16_ (icc, length, offset + 8 + 4 * 2));
+          fprintf (stdout, "\n");
+       }
+
      }
   }
+
+
   {
      int offset, element_size;
+     if (icc_tag (icc, length, "rXYZ", &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);
+       fprintf (stdout, "red        CIE XYZ: %.6f %.6f %.6f\n", wX, wY, wZ);
+     }
      if (icc_tag (icc, length, "gXYZ", &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);
-       fprintf (stdout, "Green      CIE xyz: %f %f %f\n", wX, wY, wZ);
+       fprintf (stdout, "green      CIE XYZ: %.6f %.6f %.6f\n", wX, wY, wZ);
      }
-  }
-  {
-     int offset, element_size;
      if (icc_tag (icc, length, "bXYZ", &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);
-       fprintf (stdout, "Blue       CIE xyz: %f %f %f\n", wX, wY, wZ);
+       fprintf (stdout, "blue       CIE XYZ: %.6f %.6f %.6f\n", wX, wY, wZ);
+     }
+  }
+  if(exact){
+     int offset, element_size;
+     if (icc_tag (icc, length, "rXYZ", &offset, &element_size))
+     {
+       fprintf (stdout, "exact:              ");
+       print_s15f16 (load_s15f16_ (icc, length, offset + 8));
+       fprintf (stdout, " ");
+       print_s15f16 (load_s15f16_ (icc, length, offset + 8 + 4));
+       fprintf (stdout, " ");
+       print_s15f16 (load_s15f16_ (icc, length, offset + 8 + 4 * 2));
+       fprintf (stdout, "\n");
+     }
+     if (icc_tag (icc, length, "gXYZ", &offset, &element_size))
+     {
+       fprintf (stdout, "                    ");
+       print_s15f16 (load_s15f16_ (icc, length, offset + 8));
+       fprintf (stdout, " ");
+       print_s15f16 (load_s15f16_ (icc, length, offset + 8 + 4));
+       fprintf (stdout, " ");
+       print_s15f16 (load_s15f16_ (icc, length, offset + 8 + 4 * 2));
+       fprintf (stdout, "\n");
+     }
+     if (icc_tag (icc, length, "bXYZ", &offset, &element_size))
+     {
+       fprintf (stdout, "                    ");
+       print_s15f16 (load_s15f16_ (icc, length, offset + 8));
+       fprintf (stdout, " ");
+       print_s15f16 (load_s15f16_ (icc, length, offset + 8 + 4));
+       fprintf (stdout, " ");
+       print_s15f16 (load_s15f16_ (icc, length, offset + 8 + 4 * 2));
+       fprintf (stdout, "\n");
      }
   }
 
@@ -347,7 +524,14 @@ static int load_icc_from_memory (const char *icc, long length, char **error)
          {
             case 0:
               g = load_s15f16 (icc, length, offset + 12 + 2 * 0);
-              fprintf (stdout, "parametric TRC gamma type %f\n", g);
+              fprintf (stdout, "parametric TRC gamma type %.6f\n", g);
+              if (exact)
+              {
+              fprintf (stdout, "    exact:");
+              print_s15f16 (load_s15f16_ (icc, length, offset + 12 + 2 * 0));
+              fprintf (stdout, "\n");
+              }
+
               break;
 
             case 3:
@@ -357,8 +541,19 @@ static int load_icc_from_memory (const char *icc, long length, char **error)
               c = load_s15f16 (icc, length, offset + 12 + 2 * 3);
               d = load_s15f16 (icc, length, offset + 12 + 2 * 4);
               e = load_s15f16 (icc, length, offset + 12 + 2 * 5);
-              f = load_s15f16 (icc, length, offset + 12 + 2 * 5);
-              fprintf (stdout, "parametric TRC sRGB type %f %f %f %f %f %f %f\n", g, a, b, c, d, e, f);
+              f = load_s15f16 (icc, length, offset + 12 + 2 * 6);
+              fprintf (stdout, "parametric TRC sRGB type %.6f %.6f %.6f %.6f %.6f %.6f %.6f\n", g, a, b, c, 
d, e, f);
+              if (exact)
+              {
+                int i;
+                fprintf (stdout, "    exact:");
+                for (i = 0; i < 7; i++)
+                {
+                  print_s15f16 (load_s15f16_ (icc, length, offset + 12 + 2 * i));
+                  fprintf (stdout, " ");
+                }
+                fprintf (stdout, "\n");
+              }
               break;
             default:
             fprintf (stdout, "unhandled parametric TRC type %i\n", function_type);
@@ -374,8 +569,15 @@ static int load_icc_from_memory (const char *icc, long length, char **error)
        }
        else if (count == 1)
        {
-         fprintf (stdout, "gamma TRC of: %f\n", load_byte (icc, length, offset + 12) +
-                                                load_byte (icc, length, offset + 12 + 1) / 255.0);
+         fprintf (stdout, "gamma TRC of: %.6f\n",
+                load_u8f8 (icc,length, offset + 12));
+         if (exact)
+         {
+            fprintf (stdout, " exact: ");
+            print_u8f8 (load_u8f8_ (icc,length, offset + 12));
+            fprintf (stdout, "\n");
+
+         }
        }
        else for (i = 0; i < count && i < 10; i ++)
        {
@@ -443,17 +645,22 @@ file_get_contents (const char  *path,
 
 int main (int argc, char **argv)
 {
-  char *error = NULL;
+  int i;
   if (argc < 2)
   {
     fprintf (stdout, "need one arg, an ICC profile file\n");
     return -1;
   }
 
-  load_icc (argv[1], &error);
-  if (error)
+  for (i = 1; argv[i]; i++)
   {
-    fprintf (stdout, "icc-parse-problem: %s\n", error);
+    char *error = NULL;
+    fprintf (stdout, "\nfile: %s\n", argv[i]);
+    load_icc (argv[i], &error);
+    if (error)
+    {
+      fprintf (stdout, "icc-parse-problem: %s\n", error);
+    }
   }
 
   return 0;


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