gegl r2482 - in trunk: . gegl/buffer tests/buffer



Author: ok
Date: Tue Jun 17 20:51:37 2008
New Revision: 2482
URL: http://svn.gnome.org/viewvc/gegl?rev=2482&view=rev

Log:
* gegl/buffer/gegl-buffer-private.h: moved the linear API ..
* gegl/buffer/gegl-buffer-linear.h: into it's own header.
* gegl/buffer/Makefile.am: added gegl-buffer-linear.h
* gegl/buffer/gegl-buffer-linear.c: made all accesor functions take
a GeglRectangle instead of passing width and height as individual ints.
* gegl/buffer/gegl-buffer-iterator.h: improved documentation.
* tests/buffer/Makefile: output which files are only found in output
after running.


Added:
   trunk/gegl/buffer/gegl-buffer-linear.h
Modified:
   trunk/ChangeLog
   trunk/gegl/buffer/Makefile.am
   trunk/gegl/buffer/gegl-buffer-iterator.h
   trunk/gegl/buffer/gegl-buffer-linear.c
   trunk/gegl/buffer/gegl-buffer-private.h
   trunk/tests/buffer/Makefile

Modified: trunk/gegl/buffer/Makefile.am
==============================================================================
--- trunk/gegl/buffer/Makefile.am	(original)
+++ trunk/gegl/buffer/Makefile.am	Tue Jun 17 20:51:37 2008
@@ -41,6 +41,7 @@
     gegl-buffer.h		\
     gegl-buffer-private.h	\
     gegl-buffer-iterator.h	\
+    gegl-buffer-linear.h	\
     gegl-buffer-load.h		\
     gegl-buffer-save.h		\
     gegl-buffer-types.h		\

Modified: trunk/gegl/buffer/gegl-buffer-iterator.h
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-iterator.h	(original)
+++ trunk/gegl/buffer/gegl-buffer-iterator.h	Tue Jun 17 20:51:37 2008
@@ -94,4 +94,22 @@
 gboolean             gegl_buffer_iterator_next (GeglBufferIterator *iterator);
 
 
+#ifdef EXAMPLE
+
+  GeglBufferIterator *gi;
+  gi = gegl_buffer_iterator_new (buffer, roi,
+                                 babl_format("Y' float"), GEGL_BUFFER_WRITE);
+  while (gegl_buffer_iterator_next (gi))
+    {
+      gfloat *buf = gi->data[0];
+      gint    i;
+      for (i=0; i<gi->length; i++)
+        {
+          buf[i]=0.5;
+        }
+    }
+
+
+#endif
+
 #endif

