windowscodecs: find_decoder() should return an error it received from the decoder.

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@baikal.ru>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Dmitry Timoshkov 2018-11-30 09:53:23 +03:00 committed by Alexandre Julliard
parent 5a4f5ce8b4
commit 957d1097d2
1 changed files with 24 additions and 20 deletions

View File

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