[babl] babl: make trcs capable of iterating buffers



commit d12d40363fd6e03e87dd1531811fcb3c295cfab2
Author: Øyvind Kolås <pippin gimp org>
Date:   Fri Sep 1 20:03:13 2017 +0200

    babl: make trcs capable of iterating buffers

 babl/babl-fish-path.c |  203 ++++++++++++++++--------------------------------
 babl/babl-trc.c       |  119 +++++++++++++++++++++++++++++
 babl/babl-trc.h       |   31 ++++++++
 3 files changed, 218 insertions(+), 135 deletions(-)
---
diff --git a/babl/babl-fish-path.c b/babl/babl-fish-path.c
index 9236119..176f02f 100644
--- a/babl/babl-fish-path.c
+++ b/babl/babl-fish-path.c
@@ -431,56 +431,35 @@ universal_nonlinear_rgb_converter (const Babl *conversion,unsigned char *src_cha
   const Babl *source_space = babl_conversion_get_source_space (conversion);
   const Babl *destination_space = babl_conversion_get_destination_space (conversion);
 
-  void   *to_trc_red;
-  void   *to_trc_green;
-  void   *to_trc_blue;
-  float (*to_linear_red) (void *trc, float value);
-  float (*to_linear_green) (void *trc, float value);
-  float (*to_linear_blue) (void *trc, float value);
-  void   *from_trc_red;
-  void   *from_trc_green;
-  void   *from_trc_blue;
-  float (*from_linear_red) (void *trc, float value);
-  float (*from_linear_green) (void *trc, float value);
-  float (*from_linear_blue) (void *trc, float value);
-
   float * matrixf = conversion->conversion.data;
-  int i;
   float *rgba_in = (void*)src_char;
   float *rgba_out = (void*)dst_char;
 
-  to_linear_red   = (void*)source_space->space.trc[0]->trc.fun_to_linear;
-  to_trc_red      = (void*)source_space->space.trc[0];
-  from_linear_red = (void*)destination_space->space.trc[0]->trc.fun_from_linear;
-  from_trc_red    = (void*)destination_space->space.trc[0];
-
-  to_linear_green = (void*)source_space->space.trc[1]->trc.fun_to_linear;
-  to_trc_green    = (void*)source_space->space.trc[1];
-  from_linear_green= (void*)destination_space->space.trc[1]->trc.fun_from_linear;
-  from_trc_green  = (void*)destination_space->space.trc[1];
-
-  to_linear_blue  = (void*)source_space->space.trc[2]->trc.fun_to_linear;
-  to_trc_blue     = (void*)source_space->space.trc[2];
-  from_linear_blue= (void*)destination_space->space.trc[2]->trc.fun_from_linear;
-  from_trc_blue   = (void*)destination_space->space.trc[2];
-
+  {
+    int i;
   for (i = 0; i < samples; i++)
   {
-    rgba_out[i*4]  =to_linear_red(to_trc_red, rgba_in[i*4]);
-    rgba_out[i*4+1]=to_linear_green(to_trc_green, rgba_in[i*4+1]);
-    rgba_out[i*4+2]=to_linear_blue(to_trc_blue, rgba_in[i*4+1]);
-    rgba_out[i*4+3]=rgba_in[3];
+    rgba_out[i*4+3] = rgba_in[i*4+3];
+  }
+  }
+  {
+    int c;
+    for (c = 0; c < 3; c ++)
+    {
+      const Babl *trc = (void*)source_space->space.trc[c];
+      babl_trc_to_linear_buf(trc, rgba_in + c, rgba_out + c, 4, 4, samples);
+    }
   }
 
   babl_matrix_mul_vectorff_buf4 (matrixf, rgba_out, rgba_out, samples);
 
-  for (i = 0; i < samples; i++)
   {
-    rgba_out[0] = from_linear_red(from_trc_red, rgba_out[0]);
-    rgba_out[1] = from_linear_green(from_trc_green, rgba_out[1]);
-    rgba_out[2] = from_linear_blue(from_trc_blue, rgba_out[2]);
-    rgba_in  += 4;
-    rgba_out += 4;
+    int c;
+    for (c = 0; c < 3; c ++)
+    {
+      const Babl *trc = (void*)destination_space->space.trc[c];
+      babl_trc_from_linear_buf(trc, rgba_out + c, rgba_out + c, 4, 4, samples);
+    }
   }
 
   return samples;
@@ -490,33 +469,24 @@ static inline long
 universal_nonlinear_rgb_linear_converter (const Babl *conversion,unsigned char *src_char, unsigned char 
*dst_char, long samples)
 {
   const Babl *source_space = babl_conversion_get_source_space (conversion);
-
-  void   *to_trc_red;
-  void   *to_trc_green;
-  void   *to_trc_blue;
-  float (*to_linear_red) (void *trc, float value);
-  float (*to_linear_green) (void *trc, float value);
-  float (*to_linear_blue) (void *trc, float value);
-
   float * matrixf = conversion->conversion.data;
-  int i;
   float *rgba_in = (void*)src_char;
   float *rgba_out = (void*)dst_char;
 
-  to_linear_red   = (void*)source_space->space.trc[0]->trc.fun_to_linear;
-  to_trc_red      = (void*)source_space->space.trc[0];
-  to_linear_green = (void*)source_space->space.trc[1]->trc.fun_to_linear;
-  to_trc_green    = (void*)source_space->space.trc[1];
-  to_linear_blue  = (void*)source_space->space.trc[2]->trc.fun_to_linear;
-  to_trc_blue     = (void*)source_space->space.trc[2];
-
+  {
+    int i;
   for (i = 0; i < samples; i++)
   {
-    rgba_out[i*4]   = to_linear_red  (to_trc_red,   rgba_in[0]);
-    rgba_out[i*4+1] = to_linear_green(to_trc_green, rgba_in[1]);
-    rgba_out[i*4+2] = to_linear_blue (to_trc_blue,  rgba_in[2]);
-    rgba_out[i*4+3] = rgba_in[3];
-    rgba_in  += 4;
+    rgba_out[i*4+3] = rgba_in[i*4+3];
+  }
+  }
+  {
+    int c;
+    for (c = 0; c < 3; c ++)
+    {
+      const Babl *trc = (void*)source_space->space.trc[c];
+      babl_trc_to_linear_buf(trc, rgba_in + c, rgba_out + c, 4, 4, samples);
+    }
   }
 
   babl_matrix_mul_vectorff_buf4 (matrixf, rgba_out, rgba_out, samples);
@@ -626,59 +596,31 @@ universal_nonlinear_rgb_converter_sse2 (const Babl *conversion,unsigned char *sr
 {
   const Babl *source_space = babl_conversion_get_source_space (conversion);
   const Babl *destination_space = babl_conversion_get_destination_space (conversion);
-
-  void   *to_trc_red;
-  void   *to_trc_green;
-  void   *to_trc_blue;
-  float (*to_linear_red) (void *trc, float value);
-  float (*to_linear_green) (void *trc, float value);
-  float (*to_linear_blue) (void *trc, float value);
-  void   *from_trc_red;
-  void   *from_trc_green;
-  void   *from_trc_blue;
-  float (*from_linear_red) (void *trc, float value);
-  float (*from_linear_green) (void *trc, float value);
-  float (*from_linear_blue) (void *trc, float value);
-
   float * matrixf = conversion->conversion.data;
   int i;
   float *rgba_in = (void*)src_char;
   float *rgba_out = (void*)dst_char;
-
-  to_linear_red   = (void*)source_space->space.trc[0]->trc.fun_to_linear;
-  to_trc_red      = (void*)source_space->space.trc[0];
-  from_linear_red = (void*)destination_space->space.trc[0]->trc.fun_from_linear;
-  from_trc_red    = (void*)destination_space->space.trc[0];
-
-  to_linear_green = (void*)source_space->space.trc[1]->trc.fun_to_linear;
-  to_trc_green    = (void*)source_space->space.trc[1];
-  from_linear_green= (void*)destination_space->space.trc[1]->trc.fun_from_linear;
-  from_trc_green  = (void*)destination_space->space.trc[1];
-
-  to_linear_blue  = (void*)source_space->space.trc[2]->trc.fun_to_linear;
-  to_trc_blue     = (void*)source_space->space.trc[2];
-  from_linear_blue= (void*)destination_space->space.trc[2]->trc.fun_from_linear;
-  from_trc_blue   = (void*)destination_space->space.trc[2];
-
+  {
+    int c;
+    for (c = 0; c < 3; c ++)
+    {
+      const Babl *trc = (void*)source_space->space.trc[c];
+      babl_trc_to_linear_buf(trc, rgba_in + c, rgba_out + c, 4, 4, samples);
+    }
+  }
   for (i = 0; i < samples; i++)
   {
-    rgba_out[i*4]  =to_linear_red(to_trc_red, rgba_in[i*4]);
-    rgba_out[i*4+1]=to_linear_green(to_trc_green, rgba_in[i*4+1]);
-    rgba_out[i*4+2]=to_linear_blue(to_trc_blue, rgba_in[i*4+1]);
     rgba_out[i*4+3]=rgba_in[3];
   }
-
   babl_matrix_mul_vectorff_buf4_sse2 (matrixf, rgba_out, rgba_out, samples);
-
-  for (i = 0; i < samples; i++)
   {
-    rgba_out[0] = from_linear_red(from_trc_red, rgba_out[0]);
-    rgba_out[1] = from_linear_green(from_trc_green, rgba_out[1]);
-    rgba_out[2] = from_linear_blue(from_trc_blue, rgba_out[2]);
-    rgba_in  += 4;
-    rgba_out += 4;
+    int c;
+    for (c = 0; c < 3; c ++)
+    {
+      const Babl *trc = (void*)destination_space->space.trc[c];
+      babl_trc_from_linear_buf(trc, rgba_out + c, rgba_out + c, 4, 4, samples);
+    }
   }
-
   return samples;
 }
 
@@ -713,23 +655,23 @@ universal_nonlinear_rgba_u8_converter_sse2 (const Babl *conversion,unsigned char
     rgb[i*4+0]=in_trc_lut[rgba_in_u8[i*4+0]];
     rgb[i*4+1]=in_trc_lut[rgba_in_u8[i*4+1]];
     rgb[i*4+2]=in_trc_lut[rgba_in_u8[i*4+2]];
+    rgba_out_u8[i*4+3] = rgba_in_u8[i*4+3];
   }
 
   babl_matrix_mul_vectorff_buf4_sse2 (matrixf, rgb, rgb, samples);
 
   {
-  const Babl *from_trc_red   = (void*)destination_space->space.trc[0];
-  const Babl *from_trc_green = (void*)destination_space->space.trc[1];
-  const Babl *from_trc_blue  = (void*)destination_space->space.trc[2];
-  for (i = 0; i < samples; i++)
-  {
-    rgba_out_u8[0] = babl_trc_from_linear (from_trc_red,   rgb[i*4+0]) * 255.5f;
-    rgba_out_u8[1] = babl_trc_from_linear (from_trc_green, rgb[i*4+1]) * 255.5f;
-    rgba_out_u8[2] = babl_trc_from_linear (from_trc_blue,  rgb[i*4+2]) * 255.5f;
-    rgba_out_u8[3] = rgba_in_u8[3];
-    rgba_in_u8  += 4;
-    rgba_out_u8 += 4;
-  }
+    int c;
+    for (c = 0; c < 3; c ++)
+    {
+      const Babl *trc = (void*)destination_space->space.trc[0];
+      babl_trc_from_linear_buf(trc, rgb + c, rgb + c, 4, 4, samples);
+    }
+
+    /* XXX: this is a prime candidate for sseification */
+    for (i = 0; i < samples; i++)
+      for (c = 0; c < 3; c ++)
+        rgba_out_u8[i*4+c] = rgb[i*4+c] * 255.5f;
   }
 
   return samples;
@@ -739,33 +681,24 @@ static inline long
 universal_nonlinear_rgb_linear_converter_sse2 (const Babl *conversion,unsigned char *src_char, unsigned char 
*dst_char, long samples)
 {
   const Babl *source_space = babl_conversion_get_source_space (conversion);
-
-  void   *to_trc_red;
-  void   *to_trc_green;
-  void   *to_trc_blue;
-  float (*to_linear_red) (void *trc, float value);
-  float (*to_linear_green) (void *trc, float value);
-  float (*to_linear_blue) (void *trc, float value);
-
   float * matrixf = conversion->conversion.data;
-  int i;
   float *rgba_in = (void*)src_char;
   float *rgba_out = (void*)dst_char;
 
-  to_linear_red   = (void*)source_space->space.trc[0]->trc.fun_to_linear;
-  to_trc_red      = (void*)source_space->space.trc[0];
-  to_linear_green = (void*)source_space->space.trc[1]->trc.fun_to_linear;
-  to_trc_green    = (void*)source_space->space.trc[1];
-  to_linear_blue  = (void*)source_space->space.trc[2]->trc.fun_to_linear;
-  to_trc_blue     = (void*)source_space->space.trc[2];
-
+  {
+    int i;
   for (i = 0; i < samples; i++)
   {
-    rgba_out[i*4]   = to_linear_red  (to_trc_red,   rgba_in[0]);
-    rgba_out[i*4+1] = to_linear_green(to_trc_green, rgba_in[1]);
-    rgba_out[i*4+2] = to_linear_blue (to_trc_blue,  rgba_in[2]);
-    rgba_out[i*4+3] = rgba_in[3];
-    rgba_in  += 4;
+    rgba_out[i*4+3] = rgba_in[i*4+3];
+  }
+  }
+  {
+    int c;
+    for (c = 0; c < 3; c ++)
+    {
+      const Babl *trc = (void*)source_space->space.trc[c];
+      babl_trc_to_linear_buf(trc, rgba_in + c, rgba_out + c, 4, 4, samples);
+    }
   }
 
   babl_matrix_mul_vectorff_buf4_sse2 (matrixf, rgba_out, rgba_out, samples);
diff --git a/babl/babl-trc.c b/babl/babl-trc.c
index 9275cb6..e22a71a 100644
--- a/babl/babl-trc.c
+++ b/babl/babl-trc.c
@@ -349,6 +349,26 @@ static inline float _babl_trc_gamma_to_linear (const Babl *trc_, float value)
   return babl_powf (value, trc->gamma);
 }
 
+
+static inline void _babl_trc_gamma_to_linear_buf (const Babl *trc_, const float *in, float *out, int in_gap, 
int out_gap, int count)
+{
+  BablTRC *trc = (void*)trc_;
+  float gamma = trc->gamma;
+  int i;
+  for (i = 0; i < count; i ++)
+    out[out_gap * i] = babl_powf (in[in_gap *i], gamma);
+}
+
+
+static inline void _babl_trc_gamma_from_linear_buf (const Babl *trc_, const float *in, float *out, int 
in_gap, int out_gap, int count)
+{
+  BablTRC *trc = (void*)trc_;
+  float gamma = trc->rgamma;
+  int i;
+  for (i = 0; i < count; i ++)
+    out[out_gap * i] = babl_powf (in[in_gap *i], gamma);
+}
+
 static inline float _babl_trc_gamma_from_linear (const Babl *trc_, float value)
 {
   BablTRC *trc = (void*)trc_;
@@ -478,6 +498,92 @@ 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 count)
+{
+  int i;
+  for (i = 0; i < count; i ++)
+    out[out_gap * i] = babl_gamma_2_2_to_linearf (in[in_gap * i]);
+}
+
+static inline void _babl_trc_srgb_from_linear_buf (const Babl *trc_,
+                                                   const float *in, float *out,
+                                                   int in_gap, int out_gap,
+                                                   int count)
+{
+  int i;
+  for (i = 0; i < count; i ++)
+    out[out_gap * i] = babl_linear_to_gamma_2_2f (in[in_gap * i]);
+}
+
+static inline void _babl_trc_to_linear_buf_generic (const Babl *trc_, const float *in, float *out, int 
in_gap, int out_gap, int count)
+{
+  int i;
+  BablTRC *trc = (void*)trc_;
+  for (i = 0; i < count; i ++)
+    out[out_gap * i] = trc->fun_to_linear (trc_, in[in_gap * i]);
+}
+
+static inline void _babl_trc_from_linear_buf_generic (const Babl *trc_,
+                                                      const float *in, float *out,
+                                                      int in_gap, int out_gap,
+                                                      int count)
+{
+  int i;
+  BablTRC *trc = (void*)trc_;
+  for (i = 0; i < count; i ++)
+    out[out_gap * i] = trc->fun_from_linear (trc_, in[in_gap * i]);
+}
+
+static inline void _babl_trc_gamma_1_8_from_linear_buf (const Babl *trc_,
+                                                        const float *in, float *out,
+                                                        int in_gap, int out_gap,
+                                                        int count)
+{
+  int i;
+  for (i = 0; i < count; i ++)
+    out[i * out_gap] = _babl_trc_gamma_1_8_from_linear (trc_, in[i * in_gap]);
+}
+
+static inline void _babl_trc_gamma_2_2_from_linear_buf (const Babl *trc_,
+                                                        const float *in, float *out,
+                                                        int in_gap, int out_gap,
+                                                        int count)
+{
+  int i;
+  for (i = 0; i < count; i ++)
+    out[i * out_gap] = _babl_trc_gamma_2_2_from_linear (trc_, in[i * in_gap]);
+}
+
+static inline void _babl_trc_linear_buf (const Babl *trc_,
+                                         const float *in, float *out,
+                                         int in_gap, int out_gap,
+                                         int count)
+{
+  int i;
+  for (i = 0; i < count; i ++)
+    out[i * out_gap] = in[i * in_gap];
+}
+
+static inline void _babl_trc_gamma_1_8_to_linear_buf (const Babl *trc_,
+                                                      const float *in, float *out,
+                                                      int in_gap, int out_gap,
+                                                      int count)
+{
+  int i;
+  for (i = 0; i < count; i ++)
+    out[i * out_gap] = _babl_trc_gamma_1_8_to_linear (trc_, in[i * in_gap]);
+}
+
+static inline void _babl_trc_gamma_2_2_to_linear_buf (const Babl *trc_,
+                                                        const float *in, float *out,
+                                                        int in_gap, int out_gap,
+                                                        int count)
+{
+  int i;
+  for (i = 0; i < count; i ++)
+    out[i * out_gap] = _babl_trc_gamma_2_2_to_linear (trc_, in[i * in_gap]);
+}
+
 
 const Babl *
 babl_trc (const char *name)
@@ -557,27 +663,40 @@ babl_trc_new (const char *name,
         babl_trc_to_linear (BABL(&trc_db[i]), trc_db[i].lut[(int) ( j/(n_lut-1.0) * (n_lut-1))]);
   }
 
+  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_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;
       break;
     case BABL_TRC_GAMMA_2_2:
       trc_db[i].fun_to_linear = _babl_trc_gamma_2_2_to_linear;
       trc_db[i].fun_from_linear = _babl_trc_gamma_2_2_from_linear;
+      trc_db[i].fun_from_linear_buf = _babl_trc_gamma_2_2_from_linear_buf;
+      trc_db[i].fun_to_linear_buf = _babl_trc_gamma_2_2_to_linear_buf;
       break;
     case BABL_TRC_GAMMA_1_8:
       trc_db[i].fun_to_linear = _babl_trc_gamma_1_8_to_linear;
       trc_db[i].fun_from_linear = _babl_trc_gamma_1_8_from_linear;
+      trc_db[i].fun_from_linear_buf = _babl_trc_gamma_1_8_from_linear_buf;
+      trc_db[i].fun_to_linear_buf = _babl_trc_gamma_1_8_to_linear_buf;
       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;
diff --git a/babl/babl-trc.h b/babl/babl-trc.h
index dc1abf9..4dafd04 100644
--- a/babl/babl-trc.h
+++ b/babl/babl-trc.h
@@ -42,11 +42,42 @@ typedef struct
   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 count);
+  void           (*fun_from_linear_buf)(const Babl *trc,
+                                      const float *in,
+                                      float *out,
+                                      int in_gap,
+                                      int out_gap,
+                                      int count);
   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 count)
+{
+  BablTRC *trc = (void*)trc_;
+  trc->fun_from_linear_buf (trc_, in, out, in_gap, out_gap, count);
+}
+
+static inline void babl_trc_to_linear_buf (const Babl *trc_,
+                                           const float *in, float *out,
+                                           int in_gap, int out_gap,
+                                           int count)
+{
+  BablTRC *trc = (void*)trc_;
+  trc->fun_to_linear_buf (trc_, in, out, in_gap, out_gap, count);
+}
+
 static inline float babl_trc_from_linear (const Babl *trc_, float value)
 {
   BablTRC *trc = (void*)trc_;


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