mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-25 13:11:13 +00:00
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)
This commit is contained in:
parent
a40561930a
commit
71e0ad8d9e
@ -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
|
||||
|
@ -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;
|
||||
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, ctype & PNG_COLOR_MASK_ALPHA, 8, w, h);
|
||||
|
||||
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.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user