Module: wine Branch: master Commit: 3b51859871513262770562bfd5d5f5447b20c7a1 URL: http://source.winehq.org/git/wine.git/?a=commit;h=3b51859871513262770562bfd5...
Author: Vincent Povirk vincent@codeweavers.com Date: Wed Mar 25 16:34:35 2015 -0500
gdiplus: Add support for reading PNG tEXt metadata.
---
dlls/gdiplus/image.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-)
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c index 77b9305..de03096 100644 --- a/dlls/gdiplus/image.c +++ b/dlls/gdiplus/image.c @@ -3417,6 +3417,101 @@ static void gif_metadata_reader(GpBitmap *bitmap, IWICBitmapDecoder *decoder, UI IWICBitmapFrameDecode_Release(frame); }
+static PropertyItem* create_prop(PROPID propid, PROPVARIANT* value) +{ + PropertyItem *item = NULL; + 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, propid) != Ok) + { + GdipFree(item); + item = NULL; + } + } + + return item; +} + +static void png_metadata_reader(GpBitmap *bitmap, IWICBitmapDecoder *decoder, UINT active_frame) +{ + HRESULT hr; + IWICBitmapFrameDecode *frame; + IWICMetadataBlockReader *block_reader; + IWICMetadataReader *reader; + UINT block_count, i, j; + struct keyword_info { + const char* name; + PROPID propid; + BOOL seen; + } keywords[] = { + { "Title", PropertyTagImageTitle }, + { "Author", PropertyTagArtist }, + { "Description", PropertyTagImageDescription }, + { "Copyright", PropertyTagCopyright }, + { "Software", PropertyTagSoftwareUsed }, + { "Source", PropertyTagEquipModel }, + { "Comment", PropertyTagExifUserComment }, + }; + + hr = IWICBitmapDecoder_GetFrame(decoder, active_frame, &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) + { + GUID format; + + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + if (SUCCEEDED(hr) && IsEqualGUID(&GUID_MetadataFormatChunktEXt, &format)) + { + PROPVARIANT name, value; + PropertyItem* item; + + hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, &name, &value); + + if (SUCCEEDED(hr)) + { + if (name.vt == VT_LPSTR) + { + for (j=0; j<sizeof(keywords)/sizeof(keywords[0]); j++) + if (!strcmp(keywords[j].name, name.u.pszVal)) + break; + if (j < sizeof(keywords)/sizeof(keywords[0]) && !keywords[j].seen) + { + keywords[j].seen = TRUE; + item = create_prop(keywords[j].propid, &value); + if (item) + add_property(bitmap, item); + } + } + + PropVariantClear(&name); + PropVariantClear(&value); + } + } + + IWICMetadataReader_Release(reader); + } + } + } + IWICMetadataBlockReader_Release(block_reader); + } + + IWICBitmapFrameDecode_Release(frame); +} + static GpStatus initialize_decoder_wic(IStream *stream, REFGUID container, IWICBitmapDecoder **decoder) { IWICImagingFactory *factory; @@ -3805,7 +3900,7 @@ static GpStatus decode_image_jpeg(IStream* stream, GpImage **image)
static GpStatus decode_image_png(IStream* stream, GpImage **image) { - return decode_image_wic(stream, &GUID_ContainerFormatPng, NULL, image); + return decode_image_wic(stream, &GUID_ContainerFormatPng, png_metadata_reader, image); }
static GpStatus decode_image_gif(IStream* stream, GpImage **image)