From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/windowscodecs/tests/info.c | 54 ++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 5 deletions(-)
diff --git a/dlls/windowscodecs/tests/info.c b/dlls/windowscodecs/tests/info.c index 9f184a8953b..cefd56e2bb4 100644 --- a/dlls/windowscodecs/tests/info.c +++ b/dlls/windowscodecs/tests/info.c @@ -493,9 +493,34 @@ static DWORD WINAPI cache_across_threads_test(void *arg)
static void test_reader_info(void) { + static const GUID *classes[] = + { + &CLSID_WICUnknownMetadataReader, + &CLSID_WICLSDMetadataReader, + &CLSID_WICIMDMetadataReader, + &CLSID_WICAPEMetadataReader, + &CLSID_WICGifCommentMetadataReader, + &CLSID_WICPngTextMetadataReader, + &CLSID_WICPngGamaMetadataReader, + &CLSID_WICPngChrmMetadataReader, + &CLSID_WICPngHistMetadataReader, + &CLSID_WICPngTimeMetadataReader, + &CLSID_WICIfdMetadataReader, + &CLSID_WICGpsMetadataReader, + &CLSID_WICExifMetadataReader, + &CLSID_WICApp1MetadataReader, + + &CLSID_WICUnknownMetadataWriter, + &CLSID_WICIfdMetadataWriter, + &CLSID_WICGpsMetadataWriter, + &CLSID_WICExifMetadataWriter, + &CLSID_WICApp1MetadataWriter, + }; + IWICMetadataHandlerInfo *handler_info; IWICImagingFactory *factory; IWICComponentInfo *info, *info2; IWICMetadataReaderInfo *reader_info; + IWICMetadataReader *reader; HRESULT hr; CLSID clsid; GUID container_formats[10]; @@ -504,14 +529,33 @@ static void test_reader_info(void) HANDLE thread; WICMetadataPattern *patterns;
- hr = get_component_info(&CLSID_WICUnknownMetadataReader, &info2); - ok(hr == S_OK, "CreateComponentInfo failed, hr=%lx\n", hr); - IWICComponentInfo_Release(info2); - hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); - if (FAILED(hr)) return; + + for (int i = 0; i < ARRAY_SIZE(classes); ++i) + { + hr = IWICImagingFactory_CreateComponentInfo(factory, classes[i], &info); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IWICComponentInfo_Release(info); + + hr = CoCreateInstance(classes[i], NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataReader, (void **)&reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &handler_info); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICMetadataHandlerInfo_GetCLSID(handler_info, &clsid); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&clsid, classes[i]), "Unexpected clsid %s.\n", wine_dbgstr_guid(&clsid)); + IWICMetadataHandlerInfo_Release(handler_info); + + IWICMetadataReader_Release(reader); + } + + hr = get_component_info(&CLSID_WICUnknownMetadataReader, &info2); + ok(hr == S_OK, "CreateComponentInfo failed, hr=%lx\n", hr); + IWICComponentInfo_Release(info2);
hr = IWICImagingFactory_CreateComponentInfo(factory, &CLSID_WICUnknownMetadataReader, &info); ok(hr == S_OK, "CreateComponentInfo failed, hr=%lx\n", hr);
From: Nikolay Sivov nsivov@codeweavers.com
A few of GetMetadataHandlerInfo() are removed as they are giving a wrong idea of what's happening. This method does fail unless handler info was already returned once and is cached.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/windowscodecs/tests/metadata.c | 98 ++++++++++++++++++----------- 1 file changed, 63 insertions(+), 35 deletions(-)
diff --git a/dlls/windowscodecs/tests/metadata.c b/dlls/windowscodecs/tests/metadata.c index 52ce2066f3b..602d2406be1 100644 --- a/dlls/windowscodecs/tests/metadata.c +++ b/dlls/windowscodecs/tests/metadata.c @@ -113,6 +113,57 @@ static void check_persist_classid_(unsigned int line, void *iface_ptr, const CLS IWICPersistStream_Release(persist_stream); }
+static IStream *create_stream(const char *data, int data_size) +{ + HRESULT hr; + IStream *stream; + HGLOBAL hdata; + void *locked_data; + + hdata = GlobalAlloc(GMEM_MOVEABLE, data_size); + ok(hdata != 0, "GlobalAlloc failed\n"); + if (!hdata) return NULL; + + locked_data = GlobalLock(hdata); + memcpy(locked_data, data, data_size); + GlobalUnlock(hdata); + + hr = CreateStreamOnHGlobal(hdata, TRUE, &stream); + ok(hr == S_OK, "CreateStreamOnHGlobal failed, hr=%lx\n", hr); + + return stream; +} + +#define check_create_from_container(a, b, c, d) check_create_from_container_(__LINE__, a, b, c, d) +static void check_create_from_container_(unsigned int line, const GUID *container, const GUID *format, + const void *data, size_t size) +{ + IWICComponentFactory *factory; + IWICMetadataReader *reader; + IStream *stream; + HRESULT hr; + GUID guid; + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICComponentFactory, (void **)&factory); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + stream = create_stream(data, size); + ok_(__FILE__, line)(!!stream, "Failed to create a stream.\n"); + + hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, + &GUID_ContainerFormatPng, NULL, WICMetadataCreationFailUnknown, stream, &reader); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IWICMetadataReader_GetMetadataFormat(reader, &guid); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok_(__FILE__, line)(IsEqualGUID(&guid, format), "Unexpected format %s.\n", wine_dbgstr_guid(&guid)); + + IStream_Release(stream); + IWICMetadataReader_Release(reader); + IWICComponentFactory_Release(factory); +} + static HRESULT create_query_reader_from_metadata_reader(IWICComponentFactory *factory, IWICMetadataReader *metadata_reader, const GUID *container_format, IWICMetadataQueryReader **query_reader);
@@ -451,27 +502,6 @@ static ULONG get_refcount(void *iface) return IUnknown_Release(unknown); }
-static IStream *create_stream(const char *data, int data_size) -{ - HRESULT hr; - IStream *stream; - HGLOBAL hdata; - void *locked_data; - - hdata = GlobalAlloc(GMEM_MOVEABLE, data_size); - ok(hdata != 0, "GlobalAlloc failed\n"); - if (!hdata) return NULL; - - locked_data = GlobalLock(hdata); - memcpy(locked_data, data, data_size); - GlobalUnlock(hdata); - - hr = CreateStreamOnHGlobal(hdata, TRUE, &stream); - ok(hr == S_OK, "CreateStreamOnHGlobal failed, hr=%lx\n", hr); - - return stream; -} - static void load_stream(void *iface_ptr, const char *data, int data_size, DWORD persist_options) { IWICStreamProvider *stream_provider; @@ -964,7 +994,6 @@ static void test_metadata_unknown(void)
static void test_metadata_tEXt(void) { - IWICMetadataHandlerInfo *info; HRESULT hr; IWICMetadataReader *reader; IWICEnumMetadataItem *enumerator; @@ -989,6 +1018,8 @@ static void test_metadata_tEXt(void) check_interface(reader, &IID_IWICPersistStream, TRUE); check_interface(reader, &IID_IWICStreamProvider, TRUE); check_persist_classid(reader, &CLSID_WICPngTextMetadataReader); + check_create_from_container(&GUID_ContainerFormatPng, &GUID_MetadataFormatChunktEXt, + &metadata_tEXt, sizeof(metadata_tEXt));
hr = IWICMetadataReader_GetCount(reader, NULL); ok(hr == E_INVALIDARG, "GetCount failed, hr=%lx\n", hr); @@ -999,12 +1030,6 @@ static void test_metadata_tEXt(void)
load_stream(reader, metadata_tEXt, sizeof(metadata_tEXt), WICPersistOptionDefault);
- hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); - todo_wine - ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "Unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) - IWICMetadataHandlerInfo_Release(info); - hr = IWICMetadataReader_GetCount(reader, &count); ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %i\n", count); @@ -1138,7 +1163,6 @@ static void test_metadata_tEXt(void)
static void test_metadata_gAMA(void) { - IWICMetadataHandlerInfo *info; HRESULT hr; IWICMetadataReader *reader; PROPVARIANT schema, id, value; @@ -1161,6 +1185,8 @@ static void test_metadata_gAMA(void) check_interface(reader, &IID_IWICPersistStream, TRUE); check_interface(reader, &IID_IWICStreamProvider, TRUE); check_persist_classid(reader, &CLSID_WICPngGamaMetadataReader); + check_create_from_container(&GUID_ContainerFormatPng, &GUID_MetadataFormatChunkgAMA, + &metadata_gAMA, sizeof(metadata_gAMA));
hr = IWICMetadataReader_GetCount(reader, &count); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -1185,12 +1211,6 @@ static void test_metadata_gAMA(void)
load_stream(reader, metadata_gAMA, sizeof(metadata_gAMA), WICPersistOptionDefault);
- hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); - todo_wine - ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "Unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) - IWICMetadataHandlerInfo_Release(info); - hr = IWICMetadataReader_GetMetadataFormat(reader, &format); ok(hr == S_OK, "GetMetadataFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatChunkgAMA), "unexpected format %s\n", wine_dbgstr_guid(&format)); @@ -1318,6 +1338,8 @@ static void test_metadata_cHRM(void) check_interface(reader, &IID_IWICPersistStream, TRUE); check_interface(reader, &IID_IWICStreamProvider, TRUE); check_persist_classid(reader, &CLSID_WICPngChrmMetadataReader); + check_create_from_container(&GUID_ContainerFormatPng, &GUID_MetadataFormatChunkcHRM, + &metadata_cHRM, sizeof(metadata_cHRM));
hr = IWICMetadataReader_GetCount(reader, &count); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -1475,6 +1497,8 @@ static void test_metadata_hIST(void) check_interface(reader, &IID_IWICPersistStream, TRUE); check_interface(reader, &IID_IWICStreamProvider, TRUE); check_persist_classid(reader, &CLSID_WICPngHistMetadataReader); + check_create_from_container(&GUID_ContainerFormatPng, &GUID_MetadataFormatChunkhIST, + &metadata_hIST, sizeof(metadata_hIST));
hr = IWICMetadataReader_GetCount(reader, &count); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -1602,6 +1626,8 @@ static void test_metadata_tIME(void) check_interface(reader, &IID_IWICPersistStream, TRUE); check_interface(reader, &IID_IWICStreamProvider, TRUE); check_persist_classid(reader, &CLSID_WICPngTimeMetadataReader); + check_create_from_container(&GUID_ContainerFormatPng, &GUID_MetadataFormatChunktIME, + &metadata_tIME, sizeof(metadata_tIME));
hr = IWICMetadataReader_GetCount(reader, &count); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -1773,6 +1799,8 @@ static void test_metadata_bKGD(void) check_interface(reader, &IID_IWICPersistStream, TRUE); check_interface(reader, &IID_IWICStreamProvider, TRUE); check_persist_classid(reader, &CLSID_WICPngBkgdMetadataReader); + check_create_from_container(&GUID_ContainerFormatPng, &GUID_MetadataFormatChunkbKGD, + &metadata_bKGD_palette, sizeof(metadata_bKGD_palette));
hr = IWICMetadataReader_GetCount(reader, &count); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/windowscodecs/tests/info.c | 110 ++++++++++++++++++++++++-------- 1 file changed, 83 insertions(+), 27 deletions(-)
diff --git a/dlls/windowscodecs/tests/info.c b/dlls/windowscodecs/tests/info.c index cefd56e2bb4..29a2d87e9ce 100644 --- a/dlls/windowscodecs/tests/info.c +++ b/dlls/windowscodecs/tests/info.c @@ -28,6 +28,49 @@ #include "wincodecsdk.h" #include "wine/test.h"
+static const GUID *metadata_handlers[] = +{ + &CLSID_WICUnknownMetadataReader, + &CLSID_WICLSDMetadataReader, + &CLSID_WICIMDMetadataReader, + &CLSID_WICAPEMetadataReader, + &CLSID_WICGifCommentMetadataReader, + &CLSID_WICPngTextMetadataReader, + &CLSID_WICPngGamaMetadataReader, + &CLSID_WICPngChrmMetadataReader, + &CLSID_WICPngHistMetadataReader, + &CLSID_WICPngTimeMetadataReader, + &CLSID_WICIfdMetadataReader, + &CLSID_WICGpsMetadataReader, + &CLSID_WICExifMetadataReader, + &CLSID_WICApp1MetadataReader, + + &CLSID_WICUnknownMetadataWriter, + &CLSID_WICIfdMetadataWriter, + &CLSID_WICGpsMetadataWriter, + &CLSID_WICExifMetadataWriter, + &CLSID_WICApp1MetadataWriter, +}; + +static void run_child_test(const char *name) +{ + char path_name[MAX_PATH]; + PROCESS_INFORMATION info; + STARTUPINFOA startup; + char **argv; + + winetest_get_mainargs(&argv); + + memset(&startup, 0, sizeof(startup)); + startup.cb = sizeof(startup); + sprintf(path_name, "%s info %s", argv[0], name); + ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info), + "CreateProcess failed.\n" ); + wait_child_process(info.hProcess); + CloseHandle(info.hProcess); + CloseHandle(info.hThread); +} + static HRESULT get_component_info(const GUID *clsid, IWICComponentInfo **result) { IWICImagingFactory *factory; @@ -493,29 +536,6 @@ static DWORD WINAPI cache_across_threads_test(void *arg)
static void test_reader_info(void) { - static const GUID *classes[] = - { - &CLSID_WICUnknownMetadataReader, - &CLSID_WICLSDMetadataReader, - &CLSID_WICIMDMetadataReader, - &CLSID_WICAPEMetadataReader, - &CLSID_WICGifCommentMetadataReader, - &CLSID_WICPngTextMetadataReader, - &CLSID_WICPngGamaMetadataReader, - &CLSID_WICPngChrmMetadataReader, - &CLSID_WICPngHistMetadataReader, - &CLSID_WICPngTimeMetadataReader, - &CLSID_WICIfdMetadataReader, - &CLSID_WICGpsMetadataReader, - &CLSID_WICExifMetadataReader, - &CLSID_WICApp1MetadataReader, - - &CLSID_WICUnknownMetadataWriter, - &CLSID_WICIfdMetadataWriter, - &CLSID_WICGpsMetadataWriter, - &CLSID_WICExifMetadataWriter, - &CLSID_WICApp1MetadataWriter, - }; IWICMetadataHandlerInfo *handler_info; IWICImagingFactory *factory; IWICComponentInfo *info, *info2; @@ -533,13 +553,13 @@ static void test_reader_info(void) &IID_IWICImagingFactory, (void**)&factory); ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr);
- for (int i = 0; i < ARRAY_SIZE(classes); ++i) + for (int i = 0; i < ARRAY_SIZE(metadata_handlers); ++i) { - hr = IWICImagingFactory_CreateComponentInfo(factory, classes[i], &info); + hr = IWICImagingFactory_CreateComponentInfo(factory, metadata_handlers[i], &info); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); IWICComponentInfo_Release(info);
- hr = CoCreateInstance(classes[i], NULL, CLSCTX_INPROC_SERVER, + hr = CoCreateInstance(metadata_handlers[i], NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void **)&reader); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
@@ -547,7 +567,7 @@ static void test_reader_info(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IWICMetadataHandlerInfo_GetCLSID(handler_info, &clsid); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - ok(IsEqualGUID(&clsid, classes[i]), "Unexpected clsid %s.\n", wine_dbgstr_guid(&clsid)); + ok(IsEqualGUID(&clsid, metadata_handlers[i]), "Unexpected clsid %s.\n", wine_dbgstr_guid(&clsid)); IWICMetadataHandlerInfo_Release(handler_info);
IWICMetadataReader_Release(reader); @@ -755,10 +775,46 @@ static void test_component_enumerator(void) IWICImagingFactory_Release(factory); }
+static void test_handler_info_cold_cache(void) +{ + IWICMetadataHandlerInfo *info; + IWICMetadataReader *reader; + HRESULT hr; + + for (int i = 0; i < ARRAY_SIZE(metadata_handlers); ++i) + { + hr = CoCreateInstance(metadata_handlers[i], NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataReader, (void **)&reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); + todo_wine + ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + IWICMetadataHandlerInfo_Release(info); + + IWICMetadataReader_Release(reader); + } +} + START_TEST(info) { + char **argv; + int argc; + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+ argc = winetest_get_mainargs(&argv); + if (argc >= 3) + { + if (!strcmp(argv[2], "get_handler_info_cold_cache")) + test_handler_info_cold_cache(); + + CoUninitialize(); + return; + } + + run_child_test("get_handler_info_cold_cache"); test_decoder_info(); test_reader_info(); test_pixelformat_info();
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/windowscodecs/wincodecs_private.h | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h index 48de3971e15..89ada4e024c 100644 --- a/dlls/windowscodecs/wincodecs_private.h +++ b/dlls/windowscodecs/wincodecs_private.h @@ -211,10 +211,6 @@ typedef struct _MetadataHandlerVtbl const CLSID *clsid; HRESULT (*fnLoad)(IStream *stream, const GUID *preferred_vendor, DWORD persist_options, MetadataItem **items, DWORD *item_count); - HRESULT (*fnSave)(IStream *stream, DWORD persist_options, - const MetadataItem *items, DWORD item_count); - HRESULT (*fnGetSizeMax)(const MetadataItem *items, DWORD item_count, - ULARGE_INTEGER *size); } MetadataHandlerVtbl;
extern HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, REFIID iid, void** ppv);
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/windowscodecs/gifformat.c | 55 +++++------- dlls/windowscodecs/metadatahandler.c | 112 ++++++++++--------------- dlls/windowscodecs/pngformat.c | 45 +++++----- dlls/windowscodecs/wincodecs_private.h | 22 ++++- 4 files changed, 111 insertions(+), 123 deletions(-)
diff --git a/dlls/windowscodecs/gifformat.c b/dlls/windowscodecs/gifformat.c index 25403955284..d3d8678e9f8 100644 --- a/dlls/windowscodecs/gifformat.c +++ b/dlls/windowscodecs/gifformat.c @@ -78,17 +78,13 @@ struct image_descriptor
#include "poppack.h"
-static HRESULT load_LSD_metadata(IStream *stream, const GUID *vendor, DWORD options, - MetadataItem **items, DWORD *count) +static HRESULT load_LSD_metadata(MetadataHandler *handler, IStream *stream, const GUID *vendor, DWORD options) { struct logical_screen_descriptor lsd_data; HRESULT hr; ULONG bytesread, i; MetadataItem *result;
- *items = NULL; - *count = 0; - hr = IStream_Read(stream, &lsd_data, sizeof(lsd_data), &bytesread); if (FAILED(hr) || bytesread != sizeof(lsd_data)) return S_OK;
@@ -149,8 +145,9 @@ static HRESULT load_LSD_metadata(IStream *stream, const GUID *vendor, DWORD opti result[8].value.vt = VT_UI1; result[8].value.bVal = lsd_data.pixel_aspect_ratio;
- *items = result; - *count = 9; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 9;
return S_OK; } @@ -166,17 +163,13 @@ HRESULT LSDReader_CreateInstance(REFIID iid, void **ppv) return MetadataReader_Create(&LSDReader_Vtbl, iid, ppv); }
-static HRESULT load_IMD_metadata(IStream *stream, const GUID *vendor, DWORD options, - MetadataItem **items, DWORD *count) +static HRESULT load_IMD_metadata(MetadataHandler *handler, IStream *stream, const GUID *vendor, DWORD options) { struct image_descriptor 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;
@@ -230,8 +223,9 @@ static HRESULT load_IMD_metadata(IStream *stream, const GUID *vendor, DWORD opti result[7].value.vt = VT_UI1; result[7].value.bVal = imd_data.packed & 7;
- *items = result; - *count = 8; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 8;
return S_OK; } @@ -247,8 +241,7 @@ HRESULT IMDReader_CreateInstance(REFIID iid, void **ppv) return MetadataReader_Create(&IMDReader_Vtbl, iid, ppv); }
-static HRESULT load_GCE_metadata(IStream *stream, const GUID *vendor, DWORD options, - MetadataItem **items, DWORD *count) +static HRESULT load_GCE_metadata(MetadataHandler *handler, IStream *stream, const GUID *vendor, DWORD options) { #include "pshpack1.h" struct graphic_control_extension @@ -267,9 +260,6 @@ static HRESULT load_GCE_metadata(IStream *stream, const GUID *vendor, DWORD opti 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;
@@ -308,8 +298,9 @@ static HRESULT load_GCE_metadata(IStream *stream, const GUID *vendor, DWORD opti result[4].value.vt = VT_UI1; result[4].value.bVal = gce_data.transparent_color_index;
- *items = result; - *count = 5; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 5;
return S_OK; } @@ -325,8 +316,7 @@ HRESULT GCEReader_CreateInstance(REFIID iid, void **ppv) return MetadataReader_Create(&GCEReader_Vtbl, iid, ppv); }
-static HRESULT load_APE_metadata(IStream *stream, const GUID *vendor, DWORD options, - MetadataItem **items, DWORD *count) +static HRESULT load_APE_metadata(MetadataHandler *handler, IStream *stream, const GUID *vendor, DWORD options) { #include "pshpack1.h" struct application_extension @@ -343,9 +333,6 @@ static HRESULT load_APE_metadata(IStream *stream, const GUID *vendor, DWORD opti BYTE subblock_size; BYTE *data;
- *items = NULL; - *count = 0; - hr = IStream_Read(stream, &ape_data, sizeof(ape_data), &bytesread); if (FAILED(hr) || bytesread != sizeof(ape_data)) return S_OK; if (ape_data.extension_introducer != 0x21 || @@ -415,8 +402,9 @@ static HRESULT load_APE_metadata(IStream *stream, const GUID *vendor, DWORD opti result[1].value.caub.cElems = data_size; result[1].value.caub.pElems = data;
- *items = result; - *count = 2; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 2;
return S_OK; } @@ -432,8 +420,7 @@ HRESULT APEReader_CreateInstance(REFIID iid, void **ppv) return MetadataReader_Create(&APEReader_Vtbl, iid, ppv); }
-static HRESULT load_GifComment_metadata(IStream *stream, const GUID *vendor, DWORD options, - MetadataItem **items, DWORD *count) +static HRESULT load_GifComment_metadata(MetadataHandler *handler, IStream *stream, const GUID *vendor, DWORD options) { #include "pshpack1.h" struct gif_extension @@ -448,9 +435,6 @@ static HRESULT load_GifComment_metadata(IStream *stream, const GUID *vendor, DWO BYTE subblock_size; char *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 || @@ -509,8 +493,9 @@ static HRESULT load_GifComment_metadata(IStream *stream, const GUID *vendor, DWO result->value.vt = VT_LPSTR; result->value.pszVal = data;
- *items = result; - *count = 1; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 1;
return S_OK; } diff --git a/dlls/windowscodecs/metadatahandler.c b/dlls/windowscodecs/metadatahandler.c index a33abb48ce1..ebb7a08b0b6 100644 --- a/dlls/windowscodecs/metadatahandler.c +++ b/dlls/windowscodecs/metadatahandler.c @@ -33,20 +33,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
-typedef struct MetadataHandler { - IWICMetadataWriter IWICMetadataWriter_iface; - LONG ref; - IWICPersistStream IWICPersistStream_iface; - IWICStreamProvider IWICStreamProvider_iface; - const MetadataHandlerVtbl *vtable; - MetadataItem *items; - DWORD item_count; - DWORD persist_options; - IStream *stream; - ULARGE_INTEGER origin; - CRITICAL_SECTION lock; -} MetadataHandler; - static inline MetadataHandler *impl_from_IWICMetadataWriter(IWICMetadataWriter *iface) { return CONTAINING_RECORD(iface, MetadataHandler, IWICMetadataWriter_iface); @@ -69,7 +55,7 @@ static void clear_metadata_item(MetadataItem *item) PropVariantClear(&item->value); }
-static void MetadataHandler_FreeItems(MetadataHandler *This) +void MetadataHandler_FreeItems(MetadataHandler *This) { DWORD i;
@@ -516,8 +502,6 @@ static HRESULT WINAPI MetadataHandler_LoadEx(IWICPersistStream *iface, { MetadataHandler *This = impl_from_IWICPersistStream(iface); HRESULT hr = S_OK; - MetadataItem *new_items=NULL; - DWORD item_count=0; LARGE_INTEGER move;
TRACE("(%p,%p,%s,%lx)\n", iface, stream, debugstr_guid(pguidPreferredVendor), dwPersistOptions); @@ -530,8 +514,7 @@ static HRESULT WINAPI MetadataHandler_LoadEx(IWICPersistStream *iface, move.QuadPart = 0; hr = IStream_Seek(stream, move, STREAM_SEEK_CUR, &This->origin); if (SUCCEEDED(hr)) - hr = This->vtable->fnLoad(stream, pguidPreferredVendor, dwPersistOptions, - &new_items, &item_count); + hr = This->vtable->fnLoad(This, stream, pguidPreferredVendor, dwPersistOptions); }
if (This->stream) @@ -546,13 +529,6 @@ static HRESULT WINAPI MetadataHandler_LoadEx(IWICPersistStream *iface, } This->persist_options = dwPersistOptions & WICPersistOptionMask;
- if (new_items) - { - MetadataHandler_FreeItems(This); - This->items = new_items; - This->item_count = item_count; - } - LeaveCriticalSection(&This->lock);
return hr; @@ -892,8 +868,8 @@ static HRESULT MetadataHandlerEnum_Create(MetadataHandler *parent, DWORD index, return S_OK; }
-static HRESULT LoadUnknownMetadata(IStream *input, const GUID *preferred_vendor, - DWORD persist_options, MetadataItem **items, DWORD *item_count) +static HRESULT LoadUnknownMetadata(MetadataHandler *handler, IStream *input, const GUID *preferred_vendor, + DWORD persist_options) { HRESULT hr; MetadataItem *result; @@ -933,8 +909,9 @@ static HRESULT LoadUnknownMetadata(IStream *input, const GUID *preferred_vendor, result[0].value.blob.cbSize = bytesread; result[0].value.blob.pBlobData = data;
- *items = result; - *item_count = 1; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 1;
return S_OK; } @@ -1398,8 +1375,8 @@ static HRESULT load_IFD_entry(IStream *input, const GUID *vendor, DWORD options, return hr; }
-static HRESULT load_ifd_metadata_internal(IStream *input, const GUID *vendor, - DWORD persist_options, bool resolve_pointer_tags, bool is_writer, MetadataItem **items, DWORD *item_count) +static HRESULT load_ifd_metadata_internal(MetadataHandler *handler, IStream *input, const GUID *vendor, + DWORD persist_options, bool resolve_pointer_tags, bool is_writer) { HRESULT hr; MetadataItem *result; @@ -1489,64 +1466,66 @@ static HRESULT load_ifd_metadata_internal(IStream *input, const GUID *vendor,
free(entry);
- *items = result; - *item_count = count; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = count;
return S_OK; }
-static HRESULT LoadIfdMetadataReader(IStream *input, const GUID *vendor, - DWORD options, MetadataItem **items, DWORD *item_count) +static HRESULT LoadIfdMetadataReader(MetadataHandler *handler, IStream *input, const GUID *vendor, + DWORD options) { TRACE("%p, %#lx.\n", input, options); - return load_ifd_metadata_internal(input, vendor, options, true, false, items, item_count); + return load_ifd_metadata_internal(handler, input, vendor, options, true, false); }
-static HRESULT LoadIfdMetadataWriter(IStream *input, const GUID *vendor, - DWORD options, MetadataItem **items, DWORD *item_count) +static HRESULT LoadIfdMetadataWriter(MetadataHandler *handler, IStream *input, const GUID *vendor, + DWORD options) { TRACE("%p, %#lx.\n", input, options); - return load_ifd_metadata_internal(input, vendor, options, true, true, items, item_count); + return load_ifd_metadata_internal(handler, input, vendor, options, true, true); }
-static HRESULT LoadExifMetadataReader(IStream *input, const GUID *vendor, - DWORD options, MetadataItem **items, DWORD *item_count) +static HRESULT LoadExifMetadataReader(MetadataHandler *handler, IStream *input, const GUID *vendor, + DWORD options) { TRACE("%p, %#lx.\n", input, options);
- return load_ifd_metadata_internal(input, vendor, options, false, false, items, item_count); + return load_ifd_metadata_internal(handler, input, vendor, options, false, false); }
-static HRESULT LoadExifMetadataWriter(IStream *input, const GUID *vendor, - DWORD options, MetadataItem **items, DWORD *item_count) +static HRESULT LoadExifMetadataWriter(MetadataHandler *handler, IStream *input, const GUID *vendor, + DWORD options) { TRACE("%p, %#lx.\n", input, options);
- return load_ifd_metadata_internal(input, vendor, options, false, true, items, item_count); + return load_ifd_metadata_internal(handler, input, vendor, options, false, true); }
-static HRESULT LoadGpsMetadataReader(IStream *input, const GUID *vendor, - DWORD options, MetadataItem **items, DWORD *item_count) +static HRESULT LoadGpsMetadataReader(MetadataHandler *handler, IStream *input, const GUID *vendor, + DWORD options) { TRACE("%p, %#lx.\n", input, options);
- return load_ifd_metadata_internal(input, vendor, options, false, false, items, item_count); + return load_ifd_metadata_internal(handler, input, vendor, options, false, false); }
-static HRESULT LoadGpsMetadataWriter(IStream *input, const GUID *vendor, - DWORD options, MetadataItem **items, DWORD *item_count) +static HRESULT LoadGpsMetadataWriter(MetadataHandler *handler, IStream *input, const GUID *vendor, + DWORD options) { TRACE("%p, %#lx.\n", input, options);
- return load_ifd_metadata_internal(input, vendor, options, false, true, items, item_count); + return load_ifd_metadata_internal(handler, input, vendor, options, false, true); }
-static HRESULT load_app1_metadata_internal(IStream *input, const GUID *vendor, DWORD options, - bool is_writer, MetadataItem **items, DWORD *item_count) +static HRESULT load_app1_metadata_internal(MetadataHandler *handler, IStream *input, const GUID *vendor, DWORD options, + bool is_writer) { static const char exif_header[] = {'E','x','i','f',0,0}; IWICMetadataReader *ifd_reader = NULL; BOOL native_byte_order; + MetadataItem *result; LARGE_INTEGER move;
#include "pshpack2.h" @@ -1613,31 +1592,32 @@ static HRESULT load_app1_metadata_internal(IStream *input, const GUID *vendor, D return hr; }
- if (!(*items = calloc(1, sizeof(**items)))) + if (!(result = calloc(1, sizeof(*result)))) { IWICMetadataReader_Release(ifd_reader); return E_OUTOFMEMORY; }
- (*items)[0].id.vt = VT_UI2; - (*items)[0].id.uiVal = 0; - (*items)[0].value.vt = VT_UNKNOWN; - (*items)[0].value.punkVal = (IUnknown *)ifd_reader; - *item_count = 1; + result->id.vt = VT_UI2; + result->id.uiVal = 0; + result->value.vt = VT_UNKNOWN; + result->value.punkVal = (IUnknown *)ifd_reader; + + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 1;
return S_OK; }
-static HRESULT LoadApp1MetadataReader(IStream *input, const GUID *vendor, DWORD options, - MetadataItem **items, DWORD *item_count) +static HRESULT LoadApp1MetadataReader(MetadataHandler *handler, IStream *input, const GUID *vendor, DWORD options) { - return load_app1_metadata_internal(input, vendor, options, false, items, item_count); + return load_app1_metadata_internal(handler, input, vendor, options, false); }
-static HRESULT LoadApp1MetadataWriter(IStream *input, const GUID *vendor, DWORD options, - MetadataItem **items, DWORD *item_count) +static HRESULT LoadApp1MetadataWriter(MetadataHandler *handler, IStream *input, const GUID *vendor, DWORD options) { - return load_app1_metadata_internal(input, vendor, options, true, items, item_count); + return load_app1_metadata_internal(handler, input, vendor, options, true); }
static const MetadataHandlerVtbl IfdMetadataReader_Vtbl = { diff --git a/dlls/windowscodecs/pngformat.c b/dlls/windowscodecs/pngformat.c index 0e69671c9b8..51613f538c3 100644 --- a/dlls/windowscodecs/pngformat.c +++ b/dlls/windowscodecs/pngformat.c @@ -40,8 +40,8 @@ static inline ULONG read_ulong_be(BYTE* data) return data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; }
-static HRESULT LoadTextMetadata(IStream *stream, const GUID *preferred_vendor, - DWORD persist_options, MetadataItem **items, DWORD *item_count) +static HRESULT LoadTextMetadata(MetadataHandler *handler, IStream *stream, const GUID *preferred_vendor, + DWORD persist_options) { HRESULT hr; BYTE type[4]; @@ -92,8 +92,9 @@ static HRESULT LoadTextMetadata(IStream *stream, const GUID *preferred_vendor, result[0].value.vt = VT_LPSTR; result[0].value.pszVal = value;
- *items = result; - *item_count = 1; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 1;
free(data);
@@ -111,8 +112,8 @@ HRESULT PngTextReader_CreateInstance(REFIID iid, void** ppv) return MetadataReader_Create(&TextReader_Vtbl, iid, ppv); }
-static HRESULT LoadGamaMetadata(IStream *stream, const GUID *preferred_vendor, - DWORD persist_options, MetadataItem **items, DWORD *item_count) +static HRESULT LoadGamaMetadata(MetadataHandler *handler, IStream *stream, const GUID *preferred_vendor, + DWORD persist_options) { HRESULT hr; BYTE type[4]; @@ -153,8 +154,9 @@ static HRESULT LoadGamaMetadata(IStream *stream, const GUID *preferred_vendor, result[0].value.vt = VT_UI4; result[0].value.ulVal = gamma;
- *items = result; - *item_count = 1; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 1;
return S_OK; } @@ -170,8 +172,8 @@ 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) +static HRESULT LoadChrmMetadata(MetadataHandler *handler, IStream *stream, const GUID *preferred_vendor, + DWORD persist_options) { HRESULT hr; BYTE type[4]; @@ -228,8 +230,9 @@ static HRESULT LoadChrmMetadata(IStream *stream, const GUID *preferred_vendor, result[i].value.ulVal = read_ulong_be(&data[i*4]); }
- *items = result; - *item_count = 8; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 8;
free(data);
@@ -247,8 +250,8 @@ HRESULT PngChrmReader_CreateInstance(REFIID iid, void** ppv) return MetadataReader_Create(&ChrmReader_Vtbl, iid, ppv); }
-static HRESULT LoadHistMetadata(IStream *stream, const GUID *preferred_vendor, - DWORD persist_options, MetadataItem **items, DWORD *item_count) +static HRESULT LoadHistMetadata(MetadataHandler *handler, IStream *stream, const GUID *preferred_vendor, + DWORD persist_options) { HRESULT hr; BYTE type[4]; @@ -293,8 +296,9 @@ static HRESULT LoadHistMetadata(IStream *stream, const GUID *preferred_vendor, result[0].value.caui.cElems = element_count; result[0].value.caui.pElems = elements;
- *items = result; - *item_count = 1; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 1;
return S_OK; } @@ -310,8 +314,8 @@ HRESULT PngHistReader_CreateInstance(REFIID iid, void** ppv) return MetadataReader_Create(&HistReader_Vtbl, iid, ppv); }
-static HRESULT LoadTimeMetadata(IStream *stream, const GUID *preferred_vendor, - DWORD persist_options, MetadataItem **items, DWORD *item_count) +static HRESULT LoadTimeMetadata(MetadataHandler *handler, IStream *stream, const GUID *preferred_vendor, + DWORD persist_options) { HRESULT hr; BYTE type[4]; @@ -377,8 +381,9 @@ static HRESULT LoadTimeMetadata(IStream *stream, const GUID *preferred_vendor, result[5].value.vt = VT_UI1; result[5].value.bVal = data[6];
- *items = result; - *item_count = 6; + MetadataHandler_FreeItems(handler); + handler->items = result; + handler->item_count = 6;
free(data);
diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h index 89ada4e024c..5cc86d5d663 100644 --- a/dlls/windowscodecs/wincodecs_private.h +++ b/dlls/windowscodecs/wincodecs_private.h @@ -205,15 +205,33 @@ enum metadatahandler_flags METADATAHANDLER_FIXED_ITEMS = 0x2, /* Items cannot be added or removed. */ };
+typedef struct MetadataHandler MetadataHandler; + typedef struct _MetadataHandlerVtbl { DWORD flags; const CLSID *clsid; - HRESULT (*fnLoad)(IStream *stream, const GUID *preferred_vendor, - DWORD persist_options, MetadataItem **items, DWORD *item_count); + HRESULT (*fnLoad)(MetadataHandler *handler, IStream *stream, const GUID *preferred_vendor, + DWORD persist_options); } MetadataHandlerVtbl;
+typedef struct MetadataHandler +{ + IWICMetadataWriter IWICMetadataWriter_iface; + LONG ref; + IWICPersistStream IWICPersistStream_iface; + IWICStreamProvider IWICStreamProvider_iface; + const MetadataHandlerVtbl *vtable; + MetadataItem *items; + DWORD item_count; + DWORD persist_options; + IStream *stream; + ULARGE_INTEGER origin; + CRITICAL_SECTION lock; +} MetadataHandler; + extern HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, REFIID iid, void** ppv); +extern void MetadataHandler_FreeItems(MetadataHandler *handler);
extern HRESULT UnknownMetadataReader_CreateInstance(REFIID iid, void** ppv); extern HRESULT UnknownMetadataWriter_CreateInstance(REFIID iid, void** ppv);
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/windowscodecs/metadatahandler.c | 32 ++++++++++++++--- dlls/windowscodecs/tests/metadata.c | 48 ++++++++------------------ dlls/windowscodecs/wincodecs_private.h | 1 + 3 files changed, 44 insertions(+), 37 deletions(-)
diff --git a/dlls/windowscodecs/metadatahandler.c b/dlls/windowscodecs/metadatahandler.c index ebb7a08b0b6..d087a0640d7 100644 --- a/dlls/windowscodecs/metadatahandler.c +++ b/dlls/windowscodecs/metadatahandler.c @@ -648,7 +648,7 @@ static const IWICStreamProviderVtbl MetadataHandler_StreamProvider_Vtbl = HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, REFIID iid, void** ppv) { MetadataHandler *This; - HRESULT hr; + HRESULT hr = S_OK;
TRACE("%s\n", debugstr_guid(vtable->clsid));
@@ -666,7 +666,11 @@ HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, REFIID iid, voi InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": MetadataHandler.lock");
- hr = IWICMetadataWriter_QueryInterface(&This->IWICMetadataWriter_iface, iid, ppv); + if (This->vtable->fnCreate) + hr = This->vtable->fnCreate(This); + + if (SUCCEEDED(hr)) + hr = IWICMetadataWriter_QueryInterface(&This->IWICMetadataWriter_iface, iid, ppv);
IWICMetadataWriter_Release(&This->IWICMetadataWriter_iface);
@@ -916,10 +920,29 @@ static HRESULT LoadUnknownMetadata(MetadataHandler *handler, IStream *input, con return S_OK; }
+static HRESULT CreateUnknownHandler(MetadataHandler *handler) +{ + MetadataItem *item; + + if (!(item = calloc(1, sizeof(*item)))) + return E_OUTOFMEMORY; + + PropVariantInit(&item->schema); + PropVariantInit(&item->id); + PropVariantInit(&item->value); + item->value.vt = VT_BLOB; + + handler->items = item; + handler->item_count = 1; + + return S_OK; +} + static const MetadataHandlerVtbl UnknownMetadataReader_Vtbl = { .clsid = &CLSID_WICUnknownMetadataReader, - .fnLoad = LoadUnknownMetadata + .fnLoad = LoadUnknownMetadata, + .fnCreate = CreateUnknownHandler, };
HRESULT UnknownMetadataReader_CreateInstance(REFIID iid, void** ppv) @@ -931,7 +954,8 @@ static const MetadataHandlerVtbl UnknownMetadataWriter_Vtbl = { .flags = METADATAHANDLER_IS_WRITER | METADATAHANDLER_FIXED_ITEMS, .clsid = &CLSID_WICUnknownMetadataWriter, - .fnLoad = LoadUnknownMetadata + .fnLoad = LoadUnknownMetadata, + .fnCreate = CreateUnknownHandler, };
HRESULT UnknownMetadataWriter_CreateInstance(REFIID iid, void** ppv) diff --git a/dlls/windowscodecs/tests/metadata.c b/dlls/windowscodecs/tests/metadata.c index 602d2406be1..022c5b9008f 100644 --- a/dlls/windowscodecs/tests/metadata.c +++ b/dlls/windowscodecs/tests/metadata.c @@ -783,20 +783,15 @@ static void test_metadata_unknown(void)
hr = IWICMetadataReader_GetCount(reader, &count); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(count == 1, "Unexpected count %u.\n", count);
PropVariantInit(&value); hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, NULL, &value); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr == S_OK) - { - ok(value.vt == VT_BLOB, "Unexpected type %d.\n", value.vt); - ok(!value.blob.cbSize, "Unexpected size %lu.\n", value.blob.cbSize); - ok(!value.blob.pBlobData, "Unexpected data pointer %p.\n", value.blob.pBlobData); - PropVariantClear(&value); - } + ok(value.vt == VT_BLOB, "Unexpected type %d.\n", value.vt); + ok(!value.blob.cbSize, "Unexpected size %lu.\n", value.blob.cbSize); + ok(!value.blob.pBlobData, "Unexpected data pointer %p.\n", value.blob.pBlobData); + PropVariantClear(&value);
load_stream(reader, metadata_unknown, sizeof(metadata_unknown), WICPersistOptionDefault);
@@ -915,23 +910,18 @@ static void test_metadata_unknown(void)
hr = IWICMetadataWriter_GetCount(writer, &count); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(count == 1, "Unexpected count %u.\n", count);
PropVariantInit(&schema); PropVariantInit(&id); PropVariantInit(&value); hr = IWICMetadataWriter_GetValueByIndex(writer, 0, &schema, &id, &value); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr == S_OK) - { - ok(schema.vt == VT_EMPTY, "Unexpected type %d.\n", schema.vt); - ok(id.vt == VT_EMPTY, "Unexpected type %d.\n", id.vt); - ok(value.vt == VT_BLOB, "Unexpected type %d.\n", value.vt); - ok(!value.blob.cbSize, "Unexpected size %lu.\n", value.blob.cbSize); - ok(!value.blob.pBlobData, "Unexpected data pointer %p.\n", value.blob.pBlobData); - } + ok(schema.vt == VT_EMPTY, "Unexpected type %d.\n", schema.vt); + ok(id.vt == VT_EMPTY, "Unexpected type %d.\n", id.vt); + ok(value.vt == VT_BLOB, "Unexpected type %d.\n", value.vt); + ok(!value.blob.cbSize, "Unexpected size %lu.\n", value.blob.cbSize); + ok(!value.blob.pBlobData, "Unexpected data pointer %p.\n", value.blob.pBlobData);
PropVariantInit(&schema); PropVariantInit(&value); @@ -6779,26 +6769,18 @@ static void test_CreateQueryWriter(void)
PropVariantInit(&value); hr = IWICMetadataQueryWriter_GetMetadataByName(query_writer, L"/", &value); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr == S_OK) - { - ok(value.vt == VT_BLOB, "Unexpected value type %u.\n", value.vt); - ok(!value.blob.cbSize, "Unexpected size %lu.\n", value.blob.cbSize); - ok(!value.blob.pBlobData, "Unexpected data pointer %p.\n", value.blob.pBlobData); - PropVariantClear(&value); - } + ok(value.vt == VT_BLOB, "Unexpected value type %u.\n", value.vt); + ok(!value.blob.cbSize, "Unexpected size %lu.\n", value.blob.cbSize); + ok(!value.blob.pBlobData, "Unexpected data pointer %p.\n", value.blob.pBlobData); + PropVariantClear(&value);
hr = IWICMetadataQueryWriter_GetEnumerator(query_writer, &enum_string); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IEnumString_Next(enum_string, 1, &str, &fetched); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr == S_OK) - { - ok(!wcscmp(str, L"/{}"), "Unexpected string %s.\n", wine_dbgstr_w(str)); - CoTaskMemFree(str); - } + ok(!wcscmp(str, L"/{}"), "Unexpected string %s.\n", wine_dbgstr_w(str)); + CoTaskMemFree(str); hr = IEnumString_Next(enum_string, 1, &str, &fetched); ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr); IEnumString_Release(enum_string); diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h index 5cc86d5d663..690d5e34e58 100644 --- a/dlls/windowscodecs/wincodecs_private.h +++ b/dlls/windowscodecs/wincodecs_private.h @@ -213,6 +213,7 @@ typedef struct _MetadataHandlerVtbl const CLSID *clsid; HRESULT (*fnLoad)(MetadataHandler *handler, IStream *stream, const GUID *preferred_vendor, DWORD persist_options); + HRESULT (*fnCreate)(MetadataHandler *handler); } MetadataHandlerVtbl;
typedef struct MetadataHandler
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/windowscodecs/metadataquery.c | 14 ------- dlls/windowscodecs/pngformat.c | 57 +++++++++++++++++--------- dlls/windowscodecs/tests/metadata.c | 17 +++----- dlls/windowscodecs/wincodecs_private.h | 14 +++++++ 4 files changed, 58 insertions(+), 44 deletions(-)
diff --git a/dlls/windowscodecs/metadataquery.c b/dlls/windowscodecs/metadataquery.c index 9794a35214b..39a788e1832 100644 --- a/dlls/windowscodecs/metadataquery.c +++ b/dlls/windowscodecs/metadataquery.c @@ -341,20 +341,6 @@ static bool parser_unescape(struct query_parser *parser) return false; }
-static HRESULT init_propvar_from_string(const WCHAR *str, PROPVARIANT *var) -{ - size_t size = (wcslen(str) + 1) * sizeof(*str); - WCHAR *s; - - if (!(s = CoTaskMemAlloc(size))) - return E_OUTOFMEMORY; - memcpy(s, str, size); - - var->pwszVal = s; - var->vt = VT_LPWSTR; - return S_OK; -} - static void parse_query_name(struct query_parser *parser, PROPVARIANT *item) { size_t len = 0; diff --git a/dlls/windowscodecs/pngformat.c b/dlls/windowscodecs/pngformat.c index 51613f538c3..ebf8e1477d7 100644 --- a/dlls/windowscodecs/pngformat.c +++ b/dlls/windowscodecs/pngformat.c @@ -112,6 +112,26 @@ HRESULT PngTextReader_CreateInstance(REFIID iid, void** ppv) return MetadataReader_Create(&TextReader_Vtbl, iid, ppv); }
+static HRESULT create_gamma_item(ULONG gamma, MetadataItem **item) +{ + HRESULT hr; + + if (!(*item = calloc(1, sizeof(**item)))) + return E_OUTOFMEMORY; + + hr = init_propvar_from_string(L"ImageGamma", &(*item)->id); + if (FAILED(hr)) + { + free(*item); + return hr; + } + + (*item)->value.vt = VT_UI4; + (*item)->value.ulVal = gamma; + + return S_OK; +} + static HRESULT LoadGamaMetadata(MetadataHandler *handler, IStream *stream, const GUID *preferred_vendor, DWORD persist_options) { @@ -120,7 +140,6 @@ static HRESULT LoadGamaMetadata(MetadataHandler *handler, IStream *stream, const BYTE *data; ULONG data_size; ULONG gamma; - LPWSTR name; MetadataItem *result;
hr = read_png_chunk(stream, type, &data, &data_size); @@ -136,23 +155,8 @@ static HRESULT LoadGamaMetadata(MetadataHandler *handler, IStream *stream, const
free(data);
- result = calloc(1, sizeof(MetadataItem)); - SHStrDupW(L"ImageGamma", &name); - if (!result || !name) - { - free(result); - CoTaskMemFree(name); - return E_OUTOFMEMORY; - } - - PropVariantInit(&result[0].schema); - PropVariantInit(&result[0].id); - PropVariantInit(&result[0].value); - - result[0].id.vt = VT_LPWSTR; - result[0].id.pwszVal = name; - result[0].value.vt = VT_UI4; - result[0].value.ulVal = gamma; + if (FAILED(hr = create_gamma_item(gamma, &result))) + return hr;
MetadataHandler_FreeItems(handler); handler->items = result; @@ -161,10 +165,25 @@ static HRESULT LoadGamaMetadata(MetadataHandler *handler, IStream *stream, const return S_OK; }
+static HRESULT CreateGamaHandler(MetadataHandler *handler) +{ + MetadataItem *item; + HRESULT hr; + + if (FAILED(hr = create_gamma_item(45455, &item))) + return hr; + + handler->items = item; + handler->item_count = 1; + + return S_OK; +} + static const MetadataHandlerVtbl GamaReader_Vtbl = { 0, &CLSID_WICPngGamaMetadataReader, - LoadGamaMetadata + LoadGamaMetadata, + CreateGamaHandler, };
HRESULT PngGamaReader_CreateInstance(REFIID iid, void** ppv) diff --git a/dlls/windowscodecs/tests/metadata.c b/dlls/windowscodecs/tests/metadata.c index 022c5b9008f..2037fec17da 100644 --- a/dlls/windowscodecs/tests/metadata.c +++ b/dlls/windowscodecs/tests/metadata.c @@ -1180,24 +1180,19 @@ static void test_metadata_gAMA(void)
hr = IWICMetadataReader_GetCount(reader, &count); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(count == 1, "Unexpected count %u.\n", count);
id.vt = value.vt = VT_EMPTY; hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, &id, &value); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- if (hr == S_OK) - { - ok(id.vt == VT_LPWSTR, "Unexpected vt %d.\n", id.vt); - ok(!lstrcmpW(id.pwszVal, L"ImageGamma"), "unexpected value: %s\n", wine_dbgstr_w(id.pwszVal)); - PropVariantClear(&id); + ok(id.vt == VT_LPWSTR, "Unexpected vt %d.\n", id.vt); + ok(!lstrcmpW(id.pwszVal, L"ImageGamma"), "unexpected value: %s\n", wine_dbgstr_w(id.pwszVal)); + PropVariantClear(&id);
- ok(value.vt == VT_UI4, "Unexpected vt %d.\n", value.vt); - ok(value.ulVal == 45455, "Unexpected value %lu.\n", value.ulVal); - PropVariantClear(&value); - } + ok(value.vt == VT_UI4, "Unexpected vt %d.\n", value.vt); + ok(value.ulVal == 45455, "Unexpected value %lu.\n", value.ulVal); + PropVariantClear(&value);
load_stream(reader, metadata_gAMA, sizeof(metadata_gAMA), WICPersistOptionDefault);
diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h index 690d5e34e58..71c011e4e6f 100644 --- a/dlls/windowscodecs/wincodecs_private.h +++ b/dlls/windowscodecs/wincodecs_private.h @@ -192,6 +192,20 @@ extern HRESULT IcoDibDecoder_CreateInstance(BmpDecoder **ppDecoder); extern void BmpDecoder_GetWICDecoder(BmpDecoder *This, IWICBitmapDecoder **ppDecoder); extern void BmpDecoder_FindIconMask(BmpDecoder *This, ULONG *mask_offset, int *topdown);
+static inline HRESULT init_propvar_from_string(const WCHAR *str, PROPVARIANT *var) +{ + size_t size = (wcslen(str) + 1) * sizeof(*str); + WCHAR *s; + + if (!(s = CoTaskMemAlloc(size))) + return E_OUTOFMEMORY; + memcpy(s, str, size); + + var->pwszVal = s; + var->vt = VT_LPWSTR; + return S_OK; +} + typedef struct _MetadataItem { PROPVARIANT schema;
Esme Povirk (@madewokherd) commented about dlls/windowscodecs/tests/metadata.c:
+{
- IWICComponentFactory *factory;
- IWICMetadataReader *reader;
- IStream *stream;
- HRESULT hr;
- GUID guid;
- hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
&IID_IWICComponentFactory, (void **)&factory);
- ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- stream = create_stream(data, size);
- ok_(__FILE__, line)(!!stream, "Failed to create a stream.\n");
- hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory,
&GUID_ContainerFormatPng, NULL, WICMetadataCreationFailUnknown, stream, &reader);
Did you mean to use `container` instead of hard-coding PNG here?
On Wed Apr 9 17:43:53 2025 +0000, Esme Povirk wrote:
Did you mean to use `container` instead of hard-coding PNG here?
Oof, yes. That explains why some things didn't work.
Looks good to me other than the one comment.