Dmitry Timoshkov : gdiplus: Add GIF comment to the image properties.

Alexandre Julliard julliard at winehq.org
Tue Sep 25 15:13:38 CDT 2012


Module: wine
Branch: master
Commit: 000f4725aa67dee4f3c321b87d03b297257a53a7
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=000f4725aa67dee4f3c321b87d03b297257a53a7

Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date:   Tue Sep 25 12:51:23 2012 +0900

gdiplus: Add GIF comment to the image properties.

---

 dlls/gdiplus/image.c |  127 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 126 insertions(+), 1 deletions(-)

diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index c6018ab..69879ac 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -3100,8 +3100,133 @@ GpStatus WINGDIPAPI GdipLoadImageFromFileICM(GDIPCONST WCHAR* filename,GpImage *
     return GdipLoadImageFromFile(filename, image);
 }
 
-static void gif_metadata_reader(GpBitmap *bitmap, IWICBitmapDecoder *decoder, UINT frame)
+static void add_property(GpBitmap *bitmap, PropertyItem *item)
 {
+    UINT prop_size, prop_count;
+    PropertyItem *prop_item;
+
+    if (bitmap->prop_item == NULL)
+    {
+        prop_size = prop_count = 0;
+        prop_item = GdipAlloc(item->length + sizeof(PropertyItem));
+        if (!prop_item) return;
+    }
+    else
+    {
+        UINT i;
+        char *item_value;
+
+        GdipGetPropertySize((GpImage *)bitmap, &prop_size, &prop_count);
+
+        prop_item = GdipAlloc(prop_size + item->length + sizeof(PropertyItem));
+        if (!prop_item) return;
+        memcpy(prop_item, bitmap->prop_item, sizeof(PropertyItem) * bitmap->prop_count);
+        prop_size -= sizeof(PropertyItem) * bitmap->prop_count;
+        memcpy(prop_item + prop_count + 1, bitmap->prop_item + prop_count, prop_size);
+
+        item_value = (char *)(prop_item + prop_count + 1);
+
+        for (i = 0; i < prop_count; i++)
+        {
+            prop_item[i].value = item_value;
+            item_value += prop_item[i].length;
+        }
+    }
+
+    prop_item[prop_count].id = item->id;
+    prop_item[prop_count].type = item->type;
+    prop_item[prop_count].length = item->length;
+    prop_item[prop_count].value = (char *)(prop_item + prop_count + 1) + prop_size;
+    memcpy(prop_item[prop_count].value, item->value, item->length);
+
+    GdipFree(bitmap->prop_item);
+    bitmap->prop_item = prop_item;
+    bitmap->prop_count++;
+}
+
+static PropertyItem *get_property(IWICMetadataReader *reader, const GUID *guid, const WCHAR *prop_name)
+{
+    HRESULT hr;
+    GUID format;
+    PROPVARIANT id, value;
+    PropertyItem *item = NULL;
+
+    IWICMetadataReader_GetMetadataFormat(reader, &format);
+    if (!IsEqualGUID(&format, guid)) return NULL;
+
+    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 NULL;
+    lstrcpyW(id.u.pwszVal, prop_name);
+    hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value);
+    if (hr == S_OK)
+    {
+        UINT item_size = propvariant_size(&value);
+        if (item_size)
+        {
+            item_size += sizeof(*item);
+            item = GdipAlloc(item_size);
+            if (propvariant_to_item(&value, item, item_size, 0) != Ok)
+            {
+                GdipFree(item);
+                item = NULL;
+            }
+        }
+    }
+
+    PropVariantClear(&id);
+    PropVariantClear(&value);
+
+    return item;
+}
+
+static PropertyItem *get_gif_comment(IWICMetadataReader *reader)
+{
+    static const WCHAR textentryW[] = { 'T','e','x','t','E','n','t','r','y',0 };
+    PropertyItem *comment;
+
+    comment = get_property(reader, &GUID_MetadataFormatGifComment, textentryW);
+    if (comment)
+        comment->id = PropertyTagExifUserComment;
+
+    return comment;
+}
+
+static void gif_metadata_reader(GpBitmap *bitmap, IWICBitmapDecoder *decoder, UINT active_frame)
+{
+    HRESULT hr;
+    IWICMetadataBlockReader *block_reader;
+    IWICMetadataReader *reader;
+    UINT block_count, i;
+    PropertyItem *comment = NULL;
+
+    hr = IWICBitmapDecoder_QueryInterface(decoder, &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 (!comment)
+                        comment = get_gif_comment(reader);
+
+                    IWICMetadataReader_Release(reader);
+                }
+            }
+        }
+        IWICMetadataBlockReader_Release(block_reader);
+    }
+
+    if (comment) add_property(bitmap, comment);
+
+    GdipFree(comment);
 }
 
 typedef void (*metadata_reader_func)(GpBitmap *bitmap, IWICBitmapDecoder *decoder, UINT frame);




More information about the wine-cvs mailing list