diff --git a/gdk/gdktexture.c b/gdk/gdktexture.c index a33fc3347c..a6e79bca56 100644 --- a/gdk/gdktexture.c +++ b/gdk/gdktexture.c @@ -410,6 +410,13 @@ gdk_texture_new_from_file (GFile *file, return texture; } +gboolean +gdk_texture_can_load (GBytes *bytes) +{ + return gdk_is_png (bytes) || + gdk_is_jpeg (bytes) || + gdk_is_tiff (bytes); +} /** * gdk_texture_new_from_bytes: diff --git a/gdk/gdktextureprivate.h b/gdk/gdktextureprivate.h index f4cb5eab66..814ed5d92c 100644 --- a/gdk/gdktextureprivate.h +++ b/gdk/gdktextureprivate.h @@ -35,6 +35,8 @@ struct _GdkTextureClass { gsize stride); }; +gboolean gdk_texture_can_load (GBytes *bytes); + GdkTexture * gdk_texture_new_for_surface (cairo_surface_t *surface); cairo_surface_t * gdk_texture_download_surface (GdkTexture *texture); /* NB: GdkMemoryTexture */ diff --git a/gtk/gdkpixbufutils.c b/gtk/gdkpixbufutils.c index 2b48d76943..7bbe5d5fd8 100644 --- a/gtk/gdkpixbufutils.c +++ b/gtk/gdkpixbufutils.c @@ -20,6 +20,8 @@ #include "gdkpixbufutilsprivate.h" #include "gtkscalerprivate.h" +#include "gdk/gdktextureprivate.h" + static GdkPixbuf * load_from_stream (GdkPixbufLoader *loader, GInputStream *stream, @@ -597,42 +599,44 @@ GdkPaintable * gdk_paintable_new_from_bytes_scaled (GBytes *bytes, int scale_factor) { - GdkPixbufLoader *loader; - GdkPixbuf *pixbuf = NULL; LoaderData loader_data; GdkTexture *texture; GdkPaintable *paintable; loader_data.scale_factor = scale_factor; - loader = gdk_pixbuf_loader_new (); - g_signal_connect (loader, "size-prepared", - G_CALLBACK (on_loader_size_prepared), &loader_data); + if (gdk_texture_can_load (bytes)) + { + /* We know these formats can't be scaled */ + texture = gdk_texture_new_from_bytes (bytes, NULL); + if (texture == NULL) + return NULL; + } + else + { + GdkPixbufLoader *loader; + gboolean success; - if (!gdk_pixbuf_loader_write_bytes (loader, bytes, NULL)) - goto out; + loader = gdk_pixbuf_loader_new (); + g_signal_connect (loader, "size-prepared", + G_CALLBACK (on_loader_size_prepared), &loader_data); - if (!gdk_pixbuf_loader_close (loader, NULL)) - goto out; + success = gdk_pixbuf_loader_write_bytes (loader, bytes, NULL); + /* close even when writing failed */ + success &= gdk_pixbuf_loader_close (loader, NULL); - pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); - if (pixbuf != NULL) - g_object_ref (pixbuf); + if (!success) + return NULL; - out: - gdk_pixbuf_loader_close (loader, NULL); - g_object_unref (loader); + texture = gdk_texture_new_for_pixbuf (gdk_pixbuf_loader_get_pixbuf (loader)); + g_object_unref (loader); + } - if (!pixbuf) - return NULL; - - texture = gdk_texture_new_for_pixbuf (pixbuf); if (loader_data.scale_factor != 1) paintable = gtk_scaler_new (GDK_PAINTABLE (texture), loader_data.scale_factor); else paintable = g_object_ref ((GdkPaintable *)texture); - g_object_unref (pixbuf); g_object_unref (texture); return paintable;