gegl r2217 - in trunk: . gegl/buffer



Author: ok
Date: Tue Apr 22 00:02:55 2008
New Revision: 2217
URL: http://svn.gnome.org/viewvc/gegl?rev=2217&view=rev

Log:
Make GeglBuffer able to use a serialized buffer directly as swap, as
well as synchronize a buffer so that it can be resumed from swap.
* gegl/buffer/gegl-buffer-load.c:
(gegl_buffer_read_header): moved magic check to header read.
(gegl_buffer_open): replaced by GeglBuffer being backed by a
serialized GeglBuffer.
* gegl/buffer/gegl-buffer.c: (gegl_buffer_constructor),
(gegl_buffer_class_init), (gegl_buffer_new_from_path):
made it possible to create buffer using a path.
* gegl/buffer/gegl-tile-backend-file.c: (flush),
(gegl_tile_backend_file_constructor): allow opening already
written swap files.
* gegl/buffer/gegl-tile-backend.h: provide some private storage to
store a pointer to the header used to read in a buffer.


Modified:
   trunk/ChangeLog
   trunk/gegl/buffer/gegl-buffer-load.c
   trunk/gegl/buffer/gegl-buffer.c
   trunk/gegl/buffer/gegl-tile-backend-file.c
   trunk/gegl/buffer/gegl-tile-backend.h

Modified: trunk/gegl/buffer/gegl-buffer-load.c
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-load.c	(original)
+++ trunk/gegl/buffer/gegl-buffer-load.c	Tue Apr 22 00:02:55 2008
@@ -90,6 +90,15 @@
                    ret->header.tile_width,
                    ret->header.tile_height,
                    (guint)ret->block.next);
+
+  if (!(ret->header.magic[0]=='G' &&
+       ret->header.magic[1]=='E' &&
+       ret->header.magic[2]=='G' &&
+       ret->header.magic[3]=='L'))
+    {
+      g_warning ("Magic is wrong! %s", ret->header.magic);
+    }
+
   return ret;
 }
 
@@ -214,10 +223,16 @@
 GeglBuffer *
 gegl_buffer_open (const gchar *path)
 {
+  sanity();
+
+  return g_object_new (GEGL_TYPE_BUFFER, "path", path, NULL);
+
+#if 0  /* old code that feeds tile by tile into the buffer */
+
   GeglBuffer *ret;
-  LoadInfo *info = g_slice_new0 (LoadInfo);
 
-  sanity();
+  LoadInfo *info = g_slice_new0 (LoadInfo);
+  
 
   info->path = g_strdup (path);
   info->file = g_file_new_for_commandline_arg (info->path);
@@ -241,13 +256,6 @@
   }
 
 
-  if (!(info->header.magic[0]=='G' &&
-       info->header.magic[1]=='E' &&
-       info->header.magic[2]=='G' &&
-       info->header.magic[3]=='L'))
-    {
-      g_warning ("Magic is wrong! %s", info->header.magic);
-    }
 
   info->tile_size    = info->header.tile_width *
                        info->header.tile_height *
@@ -313,4 +321,5 @@
 
   load_info_destroy (info);
   return ret;
+#endif
 }

Modified: trunk/gegl/buffer/gegl-buffer.c
==============================================================================
--- trunk/gegl/buffer/gegl-buffer.c	(original)
+++ trunk/gegl/buffer/gegl-buffer.c	Tue Apr 22 00:02:55 2008
@@ -41,6 +41,7 @@
 #include <glib-object.h>
 #include <glib/gstdio.h>
 #include <glib/gprintf.h>
+#include <gio/gio.h>
 
 #include "gegl-types.h"
 
@@ -60,6 +61,7 @@
 #include "gegl-types.h"
 #include "gegl-utils.h"
 #include "gegl-id-pool.h"
+#include "gegl-buffer-index.h"
 
 
 G_DEFINE_TYPE (GeglBuffer, gegl_buffer, GEGL_TYPE_TILE_HANDLER)
@@ -93,6 +95,8 @@
                                                  gint        y,
                                                  gint        width,
                                                  gint        height);
+static GeglBuffer *
+gegl_buffer_new_from_path (const gchar *path);
 
 static inline gint needed_tiles (gint w,
                                  gint stride)
