[babl] add BablTRC class, that handles gamma or sRGB



commit c93fad83ccd4b0a317e38d2477ae213727a1949c
Author: Øyvind Kolås <pippin gimp org>
Date:   Sat Aug 19 01:20:46 2017 +0200

    add BablTRC class, that handles gamma or sRGB
    
    Done this way, it is easily extendable to also handle LUTs.

 babl/Makefile.am       |    1 +
 babl/babl-classes.h    |    3 +
 babl/babl-internal.c   |    1 +
 babl/babl-internal.h   |    9 +++
 babl/babl-space.c      |   50 +++++++++----------
 babl/babl-space.h      |   56 +--------------------
 babl/babl-trc.c        |  130 ++++++++++++++++++++++++++++++++++++++++++++++++
 babl/babl-trc.h        |   98 ++++++++++++++++++++++++++++++++++++
 babl/babl.c            |    3 +-
 babl/babl.h            |   73 +++++++++++++++++++--------
 babl/base/model-gray.c |   13 +++--
 babl/base/model-rgb.c  |   34 +++++++-----
 babl/base/pow-24.h     |    2 +-
 13 files changed, 349 insertions(+), 124 deletions(-)
---
diff --git a/babl/Makefile.am b/babl/Makefile.am
index 9d39687..1a6d38d 100644
--- a/babl/Makefile.am
+++ b/babl/Makefile.am
@@ -32,6 +32,7 @@ c_sources =                           \
        babl-sampling.c                 \
        babl-sanity.c                   \
        babl-space.c                    \
+       babl-trc.c                      \
        babl-type.c                     \
        babl-util.c                     \
        babl-cpuaccel.c                 \