Modified: trunk/gegl/buffer/gegl-buffer-linear.c
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-linear.c	(original)
+++ trunk/gegl/buffer/gegl-buffer-linear.c	Tue Jun 17 20:51:37 2008
@@ -17,10 +17,10 @@
                          const Babl          *format,
                          gint                 rowstride)
 {
-  GeglRectangle empty={0,0,0,0};
-
   if (extent==NULL)
-    extent = &empty;
+    {
+      g_error ("got a NULL extent");
+    }
 
   if (format==NULL)
     format = babl_format ("RGBA float");
@@ -28,11 +28,17 @@
   if (rowstride <= 0)
     rowstride = extent->width;
 
+  /* creating a linear buffer for GeglBuffer is a matter of
+   * requesting the correct parameters when creating the
+   * buffer
+   */
   return g_object_new (GEGL_TYPE_BUFFER,
-                       "x", extent->x,
-                       "y", extent->y,
-                       "width", extent->width,
-                       "height", extent->height,
+                       "x",          extent->x,
+                       "y",          extent->y,
+                       "shift-x",    extent->x,
+                       "shift-y",    extent->y,
+                       "width",      extent->width,
+                       "height",     extent->height,
                        "tile-width", rowstride,
                        "tile-height", extent->height,
                        "format", format,
@@ -46,7 +52,8 @@
   return gegl_buffer_linear_new2 (extent, format, 0);
 }
 
-
+/* XXX:
+ * this should probably be abstracted into a gegl_buffer_cache_insert_tile */
 void gegl_tile_handler_cache_insert (GeglTileHandlerCache *cache,
                                      GeglTile             *tile,
                                      gint                  x,
@@ -54,24 +61,24 @@
                                      gint                  z);
 
 GeglBuffer *
-gegl_buffer_linear_new_from_data (const gpointer data,
-                                  const Babl    *format,
-                                  gint           width,
-                                  gint           height,
-                                  gint           rowstride,
-                                  GCallback      destroy_fn,
-                                  gpointer       destroy_fn_data)
+gegl_buffer_linear_new_from_data (const gpointer       data,
+                                  const Babl          *format,
+                                  const GeglRectangle *extent,
+                                  gint                 rowstride,
+                                  GCallback            destroy_fn,
+                                  gpointer             destroy_fn_data)
 {
   GeglBuffer *buffer;
-  GeglRectangle extent={0,0,width, height};
 
   g_assert (format);
 
-  if (rowstride <= 0)
-    rowstride = width;
+  if (rowstride <= 0) /* handle both 0 and negative coordinates as a request
+                       * for a rowstride, negative rowstrides are not supported.
+                       */
+    rowstride = extent->width;
   else
     rowstride = rowstride / format->format.bytes_per_pixel;
-  buffer = gegl_buffer_linear_new2 (&extent, format, rowstride);
+    buffer = gegl_buffer_linear_new2 (extent, format, rowstride);
 
   {
     GeglTile *tile = g_object_new (GEGL_TYPE_TILE, NULL);
@@ -83,7 +90,7 @@
     tile->y = 0;
     tile->z = 0;
     tile->data       = (gpointer)data;
-    tile->size       = format->format.bytes_per_pixel * rowstride * height;
+    tile->size       = format->format.bytes_per_pixel * rowstride * extent->height;
     tile->next_shared = tile;
     tile->prev_shared = tile;
 
@@ -98,24 +105,36 @@
   return buffer;
 }
 
+/* the information kept about a linear buffer, multiple requests can
+ * be handled by the same structure, the multiple clients would have
+ * an immediate shared access to the linear buffer.
+ */
 typedef struct {
   gpointer       buf;
   GeglRectangle  extent;
   const Babl    *format;
+  gint           refs;
 } BufferInfo;
 
+/* FIXME: make this use direct data access in more cases than the
+ * case of the base buffer.
+ */
 gpointer *
-gegl_buffer_linear_open (GeglBuffer *buffer,
-                         gint       *width,
-                         gint       *height,
-                         gint       *rowstride,
-                         const Babl *format)
+gegl_buffer_linear_open (GeglBuffer          *buffer,
+                         const GeglRectangle *extent,   /* if NULL, use buf  */
+                         gint                *rowstride,/* returns rowstride */
+                         const Babl          *format)   /* if NULL, from buf */
 {
   if (!format)
     format = buffer->format;
 
-  if (buffer->extent.width == buffer->tile_width &&
-      buffer->extent.height == buffer->tile_height &&
+  if (extent == NULL)
+    extent=&buffer->extent;
+
+  if (extent->x     == buffer->extent.x &&
+      extent->y     == buffer->extent.y &&
+      extent->width == buffer->tile_width &&
+      extent->height <= buffer->tile_height &&
       buffer->format == format)
     {
       GeglTile *tile;
@@ -124,7 +143,10 @@
       g_assert (buffer->tile_height == buffer->tile_storage->tile_height);
 
       tile = g_object_get_data (G_OBJECT (buffer), "linear-tile");
-      g_assert (tile == NULL);
+      g_assert (tile == NULL); /* We need to reference count returned direct
+                                * linear buffers to allow multiple open like
+                                * the copying case.
+                                */
       tile = gegl_tile_source_get_tile ((GeglTileSource*) (buffer),
                                         0,0,0);
       g_assert (tile);
@@ -133,14 +155,34 @@
 
       g_object_set_data (G_OBJECT (buffer), "linear-tile", tile);
 
-      if(width)*width = buffer->extent.width;
-      if(height)*height = buffer->extent.height;
       if(rowstride)*rowstride = buffer->tile_storage->tile_width * format->format.bytes_per_pixel;
       return (gpointer)gegl_tile_get_data (tile);
     }
-  /* FIXME: first check if there is a linear buffer, we should share that one to
-   * avoid conflicts.
+  /* first check if there is a linear buffer, share the existing buffer if one
+   * exists.
    */
+    {
+      GList *linear_buffers;
+      GList *iter;
+      BufferInfo *info = NULL;
+      linear_buffers = g_object_get_data (G_OBJECT (buffer), "linear-buffers");
+
+      for (iter = linear_buffers; iter; iter=iter->next)
+        {
+          info = iter->data;
+          if (info->format        == format           &&
+              info->extent.x      == buffer->extent.x &&
+              info->extent.y      == buffer->extent.y &&
+              info->extent.width  == buffer->extent.width &&
+              info->extent.height == buffer->extent.height
+              )
+            {
+              info->refs++;
+              return info->buf;
+            }
+        }
+    }
+
   {
     BufferInfo *info = g_new0 (BufferInfo, 1);
     GList *linear_buffers;
@@ -153,8 +195,6 @@
     info->format = format;
 
     rs = info->extent.width * format->format.bytes_per_pixel;
-    if(width)*width = info->extent.width;
-    if(height)*height = info->extent.height;
     if(rowstride)*rowstride = rs;
 
     info->buf = gegl_malloc (rs * info->extent.height);
@@ -189,6 +229,13 @@
           info = iter->data;
           if (info->buf == linear)
             {
+              info->refs--;
+
+              if (info->refs>0)
+                return; /* there are still others holding a reference to
+                         * this linear buffer
+                         */
+
               gegl_buffer_set (buffer, &info->extent, info->format, info->buf, 0);
               break;
             }

Added: trunk/gegl/buffer/gegl-buffer-linear.h
==============================================================================
--- (empty file)
+++ trunk/gegl/buffer/gegl-buffer-linear.h	Tue Jun 17 20:51:37 2008
@@ -0,0 +1,75 @@
+#ifndef __GEGL_BUFFER_LINEAR_H
+#define __GEGL_BUFFER_LINEAR_H
+
+/**
+ * gegl_buffer_linear_new:
+ * @extent: dimensions of buffer.
+ * @format: desired pixel format.
+ *
+ * Creates a GeglBuffer backed by a linear memory buffer, of the given
+ * @extent in the specified @format. babl_format ("R'G'B'A u8") for instance
+ * to make a normal 8bit buffer.
+ *
+ * Returns: a GeglBuffer that can be used as any other GeglBuffer.
+ */
+GeglBuffer *gegl_buffer_linear_new           (const GeglRectangle *extent,
+                                              const Babl          *format);
+
+/**
+ * gegl_buffer_linear_new_from_data:
+ * @data: a pointer to a linear buffer in memory.
+ * @format: the format of the data in memory
+ * @width: the width of the buffer
+ * @height: the height of the buffer
+ * @rowstride: the number of bytes between rowstarts in memory (or 0 to
+ *             autodetect)
+ * @destory_fn: function to call to free data or NULL if memory should not be
+ *              freed.
+ * @destroy_fn_data: extra argument to be passed to void destroy(ptr, data) type
+ *              function.
+ *
+ * Creates a GeglBuffer backed by a linear memory buffer that already exists,
+ * of the given @extent in the specified @format. babl_format ("R'G'B'A u8")
+ * for instance to make a normal 8bit buffer. 
+ *
+ * Returns: a GeglBuffer that can be used as any other GeglBuffer.
+ */
+GeglBuffer * gegl_buffer_linear_new_from_data (const gpointer       data,
+                                                const Babl          *format,
+                                                const GeglRectangle *extent,
+                                                gint                 rowstride,
+                                                GCallback            destroy_fn,
+                                                gpointer             destroy_fn_data);
+
+/**
+ * gegl_buffer_linear_open:
+ * @buffer: a #GeglBuffer.
+ * @roi: region to open, pass NULL for entire buffer.
+ * @rowstride: return location for rowstride.
+ * @format: desired format or NULL to use buffers format.
+ *
+ * Raw direct random access to the full data of a buffer in linear memory.
+ *
+ * Returns: a pointer to a linear memory region describing the buffer, if the
+ * request is compatible with the underlying data storage direct access
+ * to the underlying data is provided.
+ */
+gpointer       *gegl_buffer_linear_open      (GeglBuffer          *buffer,
+                                              const GeglRectangle *extent,
+                                              gint                *rowstride,
+                                              const Babl          *format);
+
+/**
+ * gegl_buffer_linear_close:
+ * @buffer: a #GeglBuffer.
+ * @linear: a previously returned buffer.
+ *
+ * This function makes sure GeglBuffer and underlying code is aware of changes
+ * being made to the linear buffer. If the request was not a compatible one
+ * it is written back to the buffer. Multiple concurrent users can be handed
+ * the same buffer (both raw access and converted).
+ */
+void            gegl_buffer_linear_close     (GeglBuffer    *buffer,
+                                              gpointer       linear);
+
+#endif

Modified: trunk/gegl/buffer/gegl-buffer-private.h
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-private.h	(original)
+++ trunk/gegl/buffer/gegl-buffer-private.h	Tue Jun 17 20:51:37 2008
@@ -24,6 +24,7 @@
 #include "gegl-sampler.h"
 #include "gegl-tile-handler.h"
 #include "gegl-buffer-iterator.h"
+#include "gegl-buffer-linear.h"
 
 #define GEGL_BUFFER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  GEGL_TYPE_BUFFER, GeglBufferClass))
 #define GEGL_IS_BUFFER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEGL_TYPE_BUFFER))
@@ -101,24 +102,6 @@
 gboolean             gegl_buffer_lock        (GeglBuffer *buffer);
 gboolean             gegl_buffer_unlock      (GeglBuffer *buffer);
 
-GeglBuffer *gegl_buffer_linear_new           (const GeglRectangle *extent,
-                                              const Babl          *format);
-
-GeglBuffer *gegl_buffer_linear_new_from_data (const gpointer data,
-                                              const Babl    *format,
-                                              gint           width,
-                                              gint           height,
-                                              gint           rowstride,
-                                              GCallback      destroy_fn,
-                                              gpointer       destroy_fn_data);
-
-gpointer       *gegl_buffer_linear_open      (GeglBuffer    *buffer,
-                                              gint          *width,
-                                              gint          *height,
-                                              gint          *rowstride,
-                                              const Babl    *format);
-void            gegl_buffer_linear_close     (GeglBuffer    *buffer,
-                                              gpointer       linear);
 
 
 GType gegl_sampler_type_from_interpolation (GeglInterpolation interpolation);

Modified: trunk/tests/buffer/Makefile
==============================================================================
--- trunk/tests/buffer/Makefile	(original)
+++ trunk/tests/buffer/Makefile	Tue Jun 17 20:51:37 2008
@@ -25,6 +25,7 @@
 	@cat report
 	@echo ''
 	@echo `cat report | grep identical | wc -l` of `ls -1 reference | wc -l` tests succesful.
+	@cat report | grep Only
 	rm report
 
 clean:



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