Module: wine Branch: master Commit: ec206a843feb489a4a47951a3a1e7f0d7ae439f7 URL: http://source.winehq.org/git/wine.git/?a=commit;h=ec206a843feb489a4a47951a3a...
Author: Dmitry Timoshkov dmitry@baikal.ru Date: Mon Sep 17 10:04:14 2012 +0900
windowscodecs: Implement GIF Comment Extension metadata reader.
---
dlls/windowscodecs/clsfactory.c | 1 + dlls/windowscodecs/gifformat.c | 95 +++++++++++++++++++++++++ dlls/windowscodecs/regsvr.c | 25 +++++++ dlls/windowscodecs/tests/metadata.c | 1 - dlls/windowscodecs/wincodecs_private.h | 1 + dlls/windowscodecs/windowscodecs_wincodec.idl | 7 ++ 6 files changed, 129 insertions(+), 1 deletions(-)
diff --git a/dlls/windowscodecs/clsfactory.c b/dlls/windowscodecs/clsfactory.c index 61ddfd9..a57d673 100644 --- a/dlls/windowscodecs/clsfactory.c +++ b/dlls/windowscodecs/clsfactory.c @@ -66,6 +66,7 @@ static const classinfo wic_classes[] = { {&CLSID_WICIMDMetadataReader, IMDReader_CreateInstance}, {&CLSID_WICGCEMetadataReader, GCEReader_CreateInstance}, {&CLSID_WICAPEMetadataReader, APEReader_CreateInstance}, + {&CLSID_WICGifCommentMetadataReader, GifCommentReader_CreateInstance}, {0}};
typedef struct { diff --git a/dlls/windowscodecs/gifformat.c b/dlls/windowscodecs/gifformat.c index 14d7d01..1dba2bb 100644 --- a/dlls/windowscodecs/gifformat.c +++ b/dlls/windowscodecs/gifformat.c @@ -434,6 +434,101 @@ HRESULT APEReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) return MetadataReader_Create(&APEReader_Vtbl, pUnkOuter, iid, ppv); }
+static HRESULT load_GifComment_metadata(IStream *stream, const GUID *vendor, DWORD options, + MetadataItem **items, DWORD *count) +{ +#include "pshpack1.h" + struct gif_extenstion + { + BYTE extension_introducer; + BYTE extension_label; + } ext_data; +#include "poppack.h" + HRESULT hr; + ULONG bytesread, data_size; + MetadataItem *result; + BYTE subblock_size; + BYTE *data; + + *items = NULL; + *count = 0; + + hr = IStream_Read(stream, &ext_data, sizeof(ext_data), &bytesread); + if (FAILED(hr) || bytesread != sizeof(ext_data)) return S_OK; + if (ext_data.extension_introducer != 0x21 || ext_data.extension_label != 0xfe) + return S_OK; + + data = NULL; + data_size = 0; + + for (;;) + { + hr = IStream_Read(stream, &subblock_size, sizeof(subblock_size), &bytesread); + if (FAILED(hr) || bytesread != sizeof(subblock_size)) + { + HeapFree(GetProcessHeap(), 0, data); + return S_OK; + } + if (!subblock_size) break; + + if (!data) + data = HeapAlloc(GetProcessHeap(), 0, subblock_size); + else + { + BYTE *new_data = HeapReAlloc(GetProcessHeap(), 0, data, data_size + subblock_size); + if (!new_data) + { + HeapFree(GetProcessHeap(), 0, data); + return S_OK; + } + data = new_data; + } + hr = IStream_Read(stream, data + data_size, subblock_size, &bytesread); + if (FAILED(hr) || bytesread != subblock_size) + { + HeapFree(GetProcessHeap(), 0, data); + return S_OK; + } + data_size += subblock_size; + } + + result = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataItem)); + if (!result) + { + HeapFree(GetProcessHeap(), 0, data); + return E_OUTOFMEMORY; + } + + PropVariantInit(&result->schema); + PropVariantInit(&result->id); + PropVariantInit(&result->value); + + result->id.vt = VT_LPWSTR; + result->id.u.pwszVal = strdupAtoW("TextEntry"); + result->value.vt = VT_LPSTR; + result->value.u.pszVal = HeapAlloc(GetProcessHeap(), 0, data_size + 1); + memcpy(result->value.u.pszVal, data, data_size); + result->value.u.pszVal[data_size] = 0; + + HeapFree(GetProcessHeap(), 0, data); + + *items = result; + *count = 1; + + return S_OK; +} + +static const MetadataHandlerVtbl GifCommentReader_Vtbl = { + 0, + &CLSID_WICGifCommentMetadataReader, + load_GifComment_metadata +}; + +HRESULT GifCommentReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) +{ + return MetadataReader_Create(&GifCommentReader_Vtbl, pUnkOuter, iid, ppv); +} + static IStream *create_stream(const void *data, int data_size) { HRESULT hr; diff --git a/dlls/windowscodecs/regsvr.c b/dlls/windowscodecs/regsvr.c index 47e522c..626887f 100644 --- a/dlls/windowscodecs/regsvr.c +++ b/dlls/windowscodecs/regsvr.c @@ -1577,6 +1577,21 @@ static const struct reader_containers ape_containers[] = { { NULL } /* list terminator */ };
+static const BYTE gif_comment_magic[] = { 0x21, 0xfe }; + +static const struct metadata_pattern gif_comment_metadata_pattern[] = { + { 0, 2, gif_comment_magic, mask_all, 0 }, + { 0 } +}; + +static const struct reader_containers gif_comment_containers[] = { + { + &GUID_ContainerFormatGif, + gif_comment_metadata_pattern + }, + { NULL } /* list terminator */ +}; + static struct regsvr_metadatareader const metadatareader_list[] = { { &CLSID_WICUnknownMetadataReader, "The Wine Project", @@ -1648,6 +1663,16 @@ static struct regsvr_metadatareader const metadatareader_list[] = { 0, 0, 0, ape_containers }, + { &CLSID_WICGifCommentMetadataReader, + "The Wine Project", + "Comment Extension Reader", + "1.0.0.0", + "1.0.0.0", + &GUID_VendorMicrosoft, + &GUID_MetadataFormatGifComment, + 0, 0, 0, + gif_comment_containers + }, { NULL } /* list terminator */ };
diff --git a/dlls/windowscodecs/tests/metadata.c b/dlls/windowscodecs/tests/metadata.c index 27a8dcf..ed02e2f 100644 --- a/dlls/windowscodecs/tests/metadata.c +++ b/dlls/windowscodecs/tests/metadata.c @@ -1727,7 +1727,6 @@ static void test_metadata_GIF_comment(void)
hr = CoCreateInstance(&CLSID_WICGifCommentMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void **)&reader); -todo_wine ok(hr == S_OK || broken(hr == E_NOINTERFACE || hr == REGDB_E_CLASSNOTREG) /* before Win7 */, "CoCreateInstance error %#x\n", hr);
diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h index 406a3fa..41d2d80 100644 --- a/dlls/windowscodecs/wincodecs_private.h +++ b/dlls/windowscodecs/wincodecs_private.h @@ -99,5 +99,6 @@ extern HRESULT LSDReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void ** extern HRESULT IMDReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN; extern HRESULT GCEReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN; extern HRESULT APEReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN; +extern HRESULT GifCommentReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN;
#endif /* WINCODECS_PRIVATE_H */ diff --git a/dlls/windowscodecs/windowscodecs_wincodec.idl b/dlls/windowscodecs/windowscodecs_wincodec.idl index 7ca2235..658ced0 100644 --- a/dlls/windowscodecs/windowscodecs_wincodec.idl +++ b/dlls/windowscodecs/windowscodecs_wincodec.idl @@ -170,3 +170,10 @@ coclass WICGCEMetadataReader { interface IWICMetadataReader; } uuid(1767b93a-b021-44ea-920f-863c11f4f768) ] coclass WICAPEMetadataReader { interface IWICMetadataReader; } + +[ + helpstring("WIC Comment Extension Reader"), + threading(both), + uuid(32557d3b-69dc-4f95-836e-f5972b2f6159) +] +coclass WICGifCommentMetadataReader { interface IWICMetadataReader; }