From 26628b4c0a5cac045303470124bcd5b5a7eb08f4 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Tue, 11 Sep 2012 16:50:42 +0900 Subject: [PATCH] windowscodecs: Implement Graphic Control Extension metadata reader. --- dlls/windowscodecs/clsfactory.c | 1 + dlls/windowscodecs/gifformat.c | 78 +++++++++++++++++++ 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, 112 insertions(+), 1 deletion(-) diff --git a/dlls/windowscodecs/clsfactory.c b/dlls/windowscodecs/clsfactory.c index dc70c04d970..a42aeab84b8 100644 --- a/dlls/windowscodecs/clsfactory.c +++ b/dlls/windowscodecs/clsfactory.c @@ -64,6 +64,7 @@ static const classinfo wic_classes[] = { {&CLSID_WICPngTextMetadataReader, PngTextReader_CreateInstance}, {&CLSID_WICLSDMetadataReader, LSDReader_CreateInstance}, {&CLSID_WICIMDMetadataReader, IMDReader_CreateInstance}, + {&CLSID_WICGCEMetadataReader, GCEReader_CreateInstance}, {0}}; typedef struct { diff --git a/dlls/windowscodecs/gifformat.c b/dlls/windowscodecs/gifformat.c index f6a7d27f045..318dc5df027 100644 --- a/dlls/windowscodecs/gifformat.c +++ b/dlls/windowscodecs/gifformat.c @@ -240,6 +240,84 @@ HRESULT IMDReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) return MetadataReader_Create(&IMDReader_Vtbl, pUnkOuter, iid, ppv); } +static HRESULT load_GCE_metadata(IStream *stream, const GUID *vendor, DWORD options, + MetadataItem **items, DWORD *count) +{ +#include "pshpack1.h" + struct graphic_control_extenstion + { + BYTE packed; + /* reservred: 3; + * disposal : 3; + * user_input_flag : 1; + * transparency_flag : 1; + */ + USHORT delay; + BYTE transparent_color_index; + } gce_data; +#include "poppack.h" + HRESULT hr; + ULONG bytesread, i; + MetadataItem *result; + + *items = NULL; + *count = 0; + + hr = IStream_Read(stream, &gce_data, sizeof(gce_data), &bytesread); + if (FAILED(hr) || bytesread != sizeof(gce_data)) return S_OK; + + result = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataItem) * 5); + if (!result) return E_OUTOFMEMORY; + + for (i = 0; i < 5; i++) + { + PropVariantInit(&result[i].schema); + PropVariantInit(&result[i].id); + PropVariantInit(&result[i].value); + } + + result[0].id.vt = VT_LPWSTR; + result[0].id.u.pwszVal = strdupAtoW("Disposal"); + result[0].value.vt = VT_UI1; + result[0].value.u.bVal = (gce_data.packed >> 2) & 7; + + result[1].id.vt = VT_LPWSTR; + result[1].id.u.pwszVal = strdupAtoW("UserInputFlag"); + result[1].value.vt = VT_BOOL; + result[1].value.u.boolVal = (gce_data.packed >> 1) & 1; + + result[2].id.vt = VT_LPWSTR; + result[2].id.u.pwszVal = strdupAtoW("TransparencyFlag"); + result[2].value.vt = VT_BOOL; + result[2].value.u.boolVal = gce_data.packed & 1; + + result[3].id.vt = VT_LPWSTR; + result[3].id.u.pwszVal = strdupAtoW("Delay"); + result[3].value.vt = VT_UI2; + result[3].value.u.uiVal = gce_data.delay; + + result[4].id.vt = VT_LPWSTR; + result[4].id.u.pwszVal = strdupAtoW("TransparentColorIndex"); + result[4].value.vt = VT_UI1; + result[4].value.u.bVal = gce_data.transparent_color_index; + + *items = result; + *count = 5; + + return S_OK; +} + +static const MetadataHandlerVtbl GCEReader_Vtbl = { + 0, + &CLSID_WICGCEMetadataReader, + load_GCE_metadata +}; + +HRESULT GCEReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) +{ + return MetadataReader_Create(&GCEReader_Vtbl, pUnkOuter, iid, ppv); +} + typedef struct { IWICBitmapDecoder IWICBitmapDecoder_iface; LONG ref; diff --git a/dlls/windowscodecs/regsvr.c b/dlls/windowscodecs/regsvr.c index c2327783c17..a7ac4b2a44c 100644 --- a/dlls/windowscodecs/regsvr.c +++ b/dlls/windowscodecs/regsvr.c @@ -1547,6 +1547,21 @@ static const struct reader_containers imd_containers[] = { { NULL } /* list terminator */ }; +static const BYTE gce_magic[] = { 0x21, 0xf9, 0x04 }; + +static const struct metadata_pattern gce_metadata_pattern[] = { + { 0, 3, gce_magic, mask_all, 3 }, + { 0 } +}; + +static const struct reader_containers gce_containers[] = { + { + &GUID_ContainerFormatGif, + gce_metadata_pattern + }, + { NULL } /* list terminator */ +}; + static struct regsvr_metadatareader const metadatareader_list[] = { { &CLSID_WICUnknownMetadataReader, "The Wine Project", @@ -1598,6 +1613,16 @@ static struct regsvr_metadatareader const metadatareader_list[] = { 0, 0, 0, imd_containers }, + { &CLSID_WICGCEMetadataReader, + "The Wine Project", + "Graphic Control Extension Reader", + "1.0.0.0", + "1.0.0.0", + &GUID_VendorMicrosoft, + &GUID_MetadataFormatGCE, + 0, 0, 0, + gce_containers + }, { NULL } /* list terminator */ }; diff --git a/dlls/windowscodecs/tests/metadata.c b/dlls/windowscodecs/tests/metadata.c index bfa9116f541..e2741061941 100644 --- a/dlls/windowscodecs/tests/metadata.c +++ b/dlls/windowscodecs/tests/metadata.c @@ -1440,7 +1440,6 @@ static void test_metadata_GCE(void) hr = CoCreateInstance(&CLSID_WICGCEMetadataReader, 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 e26eec04fd2..b712b2f9f29 100644 --- a/dlls/windowscodecs/wincodecs_private.h +++ b/dlls/windowscodecs/wincodecs_private.h @@ -97,5 +97,6 @@ extern HRESULT IfdMetadataReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, extern HRESULT PngTextReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN; extern HRESULT LSDReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN; extern HRESULT IMDReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN; +extern HRESULT GCEReader_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 942cbb7af98..e109bf2b23e 100644 --- a/dlls/windowscodecs/windowscodecs_wincodec.idl +++ b/dlls/windowscodecs/windowscodecs_wincodec.idl @@ -156,3 +156,10 @@ coclass WICLSDMetadataReader { interface IWICMetadataReader; } uuid(7447a267-0015-42c8-a8f1-fb3b94c68361) ] coclass WICIMDMetadataReader { interface IWICMetadataReader; } + +[ + helpstring("WIC GCE Metadata Reader"), + threading(both), + uuid(b92e345d-f52d-41f3-b562-081bc772e3b9) +] +coclass WICGCEMetadataReader { interface IWICMetadataReader; }