[PATCH 6/7] windowscodecs: find_decoder() should return an error it received from the decoder.

Dmitry Timoshkov dmitry at baikal.ru
Fri Nov 30 00:53:23 CST 2018


If IWICBitmapDecoderInfo::MatchesPattern() has recognized the decoder by the pattern,
and the called IWICBitmapDecoder::Initialize() has failed, an error should be returned
right away instead of trying next codec. This allows report image format related errors
instead of WINCODEC_ERR_COMPONENTNOTFOUND.

Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 dlls/windowscodecs/imgfactory.c | 42 ++++++++++++++++++---------------
 1 file changed, 23 insertions(+), 19 deletions(-)

diff --git a/dlls/windowscodecs/imgfactory.c b/dlls/windowscodecs/imgfactory.c
index b564efc332..fb235fbbe1 100644
--- a/dlls/windowscodecs/imgfactory.c
+++ b/dlls/windowscodecs/imgfactory.c
@@ -131,22 +131,23 @@ static HRESULT WINAPI ImagingFactory_CreateDecoderFromFilename(
     return hr;
 }
 
-static IWICBitmapDecoder *find_decoder(IStream *pIStream, const GUID *pguidVendor,
-                                       WICDecodeOptions metadataOptions)
+static HRESULT find_decoder(IStream *pIStream, const GUID *pguidVendor,
+                            WICDecodeOptions metadataOptions, IWICBitmapDecoder **decoder)
 {
     IEnumUnknown *enumdecoders;
     IUnknown *unkdecoderinfo;
     IWICBitmapDecoderInfo *decoderinfo;
-    IWICBitmapDecoder *decoder = NULL;
     GUID vendor;
     HRESULT res;
     ULONG num_fetched;
     BOOL matches;
 
+    *decoder = NULL;
+
     res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders);
-    if (FAILED(res)) return NULL;
+    if (FAILED(res)) return res;
 
-    while (!decoder)
+    while (!*decoder)
     {
         res = IEnumUnknown_Next(enumdecoders, 1, &unkdecoderinfo, &num_fetched);
 
@@ -171,18 +172,21 @@ static IWICBitmapDecoder *find_decoder(IStream *pIStream, const GUID *pguidVendo
 
                 if (SUCCEEDED(res) && matches)
                 {
-                    res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, &decoder);
+                    res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, decoder);
 
                     /* FIXME: should use QueryCapability to choose a decoder */
 
                     if (SUCCEEDED(res))
                     {
-                        res = IWICBitmapDecoder_Initialize(decoder, pIStream, metadataOptions);
+                        res = IWICBitmapDecoder_Initialize(*decoder, pIStream, metadataOptions);
 
                         if (FAILED(res))
                         {
-                            IWICBitmapDecoder_Release(decoder);
-                            decoder = NULL;
+                            IWICBitmapDecoder_Release(*decoder);
+                            IWICBitmapDecoderInfo_Release(decoderinfo);
+                            IUnknown_Release(unkdecoderinfo);
+                            *decoder = NULL;
+                            return res;
                         }
                     }
                 }
@@ -198,7 +202,7 @@ static IWICBitmapDecoder *find_decoder(IStream *pIStream, const GUID *pguidVendo
 
     IEnumUnknown_Release(enumdecoders);
 
-    return decoder;
+    return WINCODEC_ERR_COMPONENTNOTFOUND;
 }
 
 static HRESULT WINAPI ImagingFactory_CreateDecoderFromStream(
@@ -212,9 +216,9 @@ static HRESULT WINAPI ImagingFactory_CreateDecoderFromStream(
         metadataOptions, ppIDecoder);
 
     if (pguidVendor)
-        decoder = find_decoder(pIStream, pguidVendor, metadataOptions);
+        res = find_decoder(pIStream, pguidVendor, metadataOptions, &decoder);
     if (!decoder)
-        decoder = find_decoder(pIStream, NULL, metadataOptions);
+        res = find_decoder(pIStream, NULL, metadataOptions, &decoder);
 
     if (decoder)
     {
@@ -229,17 +233,17 @@ static HRESULT WINAPI ImagingFactory_CreateDecoderFromStream(
             BYTE data[4];
             ULONG bytesread;
 
-            WARN("failed to load from a stream\n");
+            WARN("failed to load from a stream %#x\n", res);
 
             seek.QuadPart = 0;
-            res = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL);
-            if (SUCCEEDED(res))
-                res = IStream_Read(pIStream, data, 4, &bytesread);
-            if (SUCCEEDED(res))
-                WARN("first %i bytes of stream=%x %x %x %x\n", bytesread, data[0], data[1], data[2], data[3]);
+            if (IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL) == S_OK)
+            {
+                if (IStream_Read(pIStream, data, 4, &bytesread) == S_OK)
+                    WARN("first %i bytes of stream=%x %x %x %x\n", bytesread, data[0], data[1], data[2], data[3]);
+            }
         }
         *ppIDecoder = NULL;
-        return WINCODEC_ERR_COMPONENTNOTFOUND;
+        return res;
     }
 }
 
-- 
2.17.1




More information about the wine-devel mailing list