diff --git a/babl/babl-classes.h b/babl/babl-classes.h
index 054e910..eb05add 100644
--- a/babl/babl-classes.h
+++ b/babl/babl-classes.h
@@ -35,6 +35,7 @@ enum {
   BABL_TYPE_INTEGER,
   BABL_TYPE_FLOAT,
   BABL_SAMPLING,
+  BABL_TRC,
   BABL_COMPONENT,
   BABL_MODEL,
   BABL_FORMAT,
@@ -58,6 +59,7 @@ enum {
 
 #include "babl-type.h"
 #include "babl-sampling.h"
+#include "babl-trc.h"
 #include "babl-space.h"
 #include "babl-component.h"
 #include "babl-model.h"
@@ -78,6 +80,7 @@ typedef union _Babl
   BablType          type;
   BablSampling      sampling;
   BablSpace         space;
+  BablSpace         trc;
   BablComponent     component;
   BablModel         model;
   BablFormat        format;
diff --git a/babl/babl-internal.c b/babl/babl-internal.c
index 789cf6a..0589e3f 100644
--- a/babl/babl-internal.c
+++ b/babl/babl-internal.c
@@ -27,6 +27,7 @@ static const char *class_names[] =
   "BablTypeInteger",
   "BablTypeFloat",
   "BablSampling",
+  "BablTRC",
   "BablComponent",
   "BablModel",
   "BablFormat",
diff --git a/babl/babl-internal.h b/babl/babl-internal.h
index 6ed9195..65c6c22 100644
--- a/babl/babl-internal.h
+++ b/babl/babl-internal.h
@@ -338,4 +338,13 @@ void babl_init_db (void);
 void babl_store_db (void);
 int _babl_max_path_len (void);
 
+double babl_trc_from_linear (const Babl *trc, double value);
+double babl_trc_to_linear   (const Babl *trc, double value);
+float babl_trc_from_linearf (const Babl *trc, float value);
+float babl_trc_to_linearf   (const Babl *trc, float value);
+
+const Babl * babl_trc_new (const char *name,
+                           BablTRCType type,
+                           double      gamma);
+
 #endif
diff --git a/babl/babl-space.c b/babl/babl-space.c
index c264a1c..5838fe2 100644
--- a/babl/babl-space.c
+++ b/babl/babl-space.c
@@ -133,14 +133,6 @@ babl_space_get_chromaticities (const Babl *space,
   if (yb) *yb = space->space.yb;
 }
 
-BablTRC babl_space_get_trc (const Babl *space, double *gamma)
-{
-  if (!space)
-    return 0;
-  if (gamma) *gamma = space->space.gamma;
-  return space->space.trc;
-}
-
 const Babl *
 babl_space (const char *name)
 {
@@ -157,7 +149,9 @@ babl_space_new (const char *name,
                 double rx, double ry,
                 double gx, double gy,
                 double bx, double by,
-                double gamma, BablTRC trc)
+                const Babl *trc_red,
+                const Babl *trc_green,
+                const Babl *trc_blue)
 {
   int i=0;
   static BablSpace space;
@@ -172,13 +166,14 @@ babl_space_new (const char *name,
   space.yb = by;
   space.xw = wx;
   space.yw = wy;
-  space.gamma = gamma;
-  space.trc = trc;
+  space.trc[0] = trc_red;
+  space.trc[1] = trc_green?trc_green:trc_red;
+  space.trc[2] = trc_blue?trc_blue:trc_red;
 
   for (i = 0; space_db[i].instance.class_type; i++)
   {
     int offset = ((char*)&space_db[i].xr) - (char*)(&space_db[i]);
-    int size   = ((char*)&space_db[i].trc) - ((char*)&space_db[i].xr);
+    int size   = ((char*)&space_db[i].trc) + sizeof(space_db[i].trc) - ((char*)&space_db[i].xr);
 
     if (memcmp ((char*)(&space_db[i]) + offset, ((char*)&space) + offset, size)==0)
       {
@@ -195,8 +190,9 @@ babl_space_new (const char *name,
   if (name)
     sprintf (space_db[i].name, "%s", name);
   else
-    sprintf (space_db[i].name, "space-%.4f,%.4f_%.4f,%.4f_%.4f,%.4f_%.4f,%.4f_%.4f,%i",
-             wx,wy,rx,ry,bx,by,gx,gy,gamma,trc);
+    sprintf (space_db[i].name, "space-%.4f,%.4f_%.4f,%.4f_%.4f,%.4f_%.4f,%.4f_%s,%s,%s",
+             wx,wy,rx,ry,bx,by,gx,gy,babl_get_name (space.trc[0]),
+             babl_get_name(space.trc[1]), babl_get_name(space.trc[2]));
 
   /* compute matrixes */
   babl_space_compute_matrices (&space_db[i]);
@@ -224,7 +220,7 @@ babl_space_class_init (void)
                   0.6400,  0.3300,
                   0.3000,  0.6000,
                   0.1500,  0.0600,
-                  1.0, BABL_TRC_LINEAR);
+                  babl_trc("linear"), NULL, NULL);
 #else
   babl_space_new ("sRGB",
                   0.3127,  0.3290, /* D65 */
@@ -232,7 +228,7 @@ babl_space_class_init (void)
                   0.6400,  0.3300,
                   0.3000,  0.6000,
                   0.1500,  0.0600,
-                  2.2, BABL_TRC_SRGB);
+                  babl_trc("sRGB"), NULL, NULL);
 #endif
 
   babl_space_new ("Adobe",
@@ -240,77 +236,77 @@ babl_space_class_init (void)
                   0.6400,  0.3300,
                   0.2100,  0.7100,
                   0.1500,  0.0600,
-                  2.2, BABL_TRC_GAMMA);
+                  babl_trc("2.2"), NULL, NULL);
 
   babl_space_new ("Apple",
                   0.3127,  0.3290, /* D65 */
                   0.6250,  0.3400,
                   0.2800,  0.5950,
                   0.1550,  0.0700,
-                  1.8, BABL_TRC_GAMMA);
+                  babl_trc("1.8"), NULL, NULL);
 
   babl_space_new ("Best",
                   0.34567, 0.3585,  /* D50 */
                   0.7347,  0.2653,
                   0.2150,  0.7750,
                   0.1300,  0.0350,
-                  2.2, BABL_TRC_GAMMA);
+                  babl_trc("2.2"), NULL, NULL);
 
   babl_space_new ("Beta",
                   0.34567, 0.3585,  /* D50 */
                   0.6888,  0.3112,
                   0.1986,  0.7551,
                   0.1265,  0.0352,
-                  2.2, BABL_TRC_GAMMA);
+                  babl_trc("2.2"), NULL, NULL);
 
   babl_space_new ("ProPhoto",
                   0.34567, 0.3585,  /* D50 */
                   0.7347,  0.2653,
                   0.1596,  0.8404,
                   0.0366,  0.0001,
-                  1.8, BABL_TRC_GAMMA);
+                  babl_trc("1.8"), NULL, NULL);
 
   babl_space_new ("Bruce",
                   0.3127,  0.3290, /* D65 */
                   0.6400,  0.3300,
                   0.2800,  0.6500,
                   0.1500,  0.0600,
-                  1.8, BABL_TRC_GAMMA);
+                  babl_trc("1.8"), NULL, NULL);
 
   babl_space_new ("PAL",
                   0.3127,  0.3290, /* D65 */
                   0.6400,  0.3300,
                   0.2900,  0.6000,
                   0.1500,  0.0600,
-                  2.2, BABL_TRC_GAMMA);
+                  babl_trc("2.2"), NULL, NULL);
 
   babl_space_new ("SMPTE-C",
                   0.3127,  0.3290, /* D65 */
                   0.6300,  0.3300,
                   0.3100,  0.5950,
                   0.1550,  0.0700,
-                  2.2, BABL_TRC_GAMMA);
+                  babl_trc("2.2"), NULL, NULL);
 
   babl_space_new ("ColorMatch",
                   0.34567, 0.3585,  /* D50 */
                   0.6300,  0.3400,
                   0.2950,  0.6050,
                   0.1500,  0.0750,
-                  1.8, BABL_TRC_GAMMA);
+                  babl_trc("1.8"), NULL, NULL);
 
   babl_space_new ("Don RGB 4",
                   0.34567, 0.3585,  /* D50 */
                   0.6960,  0.3000,
                   0.2150,  0.7650,
                   0.1300,  0.0350,
-                  1.8, BABL_TRC_GAMMA);
+                  babl_trc("1.8"), NULL, NULL);
 
   babl_space_new ("WideGamutRGB",
                   0.34567, 0.3585,  /* D50 */
                   0.7350,  0.2650,
                   0.1150,  0.8260,
                   0.1570,  0.0180,
-                  2.2, BABL_TRC_GAMMA);
+                  babl_trc("2.2"), NULL, 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 f13f319..e387d4f 100644
--- a/babl/babl-space.h
+++ b/babl/babl-space.h
@@ -40,8 +40,7 @@ typedef struct
   double           xb;  // blue primary chromaticity
   double           yb;
 
