[PATCH 2/5] windowscodecs: Implement IWICComponentFactory_CreateMetadataReader.

Rémi Bernon rbernon at codeweavers.com
Thu Jan 14 15:20:52 CST 2021


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/windowscodecs/imgfactory.c     | 108 ++++++++++++++++++++++------
 dlls/windowscodecs/tests/metadata.c |  50 +++++++++++++
 2 files changed, 138 insertions(+), 20 deletions(-)

diff --git a/dlls/windowscodecs/imgfactory.c b/dlls/windowscodecs/imgfactory.c
index df180681af1..4142240c7f8 100644
--- a/dlls/windowscodecs/imgfactory.c
+++ b/dlls/windowscodecs/imgfactory.c
@@ -1246,16 +1246,8 @@ static HRESULT WINAPI ComponentFactory_CreateQueryWriterFromReader(IWICComponent
     return IWICImagingFactory2_CreateQueryWriterFromReader(&This->IWICImagingFactory2_iface, reader, vendor, writer);
 }
 
-static HRESULT WINAPI ComponentFactory_CreateMetadataReader(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),
-        options, stream, reader);
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI ComponentFactory_CreateMetadataReaderFromContainer(IWICComponentFactory *iface,
-        REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader)
+static HRESULT create_metadata_reader(IWICComponentFactory *iface, REFGUID metadata_format, REFGUID container_format,
+        const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader)
 {
     HRESULT hr;
     IEnumUnknown *enumreaders;
@@ -1263,15 +1255,10 @@ static HRESULT WINAPI ComponentFactory_CreateMetadataReaderFromContainer(IWICCom
     IWICMetadataReaderInfo *readerinfo;
     IWICPersistStream *wicpersiststream;
     ULONG num_fetched;
-    GUID decoder_vendor;
+    GUID guid, *guids;
     BOOL matches;
     LARGE_INTEGER zero;
-
-    TRACE("%p,%s,%s,%x,%p,%p\n", iface, debugstr_guid(format), debugstr_guid(vendor),
-        options, stream, reader);
-
-    if (!format || !stream || !reader)
-        return E_INVALIDARG;
+    UINT count, i;
 
     zero.QuadPart = 0;
 
@@ -1293,9 +1280,9 @@ start:
             {
                 if (vendor)
                 {
-                    hr = IWICMetadataReaderInfo_GetVendorGUID(readerinfo, &decoder_vendor);
+                    hr = IWICMetadataReaderInfo_GetVendorGUID(readerinfo, &guid);
 
-                    if (FAILED(hr) || !IsEqualIID(vendor, &decoder_vendor))
+                    if (FAILED(hr) || !IsEqualIID(vendor, &guid))
                     {
                         IWICMetadataReaderInfo_Release(readerinfo);
                         IUnknown_Release(unkreaderinfo);
@@ -1303,7 +1290,63 @@ start:
                     }
                 }
 
-                hr = IWICMetadataReaderInfo_MatchesPattern(readerinfo, format, stream, &matches);
+                if (metadata_format)
+                {
+                    hr = IWICMetadataReaderInfo_GetMetadataFormat(readerinfo, &guid);
+
+                    if (FAILED(hr) || !IsEqualIID(metadata_format, &guid))
+                    {
+                        IWICMetadataReaderInfo_Release(readerinfo);
+                        IUnknown_Release(unkreaderinfo);
+                        continue;
+                    }
+
+                    if (!stream)
+                    {
+                        hr = IWICMetadataReaderInfo_CreateInstance(readerinfo, reader);
+                        break;
+                    }
+
+                    hr = IWICMetadataReaderInfo_GetContainerFormats(readerinfo, 0, NULL, &count);
+
+                    if (FAILED(hr) || !count)
+                    {
+                        IWICMetadataReaderInfo_Release(readerinfo);
+                        IUnknown_Release(unkreaderinfo);
+                        continue;
+                    }
+
+                    guids = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*guids));
+
+                    if (!guids)
+                    {
+                        IWICMetadataReaderInfo_Release(readerinfo);
+                        IUnknown_Release(unkreaderinfo);
+                        continue;
+                    }
+
+                    hr = IWICMetadataReaderInfo_GetContainerFormats(readerinfo, count, guids, &count);
+
+                    if (FAILED(hr) || !count)
+                    {
+                        HeapFree(GetProcessHeap(), 0, guids);
+                        IWICMetadataReaderInfo_Release(readerinfo);
+                        IUnknown_Release(unkreaderinfo);
+                        continue;
+                    }
+
+                    for (i = 0; i < count; ++i)
+                    {
+                        hr = IWICMetadataReaderInfo_MatchesPattern(readerinfo, &guids[i], stream, &matches);
+                        if (SUCCEEDED(hr) && matches) break;
+                    }
+
+                    HeapFree(GetProcessHeap(), 0, guids);
+                }
+                else
+                {
+                    hr = IWICMetadataReaderInfo_MatchesPattern(readerinfo, container_format, stream, &matches);
+                }
 
                 if (SUCCEEDED(hr) && matches)
                 {
@@ -1380,6 +1423,31 @@ start:
         return S_OK;
     else
         return WINCODEC_ERR_COMPONENTNOTFOUND;
+
+}
+
+static HRESULT WINAPI ComponentFactory_CreateMetadataReader(IWICComponentFactory *iface,
+        REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader)
+{
+    TRACE("%p,%s,%s,%x,%p,%p\n", iface, debugstr_guid(format), debugstr_guid(vendor),
+        options, stream, reader);
+
+    if (!format || !reader)
+        return E_INVALIDARG;
+
+    return create_metadata_reader(iface, format, NULL, vendor, options, stream, reader);
+}
+
+static HRESULT WINAPI ComponentFactory_CreateMetadataReaderFromContainer(IWICComponentFactory *iface,
+        REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader)
+{
+    TRACE("%p,%s,%s,%x,%p,%p\n", iface, debugstr_guid(format), debugstr_guid(vendor),
+        options, stream, reader);
+
+    if (!format || !stream || !reader)
+        return E_INVALIDARG;
+
+    return create_metadata_reader(iface, NULL, format, vendor, options, stream, reader);
 }
 
 static HRESULT WINAPI ComponentFactory_CreateMetadataWriter(IWICComponentFactory *iface,
diff --git a/dlls/windowscodecs/tests/metadata.c b/dlls/windowscodecs/tests/metadata.c
index a955702c82c..8183f53cf33 100644
--- a/dlls/windowscodecs/tests/metadata.c
+++ b/dlls/windowscodecs/tests/metadata.c
@@ -967,6 +967,56 @@ static void test_create_reader(void)
 
     stream = create_stream(metadata_tEXt, sizeof(metadata_tEXt));
 
+    hr = IWICComponentFactory_CreateMetadataReader(factory,
+        NULL, NULL, WICPersistOptionDefault,
+        stream, &reader);
+    ok(hr == E_INVALIDARG, "CreateMetadataReader failed, hr=%x\n", hr);
+
+    hr = IWICComponentFactory_CreateMetadataReader(factory,
+        &GUID_MetadataFormatChunktEXt, NULL, WICPersistOptionDefault,
+        stream, NULL);
+    ok(hr == E_INVALIDARG, "CreateMetadataReader failed, hr=%x\n", hr);
+
+    hr = IWICComponentFactory_CreateMetadataReader(factory,
+        &GUID_MetadataFormatChunktEXt, NULL, WICPersistOptionDefault,
+        NULL, &reader);
+    ok(hr == S_OK, "CreateMetadataReader failed, hr=%x\n", hr);
+
+    if (SUCCEEDED(hr))
+    {
+        hr = IWICMetadataReader_GetCount(reader, &count);
+        ok(hr == S_OK, "GetCount failed, hr=%x\n", hr);
+        ok(count == 0, "unexpected count %i\n", count);
+
+        hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
+        ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr);
+        ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktEXt), "unexpected format %s\n", wine_dbgstr_guid(&format));
+
+        IWICMetadataReader_Release(reader);
+    }
+
+    hr = IWICComponentFactory_CreateMetadataReader(factory,
+        &GUID_MetadataFormatChunktEXt, NULL, WICPersistOptionDefault,
+        stream, &reader);
+    ok(hr == S_OK, "CreateMetadataReader failed, hr=%x\n", hr);
+
+    if (SUCCEEDED(hr))
+    {
+        hr = IWICMetadataReader_GetCount(reader, &count);
+        ok(hr == S_OK, "GetCount failed, hr=%x\n", hr);
+        ok(count == 1, "unexpected count %i\n", count);
+
+        hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
+        ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr);
+        ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktEXt), "unexpected format %s\n", wine_dbgstr_guid(&format));
+
+        IWICMetadataReader_Release(reader);
+    }
+
+    IStream_Release(stream);
+
+    stream = create_stream(metadata_tEXt, sizeof(metadata_tEXt));
+
     hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory,
         NULL, NULL, WICPersistOptionDefault,
         stream, &reader);
-- 
2.30.0




More information about the wine-devel mailing list