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