-  double           gamma;// gamma TRC
-  BablTRC          trc;  // flag for treatment of gamma (sRGB(1) vs just pow(0))
+  const Babl      *trc[3];
   char             name[128];
 
   double RGBtoXYZ[9]; /* matrices for conversions */
@@ -53,59 +52,6 @@ typedef struct
 
 } BablSpace;
 #include <stdio.h>
-static inline double babl_space_from_linear (const Babl *space_, double value)
-{
-  BablSpace *space = (void*)space_;
-  switch (space->trc)
-  {
-    case BABL_TRC_LINEAR: 
-            return value;
-    case BABL_TRC_GAMMA:
-            return pow (value, 1.0/space->gamma);
-    case BABL_TRC_SRGB:
-            return babl_linear_to_gamma_2_2 (value);
-  }
-  return value;
-}
-
-static inline double babl_space_to_linear (const Babl *space_, double value)
-{
-  BablSpace *space = (void*)space_;
-  switch (space->trc)
-  {
-    case BABL_TRC_LINEAR:
-            return value;
-    case BABL_TRC_GAMMA:
-            return pow (value, space->gamma);
-    case BABL_TRC_SRGB:
-            return babl_gamma_2_2_to_linear (value);
-  }
-  return value;
-}
-
-static inline float babl_space_from_linearf (const Babl *space_, float value)
-{
-  BablSpace *space = (void*)space_;
-  switch (space->trc)
-  {
-    case BABL_TRC_LINEAR: return value;
-    case BABL_TRC_GAMMA:  return powf (value, 1.0f/space->gamma);
-    case BABL_TRC_SRGB:   return babl_linear_to_gamma_2_2f (value);
-  }
-  return value;
-}
-
-static inline float babl_space_to_linearf (const Babl *space_, float value)
-{
-  BablSpace *space = (void*)space_;
-  switch (space->trc)
-  {
-    case BABL_TRC_LINEAR: return value;
-    case BABL_TRC_GAMMA:  return powf (value, space->gamma);
-    case BABL_TRC_SRGB:   return babl_gamma_2_2_to_linearf (value);
-  }
-  return value;
-}
 
 #define m(matr, j, i)  matr[j*3+i]
 
