[gegl] Use explicit rects for demosaic input and outputs



commit 4f6b93024b5a8f1a37cf7b5329e89c36651a085d
Author: Danny Robson <danny blubinc net>
Date:   Sat Jan 30 14:42:44 2010 +1100

    Use explicit rects for demosaic input and outputs
    
    Explicitly sizing the working area of the input and output pads for the
    demosaic routines makes the operation more robust.
    
    Additionally, the output pad does not appear to contain correct extent
    information. This causes nonsensical memory allocation sizes during
    demosaic if not relying on the ROI passed to process.

 operations/workshop/demosaic-bimedian.c |   35 +++++++++++++----------
 operations/workshop/demosaic-simple.c   |   45 ++++++++++++++----------------
 2 files changed, 41 insertions(+), 39 deletions(-)
---
diff --git a/operations/workshop/demosaic-bimedian.c b/operations/workshop/demosaic-bimedian.c
index 610b615..7841092 100644
--- a/operations/workshop/demosaic-bimedian.c
+++ b/operations/workshop/demosaic-bimedian.c
@@ -72,35 +72,35 @@ m4 (gfloat a, gfloat b, gfloat c, gfloat d)
 }
 
 /* Defines to make the row/col offsets below obvious. */
-#define ROW src_extent->width
+#define ROW src_rect->width
 #define COL 1
 
 /* We expect src_extent to have a one pixel border around all four sides
  * of dst_extent.
  */
 static void
