Module: wine Branch: master Commit: 97fc6be67da0c086e8fbe56e409884c5dfb8e49e URL: http://source.winehq.org/git/wine.git/?a=commit;h=97fc6be67da0c086e8fbe56e40...
Author: Dmitry Timoshkov dmitry@baikal.ru Date: Tue Sep 11 16:49:50 2012 +0900
windowscodecs: Implement Image Descriptor metadata reader.
---
dlls/windowscodecs/clsfactory.c | 1 + dlls/windowscodecs/gifformat.c | 94 +++++++++++++++++++++++++ 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, 128 insertions(+), 1 deletions(-)
diff --git a/dlls/windowscodecs/clsfactory.c b/dlls/windowscodecs/clsfactory.c index 3f1328c..dc70c04 100644 --- a/dlls/windowscodecs/clsfactory.c +++ b/dlls/windowscodecs/clsfactory.c @@ -63,6 +63,7 @@ static const classinfo wic_classes[] = { {&CLSID_WICIfdMetadataReader, IfdMetadataReader_CreateInstance}, {&CLSID_WICPngTextMetadataReader, PngTextReader_CreateInstance}, {&CLSID_WICLSDMetadataReader, LSDReader_CreateInstance}, + {&CLSID_WICIMDMetadataReader, IMDReader_CreateInstance}, {0}};
typedef struct { diff --git a/dlls/windowscodecs/gifformat.c b/dlls/windowscodecs/gifformat.c index c4ee566..f6a7d27 100644 --- a/dlls/windowscodecs/gifformat.c +++ b/dlls/windowscodecs/gifformat.c @@ -146,6 +146,100 @@ HRESULT LSDReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) return MetadataReader_Create(&LSDReader_Vtbl, pUnkOuter, iid, ppv); }
+static HRESULT load_IMD_metadata(IStream *stream, const GUID *vendor, DWORD options, + MetadataItem **items, DWORD *count) +{ + struct image_descriptor + { + USHORT left; + USHORT top; + USHORT width; + USHORT height; + BYTE packed; + /* local_color_table_flag : 1; + * interlace_flag : 1; + * sort_flag : 1; + * reserved : 2; + * local_color_table_size : 3; + */ + } imd_data; + HRESULT hr; + ULONG bytesread, i; + MetadataItem *result; + + *items = NULL; + *count = 0; + + hr = IStream_Read(stream, &imd_data, sizeof(imd_data), &bytesread); + if (FAILED(hr) || bytesread != sizeof(imd_data)) return S_OK; + + result = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataItem) * 8); + if (!result) return E_OUTOFMEMORY; + + for (i = 0; i < 8; 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("Left"); + result[0].value.vt = VT_UI2; + result[0].value.u.uiVal = imd_data.left; + + result[1].id.vt = VT_LPWSTR; + result[1].id.u.pwszVal = strdupAtoW("Top"); + result[1].value.vt = VT_UI2; + result[1].value.u.uiVal = imd_data.top; + + result[2].id.vt = VT_LPWSTR; + result[2].id.u.pwszVal = strdupAtoW("Width"); + result[2].value.vt = VT_UI2; + result[2].value.u.uiVal = imd_data.width; + + result[3].id.vt = VT_LPWSTR; + result[3].id.u.pwszVal = strdupAtoW("Height"); + result[3].value.vt = VT_UI2; + result[3].value.u.uiVal = imd_data.height; + + result[4].id.vt = VT_LPWSTR; + result[4].id.u.pwszVal = strdupAtoW("LocalColorTableFlag"); + result[4].value.vt = VT_BOOL; + result[4].value.u.boolVal = (imd_data.packed >> 7) & 1; + + result[5].id.vt = VT_LPWSTR; + result[5].id.u.pwszVal = strdupAtoW("InterlaceFlag"); + result[5].value.vt = VT_BOOL; + result[5].value.u.boolVal = (imd_data.packed >> 6) & 1; + + result[6].id.vt = VT_LPWSTR; + result[6].id.u.pwszVal = strdupAtoW("SortFlag"); + result[6].value.vt = VT_BOOL; + result[6].value.u.boolVal = (imd_data.packed >> 5) & 1; + + result[7].id.vt = VT_LPWSTR; + result[7].id.u.pwszVal = strdupAtoW("LocalColorTableSize"); + result[7].value.vt = VT_UI1; + result[7].value.u.bVal = imd_data.packed & 7; + + *items = result; + *count = 8; + + return S_OK; +} + +static const MetadataHandlerVtbl IMDReader_Vtbl = { + 0, + &CLSID_WICIMDMetadataReader, + load_IMD_metadata +}; + +HRESULT IMDReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) +{ + return MetadataReader_Create(&IMDReader_Vtbl, pUnkOuter, iid, ppv); +} + typedef struct { IWICBitmapDecoder IWICBitmapDecoder_iface; LONG ref; diff --git a/dlls/windowscodecs/regsvr.c b/dlls/windowscodecs/regsvr.c index cb48d63..c232778 100644 --- a/dlls/windowscodecs/regsvr.c +++ b/dlls/windowscodecs/regsvr.c @@ -1532,6 +1532,21 @@ static const struct reader_containers lsd_containers[] = { { NULL } /* list terminator */ };
+static const BYTE imd_magic[] = { 0x2c }; + +static const struct metadata_pattern imd_metadata_pattern[] = { + { 0, 1, imd_magic, mask_all, 1 }, + { 0 } +}; + +static const struct reader_containers imd_containers[] = { + { + &GUID_ContainerFormatGif, + imd_metadata_pattern + }, + { NULL } /* list terminator */ +}; + static struct regsvr_metadatareader const metadatareader_list[] = { { &CLSID_WICUnknownMetadataReader, "The Wine Project", @@ -1573,6 +1588,16 @@ static struct regsvr_metadatareader const metadatareader_list[] = { 0, 0, 0, lsd_containers }, + { &CLSID_WICIMDMetadataReader, + "The Wine Project", + "Image Descriptor Reader", + "1.0.0.0", + "1.0.0.0", + &GUID_VendorMicrosoft, + &GUID_MetadataFormatIMD, + 0, 0, 0, + imd_containers + }, { NULL } /* list terminator */ };
diff --git a/dlls/windowscodecs/tests/metadata.c b/dlls/windowscodecs/tests/metadata.c index fd81e6f..bfa9116 100644 --- a/dlls/windowscodecs/tests/metadata.c +++ b/dlls/windowscodecs/tests/metadata.c @@ -1365,7 +1365,6 @@ static void test_metadata_IMD(void)
hr = CoCreateInstance(&CLSID_WICIMDMetadataReader, 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 908b2e6..e26eec0 100644 --- a/dlls/windowscodecs/wincodecs_private.h +++ b/dlls/windowscodecs/wincodecs_private.h @@ -96,5 +96,6 @@ extern HRESULT UnknownMetadataReader_CreateInstance(IUnknown *pUnkOuter, REFIID extern HRESULT IfdMetadataReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv) DECLSPEC_HIDDEN; 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;
#endif /* WINCODECS_PRIVATE_H */ diff --git a/dlls/windowscodecs/windowscodecs_wincodec.idl b/dlls/windowscodecs/windowscodecs_wincodec.idl index d360ae5..942cbb7 100644 --- a/dlls/windowscodecs/windowscodecs_wincodec.idl +++ b/dlls/windowscodecs/windowscodecs_wincodec.idl @@ -149,3 +149,10 @@ coclass WICPngTextMetadataReader { interface IWICMetadataReader; } uuid(41070793-59e4-479a-a1f7-954adc2ef5fc) ] coclass WICLSDMetadataReader { interface IWICMetadataReader; } + +[ + helpstring("WIC IMD Metadata Reader"), + threading(both), + uuid(7447a267-0015-42c8-a8f1-fb3b94c68361) +] +coclass WICIMDMetadataReader { interface IWICMetadataReader; }