summaryrefslogtreecommitdiff
path: root/gdk-pixbuf
diff options
context:
space:
mode:
authorDominic Lachowicz <domlachowicz@gmail.com>2008-09-18 14:30:43 +0000
committerDom Lachowicz <doml@src.gnome.org>2008-09-18 14:30:43 +0000
commitb559c7dacc4a7f8ee0e525192775eac5207e3cc4 (patch)
tree1521ef4cf2cc22f4d2fb4fd9f9b2248589a72ea0 /gdk-pixbuf
parent08e3627b2e382d14df2b49a223b596f2510a1862 (diff)
downloadgdk-pixbuf-b559c7dacc4a7f8ee0e525192775eac5207e3cc4.tar.gz
Fix 2 cases where we leaked a GpImage (#552545)
2008-09-18 Dominic Lachowicz <domlachowicz@gmail.com> * io-gdip-utils.c: Fix 2 cases where we leaked a GpImage (#552545) svn path=/trunk/; revision=21426
Diffstat (limited to 'gdk-pixbuf')
-rw-r--r--gdk-pixbuf/ChangeLog4
-rw-r--r--gdk-pixbuf/io-gdip-native.h29
-rw-r--r--gdk-pixbuf/io-gdip-utils.c27
3 files changed, 55 insertions, 5 deletions
diff --git a/gdk-pixbuf/ChangeLog b/gdk-pixbuf/ChangeLog
index 1000313c9..619dddded 100644
--- a/gdk-pixbuf/ChangeLog
+++ b/gdk-pixbuf/ChangeLog
@@ -1,3 +1,7 @@
+2008-09-18 Dominic Lachowicz <domlachowicz@gmail.com>
+
+ * io-gdip-utils.c: Fix 2 cases where we leaked a GpImage (#552545)
+
2008-09-17 Matthias Clasen <mclasen@redhat.com>
* === Released 2.14.2 ===
diff --git a/gdk-pixbuf/io-gdip-native.h b/gdk-pixbuf/io-gdip-native.h
index f5787ea83..24ea824f4 100644
--- a/gdk-pixbuf/io-gdip-native.h
+++ b/gdk-pixbuf/io-gdip-native.h
@@ -188,6 +188,26 @@ struct _ImageCodecInfo
};
typedef struct _ImageCodecInfo ImageCodecInfo;
+struct _BitmapData
+{
+ UINT Width;
+ UINT Height;
+ INT Stride;
+ PixelFormat PixelFormat;
+ VOID* Scan0;
+ UINT_PTR Reserved;
+};
+typedef struct _BitmapData BitmapData;
+
+struct _GpRect
+{
+ INT X;
+ INT Y;
+ INT Width;
+ INT Height;
+};
+typedef struct _GpRect GpRect;
+
#ifndef IStream_Release
#define IStream_Release(This) (This)->lpVtbl->Release(This)
#endif
@@ -200,6 +220,10 @@ typedef struct _ImageCodecInfo ImageCodecInfo;
#define IStream_Read(This,pv,cb,pcbRead) (This)->lpVtbl->Read(This,pv,cb,pcbRead)
#endif
+#ifndef IStream_SetSize
+#define IStream_SetSize(This,size) (This)->lpVtbl->SetSize(This,size)
+#endif
+
typedef GpStatus (WINGDIPAPI* GdiplusStartupFunc) (gpointer, const gpointer, gpointer);
typedef GpStatus (WINGDIPAPI* GdipCreateBitmapFromStreamFunc) (gpointer, GpBitmap**);
typedef GpStatus (WINGDIPAPI* GdipBitmapGetPixelFunc) (GpBitmap*, gint x, gint y, ARGB*);
@@ -232,4 +256,9 @@ typedef GpStatus (WINGDIPAPI* GdipGetImageVerticalResolutionFunc) (GpImage *imag
typedef GpStatus (WINGDIPAPI* GdipLoadImageFromStreamFunc) (IStream* stream, GpImage **image);
typedef GpStatus (WINGDIPAPI* GdipDeleteGraphicsFunc) (GpGraphics *graphics);
+typedef GpStatus (WINGDIPAPI* GdipBitmapLockBitsFunc) (GpBitmap* bitmap, const GpRect* rect, UINT flags, PixelFormat format, BitmapData* lockedBitmapData);
+typedef GpStatus (WINGDIPAPI* GdipBitmapUnlockBitsFunc) (GpBitmap* bitmap, BitmapData* lockedBitmapData);
+typedef GpStatus (WINGDIPAPI* GdipGetImagePixelFormatFunc) (GpImage *image, PixelFormat *format);
+typedef GpStatus (WINGDIPAPI* GdipCloneBitmapAreaIFunc) (INT x, INT y, INT width, INT height, PixelFormat format, GpBitmap *srcBitmap, GpBitmap **dstBitmap);
+
#endif
diff --git a/gdk-pixbuf/io-gdip-utils.c b/gdk-pixbuf/io-gdip-utils.c
index 74a0f1758..935372516 100644
--- a/gdk-pixbuf/io-gdip-utils.c
+++ b/gdk-pixbuf/io-gdip-utils.c
@@ -58,6 +58,10 @@ static GdipLoadImageFromStreamFunc GdipLoadImageFromStream;
static GdipDeleteGraphicsFunc GdipDeleteGraphics;
static GdipGetImageEncodersFunc GdipGetImageEncoders;
static GdipGetImageEncodersSizeFunc GdipGetImageEncodersSize;
+static GdipBitmapLockBitsFunc GdipBitmapLockBits;
+static GdipBitmapUnlockBitsFunc GdipBitmapUnlockBits;
+static GdipGetImagePixelFormatFunc GdipGetImagePixelFormat;
+static GdipCloneBitmapAreaIFunc GdipCloneBitmapAreaI;
DEFINE_GUID(FrameDimensionTime, 0x6aedbd6d,0x3fb5,0x418a,0x83,0xa6,0x7f,0x45,0x22,0x9d,0xc8,0x72);
DEFINE_GUID(FrameDimensionPage, 0x7462dc86,0x6180,0x4c7e,0x8e,0x3f,0xee,0x73,0x33,0xa7,0xa4,0x83);
@@ -161,6 +165,10 @@ gdip_init (void)
LOOKUP (GdipDeleteGraphics);
LOOKUP (GdipGetImageEncoders);
LOOKUP (GdipGetImageEncodersSize);
+ LOOKUP (GdipBitmapLockBits);
+ LOOKUP (GdipBitmapUnlockBits);
+ LOOKUP (GdipGetImagePixelFormat);
+ LOOKUP (GdipCloneBitmapAreaI);
#undef LOOKUP
@@ -338,12 +346,14 @@ gdip_buffer_to_bitmap (const gchar *buffer, size_t size, GError **error)
GpBitmap *bitmap = NULL;
IStream *stream = NULL;
GpStatus status;
+ guint64 size64 = size;
hg = gdip_buffer_to_hglobal (buffer, size, error);
if (!hg)
return NULL;
+ IStream_SetSize (stream, *(ULARGE_INTEGER *)&size64);
hr = CreateStreamOnHGlobal (hg, FALSE, (LPSTREAM *)&stream);
if (!SUCCEEDED (hr)) {
@@ -371,6 +381,7 @@ gdip_buffer_to_image (const gchar *buffer, size_t size, GError **error)
GpImage *image = NULL;
IStream *stream = NULL;
GpStatus status;
+ guint64 size64 = size;
hg = gdip_buffer_to_hglobal (buffer, size, error);
@@ -385,6 +396,7 @@ gdip_buffer_to_image (const gchar *buffer, size_t size, GError **error)
return NULL;
}
+ IStream_SetSize (stream, *(ULARGE_INTEGER *)&size64);
status = GdipLoadImageFromStream (stream, &image);
if (Ok != status)
@@ -651,7 +663,7 @@ gdk_pixbuf__gdip_image_load_increment (gpointer data,
}
static GdkPixbuf *
-gdip_bitmap_to_pixbuf (GpBitmap *bitmap)
+gdip_bitmap_to_pixbuf (GpBitmap *bitmap, GError **error)
{
GdkPixbuf *pixbuf = NULL;
guchar *cursor = NULL;
@@ -667,8 +679,10 @@ gdip_bitmap_to_pixbuf (GpBitmap *bitmap)
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, has_alpha, 8, width, height);
- if (!pixbuf)
+ if (!pixbuf) {
+ g_set_error_literal (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, _("Couldn't load bitmap"));
return NULL;
+ }
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
cursor = gdk_pixbuf_get_pixels (pixbuf);
@@ -677,9 +691,11 @@ gdip_bitmap_to_pixbuf (GpBitmap *bitmap)
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
ARGB pixel;
+ GpStatus status;
guchar *b = cursor + (y * rowstride + (x * n_channels));
- if (Ok != GdipBitmapGetPixel (bitmap, x, y, &pixel)) {
+ if (Ok != (status = GdipBitmapGetPixel (bitmap, x, y, &pixel))) {
+ gdip_set_error_from_gpstatus (error, GDK_PIXBUF_ERROR_FAILED, status);
g_object_unref (pixbuf);
return NULL;
}
@@ -726,14 +742,14 @@ stop_load (GpBitmap *bitmap, GdipContext *context, GError **error)
gdip_bitmap_select_frame (bitmap, i, TRUE);
- pixbuf = gdip_bitmap_to_pixbuf (bitmap);
+ pixbuf = gdip_bitmap_to_pixbuf (bitmap, error);
if (!pixbuf) {
if (animation != NULL)
g_object_unref (G_OBJECT (animation));
+ GdipDisposeImage ((GpImage *)bitmap);
destroy_gdipcontext (context);
- g_set_error_literal (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, _("Couldn't create pixbuf"));
return FALSE;
}
@@ -779,6 +795,7 @@ stop_load (GpBitmap *bitmap, GdipContext *context, GError **error)
if (animation != NULL)
g_object_unref (G_OBJECT (animation));
+ GdipDisposeImage ((GpImage *)bitmap);
destroy_gdipcontext (context);
return TRUE;