};
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
#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*);
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
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);
LOOKUP (GdipDeleteGraphics);
LOOKUP (GdipGetImageEncoders);
LOOKUP (GdipGetImageEncodersSize);
+ LOOKUP (GdipBitmapLockBits);
+ LOOKUP (GdipBitmapUnlockBits);
+ LOOKUP (GdipGetImagePixelFormat);
+ LOOKUP (GdipCloneBitmapAreaI);
#undef LOOKUP
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)) {
GpImage *image = NULL;
IStream *stream = NULL;
GpStatus status;
+ guint64 size64 = size;
hg = gdip_buffer_to_hglobal (buffer, size, error);
return NULL;
}
+ IStream_SetSize (stream, *(ULARGE_INTEGER *)&size64);
status = GdipLoadImageFromStream (stream, &image);
if (Ok != status)
}
static GdkPixbuf *
-gdip_bitmap_to_pixbuf (GpBitmap *bitmap)
+gdip_bitmap_to_pixbuf (GpBitmap *bitmap, GError **error)
{
GdkPixbuf *pixbuf = NULL;
guchar *cursor = NULL;
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);
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;
}
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;
}
if (animation != NULL)
g_object_unref (G_OBJECT (animation));
+ GdipDisposeImage ((GpImage *)bitmap);
destroy_gdipcontext (context);
return TRUE;