diff --git a/babl/babl-trc.c b/babl/babl-trc.c
new file mode 100644
index 0000000..c1bc107
--- /dev/null
+++ b/babl/babl-trc.c
@@ -0,0 +1,130 @@
+/* babl - dynamically extendable universal pixel conversion library.
+ * Copyright (C) 2017 Øyvind Kolås.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#define MAX_TRCS   100
+
+#include "config.h"
+#include "babl-internal.h"
+#include "base/util.h"
+
+static BablTRC trc_db[MAX_TRCS];
+
+const Babl *
+babl_trc (const char *name)
+{
+  int i;
+  for (i = 0; trc_db[i].instance.class_type; i++)
+    if (!strcmp (trc_db[i].instance.name, name))
+    {
+      return (Babl*)&trc_db[i];
+    }
+  babl_log("failed to find trc '%s'\n", name);
+  return NULL;
+}
+
+const Babl *
+babl_trc_new (const char *name,
+              BablTRCType type,
+              double      gamma)
+{
+  int i=0;
+  static BablTRC trc;
+  trc.instance.class_type = BABL_TRC;
+  trc.instance.id         = 0;
+  trc.type = type;
+  trc.gamma = gamma;
+
+  for (i = 0; trc_db[i].instance.class_type; i++)
+  {
+    int offset = ((char*)&trc_db[i].type) - (char*)(&trc_db[i]);
+    int size   = ((char*)&trc_db[i].gamma + sizeof(double)) - ((char*)&trc_db[i].type);
+
+    if (memcmp ((char*)(&trc_db[i]) + offset, ((char*)&trc) + offset, size)==0)
+      {
+        return (void*)&trc_db[i];
+      }
+  }
+  if (i >= MAX_TRCS-1)
+  {
+    babl_log ("too many BablTRCs");
+    return NULL;
+  }
+  trc_db[i]=trc;
+  trc_db[i].instance.name = trc_db[i].name;
+  if (name)
+    sprintf (trc_db[i].name, "%s", name);
+  else
+    sprintf (trc_db[i].name, "trc-%i-%f", type, gamma);
+
+  return (Babl*)&trc_db[i];
+}
+
+void
+babl_trc_class_for_each (BablEachFunction each_fun,
+                           void            *user_data)
+{
+  int i=0;
+  for (i = 0; trc_db[i].instance.class_type; i++)
+    if (each_fun (BABL (&trc_db[i]), user_data))
+      return;
+}
+
+const Babl *
+babl_trc_gamma (double gamma)
+{
+  char name[32];
+  int i;
+  sprintf (name, "%.6f", gamma);
+  for (i = 0; name[i]; i++)
+    if (name[i] == ',') name[i] = '.';
+  while (name[strlen(name)-1]=='0')
+    name[strlen(name)-1]='\0';
+  return babl_trc_new (name,   BABL_TRC_GAMMA, gamma);
+}
+
+void
+babl_trc_class_init (void)
+{
+  /* we register sRGB first so that lookups for it is fastest */
+  babl_trc_new ("sRGB",  BABL_TRC_SRGB,    2.2);
+  babl_trc_gamma (2.2);
+  babl_trc_gamma (1.8);
+  babl_trc_gamma (1.0);
+  babl_trc_new ("linear", BABL_TRC_LINEAR, 1.0);
+}
+
+double babl_trc_from_linear (const Babl *trc_, double value)
+{
+  return _babl_trc_from_linear (trc_, value);
+}
+
+double babl_trc_to_linear (const Babl *trc_, double value)
+{
+  return _babl_trc_to_linear (trc_, value);
+}
+
+float babl_trc_from_linearf (const Babl *trc_, float value)
+{
+  return _babl_trc_from_linearf (trc_, value);
+}
+
+float babl_trc_to_linearf (const Babl *trc_, float value)
+{
+  return _babl_trc_to_linearf (trc_, value);
+}
+
diff --git a/babl/babl-trc.h b/babl/babl-trc.h
new file mode 100644
index 0000000..fd7a0c5
--- /dev/null
+++ b/babl/babl-trc.h
@@ -0,0 +1,98 @@
+/* babl - dynamically extendable universal pixel conversion library.
+ * Copyright (C) 2017, Øyvind Kolås and others.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _BABL_TRC_H
+#define _BABL_TRC_H
+
+#include <math.h>
+#include <string.h>
+#include "base/util.h"
+
+BABL_CLASS_DECLARE (trc);
+
+typedef enum {BABL_TRC_LINEAR,
+              BABL_TRC_GAMMA,
+              BABL_TRC_SRGB} BablTRCType;
+
+typedef struct
+{
+  BablInstance     instance;
+  BablTRCType      type;
+  double           gamma;
+  char             name[128];
+
+} BablTRC;
+
+static inline double _babl_trc_from_linear (const Babl *trc_, double value)
+{
+  BablTRC *trc = (void*)trc_;
+  switch (trc->type)
+  {
+    case BABL_TRC_LINEAR:
+            return value;
+    case BABL_TRC_GAMMA:
+            return pow (value, 1.0/trc->gamma);
+    case BABL_TRC_SRGB:
+            return babl_linear_to_gamma_2_2 (value);
+  }
+  return value;
+}
+
+static inline double _babl_trc_to_linear (const Babl *trc_, double value)
+{
+  BablTRC *trc = (void*)trc_;
+  switch (trc->type)
+  {
+    case BABL_TRC_LINEAR:
+            return value;
+    case BABL_TRC_GAMMA:
+            return pow (value, trc->gamma);
+    case BABL_TRC_SRGB:
+            return babl_gamma_2_2_to_linear (value);
+  }
+  return value;
+}
+
+static inline float _babl_trc_from_linearf (const Babl *trc_, float value)
+{
+  BablTRC *trc = (void*)trc_;
+  switch (trc->type)
+  {
+    case BABL_TRC_LINEAR: return value;
+    case BABL_TRC_GAMMA:  return powf (value, 1.0f/trc->gamma);
+    case BABL_TRC_SRGB:   return babl_linear_to_gamma_2_2f (value);
+  }
+  return value;
+}
+
+static inline float _babl_trc_to_linearf (const Babl *trc_, float value)
+{
+  BablTRC *trc = (void*)trc_;
+  switch (trc->type)
+  {
+    case BABL_TRC_LINEAR: return value;
+    case BABL_TRC_GAMMA:  return powf (value, trc->gamma);
+    case BABL_TRC_SRGB:   return babl_gamma_2_2_to_linearf (value);
+  }
+  return value;
+}
+
+void
+babl_trc_class_init (void);
+
+#endif
diff --git a/babl/babl.c b/babl/babl.c
index 7d5bf09..c734fb3 100644
--- a/babl/babl.c
+++ b/babl/babl.c
@@ -135,9 +135,10 @@ babl_init (void)
       char * dir_list;
 
       babl_internal_init ();
-      babl_space_class_init ();
       babl_sampling_class_init ();
       babl_type_db ();
+      babl_trc_class_init ();
+      babl_space_class_init ();
       babl_component_db ();
       babl_model_db ();
       babl_format_db ();
diff --git a/babl/babl.h b/babl/babl.h
index b1b1537..6eed5ea 100644
--- a/babl/babl.h
+++ b/babl/babl.h
@@ -101,11 +101,50 @@ const Babl * babl_format            (const char *name);
  */
 const Babl * babl_format_with_space (const char *name, const Babl *space);
 
