[gimp/goat-invasion: 411/526] app: port XCF loading to writing to the drawable's GeglBuffer
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/goat-invasion: 411/526] app: port XCF loading to writing to the drawable's GeglBuffer
- Date: Sun, 22 Apr 2012 13:33:48 +0000 (UTC)
commit 873325e6294fcda07e356f9d605a4090ba5da217
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]