[gimp/osx-build: 44/44] Bug 730211 - Extra zeroes appear in XCF files (draft)
- From: Sven Claussner <sclaussner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/osx-build: 44/44] Bug 730211 - Extra zeroes appear in XCF files (draft)
- Date: Sun, 22 Jun 2014 19:10:29 +0000 (UTC)
commit faa8ad2ac74b081e4d5714ee1c8ac8cf2245c1c0
Author: Massimo Valentini <mvalentini src gnome org>
Date: Sat Jun 14 17:57:11 2014 +0200
Bug 730211 - Extra zeroes appear in XCF files (draft)
Patch to solve bug 730211. GIMP can be built with it and a simple
test to save and load "layers recovered.xcf" passes.
Needs further review and extensive testing as proposed by Massimo
in comment 14 of the bug report.
app/xcf/xcf-save.c | 184 ++++++++++++++--------------------------------------
1 files changed, 50 insertions(+), 134 deletions(-)
---
diff --git a/app/xcf/xcf-save.c b/app/xcf/xcf-save.c
index 50809df..d4c943b 100644
--- a/app/xcf/xcf-save.c
+++ b/app/xcf/xcf-save.c
@@ -174,6 +174,7 @@ static gboolean xcf_save_vectors (XcfInfo *info,
(gdouble) progress / (gdouble) max_progress); \
} G_STMT_END
+static const guint32 zero;
void
xcf_save_choose_format (XcfInfo *info,
@@ -278,85 +279,45 @@ xcf_save_image (XcfInfo *info,
xcf_progress_update (info);
- /* save the current file position as it is the start of where
- * we place the layer offset information.
- */
- saved_pos = info->cp;
-
- /* seek to after the offset lists */
- xcf_check_error (xcf_seek_pos (info,
- info->cp + (n_layers + n_channels + 2) * 4,
- error));
+ offset = info->cp + (n_layers + n_channels + 2) * 4;
for (list = all_layers; list; list = g_list_next (list))
{
GimpLayer *layer = list->data;
- /* save the start offset of where we are writing
- * out the next layer.
- */
- offset = info->cp;
+ xcf_write_int32_check_error (info, &offset, 1);
- /* write out the layer. */
- xcf_check_error (xcf_save_layer (info, image, layer, error));
+ saved_pos = info->cp;
+ xcf_check_error (xcf_seek_pos (info, offset, error));
- xcf_progress_update (info);
+ xcf_check_error (xcf_save_layer (info, image, layer, error));
- /* seek back to where we are to write out the next
- * layer offset and write it out.
- */
+ offset = info->cp;
xcf_check_error (xcf_seek_pos (info, saved_pos, error));
- xcf_write_int32_check_error (info, &offset, 1);
- /* increment the location we are to write out the
- * next offset.
- */
- saved_pos = info->cp;
-
- /* seek to the end of the file which is where
- * we will write out the next layer.
- */
- xcf_check_error (xcf_seek_end (info, error));
+ xcf_progress_update (info);
}
/* write out a '0' offset position to indicate the end
* of the layer offsets.
*/
- offset = 0;
- xcf_check_error (xcf_seek_pos (info, saved_pos, error));
- xcf_write_int32_check_error (info, &offset, 1);
- saved_pos = info->cp;
- xcf_check_error (xcf_seek_end (info, error));
+ xcf_write_int32_check_error (info, &zero, 1);
for (list = all_channels; list; list = g_list_next (list))
{
GimpChannel *channel = list->data;
- /* save the start offset of where we are writing
- * out the next channel.
- */
- offset = info->cp;
+ xcf_write_int32_check_error (info, &offset, 1);
- /* write out the layer. */
- xcf_check_error (xcf_save_channel (info, image, channel, error));
+ saved_pos = info->cp;
+ xcf_check_error (xcf_seek_pos (info, offset, error));
- xcf_progress_update (info);
+ xcf_check_error (xcf_save_channel (info, image, channel, error));
- /* seek back to where we are to write out the next
- * channel offset and write it out.
- */
+ offset = info->cp;
xcf_check_error (xcf_seek_pos (info, saved_pos, error));
- xcf_write_int32_check_error (info, &offset, 1);
- /* increment the location we are to write out the
- * next offset.
- */
- saved_pos = info->cp;
-
- /* seek to the end of the file which is where
- * we will write out the next channel.
- */
- xcf_check_error (xcf_seek_end (info, error));
+ xcf_progress_update (info);
}
g_list_free (all_layers);
@@ -365,10 +326,7 @@ xcf_save_image (XcfInfo *info,
/* write out a '0' offset position to indicate the end
* of the channel offsets.
*/
- offset = 0;
- xcf_check_error (xcf_seek_pos (info, saved_pos, error));
- xcf_write_int32_check_error (info, &offset, 1);
- saved_pos = info->cp;
+ xcf_write_int32_check_error (info, &zero, 1);
return !ferror (info->fp);
}
@@ -976,7 +934,7 @@ xcf_save_prop (XcfInfo *info,
return FALSE;
}
- xcf_check_error (xcf_seek_end (info, error));
+ xcf_check_error (xcf_seek_pos (info, base + length, error));
}
}
break;
@@ -1023,7 +981,7 @@ xcf_save_prop (XcfInfo *info,
return FALSE;
}
- xcf_check_error (xcf_seek_end (info, error));
+ xcf_check_error (xcf_seek_pos (info, base + length, error));
}
break;
@@ -1089,7 +1047,7 @@ xcf_save_prop (XcfInfo *info,
return FALSE;
}
- xcf_check_error (xcf_seek_end (info, error));
+ xcf_check_error (xcf_seek_pos (info, base + length, error));
}
break;
@@ -1189,40 +1147,37 @@ xcf_save_layer (XcfInfo *info,
/* save the current position which is where the hierarchy offset
* will be stored.
*/
- saved_pos = info->cp;
/* write out the layer tile hierarchy */
- xcf_check_error (xcf_seek_pos (info, info->cp + 8, error));
- offset = info->cp;
+ offset = info->cp + 8;
+ xcf_write_int32_check_error (info, &offset, 1);
+
+ saved_pos = info->cp;
+ xcf_check_error (xcf_seek_pos (info, offset, error));
xcf_check_error (xcf_save_hierarchy (info,
gimp_drawable_get_tiles (GIMP_DRAWABLE (layer)),
error));
+ offset = info->cp;
xcf_check_error (xcf_seek_pos (info, saved_pos, error));
- xcf_write_int32_check_error (info, &offset, 1);
-
- /* save the current position which is where the layer mask offset
- * will be stored.
- */
- saved_pos = info->cp;
/* write out the layer mask */
if (gimp_layer_get_mask (layer))
{
GimpLayerMask *mask = gimp_layer_get_mask (layer);
- xcf_check_error (xcf_seek_end (info, error));
- offset = info->cp;
+ xcf_write_int32_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),
error));
}
else
- offset = 0;
-
- xcf_check_error (xcf_seek_pos (info, saved_pos, error));
- xcf_write_int32_check_error (info, &offset, 1);
+ {
+ xcf_write_int32_check_error (info, &zero, 1);
+ xcf_check_error (xcf_seek_pos (info, offset, error));
+ }
return TRUE;
}
@@ -1264,23 +1219,13 @@ xcf_save_channel (XcfInfo *info,
/* write out the channel properties */
xcf_save_channel_props (info, image, channel, error);
- /* save the current position which is where the hierarchy offset
- * will be stored.
- */
- saved_pos = info->cp;
-
- /* write out the channel tile hierarchy */
- xcf_check_error (xcf_seek_pos (info, info->cp + 4, error));
- offset = info->cp;
+ offset = info->cp + 4;
+ xcf_write_int32_check_error (info, &offset, 1);
xcf_check_error (xcf_save_hierarchy (info,
gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
error));
- xcf_check_error (xcf_seek_pos (info, saved_pos, error));
- xcf_write_int32_check_error (info, &offset, 1);
- saved_pos = info->cp;
-
return TRUE;
}
@@ -1331,11 +1276,14 @@ xcf_save_hierarchy (XcfInfo *info,
tmp2 = xcf_calc_levels (height, TILE_HEIGHT);
nlevels = MAX (tmp1, tmp2);
- xcf_check_error (xcf_seek_pos (info, info->cp + (1 + nlevels) * 4, error));
+ offset = info->cp + (1 + nlevels) * 4;
for (i = 0; i < nlevels; i++)
{
- offset = info->cp;
+ xcf_write_int32_check_error (info, &offset, 1);
+
+ saved_pos = info->cp;
+ xcf_check_error (xcf_seek_pos (info, offset, error));
if (i == 0)
{
@@ -1353,29 +1301,15 @@ xcf_save_hierarchy (XcfInfo *info,
xcf_write_int32_check_error (info, (guint32 *) &tmp1, 1);
}
- /* seek back to where we are to write out the next
- * level offset and write it out.
- */
+ offset = info->cp;
xcf_check_error (xcf_seek_pos (info, saved_pos, error));
- xcf_write_int32_check_error (info, &offset, 1);
-
- /* increment the location we are to write out the
- * next offset.
- */
- saved_pos = info->cp;
-
- /* seek to the end of the file which is where
- * we will write out the next level.
- */
- xcf_check_error (xcf_seek_end (info, error));
}
/* write out a '0' offset position to indicate the end
* of the level offsets.
*/
- offset = 0;
- xcf_check_error (xcf_seek_pos (info, saved_pos, error));
- xcf_write_int32_check_error (info, &offset, 1);
+ xcf_write_int32_check_error (info, &zero, 1);
+ xcf_check_error (xcf_seek_pos (info, offset, error));
return TRUE;
}
@@ -1401,24 +1335,21 @@ xcf_save_level (XcfInfo *info,
xcf_write_int32_check_error (info, (guint32 *) &width, 1);
xcf_write_int32_check_error (info, (guint32 *) &height, 1);
- saved_pos = info->cp;
-
/* allocate a temporary buffer to store the rle data before it is
written to disk */
rlebuf =
g_malloc (TILE_WIDTH * TILE_HEIGHT * tile_manager_bpp (level) * 1.5);
+ ntiles = level->ntile_rows * level->ntile_cols;
+ offset = info->cp + (ntiles + 1) * 4;
if (level->tiles)
{
- ntiles = level->ntile_rows * level->ntile_cols;
- xcf_check_error (xcf_seek_pos (info, info->cp + (ntiles + 1) * 4, error));
-
for (i = 0; i < ntiles; i++)
{
- /* save the start offset of where we are writing
- * out the next tile.
- */
- offset = info->cp;
+ xcf_write_int32_check_error (info, &offset, 1);
+
+ saved_pos = info->cp;
+ xcf_check_error (xcf_seek_pos (info, offset, error));
/* write out the tile. */
switch (info->compression)
@@ -1438,21 +1369,8 @@ xcf_save_level (XcfInfo *info,
break;
}
- /* seek back to where we are to write out the next
- * tile offset and write it out.
- */
+ offset = info->cp;
xcf_check_error (xcf_seek_pos (info, saved_pos, error));
- xcf_write_int32_check_error (info, &offset, 1);
-
- /* increment the location we are to write out the
- * next offset.
- */
- saved_pos = info->cp;
-
- /* seek to the end of the file which is where
- * we will write out the next tile.
- */
- xcf_check_error (xcf_seek_end (info, error));
}
}
@@ -1461,12 +1379,10 @@ xcf_save_level (XcfInfo *info,
/* write out a '0' offset position to indicate the end
* of the level offsets.
*/
- offset = 0;
- xcf_check_error (xcf_seek_pos (info, saved_pos, error));
- xcf_write_int32_check_error (info, &offset, 1);
+ xcf_write_int32_check_error (info, &zero, 1);
+ xcf_check_error (xcf_seek_pos (info, offset, error));
return TRUE;
-
}
static gboolean
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]