[gimp/goat-invasion: 411/412] app: port XCF loading to writing to the drawable's GeglBuffer



commit b436b4cdad539086d3ab128cf8e35c59bf0dcf40
Author: Michael Natterer <mitch gimp org>
Date:   Mon Apr 2 23:32:38 2012 +0200

    app: port XCF loading to writing to the drawable's GeglBuffer

 app/gegl/gimp-gegl-tile-compat.c |   23 +++-
 app/gegl/gimp-gegl-tile-compat.h |   14 ++-
 app/xcf/xcf-load.c               |  269 +++++++++++++++++++-------------------
 app/xcf/xcf-private.h            |    3 +
 4 files changed, 160 insertions(+), 149 deletions(-)
---
diff --git a/app/gegl/gimp-gegl-tile-compat.c b/app/gegl/gimp-gegl-tile-compat.c
index b9b08b8..d92e8f8 100644
--- a/app/gegl/gimp-gegl-tile-compat.c
+++ b/app/gegl/gimp-gegl-tile-compat.c
@@ -27,6 +27,20 @@
 #include "gimp-gegl-tile-compat.h"
 
 
+gint
+gimp_gegl_buffer_get_n_tile_rows (GeglBuffer *buffer,
+                                  gint        tile_height)
+{
+  return (gegl_buffer_get_height (buffer) + tile_height - 1) / tile_height;
+}
+
+gint
+gimp_gegl_buffer_get_n_tile_cols (GeglBuffer *buffer,
+                                  gint        tile_width)
+{
+  return (gegl_buffer_get_width (buffer) + tile_width - 1) / tile_width;
+}
+
 gboolean
 gimp_gegl_buffer_get_tile_rect (GeglBuffer    *buffer,
                                 gint           tile_width,
@@ -39,13 +53,8 @@ gimp_gegl_buffer_get_tile_rect (GeglBuffer    *buffer,
   gint tile_row;
   gint tile_column;
 
-  n_tile_rows =
-    (gegl_buffer_get_height (buffer) + tile_height - 1) /
-    tile_height;
-
-  n_tile_columns =
-    (gegl_buffer_get_width (buffer) + tile_width - 1) /
-    tile_width;
+  n_tile_rows    = gimp_gegl_buffer_get_n_tile_rows (buffer, tile_height);
+  n_tile_columns = gimp_gegl_buffer_get_n_tile_cols (buffer, tile_width);
 
   if (tile_num > n_tile_rows * n_tile_columns - 1)
     return FALSE;
diff --git a/app/gegl/gimp-gegl-tile-compat.h b/app/gegl/gimp-gegl-tile-compat.h
index 1d99852..2dc523e 100644
--- a/app/gegl/gimp-gegl-tile-compat.h
+++ b/app/gegl/gimp-gegl-tile-compat.h
@@ -22,11 +22,15 @@
 #define __GIMP_GEGL_TILE_COMPAT_H__
 
 
-gboolean   gimp_gegl_buffer_get_tile_rect (GeglBuffer    *buffer,
-                                           gint           tile_width,
-                                           gint           tile_height,
-                                           gint           tile_num,
-                                           GeglRectangle *rect);
+gint       gimp_gegl_buffer_get_n_tile_rows (GeglBuffer    *buffer,
+                                             gint           tile_height);
+gint       gimp_gegl_buffer_get_n_tile_cols (GeglBuffer    *buffer,
+                                             gint           tile_width);
+gboolean   gimp_gegl_buffer_get_tile_rect   (GeglBuffer    *buffer,
+                                             gint           tile_width,
+                                             gint           tile_height,
+                                             gint           tile_num,
+                                             GeglRectangle *rect);
 
 
 #endif /* __GIMP_GEGL_TILE_COMPAT_H__ */
diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c
index 956874b..16b56a3 100644
--- a/app/xcf/xcf-load.c
+++ b/app/xcf/xcf-load.c
@@ -28,12 +28,10 @@
 
 #include "core/core-types.h"
 
-#include "base/tile.h"
-#include "base/tile-manager.h"
-#include "base/tile-manager-private.h"
-
 #include "config/gimpcoreconfig.h"
 
+#include "gegl/gimp-gegl-tile-compat.h"
+
 #include "core/gimp.h"
 #include "core/gimpcontainer.h"
 #include "core/gimpdrawable-private.h" /* eek */
@@ -73,52 +71,54 @@
 
 /* #define GIMP_XCF_PATH_DEBUG */
 
-static void            xcf_load_add_masks     (GimpImage    *image);
-static gboolean        xcf_load_image_props   (XcfInfo      *info,
-                                               GimpImage    *image);
-static gboolean        xcf_load_layer_props   (XcfInfo      *info,
-                                               GimpImage    *image,
-                                               GimpLayer   **layer,
-                                               GList       **item_path,
-                                               gboolean     *apply_mask,
-                                               gboolean     *edit_mask,
-                                               gboolean     *show_mask,
-                                               guint32      *text_layer_flags,
-                                               guint32      *group_layer_flags);
-static gboolean        xcf_load_channel_props (XcfInfo      *info,
-                                               GimpImage    *image,
-                                               GimpChannel **channel);
-static gboolean        xcf_load_prop          (XcfInfo      *info,
-                                               PropType     *prop_type,
-                                               guint32      *prop_size);
-static GimpLayer     * xcf_load_layer         (XcfInfo      *info,
-                                               GimpImage    *image,
-                                               GList       **item_path);
-static GimpChannel   * xcf_load_channel       (XcfInfo      *info,
-                                               GimpImage    *image);
-static GimpLayerMask * xcf_load_layer_mask    (XcfInfo      *info,
-                                               GimpImage    *image);
-static gboolean        xcf_load_hierarchy     (XcfInfo      *info,
-                                               TileManager  *tiles);
-static gboolean        xcf_load_level         (XcfInfo      *info,
-                                               TileManager  *tiles);
-static gboolean        xcf_load_tile          (XcfInfo      *info,
-                                               Tile         *tile);
-static gboolean        xcf_load_tile_rle      (XcfInfo      *info,
-                                               Tile         *tile,
-                                               gint          data_length);
-static GimpParasite  * xcf_load_parasite      (XcfInfo      *info);
-static gboolean        xcf_load_old_paths     (XcfInfo      *info,
-                                               GimpImage    *image);
-static gboolean        xcf_load_old_path      (XcfInfo      *info,
-                                               GimpImage    *image);
-static gboolean        xcf_load_vectors       (XcfInfo      *info,
-                                               GimpImage    *image);
-static gboolean        xcf_load_vector        (XcfInfo      *info,
-                                               GimpImage    *image);
-
-static gboolean        xcf_skip_unknown_prop  (XcfInfo      *info,
-                                               gsize         size);
+static void            xcf_load_add_masks     (GimpImage     *image);
+static gboolean        xcf_load_image_props   (XcfInfo       *info,
+                                               GimpImage     *image);
+static gboolean        xcf_load_layer_props   (XcfInfo       *info,
+                                               GimpImage     *image,
+                                               GimpLayer    **layer,
+                                               GList        **item_path,
+                                               gboolean      *apply_mask,
+                                               gboolean      *edit_mask,
+                                               gboolean      *show_mask,
+                                               guint32       *text_layer_flags,
+                                               guint32       *group_layer_flags);
+static gboolean        xcf_load_channel_props (XcfInfo       *info,
+                                               GimpImage     *image,
+                                               GimpChannel  **channel);
+static gboolean        xcf_load_prop          (XcfInfo       *info,
+                                               PropType      *prop_type,
+                                               guint32       *prop_size);
+static GimpLayer     * xcf_load_layer         (XcfInfo       *info,
+                                               GimpImage     *image,
+                                               GList        **item_path);
+static GimpChannel   * xcf_load_channel       (XcfInfo       *info,
+                                               GimpImage     *image);
+static GimpLayerMask * xcf_load_layer_mask    (XcfInfo       *info,
+                                               GimpImage     *image);
+static gboolean        xcf_load_buffer        (XcfInfo       *info,
+                                               GeglBuffer    *buffer);
+static gboolean        xcf_load_level         (XcfInfo       *info,
+                                               GeglBuffer    *buffer);
+static gboolean        xcf_load_tile          (XcfInfo       *info,
+                                               GeglBuffer    *buffer,
+                                               GeglRectangle *tile_rect);
+static gboolean        xcf_load_tile_rle      (XcfInfo       *info,
+                                               GeglBuffer    *buffer,
+                                               GeglRectangle *tile_rect,
+                                               gint           data_length);
+static GimpParasite  * xcf_load_parasite      (XcfInfo       *info);
+static gboolean        xcf_load_old_paths     (XcfInfo       *info,
+                                               GimpImage     *image);
+static gboolean        xcf_load_old_path      (XcfInfo       *info,
+                                               GimpImage     *image);
+static gboolean        xcf_load_vectors       (XcfInfo       *info,
+                                               GimpImage     *image);
+static gboolean        xcf_load_vector        (XcfInfo       *info,
+                                               GimpImage     *image);
+
+static gboolean        xcf_skip_unknown_prop  (XcfInfo       *info,
+                                               gsize          size);
 
 
 #define xcf_progress_update(info) G_STMT_START  \
@@ -1147,8 +1147,8 @@ xcf_load_layer (XcfInfo    *info,
       if (! xcf_seek_pos (info, hierarchy_offset, NULL))
         goto error;
 
-      if (! xcf_load_hierarchy (info,
-                                gimp_drawable_get_tiles (GIMP_DRAWABLE (layer))))
+      if (! xcf_load_buffer (info,
+                             gimp_drawable_get_buffer (GIMP_DRAWABLE (layer))))
         goto error;
 
       xcf_progress_update (info);
@@ -1239,8 +1239,8 @@ xcf_load_channel (XcfInfo   *info,
   if (!xcf_seek_pos (info, hierarchy_offset, NULL))
     goto error;
 
-  if (!xcf_load_hierarchy (info,
-                           gimp_drawable_get_tiles (GIMP_DRAWABLE (channel))))
+  if (!xcf_load_buffer (info,
+                        gimp_drawable_get_buffer (GIMP_DRAWABLE (channel))))
     goto error;
 
   xcf_progress_update (info);
@@ -1298,8 +1298,8 @@ xcf_load_layer_mask (XcfInfo   *info,
   if (! xcf_seek_pos (info, hierarchy_offset, NULL))
     goto error;
 
-  if (!xcf_load_hierarchy (info,
-                           gimp_drawable_get_tiles (GIMP_DRAWABLE (layer_mask))))
+  if (!xcf_load_buffer (info,
+                        gimp_drawable_get_buffer (GIMP_DRAWABLE (layer_mask))))
     goto error;
 
   xcf_progress_update (info);
@@ -1316,15 +1316,18 @@ xcf_load_layer_mask (XcfInfo   *info,
 }
 
 static gboolean
-xcf_load_hierarchy (XcfInfo     *info,
-                    TileManager *tiles)
+xcf_load_buffer (XcfInfo    *info,
+                 GeglBuffer *buffer)
 {
-  guint32 saved_pos;
-  guint32 offset;
-  guint32 junk;
-  gint    width;
-  gint    height;
-  gint    bpp;
+  const Babl *format;
+  guint32     saved_pos;
+  guint32     offset;
+  guint32     junk;
+  gint        width;
+  gint        height;
+  gint        bpp;
+
+  format = gegl_buffer_get_format (buffer);
 
   info->cp += xcf_read_int32 (info->fp, (guint32 *) &width, 1);
   info->cp += xcf_read_int32 (info->fp, (guint32 *) &height, 1);
@@ -1333,9 +1336,9 @@ xcf_load_hierarchy (XcfInfo     *info,
   /* make sure the values in the file correspond to the values
    *  calculated when the TileManager was created.
    */
-  if (width  != tile_manager_width (tiles)  ||
-      height != tile_manager_height (tiles) ||
-      bpp    != tile_manager_bpp (tiles))
+  if (width  != gegl_buffer_get_width (buffer)  ||
+      height != gegl_buffer_get_height (buffer) ||
+      bpp    != babl_format_get_bytes_per_pixel (format))
     return FALSE;
 
   /* load in the levels...we make sure that the number of levels
@@ -1363,7 +1366,7 @@ xcf_load_hierarchy (XcfInfo     *info,
     return FALSE;
 
   /* read in the level */
-  if (!xcf_load_level (info, tiles))
+  if (!xcf_load_level (info, buffer))
     return FALSE;
 
   /* restore the saved position so we'll be ready to
@@ -1377,24 +1380,24 @@ xcf_load_hierarchy (XcfInfo     *info,
 
 
 static gboolean
-xcf_load_level (XcfInfo     *info,
-                TileManager *tiles)
+xcf_load_level (XcfInfo    *info,
+                GeglBuffer *buffer)
 {
   guint32 saved_pos;
   guint32 offset, offset2;
-  guint ntiles;
-  gint  width;
-  gint  height;
-  gint  i;
-  gint  fail;
-  Tile *previous;
-  Tile *tile;
+  gint    n_tile_rows;
+  gint    n_tile_cols;
+  guint   ntiles;
+  gint    width;
+  gint    height;
+  gint    i;
+  gint    fail;
 
   info->cp += xcf_read_int32 (info->fp, (guint32 *) &width, 1);
   info->cp += xcf_read_int32 (info->fp, (guint32 *) &height, 1);
 
-  if (width  != tile_manager_width  (tiles) ||
-      height != tile_manager_height (tiles))
+  if (width  != gegl_buffer_get_width (buffer) ||
+      height != gegl_buffer_get_height (buffer))
     return FALSE;
 
   /* read in the first tile offset.
@@ -1405,13 +1408,14 @@ xcf_load_level (XcfInfo     *info,
   if (offset == 0)
     return TRUE;
 
-  /* Initialise the reference for the in-memory tile-compression
-   */
-  previous = NULL;
+  n_tile_rows = gimp_gegl_buffer_get_n_tile_rows (buffer, XCF_TILE_HEIGHT);
+  n_tile_cols = gimp_gegl_buffer_get_n_tile_cols (buffer, XCF_TILE_WIDTH);
 
-  ntiles = tiles->ntile_rows * tiles->ntile_cols;
+  ntiles = n_tile_rows * n_tile_cols;
   for (i = 0; i < ntiles; i++)
     {
+      GeglRectangle rect;
+
       fail = FALSE;
 
       if (offset == 0)
@@ -1434,7 +1438,7 @@ xcf_load_level (XcfInfo     *info,
       /* if the offset is 0 then we need to read in the maximum possible
          allowing for negative compression */
       if (offset2 == 0)
-        offset2 = offset + TILE_WIDTH * TILE_WIDTH * 4 * 1.5;
+        offset2 = offset + XCF_TILE_WIDTH * XCF_TILE_WIDTH * 4 * 1.5;
                                         /* 1.5 is probably more
                                            than we need to allow */
 
@@ -1443,17 +1447,19 @@ xcf_load_level (XcfInfo     *info,
         return FALSE;
 
       /* get the tile from the tile manager */
-      tile = tile_manager_get (tiles, i, TRUE, TRUE);
+      gimp_gegl_buffer_get_tile_rect (buffer,
+                                      XCF_TILE_WIDTH, XCF_TILE_HEIGHT,
+                                      i, &rect);
 
       /* read in the tile */
       switch (info->compression)
         {
         case COMPRESS_NONE:
-          if (!xcf_load_tile (info, tile))
+          if (!xcf_load_tile (info, buffer, &rect))
             fail = TRUE;
           break;
         case COMPRESS_RLE:
-          if (!xcf_load_tile_rle (info, tile, offset2 - offset))
+          if (!xcf_load_tile_rle (info, buffer, &rect, offset2 - offset))
             fail = TRUE;
           break;
         case COMPRESS_ZLIB:
@@ -1467,30 +1473,7 @@ xcf_load_level (XcfInfo     *info,
         }
 
       if (fail)
-        {
-          tile_release (tile, TRUE);
-          return FALSE;
-        }
-
-      /* To potentially save memory, we compare the
-       *  newly-fetched tile against the last one, and
-       *  if they're the same we copy-on-write mirror one against
-       *  the other.
-       */
-      if (previous != NULL)
-        {
-          tile_lock (previous);
-          if (tile_ewidth (tile) == tile_ewidth (previous) &&
-              tile_eheight (tile) == tile_eheight (previous) &&
-              tile_bpp (tile) == tile_bpp (previous) &&
-              memcmp (tile_data_pointer (tile, 0, 0),
-                      tile_data_pointer (previous, 0, 0),
-                      tile_size (tile)) == 0)
-            tile_manager_map (tiles, i, previous);
-          tile_release (previous, FALSE);
-        }
-      tile_release (tile, TRUE);
-      previous = tile_manager_get (tiles, i, FALSE, FALSE);
+        return FALSE;
 
       /* restore the saved position so we'll be ready to
        *  read the next offset.
@@ -1513,29 +1496,38 @@ xcf_load_level (XcfInfo     *info,
 }
 
 static gboolean
-xcf_load_tile (XcfInfo *info,
-               Tile    *tile)
+xcf_load_tile (XcfInfo       *info,
+               GeglBuffer    *buffer,
+               GeglRectangle *tile_rect)
 {
-  info->cp += xcf_read_int8 (info->fp, tile_data_pointer (tile, 0, 0),
-                             tile_size (tile));
+  const Babl *format    = gegl_buffer_get_format (buffer);
+  gint        bpp       = babl_format_get_bytes_per_pixel (format);
+  gint        tile_size = bpp * tile_rect->width * tile_rect->height;
+  guchar     *tile_data = g_alloca (tile_size);
+
+  info->cp += xcf_read_int8 (info->fp, tile_data, tile_size);
+
+  gegl_buffer_set (buffer, tile_rect, 0, NULL, tile_data,
+                   GEGL_AUTO_ROWSTRIDE);
 
   return TRUE;
 }
 
 static gboolean
-xcf_load_tile_rle (XcfInfo *info,
-                   Tile    *tile,
-                   int     data_length)
+xcf_load_tile_rle (XcfInfo       *info,
+                   GeglBuffer    *buffer,
+                   GeglRectangle *tile_rect,
+                   gint           data_length)
 {
-  guchar *data;
-  guchar val;
-  gint size;
-  gint count;
-  gint length;
-  gint bpp;
-  gint i, j;
-  gint nmemb_read_successfully;
-  guchar *xcfdata, *xcfodata, *xcfdatalimit;
+  const Babl *format    = gegl_buffer_get_format (buffer);
+  gint        bpp       = babl_format_get_bytes_per_pixel (format);
+  gint        tile_size = bpp * tile_rect->width * tile_rect->height;
+  guchar     *tile_data = g_alloca (tile_size);
+  gint        i;
+  gint        nmemb_read_successfully;
+  guchar     *xcfdata;
+  guchar     *xcfodata;
+  guchar     *xcfdatalimit;
 
   /* Workaround for bug #357809: avoid crashing on g_malloc() and skip
    * this tile (return TRUE without storing data) as if it did not
@@ -1546,12 +1538,11 @@ xcf_load_tile_rle (XcfInfo *info,
   if (data_length <= 0)
     return TRUE;
 
-  bpp = tile_bpp (tile);
-
-  xcfdata = xcfodata = g_malloc (data_length);
+  xcfdata = xcfodata = g_alloca (data_length);
 
   /* we have to use fread instead of xcf_read_* because we may be
-     reading past the end of the file here */
+   * reading past the end of the file here
+   */
   nmemb_read_successfully = fread ((gchar *) xcfdata, sizeof (gchar),
                                    data_length, info->fp);
   info->cp += nmemb_read_successfully;
@@ -1560,9 +1551,12 @@ xcf_load_tile_rle (XcfInfo *info,
 
   for (i = 0; i < bpp; i++)
     {
-      data = (guchar *) tile_data_pointer (tile, 0, 0) + i;
-      size = tile_ewidth (tile) * tile_eheight (tile);
-      count = 0;
+      guchar *data  = tile_data + i;
+      gint    size  = tile_rect->width * tile_rect->height;
+      gint    count = 0;
+      guchar  val;
+      gint    length;
+      gint    j;
 
       while (size > 0)
         {
@@ -1644,12 +1638,13 @@ xcf_load_tile_rle (XcfInfo *info,
             }
         }
     }
-  g_free (xcfodata);
+
+  gegl_buffer_set (buffer, tile_rect, 0, NULL, tile_data,
+                   GEGL_AUTO_ROWSTRIDE);
+
   return TRUE;
 
  bogus_rle:
-  if (xcfodata)
-    g_free (xcfodata);
   return FALSE;
 }
 
diff --git a/app/xcf/xcf-private.h b/app/xcf/xcf-private.h
index 33076d4..05f1492 100644
--- a/app/xcf/xcf-private.h
+++ b/app/xcf/xcf-private.h
@@ -19,6 +19,9 @@
 #define __XCF_PRIVATE_H__
 
 
+#define XCF_TILE_WIDTH  64
+#define XCF_TILE_HEIGHT 64
+
 typedef enum
 {
   PROP_END                =  0,



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