[gegl] snn-mean: handle mipmap rendering



commit ecfa994c0197818afb904c8fb26758c44c372bf0
Author: Øyvind Kolås <pippin gimp org>
Date:   Sat Feb 25 01:22:48 2017 +0100

    snn-mean: handle mipmap rendering

 operations/common/snn-mean.c |   51 ++++++++++++++++++++++++++++--------------
 1 files changed, 34 insertions(+), 17 deletions(-)
---
diff --git a/operations/common/snn-mean.c b/operations/common/snn-mean.c
index e22c957..b027e48 100644
--- a/operations/common/snn-mean.c
+++ b/operations/common/snn-mean.c
@@ -45,10 +45,12 @@ property_int (pairs, _("Pairs"), 2)
 
 static void
 snn_mean (GeglBuffer          *src,
+          const GeglRectangle *src_rect,
           GeglBuffer          *dst,
           const GeglRectangle *dst_rect,
           gdouble              radius,
-          gint                 pairs);
+          gint                 pairs,
+          gint                 level);
 
 
 static void prepare (GeglOperation *operation)
@@ -75,7 +77,6 @@ process (GeglOperation       *operation,
          gint                 level)
 {
   GeglProperties      *o = GEGL_PROPERTIES (operation);
-  GeglBuffer          *temp_in;
   GeglRectangle        compute;
 
   if (gegl_operation_use_opencl (operation))
@@ -90,10 +91,7 @@ process (GeglOperation       *operation,
     }
   else
     {
-      temp_in = gegl_buffer_create_sub_buffer (input, &compute);
-
-      snn_mean (temp_in, output, result, o->radius, o->pairs);
-      g_object_unref (temp_in);
+      snn_mean (input, &compute, output, result, o->radius, o->pairs, level);
     }
 
   return  TRUE;
@@ -112,23 +110,42 @@ static inline gfloat colordiff (gfloat *pixA,
 
 static void
 snn_mean (GeglBuffer          *src,
+          const GeglRectangle *src_rect,
           GeglBuffer          *dst,
           const GeglRectangle *dst_rect,
           gdouble              dradius,
-          gint                 pairs)
+          gint                 pairs,
+          gint                 level)
 {
   gint x,y;
   gint offset;
   gfloat *src_buf;
   gfloat *dst_buf;
   gint radius = dradius;
-  gint src_width = gegl_buffer_get_width (src);
-  gint src_height = gegl_buffer_get_height (src);
-
-  src_buf = g_new0 (gfloat, gegl_buffer_get_pixel_count (src) * 4);
+  GeglRectangle src_rect_scaled, dst_rect_scaled;
+  if (level)
+  {
+    src_rect_scaled = *src_rect;
+    dst_rect_scaled = *dst_rect;
+    src_rect_scaled.x >>= level;
+    src_rect_scaled.y >>= level;
+    src_rect_scaled.width >>= level;
+    src_rect_scaled.height >>= level;
+    dst_rect_scaled.x >>= level;
+    dst_rect_scaled.y >>= level;
+    dst_rect_scaled.width >>= level;
+    dst_rect_scaled.height >>= level;
+    src_rect = &src_rect_scaled;
+    dst_rect = &dst_rect_scaled;
+    dradius /= (1<<level);
+  }
+  radius = dradius;
+
+
+  src_buf = g_new0 (gfloat, src_rect->width * src_rect->height * 4);
   dst_buf = g_new0 (gfloat, dst_rect->width * dst_rect->height * 4);
 
-  gegl_buffer_get (src, NULL, 1.0, babl_format ("RGBA float"), src_buf, 
+  gegl_buffer_get (src, src_rect, 1.0/(1<<level), babl_format ("RGBA float"), src_buf, 
                    GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
 
   offset = 0;
@@ -137,7 +154,7 @@ snn_mean (GeglBuffer          *src,
     {
       gfloat *center_pix;
 
-      center_pix = src_buf + ((radius) + (y+radius)* src_width)*4;
+      center_pix = src_buf + ((radius) + (y+radius)* src_rect->width)*4;
 
       for (x=0; x<dst_rect->width; x++)
         {
@@ -175,10 +192,10 @@ snn_mean (GeglBuffer          *src,
                     /* check which member of the symmetric quadruple to use */
                     for (i=0;i<pairs*2;i++)
                       {
-                        if (xs[i] >= 0 && xs[i] < src_width &&
-                            ys[i] >= 0 && ys[i] < src_height)
+                        if (xs[i] >= 0 && xs[i] < src_rect->width &&
+                            ys[i] >= 0 && ys[i] < src_rect->height)
                           {
-                            gfloat *tpix = src_buf + (xs[i]+ys[i]* src_width)*4;
+                            gfloat *tpix = src_buf + (xs[i]+ys[i]* src_rect->width)*4;
                             gfloat diff = colordiff (tpix, center_pix);
                             if (diff < best_diff)
                               {
@@ -208,7 +225,7 @@ snn_mean (GeglBuffer          *src,
           center_pix += 4;
         }
     }
-  gegl_buffer_set (dst, dst_rect, 0, babl_format ("RGBA float"), dst_buf,
+  gegl_buffer_set (dst, dst_rect, level, babl_format ("RGBA float"), dst_buf,
                    GEGL_AUTO_ROWSTRIDE);
   g_free (src_buf);
   g_free (dst_buf);


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