-typedef enum {
-  BABL_TRC_LINEAR,
-  BABL_TRC_GAMMA,
-  BABL_TRC_SRGB
-} BablTRC;
+/**
+ * babl_trc:
+ *
+ * Look up a TRC by name, "sRGB" "1.0" "linear" and "2.2" are recognized
+ * strings in a stock babl configuration.
+ */
+const Babl * babl_trc       (const char *name);
+
+/**
+ * babl_trc_gamma:
+ *
+ * Creates a Babl TRC for a specific gamma value.
+ */
+const Babl * babl_trc_gamma (double gamma);
+
+/**
+ * babl_trc_from_linear:
+ *
+ * Makes linear data non-linear according to the trc.
+ */
+double babl_trc_from_linear (const Babl *trc, double value);
+
+/**
+ * babl_trc_from_linear:
+ *
+ * Makes non-linear data with the TRC linear data.
+ */
+double babl_trc_to_linear   (const Babl *trc, double value);
+
+/**
+ * babl_trc_from_linearf:
+ *
+ * Makes linear data non-linear according to the trc, single precision float,
+ * a little bit faster than the double version.
+ */
+float babl_trc_from_linearf (const Babl *trc, float value);
+
+/**
+ * babl_trc_from_linearf:
+ *
+ * Makes non-linear data with the TRC linear data, single precision float
+ * alittle bit faster than the double version.
+ */
+float babl_trc_to_linearf   (const Babl *trc, float value);
 
 /**
  * babl_space:
@@ -114,22 +153,25 @@ typedef enum {
  * working space referred to by name. Babl knows of:
  *    sRGB, Adobe, Apple and ProPhoto
  */
