Module: wine Branch: master Commit: 2e16630a61c1ac581ba2a2ee84f20aa2c7d0f9bd URL: http://source.winehq.org/git/wine.git/?a=commit;h=2e16630a61c1ac581ba2a2ee84...
Author: Vincent Povirk vincent@codeweavers.com Date: Wed Jun 15 12:43:40 2016 -0500
windowscodecs: Implement png cHRM metadata reader.
Signed-off-by: Vincent Povirk vincent@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/windowscodecs/clsfactory.c | 1 + dlls/windowscodecs/pngformat.c | 78 +++++++++++++++++++++++++++ dlls/windowscodecs/regsvr.c | 25 +++++++++ dlls/windowscodecs/tests/metadata.c | 2 +- dlls/windowscodecs/wincodecs_private.h | 1 + dlls/windowscodecs/windowscodecs_wincodec.idl | 7 +++ 6 files changed, 113 insertions(+), 1 deletion(-)
diff --git a/dlls/windowscodecs/clsfactory.c b/dlls/windowscodecs/clsfactory.c index d4c524a..77eeedc 100644 --- a/dlls/windowscodecs/clsfactory.c +++ b/dlls/windowscodecs/clsfactory.c @@ -59,6 +59,7 @@ static const classinfo wic_classes[] = { {&CLSID_WineTgaDecoder, TgaDecoder_CreateInstance}, {&CLSID_WICUnknownMetadataReader, UnknownMetadataReader_CreateInstance}, {&CLSID_WICIfdMetadataReader, IfdMetadataReader_CreateInstance}, + {&CLSID_WICPngChrmMetadataReader, PngChrmReader_CreateInstance}, {&CLSID_WICPngGamaMetadataReader, PngGamaReader_CreateInstance}, {&CLSID_WICPngTextMetadataReader, PngTextReader_CreateInstance}, {&CLSID_WICLSDMetadataReader, LSDReader_CreateInstance}, diff --git a/dlls/windowscodecs/pngformat.c b/dlls/windowscodecs/pngformat.c index 3eb4d0e..bb2aef9 100644 --- a/dlls/windowscodecs/pngformat.c +++ b/dlls/windowscodecs/pngformat.c @@ -220,6 +220,84 @@ HRESULT PngGamaReader_CreateInstance(REFIID iid, void** ppv) return MetadataReader_Create(&GamaReader_Vtbl, iid, ppv); }
+static HRESULT LoadChrmMetadata(IStream *stream, const GUID *preferred_vendor, + DWORD persist_options, MetadataItem **items, DWORD *item_count) +{ + HRESULT hr; + BYTE type[4]; + BYTE *data; + ULONG data_size; + static const WCHAR names[8][12] = { + {'W','h','i','t','e','P','o','i','n','t','X',0}, + {'W','h','i','t','e','P','o','i','n','t','Y',0}, + {'R','e','d','X',0}, + {'R','e','d','Y',0}, + {'G','r','e','e','n','X',0}, + {'G','r','e','e','n','Y',0}, + {'B','l','u','e','X',0}, + {'B','l','u','e','Y',0}, + }; + LPWSTR dyn_names[8] = {0}; + MetadataItem *result; + int i; + + hr = read_png_chunk(stream, type, &data, &data_size); + if (FAILED(hr)) return hr; + + if (data_size < 32) + { + HeapFree(GetProcessHeap(), 0, data); + return E_FAIL; + } + + result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem)*8); + for (i=0; i<8; i++) + { + dyn_names[i] = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(lstrlenW(names[i])+1)); + if (!dyn_names[i]) break; + } + if (!result || i < 8) + { + HeapFree(GetProcessHeap(), 0, result); + for (i=0; i<8; i++) + HeapFree(GetProcessHeap(), 0, dyn_names[i]); + HeapFree(GetProcessHeap(), 0, data); + return E_OUTOFMEMORY; + } + + for (i=0; i<8; i++) + { + PropVariantInit(&result[i].schema); + + PropVariantInit(&result[i].id); + result[i].id.vt = VT_LPWSTR; + result[i].id.u.pwszVal = dyn_names[i]; + lstrcpyW(dyn_names[i], names[i]); + + PropVariantInit(&result[i].value); + result[i].value.vt = VT_UI4; + result[i].value.u.ulVal = read_ulong_be(&data[i*4]); + } + + *items = result; + *item_count = 8; + + HeapFree(GetProcessHeap(), 0, data); + + return S_OK; +} + +static const MetadataHandlerVtbl ChrmReader_Vtbl = { + 0, + &CLSID_WICPngChrmMetadataReader, + LoadChrmMetadata +}; + +HRESULT PngChrmReader_CreateInstance(REFIID iid, void** ppv) +{ + return MetadataReader_Create(&ChrmReader_Vtbl, iid, ppv); +} + #ifdef SONAME_LIBPNG
static void *libpng_handle; diff --git a/dlls/windowscodecs/regsvr.c b/dlls/windowscodecs/regsvr.c index 9c4062e..ff499e5 100644 --- a/dlls/windowscodecs/regsvr.c +++ b/dlls/windowscodecs/regsvr.c @@ -1515,6 +1515,21 @@ static const struct reader_containers pnggama_containers[] = { { NULL } /* list terminator */ };
+static const BYTE cHRM[] = "cHRM"; + +static const struct metadata_pattern pngchrm_metadata_pattern[] = { + { 4, 4, cHRM, mask_all, 4 }, + { 0 } +}; + +static const struct reader_containers pngchrm_containers[] = { + { + &GUID_ContainerFormatPng, + pngchrm_metadata_pattern + }, + { NULL } /* list terminator */ +}; + static const struct metadata_pattern lsd_metadata_patterns[] = { { 0, 6, gif87a_magic, mask_all, 0 }, { 0, 6, gif89a_magic, mask_all, 0 }, @@ -1610,6 +1625,16 @@ static struct regsvr_metadatareader const metadatareader_list[] = { 1, 1, 0, ifd_containers }, + { &CLSID_WICPngChrmMetadataReader, + "The Wine Project", + "Chunk cHRM Reader", + "1.0.0.0", + "1.0.0.0", + &GUID_VendorMicrosoft, + &GUID_MetadataFormatChunkcHRM, + 0, 0, 0, + pngchrm_containers + }, { &CLSID_WICPngGamaMetadataReader, "The Wine Project", "Chunk gAMA Reader", diff --git a/dlls/windowscodecs/tests/metadata.c b/dlls/windowscodecs/tests/metadata.c index c44cf9f..3912209 100644 --- a/dlls/windowscodecs/tests/metadata.c +++ b/dlls/windowscodecs/tests/metadata.c @@ -495,7 +495,7 @@ static void test_metadata_cHRM(void)
hr = CoCreateInstance(&CLSID_WICPngChrmMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void**)&reader); - todo_wine ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /*winxp*/, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /*winxp*/, "CoCreateInstance failed, hr=%x\n", hr); if (FAILED(hr)) return;
load_stream((IUnknown*)reader, metadata_cHRM, sizeof(metadata_cHRM), WICPersistOptionsDefault); diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h index f54403c..a8af0d6 100644 --- a/dlls/windowscodecs/wincodecs_private.h +++ b/dlls/windowscodecs/wincodecs_private.h @@ -154,6 +154,7 @@ extern HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, REFIID i
extern HRESULT UnknownMetadataReader_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; extern HRESULT IfdMetadataReader_CreateInstance(REFIID iid, void **ppv) DECLSPEC_HIDDEN; +extern HRESULT PngChrmReader_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; extern HRESULT PngGamaReader_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; extern HRESULT PngTextReader_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; extern HRESULT LSDReader_CreateInstance(REFIID iid, void **ppv) DECLSPEC_HIDDEN; diff --git a/dlls/windowscodecs/windowscodecs_wincodec.idl b/dlls/windowscodecs/windowscodecs_wincodec.idl index 089bb39..fd7ff01 100644 --- a/dlls/windowscodecs/windowscodecs_wincodec.idl +++ b/dlls/windowscodecs/windowscodecs_wincodec.idl @@ -140,6 +140,13 @@ coclass WICUnknownMetadataReader { interface IWICMetadataReader; } coclass WICIfdMetadataReader { interface IWICIfdMetadataReader; }
[ + helpstring("WIC Png cHRM Metadata Reader"), + threading(both), + uuid(f90b5f36-367b-402a-9dd1-bc0fd59d8f62) +] +coclass WICPngChrmMetadataReader { interface IWICMetadataReader; } + +[ helpstring("WIC Png gAMA Metadata Reader"), threading(both), uuid(3692ca39-e082-4350-9e1f-3704cb083cd5)