From: Vincent Povirk Subject: [5/5] windowscodecs: Implement ComponentFactory_CreateMetadataReaderFromContainer. Message-Id: Date: Wed, 12 Nov 2014 16:11:52 -0600 From a3735fa76b9dc568f32561eda4617e216af82138 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Wed, 12 Nov 2014 15:51:09 -0600 Subject: [PATCH 5/7] windowscodecs: Implement ComponentFactory_CreateMetadataReaderFromContainer. --- dlls/windowscodecs/imgfactory.c | 101 +++++++++++++++++++++++++++++++++++- dlls/windowscodecs/tests/metadata.c | 25 +++++---- 2 files changed, 115 insertions(+), 11 deletions(-) diff --git a/dlls/windowscodecs/imgfactory.c b/dlls/windowscodecs/imgfactory.c index e7095dd..444f2e4 100644 --- a/dlls/windowscodecs/imgfactory.c +++ b/dlls/windowscodecs/imgfactory.c @@ -956,9 +956,106 @@ static HRESULT WINAPI ComponentFactory_CreateMetadataReader(IWICComponentFactory static HRESULT WINAPI ComponentFactory_CreateMetadataReaderFromContainer(IWICComponentFactory *iface, REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader) { - FIXME("%p,%s,%s,%x,%p,%p: stub\n", iface, debugstr_guid(format), debugstr_guid(vendor), + HRESULT hr; + IEnumUnknown *enumreaders; + IUnknown *unkreaderinfo; + IWICMetadataReaderInfo *readerinfo; + IWICPersistStream *wicpersiststream; + ULONG num_fetched; + GUID decoder_vendor; + BOOL matches; + LARGE_INTEGER zero; + + TRACE("%p,%s,%s,%x,%p,%p\n", iface, debugstr_guid(format), debugstr_guid(vendor), options, stream, reader); - return E_NOTIMPL; + + if (!format || !stream || !reader) + return E_INVALIDARG; + + zero.QuadPart = 0; + + hr = CreateComponentEnumerator(WICMetadataReader, WICComponentEnumerateDefault, &enumreaders); + if (FAILED(hr)) return hr; + + *reader = NULL; + +start: + while (!*reader) + { + hr = IEnumUnknown_Next(enumreaders, 1, &unkreaderinfo, &num_fetched); + + if (hr == S_OK) + { + hr = IUnknown_QueryInterface(unkreaderinfo, &IID_IWICMetadataReaderInfo, (void**)&readerinfo); + + if (SUCCEEDED(hr)) + { + if (vendor) + { + hr = IWICMetadataReaderInfo_GetVendorGUID(readerinfo, &decoder_vendor); + + if (FAILED(hr) || !IsEqualIID(vendor, &decoder_vendor)) + { + IWICMetadataReaderInfo_Release(readerinfo); + IUnknown_Release(unkreaderinfo); + continue; + } + } + + hr = IWICMetadataReaderInfo_MatchesPattern(readerinfo, format, stream, &matches); + + if (SUCCEEDED(hr) && matches) + { + hr = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL); + + if (SUCCEEDED(hr)) + hr = IWICMetadataReaderInfo_CreateInstance(readerinfo, reader); + + if (SUCCEEDED(hr)) + { + hr = IWICMetadataReader_QueryInterface(*reader, &IID_IWICPersistStream, (void**)&wicpersiststream); + + if (SUCCEEDED(hr)) + { + hr = IWICPersistStream_LoadEx(wicpersiststream, + stream, vendor, options & WICPersistOptionsMask); + + IWICPersistStream_Release(wicpersiststream); + } + + if (FAILED(hr)) + { + IWICMetadataReader_Release(*reader); + *reader = NULL; + } + } + } + + IUnknown_Release(readerinfo); + } + + IUnknown_Release(unkreaderinfo); + } + else + break; + } + + if (!*reader && vendor) + { + vendor = NULL; + IEnumUnknown_Reset(enumreaders); + goto start; + } + + IEnumUnknown_Release(enumreaders); + + if (!*reader && !(options & WICMetadataCreationFailUnknown)) + FIXME("create unknown metadata reader\n"); + + if (*reader) + return S_OK; + else + return WINCODEC_ERR_COMPONENTNOTFOUND; } static HRESULT WINAPI ComponentFactory_CreateMetadataWriter(IWICComponentFactory *iface, diff --git a/dlls/windowscodecs/tests/metadata.c b/dlls/windowscodecs/tests/metadata.c index e42b474..07ef29b 100644 --- a/dlls/windowscodecs/tests/metadata.c +++ b/dlls/windowscodecs/tests/metadata.c @@ -841,17 +841,24 @@ static void test_create_reader(void) stream = create_stream(metadata_tEXt, sizeof(metadata_tEXt)); hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, + NULL, NULL, WICPersistOptionsDefault, + stream, &reader); + ok(hr == E_INVALIDARG, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr); + + hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, + &GUID_ContainerFormatPng, NULL, WICPersistOptionsDefault, + NULL, &reader); + ok(hr == E_INVALIDARG, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr); + + hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, + &GUID_ContainerFormatPng, NULL, WICPersistOptionsDefault, + stream, NULL); + ok(hr == E_INVALIDARG, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr); + + hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, &GUID_ContainerFormatPng, NULL, WICPersistOptionsDefault, stream, &reader); -todo_wine ok(hr == S_OK, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr); - /* NOTE: removed once Wine is fixed */ - if (FAILED(hr)) - { - IStream_Release(stream); - IWICComponentFactory_Release(factory); - return; - } if (SUCCEEDED(hr)) { @@ -869,7 +876,7 @@ todo_wine hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, &GUID_ContainerFormatWmp, NULL, WICPersistOptionsDefault, stream, &reader); - ok(hr == S_OK, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr); + todo_wine ok(hr == S_OK, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { -- 2.1.0