[gimp] Bug 731390 - XCF files have a max size of 4G
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Bug 731390 - XCF files have a max size of 4G
- Date: Thu, 23 Mar 2017 10:49:14 +0000 (UTC)
commit a0a5f714bbf0a2f25cff50a83fcb49cec824a40f
Author: Michael Natterer <mitch gimp org>
Date: Thu Mar 23 11:44:41 2017 +0100
Bug 731390 - XCF files have a max size of 4G
Step one, without changing anything in the saved XCFs yet:
Abstract reading and writing of file offsets away into their own
xcf_read_offset() and xcf_write_offset() functions, which take
"goffset" instead of "guint32". Also change xcf_seek_pos() to take a
goffset argument.
Change all file offset variables in xcf-load.c, xcf-write.c and struct
XcfInfo to goffset, and add new member "bytes_per_offset" to XcfInfo,
which is currently always 4.
app/xcf/xcf-load.c | 67 +++++++++++++------------
app/xcf/xcf-private.h | 5 +-
app/xcf/xcf-read.c | 23 +++++++++
app/xcf/xcf-read.h | 3 +
app/xcf/xcf-save.c | 127 ++++++++++++++++++++++++++----------------------
app/xcf/xcf-seek.c | 2 +-
app/xcf/xcf-seek.h | 6 +-
app/xcf/xcf-write.c | 35 ++++++++++++-
app/xcf/xcf-write.h | 42 +++++++++-------
app/xcf/xcf.c | 4 ++
10 files changed, 196 insertions(+), 118 deletions(-)
---
diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c
index 5c1410d..5856e08 100644
--- a/app/xcf/xcf-load.c
+++ b/app/xcf/xcf-load.c
@@ -150,8 +150,8 @@ xcf_load_image (Gimp *gimp,
GimpImage *image = NULL;
const GimpParasite *parasite;
gboolean has_metadata = FALSE;
- guint32 saved_pos;
- guint32 offset;
+ goffset saved_pos;
+ goffset offset;
gint width;
gint height;
gint image_type;
@@ -393,7 +393,7 @@ xcf_load_image (Gimp *gimp,
GList *item_path = NULL;
/* read in the offset of the next layer */
- info->cp += xcf_read_int32 (info->input, &offset, 1);
+ info->cp += xcf_read_offset (info->input, &offset, 1);
/* if the offset is 0 then we are at the end
* of the layer list.
@@ -477,7 +477,7 @@ xcf_load_image (Gimp *gimp,
GimpChannel *channel;
/* read in the offset of the next channel */
- info->cp += xcf_read_int32 (info->input, &offset, 1);
+ info->cp += xcf_read_offset (info->input, &offset, 1);
/* if the offset is 0 then we are at the end
* of the channel list.
@@ -801,7 +801,7 @@ xcf_load_image_props (XcfInfo *info,
case PROP_PARASITES:
{
- glong base = info->cp;
+ goffset base = info->cp;
while (info->cp - base < prop_size)
{
@@ -912,14 +912,14 @@ xcf_load_image_props (XcfInfo *info,
case PROP_VECTORS:
{
- guint32 base = info->cp;
+ goffset base = info->cp;
if (xcf_load_vectors (info, image))
{
if (base + prop_size != info->cp)
{
g_printerr ("Mismatch in PROP_VECTORS size: "
- "skipping %d bytes.\n",
+ "skipping " G_GOFFSET_FORMAT " bytes.\n",
base + prop_size - info->cp);
xcf_seek_pos (info, base + prop_size, NULL);
}
@@ -978,9 +978,8 @@ xcf_load_layer_props (XcfInfo *info,
case PROP_FLOATING_SELECTION:
info->floating_sel = *layer;
- info->cp +=
- xcf_read_int32 (info->input,
- (guint32 *) &info->floating_sel_offset, 1);
+ info->cp += xcf_read_offset (info->input,
+ &info->floating_sel_offset, 1);
break;
case PROP_OPACITY:
@@ -1147,7 +1146,7 @@ xcf_load_layer_props (XcfInfo *info,
case PROP_PARASITES:
{
- glong base = info->cp;
+ goffset base = info->cp;
while (info->cp - base < prop_size)
{
@@ -1220,8 +1219,8 @@ xcf_load_layer_props (XcfInfo *info,
case PROP_ITEM_PATH:
{
- glong base = info->cp;
- GList *path = NULL;
+ goffset base = info->cp;
+ GList *path = NULL;
while (info->cp - base < prop_size)
{
@@ -1408,7 +1407,7 @@ xcf_load_channel_props (XcfInfo *info,
case PROP_PARASITES:
{
- glong base = info->cp;
+ goffset base = info->cp;
while ((info->cp - base) < prop_size)
{
@@ -1481,8 +1480,8 @@ xcf_load_layer (XcfInfo *info,
{
GimpLayer *layer;
GimpLayerMask *layer_mask;
- guint32 hierarchy_offset;
- guint32 layer_mask_offset;
+ goffset hierarchy_offset;
+ goffset layer_mask_offset;
gboolean apply_mask = TRUE;
gboolean edit_mask = FALSE;
gboolean show_mask = FALSE;
@@ -1592,8 +1591,8 @@ xcf_load_layer (XcfInfo *info,
}
/* read the hierarchy and layer mask offsets */
- info->cp += xcf_read_int32 (info->input, &hierarchy_offset, 1);
- info->cp += xcf_read_int32 (info->input, &layer_mask_offset, 1);
+ info->cp += xcf_read_offset (info->input, &hierarchy_offset, 1);
+ info->cp += xcf_read_offset (info->input, &layer_mask_offset, 1);
/* read in the hierarchy (ignore it for group layers, both as an
* optimization and because the hierarchy's extents don't match
@@ -1664,7 +1663,7 @@ xcf_load_channel (XcfInfo *info,
GimpImage *image)
{
GimpChannel *channel;
- guint32 hierarchy_offset;
+ goffset hierarchy_offset;
gint width;
gint height;
gboolean is_fs_drawable;
@@ -1697,7 +1696,7 @@ xcf_load_channel (XcfInfo *info,
xcf_progress_update (info);
/* read the hierarchy and layer mask offsets */
- info->cp += xcf_read_int32 (info->input, &hierarchy_offset, 1);
+ info->cp += xcf_read_offset (info->input, &hierarchy_offset, 1);
/* read in the hierarchy */
if (!xcf_seek_pos (info, hierarchy_offset, NULL))
@@ -1725,7 +1724,7 @@ xcf_load_layer_mask (XcfInfo *info,
{
GimpLayerMask *layer_mask;
GimpChannel *channel;
- guint32 hierarchy_offset;
+ goffset hierarchy_offset;
gint width;
gint height;
gboolean is_fs_drawable;
@@ -1759,7 +1758,7 @@ xcf_load_layer_mask (XcfInfo *info,
xcf_progress_update (info);
/* read the hierarchy and layer mask offsets */
- info->cp += xcf_read_int32 (info->input, &hierarchy_offset, 1);
+ info->cp += xcf_read_offset (info->input, &hierarchy_offset, 1);
/* read in the hierarchy */
if (! xcf_seek_pos (info, hierarchy_offset, NULL))
@@ -1787,7 +1786,7 @@ xcf_load_buffer (XcfInfo *info,
GeglBuffer *buffer)
{
const Babl *format;
- guint32 offset;
+ goffset offset;
gint width;
gint height;
gint bpp;
@@ -1806,7 +1805,7 @@ xcf_load_buffer (XcfInfo *info,
bpp != babl_format_get_bytes_per_pixel (format))
return FALSE;
- info->cp += xcf_read_int32 (info->input, &offset, 1); /* top level */
+ info->cp += xcf_read_offset (info->input, &offset, 1); /* top level */
/* seek to the level offset */
if (!xcf_seek_pos (info, offset, NULL))
@@ -1829,8 +1828,9 @@ xcf_load_level (XcfInfo *info,
{
const Babl *format;
gint bpp;
- guint32 saved_pos;
- guint32 offset, offset2;
+ goffset saved_pos;
+ goffset offset;
+ goffset offset2;
gint n_tile_rows;
gint n_tile_cols;
guint ntiles;
@@ -1853,7 +1853,7 @@ xcf_load_level (XcfInfo *info,
* if it is '0', then this tile level is empty
* and we can simply return.
*/
- info->cp += xcf_read_int32 (info->input, &offset, 1);
+ info->cp += xcf_read_offset (info->input, &offset, 1);
if (offset == 0)
return TRUE;
@@ -1881,11 +1881,13 @@ xcf_load_level (XcfInfo *info,
saved_pos = info->cp;
/* read in the offset of the next tile so we can calculate the amount
- of data needed for this tile*/
- info->cp += xcf_read_int32 (info->input, &offset2, 1);
+ * of data needed for this tile
+ */
+ info->cp += xcf_read_offset (info->input, &offset2, 1);
/* if the offset is 0 then we need to read in the maximum possible
- allowing for negative compression */
+ * allowing for negative compression
+ */
if (offset2 == 0)
offset2 = offset + XCF_TILE_WIDTH * XCF_TILE_WIDTH * bpp * 1.5;
/* 1.5 is probably more
@@ -1943,13 +1945,14 @@ xcf_load_level (XcfInfo *info,
return FALSE;
/* read in the offset of the next tile */
- info->cp += xcf_read_int32 (info->input, &offset, 1);
+ info->cp += xcf_read_offset (info->input, &offset, 1);
}
if (offset != 0)
{
gimp_message (info->gimp, G_OBJECT (info->progress), GIMP_MESSAGE_ERROR,
- "encountered garbage after reading level: %d", offset);
+ "encountered garbage after reading level: " G_GOFFSET_FORMAT,
+ offset);
return FALSE;
}
diff --git a/app/xcf/xcf-private.h b/app/xcf/xcf-private.h
index a2af8ad..8762dbc 100644
--- a/app/xcf/xcf-private.h
+++ b/app/xcf/xcf-private.h
@@ -98,14 +98,15 @@ struct _XcfInfo
GInputStream *input;
GOutputStream *output;
GSeekable *seekable;
- guint cp;
+ goffset cp;
+ gint bytes_per_offset;
GFile *file;
GimpTattoo tattoo_state;
GimpLayer *active_layer;
GimpChannel *active_channel;
GimpDrawable *floating_sel_drawable;
GimpLayer *floating_sel;
- guint floating_sel_offset;
+ goffset floating_sel_offset;
XcfCompressionType compression;
gint file_version;
};
diff --git a/app/xcf/xcf-read.c b/app/xcf/xcf-read.c
index ad16144..b2a524c 100644
--- a/app/xcf/xcf-read.c
+++ b/app/xcf/xcf-read.c
@@ -51,6 +51,29 @@ xcf_read_int32 (GInputStream *input,
}
guint
+xcf_read_offset (GInputStream *input,
+ goffset *data,
+ gint count)
+{
+ guint total = 0;
+ gint32 *int_offsets = g_alloca (count * sizeof (gint32));
+
+ if (count > 0)
+ {
+ total += xcf_read_int8 (input, (guint8 *) int_offsets, count * 4);
+
+ while (count--)
+ {
+ *data = g_ntohl (*int_offsets);
+ int_offsets++;
+ data++;
+ }
+ }
+
+ return total;
+}
+
+guint
xcf_read_float (GInputStream *input,
gfloat *data,
gint count)
diff --git a/app/xcf/xcf-read.h b/app/xcf/xcf-read.h
index 5f107f7..0e71832 100644
--- a/app/xcf/xcf-read.h
+++ b/app/xcf/xcf-read.h
@@ -22,6 +22,9 @@
guint xcf_read_int32 (GInputStream *input,
guint32 *data,
gint count);
+guint xcf_read_offset (GInputStream *input,
+ goffset *data,
+ gint count);
guint xcf_read_float (GInputStream *input,
gfloat *data,
gint count);
diff --git a/app/xcf/xcf-save.c b/app/xcf/xcf-save.c
index 46b408d..a89c349 100644
--- a/app/xcf/xcf-save.c
+++ b/app/xcf/xcf-save.c
@@ -139,13 +139,22 @@ static gboolean xcf_save_vectors (XcfInfo *info,
} \
} G_STMT_END
-#define xcf_write_zero_int32_check_error(info, count) G_STMT_START { \
- info->cp += xcf_write_zero_int32 (info->output, count, &tmp_error); \
- if (tmp_error) \
- { \
- g_propagate_error (error, tmp_error); \
- return FALSE; \
- } \
+#define xcf_write_offset_check_error(info, data, count) G_STMT_START { \
+ info->cp += xcf_write_offset (info->output, data, count, &tmp_error); \
+ if (tmp_error) \
+ { \
+ g_propagate_error (error, tmp_error); \
+ return FALSE; \
+ } \
+ } G_STMT_END
+
+#define xcf_write_zero_offset_check_error(info, count) G_STMT_START { \
+ info->cp += xcf_write_zero_offset (info->output, count, &tmp_error); \
+ if (tmp_error) \
+ { \
+ g_propagate_error (error, tmp_error); \
+ return FALSE; \
+ } \
} G_STMT_END
#define xcf_write_int8_check_error(info, data, count) G_STMT_START { \
@@ -202,8 +211,8 @@ xcf_save_image (XcfInfo *info,
GList *all_layers;
GList *all_channels;
GList *list;
- guint32 saved_pos;
- guint32 offset;
+ goffset saved_pos;
+ goffset offset;
guint32 value;
guint n_layers;
guint n_channels;
@@ -255,9 +264,7 @@ xcf_save_image (XcfInfo *info,
max_progress = 1 + n_layers + n_channels;
- /* write the property information for the image.
- */
-
+ /* write the property information for the image */
xcf_check_error (xcf_save_image_props (info, image, error));
xcf_progress_update (info);
@@ -266,7 +273,7 @@ xcf_save_image (XcfInfo *info,
saved_pos = info->cp;
/* write an empty offset table */
- xcf_write_zero_int32_check_error (info, n_layers + n_channels + 2);
+ xcf_write_zero_offset_check_error (info, n_layers + n_channels + 2);
/* 'offset' is where we will write the next layer or channel */
offset = info->cp;
@@ -279,7 +286,7 @@ xcf_save_image (XcfInfo *info,
* offset of the layer
*/
xcf_check_error (xcf_seek_pos (info, saved_pos, error));
- xcf_write_int32_check_error (info, &offset, 1);
+ xcf_write_offset_check_error (info, &offset, 1);
/* remember the next slot in the offset table */
saved_pos = info->cp;
@@ -297,7 +304,7 @@ xcf_save_image (XcfInfo *info,
/* skip a '0' in the offset table to indicate the end of the layer
* offsets
*/
- saved_pos += 4;
+ saved_pos += info->bytes_per_offset;
for (list = all_channels; list; list = g_list_next (list))
{
@@ -307,7 +314,7 @@ xcf_save_image (XcfInfo *info,
* offset of the channel
*/
xcf_check_error (xcf_seek_pos (info, saved_pos, error));
- xcf_write_int32_check_error (info, &offset, 1);
+ xcf_write_offset_check_error (info, &offset, 1);
/* remember the next slot in the offset table */
saved_pos = info->cp;
@@ -454,6 +461,7 @@ xcf_save_image_props (XcfInfo *info,
gimp_parasite_name (compat_parasite));
gimp_parasite_free (compat_parasite);
}
+
xcf_check_error (xcf_save_prop (info, image, PROP_END, error));
return TRUE;
@@ -683,15 +691,15 @@ xcf_save_prop (XcfInfo *info,
case PROP_FLOATING_SELECTION:
{
- guint32 dummy;
+ goffset dummy;
dummy = 0;
- size = 4;
+ size = info->bytes_per_offset;
xcf_write_prop_type_check_error (info, prop_type);
xcf_write_int32_check_error (info, &size, 1);
info->floating_sel_offset = info->cp;
- xcf_write_int32_check_error (info, &dummy, 1);
+ xcf_write_offset_check_error (info, &dummy, 1);
}
break;
@@ -1067,16 +1075,19 @@ xcf_save_prop (XcfInfo *info,
if (gimp_parasite_list_persistent_length (list) > 0)
{
- guint32 base, length = 0;
- long pos;
+ goffset base;
+ goffset pos;
+ guint32 length = 0;
xcf_write_prop_type_check_error (info, prop_type);
- /* because we don't know how much room the parasite list will take
- * we save the file position and write the length later
+ /* because we don't know how much room the parasite list
+ * will take we save the file position and write the
+ * length later
*/
pos = info->cp;
xcf_write_int32_check_error (info, &length, 1);
+
base = info->cp;
xcf_check_error (xcf_save_parasite_list (info, list, error));
@@ -1108,13 +1119,14 @@ xcf_save_prop (XcfInfo *info,
case PROP_PATHS:
{
- guint32 base, length = 0;
- glong pos;
+ goffset base;
+ goffset pos;
+ guint32 length = 0;
xcf_write_prop_type_check_error (info, prop_type);
- /* because we don't know how much room the paths list will take
- * we save the file position and write the length later
+ /* because we don't know how much room the paths list will
+ * take we save the file position and write the length later
*/
pos = info->cp;
xcf_write_int32_check_error (info, &length, 1);
@@ -1169,13 +1181,14 @@ xcf_save_prop (XcfInfo *info,
case PROP_VECTORS:
{
- guint32 base, length = 0;
- glong pos;
+ goffset base;
+ goffset pos;
+ guint32 length = 0;
xcf_write_prop_type_check_error (info, prop_type);
- /* because we don't know how much room the paths list will take
- * we save the file position and write the length later
+ /* because we don't know how much room the paths list will
+ * take we save the file position and write the length later
*/
pos = info->cp;
xcf_write_int32_check_error (info, &length, 1);
@@ -1253,8 +1266,8 @@ xcf_save_layer (XcfInfo *info,
GimpLayer *layer,
GError **error)
{
- guint32 saved_pos;
- guint32 offset;
+ goffset saved_pos;
+ goffset offset;
guint32 value;
const gchar *string;
GError *tmp_error = NULL;
@@ -1266,7 +1279,7 @@ xcf_save_layer (XcfInfo *info,
{
saved_pos = info->cp;
xcf_check_error (xcf_seek_pos (info, info->floating_sel_offset, error));
- xcf_write_int32_check_error (info, &saved_pos, 1);
+ xcf_write_offset_check_error (info, &saved_pos, 1);
xcf_check_error (xcf_seek_pos (info, saved_pos, error));
}
@@ -1288,13 +1301,13 @@ xcf_save_layer (XcfInfo *info,
xcf_save_layer_props (info, image, layer, error);
/* write out the layer tile hierarchy */
- offset = info->cp + 8;
- xcf_write_int32_check_error (info, &offset, 1);
+ offset = info->cp + 2 * info->bytes_per_offset;
+ xcf_write_offset_check_error (info, &offset, 1);
saved_pos = info->cp;
/* write a zero layer mask offset */
- xcf_write_zero_int32_check_error (info, 1);
+ xcf_write_zero_offset_check_error (info, 1);
xcf_check_error (xcf_save_buffer (info,
gimp_drawable_get_buffer (GIMP_DRAWABLE (layer)),
@@ -1308,7 +1321,7 @@ xcf_save_layer (XcfInfo *info,
GimpLayerMask *mask = gimp_layer_get_mask (layer);
xcf_check_error (xcf_seek_pos (info, saved_pos, error));
- xcf_write_int32_check_error (info, &offset, 1);
+ xcf_write_offset_check_error (info, &offset, 1);
xcf_check_error (xcf_seek_pos (info, offset, error));
xcf_check_error (xcf_save_channel (info, image, GIMP_CHANNEL (mask),
@@ -1324,8 +1337,8 @@ xcf_save_channel (XcfInfo *info,
GimpChannel *channel,
GError **error)
{
- guint32 saved_pos;
- guint32 offset;
+ goffset saved_pos;
+ goffset offset;
guint32 value;
const gchar *string;
GError *tmp_error = NULL;
@@ -1337,7 +1350,7 @@ xcf_save_channel (XcfInfo *info,
{
saved_pos = info->cp;
xcf_check_error (xcf_seek_pos (info, info->floating_sel_offset, error));
- xcf_write_int32_check_error (info, &saved_pos, 1);
+ xcf_write_offset_check_error (info, &saved_pos, 1);
xcf_check_error (xcf_seek_pos (info, saved_pos, error));
}
@@ -1356,8 +1369,8 @@ xcf_save_channel (XcfInfo *info,
xcf_save_channel_props (info, image, channel, error);
/* write out the channel tile hierarchy */
- offset = info->cp + 4;
- xcf_write_int32_check_error (info, &offset, 1);
+ offset = info->cp + info->bytes_per_offset;
+ xcf_write_offset_check_error (info, &offset, 1);
xcf_check_error (xcf_save_buffer (info,
gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
@@ -1370,7 +1383,7 @@ static gint
xcf_calc_levels (gint size,
gint tile_size)
{
- int levels;
+ gint levels;
levels = 1;
while (size > tile_size)
@@ -1389,8 +1402,8 @@ xcf_save_buffer (XcfInfo *info,
GError **error)
{
const Babl *format;
- guint32 saved_pos;
- guint32 offset;
+ goffset saved_pos;
+ goffset offset;
guint32 width;
guint32 height;
guint32 bpp;
@@ -1409,8 +1422,6 @@ xcf_save_buffer (XcfInfo *info,
xcf_write_int32_check_error (info, (guint32 *) &height, 1);
xcf_write_int32_check_error (info, (guint32 *) &bpp, 1);
- saved_pos = info->cp;
-
tmp1 = xcf_calc_levels (width, XCF_TILE_WIDTH);
tmp2 = xcf_calc_levels (height, XCF_TILE_HEIGHT);
nlevels = MAX (tmp1, tmp2);
@@ -1419,7 +1430,7 @@ xcf_save_buffer (XcfInfo *info,
saved_pos = info->cp;
/* write an empty offset table */
- xcf_write_zero_int32_check_error (info, nlevels + 1);
+ xcf_write_zero_offset_check_error (info, nlevels + 1);
/* 'offset' is where we will write the next level */
offset = info->cp;
@@ -1430,7 +1441,7 @@ xcf_save_buffer (XcfInfo *info,
* offset of the level
*/
xcf_check_error (xcf_seek_pos (info, saved_pos, error));
- xcf_write_int32_check_error (info, &offset, 1);
+ xcf_write_offset_check_error (info, &offset, 1);
/* remember the next slot in the offset table */
saved_pos = info->cp;
@@ -1471,10 +1482,10 @@ xcf_save_level (XcfInfo *info,
GError **error)
{
const Babl *format;
- guint32 *offset_table;
- guint32 *next_offset;
- guint32 saved_pos;
- guint32 offset;
+ goffset *offset_table;
+ goffset *next_offset;
+ goffset saved_pos;
+ goffset offset;
guint32 width;
guint32 height;
gint bpp;
@@ -1511,15 +1522,15 @@ xcf_save_level (XcfInfo *info,
* tile, see bug #686862. allocate ntiles + 1 slots because a zero
* offset indicates the offset table's end.
*/
- offset_table = g_alloca ((ntiles + 1) * sizeof (gint32));
- memset (offset_table, 0, (ntiles + 1) * sizeof (gint32));
+ offset_table = g_alloca ((ntiles + 1) * sizeof (goffset));
+ memset (offset_table, 0, (ntiles + 1) * sizeof (goffset));
next_offset = offset_table;
/* 'saved_pos' is the offset of the tile offset table */
saved_pos = info->cp;
/* write an empty offset table */
- xcf_write_zero_int32_check_error (info, ntiles + 1);
+ xcf_write_zero_offset_check_error (info, ntiles + 1);
/* 'offset' is where we will write the next tile */
offset = info->cp;
@@ -1561,7 +1572,7 @@ xcf_save_level (XcfInfo *info,
/* seek back to the offset table and write it */
xcf_check_error (xcf_seek_pos (info, saved_pos, error));
- xcf_write_int32_check_error (info, offset_table, ntiles + 1);
+ xcf_write_offset_check_error (info, offset_table, ntiles + 1);
/* seek to the end of the file */
xcf_check_error (xcf_seek_pos (info, offset, error));
diff --git a/app/xcf/xcf-seek.c b/app/xcf/xcf-seek.c
index 140bc3e..257e0a9 100644
--- a/app/xcf/xcf-seek.c
+++ b/app/xcf/xcf-seek.c
@@ -29,7 +29,7 @@
gboolean
xcf_seek_pos (XcfInfo *info,
- guint pos,
+ goffset pos,
GError **error)
{
if (info->cp != pos)
diff --git a/app/xcf/xcf-seek.h b/app/xcf/xcf-seek.h
index ede3f2f..29845e6 100644
--- a/app/xcf/xcf-seek.h
+++ b/app/xcf/xcf-seek.h
@@ -19,9 +19,9 @@
#define __XCF_SEEK_H__
-gboolean xcf_seek_pos (XcfInfo *info,
- guint pos,
- GError **error);
+gboolean xcf_seek_pos (XcfInfo *info,
+ goffset pos,
+ GError **error);
#endif /* __XCF_SEEK_H__ */
diff --git a/app/xcf/xcf-write.c b/app/xcf/xcf-write.c
index 8360027..5c54331 100644
--- a/app/xcf/xcf-write.c
+++ b/app/xcf/xcf-write.c
@@ -56,9 +56,38 @@ xcf_write_int32 (GOutputStream *output,
}
guint
-xcf_write_zero_int32 (GOutputStream *output,
- gint count,
- GError **error)
+xcf_write_offset (GOutputStream *output,
+ const goffset *data,
+ gint count,
+ GError **error)
+{
+ GError *tmp_error = NULL;
+ gint i;
+
+ if (count > 0)
+ {
+ for (i = 0; i < count; i++)
+ {
+ guint32 tmp = g_htonl (data[i]);
+
+ xcf_write_int8 (output, (const guint8 *) &tmp, 4, &tmp_error);
+
+ if (tmp_error)
+ {
+ g_propagate_error (error, tmp_error);
+
+ return i * 4;
+ }
+ }
+ }
+
+ return count * 4;
+}
+
+guint
+xcf_write_zero_offset (GOutputStream *output,
+ gint count,
+ GError **error)
{
if (count > 0)
{
diff --git a/app/xcf/xcf-write.h b/app/xcf/xcf-write.h
index ef46646..1bb68d5 100644
--- a/app/xcf/xcf-write.h
+++ b/app/xcf/xcf-write.h
@@ -19,25 +19,29 @@
#define __XCF_WRITE_H__
-guint xcf_write_int32 (GOutputStream *output,
- const guint32 *data,
- gint count,
- GError **error);
-guint xcf_write_zero_int32 (GOutputStream *output,
- gint count,
- GError **error);
-guint xcf_write_float (GOutputStream *output,
- const gfloat *data,
- gint count,
- GError **error);
-guint xcf_write_int8 (GOutputStream *output,
- const guint8 *data,
- gint count,
- GError **error);
-guint xcf_write_string (GOutputStream *output,
- gchar **data,
- gint count,
- GError **error);
+guint xcf_write_int32 (GOutputStream *output,
+ const guint32 *data,
+ gint count,
+ GError **error);
+guint xcf_write_offset (GOutputStream *output,
+ const goffset *data,
+ gint count,
+ GError **error);
+guint xcf_write_zero_offset (GOutputStream *output,
+ gint count,
+ GError **error);
+guint xcf_write_float (GOutputStream *output,
+ const gfloat *data,
+ gint count,
+ GError **error);
+guint xcf_write_int8 (GOutputStream *output,
+ const guint8 *data,
+ gint count,
+ GError **error);
+guint xcf_write_string (GOutputStream *output,
+ gchar **data,
+ gint count,
+ GError **error);
#endif /* __XCF_WRITE_H__ */
diff --git a/app/xcf/xcf.c b/app/xcf/xcf.c
index ec55b79..efcee24 100644
--- a/app/xcf/xcf.c
+++ b/app/xcf/xcf.c
@@ -280,6 +280,8 @@ xcf_load_stream (Gimp *gimp,
success = TRUE;
+ info.bytes_per_offset = 4;
+
info.cp += xcf_read_int8 (info.input, (guint8 *) id, 14);
if (! g_str_has_prefix (id, "gimp xcf "))
@@ -367,6 +369,8 @@ xcf_save_stream (Gimp *gimp,
COMPRESS_ZLIB,
NULL, NULL);
+ info.bytes_per_offset = 4;
+
if (progress)
gimp_progress_start (progress, FALSE, _("Saving '%s'"), filename);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]