Piotr Caban : gdiplus: Convert animated gif to PixelFormat32bppARGB on load.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Mar 13 08:44:24 CDT 2015
Module: wine
Branch: master
Commit: 799362a0b7afa59d8238ed1536d791088f6cee9f
URL: http://source.winehq.org/git/wine.git/?a=commit;h=799362a0b7afa59d8238ed1536d791088f6cee9f
Author: Piotr Caban <piotr at codeweavers.com>
Date: Thu Mar 12 10:17:34 2015 +0100
gdiplus: Convert animated gif to PixelFormat32bppARGB on load.
---
dlls/gdiplus/image.c | 55 ++++++++++++++++++++++++++++++++--------------
dlls/gdiplus/tests/image.c | 16 ++++++++++++++
2 files changed, 55 insertions(+), 16 deletions(-)
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index 36502d7..409a3c6 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -3421,7 +3421,7 @@ static GpStatus initialize_decoder_wic(IStream *stream, REFGUID container, IWICB
typedef void (*metadata_reader_func)(GpBitmap *bitmap, IWICBitmapDecoder *decoder, UINT frame);
-static GpStatus decode_frame_wic(IWICBitmapDecoder *decoder,
+static GpStatus decode_frame_wic(IWICBitmapDecoder *decoder, BOOL force_conversion,
UINT active_frame, metadata_reader_func metadata_reader, GpImage **image)
{
GpStatus status=Ok;
@@ -3449,25 +3449,25 @@ static GpStatus decode_frame_wic(IWICBitmapDecoder *decoder,
if (SUCCEEDED(hr))
{
- IWICBitmapSource *bmp_source;
- IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICBitmapSource, (void **)&bmp_source);
-
- for (i=0; pixel_formats[i].wic_format; i++)
+ if (!force_conversion)
{
- if (IsEqualGUID(&wic_format, pixel_formats[i].wic_format))
+ for (i=0; pixel_formats[i].wic_format; i++)
{
- source = bmp_source;
- gdip_format = pixel_formats[i].gdip_format;
- palette_type = pixel_formats[i].palette_type;
- break;
+ if (IsEqualGUID(&wic_format, pixel_formats[i].wic_format))
+ {
+ source = (IWICBitmapSource*)frame;
+ IWICBitmapSource_AddRef(source);
+ gdip_format = pixel_formats[i].gdip_format;
+ palette_type = pixel_formats[i].palette_type;
+ break;
+ }
}
}
if (!source)
{
/* unknown format; fall back on 32bppARGB */
- hr = WICConvertBitmapSource(&GUID_WICPixelFormat32bppBGRA, bmp_source, &source);
+ hr = WICConvertBitmapSource(&GUID_WICPixelFormat32bppBGRA, (IWICBitmapSource*)frame, &source);
gdip_format = PixelFormat32bppARGB;
- IWICBitmapSource_Release(bmp_source);
}
TRACE("%s => %#x\n", wine_dbgstr_guid(&wic_format), gdip_format);
}
@@ -3578,7 +3578,7 @@ static GpStatus decode_image_wic(IStream *stream, REFGUID container,
if(status != Ok)
return status;
- status = decode_frame_wic(decoder, 0, metadata_reader, image);
+ status = decode_frame_wic(decoder, FALSE, 0, metadata_reader, image);
IWICBitmapDecoder_Release(decoder);
return status;
}
@@ -3588,7 +3588,7 @@ static GpStatus select_frame_wic(GpImage *image, UINT active_frame)
GpImage *new_image;
GpStatus status;
- status = decode_frame_wic(image->decoder, active_frame, NULL, &new_image);
+ status = decode_frame_wic(image->decoder, FALSE, active_frame, NULL, &new_image);
if(status != Ok)
return status;
@@ -3608,7 +3608,7 @@ static GpStatus select_frame_gif(GpImage *image, UINT active_frame)
GpImage *new_image;
GpStatus status;
- status = decode_frame_wic(image->decoder, active_frame, gif_metadata_reader, &new_image);
+ status = decode_frame_wic(image->decoder, TRUE, active_frame, gif_metadata_reader, &new_image);
if(status != Ok)
return status;
@@ -3658,7 +3658,30 @@ static GpStatus decode_image_png(IStream* stream, GpImage **image)
static GpStatus decode_image_gif(IStream* stream, GpImage **image)
{
- return decode_image_wic(stream, &GUID_ContainerFormatGif, gif_metadata_reader, image);
+ IWICBitmapDecoder *decoder;
+ UINT frame_count;
+ GpStatus status;
+ HRESULT hr;
+
+ status = initialize_decoder_wic(stream, &GUID_ContainerFormatGif, &decoder);
+ if(status != Ok)
+ return status;
+
+ hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
+ if(FAILED(hr))
+ return hresult_to_status(hr);
+
+ status = decode_frame_wic(decoder, frame_count>1 ? TRUE : FALSE,
+ 0, gif_metadata_reader, image);
+ IWICBitmapDecoder_Release(decoder);
+ if(status != Ok)
+ return status;
+
+ if(frame_count > 1) {
+ GdipFree((*image)->palette);
+ (*image)->palette = NULL;
+ }
+ return Ok;
}
static GpStatus decode_image_tiff(IStream* stream, GpImage **image)
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c
index fe80bd6..f33cb90 100644
--- a/dlls/gdiplus/tests/image.c
+++ b/dlls/gdiplus/tests/image.c
@@ -2434,6 +2434,8 @@ static void test_multiframegif(void)
ARGB color;
UINT count;
GUID dimension;
+ PixelFormat pixel_format;
+ INT palette_size;
/* Test frame functions with an animated GIF */
hglob = GlobalAlloc (0, sizeof(gifanimation));
@@ -2452,6 +2454,16 @@ static void test_multiframegif(void)
return;
}
+ stat = GdipGetImagePixelFormat((GpImage*)bmp, &pixel_format);
+ expect(Ok, stat);
+ expect(PixelFormat32bppARGB, pixel_format);
+
+ stat = GdipGetImagePaletteSize((GpImage*)bmp, &palette_size);
+ expect(Ok, stat);
+ ok(palette_size == sizeof(ColorPalette) ||
+ broken(palette_size == sizeof(ColorPalette)+sizeof(ARGB[3])),
+ "palette_size = %d\n", palette_size);
+
/* Bitmap starts at frame 0 */
color = 0xdeadbeef;
stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
@@ -2543,6 +2555,10 @@ static void test_multiframegif(void)
return;
}
+ stat = GdipGetImagePixelFormat((GpImage*)bmp, &pixel_format);
+ expect(Ok, stat);
+ expect(PixelFormat8bppIndexed, pixel_format);
+
/* Check metadata */
stat = GdipImageGetFrameDimensionsCount((GpImage*)bmp,&count);
expect(Ok, stat);
More information about the wine-cvs
mailing list