mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 10:50:10 +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>
|
2002-04-05 Matthias Clasen <maclas@gmx.de>
|
||||||
|
|
||||||
* io-tiff.c (tiff_image_parse): Avoid allocating an extra copy of
|
* 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
|
static gboolean
|
||||||
png_text_to_pixbuf_option (png_text text_ptr,
|
png_text_to_pixbuf_option (png_text text_ptr,
|
||||||
gchar **key,
|
gchar **key,
|
||||||
@ -240,16 +233,16 @@ png_free_callback (png_structp o, png_voidp x)
|
|||||||
static GdkPixbuf *
|
static GdkPixbuf *
|
||||||
gdk_pixbuf__png_image_load (FILE *f, GError **error)
|
gdk_pixbuf__png_image_load (FILE *f, GError **error)
|
||||||
{
|
{
|
||||||
GdkPixbuf *pixbuf;
|
GdkPixbuf * volatile pixbuf = NULL;
|
||||||
png_structp png_ptr;
|
png_structp png_ptr;
|
||||||
png_infop info_ptr;
|
png_infop info_ptr;
|
||||||
png_textp text_ptr;
|
png_textp text_ptr;
|
||||||
gint i, ctype, bpp;
|
gint i, ctype;
|
||||||
png_uint_32 w, h;
|
png_uint_32 w, h;
|
||||||
png_bytepp volatile rows = NULL;
|
png_bytepp volatile rows = NULL;
|
||||||
guchar * volatile pixels = NULL;
|
|
||||||
gint num_texts;
|
gint num_texts;
|
||||||
gchar **options = NULL;
|
gchar *key;
|
||||||
|
gchar *value;
|
||||||
|
|
||||||
#ifdef PNG_USER_MEM_SUPPORTED
|
#ifdef PNG_USER_MEM_SUPPORTED
|
||||||
png_ptr = png_create_read_struct_2 (PNG_LIBPNG_VER_STRING,
|
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)
|
if (rows)
|
||||||
g_free (rows);
|
g_free (rows);
|
||||||
|
|
||||||
if (pixels)
|
if (pixbuf)
|
||||||
g_free (pixels);
|
g_object_unref (pixbuf);
|
||||||
|
|
||||||
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -293,16 +286,9 @@ gdk_pixbuf__png_image_load (FILE *f, GError **error)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctype & PNG_COLOR_MASK_ALPHA)
|
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, ctype & PNG_COLOR_MASK_ALPHA, 8, w, h);
|
||||||
bpp = 4;
|
|
||||||
else
|
|
||||||
bpp = 3;
|
|
||||||
|
|
||||||
pixels = g_try_malloc (w * h * bpp);
|
if (!pixbuf) {
|
||||||
if (!pixels) {
|
|
||||||
/* Check error NULL, normally this would be broken,
|
|
||||||
* but libpng makes me want to code defensively.
|
|
||||||
*/
|
|
||||||
if (error && *error == NULL) {
|
if (error && *error == NULL) {
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
GDK_PIXBUF_ERROR,
|
GDK_PIXBUF_ERROR,
|
||||||
@ -310,6 +296,7 @@ gdk_pixbuf__png_image_load (FILE *f, GError **error)
|
|||||||
_("Insufficient memory to load PNG file"));
|
_("Insufficient memory to load PNG file"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -317,44 +304,22 @@ gdk_pixbuf__png_image_load (FILE *f, GError **error)
|
|||||||
rows = g_new (png_bytep, h);
|
rows = g_new (png_bytep, h);
|
||||||
|
|
||||||
for (i = 0; i < h; i++)
|
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_image (png_ptr, rows);
|
||||||
png_read_end (png_ptr, info_ptr);
|
png_read_end (png_ptr, info_ptr);
|
||||||
|
|
||||||
if (png_get_text (png_ptr, info_ptr, &text_ptr, &num_texts)) {
|
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++) {
|
for (i = 0; i < num_texts; i++) {
|
||||||
png_text_to_pixbuf_option (text_ptr[i],
|
png_text_to_pixbuf_option (text_ptr[i], &key, &value);
|
||||||
options + 2*i,
|
gdk_pixbuf_set_option (pixbuf, key, value);
|
||||||
options + 2*i + 1);
|
g_free (key);
|
||||||
|
g_free (value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
|
||||||
g_free (rows);
|
g_free (rows);
|
||||||
|
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pixbuf;
|
return pixbuf;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user