From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/windowscodecs/encoder.c | 2 +- dlls/windowscodecs/gifformat.c | 6 ++-- dlls/windowscodecs/imgfactory.c | 25 ++++++++++---- dlls/windowscodecs/metadataquery.c | 48 ++++++++++++++++++++++++-- dlls/windowscodecs/tests/metadata.c | 27 ++++++++------- dlls/windowscodecs/wincodecs_private.h | 6 ++-- 6 files changed, 85 insertions(+), 29 deletions(-)
diff --git a/dlls/windowscodecs/encoder.c b/dlls/windowscodecs/encoder.c index de1dadc70c2..e9b9ae181ab 100644 --- a/dlls/windowscodecs/encoder.c +++ b/dlls/windowscodecs/encoder.c @@ -479,7 +479,7 @@ static HRESULT WINAPI CommonEncoderFrame_GetMetadataQueryWriter(IWICBitmapFrameE if (!(encoder->parent->encoder_info.flags & ENCODER_FLAGS_SUPPORTS_METADATA)) return WINCODEC_ERR_UNSUPPORTEDOPERATION;
- return MetadataQueryWriter_CreateInstance(&encoder->IWICMetadataBlockWriter_iface, ppIMetadataQueryWriter); + return MetadataQueryWriter_CreateInstanceFromBlockWriter(&encoder->IWICMetadataBlockWriter_iface, ppIMetadataQueryWriter); }
static const IWICBitmapFrameEncodeVtbl CommonEncoderFrame_Vtbl = { diff --git a/dlls/windowscodecs/gifformat.c b/dlls/windowscodecs/gifformat.c index a347ee3bc50..554d4cf14fd 100644 --- a/dlls/windowscodecs/gifformat.c +++ b/dlls/windowscodecs/gifformat.c @@ -837,7 +837,7 @@ static HRESULT WINAPI GifFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDecod if (!ppIMetadataQueryReader) return E_INVALIDARG;
- return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, ppIMetadataQueryReader); + return MetadataQueryReader_CreateInstanceFromBlockReader(&This->IWICMetadataBlockReader_iface, ppIMetadataQueryReader); }
static HRESULT WINAPI GifFrameDecode_GetColorContexts(IWICBitmapFrameDecode *iface, @@ -1216,7 +1216,7 @@ static HRESULT WINAPI GifDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface
if (!ppIMetadataQueryReader) return E_INVALIDARG;
- return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, ppIMetadataQueryReader); + return MetadataQueryReader_CreateInstanceFromBlockReader(&This->IWICMetadataBlockReader_iface, ppIMetadataQueryReader); }
static HRESULT WINAPI GifDecoder_GetPreview(IWICBitmapDecoder *iface, @@ -2098,7 +2098,7 @@ static HRESULT WINAPI GifFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncod if (!encode->initialized) return WINCODEC_ERR_NOTINITIALIZED;
- return MetadataQueryWriter_CreateInstance(&encode->IWICMetadataBlockWriter_iface, writer); + return MetadataQueryWriter_CreateInstanceFromBlockWriter(&encode->IWICMetadataBlockWriter_iface, writer); }
static const IWICBitmapFrameEncodeVtbl GifFrameEncode_Vtbl = diff --git a/dlls/windowscodecs/imgfactory.c b/dlls/windowscodecs/imgfactory.c index 5af765e3852..8de1d370a38 100644 --- a/dlls/windowscodecs/imgfactory.c +++ b/dlls/windowscodecs/imgfactory.c @@ -1000,12 +1000,23 @@ static HRESULT WINAPI ImagingFactory_CreateFastMetadataEncoderFromFrameDecode( }
static HRESULT WINAPI ImagingFactory_CreateQueryWriter(IWICImagingFactory2 *iface, - REFGUID guidMetadataFormat, const GUID *pguidVendor, - IWICMetadataQueryWriter **ppIQueryWriter) + REFGUID format, const GUID *vendor, IWICMetadataQueryWriter **query_writer) { - FIXME("(%p,%s,%s,%p): stub\n", iface, debugstr_guid(guidMetadataFormat), - debugstr_guid(pguidVendor), ppIQueryWriter); - return E_NOTIMPL; + IWICMetadataWriter *writer; + HRESULT hr; + + TRACE("(%p,%s,%s,%p)\n", iface, debugstr_guid(format), debugstr_guid(vendor), query_writer); + + *query_writer = NULL; + + hr = create_metadata_writer(format, vendor, 0, &writer); + if (SUCCEEDED(hr)) + { + hr = MetadataQueryWriter_CreateInstance(writer, query_writer); + IWICMetadataWriter_Release(writer); + } + + return hr; }
static HRESULT WINAPI ImagingFactory_CreateQueryWriterFromReader(IWICImagingFactory2 *iface, @@ -1769,7 +1780,7 @@ static HRESULT WINAPI ComponentFactory_CreateQueryReaderFromBlockReader(IWICComp if (!block_reader || !query_reader) return E_INVALIDARG;
- return MetadataQueryReader_CreateInstance(block_reader, query_reader); + return MetadataQueryReader_CreateInstanceFromBlockReader(block_reader, query_reader); }
static HRESULT WINAPI ComponentFactory_CreateQueryWriterFromBlockWriter(IWICComponentFactory *iface, @@ -1780,7 +1791,7 @@ static HRESULT WINAPI ComponentFactory_CreateQueryWriterFromBlockWriter(IWICComp if (!block_writer || !query_writer) return E_INVALIDARG;
- return MetadataQueryWriter_CreateInstance(block_writer, query_writer); + return MetadataQueryWriter_CreateInstanceFromBlockWriter(block_writer, query_writer); }
static HRESULT WINAPI ComponentFactory_CreateEncoderPropertyBag(IWICComponentFactory *iface, diff --git a/dlls/windowscodecs/metadataquery.c b/dlls/windowscodecs/metadataquery.c index dab3f673d11..e3225d8d361 100644 --- a/dlls/windowscodecs/metadataquery.c +++ b/dlls/windowscodecs/metadataquery.c @@ -735,6 +735,17 @@ static HRESULT WINAPI query_handler_GetMetadataByName(IWICMetadataQueryWriter *i return hr; }
+static WCHAR *query_get_guid_item_string(WCHAR *str, unsigned int len, const GUID *guid) +{ + if (SUCCEEDED(WICMapGuidToShortName(guid, len, str, NULL))) + return str; + + swprintf(str, len, L"{guid=%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1], guid->Data4[2], + guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); + return str; +} + struct string_enumerator { IEnumString IEnumString_iface; @@ -886,6 +897,9 @@ static HRESULT create_query_handler(IUnknown *block_handler, enum metadata_objec const WCHAR *root, IWICMetadataQueryWriter **ret) { struct query_handler *obj; + WCHAR buff[64]; + HRESULT hr; + GUID guid;
obj = calloc(1, sizeof(*obj)); if (!obj) @@ -897,7 +911,25 @@ static HRESULT create_query_handler(IUnknown *block_handler, enum metadata_objec obj->object.handler = block_handler; obj->object_type = object_type; if (!root) - root = L"/"; + { + if (is_block_handler(obj)) + { + root = L"/"; + } + else + { + if (FAILED(hr = IWICMetadataReader_GetMetadataFormat(obj->object.reader, &guid))) + { + IWICMetadataQueryWriter_Release(&obj->IWICMetadataQueryWriter_iface); + return hr; + } + + buff[0] = '/'; + query_get_guid_item_string(buff + 1, ARRAY_SIZE(buff) - 1, &guid); + root = buff; + } + } + obj->root = wcsdup(root);
*ret = &obj->IWICMetadataQueryWriter_iface; @@ -905,18 +937,28 @@ static HRESULT create_query_handler(IUnknown *block_handler, enum metadata_objec return S_OK; }
-HRESULT MetadataQueryReader_CreateInstance(IWICMetadataBlockReader *block_reader, +HRESULT MetadataQueryReader_CreateInstanceFromBlockReader(IWICMetadataBlockReader *block_reader, IWICMetadataQueryReader **out) { return create_query_handler((IUnknown *)block_reader, BLOCK_READER, NULL, (IWICMetadataQueryWriter **)out); }
-HRESULT MetadataQueryWriter_CreateInstance(IWICMetadataBlockWriter *block_writer, +HRESULT MetadataQueryWriter_CreateInstanceFromBlockWriter(IWICMetadataBlockWriter *block_writer, IWICMetadataQueryWriter **out) { return create_query_handler((IUnknown *)block_writer, BLOCK_WRITER, NULL, out); }
+HRESULT MetadataQueryReader_CreateInstance(IWICMetadataReader *reader, IWICMetadataQueryReader **out) +{ + return create_query_handler((IUnknown *)reader, READER, NULL, (IWICMetadataQueryWriter **)out); +} + +HRESULT MetadataQueryWriter_CreateInstance(IWICMetadataWriter *writer, IWICMetadataQueryWriter **out) +{ + return create_query_handler((IUnknown *)writer, WRITER, NULL, out); +} + static const struct { const GUID *guid; diff --git a/dlls/windowscodecs/tests/metadata.c b/dlls/windowscodecs/tests/metadata.c index efbb8d57ec1..42d14f28ad5 100644 --- a/dlls/windowscodecs/tests/metadata.c +++ b/dlls/windowscodecs/tests/metadata.c @@ -5666,13 +5666,7 @@ static void test_CreateQueryWriter(void)
/* "Unknown" format. */ hr = IWICImagingFactory_CreateQueryWriter(factory, &GUID_MetadataFormatUnknown, NULL, &query_writer); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (FAILED(hr)) - { - IWICImagingFactory_Release(factory); - return; - }
hr = IWICMetadataQueryWriter_GetLocation(query_writer, ARRAY_SIZE(buff), buff, &len); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -5684,18 +5678,26 @@ 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); - 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); + 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); + }
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); - ok(!wcscmp(str, L"/{}"), "Unexpected string %s.\n", wine_dbgstr_w(str)); - CoTaskMemFree(str); + if (hr == S_OK) + { + 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); @@ -5800,7 +5802,6 @@ if (hr == S_OK)
query_writer = NULL; hr = IWICComponentFactory_CreateQueryWriter(factory, &GUID_MetadataFormatChunktIME, NULL, &query_writer); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IWICComponentFactory_CreateQueryWriterFromReader(factory, (IWICMetadataQueryReader *)query_writer, diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h index 733c1e8c438..5b193bb1b26 100644 --- a/dlls/windowscodecs/wincodecs_private.h +++ b/dlls/windowscodecs/wincodecs_private.h @@ -239,8 +239,10 @@ extern HRESULT IMDReader_CreateInstance(REFIID iid, void **ppv); extern HRESULT GCEReader_CreateInstance(REFIID iid, void **ppv); extern HRESULT APEReader_CreateInstance(REFIID iid, void **ppv); extern HRESULT GifCommentReader_CreateInstance(REFIID iid, void **ppv); -extern HRESULT MetadataQueryReader_CreateInstance(IWICMetadataBlockReader *, IWICMetadataQueryReader **); -extern HRESULT MetadataQueryWriter_CreateInstance(IWICMetadataBlockWriter *, IWICMetadataQueryWriter **); +extern HRESULT MetadataQueryReader_CreateInstanceFromBlockReader(IWICMetadataBlockReader *, IWICMetadataQueryReader **); +extern HRESULT MetadataQueryWriter_CreateInstanceFromBlockWriter(IWICMetadataBlockWriter *, IWICMetadataQueryWriter **); +extern HRESULT MetadataQueryReader_CreateInstance(IWICMetadataReader *, IWICMetadataQueryReader **); +extern HRESULT MetadataQueryWriter_CreateInstance(IWICMetadataWriter *, IWICMetadataQueryWriter **); extern HRESULT stream_initialize_from_filehandle(IWICStream *iface, HANDLE hfile);
static inline const char *debug_wic_rect(const WICRect *rect)