diff --git a/app/xcf/Makefile.am b/app/xcf/Makefile.am index 65a3dc8a80..a95a87cf7c 100644 --- a/app/xcf/Makefile.am +++ b/app/xcf/Makefile.am @@ -25,5 +25,7 @@ libappxcf_a_SOURCES = \ xcf-save.h \ xcf-seek.c \ xcf-seek.h \ + xcf-utils.c \ + xcf-utils.h \ xcf-write.c \ xcf-write.h diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c index c820c50c04..a4978afb4a 100644 --- a/app/xcf/xcf-load.c +++ b/app/xcf/xcf-load.c @@ -70,6 +70,7 @@ #include "xcf-load.h" #include "xcf-read.h" #include "xcf-seek.h" +#include "xcf-utils.h" #include "gimp-log.h" #include "gimp-intl.h" @@ -2064,8 +2065,11 @@ xcf_load_tile (XcfInfo *info, tile_size / bpp * n_components); } - gegl_buffer_set (buffer, tile_rect, 0, format, tile_data, - GEGL_AUTO_ROWSTRIDE); + if (! xcf_data_is_zero (tile_data, tile_size)) + { + gegl_buffer_set (buffer, tile_rect, 0, format, tile_data, + GEGL_AUTO_ROWSTRIDE); + } return TRUE; } @@ -2080,6 +2084,7 @@ xcf_load_tile_rle (XcfInfo *info, gint bpp = babl_format_get_bytes_per_pixel (format); gint tile_size = bpp * tile_rect->width * tile_rect->height; guchar *tile_data = g_alloca (tile_size); + guchar nonzero = FALSE; gsize bytes_read; gint i; guchar *xcfdata; @@ -2158,6 +2163,7 @@ xcf_load_tile_rle (XcfInfo *info, while (length-- > 0) { *data = *xcfdata++; + nonzero |= *data; data += bpp; } } @@ -2189,6 +2195,7 @@ xcf_load_tile_rle (XcfInfo *info, } val = *xcfdata++; + nonzero |= val; for (j = 0; j < length; j++) { @@ -2199,17 +2206,20 @@ xcf_load_tile_rle (XcfInfo *info, } } - if (info->file_version >= 12) + if (nonzero) { - gint n_components = babl_format_get_n_components (format); + if (info->file_version >= 12) + { + gint n_components = babl_format_get_n_components (format); - xcf_read_from_be (bpp / n_components, tile_data, - tile_size / bpp * n_components); + xcf_read_from_be (bpp / n_components, tile_data, + tile_size / bpp * n_components); + } + + gegl_buffer_set (buffer, tile_rect, 0, format, tile_data, + GEGL_AUTO_ROWSTRIDE); } - gegl_buffer_set (buffer, tile_rect, 0, format, tile_data, - GEGL_AUTO_ROWSTRIDE); - return TRUE; bogus_rle: @@ -2297,17 +2307,20 @@ xcf_load_tile_zlib (XcfInfo *info, } } - if (info->file_version >= 12) + if (! xcf_data_is_zero (tile_data, tile_size)) { - gint n_components = babl_format_get_n_components (format); + if (info->file_version >= 12) + { + gint n_components = babl_format_get_n_components (format); - xcf_read_from_be (bpp / n_components, tile_data, - tile_size / bpp * n_components); + xcf_read_from_be (bpp / n_components, tile_data, + tile_size / bpp * n_components); + } + + gegl_buffer_set (buffer, tile_rect, 0, format, tile_data, + GEGL_AUTO_ROWSTRIDE); } - gegl_buffer_set (buffer, tile_rect, 0, format, tile_data, - GEGL_AUTO_ROWSTRIDE); - inflateEnd (&strm); return TRUE; diff --git a/app/xcf/xcf-utils.c b/app/xcf/xcf-utils.c new file mode 100644 index 0000000000..6ef0b72cfb --- /dev/null +++ b/app/xcf/xcf-utils.c @@ -0,0 +1,53 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" + +#include +#include +#include + +#include "xcf-utils.h" + + +gboolean +xcf_data_is_zero (const void *data, + gint size) +{ + const guint8 *data8; + const guint64 *data64; + + for (data8 = data; size > 0 && (guintptr) data8 % 8 != 0; data8++, size--) + { + if (*data8) + return FALSE; + } + + for (data64 = (gpointer) data8; size >= 8; data64++, size -= 8) + { + if (*data64) + return FALSE; + } + + for (data8 = (gpointer) data64; size > 0; data8++, size--) + { + if (*data8) + return FALSE; + } + + return TRUE; +} diff --git a/app/xcf/xcf-utils.h b/app/xcf/xcf-utils.h new file mode 100644 index 0000000000..07b6856c6a --- /dev/null +++ b/app/xcf/xcf-utils.h @@ -0,0 +1,26 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __XCF_UTILS_H__ +#define __XCF_UTILS_H__ + + +gboolean xcf_data_is_zero (const void *data, + gint size); + + +#endif /* __XCF_UTILS_H__ */