@@ -375,24 +379,52 @@
        * source (this adds a redirectin buffer in between for
        * all "allocated from format", type buffers.
        */
-      g_assert (buffer->format);
+      if (buffer->path)
+        {
+          GeglBufferHeader *header;
+          source = GEGL_TILE_SOURCE (gegl_buffer_new_from_path (buffer->path));
+          /* after construction,. x and y should be set to reflect
+           * the top level behavior exhibited by this buffer object.
+           */
+          g_object_set (buffer,
+                        "source", source,
+                        NULL);
+          g_object_unref (source);
+
+          g_assert (source);
+          backend = gegl_buffer_backend (GEGL_BUFFER (source));
+          g_assert (backend);
+          header = backend->header;
+          buffer->extent.x = header->x;
+          buffer->extent.y = header->y;
+          buffer->extent.width = header->width;
+          buffer->extent.height = header->height;
+          buffer->format = backend->format;
+        }
+      else if (buffer->format)
+        {
 
-      source = GEGL_TILE_SOURCE (gegl_buffer_new_from_format (buffer->format,
-                                                         buffer->extent.x,
-                                                         buffer->extent.y,
-                                                         buffer->extent.width,
-                                                         buffer->extent.height));
-      /* after construction,. x and y should be set to reflect
-       * the top level behavior exhibited by this buffer object.
-       */
-      g_object_set (buffer,
-                    "source", source,
-                    NULL);
-      g_object_unref (source);
-
-      g_assert (source);
-      backend = gegl_buffer_backend (GEGL_BUFFER (source));
-      g_assert (backend);
+          source = GEGL_TILE_SOURCE (gegl_buffer_new_from_format (buffer->format,
+                                                             buffer->extent.x,
+                                                             buffer->extent.y,
+                                                             buffer->extent.width,
+                                                             buffer->extent.height));
+          /* after construction,. x and y should be set to reflect
+           * the top level behavior exhibited by this buffer object.
+           */
+          g_object_set (buffer,
+                        "source", source,
+                        NULL);
+          g_object_unref (source);
+
+          g_assert (source);
+          backend = gegl_buffer_backend (GEGL_BUFFER (source));
+          g_assert (backend);
+        }
+      else
+        {
+          g_warning ("not enough data to have a tile source for our buffer");
+        }
     }
 
   g_assert (backend);
@@ -650,9 +682,9 @@
                                                      G_PARAM_CONSTRUCT_ONLY));
 
   g_object_class_install_property (gobject_class, PROP_PATH,
-                                   g_param_spec_string ("path", "Path", "URI to where the buffer is stored",
-                                                     "/tmp/hm",
-                                                     G_PARAM_READWRITE));
+                                   g_param_spec_string ("path", "Path",
+                                                        "URI to where the buffer is stored",
+                                     NULL, G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
 }
 
 static void
@@ -823,6 +855,30 @@
 
 
 
+
+static GeglBuffer *
+gegl_buffer_new_from_path (const gchar *path)
+{
+  GeglTileStorage *tile_storage;
+  GeglBuffer  *buffer;
+
+  tile_storage = g_object_new (GEGL_TYPE_TILE_STORAGE,
+                              "format", babl_format,
+                              "path",   path,
+                              NULL);
+  buffer = g_object_new (GEGL_TYPE_BUFFER,
+                                    "source", tile_storage,
+                                    /*"x", x,
+                                    "y", y,
+                                    "width", width,
+                                    "height", height,*/
+                                    NULL);
+  /* XXX: query backend about width/height? (this seems odd) */
+
+  g_object_unref (tile_storage);
+  return buffer;
+}
+
 static GeglBuffer *
 gegl_buffer_new_from_format (const void *babl_format,
                              gint        x,

Modified: trunk/gegl/buffer/gegl-tile-backend-file.c
==============================================================================
--- trunk/gegl/buffer/gegl-tile-backend-file.c	(original)
+++ trunk/gegl/buffer/gegl-tile-backend-file.c	Tue Apr 22 00:02:55 2008
@@ -70,6 +70,10 @@
                                 * to be able to keep track of the ->next
                                 * offsets in the blocks.
                                 */
+
+  /* loading buffer */
+
+  GList *tiles;
 };
 
 
@@ -468,6 +472,7 @@
 
   tiles = g_hash_table_get_keys (self->index);
 
