summaryrefslogtreecommitdiff
path: root/gdk-pixbuf
diff options
context:
space:
mode:
authorTor Lillqvist <tml@iki.fi>2009-10-08 10:54:22 +0300
committerTor Lillqvist <tml@iki.fi>2009-10-08 10:59:55 +0300
commit9212f560f0df8e9697d952fb4f3ad89595a4cab2 (patch)
tree65a1200e2e428753b0aa96da0f39a0801fef131a /gdk-pixbuf
parentf38fc7f37db3f2a135fe085014b7cfd568a7bb21 (diff)
downloadgdk-pixbuf-9212f560f0df8e9697d952fb4f3ad89595a4cab2.tar.gz
Fix the GDI+ gdk-pixbuf loader
Should fix bug #552678. Patch by Dominic Lachowicz, based on a clueful response from Jason Copenhaver on Albeto Ruiz's blog http://aruiz.typepad.com/siliconisland/2009/08/dear-lazyweb-gtk-need-gdi-help.html
Diffstat (limited to 'gdk-pixbuf')
-rw-r--r--gdk-pixbuf/io-gdip-utils.c68
1 files changed, 38 insertions, 30 deletions
diff --git a/gdk-pixbuf/io-gdip-utils.c b/gdk-pixbuf/io-gdip-utils.c
index 3dba9e5a7..b8fa72bea 100644
--- a/gdk-pixbuf/io-gdip-utils.c
+++ b/gdk-pixbuf/io-gdip-utils.c
@@ -31,6 +31,18 @@
#define LOAD_BUFFER_SIZE 65536
+struct _GdipContext {
+ GdkPixbufModuleUpdatedFunc updated_func;
+ GdkPixbufModulePreparedFunc prepared_func;
+ GdkPixbufModuleSizeFunc size_func;
+
+ gpointer user_data;
+ GByteArray *buffer;
+ IStream *stream;
+ HGLOBAL hg;
+};
+typedef struct _GdipContext GdipContext;
+
static GdiplusStartupFunc GdiplusStartup;
static GdipCreateBitmapFromStreamFunc GdipCreateBitmapFromStream;
static GdipBitmapGetPixelFunc GdipBitmapGetPixel;
@@ -339,16 +351,16 @@ gdip_pixbuf_to_bitmap (GdkPixbuf *pixbuf)
}
static GpBitmap *
-gdip_buffer_to_bitmap (const gchar *buffer, size_t size, GError **error)
+gdip_buffer_to_bitmap (GdipContext *context, GError **error)
{
HRESULT hr;
HGLOBAL hg = NULL;
GpBitmap *bitmap = NULL;
IStream *stream = NULL;
GpStatus status;
- guint64 size64 = size;
+ guint64 size64 = context->buffer->len;
- hg = gdip_buffer_to_hglobal (buffer, size, error);
+ hg = gdip_buffer_to_hglobal (context->buffer->data, context->buffer->len, error);
if (!hg)
return NULL;
@@ -365,26 +377,30 @@ gdip_buffer_to_bitmap (const gchar *buffer, size_t size, GError **error)
status = GdipCreateBitmapFromStream (stream, &bitmap);
- if (Ok != status)
+ if (Ok != status) {
gdip_set_error_from_gpstatus (error, GDK_PIXBUF_ERROR_FAILED, status);
+ IStream_Release (stream);
+ GlobalFree (hg);
+ return NULL;
+ }
- IStream_Release (stream);
- GlobalFree (hg);
+ context->stream = stream;
+ context->hg = hg;
return bitmap;
}
static GpImage *
-gdip_buffer_to_image (const gchar *buffer, size_t size, GError **error)
+gdip_buffer_to_image (GdipContext *context, GError **error)
{
HRESULT hr;
HGLOBAL hg = NULL;
GpImage *image = NULL;
IStream *stream = NULL;
GpStatus status;
- guint64 size64 = size;
+ guint64 size64 = context->buffer->len;
- hg = gdip_buffer_to_hglobal (buffer, size, error);
+ hg = gdip_buffer_to_hglobal (context->buffer->data, context->buffer->len, error);
if (!hg)
return NULL;
@@ -400,11 +416,15 @@ gdip_buffer_to_image (const gchar *buffer, size_t size, GError **error)
IStream_SetSize (stream, *(ULARGE_INTEGER *)&size64);
status = GdipLoadImageFromStream (stream, &image);
- if (Ok != status)
+ if (Ok != status) {
gdip_set_error_from_gpstatus (error, GDK_PIXBUF_ERROR_FAILED, status);
+ IStream_Release (stream);
+ GlobalFree (hg);
+ return NULL;
+ }
- IStream_Release (stream);
- GlobalFree (hg);
+ context->stream = stream;
+ context->hg = hg;
return image;
}
@@ -591,24 +611,14 @@ gdip_bitmap_get_n_loops (GpBitmap *bitmap, guint *loops)
return success;
}
-/*************************************************************************/
-/*************************************************************************/
-
-struct _GdipContext {
- GdkPixbufModuleUpdatedFunc updated_func;
- GdkPixbufModulePreparedFunc prepared_func;
- GdkPixbufModuleSizeFunc size_func;
-
- gpointer user_data;
-
- GByteArray *buffer;
-};
-typedef struct _GdipContext GdipContext;
-
static void
destroy_gdipcontext (GdipContext *context)
{
if (context != NULL) {
+ if (context->stream != NULL) {
+ IStream_Release(context->stream);
+ GlobalFree (context->hg);
+ }
g_byte_array_free (context->buffer, TRUE);
g_free (context);
}
@@ -807,9 +817,8 @@ gdk_pixbuf__gdip_image_stop_load (gpointer data, GError **error)
{
GdipContext *context = (GdipContext *)data;
GpBitmap *bitmap = NULL;
- GByteArray *image_buffer = context->buffer;
- bitmap = gdip_buffer_to_bitmap ((gchar *)image_buffer->data, image_buffer->len, error);
+ bitmap = gdip_buffer_to_bitmap (context, error);
if (!bitmap) {
destroy_gdipcontext (context);
@@ -824,7 +833,6 @@ static gboolean
gdk_pixbuf__gdip_image_stop_vector_load (gpointer data, GError **error)
{
GdipContext *context = (GdipContext *)data;
- GByteArray *image_buffer = context->buffer;
GpImage *metafile;
GpGraphics *graphics;
@@ -833,7 +841,7 @@ gdk_pixbuf__gdip_image_stop_vector_load (gpointer data, GError **error)
float metafile_xres, metafile_yres;
guint width, height;
- metafile = gdip_buffer_to_image ((gchar *)image_buffer->data, image_buffer->len, error);
+ metafile = gdip_buffer_to_image (context, error);
if (!metafile) {
destroy_gdipcontext (context);
g_set_error_literal (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE, _("Couldn't load metafile"));