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
This commit is contained in:
Michael Natterer 2017-03-23 14:17:56 +01:00
parent 829bad4063
commit dd47e7bc3d
2 changed files with 34 additions and 15 deletions

View File

@ -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;

View File

@ -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);