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

View file

@ -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;
res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders);
if (FAILED(res)) return NULL;
*decoder = NULL;
while (!decoder)
res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders);
if (FAILED(res)) return res;
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;
}
}