-const Babl * babl_space             (const char *name);
+const Babl * babl_space (const char *name);
 
 /**
  * babl_space_new:
  *
  * Creates a new RGB matrix color space definition with the specified
  * white point wx, wy, primary chromaticities rx,ry,gx,gy,bx,by and
- * TRC to be used. After registering a new babl-space it can be used
- * with babl_space().
+ * TRCs to be used. After registering a new babl-space it can be used
+ * with babl_space() passing its name;
  */
 const Babl * babl_space_new (const char *name,
                              double wx, double wy,
                              double rx, double ry,
                              double gx, double gy,
                              double bx, double by,
-                             double gamma, BablTRC trc);
+                             const Babl *trc_red,
+                             const Babl *trc_green,
+                             const Babl *trc_blue);
+
 
 void babl_space_to_xyz   (const Babl *space, const double *rgb, double *xyz);
 void babl_space_from_xyz (const Babl *space, const double *xyz, double *rgb);
@@ -141,19 +183,6 @@ void babl_space_from_xyz (const Babl *space, const double *xyz, double *rgb);
  */
 const Babl * babl_format_get_space  (const Babl *format);
 
-/*
- * babl_space_get_trc:
- *
- * Returns the type of transfer response curve used for ' annotated components
- * for this space. BABL_TRC_LINEAR means no mapping, BABL_TRC_GAMMA means use
- * the gamma double value and BABL_TRC_SRGB means use the sRGB gamma
- * function.
- *
- * If a pointer to return double is not provided but is NULL, then the trc type
- * is still returned.
- */
-BablTRC babl_space_get_trc            (const Babl *space, double *gamma);
-
 /**
  * babl_space_get_chromaticities:
  *
diff --git a/babl/base/model-gray.c b/babl/base/model-gray.c
index ef10ce7..16b1811 100644
--- a/babl/base/model-gray.c
+++ b/babl/base/model-gray.c
@@ -175,6 +175,7 @@ rgb_to_gray_2_2 (Babl  *conversion,
                  long   n)
 {
   const Babl *space = babl_conversion_get_destination_space (conversion);
+  const Babl *trc = space->space.trc[0];
   BABL_PLANAR_SANITY
   while (n--)
     {
@@ -192,7 +193,7 @@ rgb_to_gray_2_2 (Babl  *conversion,
       luminance = red   * RGB_LUMINANCE_RED +    // XXX: should be taken from BablSpace
                   green * RGB_LUMINANCE_GREEN +
                   blue  * RGB_LUMINANCE_BLUE;
-      *(double *) dst[0] = babl_space_from_linear (space, luminance);
+      *(double *) dst[0] = _babl_trc_from_linear (trc, luminance);
 
       if (dst_bands == 2)
         *(double *) dst[1] = alpha;
@@ -214,6 +215,8 @@ gray_2_2_to_rgb (Babl *conversion,
                  long   n)
 {
   const Babl *space = babl_conversion_get_source_space (conversion);
+  const Babl *trc = space->space.trc[0];
+
   BABL_PLANAR_SANITY
   while (n--)
     {
@@ -221,7 +224,7 @@ gray_2_2_to_rgb (Babl *conversion,
       double red, green, blue;
       double alpha;
 
-      luminance = babl_space_to_linear (space, *(double *) src[0]);
+      luminance = _babl_trc_to_linear (trc, *(double *) src[0]);
       red       = luminance;
       green     = luminance;
       blue      = luminance;
@@ -446,6 +449,7 @@ rgba2gray_gamma_2_2_premultiplied (Babl *conversion,
                                    long  n)
 {
   const Babl *space = babl_conversion_get_destination_space (conversion);
+  const Babl *trc = space->space.trc[0];
 
   while (n--)
     {
@@ -460,7 +464,7 @@ rgba2gray_gamma_2_2_premultiplied (Babl *conversion,
       luminance = red * RGB_LUMINANCE_RED +
                   green * RGB_LUMINANCE_GREEN +
                   blue * RGB_LUMINANCE_BLUE;
-      luma = babl_space_from_linear (space, luminance);
+      luma = _babl_trc_from_linear (trc, luminance);
 
       ((double *) dst)[0] = luma * alpha;
       ((double *) dst)[1] = alpha;
@@ -479,6 +483,7 @@ gray_gamma_2_2_premultiplied2rgba (Babl *conversion,
                                    long  n)
 {
   const Babl *space = babl_conversion_get_destination_space (conversion);
+  const Babl *trc = space->space.trc[0];
 
   while (n--)
     {
@@ -487,7 +492,7 @@ gray_gamma_2_2_premultiplied2rgba (Babl *conversion,
       double luminance;
 
       luma      = luma / alpha;
-      luminance = babl_space_to_linear (space, luma);
+      luminance = _babl_trc_to_linear (trc, luma);
 
       ((double *) dst)[0] = luminance;
       ((double *) dst)[1] = luminance;
diff --git a/babl/base/model-rgb.c b/babl/base/model-rgb.c
index b181888..bb660a8 100644
--- a/babl/base/model-rgb.c
+++ b/babl/base/model-rgb.c
@@ -192,6 +192,7 @@ g3_gamma_2_2 (Babl  *conversion,
               long   samples)
 {
   const Babl *space = babl_conversion_get_destination_space (conversion);
+  const Babl **trc  = (void*)space->space.trc;
 
   long n = samples;
 
@@ -200,7 +201,7 @@ g3_gamma_2_2 (Babl  *conversion,
     {
       int band;
       for (band = 0; band < 3; band++)
-        *(double *) dst[band] = babl_space_from_linear (space, (*(double *) src[band]));
+        *(double *) dst[band] = _babl_trc_from_linear (trc[band], (*(double *) src[band]));
       for (; band < dst_bands; band++)
         *(double *) dst[band] = *(double *) src[band];
 
@@ -221,6 +222,7 @@ g3_inv_gamma_2_2 (Babl  *conversion,
                   long   samples)
 {
   const Babl *space = babl_conversion_get_source_space (conversion);
+  const Babl **trc  = (void*)space->space.trc;
   long n = samples;
 
   BABL_PLANAR_SANITY
@@ -229,7 +231,7 @@ g3_inv_gamma_2_2 (Babl  *conversion,
       int band;
       for (band = 0; band < 3; band++)
         {
-          *(double *) dst[band] = babl_space_to_linear (space, (*(double *) src[band]));
+          *(double *) dst[band] = _babl_trc_to_linear (trc[band], (*(double *) src[band]));
         }
       for (; band < dst_bands; band++)
         {
@@ -319,14 +321,15 @@ rgba2rgba_gamma_2_2_premultiplied (Babl *conversion,
                                    long  samples)
 {
   const Babl *space = babl_conversion_get_destination_space (conversion);
+  const Babl **trc  = (void*)space->space.trc;
   long n = samples;
 
   while (n--)
     {
       double alpha = ((double *) src)[3];
-      ((double *) dst)[0] = babl_space_from_linear (space, ((double *) src)[0]) * alpha;
-      ((double *) dst)[1] = babl_space_from_linear (space, ((double *) src)[1]) * alpha;
-      ((double *) dst)[2] = babl_space_from_linear (space, ((double *) src)[2]) * alpha;
+      ((double *) dst)[0] = _babl_trc_from_linear (trc[0], ((double *) src)[0]) * alpha;
+      ((double *) dst)[1] = _babl_trc_from_linear (trc[1], ((double *) src)[1]) * alpha;
+      ((double *) dst)[2] = _babl_trc_from_linear (trc[2], ((double *) src)[2]) * alpha;
       ((double *) dst)[3] = alpha;
       src                += 4 * sizeof (double);
       dst                += 4 * sizeof (double);
@@ -342,6 +345,7 @@ rgba_gamma_2_2_premultiplied2rgba (Babl *conversion,
                                    long            samples)
 {
   const Babl *space = babl_conversion_get_source_space (conversion);
+  const Babl **trc  = (void*)space->space.trc;
   long n = samples;
 
   while (n--)
@@ -349,9 +353,9 @@ rgba_gamma_2_2_premultiplied2rgba (Babl *conversion,
       double alpha = ((double *) src)[3];
       if (alpha > BABL_ALPHA_THRESHOLD)
         {
-          ((double *) dst)[0] = babl_space_to_linear (space, ((double *) src)[0] / alpha);
-          ((double *) dst)[1] = babl_space_to_linear (space, ((double *) src)[1] / alpha);
-          ((double *) dst)[2] = babl_space_to_linear (space, ((double *) src)[2] / alpha);
+          ((double *) dst)[0] = _babl_trc_to_linear (trc[0], ((double *) src)[0] / alpha);
+          ((double *) dst)[1] = _babl_trc_to_linear (trc[1], ((double *) src)[1] / alpha);
+          ((double *) dst)[2] = _babl_trc_to_linear (trc[2], ((double *) src)[2] / alpha);
         }
       else
         {
@@ -375,14 +379,15 @@ rgba2rgba_gamma_2_2 (Babl *conversion,
                      long  samples)
 {
   const Babl *space = babl_conversion_get_destination_space (conversion);
+  const Babl **trc  = (void*)space->space.trc;
   long n = samples;
 
   while (n--)
     {
       double alpha = ((double *) src)[3];
-      ((double *) dst)[0] = babl_space_from_linear (space, ((double *) src)[0]);
-      ((double *) dst)[1] = babl_space_from_linear (space, ((double *) src)[1]);
-      ((double *) dst)[2] = babl_space_from_linear (space, ((double *) src)[2]);
+      ((double *) dst)[0] = _babl_trc_from_linear (trc[0], ((double *) src)[0]);
+      ((double *) dst)[1] = _babl_trc_from_linear (trc[1], ((double *) src)[1]);
+      ((double *) dst)[2] = _babl_trc_from_linear (trc[2], ((double *) src)[2]);
       ((double *) dst)[3] = alpha;
       src                += 4 * sizeof (double);
       dst                += 4 * sizeof (double);
@@ -398,14 +403,15 @@ rgba_gamma_2_22rgba (Babl *conversion,
                      long  samples)
 {
   const Babl *space = babl_conversion_get_source_space (conversion);
+  const Babl **trc  = (void*)(space->space.trc);
   long n = samples;
 
   while (n--)
     {
       double alpha = ((double *) src)[3];
-      ((double *) dst)[0] = babl_space_to_linear (space, ((double *) src)[0]);
-      ((double *) dst)[1] = babl_space_to_linear (space, ((double *) src)[1]);
-      ((double *) dst)[2] = babl_space_to_linear (space, ((double *) src)[2]);
+      ((double *) dst)[0] = _babl_trc_to_linear (trc[0], ((double *) src)[0]);
+      ((double *) dst)[1] = _babl_trc_to_linear (trc[1], ((double *) src)[1]);
+      ((double *) dst)[2] = _babl_trc_to_linear (trc[2], ((double *) src)[2]);
       ((double *) dst)[3] = alpha;
 
       src += 4 * sizeof (double);
diff --git a/babl/base/pow-24.h b/babl/base/pow-24.h
index 0defef6..a55c029 100644
--- a/babl/base/pow-24.h
+++ b/babl/base/pow-24.h
@@ -120,7 +120,7 @@ static inline float babl_frexpf(float x, int *e)
 static inline float
 init_newtonf (float x, float exponent, float c0, float c1, float c2)
 {
-    int iexp;
+    int iexp = 0;
     float y = babl_frexpf(x, &iexp);
     y = 2*y+(iexp-2);
     c1 *= M_LN2*exponent;


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