[gimp] Bug 686862 - Seek less when saving XCF files



commit 744eeb8e1a70270a58b44b19f515dd58f2964f12
Author: Michael Natterer <mitch gimp org>
Date:   Mon Apr 6 20:01:39 2015 +0200

    Bug 686862 - Seek less when saving XCF files
    
    Get rid of most seeking by writing the tile offsets to a table in
    memory, instead of directly to the file after each tile. Only seek
    back after writing all tiles, in order to save the entire table at
    once.

 app/xcf/xcf-save.c |   34 +++++++++++++++++++---------------
 1 files changed, 19 insertions(+), 15 deletions(-)
---
diff --git a/app/xcf/xcf-save.c b/app/xcf/xcf-save.c
index c0383e9..92b1dc6 100644
--- a/app/xcf/xcf-save.c
+++ b/app/xcf/xcf-save.c
@@ -1358,6 +1358,8 @@ xcf_save_level (XcfInfo     *info,
                 GError     **error)
 {
   const Babl *format;
+  guint32    *offset_table;
+  guint32    *next_offset;
   guint32     saved_pos;
   guint32     offset;
   guint32     width;
@@ -1392,7 +1394,15 @@ xcf_save_level (XcfInfo     *info,
 
   ntiles = n_tile_rows * n_tile_cols;
 
-  /* 'saved_pos' is the next slot in the offset table */
+  /* allocate an offset table so we don't have to seek back after each
+   * 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));
+  next_offset = offset_table;
+
+  /* 'saved_pos' is the offset of the tile offset table  */
   saved_pos = info->cp;
 
   /* write an empty offset table */
@@ -1405,17 +1415,8 @@ xcf_save_level (XcfInfo     *info,
     {
       GeglRectangle rect;
 
-      /* seek back to the next slot in the offset table and write the
-       * offset of the tile
-       */
-      xcf_check_error (xcf_seek_pos (info, saved_pos, error));
-      xcf_write_int32_check_error (info, &offset, 1);
-
-      /* remember the next slot in the offset table */
-      saved_pos = info->cp;
-
-      /* seek to the tile offset and save the tile */
-      xcf_check_error (xcf_seek_pos (info, offset, error));
+      /* store the offset in the table and increment the next pointer */
+      *next_offset++ = offset;
 
       gimp_gegl_buffer_get_tile_rect (buffer,
                                       XCF_TILE_WIDTH, XCF_TILE_HEIGHT,
@@ -1445,9 +1446,12 @@ xcf_save_level (XcfInfo     *info,
       offset = info->cp;
     }
 
-  /* there is already a '0' at the end of the offset table to indicate
-   * the end of the tile offsets
-   */
+  /* 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);
+
+  /* seek to the end of the file */
+  xcf_check_error (xcf_seek_pos (info, offset, error));
 
   return TRUE;
 }


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