Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
Although JPEG-XR is already upstream (supposedly) in 6.0, this is a bit of refactoring to make windowscodecs.dll decoder.c, and its unix lib interfaces usable directly from wmphoto.dll, in order to later integrate jxrlib for decoding JPEG-XR images.
We could also duplicate the code, but that doesn't feel very nice.
dlls/windowscodecs/main.c | 37 ------------------------------------- dlls/windowscodecs/stream.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 37 deletions(-)
diff --git a/dlls/windowscodecs/main.c b/dlls/windowscodecs/main.c index e78acc3f34f..efc6bc2c227 100644 --- a/dlls/windowscodecs/main.c +++ b/dlls/windowscodecs/main.c @@ -190,43 +190,6 @@ HRESULT write_source(IWICBitmapFrameEncode *iface, return hr; }
-HRESULT CDECL stream_getsize(IStream *stream, ULONGLONG *size) -{ - STATSTG statstg; - HRESULT hr; - - hr = IStream_Stat(stream, &statstg, STATFLAG_NONAME); - - if (SUCCEEDED(hr)) - *size = statstg.cbSize.QuadPart; - - return hr; -} - -HRESULT CDECL stream_read(IStream *stream, void *buffer, ULONG read, ULONG *bytes_read) -{ - return IStream_Read(stream, buffer, read, bytes_read); -} - -HRESULT CDECL stream_seek(IStream *stream, LONGLONG ofs, DWORD origin, ULONGLONG *new_position) -{ - HRESULT hr; - LARGE_INTEGER ofs_large; - ULARGE_INTEGER pos_large; - - ofs_large.QuadPart = ofs; - hr = IStream_Seek(stream, ofs_large, origin, &pos_large); - if (new_position) - *new_position = pos_large.QuadPart; - - return hr; -} - -HRESULT CDECL stream_write(IStream *stream, const void *buffer, ULONG write, ULONG *bytes_written) -{ - return IStream_Write(stream, buffer, write, bytes_written); -} - HRESULT get_pixelformat_bpp(const GUID *pixelformat, UINT *bpp) { HRESULT hr; diff --git a/dlls/windowscodecs/stream.c b/dlls/windowscodecs/stream.c index 68b9148bd5e..8c36825b641 100644 --- a/dlls/windowscodecs/stream.c +++ b/dlls/windowscodecs/stream.c @@ -1167,3 +1167,40 @@ HRESULT StreamImpl_Create(IWICStream **stream)
return S_OK; } + +HRESULT CDECL stream_getsize(IStream *stream, ULONGLONG *size) +{ + STATSTG statstg; + HRESULT hr; + + hr = IStream_Stat(stream, &statstg, STATFLAG_NONAME); + + if (SUCCEEDED(hr)) + *size = statstg.cbSize.QuadPart; + + return hr; +} + +HRESULT CDECL stream_read(IStream *stream, void *buffer, ULONG read, ULONG *bytes_read) +{ + return IStream_Read(stream, buffer, read, bytes_read); +} + +HRESULT CDECL stream_seek(IStream *stream, LONGLONG ofs, DWORD origin, ULONGLONG *new_position) +{ + HRESULT hr; + LARGE_INTEGER ofs_large; + ULARGE_INTEGER pos_large; + + ofs_large.QuadPart = ofs; + hr = IStream_Seek(stream, ofs_large, origin, &pos_large); + if (new_position) + *new_position = pos_large.QuadPart; + + return hr; +} + +HRESULT CDECL stream_write(IStream *stream, const void *buffer, ULONG write, ULONG *bytes_written) +{ + return IStream_Write(stream, buffer, write, bytes_written); +}
Signed-off-by: Rémi Bernon rbernon@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);
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/windowscodecs/decoder.c | 46 ++++++-------------------- dlls/windowscodecs/libtiff.c | 4 +-- dlls/windowscodecs/wincodecs_private.h | 4 +-- 3 files changed, 15 insertions(+), 39 deletions(-)
diff --git a/dlls/windowscodecs/decoder.c b/dlls/windowscodecs/decoder.c index 3e43fa91114..0af203febf6 100644 --- a/dlls/windowscodecs/decoder.c +++ b/dlls/windowscodecs/decoder.c @@ -634,48 +634,24 @@ static HRESULT WINAPI CommonDecoderFrame_Block_GetReaderByIndex(IWICMetadataBloc offset, length); }
- if (This->metadata_blocks[nIndex].options & DECODER_BLOCK_READER_CLSID) - { - IWICMetadataReader *reader; - IWICPersistStream *persist; - if (SUCCEEDED(hr)) - { - hr = create_instance(&This->metadata_blocks[nIndex].reader_clsid, - &IID_IWICMetadataReader, (void**)&reader); - } - - if (SUCCEEDED(hr)) - { - hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICPersistStream, (void**)&persist); - - if (SUCCEEDED(hr)) - { - hr = IWICPersistStream_LoadEx(persist, (IStream*)stream, NULL, - This->metadata_blocks[nIndex].options & DECODER_BLOCK_OPTION_MASK); - - IWICPersistStream_Release(persist); - } + if (SUCCEEDED(hr)) + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICComponentFactory, (void **)&factory);
- if (SUCCEEDED(hr)) - *ppIMetadataReader = reader; - else - IWICMetadataReader_Release(reader); - } - } - else + if (SUCCEEDED(hr)) { - if (SUCCEEDED(hr)) - hr = ImagingFactory_CreateInstance(&IID_IWICComponentFactory, (void**)&factory); - - if (SUCCEEDED(hr)) - { + if (This->metadata_blocks[nIndex].options & DECODER_BLOCK_FORMAT_GUID) + hr = IWICComponentFactory_CreateMetadataReader(factory, + &This->metadata_blocks[nIndex].format_guid, NULL, + This->metadata_blocks[nIndex].options & DECODER_BLOCK_OPTION_MASK, + (IStream*)stream, ppIMetadataReader); + else hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, &This->parent->decoder_info.block_format, NULL, This->metadata_blocks[nIndex].options & DECODER_BLOCK_OPTION_MASK, (IStream*)stream, ppIMetadataReader);
- IWICComponentFactory_Release(factory); - } + IWICComponentFactory_Release(factory); }
IWICStream_Release(stream); diff --git a/dlls/windowscodecs/libtiff.c b/dlls/windowscodecs/libtiff.c index 6f5cfc53c62..d318ff80095 100644 --- a/dlls/windowscodecs/libtiff.c +++ b/dlls/windowscodecs/libtiff.c @@ -1129,8 +1129,8 @@ static HRESULT CDECL tiff_decoder_get_metadata_blocks(struct decoder *iface, #else result.options = byte_swapped ? WICPersistOptionBigEndian : WICPersistOptionLittleEndian; #endif - result.options |= WICPersistOptionNoCacheStream|DECODER_BLOCK_FULL_STREAM|DECODER_BLOCK_READER_CLSID; - result.reader_clsid = CLSID_WICIfdMetadataReader; + result.options |= WICPersistOptionNoCacheStream|DECODER_BLOCK_FULL_STREAM|DECODER_BLOCK_FORMAT_GUID; + result.format_guid = GUID_MetadataFormatIfd;
*blocks = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(**blocks)); **blocks = result; diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h index 3b20f7d6c24..5085e4c057c 100644 --- a/dlls/windowscodecs/wincodecs_private.h +++ b/dlls/windowscodecs/wincodecs_private.h @@ -284,13 +284,13 @@ struct decoder_frame
#define DECODER_BLOCK_OPTION_MASK 0x0001000F #define DECODER_BLOCK_FULL_STREAM 0x80000000 -#define DECODER_BLOCK_READER_CLSID 0x40000000 +#define DECODER_BLOCK_FORMAT_GUID 0x40000000 struct decoder_block { ULONGLONG offset; ULONGLONG length; DWORD options; - GUID reader_clsid; + GUID format_guid; };
struct decoder
We avoid using CoCreateInstance inside windowscodecs because COM may not be initialized. Applications can use WICCreateImagingFactory_Proxy to get WIC interfaces without initializing COM.
I'm guessing this is for wmphoto. My suggestion would be to use a different create_instance implementation in that library, maybe just a wrapper around CoCreateInstance. We may need to reorganize things so we can share the correct set of functions.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/windowscodecs/decoder.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/dlls/windowscodecs/decoder.c b/dlls/windowscodecs/decoder.c index 0af203febf6..5318e7f2850 100644 --- a/dlls/windowscodecs/decoder.c +++ b/dlls/windowscodecs/decoder.c @@ -433,6 +433,8 @@ static HRESULT WINAPI CommonDecoderFrame_GetMetadataQueryReader(IWICBitmapFrameD IWICMetadataQueryReader **ppIMetadataQueryReader) { CommonDecoderFrame *This = impl_from_IWICBitmapFrameDecode(iface); + IWICComponentFactory* factory; + HRESULT hr;
TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader);
@@ -442,7 +444,16 @@ static HRESULT WINAPI CommonDecoderFrame_GetMetadataQueryReader(IWICBitmapFrameD if (!(This->parent->file_info.flags & WICBitmapDecoderCapabilityCanEnumerateMetadata)) return WINCODEC_ERR_UNSUPPORTEDOPERATION;
- return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, NULL, ppIMetadataQueryReader); + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICComponentFactory, (void **)&factory); + + if (FAILED(hr)) + return hr; + + hr = IWICComponentFactory_CreateQueryReaderFromBlockReader(factory, &This->IWICMetadataBlockReader_iface, ppIMetadataQueryReader); + + IWICComponentFactory_Release(factory); + return hr; }
static HRESULT WINAPI CommonDecoderFrame_GetColorContexts(IWICBitmapFrameDecode *iface,
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/windowscodecs/decoder.c | 29 +++++++++++++++++++++++++++++ dlls/windowscodecs/info.c | 16 ---------------- 2 files changed, 29 insertions(+), 16 deletions(-)
diff --git a/dlls/windowscodecs/decoder.c b/dlls/windowscodecs/decoder.c index 5318e7f2850..3d67733d08f 100644 --- a/dlls/windowscodecs/decoder.c +++ b/dlls/windowscodecs/decoder.c @@ -783,3 +783,32 @@ HRESULT CommonDecoder_CreateInstance(struct decoder *decoder,
return hr; } + +HRESULT get_decoder_info(REFCLSID clsid, IWICBitmapDecoderInfo **info) +{ + IWICImagingFactory* factory; + IWICComponentInfo *compinfo; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICImagingFactory, (void **)&factory); + + if (FAILED(hr)) + return hr; + + hr = IWICImagingFactory_CreateComponentInfo(factory, clsid, &compinfo); + + if (FAILED(hr)) + { + IWICImagingFactory_Release(factory); + return hr; + } + + hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo, + (void **)info); + + IWICComponentInfo_Release(compinfo); + IWICImagingFactory_Release(factory); + + return hr; +} diff --git a/dlls/windowscodecs/info.c b/dlls/windowscodecs/info.c index cbe8aae572d..615756f6672 100644 --- a/dlls/windowscodecs/info.c +++ b/dlls/windowscodecs/info.c @@ -2114,22 +2114,6 @@ void ReleaseComponentInfos(void) IWICComponentInfo_Release(&info->IWICComponentInfo_iface); }
-HRESULT get_decoder_info(REFCLSID clsid, IWICBitmapDecoderInfo **info) -{ - IWICComponentInfo *compinfo; - HRESULT hr; - - hr = CreateComponentInfo(clsid, &compinfo); - if (FAILED(hr)) return hr; - - hr = IWICComponentInfo_QueryInterface(compinfo, &IID_IWICBitmapDecoderInfo, - (void **)info); - - IWICComponentInfo_Release(compinfo); - - return hr; -} - typedef struct { IEnumUnknown IEnumUnknown_iface; LONG ref;
I don't think this makes sense as these functions have nothing to do with the IWICStream implementation.
I would suggest moving these functions, along with configure_write_source and write_source, to a new source file to share between the WIC libraries.