[gimp] Bug 731390 - XCF files have a max size of 4G



commit dd47e7bc3d06933bb05f06a2e48d17fce143346b
Author: Michael Natterer <mitch gimp org>
Date:   Thu Mar 23 14:17:56 2017 +0100

    Bug 731390 - XCF files have a max size of 4G
    
    Enable 64 bit file offsets in XCF files, starting with newly added XCF
    version 11.
    
    We use at least version 11 if:
    
    - we would use the previous version 10 (essentially skipping 10)
    - the in-memory size of the image is larger than 4 Gig

 app/core/gimpimage.c |   14 ++++++++++++++
 app/xcf/xcf.c        |   35 ++++++++++++++++++++---------------
 2 files changed, 34 insertions(+), 15 deletions(-)
---
diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c
index e82c791..f032a1a 100644
--- a/app/core/gimpimage.c
+++ b/app/core/gimpimage.c
@@ -2495,6 +2495,19 @@ gimp_image_get_xcf_version (GimpImage    *image,
   if (zlib_compression)
     version = MAX (8, version);
 
+  /* if version is 10 (lots of new layer modes), go to version 11 with
+   * 64 bit offsets right away
+   */
+  if (version == 10)
+    version = 11;
+
+  /* use the image's in-memory size as an upper bound to estimate the
+   * need for 64 bit file offsets inside the XCF, this is a *very*
+   * conservative estimate and should never fail
+   */
+  if (gimp_object_get_memsize (GIMP_OBJECT (image), NULL) >= ((gint64) 1 << 32))
+    version = MAX (11, version);
+
   switch (version)
     {
     case 0:
@@ -2516,6 +2529,7 @@ gimp_image_get_xcf_version (GimpImage    *image,
     case 8:
     case 9:
     case 10:
+    case 11:
       if (gimp_version)   *gimp_version   = 210;
       if (version_string) *version_string = "GIMP 2.10";
       break;
diff --git a/app/xcf/xcf.c b/app/xcf/xcf.c
index dc3cef9..6bfd0a8 100644
--- a/app/xcf/xcf.c
+++ b/app/xcf/xcf.c
@@ -77,7 +77,8 @@ static GimpXcfLoaderFunc * const xcf_loaders[] =
   xcf_load_image,   /* version  7 */
   xcf_load_image,   /* version  8 */
   xcf_load_image,   /* version  9 */
-  xcf_load_image    /* version 10 */
+  xcf_load_image,   /* version 10 */
+  xcf_load_image    /* version 11 */
 };
 
 
@@ -268,20 +269,19 @@ xcf_load_stream (Gimp          *gimp,
   else
     filename = _("Memory Stream");
 
-  info.gimp        = gimp;
-  info.input       = input;
-  info.seekable    = G_SEEKABLE (input);
-  info.progress    = progress;
-  info.file        = input_file;
-  info.compression = COMPRESS_NONE;
+  info.gimp             = gimp;
+  info.input            = input;
+  info.seekable         = G_SEEKABLE (input);
+  info.bytes_per_offset = 4;
+  info.progress         = progress;
+  info.file             = input_file;
+  info.compression      = COMPRESS_NONE;
 
   if (progress)
     gimp_progress_start (progress, FALSE, _("Opening '%s'"), filename);
 
   success = TRUE;
 
-  info.bytes_per_offset = 4;
-
   xcf_read_int8 (&info, (guint8 *) id, 14);
 
   if (! g_str_has_prefix (id, "gimp xcf "))
@@ -301,6 +301,9 @@ xcf_load_stream (Gimp          *gimp,
       success = FALSE;
     }
 
+  if (info.file_version >= 11)
+    info.bytes_per_offset = 8;
+
   if (success)
     {
       if (info.file_version >= 0 &&
@@ -353,11 +356,12 @@ xcf_save_stream (Gimp           *gimp,
   else
     filename = _("Memory Stream");
 
-  info.gimp     = gimp;
-  info.output   = output;
-  info.seekable = G_SEEKABLE (output);
-  info.progress = progress;
-  info.file     = output_file;
+  info.gimp             = gimp;
+  info.output           = output;
+  info.seekable         = G_SEEKABLE (output);
+  info.bytes_per_offset = 4;
+  info.progress         = progress;
+  info.file             = output_file;
 
   if (gimp_image_get_xcf_compat_mode (image))
     info.compression = COMPRESS_RLE;
@@ -369,7 +373,8 @@ xcf_save_stream (Gimp           *gimp,
                                                   COMPRESS_ZLIB,
                                                   NULL, NULL);
 
-  info.bytes_per_offset = 4;
+  if (info.file_version >= 11)
+    info.bytes_per_offset = 8;
 
   if (progress)
     gimp_progress_start (progress, FALSE, _("Saving '%s'"), filename);


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