gtk+ r21426 - trunk/gdk-pixbuf



Author: doml
Date: Thu Sep 18 14:30:43 2008
New Revision: 21426
URL: http://svn.gnome.org/viewvc/gtk+?rev=21426&view=rev

Log:
2008-09-18  Dominic Lachowicz  <domlachowicz gmail com>

        * io-gdip-utils.c: Fix 2 cases where we leaked a GpImage (#552545)



Modified:
   trunk/gdk-pixbuf/ChangeLog
   trunk/gdk-pixbuf/io-gdip-native.h
   trunk/gdk-pixbuf/io-gdip-utils.c

Modified: trunk/gdk-pixbuf/io-gdip-native.h
==============================================================================
--- trunk/gdk-pixbuf/io-gdip-native.h	(original)
+++ trunk/gdk-pixbuf/io-gdip-native.h	Thu Sep 18 14:30:43 2008
@@ -188,6 +188,26 @@
 };
 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 @@
 #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* 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

Modified: trunk/gdk-pixbuf/io-gdip-utils.c
==============================================================================
--- trunk/gdk-pixbuf/io-gdip-utils.c	(original)
+++ trunk/gdk-pixbuf/io-gdip-utils.c	Thu Sep 18 14:30:43 2008
@@ -58,6 +58,10 @@
 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 @@
   LOOKUP (GdipDeleteGraphics);
   LOOKUP (GdipGetImageEncoders);
   LOOKUP (GdipGetImageEncodersSize);
+  LOOKUP (GdipBitmapLockBits);
+  LOOKUP (GdipBitmapUnlockBits);
+  LOOKUP (GdipGetImagePixelFormat);
+  LOOKUP (GdipCloneBitmapAreaI);
 
 #undef LOOKUP
 
@@ -338,12 +346,14 @@
   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 @@
   GpImage *image = NULL;
   IStream *stream = NULL;
   GpStatus status;
+  guint64 size64 = size;
 
   hg = gdip_buffer_to_hglobal (buffer, size, error);
 
@@ -385,6 +396,7 @@
     return NULL;
   }
   
+  IStream_SetSize (stream, *(ULARGE_INTEGER *)&size64);
   status = GdipLoadImageFromStream (stream, &image);
 
   if (Ok != status)
@@ -651,7 +663,7 @@
 }
 
 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 @@
 
   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 @@
   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 @@
 
     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 @@
   if (animation != NULL)
     g_object_unref (G_OBJECT (animation));
 
+  GdipDisposeImage ((GpImage *)bitmap);
   destroy_gdipcontext (context);
   
   return TRUE;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]