Vincent Povirk : windowscodecs: Implement png cHRM metadata reader.
Alexandre Julliard
julliard at winehq.org
Thu Jun 16 10:20:55 CDT 2016
Module: wine
Branch: master
Commit: 2e16630a61c1ac581ba2a2ee84f20aa2c7d0f9bd
URL: http://source.winehq.org/git/wine.git/?a=commit;h=2e16630a61c1ac581ba2a2ee84f20aa2c7d0f9bd
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Wed Jun 15 12:43:40 2016 -0500
windowscodecs: Implement png cHRM metadata reader.
Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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)
More information about the wine-cvs
mailing list