Dmitry Timoshkov : gdiplus: Add GIF transparent index to the image properties.
Alexandre Julliard
julliard at winehq.org
Tue Sep 25 15:13:38 CDT 2012
Module: wine
Branch: master
Commit: 54edca19e1dbcb33f197771557c7ee05faf0f7bd
URL: http://source.winehq.org/git/wine.git/?a=commit;h=54edca19e1dbcb33f197771557c7ee05faf0f7bd
Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date: Tue Sep 25 12:54:01 2012 +0900
gdiplus: Add GIF transparent index to the image properties.
---
dlls/gdiplus/image.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 73 insertions(+), 0 deletions(-)
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index e3c4353..1732781 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -3144,6 +3144,33 @@ static void add_property(GpBitmap *bitmap, PropertyItem *item)
bitmap->prop_count++;
}
+static BOOL get_bool_property(IWICMetadataReader *reader, const GUID *guid, const WCHAR *prop_name)
+{
+ HRESULT hr;
+ GUID format;
+ PROPVARIANT id, value;
+ BOOL ret = FALSE;
+
+ IWICMetadataReader_GetMetadataFormat(reader, &format);
+ if (!IsEqualGUID(&format, guid)) return FALSE;
+
+ PropVariantInit(&id);
+ PropVariantInit(&value);
+
+ id.vt = VT_LPWSTR;
+ id.u.pwszVal = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(prop_name) + 1) * sizeof(WCHAR));
+ if (!id.u.pwszVal) return FALSE;
+ lstrcpyW(id.u.pwszVal, prop_name);
+ hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value);
+ if (hr == S_OK && value.vt == VT_BOOL)
+ ret = value.u.boolVal;
+
+ PropVariantClear(&id);
+ PropVariantClear(&value);
+
+ return ret;
+}
+
static PropertyItem *get_property(IWICMetadataReader *reader, const GUID *guid, const WCHAR *prop_name)
{
HRESULT hr;
@@ -3207,6 +3234,21 @@ static PropertyItem *get_gif_background(IWICMetadataReader *reader)
return background;
}
+static PropertyItem *get_gif_transparent_idx(IWICMetadataReader *reader)
+{
+ static const WCHAR transparency_flagW[] = { 'T','r','a','n','s','p','a','r','e','n','c','y','F','l','a','g',0 };
+ static const WCHAR colorW[] = { 'T','r','a','n','s','p','a','r','e','n','t','C','o','l','o','r','I','n','d','e','x',0 };
+ PropertyItem *index = NULL;
+
+ if (get_bool_property(reader, &GUID_MetadataFormatGCE, transparency_flagW))
+ {
+ index = get_property(reader, &GUID_MetadataFormatGCE, colorW);
+ if (index)
+ index->id = PropertyTagIndexTransparent;
+ }
+ return index;
+}
+
static LONG get_gif_frame_delay(IWICBitmapFrameDecode *frame)
{
static const WCHAR delayW[] = { 'D','e','l','a','y',0 };
@@ -3254,6 +3296,7 @@ static void gif_metadata_reader(GpBitmap *bitmap, IWICBitmapDecoder *decoder, UI
IWICMetadataReader *reader;
UINT frame_count, block_count, i;
PropertyItem *delay = NULL, *comment = NULL, *background = NULL;
+ PropertyItem *transparent_idx = NULL;
IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
if (frame_count > 1)
@@ -3314,6 +3357,36 @@ static void gif_metadata_reader(GpBitmap *bitmap, IWICBitmapDecoder *decoder, UI
GdipFree(delay);
GdipFree(comment);
GdipFree(background);
+
+ /* Win7 gdiplus always returns transparent color index from frame 0 */
+ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
+ if (hr != S_OK) return;
+
+ hr = IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICMetadataBlockReader, (void **)&block_reader);
+ if (hr == S_OK)
+ {
+ hr = IWICMetadataBlockReader_GetCount(block_reader, &block_count);
+ if (hr == S_OK)
+ {
+ for (i = 0; i < block_count; i++)
+ {
+ hr = IWICMetadataBlockReader_GetReaderByIndex(block_reader, i, &reader);
+ if (hr == S_OK)
+ {
+ if (!transparent_idx)
+ transparent_idx = get_gif_transparent_idx(reader);
+
+ IWICMetadataReader_Release(reader);
+ }
+ }
+ }
+ IWICMetadataBlockReader_Release(block_reader);
+ }
+
+ if (transparent_idx) add_property(bitmap, transparent_idx);
+ GdipFree(transparent_idx);
+
+ IWICBitmapFrameDecode_Release(frame);
}
typedef void (*metadata_reader_func)(GpBitmap *bitmap, IWICBitmapDecoder *decoder, UINT frame);
More information about the wine-cvs
mailing list