-demosaic (GeglChantO *op,
-          GeglBuffer *src,
-          GeglBuffer *dst)
+demosaic (GeglChantO          *op,
+          GeglBuffer          *src,
+          const GeglRectangle *src_rect,
+          GeglBuffer          *dst,
+          const GeglRectangle *dst_rect)
 {
-  const GeglRectangle *src_extent = gegl_buffer_get_extent (src);
-  const GeglRectangle *dst_extent = gegl_buffer_get_extent (dst);
   gint x,y;
   gint offset, doffset;
   gfloat *src_buf;
   gfloat *dst_buf;
 
-  src_buf = g_new0 (gfloat, gegl_buffer_get_pixel_count (src));
-  dst_buf = g_new0 (gfloat, gegl_buffer_get_pixel_count (dst) * 3);
+  src_buf = g_new0 (gfloat, src_rect->width * src_rect->height * 1);
+  dst_buf = g_new0 (gfloat, dst_rect->width * dst_rect->height * 3);
 
-  gegl_buffer_get (src, 1.0, NULL, babl_format ("Y float"), src_buf,
+  gegl_buffer_get (src, 1.0, src_rect, babl_format ("Y float"), src_buf,
            GEGL_AUTO_ROWSTRIDE);
 
   offset = ROW + COL;
   doffset = 0;
-  for (y=dst_extent->y; y<dst_extent->height + dst_extent->y; y++)
+  for (y=dst_rect->y; y<dst_rect->height + dst_rect->y; y++)
     {
-      for (x=dst_extent->x; x<dst_extent->width + dst_extent->x; x++)
+      for (x=dst_rect->x; x<dst_rect->width + dst_rect->x; x++)
         {
           gfloat red=0.0;
           gfloat green=0.0;
@@ -167,20 +167,24 @@ demosaic (GeglChantO *op,
       offset+=2;
     }
 
-  gegl_buffer_set (dst, NULL, babl_format ("RGB float"), dst_buf, GEGL_AUTO_ROWSTRIDE);
+  gegl_buffer_set (dst, dst_rect, babl_format ("RGB float"), dst_buf, GEGL_AUTO_ROWSTRIDE);
   g_free (src_buf);
   g_free (dst_buf);
 }
 
+
 /* Specify required extra pixels around dst_extent: one pixel on every side.
  */
 static void prepare (GeglOperation *operation)
 {
   GeglOperationAreaFilter *area = GEGL_OPERATION_AREA_FILTER (operation);
   area->right = area->bottom = 1;
-  area->left = area->top = 1;
+  area->left  = area->top    = 1;
+
+  gegl_operation_set_format (operation, "output", babl_format ("RGB float"));
 }
 
+
 static gboolean
 process (GeglOperation       *operation,
          GeglBuffer          *input,
@@ -188,8 +192,9 @@ process (GeglOperation       *operation,
          const GeglRectangle *result)
 {
   GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
+  GeglRectangle src_rect = gegl_operation_get_required_for_output (operation, "input", result);
 
-  demosaic (o, input, output);
+  demosaic (o, input, &src_rect, output, result);
 
   return  TRUE;
 }
@@ -204,7 +209,7 @@ gegl_chant_class_init (GeglChantClass *klass)
   operation_class = GEGL_OPERATION_CLASS (klass);
   filter_class    = GEGL_OPERATION_FILTER_CLASS (klass);
 
-  filter_class->process = process;
+  filter_class->process    = process;
   operation_class->prepare = prepare;
 
   operation_class->name        = "gegl:demosaic-bimedian";
diff --git a/operations/workshop/demosaic-simple.c b/operations/workshop/demosaic-simple.c
index 8310582..13c0356 100644
--- a/operations/workshop/demosaic-simple.c
+++ b/operations/workshop/demosaic-simple.c
@@ -33,34 +33,34 @@ gegl_chant_int (pattern, _("Bayer pattern"), 0, 3, 0,
 #include "gegl-chant.h"
 
 static void
-demosaic (GeglChantO *op,
-          GeglBuffer *src,
-          GeglBuffer *dst)
+demosaic (GeglChantO          *op,
+          GeglBuffer          *src,
+          const GeglRectangle *src_rect,
+          GeglBuffer          *dst,
+          const GeglRectangle *dst_rect)
 {
-  const GeglRectangle *src_extent = gegl_buffer_get_extent (src);
-  const GeglRectangle *dst_extent = gegl_buffer_get_extent (dst);
   gint x,y;
   gint offset;
   gfloat *src_buf;
   gfloat *dst_buf;
 
-  src_buf = g_new0 (gfloat, gegl_buffer_get_pixel_count (src));
-  dst_buf = g_new0 (gfloat, gegl_buffer_get_pixel_count (dst) * 3);
+  src_buf = g_new0 (gfloat, src_rect->width * src_rect->height * 1);
+  dst_buf = g_new0 (gfloat, dst_rect->width * dst_rect->height * 3);
 
-  gegl_buffer_get (src, 1.0, NULL, babl_format ("Y float"), src_buf, GEGL_AUTO_ROWSTRIDE);
+  gegl_buffer_get (src, 1.0, src_rect, babl_format ("Y float"), src_buf, GEGL_AUTO_ROWSTRIDE);
 
   offset=0;
-  for (y=src_extent->y; y < dst_extent->height + src_extent->y; y++)
+  for (y=src_rect->y; y < dst_rect->height + src_rect->y; y++)
     {
-      gint src_offset = (y-src_extent->y) * src_extent->width;
-      for (x=src_extent->x; x < dst_extent->width + src_extent->x; x++)
+      gint src_offset = (y-src_rect->y) * src_rect->width;
+      for (x=src_rect->x; x < dst_rect->width + src_rect->x; x++)
         {
           gfloat red=0.0;
           gfloat green=0.0;
           gfloat blue=0.0;
 
-          if (y<dst_extent->height+dst_extent->y &&
-              x<dst_extent->width+dst_extent->x)
+          if (y<dst_rect->height+dst_rect->y &&
+              x<dst_rect->width+dst_rect->x)
             {
           if ((y + op->pattern%2)%2==0)
             {
@@ -68,26 +68,26 @@ demosaic (GeglChantO *op,
                 {
                   blue=src_buf[src_offset+1];
                   green=src_buf[src_offset];
-                  red=src_buf[src_offset + src_extent->width];
+                  red=src_buf[src_offset + src_rect->width];
                 }
               else
                 {
                   blue=src_buf[src_offset];
                   green=src_buf[src_offset+1];
-                  red=src_buf[src_offset+1+src_extent->width];
+                  red=src_buf[src_offset+1+src_rect->width];
                 }
             }
           else
             {
               if ((x+op->pattern/2)%2==1)
                 {
-                  blue=src_buf[src_offset + src_extent->width + 1];
+                  blue=src_buf[src_offset + src_rect->width + 1];
                   green=src_buf[src_offset + 1];
                   red=src_buf[src_offset];
                 }
               else
                 {
-                  blue=src_buf[src_offset + src_extent->width];
+                  blue=src_buf[src_offset + src_rect->width];
                   green=src_buf[src_offset];
                   red=src_buf[src_offset + 1];
                 }
@@ -103,7 +103,7 @@ demosaic (GeglChantO *op,
         }
     }
 
-  gegl_buffer_set (dst, NULL, babl_format ("RGB float"), dst_buf, GEGL_AUTO_ROWSTRIDE);
+  gegl_buffer_set (dst, dst_rect, babl_format ("RGB float"), dst_buf, GEGL_AUTO_ROWSTRIDE);
   g_free (src_buf);
   g_free (dst_buf);
 }
@@ -112,7 +112,8 @@ static void prepare (GeglOperation *operation)
 {
   GeglOperationAreaFilter *area = GEGL_OPERATION_AREA_FILTER (operation);
   area->right = area->bottom = 1;
-  gegl_operation_set_format (operation, "output", babl_format ("RGBA float"));
+
+  gegl_operation_set_format (operation, "output", babl_format ("RGB float"));
 }
 
 static gboolean
@@ -125,11 +126,7 @@ process (GeglOperation       *operation,
   GeglBuffer   *temp_in;
   GeglRectangle compute = gegl_operation_get_required_for_output (operation, "input", result);
 
-  temp_in = gegl_buffer_create_sub_buffer (input, &compute);
-
-  demosaic (o, temp_in, output);
-
-  g_object_unref (temp_in);
+  demosaic (o, input, &compute, output, result);
 
   return  TRUE;
 }



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