[gegl] gegl: make downscale_2x2 always operate in linear space



commit 2824b09e34b1e4492bebc4a86e617a2b982c6bde
Author: Øyvind Kolås <pippin gimp org>
Date:   Thu Jan 18 01:39:23 2018 +0100

    gegl: make downscale_2x2 always operate in linear space

 gegl/gegl-algorithms.c     |   83 ++++++++++++++++++++-----------------------
 gegl/gegl-types-internal.h |   19 ++++++++++
 2 files changed, 58 insertions(+), 44 deletions(-)
---
diff --git a/gegl/gegl-algorithms.c b/gegl/gegl-algorithms.c
index dcd7b42..f39cf4e 100644
--- a/gegl/gegl-algorithms.c
+++ b/gegl/gegl-algorithms.c
@@ -51,21 +51,38 @@ void gegl_downscale_2x2 (const Babl *format,
 {
   const gint  bpp = babl_format_get_bytes_per_pixel (format);
   const Babl *comp_type = babl_format_get_type (format, 0);
+  const Babl *model     = babl_format_get_model (format);
 
-  if (comp_type == gegl_babl_float())
-    gegl_downscale_2x2_float (bpp, src_width, src_height, src_data, src_rowstride, dst_data, dst_rowstride);
-  else if (comp_type == gegl_babl_u8())
-    gegl_downscale_2x2_u8 (bpp, src_width, src_height, src_data, src_rowstride, dst_data, dst_rowstride);
-  else if (comp_type == gegl_babl_u16())
-    gegl_downscale_2x2_u16 (bpp, src_width, src_height, src_data, src_rowstride, dst_data, dst_rowstride);
-  else if (comp_type == gegl_babl_u32())
-    gegl_downscale_2x2_u32 (bpp, src_width, src_height, src_data, src_rowstride, dst_data, dst_rowstride);
-  else if (comp_type == gegl_babl_double())
-    gegl_downscale_2x2_double (bpp, src_width, src_height, src_data, src_rowstride, dst_data, dst_rowstride);
-  else
+  if (gegl_babl_model_is_linear (model))
   {
-    gegl_downscale_2x2_generic (format, src_width, src_height, src_data, src_rowstride, dst_data, 
dst_rowstride);
+    if (comp_type == gegl_babl_float())
+    {
+      gegl_downscale_2x2_float (bpp, src_width, src_height, src_data, src_rowstride, dst_data, 
dst_rowstride);
+      return;
+    }
+    else if (comp_type == gegl_babl_u8())
+    {
+      gegl_downscale_2x2_u8 (bpp, src_width, src_height, src_data, src_rowstride, dst_data, dst_rowstride);
+      return;
+    }
+    else if (comp_type == gegl_babl_u16())
+    {
+      gegl_downscale_2x2_u16 (bpp, src_width, src_height, src_data, src_rowstride, dst_data, dst_rowstride);
+      return;
+    }
+    else if (comp_type == gegl_babl_u32())
+    {
+      gegl_downscale_2x2_u32 (bpp, src_width, src_height, src_data, src_rowstride, dst_data, dst_rowstride);
+      return;
+    }
+    else if (comp_type == gegl_babl_double())
+    {
+      gegl_downscale_2x2_double (bpp, src_width, src_height, src_data, src_rowstride, dst_data, 
dst_rowstride);
+      return;
+    }
   }
+
+  gegl_downscale_2x2_generic (format, src_width, src_height, src_data, src_rowstride, dst_data, 
dst_rowstride);
 }
 
 static void
@@ -87,44 +104,22 @@ gegl_downscale_2x2_generic (const Babl *format,
   gint dst_height        = src_height / 2;
   gint in_tmp_rowstride  = src_width * tmp_bpp;
   gint out_tmp_rowstride = dst_width * tmp_bpp;
+
+  /* XXX: replace with self-aligned alloc for sized below a threshold */
   void *in_tmp           = gegl_malloc (src_height * in_tmp_rowstride);
   void *out_tmp          = gegl_malloc (dst_height * out_tmp_rowstride);
 
-  if (src_rowstride == src_width * bpp)
-    {
-      babl_process (from_fish, src_data, in_tmp, src_width * src_height);
-    }
-  else
-    {
-      guchar *src = src_data;
-      guchar *dst = in_tmp;
-
-      for (y = 0; y < src_height; y++)
-        {
-          babl_process (from_fish, src, dst, src_width);
-          src += src_rowstride;
-          dst += in_tmp_rowstride;
-        }
-    }
+  babl_process_rows (from_fish,
+                     src_data, src_rowstride,
+                     in_tmp,   in_tmp_rowstride,
+                     src_width, src_height);
   gegl_downscale_2x2_float (tmp_bpp, src_width, src_height,
                             in_tmp, in_tmp_rowstride,
                             out_tmp, out_tmp_rowstride);
-  if (dst_rowstride == dst_width * bpp)
-    {
-      babl_process (to_fish, out_tmp, dst_data, dst_width * dst_height);
-    }
-  else
-    {
-      guchar *src = out_tmp;
-      guchar *dst = dst_data;
-
-      for (y = 0; y < dst_height; y++)
-        {
-          babl_process (to_fish, src, dst, dst_width);
-          src += out_tmp_rowstride;
-          dst += dst_rowstride;
-        }
-    }
+  babl_process_rows (to_fish,
+                     out_tmp, out_tmp_rowstride,
+                     dst_data, dst_rowstride,
+                     dst_width, dst_height);
   gegl_free (in_tmp);
   gegl_free (out_tmp);
 }
diff --git a/gegl/gegl-types-internal.h b/gegl/gegl-types-internal.h
index d39606e..992ea1f 100644
--- a/gegl/gegl-types-internal.h
+++ b/gegl/gegl-types-internal.h
@@ -76,6 +76,25 @@ GEGL_CACHED_BABL(type, u16, "u16")
 GEGL_CACHED_BABL(type, u32, "u32")
 GEGL_CACHED_BABL(type, double, "double")
 
+GEGL_CACHED_BABL(model, rgb_linear, "RGB")
+GEGL_CACHED_BABL(model, rgba_linear, "RGBA")
+GEGL_CACHED_BABL(model, rgbA_linear, "RaGaBaA")
+GEGL_CACHED_BABL(model, y_linear, "Y")
+GEGL_CACHED_BABL(model, ya_linear, "YA")
+GEGL_CACHED_BABL(model, yA_linear, "YaA")
+
+static inline gboolean gegl_babl_model_is_linear (const Babl *babl)
+{
+  if (babl == gegl_babl_rgba_linear() ||
+      babl == gegl_babl_rgbA_linear() ||
+      babl == gegl_babl_rgb_linear() ||
+      babl == gegl_babl_ya_linear() ||
+      babl == gegl_babl_ya_linear() ||
+      babl == gegl_babl_yA_linear())
+    return TRUE;
+  return FALSE;
+}
+
 GEGL_CACHED_BABL(format, rgba_float, "R'G'B'A float")
 GEGL_CACHED_BABL(format, rgbA_float, "R'aG'aB'aA float")
 GEGL_CACHED_BABL(format, rgba_linear_float, "RGBA float")


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