gdiplus: Convert animated gif to PixelFormat32bppARGB on load.

This commit is contained in:
Piotr Caban 2015-03-12 10:17:34 +01:00 committed by Alexandre Julliard
parent b3a9c698e8
commit 799362a0b7
2 changed files with 55 additions and 16 deletions

View File

@ -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); 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) UINT active_frame, metadata_reader_func metadata_reader, GpImage **image)
{ {
GpStatus status=Ok; GpStatus status=Ok;
@ -3449,25 +3449,25 @@ static GpStatus decode_frame_wic(IWICBitmapDecoder *decoder,
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
IWICBitmapSource *bmp_source; if (!force_conversion)
IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICBitmapSource, (void **)&bmp_source); {
for (i=0; pixel_formats[i].wic_format; i++) for (i=0; pixel_formats[i].wic_format; i++)
{ {
if (IsEqualGUID(&wic_format, pixel_formats[i].wic_format)) if (IsEqualGUID(&wic_format, pixel_formats[i].wic_format))
{ {
source = bmp_source; source = (IWICBitmapSource*)frame;
IWICBitmapSource_AddRef(source);
gdip_format = pixel_formats[i].gdip_format; gdip_format = pixel_formats[i].gdip_format;
palette_type = pixel_formats[i].palette_type; palette_type = pixel_formats[i].palette_type;
break; break;
} }
} }
}
if (!source) if (!source)
{ {
/* unknown format; fall back on 32bppARGB */ /* unknown format; fall back on 32bppARGB */
hr = WICConvertBitmapSource(&GUID_WICPixelFormat32bppBGRA, bmp_source, &source); hr = WICConvertBitmapSource(&GUID_WICPixelFormat32bppBGRA, (IWICBitmapSource*)frame, &source);
gdip_format = PixelFormat32bppARGB; gdip_format = PixelFormat32bppARGB;
IWICBitmapSource_Release(bmp_source);
} }
TRACE("%s => %#x\n", wine_dbgstr_guid(&wic_format), gdip_format); 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) if(status != Ok)
return status; return status;
status = decode_frame_wic(decoder, 0, metadata_reader, image); status = decode_frame_wic(decoder, FALSE, 0, metadata_reader, image);
IWICBitmapDecoder_Release(decoder); IWICBitmapDecoder_Release(decoder);
return status; return status;
} }
@ -3588,7 +3588,7 @@ static GpStatus select_frame_wic(GpImage *image, UINT active_frame)
GpImage *new_image; GpImage *new_image;
GpStatus status; 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) if(status != Ok)
return status; return status;
@ -3608,7 +3608,7 @@ static GpStatus select_frame_gif(GpImage *image, UINT active_frame)
GpImage *new_image; GpImage *new_image;
GpStatus status; 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) if(status != Ok)
return status; return status;
@ -3658,7 +3658,30 @@ static GpStatus decode_image_png(IStream* stream, GpImage **image)
static GpStatus decode_image_gif(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) static GpStatus decode_image_tiff(IStream* stream, GpImage **image)

View File

@ -2434,6 +2434,8 @@ static void test_multiframegif(void)
ARGB color; ARGB color;
UINT count; UINT count;
GUID dimension; GUID dimension;
PixelFormat pixel_format;
INT palette_size;
/* Test frame functions with an animated GIF */ /* Test frame functions with an animated GIF */
hglob = GlobalAlloc (0, sizeof(gifanimation)); hglob = GlobalAlloc (0, sizeof(gifanimation));
@ -2452,6 +2454,16 @@ static void test_multiframegif(void)
return; 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 */ /* Bitmap starts at frame 0 */
color = 0xdeadbeef; color = 0xdeadbeef;
stat = GdipBitmapGetPixel(bmp, 0, 0, &color); stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
@ -2543,6 +2555,10 @@ static void test_multiframegif(void)
return; return;
} }
stat = GdipGetImagePixelFormat((GpImage*)bmp, &pixel_format);
expect(Ok, stat);
expect(PixelFormat8bppIndexed, pixel_format);
/* Check metadata */ /* Check metadata */
stat = GdipImageGetFrameDimensionsCount((GpImage*)bmp,&count); stat = GdipImageGetFrameDimensionsCount((GpImage*)bmp,&count);
expect(Ok, stat); expect(Ok, stat);