[gegl] buffer: only zero border pixels when performing filtering



commit e7cfe11973e6dadda1532bdf25fd9469304a9934
Author: Ell <ell_se yahoo com>
Date:   Sun Oct 14 07:39:30 2018 -0400

    buffer: only zero border pixels when performing filtering
    
    In _gegl_buffer_get_unlocked(), don't use g_malloc0() when
    allocating the sample buffer while performing linear- or box-
    filtering.  Rather, always use g_malloc(), and only zero the non-
    sampled "border" pixels in these cases, to avoid unnecessarily
    zeroing pixels that would be overwritten.

 gegl/buffer/gegl-buffer-access.c | 57 ++++++++++++++++++++++++++++++----------
 1 file changed, 43 insertions(+), 14 deletions(-)
---
diff --git a/gegl/buffer/gegl-buffer-access.c b/gegl/buffer/gegl-buffer-access.c
index f2e6a64df..587dfc949 100644
--- a/gegl/buffer/gegl-buffer-access.c
+++ b/gegl/buffer/gegl-buffer-access.c
@@ -2129,20 +2129,7 @@ _gegl_buffer_get_unlocked (GeglBuffer          *buffer,
         interpolation = GEGL_BUFFER_FILTER_BILINEAR;
     }
 
-    if (interpolation == GEGL_BUFFER_FILTER_NEAREST)
-      {
-        sample_buf = g_malloc (allocated);
-      }
-    else
-      {
-        /* both bilinear and bicubic end up with memory corruption
-           glitchy artifacts - probably bleeding in from edges of
-           used buffer, when allocations are not cleared, there might
-           be somep performance gain in ensuring proper buffer filling -
-           or even selective zeroing.
-         */
-        sample_buf = g_malloc0 (allocated);
-      }
+    sample_buf = g_malloc (allocated);
 
     while (rect2.width > 0 && rect2.height > 0)
     {
@@ -2212,6 +2199,26 @@ _gegl_buffer_get_unlocked (GeglBuffer          *buffer,
           case GEGL_BUFFER_FILTER_BILINEAR:
             buf_width  += 1;
             buf_height += 1;
+
+            /* fill the regions of the buffer outside the sampled area with
+             * zeros, since they may be involved in the arithmetic.  even
+             * though their actual value should have no, or negligible, effect,
+             * they must at least be finite, when dealing with float formats.
+             */
+            {
+              guchar *p = sample_buf;
+              gint    y;
+
+              for (y = 0; y < buf_height - 1; y++)
+                {
+                  memset (p + (buf_width - 1) * bpp, 0, bpp);
+
+                  p += buf_width * bpp;
+                }
+
+              memset (p, 0, buf_width * bpp);
+            }
+
             gegl_buffer_iterate_read_dispatch (buffer, &sample_rect,
                                        (guchar*)sample_buf,
                                         buf_width * bpp,
@@ -2239,6 +2246,28 @@ _gegl_buffer_get_unlocked (GeglBuffer          *buffer,
               buf_height += 2;
               offset = (buf_width + 1) * bpp;
 
+              /* fill the regions of the buffer outside the sampled area with
+               * zeros, since they may be involved in the arithmetic.  even
+               * though their actual value should have no, or negligible,
+               * effect, they must at least be finite, when dealing with float
+               * formats.
+               */
+              {
+                guchar *p = sample_buf;
+                gint    y;
+
+                memset (p, 0, (buf_width - 1) * bpp);
+
+                for (y = 0; y < buf_height - 1; y++)
+                  {
+                    memset (p + (buf_width - 1) * bpp, 0, 2 * bpp);
+
+                    p += buf_width * bpp;
+                  }
+
+                memset (p + bpp, 0, (buf_width - 1) * bpp);
+              }
+
               gegl_buffer_iterate_read_dispatch (buffer, &sample_rect,
                                          (guchar*)sample_buf + offset,
                                           buf_width * bpp,


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