[2/3] windowscodecs: Implement ComponentFactory_CreateMetadataReaderFromContainer.

Vincent Povirk madewokherd at gmail.com
Thu Nov 13 11:45:45 CST 2014


-------------- next part --------------
From 709de407f5e5db5e04910b92882b92ce7843af21 Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Wed, 12 Nov 2014 15:51:09 -0600
Subject: [PATCH 2/3] 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 e9ab77c..2dc6049 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



More information about the wine-patches mailing list