summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <matthiasc@src.gnome.org>2002-04-06 18:51:40 +0000
committerMatthias Clasen <matthiasc@src.gnome.org>2002-04-06 18:51:40 +0000
commit71e0ad8d9ed2d87bbb51fce8ac802c82c2f79db8 (patch)
treeb0dd9336ccfa31e6d2216ab32566863e2a5a6f49
parenta40561930afcd4eda2d43eb252dd5bf1f6a06768 (diff)
downloadgdk-pixbuf-71e0ad8d9ed2d87bbb51fce8ac802c82c2f79db8.tar.gz
Restructured to use gdk_pixbuf_new instead of manually allocating image
* io-png.c (gdk_pixbuf__png_image_load): Restructured to use gdk_pixbuf_new instead of manually allocating image storage. This gives us a good rowstride and overflow checks. (#77807)
-rw-r--r--gdk-pixbuf/ChangeLog6
-rw-r--r--gdk-pixbuf/io-png.c69
2 files changed, 23 insertions, 52 deletions
diff --git a/gdk-pixbuf/ChangeLog b/gdk-pixbuf/ChangeLog
index 7334f0c30..7abfc86c2 100644
--- a/gdk-pixbuf/ChangeLog
+++ b/gdk-pixbuf/ChangeLog
@@ -1,3 +1,9 @@
+2002-04-06 Matthias Clasen <maclas@gmx.de>
+
+ * io-png.c (gdk_pixbuf__png_image_load): Restructured to use
+ gdk_pixbuf_new instead of manually allocating image storage. This
+ gives us a good rowstride and overflow checks. (#77807)
+
2002-04-05 Matthias Clasen <maclas@gmx.de>
* io-tiff.c (tiff_image_parse): Avoid allocating an extra copy of
diff --git a/gdk-pixbuf/io-png.c b/gdk-pixbuf/io-png.c
index 8111cacc0..ca1bd17a5 100644
--- a/gdk-pixbuf/io-png.c
+++ b/gdk-pixbuf/io-png.c
@@ -199,13 +199,6 @@ png_simple_warning_callback(png_structp png_save_ptr,
*/
}
-/* Destroy notification function for the pixbuf */
-static void
-free_buffer (guchar *pixels, gpointer data)
-{
- g_free (pixels);
-}
-
static gboolean
png_text_to_pixbuf_option (png_text text_ptr,
gchar **key,
@@ -240,16 +233,16 @@ png_free_callback (png_structp o, png_voidp x)
static GdkPixbuf *
gdk_pixbuf__png_image_load (FILE *f, GError **error)
{
- GdkPixbuf *pixbuf;
+ GdkPixbuf * volatile pixbuf = NULL;
png_structp png_ptr;
png_infop info_ptr;
png_textp text_ptr;
- gint i, ctype, bpp;
+ gint i, ctype;
png_uint_32 w, h;
png_bytepp volatile rows = NULL;
- guchar * volatile pixels = NULL;
gint num_texts;
- gchar **options = NULL;
+ gchar *key;
+ gchar *value;
#ifdef PNG_USER_MEM_SUPPORTED
png_ptr = png_create_read_struct_2 (PNG_LIBPNG_VER_STRING,
@@ -278,8 +271,8 @@ gdk_pixbuf__png_image_load (FILE *f, GError **error)
if (rows)
g_free (rows);
- if (pixels)
- g_free (pixels);
+ if (pixbuf)
+ g_object_unref (pixbuf);
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
return NULL;
@@ -293,16 +286,9 @@ gdk_pixbuf__png_image_load (FILE *f, GError **error)
return NULL;
}
- if (ctype & PNG_COLOR_MASK_ALPHA)
- bpp = 4;
- else
- bpp = 3;
-
- pixels = g_try_malloc (w * h * bpp);
- if (!pixels) {
- /* Check error NULL, normally this would be broken,
- * but libpng makes me want to code defensively.
- */
+ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, ctype & PNG_COLOR_MASK_ALPHA, 8, w, h);
+
+ if (!pixbuf) {
if (error && *error == NULL) {
g_set_error (error,
GDK_PIXBUF_ERROR,
@@ -310,6 +296,7 @@ gdk_pixbuf__png_image_load (FILE *f, GError **error)
_("Insufficient memory to load PNG file"));
}
+
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
return NULL;
}
@@ -317,44 +304,22 @@ gdk_pixbuf__png_image_load (FILE *f, GError **error)
rows = g_new (png_bytep, h);
for (i = 0; i < h; i++)
- rows[i] = pixels + i * w * bpp;
+ rows[i] = pixbuf->pixels + i * pixbuf->rowstride;
png_read_image (png_ptr, rows);
png_read_end (png_ptr, info_ptr);
if (png_get_text (png_ptr, info_ptr, &text_ptr, &num_texts)) {
- options = g_new (gchar *, num_texts * 2);
for (i = 0; i < num_texts; i++) {
- png_text_to_pixbuf_option (text_ptr[i],
- options + 2*i,
- options + 2*i + 1);
+ png_text_to_pixbuf_option (text_ptr[i], &key, &value);
+ gdk_pixbuf_set_option (pixbuf, key, value);
+ g_free (key);
+ g_free (value);
}
}
- png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
- g_free (rows);
-
- if (ctype & PNG_COLOR_MASK_ALPHA)
- pixbuf = gdk_pixbuf_new_from_data (pixels, GDK_COLORSPACE_RGB, TRUE, 8,
- w, h, w * 4,
- free_buffer, NULL);
- else
- pixbuf = gdk_pixbuf_new_from_data (pixels, GDK_COLORSPACE_RGB, FALSE, 8,
- w, h, w * 3,
- free_buffer, NULL);
- if (options) {
- for (i = 0; i < num_texts; i++) {
- if (pixbuf) {
- if (!gdk_pixbuf_set_option (pixbuf,
- options[2*i],
- options[2*i+1]))
- g_warning ("Got multiple tEXt chunks for the same key.");
- }
- g_free (options[2*i]);
- g_free (options[2*i+1]);
- }
- g_free (options);
- }
+ g_free (rows);
+ png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
return pixbuf;
}