[babl] babl: add missing files babl-trc.[ch]



commit 45349ee92dcba00aa948cbaee244d58e973f2c28
Author: Øyvind Kolås <pippin gimp org>
Date:   Sun Jan 23 02:46:23 2022 +0100

    babl: add missing files babl-trc.[ch]

 babl/base/babl-trc.c | 608 +++++++++++++++++++++++++++++++++++++++++++++++++++
 babl/base/babl-trc.h | 107 +++++++++
 2 files changed, 715 insertions(+)
---
diff --git a/babl/base/babl-trc.c b/babl/base/babl-trc.c
new file mode 100644
index 000000000..6cb4900b4
--- /dev/null
+++ b/babl/base/babl-trc.c
@@ -0,0 +1,608 @@
+/* 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
+ * <https://www.gnu.org/licenses/>.
+ */
+
+#define MAX_TRCS   100
+
+/* FIXME: choose parameters more intelligently */
+#define POLY_GAMMA_X0     (  0.5 / 255.0)
+#define POLY_GAMMA_X1     (254.5 / 255.0)
+#define POLY_GAMMA_DEGREE 6
+#define POLY_GAMMA_SCALE  2
+
+#include "config.h"
+#include "babl-internal.h"
+#include "babl-base.h"
+#include "base/util.h"
+
+static BablTRC trc_db[MAX_TRCS];
+
+static inline float 
+_babl_trc_linear (const Babl *trc_, 
+                  float       value)
+{
+  return value;
+}
+
+static inline float 
+babl_trc_lut_from_linear (const Babl *trc_, 
+                          float       x)
+{
+  BablTRC *trc = (void*)trc_;
+  int entry;
+  float ret, diff;
+
+  entry = x * (trc->lut_size-1);
+  diff =  ( (x * (trc->lut_size-1)) - entry);
+
+  if (entry >= trc->lut_size -1)
+  {
+    entry = trc->lut_size - 1;
+    diff = 0.0;
+  }
+  else if (entry < 0) entry = 0;
+
+  if (diff > 0.0)
+  {
+    ret = trc->inv_lut[entry] * (1.0 - diff) + trc->inv_lut[entry+1] * diff;
+  }
+  else
+  {
+    ret = trc->inv_lut[entry];
+  }
+  return ret;
+}
+
+static inline float 
+babl_trc_lut_to_linear (const Babl *trc_, 
+                        float       x)
+{
+  BablTRC *trc = (void*)trc_;
+  int entry;
+  float ret, diff;
+
+  entry = x * (trc->lut_size-1);
+  diff =  ( (x * (trc->lut_size-1)) - entry);
+
+  if (entry >= trc->lut_size) entry = trc->lut_size - 1;
+  else if (entry < 0) entry = 0;
+
+  if (diff > 0.0 && entry < trc->lut_size - 1)
+  {
+    ret = trc->lut[entry] * (1.0 - diff) + trc->lut[entry+1] * diff;
+  }
+  else
+  {
+    ret = trc->lut[entry];
+  }
+  return ret;
+}
+
+static inline float 
+_babl_trc_gamma_to_linear (const Babl *trc_, 
+                           float       value)
+{
+  BablTRC *trc = (void*)trc_;
+  if (value >= trc->poly_gamma_to_linear_x0 &&
+      value <= trc->poly_gamma_to_linear_x1)
+    {
+      return babl_polynomial_eval (&trc->poly_gamma_to_linear, value);
+    }
+  else if (value > 0.0f)
+    {
+      return powf (value, trc->gamma);
+    }
+  return 0.0f;
+}
+
+static inline float 
+_babl_trc_gamma_from_linear (const Babl *trc_, 
+                             float       value)
+{
+  BablTRC *trc = (void*)trc_;
+  if (value >= trc->poly_gamma_from_linear_x0 &&
+      value <= trc->poly_gamma_from_linear_x1)
+    {
+      return babl_polynomial_eval (&trc->poly_gamma_from_linear, value);
+    }
+  else if (value > 0.0f)
+    {
+      return powf (value, trc->rgamma);
+    }
+  return 0.0f;
+}
+
+static inline void 
+_babl_trc_gamma_to_linear_buf (const Babl  *trc_, 
+                               const float *__restrict__ in, 
+                               float       *__restrict__ out, 
+                               int          in_gap, 
+                               int          out_gap, 
+                               int          components, 
+                               int          count)
+{
+  if (in_gap == out_gap && in_gap == 4 && components == 3)
+  {
+    for (int i = 0; i < count; i ++)
+      for (int c = 0; c < 3; c ++)
+        out[4 * i + c] = _babl_trc_gamma_to_linear (trc_, in[4 *i + c]);
+  }
+  else
+  {
+    for (int i = 0; i < count; i ++)
+      for (int c = 0; c < components; c ++)
+        out[out_gap * i + c] = _babl_trc_gamma_to_linear (trc_, in[in_gap *i + c]);
+  }
+}
+
+static inline void 
+_babl_trc_gamma_from_linear_buf (const Babl  *trc_, 
+                                 const float *__restrict__ in, 
+                                 float       *__restrict__ out, 
+                                 int          in_gap, 
+                                 int          out_gap, 
+                                 int          components, 
+                                 int          count)
+{
+  if (in_gap == out_gap && in_gap == 4 && components == 3)
+  {
+    for (int i = 0; i < count; i ++)
+      for (int c = 0; c < 3; c ++)
+        out[4 * i + c] = _babl_trc_gamma_from_linear (trc_, in[4 *i + c]);
+  }
+  else
+  {
+    for (int i = 0; i < count; i ++)
+      for (int c = 0; c < components; c ++)
+        out[out_gap * i + c] = _babl_trc_gamma_from_linear (trc_, in[in_gap *i + c]);
+  }
+}
+
+static inline float 
+_babl_trc_formula_srgb_from_linear (const Babl *trc_, 
+                                    float       value)
+{
+  BablTRC *trc = (void*)trc_;
+  float x= value;
+  float a = trc->lut[1];
+  float b = trc->lut[2];
+  float c = trc->lut[3];
+  float d = trc->lut[4];
+  float e = trc->lut[5];
+  float f = trc->lut[6];
+
+  if (x - f > c * d)  // XXX: verify that this math is the correct inverse
+  {
+    float v = _babl_trc_gamma_from_linear ((Babl *) trc, x - f);
+    v = (v-b)/a;
+    if (v < 0.0 || v >= 0.0)
+      return v;
+    return 0.0;
+  }
+  if (c > 0.0)
+    return (x - e) / c;
+  return 0.0;
+}
+
+static inline float 
+_babl_trc_formula_srgb_to_linear (const Babl *trc_, 
+                                  float       value)
+{
+  BablTRC *trc = (void*)trc_;
+  float x= value;
+  float a = trc->lut[1];
+  float b = trc->lut[2];
+  float c = trc->lut[3];
+  float d = trc->lut[4];
+  float e = trc->lut[5];
+  float f = trc->lut[6];
+
+  if (x >= d)
+  {
+    return _babl_trc_gamma_to_linear ((Babl *) trc, a * x + b) + e;
+  }
+  return c * x + f;
+}
+static inline float 
+_babl_trc_formula_cie_from_linear (const Babl *trc_, 
+                                   float       value)
+{
+  BablTRC *trc = (void*)trc_;
+  float x= value;
+  float a = trc->lut[1];
+  float b = trc->lut[2];
+  float c = trc->lut[3];
+
+  if (x > c)
+  {
+    float v = _babl_trc_gamma_from_linear ((Babl *) trc, x - c);
+    v = (v-b)/a;
+    if (v < 0.0 || v >= 0.0)
+      return v;
+  }
+  return 0.0;
+}
+
+static inline float 
+_babl_trc_formula_cie_to_linear (const Babl *trc_, 
+                                 float       value)
+{
+  BablTRC *trc = (void*)trc_;
+  float x= value;
+  float a = trc->lut[1];
+  float b = trc->lut[2];
+  float c = trc->lut[3];
+
+  if (x >= -b / a)
+  {
+    return _babl_trc_gamma_to_linear ((Babl *) trc, a * x + b) + c;
+  }
+  return c;
+}
+
+
+
+static inline float 
+_babl_trc_srgb_to_linear (const Babl *trc_, 
+                          float       value)
+{
+  return babl_gamma_2_2_to_linearf (value);
+}
+
+static inline float 
+_babl_trc_srgb_from_linear (const Babl *trc_, 
+                            float       value)
+{
+  return babl_linear_to_gamma_2_2f (value);
+}
+
+static inline void 
+_babl_trc_srgb_to_linear_buf (const Babl  *trc_, 
+                              const float *in, 
+                              float       *out, 
+                              int          in_gap, 
+                              int          out_gap, 
+                              int          components, 
+                              int          count)
+{
+  if (in_gap == out_gap && in_gap == 4 && components == 3)
+  {
+  for (int i = 0; i < count; i ++)
+    for (int c = 0; c < 3; c++)
+      out[4 * i + c] = babl_gamma_2_2_to_linearf (in[4 * i + c]);
+  }
+  else
+  {
+  for (int i = 0; i < count; i ++)
+    for (int c = 0; c < components; c++)
+      out[out_gap * i + c] = babl_gamma_2_2_to_linearf (in[in_gap * i + c]);
+  }
+}
+
+static inline void 
+_babl_trc_srgb_from_linear_buf (const Babl  *trc_,
+                                const float *in, 
+                                float       *out,
+                                int          in_gap,
+                                int          out_gap,
+                                int          components,
+                                int          count)
+{
+  if (in_gap == out_gap && in_gap == 4 && components == 3)
+  {
+      for (int i = 0; i < count; i ++)
+       for (int c = 0; c < 3; c++)
+         out[4 * i + c] = babl_linear_to_gamma_2_2f (in[4 * i + c]);
+  }
+  else
+  {
+     for (int i = 0; i < count; i ++)
+       for (int c = 0; c < components; c++)
+         out[out_gap * i + c] = babl_linear_to_gamma_2_2f (in[in_gap * i + c]);
+  }
+}
+
+static inline void 
+_babl_trc_to_linear_buf_generic (const Babl  *trc_, 
+                                 const float *__restrict__ in, 
+                                 float       *__restrict__ out, 
+                                 int          in_gap, 
+                                 int          out_gap, 
+                                 int          components, 
+                                 int          count)
+{
+  BablTRC *trc = (void*)trc_;
+  if (in_gap == out_gap && in_gap == 4 && components == 3)
+  {
+    for (int i = 0; i < count; i ++)
+      for (int c = 0; c < 3; c ++)
+        out[4 * i + c] = trc->fun_to_linear (trc_, in[4 * i + c]);
+  }
+  else
+  {
+    for (int i = 0; i < count; i ++)
+      for (int c = 0; c < components; c ++)
+        out[out_gap * i + c] = trc->fun_to_linear (trc_, in[in_gap * i + c]);
+  }
+}
+
+static inline void 
+_babl_trc_from_linear_buf_generic (const Babl  *trc_,
+                                   const float *__restrict__ in, 
+                                   float       *__restrict__ out,
+                                   int          in_gap, 
+                                   int          out_gap,
+                                   int          components,
+                                   int          count)
+{
+  BablTRC *trc = (void*)trc_;
+  if (in_gap == out_gap && in_gap == 4 && components == 3)
+  {
+    for (int i = 0; i < count; i ++)
+      for (int c = 0; c < 3; c ++)
+        out[4 * i + c] = trc->fun_from_linear (trc_, in[4 * i + c]);
+  }
+  else
+  {
+    for (int i = 0; i < count; i ++)
+      for (int c = 0; c < components; c ++)
+        out[out_gap * i + c] = trc->fun_from_linear (trc_, in[in_gap * i + c]);
+  }
+}
+
+static inline void _babl_trc_linear_buf (const Babl  *trc_,
+                                         const float *__restrict__ in, 
+                                         float       *__restrict__ out,
+                                         int          in_gap, 
+                                         int          out_gap,
+                                         int          components,
+                                         int          count)
+{
+  if (in_gap == out_gap && in_gap == 4 && components == 3)
+  {
+     for (int i = 0; i < count; i ++)
+       for (int c = 0; c < 3; c ++)
+         out[i * 4 + c] = in[i * 4 + c];
+  }
+  else
+  {
+    for (int i = 0; i < count; i ++)
+      for (int c = 0; c < components; c ++)
+        out[i * out_gap + c] = in[i * in_gap + c];
+  }
+}
+
+const Babl *
+BABL_SIMD_SUFFIX (babl_trc_lookup_by_name) (const char *name);
+
+const Babl *
+BABL_SIMD_SUFFIX (babl_trc_lookup_by_name) (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_SIMD_SUFFIX (babl_trc_new) (const char *name,
+              BablTRCType type,
+              double      gamma,
+              int         n_lut,
+              float      *lut);
+
+const Babl *
+BABL_SIMD_SUFFIX (babl_trc_new) (const char *name,
+              BablTRCType type,
+              double      gamma,
+              int         n_lut,
+              float      *lut)
+{
+  int i=0;
+  static BablTRC trc;
+  trc.instance.class_type = BABL_TRC;
+  trc.instance.id         = 0;
+  trc.type = type;
+  trc.gamma  = gamma > 0.0    ? gamma       : 0.0;
+  trc.rgamma = gamma > 0.0001 ? 1.0 / gamma : 0.0;
+
+  if (n_lut )
+  {
+    for (i = 0; trc_db[i].instance.class_type; i++)
+    {
+    if ( trc_db[i].lut_size == n_lut &&
+         (memcmp (trc_db[i].lut, lut, sizeof (float) * n_lut)==0)
+       )
+      {
+        return (void*)&trc_db[i];
+      }
+    }
+  }
+  else
+  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)
+    snprintf (trc_db[i].name, sizeof (trc_db[i].name), "%s", name);
+  else if (n_lut)
+    snprintf (trc_db[i].name, sizeof (trc_db[i].name), "lut-trc");
+  else
+    snprintf (trc_db[i].name, sizeof (trc_db[i].name), "trc-%i-%f", type, gamma);
+
+  if (n_lut)
+  {
+    int j;
+    trc_db[i].lut_size = n_lut;
+    trc_db[i].lut = babl_calloc (sizeof (float), n_lut);
+    memcpy (trc_db[i].lut, lut, sizeof (float) * n_lut);
+    trc_db[i].inv_lut = babl_calloc (sizeof (float), n_lut);
+
+    for (j = 0; j < n_lut; j++)
+    {
+      int k;
+      double min = 0.0;
+      double max = 1.0;
+      for (k = 0; k < 16; k++)
+      {
+        double guess = (min + max) / 2;
+        float reversed_index = babl_trc_lut_to_linear (BABL(&trc_db[i]), guess) * (n_lut-1.0);
+
+        if (reversed_index < j)
+        {
+          min = guess;
+        }
+        else if (reversed_index > j)
+        {
+          max = guess;
+        }
+      }
+      trc_db[i].inv_lut[j] = (min + max) / 2;
+    }
+  }
+
+  trc_db[i].fun_to_linear_buf = _babl_trc_to_linear_buf_generic;
+  trc_db[i].fun_from_linear_buf = _babl_trc_from_linear_buf_generic;
+
+  switch (trc_db[i].type)
+  {
+    case BABL_TRC_LINEAR:
+      trc_db[i].fun_to_linear = _babl_trc_linear;
+      trc_db[i].fun_from_linear = _babl_trc_linear;
+      trc_db[i].fun_from_linear_buf = _babl_trc_linear_buf;
+      trc_db[i].fun_to_linear_buf = _babl_trc_linear_buf;
+      break;
+    case BABL_TRC_FORMULA_GAMMA:
+      trc_db[i].fun_to_linear = _babl_trc_gamma_to_linear;
+      trc_db[i].fun_from_linear = _babl_trc_gamma_from_linear;
+      trc_db[i].fun_to_linear_buf = _babl_trc_gamma_to_linear_buf;
+      trc_db[i].fun_from_linear_buf = _babl_trc_gamma_from_linear_buf;
+
+      trc_db[i].poly_gamma_to_linear_x0 = POLY_GAMMA_X0;
+      trc_db[i].poly_gamma_to_linear_x1 = POLY_GAMMA_X1;
+      babl_polynomial_approximate_gamma (&trc_db[i].poly_gamma_to_linear,
+                                         trc_db[i].gamma,
+                                         trc_db[i].poly_gamma_to_linear_x0,
+                                         trc_db[i].poly_gamma_to_linear_x1,
+                                         POLY_GAMMA_DEGREE, POLY_GAMMA_SCALE);
+
+      trc_db[i].poly_gamma_from_linear_x0 = POLY_GAMMA_X0;
+      trc_db[i].poly_gamma_from_linear_x1 = POLY_GAMMA_X1;
+      babl_polynomial_approximate_gamma (&trc_db[i].poly_gamma_from_linear,
+                                         trc_db[i].rgamma,
+                                         trc_db[i].poly_gamma_from_linear_x0,
+                                         trc_db[i].poly_gamma_from_linear_x1,
+                                         POLY_GAMMA_DEGREE, POLY_GAMMA_SCALE);
+      break;
+    case BABL_TRC_FORMULA_CIE:
+      trc_db[i].lut = babl_calloc (sizeof (float), 4);
+      {
+        int j;
+        for (j = 0; j < 4; j++)
+          trc_db[i].lut[j] = lut[j];
+      }
+      trc_db[i].fun_to_linear = _babl_trc_formula_cie_to_linear;
+      trc_db[i].fun_from_linear = _babl_trc_formula_cie_from_linear;
+
+      trc_db[i].poly_gamma_to_linear_x0 = lut[4];
+      trc_db[i].poly_gamma_to_linear_x1 = POLY_GAMMA_X1;
+      babl_polynomial_approximate_gamma (&trc_db[i].poly_gamma_to_linear,
+                                         trc_db[i].gamma,
+                                         trc_db[i].poly_gamma_to_linear_x0,
+                                         trc_db[i].poly_gamma_to_linear_x1,
+                                         POLY_GAMMA_DEGREE, POLY_GAMMA_SCALE);
+
+      trc_db[i].poly_gamma_from_linear_x0 = lut[3] * lut[4];
+      trc_db[i].poly_gamma_from_linear_x1 = POLY_GAMMA_X1;
+      babl_polynomial_approximate_gamma (&trc_db[i].poly_gamma_from_linear,
+                                         trc_db[i].rgamma,
+                                         trc_db[i].poly_gamma_from_linear_x0,
+                                         trc_db[i].poly_gamma_from_linear_x1,
+                                         POLY_GAMMA_DEGREE, POLY_GAMMA_SCALE);
+      break;
+
+    case BABL_TRC_FORMULA_SRGB:
+      trc_db[i].lut = babl_calloc (sizeof (float), 7);
+      {
+        int j;
+        for (j = 0; j < 7; j++)
+          trc_db[i].lut[j] = lut[j];
+      }
+      trc_db[i].fun_to_linear = _babl_trc_formula_srgb_to_linear;
+      trc_db[i].fun_from_linear = _babl_trc_formula_srgb_from_linear;
+
+      trc_db[i].poly_gamma_to_linear_x0 = lut[4];
+      trc_db[i].poly_gamma_to_linear_x1 = POLY_GAMMA_X1;
+      babl_polynomial_approximate_gamma (&trc_db[i].poly_gamma_to_linear,
+                                         trc_db[i].gamma,
+                                         trc_db[i].poly_gamma_to_linear_x0,
+                                         trc_db[i].poly_gamma_to_linear_x1,
+                                         POLY_GAMMA_DEGREE, POLY_GAMMA_SCALE);
+
+      trc_db[i].poly_gamma_from_linear_x0 = lut[3] * lut[4];
+      trc_db[i].poly_gamma_from_linear_x1 = POLY_GAMMA_X1;
+      babl_polynomial_approximate_gamma (&trc_db[i].poly_gamma_from_linear,
+                                         trc_db[i].rgamma,
+                                         trc_db[i].poly_gamma_from_linear_x0,
+                                         trc_db[i].poly_gamma_from_linear_x1,
+                                         POLY_GAMMA_DEGREE, POLY_GAMMA_SCALE);
+      break;
+    case BABL_TRC_SRGB:
+      trc_db[i].fun_to_linear = _babl_trc_srgb_to_linear;
+      trc_db[i].fun_from_linear = _babl_trc_srgb_from_linear;
+      trc_db[i].fun_from_linear_buf = _babl_trc_srgb_from_linear_buf;
+      trc_db[i].fun_to_linear_buf = _babl_trc_srgb_to_linear_buf;
+      break;
+    case BABL_TRC_LUT:
+      trc_db[i].fun_to_linear = babl_trc_lut_to_linear;
+      trc_db[i].fun_from_linear = babl_trc_lut_from_linear;
+      break;
+  }
+  return (Babl*)&trc_db[i];
+}
+
+void
+BABL_SIMD_SUFFIX(babl_trc_class_for_each) (BablEachFunction each_fun,
+                                           void            *user_data);
+
+void
+BABL_SIMD_SUFFIX(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;
+}
+
diff --git a/babl/base/babl-trc.h b/babl/base/babl-trc.h
new file mode 100644
index 000000000..79b6891f0
--- /dev/null
+++ b/babl/base/babl-trc.h
@@ -0,0 +1,107 @@
+/* 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
+ * <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef _BABL_TRC_H
+#define _BABL_TRC_H
+
+#include <math.h>
+#include <string.h>
+#include "base/util.h"
+#include "babl-polynomial.h"
+
+BABL_CLASS_DECLARE (trc);
+
+typedef enum {BABL_TRC_LINEAR,
+              BABL_TRC_FORMULA_GAMMA,
+              BABL_TRC_SRGB,
+              BABL_TRC_FORMULA_SRGB,
+              BABL_TRC_LUT,
+              BABL_TRC_FORMULA_CIE}
+BablTRCType;
+
+typedef struct
+{
+  BablInstance     instance;
+  BablTRCType      type;
+  int              lut_size;
+  double           gamma;
+  float            rgamma;
+  float          (*fun_to_linear)(const Babl *trc, float val);
+  float          (*fun_from_linear)(const Babl *trc, float val);
+
+  void           (*fun_to_linear_buf)(const Babl *trc,
+                                      const float *in,
+                                      float *out,
+                                      int in_gap,
+                                      int out_gap,
+                                      int components,
+                                      int count);
+  void           (*fun_from_linear_buf)(const Babl *trc,
+                                      const float *in,
+                                      float *out,
+                                      int in_gap,
+                                      int out_gap,
+                                      int components,
+                                      int count);
+  BablPolynomial   poly_gamma_to_linear;
+  float            poly_gamma_to_linear_x0;
+  float            poly_gamma_to_linear_x1;
+  BablPolynomial   poly_gamma_from_linear;
+  float            poly_gamma_from_linear_x0;
+  float            poly_gamma_from_linear_x1;
+  float           *lut;
+  float           *inv_lut;
+  char             name[128];
+} BablTRC;
+
+static inline void babl_trc_from_linear_buf (const Babl *trc_,
+                                             const float *in, float *out,
+                                             int in_gap, int out_gap,
+                                             int components,
+                                             int count)
+{
+  BablTRC *trc = (void*)trc_;
+  trc->fun_from_linear_buf (trc_, in, out, in_gap, out_gap, components, count);
+}
+
+static inline void babl_trc_to_linear_buf (const Babl *trc_,
+                                           const float *in, float *out,
+                                           int in_gap, int out_gap,
+                                           int components,
+                                           int count)
+{
+  BablTRC *trc = (void*)trc_;
+  trc->fun_to_linear_buf (trc_, in, out, in_gap, out_gap, components, count);
+}
+
+static inline float babl_trc_from_linear (const Babl *trc_, float value)
+{
+  BablTRC *trc = (void*)trc_;
+  return trc->fun_from_linear (trc_, value);
+}
+
+static inline float babl_trc_to_linear (const Babl *trc_, float value)
+{
+  BablTRC *trc = (void*)trc_;
+  return trc->fun_to_linear (trc_, value);
+}
+
+void
+babl_trc_class_init_generic (void);
+
+#endif


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