diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c index 5c1410dcba..5856e08e47 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 a2af8ad28a..8762dbcdc6 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 ad16144cdc..b2a524c3a6 100644 --- a/app/xcf/xcf-read.c +++ b/app/xcf/xcf-read.c @@ -50,6 +50,29 @@ xcf_read_int32 (GInputStream *input, return total; } +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, diff --git a/app/xcf/xcf-read.h b/app/xcf/xcf-read.h index 5f107f7068..0e7183218b 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 46b408d90a..a89c3493a5 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 140bc3ec52..257e0a9ee7 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 ede3f2f14d..29845e656b 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 8360027e27..5c54331b59 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 ef46646428..1bb68d5284 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 ec55b797cb..efcee2447e 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);