+/*  g_assert(g_seekable_seek (G_SEEKABLE (self->o), self->header.next, G_SEEK_SET, NULL, NULL));*/
   /* save the index */
   {
     GList *iter;
@@ -648,32 +653,71 @@
 {
   GObject      *object;
   GeglTileBackendFile *self;
+  GeglTileBackend *backend;
 
   object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
   self   = GEGL_TILE_BACKEND_FILE (object);
+  backend = GEGL_TILE_BACKEND (object);
 
   GEGL_NOTE (TILE_BACKEND, "constructing file backend: %s", self->path);
   self->file = g_file_new_for_commandline_arg (self->path);
-  self->o = G_OUTPUT_STREAM (g_file_replace (self->file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL));
-  g_output_stream_flush (self->o, NULL, NULL);
-  self->i = G_INPUT_STREAM (g_file_read (self->file, NULL, NULL));
+  
+  self->index = g_hash_table_new (hashfunc, equalfunc);
 
+  /* if the file already exist we try to open it for appending instead of replacing */
+  if (g_file_query_exists (self->file, NULL))
+    {
+      goffset offset;
 
-  self->next_pre_alloc = 256;  /* reserved space for header */
-  self->total          = 256;  /* reserved space for header */
-  g_assert(g_seekable_seek (G_SEEKABLE (self->o), 256, G_SEEK_SET, NULL, NULL));
+      self->i = G_INPUT_STREAM (g_file_read (self->file, NULL, NULL));
+      self->o = G_OUTPUT_STREAM (g_file_append_to (self->file, G_FILE_CREATE_NONE, NULL, NULL));
+      self->header = gegl_buffer_read_header (self->i, &offset)->header;
+      backend->tile_width = self->header.tile_width;
+      backend->tile_height = self->header.tile_height;
+      backend->format = babl_format (self->header.description);
+      /* we are overriding all of the work of the actual constructor here */
+      backend->px_size = backend->format->format.bytes_per_pixel;
+      backend->tile_size = backend->tile_width * backend->tile_height * backend->px_size;
 
+      offset = self->header.next;
+      self->tiles = gegl_buffer_read_index (self->i, &offset);
 
-  if (!self->file)
+      /* insert each of the entries into the hash table */
+      {
+        /* compute total from and next pre alloc by monitoring tiles as they
+         * are added here
+         */
+        goffset max=0;
+        GList *iter;
+        for (iter = self->tiles; iter; iter=iter->next)
+          {
+            GeglBufferItem *item = iter->data;
+            if (item->tile.offset > max)
+              max = item->tile.offset + backend->tile_size;
+            g_hash_table_insert (self->index, iter->data, iter->data);
+          }
+        g_list_free (self->tiles);
+        self->next_pre_alloc = max;
+        self->total          = max;
+        self->tiles = NULL;
+      }
+    }
+  else
     {
-      g_warning ("Unable to open swap file '%s'\n",self->path);
-      return NULL;
+      self->o = G_OUTPUT_STREAM (g_file_replace (self->file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL));
+      g_output_stream_flush (self->o, NULL, NULL);
+      self->i = G_INPUT_STREAM (g_file_read (self->file, NULL, NULL));
+      self->next_pre_alloc = 256;  /* reserved space for header */
+      self->total          = 256;  /* reserved space for header */
+      g_assert(g_seekable_seek (G_SEEKABLE (self->o), 256, G_SEEK_SET, NULL, NULL));
     }
+
   g_assert (self->file);
   g_assert (self->i);
   g_assert (self->o);
 
-  self->index = g_hash_table_new (hashfunc, equalfunc);
+
+  backend->header = &self->header;
 
   return object;
 }

Modified: trunk/gegl/buffer/gegl-tile-backend.h
==============================================================================
--- trunk/gegl/buffer/gegl-tile-backend.h	(original)
+++ trunk/gegl/buffer/gegl-tile-backend.h	Tue Apr 22 00:02:55 2008
@@ -39,6 +39,9 @@
   Babl           *format;        /* defaults to the babl format "R'G'B'A u8" */
   gint            px_size;       /* size of a single pixel in bytes */
   gint            tile_size;     /* size of an entire tile in bytes */
+
+  /* private */
+  gpointer        header;
 };
 
 struct _GeglTileBackendClass



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