From 197ed01e95f242af87a3905d83c2cd22326a7668 Mon Sep 17 00:00:00 2001 From: Mikhail Tyukin Date: Sun, 26 Jan 2025 12:59:50 -0500 Subject: [PATCH] [WINDOWSCODECS][WINDOWSCODECSEXT] Sync to wine-10.0 (#7665) --- dll/win32/windowscodecs/CMakeLists.txt | 19 +- dll/win32/windowscodecs/bitmap.c | 55 +- dll/win32/windowscodecs/bmpdecode.c | 82 +- dll/win32/windowscodecs/bmpencode.c | 44 +- dll/win32/windowscodecs/clipper.c | 12 +- dll/win32/windowscodecs/clsfactory.c | 24 +- dll/win32/windowscodecs/colorcontext.c | 24 +- dll/win32/windowscodecs/colortransform.c | 10 +- dll/win32/windowscodecs/converter.c | 276 +- dll/win32/windowscodecs/ddsformat.c | 2162 ++++++++++++ dll/win32/windowscodecs/decoder.c | 811 +++++ dll/win32/windowscodecs/encoder.c | 903 +++++ dll/win32/windowscodecs/fliprotate.c | 14 +- dll/win32/windowscodecs/gifformat.c | 525 +-- dll/win32/windowscodecs/icnsformat.c | 743 ---- dll/win32/windowscodecs/icoformat.c | 40 +- dll/win32/windowscodecs/imgfactory.c | 508 ++- dll/win32/windowscodecs/info.c | 309 +- dll/win32/windowscodecs/jpegformat.c | 1562 --------- dll/win32/windowscodecs/libjpeg.c | 662 ++++ dll/win32/windowscodecs/libpng.c | 842 +++++ dll/win32/windowscodecs/libtiff.c | 1352 +++++++ dll/win32/windowscodecs/main.c | 260 +- dll/win32/windowscodecs/metadatahandler.c | 295 +- dll/win32/windowscodecs/metadataquery.c | 580 +-- dll/win32/windowscodecs/palette.c | 56 +- dll/win32/windowscodecs/pngformat.c | 2113 +---------- dll/win32/windowscodecs/precomp.h | 3 +- dll/win32/windowscodecs/propertybag.c | 33 +- dll/win32/windowscodecs/proxy.c | 2 - dll/win32/windowscodecs/regsvr.c | 207 +- dll/win32/windowscodecs/scaler.c | 28 +- dll/win32/windowscodecs/stream.c | 108 +- dll/win32/windowscodecs/tgaformat.c | 34 +- dll/win32/windowscodecs/tiffformat.c | 2385 ------------- dll/win32/windowscodecs/ungif.c | 93 +- dll/win32/windowscodecs/ungif.h | 7 +- dll/win32/windowscodecs/uuid.c | 36 + dll/win32/windowscodecs/wincodecs_common.c | 211 ++ dll/win32/windowscodecs/wincodecs_common.h | 214 ++ dll/win32/windowscodecs/wincodecs_private.h | 323 +- .../windowscodecs/windowscodecs_wincodec.idl | 32 +- dll/win32/windowscodecsext/main.c | 18 - media/doc/WINESYNC.txt | 4 +- .../winetests/windowscodecs/CMakeLists.txt | 8 +- .../rostests/winetests/windowscodecs/bitmap.c | 460 +-- .../winetests/windowscodecs/bmpformat.c | 647 +++- .../winetests/windowscodecs/converter.c | 578 ++- .../winetests/windowscodecs/ddsformat.c | 1579 +++++++++ .../winetests/windowscodecs/gifformat.c | 198 +- .../winetests/windowscodecs/icoformat.c | 20 +- .../rostests/winetests/windowscodecs/info.c | 263 +- .../winetests/windowscodecs/jpegformat.c | 38 +- .../winetests/windowscodecs/metadata.c | 3102 ++++++++++++----- .../winetests/windowscodecs/palette.c | 154 +- .../winetests/windowscodecs/pngformat.c | 203 +- .../winetests/windowscodecs/propertybag.c | 56 +- .../rostests/winetests/windowscodecs/stream.c | 438 +-- .../winetests/windowscodecs/testlist.c | 4 + .../winetests/windowscodecs/tiffformat.c | 344 +- .../winetests/windowscodecs/wmpformat.c | 182 + .../winetests/windowscodecsext/CMakeLists.txt | 1 + .../winetests/windowscodecsext/transform.c | 12 +- sdk/include/psdk/CMakeLists.txt | 1 + sdk/include/psdk/dxgiformat.idl | 145 + sdk/include/psdk/wincodec.idl | 137 + sdk/include/psdk/wincodecsdk.idl | 82 + sdk/tools/winesync/windowscodecs.cfg | 10 + 68 files changed, 16264 insertions(+), 10419 deletions(-) create mode 100644 dll/win32/windowscodecs/ddsformat.c create mode 100644 dll/win32/windowscodecs/decoder.c create mode 100644 dll/win32/windowscodecs/encoder.c delete mode 100644 dll/win32/windowscodecs/icnsformat.c delete mode 100644 dll/win32/windowscodecs/jpegformat.c create mode 100644 dll/win32/windowscodecs/libjpeg.c create mode 100644 dll/win32/windowscodecs/libpng.c create mode 100644 dll/win32/windowscodecs/libtiff.c delete mode 100644 dll/win32/windowscodecs/tiffformat.c create mode 100644 dll/win32/windowscodecs/uuid.c create mode 100644 dll/win32/windowscodecs/wincodecs_common.c create mode 100644 dll/win32/windowscodecs/wincodecs_common.h create mode 100644 modules/rostests/winetests/windowscodecs/ddsformat.c create mode 100644 modules/rostests/winetests/windowscodecs/wmpformat.c create mode 100644 sdk/include/psdk/dxgiformat.idl create mode 100644 sdk/tools/winesync/windowscodecs.cfg diff --git a/dll/win32/windowscodecs/CMakeLists.txt b/dll/win32/windowscodecs/CMakeLists.txt index ee7ff716e3b..c8e043b4979 100644 --- a/dll/win32/windowscodecs/CMakeLists.txt +++ b/dll/win32/windowscodecs/CMakeLists.txt @@ -1,12 +1,12 @@ add_definitions( -D__WINESRC__ - -D__ROS_LONG64__ -DENTRY_PREFIX=WIC_ -DPROXY_DELEGATION -DWINE_REGISTER_DLL) remove_definitions(-D_WIN32_WINNT=0x502) +remove_definitions(-D_CRT_NON_CONFORMING_SWPRINTFS) add_definitions(-D_WIN32_WINNT=0x600) include_directories( @@ -27,13 +27,17 @@ list(APPEND SOURCE colorcontext.c colortransform.c converter.c + ddsformat.c + decoder.c + encoder.c fliprotate.c gifformat.c - icnsformat.c icoformat.c imgfactory.c info.c - jpegformat.c + libjpeg.c + libpng.c + libtiff.c main.c metadatahandler.c metadataquery.c @@ -45,8 +49,9 @@ list(APPEND SOURCE scaler.c stream.c tgaformat.c - tiffformat.c - ungif.c) + ungif.c + uuid.c + wincodecs_common.c) if(MSVC) if(ARCH STREQUAL "i386") @@ -79,7 +84,7 @@ if(MSVC) endif() set_module_type(windowscodecs win32dll) -target_link_libraries(windowscodecs wine uuid ${PSEH_LIB}) -add_importlibs(windowscodecs ole32 oleaut32 rpcrt4 shlwapi user32 gdi32 advapi32 advapi32_vista propsys msvcrt kernel32 ntdll) +target_link_libraries(windowscodecs wine uuid ${PSEH_LIB} oldnames) +add_importlibs(windowscodecs libjpeg libpng libtiff ole32 oleaut32 rpcrt4 shlwapi user32 gdi32 advapi32 advapi32_vista propsys msvcrt kernel32 ntdll) add_pch(windowscodecs precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET windowscodecs DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/windowscodecs/bitmap.c b/dll/win32/windowscodecs/bitmap.c index 7959da6911d..dee3f28d5d7 100644 --- a/dll/win32/windowscodecs/bitmap.c +++ b/dll/win32/windowscodecs/bitmap.c @@ -17,10 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef __REACTOS__ -#include "config.h" -#endif - #include #define COBJMACROS @@ -34,6 +30,9 @@ #include "wine/asm.h" #include "wine/debug.h" +#include "initguid.h" +DEFINE_GUID(IID_CMetaBitmapRenderTarget, 0x0ccd7824,0xdc16,0x4d09,0xbc,0xa8,0x6b,0x09,0xc4,0xef,0x55,0x35); + WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); /* WARNING: .NET Media Integration Layer (MIL) directly dereferences @@ -82,11 +81,6 @@ static inline BitmapImpl *impl_from_IMILUnknown1(IMILUnknown1 *iface) return CONTAINING_RECORD(iface, BitmapImpl, IMILUnknown1_iface); } -static inline BitmapImpl *impl_from_IMILUnknown2(IMILUnknown2 *iface) -{ - return CONTAINING_RECORD(iface, BitmapImpl, IMILUnknown2_iface); -} - static inline BitmapLockImpl *impl_from_IWICBitmapLock(IWICBitmapLock *iface) { return CONTAINING_RECORD(iface, BitmapLockImpl, IWICBitmapLock_iface); @@ -155,7 +149,7 @@ static ULONG WINAPI BitmapLockImpl_AddRef(IWICBitmapLock *iface) BitmapLockImpl *This = impl_from_IWICBitmapLock(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -165,13 +159,13 @@ static ULONG WINAPI BitmapLockImpl_Release(IWICBitmapLock *iface) BitmapLockImpl *This = impl_from_IWICBitmapLock(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { BitmapImpl_ReleaseLock(This->parent); IWICBitmap_Release(&This->parent->IWICBitmap_iface); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -262,7 +256,10 @@ static HRESULT WINAPI BitmapImpl_QueryInterface(IWICBitmap *iface, REFIID iid, } else { - FIXME("unknown interface %s\n", debugstr_guid(iid)); + if (IsEqualIID(&IID_CMetaBitmapRenderTarget, iid)) + WARN("Ignoring interface %s\n", debugstr_guid(iid)); + else + FIXME("unknown interface %s\n", debugstr_guid(iid)); *ppv = NULL; return E_NOINTERFACE; } @@ -276,7 +273,7 @@ static ULONG WINAPI BitmapImpl_AddRef(IWICBitmap *iface) BitmapImpl *This = impl_from_IWICBitmap(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -286,7 +283,7 @@ static ULONG WINAPI BitmapImpl_Release(IWICBitmap *iface) BitmapImpl *This = impl_from_IWICBitmap(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { @@ -296,8 +293,8 @@ static ULONG WINAPI BitmapImpl_Release(IWICBitmap *iface) if (This->view) UnmapViewOfFile(This->view); else - HeapFree(GetProcessHeap(), 0, This->data); - HeapFree(GetProcessHeap(), 0, This); + free(This->data); + free(This); } return ref; @@ -378,7 +375,7 @@ static HRESULT WINAPI BitmapImpl_Lock(IWICBitmap *iface, const WICRect *prcLock, BitmapLockImpl *result; WICRect rc; - TRACE("(%p,%s,%x,%p)\n", iface, debug_wic_rect(prcLock), flags, ppILock); + TRACE("(%p,%s,%lx,%p)\n", iface, debug_wic_rect(prcLock), flags, ppILock); if (!(flags & (WICBitmapLockRead|WICBitmapLockWrite)) || !ppILock) return E_INVALIDARG; @@ -401,13 +398,13 @@ static HRESULT WINAPI BitmapImpl_Lock(IWICBitmap *iface, const WICRect *prcLock, return E_FAIL; } - result = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapLockImpl)); + result = malloc(sizeof(BitmapLockImpl)); if (!result) return E_OUTOFMEMORY; if (!BitmapImpl_AcquireLock(This, flags & WICBitmapLockWrite)) { - HeapFree(GetProcessHeap(), 0, result); + free(result); return WINCODEC_ERR_ALREADYLOCKED; } @@ -605,7 +602,7 @@ static HRESULT WINAPI IMILBitmapImpl_unknown1(IMILBitmap *iface, void **ppv) static HRESULT WINAPI IMILBitmapImpl_Lock(IMILBitmap *iface, const WICRect *rc, DWORD flags, IWICBitmapLock **lock) { BitmapImpl *This = impl_from_IMILBitmap(iface); - TRACE("(%p,%p,%08x,%p)\n", iface, rc, flags, lock); + TRACE("(%p,%p,%08lx,%p)\n", iface, rc, flags, lock); return IWICBitmap_Lock(&This->IWICBitmap_iface, rc, flags, lock); } @@ -675,7 +672,7 @@ static ULONG WINAPI IMILUnknown1Impl_Release(IMILUnknown1 *iface) return IWICBitmap_Release(&This->IWICBitmap_iface); } -DECLSPEC_HIDDEN void WINAPI IMILUnknown1Impl_unknown1(IMILUnknown1 *iface, void *arg) +void WINAPI IMILUnknown1Impl_unknown1(IMILUnknown1 *iface, void *arg) { FIXME("(%p,%p): stub\n", iface, arg); } @@ -686,7 +683,7 @@ static HRESULT WINAPI IMILUnknown1Impl_unknown2(IMILUnknown1 *iface, void *arg1, return E_NOTIMPL; } -DECLSPEC_HIDDEN HRESULT WINAPI IMILUnknown1Impl_unknown3(IMILUnknown1 *iface, void *arg) +HRESULT WINAPI IMILUnknown1Impl_unknown3(IMILUnknown1 *iface, void *arg) { FIXME("(%p,%p): stub\n", iface, arg); return E_NOTIMPL; @@ -716,7 +713,7 @@ static HRESULT WINAPI IMILUnknown1Impl_unknown7(IMILUnknown1 *iface, void *arg) return E_NOTIMPL; } -DECLSPEC_HIDDEN HRESULT WINAPI IMILUnknown1Impl_unknown8(IMILUnknown1 *iface) +HRESULT WINAPI IMILUnknown1Impl_unknown8(IMILUnknown1 *iface) { FIXME("(%p): stub\n", iface); return E_NOTIMPL; @@ -808,13 +805,13 @@ HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight, UINT stride, UINT datasiz if (datasize < stride * uiHeight) return WINCODEC_ERR_INSUFFICIENTBUFFER; if (stride < ((bpp*uiWidth)+7)/8) return E_INVALIDARG; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapImpl)); + This = malloc(sizeof(BitmapImpl)); if (!This) return E_OUTOFMEMORY; if (view) data = (BYTE *)view + offset; - else if (!(data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, datasize))) + else if (!(data = calloc(1, datasize))) { - HeapFree(GetProcessHeap(), 0, This); + free(This); return E_OUTOFMEMORY; } @@ -835,7 +832,11 @@ HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight, UINT stride, UINT datasiz This->bpp = bpp; memcpy(&This->pixelformat, pixelFormat, sizeof(GUID)); This->dpix = This->dpiy = 0.0; +#ifdef __REACTOS__ InitializeCriticalSection(&This->cs); +#else + InitializeCriticalSectionEx(&This->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BitmapImpl.lock"); *ppIBitmap = &This->IWICBitmap_iface; diff --git a/dll/win32/windowscodecs/bmpdecode.c b/dll/win32/windowscodecs/bmpdecode.c index 5ee4ac38ccb..9eb74b3d7cc 100644 --- a/dll/win32/windowscodecs/bmpdecode.c +++ b/dll/win32/windowscodecs/bmpdecode.c @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #include @@ -226,9 +224,9 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, int i; count = 1 << bch->bcBitCount; - wiccolors = HeapAlloc(GetProcessHeap(), 0, sizeof(WICColor) * count); + wiccolors = malloc(sizeof(WICColor) * count); tablesize = sizeof(RGBTRIPLE) * count; - bgrcolors = HeapAlloc(GetProcessHeap(), 0, tablesize); + bgrcolors = malloc(tablesize); if (!wiccolors || !bgrcolors) { hr = E_OUTOFMEMORY; @@ -274,7 +272,7 @@ static HRESULT WINAPI BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, count = min(This->bih.bV5ClrUsed, 1 << This->bih.bV5BitCount); tablesize = sizeof(WICColor) * count; - wiccolors = HeapAlloc(GetProcessHeap(), 0, tablesize); + wiccolors = malloc(tablesize); if (!wiccolors) { hr = E_OUTOFMEMORY; @@ -310,8 +308,8 @@ end: if (SUCCEEDED(hr)) hr = IWICPalette_InitializeCustom(pIPalette, wiccolors, count); - HeapFree(GetProcessHeap(), 0, wiccolors); - HeapFree(GetProcessHeap(), 0, bgrcolors); + free(wiccolors); + free(bgrcolors); return hr; } @@ -388,7 +386,7 @@ static HRESULT BmpFrameDecode_ReadUncompressed(BmpDecoder* This) bytesperrow = (((width * This->bitsperpixel)+31)/32)*4; datasize = bytesperrow * height; - This->imagedata = HeapAlloc(GetProcessHeap(), 0, datasize); + This->imagedata = malloc(datasize); if (!This->imagedata) return E_OUTOFMEMORY; offbits.QuadPart = This->image_offset; @@ -411,12 +409,45 @@ static HRESULT BmpFrameDecode_ReadUncompressed(BmpDecoder* This) return S_OK; fail: - HeapFree(GetProcessHeap(), 0, This->imagedata); + free(This->imagedata); This->imagedata = NULL; if (SUCCEEDED(hr)) hr = E_FAIL; return hr; } +static HRESULT BmpFrameDecode_ReadABGRasBGR(BmpDecoder* This) +{ + UINT x, y, width, height; + BYTE *pixel; + HRESULT hr; + + hr = IWICBitmapFrameDecode_GetSize(&This->IWICBitmapFrameDecode_iface, &width, &height); + + if (SUCCEEDED(hr)) + { + hr = BmpFrameDecode_ReadUncompressed(This); + } + + if (SUCCEEDED(hr)) + { + for (y = 0; y < height; y++) + { + pixel = This->imagedatastart + This->stride * (INT)y; + + for (x = 0; x < width; x++) + { + pixel[0] = pixel[1]; + pixel[1] = pixel[2]; + pixel[2] = pixel[3]; + pixel[3] = 0; + pixel += 4; + } + } + } + + return hr; +} + static HRESULT BmpFrameDecode_ReadRGB8(BmpDecoder* This) { HRESULT hr; @@ -482,7 +513,7 @@ static HRESULT BmpFrameDecode_ReadRLE8(BmpDecoder* This) else palettesize = 4 * 256; - This->imagedata = HeapAlloc(GetProcessHeap(), 0, datasize); + This->imagedata = malloc(datasize); if (!This->imagedata) { hr = E_OUTOFMEMORY; @@ -578,7 +609,7 @@ end: return S_OK; fail: - HeapFree(GetProcessHeap(), 0, This->imagedata); + free(This->imagedata); This->imagedata = NULL; if (SUCCEEDED(hr)) hr = E_FAIL; return hr; @@ -606,7 +637,7 @@ static HRESULT BmpFrameDecode_ReadRLE4(BmpDecoder* This) else palettesize = 4 * 16; - This->imagedata = HeapAlloc(GetProcessHeap(), 0, datasize); + This->imagedata = malloc(datasize); if (!This->imagedata) { hr = E_OUTOFMEMORY; @@ -718,7 +749,7 @@ end: return S_OK; fail: - HeapFree(GetProcessHeap(), 0, This->imagedata); + free(This->imagedata); This->imagedata = NULL; if (SUCCEEDED(hr)) hr = E_FAIL; return hr; @@ -744,7 +775,7 @@ static const struct bitfields_format bitfields_formats[] = { {16,0xf800,0x7e0,0x1f,0,&GUID_WICPixelFormat16bppBGR565,BmpFrameDecode_ReadUncompressed}, {32,0xff0000,0xff00,0xff,0,&GUID_WICPixelFormat32bppBGR,BmpFrameDecode_ReadUncompressed}, {32,0xff0000,0xff00,0xff,0xff000000,&GUID_WICPixelFormat32bppBGRA,BmpFrameDecode_ReadUncompressed}, - {32,0xff000000,0xff0000,0xff00,0xff,&GUID_WICPixelFormat32bppRGBA,BmpFrameDecode_ReadUncompressed}, + {32,0xff000000,0xff0000,0xff00,0xff,&GUID_WICPixelFormat32bppBGR,BmpFrameDecode_ReadABGRasBGR}, {32,0xff,0xff00,0xff0000,0,&GUID_WICPixelFormat32bppBGR,BmpFrameDecode_ReadRGB8}, {0} }; @@ -861,7 +892,7 @@ static HRESULT BmpDecoder_ReadHeaders(BmpDecoder* This, IStream *stream) } else /* struct is compatible with BITMAPINFOHEADER */ { - TRACE("bitmap header=%i compression=%i depth=%i\n", This->bih.bV5Size, This->bih.bV5Compression, This->bih.bV5BitCount); + TRACE("bitmap header=%li compression=%li depth=%i\n", This->bih.bV5Size, This->bih.bV5Compression, This->bih.bV5BitCount); switch(This->bih.bV5Compression) { case BI_RGB: @@ -935,7 +966,7 @@ static HRESULT BmpDecoder_ReadHeaders(BmpDecoder* This, IStream *stream) { This->read_data_func = BmpFrameDecode_ReadUncompressed; This->pixelformat = &GUID_WICPixelFormatUndefined; - FIXME("unsupported bitfields type depth=%i red=%x green=%x blue=%x alpha=%x\n", + FIXME("unsupported bitfields type depth=%i red=%lx green=%lx blue=%lx alpha=%lx\n", This->bih.bV5BitCount, This->bih.bV5RedMask, This->bih.bV5GreenMask, This->bih.bV5BlueMask, This->bih.bV5AlphaMask); } break; @@ -944,7 +975,7 @@ static HRESULT BmpDecoder_ReadHeaders(BmpDecoder* This, IStream *stream) This->bitsperpixel = 0; This->read_data_func = BmpFrameDecode_ReadUnsupported; This->pixelformat = &GUID_WICPixelFormatUndefined; - FIXME("unsupported bitmap type header=%i compression=%i depth=%i\n", This->bih.bV5Size, This->bih.bV5Compression, This->bih.bV5BitCount); + FIXME("unsupported bitmap type header=%li compression=%li depth=%i\n", This->bih.bV5Size, This->bih.bV5Compression, This->bih.bV5BitCount); break; } } @@ -999,7 +1030,7 @@ static ULONG WINAPI BmpDecoder_AddRef(IWICBitmapDecoder *iface) BmpDecoder *This = impl_from_IWICBitmapDecoder(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -1009,15 +1040,15 @@ static ULONG WINAPI BmpDecoder_Release(IWICBitmapDecoder *iface) BmpDecoder *This = impl_from_IWICBitmapDecoder(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { if (This->stream) IStream_Release(This->stream); - HeapFree(GetProcessHeap(), 0, This->imagedata); + free(This->imagedata); This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -1155,7 +1186,7 @@ static HRESULT BmpDecoder_Create(int packed, int icoframe, BmpDecoder **ppDecode { BmpDecoder *This; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpDecoder)); + This = malloc(sizeof(BmpDecoder)); if (!This) return E_OUTOFMEMORY; This->IWICBitmapDecoder_iface.lpVtbl = &BmpDecoder_Vtbl; @@ -1164,7 +1195,11 @@ static HRESULT BmpDecoder_Create(int packed, int icoframe, BmpDecoder **ppDecode This->initialized = FALSE; This->stream = NULL; This->imagedata = NULL; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BmpDecoder.lock"); This->packed = packed; This->icoframe = icoframe; @@ -1220,7 +1255,8 @@ void BmpDecoder_FindIconMask(BmpDecoder *This, ULONG *mask_offset, int *topdown) if (This->read_data_func == BmpFrameDecode_ReadUncompressed) { /* RGB or BITFIELDS data */ - ULONG width, height, bytesperrow, datasize; + UINT width, height; + ULONG bytesperrow, datasize; IWICBitmapFrameDecode_GetSize(&This->IWICBitmapFrameDecode_iface, &width, &height); bytesperrow = (((width * This->bitsperpixel)+31)/32)*4; datasize = bytesperrow * height; diff --git a/dll/win32/windowscodecs/bmpencode.c b/dll/win32/windowscodecs/bmpencode.c index 3b77517a8d9..28da4a5e6d2 100644 --- a/dll/win32/windowscodecs/bmpencode.c +++ b/dll/win32/windowscodecs/bmpencode.c @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -56,10 +54,7 @@ static const struct bmp_pixelformat formats[] = { {&GUID_WICPixelFormat16bppBGR555, 16, 0, BI_RGB}, {&GUID_WICPixelFormat16bppBGR565, 16, 0, BI_BITFIELDS, 0xf800, 0x7e0, 0x1f, 0}, {&GUID_WICPixelFormat32bppBGR, 32, 0, BI_RGB}, -#if 0 - /* Windows doesn't seem to support this one. */ {&GUID_WICPixelFormat32bppBGRA, 32, 0, BI_BITFIELDS, 0xff0000, 0xff00, 0xff, 0xff000000}, -#endif {NULL} }; @@ -79,8 +74,6 @@ typedef struct BmpFrameEncode { BOOL committed; } BmpFrameEncode; -static const WCHAR wszEnableV5Header32bppBGRA[] = {'E','n','a','b','l','e','V','5','H','e','a','d','e','r','3','2','b','p','p','B','G','R','A',0}; - static inline BmpFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface) { return CONTAINING_RECORD(iface, BmpFrameEncode, IWICBitmapFrameEncode_iface); @@ -114,7 +107,7 @@ static ULONG WINAPI BmpFrameEncode_AddRef(IWICBitmapFrameEncode *iface) BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -124,13 +117,13 @@ static ULONG WINAPI BmpFrameEncode_Release(IWICBitmapFrameEncode *iface) BmpFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { if (This->stream) IStream_Release(This->stream); - HeapFree(GetProcessHeap(), 0, This->bits); - HeapFree(GetProcessHeap(), 0, This); + free(This->bits); + free(This); } return ref; @@ -253,7 +246,7 @@ static HRESULT BmpFrameEncode_AllocateBits(BmpFrameEncode *This) return WINCODEC_ERR_WRONGSTATE; This->stride = (((This->width * This->format->bpp)+31)/32)*4; - This->bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->stride * This->height); + This->bits = calloc(This->stride, This->height); if (!This->bits) return E_OUTOFMEMORY; } @@ -316,7 +309,8 @@ static HRESULT WINAPI BmpFrameEncode_WriteSource(IWICBitmapFrameEncode *iface, if (SUCCEEDED(hr)) { hr = write_source(iface, pIBitmapSource, prc, - This->format->guid, This->format->bpp, This->width, This->height); + This->format->guid, This->format->bpp, !This->colors && This->format->colors, + This->width, This->height); } return hr; @@ -400,10 +394,16 @@ static HRESULT WINAPI BmpFrameEncode_Commit(IWICBitmapFrameEncode *iface) } static HRESULT WINAPI BmpFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface, - IWICMetadataQueryWriter **ppIMetadataQueryWriter) + IWICMetadataQueryWriter **query_writer) { - FIXME("(%p, %p): stub\n", iface, ppIMetadataQueryWriter); - return E_NOTIMPL; + BmpFrameEncode *encoder = impl_from_IWICBitmapFrameEncode(iface); + + TRACE("iface %p, query_writer %p.\n", iface, query_writer); + + if (!encoder->initialized) + return WINCODEC_ERR_NOTINITIALIZED; + + return WINCODEC_ERR_UNSUPPORTEDOPERATION; } static const IWICBitmapFrameEncodeVtbl BmpFrameEncode_Vtbl = { @@ -463,7 +463,7 @@ static ULONG WINAPI BmpEncoder_AddRef(IWICBitmapEncoder *iface) BmpEncoder *This = impl_from_IWICBitmapEncoder(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -473,13 +473,13 @@ static ULONG WINAPI BmpEncoder_Release(IWICBitmapEncoder *iface) BmpEncoder *This = impl_from_IWICBitmapEncoder(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { if (This->stream) IStream_Release(This->stream); if (This->frame) IWICBitmapFrameEncode_Release(&This->frame->IWICBitmapFrameEncode_iface); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -563,7 +563,7 @@ static HRESULT WINAPI BmpEncoder_CreateNewFrame(IWICBitmapEncoder *iface, HRESULT hr; static const PROPBAG2 opts[1] = { - { PROPBAG2_TYPE_DATA, VT_BOOL, 0, 0, (LPOLESTR)wszEnableV5Header32bppBGRA }, + { PROPBAG2_TYPE_DATA, VT_BOOL, 0, 0, (LPOLESTR)L"EnableV5Header32bppBGRA" }, }; TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions); @@ -578,7 +578,7 @@ static HRESULT WINAPI BmpEncoder_CreateNewFrame(IWICBitmapEncoder *iface, if (FAILED(hr)) return hr; } - encode = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpFrameEncode)); + encode = malloc(sizeof(BmpFrameEncode)); if (!encode) { IPropertyBag2_Release(*ppIEncoderOptions); @@ -648,7 +648,7 @@ HRESULT BmpEncoder_CreateInstance(REFIID iid, void** ppv) *ppv = NULL; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(BmpEncoder)); + This = malloc(sizeof(BmpEncoder)); if (!This) return E_OUTOFMEMORY; This->IWICBitmapEncoder_iface.lpVtbl = &BmpEncoder_Vtbl; diff --git a/dll/win32/windowscodecs/clipper.c b/dll/win32/windowscodecs/clipper.c index 02e0d967f52..b4b2c23ee45 100644 --- a/dll/win32/windowscodecs/clipper.c +++ b/dll/win32/windowscodecs/clipper.c @@ -72,7 +72,7 @@ static ULONG WINAPI BitmapClipper_AddRef(IWICBitmapClipper *iface) BitmapClipper *This = impl_from_IWICBitmapClipper(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -82,14 +82,14 @@ static ULONG WINAPI BitmapClipper_Release(IWICBitmapClipper *iface) BitmapClipper *This = impl_from_IWICBitmapClipper(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); if (This->source) IWICBitmapSource_Release(This->source); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -244,13 +244,17 @@ HRESULT BitmapClipper_Create(IWICBitmapClipper **clipper) { BitmapClipper *This; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapClipper)); + This = malloc(sizeof(BitmapClipper)); if (!This) return E_OUTOFMEMORY; This->IWICBitmapClipper_iface.lpVtbl = &BitmapClipper_Vtbl; This->ref = 1; This->source = NULL; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BitmapClipper.lock"); *clipper = &This->IWICBitmapClipper_iface; diff --git a/dll/win32/windowscodecs/clsfactory.c b/dll/win32/windowscodecs/clsfactory.c index 2de518a00c1..87b77c9c089 100644 --- a/dll/win32/windowscodecs/clsfactory.c +++ b/dll/win32/windowscodecs/clsfactory.c @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -27,6 +25,8 @@ #include "winreg.h" #include "objbase.h" #include "ocidl.h" +#include "wincodec.h" +#include "wincodecsdk.h" #include "initguid.h" #include "wincodecs_private.h" @@ -35,7 +35,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); -extern HRESULT WINAPI WIC_DllGetClassObject(REFCLSID, REFIID, LPVOID *) DECLSPEC_HIDDEN; +extern HRESULT WINAPI WIC_DllGetClassObject(REFCLSID, REFIID, LPVOID *); typedef struct { REFCLSID classid; @@ -47,6 +47,7 @@ static const classinfo wic_classes[] = { {&CLSID_WICImagingFactory2, ImagingFactory_CreateInstance}, {&CLSID_WICBmpDecoder, BmpDecoder_CreateInstance}, {&CLSID_WICPngDecoder, PngDecoder_CreateInstance}, + {&CLSID_WICPngDecoder2, PngDecoder_CreateInstance}, {&CLSID_WICPngEncoder, PngEncoder_CreateInstance}, {&CLSID_WICBmpEncoder, BmpEncoder_CreateInstance}, {&CLSID_WICGifDecoder, GifDecoder_CreateInstance}, @@ -56,14 +57,17 @@ static const classinfo wic_classes[] = { {&CLSID_WICJpegEncoder, JpegEncoder_CreateInstance}, {&CLSID_WICTiffDecoder, TiffDecoder_CreateInstance}, {&CLSID_WICTiffEncoder, TiffEncoder_CreateInstance}, - {&CLSID_WICIcnsEncoder, IcnsEncoder_CreateInstance}, + {&CLSID_WICDdsDecoder, DdsDecoder_CreateInstance}, + {&CLSID_WICDdsEncoder, DdsEncoder_CreateInstance}, {&CLSID_WICDefaultFormatConverter, FormatConverter_CreateInstance}, {&CLSID_WineTgaDecoder, TgaDecoder_CreateInstance}, {&CLSID_WICUnknownMetadataReader, UnknownMetadataReader_CreateInstance}, {&CLSID_WICIfdMetadataReader, IfdMetadataReader_CreateInstance}, {&CLSID_WICPngChrmMetadataReader, PngChrmReader_CreateInstance}, {&CLSID_WICPngGamaMetadataReader, PngGamaReader_CreateInstance}, + {&CLSID_WICPngHistMetadataReader, PngHistReader_CreateInstance}, {&CLSID_WICPngTextMetadataReader, PngTextReader_CreateInstance}, + {&CLSID_WICPngTimeMetadataReader, PngTimeReader_CreateInstance}, {&CLSID_WICLSDMetadataReader, LSDReader_CreateInstance}, {&CLSID_WICIMDMetadataReader, IMDReader_CreateInstance}, {&CLSID_WICGCEMetadataReader, GCEReader_CreateInstance}, @@ -110,7 +114,7 @@ static ULONG WINAPI ClassFactoryImpl_AddRef(IClassFactory *iface) ClassFactoryImpl *This = impl_from_IClassFactory(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -120,10 +124,10 @@ static ULONG WINAPI ClassFactoryImpl_Release(IClassFactory *iface) ClassFactoryImpl *This = impl_from_IClassFactory(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) - HeapFree(GetProcessHeap(), 0, This); + free(This); return ref; } @@ -161,7 +165,7 @@ static HRESULT ClassFactoryImpl_Constructor(const classinfo *info, REFIID riid, *ppv = NULL; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(ClassFactoryImpl)); + This = malloc(sizeof(ClassFactoryImpl)); if (!This) return E_OUTOFMEMORY; This->IClassFactory_iface.lpVtbl = &ClassFactoryImpl_Vtbl; @@ -201,11 +205,11 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) else ret = WIC_DllGetClassObject(rclsid, iid, ppv); - TRACE("<-- %08X\n", ret); + TRACE("<-- %08lX\n", ret); return ret; } -HRESULT create_instance(CLSID *clsid, const IID *iid, void **ppv) +HRESULT create_instance(const CLSID *clsid, const IID *iid, void **ppv) { int i; diff --git a/dll/win32/windowscodecs/colorcontext.c b/dll/win32/windowscodecs/colorcontext.c index eb13482cf43..a52e4e06eb7 100644 --- a/dll/win32/windowscodecs/colorcontext.c +++ b/dll/win32/windowscodecs/colorcontext.c @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -74,7 +72,7 @@ static ULONG WINAPI ColorContext_AddRef(IWICColorContext *iface) ColorContext *This = impl_from_IWICColorContext(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -84,12 +82,12 @@ static ULONG WINAPI ColorContext_Release(IWICColorContext *iface) ColorContext *This = impl_from_IWICColorContext(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { - HeapFree(GetProcessHeap(), 0, This->profile); - HeapFree(GetProcessHeap(), 0, This); + free(This->profile); + free(This); } return ref; @@ -118,7 +116,7 @@ static HRESULT load_profile(const WCHAR *filename, BYTE **profile, UINT *len) CloseHandle(handle); return E_FAIL; } - if (!(*profile = HeapAlloc(GetProcessHeap(), 0, size.u.LowPart))) + if (!(*profile = malloc(size.u.LowPart))) { CloseHandle(handle); return E_OUTOFMEMORY; @@ -126,12 +124,12 @@ static HRESULT load_profile(const WCHAR *filename, BYTE **profile, UINT *len) ret = ReadFile(handle, *profile, size.u.LowPart, &count, NULL); CloseHandle(handle); if (!ret) { - HeapFree (GetProcessHeap(),0,*profile); + free(*profile); *profile = NULL; return HRESULT_FROM_WIN32(GetLastError()); } if (count != size.u.LowPart) { - HeapFree (GetProcessHeap(),0,*profile); + free(*profile); *profile = NULL; return E_FAIL; } @@ -156,7 +154,7 @@ static HRESULT WINAPI ColorContext_InitializeFromFilename(IWICColorContext *ifac hr = load_profile(wzFilename, &profile, &len); if (FAILED(hr)) return hr; - HeapFree(GetProcessHeap(), 0, This->profile); + free(This->profile); This->profile = profile; This->profile_len = len; This->type = WICColorContextProfile; @@ -174,10 +172,10 @@ static HRESULT WINAPI ColorContext_InitializeFromMemory(IWICColorContext *iface, if (This->type != WICColorContextUninitialized && This->type != WICColorContextProfile) return WINCODEC_ERR_WRONGSTATE; - if (!(profile = HeapAlloc(GetProcessHeap(), 0, cbBufferSize))) return E_OUTOFMEMORY; + if (!(profile = malloc(cbBufferSize))) return E_OUTOFMEMORY; memcpy(profile, pbBuffer, cbBufferSize); - HeapFree(GetProcessHeap(), 0, This->profile); + free(This->profile); This->profile = profile; This->profile_len = cbBufferSize; This->type = WICColorContextProfile; @@ -261,7 +259,7 @@ HRESULT ColorContext_Create(IWICColorContext **colorcontext) if (!colorcontext) return E_INVALIDARG; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(ColorContext)); + This = malloc(sizeof(ColorContext)); if (!This) return E_OUTOFMEMORY; This->IWICColorContext_iface.lpVtbl = &ColorContext_Vtbl; diff --git a/dll/win32/windowscodecs/colortransform.c b/dll/win32/windowscodecs/colortransform.c index af66c67443d..9a392d6dc0c 100644 --- a/dll/win32/windowscodecs/colortransform.c +++ b/dll/win32/windowscodecs/colortransform.c @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -72,7 +70,7 @@ static ULONG WINAPI ColorTransform_AddRef(IWICColorTransform *iface) ColorTransform *This = impl_from_IWICColorTransform(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -82,12 +80,12 @@ static ULONG WINAPI ColorTransform_Release(IWICColorTransform *iface) ColorTransform *This = impl_from_IWICColorTransform(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { if (This->dst) IWICBitmapSource_Release(This->dst); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -177,7 +175,7 @@ HRESULT ColorTransform_Create(IWICColorTransform **colortransform) if (!colortransform) return E_INVALIDARG; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(ColorTransform)); + This = malloc(sizeof(ColorTransform)); if (!This) return E_OUTOFMEMORY; This->IWICColorTransform_iface.lpVtbl = &ColorTransform_Vtbl; diff --git a/dll/win32/windowscodecs/converter.c b/dll/win32/windowscodecs/converter.c index cac2ac1aa5a..2156e0aec8f 100644 --- a/dll/win32/windowscodecs/converter.c +++ b/dll/win32/windowscodecs/converter.c @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #include @@ -30,7 +28,6 @@ #include "wincodecs_private.h" -#include "wine/heap.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); @@ -71,6 +68,7 @@ struct pixelformatinfo { enum pixelformat format; const WICPixelFormatGUID *guid; copyfunc copy_function; + BOOL is_indexed_format; }; typedef struct FormatConverter { @@ -176,7 +174,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = (prc->Width+7)/8; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -205,7 +203,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -243,7 +241,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = (prc->Width+3)/4; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -268,7 +266,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -306,7 +304,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = (prc->Width+1)/2; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -329,7 +327,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -349,7 +347,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -371,7 +369,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -405,7 +403,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -424,7 +422,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -444,7 +442,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = prc->Width * 2; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -467,7 +465,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -487,7 +485,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = 2 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -515,7 +513,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -535,7 +533,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = 2 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -563,7 +561,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -583,7 +581,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = 2 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -611,7 +609,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -631,7 +629,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = 3 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -654,7 +652,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -675,7 +673,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = 3 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -702,7 +700,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -728,7 +726,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe HRESULT res; res = IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); if (FAILED(res)) return res; - convert_rgba_to_bgra(4, pbBuffer, prc->Width, prc->Height, cbStride); + reverse_bgr8(4, pbBuffer, prc->Width, prc->Height, cbStride); } return S_OK; case format_32bppBGRA: @@ -772,7 +770,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = 6 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -796,7 +794,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -816,7 +814,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe srcstride = 8 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -841,7 +839,7 @@ static HRESULT copypixels_to_32bppBGRA(struct FormatConverter *This, const WICRe } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -985,9 +983,9 @@ static HRESULT copypixels_to_32bppPBGRA(struct FormatConverter *This, const WICR BYTE alpha = pbBuffer[cbStride*y+4*x+3]; if (alpha != 255) { - pbBuffer[cbStride*y+4*x] = pbBuffer[cbStride*y+4*x] * alpha / 255; - pbBuffer[cbStride*y+4*x+1] = pbBuffer[cbStride*y+4*x+1] * alpha / 255; - pbBuffer[cbStride*y+4*x+2] = pbBuffer[cbStride*y+4*x+2] * alpha / 255; + pbBuffer[cbStride*y+4*x] = (pbBuffer[cbStride*y+4*x] * alpha + 127) / 255; + pbBuffer[cbStride*y+4*x+1] = (pbBuffer[cbStride*y+4*x+1] * alpha + 127) / 255; + pbBuffer[cbStride*y+4*x+2] = (pbBuffer[cbStride*y+4*x+2] * alpha + 127) / 255; } } } @@ -1018,9 +1016,9 @@ static HRESULT copypixels_to_32bppPRGBA(struct FormatConverter *This, const WICR BYTE alpha = pbBuffer[cbStride*y+4*x+3]; if (alpha != 255) { - pbBuffer[cbStride*y+4*x] = pbBuffer[cbStride*y+4*x] * alpha / 255; - pbBuffer[cbStride*y+4*x+1] = pbBuffer[cbStride*y+4*x+1] * alpha / 255; - pbBuffer[cbStride*y+4*x+2] = pbBuffer[cbStride*y+4*x+2] * alpha / 255; + pbBuffer[cbStride*y+4*x] = (pbBuffer[cbStride*y+4*x] * alpha + 127) / 255; + pbBuffer[cbStride*y+4*x+1] = (pbBuffer[cbStride*y+4*x+1] * alpha + 127) / 255; + pbBuffer[cbStride*y+4*x+2] = (pbBuffer[cbStride*y+4*x+2] * alpha + 127) / 255; } } } @@ -1063,7 +1061,7 @@ static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRec srcstride = 4 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -1107,7 +1105,7 @@ static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRec } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -1122,7 +1120,7 @@ static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRec srcstride = 4 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; hr = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -1149,7 +1147,7 @@ static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRec } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return hr; } @@ -1164,7 +1162,7 @@ static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRec srcstride = 4 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = heap_alloc(srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; hr = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -1192,7 +1190,7 @@ static HRESULT copypixels_to_24bppBGR(struct FormatConverter *This, const WICRec } } - heap_free(srcdata); + free(srcdata); return hr; } return S_OK; @@ -1238,7 +1236,7 @@ static HRESULT copypixels_to_24bppRGB(struct FormatConverter *This, const WICRec srcstride = 4 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -1265,7 +1263,7 @@ static HRESULT copypixels_to_24bppRGB(struct FormatConverter *This, const WICRec } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return res; } @@ -1343,7 +1341,7 @@ static HRESULT copypixels_to_8bppGray(struct FormatConverter *This, const WICRec srcstride = 4 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; hr = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); @@ -1365,7 +1363,7 @@ static HRESULT copypixels_to_8bppGray(struct FormatConverter *This, const WICRec } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); } return hr; @@ -1377,7 +1375,7 @@ static HRESULT copypixels_to_8bppGray(struct FormatConverter *This, const WICRec srcstride = 3 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; hr = copypixels_to_24bppBGR(This, prc, srcstride, srcdatasize, srcdata, source_format); @@ -1403,7 +1401,7 @@ static HRESULT copypixels_to_8bppGray(struct FormatConverter *This, const WICRec } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return hr; } @@ -1467,7 +1465,7 @@ static HRESULT copypixels_to_8bppIndexed(struct FormatConverter *This, const WIC srcstride = 3 * prc->Width; srcdatasize = srcstride * prc->Height; - srcdata = HeapAlloc(GetProcessHeap(), 0, srcdatasize); + srcdata = malloc(srcdatasize); if (!srcdata) return E_OUTOFMEMORY; hr = copypixels_to_24bppBGR(This, prc, srcstride, srcdatasize, srcdata, source_format); @@ -1490,15 +1488,138 @@ static HRESULT copypixels_to_8bppIndexed(struct FormatConverter *This, const WIC } } - HeapFree(GetProcessHeap(), 0, srcdata); + free(srcdata); return hr; } +static HRESULT copypixels_to_16bppBGRA5551(struct FormatConverter *This, const WICRect *prc, + UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) +{ + switch (source_format) + { + case format_16bppBGRA5551: + if (prc) + return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); + return S_OK; + case format_32bppBGRA: + if(prc) + { + HRESULT res; + INT x, y; + BYTE *srcdata; + UINT srcstride, srcdatasize; + const BYTE *srcrow; + const DWORD *srcpixel; + BYTE *dstrow; + DWORD srcval = 0; + WORD *dstpixel; + + int a, r, g, b; + + srcstride = 4 * prc->Width; + srcdatasize = srcstride * prc->Height; + + srcdata = malloc(srcdatasize); + if (!srcdata) return E_OUTOFMEMORY; + + res = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); + if(SUCCEEDED(res)) + { + srcrow = srcdata; + dstrow = pbBuffer; + for(y=0; y< prc->Height; y++) { + srcpixel = (const DWORD*)srcrow; + dstpixel = (WORD *)dstrow; + for(x=0; xWidth; x++) { + srcval=*srcpixel++; + a = (srcval & 0xff000000) >> 24; + r = (srcval & 0x00ff0000) >> 16; + g = (srcval & 0x0000ff00) >> 8; + b = (srcval & 0x000000ff); + a = (a >> 7) << 15; + r = (r >> 3) << 10; + g = (g >> 3) << 5; + b = (b >> 3); + *dstpixel++ = (a|r|g|b); + } + srcrow += srcstride; + dstrow += cbStride; + } + } + free(srcdata); + } + return S_OK; + default: + FIXME("Unimplemented conversion path! %d\n", source_format); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; + } +} + +static HRESULT copypixels_to_64bppRGBA(struct FormatConverter *This, const WICRect *prc, + UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer, enum pixelformat source_format) +{ + HRESULT hr; + + switch (source_format) + { + case format_64bppRGBA: + if (prc) + return IWICBitmapSource_CopyPixels(This->source, prc, cbStride, cbBufferSize, pbBuffer); + return S_OK; + + case format_48bppRGB: + { + UINT srcstride, srcdatasize; + const USHORT *srcpixel; + const BYTE *srcrow; + USHORT *dstpixel; + BYTE *srcdata; + BYTE *dstrow; + INT x, y; + + if (!prc) + return S_OK; + + srcstride = 6 * prc->Width; + srcdatasize = srcstride * prc->Height; + + srcdata = malloc(srcdatasize); + if (!srcdata) return E_OUTOFMEMORY; + + hr = IWICBitmapSource_CopyPixels(This->source, prc, srcstride, srcdatasize, srcdata); + if (SUCCEEDED(hr)) + { + srcrow = srcdata; + dstrow = pbBuffer; + for (y = 0; y < prc->Height; y++) + { + srcpixel = (USHORT *)srcrow; + dstpixel= (USHORT *)dstrow; + for (x = 0; x < prc->Width; x++) + { + *dstpixel++ = *srcpixel++; + *dstpixel++ = *srcpixel++; + *dstpixel++ = *srcpixel++; + *dstpixel++ = 65535; + } + srcrow += srcstride; + dstrow += cbStride; + } + } + free(srcdata); + return hr; + } + default: + FIXME("Unimplemented conversion path %d.\n", source_format); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; + } +} + static const struct pixelformatinfo supported_formats[] = { - {format_1bppIndexed, &GUID_WICPixelFormat1bppIndexed, NULL}, - {format_2bppIndexed, &GUID_WICPixelFormat2bppIndexed, NULL}, - {format_4bppIndexed, &GUID_WICPixelFormat4bppIndexed, NULL}, - {format_8bppIndexed, &GUID_WICPixelFormat8bppIndexed, copypixels_to_8bppIndexed}, + {format_1bppIndexed, &GUID_WICPixelFormat1bppIndexed, NULL, TRUE}, + {format_2bppIndexed, &GUID_WICPixelFormat2bppIndexed, NULL, TRUE}, + {format_4bppIndexed, &GUID_WICPixelFormat4bppIndexed, NULL, TRUE}, + {format_8bppIndexed, &GUID_WICPixelFormat8bppIndexed, copypixels_to_8bppIndexed, TRUE}, {format_BlackWhite, &GUID_WICPixelFormatBlackWhite, NULL}, {format_2bppGray, &GUID_WICPixelFormat2bppGray, NULL}, {format_4bppGray, &GUID_WICPixelFormat4bppGray, NULL}, @@ -1506,7 +1627,7 @@ static const struct pixelformatinfo supported_formats[] = { {format_16bppGray, &GUID_WICPixelFormat16bppGray, NULL}, {format_16bppBGR555, &GUID_WICPixelFormat16bppBGR555, NULL}, {format_16bppBGR565, &GUID_WICPixelFormat16bppBGR565, NULL}, - {format_16bppBGRA5551, &GUID_WICPixelFormat16bppBGRA5551, NULL}, + {format_16bppBGRA5551, &GUID_WICPixelFormat16bppBGRA5551, copypixels_to_16bppBGRA5551}, {format_24bppBGR, &GUID_WICPixelFormat24bppBGR, copypixels_to_24bppBGR}, {format_24bppRGB, &GUID_WICPixelFormat24bppRGB, copypixels_to_24bppRGB}, {format_32bppGrayFloat, &GUID_WICPixelFormat32bppGrayFloat, copypixels_to_32bppGrayFloat}, @@ -1517,7 +1638,7 @@ static const struct pixelformatinfo supported_formats[] = { {format_32bppPBGRA, &GUID_WICPixelFormat32bppPBGRA, copypixels_to_32bppPBGRA}, {format_32bppPRGBA, &GUID_WICPixelFormat32bppPRGBA, copypixels_to_32bppPRGBA}, {format_48bppRGB, &GUID_WICPixelFormat48bppRGB, NULL}, - {format_64bppRGBA, &GUID_WICPixelFormat64bppRGBA, NULL}, + {format_64bppRGBA, &GUID_WICPixelFormat64bppRGBA, copypixels_to_64bppRGBA}, {format_32bppCMYK, &GUID_WICPixelFormat32bppCMYK, NULL}, {0} }; @@ -1561,7 +1682,7 @@ static ULONG WINAPI FormatConverter_AddRef(IWICFormatConverter *iface) FormatConverter *This = impl_from_IWICFormatConverter(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -1571,7 +1692,7 @@ static ULONG WINAPI FormatConverter_Release(IWICFormatConverter *iface) FormatConverter *This = impl_from_IWICFormatConverter(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { @@ -1579,7 +1700,7 @@ static ULONG WINAPI FormatConverter_Release(IWICFormatConverter *iface) DeleteCriticalSection(&This->lock); if (This->source) IWICBitmapSource_Release(This->source); if (This->palette) IWICPalette_Release(This->palette); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -1638,12 +1759,7 @@ static HRESULT WINAPI FormatConverter_CopyPalette(IWICFormatConverter *iface, if (!This->palette) { - HRESULT hr; - UINT bpp; - - hr = get_pixelformat_bpp(This->dst_format->guid, &bpp); - if (hr != S_OK) return hr; - if (bpp <= 8) return WINCODEC_ERR_WRONGSTATE; + if (This->dst_format->is_indexed_format) return WINCODEC_ERR_WRONGSTATE; return IWICBitmapSource_CopyPalette(This->source, palette); } @@ -1691,6 +1807,13 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface, TRACE("(%p,%p,%s,%u,%p,%0.3f,%u)\n", iface, source, debugstr_guid(dstFormat), dither, palette, alpha_threshold, palette_type); + dstinfo = get_formatinfo(dstFormat); + if (!dstinfo) + { + FIXME("Unsupported destination format %s\n", debugstr_guid(dstFormat)); + return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + } + if (!palette) { UINT bpp; @@ -1705,18 +1828,21 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface, case WICBitmapPaletteTypeCustom: IWICPalette_Release(palette); palette = NULL; - if (bpp <= 8) return E_INVALIDARG; + + /* Indexed types require a palette */ + if (dstinfo->is_indexed_format) + return E_INVALIDARG; break; case WICBitmapPaletteTypeMedianCut: { - if (bpp <= 8) + if (dstinfo->is_indexed_format) res = IWICPalette_InitializeFromBitmap(palette, source, 1 << bpp, FALSE); break; } default: - if (bpp <= 8) + if (dstinfo->is_indexed_format) res = IWICPalette_InitializePredefined(palette, palette_type, FALSE); break; } @@ -1749,14 +1875,6 @@ static HRESULT WINAPI FormatConverter_Initialize(IWICFormatConverter *iface, goto end; } - dstinfo = get_formatinfo(dstFormat); - if (!dstinfo) - { - res = WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; - FIXME("Unsupported destination format %s\n", debugstr_guid(dstFormat)); - goto end; - } - if (dstinfo->copy_function) { IWICBitmapSource_AddRef(source); @@ -1841,14 +1959,18 @@ HRESULT FormatConverter_CreateInstance(REFIID iid, void** ppv) *ppv = NULL; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverter)); + This = malloc(sizeof(FormatConverter)); if (!This) return E_OUTOFMEMORY; This->IWICFormatConverter_iface.lpVtbl = &FormatConverter_Vtbl; This->ref = 1; This->source = NULL; This->palette = NULL; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FormatConverter.lock"); ret = IWICFormatConverter_QueryInterface(&This->IWICFormatConverter_iface, iid, ppv); diff --git a/dll/win32/windowscodecs/ddsformat.c b/dll/win32/windowscodecs/ddsformat.c new file mode 100644 index 00000000000..680febb0d93 --- /dev/null +++ b/dll/win32/windowscodecs/ddsformat.c @@ -0,0 +1,2162 @@ +/* + * Copyright 2020 Ziqing Hui + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * + * Note: + * + * Uncompressed image: + * For uncompressed formats, a block is equivalent to a pixel. + * + * Cube map: + * A cube map is equivalent to a 2D texture array which has 6 textures. + * A cube map array is equivalent to a 2D texture array which has cubeCount*6 textures. + */ + +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + +#define DDS_MAGIC 0x20534444 +#ifndef MAKEFOURCC +#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ + ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \ + ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 )) +#endif + +#define GET_RGB565_R(color) ((BYTE)(((color) >> 11) & 0x1F)) +#define GET_RGB565_G(color) ((BYTE)(((color) >> 5) & 0x3F)) +#define GET_RGB565_B(color) ((BYTE)(((color) >> 0) & 0x1F)) +#define MAKE_RGB565(r, g, b) ((WORD)(((BYTE)(r) << 11) | ((BYTE)(g) << 5) | (BYTE)(b))) +#define MAKE_ARGB(a, r, g, b) (((DWORD)(a) << 24) | ((DWORD)(r) << 16) | ((DWORD)(g) << 8) | (DWORD)(b)) + +#define DDPF_ALPHAPIXELS 0x00000001 +#define DDPF_ALPHA 0x00000002 +#define DDPF_FOURCC 0x00000004 +#define DDPF_PALETTEINDEXED8 0x00000020 +#define DDPF_RGB 0x00000040 +#define DDPF_LUMINANCE 0x00020000 +#define DDPF_BUMPDUDV 0x00080000 + +#define DDSCAPS2_CUBEMAP 0x00000200 +#define DDSCAPS2_VOLUME 0x00200000 + +#define DDS_DIMENSION_TEXTURE1D 2 +#define DDS_DIMENSION_TEXTURE2D 3 +#define DDS_DIMENSION_TEXTURE3D 4 + +#define DDS_RESOURCE_MISC_TEXTURECUBE 0x00000004 + +#define DDS_BLOCK_WIDTH 4 +#define DDS_BLOCK_HEIGHT 4 + +typedef struct { + DWORD size; + DWORD flags; + DWORD fourCC; + DWORD rgbBitCount; + DWORD rBitMask; + DWORD gBitMask; + DWORD bBitMask; + DWORD aBitMask; +} DDS_PIXELFORMAT; + +typedef struct { + DWORD size; + DWORD flags; + DWORD height; + DWORD width; + DWORD pitchOrLinearSize; + DWORD depth; + DWORD mipMapCount; + DWORD reserved1[11]; + DDS_PIXELFORMAT ddspf; + DWORD caps; + DWORD caps2; + DWORD caps3; + DWORD caps4; + DWORD reserved2; +} DDS_HEADER; + +typedef struct { + DWORD dxgiFormat; + DWORD resourceDimension; + DWORD miscFlag; + DWORD arraySize; + DWORD miscFlags2; +} DDS_HEADER_DXT10; + +typedef struct dds_info { + UINT width; + UINT height; + UINT depth; + UINT mip_levels; + UINT array_size; + UINT frame_count; + UINT data_offset; + UINT bytes_per_block; /* for uncompressed format, this means bytes per pixel*/ + DXGI_FORMAT format; + WICDdsDimension dimension; + WICDdsAlphaMode alpha_mode; + const GUID *pixel_format; + UINT pixel_format_bpp; +} dds_info; + +typedef struct dds_frame_info { + UINT width; + UINT height; + DXGI_FORMAT format; + UINT bytes_per_block; /* for uncompressed format, this means bytes per pixel*/ + UINT block_width; + UINT block_height; + UINT width_in_blocks; + UINT height_in_blocks; + const GUID *pixel_format; + UINT pixel_format_bpp; +} dds_frame_info; + +typedef struct DdsDecoder { + IWICBitmapDecoder IWICBitmapDecoder_iface; + IWICDdsDecoder IWICDdsDecoder_iface; + IWICWineDecoder IWICWineDecoder_iface; + LONG ref; + BOOL initialized; + IStream *stream; + CRITICAL_SECTION lock; + dds_info info; +} DdsDecoder; + +typedef struct DdsFrameDecode { + IWICBitmapFrameDecode IWICBitmapFrameDecode_iface; + IWICDdsFrameDecode IWICDdsFrameDecode_iface; + LONG ref; + BYTE *block_data; + BYTE *pixel_data; + CRITICAL_SECTION lock; + dds_frame_info info; +} DdsFrameDecode; + +typedef struct DdsEncoder { + IWICBitmapEncoder IWICBitmapEncoder_iface; + IWICDdsEncoder IWICDdsEncoder_iface; + LONG ref; + CRITICAL_SECTION lock; + IStream *stream; + UINT frame_count; + UINT frame_index; + BOOL uncommitted_frame; + BOOL committed; + dds_info info; +} DdsEncoder; + +typedef struct DdsFrameEncode { + IWICBitmapFrameEncode IWICBitmapFrameEncode_iface; + LONG ref; + DdsEncoder *parent; + BOOL initialized; + BOOL frame_created; + UINT width; + UINT height; + double dpi_x; + double dpi_y; +} DdsFrameEncode; + +static struct dds_format { + DDS_PIXELFORMAT pixel_format; + const GUID *wic_format; + UINT wic_format_bpp; + DXGI_FORMAT dxgi_format; +} dds_format_table[] = { + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D', 'X', 'T', '1'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppPBGRA, 32, DXGI_FORMAT_BC1_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D', 'X', 'T', '2'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppPBGRA, 32, DXGI_FORMAT_BC2_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D', 'X', 'T', '3'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppBGRA, 32, DXGI_FORMAT_BC2_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D', 'X', 'T', '4'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppPBGRA, 32, DXGI_FORMAT_BC3_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D', 'X', 'T', '5'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppBGRA, 32, DXGI_FORMAT_BC3_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('B', 'C', '4', 'U'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppBGRA, 32, DXGI_FORMAT_BC4_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('B', 'C', '4', 'S'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppBGRA, 32, DXGI_FORMAT_BC4_SNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('B', 'C', '5', 'U'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppBGRA, 32, DXGI_FORMAT_BC5_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('B', 'C', '5', 'S'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppBGRA, 32, DXGI_FORMAT_BC5_SNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('A', 'T', 'I', '1'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppBGRA, 32, DXGI_FORMAT_BC4_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('A', 'T', 'I', '2'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppBGRA, 32, DXGI_FORMAT_BC5_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('R', 'G', 'B', 'G'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bpp4Channels, 32, DXGI_FORMAT_R8G8_B8G8_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('G', 'R', 'G', 'B'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bpp4Channels, 32, DXGI_FORMAT_G8R8_G8B8_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D', 'X', '1', '0'), 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormatUndefined, 0, DXGI_FORMAT_UNKNOWN }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, 0x24, 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat64bppRGBA, 64, DXGI_FORMAT_R16G16B16A16_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, 0x6E, 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat64bppRGBA, 64, DXGI_FORMAT_R16G16B16A16_SNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, 0x6F, 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat16bppGrayHalf, 16, DXGI_FORMAT_R16_FLOAT }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, 0x70, 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormatUndefined, 0, DXGI_FORMAT_R16G16_FLOAT }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, 0x71, 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat64bppRGBAHalf, 64, DXGI_FORMAT_R16G16B16A16_FLOAT }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, 0x72, 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat32bppGrayFloat, 32, DXGI_FORMAT_R32_FLOAT }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, 0x73, 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormatUndefined, 32, DXGI_FORMAT_R32G32_FLOAT }, + { { sizeof(DDS_PIXELFORMAT), DDPF_FOURCC, 0x74, 0, 0, 0, 0, 0 }, + &GUID_WICPixelFormat128bppRGBAFloat, 128, DXGI_FORMAT_R32G32B32A32_FLOAT }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB, 0, 32, 0xFF,0xFF00,0xFF0000,0xFF000000 }, + &GUID_WICPixelFormat32bppRGBA, 32, DXGI_FORMAT_R8G8B8A8_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB, 0, 32, 0xFF,0xFF00,0xFF0000,0 }, + &GUID_WICPixelFormat32bppRGB, 32, DXGI_FORMAT_UNKNOWN }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB, 0, 32, 0xFF0000,0xFF00,0xFF,0xFF000000 }, + &GUID_WICPixelFormat32bppBGRA, 32, DXGI_FORMAT_B8G8R8A8_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB, 0, 32, 0xFF0000,0xFF00,0xFF,0 }, + &GUID_WICPixelFormat32bppBGR, 32, DXGI_FORMAT_B8G8R8X8_UNORM }, + /* The red and blue masks are swapped for DXGI_FORMAT_R10G10B10A2_UNORM. + * For "correct" one, the RGB masks should be 0x3FF,0xFFC00,0x3FF00000. + * see: https://walbourn.github.io/dds-update-and-1010102-problems */ + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB, 0, 32, 0x3FF00000,0xFFC00,0x3FF,0xC0000000 }, + &GUID_WICPixelFormat32bppR10G10B10A2, 32, DXGI_FORMAT_R10G10B10A2_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB, 0, 32, 0x3FF,0xFFC00,0x3FF00000,0xC0000000 }, + &GUID_WICPixelFormat32bppRGBA1010102, 32, DXGI_FORMAT_R10G10B10A2_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB , 0, 32, 0xFFFF,0xFFFF0000,0,0 }, + &GUID_WICPixelFormatUndefined, 0, DXGI_FORMAT_R16G16_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB , 0, 32, 0xFFFFFFFF,0,0,0 }, + &GUID_WICPixelFormat32bppGrayFloat, 32, DXGI_FORMAT_R32_FLOAT }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB , 0, 24, 0xFF0000,0x00FF00,0x0000FF,0 }, + &GUID_WICPixelFormat24bppBGR, 24, DXGI_FORMAT_UNKNOWN }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB , 0, 24, 0x0000FF,0x00FF00,0xFF0000,0 }, + &GUID_WICPixelFormat24bppRGB, 24, DXGI_FORMAT_UNKNOWN }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB, 0, 16, 0xF800,0x7E0,0x1F,0 }, + &GUID_WICPixelFormat16bppBGR565, 16, DXGI_FORMAT_B5G6R5_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB, 0, 16, 0x7C00,0x3E0,0x1F,0 }, + &GUID_WICPixelFormat16bppBGR555, 16, DXGI_FORMAT_UNKNOWN }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB, 0, 16, 0x7C00,0x3E0,0x1F,0x8000 }, + &GUID_WICPixelFormat16bppBGRA5551, 16, DXGI_FORMAT_B5G5R5A1_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_RGB, 0, 16, 0xF00,0xF0,0xF,0xF000 }, + &GUID_WICPixelFormatUndefined, 0, DXGI_FORMAT_B4G4R4A4_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_ALPHA, 0, 8, 0,0,0,0xFF }, + &GUID_WICPixelFormat8bppAlpha, 8, DXGI_FORMAT_A8_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_LUMINANCE, 0, 16, 0xFFFF,0,0,0 }, + &GUID_WICPixelFormat16bppGray, 16, DXGI_FORMAT_R16_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_LUMINANCE, 0, 16, 0xFF,0,0,0xFF00 }, + &GUID_WICPixelFormatUndefined, 0, DXGI_FORMAT_R8G8_UNORM }, + { { sizeof(DDS_PIXELFORMAT), DDPF_LUMINANCE, 0, 8, 0xFF,0,0,0 }, + &GUID_WICPixelFormat8bppGray, 8, DXGI_FORMAT_R8_UNORM }, + { { 0 }, &GUID_WICPixelFormat8bppAlpha, 8, DXGI_FORMAT_A8_UNORM }, + { { 0 }, &GUID_WICPixelFormat8bppGray, 8, DXGI_FORMAT_R8_UNORM }, + { { 0 }, &GUID_WICPixelFormat16bppGray, 16, DXGI_FORMAT_R16_UNORM }, + { { 0 }, &GUID_WICPixelFormat16bppGrayHalf, 16, DXGI_FORMAT_R16_FLOAT }, + { { 0 }, &GUID_WICPixelFormat16bppBGR565, 16, DXGI_FORMAT_B5G6R5_UNORM }, + { { 0 }, &GUID_WICPixelFormat16bppBGRA5551, 16, DXGI_FORMAT_B5G5R5A1_UNORM }, + { { 0 }, &GUID_WICPixelFormat32bppGrayFloat, 32, DXGI_FORMAT_R32_FLOAT }, + { { 0 }, &GUID_WICPixelFormat32bppRGBA, 32, DXGI_FORMAT_R8G8B8A8_UNORM }, + { { 0 }, &GUID_WICPixelFormat32bppBGRA, 32, DXGI_FORMAT_B8G8R8A8_UNORM }, + { { 0 }, &GUID_WICPixelFormat32bppBGR, 32, DXGI_FORMAT_B8G8R8X8_UNORM }, + { { 0 }, &GUID_WICPixelFormat32bppR10G10B10A2, 32, DXGI_FORMAT_R10G10B10A2_UNORM }, + { { 0 }, &GUID_WICPixelFormat32bppRGBE, 32, DXGI_FORMAT_R9G9B9E5_SHAREDEXP }, + { { 0 }, &GUID_WICPixelFormat32bppRGBA1010102XR, 32, DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM }, + { { 0 }, &GUID_WICPixelFormat64bppRGBA, 64, DXGI_FORMAT_R16G16B16A16_UNORM }, + { { 0 }, &GUID_WICPixelFormat64bppRGBAHalf, 64, DXGI_FORMAT_R16G16B16A16_FLOAT }, + { { 0 }, &GUID_WICPixelFormat96bppRGBFloat, 96, DXGI_FORMAT_R32G32B32_FLOAT }, + { { 0 }, &GUID_WICPixelFormat128bppRGBAFloat, 128, DXGI_FORMAT_R32G32B32A32_FLOAT }, + { { 0 }, &GUID_WICPixelFormatUndefined, 0, DXGI_FORMAT_UNKNOWN } +}; + +static DXGI_FORMAT compressed_formats[] = { + DXGI_FORMAT_BC1_TYPELESS, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_BC2_TYPELESS, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM_SRGB, + DXGI_FORMAT_BC3_TYPELESS, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM_SRGB, + DXGI_FORMAT_BC4_TYPELESS, DXGI_FORMAT_BC4_UNORM, DXGI_FORMAT_BC4_SNORM, + DXGI_FORMAT_BC5_TYPELESS, DXGI_FORMAT_BC5_UNORM, DXGI_FORMAT_BC5_SNORM, + DXGI_FORMAT_BC6H_TYPELESS, DXGI_FORMAT_BC6H_UF16, DXGI_FORMAT_BC6H_SF16, + DXGI_FORMAT_BC7_TYPELESS, DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_BC7_UNORM_SRGB +}; + +static HRESULT WINAPI DdsDecoder_Dds_GetFrame(IWICDdsDecoder *, UINT, UINT, UINT, IWICBitmapFrameDecode **); + +static DWORD rgb565_to_argb(WORD color, BYTE alpha) +{ + return MAKE_ARGB(alpha, (GET_RGB565_R(color) * 0xFF + 0x0F) / 0x1F, + (GET_RGB565_G(color) * 0xFF + 0x1F) / 0x3F, + (GET_RGB565_B(color) * 0xFF + 0x0F) / 0x1F); +} + +static inline BOOL has_extended_header(DDS_HEADER *header) +{ + return (header->ddspf.flags & DDPF_FOURCC) && + (header->ddspf.fourCC == MAKEFOURCC('D', 'X', '1', '0')); +} + +static WICDdsDimension get_dimension(DDS_HEADER *header, DDS_HEADER_DXT10 *header_dxt10) +{ + if (header_dxt10) { + if (header_dxt10->miscFlag & DDS_RESOURCE_MISC_TEXTURECUBE) return WICDdsTextureCube; + switch (header_dxt10->resourceDimension) + { + case DDS_DIMENSION_TEXTURE1D: return WICDdsTexture1D; + case DDS_DIMENSION_TEXTURE2D: return WICDdsTexture2D; + case DDS_DIMENSION_TEXTURE3D: return WICDdsTexture3D; + default: return WICDdsTexture2D; + } + } else { + if (header->caps2 & DDSCAPS2_CUBEMAP) { + return WICDdsTextureCube; + } else if (header->caps2 & DDSCAPS2_VOLUME) { + return WICDdsTexture3D; + } else { + return WICDdsTexture2D; + } + } +} + +static struct dds_format *get_dds_format(DDS_PIXELFORMAT *pixel_format) +{ + UINT i; + + for (i = 0; i < ARRAY_SIZE(dds_format_table); i++) + { + if ((pixel_format->flags & dds_format_table[i].pixel_format.flags) && + (pixel_format->fourCC == dds_format_table[i].pixel_format.fourCC) && + (pixel_format->rgbBitCount == dds_format_table[i].pixel_format.rgbBitCount) && + (pixel_format->rBitMask == dds_format_table[i].pixel_format.rBitMask) && + (pixel_format->gBitMask == dds_format_table[i].pixel_format.gBitMask) && + (pixel_format->bBitMask == dds_format_table[i].pixel_format.bBitMask) && + (pixel_format->aBitMask == dds_format_table[i].pixel_format.aBitMask)) + return dds_format_table + i; + } + + return dds_format_table + ARRAY_SIZE(dds_format_table) - 1; +} + +static WICDdsAlphaMode get_alpha_mode_from_fourcc(DWORD fourcc) +{ + switch (fourcc) + { + case MAKEFOURCC('D', 'X', 'T', '1'): + case MAKEFOURCC('D', 'X', 'T', '2'): + case MAKEFOURCC('D', 'X', 'T', '4'): + return WICDdsAlphaModePremultiplied; + default: + return WICDdsAlphaModeUnknown; + } +} + +static UINT get_bytes_per_block_from_format(DXGI_FORMAT format) +{ + /* for uncompressed format, return bytes per pixel*/ + switch (format) + { + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8_UINT: + case DXGI_FORMAT_R8_SNORM: + case DXGI_FORMAT_R8_SINT: + case DXGI_FORMAT_A8_UNORM: + return 1; + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R8G8_SNORM: + case DXGI_FORMAT_R8G8_SINT: + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R16_SNORM: + case DXGI_FORMAT_R16_SINT: + case DXGI_FORMAT_B5G6R5_UNORM: + case DXGI_FORMAT_B5G5R5A1_UNORM: + case DXGI_FORMAT_B4G4R4A4_UNORM: + return 2; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + case DXGI_FORMAT_R11G11B10_FLOAT: + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_UNORM: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R16G16_SNORM: + case DXGI_FORMAT_R16G16_SINT: + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_UINT: + case DXGI_FORMAT_R32_SINT: + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8X8_UNORM: + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + return 4; + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R16G16B16A16_SNORM: + case DXGI_FORMAT_R16G16B16A16_SINT: + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G32_FLOAT: + case DXGI_FORMAT_R32G32_UINT: + case DXGI_FORMAT_R32G32_SINT: + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + return 8; + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R32G32B32_SINT: + return 12; + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_UINT: + case DXGI_FORMAT_R32G32B32A32_SINT: + return 16; + default: + WARN("DXGI format 0x%x is not supported in DDS decoder\n", format); + return 0; + } +} + +static UINT get_frame_count(UINT depth, UINT mip_levels, UINT array_size, WICDdsDimension dimension) +{ + UINT frame_count, i; + + if (depth == 1) + { + frame_count = mip_levels; + } + else + { + frame_count = 0; + for (i = 0; i < mip_levels; i++) + { + frame_count += depth; + if (depth > 1) depth /= 2; + } + } + + frame_count *= array_size; + if (dimension == WICDdsTextureCube) frame_count *= 6; + + return frame_count; +} + +static void get_frame_dds_index(UINT index, dds_info *info, UINT *array_index, UINT *mip_level, UINT *slice_index) +{ + UINT frame_per_texture, depth; + + if (info->dimension == WICDdsTextureCube) + frame_per_texture = info->mip_levels; + else + frame_per_texture = info->frame_count / info->array_size; + + *array_index = index / frame_per_texture; + *slice_index = index % frame_per_texture; + depth = info->depth; + *mip_level = 0; + while (*slice_index >= depth) + { + *slice_index -= depth; + (*mip_level)++; + if (depth > 1) depth /= 2; + } +} + +static const GUID *dxgi_format_to_wic_format(DXGI_FORMAT dxgi_format) +{ + UINT i; + for (i = 0; i < ARRAY_SIZE(dds_format_table); i++) + { + if (dds_format_table[i].pixel_format.size == 0 && + dds_format_table[i].dxgi_format == dxgi_format) + return dds_format_table[i].wic_format; + } + return &GUID_WICPixelFormatUndefined; +} + +static BOOL is_compressed(DXGI_FORMAT format) +{ + UINT i; + + for (i = 0; i < ARRAY_SIZE(compressed_formats); i++) + { + if (format == compressed_formats[i]) return TRUE; + } + return FALSE; +} + +static void get_dds_info(dds_info* info, DDS_HEADER *header, DDS_HEADER_DXT10 *header_dxt10) +{ + struct dds_format *format_info; + + info->width = header->width; + info->height = header->height; + info->depth = 1; + info->mip_levels = 1; + info->array_size = 1; + if (header->depth) info->depth = header->depth; + if (header->mipMapCount) info->mip_levels = header->mipMapCount; + + if (has_extended_header(header)) { + if (header_dxt10->arraySize) info->array_size = header_dxt10->arraySize; + info->format = header_dxt10->dxgiFormat; + info->dimension = get_dimension(NULL, header_dxt10); + info->alpha_mode = header_dxt10->miscFlags2 & 0x00000008; + info->data_offset = sizeof(DWORD) + sizeof(*header) + sizeof(*header_dxt10); + if (is_compressed(info->format)) { + info->pixel_format = (info->alpha_mode == WICDdsAlphaModePremultiplied) ? + &GUID_WICPixelFormat32bppPBGRA : &GUID_WICPixelFormat32bppBGRA; + info->pixel_format_bpp = 32; + } else { + info->pixel_format = dxgi_format_to_wic_format(info->format); + info->pixel_format_bpp = get_bytes_per_block_from_format(info->format) * 8; + } + } else { + format_info = get_dds_format(&header->ddspf); + info->format = format_info->dxgi_format; + info->dimension = get_dimension(header, NULL); + info->alpha_mode = get_alpha_mode_from_fourcc(header->ddspf.fourCC); + info->data_offset = sizeof(DWORD) + sizeof(*header); + info->pixel_format = format_info->wic_format; + info->pixel_format_bpp = format_info->wic_format_bpp; + } + + if (header->ddspf.flags & (DDPF_RGB | DDPF_ALPHA | DDPF_LUMINANCE)) { + info->bytes_per_block = header->ddspf.rgbBitCount / 8; + } else { + info->bytes_per_block = get_bytes_per_block_from_format(info->format); + } + + info->frame_count = get_frame_count(info->depth, info->mip_levels, info->array_size, info->dimension); +} + +static void decode_block(const BYTE *block_data, UINT block_count, DXGI_FORMAT format, + UINT width, UINT height, DWORD *buffer) +{ + const BYTE *block, *color_indices, *alpha_indices, *alpha_table; + int i, j, x, y, block_x, block_y, color_index, alpha_index; + int block_size, color_offset, color_indices_offset; + WORD color[4], color_value = 0; + BYTE alpha[8], alpha_value = 0; + + if (format == DXGI_FORMAT_BC1_UNORM) { + block_size = 8; + color_offset = 0; + color_indices_offset = 4; + } else { + block_size = 16; + color_offset = 8; + color_indices_offset = 12; + } + block_x = 0; + block_y = 0; + + for (i = 0; i < block_count; i++) + { + block = block_data + i * block_size; + + color[0] = *((WORD *)(block + color_offset)); + color[1] = *((WORD *)(block + color_offset + 2)); + color[2] = MAKE_RGB565(((GET_RGB565_R(color[0]) * 2 + GET_RGB565_R(color[1]) + 1) / 3), + ((GET_RGB565_G(color[0]) * 2 + GET_RGB565_G(color[1]) + 1) / 3), + ((GET_RGB565_B(color[0]) * 2 + GET_RGB565_B(color[1]) + 1) / 3)); + color[3] = MAKE_RGB565(((GET_RGB565_R(color[0]) + GET_RGB565_R(color[1]) * 2 + 1) / 3), + ((GET_RGB565_G(color[0]) + GET_RGB565_G(color[1]) * 2 + 1) / 3), + ((GET_RGB565_B(color[0]) + GET_RGB565_B(color[1]) * 2 + 1) / 3)); + + switch (format) + { + case DXGI_FORMAT_BC1_UNORM: + if (color[0] <= color[1]) { + color[2] = MAKE_RGB565(((GET_RGB565_R(color[0]) + GET_RGB565_R(color[1]) + 1) / 2), + ((GET_RGB565_G(color[0]) + GET_RGB565_G(color[1]) + 1) / 2), + ((GET_RGB565_B(color[0]) + GET_RGB565_B(color[1]) + 1) / 2)); + color[3] = 0; + } + break; + case DXGI_FORMAT_BC2_UNORM: + alpha_table = block; + break; + case DXGI_FORMAT_BC3_UNORM: + alpha[0] = *block; + alpha[1] = *(block + 1); + if (alpha[0] > alpha[1]) { + for (j = 2; j < 8; j++) + { + alpha[j] = (BYTE)((alpha[0] * (8 - j) + alpha[1] * (j - 1) + 3) / 7); + } + } else { + for (j = 2; j < 6; j++) + { + alpha[j] = (BYTE)((alpha[0] * (6 - j) + alpha[1] * (j - 1) + 2) / 5); + } + alpha[6] = 0; + alpha[7] = 0xFF; + } + alpha_indices = block + 2; + break; + default: + break; + } + + color_indices = block + color_indices_offset; + for (j = 0; j < 16; j++) + { + x = block_x + j % 4; + y = block_y + j / 4; + if (x >= width || y >= height) continue; + + color_index = (color_indices[j / 4] >> ((j % 4) * 2)) & 0x3; + color_value = color[color_index]; + + switch (format) + { + case DXGI_FORMAT_BC1_UNORM: + if ((color[0] <= color[1]) && !color_value) { + color_value = 0; + alpha_value = 0; + } else { + alpha_value = 0xFF; + } + break; + case DXGI_FORMAT_BC2_UNORM: + alpha_value = (alpha_table[j / 2] >> (j % 2) * 4) & 0xF; + alpha_value = (BYTE)((alpha_value * 0xFF + 0x7)/ 0xF); + break; + case DXGI_FORMAT_BC3_UNORM: + alpha_index = (*((DWORD *)(alpha_indices + (j / 8) * 3)) >> ((j % 8) * 3)) & 0x7; + alpha_value = alpha[alpha_index]; + break; + default: + break; + } + buffer[x + y * width] = rgb565_to_argb(color_value, alpha_value); + } + + block_x += DDS_BLOCK_WIDTH; + if (block_x >= width) { + block_x = 0; + block_y += DDS_BLOCK_HEIGHT; + } + } +} + +static inline DdsDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface) +{ + return CONTAINING_RECORD(iface, DdsDecoder, IWICBitmapDecoder_iface); +} + +static inline DdsDecoder *impl_from_IWICDdsDecoder(IWICDdsDecoder *iface) +{ + return CONTAINING_RECORD(iface, DdsDecoder, IWICDdsDecoder_iface); +} + +static inline DdsDecoder *impl_from_IWICWineDecoder(IWICWineDecoder *iface) +{ + return CONTAINING_RECORD(iface, DdsDecoder, IWICWineDecoder_iface); +} + +static inline DdsFrameDecode *impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDecode *iface) +{ + return CONTAINING_RECORD(iface, DdsFrameDecode, IWICBitmapFrameDecode_iface); +} + +static inline DdsFrameDecode *impl_from_IWICDdsFrameDecode(IWICDdsFrameDecode *iface) +{ + return CONTAINING_RECORD(iface, DdsFrameDecode, IWICDdsFrameDecode_iface); +} + +static inline DdsEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface) +{ + return CONTAINING_RECORD(iface, DdsEncoder, IWICBitmapEncoder_iface); +} + +static inline DdsEncoder *impl_from_IWICDdsEncoder(IWICDdsEncoder *iface) +{ + return CONTAINING_RECORD(iface, DdsEncoder, IWICDdsEncoder_iface); +} + +static inline DdsFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface) +{ + return CONTAINING_RECORD(iface, DdsFrameEncode, IWICBitmapFrameEncode_iface); +} + +static HRESULT WINAPI DdsFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid, + void **ppv) +{ + DdsFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IWICBitmapSource, iid) || + IsEqualIID(&IID_IWICBitmapFrameDecode, iid)) { + *ppv = &This->IWICBitmapFrameDecode_iface; + } else if (IsEqualGUID(&IID_IWICDdsFrameDecode, iid)) { + *ppv = &This->IWICDdsFrameDecode_iface; + } else { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI DdsFrameDecode_AddRef(IWICBitmapFrameDecode *iface) +{ + DdsFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + return ref; +} + +static ULONG WINAPI DdsFrameDecode_Release(IWICBitmapFrameDecode *iface) +{ + DdsFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + if (ref == 0) { + if (This->pixel_data != This->block_data) free(This->pixel_data); + free(This->block_data); + free(This); + } + + return ref; +} + +static HRESULT WINAPI DdsFrameDecode_GetSize(IWICBitmapFrameDecode *iface, + UINT *puiWidth, UINT *puiHeight) +{ + DdsFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); + + if (!puiWidth || !puiHeight) return E_INVALIDARG; + + *puiWidth = This->info.width; + *puiHeight = This->info.height; + + TRACE("(%p) -> (%d,%d)\n", iface, *puiWidth, *puiHeight); + + return S_OK; +} + +static HRESULT WINAPI DdsFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface, + WICPixelFormatGUID *pPixelFormat) +{ + DdsFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); + + if (!pPixelFormat) return E_INVALIDARG; + + *pPixelFormat = *This->info.pixel_format; + + TRACE("(%p) -> %s\n", iface, debugstr_guid(pPixelFormat)); + + return S_OK; +} + +static HRESULT WINAPI DdsFrameDecode_GetResolution(IWICBitmapFrameDecode *iface, + double *pDpiX, double *pDpiY) +{ + FIXME("(%p,%p,%p): stub.\n", iface, pDpiX, pDpiY); + + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, + IWICPalette *pIPalette) +{ + FIXME("(%p,%p): stub.\n", iface, pIPalette); + + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface, + const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) +{ + DdsFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); + UINT bpp, frame_stride, frame_size; + INT x, y, width, height; + HRESULT hr; + + TRACE("(%p,%s,%u,%u,%p)\n", iface, debug_wic_rect(prc), cbStride, cbBufferSize, pbBuffer); + + if (!pbBuffer) return E_INVALIDARG; + + bpp = This->info.pixel_format_bpp; + if (!bpp) return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + + frame_stride = This->info.width * bpp / 8; + frame_size = frame_stride * This->info.height; + if (!prc) { + if (cbStride < frame_stride) return E_INVALIDARG; + if (cbBufferSize < frame_size) return WINCODEC_ERR_INSUFFICIENTBUFFER; + } else { + x = prc->X; + y = prc->Y; + width = prc->Width; + height = prc->Height; + if (x < 0 || y < 0 || width <= 0 || height <= 0 || + x + width > This->info.width || + y + height > This->info.height) { + return E_INVALIDARG; + } + if (cbStride < width * bpp / 8) return E_INVALIDARG; + if (cbBufferSize < cbStride * height) return WINCODEC_ERR_INSUFFICIENTBUFFER; + } + + EnterCriticalSection(&This->lock); + + if (!This->pixel_data) { + if (is_compressed(This->info.format)) { + This->pixel_data = malloc(frame_size); + if (!This->pixel_data) { + hr = E_OUTOFMEMORY; + goto end; + } + decode_block(This->block_data, This->info.width_in_blocks * This->info.height_in_blocks, This->info.format, + This->info.width, This->info.height, (DWORD *)This->pixel_data); + } else { + This->pixel_data = This->block_data; + } + } + + hr = copy_pixels(bpp, This->pixel_data, This->info.width, This->info.height, frame_stride, + prc, cbStride, cbBufferSize, pbBuffer); + +end: + LeaveCriticalSection(&This->lock); + + return hr; +} + +static HRESULT WINAPI DdsFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDecode *iface, + IWICMetadataQueryReader **ppIMetadataQueryReader) +{ + FIXME("(%p,%p): stub.\n", iface, ppIMetadataQueryReader); + + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsFrameDecode_GetColorContexts(IWICBitmapFrameDecode *iface, + UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) +{ + FIXME("(%p,%u,%p,%p): stub.\n", iface, cCount, ppIColorContexts, pcActualCount); + + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsFrameDecode_GetThumbnail(IWICBitmapFrameDecode *iface, + IWICBitmapSource **ppIThumbnail) +{ + FIXME("(%p,%p): stub.\n", iface, ppIThumbnail); + + return E_NOTIMPL; +} + +static const IWICBitmapFrameDecodeVtbl DdsFrameDecode_Vtbl = { + DdsFrameDecode_QueryInterface, + DdsFrameDecode_AddRef, + DdsFrameDecode_Release, + DdsFrameDecode_GetSize, + DdsFrameDecode_GetPixelFormat, + DdsFrameDecode_GetResolution, + DdsFrameDecode_CopyPalette, + DdsFrameDecode_CopyPixels, + DdsFrameDecode_GetMetadataQueryReader, + DdsFrameDecode_GetColorContexts, + DdsFrameDecode_GetThumbnail +}; + +static HRESULT WINAPI DdsFrameDecode_Dds_QueryInterface(IWICDdsFrameDecode *iface, + REFIID iid, void **ppv) +{ + DdsFrameDecode *This = impl_from_IWICDdsFrameDecode(iface); + return DdsFrameDecode_QueryInterface(&This->IWICBitmapFrameDecode_iface, iid, ppv); +} + +static ULONG WINAPI DdsFrameDecode_Dds_AddRef(IWICDdsFrameDecode *iface) +{ + DdsFrameDecode *This = impl_from_IWICDdsFrameDecode(iface); + return DdsFrameDecode_AddRef(&This->IWICBitmapFrameDecode_iface); +} + +static ULONG WINAPI DdsFrameDecode_Dds_Release(IWICDdsFrameDecode *iface) +{ + DdsFrameDecode *This = impl_from_IWICDdsFrameDecode(iface); + return DdsFrameDecode_Release(&This->IWICBitmapFrameDecode_iface); +} + +static HRESULT WINAPI DdsFrameDecode_Dds_GetSizeInBlocks(IWICDdsFrameDecode *iface, + UINT *widthInBlocks, UINT *heightInBlocks) +{ + DdsFrameDecode *This = impl_from_IWICDdsFrameDecode(iface); + + if (!widthInBlocks || !heightInBlocks) return E_INVALIDARG; + + *widthInBlocks = This->info.width_in_blocks; + *heightInBlocks = This->info.height_in_blocks; + + TRACE("(%p,%p,%p) -> (%d,%d)\n", iface, widthInBlocks, heightInBlocks, *widthInBlocks, *heightInBlocks); + + return S_OK; +} + +static HRESULT WINAPI DdsFrameDecode_Dds_GetFormatInfo(IWICDdsFrameDecode *iface, + WICDdsFormatInfo *formatInfo) +{ + DdsFrameDecode *This = impl_from_IWICDdsFrameDecode(iface); + + if (!formatInfo) return E_INVALIDARG; + + formatInfo->DxgiFormat = This->info.format; + formatInfo->BytesPerBlock = This->info.bytes_per_block; + formatInfo->BlockWidth = This->info.block_width; + formatInfo->BlockHeight = This->info.block_height; + + TRACE("(%p,%p) -> (0x%x,%d,%d,%d)\n", iface, formatInfo, + formatInfo->DxgiFormat, formatInfo->BytesPerBlock, formatInfo->BlockWidth, formatInfo->BlockHeight); + + return S_OK; +} + +static HRESULT WINAPI DdsFrameDecode_Dds_CopyBlocks(IWICDdsFrameDecode *iface, + const WICRect *boundsInBlocks, UINT stride, UINT bufferSize, + BYTE *buffer) +{ + DdsFrameDecode *This = impl_from_IWICDdsFrameDecode(iface); + int x, y, width, height; + UINT bytes_per_block, frame_stride, frame_size; + + TRACE("(%p,%p,%u,%u,%p)\n", iface, boundsInBlocks, stride, bufferSize, buffer); + + if (!buffer) return E_INVALIDARG; + + bytes_per_block = This->info.bytes_per_block; + frame_stride = This->info.width_in_blocks * bytes_per_block; + frame_size = frame_stride * This->info.height_in_blocks; + + if (!boundsInBlocks) { + if (stride < frame_stride) return E_INVALIDARG; + if (bufferSize < frame_size) return E_INVALIDARG; + } else { + x = boundsInBlocks->X; + y = boundsInBlocks->Y; + width = boundsInBlocks->Width; + height = boundsInBlocks->Height; + if (x < 0 || y < 0 || width <= 0 || height <= 0 || + x + width > This->info.width_in_blocks || + y + height > This->info.height_in_blocks) { + return E_INVALIDARG; + } + if (stride < width * bytes_per_block) return E_INVALIDARG; + if (bufferSize < stride * height) return E_INVALIDARG; + } + + return copy_pixels(This->info.bytes_per_block * 8, This->block_data, This->info.width_in_blocks, + This->info.height_in_blocks, frame_stride, boundsInBlocks, stride, bufferSize, buffer); +} + +static const IWICDdsFrameDecodeVtbl DdsFrameDecode_Dds_Vtbl = { + DdsFrameDecode_Dds_QueryInterface, + DdsFrameDecode_Dds_AddRef, + DdsFrameDecode_Dds_Release, + DdsFrameDecode_Dds_GetSizeInBlocks, + DdsFrameDecode_Dds_GetFormatInfo, + DdsFrameDecode_Dds_CopyBlocks +}; + +static HRESULT DdsFrameDecode_CreateInstance(DdsFrameDecode **frame_decode) +{ + DdsFrameDecode *result; + + result = malloc(sizeof(*result)); + if (!result) return E_OUTOFMEMORY; + + result->IWICBitmapFrameDecode_iface.lpVtbl = &DdsFrameDecode_Vtbl; + result->IWICDdsFrameDecode_iface.lpVtbl = &DdsFrameDecode_Dds_Vtbl; + result->ref = 1; +#ifdef __REACTOS__ + InitializeCriticalSection(&result->lock); +#else + InitializeCriticalSectionEx(&result->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif + result->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": DdsFrameDecode.lock"); + + *frame_decode = result; + return S_OK; +} + +static HRESULT WINAPI DdsDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid, + void **ppv) +{ + DdsDecoder *This = impl_from_IWICBitmapDecoder(iface); + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IWICBitmapDecoder, iid)) { + *ppv = &This->IWICBitmapDecoder_iface; + } else if (IsEqualIID(&IID_IWICDdsDecoder, iid)) { + *ppv = &This->IWICDdsDecoder_iface; + } else if (IsEqualIID(&IID_IWICWineDecoder, iid)) { + *ppv = &This->IWICWineDecoder_iface; + } else { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI DdsDecoder_AddRef(IWICBitmapDecoder *iface) +{ + DdsDecoder *This = impl_from_IWICBitmapDecoder(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + return ref; +} + +static ULONG WINAPI DdsDecoder_Release(IWICBitmapDecoder *iface) +{ + DdsDecoder *This = impl_from_IWICBitmapDecoder(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + if (ref == 0) + { + This->lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->lock); + if (This->stream) IStream_Release(This->stream); + free(This); + } + + return ref; +} + +static HRESULT WINAPI DdsDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *stream, + DWORD *capability) +{ + FIXME("(%p,%p,%p): stub.\n", iface, stream, capability); + + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream, + WICDecodeOptions cacheOptions) +{ + DdsDecoder *This = impl_from_IWICBitmapDecoder(iface); + HRESULT hr; + + TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions); + + EnterCriticalSection(&This->lock); + + hr = IWICWineDecoder_Initialize(&This->IWICWineDecoder_iface, pIStream, cacheOptions); + if (FAILED(hr)) goto end; + + if (This->info.dimension == WICDdsTextureCube || + (This->info.format != DXGI_FORMAT_BC1_UNORM && + This->info.format != DXGI_FORMAT_BC2_UNORM && + This->info.format != DXGI_FORMAT_BC3_UNORM)) { + IStream_Release(pIStream); + This->stream = NULL; + This->initialized = FALSE; + hr = WINCODEC_ERR_BADHEADER; + } + +end: + LeaveCriticalSection(&This->lock); + + return hr; +} + +static HRESULT WINAPI DdsDecoder_GetContainerFormat(IWICBitmapDecoder *iface, + GUID *pguidContainerFormat) +{ + TRACE("(%p,%p)\n", iface, pguidContainerFormat); + + memcpy(pguidContainerFormat, &GUID_ContainerFormatDds, sizeof(GUID)); + + return S_OK; +} + +static HRESULT WINAPI DdsDecoder_GetDecoderInfo(IWICBitmapDecoder *iface, + IWICBitmapDecoderInfo **ppIDecoderInfo) +{ + TRACE("(%p,%p)\n", iface, ppIDecoderInfo); + + return get_decoder_info(&CLSID_WICDdsDecoder, ppIDecoderInfo); +} + +static HRESULT WINAPI DdsDecoder_CopyPalette(IWICBitmapDecoder *iface, + IWICPalette *pIPalette) +{ + TRACE("(%p,%p)\n", iface, pIPalette); + + return WINCODEC_ERR_PALETTEUNAVAILABLE; +} + +static HRESULT WINAPI DdsDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface, + IWICMetadataQueryReader **ppIMetadataQueryReader) +{ + if (!ppIMetadataQueryReader) return E_INVALIDARG; + + FIXME("(%p,%p)\n", iface, ppIMetadataQueryReader); + + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsDecoder_GetPreview(IWICBitmapDecoder *iface, + IWICBitmapSource **ppIBitmapSource) +{ + TRACE("(%p,%p)\n", iface, ppIBitmapSource); + + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI DdsDecoder_GetColorContexts(IWICBitmapDecoder *iface, + UINT cCount, IWICColorContext **ppDdslorContexts, UINT *pcActualCount) +{ + TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppDdslorContexts, pcActualCount); + + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI DdsDecoder_GetThumbnail(IWICBitmapDecoder *iface, + IWICBitmapSource **ppIThumbnail) +{ + TRACE("(%p,%p)\n", iface, ppIThumbnail); + + return WINCODEC_ERR_CODECNOTHUMBNAIL; +} + +static HRESULT WINAPI DdsDecoder_GetFrameCount(IWICBitmapDecoder *iface, + UINT *pCount) +{ + DdsDecoder *This = impl_from_IWICBitmapDecoder(iface); + + if (!pCount) return E_INVALIDARG; + if (!This->initialized) return WINCODEC_ERR_WRONGSTATE; + + EnterCriticalSection(&This->lock); + + *pCount = This->info.frame_count; + + LeaveCriticalSection(&This->lock); + + TRACE("(%p) -> %d\n", iface, *pCount); + + return S_OK; +} + +static HRESULT WINAPI DdsDecoder_GetFrame(IWICBitmapDecoder *iface, + UINT index, IWICBitmapFrameDecode **ppIBitmapFrame) +{ + DdsDecoder *This = impl_from_IWICBitmapDecoder(iface); + UINT array_index, mip_level, slice_index; + + TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame); + + if (!ppIBitmapFrame) return E_INVALIDARG; + + EnterCriticalSection(&This->lock); + + if (!This->initialized) { + LeaveCriticalSection(&This->lock); + return WINCODEC_ERR_WRONGSTATE; + } + + get_frame_dds_index(index, &This->info, &array_index, &mip_level, &slice_index); + + LeaveCriticalSection(&This->lock); + + return DdsDecoder_Dds_GetFrame(&This->IWICDdsDecoder_iface, array_index, mip_level, slice_index, ppIBitmapFrame); +} + +static const IWICBitmapDecoderVtbl DdsDecoder_Vtbl = { + DdsDecoder_QueryInterface, + DdsDecoder_AddRef, + DdsDecoder_Release, + DdsDecoder_QueryCapability, + DdsDecoder_Initialize, + DdsDecoder_GetContainerFormat, + DdsDecoder_GetDecoderInfo, + DdsDecoder_CopyPalette, + DdsDecoder_GetMetadataQueryReader, + DdsDecoder_GetPreview, + DdsDecoder_GetColorContexts, + DdsDecoder_GetThumbnail, + DdsDecoder_GetFrameCount, + DdsDecoder_GetFrame +}; + +static HRESULT WINAPI DdsDecoder_Dds_QueryInterface(IWICDdsDecoder *iface, + REFIID iid, void **ppv) +{ + DdsDecoder *This = impl_from_IWICDdsDecoder(iface); + return DdsDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); +} + +static ULONG WINAPI DdsDecoder_Dds_AddRef(IWICDdsDecoder *iface) +{ + DdsDecoder *This = impl_from_IWICDdsDecoder(iface); + return DdsDecoder_AddRef(&This->IWICBitmapDecoder_iface); +} + +static ULONG WINAPI DdsDecoder_Dds_Release(IWICDdsDecoder *iface) +{ + DdsDecoder *This = impl_from_IWICDdsDecoder(iface); + return DdsDecoder_Release(&This->IWICBitmapDecoder_iface); +} + +static HRESULT WINAPI DdsDecoder_Dds_GetParameters(IWICDdsDecoder *iface, + WICDdsParameters *parameters) +{ + DdsDecoder *This = impl_from_IWICDdsDecoder(iface); + HRESULT hr; + + if (!parameters) return E_INVALIDARG; + + EnterCriticalSection(&This->lock); + + if (!This->initialized) { + hr = WINCODEC_ERR_WRONGSTATE; + goto end; + } + + parameters->Width = This->info.width; + parameters->Height = This->info.height; + parameters->Depth = This->info.depth; + parameters->MipLevels = This->info.mip_levels; + parameters->ArraySize = This->info.array_size; + parameters->DxgiFormat = This->info.format; + parameters->Dimension = This->info.dimension; + parameters->AlphaMode = This->info.alpha_mode; + + TRACE("(%p) -> (%dx%d depth=%d mipLevels=%d arraySize=%d dxgiFormat=0x%x dimension=0x%x alphaMode=0x%x)\n", + iface, parameters->Width, parameters->Height, parameters->Depth, parameters->MipLevels, + parameters->ArraySize, parameters->DxgiFormat, parameters->Dimension, parameters->AlphaMode); + + hr = S_OK; + +end: + LeaveCriticalSection(&This->lock); + + return hr; +} + +static HRESULT WINAPI DdsDecoder_Dds_GetFrame(IWICDdsDecoder *iface, + UINT arrayIndex, UINT mipLevel, UINT sliceIndex, + IWICBitmapFrameDecode **bitmapFrame) +{ + DdsDecoder *This = impl_from_IWICDdsDecoder(iface); + HRESULT hr; + LARGE_INTEGER seek; + UINT width, height, depth, block_width, block_height, width_in_blocks, height_in_blocks, size; + UINT frame_width = 0, frame_height = 0, frame_width_in_blocks = 0, frame_height_in_blocks = 0, frame_size = 0; + UINT bytes_per_block, i; + DWORD bytesread; + DdsFrameDecode *frame_decode = NULL; + + TRACE("(%p,%u,%u,%u,%p)\n", iface, arrayIndex, mipLevel, sliceIndex, bitmapFrame); + + if (!bitmapFrame) return E_INVALIDARG; + + EnterCriticalSection(&This->lock); + + if (!This->initialized) { + hr = WINCODEC_ERR_WRONGSTATE; + goto end; + } + + if ((arrayIndex >= This->info.array_size && This->info.dimension != WICDdsTextureCube) || + (arrayIndex >= This->info.array_size * 6) || + (mipLevel >= This->info.mip_levels) || + (sliceIndex >= This->info.depth)) { + hr = E_INVALIDARG; + goto end; + } + + if (is_compressed(This->info.format)) { + block_width = DDS_BLOCK_WIDTH; + block_height = DDS_BLOCK_HEIGHT; + } else { + block_width = 1; + block_height = 1; + } + bytes_per_block = This->info.bytes_per_block; + seek.QuadPart = This->info.data_offset; + + width = This->info.width; + height = This->info.height; + depth = This->info.depth; + for (i = 0; i < This->info.mip_levels; i++) + { + width_in_blocks = (width + block_width - 1) / block_width; + height_in_blocks = (height + block_height - 1) / block_height; + size = width_in_blocks * height_in_blocks * bytes_per_block; + + if (i < mipLevel) { + seek.QuadPart += size * depth; + } else if (i == mipLevel){ + seek.QuadPart += size * sliceIndex; + frame_width = width; + frame_height = height; + frame_width_in_blocks = width_in_blocks; + frame_height_in_blocks = height_in_blocks; + frame_size = frame_width_in_blocks * frame_height_in_blocks * bytes_per_block; + if (arrayIndex == 0) break; + } + seek.QuadPart += arrayIndex * size * depth; + + if (width > 1) width /= 2; + if (height > 1) height /= 2; + if (depth > 1) depth /= 2; + } + + hr = DdsFrameDecode_CreateInstance(&frame_decode); + if (hr != S_OK) goto end; + frame_decode->info.width = frame_width; + frame_decode->info.height = frame_height; + frame_decode->info.format = This->info.format; + frame_decode->info.bytes_per_block = bytes_per_block; + frame_decode->info.block_width = block_width; + frame_decode->info.block_height = block_height; + frame_decode->info.width_in_blocks = frame_width_in_blocks; + frame_decode->info.height_in_blocks = frame_height_in_blocks; + frame_decode->info.pixel_format = This->info.pixel_format; + frame_decode->info.pixel_format_bpp = This->info.pixel_format_bpp; + frame_decode->block_data = malloc(frame_size); + frame_decode->pixel_data = NULL; + hr = IStream_Seek(This->stream, seek, SEEK_SET, NULL); + if (hr != S_OK) goto end; + hr = IStream_Read(This->stream, frame_decode->block_data, frame_size, &bytesread); + if (hr != S_OK || bytesread != frame_size) { + hr = WINCODEC_ERR_STREAMREAD; + goto end; + } + *bitmapFrame = &frame_decode->IWICBitmapFrameDecode_iface; + + hr = S_OK; + +end: + LeaveCriticalSection(&This->lock); + + if (hr != S_OK && frame_decode) DdsFrameDecode_Release(&frame_decode->IWICBitmapFrameDecode_iface); + + return hr; +} + +static const IWICDdsDecoderVtbl DdsDecoder_Dds_Vtbl = { + DdsDecoder_Dds_QueryInterface, + DdsDecoder_Dds_AddRef, + DdsDecoder_Dds_Release, + DdsDecoder_Dds_GetParameters, + DdsDecoder_Dds_GetFrame +}; + +static HRESULT WINAPI DdsDecoder_Wine_QueryInterface(IWICWineDecoder *iface, REFIID iid, void **ppv) +{ + DdsDecoder *This = impl_from_IWICWineDecoder(iface); + return DdsDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); +} + +static ULONG WINAPI DdsDecoder_Wine_AddRef(IWICWineDecoder *iface) +{ + DdsDecoder *This = impl_from_IWICWineDecoder(iface); + return DdsDecoder_AddRef(&This->IWICBitmapDecoder_iface); +} + +static ULONG WINAPI DdsDecoder_Wine_Release(IWICWineDecoder *iface) +{ + DdsDecoder *This = impl_from_IWICWineDecoder(iface); + return DdsDecoder_Release(&This->IWICBitmapDecoder_iface); +} + +static HRESULT WINAPI DdsDecoder_Wine_Initialize(IWICWineDecoder *iface, IStream *stream, WICDecodeOptions options) +{ + DdsDecoder *This = impl_from_IWICWineDecoder(iface); + DDS_HEADER_DXT10 header_dxt10; + LARGE_INTEGER seek; + DDS_HEADER header; + ULONG bytesread; + DWORD magic; + HRESULT hr; + + TRACE("(This %p, stream %p, options %#x)\n", iface, stream, options); + + EnterCriticalSection(&This->lock); + + if (This->initialized) { + hr = WINCODEC_ERR_WRONGSTATE; + goto end; + } + + seek.QuadPart = 0; + hr = IStream_Seek(stream, seek, SEEK_SET, NULL); + if (FAILED(hr)) goto end; + + hr = IStream_Read(stream, &magic, sizeof(magic), &bytesread); + if (FAILED(hr)) goto end; + if (bytesread != sizeof(magic)) { + hr = WINCODEC_ERR_STREAMREAD; + goto end; + } + if (magic != DDS_MAGIC) { + hr = WINCODEC_ERR_UNKNOWNIMAGEFORMAT; + goto end; + } + + hr = IStream_Read(stream, &header, sizeof(header), &bytesread); + if (FAILED(hr)) goto end; + if (bytesread != sizeof(header)) { + hr = WINCODEC_ERR_STREAMREAD; + goto end; + } + if (header.size != sizeof(header)) { + hr = WINCODEC_ERR_BADHEADER; + goto end; + } + + if (has_extended_header(&header)) { + hr = IStream_Read(stream, &header_dxt10, sizeof(header_dxt10), &bytesread); + if (FAILED(hr)) goto end; + if (bytesread != sizeof(header_dxt10)) { + hr = WINCODEC_ERR_STREAMREAD; + goto end; + } + } + + get_dds_info(&This->info, &header, &header_dxt10); + + This->initialized = TRUE; + This->stream = stream; + IStream_AddRef(stream); + +end: + LeaveCriticalSection(&This->lock); + + return hr; +} + +static const IWICWineDecoderVtbl DdsDecoder_Wine_Vtbl = { + DdsDecoder_Wine_QueryInterface, + DdsDecoder_Wine_AddRef, + DdsDecoder_Wine_Release, + DdsDecoder_Wine_Initialize +}; + +static HRESULT WINAPI DdsFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid, void **ppv) +{ + DdsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IWICBitmapFrameEncode, iid)) + { + *ppv = &This->IWICBitmapFrameEncode_iface; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI DdsFrameEncode_AddRef(IWICBitmapFrameEncode *iface) +{ + DdsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + return ref; +} + +static ULONG WINAPI DdsFrameEncode_Release(IWICBitmapFrameEncode *iface) +{ + DdsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + if (ref == 0) + { + IWICBitmapEncoder_Release(&This->parent->IWICBitmapEncoder_iface); + free(This); + } + + return ref; +} + +static HRESULT WINAPI DdsFrameEncode_Initialize(IWICBitmapFrameEncode *iface, + IPropertyBag2 *encoderOptions) +{ + DdsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("(%p,%p)\n", iface, encoderOptions); + if (encoderOptions) FIXME("encoder options are not supported for DDS.\n"); + + EnterCriticalSection(&This->parent->lock); + + if (This->initialized) + { + hr = WINCODEC_ERR_WRONGSTATE; + } + else + { + This->initialized = TRUE; + hr = S_OK; + } + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI DdsFrameEncode_SetSize(IWICBitmapFrameEncode *iface, + UINT width, UINT height) +{ + DdsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("(%p,%u,%u)\n", iface, width, height); + + EnterCriticalSection(&This->parent->lock); + + if (!This->initialized || This->frame_created) + { + hr = WINCODEC_ERR_WRONGSTATE; + } + else + { + This->width = width; + This->height = height; + hr = S_OK; + } + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI DdsFrameEncode_SetResolution(IWICBitmapFrameEncode *iface, + double dpiX, double dpiY) +{ + DdsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY); + + EnterCriticalSection(&This->parent->lock); + + if (!This->initialized || This->frame_created) + { + hr = WINCODEC_ERR_WRONGSTATE; + } + else + { + This->dpi_x = dpiX; + This->dpi_y = dpiY; + hr = S_OK; + } + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI DdsFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface, + WICPixelFormatGUID *pixelFormat) +{ + DdsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("(%p,%s)\n", iface, debugstr_guid(pixelFormat)); + + EnterCriticalSection(&This->parent->lock); + + if (!This->initialized) + { + hr = WINCODEC_ERR_NOTINITIALIZED; + } + else if (This->frame_created) + { + hr = WINCODEC_ERR_WRONGSTATE; + } + else + { + *pixelFormat = GUID_WICPixelFormat32bppBGRA; + hr = S_OK; + } + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI DdsFrameEncode_SetColorContexts(IWICBitmapFrameEncode *iface, + UINT count, IWICColorContext **colorContext) +{ + FIXME("(%p,%u,%p): stub\n", iface, count, colorContext); + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsFrameEncode_SetPalette(IWICBitmapFrameEncode *iface, + IWICPalette *palette) +{ + FIXME("(%p,%p): stub\n", iface, palette); + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface, + IWICBitmapSource *thumbnail) +{ + TRACE("(%p,%p)\n", iface, thumbnail); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI DdsFrameEncode_WritePixels(IWICBitmapFrameEncode *iface, + UINT lineCount, UINT stride, UINT bufferSize, BYTE *pixels) +{ + FIXME("(%p,%u,%u,%u,%p): stub\n", iface, lineCount, stride, bufferSize, pixels); + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsFrameEncode_WriteSource(IWICBitmapFrameEncode *iface, + IWICBitmapSource *bitmapSource, WICRect *rc) +{ + FIXME("(%p,%p,%s): stub\n", iface, bitmapSource, debug_wic_rect(rc)); + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsFrameEncode_Commit(IWICBitmapFrameEncode *iface) +{ + FIXME("(%p): stub\n", iface); + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface, + IWICMetadataQueryWriter **metadataQueryWriter) +{ + FIXME("(%p,%p): stub\n", iface, metadataQueryWriter); + return E_NOTIMPL; +} + +static const IWICBitmapFrameEncodeVtbl DdsFrameEncode_Vtbl = { + DdsFrameEncode_QueryInterface, + DdsFrameEncode_AddRef, + DdsFrameEncode_Release, + DdsFrameEncode_Initialize, + DdsFrameEncode_SetSize, + DdsFrameEncode_SetResolution, + DdsFrameEncode_SetPixelFormat, + DdsFrameEncode_SetColorContexts, + DdsFrameEncode_SetPalette, + DdsFrameEncode_SetThumbnail, + DdsFrameEncode_WritePixels, + DdsFrameEncode_WriteSource, + DdsFrameEncode_Commit, + DdsFrameEncode_GetMetadataQueryWriter +}; + +HRESULT DdsDecoder_CreateInstance(REFIID iid, void** ppv) +{ + DdsDecoder *This; + HRESULT ret; + + TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); + + *ppv = NULL; + + This = malloc(sizeof(DdsDecoder)); + if (!This) return E_OUTOFMEMORY; + + This->IWICBitmapDecoder_iface.lpVtbl = &DdsDecoder_Vtbl; + This->IWICDdsDecoder_iface.lpVtbl = &DdsDecoder_Dds_Vtbl; + This->IWICWineDecoder_iface.lpVtbl = &DdsDecoder_Wine_Vtbl; + This->ref = 1; + This->initialized = FALSE; + This->stream = NULL; +#ifdef __REACTOS__ + InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif + This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": DdsDecoder.lock"); + + ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); + IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface); + + return ret; +} + +static HRESULT WINAPI DdsEncoder_Dds_QueryInterface(IWICDdsEncoder *iface, REFIID iid, + void **ppv) +{ + DdsEncoder *This = impl_from_IWICDdsEncoder(iface); + return IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv); +} + +static ULONG WINAPI DdsEncoder_Dds_AddRef(IWICDdsEncoder *iface) +{ + DdsEncoder *This = impl_from_IWICDdsEncoder(iface); + return IWICBitmapEncoder_AddRef(&This->IWICBitmapEncoder_iface); +} + +static ULONG WINAPI DdsEncoder_Dds_Release(IWICDdsEncoder *iface) +{ + DdsEncoder *This = impl_from_IWICDdsEncoder(iface); + return IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface); +} + +static HRESULT WINAPI DdsEncoder_Dds_SetParameters(IWICDdsEncoder *iface, + WICDdsParameters *parameters) +{ + DdsEncoder *This = impl_from_IWICDdsEncoder(iface); + HRESULT hr; + + TRACE("(%p,%p)\n", iface, parameters); + + if (!parameters) return E_INVALIDARG; + + EnterCriticalSection(&This->lock); + + if (!This->stream) + { + hr = WINCODEC_ERR_WRONGSTATE; + goto end; + } + + This->info.width = parameters->Width; + This->info.height = parameters->Height; + This->info.depth = parameters->Depth; + This->info.mip_levels = parameters->MipLevels; + This->info.array_size = parameters->ArraySize; + This->info.format = parameters->DxgiFormat; + This->info.dimension = parameters->Dimension; + This->info.alpha_mode = parameters->AlphaMode; + + This->info.bytes_per_block = get_bytes_per_block_from_format(This->info.format); + This->info.frame_count = get_frame_count(This->info.depth, This->info.mip_levels, + This->info.array_size, This->info.dimension); + + hr = S_OK; + +end: + LeaveCriticalSection(&This->lock); + return hr; +} + +static HRESULT WINAPI DdsEncoder_Dds_GetParameters(IWICDdsEncoder *iface, + WICDdsParameters *parameters) +{ + DdsEncoder *This = impl_from_IWICDdsEncoder(iface); + HRESULT hr; + + TRACE("(%p,%p)\n", iface, parameters); + + if (!parameters) return E_INVALIDARG; + + EnterCriticalSection(&This->lock); + + if (!This->stream) + { + hr = WINCODEC_ERR_WRONGSTATE; + goto end; + } + + parameters->Width = This->info.width; + parameters->Height = This->info.height; + parameters->Depth = This->info.depth; + parameters->MipLevels = This->info.mip_levels; + parameters->ArraySize = This->info.array_size; + parameters->DxgiFormat = This->info.format; + parameters->Dimension = This->info.dimension; + parameters->AlphaMode = This->info.alpha_mode; + + TRACE("(%p,%p) -> (%dx%d depth=%u mipLevels=%u arraySize=%u dxgiFormat=%#x dimension=%#x alphaMode=%#x)\n", + iface, parameters, parameters->Width, parameters->Height, parameters->Depth, parameters->MipLevels, + parameters->ArraySize, parameters->DxgiFormat, parameters->Dimension, parameters->AlphaMode); + + hr = S_OK; + +end: + LeaveCriticalSection(&This->lock); + return hr; +} + +static HRESULT WINAPI DdsEncoder_Dds_CreateNewFrame(IWICDdsEncoder *iface, + IWICBitmapFrameEncode **frameEncode, + UINT *arrayIndex, UINT *mipLevel, UINT *sliceIndex) +{ + DdsEncoder *This = impl_from_IWICDdsEncoder(iface); + UINT array_index, mip_level, slice_index; + DdsFrameEncode *result; + HRESULT hr; + + TRACE("(%p,%p,%p,%p,%p)\n", iface, frameEncode, arrayIndex, mipLevel, sliceIndex); + + EnterCriticalSection(&This->lock); + + if (!This->stream || This->committed || This->uncommitted_frame) + { + hr = WINCODEC_ERR_WRONGSTATE; + goto end; + } + + result = malloc(sizeof(*result)); + if (!result) + { + hr = E_OUTOFMEMORY; + goto end; + } + + get_frame_dds_index(This->frame_index, &This->info, &array_index, &mip_level, &slice_index); + if (arrayIndex) *arrayIndex = array_index; + if (mipLevel) *mipLevel = mip_level; + if (sliceIndex) *sliceIndex = slice_index; + + This->frame_index++; + result->IWICBitmapFrameEncode_iface.lpVtbl = &DdsFrameEncode_Vtbl; + result->ref = 1; + result->parent = This; + result->parent->uncommitted_frame = TRUE; + result->initialized = FALSE; + result->frame_created = FALSE; + IWICDdsEncoder_AddRef(iface); + + *frameEncode = &result->IWICBitmapFrameEncode_iface; + hr = S_OK; + +end: + LeaveCriticalSection(&This->lock); + return hr; +} + +static const IWICDdsEncoderVtbl DdsEncoder_Dds_Vtbl = +{ + DdsEncoder_Dds_QueryInterface, + DdsEncoder_Dds_AddRef, + DdsEncoder_Dds_Release, + DdsEncoder_Dds_SetParameters, + DdsEncoder_Dds_GetParameters, + DdsEncoder_Dds_CreateNewFrame +}; + +static HRESULT WINAPI DdsEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid, + void **ppv) +{ + DdsEncoder *This = impl_from_IWICBitmapEncoder(iface); + FIXME("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IWICBitmapEncoder, iid)) { + *ppv = &This->IWICBitmapEncoder_iface; + } else if (IsEqualIID(&IID_IWICDdsEncoder, iid)) { + *ppv = &This->IWICDdsEncoder_iface; + } else { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI DdsEncoder_AddRef(IWICBitmapEncoder *iface) +{ + DdsEncoder *This = impl_from_IWICBitmapEncoder(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + return ref; +} + +static ULONG WINAPI DdsEncoder_Release(IWICBitmapEncoder *iface) +{ + DdsEncoder *This = impl_from_IWICBitmapEncoder(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + if (ref == 0) { + This->lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->lock); + if (This->stream) IStream_Release(This->stream); + free(This); + } + + return ref; +} + +static HRESULT WINAPI DdsEncoder_Initialize(IWICBitmapEncoder *iface, + IStream *stream, WICBitmapEncoderCacheOption cacheOption) +{ + DdsEncoder *This = impl_from_IWICBitmapEncoder(iface); + HRESULT hr; + + TRACE("(%p,%p,%u)\n", iface, stream, cacheOption); + + if (cacheOption != WICBitmapEncoderNoCache) + FIXME("Cache option %#x is not supported.\n", cacheOption); + + if (!stream) return E_INVALIDARG; + + EnterCriticalSection(&This->lock); + + if (This->stream) + { + hr = WINCODEC_ERR_WRONGSTATE; + goto end; + } + + This->stream = stream; + IStream_AddRef(stream); + + This->info.width = 1; + This->info.height = 1; + This->info.depth = 1; + This->info.mip_levels = 1; + This->info.array_size = 1; + This->info.frame_count = 1; + This->info.data_offset = 0; + This->info.bytes_per_block = get_bytes_per_block_from_format(DXGI_FORMAT_BC3_UNORM); + This->info.format = DXGI_FORMAT_BC3_UNORM; + This->info.dimension = WICDdsTexture2D; + This->info.alpha_mode = WICDdsAlphaModeUnknown; + This->info.pixel_format = &GUID_WICPixelFormatUndefined; + This->info.pixel_format_bpp = 0; + + hr = S_OK; + +end: + LeaveCriticalSection(&This->lock); + + return hr; +} + +static HRESULT WINAPI DdsEncoder_GetContainerFormat(IWICBitmapEncoder *iface, GUID *format) +{ + TRACE("(%p,%p)\n", iface, format); + + if (!format) + return E_INVALIDARG; + + memcpy(format, &GUID_ContainerFormatDds, sizeof(*format)); + return S_OK; +} + +static HRESULT WINAPI DdsEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info) +{ + IWICComponentInfo *comp_info; + HRESULT hr; + + TRACE("%p,%p\n", iface, info); + + if (!info) return E_INVALIDARG; + + hr = CreateComponentInfo(&CLSID_WICDdsEncoder, &comp_info); + if (hr == S_OK) { + hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info); + IWICComponentInfo_Release(comp_info); + } + return hr; +} + +static HRESULT WINAPI DdsEncoder_SetColorContexts(IWICBitmapEncoder *iface, + UINT cCount, IWICColorContext **ppIColorContext) +{ + FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *palette) +{ + DdsEncoder *This = impl_from_IWICBitmapEncoder(iface); + HRESULT hr; + + TRACE("(%p,%p)\n", iface, palette); + + EnterCriticalSection(&This->lock); + + hr = This->stream ? WINCODEC_ERR_UNSUPPORTEDOPERATION : WINCODEC_ERR_NOTINITIALIZED; + + LeaveCriticalSection(&This->lock); + + return hr; +} + +static HRESULT WINAPI DdsEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail) +{ + TRACE("(%p,%p)\n", iface, pIThumbnail); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI DdsEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *pIPreview) +{ + TRACE("(%p,%p)\n", iface, pIPreview); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI DdsEncoder_CreateNewFrame(IWICBitmapEncoder *iface, + IWICBitmapFrameEncode **frameEncode, IPropertyBag2 **encoderOptions) +{ + DdsEncoder *This = impl_from_IWICBitmapEncoder(iface); + + TRACE("(%p,%p,%p)\n", iface, frameEncode, encoderOptions); + + return IWICDdsEncoder_CreateNewFrame(&This->IWICDdsEncoder_iface, frameEncode, NULL, NULL, NULL); +} + +static HRESULT WINAPI DdsEncoder_Commit(IWICBitmapEncoder *iface) +{ + FIXME("(%p): stub\n", iface); + return E_NOTIMPL; +} + +static HRESULT WINAPI DdsEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface, + IWICMetadataQueryWriter **ppIMetadataQueryWriter) +{ + FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryWriter); + return E_NOTIMPL; +} + +static const IWICBitmapEncoderVtbl DdsEncoder_Vtbl = { + DdsEncoder_QueryInterface, + DdsEncoder_AddRef, + DdsEncoder_Release, + DdsEncoder_Initialize, + DdsEncoder_GetContainerFormat, + DdsEncoder_GetEncoderInfo, + DdsEncoder_SetColorContexts, + DdsEncoder_SetPalette, + DdsEncoder_SetThumbnail, + DdsEncoder_SetPreview, + DdsEncoder_CreateNewFrame, + DdsEncoder_Commit, + DdsEncoder_GetMetadataQueryWriter +}; + +HRESULT DdsEncoder_CreateInstance( REFIID iid, void **ppv) +{ + DdsEncoder *This; + HRESULT ret; + + TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); + + *ppv = NULL; + + This = malloc(sizeof(DdsEncoder)); + if (!This) return E_OUTOFMEMORY; + + This->IWICBitmapEncoder_iface.lpVtbl = &DdsEncoder_Vtbl; + This->IWICDdsEncoder_iface.lpVtbl = &DdsEncoder_Dds_Vtbl; + This->ref = 1; + This->stream = NULL; + This->frame_count = 0; + This->frame_index = 0; + This->uncommitted_frame = FALSE; + This->committed = FALSE; +#ifdef __REACTOS__ + InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif + This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": DdsEncoder.lock"); + + ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv); + IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface); + + return ret; +} diff --git a/dll/win32/windowscodecs/decoder.c b/dll/win32/windowscodecs/decoder.c new file mode 100644 index 00000000000..08fe23e1bf0 --- /dev/null +++ b/dll/win32/windowscodecs/decoder.c @@ -0,0 +1,811 @@ +/* + * Copyright 2020 Esme Povirk + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + +typedef struct { + IWICBitmapDecoder IWICBitmapDecoder_iface; + LONG ref; + CRITICAL_SECTION lock; /* must be held when stream or decoder is accessed */ + IStream *stream; + struct decoder *decoder; + struct decoder_info decoder_info; + struct decoder_stat file_info; + WICDecodeOptions cache_options; +} CommonDecoder; + +static inline CommonDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface) +{ + return CONTAINING_RECORD(iface, CommonDecoder, IWICBitmapDecoder_iface); +} + +static HRESULT WINAPI CommonDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid, + void **ppv) +{ + CommonDecoder *This = impl_from_IWICBitmapDecoder(iface); + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICBitmapDecoder, iid)) + { + *ppv = &This->IWICBitmapDecoder_iface; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI CommonDecoder_AddRef(IWICBitmapDecoder *iface) +{ + CommonDecoder *This = impl_from_IWICBitmapDecoder(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + return ref; +} + +static ULONG WINAPI CommonDecoder_Release(IWICBitmapDecoder *iface) +{ + CommonDecoder *This = impl_from_IWICBitmapDecoder(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + if (ref == 0) + { + if (This->stream) + IStream_Release(This->stream); + This->lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->lock); + decoder_destroy(This->decoder); + free(This); + } + + return ref; +} + +static HRESULT WINAPI CommonDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *stream, + DWORD *capability) +{ + CommonDecoder *This = impl_from_IWICBitmapDecoder(iface); + HRESULT hr; + + TRACE("(%p,%p,%p)\n", iface, stream, capability); + + if (!stream || !capability) return E_INVALIDARG; + + hr = IWICBitmapDecoder_Initialize(iface, stream, WICDecodeMetadataCacheOnDemand); + if (hr != S_OK) return hr; + + *capability = (This->file_info.flags & DECODER_FLAGS_CAPABILITY_MASK); + return S_OK; +} + +static HRESULT WINAPI CommonDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream, + WICDecodeOptions cacheOptions) +{ + CommonDecoder *This = impl_from_IWICBitmapDecoder(iface); + HRESULT hr=S_OK; + + TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions); + + EnterCriticalSection(&This->lock); + + if (This->stream) + hr = WINCODEC_ERR_WRONGSTATE; + + if (SUCCEEDED(hr)) + hr = decoder_initialize(This->decoder, pIStream, &This->file_info); + + if (SUCCEEDED(hr)) + { + This->cache_options = cacheOptions; + This->stream = pIStream; + IStream_AddRef(This->stream); + } + + LeaveCriticalSection(&This->lock); + + return hr; +} + +static HRESULT WINAPI CommonDecoder_GetContainerFormat(IWICBitmapDecoder *iface, + GUID *pguidContainerFormat) +{ + CommonDecoder *This = impl_from_IWICBitmapDecoder(iface); + memcpy(pguidContainerFormat, &This->decoder_info.container_format, sizeof(GUID)); + return S_OK; +} + +static HRESULT WINAPI CommonDecoder_GetDecoderInfo(IWICBitmapDecoder *iface, + IWICBitmapDecoderInfo **ppIDecoderInfo) +{ + CommonDecoder *This = impl_from_IWICBitmapDecoder(iface); + TRACE("(%p,%p)\n", iface, ppIDecoderInfo); + + return get_decoder_info(&This->decoder_info.clsid, ppIDecoderInfo); +} + +static HRESULT WINAPI CommonDecoder_CopyPalette(IWICBitmapDecoder *iface, + IWICPalette *palette) +{ + TRACE("(%p,%p)\n", iface, palette); + return WINCODEC_ERR_PALETTEUNAVAILABLE; +} + +static HRESULT WINAPI CommonDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface, + IWICMetadataQueryReader **reader) +{ + TRACE("(%p,%p)\n", iface, reader); + + if (!reader) return E_INVALIDARG; + + *reader = NULL; + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI CommonDecoder_GetPreview(IWICBitmapDecoder *iface, + IWICBitmapSource **ppIBitmapSource) +{ + TRACE("(%p,%p)\n", iface, ppIBitmapSource); + + if (!ppIBitmapSource) return E_INVALIDARG; + + *ppIBitmapSource = NULL; + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI CommonDecoder_GetColorContexts(IWICBitmapDecoder *iface, + UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) +{ + TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI CommonDecoder_GetThumbnail(IWICBitmapDecoder *iface, + IWICBitmapSource **ppIThumbnail) +{ + TRACE("(%p,%p)\n", iface, ppIThumbnail); + + if (!ppIThumbnail) return E_INVALIDARG; + + *ppIThumbnail = NULL; + return WINCODEC_ERR_CODECNOTHUMBNAIL; +} + +static HRESULT WINAPI CommonDecoder_GetFrameCount(IWICBitmapDecoder *iface, + UINT *pCount) +{ + CommonDecoder *This = impl_from_IWICBitmapDecoder(iface); + if (!pCount) return E_INVALIDARG; + + if (This->stream) + *pCount = This->file_info.frame_count; + else + *pCount = 0; + + return S_OK; +} + +static HRESULT WINAPI CommonDecoder_GetFrame(IWICBitmapDecoder *iface, + UINT index, IWICBitmapFrameDecode **ppIBitmapFrame); + +static const IWICBitmapDecoderVtbl CommonDecoder_Vtbl = { + CommonDecoder_QueryInterface, + CommonDecoder_AddRef, + CommonDecoder_Release, + CommonDecoder_QueryCapability, + CommonDecoder_Initialize, + CommonDecoder_GetContainerFormat, + CommonDecoder_GetDecoderInfo, + CommonDecoder_CopyPalette, + CommonDecoder_GetMetadataQueryReader, + CommonDecoder_GetPreview, + CommonDecoder_GetColorContexts, + CommonDecoder_GetThumbnail, + CommonDecoder_GetFrameCount, + CommonDecoder_GetFrame +}; + +typedef struct { + IWICBitmapFrameDecode IWICBitmapFrameDecode_iface; + IWICMetadataBlockReader IWICMetadataBlockReader_iface; + LONG ref; + CommonDecoder *parent; + DWORD frame; + struct decoder_frame decoder_frame; + BOOL metadata_initialized; + UINT metadata_count; + struct decoder_block* metadata_blocks; +} CommonDecoderFrame; + +static inline CommonDecoderFrame *impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDecode *iface) +{ + return CONTAINING_RECORD(iface, CommonDecoderFrame, IWICBitmapFrameDecode_iface); +} + +static inline CommonDecoderFrame *impl_from_IWICMetadataBlockReader(IWICMetadataBlockReader *iface) +{ + return CONTAINING_RECORD(iface, CommonDecoderFrame, IWICMetadataBlockReader_iface); +} + +static HRESULT WINAPI CommonDecoderFrame_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid, + void **ppv) +{ + CommonDecoderFrame *This = impl_from_IWICBitmapFrameDecode(iface); + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IWICBitmapSource, iid) || + IsEqualIID(&IID_IWICBitmapFrameDecode, iid)) + { + *ppv = &This->IWICBitmapFrameDecode_iface; + } + else if (IsEqualIID(&IID_IWICMetadataBlockReader, iid) && + (This->parent->file_info.flags & WICBitmapDecoderCapabilityCanEnumerateMetadata)) + { + *ppv = &This->IWICMetadataBlockReader_iface; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI CommonDecoderFrame_AddRef(IWICBitmapFrameDecode *iface) +{ + CommonDecoderFrame *This = impl_from_IWICBitmapFrameDecode(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + return ref; +} + +static ULONG WINAPI CommonDecoderFrame_Release(IWICBitmapFrameDecode *iface) +{ + CommonDecoderFrame *This = impl_from_IWICBitmapFrameDecode(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + if (ref == 0) + { + IWICBitmapDecoder_Release(&This->parent->IWICBitmapDecoder_iface); + free(This->metadata_blocks); + free(This); + } + + return ref; +} + +static HRESULT WINAPI CommonDecoderFrame_GetSize(IWICBitmapFrameDecode *iface, + UINT *puiWidth, UINT *puiHeight) +{ + CommonDecoderFrame *This = impl_from_IWICBitmapFrameDecode(iface); + + TRACE("(%p,%p,%p)\n", This, puiWidth, puiHeight); + + if (!puiWidth || !puiHeight) + return E_POINTER; + + *puiWidth = This->decoder_frame.width; + *puiHeight = This->decoder_frame.height; + return S_OK; +} + +static HRESULT WINAPI CommonDecoderFrame_GetPixelFormat(IWICBitmapFrameDecode *iface, + WICPixelFormatGUID *pPixelFormat) +{ + CommonDecoderFrame *This = impl_from_IWICBitmapFrameDecode(iface); + + TRACE("(%p,%p)\n", This, pPixelFormat); + + if (!pPixelFormat) + return E_POINTER; + + *pPixelFormat = This->decoder_frame.pixel_format; + return S_OK; +} + +static HRESULT WINAPI CommonDecoderFrame_GetResolution(IWICBitmapFrameDecode *iface, + double *pDpiX, double *pDpiY) +{ + CommonDecoderFrame *This = impl_from_IWICBitmapFrameDecode(iface); + + TRACE("(%p,%p,%p)\n", This, pDpiX, pDpiY); + + if (!pDpiX || !pDpiY) + return E_POINTER; + + *pDpiX = This->decoder_frame.dpix; + *pDpiY = This->decoder_frame.dpiy; + return S_OK; +} + +static HRESULT WINAPI CommonDecoderFrame_CopyPalette(IWICBitmapFrameDecode *iface, + IWICPalette *pIPalette) +{ + CommonDecoderFrame *This = impl_from_IWICBitmapFrameDecode(iface); + HRESULT hr=S_OK; + + TRACE("(%p,%p)\n", iface, pIPalette); + + if (This->decoder_frame.num_colors) + { + hr = IWICPalette_InitializeCustom(pIPalette, This->decoder_frame.palette, This->decoder_frame.num_colors); + } + else + { + hr = WINCODEC_ERR_PALETTEUNAVAILABLE; + } + + return hr; +} + +static HRESULT WINAPI CommonDecoderFrame_CopyPixels(IWICBitmapFrameDecode *iface, + const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) +{ + CommonDecoderFrame *This = impl_from_IWICBitmapFrameDecode(iface); + HRESULT hr; + UINT bytesperrow; + WICRect rect; + + TRACE("(%p,%s,%u,%u,%p)\n", iface, debug_wic_rect(prc), cbStride, cbBufferSize, pbBuffer); + + if (!pbBuffer) + return E_POINTER; + + if (!prc) + { + rect.X = 0; + rect.Y = 0; + rect.Width = This->decoder_frame.width; + rect.Height = This->decoder_frame.height; + prc = ▭ + } + else + { + if (prc->X < 0 || prc->Y < 0 || + prc->X+prc->Width > This->decoder_frame.width || + prc->Y+prc->Height > This->decoder_frame.height) + return E_INVALIDARG; + } + + bytesperrow = ((This->decoder_frame.bpp * prc->Width)+7)/8; + + if (cbStride < bytesperrow) + return E_INVALIDARG; + + if ((cbStride * (prc->Height-1)) + bytesperrow > cbBufferSize) + return E_INVALIDARG; + + EnterCriticalSection(&This->parent->lock); + + hr = decoder_copy_pixels(This->parent->decoder, This->frame, + prc, cbStride, cbBufferSize, pbBuffer); + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI CommonDecoderFrame_GetMetadataQueryReader(IWICBitmapFrameDecode *iface, + IWICMetadataQueryReader **ppIMetadataQueryReader) +{ + CommonDecoderFrame *This = impl_from_IWICBitmapFrameDecode(iface); + IWICComponentFactory* factory; + HRESULT hr; + + TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader); + + if (!ppIMetadataQueryReader) + return E_INVALIDARG; + + if (!(This->parent->file_info.flags & WICBitmapDecoderCapabilityCanEnumerateMetadata)) + return WINCODEC_ERR_UNSUPPORTEDOPERATION; + + hr = create_instance(&CLSID_WICImagingFactory, &IID_IWICComponentFactory, (void**)&factory); + + if (SUCCEEDED(hr)) + { + hr = IWICComponentFactory_CreateQueryReaderFromBlockReader(factory, &This->IWICMetadataBlockReader_iface, ppIMetadataQueryReader); + IWICComponentFactory_Release(factory); + } + + if (FAILED(hr)) + *ppIMetadataQueryReader = NULL; + + return hr; +} + +static HRESULT WINAPI CommonDecoderFrame_GetColorContexts(IWICBitmapFrameDecode *iface, + UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) +{ + CommonDecoderFrame *This = impl_from_IWICBitmapFrameDecode(iface); + HRESULT hr=S_OK; + UINT i; + BYTE *profile; + DWORD profile_len; + + TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount); + + if (!pcActualCount) return E_INVALIDARG; + + if (This->parent->file_info.flags & DECODER_FLAGS_UNSUPPORTED_COLOR_CONTEXT) + { + FIXME("not supported for %s\n", wine_dbgstr_guid(&This->parent->decoder_info.clsid)); + *pcActualCount = 0; + return WINCODEC_ERR_UNSUPPORTEDOPERATION; + } + + *pcActualCount = This->decoder_frame.num_color_contexts; + + if (This->decoder_frame.num_color_contexts && cCount && ppIColorContexts) + { + if (cCount >= This->decoder_frame.num_color_contexts) + { + EnterCriticalSection(&This->parent->lock); + + for (i=0; idecoder_frame.num_color_contexts; i++) + { + hr = decoder_get_color_context(This->parent->decoder, This->frame, i, + &profile, &profile_len); + if (SUCCEEDED(hr)) + { + hr = IWICColorContext_InitializeFromMemory(ppIColorContexts[i], profile, profile_len); + + free(profile); + } + + if (FAILED(hr)) + break; + } + + LeaveCriticalSection(&This->parent->lock); + } + else + { + hr = E_INVALIDARG; + } + } + + return hr; +} + +static HRESULT WINAPI CommonDecoderFrame_GetThumbnail(IWICBitmapFrameDecode *iface, + IWICBitmapSource **ppIThumbnail) +{ + TRACE("(%p,%p)\n", iface, ppIThumbnail); + + if (!ppIThumbnail) return E_INVALIDARG; + + *ppIThumbnail = NULL; + return WINCODEC_ERR_CODECNOTHUMBNAIL; +} + +static const IWICBitmapFrameDecodeVtbl CommonDecoderFrameVtbl = { + CommonDecoderFrame_QueryInterface, + CommonDecoderFrame_AddRef, + CommonDecoderFrame_Release, + CommonDecoderFrame_GetSize, + CommonDecoderFrame_GetPixelFormat, + CommonDecoderFrame_GetResolution, + CommonDecoderFrame_CopyPalette, + CommonDecoderFrame_CopyPixels, + CommonDecoderFrame_GetMetadataQueryReader, + CommonDecoderFrame_GetColorContexts, + CommonDecoderFrame_GetThumbnail +}; + +static HRESULT WINAPI CommonDecoderFrame_Block_QueryInterface(IWICMetadataBlockReader *iface, REFIID iid, + void **ppv) +{ + CommonDecoderFrame *This = impl_from_IWICMetadataBlockReader(iface); + return IWICBitmapFrameDecode_QueryInterface(&This->IWICBitmapFrameDecode_iface, iid, ppv); +} + +static ULONG WINAPI CommonDecoderFrame_Block_AddRef(IWICMetadataBlockReader *iface) +{ + CommonDecoderFrame *This = impl_from_IWICMetadataBlockReader(iface); + return IWICBitmapFrameDecode_AddRef(&This->IWICBitmapFrameDecode_iface); +} + +static ULONG WINAPI CommonDecoderFrame_Block_Release(IWICMetadataBlockReader *iface) +{ + CommonDecoderFrame *This = impl_from_IWICMetadataBlockReader(iface); + return IWICBitmapFrameDecode_Release(&This->IWICBitmapFrameDecode_iface); +} + +static HRESULT WINAPI CommonDecoderFrame_Block_GetContainerFormat(IWICMetadataBlockReader *iface, + GUID *pguidContainerFormat) +{ + CommonDecoderFrame *This = impl_from_IWICMetadataBlockReader(iface); + if (!pguidContainerFormat) return E_INVALIDARG; + *pguidContainerFormat = This->parent->decoder_info.block_format; + return S_OK; +} + +static HRESULT CommonDecoderFrame_InitializeMetadata(CommonDecoderFrame *This) +{ + HRESULT hr=S_OK; + + if (This->metadata_initialized) + return S_OK; + + EnterCriticalSection(&This->parent->lock); + + if (!This->metadata_initialized) + { + hr = decoder_get_metadata_blocks(This->parent->decoder, This->frame, &This->metadata_count, &This->metadata_blocks); + if (SUCCEEDED(hr)) + This->metadata_initialized = TRUE; + } + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI CommonDecoderFrame_Block_GetCount(IWICMetadataBlockReader *iface, + UINT *pcCount) +{ + CommonDecoderFrame *This = impl_from_IWICMetadataBlockReader(iface); + HRESULT hr; + + TRACE("%p,%p\n", iface, pcCount); + + if (!pcCount) return E_INVALIDARG; + + hr = CommonDecoderFrame_InitializeMetadata(This); + if (SUCCEEDED(hr)) + *pcCount = This->metadata_count; + + return hr; +} + +static HRESULT WINAPI CommonDecoderFrame_Block_GetReaderByIndex(IWICMetadataBlockReader *iface, + UINT nIndex, IWICMetadataReader **ppIMetadataReader) +{ + CommonDecoderFrame *This = impl_from_IWICMetadataBlockReader(iface); + HRESULT hr; + IWICComponentFactory* factory = NULL; + IWICStream* stream; + + TRACE("%p,%d,%p\n", iface, nIndex, ppIMetadataReader); + + if (!ppIMetadataReader) + return E_INVALIDARG; + + hr = CommonDecoderFrame_InitializeMetadata(This); + + if (SUCCEEDED(hr) && nIndex >= This->metadata_count) + hr = E_INVALIDARG; + + if (SUCCEEDED(hr)) + hr = create_instance(&CLSID_WICImagingFactory, &IID_IWICComponentFactory, (void**)&factory); + + if (SUCCEEDED(hr)) + hr = IWICComponentFactory_CreateStream(factory, &stream); + + if (SUCCEEDED(hr)) + { + if (This->metadata_blocks[nIndex].options & DECODER_BLOCK_FULL_STREAM) + { + LARGE_INTEGER offset; + offset.QuadPart = This->metadata_blocks[nIndex].offset; + + hr = IWICStream_InitializeFromIStream(stream, This->parent->stream); + + if (SUCCEEDED(hr)) + hr = IWICStream_Seek(stream, offset, STREAM_SEEK_SET, NULL); + } + else + { + ULARGE_INTEGER offset, length; + + offset.QuadPart = This->metadata_blocks[nIndex].offset; + length.QuadPart = This->metadata_blocks[nIndex].length; + + hr = IWICStream_InitializeFromIStreamRegion(stream, This->parent->stream, + 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)) + *ppIMetadataReader = reader; + else + IWICMetadataReader_Release(reader); + } + } + else + { + hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, + &This->parent->decoder_info.block_format, NULL, + This->metadata_blocks[nIndex].options & DECODER_BLOCK_OPTION_MASK, + (IStream*)stream, ppIMetadataReader); + } + + IWICStream_Release(stream); + } + + if (factory) IWICComponentFactory_Release(factory); + + if (FAILED(hr)) + *ppIMetadataReader = NULL; + + return S_OK; +} + +static HRESULT WINAPI CommonDecoderFrame_Block_GetEnumerator(IWICMetadataBlockReader *iface, + IEnumUnknown **ppIEnumMetadata) +{ + FIXME("%p,%p\n", iface, ppIEnumMetadata); + return E_NOTIMPL; +} + +static const IWICMetadataBlockReaderVtbl CommonDecoderFrame_BlockVtbl = { + CommonDecoderFrame_Block_QueryInterface, + CommonDecoderFrame_Block_AddRef, + CommonDecoderFrame_Block_Release, + CommonDecoderFrame_Block_GetContainerFormat, + CommonDecoderFrame_Block_GetCount, + CommonDecoderFrame_Block_GetReaderByIndex, + CommonDecoderFrame_Block_GetEnumerator, +}; + +static HRESULT WINAPI CommonDecoder_GetFrame(IWICBitmapDecoder *iface, + UINT index, IWICBitmapFrameDecode **ppIBitmapFrame) +{ + CommonDecoder *This = impl_from_IWICBitmapDecoder(iface); + HRESULT hr=S_OK; + CommonDecoderFrame *result; + + TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame); + + if (!ppIBitmapFrame) + return E_INVALIDARG; + + EnterCriticalSection(&This->lock); + + if (!This->stream || index >= This->file_info.frame_count) + hr = WINCODEC_ERR_FRAMEMISSING; + + if (SUCCEEDED(hr)) + { + result = malloc(sizeof(*result)); + if (!result) + hr = E_OUTOFMEMORY; + } + + if (SUCCEEDED(hr)) + { + result->IWICBitmapFrameDecode_iface.lpVtbl = &CommonDecoderFrameVtbl; + result->IWICMetadataBlockReader_iface.lpVtbl = &CommonDecoderFrame_BlockVtbl; + result->ref = 1; + result->parent = This; + result->frame = index; + result->metadata_initialized = FALSE; + result->metadata_count = 0; + result->metadata_blocks = NULL; + + hr = decoder_get_frame_info(This->decoder, index, &result->decoder_frame); + + if (SUCCEEDED(hr) && This->cache_options == WICDecodeMetadataCacheOnLoad) + hr = CommonDecoderFrame_InitializeMetadata(result); + + if (FAILED(hr)) + free(result); + } + + LeaveCriticalSection(&This->lock); + + if (SUCCEEDED(hr)) + { + TRACE("-> %ux%u, %u-bit pixelformat=%s res=%f,%f colors=%lu contexts=%lu\n", + result->decoder_frame.width, result->decoder_frame.height, + result->decoder_frame.bpp, wine_dbgstr_guid(&result->decoder_frame.pixel_format), + result->decoder_frame.dpix, result->decoder_frame.dpiy, + result->decoder_frame.num_colors, result->decoder_frame.num_color_contexts); + IWICBitmapDecoder_AddRef(&This->IWICBitmapDecoder_iface); + *ppIBitmapFrame = &result->IWICBitmapFrameDecode_iface; + } + else + { + *ppIBitmapFrame = NULL; + } + + return hr; +} + +HRESULT CommonDecoder_CreateInstance(struct decoder *decoder, + const struct decoder_info *decoder_info, REFIID iid, void** ppv) +{ + CommonDecoder *This; + HRESULT hr; + + TRACE("(%s,%s,%p)\n", debugstr_guid(&decoder_info->clsid), debugstr_guid(iid), ppv); + + This = malloc(sizeof(*This)); + if (!This) + { + decoder_destroy(decoder); + return E_OUTOFMEMORY; + } + + This->IWICBitmapDecoder_iface.lpVtbl = &CommonDecoder_Vtbl; + This->ref = 1; + This->stream = NULL; + This->decoder = decoder; + This->decoder_info = *decoder_info; +#ifdef __REACTOS__ + InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif + This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": CommonDecoder.lock"); + + hr = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); + IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface); + + return hr; +} diff --git a/dll/win32/windowscodecs/encoder.c b/dll/win32/windowscodecs/encoder.c new file mode 100644 index 00000000000..b2be1f12e1c --- /dev/null +++ b/dll/win32/windowscodecs/encoder.c @@ -0,0 +1,903 @@ +/* + * Copyright 2020 Esme Povirk + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + +static const PROPBAG2 encoder_option_properties[ENCODER_OPTION_END] = { + { PROPBAG2_TYPE_DATA, VT_BOOL, 0, 0, (LPOLESTR)L"InterlaceOption" }, + { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)L"FilterOption" }, + { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)L"TiffCompressionMethod" }, + { PROPBAG2_TYPE_DATA, VT_R4, 0, 0, (LPOLESTR)L"CompressionQuality" }, + { PROPBAG2_TYPE_DATA, VT_R4, 0, 0, (LPOLESTR)L"ImageQuality" }, + { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)L"BitmapTransform" }, + { PROPBAG2_TYPE_DATA, VT_I4 | VT_ARRAY, 0, 0, (LPOLESTR)L"Luminance" }, + { PROPBAG2_TYPE_DATA, VT_I4 | VT_ARRAY, 0, 0, (LPOLESTR)L"Chrominance" }, + { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)L"JpegYCrCbSubsampling" }, + { PROPBAG2_TYPE_DATA, VT_BOOL, 0, 0, (LPOLESTR)L"SuppressApp0" } +}; + +typedef struct CommonEncoder { + IWICBitmapEncoder IWICBitmapEncoder_iface; + LONG ref; + CRITICAL_SECTION lock; /* must be held when stream or encoder is accessed */ + IStream *stream; + struct encoder *encoder; + struct encoder_info encoder_info; + UINT frame_count; + BOOL uncommitted_frame; + BOOL committed; +} CommonEncoder; + +typedef struct CommonEncoderFrame { + IWICBitmapFrameEncode IWICBitmapFrameEncode_iface; + IWICMetadataBlockWriter IWICMetadataBlockWriter_iface; + LONG ref; + CommonEncoder *parent; + struct encoder_frame encoder_frame; + BOOL initialized; + BOOL frame_created; + UINT lines_written; + BOOL committed; +} CommonEncoderFrame; + +static inline CommonEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface) +{ + return CONTAINING_RECORD(iface, CommonEncoder, IWICBitmapEncoder_iface); +} + +static inline CommonEncoderFrame *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface) +{ + return CONTAINING_RECORD(iface, CommonEncoderFrame, IWICBitmapFrameEncode_iface); +} + +static inline CommonEncoderFrame *impl_from_IWICMetadataBlockWriter(IWICMetadataBlockWriter *iface) +{ + return CONTAINING_RECORD(iface, CommonEncoderFrame, IWICMetadataBlockWriter_iface); +} + +static HRESULT WINAPI CommonEncoderFrame_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid, + void **ppv) +{ + CommonEncoderFrame *object = impl_from_IWICBitmapFrameEncode(iface); + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IWICBitmapFrameEncode, iid)) + { + *ppv = &object->IWICBitmapFrameEncode_iface; + } + else if (object->parent->encoder_info.flags & ENCODER_FLAGS_SUPPORTS_METADATA + && IsEqualIID(&IID_IWICMetadataBlockWriter, iid)) + { + *ppv = &object->IWICMetadataBlockWriter_iface; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI CommonEncoderFrame_AddRef(IWICBitmapFrameEncode *iface) +{ + CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + return ref; +} + +static ULONG WINAPI CommonEncoderFrame_Release(IWICBitmapFrameEncode *iface) +{ + CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + if (ref == 0) + { + IWICBitmapEncoder_Release(&This->parent->IWICBitmapEncoder_iface); + free(This); + } + + return ref; +} + +static HRESULT WINAPI CommonEncoderFrame_Initialize(IWICBitmapFrameEncode *iface, + IPropertyBag2 *pIEncoderOptions) +{ + CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr=S_OK; + struct encoder_frame options = {{0}}; + PROPBAG2 opts[7]= {{0}}; + VARIANT opt_values[7]; + HRESULT opt_hres[7]; + DWORD num_opts, i; + + TRACE("(%p,%p)\n", iface, pIEncoderOptions); + + if (pIEncoderOptions) + { + for (i=0; This->parent->encoder_info.encoder_options[i] != ENCODER_OPTION_END; i++) + opts[i] = encoder_option_properties[This->parent->encoder_info.encoder_options[i]]; + num_opts = i; + + hr = IPropertyBag2_Read(pIEncoderOptions, num_opts, opts, NULL, opt_values, opt_hres); + + if (FAILED(hr)) + return hr; + + for (i=0; This->parent->encoder_info.encoder_options[i] != ENCODER_OPTION_END; i++) + { + VARIANT *val = &opt_values[i]; + + switch (This->parent->encoder_info.encoder_options[i]) + { + case ENCODER_OPTION_INTERLACE: + if (V_VT(val) == VT_EMPTY) + options.interlace = FALSE; + else + options.interlace = (V_BOOL(val) != 0); + break; + case ENCODER_OPTION_FILTER: + options.filter = V_UI1(val); + if (options.filter > WICPngFilterAdaptive) + { + WARN("Unrecognized filter option value %lu.\n", options.filter); + options.filter = WICPngFilterUnspecified; + } + break; + default: + break; + } + } + } + else + { + options.interlace = FALSE; + options.filter = WICPngFilterUnspecified; + } + + EnterCriticalSection(&This->parent->lock); + + if (This->initialized) + hr = WINCODEC_ERR_WRONGSTATE; + else + { + This->encoder_frame = options; + This->initialized = TRUE; + } + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI CommonEncoderFrame_SetSize(IWICBitmapFrameEncode *iface, + UINT uiWidth, UINT uiHeight) +{ + CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight); + + EnterCriticalSection(&This->parent->lock); + + if (This->parent->encoder_info.flags & ENCODER_FLAGS_ICNS_SIZE) + { + if (uiWidth != uiHeight) + { + WARN("cannot generate ICNS icon from %dx%d image\n", uiWidth, uiHeight); + hr = E_INVALIDARG; + goto end; + } + + switch (uiWidth) + { + case 16: + case 32: + case 48: + case 128: + case 256: + case 512: + break; + default: + WARN("cannot generate ICNS icon from %dx%d image\n", uiWidth, uiHeight); + hr = E_INVALIDARG; + goto end; + } + } + + if (!This->initialized || This->frame_created) + { + hr = WINCODEC_ERR_WRONGSTATE; + } + else + { + This->encoder_frame.width = uiWidth; + This->encoder_frame.height = uiHeight; + hr = S_OK; + } + +end: + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI CommonEncoderFrame_SetResolution(IWICBitmapFrameEncode *iface, + double dpiX, double dpiY) +{ + CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY); + + EnterCriticalSection(&This->parent->lock); + + if (!This->initialized || This->frame_created) + { + hr = WINCODEC_ERR_WRONGSTATE; + } + else + { + This->encoder_frame.dpix = dpiX; + This->encoder_frame.dpiy = dpiY; + hr = S_OK; + } + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI CommonEncoderFrame_SetPixelFormat(IWICBitmapFrameEncode *iface, + WICPixelFormatGUID *pPixelFormat) +{ + CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + GUID pixel_format; + DWORD bpp; + BOOL indexed; + + TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat)); + + EnterCriticalSection(&This->parent->lock); + + if (!This->initialized || This->frame_created) + { + hr = WINCODEC_ERR_WRONGSTATE; + } + else + { + pixel_format = *pPixelFormat; + hr = encoder_get_supported_format(This->parent->encoder, &pixel_format, &bpp, &indexed); + } + + if (SUCCEEDED(hr)) + { + TRACE("<-- %s bpp=%li indexed=%i\n", wine_dbgstr_guid(&pixel_format), bpp, indexed); + *pPixelFormat = pixel_format; + This->encoder_frame.pixel_format = pixel_format; + This->encoder_frame.bpp = bpp; + This->encoder_frame.indexed = indexed; + } + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI CommonEncoderFrame_SetColorContexts(IWICBitmapFrameEncode *iface, + UINT cCount, IWICColorContext **ppIColorContext) +{ + FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); + return E_NOTIMPL; +} + +static HRESULT WINAPI CommonEncoderFrame_SetPalette(IWICBitmapFrameEncode *iface, + IWICPalette *palette) +{ + CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("(%p,%p)\n", iface, palette); + + if (!palette) + return E_INVALIDARG; + + EnterCriticalSection(&This->parent->lock); + + if (!This->initialized) + hr = WINCODEC_ERR_NOTINITIALIZED; + else if (This->frame_created) + hr = WINCODEC_ERR_WRONGSTATE; + else + hr = IWICPalette_GetColors(palette, 256, This->encoder_frame.palette, + &This->encoder_frame.num_colors); + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI CommonEncoderFrame_SetThumbnail(IWICBitmapFrameEncode *iface, + IWICBitmapSource *pIThumbnail) +{ + FIXME("(%p,%p): stub\n", iface, pIThumbnail); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI CommonEncoderFrame_WritePixels(IWICBitmapFrameEncode *iface, + UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels) +{ + CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr=S_OK; + DWORD required_stride; + + TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels); + + EnterCriticalSection(&This->parent->lock); + + if (!This->initialized || !This->encoder_frame.height || !This->encoder_frame.width || + !This->encoder_frame.bpp) + { + LeaveCriticalSection(&This->parent->lock); + return WINCODEC_ERR_WRONGSTATE; + } + + required_stride = (This->encoder_frame.width * This->encoder_frame.bpp + 7)/8; + + if (lineCount == 0 || This->encoder_frame.height - This->lines_written < lineCount || + cbStride < required_stride || cbBufferSize < cbStride * (lineCount - 1) + required_stride || + !pbPixels) + { + LeaveCriticalSection(&This->parent->lock); + return E_INVALIDARG; + } + + if (!This->frame_created) + { + hr = encoder_create_frame(This->parent->encoder, &This->encoder_frame); + if (SUCCEEDED(hr)) + This->frame_created = TRUE; + } + + if (SUCCEEDED(hr)) + { + hr = encoder_write_lines(This->parent->encoder, pbPixels, lineCount, cbStride); + if (SUCCEEDED(hr)) + This->lines_written += lineCount; + } + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI CommonEncoderFrame_WriteSource(IWICBitmapFrameEncode *iface, + IWICBitmapSource *pIBitmapSource, WICRect *prc) +{ + CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + TRACE("(%p,%p,%s)\n", iface, pIBitmapSource, debug_wic_rect(prc)); + + if (!This->initialized) + return WINCODEC_ERR_WRONGSTATE; + + hr = configure_write_source(iface, pIBitmapSource, prc, + This->encoder_frame.bpp ? &This->encoder_frame.pixel_format : NULL, + This->encoder_frame.width, This->encoder_frame.height, + This->encoder_frame.dpix, This->encoder_frame.dpiy); + + if (SUCCEEDED(hr)) + { + hr = write_source(iface, pIBitmapSource, prc, + &This->encoder_frame.pixel_format, This->encoder_frame.bpp, + !This->encoder_frame.num_colors && This->encoder_frame.indexed, + This->encoder_frame.width, This->encoder_frame.height); + } + + return hr; +} + +static HRESULT WINAPI CommonEncoderFrame_Commit(IWICBitmapFrameEncode *iface) +{ + CommonEncoderFrame *This = impl_from_IWICBitmapFrameEncode(iface); + HRESULT hr; + + TRACE("(%p)\n", iface); + + EnterCriticalSection(&This->parent->lock); + + if (!This->frame_created || This->lines_written != This->encoder_frame.height || + This->committed) + { + hr = WINCODEC_ERR_WRONGSTATE; + } + else + { + hr = encoder_commit_frame(This->parent->encoder); + if (SUCCEEDED(hr)) + { + This->committed = TRUE; + This->parent->uncommitted_frame = FALSE; + } + } + + LeaveCriticalSection(&This->parent->lock); + + return hr; +} + +static HRESULT WINAPI CommonEncoderFrame_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface, + IWICMetadataQueryWriter **ppIMetadataQueryWriter) +{ + CommonEncoderFrame *encoder = impl_from_IWICBitmapFrameEncode(iface); + + TRACE("iface, %p, ppIMetadataQueryWriter %p.\n", iface, ppIMetadataQueryWriter); + + if (!ppIMetadataQueryWriter) + return E_INVALIDARG; + + if (!encoder->initialized) + return WINCODEC_ERR_NOTINITIALIZED; + + if (!(encoder->parent->encoder_info.flags & ENCODER_FLAGS_SUPPORTS_METADATA)) + return WINCODEC_ERR_UNSUPPORTEDOPERATION; + + return MetadataQueryWriter_CreateInstance(&encoder->IWICMetadataBlockWriter_iface, NULL, ppIMetadataQueryWriter); +} + +static const IWICBitmapFrameEncodeVtbl CommonEncoderFrame_Vtbl = { + CommonEncoderFrame_QueryInterface, + CommonEncoderFrame_AddRef, + CommonEncoderFrame_Release, + CommonEncoderFrame_Initialize, + CommonEncoderFrame_SetSize, + CommonEncoderFrame_SetResolution, + CommonEncoderFrame_SetPixelFormat, + CommonEncoderFrame_SetColorContexts, + CommonEncoderFrame_SetPalette, + CommonEncoderFrame_SetThumbnail, + CommonEncoderFrame_WritePixels, + CommonEncoderFrame_WriteSource, + CommonEncoderFrame_Commit, + CommonEncoderFrame_GetMetadataQueryWriter +}; + +static HRESULT WINAPI CommonEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid, + void **ppv) +{ + CommonEncoder *This = impl_from_IWICBitmapEncoder(iface); + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || + IsEqualIID(&IID_IWICBitmapEncoder, iid)) + { + *ppv = &This->IWICBitmapEncoder_iface; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI CommonEncoder_AddRef(IWICBitmapEncoder *iface) +{ + CommonEncoder *This = impl_from_IWICBitmapEncoder(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + return ref; +} + +static ULONG WINAPI CommonEncoder_Release(IWICBitmapEncoder *iface) +{ + CommonEncoder *This = impl_from_IWICBitmapEncoder(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%lu\n", iface, ref); + + if (ref == 0) + { + This->lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->lock); + if (This->stream) + IStream_Release(This->stream); + encoder_destroy(This->encoder); + free(This); + } + + return ref; +} + +static HRESULT WINAPI CommonEncoder_Initialize(IWICBitmapEncoder *iface, + IStream *pIStream, WICBitmapEncoderCacheOption cacheOption) +{ + CommonEncoder *This = impl_from_IWICBitmapEncoder(iface); + HRESULT hr; + + TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption); + + if (!pIStream) + return E_POINTER; + + EnterCriticalSection(&This->lock); + + if (This->stream) + { + LeaveCriticalSection(&This->lock); + return WINCODEC_ERR_WRONGSTATE; + } + + hr = encoder_initialize(This->encoder, pIStream); + + if (SUCCEEDED(hr)) + { + This->stream = pIStream; + IStream_AddRef(This->stream); + } + + LeaveCriticalSection(&This->lock); + + return S_OK; +} + +static HRESULT WINAPI CommonEncoder_GetContainerFormat(IWICBitmapEncoder *iface, GUID *format) +{ + CommonEncoder *This = impl_from_IWICBitmapEncoder(iface); + TRACE("(%p,%p)\n", iface, format); + + if (!format) + return E_INVALIDARG; + + memcpy(format, &This->encoder_info.container_format, sizeof(*format)); + return S_OK; +} + +static HRESULT WINAPI CommonEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info) +{ + CommonEncoder *This = impl_from_IWICBitmapEncoder(iface); + IWICComponentInfo *comp_info; + HRESULT hr; + + TRACE("%p,%p\n", iface, info); + + if (!info) return E_INVALIDARG; + + hr = CreateComponentInfo(&This->encoder_info.clsid, &comp_info); + if (hr == S_OK) + { + hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info); + IWICComponentInfo_Release(comp_info); + } + return hr; +} + +static HRESULT WINAPI CommonEncoder_SetColorContexts(IWICBitmapEncoder *iface, + UINT cCount, IWICColorContext **ppIColorContext) +{ + FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); + return E_NOTIMPL; +} + +static HRESULT WINAPI CommonEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *palette) +{ + CommonEncoder *This = impl_from_IWICBitmapEncoder(iface); + HRESULT hr; + + TRACE("(%p,%p)\n", iface, palette); + + EnterCriticalSection(&This->lock); + + hr = This->stream ? WINCODEC_ERR_UNSUPPORTEDOPERATION : WINCODEC_ERR_NOTINITIALIZED; + + LeaveCriticalSection(&This->lock); + + return hr; +} + +static HRESULT WINAPI CommonEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail) +{ + TRACE("(%p,%p)\n", iface, pIThumbnail); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI CommonEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *pIPreview) +{ + TRACE("(%p,%p)\n", iface, pIPreview); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; +} + +static HRESULT WINAPI CommonEncoderFrame_Block_QueryInterface(IWICMetadataBlockWriter *iface, REFIID iid, void **ppv) +{ + CommonEncoderFrame *encoder = impl_from_IWICMetadataBlockWriter(iface); + + return IWICBitmapFrameEncode_QueryInterface(&encoder->IWICBitmapFrameEncode_iface, iid, ppv); +} + +static ULONG WINAPI CommonEncoderFrame_Block_AddRef(IWICMetadataBlockWriter *iface) +{ + CommonEncoderFrame *encoder = impl_from_IWICMetadataBlockWriter(iface); + + return IWICBitmapFrameEncode_AddRef(&encoder->IWICBitmapFrameEncode_iface); +} + +static ULONG WINAPI CommonEncoderFrame_Block_Release(IWICMetadataBlockWriter *iface) +{ + CommonEncoderFrame *encoder = impl_from_IWICMetadataBlockWriter(iface); + + return IWICBitmapFrameEncode_Release(&encoder->IWICBitmapFrameEncode_iface); +} + +static HRESULT WINAPI CommonEncoderFrame_Block_GetContainerFormat(IWICMetadataBlockWriter *iface, GUID *container_format) +{ + FIXME("iface %p, container_format %p stub.\n", iface, container_format); + + return E_NOTIMPL; +} + +static HRESULT WINAPI CommonEncoderFrame_Block_GetCount(IWICMetadataBlockWriter *iface, UINT *count) +{ + FIXME("iface %p, count %p stub.\n", iface, count); + + return E_NOTIMPL; +} + +static HRESULT WINAPI CommonEncoderFrame_Block_GetReaderByIndex(IWICMetadataBlockWriter *iface, + UINT index, IWICMetadataReader **metadata_reader) +{ + FIXME("iface %p, index %d, metadata_reader %p stub.\n", iface, index, metadata_reader); + + return E_NOTIMPL; +} + +static HRESULT WINAPI CommonEncoderFrame_Block_GetEnumerator(IWICMetadataBlockWriter *iface, IEnumUnknown **enum_metadata) +{ + FIXME("iface %p, ppIEnumMetadata %p stub.\n", iface, enum_metadata); + + return E_NOTIMPL; +} + +static HRESULT WINAPI CommonEncoderFrame_Block_InitializeFromBlockReader(IWICMetadataBlockWriter *iface, + IWICMetadataBlockReader *metadata_block_reader) +{ + FIXME("iface %p, metadata_block_reader %p stub.\n", iface, metadata_block_reader); + + return E_NOTIMPL; +} + +static HRESULT WINAPI CommonEncoderFrame_Block_GetWriterByIndex(IWICMetadataBlockWriter *iface, UINT index, + IWICMetadataWriter **metadata_writer) +{ + FIXME("iface %p, index %u, metadata_writer %p stub.\n", iface, index, metadata_writer); + + return E_NOTIMPL; +} + +static HRESULT WINAPI CommonEncoderFrame_Block_AddWriter(IWICMetadataBlockWriter *iface, IWICMetadataWriter *metadata_writer) +{ + FIXME("iface %p, metadata_writer %p.\n", iface, metadata_writer); + + return E_NOTIMPL; +} + +static HRESULT WINAPI CommonEncoderFrame_Block_SetWriterByIndex(IWICMetadataBlockWriter *iface, UINT index, + IWICMetadataWriter *metadata_writer) +{ + FIXME("iface %p, index %u, metadata_writer %p stub.\n", iface, index, metadata_writer); + + return E_NOTIMPL; +} + +static HRESULT WINAPI CommonEncoderFrame_Block_RemoveWriterByIndex(IWICMetadataBlockWriter *iface, UINT index) +{ + FIXME("iface %p, index %u.\n", iface, index); + + return E_NOTIMPL; +} + +static const IWICMetadataBlockWriterVtbl CommonEncoderFrame_BlockVtbl = +{ + CommonEncoderFrame_Block_QueryInterface, + CommonEncoderFrame_Block_AddRef, + CommonEncoderFrame_Block_Release, + CommonEncoderFrame_Block_GetContainerFormat, + CommonEncoderFrame_Block_GetCount, + CommonEncoderFrame_Block_GetReaderByIndex, + CommonEncoderFrame_Block_GetEnumerator, + CommonEncoderFrame_Block_InitializeFromBlockReader, + CommonEncoderFrame_Block_GetWriterByIndex, + CommonEncoderFrame_Block_AddWriter, + CommonEncoderFrame_Block_SetWriterByIndex, + CommonEncoderFrame_Block_RemoveWriterByIndex, +}; + +static HRESULT WINAPI CommonEncoder_CreateNewFrame(IWICBitmapEncoder *iface, + IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions) +{ + CommonEncoder *This = impl_from_IWICBitmapEncoder(iface); + CommonEncoderFrame *result; + HRESULT hr; + DWORD opts_length; + PROPBAG2 opts[6]; + + TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions); + + EnterCriticalSection(&This->lock); + + if (This->frame_count != 0 && !(This->encoder_info.flags & ENCODER_FLAGS_MULTI_FRAME)) + { + LeaveCriticalSection(&This->lock); + return WINCODEC_ERR_UNSUPPORTEDOPERATION; + } + + if (!This->stream || This->committed || This->uncommitted_frame) + { + LeaveCriticalSection(&This->lock); + return WINCODEC_ERR_NOTINITIALIZED; + } + + result = calloc(1, sizeof(*result)); + if (!result) + { + LeaveCriticalSection(&This->lock); + return E_OUTOFMEMORY; + } + + result->IWICBitmapFrameEncode_iface.lpVtbl = &CommonEncoderFrame_Vtbl; + result->IWICMetadataBlockWriter_iface.lpVtbl = &CommonEncoderFrame_BlockVtbl; + result->ref = 1; + result->parent = This; + + if (ppIEncoderOptions) + { + for (opts_length = 0; This->encoder_info.encoder_options[opts_length] < ENCODER_OPTION_END; opts_length++) + { + opts[opts_length] = encoder_option_properties[This->encoder_info.encoder_options[opts_length]]; + } + + hr = CreatePropertyBag2(opts, opts_length, ppIEncoderOptions); + if (FAILED(hr)) + { + LeaveCriticalSection(&This->lock); + free(result); + return hr; + } + } + + IWICBitmapEncoder_AddRef(iface); + This->frame_count++; + This->uncommitted_frame = TRUE; + + LeaveCriticalSection(&This->lock); + + *ppIFrameEncode = &result->IWICBitmapFrameEncode_iface; + + return S_OK; +} + +static HRESULT WINAPI CommonEncoder_Commit(IWICBitmapEncoder *iface) +{ + CommonEncoder *This = impl_from_IWICBitmapEncoder(iface); + HRESULT hr; + + TRACE("(%p)\n", iface); + + EnterCriticalSection(&This->lock); + + if (This->committed || This->uncommitted_frame) + hr = WINCODEC_ERR_WRONGSTATE; + else + { + hr = encoder_commit_file(This->encoder); + if (SUCCEEDED(hr)) + This->committed = TRUE; + } + + LeaveCriticalSection(&This->lock); + + return hr; +} + +static HRESULT WINAPI CommonEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface, + IWICMetadataQueryWriter **ppIMetadataQueryWriter) +{ + FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryWriter); + return E_NOTIMPL; +} + +static const IWICBitmapEncoderVtbl CommonEncoder_Vtbl = { + CommonEncoder_QueryInterface, + CommonEncoder_AddRef, + CommonEncoder_Release, + CommonEncoder_Initialize, + CommonEncoder_GetContainerFormat, + CommonEncoder_GetEncoderInfo, + CommonEncoder_SetColorContexts, + CommonEncoder_SetPalette, + CommonEncoder_SetThumbnail, + CommonEncoder_SetPreview, + CommonEncoder_CreateNewFrame, + CommonEncoder_Commit, + CommonEncoder_GetMetadataQueryWriter +}; + +HRESULT CommonEncoder_CreateInstance(struct encoder *encoder, + const struct encoder_info *encoder_info, REFIID iid, void** ppv) +{ + CommonEncoder *This; + HRESULT ret; + + TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); + + *ppv = NULL; + + This = malloc(sizeof(CommonEncoder)); + if (!This) + { + encoder_destroy(encoder); + return E_OUTOFMEMORY; + } + + This->IWICBitmapEncoder_iface.lpVtbl = &CommonEncoder_Vtbl; + This->ref = 1; + This->stream = NULL; + This->encoder = encoder; + This->encoder_info = *encoder_info; + This->frame_count = 0; + This->uncommitted_frame = FALSE; + This->committed = FALSE; +#ifdef __REACTOS__ + InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif + This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": CommonEncoder.lock"); + + ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv); + IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface); + + return ret; +} diff --git a/dll/win32/windowscodecs/fliprotate.c b/dll/win32/windowscodecs/fliprotate.c index 46402237eef..cb631637ba1 100644 --- a/dll/win32/windowscodecs/fliprotate.c +++ b/dll/win32/windowscodecs/fliprotate.c @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -76,7 +74,7 @@ static ULONG WINAPI FlipRotator_AddRef(IWICBitmapFlipRotator *iface) FlipRotator *This = impl_from_IWICBitmapFlipRotator(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -86,14 +84,14 @@ static ULONG WINAPI FlipRotator_Release(IWICBitmapFlipRotator *iface) FlipRotator *This = impl_from_IWICBitmapFlipRotator(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); if (This->source) IWICBitmapSource_Release(This->source); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -269,7 +267,7 @@ HRESULT FlipRotator_Create(IWICBitmapFlipRotator **fliprotator) { FlipRotator *This; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(FlipRotator)); + This = malloc(sizeof(FlipRotator)); if (!This) return E_OUTOFMEMORY; This->IWICBitmapFlipRotator_iface.lpVtbl = &FlipRotator_Vtbl; @@ -278,7 +276,11 @@ HRESULT FlipRotator_Create(IWICBitmapFlipRotator **fliprotator) This->flip_x = 0; This->flip_y = 0; This->swap_xy = 0; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FlipRotator.lock"); *fliprotator = &This->IWICBitmapFlipRotator_iface; diff --git a/dll/win32/windowscodecs/gifformat.c b/dll/win32/windowscodecs/gifformat.c index d4d23ff6f3c..1c9f884bd8c 100644 --- a/dll/win32/windowscodecs/gifformat.c +++ b/dll/win32/windowscodecs/gifformat.c @@ -17,23 +17,19 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS -#define NONAMELESSUNION - #include "windef.h" #include "winbase.h" #include "objbase.h" +#include "shlwapi.h" #include "ungif.h" #include "wincodecs_private.h" #include "wine/debug.h" - #ifdef __REACTOS__ #include #endif @@ -74,14 +70,6 @@ struct image_descriptor #include "poppack.h" -static LPWSTR strdupAtoW(const char *src) -{ - int len = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0); - LPWSTR dst = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); - if (dst) MultiByteToWideChar(CP_ACP, 0, src, -1, dst, len); - return dst; -} - static HRESULT load_LSD_metadata(IStream *stream, const GUID *vendor, DWORD options, MetadataItem **items, DWORD *count) { @@ -96,7 +84,7 @@ static HRESULT load_LSD_metadata(IStream *stream, const GUID *vendor, DWORD opti hr = IStream_Read(stream, &lsd_data, sizeof(lsd_data), &bytesread); if (FAILED(hr) || bytesread != sizeof(lsd_data)) return S_OK; - result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem) * 9); + result = calloc(9, sizeof(MetadataItem)); if (!result) return E_OUTOFMEMORY; for (i = 0; i < 9; i++) @@ -107,51 +95,51 @@ static HRESULT load_LSD_metadata(IStream *stream, const GUID *vendor, DWORD opti } result[0].id.vt = VT_LPWSTR; - result[0].id.u.pwszVal = strdupAtoW("Signature"); + SHStrDupW(L"Signature", &result[0].id.pwszVal); result[0].value.vt = VT_UI1|VT_VECTOR; - result[0].value.u.caub.cElems = sizeof(lsd_data.signature); - result[0].value.u.caub.pElems = HeapAlloc(GetProcessHeap(), 0, sizeof(lsd_data.signature)); - memcpy(result[0].value.u.caub.pElems, lsd_data.signature, sizeof(lsd_data.signature)); + result[0].value.caub.cElems = sizeof(lsd_data.signature); + result[0].value.caub.pElems = CoTaskMemAlloc(sizeof(lsd_data.signature)); + memcpy(result[0].value.caub.pElems, lsd_data.signature, sizeof(lsd_data.signature)); result[1].id.vt = VT_LPWSTR; - result[1].id.u.pwszVal = strdupAtoW("Width"); + SHStrDupW(L"Width", &result[1].id.pwszVal); result[1].value.vt = VT_UI2; - result[1].value.u.uiVal = lsd_data.width; + result[1].value.uiVal = lsd_data.width; result[2].id.vt = VT_LPWSTR; - result[2].id.u.pwszVal = strdupAtoW("Height"); + SHStrDupW(L"Height", &result[2].id.pwszVal); result[2].value.vt = VT_UI2; - result[2].value.u.uiVal = lsd_data.height; + result[2].value.uiVal = lsd_data.height; result[3].id.vt = VT_LPWSTR; - result[3].id.u.pwszVal = strdupAtoW("GlobalColorTableFlag"); + SHStrDupW(L"GlobalColorTableFlag", &result[3].id.pwszVal); result[3].value.vt = VT_BOOL; - result[3].value.u.boolVal = (lsd_data.packed >> 7) & 1; + result[3].value.boolVal = (lsd_data.packed >> 7) & 1; result[4].id.vt = VT_LPWSTR; - result[4].id.u.pwszVal = strdupAtoW("ColorResolution"); + SHStrDupW(L"ColorResolution", &result[4].id.pwszVal); result[4].value.vt = VT_UI1; - result[4].value.u.bVal = (lsd_data.packed >> 4) & 7; + result[4].value.bVal = (lsd_data.packed >> 4) & 7; result[5].id.vt = VT_LPWSTR; - result[5].id.u.pwszVal = strdupAtoW("SortFlag"); + SHStrDupW(L"SortFlag", &result[5].id.pwszVal); result[5].value.vt = VT_BOOL; - result[5].value.u.boolVal = (lsd_data.packed >> 3) & 1; + result[5].value.boolVal = (lsd_data.packed >> 3) & 1; result[6].id.vt = VT_LPWSTR; - result[6].id.u.pwszVal = strdupAtoW("GlobalColorTableSize"); + SHStrDupW(L"GlobalColorTableSize", &result[6].id.pwszVal); result[6].value.vt = VT_UI1; - result[6].value.u.bVal = lsd_data.packed & 7; + result[6].value.bVal = lsd_data.packed & 7; result[7].id.vt = VT_LPWSTR; - result[7].id.u.pwszVal = strdupAtoW("BackgroundColorIndex"); + SHStrDupW(L"BackgroundColorIndex", &result[7].id.pwszVal); result[7].value.vt = VT_UI1; - result[7].value.u.bVal = lsd_data.background_color_index; + result[7].value.bVal = lsd_data.background_color_index; result[8].id.vt = VT_LPWSTR; - result[8].id.u.pwszVal = strdupAtoW("PixelAspectRatio"); + SHStrDupW(L"PixelAspectRatio", &result[8].id.pwszVal); result[8].value.vt = VT_UI1; - result[8].value.u.bVal = lsd_data.pixel_aspect_ratio; + result[8].value.bVal = lsd_data.pixel_aspect_ratio; *items = result; *count = 9; @@ -184,7 +172,7 @@ static HRESULT load_IMD_metadata(IStream *stream, const GUID *vendor, DWORD opti hr = IStream_Read(stream, &imd_data, sizeof(imd_data), &bytesread); if (FAILED(hr) || bytesread != sizeof(imd_data)) return S_OK; - result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem) * 8); + result = calloc(8, sizeof(MetadataItem)); if (!result) return E_OUTOFMEMORY; for (i = 0; i < 8; i++) @@ -195,44 +183,44 @@ static HRESULT load_IMD_metadata(IStream *stream, const GUID *vendor, DWORD opti } result[0].id.vt = VT_LPWSTR; - result[0].id.u.pwszVal = strdupAtoW("Left"); + SHStrDupW(L"Left", &result[0].id.pwszVal); result[0].value.vt = VT_UI2; - result[0].value.u.uiVal = imd_data.left; + result[0].value.uiVal = imd_data.left; result[1].id.vt = VT_LPWSTR; - result[1].id.u.pwszVal = strdupAtoW("Top"); + SHStrDupW(L"Top", &result[1].id.pwszVal); result[1].value.vt = VT_UI2; - result[1].value.u.uiVal = imd_data.top; + result[1].value.uiVal = imd_data.top; result[2].id.vt = VT_LPWSTR; - result[2].id.u.pwszVal = strdupAtoW("Width"); + SHStrDupW(L"Width", &result[2].id.pwszVal); result[2].value.vt = VT_UI2; - result[2].value.u.uiVal = imd_data.width; + result[2].value.uiVal = imd_data.width; result[3].id.vt = VT_LPWSTR; - result[3].id.u.pwszVal = strdupAtoW("Height"); + SHStrDupW(L"Height", &result[3].id.pwszVal); result[3].value.vt = VT_UI2; - result[3].value.u.uiVal = imd_data.height; + result[3].value.uiVal = imd_data.height; result[4].id.vt = VT_LPWSTR; - result[4].id.u.pwszVal = strdupAtoW("LocalColorTableFlag"); + SHStrDupW(L"LocalColorTableFlag", &result[4].id.pwszVal); result[4].value.vt = VT_BOOL; - result[4].value.u.boolVal = (imd_data.packed >> 7) & 1; + result[4].value.boolVal = (imd_data.packed >> 7) & 1; result[5].id.vt = VT_LPWSTR; - result[5].id.u.pwszVal = strdupAtoW("InterlaceFlag"); + SHStrDupW(L"InterlaceFlag", &result[5].id.pwszVal); result[5].value.vt = VT_BOOL; - result[5].value.u.boolVal = (imd_data.packed >> 6) & 1; + result[5].value.boolVal = (imd_data.packed >> 6) & 1; result[6].id.vt = VT_LPWSTR; - result[6].id.u.pwszVal = strdupAtoW("SortFlag"); + SHStrDupW(L"SortFlag", &result[6].id.pwszVal); result[6].value.vt = VT_BOOL; - result[6].value.u.boolVal = (imd_data.packed >> 5) & 1; + result[6].value.boolVal = (imd_data.packed >> 5) & 1; result[7].id.vt = VT_LPWSTR; - result[7].id.u.pwszVal = strdupAtoW("LocalColorTableSize"); + SHStrDupW(L"LocalColorTableSize", &result[7].id.pwszVal); result[7].value.vt = VT_UI1; - result[7].value.u.bVal = imd_data.packed & 7; + result[7].value.bVal = imd_data.packed & 7; *items = result; *count = 8; @@ -277,7 +265,7 @@ static HRESULT load_GCE_metadata(IStream *stream, const GUID *vendor, DWORD opti hr = IStream_Read(stream, &gce_data, sizeof(gce_data), &bytesread); if (FAILED(hr) || bytesread != sizeof(gce_data)) return S_OK; - result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem) * 5); + result = calloc(5, sizeof(MetadataItem)); if (!result) return E_OUTOFMEMORY; for (i = 0; i < 5; i++) @@ -288,29 +276,29 @@ static HRESULT load_GCE_metadata(IStream *stream, const GUID *vendor, DWORD opti } result[0].id.vt = VT_LPWSTR; - result[0].id.u.pwszVal = strdupAtoW("Disposal"); + SHStrDupW(L"Disposal", &result[0].id.pwszVal); result[0].value.vt = VT_UI1; - result[0].value.u.bVal = (gce_data.packed >> 2) & 7; + result[0].value.bVal = (gce_data.packed >> 2) & 7; result[1].id.vt = VT_LPWSTR; - result[1].id.u.pwszVal = strdupAtoW("UserInputFlag"); + SHStrDupW(L"UserInputFlag", &result[1].id.pwszVal); result[1].value.vt = VT_BOOL; - result[1].value.u.boolVal = (gce_data.packed >> 1) & 1; + result[1].value.boolVal = (gce_data.packed >> 1) & 1; result[2].id.vt = VT_LPWSTR; - result[2].id.u.pwszVal = strdupAtoW("TransparencyFlag"); + SHStrDupW(L"TransparencyFlag", &result[2].id.pwszVal); result[2].value.vt = VT_BOOL; - result[2].value.u.boolVal = gce_data.packed & 1; + result[2].value.boolVal = gce_data.packed & 1; result[3].id.vt = VT_LPWSTR; - result[3].id.u.pwszVal = strdupAtoW("Delay"); + SHStrDupW(L"Delay", &result[3].id.pwszVal); result[3].value.vt = VT_UI2; - result[3].value.u.uiVal = gce_data.delay; + result[3].value.uiVal = gce_data.delay; result[4].id.vt = VT_LPWSTR; - result[4].id.u.pwszVal = strdupAtoW("TransparentColorIndex"); + SHStrDupW(L"TransparentColorIndex", &result[4].id.pwszVal); result[4].value.vt = VT_UI1; - result[4].value.u.bVal = gce_data.transparent_color_index; + result[4].value.bVal = gce_data.transparent_color_index; *items = result; *count = 5; @@ -365,19 +353,19 @@ static HRESULT load_APE_metadata(IStream *stream, const GUID *vendor, DWORD opti hr = IStream_Read(stream, &subblock_size, sizeof(subblock_size), &bytesread); if (FAILED(hr) || bytesread != sizeof(subblock_size)) { - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(data); return S_OK; } if (!subblock_size) break; if (!data) - data = HeapAlloc(GetProcessHeap(), 0, subblock_size + 1); + data = CoTaskMemAlloc(subblock_size + 1); else { - BYTE *new_data = HeapReAlloc(GetProcessHeap(), 0, data, data_size + subblock_size + 1); + BYTE *new_data = CoTaskMemRealloc(data, data_size + subblock_size + 1); if (!new_data) { - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(data); return S_OK; } data = new_data; @@ -386,16 +374,16 @@ static HRESULT load_APE_metadata(IStream *stream, const GUID *vendor, DWORD opti hr = IStream_Read(stream, data + data_size + 1, subblock_size, &bytesread); if (FAILED(hr) || bytesread != subblock_size) { - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(data); return S_OK; } data_size += subblock_size + 1; } - result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem) * 2); + result = calloc(2, sizeof(MetadataItem)); if (!result) { - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(data); return E_OUTOFMEMORY; } @@ -407,17 +395,17 @@ static HRESULT load_APE_metadata(IStream *stream, const GUID *vendor, DWORD opti } result[0].id.vt = VT_LPWSTR; - result[0].id.u.pwszVal = strdupAtoW("Application"); + SHStrDupW(L"Application", &result[0].id.pwszVal); result[0].value.vt = VT_UI1|VT_VECTOR; - result[0].value.u.caub.cElems = sizeof(ape_data.application); - result[0].value.u.caub.pElems = HeapAlloc(GetProcessHeap(), 0, sizeof(ape_data.application)); - memcpy(result[0].value.u.caub.pElems, ape_data.application, sizeof(ape_data.application)); + result[0].value.caub.cElems = sizeof(ape_data.application); + result[0].value.caub.pElems = CoTaskMemAlloc(sizeof(ape_data.application)); + memcpy(result[0].value.caub.pElems, ape_data.application, sizeof(ape_data.application)); result[1].id.vt = VT_LPWSTR; - result[1].id.u.pwszVal = strdupAtoW("Data"); + SHStrDupW(L"Data", &result[1].id.pwszVal); result[1].value.vt = VT_UI1|VT_VECTOR; - result[1].value.u.caub.cElems = data_size; - result[1].value.u.caub.pElems = data; + result[1].value.caub.cElems = data_size; + result[1].value.caub.pElems = data; *items = result; *count = 2; @@ -469,19 +457,19 @@ static HRESULT load_GifComment_metadata(IStream *stream, const GUID *vendor, DWO hr = IStream_Read(stream, &subblock_size, sizeof(subblock_size), &bytesread); if (FAILED(hr) || bytesread != sizeof(subblock_size)) { - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(data); return S_OK; } if (!subblock_size) break; if (!data) - data = HeapAlloc(GetProcessHeap(), 0, subblock_size + 1); + data = CoTaskMemAlloc(subblock_size + 1); else { - char *new_data = HeapReAlloc(GetProcessHeap(), 0, data, data_size + subblock_size + 1); + char *new_data = CoTaskMemRealloc(data, data_size + subblock_size + 1); if (!new_data) { - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(data); return S_OK; } data = new_data; @@ -489,7 +477,7 @@ static HRESULT load_GifComment_metadata(IStream *stream, const GUID *vendor, DWO hr = IStream_Read(stream, data + data_size, subblock_size, &bytesread); if (FAILED(hr) || bytesread != subblock_size) { - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(data); return S_OK; } data_size += subblock_size; @@ -497,10 +485,10 @@ static HRESULT load_GifComment_metadata(IStream *stream, const GUID *vendor, DWO data[data_size] = 0; - result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem)); + result = calloc(1, sizeof(MetadataItem)); if (!result) { - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(data); return E_OUTOFMEMORY; } @@ -509,9 +497,9 @@ static HRESULT load_GifComment_metadata(IStream *stream, const GUID *vendor, DWO PropVariantInit(&result->value); result->id.vt = VT_LPWSTR; - result->id.u.pwszVal = strdupAtoW("TextEntry"); + SHStrDupW(L"TextEntry", &result->id.pwszVal); result->value.vt = VT_LPSTR; - result->value.u.pszVal = data; + result->value.pszVal = data; *items = result; *count = 1; @@ -652,7 +640,7 @@ static ULONG WINAPI GifFrameDecode_AddRef(IWICBitmapFrameDecode *iface) GifFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -662,12 +650,12 @@ static ULONG WINAPI GifFrameDecode_Release(IWICBitmapFrameDecode *iface) GifFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { IWICBitmapDecoder_Release(&This->parent->IWICBitmapDecoder_iface); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -707,44 +695,69 @@ static HRESULT WINAPI GifFrameDecode_GetResolution(IWICBitmapFrameDecode *iface, return S_OK; } +static void copy_palette(ColorMapObject *cm, Extensions *extensions, int count, WICColor *colors) +{ + int i; + + if (cm) + { + for (i = 0; i < count; i++) + { + colors[i] = 0xff000000 | /* alpha */ + cm->Colors[i].Red << 16 | + cm->Colors[i].Green << 8 | + cm->Colors[i].Blue; + } + } + else + { + colors[0] = 0xff000000; + colors[1] = 0xffffffff; + for (i = 2; i < count; i++) + colors[i] = 0xff000000; + } + + /* look for the transparent color extension */ + for (i = 0; i < extensions->ExtensionBlockCount; i++) + { + ExtensionBlock *eb = extensions->ExtensionBlocks + i; + if (eb->Function == GRAPHICS_EXT_FUNC_CODE && + eb->ByteCount == 8 && eb->Bytes[3] & 1) + { + int trans = (unsigned char)eb->Bytes[6]; + colors[trans] &= 0xffffff; /* set alpha to 0 */ + break; + } + } +} + static HRESULT WINAPI GifFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, IWICPalette *pIPalette) { GifFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); WICColor colors[256]; ColorMapObject *cm = This->frame->ImageDesc.ColorMap; - int i, trans; - ExtensionBlock *eb; + int count; + TRACE("(%p,%p)\n", iface, pIPalette); - if (!cm) cm = This->parent->gif->SColorMap; - - if (cm->ColorCount > 256) + if (cm) + count = cm->ColorCount; + else { - ERR("GIF contains %i colors???\n", cm->ColorCount); + cm = This->parent->gif->SColorMap; + count = This->parent->gif->SColorTableSize; + } + + if (count > 256) + { + ERR("GIF contains %i colors???\n", count); return E_FAIL; } - for (i = 0; i < cm->ColorCount; i++) { - colors[i] = 0xff000000| /* alpha */ - cm->Colors[i].Red << 16| - cm->Colors[i].Green << 8| - cm->Colors[i].Blue; - } + copy_palette(cm, &This->frame->Extensions, count, colors); - /* look for the transparent color extension */ - for (i = 0; i < This->frame->Extensions.ExtensionBlockCount; ++i) { - eb = This->frame->Extensions.ExtensionBlocks + i; - if (eb->Function == GRAPHICS_EXT_FUNC_CODE && eb->ByteCount == 8) { - if (eb->Bytes[3] & 1) { - trans = (unsigned char)eb->Bytes[6]; - colors[trans] &= 0xffffff; /* set alpha to 0 */ - break; - } - } - } - - return IWICPalette_InitializeCustom(pIPalette, colors, cm->ColorCount); + return IWICPalette_InitializeCustom(pIPalette, colors, count); } static HRESULT copy_interlaced_pixels(const BYTE *srcbuffer, @@ -953,7 +966,10 @@ static HRESULT WINAPI GifFrameDecode_Block_GetReaderByIndex(IWICMetadataBlockRea UINT index, IWICMetadataReader **reader) { GifFrameDecode *This = frame_from_IWICMetadataBlockReader(iface); - int i, gce_index = -1, gce_skipped = 0; + class_constructor constructor; + ExtensionBlock *ext; + const void *data; + int data_size; TRACE("(%p,%u,%p)\n", iface, index, reader); @@ -965,40 +981,27 @@ static HRESULT WINAPI GifFrameDecode_Block_GetReaderByIndex(IWICMetadataBlockRea if (index >= This->frame->Extensions.ExtensionBlockCount + 1) return E_INVALIDARG; - for (i = 0; i < This->frame->Extensions.ExtensionBlockCount; i++) + ext = This->frame->Extensions.ExtensionBlocks + index - 1; + if (ext->Function == GRAPHICS_EXT_FUNC_CODE) { - class_constructor constructor; - const void *data; - int data_size; - - if (index != i + 1 - gce_skipped) continue; - - if (This->frame->Extensions.ExtensionBlocks[i].Function == GRAPHICS_EXT_FUNC_CODE) - { - gce_index = i; - gce_skipped = 1; - continue; - } - else if (This->frame->Extensions.ExtensionBlocks[i].Function == COMMENT_EXT_FUNC_CODE) - { - constructor = GifCommentReader_CreateInstance; - data = This->frame->Extensions.ExtensionBlocks[i].Bytes; - data_size = This->frame->Extensions.ExtensionBlocks[i].ByteCount; - } - else - { - constructor = UnknownMetadataReader_CreateInstance; - data = This->frame->Extensions.ExtensionBlocks[i].Bytes; - data_size = This->frame->Extensions.ExtensionBlocks[i].ByteCount; - } - return create_metadata_reader(data, data_size, constructor, reader); + constructor = GCEReader_CreateInstance; + data = ext->Bytes + 3; + data_size = ext->ByteCount - 4; + } + else if (ext->Function == COMMENT_EXT_FUNC_CODE) + { + constructor = GifCommentReader_CreateInstance; + data = ext->Bytes; + data_size = ext->ByteCount; + } + else + { + constructor = UnknownMetadataReader_CreateInstance; + data = ext->Bytes; + data_size = ext->ByteCount; } - if (gce_index == -1) return E_INVALIDARG; - - return create_metadata_reader(This->frame->Extensions.ExtensionBlocks[gce_index].Bytes + 3, - This->frame->Extensions.ExtensionBlocks[gce_index].ByteCount - 4, - GCEReader_CreateInstance, reader); + return create_metadata_reader(data, data_size, constructor, reader); } static HRESULT WINAPI GifFrameDecode_Block_GetEnumerator(IWICMetadataBlockReader *iface, @@ -1051,7 +1054,7 @@ static ULONG WINAPI GifDecoder_AddRef(IWICBitmapDecoder *iface) GifDecoder *This = impl_from_IWICBitmapDecoder(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -1061,7 +1064,7 @@ static ULONG WINAPI GifDecoder_Release(IWICBitmapDecoder *iface) GifDecoder *This = impl_from_IWICBitmapDecoder(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { @@ -1072,7 +1075,7 @@ static ULONG WINAPI GifDecoder_Release(IWICBitmapDecoder *iface) } This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -1186,8 +1189,7 @@ static HRESULT WINAPI GifDecoder_CopyPalette(IWICBitmapDecoder *iface, IWICPalet GifDecoder *This = impl_from_IWICBitmapDecoder(iface); WICColor colors[256]; ColorMapObject *cm; - int i, trans, count; - ExtensionBlock *eb; + int count; TRACE("(%p,%p)\n", iface, palette); @@ -1195,49 +1197,15 @@ static HRESULT WINAPI GifDecoder_CopyPalette(IWICBitmapDecoder *iface, IWICPalet return WINCODEC_ERR_WRONGSTATE; cm = This->gif->SColorMap; - if (cm) + count = This->gif->SColorTableSize; + + if (count > 256) { - if (cm->ColorCount > 256) - { - ERR("GIF contains invalid number of colors: %d\n", cm->ColorCount); - return E_FAIL; - } - - for (i = 0; i < cm->ColorCount; i++) - { - colors[i] = 0xff000000 | /* alpha */ - cm->Colors[i].Red << 16 | - cm->Colors[i].Green << 8 | - cm->Colors[i].Blue; - } - - count = cm->ColorCount; - } - else - { - colors[0] = 0xff000000; - colors[1] = 0xffffffff; - - for (i = 2; i < 256; i++) - colors[i] = 0xff000000; - - count = 256; + ERR("GIF contains invalid number of colors: %d\n", count); + return E_FAIL; } - /* look for the transparent color extension */ - for (i = 0; i < This->gif->SavedImages[This->current_frame].Extensions.ExtensionBlockCount; i++) - { - eb = This->gif->SavedImages[This->current_frame].Extensions.ExtensionBlocks + i; - if (eb->Function == GRAPHICS_EXT_FUNC_CODE && eb->ByteCount == 8) - { - if (eb->Bytes[3] & 1) - { - trans = (unsigned char)eb->Bytes[6]; - colors[trans] &= 0xffffff; /* set alpha to 0 */ - break; - } - } - } + copy_palette(cm, &This->gif->SavedImages[This->current_frame].Extensions, count, colors); return IWICPalette_InitializeCustom(palette, colors, count); } @@ -1302,7 +1270,7 @@ static HRESULT WINAPI GifDecoder_GetFrame(IWICBitmapDecoder *iface, if (index >= This->gif->ImageCount) return E_INVALIDARG; - result = HeapAlloc(GetProcessHeap(), 0, sizeof(GifFrameDecode)); + result = malloc(sizeof(GifFrameDecode)); if (!result) return E_OUTOFMEMORY; result->IWICBitmapFrameDecode_iface.lpVtbl = &GifFrameDecode_Vtbl; @@ -1440,7 +1408,7 @@ HRESULT GifDecoder_CreateInstance(REFIID iid, void** ppv) *ppv = NULL; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(GifDecoder)); + This = malloc(sizeof(GifDecoder)); if (!This) return E_OUTOFMEMORY; This->IWICBitmapDecoder_iface.lpVtbl = &GifDecoder_Vtbl; @@ -1450,7 +1418,11 @@ HRESULT GifDecoder_CreateInstance(REFIID iid, void** ppv) This->initialized = FALSE; This->gif = NULL; This->current_frame = 0; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": GifDecoder.lock"); ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); @@ -1479,6 +1451,7 @@ static inline GifEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface) typedef struct GifFrameEncode { IWICBitmapFrameEncode IWICBitmapFrameEncode_iface; + IWICMetadataBlockWriter IWICMetadataBlockWriter_iface; LONG ref; GifEncoder *encoder; BOOL initialized, interlace, committed; @@ -1494,8 +1467,15 @@ static inline GifFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEnc return CONTAINING_RECORD(iface, GifFrameEncode, IWICBitmapFrameEncode_iface); } +static inline GifFrameEncode *impl_from_IWICMetadataBlockWriter(IWICMetadataBlockWriter *iface) +{ + return CONTAINING_RECORD(iface, GifFrameEncode, IWICMetadataBlockWriter_iface); +} + static HRESULT WINAPI GifFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid, void **ppv) { + GifFrameEncode *encoder = impl_from_IWICBitmapFrameEncode(iface); + TRACE("%p,%s,%p\n", iface, debugstr_guid(iid), ppv); if (!ppv) return E_INVALIDARG; @@ -1503,13 +1483,20 @@ static HRESULT WINAPI GifFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICBitmapFrameEncode, iid)) { - IWICBitmapFrameEncode_AddRef(iface); *ppv = iface; - return S_OK; + } + else if (IsEqualIID(&IID_IWICMetadataBlockWriter, iid)) + { + *ppv = &encoder->IWICMetadataBlockWriter_iface; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; } - *ppv = NULL; - return E_NOINTERFACE; + IUnknown_AddRef((IUnknown *)*ppv); + return S_OK; } static ULONG WINAPI GifFrameEncode_AddRef(IWICBitmapFrameEncode *iface) @@ -1517,7 +1504,7 @@ static ULONG WINAPI GifFrameEncode_AddRef(IWICBitmapFrameEncode *iface) GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("%p -> %u\n", iface, ref); + TRACE("%p -> %lu\n", iface, ref); return ref; } @@ -1526,13 +1513,13 @@ static ULONG WINAPI GifFrameEncode_Release(IWICBitmapFrameEncode *iface) GifFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("%p -> %u\n", iface, ref); + TRACE("%p -> %lu\n", iface, ref); if (!ref) { IWICBitmapEncoder_Release(&This->encoder->IWICBitmapEncoder_iface); - HeapFree(GetProcessHeap(), 0, This->image_data); - HeapFree(GetProcessHeap(), 0, This); + free(This->image_data); + free(This); } return ref; @@ -1573,9 +1560,9 @@ static HRESULT WINAPI GifFrameEncode_SetSize(IWICBitmapFrameEncode *iface, UINT if (This->initialized) { - HeapFree(GetProcessHeap(), 0, This->image_data); + free(This->image_data); - This->image_data = HeapAlloc(GetProcessHeap(), 0, width * height); + This->image_data = malloc(width * height); if (This->image_data) { This->width = width; @@ -1731,7 +1718,7 @@ static HRESULT WINAPI GifFrameEncode_WriteSource(IWICBitmapFrameEncode *iface, I hr = configure_write_source(iface, source, rc, format, This->width, This->height, This->xres, This->yres); if (hr == S_OK) - hr = write_source(iface, source, rc, format, 8, This->width, This->height); + hr = write_source(iface, source, rc, format, 8, !This->colors, This->width, This->height); } else hr = WINCODEC_ERR_WRONGSTATE; @@ -2108,8 +2095,17 @@ static HRESULT WINAPI GifFrameEncode_Commit(IWICBitmapFrameEncode *iface) static HRESULT WINAPI GifFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface, IWICMetadataQueryWriter **writer) { - FIXME("%p, %p: stub\n", iface, writer); - return E_NOTIMPL; + GifFrameEncode *encode = impl_from_IWICBitmapFrameEncode(iface); + + TRACE("iface, %p, writer %p.\n", iface, writer); + + if (!writer) + return E_INVALIDARG; + + if (!encode->initialized) + return WINCODEC_ERR_NOTINITIALIZED; + + return MetadataQueryWriter_CreateInstance(&encode->IWICMetadataBlockWriter_iface, NULL, writer); } static const IWICBitmapFrameEncodeVtbl GifFrameEncode_Vtbl = @@ -2153,7 +2149,7 @@ static ULONG WINAPI GifEncoder_AddRef(IWICBitmapEncoder *iface) GifEncoder *This = impl_from_IWICBitmapEncoder(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("%p -> %u\n", iface, ref); + TRACE("%p -> %lu\n", iface, ref); return ref; } @@ -2162,14 +2158,14 @@ static ULONG WINAPI GifEncoder_Release(IWICBitmapEncoder *iface) GifEncoder *This = impl_from_IWICBitmapEncoder(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("%p -> %u\n", iface, ref); + TRACE("%p -> %lu\n", iface, ref); if (!ref) { if (This->stream) IStream_Release(This->stream); This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -2265,6 +2261,109 @@ static HRESULT WINAPI GifEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmap return WINCODEC_ERR_UNSUPPORTEDOPERATION; } +static HRESULT WINAPI GifEncoderFrame_Block_QueryInterface(IWICMetadataBlockWriter *iface, REFIID iid, void **ppv) +{ + GifFrameEncode *frame_encoder = impl_from_IWICMetadataBlockWriter(iface); + + return IWICBitmapFrameEncode_QueryInterface(&frame_encoder->IWICBitmapFrameEncode_iface, iid, ppv); +} + +static ULONG WINAPI GifEncoderFrame_Block_AddRef(IWICMetadataBlockWriter *iface) +{ + GifFrameEncode *frame_encoder = impl_from_IWICMetadataBlockWriter(iface); + + return IWICBitmapFrameEncode_AddRef(&frame_encoder->IWICBitmapFrameEncode_iface); +} + +static ULONG WINAPI GifEncoderFrame_Block_Release(IWICMetadataBlockWriter *iface) +{ + GifFrameEncode *frame_encoder = impl_from_IWICMetadataBlockWriter(iface); + + return IWICBitmapFrameEncode_Release(&frame_encoder->IWICBitmapFrameEncode_iface); +} + +static HRESULT WINAPI GifEncoderFrame_Block_GetContainerFormat(IWICMetadataBlockWriter *iface, GUID *container_format) +{ + FIXME("iface %p, container_format %p stub.\n", iface, container_format); + + return E_NOTIMPL; +} + +static HRESULT WINAPI GifEncoderFrame_Block_GetCount(IWICMetadataBlockWriter *iface, UINT *count) +{ + FIXME("iface %p, count %p stub.\n", iface, count); + + return E_NOTIMPL; +} + +static HRESULT WINAPI GifEncoderFrame_Block_GetReaderByIndex(IWICMetadataBlockWriter *iface, + UINT index, IWICMetadataReader **metadata_reader) +{ + FIXME("iface %p, index %d, metadata_reader %p stub.\n", iface, index, metadata_reader); + + return E_NOTIMPL; +} + +static HRESULT WINAPI GifEncoderFrame_Block_GetEnumerator(IWICMetadataBlockWriter *iface, IEnumUnknown **enum_metadata) +{ + FIXME("iface %p, enum_metadata %p stub.\n", iface, enum_metadata); + + return E_NOTIMPL; +} + +static HRESULT WINAPI GifEncoderFrame_Block_InitializeFromBlockReader(IWICMetadataBlockWriter *iface, + IWICMetadataBlockReader *block_reader) +{ + FIXME("iface %p, block_reader %p stub.\n", iface, block_reader); + + return E_NOTIMPL; +} + +static HRESULT WINAPI GifEncoderFrame_Block_GetWriterByIndex(IWICMetadataBlockWriter *iface, UINT index, + IWICMetadataWriter **metadata_writer) +{ + FIXME("iface %p, index %u, metadata_writer %p stub.\n", iface, index, metadata_writer); + + return E_NOTIMPL; +} + +static HRESULT WINAPI GifEncoderFrame_Block_AddWriter(IWICMetadataBlockWriter *iface, IWICMetadataWriter *metadata_writer) +{ + FIXME("iface %p, metadata_writer %p stub.\n", iface, metadata_writer); + + return E_NOTIMPL; +} + +static HRESULT WINAPI GifEncoderFrame_Block_SetWriterByIndex(IWICMetadataBlockWriter *iface, UINT index, + IWICMetadataWriter *metadata_writer) +{ + FIXME("iface %p, index %u, metadata_writer %p stub.\n", iface, index, metadata_writer); + + return E_NOTIMPL; +} + +static HRESULT WINAPI GifEncoderFrame_Block_RemoveWriterByIndex(IWICMetadataBlockWriter *iface, UINT index) +{ + FIXME("iface %p, index %u stub.\n", iface, index); + + return E_NOTIMPL; +} + +static const IWICMetadataBlockWriterVtbl GifFrameEncode_BlockVtbl = { + GifEncoderFrame_Block_QueryInterface, + GifEncoderFrame_Block_AddRef, + GifEncoderFrame_Block_Release, + GifEncoderFrame_Block_GetContainerFormat, + GifEncoderFrame_Block_GetCount, + GifEncoderFrame_Block_GetReaderByIndex, + GifEncoderFrame_Block_GetEnumerator, + GifEncoderFrame_Block_InitializeFromBlockReader, + GifEncoderFrame_Block_GetWriterByIndex, + GifEncoderFrame_Block_AddWriter, + GifEncoderFrame_Block_SetWriterByIndex, + GifEncoderFrame_Block_RemoveWriterByIndex, +}; + static HRESULT WINAPI GifEncoder_CreateNewFrame(IWICBitmapEncoder *iface, IWICBitmapFrameEncode **frame, IPropertyBag2 **options) { GifEncoder *This = impl_from_IWICBitmapEncoder(iface); @@ -2278,12 +2377,14 @@ static HRESULT WINAPI GifEncoder_CreateNewFrame(IWICBitmapEncoder *iface, IWICBi if (This->initialized && !This->committed) { - GifFrameEncode *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(*ret)); + GifFrameEncode *ret = malloc(sizeof(*ret)); if (ret) { This->n_frames++; ret->IWICBitmapFrameEncode_iface.lpVtbl = &GifFrameEncode_Vtbl; + ret->IWICMetadataBlockWriter_iface.lpVtbl = &GifFrameEncode_BlockVtbl; + ret->ref = 1; ret->encoder = This; ret->initialized = FALSE; @@ -2381,13 +2482,17 @@ HRESULT GifEncoder_CreateInstance(REFIID iid, void **ppv) *ppv = NULL; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); + This = malloc(sizeof(*This)); if (!This) return E_OUTOFMEMORY; This->IWICBitmapEncoder_iface.lpVtbl = &GifEncoder_Vtbl; This->ref = 1; This->stream = NULL; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": GifEncoder.lock"); This->initialized = FALSE; This->info_written = FALSE; diff --git a/dll/win32/windowscodecs/icnsformat.c b/dll/win32/windowscodecs/icnsformat.c deleted file mode 100644 index 8194bc508a5..00000000000 --- a/dll/win32/windowscodecs/icnsformat.c +++ /dev/null @@ -1,743 +0,0 @@ -/* - * Copyright 2010 Damjan Jovanovic - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#include - -#ifdef HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H -#define GetCurrentProcess GetCurrentProcess_Mac -#define GetCurrentThread GetCurrentThread_Mac -#define LoadResource LoadResource_Mac -#define AnimatePalette AnimatePalette_Mac -#define EqualRgn EqualRgn_Mac -#define FillRgn FillRgn_Mac -#define FrameRgn FrameRgn_Mac -#define GetPixel GetPixel_Mac -#define InvertRgn InvertRgn_Mac -#define LineTo LineTo_Mac -#define OffsetRgn OffsetRgn_Mac -#define PaintRgn PaintRgn_Mac -#define Polygon Polygon_Mac -#define ResizePalette ResizePalette_Mac -#define SetRectRgn SetRectRgn_Mac -#define EqualRect EqualRect_Mac -#define FillRect FillRect_Mac -#define FrameRect FrameRect_Mac -#define GetCursor GetCursor_Mac -#define InvertRect InvertRect_Mac -#define OffsetRect OffsetRect_Mac -#define PtInRect PtInRect_Mac -#define SetCursor SetCursor_Mac -#define SetRect SetRect_Mac -#define ShowCursor ShowCursor_Mac -#define UnionRect UnionRect_Mac -#include -#undef GetCurrentProcess -#undef GetCurrentThread -#undef LoadResource -#undef AnimatePalette -#undef EqualRgn -#undef FillRgn -#undef FrameRgn -#undef GetPixel -#undef InvertRgn -#undef LineTo -#undef OffsetRgn -#undef PaintRgn -#undef Polygon -#undef ResizePalette -#undef SetRectRgn -#undef EqualRect -#undef FillRect -#undef FrameRect -#undef GetCursor -#undef InvertRect -#undef OffsetRect -#undef PtInRect -#undef SetCursor -#undef SetRect -#undef ShowCursor -#undef UnionRect -#endif - -#define COBJMACROS - -#include "windef.h" -#include "winbase.h" -#include "objbase.h" - -#include "wincodecs_private.h" - -#include "wine/debug.h" -#include "wine/library.h" - -WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); - -#if defined(HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H) && \ - MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4 - -typedef struct IcnsEncoder { - IWICBitmapEncoder IWICBitmapEncoder_iface; - LONG ref; - IStream *stream; - IconFamilyHandle icns_family; - BOOL any_frame_committed; - int outstanding_commits; - BOOL committed; - CRITICAL_SECTION lock; -} IcnsEncoder; - -static inline IcnsEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface) -{ - return CONTAINING_RECORD(iface, IcnsEncoder, IWICBitmapEncoder_iface); -} - -typedef struct IcnsFrameEncode { - IWICBitmapFrameEncode IWICBitmapFrameEncode_iface; - IcnsEncoder *encoder; - LONG ref; - BOOL initialized; - UINT size; - OSType icns_type; - BYTE* icns_image; - int lines_written; - BOOL committed; -} IcnsFrameEncode; - -static inline IcnsFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface) -{ - return CONTAINING_RECORD(iface, IcnsFrameEncode, IWICBitmapFrameEncode_iface); -} - -static HRESULT WINAPI IcnsFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid, - void **ppv) -{ - IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapFrameEncode, iid)) - { - *ppv = &This->IWICBitmapFrameEncode_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI IcnsFrameEncode_AddRef(IWICBitmapFrameEncode *iface) -{ - IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - return ref; -} - -static ULONG WINAPI IcnsFrameEncode_Release(IWICBitmapFrameEncode *iface) -{ - IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - if (ref == 0) - { - if (!This->committed) - { - EnterCriticalSection(&This->encoder->lock); - This->encoder->outstanding_commits--; - LeaveCriticalSection(&This->encoder->lock); - } - HeapFree(GetProcessHeap(), 0, This->icns_image); - - IWICBitmapEncoder_Release(&This->encoder->IWICBitmapEncoder_iface); - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static HRESULT WINAPI IcnsFrameEncode_Initialize(IWICBitmapFrameEncode *iface, - IPropertyBag2 *pIEncoderOptions) -{ - IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr = S_OK; - - TRACE("(%p,%p)\n", iface, pIEncoderOptions); - - EnterCriticalSection(&This->encoder->lock); - - if (This->initialized) - { - hr = WINCODEC_ERR_WRONGSTATE; - goto end; - } - This->initialized = TRUE; - -end: - LeaveCriticalSection(&This->encoder->lock); - return hr; -} - -static HRESULT WINAPI IcnsFrameEncode_SetSize(IWICBitmapFrameEncode *iface, - UINT uiWidth, UINT uiHeight) -{ - IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr = S_OK; - - TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight); - - EnterCriticalSection(&This->encoder->lock); - - if (!This->initialized || This->icns_image) - { - hr = WINCODEC_ERR_WRONGSTATE; - goto end; - } - - if (uiWidth != uiHeight) - { - WARN("cannot generate ICNS icon from %dx%d image\n", uiWidth, uiHeight); - hr = E_INVALIDARG; - goto end; - } - - switch (uiWidth) - { - case 16: - case 32: - case 48: - case 128: - case 256: - case 512: - break; - default: - WARN("cannot generate ICNS icon from %dx%d image\n", This->size, This->size); - hr = E_INVALIDARG; - goto end; - } - - This->size = uiWidth; - -end: - LeaveCriticalSection(&This->encoder->lock); - return hr; -} - -static HRESULT WINAPI IcnsFrameEncode_SetResolution(IWICBitmapFrameEncode *iface, - double dpiX, double dpiY) -{ - IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr = S_OK; - - TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY); - - EnterCriticalSection(&This->encoder->lock); - - if (!This->initialized || This->icns_image) - { - hr = WINCODEC_ERR_WRONGSTATE; - goto end; - } - -end: - LeaveCriticalSection(&This->encoder->lock); - return S_OK; -} - -static HRESULT WINAPI IcnsFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface, - WICPixelFormatGUID *pPixelFormat) -{ - IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr = S_OK; - - TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat)); - - EnterCriticalSection(&This->encoder->lock); - - if (!This->initialized || This->icns_image) - { - hr = WINCODEC_ERR_WRONGSTATE; - goto end; - } - - memcpy(pPixelFormat, &GUID_WICPixelFormat32bppBGRA, sizeof(GUID)); - -end: - LeaveCriticalSection(&This->encoder->lock); - return S_OK; -} - -static HRESULT WINAPI IcnsFrameEncode_SetColorContexts(IWICBitmapFrameEncode *iface, - UINT cCount, IWICColorContext **ppIColorContext) -{ - FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); - return E_NOTIMPL; -} - -static HRESULT WINAPI IcnsFrameEncode_SetPalette(IWICBitmapFrameEncode *iface, - IWICPalette *pIPalette) -{ - FIXME("(%p,%p): stub\n", iface, pIPalette); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI IcnsFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface, - IWICBitmapSource *pIThumbnail) -{ - FIXME("(%p,%p): stub\n", iface, pIThumbnail); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI IcnsFrameEncode_WritePixels(IWICBitmapFrameEncode *iface, - UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels) -{ - IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr = S_OK; - UINT i; - - TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels); - - EnterCriticalSection(&This->encoder->lock); - - if (!This->initialized || !This->size) - { - hr = WINCODEC_ERR_WRONGSTATE; - goto end; - } - if (lineCount == 0 || lineCount + This->lines_written > This->size) - { - hr = E_INVALIDARG; - goto end; - } - - if (!This->icns_image) - { - switch (This->size) - { - case 16: This->icns_type = kIconServices16PixelDataARGB; break; - case 32: This->icns_type = kIconServices32PixelDataARGB; break; - case 48: This->icns_type = kIconServices48PixelDataARGB; break; - case 128: This->icns_type = kIconServices128PixelDataARGB; break; - case 256: This->icns_type = kIconServices256PixelDataARGB; break; - case 512: This->icns_type = kIconServices512PixelDataARGB; break; - default: - WARN("cannot generate ICNS icon from %dx%d image\n", This->size, This->size); - hr = E_INVALIDARG; - goto end; - } - This->icns_image = HeapAlloc(GetProcessHeap(), 0, This->size * This->size * 4); - if (!This->icns_image) - { - WARN("failed to allocate image buffer\n"); - hr = E_FAIL; - goto end; - } - } - - for (i = 0; i < lineCount; i++) - { - BYTE *src_row, *dst_row; - UINT j; - src_row = pbPixels + cbStride * i; - dst_row = This->icns_image + (This->lines_written + i)*(This->size*4); - /* swap bgr -> rgb */ - for (j = 0; j < This->size*4; j += 4) - { - dst_row[j] = src_row[j+3]; - dst_row[j+1] = src_row[j+2]; - dst_row[j+2] = src_row[j+1]; - dst_row[j+3] = src_row[j]; - } - } - This->lines_written += lineCount; - -end: - LeaveCriticalSection(&This->encoder->lock); - return hr; -} - -static HRESULT WINAPI IcnsFrameEncode_WriteSource(IWICBitmapFrameEncode *iface, - IWICBitmapSource *pIBitmapSource, WICRect *prc) -{ - IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr; - - TRACE("(%p,%p,%s)\n", iface, pIBitmapSource, debug_wic_rect(prc)); - - if (!This->initialized) - return WINCODEC_ERR_WRONGSTATE; - - hr = configure_write_source(iface, pIBitmapSource, prc, - &GUID_WICPixelFormat32bppBGRA, This->size, This->size, - 1.0, 1.0); - - if (SUCCEEDED(hr)) - { - hr = write_source(iface, pIBitmapSource, prc, - &GUID_WICPixelFormat32bppBGRA, 32, This->size, This->size); - } - - return hr; -} - -static HRESULT WINAPI IcnsFrameEncode_Commit(IWICBitmapFrameEncode *iface) -{ - IcnsFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - Handle handle; - OSErr ret; - HRESULT hr = S_OK; - - TRACE("(%p)\n", iface); - - EnterCriticalSection(&This->encoder->lock); - - if (!This->icns_image || This->lines_written != This->size || This->committed) - { - hr = WINCODEC_ERR_WRONGSTATE; - goto end; - } - - ret = PtrToHand(This->icns_image, &handle, This->size * This->size * 4); - if (ret != noErr || !handle) - { - WARN("PtrToHand failed with error %d\n", ret); - hr = E_FAIL; - goto end; - } - - ret = SetIconFamilyData(This->encoder->icns_family, This->icns_type, handle); - DisposeHandle(handle); - - if (ret != noErr) - { - WARN("SetIconFamilyData failed for image with error %d\n", ret); - hr = E_FAIL; - goto end; - } - - This->committed = TRUE; - This->encoder->any_frame_committed = TRUE; - This->encoder->outstanding_commits--; - -end: - LeaveCriticalSection(&This->encoder->lock); - return hr; -} - -static HRESULT WINAPI IcnsFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface, - IWICMetadataQueryWriter **ppIMetadataQueryWriter) -{ - FIXME("(%p, %p): stub\n", iface, ppIMetadataQueryWriter); - return E_NOTIMPL; -} - -static const IWICBitmapFrameEncodeVtbl IcnsEncoder_FrameVtbl = { - IcnsFrameEncode_QueryInterface, - IcnsFrameEncode_AddRef, - IcnsFrameEncode_Release, - IcnsFrameEncode_Initialize, - IcnsFrameEncode_SetSize, - IcnsFrameEncode_SetResolution, - IcnsFrameEncode_SetPixelFormat, - IcnsFrameEncode_SetColorContexts, - IcnsFrameEncode_SetPalette, - IcnsFrameEncode_SetThumbnail, - IcnsFrameEncode_WritePixels, - IcnsFrameEncode_WriteSource, - IcnsFrameEncode_Commit, - IcnsFrameEncode_GetMetadataQueryWriter -}; - -static HRESULT WINAPI IcnsEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid, - void **ppv) -{ - IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapEncoder, iid)) - { - *ppv = &This->IWICBitmapEncoder_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI IcnsEncoder_AddRef(IWICBitmapEncoder *iface) -{ - IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - return ref; -} - -static ULONG WINAPI IcnsEncoder_Release(IWICBitmapEncoder *iface) -{ - IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - if (ref == 0) - { - This->lock.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->lock); - if (This->icns_family) - DisposeHandle((Handle)This->icns_family); - if (This->stream) - IStream_Release(This->stream); - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static HRESULT WINAPI IcnsEncoder_Initialize(IWICBitmapEncoder *iface, - IStream *pIStream, WICBitmapEncoderCacheOption cacheOption) -{ - IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface); - HRESULT hr = S_OK; - - TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption); - - EnterCriticalSection(&This->lock); - - if (This->icns_family) - { - hr = WINCODEC_ERR_WRONGSTATE; - goto end; - } - This->icns_family = (IconFamilyHandle)NewHandle(0); - if (!This->icns_family) - { - WARN("error creating icns family\n"); - hr = E_FAIL; - goto end; - } - IStream_AddRef(pIStream); - This->stream = pIStream; - -end: - LeaveCriticalSection(&This->lock); - - return hr; -} - -static HRESULT WINAPI IcnsEncoder_GetContainerFormat(IWICBitmapEncoder *iface, - GUID *pguidContainerFormat) -{ - FIXME("(%p,%s): stub\n", iface, debugstr_guid(pguidContainerFormat)); - return E_NOTIMPL; -} - -static HRESULT WINAPI IcnsEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, - IWICBitmapEncoderInfo **ppIEncoderInfo) -{ - FIXME("(%p,%p): stub\n", iface, ppIEncoderInfo); - return E_NOTIMPL; -} - -static HRESULT WINAPI IcnsEncoder_SetColorContexts(IWICBitmapEncoder *iface, - UINT cCount, IWICColorContext **ppIColorContext) -{ - FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); - return E_NOTIMPL; -} - -static HRESULT WINAPI IcnsEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *pIPalette) -{ - TRACE("(%p,%p)\n", iface, pIPalette); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI IcnsEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail) -{ - TRACE("(%p,%p)\n", iface, pIThumbnail); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI IcnsEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *pIPreview) -{ - TRACE("(%p,%p)\n", iface, pIPreview); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI IcnsEncoder_CreateNewFrame(IWICBitmapEncoder *iface, - IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions) -{ - IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface); - HRESULT hr = S_OK; - IcnsFrameEncode *frameEncode = NULL; - - TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions); - - EnterCriticalSection(&This->lock); - - if (!This->icns_family) - { - hr = WINCODEC_ERR_NOTINITIALIZED; - goto end; - } - - if (ppIEncoderOptions) - { - hr = CreatePropertyBag2(NULL, 0, ppIEncoderOptions); - if (FAILED(hr)) - goto end; - } - - frameEncode = HeapAlloc(GetProcessHeap(), 0, sizeof(IcnsFrameEncode)); - if (frameEncode == NULL) - { - hr = E_OUTOFMEMORY; - goto end; - } - frameEncode->IWICBitmapFrameEncode_iface.lpVtbl = &IcnsEncoder_FrameVtbl; - frameEncode->encoder = This; - frameEncode->ref = 1; - frameEncode->initialized = FALSE; - frameEncode->size = 0; - frameEncode->icns_image = NULL; - frameEncode->lines_written = 0; - frameEncode->committed = FALSE; - *ppIFrameEncode = &frameEncode->IWICBitmapFrameEncode_iface; - This->outstanding_commits++; - IWICBitmapEncoder_AddRef(&This->IWICBitmapEncoder_iface); - -end: - LeaveCriticalSection(&This->lock); - - return hr; -} - -static HRESULT WINAPI IcnsEncoder_Commit(IWICBitmapEncoder *iface) -{ - IcnsEncoder *This = impl_from_IWICBitmapEncoder(iface); - size_t buffer_size; - HRESULT hr = S_OK; - ULONG byteswritten; - - TRACE("(%p)\n", iface); - - EnterCriticalSection(&This->lock); - - if (!This->any_frame_committed || This->outstanding_commits > 0 || This->committed) - { - hr = WINCODEC_ERR_WRONGSTATE; - goto end; - } - - buffer_size = GetHandleSize((Handle)This->icns_family); - hr = IStream_Write(This->stream, *This->icns_family, buffer_size, &byteswritten); - if (FAILED(hr) || byteswritten != buffer_size) - { - WARN("writing file failed, hr = 0x%08X\n", hr); - hr = E_FAIL; - goto end; - } - - This->committed = TRUE; - -end: - LeaveCriticalSection(&This->lock); - return hr; -} - -static HRESULT WINAPI IcnsEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface, - IWICMetadataQueryWriter **ppIMetadataQueryWriter) -{ - FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryWriter); - return E_NOTIMPL; -} - -static const IWICBitmapEncoderVtbl IcnsEncoder_Vtbl = { - IcnsEncoder_QueryInterface, - IcnsEncoder_AddRef, - IcnsEncoder_Release, - IcnsEncoder_Initialize, - IcnsEncoder_GetContainerFormat, - IcnsEncoder_GetEncoderInfo, - IcnsEncoder_SetColorContexts, - IcnsEncoder_SetPalette, - IcnsEncoder_SetThumbnail, - IcnsEncoder_SetPreview, - IcnsEncoder_CreateNewFrame, - IcnsEncoder_Commit, - IcnsEncoder_GetMetadataQueryWriter -}; - -HRESULT IcnsEncoder_CreateInstance(REFIID iid, void** ppv) -{ - IcnsEncoder *This; - HRESULT ret; - - TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); - - *ppv = NULL; - - This = HeapAlloc(GetProcessHeap(), 0, sizeof(IcnsEncoder)); - if (!This) return E_OUTOFMEMORY; - - This->IWICBitmapEncoder_iface.lpVtbl = &IcnsEncoder_Vtbl; - This->ref = 1; - This->stream = NULL; - This->icns_family = NULL; - This->any_frame_committed = FALSE; - This->outstanding_commits = 0; - This->committed = FALSE; - InitializeCriticalSection(&This->lock); - This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IcnsEncoder.lock"); - - ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv); - IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface); - - return ret; -} - -#else /* !defined(HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H) || - MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 */ - -HRESULT IcnsEncoder_CreateInstance(REFIID iid, void** ppv) -{ - ERR("Trying to save ICNS picture, but ICNS support is not compiled in.\n"); - return E_FAIL; -} - -#endif diff --git a/dll/win32/windowscodecs/icoformat.c b/dll/win32/windowscodecs/icoformat.c index d2a6196cd07..f4f01dd1767 100644 --- a/dll/win32/windowscodecs/icoformat.c +++ b/dll/win32/windowscodecs/icoformat.c @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -111,7 +109,7 @@ static ULONG WINAPI IcoFrameDecode_AddRef(IWICBitmapFrameDecode *iface) IcoFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -121,12 +119,12 @@ static ULONG WINAPI IcoFrameDecode_Release(IWICBitmapFrameDecode *iface) IcoFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { - HeapFree(GetProcessHeap(), 0, This->bits); - HeapFree(GetProcessHeap(), 0, This); + free(This->bits); + free(This); } return ref; @@ -249,7 +247,7 @@ static HRESULT ReadIcoDib(IStream *stream, IcoFrameDecode *result) if (SUCCEEDED(hr)) { - result->bits = HeapAlloc(GetProcessHeap(), 0, result->width * result->height * 4); + result->bits = malloc(result->width * result->height * 4); if (!result->bits) hr = E_OUTOFMEMORY; } @@ -338,7 +336,7 @@ static HRESULT ReadIcoDib(IStream *stream, IcoFrameDecode *result) if (SUCCEEDED(hr)) { - tempdata = HeapAlloc(GetProcessHeap(), 0, andBytes); + tempdata = malloc(andBytes); if (!tempdata) hr = E_OUTOFMEMORY; } @@ -378,7 +376,7 @@ static HRESULT ReadIcoDib(IStream *stream, IcoFrameDecode *result) } } - HeapFree(GetProcessHeap(), 0, tempdata); + free(tempdata); } } @@ -414,7 +412,7 @@ static HRESULT ReadIcoPng(IStream *stream, IcoFrameDecode *result) hr = IWICBitmapFrameDecode_GetResolution(sourceFrame, &result->dpiX, &result->dpiY); if (FAILED(hr)) goto end; - result->bits = HeapAlloc(GetProcessHeap(), 0, 4 * result->width * result->height); + result->bits = malloc(4 * result->width * result->height); if (result->bits == NULL) { hr = E_OUTOFMEMORY; @@ -465,7 +463,7 @@ static ULONG WINAPI IcoDecoder_AddRef(IWICBitmapDecoder *iface) IcoDecoder *This = impl_from_IWICBitmapDecoder(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -475,14 +473,14 @@ static ULONG WINAPI IcoDecoder_Release(IWICBitmapDecoder *iface) IcoDecoder *This = impl_from_IWICBitmapDecoder(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); if (This->stream) IStream_Release(This->stream); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -547,7 +545,7 @@ static HRESULT WINAPI IcoDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p hr = IStream_Stat(pIStream, &statstg, STATFLAG_NONAME); if (FAILED(hr)) { - WARN("Stat() failed, hr %#x.\n", hr); + WARN("Stat() failed, hr %#lx.\n", hr); goto end; } @@ -670,7 +668,7 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface, goto fail; } - result = HeapAlloc(GetProcessHeap(), 0, sizeof(IcoFrameDecode)); + result = malloc(sizeof(IcoFrameDecode)); if (!result) { hr = E_OUTOFMEMORY; @@ -716,7 +714,7 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface, hr = ReadIcoPng((IStream*)substream, result); break; default: - FIXME("Unrecognized ICO frame magic: %x\n", magic); + FIXME("Unrecognized ICO frame magic: %lx\n", magic); hr = E_FAIL; break; } @@ -732,10 +730,10 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface, fail: LeaveCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, result); + free(result); if (substream) IWICStream_Release(substream); if (SUCCEEDED(hr)) hr = E_FAIL; - TRACE("<-- %x\n", hr); + TRACE("<-- %lx\n", hr); return hr; } @@ -765,14 +763,18 @@ HRESULT IcoDecoder_CreateInstance(REFIID iid, void** ppv) *ppv = NULL; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(IcoDecoder)); + This = malloc(sizeof(IcoDecoder)); if (!This) return E_OUTOFMEMORY; This->IWICBitmapDecoder_iface.lpVtbl = &IcoDecoder_Vtbl; This->ref = 1; This->stream = NULL; This->initialized = FALSE; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IcoDecoder.lock"); ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); diff --git a/dll/win32/windowscodecs/imgfactory.c b/dll/win32/windowscodecs/imgfactory.c index e127e405570..84a46303c95 100644 --- a/dll/win32/windowscodecs/imgfactory.c +++ b/dll/win32/windowscodecs/imgfactory.c @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #include @@ -85,7 +83,7 @@ static ULONG WINAPI ImagingFactory_AddRef(IWICImagingFactory2 *iface) ImagingFactory *This = impl_from_IWICImagingFactory2(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -95,10 +93,10 @@ static ULONG WINAPI ImagingFactory_Release(IWICImagingFactory2 *iface) ImagingFactory *This = impl_from_IWICImagingFactory2(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) - HeapFree(GetProcessHeap(), 0, This); + free(This); return ref; } @@ -111,7 +109,7 @@ static HRESULT WINAPI ImagingFactory_CreateDecoderFromFilename( IWICStream *stream; HRESULT hr; - TRACE("(%p,%s,%s,%u,%u,%p)\n", iface, debugstr_w(wzFilename), + TRACE("(%p,%s,%s,%lu,%u,%p)\n", iface, debugstr_w(wzFilename), debugstr_guid(pguidVendor), dwDesiredAccess, metadataOptions, ppIDecoder); hr = StreamImpl_Create(&stream); @@ -134,76 +132,74 @@ static HRESULT WINAPI ImagingFactory_CreateDecoderFromFilename( static HRESULT find_decoder(IStream *pIStream, const GUID *pguidVendor, WICDecodeOptions metadataOptions, IWICBitmapDecoder **decoder) { - IEnumUnknown *enumdecoders; - IUnknown *unkdecoderinfo; - IWICBitmapDecoderInfo *decoderinfo; + IEnumUnknown *enumdecoders = NULL; + IUnknown *unkdecoderinfo = NULL; GUID vendor; - HRESULT res; + HRESULT res, res_wine; ULONG num_fetched; - BOOL matches; + BOOL matches, found; *decoder = NULL; res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders); if (FAILED(res)) return res; - while (!*decoder) + found = FALSE; + while (IEnumUnknown_Next(enumdecoders, 1, &unkdecoderinfo, &num_fetched) == S_OK) { - res = IEnumUnknown_Next(enumdecoders, 1, &unkdecoderinfo, &num_fetched); + IWICBitmapDecoderInfo *decoderinfo = NULL; + IWICWineDecoder *wine_decoder = NULL; - if (res == S_OK) + res = IUnknown_QueryInterface(unkdecoderinfo, &IID_IWICBitmapDecoderInfo, (void**)&decoderinfo); + if (FAILED(res)) goto next; + + if (pguidVendor) { - res = IUnknown_QueryInterface(unkdecoderinfo, &IID_IWICBitmapDecoderInfo, (void**)&decoderinfo); + res = IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo, &vendor); + if (FAILED(res) || !IsEqualIID(&vendor, pguidVendor)) goto next; + } - if (SUCCEEDED(res)) + res = IWICBitmapDecoderInfo_MatchesPattern(decoderinfo, pIStream, &matches); + if (FAILED(res) || !matches) goto next; + + res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, decoder); + if (FAILED(res)) goto next; + + /* FIXME: should use QueryCapability to choose a decoder */ + + found = TRUE; + res = IWICBitmapDecoder_Initialize(*decoder, pIStream, metadataOptions); + if (FAILED(res)) + { + res_wine = IWICBitmapDecoder_QueryInterface(*decoder, &IID_IWICWineDecoder, (void **)&wine_decoder); + if (FAILED(res_wine)) { - if (pguidVendor) - { - res = IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo, &vendor); - if (FAILED(res) || !IsEqualIID(&vendor, pguidVendor)) - { - IWICBitmapDecoderInfo_Release(decoderinfo); - IUnknown_Release(unkdecoderinfo); - continue; - } - } - - res = IWICBitmapDecoderInfo_MatchesPattern(decoderinfo, pIStream, &matches); - - if (SUCCEEDED(res) && matches) - { - res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, decoder); - - /* FIXME: should use QueryCapability to choose a decoder */ - - if (SUCCEEDED(res)) - { - res = IWICBitmapDecoder_Initialize(*decoder, pIStream, metadataOptions); - - if (FAILED(res)) - { - IWICBitmapDecoder_Release(*decoder); - IWICBitmapDecoderInfo_Release(decoderinfo); - IUnknown_Release(unkdecoderinfo); - IEnumUnknown_Release(enumdecoders); - *decoder = NULL; - return res; - } - } - } - - IWICBitmapDecoderInfo_Release(decoderinfo); + IWICBitmapDecoder_Release(*decoder); + *decoder = NULL; + goto next; } - IUnknown_Release(unkdecoderinfo); + res_wine = IWICWineDecoder_Initialize(wine_decoder, pIStream, metadataOptions); + if (FAILED(res_wine)) + { + IWICBitmapDecoder_Release(*decoder); + *decoder = NULL; + goto next; + } + + res = res_wine; } - else - break; + + next: + if (wine_decoder) IWICWineDecoder_Release(wine_decoder); + if (decoderinfo) IWICBitmapDecoderInfo_Release(decoderinfo); + IUnknown_Release(unkdecoderinfo); + if (found) break; } IEnumUnknown_Release(enumdecoders); - - return WINCODEC_ERR_COMPONENTNOTFOUND; + if (!found) res = WINCODEC_ERR_COMPONENTNOTFOUND; + return res; } static HRESULT WINAPI ImagingFactory_CreateDecoderFromStream( @@ -234,13 +230,13 @@ static HRESULT WINAPI ImagingFactory_CreateDecoderFromStream( BYTE data[4]; ULONG bytesread; - WARN("failed to load from a stream %#x\n", res); + WARN("failed to load from a stream %#lx\n", res); seek.QuadPart = 0; 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]); + WARN("first %li bytes of stream=%x %x %x %x\n", bytesread, data[0], data[1], data[2], data[3]); } } *ppIDecoder = NULL; @@ -255,7 +251,7 @@ static HRESULT WINAPI ImagingFactory_CreateDecoderFromFileHandle( IWICStream *stream; HRESULT hr; - TRACE("(%p,%lx,%s,%u,%p)\n", iface, hFile, debugstr_guid(pguidVendor), + TRACE("(%p,%Ix,%s,%u,%p)\n", iface, hFile, debugstr_guid(pguidVendor), metadataOptions, ppIDecoder); hr = StreamImpl_Create(&stream); @@ -713,7 +709,7 @@ static BOOL get_16bpp_format(HBITMAP hbm, WICPixelFormatGUID *format) } else { - FIXME("unrecognized bitfields %x,%x,%x\n", bmh.bV4RedMask, + FIXME("unrecognized bitfields %lx,%lx,%lx\n", bmh.bV4RedMask, bmh.bV4GreenMask, bmh.bV4BlueMask); ret = FALSE; } @@ -798,7 +794,11 @@ static HRESULT WINAPI ImagingFactory_CreateBitmapFromHBITMAP(IWICImagingFactory2 { BYTE *buffer; HDC hdc; +#ifdef __REACTOS__ char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors) + 256 * sizeof(RGBQUAD)]; +#else + char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors[256])]; +#endif BITMAPINFO *bmi = (BITMAPINFO *)bmibuf; IWICBitmapLock_GetDataPointer(lock, &size, &buffer); @@ -905,16 +905,14 @@ static HRESULT WINAPI ImagingFactory_CreateBitmapFromHICON(IWICImagingFactory2 * if (bm.bmBitsPixel == 32) { /* If any pixel has a non-zero alpha, ignore hbmMask */ - bits = (DWORD *)buffer; - for (x = 0; x < width && !has_alpha; x++, bits++) + DWORD *ptr = (DWORD *)buffer; + DWORD *end = ptr + width * height; + while (ptr != end) { - for (y = 0; y < height; y++) + if (*ptr++ & 0xff000000) { - if (*bits & 0xff000000) - { - has_alpha = TRUE; - break; - } + has_alpha = TRUE; + break; } } } @@ -930,7 +928,7 @@ static HRESULT WINAPI ImagingFactory_CreateBitmapFromHICON(IWICImagingFactory2 * { BYTE *mask; - mask = HeapAlloc(GetProcessHeap(), 0, size); + mask = malloc(size); if (!mask) { IWICBitmapLock_Release(lock); @@ -957,7 +955,7 @@ static HRESULT WINAPI ImagingFactory_CreateBitmapFromHICON(IWICImagingFactory2 * } } - HeapFree(GetProcessHeap(), 0, mask); + free(mask); } else { @@ -985,7 +983,7 @@ failed: static HRESULT WINAPI ImagingFactory_CreateComponentEnumerator(IWICImagingFactory2 *iface, DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown) { - TRACE("(%p,%u,%u,%p)\n", iface, componentTypes, options, ppIEnumUnknown); + TRACE("(%p,%lu,%lu,%p)\n", iface, componentTypes, options, ppIEnumUnknown); return CreateComponentEnumerator(componentTypes, options, ppIEnumUnknown); } @@ -1254,146 +1252,280 @@ static HRESULT WINAPI ComponentFactory_CreateQueryWriterFromReader(IWICComponent return IWICImagingFactory2_CreateQueryWriterFromReader(&This->IWICImagingFactory2_iface, reader, vendor, writer); } +enum iterator_result +{ + ITER_SKIP, + ITER_DONE, +}; + +struct iterator_context +{ + const GUID *format; + const GUID *vendor; + DWORD options; + IStream *stream; + + void **result; +}; + +typedef enum iterator_result (*iterator_func)(IUnknown *item, struct iterator_context *context); + +static enum iterator_result create_metadata_reader_from_container_iterator(IUnknown *item, + struct iterator_context *context) +{ + IWICPersistStream *persist_stream = NULL; + IWICMetadataReaderInfo *readerinfo; + IWICMetadataReader *reader = NULL; + LARGE_INTEGER zero = {{0}}; + BOOL matches; + HRESULT hr; + GUID guid; + + if (FAILED(IUnknown_QueryInterface(item, &IID_IWICMetadataReaderInfo, (void **)&readerinfo))) + return ITER_SKIP; + + if (context->vendor) + { + hr = IWICMetadataReaderInfo_GetVendorGUID(readerinfo, &guid); + + if (FAILED(hr) || !IsEqualIID(context->vendor, &guid)) + { + IWICMetadataReaderInfo_Release(readerinfo); + return ITER_SKIP; + } + } + + hr = IWICMetadataReaderInfo_MatchesPattern(readerinfo, context->format, context->stream, &matches); + + if (SUCCEEDED(hr) && matches) + { + hr = IStream_Seek(context->stream, zero, STREAM_SEEK_SET, NULL); + + if (SUCCEEDED(hr)) + hr = IWICMetadataReaderInfo_CreateInstance(readerinfo, &reader); + + if (SUCCEEDED(hr)) + hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist_stream); + + if (SUCCEEDED(hr)) + hr = IWICPersistStream_LoadEx(persist_stream, context->stream, context->vendor, + context->options & WICPersistOptionMask); + + if (persist_stream) + IWICPersistStream_Release(persist_stream); + + if (SUCCEEDED(hr)) + { + *context->result = reader; + IWICMetadataReaderInfo_Release(readerinfo); + return ITER_DONE; + } + + if (reader) + IWICMetadataReader_Release(reader); + } + + IWICMetadataReaderInfo_Release(readerinfo); + + return ITER_SKIP; +} + +static enum iterator_result create_metadata_reader_iterator(IUnknown *item, + struct iterator_context *context) +{ + IWICPersistStream *persist_stream = NULL; + IWICMetadataReaderInfo *readerinfo; + IWICMetadataReader *reader = NULL; + LARGE_INTEGER zero = {{0}}; + HRESULT hr; + GUID guid; + + if (FAILED(IUnknown_QueryInterface(item, &IID_IWICMetadataReaderInfo, (void **)&readerinfo))) + return ITER_SKIP; + + if (context->vendor) + { + hr = IWICMetadataReaderInfo_GetVendorGUID(readerinfo, &guid); + + if (FAILED(hr) || !IsEqualIID(context->vendor, &guid)) + { + IWICMetadataReaderInfo_Release(readerinfo); + return ITER_SKIP; + } + } + + hr = IWICMetadataReaderInfo_GetMetadataFormat(readerinfo, &guid); + + if (FAILED(hr) || !IsEqualIID(context->format, &guid)) + { + IWICMetadataReaderInfo_Release(readerinfo); + return ITER_SKIP; + } + + if (SUCCEEDED(hr)) + hr = IWICMetadataReaderInfo_CreateInstance(readerinfo, &reader); + + IWICMetadataReaderInfo_Release(readerinfo); + + if (context->stream) + { + if (SUCCEEDED(hr)) + hr = IStream_Seek(context->stream, zero, STREAM_SEEK_SET, NULL); + + if (SUCCEEDED(hr)) + hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist_stream); + + if (SUCCEEDED(hr)) + hr = IWICPersistStream_LoadEx(persist_stream, context->stream, context->vendor, + context->options & WICPersistOptionMask); + + if (persist_stream) + IWICPersistStream_Release(persist_stream); + } + + if (SUCCEEDED(hr)) + { + *context->result = reader; + return ITER_DONE; + } + + if (reader) + IWICMetadataReader_Release(reader); + + return ITER_SKIP; +} + +static HRESULT foreach_component(DWORD mask, iterator_func func, struct iterator_context *context) +{ + enum iterator_result ret; + IEnumUnknown *enumerator; + IUnknown *item; + HRESULT hr; + + if (FAILED(hr = CreateComponentEnumerator(mask, WICComponentEnumerateDefault, &enumerator))) + return hr; + + while (IEnumUnknown_Next(enumerator, 1, &item, NULL) == S_OK) + { + *context->result = NULL; + + ret = func(item, context); + IUnknown_Release(item); + + if (ret == ITER_SKIP) + continue; + + break; + } + + IEnumUnknown_Release(enumerator); + + return *context->result ? S_OK : WINCODEC_ERR_COMPONENTNOTFOUND; +} + +static HRESULT create_unknown_metadata_reader(IStream *stream, DWORD options, IWICMetadataReader **reader) +{ + IWICPersistStream *persist_stream = NULL; + LARGE_INTEGER zero = {{0}}; + HRESULT hr; + + hr = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL); + + if (SUCCEEDED(hr)) + hr = UnknownMetadataReader_CreateInstance(&IID_IWICMetadataReader, (void **)reader); + + if (SUCCEEDED(hr)) + hr = IWICMetadataReader_QueryInterface(*reader, &IID_IWICPersistStream, (void **)&persist_stream); + + if (SUCCEEDED(hr)) + hr = IWICPersistStream_LoadEx(persist_stream, stream, NULL, options & WICPersistOptionMask); + + if (persist_stream) + IWICPersistStream_Release(persist_stream); + + if (FAILED(hr)) + { + IWICMetadataReader_Release(*reader); + *reader = NULL; + } + + return hr; +} + 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), + struct iterator_context context = { 0 }; + HRESULT hr; + + TRACE("%p,%s,%s,%lx,%p,%p\n", iface, debugstr_guid(format), debugstr_guid(vendor), options, stream, reader); - return E_NOTIMPL; + + if (!format || !reader) + return E_INVALIDARG; + + context.format = format; + context.vendor = vendor; + context.options = options; + context.stream = stream; + context.result = (void **)reader; + + hr = foreach_component(WICMetadataReader, create_metadata_reader_iterator, &context); + + if (FAILED(hr) && vendor) + { + context.vendor = NULL; + hr = foreach_component(WICMetadataReader, create_metadata_reader_iterator, &context); + } + + if (FAILED(hr)) + WARN("Failed to create a metadata reader instance, hr %#lx.\n", hr); + + if (!*reader && !(options & WICMetadataCreationFailUnknown)) + hr = create_unknown_metadata_reader(stream, options, reader); + + return *reader ? S_OK : WINCODEC_ERR_COMPONENTNOTFOUND; } static HRESULT WINAPI ComponentFactory_CreateMetadataReaderFromContainer(IWICComponentFactory *iface, REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader) { + struct iterator_context context = { 0 }; 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), + TRACE("%p,%s,%s,%lx,%p,%p\n", iface, debugstr_guid(format), debugstr_guid(vendor), options, stream, reader); if (!format || !stream || !reader) return E_INVALIDARG; - zero.QuadPart = 0; + context.format = format; + context.vendor = vendor; + context.options = options; + context.stream = stream; + context.result = (void **)reader; - hr = CreateComponentEnumerator(WICMetadataReader, WICComponentEnumerateDefault, &enumreaders); - if (FAILED(hr)) return hr; + hr = foreach_component(WICMetadataReader, create_metadata_reader_from_container_iterator, &context); - *reader = NULL; - -start: - while (!*reader) + if (FAILED(hr) && vendor) { - 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 & WICPersistOptionMask); - - IWICPersistStream_Release(wicpersiststream); - } - - if (FAILED(hr)) - { - IWICMetadataReader_Release(*reader); - *reader = NULL; - } - } - } - - IUnknown_Release(readerinfo); - } - - IUnknown_Release(unkreaderinfo); - } - else - break; + context.vendor = NULL; + hr = foreach_component(WICMetadataReader, create_metadata_reader_from_container_iterator, &context); } - if (!*reader && vendor) - { - vendor = NULL; - IEnumUnknown_Reset(enumreaders); - goto start; - } - - IEnumUnknown_Release(enumreaders); + if (FAILED(hr)) + WARN("Failed to create a metadata reader instance, hr %#lx.\n", hr); if (!*reader && !(options & WICMetadataCreationFailUnknown)) - { - hr = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL); + hr = create_unknown_metadata_reader(stream, options, reader); - if (SUCCEEDED(hr)) - hr = UnknownMetadataReader_CreateInstance(&IID_IWICMetadataReader, (void**)reader); - - if (SUCCEEDED(hr)) - { - hr = IWICMetadataReader_QueryInterface(*reader, &IID_IWICPersistStream, (void**)&wicpersiststream); - - if (SUCCEEDED(hr)) - { - hr = IWICPersistStream_LoadEx(wicpersiststream, stream, NULL, options & WICPersistOptionMask); - - IWICPersistStream_Release(wicpersiststream); - } - - if (FAILED(hr)) - { - IWICMetadataReader_Release(*reader); - *reader = NULL; - } - } - } - - if (*reader) - return S_OK; - else - return WINCODEC_ERR_COMPONENTNOTFOUND; + return *reader ? S_OK : WINCODEC_ERR_COMPONENTNOTFOUND; } static HRESULT WINAPI ComponentFactory_CreateMetadataWriter(IWICComponentFactory *iface, REFGUID format, const GUID *vendor, DWORD options, IWICMetadataWriter **writer) { - FIXME("%p,%s,%s,%x,%p: stub\n", iface, debugstr_guid(format), debugstr_guid(vendor), options, writer); + FIXME("%p,%s,%s,%lx,%p: stub\n", iface, debugstr_guid(format), debugstr_guid(vendor), options, writer); return E_NOTIMPL; } @@ -1418,8 +1550,12 @@ static HRESULT WINAPI ComponentFactory_CreateQueryReaderFromBlockReader(IWICComp static HRESULT WINAPI ComponentFactory_CreateQueryWriterFromBlockWriter(IWICComponentFactory *iface, IWICMetadataBlockWriter *block_writer, IWICMetadataQueryWriter **query_writer) { - FIXME("%p,%p,%p: stub\n", iface, block_writer, query_writer); - return E_NOTIMPL; + TRACE("%p,%p,%p\n", iface, block_writer, query_writer); + + if (!block_writer || !query_writer) + return E_INVALIDARG; + + return MetadataQueryWriter_CreateInstance(block_writer, NULL, query_writer); } static HRESULT WINAPI ComponentFactory_CreateEncoderPropertyBag(IWICComponentFactory *iface, @@ -1476,7 +1612,7 @@ HRESULT ImagingFactory_CreateInstance(REFIID iid, void** ppv) *ppv = NULL; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); + This = malloc(sizeof(*This)); if (!This) return E_OUTOFMEMORY; This->IWICImagingFactory2_iface.lpVtbl = &ImagingFactory_Vtbl; diff --git a/dll/win32/windowscodecs/info.c b/dll/win32/windowscodecs/info.c index 8c8157445f9..db091dfc1e2 100644 --- a/dll/win32/windowscodecs/info.c +++ b/dll/win32/windowscodecs/info.c @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -31,33 +29,11 @@ #include "wincodecs_private.h" #include "wine/debug.h" -#include "wine/unicode.h" #include "wine/list.h" #include "wine/rbtree.h" -#include "wine/heap.h" WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); -static const WCHAR mimetypes_valuename[] = {'M','i','m','e','T','y','p','e','s',0}; -static const WCHAR author_valuename[] = {'A','u','t','h','o','r',0}; -static const WCHAR friendlyname_valuename[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0}; -static const WCHAR pixelformats_keyname[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0}; -static const WCHAR formats_keyname[] = {'F','o','r','m','a','t','s',0}; -static const WCHAR containerformat_valuename[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0}; -static const WCHAR metadataformat_valuename[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0}; -static const WCHAR vendor_valuename[] = {'V','e','n','d','o','r',0}; -static const WCHAR version_valuename[] = {'V','e','r','s','i','o','n',0}; -static const WCHAR specversion_valuename[] = {'S','p','e','c','V','e','r','s','i','o','n',0}; -static const WCHAR bitsperpixel_valuename[] = {'B','i','t','L','e','n','g','t','h',0}; -static const WCHAR channelcount_valuename[] = {'C','h','a','n','n','e','l','C','o','u','n','t',0}; -static const WCHAR channelmasks_keyname[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0}; -static const WCHAR numericrepresentation_valuename[] = {'N','u','m','e','r','i','c','R','e','p','r','e','s','e','n','t','a','t','i','o','n',0}; -static const WCHAR supportstransparency_valuename[] = {'S','u','p','p','o','r','t','s','T','r','a','n','s','p','a','r','e','n','c','y',0}; -static const WCHAR requiresfullstream_valuename[] = {'R','e','q','u','i','r','e','s','F','u','l','l','S','t','r','e','a','m',0}; -static const WCHAR supportspadding_valuename[] = {'S','u','p','p','o','r','t','s','P','a','d','d','i','n','g',0}; -static const WCHAR fileextensions_valuename[] = {'F','i','l','e','E','x','t','e','n','s','i','o','n','s',0}; -static const WCHAR containers_keyname[] = {'C','o','n','t','a','i','n','e','r','s',0}; - typedef struct { IWICComponentInfo IWICComponentInfo_iface; LONG ref; @@ -74,8 +50,7 @@ static HRESULT ComponentInfo_GetStringValue(HKEY classkey, LPCWSTR value, if (!actual_size) return E_INVALIDARG; - ret = RegGetValueW(classkey, NULL, value, RRF_RT_REG_SZ|RRF_NOEXPAND, NULL, - buffer, &cbdata); + ret = RegQueryValueExW(classkey, value, 0, NULL, (void *)buffer, &cbdata); if (ret == ERROR_FILE_NOT_FOUND) { @@ -124,8 +99,8 @@ static HRESULT ComponentInfo_GetGUIDValue(HKEY classkey, LPCWSTR value, return hr; } -static HRESULT ComponentInfo_GetDWORDValue(HKEY classkey, LPCWSTR value, - DWORD *result) +static HRESULT ComponentInfo_GetUINTValue(HKEY classkey, LPCWSTR value, + void *result) { LONG ret; DWORD cbdata = sizeof(DWORD); @@ -138,7 +113,7 @@ static HRESULT ComponentInfo_GetDWORDValue(HKEY classkey, LPCWSTR value, if (ret == ERROR_FILE_NOT_FOUND) { - *result = 0; + *(UINT *)result = 0; return S_OK; } @@ -202,7 +177,7 @@ static HRESULT ComponentInfo_GetGuidList(HKEY classkey, LPCWSTR subkeyname, } else { - ret = RegQueryInfoKeyW(subkey, NULL, NULL, NULL, actual_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + ret = RegQueryInfoKeyW(subkey, NULL, NULL, NULL, (DWORD *)actual_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (ret != ERROR_SUCCESS) hr = HRESULT_FROM_WIN32(ret); } @@ -255,7 +230,7 @@ static ULONG WINAPI BitmapDecoderInfo_AddRef(IWICBitmapDecoderInfo *iface) BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); ULONG ref = InterlockedIncrement(&This->base.ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -265,13 +240,13 @@ static ULONG WINAPI BitmapDecoderInfo_Release(IWICBitmapDecoderInfo *iface) BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); ULONG ref = InterlockedDecrement(&This->base.ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { RegCloseKey(This->classkey); - heap_free(This->patterns); - HeapFree(GetProcessHeap(), 0, This); + free(This->patterns); + free(This); } return ref; @@ -311,8 +286,7 @@ static HRESULT WINAPI BitmapDecoderInfo_GetAuthor(IWICBitmapDecoderInfo *iface, TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, author_valuename, - cchAuthor, wzAuthor, pcchActual); + return ComponentInfo_GetStringValue(This->classkey, L"Author", cchAuthor, wzAuthor, pcchActual); } static HRESULT WINAPI BitmapDecoderInfo_GetVendorGUID(IWICBitmapDecoderInfo *iface, GUID *pguidVendor) @@ -321,7 +295,7 @@ static HRESULT WINAPI BitmapDecoderInfo_GetVendorGUID(IWICBitmapDecoderInfo *ifa TRACE("(%p,%p)\n", iface, pguidVendor); - return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor); + return ComponentInfo_GetGUIDValue(This->classkey, L"Vendor", pguidVendor); } static HRESULT WINAPI BitmapDecoderInfo_GetVersion(IWICBitmapDecoderInfo *iface, UINT cchVersion, @@ -331,7 +305,7 @@ static HRESULT WINAPI BitmapDecoderInfo_GetVersion(IWICBitmapDecoderInfo *iface, TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, version_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"Version", cchVersion, wzVersion, pcchActual); } @@ -342,7 +316,7 @@ static HRESULT WINAPI BitmapDecoderInfo_GetSpecVersion(IWICBitmapDecoderInfo *if TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, specversion_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"SpecVersion", cchSpecVersion, wzSpecVersion, pcchActual); } @@ -353,7 +327,7 @@ static HRESULT WINAPI BitmapDecoderInfo_GetFriendlyName(IWICBitmapDecoderInfo *i TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"FriendlyName", cchFriendlyName, wzFriendlyName, pcchActual); } @@ -362,7 +336,7 @@ static HRESULT WINAPI BitmapDecoderInfo_GetContainerFormat(IWICBitmapDecoderInfo { BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); TRACE("(%p,%p)\n", iface, pguidContainerFormat); - return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat); + return ComponentInfo_GetGUIDValue(This->classkey, L"ContainerFormat", pguidContainerFormat); } static HRESULT WINAPI BitmapDecoderInfo_GetPixelFormats(IWICBitmapDecoderInfo *iface, @@ -370,7 +344,7 @@ static HRESULT WINAPI BitmapDecoderInfo_GetPixelFormats(IWICBitmapDecoderInfo *i { BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface); TRACE("(%p,%u,%p,%p)\n", iface, cFormats, pguidPixelFormats, pcActual); - return ComponentInfo_GetGuidList(This->classkey, formats_keyname, cFormats, pguidPixelFormats, pcActual); + return ComponentInfo_GetGuidList(This->classkey, L"Formats", cFormats, pguidPixelFormats, pcActual); } static HRESULT WINAPI BitmapDecoderInfo_GetColorManagementVersion(IWICBitmapDecoderInfo *iface, @@ -401,7 +375,7 @@ static HRESULT WINAPI BitmapDecoderInfo_GetMimeTypes(IWICBitmapDecoderInfo *ifac TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"MimeTypes", cchMimeTypes, wzMimeTypes, pcchActual); } @@ -412,7 +386,7 @@ static HRESULT WINAPI BitmapDecoderInfo_GetFileExtensions(IWICBitmapDecoderInfo TRACE("(%p,%u,%p,%p)\n", iface, cchFileExtensions, wzFileExtensions, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, fileextensions_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"FileExtensions", cchFileExtensions, wzFileExtensions, pcchActual); } @@ -489,9 +463,9 @@ static HRESULT WINAPI BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo *if { if (datasize < This->patterns[i].Length) { - HeapFree(GetProcessHeap(), 0, data); + free(data); datasize = This->patterns[i].Length; - data = HeapAlloc(GetProcessHeap(), 0, This->patterns[i].Length); + data = malloc(This->patterns[i].Length); if (!data) { hr = E_OUTOFMEMORY; @@ -531,7 +505,7 @@ static HRESULT WINAPI BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo *if *pfMatches = FALSE; } - HeapFree(GetProcessHeap(), 0, data); + free(data); return hr; } @@ -576,23 +550,17 @@ static const IWICBitmapDecoderInfoVtbl BitmapDecoderInfo_Vtbl = { static void read_bitmap_patterns(BitmapDecoderInfo *info) { - UINT pattern_count=0, patterns_size=0; + DWORD pattern_count=0; + UINT patterns_size=0; WCHAR subkeyname[11]; LONG res; HKEY patternskey, patternkey; - static const WCHAR uintformatW[] = {'%','u',0}; - static const WCHAR patternsW[] = {'P','a','t','t','e','r','n','s',0}; - static const WCHAR positionW[] = {'P','o','s','i','t','i','o','n',0}; - static const WCHAR lengthW[] = {'L','e','n','g','t','h',0}; - static const WCHAR patternW[] = {'P','a','t','t','e','r','n',0}; - static const WCHAR maskW[] = {'M','a','s','k',0}; - static const WCHAR endofstreamW[] = {'E','n','d','O','f','S','t','r','e','a','m',0}; UINT i; WICBitmapPattern *patterns; BYTE *patterns_ptr; DWORD length, valuesize; - res = RegOpenKeyExW(info->classkey, patternsW, 0, KEY_READ, &patternskey); + res = RegOpenKeyExW(info->classkey, L"Patterns", 0, KEY_READ, &patternskey); if (res != ERROR_SUCCESS) return; res = RegQueryInfoKeyW(patternskey, NULL, NULL, NULL, &pattern_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL); @@ -603,7 +571,7 @@ static void read_bitmap_patterns(BitmapDecoderInfo *info) } patterns_size = pattern_count * sizeof(WICBitmapPattern); - patterns = heap_alloc(patterns_size); + patterns = malloc(patterns_size); if (!patterns) { RegCloseKey(patternskey); @@ -612,34 +580,34 @@ static void read_bitmap_patterns(BitmapDecoderInfo *info) for (i=0; res == ERROR_SUCCESS && i < pattern_count; i++) { - snprintfW(subkeyname, 11, uintformatW, i); + swprintf(subkeyname, 11, L"%u", i); res = RegOpenKeyExW(patternskey, subkeyname, 0, KEY_READ, &patternkey); if (res != ERROR_SUCCESS) break; valuesize = sizeof(ULONG); - res = RegGetValueW(patternkey, NULL, lengthW, RRF_RT_DWORD, NULL, &length, &valuesize); + res = RegGetValueW(patternkey, NULL, L"Length", RRF_RT_DWORD, NULL, &length, &valuesize); if (res == ERROR_SUCCESS) { patterns_size += length*2; patterns[i].Length = length; valuesize = sizeof(BOOL); - res = RegGetValueW(patternkey, NULL, endofstreamW, RRF_RT_DWORD, NULL, + res = RegGetValueW(patternkey, NULL, L"EndOfStream", RRF_RT_DWORD, NULL, &patterns[i].EndOfStream, &valuesize); if (res) patterns[i].EndOfStream = 0; patterns[i].Position.QuadPart = 0; valuesize = sizeof(ULARGE_INTEGER); - res = RegGetValueW(patternkey, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD, NULL, + res = RegGetValueW(patternkey, NULL, L"Position", RRF_RT_DWORD|RRF_RT_QWORD, NULL, &patterns[i].Position, &valuesize); } RegCloseKey(patternkey); } - if (res != ERROR_SUCCESS || !(patterns_ptr = heap_realloc(patterns, patterns_size))) + if (res != ERROR_SUCCESS || !(patterns_ptr = realloc(patterns, patterns_size))) { - heap_free(patterns); + free(patterns); RegCloseKey(patternskey); return; } @@ -648,14 +616,14 @@ static void read_bitmap_patterns(BitmapDecoderInfo *info) for (i=0; res == ERROR_SUCCESS && i < pattern_count; i++) { - snprintfW(subkeyname, 11, uintformatW, i); + swprintf(subkeyname, 11, L"%u", i); res = RegOpenKeyExW(patternskey, subkeyname, 0, KEY_READ, &patternkey); if (res != ERROR_SUCCESS) break; length = patterns[i].Length; patterns[i].Pattern = patterns_ptr; valuesize = length; - res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY, NULL, + res = RegGetValueW(patternkey, NULL, L"Pattern", RRF_RT_REG_BINARY, NULL, patterns[i].Pattern, &valuesize); patterns_ptr += length; @@ -663,7 +631,7 @@ static void read_bitmap_patterns(BitmapDecoderInfo *info) { patterns[i].Mask = patterns_ptr; valuesize = length; - res = RegGetValueW(patternkey, NULL, maskW, RRF_RT_REG_BINARY, NULL, + res = RegGetValueW(patternkey, NULL, L"Mask", RRF_RT_REG_BINARY, NULL, patterns[i].Mask, &valuesize); patterns_ptr += length; } @@ -675,7 +643,7 @@ static void read_bitmap_patterns(BitmapDecoderInfo *info) if (res != ERROR_SUCCESS) { - heap_free(patterns); + free(patterns); return; } @@ -688,7 +656,7 @@ static HRESULT BitmapDecoderInfo_Constructor(HKEY classkey, REFCLSID clsid, Comp { BitmapDecoderInfo *This; - This = heap_alloc_zero(sizeof(BitmapDecoderInfo)); + This = calloc(1, sizeof(BitmapDecoderInfo)); if (!This) { RegCloseKey(classkey); @@ -746,7 +714,7 @@ static ULONG WINAPI BitmapEncoderInfo_AddRef(IWICBitmapEncoderInfo *iface) BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); ULONG ref = InterlockedIncrement(&This->base.ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -756,12 +724,12 @@ static ULONG WINAPI BitmapEncoderInfo_Release(IWICBitmapEncoderInfo *iface) BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); ULONG ref = InterlockedDecrement(&This->base.ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { RegCloseKey(This->classkey); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -801,8 +769,7 @@ static HRESULT WINAPI BitmapEncoderInfo_GetAuthor(IWICBitmapEncoderInfo *iface, TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, author_valuename, - cchAuthor, wzAuthor, pcchActual); + return ComponentInfo_GetStringValue(This->classkey, L"Author", cchAuthor, wzAuthor, pcchActual); } static HRESULT WINAPI BitmapEncoderInfo_GetVendorGUID(IWICBitmapEncoderInfo *iface, GUID *pguidVendor) @@ -811,7 +778,7 @@ static HRESULT WINAPI BitmapEncoderInfo_GetVendorGUID(IWICBitmapEncoderInfo *ifa TRACE("(%p,%p)\n", iface, pguidVendor); - return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor); + return ComponentInfo_GetGUIDValue(This->classkey, L"Vendor", pguidVendor); } static HRESULT WINAPI BitmapEncoderInfo_GetVersion(IWICBitmapEncoderInfo *iface, UINT cchVersion, @@ -821,7 +788,7 @@ static HRESULT WINAPI BitmapEncoderInfo_GetVersion(IWICBitmapEncoderInfo *iface, TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, version_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"Version", cchVersion, wzVersion, pcchActual); } @@ -832,7 +799,7 @@ static HRESULT WINAPI BitmapEncoderInfo_GetSpecVersion(IWICBitmapEncoderInfo *if TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, specversion_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"SpecVersion", cchSpecVersion, wzSpecVersion, pcchActual); } @@ -843,7 +810,7 @@ static HRESULT WINAPI BitmapEncoderInfo_GetFriendlyName(IWICBitmapEncoderInfo *i TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"FriendlyName", cchFriendlyName, wzFriendlyName, pcchActual); } @@ -852,7 +819,7 @@ static HRESULT WINAPI BitmapEncoderInfo_GetContainerFormat(IWICBitmapEncoderInfo { BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); TRACE("(%p,%p)\n", iface, pguidContainerFormat); - return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat); + return ComponentInfo_GetGUIDValue(This->classkey, L"ContainerFormat", pguidContainerFormat); } static HRESULT WINAPI BitmapEncoderInfo_GetPixelFormats(IWICBitmapEncoderInfo *iface, @@ -860,7 +827,7 @@ static HRESULT WINAPI BitmapEncoderInfo_GetPixelFormats(IWICBitmapEncoderInfo *i { BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface); TRACE("(%p,%u,%p,%p)\n", iface, cFormats, pguidPixelFormats, pcActual); - return ComponentInfo_GetGuidList(This->classkey, formats_keyname, cFormats, pguidPixelFormats, pcActual); + return ComponentInfo_GetGuidList(This->classkey, L"Formats", cFormats, pguidPixelFormats, pcActual); } static HRESULT WINAPI BitmapEncoderInfo_GetColorManagementVersion(IWICBitmapEncoderInfo *iface, @@ -891,7 +858,7 @@ static HRESULT WINAPI BitmapEncoderInfo_GetMimeTypes(IWICBitmapEncoderInfo *ifac TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"MimeTypes", cchMimeTypes, wzMimeTypes, pcchActual); } @@ -902,7 +869,7 @@ static HRESULT WINAPI BitmapEncoderInfo_GetFileExtensions(IWICBitmapEncoderInfo TRACE("(%p,%u,%p,%p)\n", iface, cchFileExtensions, wzFileExtensions, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, fileextensions_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"FileExtensions", cchFileExtensions, wzFileExtensions, pcchActual); } @@ -982,7 +949,7 @@ static HRESULT BitmapEncoderInfo_Constructor(HKEY classkey, REFCLSID clsid, Comp { BitmapEncoderInfo *This; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapEncoderInfo)); + This = malloc(sizeof(BitmapEncoderInfo)); if (!This) { RegCloseKey(classkey); @@ -1037,7 +1004,7 @@ static ULONG WINAPI FormatConverterInfo_AddRef(IWICFormatConverterInfo *iface) FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface); ULONG ref = InterlockedIncrement(&This->base.ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -1047,12 +1014,12 @@ static ULONG WINAPI FormatConverterInfo_Release(IWICFormatConverterInfo *iface) FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface); ULONG ref = InterlockedDecrement(&This->base.ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { RegCloseKey(This->classkey); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -1092,8 +1059,7 @@ static HRESULT WINAPI FormatConverterInfo_GetAuthor(IWICFormatConverterInfo *ifa TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, author_valuename, - cchAuthor, wzAuthor, pcchActual); + return ComponentInfo_GetStringValue(This->classkey, L"Author", cchAuthor, wzAuthor, pcchActual); } static HRESULT WINAPI FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo *iface, GUID *pguidVendor) @@ -1102,7 +1068,7 @@ static HRESULT WINAPI FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo TRACE("(%p,%p)\n", iface, pguidVendor); - return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor); + return ComponentInfo_GetGUIDValue(This->classkey, L"Vendor", pguidVendor); } static HRESULT WINAPI FormatConverterInfo_GetVersion(IWICFormatConverterInfo *iface, UINT cchVersion, @@ -1112,7 +1078,7 @@ static HRESULT WINAPI FormatConverterInfo_GetVersion(IWICFormatConverterInfo *if TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, version_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"Version", cchVersion, wzVersion, pcchActual); } @@ -1123,7 +1089,7 @@ static HRESULT WINAPI FormatConverterInfo_GetSpecVersion(IWICFormatConverterInfo TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, specversion_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"SpecVersion", cchSpecVersion, wzSpecVersion, pcchActual); } @@ -1134,7 +1100,7 @@ static HRESULT WINAPI FormatConverterInfo_GetFriendlyName(IWICFormatConverterInf TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"FriendlyName", cchFriendlyName, wzFriendlyName, pcchActual); } @@ -1165,7 +1131,7 @@ static BOOL ConverterSupportsFormat(IWICFormatConverterInfo *iface, const WCHAR /* Avoid testing using IWICFormatConverter_GetPixelFormats because that would be O(n). A registry test should do better. */ - res = RegOpenKeyExW(This->classkey, pixelformats_keyname, 0, KEY_READ, &formats_key); + res = RegOpenKeyExW(This->classkey, L"PixelFormats", 0, KEY_READ, &formats_key); if (res != ERROR_SUCCESS) return FALSE; res = RegOpenKeyExW(formats_key, formatguid, 0, KEY_READ, &guid_key); @@ -1196,7 +1162,7 @@ static HRESULT FormatConverterInfo_Constructor(HKEY classkey, REFCLSID clsid, Co { FormatConverterInfo *This; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverterInfo)); + This = malloc(sizeof(FormatConverterInfo)); if (!This) { RegCloseKey(classkey); @@ -1252,7 +1218,7 @@ static ULONG WINAPI PixelFormatInfo_AddRef(IWICPixelFormatInfo2 *iface) PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface); ULONG ref = InterlockedIncrement(&This->base.ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -1262,12 +1228,12 @@ static ULONG WINAPI PixelFormatInfo_Release(IWICPixelFormatInfo2 *iface) PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface); ULONG ref = InterlockedDecrement(&This->base.ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { RegCloseKey(This->classkey); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -1314,8 +1280,7 @@ static HRESULT WINAPI PixelFormatInfo_GetAuthor(IWICPixelFormatInfo2 *iface, UIN TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, author_valuename, - cchAuthor, wzAuthor, pcchActual); + return ComponentInfo_GetStringValue(This->classkey, L"Author", cchAuthor, wzAuthor, pcchActual); } static HRESULT WINAPI PixelFormatInfo_GetVendorGUID(IWICPixelFormatInfo2 *iface, GUID *pguidVendor) @@ -1324,7 +1289,7 @@ static HRESULT WINAPI PixelFormatInfo_GetVendorGUID(IWICPixelFormatInfo2 *iface, TRACE("(%p,%p)\n", iface, pguidVendor); - return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor); + return ComponentInfo_GetGUIDValue(This->classkey, L"Vendor", pguidVendor); } static HRESULT WINAPI PixelFormatInfo_GetVersion(IWICPixelFormatInfo2 *iface, UINT cchVersion, @@ -1334,7 +1299,7 @@ static HRESULT WINAPI PixelFormatInfo_GetVersion(IWICPixelFormatInfo2 *iface, UI TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, version_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"Version", cchVersion, wzVersion, pcchActual); } @@ -1345,7 +1310,7 @@ static HRESULT WINAPI PixelFormatInfo_GetSpecVersion(IWICPixelFormatInfo2 *iface TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, specversion_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"SpecVersion", cchSpecVersion, wzSpecVersion, pcchActual); } @@ -1356,7 +1321,7 @@ static HRESULT WINAPI PixelFormatInfo_GetFriendlyName(IWICPixelFormatInfo2 *ifac TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual); - return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"FriendlyName", cchFriendlyName, wzFriendlyName, pcchActual); } @@ -1387,7 +1352,7 @@ static HRESULT WINAPI PixelFormatInfo_GetBitsPerPixel(IWICPixelFormatInfo2 *ifac TRACE("(%p,%p)\n", iface, puiBitsPerPixel); - return ComponentInfo_GetDWORDValue(This->classkey, bitsperpixel_valuename, puiBitsPerPixel); + return ComponentInfo_GetUINTValue(This->classkey, L"BitLength", puiBitsPerPixel); } static HRESULT WINAPI PixelFormatInfo_GetChannelCount(IWICPixelFormatInfo2 *iface, @@ -1397,13 +1362,12 @@ static HRESULT WINAPI PixelFormatInfo_GetChannelCount(IWICPixelFormatInfo2 *ifac TRACE("(%p,%p)\n", iface, puiChannelCount); - return ComponentInfo_GetDWORDValue(This->classkey, channelcount_valuename, puiChannelCount); + return ComponentInfo_GetUINTValue(This->classkey, L"ChannelCount", puiChannelCount); } static HRESULT WINAPI PixelFormatInfo_GetChannelMask(IWICPixelFormatInfo2 *iface, UINT uiChannelIndex, UINT cbMaskBuffer, BYTE *pbMaskBuffer, UINT *pcbActual) { - static const WCHAR uintformatW[] = {'%','u',0}; PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface); UINT channel_count; HRESULT hr; @@ -1423,11 +1387,11 @@ static HRESULT WINAPI PixelFormatInfo_GetChannelMask(IWICPixelFormatInfo2 *iface if (SUCCEEDED(hr)) { - snprintfW(valuename, 11, uintformatW, uiChannelIndex); + swprintf(valuename, 11, L"%u", uiChannelIndex); cbData = cbMaskBuffer; - ret = RegGetValueW(This->classkey, channelmasks_keyname, valuename, RRF_RT_REG_BINARY, NULL, pbMaskBuffer, &cbData); + ret = RegGetValueW(This->classkey, L"ChannelMasks", valuename, RRF_RT_REG_BINARY, NULL, pbMaskBuffer, &cbData); if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) *pcbActual = cbData; @@ -1448,7 +1412,7 @@ static HRESULT WINAPI PixelFormatInfo_SupportsTransparency(IWICPixelFormatInfo2 TRACE("(%p,%p)\n", iface, pfSupportsTransparency); - return ComponentInfo_GetDWORDValue(This->classkey, supportstransparency_valuename, (DWORD*)pfSupportsTransparency); + return ComponentInfo_GetUINTValue(This->classkey, L"SupportsTransparency", pfSupportsTransparency); } static HRESULT WINAPI PixelFormatInfo_GetNumericRepresentation(IWICPixelFormatInfo2 *iface, @@ -1458,7 +1422,7 @@ static HRESULT WINAPI PixelFormatInfo_GetNumericRepresentation(IWICPixelFormatIn TRACE("(%p,%p)\n", iface, pNumericRepresentation); - return ComponentInfo_GetDWORDValue(This->classkey, numericrepresentation_valuename, pNumericRepresentation); + return ComponentInfo_GetUINTValue(This->classkey, L"NumericRepresentation", pNumericRepresentation); } static const IWICPixelFormatInfo2Vtbl PixelFormatInfo_Vtbl = { @@ -1486,7 +1450,7 @@ static HRESULT PixelFormatInfo_Constructor(HKEY classkey, REFCLSID clsid, Compon { PixelFormatInfo *This; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(PixelFormatInfo)); + This = malloc(sizeof(PixelFormatInfo)); if (!This) { RegCloseKey(classkey); @@ -1565,7 +1529,7 @@ static ULONG WINAPI MetadataReaderInfo_AddRef(IWICMetadataReaderInfo *iface) MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); ULONG ref = InterlockedIncrement(&This->base.ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -1574,17 +1538,17 @@ static ULONG WINAPI MetadataReaderInfo_Release(IWICMetadataReaderInfo *iface) MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); ULONG ref = InterlockedDecrement(&This->base.ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (!ref) { unsigned i; RegCloseKey(This->classkey); for (i = 0; i < This->container_count; i++) - heap_free(This->containers[i].patterns); - heap_free(This->containers); - heap_free(This->container_formats); - HeapFree(GetProcessHeap(), 0, This); + free(This->containers[i].patterns); + free(This->containers); + free(This->container_formats); + free(This); } return ref; } @@ -1625,8 +1589,7 @@ static HRESULT WINAPI MetadataReaderInfo_GetAuthor(IWICMetadataReaderInfo *iface TRACE("(%p,%u,%p,%p)\n", iface, length, author, actual_length); - return ComponentInfo_GetStringValue(This->classkey, author_valuename, - length, author, actual_length); + return ComponentInfo_GetStringValue(This->classkey, L"Author", length, author, actual_length); } static HRESULT WINAPI MetadataReaderInfo_GetVendorGUID(IWICMetadataReaderInfo *iface, @@ -1636,7 +1599,7 @@ static HRESULT WINAPI MetadataReaderInfo_GetVendorGUID(IWICMetadataReaderInfo *i TRACE("(%p,%p)\n", iface, vendor); - return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, vendor); + return ComponentInfo_GetGUIDValue(This->classkey, L"Vendor", vendor); } static HRESULT WINAPI MetadataReaderInfo_GetVersion(IWICMetadataReaderInfo *iface, @@ -1646,8 +1609,7 @@ static HRESULT WINAPI MetadataReaderInfo_GetVersion(IWICMetadataReaderInfo *ifac TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length); - return ComponentInfo_GetStringValue(This->classkey, version_valuename, - length, version, actual_length); + return ComponentInfo_GetStringValue(This->classkey, L"Version", length, version, actual_length); } static HRESULT WINAPI MetadataReaderInfo_GetSpecVersion(IWICMetadataReaderInfo *iface, @@ -1657,7 +1619,7 @@ static HRESULT WINAPI MetadataReaderInfo_GetSpecVersion(IWICMetadataReaderInfo * TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length); - return ComponentInfo_GetStringValue(This->classkey, specversion_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"SpecVersion", length, version, actual_length); } @@ -1668,7 +1630,7 @@ static HRESULT WINAPI MetadataReaderInfo_GetFriendlyName(IWICMetadataReaderInfo TRACE("(%p,%u,%p,%p)\n", iface, length, name, actual_length); - return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename, + return ComponentInfo_GetStringValue(This->classkey, L"FriendlyName", length, name, actual_length); } @@ -1677,7 +1639,7 @@ static HRESULT WINAPI MetadataReaderInfo_GetMetadataFormat(IWICMetadataReaderInf { MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); TRACE("(%p,%p)\n", iface, format); - return ComponentInfo_GetGUIDValue(This->classkey, metadataformat_valuename, format); + return ComponentInfo_GetGUIDValue(This->classkey, L"MetadataFormat", format); } static HRESULT WINAPI MetadataReaderInfo_GetContainerFormats(IWICMetadataReaderInfo *iface, @@ -1695,7 +1657,7 @@ static HRESULT WINAPI MetadataReaderInfo_GetContainerFormats(IWICMetadataReaderI { if (This->container_count && length < This->container_count) return WINCODEC_ERR_INSUFFICIENTBUFFER; - memcpy(formats, This->container_formats, This->container_count); + memcpy(formats, This->container_formats, This->container_count * sizeof(*formats)); } return S_OK; } @@ -1719,7 +1681,7 @@ static HRESULT WINAPI MetadataReaderInfo_DoesRequireFullStream(IWICMetadataReade { MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); TRACE("(%p,%p)\n", iface, param); - return ComponentInfo_GetDWORDValue(This->classkey, requiresfullstream_valuename, (DWORD *)param); + return ComponentInfo_GetUINTValue(This->classkey, L"RequiresFullStream", param); } static HRESULT WINAPI MetadataReaderInfo_DoesSupportPadding(IWICMetadataReaderInfo *iface, @@ -1727,7 +1689,7 @@ static HRESULT WINAPI MetadataReaderInfo_DoesSupportPadding(IWICMetadataReaderIn { MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface); TRACE("(%p,%p)\n", iface, param); - return ComponentInfo_GetDWORDValue(This->classkey, supportspadding_valuename, (DWORD *)param); + return ComponentInfo_GetUINTValue(This->classkey, L"SupportsPadding", param); } static HRESULT WINAPI MetadataReaderInfo_DoesRequireFixedSize(IWICMetadataReaderInfo *iface, @@ -1783,9 +1745,9 @@ static HRESULT WINAPI MetadataReaderInfo_MatchesPattern(IWICMetadataReaderInfo * { if (datasize < container->patterns[i].Length) { - HeapFree(GetProcessHeap(), 0, data); + free(data); datasize = container->patterns[i].Length; - data = HeapAlloc(GetProcessHeap(), 0, container->patterns[i].Length); + data = malloc(container->patterns[i].Length); if (!data) { hr = E_OUTOFMEMORY; @@ -1821,7 +1783,7 @@ static HRESULT WINAPI MetadataReaderInfo_MatchesPattern(IWICMetadataReaderInfo * *matches = FALSE; } - HeapFree(GetProcessHeap(), 0, data); + free(data); return hr; } @@ -1863,21 +1825,17 @@ static const IWICMetadataReaderInfoVtbl MetadataReaderInfo_Vtbl = { static void read_metadata_patterns(MetadataReaderInfo *info, GUID *container_guid, struct metadata_container *container) { - UINT pattern_count=0, patterns_size=0; + DWORD pattern_count=0; + UINT patterns_size=0; WCHAR subkeyname[11], guidkeyname[39]; LONG res; HKEY containers_key, guid_key, patternkey; - static const WCHAR uintformatW[] = {'%','u',0}; - static const WCHAR patternW[] = {'P','a','t','t','e','r','n',0}; - static const WCHAR positionW[] = {'P','o','s','i','t','i','o','n',0}; - static const WCHAR maskW[] = {'M','a','s','k',0}; - static const WCHAR dataoffsetW[] = {'D','a','t','a','O','f','f','s','e','t',0}; UINT i; WICMetadataPattern *patterns; BYTE *patterns_ptr; DWORD length, valuesize; - res = RegOpenKeyExW(info->classkey, containers_keyname, 0, KEY_READ, &containers_key); + res = RegOpenKeyExW(info->classkey, L"Containers", 0, KEY_READ, &containers_key); if (res != ERROR_SUCCESS) return; StringFromGUID2(container_guid, guidkeyname, 39); @@ -1894,7 +1852,7 @@ static void read_metadata_patterns(MetadataReaderInfo *info, GUID *container_gui } patterns_size = pattern_count * sizeof(WICMetadataPattern); - patterns = heap_alloc(patterns_size); + patterns = malloc(patterns_size); if (!patterns) { RegCloseKey(guid_key); @@ -1903,33 +1861,33 @@ static void read_metadata_patterns(MetadataReaderInfo *info, GUID *container_gui for (i=0; res == ERROR_SUCCESS && i < pattern_count; i++) { - snprintfW(subkeyname, 11, uintformatW, i); + swprintf(subkeyname, 11, L"%u", i); res = RegOpenKeyExW(guid_key, subkeyname, 0, KEY_READ, &patternkey); if (res != ERROR_SUCCESS) break; - res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY, NULL, NULL, &length); + res = RegGetValueW(patternkey, NULL, L"Pattern", RRF_RT_REG_BINARY, NULL, NULL, &length); if (res == ERROR_SUCCESS) { patterns_size += length*2; patterns[i].Length = length; valuesize = sizeof(DWORD64); - res = RegGetValueW(patternkey, NULL, dataoffsetW, RRF_RT_DWORD|RRF_RT_QWORD, NULL, + res = RegGetValueW(patternkey, NULL, L"DataOffset", RRF_RT_DWORD|RRF_RT_QWORD, NULL, &patterns[i].DataOffset, &valuesize); if (res) patterns[i].DataOffset.QuadPart = 0; patterns[i].Position.QuadPart = 0; valuesize = sizeof(DWORD64); - res = RegGetValueW(patternkey, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD, NULL, + res = RegGetValueW(patternkey, NULL, L"Position", RRF_RT_DWORD|RRF_RT_QWORD, NULL, &patterns[i].Position, &valuesize); } RegCloseKey(patternkey); } - if (res != ERROR_SUCCESS || !(patterns_ptr = heap_realloc(patterns, patterns_size))) + if (res != ERROR_SUCCESS || !(patterns_ptr = realloc(patterns, patterns_size))) { - heap_free(patterns); + free(patterns); RegCloseKey(guid_key); return; } @@ -1938,14 +1896,14 @@ static void read_metadata_patterns(MetadataReaderInfo *info, GUID *container_gui for (i=0; res == ERROR_SUCCESS && i < pattern_count; i++) { - snprintfW(subkeyname, 11, uintformatW, i); + swprintf(subkeyname, 11, L"%u", i); res = RegOpenKeyExW(guid_key, subkeyname, 0, KEY_READ, &patternkey); if (res != ERROR_SUCCESS) break; length = patterns[i].Length; patterns[i].Pattern = patterns_ptr; valuesize = length; - res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY, NULL, + res = RegGetValueW(patternkey, NULL, L"Pattern", RRF_RT_REG_BINARY, NULL, patterns[i].Pattern, &valuesize); patterns_ptr += length; @@ -1953,7 +1911,7 @@ static void read_metadata_patterns(MetadataReaderInfo *info, GUID *container_gui { patterns[i].Mask = patterns_ptr; valuesize = length; - res = RegGetValueW(patternkey, NULL, maskW, RRF_RT_REG_BINARY, NULL, + res = RegGetValueW(patternkey, NULL, L"Mask", RRF_RT_REG_BINARY, NULL, patterns[i].Mask, &valuesize); patterns_ptr += length; } @@ -1965,7 +1923,7 @@ static void read_metadata_patterns(MetadataReaderInfo *info, GUID *container_gui if (res != ERROR_SUCCESS) { - heap_free(patterns); + free(patterns); return; } @@ -1980,17 +1938,17 @@ static BOOL read_metadata_info(MetadataReaderInfo *info) GUID *formats; HRESULT hr; - hr = ComponentInfo_GetGuidList(info->classkey, containers_keyname, 0, NULL, &format_count); + hr = ComponentInfo_GetGuidList(info->classkey, L"Containers", 0, NULL, &format_count); if (FAILED(hr)) return TRUE; - formats = heap_calloc(format_count, sizeof(*formats)); + formats = calloc(format_count, sizeof(*formats)); if (!formats) return FALSE; - hr = ComponentInfo_GetGuidList(info->classkey, containers_keyname, format_count, formats, + hr = ComponentInfo_GetGuidList(info->classkey, L"Containers", format_count, formats, &format_count); if (FAILED(hr)) { - heap_free(formats); + free(formats); return FALSE; } @@ -2001,7 +1959,7 @@ static BOOL read_metadata_info(MetadataReaderInfo *info) { unsigned i; - info->containers = heap_calloc(format_count, sizeof(*info->containers)); + info->containers = calloc(format_count, sizeof(*info->containers)); if (!info->containers) return FALSE; for (i = 0; i < format_count; i++) @@ -2015,7 +1973,7 @@ static HRESULT MetadataReaderInfo_Constructor(HKEY classkey, REFCLSID clsid, Com { MetadataReaderInfo *This; - This = heap_alloc_zero(sizeof(*This)); + This = calloc(1, sizeof(*This)); if (!This) { RegCloseKey(classkey); @@ -2037,9 +1995,6 @@ static HRESULT MetadataReaderInfo_Constructor(HKEY classkey, REFCLSID clsid, Com return S_OK; } -static const WCHAR clsid_keyname[] = {'C','L','S','I','D',0}; -static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0}; - struct category { WICComponentType type; const GUID *catid; @@ -2097,7 +2052,7 @@ HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo) return S_OK; } - res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey); + res = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"CLSID", 0, KEY_READ, &clsidkey); if (res != ERROR_SUCCESS) { LeaveCriticalSection(&component_info_cache_cs); @@ -2110,7 +2065,7 @@ HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo) res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey); if (res == ERROR_SUCCESS) { - res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey); + res = RegOpenKeyExW(catidkey, L"Instance", 0, KEY_READ, &instancekey); if (res == ERROR_SUCCESS) { StringFromGUID2(clsid, guidstring, 39); @@ -2223,7 +2178,7 @@ static ULONG WINAPI ComponentEnum_AddRef(IEnumUnknown *iface) ComponentEnum *This = impl_from_IEnumUnknown(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -2234,7 +2189,7 @@ static ULONG WINAPI ComponentEnum_Release(IEnumUnknown *iface) ULONG ref = InterlockedDecrement(&This->ref); ComponentEnumItem *cursor, *cursor2; - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { @@ -2242,11 +2197,11 @@ static ULONG WINAPI ComponentEnum_Release(IEnumUnknown *iface) { IUnknown_Release(cursor->unk); list_remove(&cursor->entry); - HeapFree(GetProcessHeap(), 0, cursor); + free(cursor); } This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -2260,7 +2215,7 @@ static HRESULT WINAPI ComponentEnum_Next(IEnumUnknown *iface, ULONG celt, ComponentEnumItem *item; HRESULT hr=S_OK; - TRACE("(%p,%u,%p,%p)\n", iface, celt, rgelt, pceltFetched); + TRACE("(%p,%lu,%p,%p)\n", iface, celt, rgelt, pceltFetched); EnterCriticalSection(&This->lock); while (num_fetchedlock); for (i=0; iref = 1; new_enum->cursor = NULL; list_init(&new_enum->objects); +#ifdef __REACTOS__ InitializeCriticalSection(&new_enum->lock); +#else + InitializeCriticalSectionEx(&new_enum->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif new_enum->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock"); EnterCriticalSection(&This->lock); @@ -2344,7 +2303,7 @@ static HRESULT WINAPI ComponentEnum_Clone(IEnumUnknown *iface, IEnumUnknown **pp LIST_FOR_EACH_ENTRY(old_item, &This->objects, ComponentEnumItem, entry) { - new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem)); + new_item = malloc(sizeof(ComponentEnumItem)); if (!new_item) { ret = E_OUTOFMEMORY; @@ -2389,13 +2348,13 @@ HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnkn HRESULT hr=S_OK; CLSID clsid; - if (options) FIXME("ignoring flags %x\n", options); + if (options) FIXME("ignoring flags %lx\n", options); - res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey); + res = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"CLSID", 0, KEY_READ, &clsidkey); if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res); - This = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum)); + This = malloc(sizeof(ComponentEnum)); if (!This) { RegCloseKey(clsidkey); @@ -2405,7 +2364,11 @@ HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnkn This->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl; This->ref = 1; list_init(&This->objects); +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock"); for (category=categories; category->type && hr == S_OK; category++) @@ -2415,7 +2378,7 @@ HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnkn res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey); if (res == ERROR_SUCCESS) { - res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey); + res = RegOpenKeyExW(catidkey, L"Instance", 0, KEY_READ, &instancekey); if (res == ERROR_SUCCESS) { i=0; @@ -2425,7 +2388,7 @@ HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnkn res = RegEnumKeyExW(instancekey, i, guidstring, &guidstring_size, NULL, NULL, NULL, NULL); if (res != ERROR_SUCCESS) break; - item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem)); + item = malloc(sizeof(ComponentEnumItem)); if (!item) { hr = E_OUTOFMEMORY; break; } hr = CLSIDFromString(guidstring, &clsid); @@ -2438,7 +2401,7 @@ HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnkn if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, item); + free(item); hr = S_OK; } } diff --git a/dll/win32/windowscodecs/jpegformat.c b/dll/win32/windowscodecs/jpegformat.c deleted file mode 100644 index 1df898f28c7..00000000000 --- a/dll/win32/windowscodecs/jpegformat.c +++ /dev/null @@ -1,1562 +0,0 @@ -/* - * Copyright 2009 Vincent Povirk for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#ifdef HAVE_UNISTD_H -# include -#endif -#include -#include -#include -#include - -#ifdef SONAME_LIBJPEG -/* This is a hack, so jpeglib.h does not redefine INT32 and the like*/ -#define XMD_H -#define UINT8 JPEG_UINT8 -#define UINT16 JPEG_UINT16 -#define boolean jpeg_boolean -#undef HAVE_STDLIB_H -# include -#undef HAVE_STDLIB_H -#define HAVE_STDLIB_H 1 -#undef UINT8 -#undef UINT16 -#undef boolean -#endif - -#define COBJMACROS - -#include "windef.h" -#include "winbase.h" -#include "objbase.h" - -#include "wincodecs_private.h" - -#include "wine/heap.h" -#include "wine/debug.h" -#include "wine/library.h" - -WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); - -#ifdef SONAME_LIBJPEG -WINE_DECLARE_DEBUG_CHANNEL(jpeg); - -static void *libjpeg_handle; - -static const WCHAR wszImageQuality[] = {'I','m','a','g','e','Q','u','a','l','i','t','y',0}; -static const WCHAR wszBitmapTransform[] = {'B','i','t','m','a','p','T','r','a','n','s','f','o','r','m',0}; -static const WCHAR wszLuminance[] = {'L','u','m','i','n','a','n','c','e',0}; -static const WCHAR wszChrominance[] = {'C','h','r','o','m','i','n','a','n','c','e',0}; -static const WCHAR wszJpegYCrCbSubsampling[] = {'J','p','e','g','Y','C','r','C','b','S','u','b','s','a','m','p','l','i','n','g',0}; -static const WCHAR wszSuppressApp0[] = {'S','u','p','p','r','e','s','s','A','p','p','0',0}; - -#define MAKE_FUNCPTR(f) static typeof(f) * p##f -MAKE_FUNCPTR(jpeg_CreateCompress); -MAKE_FUNCPTR(jpeg_CreateDecompress); -MAKE_FUNCPTR(jpeg_destroy_compress); -MAKE_FUNCPTR(jpeg_destroy_decompress); -MAKE_FUNCPTR(jpeg_finish_compress); -MAKE_FUNCPTR(jpeg_read_header); -MAKE_FUNCPTR(jpeg_read_scanlines); -MAKE_FUNCPTR(jpeg_resync_to_restart); -MAKE_FUNCPTR(jpeg_set_defaults); -MAKE_FUNCPTR(jpeg_start_compress); -MAKE_FUNCPTR(jpeg_start_decompress); -MAKE_FUNCPTR(jpeg_std_error); -MAKE_FUNCPTR(jpeg_write_scanlines); -#undef MAKE_FUNCPTR - -static void *load_libjpeg(void) -{ - if((libjpeg_handle = wine_dlopen(SONAME_LIBJPEG, RTLD_NOW, NULL, 0)) != NULL) { - -#define LOAD_FUNCPTR(f) \ - if((p##f = wine_dlsym(libjpeg_handle, #f, NULL, 0)) == NULL) { \ - libjpeg_handle = NULL; \ - return NULL; \ - } - - LOAD_FUNCPTR(jpeg_CreateCompress); - LOAD_FUNCPTR(jpeg_CreateDecompress); - LOAD_FUNCPTR(jpeg_destroy_compress); - LOAD_FUNCPTR(jpeg_destroy_decompress); - LOAD_FUNCPTR(jpeg_finish_compress); - LOAD_FUNCPTR(jpeg_read_header); - LOAD_FUNCPTR(jpeg_read_scanlines); - LOAD_FUNCPTR(jpeg_resync_to_restart); - LOAD_FUNCPTR(jpeg_set_defaults); - LOAD_FUNCPTR(jpeg_start_compress); - LOAD_FUNCPTR(jpeg_start_decompress); - LOAD_FUNCPTR(jpeg_std_error); - LOAD_FUNCPTR(jpeg_write_scanlines); -#undef LOAD_FUNCPTR - } - return libjpeg_handle; -} - -static void error_exit_fn(j_common_ptr cinfo) -{ - char message[JMSG_LENGTH_MAX]; - if (ERR_ON(jpeg)) - { - cinfo->err->format_message(cinfo, message); - ERR_(jpeg)("%s\n", message); - } - longjmp(*(jmp_buf*)cinfo->client_data, 1); -} - -static void emit_message_fn(j_common_ptr cinfo, int msg_level) -{ - char message[JMSG_LENGTH_MAX]; - - if (msg_level < 0 && ERR_ON(jpeg)) - { - cinfo->err->format_message(cinfo, message); - ERR_(jpeg)("%s\n", message); - } - else if (msg_level == 0 && WARN_ON(jpeg)) - { - cinfo->err->format_message(cinfo, message); - WARN_(jpeg)("%s\n", message); - } - else if (msg_level > 0 && TRACE_ON(jpeg)) - { - cinfo->err->format_message(cinfo, message); - TRACE_(jpeg)("%s\n", message); - } -} - -typedef struct { - IWICBitmapDecoder IWICBitmapDecoder_iface; - IWICBitmapFrameDecode IWICBitmapFrameDecode_iface; - IWICMetadataBlockReader IWICMetadataBlockReader_iface; - LONG ref; - BOOL initialized; - BOOL cinfo_initialized; - IStream *stream; - struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; - struct jpeg_source_mgr source_mgr; - BYTE source_buffer[1024]; - UINT bpp, stride; - BYTE *image_data; - CRITICAL_SECTION lock; -} JpegDecoder; - -static inline JpegDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface) -{ - return CONTAINING_RECORD(iface, JpegDecoder, IWICBitmapDecoder_iface); -} - -static inline JpegDecoder *impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDecode *iface) -{ - return CONTAINING_RECORD(iface, JpegDecoder, IWICBitmapFrameDecode_iface); -} - -static inline JpegDecoder *decoder_from_decompress(j_decompress_ptr decompress) -{ - return CONTAINING_RECORD(decompress, JpegDecoder, cinfo); -} - -static inline JpegDecoder *impl_from_IWICMetadataBlockReader(IWICMetadataBlockReader *iface) -{ - return CONTAINING_RECORD(iface, JpegDecoder, IWICMetadataBlockReader_iface); -} - -static HRESULT WINAPI JpegDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid, - void **ppv) -{ - JpegDecoder *This = impl_from_IWICBitmapDecoder(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapDecoder, iid)) - { - *ppv = &This->IWICBitmapDecoder_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI JpegDecoder_AddRef(IWICBitmapDecoder *iface) -{ - JpegDecoder *This = impl_from_IWICBitmapDecoder(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - return ref; -} - -static ULONG WINAPI JpegDecoder_Release(IWICBitmapDecoder *iface) -{ - JpegDecoder *This = impl_from_IWICBitmapDecoder(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - if (ref == 0) - { - This->lock.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->lock); - if (This->cinfo_initialized) pjpeg_destroy_decompress(&This->cinfo); - if (This->stream) IStream_Release(This->stream); - HeapFree(GetProcessHeap(), 0, This->image_data); - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static HRESULT WINAPI JpegDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *stream, - DWORD *capability) -{ - HRESULT hr; - - TRACE("(%p,%p,%p)\n", iface, stream, capability); - - if (!stream || !capability) return E_INVALIDARG; - - hr = IWICBitmapDecoder_Initialize(iface, stream, WICDecodeMetadataCacheOnDemand); - if (hr != S_OK) return hr; - - *capability = WICBitmapDecoderCapabilityCanDecodeAllImages | - WICBitmapDecoderCapabilityCanDecodeSomeImages; - /* FIXME: WICBitmapDecoderCapabilityCanEnumerateMetadata */ - return S_OK; -} - -static void source_mgr_init_source(j_decompress_ptr cinfo) -{ -} - -static jpeg_boolean source_mgr_fill_input_buffer(j_decompress_ptr cinfo) -{ - JpegDecoder *This = decoder_from_decompress(cinfo); - HRESULT hr; - ULONG bytesread; - - hr = IStream_Read(This->stream, This->source_buffer, 1024, &bytesread); - - if (FAILED(hr) || bytesread == 0) - { - return FALSE; - } - else - { - This->source_mgr.next_input_byte = This->source_buffer; - This->source_mgr.bytes_in_buffer = bytesread; - return TRUE; - } -} - -static void source_mgr_skip_input_data(j_decompress_ptr cinfo, long num_bytes) -{ - JpegDecoder *This = decoder_from_decompress(cinfo); - LARGE_INTEGER seek; - - if (num_bytes > This->source_mgr.bytes_in_buffer) - { - seek.QuadPart = num_bytes - This->source_mgr.bytes_in_buffer; - IStream_Seek(This->stream, seek, STREAM_SEEK_CUR, NULL); - This->source_mgr.bytes_in_buffer = 0; - } - else if (num_bytes > 0) - { - This->source_mgr.next_input_byte += num_bytes; - This->source_mgr.bytes_in_buffer -= num_bytes; - } -} - -static void source_mgr_term_source(j_decompress_ptr cinfo) -{ -} - -static HRESULT WINAPI JpegDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream, - WICDecodeOptions cacheOptions) -{ - JpegDecoder *This = impl_from_IWICBitmapDecoder(iface); - int ret; - LARGE_INTEGER seek; - jmp_buf jmpbuf; - UINT data_size, i; - - TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOptions); - - EnterCriticalSection(&This->lock); - - if (This->cinfo_initialized) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - pjpeg_std_error(&This->jerr); - - This->jerr.error_exit = error_exit_fn; - This->jerr.emit_message = emit_message_fn; - - This->cinfo.err = &This->jerr; - - This->cinfo.client_data = jmpbuf; - - if (setjmp(jmpbuf)) - { - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - - pjpeg_CreateDecompress(&This->cinfo, JPEG_LIB_VERSION, sizeof(struct jpeg_decompress_struct)); - - This->cinfo_initialized = TRUE; - - This->stream = pIStream; - IStream_AddRef(pIStream); - - seek.QuadPart = 0; - IStream_Seek(This->stream, seek, STREAM_SEEK_SET, NULL); - - This->source_mgr.bytes_in_buffer = 0; - This->source_mgr.init_source = source_mgr_init_source; - This->source_mgr.fill_input_buffer = source_mgr_fill_input_buffer; - This->source_mgr.skip_input_data = source_mgr_skip_input_data; - This->source_mgr.resync_to_restart = pjpeg_resync_to_restart; - This->source_mgr.term_source = source_mgr_term_source; - - This->cinfo.src = &This->source_mgr; - - ret = pjpeg_read_header(&This->cinfo, TRUE); - - if (ret != JPEG_HEADER_OK) { - WARN("Jpeg image in stream has bad format, read header returned %d.\n",ret); - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - - switch (This->cinfo.jpeg_color_space) - { - case JCS_GRAYSCALE: - This->cinfo.out_color_space = JCS_GRAYSCALE; - break; - case JCS_RGB: - case JCS_YCbCr: - This->cinfo.out_color_space = JCS_RGB; - break; - case JCS_CMYK: - case JCS_YCCK: - This->cinfo.out_color_space = JCS_CMYK; - break; - default: - ERR("Unknown JPEG color space %i\n", This->cinfo.jpeg_color_space); - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - - if (!pjpeg_start_decompress(&This->cinfo)) - { - ERR("jpeg_start_decompress failed\n"); - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - - if (This->cinfo.out_color_space == JCS_GRAYSCALE) This->bpp = 8; - else if (This->cinfo.out_color_space == JCS_CMYK) This->bpp = 32; - else This->bpp = 24; - - This->stride = (This->bpp * This->cinfo.output_width + 7) / 8; - data_size = This->stride * This->cinfo.output_height; - - This->image_data = heap_alloc(data_size); - if (!This->image_data) - { - LeaveCriticalSection(&This->lock); - return E_OUTOFMEMORY; - } - - while (This->cinfo.output_scanline < This->cinfo.output_height) - { - UINT first_scanline = This->cinfo.output_scanline; - UINT max_rows; - JSAMPROW out_rows[4]; - JDIMENSION ret; - - max_rows = min(This->cinfo.output_height-first_scanline, 4); - for (i=0; iimage_data + This->stride * (first_scanline+i); - - ret = pjpeg_read_scanlines(&This->cinfo, out_rows, max_rows); - if (ret == 0) - { - ERR("read_scanlines failed\n"); - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - } - - if (This->bpp == 24) - { - /* libjpeg gives us RGB data and we want BGR, so byteswap the data */ - reverse_bgr8(3, This->image_data, - This->cinfo.output_width, This->cinfo.output_height, - This->stride); - } - - if (This->cinfo.out_color_space == JCS_CMYK && This->cinfo.saw_Adobe_marker) - { - /* Adobe JPEG's have inverted CMYK data. */ - for (i=0; iimage_data[i] ^= 0xff; - } - - This->initialized = TRUE; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI JpegDecoder_GetContainerFormat(IWICBitmapDecoder *iface, - GUID *pguidContainerFormat) -{ - memcpy(pguidContainerFormat, &GUID_ContainerFormatJpeg, sizeof(GUID)); - return S_OK; -} - -static HRESULT WINAPI JpegDecoder_GetDecoderInfo(IWICBitmapDecoder *iface, - IWICBitmapDecoderInfo **ppIDecoderInfo) -{ - TRACE("(%p,%p)\n", iface, ppIDecoderInfo); - - return get_decoder_info(&CLSID_WICJpegDecoder, ppIDecoderInfo); -} - -static HRESULT WINAPI JpegDecoder_CopyPalette(IWICBitmapDecoder *iface, - IWICPalette *pIPalette) -{ - TRACE("(%p,%p)\n", iface, pIPalette); - - return WINCODEC_ERR_PALETTEUNAVAILABLE; -} - -static HRESULT WINAPI JpegDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface, - IWICMetadataQueryReader **reader) -{ - TRACE("(%p,%p)\n", iface, reader); - - if (!reader) return E_INVALIDARG; - - *reader = NULL; - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI JpegDecoder_GetPreview(IWICBitmapDecoder *iface, - IWICBitmapSource **ppIBitmapSource) -{ - FIXME("(%p,%p): stub\n", iface, ppIBitmapSource); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI JpegDecoder_GetColorContexts(IWICBitmapDecoder *iface, - UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) -{ - FIXME("(%p,%u,%p,%p): stub\n", iface, cCount, ppIColorContexts, pcActualCount); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI JpegDecoder_GetThumbnail(IWICBitmapDecoder *iface, - IWICBitmapSource **ppIThumbnail) -{ - FIXME("(%p,%p): stub\n", iface, ppIThumbnail); - return WINCODEC_ERR_CODECNOTHUMBNAIL; -} - -static HRESULT WINAPI JpegDecoder_GetFrameCount(IWICBitmapDecoder *iface, - UINT *pCount) -{ - if (!pCount) return E_INVALIDARG; - - *pCount = 1; - return S_OK; -} - -static HRESULT WINAPI JpegDecoder_GetFrame(IWICBitmapDecoder *iface, - UINT index, IWICBitmapFrameDecode **ppIBitmapFrame) -{ - JpegDecoder *This = impl_from_IWICBitmapDecoder(iface); - TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame); - - if (!This->initialized) return WINCODEC_ERR_FRAMEMISSING; - - if (index != 0) return E_INVALIDARG; - - IWICBitmapDecoder_AddRef(iface); - *ppIBitmapFrame = &This->IWICBitmapFrameDecode_iface; - - return S_OK; -} - -static const IWICBitmapDecoderVtbl JpegDecoder_Vtbl = { - JpegDecoder_QueryInterface, - JpegDecoder_AddRef, - JpegDecoder_Release, - JpegDecoder_QueryCapability, - JpegDecoder_Initialize, - JpegDecoder_GetContainerFormat, - JpegDecoder_GetDecoderInfo, - JpegDecoder_CopyPalette, - JpegDecoder_GetMetadataQueryReader, - JpegDecoder_GetPreview, - JpegDecoder_GetColorContexts, - JpegDecoder_GetThumbnail, - JpegDecoder_GetFrameCount, - JpegDecoder_GetFrame -}; - -static HRESULT WINAPI JpegDecoder_Frame_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid, - void **ppv) -{ - JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapSource, iid) || - IsEqualIID(&IID_IWICBitmapFrameDecode, iid)) - { - *ppv = &This->IWICBitmapFrameDecode_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI JpegDecoder_Frame_AddRef(IWICBitmapFrameDecode *iface) -{ - JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - return IWICBitmapDecoder_AddRef(&This->IWICBitmapDecoder_iface); -} - -static ULONG WINAPI JpegDecoder_Frame_Release(IWICBitmapFrameDecode *iface) -{ - JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - return IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface); -} - -static HRESULT WINAPI JpegDecoder_Frame_GetSize(IWICBitmapFrameDecode *iface, - UINT *puiWidth, UINT *puiHeight) -{ - JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - *puiWidth = This->cinfo.output_width; - *puiHeight = This->cinfo.output_height; - TRACE("(%p)->(%u,%u)\n", iface, *puiWidth, *puiHeight); - return S_OK; -} - -static HRESULT WINAPI JpegDecoder_Frame_GetPixelFormat(IWICBitmapFrameDecode *iface, - WICPixelFormatGUID *pPixelFormat) -{ - JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - TRACE("(%p,%p)\n", iface, pPixelFormat); - if (This->cinfo.out_color_space == JCS_RGB) - memcpy(pPixelFormat, &GUID_WICPixelFormat24bppBGR, sizeof(GUID)); - else if (This->cinfo.out_color_space == JCS_CMYK) - memcpy(pPixelFormat, &GUID_WICPixelFormat32bppCMYK, sizeof(GUID)); - else /* This->cinfo.out_color_space == JCS_GRAYSCALE */ - memcpy(pPixelFormat, &GUID_WICPixelFormat8bppGray, sizeof(GUID)); - return S_OK; -} - -static HRESULT WINAPI JpegDecoder_Frame_GetResolution(IWICBitmapFrameDecode *iface, - double *pDpiX, double *pDpiY) -{ - JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - - EnterCriticalSection(&This->lock); - - switch (This->cinfo.density_unit) - { - case 2: /* pixels per centimeter */ - *pDpiX = This->cinfo.X_density * 2.54; - *pDpiY = This->cinfo.Y_density * 2.54; - break; - - case 1: /* pixels per inch */ - *pDpiX = This->cinfo.X_density; - *pDpiY = This->cinfo.Y_density; - break; - - case 0: /* unknown */ - default: - *pDpiX = 96.0; - *pDpiY = 96.0; - break; - } - - LeaveCriticalSection(&This->lock); - - TRACE("(%p)->(%0.2f,%0.2f)\n", iface, *pDpiX, *pDpiY); - - return S_OK; -} - -static HRESULT WINAPI JpegDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface, - IWICPalette *pIPalette) -{ - FIXME("(%p,%p): stub\n", iface, pIPalette); - return E_NOTIMPL; -} - -static HRESULT WINAPI JpegDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface, - const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) -{ - JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - - TRACE("(%p,%s,%u,%u,%p)\n", iface, debug_wic_rect(prc), cbStride, cbBufferSize, pbBuffer); - - return copy_pixels(This->bpp, This->image_data, - This->cinfo.output_width, This->cinfo.output_height, This->stride, - prc, cbStride, cbBufferSize, pbBuffer); -} - -static HRESULT WINAPI JpegDecoder_Frame_GetMetadataQueryReader(IWICBitmapFrameDecode *iface, - IWICMetadataQueryReader **ppIMetadataQueryReader) -{ - JpegDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - - TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader); - - if (!ppIMetadataQueryReader) - return E_INVALIDARG; - - return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, NULL, ppIMetadataQueryReader); -} - -static HRESULT WINAPI JpegDecoder_Frame_GetColorContexts(IWICBitmapFrameDecode *iface, - UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) -{ - FIXME("(%p,%u,%p,%p): stub\n", iface, cCount, ppIColorContexts, pcActualCount); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI JpegDecoder_Frame_GetThumbnail(IWICBitmapFrameDecode *iface, - IWICBitmapSource **ppIThumbnail) -{ - FIXME("(%p,%p): stub\n", iface, ppIThumbnail); - return WINCODEC_ERR_CODECNOTHUMBNAIL; -} - -static const IWICBitmapFrameDecodeVtbl JpegDecoder_Frame_Vtbl = { - JpegDecoder_Frame_QueryInterface, - JpegDecoder_Frame_AddRef, - JpegDecoder_Frame_Release, - JpegDecoder_Frame_GetSize, - JpegDecoder_Frame_GetPixelFormat, - JpegDecoder_Frame_GetResolution, - JpegDecoder_Frame_CopyPalette, - JpegDecoder_Frame_CopyPixels, - JpegDecoder_Frame_GetMetadataQueryReader, - JpegDecoder_Frame_GetColorContexts, - JpegDecoder_Frame_GetThumbnail -}; - -static HRESULT WINAPI JpegDecoder_Block_QueryInterface(IWICMetadataBlockReader *iface, REFIID iid, - void **ppv) -{ - JpegDecoder *This = impl_from_IWICMetadataBlockReader(iface); - return IWICBitmapFrameDecode_QueryInterface(&This->IWICBitmapFrameDecode_iface, iid, ppv); -} - -static ULONG WINAPI JpegDecoder_Block_AddRef(IWICMetadataBlockReader *iface) -{ - JpegDecoder *This = impl_from_IWICMetadataBlockReader(iface); - return IWICBitmapDecoder_AddRef(&This->IWICBitmapDecoder_iface); -} - -static ULONG WINAPI JpegDecoder_Block_Release(IWICMetadataBlockReader *iface) -{ - JpegDecoder *This = impl_from_IWICMetadataBlockReader(iface); - return IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface); -} - -static HRESULT WINAPI JpegDecoder_Block_GetContainerFormat(IWICMetadataBlockReader *iface, - GUID *pguidContainerFormat) -{ - TRACE("%p,%p\n", iface, pguidContainerFormat); - - if (!pguidContainerFormat) return E_INVALIDARG; - - memcpy(pguidContainerFormat, &GUID_ContainerFormatJpeg, sizeof(GUID)); - - return S_OK; -} - -static HRESULT WINAPI JpegDecoder_Block_GetCount(IWICMetadataBlockReader *iface, - UINT *pcCount) -{ - FIXME("%p,%p\n", iface, pcCount); - - if (!pcCount) return E_INVALIDARG; - - *pcCount = 0; - - return S_OK; -} - -static HRESULT WINAPI JpegDecoder_Block_GetReaderByIndex(IWICMetadataBlockReader *iface, - UINT nIndex, IWICMetadataReader **ppIMetadataReader) -{ - FIXME("%p,%d,%p\n", iface, nIndex, ppIMetadataReader); - return E_INVALIDARG; -} - -static HRESULT WINAPI JpegDecoder_Block_GetEnumerator(IWICMetadataBlockReader *iface, - IEnumUnknown **ppIEnumMetadata) -{ - FIXME("%p,%p\n", iface, ppIEnumMetadata); - return E_NOTIMPL; -} - -static const IWICMetadataBlockReaderVtbl JpegDecoder_Block_Vtbl = { - JpegDecoder_Block_QueryInterface, - JpegDecoder_Block_AddRef, - JpegDecoder_Block_Release, - JpegDecoder_Block_GetContainerFormat, - JpegDecoder_Block_GetCount, - JpegDecoder_Block_GetReaderByIndex, - JpegDecoder_Block_GetEnumerator, -}; - -HRESULT JpegDecoder_CreateInstance(REFIID iid, void** ppv) -{ - JpegDecoder *This; - HRESULT ret; - - TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); - - if (!libjpeg_handle && !load_libjpeg()) - { - ERR("Failed reading JPEG because unable to find %s\n", SONAME_LIBJPEG); - return E_FAIL; - } - - *ppv = NULL; - - This = HeapAlloc(GetProcessHeap(), 0, sizeof(JpegDecoder)); - if (!This) return E_OUTOFMEMORY; - - This->IWICBitmapDecoder_iface.lpVtbl = &JpegDecoder_Vtbl; - This->IWICBitmapFrameDecode_iface.lpVtbl = &JpegDecoder_Frame_Vtbl; - This->IWICMetadataBlockReader_iface.lpVtbl = &JpegDecoder_Block_Vtbl; - This->ref = 1; - This->initialized = FALSE; - This->cinfo_initialized = FALSE; - This->stream = NULL; - This->image_data = NULL; - InitializeCriticalSection(&This->lock); - This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JpegDecoder.lock"); - - ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); - IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface); - - return ret; -} - -typedef struct jpeg_compress_format { - const WICPixelFormatGUID *guid; - int bpp; - int num_components; - J_COLOR_SPACE color_space; - int swap_rgb; -} jpeg_compress_format; - -static const jpeg_compress_format compress_formats[] = { - { &GUID_WICPixelFormat24bppBGR, 24, 3, JCS_RGB, 1 }, - { &GUID_WICPixelFormat32bppCMYK, 32, 4, JCS_CMYK }, - { &GUID_WICPixelFormat8bppGray, 8, 1, JCS_GRAYSCALE }, - { 0 } -}; - -typedef struct JpegEncoder { - IWICBitmapEncoder IWICBitmapEncoder_iface; - IWICBitmapFrameEncode IWICBitmapFrameEncode_iface; - LONG ref; - struct jpeg_compress_struct cinfo; - struct jpeg_error_mgr jerr; - struct jpeg_destination_mgr dest_mgr; - BOOL initialized; - int frame_count; - BOOL frame_initialized; - BOOL started_compress; - int lines_written; - BOOL frame_committed; - BOOL committed; - UINT width, height; - double xres, yres; - const jpeg_compress_format *format; - IStream *stream; - WICColor palette[256]; - UINT colors; - CRITICAL_SECTION lock; - BYTE dest_buffer[1024]; -} JpegEncoder; - -static inline JpegEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface) -{ - return CONTAINING_RECORD(iface, JpegEncoder, IWICBitmapEncoder_iface); -} - -static inline JpegEncoder *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface) -{ - return CONTAINING_RECORD(iface, JpegEncoder, IWICBitmapFrameEncode_iface); -} - -static inline JpegEncoder *encoder_from_compress(j_compress_ptr compress) -{ - return CONTAINING_RECORD(compress, JpegEncoder, cinfo); -} - -static void dest_mgr_init_destination(j_compress_ptr cinfo) -{ - JpegEncoder *This = encoder_from_compress(cinfo); - - This->dest_mgr.next_output_byte = This->dest_buffer; - This->dest_mgr.free_in_buffer = sizeof(This->dest_buffer); -} - -static jpeg_boolean dest_mgr_empty_output_buffer(j_compress_ptr cinfo) -{ - JpegEncoder *This = encoder_from_compress(cinfo); - HRESULT hr; - ULONG byteswritten; - - hr = IStream_Write(This->stream, This->dest_buffer, - sizeof(This->dest_buffer), &byteswritten); - - if (hr != S_OK || byteswritten == 0) - { - ERR("Failed writing data, hr=%x\n", hr); - return FALSE; - } - - This->dest_mgr.next_output_byte = This->dest_buffer; - This->dest_mgr.free_in_buffer = sizeof(This->dest_buffer); - return TRUE; -} - -static void dest_mgr_term_destination(j_compress_ptr cinfo) -{ - JpegEncoder *This = encoder_from_compress(cinfo); - ULONG byteswritten; - HRESULT hr; - - if (This->dest_mgr.free_in_buffer != sizeof(This->dest_buffer)) - { - hr = IStream_Write(This->stream, This->dest_buffer, - sizeof(This->dest_buffer) - This->dest_mgr.free_in_buffer, &byteswritten); - - if (hr != S_OK || byteswritten == 0) - ERR("Failed writing data, hr=%x\n", hr); - } -} - -static HRESULT WINAPI JpegEncoder_Frame_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid, - void **ppv) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapFrameEncode, iid)) - { - *ppv = &This->IWICBitmapFrameEncode_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI JpegEncoder_Frame_AddRef(IWICBitmapFrameEncode *iface) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - return IWICBitmapEncoder_AddRef(&This->IWICBitmapEncoder_iface); -} - -static ULONG WINAPI JpegEncoder_Frame_Release(IWICBitmapFrameEncode *iface) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - return IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface); -} - -static HRESULT WINAPI JpegEncoder_Frame_Initialize(IWICBitmapFrameEncode *iface, - IPropertyBag2 *pIEncoderOptions) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%p)\n", iface, pIEncoderOptions); - - EnterCriticalSection(&This->lock); - - if (This->frame_initialized) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->frame_initialized = TRUE; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI JpegEncoder_Frame_SetSize(IWICBitmapFrameEncode *iface, - UINT uiWidth, UINT uiHeight) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight); - - EnterCriticalSection(&This->lock); - - if (!This->frame_initialized || This->started_compress) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->width = uiWidth; - This->height = uiHeight; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI JpegEncoder_Frame_SetResolution(IWICBitmapFrameEncode *iface, - double dpiX, double dpiY) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY); - - EnterCriticalSection(&This->lock); - - if (!This->frame_initialized || This->started_compress) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->xres = dpiX; - This->yres = dpiY; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI JpegEncoder_Frame_SetPixelFormat(IWICBitmapFrameEncode *iface, - WICPixelFormatGUID *pPixelFormat) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - int i; - TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat)); - - EnterCriticalSection(&This->lock); - - if (!This->frame_initialized || This->started_compress) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - for (i=0; compress_formats[i].guid; i++) - { - if (memcmp(compress_formats[i].guid, pPixelFormat, sizeof(GUID)) == 0) - break; - } - - if (!compress_formats[i].guid) i = 0; - - This->format = &compress_formats[i]; - memcpy(pPixelFormat, This->format->guid, sizeof(GUID)); - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI JpegEncoder_Frame_SetColorContexts(IWICBitmapFrameEncode *iface, - UINT cCount, IWICColorContext **ppIColorContext) -{ - FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); - return E_NOTIMPL; -} - -static HRESULT WINAPI JpegEncoder_Frame_SetPalette(IWICBitmapFrameEncode *iface, - IWICPalette *palette) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr; - - TRACE("(%p,%p)\n", iface, palette); - - if (!palette) return E_INVALIDARG; - - EnterCriticalSection(&This->lock); - - if (This->frame_initialized) - hr = IWICPalette_GetColors(palette, 256, This->palette, &This->colors); - else - hr = WINCODEC_ERR_NOTINITIALIZED; - - LeaveCriticalSection(&This->lock); - return hr; -} - -static HRESULT WINAPI JpegEncoder_Frame_SetThumbnail(IWICBitmapFrameEncode *iface, - IWICBitmapSource *pIThumbnail) -{ - FIXME("(%p,%p): stub\n", iface, pIThumbnail); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI JpegEncoder_Frame_WritePixels(IWICBitmapFrameEncode *iface, - UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - jmp_buf jmpbuf; - BYTE *swapped_data = NULL, *current_row; - UINT line; - int row_size; - TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels); - - EnterCriticalSection(&This->lock); - - if (!This->frame_initialized || !This->width || !This->height || !This->format) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - if (lineCount == 0 || lineCount + This->lines_written > This->height) - { - LeaveCriticalSection(&This->lock); - return E_INVALIDARG; - } - - /* set up setjmp/longjmp error handling */ - if (setjmp(jmpbuf)) - { - LeaveCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, swapped_data); - return E_FAIL; - } - This->cinfo.client_data = jmpbuf; - - if (!This->started_compress) - { - This->cinfo.image_width = This->width; - This->cinfo.image_height = This->height; - This->cinfo.input_components = This->format->num_components; - This->cinfo.in_color_space = This->format->color_space; - - pjpeg_set_defaults(&This->cinfo); - - if (This->xres != 0.0 && This->yres != 0.0) - { - This->cinfo.density_unit = 1; /* dots per inch */ - This->cinfo.X_density = This->xres; - This->cinfo.Y_density = This->yres; - } - - pjpeg_start_compress(&This->cinfo, TRUE); - - This->started_compress = TRUE; - } - - row_size = This->format->bpp / 8 * This->width; - - if (This->format->swap_rgb) - { - swapped_data = HeapAlloc(GetProcessHeap(), 0, row_size); - if (!swapped_data) - { - LeaveCriticalSection(&This->lock); - return E_OUTOFMEMORY; - } - } - - for (line=0; line < lineCount; line++) - { - if (This->format->swap_rgb) - { - UINT x; - - memcpy(swapped_data, pbPixels + (cbStride * line), row_size); - - for (x=0; x < This->width; x++) - { - BYTE b; - - b = swapped_data[x*3]; - swapped_data[x*3] = swapped_data[x*3+2]; - swapped_data[x*3+2] = b; - } - - current_row = swapped_data; - } - else - current_row = pbPixels + (cbStride * line); - - if (!pjpeg_write_scanlines(&This->cinfo, ¤t_row, 1)) - { - ERR("failed writing scanlines\n"); - LeaveCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, swapped_data); - return E_FAIL; - } - - This->lines_written++; - } - - LeaveCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, swapped_data); - - return S_OK; -} - -static HRESULT WINAPI JpegEncoder_Frame_WriteSource(IWICBitmapFrameEncode *iface, - IWICBitmapSource *pIBitmapSource, WICRect *prc) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr; - TRACE("(%p,%p,%s)\n", iface, pIBitmapSource, debug_wic_rect(prc)); - - if (!This->frame_initialized) - return WINCODEC_ERR_WRONGSTATE; - - hr = configure_write_source(iface, pIBitmapSource, prc, - This->format ? This->format->guid : NULL, This->width, This->height, - This->xres, This->yres); - - if (SUCCEEDED(hr)) - { - hr = write_source(iface, pIBitmapSource, prc, - This->format->guid, This->format->bpp, This->width, This->height); - } - - return hr; -} - -static HRESULT WINAPI JpegEncoder_Frame_Commit(IWICBitmapFrameEncode *iface) -{ - JpegEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - jmp_buf jmpbuf; - TRACE("(%p)\n", iface); - - EnterCriticalSection(&This->lock); - - if (!This->started_compress || This->lines_written != This->height || This->frame_committed) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - /* set up setjmp/longjmp error handling */ - if (setjmp(jmpbuf)) - { - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - This->cinfo.client_data = jmpbuf; - - pjpeg_finish_compress(&This->cinfo); - - This->frame_committed = TRUE; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI JpegEncoder_Frame_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface, - IWICMetadataQueryWriter **ppIMetadataQueryWriter) -{ - FIXME("(%p, %p): stub\n", iface, ppIMetadataQueryWriter); - return E_NOTIMPL; -} - -static const IWICBitmapFrameEncodeVtbl JpegEncoder_FrameVtbl = { - JpegEncoder_Frame_QueryInterface, - JpegEncoder_Frame_AddRef, - JpegEncoder_Frame_Release, - JpegEncoder_Frame_Initialize, - JpegEncoder_Frame_SetSize, - JpegEncoder_Frame_SetResolution, - JpegEncoder_Frame_SetPixelFormat, - JpegEncoder_Frame_SetColorContexts, - JpegEncoder_Frame_SetPalette, - JpegEncoder_Frame_SetThumbnail, - JpegEncoder_Frame_WritePixels, - JpegEncoder_Frame_WriteSource, - JpegEncoder_Frame_Commit, - JpegEncoder_Frame_GetMetadataQueryWriter -}; - -static HRESULT WINAPI JpegEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid, - void **ppv) -{ - JpegEncoder *This = impl_from_IWICBitmapEncoder(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapEncoder, iid)) - { - *ppv = &This->IWICBitmapEncoder_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI JpegEncoder_AddRef(IWICBitmapEncoder *iface) -{ - JpegEncoder *This = impl_from_IWICBitmapEncoder(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - return ref; -} - -static ULONG WINAPI JpegEncoder_Release(IWICBitmapEncoder *iface) -{ - JpegEncoder *This = impl_from_IWICBitmapEncoder(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - if (ref == 0) - { - This->lock.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->lock); - if (This->initialized) pjpeg_destroy_compress(&This->cinfo); - if (This->stream) IStream_Release(This->stream); - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static HRESULT WINAPI JpegEncoder_Initialize(IWICBitmapEncoder *iface, - IStream *pIStream, WICBitmapEncoderCacheOption cacheOption) -{ - JpegEncoder *This = impl_from_IWICBitmapEncoder(iface); - jmp_buf jmpbuf; - - TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption); - - EnterCriticalSection(&This->lock); - - if (This->initialized) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - pjpeg_std_error(&This->jerr); - - This->jerr.error_exit = error_exit_fn; - This->jerr.emit_message = emit_message_fn; - - This->cinfo.err = &This->jerr; - - This->cinfo.client_data = jmpbuf; - - if (setjmp(jmpbuf)) - { - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - - pjpeg_CreateCompress(&This->cinfo, JPEG_LIB_VERSION, sizeof(struct jpeg_compress_struct)); - - This->stream = pIStream; - IStream_AddRef(pIStream); - - This->dest_mgr.next_output_byte = This->dest_buffer; - This->dest_mgr.free_in_buffer = sizeof(This->dest_buffer); - - This->dest_mgr.init_destination = dest_mgr_init_destination; - This->dest_mgr.empty_output_buffer = dest_mgr_empty_output_buffer; - This->dest_mgr.term_destination = dest_mgr_term_destination; - - This->cinfo.dest = &This->dest_mgr; - - This->initialized = TRUE; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI JpegEncoder_GetContainerFormat(IWICBitmapEncoder *iface, GUID *format) -{ - TRACE("(%p,%p)\n", iface, format); - - if (!format) - return E_INVALIDARG; - - memcpy(format, &GUID_ContainerFormatJpeg, sizeof(*format)); - return S_OK; -} - -static HRESULT WINAPI JpegEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info) -{ - IWICComponentInfo *comp_info; - HRESULT hr; - - TRACE("%p,%p\n", iface, info); - - if (!info) return E_INVALIDARG; - - hr = CreateComponentInfo(&CLSID_WICJpegEncoder, &comp_info); - if (hr == S_OK) - { - hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info); - IWICComponentInfo_Release(comp_info); - } - return hr; -} - -static HRESULT WINAPI JpegEncoder_SetColorContexts(IWICBitmapEncoder *iface, - UINT cCount, IWICColorContext **ppIColorContext) -{ - FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); - return E_NOTIMPL; -} - -static HRESULT WINAPI JpegEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *pIPalette) -{ - JpegEncoder *This = impl_from_IWICBitmapEncoder(iface); - HRESULT hr; - - TRACE("(%p,%p)\n", iface, pIPalette); - - EnterCriticalSection(&This->lock); - - hr = This->initialized ? WINCODEC_ERR_UNSUPPORTEDOPERATION : WINCODEC_ERR_NOTINITIALIZED; - - LeaveCriticalSection(&This->lock); - - return hr; -} - -static HRESULT WINAPI JpegEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail) -{ - TRACE("(%p,%p)\n", iface, pIThumbnail); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI JpegEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *pIPreview) -{ - TRACE("(%p,%p)\n", iface, pIPreview); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI JpegEncoder_CreateNewFrame(IWICBitmapEncoder *iface, - IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions) -{ - JpegEncoder *This = impl_from_IWICBitmapEncoder(iface); - HRESULT hr; - static const PROPBAG2 opts[6] = - { - { PROPBAG2_TYPE_DATA, VT_R4, 0, 0, (LPOLESTR)wszImageQuality }, - { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)wszBitmapTransform }, - { PROPBAG2_TYPE_DATA, VT_I4 | VT_ARRAY, 0, 0, (LPOLESTR)wszLuminance }, - { PROPBAG2_TYPE_DATA, VT_I4 | VT_ARRAY, 0, 0, (LPOLESTR)wszChrominance }, - { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)wszJpegYCrCbSubsampling }, - { PROPBAG2_TYPE_DATA, VT_BOOL, 0, 0, (LPOLESTR)wszSuppressApp0 }, - }; - - TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions); - - EnterCriticalSection(&This->lock); - - if (This->frame_count != 0) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; - } - - if (!This->initialized) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_NOTINITIALIZED; - } - - if (ppIEncoderOptions) - { - hr = CreatePropertyBag2(opts, ARRAY_SIZE(opts), ppIEncoderOptions); - if (FAILED(hr)) - { - LeaveCriticalSection(&This->lock); - return hr; - } - } - - This->frame_count = 1; - - LeaveCriticalSection(&This->lock); - - IWICBitmapEncoder_AddRef(iface); - *ppIFrameEncode = &This->IWICBitmapFrameEncode_iface; - - return S_OK; -} - -static HRESULT WINAPI JpegEncoder_Commit(IWICBitmapEncoder *iface) -{ - JpegEncoder *This = impl_from_IWICBitmapEncoder(iface); - TRACE("(%p)\n", iface); - - EnterCriticalSection(&This->lock); - - if (!This->frame_committed || This->committed) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->committed = TRUE; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI JpegEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface, - IWICMetadataQueryWriter **ppIMetadataQueryWriter) -{ - FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryWriter); - return E_NOTIMPL; -} - -static const IWICBitmapEncoderVtbl JpegEncoder_Vtbl = { - JpegEncoder_QueryInterface, - JpegEncoder_AddRef, - JpegEncoder_Release, - JpegEncoder_Initialize, - JpegEncoder_GetContainerFormat, - JpegEncoder_GetEncoderInfo, - JpegEncoder_SetColorContexts, - JpegEncoder_SetPalette, - JpegEncoder_SetThumbnail, - JpegEncoder_SetPreview, - JpegEncoder_CreateNewFrame, - JpegEncoder_Commit, - JpegEncoder_GetMetadataQueryWriter -}; - -HRESULT JpegEncoder_CreateInstance(REFIID iid, void** ppv) -{ - JpegEncoder *This; - HRESULT ret; - - TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); - - *ppv = NULL; - - if (!libjpeg_handle && !load_libjpeg()) - { - ERR("Failed writing JPEG because unable to find %s\n",SONAME_LIBJPEG); - return E_FAIL; - } - - This = HeapAlloc(GetProcessHeap(), 0, sizeof(JpegEncoder)); - if (!This) return E_OUTOFMEMORY; - - This->IWICBitmapEncoder_iface.lpVtbl = &JpegEncoder_Vtbl; - This->IWICBitmapFrameEncode_iface.lpVtbl = &JpegEncoder_FrameVtbl; - This->ref = 1; - This->initialized = FALSE; - This->frame_count = 0; - This->frame_initialized = FALSE; - This->started_compress = FALSE; - This->lines_written = 0; - This->frame_committed = FALSE; - This->committed = FALSE; - This->width = This->height = 0; - This->xres = This->yres = 0.0; - This->format = NULL; - This->stream = NULL; - This->colors = 0; - InitializeCriticalSection(&This->lock); - This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JpegEncoder.lock"); - - ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv); - IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface); - - return ret; -} - -#else /* !defined(SONAME_LIBJPEG) */ - -HRESULT JpegDecoder_CreateInstance(REFIID iid, void** ppv) -{ - ERR("Trying to load JPEG picture, but JPEG support is not compiled in.\n"); - return E_FAIL; -} - -HRESULT JpegEncoder_CreateInstance(REFIID iid, void** ppv) -{ - ERR("Trying to save JPEG picture, but JPEG support is not compiled in.\n"); - return E_FAIL; -} - -#endif diff --git a/dll/win32/windowscodecs/libjpeg.c b/dll/win32/windowscodecs/libjpeg.c new file mode 100644 index 00000000000..22903ae4340 --- /dev/null +++ b/dll/win32/windowscodecs/libjpeg.c @@ -0,0 +1,662 @@ +/* + * Copyright 2009 Vincent Povirk for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winternl.h" +#include "winbase.h" +#include "objbase.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); +WINE_DECLARE_DEBUG_CHANNEL(jpeg); + +static void error_exit_fn(j_common_ptr cinfo) +{ + char message[JMSG_LENGTH_MAX]; + if (ERR_ON(jpeg)) + { + cinfo->err->format_message(cinfo, message); + ERR_(jpeg)("%s\n", message); + } + longjmp(*(jmp_buf*)cinfo->client_data, 1); +} + +static void emit_message_fn(j_common_ptr cinfo, int msg_level) +{ + char message[JMSG_LENGTH_MAX]; + + if (msg_level < 0 && ERR_ON(jpeg)) + { + cinfo->err->format_message(cinfo, message); + ERR_(jpeg)("%s\n", message); + } + else if (msg_level == 0 && WARN_ON(jpeg)) + { + cinfo->err->format_message(cinfo, message); + WARN_(jpeg)("%s\n", message); + } + else if (msg_level > 0 && TRACE_ON(jpeg)) + { + cinfo->err->format_message(cinfo, message); + TRACE_(jpeg)("%s\n", message); + } +} + +struct jpeg_decoder { + struct decoder decoder; + struct decoder_frame frame; + BOOL cinfo_initialized; + IStream *stream; + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + struct jpeg_source_mgr source_mgr; + BYTE source_buffer[1024]; + UINT stride; + BYTE *image_data; +}; + +static inline struct jpeg_decoder *impl_from_decoder(struct decoder* iface) +{ + return CONTAINING_RECORD(iface, struct jpeg_decoder, decoder); +} + +static inline struct jpeg_decoder *decoder_from_decompress(j_decompress_ptr decompress) +{ + return CONTAINING_RECORD(decompress, struct jpeg_decoder, cinfo); +} + +static void CDECL jpeg_decoder_destroy(struct decoder* iface) +{ + struct jpeg_decoder *This = impl_from_decoder(iface); + + if (This->cinfo_initialized) jpeg_destroy_decompress(&This->cinfo); + free(This->image_data); + free(This); +} + +static void source_mgr_init_source(j_decompress_ptr cinfo) +{ +} + +static boolean source_mgr_fill_input_buffer(j_decompress_ptr cinfo) +{ + struct jpeg_decoder *This = decoder_from_decompress(cinfo); + HRESULT hr; + ULONG bytesread; + + hr = stream_read(This->stream, This->source_buffer, 1024, &bytesread); + + if (FAILED(hr) || bytesread == 0) + { + return FALSE; + } + else + { + This->source_mgr.next_input_byte = This->source_buffer; + This->source_mgr.bytes_in_buffer = bytesread; + return TRUE; + } +} + +static void source_mgr_skip_input_data(j_decompress_ptr cinfo, long num_bytes) +{ + struct jpeg_decoder *This = decoder_from_decompress(cinfo); + + if (num_bytes > This->source_mgr.bytes_in_buffer) + { + stream_seek(This->stream, num_bytes - This->source_mgr.bytes_in_buffer, STREAM_SEEK_CUR, NULL); + This->source_mgr.bytes_in_buffer = 0; + } + else if (num_bytes > 0) + { + This->source_mgr.next_input_byte += num_bytes; + This->source_mgr.bytes_in_buffer -= num_bytes; + } +} + +static void source_mgr_term_source(j_decompress_ptr cinfo) +{ +} + +static HRESULT CDECL jpeg_decoder_initialize(struct decoder* iface, IStream *stream, struct decoder_stat *st) +{ + struct jpeg_decoder *This = impl_from_decoder(iface); + int ret; + jmp_buf jmpbuf; + UINT data_size, i; + + if (This->cinfo_initialized) + return WINCODEC_ERR_WRONGSTATE; + + jpeg_std_error(&This->jerr); + + This->jerr.error_exit = error_exit_fn; + This->jerr.emit_message = emit_message_fn; + + This->cinfo.err = &This->jerr; + + This->cinfo.client_data = jmpbuf; + + if (setjmp(jmpbuf)) + return E_FAIL; + + jpeg_CreateDecompress(&This->cinfo, JPEG_LIB_VERSION, sizeof(struct jpeg_decompress_struct)); + + This->cinfo_initialized = TRUE; + + This->stream = stream; + + stream_seek(This->stream, 0, STREAM_SEEK_SET, NULL); + + This->source_mgr.bytes_in_buffer = 0; + This->source_mgr.init_source = source_mgr_init_source; + This->source_mgr.fill_input_buffer = source_mgr_fill_input_buffer; + This->source_mgr.skip_input_data = source_mgr_skip_input_data; + This->source_mgr.resync_to_restart = jpeg_resync_to_restart; + This->source_mgr.term_source = source_mgr_term_source; + + This->cinfo.src = &This->source_mgr; + + ret = jpeg_read_header(&This->cinfo, TRUE); + + if (ret != JPEG_HEADER_OK) { + WARN("Jpeg image in stream has bad format, read header returned %d.\n",ret); + return E_FAIL; + } + + switch (This->cinfo.jpeg_color_space) + { + case JCS_GRAYSCALE: + This->cinfo.out_color_space = JCS_GRAYSCALE; + This->frame.bpp = 8; + This->frame.pixel_format = GUID_WICPixelFormat8bppGray; + break; + case JCS_RGB: + case JCS_YCbCr: + This->cinfo.out_color_space = JCS_RGB; + This->frame.bpp = 24; + This->frame.pixel_format = GUID_WICPixelFormat24bppBGR; + break; + case JCS_CMYK: + case JCS_YCCK: + This->cinfo.out_color_space = JCS_CMYK; + This->frame.bpp = 32; + This->frame.pixel_format = GUID_WICPixelFormat32bppCMYK; + break; + default: + ERR("Unknown JPEG color space %i\n", This->cinfo.jpeg_color_space); + return E_FAIL; + } + + if (!jpeg_start_decompress(&This->cinfo)) + { + ERR("jpeg_start_decompress failed\n"); + return E_FAIL; + } + + This->frame.width = This->cinfo.output_width; + This->frame.height = This->cinfo.output_height; + + switch (This->cinfo.density_unit) + { + case 2: /* pixels per centimeter */ + This->frame.dpix = This->cinfo.X_density * 2.54; + This->frame.dpiy = This->cinfo.Y_density * 2.54; + break; + + case 1: /* pixels per inch */ + This->frame.dpix = This->cinfo.X_density; + This->frame.dpiy = This->cinfo.Y_density; + break; + + case 0: /* unknown */ + default: + This->frame.dpix = This->frame.dpiy = 96.0; + break; + } + + This->frame.num_color_contexts = 0; + This->frame.num_colors = 0; + + This->stride = (This->frame.bpp * This->cinfo.output_width + 7) / 8; + data_size = This->stride * This->cinfo.output_height; + + if (data_size / This->stride < This->cinfo.output_height) + /* overflow in multiplication */ + return E_OUTOFMEMORY; + + This->image_data = malloc(data_size); + if (!This->image_data) + return E_OUTOFMEMORY; + + while (This->cinfo.output_scanline < This->cinfo.output_height) + { + UINT first_scanline = This->cinfo.output_scanline; + UINT max_rows; + JSAMPROW out_rows[4]; + JDIMENSION ret; + + max_rows = min(This->cinfo.output_height-first_scanline, 4); + for (i=0; iimage_data + This->stride * (first_scanline+i); + + ret = jpeg_read_scanlines(&This->cinfo, out_rows, max_rows); + if (ret == 0) + { + ERR("read_scanlines failed\n"); + return E_FAIL; + } + } + + if (This->frame.bpp == 24) + { + /* libjpeg gives us RGB data and we want BGR, so byteswap the data */ + reverse_bgr8(3, This->image_data, + This->cinfo.output_width, This->cinfo.output_height, + This->stride); + } + + if (This->cinfo.out_color_space == JCS_CMYK && This->cinfo.saw_Adobe_marker) + { + /* Adobe JPEG's have inverted CMYK data. */ + for (i=0; iimage_data[i] ^= 0xff; + } + + st->frame_count = 1; + st->flags = WICBitmapDecoderCapabilityCanDecodeAllImages | + WICBitmapDecoderCapabilityCanDecodeSomeImages | + WICBitmapDecoderCapabilityCanEnumerateMetadata | + DECODER_FLAGS_UNSUPPORTED_COLOR_CONTEXT; + return S_OK; +} + +static HRESULT CDECL jpeg_decoder_get_frame_info(struct decoder* iface, UINT frame, struct decoder_frame *info) +{ + struct jpeg_decoder *This = impl_from_decoder(iface); + *info = This->frame; + return S_OK; +} + +static HRESULT CDECL jpeg_decoder_copy_pixels(struct decoder* iface, UINT frame, + const WICRect *prc, UINT stride, UINT buffersize, BYTE *buffer) +{ + struct jpeg_decoder *This = impl_from_decoder(iface); + return copy_pixels(This->frame.bpp, This->image_data, + This->frame.width, This->frame.height, This->stride, + prc, stride, buffersize, buffer); +} + +static HRESULT CDECL jpeg_decoder_get_metadata_blocks(struct decoder* iface, UINT frame, + UINT *count, struct decoder_block **blocks) +{ + FIXME("stub\n"); + *count = 0; + *blocks = NULL; + return S_OK; +} + +static HRESULT CDECL jpeg_decoder_get_color_context(struct decoder* This, UINT frame, UINT num, + BYTE **data, DWORD *datasize) +{ + /* This should never be called because we report 0 color contexts and the unsupported flag. */ + FIXME("stub\n"); + return E_NOTIMPL; +} + +static const struct decoder_funcs jpeg_decoder_vtable = { + jpeg_decoder_initialize, + jpeg_decoder_get_frame_info, + jpeg_decoder_copy_pixels, + jpeg_decoder_get_metadata_blocks, + jpeg_decoder_get_color_context, + jpeg_decoder_destroy +}; + +HRESULT CDECL jpeg_decoder_create(struct decoder_info *info, struct decoder **result) +{ + struct jpeg_decoder *This; + + This = malloc(sizeof(struct jpeg_decoder)); + if (!This) return E_OUTOFMEMORY; + + This->decoder.vtable = &jpeg_decoder_vtable; + This->cinfo_initialized = FALSE; + This->stream = NULL; + This->image_data = NULL; + *result = &This->decoder; + + info->container_format = GUID_ContainerFormatJpeg; + info->block_format = GUID_ContainerFormatJpeg; + info->clsid = CLSID_WICJpegDecoder; + + return S_OK; +} + +typedef struct jpeg_compress_format { + const WICPixelFormatGUID *guid; + int bpp; + int num_components; + J_COLOR_SPACE color_space; + int swap_rgb; +} jpeg_compress_format; + +static const jpeg_compress_format compress_formats[] = { + { &GUID_WICPixelFormat24bppBGR, 24, 3, JCS_RGB, 1 }, + { &GUID_WICPixelFormat32bppCMYK, 32, 4, JCS_CMYK }, + { &GUID_WICPixelFormat8bppGray, 8, 1, JCS_GRAYSCALE }, + { 0 } +}; + +struct jpeg_encoder +{ + struct encoder encoder; + IStream *stream; + BOOL cinfo_initialized; + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + struct jpeg_destination_mgr dest_mgr; + struct encoder_frame encoder_frame; + const jpeg_compress_format *format; + BYTE dest_buffer[1024]; +}; + +static inline struct jpeg_encoder *impl_from_encoder(struct encoder* iface) +{ + return CONTAINING_RECORD(iface, struct jpeg_encoder, encoder); +} + +static inline struct jpeg_encoder *encoder_from_compress(j_compress_ptr compress) +{ + return CONTAINING_RECORD(compress, struct jpeg_encoder, cinfo); +} + +static void dest_mgr_init_destination(j_compress_ptr cinfo) +{ + struct jpeg_encoder *This = encoder_from_compress(cinfo); + + This->dest_mgr.next_output_byte = This->dest_buffer; + This->dest_mgr.free_in_buffer = sizeof(This->dest_buffer); +} + +static boolean dest_mgr_empty_output_buffer(j_compress_ptr cinfo) +{ + struct jpeg_encoder *This = encoder_from_compress(cinfo); + HRESULT hr; + ULONG byteswritten; + + hr = stream_write(This->stream, This->dest_buffer, + sizeof(This->dest_buffer), &byteswritten); + + if (hr != S_OK || byteswritten == 0) + { + ERR("Failed writing data, hr=%lx\n", hr); + return FALSE; + } + + This->dest_mgr.next_output_byte = This->dest_buffer; + This->dest_mgr.free_in_buffer = sizeof(This->dest_buffer); + return TRUE; +} + +static void dest_mgr_term_destination(j_compress_ptr cinfo) +{ + struct jpeg_encoder *This = encoder_from_compress(cinfo); + ULONG byteswritten; + HRESULT hr; + + if (This->dest_mgr.free_in_buffer != sizeof(This->dest_buffer)) + { + hr = stream_write(This->stream, This->dest_buffer, + sizeof(This->dest_buffer) - This->dest_mgr.free_in_buffer, &byteswritten); + + if (hr != S_OK || byteswritten == 0) + ERR("Failed writing data, hr=%lx\n", hr); + } +} + +static HRESULT CDECL jpeg_encoder_initialize(struct encoder* iface, IStream *stream) +{ + struct jpeg_encoder *This = impl_from_encoder(iface); + jmp_buf jmpbuf; + + jpeg_std_error(&This->jerr); + + This->jerr.error_exit = error_exit_fn; + This->jerr.emit_message = emit_message_fn; + + This->cinfo.err = &This->jerr; + + This->cinfo.client_data = jmpbuf; + + if (setjmp(jmpbuf)) + return E_FAIL; + + jpeg_CreateCompress(&This->cinfo, JPEG_LIB_VERSION, sizeof(struct jpeg_compress_struct)); + + This->stream = stream; + + This->dest_mgr.next_output_byte = This->dest_buffer; + This->dest_mgr.free_in_buffer = sizeof(This->dest_buffer); + + This->dest_mgr.init_destination = dest_mgr_init_destination; + This->dest_mgr.empty_output_buffer = dest_mgr_empty_output_buffer; + This->dest_mgr.term_destination = dest_mgr_term_destination; + + This->cinfo.dest = &This->dest_mgr; + + This->cinfo_initialized = TRUE; + + return S_OK; +} + +static HRESULT CDECL jpeg_encoder_get_supported_format(struct encoder* iface, GUID *pixel_format, + DWORD *bpp, BOOL *indexed) +{ + int i; + + for (i=0; compress_formats[i].guid; i++) + { + if (memcmp(compress_formats[i].guid, pixel_format, sizeof(GUID)) == 0) + break; + } + + if (!compress_formats[i].guid) i = 0; + + *pixel_format = *compress_formats[i].guid; + *bpp = compress_formats[i].bpp; + *indexed = FALSE; + + return S_OK; +} + +static HRESULT CDECL jpeg_encoder_create_frame(struct encoder* iface, const struct encoder_frame *frame) +{ + struct jpeg_encoder *This = impl_from_encoder(iface); + jmp_buf jmpbuf; + int i; + + This->encoder_frame = *frame; + + if (setjmp(jmpbuf)) + return E_FAIL; + + This->cinfo.client_data = jmpbuf; + + for (i=0; compress_formats[i].guid; i++) + { + if (memcmp(compress_formats[i].guid, &frame->pixel_format, sizeof(GUID)) == 0) + break; + } + This->format = &compress_formats[i]; + + This->cinfo.image_width = frame->width; + This->cinfo.image_height = frame->height; + This->cinfo.input_components = This->format->num_components; + This->cinfo.in_color_space = This->format->color_space; + + jpeg_set_defaults(&This->cinfo); + + if (frame->dpix != 0.0 && frame->dpiy != 0.0) + { + This->cinfo.density_unit = 1; /* dots per inch */ + This->cinfo.X_density = frame->dpix; + This->cinfo.Y_density = frame->dpiy; + } + + jpeg_start_compress(&This->cinfo, TRUE); + + return S_OK; +} + +static HRESULT CDECL jpeg_encoder_write_lines(struct encoder* iface, BYTE *data, + DWORD line_count, DWORD stride) +{ + struct jpeg_encoder *This = impl_from_encoder(iface); + jmp_buf jmpbuf; + BYTE *swapped_data = NULL, *current_row; + UINT line; + int row_size; + + if (setjmp(jmpbuf)) + { + free(swapped_data); + return E_FAIL; + } + + This->cinfo.client_data = jmpbuf; + + row_size = This->format->bpp / 8 * This->encoder_frame.width; + + if (This->format->swap_rgb) + { + swapped_data = malloc(row_size); + if (!swapped_data) + return E_OUTOFMEMORY; + } + + for (line=0; line < line_count; line++) + { + if (This->format->swap_rgb) + { + UINT x; + + memcpy(swapped_data, data + (stride * line), row_size); + + for (x=0; x < This->encoder_frame.width; x++) + { + BYTE b; + + b = swapped_data[x*3]; + swapped_data[x*3] = swapped_data[x*3+2]; + swapped_data[x*3+2] = b; + } + + current_row = swapped_data; + } + else + current_row = data + (stride * line); + + if (!jpeg_write_scanlines(&This->cinfo, ¤t_row, 1)) + { + ERR("failed writing scanlines\n"); + free(swapped_data); + return E_FAIL; + } + } + + free(swapped_data); + + return S_OK; +} + +static HRESULT CDECL jpeg_encoder_commit_frame(struct encoder* iface) +{ + struct jpeg_encoder *This = impl_from_encoder(iface); + jmp_buf jmpbuf; + + if (setjmp(jmpbuf)) + return E_FAIL; + + This->cinfo.client_data = jmpbuf; + + jpeg_finish_compress(&This->cinfo); + + return S_OK; +} + +static HRESULT CDECL jpeg_encoder_commit_file(struct encoder* iface) +{ + return S_OK; +} + +static void CDECL jpeg_encoder_destroy(struct encoder* iface) +{ + struct jpeg_encoder *This = impl_from_encoder(iface); + if (This->cinfo_initialized) + jpeg_destroy_compress(&This->cinfo); + free(This); +}; + +static const struct encoder_funcs jpeg_encoder_vtable = { + jpeg_encoder_initialize, + jpeg_encoder_get_supported_format, + jpeg_encoder_create_frame, + jpeg_encoder_write_lines, + jpeg_encoder_commit_frame, + jpeg_encoder_commit_file, + jpeg_encoder_destroy +}; + +HRESULT CDECL jpeg_encoder_create(struct encoder_info *info, struct encoder **result) +{ + struct jpeg_encoder *This; + + This = malloc(sizeof(struct jpeg_encoder)); + if (!This) return E_OUTOFMEMORY; + + This->encoder.vtable = &jpeg_encoder_vtable; + This->stream = NULL; + This->cinfo_initialized = FALSE; + *result = &This->encoder; + + info->flags = ENCODER_FLAGS_SUPPORTS_METADATA; + info->container_format = GUID_ContainerFormatJpeg; + info->clsid = CLSID_WICJpegEncoder; + info->encoder_options[0] = ENCODER_OPTION_IMAGE_QUALITY; + info->encoder_options[1] = ENCODER_OPTION_BITMAP_TRANSFORM; + info->encoder_options[2] = ENCODER_OPTION_LUMINANCE; + info->encoder_options[3] = ENCODER_OPTION_CHROMINANCE; + info->encoder_options[4] = ENCODER_OPTION_YCRCB_SUBSAMPLING; + info->encoder_options[5] = ENCODER_OPTION_SUPPRESS_APP0; + info->encoder_options[6] = ENCODER_OPTION_END; + + return S_OK; +} diff --git a/dll/win32/windowscodecs/libpng.c b/dll/win32/windowscodecs/libpng.c new file mode 100644 index 00000000000..137a8e15e33 --- /dev/null +++ b/dll/win32/windowscodecs/libpng.c @@ -0,0 +1,842 @@ +/* + * Copyright 2016 Dmitry Timoshkov + * Copyright 2020 Esme Povirk + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winternl.h" +#include "winbase.h" +#include "objbase.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + +struct png_decoder +{ + struct decoder decoder; + IStream *stream; + struct decoder_frame decoder_frame; + UINT stride; + BYTE *image_bits; + BYTE *color_profile; + DWORD color_profile_len; +}; + +static inline struct png_decoder *impl_from_decoder(struct decoder* iface) +{ + return CONTAINING_RECORD(iface, struct png_decoder, decoder); +} + +static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + IStream *stream = png_get_io_ptr(png_ptr); + HRESULT hr; + ULONG bytesread; + + hr = stream_read(stream, data, length, &bytesread); + if (FAILED(hr) || bytesread != length) + { + png_error(png_ptr, "failed reading data"); + } +} + +static HRESULT CDECL png_decoder_initialize(struct decoder *iface, IStream *stream, struct decoder_stat *st) +{ + struct png_decoder *This = impl_from_decoder(iface); + png_structp png_ptr; + png_infop info_ptr; + HRESULT hr = E_FAIL; + int color_type, bit_depth; + png_bytep trans; + int num_trans; + png_uint_32 transparency; + png_color_16p trans_values; + png_uint_32 ret, xres, yres; + int unit_type; + png_colorp png_palette; + int num_palette; + int i; + UINT image_size; + png_bytep *row_pointers=NULL; + png_charp cp_name; + png_bytep cp_profile; + png_uint_32 cp_len; + int cp_compression; + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) + { + return E_FAIL; + } + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + png_destroy_read_struct(&png_ptr, NULL, NULL); + return E_FAIL; + } + + /* set up setjmp/longjmp error handling */ + if (setjmp(png_jmpbuf(png_ptr))) + { + hr = WINCODEC_ERR_UNKNOWNIMAGEFORMAT; + goto end; + } + png_set_crc_action(png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE); + png_set_chunk_malloc_max(png_ptr, 0); + + /* seek to the start of the stream */ + hr = stream_seek(stream, 0, STREAM_SEEK_SET, NULL); + if (FAILED(hr)) + { + goto end; + } + + /* set up custom i/o handling */ + png_set_read_fn(png_ptr, stream, user_read_data); + + /* read the header */ + png_read_info(png_ptr, info_ptr); + + /* choose a pixel format */ + color_type = png_get_color_type(png_ptr, info_ptr); + bit_depth = png_get_bit_depth(png_ptr, info_ptr); + + /* PNGs with bit-depth greater than 8 are network byte order. Windows does not expect this. */ + if (bit_depth > 8) + png_set_swap(png_ptr); + + /* check for color-keyed alpha */ + transparency = png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &trans_values); + if (!transparency) + num_trans = 0; + + if (transparency && (color_type == PNG_COLOR_TYPE_RGB || + (color_type == PNG_COLOR_TYPE_GRAY && bit_depth == 16))) + { + /* expand to RGBA */ + if (color_type == PNG_COLOR_TYPE_GRAY) + png_set_gray_to_rgb(png_ptr); + png_set_tRNS_to_alpha(png_ptr); + color_type = PNG_COLOR_TYPE_RGB_ALPHA; + } + + switch (color_type) + { + case PNG_COLOR_TYPE_GRAY_ALPHA: + /* WIC does not support grayscale alpha formats so use RGBA */ + png_set_gray_to_rgb(png_ptr); + /* fall through */ + case PNG_COLOR_TYPE_RGB_ALPHA: + This->decoder_frame.bpp = bit_depth * 4; + switch (bit_depth) + { + case 8: + png_set_bgr(png_ptr); + This->decoder_frame.pixel_format = GUID_WICPixelFormat32bppBGRA; + break; + case 16: This->decoder_frame.pixel_format = GUID_WICPixelFormat64bppRGBA; break; + default: + ERR("invalid RGBA bit depth: %i\n", bit_depth); + hr = E_FAIL; + goto end; + } + break; + case PNG_COLOR_TYPE_GRAY: + This->decoder_frame.bpp = bit_depth; + if (!transparency) + { + switch (bit_depth) + { + case 1: This->decoder_frame.pixel_format = GUID_WICPixelFormatBlackWhite; break; + case 2: This->decoder_frame.pixel_format = GUID_WICPixelFormat2bppGray; break; + case 4: This->decoder_frame.pixel_format = GUID_WICPixelFormat4bppGray; break; + case 8: This->decoder_frame.pixel_format = GUID_WICPixelFormat8bppGray; break; + case 16: This->decoder_frame.pixel_format = GUID_WICPixelFormat16bppGray; break; + default: + ERR("invalid grayscale bit depth: %i\n", bit_depth); + hr = E_FAIL; + goto end; + } + break; + } + /* else fall through */ + case PNG_COLOR_TYPE_PALETTE: + This->decoder_frame.bpp = bit_depth; + switch (bit_depth) + { + case 1: This->decoder_frame.pixel_format = GUID_WICPixelFormat1bppIndexed; break; + case 2: This->decoder_frame.pixel_format = GUID_WICPixelFormat2bppIndexed; break; + case 4: This->decoder_frame.pixel_format = GUID_WICPixelFormat4bppIndexed; break; + case 8: This->decoder_frame.pixel_format = GUID_WICPixelFormat8bppIndexed; break; + default: + ERR("invalid indexed color bit depth: %i\n", bit_depth); + hr = E_FAIL; + goto end; + } + break; + case PNG_COLOR_TYPE_RGB: + This->decoder_frame.bpp = bit_depth * 3; + switch (bit_depth) + { + case 8: + png_set_bgr(png_ptr); + This->decoder_frame.pixel_format = GUID_WICPixelFormat24bppBGR; + break; + case 16: This->decoder_frame.pixel_format = GUID_WICPixelFormat48bppRGB; break; + default: + ERR("invalid RGB color bit depth: %i\n", bit_depth); + hr = E_FAIL; + goto end; + } + break; + default: + ERR("invalid color type %i\n", color_type); + hr = E_FAIL; + goto end; + } + + This->decoder_frame.width = png_get_image_width(png_ptr, info_ptr); + This->decoder_frame.height = png_get_image_height(png_ptr, info_ptr); + + ret = png_get_pHYs(png_ptr, info_ptr, &xres, &yres, &unit_type); + + if (ret && unit_type == PNG_RESOLUTION_METER) + { + This->decoder_frame.dpix = xres * 0.0254; + This->decoder_frame.dpiy = yres * 0.0254; + } + else + { + WARN("no pHYs block present\n"); + This->decoder_frame.dpix = This->decoder_frame.dpiy = 96.0; + } + + ret = png_get_iCCP(png_ptr, info_ptr, &cp_name, &cp_compression, &cp_profile, &cp_len); + if (ret) + { + This->decoder_frame.num_color_contexts = 1; + This->color_profile_len = cp_len; + This->color_profile = malloc(cp_len); + if (!This->color_profile) + { + hr = E_OUTOFMEMORY; + goto end; + } + memcpy(This->color_profile, cp_profile, cp_len); + } + else + This->decoder_frame.num_color_contexts = 0; + + if (color_type == PNG_COLOR_TYPE_PALETTE) + { + ret = png_get_PLTE(png_ptr, info_ptr, &png_palette, &num_palette); + if (!ret) + { + ERR("paletted image with no PLTE chunk\n"); + hr = E_FAIL; + goto end; + } + + if (num_palette > 256) + { + ERR("palette has %i colors?!\n", num_palette); + hr = E_FAIL; + goto end; + } + + This->decoder_frame.num_colors = num_palette; + for (i=0; idecoder_frame.palette[i] = (alpha << 24 | + png_palette[i].red << 16| + png_palette[i].green << 8| + png_palette[i].blue); + } + } + else if (color_type == PNG_COLOR_TYPE_GRAY && transparency && bit_depth <= 8) { + num_palette = 1 << bit_depth; + + This->decoder_frame.num_colors = num_palette; + for (i=0; idecoder_frame.palette[i] = (alpha << 24 | val << 16 | val << 8 | val); + } + } + else + { + This->decoder_frame.num_colors = 0; + } + + This->stride = (This->decoder_frame.width * This->decoder_frame.bpp + 7) / 8; + image_size = This->stride * This->decoder_frame.height; + + This->image_bits = malloc(image_size); + if (!This->image_bits) + { + hr = E_OUTOFMEMORY; + goto end; + } + + row_pointers = malloc(sizeof(png_bytep)*This->decoder_frame.height); + if (!row_pointers) + { + hr = E_OUTOFMEMORY; + goto end; + } + + for (i=0; idecoder_frame.height; i++) + row_pointers[i] = This->image_bits + i * This->stride; + + png_read_image(png_ptr, row_pointers); + + free(row_pointers); + row_pointers = NULL; + + /* png_read_end intentionally not called to not seek to the end of the file */ + + st->flags = WICBitmapDecoderCapabilityCanDecodeAllImages | + WICBitmapDecoderCapabilityCanDecodeSomeImages | + WICBitmapDecoderCapabilityCanEnumerateMetadata; + st->frame_count = 1; + + This->stream = stream; + + hr = S_OK; + +end: + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + free(row_pointers); + if (FAILED(hr)) + { + free(This->image_bits); + This->image_bits = NULL; + free(This->color_profile); + This->color_profile = NULL; + } + return hr; +} + +static HRESULT CDECL png_decoder_get_frame_info(struct decoder *iface, UINT frame, struct decoder_frame *info) +{ + struct png_decoder *This = impl_from_decoder(iface); + *info = This->decoder_frame; + return S_OK; +} + +static HRESULT CDECL png_decoder_copy_pixels(struct decoder *iface, UINT frame, + const WICRect *prc, UINT stride, UINT buffersize, BYTE *buffer) +{ + struct png_decoder *This = impl_from_decoder(iface); + + return copy_pixels(This->decoder_frame.bpp, This->image_bits, + This->decoder_frame.width, This->decoder_frame.height, This->stride, + prc, stride, buffersize, buffer); +} + +static HRESULT CDECL png_decoder_get_metadata_blocks(struct decoder* iface, + UINT frame, UINT *count, struct decoder_block **blocks) +{ + struct png_decoder *This = impl_from_decoder(iface); + HRESULT hr; + struct decoder_block *result = NULL; + ULONGLONG seek; + BYTE chunk_type[4]; + ULONG chunk_size; + ULONGLONG chunk_start; + ULONG metadata_blocks_size = 0; + + seek = 8; + *count = 0; + + do + { + hr = stream_seek(This->stream, seek, STREAM_SEEK_SET, &chunk_start); + if (FAILED(hr)) goto end; + + hr = read_png_chunk(This->stream, chunk_type, NULL, &chunk_size); + if (FAILED(hr)) goto end; + + if (chunk_type[0] >= 'a' && chunk_type[0] <= 'z' && + memcmp(chunk_type, "tRNS", 4) && memcmp(chunk_type, "pHYs", 4)) + { + /* This chunk is considered metadata. */ + if (*count == metadata_blocks_size) + { + struct decoder_block *new_metadata_blocks; + ULONG new_metadata_blocks_size; + + new_metadata_blocks_size = 4 + metadata_blocks_size * 2; + new_metadata_blocks = malloc(new_metadata_blocks_size * sizeof(*new_metadata_blocks)); + + if (!new_metadata_blocks) + { + hr = E_OUTOFMEMORY; + goto end; + } + + memcpy(new_metadata_blocks, result, + *count * sizeof(*new_metadata_blocks)); + + free(result); + result = new_metadata_blocks; + metadata_blocks_size = new_metadata_blocks_size; + } + + result[*count].offset = chunk_start; + result[*count].length = chunk_size + 12; + result[*count].options = WICMetadataCreationAllowUnknown; + (*count)++; + } + + seek = chunk_start + chunk_size + 12; /* skip data and CRC */ + } while (memcmp(chunk_type, "IEND", 4)); + +end: + if (SUCCEEDED(hr)) + { + *blocks = result; + } + else + { + *count = 0; + *blocks = NULL; + free(result); + } + return hr; +} + +static HRESULT CDECL png_decoder_get_color_context(struct decoder* iface, UINT frame, UINT num, + BYTE **data, DWORD *datasize) +{ + struct png_decoder *This = impl_from_decoder(iface); + + *data = malloc(This->color_profile_len); + *datasize = This->color_profile_len; + + if (!*data) + return E_OUTOFMEMORY; + + memcpy(*data, This->color_profile, This->color_profile_len); + + return S_OK; +} + +static void CDECL png_decoder_destroy(struct decoder* iface) +{ + struct png_decoder *This = impl_from_decoder(iface); + + free(This->image_bits); + free(This->color_profile); + free(This); +} + +static const struct decoder_funcs png_decoder_vtable = { + png_decoder_initialize, + png_decoder_get_frame_info, + png_decoder_copy_pixels, + png_decoder_get_metadata_blocks, + png_decoder_get_color_context, + png_decoder_destroy +}; + +HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **result) +{ + struct png_decoder *This; + + This = malloc(sizeof(*This)); + + if (!This) + { + return E_OUTOFMEMORY; + } + + This->decoder.vtable = &png_decoder_vtable; + This->image_bits = NULL; + This->color_profile = NULL; + *result = &This->decoder; + + info->container_format = GUID_ContainerFormatPng; + info->block_format = GUID_ContainerFormatPng; + info->clsid = CLSID_WICPngDecoder; + + return S_OK; +} + +struct png_pixelformat { + const WICPixelFormatGUID *guid; + UINT bpp; + int bit_depth; + int color_type; + BOOL remove_filler; + BOOL swap_rgb; +}; + +static const struct png_pixelformat formats[] = { + {&GUID_WICPixelFormat32bppBGRA, 32, 8, PNG_COLOR_TYPE_RGB_ALPHA, 0, 1}, + {&GUID_WICPixelFormat24bppBGR, 24, 8, PNG_COLOR_TYPE_RGB, 0, 1}, + {&GUID_WICPixelFormatBlackWhite, 1, 1, PNG_COLOR_TYPE_GRAY, 0, 0}, + {&GUID_WICPixelFormat2bppGray, 2, 2, PNG_COLOR_TYPE_GRAY, 0, 0}, + {&GUID_WICPixelFormat4bppGray, 4, 4, PNG_COLOR_TYPE_GRAY, 0, 0}, + {&GUID_WICPixelFormat8bppGray, 8, 8, PNG_COLOR_TYPE_GRAY, 0, 0}, + {&GUID_WICPixelFormat16bppGray, 16, 16, PNG_COLOR_TYPE_GRAY, 0, 0}, + {&GUID_WICPixelFormat32bppBGR, 32, 8, PNG_COLOR_TYPE_RGB, 1, 1}, + {&GUID_WICPixelFormat48bppRGB, 48, 16, PNG_COLOR_TYPE_RGB, 0, 0}, + {&GUID_WICPixelFormat64bppRGBA, 64, 16, PNG_COLOR_TYPE_RGB_ALPHA, 0, 0}, + {&GUID_WICPixelFormat1bppIndexed, 1, 1, PNG_COLOR_TYPE_PALETTE, 0, 0}, + {&GUID_WICPixelFormat2bppIndexed, 2, 2, PNG_COLOR_TYPE_PALETTE, 0, 0}, + {&GUID_WICPixelFormat4bppIndexed, 4, 4, PNG_COLOR_TYPE_PALETTE, 0, 0}, + {&GUID_WICPixelFormat8bppIndexed, 8, 8, PNG_COLOR_TYPE_PALETTE, 0, 0}, + {NULL}, +}; + +struct png_encoder +{ + struct encoder encoder; + IStream *stream; + png_structp png_ptr; + png_infop info_ptr; + struct encoder_frame encoder_frame; + const struct png_pixelformat *format; + BYTE *data; + UINT stride; + UINT passes; + UINT lines_written; +}; + +static inline struct png_encoder *impl_from_encoder(struct encoder* iface) +{ + return CONTAINING_RECORD(iface, struct png_encoder, encoder); +} + +static void user_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + struct png_encoder *This = png_get_io_ptr(png_ptr); + HRESULT hr; + ULONG byteswritten; + + hr = stream_write(This->stream, data, length, &byteswritten); + if (FAILED(hr) || byteswritten != length) + { + png_error(png_ptr, "failed writing data"); + } +} + +static void user_flush(png_structp png_ptr) +{ +} + +static HRESULT CDECL png_encoder_initialize(struct encoder *encoder, IStream *stream) +{ + struct png_encoder *This = impl_from_encoder(encoder); + + TRACE("(%p,%p)\n", encoder, stream); + + /* initialize libpng */ + This->png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!This->png_ptr) + return E_FAIL; + + This->info_ptr = png_create_info_struct(This->png_ptr); + if (!This->info_ptr) + { + png_destroy_write_struct(&This->png_ptr, NULL); + This->png_ptr = NULL; + return E_FAIL; + } + + This->stream = stream; + + /* set up setjmp/longjmp error handling */ + if (setjmp(png_jmpbuf(This->png_ptr))) + { + png_destroy_write_struct(&This->png_ptr, &This->info_ptr); + This->png_ptr = NULL; + This->stream = NULL; + return E_FAIL; + } + + /* set up custom i/o handling */ + png_set_write_fn(This->png_ptr, This, user_write_data, user_flush); + + return S_OK; +} + +static HRESULT CDECL png_encoder_get_supported_format(struct encoder* iface, GUID *pixel_format, DWORD *bpp, BOOL *indexed) +{ + int i; + + for (i=0; formats[i].guid; i++) + { + if (memcmp(formats[i].guid, pixel_format, sizeof(GUID)) == 0) + break; + } + + if (!formats[i].guid) + i = 0; + + *pixel_format = *formats[i].guid; + *bpp = formats[i].bpp; + *indexed = (formats[i].color_type == PNG_COLOR_TYPE_PALETTE); + + return S_OK; +} + +static HRESULT CDECL png_encoder_create_frame(struct encoder *encoder, const struct encoder_frame *encoder_frame) +{ + struct png_encoder *This = impl_from_encoder(encoder); + int i; + + for (i=0; formats[i].guid; i++) + { + if (memcmp(formats[i].guid, &encoder_frame->pixel_format, sizeof(GUID)) == 0) + { + This->format = &formats[i]; + break; + } + } + + if (!formats[i].guid) + { + ERR("invalid pixel format %s\n", wine_dbgstr_guid(&encoder_frame->pixel_format)); + return E_FAIL; + } + + /* set up setjmp/longjmp error handling */ + if (setjmp(png_jmpbuf(This->png_ptr))) + return E_FAIL; + + This->encoder_frame = *encoder_frame; + This->lines_written = 0; + + if (encoder_frame->interlace) + { + /* libpng requires us to write all data multiple times in this case. */ + This->stride = (This->format->bpp * encoder_frame->width + 7)/8; + This->data = malloc(encoder_frame->height * This->stride); + if (!This->data) + return E_OUTOFMEMORY; + } + + /* Tell PNG we need to byte swap if writing a >8-bpp image */ + if (This->format->bit_depth > 8) + png_set_swap(This->png_ptr); + + png_set_IHDR(This->png_ptr, This->info_ptr, encoder_frame->width, encoder_frame->height, + This->format->bit_depth, This->format->color_type, + encoder_frame->interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + + if (encoder_frame->dpix != 0.0 && encoder_frame->dpiy != 0.0) + { + png_set_pHYs(This->png_ptr, This->info_ptr, (encoder_frame->dpix+0.0127) / 0.0254, + (encoder_frame->dpiy+0.0127) / 0.0254, PNG_RESOLUTION_METER); + } + + if (This->format->color_type == PNG_COLOR_TYPE_PALETTE && encoder_frame->num_colors) + { + png_color png_palette[256]; + png_byte trans[256]; + UINT i, num_trans = 0, colors; + + /* Newer libpng versions don't accept larger palettes than the declared + * bit depth, so we need to generate the palette of the correct length. + */ + colors = min(encoder_frame->num_colors, 1 << This->format->bit_depth); + + for (i = 0; i < colors; i++) + { + png_palette[i].red = (encoder_frame->palette[i] >> 16) & 0xff; + png_palette[i].green = (encoder_frame->palette[i] >> 8) & 0xff; + png_palette[i].blue = encoder_frame->palette[i] & 0xff; + trans[i] = (encoder_frame->palette[i] >> 24) & 0xff; + if (trans[i] != 0xff) + num_trans = i+1; + } + + png_set_PLTE(This->png_ptr, This->info_ptr, png_palette, colors); + + if (num_trans) + png_set_tRNS(This->png_ptr, This->info_ptr, trans, num_trans, NULL); + } + + png_write_info(This->png_ptr, This->info_ptr); + + if (This->format->remove_filler) + png_set_filler(This->png_ptr, 0, PNG_FILLER_AFTER); + + if (This->format->swap_rgb) + png_set_bgr(This->png_ptr); + + if (encoder_frame->interlace) + This->passes = png_set_interlace_handling(This->png_ptr); + + if (encoder_frame->filter != WICPngFilterUnspecified) + { + static const int png_filter_map[] = + { + /* WICPngFilterUnspecified */ PNG_NO_FILTERS, + /* WICPngFilterNone */ PNG_FILTER_NONE, + /* WICPngFilterSub */ PNG_FILTER_SUB, + /* WICPngFilterUp */ PNG_FILTER_UP, + /* WICPngFilterAverage */ PNG_FILTER_AVG, + /* WICPngFilterPaeth */ PNG_FILTER_PAETH, + /* WICPngFilterAdaptive */ PNG_ALL_FILTERS, + }; + + png_set_filter(This->png_ptr, 0, png_filter_map[encoder_frame->filter]); + } + + return S_OK; +} + +static HRESULT CDECL png_encoder_write_lines(struct encoder* encoder, BYTE *data, DWORD line_count, DWORD stride) +{ + struct png_encoder *This = impl_from_encoder(encoder); + png_byte **row_pointers=NULL; + UINT i; + + if (This->encoder_frame.interlace) + { + /* Just store the data so we can write it in multiple passes in Commit. */ + for (i=0; idata + This->stride * (This->lines_written + i), + data + stride * i, + This->stride); + + This->lines_written += line_count; + + return S_OK; + } + + /* set up setjmp/longjmp error handling */ + if (setjmp(png_jmpbuf(This->png_ptr))) + { + free(row_pointers); + return E_FAIL; + } + + row_pointers = malloc(line_count * sizeof(png_byte*)); + if (!row_pointers) + return E_OUTOFMEMORY; + + for (i=0; ipng_ptr, row_pointers, line_count); + This->lines_written += line_count; + + free(row_pointers); + + return S_OK; +} + +static HRESULT CDECL png_encoder_commit_frame(struct encoder *encoder) +{ + struct png_encoder *This = impl_from_encoder(encoder); + png_byte **row_pointers=NULL; + + /* set up setjmp/longjmp error handling */ + if (setjmp(png_jmpbuf(This->png_ptr))) + { + free(row_pointers); + return E_FAIL; + } + + if (This->encoder_frame.interlace) + { + int i; + + row_pointers = malloc(This->encoder_frame.height * sizeof(png_byte*)); + if (!row_pointers) + return E_OUTOFMEMORY; + + for (i=0; iencoder_frame.height; i++) + row_pointers[i] = This->data + This->stride * i; + + for (i=0; ipasses; i++) + png_write_rows(This->png_ptr, row_pointers, This->encoder_frame.height); + } + + png_write_end(This->png_ptr, This->info_ptr); + + free(row_pointers); + + return S_OK; +} + +static HRESULT CDECL png_encoder_commit_file(struct encoder *encoder) +{ + return S_OK; +} + +static void CDECL png_encoder_destroy(struct encoder *encoder) +{ + struct png_encoder *This = impl_from_encoder(encoder); + if (This->png_ptr) + png_destroy_write_struct(&This->png_ptr, &This->info_ptr); + free(This->data); + free(This); +} + +static const struct encoder_funcs png_encoder_vtable = { + png_encoder_initialize, + png_encoder_get_supported_format, + png_encoder_create_frame, + png_encoder_write_lines, + png_encoder_commit_frame, + png_encoder_commit_file, + png_encoder_destroy +}; + +HRESULT CDECL png_encoder_create(struct encoder_info *info, struct encoder **result) +{ + struct png_encoder *This; + + This = malloc(sizeof(*This)); + + if (!This) + { + return E_OUTOFMEMORY; + } + + This->encoder.vtable = &png_encoder_vtable; + This->png_ptr = NULL; + This->info_ptr = NULL; + This->data = NULL; + *result = &This->encoder; + + info->flags = ENCODER_FLAGS_SUPPORTS_METADATA; + info->container_format = GUID_ContainerFormatPng; + info->clsid = CLSID_WICPngEncoder; + info->encoder_options[0] = ENCODER_OPTION_INTERLACE; + info->encoder_options[1] = ENCODER_OPTION_FILTER; + info->encoder_options[2] = ENCODER_OPTION_END; + + return S_OK; +} diff --git a/dll/win32/windowscodecs/libtiff.c b/dll/win32/windowscodecs/libtiff.c new file mode 100644 index 00000000000..9db707f82cb --- /dev/null +++ b/dll/win32/windowscodecs/libtiff.c @@ -0,0 +1,1352 @@ +/* + * Copyright 2010 Vincent Povirk for CodeWeavers + * Copyright 2016 Dmitry Timoshkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winternl.h" +#include "winbase.h" +#include "objbase.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); +#ifdef __REACTOS__ +#include "wine/library.h" +extern int isfinite(double x); +static void tiff_error_handler( const char *module, const char *format, va_list args ) +{ + +} +static void tiff_warning_handler( const char *module, const char *format, va_list args ) +{ + +} +#else +WINE_DECLARE_DEBUG_CHANNEL(tiff); + +static void tiff_error_handler( const char *module, const char *format, va_list args ) +{ + if (!ERR_ON(tiff)) return; + if (__wine_dbg_vlog( __WINE_DBCL_ERR, &__wine_dbch_tiff, module, format, args ) != -1) + __wine_dbg_output( "\n" ); +} + +static void tiff_warning_handler( const char *module, const char *format, va_list args ) +{ + if (!WARN_ON(tiff)) return; + if (__wine_dbg_vlog( __WINE_DBCL_WARN, &__wine_dbch_tiff, module, format, args ) != -1) + __wine_dbg_output( "\n" ); +} +#endif + +static tsize_t tiff_stream_read(thandle_t client_data, tdata_t data, tsize_t size) +{ + IStream *stream = (IStream*)client_data; + ULONG bytes_read; + HRESULT hr; + + hr = stream_read(stream, data, size, &bytes_read); + if (FAILED(hr)) bytes_read = 0; + return bytes_read; +} + +static tsize_t tiff_stream_write(thandle_t client_data, tdata_t data, tsize_t size) +{ + IStream *stream = (IStream*)client_data; + ULONG bytes_written; + HRESULT hr; + + hr = stream_write(stream, data, size, &bytes_written); + if (FAILED(hr)) bytes_written = 0; + return bytes_written; +} + +static toff_t tiff_stream_seek(thandle_t client_data, toff_t offset, int whence) +{ + IStream *stream = (IStream*)client_data; + DWORD origin; + ULONGLONG new_position; + HRESULT hr; + + switch (whence) + { + case SEEK_SET: + origin = STREAM_SEEK_SET; + break; + case SEEK_CUR: + origin = STREAM_SEEK_CUR; + break; + case SEEK_END: + origin = STREAM_SEEK_END; + break; + default: + ERR("unknown whence value %i\n", whence); + return -1; + } + + hr = stream_seek(stream, offset, origin, &new_position); + if (SUCCEEDED(hr)) return new_position; + else return -1; +} + +static int tiff_stream_close(thandle_t client_data) +{ + /* Caller is responsible for releasing the stream object. */ + return 0; +} + +static toff_t tiff_stream_size(thandle_t client_data) +{ + IStream *stream = (IStream*)client_data; + ULONGLONG size; + HRESULT hr; + + hr = stream_getsize(stream, &size); + + if (SUCCEEDED(hr)) return size; + else return -1; +} + +static int tiff_stream_map(thandle_t client_data, tdata_t *addr, toff_t *size) +{ + /* Cannot mmap streams */ + return 0; +} + +static void tiff_stream_unmap(thandle_t client_data, tdata_t addr, toff_t size) +{ + /* No need to ever do this, since we can't map things. */ +} + +static TIFF* tiff_open_stream(IStream *stream, const char *mode) +{ + stream_seek(stream, 0, STREAM_SEEK_SET, NULL); + + return TIFFClientOpen("", mode, stream, tiff_stream_read, + tiff_stream_write, (void *)tiff_stream_seek, tiff_stream_close, + (void *)tiff_stream_size, (void *)tiff_stream_map, (void *)tiff_stream_unmap); +} + +typedef struct { + struct decoder_frame frame; + int bps; + int samples; + int source_bpp; + int planar; + int indexed; + int reverse_bgr; + int invert_grayscale; + UINT tile_width, tile_height; + UINT tile_stride; + UINT tile_size; + int tiled; + UINT tiles_across; +} tiff_decode_info; + +struct tiff_decoder +{ + struct decoder decoder; + IStream *stream; + TIFF *tiff; + DWORD frame_count; + DWORD cached_frame; + tiff_decode_info cached_decode_info; + INT cached_tile_x, cached_tile_y; + BYTE *cached_tile; +}; + +static inline struct tiff_decoder *impl_from_decoder(struct decoder* iface) +{ + return CONTAINING_RECORD(iface, struct tiff_decoder, decoder); +} + +static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info) +{ + uint16_t photometric, bps, samples, planar; + uint16_t extra_sample_count, extra_sample, *extra_samples; + uint16_t *red, *green, *blue; + UINT resolution_unit; + float xres=0.0, yres=0.0; + int ret, i; + const BYTE *profile; + UINT len; + + decode_info->indexed = 0; + decode_info->reverse_bgr = 0; + decode_info->invert_grayscale = 0; + decode_info->tiled = 0; + decode_info->source_bpp = 0; + + ret = TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric); + if (!ret) + { + WARN("missing PhotometricInterpretation tag\n"); + return E_FAIL; + } + + ret = TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bps); + if (!ret) bps = 1; + decode_info->bps = bps; + + ret = TIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &samples); + if (!ret) samples = 1; + decode_info->samples = samples; + + if (samples == 1) + planar = 1; + else + { + ret = TIFFGetField(tiff, TIFFTAG_PLANARCONFIG, &planar); + if (!ret) planar = 1; + if (planar != 1) + { + FIXME("unhandled planar configuration %u\n", planar); + return E_FAIL; + } + } + decode_info->planar = planar; + + TRACE("planar %u, photometric %u, samples %u, bps %u\n", planar, photometric, samples, bps); + + switch(photometric) + { + case 0: /* WhiteIsZero */ + decode_info->invert_grayscale = 1; + /* fall through */ + case 1: /* BlackIsZero */ + if (samples == 2) + { + ret = TIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &extra_sample_count, &extra_samples); + if (!ret) + { + extra_sample_count = 1; + extra_sample = 0; + extra_samples = &extra_sample; + } + } + else if (samples != 1) + { + FIXME("unhandled %dbpp sample count %u\n", bps, samples); + return E_FAIL; + } + + decode_info->frame.bpp = bps * samples; + decode_info->source_bpp = decode_info->frame.bpp; + switch (bps) + { + case 1: + if (samples != 1) + { + FIXME("unhandled 1bpp sample count %u\n", samples); + return E_FAIL; + } + decode_info->frame.pixel_format = GUID_WICPixelFormatBlackWhite; + break; + case 4: + if (samples != 1) + { + FIXME("unhandled 4bpp grayscale sample count %u\n", samples); + return E_FAIL; + } + decode_info->frame.pixel_format = GUID_WICPixelFormat4bppGray; + break; + case 8: + if (samples == 1) + decode_info->frame.pixel_format = GUID_WICPixelFormat8bppGray; + else + { + decode_info->frame.bpp = 32; + + switch(extra_samples[0]) + { + case 1: /* Associated (pre-multiplied) alpha data */ + decode_info->frame.pixel_format = GUID_WICPixelFormat32bppPBGRA; + break; + case 0: /* Unspecified data */ + case 2: /* Unassociated alpha data */ + decode_info->frame.pixel_format = GUID_WICPixelFormat32bppBGRA; + break; + default: + FIXME("unhandled extra sample type %u\n", extra_samples[0]); + return E_FAIL; + } + } + break; + case 16: + if (samples != 1) + { + FIXME("unhandled 16bpp grayscale sample count %u\n", samples); + return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + } + decode_info->frame.pixel_format = GUID_WICPixelFormat16bppGray; + break; + case 32: + if (samples != 1) + { + FIXME("unhandled 32bpp grayscale sample count %u\n", samples); + return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + } + decode_info->frame.pixel_format = GUID_WICPixelFormat32bppGrayFloat; + break; + default: + WARN("unhandled greyscale bit count %u\n", bps); + return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + } + break; + case 2: /* RGB */ + if (samples == 4) + { + ret = TIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &extra_sample_count, &extra_samples); + if (!ret) + { + extra_sample_count = 1; + extra_sample = 0; + extra_samples = &extra_sample; + } + } + else if (samples != 3) + { + FIXME("unhandled RGB sample count %u\n", samples); + return E_FAIL; + } + + decode_info->frame.bpp = max(bps, 8) * samples; + decode_info->source_bpp = bps * samples; + switch(bps) + { + case 1: + case 4: + case 8: + decode_info->reverse_bgr = 1; + if (samples == 3) + decode_info->frame.pixel_format = GUID_WICPixelFormat24bppBGR; + else + switch(extra_samples[0]) + { + case 1: /* Associated (pre-multiplied) alpha data */ + decode_info->frame.pixel_format = GUID_WICPixelFormat32bppPBGRA; + break; + case 0: /* Unspecified data */ + case 2: /* Unassociated alpha data */ + decode_info->frame.pixel_format = GUID_WICPixelFormat32bppBGRA; + break; + default: + FIXME("unhandled extra sample type %i\n", extra_samples[0]); + return E_FAIL; + } + break; + case 16: + if (samples == 3) + decode_info->frame.pixel_format = GUID_WICPixelFormat48bppRGB; + else + switch(extra_samples[0]) + { + case 1: /* Associated (pre-multiplied) alpha data */ + decode_info->frame.pixel_format = GUID_WICPixelFormat64bppPRGBA; + break; + case 0: /* Unspecified data */ + case 2: /* Unassociated alpha data */ + decode_info->frame.pixel_format = GUID_WICPixelFormat64bppRGBA; + break; + default: + FIXME("unhandled extra sample type %i\n", extra_samples[0]); + return E_FAIL; + } + break; + case 32: + if (samples == 3) + decode_info->frame.pixel_format = GUID_WICPixelFormat96bppRGBFloat; + else + switch(extra_samples[0]) + { + case 1: /* Associated (pre-multiplied) alpha data */ + decode_info->frame.pixel_format = GUID_WICPixelFormat128bppPRGBAFloat; + break; + case 0: /* Unspecified data */ + case 2: /* Unassociated alpha data */ + decode_info->frame.pixel_format = GUID_WICPixelFormat128bppRGBAFloat; + break; + default: + FIXME("unhandled extra sample type %i\n", extra_samples[0]); + return E_FAIL; + } + break; + default: + WARN("unhandled RGB bit count %u\n", bps); + return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + } + break; + case 3: /* RGB Palette */ + if (samples != 1) + { + FIXME("unhandled indexed sample count %u\n", samples); + return E_FAIL; + } + + decode_info->indexed = 1; + decode_info->frame.bpp = bps; + switch (bps) + { + case 1: + decode_info->frame.pixel_format = GUID_WICPixelFormat1bppIndexed; + break; + case 2: + decode_info->frame.pixel_format = GUID_WICPixelFormat2bppIndexed; + break; + case 4: + decode_info->frame.pixel_format = GUID_WICPixelFormat4bppIndexed; + break; + case 8: + decode_info->frame.pixel_format = GUID_WICPixelFormat8bppIndexed; + break; + default: + FIXME("unhandled indexed bit count %u\n", bps); + return E_NOTIMPL; + } + break; + + case 5: /* Separated */ + if (samples != 4) + { + FIXME("unhandled Separated sample count %u\n", samples); + return E_FAIL; + } + + decode_info->frame.bpp = bps * samples; + switch(bps) + { + case 8: + decode_info->frame.pixel_format = GUID_WICPixelFormat32bppCMYK; + break; + case 16: + decode_info->frame.pixel_format = GUID_WICPixelFormat64bppCMYK; + break; + + default: + WARN("unhandled Separated bit count %u\n", bps); + return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + } + break; + + case 4: /* Transparency mask */ + case 6: /* YCbCr */ + case 8: /* CIELab */ + default: + FIXME("unhandled PhotometricInterpretation %u\n", photometric); + return E_FAIL; + } + + ret = TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &decode_info->frame.width); + if (!ret) + { + WARN("missing image width\n"); + return E_FAIL; + } + + ret = TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &decode_info->frame.height); + if (!ret) + { + WARN("missing image length\n"); + return E_FAIL; + } + + if ((ret = TIFFGetField(tiff, TIFFTAG_TILEWIDTH, &decode_info->tile_width))) + { + decode_info->tiled = 1; + + ret = TIFFGetField(tiff, TIFFTAG_TILELENGTH, &decode_info->tile_height); + if (!ret) + { + WARN("missing tile height\n"); + return E_FAIL; + } + + decode_info->tile_stride = ((decode_info->frame.bpp * decode_info->tile_width + 7)/8); + decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride; + decode_info->tiles_across = (decode_info->frame.width + decode_info->tile_width - 1) / decode_info->tile_width; + } + else if ((ret = TIFFGetField(tiff, TIFFTAG_ROWSPERSTRIP, &decode_info->tile_height))) + { + if (decode_info->tile_height > decode_info->frame.height) + decode_info->tile_height = decode_info->frame.height; + decode_info->tile_width = decode_info->frame.width; + decode_info->tile_stride = ((decode_info->frame.bpp * decode_info->tile_width + 7)/8); + decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride; + } + else + { + /* Some broken TIFF files have a single strip and lack the RowsPerStrip tag */ + decode_info->tile_height = decode_info->frame.height; + decode_info->tile_width = decode_info->frame.width; + decode_info->tile_stride = ((decode_info->frame.bpp * decode_info->tile_width + 7)/8); + decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride; + } + + resolution_unit = 0; + TIFFGetField(tiff, TIFFTAG_RESOLUTIONUNIT, &resolution_unit); + + ret = TIFFGetField(tiff, TIFFTAG_XRESOLUTION, &xres); + if (!ret) + { + WARN("missing X resolution\n"); + } + /* Emulate the behavior of current libtiff versions (libtiff commit a39f6131) + * yielding 0 instead of INFINITY for IFD_RATIONAL fields with denominator 0. */ + if (!isfinite(xres)) + { + xres = 0.0; + } + + ret = TIFFGetField(tiff, TIFFTAG_YRESOLUTION, &yres); + if (!ret) + { + WARN("missing Y resolution\n"); + } + if (!isfinite(yres)) + { + yres = 0.0; + } + + if (xres == 0.0 || yres == 0.0) + { + decode_info->frame.dpix = decode_info->frame.dpiy = 96.0; + } + else + { + switch (resolution_unit) + { + default: + FIXME("unknown resolution unit %i\n", resolution_unit); + /* fall through */ + case 0: /* Not set */ + case 1: /* Relative measurements */ + case 2: /* Inch */ + decode_info->frame.dpix = xres; + decode_info->frame.dpiy = yres; + break; + case 3: /* Centimeter */ + decode_info->frame.dpix = xres * 2.54; + decode_info->frame.dpiy = yres * 2.54; + break; + } + } + + if (decode_info->indexed && + TIFFGetField(tiff, TIFFTAG_COLORMAP, &red, &green, &blue)) + { + decode_info->frame.num_colors = 1 << decode_info->bps; + for (i=0; iframe.num_colors; i++) + { + decode_info->frame.palette[i] = 0xff000000 | + ((red[i]<<8) & 0xff0000) | + (green[i] & 0xff00) | + ((blue[i]>>8) & 0xff); + } + } + else + { + decode_info->frame.num_colors = 0; + } + + if (TIFFGetField(tiff, TIFFTAG_ICCPROFILE, &len, &profile)) + decode_info->frame.num_color_contexts = 1; + else + decode_info->frame.num_color_contexts = 0; + + return S_OK; +} + +static HRESULT CDECL tiff_decoder_initialize(struct decoder* iface, IStream *stream, struct decoder_stat *st) +{ + struct tiff_decoder *This = impl_from_decoder(iface); + HRESULT hr; + + This->tiff = tiff_open_stream(stream, "r"); + if (!This->tiff) + return E_FAIL; + + This->frame_count = TIFFNumberOfDirectories(This->tiff); + This->cached_frame = 0; + hr = tiff_get_decode_info(This->tiff, &This->cached_decode_info); + if (FAILED(hr)) + goto fail; + + st->frame_count = This->frame_count; + st->flags = WICBitmapDecoderCapabilityCanDecodeAllImages | + WICBitmapDecoderCapabilityCanDecodeSomeImages | + WICBitmapDecoderCapabilityCanEnumerateMetadata; + return S_OK; + +fail: + TIFFClose(This->tiff); + This->tiff = NULL; + return hr; +} + +static HRESULT tiff_decoder_select_frame(struct tiff_decoder* This, DWORD frame) +{ + HRESULT hr; + UINT prev_tile_size; + int res; + + if (frame >= This->frame_count) + return E_INVALIDARG; + + if (This->cached_frame == frame) + return S_OK; + + prev_tile_size = This->cached_tile ? This->cached_decode_info.tile_size : 0; + + res = TIFFSetDirectory(This->tiff, frame); + if (!res) + return E_INVALIDARG; + + hr = tiff_get_decode_info(This->tiff, &This->cached_decode_info); + + This->cached_tile_x = -1; + + if (SUCCEEDED(hr)) + { + This->cached_frame = frame; + if (This->cached_decode_info.tile_size > prev_tile_size) + { + free(This->cached_tile); + This->cached_tile = NULL; + } + } + else + { + /* Set an invalid value to ensure we'll refresh cached_decode_info before using it. */ + This->cached_frame = This->frame_count; + free(This->cached_tile); + This->cached_tile = NULL; + } + + return hr; +} + +static HRESULT CDECL tiff_decoder_get_frame_info(struct decoder* iface, UINT frame, struct decoder_frame *info) +{ + struct tiff_decoder *This = impl_from_decoder(iface); + HRESULT hr; + + hr = tiff_decoder_select_frame(This, frame); + if (SUCCEEDED(hr)) + { + *info = This->cached_decode_info.frame; + } + + return hr; +} + +static HRESULT tiff_decoder_read_tile(struct tiff_decoder *This, UINT tile_x, UINT tile_y) +{ + tsize_t ret; + int swap_bytes; + tiff_decode_info *info = &This->cached_decode_info; + + swap_bytes = TIFFIsByteSwapped(This->tiff); + + if (info->tiled) + ret = TIFFReadEncodedTile(This->tiff, tile_x + tile_y * info->tiles_across, This->cached_tile, info->tile_size); + else + ret = TIFFReadEncodedStrip(This->tiff, tile_y, This->cached_tile, info->tile_size); + + if (ret == -1) + return E_FAIL; + + /* 3bps RGB */ + if (info->source_bpp == 3 && info->samples == 3 && info->frame.bpp == 24) + { + BYTE *srcdata, *src, *dst; + DWORD x, y, count, width_bytes = (info->tile_width * 3 + 7) / 8; + + count = width_bytes * info->tile_height; + + srcdata = malloc(count); + if (!srcdata) return E_OUTOFMEMORY; + memcpy(srcdata, This->cached_tile, count); + + for (y = 0; y < info->tile_height; y++) + { + src = srcdata + y * width_bytes; + dst = This->cached_tile + y * info->tile_width * 3; + + for (x = 0; x < info->tile_width; x += 8) + { + dst[2] = (src[0] & 0x80) ? 0xff : 0; /* R */ + dst[1] = (src[0] & 0x40) ? 0xff : 0; /* G */ + dst[0] = (src[0] & 0x20) ? 0xff : 0; /* B */ + if (x + 1 < info->tile_width) + { + dst[5] = (src[0] & 0x10) ? 0xff : 0; /* R */ + dst[4] = (src[0] & 0x08) ? 0xff : 0; /* G */ + dst[3] = (src[0] & 0x04) ? 0xff : 0; /* B */ + } + if (x + 2 < info->tile_width) + { + dst[8] = (src[0] & 0x02) ? 0xff : 0; /* R */ + dst[7] = (src[0] & 0x01) ? 0xff : 0; /* G */ + dst[6] = (src[1] & 0x80) ? 0xff : 0; /* B */ + } + if (x + 3 < info->tile_width) + { + dst[11] = (src[1] & 0x40) ? 0xff : 0; /* R */ + dst[10] = (src[1] & 0x20) ? 0xff : 0; /* G */ + dst[9] = (src[1] & 0x10) ? 0xff : 0; /* B */ + } + if (x + 4 < info->tile_width) + { + dst[14] = (src[1] & 0x08) ? 0xff : 0; /* R */ + dst[13] = (src[1] & 0x04) ? 0xff : 0; /* G */ + dst[12] = (src[1] & 0x02) ? 0xff : 0; /* B */ + } + if (x + 5 < info->tile_width) + { + dst[17] = (src[1] & 0x01) ? 0xff : 0; /* R */ + dst[16] = (src[2] & 0x80) ? 0xff : 0; /* G */ + dst[15] = (src[2] & 0x40) ? 0xff : 0; /* B */ + } + if (x + 6 < info->tile_width) + { + dst[20] = (src[2] & 0x20) ? 0xff : 0; /* R */ + dst[19] = (src[2] & 0x10) ? 0xff : 0; /* G */ + dst[18] = (src[2] & 0x08) ? 0xff : 0; /* B */ + } + if (x + 7 < info->tile_width) + { + dst[23] = (src[2] & 0x04) ? 0xff : 0; /* R */ + dst[22] = (src[2] & 0x02) ? 0xff : 0; /* G */ + dst[21] = (src[2] & 0x01) ? 0xff : 0; /* B */ + } + src += 3; + dst += 24; + } + } + + free(srcdata); + } + /* 12bps RGB */ + else if (info->source_bpp == 12 && info->samples == 3 && info->frame.bpp == 24) + { + BYTE *srcdata, *src, *dst; + DWORD x, y, count, width_bytes = (info->tile_width * 12 + 7) / 8; + + count = width_bytes * info->tile_height; + + srcdata = malloc(count); + if (!srcdata) return E_OUTOFMEMORY; + memcpy(srcdata, This->cached_tile, count); + + for (y = 0; y < info->tile_height; y++) + { + src = srcdata + y * width_bytes; + dst = This->cached_tile + y * info->tile_width * 3; + + for (x = 0; x < info->tile_width; x += 2) + { + dst[0] = ((src[1] & 0xf0) >> 4) * 17; /* B */ + dst[1] = (src[0] & 0x0f) * 17; /* G */ + dst[2] = ((src[0] & 0xf0) >> 4) * 17; /* R */ + if (x + 1 < info->tile_width) + { + dst[5] = (src[1] & 0x0f) * 17; /* B */ + dst[4] = ((src[2] & 0xf0) >> 4) * 17; /* G */ + dst[3] = (src[2] & 0x0f) * 17; /* R */ + } + src += 3; + dst += 6; + } + } + + free(srcdata); + } + /* 4bps RGBA */ + else if (info->source_bpp == 4 && info->samples == 4 && info->frame.bpp == 32) + { + BYTE *srcdata, *src, *dst; + DWORD x, y, count, width_bytes = (info->tile_width * 3 + 7) / 8; + + count = width_bytes * info->tile_height; + + srcdata = malloc(count); + if (!srcdata) return E_OUTOFMEMORY; + memcpy(srcdata, This->cached_tile, count); + + for (y = 0; y < info->tile_height; y++) + { + src = srcdata + y * width_bytes; + dst = This->cached_tile + y * info->tile_width * 4; + + /* 1 source byte expands to 2 BGRA samples */ + + for (x = 0; x < info->tile_width; x += 2) + { + dst[0] = (src[0] & 0x20) ? 0xff : 0; /* B */ + dst[1] = (src[0] & 0x40) ? 0xff : 0; /* G */ + dst[2] = (src[0] & 0x80) ? 0xff : 0; /* R */ + dst[3] = (src[0] & 0x10) ? 0xff : 0; /* A */ + if (x + 1 < info->tile_width) + { + dst[4] = (src[0] & 0x02) ? 0xff : 0; /* B */ + dst[5] = (src[0] & 0x04) ? 0xff : 0; /* G */ + dst[6] = (src[0] & 0x08) ? 0xff : 0; /* R */ + dst[7] = (src[0] & 0x01) ? 0xff : 0; /* A */ + } + src++; + dst += 8; + } + } + + free(srcdata); + } + /* 16bps RGBA */ + else if (info->source_bpp == 16 && info->samples == 4 && info->frame.bpp == 32) + { + BYTE *srcdata, *src, *dst; + DWORD x, y, count, width_bytes = (info->tile_width * 12 + 7) / 8; + + count = width_bytes * info->tile_height; + + srcdata = malloc(count); + if (!srcdata) return E_OUTOFMEMORY; + memcpy(srcdata, This->cached_tile, count); + + for (y = 0; y < info->tile_height; y++) + { + src = srcdata + y * width_bytes; + dst = This->cached_tile + y * info->tile_width * 4; + + for (x = 0; x < info->tile_width; x++) + { + dst[0] = ((src[1] & 0xf0) >> 4) * 17; /* B */ + dst[1] = (src[0] & 0x0f) * 17; /* G */ + dst[2] = ((src[0] & 0xf0) >> 4) * 17; /* R */ + dst[3] = (src[1] & 0x0f) * 17; /* A */ + src += 2; + dst += 4; + } + } + + free(srcdata); + } + /* 8bpp grayscale with extra alpha */ + else if (info->source_bpp == 16 && info->samples == 2 && info->frame.bpp == 32) + { + BYTE *src; + DWORD *dst, count = info->tile_width * info->tile_height; + + src = This->cached_tile + info->tile_width * info->tile_height * 2 - 2; + dst = (DWORD *)(This->cached_tile + info->tile_size - 4); + + while (count--) + { + *dst-- = src[0] | (src[0] << 8) | (src[0] << 16) | (src[1] << 24); + src -= 2; + } + } + + if (info->reverse_bgr) + { + if (info->bps == 8) + { + UINT sample_count = info->samples; + + reverse_bgr8(sample_count, This->cached_tile, info->tile_width, + info->tile_height, info->tile_width * sample_count); + } + } + + if (swap_bytes && info->bps > 8) + { + UINT row, i, samples_per_row; + BYTE *sample, temp; + + samples_per_row = info->tile_width * info->samples; + + switch(info->bps) + { + case 16: + for (row=0; rowtile_height; row++) + { + sample = This->cached_tile + row * info->tile_stride; + for (i=0; ibps); + return E_FAIL; + } + } + + if (info->invert_grayscale) + { + BYTE *byte, *end; + + if (info->samples != 1) + { + ERR("cannot invert grayscale image with %u samples\n", info->samples); + return E_FAIL; + } + + end = This->cached_tile+info->tile_size; + + for (byte = This->cached_tile; byte != end; byte++) + *byte = ~(*byte); + } + + This->cached_tile_x = tile_x; + This->cached_tile_y = tile_y; + + return S_OK; +} + +static HRESULT CDECL tiff_decoder_copy_pixels(struct decoder* iface, UINT frame, + const WICRect *prc, UINT stride, UINT buffersize, BYTE *buffer) +{ + struct tiff_decoder *This = impl_from_decoder(iface); + HRESULT hr; + UINT min_tile_x, max_tile_x, min_tile_y, max_tile_y; + UINT tile_x, tile_y; + BYTE *dst_tilepos; + WICRect rc; + tiff_decode_info *info = &This->cached_decode_info; + + hr = tiff_decoder_select_frame(This, frame); + if (FAILED(hr)) + return hr; + + if (!This->cached_tile) + { + This->cached_tile = malloc(info->tile_size); + if (!This->cached_tile) + return E_OUTOFMEMORY; + } + + min_tile_x = prc->X / info->tile_width; + min_tile_y = prc->Y / info->tile_height; + max_tile_x = (prc->X+prc->Width-1) / info->tile_width; + max_tile_y = (prc->Y+prc->Height-1) / info->tile_height; + + for (tile_x=min_tile_x; tile_x <= max_tile_x; tile_x++) + { + for (tile_y=min_tile_y; tile_y <= max_tile_y; tile_y++) + { + if (tile_x != This->cached_tile_x || tile_y != This->cached_tile_y) + { + hr = tiff_decoder_read_tile(This, tile_x, tile_y); + } + + if (SUCCEEDED(hr)) + { + if (prc->X < tile_x * info->tile_width) + rc.X = 0; + else + rc.X = prc->X - tile_x * info->tile_width; + + if (prc->Y < tile_y * info->tile_height) + rc.Y = 0; + else + rc.Y = prc->Y - tile_y * info->tile_height; + + if (prc->X+prc->Width > (tile_x+1) * info->tile_width) + rc.Width = info->tile_width - rc.X; + else if (prc->X < tile_x * info->tile_width) + rc.Width = prc->Width + prc->X - tile_x * info->tile_width; + else + rc.Width = prc->Width; + + if (prc->Y+prc->Height > (tile_y+1) * info->tile_height) + rc.Height = info->tile_height - rc.Y; + else if (prc->Y < tile_y * info->tile_height) + rc.Height = prc->Height + prc->Y - tile_y * info->tile_height; + else + rc.Height = prc->Height; + + dst_tilepos = buffer + (stride * ((rc.Y + tile_y * info->tile_height) - prc->Y)) + + ((info->frame.bpp * ((rc.X + tile_x * info->tile_width) - prc->X) + 7) / 8); + + hr = copy_pixels(info->frame.bpp, This->cached_tile, + info->tile_width, info->tile_height, info->tile_stride, + &rc, stride, buffersize, dst_tilepos); + } + + if (FAILED(hr)) + { + TRACE("<-- 0x%lx\n", hr); + return hr; + } + } + } + + return S_OK; +} + +static HRESULT CDECL tiff_decoder_get_color_context(struct decoder *iface, + UINT frame, UINT num, BYTE **data, DWORD *datasize) +{ + struct tiff_decoder *This = impl_from_decoder(iface); + const BYTE *profile; + UINT len; + HRESULT hr; + + hr = tiff_decoder_select_frame(This, frame); + if (FAILED(hr)) + return hr; + + if (!TIFFGetField(This->tiff, TIFFTAG_ICCPROFILE, &len, &profile)) + { + return E_UNEXPECTED; + } + + *datasize = len; + *data = malloc(len); + if (!*data) + return E_OUTOFMEMORY; + + memcpy(*data, profile, len); + + return S_OK; +} + +static HRESULT CDECL tiff_decoder_get_metadata_blocks(struct decoder *iface, + UINT frame, UINT *count, struct decoder_block **blocks) +{ + struct tiff_decoder *This = impl_from_decoder(iface); + HRESULT hr; + BOOL byte_swapped; + struct decoder_block result; + + hr = tiff_decoder_select_frame(This, frame); + if (FAILED(hr)) + return hr; + + *count = 1; + + result.offset = TIFFCurrentDirOffset(This->tiff); + result.length = 0; + + byte_swapped = TIFFIsByteSwapped(This->tiff); +#ifdef WORDS_BIGENDIAN + result.options = byte_swapped ? WICPersistOptionLittleEndian : WICPersistOptionBigEndian; +#else + result.options = byte_swapped ? WICPersistOptionBigEndian : WICPersistOptionLittleEndian; +#endif + result.options |= WICPersistOptionNoCacheStream|DECODER_BLOCK_FULL_STREAM|DECODER_BLOCK_READER_CLSID; + result.reader_clsid = CLSID_WICIfdMetadataReader; + + *blocks = malloc(sizeof(**blocks)); + **blocks = result; + + return S_OK; +} + +static void CDECL tiff_decoder_destroy(struct decoder* iface) +{ + struct tiff_decoder *This = impl_from_decoder(iface); + if (This->tiff) TIFFClose(This->tiff); + free(This->cached_tile); + free(This); +} + +static const struct decoder_funcs tiff_decoder_vtable = { + tiff_decoder_initialize, + tiff_decoder_get_frame_info, + tiff_decoder_copy_pixels, + tiff_decoder_get_metadata_blocks, + tiff_decoder_get_color_context, + tiff_decoder_destroy +}; + +HRESULT CDECL tiff_decoder_create(struct decoder_info *info, struct decoder **result) +{ + struct tiff_decoder *This; + + This = malloc(sizeof(*This)); + if (!This) return E_OUTOFMEMORY; + + This->decoder.vtable = &tiff_decoder_vtable; + This->tiff = NULL; + This->cached_tile = NULL; + This->cached_tile_x = -1; + *result = &This->decoder; + + info->container_format = GUID_ContainerFormatTiff; + info->block_format = GUID_ContainerFormatTiff; + info->clsid = CLSID_WICTiffDecoder; + + TIFFSetErrorHandler( tiff_error_handler ); + TIFFSetWarningHandler( tiff_warning_handler ); + return S_OK; +} + +struct tiff_encode_format { + const WICPixelFormatGUID *guid; + int photometric; + int bps; + int samples; + int bpp; + int extra_sample; + int extra_sample_type; + int reverse_bgr; + int indexed; +}; + +static const struct tiff_encode_format formats[] = { + {&GUID_WICPixelFormat24bppBGR, 2, 8, 3, 24, 0, 0, 1}, + {&GUID_WICPixelFormat24bppRGB, 2, 8, 3, 24, 0, 0, 0}, + {&GUID_WICPixelFormatBlackWhite, 1, 1, 1, 1, 0, 0, 0}, + {&GUID_WICPixelFormat4bppGray, 1, 4, 1, 4, 0, 0, 0}, + {&GUID_WICPixelFormat8bppGray, 1, 8, 1, 8, 0, 0, 0}, + {&GUID_WICPixelFormat32bppBGRA, 2, 8, 4, 32, 1, 2, 1}, + {&GUID_WICPixelFormat32bppPBGRA, 2, 8, 4, 32, 1, 1, 1}, + {&GUID_WICPixelFormat48bppRGB, 2, 16, 3, 48, 0, 0, 0}, + {&GUID_WICPixelFormat64bppRGBA, 2, 16, 4, 64, 1, 2, 0}, + {&GUID_WICPixelFormat64bppPRGBA, 2, 16, 4, 64, 1, 1, 0}, + {&GUID_WICPixelFormat1bppIndexed, 3, 1, 1, 1, 0, 0, 0, 1}, + {&GUID_WICPixelFormat4bppIndexed, 3, 4, 1, 4, 0, 0, 0, 1}, + {&GUID_WICPixelFormat8bppIndexed, 3, 8, 1, 8, 0, 0, 0, 1}, + {0} +}; + +typedef struct tiff_encoder { + struct encoder encoder; + TIFF *tiff; + const struct tiff_encode_format *format; + struct encoder_frame encoder_frame; + DWORD num_frames; + DWORD lines_written; +} tiff_encoder; + +static inline struct tiff_encoder *impl_from_encoder(struct encoder* iface) +{ + return CONTAINING_RECORD(iface, struct tiff_encoder, encoder); +} + +static HRESULT CDECL tiff_encoder_initialize(struct encoder* iface, IStream *stream) +{ + struct tiff_encoder* This = impl_from_encoder(iface); + TIFF *tiff; + + tiff = tiff_open_stream(stream, "w"); + + if (!tiff) + return E_FAIL; + + This->tiff = tiff; + + return S_OK; +} + +static HRESULT CDECL tiff_encoder_get_supported_format(struct encoder *iface, + GUID *pixel_format, DWORD *bpp, BOOL *indexed) +{ + int i; + + if (IsEqualGUID(pixel_format, &GUID_WICPixelFormat2bppIndexed)) + *pixel_format = GUID_WICPixelFormat4bppIndexed; + + for (i=0; formats[i].guid; i++) + { + if (IsEqualGUID(formats[i].guid, pixel_format)) + break; + } + + if (!formats[i].guid) i = 0; + + *pixel_format = *formats[i].guid; + *bpp = formats[i].bpp; + *indexed = formats[i].indexed; + + return S_OK; +} + +static HRESULT CDECL tiff_encoder_create_frame(struct encoder* iface, const struct encoder_frame *frame) +{ + struct tiff_encoder* This = impl_from_encoder(iface); + int i; + + if (This->num_frames != 0) + TIFFWriteDirectory(This->tiff); + + This->num_frames++; + This->lines_written = 0; + This->encoder_frame = *frame; + + for (i=0; formats[i].guid; i++) + { + if (IsEqualGUID(formats[i].guid, &frame->pixel_format)) + break; + } + + This->format = &formats[i]; + + TIFFSetField(This->tiff, TIFFTAG_PHOTOMETRIC, (uint16_t)This->format->photometric); + TIFFSetField(This->tiff, TIFFTAG_PLANARCONFIG, (uint16_t)1); + TIFFSetField(This->tiff, TIFFTAG_BITSPERSAMPLE, (uint16_t)This->format->bps); + TIFFSetField(This->tiff, TIFFTAG_SAMPLESPERPIXEL, (uint16_t)This->format->samples); + + if (This->format->extra_sample) + { + uint16_t extra_samples; + extra_samples = This->format->extra_sample_type; + + TIFFSetField(This->tiff, TIFFTAG_EXTRASAMPLES, (uint16_t)1, &extra_samples); + } + + TIFFSetField(This->tiff, TIFFTAG_IMAGEWIDTH, (uint32_t)frame->width); + TIFFSetField(This->tiff, TIFFTAG_IMAGELENGTH, (uint32_t)frame->height); + + if (frame->dpix != 0.0 && frame->dpiy != 0.0) + { + TIFFSetField(This->tiff, TIFFTAG_RESOLUTIONUNIT, (uint16_t)2); /* Inch */ + TIFFSetField(This->tiff, TIFFTAG_XRESOLUTION, (float)frame->dpix); + TIFFSetField(This->tiff, TIFFTAG_YRESOLUTION, (float)frame->dpiy); + } + + if (This->format->bpp <= 8 && frame->num_colors && This->format->indexed) + { + uint16_t red[256], green[256], blue[256]; + UINT i; + + for (i = 0; i < frame->num_colors; i++) + { + red[i] = (frame->palette[i] >> 8) & 0xff00; + green[i] = frame->palette[i] & 0xff00; + blue[i] = (frame->palette[i] << 8) & 0xff00; + } + + TIFFSetField(This->tiff, TIFFTAG_COLORMAP, red, green, blue); + } + + return S_OK; +} + +static HRESULT CDECL tiff_encoder_write_lines(struct encoder* iface, + BYTE *data, DWORD line_count, DWORD stride) +{ + struct tiff_encoder* This = impl_from_encoder(iface); + BYTE *row_data, *swapped_data = NULL; + UINT i, j, line_size; + + line_size = ((This->encoder_frame.width * This->format->bpp)+7)/8; + + if (This->format->reverse_bgr) + { + swapped_data = malloc(line_size); + if (!swapped_data) + return E_OUTOFMEMORY; + } + + for (i=0; iformat->reverse_bgr && This->format->bps == 8) + { + memcpy(swapped_data, row_data, line_size); + for (j=0; jformat->samples) + { + BYTE temp; + temp = swapped_data[j]; + swapped_data[j] = swapped_data[j+2]; + swapped_data[j+2] = temp; + } + row_data = swapped_data; + } + + TIFFWriteScanline(This->tiff, (tdata_t)row_data, i+This->lines_written, 0); + } + + This->lines_written += line_count; + + return S_OK; +} + +static HRESULT CDECL tiff_encoder_commit_frame(struct encoder* iface) +{ + return S_OK; +} + +static HRESULT CDECL tiff_encoder_commit_file(struct encoder* iface) +{ + struct tiff_encoder* This = impl_from_encoder(iface); + + TIFFClose(This->tiff); + This->tiff = NULL; + + return S_OK; +} + +static void CDECL tiff_encoder_destroy(struct encoder* iface) +{ + struct tiff_encoder *This = impl_from_encoder(iface); + + if (This->tiff) TIFFClose(This->tiff); + free(This); +} + +static const struct encoder_funcs tiff_encoder_vtable = { + tiff_encoder_initialize, + tiff_encoder_get_supported_format, + tiff_encoder_create_frame, + tiff_encoder_write_lines, + tiff_encoder_commit_frame, + tiff_encoder_commit_file, + tiff_encoder_destroy +}; + +HRESULT CDECL tiff_encoder_create(struct encoder_info *info, struct encoder **result) +{ + struct tiff_encoder *This; + + This = malloc(sizeof(*This)); + if (!This) return E_OUTOFMEMORY; + + This->encoder.vtable = &tiff_encoder_vtable; + This->tiff = NULL; + This->num_frames = 0; + + info->flags = ENCODER_FLAGS_MULTI_FRAME | ENCODER_FLAGS_SUPPORTS_METADATA; + info->container_format = GUID_ContainerFormatTiff; + info->clsid = CLSID_WICTiffEncoder; + info->encoder_options[0] = ENCODER_OPTION_COMPRESSION_METHOD; + info->encoder_options[1] = ENCODER_OPTION_COMPRESSION_QUALITY; + info->encoder_options[2] = ENCODER_OPTION_END; + + *result = &This->encoder; + + TIFFSetErrorHandler( tiff_error_handler ); + TIFFSetWarningHandler( tiff_warning_handler ); + return S_OK; +} diff --git a/dll/win32/windowscodecs/main.c b/dll/win32/windowscodecs/main.c index 751f4625133..aa542483c20 100644 --- a/dll/win32/windowscodecs/main.c +++ b/dll/win32/windowscodecs/main.c @@ -18,21 +18,21 @@ #define COBJMACROS -#include "config.h" #include #include "windef.h" #include "winbase.h" +#include "winternl.h" #include "objbase.h" #include "wincodecs_private.h" #include "wine/debug.h" -WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); +extern BOOL WINAPI WIC_DllMain(HINSTANCE, DWORD, LPVOID); -extern BOOL WINAPI WIC_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN; +HMODULE windowscodecs_module = 0; BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { @@ -41,8 +41,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); + windowscodecs_module = hinstDLL; break; case DLL_PROCESS_DETACH: + if (lpvReserved) break; ReleaseComponentInfos(); break; } @@ -50,204 +52,12 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) return WIC_DllMain(hinstDLL, fdwReason, lpvReserved); } +#ifdef __REACTOS__ HRESULT WINAPI DllCanUnloadNow(void) { return S_FALSE; } - -HRESULT copy_pixels(UINT bpp, const BYTE *srcbuffer, - UINT srcwidth, UINT srcheight, INT srcstride, - const WICRect *rc, UINT dststride, UINT dstbuffersize, BYTE *dstbuffer) -{ - UINT bytesperrow; - UINT row_offset; /* number of bits into the source rows where the data starts */ - WICRect rect; - - if (!rc) - { - rect.X = 0; - rect.Y = 0; - rect.Width = srcwidth; - rect.Height = srcheight; - rc = ▭ - } - else - { - if (rc->X < 0 || rc->Y < 0 || rc->X+rc->Width > srcwidth || rc->Y+rc->Height > srcheight) - return E_INVALIDARG; - } - - bytesperrow = ((bpp * rc->Width)+7)/8; - - if (dststride < bytesperrow) - return E_INVALIDARG; - - if ((dststride * (rc->Height-1)) + bytesperrow > dstbuffersize) - return E_INVALIDARG; - - /* if the whole bitmap is copied and the buffer format matches then it's a matter of a single memcpy */ - if (rc->X == 0 && rc->Y == 0 && rc->Width == srcwidth && rc->Height == srcheight && - srcstride == dststride && srcstride == bytesperrow) - { - memcpy(dstbuffer, srcbuffer, srcstride * srcheight); - return S_OK; - } - - row_offset = rc->X * bpp; - - if (row_offset % 8 == 0) - { - /* everything lines up on a byte boundary */ - INT row; - const BYTE *src; - BYTE *dst; - - src = srcbuffer + (row_offset / 8) + srcstride * rc->Y; - dst = dstbuffer; - for (row=0; row < rc->Height; row++) - { - memcpy(dst, src, bytesperrow); - src += srcstride; - dst += dststride; - } - return S_OK; - } - else - { - /* we have to do a weird bitwise copy. eww. */ - FIXME("cannot reliably copy bitmap data if bpp < 8\n"); - return E_FAIL; - } -} - -HRESULT configure_write_source(IWICBitmapFrameEncode *iface, - IWICBitmapSource *source, const WICRect *prc, - const WICPixelFormatGUID *format, - INT width, INT height, double xres, double yres) -{ - HRESULT hr = S_OK; - - if (width == 0 || height == 0) - return WINCODEC_ERR_WRONGSTATE; - - if (!format) - { - WICPixelFormatGUID src_format; - - hr = IWICBitmapSource_GetPixelFormat(source, &src_format); - if (FAILED(hr)) return hr; - - hr = IWICBitmapFrameEncode_SetPixelFormat(iface, &src_format); - if (FAILED(hr)) return hr; - } - - if (xres == 0.0 || yres == 0.0) - { - hr = IWICBitmapSource_GetResolution(source, &xres, &yres); - if (FAILED(hr)) return hr; - hr = IWICBitmapFrameEncode_SetResolution(iface, xres, yres); - if (FAILED(hr)) return hr; - } - - return hr; -} - -HRESULT write_source(IWICBitmapFrameEncode *iface, - IWICBitmapSource *source, const WICRect *prc, - const WICPixelFormatGUID *format, UINT bpp, - INT width, INT height) -{ - IWICBitmapSource *converted_source; - HRESULT hr=S_OK; - WICRect rc; - UINT stride; - BYTE* pixeldata; - - if (!prc) - { - UINT src_width, src_height; - hr = IWICBitmapSource_GetSize(source, &src_width, &src_height); - if (FAILED(hr)) return hr; - rc.X = 0; - rc.Y = 0; - rc.Width = src_width; - rc.Height = src_height; - prc = &rc; - } - - if (prc->Width != width || prc->Height <= 0) - return E_INVALIDARG; - - hr = WICConvertBitmapSource(format, source, &converted_source); - if (FAILED(hr)) - { - ERR("Failed to convert source, target format %s, %#x\n", debugstr_guid(format), hr); - return E_NOTIMPL; - } - - stride = (bpp * width + 7)/8; - - pixeldata = HeapAlloc(GetProcessHeap(), 0, stride * prc->Height); - if (!pixeldata) - { - IWICBitmapSource_Release(converted_source); - return E_OUTOFMEMORY; - } - - hr = IWICBitmapSource_CopyPixels(converted_source, prc, stride, - stride*prc->Height, pixeldata); - - if (SUCCEEDED(hr)) - { - hr = IWICBitmapFrameEncode_WritePixels(iface, prc->Height, stride, - stride*prc->Height, pixeldata); - } - - HeapFree(GetProcessHeap(), 0, pixeldata); - IWICBitmapSource_Release(converted_source); - - return hr; -} - -void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride) -{ - UINT x, y; - BYTE *pixel, temp; - - for (y=0; y #include #define COBJMACROS -#define NONAMELESSUNION - #include "windef.h" #include "winbase.h" -#include "wine/winternl.h" +#include "winternl.h" #include "objbase.h" #include "propvarutil.h" @@ -41,6 +37,7 @@ typedef struct MetadataHandler { IWICMetadataWriter IWICMetadataWriter_iface; LONG ref; IWICPersistStream IWICPersistStream_iface; + IWICStreamProvider IWICStreamProvider_iface; const MetadataHandlerVtbl *vtable; MetadataItem *items; DWORD item_count; @@ -57,6 +54,11 @@ static inline MetadataHandler *impl_from_IWICPersistStream(IWICPersistStream *if return CONTAINING_RECORD(iface, MetadataHandler, IWICPersistStream_iface); } +static inline MetadataHandler *impl_from_IWICStreamProvider(IWICStreamProvider *iface) +{ + return CONTAINING_RECORD(iface, MetadataHandler, IWICStreamProvider_iface); +} + static void MetadataHandler_FreeItems(MetadataHandler *This) { DWORD i; @@ -68,7 +70,9 @@ static void MetadataHandler_FreeItems(MetadataHandler *This) PropVariantClear(&This->items[i].value); } - HeapFree(GetProcessHeap(), 0, This->items); + free(This->items); + This->items = NULL; + This->item_count = 0; } static HRESULT MetadataHandlerEnum_Create(MetadataHandler *parent, DWORD index, @@ -94,6 +98,10 @@ static HRESULT WINAPI MetadataHandler_QueryInterface(IWICMetadataWriter *iface, { *ppv = &This->IWICPersistStream_iface; } + else if (IsEqualIID(&IID_IWICStreamProvider, iid)) + { + *ppv = &This->IWICStreamProvider_iface; + } else { *ppv = NULL; @@ -109,7 +117,7 @@ static ULONG WINAPI MetadataHandler_AddRef(IWICMetadataWriter *iface) MetadataHandler *This = impl_from_IWICMetadataWriter(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -119,14 +127,14 @@ static ULONG WINAPI MetadataHandler_Release(IWICMetadataWriter *iface) MetadataHandler *This = impl_from_IWICMetadataWriter(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { MetadataHandler_FreeItems(This); This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -349,19 +357,22 @@ static HRESULT WINAPI MetadataHandler_GetSizeMax(IWICPersistStream *iface, } static HRESULT WINAPI MetadataHandler_LoadEx(IWICPersistStream *iface, - IStream *pIStream, const GUID *pguidPreferredVendor, DWORD dwPersistOptions) + IStream *stream, const GUID *pguidPreferredVendor, DWORD dwPersistOptions) { MetadataHandler *This = impl_from_IWICPersistStream(iface); - HRESULT hr; + HRESULT hr = S_OK; MetadataItem *new_items=NULL; DWORD item_count=0; - TRACE("(%p,%p,%s,%x)\n", iface, pIStream, debugstr_guid(pguidPreferredVendor), dwPersistOptions); + TRACE("(%p,%p,%s,%lx)\n", iface, stream, debugstr_guid(pguidPreferredVendor), dwPersistOptions); EnterCriticalSection(&This->lock); - hr = This->vtable->fnLoad(pIStream, pguidPreferredVendor, dwPersistOptions, - &new_items, &item_count); + if (stream) + { + hr = This->vtable->fnLoad(stream, pguidPreferredVendor, dwPersistOptions, + &new_items, &item_count); + } if (SUCCEEDED(hr)) { @@ -378,7 +389,7 @@ static HRESULT WINAPI MetadataHandler_LoadEx(IWICPersistStream *iface, static HRESULT WINAPI MetadataHandler_SaveEx(IWICPersistStream *iface, IStream *pIStream, DWORD dwPersistOptions, BOOL fClearDirty) { - FIXME("(%p,%p,%x,%i): stub\n", iface, pIStream, dwPersistOptions, fClearDirty); + FIXME("(%p,%p,%lx,%i): stub\n", iface, pIStream, dwPersistOptions, fClearDirty); return E_NOTIMPL; } @@ -395,6 +406,63 @@ static const IWICPersistStreamVtbl MetadataHandler_PersistStream_Vtbl = { MetadataHandler_SaveEx }; +static HRESULT WINAPI metadatahandler_stream_provider_QueryInterface(IWICStreamProvider *iface, REFIID iid, void **ppv) +{ + MetadataHandler *handler = impl_from_IWICStreamProvider(iface); + return IWICMetadataWriter_QueryInterface(&handler->IWICMetadataWriter_iface, iid, ppv); +} + +static ULONG WINAPI metadatahandler_stream_provider_AddRef(IWICStreamProvider *iface) +{ + MetadataHandler *handler = impl_from_IWICStreamProvider(iface); + return IWICMetadataWriter_AddRef(&handler->IWICMetadataWriter_iface); +} + +static ULONG WINAPI metadatahandler_stream_provider_Release(IWICStreamProvider *iface) +{ + MetadataHandler *handler = impl_from_IWICStreamProvider(iface); + return IWICMetadataWriter_Release(&handler->IWICMetadataWriter_iface); +} + +static HRESULT WINAPI metadatahandler_stream_provider_GetStream(IWICStreamProvider *iface, IStream **stream) +{ + FIXME("%p, %p stub\n", iface, stream); + + return E_NOTIMPL; +} + +static HRESULT WINAPI metadatahandler_stream_provider_GetPersistOptions(IWICStreamProvider *iface, DWORD *options) +{ + FIXME("%p, %p stub\n", iface, options); + + return E_NOTIMPL; +} + +static HRESULT WINAPI metadatahandler_stream_provider_GetPreferredVendorGUID(IWICStreamProvider *iface, GUID *guid) +{ + FIXME("%p, %p stub\n", iface, guid); + + return E_NOTIMPL; +} + +static HRESULT WINAPI metadatahandler_stream_provider_RefreshStream(IWICStreamProvider *iface) +{ + FIXME("%p stub\n", iface); + + return E_NOTIMPL; +} + +static const IWICStreamProviderVtbl MetadataHandler_StreamProvider_Vtbl = +{ + metadatahandler_stream_provider_QueryInterface, + metadatahandler_stream_provider_AddRef, + metadatahandler_stream_provider_Release, + metadatahandler_stream_provider_GetStream, + metadatahandler_stream_provider_GetPersistOptions, + metadatahandler_stream_provider_GetPreferredVendorGUID, + metadatahandler_stream_provider_RefreshStream, +}; + HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, REFIID iid, void** ppv) { MetadataHandler *This; @@ -404,17 +472,22 @@ HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, REFIID iid, voi *ppv = NULL; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataHandler)); + This = malloc(sizeof(MetadataHandler)); if (!This) return E_OUTOFMEMORY; This->IWICMetadataWriter_iface.lpVtbl = &MetadataHandler_Vtbl; This->IWICPersistStream_iface.lpVtbl = &MetadataHandler_PersistStream_Vtbl; + This->IWICStreamProvider_iface.lpVtbl = &MetadataHandler_StreamProvider_Vtbl; This->ref = 1; This->vtable = vtable; This->items = NULL; This->item_count = 0; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": MetadataHandler.lock"); hr = IWICMetadataWriter_QueryInterface(&This->IWICMetadataWriter_iface, iid, ppv); @@ -464,7 +537,7 @@ static ULONG WINAPI MetadataHandlerEnum_AddRef(IWICEnumMetadataItem *iface) MetadataHandlerEnum *This = impl_from_IWICEnumMetadataItem(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -474,12 +547,12 @@ static ULONG WINAPI MetadataHandlerEnum_Release(IWICEnumMetadataItem *iface) MetadataHandlerEnum *This = impl_from_IWICEnumMetadataItem(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { IWICMetadataWriter_Release(&This->parent->IWICMetadataWriter_iface); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -493,8 +566,12 @@ static HRESULT WINAPI MetadataHandlerEnum_Next(IWICEnumMetadataItem *iface, ULONG new_index; HRESULT hr=S_FALSE; ULONG i; + ULONG fetched; - TRACE("(%p,%i)\n", iface, celt); + TRACE("(%p,%li)\n", iface, celt); + + if (!pceltFetched) + pceltFetched = &fetched; EnterCriticalSection(&This->parent->lock); @@ -594,7 +671,7 @@ static HRESULT MetadataHandlerEnum_Create(MetadataHandler *parent, DWORD index, *ppIEnumMetadataItem = NULL; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataHandlerEnum)); + This = malloc(sizeof(MetadataHandlerEnum)); if (!This) return E_OUTOFMEMORY; IWICMetadataWriter_AddRef(&parent->IWICMetadataWriter_iface); @@ -624,21 +701,21 @@ static HRESULT LoadUnknownMetadata(IStream *input, const GUID *preferred_vendor, if (FAILED(hr)) return hr; - data = HeapAlloc(GetProcessHeap(), 0, stat.cbSize.QuadPart); + data = CoTaskMemAlloc(stat.cbSize.QuadPart); if (!data) return E_OUTOFMEMORY; hr = IStream_Read(input, data, stat.cbSize.QuadPart, &bytesread); if (bytesread != stat.cbSize.QuadPart) hr = E_FAIL; if (hr != S_OK) { - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(data); return hr; } - result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem)); + result = calloc(1, sizeof(MetadataItem)); if (!result) { - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(data); return E_OUTOFMEMORY; } @@ -647,8 +724,8 @@ static HRESULT LoadUnknownMetadata(IStream *input, const GUID *preferred_vendor, PropVariantInit(&result[0].value); result[0].value.vt = VT_BLOB; - result[0].value.u.blob.cbSize = bytesread; - result[0].value.u.blob.pBlobData = data; + result[0].value.blob.cbSize = bytesread; + result[0].value.blob.pBlobData = data; *items = result; *item_count = 1; @@ -718,15 +795,15 @@ static int tag_to_vt(SHORT tag) static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, MetadataItem *item, BOOL native_byte_order) { - ULONG count, value, i; + ULONG count, value, i, bytesread; SHORT type; LARGE_INTEGER pos; HRESULT hr; item->schema.vt = VT_EMPTY; item->id.vt = VT_UI2; - item->id.u.uiVal = entry->id; - SWAP_USHORT(item->id.u.uiVal); + item->id.uiVal = entry->id; + SWAP_USHORT(item->id.uiVal); count = entry->count; SWAP_ULONG(count); @@ -747,33 +824,34 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, const BYTE *data = (const BYTE *)&entry->value; if (count == 1) - item->value.u.bVal = data[0]; + item->value.bVal = data[0]; else { item->value.vt |= VT_VECTOR; - item->value.u.caub.cElems = count; - item->value.u.caub.pElems = HeapAlloc(GetProcessHeap(), 0, count); - memcpy(item->value.u.caub.pElems, data, count); + item->value.caub.cElems = count; + item->value.caub.pElems = CoTaskMemAlloc(count); + memcpy(item->value.caub.pElems, data, count); } break; } item->value.vt |= VT_VECTOR; - item->value.u.caub.cElems = count; - item->value.u.caub.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count); - if (!item->value.u.caub.pElems) return E_OUTOFMEMORY; + item->value.caub.cElems = count; + item->value.caub.pElems = CoTaskMemAlloc(count); + if (!item->value.caub.pElems) return E_OUTOFMEMORY; pos.QuadPart = value; hr = IStream_Seek(input, pos, SEEK_SET, NULL); if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, item->value.u.caub.pElems); + CoTaskMemFree(item->value.caub.pElems); return hr; } - hr = IStream_Read(input, item->value.u.caub.pElems, count, NULL); - if (FAILED(hr)) + hr = IStream_Read(input, item->value.caub.pElems, count, &bytesread); + if (bytesread != count) hr = E_FAIL; + if (hr != S_OK) { - HeapFree(GetProcessHeap(), 0, item->value.u.caub.pElems); + CoTaskMemFree(item->value.caub.pElems); return hr; } break; @@ -787,41 +865,42 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, if (count == 1) { - item->value.u.uiVal = data[0]; - SWAP_USHORT(item->value.u.uiVal); + item->value.uiVal = data[0]; + SWAP_USHORT(item->value.uiVal); } else { item->value.vt |= VT_VECTOR; - item->value.u.caui.cElems = count; - item->value.u.caui.pElems = HeapAlloc(GetProcessHeap(), 0, count * 2); - memcpy(item->value.u.caui.pElems, data, count * 2); + item->value.caui.cElems = count; + item->value.caui.pElems = CoTaskMemAlloc(count * 2); + memcpy(item->value.caui.pElems, data, count * 2); for (i = 0; i < count; i++) - SWAP_USHORT(item->value.u.caui.pElems[i]); + SWAP_USHORT(item->value.caui.pElems[i]); } break; } item->value.vt |= VT_VECTOR; - item->value.u.caui.cElems = count; - item->value.u.caui.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * 2); - if (!item->value.u.caui.pElems) return E_OUTOFMEMORY; + item->value.caui.cElems = count; + item->value.caui.pElems = CoTaskMemAlloc(count * 2); + if (!item->value.caui.pElems) return E_OUTOFMEMORY; pos.QuadPart = value; hr = IStream_Seek(input, pos, SEEK_SET, NULL); if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, item->value.u.caui.pElems); + CoTaskMemFree(item->value.caui.pElems); return hr; } - hr = IStream_Read(input, item->value.u.caui.pElems, count * 2, NULL); - if (FAILED(hr)) + hr = IStream_Read(input, item->value.caui.pElems, count * 2, &bytesread); + if (bytesread != count * 2) hr = E_FAIL; + if (hr != S_OK) { - HeapFree(GetProcessHeap(), 0, item->value.u.caui.pElems); + CoTaskMemFree(item->value.caui.pElems); return hr; } for (i = 0; i < count; i++) - SWAP_USHORT(item->value.u.caui.pElems[i]); + SWAP_USHORT(item->value.caui.pElems[i]); break; case IFD_LONG: case IFD_SLONG: @@ -830,30 +909,31 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, if (count == 1) { - item->value.u.ulVal = value; + item->value.ulVal = value; break; } item->value.vt |= VT_VECTOR; - item->value.u.caul.cElems = count; - item->value.u.caul.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * 4); - if (!item->value.u.caul.pElems) return E_OUTOFMEMORY; + item->value.caul.cElems = count; + item->value.caul.pElems = CoTaskMemAlloc(count * 4); + if (!item->value.caul.pElems) return E_OUTOFMEMORY; pos.QuadPart = value; hr = IStream_Seek(input, pos, SEEK_SET, NULL); if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, item->value.u.caul.pElems); + CoTaskMemFree(item->value.caul.pElems); return hr; } - hr = IStream_Read(input, item->value.u.caul.pElems, count * 4, NULL); - if (FAILED(hr)) + hr = IStream_Read(input, item->value.caul.pElems, count * 4, &bytesread); + if (bytesread != count * 4) hr = E_FAIL; + if (hr != S_OK) { - HeapFree(GetProcessHeap(), 0, item->value.u.caul.pElems); + CoTaskMemFree(item->value.caul.pElems); return hr; } for (i = 0; i < count; i++) - SWAP_ULONG(item->value.u.caul.pElems[i]); + SWAP_ULONG(item->value.caul.pElems[i]); break; case IFD_RATIONAL: case IFD_SRATIONAL: @@ -873,61 +953,63 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, hr = IStream_Seek(input, pos, SEEK_SET, NULL); if (FAILED(hr)) return hr; - hr = IStream_Read(input, &ull, sizeof(ull), NULL); + hr = IStream_Read(input, &ull, sizeof(ull), &bytesread); + if (bytesread != sizeof(ull)) hr = E_FAIL; if (hr != S_OK) return hr; - item->value.u.uhVal.QuadPart = ull; + item->value.uhVal.QuadPart = ull; if (type == IFD_DOUBLE) - SWAP_ULONGLONG(item->value.u.uhVal.QuadPart); + SWAP_ULONGLONG(item->value.uhVal.QuadPart); else { - SWAP_ULONG(item->value.u.uhVal.u.LowPart); - SWAP_ULONG(item->value.u.uhVal.u.HighPart); + SWAP_ULONG(item->value.uhVal.LowPart); + SWAP_ULONG(item->value.uhVal.HighPart); } break; } else { item->value.vt |= VT_VECTOR; - item->value.u.cauh.cElems = count; - item->value.u.cauh.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * 8); - if (!item->value.u.cauh.pElems) return E_OUTOFMEMORY; + item->value.cauh.cElems = count; + item->value.cauh.pElems = CoTaskMemAlloc(count * 8); + if (!item->value.cauh.pElems) return E_OUTOFMEMORY; pos.QuadPart = value; hr = IStream_Seek(input, pos, SEEK_SET, NULL); if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, item->value.u.cauh.pElems); + CoTaskMemFree(item->value.cauh.pElems); return hr; } - hr = IStream_Read(input, item->value.u.cauh.pElems, count * 8, NULL); - if (FAILED(hr)) + hr = IStream_Read(input, item->value.cauh.pElems, count * 8, &bytesread); + if (bytesread != count * 8) hr = E_FAIL; + if (hr != S_OK) { - HeapFree(GetProcessHeap(), 0, item->value.u.cauh.pElems); + CoTaskMemFree(item->value.cauh.pElems); return hr; } for (i = 0; i < count; i++) { if (type == IFD_DOUBLE) - SWAP_ULONGLONG(item->value.u.cauh.pElems[i].QuadPart); + SWAP_ULONGLONG(item->value.cauh.pElems[i].QuadPart); else { - SWAP_ULONG(item->value.u.cauh.pElems[i].u.LowPart); - SWAP_ULONG(item->value.u.cauh.pElems[i].u.HighPart); + SWAP_ULONG(item->value.cauh.pElems[i].LowPart); + SWAP_ULONG(item->value.cauh.pElems[i].HighPart); } } } break; case IFD_ASCII: - item->value.u.pszVal = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count + 1); - if (!item->value.u.pszVal) return E_OUTOFMEMORY; + item->value.pszVal = CoTaskMemAlloc(count + 1); + if (!item->value.pszVal) return E_OUTOFMEMORY; if (count <= 4) { const char *data = (const char *)&entry->value; - memcpy(item->value.u.pszVal, data, count); - item->value.u.pszVal[count] = 0; + memcpy(item->value.pszVal, data, count); + item->value.pszVal[count] = 0; break; } @@ -935,16 +1017,17 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, hr = IStream_Seek(input, pos, SEEK_SET, NULL); if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, item->value.u.pszVal); + CoTaskMemFree(item->value.pszVal); return hr; } - hr = IStream_Read(input, item->value.u.pszVal, count, NULL); - if (FAILED(hr)) + hr = IStream_Read(input, item->value.pszVal, count, &bytesread); + if (bytesread != count) hr = E_FAIL; + if (hr != S_OK) { - HeapFree(GetProcessHeap(), 0, item->value.u.pszVal); + CoTaskMemFree(item->value.pszVal); return hr; } - item->value.u.pszVal[count] = 0; + item->value.pszVal[count] = 0; break; case IFD_UNDEFINED: if (!count) @@ -954,15 +1037,15 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, break; } - item->value.u.blob.pBlobData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count); - if (!item->value.u.blob.pBlobData) return E_OUTOFMEMORY; + item->value.blob.pBlobData = CoTaskMemAlloc(count); + if (!item->value.blob.pBlobData) return E_OUTOFMEMORY; - item->value.u.blob.cbSize = count; + item->value.blob.cbSize = count; if (count <= 4) { const char *data = (const char *)&entry->value; - memcpy(item->value.u.blob.pBlobData, data, count); + memcpy(item->value.blob.pBlobData, data, count); break; } @@ -970,18 +1053,19 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, hr = IStream_Seek(input, pos, SEEK_SET, NULL); if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, item->value.u.blob.pBlobData); + CoTaskMemFree(item->value.blob.pBlobData); return hr; } - hr = IStream_Read(input, item->value.u.blob.pBlobData, count, NULL); - if (FAILED(hr)) + hr = IStream_Read(input, item->value.blob.pBlobData, count, &bytesread); + if (bytesread != count) hr = E_FAIL; + if (hr != S_OK) { - HeapFree(GetProcessHeap(), 0, item->value.u.blob.pBlobData); + CoTaskMemFree(item->value.blob.pBlobData); return hr; } break; default: - FIXME("loading field of type %d, count %u is not implemented\n", type, count); + FIXME("loading field of type %d, count %lu is not implemented\n", type, count); break; } return S_OK; @@ -1012,14 +1096,14 @@ static HRESULT LoadIfdMetadata(IStream *input, const GUID *preferred_vendor, SWAP_USHORT(count); - entry = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*entry)); + entry = malloc(count * sizeof(*entry)); if (!entry) return E_OUTOFMEMORY; hr = IStream_Read(input, entry, count * sizeof(*entry), &bytesread); if (bytesread != count * sizeof(*entry)) hr = E_FAIL; if (hr != S_OK) { - HeapFree(GetProcessHeap(), 0, entry); + free(entry); return hr; } @@ -1054,14 +1138,14 @@ static HRESULT LoadIfdMetadata(IStream *input, const GUID *preferred_vendor, if (hr != S_OK || i == 4096) { - HeapFree(GetProcessHeap(), 0, entry); + free(entry); return WINCODEC_ERR_BADMETADATAHEADER; } - result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * sizeof(*result)); + result = calloc(count, sizeof(*result)); if (!result) { - HeapFree(GetProcessHeap(), 0, entry); + free(entry); return E_OUTOFMEMORY; } @@ -1070,13 +1154,13 @@ static HRESULT LoadIfdMetadata(IStream *input, const GUID *preferred_vendor, hr = load_IFD_entry(input, &entry[i], &result[i], native_byte_order); if (FAILED(hr)) { - HeapFree(GetProcessHeap(), 0, entry); - HeapFree(GetProcessHeap(), 0, result); + free(entry); + free(result); return hr; } } - HeapFree(GetProcessHeap(), 0, entry); + free(entry); *items = result; *item_count = count; @@ -1094,3 +1178,4 @@ HRESULT IfdMetadataReader_CreateInstance(REFIID iid, void **ppv) { return MetadataReader_Create(&IfdMetadataReader_Vtbl, iid, ppv); } + diff --git a/dll/win32/windowscodecs/metadataquery.c b/dll/win32/windowscodecs/metadataquery.c index 79340427547..d0d27bdd0fb 100644 --- a/dll/win32/windowscodecs/metadataquery.c +++ b/dll/win32/windowscodecs/metadataquery.c @@ -17,13 +17,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include +#include #define COBJMACROS -#define NONAMELESSUNION - #include "windef.h" #include "winbase.h" #include "objbase.h" @@ -75,7 +72,7 @@ static ULONG WINAPI mqr_AddRef(IWICMetadataQueryReader *iface) { QueryReader *This = impl_from_IWICMetadataQueryReader(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", This, ref); + TRACE("(%p) refcount=%lu\n", This, ref); return ref; } @@ -83,12 +80,12 @@ static ULONG WINAPI mqr_Release(IWICMetadataQueryReader *iface) { QueryReader *This = impl_from_IWICMetadataQueryReader(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", This, ref); + TRACE("(%p) refcount=%lu\n", This, ref); if (!ref) { IWICMetadataBlockReader_Release(This->block); - HeapFree(GetProcessHeap(), 0, This->root); - HeapFree(GetProcessHeap(), 0, This); + free(This->root); + free(This); } return ref; } @@ -104,7 +101,6 @@ static HRESULT WINAPI mqr_GetContainerFormat(IWICMetadataQueryReader *iface, GUI static HRESULT WINAPI mqr_GetLocation(IWICMetadataQueryReader *iface, UINT len, WCHAR *location, UINT *ret_len) { - static const WCHAR rootW[] = { '/',0 }; QueryReader *This = impl_from_IWICMetadataQueryReader(iface); const WCHAR *root; UINT actual_len; @@ -113,7 +109,7 @@ static HRESULT WINAPI mqr_GetLocation(IWICMetadataQueryReader *iface, UINT len, if (!ret_len) return E_INVALIDARG; - root = This->root ? This->root : rootW; + root = This->root ? This->root : L"/"; actual_len = lstrlenW(root) + 1; if (location) @@ -201,7 +197,7 @@ static HRESULT get_token(struct string_t *elem, PROPVARIANT *id, PROPVARIANT *sc if (start[1] < '0' || start[1] > '9') return DISP_E_TYPEMISMATCH; - *idx = strtolW(start + 1, &idx_end, 10); + *idx = wcstol(start + 1, &idx_end, 10); if (idx_end > elem->str + elem->len) return WINCODEC_ERR_INVALIDQUERYREQUEST; if (*idx_end != ']') return WINCODEC_ERR_INVALIDQUERYREQUEST; if (*idx < 0) return WINCODEC_ERR_INVALIDQUERYREQUEST; @@ -212,7 +208,7 @@ static HRESULT get_token(struct string_t *elem, PROPVARIANT *id, PROPVARIANT *sc hr = get_token(&next_elem, id, schema, idx); if (hr != S_OK) { - TRACE("get_token error %#x\n", hr); + TRACE("get_token error %#lx\n", hr); return hr; } elem->len = (end - start) + next_elem.len; @@ -225,7 +221,7 @@ static HRESULT get_token(struct string_t *elem, PROPVARIANT *id, PROPVARIANT *sc VARTYPE vt; PROPVARIANT next_token; - end = memchrW(start + 1, '=', elem->len - 1); + end = wmemchr(start + 1, '=', elem->len - 1); if (!end) return WINCODEC_ERR_INVALIDQUERYREQUEST; if (end > elem->str + elem->len) return WINCODEC_ERR_INVALIDQUERYREQUEST; @@ -236,10 +232,10 @@ static HRESULT get_token(struct string_t *elem, PROPVARIANT *id, PROPVARIANT *sc if (vt == VT_ILLEGAL) return WINCODEC_ERR_WRONGSTATE; next_token.vt = VT_BSTR; - next_token.u.bstrVal = SysAllocStringLen(NULL, elem->len - (end - start) + 1); - if (!next_token.u.bstrVal) return E_OUTOFMEMORY; + next_token.bstrVal = SysAllocStringLen(NULL, elem->len - (end - start) + 1); + if (!next_token.bstrVal) return E_OUTOFMEMORY; - bstr = next_token.u.bstrVal; + bstr = next_token.bstrVal; end++; while (*end && *end != '}' && end - start < elem->len) @@ -253,19 +249,19 @@ static HRESULT get_token(struct string_t *elem, PROPVARIANT *id, PROPVARIANT *sc return WINCODEC_ERR_INVALIDQUERYREQUEST; } *bstr = 0; - TRACE("schema/id %s\n", wine_dbgstr_w(next_token.u.bstrVal)); + TRACE("schema/id %s\n", wine_dbgstr_w(next_token.bstrVal)); if (vt == VT_CLSID) { id->vt = VT_CLSID; - id->u.puuid = CoTaskMemAlloc(sizeof(GUID)); - if (!id->u.puuid) + id->puuid = CoTaskMemAlloc(sizeof(GUID)); + if (!id->puuid) { PropVariantClear(&next_token); return E_OUTOFMEMORY; } - hr = UuidFromStringW(next_token.u.bstrVal, id->u.puuid); + hr = UuidFromStringW(next_token.bstrVal, id->puuid); } else hr = PropVariantChangeType(id, &next_token, 0, vt); @@ -288,7 +284,7 @@ static HRESULT get_token(struct string_t *elem, PROPVARIANT *id, PROPVARIANT *sc hr = get_token(&next_elem, &next_id, &next_schema, &next_idx); if (hr != S_OK) { - TRACE("get_token error %#x\n", hr); + TRACE("get_token error %#lx\n", hr); return hr; } elem->len = (end - start + 1) + next_elem.len; @@ -312,10 +308,10 @@ static HRESULT get_token(struct string_t *elem, PROPVARIANT *id, PROPVARIANT *sc return S_OK; } - end = memchrW(start, '/', elem->len); + end = wmemchr(start, '/', elem->len); if (!end) end = start + elem->len; - p = memchrW(start, ':', end - start); + p = wmemchr(start, ':', end - start); if (p) { next_elem.str = p + 1; @@ -327,10 +323,10 @@ static HRESULT get_token(struct string_t *elem, PROPVARIANT *id, PROPVARIANT *sc elem->len = end - start; id->vt = VT_BSTR; - id->u.bstrVal = SysAllocStringLen(NULL, elem->len + 1); - if (!id->u.bstrVal) return E_OUTOFMEMORY; + id->bstrVal = SysAllocStringLen(NULL, elem->len + 1); + if (!id->bstrVal) return E_OUTOFMEMORY; - bstr = id->u.bstrVal; + bstr = id->bstrVal; p = elem->str; while (p - elem->str < elem->len) { @@ -348,7 +344,7 @@ static HRESULT get_token(struct string_t *elem, PROPVARIANT *id, PROPVARIANT *sc hr = get_token(&next_elem, &next_id, &next_schema, &next_idx); if (hr != S_OK) { - TRACE("get_token error %#x\n", hr); + TRACE("get_token error %#lx\n", hr); PropVariantClear(id); PropVariantClear(schema); return hr; @@ -430,16 +426,16 @@ static HRESULT get_next_reader(IWICMetadataReader *reader, UINT index, if (index) { schema.vt = VT_UI2; - schema.u.uiVal = index; + schema.uiVal = index; } id.vt = VT_CLSID; - id.u.puuid = guid; + id.puuid = guid; hr = IWICMetadataReader_GetValue(reader, &schema, &id, &value); if (hr != S_OK) return hr; if (value.vt == VT_UNKNOWN) - hr = IUnknown_QueryInterface(value.u.punkVal, &IID_IWICMetadataReader, (void **)new_reader); + hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataReader, (void **)new_reader); else hr = WINCODEC_ERR_UNEXPECTEDMETADATATYPE; @@ -463,7 +459,7 @@ static HRESULT WINAPI mqr_GetMetadataByName(IWICMetadataQueryReader *iface, LPCW len = lstrlenW(query) + 1; if (This->root) len += lstrlenW(This->root); - full_query = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + full_query = malloc(len * sizeof(WCHAR)); full_query[0] = 0; if (This->root) lstrcpyW(full_query, This->root); @@ -493,7 +489,7 @@ static HRESULT WINAPI mqr_GetMetadataByName(IWICMetadataQueryReader *iface, LPCW hr = get_token(&elem, &tk_id, &tk_schema, &index); if (hr != S_OK) { - WARN("get_token error %#x\n", hr); + WARN("get_token error %#lx\n", hr); break; } TRACE("parsed %d characters: %s, index %d\n", elem.len, wine_dbgstr_wn(elem.str, elem.len), index); @@ -501,7 +497,7 @@ static HRESULT WINAPI mqr_GetMetadataByName(IWICMetadataQueryReader *iface, LPCW if (!elem.len) break; - if (tk_id.vt == VT_CLSID || (tk_id.vt == VT_BSTR && WICMapShortNameToGuid(tk_id.u.bstrVal, &guid) == S_OK)) + if (tk_id.vt == VT_CLSID || (tk_id.vt == VT_BSTR && WICMapShortNameToGuid(tk_id.bstrVal, &guid) == S_OK)) { WCHAR *root; @@ -511,7 +507,7 @@ static HRESULT WINAPI mqr_GetMetadataByName(IWICMetadataQueryReader *iface, LPCW PropVariantClear(&tk_schema); } - if (tk_id.vt == VT_CLSID) guid = *tk_id.u.puuid; + if (tk_id.vt == VT_CLSID) guid = *tk_id.puuid; if (reader) { @@ -536,7 +532,7 @@ static HRESULT WINAPI mqr_GetMetadataByName(IWICMetadataQueryReader *iface, LPCW PropVariantClear(&new_value); new_value.vt = VT_UNKNOWN; - hr = MetadataQueryReader_CreateInstance(This->block, root, (IWICMetadataQueryReader **)&new_value.u.punkVal); + hr = MetadataQueryReader_CreateInstance(This->block, root, (IWICMetadataQueryReader **)&new_value.punkVal); SysFreeString(root); if (hr != S_OK) break; } @@ -556,9 +552,9 @@ static HRESULT WINAPI mqr_GetMetadataByName(IWICMetadataQueryReader *iface, LPCW if (hr != S_OK) break; schema.vt = VT_LPWSTR; - schema.u.pwszVal = (LPWSTR)map_shortname_to_schema(&guid, tk_schema.u.bstrVal); - if (!schema.u.pwszVal) - schema.u.pwszVal = tk_schema.u.bstrVal; + schema.pwszVal = (LPWSTR)map_shortname_to_schema(&guid, tk_schema.bstrVal); + if (!schema.pwszVal) + schema.pwszVal = tk_schema.bstrVal; } else schema = tk_schema; @@ -566,7 +562,7 @@ static HRESULT WINAPI mqr_GetMetadataByName(IWICMetadataQueryReader *iface, LPCW if (tk_id.vt == VT_BSTR) { id.vt = VT_LPWSTR; - id.u.pwszVal = tk_id.u.bstrVal; + id.pwszVal = tk_id.bstrVal; } else id = tk_id; @@ -593,19 +589,131 @@ static HRESULT WINAPI mqr_GetMetadataByName(IWICMetadataQueryReader *iface, LPCW else PropVariantClear(&new_value); - HeapFree(GetProcessHeap(), 0, full_query); + free(full_query); return hr; } -static HRESULT WINAPI mqr_GetEnumerator(IWICMetadataQueryReader *iface, - IEnumString **ppIEnumString) +struct string_enumerator { - QueryReader *This = impl_from_IWICMetadataQueryReader(iface); - FIXME("(%p,%p)\n", This, ppIEnumString); + IEnumString IEnumString_iface; + LONG ref; +}; + +static struct string_enumerator *impl_from_IEnumString(IEnumString *iface) +{ + return CONTAINING_RECORD(iface, struct string_enumerator, IEnumString_iface); +} + +static HRESULT WINAPI string_enumerator_QueryInterface(IEnumString *iface, REFIID riid, void **ppv) +{ + struct string_enumerator *this = impl_from_IEnumString(iface); + + TRACE("iface %p, riid %s, ppv %p.\n", iface, debugstr_guid(riid), ppv); + + if (IsEqualGUID(riid, &IID_IEnumString) || IsEqualGUID(riid, &IID_IUnknown)) + *ppv = &this->IEnumString_iface; + else + { + WARN("Unknown riid %s.\n", debugstr_guid(riid)); + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef(&this->IEnumString_iface); + return S_OK; +} + +static ULONG WINAPI string_enumerator_AddRef(IEnumString *iface) +{ + struct string_enumerator *this = impl_from_IEnumString(iface); + ULONG ref = InterlockedIncrement(&this->ref); + + TRACE("iface %p, ref %lu.\n", iface, ref); + + return ref; +} + +static ULONG WINAPI string_enumerator_Release(IEnumString *iface) +{ + struct string_enumerator *this = impl_from_IEnumString(iface); + ULONG ref = InterlockedDecrement(&this->ref); + + TRACE("iface %p, ref %lu.\n", iface, ref); + + if (!ref) + free(this); + + return ref; +} + +static HRESULT WINAPI string_enumerator_Next(IEnumString *iface, ULONG count, LPOLESTR *strings, ULONG *ret) +{ + FIXME("iface %p, count %lu, strings %p, ret %p stub.\n", iface, count, strings, ret); + + if (!strings || !ret) + return E_INVALIDARG; + + *ret = 0; + return count ? S_FALSE : S_OK; +} + +static HRESULT WINAPI string_enumerator_Reset(IEnumString *iface) +{ + TRACE("iface %p.\n", iface); + + return S_OK; +} + +static HRESULT WINAPI string_enumerator_Skip(IEnumString *iface, ULONG count) +{ + FIXME("iface %p, count %lu stub.\n", iface, count); + + return count ? S_FALSE : S_OK; +} + +static HRESULT WINAPI string_enumerator_Clone(IEnumString *iface, IEnumString **out) +{ + FIXME("iface %p, out %p stub.\n", iface, out); + + *out = NULL; return E_NOTIMPL; } +static const IEnumStringVtbl string_enumerator_vtbl = +{ + string_enumerator_QueryInterface, + string_enumerator_AddRef, + string_enumerator_Release, + string_enumerator_Next, + string_enumerator_Skip, + string_enumerator_Reset, + string_enumerator_Clone +}; + +static HRESULT string_enumerator_create(IEnumString **enum_string) +{ + struct string_enumerator *object; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->IEnumString_iface.lpVtbl = &string_enumerator_vtbl; + object->ref = 1; + + *enum_string = &object->IEnumString_iface; + + return S_OK; +} + +static HRESULT WINAPI mqr_GetEnumerator(IWICMetadataQueryReader *iface, + IEnumString **enum_string) +{ + TRACE("iface %p, enum_string %p.\n", iface, enum_string); + + return string_enumerator_create(enum_string); +} + static IWICMetadataQueryReaderVtbl mqr_vtbl = { mqr_QueryInterface, mqr_AddRef, @@ -620,7 +728,7 @@ HRESULT MetadataQueryReader_CreateInstance(IWICMetadataBlockReader *mbr, const W { QueryReader *obj; - obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*obj)); + obj = calloc(1, sizeof(*obj)); if (!obj) return E_OUTOFMEMORY; @@ -630,57 +738,152 @@ HRESULT MetadataQueryReader_CreateInstance(IWICMetadataBlockReader *mbr, const W IWICMetadataBlockReader_AddRef(mbr); obj->block = mbr; - obj->root = root ? heap_strdupW(root) : NULL; + obj->root = wcsdup(root); *out = &obj->IWICMetadataQueryReader_iface; return S_OK; } -static const WCHAR bmpW[] = { 'b','m','p',0 }; -static const WCHAR pngW[] = { 'p','n','g',0 }; -static const WCHAR icoW[] = { 'i','c','o',0 }; -static const WCHAR jpgW[] = { 'j','p','g',0 }; -static const WCHAR tiffW[] = { 't','i','f','f',0 }; -static const WCHAR gifW[] = { 'g','i','f',0 }; -static const WCHAR wmphotoW[] = { 'w','m','p','h','o','t','o',0 }; -static const WCHAR unknownW[] = { 'u','n','k','n','o','w','n',0 }; -static const WCHAR ifdW[] = { 'i','f','d',0 }; -static const WCHAR subW[] = { 's','u','b',0 }; -static const WCHAR exifW[] = { 'e','x','i','f',0 }; -static const WCHAR gpsW[] = { 'g','p','s',0 }; -static const WCHAR interopW[] = { 'i','n','t','e','r','o','p',0 }; -static const WCHAR app0W[] = { 'a','p','p','0',0 }; -static const WCHAR app1W[] = { 'a','p','p','1',0 }; -static const WCHAR app13W[] = { 'a','p','p','1','3',0 }; -static const WCHAR iptcW[] = { 'i','p','t','c',0 }; -static const WCHAR irbW[] = { 'i','r','b',0 }; -static const WCHAR _8bimiptcW[] = { '8','b','i','m','i','p','t','c',0 }; -static const WCHAR _8bimResInfoW[] = { '8','b','i','m','R','e','s','I','n','f','o',0 }; -static const WCHAR _8bimiptcdigestW[] = { '8','b','i','m','i','p','t','c','d','i','g','e','s','t',0 }; -static const WCHAR xmpW[] = { 'x','m','p',0 }; -static const WCHAR thumbW[] = { 't','h','u','m','b',0 }; -static const WCHAR tEXtW[] = { 't','E','X','t',0 }; -static const WCHAR xmpstructW[] = { 'x','m','p','s','t','r','u','c','t',0 }; -static const WCHAR xmpbagW[] = { 'x','m','p','b','a','g',0 }; -static const WCHAR xmpseqW[] = { 'x','m','p','s','e','q',0 }; -static const WCHAR xmpaltW[] = { 'x','m','p','a','l','t',0 }; -static const WCHAR logscrdescW[] = { 'l','o','g','s','c','r','d','e','s','c',0 }; -static const WCHAR imgdescW[] = { 'i','m','g','d','e','s','c',0 }; -static const WCHAR grctlextW[] = { 'g','r','c','t','l','e','x','t',0 }; -static const WCHAR appextW[] = { 'a','p','p','e','x','t',0 }; -static const WCHAR chrominanceW[] = { 'c','h','r','o','m','i','n','a','n','c','e',0 }; -static const WCHAR luminanceW[] = { 'l','u','m','i','n','a','n','c','e',0 }; -static const WCHAR comW[] = { 'c','o','m',0 }; -static const WCHAR commentextW[] = { 'c','o','m','m','e','n','t','e','x','t',0 }; -static const WCHAR gAMAW[] = { 'g','A','M','A',0 }; -static const WCHAR bKGDW[] = { 'b','K','G','D',0 }; -static const WCHAR iTXtW[] = { 'i','T','X','t',0 }; -static const WCHAR cHRMW[] = { 'c','H','R','M',0 }; -static const WCHAR hISTW[] = { 'h','I','S','T',0 }; -static const WCHAR iCCPW[] = { 'i','C','C','P',0 }; -static const WCHAR sRGBW[] = { 's','R','G','B',0 }; -static const WCHAR tIMEW[] = { 't','I','M','E',0 }; +typedef struct +{ + IWICMetadataQueryWriter IWICMetadataQueryWriter_iface; + LONG ref; + IWICMetadataBlockWriter *block; + WCHAR *root; +} +QueryWriter; + +static inline QueryWriter *impl_from_IWICMetadataQueryWriter(IWICMetadataQueryWriter *iface) +{ + return CONTAINING_RECORD(iface, QueryWriter, IWICMetadataQueryWriter_iface); +} + +static HRESULT WINAPI mqw_QueryInterface(IWICMetadataQueryWriter *iface, REFIID riid, + void **object) +{ + QueryWriter *writer = impl_from_IWICMetadataQueryWriter(iface); + + TRACE("writer %p, riid %s, object %p.\n", writer, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IWICMetadataQueryWriter) + || IsEqualGUID(riid, &IID_IWICMetadataQueryReader)) + *object = &writer->IWICMetadataQueryWriter_iface; + else + *object = NULL; + + if (*object) + { + IUnknown_AddRef((IUnknown *)*object); + return S_OK; + } + + return E_NOINTERFACE; +} + +static ULONG WINAPI mqw_AddRef(IWICMetadataQueryWriter *iface) +{ + QueryWriter *writer = impl_from_IWICMetadataQueryWriter(iface); + ULONG ref = InterlockedIncrement(&writer->ref); + + TRACE("writer %p, refcount=%lu\n", writer, ref); + + return ref; +} + +static ULONG WINAPI mqw_Release(IWICMetadataQueryWriter *iface) +{ + QueryWriter *writer = impl_from_IWICMetadataQueryWriter(iface); + ULONG ref = InterlockedDecrement(&writer->ref); + + TRACE("writer %p, refcount=%lu.\n", writer, ref); + + if (!ref) + { + IWICMetadataBlockWriter_Release(writer->block); + free(writer->root); + free(writer); + } + return ref; +} + +static HRESULT WINAPI mqw_GetContainerFormat(IWICMetadataQueryWriter *iface, GUID *container_format) +{ + FIXME("iface %p, container_format %p stub.\n", iface, container_format); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mqw_GetEnumerator(IWICMetadataQueryWriter *iface, IEnumString **enum_string) +{ + TRACE("iface %p, enum_string %p.\n", iface, enum_string); + + return string_enumerator_create(enum_string); +} + +static HRESULT WINAPI mqw_GetLocation(IWICMetadataQueryWriter *iface, UINT max_length, WCHAR *namespace, UINT *actual_length) +{ + FIXME("iface %p, max_length %u, namespace %s, actual_length %p stub.\n", + iface, max_length, debugstr_w(namespace), actual_length); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mqw_GetMetadataByName(IWICMetadataQueryWriter *iface, LPCWSTR name, PROPVARIANT *value) +{ + FIXME("name %s, value %p stub.\n", debugstr_w(name), value); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mqw_SetMetadataByName(IWICMetadataQueryWriter *iface, LPCWSTR name, const PROPVARIANT *value) +{ + FIXME("iface %p, name %s, value %p stub.\n", iface, debugstr_w(name), value); + + return S_OK; +} + +static HRESULT WINAPI mqw_RemoveMetadataByName(IWICMetadataQueryWriter *iface, LPCWSTR name) +{ + FIXME("iface %p, name %s stub.\n", iface, debugstr_w(name)); + + return E_NOTIMPL; +} + +static const IWICMetadataQueryWriterVtbl mqw_vtbl = +{ + mqw_QueryInterface, + mqw_AddRef, + mqw_Release, + mqw_GetContainerFormat, + mqw_GetLocation, + mqw_GetMetadataByName, + mqw_GetEnumerator, + mqw_SetMetadataByName, + mqw_RemoveMetadataByName, +}; + +HRESULT MetadataQueryWriter_CreateInstance(IWICMetadataBlockWriter *mbw, const WCHAR *root, IWICMetadataQueryWriter **out) +{ + QueryWriter *obj; + + obj = calloc(1, sizeof(*obj)); + if (!obj) + return E_OUTOFMEMORY; + + obj->IWICMetadataQueryWriter_iface.lpVtbl = &mqw_vtbl; + obj->ref = 1; + + IWICMetadataBlockWriter_AddRef(mbw); + obj->block = mbw; + + obj->root = wcsdup(root); + + *out = &obj->IWICMetadataQueryWriter_iface; + + return S_OK; +} static const struct { @@ -688,50 +891,50 @@ static const struct const WCHAR *name; } guid2name[] = { - { &GUID_ContainerFormatBmp, bmpW }, - { &GUID_ContainerFormatPng, pngW }, - { &GUID_ContainerFormatIco, icoW }, - { &GUID_ContainerFormatJpeg, jpgW }, - { &GUID_ContainerFormatTiff, tiffW }, - { &GUID_ContainerFormatGif, gifW }, - { &GUID_ContainerFormatWmp, wmphotoW }, - { &GUID_MetadataFormatUnknown, unknownW }, - { &GUID_MetadataFormatIfd, ifdW }, - { &GUID_MetadataFormatSubIfd, subW }, - { &GUID_MetadataFormatExif, exifW }, - { &GUID_MetadataFormatGps, gpsW }, - { &GUID_MetadataFormatInterop, interopW }, - { &GUID_MetadataFormatApp0, app0W }, - { &GUID_MetadataFormatApp1, app1W }, - { &GUID_MetadataFormatApp13, app13W }, - { &GUID_MetadataFormatIPTC, iptcW }, - { &GUID_MetadataFormatIRB, irbW }, - { &GUID_MetadataFormat8BIMIPTC, _8bimiptcW }, - { &GUID_MetadataFormat8BIMResolutionInfo, _8bimResInfoW }, - { &GUID_MetadataFormat8BIMIPTCDigest, _8bimiptcdigestW }, - { &GUID_MetadataFormatXMP, xmpW }, - { &GUID_MetadataFormatThumbnail, thumbW }, - { &GUID_MetadataFormatChunktEXt, tEXtW }, - { &GUID_MetadataFormatXMPStruct, xmpstructW }, - { &GUID_MetadataFormatXMPBag, xmpbagW }, - { &GUID_MetadataFormatXMPSeq, xmpseqW }, - { &GUID_MetadataFormatXMPAlt, xmpaltW }, - { &GUID_MetadataFormatLSD, logscrdescW }, - { &GUID_MetadataFormatIMD, imgdescW }, - { &GUID_MetadataFormatGCE, grctlextW }, - { &GUID_MetadataFormatAPE, appextW }, - { &GUID_MetadataFormatJpegChrominance, chrominanceW }, - { &GUID_MetadataFormatJpegLuminance, luminanceW }, - { &GUID_MetadataFormatJpegComment, comW }, - { &GUID_MetadataFormatGifComment, commentextW }, - { &GUID_MetadataFormatChunkgAMA, gAMAW }, - { &GUID_MetadataFormatChunkbKGD, bKGDW }, - { &GUID_MetadataFormatChunkiTXt, iTXtW }, - { &GUID_MetadataFormatChunkcHRM, cHRMW }, - { &GUID_MetadataFormatChunkhIST, hISTW }, - { &GUID_MetadataFormatChunkiCCP, iCCPW }, - { &GUID_MetadataFormatChunksRGB, sRGBW }, - { &GUID_MetadataFormatChunktIME, tIMEW } + { &GUID_ContainerFormatBmp, L"bmp" }, + { &GUID_ContainerFormatPng, L"png" }, + { &GUID_ContainerFormatIco, L"ico" }, + { &GUID_ContainerFormatJpeg, L"jpg" }, + { &GUID_ContainerFormatTiff, L"tiff" }, + { &GUID_ContainerFormatGif, L"gif" }, + { &GUID_ContainerFormatWmp, L"wmphoto" }, + { &GUID_MetadataFormatUnknown, L"unknown" }, + { &GUID_MetadataFormatIfd, L"ifd" }, + { &GUID_MetadataFormatSubIfd, L"sub" }, + { &GUID_MetadataFormatExif, L"exif" }, + { &GUID_MetadataFormatGps, L"gps" }, + { &GUID_MetadataFormatInterop, L"interop" }, + { &GUID_MetadataFormatApp0, L"app0" }, + { &GUID_MetadataFormatApp1, L"app1" }, + { &GUID_MetadataFormatApp13, L"app13" }, + { &GUID_MetadataFormatIPTC, L"iptc" }, + { &GUID_MetadataFormatIRB, L"irb" }, + { &GUID_MetadataFormat8BIMIPTC, L"8bimiptc" }, + { &GUID_MetadataFormat8BIMResolutionInfo, L"8bimResInfo" }, + { &GUID_MetadataFormat8BIMIPTCDigest, L"8bimiptcdigest" }, + { &GUID_MetadataFormatXMP, L"xmp" }, + { &GUID_MetadataFormatThumbnail, L"thumb" }, + { &GUID_MetadataFormatChunktEXt, L"tEXt" }, + { &GUID_MetadataFormatXMPStruct, L"xmpstruct" }, + { &GUID_MetadataFormatXMPBag, L"xmpbag" }, + { &GUID_MetadataFormatXMPSeq, L"xmpseq" }, + { &GUID_MetadataFormatXMPAlt, L"xmpalt" }, + { &GUID_MetadataFormatLSD, L"logscrdesc" }, + { &GUID_MetadataFormatIMD, L"imgdesc" }, + { &GUID_MetadataFormatGCE, L"grctlext" }, + { &GUID_MetadataFormatAPE, L"appext" }, + { &GUID_MetadataFormatJpegChrominance, L"chrominance" }, + { &GUID_MetadataFormatJpegLuminance, L"luminance" }, + { &GUID_MetadataFormatJpegComment, L"com" }, + { &GUID_MetadataFormatGifComment, L"commentext" }, + { &GUID_MetadataFormatChunkgAMA, L"gAMA" }, + { &GUID_MetadataFormatChunkbKGD, L"bKGD" }, + { &GUID_MetadataFormatChunkiTXt, L"iTXt" }, + { &GUID_MetadataFormatChunkcHRM, L"cHRM" }, + { &GUID_MetadataFormatChunkhIST, L"hIST" }, + { &GUID_MetadataFormatChunkiCCP, L"iCCP" }, + { &GUID_MetadataFormatChunksRGB, L"sRGB" }, + { &GUID_MetadataFormatChunktIME, L"tIME" } }; HRESULT WINAPI WICMapGuidToShortName(REFGUID guid, UINT len, WCHAR *name, UINT *ret_len) @@ -785,91 +988,38 @@ HRESULT WINAPI WICMapShortNameToGuid(PCWSTR name, GUID *guid) return WINCODEC_ERR_PROPERTYNOTFOUND; } -static const WCHAR rdf[] = { 'r','d','f',0 }; -static const WCHAR rdf_scheme[] = { 'h','t','t','p',':','/','/','w','w','w','.','w','3','.','o','r','g','/','1','9','9','9','/','0','2','/','2','2','-','r','d','f','-','s','y','n','t','a','x','-','n','s','#',0 }; -static const WCHAR dc[] = { 'd','c',0 }; -static const WCHAR dc_scheme[] = { 'h','t','t','p',':','/','/','p','u','r','l','.','o','r','g','/','d','c','/','e','l','e','m','e','n','t','s','/','1','.','1','/',0 }; -static const WCHAR xmp[] = { 'x','m','p',0 }; -static const WCHAR xmp_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/',0 }; -static const WCHAR xmpidq[] = { 'x','m','p','i','d','q',0 }; -static const WCHAR xmpidq_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','m','p','/','I','d','e','n','t','i','f','i','e','r','/','q','u','a','l','/','1','.','0','/',0 }; -static const WCHAR xmpRights[] = { 'x','m','p','R','i','g','h','t','s',0 }; -static const WCHAR xmpRights_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','r','i','g','h','t','s','/',0 }; -static const WCHAR xmpMM[] = { 'x','m','p','M','M',0 }; -static const WCHAR xmpMM_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','m','m','/',0 }; -static const WCHAR xmpBJ[] = { 'x','m','p','B','J',0 }; -static const WCHAR xmpBJ_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','b','j','/',0 }; -static const WCHAR xmpTPg[] = { 'x','m','p','T','P','g',0 }; -static const WCHAR xmpTPg_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','t','/','p','g','/',0 }; -static const WCHAR pdf[] = { 'p','d','f',0 }; -static const WCHAR pdf_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','p','d','f','/','1','.','3','/',0 }; -static const WCHAR photoshop[] = { 'p','h','o','t','o','s','h','o','p',0 }; -static const WCHAR photoshop_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','p','h','o','t','o','s','h','o','p','/','1','.','0','/',0 }; -static const WCHAR tiff[] = { 't','i','f','f',0 }; -static const WCHAR tiff_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','t','i','f','f','/','1','.','0','/',0 }; -static const WCHAR exif[] = { 'e','x','i','f',0 }; -static const WCHAR exif_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','e','x','i','f','/','1','.','0','/',0 }; -static const WCHAR stDim[] = { 's','t','D','i','m',0 }; -static const WCHAR stDim_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','s','T','y','p','e','/','D','i','m','e','n','s','i','o','n','s','#',0 }; -static const WCHAR xapGImg[] = { 'x','a','p','G','I','m','g',0 }; -static const WCHAR xapGImg_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','g','/','i','m','g','/',0 }; -static const WCHAR stEvt[] = { 's','t','E','v','t',0 }; -static const WCHAR stEvt_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','s','T','y','p','e','/','R','e','s','o','u','r','c','e','E','v','e','n','t','#',0 }; -static const WCHAR stRef[] = { 's','t','R','e','f',0 }; -static const WCHAR stRef_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','s','T','y','p','e','/','R','e','s','o','u','r','c','e','R','e','f','#',0 }; -static const WCHAR stVer[] = { 's','t','V','e','r',0 }; -static const WCHAR stVer_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','s','T','y','p','e','/','V','e','r','s','i','o','n','#',0 }; -static const WCHAR stJob[] = { 's','t','J','o','b',0 }; -static const WCHAR stJob_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/','s','T','y','p','e','/','J','o','b','#',0 }; -static const WCHAR aux[] = { 'a','u','x',0 }; -static const WCHAR aux_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','e','x','i','f','/','1','.','0','/','a','u','x','/',0 }; -static const WCHAR crs[] = { 'c','r','s',0 }; -static const WCHAR crs_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','c','a','m','e','r','a','-','r','a','w','-','s','e','t','t','i','n','g','s','/','1','.','0','/',0 }; -static const WCHAR xmpDM[] = { 'x','m','p','D','M',0 }; -static const WCHAR xmpDM_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','m','p','/','1','.','0','/','D','y','n','a','m','i','c','M','e','d','i','a','/',0 }; -static const WCHAR Iptc4xmpCore[] = { 'I','p','t','c','4','x','m','p','C','o','r','e',0 }; -static const WCHAR Iptc4xmpCore_scheme[] = { 'h','t','t','p',':','/','/','i','p','t','c','.','o','r','g','/','s','t','d','/','I','p','t','c','4','x','m','p','C','o','r','e','/','1','.','0','/','x','m','l','n','s','/',0 }; -static const WCHAR MicrosoftPhoto[] = { 'M','i','c','r','o','s','o','f','t','P','h','o','t','o',0 }; -static const WCHAR MicrosoftPhoto_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','p','h','o','t','o','/','1','.','0','/',0 }; -static const WCHAR MP[] = { 'M','P',0 }; -static const WCHAR MP_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','p','h','o','t','o','/','1','.','2','/',0 }; -static const WCHAR MPRI[] = { 'M','P','R','I',0 }; -static const WCHAR MPRI_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','p','h','o','t','o','/','1','.','2','/','t','/','R','e','g','i','o','n','I','n','f','o','#',0 }; -static const WCHAR MPReg[] = { 'M','P','R','e','g',0 }; -static const WCHAR MPReg_scheme[] = { 'h','t','t','p',':','/','/','n','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','p','h','o','t','o','/','1','.','2','/','t','/','R','e','g','i','o','n','#',0 }; - static const struct { const WCHAR *name; const WCHAR *schema; } name2schema[] = { - { rdf, rdf_scheme }, - { dc, dc_scheme }, - { xmp, xmp_scheme }, - { xmpidq, xmpidq_scheme }, - { xmpRights, xmpRights_scheme }, - { xmpMM, xmpMM_scheme }, - { xmpBJ, xmpBJ_scheme }, - { xmpTPg, xmpTPg_scheme }, - { pdf, pdf_scheme }, - { photoshop, photoshop_scheme }, - { tiff, tiff_scheme }, - { exif, exif_scheme }, - { stDim, stDim_scheme }, - { xapGImg, xapGImg_scheme }, - { stEvt, stEvt_scheme }, - { stRef, stRef_scheme }, - { stVer, stVer_scheme }, - { stJob, stJob_scheme }, - { aux, aux_scheme }, - { crs, crs_scheme }, - { xmpDM, xmpDM_scheme }, - { Iptc4xmpCore, Iptc4xmpCore_scheme }, - { MicrosoftPhoto, MicrosoftPhoto_scheme }, - { MP, MP_scheme }, - { MPRI, MPRI_scheme }, - { MPReg, MPReg_scheme } + { L"rdf", L"http://www.w3.org/1999/02/22-rdf-syntax-ns#" }, + { L"dc", L"http://purl.org/dc/elements/1.1/" }, + { L"xmp", L"http://ns.adobe.com/xap/1.0/" }, + { L"xmpidq", L"http://ns.adobe.com/xmp/Identifier/qual/1.0/" }, + { L"xmpRights", L"http://ns.adobe.com/xap/1.0/rights/" }, + { L"xmpMM", L"http://ns.adobe.com/xap/1.0/mm/" }, + { L"xmpBJ", L"http://ns.adobe.com/xap/1.0/bj/" }, + { L"xmpTPg", L"http://ns.adobe.com/xap/1.0/t/pg/" }, + { L"pdf", L"http://ns.adobe.com/pdf/1.3/" }, + { L"photoshop", L"http://ns.adobe.com/photoshop/1.0/" }, + { L"tiff", L"http://ns.adobe.com/tiff/1.0/" }, + { L"exif", L"http://ns.adobe.com/exif/1.0/" }, + { L"stDim", L"http://ns.adobe.com/xap/1.0/sType/Dimensions#" }, + { L"xapGImg", L"http://ns.adobe.com/xap/1.0/g/img/" }, + { L"stEvt", L"http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" }, + { L"stRef", L"http://ns.adobe.com/xap/1.0/sType/ResourceRef#" }, + { L"stVer", L"http://ns.adobe.com/xap/1.0/sType/Version#" }, + { L"stJob", L"http://ns.adobe.com/xap/1.0/sType/Job#" }, + { L"aux", L"http://ns.adobe.com/exif/1.0/aux/" }, + { L"crs", L"http://ns.adobe.com/camera-raw-settings/1.0/" }, + { L"xmpDM", L"http://ns.adobe.com/xmp/1.0/DynamicMedia/" }, + { L"Iptc4xmpCore", L"http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/" }, + { L"MicrosoftPhoto", L"http://ns.microsoft.com/photo/1.0/" }, + { L"MP", L"http://ns.microsoft.com/photo/1.2/" }, + { L"MPRI", L"http://ns.microsoft.com/photo/1.2/t/RegionInfo#" }, + { L"MPReg", L"http://ns.microsoft.com/photo/1.2/t/Region#" } }; static const WCHAR *map_shortname_to_schema(const GUID *format, const WCHAR *name) @@ -885,7 +1035,7 @@ static const WCHAR *map_shortname_to_schema(const GUID *format, const WCHAR *nam for (i = 0; i < ARRAY_SIZE(name2schema); i++) { - if (!lstrcmpW(name2schema[i].name, name)) + if (!wcscmp(name2schema[i].name, name)) return name2schema[i].schema; } @@ -910,7 +1060,7 @@ HRESULT WINAPI WICMapSchemaToName(REFGUID format, LPWSTR schema, UINT len, WCHAR for (i = 0; i < ARRAY_SIZE(name2schema); i++) { - if (!lstrcmpW(name2schema[i].schema, schema)) + if (!wcscmp(name2schema[i].schema, schema)) { if (name) { diff --git a/dll/win32/windowscodecs/palette.c b/dll/win32/windowscodecs/palette.c index f99cbe00fd1..b45d4f30c97 100644 --- a/dll/win32/windowscodecs/palette.c +++ b/dll/win32/windowscodecs/palette.c @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -76,7 +74,7 @@ static ULONG WINAPI PaletteImpl_AddRef(IWICPalette *iface) PaletteImpl *This = impl_from_IWICPalette(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -86,14 +84,14 @@ static ULONG WINAPI PaletteImpl_Release(IWICPalette *iface) PaletteImpl *This = impl_from_IWICPalette(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This->colors); - HeapFree(GetProcessHeap(), 0, This); + free(This->colors); + free(This); } return ref; @@ -105,7 +103,7 @@ static WICColor *generate_gray16_palette(UINT *count) UINT i; *count = 16; - entries = HeapAlloc(GetProcessHeap(), 0, 16 * sizeof(WICColor)); + entries = malloc(16 * sizeof(WICColor)); if (!entries) return NULL; for (i = 0; i < 16; i++) @@ -122,7 +120,7 @@ static WICColor *generate_gray256_palette(UINT *count) UINT i; *count = 256; - entries = HeapAlloc(GetProcessHeap(), 0, 256 * sizeof(WICColor)); + entries = malloc(256 * sizeof(WICColor)); if (!entries) return NULL; for (i = 0; i < 256; i++) @@ -139,7 +137,7 @@ static WICColor *generate_halftone8_palette(UINT *count, BOOL add_transparent) UINT i; *count = add_transparent ? 17 : 16; - entries = HeapAlloc(GetProcessHeap(), 0, *count * sizeof(WICColor)); + entries = malloc(*count * sizeof(WICColor)); if (!entries) return NULL; for (i = 0; i < 8; i++) @@ -170,7 +168,7 @@ static WICColor *generate_halftone27_palette(UINT *count, BOOL add_transparent) UINT i; *count = add_transparent ? 29 : 28; - entries = HeapAlloc(GetProcessHeap(), 0, *count * sizeof(WICColor)); + entries = malloc(*count * sizeof(WICColor)); if (!entries) return NULL; for (i = 0; i < 27; i++) @@ -195,7 +193,7 @@ static WICColor *generate_halftone64_palette(UINT *count, BOOL add_transparent) UINT i; *count = add_transparent ? 73 : 72; - entries = HeapAlloc(GetProcessHeap(), 0, *count * sizeof(WICColor)); + entries = malloc(*count * sizeof(WICColor)); if (!entries) return NULL; for (i = 0; i < 64; i++) @@ -227,7 +225,7 @@ static WICColor *generate_halftone125_palette(UINT *count, BOOL add_transparent) UINT i; *count = add_transparent ? 127 : 126; - entries = HeapAlloc(GetProcessHeap(), 0, *count * sizeof(WICColor)); + entries = malloc(*count * sizeof(WICColor)); if (!entries) return NULL; for (i = 0; i < 125; i++) @@ -252,7 +250,7 @@ static WICColor *generate_halftone216_palette(UINT *count, BOOL add_transparent) UINT i; *count = add_transparent ? 225 : 224; - entries = HeapAlloc(GetProcessHeap(), 0, *count * sizeof(WICColor)); + entries = malloc(*count * sizeof(WICColor)); if (!entries) return NULL; for (i = 0; i < 216; i++) @@ -284,7 +282,7 @@ static WICColor *generate_halftone252_palette(UINT *count, BOOL add_transparent) UINT i; *count = add_transparent ? 253 : 252; - entries = HeapAlloc(GetProcessHeap(), 0, *count * sizeof(WICColor)); + entries = malloc(*count * sizeof(WICColor)); if (!entries) return NULL; for (i = 0; i < 252; i++) @@ -309,7 +307,7 @@ static WICColor *generate_halftone256_palette(UINT *count, BOOL add_transparent) UINT i; *count = 256; - entries = HeapAlloc(GetProcessHeap(), 0, 256 * sizeof(WICColor)); + entries = malloc(256 * sizeof(WICColor)); if (!entries) return NULL; for (i = 0; i < 256; i++) @@ -341,7 +339,7 @@ static HRESULT WINAPI PaletteImpl_InitializePredefined(IWICPalette *iface, { case WICBitmapPaletteTypeFixedBW: count = 2; - colors = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WICColor)); + colors = malloc(count * sizeof(WICColor)); if (!colors) return E_OUTOFMEMORY; colors[0] = 0xff000000; colors[1] = 0xffffffff; @@ -349,7 +347,7 @@ static HRESULT WINAPI PaletteImpl_InitializePredefined(IWICPalette *iface, case WICBitmapPaletteTypeFixedGray4: count = 4; - colors = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WICColor)); + colors = malloc(count * sizeof(WICColor)); if (!colors) return E_OUTOFMEMORY; colors[0] = 0xff000000; colors[1] = 0xff555555; @@ -408,7 +406,7 @@ static HRESULT WINAPI PaletteImpl_InitializePredefined(IWICPalette *iface, } EnterCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This->colors); + free(This->colors); This->colors = colors; This->count = count; This->type = type; @@ -432,13 +430,13 @@ static HRESULT WINAPI PaletteImpl_InitializeCustom(IWICPalette *iface, else { if (!pColors) return E_INVALIDARG; - new_colors = HeapAlloc(GetProcessHeap(), 0, sizeof(WICColor) * colorCount); + new_colors = malloc(sizeof(WICColor) * colorCount); if (!new_colors) return E_OUTOFMEMORY; memcpy(new_colors, pColors, sizeof(WICColor) * colorCount); } EnterCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This->colors); + free(This->colors); This->colors = new_colors; This->count = colorCount; This->type = WICBitmapPaletteTypeCustom; @@ -614,7 +612,7 @@ static int median_cut(unsigned char *image, unsigned int width, unsigned int hei struct box *b1, *b2; int numboxes, i; - if (!(h = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*h)))) + if (!(h = calloc(1, sizeof(*h)))) return 0; for (y = 0; y < height; y++) @@ -643,7 +641,7 @@ static int median_cut(unsigned char *image, unsigned int width, unsigned int hei for (i = 0; i < numboxes; i++) colors[i] = box_color(h, &boxes[i]); - HeapFree(GetProcessHeap(), 0, h); + free(h); return numboxes; } @@ -681,7 +679,7 @@ static HRESULT WINAPI PaletteImpl_InitializeFromBitmap(IWICPalette *palette, else rgb24_source = source; - hr = ImagingFactory_CreateInstance(&IID_IWICImagingFactory, (void **)&factory); + hr = create_instance(&CLSID_WICImagingFactory, &IID_IWICImagingFactory, (void **)&factory); if (hr != S_OK) goto fail; hr = IWICImagingFactory_CreateBitmapFromSource(factory, rgb24_source, WICBitmapCacheOnLoad, &rgb24_bitmap); @@ -741,18 +739,18 @@ static HRESULT WINAPI PaletteImpl_InitializeFromPalette(IWICPalette *iface, if (hr != S_OK) return hr; if (count) { - colors = HeapAlloc(GetProcessHeap(), 0, sizeof(WICColor) * count); + colors = malloc(sizeof(WICColor) * count); if (!colors) return E_OUTOFMEMORY; hr = IWICPalette_GetColors(source, count, colors, &count); if (hr != S_OK) { - HeapFree(GetProcessHeap(), 0, colors); + free(colors); return hr; } } EnterCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This->colors); + free(This->colors); This->colors = colors; This->count = count; This->type = type; @@ -900,7 +898,7 @@ HRESULT PaletteImpl_Create(IWICPalette **palette) { PaletteImpl *This; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(PaletteImpl)); + This = malloc(sizeof(PaletteImpl)); if (!This) return E_OUTOFMEMORY; This->IWICPalette_iface.lpVtbl = &PaletteImpl_Vtbl; @@ -908,7 +906,11 @@ HRESULT PaletteImpl_Create(IWICPalette **palette) This->count = 0; This->colors = NULL; This->type = WICBitmapPaletteTypeCustom; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PaletteImpl.lock"); *palette = &This->IWICPalette_iface; diff --git a/dll/win32/windowscodecs/pngformat.c b/dll/win32/windowscodecs/pngformat.c index c0e272e86f0..0e69671c9b8 100644 --- a/dll/win32/windowscodecs/pngformat.c +++ b/dll/win32/windowscodecs/pngformat.c @@ -17,75 +17,29 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include -#ifdef HAVE_PNG_H -#include -#endif - -#define NONAMELESSUNION #define COBJMACROS #include "windef.h" #include "winbase.h" #include "objbase.h" +#include "shlwapi.h" #include "wincodecs_private.h" #include "wine/debug.h" -#include "wine/library.h" -WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); +static inline USHORT read_ushort_be(BYTE* data) +{ + return data[0] << 8 | data[1]; +} static inline ULONG read_ulong_be(BYTE* data) { return data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; } -static HRESULT read_png_chunk(IStream *stream, BYTE *type, BYTE **data, ULONG *data_size) -{ - BYTE header[8]; - HRESULT hr; - ULONG bytesread; - - hr = IStream_Read(stream, header, 8, &bytesread); - if (FAILED(hr) || bytesread < 8) - { - if (SUCCEEDED(hr)) - hr = E_FAIL; - return hr; - } - - *data_size = read_ulong_be(&header[0]); - - memcpy(type, &header[4], 4); - - if (data) - { - *data = HeapAlloc(GetProcessHeap(), 0, *data_size); - if (!*data) - return E_OUTOFMEMORY; - - hr = IStream_Read(stream, *data, *data_size, &bytesread); - - if (FAILED(hr) || bytesread < *data_size) - { - if (SUCCEEDED(hr)) - hr = E_FAIL; - HeapFree(GetProcessHeap(), 0, *data); - *data = NULL; - return hr; - } - - /* Windows ignores CRC of the chunk */ - } - - return S_OK; -} - static HRESULT LoadTextMetadata(IStream *stream, const GUID *preferred_vendor, DWORD persist_options, MetadataItem **items, DWORD *item_count) { @@ -107,21 +61,21 @@ static HRESULT LoadTextMetadata(IStream *stream, const GUID *preferred_vendor, if (!name_end_ptr || name_len > 79) { - HeapFree(GetProcessHeap(), 0, data); + free(data); return E_FAIL; } value_len = data_size - name_len - 1; - result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem)); - name = HeapAlloc(GetProcessHeap(), 0, name_len + 1); - value = HeapAlloc(GetProcessHeap(), 0, value_len + 1); + result = calloc(1, sizeof(MetadataItem)); + name = CoTaskMemAlloc(name_len + 1); + value = CoTaskMemAlloc(value_len + 1); if (!result || !name || !value) { - HeapFree(GetProcessHeap(), 0, data); - HeapFree(GetProcessHeap(), 0, result); - HeapFree(GetProcessHeap(), 0, name); - HeapFree(GetProcessHeap(), 0, value); + free(data); + free(result); + CoTaskMemFree(name); + CoTaskMemFree(value); return E_OUTOFMEMORY; } @@ -134,14 +88,14 @@ static HRESULT LoadTextMetadata(IStream *stream, const GUID *preferred_vendor, value[value_len] = 0; result[0].id.vt = VT_LPSTR; - result[0].id.u.pszVal = name; + result[0].id.pszVal = name; result[0].value.vt = VT_LPSTR; - result[0].value.u.pszVal = value; + result[0].value.pszVal = value; *items = result; *item_count = 1; - HeapFree(GetProcessHeap(), 0, data); + free(data); return S_OK; } @@ -165,7 +119,6 @@ static HRESULT LoadGamaMetadata(IStream *stream, const GUID *preferred_vendor, BYTE *data; ULONG data_size; ULONG gamma; - static const WCHAR ImageGamma[] = {'I','m','a','g','e','G','a','m','m','a',0}; LPWSTR name; MetadataItem *result; @@ -174,20 +127,20 @@ static HRESULT LoadGamaMetadata(IStream *stream, const GUID *preferred_vendor, if (data_size < 4) { - HeapFree(GetProcessHeap(), 0, data); + free(data); return E_FAIL; } gamma = read_ulong_be(data); - HeapFree(GetProcessHeap(), 0, data); + free(data); - result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem)); - name = HeapAlloc(GetProcessHeap(), 0, sizeof(ImageGamma)); + result = calloc(1, sizeof(MetadataItem)); + SHStrDupW(L"ImageGamma", &name); if (!result || !name) { - HeapFree(GetProcessHeap(), 0, result); - HeapFree(GetProcessHeap(), 0, name); + free(result); + CoTaskMemFree(name); return E_OUTOFMEMORY; } @@ -195,12 +148,10 @@ static HRESULT LoadGamaMetadata(IStream *stream, const GUID *preferred_vendor, PropVariantInit(&result[0].id); PropVariantInit(&result[0].value); - memcpy(name, ImageGamma, sizeof(ImageGamma)); - result[0].id.vt = VT_LPWSTR; - result[0].id.u.pwszVal = name; + result[0].id.pwszVal = name; result[0].value.vt = VT_UI4; - result[0].value.u.ulVal = gamma; + result[0].value.ulVal = gamma; *items = result; *item_count = 1; @@ -227,14 +178,14 @@ static HRESULT LoadChrmMetadata(IStream *stream, const GUID *preferred_vendor, BYTE *data; ULONG data_size; static const WCHAR names[8][12] = { - {'W','h','i','t','e','P','o','i','n','t','X',0}, - {'W','h','i','t','e','P','o','i','n','t','Y',0}, - {'R','e','d','X',0}, - {'R','e','d','Y',0}, - {'G','r','e','e','n','X',0}, - {'G','r','e','e','n','Y',0}, - {'B','l','u','e','X',0}, - {'B','l','u','e','Y',0}, + L"WhitePointX", + L"WhitePointY", + L"RedX", + L"RedY", + L"GreenX", + L"GreenY", + L"BlueX", + L"BlueY", }; LPWSTR dyn_names[8] = {0}; MetadataItem *result; @@ -245,22 +196,22 @@ static HRESULT LoadChrmMetadata(IStream *stream, const GUID *preferred_vendor, if (data_size < 32) { - HeapFree(GetProcessHeap(), 0, data); + free(data); return E_FAIL; } - result = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MetadataItem)*8); + result = calloc(8, sizeof(MetadataItem)); for (i=0; i<8; i++) { - dyn_names[i] = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(lstrlenW(names[i])+1)); + SHStrDupW(names[i], &dyn_names[i]); if (!dyn_names[i]) break; } if (!result || i < 8) { - HeapFree(GetProcessHeap(), 0, result); + free(result); for (i=0; i<8; i++) - HeapFree(GetProcessHeap(), 0, dyn_names[i]); - HeapFree(GetProcessHeap(), 0, data); + CoTaskMemFree(dyn_names[i]); + free(data); return E_OUTOFMEMORY; } @@ -270,18 +221,17 @@ static HRESULT LoadChrmMetadata(IStream *stream, const GUID *preferred_vendor, PropVariantInit(&result[i].id); result[i].id.vt = VT_LPWSTR; - result[i].id.u.pwszVal = dyn_names[i]; - lstrcpyW(dyn_names[i], names[i]); + result[i].id.pwszVal = dyn_names[i]; PropVariantInit(&result[i].value); result[i].value.vt = VT_UI4; - result[i].value.u.ulVal = read_ulong_be(&data[i*4]); + result[i].value.ulVal = read_ulong_be(&data[i*4]); } *items = result; *item_count = 8; - HeapFree(GetProcessHeap(), 0, data); + free(data); return S_OK; } @@ -297,1904 +247,179 @@ HRESULT PngChrmReader_CreateInstance(REFIID iid, void** ppv) return MetadataReader_Create(&ChrmReader_Vtbl, iid, ppv); } -#ifdef SONAME_LIBPNG - -static void *libpng_handle; -#define MAKE_FUNCPTR(f) static typeof(f) * p##f -MAKE_FUNCPTR(png_create_read_struct); -MAKE_FUNCPTR(png_create_info_struct); -MAKE_FUNCPTR(png_create_write_struct); -MAKE_FUNCPTR(png_destroy_read_struct); -MAKE_FUNCPTR(png_destroy_write_struct); -MAKE_FUNCPTR(png_error); -MAKE_FUNCPTR(png_get_bit_depth); -MAKE_FUNCPTR(png_get_color_type); -MAKE_FUNCPTR(png_get_error_ptr); -MAKE_FUNCPTR(png_get_iCCP); -MAKE_FUNCPTR(png_get_image_height); -MAKE_FUNCPTR(png_get_image_width); -MAKE_FUNCPTR(png_get_io_ptr); -MAKE_FUNCPTR(png_get_pHYs); -MAKE_FUNCPTR(png_get_PLTE); -MAKE_FUNCPTR(png_get_tRNS); -MAKE_FUNCPTR(png_set_bgr); -MAKE_FUNCPTR(png_set_crc_action); -MAKE_FUNCPTR(png_set_error_fn); -MAKE_FUNCPTR(png_set_filler); -MAKE_FUNCPTR(png_set_filter); -MAKE_FUNCPTR(png_set_gray_to_rgb); -MAKE_FUNCPTR(png_set_interlace_handling); -MAKE_FUNCPTR(png_set_IHDR); -MAKE_FUNCPTR(png_set_pHYs); -MAKE_FUNCPTR(png_set_PLTE); -MAKE_FUNCPTR(png_set_read_fn); -MAKE_FUNCPTR(png_set_strip_16); -MAKE_FUNCPTR(png_set_tRNS); -MAKE_FUNCPTR(png_set_tRNS_to_alpha); -MAKE_FUNCPTR(png_set_write_fn); -MAKE_FUNCPTR(png_set_swap); -MAKE_FUNCPTR(png_read_end); -MAKE_FUNCPTR(png_read_image); -MAKE_FUNCPTR(png_read_info); -MAKE_FUNCPTR(png_write_end); -MAKE_FUNCPTR(png_write_info); -MAKE_FUNCPTR(png_write_rows); -#undef MAKE_FUNCPTR - -static CRITICAL_SECTION init_png_cs; -static CRITICAL_SECTION_DEBUG init_png_cs_debug = -{ - 0, 0, &init_png_cs, - { &init_png_cs_debug.ProcessLocksList, - &init_png_cs_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": init_png_cs") } -}; -static CRITICAL_SECTION init_png_cs = { &init_png_cs_debug, -1, 0, 0, 0, 0 }; - -static const WCHAR wszPngInterlaceOption[] = {'I','n','t','e','r','l','a','c','e','O','p','t','i','o','n',0}; -static const WCHAR wszPngFilterOption[] = {'F','i','l','t','e','r','O','p','t','i','o','n',0}; - -static void *load_libpng(void) -{ - void *result; - - EnterCriticalSection(&init_png_cs); - - if(!libpng_handle && (libpng_handle = wine_dlopen(SONAME_LIBPNG, RTLD_NOW, NULL, 0)) != NULL) { - -#define LOAD_FUNCPTR(f) \ - if((p##f = wine_dlsym(libpng_handle, #f, NULL, 0)) == NULL) { \ - libpng_handle = NULL; \ - LeaveCriticalSection(&init_png_cs); \ - return NULL; \ - } - LOAD_FUNCPTR(png_create_read_struct); - LOAD_FUNCPTR(png_create_info_struct); - LOAD_FUNCPTR(png_create_write_struct); - LOAD_FUNCPTR(png_destroy_read_struct); - LOAD_FUNCPTR(png_destroy_write_struct); - LOAD_FUNCPTR(png_error); - LOAD_FUNCPTR(png_get_bit_depth); - LOAD_FUNCPTR(png_get_color_type); - LOAD_FUNCPTR(png_get_error_ptr); - LOAD_FUNCPTR(png_get_iCCP); - LOAD_FUNCPTR(png_get_image_height); - LOAD_FUNCPTR(png_get_image_width); - LOAD_FUNCPTR(png_get_io_ptr); - LOAD_FUNCPTR(png_get_pHYs); - LOAD_FUNCPTR(png_get_PLTE); - LOAD_FUNCPTR(png_get_tRNS); - LOAD_FUNCPTR(png_set_bgr); - LOAD_FUNCPTR(png_set_crc_action); - LOAD_FUNCPTR(png_set_error_fn); - LOAD_FUNCPTR(png_set_filler); - LOAD_FUNCPTR(png_set_filter); - LOAD_FUNCPTR(png_set_gray_to_rgb); - LOAD_FUNCPTR(png_set_interlace_handling); - LOAD_FUNCPTR(png_set_IHDR); - LOAD_FUNCPTR(png_set_pHYs); - LOAD_FUNCPTR(png_set_PLTE); - LOAD_FUNCPTR(png_set_read_fn); - LOAD_FUNCPTR(png_set_strip_16); - LOAD_FUNCPTR(png_set_tRNS); - LOAD_FUNCPTR(png_set_tRNS_to_alpha); - LOAD_FUNCPTR(png_set_write_fn); - LOAD_FUNCPTR(png_set_swap); - LOAD_FUNCPTR(png_read_end); - LOAD_FUNCPTR(png_read_image); - LOAD_FUNCPTR(png_read_info); - LOAD_FUNCPTR(png_write_end); - LOAD_FUNCPTR(png_write_info); - LOAD_FUNCPTR(png_write_rows); - -#undef LOAD_FUNCPTR - } - - result = libpng_handle; - - LeaveCriticalSection(&init_png_cs); - - return result; -} - -static void user_error_fn(png_structp png_ptr, png_const_charp error_message) -{ - jmp_buf *pjmpbuf; - - /* This uses setjmp/longjmp just like the default. We can't use the - * default because there's no way to access the jmp buffer in the png_struct - * that works in 1.2 and 1.4 and allows us to dynamically load libpng. */ - WARN("PNG error: %s\n", debugstr_a(error_message)); - pjmpbuf = ppng_get_error_ptr(png_ptr); - longjmp(*pjmpbuf, 1); -} - -static void user_warning_fn(png_structp png_ptr, png_const_charp warning_message) -{ - WARN("PNG warning: %s\n", debugstr_a(warning_message)); -} - -typedef struct { - ULARGE_INTEGER ofs, len; - IWICMetadataReader* reader; -} metadata_block_info; - -typedef struct { - IWICBitmapDecoder IWICBitmapDecoder_iface; - IWICBitmapFrameDecode IWICBitmapFrameDecode_iface; - IWICMetadataBlockReader IWICMetadataBlockReader_iface; - LONG ref; - IStream *stream; - png_structp png_ptr; - png_infop info_ptr; - png_infop end_info; - BOOL initialized; - int bpp; - int width, height; - UINT stride; - const WICPixelFormatGUID *format; - BYTE *image_bits; - CRITICAL_SECTION lock; /* must be held when png structures are accessed or initialized is set */ - ULONG metadata_count; - metadata_block_info* metadata_blocks; -} PngDecoder; - -static inline PngDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface) -{ - return CONTAINING_RECORD(iface, PngDecoder, IWICBitmapDecoder_iface); -} - -static inline PngDecoder *impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDecode *iface) -{ - return CONTAINING_RECORD(iface, PngDecoder, IWICBitmapFrameDecode_iface); -} - -static inline PngDecoder *impl_from_IWICMetadataBlockReader(IWICMetadataBlockReader *iface) -{ - return CONTAINING_RECORD(iface, PngDecoder, IWICMetadataBlockReader_iface); -} - -static const IWICBitmapFrameDecodeVtbl PngDecoder_FrameVtbl; - -static HRESULT WINAPI PngDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid, - void **ppv) -{ - PngDecoder *This = impl_from_IWICBitmapDecoder(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICBitmapDecoder, iid)) - { - *ppv = &This->IWICBitmapDecoder_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI PngDecoder_AddRef(IWICBitmapDecoder *iface) -{ - PngDecoder *This = impl_from_IWICBitmapDecoder(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - return ref; -} - -static ULONG WINAPI PngDecoder_Release(IWICBitmapDecoder *iface) -{ - PngDecoder *This = impl_from_IWICBitmapDecoder(iface); - ULONG ref = InterlockedDecrement(&This->ref); - ULONG i; - - TRACE("(%p) refcount=%u\n", iface, ref); - - if (ref == 0) - { - if (This->stream) - IStream_Release(This->stream); - if (This->png_ptr) - ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, &This->end_info); - This->lock.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This->image_bits); - for (i=0; imetadata_count; i++) - { - if (This->metadata_blocks[i].reader) - IWICMetadataReader_Release(This->metadata_blocks[i].reader); - } - HeapFree(GetProcessHeap(), 0, This->metadata_blocks); - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static HRESULT WINAPI PngDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *stream, - DWORD *capability) +static HRESULT LoadHistMetadata(IStream *stream, const GUID *preferred_vendor, + DWORD persist_options, MetadataItem **items, DWORD *item_count) { HRESULT hr; - - TRACE("(%p,%p,%p)\n", iface, stream, capability); - - if (!stream || !capability) return E_INVALIDARG; - - hr = IWICBitmapDecoder_Initialize(iface, stream, WICDecodeMetadataCacheOnDemand); - if (hr != S_OK) return hr; - - *capability = WICBitmapDecoderCapabilityCanDecodeAllImages | - WICBitmapDecoderCapabilityCanDecodeSomeImages; - /* FIXME: WICBitmapDecoderCapabilityCanEnumerateMetadata */ - return S_OK; -} - -static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) -{ - IStream *stream = ppng_get_io_ptr(png_ptr); - HRESULT hr; - ULONG bytesread; - - hr = IStream_Read(stream, data, length, &bytesread); - if (FAILED(hr) || bytesread != length) - { - ppng_error(png_ptr, "failed reading data"); - } -} - -static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream, - WICDecodeOptions cacheOptions) -{ - PngDecoder *This = impl_from_IWICBitmapDecoder(iface); - LARGE_INTEGER seek; - HRESULT hr=S_OK; - png_bytep *row_pointers=NULL; - UINT image_size; - UINT i; - int color_type, bit_depth; - png_bytep trans; - int num_trans; - png_uint_32 transparency; - png_color_16p trans_values; - jmp_buf jmpbuf; - BYTE chunk_type[4]; - ULONG chunk_size; - ULARGE_INTEGER chunk_start; - ULONG metadata_blocks_size = 0; - - TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions); - - EnterCriticalSection(&This->lock); - - /* initialize libpng */ - This->png_ptr = ppng_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!This->png_ptr) - { - hr = E_FAIL; - goto end; - } - - This->info_ptr = ppng_create_info_struct(This->png_ptr); - if (!This->info_ptr) - { - ppng_destroy_read_struct(&This->png_ptr, NULL, NULL); - This->png_ptr = NULL; - hr = E_FAIL; - goto end; - } - - This->end_info = ppng_create_info_struct(This->png_ptr); - if (!This->end_info) - { - ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, NULL); - This->png_ptr = NULL; - hr = E_FAIL; - goto end; - } - - /* set up setjmp/longjmp error handling */ - if (setjmp(jmpbuf)) - { - ppng_destroy_read_struct(&This->png_ptr, &This->info_ptr, &This->end_info); - This->png_ptr = NULL; - hr = WINCODEC_ERR_UNKNOWNIMAGEFORMAT; - goto end; - } - ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn); - ppng_set_crc_action(This->png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE); - - /* seek to the start of the stream */ - seek.QuadPart = 0; - hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL); - if (FAILED(hr)) goto end; - - /* set up custom i/o handling */ - ppng_set_read_fn(This->png_ptr, pIStream, user_read_data); - - /* read the header */ - ppng_read_info(This->png_ptr, This->info_ptr); - - /* choose a pixel format */ - color_type = ppng_get_color_type(This->png_ptr, This->info_ptr); - bit_depth = ppng_get_bit_depth(This->png_ptr, This->info_ptr); - - /* PNGs with bit-depth greater than 8 are network byte order. Windows does not expect this. */ - if (bit_depth > 8) - ppng_set_swap(This->png_ptr); - - /* check for color-keyed alpha */ - transparency = ppng_get_tRNS(This->png_ptr, This->info_ptr, &trans, &num_trans, &trans_values); - - if (transparency && (color_type == PNG_COLOR_TYPE_RGB || - (color_type == PNG_COLOR_TYPE_GRAY && bit_depth == 16))) - { - /* expand to RGBA */ - if (color_type == PNG_COLOR_TYPE_GRAY) - ppng_set_gray_to_rgb(This->png_ptr); - ppng_set_tRNS_to_alpha(This->png_ptr); - color_type = PNG_COLOR_TYPE_RGB_ALPHA; - } - - switch (color_type) - { - case PNG_COLOR_TYPE_GRAY_ALPHA: - /* WIC does not support grayscale alpha formats so use RGBA */ - ppng_set_gray_to_rgb(This->png_ptr); - /* fall through */ - case PNG_COLOR_TYPE_RGB_ALPHA: - This->bpp = bit_depth * 4; - switch (bit_depth) - { - case 8: - ppng_set_bgr(This->png_ptr); - This->format = &GUID_WICPixelFormat32bppBGRA; - break; - case 16: This->format = &GUID_WICPixelFormat64bppRGBA; break; - default: - ERR("invalid RGBA bit depth: %i\n", bit_depth); - hr = E_FAIL; - goto end; - } - break; - case PNG_COLOR_TYPE_GRAY: - This->bpp = bit_depth; - if (!transparency) - { - switch (bit_depth) - { - case 1: This->format = &GUID_WICPixelFormatBlackWhite; break; - case 2: This->format = &GUID_WICPixelFormat2bppGray; break; - case 4: This->format = &GUID_WICPixelFormat4bppGray; break; - case 8: This->format = &GUID_WICPixelFormat8bppGray; break; - case 16: This->format = &GUID_WICPixelFormat16bppGray; break; - default: - ERR("invalid grayscale bit depth: %i\n", bit_depth); - hr = E_FAIL; - goto end; - } - break; - } - /* else fall through */ - case PNG_COLOR_TYPE_PALETTE: - This->bpp = bit_depth; - switch (bit_depth) - { - case 1: This->format = &GUID_WICPixelFormat1bppIndexed; break; - case 2: This->format = &GUID_WICPixelFormat2bppIndexed; break; - case 4: This->format = &GUID_WICPixelFormat4bppIndexed; break; - case 8: This->format = &GUID_WICPixelFormat8bppIndexed; break; - default: - ERR("invalid indexed color bit depth: %i\n", bit_depth); - hr = E_FAIL; - goto end; - } - break; - case PNG_COLOR_TYPE_RGB: - This->bpp = bit_depth * 3; - switch (bit_depth) - { - case 8: - ppng_set_bgr(This->png_ptr); - This->format = &GUID_WICPixelFormat24bppBGR; - break; - case 16: This->format = &GUID_WICPixelFormat48bppRGB; break; - default: - ERR("invalid RGB color bit depth: %i\n", bit_depth); - hr = E_FAIL; - goto end; - } - break; - default: - ERR("invalid color type %i\n", color_type); - hr = E_FAIL; - goto end; - } - - /* read the image data */ - This->width = ppng_get_image_width(This->png_ptr, This->info_ptr); - This->height = ppng_get_image_height(This->png_ptr, This->info_ptr); - This->stride = (This->width * This->bpp + 7) / 8; - image_size = This->stride * This->height; - - This->image_bits = HeapAlloc(GetProcessHeap(), 0, image_size); - if (!This->image_bits) - { - hr = E_OUTOFMEMORY; - goto end; - } - - row_pointers = HeapAlloc(GetProcessHeap(), 0, sizeof(png_bytep)*This->height); - if (!row_pointers) - { - hr = E_OUTOFMEMORY; - goto end; - } - - for (i=0; iheight; i++) - row_pointers[i] = This->image_bits + i * This->stride; - - ppng_read_image(This->png_ptr, row_pointers); - - HeapFree(GetProcessHeap(), 0, row_pointers); - row_pointers = NULL; - - ppng_read_end(This->png_ptr, This->end_info); - - /* Find the metadata chunks in the file. */ - seek.QuadPart = 8; - - do - { - hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, &chunk_start); - if (FAILED(hr)) goto end; - - hr = read_png_chunk(pIStream, chunk_type, NULL, &chunk_size); - if (FAILED(hr)) goto end; - - if (chunk_type[0] >= 'a' && chunk_type[0] <= 'z' && - memcmp(chunk_type, "tRNS", 4) && memcmp(chunk_type, "pHYs", 4)) - { - /* This chunk is considered metadata. */ - if (This->metadata_count == metadata_blocks_size) - { - metadata_block_info* new_metadata_blocks; - ULONG new_metadata_blocks_size; - - new_metadata_blocks_size = 4 + metadata_blocks_size * 2; - new_metadata_blocks = HeapAlloc(GetProcessHeap(), 0, - new_metadata_blocks_size * sizeof(*new_metadata_blocks)); - - if (!new_metadata_blocks) - { - hr = E_OUTOFMEMORY; - goto end; - } - - memcpy(new_metadata_blocks, This->metadata_blocks, - This->metadata_count * sizeof(*new_metadata_blocks)); - - HeapFree(GetProcessHeap(), 0, This->metadata_blocks); - This->metadata_blocks = new_metadata_blocks; - metadata_blocks_size = new_metadata_blocks_size; - } - - This->metadata_blocks[This->metadata_count].ofs = chunk_start; - This->metadata_blocks[This->metadata_count].len.QuadPart = chunk_size + 12; - This->metadata_blocks[This->metadata_count].reader = NULL; - This->metadata_count++; - } - - seek.QuadPart = chunk_start.QuadPart + chunk_size + 12; /* skip data and CRC */ - } while (memcmp(chunk_type, "IEND", 4)); - - This->stream = pIStream; - IStream_AddRef(This->stream); - - This->initialized = TRUE; - -end: - LeaveCriticalSection(&This->lock); - - HeapFree(GetProcessHeap(), 0, row_pointers); - - return hr; -} - -static HRESULT WINAPI PngDecoder_GetContainerFormat(IWICBitmapDecoder *iface, - GUID *pguidContainerFormat) -{ - memcpy(pguidContainerFormat, &GUID_ContainerFormatPng, sizeof(GUID)); - return S_OK; -} - -static HRESULT WINAPI PngDecoder_GetDecoderInfo(IWICBitmapDecoder *iface, - IWICBitmapDecoderInfo **ppIDecoderInfo) -{ - TRACE("(%p,%p)\n", iface, ppIDecoderInfo); - - return get_decoder_info(&CLSID_WICPngDecoder, ppIDecoderInfo); -} - -static HRESULT WINAPI PngDecoder_CopyPalette(IWICBitmapDecoder *iface, - IWICPalette *palette) -{ - TRACE("(%p,%p)\n", iface, palette); - return WINCODEC_ERR_PALETTEUNAVAILABLE; -} - -static HRESULT WINAPI PngDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface, - IWICMetadataQueryReader **reader) -{ - TRACE("(%p,%p)\n", iface, reader); - - if (!reader) return E_INVALIDARG; - - *reader = NULL; - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI PngDecoder_GetPreview(IWICBitmapDecoder *iface, - IWICBitmapSource **ppIBitmapSource) -{ - TRACE("(%p,%p)\n", iface, ppIBitmapSource); - - if (!ppIBitmapSource) return E_INVALIDARG; - - *ppIBitmapSource = NULL; - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI PngDecoder_GetColorContexts(IWICBitmapDecoder *iface, - UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) -{ - TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI PngDecoder_GetThumbnail(IWICBitmapDecoder *iface, - IWICBitmapSource **ppIThumbnail) -{ - TRACE("(%p,%p)\n", iface, ppIThumbnail); - - if (!ppIThumbnail) return E_INVALIDARG; - - *ppIThumbnail = NULL; - return WINCODEC_ERR_CODECNOTHUMBNAIL; -} - -static HRESULT WINAPI PngDecoder_GetFrameCount(IWICBitmapDecoder *iface, - UINT *pCount) -{ - if (!pCount) return E_INVALIDARG; - - *pCount = 1; - return S_OK; -} - -static HRESULT WINAPI PngDecoder_GetFrame(IWICBitmapDecoder *iface, - UINT index, IWICBitmapFrameDecode **ppIBitmapFrame) -{ - PngDecoder *This = impl_from_IWICBitmapDecoder(iface); - TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame); - - if (!This->initialized) return WINCODEC_ERR_FRAMEMISSING; - - if (index != 0) return E_INVALIDARG; - - IWICBitmapDecoder_AddRef(iface); - - *ppIBitmapFrame = &This->IWICBitmapFrameDecode_iface; - - return S_OK; -} - -static const IWICBitmapDecoderVtbl PngDecoder_Vtbl = { - PngDecoder_QueryInterface, - PngDecoder_AddRef, - PngDecoder_Release, - PngDecoder_QueryCapability, - PngDecoder_Initialize, - PngDecoder_GetContainerFormat, - PngDecoder_GetDecoderInfo, - PngDecoder_CopyPalette, - PngDecoder_GetMetadataQueryReader, - PngDecoder_GetPreview, - PngDecoder_GetColorContexts, - PngDecoder_GetThumbnail, - PngDecoder_GetFrameCount, - PngDecoder_GetFrame -}; - -static HRESULT WINAPI PngDecoder_Frame_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid, - void **ppv) -{ - PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapSource, iid) || - IsEqualIID(&IID_IWICBitmapFrameDecode, iid)) - { - *ppv = &This->IWICBitmapFrameDecode_iface; - } - else if (IsEqualIID(&IID_IWICMetadataBlockReader, iid)) - { - *ppv = &This->IWICMetadataBlockReader_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI PngDecoder_Frame_AddRef(IWICBitmapFrameDecode *iface) -{ - PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - return IWICBitmapDecoder_AddRef(&This->IWICBitmapDecoder_iface); -} - -static ULONG WINAPI PngDecoder_Frame_Release(IWICBitmapFrameDecode *iface) -{ - PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - return IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface); -} - -static HRESULT WINAPI PngDecoder_Frame_GetSize(IWICBitmapFrameDecode *iface, - UINT *puiWidth, UINT *puiHeight) -{ - PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - *puiWidth = This->width; - *puiHeight = This->height; - TRACE("(%p)->(%u,%u)\n", iface, *puiWidth, *puiHeight); - return S_OK; -} - -static HRESULT WINAPI PngDecoder_Frame_GetPixelFormat(IWICBitmapFrameDecode *iface, - WICPixelFormatGUID *pPixelFormat) -{ - PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - TRACE("(%p,%p)\n", iface, pPixelFormat); - - memcpy(pPixelFormat, This->format, sizeof(GUID)); - - return S_OK; -} - -static HRESULT WINAPI PngDecoder_Frame_GetResolution(IWICBitmapFrameDecode *iface, - double *pDpiX, double *pDpiY) -{ - PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - png_uint_32 ret, xres, yres; - int unit_type; - - EnterCriticalSection(&This->lock); - - ret = ppng_get_pHYs(This->png_ptr, This->info_ptr, &xres, &yres, &unit_type); - - if (ret && unit_type == PNG_RESOLUTION_METER) - { - *pDpiX = xres * 0.0254; - *pDpiY = yres * 0.0254; - } - else - { - WARN("no pHYs block present\n"); - *pDpiX = *pDpiY = 96.0; - } - - LeaveCriticalSection(&This->lock); - - TRACE("(%p)->(%0.2f,%0.2f)\n", iface, *pDpiX, *pDpiY); - - return S_OK; -} - -static HRESULT WINAPI PngDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface, - IWICPalette *pIPalette) -{ - PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - png_uint_32 ret, color_type, bit_depth; - png_colorp png_palette; - int num_palette; - WICColor palette[256]; - png_bytep trans_alpha; - int num_trans; - png_color_16p trans_values; - int i; - HRESULT hr=S_OK; - - TRACE("(%p,%p)\n", iface, pIPalette); - - EnterCriticalSection(&This->lock); - - color_type = ppng_get_color_type(This->png_ptr, This->info_ptr); - bit_depth = ppng_get_bit_depth(This->png_ptr, This->info_ptr); - - if (color_type == PNG_COLOR_TYPE_PALETTE) - { - ret = ppng_get_PLTE(This->png_ptr, This->info_ptr, &png_palette, &num_palette); - if (!ret) - { - hr = WINCODEC_ERR_PALETTEUNAVAILABLE; - goto end; - } - - if (num_palette > 256) - { - ERR("palette has %i colors?!\n", num_palette); - hr = E_FAIL; - goto end; - } - - ret = ppng_get_tRNS(This->png_ptr, This->info_ptr, &trans_alpha, &num_trans, &trans_values); - if (!ret) num_trans = 0; - - for (i=0; ipng_ptr, This->info_ptr, &trans_alpha, &num_trans, &trans_values); - - if (!ret) - { - hr = WINCODEC_ERR_PALETTEUNAVAILABLE; - goto end; - } - - num_palette = 1 << bit_depth; - - for (i=0; ilock); - - if (SUCCEEDED(hr)) - hr = IWICPalette_InitializeCustom(pIPalette, palette, num_palette); - - return hr; -} - -static HRESULT WINAPI PngDecoder_Frame_CopyPixels(IWICBitmapFrameDecode *iface, - const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) -{ - PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - TRACE("(%p,%s,%u,%u,%p)\n", iface, debug_wic_rect(prc), cbStride, cbBufferSize, pbBuffer); - - return copy_pixels(This->bpp, This->image_bits, - This->width, This->height, This->stride, - prc, cbStride, cbBufferSize, pbBuffer); -} - -static HRESULT WINAPI PngDecoder_Frame_GetMetadataQueryReader(IWICBitmapFrameDecode *iface, - IWICMetadataQueryReader **ppIMetadataQueryReader) -{ - PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - - TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader); - - if (!ppIMetadataQueryReader) - return E_INVALIDARG; - - return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, NULL, ppIMetadataQueryReader); -} - -static HRESULT WINAPI PngDecoder_Frame_GetColorContexts(IWICBitmapFrameDecode *iface, - UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) -{ - PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface); - png_charp name; - BYTE *profile; - png_uint_32 len; - int compression_type; - HRESULT hr; - - TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount); - - if (!pcActualCount) return E_INVALIDARG; - - EnterCriticalSection(&This->lock); - - if (ppng_get_iCCP(This->png_ptr, This->info_ptr, &name, &compression_type, (void *)&profile, &len)) - { - if (cCount && ppIColorContexts) - { - hr = IWICColorContext_InitializeFromMemory(*ppIColorContexts, profile, len); - if (FAILED(hr)) - { - LeaveCriticalSection(&This->lock); - return hr; - } - } - *pcActualCount = 1; - } - else - *pcActualCount = 0; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI PngDecoder_Frame_GetThumbnail(IWICBitmapFrameDecode *iface, - IWICBitmapSource **ppIThumbnail) -{ - TRACE("(%p,%p)\n", iface, ppIThumbnail); - - if (!ppIThumbnail) return E_INVALIDARG; - - *ppIThumbnail = NULL; - return WINCODEC_ERR_CODECNOTHUMBNAIL; -} - -static const IWICBitmapFrameDecodeVtbl PngDecoder_FrameVtbl = { - PngDecoder_Frame_QueryInterface, - PngDecoder_Frame_AddRef, - PngDecoder_Frame_Release, - PngDecoder_Frame_GetSize, - PngDecoder_Frame_GetPixelFormat, - PngDecoder_Frame_GetResolution, - PngDecoder_Frame_CopyPalette, - PngDecoder_Frame_CopyPixels, - PngDecoder_Frame_GetMetadataQueryReader, - PngDecoder_Frame_GetColorContexts, - PngDecoder_Frame_GetThumbnail -}; - -static HRESULT WINAPI PngDecoder_Block_QueryInterface(IWICMetadataBlockReader *iface, REFIID iid, - void **ppv) -{ - PngDecoder *This = impl_from_IWICMetadataBlockReader(iface); - return IWICBitmapFrameDecode_QueryInterface(&This->IWICBitmapFrameDecode_iface, iid, ppv); -} - -static ULONG WINAPI PngDecoder_Block_AddRef(IWICMetadataBlockReader *iface) -{ - PngDecoder *This = impl_from_IWICMetadataBlockReader(iface); - return IWICBitmapDecoder_AddRef(&This->IWICBitmapDecoder_iface); -} - -static ULONG WINAPI PngDecoder_Block_Release(IWICMetadataBlockReader *iface) -{ - PngDecoder *This = impl_from_IWICMetadataBlockReader(iface); - return IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface); -} - -static HRESULT WINAPI PngDecoder_Block_GetContainerFormat(IWICMetadataBlockReader *iface, - GUID *pguidContainerFormat) -{ - if (!pguidContainerFormat) return E_INVALIDARG; - memcpy(pguidContainerFormat, &GUID_ContainerFormatPng, sizeof(GUID)); - return S_OK; -} - -static HRESULT WINAPI PngDecoder_Block_GetCount(IWICMetadataBlockReader *iface, - UINT *pcCount) -{ - PngDecoder *This = impl_from_IWICMetadataBlockReader(iface); - - TRACE("%p,%p\n", iface, pcCount); - - if (!pcCount) return E_INVALIDARG; - - *pcCount = This->metadata_count; - - return S_OK; -} - -static HRESULT WINAPI PngDecoder_Block_GetReaderByIndex(IWICMetadataBlockReader *iface, - UINT nIndex, IWICMetadataReader **ppIMetadataReader) -{ - PngDecoder *This = impl_from_IWICMetadataBlockReader(iface); - HRESULT hr; - IWICComponentFactory* factory; - IWICStream* stream; - - TRACE("%p,%d,%p\n", iface, nIndex, ppIMetadataReader); - - if (nIndex >= This->metadata_count || !ppIMetadataReader) - return E_INVALIDARG; - - if (!This->metadata_blocks[nIndex].reader) - { - hr = StreamImpl_Create(&stream); - - if (SUCCEEDED(hr)) - { - hr = IWICStream_InitializeFromIStreamRegion(stream, This->stream, - This->metadata_blocks[nIndex].ofs, This->metadata_blocks[nIndex].len); - - if (SUCCEEDED(hr)) - hr = ImagingFactory_CreateInstance(&IID_IWICComponentFactory, (void**)&factory); - - if (SUCCEEDED(hr)) - { - hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, - &GUID_ContainerFormatPng, NULL, WICMetadataCreationAllowUnknown, - (IStream*)stream, &This->metadata_blocks[nIndex].reader); - - IWICComponentFactory_Release(factory); - } - - IWICStream_Release(stream); - } - - if (FAILED(hr)) - { - *ppIMetadataReader = NULL; - return hr; - } - } - - *ppIMetadataReader = This->metadata_blocks[nIndex].reader; - IWICMetadataReader_AddRef(*ppIMetadataReader); - - return S_OK; -} - -static HRESULT WINAPI PngDecoder_Block_GetEnumerator(IWICMetadataBlockReader *iface, - IEnumUnknown **ppIEnumMetadata) -{ - FIXME("%p,%p\n", iface, ppIEnumMetadata); - return E_NOTIMPL; -} - -static const IWICMetadataBlockReaderVtbl PngDecoder_BlockVtbl = { - PngDecoder_Block_QueryInterface, - PngDecoder_Block_AddRef, - PngDecoder_Block_Release, - PngDecoder_Block_GetContainerFormat, - PngDecoder_Block_GetCount, - PngDecoder_Block_GetReaderByIndex, - PngDecoder_Block_GetEnumerator, -}; - -HRESULT PngDecoder_CreateInstance(REFIID iid, void** ppv) -{ - PngDecoder *This; - HRESULT ret; - - TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); - - *ppv = NULL; - - if (!load_libpng()) - { - ERR("Failed reading PNG because unable to find %s\n",SONAME_LIBPNG); - return E_FAIL; - } - - This = HeapAlloc(GetProcessHeap(), 0, sizeof(PngDecoder)); - if (!This) return E_OUTOFMEMORY; - - This->IWICBitmapDecoder_iface.lpVtbl = &PngDecoder_Vtbl; - This->IWICBitmapFrameDecode_iface.lpVtbl = &PngDecoder_FrameVtbl; - This->IWICMetadataBlockReader_iface.lpVtbl = &PngDecoder_BlockVtbl; - This->ref = 1; - This->png_ptr = NULL; - This->info_ptr = NULL; - This->end_info = NULL; - This->stream = NULL; - This->initialized = FALSE; - This->image_bits = NULL; - InitializeCriticalSection(&This->lock); - This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PngDecoder.lock"); - This->metadata_count = 0; - This->metadata_blocks = NULL; - - ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); - IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface); - - return ret; -} - -struct png_pixelformat { - const WICPixelFormatGUID *guid; - UINT bpp; - int bit_depth; - int color_type; - BOOL remove_filler; - BOOL swap_rgb; -}; - -static const struct png_pixelformat formats[] = { - {&GUID_WICPixelFormat32bppBGRA, 32, 8, PNG_COLOR_TYPE_RGB_ALPHA, 0, 1}, - {&GUID_WICPixelFormat24bppBGR, 24, 8, PNG_COLOR_TYPE_RGB, 0, 1}, - {&GUID_WICPixelFormatBlackWhite, 1, 1, PNG_COLOR_TYPE_GRAY, 0, 0}, - {&GUID_WICPixelFormat2bppGray, 2, 2, PNG_COLOR_TYPE_GRAY, 0, 0}, - {&GUID_WICPixelFormat4bppGray, 4, 4, PNG_COLOR_TYPE_GRAY, 0, 0}, - {&GUID_WICPixelFormat8bppGray, 8, 8, PNG_COLOR_TYPE_GRAY, 0, 0}, - {&GUID_WICPixelFormat16bppGray, 16, 16, PNG_COLOR_TYPE_GRAY, 0, 0}, - {&GUID_WICPixelFormat32bppBGR, 32, 8, PNG_COLOR_TYPE_RGB, 1, 1}, - {&GUID_WICPixelFormat48bppRGB, 48, 16, PNG_COLOR_TYPE_RGB, 0, 0}, - {&GUID_WICPixelFormat64bppRGBA, 64, 16, PNG_COLOR_TYPE_RGB_ALPHA, 0, 0}, - {&GUID_WICPixelFormat1bppIndexed, 1, 1, PNG_COLOR_TYPE_PALETTE, 0, 0}, - {&GUID_WICPixelFormat2bppIndexed, 2, 2, PNG_COLOR_TYPE_PALETTE, 0, 0}, - {&GUID_WICPixelFormat4bppIndexed, 4, 4, PNG_COLOR_TYPE_PALETTE, 0, 0}, - {&GUID_WICPixelFormat8bppIndexed, 8, 8, PNG_COLOR_TYPE_PALETTE, 0, 0}, - {NULL}, -}; - -typedef struct PngEncoder { - IWICBitmapEncoder IWICBitmapEncoder_iface; - IWICBitmapFrameEncode IWICBitmapFrameEncode_iface; - LONG ref; - IStream *stream; - png_structp png_ptr; - png_infop info_ptr; - UINT frame_count; - BOOL frame_initialized; - const struct png_pixelformat *format; - BOOL info_written; - UINT width, height; - double xres, yres; - UINT lines_written; - BOOL frame_committed; - BOOL committed; - CRITICAL_SECTION lock; - BOOL interlace; - WICPngFilterOption filter; + BYTE type[4]; BYTE *data; - UINT stride; - UINT passes; - WICColor palette[256]; - UINT colors; -} PngEncoder; + ULONG data_size, element_count, i; + LPWSTR name; + MetadataItem *result; + USHORT *elements; -static inline PngEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface) -{ - return CONTAINING_RECORD(iface, PngEncoder, IWICBitmapEncoder_iface); -} + hr = read_png_chunk(stream, type, &data, &data_size); + if (FAILED(hr)) return hr; -static inline PngEncoder *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface) -{ - return CONTAINING_RECORD(iface, PngEncoder, IWICBitmapFrameEncode_iface); -} - -static HRESULT WINAPI PngFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid, - void **ppv) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapFrameEncode, iid)) + element_count = data_size / 2; + elements = CoTaskMemAlloc(element_count * sizeof(USHORT)); + if (!elements) { - *ppv = &This->IWICBitmapFrameEncode_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; + free(data); + return E_OUTOFMEMORY; } + for (i = 0; i < element_count; i++) + elements[i] = read_ushort_be(data + i * 2); - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} + free(data); -static ULONG WINAPI PngFrameEncode_AddRef(IWICBitmapFrameEncode *iface) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - return IWICBitmapEncoder_AddRef(&This->IWICBitmapEncoder_iface); -} - -static ULONG WINAPI PngFrameEncode_Release(IWICBitmapFrameEncode *iface) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - return IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface); -} - -static HRESULT WINAPI PngFrameEncode_Initialize(IWICBitmapFrameEncode *iface, - IPropertyBag2 *pIEncoderOptions) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - WICPngFilterOption filter; - BOOL interlace; - PROPBAG2 opts[2]= {{0}}; - VARIANT opt_values[2]; - HRESULT opt_hres[2]; - HRESULT hr; - - TRACE("(%p,%p)\n", iface, pIEncoderOptions); - - opts[0].pstrName = (LPOLESTR)wszPngInterlaceOption; - opts[0].vt = VT_BOOL; - opts[1].pstrName = (LPOLESTR)wszPngFilterOption; - opts[1].vt = VT_UI1; - - if (pIEncoderOptions) - { - hr = IPropertyBag2_Read(pIEncoderOptions, ARRAY_SIZE(opts), opts, NULL, opt_values, opt_hres); - - if (FAILED(hr)) - return hr; - - if (V_VT(&opt_values[0]) == VT_EMPTY) - interlace = FALSE; - else - interlace = (V_BOOL(&opt_values[0]) != 0); - - filter = V_UI1(&opt_values[1]); - if (filter > WICPngFilterAdaptive) - { - WARN("Unrecognized filter option value %u.\n", filter); - filter = WICPngFilterUnspecified; - } - } - else - { - interlace = FALSE; - filter = WICPngFilterUnspecified; - } - - EnterCriticalSection(&This->lock); - - if (This->frame_initialized) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->interlace = interlace; - This->filter = filter; - - This->frame_initialized = TRUE; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI PngFrameEncode_SetSize(IWICBitmapFrameEncode *iface, - UINT uiWidth, UINT uiHeight) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight); - - EnterCriticalSection(&This->lock); - - if (!This->frame_initialized || This->info_written) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->width = uiWidth; - This->height = uiHeight; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI PngFrameEncode_SetResolution(IWICBitmapFrameEncode *iface, - double dpiX, double dpiY) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY); - - EnterCriticalSection(&This->lock); - - if (!This->frame_initialized || This->info_written) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->xres = dpiX; - This->yres = dpiY; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI PngFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface, - WICPixelFormatGUID *pPixelFormat) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - int i; - TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat)); - - EnterCriticalSection(&This->lock); - - if (!This->frame_initialized || This->info_written) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - for (i=0; formats[i].guid; i++) - { - if (memcmp(formats[i].guid, pPixelFormat, sizeof(GUID)) == 0) - break; - } - - if (!formats[i].guid) i = 0; - - This->format = &formats[i]; - memcpy(pPixelFormat, This->format->guid, sizeof(GUID)); - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI PngFrameEncode_SetColorContexts(IWICBitmapFrameEncode *iface, - UINT cCount, IWICColorContext **ppIColorContext) -{ - FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); - return E_NOTIMPL; -} - -static HRESULT WINAPI PngFrameEncode_SetPalette(IWICBitmapFrameEncode *iface, - IWICPalette *palette) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr; - - TRACE("(%p,%p)\n", iface, palette); - - if (!palette) return E_INVALIDARG; - - EnterCriticalSection(&This->lock); - - if (This->frame_initialized) - hr = IWICPalette_GetColors(palette, 256, This->palette, &This->colors); - else - hr = WINCODEC_ERR_NOTINITIALIZED; - - LeaveCriticalSection(&This->lock); - return hr; -} - -static HRESULT WINAPI PngFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface, - IWICBitmapSource *pIThumbnail) -{ - FIXME("(%p,%p): stub\n", iface, pIThumbnail); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI PngFrameEncode_WritePixels(IWICBitmapFrameEncode *iface, - UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - png_byte **row_pointers=NULL; - UINT i; - jmp_buf jmpbuf; - TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels); - - EnterCriticalSection(&This->lock); - - if (!This->frame_initialized || !This->width || !This->height || !This->format) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - if (lineCount == 0 || lineCount + This->lines_written > This->height) - { - LeaveCriticalSection(&This->lock); - return E_INVALIDARG; - } - - /* set up setjmp/longjmp error handling */ - if (setjmp(jmpbuf)) - { - LeaveCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, row_pointers); - return E_FAIL; - } - ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn); - - if (!This->info_written) - { - if (This->interlace) - { - /* libpng requires us to write all data multiple times in this case. */ - This->stride = (This->format->bpp * This->width + 7)/8; - This->data = HeapAlloc(GetProcessHeap(), 0, This->height * This->stride); - if (!This->data) - { - LeaveCriticalSection(&This->lock); - return E_OUTOFMEMORY; - } - } - - /* Tell PNG we need to byte swap if writing a >8-bpp image */ - if (This->format->bit_depth > 8) - ppng_set_swap(This->png_ptr); - - ppng_set_IHDR(This->png_ptr, This->info_ptr, This->width, This->height, - This->format->bit_depth, This->format->color_type, - This->interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - - if (This->xres != 0.0 && This->yres != 0.0) - { - ppng_set_pHYs(This->png_ptr, This->info_ptr, (This->xres+0.0127) / 0.0254, - (This->yres+0.0127) / 0.0254, PNG_RESOLUTION_METER); - } - - if (This->format->color_type == PNG_COLOR_TYPE_PALETTE && This->colors) - { - png_color png_palette[256]; - png_byte trans[256]; - UINT i, num_trans = 0, colors; - - /* Newer libpng versions don't accept larger palettes than the declared - * bit depth, so we need to generate the palette of the correct length. - */ - colors = min(This->colors, 1 << This->format->bit_depth); - - for (i = 0; i < colors; i++) - { - png_palette[i].red = (This->palette[i] >> 16) & 0xff; - png_palette[i].green = (This->palette[i] >> 8) & 0xff; - png_palette[i].blue = This->palette[i] & 0xff; - trans[i] = (This->palette[i] >> 24) & 0xff; - if (trans[i] != 0xff) - num_trans = i+1; - } - - ppng_set_PLTE(This->png_ptr, This->info_ptr, png_palette, colors); - - if (num_trans) - ppng_set_tRNS(This->png_ptr, This->info_ptr, trans, num_trans, NULL); - } - - ppng_write_info(This->png_ptr, This->info_ptr); - - if (This->format->remove_filler) - ppng_set_filler(This->png_ptr, 0, PNG_FILLER_AFTER); - - if (This->format->swap_rgb) - ppng_set_bgr(This->png_ptr); - - if (This->interlace) - This->passes = ppng_set_interlace_handling(This->png_ptr); - - if (This->filter != WICPngFilterUnspecified) - { - static const int png_filter_map[] = - { - /* WICPngFilterUnspecified */ PNG_NO_FILTERS, - /* WICPngFilterNone */ PNG_FILTER_NONE, - /* WICPngFilterSub */ PNG_FILTER_SUB, - /* WICPngFilterUp */ PNG_FILTER_UP, - /* WICPngFilterAverage */ PNG_FILTER_AVG, - /* WICPngFilterPaeth */ PNG_FILTER_PAETH, - /* WICPngFilterAdaptive */ PNG_ALL_FILTERS, - }; - - ppng_set_filter(This->png_ptr, 0, png_filter_map[This->filter]); - } - - This->info_written = TRUE; - } - - if (This->interlace) - { - /* Just store the data so we can write it in multiple passes in Commit. */ - for (i=0; idata + This->stride * (This->lines_written + i), - pbPixels + cbStride * i, - This->stride); - - This->lines_written += lineCount; - - LeaveCriticalSection(&This->lock); - return S_OK; - } - - row_pointers = HeapAlloc(GetProcessHeap(), 0, lineCount * sizeof(png_byte*)); - if (!row_pointers) - { - LeaveCriticalSection(&This->lock); + result = calloc(1, sizeof(MetadataItem)); + SHStrDupW(L"Frequencies", &name); + if (!result || !name) { + free(result); + CoTaskMemFree(name); + CoTaskMemFree(elements); return E_OUTOFMEMORY; } - for (i=0; ipng_ptr, row_pointers, lineCount); - This->lines_written += lineCount; + result[0].id.vt = VT_LPWSTR; + result[0].id.pwszVal = name; - LeaveCriticalSection(&This->lock); + result[0].value.vt = VT_UI2|VT_VECTOR; + result[0].value.caui.cElems = element_count; + result[0].value.caui.pElems = elements; - HeapFree(GetProcessHeap(), 0, row_pointers); + *items = result; + *item_count = 1; return S_OK; } -static HRESULT WINAPI PngFrameEncode_WriteSource(IWICBitmapFrameEncode *iface, - IWICBitmapSource *pIBitmapSource, WICRect *prc) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr; - TRACE("(%p,%p,%s)\n", iface, pIBitmapSource, debug_wic_rect(prc)); - - if (!This->frame_initialized) - return WINCODEC_ERR_WRONGSTATE; - - hr = configure_write_source(iface, pIBitmapSource, prc, - This->format ? This->format->guid : NULL, This->width, This->height, - This->xres, This->yres); - - if (SUCCEEDED(hr)) - { - hr = write_source(iface, pIBitmapSource, prc, - This->format->guid, This->format->bpp, This->width, This->height); - } - - return hr; -} - -static HRESULT WINAPI PngFrameEncode_Commit(IWICBitmapFrameEncode *iface) -{ - PngEncoder *This = impl_from_IWICBitmapFrameEncode(iface); - png_byte **row_pointers=NULL; - jmp_buf jmpbuf; - TRACE("(%p)\n", iface); - - EnterCriticalSection(&This->lock); - - if (!This->info_written || This->lines_written != This->height || This->frame_committed) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - /* set up setjmp/longjmp error handling */ - if (setjmp(jmpbuf)) - { - LeaveCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, row_pointers); - return E_FAIL; - } - ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn); - - if (This->interlace) - { - int i; - - row_pointers = HeapAlloc(GetProcessHeap(), 0, This->height * sizeof(png_byte*)); - if (!row_pointers) - { - LeaveCriticalSection(&This->lock); - return E_OUTOFMEMORY; - } - - for (i=0; iheight; i++) - row_pointers[i] = This->data + This->stride * i; - - for (i=0; ipasses; i++) - ppng_write_rows(This->png_ptr, row_pointers, This->height); - } - - ppng_write_end(This->png_ptr, This->info_ptr); - - This->frame_committed = TRUE; - - HeapFree(GetProcessHeap(), 0, row_pointers); - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI PngFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface, - IWICMetadataQueryWriter **ppIMetadataQueryWriter) -{ - FIXME("(%p, %p): stub\n", iface, ppIMetadataQueryWriter); - return E_NOTIMPL; -} - -static const IWICBitmapFrameEncodeVtbl PngEncoder_FrameVtbl = { - PngFrameEncode_QueryInterface, - PngFrameEncode_AddRef, - PngFrameEncode_Release, - PngFrameEncode_Initialize, - PngFrameEncode_SetSize, - PngFrameEncode_SetResolution, - PngFrameEncode_SetPixelFormat, - PngFrameEncode_SetColorContexts, - PngFrameEncode_SetPalette, - PngFrameEncode_SetThumbnail, - PngFrameEncode_WritePixels, - PngFrameEncode_WriteSource, - PngFrameEncode_Commit, - PngFrameEncode_GetMetadataQueryWriter +static const MetadataHandlerVtbl HistReader_Vtbl = { + 0, + &CLSID_WICPngHistMetadataReader, + LoadHistMetadata }; -static HRESULT WINAPI PngEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid, - void **ppv) +HRESULT PngHistReader_CreateInstance(REFIID iid, void** ppv) { - PngEncoder *This = impl_from_IWICBitmapEncoder(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapEncoder, iid)) - { - *ppv = &This->IWICBitmapEncoder_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; + return MetadataReader_Create(&HistReader_Vtbl, iid, ppv); } -static ULONG WINAPI PngEncoder_AddRef(IWICBitmapEncoder *iface) +static HRESULT LoadTimeMetadata(IStream *stream, const GUID *preferred_vendor, + DWORD persist_options, MetadataItem **items, DWORD *item_count) { - PngEncoder *This = impl_from_IWICBitmapEncoder(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - return ref; -} - -static ULONG WINAPI PngEncoder_Release(IWICBitmapEncoder *iface) -{ - PngEncoder *This = impl_from_IWICBitmapEncoder(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - if (ref == 0) - { - This->lock.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->lock); - if (This->png_ptr) - ppng_destroy_write_struct(&This->png_ptr, &This->info_ptr); - if (This->stream) - IStream_Release(This->stream); - HeapFree(GetProcessHeap(), 0, This->data); - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static void user_write_data(png_structp png_ptr, png_bytep data, png_size_t length) -{ - PngEncoder *This = ppng_get_io_ptr(png_ptr); HRESULT hr; - ULONG byteswritten; - - hr = IStream_Write(This->stream, data, length, &byteswritten); - if (FAILED(hr) || byteswritten != length) + BYTE type[4]; + BYTE *data; + ULONG data_size, i; + MetadataItem *result; + static const WCHAR *names[6] = { - ppng_error(png_ptr, "failed writing data"); - } -} - -static void user_flush(png_structp png_ptr) -{ -} - -static HRESULT WINAPI PngEncoder_Initialize(IWICBitmapEncoder *iface, - IStream *pIStream, WICBitmapEncoderCacheOption cacheOption) -{ - PngEncoder *This = impl_from_IWICBitmapEncoder(iface); - jmp_buf jmpbuf; - - TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption); - - EnterCriticalSection(&This->lock); - - if (This->png_ptr) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - /* initialize libpng */ - This->png_ptr = ppng_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!This->png_ptr) - { - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - - This->info_ptr = ppng_create_info_struct(This->png_ptr); - if (!This->info_ptr) - { - ppng_destroy_write_struct(&This->png_ptr, NULL); - This->png_ptr = NULL; - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - - IStream_AddRef(pIStream); - This->stream = pIStream; - - /* set up setjmp/longjmp error handling */ - if (setjmp(jmpbuf)) - { - ppng_destroy_write_struct(&This->png_ptr, &This->info_ptr); - This->png_ptr = NULL; - IStream_Release(This->stream); - This->stream = NULL; - LeaveCriticalSection(&This->lock); - return E_FAIL; - } - ppng_set_error_fn(This->png_ptr, jmpbuf, user_error_fn, user_warning_fn); - - /* set up custom i/o handling */ - ppng_set_write_fn(This->png_ptr, This, user_write_data, user_flush); - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI PngEncoder_GetContainerFormat(IWICBitmapEncoder *iface, GUID *format) -{ - TRACE("(%p,%p)\n", iface, format); - - if (!format) - return E_INVALIDARG; - - memcpy(format, &GUID_ContainerFormatPng, sizeof(*format)); - return S_OK; -} - -static HRESULT WINAPI PngEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info) -{ - IWICComponentInfo *comp_info; - HRESULT hr; - - TRACE("%p,%p\n", iface, info); - - if (!info) return E_INVALIDARG; - - hr = CreateComponentInfo(&CLSID_WICPngEncoder, &comp_info); - if (hr == S_OK) - { - hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info); - IWICComponentInfo_Release(comp_info); - } - return hr; -} - -static HRESULT WINAPI PngEncoder_SetColorContexts(IWICBitmapEncoder *iface, - UINT cCount, IWICColorContext **ppIColorContext) -{ - FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); - return E_NOTIMPL; -} - -static HRESULT WINAPI PngEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *palette) -{ - PngEncoder *This = impl_from_IWICBitmapEncoder(iface); - HRESULT hr; - - TRACE("(%p,%p)\n", iface, palette); - - EnterCriticalSection(&This->lock); - - hr = This->stream ? WINCODEC_ERR_UNSUPPORTEDOPERATION : WINCODEC_ERR_NOTINITIALIZED; - - LeaveCriticalSection(&This->lock); - - return hr; -} - -static HRESULT WINAPI PngEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail) -{ - TRACE("(%p,%p)\n", iface, pIThumbnail); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI PngEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *pIPreview) -{ - TRACE("(%p,%p)\n", iface, pIPreview); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI PngEncoder_CreateNewFrame(IWICBitmapEncoder *iface, - IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions) -{ - PngEncoder *This = impl_from_IWICBitmapEncoder(iface); - HRESULT hr; - static const PROPBAG2 opts[2] = - { - { PROPBAG2_TYPE_DATA, VT_BOOL, 0, 0, (LPOLESTR)wszPngInterlaceOption }, - { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)wszPngFilterOption }, + L"Year", + L"Month", + L"Day", + L"Hour", + L"Minute", + L"Second", }; + LPWSTR id_values[6] = {0}; - TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions); - EnterCriticalSection(&This->lock); + hr = read_png_chunk(stream, type, &data, &data_size); + if (FAILED(hr)) return hr; - if (This->frame_count != 0) + if (data_size != 7) { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; - } - - if (!This->stream) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_NOTINITIALIZED; - } - - if (ppIEncoderOptions) - { - hr = CreatePropertyBag2(opts, ARRAY_SIZE(opts), ppIEncoderOptions); - if (FAILED(hr)) - { - LeaveCriticalSection(&This->lock); - return hr; - } - } - - This->frame_count = 1; - - LeaveCriticalSection(&This->lock); - - IWICBitmapEncoder_AddRef(iface); - *ppIFrameEncode = &This->IWICBitmapFrameEncode_iface; - - return S_OK; -} - -static HRESULT WINAPI PngEncoder_Commit(IWICBitmapEncoder *iface) -{ - PngEncoder *This = impl_from_IWICBitmapEncoder(iface); - TRACE("(%p)\n", iface); - - EnterCriticalSection(&This->lock); - - if (!This->frame_committed || This->committed) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->committed = TRUE; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI PngEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface, - IWICMetadataQueryWriter **ppIMetadataQueryWriter) -{ - FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryWriter); - return E_NOTIMPL; -} - -static const IWICBitmapEncoderVtbl PngEncoder_Vtbl = { - PngEncoder_QueryInterface, - PngEncoder_AddRef, - PngEncoder_Release, - PngEncoder_Initialize, - PngEncoder_GetContainerFormat, - PngEncoder_GetEncoderInfo, - PngEncoder_SetColorContexts, - PngEncoder_SetPalette, - PngEncoder_SetThumbnail, - PngEncoder_SetPreview, - PngEncoder_CreateNewFrame, - PngEncoder_Commit, - PngEncoder_GetMetadataQueryWriter -}; - -HRESULT PngEncoder_CreateInstance(REFIID iid, void** ppv) -{ - PngEncoder *This; - HRESULT ret; - - TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); - - *ppv = NULL; - - if (!load_libpng()) - { - ERR("Failed writing PNG because unable to find %s\n",SONAME_LIBPNG); + free(data); return E_FAIL; } - This = HeapAlloc(GetProcessHeap(), 0, sizeof(PngEncoder)); - if (!This) return E_OUTOFMEMORY; + result = calloc(6, sizeof(MetadataItem)); + for (i = 0; i < 6; i++) + { + SHStrDupW(names[i], &id_values[i]); + if (!id_values[i]) break; + } + if (!result || i < 6) + { + free(result); + for (i = 0; i < 6; i++) + CoTaskMemFree(id_values[i]); + free(data); + return E_OUTOFMEMORY; + } - This->IWICBitmapEncoder_iface.lpVtbl = &PngEncoder_Vtbl; - This->IWICBitmapFrameEncode_iface.lpVtbl = &PngEncoder_FrameVtbl; - This->ref = 1; - This->png_ptr = NULL; - This->info_ptr = NULL; - This->stream = NULL; - This->frame_count = 0; - This->frame_initialized = FALSE; - This->format = NULL; - This->info_written = FALSE; - This->width = 0; - This->height = 0; - This->xres = 0.0; - This->yres = 0.0; - This->lines_written = 0; - This->frame_committed = FALSE; - This->committed = FALSE; - This->data = NULL; - This->colors = 0; - InitializeCriticalSection(&This->lock); - This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PngEncoder.lock"); + for (i = 0; i < 6; i++) + { + PropVariantInit(&result[i].schema); + PropVariantInit(&result[i].id); + PropVariantInit(&result[i].value); - ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv); - IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface); + result[i].id.vt = VT_LPWSTR; + result[i].id.pwszVal = id_values[i]; + } - return ret; + result[0].value.vt = VT_UI2; + result[0].value.uiVal = read_ushort_be(data); + result[1].value.vt = VT_UI1; + result[1].value.bVal = data[2]; + result[2].value.vt = VT_UI1; + result[2].value.bVal = data[3]; + result[3].value.vt = VT_UI1; + result[3].value.bVal = data[4]; + result[4].value.vt = VT_UI1; + result[4].value.bVal = data[5]; + result[5].value.vt = VT_UI1; + result[5].value.bVal = data[6]; + + *items = result; + *item_count = 6; + + free(data); + + return S_OK; } -#else /* !HAVE_PNG_H */ +static const MetadataHandlerVtbl TimeReader_Vtbl = { + 0, + &CLSID_WICPngTimeMetadataReader, + LoadTimeMetadata +}; + +HRESULT PngTimeReader_CreateInstance(REFIID iid, void** ppv) +{ + return MetadataReader_Create(&TimeReader_Vtbl, iid, ppv); +} HRESULT PngDecoder_CreateInstance(REFIID iid, void** ppv) { - ERR("Trying to load PNG picture, but PNG support is not compiled in.\n"); - return E_FAIL; + HRESULT hr; + struct decoder *decoder; + struct decoder_info decoder_info; + + hr = png_decoder_create(&decoder_info, &decoder); + + if (SUCCEEDED(hr)) + hr = CommonDecoder_CreateInstance(decoder, &decoder_info, iid, ppv); + + return hr; } HRESULT PngEncoder_CreateInstance(REFIID iid, void** ppv) { - ERR("Trying to save PNG picture, but PNG support is not compiled in.\n"); - return E_FAIL; -} + HRESULT hr; + struct encoder *encoder; + struct encoder_info encoder_info; -#endif + hr = png_encoder_create(&encoder_info, &encoder); + + if (SUCCEEDED(hr)) + hr = CommonEncoder_CreateInstance(encoder, &encoder_info, iid, ppv); + + return hr; +} diff --git a/dll/win32/windowscodecs/precomp.h b/dll/win32/windowscodecs/precomp.h index 0d0ac5c7af7..39b7e622332 100644 --- a/dll/win32/windowscodecs/precomp.h +++ b/dll/win32/windowscodecs/precomp.h @@ -9,8 +9,6 @@ #define COM_NO_WINDOWS_H #define COBJMACROS -#define NONAMELESSUNION -#define NONAMELESSSTRUCT #include #include @@ -18,6 +16,7 @@ #include #include #include +#include #include "wincodecs_private.h" diff --git a/dll/win32/windowscodecs/propertybag.c b/dll/win32/windowscodecs/propertybag.c index e9d1af9670d..c91995b143e 100644 --- a/dll/win32/windowscodecs/propertybag.c +++ b/dll/win32/windowscodecs/propertybag.c @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -26,7 +24,6 @@ #include "windef.h" #include "winbase.h" #include "objbase.h" -#include "wine/unicode.h" #include "wincodecs_private.h" @@ -75,7 +72,7 @@ static ULONG WINAPI PropertyBag_AddRef(IPropertyBag2 *iface) PropertyBag *This = impl_from_IPropertyBag2(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -85,7 +82,7 @@ static ULONG WINAPI PropertyBag_Release(IPropertyBag2 *iface) PropertyBag *This = impl_from_IPropertyBag2(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { @@ -99,9 +96,9 @@ static ULONG WINAPI PropertyBag_Release(IPropertyBag2 *iface) } } - HeapFree(GetProcessHeap(), 0, This->properties); - HeapFree(GetProcessHeap(), 0, This->values); - HeapFree(GetProcessHeap(), 0, This); + free(This->properties); + free(This->values); + free(This); } return ref; @@ -117,7 +114,7 @@ static LONG find_item(PropertyBag *This, LPCOLESTR name) for (i=0; i < This->prop_count; i++) { - if (strcmpW(name, This->properties[i].pstrName) == 0) + if (wcscmp(name, This->properties[i].pstrName) == 0) return i; } @@ -131,7 +128,7 @@ static HRESULT WINAPI PropertyBag_Read(IPropertyBag2 *iface, ULONG cProperties, ULONG i; PropertyBag *This = impl_from_IPropertyBag2(iface); - TRACE("(%p,%u,%p,%p,%p,%p)\n", iface, cProperties, pPropBag, pErrLog, pvarValue, phrError); + TRACE("(%p,%lu,%p,%p,%p,%p)\n", iface, cProperties, pPropBag, pErrLog, pvarValue, phrError); for (i=0; i < cProperties; i++) { @@ -166,7 +163,7 @@ static HRESULT WINAPI PropertyBag_Write(IPropertyBag2 *iface, ULONG cProperties, ULONG i; PropertyBag *This = impl_from_IPropertyBag2(iface); - TRACE("(%p,%u,%p,%p)\n", iface, cProperties, pPropBag, pvarValue); + TRACE("(%p,%lu,%p,%p)\n", iface, cProperties, pPropBag, pvarValue); for (i=0; i < cProperties; i++) { @@ -220,11 +217,11 @@ static HRESULT copy_propbag2(PROPBAG2 *dest, const PROPBAG2 *src) dest->dwHint = src->dwHint; dest->dwType = src->dwType; dest->vt = src->vt; - dest->pstrName = CoTaskMemAlloc((strlenW(src->pstrName)+1) * sizeof(WCHAR)); + dest->pstrName = CoTaskMemAlloc((lstrlenW(src->pstrName)+1) * sizeof(WCHAR)); if(!dest->pstrName) return E_OUTOFMEMORY; - strcpyW(dest->pstrName, src->pstrName); + lstrcpyW(dest->pstrName, src->pstrName); return S_OK; } @@ -236,7 +233,7 @@ static HRESULT WINAPI PropertyBag_GetPropertyInfo(IPropertyBag2 *iface, ULONG iP ULONG i; PropertyBag *This = impl_from_IPropertyBag2(iface); - TRACE("(%p,%u,%u,%p,%p)\n", iface, iProperty, cProperties, pPropBag, pcProperties); + TRACE("(%p,%lu,%lu,%p,%p)\n", iface, iProperty, cProperties, pPropBag, pcProperties); if (iProperty >= This->prop_count && iProperty > 0) return WINCODEC_ERR_VALUEOUTOFRANGE; @@ -263,7 +260,7 @@ static HRESULT WINAPI PropertyBag_GetPropertyInfo(IPropertyBag2 *iface, ULONG iP static HRESULT WINAPI PropertyBag_LoadObject(IPropertyBag2 *iface, LPCOLESTR pstrName, DWORD dwHint, IUnknown *pUnkObject, IErrorLog *pErrLog) { - FIXME("(%p,%s,%u,%p,%p): stub\n", iface, debugstr_w(pstrName), dwHint, pUnkObject, pErrLog); + FIXME("(%p,%s,%lu,%p,%p): stub\n", iface, debugstr_w(pstrName), dwHint, pUnkObject, pErrLog); return E_NOTIMPL; } @@ -285,7 +282,7 @@ HRESULT CreatePropertyBag2(const PROPBAG2 *options, UINT count, HRESULT res = S_OK; PropertyBag *This; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(PropertyBag)); + This = malloc(sizeof(PropertyBag)); if (!This) return E_OUTOFMEMORY; This->IPropertyBag2_iface.lpVtbl = &PropertyBag_Vtbl; @@ -299,8 +296,8 @@ HRESULT CreatePropertyBag2(const PROPBAG2 *options, UINT count, } else { - This->properties = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PROPBAG2)*count); - This->values = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VARIANT)*count); + This->properties = calloc(count, sizeof(PROPBAG2)); + This->values = calloc(count, sizeof(VARIANT)); if (!This->properties || !This->values) res = E_OUTOFMEMORY; diff --git a/dll/win32/windowscodecs/proxy.c b/dll/win32/windowscodecs/proxy.c index 34b618e8d91..35d67db1e3e 100644 --- a/dll/win32/windowscodecs/proxy.c +++ b/dll/win32/windowscodecs/proxy.c @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS diff --git a/dll/win32/windowscodecs/regsvr.c b/dll/win32/windowscodecs/regsvr.c index 158329dd845..c74fcecb3a2 100644 --- a/dll/win32/windowscodecs/regsvr.c +++ b/dll/win32/windowscodecs/regsvr.c @@ -31,7 +31,6 @@ #include "ocidl.h" #include "wine/debug.h" -#include "wine/unicode.h" #include "wincodecs_private.h" @@ -148,37 +147,36 @@ static HRESULT unregister_pixelformats(struct regsvr_pixelformat const *list); /*********************************************************************** * static string constants */ -static const WCHAR clsid_keyname[] = { - 'C', 'L', 'S', 'I', 'D', 0 }; +static const WCHAR clsid_keyname[] = L"CLSID"; static const char author_valuename[] = "Author"; static const char friendlyname_valuename[] = "FriendlyName"; -static const WCHAR vendor_valuename[] = {'V','e','n','d','o','r',0}; -static const WCHAR containerformat_valuename[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0}; +static const WCHAR vendor_valuename[] = L"Vendor"; +static const WCHAR containerformat_valuename[] = L"ContainerFormat"; static const char version_valuename[] = "Version"; static const char mimetypes_valuename[] = "MimeTypes"; static const char extensions_valuename[] = "FileExtensions"; -static const WCHAR formats_keyname[] = {'F','o','r','m','a','t','s',0}; -static const WCHAR patterns_keyname[] = {'P','a','t','t','e','r','n','s',0}; -static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0}; -static const WCHAR clsid_valuename[] = {'C','L','S','I','D',0}; +static const WCHAR formats_keyname[] = L"Formats"; +static const WCHAR patterns_keyname[] = L"Patterns"; +static const WCHAR instance_keyname[] = L"Instance"; +static const WCHAR clsid_valuename[] = L"CLSID"; static const char length_valuename[] = "Length"; static const char position_valuename[] = "Position"; static const char pattern_valuename[] = "Pattern"; static const char mask_valuename[] = "Mask"; static const char endofstream_valuename[] = "EndOfStream"; -static const WCHAR pixelformats_keyname[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0}; -static const WCHAR metadataformat_valuename[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0}; +static const WCHAR pixelformats_keyname[] = L"PixelFormats"; +static const WCHAR metadataformat_valuename[] = L"MetadataFormat"; static const char specversion_valuename[] = "SpecVersion"; static const char requiresfullstream_valuename[] = "RequiresFullStream"; static const char supportspadding_valuename[] = "SupportsPadding"; static const char requiresfixedsize_valuename[] = "FixedSize"; -static const WCHAR containers_keyname[] = {'C','o','n','t','a','i','n','e','r','s',0}; +static const WCHAR containers_keyname[] = L"Containers"; static const char dataoffset_valuename[] = "DataOffset"; static const char bitsperpixel_valuename[] = "BitLength"; static const char channelcount_valuename[] = "ChannelCount"; static const char numericrepresentation_valuename[] = "NumericRepresentation"; static const char supportstransparency_valuename[] = "SupportsTransparency"; -static const WCHAR channelmasks_keyname[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0}; +static const WCHAR channelmasks_keyname[] = L"ChannelMasks"; /*********************************************************************** * register_decoders @@ -306,8 +304,7 @@ static HRESULT register_decoders(struct regsvr_decoder const *list) for (i=0; list->patterns[i].length; i++) { HKEY pattern_key; - static const WCHAR int_format[] = {'%','i',0}; - snprintfW(buf, 39, int_format, i); + swprintf(buf, 39, L"%i", i); res = RegCreateKeyExW(patterns_key, buf, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &pattern_key, NULL); if (res != ERROR_SUCCESS) break; @@ -852,8 +849,7 @@ static HRESULT register_metadatareaders(struct regsvr_metadatareader const *list for (i=0; container->patterns[i].length; i++) { HKEY pattern_key; - static const WCHAR int_format[] = {'%','i',0}; - snprintfW(buf, 39, int_format, i); + swprintf(buf, 39, L"%i", i); res = RegCreateKeyExW(format_key, buf, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &pattern_key, NULL); if (res != ERROR_SUCCESS) break; @@ -1032,7 +1028,6 @@ static HRESULT register_pixelformats(struct regsvr_pixelformat const *list) if (res != ERROR_SUCCESS) goto error_close_clsid_key; if (list->channelmasks) { - static const WCHAR valuename_format[] = {'%','d',0}; HKEY masks_key; UINT i, mask_size; WCHAR mask_valuename[11]; @@ -1044,7 +1039,7 @@ static HRESULT register_pixelformats(struct regsvr_pixelformat const *list) if (res != ERROR_SUCCESS) goto error_close_clsid_key; for (i=0; i < list->channelcount; i++) { - sprintfW(mask_valuename, valuename_format, i); + swprintf(mask_valuename, ARRAY_SIZE(mask_valuename), L"%d", i); res = RegSetValueExW(masks_key, mask_valuename, 0, REG_BINARY, list->channelmasks[i], mask_size); if (res != ERROR_SUCCESS) break; @@ -1140,6 +1135,18 @@ static struct decoder_pattern const bmp_patterns[] = { {0} }; +static const BYTE dds_magic[] = "DDS "; + +static GUID const * const dds_formats[] = { + &GUID_WICPixelFormat32bppBGRA, + NULL +}; + +static struct decoder_pattern const dds_patterns[] = { + {4,0,dds_magic,mask_all,0}, + {0} +}; + static const BYTE gif87a_magic[6] = "GIF87a"; static const BYTE gif89a_magic[6] = "GIF89a"; @@ -1180,6 +1187,48 @@ static struct decoder_pattern const jpeg_patterns[] = { {0} }; +static const BYTE wmp_magic_v0[] = {0x49, 0x49, 0xbc, 0x00}; +static const BYTE wmp_magic_v1[] = {0x49, 0x49, 0xbc, 0x01}; + +static GUID const * const wmp_formats[] = { + &GUID_WICPixelFormat128bppRGBAFixedPoint, + &GUID_WICPixelFormat128bppRGBAFloat, + &GUID_WICPixelFormat128bppRGBFloat, + &GUID_WICPixelFormat16bppBGR555, + &GUID_WICPixelFormat16bppBGR565, + &GUID_WICPixelFormat16bppGray, + &GUID_WICPixelFormat16bppGrayFixedPoint, + &GUID_WICPixelFormat16bppGrayHalf, + &GUID_WICPixelFormat24bppBGR, + &GUID_WICPixelFormat24bppRGB, + &GUID_WICPixelFormat32bppBGR, + &GUID_WICPixelFormat32bppBGR101010, + &GUID_WICPixelFormat32bppBGRA, + &GUID_WICPixelFormat32bppCMYK, + &GUID_WICPixelFormat32bppGrayFixedPoint, + &GUID_WICPixelFormat32bppGrayFloat, + &GUID_WICPixelFormat32bppRGBE, + &GUID_WICPixelFormat40bppCMYKAlpha, + &GUID_WICPixelFormat48bppRGB, + &GUID_WICPixelFormat48bppRGBFixedPoint, + &GUID_WICPixelFormat48bppRGBHalf, + &GUID_WICPixelFormat64bppCMYK, + &GUID_WICPixelFormat64bppRGBA, + &GUID_WICPixelFormat64bppRGBAFixedPoint, + &GUID_WICPixelFormat64bppRGBAHalf, + &GUID_WICPixelFormat80bppCMYKAlpha, + &GUID_WICPixelFormat8bppGray, + &GUID_WICPixelFormat96bppRGBFixedPoint, + &GUID_WICPixelFormatBlackWhite, + NULL +}; + +static struct decoder_pattern const wmp_patterns[] = { + {4,0,wmp_magic_v0,mask_all,0}, + {4,0,wmp_magic_v1,mask_all,0}, + {0} +}; + static const BYTE png_magic[] = {137,80,78,71,13,10,26,10}; static GUID const * const png_formats[] = { @@ -1226,7 +1275,9 @@ static GUID const * const tiff_decode_formats[] = { &GUID_WICPixelFormat64bppPRGBA, &GUID_WICPixelFormat32bppCMYK, &GUID_WICPixelFormat64bppCMYK, + &GUID_WICPixelFormat96bppRGBFloat, &GUID_WICPixelFormat128bppRGBAFloat, + &GUID_WICPixelFormat128bppPRGBAFloat, NULL }; @@ -1278,6 +1329,17 @@ static struct regsvr_decoder const decoder_list[] = { bmp_formats, bmp_patterns }, + { &CLSID_WICDdsDecoder, + "The Wine Project", + "DDS Decoder", + "1.0.0.0", + &GUID_VendorMicrosoft, + &GUID_ContainerFormatDds, + "image/vnd.ms-dds", + ".dds", + dds_formats, + dds_patterns + }, { &CLSID_WICGifDecoder, "The Wine Project", "GIF Decoder", @@ -1311,6 +1373,17 @@ static struct regsvr_decoder const decoder_list[] = { jpeg_formats, jpeg_patterns }, + { &CLSID_WICWmpDecoder, + "The Wine Project", + "JPEG-XR Decoder", + "1.0.0.0", + &GUID_VendorMicrosoft, + &GUID_ContainerFormatWmp, + "image/jxr", + ".jxr;.hdp;.wdp", + wmp_formats, + wmp_patterns + }, { &CLSID_WICPngDecoder, "The Wine Project", "PNG Decoder", @@ -1393,11 +1466,6 @@ static GUID const * const tiff_encode_formats[] = { NULL }; -static GUID const * const icns_encode_formats[] = { - &GUID_WICPixelFormat32bppBGRA, - NULL -}; - static struct regsvr_encoder const encoder_list[] = { { &CLSID_WICBmpEncoder, "The Wine Project", @@ -1449,16 +1517,6 @@ static struct regsvr_encoder const encoder_list[] = { ".tif;.tiff", tiff_encode_formats }, - { &CLSID_WICIcnsEncoder, - "The Wine Project", - "ICNS Encoder", - "1.0.0.0", - &GUID_VendorWine, - NULL, /* no container format guid */ - "image/icns", - ".icns", - icns_encode_formats - }, { NULL } /* list terminator */ }; @@ -1562,6 +1620,36 @@ static const struct reader_containers pngchrm_containers[] = { { NULL } /* list terminator */ }; +static const BYTE hIST[] = "hIST"; + +static const struct metadata_pattern pnghist_metadata_pattern[] = { + { 4, 4, hIST, mask_all, 4 }, + { 0 } +}; + +static const struct reader_containers pnghist_containers[] = { + { + &GUID_ContainerFormatPng, + pnghist_metadata_pattern + }, + { NULL } /* list terminator */ +}; + +static const BYTE tIME[] = "tIME"; + +static const struct metadata_pattern pngtime_metadata_pattern[] = { + { 4, 4, tIME, mask_all, 4 }, + { 0 } +}; + +static const struct reader_containers pngtime_containers[] = { + { + &GUID_ContainerFormatPng, + pngtime_metadata_pattern + }, + { NULL } /* list terminator */ +}; + static const struct metadata_pattern lsd_metadata_patterns[] = { { 0, 6, gif87a_magic, mask_all, 0 }, { 0, 6, gif89a_magic, mask_all, 0 }, @@ -1677,6 +1765,16 @@ static struct regsvr_metadatareader const metadatareader_list[] = { 0, 0, 0, pnggama_containers }, + { &CLSID_WICPngHistMetadataReader, + "The Wine Project", + "Chunk hIST Reader", + "1.0.0.0", + "1.0.0.0", + &GUID_VendorMicrosoft, + &GUID_MetadataFormatChunkhIST, + 0, 0, 0, + pnghist_containers + }, { &CLSID_WICPngTextMetadataReader, "The Wine Project", "Chunk tEXt Reader", @@ -1687,6 +1785,16 @@ static struct regsvr_metadatareader const metadatareader_list[] = { 0, 0, 0, pngtext_containers }, + { &CLSID_WICPngTimeMetadataReader, + "The Wine Project", + "Chunk tIME Reader", + "1.0.0.0", + "1.0.0.0", + &GUID_VendorMicrosoft, + &GUID_MetadataFormatChunktIME, + 0, 0, 0, + pngtime_containers + }, { &CLSID_WICLSDMetadataReader, "The Wine Project", "Logical Screen Descriptor Reader", @@ -1756,6 +1864,10 @@ static BYTE const channel_mask_16bit4[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, static BYTE const channel_mask_32bit[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }; +static BYTE const channel_mask_96bit1[] = { 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; +static BYTE const channel_mask_96bit2[] = { 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 }; +static BYTE const channel_mask_96bit3[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff }; + static BYTE const channel_mask_128bit1[] = { 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; static BYTE const channel_mask_128bit2[] = { 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; static BYTE const channel_mask_128bit3[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 }; @@ -1778,6 +1890,7 @@ static BYTE const * const channel_masks_16bit[] = { channel_mask_16bit, channel_mask_16bit2, channel_mask_16bit3, channel_mask_16bit4}; static BYTE const * const channel_masks_32bit[] = { channel_mask_32bit }; +static BYTE const * const channel_masks_96bit[] = { channel_mask_96bit1, channel_mask_96bit2, channel_mask_96bit3 }; static BYTE const * const channel_masks_128bit[] = { channel_mask_128bit1, channel_mask_128bit2, channel_mask_128bit3, channel_mask_128bit4 }; static BYTE const * const channel_masks_BGRA5551[] = { channel_mask_5bit, @@ -2073,6 +2186,17 @@ static struct regsvr_pixelformat const pixelformat_list[] = { WICPixelFormatNumericRepresentationUnsignedInteger, 0 }, + { &GUID_WICPixelFormat96bppRGBFloat, + "The Wine Project", + "96bpp RGBFloat", + NULL, /* no version */ + &GUID_VendorMicrosoft, + 96, /* bitsperpixel */ + 3, /* channel count */ + channel_masks_96bit, + WICPixelFormatNumericRepresentationFloat, + 0 + }, { &GUID_WICPixelFormat128bppRGBAFloat, "The Wine Project", "128bpp RGBAFloat", @@ -2084,6 +2208,17 @@ static struct regsvr_pixelformat const pixelformat_list[] = { WICPixelFormatNumericRepresentationFloat, 1 }, + { &GUID_WICPixelFormat128bppPRGBAFloat, + "The Wine Project", + "128bpp PRGBAFloat", + NULL, /* no version */ + &GUID_VendorMicrosoft, + 128, /* bitsperpixel */ + 4, /* channel count */ + channel_masks_128bit, + WICPixelFormatNumericRepresentationFloat, + 1 + }, { NULL } /* list terminator */ }; @@ -2185,8 +2320,8 @@ static HRESULT unregister_categories(const struct regsvr_category *list) return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; } -extern HRESULT WINAPI WIC_DllRegisterServer(void) DECLSPEC_HIDDEN; -extern HRESULT WINAPI WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN; +extern HRESULT WINAPI WIC_DllRegisterServer(void); +extern HRESULT WINAPI WIC_DllUnregisterServer(void); HRESULT WINAPI DllRegisterServer(void) { diff --git a/dll/win32/windowscodecs/scaler.c b/dll/win32/windowscodecs/scaler.c index d6e56d096ea..ab68debffa0 100644 --- a/dll/win32/windowscodecs/scaler.c +++ b/dll/win32/windowscodecs/scaler.c @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -91,7 +89,7 @@ static ULONG WINAPI BitmapScaler_AddRef(IWICBitmapScaler *iface) BitmapScaler *This = impl_from_IWICBitmapScaler(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -101,14 +99,14 @@ static ULONG WINAPI BitmapScaler_Release(IWICBitmapScaler *iface) BitmapScaler *This = impl_from_IWICBitmapScaler(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); if (This->source) IWICBitmapSource_Release(This->source); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; @@ -253,7 +251,7 @@ static HRESULT WINAPI BitmapScaler_CopyPixels(IWICBitmapScaler *iface, goto end; } - if ((cbStride * dest_rect.Height) > cbBufferSize) + if (cbStride * (dest_rect.Height - 1) + bytesperrow > cbBufferSize) { hr = E_INVALIDARG; goto end; @@ -279,13 +277,13 @@ static HRESULT WINAPI BitmapScaler_CopyPixels(IWICBitmapScaler *iface, src_bytesperrow = (src_rect.Width * This->bpp + 7)/8; buffer_size = src_bytesperrow * src_rect.Height; - src_rows = HeapAlloc(GetProcessHeap(), 0, sizeof(BYTE*) * src_rect.Height); - src_bits = HeapAlloc(GetProcessHeap(), 0, buffer_size); + src_rows = malloc(sizeof(BYTE*) * src_rect.Height); + src_bits = malloc(buffer_size); if (!src_rows || !src_bits) { - HeapFree(GetProcessHeap(), 0, src_rows); - HeapFree(GetProcessHeap(), 0, src_bits); + free(src_rows); + free(src_bits); hr = E_OUTOFMEMORY; goto end; } @@ -305,8 +303,8 @@ static HRESULT WINAPI BitmapScaler_CopyPixels(IWICBitmapScaler *iface, } } - HeapFree(GetProcessHeap(), 0, src_rows); - HeapFree(GetProcessHeap(), 0, src_bits); + free(src_rows); + free(src_bits); end: LeaveCriticalSection(&This->lock); @@ -516,7 +514,7 @@ HRESULT BitmapScaler_Create(IWICBitmapScaler **scaler) { BitmapScaler *This; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapScaler)); + This = malloc(sizeof(BitmapScaler)); if (!This) return E_OUTOFMEMORY; This->IWICBitmapScaler_iface.lpVtbl = &BitmapScaler_Vtbl; @@ -529,7 +527,11 @@ HRESULT BitmapScaler_Create(IWICBitmapScaler **scaler) This->src_height = 0; This->mode = 0; This->bpp = 0; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BitmapScaler.lock"); *scaler = &This->IWICBitmapScaler_iface; diff --git a/dll/win32/windowscodecs/stream.c b/dll/win32/windowscodecs/stream.c index 366d11b1116..03b124c08c9 100644 --- a/dll/win32/windowscodecs/stream.c +++ b/dll/win32/windowscodecs/stream.c @@ -76,7 +76,7 @@ static ULONG WINAPI StreamOnMemory_AddRef(IStream *iface) StreamOnMemory *This = StreamOnMemory_from_IStream(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -86,12 +86,12 @@ static ULONG WINAPI StreamOnMemory_Release(IStream *iface) StreamOnMemory *This = StreamOnMemory_from_IStream(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; } @@ -102,7 +102,7 @@ static HRESULT WINAPI StreamOnMemory_Read(IStream *iface, StreamOnMemory *This = StreamOnMemory_from_IStream(iface); ULONG uBytesRead; - TRACE("(%p, %p, %u, %p)\n", This, pv, cb, pcbRead); + TRACE("(%p, %p, %lu, %p)\n", This, pv, cb, pcbRead); if (!pv) return E_INVALIDARG; @@ -123,7 +123,7 @@ static HRESULT WINAPI StreamOnMemory_Write(IStream *iface, StreamOnMemory *This = StreamOnMemory_from_IStream(iface); HRESULT hr; - TRACE("(%p, %p, %u, %p)\n", This, pv, cb, pcbWritten); + TRACE("(%p, %p, %lu, %p)\n", This, pv, cb, pcbWritten); if (!pv) return E_INVALIDARG; @@ -149,7 +149,7 @@ static HRESULT WINAPI StreamOnMemory_Seek(IStream *iface, LARGE_INTEGER NewPosition; HRESULT hr=S_OK; - TRACE("(%p, %s, %d, %p)\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), dwOrigin, plibNewPosition); + TRACE("(%p, %s, %ld, %p)\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), dwOrigin, plibNewPosition); EnterCriticalSection(&This->lock); if (dwOrigin == STREAM_SEEK_SET) NewPosition.QuadPart = dlibMove.QuadPart; @@ -189,12 +189,11 @@ static HRESULT WINAPI StreamOnMemory_CopyTo(IStream *iface, return E_NOTIMPL; } -/* Commit isn't implemented in the native windowscodecs DLL either */ static HRESULT WINAPI StreamOnMemory_Commit(IStream *iface, DWORD grfCommitFlags) { - TRACE("(%p, %#x)\n", iface, grfCommitFlags); - return E_NOTIMPL; + TRACE("(%p, %#lx)\n", iface, grfCommitFlags); + return S_OK; } /* Revert isn't implemented in the native windowscodecs DLL either */ @@ -208,7 +207,7 @@ static HRESULT WINAPI StreamOnMemory_Revert(IStream *iface) static HRESULT WINAPI StreamOnMemory_LockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { - TRACE("(%p, %s, %s, %d)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), + TRACE("(%p, %s, %s, %ld)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), wine_dbgstr_longlong(cb.QuadPart), dwLockType); return E_NOTIMPL; } @@ -217,7 +216,7 @@ static HRESULT WINAPI StreamOnMemory_LockRegion(IStream *iface, static HRESULT WINAPI StreamOnMemory_UnlockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { - TRACE("(%p, %s, %s, %d)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), + TRACE("(%p, %s, %s, %ld)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), wine_dbgstr_longlong(cb.QuadPart), dwLockType); return E_NOTIMPL; } @@ -226,7 +225,7 @@ static HRESULT WINAPI StreamOnMemory_Stat(IStream *iface, STATSTG *pstatstg, DWORD grfStatFlag) { StreamOnMemory *This = StreamOnMemory_from_IStream(iface); - TRACE("(%p, %p, %#x)\n", This, pstatstg, grfStatFlag); + TRACE("(%p, %p, %#lx)\n", This, pstatstg, grfStatFlag); if (!pstatstg) return E_INVALIDARG; @@ -311,7 +310,7 @@ static ULONG WINAPI StreamOnFileHandle_AddRef(IStream *iface) StreamOnFileHandle *This = StreamOnFileHandle_from_IStream(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -321,13 +320,13 @@ static ULONG WINAPI StreamOnFileHandle_Release(IStream *iface) StreamOnFileHandle *This = StreamOnFileHandle_from_IStream(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { IWICStream_Release(This->stream); UnmapViewOfFile(This->mem); CloseHandle(This->map); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; } @@ -336,7 +335,7 @@ static HRESULT WINAPI StreamOnFileHandle_Read(IStream *iface, void *pv, ULONG cb, ULONG *pcbRead) { StreamOnFileHandle *This = StreamOnFileHandle_from_IStream(iface); - TRACE("(%p, %p, %u, %p)\n", This, pv, cb, pcbRead); + TRACE("(%p, %p, %lu, %p)\n", This, pv, cb, pcbRead); return IWICStream_Read(This->stream, pv, cb, pcbRead); } @@ -344,7 +343,7 @@ static HRESULT WINAPI StreamOnFileHandle_Read(IStream *iface, static HRESULT WINAPI StreamOnFileHandle_Write(IStream *iface, void const *pv, ULONG cb, ULONG *pcbWritten) { - ERR("(%p, %p, %u, %p)\n", iface, pv, cb, pcbWritten); + ERR("(%p, %p, %lu, %p)\n", iface, pv, cb, pcbWritten); return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED); } @@ -352,7 +351,7 @@ static HRESULT WINAPI StreamOnFileHandle_Seek(IStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) { StreamOnFileHandle *This = StreamOnFileHandle_from_IStream(iface); - TRACE("(%p, %s, %d, %p)\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), dwOrigin, plibNewPosition); + TRACE("(%p, %s, %ld, %p)\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), dwOrigin, plibNewPosition); return IWICStream_Seek(This->stream, dlibMove, dwOrigin, plibNewPosition); } @@ -374,8 +373,8 @@ static HRESULT WINAPI StreamOnFileHandle_CopyTo(IStream *iface, static HRESULT WINAPI StreamOnFileHandle_Commit(IStream *iface, DWORD grfCommitFlags) { - TRACE("(%p, %#x)\n", iface, grfCommitFlags); - return E_NOTIMPL; + TRACE("(%p, %#lx)\n", iface, grfCommitFlags); + return S_OK; } static HRESULT WINAPI StreamOnFileHandle_Revert(IStream *iface) @@ -387,7 +386,7 @@ static HRESULT WINAPI StreamOnFileHandle_Revert(IStream *iface) static HRESULT WINAPI StreamOnFileHandle_LockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { - TRACE("(%p, %s, %s, %d)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), + TRACE("(%p, %s, %s, %ld)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), wine_dbgstr_longlong(cb.QuadPart), dwLockType); return E_NOTIMPL; } @@ -395,7 +394,7 @@ static HRESULT WINAPI StreamOnFileHandle_LockRegion(IStream *iface, static HRESULT WINAPI StreamOnFileHandle_UnlockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { - TRACE("(%p, %s, %s, %d)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), + TRACE("(%p, %s, %s, %ld)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), wine_dbgstr_longlong(cb.QuadPart), dwLockType); return E_NOTIMPL; } @@ -404,7 +403,7 @@ static HRESULT WINAPI StreamOnFileHandle_Stat(IStream *iface, STATSTG *pstatstg, DWORD grfStatFlag) { StreamOnFileHandle *This = StreamOnFileHandle_from_IStream(iface); - TRACE("(%p, %p, %#x)\n", This, pstatstg, grfStatFlag); + TRACE("(%p, %p, %#lx)\n", This, pstatstg, grfStatFlag); return IWICStream_Stat(This->stream, pstatstg, grfStatFlag); } @@ -486,7 +485,7 @@ static ULONG WINAPI StreamOnStreamRange_AddRef(IStream *iface) StreamOnStreamRange *This = StreamOnStreamRange_from_IStream(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -496,13 +495,13 @@ static ULONG WINAPI StreamOnStreamRange_Release(IStream *iface) StreamOnStreamRange *This = StreamOnStreamRange_from_IStream(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { This->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->lock); IStream_Release(This->stream); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; } @@ -516,7 +515,7 @@ static HRESULT WINAPI StreamOnStreamRange_Read(IStream *iface, ULARGE_INTEGER OldPosition; LARGE_INTEGER SetPosition; - TRACE("(%p, %p, %u, %p)\n", This, pv, cb, pcbRead); + TRACE("(%p, %p, %lu, %p)\n", This, pv, cb, pcbRead); if (!pv) return E_INVALIDARG; @@ -559,7 +558,7 @@ static HRESULT WINAPI StreamOnStreamRange_Write(IStream *iface, ULARGE_INTEGER OldPosition; LARGE_INTEGER SetPosition; ULONG uBytesWritten=0; - TRACE("(%p, %p, %u, %p)\n", This, pv, cb, pcbWritten); + TRACE("(%p, %p, %lu, %p)\n", This, pv, cb, pcbWritten); if (!pv) return E_INVALIDARG; @@ -601,7 +600,7 @@ static HRESULT WINAPI StreamOnStreamRange_Seek(IStream *iface, ULARGE_INTEGER NewPosition, actual_size; HRESULT hr=S_OK; STATSTG statstg; - TRACE("(%p, %s, %d, %p)\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), dwOrigin, plibNewPosition); + TRACE("(%p, %s, %ld, %p)\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), dwOrigin, plibNewPosition); EnterCriticalSection(&This->lock); actual_size = This->max_size; @@ -655,8 +654,9 @@ static HRESULT WINAPI StreamOnStreamRange_CopyTo(IStream *iface, static HRESULT WINAPI StreamOnStreamRange_Commit(IStream *iface, DWORD grfCommitFlags) { - TRACE("(%p, %#x)\n", iface, grfCommitFlags); - return E_NOTIMPL; + StreamOnStreamRange *This = StreamOnStreamRange_from_IStream(iface); + TRACE("(%p, %#lx)\n", This, grfCommitFlags); + return IStream_Commit(This->stream, grfCommitFlags); } /* Revert isn't implemented in the native windowscodecs DLL either */ @@ -670,7 +670,7 @@ static HRESULT WINAPI StreamOnStreamRange_Revert(IStream *iface) static HRESULT WINAPI StreamOnStreamRange_LockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { - TRACE("(%p, %s, %s, %d)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), + TRACE("(%p, %s, %s, %ld)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), wine_dbgstr_longlong(cb.QuadPart), dwLockType); return E_NOTIMPL; } @@ -679,7 +679,7 @@ static HRESULT WINAPI StreamOnStreamRange_LockRegion(IStream *iface, static HRESULT WINAPI StreamOnStreamRange_UnlockRegion(IStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { - TRACE("(%p, %s, %s, %d)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), + TRACE("(%p, %s, %s, %ld)\n", iface, wine_dbgstr_longlong(libOffset.QuadPart), wine_dbgstr_longlong(cb.QuadPart), dwLockType); return E_NOTIMPL; } @@ -689,7 +689,7 @@ static HRESULT WINAPI StreamOnStreamRange_Stat(IStream *iface, { StreamOnStreamRange *This = StreamOnStreamRange_from_IStream(iface); HRESULT hr; - TRACE("(%p, %p, %#x)\n", This, pstatstg, grfStatFlag); + TRACE("(%p, %p, %#lx)\n", This, pstatstg, grfStatFlag); if (!pstatstg) return E_INVALIDARG; @@ -781,7 +781,7 @@ static ULONG WINAPI IWICStreamImpl_AddRef(IWICStream *iface) IWICStreamImpl *This = impl_from_IWICStream(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -791,11 +791,11 @@ static ULONG WINAPI IWICStreamImpl_Release(IWICStream *iface) IWICStreamImpl *This = impl_from_IWICStream(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { if (This->pStream) IStream_Release(This->pStream); - HeapFree(GetProcessHeap(), 0, This); + free(This); } return ref; } @@ -804,7 +804,7 @@ static HRESULT WINAPI IWICStreamImpl_Read(IWICStream *iface, void *pv, ULONG cb, ULONG *pcbRead) { IWICStreamImpl *This = impl_from_IWICStream(iface); - TRACE("(%p, %p, %u, %p)\n", This, pv, cb, pcbRead); + TRACE("(%p, %p, %lu, %p)\n", This, pv, cb, pcbRead); if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED; return IStream_Read(This->pStream, pv, cb, pcbRead); @@ -814,7 +814,7 @@ static HRESULT WINAPI IWICStreamImpl_Write(IWICStream *iface, void const *pv, ULONG cb, ULONG *pcbWritten) { IWICStreamImpl *This = impl_from_IWICStream(iface); - TRACE("(%p, %p, %u, %p)\n", This, pv, cb, pcbWritten); + TRACE("(%p, %p, %lu, %p)\n", This, pv, cb, pcbWritten); if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED; return IStream_Write(This->pStream, pv, cb, pcbWritten); @@ -824,7 +824,7 @@ static HRESULT WINAPI IWICStreamImpl_Seek(IWICStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) { IWICStreamImpl *This = impl_from_IWICStream(iface); - TRACE("(%p, %s, %d, %p)\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), + TRACE("(%p, %s, %ld, %p)\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), dwOrigin, plibNewPosition); if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED; @@ -855,7 +855,7 @@ static HRESULT WINAPI IWICStreamImpl_Commit(IWICStream *iface, DWORD grfCommitFlags) { IWICStreamImpl *This = impl_from_IWICStream(iface); - TRACE("(%p, %#x)\n", This, grfCommitFlags); + TRACE("(%p, %#lx)\n", This, grfCommitFlags); if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED; return IStream_Commit(This->pStream, grfCommitFlags); @@ -874,7 +874,7 @@ static HRESULT WINAPI IWICStreamImpl_LockRegion(IWICStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { IWICStreamImpl *This = impl_from_IWICStream(iface); - TRACE("(%p, %s, %s, %d)\n", This, wine_dbgstr_longlong(libOffset.QuadPart), + TRACE("(%p, %s, %s, %ld)\n", This, wine_dbgstr_longlong(libOffset.QuadPart), wine_dbgstr_longlong(cb.QuadPart), dwLockType); if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED; @@ -885,7 +885,7 @@ static HRESULT WINAPI IWICStreamImpl_UnlockRegion(IWICStream *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { IWICStreamImpl *This = impl_from_IWICStream(iface); - TRACE("(%p, %s, %s, %d)\n", This, wine_dbgstr_longlong(libOffset.QuadPart), + TRACE("(%p, %s, %s, %ld)\n", This, wine_dbgstr_longlong(libOffset.QuadPart), wine_dbgstr_longlong(cb.QuadPart), dwLockType); if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED; @@ -896,7 +896,7 @@ static HRESULT WINAPI IWICStreamImpl_Stat(IWICStream *iface, STATSTG *pstatstg, DWORD grfStatFlag) { IWICStreamImpl *This = impl_from_IWICStream(iface); - TRACE("(%p, %p, %#x)\n", This, pstatstg, grfStatFlag); + TRACE("(%p, %p, %#lx)\n", This, pstatstg, grfStatFlag); if (!This->pStream) return WINCODEC_ERR_NOTINITIALIZED; return IStream_Stat(This->pStream, pstatstg, grfStatFlag); @@ -942,7 +942,7 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromFilename(IWICStream *iface, DWORD dwMode; IStream *stream; - TRACE("(%p, %s, %u)\n", iface, debugstr_w(wzFileName), dwDesiredAccess); + TRACE("(%p, %s, %lu)\n", iface, debugstr_w(wzFileName), dwDesiredAccess); if (This->pStream) return WINCODEC_ERR_WRONGSTATE; @@ -989,12 +989,12 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromMemory(IWICStream *iface, { IWICStreamImpl *This = impl_from_IWICStream(iface); StreamOnMemory *pObject; - TRACE("(%p, %p, %u)\n", iface, pbBuffer, cbBufferSize); + TRACE("(%p, %p, %lu)\n", iface, pbBuffer, cbBufferSize); if (!pbBuffer) return E_INVALIDARG; if (This->pStream) return WINCODEC_ERR_WRONGSTATE; - pObject = HeapAlloc(GetProcessHeap(), 0, sizeof(StreamOnMemory)); + pObject = malloc(sizeof(StreamOnMemory)); if (!pObject) return E_OUTOFMEMORY; pObject->IStream_iface.lpVtbl = &StreamOnMemory_Vtbl; @@ -1002,7 +1002,11 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromMemory(IWICStream *iface, pObject->pbMemory = pbBuffer; pObject->dwMemsize = cbBufferSize; pObject->dwCurPos = 0; +#ifdef __REACTOS__ InitializeCriticalSection(&pObject->lock); +#else + InitializeCriticalSectionEx(&pObject->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif pObject->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": StreamOnMemory.lock"); if (InterlockedCompareExchangePointer((void**)&This->pStream, pObject, NULL)) @@ -1058,7 +1062,7 @@ HRESULT stream_initialize_from_filehandle(IWICStream *iface, HANDLE file) hr = IWICStreamImpl_InitializeFromMemory(stream, mem, size.u.LowPart); if (FAILED(hr)) goto error; - pObject = HeapAlloc(GetProcessHeap(), 0, sizeof(StreamOnFileHandle)); + pObject = malloc(sizeof(StreamOnFileHandle)); if (!pObject) { hr = E_OUTOFMEMORY; @@ -1097,7 +1101,7 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromIStreamRegion(IWICStream *ifa if (!pIStream) return E_INVALIDARG; if (This->pStream) return WINCODEC_ERR_WRONGSTATE; - pObject = HeapAlloc(GetProcessHeap(), 0, sizeof(StreamOnStreamRange)); + pObject = malloc(sizeof(StreamOnStreamRange)); if (!pObject) return E_OUTOFMEMORY; pObject->IStream_iface.lpVtbl = &StreamOnStreamRange_Vtbl; @@ -1107,7 +1111,11 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromIStreamRegion(IWICStream *ifa pObject->pos.QuadPart = 0; pObject->offset = ulOffset; pObject->max_size = ulMaxSize; +#ifdef __REACTOS__ InitializeCriticalSection(&pObject->lock); +#else + InitializeCriticalSectionEx(&pObject->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif pObject->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": StreamOnStreamRange.lock"); if (InterlockedCompareExchangePointer((void**)&This->pStream, pObject, NULL)) @@ -1153,7 +1161,7 @@ HRESULT StreamImpl_Create(IWICStream **stream) if( !stream ) return E_INVALIDARG; - pObject = HeapAlloc(GetProcessHeap(), 0, sizeof(IWICStreamImpl)); + pObject = malloc(sizeof(IWICStreamImpl)); if( !pObject ) { *stream = NULL; return E_OUTOFMEMORY; diff --git a/dll/win32/windowscodecs/tgaformat.c b/dll/win32/windowscodecs/tgaformat.c index 72c9baa0168..1d2731bb3f5 100644 --- a/dll/win32/windowscodecs/tgaformat.c +++ b/dll/win32/windowscodecs/tgaformat.c @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include #define COBJMACROS @@ -30,7 +27,6 @@ #include "wincodecs_private.h" #include "wine/debug.h" -#include "wine/library.h" WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); @@ -156,7 +152,7 @@ static ULONG WINAPI TgaDecoder_AddRef(IWICBitmapDecoder *iface) TgaDecoder *This = impl_from_IWICBitmapDecoder(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); return ref; } @@ -166,7 +162,7 @@ static ULONG WINAPI TgaDecoder_Release(IWICBitmapDecoder *iface) TgaDecoder *This = impl_from_IWICBitmapDecoder(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p) refcount=%u\n", iface, ref); + TRACE("(%p) refcount=%lu\n", iface, ref); if (ref == 0) { @@ -174,8 +170,8 @@ static ULONG WINAPI TgaDecoder_Release(IWICBitmapDecoder *iface) DeleteCriticalSection(&This->lock); if (This->stream) IStream_Release(This->stream); - HeapFree(GetProcessHeap(), 0, This->imagebits); - HeapFree(GetProcessHeap(), 0, This); + free(This->imagebits); + free(This); } return ref; @@ -226,7 +222,7 @@ static HRESULT WINAPI TgaDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p hr = IStream_Read(pIStream, &This->header, sizeof(tga_header), &bytesread); if (SUCCEEDED(hr) && bytesread != sizeof(tga_header)) { - TRACE("got only %u bytes\n", bytesread); + TRACE("got only %lu bytes\n", bytesread); hr = E_FAIL; } if (FAILED(hr)) goto end; @@ -298,7 +294,7 @@ static HRESULT WINAPI TgaDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p hr = IStream_Read(pIStream, &footer, sizeof(tga_footer), &bytesread); if (SUCCEEDED(hr) && bytesread != sizeof(tga_footer)) { - TRACE("got only %u footer bytes\n", bytesread); + TRACE("got only %lu footer bytes\n", bytesread); hr = E_FAIL; } @@ -330,7 +326,7 @@ static HRESULT WINAPI TgaDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p hr = IStream_Read(pIStream, &This->extension_area, sizeof(tga_extension_area), &bytesread); if (SUCCEEDED(hr) && bytesread != sizeof(tga_extension_area)) { - TRACE("got only %u extension area bytes\n", bytesread); + TRACE("got only %lu extension area bytes\n", bytesread); hr = E_FAIL; } if (SUCCEEDED(hr) && This->extension_area.size < 495) @@ -627,7 +623,7 @@ static HRESULT WINAPI TgaDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface, return E_FAIL; } - colormap_data = HeapAlloc(GetProcessHeap(), 0, This->colormap_length); + colormap_data = malloc(This->colormap_length); if (!colormap_data) return E_OUTOFMEMORY; wcolormap_data = (WORD*)colormap_data; @@ -643,7 +639,7 @@ static HRESULT WINAPI TgaDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface, hr = IStream_Read(This->stream, colormap_data, This->colormap_length, &bytesread); if (SUCCEEDED(hr) && bytesread != This->colormap_length) { - WARN("expected %i bytes in colormap, got %i\n", This->colormap_length, bytesread); + WARN("expected %li bytes in colormap, got %li\n", This->colormap_length, bytesread); hr = E_FAIL; } } @@ -747,7 +743,7 @@ static HRESULT WINAPI TgaDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface, } } - HeapFree(GetProcessHeap(), 0, colormap_data); + free(colormap_data); if (SUCCEEDED(hr)) hr = IWICPalette_InitializeCustom(pIPalette, colors, 256); @@ -835,7 +831,7 @@ static HRESULT TgaDecoder_ReadImage(TgaDecoder *This) if (SUCCEEDED(hr)) { datasize = This->header.width * This->header.height * (This->header.depth / 8); - This->imagebits = HeapAlloc(GetProcessHeap(), 0, datasize); + This->imagebits = malloc(datasize); if (!This->imagebits) hr = E_OUTOFMEMORY; } @@ -874,7 +870,7 @@ static HRESULT TgaDecoder_ReadImage(TgaDecoder *This) } else { - HeapFree(GetProcessHeap(), 0, This->imagebits); + free(This->imagebits); This->imagebits = NULL; } } @@ -948,7 +944,7 @@ HRESULT TgaDecoder_CreateInstance(REFIID iid, void** ppv) *ppv = NULL; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(TgaDecoder)); + This = malloc(sizeof(TgaDecoder)); if (!This) return E_OUTOFMEMORY; This->IWICBitmapDecoder_iface.lpVtbl = &TgaDecoder_Vtbl; @@ -957,7 +953,11 @@ HRESULT TgaDecoder_CreateInstance(REFIID iid, void** ppv) This->initialized = FALSE; This->stream = NULL; This->imagebits = NULL; +#ifdef __REACTOS__ InitializeCriticalSection(&This->lock); +#else + InitializeCriticalSectionEx(&This->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); +#endif This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TgaDecoder.lock"); ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); diff --git a/dll/win32/windowscodecs/tiffformat.c b/dll/win32/windowscodecs/tiffformat.c deleted file mode 100644 index b3d32eec611..00000000000 --- a/dll/win32/windowscodecs/tiffformat.c +++ /dev/null @@ -1,2385 +0,0 @@ -/* - * Copyright 2010 Vincent Povirk for CodeWeavers - * Copyright 2016 Dmitry Timoshkov - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_TIFFIO_H -#include -#endif - -#define COBJMACROS - -#include "windef.h" -#include "winbase.h" -#include "objbase.h" - -#include "wincodecs_private.h" - -#include "wine/debug.h" -#include "wine/library.h" - -WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); - -#ifdef SONAME_LIBTIFF - -/* Workaround for broken libtiff 4.x headers on some 64-bit hosts which - * define TIFF_UINT64_T/toff_t as 32-bit for 32-bit builds, while they - * are supposed to be always 64-bit. - * TIFF_UINT64_T doesn't exist in libtiff 3.x, it was introduced in 4.x. - */ -#ifdef TIFF_UINT64_T -# undef toff_t -# define toff_t UINT64 -#endif - -static CRITICAL_SECTION init_tiff_cs; -static CRITICAL_SECTION_DEBUG init_tiff_cs_debug = -{ - 0, 0, &init_tiff_cs, - { &init_tiff_cs_debug.ProcessLocksList, - &init_tiff_cs_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": init_tiff_cs") } -}; -static CRITICAL_SECTION init_tiff_cs = { &init_tiff_cs_debug, -1, 0, 0, 0, 0 }; - -static const WCHAR wszTiffCompressionMethod[] = {'T','i','f','f','C','o','m','p','r','e','s','s','i','o','n','M','e','t','h','o','d',0}; -static const WCHAR wszCompressionQuality[] = {'C','o','m','p','r','e','s','s','i','o','n','Q','u','a','l','i','t','y',0}; - -static void *libtiff_handle; -#define MAKE_FUNCPTR(f) static typeof(f) * p##f -MAKE_FUNCPTR(TIFFClientOpen); -MAKE_FUNCPTR(TIFFClose); -MAKE_FUNCPTR(TIFFCurrentDirOffset); -MAKE_FUNCPTR(TIFFGetField); -MAKE_FUNCPTR(TIFFIsByteSwapped); -MAKE_FUNCPTR(TIFFNumberOfDirectories); -MAKE_FUNCPTR(TIFFReadDirectory); -MAKE_FUNCPTR(TIFFReadEncodedStrip); -MAKE_FUNCPTR(TIFFReadEncodedTile); -MAKE_FUNCPTR(TIFFSetDirectory); -MAKE_FUNCPTR(TIFFSetField); -MAKE_FUNCPTR(TIFFWriteDirectory); -MAKE_FUNCPTR(TIFFWriteScanline); -#undef MAKE_FUNCPTR - -static void *load_libtiff(void) -{ - void *result; - - EnterCriticalSection(&init_tiff_cs); - - if (!libtiff_handle && - (libtiff_handle = wine_dlopen(SONAME_LIBTIFF, RTLD_NOW, NULL, 0)) != NULL) - { - void * (*pTIFFSetWarningHandler)(void *); - void * (*pTIFFSetWarningHandlerExt)(void *); - -#define LOAD_FUNCPTR(f) \ - if((p##f = wine_dlsym(libtiff_handle, #f, NULL, 0)) == NULL) { \ - ERR("failed to load symbol %s\n", #f); \ - libtiff_handle = NULL; \ - LeaveCriticalSection(&init_tiff_cs); \ - return NULL; \ - } - LOAD_FUNCPTR(TIFFClientOpen); - LOAD_FUNCPTR(TIFFClose); - LOAD_FUNCPTR(TIFFCurrentDirOffset); - LOAD_FUNCPTR(TIFFGetField); - LOAD_FUNCPTR(TIFFIsByteSwapped); - LOAD_FUNCPTR(TIFFNumberOfDirectories); - LOAD_FUNCPTR(TIFFReadDirectory); - LOAD_FUNCPTR(TIFFReadEncodedStrip); - LOAD_FUNCPTR(TIFFReadEncodedTile); - LOAD_FUNCPTR(TIFFSetDirectory); - LOAD_FUNCPTR(TIFFSetField); - LOAD_FUNCPTR(TIFFWriteDirectory); - LOAD_FUNCPTR(TIFFWriteScanline); -#undef LOAD_FUNCPTR - - if ((pTIFFSetWarningHandler = wine_dlsym(libtiff_handle, "TIFFSetWarningHandler", NULL, 0))) - pTIFFSetWarningHandler(NULL); - if ((pTIFFSetWarningHandlerExt = wine_dlsym(libtiff_handle, "TIFFSetWarningHandlerExt", NULL, 0))) - pTIFFSetWarningHandlerExt(NULL); - } - - result = libtiff_handle; - - LeaveCriticalSection(&init_tiff_cs); - return result; -} - -static tsize_t tiff_stream_read(thandle_t client_data, tdata_t data, tsize_t size) -{ - IStream *stream = (IStream*)client_data; - ULONG bytes_read; - HRESULT hr; - - hr = IStream_Read(stream, data, size, &bytes_read); - if (FAILED(hr)) bytes_read = 0; - return bytes_read; -} - -static tsize_t tiff_stream_write(thandle_t client_data, tdata_t data, tsize_t size) -{ - IStream *stream = (IStream*)client_data; - ULONG bytes_written; - HRESULT hr; - - hr = IStream_Write(stream, data, size, &bytes_written); - if (FAILED(hr)) bytes_written = 0; - return bytes_written; -} - -static toff_t tiff_stream_seek(thandle_t client_data, toff_t offset, int whence) -{ - IStream *stream = (IStream*)client_data; - LARGE_INTEGER move; - DWORD origin; - ULARGE_INTEGER new_position; - HRESULT hr; - - move.QuadPart = offset; - switch (whence) - { - case SEEK_SET: - origin = STREAM_SEEK_SET; - break; - case SEEK_CUR: - origin = STREAM_SEEK_CUR; - break; - case SEEK_END: - origin = STREAM_SEEK_END; - break; - default: - ERR("unknown whence value %i\n", whence); - return -1; - } - - hr = IStream_Seek(stream, move, origin, &new_position); - if (SUCCEEDED(hr)) return new_position.QuadPart; - else return -1; -} - -static int tiff_stream_close(thandle_t client_data) -{ - /* Caller is responsible for releasing the stream object. */ - return 0; -} - -static toff_t tiff_stream_size(thandle_t client_data) -{ - IStream *stream = (IStream*)client_data; - STATSTG statstg; - HRESULT hr; - - hr = IStream_Stat(stream, &statstg, STATFLAG_NONAME); - - if (SUCCEEDED(hr)) return statstg.cbSize.QuadPart; - else return -1; -} - -static int tiff_stream_map(thandle_t client_data, tdata_t *addr, toff_t *size) -{ - /* Cannot mmap streams */ - return 0; -} - -static void tiff_stream_unmap(thandle_t client_data, tdata_t addr, toff_t size) -{ - /* No need to ever do this, since we can't map things. */ -} - -static TIFF* tiff_open_stream(IStream *stream, const char *mode) -{ - LARGE_INTEGER zero; - - zero.QuadPart = 0; - IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL); - - return pTIFFClientOpen("", mode, stream, tiff_stream_read, - tiff_stream_write, (void *)tiff_stream_seek, tiff_stream_close, - (void *)tiff_stream_size, (void *)tiff_stream_map, (void *)tiff_stream_unmap); -} - -typedef struct { - IWICBitmapDecoder IWICBitmapDecoder_iface; - LONG ref; - IStream *stream; - CRITICAL_SECTION lock; /* Must be held when tiff is used or initialized is set */ - TIFF *tiff; - BOOL initialized; -} TiffDecoder; - -typedef struct { - const WICPixelFormatGUID *format; - int bps; - int samples; - int bpp, source_bpp; - int planar; - int indexed; - int reverse_bgr; - int invert_grayscale; - UINT width, height; - UINT tile_width, tile_height; - UINT tile_stride; - UINT tile_size; - int tiled; - UINT tiles_across; - UINT resolution_unit; - float xres, yres; -} tiff_decode_info; - -typedef struct { - IWICBitmapFrameDecode IWICBitmapFrameDecode_iface; - IWICMetadataBlockReader IWICMetadataBlockReader_iface; - LONG ref; - TiffDecoder *parent; - UINT index; - tiff_decode_info decode_info; - INT cached_tile_x, cached_tile_y; - BYTE *cached_tile; -} TiffFrameDecode; - -static const IWICBitmapFrameDecodeVtbl TiffFrameDecode_Vtbl; -static const IWICMetadataBlockReaderVtbl TiffFrameDecode_BlockVtbl; - -static inline TiffDecoder *impl_from_IWICBitmapDecoder(IWICBitmapDecoder *iface) -{ - return CONTAINING_RECORD(iface, TiffDecoder, IWICBitmapDecoder_iface); -} - -static inline TiffFrameDecode *impl_from_IWICBitmapFrameDecode(IWICBitmapFrameDecode *iface) -{ - return CONTAINING_RECORD(iface, TiffFrameDecode, IWICBitmapFrameDecode_iface); -} - -static inline TiffFrameDecode *impl_from_IWICMetadataBlockReader(IWICMetadataBlockReader *iface) -{ - return CONTAINING_RECORD(iface, TiffFrameDecode, IWICMetadataBlockReader_iface); -} - -static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info) -{ - uint16 photometric, bps, samples, planar; - uint16 extra_sample_count, extra_sample, *extra_samples; - int ret; - - decode_info->indexed = 0; - decode_info->reverse_bgr = 0; - decode_info->invert_grayscale = 0; - decode_info->tiled = 0; - decode_info->source_bpp = 0; - - ret = pTIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric); - if (!ret) - { - WARN("missing PhotometricInterpretation tag\n"); - return E_FAIL; - } - - ret = pTIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bps); - if (!ret) bps = 1; - decode_info->bps = bps; - - ret = pTIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &samples); - if (!ret) samples = 1; - decode_info->samples = samples; - - if (samples == 1) - planar = 1; - else - { - ret = pTIFFGetField(tiff, TIFFTAG_PLANARCONFIG, &planar); - if (!ret) planar = 1; - if (planar != 1) - { - FIXME("unhandled planar configuration %u\n", planar); - return E_FAIL; - } - } - decode_info->planar = planar; - - TRACE("planar %u, photometric %u, samples %u, bps %u\n", planar, photometric, samples, bps); - - switch(photometric) - { - case 0: /* WhiteIsZero */ - decode_info->invert_grayscale = 1; - /* fall through */ - case 1: /* BlackIsZero */ - if (samples == 2) - { - ret = pTIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &extra_sample_count, &extra_samples); - if (!ret) - { - extra_sample_count = 1; - extra_sample = 0; - extra_samples = &extra_sample; - } - } - else if (samples != 1) - { - FIXME("unhandled %dbpp sample count %u\n", bps, samples); - return E_FAIL; - } - - decode_info->bpp = bps * samples; - decode_info->source_bpp = decode_info->bpp; - switch (bps) - { - case 1: - if (samples != 1) - { - FIXME("unhandled 1bpp sample count %u\n", samples); - return E_FAIL; - } - decode_info->format = &GUID_WICPixelFormatBlackWhite; - break; - case 4: - if (samples != 1) - { - FIXME("unhandled 4bpp grayscale sample count %u\n", samples); - return E_FAIL; - } - decode_info->format = &GUID_WICPixelFormat4bppGray; - break; - case 8: - if (samples == 1) - decode_info->format = &GUID_WICPixelFormat8bppGray; - else - { - decode_info->bpp = 32; - - switch(extra_samples[0]) - { - case 1: /* Associated (pre-multiplied) alpha data */ - decode_info->format = &GUID_WICPixelFormat32bppPBGRA; - break; - case 0: /* Unspecified data */ - case 2: /* Unassociated alpha data */ - decode_info->format = &GUID_WICPixelFormat32bppBGRA; - break; - default: - FIXME("unhandled extra sample type %u\n", extra_samples[0]); - return E_FAIL; - } - } - break; - case 16: - if (samples != 1) - { - FIXME("unhandled 16bpp grayscale sample count %u\n", samples); - return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; - } - decode_info->format = &GUID_WICPixelFormat16bppGray; - break; - case 32: - if (samples != 1) - { - FIXME("unhandled 32bpp grayscale sample count %u\n", samples); - return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; - } - decode_info->format = &GUID_WICPixelFormat32bppGrayFloat; - break; - default: - WARN("unhandled greyscale bit count %u\n", bps); - return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; - } - break; - case 2: /* RGB */ - if (samples == 4) - { - ret = pTIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &extra_sample_count, &extra_samples); - if (!ret) - { - extra_sample_count = 1; - extra_sample = 0; - extra_samples = &extra_sample; - } - } - else if (samples != 3) - { - FIXME("unhandled RGB sample count %u\n", samples); - return E_FAIL; - } - - decode_info->bpp = max(bps, 8) * samples; - decode_info->source_bpp = bps * samples; - switch(bps) - { - case 1: - case 4: - case 8: - decode_info->reverse_bgr = 1; - if (samples == 3) - decode_info->format = &GUID_WICPixelFormat24bppBGR; - else - switch(extra_samples[0]) - { - case 1: /* Associated (pre-multiplied) alpha data */ - decode_info->format = &GUID_WICPixelFormat32bppPBGRA; - break; - case 0: /* Unspecified data */ - case 2: /* Unassociated alpha data */ - decode_info->format = &GUID_WICPixelFormat32bppBGRA; - break; - default: - FIXME("unhandled extra sample type %i\n", extra_samples[0]); - return E_FAIL; - } - break; - case 16: - if (samples == 3) - decode_info->format = &GUID_WICPixelFormat48bppRGB; - else - switch(extra_samples[0]) - { - case 1: /* Associated (pre-multiplied) alpha data */ - decode_info->format = &GUID_WICPixelFormat64bppPRGBA; - break; - case 0: /* Unspecified data */ - case 2: /* Unassociated alpha data */ - decode_info->format = &GUID_WICPixelFormat64bppRGBA; - break; - default: - FIXME("unhandled extra sample type %i\n", extra_samples[0]); - return E_FAIL; - } - break; - case 32: - if (samples != 4) - { - FIXME("unhandled 32bpp RGB sample count %u\n", samples); - return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; - } - decode_info->format = &GUID_WICPixelFormat128bppRGBAFloat; - break; - default: - WARN("unhandled RGB bit count %u\n", bps); - return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; - } - break; - case 3: /* RGB Palette */ - if (samples != 1) - { - FIXME("unhandled indexed sample count %u\n", samples); - return E_FAIL; - } - - decode_info->indexed = 1; - decode_info->bpp = bps; - switch (bps) - { - case 1: - decode_info->format = &GUID_WICPixelFormat1bppIndexed; - break; - case 2: - decode_info->format = &GUID_WICPixelFormat2bppIndexed; - break; - case 4: - decode_info->format = &GUID_WICPixelFormat4bppIndexed; - break; - case 8: - decode_info->format = &GUID_WICPixelFormat8bppIndexed; - break; - default: - FIXME("unhandled indexed bit count %u\n", bps); - return E_NOTIMPL; - } - break; - - case 5: /* Separated */ - if (samples != 4) - { - FIXME("unhandled Separated sample count %u\n", samples); - return E_FAIL; - } - - decode_info->bpp = bps * samples; - switch(bps) - { - case 8: - decode_info->format = &GUID_WICPixelFormat32bppCMYK; - break; - case 16: - decode_info->format = &GUID_WICPixelFormat64bppCMYK; - break; - - default: - WARN("unhandled Separated bit count %u\n", bps); - return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; - } - break; - - case 4: /* Transparency mask */ - case 6: /* YCbCr */ - case 8: /* CIELab */ - default: - FIXME("unhandled PhotometricInterpretation %u\n", photometric); - return E_FAIL; - } - - ret = pTIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &decode_info->width); - if (!ret) - { - WARN("missing image width\n"); - return E_FAIL; - } - - ret = pTIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &decode_info->height); - if (!ret) - { - WARN("missing image length\n"); - return E_FAIL; - } - - if ((ret = pTIFFGetField(tiff, TIFFTAG_TILEWIDTH, &decode_info->tile_width))) - { - decode_info->tiled = 1; - - ret = pTIFFGetField(tiff, TIFFTAG_TILELENGTH, &decode_info->tile_height); - if (!ret) - { - WARN("missing tile height\n"); - return E_FAIL; - } - - decode_info->tile_stride = ((decode_info->bpp * decode_info->tile_width + 7)/8); - decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride; - decode_info->tiles_across = (decode_info->width + decode_info->tile_width - 1) / decode_info->tile_width; - } - else if ((ret = pTIFFGetField(tiff, TIFFTAG_ROWSPERSTRIP, &decode_info->tile_height))) - { - if (decode_info->tile_height > decode_info->height) - decode_info->tile_height = decode_info->height; - decode_info->tile_width = decode_info->width; - decode_info->tile_stride = ((decode_info->bpp * decode_info->tile_width + 7)/8); - decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride; - } - else - { - /* Some broken TIFF files have a single strip and lack the RowsPerStrip tag */ - decode_info->tile_height = decode_info->height; - decode_info->tile_width = decode_info->width; - decode_info->tile_stride = ((decode_info->bpp * decode_info->tile_width + 7)/8); - decode_info->tile_size = decode_info->tile_height * decode_info->tile_stride; - } - - decode_info->resolution_unit = 0; - pTIFFGetField(tiff, TIFFTAG_RESOLUTIONUNIT, &decode_info->resolution_unit); - - ret = pTIFFGetField(tiff, TIFFTAG_XRESOLUTION, &decode_info->xres); - if (!ret) - { - WARN("missing X resolution\n"); - } - /* Emulate the behavior of current libtiff versions (libtiff commit a39f6131) - * yielding 0 instead of INFINITY for IFD_RATIONAL fields with denominator 0. */ - if (!isfinite(decode_info->xres)) - { - decode_info->xres = 0.0; - } - - ret = pTIFFGetField(tiff, TIFFTAG_YRESOLUTION, &decode_info->yres); - if (!ret) - { - WARN("missing Y resolution\n"); - } - if (!isfinite(decode_info->yres)) - { - decode_info->yres = 0.0; - } - - return S_OK; -} - -static HRESULT WINAPI TiffDecoder_QueryInterface(IWICBitmapDecoder *iface, REFIID iid, - void **ppv) -{ - TiffDecoder *This = impl_from_IWICBitmapDecoder(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapDecoder, iid)) - { - *ppv = &This->IWICBitmapDecoder_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI TiffDecoder_AddRef(IWICBitmapDecoder *iface) -{ - TiffDecoder *This = impl_from_IWICBitmapDecoder(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - return ref; -} - -static ULONG WINAPI TiffDecoder_Release(IWICBitmapDecoder *iface) -{ - TiffDecoder *This = impl_from_IWICBitmapDecoder(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - if (ref == 0) - { - if (This->tiff) pTIFFClose(This->tiff); - if (This->stream) IStream_Release(This->stream); - This->lock.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static HRESULT WINAPI TiffDecoder_QueryCapability(IWICBitmapDecoder *iface, IStream *stream, - DWORD *capability) -{ - HRESULT hr; - - TRACE("(%p,%p,%p)\n", iface, stream, capability); - - if (!stream || !capability) return E_INVALIDARG; - - hr = IWICBitmapDecoder_Initialize(iface, stream, WICDecodeMetadataCacheOnDemand); - if (hr != S_OK) return hr; - - *capability = WICBitmapDecoderCapabilityCanDecodeAllImages | - WICBitmapDecoderCapabilityCanDecodeSomeImages | - WICBitmapDecoderCapabilityCanEnumerateMetadata; - return S_OK; -} - -static HRESULT WINAPI TiffDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream, - WICDecodeOptions cacheOptions) -{ - TiffDecoder *This = impl_from_IWICBitmapDecoder(iface); - TIFF *tiff; - tiff_decode_info decode_info; - HRESULT hr=S_OK; - - TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions); - - EnterCriticalSection(&This->lock); - - if (This->initialized) - { - hr = WINCODEC_ERR_WRONGSTATE; - goto exit; - } - - tiff = tiff_open_stream(pIStream, "r"); - if (!tiff) - { - hr = E_FAIL; - goto exit; - } - - /* make sure that TIFF format is supported */ - hr = tiff_get_decode_info(tiff, &decode_info); - if (hr != S_OK) - { - pTIFFClose(tiff); - goto exit; - } - - This->tiff = tiff; - This->stream = pIStream; - IStream_AddRef(pIStream); - This->initialized = TRUE; - -exit: - LeaveCriticalSection(&This->lock); - return hr; -} - -static HRESULT WINAPI TiffDecoder_GetContainerFormat(IWICBitmapDecoder *iface, - GUID *pguidContainerFormat) -{ - if (!pguidContainerFormat) return E_INVALIDARG; - - memcpy(pguidContainerFormat, &GUID_ContainerFormatTiff, sizeof(GUID)); - return S_OK; -} - -static HRESULT WINAPI TiffDecoder_GetDecoderInfo(IWICBitmapDecoder *iface, - IWICBitmapDecoderInfo **ppIDecoderInfo) -{ - TRACE("(%p,%p)\n", iface, ppIDecoderInfo); - - return get_decoder_info(&CLSID_WICTiffDecoder, ppIDecoderInfo); -} - -static HRESULT WINAPI TiffDecoder_CopyPalette(IWICBitmapDecoder *iface, - IWICPalette *palette) -{ - TRACE("(%p,%p)\n", iface, palette); - return WINCODEC_ERR_PALETTEUNAVAILABLE; -} - -static HRESULT WINAPI TiffDecoder_GetMetadataQueryReader(IWICBitmapDecoder *iface, - IWICMetadataQueryReader **ppIMetadataQueryReader) -{ - TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader); - - if (!ppIMetadataQueryReader) return E_INVALIDARG; - - *ppIMetadataQueryReader = NULL; - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI TiffDecoder_GetPreview(IWICBitmapDecoder *iface, - IWICBitmapSource **ppIBitmapSource) -{ - TRACE("(%p,%p)\n", iface, ppIBitmapSource); - - if (!ppIBitmapSource) return E_INVALIDARG; - - *ppIBitmapSource = NULL; - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI TiffDecoder_GetColorContexts(IWICBitmapDecoder *iface, - UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) -{ - FIXME("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI TiffDecoder_GetThumbnail(IWICBitmapDecoder *iface, - IWICBitmapSource **ppIThumbnail) -{ - TRACE("(%p,%p)\n", iface, ppIThumbnail); - - if (!ppIThumbnail) return E_INVALIDARG; - - *ppIThumbnail = NULL; - return WINCODEC_ERR_CODECNOTHUMBNAIL; -} - -static HRESULT WINAPI TiffDecoder_GetFrameCount(IWICBitmapDecoder *iface, - UINT *pCount) -{ - TiffDecoder *This = impl_from_IWICBitmapDecoder(iface); - - if (!pCount) return E_INVALIDARG; - - EnterCriticalSection(&This->lock); - *pCount = This->tiff ? pTIFFNumberOfDirectories(This->tiff) : 0; - LeaveCriticalSection(&This->lock); - - TRACE("(%p) <-- %i\n", iface, *pCount); - - return S_OK; -} - -static HRESULT WINAPI TiffDecoder_GetFrame(IWICBitmapDecoder *iface, - UINT index, IWICBitmapFrameDecode **ppIBitmapFrame) -{ - TiffDecoder *This = impl_from_IWICBitmapDecoder(iface); - TiffFrameDecode *result; - int res; - tiff_decode_info decode_info; - HRESULT hr; - - TRACE("(%p,%u,%p)\n", iface, index, ppIBitmapFrame); - - if (!This->tiff) - return WINCODEC_ERR_FRAMEMISSING; - - EnterCriticalSection(&This->lock); - res = pTIFFSetDirectory(This->tiff, index); - if (!res) hr = E_INVALIDARG; - else hr = tiff_get_decode_info(This->tiff, &decode_info); - LeaveCriticalSection(&This->lock); - - if (SUCCEEDED(hr)) - { - result = HeapAlloc(GetProcessHeap(), 0, sizeof(TiffFrameDecode)); - - if (result) - { - result->IWICBitmapFrameDecode_iface.lpVtbl = &TiffFrameDecode_Vtbl; - result->IWICMetadataBlockReader_iface.lpVtbl = &TiffFrameDecode_BlockVtbl; - result->ref = 1; - result->parent = This; - IWICBitmapDecoder_AddRef(iface); - result->index = index; - result->decode_info = decode_info; - result->cached_tile_x = -1; - result->cached_tile = HeapAlloc(GetProcessHeap(), 0, decode_info.tile_size); - - if (result->cached_tile) - *ppIBitmapFrame = &result->IWICBitmapFrameDecode_iface; - else - { - hr = E_OUTOFMEMORY; - IWICBitmapFrameDecode_Release(&result->IWICBitmapFrameDecode_iface); - } - } - else hr = E_OUTOFMEMORY; - } - - if (FAILED(hr)) *ppIBitmapFrame = NULL; - - return hr; -} - -static const IWICBitmapDecoderVtbl TiffDecoder_Vtbl = { - TiffDecoder_QueryInterface, - TiffDecoder_AddRef, - TiffDecoder_Release, - TiffDecoder_QueryCapability, - TiffDecoder_Initialize, - TiffDecoder_GetContainerFormat, - TiffDecoder_GetDecoderInfo, - TiffDecoder_CopyPalette, - TiffDecoder_GetMetadataQueryReader, - TiffDecoder_GetPreview, - TiffDecoder_GetColorContexts, - TiffDecoder_GetThumbnail, - TiffDecoder_GetFrameCount, - TiffDecoder_GetFrame -}; - -static HRESULT WINAPI TiffFrameDecode_QueryInterface(IWICBitmapFrameDecode *iface, REFIID iid, - void **ppv) -{ - TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapSource, iid) || - IsEqualIID(&IID_IWICBitmapFrameDecode, iid)) - { - *ppv = &This->IWICBitmapFrameDecode_iface; - } - else if (IsEqualIID(&IID_IWICMetadataBlockReader, iid)) - { - *ppv = &This->IWICMetadataBlockReader_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI TiffFrameDecode_AddRef(IWICBitmapFrameDecode *iface) -{ - TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - return ref; -} - -static ULONG WINAPI TiffFrameDecode_Release(IWICBitmapFrameDecode *iface) -{ - TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - if (ref == 0) - { - IWICBitmapDecoder_Release(&This->parent->IWICBitmapDecoder_iface); - HeapFree(GetProcessHeap(), 0, This->cached_tile); - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static HRESULT WINAPI TiffFrameDecode_GetSize(IWICBitmapFrameDecode *iface, - UINT *puiWidth, UINT *puiHeight) -{ - TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); - - *puiWidth = This->decode_info.width; - *puiHeight = This->decode_info.height; - - TRACE("(%p) <-- %ux%u\n", iface, *puiWidth, *puiHeight); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameDecode_GetPixelFormat(IWICBitmapFrameDecode *iface, - WICPixelFormatGUID *pPixelFormat) -{ - TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); - - memcpy(pPixelFormat, This->decode_info.format, sizeof(GUID)); - - TRACE("(%p) <-- %s\n", This, debugstr_guid(This->decode_info.format)); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameDecode_GetResolution(IWICBitmapFrameDecode *iface, - double *pDpiX, double *pDpiY) -{ - TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); - - if (This->decode_info.xres == 0 || This->decode_info.yres == 0) - { - *pDpiX = *pDpiY = 96.0; - } - else - { - switch (This->decode_info.resolution_unit) - { - default: - FIXME("unknown resolution unit %i\n", This->decode_info.resolution_unit); - /* fall through */ - case 0: /* Not set */ - case 1: /* Relative measurements */ - case 2: /* Inch */ - *pDpiX = This->decode_info.xres; - *pDpiY = This->decode_info.yres; - break; - case 3: /* Centimeter */ - *pDpiX = This->decode_info.xres * 2.54; - *pDpiY = This->decode_info.yres * 2.54; - break; - } - } - - TRACE("(%p) <-- %f,%f unit=%i\n", iface, *pDpiX, *pDpiY, This->decode_info.resolution_unit); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, - IWICPalette *pIPalette) -{ - TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); - uint16 *red, *green, *blue; - WICColor colors[256]; - int color_count, ret, i; - - TRACE("(%p,%p)\n", iface, pIPalette); - - color_count = 1<decode_info.bps; - - EnterCriticalSection(&This->parent->lock); - ret = pTIFFGetField(This->parent->tiff, TIFFTAG_COLORMAP, &red, &green, &blue); - LeaveCriticalSection(&This->parent->lock); - - if (!ret) - { - WARN("Couldn't read color map\n"); - return WINCODEC_ERR_PALETTEUNAVAILABLE; - } - - for (i=0; i>8) & 0xff); - } - - return IWICPalette_InitializeCustom(pIPalette, colors, color_count); -} - -static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT tile_y) -{ - tsize_t ret; - int swap_bytes; - - swap_bytes = pTIFFIsByteSwapped(This->parent->tiff); - - ret = pTIFFSetDirectory(This->parent->tiff, This->index); - if (ret == -1) - return E_FAIL; - - if (This->decode_info.tiled) - ret = pTIFFReadEncodedTile(This->parent->tiff, tile_x + tile_y * This->decode_info.tiles_across, This->cached_tile, This->decode_info.tile_size); - else - ret = pTIFFReadEncodedStrip(This->parent->tiff, tile_y, This->cached_tile, This->decode_info.tile_size); - - if (ret == -1) - return E_FAIL; - - /* 3bpp RGB */ - if (This->decode_info.source_bpp == 3 && This->decode_info.samples == 3 && This->decode_info.bpp == 24) - { - BYTE *srcdata, *src, *dst; - DWORD x, y, count, width_bytes = (This->decode_info.tile_width * 3 + 7) / 8; - - count = width_bytes * This->decode_info.tile_height; - - srcdata = HeapAlloc(GetProcessHeap(), 0, count); - if (!srcdata) return E_OUTOFMEMORY; - memcpy(srcdata, This->cached_tile, count); - - for (y = 0; y < This->decode_info.tile_height; y++) - { - src = srcdata + y * width_bytes; - dst = This->cached_tile + y * This->decode_info.tile_width * 3; - - for (x = 0; x < This->decode_info.tile_width; x += 8) - { - dst[2] = (src[0] & 0x80) ? 0xff : 0; /* R */ - dst[1] = (src[0] & 0x40) ? 0xff : 0; /* G */ - dst[0] = (src[0] & 0x20) ? 0xff : 0; /* B */ - if (x + 1 < This->decode_info.tile_width) - { - dst[5] = (src[0] & 0x10) ? 0xff : 0; /* R */ - dst[4] = (src[0] & 0x08) ? 0xff : 0; /* G */ - dst[3] = (src[0] & 0x04) ? 0xff : 0; /* B */ - } - if (x + 2 < This->decode_info.tile_width) - { - dst[8] = (src[0] & 0x02) ? 0xff : 0; /* R */ - dst[7] = (src[0] & 0x01) ? 0xff : 0; /* G */ - dst[6] = (src[1] & 0x80) ? 0xff : 0; /* B */ - } - if (x + 3 < This->decode_info.tile_width) - { - dst[11] = (src[1] & 0x40) ? 0xff : 0; /* R */ - dst[10] = (src[1] & 0x20) ? 0xff : 0; /* G */ - dst[9] = (src[1] & 0x10) ? 0xff : 0; /* B */ - } - if (x + 4 < This->decode_info.tile_width) - { - dst[14] = (src[1] & 0x08) ? 0xff : 0; /* R */ - dst[13] = (src[1] & 0x04) ? 0xff : 0; /* G */ - dst[12] = (src[1] & 0x02) ? 0xff : 0; /* B */ - } - if (x + 5 < This->decode_info.tile_width) - { - dst[17] = (src[1] & 0x01) ? 0xff : 0; /* R */ - dst[16] = (src[2] & 0x80) ? 0xff : 0; /* G */ - dst[15] = (src[2] & 0x40) ? 0xff : 0; /* B */ - } - if (x + 6 < This->decode_info.tile_width) - { - dst[20] = (src[2] & 0x20) ? 0xff : 0; /* R */ - dst[19] = (src[2] & 0x10) ? 0xff : 0; /* G */ - dst[18] = (src[2] & 0x08) ? 0xff : 0; /* B */ - } - if (x + 7 < This->decode_info.tile_width) - { - dst[23] = (src[2] & 0x04) ? 0xff : 0; /* R */ - dst[22] = (src[2] & 0x02) ? 0xff : 0; /* G */ - dst[21] = (src[2] & 0x01) ? 0xff : 0; /* B */ - } - src += 3; - dst += 24; - } - } - - HeapFree(GetProcessHeap(), 0, srcdata); - } - /* 12bpp RGB */ - else if (This->decode_info.source_bpp == 12 && This->decode_info.samples == 3 && This->decode_info.bpp == 24) - { - BYTE *srcdata, *src, *dst; - DWORD x, y, count, width_bytes = (This->decode_info.tile_width * 12 + 7) / 8; - - count = width_bytes * This->decode_info.tile_height; - - srcdata = HeapAlloc(GetProcessHeap(), 0, count); - if (!srcdata) return E_OUTOFMEMORY; - memcpy(srcdata, This->cached_tile, count); - - for (y = 0; y < This->decode_info.tile_height; y++) - { - src = srcdata + y * width_bytes; - dst = This->cached_tile + y * This->decode_info.tile_width * 3; - - for (x = 0; x < This->decode_info.tile_width; x += 2) - { - dst[0] = ((src[1] & 0xf0) >> 4) * 17; /* B */ - dst[1] = (src[0] & 0x0f) * 17; /* G */ - dst[2] = ((src[0] & 0xf0) >> 4) * 17; /* R */ - if (x + 1 < This->decode_info.tile_width) - { - dst[5] = (src[1] & 0x0f) * 17; /* B */ - dst[4] = ((src[2] & 0xf0) >> 4) * 17; /* G */ - dst[3] = (src[2] & 0x0f) * 17; /* R */ - } - src += 3; - dst += 6; - } - } - - HeapFree(GetProcessHeap(), 0, srcdata); - } - /* 4bps RGBA */ - else if (This->decode_info.source_bpp == 4 && This->decode_info.samples == 4 && This->decode_info.bpp == 32) - { - BYTE *srcdata, *src, *dst; - DWORD x, y, count, width_bytes = (This->decode_info.tile_width * 3 + 7) / 8; - - count = width_bytes * This->decode_info.tile_height; - - srcdata = HeapAlloc(GetProcessHeap(), 0, count); - if (!srcdata) return E_OUTOFMEMORY; - memcpy(srcdata, This->cached_tile, count); - - for (y = 0; y < This->decode_info.tile_height; y++) - { - src = srcdata + y * width_bytes; - dst = This->cached_tile + y * This->decode_info.tile_width * 4; - - /* 1 source byte expands to 2 BGRA samples */ - - for (x = 0; x < This->decode_info.tile_width; x += 2) - { - dst[0] = (src[0] & 0x20) ? 0xff : 0; /* B */ - dst[1] = (src[0] & 0x40) ? 0xff : 0; /* G */ - dst[2] = (src[0] & 0x80) ? 0xff : 0; /* R */ - dst[3] = (src[0] & 0x10) ? 0xff : 0; /* A */ - if (x + 1 < This->decode_info.tile_width) - { - dst[4] = (src[0] & 0x02) ? 0xff : 0; /* B */ - dst[5] = (src[0] & 0x04) ? 0xff : 0; /* G */ - dst[6] = (src[0] & 0x08) ? 0xff : 0; /* R */ - dst[7] = (src[0] & 0x01) ? 0xff : 0; /* A */ - } - src++; - dst += 8; - } - } - - HeapFree(GetProcessHeap(), 0, srcdata); - } - /* 16bpp RGBA */ - else if (This->decode_info.source_bpp == 16 && This->decode_info.samples == 4 && This->decode_info.bpp == 32) - { - BYTE *src, *dst; - DWORD count = This->decode_info.tile_width * This->decode_info.tile_height; - - src = This->cached_tile + count * 2; - dst = This->cached_tile + This->decode_info.tile_size; - - while (count--) - { - BYTE b[2]; - - src -= 2; - dst -= 4; - - b[0] = src[0]; - b[1] = src[1]; - - dst[0] = ((b[1] & 0xf0) >> 4) * 17; /* B */ - dst[1] = (b[0] & 0x0f) * 17; /* G */ - dst[2] = ((b[0] & 0xf0) >> 4) * 17; /* R */ - dst[3] = (b[1] & 0x0f) * 17; /* A */ - } - } - /* 8bpp grayscale with extra alpha */ - else if (This->decode_info.source_bpp == 16 && This->decode_info.samples == 2 && This->decode_info.bpp == 32) - { - BYTE *src; - DWORD *dst, count = This->decode_info.tile_width * This->decode_info.tile_height; - - src = This->cached_tile + This->decode_info.tile_width * This->decode_info.tile_height * 2 - 2; - dst = (DWORD *)(This->cached_tile + This->decode_info.tile_size - 4); - - while (count--) - { - *dst-- = src[0] | (src[0] << 8) | (src[0] << 16) | (src[1] << 24); - src -= 2; - } - } - - if (This->decode_info.reverse_bgr) - { - if (This->decode_info.bps == 8) - { - UINT sample_count = This->decode_info.samples; - - reverse_bgr8(sample_count, This->cached_tile, This->decode_info.tile_width, - This->decode_info.tile_height, This->decode_info.tile_width * sample_count); - } - } - - if (swap_bytes && This->decode_info.bps > 8) - { - UINT row, i, samples_per_row; - BYTE *sample, temp; - - samples_per_row = This->decode_info.tile_width * This->decode_info.samples; - - switch(This->decode_info.bps) - { - case 16: - for (row=0; rowdecode_info.tile_height; row++) - { - sample = This->cached_tile + row * This->decode_info.tile_stride; - for (i=0; idecode_info.bps); - return E_FAIL; - } - } - - if (This->decode_info.invert_grayscale) - { - BYTE *byte, *end; - - if (This->decode_info.samples != 1) - { - ERR("cannot invert grayscale image with %u samples\n", This->decode_info.samples); - return E_FAIL; - } - - end = This->cached_tile+This->decode_info.tile_size; - - for (byte = This->cached_tile; byte != end; byte++) - *byte = ~(*byte); - } - - This->cached_tile_x = tile_x; - This->cached_tile_y = tile_y; - - return S_OK; -} - -static HRESULT WINAPI TiffFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface, - const WICRect *prc, UINT cbStride, UINT cbBufferSize, BYTE *pbBuffer) -{ - TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); - UINT min_tile_x, max_tile_x, min_tile_y, max_tile_y; - UINT tile_x, tile_y; - WICRect rc; - HRESULT hr=S_OK; - BYTE *dst_tilepos; - UINT bytesperrow; - WICRect rect; - - TRACE("(%p,%s,%u,%u,%p)\n", iface, debug_wic_rect(prc), cbStride, cbBufferSize, pbBuffer); - - if (!prc) - { - rect.X = 0; - rect.Y = 0; - rect.Width = This->decode_info.width; - rect.Height = This->decode_info.height; - prc = ▭ - } - else - { - if (prc->X < 0 || prc->Y < 0 || prc->X+prc->Width > This->decode_info.width || - prc->Y+prc->Height > This->decode_info.height) - return E_INVALIDARG; - } - - bytesperrow = ((This->decode_info.bpp * prc->Width)+7)/8; - - if (cbStride < bytesperrow) - return E_INVALIDARG; - - if ((cbStride * (prc->Height-1)) + bytesperrow > cbBufferSize) - return E_INVALIDARG; - - min_tile_x = prc->X / This->decode_info.tile_width; - min_tile_y = prc->Y / This->decode_info.tile_height; - max_tile_x = (prc->X+prc->Width-1) / This->decode_info.tile_width; - max_tile_y = (prc->Y+prc->Height-1) / This->decode_info.tile_height; - - EnterCriticalSection(&This->parent->lock); - - for (tile_x=min_tile_x; tile_x <= max_tile_x; tile_x++) - { - for (tile_y=min_tile_y; tile_y <= max_tile_y; tile_y++) - { - if (tile_x != This->cached_tile_x || tile_y != This->cached_tile_y) - { - hr = TiffFrameDecode_ReadTile(This, tile_x, tile_y); - } - - if (SUCCEEDED(hr)) - { - if (prc->X < tile_x * This->decode_info.tile_width) - rc.X = 0; - else - rc.X = prc->X - tile_x * This->decode_info.tile_width; - - if (prc->Y < tile_y * This->decode_info.tile_height) - rc.Y = 0; - else - rc.Y = prc->Y - tile_y * This->decode_info.tile_height; - - if (prc->X+prc->Width > (tile_x+1) * This->decode_info.tile_width) - rc.Width = This->decode_info.tile_width - rc.X; - else if (prc->X < tile_x * This->decode_info.tile_width) - rc.Width = prc->Width + prc->X - tile_x * This->decode_info.tile_width; - else - rc.Width = prc->Width; - - if (prc->Y+prc->Height > (tile_y+1) * This->decode_info.tile_height) - rc.Height = This->decode_info.tile_height - rc.Y; - else if (prc->Y < tile_y * This->decode_info.tile_height) - rc.Height = prc->Height + prc->Y - tile_y * This->decode_info.tile_height; - else - rc.Height = prc->Height; - - dst_tilepos = pbBuffer + (cbStride * ((rc.Y + tile_y * This->decode_info.tile_height) - prc->Y)) + - ((This->decode_info.bpp * ((rc.X + tile_x * This->decode_info.tile_width) - prc->X) + 7) / 8); - - hr = copy_pixels(This->decode_info.bpp, This->cached_tile, - This->decode_info.tile_width, This->decode_info.tile_height, This->decode_info.tile_stride, - &rc, cbStride, cbBufferSize, dst_tilepos); - } - - if (FAILED(hr)) - { - LeaveCriticalSection(&This->parent->lock); - TRACE("<-- 0x%x\n", hr); - return hr; - } - } - } - - LeaveCriticalSection(&This->parent->lock); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDecode *iface, - IWICMetadataQueryReader **ppIMetadataQueryReader) -{ - TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); - - TRACE("(%p,%p)\n", iface, ppIMetadataQueryReader); - - if (!ppIMetadataQueryReader) - return E_INVALIDARG; - - return MetadataQueryReader_CreateInstance(&This->IWICMetadataBlockReader_iface, NULL, ppIMetadataQueryReader); -} - -static HRESULT WINAPI TiffFrameDecode_GetColorContexts(IWICBitmapFrameDecode *iface, - UINT cCount, IWICColorContext **ppIColorContexts, UINT *pcActualCount) -{ - TiffFrameDecode *This = impl_from_IWICBitmapFrameDecode(iface); - const BYTE *profile; - UINT len; - HRESULT hr; - - TRACE("(%p,%u,%p,%p)\n", iface, cCount, ppIColorContexts, pcActualCount); - - EnterCriticalSection(&This->parent->lock); - - if (pTIFFGetField(This->parent->tiff, TIFFTAG_ICCPROFILE, &len, &profile)) - { - if (cCount && ppIColorContexts) - { - hr = IWICColorContext_InitializeFromMemory(*ppIColorContexts, profile, len); - if (FAILED(hr)) - { - LeaveCriticalSection(&This->parent->lock); - return hr; - } - } - *pcActualCount = 1; - } - else - *pcActualCount = 0; - - LeaveCriticalSection(&This->parent->lock); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameDecode_GetThumbnail(IWICBitmapFrameDecode *iface, - IWICBitmapSource **ppIThumbnail) -{ - TRACE("(%p,%p)\n", iface, ppIThumbnail); - - if (!ppIThumbnail) return E_INVALIDARG; - - *ppIThumbnail = NULL; - return WINCODEC_ERR_CODECNOTHUMBNAIL; -} - -static const IWICBitmapFrameDecodeVtbl TiffFrameDecode_Vtbl = { - TiffFrameDecode_QueryInterface, - TiffFrameDecode_AddRef, - TiffFrameDecode_Release, - TiffFrameDecode_GetSize, - TiffFrameDecode_GetPixelFormat, - TiffFrameDecode_GetResolution, - TiffFrameDecode_CopyPalette, - TiffFrameDecode_CopyPixels, - TiffFrameDecode_GetMetadataQueryReader, - TiffFrameDecode_GetColorContexts, - TiffFrameDecode_GetThumbnail -}; - -static HRESULT WINAPI TiffFrameDecode_Block_QueryInterface(IWICMetadataBlockReader *iface, - REFIID iid, void **ppv) -{ - TiffFrameDecode *This = impl_from_IWICMetadataBlockReader(iface); - return IWICBitmapFrameDecode_QueryInterface(&This->IWICBitmapFrameDecode_iface, iid, ppv); -} - -static ULONG WINAPI TiffFrameDecode_Block_AddRef(IWICMetadataBlockReader *iface) -{ - TiffFrameDecode *This = impl_from_IWICMetadataBlockReader(iface); - return IWICBitmapFrameDecode_AddRef(&This->IWICBitmapFrameDecode_iface); -} - -static ULONG WINAPI TiffFrameDecode_Block_Release(IWICMetadataBlockReader *iface) -{ - TiffFrameDecode *This = impl_from_IWICMetadataBlockReader(iface); - return IWICBitmapFrameDecode_Release(&This->IWICBitmapFrameDecode_iface); -} - -static HRESULT WINAPI TiffFrameDecode_Block_GetContainerFormat(IWICMetadataBlockReader *iface, - GUID *guid) -{ - TRACE("(%p,%p)\n", iface, guid); - - if (!guid) return E_INVALIDARG; - - *guid = GUID_ContainerFormatTiff; - return S_OK; -} - -static HRESULT WINAPI TiffFrameDecode_Block_GetCount(IWICMetadataBlockReader *iface, - UINT *count) -{ - TRACE("%p,%p\n", iface, count); - - if (!count) return E_INVALIDARG; - - *count = 1; - return S_OK; -} - -static HRESULT create_metadata_reader(TiffFrameDecode *This, IWICMetadataReader **reader) -{ - HRESULT hr; - LARGE_INTEGER dir_offset; - IWICMetadataReader *metadata_reader; - IWICPersistStream *persist; - - /* FIXME: Use IWICComponentFactory_CreateMetadataReader once it's implemented */ - - hr = IfdMetadataReader_CreateInstance(&IID_IWICMetadataReader, (void **)&metadata_reader); - if (FAILED(hr)) return hr; - - hr = IWICMetadataReader_QueryInterface(metadata_reader, &IID_IWICPersistStream, (void **)&persist); - if (FAILED(hr)) - { - IWICMetadataReader_Release(metadata_reader); - return hr; - } - - EnterCriticalSection(&This->parent->lock); - - dir_offset.QuadPart = pTIFFCurrentDirOffset(This->parent->tiff); - hr = IStream_Seek(This->parent->stream, dir_offset, STREAM_SEEK_SET, NULL); - if (SUCCEEDED(hr)) - { - BOOL byte_swapped = pTIFFIsByteSwapped(This->parent->tiff); -#ifdef WORDS_BIGENDIAN - DWORD persist_options = byte_swapped ? WICPersistOptionLittleEndian : WICPersistOptionBigEndian; -#else - DWORD persist_options = byte_swapped ? WICPersistOptionBigEndian : WICPersistOptionLittleEndian; -#endif - persist_options |= WICPersistOptionNoCacheStream; - hr = IWICPersistStream_LoadEx(persist, This->parent->stream, NULL, persist_options); - if (FAILED(hr)) - ERR("IWICPersistStream_LoadEx error %#x\n", hr); - } - - LeaveCriticalSection(&This->parent->lock); - - IWICPersistStream_Release(persist); - - if (FAILED(hr)) - { - IWICMetadataReader_Release(metadata_reader); - return hr; - } - - *reader = metadata_reader; - return S_OK; -} - -static HRESULT WINAPI TiffFrameDecode_Block_GetReaderByIndex(IWICMetadataBlockReader *iface, - UINT index, IWICMetadataReader **reader) -{ - TiffFrameDecode *This = impl_from_IWICMetadataBlockReader(iface); - - TRACE("(%p,%u,%p)\n", iface, index, reader); - - if (!reader || index != 0) return E_INVALIDARG; - - return create_metadata_reader(This, reader); -} - -static HRESULT WINAPI TiffFrameDecode_Block_GetEnumerator(IWICMetadataBlockReader *iface, - IEnumUnknown **enum_metadata) -{ - FIXME("(%p,%p): stub\n", iface, enum_metadata); - return E_NOTIMPL; -} - -static const IWICMetadataBlockReaderVtbl TiffFrameDecode_BlockVtbl = -{ - TiffFrameDecode_Block_QueryInterface, - TiffFrameDecode_Block_AddRef, - TiffFrameDecode_Block_Release, - TiffFrameDecode_Block_GetContainerFormat, - TiffFrameDecode_Block_GetCount, - TiffFrameDecode_Block_GetReaderByIndex, - TiffFrameDecode_Block_GetEnumerator -}; - -HRESULT TiffDecoder_CreateInstance(REFIID iid, void** ppv) -{ - HRESULT ret; - TiffDecoder *This; - - TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); - - *ppv = NULL; - - if (!load_libtiff()) - { - ERR("Failed reading TIFF because unable to load %s\n",SONAME_LIBTIFF); - return E_FAIL; - } - - This = HeapAlloc(GetProcessHeap(), 0, sizeof(TiffDecoder)); - if (!This) return E_OUTOFMEMORY; - - This->IWICBitmapDecoder_iface.lpVtbl = &TiffDecoder_Vtbl; - This->ref = 1; - This->stream = NULL; - InitializeCriticalSection(&This->lock); - This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TiffDecoder.lock"); - This->tiff = NULL; - This->initialized = FALSE; - - ret = IWICBitmapDecoder_QueryInterface(&This->IWICBitmapDecoder_iface, iid, ppv); - IWICBitmapDecoder_Release(&This->IWICBitmapDecoder_iface); - - return ret; -} - -struct tiff_encode_format { - const WICPixelFormatGUID *guid; - int photometric; - int bps; - int samples; - int bpp; - int extra_sample; - int extra_sample_type; - int reverse_bgr; -}; - -static const struct tiff_encode_format formats[] = { - {&GUID_WICPixelFormat24bppBGR, 2, 8, 3, 24, 0, 0, 1}, - {&GUID_WICPixelFormat24bppRGB, 2, 8, 3, 24, 0, 0, 0}, - {&GUID_WICPixelFormatBlackWhite, 1, 1, 1, 1, 0, 0, 0}, - {&GUID_WICPixelFormat4bppGray, 1, 4, 1, 4, 0, 0, 0}, - {&GUID_WICPixelFormat8bppGray, 1, 8, 1, 8, 0, 0, 0}, - {&GUID_WICPixelFormat32bppBGRA, 2, 8, 4, 32, 1, 2, 1}, - {&GUID_WICPixelFormat32bppPBGRA, 2, 8, 4, 32, 1, 1, 1}, - {&GUID_WICPixelFormat48bppRGB, 2, 16, 3, 48, 0, 0, 0}, - {&GUID_WICPixelFormat64bppRGBA, 2, 16, 4, 64, 1, 2, 0}, - {&GUID_WICPixelFormat64bppPRGBA, 2, 16, 4, 64, 1, 1, 0}, - {&GUID_WICPixelFormat1bppIndexed, 3, 1, 1, 1, 0, 0, 0}, - {&GUID_WICPixelFormat4bppIndexed, 3, 4, 1, 4, 0, 0, 0}, - {&GUID_WICPixelFormat8bppIndexed, 3, 8, 1, 8, 0, 0, 0}, - {0} -}; - -typedef struct TiffEncoder { - IWICBitmapEncoder IWICBitmapEncoder_iface; - LONG ref; - IStream *stream; - CRITICAL_SECTION lock; /* Must be held when tiff is used or fields below are set */ - TIFF *tiff; - BOOL initialized; - BOOL committed; - ULONG num_frames; - ULONG num_frames_committed; -} TiffEncoder; - -static inline TiffEncoder *impl_from_IWICBitmapEncoder(IWICBitmapEncoder *iface) -{ - return CONTAINING_RECORD(iface, TiffEncoder, IWICBitmapEncoder_iface); -} - -typedef struct TiffFrameEncode { - IWICBitmapFrameEncode IWICBitmapFrameEncode_iface; - LONG ref; - TiffEncoder *parent; - /* fields below are protected by parent->lock */ - BOOL initialized; - BOOL info_written; - BOOL committed; - const struct tiff_encode_format *format; - UINT width, height; - double xres, yres; - UINT lines_written; - WICColor palette[256]; - UINT colors; -} TiffFrameEncode; - -static inline TiffFrameEncode *impl_from_IWICBitmapFrameEncode(IWICBitmapFrameEncode *iface) -{ - return CONTAINING_RECORD(iface, TiffFrameEncode, IWICBitmapFrameEncode_iface); -} - -static HRESULT WINAPI TiffFrameEncode_QueryInterface(IWICBitmapFrameEncode *iface, REFIID iid, - void **ppv) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapFrameEncode, iid)) - { - *ppv = &This->IWICBitmapFrameEncode_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI TiffFrameEncode_AddRef(IWICBitmapFrameEncode *iface) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - return ref; -} - -static ULONG WINAPI TiffFrameEncode_Release(IWICBitmapFrameEncode *iface) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - if (ref == 0) - { - IWICBitmapEncoder_Release(&This->parent->IWICBitmapEncoder_iface); - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static HRESULT WINAPI TiffFrameEncode_Initialize(IWICBitmapFrameEncode *iface, - IPropertyBag2 *pIEncoderOptions) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%p)\n", iface, pIEncoderOptions); - - EnterCriticalSection(&This->parent->lock); - - if (This->initialized) - { - LeaveCriticalSection(&This->parent->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->initialized = TRUE; - - LeaveCriticalSection(&This->parent->lock); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameEncode_SetSize(IWICBitmapFrameEncode *iface, - UINT uiWidth, UINT uiHeight) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%u,%u)\n", iface, uiWidth, uiHeight); - - EnterCriticalSection(&This->parent->lock); - - if (!This->initialized || This->info_written) - { - LeaveCriticalSection(&This->parent->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->width = uiWidth; - This->height = uiHeight; - - LeaveCriticalSection(&This->parent->lock); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameEncode_SetResolution(IWICBitmapFrameEncode *iface, - double dpiX, double dpiY) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - TRACE("(%p,%0.2f,%0.2f)\n", iface, dpiX, dpiY); - - EnterCriticalSection(&This->parent->lock); - - if (!This->initialized || This->info_written) - { - LeaveCriticalSection(&This->parent->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - This->xres = dpiX; - This->yres = dpiY; - - LeaveCriticalSection(&This->parent->lock); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameEncode_SetPixelFormat(IWICBitmapFrameEncode *iface, - WICPixelFormatGUID *pPixelFormat) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - int i; - - TRACE("(%p,%s)\n", iface, debugstr_guid(pPixelFormat)); - - EnterCriticalSection(&This->parent->lock); - - if (!This->initialized || This->info_written) - { - LeaveCriticalSection(&This->parent->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - if (IsEqualGUID(pPixelFormat, &GUID_WICPixelFormat2bppIndexed)) - *pPixelFormat = GUID_WICPixelFormat4bppIndexed; - - for (i=0; formats[i].guid; i++) - { - if (IsEqualGUID(formats[i].guid, pPixelFormat)) - break; - } - - if (!formats[i].guid) i = 0; - - This->format = &formats[i]; - memcpy(pPixelFormat, This->format->guid, sizeof(GUID)); - - LeaveCriticalSection(&This->parent->lock); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameEncode_SetColorContexts(IWICBitmapFrameEncode *iface, - UINT cCount, IWICColorContext **ppIColorContext) -{ - FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); - return E_NOTIMPL; -} - -static HRESULT WINAPI TiffFrameEncode_SetPalette(IWICBitmapFrameEncode *iface, - IWICPalette *palette) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr; - - TRACE("(%p,%p)\n", iface, palette); - - if (!palette) return E_INVALIDARG; - - EnterCriticalSection(&This->parent->lock); - - if (This->initialized) - hr = IWICPalette_GetColors(palette, 256, This->palette, &This->colors); - else - hr = WINCODEC_ERR_NOTINITIALIZED; - - LeaveCriticalSection(&This->parent->lock); - return hr; -} - -static HRESULT WINAPI TiffFrameEncode_SetThumbnail(IWICBitmapFrameEncode *iface, - IWICBitmapSource *pIThumbnail) -{ - FIXME("(%p,%p): stub\n", iface, pIThumbnail); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI TiffFrameEncode_WritePixels(IWICBitmapFrameEncode *iface, - UINT lineCount, UINT cbStride, UINT cbBufferSize, BYTE *pbPixels) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - BYTE *row_data, *swapped_data = NULL; - UINT i, j, line_size; - - TRACE("(%p,%u,%u,%u,%p)\n", iface, lineCount, cbStride, cbBufferSize, pbPixels); - - EnterCriticalSection(&This->parent->lock); - - if (!This->initialized || !This->width || !This->height || !This->format) - { - LeaveCriticalSection(&This->parent->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - if (lineCount == 0 || lineCount + This->lines_written > This->height) - { - LeaveCriticalSection(&This->parent->lock); - return E_INVALIDARG; - } - - line_size = ((This->width * This->format->bpp)+7)/8; - - if (This->format->reverse_bgr) - { - swapped_data = HeapAlloc(GetProcessHeap(), 0, line_size); - if (!swapped_data) - { - LeaveCriticalSection(&This->parent->lock); - return E_OUTOFMEMORY; - } - } - - if (!This->info_written) - { - pTIFFSetField(This->parent->tiff, TIFFTAG_PHOTOMETRIC, (uint16)This->format->photometric); - pTIFFSetField(This->parent->tiff, TIFFTAG_PLANARCONFIG, (uint16)1); - pTIFFSetField(This->parent->tiff, TIFFTAG_BITSPERSAMPLE, (uint16)This->format->bps); - pTIFFSetField(This->parent->tiff, TIFFTAG_SAMPLESPERPIXEL, (uint16)This->format->samples); - - if (This->format->extra_sample) - { - uint16 extra_samples; - extra_samples = This->format->extra_sample_type; - - pTIFFSetField(This->parent->tiff, TIFFTAG_EXTRASAMPLES, (uint16)1, &extra_samples); - } - - pTIFFSetField(This->parent->tiff, TIFFTAG_IMAGEWIDTH, (uint32)This->width); - pTIFFSetField(This->parent->tiff, TIFFTAG_IMAGELENGTH, (uint32)This->height); - - if (This->xres != 0.0 && This->yres != 0.0) - { - pTIFFSetField(This->parent->tiff, TIFFTAG_RESOLUTIONUNIT, (uint16)2); /* Inch */ - pTIFFSetField(This->parent->tiff, TIFFTAG_XRESOLUTION, (float)This->xres); - pTIFFSetField(This->parent->tiff, TIFFTAG_YRESOLUTION, (float)This->yres); - } - - if (This->format->bpp <= 8 && This->colors && !IsEqualGUID(This->format->guid, &GUID_WICPixelFormatBlackWhite)) - { - uint16 red[256], green[256], blue[256]; - UINT i; - - for (i = 0; i < This->colors; i++) - { - red[i] = (This->palette[i] >> 8) & 0xff00; - green[i] = This->palette[i] & 0xff00; - blue[i] = (This->palette[i] << 8) & 0xff00; - } - - pTIFFSetField(This->parent->tiff, TIFFTAG_COLORMAP, red, green, blue); - } - - This->info_written = TRUE; - } - - for (i=0; iformat->reverse_bgr && This->format->bps == 8) - { - memcpy(swapped_data, row_data, line_size); - for (j=0; jformat->samples) - { - BYTE temp; - temp = swapped_data[j]; - swapped_data[j] = swapped_data[j+2]; - swapped_data[j+2] = temp; - } - row_data = swapped_data; - } - - pTIFFWriteScanline(This->parent->tiff, (tdata_t)row_data, i+This->lines_written, 0); - } - - This->lines_written += lineCount; - - LeaveCriticalSection(&This->parent->lock); - - HeapFree(GetProcessHeap(), 0, swapped_data); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameEncode_WriteSource(IWICBitmapFrameEncode *iface, - IWICBitmapSource *pIBitmapSource, WICRect *prc) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - HRESULT hr; - - TRACE("(%p,%p,%s)\n", iface, pIBitmapSource, debug_wic_rect(prc)); - - if (!This->initialized) - return WINCODEC_ERR_WRONGSTATE; - - hr = configure_write_source(iface, pIBitmapSource, prc, - This->format ? This->format->guid : NULL, This->width, This->height, - This->xres, This->yres); - - if (SUCCEEDED(hr)) - { - hr = write_source(iface, pIBitmapSource, prc, - This->format->guid, This->format->bpp, This->width, This->height); - } - - return hr; -} - -static HRESULT WINAPI TiffFrameEncode_Commit(IWICBitmapFrameEncode *iface) -{ - TiffFrameEncode *This = impl_from_IWICBitmapFrameEncode(iface); - - TRACE("(%p)\n", iface); - - EnterCriticalSection(&This->parent->lock); - - if (!This->info_written || This->lines_written != This->height || This->committed) - { - LeaveCriticalSection(&This->parent->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - /* libtiff will commit the data when creating a new frame or closing the file */ - - This->committed = TRUE; - This->parent->num_frames_committed++; - - LeaveCriticalSection(&This->parent->lock); - - return S_OK; -} - -static HRESULT WINAPI TiffFrameEncode_GetMetadataQueryWriter(IWICBitmapFrameEncode *iface, - IWICMetadataQueryWriter **ppIMetadataQueryWriter) -{ - FIXME("(%p, %p): stub\n", iface, ppIMetadataQueryWriter); - return E_NOTIMPL; -} - -static const IWICBitmapFrameEncodeVtbl TiffFrameEncode_Vtbl = { - TiffFrameEncode_QueryInterface, - TiffFrameEncode_AddRef, - TiffFrameEncode_Release, - TiffFrameEncode_Initialize, - TiffFrameEncode_SetSize, - TiffFrameEncode_SetResolution, - TiffFrameEncode_SetPixelFormat, - TiffFrameEncode_SetColorContexts, - TiffFrameEncode_SetPalette, - TiffFrameEncode_SetThumbnail, - TiffFrameEncode_WritePixels, - TiffFrameEncode_WriteSource, - TiffFrameEncode_Commit, - TiffFrameEncode_GetMetadataQueryWriter -}; - -static HRESULT WINAPI TiffEncoder_QueryInterface(IWICBitmapEncoder *iface, REFIID iid, - void **ppv) -{ - TiffEncoder *This = impl_from_IWICBitmapEncoder(iface); - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); - - if (!ppv) return E_INVALIDARG; - - if (IsEqualIID(&IID_IUnknown, iid) || - IsEqualIID(&IID_IWICBitmapEncoder, iid)) - { - *ppv = &This->IWICBitmapEncoder_iface; - } - else - { - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI TiffEncoder_AddRef(IWICBitmapEncoder *iface) -{ - TiffEncoder *This = impl_from_IWICBitmapEncoder(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - return ref; -} - -static ULONG WINAPI TiffEncoder_Release(IWICBitmapEncoder *iface) -{ - TiffEncoder *This = impl_from_IWICBitmapEncoder(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) refcount=%u\n", iface, ref); - - if (ref == 0) - { - if (This->tiff) pTIFFClose(This->tiff); - if (This->stream) IStream_Release(This->stream); - This->lock.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->lock); - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static HRESULT WINAPI TiffEncoder_Initialize(IWICBitmapEncoder *iface, - IStream *pIStream, WICBitmapEncoderCacheOption cacheOption) -{ - TiffEncoder *This = impl_from_IWICBitmapEncoder(iface); - TIFF *tiff; - HRESULT hr=S_OK; - - TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOption); - - EnterCriticalSection(&This->lock); - - if (This->initialized || This->committed) - { - hr = WINCODEC_ERR_WRONGSTATE; - goto exit; - } - - tiff = tiff_open_stream(pIStream, "w"); - - if (!tiff) - { - hr = E_FAIL; - goto exit; - } - - This->tiff = tiff; - This->stream = pIStream; - IStream_AddRef(pIStream); - This->initialized = TRUE; - -exit: - LeaveCriticalSection(&This->lock); - return hr; -} - -static HRESULT WINAPI TiffEncoder_GetContainerFormat(IWICBitmapEncoder *iface, - GUID *pguidContainerFormat) -{ - TRACE("(%p,%p)\n", iface, pguidContainerFormat); - - if (!pguidContainerFormat) - return E_INVALIDARG; - - memcpy(pguidContainerFormat, &GUID_ContainerFormatTiff, sizeof(GUID)); - return S_OK; -} - -static HRESULT WINAPI TiffEncoder_GetEncoderInfo(IWICBitmapEncoder *iface, IWICBitmapEncoderInfo **info) -{ - IWICComponentInfo *comp_info; - HRESULT hr; - - TRACE("%p,%p\n", iface, info); - - if (!info) return E_INVALIDARG; - - hr = CreateComponentInfo(&CLSID_WICTiffEncoder, &comp_info); - if (hr == S_OK) - { - hr = IWICComponentInfo_QueryInterface(comp_info, &IID_IWICBitmapEncoderInfo, (void **)info); - IWICComponentInfo_Release(comp_info); - } - return hr; -} - -static HRESULT WINAPI TiffEncoder_SetColorContexts(IWICBitmapEncoder *iface, - UINT cCount, IWICColorContext **ppIColorContext) -{ - FIXME("(%p,%u,%p): stub\n", iface, cCount, ppIColorContext); - return E_NOTIMPL; -} - -static HRESULT WINAPI TiffEncoder_SetPalette(IWICBitmapEncoder *iface, IWICPalette *palette) -{ - TiffEncoder *This = impl_from_IWICBitmapEncoder(iface); - HRESULT hr; - - TRACE("(%p,%p)\n", iface, palette); - - EnterCriticalSection(&This->lock); - - hr = This->stream ? WINCODEC_ERR_UNSUPPORTEDOPERATION : WINCODEC_ERR_NOTINITIALIZED; - - LeaveCriticalSection(&This->lock); - - return hr; -} - -static HRESULT WINAPI TiffEncoder_SetThumbnail(IWICBitmapEncoder *iface, IWICBitmapSource *pIThumbnail) -{ - TRACE("(%p,%p)\n", iface, pIThumbnail); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI TiffEncoder_SetPreview(IWICBitmapEncoder *iface, IWICBitmapSource *pIPreview) -{ - TRACE("(%p,%p)\n", iface, pIPreview); - return WINCODEC_ERR_UNSUPPORTEDOPERATION; -} - -static HRESULT WINAPI TiffEncoder_CreateNewFrame(IWICBitmapEncoder *iface, - IWICBitmapFrameEncode **ppIFrameEncode, IPropertyBag2 **ppIEncoderOptions) -{ - TiffEncoder *This = impl_from_IWICBitmapEncoder(iface); - TiffFrameEncode *result; - static const PROPBAG2 opts[2] = - { - { PROPBAG2_TYPE_DATA, VT_UI1, 0, 0, (LPOLESTR)wszTiffCompressionMethod }, - { PROPBAG2_TYPE_DATA, VT_R4, 0, 0, (LPOLESTR)wszCompressionQuality }, - }; - HRESULT hr=S_OK; - - TRACE("(%p,%p,%p)\n", iface, ppIFrameEncode, ppIEncoderOptions); - - EnterCriticalSection(&This->lock); - - if (!This->initialized || This->committed) - { - hr = WINCODEC_ERR_WRONGSTATE; - } - else if (This->num_frames != This->num_frames_committed) - { - FIXME("New frame created before previous frame was committed\n"); - hr = E_FAIL; - } - - if (ppIEncoderOptions && SUCCEEDED(hr)) - { - hr = CreatePropertyBag2(opts, ARRAY_SIZE(opts), ppIEncoderOptions); - if (SUCCEEDED(hr)) - { - VARIANT v; - VariantInit(&v); - V_VT(&v) = VT_UI1; - V_UI1(&v) = WICTiffCompressionDontCare; - hr = IPropertyBag2_Write(*ppIEncoderOptions, 1, (PROPBAG2 *)opts, &v); - VariantClear(&v); - if (FAILED(hr)) - { - IPropertyBag2_Release(*ppIEncoderOptions); - *ppIEncoderOptions = NULL; - } - } - } - - if (SUCCEEDED(hr)) - { - result = HeapAlloc(GetProcessHeap(), 0, sizeof(*result)); - - if (result) - { - result->IWICBitmapFrameEncode_iface.lpVtbl = &TiffFrameEncode_Vtbl; - result->ref = 1; - result->parent = This; - result->initialized = FALSE; - result->info_written = FALSE; - result->committed = FALSE; - result->format = NULL; - result->width = 0; - result->height = 0; - result->xres = 0.0; - result->yres = 0.0; - result->lines_written = 0; - result->colors = 0; - - IWICBitmapEncoder_AddRef(iface); - *ppIFrameEncode = &result->IWICBitmapFrameEncode_iface; - - if (This->num_frames != 0) - pTIFFWriteDirectory(This->tiff); - - This->num_frames++; - } - else - hr = E_OUTOFMEMORY; - - if (FAILED(hr)) - { - IPropertyBag2_Release(*ppIEncoderOptions); - *ppIEncoderOptions = NULL; - } - } - - LeaveCriticalSection(&This->lock); - - return hr; -} - -static HRESULT WINAPI TiffEncoder_Commit(IWICBitmapEncoder *iface) -{ - TiffEncoder *This = impl_from_IWICBitmapEncoder(iface); - - TRACE("(%p)\n", iface); - - EnterCriticalSection(&This->lock); - - if (!This->initialized || This->committed) - { - LeaveCriticalSection(&This->lock); - return WINCODEC_ERR_WRONGSTATE; - } - - pTIFFClose(This->tiff); - IStream_Release(This->stream); - This->stream = NULL; - This->tiff = NULL; - - This->committed = TRUE; - - LeaveCriticalSection(&This->lock); - - return S_OK; -} - -static HRESULT WINAPI TiffEncoder_GetMetadataQueryWriter(IWICBitmapEncoder *iface, - IWICMetadataQueryWriter **ppIMetadataQueryWriter) -{ - FIXME("(%p,%p): stub\n", iface, ppIMetadataQueryWriter); - return E_NOTIMPL; -} - -static const IWICBitmapEncoderVtbl TiffEncoder_Vtbl = { - TiffEncoder_QueryInterface, - TiffEncoder_AddRef, - TiffEncoder_Release, - TiffEncoder_Initialize, - TiffEncoder_GetContainerFormat, - TiffEncoder_GetEncoderInfo, - TiffEncoder_SetColorContexts, - TiffEncoder_SetPalette, - TiffEncoder_SetThumbnail, - TiffEncoder_SetPreview, - TiffEncoder_CreateNewFrame, - TiffEncoder_Commit, - TiffEncoder_GetMetadataQueryWriter -}; - -HRESULT TiffEncoder_CreateInstance(REFIID iid, void** ppv) -{ - TiffEncoder *This; - HRESULT ret; - - TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); - - *ppv = NULL; - - if (!load_libtiff()) - { - ERR("Failed writing TIFF because unable to load %s\n",SONAME_LIBTIFF); - return E_FAIL; - } - - This = HeapAlloc(GetProcessHeap(), 0, sizeof(TiffEncoder)); - if (!This) return E_OUTOFMEMORY; - - This->IWICBitmapEncoder_iface.lpVtbl = &TiffEncoder_Vtbl; - This->ref = 1; - This->stream = NULL; - InitializeCriticalSection(&This->lock); - This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TiffEncoder.lock"); - This->tiff = NULL; - This->initialized = FALSE; - This->num_frames = 0; - This->num_frames_committed = 0; - This->committed = FALSE; - - ret = IWICBitmapEncoder_QueryInterface(&This->IWICBitmapEncoder_iface, iid, ppv); - IWICBitmapEncoder_Release(&This->IWICBitmapEncoder_iface); - - return ret; -} - -#else /* !SONAME_LIBTIFF */ - -HRESULT TiffDecoder_CreateInstance(REFIID iid, void** ppv) -{ - ERR("Trying to load TIFF picture, but Wine was compiled without TIFF support.\n"); - return E_FAIL; -} - -HRESULT TiffEncoder_CreateInstance(REFIID iid, void** ppv) -{ - ERR("Trying to save TIFF picture, but Wine was compiled without TIFF support.\n"); - return E_FAIL; -} - -#endif diff --git a/dll/win32/windowscodecs/ungif.c b/dll/win32/windowscodecs/ungif.c index c6711c8e24c..63aa02427c6 100644 --- a/dll/win32/windowscodecs/ungif.c +++ b/dll/win32/windowscodecs/ungif.c @@ -58,26 +58,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); -static void *ungif_alloc( size_t sz ) -{ - return HeapAlloc( GetProcessHeap(), 0, sz ); -} - -static void *ungif_calloc( size_t num, size_t sz ) -{ - return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, num*sz ); -} - -static void *ungif_realloc( void *ptr, size_t sz ) -{ - return HeapReAlloc( GetProcessHeap(), 0, ptr, sz ); -} - -static void ungif_free( void *ptr ) -{ - HeapFree( GetProcessHeap(), 0, ptr ); -} - #define LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */ #define LZ_BITS 12 @@ -154,14 +134,14 @@ MakeMapObject(int ColorCount, return NULL; } - Object = ungif_alloc(sizeof(ColorMapObject)); + Object = malloc(sizeof(ColorMapObject)); if (Object == NULL) { return NULL; } - Object->Colors = ungif_calloc(ColorCount, sizeof(GifColorType)); + Object->Colors = calloc(ColorCount, sizeof(GifColorType)); if (Object->Colors == NULL) { - ungif_free(Object); + free(Object); return NULL; } @@ -182,8 +162,8 @@ static void FreeMapObject(ColorMapObject * Object) { if (Object != NULL) { - ungif_free(Object->Colors); - ungif_free(Object); + free(Object->Colors); + free(Object); /*** FIXME: * When we are willing to break API we need to make this function * FreeMapObject(ColorMapObject **Object) @@ -200,12 +180,9 @@ AddExtensionBlock(Extensions *New, ExtensionBlock *ep; - if (New->ExtensionBlocks == NULL) - New->ExtensionBlocks = ungif_alloc(sizeof(ExtensionBlock)); - else - New->ExtensionBlocks = ungif_realloc(New->ExtensionBlocks, - sizeof(ExtensionBlock) * - (New->ExtensionBlockCount + 1)); + New->ExtensionBlocks = realloc(New->ExtensionBlocks, + sizeof(ExtensionBlock) * + (New->ExtensionBlockCount + 1)); if (New->ExtensionBlocks == NULL) return (GIF_ERROR); @@ -213,7 +190,7 @@ AddExtensionBlock(Extensions *New, ep = &New->ExtensionBlocks[New->ExtensionBlockCount++]; ep->ByteCount=Len + 3; - ep->Bytes = ungif_alloc(ep->ByteCount + 3); + ep->Bytes = malloc(ep->ByteCount + 3); if (ep->Bytes == NULL) return (GIF_ERROR); @@ -242,7 +219,7 @@ AppendExtensionBlock(Extensions *New, ep = &New->ExtensionBlocks[New->ExtensionBlockCount - 1]; - ep->Bytes = ungif_realloc(ep->Bytes, ep->ByteCount + Len + 1); + ep->Bytes = realloc(ep->Bytes, ep->ByteCount + Len + 1); if (ep->Bytes == NULL) return (GIF_ERROR); @@ -266,8 +243,8 @@ FreeExtension(Extensions *Extensions) } for (ep = Extensions->ExtensionBlocks; ep < (Extensions->ExtensionBlocks + Extensions->ExtensionBlockCount); ep++) - ungif_free(ep->Bytes); - ungif_free(Extensions->ExtensionBlocks); + free(ep->Bytes); + free(Extensions->ExtensionBlocks); Extensions->ExtensionBlocks = NULL; } @@ -290,12 +267,12 @@ FreeSavedImages(GifFileType * GifFile) { sp->ImageDesc.ColorMap = NULL; } - ungif_free(sp->RasterBits); + free(sp->RasterBits); if (sp->Extensions.ExtensionBlocks) FreeExtension(&sp->Extensions); } - ungif_free(GifFile->SavedImages); + free(GifFile->SavedImages); GifFile->SavedImages=NULL; } @@ -320,6 +297,7 @@ DGifGetScreenDesc(GifFileType * GifFile) { GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1; SortFlag = (Buf[0] & 0x08) != 0; BitsPerPixel = (Buf[0] & 0x07) + 1; + GifFile->SColorTableSize = 1 << BitsPerPixel; GifFile->SBackGroundColor = Buf[1]; GifFile->SAspectRatio = Buf[2]; if (Buf[0] & 0x80) { /* Do we have global color map? */ @@ -431,16 +409,10 @@ DGifGetImageDesc(GifFileType * GifFile) { GifFile->Image.ColorMap = NULL; } - if (GifFile->SavedImages) { - if ((GifFile->SavedImages = ungif_realloc(GifFile->SavedImages, - sizeof(SavedImage) * - (GifFile->ImageCount + 1))) == NULL) { - return GIF_ERROR; - } - } else { - if ((GifFile->SavedImages = ungif_alloc(sizeof(SavedImage))) == NULL) { - return GIF_ERROR; - } + if ((GifFile->SavedImages = realloc(GifFile->SavedImages, + sizeof(SavedImage) * + (GifFile->ImageCount + 1))) == NULL) { + return GIF_ERROR; } sp = &GifFile->SavedImages[GifFile->ImageCount]; @@ -460,8 +432,7 @@ DGifGetImageDesc(GifFileType * GifFile) { GifFile->ImageCount++; - Private->PixelCount = (long)GifFile->Image.Width * - (long)GifFile->Image.Height; + Private->PixelCount = GifFile->Image.Width * GifFile->Image.Height; DGifSetupDecompress(GifFile); /* Reset decompress algorithm parameters. */ @@ -896,7 +867,7 @@ DGifSlurp(GifFileType * GifFile) { sp = &GifFile->SavedImages[GifFile->ImageCount - 1]; ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height; - sp->RasterBits = ungif_alloc(ImageSize * sizeof(GifPixelType)); + sp->RasterBits = malloc(ImageSize * sizeof(GifPixelType)); if (sp->RasterBits == NULL) { return GIF_ERROR; } @@ -997,16 +968,16 @@ DGifOpen(void *userData, GifFileType *GifFile; GifFilePrivateType *Private; - GifFile = ungif_alloc(sizeof(GifFileType)); + GifFile = malloc(sizeof(GifFileType)); if (GifFile == NULL) { return NULL; } memset(GifFile, '\0', sizeof(GifFileType)); - Private = ungif_alloc(sizeof(GifFilePrivateType)); + Private = malloc(sizeof(GifFilePrivateType)); if (!Private) { - ungif_free(GifFile); + free(GifFile); return NULL; } @@ -1017,8 +988,8 @@ DGifOpen(void *userData, /* Lets see if this is a GIF file: */ if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) { - ungif_free(Private); - ungif_free(GifFile); + free(Private); + free(GifFile); return NULL; } @@ -1026,14 +997,14 @@ DGifOpen(void *userData, * something more useful with it. */ Buf[GIF_STAMP_LEN] = 0; if (memcmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { - ungif_free(Private); - ungif_free(GifFile); + free(Private); + free(GifFile); return NULL; } if (DGifGetScreenDesc(GifFile) == GIF_ERROR) { - ungif_free(Private); - ungif_free(GifFile); + free(Private); + free(GifFile); return NULL; } @@ -1063,7 +1034,7 @@ DGifCloseFile(GifFileType * GifFile) { GifFile->SColorMap = NULL; } - ungif_free(Private); + free(Private); Private = NULL; if (GifFile->SavedImages) { @@ -1073,7 +1044,7 @@ DGifCloseFile(GifFileType * GifFile) { FreeExtension(&GifFile->Extensions); - ungif_free(GifFile); + free(GifFile); return GIF_OK; } diff --git a/dll/win32/windowscodecs/ungif.h b/dll/win32/windowscodecs/ungif.h index 6caa600bbf2..f61a7eb1e16 100644 --- a/dll/win32/windowscodecs/ungif.h +++ b/dll/win32/windowscodecs/ungif.h @@ -114,6 +114,7 @@ typedef struct { typedef struct GifFileType { GifWord SWidth, SHeight, /* Screen dimensions. */ SColorResolution, /* How many colors can we generate? */ + SColorTableSize, /* Calculated color table size, even if not present */ SBackGroundColor, /* I hope you understand this one... */ SAspectRatio; /* Pixel aspect ratio, in 1/64 units, starting at 1:4. */ ColorMapObject *SColorMap; /* NULL if not exists. */ @@ -144,9 +145,9 @@ typedef int (*InputFunc) (GifFileType *, GifByteType *, int); #define APPLICATION_EXT_FUNC_CODE 0xff /* application block */ /* public interface to ungif.c */ -int DGifSlurp(GifFileType * GifFile) DECLSPEC_HIDDEN; -GifFileType *DGifOpen(void *userPtr, InputFunc readFunc) DECLSPEC_HIDDEN; -int DGifCloseFile(GifFileType * GifFile) DECLSPEC_HIDDEN; +int DGifSlurp(GifFileType * GifFile); +GifFileType *DGifOpen(void *userPtr, InputFunc readFunc); +int DGifCloseFile(GifFileType * GifFile); #define D_GIF_ERR_OPEN_FAILED 101 /* And DGif possible errors. */ #define D_GIF_ERR_READ_FAILED 102 diff --git a/dll/win32/windowscodecs/uuid.c b/dll/win32/windowscodecs/uuid.c new file mode 100644 index 00000000000..74de2806344 --- /dev/null +++ b/dll/win32/windowscodecs/uuid.c @@ -0,0 +1,36 @@ +/* + * Copyright 2009 Vincent Povirk for CodeWeavers + * Copyright 2020 Jacek Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#if 0 +#pragma makedep implib +#endif + +#include "windows.h" +#include "ocidl.h" +#include "propidl.h" +#include "initguid.h" +#include "wincodec.h" +#include "wincodecsdk.h" + +DEFINE_GUID(IID_IMILBitmap,0xb1784d3f,0x8115,0x4763,0x13,0xaa,0x32,0xed,0xdb,0x68,0x29,0x4a); +DEFINE_GUID(IID_IMILBitmapSource,0x7543696a,0xbc8d,0x46b0,0x5f,0x81,0x8d,0x95,0x72,0x89,0x72,0xbe); +DEFINE_GUID(IID_IMILBitmapLock,0xa67b2b53,0x8fa1,0x4155,0x8f,0x64,0x0c,0x24,0x7a,0x8f,0x84,0xcd); +DEFINE_GUID(IID_IMILBitmapScaler,0xa767b0f0,0x1c8c,0x4aef,0x56,0x8f,0xad,0xf9,0x6d,0xcf,0xd5,0xcb); +DEFINE_GUID(IID_IMILFormatConverter,0x7e2a746f,0x25c5,0x4851,0xb3,0xaf,0x44,0x3b,0x79,0x63,0x9e,0xc0); +DEFINE_GUID(IID_IMILPalette,0xca8e206f,0xf22c,0x4af7,0x6f,0xba,0x7b,0xed,0x5e,0xb1,0xc9,0x2f); diff --git a/dll/win32/windowscodecs/wincodecs_common.c b/dll/win32/windowscodecs/wincodecs_common.c new file mode 100644 index 00000000000..8da1bfed20c --- /dev/null +++ b/dll/win32/windowscodecs/wincodecs_common.c @@ -0,0 +1,211 @@ +/* + * wincodecs_common.c - Functions shared with other WIC libraries. + * + * Copyright 2020 Esme Povirk + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include + +#include "windef.h" +#include "winbase.h" +#include "winternl.h" +#include "objbase.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + +#include "wincodecs_common.h" + +HRESULT configure_write_source(IWICBitmapFrameEncode *iface, + IWICBitmapSource *source, const WICRect *prc, + const WICPixelFormatGUID *format, + INT width, INT height, double xres, double yres) +{ + UINT src_width, src_height; + HRESULT hr = S_OK; + + if (width == 0 && height == 0) + { + if (prc) + { + if (prc->Width <= 0 || prc->Height <= 0) return E_INVALIDARG; + width = prc->Width; + height = prc->Height; + } + else + { + hr = IWICBitmapSource_GetSize(source, &src_width, &src_height); + if (FAILED(hr)) return hr; + if (src_width == 0 || src_height == 0) return E_INVALIDARG; + width = src_width; + height = src_height; + } + hr = IWICBitmapFrameEncode_SetSize(iface, (UINT)width, (UINT)height); + if (FAILED(hr)) return hr; + } + if (width == 0 || height == 0) return E_INVALIDARG; + + if (!format) + { + WICPixelFormatGUID src_format; + + hr = IWICBitmapSource_GetPixelFormat(source, &src_format); + if (FAILED(hr)) return hr; + + hr = IWICBitmapFrameEncode_SetPixelFormat(iface, &src_format); + if (FAILED(hr)) return hr; + } + + if (xres == 0.0 || yres == 0.0) + { + hr = IWICBitmapSource_GetResolution(source, &xres, &yres); + if (FAILED(hr)) return hr; + hr = IWICBitmapFrameEncode_SetResolution(iface, xres, yres); + if (FAILED(hr)) return hr; + } + + return hr; +} + +HRESULT write_source(IWICBitmapFrameEncode *iface, + IWICBitmapSource *source, const WICRect *prc, + const WICPixelFormatGUID *format, UINT bpp, BOOL need_palette, + INT width, INT height) +{ + IWICBitmapSource *converted_source; + HRESULT hr=S_OK; + WICRect rc; + UINT stride; + BYTE* pixeldata; + + if (!prc) + { + UINT src_width, src_height; + hr = IWICBitmapSource_GetSize(source, &src_width, &src_height); + if (FAILED(hr)) return hr; + rc.X = 0; + rc.Y = 0; + rc.Width = src_width; + rc.Height = src_height; + prc = &rc; + } + + if (prc->Width != width || prc->Height <= 0) + return E_INVALIDARG; + + hr = WICConvertBitmapSource(format, source, &converted_source); + if (FAILED(hr)) + { + ERR("Failed to convert source, target format %s, %#lx\n", debugstr_guid(format), hr); + return E_NOTIMPL; + } + + if (need_palette) + { + IWICImagingFactory *factory; + IWICPalette *palette; + + hr = create_instance(&CLSID_WICImagingFactory, &IID_IWICImagingFactory, (void**)&factory); + + if (SUCCEEDED(hr)) + { + hr = IWICImagingFactory_CreatePalette(factory, &palette); + IWICImagingFactory_Release(factory); + } + + if (SUCCEEDED(hr)) + { + hr = IWICBitmapSource_CopyPalette(converted_source, palette); + + if (SUCCEEDED(hr)) + hr = IWICBitmapFrameEncode_SetPalette(iface, palette); + + IWICPalette_Release(palette); + } + + if (FAILED(hr)) + { + IWICBitmapSource_Release(converted_source); + return hr; + } + } + + stride = (bpp * width + 7)/8; + + pixeldata = malloc(stride * prc->Height); + if (!pixeldata) + { + IWICBitmapSource_Release(converted_source); + return E_OUTOFMEMORY; + } + + hr = IWICBitmapSource_CopyPixels(converted_source, prc, stride, + stride*prc->Height, pixeldata); + + if (SUCCEEDED(hr)) + { + hr = IWICBitmapFrameEncode_WritePixels(iface, prc->Height, stride, + stride*prc->Height, pixeldata); + } + + free(pixeldata); + IWICBitmapSource_Release(converted_source); + + 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); +} diff --git a/dll/win32/windowscodecs/wincodecs_common.h b/dll/win32/windowscodecs/wincodecs_common.h new file mode 100644 index 00000000000..dcccdc2e5f1 --- /dev/null +++ b/dll/win32/windowscodecs/wincodecs_common.h @@ -0,0 +1,214 @@ +/* + * Copyright 2020 Esme Povirk + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +HRESULT CDECL decoder_initialize(struct decoder *decoder, IStream *stream, struct decoder_stat *st) +{ + return decoder->vtable->initialize(decoder, stream, st); +} + +HRESULT CDECL decoder_get_frame_info(struct decoder *decoder, UINT frame, struct decoder_frame *info) +{ + return decoder->vtable->get_frame_info(decoder, frame, info); +} + +HRESULT CDECL decoder_copy_pixels(struct decoder *decoder, UINT frame, + const WICRect *prc, UINT stride, UINT buffersize, BYTE *buffer) +{ + return decoder->vtable->copy_pixels(decoder, frame, prc, stride, buffersize, buffer); +} + +HRESULT CDECL decoder_get_metadata_blocks(struct decoder *decoder, UINT frame, UINT *count, struct decoder_block **blocks) +{ + return decoder->vtable->get_metadata_blocks(decoder, frame, count, blocks); +} + +HRESULT CDECL decoder_get_color_context(struct decoder *decoder, UINT frame, + UINT num, BYTE **data, DWORD *datasize) +{ + return decoder->vtable->get_color_context(decoder, frame, num, data, datasize); +} + +void CDECL decoder_destroy(struct decoder *decoder) +{ + decoder->vtable->destroy(decoder); +} + +HRESULT CDECL encoder_initialize(struct encoder *encoder, IStream *stream) +{ + return encoder->vtable->initialize(encoder, stream); +} + +HRESULT CDECL encoder_get_supported_format(struct encoder* encoder, GUID *pixel_format, DWORD *bpp, BOOL *indexed) +{ + return encoder->vtable->get_supported_format(encoder, pixel_format, bpp, indexed); +} + +HRESULT CDECL encoder_create_frame(struct encoder* encoder, const struct encoder_frame *frame) +{ + return encoder->vtable->create_frame(encoder, frame); +} + +HRESULT CDECL encoder_write_lines(struct encoder* encoder, BYTE *data, DWORD line_count, DWORD stride) +{ + return encoder->vtable->write_lines(encoder, data, line_count, stride); +} + +HRESULT CDECL encoder_commit_frame(struct encoder* encoder) +{ + return encoder->vtable->commit_frame(encoder); +} + +HRESULT CDECL encoder_commit_file(struct encoder* encoder) +{ + return encoder->vtable->commit_file(encoder); +} + +void CDECL encoder_destroy(struct encoder *encoder) +{ + encoder->vtable->destroy(encoder); +} + +HRESULT copy_pixels(UINT bpp, const BYTE *srcbuffer, + UINT srcwidth, UINT srcheight, INT srcstride, + const WICRect *rc, UINT dststride, UINT dstbuffersize, BYTE *dstbuffer) +{ + UINT bytesperrow; + UINT row_offset; /* number of bits into the source rows where the data starts */ + WICRect rect; + + if (!rc) + { + rect.X = 0; + rect.Y = 0; + rect.Width = srcwidth; + rect.Height = srcheight; + rc = ▭ + } + else + { + if (rc->X < 0 || rc->Y < 0 || rc->X+rc->Width > srcwidth || rc->Y+rc->Height > srcheight) + return E_INVALIDARG; + } + + bytesperrow = ((bpp * rc->Width)+7)/8; + + if (dststride < bytesperrow) + return E_INVALIDARG; + + if ((dststride * (rc->Height-1)) + bytesperrow > dstbuffersize) + return E_INVALIDARG; + + /* if the whole bitmap is copied and the buffer format matches then it's a matter of a single memcpy */ + if (rc->X == 0 && rc->Y == 0 && rc->Width == srcwidth && rc->Height == srcheight && + srcstride == dststride && srcstride == bytesperrow) + { + memcpy(dstbuffer, srcbuffer, srcstride * srcheight); + return S_OK; + } + + row_offset = rc->X * bpp; + + if (row_offset % 8 == 0) + { + /* everything lines up on a byte boundary */ + INT row; + const BYTE *src; + BYTE *dst; + + src = srcbuffer + (row_offset / 8) + srcstride * rc->Y; + dst = dstbuffer; + for (row=0; row < rc->Height; row++) + { + memcpy(dst, src, bytesperrow); + src += srcstride; + dst += dststride; + } + return S_OK; + } + else + { + /* we have to do a weird bitwise copy. eww. */ + FIXME("cannot reliably copy bitmap data if bpp < 8\n"); + return E_FAIL; + } +} + +static inline ULONG read_ulong_be(BYTE* data) +{ + return data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; +} + +HRESULT read_png_chunk(IStream *stream, BYTE *type, BYTE **data, ULONG *data_size) +{ + BYTE header[8]; + HRESULT hr; + ULONG bytesread; + + hr = stream_read(stream, header, 8, &bytesread); + if (FAILED(hr) || bytesread < 8) + { + if (SUCCEEDED(hr)) + hr = E_FAIL; + return hr; + } + + *data_size = read_ulong_be(&header[0]); + + memcpy(type, &header[4], 4); + + if (data) + { + *data = malloc(*data_size); + if (!*data) + return E_OUTOFMEMORY; + + hr = stream_read(stream, *data, *data_size, &bytesread); + + if (FAILED(hr) || bytesread < *data_size) + { + if (SUCCEEDED(hr)) + hr = E_FAIL; + free(*data); + *data = NULL; + return hr; + } + + /* Windows ignores CRC of the chunk */ + } + + return S_OK; +} + +void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride) +{ + UINT x, y; + BYTE *pixel, temp; + + for (y=0; y +#endif DEFINE_GUID(CLSID_WineTgaDecoder, 0xb11fc79a,0x67cc,0x43e6,0xa9,0xce,0xe3,0xd5,0x49,0x45,0xd3,0x04); -DEFINE_GUID(CLSID_WICIcnsEncoder, 0x312fb6f1,0xb767,0x409d,0x8a,0x6d,0x0f,0xc1,0x54,0xd4,0xf0,0x5c); - DEFINE_GUID(GUID_WineContainerFormatTga, 0x0c44fda1,0xa5c5,0x4298,0x96,0x85,0x47,0x3f,0xc1,0x7c,0xd3,0x22); DEFINE_GUID(GUID_VendorWine, 0xddf46da1,0x7dc1,0x404e,0x98,0xf2,0xef,0xa4,0x8d,0xfc,0x95,0x0a); -DEFINE_GUID(IID_IMILBitmap,0xb1784d3f,0x8115,0x4763,0x13,0xaa,0x32,0xed,0xdb,0x68,0x29,0x4a); -DEFINE_GUID(IID_IMILBitmapSource,0x7543696a,0xbc8d,0x46b0,0x5f,0x81,0x8d,0x95,0x72,0x89,0x72,0xbe); -DEFINE_GUID(IID_IMILBitmapLock,0xa67b2b53,0x8fa1,0x4155,0x8f,0x64,0x0c,0x24,0x7a,0x8f,0x84,0xcd); -DEFINE_GUID(IID_IMILBitmapScaler,0xa767b0f0,0x1c8c,0x4aef,0x56,0x8f,0xad,0xf9,0x6d,0xcf,0xd5,0xcb); -DEFINE_GUID(IID_IMILFormatConverter,0x7e2a746f,0x25c5,0x4851,0xb3,0xaf,0x44,0x3b,0x79,0x63,0x9e,0xc0); -DEFINE_GUID(IID_IMILPalette,0xca8e206f,0xf22c,0x4af7,0x6f,0xba,0x7b,0xed,0x5e,0xb1,0xc9,0x2f); +#ifdef __REACTOS__ +extern const GUID IID_IMILBitmap; +extern const GUID IID_IMILBitmapSource; +extern const GUID IID_IMILBitmapLock; +extern const GUID IID_IMILBitmapScaler; +extern const GUID IID_IMILFormatConverter; +extern const GUID IID_IMILPalette; +#else +extern IID IID_IMILBitmap; +extern IID IID_IMILBitmapSource; +extern IID IID_IMILBitmapLock; +extern IID IID_IMILBitmapScaler; +extern IID IID_IMILFormatConverter; +extern IID IID_IMILPalette; +#endif #define INTERFACE IMILBitmapSource DECLARE_INTERFACE_(IMILBitmapSource,IUnknown) @@ -108,18 +118,27 @@ DECLARE_INTERFACE_(IMILUnknown1,IUnknown) STDMETHOD_(ULONG,AddRef)(THIS) PURE; STDMETHOD_(ULONG,Release)(THIS) PURE; /*** thiscall method ***/ + #ifdef __REACTOS__ STDMETHOD_(void,unknown1)(THIS_ void*) PURE; - /*** stdcall ***/ + #else + THISCALLMETHOD_(void,unknown1)(THIS_ void*) PURE; + #endif STDMETHOD_(HRESULT,unknown2)(THIS_ void*, void*) PURE; - /*** thiscall method ***/ + #ifdef __REACTOS__ STDMETHOD_(HRESULT,unknown3)(THIS_ void*) PURE; - /*** stdcall ***/ + #else + THISCALLMETHOD_(HRESULT,unknown3)(THIS_ void*) PURE; + #endif STDMETHOD_(HRESULT,unknown4)(THIS_ void*) PURE; STDMETHOD_(HRESULT,unknown5)(THIS_ void*) PURE; STDMETHOD_(HRESULT,unknown6)(THIS_ DWORD64) PURE; STDMETHOD_(HRESULT,unknown7)(THIS_ void*) PURE; + #ifdef __REACTOS__ /*** thiscall method ***/ STDMETHOD_(HRESULT,unknown8)(THIS) PURE; + #else + THISCALLMETHOD_(HRESULT,unknown8)(THIS) PURE; + #endif }; #undef INTERFACE @@ -137,70 +156,70 @@ DECLARE_INTERFACE_(IMILUnknown2,IUnknown) }; #undef INTERFACE -HRESULT create_instance(CLSID *clsid, const IID *iid, void **ppv) DECLSPEC_HIDDEN; +HRESULT create_instance(const CLSID *clsid, const IID *iid, void **ppv); typedef HRESULT(*class_constructor)(REFIID,void**); -extern HRESULT FormatConverter_CreateInstance(REFIID riid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT ImagingFactory_CreateInstance(REFIID riid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT BmpDecoder_CreateInstance(REFIID riid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT PngDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT PngEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT BmpEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT DibDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT GifDecoder_CreateInstance(REFIID riid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT GifEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT IcoDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT JpegDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT JpegEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT TiffDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT TiffEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT IcnsEncoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT TgaDecoder_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; +extern HRESULT FormatConverter_CreateInstance(REFIID riid, void** ppv); +extern HRESULT ImagingFactory_CreateInstance(REFIID riid, void** ppv); +extern HRESULT BmpDecoder_CreateInstance(REFIID riid, void** ppv); +extern HRESULT PngDecoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT PngEncoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT BmpEncoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT DibDecoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT GifDecoder_CreateInstance(REFIID riid, void** ppv); +extern HRESULT GifEncoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT IcoDecoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT JpegDecoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT JpegEncoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT TiffDecoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT TiffEncoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT TgaDecoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT DdsDecoder_CreateInstance(REFIID iid, void** ppv); +extern HRESULT DdsEncoder_CreateInstance(REFIID iid, void** ppv); extern HRESULT BitmapImpl_Create(UINT uiWidth, UINT uiHeight, UINT stride, UINT datasize, void *view, UINT offset, REFWICPixelFormatGUID pixelFormat, WICBitmapCreateCacheOption option, - IWICBitmap **ppIBitmap) DECLSPEC_HIDDEN; -extern HRESULT BitmapScaler_Create(IWICBitmapScaler **scaler) DECLSPEC_HIDDEN; -extern HRESULT FlipRotator_Create(IWICBitmapFlipRotator **fliprotator) DECLSPEC_HIDDEN; -extern HRESULT PaletteImpl_Create(IWICPalette **palette) DECLSPEC_HIDDEN; -extern HRESULT StreamImpl_Create(IWICStream **stream) DECLSPEC_HIDDEN; -extern HRESULT ColorContext_Create(IWICColorContext **context) DECLSPEC_HIDDEN; -extern HRESULT ColorTransform_Create(IWICColorTransform **transform) DECLSPEC_HIDDEN; -extern HRESULT BitmapClipper_Create(IWICBitmapClipper **clipper) DECLSPEC_HIDDEN; + IWICBitmap **ppIBitmap); +extern HRESULT BitmapScaler_Create(IWICBitmapScaler **scaler); +extern HRESULT FlipRotator_Create(IWICBitmapFlipRotator **fliprotator); +extern HRESULT PaletteImpl_Create(IWICPalette **palette); +extern HRESULT StreamImpl_Create(IWICStream **stream); +extern HRESULT ColorContext_Create(IWICColorContext **context); +extern HRESULT ColorTransform_Create(IWICColorTransform **transform); +extern HRESULT BitmapClipper_Create(IWICBitmapClipper **clipper); extern HRESULT copy_pixels(UINT bpp, const BYTE *srcbuffer, UINT srcwidth, UINT srcheight, INT srcstride, - const WICRect *rc, UINT dststride, UINT dstbuffersize, BYTE *dstbuffer) DECLSPEC_HIDDEN; + const WICRect *rc, UINT dststride, UINT dstbuffersize, BYTE *dstbuffer); extern HRESULT configure_write_source(IWICBitmapFrameEncode *iface, IWICBitmapSource *source, const WICRect *prc, const WICPixelFormatGUID *format, - INT width, INT height, double xres, double yres) DECLSPEC_HIDDEN; + INT width, INT height, double xres, double yres); extern HRESULT write_source(IWICBitmapFrameEncode *iface, IWICBitmapSource *source, const WICRect *prc, - const WICPixelFormatGUID *format, UINT bpp, - INT width, INT height) DECLSPEC_HIDDEN; + const WICPixelFormatGUID *format, UINT bpp, BOOL need_palette, + INT width, INT height); -extern void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride) DECLSPEC_HIDDEN; -extern void convert_rgba_to_bgra(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride) DECLSPEC_HIDDEN; +extern void reverse_bgr8(UINT bytesperpixel, LPBYTE bits, UINT width, UINT height, INT stride); -extern HRESULT get_pixelformat_bpp(const GUID *pixelformat, UINT *bpp) DECLSPEC_HIDDEN; +extern HRESULT get_pixelformat_bpp(const GUID *pixelformat, UINT *bpp); extern HRESULT CreatePropertyBag2(const PROPBAG2 *options, UINT count, - IPropertyBag2 **property) DECLSPEC_HIDDEN; + IPropertyBag2 **property); -extern HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo) DECLSPEC_HIDDEN; -extern void ReleaseComponentInfos(void) DECLSPEC_HIDDEN; -extern HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown) DECLSPEC_HIDDEN; -extern HRESULT get_decoder_info(REFCLSID clsid, IWICBitmapDecoderInfo **info) DECLSPEC_HIDDEN; +extern HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo); +extern void ReleaseComponentInfos(void); +extern HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown); +extern HRESULT get_decoder_info(REFCLSID clsid, IWICBitmapDecoderInfo **info); typedef struct BmpDecoder BmpDecoder; -extern HRESULT IcoDibDecoder_CreateInstance(BmpDecoder **ppDecoder) DECLSPEC_HIDDEN; -extern void BmpDecoder_GetWICDecoder(BmpDecoder *This, IWICBitmapDecoder **ppDecoder) DECLSPEC_HIDDEN; -extern void BmpDecoder_FindIconMask(BmpDecoder *This, ULONG *mask_offset, int *topdown) DECLSPEC_HIDDEN; +extern HRESULT IcoDibDecoder_CreateInstance(BmpDecoder **ppDecoder); +extern void BmpDecoder_GetWICDecoder(BmpDecoder *This, IWICBitmapDecoder **ppDecoder); +extern void BmpDecoder_FindIconMask(BmpDecoder *This, ULONG *mask_offset, int *topdown); typedef struct _MetadataItem { @@ -221,30 +240,23 @@ typedef struct _MetadataHandlerVtbl ULARGE_INTEGER *size); } MetadataHandlerVtbl; -extern HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, REFIID iid, void** ppv) DECLSPEC_HIDDEN; +extern HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, REFIID iid, void** ppv); -extern HRESULT UnknownMetadataReader_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT IfdMetadataReader_CreateInstance(REFIID iid, void **ppv) DECLSPEC_HIDDEN; -extern HRESULT PngChrmReader_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT PngGamaReader_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT PngTextReader_CreateInstance(REFIID iid, void** ppv) DECLSPEC_HIDDEN; -extern HRESULT LSDReader_CreateInstance(REFIID iid, void **ppv) DECLSPEC_HIDDEN; -extern HRESULT IMDReader_CreateInstance(REFIID iid, void **ppv) DECLSPEC_HIDDEN; -extern HRESULT GCEReader_CreateInstance(REFIID iid, void **ppv) DECLSPEC_HIDDEN; -extern HRESULT APEReader_CreateInstance(REFIID iid, void **ppv) DECLSPEC_HIDDEN; -extern HRESULT GifCommentReader_CreateInstance(REFIID iid, void **ppv) DECLSPEC_HIDDEN; -extern HRESULT MetadataQueryReader_CreateInstance(IWICMetadataBlockReader *, const WCHAR *, IWICMetadataQueryReader **) DECLSPEC_HIDDEN; -extern HRESULT stream_initialize_from_filehandle(IWICStream *iface, HANDLE hfile) DECLSPEC_HIDDEN; - -static inline WCHAR *heap_strdupW(const WCHAR *src) -{ - WCHAR *dst; - SIZE_T len; - if (!src) return NULL; - len = (strlenW(src) + 1) * sizeof(WCHAR); - if ((dst = HeapAlloc(GetProcessHeap(), 0, len))) memcpy(dst, src, len); - return dst; -} +extern HRESULT UnknownMetadataReader_CreateInstance(REFIID iid, void** ppv); +extern HRESULT IfdMetadataReader_CreateInstance(REFIID iid, void **ppv); +extern HRESULT PngChrmReader_CreateInstance(REFIID iid, void** ppv); +extern HRESULT PngGamaReader_CreateInstance(REFIID iid, void** ppv); +extern HRESULT PngHistReader_CreateInstance(REFIID iid, void** ppv); +extern HRESULT PngTextReader_CreateInstance(REFIID iid, void** ppv); +extern HRESULT PngTimeReader_CreateInstance(REFIID iid, void** ppv); +extern HRESULT LSDReader_CreateInstance(REFIID iid, void **ppv); +extern HRESULT IMDReader_CreateInstance(REFIID iid, void **ppv); +extern HRESULT GCEReader_CreateInstance(REFIID iid, void **ppv); +extern HRESULT APEReader_CreateInstance(REFIID iid, void **ppv); +extern HRESULT GifCommentReader_CreateInstance(REFIID iid, void **ppv); +extern HRESULT MetadataQueryReader_CreateInstance(IWICMetadataBlockReader *, const WCHAR *, IWICMetadataQueryReader **); +extern HRESULT MetadataQueryWriter_CreateInstance(IWICMetadataBlockWriter *, const WCHAR *, IWICMetadataQueryWriter **); +extern HRESULT stream_initialize_from_filehandle(IWICStream *iface, HANDLE hfile); static inline const char *debug_wic_rect(const WICRect *rect) { @@ -252,4 +264,165 @@ static inline const char *debug_wic_rect(const WICRect *rect) return wine_dbg_sprintf("(%u,%u)-(%u,%u)", rect->X, rect->Y, rect->Width, rect->Height); } +extern HMODULE windowscodecs_module; + +HRESULT read_png_chunk(IStream *stream, BYTE *type, BYTE **data, ULONG *data_size); + +struct decoder_funcs; + +struct decoder_info +{ + GUID container_format; + GUID block_format; + CLSID clsid; +}; + +#define DECODER_FLAGS_CAPABILITY_MASK 0x1f +#define DECODER_FLAGS_UNSUPPORTED_COLOR_CONTEXT 0x80000000 + +struct decoder_stat +{ + DWORD flags; + UINT frame_count; +}; + +struct decoder_frame +{ + CLSID pixel_format; + UINT width, height; + UINT bpp; + DOUBLE dpix, dpiy; + DWORD num_color_contexts; + DWORD num_colors; + WICColor palette[256]; +}; + +#define DECODER_BLOCK_OPTION_MASK 0x0001000F +#define DECODER_BLOCK_FULL_STREAM 0x80000000 +#define DECODER_BLOCK_READER_CLSID 0x40000000 +struct decoder_block +{ + ULONGLONG offset; + ULONGLONG length; + DWORD options; + GUID reader_clsid; +}; + +struct decoder +{ + const struct decoder_funcs *vtable; +}; + +struct decoder_funcs +{ + HRESULT (CDECL *initialize)(struct decoder* This, IStream *stream, struct decoder_stat *st); + HRESULT (CDECL *get_frame_info)(struct decoder* This, UINT frame, struct decoder_frame *info); + HRESULT (CDECL *copy_pixels)(struct decoder* This, UINT frame, const WICRect *prc, + UINT stride, UINT buffersize, BYTE *buffer); + HRESULT (CDECL *get_metadata_blocks)(struct decoder* This, UINT frame, UINT *count, + struct decoder_block **blocks); + HRESULT (CDECL *get_color_context)(struct decoder* This, UINT frame, UINT num, + BYTE **data, DWORD *datasize); + void (CDECL *destroy)(struct decoder* This); +}; + +HRESULT CDECL stream_getsize(IStream *stream, ULONGLONG *size); +HRESULT CDECL stream_read(IStream *stream, void *buffer, ULONG read, ULONG *bytes_read); +HRESULT CDECL stream_seek(IStream *stream, LONGLONG ofs, DWORD origin, ULONGLONG *new_position); +HRESULT CDECL stream_write(IStream *stream, const void *buffer, ULONG write, ULONG *bytes_written); + +HRESULT CDECL decoder_create(const CLSID *decoder_clsid, struct decoder_info *info, struct decoder **result); +HRESULT CDECL decoder_initialize(struct decoder *This, IStream *stream, struct decoder_stat *st); +HRESULT CDECL decoder_get_frame_info(struct decoder* This, UINT frame, struct decoder_frame *info); +HRESULT CDECL decoder_copy_pixels(struct decoder* This, UINT frame, const WICRect *prc, + UINT stride, UINT buffersize, BYTE *buffer); +HRESULT CDECL decoder_get_metadata_blocks(struct decoder* This, UINT frame, UINT *count, + struct decoder_block **blocks); +HRESULT CDECL decoder_get_color_context(struct decoder* This, UINT frame, UINT num, + BYTE **data, DWORD *datasize); +void CDECL decoder_destroy(struct decoder *This); + +struct encoder_funcs; + +/* sync with encoder_option_properties */ +enum encoder_option +{ + ENCODER_OPTION_INTERLACE, + ENCODER_OPTION_FILTER, + ENCODER_OPTION_COMPRESSION_METHOD, + ENCODER_OPTION_COMPRESSION_QUALITY, + ENCODER_OPTION_IMAGE_QUALITY, + ENCODER_OPTION_BITMAP_TRANSFORM, + ENCODER_OPTION_LUMINANCE, + ENCODER_OPTION_CHROMINANCE, + ENCODER_OPTION_YCRCB_SUBSAMPLING, + ENCODER_OPTION_SUPPRESS_APP0, + ENCODER_OPTION_END +}; + +#define ENCODER_FLAGS_MULTI_FRAME 0x1 +#define ENCODER_FLAGS_ICNS_SIZE 0x2 +#define ENCODER_FLAGS_SUPPORTS_METADATA 0x4 + +struct encoder_info +{ + DWORD flags; + GUID container_format; + CLSID clsid; + DWORD encoder_options[7]; +}; + +struct encoder_frame +{ + GUID pixel_format; + UINT width, height; + UINT bpp; + BOOL indexed; + DOUBLE dpix, dpiy; + UINT num_colors; + WICColor palette[256]; + /* encoder options */ + BOOL interlace; + DWORD filter; +}; + +struct encoder +{ + const struct encoder_funcs *vtable; +}; + +struct encoder_funcs +{ + HRESULT (CDECL *initialize)(struct encoder* This, IStream *stream); + HRESULT (CDECL *get_supported_format)(struct encoder* This, GUID *pixel_format, DWORD *bpp, BOOL *indexed); + HRESULT (CDECL *create_frame)(struct encoder* This, const struct encoder_frame *frame); + HRESULT (CDECL *write_lines)(struct encoder* This, BYTE *data, DWORD line_count, DWORD stride); + HRESULT (CDECL *commit_frame)(struct encoder* This); + HRESULT (CDECL *commit_file)(struct encoder* This); + void (CDECL *destroy)(struct encoder* This); +}; + +HRESULT CDECL encoder_initialize(struct encoder* This, IStream *stream); +HRESULT CDECL encoder_get_supported_format(struct encoder* This, GUID *pixel_format, DWORD *bpp, BOOL *indexed); +HRESULT CDECL encoder_create_frame(struct encoder* This, const struct encoder_frame *frame); +HRESULT CDECL encoder_write_lines(struct encoder* This, BYTE *data, DWORD line_count, DWORD stride); +HRESULT CDECL encoder_commit_frame(struct encoder* This); +HRESULT CDECL encoder_commit_file(struct encoder* This); +void CDECL encoder_destroy(struct encoder* This); + +HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **result); +HRESULT CDECL tiff_decoder_create(struct decoder_info *info, struct decoder **result); +HRESULT CDECL jpeg_decoder_create(struct decoder_info *info, struct decoder **result); + +HRESULT CDECL png_encoder_create(struct encoder_info *info, struct encoder **result); +HRESULT CDECL tiff_encoder_create(struct encoder_info *info, struct encoder **result); +HRESULT CDECL jpeg_encoder_create(struct encoder_info *info, struct encoder **result); +HRESULT CDECL icns_encoder_create(struct encoder_info *info, struct encoder **result); + +extern HRESULT CommonDecoder_CreateInstance(struct decoder *decoder, + const struct decoder_info *decoder_info, REFIID iid, void** ppv); + +extern HRESULT CommonEncoder_CreateInstance(struct encoder *encoder, + const struct encoder_info *encoder_info, REFIID iid, void** ppv); + #endif /* WINCODECS_PRIVATE_H */ diff --git a/dll/win32/windowscodecs/windowscodecs_wincodec.idl b/dll/win32/windowscodecs/windowscodecs_wincodec.idl index fec63d04e13..f47684890c1 100644 --- a/dll/win32/windowscodecs/windowscodecs_wincodec.idl +++ b/dll/win32/windowscodecs/windowscodecs_wincodec.idl @@ -25,7 +25,7 @@ threading(both), uuid(00000301-a8f2-4877-ba0a-fd2b6645fb94) /* IWICFormatConverter */ ] -coclass PSFactoryBuffer { interface IFactoryBuffer; } +coclass PSFactoryBuffer { interface IPSFactoryBuffer; } [ helpstring("WIC Imaging Factory"), @@ -119,11 +119,18 @@ coclass WICTiffDecoder { interface IWICBitmapDecoder; } coclass WICTiffEncoder { interface IWICBitmapEncoder; } [ - helpstring("WIC ICNS Encoder"), + helpstring("WIC DDS Decoder"), threading(both), - uuid(312fb6f1-b767-409d-8a6d-0fc154d4f05c) + uuid(9053699f-a341-429d-9e90-ee437cf80c73) ] -coclass WICIcnsEncoder { interface IWICBitmapEncoder; } +coclass WICDdsDecoder { interface IWICBitmapDecoder; } + +[ + helpstring("WIC DDS Encoder"), + threading(both), + uuid(a61dde94-66ce-4ac1-881b-71680588895e) +] +coclass WICDdsEncoder { interface IWICBitmapEncoder; } [ helpstring("WIC Default Format Converter"), @@ -151,7 +158,7 @@ coclass WICUnknownMetadataReader { interface IWICMetadataReader; } threading(both), uuid(8f914656-9d0a-4eb2-9019-0bf96d8a9ee6) ] -coclass WICIfdMetadataReader { interface IWICIfdMetadataReader; } +coclass WICIfdMetadataReader { interface IWICMetadataReader; } [ helpstring("WIC Png cHRM Metadata Reader"), @@ -167,13 +174,28 @@ coclass WICPngChrmMetadataReader { interface IWICMetadataReader; } ] coclass WICPngGamaMetadataReader { interface IWICMetadataReader; } +[ + helpstring("WIC Png hIST Metadata Reader"), + threading(both), + uuid(877a0bb7-a313-4491-87b5-2e6d0594f520) +] +coclass WICPngHistMetadataReader { interface IWICMetadataReader; } + [ helpstring("WIC Png tEXt Metadata Reader"), threading(both), uuid(4b59afcc-b8c3-408a-b670-89e5fab6fda7) + ] coclass WICPngTextMetadataReader { interface IWICMetadataReader; } +[ + helpstring("WIC Png tIME Metadata Reader"), + threading(both), + uuid(d94edf02-efe5-4f0d-85c8-f5a68b3000b1) +] +coclass WICPngTimeMetadataReader { interface IWICMetadataReader; } + [ helpstring("WIC LSD Metadata Reader"), threading(both), diff --git a/dll/win32/windowscodecsext/main.c b/dll/win32/windowscodecsext/main.c index 8835a313e83..3f2be235f18 100644 --- a/dll/win32/windowscodecsext/main.c +++ b/dll/win32/windowscodecsext/main.c @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" - #include #define COBJMACROS @@ -32,22 +30,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); -BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) -{ - TRACE("(%p, %u, %p)\n", instance, reason, reserved); - - switch (reason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(instance); - break; - } - - return TRUE; -} - /****************************************************************** * DllGetClassObject */ diff --git a/media/doc/WINESYNC.txt b/media/doc/WINESYNC.txt index e66dd40c987..203f7ae3333 100644 --- a/media/doc/WINESYNC.txt +++ b/media/doc/WINESYNC.txt @@ -206,8 +206,8 @@ dll/win32/version # Synced to WineStaging-4.18 dll/win32/vssapi # Synced to WineStaging-4.18 dll/win32/wbemdisp # Synced to WineStaging-4.18 dll/win32/wbemprox # Synced to WineStaging-4.18 -dll/win32/windowscodecs # Synced to WineStaging-4.18 -dll/win32/windowscodecsext # Synced to WineStaging-2.9 +dll/win32/windowscodecs # Synced to Wine-10.0 +dll/win32/windowscodecsext # Synced to Wine-10.0 dll/win32/winemp3.acm # Synced to WineStaging-4.18 dll/win32/wing32 # Synced to WineStaging-3.3 dll/win32/winhttp # Synced to WineStaging-4.18 diff --git a/modules/rostests/winetests/windowscodecs/CMakeLists.txt b/modules/rostests/winetests/windowscodecs/CMakeLists.txt index 418181b1b23..d1aa7bfba16 100644 --- a/modules/rostests/winetests/windowscodecs/CMakeLists.txt +++ b/modules/rostests/winetests/windowscodecs/CMakeLists.txt @@ -3,10 +3,13 @@ add_definitions( -DUSE_WINE_TODOS -DWINETEST_USE_DBGSTR_LONGLONG) +remove_definitions(-D__ROS_LONG64__) + list(APPEND SOURCE bitmap.c bmpformat.c converter.c + ddsformat.c gifformat.c icoformat.c info.c @@ -16,7 +19,8 @@ list(APPEND SOURCE pngformat.c propertybag.c stream.c - tiffformat.c) + tiffformat.c + wmpformat.c) list(APPEND PCH_SKIP_SOURCE guid.c @@ -33,5 +37,7 @@ if(MSVC) add_importlibs(windowscodecs_winetest ntdll) endif() +target_link_libraries(windowscodecs_winetest uuid) + add_pch(windowscodecs_winetest precomp.h "${PCH_SKIP_SOURCE}") add_rostests_file(TARGET windowscodecs_winetest) diff --git a/modules/rostests/winetests/windowscodecs/bitmap.c b/modules/rostests/winetests/windowscodecs/bitmap.c index 6cb0c5665c2..78725fed646 100644 --- a/modules/rostests/winetests/windowscodecs/bitmap.c +++ b/modules/rostests/winetests/windowscodecs/bitmap.c @@ -31,13 +31,24 @@ #include "wine/test.h" #include "initguid.h" -DEFINE_GUID(IID_IMILUnknown,0x0ccd7824,0xdc16,0x4d09,0xbc,0xa8,0x6b,0x09,0xc4,0xef,0x55,0x35); +DEFINE_GUID(IID_CMetaBitmapRenderTarget, 0x0ccd7824,0xdc16,0x4d09,0xbc,0xa8,0x6b,0x09,0xc4,0xef,0x55,0x35); + +#ifndef IID_IMILBitmap +#include DEFINE_GUID(IID_IMILBitmap,0xb1784d3f,0x8115,0x4763,0x13,0xaa,0x32,0xed,0xdb,0x68,0x29,0x4a); DEFINE_GUID(IID_IMILBitmapSource,0x7543696a,0xbc8d,0x46b0,0x5f,0x81,0x8d,0x95,0x72,0x89,0x72,0xbe); DEFINE_GUID(IID_IMILBitmapLock,0xa67b2b53,0x8fa1,0x4155,0x8f,0x64,0x0c,0x24,0x7a,0x8f,0x84,0xcd); DEFINE_GUID(IID_IMILBitmapScaler,0xa767b0f0,0x1c8c,0x4aef,0x56,0x8f,0xad,0xf9,0x6d,0xcf,0xd5,0xcb); DEFINE_GUID(IID_IMILFormatConverter,0x7e2a746f,0x25c5,0x4851,0xb3,0xaf,0x44,0x3b,0x79,0x63,0x9e,0xc0); DEFINE_GUID(IID_IMILPalette,0xca8e206f,0xf22c,0x4af7,0x6f,0xba,0x7b,0xed,0x5e,0xb1,0xc9,0x2f); +#else +extern IID IID_IMILBitmap; +extern IID IID_IMILBitmapSource; +extern IID IID_IMILBitmapLock; +extern IID IID_IMILBitmapScaler; +extern IID IID_IMILFormatConverter; +extern IID IID_IMILPalette; +#endif #undef INTERFACE #define INTERFACE IMILBitmapSource @@ -206,8 +217,8 @@ static HBITMAP create_dib(int width, int height, int bpp, LOGPALETTE *pal, const ok(hdib != 0, "CreateDIBSection(%dx%d,%d bpp) failed\n", width, height, bpp); GetObjectW(hdib, sizeof(bm), &bm); - ok(bm.bmWidth == width, "expected %d, got %d\n", width, bm.bmWidth); - ok(bm.bmHeight == height, "expected %d, got %d\n", height, bm.bmHeight); + ok(bm.bmWidth == width, "expected %d, got %ld\n", width, bm.bmWidth); + ok(bm.bmHeight == height, "expected %d, got %ld\n", height, bm.bmHeight); ok(bm.bmPlanes == 1, "expected 1, got %d\n", bm.bmPlanes); ok(bm.bmBitsPixel == bpp, "expected %d, got %d\n", bpp, bm.bmBitsPixel); @@ -240,32 +251,32 @@ static void test_createbitmap(void) hr = IWICImagingFactory_CreateBitmap(factory, 3, 3, &GUID_WICPixelFormat24bppBGR, WICBitmapCacheOnLoad, &bitmap); - ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%lx\n", hr); if (FAILED(hr)) return; hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%lx\n", hr); /* Palette is unavailable until explicitly set */ hr = IWICBitmap_CopyPalette(bitmap, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "IWICBitmap_CopyPalette failed hr=%x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "IWICBitmap_CopyPalette failed hr=%lx\n", hr); hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray256, FALSE); - ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr); + ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%lx\n", hr); hr = IWICBitmap_SetPalette(bitmap, palette); - ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%lx\n", hr); hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray4, FALSE); - ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr); + ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%lx\n", hr); hr = IWICBitmap_CopyPalette(bitmap, palette); - ok(hr == S_OK, "IWICBitmap_CopyPalette failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_CopyPalette failed hr=%lx\n", hr); hr = IWICPalette_GetType(palette, &palettetype); - ok(hr == S_OK, "IWICPalette_GetType failed hr=%x\n", hr); + ok(hr == S_OK, "IWICPalette_GetType failed hr=%lx\n", hr); ok(palettetype == WICBitmapPaletteTypeFixedGray256, "expected WICBitmapPaletteTypeFixedGray256, got %x\n", palettetype); @@ -273,7 +284,7 @@ static void test_createbitmap(void) /* pixel data is initially zeroed */ hr = IWICBitmap_CopyPixels(bitmap, NULL, 9, 27, returned_data); - ok(hr == S_OK, "IWICBitmap_CopyPixels failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_CopyPixels failed hr=%lx\n", hr); for (i=0; i<27; i++) ok(returned_data[i] == 0, "returned_data[%i] == %i\n", i, returned_data[i]); @@ -283,36 +294,36 @@ static void test_createbitmap(void) rc.Width = 4; rc.Height = 3; hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock); - ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%lx\n", hr); if (SUCCEEDED(hr)) IWICBitmapLock_Release(lock); rc.Width = 3; rc.Height = 4; hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock); - ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%lx\n", hr); if (SUCCEEDED(hr)) IWICBitmapLock_Release(lock); rc.Height = 3; rc.X = 4; hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock); - ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%lx\n", hr); if (SUCCEEDED(hr)) IWICBitmapLock_Release(lock); rc.X = 0; rc.Y = 4; hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock); - ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%lx\n", hr); if (SUCCEEDED(hr)) IWICBitmapLock_Release(lock); /* NULL lock rect */ hr = IWICBitmap_Lock(bitmap, NULL, WICBitmapLockRead, &lock); - ok(hr == S_OK || broken(hr == E_INVALIDARG) /* winxp */, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == S_OK || broken(hr == E_INVALIDARG) /* winxp */, "IWICBitmap_Lock failed hr=%lx\n", hr); if (SUCCEEDED(hr)) { /* entire bitmap is locked */ hr = IWICBitmapLock_GetSize(lock, &width, &height); - ok(hr == S_OK, "IWICBitmapLock_GetSize failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetSize failed hr=%lx\n", hr); ok(width == 3, "got %d, expected 3\n", width); ok(height == 3, "got %d, expected 3\n", height); @@ -324,38 +335,38 @@ static void test_createbitmap(void) /* lock with a valid rect */ rc.Y = 0; hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock); - ok(hr == S_OK, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_Lock failed hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapLock_GetStride(lock, &lock_buffer_stride); - ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%lx\n", hr); /* stride is divisible by 4 */ ok(lock_buffer_stride == 12, "got %i, expected 12\n", lock_buffer_stride); hr = IWICBitmapLock_GetDataPointer(lock, &lock_buffer_size, &lock_buffer); - ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%lx\n", hr); /* buffer size does not include padding from the last row */ ok(lock_buffer_size == 33, "got %i, expected 33\n", lock_buffer_size); ok(lock_buffer != NULL, "got NULL data pointer\n"); base_lock_buffer = lock_buffer; hr = IWICBitmapLock_GetPixelFormat(lock, &pixelformat); - ok(hr == S_OK, "IWICBitmapLock_GetPixelFormat failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetPixelFormat failed hr=%lx\n", hr); ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n"); hr = IWICBitmapLock_GetSize(lock, &width, &height); - ok(hr == S_OK, "IWICBitmapLock_GetSize failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetSize failed hr=%lx\n", hr); ok(width == 3, "got %d, expected 3\n", width); ok(height == 3, "got %d, expected 3\n", height); /* We can have multiple simultaneous read locks */ hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock2); - ok(hr == S_OK, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_Lock failed hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapLock_GetDataPointer(lock2, &lock_buffer_size, &lock_buffer); - ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%lx\n", hr); ok(lock_buffer_size == 33, "got %i, expected 33\n", lock_buffer_size); ok(lock_buffer == base_lock_buffer, "got %p, expected %p\n", lock_buffer, base_lock_buffer); @@ -366,7 +377,7 @@ static void test_createbitmap(void) { /* But not a read and a write lock */ hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockWrite, &lock2); - ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%lx\n", hr); } /* But we don't need a write lock to write */ @@ -381,7 +392,7 @@ static void test_createbitmap(void) /* test that the data we wrote is returned by CopyPixels */ hr = IWICBitmap_CopyPixels(bitmap, NULL, 9, 27, returned_data); - ok(hr == S_OK, "IWICBitmap_CopyPixels failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_CopyPixels failed hr=%lx\n", hr); for (i=0; i<27; i++) ok(returned_data[i] == bitmap_data[i], "returned_data[%i] == %i\n", i, returned_data[i]); @@ -392,7 +403,7 @@ static void test_createbitmap(void) rc.Width = 1; rc.Height = 2; hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockWrite, &lock); - ok(hr == S_OK, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_Lock failed hr=%lx\n", hr); if (SUCCEEDED(hr)) { @@ -400,27 +411,27 @@ static void test_createbitmap(void) { /* Can't lock again while locked for writing */ hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockWrite, &lock2); - ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%lx\n", hr); hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock2); - ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%lx\n", hr); } hr = IWICBitmapLock_GetStride(lock, &lock_buffer_stride); - ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%lx\n", hr); ok(lock_buffer_stride == 12, "got %i, expected 12\n", lock_buffer_stride); hr = IWICBitmapLock_GetDataPointer(lock, &lock_buffer_size, &lock_buffer); - ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%lx\n", hr); ok(lock_buffer_size == 15, "got %i, expected 15\n", lock_buffer_size); ok(lock_buffer == base_lock_buffer+6, "got %p, expected %p+6\n", lock_buffer, base_lock_buffer); hr = IWICBitmapLock_GetPixelFormat(lock, &pixelformat); - ok(hr == S_OK, "IWICBitmapLock_GetPixelFormat failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetPixelFormat failed hr=%lx\n", hr); ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n"); hr = IWICBitmapLock_GetSize(lock, &width, &height); - ok(hr == S_OK, "IWICBitmapLock_GetSize failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetSize failed hr=%lx\n", hr); ok(width == 1, "got %d, expected 1\n", width); ok(height == 2, "got %d, expected 2\n", height); @@ -428,24 +439,24 @@ static void test_createbitmap(void) } hr = IWICBitmap_GetPixelFormat(bitmap, &pixelformat); - ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%lx\n", hr); ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n"); hr = IWICBitmap_GetResolution(bitmap, &dpix, &dpiy); - ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%lx\n", hr); ok(dpix == 0.0, "got %f, expected 0.0\n", dpix); ok(dpiy == 0.0, "got %f, expected 0.0\n", dpiy); hr = IWICBitmap_SetResolution(bitmap, 12.0, 34.0); - ok(hr == S_OK, "IWICBitmap_SetResolution failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_SetResolution failed hr=%lx\n", hr); hr = IWICBitmap_GetResolution(bitmap, &dpix, &dpiy); - ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%lx\n", hr); ok(dpix == 12.0, "got %f, expected 12.0\n", dpix); ok(dpiy == 34.0, "got %f, expected 34.0\n", dpiy); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "IWICBitmap_GetSize failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetSize failed hr=%lx\n", hr); ok(width == 3, "got %d, expected 3\n", width); ok(height == 3, "got %d, expected 3\n", height); @@ -476,19 +487,19 @@ static void test_createbitmapfromsource(void) hr = IWICImagingFactory_CreateBitmap(factory, 3, 3, &GUID_WICPixelFormat24bppBGR, WICBitmapCacheOnLoad, &bitmap); - ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%lx\n", hr); if (FAILED(hr)) return; hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%lx\n", hr); hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray256, FALSE); - ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr); + ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%lx\n", hr); hr = IWICBitmap_SetPalette(bitmap, palette); - ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%lx\n", hr); IWICPalette_Release(palette); @@ -496,15 +507,15 @@ static void test_createbitmapfromsource(void) rc.Width = 3; rc.Height = 3; hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockWrite, &lock); - ok(hr == S_OK, "IWICBitmap_Lock failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_Lock failed hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapLock_GetStride(lock, &lock_buffer_stride); - ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%lx\n", hr); ok(lock_buffer_stride == 12, "got %i, expected 12\n", lock_buffer_stride); hr = IWICBitmapLock_GetDataPointer(lock, &lock_buffer_size, &lock_buffer); - ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%lx\n", hr); ok(lock_buffer_size == 33, "got %i, expected 33\n", lock_buffer_size); ok(lock_buffer != NULL, "got NULL data pointer\n"); @@ -515,55 +526,55 @@ static void test_createbitmapfromsource(void) } hr = IWICBitmap_SetResolution(bitmap, 12.0, 34.0); - ok(hr == S_OK, "IWICBitmap_SetResolution failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_SetResolution failed hr=%lx\n", hr); /* WICBitmapNoCache */ hr = IWICImagingFactory_CreateBitmapFromSource(factory, (IWICBitmapSource *)bitmap, WICBitmapNoCache, &bitmap2); - ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromSource failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromSource failed hr=%lx\n", hr); ok(bitmap2 == bitmap, "Unexpected bitmap instance.\n"); IWICBitmap_Release(bitmap2); bitmap2 = (void *)0xdeadbeef; hr = IWICImagingFactory_CreateBitmapFromSource(factory, &bitmapsource, WICBitmapNoCache, &bitmap2); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); ok(bitmap2 == (void *)0xdeadbeef, "Unexpected pointer %p.\n", bitmap2); hr = IWICImagingFactory_CreateBitmapFromSource(factory, (IWICBitmapSource*)bitmap, WICBitmapCacheOnLoad, &bitmap2); - ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromSource failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromSource failed hr=%lx\n", hr); IWICBitmap_Release(bitmap); if (FAILED(hr)) return; hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%lx\n", hr); /* palette isn't copied for non-indexed formats? */ hr = IWICBitmap_CopyPalette(bitmap2, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "IWICBitmap_CopyPalette failed hr=%x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "IWICBitmap_CopyPalette failed hr=%lx\n", hr); IWICPalette_Release(palette); hr = IWICBitmap_CopyPixels(bitmap2, NULL, 9, 27, returned_data); - ok(hr == S_OK, "IWICBitmap_CopyPixels failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_CopyPixels failed hr=%lx\n", hr); for (i=0; i<27; i++) ok(returned_data[i] == bitmap_data[i], "returned_data[%i] == %i\n", i, returned_data[i]); hr = IWICBitmap_GetPixelFormat(bitmap2, &pixelformat); - ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%lx\n", hr); ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n"); hr = IWICBitmap_GetResolution(bitmap2, &dpix, &dpiy); - ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%lx\n", hr); ok(dpix == 12.0, "got %f, expected 12.0\n", dpix); ok(dpiy == 34.0, "got %f, expected 34.0\n", dpiy); hr = IWICBitmap_GetSize(bitmap2, &width, &height); - ok(hr == S_OK, "IWICBitmap_GetSize failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetSize failed hr=%lx\n", hr); ok(width == 3, "got %d, expected 3\n", width); ok(height == 3, "got %d, expected 3\n", height); @@ -572,86 +583,86 @@ static void test_createbitmapfromsource(void) /* Ensure palette is copied for indexed formats */ hr = IWICImagingFactory_CreateBitmap(factory, 3, 3, &GUID_WICPixelFormat4bppIndexed, WICBitmapCacheOnLoad, &bitmap); - ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%lx\n", hr); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%lx\n", hr); hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray256, FALSE); - ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr); + ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%lx\n", hr); hr = IWICBitmap_SetPalette(bitmap, palette); - ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%lx\n", hr); IWICPalette_Release(palette); hr = IWICImagingFactory_CreateBitmapFromSource(factory, (IWICBitmapSource*)bitmap, WICBitmapCacheOnLoad, &bitmap2); - ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromSource failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromSource failed hr=%lx\n", hr); IWICBitmap_Release(bitmap); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%lx\n", hr); hr = IWICBitmap_CopyPalette(bitmap2, palette); - ok(hr == S_OK, "IWICBitmap_CopyPalette failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_CopyPalette failed hr=%lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "IWICPalette_GetColorCount failed hr=%x\n", hr); + ok(hr == S_OK, "IWICPalette_GetColorCount failed hr=%lx\n", hr); ok(count == 256, "unexpected count %d\n", count); hr = IWICPalette_GetType(palette, &palette_type); - ok(hr == S_OK, "IWICPalette_GetType failed hr=%x\n", hr); + ok(hr == S_OK, "IWICPalette_GetType failed hr=%lx\n", hr); ok(palette_type == WICBitmapPaletteTypeFixedGray256, "unexpected palette type %d\n", palette_type); IWICPalette_Release(palette); hr = IWICBitmap_GetPixelFormat(bitmap2, &pixelformat); - ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%lx\n", hr); ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat4bppIndexed), "unexpected pixel format\n"); hr = IWICBitmap_GetSize(bitmap2, &width, &height); - ok(hr == S_OK, "IWICBitmap_GetSize failed hr=%x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetSize failed hr=%lx\n", hr); ok(width == 3, "got %d, expected 3\n", width); ok(height == 3, "got %d, expected 3\n", height); /* CreateBitmapFromSourceRect */ hr = IWICImagingFactory_CreateBitmapFromSourceRect(factory, (IWICBitmapSource *)bitmap2, 0, 0, 16, 32, &bitmap); - ok(hr == S_OK, "Failed to create a bitmap, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create a bitmap, hr %#lx.\n", hr); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "Failed to get bitmap size, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to get bitmap size, hr %#lx.\n", hr); ok(width == 3, "Unexpected width %u.\n", width); ok(height == 3, "Unexpected height %u.\n", height); IWICBitmap_Release(bitmap); hr = IWICImagingFactory_CreateBitmapFromSourceRect(factory, (IWICBitmapSource *)bitmap2, 0, 0, 1, 1, &bitmap); - ok(hr == S_OK, "Failed to create a bitmap, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create a bitmap, hr %#lx.\n", hr); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "Failed to get bitmap size, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to get bitmap size, hr %#lx.\n", hr); ok(width == 1, "Unexpected width %u.\n", width); ok(height == 1, "Unexpected height %u.\n", height); IWICBitmap_Release(bitmap); hr = IWICImagingFactory_CreateBitmapFromSourceRect(factory, (IWICBitmapSource *)bitmap2, 2, 1, 16, 32, &bitmap); - ok(hr == S_OK, "Failed to create a bitmap, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create a bitmap, hr %#lx.\n", hr); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "Failed to get bitmap size, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to get bitmap size, hr %#lx.\n", hr); ok(width == 1, "Unexpected width %u.\n", width); ok(height == 2, "Unexpected height %u.\n", height); IWICBitmap_Release(bitmap); hr = IWICImagingFactory_CreateBitmapFromSourceRect(factory, (IWICBitmapSource *)bitmap2, 0, 0, 0, 2, &bitmap); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICImagingFactory_CreateBitmapFromSourceRect(factory, (IWICBitmapSource *)bitmap2, 0, 0, 2, 0, &bitmap); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICImagingFactory_CreateBitmapFromSourceRect(factory, (IWICBitmapSource *)bitmap2, 1, 3, 16, 32, &bitmap); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICImagingFactory_CreateBitmapFromSourceRect(factory, (IWICBitmapSource *)bitmap2, 3, 1, 16, 32, &bitmap); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); IWICBitmap_Release(bitmap2); } @@ -676,30 +687,30 @@ static void test_CreateBitmapFromMemory(void) hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR, 0, 0, NULL, &bitmap); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR, 0, sizeof(data3x3), data3x3, &bitmap); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR, 6, sizeof(data3x3), data3x3, &bitmap); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR, 12, sizeof(data3x3), data3x3, &bitmap); - ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "expected WINCODEC_ERR_INSUFFICIENTBUFFER, got %#x\n", hr); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "expected WINCODEC_ERR_INSUFFICIENTBUFFER, got %#lx\n", hr); hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR, 9, sizeof(data3x3) - 1, data3x3, &bitmap); - ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "expected WINCODEC_ERR_INSUFFICIENTBUFFER, got %#x\n", hr); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "expected WINCODEC_ERR_INSUFFICIENTBUFFER, got %#lx\n", hr); hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 3, &GUID_WICPixelFormat24bppBGR, 9, sizeof(data3x3), data3x3, &bitmap); - ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromMemory error %#x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromMemory error %#lx\n", hr); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetSize error %#lx\n", hr); ok(width == 3, "expected 3, got %u\n", width); ok(height == 3, "expected 3, got %u\n", height); @@ -707,7 +718,7 @@ static void test_CreateBitmapFromMemory(void) memset(data, 0, sizeof(data)); hr = IWICBitmap_CopyPixels(bitmap, NULL, 9, sizeof(data), data); - ok(hr == S_OK, "IWICBitmap_CopyPixels error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_CopyPixels error %#lx\n", hr); for (i = 0; i < sizeof(data); i++) ok(data[i] == orig_data3x3[i], "%u: expected %u, got %u\n", i, data[i], data3x3[i]); @@ -715,16 +726,16 @@ static void test_CreateBitmapFromMemory(void) hr = IWICImagingFactory_CreateBitmapFromMemory(factory, 3, 2, &GUID_WICPixelFormat24bppBGR, 13, sizeof(orig_data3x3), orig_data3x3, &bitmap); - ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromMemory error %#x\n", hr); + ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromMemory error %#lx\n", hr); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetSize error %#lx\n", hr); ok(width == 3, "expected 3, got %u\n", width); ok(height == 2, "expected 2, got %u\n", height); memset(data, 0, sizeof(data)); hr = IWICBitmap_CopyPixels(bitmap, NULL, 13, sizeof(data), data); - ok(hr == S_OK, "IWICBitmap_CopyPixels error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_CopyPixels error %#lx\n", hr); for (i = 0; i < sizeof(data); i++) ok(data[i] == data3x2[i], "%u: expected %u, got %u\n", i, data3x2[i], data[i]); @@ -753,16 +764,16 @@ static void test_CreateBitmapFromHICON(void) DeleteObject(info.hbmMask); hr = IWICImagingFactory_CreateBitmapFromHICON(factory, 0, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICImagingFactory_CreateBitmapFromHICON(factory, 0, &bitmap); - ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_CURSOR_HANDLE), "expected ERROR_INVALID_CURSOR_HANDLE, got %#x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_CURSOR_HANDLE), "expected ERROR_INVALID_CURSOR_HANDLE, got %#lx\n", hr); hr = IWICImagingFactory_CreateBitmapFromHICON(factory, icon, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICImagingFactory_CreateBitmapFromHICON(factory, icon, &bitmap); - ok(hr == S_OK, "CreateBitmapFromHICON error %#x\n", hr); + ok(hr == S_OK, "CreateBitmapFromHICON error %#lx\n", hr); DestroyIcon(icon); if (hr != S_OK) return; @@ -771,7 +782,7 @@ static void test_CreateBitmapFromHICON(void) "unexpected pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetSize error %#lx\n", hr); ok(width == 16, "expected 16, got %u\n", width); ok(height == 16, "expected 16, got %u\n", height); @@ -791,7 +802,7 @@ static void test_CreateBitmapFromHICON(void) DeleteObject(info.hbmMask); hr = IWICImagingFactory_CreateBitmapFromHICON(factory, icon, &bitmap); - ok(hr == S_OK, "CreateBitmapFromHICON error %#x\n", hr); + ok(hr == S_OK, "CreateBitmapFromHICON error %#lx\n", hr); DestroyIcon(icon); IWICBitmap_GetPixelFormat(bitmap, &format); @@ -799,7 +810,7 @@ static void test_CreateBitmapFromHICON(void) "unexpected pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetSize error %#lx\n", hr); ok(width == 16, "expected 16, got %u\n", width); ok(height == 16, "expected 16, got %u\n", height); @@ -830,26 +841,26 @@ static void test_CreateBitmapFromHBITMAP(void) ok(hbmp != 0, "failed to create bitmap\n"); hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, 0, 0, WICBitmapIgnoreAlpha, &bitmap); - ok(hr == WINCODEC_ERR_WIN32ERROR || hr == 0x88980003 /*XP*/, "expected WINCODEC_ERR_WIN32ERROR, got %#x\n", hr); + ok(hr == WINCODEC_ERR_WIN32ERROR || hr == 0x88980003 /*XP*/, "expected WINCODEC_ERR_WIN32ERROR, got %#lx\n", hr); hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, 0, WICBitmapIgnoreAlpha, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, 0, WICBitmapIgnoreAlpha, &bitmap); - ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr); + ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#lx\n", hr); IWICBitmap_GetPixelFormat(bitmap, &format); ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), "unexpected pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetSize error %#lx\n", hr); ok(width == 3, "expected 3, got %u\n", width); ok(height == 3, "expected 3, got %u\n", height); memset(data, 0, sizeof(data)); hr = IWICBitmap_CopyPixels(bitmap, NULL, 4, sizeof(data), data); - ok(hr == S_OK, "IWICBitmap_CopyPixels error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_CopyPixels error %#lx\n", hr); for (i = 0; i < sizeof(data); i++) ok(data[i] == data_8bpp_rgb_dib[i], "%u: expected %#x, got %#x\n", i, data_8bpp_rgb_dib[i], data[i]); @@ -866,30 +877,30 @@ static void test_CreateBitmapFromHBITMAP(void) hbmp = create_dib(3, 3, 8, pal, data_8bpp_pal_dib); hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, hpal, WICBitmapIgnoreAlpha, &bitmap); - ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr); + ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#lx\n", hr); IWICBitmap_GetPixelFormat(bitmap, &format); -todo_wine + todo_wine ok(IsEqualGUID(&format, &GUID_WICPixelFormat4bppIndexed), "unexpected pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetSize error %#lx\n", hr); ok(width == 3, "expected 3, got %u\n", width); ok(height == 3, "expected 3, got %u\n", height); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICBitmap_CopyPalette(bitmap, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetType(palette, &type); - ok(hr == S_OK, "%u: GetType error %#x\n", i, hr); + ok(hr == S_OK, "%u: GetType error %#lx\n", i, hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); -todo_wine + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); + todo_wine ok(count == 16, "expected 16, got %u\n", count); IWICPalette_Release(palette); @@ -908,35 +919,35 @@ todo_wine hbmp = create_dib(3, 3, 8, pal, data_8bpp_pal_dib); hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, hpal, WICBitmapIgnoreAlpha, &bitmap); - ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr); + ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#lx\n", hr); IWICBitmap_GetPixelFormat(bitmap, &format); ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), "unexpected pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "IWICBitmap_GetSize error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_GetSize error %#lx\n", hr); ok(width == 3, "expected 3, got %u\n", width); ok(height == 3, "expected 3, got %u\n", height); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICBitmap_CopyPalette(bitmap, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetType(palette, &type); - ok(hr == S_OK, "%u: GetType error %#x\n", i, hr); + ok(hr == S_OK, "%u: GetType error %#lx\n", i, hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 256, "expected 256, got %u\n", count); IWICPalette_Release(palette); memset(data, 0, sizeof(data)); hr = IWICBitmap_CopyPixels(bitmap, NULL, 4, sizeof(data), data); - ok(hr == S_OK, "IWICBitmap_CopyPixels error %#x\n", hr); + ok(hr == S_OK, "IWICBitmap_CopyPixels error %#lx\n", hr); for (i = 0; i < sizeof(data); i++) todo_wine_if (data[i] != data_8bpp_pal_wic[i]) ok(data[i] == data_8bpp_pal_wic[i], "%u: expected %#x, got %#x\n", i, data_8bpp_pal_wic[i], data[i]); @@ -948,10 +959,10 @@ todo_wine /* 32bpp alpha */ hbmp = create_dib(2, 2, 32, NULL, NULL); hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, NULL, WICBitmapUseAlpha, &bitmap); - ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr); + ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#lx\n", hr); hr = IWICBitmap_GetPixelFormat(bitmap, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppBGRA), "unexpected pixel format %s\n", wine_dbgstr_guid(&format)); @@ -959,10 +970,10 @@ todo_wine /* 32bpp pre-multiplied alpha */ hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, NULL, WICBitmapUsePremultipliedAlpha, &bitmap); - ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr); + ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#lx\n", hr); hr = IWICBitmap_GetPixelFormat(bitmap, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppPBGRA), "unexpected pixel format %s\n", wine_dbgstr_guid(&format)); @@ -970,10 +981,10 @@ todo_wine /* 32bpp no alpha */ hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmp, NULL, WICBitmapIgnoreAlpha, &bitmap); - ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#x\n", hr); + ok(hr == S_OK, "CreateBitmapFromHBITMAP error %#lx\n", hr); hr = IWICBitmap_GetPixelFormat(bitmap, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppBGR), "unexpected pixel format %s\n", wine_dbgstr_guid(&format)); @@ -992,29 +1003,29 @@ static void test_clipper(void) hr = IWICImagingFactory_CreateBitmap(factory, 10, 10, &GUID_WICPixelFormat24bppBGR, WICBitmapCacheOnLoad, &bitmap); - ok(hr == S_OK, "got 0x%08x\n", hr); + ok(hr == S_OK, "got 0x%08lx\n", hr); hr = IWICImagingFactory_CreateBitmapClipper(factory, &clipper); - ok(hr == S_OK, "got 0x%08x\n", hr); + ok(hr == S_OK, "got 0x%08lx\n", hr); rect.X = rect.Y = 0; rect.Width = rect.Height = 11; hr = IWICBitmapClipper_Initialize(clipper, (IWICBitmapSource*)bitmap, &rect); - ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(hr == E_INVALIDARG, "got 0x%08lx\n", hr); rect.X = rect.Y = 5; rect.Width = rect.Height = 6; hr = IWICBitmapClipper_Initialize(clipper, (IWICBitmapSource*)bitmap, &rect); - ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(hr == E_INVALIDARG, "got 0x%08lx\n", hr); rect.X = rect.Y = 5; rect.Width = rect.Height = 5; hr = IWICBitmapClipper_Initialize(clipper, (IWICBitmapSource*)bitmap, &rect); - ok(hr == S_OK, "got 0x%08x\n", hr); + ok(hr == S_OK, "got 0x%08lx\n", hr); width = height = 0; hr = IWICBitmapClipper_GetSize(clipper, &width, &height); - ok(hr == S_OK, "got 0x%08x\n", hr); + ok(hr == S_OK, "got 0x%08lx\n", hr); ok(width == 5, "got %d\n", width); ok(height == 5, "got %d\n", height); @@ -1023,12 +1034,12 @@ static void test_clipper(void) /* CopyPixels */ hr = IWICImagingFactory_CreateBitmapClipper(factory, &clipper); - ok(hr == S_OK, "got 0x%08x\n", hr); + ok(hr == S_OK, "got 0x%08lx\n", hr); rect.X = rect.Y = 5; rect.Width = rect.Height = 5; hr = IWICBitmapClipper_Initialize(clipper, &bitmapsource, &rect); - ok(hr == S_OK, "got 0x%08x\n", hr); + ok(hr == S_OK, "got 0x%08lx\n", hr); rect.X = rect.Y = 0; rect.Width = rect.Height = 2; @@ -1038,7 +1049,7 @@ static void test_clipper(void) memset(&g_rect, 0, sizeof(g_rect)); called_CopyPixels = FALSE; hr = IWICBitmapClipper_CopyPixels(clipper, &rect, 0, sizeof(buffer), buffer); - ok(hr == S_OK, "got 0x%08x\n", hr); + ok(hr == S_OK, "got 0x%08lx\n", hr); ok(called_CopyPixels, "CopyPixels not called\n"); ok(g_rect.X == 5 && g_rect.Y == 5 && g_rect.Width == 2 && g_rect.Height == 2, "got wrong rectangle (%d,%d)-(%d,%d)\n", g_rect.X, g_rect.Y, g_rect.Width, g_rect.Height); @@ -1051,7 +1062,7 @@ static void test_clipper(void) rect.Width = rect.Height = 5; hr = IWICBitmapClipper_CopyPixels(clipper, &rect, 0, sizeof(buffer), buffer); - ok(hr == S_OK, "got 0x%08x\n", hr); + ok(hr == S_OK, "got 0x%08lx\n", hr); ok(called_CopyPixels, "CopyPixels not called\n"); ok(g_rect.X == 5 && g_rect.Y == 5 && g_rect.Width == 5 && g_rect.Height == 5, "got wrong rectangle (%d,%d)-(%d,%d)\n", g_rect.X, g_rect.Y, g_rect.Width, g_rect.Height); @@ -1064,14 +1075,14 @@ static void test_clipper(void) rect.Width = rect.Height = 20; hr = IWICBitmapClipper_CopyPixels(clipper, &rect, 0, sizeof(buffer), buffer); - ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(hr == E_INVALIDARG, "got 0x%08lx\n", hr); ok(!called_CopyPixels, "CopyPixels called\n"); rect.X = rect.Y = 5; rect.Width = rect.Height = 5; hr = IWICBitmapClipper_CopyPixels(clipper, &rect, 0, sizeof(buffer), buffer); - ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(hr == E_INVALIDARG, "got 0x%08lx\n", hr); ok(!called_CopyPixels, "CopyPixels called\n"); /* null rectangle */ @@ -1079,7 +1090,7 @@ static void test_clipper(void) called_CopyPixels = FALSE; hr = IWICBitmapClipper_CopyPixels(clipper, NULL, 0, sizeof(buffer), buffer); - ok(hr == S_OK, "got 0x%08x\n", hr); + ok(hr == S_OK, "got 0x%08lx\n", hr); ok(called_CopyPixels, "CopyPixels not called\n"); ok(g_rect.X == 5 && g_rect.Y == 5 && g_rect.Width == 5 && g_rect.Height == 5, "got wrong rectangle (%d,%d)-(%d,%d)\n", g_rect.X, g_rect.Y, g_rect.Width, g_rect.Height); @@ -1111,7 +1122,7 @@ static void test_WICCreateBitmapFromSectionEx(void) GetSystemInfo(&sysinfo); hsection = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sysinfo.dwAllocationGranularity * 2, NULL); - ok(hsection != NULL, "CreateFileMapping failed %u\n", GetLastError()); + ok(hsection != NULL, "CreateFileMapping failed %lu\n", GetLastError()); memset(&info, 0, sizeof(info)); info.bmiHeader.biSize = sizeof(info.bmiHeader); @@ -1126,20 +1137,20 @@ static void test_WICCreateBitmapFromSectionEx(void) hr = pWICCreateBitmapFromSectionEx(3, 3, &GUID_WICPixelFormat24bppBGR, hsection, 0, 0, WICSectionAccessLevelReadWrite, &bitmap); - ok(hr == S_OK, "WICCreateBitmapFromSectionEx returned %#x\n", hr); + ok(hr == S_OK, "WICCreateBitmapFromSectionEx returned %#lx\n", hr); IWICBitmap_Release(bitmap); /* non-zero offset, smaller than allocation granularity */ hr = pWICCreateBitmapFromSectionEx(3, 3, &GUID_WICPixelFormat24bppBGR, hsection, 0, 0x100, WICSectionAccessLevelReadWrite, &bitmap); - ok(hr == S_OK, "WICCreateBitmapFromSectionEx returned %#x\n", hr); + ok(hr == S_OK, "WICCreateBitmapFromSectionEx returned %#lx\n", hr); IWICBitmap_Release(bitmap); /* offset larger than allocation granularity */ hr = pWICCreateBitmapFromSectionEx(3, 3, &GUID_WICPixelFormat24bppBGR, hsection, 0, sysinfo.dwAllocationGranularity + 1, WICSectionAccessLevelReadWrite, &bitmap); - ok(hr == S_OK, "WICCreateBitmapFromSectionEx returned %#x\n", hr); + ok(hr == S_OK, "WICCreateBitmapFromSectionEx returned %#lx\n", hr); IWICBitmap_Release(bitmap); DeleteObject(hdib); CloseHandle(hsection); @@ -1153,162 +1164,165 @@ static void test_bitmap_scaler(void) double res_x, res_y; IWICBitmap *bitmap; UINT width, height; - BYTE buf[16]; + BYTE buf[93]; /* capable of holding a 7*4px, 24bpp image with stride 24 -> buffer size = 3*24+21 */ HRESULT hr; hr = IWICImagingFactory_CreateBitmap(factory, 4, 2, &GUID_WICPixelFormat24bppBGR, WICBitmapCacheOnLoad, &bitmap); - ok(hr == S_OK, "Failed to create a bitmap, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create a bitmap, hr %#lx.\n", hr); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "Failed to get bitmap size, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to get bitmap size, hr %#lx.\n", hr); ok(width == 4, "Unexpected width %u.\n", width); ok(height == 2, "Unexpected height %u.\n", height); hr = IWICBitmap_GetResolution(bitmap, &res_x, &res_y); - ok(hr == S_OK, "Failed to get bitmap resolution, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to get bitmap resolution, hr %#lx.\n", hr); ok(res_x == 0.0 && res_y == 0.0, "Unexpected resolution %f x %f.\n", res_x, res_y); hr = IWICImagingFactory_CreateBitmapScaler(factory, &scaler); - ok(hr == S_OK, "Failed to create bitmap scaler, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create bitmap scaler, hr %#lx.\n", hr); hr = IWICBitmapScaler_Initialize(scaler, NULL, 0, 0, WICBitmapInterpolationModeNearestNeighbor); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 0, 0, WICBitmapInterpolationModeNearestNeighbor); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetSize(scaler, NULL, &height); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetSize(scaler, &width, NULL); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetResolution(scaler, NULL, NULL); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#lx.\n", hr); res_x = 0.1; hr = IWICBitmapScaler_GetResolution(scaler, &res_x, NULL); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#lx.\n", hr); ok(res_x == 0.1, "Unexpected resolution %f.\n", res_x); hr = IWICBitmapScaler_GetResolution(scaler, NULL, &res_y); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetResolution(scaler, &res_x, &res_y); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetPixelFormat(scaler, NULL); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); memset(&pixel_format, 0, sizeof(pixel_format)); hr = IWICBitmapScaler_GetPixelFormat(scaler, &pixel_format); - ok(hr == S_OK, "Failed to get pixel format, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to get pixel format, hr %#lx.\n", hr); ok(IsEqualGUID(&pixel_format, &GUID_WICPixelFormatDontCare), "Unexpected pixel format %s.\n", wine_dbgstr_guid(&pixel_format)); width = 123; height = 321; hr = IWICBitmapScaler_GetSize(scaler, &width, &height); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#lx.\n", hr); ok(width == 123, "Unexpected width %u.\n", width); ok(height == 321, "Unexpected height %u.\n", height); hr = IWICBitmapScaler_CopyPalette(scaler, NULL); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "Failed to create a palette, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create a palette, hr %#lx.\n", hr); hr = IWICBitmapScaler_CopyPalette(scaler, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "Unexpected hr %#lx.\n", hr); IWICPalette_Release(palette); hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 4, 0, WICBitmapInterpolationModeNearestNeighbor); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetSize(scaler, &width, &height); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_CopyPixels(scaler, NULL, 1, sizeof(buf), buf); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 0, 2, WICBitmapInterpolationModeNearestNeighbor); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetSize(scaler, &width, &height); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_Initialize(scaler, NULL, 8, 4, WICBitmapInterpolationModeNearestNeighbor); - ok(hr == E_INVALIDARG, "Failed to initialize bitmap scaler, hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Failed to initialize bitmap scaler, hr %#lx.\n", hr); - hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 8, 4, + hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 7, 4, WICBitmapInterpolationModeNearestNeighbor); - ok(hr == S_OK, "Failed to initialize bitmap scaler, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to initialize bitmap scaler, hr %#lx.\n", hr); hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 0, 4, WICBitmapInterpolationModeNearestNeighbor); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); - hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 8, 0, + hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 7, 0, WICBitmapInterpolationModeNearestNeighbor); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_Initialize(scaler, NULL, 8, 4, WICBitmapInterpolationModeNearestNeighbor); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); - hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 8, 4, + hr = IWICBitmapScaler_Initialize(scaler, (IWICBitmapSource *)bitmap, 7, 4, WICBitmapInterpolationModeNearestNeighbor); - ok(hr == WINCODEC_ERR_WRONGSTATE, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetSize(scaler, &width, &height); - ok(hr == S_OK, "Failed to get scaler size, hr %#x.\n", hr); - ok(width == 8, "Unexpected width %u.\n", width); + ok(hr == S_OK, "Failed to get scaler size, hr %#lx.\n", hr); + ok(width == 7, "Unexpected width %u.\n", width); ok(height == 4, "Unexpected height %u.\n", height); hr = IWICBitmapScaler_GetSize(scaler, NULL, &height); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetSize(scaler, &width, NULL); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetSize(scaler, NULL, NULL); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICBitmapScaler_GetPixelFormat(scaler, NULL); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); memset(&pixel_format, 0, sizeof(pixel_format)); hr = IWICBitmapScaler_GetPixelFormat(scaler, &pixel_format); - ok(hr == S_OK, "Failed to get pixel format, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to get pixel format, hr %#lx.\n", hr); ok(IsEqualGUID(&pixel_format, &GUID_WICPixelFormat24bppBGR), "Unexpected pixel format %s.\n", wine_dbgstr_guid(&pixel_format)); hr = IWICBitmapScaler_GetResolution(scaler, NULL, NULL); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); res_x = 0.1; hr = IWICBitmapScaler_GetResolution(scaler, &res_x, NULL); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); ok(res_x == 0.1, "Unexpected resolution %f.\n", res_x); hr = IWICBitmapScaler_GetResolution(scaler, NULL, &res_y); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); res_x = res_y = 1.0; hr = IWICBitmapScaler_GetResolution(scaler, &res_x, &res_y); - ok(hr == S_OK, "Failed to get scaler resolution, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to get scaler resolution, hr %#lx.\n", hr); ok(res_x == 0.0 && res_y == 0.0, "Unexpected resolution %f x %f.\n", res_x, res_y); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "Failed to create a palette, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create a palette, hr %#lx.\n", hr); hr = IWICBitmapScaler_CopyPalette(scaler, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "Unexpected hr %#x.\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "Unexpected hr %#lx.\n", hr); IWICPalette_Release(palette); + hr = IWICBitmapScaler_CopyPixels(scaler, NULL, /*cbStride=*/24, sizeof(buf), buf); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IWICBitmapScaler_Release(scaler); IWICBitmap_Release(bitmap); @@ -1338,131 +1352,137 @@ static void test_IMILBitmap(void) /* Bitmap */ hr = IWICImagingFactory_CreateBitmap(factory, 1, 1, &GUID_WICPixelFormat24bppBGR, WICBitmapCacheOnDemand, &bitmap); - ok(hr == S_OK, "CreateBitmap error %#x\n", hr); + ok(hr == S_OK, "CreateBitmap error %#lx\n", hr); - ok(obj_refcount(bitmap) == 1, "ref count %d\n", obj_refcount(bitmap)); + ok(obj_refcount(bitmap) == 1, "ref count %ld\n", obj_refcount(bitmap)); hr = IWICBitmap_GetPixelFormat(bitmap, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat24bppBGR), "wrong format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmap_GetResolution(bitmap, &dpix, &dpiy); - ok(hr == S_OK, "GetResolution error %#x\n", hr); + ok(hr == S_OK, "GetResolution error %#lx\n", hr); ok(dpix == 0.0, "got %f, expected 0.0\n", dpix); ok(dpiy == 0.0, "got %f, expected 0.0\n", dpiy); hr = IWICBitmap_SetResolution(bitmap, 12.0, 34.0); - ok(hr == S_OK, "SetResolution error %#x\n", hr); + ok(hr == S_OK, "SetResolution error %#lx\n", hr); hr = IWICBitmap_GetResolution(bitmap, &dpix, &dpiy); - ok(hr == S_OK, "GetResolution error %#x\n", hr); + ok(hr == S_OK, "GetResolution error %#lx\n", hr); ok(dpix == 12.0, "got %f, expected 12.0\n", dpix); ok(dpiy == 34.0, "got %f, expected 34.0\n", dpiy); hr = IWICBitmap_GetSize(bitmap, &width, &height); - ok(hr == S_OK, "GetSize error %#x\n", hr); + ok(hr == S_OK, "GetSize error %#lx\n", hr); ok(width == 1, "got %u, expected 1\n", width); ok(height == 1, "got %u, expected 1\n", height); hr = IWICBitmap_QueryInterface(bitmap, &IID_IMILBitmap, (void **)&mil_bitmap); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); - ok(obj_refcount(bitmap) == 2, "ref count %d\n", obj_refcount(bitmap)); - ok(obj_refcount(mil_bitmap) == 2, "ref count %d\n", obj_refcount(mil_bitmap)); + ok(obj_refcount(bitmap) == 2, "ref count %ld\n", obj_refcount(bitmap)); + ok(obj_refcount(mil_bitmap) == 2, "ref count %ld\n", obj_refcount(mil_bitmap)); hr = IWICBitmap_QueryInterface(bitmap, &IID_IUnknown, (void **)&wic_unknown); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); hr = mil_bitmap->lpVtbl->QueryInterface(mil_bitmap, &IID_IUnknown, (void **)&mil_unknown); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); ok((void *)wic_unknown->lpVtbl == (void *)mil_unknown->lpVtbl, "wrong lpVtbl ptrs %p != %p\n", wic_unknown->lpVtbl, mil_unknown->lpVtbl); IUnknown_Release(wic_unknown); IUnknown_Release(mil_unknown); hr = IWICBitmap_QueryInterface(bitmap, &IID_IMILBitmapSource, (void **)&mil_source); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); ok((void *)mil_source->lpVtbl == (void *)mil_bitmap->lpVtbl, "IMILBitmap->lpVtbl should be equal to IMILBitmapSource->lpVtbl\n"); - ok(obj_refcount(bitmap) == 3, "ref count %d\n", obj_refcount(bitmap)); - ok(obj_refcount(mil_bitmap) == 3, "ref count %d\n", obj_refcount(mil_bitmap)); - ok(obj_refcount(mil_source) == 3, "ref count %d\n", obj_refcount(mil_source)); + ok(obj_refcount(bitmap) == 3, "ref count %ld\n", obj_refcount(bitmap)); + ok(obj_refcount(mil_bitmap) == 3, "ref count %ld\n", obj_refcount(mil_bitmap)); + ok(obj_refcount(mil_source) == 3, "ref count %ld\n", obj_refcount(mil_source)); hr = mil_source->lpVtbl->GetPixelFormat(mil_source, &MIL_format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(MIL_format == 0x0c, "wrong format %d\n", MIL_format); hr = mil_source->lpVtbl->GetResolution(mil_source, &dpix, &dpiy); - ok(hr == S_OK, "GetResolution error %#x\n", hr); + ok(hr == S_OK, "GetResolution error %#lx\n", hr); ok(dpix == 12.0, "got %f, expected 12.0\n", dpix); ok(dpiy == 34.0, "got %f, expected 34.0\n", dpiy); hr = mil_source->lpVtbl->GetSize(mil_source, &width, &height); - ok(hr == S_OK, "GetSize error %#x\n", hr); + ok(hr == S_OK, "GetSize error %#lx\n", hr); ok(width == 1, "got %u, expected 1\n", width); ok(height == 1, "got %u, expected 1\n", height); /* Scaler */ hr = IWICImagingFactory_CreateBitmapScaler(factory, &scaler); - ok(hr == S_OK, "CreateBitmapScaler error %#x\n", hr); + ok(hr == S_OK, "CreateBitmapScaler error %#lx\n", hr); - ok(obj_refcount(scaler) == 1, "ref count %d\n", obj_refcount(scaler)); + ok(obj_refcount(scaler) == 1, "ref count %ld\n", obj_refcount(scaler)); hr = IWICBitmapScaler_QueryInterface(scaler, &IID_IMILBitmapScaler, (void **)&mil_scaler); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); - ok(obj_refcount(scaler) == 2, "ref count %d\n", obj_refcount(scaler)); - ok(obj_refcount(mil_scaler) == 2, "ref count %d\n", obj_refcount(mil_scaler)); + ok(obj_refcount(scaler) == 2, "ref count %ld\n", obj_refcount(scaler)); + ok(obj_refcount(mil_scaler) == 2, "ref count %ld\n", obj_refcount(mil_scaler)); hr = IWICBitmapScaler_QueryInterface(scaler, &IID_IUnknown, (void **)&wic_unknown); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); hr = mil_scaler->lpVtbl->QueryInterface(mil_scaler, &IID_IUnknown, (void **)&mil_unknown); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); ok((void *)wic_unknown->lpVtbl == (void *)mil_unknown->lpVtbl, "wrong lpVtbl ptrs %p != %p\n", wic_unknown->lpVtbl, mil_unknown->lpVtbl); IUnknown_Release(wic_unknown); IUnknown_Release(mil_unknown); hr = mil_scaler->lpVtbl->GetPixelFormat(mil_scaler, &MIL_format); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetPixelFormat error %#x\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetPixelFormat error %#lx\n", hr); hr = mil_scaler->lpVtbl->GetResolution(mil_scaler, &dpix, &dpiy); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetResolution error %#x\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetResolution error %#lx\n", hr); hr = mil_scaler->lpVtbl->GetSize(mil_scaler, &width, &height); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetSize error %#x\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetSize error %#lx\n", hr); memset(buf, 0xde, sizeof(buf)); hr = mil_scaler->lpVtbl->CopyPixels(mil_scaler, NULL, 3, sizeof(buf), buf); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "CopyPixels error %#x\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "CopyPixels error %#lx\n", hr); hr = mil_scaler->lpVtbl->Initialize(mil_scaler, mil_source, 1, 1, 1); - ok(hr == S_OK, "Initialize error %#x\n", hr); + ok(hr == S_OK, "Initialize error %#lx\n", hr); hr = mil_scaler->lpVtbl->GetPixelFormat(mil_scaler, &MIL_format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(MIL_format == 0x0c, "wrong format %d\n", MIL_format); hr = mil_scaler->lpVtbl->GetResolution(mil_scaler, &dpix, &dpiy); - ok(hr == S_OK, "GetResolution error %#x\n", hr); + ok(hr == S_OK, "GetResolution error %#lx\n", hr); ok(dpix == 12.0, "got %f, expected 12.0\n", dpix); ok(dpiy == 34.0, "got %f, expected 34.0\n", dpiy); hr = mil_scaler->lpVtbl->GetSize(mil_scaler, &width, &height); - ok(hr == S_OK, "GetSize error %#x\n", hr); + ok(hr == S_OK, "GetSize error %#lx\n", hr); ok(width == 1, "got %u, expected 1\n", width); ok(height == 1, "got %u, expected 1\n", height); memset(buf, 0xde, sizeof(buf)); hr = mil_scaler->lpVtbl->CopyPixels(mil_scaler, NULL, 3, sizeof(buf), buf); - ok(hr == S_OK, "CopyPixels error %#x\n", hr); + ok(hr == S_OK, "CopyPixels error %#lx\n", hr); ok(buf[0] == 0 && buf[1] == 0 && buf[2] == 0 && buf[3] == 0xde,"wrong data: %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3]); mil_scaler->lpVtbl->Release(mil_scaler); IWICBitmapScaler_Release(scaler); mil_source->lpVtbl->Release(mil_source); mil_bitmap->lpVtbl->Release(mil_bitmap); + + mil_unknown = (void *)0xdeadbeef; + hr = IWICBitmap_QueryInterface(bitmap, &IID_CMetaBitmapRenderTarget, (void **)&mil_unknown); + ok(hr == E_NOINTERFACE, "got %#lx\n", hr); + ok(!mil_unknown, "got %p\n", mil_unknown); + IWICBitmap_Release(bitmap); } @@ -1474,7 +1494,7 @@ START_TEST(bitmap) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); test_IMILBitmap(); test_createbitmap(); diff --git a/modules/rostests/winetests/windowscodecs/bmpformat.c b/modules/rostests/winetests/windowscodecs/bmpformat.c index 8bac7a3853e..724723f647a 100644 --- a/modules/rostests/winetests/windowscodecs/bmpformat.c +++ b/modules/rostests/winetests/windowscodecs/bmpformat.c @@ -22,7 +22,6 @@ #define COBJMACROS #include "windef.h" -#include "initguid.h" #include "objbase.h" #include "wincodec.h" #include "wincodecsdk.h" @@ -76,7 +75,7 @@ static void test_decode_24bpp(void) hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_24bpp)); @@ -88,11 +87,11 @@ static void test_decode_24bpp(void) GlobalUnlock(hbmpdata); hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream); - ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad); - ok(hr == S_OK || broken(hr == WINCODEC_ERR_BADIMAGE) /* XP */, "Initialize failed, hr=%x\n", hr); + ok(hr == S_OK || broken(hr == WINCODEC_ERR_BADIMAGE) /* XP */, "Initialize failed, hr=%lx\n", hr); if (FAILED(hr)) { win_skip("BMP decoder failed to initialize\n"); @@ -102,72 +101,72 @@ static void test_decode_24bpp(void) } hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); - ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n"); hr = IWICBitmapDecoder_GetMetadataQueryReader(decoder, &queryreader); - ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %lx\n", hr); hr = IWICBitmapDecoder_GetColorContexts(decoder, 1, &colorcontext, &count); - ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %lx\n", hr); hr = IWICBitmapDecoder_GetThumbnail(decoder, &thumbnail); - ok(hr == WINCODEC_ERR_CODECNOTHUMBNAIL, "expected WINCODEC_ERR_CODECNOTHUMBNAIL, got %x\n", hr); + ok(hr == WINCODEC_ERR_CODECNOTHUMBNAIL, "expected WINCODEC_ERR_CODECNOTHUMBNAIL, got %lx\n", hr); hr = IWICBitmapDecoder_GetPreview(decoder, &thumbnail); - ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %lx\n", hr); hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); - ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %u\n", count); hr = IWICBitmapDecoder_GetFrame(decoder, 1, &framedecode); - ok(hr == E_INVALIDARG || hr == WINCODEC_ERR_FRAMEMISSING, "GetFrame returned %x\n", hr); + ok(hr == E_INVALIDARG || hr == WINCODEC_ERR_FRAMEMISSING, "GetFrame returned %lx\n", hr); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); - ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrame failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { IWICImagingFactory *factory; IWICPalette *palette; hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); - ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetSize failed, hr=%lx\n", hr); ok(width == 2, "expected width=2, got %u\n", width); ok(height == 3, "expected height=2, got %u\n", height); hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY); - ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetResolution failed, hr=%lx\n", hr); ok(dpiX == 96.0, "expected dpiX=96.0, got %f\n", dpiX); ok(dpiY == 96.0, "expected dpiY=96.0, got %f\n", dpiY); hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult); - ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n"); hr = IWICBitmapFrameDecode_GetMetadataQueryReader(framedecode, &queryreader); - ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %lx\n", hr); hr = IWICBitmapFrameDecode_GetColorContexts(framedecode, 1, &colorcontext, &count); - ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %x\n", hr); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "expected WINCODEC_ERR_UNSUPPORTEDOPERATION, got %lx\n", hr); hr = IWICBitmapFrameDecode_GetThumbnail(framedecode, &thumbnail); - ok(hr == WINCODEC_ERR_CODECNOTHUMBNAIL, "expected WINCODEC_ERR_CODECNOTHUMBNAIL, got %x\n", hr); + ok(hr == WINCODEC_ERR_CODECNOTHUMBNAIL, "expected WINCODEC_ERR_CODECNOTHUMBNAIL, got %lx\n", hr); hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreatePalette failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_CopyPalette(decoder, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %lx\n", hr); IWICPalette_Release(palette); } @@ -180,39 +179,39 @@ static void test_decode_24bpp(void) rc.Width = 3; rc.Height = 3; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 6, sizeof(imagedata), imagedata); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); rc.X = -1; rc.Y = 0; rc.Width = 2; rc.Height = 3; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 6, sizeof(imagedata), imagedata); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); rc.X = 0; rc.Y = 0; rc.Width = 2; rc.Height = 3; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 4, sizeof(imagedata), imagedata); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); rc.X = 0; rc.Y = 0; rc.Width = 2; rc.Height = 3; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 4, 5, imagedata); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); rc.X = 0; rc.Y = 0; rc.Width = 2; rc.Height = 3; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 6, sizeof(imagedata), imagedata); - ok(SUCCEEDED(hr), "CopyPixels failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPixels failed, hr=%lx\n", hr); ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n"); hr = IWICBitmapFrameDecode_CopyPixels(framedecode, NULL, 6, sizeof(imagedata), imagedata); - ok(SUCCEEDED(hr), "CopyPixels(rect=NULL) failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPixels(rect=NULL) failed, hr=%lx\n", hr); ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n"); IWICBitmapFrameDecode_Release(framedecode); @@ -220,29 +219,29 @@ static void test_decode_24bpp(void) /* cannot initialize twice */ hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad); - ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%lx\n", hr); /* cannot querycapability after initialize */ hr = IWICBitmapDecoder_QueryCapability(decoder, bmpstream, &capability); - ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%lx\n", hr); hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder2); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability); - ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryCapability failed, hr=%lx\n", hr); ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages), - "unexpected capabilities: %x\n", capability); + "unexpected capabilities: %lx\n", capability); /* cannot initialize after querycapability */ hr = IWICBitmapDecoder_Initialize(decoder2, bmpstream, WICDecodeMetadataCacheOnLoad); - ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%lx\n", hr); /* cannot querycapability twice */ hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability); - ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, hr=%lx\n", hr); IWICBitmapDecoder_Release(decoder2); } @@ -296,7 +295,7 @@ static void test_decode_1bpp(void) hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_1bpp)); @@ -308,62 +307,62 @@ static void test_decode_1bpp(void) GlobalUnlock(hbmpdata); hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream); - ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad); - ok(hr == S_OK, "Initialize failed, hr=%x\n", hr); + ok(hr == S_OK, "Initialize failed, hr=%lx\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); - ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n"); hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); - ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %u\n", count); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); - ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrame failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { IWICImagingFactory *factory; IWICPalette *palette; hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); - ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetSize failed, hr=%lx\n", hr); ok(width == 2, "expected width=2, got %u\n", width); ok(height == 2, "expected height=2, got %u\n", height); hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY); - ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetResolution failed, hr=%lx\n", hr); ok(dpiX == 96.0, "expected dpiX=96.0, got %f\n", dpiX); ok(dpiY == 96.0, "expected dpiY=96.0, got %f\n", dpiY); hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult); - ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat1bppIndexed), "unexpected pixel format\n"); hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreatePalette failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_CopyPalette(decoder, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette); - ok(SUCCEEDED(hr), "CopyPalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPalette failed, hr=%lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 2, "expected count=2, got %u\n", count); hr = IWICPalette_GetColors(palette, 2, palettedata, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 2, "expected count=2, got %u\n", count); ok(!memcmp(palettedata, expected_palettedata, sizeof(palettedata)), "unexpected palette data\n"); @@ -378,7 +377,7 @@ static void test_decode_1bpp(void) rc.Width = 2; rc.Height = 2; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 1, sizeof(imagedata), imagedata); - ok(SUCCEEDED(hr), "CopyPixels failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPixels failed, hr=%lx\n", hr); ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n"); IWICBitmapFrameDecode_Release(framedecode); @@ -386,13 +385,13 @@ static void test_decode_1bpp(void) hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder2); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability); - ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryCapability failed, hr=%lx\n", hr); ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages), - "unexpected capabilities: %x\n", capability); + "unexpected capabilities: %lx\n", capability); IWICBitmapDecoder_Release(decoder2); } @@ -455,7 +454,7 @@ static void test_decode_4bpp(void) hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_4bpp)); @@ -467,62 +466,62 @@ static void test_decode_4bpp(void) GlobalUnlock(hbmpdata); hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream); - ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad); - ok(hr == S_OK, "Initialize failed, hr=%x\n", hr); + ok(hr == S_OK, "Initialize failed, hr=%lx\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); - ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n"); hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); - ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %u\n", count); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); - ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrame failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { IWICImagingFactory *factory; IWICPalette *palette; hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); - ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetSize failed, hr=%lx\n", hr); ok(width == 2, "expected width=2, got %u\n", width); ok(height == 2, "expected height=2, got %u\n", height); hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY); - ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetResolution failed, hr=%lx\n", hr); ok(fabs(dpiX - 254.0) < 0.01, "expected dpiX=96.0, got %f\n", dpiX); ok(fabs(dpiY - 508.0) < 0.01, "expected dpiY=96.0, got %f\n", dpiY); hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult); - ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat4bppIndexed), "unexpected pixel format\n"); hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreatePalette failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_CopyPalette(decoder, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette); - ok(SUCCEEDED(hr), "CopyPalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPalette failed, hr=%lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 5, "expected count=5, got %u\n", count); hr = IWICPalette_GetColors(palette, 5, palettedata, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 5, "expected count=5, got %u\n", count); ok(!memcmp(palettedata, expected_palettedata, sizeof(palettedata)), "unexpected palette data\n"); @@ -537,7 +536,7 @@ static void test_decode_4bpp(void) rc.Width = 2; rc.Height = 2; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 1, sizeof(imagedata), imagedata); - ok(SUCCEEDED(hr), "CopyPixels failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPixels failed, hr=%lx\n", hr); ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n"); IWICBitmapFrameDecode_Release(framedecode); @@ -545,13 +544,13 @@ static void test_decode_4bpp(void) hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder2); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability); - ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryCapability failed, hr=%lx\n", hr); ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages), - "unexpected capabilities: %x\n", capability); + "unexpected capabilities: %lx\n", capability); IWICBitmapDecoder_Release(decoder2); } @@ -635,7 +634,7 @@ static void test_decode_rle8(void) hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_rle8)); @@ -647,62 +646,62 @@ static void test_decode_rle8(void) GlobalUnlock(hbmpdata); hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream); - ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad); - ok(hr == S_OK, "Initialize failed, hr=%x\n", hr); + ok(hr == S_OK, "Initialize failed, hr=%lx\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); - ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n"); hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); - ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %u\n", count); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); - ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrame failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { IWICImagingFactory *factory; IWICPalette *palette; hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); - ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetSize failed, hr=%lx\n", hr); ok(width == 8, "expected width=8, got %u\n", width); ok(height == 8, "expected height=8, got %u\n", height); hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY); - ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetResolution failed, hr=%lx\n", hr); ok(fabs(dpiX - 72.0) < 0.01, "expected dpiX=96.0, got %f\n", dpiX); ok(fabs(dpiY - 72.0) < 0.01, "expected dpiY=96.0, got %f\n", dpiY); hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult); - ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat32bppBGR), "unexpected pixel format\n"); hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreatePalette failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_CopyPalette(decoder, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette); - ok(SUCCEEDED(hr), "CopyPalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPalette failed, hr=%lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 17, "expected count=17, got %u\n", count); hr = IWICPalette_GetColors(palette, 17, palettedata, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 17, "expected count=17, got %u\n", count); ok(!memcmp(palettedata, expected_palettedata, sizeof(palettedata)), "unexpected palette data\n"); @@ -717,7 +716,7 @@ static void test_decode_rle8(void) rc.Width = 8; rc.Height = 8; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 32, sizeof(imagedata), (BYTE*)imagedata); - ok(SUCCEEDED(hr), "CopyPixels failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPixels failed, hr=%lx\n", hr); ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n"); IWICBitmapFrameDecode_Release(framedecode); @@ -725,13 +724,13 @@ static void test_decode_rle8(void) hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder2); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability); - ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryCapability failed, hr=%lx\n", hr); ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages), - "unexpected capabilities: %x\n", capability); + "unexpected capabilities: %lx\n", capability); IWICBitmapDecoder_Release(decoder2); } @@ -802,7 +801,7 @@ static void test_decode_rle4(void) hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_rle4)); @@ -814,62 +813,62 @@ static void test_decode_rle4(void) GlobalUnlock(hbmpdata); hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream); - ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad); - ok(hr == S_OK, "Initialize failed, hr=%x\n", hr); + ok(hr == S_OK, "Initialize failed, hr=%lx\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); - ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n"); hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); - ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %u\n", count); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); - ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrame failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { IWICImagingFactory *factory; IWICPalette *palette; hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); - ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetSize failed, hr=%lx\n", hr); ok(width == 8, "expected width=8, got %u\n", width); ok(height == 8, "expected height=8, got %u\n", height); hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY); - ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetResolution failed, hr=%lx\n", hr); ok(fabs(dpiX - 72.0) < 0.01, "expected dpiX=96.0, got %f\n", dpiX); ok(fabs(dpiY - 72.0) < 0.01, "expected dpiY=96.0, got %f\n", dpiY); hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult); - ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat32bppBGR), "unexpected pixel format\n"); hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreatePalette failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_CopyPalette(decoder, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette); - ok(SUCCEEDED(hr), "CopyPalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPalette failed, hr=%lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 6, "expected count=6, got %u\n", count); hr = IWICPalette_GetColors(palette, 6, palettedata, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 6, "expected count=6, got %u\n", count); ok(!memcmp(palettedata, expected_palettedata, sizeof(palettedata)), "unexpected palette data\n"); @@ -884,7 +883,7 @@ static void test_decode_rle4(void) rc.Width = 8; rc.Height = 8; hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 32, sizeof(imagedata), (BYTE*)imagedata); - ok(SUCCEEDED(hr), "CopyPixels failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPixels failed, hr=%lx\n", hr); ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n"); IWICBitmapFrameDecode_Release(framedecode); @@ -892,13 +891,13 @@ static void test_decode_rle4(void) hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder2); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_QueryCapability(decoder2, bmpstream, &capability); - ok(hr == S_OK, "QueryCapability failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryCapability failed, hr=%lx\n", hr); ok(capability == (WICBitmapDecoderCapabilityCanDecodeAllImages), - "unexpected capabilities: %x\n", capability); + "unexpected capabilities: %lx\n", capability); IWICBitmapDecoder_Release(decoder2); } @@ -911,6 +910,142 @@ static void test_decode_rle4(void) IWICBitmapDecoder_Release(decoder); } +static const char testbmp_bitfields_abgr[] = { + /* BITMAPFILEHEADER */ + 'B','M', /* "BM" */ + sizeof(BITMAPFILEHEADER)+sizeof(BITMAPV5HEADER)+8,0,0,0, /* file size */ + 0,0,0,0, /* reserved */ + sizeof(BITMAPFILEHEADER)+sizeof(BITMAPV5HEADER),0,0,0, /* offset to bits */ + /* BITMAPV5HEADER */ + sizeof(BITMAPV5HEADER),0,0,0, /* size */ + 2,0,0,0, /* width */ + 1,0,0,0, /* height */ + 1,0, /* planes */ + 32,0, /* bit count */ + BI_BITFIELDS,0,0,0, /* compression */ + 8,0,0,0, /* image size */ + 19,11,0,0, /* X pixels per meter */ + 19,11,0,0, /* Y pixels per meter */ + 0,0,0,0, /* colors used */ + 0,0,0,0, /* colors important */ + 0,0,0,255, /* red mask */ + 0,0,255,0, /* green mask */ + 0,255,0,0, /* blue mask */ + 255,0,0,0, /* alpha mask */ + 'B','G','R','s', /* color space */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, /* gamma */ + LCS_GM_GRAPHICS,0,0,0, /* intent */ + 0,0,0,0,0,0,0,0,0,0,0,0, + /* bits */ + 0,255,0,0,255,0,255,0 +}; + +static void test_decode_bitfields(void) +{ + IWICBitmapDecoder *decoder; + IWICBitmapFrameDecode *framedecode; + HRESULT hr; + HGLOBAL hbmpdata; + char *bmpdata; + IStream *bmpstream; + GUID guidresult; + UINT count=0, width=0, height=0; + double dpiX, dpiY; + DWORD imagedata[2] = {1}; + const DWORD expected_imagedata[2] = { 0xff, 0xff00 }; + WICRect rc; + + hr = CoCreateInstance(&CLSID_WICBmpDecoder, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICBitmapDecoder, (void**)&decoder); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); + if (FAILED(hr)) return; + + hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_bitfields_abgr)); + ok(hbmpdata != 0, "GlobalAlloc failed\n"); + if (hbmpdata) + { + bmpdata = GlobalLock(hbmpdata); + memcpy(bmpdata, testbmp_bitfields_abgr, sizeof(testbmp_bitfields_abgr)); + GlobalUnlock(hbmpdata); + + hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); + if (SUCCEEDED(hr)) + { + hr = IWICBitmapDecoder_Initialize(decoder, bmpstream, WICDecodeMetadataCacheOnLoad); + ok(hr == S_OK, "Initialize failed, hr=%lx\n", hr); + + hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); + ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%lx\n", hr); + ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n"); + + hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); + ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%lx\n", hr); + ok(count == 1, "unexpected count %u\n", count); + + hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); + ok(SUCCEEDED(hr), "GetFrame failed, hr=%lx\n", hr); + if (SUCCEEDED(hr)) + { + IWICImagingFactory *factory; + IWICPalette *palette; + + hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); + ok(SUCCEEDED(hr), "GetSize failed, hr=%lx\n", hr); + ok(width == 2, "expected width=2, got %u\n", width); + ok(height == 1, "expected height=1, got %u\n", height); + + hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY); + ok(SUCCEEDED(hr), "GetResolution failed, hr=%lx\n", hr); + ok(fabs(dpiX - 72.0) < 0.01, "expected dpiX=72.0, got %f\n", dpiX); + ok(fabs(dpiY - 72.0) < 0.01, "expected dpiY=72.0, got %f\n", dpiY); + + hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult); + ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%lx\n", hr); + ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat32bppBGR), "unexpected pixel format\n"); + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICImagingFactory, (void**)&factory); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); + if (SUCCEEDED(hr)) + { + hr = IWICImagingFactory_CreatePalette(factory, &palette); + ok(SUCCEEDED(hr), "CreatePalette failed, hr=%lx\n", hr); + if (SUCCEEDED(hr)) + { + hr = IWICBitmapDecoder_CopyPalette(decoder, palette); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %lx\n", hr); + + hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %lx\n", hr); + + IWICPalette_Release(palette); + } + + IWICImagingFactory_Release(factory); + } + + rc.X = 0; + rc.Y = 0; + rc.Width = 2; + rc.Height = 1; + hr = IWICBitmapFrameDecode_CopyPixels(framedecode, &rc, 32, sizeof(imagedata), (BYTE*)imagedata); + ok(SUCCEEDED(hr), "CopyPixels failed, hr=%lx\n", hr); + ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)), "unexpected image data\n"); + + IWICBitmapFrameDecode_Release(framedecode); + } + + IStream_Release(bmpstream); + } + + GlobalFree(hbmpdata); + } + + IWICBitmapDecoder_Release(decoder); +} + static void test_componentinfo(void) { IWICImagingFactory *factory; @@ -929,31 +1064,31 @@ static void test_componentinfo(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICImagingFactory_CreateComponentInfo(factory, &CLSID_WICBmpDecoder, &info); - ok(SUCCEEDED(hr), "CreateComponentInfo failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateComponentInfo failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICComponentInfo_GetComponentType(info, &type); - ok(SUCCEEDED(hr), "GetComponentType failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetComponentType failed, hr=%lx\n", hr); ok(type == WICDecoder, "got %i, expected WICDecoder\n", type); hr = IWICComponentInfo_QueryInterface(info, &IID_IWICBitmapDecoderInfo, (void**)&decoderinfo); - ok(SUCCEEDED(hr), "QueryInterface failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "QueryInterface failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { pattern_count = 0; pattern_size = 0; hr = IWICBitmapDecoderInfo_GetPatterns(decoderinfo, 0, NULL, &pattern_count, &pattern_size); - ok(SUCCEEDED(hr), "GetPatterns failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetPatterns failed, hr=%lx\n", hr); ok(pattern_count != 0, "pattern count is 0\n"); ok(pattern_size > pattern_count * sizeof(WICBitmapPattern), "size=%i, count=%i\n", pattern_size, pattern_count); patterns = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pattern_size); hr = IWICBitmapDecoderInfo_GetPatterns(decoderinfo, pattern_size, patterns, &pattern_count, &pattern_size); - ok(SUCCEEDED(hr), "GetPatterns failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetPatterns failed, hr=%lx\n", hr); ok(pattern_count != 0, "pattern count is 0\n"); ok(pattern_size > pattern_count * sizeof(WICBitmapPattern), "size=%i, count=%i\n", pattern_size, pattern_count); ok(patterns[0].Length != 0, "pattern length is 0\n"); @@ -962,16 +1097,16 @@ static void test_componentinfo(void) pattern_size -= 1; hr = IWICBitmapDecoderInfo_GetPatterns(decoderinfo, pattern_size, patterns, &pattern_count, &pattern_size); - ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetPatterns returned %x, expected WINCODEC_ERR_INSUFFICIENTBUFFER\n", hr); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetPatterns returned %lx, expected WINCODEC_ERR_INSUFFICIENTBUFFER\n", hr); HeapFree(GetProcessHeap(), 0, patterns); hr = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, &decoder); - ok(SUCCEEDED(hr), "CreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); - ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n"); IWICBitmapDecoder_Release(decoder); @@ -986,12 +1121,12 @@ static void test_componentinfo(void) GlobalUnlock(hbmpdata); hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream); - ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { boolresult = 0; hr = IWICBitmapDecoderInfo_MatchesPattern(decoderinfo, bmpstream, &boolresult); - ok(SUCCEEDED(hr), "MatchesPattern failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "MatchesPattern failed, hr=%lx\n", hr); ok(boolresult, "pattern not matched\n"); IStream_Release(bmpstream); @@ -1022,7 +1157,7 @@ static void test_createfromstream(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; hbmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(testbmp_1bpp)); @@ -1034,16 +1169,16 @@ static void test_createfromstream(void) GlobalUnlock(hbmpdata); hr = CreateStreamOnHGlobal(hbmpdata, FALSE, &bmpstream); - ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICImagingFactory_CreateDecoderFromStream(factory, bmpstream, NULL, WICDecodeMetadataCacheOnDemand, &decoder); - ok(SUCCEEDED(hr), "CreateDecoderFromStream failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateDecoderFromStream failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); - ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatBmp), "unexpected container format\n"); IWICBitmapDecoder_Release(decoder); @@ -1066,25 +1201,272 @@ static void test_create_decoder(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void **)&factory); - ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); hr = IWICImagingFactory_CreateDecoder(factory, NULL, NULL, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICImagingFactory_CreateDecoder(factory, NULL, NULL, &decoder); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICImagingFactory_CreateDecoder(factory, &GUID_ContainerFormatBmp, NULL, &decoder); - ok(hr == S_OK, "CreateDecoder error %#x\n", hr); + ok(hr == S_OK, "CreateDecoder error %#lx\n", hr); IWICBitmapDecoder_Release(decoder); hr = IWICImagingFactory_CreateDecoder(factory, &GUID_ContainerFormatBmp, &GUID_VendorMicrosoft, &decoder); - ok(hr == S_OK, "CreateDecoder error %#x\n", hr); + ok(hr == S_OK, "CreateDecoder error %#lx\n", hr); IWICBitmapDecoder_Release(decoder); IWICImagingFactory_Release(factory); } +static void test_writesource_palette(void) +{ + IWICImagingFactory *factory; + HRESULT hr; + WICColor encode_palette[2] = {0xff111111, 0xffcccccc}; + WICColor source_palette[2] = {0xff555555, 0xffaaaaaa}; + WICColor result_palette[2]; + UINT result_colors; + IWICBitmap *bitmap; + IWICPalette *palette; + IStream *stream; + IWICBitmapEncoder *encoder; + IWICBitmapFrameEncode *frame_encode; + IPropertyBag2 *encode_options; + GUID pixelformat; + IWICBitmapDecoder *decoder; + IWICBitmapFrameDecode *frame_decode; + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICImagingFactory, (void **)&factory); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); + + /* Encoder with palette set */ + hr = IWICImagingFactory_CreateBitmap(factory, 1, 1, &GUID_WICPixelFormat1bppIndexed, + WICBitmapCacheOnDemand, &bitmap); + ok(hr == S_OK, "CreateBitmap error %#lx\n", hr); + + hr = IWICImagingFactory_CreatePalette(factory, &palette); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); + + hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); + ok(hr == S_OK, "CreateStream error %#lx\n", hr); + + hr = IWICImagingFactory_CreateEncoder(factory, &GUID_ContainerFormatBmp, &GUID_VendorMicrosoft, &encoder); + ok(hr == S_OK, "CreateDecoder error %#lx\n", hr); + + hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache); + ok(hr == S_OK, "IWICBitmapEncoder_Initialize error %#lx\n", hr); + + hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frame_encode, &encode_options); + ok(hr == S_OK, "CreateNewFrame error %#lx\n", hr); + + hr = IWICBitmapFrameEncode_Initialize(frame_encode, encode_options); + ok(hr == S_OK, "IWICBitmapFrameEncode_Initialize error %#lx\n", hr); + + IPropertyBag2_Release(encode_options); + + hr = IWICBitmapFrameEncode_SetSize(frame_encode, 1, 1); + ok(hr == S_OK, "SetSize error %#lx\n", hr); + + pixelformat = GUID_WICPixelFormat1bppIndexed; + hr = IWICBitmapFrameEncode_SetPixelFormat(frame_encode, &pixelformat); + ok(hr == S_OK, "SetPixelFormat error %#lx\n", hr); + ok(!memcmp(&pixelformat, &GUID_WICPixelFormat1bppIndexed, sizeof(pixelformat)), "pixel format changed\n"); + + hr = IWICPalette_InitializeCustom(palette, encode_palette, 2); + ok(hr == S_OK, "InitializeCustom error %#lx\n", hr); + + hr = IWICBitmapFrameEncode_SetPalette(frame_encode, palette); + ok(hr == S_OK, "SetPalette error %#lx\n", hr); + + hr = IWICPalette_InitializeCustom(palette, source_palette, 2); + ok(hr == S_OK, "InitializeCustom error %#lx\n", hr); + + hr = IWICBitmap_SetPalette(bitmap, palette); + ok(hr == S_OK, "SetPalette error %#lx\n", hr); + + hr = IWICBitmapFrameEncode_WriteSource(frame_encode, (IWICBitmapSource*)bitmap, NULL); + ok(hr == S_OK, "WriteSource error %#lx\n", hr); + + hr = IWICBitmapFrameEncode_Commit(frame_encode); + ok(hr == S_OK, "Commit error %#lx\n", hr); + + IWICBitmapFrameEncode_Release(frame_encode); + + hr = IWICBitmapEncoder_Commit(encoder); + ok(hr == S_OK, "Commit error %#lx\n", hr); + + IWICBitmapEncoder_Release(encoder); + + hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, WICDecodeMetadataCacheOnLoad, &decoder); + ok(hr == S_OK, "CreateDecoderFromStream error %#lx\n", hr); + + hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame_decode); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); + + hr = IWICBitmapFrameDecode_CopyPalette(frame_decode, palette); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); + + hr = IWICPalette_GetColors(palette, 2, result_palette, &result_colors); + ok(hr == S_OK, "GetColors error %#lx\n", hr); + ok(result_colors == 2, "Got %i colors\n", result_colors); + ok(result_palette[0] == encode_palette[0], "Unexpected palette entry: %x\n", result_palette[0]); + ok(result_palette[1] == encode_palette[1], "Unexpected palette entry: %x\n", result_palette[0]); + + IWICBitmapFrameDecode_Release(frame_decode); + IWICBitmapDecoder_Release(decoder); + IStream_Release(stream); + + /* Encoder with no palette set */ + hr = IWICImagingFactory_CreateEncoder(factory, &GUID_ContainerFormatBmp, &GUID_VendorMicrosoft, &encoder); + ok(hr == S_OK, "CreateDecoder error %#lx\n", hr); + + hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); + ok(hr == S_OK, "CreateStream error %#lx\n", hr); + + hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache); + ok(hr == S_OK, "IWICBitmapEncoder_Initialize error %#lx\n", hr); + + hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frame_encode, &encode_options); + ok(hr == S_OK, "CreateNewFrame error %#lx\n", hr); + + hr = IWICBitmapFrameEncode_Initialize(frame_encode, encode_options); + ok(hr == S_OK, "IWICBitmapFrameEncode_Initialize error %#lx\n", hr); + + IPropertyBag2_Release(encode_options); + + hr = IWICBitmapFrameEncode_SetSize(frame_encode, 1, 1); + ok(hr == S_OK, "SetSize error %#lx\n", hr); + + pixelformat = GUID_WICPixelFormat1bppIndexed; + hr = IWICBitmapFrameEncode_SetPixelFormat(frame_encode, &pixelformat); + ok(hr == S_OK, "SetPixelFormat error %#lx\n", hr); + ok(!memcmp(&pixelformat, &GUID_WICPixelFormat1bppIndexed, sizeof(pixelformat)), "pixel format changed\n"); + + hr = IWICPalette_InitializeCustom(palette, source_palette, 2); + ok(hr == S_OK, "InitializeCustom error %#lx\n", hr); + + hr = IWICBitmap_SetPalette(bitmap, palette); + ok(hr == S_OK, "SetPalette error %#lx\n", hr); + + hr = IWICBitmapFrameEncode_WriteSource(frame_encode, (IWICBitmapSource*)bitmap, NULL); + if (hr == WINCODEC_ERR_PALETTEUNAVAILABLE) + { + win_skip("old WriteSource palette behavior\n"); /* winxp */ + IWICBitmapFrameEncode_Release(frame_encode); + IWICBitmapEncoder_Release(encoder); + IStream_Release(stream); + IWICPalette_Release(palette); + IWICBitmap_Release(bitmap); + IWICImagingFactory_Release(factory); + return; + } + ok(hr == S_OK, "WriteSource error %#lx\n", hr); + + hr = IWICBitmapFrameEncode_Commit(frame_encode); + ok(hr == S_OK, "Commit error %#lx\n", hr); + + IWICBitmapFrameEncode_Release(frame_encode); + + hr = IWICBitmapEncoder_Commit(encoder); + ok(hr == S_OK, "Commit error %#lx\n", hr); + + IWICBitmapEncoder_Release(encoder); + + hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, WICDecodeMetadataCacheOnLoad, &decoder); + ok(hr == S_OK, "CreateDecoderFromStream error %#lx\n", hr); + + hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame_decode); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); + + hr = IWICBitmapFrameDecode_CopyPalette(frame_decode, palette); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); + + hr = IWICPalette_GetColors(palette, 2, result_palette, &result_colors); + ok(hr == S_OK, "GetColors error %#lx\n", hr); + ok(result_colors == 2, "Got %i colors\n", result_colors); + ok(result_palette[0] == source_palette[0], "Unexpected palette entry: %x\n", result_palette[0]); + ok(result_palette[1] == source_palette[1], "Unexpected palette entry: %x\n", result_palette[0]); + + IWICBitmapFrameDecode_Release(frame_decode); + IWICBitmapDecoder_Release(decoder); + IStream_Release(stream); + + IWICPalette_Release(palette); + IWICBitmap_Release(bitmap); + IWICImagingFactory_Release(factory); +} + +static void test_encoder_formats(void) +{ + static const struct + { + const GUID *format; + BOOL supported; + const char *name; + } + tests[] = + { + {&GUID_WICPixelFormat24bppBGR, TRUE, "WICPixelFormat24bppBGR"}, + {&GUID_WICPixelFormatBlackWhite, FALSE, "WICPixelFormatBlackWhite"}, + {&GUID_WICPixelFormat1bppIndexed, TRUE, "WICPixelFormat1bppIndexed"}, + {&GUID_WICPixelFormat2bppIndexed, FALSE, "WICPixelFormat2bppIndexed"}, + {&GUID_WICPixelFormat4bppIndexed, TRUE, "WICPixelFormat4bppIndexed"}, + {&GUID_WICPixelFormat8bppIndexed, TRUE, "WICPixelFormat8bppIndexed"}, + {&GUID_WICPixelFormat16bppBGR555, TRUE, "WICPixelFormat16bppBGR555"}, + {&GUID_WICPixelFormat16bppBGR565, TRUE, "WICPixelFormat16bppBGR565"}, + {&GUID_WICPixelFormat32bppBGR, TRUE, "WICPixelFormat32bppBGR"}, + {&GUID_WICPixelFormat32bppBGRA, TRUE, "WICPixelFormat32bppBGRA"}, + {&GUID_WICPixelFormat8bppGray, FALSE, "WICPixelFormat8bppGray"}, + }; + + IWICImagingFactory *factory; + HRESULT hr; + IStream *stream; + IWICBitmapEncoder *encoder; + IWICBitmapFrameEncode *frame_encode; + GUID pixelformat; + LONG refcount; + unsigned int i; + BOOL supported; + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICImagingFactory, (void **)&factory); + ok(hr == S_OK, "got %#lx.\n", hr); + + hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); + ok(hr == S_OK, "got %#lx.\n", hr); + + hr = IWICImagingFactory_CreateEncoder(factory, &GUID_ContainerFormatBmp, &GUID_VendorMicrosoft, &encoder); + ok(hr == S_OK, "got %#lx.\n", hr); + + hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache); + ok(hr == S_OK, "got %#lx.\n", hr); + hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frame_encode, NULL); + ok(hr == S_OK, "got %#lx.\n", hr); + hr = IWICBitmapFrameEncode_Initialize(frame_encode, NULL); + ok(hr == S_OK, "got %#lx.\n", hr); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + winetest_push_context("%s", tests[i].name); + pixelformat = *tests[i].format; + hr = IWICBitmapFrameEncode_SetPixelFormat(frame_encode, &pixelformat); + ok(hr == S_OK, "got %#lx.\n", hr); + supported = !memcmp(&pixelformat, tests[i].format, sizeof(pixelformat)); + ok(supported == tests[i].supported, "got %d.\n", supported); + winetest_pop_context(); + } + + IWICBitmapFrameEncode_Release(frame_encode); + refcount = IWICBitmapEncoder_Release(encoder); + ok(!refcount, "got %ld.\n", refcount); + IStream_Release(stream); + IWICImagingFactory_Release(factory); +} + START_TEST(bmpformat) { CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); @@ -1094,9 +1476,12 @@ START_TEST(bmpformat) test_decode_4bpp(); test_decode_rle8(); test_decode_rle4(); + test_decode_bitfields(); test_componentinfo(); test_createfromstream(); test_create_decoder(); + test_writesource_palette(); + test_encoder_formats(); CoUninitialize(); } diff --git a/modules/rostests/winetests/windowscodecs/converter.c b/modules/rostests/winetests/windowscodecs/converter.c index 348d5a8cb21..f6cef841d56 100644 --- a/modules/rostests/winetests/windowscodecs/converter.c +++ b/modules/rostests/winetests/windowscodecs/converter.c @@ -227,7 +227,7 @@ static void CreateTestBitmap(const bitmap_data *data, BitmapTestSrc **This) static void DeleteTestBitmap(BitmapTestSrc *This) { ok(This->IWICBitmapSource_iface.lpVtbl == &BitmapTestSrc_Vtbl, "test bitmap %p deleted with incorrect vtable\n", This); - ok(This->ref == 1, "test bitmap %p deleted with %i references instead of 1\n", This, This->ref); + ok(This->ref == 1, "test bitmap %p deleted with %li references instead of 1\n", This, This->ref); HeapFree(GetProcessHeap(), 0, This); } @@ -335,17 +335,17 @@ static void compare_bitmap_data(const struct bitmap_data *src, const struct bitm HRESULT hr; hr = IWICBitmapSource_GetSize(source, &width, &height); - ok(SUCCEEDED(hr), "GetSize(%s) failed, hr=%x\n", name, hr); + ok(SUCCEEDED(hr), "GetSize(%s) failed, hr=%lx\n", name, hr); ok(width == expect->width, "expecting %u, got %u (%s)\n", expect->width, width, name); ok(height == expect->height, "expecting %u, got %u (%s)\n", expect->height, height, name); hr = IWICBitmapSource_GetResolution(source, &xres, &yres); - ok(SUCCEEDED(hr), "GetResolution(%s) failed, hr=%x\n", name, hr); + ok(SUCCEEDED(hr), "GetResolution(%s) failed, hr=%lx\n", name, hr); ok(fabs(xres - expect->xres) < 0.02, "expecting %0.2f, got %0.2f (%s)\n", expect->xres, xres, name); ok(fabs(yres - expect->yres) < 0.02, "expecting %0.2f, got %0.2f (%s)\n", expect->yres, yres, name); hr = IWICBitmapSource_GetPixelFormat(source, &dst_pixelformat); - ok(SUCCEEDED(hr), "GetPixelFormat(%s) failed, hr=%x\n", name, hr); + ok(SUCCEEDED(hr), "GetPixelFormat(%s) failed, hr=%lx\n", name, hr); ok(IsEqualGUID(&dst_pixelformat, expect->format), "got unexpected pixel format %s (%s)\n", wine_dbgstr_guid(&dst_pixelformat), name); prc.X = 0; @@ -359,7 +359,7 @@ static void compare_bitmap_data(const struct bitmap_data *src, const struct bitm converted_bits = HeapAlloc(GetProcessHeap(), 0, buffersize); memset(converted_bits, 0xaa, buffersize); hr = IWICBitmapSource_CopyPixels(source, &prc, stride, buffersize, converted_bits); - ok(SUCCEEDED(hr), "CopyPixels(%s) failed, hr=%x\n", name, hr); + ok(SUCCEEDED(hr), "CopyPixels(%s) failed, hr=%lx\n", name, hr); /* The result of conversion of color to indexed formats depends on * optimized palette generation implementation. We either need to @@ -371,7 +371,7 @@ static void compare_bitmap_data(const struct bitmap_data *src, const struct bitm /* Test with NULL rectangle - should copy the whole bitmap */ memset(converted_bits, 0xaa, buffersize); hr = IWICBitmapSource_CopyPixels(source, NULL, stride, buffersize, converted_bits); - ok(SUCCEEDED(hr), "CopyPixels(%s,rc=NULL) failed, hr=%x\n", name, hr); + ok(SUCCEEDED(hr), "CopyPixels(%s,rc=NULL) failed, hr=%lx\n", name, hr); /* see comment above */ if (!(!is_indexed_format(src->format) && is_indexed_format(expect->format))) ok(compare_bits(expect, buffersize, converted_bits), "unexpected pixel data (%s)\n", name); @@ -453,13 +453,21 @@ static const BYTE bits_32bppBGR[] = { 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, - 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80}; + 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, 0,255,255,80, 255,0,255,80, 255,255,0,80, 255,255,255,80, + 3,3,3,80, 6,6,6,80, 12,12,12,80, 15,15,15,80, 19,19,19,80, 22,22,22,80, 28,28,28,80, 31,31,31,80, + 35,35,35,80, 38,38,38,80, 41,41,41,80, 47,47,47,80, 47,47,47,80, 54,54,54,80, 57,57,57,80, 63,63,63,80, + 66,66,66,80, 70,70,70,80, 73,73,73,80, 79,79,79,80, 82,82,82,80, 86,86,86,80, 89,89,89,80, 95,95,95,80, + 98,98,98,80, 98,98,98,80, 105,105,105,80, 108,108,108,80, 114,114,114,80, 117,117,117,80, 121,121,121,80, 124,124,124,80, + 130,130,130,80, 133,133,133,80, 137,137,137,80, 140,140,140,80, 146,146,146,80, 149,149,149,80, 156,156,156,80, 156,156,156,80, + 159,159,159,80, 165,165,165,80, 168,168,168,80, 172,172,172,80, 175,175,175,80, 181,181,181,80, 184,184,184,80, 188,188,188,80, + 191,191,191,80, 197,197,197,80, 200,200,200,80, 207,207,207,80, 207,207,207,80, 213,213,213,80, 216,216,216,80, 219,219,219,80, + 223,223,223,80, 226,226,226,80, 232,232,232,80, 235,235,235,80, 239,239,239,80, 242,242,242,80, 248,248,248,80, 251,251,251,80}; static const struct bitmap_data testdata_32bppBGR = { &GUID_WICPixelFormat32bppBGR, 32, bits_32bppBGR, 32, 2, 96.0, 96.0}; static const struct bitmap_data testdata_32bppBGRA80 = { - &GUID_WICPixelFormat32bppBGRA, 32, bits_32bppBGR, 32, 2, 96.0, 96.0}; + &GUID_WICPixelFormat32bppBGRA, 32, bits_32bppBGR, 32, 4, 96.0, 96.0}; static const struct bitmap_data testdata_32bppRGBA80 = { - &GUID_WICPixelFormat32bppRGBA, 32, bits_32bppBGR, 32, 2, 96.0, 96.0}; + &GUID_WICPixelFormat32bppRGBA, 32, bits_32bppBGR, 32, 4, 96.0, 96.0}; static const BYTE bits_32bppBGRA[] = { 255,0,0,255, 0,255,0,255, 0,0,255,255, 0,0,0,255, 255,0,0,255, 0,255,0,255, 0,0,255,255, 0,0,0,255, @@ -469,13 +477,31 @@ static const BYTE bits_32bppBGRA[] = { 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, - 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255}; + 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, 0,255,255,255, 255,0,255,255, 255,255,0,255, 255,255,255,255, + 3,3,3,255, 6,6,6,255, 12,12,12,255, 15,15,15,255, 19,19,19,255, 22,22,22,255, 28,28,28,255, 31,31,31,80, + 35,35,35,255, 38,38,38,255, 41,41,41,255, 47,47,47,255, 47,47,47,255, 54,54,54,255, 57,57,57,255, 63,63,63,80, + 66,66,66,255, 70,70,70,255, 73,73,73,255, 79,79,79,255, 82,82,82,255, 86,86,86,255, 89,89,89,255, 95,95,95,80, + 98,98,98,255, 98,98,98,255, 105,105,105,255, 108,108,108,255, 114,114,114,255, 117,117,117,255, 121,121,121,255, 124,124,124,80, + 130,130,130,255, 133,133,133,255, 137,137,137,255, 140,140,140,255, 146,146,146,255, 149,149,149,255, 156,156,156,255, 156,156,156,80, + 159,159,159,255, 165,165,165,255, 168,168,168,255, 172,172,172,255, 175,175,175,255, 181,181,181,255, 184,184,184,255, 188,188,188,80, + 191,191,191,255, 197,197,197,255, 200,200,200,255, 207,207,207,255, 207,207,207,255, 213,213,213,255, 216,216,216,255, 219,219,219,80, + 223,223,223,255, 226,226,226,255, 232,232,232,255, 235,235,235,255, 239,239,239,255, 242,242,242,255, 248,248,248,255, 251,251,251,80}; +static const BYTE bits_32bppRGBA[] = { + 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255, 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255, + 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255, 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255, + 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255, 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255, + 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255, 0,0,255,255, 0,255,0,255, 255,0,0,255, 0,0,0,255, + 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255, 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255, + 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255, 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255, + 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255, 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255, + 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255, 255,255,0,255, 255,0,255,255, 0,255,255,255, 255,255,255,255}; + static const struct bitmap_data testdata_32bppBGRA = { &GUID_WICPixelFormat32bppBGRA, 32, bits_32bppBGRA, 32, 2, 96.0, 96.0}; static const struct bitmap_data testdata_32bppRGBA = { - &GUID_WICPixelFormat32bppRGBA, 32, bits_32bppBGRA, 32, 2, 96.0, 96.0}; + &GUID_WICPixelFormat32bppRGBA, 32, bits_32bppRGBA, 32, 2, 96.0, 96.0}; static const struct bitmap_data testdata_32bppRGB = { - &GUID_WICPixelFormat32bppRGB, 32, bits_32bppBGRA, 32, 2, 96.0, 96.0}; + &GUID_WICPixelFormat32bppRGB, 32, bits_32bppRGBA, 32, 2, 96.0, 96.0}; static const BYTE bits_32bppPBGRA[] = { 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80, 80,0,0,80, 0,80,0,80, 0,0,80,80, 0,0,0,80, @@ -485,21 +511,29 @@ static const BYTE bits_32bppPBGRA[] = { 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, - 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80}; + 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, 0,80,80,80, 80,0,80,80, 80,80,0,80, 80,80,80,80, + 1,1,1,80, 2,2,2,80, 4,4,4,80, 5,5,5,80, 6,6,6,80, 7,7,7,80, 9,9,9,80, 10,10,10,80, + 11,11,11,80, 12,12,12,80, 13,13,13,80, 15,15,15,80, 15,15,15,80, 17,17,17,80, 18,18,18,80, 20,20,20,80, + 21,21,21,80, 22,22,22,80, 23,23,23,80, 25,25,25,80, 26,26,26,80, 27,27,27,80, 28,28,28,80, 30,30,30,80, + 31,31,31,80, 31,31,31,80, 33,33,33,80, 34,34,34,80, 36,36,36,80, 37,37,37,80, 38,38,38,80, 39,39,39,80, + 41,41,41,80, 42,42,42,80, 43,43,43,80, 44,44,44,80, 46,46,46,80, 47,47,47,80, 49,49,49,80, 49,49,49,80, + 50,50,50,80, 52,52,52,80, 53,53,53,80, 54,54,54,80, 55,55,55,80, 57,57,57,80, 58,58,58,80, 59,59,59,80, + 60,60,60,80, 62,62,62,80, 63,63,63,80, 65,65,65,80, 65,65,65,80, 67,67,67,80, 68,68,68,80, 69,69,69,80, + 70,70,70,80, 71,71,71,80, 73,73,73,80, 74,74,74,80, 75,75,75,80, 76,76,76,80, 78,78,78,80, 79,79,79,80}; static const struct bitmap_data testdata_32bppPBGRA = { - &GUID_WICPixelFormat32bppPBGRA, 32, bits_32bppPBGRA, 32, 2, 96.0, 96.0}; + &GUID_WICPixelFormat32bppPBGRA, 32, bits_32bppPBGRA, 32, 4, 96.0, 96.0}; static const struct bitmap_data testdata_32bppPRGBA = { - &GUID_WICPixelFormat32bppPRGBA, 32, bits_32bppPBGRA, 32, 2, 96.0, 96.0}; + &GUID_WICPixelFormat32bppPRGBA, 32, bits_32bppPBGRA, 32, 4, 96.0, 96.0}; static const BYTE bits_64bppRGBA[] = { - 128,255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255,128, 255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255, - 128,255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255,128, 255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255, - 128,255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255,128, 255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255, - 128,255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255,128, 255,128,0,128,0,128,255,128, 0,128,255,128,0,128,255,128, 0,128,0,128,255,128,255,128, 0,128,0,128,0,128,255, - 128,0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255,128, 0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255, - 128,0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255,128, 0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255, - 128,0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255,128, 0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255, - 128,0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255,128, 0,128,255,128,255,128,255,128, 255,128,0,128,255,128,255,128, 255,128,255,128,0,128,255,128, 255,128,255,128,255,128,255}; + 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255, 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255, + 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255, 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255, + 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255, 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255, + 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255, 128,0,128,0,128,255,128,255, 128,0,128,255,128,0,128,255, 128,255,128,0,128,0,128,255, 128,0,128,0,128,0,128,255, + 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255, 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255, + 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255, 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255, + 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255, 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255, + 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255, 128,255,128,255,128,0,128,255, 128,255,128,0,128,255,128,255, 128,0,128,255,128,255,128,255, 128,255,128,255,128,255,128,255}; static const struct bitmap_data testdata_64bppRGBA = { &GUID_WICPixelFormat64bppRGBA, 64, bits_64bppRGBA, 32, 2, 96.0, 96.0}; @@ -528,6 +562,18 @@ static const float bits_32bppGrayFloat[] = { static const struct bitmap_data testdata_32bppGrayFloat = { &GUID_WICPixelFormat32bppGrayFloat, 32, (const BYTE *)bits_32bppGrayFloat, 32, 2, 96.0, 96.0, &testdata_32bppGrayFloat_xp}; +static const BYTE bits_4bppGray_xp[] = { + 77,112,77,112,77,112,77,112,77,112,77,112,77,112,77,112,249, + 239,249,239,249,239,249,239,249,239,249,239,249,239,249,239}; +static const struct bitmap_data testdata_4bppGray_xp = { + &GUID_WICPixelFormat4bppGray, 4, bits_4bppGray_xp, 32, 2, 96.0, 96.0}; + +static const BYTE bits_4bppGray[] = { + 77,112,77,112,77,112,77,112,77,112,77,112,77,112,77,112,249, + 239,249,239,249,239,249,239,249,239,249,239,249,239,249,239}; +static const struct bitmap_data testdata_4bppGray = { + &GUID_WICPixelFormat4bppGray, 4, bits_4bppGray, 32, 2, 96.0, 96.0, &testdata_4bppGray_xp}; + static const BYTE bits_8bppGray_xp[] = { 29,150,76,0,29,150,76,0,29,150,76,0,29,150,76,0, 29,150,76,0,29,150,76,0,29,150,76,0,29,150,76,0, @@ -556,6 +602,40 @@ static const BYTE bits_24bppBGR_gray[] = { static const struct bitmap_data testdata_24bppBGR_gray = { &GUID_WICPixelFormat24bppBGR, 24, bits_24bppBGR_gray, 32, 2, 96.0, 96.0}; +#define TO_16bppBGRA5551(b,g,r,a) ( \ + ((a >> 7) << 15) | \ + ((r >> 3) << 10) | \ + ((g >> 3) << 5) | \ + ((b >> 3)) \ +) + +static const WORD bits_16bppBGRA5551[] = { + TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255), TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255), + TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255), TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255), + TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255), TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255), + TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255), TO_16bppBGRA5551(255,0,0,255), TO_16bppBGRA5551(0,255,0,255), TO_16bppBGRA5551(0,0,255,255), TO_16bppBGRA5551(0,0,0,255), + TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255), TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255), + TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255), TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255), + TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255), TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255), + TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255), TO_16bppBGRA5551(0,255,255,255), TO_16bppBGRA5551(255,0,255,255), TO_16bppBGRA5551(255,255,0,255), TO_16bppBGRA5551(255,255,255,255)}; + +static const struct bitmap_data testdata_16bppBGRA5551 = { + &GUID_WICPixelFormat16bppBGRA5551, 16, (BYTE*)bits_16bppBGRA5551, 32, 2, 96.0, 96.0}; + +static const WORD bits_48bppRGB[] = { + 0,0,0, 0,65535,0, 32767,32768,32767, + 65535,65535,65535, 10,10,10, 0,0,10}; + +static const struct bitmap_data testdata_48bppRGB = { + &GUID_WICPixelFormat48bppRGB, 48, (BYTE*)bits_48bppRGB, 3, 2, 96.0, 96.0}; + +static const WORD bits_64bppRGBA_2[] = { + 0,0,0,65535, 0,65535,0,65535, 32767,32768,32767,65535, + 65535,65535,65535,65535, 10,10,10,65535, 0,0,10,65535,}; + +static const struct bitmap_data testdata_64bppRGBA_2 = { + &GUID_WICPixelFormat64bppRGBA, 64, (BYTE*)bits_64bppRGBA_2, 3, 2, 96.0, 96.0}; + static void test_conversion(const struct bitmap_data *src, const struct bitmap_data *dst, const char *name, BOOL todo) { BitmapTestSrc *src_obj; @@ -567,7 +647,7 @@ static void test_conversion(const struct bitmap_data *src, const struct bitmap_d hr = WICConvertBitmapSource(dst->format, &src_obj->IWICBitmapSource_iface, &dst_bitmap); todo_wine_if (todo) ok(hr == S_OK || - broken(hr == E_INVALIDARG || hr == WINCODEC_ERR_COMPONENTNOTFOUND) /* XP */, "WICConvertBitmapSource(%s) failed, hr=%x\n", name, hr); + broken(hr == E_INVALIDARG || hr == WINCODEC_ERR_COMPONENTNOTFOUND) /* XP */, "WICConvertBitmapSource(%s) failed, hr=%lx\n", name, hr); if (hr == S_OK) { @@ -589,7 +669,7 @@ static void test_invalid_conversion(void) /* convert to a non-pixel-format GUID */ hr = WICConvertBitmapSource(&GUID_VendorMicrosoft, &src_obj->IWICBitmapSource_iface, &dst_bitmap); - ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "WICConvertBitmapSource returned %x\n", hr); + ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "WICConvertBitmapSource returned %lx\n", hr); DeleteTestBitmap(src_obj); } @@ -605,18 +685,18 @@ static void test_default_converter(void) hr = CoCreateInstance(&CLSID_WICDefaultFormatConverter, NULL, CLSCTX_INPROC_SERVER, &IID_IWICFormatConverter, (void**)&converter); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICFormatConverter_CanConvert(converter, &GUID_WICPixelFormat32bppBGRA, &GUID_WICPixelFormat32bppBGR, &can_convert); - ok(SUCCEEDED(hr), "CanConvert returned %x\n", hr); + ok(SUCCEEDED(hr), "CanConvert returned %lx\n", hr); ok(can_convert, "expected TRUE, got %i\n", can_convert); hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, &GUID_WICPixelFormat32bppBGR, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeCustom); - ok(SUCCEEDED(hr), "Initialize returned %x\n", hr); + ok(SUCCEEDED(hr), "Initialize returned %lx\n", hr); if (SUCCEEDED(hr)) compare_bitmap_data(&testdata_32bppBGRA, &testdata_32bppBGR, (IWICBitmapSource*)converter, "default converter"); @@ -627,6 +707,72 @@ static void test_default_converter(void) DeleteTestBitmap(src_obj); } +static void test_converter_4bppGray(void) +{ + BitmapTestSrc *src_obj; + IWICFormatConverter *converter; + BOOL can_convert = TRUE; + HRESULT hr; + + CreateTestBitmap(&testdata_32bppBGRA, &src_obj); + + hr = CoCreateInstance(&CLSID_WICDefaultFormatConverter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICFormatConverter, (void**)&converter); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); + if (SUCCEEDED(hr)) + { + hr = IWICFormatConverter_CanConvert(converter, &GUID_WICPixelFormat32bppBGRA, + &GUID_WICPixelFormat4bppGray, &can_convert); + ok(SUCCEEDED(hr), "CanConvert returned %lx\n", hr); + todo_wine ok(can_convert, "expected TRUE, got %i\n", can_convert); + + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat4bppGray, WICBitmapDitherTypeNone, NULL, 0.0, + WICBitmapPaletteTypeCustom); + todo_wine ok(SUCCEEDED(hr), "Initialize returned %lx\n", hr); + + if (SUCCEEDED(hr)) + compare_bitmap_data(&testdata_32bppBGRA, &testdata_4bppGray, (IWICBitmapSource*)converter, "4bppGray converter"); + + IWICFormatConverter_Release(converter); + } + + DeleteTestBitmap(src_obj); +} + +static void test_converter_8bppGray(void) +{ + BitmapTestSrc *src_obj; + IWICFormatConverter *converter; + BOOL can_convert = TRUE; + HRESULT hr; + + CreateTestBitmap(&testdata_32bppBGRA, &src_obj); + + hr = CoCreateInstance(&CLSID_WICDefaultFormatConverter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICFormatConverter, (void**)&converter); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); + if (SUCCEEDED(hr)) + { + hr = IWICFormatConverter_CanConvert(converter, &GUID_WICPixelFormat32bppBGRA, + &GUID_WICPixelFormat8bppGray, &can_convert); + ok(SUCCEEDED(hr), "CanConvert returned %lx\n", hr); + ok(can_convert, "expected TRUE, got %i\n", can_convert); + + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat8bppGray, WICBitmapDitherTypeNone, NULL, 0.0, + WICBitmapPaletteTypeCustom); + ok(SUCCEEDED(hr), "Initialize returned %lx\n", hr); + + if (SUCCEEDED(hr)) + compare_bitmap_data(&testdata_32bppBGRA, &testdata_8bppGray, (IWICBitmapSource*)converter, "8bppGray converter"); + + IWICFormatConverter_Release(converter); + } + + DeleteTestBitmap(src_obj); +} + typedef struct property_opt_test_data { LPCOLESTR name; @@ -715,13 +861,13 @@ static void test_specific_encoder_properties(IPropertyBag2 *options, const prope { ok(all_props[idx].vt == data[i].var_type, "Property %s has unexpected vt type, vt=%i\n", wine_dbgstr_w(data[i].name), all_props[idx].vt); - ok(all_props[idx].dwType == PROPBAG2_TYPE_DATA, "Property %s has unexpected dw type, vt=%i\n", + ok(all_props[idx].dwType == PROPBAG2_TYPE_DATA, "Property %s has unexpected dw type, vt=%li\n", wine_dbgstr_w(data[i].name), all_props[idx].dwType); ok(all_props[idx].cfType == 0, "Property %s has unexpected cf type, vt=%i\n", wine_dbgstr_w(data[i].name), all_props[idx].cfType); } - ok(SUCCEEDED(hr), "Reading property %s from bag failed, hr=%x\n", + ok(SUCCEEDED(hr), "Reading property %s from bag failed, hr=%lx\n", wine_dbgstr_w(data[i].name), hr); if (SUCCEEDED(hr)) @@ -767,16 +913,16 @@ static void test_encoder_properties(const CLSID* clsid_encoder, IPropertyBag2 *o /* CountProperties */ { hr = IPropertyBag2_CountProperties(options, &cProperties); - ok(SUCCEEDED(hr), "Reading property count, hr=%x\n", hr); + ok(SUCCEEDED(hr), "Reading property count, hr=%lx\n", hr); } /* GetPropertyInfo */ { hr = IPropertyBag2_GetPropertyInfo(options, cProperties, 1, all_props, &cProperties2); - ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "IPropertyBag2::GetPropertyInfo - iProperty out of bounce handled wrong, hr=%x\n", hr); + ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "IPropertyBag2::GetPropertyInfo - iProperty out of bounce handled wrong, hr=%lx\n", hr); hr = IPropertyBag2_GetPropertyInfo(options, 0, cProperties+1, all_props, &cProperties2); - ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "IPropertyBag2::GetPropertyInfo - cProperty out of bounce handled wrong, hr=%x\n", hr); + ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "IPropertyBag2::GetPropertyInfo - cProperty out of bounce handled wrong, hr=%lx\n", hr); if (cProperties == 0) /* GetPropertyInfo can be called for zero items on Windows 8 but not on Windows 7 (wine behaves like Win8) */ { @@ -786,7 +932,7 @@ static void test_encoder_properties(const CLSID* clsid_encoder, IPropertyBag2 *o else { hr = IPropertyBag2_GetPropertyInfo(options, 0, min(64, cProperties), all_props, &cProperties2); - ok(SUCCEEDED(hr), "Reading infos from property bag failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "Reading infos from property bag failed, hr=%lx\n", hr); } if (FAILED(hr)) @@ -816,17 +962,12 @@ static void load_stream(IUnknown *reader, IStream *stream) { HRESULT hr; IWICPersistStream *persist; -#ifdef WORDS_BIGENDIAN - DWORD persist_options = WICPersistOptionBigEndian; -#else - DWORD persist_options = WICPersistOptionLittleEndian; -#endif hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); - ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryInterface failed, hr=%lx\n", hr); - hr = IWICPersistStream_LoadEx(persist, stream, NULL, persist_options); - ok(hr == S_OK, "LoadEx failed, hr=%x\n", hr); + hr = IWICPersistStream_LoadEx(persist, stream, NULL, 0); + ok(hr == S_OK, "LoadEx failed, hr=%lx\n", hr); IWICPersistStream_Release(persist); } @@ -856,23 +997,23 @@ static void check_tiff_format(IStream *stream, const WICPixelFormatGUID *format) memset(&tiff, 0, sizeof(tiff)); hr = IStream_Read(stream, &tiff, sizeof(tiff), NULL); - ok(hr == S_OK, "IStream_Read error %#x\n", hr); + ok(hr == S_OK, "IStream_Read error %#lx\n", hr); ok(tiff.byte_order == MAKEWORD('I','I') || tiff.byte_order == MAKEWORD('M','M'), "wrong TIFF byte order mark %02x\n", tiff.byte_order); ok(tiff.version == 42, "wrong TIFF version %u\n", tiff.version); pos.QuadPart = tiff.dir_offset; hr = IStream_Seek(stream, pos, SEEK_SET, NULL); - ok(hr == S_OK, "IStream_Seek error %#x\n", hr); + ok(hr == S_OK, "IStream_Seek error %#lx\n", hr); hr = CoCreateInstance(&CLSID_WICIfdMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void **)&reader); - ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); load_stream((IUnknown *)reader, stream); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count != 0, "wrong count %u\n", count); for (i = 0; i < ARRAY_SIZE(tag); i++) @@ -881,14 +1022,14 @@ static void check_tiff_format(IStream *stream, const WICPixelFormatGUID *format) PropVariantInit(&value); id.vt = VT_UI2; - U(id).uiVal = tag[i].id; + id.uiVal = tag[i].id; hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value); ok(hr == S_OK || (tag[i].id == 0x140 && hr == WINCODEC_ERR_PROPERTYNOTFOUND), - "GetValue(%04x) error %#x\n", tag[i].id, hr); + "GetValue(%04x) error %#lx\n", tag[i].id, hr); if (hr == S_OK) { ok(value.vt == VT_UI2 || value.vt == VT_UI4 || value.vt == (VT_UI2 | VT_VECTOR), "wrong vt: %d\n", value.vt); - tag[i].value[0] = U(value).uiVal; + tag[i].value[0] = value.uiVal; } else tag[i].value[0] = -1; @@ -959,62 +1100,62 @@ static void check_bmp_format(IStream *stream, const WICPixelFormatGUID *format) BITMAPV5HEADER bih; hr = IStream_Read(stream, &bfh, sizeof(bfh), NULL); - ok(hr == S_OK, "IStream_Read error %#x\n", hr); + ok(hr == S_OK, "IStream_Read error %#lx\n", hr); ok(bfh.bfType == 0x4d42, "wrong BMP signature %02x\n", bfh.bfType); ok(bfh.bfReserved1 == 0, "wrong bfReserved1 %02x\n", bfh.bfReserved1); ok(bfh.bfReserved2 == 0, "wrong bfReserved2 %02x\n", bfh.bfReserved2); hr = IStream_Read(stream, &bih, sizeof(bih), NULL); - ok(hr == S_OK, "IStream_Read error %#x\n", hr); + ok(hr == S_OK, "IStream_Read error %#lx\n", hr); if (IsEqualGUID(format, &GUID_WICPixelFormat1bppIndexed)) { - ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08x\n", bfh.bfOffBits); + ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08lx\n", bfh.bfOffBits); - ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width); - ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height); + ok(bih.bV5Width == 32, "wrong width %lu\n", bih.bV5Width); + ok(bih.bV5Height == 2, "wrong height %lu\n", bih.bV5Height); ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes); ok(bih.bV5BitCount == 1, "wrong BitCount %d\n", bih.bV5BitCount); - ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %d\n", bih.bV5ClrUsed); - ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %d\n", bih.bV5ClrImportant); + ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %ld\n", bih.bV5ClrUsed); + ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %ld\n", bih.bV5ClrImportant); } else if (IsEqualGUID(format, &GUID_WICPixelFormat4bppIndexed)) { - ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08x\n", bfh.bfOffBits); + ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08lx\n", bfh.bfOffBits); - ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width); - ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height); + ok(bih.bV5Width == 32, "wrong width %lu\n", bih.bV5Width); + ok(bih.bV5Height == 2, "wrong height %lu\n", bih.bV5Height); ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes); ok(bih.bV5BitCount == 4, "wrong BitCount %d\n", bih.bV5BitCount); - ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %d\n", bih.bV5ClrUsed); - ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %d\n", bih.bV5ClrImportant); + ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %ld\n", bih.bV5ClrUsed); + ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %ld\n", bih.bV5ClrImportant); } else if (IsEqualGUID(format, &GUID_WICPixelFormat8bppIndexed)) { - ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08x\n", bfh.bfOffBits); + ok(bfh.bfOffBits == 0x0436, "wrong bfOffBits %08lx\n", bfh.bfOffBits); - ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width); - ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height); + ok(bih.bV5Width == 32, "wrong width %lu\n", bih.bV5Width); + ok(bih.bV5Height == 2, "wrong height %lu\n", bih.bV5Height); ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes); ok(bih.bV5BitCount == 8, "wrong BitCount %d\n", bih.bV5BitCount); - ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %d\n", bih.bV5ClrUsed); - ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %d\n", bih.bV5ClrImportant); + ok(bih.bV5ClrUsed == 256, "wrong ClrUsed %ld\n", bih.bV5ClrUsed); + ok(bih.bV5ClrImportant == 256, "wrong ClrImportant %ld\n", bih.bV5ClrImportant); } else if (IsEqualGUID(format, &GUID_WICPixelFormat32bppBGR)) { - ok(bfh.bfOffBits == 0x0036, "wrong bfOffBits %08x\n", bfh.bfOffBits); + ok(bfh.bfOffBits == 0x0036, "wrong bfOffBits %08lx\n", bfh.bfOffBits); - ok(bih.bV5Width == 32, "wrong width %u\n", bih.bV5Width); - ok(bih.bV5Height == 2, "wrong height %u\n", bih.bV5Height); + ok(bih.bV5Width == 32, "wrong width %lu\n", bih.bV5Width); + ok(bih.bV5Height == 2, "wrong height %lu\n", bih.bV5Height); ok(bih.bV5Planes == 1, "wrong Planes %d\n", bih.bV5Planes); ok(bih.bV5BitCount == 32, "wrong BitCount %d\n", bih.bV5BitCount); - ok(bih.bV5ClrUsed == 0, "wrong ClrUsed %d\n", bih.bV5ClrUsed); - ok(bih.bV5ClrImportant == 0, "wrong ClrImportant %d\n", bih.bV5ClrImportant); + ok(bih.bV5ClrUsed == 0, "wrong ClrUsed %ld\n", bih.bV5ClrUsed); + ok(bih.bV5ClrImportant == 0, "wrong ClrImportant %ld\n", bih.bV5ClrImportant); } else ok(0, "unknown BMP pixel format %s\n", wine_dbgstr_guid(format)); @@ -1047,7 +1188,7 @@ static void check_png_format(IStream *stream, const WICPixelFormatGUID *format) memset(&png, 0, sizeof(png)); hr = IStream_Read(stream, &png, sizeof(png), NULL); - ok(hr == S_OK, "IStream_Read error %#x\n", hr); + ok(hr == S_OK, "IStream_Read error %#lx\n", hr); ok(!memcmp(png.png_sig, png_sig, sizeof(png_sig)), "expected PNG signature\n"); ok(!memcmp(png.ihdr_sig, png_IHDR, sizeof(png_IHDR)), "expected PNG IHDR\n"); @@ -1145,7 +1286,7 @@ static void check_gif_format(IStream *stream, const WICPixelFormatGUID *format) memset(&lsd, 0, sizeof(lsd)); hr = IStream_Read(stream, &lsd, sizeof(lsd), NULL); - ok(hr == S_OK, "IStream_Read error %#x\n", hr); + ok(hr == S_OK, "IStream_Read error %#lx\n", hr); ok(!memcmp(lsd.signature, "GIF89a", 6), "wrong GIF signature %.6s\n", lsd.signature); @@ -1163,7 +1304,7 @@ static void check_bitmap_format(IStream *stream, const CLSID *encoder, const WIC pos.QuadPart = 0; hr = IStream_Seek(stream, pos, SEEK_SET, (ULARGE_INTEGER *)&pos); - ok(hr == S_OK, "IStream_Seek error %#x\n", hr); + ok(hr == S_OK, "IStream_Seek error %#lx\n", hr); if (IsEqualGUID(encoder, &CLSID_WICPngEncoder)) check_png_format(stream, format); @@ -1177,7 +1318,7 @@ static void check_bitmap_format(IStream *stream, const CLSID *encoder, const WIC ok(0, "unknown encoder %s\n", wine_dbgstr_guid(encoder)); hr = IStream_Seek(stream, pos, SEEK_SET, NULL); - ok(hr == S_OK, "IStream_Seek error %#x\n", hr); + ok(hr == S_OK, "IStream_Seek error %#lx\n", hr); } struct setting { @@ -1193,7 +1334,7 @@ static void _expect_ref(IUnknown* obj, ULONG ref, int line) ULONG rc; IUnknown_AddRef(obj); rc = IUnknown_Release(obj); - ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc); + ok_(__FILE__,line)(rc == ref, "expected refcount %ld, got %ld\n", ref, rc); } static void test_set_frame_palette(IWICBitmapFrameEncode *frameencode) @@ -1204,36 +1345,36 @@ static void test_set_frame_palette(IWICBitmapFrameEncode *frameencode) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICComponentFactory, (void **)&factory); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); hr = IWICBitmapFrameEncode_SetPalette(frameencode, NULL); - ok(hr == E_INVALIDARG, "SetPalette failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "SetPalette failed, hr=%lx\n", hr); hr = IWICComponentFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette failed, hr=%x\n", hr); + ok(hr == S_OK, "CreatePalette failed, hr=%lx\n", hr); hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette); -todo_wine - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr=%x\n", hr); + todo_wine + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "Unexpected hr=%lx\n", hr); hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedHalftone256, FALSE); - ok(hr == S_OK, "InitializePredefined failed, hr=%x\n", hr); + ok(hr == S_OK, "InitializePredefined failed, hr=%lx\n", hr); EXPECT_REF(palette, 1); hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette); - ok(hr == S_OK, "SetPalette failed, hr=%x\n", hr); + ok(hr == S_OK, "SetPalette failed, hr=%lx\n", hr); EXPECT_REF(palette, 1); hr = IWICBitmapFrameEncode_SetPalette(frameencode, NULL); - ok(hr == E_INVALIDARG, "SetPalette failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "SetPalette failed, hr=%lx\n", hr); IWICPalette_Release(palette); IWICComponentFactory_Release(factory); } -static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* clsid_encoder, +static void test_multi_encoder_impl(const struct bitmap_data **srcs, const CLSID* clsid_encoder, const struct bitmap_data **dsts, const CLSID *clsid_decoder, WICRect *rc, - const struct setting *settings, const char *name, IWICPalette *palette) + const struct setting *settings, const char *name, IWICPalette *palette, BOOL set_size) { const GUID *container_format = NULL; HRESULT hr; @@ -1251,13 +1392,13 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls hr = CoCreateInstance(clsid_encoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapEncoder, (void **)&encoder); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); - ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); hr = IWICBitmapEncoder_GetContainerFormat(encoder, NULL); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); if (IsEqualGUID(clsid_encoder, &CLSID_WICPngEncoder)) container_format = &GUID_ContainerFormatPng; @@ -1267,6 +1408,8 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls container_format = &GUID_ContainerFormatTiff; else if (IsEqualGUID(clsid_encoder, &CLSID_WICJpegEncoder)) container_format = &GUID_ContainerFormatJpeg; + else if (IsEqualGUID(clsid_encoder, &CLSID_WICGifEncoder)) + container_format = &GUID_ContainerFormatGif; else ok(0, "Unknown encoder %s.\n", wine_dbgstr_guid(clsid_encoder)); @@ -1274,16 +1417,16 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls { memset(&guid, 0, sizeof(guid)); hr = IWICBitmapEncoder_GetContainerFormat(encoder, &guid); - ok(SUCCEEDED(hr), "Failed to get container format, hr %#x.\n", hr); + ok(SUCCEEDED(hr), "Failed to get container format, hr %#lx.\n", hr); ok(IsEqualGUID(container_format, &guid), "Unexpected container format %s.\n", wine_dbgstr_guid(&guid)); } hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache); - ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "Initialize failed, hr=%lx\n", hr); /* Encoder options are optional. */ hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frameencode, NULL); - ok(SUCCEEDED(hr), "Failed to create encode frame, hr %#x.\n", hr); + ok(SUCCEEDED(hr), "Failed to create encode frame, hr %#lx.\n", hr); IStream_Release(stream); IWICBitmapEncoder_Release(encoder); @@ -1291,7 +1434,7 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls hr = CoCreateInstance(clsid_encoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapEncoder, (void**)&encoder); - ok(SUCCEEDED(hr), "CoCreateInstance(%s) failed, hr=%x\n", wine_dbgstr_guid(clsid_encoder), hr); + ok(SUCCEEDED(hr), "CoCreateInstance(%s) failed, hr=%lx\n", wine_dbgstr_guid(clsid_encoder), hr); if (SUCCEEDED(hr)) { hglobal = GlobalAlloc(GMEM_MOVEABLE, 0); @@ -1299,53 +1442,37 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls if (hglobal) { hr = CreateStreamOnHGlobal(hglobal, TRUE, &stream); - ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); } if (hglobal && SUCCEEDED(hr)) { - IWICBitmapEncoderInfo *info = NULL; - if (palette) { hr = IWICBitmapEncoder_SetPalette(encoder, palette); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "wrong error %#x (%s)\n", hr, name); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "wrong error %#lx (%s)\n", hr, name); } hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache); - ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "Initialize failed, hr=%lx\n", hr); if (palette) { hr = IWICBitmapEncoder_SetPalette(encoder, palette); if (IsEqualGUID(clsid_encoder, &CLSID_WICGifEncoder)) - ok(hr == S_OK, "SetPalette failed, hr=%#x\n", hr); + ok(hr == S_OK, "SetPalette failed, hr=%#lx\n", hr); else - ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "wrong error %#x\n", hr); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "wrong error %#lx\n", hr); hr = S_OK; } - hr = IWICBitmapEncoder_GetEncoderInfo(encoder, &info); - ok(hr == S_OK || hr == WINCODEC_ERR_COMPONENTNOTFOUND, "wrong error %#x\n", hr); - if (SUCCEEDED(hr)) - { - CLSID clsid; - - hr = IWICBitmapEncoderInfo_GetCLSID(info, &clsid); - ok(hr == S_OK, "wrong error %#x\n", hr); - ok(!IsEqualGUID(clsid_encoder, &clsid), "wrong CLSID %s (%s)\n", - wine_dbgstr_guid(clsid_encoder), wine_dbgstr_guid(&clsid)); - - IWICBitmapEncoderInfo_Release(info); - } - i=0; while (SUCCEEDED(hr) && srcs[i]) { CreateTestBitmap(srcs[i], &src_obj); hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frameencode, &options); - ok(SUCCEEDED(hr), "CreateFrame failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateFrame failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { ok(options != NULL, "Encoder initialization has not created an property bag\n"); @@ -1368,70 +1495,75 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls V_UNKNOWN(&var) = settings[j].value; hr = IPropertyBag2_Write(options, 1, &propbag, &var); - ok(SUCCEEDED(hr), "Writing property %s failed, hr=%x\n", wine_dbgstr_w(settings[j].name), hr); + ok(SUCCEEDED(hr), "Writing property %s failed, hr=%lx\n", wine_dbgstr_w(settings[j].name), hr); } } if (palette) { hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "wrong error %#x\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "wrong error %#lx\n", hr); } hr = IWICBitmapFrameEncode_Initialize(frameencode, options); - ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "Initialize failed, hr=%lx\n", hr); memcpy(&pixelformat, srcs[i]->format, sizeof(GUID)); hr = IWICBitmapFrameEncode_SetPixelFormat(frameencode, &pixelformat); - ok(SUCCEEDED(hr), "SetPixelFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "SetPixelFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&pixelformat, dsts[i]->format) || (IsEqualGUID(clsid_encoder, &CLSID_WICTiffEncoder) && srcs[i]->bpp == 2 && IsEqualGUID(&pixelformat, &GUID_WICPixelFormat4bppIndexed)) || (IsEqualGUID(clsid_encoder, &CLSID_WICBmpEncoder) && srcs[i]->bpp == 2 && IsEqualGUID(&pixelformat, &GUID_WICPixelFormat4bppIndexed)), "SetPixelFormat changed the format to %s (%s)\n", wine_dbgstr_guid(&pixelformat), name); - hr = IWICBitmapFrameEncode_SetSize(frameencode, srcs[i]->width, srcs[i]->height); - ok(SUCCEEDED(hr), "SetSize failed, hr=%x\n", hr); + if (set_size) + { + hr = IWICBitmapFrameEncode_SetSize(frameencode, srcs[i]->width, srcs[i]->height); + ok(hr == S_OK, "SetSize failed, hr=%lx\n", hr); + } if (IsEqualGUID(clsid_encoder, &CLSID_WICPngEncoder)) test_set_frame_palette(frameencode); if (palette) { - WICColor colors[256]; - hr = IWICBitmapFrameEncode_SetPalette(frameencode, palette); - ok(SUCCEEDED(hr), "SetPalette failed, hr=%x (%s)\n", hr, name); - - /* trash the assigned palette */ - memset(colors, 0, sizeof(colors)); - hr = IWICPalette_InitializeCustom(palette, colors, 256); - ok(hr == S_OK, "InitializeCustom error %#x\n", hr); + ok(SUCCEEDED(hr), "SetPalette failed, hr=%lx (%s)\n", hr, name); } hr = IWICBitmapFrameEncode_WriteSource(frameencode, &src_obj->IWICBitmapSource_iface, rc); if (rc && (rc->Width <= 0 || rc->Height <= 0)) { /* WriteSource fails but WriteSource_Proxy succeeds. */ - ok(hr == E_INVALIDARG, "WriteSource should fail, hr=%x (%s)\n", hr, name); + ok(hr == E_INVALIDARG, "WriteSource should fail, hr=%lx (%s)\n", hr, name); hr = IWICBitmapFrameEncode_WriteSource_Proxy(frameencode, &src_obj->IWICBitmapSource_iface, rc); - ok(SUCCEEDED(hr), "WriteSource_Proxy failed, %dx%d, hr=%x (%s)\n", rc->Width, rc->Height, hr, name); + if (!set_size && rc->Width < 0) + todo_wine + ok(hr == WINCODEC_ERR_SOURCERECTDOESNOTMATCHDIMENSIONS || + hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW) /* win11 */, + "WriteSource_Proxy(%dx%d) got unexpected hr %lx (%s)\n", rc->Width, rc->Height, hr, name); + else + ok(hr == S_OK, "WriteSource_Proxy failed, %dx%d, hr=%lx (%s)\n", rc->Width, rc->Height, hr, name); } else { if (rc) - ok(SUCCEEDED(hr), "WriteSource(%dx%d) failed, hr=%x (%s)\n", rc->Width, rc->Height, hr, name); + ok(SUCCEEDED(hr), "WriteSource(%dx%d) failed, hr=%lx (%s)\n", rc->Width, rc->Height, hr, name); else - ok(hr == S_OK || - (FAILED(hr) && IsEqualGUID(clsid_encoder, &CLSID_WICBmpEncoder) && srcs[i]->bpp == 2) /* XP */ || - (FAILED(hr) && IsEqualGUID(clsid_encoder, &CLSID_WICTiffEncoder) && srcs[i]->bpp == 2) /* XP */ || - broken(hr == E_INVALIDARG && IsEqualGUID(clsid_encoder, &CLSID_WICBmpEncoder) && IsEqualGUID(srcs[i]->format, &GUID_WICPixelFormatBlackWhite)) /* XP */, - "WriteSource(NULL) failed, hr=%x (%s)\n", hr, name); + todo_wine_if((IsEqualGUID(clsid_encoder, &CLSID_WICTiffEncoder) && srcs[i]->bpp == 2) || + (IsEqualGUID(clsid_encoder, &CLSID_WICBmpEncoder) && srcs[i]->bpp == 2)) + ok(hr == S_OK, "WriteSource(NULL) failed, hr=%lx (%s)\n", hr, name); + } if (SUCCEEDED(hr)) { hr = IWICBitmapFrameEncode_Commit(frameencode); - ok(SUCCEEDED(hr), "Commit failed, hr=%x (%s)\n", hr, name); + if (!set_size && rc && rc->Height < 0) + todo_wine + ok(hr == WINCODEC_ERR_UNEXPECTEDSIZE, "Commit got unexpected hr %lx (%s)\n", hr, name); + else + ok(hr == S_OK, "Commit failed, hr=%lx (%s)\n", hr, name); } IWICBitmapFrameEncode_Release(frameencode); @@ -1453,7 +1585,7 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls if (SUCCEEDED(hr)) { hr = IWICBitmapEncoder_Commit(encoder); - ok(SUCCEEDED(hr), "Commit failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "Commit failed, hr=%lx\n", hr); if (IsEqualGUID(&pixelformat, dsts[0]->format)) check_bitmap_format(stream, clsid_encoder, dsts[0]->format); @@ -1463,7 +1595,7 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls { hr = CoCreateInstance(clsid_decoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); } if (SUCCEEDED(hr)) @@ -1471,57 +1603,57 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls IWICPalette *frame_palette; hr = IWICImagingFactory_CreatePalette(factory, &frame_palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICBitmapDecoder_CopyPalette(decoder, frame_palette); if (IsEqualGUID(clsid_decoder, &CLSID_WICGifDecoder)) - ok(hr == WINCODEC_ERR_WRONGSTATE, "wrong error %#x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "wrong error %#lx\n", hr); else - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#lx\n", hr); hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand); - ok(SUCCEEDED(hr), "Initialize failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "Initialize failed, hr=%lx\n", hr); hr = IWICBitmapDecoder_CopyPalette(decoder, frame_palette); if (IsEqualGUID(clsid_decoder, &CLSID_WICGifDecoder)) - ok(hr == S_OK || broken(hr == WINCODEC_ERR_FRAMEMISSING) /* XP */, "CopyPalette failed, hr=%#x\n", hr); + ok(hr == S_OK || broken(hr == WINCODEC_ERR_FRAMEMISSING) /* XP */, "CopyPalette failed, hr=%#lx\n", hr); else - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#lx\n", hr); hr = S_OK; i=0; while (SUCCEEDED(hr) && dsts[i]) { hr = IWICBitmapDecoder_GetFrame(decoder, i, &framedecode); - ok(SUCCEEDED(hr), "GetFrame failed, hr=%x (%s)\n", hr, name); + ok(SUCCEEDED(hr), "GetFrame failed, hr=%lx (%s)\n", hr, name); if (SUCCEEDED(hr)) { hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &pixelformat); - ok(hr == S_OK, "GetPixelFormat) failed, hr=%x (%s)\n", hr, name); + ok(hr == S_OK, "GetPixelFormat) failed, hr=%lx (%s)\n", hr, name); if (IsEqualGUID(&pixelformat, dsts[i]->format)) compare_bitmap_data(srcs[i], dsts[i], (IWICBitmapSource*)framedecode, name); hr = IWICBitmapFrameDecode_CopyPalette(framedecode, frame_palette); if (winetest_debug > 1) - trace("%s, bpp %d, %s, hr %#x\n", name, dsts[i]->bpp, wine_dbgstr_guid(dsts[i]->format), hr); + trace("%s, bpp %d, %s, hr %#lx\n", name, dsts[i]->bpp, wine_dbgstr_guid(dsts[i]->format), hr); if (dsts[i]->bpp > 8 || IsEqualGUID(dsts[i]->format, &GUID_WICPixelFormatBlackWhite)) - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "wrong error %#lx\n", hr); else { UINT count, ret; WICColor colors[256]; - ok(hr == S_OK, "CopyPalette error %#x (%s)\n", hr, name); + ok(hr == S_OK, "CopyPalette error %#lx (%s)\n", hr, name); count = 0; hr = IWICPalette_GetColorCount(frame_palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); memset(colors, 0, sizeof(colors)); ret = 0; hr = IWICPalette_GetColors(frame_palette, count, colors, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); if (IsEqualGUID(clsid_decoder, &CLSID_WICPngDecoder)) { @@ -1606,6 +1738,14 @@ static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* cls } } +static void test_multi_encoder(const struct bitmap_data **srcs, const CLSID* clsid_encoder, + const struct bitmap_data **dsts, const CLSID *clsid_decoder, WICRect *rc, + const struct setting *settings, const char *name, IWICPalette *palette) +{ + test_multi_encoder_impl(srcs, clsid_encoder, dsts, clsid_decoder, rc, settings, name, palette, TRUE); + test_multi_encoder_impl(srcs, clsid_encoder, dsts, clsid_decoder, rc, settings, name, palette, FALSE); +} + static void test_encoder(const struct bitmap_data *src, const CLSID* clsid_encoder, const struct bitmap_data *dst, const CLSID *clsid_decoder, const char *name) { @@ -1616,7 +1756,7 @@ static void test_encoder(const struct bitmap_data *src, const CLSID* clsid_encod HRESULT hr; hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); memset(colors, 0, sizeof(colors)); colors[0] = 0x11111111; @@ -1626,7 +1766,7 @@ static void test_encoder(const struct bitmap_data *src, const CLSID* clsid_encod colors[4] = 0x55555555; /* TIFF decoder fails to decode a 8bpp frame if palette has less than 256 colors */ hr = IWICPalette_InitializeCustom(palette, colors, 256); - ok(hr == S_OK, "InitializeCustom error %#x\n", hr); + ok(hr == S_OK, "InitializeCustom error %#lx\n", hr); srcs[0] = src; srcs[1] = NULL; @@ -1696,54 +1836,102 @@ static void test_converter_8bppIndexed(void) CreateTestBitmap(&testdata_24bppBGR, &src_obj); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 0, "expected 0, got %u\n", count); /* NULL palette + Custom type */ hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); - ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, &GUID_WICPixelFormat24bppBGR, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeCustom); - ok(hr == S_OK, "Initialize error %#x\n", hr); + ok(hr == S_OK, "Initialize error %#lx\n", hr); hr = IWICFormatConverter_CopyPalette(converter, palette); - ok(hr == 0xdeadbeef, "unexpected error %#x\n", hr); + ok(hr == 0xdeadbeef, "unexpected error %#lx\n", hr); hr = IWICFormatConverter_CopyPixels(converter, NULL, 32 * 3, sizeof(buf), buf); - ok(hr == S_OK, "CopyPixels error %#x\n", hr); + ok(hr == S_OK, "CopyPixels error %#lx\n", hr); IWICFormatConverter_Release(converter); /* NULL palette + Custom type */ hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); - ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeCustom); - ok(hr == E_INVALIDARG, "unexpected error %#x\n", hr); + ok(hr == E_INVALIDARG, "unexpected error %#lx\n", hr); hr = IWICFormatConverter_CopyPalette(converter, palette); - ok(hr == WINCODEC_ERR_WRONGSTATE, "unexpected error %#x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "unexpected error %#lx\n", hr); hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf); - ok(hr == WINCODEC_ERR_WRONGSTATE, "unexpected error %#x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "unexpected error %#lx\n", hr); + IWICFormatConverter_Release(converter); + + hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat4bppIndexed, WICBitmapDitherTypeNone, + NULL, 0.0, WICBitmapPaletteTypeCustom); + ok(hr == E_INVALIDARG, "unexpected error %#lx\n", hr); + IWICFormatConverter_Release(converter); + + hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat2bppIndexed, WICBitmapDitherTypeNone, + NULL, 0.0, WICBitmapPaletteTypeCustom); + ok(hr == E_INVALIDARG, "unexpected error %#lx\n", hr); + IWICFormatConverter_Release(converter); + + hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat1bppIndexed, WICBitmapDitherTypeNone, + NULL, 0.0, WICBitmapPaletteTypeCustom); + ok(hr == E_INVALIDARG, "unexpected error %#lx\n", hr); + IWICFormatConverter_Release(converter); + + hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat1bppIndexed, WICBitmapDitherTypeNone, + NULL, 0.0, WICBitmapPaletteTypeMedianCut); + todo_wine ok(hr == S_OK, "unexpected error %#lx\n", hr); + IWICFormatConverter_Release(converter); + + hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat1bppIndexed, WICBitmapDitherTypeNone, + NULL, 0.0, WICBitmapPaletteTypeFixedBW); + todo_wine ok(hr == S_OK, "unexpected error %#lx\n", hr); + IWICFormatConverter_Release(converter); + + hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); + hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, + &GUID_WICPixelFormat1bppIndexed, WICBitmapDitherTypeNone, + NULL, 0.0, WICBitmapPaletteTypeFixedHalftone8); + todo_wine ok(hr == E_INVALIDARG, "unexpected error %#lx\n", hr); IWICFormatConverter_Release(converter); /* empty palette + Custom type */ hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); - ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone, palette, 0.0, WICBitmapPaletteTypeCustom); - ok(hr == S_OK, "Initialize error %#x\n", hr); + ok(hr == S_OK, "Initialize error %#lx\n", hr); hr = IWICFormatConverter_CopyPalette(converter, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 0, "expected 0, got %u\n", count); memset(buf, 0xaa, sizeof(buf)); hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf); - ok(hr == S_OK, "CopyPixels error %#x\n", hr); + ok(hr == S_OK, "CopyPixels error %#lx\n", hr); count = 0; for (i = 0; i < 32 * 2; i++) if (buf[i] != 0) count++; @@ -1752,19 +1940,19 @@ static void test_converter_8bppIndexed(void) /* NULL palette + Predefined type */ hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); - ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeFixedGray16); - ok(hr == S_OK, "Initialize error %#x\n", hr); + ok(hr == S_OK, "Initialize error %#lx\n", hr); hr = IWICFormatConverter_CopyPalette(converter, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 16, "expected 16, got %u\n", count); hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf); - ok(hr == S_OK, "CopyPixels error %#x\n", hr); + ok(hr == S_OK, "CopyPixels error %#lx\n", hr); count = 0; for (i = 0; i < 32 * 2; i++) if (buf[i] != 0) count++; @@ -1773,19 +1961,19 @@ static void test_converter_8bppIndexed(void) /* not empty palette + Predefined type */ hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); - ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone, palette, 0.0, WICBitmapPaletteTypeFixedHalftone64); - ok(hr == S_OK, "Initialize error %#x\n", hr); + ok(hr == S_OK, "Initialize error %#lx\n", hr); hr = IWICFormatConverter_CopyPalette(converter, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 16, "expected 16, got %u\n", count); hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf); - ok(hr == S_OK, "CopyPixels error %#x\n", hr); + ok(hr == S_OK, "CopyPixels error %#lx\n", hr); count = 0; for (i = 0; i < 32 * 2; i++) if (buf[i] != 0) count++; @@ -1794,19 +1982,19 @@ static void test_converter_8bppIndexed(void) /* not empty palette + MedianCut type */ hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); - ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone, palette, 0.0, WICBitmapPaletteTypeMedianCut); - ok(hr == S_OK, "Initialize error %#x\n", hr); + ok(hr == S_OK, "Initialize error %#lx\n", hr); hr = IWICFormatConverter_CopyPalette(converter, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 16, "expected 16, got %u\n", count); hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf); - ok(hr == S_OK, "CopyPixels error %#x\n", hr); + ok(hr == S_OK, "CopyPixels error %#lx\n", hr); count = 0; for (i = 0; i < 32 * 2; i++) if (buf[i] != 0) count++; @@ -1815,21 +2003,21 @@ static void test_converter_8bppIndexed(void) /* NULL palette + MedianCut type */ hr = IWICImagingFactory_CreateFormatConverter(factory, &converter); - ok(hr == S_OK, "CreateFormatConverter error %#x\n", hr); + ok(hr == S_OK, "CreateFormatConverter error %#lx\n", hr); hr = IWICFormatConverter_Initialize(converter, &src_obj->IWICBitmapSource_iface, &GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeMedianCut); - ok(hr == S_OK || broken(hr == E_INVALIDARG) /* XP */, "Initialize error %#x\n", hr); + ok(hr == S_OK || broken(hr == E_INVALIDARG) /* XP */, "Initialize error %#lx\n", hr); if (hr == S_OK) { hr = IWICFormatConverter_CopyPalette(converter, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 8, "expected 8, got %u\n", count); hr = IWICFormatConverter_CopyPixels(converter, NULL, 32, sizeof(buf), buf); - ok(hr == S_OK, "CopyPixels error %#x\n", hr); + ok(hr == S_OK, "CopyPixels error %#lx\n", hr); count = 0; for (i = 0; i < 32 * 2; i++) if (buf[i] != 0) count++; @@ -1849,7 +2037,7 @@ START_TEST(converter) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void **)&factory); - ok(hr == S_OK, "failed to create factory: %#x\n", hr); + ok(hr == S_OK, "failed to create factory: %#lx\n", hr); test_conversion(&testdata_24bppRGB, &testdata_1bppIndexed, "24bppRGB -> 1bppIndexed", TRUE); test_conversion(&testdata_24bppRGB, &testdata_2bppIndexed, "24bppRGB -> 2bppIndexed", TRUE); @@ -1880,6 +2068,10 @@ START_TEST(converter) test_conversion(&testdata_32bppBGR, &testdata_24bppRGB, "32bppBGR -> 24bppRGB", FALSE); test_conversion(&testdata_24bppRGB, &testdata_32bppBGR, "24bppRGB -> 32bppBGR", FALSE); test_conversion(&testdata_32bppBGRA, &testdata_24bppRGB, "32bppBGRA -> 24bppRGB", FALSE); + test_conversion(&testdata_32bppRGBA, &testdata_24bppBGR, "32bppRGBA -> 24bppBGR", FALSE); + + test_conversion(&testdata_32bppRGBA, &testdata_32bppBGRA, "32bppRGBA -> 32bppBGRA", FALSE); + test_conversion(&testdata_32bppBGRA, &testdata_32bppRGBA, "32bppBGRA -> 32bppRGBA", FALSE); test_conversion(&testdata_64bppRGBA, &testdata_32bppRGBA, "64bppRGBA -> 32bppRGBA", FALSE); test_conversion(&testdata_64bppRGBA, &testdata_32bppRGB, "64bppRGBA -> 32bppRGB", FALSE); @@ -1891,9 +2083,13 @@ START_TEST(converter) test_conversion(&testdata_32bppBGR, &testdata_8bppGray, "32bppBGR -> 8bppGray", FALSE); test_conversion(&testdata_32bppGrayFloat, &testdata_24bppBGR_gray, "32bppGrayFloat -> 24bppBGR gray", FALSE); test_conversion(&testdata_32bppGrayFloat, &testdata_8bppGray, "32bppGrayFloat -> 8bppGray", FALSE); + test_conversion(&testdata_32bppBGRA, &testdata_16bppBGRA5551, "32bppBGRA -> 16bppBGRA5551", FALSE); + test_conversion(&testdata_48bppRGB, &testdata_64bppRGBA_2, "48bppRGB -> 64bppRGBA", FALSE); test_invalid_conversion(); test_default_converter(); + test_converter_4bppGray(); + test_converter_8bppGray(); test_converter_8bppIndexed(); test_encoder(&testdata_8bppIndexed, &CLSID_WICGifEncoder, diff --git a/modules/rostests/winetests/windowscodecs/ddsformat.c b/modules/rostests/winetests/windowscodecs/ddsformat.c new file mode 100644 index 00000000000..116a7cbba3f --- /dev/null +++ b/modules/rostests/winetests/windowscodecs/ddsformat.c @@ -0,0 +1,1579 @@ +/* + * Copyright 2020 Ziqing Hui + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#define COBJMACROS + +#include "windef.h" +#include "wincodec.h" +#include "wine/test.h" + +#ifdef __REACTOS__ +#define debugstr_guid wine_dbgstr_guid +#endif + +#define GET_RGB565_R(color) ((BYTE)(((color) >> 11) & 0x1F)) +#define GET_RGB565_G(color) ((BYTE)(((color) >> 5) & 0x3F)) +#define GET_RGB565_B(color) ((BYTE)(((color) >> 0) & 0x1F)) +#define MAKE_RGB565(r, g, b) ((WORD)(((BYTE)(r) << 11) | ((BYTE)(g) << 5) | (BYTE)(b))) +#define MAKE_ARGB(a, r, g, b) (((DWORD)(a) << 24) | ((DWORD)(r) << 16) | ((DWORD)(g) << 8) | (DWORD)(b)) + +#define BLOCK_WIDTH 4 +#define BLOCK_HEIGHT 4 + +/* 1x1 uncompressed(Alpha) DDS image */ +static BYTE test_dds_alpha[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF +}; + +/* 1x1 uncompressed(Luminance) DDS image */ +static BYTE test_dds_luminance[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x82 +}; + +/* 4x4 uncompressed(16bpp RGB565) DDS image */ +static BYTE test_dds_rgb565[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, + 0xE0, 0x07, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF5, 0xA7, 0x08, 0x69, 0x4C, 0x7B, 0x08, 0x69, 0xF5, 0xA7, 0xF5, 0xA7, 0xF5, 0xA7, 0x4C, 0x7B, + 0x4C, 0x7B, 0x4C, 0x7B, 0x4C, 0x7B, 0xB1, 0x95, 0x4C, 0x7B, 0x08, 0x69, 0x08, 0x69, 0x4C, 0x7B +}; + +/* 1x1 uncompressed(24bpp RGB) DDS image */ +static BYTE test_dds_24bpp[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x81, 0x83 +}; + +/* 1x1 uncompressed(32bpp XRGB) DDS image */ +static BYTE test_dds_32bpp_xrgb[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x81, 0x83, 0x00 +}; + +/* 1x1 uncompressed(32bpp ARGB) DDS image */ +static BYTE test_dds_32bpp_argb[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x81, 0x83, 0xFF +}; + +/* 1x1 uncompressed(64bpp ABGR) DDS image */ +static BYTE test_dds_64bpp[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x0F, 0x10, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x83, 0x83, 0x81, 0x81, 0x70, 0x70, 0xFF, 0xFF +}; + +/* 1x1 uncompressed(96bpp ABGR float) DDS image */ +static BYTE test_dds_96bpp[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x0F, 0x10, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', '1', '0', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x84, 0x83, 0x03, 0x3F, 0x82, 0x81, 0x01, 0x3F, 0xE2, 0xE0, 0xE0, 0x3E +}; + +/* 1x1 uncompressed(128bpp ABGR float) DDS image */ +static BYTE test_dds_128bpp[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x0F, 0x10, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x84, 0x83, 0x03, 0x3F, 0x82, 0x81, 0x01, 0x3F, 0xE2, 0xE0, 0xE0, 0x3E, 0x00, 0x00, 0x80, 0x3F +}; + +/* 4x4 compressed(DXT1) cube map, mipMapCount = 3 */ +static BYTE test_dds_cube[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x0A, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', 'T', '1', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, 0xCC, 0x55, 0xCC, 0x55, + 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, + 0x32, 0x96, 0x0B, 0x7B, 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00, + 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, 0xCC, 0x55, 0xCC, 0x55, + 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, + 0x32, 0x96, 0x0B, 0x7B, 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00, + 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, 0xCC, 0x55, 0xCC, 0x55, + 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, + 0x32, 0x96, 0x0B, 0x7B, 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00 +}; + +/* 4x4 compressed(DXT1) cube map with extended header, mipMapCount=3 */ +static BYTE test_dds_cube_dx10[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x0A, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', '1', '0', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, + 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, + 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, + 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, + 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, + 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, + 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, + 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, + 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, + 0x00, 0x00, 0x00, 0x00 +}; + +/* 4x4 compressed(DXT1) DDS image with mip maps, mipMapCount=3 */ +static BYTE test_dds_mipmaps[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x0A, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', 'T', '1', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, 0xB1, 0x95, 0x6D, 0x7B, 0xFC, 0x55, 0x5D, 0x5D, + 0x2E, 0x8C, 0x4E, 0x7C, 0xAA, 0xAB, 0xAB, 0xAB +}; + +/* 4x4 compressed(DXT1) volume texture, depth=4, mipMapCount=3 */ +static BYTE test_dds_volume[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x8A, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', 'T', '1', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xD5, 0xA7, 0x2C, 0x7B, 0xE0, 0x00, 0x55, 0x55, 0xD5, 0xA7, 0x49, 0x69, 0x57, 0x00, 0xFF, 0x55, + 0xD5, 0xA7, 0x48, 0x69, 0xFD, 0x80, 0xFF, 0x55, 0x30, 0x8D, 0x89, 0x71, 0x55, 0xA8, 0x00, 0xFF, + 0x32, 0x96, 0x6D, 0x83, 0xA8, 0x55, 0x5D, 0x5D, 0x0E, 0x84, 0x6D, 0x7B, 0xA8, 0xA9, 0xAD, 0xAD, + 0x2E, 0x8C, 0x2E, 0x7C, 0xAA, 0xAB, 0xAB, 0xAB +}; + +/* 4x4 compressed(DXT1) texture array, arraySize=3, mipMapCount=3 */ +static BYTE test_dds_array[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x0A, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', '1', '0', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, + 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, + 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, + 0x00, 0x00, 0x00, 0x00, 0xF5, 0xA7, 0x08, 0x69, 0x74, 0xC0, 0xBF, 0xD7, 0x32, 0x96, 0x0B, 0x7B, + 0xCC, 0x55, 0xCC, 0x55, 0x0E, 0x84, 0x0E, 0x84, 0x00, 0x00, 0x00, 0x00 +}; + +/* 4x4 compressed(DXT1c) DDS image */ +static BYTE test_dds_dxt1c[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', 'T', '1', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9A, 0xE6, 0x2B, 0x39, 0x37, 0xB7, 0x7F, 0x7F +}; + +/* 4x4 compressed(DXT1a) DDS image */ +static BYTE test_dds_dxt1a[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', 'T', '1', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2A, 0x31, 0xF5, 0xBC, 0xE3, 0x6E, 0x2A, 0x3A +}; + +/* 4x4 compressed(DXT2) DDS image, mipMapCount=3 */ +static BYTE test_dds_dxt2[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', 'T', '2', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xDE, 0xC4, 0x10, 0x2F, 0xBF, 0xFF, 0x7B, + 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x53, 0x00, 0x00, 0x52, 0x52, 0x55, 0x55, + 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0x59, 0x00, 0x00, 0x54, 0x55, 0x55, 0x55 +}; + +/* 1x3 compressed(DXT3) DDS image, mipMapCount=2 */ +static BYTE test_dds_dxt3[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x0A, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', 'T', '3', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0C, 0x92, 0x38, 0x84, 0x00, 0xFF, 0x55, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x53, 0x8B, 0x53, 0x8B, 0x00, 0x00, 0x00, 0x00 +}; + +/* 4x4 compressed(DXT4) DDS image, mipMapCount=3 */ +static BYTE test_dds_dxt4[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', 'T', '4', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xDE, 0xC4, 0x10, 0x2F, 0xBF, 0xFF, 0x7B, + 0xFF, 0x00, 0x40, 0x02, 0x24, 0x49, 0x92, 0x24, 0x57, 0x53, 0x00, 0x00, 0x52, 0x52, 0x55, 0x55, + 0xFF, 0x00, 0x48, 0x92, 0x24, 0x49, 0x92, 0x24, 0xCE, 0x59, 0x00, 0x00, 0x54, 0x55, 0x55, 0x55 +}; + +/* 6x6 compressed(DXT5) image, mipMapCount=3 */ +static BYTE test_dds_dxt5[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x0A, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x44, 0x58, 0x54, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x73, 0x8E, 0x51, 0x97, 0x97, 0xBF, 0xAF, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9D, 0xC6, 0xCF, 0x52, 0x22, 0x22, 0xBB, 0x55, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xA2, 0xB8, 0x5B, 0xF8, 0xF8, 0xF8, 0xF8, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x3A, 0x05, 0x19, 0xCC, 0x66, 0xCC, 0x66, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x9D, 0x0A, 0x39, 0xCF, 0xEF, 0x9B, 0xEF, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x6A, 0xF0, 0x6A, 0x00, 0x00, 0x00, 0x00 +}; + +/* 12x12 compressed(DXT3) texture array, arraySize=2, mipMapCount=4 */ +static BYTE test_dds_12x12[] = { + 'D', 'D', 'S', ' ', 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x0A, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 'D', 'X', '1', '0', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4A, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB5, 0xA7, 0xAD, 0x83, + 0x60, 0x60, 0xE0, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x12, 0x96, 0x6B, 0x72, + 0xD5, 0xD5, 0xAF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x30, 0x8D, 0x89, 0x69, + 0x57, 0x5F, 0x5E, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xA7, 0xAD, 0x83, + 0x00, 0xAA, 0xFF, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x9E, 0x6D, 0x83, + 0x00, 0x00, 0xAA, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x12, 0x96, 0xCD, 0x83, + 0x5C, 0xF8, 0xAA, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0x7A, 0xC9, 0x71, + 0x80, 0x60, 0x60, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4A, 0x72, 0xA8, 0x68, + 0x28, 0xBE, 0xD7, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAF, 0x8C, 0xEA, 0x71, + 0x0B, 0xAB, 0xAD, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x9F, 0xCC, 0x7A, + 0x5C, 0xA8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0x8D, 0x49, 0x69, + 0x77, 0xEE, 0x88, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0C, 0x7B, 0x08, 0x69, + 0xF8, 0x58, 0xF8, 0x58, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4E, 0x84, 0x6B, 0x72, + 0x33, 0x99, 0x33, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x14, 0x9F, 0x0A, 0x72, + 0xDC, 0xAA, 0x75, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0E, 0x84, 0x0E, 0x84, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB5, 0xA7, 0xAD, 0x83, + 0x60, 0x60, 0xE0, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x12, 0x96, 0x6B, 0x72, + 0xD5, 0xD5, 0xAF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x30, 0x8D, 0x89, 0x69, + 0x57, 0x5F, 0x5E, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xA7, 0xAD, 0x83, + 0x00, 0xAA, 0xFF, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x9E, 0x6D, 0x83, + 0x00, 0x00, 0xAA, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x12, 0x96, 0xCD, 0x83, + 0x5C, 0xF8, 0xAA, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0x7A, 0xC9, 0x71, + 0x80, 0x60, 0x60, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4A, 0x72, 0xA8, 0x68, + 0x28, 0xBE, 0xD7, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAF, 0x8C, 0xEA, 0x71, + 0x0B, 0xAB, 0xAD, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x9F, 0xCC, 0x7A, + 0x5C, 0xA8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0x8D, 0x49, 0x69, + 0x77, 0xEE, 0x88, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0C, 0x7B, 0x08, 0x69, + 0xF8, 0x58, 0xF8, 0x58, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4E, 0x84, 0x6B, 0x72, + 0x33, 0x99, 0x33, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x14, 0x9F, 0x0A, 0x72, + 0xDC, 0xAA, 0x75, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0E, 0x84, 0x0E, 0x84, + 0x00, 0x00, 0x00, 0x00 +}; + +static BYTE test_dds_bad_magic[sizeof(test_dds_dxt1c)]; +static BYTE test_dds_bad_header[sizeof(test_dds_dxt1c)]; +static BYTE test_byte[1] = { 0 }; +static BYTE test_word[2] = { 0 }; +static BYTE test_dword[4] = { 0 }; +static BYTE test_qword_a[8] = { 0 }; +static BYTE test_qword_b[8] = "DDS "; + +static struct test_data { + BYTE *data; + UINT size; + HRESULT init_hr; + UINT expected_frame_count; + UINT expected_bytes_per_block; + UINT pixel_format_bpp; + const GUID *expected_pixel_format; + WICDdsParameters expected_parameters; + BOOL wine_init; +} test_data[] = { + { test_dds_alpha, sizeof(test_dds_alpha), WINCODEC_ERR_BADHEADER, 1, 1, 8, &GUID_WICPixelFormat8bppAlpha, + { 1, 1, 1, 1, 1, DXGI_FORMAT_A8_UNORM, WICDdsTexture2D, WICDdsAlphaModeUnknown }, TRUE }, + { test_dds_luminance, sizeof(test_dds_luminance), WINCODEC_ERR_BADHEADER, 1, 1, 8, &GUID_WICPixelFormat8bppGray, + { 1, 1, 1, 1, 1, DXGI_FORMAT_R8_UNORM, WICDdsTexture2D, WICDdsAlphaModeUnknown }, TRUE }, + { test_dds_rgb565, sizeof(test_dds_rgb565), WINCODEC_ERR_BADHEADER, 1, 2, 16, &GUID_WICPixelFormat16bppBGR565, + { 4, 4, 1, 1, 1, DXGI_FORMAT_B5G6R5_UNORM, WICDdsTexture2D, WICDdsAlphaModeUnknown }, TRUE }, + { test_dds_24bpp, sizeof(test_dds_24bpp), WINCODEC_ERR_BADHEADER, 1, 3, 24, &GUID_WICPixelFormat24bppBGR, + { 1, 1, 1, 1, 1, DXGI_FORMAT_UNKNOWN, WICDdsTexture2D, WICDdsAlphaModeUnknown }, TRUE }, + { test_dds_32bpp_xrgb, sizeof(test_dds_32bpp_xrgb), WINCODEC_ERR_BADHEADER, 1, 4, 32, &GUID_WICPixelFormat32bppBGR, + { 1, 1, 1, 1, 1, DXGI_FORMAT_B8G8R8X8_UNORM, WICDdsTexture2D, WICDdsAlphaModeUnknown }, TRUE }, + { test_dds_32bpp_argb, sizeof(test_dds_32bpp_argb), WINCODEC_ERR_BADHEADER, 1, 4, 32, &GUID_WICPixelFormat32bppBGRA, + { 1, 1, 1, 1, 1, DXGI_FORMAT_B8G8R8A8_UNORM, WICDdsTexture2D, WICDdsAlphaModeUnknown }, TRUE }, + { test_dds_64bpp, sizeof(test_dds_64bpp), WINCODEC_ERR_BADHEADER, 1, 8, 64, &GUID_WICPixelFormat64bppRGBA, + { 1, 1, 1, 1, 1, DXGI_FORMAT_R16G16B16A16_UNORM, WICDdsTexture2D, WICDdsAlphaModeUnknown }, TRUE }, + { test_dds_96bpp, sizeof(test_dds_96bpp), WINCODEC_ERR_BADHEADER, 1, 12, 96, &GUID_WICPixelFormat96bppRGBFloat, + { 1, 1, 1, 1, 1, DXGI_FORMAT_R32G32B32_FLOAT, WICDdsTexture2D, WICDdsAlphaModeUnknown }, TRUE }, + { test_dds_128bpp, sizeof(test_dds_128bpp), WINCODEC_ERR_BADHEADER, 1, 16, 128, &GUID_WICPixelFormat128bppRGBAFloat, + { 1, 1, 1, 1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, WICDdsTexture2D, WICDdsAlphaModeUnknown }, TRUE }, + { test_dds_cube, sizeof(test_dds_cube), WINCODEC_ERR_BADHEADER, 18, 8, 32, &GUID_WICPixelFormat32bppPBGRA, + { 4, 4, 1, 3, 1, DXGI_FORMAT_BC1_UNORM, WICDdsTextureCube, WICDdsAlphaModePremultiplied }, TRUE }, + { test_dds_cube_dx10, sizeof(test_dds_cube_dx10), WINCODEC_ERR_BADHEADER, 18, 8, 32, &GUID_WICPixelFormat32bppBGRA, + { 4, 4, 1, 3, 1, DXGI_FORMAT_BC1_UNORM, WICDdsTextureCube, WICDdsAlphaModeUnknown }, TRUE }, + { test_dds_mipmaps, sizeof(test_dds_mipmaps), S_OK, 3, 8, 32, &GUID_WICPixelFormat32bppPBGRA, + { 4, 4, 1, 3, 1, DXGI_FORMAT_BC1_UNORM, WICDdsTexture2D, WICDdsAlphaModePremultiplied } }, + { test_dds_volume, sizeof(test_dds_volume), S_OK, 7, 8, 32, &GUID_WICPixelFormat32bppPBGRA, + { 4, 4, 4, 3, 1, DXGI_FORMAT_BC1_UNORM, WICDdsTexture3D, WICDdsAlphaModePremultiplied } }, + { test_dds_array, sizeof(test_dds_array), S_OK, 9, 8, 32, &GUID_WICPixelFormat32bppBGRA, + { 4, 4, 1, 3, 3, DXGI_FORMAT_BC1_UNORM, WICDdsTexture2D, WICDdsAlphaModeUnknown } }, + { test_dds_dxt1c, sizeof(test_dds_dxt1c), S_OK, 1, 8, 32, &GUID_WICPixelFormat32bppPBGRA, + { 4, 4, 1, 1, 1, DXGI_FORMAT_BC1_UNORM, WICDdsTexture2D, WICDdsAlphaModePremultiplied } }, + { test_dds_dxt1a, sizeof(test_dds_dxt1a), S_OK, 1, 8, 32, &GUID_WICPixelFormat32bppPBGRA, + { 4, 4, 1, 1, 1, DXGI_FORMAT_BC1_UNORM, WICDdsTexture2D, WICDdsAlphaModePremultiplied } }, + { test_dds_dxt2, sizeof(test_dds_dxt2), S_OK, 3, 16, 32, &GUID_WICPixelFormat32bppPBGRA, + { 4, 4, 1, 3, 1, DXGI_FORMAT_BC2_UNORM, WICDdsTexture2D, WICDdsAlphaModePremultiplied } }, + { test_dds_dxt3, sizeof(test_dds_dxt3), S_OK, 2, 16, 32, &GUID_WICPixelFormat32bppBGRA, + { 1, 3, 1, 2, 1, DXGI_FORMAT_BC2_UNORM, WICDdsTexture2D, WICDdsAlphaModeUnknown } }, + { test_dds_dxt4, sizeof(test_dds_dxt4), S_OK, 3, 16, 32, &GUID_WICPixelFormat32bppPBGRA, + { 4, 4, 1, 3, 1, DXGI_FORMAT_BC3_UNORM, WICDdsTexture2D, WICDdsAlphaModePremultiplied } }, + { test_dds_dxt5, sizeof(test_dds_dxt5), S_OK, 3, 16, 32, &GUID_WICPixelFormat32bppBGRA, + { 6, 6, 1, 3, 1, DXGI_FORMAT_BC3_UNORM, WICDdsTexture2D, WICDdsAlphaModeUnknown } }, + { test_dds_12x12, sizeof(test_dds_12x12), S_OK, 8, 16, 32, &GUID_WICPixelFormat32bppBGRA, + { 12, 12, 1, 4, 2, DXGI_FORMAT_BC2_UNORM, WICDdsTexture2D, WICDdsAlphaModeUnknown } }, + { test_dds_bad_magic, sizeof(test_dds_bad_magic), WINCODEC_ERR_UNKNOWNIMAGEFORMAT }, + { test_dds_bad_header, sizeof(test_dds_bad_header), WINCODEC_ERR_BADHEADER }, + { test_byte, sizeof(test_byte), WINCODEC_ERR_STREAMREAD }, + { test_word, sizeof(test_word), WINCODEC_ERR_STREAMREAD }, + { test_dword, sizeof(test_dword), WINCODEC_ERR_UNKNOWNIMAGEFORMAT }, + { test_qword_a, sizeof(test_qword_a), WINCODEC_ERR_UNKNOWNIMAGEFORMAT }, + { test_qword_b, sizeof(test_qword_b), WINCODEC_ERR_STREAMREAD }, +}; + +static DXGI_FORMAT compressed_formats[] = { + DXGI_FORMAT_BC1_TYPELESS, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_BC2_TYPELESS, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM_SRGB, + DXGI_FORMAT_BC3_TYPELESS, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM_SRGB, + DXGI_FORMAT_BC4_TYPELESS, DXGI_FORMAT_BC4_UNORM, DXGI_FORMAT_BC4_SNORM, + DXGI_FORMAT_BC5_TYPELESS, DXGI_FORMAT_BC5_UNORM, DXGI_FORMAT_BC5_SNORM, + DXGI_FORMAT_BC6H_TYPELESS, DXGI_FORMAT_BC6H_UF16, DXGI_FORMAT_BC6H_SF16, + DXGI_FORMAT_BC7_TYPELESS, DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_BC7_UNORM_SRGB +}; + +static IWICImagingFactory *factory = NULL; + +static IWICStream *create_stream(const void *image_data, UINT image_size) +{ + HRESULT hr; + IWICStream *stream = NULL; + + hr = IWICImagingFactory_CreateStream(factory, &stream); + ok(hr == S_OK, "CreateStream failed, hr %#lx\n", hr); + if (hr != S_OK) goto fail; + + hr = IWICStream_InitializeFromMemory(stream, (BYTE *)image_data, image_size); + ok(hr == S_OK, "InitializeFromMemory failed, hr %#lx\n", hr); + if (hr != S_OK) goto fail; + + return stream; + +fail: + if (stream) IWICStream_Release(stream); + return NULL; +} + +static IWICBitmapDecoder *create_decoder(void) +{ + HRESULT hr; + IWICBitmapDecoder *decoder = NULL; + GUID guidresult; + + hr = CoCreateInstance(&CLSID_WICDdsDecoder, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICBitmapDecoder, (void **)&decoder); + if (hr != S_OK) { + win_skip("Dds decoder is not supported\n"); + return NULL; + } + + memset(&guidresult, 0, sizeof(guidresult)); + hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); + ok(hr == S_OK, "GetContainerFormat failed, hr %#lx\n", hr); + ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatDds), + "Got unexpected container format %s\n", debugstr_guid(&guidresult)); + + return decoder; +} + +static IWICBitmapEncoder *create_encoder(void) +{ + IWICBitmapEncoder *encoder = NULL; + GUID guidresult; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_WICDdsEncoder, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICBitmapEncoder, (void **)&encoder); + if (hr != S_OK) + { + win_skip("DDS encoder is not supported\n"); + return NULL; + } + + memset(&guidresult, 0, sizeof(guidresult)); + + hr = IWICBitmapEncoder_GetContainerFormat(encoder, &guidresult); + ok(hr == S_OK, "GetContainerFormat failed, hr %#lx\n", hr); + + ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatDds), + "Got unexpected container format %s\n", debugstr_guid(&guidresult)); + + return encoder; +} + +static HRESULT init_decoder(IWICBitmapDecoder *decoder, IWICStream *stream, HRESULT expected, BOOL wine_init) +{ + HRESULT hr; + IWICWineDecoder *wine_decoder; + + hr = IWICBitmapDecoder_Initialize(decoder, (IStream*)stream, WICDecodeMetadataCacheOnDemand); + ok(hr == expected, "Expected hr %#lx, got %#lx\n", expected, hr); + + if (hr != S_OK && wine_init) { + hr = IWICBitmapDecoder_QueryInterface(decoder, &IID_IWICWineDecoder, (void **)&wine_decoder); + ok(hr == S_OK || broken(hr != S_OK), "QueryInterface failed, hr %#lx\n", hr); + + if (hr == S_OK) { + hr = IWICWineDecoder_Initialize(wine_decoder, (IStream*)stream, WICDecodeMetadataCacheOnDemand); + ok(hr == S_OK, "Initialize failed, hr %#lx\n", hr); + } + } + + return hr; +} + +static void release_encoder(IWICBitmapEncoder *encoder, IWICDdsEncoder *dds_encoder, IWICStream *stream) +{ + if (dds_encoder) IWICDdsEncoder_Release(dds_encoder); + if (stream) IWICStream_Release(stream); + if (encoder) IWICBitmapEncoder_Release(encoder); +} + +static HRESULT create_and_init_encoder(BYTE *image_buffer, UINT buffer_size, WICDdsParameters *params, + IWICBitmapEncoder **encoder, IWICDdsEncoder **dds_encoder, IWICStream **stream) +{ + IWICDdsEncoder *dds = NULL; + HRESULT hr; + + *encoder = create_encoder(); + if (!*encoder) goto fail; + + *stream = create_stream(image_buffer, buffer_size); + if (!*stream) goto fail; + + hr = IWICBitmapEncoder_Initialize(*encoder, (IStream *)*stream, WICBitmapEncoderNoCache); + ok(hr == S_OK, "Initialize failed, hr %#lx\n", hr); + if (hr != S_OK) goto fail; + + hr = IWICBitmapEncoder_QueryInterface(*encoder, &IID_IWICDdsEncoder, (void **)&dds); + ok(hr == S_OK, "QueryInterface failed, hr %#lx\n", hr); + if (hr != S_OK) goto fail; + + if (params) + { + hr = IWICDdsEncoder_SetParameters(dds, params); + ok(hr == S_OK, "SetParameters failed, hr %#lx\n", hr); + if (hr != S_OK) goto fail; + } + + if (dds_encoder) + { + *dds_encoder = dds; + } + else + { + IWICDdsEncoder_Release(dds); + dds = NULL; + } + + return S_OK; + +fail: + release_encoder(*encoder, dds, *stream); + return E_FAIL; +} + +static BOOL is_compressed(DXGI_FORMAT format) +{ + UINT i; + for (i = 0; i < ARRAY_SIZE(compressed_formats); i++) + { + if (format == compressed_formats[i]) return TRUE; + } + return FALSE; +} + +static BOOL has_extended_header(const BYTE *data) +{ + return data[84] == 'D' && data[85] == 'X' && data[86] == '1' && data[87] == '0'; +} + +static DWORD rgb565_to_argb(WORD color, BYTE alpha) +{ + return MAKE_ARGB(alpha, (GET_RGB565_R(color) * 0xFF + 0x0F) / 0x1F, + (GET_RGB565_G(color) * 0xFF + 0x1F) / 0x3F, + (GET_RGB565_B(color) * 0xFF + 0x0F) / 0x1F); +} + +static void decode_block(const BYTE *block_data, UINT block_count, DXGI_FORMAT format, + UINT width, UINT height, DWORD *buffer) +{ + const BYTE *block, *color_indices, *alpha_indices, *alpha_table; + int i, j, x, y, block_x, block_y, color_index, alpha_index; + int block_size, color_offset, color_indices_offset; + WORD color[4], color_value = 0; + BYTE alpha[8], alpha_value = 0; + + if (format == DXGI_FORMAT_BC1_UNORM) { + block_size = 8; + color_offset = 0; + color_indices_offset = 4; + } else { + block_size = 16; + color_offset = 8; + color_indices_offset = 12; + } + block_x = 0; + block_y = 0; + + for (i = 0; i < block_count; i++) + { + block = block_data + i * block_size; + + color[0] = *((WORD *)(block + color_offset)); + color[1] = *((WORD *)(block + color_offset + 2)); + color[2] = MAKE_RGB565(((GET_RGB565_R(color[0]) * 2 + GET_RGB565_R(color[1]) + 1) / 3), + ((GET_RGB565_G(color[0]) * 2 + GET_RGB565_G(color[1]) + 1) / 3), + ((GET_RGB565_B(color[0]) * 2 + GET_RGB565_B(color[1]) + 1) / 3)); + color[3] = MAKE_RGB565(((GET_RGB565_R(color[0]) + GET_RGB565_R(color[1]) * 2 + 1) / 3), + ((GET_RGB565_G(color[0]) + GET_RGB565_G(color[1]) * 2 + 1) / 3), + ((GET_RGB565_B(color[0]) + GET_RGB565_B(color[1]) * 2 + 1) / 3)); + + switch (format) + { + case DXGI_FORMAT_BC1_UNORM: + if (color[0] <= color[1]) { + color[2] = MAKE_RGB565(((GET_RGB565_R(color[0]) + GET_RGB565_R(color[1]) + 1) / 2), + ((GET_RGB565_G(color[0]) + GET_RGB565_G(color[1]) + 1) / 2), + ((GET_RGB565_B(color[0]) + GET_RGB565_B(color[1]) + 1) / 2)); + color[3] = 0; + } + break; + case DXGI_FORMAT_BC2_UNORM: + alpha_table = block; + break; + case DXGI_FORMAT_BC3_UNORM: + alpha[0] = *block; + alpha[1] = *(block + 1); + if (alpha[0] > alpha[1]) { + for (j = 2; j < 8; j++) + { + alpha[j] = (BYTE)((alpha[0] * (8 - j) + alpha[1] * (j - 1) + 3) / 7); + } + } else { + for (j = 2; j < 6; j++) + { + alpha[j] = (BYTE)((alpha[0] * (6 - j) + alpha[1] * (j - 1) + 2) / 5); + } + alpha[6] = 0; + alpha[7] = 0xFF; + } + alpha_indices = block + 2; + break; + default: + break; + } + + color_indices = block + color_indices_offset; + for (j = 0; j < 16; j++) + { + x = block_x + j % 4; + y = block_y + j / 4; + if (x >= width || y >= height) continue; + + color_index = (color_indices[j / 4] >> ((j % 4) * 2)) & 0x3; + color_value = color[color_index]; + + switch (format) + { + case DXGI_FORMAT_BC1_UNORM: + if ((color[0] <= color[1]) && !color_value) { + color_value = 0; + alpha_value = 0; + } else { + alpha_value = 0xFF; + } + break; + case DXGI_FORMAT_BC2_UNORM: + alpha_value = (alpha_table[j / 2] >> (j % 2) * 4) & 0xF; + alpha_value = (BYTE)((alpha_value * 0xFF + 0x7)/ 0xF); + break; + case DXGI_FORMAT_BC3_UNORM: + alpha_index = (*((DWORD *)(alpha_indices + (j / 8) * 3)) >> ((j % 8) * 3)) & 0x7; + alpha_value = alpha[alpha_index]; + break; + default: + break; + } + buffer[x + y * width] = rgb565_to_argb(color_value, alpha_value); + } + + block_x += BLOCK_WIDTH; + if (block_x >= width) { + block_x = 0; + block_y += BLOCK_HEIGHT; + } + } +} + +static BOOL color_match(DWORD color_a, DWORD color_b) +{ + static const int tolerance = 8; + + const int da = abs((int)((color_a & 0xFF000000) >> 24) - (int)((color_b & 0xFF000000) >> 24)); + const int dr = abs((int)((color_a & 0x00FF0000) >> 16) - (int)((color_b & 0x00FF0000) >> 16)); + const int dg = abs((int)((color_a & 0x0000FF00) >> 8) - (int)((color_b & 0x0000FF00) >> 8)); + const int db = abs((int)((color_a & 0x000000FF) >> 0) - (int)((color_b & 0x000000FF) >> 0)); + + return (da <= tolerance && dr <= tolerance && dg <= tolerance && db <= tolerance); +} + +static BOOL color_buffer_match(DWORD *color_buffer_a, DWORD *color_buffer_b, UINT color_count) +{ + UINT i; + + for (i = 0; i < color_count; i++) + { + if (!color_match(color_buffer_a[i], color_buffer_b[i])) return FALSE; + } + + return TRUE; +} + +static void copy_pixels(void *src_buffer, UINT src_stride, void *dst_buffer, UINT dst_stride, UINT size) +{ + char *src = src_buffer, *dst = dst_buffer; + UINT i; + + for (i = 0; i < size; i++) + { + *dst = src[i]; + if (i % src_stride == src_stride - 1) dst += dst_stride - src_stride; + dst ++; + } +} + +static void test_dds_decoder_initialize(void) +{ + int i; + + memcpy(test_dds_bad_magic, test_dds_dxt1c, sizeof(test_dds_dxt1c)); + memcpy(test_dds_bad_header, test_dds_dxt1c, sizeof(test_dds_dxt1c)); + test_dds_bad_magic[0] = 0; + test_dds_bad_header[4] = 0; + + for (i = 0; i < ARRAY_SIZE(test_data); i++) + { + IWICStream *stream = NULL; + IWICBitmapDecoder *decoder = NULL; + + winetest_push_context("Test %u", i); + + stream = create_stream(test_data[i].data, test_data[i].size); + if (!stream) goto next; + + decoder = create_decoder(); + if (!decoder) goto next; + + init_decoder(decoder, stream, test_data[i].init_hr, test_data[i].wine_init); + + next: + if (decoder) IWICBitmapDecoder_Release(decoder); + if (stream) IWICStream_Release(stream); + winetest_pop_context(); + } +} + +static void test_dds_decoder_global_properties(IWICBitmapDecoder *decoder) +{ + HRESULT hr; + IWICPalette *palette = NULL; + IWICMetadataQueryReader *metadata_reader = NULL; + IWICBitmapSource *preview = NULL, *thumnail = NULL; + IWICColorContext *color_context = NULL; + UINT count; + + hr = IWICImagingFactory_CreatePalette(factory, &palette); + ok(hr == S_OK, "CreatePalette failed, hr %#lx\n", hr); + if (hr == S_OK) { + hr = IWICBitmapDecoder_CopyPalette(decoder, palette); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "CopyPalette got unexpected hr %#lx\n", hr); + hr = IWICBitmapDecoder_CopyPalette(decoder, NULL); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "CopyPalette got unexpected hr %#lx\n", hr); + } + + hr = IWICBitmapDecoder_GetMetadataQueryReader(decoder, &metadata_reader); + todo_wine ok (hr == S_OK, "GetMetadataQueryReader got unexpected hr %#lx\n", hr); + hr = IWICBitmapDecoder_GetMetadataQueryReader(decoder, NULL); + ok(hr == E_INVALIDARG, "GetMetadataQueryReader got unexpected hr %#lx\n", hr); + + hr = IWICBitmapDecoder_GetPreview(decoder, &preview); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetPreview got unexpected hr %#lx\n", hr); + hr = IWICBitmapDecoder_GetPreview(decoder, NULL); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetPreview got unexpected hr %#lx\n", hr); + + hr = IWICBitmapDecoder_GetColorContexts(decoder, 1, &color_context, &count); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts got unexpected hr %#lx\n", hr); + hr = IWICBitmapDecoder_GetColorContexts(decoder, 1, NULL, NULL); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts got unexpected hr %#lx\n", hr); + + hr = IWICBitmapDecoder_GetThumbnail(decoder, &thumnail); + ok(hr == WINCODEC_ERR_CODECNOTHUMBNAIL, "GetThumbnail got unexpected hr %#lx\n", hr); + hr = IWICBitmapDecoder_GetThumbnail(decoder, NULL); + ok(hr == WINCODEC_ERR_CODECNOTHUMBNAIL, "GetThumbnail got unexpected hr %#lx\n", hr); + + if (palette) IWICPalette_Release(palette); + if (metadata_reader) IWICMetadataQueryReader_Release(metadata_reader); + if (preview) IWICBitmapSource_Release(preview); + if (color_context) IWICColorContext_Release(color_context); + if (thumnail) IWICBitmapSource_Release(thumnail); +} + +static void test_dds_decoder_image_parameters(void) +{ + int i; + HRESULT hr; + WICDdsParameters parameters; + + for (i = 0; i < ARRAY_SIZE(test_data); i++) + { + UINT frame_count; + IWICStream *stream = NULL; + IWICBitmapDecoder *decoder = NULL; + IWICDdsDecoder *dds_decoder = NULL; + + winetest_push_context("Test %u", i); + + stream = create_stream(test_data[i].data, test_data[i].size); + if (!stream) goto next; + + decoder = create_decoder(); + if (!decoder) goto next; + + hr = IWICBitmapDecoder_QueryInterface(decoder, &IID_IWICDdsDecoder, (void **)&dds_decoder); + ok(hr == S_OK, "QueryInterface failed, hr %#lx\n", hr); + if (hr != S_OK) goto next; + + hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); + ok(hr == WINCODEC_ERR_WRONGSTATE, "GetFrameCount got unexpected hr %#lx\n", hr); + hr = IWICBitmapDecoder_GetFrameCount(decoder, NULL); + ok(hr == E_INVALIDARG, "GetFrameCount got unexpected hr %#lx\n", hr); + + hr = IWICDdsDecoder_GetParameters(dds_decoder, ¶meters); + ok(hr == WINCODEC_ERR_WRONGSTATE, "GetParameters got unexpected hr %#lx\n", hr); + hr = IWICDdsDecoder_GetParameters(dds_decoder, NULL); + ok(hr == E_INVALIDARG, "GetParameters got unexpected hr %#lx\n", hr); + + if (test_data[i].init_hr != S_OK && !test_data[i].wine_init) goto next; + + hr = init_decoder(decoder, stream, test_data[i].init_hr, test_data[i].wine_init); + if (hr != S_OK) { + if (test_data[i].expected_parameters.Dimension == WICDdsTextureCube) { + win_skip("Cube map is not supported\n"); + } else { + win_skip("Uncompressed DDS image is not supported\n"); + } + goto next; + } + + hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); + ok(hr == S_OK, "GetFrameCount failed, hr %#lx\n", hr); + if (hr == S_OK) { + ok(frame_count == test_data[i].expected_frame_count, "Expected frame count %u, got %u\n", + test_data[i].expected_frame_count, frame_count); + } + hr = IWICBitmapDecoder_GetFrameCount(decoder, NULL); + ok(hr == E_INVALIDARG, "GetParameters got unexpected hr %#lx\n", hr); + + hr = IWICDdsDecoder_GetParameters(dds_decoder, ¶meters); + ok(hr == S_OK, "GetParameters failed, hr %#lx\n", hr); + if (hr == S_OK) { + ok(parameters.Width == test_data[i].expected_parameters.Width, + "Expected Width %u, got %u\n", test_data[i].expected_parameters.Width, parameters.Width); + ok(parameters.Height == test_data[i].expected_parameters.Height, + "Expected Height %u, got %u\n", test_data[i].expected_parameters.Height, parameters.Height); + ok(parameters.Depth == test_data[i].expected_parameters.Depth, + "Expected Depth %u, got %u\n", test_data[i].expected_parameters.Depth, parameters.Depth); + ok(parameters.MipLevels == test_data[i].expected_parameters.MipLevels, + "Expected MipLevels %u, got %u\n", test_data[i].expected_parameters.MipLevels, parameters.MipLevels); + ok(parameters.ArraySize == test_data[i].expected_parameters.ArraySize, + "Expected ArraySize %u, got %u\n", test_data[i].expected_parameters.ArraySize, parameters.ArraySize); + ok(parameters.DxgiFormat == test_data[i].expected_parameters.DxgiFormat, + "Expected DxgiFormat %#x, got %#x\n", test_data[i].expected_parameters.DxgiFormat, parameters.DxgiFormat); + ok(parameters.Dimension == test_data[i].expected_parameters.Dimension, + "Expected Dimension %#x, got %#x\n", test_data[i].expected_parameters.Dimension, parameters.Dimension); + ok(parameters.AlphaMode == test_data[i].expected_parameters.AlphaMode, + "Expected AlphaMode %#x, got %#x\n", test_data[i].expected_parameters.AlphaMode, parameters.AlphaMode); + } + hr = IWICDdsDecoder_GetParameters(dds_decoder, NULL); + ok(hr == E_INVALIDARG, "GetParameters got unexpected hr %#lx\n", hr); + + next: + if (decoder) IWICBitmapDecoder_Release(decoder); + if (stream) IWICStream_Release(stream); + if (dds_decoder) IWICDdsDecoder_Release(dds_decoder); + winetest_pop_context(); + } +} + +static void test_dds_decoder_frame_properties(IWICBitmapFrameDecode *frame_decode, IWICDdsFrameDecode *dds_frame, + UINT frame_count, WICDdsParameters *params, struct test_data *test, UINT frame_index) +{ + HRESULT hr; + UINT width, height ,expected_width, expected_height, slice_index, depth; + UINT width_in_blocks, height_in_blocks, expected_width_in_blocks, expected_height_in_blocks; + UINT expected_block_width, expected_block_height; + WICDdsFormatInfo format_info; + GUID pixel_format; + + /* frame size tests */ + + hr = IWICBitmapFrameDecode_GetSize(frame_decode, NULL, NULL); + ok(hr == E_INVALIDARG, "GetSize got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_GetSize(frame_decode, NULL, &height); + ok(hr == E_INVALIDARG, "GetSize got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_GetSize(frame_decode, &width, NULL); + ok(hr == E_INVALIDARG, "GetSize got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_GetSize(frame_decode, &width, &height); + ok(hr == S_OK, "GetSize failed, hr %#lx\n", hr); + if (hr != S_OK) return; + + depth = params->Depth; + expected_width = params->Width; + expected_height = params->Height; + slice_index = frame_index % (frame_count / params->ArraySize); + while (slice_index >= depth) + { + if (expected_width > 1) expected_width /= 2; + if (expected_height > 1) expected_height /= 2; + slice_index -= depth; + if (depth > 1) depth /= 2; + } + ok(width == expected_width, "Expected width %u, got %u\n", expected_width, width); + ok(height == expected_height, "Expected height %u, got %u\n", expected_height, height); + + /* frame format information tests */ + + if (is_compressed(test->expected_parameters.DxgiFormat)) { + expected_block_width = BLOCK_WIDTH; + expected_block_height = BLOCK_HEIGHT; + } else { + expected_block_width = 1; + expected_block_height = 1; + } + + hr = IWICDdsFrameDecode_GetFormatInfo(dds_frame, NULL); + ok(hr == E_INVALIDARG, "GetFormatInfo got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_GetFormatInfo(dds_frame, &format_info); + ok(hr == S_OK, "GetFormatInfo failed, hr %#lx\n", hr); + if (hr != S_OK) return; + + ok(format_info.DxgiFormat == test->expected_parameters.DxgiFormat, + "Expected DXGI format %#x, got %#x\n", + test->expected_parameters.DxgiFormat, format_info.DxgiFormat); + ok(format_info.BytesPerBlock == test->expected_bytes_per_block, + "Expected bytes per block %u, got %u\n", + test->expected_bytes_per_block, format_info.BytesPerBlock); + ok(format_info.BlockWidth == expected_block_width, + "Expected block width %u, got %u\n", + expected_block_width, format_info.BlockWidth); + ok(format_info.BlockHeight == expected_block_height, + "Expected block height %u, got %u\n", + expected_block_height, format_info.BlockHeight); + + + /* size in blocks tests */ + + hr = IWICDdsFrameDecode_GetSizeInBlocks(dds_frame, NULL, NULL); + ok(hr == E_INVALIDARG, "GetSizeInBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_GetSizeInBlocks(dds_frame, NULL, &height_in_blocks); + ok(hr == E_INVALIDARG, "GetSizeInBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_GetSizeInBlocks(dds_frame, &width_in_blocks, NULL); + ok(hr == E_INVALIDARG, "GetSizeInBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_GetSizeInBlocks(dds_frame, &width_in_blocks, &height_in_blocks); + ok(hr == S_OK, "GetSizeInBlocks failed, hr %#lx\n", hr); + if (hr != S_OK) return; + + expected_width_in_blocks = (expected_width + expected_block_width - 1) / expected_block_width; + expected_height_in_blocks = (expected_height + expected_block_height - 1) / expected_block_height; + ok(width_in_blocks == expected_width_in_blocks, + "Expected width in blocks %u, got %u\n", expected_width_in_blocks, width_in_blocks); + ok(height_in_blocks == expected_height_in_blocks, + "Expected height in blocks %u, got %u\n", expected_height_in_blocks, height_in_blocks); + + /* pixel format tests */ + + hr = IWICBitmapFrameDecode_GetPixelFormat(frame_decode, NULL); + ok(hr == E_INVALIDARG, "GetPixelFormat got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_GetPixelFormat(frame_decode, &pixel_format); + ok(hr == S_OK, "GetPixelFormat failed, hr %#lx\n", hr); + if (hr != S_OK) return; + ok(IsEqualGUID(&pixel_format, test->expected_pixel_format), + "Expected pixel format %s, got %s\n", + debugstr_guid(test->expected_pixel_format), debugstr_guid(&pixel_format)); +} + +static void test_dds_decoder_frame_data(IWICBitmapFrameDecode* frame, IWICDdsFrameDecode *dds_frame, UINT frame_count, + WICDdsParameters *params, struct test_data *test, UINT frame_index) +{ + HRESULT hr; + GUID pixel_format; + WICDdsFormatInfo format_info; + WICRect rect = { 0, 0, 1, 1 }, rect_test_a = { 0, 0, 0, 0 }, rect_test_b = { 0, 0, 0xdeadbeaf, 0xdeadbeaf }; + WICRect rect_test_c = { -0xdeadbeaf, -0xdeadbeaf, 1, 1 }, rect_test_d = { 0xdeadbeaf, 0xdeadbeaf, 1, 1 }; + BYTE buffer[2048], pixels[2048]; + UINT stride, frame_stride, frame_size, frame_width, frame_height, width_in_blocks, height_in_blocks, bpp; + UINT width, height, depth, array_index; + UINT block_offset; + int slice_index; + + hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &pixel_format); + ok(hr == S_OK, "GetPixelFormat failed, hr %#lx\n", hr); + if (hr != S_OK) return; + hr = IWICBitmapFrameDecode_GetSize(frame, &frame_width, &frame_height); + ok(hr == S_OK, "GetSize failed, hr %#lx\n", hr); + if (hr != S_OK) return; + hr = IWICDdsFrameDecode_GetFormatInfo(dds_frame, &format_info); + ok(hr == S_OK, "GetFormatInfo failed, hr %#lx\n", hr); + if (hr != S_OK) return; + hr = IWICDdsFrameDecode_GetSizeInBlocks(dds_frame, &width_in_blocks, &height_in_blocks); + ok(hr == S_OK, "GetSizeInBlocks failed, hr %#lx\n", hr); + if (hr != S_OK) return; + stride = rect.Width * format_info.BytesPerBlock; + frame_stride = width_in_blocks * format_info.BytesPerBlock; + frame_size = frame_stride * height_in_blocks; + + /* CopyBlocks tests */ + + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, 0, 0, NULL); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect_test_a, stride, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect_test_b, stride, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect_test_c, stride, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect_test_d, stride, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, frame_stride - 1, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, frame_stride * 2, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, frame_stride, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, frame_stride, frame_stride * height_in_blocks - 1, buffer); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, frame_stride, frame_stride * height_in_blocks, buffer); + ok(hr == S_OK, "CopyBlocks got unexpected hr %#lx\n", hr); + + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect, 0, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect, stride - 1, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect, stride * 2, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyBlocks got unexpected hr %#lx\n", hr); + + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect, stride, 0, buffer); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect, stride, 1, buffer); + ok(hr == E_INVALIDARG || (hr == S_OK && test->expected_bytes_per_block == 1), + "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect, stride, stride * rect.Height - 1, buffer); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect, stride, stride * rect.Height, buffer); + ok(hr == S_OK, "CopyBlocks got unexpected hr %#lx\n", hr); + + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect, stride, sizeof(buffer), NULL); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + + block_offset = 128; /* DDS magic and header */ + if (has_extended_header(test->data)) block_offset += 20; /* DDS extended header */ + width = params->Width; + height = params->Height; + depth = params->Depth; + slice_index = frame_index % (frame_count / params->ArraySize); + array_index = frame_index / (frame_count / params->ArraySize); + block_offset += (test->size - block_offset) / params->ArraySize * array_index; + while (slice_index >= 0) + { + width_in_blocks = (width + format_info.BlockWidth - 1) / format_info.BlockWidth; + height_in_blocks = (width + format_info.BlockWidth - 1) / format_info.BlockWidth; + block_offset += (slice_index >= depth) ? + (width_in_blocks * height_in_blocks * format_info.BytesPerBlock * depth) : + (width_in_blocks * height_in_blocks * format_info.BytesPerBlock * slice_index); + if (width > 1) width /= 2; + if (height > 1) height /= 2; + slice_index -= depth; + if (depth > 1) depth /= 2; + } + + memset(buffer, 0, sizeof(buffer)); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, &rect, stride, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyBlocks failed, hr %#lx\n", hr); + if (hr != S_OK) return; + ok(!memcmp(test->data + block_offset, buffer, format_info.BytesPerBlock), + "Block data mismatch\n"); + + memset(buffer, 0, sizeof(buffer)); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, frame_stride, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyBlocks failed, hr %#lx\n", hr); + if (hr != S_OK) return; + ok(!memcmp(test->data + block_offset, buffer, frame_size), + "Block data mismatch\n"); + + memset(buffer, 0, sizeof(buffer)); + memset(pixels, 0, sizeof(pixels)); + copy_pixels(test->data + block_offset, frame_stride, pixels, frame_stride * 2, frame_size); + hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, frame_stride * 2, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyBlocks failed, hr %#lx\n", hr); + if (hr != S_OK) return; + ok(!memcmp(pixels, buffer, frame_size), + "Block data mismatch\n"); + + /* CopyPixels tests */ + + bpp = test->pixel_format_bpp; + stride = rect.Width * bpp / 8; + frame_stride = frame_width * bpp / 8; + frame_size = frame_stride * frame_height; + + hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, 0, 0, NULL); + ok(hr == E_INVALIDARG, "CopyPixels got unexpected hr %#lx\n", hr); + + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect_test_a, stride, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect_test_b, stride, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect_test_c, stride, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect_test_d, stride, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyPixels got unexpected hr %#lx\n", hr); + + hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, frame_stride - 1, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, frame_stride * 2, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, frame_stride, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, frame_stride, frame_stride * frame_height - 1, buffer); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, frame_stride, frame_stride * frame_height, buffer); + ok(hr == S_OK, "CopyPixels got unexpected hr %#lx\n", hr); + + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, 0, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride - 1, sizeof(buffer), buffer); + ok(hr == E_INVALIDARG, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride * 2, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyPixels got unexpected hr %#lx\n", hr); + + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride, 0, buffer); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride, 1, buffer); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER || (hr == S_OK && test->expected_bytes_per_block == 1), + "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride, stride * rect.Height - 1, buffer); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "CopyPixels got unexpected hr %#lx\n", hr); + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride, stride * rect.Height, buffer); + ok(hr == S_OK, "CopyPixels got unexpected hr %#lx\n", hr); + + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride, sizeof(buffer), NULL); + ok(hr == E_INVALIDARG, "CopyBlocks got unexpected hr %#lx\n", hr); + + memset(buffer, 0, sizeof(pixels)); + if (is_compressed(format_info.DxgiFormat)) { + decode_block(test->data + block_offset, width_in_blocks * height_in_blocks, + format_info.DxgiFormat, frame_width, frame_height, (DWORD *)pixels); + } else { + memcpy(pixels, test->data + block_offset, frame_size); + } + + memset(buffer, 0, sizeof(buffer)); + hr = IWICBitmapFrameDecode_CopyPixels(frame, &rect, stride, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyPixels failed, hr %#lx\n", hr); + if (hr == S_OK) { + if (is_compressed(format_info.DxgiFormat)) { + ok(color_buffer_match((DWORD *)pixels, (DWORD *)buffer, 1), "Pixels mismatch\n"); + } else { + ok(!memcmp(pixels, buffer, bpp / 8), "Pixels mismatch\n"); + } + } + + memset(buffer, 0, sizeof(buffer)); + hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, frame_stride, sizeof(buffer), buffer); + ok(hr == S_OK, "CopyPixels failed, hr %#lx\n", hr); + if (hr == S_OK) { + if (is_compressed(format_info.DxgiFormat)) { + ok(color_buffer_match((DWORD *)pixels, (DWORD *)buffer, frame_size / (bpp / 8)), "Pixels mismatch\n"); + } else { + ok(!memcmp(pixels, buffer, frame_size), "Pixels mismatch\n"); + }; + } +} + +static void test_dds_decoder_frame(IWICBitmapDecoder *decoder, struct test_data *test) +{ + HRESULT hr; + IWICDdsDecoder *dds_decoder = NULL; + UINT frame_count, j; + WICDdsParameters params; + + hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); + ok(hr == S_OK, "GetFrameCount failed, hr %#lx\n", hr); + if (hr != S_OK) return; + hr = IWICBitmapDecoder_QueryInterface(decoder, &IID_IWICDdsDecoder, (void **)&dds_decoder); + ok(hr == S_OK, "QueryInterface failed, hr %#lx\n", hr); + if (hr != S_OK) goto end; + hr = IWICDdsDecoder_GetParameters(dds_decoder, ¶ms); + ok(hr == S_OK, "GetParameters failed, hr %#lx\n", hr); + if (hr != S_OK) goto end; + + if (test->expected_parameters.Dimension == WICDdsTextureCube) params.ArraySize *= 6; + + for (j = 0; j < frame_count; j++) + { + IWICBitmapFrameDecode *frame_decode = NULL; + IWICDdsFrameDecode *dds_frame = NULL; + + winetest_push_context("Frame %u", j); + + hr = IWICBitmapDecoder_GetFrame(decoder, j, &frame_decode); + ok(hr == S_OK, "GetFrame failed, hr %#lx\n", hr); + if (hr != S_OK) goto next; + hr = IWICBitmapFrameDecode_QueryInterface(frame_decode, &IID_IWICDdsFrameDecode, (void **)&dds_frame); + ok(hr == S_OK, "QueryInterface failed, hr %#lx\n", hr); + if (hr != S_OK) goto next; + + test_dds_decoder_frame_properties(frame_decode, dds_frame, frame_count, ¶ms, test, j); + test_dds_decoder_frame_data(frame_decode, dds_frame, frame_count, ¶ms, test, j); + + next: + if (frame_decode) IWICBitmapFrameDecode_Release(frame_decode); + if (dds_frame) IWICDdsFrameDecode_Release(dds_frame); + winetest_pop_context(); + } + +end: + if (dds_decoder) IWICDdsDecoder_Release(dds_decoder); +} + +static void test_dds_decoder(void) +{ + int i; + HRESULT hr; + + test_dds_decoder_initialize(); + test_dds_decoder_image_parameters(); + + for (i = 0; i < ARRAY_SIZE(test_data); i++) + { + IWICStream *stream = NULL; + IWICBitmapDecoder *decoder = NULL; + + if (test_data[i].init_hr != S_OK && !test_data[i].wine_init) continue; + + winetest_push_context("Test %u", i); + + stream = create_stream(test_data[i].data, test_data[i].size); + if (!stream) goto next; + decoder = create_decoder(); + if (!decoder) goto next; + hr = init_decoder(decoder, stream, test_data[i].init_hr, test_data[i].wine_init); + if (hr != S_OK) { + if (test_data[i].expected_parameters.Dimension == WICDdsTextureCube) { + win_skip("Cube map is not supported\n"); + } else { + win_skip("Uncompressed DDS image is not supported\n"); + } + goto next; + } + + test_dds_decoder_global_properties(decoder); + test_dds_decoder_frame(decoder, test_data + i); + + next: + if (decoder) IWICBitmapDecoder_Release(decoder); + if (stream) IWICStream_Release(stream); + winetest_pop_context(); + } +} + +static void test_dds_encoder_initialize(void) +{ + IWICBitmapEncoder *encoder = NULL; + IWICStream *stream = NULL; + BYTE buffer[1]; + HRESULT hr; + + encoder = create_encoder(); + if (!encoder) goto end; + + stream = create_stream(buffer, sizeof(buffer)); + if (!stream) goto end; + + /* initialize with invalid cache option */ + + hr = IWICBitmapEncoder_Initialize(encoder, (IStream *)stream, 0xdeadbeef); + todo_wine + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "Initialize got unexpected hr %#lx\n", hr); + + hr = IWICBitmapEncoder_Initialize(encoder, (IStream *)stream, WICBitmapEncoderNoCache); + todo_wine + ok(hr == E_INVALIDARG, "Initialize got unexpected hr %#lx\n", hr); + + IWICBitmapEncoder_Release(encoder); + + /* initialize with null stream */ + + encoder = create_encoder(); + if (!encoder) goto end; + + hr = IWICBitmapEncoder_Initialize(encoder, NULL, WICBitmapEncoderNoCache); + ok(hr == E_INVALIDARG, "Initialize got unexpected hr %#lx\n", hr); + + hr = IWICBitmapEncoder_Initialize(encoder, (IStream *)stream, WICBitmapEncoderNoCache); + ok(hr == S_OK, "Initialize failed, hr %#lx\n", hr); + + IWICBitmapEncoder_Release(encoder); + + /* regularly initialize */ + + encoder = create_encoder(); + if (!encoder) goto end; + + hr = IWICBitmapEncoder_Initialize(encoder, (IStream *)stream, WICBitmapEncoderNoCache); + ok(hr == S_OK, "Initialize failed, hr %#lx\n", hr); + + hr = IWICBitmapEncoder_Initialize(encoder, (IStream *)stream, WICBitmapEncoderNoCache); + ok(hr == WINCODEC_ERR_WRONGSTATE, "Initialize got unexpected hr %#lx\n", hr); + +end: + if (stream) IWICStream_Release(stream); + if (encoder) IWICBitmapEncoder_Release(encoder); +} + +static void test_dds_encoder_params(void) +{ + WICDdsParameters params, params_set = { 4, 4, 4, 3, 1, DXGI_FORMAT_BC1_UNORM, + WICDdsTexture3D, WICDdsAlphaModePremultiplied }; + IWICDdsEncoder *dds_encoder = NULL; + IWICBitmapEncoder *encoder = NULL; + IWICStream *stream = NULL; + BYTE buffer[1024]; + HRESULT hr; + UINT i; + + hr = create_and_init_encoder(buffer, sizeof(buffer), NULL, &encoder, &dds_encoder, &stream); + if (hr != S_OK) goto end; + + hr = IWICDdsEncoder_GetParameters(dds_encoder, NULL); + ok(hr == E_INVALIDARG, "GetParameters got unexpected hr %#lx\n", hr); + + hr = IWICDdsEncoder_GetParameters(dds_encoder, ¶ms); + ok(hr == S_OK, "GetParameters failed, hr %#lx\n", hr); + if (hr != S_OK) goto end; + + /* default DDS parameters for encoder */ + ok(params.Width == 1, "Got unexpected Width %u\n", params.Width); + ok(params.Height == 1, "Got unexpected Height %u\n", params.Height); + ok(params.Depth == 1, "Got unexpected Depth %u\n", params.Depth); + ok(params.MipLevels == 1, "Got unexpected MipLevels %u\n", params.MipLevels); + ok(params.ArraySize == 1, "Got unexpected ArraySize %u\n", params.ArraySize); + ok(params.DxgiFormat == DXGI_FORMAT_BC3_UNORM, "Got unexpected DxgiFormat %#x\n", params.DxgiFormat); + ok(params.Dimension == WICDdsTexture2D, "Got unexpected Dimension %#x\n", params.Dimension); + ok(params.AlphaMode == WICDdsAlphaModeUnknown, "Got unexpected AlphaMode %#x\n", params.AlphaMode); + + hr = IWICDdsEncoder_SetParameters(dds_encoder, NULL); + ok(hr == E_INVALIDARG, "SetParameters got unexpected hr %#lx\n", hr); + + hr = IWICDdsEncoder_SetParameters(dds_encoder, ¶ms_set); + ok(hr == S_OK, "SetParameters failed, hr %#lx\n", hr); + if (hr != S_OK) goto end; + + IWICDdsEncoder_GetParameters(dds_encoder, ¶ms); + + ok(params.Width == params_set.Width, + "Expected Width %u, got %u\n", params_set.Width, params.Width); + ok(params.Height == params_set.Height, + "Expected Height %u, got %u\n", params_set.Height, params.Height); + ok(params.Depth == params_set.Depth, + "Expected Depth %u, got %u\n", params_set.Depth, params.Depth); + ok(params.MipLevels == params_set.MipLevels, + "Expected MipLevels %u, got %u\n", params_set.MipLevels, params.MipLevels); + ok(params.ArraySize == params_set.ArraySize, + "Expected ArraySize %u, got %u\n", params_set.ArraySize, params.ArraySize); + ok(params.DxgiFormat == params_set.DxgiFormat, + "Expected DxgiFormat %u, got %#x\n", params_set.DxgiFormat, params.DxgiFormat); + ok(params.Dimension == params_set.Dimension, + "Expected Dimension %u, got %#x\n", params_set.Dimension, params.Dimension); + ok(params.AlphaMode == params_set.AlphaMode, + "Expected AlphaMode %u, got %#x\n", params_set.AlphaMode, params.AlphaMode); + + for (i = 0; i < ARRAY_SIZE(test_data); ++i) + { + hr = IWICDdsEncoder_SetParameters(dds_encoder, &test_data[i].expected_parameters); + todo_wine_if(test_data[i].init_hr != S_OK) + ok((hr == S_OK && test_data[i].init_hr == S_OK) || hr == WINCODEC_ERR_BADHEADER, + "Test %u: SetParameters got unexpected hr %#lx\n", i, hr); + } + +end: + release_encoder(encoder, dds_encoder, stream); +} + +static void test_dds_encoder_create_frame(void) +{ + WICDdsParameters params = { 4, 4, 1, 3, 1, DXGI_FORMAT_BC1_UNORM, + WICDdsTexture2D, WICDdsAlphaModePremultiplied }; + IWICBitmapFrameEncode *frame0 = NULL, *frame1 = NULL; + UINT array_index, mip_level, slice_index; + IWICDdsEncoder *dds_encoder = NULL; + IWICBitmapEncoder *encoder = NULL; + IWICStream *stream = NULL; + BYTE buffer[1024]; + HRESULT hr; + + hr = create_and_init_encoder(buffer, sizeof(buffer), ¶ms, &encoder, &dds_encoder, &stream); + if (hr != S_OK) goto end; + + hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frame0, NULL); + ok(hr == S_OK, "CreateNewFrame failed, hr %#lx\n", hr); + hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frame1, NULL); + ok(hr == WINCODEC_ERR_WRONGSTATE, "CreateNewFrame got unexpected hr %#lx\n", hr); + + IWICBitmapFrameEncode_Release(frame0); + hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frame1, NULL); + ok(hr == WINCODEC_ERR_WRONGSTATE, "CreateNewFrame got unexpected hr %#lx\n", hr); + + release_encoder(encoder, dds_encoder, stream); + + create_and_init_encoder(buffer, sizeof(buffer), ¶ms, &encoder, &dds_encoder, &stream); + hr = IWICDdsEncoder_CreateNewFrame(dds_encoder, &frame0, &array_index, &mip_level, &slice_index); + ok(hr == S_OK, "CreateNewFrame failed, hr %#lx\n", hr); + IWICBitmapFrameEncode_Release(frame0); + release_encoder(encoder, dds_encoder, stream); + + create_and_init_encoder(buffer, sizeof(buffer), ¶ms, &encoder, &dds_encoder, &stream); + hr = IWICDdsEncoder_CreateNewFrame(dds_encoder, &frame0, NULL, NULL, NULL); + ok(hr == S_OK, "CreateNewFrame failed, hr %#lx\n", hr); + IWICBitmapFrameEncode_Release(frame0); + +end: + release_encoder(encoder, dds_encoder, stream); +} + +static void test_dds_encoder_pixel_format(void) +{ + DXGI_FORMAT image_formats[] = { DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC3_UNORM }; + const WICPixelFormatGUID *test_formats[] = + { + &GUID_WICPixelFormat8bppIndexed, + &GUID_WICPixelFormatBlackWhite, + &GUID_WICPixelFormat16bppGray, + &GUID_WICPixelFormat8bppAlpha, + &GUID_WICPixelFormat16bppBGR555, + &GUID_WICPixelFormat16bppBGR565, + &GUID_WICPixelFormat24bppBGR, + &GUID_WICPixelFormat32bppBGR, + &GUID_WICPixelFormat32bppBGRA, + &GUID_WICPixelFormat32bppPBGRA, + &GUID_WICPixelFormat32bppRGB, + &GUID_WICPixelFormat32bppRGBA, + &GUID_WICPixelFormat32bppPRGBA, + &GUID_WICPixelFormat48bppRGB, + &GUID_WICPixelFormat64bppRGB, + &GUID_WICPixelFormat64bppRGBA + }; + IWICBitmapFrameEncode *frame = NULL; + IWICDdsEncoder *dds_encoder = NULL; + IWICBitmapEncoder *encoder = NULL; + IWICStream *stream = NULL; + WICPixelFormatGUID format; + WICDdsParameters params; + BYTE buffer[1]; + HRESULT hr; + UINT i, j; + + for (i = 0; i < ARRAY_SIZE(image_formats); ++i) + { + hr = create_and_init_encoder(buffer, sizeof(buffer), NULL, &encoder, &dds_encoder, &stream); + if (hr != S_OK) + { + release_encoder(encoder, dds_encoder, stream); + return; + } + + IWICDdsEncoder_GetParameters(dds_encoder, ¶ms); + params.DxgiFormat = image_formats[i]; + IWICDdsEncoder_SetParameters(dds_encoder, ¶ms); + + IWICBitmapEncoder_CreateNewFrame(encoder, &frame, NULL); + + hr = IWICBitmapFrameEncode_SetPixelFormat(frame, &format); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "SetPixelFormat got unexpected hr %#lx\n", hr); + + IWICBitmapFrameEncode_Initialize(frame, NULL); + + for (j = 0; j < ARRAY_SIZE(test_formats); ++j) + { + winetest_push_context("Test %u", j); + + format = *(test_formats[j]); + hr = IWICBitmapFrameEncode_SetPixelFormat(frame, &format); + ok(hr == S_OK, "SetPixelFormat failed, hr %#lx\n", hr); + ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppBGRA), + "Got unexpected GUID %s\n", debugstr_guid(&format)); + + winetest_pop_context(); + } + + IWICBitmapFrameEncode_Release(frame); + release_encoder(encoder, dds_encoder, stream); + } +} + +static void test_dds_encoder(void) +{ + test_dds_encoder_initialize(); + test_dds_encoder_params(); + test_dds_encoder_create_frame(); + test_dds_encoder_pixel_format(); +} + +START_TEST(ddsformat) +{ + HRESULT hr; + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICImagingFactory, (void **)&factory); + ok(hr == S_OK, "CoCreateInstance failed, hr %#lx\n", hr); + if (hr != S_OK) goto end; + + test_dds_decoder(); + test_dds_encoder(); + +end: + if (factory) IWICImagingFactory_Release(factory); + CoUninitialize(); +} diff --git a/modules/rostests/winetests/windowscodecs/gifformat.c b/modules/rostests/winetests/windowscodecs/gifformat.c index 05affadca4d..08f8ba1c12b 100644 --- a/modules/rostests/winetests/windowscodecs/gifformat.c +++ b/modules/rostests/winetests/windowscodecs/gifformat.c @@ -57,6 +57,13 @@ static const char gif_local_palette[] = { 0x02,0x02,0x44,0x01,0x00,0x3b }; +static const char gif_no_palette[] = { +/* LSD */'G','I','F','8','7','a',0x01,0x00,0x01,0x00,0x21,0x02,0x00, +/* GCE */0x21,0xf9,0x04,0x01,0x05,0x00,0x01,0x00, /* index 1 */ +/* IMD */0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00, +0x02,0x02,0x44,0x01,0x00,0x3b +}; + /* Generated with ImageMagick: * convert -delay 100 -size 2x2 xc:red \ * -dispose none -page +0+0 -size 2x1 xc:white \ @@ -93,7 +100,7 @@ static IStream *create_stream(const void *image_data, UINT image_size) GlobalUnlock(hmem); hr = CreateStreamOnHGlobal(hmem, TRUE, &stream); - ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr); + ok(hr == S_OK, "CreateStreamOnHGlobal error %#lx\n", hr); return stream; } @@ -110,10 +117,10 @@ static IWICBitmapDecoder *create_decoder(const void *image_data, UINT image_size if (!stream) return NULL; hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder); - ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr); + ok(hr == S_OK, "CreateDecoderFromStream error %#lx\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); @@ -137,18 +144,18 @@ static void test_global_gif_palette(void) ok(decoder != 0, "Failed to load GIF image data\n"); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); /* global palette */ hr = IWICBitmapDecoder_CopyPalette(decoder, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]); @@ -157,22 +164,22 @@ static void test_global_gif_palette(void) /* frame palette */ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), "wrong pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]); @@ -199,21 +206,21 @@ static void test_global_gif_palette_2frames(void) /* active frame 0, GCE transparent index 1 */ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); /* global palette */ hr = IWICBitmapDecoder_CopyPalette(decoder, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]); @@ -222,19 +229,19 @@ static void test_global_gif_palette_2frames(void) /* frame 0 palette */ hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), "wrong pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]); @@ -245,18 +252,18 @@ static void test_global_gif_palette_2frames(void) /* active frame 1, GCE transparent index 2 */ hr = IWICBitmapDecoder_GetFrame(decoder, 1, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); /* global palette */ hr = IWICBitmapDecoder_CopyPalette(decoder, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0xff040506 || broken(color[1] == 0x00040506) /* XP */, "expected 0xff040506, got %#x\n", color[1]); @@ -265,19 +272,19 @@ static void test_global_gif_palette_2frames(void) /* frame 1 palette */ hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), "wrong pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0xff040506, "expected 0xff040506, got %#x\n", color[1]); @@ -304,24 +311,24 @@ static void test_local_gif_palette(void) ok(decoder != 0, "Failed to load GIF image data\n"); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); /* global palette */ hr = IWICBitmapDecoder_CopyPalette(decoder, palette); - ok(hr == S_OK || broken(hr == WINCODEC_ERR_FRAMEMISSING), "CopyPalette %#x\n", hr); + ok(hr == S_OK || broken(hr == WINCODEC_ERR_FRAMEMISSING), "CopyPalette %#lx\n", hr); if (hr == S_OK) { type = -1; hr = IWICPalette_GetType(palette, &type); - ok(hr == S_OK, "GetType error %#x\n", hr); + ok(hr == S_OK, "GetType error %#lx\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 256, "expected 256, got %u\n", count); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff000000, "expected 0xff000000, got %#x\n", color[0]); ok(color[1] == 0x00ffffff, "expected 0x00ffffff, got %#x\n", color[1]); @@ -332,27 +339,27 @@ static void test_local_gif_palette(void) /* frame palette */ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), "wrong pixel format %s\n", wine_dbgstr_guid(&format)); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); type = -1; hr = IWICPalette_GetType(palette, &type); - ok(hr == S_OK, "GetType error %#x\n", hr); + ok(hr == S_OK, "GetType error %#lx\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]); @@ -364,6 +371,67 @@ static void test_local_gif_palette(void) IWICBitmapDecoder_Release(decoder); } +static void test_no_gif_palette(void) +{ + HRESULT hr; + IWICBitmapDecoder *decoder; + IWICBitmapFrameDecode *frame; + IWICPalette *palette; + GUID format; + UINT count, ret; + WICColor color[256]; + + decoder = create_decoder(gif_no_palette, sizeof(gif_no_palette)); + ok(decoder != 0, "Failed to load GIF image data\n"); + + hr = IWICImagingFactory_CreatePalette(factory, &palette); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); + + /* global palette */ + hr = IWICBitmapDecoder_CopyPalette(decoder, palette); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); + + hr = IWICPalette_GetColorCount(palette, &count); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); + ok(count == 4, "expected 4, got %u\n", count); + + hr = IWICPalette_GetColors(palette, count, color, &ret); + ok(hr == S_OK, "GetColors error %#lx\n", hr); + ok(ret == count, "expected %u, got %u\n", count, ret); + ok(color[0] == 0xff000000, "expected 0xff000000, got %#x\n", color[0]); + ok(color[1] == 0x00ffffff, "expected 0x00ffffff, got %#x\n", color[1]); + ok(color[2] == 0xff000000, "expected 0xff000000, got %#x\n", color[2]); + ok(color[3] == 0xff000000, "expected 0xff000000, got %#x\n", color[3]); + + /* frame palette */ + hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); + + hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); + ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), + "wrong pixel format %s\n", wine_dbgstr_guid(&format)); + + hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); + + hr = IWICPalette_GetColorCount(palette, &count); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); + ok(count == 4, "expected 4, got %u\n", count); + + hr = IWICPalette_GetColors(palette, count, color, &ret); + ok(hr == S_OK, "GetColors error %#lx\n", hr); + ok(ret == count, "expected %u, got %u\n", count, ret); + ok(color[0] == 0xff000000, "expected 0xff000000, got %#x\n", color[0]); + ok(color[1] == 0x00ffffff, "expected 0x00ffffff, got %#x\n", color[1]); + ok(color[2] == 0xff000000, "expected 0xff000000, got %#x\n", color[2]); + ok(color[3] == 0xff000000, "expected 0xff000000, got %#x\n", color[3]); + + IWICPalette_Release(palette); + IWICBitmapFrameDecode_Release(frame); + IWICBitmapDecoder_Release(decoder); +} + static void test_gif_frame_sizes(void) { static const BYTE frame0[] = {0, 1, 0xfe, 0xfe, 2, 3, 0xfe, 0xfe}; @@ -379,32 +447,32 @@ static void test_gif_frame_sizes(void) ok(decoder != 0, "Failed to load GIF image data\n"); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height); - ok(hr == S_OK, "GetSize error %x\n", hr); + ok(hr == S_OK, "GetSize error %lx\n", hr); ok(width == 2, "width = %d\n", width); ok(height == 2, "height = %d\n", height); memset(buf, 0xfe, sizeof(buf)); hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, 4, sizeof(buf), buf); - ok(hr == S_OK, "CopyPixels error %x\n", hr); + ok(hr == S_OK, "CopyPixels error %lx\n", hr); ok(!memcmp(buf, frame0, sizeof(buf)), "buf = %x %x %x %x %x %x %x %x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); IWICBitmapFrameDecode_Release(frame); hr = IWICBitmapDecoder_GetFrame(decoder, 1, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height); - ok(hr == S_OK, "GetSize error %x\n", hr); + ok(hr == S_OK, "GetSize error %lx\n", hr); ok(width == 2, "width = %d\n", width); ok(height == 1, "height = %d\n", height); memset(buf, 0xfe, sizeof(buf)); hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, 4, sizeof(buf), buf); - ok(hr == S_OK, "CopyPixels error %x\n", hr); + ok(hr == S_OK, "CopyPixels error %lx\n", hr); ok(!memcmp(buf, frame1, sizeof(buf)), "buf = %x %x %x %x %x %x %x %x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); @@ -448,9 +516,9 @@ static void test_truncated_gif(void) if (!stream) return; hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder); - ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr); + ok(hr == S_OK, "CreateDecoderFromStream error %#lx\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); IWICBitmapDecoder_Release(decoder); @@ -459,9 +527,9 @@ static void test_truncated_gif(void) stream = create_stream(gif_with_trailer_2, sizeof(gif_with_trailer_2)); if (!stream) return; hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder); - ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr); + ok(hr == S_OK, "CreateDecoderFromStream error %#lx\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); IWICBitmapDecoder_Release(decoder); @@ -470,9 +538,9 @@ static void test_truncated_gif(void) stream = create_stream(gif_without_trailer_1, sizeof(gif_without_trailer_1)); if (!stream) return; hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder); - ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr); + ok(hr == S_OK, "CreateDecoderFromStream error %#lx\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); IWICBitmapDecoder_Release(decoder); @@ -481,9 +549,9 @@ static void test_truncated_gif(void) stream = create_stream(gif_without_trailer_2, sizeof(gif_without_trailer_2)); if (!stream) return; hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder); - ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr); + ok(hr == S_OK, "CreateDecoderFromStream error %#lx\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); IWICBitmapDecoder_Release(decoder); @@ -509,38 +577,38 @@ static void test_gif_notrailer(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; hr = IWICImagingFactory_CreateStream(factory, &gifstream); - ok(hr == S_OK, "CreateStream failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateStream failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICStream_InitializeFromMemory(gifstream, gifimage_notrailer, sizeof(gifimage_notrailer)); - ok(hr == S_OK, "InitializeFromMemory failed, hr=%x\n", hr); + ok(hr == S_OK, "InitializeFromMemory failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = CoCreateInstance(&CLSID_WICGifDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); } if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_Initialize(decoder, (IStream*)gifstream, WICDecodeMetadataCacheOnDemand); - ok(hr == S_OK, "Initialize failed, hr=%x\n", hr); + ok(hr == S_OK, "Initialize failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); - ok(hr == S_OK, "GetFrame failed, hr=%x\n", hr); + ok(hr == S_OK, "GetFrame failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapFrameDecode_GetResolution(framedecode, &dpiX, &dpiY); - ok(SUCCEEDED(hr), "GetResolution failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetResolution failed, hr=%lx\n", hr); ok(dpiX == 48.0, "expected dpiX=48.0, got %f\n", dpiX); ok(dpiY == 96.0, "expected dpiY=96.0, got %f\n", dpiY); @@ -551,7 +619,7 @@ static void test_gif_notrailer(void) if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_GetFrameCount(decoder, &framecount); - ok(hr == S_OK, "GetFrameCount failed, hr=%x\n", hr); + ok(hr == S_OK, "GetFrameCount failed, hr=%lx\n", hr); ok(framecount == 1, "framecount=%u\n", framecount); } @@ -571,12 +639,13 @@ START_TEST(gifformat) CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void **)&factory); - ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); if (FAILED(hr)) return; test_global_gif_palette(); test_global_gif_palette_2frames(); test_local_gif_palette(); + test_no_gif_palette(); test_gif_frame_sizes(); test_gif_notrailer(); @@ -585,11 +654,12 @@ START_TEST(gifformat) /* run the same tests with no COM initialization */ hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory); - ok(hr == S_OK, "WICCreateImagingFactory_Proxy error %#x\n", hr); + ok(hr == S_OK, "WICCreateImagingFactory_Proxy error %#lx\n", hr); test_global_gif_palette(); test_global_gif_palette_2frames(); test_local_gif_palette(); + test_no_gif_palette(); test_gif_frame_sizes(); test_truncated_gif(); diff --git a/modules/rostests/winetests/windowscodecs/icoformat.c b/modules/rostests/winetests/windowscodecs/icoformat.c index 38db51c3764..71a9dd88f04 100644 --- a/modules/rostests/winetests/windowscodecs/icoformat.c +++ b/modules/rostests/winetests/windowscodecs/icoformat.c @@ -143,34 +143,34 @@ static void test_ico_data_(void *data, DWORD data_size, HRESULT init_hr, int tod hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; hr = IWICImagingFactory_CreateStream(factory, &icostream); - ok(hr == S_OK, "CreateStream failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateStream failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICStream_InitializeFromMemory(icostream, data, data_size); - ok(hr == S_OK, "InitializeFromMemory failed, hr=%x\n", hr); + ok(hr == S_OK, "InitializeFromMemory failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = CoCreateInstance(&CLSID_WICIcoDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); } if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_Initialize(decoder, (IStream*)icostream, WICDecodeMetadataCacheOnDemand); - todo_wine_if(todo) - ok_(__FILE__, line)(hr == init_hr, "Initialize failed, hr=%x\n", hr); + todo_wine_if(todo) + ok_(__FILE__, line)(hr == init_hr, "Initialize failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); - ok(hr == S_OK, "GetFrame failed, hr=%x\n", hr); + ok(hr == S_OK, "GetFrame failed, hr=%lx\n", hr); } if (SUCCEEDED(hr)) @@ -180,16 +180,16 @@ static void test_ico_data_(void *data, DWORD data_size, HRESULT init_hr, int tod width = height = 0; hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); - ok(hr == S_OK, "GetFrameSize failed, hr=%x\n", hr); + ok(hr == S_OK, "GetFrameSize failed, hr=%lx\n", hr); ok(width == 16 && height == 16, "framesize=%ux%u\n", width, height); hr = IWICBitmapFrameDecode_GetThumbnail(framedecode, &thumbnail); - ok(hr == S_OK, "GetThumbnail failed, hr=%x\n", hr); + ok(hr == S_OK, "GetThumbnail failed, hr=%lx\n", hr); if (hr == S_OK) { width = height = 0; hr = IWICBitmapSource_GetSize(thumbnail, &width, &height); - ok(hr == S_OK, "GetFrameSize failed, hr=%x\n", hr); + ok(hr == S_OK, "GetFrameSize failed, hr=%lx\n", hr); ok(width == 16 && height == 16, "framesize=%ux%u\n", width, height); IWICBitmapSource_Release(thumbnail); } diff --git a/modules/rostests/winetests/windowscodecs/info.c b/modules/rostests/winetests/windowscodecs/info.c index ee957841667..9f184a8953b 100644 --- a/modules/rostests/winetests/windowscodecs/info.c +++ b/modules/rostests/winetests/windowscodecs/info.c @@ -28,9 +28,6 @@ #include "wincodecsdk.h" #include "wine/test.h" -#include "initguid.h" -DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); - static HRESULT get_component_info(const GUID *clsid, IWICComponentInfo **result) { IWICImagingFactory *factory; @@ -38,7 +35,7 @@ static HRESULT get_component_info(const GUID *clsid, IWICComponentInfo **result) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return hr; hr = IWICImagingFactory_CreateComponentInfo(factory, clsid, result); @@ -108,11 +105,16 @@ static void test_decoder_info(void) ".tiff,.tif", 1 }, + { + &CLSID_WICDdsDecoder, + "image/vnd.ms-dds", + ".dds", + } }; IWICBitmapDecoderInfo *decoder_info, *decoder_info2; IWICComponentInfo *info; HRESULT hr; - ULONG len; + UINT len; WCHAR value[256]; CLSID clsid; GUID pixelformats[32]; @@ -127,22 +129,26 @@ static void test_decoder_info(void) WCHAR mimetypeW[64]; hr = CoCreateInstance(test->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void **)&decoder); - ok(SUCCEEDED(hr), "Failed to create decoder, hr %#x.\n", hr); + if (test->clsid == &CLSID_WICDdsDecoder && hr != S_OK) { + win_skip("DDS decoder is not supported\n"); + continue; + } + ok(SUCCEEDED(hr), "Failed to create decoder, hr %#lx.\n", hr); decoder_info = NULL; hr = IWICBitmapDecoder_GetDecoderInfo(decoder, &decoder_info); ok(hr == S_OK || broken(IsEqualCLSID(&CLSID_WICBmpDecoder, test->clsid) && FAILED(hr)) /* Fails on Windows */, - "%u: failed to get decoder info, hr %#x.\n", i, hr); + "%u: failed to get decoder info, hr %#lx.\n", i, hr); if (hr == S_OK) { decoder_info2 = NULL; hr = IWICBitmapDecoder_GetDecoderInfo(decoder, &decoder_info2); - ok(hr == S_OK, "Failed to get decoder info, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to get decoder info, hr %#lx.\n", hr); ok(decoder_info == decoder_info2, "Unexpected decoder info instance.\n"); hr = IWICBitmapDecoderInfo_QueryInterface(decoder_info, &IID_IWICBitmapDecoder, (void **)&decoder2); - ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr); IWICBitmapDecoderInfo_Release(decoder_info); IWICBitmapDecoderInfo_Release(decoder_info2); @@ -153,126 +159,126 @@ static void test_decoder_info(void) MultiByteToWideChar(CP_ACP, 0, test->extensions, -1, extensionsW, ARRAY_SIZE(extensionsW)); hr = get_component_info(test->clsid, &info); - ok(hr == S_OK, "CreateComponentInfo failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateComponentInfo failed, hr=%lx\n", hr); hr = IWICComponentInfo_QueryInterface(info, &IID_IWICBitmapDecoderInfo, (void **)&decoder_info); - ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryInterface failed, hr=%lx\n", hr); hr = IWICBitmapDecoderInfo_GetCLSID(decoder_info, NULL); - ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%lx\n", hr); hr = IWICBitmapDecoderInfo_GetCLSID(decoder_info, &clsid); - ok(hr == S_OK, "GetCLSID failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCLSID failed, hr=%lx\n", hr); ok(IsEqualGUID(test->clsid, &clsid), "GetCLSID returned wrong result\n"); hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "GetMimeType failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetMimeType failed, hr=%lx\n", hr); len = 0; hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 1, NULL, &len); - ok(hr == E_INVALIDARG, "GetMimeType failed, hr=%x\n", hr); - todo_wine_if(test->todo) + ok(hr == E_INVALIDARG, "GetMimeType failed, hr=%lx\n", hr); + todo_wine_if(test->todo) ok(len == lstrlenW(mimetypeW) + 1, "GetMimeType returned wrong len %i\n", len); hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, len, value, NULL); - ok(hr == E_INVALIDARG, "GetMimeType failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetMimeType failed, hr=%lx\n", hr); len = 0; hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 0, NULL, &len); - ok(hr == S_OK, "GetMimeType failed, hr=%x\n", hr); - todo_wine_if(test->todo) + ok(hr == S_OK, "GetMimeType failed, hr=%lx\n", hr); + todo_wine_if(test->todo) ok(len == lstrlenW(mimetypeW) + 1, "GetMimeType returned wrong len %i\n", len); value[0] = 0; hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, len, value, &len); - ok(hr == S_OK, "GetMimeType failed, hr=%x\n", hr); + ok(hr == S_OK, "GetMimeType failed, hr=%lx\n", hr); todo_wine_if(test->todo) { ok(lstrcmpW(value, mimetypeW) == 0, "GetMimeType returned wrong value %s\n", wine_dbgstr_w(value)); ok(len == lstrlenW(mimetypeW) + 1, "GetMimeType returned wrong len %i\n", len); } hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 1, value, &len); - ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetMimeType failed, hr=%x\n", hr); - todo_wine_if(test->todo) + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetMimeType failed, hr=%lx\n", hr); + todo_wine_if(test->todo) ok(len == lstrlenW(mimetypeW) + 1, "GetMimeType returned wrong len %i\n", len); hr = IWICBitmapDecoderInfo_GetMimeTypes(decoder_info, 256, value, &len); - ok(hr == S_OK, "GetMimeType failed, hr=%x\n", hr); + ok(hr == S_OK, "GetMimeType failed, hr=%lx\n", hr); todo_wine_if(test->todo) { ok(lstrcmpW(value, mimetypeW) == 0, "GetMimeType returned wrong value %s\n", wine_dbgstr_w(value)); ok(len == lstrlenW(mimetypeW) + 1, "GetMimeType returned wrong len %i\n", len); } num_formats = 0xdeadbeef; hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, 0, NULL, &num_formats); - ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr); + ok(hr == S_OK, "GetPixelFormats failed, hr=%lx\n", hr); ok((num_formats <= 21 && num_formats >= 1) || broken(IsEqualCLSID(test->clsid, &CLSID_WICIcoDecoder) && num_formats == 0) /* WinXP */, "%u: got %d formats\n", i, num_formats); hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "GetPixelFormats failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetPixelFormats failed, hr=%lx\n", hr); count = 0xdeadbeef; hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, 0, pixelformats, &count); - ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr); + ok(hr == S_OK, "GetPixelFormats failed, hr=%lx\n", hr); ok(count == 0, "got %d formats\n", count); count = 0xdeadbeef; hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, 1, pixelformats, &count); - ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr); + ok(hr == S_OK, "GetPixelFormats failed, hr=%lx\n", hr); ok((count == 1) || broken(IsEqualCLSID(test->clsid, &CLSID_WICIcoDecoder) && count == 0) /* WinXP */, "%u: got %d formats\n", i, num_formats); ok(is_pixelformat(&pixelformats[0]), "got invalid pixel format\n"); count = 0xdeadbeef; hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, num_formats, pixelformats, &count); - ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr); + ok(hr == S_OK, "GetPixelFormats failed, hr=%lx\n", hr); ok(count == num_formats, "got %d formats, expected %d\n", count, num_formats); for (j = 0; j < num_formats; j++) ok(is_pixelformat(&pixelformats[j]), "got invalid pixel format\n"); hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, num_formats, pixelformats, NULL); - ok(hr == E_INVALIDARG, "GetPixelFormats failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetPixelFormats failed, hr=%lx\n", hr); count = 0xdeadbeef; hr = IWICBitmapDecoderInfo_GetPixelFormats(decoder_info, ARRAY_SIZE(pixelformats), pixelformats, &count); - ok(hr == S_OK, "GetPixelFormats failed, hr=%x\n", hr); + ok(hr == S_OK, "GetPixelFormats failed, hr=%lx\n", hr); ok(count == num_formats, "got %d formats, expected %d\n", count, num_formats); hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "GetFileExtensions failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetFileExtensions failed, hr=%lx\n", hr); hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 1, NULL, &len); - ok(hr == E_INVALIDARG, "GetFileExtensions failed, hr=%x\n", hr); - todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) + ok(hr == E_INVALIDARG, "GetFileExtensions failed, hr=%lx\n", hr); + todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) ok(len == lstrlenW(extensionsW) + 1, "%u: GetFileExtensions returned wrong len %i\n", i, len); hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, len, value, NULL); - ok(hr == E_INVALIDARG, "GetFileExtensions failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetFileExtensions failed, hr=%lx\n", hr); hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 0, NULL, &len); - ok(hr == S_OK, "GetFileExtensions failed, hr=%x\n", hr); - todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) + ok(hr == S_OK, "GetFileExtensions failed, hr=%lx\n", hr); + todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) ok(len == lstrlenW(extensionsW) + 1, "GetFileExtensions returned wrong len %i\n", len); value[0] = 0; hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, len, value, &len); - ok(hr == S_OK, "GetFileExtensions failed, hr=%x\n", hr); - todo_wine_if(test->todo) + ok(hr == S_OK, "GetFileExtensions failed, hr=%lx\n", hr); + todo_wine_if(test->todo) ok(lstrcmpW(value, extensionsW) == 0, "GetFileExtensions returned wrong value %s\n", wine_dbgstr_w(value)); - todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) + todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) ok(len == lstrlenW(extensionsW) + 1, "GetFileExtensions returned wrong len %i\n", len); hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 1, value, &len); - ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetFileExtensions failed, hr=%x\n", hr); - todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetFileExtensions failed, hr=%lx\n", hr); + todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) ok(len == lstrlenW(extensionsW) + 1, "GetFileExtensions returned wrong len %i\n", len); hr = IWICBitmapDecoderInfo_GetFileExtensions(decoder_info, 256, value, &len); - ok(hr == S_OK, "GetFileExtensions failed, hr=%x\n", hr); - todo_wine_if(test->todo) + ok(hr == S_OK, "GetFileExtensions failed, hr=%lx\n", hr); + todo_wine_if(test->todo) ok(lstrcmpW(value, extensionsW) == 0, "GetFileExtensions returned wrong value %s\n", wine_dbgstr_w(value)); - todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) + todo_wine_if(test->todo && !IsEqualCLSID(test->clsid, &CLSID_WICTiffDecoder)) ok(len == lstrlenW(extensionsW) + 1, "GetFileExtensions returned wrong len %i\n", len); IWICBitmapDecoderInfo_Release(decoder_info); @@ -286,7 +292,7 @@ static void test_pixelformat_info(void) IWICPixelFormatInfo *pixelformat_info; IWICPixelFormatInfo2 *pixelformat_info2; HRESULT hr; - ULONG len, known_len; + UINT len, known_len; WCHAR value[256]; GUID guid; WICComponentType componenttype; @@ -297,29 +303,29 @@ static void test_pixelformat_info(void) BOOL supportstransparency; hr = get_component_info(&GUID_WICPixelFormat32bppBGRA, &info); - ok(hr == S_OK, "CreateComponentInfo failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateComponentInfo failed, hr=%lx\n", hr); if (FAILED(hr)) return; hr = IWICComponentInfo_GetAuthor(info, 0, NULL, 0); - ok(hr == E_INVALIDARG, "GetAuthor failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetAuthor failed, hr=%lx\n", hr); len = 0xdeadbeef; hr = IWICComponentInfo_GetAuthor(info, 0, NULL, &len); - ok(hr == S_OK, "GetAuthor failed, hr=%x\n", hr); + ok(hr == S_OK, "GetAuthor failed, hr=%lx\n", hr); ok(len < 255 && len > 0, "invalid length 0x%x\n", len); known_len = len; memset(value, 0xaa, 256 * sizeof(WCHAR)); hr = IWICComponentInfo_GetAuthor(info, len-1, value, NULL); - ok(hr == E_INVALIDARG, "GetAuthor failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetAuthor failed, hr=%lx\n", hr); ok(value[0] == 0xaaaa, "string modified\n"); len = 0xdeadbeef; memset(value, 0xaa, 256 * sizeof(WCHAR)); hr = IWICComponentInfo_GetAuthor(info, known_len-1, value, &len); - ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetAuthor failed, hr=%x\n", hr); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "GetAuthor failed, hr=%lx\n", hr); ok(len == known_len, "got length of 0x%x, expected 0x%x\n", len, known_len); ok(value[known_len-1] == 0xaaaa, "string modified past given length\n"); ok(value[0] == 0xaaaa, "string modified\n"); @@ -327,7 +333,7 @@ static void test_pixelformat_info(void) len = 0xdeadbeef; memset(value, 0xaa, 256 * sizeof(WCHAR)); hr = IWICComponentInfo_GetAuthor(info, known_len, value, &len); - ok(hr == S_OK, "GetAuthor failed, hr=%x\n", hr); + ok(hr == S_OK, "GetAuthor failed, hr=%lx\n", hr); ok(len == known_len, "got length of 0x%x, expected 0x%x\n", len, known_len); ok(value[known_len-1] == 0, "string not terminated at expected length\n"); ok(value[known_len-2] != 0xaaaa, "string not modified at given length\n"); @@ -335,107 +341,107 @@ static void test_pixelformat_info(void) len = 0xdeadbeef; memset(value, 0xaa, 256 * sizeof(WCHAR)); hr = IWICComponentInfo_GetAuthor(info, known_len+1, value, &len); - ok(hr == S_OK, "GetAuthor failed, hr=%x\n", hr); + ok(hr == S_OK, "GetAuthor failed, hr=%lx\n", hr); ok(len == known_len, "got length of 0x%x, expected 0x%x\n", len, known_len); ok(value[known_len] == 0xaaaa, "string modified past end\n"); ok(value[known_len-1] == 0, "string not terminated at expected length\n"); ok(value[known_len-2] != 0xaaaa, "string not modified at given length\n"); hr = IWICComponentInfo_GetCLSID(info, NULL); - ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%lx\n", hr); memset(&guid, 0xaa, sizeof(guid)); hr = IWICComponentInfo_GetCLSID(info, &guid); - ok(hr == S_OK, "GetCLSID failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCLSID failed, hr=%lx\n", hr); ok(IsEqualGUID(&guid, &GUID_WICPixelFormat32bppBGRA), "unexpected CLSID %s\n", wine_dbgstr_guid(&guid)); hr = IWICComponentInfo_GetComponentType(info, NULL); - ok(hr == E_INVALIDARG, "GetComponentType failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetComponentType failed, hr=%lx\n", hr); hr = IWICComponentInfo_GetComponentType(info, &componenttype); - ok(hr == S_OK, "GetComponentType failed, hr=%x\n", hr); + ok(hr == S_OK, "GetComponentType failed, hr=%lx\n", hr); ok(componenttype == WICPixelFormat, "unexpected component type 0x%x\n", componenttype); len = 0xdeadbeef; hr = IWICComponentInfo_GetFriendlyName(info, 0, NULL, &len); - ok(hr == S_OK, "GetFriendlyName failed, hr=%x\n", hr); + ok(hr == S_OK, "GetFriendlyName failed, hr=%lx\n", hr); ok(len < 255 && len > 0, "invalid length 0x%x\n", len); hr = IWICComponentInfo_GetSigningStatus(info, NULL); - ok(hr == E_INVALIDARG, "GetSigningStatus failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetSigningStatus failed, hr=%lx\n", hr); hr = IWICComponentInfo_GetSigningStatus(info, &signing); - ok(hr == S_OK, "GetSigningStatus failed, hr=%x\n", hr); - ok(signing == WICComponentSigned, "unexpected signing status 0x%x\n", signing); + ok(hr == S_OK, "GetSigningStatus failed, hr=%lx\n", hr); + ok(signing == WICComponentSigned, "unexpected signing status 0x%lx\n", signing); len = 0xdeadbeef; hr = IWICComponentInfo_GetSpecVersion(info, 0, NULL, &len); - ok(hr == S_OK, "GetSpecVersion failed, hr=%x\n", hr); + ok(hr == S_OK, "GetSpecVersion failed, hr=%lx\n", hr); ok(len == 0, "invalid length 0x%x\n", len); /* spec version does not apply to pixel formats */ memset(&guid, 0xaa, sizeof(guid)); hr = IWICComponentInfo_GetVendorGUID(info, &guid); - ok(hr == S_OK, "GetVendorGUID failed, hr=%x\n", hr); + ok(hr == S_OK, "GetVendorGUID failed, hr=%lx\n", hr); ok(IsEqualGUID(&guid, &GUID_VendorMicrosoft) || broken(IsEqualGUID(&guid, &GUID_NULL)) /* XP */, "unexpected GUID %s\n", wine_dbgstr_guid(&guid)); len = 0xdeadbeef; hr = IWICComponentInfo_GetVersion(info, 0, NULL, &len); - ok(hr == S_OK, "GetVersion failed, hr=%x\n", hr); + ok(hr == S_OK, "GetVersion failed, hr=%lx\n", hr); ok(len == 0, "invalid length 0x%x\n", len); /* version does not apply to pixel formats */ hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo, (void**)&pixelformat_info); - ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryInterface failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICPixelFormatInfo_GetBitsPerPixel(pixelformat_info, NULL); - ok(hr == E_INVALIDARG, "GetBitsPerPixel failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetBitsPerPixel failed, hr=%lx\n", hr); hr = IWICPixelFormatInfo_GetBitsPerPixel(pixelformat_info, &uiresult); - ok(hr == S_OK, "GetBitsPerPixel failed, hr=%x\n", hr); + ok(hr == S_OK, "GetBitsPerPixel failed, hr=%lx\n", hr); ok(uiresult == 32, "unexpected bpp %i\n", uiresult); hr = IWICPixelFormatInfo_GetChannelCount(pixelformat_info, &uiresult); - ok(hr == S_OK, "GetChannelCount failed, hr=%x\n", hr); + ok(hr == S_OK, "GetChannelCount failed, hr=%lx\n", hr); ok(uiresult == 4, "unexpected channel count %i\n", uiresult); hr = IWICPixelFormatInfo_GetChannelMask(pixelformat_info, 0, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "GetChannelMask failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetChannelMask failed, hr=%lx\n", hr); uiresult = 0xdeadbeef; hr = IWICPixelFormatInfo_GetChannelMask(pixelformat_info, 0, 0, NULL, &uiresult); - ok(hr == S_OK, "GetChannelMask failed, hr=%x\n", hr); + ok(hr == S_OK, "GetChannelMask failed, hr=%lx\n", hr); ok(uiresult == 4, "unexpected length %i\n", uiresult); memset(abbuffer, 0xaa, sizeof(abbuffer)); hr = IWICPixelFormatInfo_GetChannelMask(pixelformat_info, 0, known_len, abbuffer, NULL); - ok(hr == E_INVALIDARG, "GetChannelMask failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetChannelMask failed, hr=%lx\n", hr); ok(abbuffer[0] == 0xaa, "buffer modified\n"); uiresult = 0xdeadbeef; memset(abbuffer, 0xaa, sizeof(abbuffer)); hr = IWICPixelFormatInfo_GetChannelMask(pixelformat_info, 0, 3, abbuffer, &uiresult); - ok(hr == E_INVALIDARG, "GetChannelMask failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetChannelMask failed, hr=%lx\n", hr); ok(abbuffer[0] == 0xaa, "buffer modified\n"); ok(uiresult == 4, "unexpected length %i\n", uiresult); memset(abbuffer, 0xaa, sizeof(abbuffer)); hr = IWICPixelFormatInfo_GetChannelMask(pixelformat_info, 0, 4, abbuffer, &uiresult); - ok(hr == S_OK, "GetChannelMask failed, hr=%x\n", hr); - ok(*((ULONG*)abbuffer) == 0xff, "unexpected mask 0x%x\n", *((ULONG*)abbuffer)); + ok(hr == S_OK, "GetChannelMask failed, hr=%lx\n", hr); + ok(*((ULONG*)abbuffer) == 0xff, "unexpected mask 0x%lx\n", *((ULONG*)abbuffer)); ok(uiresult == 4, "unexpected length %i\n", uiresult); memset(abbuffer, 0xaa, sizeof(abbuffer)); hr = IWICPixelFormatInfo_GetChannelMask(pixelformat_info, 0, 5, abbuffer, &uiresult); - ok(hr == S_OK, "GetChannelMask failed, hr=%x\n", hr); - ok(*((ULONG*)abbuffer) == 0xff, "unexpected mask 0x%x\n", *((ULONG*)abbuffer)); + ok(hr == S_OK, "GetChannelMask failed, hr=%lx\n", hr); + ok(*((ULONG*)abbuffer) == 0xff, "unexpected mask 0x%lx\n", *((ULONG*)abbuffer)); ok(abbuffer[4] == 0xaa, "buffer modified past actual length\n"); ok(uiresult == 4, "unexpected length %i\n", uiresult); memset(&guid, 0xaa, sizeof(guid)); hr = IWICPixelFormatInfo_GetFormatGUID(pixelformat_info, &guid); - ok(hr == S_OK, "GetFormatGUID failed, hr=%x\n", hr); + ok(hr == S_OK, "GetFormatGUID failed, hr=%lx\n", hr); ok(IsEqualGUID(&guid, &GUID_WICPixelFormat32bppBGRA), "unexpected GUID %s\n", wine_dbgstr_guid(&guid)); IWICPixelFormatInfo_Release(pixelformat_info); @@ -448,19 +454,19 @@ static void test_pixelformat_info(void) else { hr = IWICPixelFormatInfo2_GetNumericRepresentation(pixelformat_info2, NULL); - ok(hr == E_INVALIDARG, "GetNumericRepresentation failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetNumericRepresentation failed, hr=%lx\n", hr); numericrepresentation = 0xdeadbeef; hr = IWICPixelFormatInfo2_GetNumericRepresentation(pixelformat_info2, &numericrepresentation); - ok(hr == S_OK, "GetNumericRepresentation failed, hr=%x\n", hr); + ok(hr == S_OK, "GetNumericRepresentation failed, hr=%lx\n", hr); ok(numericrepresentation == WICPixelFormatNumericRepresentationUnsignedInteger, "unexpected numeric representation %i\n", numericrepresentation); hr = IWICPixelFormatInfo2_SupportsTransparency(pixelformat_info2, NULL); - ok(hr == E_INVALIDARG, "SupportsTransparency failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "SupportsTransparency failed, hr=%lx\n", hr); supportstransparency = 0xdeadbeef; hr = IWICPixelFormatInfo2_SupportsTransparency(pixelformat_info2, &supportstransparency); - ok(hr == S_OK, "SupportsTransparency failed, hr=%x\n", hr); + ok(hr == S_OK, "SupportsTransparency failed, hr=%lx\n", hr); ok(supportstransparency == 1, "unexpected value %i\n", supportstransparency); IWICPixelFormatInfo2_Release(pixelformat_info2); @@ -477,7 +483,7 @@ static DWORD WINAPI cache_across_threads_test(void *arg) CoInitialize(NULL); hr = get_component_info(&CLSID_WICUnknownMetadataReader, &info); - ok(hr == S_OK, "CreateComponentInfo failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateComponentInfo failed, hr=%lx\n", hr); ok(info == arg, "unexpected info pointer %p\n", info); IWICComponentInfo_Release(info); @@ -493,21 +499,22 @@ static void test_reader_info(void) HRESULT hr; CLSID clsid; GUID container_formats[10]; - UINT count, size, tid; + UINT count, size; + DWORD tid; HANDLE thread; WICMetadataPattern *patterns; hr = get_component_info(&CLSID_WICUnknownMetadataReader, &info2); - ok(hr == S_OK, "CreateComponentInfo failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateComponentInfo failed, hr=%lx\n", hr); IWICComponentInfo_Release(info2); hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; hr = IWICImagingFactory_CreateComponentInfo(factory, &CLSID_WICUnknownMetadataReader, &info); - ok(hr == S_OK, "CreateComponentInfo failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateComponentInfo failed, hr=%lx\n", hr); ok(info == info2, "info != info2\n"); thread = CreateThread(NULL, 0, cache_across_threads_test, info, 0, &tid); @@ -515,36 +522,36 @@ static void test_reader_info(void) CloseHandle(thread); hr = IWICComponentInfo_QueryInterface(info, &IID_IWICMetadataReaderInfo, (void**)&reader_info); - ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryInterface failed, hr=%lx\n", hr); hr = IWICMetadataReaderInfo_GetCLSID(reader_info, NULL); - ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%lx\n", hr); hr = IWICMetadataReaderInfo_GetCLSID(reader_info, &clsid); - ok(hr == S_OK, "GetCLSID failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCLSID failed, hr=%lx\n", hr); ok(IsEqualGUID(&CLSID_WICUnknownMetadataReader, &clsid), "GetCLSID returned wrong result\n"); hr = IWICMetadataReaderInfo_GetMetadataFormat(reader_info, &clsid); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&GUID_MetadataFormatUnknown, &clsid), "GetMetadataFormat returned wrong result\n"); hr = IWICMetadataReaderInfo_GetContainerFormats(reader_info, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "GetContainerFormats failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetContainerFormats failed, hr=%lx\n", hr); count = 0xdeadbeef; hr = IWICMetadataReaderInfo_GetContainerFormats(reader_info, 0, NULL, &count); - ok(hr == S_OK, "GetContainerFormats failed, hr=%x\n", hr); + ok(hr == S_OK, "GetContainerFormats failed, hr=%lx\n", hr); ok(count == 0, "unexpected count %d\n", count); hr = IWICMetadataReaderInfo_GetPatterns(reader_info, &GUID_ContainerFormatPng, 0, NULL, NULL, NULL); - ok(hr == E_INVALIDARG, "GetPatterns failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetPatterns failed, hr=%lx\n", hr); count = size = 0xdeadbeef; hr = IWICMetadataReaderInfo_GetPatterns(reader_info, &GUID_ContainerFormatPng, 0, NULL, &count, &size); ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND || broken(hr == S_OK) /* Windows XP */, - "GetPatterns failed, hr=%x\n", hr); + "GetPatterns failed, hr=%lx\n", hr); ok(count == 0xdeadbeef, "unexpected count %d\n", count); ok(size == 0xdeadbeef, "unexpected size %d\n", size); @@ -553,8 +560,8 @@ static void test_reader_info(void) IWICComponentInfo_Release(info); hr = IWICImagingFactory_CreateComponentInfo(factory, &CLSID_WICXMPStructMetadataReader, &info); -todo_wine - ok(hr == S_OK, "CreateComponentInfo failed, hr=%x\n", hr); + todo_wine + ok(hr == S_OK, "CreateComponentInfo failed, hr=%lx\n", hr); if (FAILED(hr)) { @@ -563,49 +570,49 @@ todo_wine } hr = IWICComponentInfo_QueryInterface(info, &IID_IWICMetadataReaderInfo, (void**)&reader_info); - ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryInterface failed, hr=%lx\n", hr); hr = IWICMetadataReaderInfo_GetCLSID(reader_info, NULL); - ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetCLSID failed, hr=%lx\n", hr); hr = IWICMetadataReaderInfo_GetCLSID(reader_info, &clsid); - ok(hr == S_OK, "GetCLSID failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCLSID failed, hr=%lx\n", hr); ok(IsEqualGUID(&CLSID_WICXMPStructMetadataReader, &clsid), "GetCLSID returned wrong result\n"); hr = IWICMetadataReaderInfo_GetMetadataFormat(reader_info, &clsid); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&GUID_MetadataFormatXMPStruct, &clsid), "GetMetadataFormat returned wrong result\n"); hr = IWICMetadataReaderInfo_GetContainerFormats(reader_info, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "GetContainerFormats failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetContainerFormats failed, hr=%lx\n", hr); count = 0xdeadbeef; hr = IWICMetadataReaderInfo_GetContainerFormats(reader_info, 0, NULL, &count); - ok(hr == S_OK, "GetContainerFormats failed, hr=%x\n", hr); + ok(hr == S_OK, "GetContainerFormats failed, hr=%lx\n", hr); ok(count >= 2, "unexpected count %d\n", count); count = 0xdeadbeef; hr = IWICMetadataReaderInfo_GetContainerFormats(reader_info, 1, container_formats, &count); - ok(hr == S_OK, "GetContainerFormats failed, hr=%x\n", hr); + ok(hr == S_OK, "GetContainerFormats failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %d\n", count); count = 0xdeadbeef; hr = IWICMetadataReaderInfo_GetContainerFormats(reader_info, 10, container_formats, &count); - ok(hr == S_OK, "GetContainerFormats failed, hr=%x\n", hr); + ok(hr == S_OK, "GetContainerFormats failed, hr=%lx\n", hr); ok(count == min(count, 10), "unexpected count %d\n", count); count = size = 0xdeadbeef; hr = IWICMetadataReaderInfo_GetPatterns(reader_info, &GUID_ContainerFormatPng, 0, NULL, &count, &size); ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND || broken(hr == S_OK) /* Windows XP */, - "GetPatterns failed, hr=%x\n", hr); + "GetPatterns failed, hr=%lx\n", hr); ok(count == 0xdeadbeef, "unexpected count %d\n", count); ok(size == 0xdeadbeef, "unexpected size %d\n", size); count = size = 0xdeadbeef; hr = IWICMetadataReaderInfo_GetPatterns(reader_info, &GUID_MetadataFormatXMP, 0, NULL, &count, &size); - ok(hr == S_OK, "GetPatterns failed, hr=%x\n", hr); + ok(hr == S_OK, "GetPatterns failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %d\n", count); ok(size > sizeof(WICMetadataPattern), "unexpected size %d\n", size); @@ -616,14 +623,14 @@ todo_wine count = size = 0xdeadbeef; hr = IWICMetadataReaderInfo_GetPatterns(reader_info, &GUID_MetadataFormatXMP, size-1, patterns, &count, &size); - ok(hr == S_OK, "GetPatterns failed, hr=%x\n", hr); + ok(hr == S_OK, "GetPatterns failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %d\n", count); ok(size > sizeof(WICMetadataPattern), "unexpected size %d\n", size); count = size = 0xdeadbeef; hr = IWICMetadataReaderInfo_GetPatterns(reader_info, &GUID_MetadataFormatXMP, size, patterns, &count, &size); - ok(hr == S_OK, "GetPatterns failed, hr=%x\n", hr); + ok(hr == S_OK, "GetPatterns failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %d\n", count); ok(size == sizeof(WICMetadataPattern) + patterns->Length * 2, "unexpected size %d\n", size); @@ -653,15 +660,15 @@ static void test_imagingfactory_interfaces(void) } hr = IWICImagingFactory2_QueryInterface(factory2, &IID_IWICComponentFactory, (void **)&component_factory); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IWICComponentFactory_QueryInterface(component_factory, &IID_IWICImagingFactory, (void **)&factory); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(factory == (IWICImagingFactory *)component_factory, "Unexpected factory pointer.\n"); IWICImagingFactory_Release(factory); hr = IWICImagingFactory2_QueryInterface(factory2, &IID_IWICImagingFactory, (void **)&factory); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(factory == (IWICImagingFactory *)component_factory, "Unexpected factory pointer.\n"); IWICComponentFactory_Release(component_factory); @@ -669,6 +676,41 @@ static void test_imagingfactory_interfaces(void) IWICImagingFactory_Release(factory); } +static void test_component_enumerator(void) +{ + static const unsigned int types[] = + { + WICDecoder, + WICEncoder, + WICPixelFormatConverter, + WICMetadataReader, + WICPixelFormat, + }; + IWICImagingFactory *factory; + IEnumUnknown *enumerator; + unsigned int i; + IUnknown *item; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICImagingFactory, (void **)&factory); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + for (i = 0; i < ARRAY_SIZE(types); ++i) + { + hr = IWICImagingFactory_CreateComponentEnumerator(factory, types[i], 0, &enumerator); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IEnumUnknown_Next(enumerator, 1, &item, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IUnknown_Release(item); + + IEnumUnknown_Release(enumerator); + } + + IWICImagingFactory_Release(factory); +} + START_TEST(info) { CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); @@ -677,6 +719,7 @@ START_TEST(info) test_reader_info(); test_pixelformat_info(); test_imagingfactory_interfaces(); + test_component_enumerator(); CoUninitialize(); } diff --git a/modules/rostests/winetests/windowscodecs/jpegformat.c b/modules/rostests/winetests/windowscodecs/jpegformat.c index c1e46c48694..e150174f98d 100644 --- a/modules/rostests/winetests/windowscodecs/jpegformat.c +++ b/modules/rostests/winetests/windowscodecs/jpegformat.c @@ -47,6 +47,8 @@ static void test_decode_adobe_cmyk(void) { IWICBitmapDecoder *decoder; IWICBitmapFrameDecode *framedecode; + IWICImagingFactory *factory; + IWICPalette *palette; HRESULT hr; HGLOBAL hjpegdata; char *jpegdata; @@ -74,9 +76,13 @@ static void test_decode_adobe_cmyk(void) hr = CoCreateInstance(&CLSID_WICJpegDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); - ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICImagingFactory, (void **)&factory); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); + hjpegdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(jpeg_adobe_cmyk_1x5)); ok(hjpegdata != 0, "GlobalAlloc failed\n"); if (hjpegdata) @@ -86,31 +92,31 @@ static void test_decode_adobe_cmyk(void) GlobalUnlock(hjpegdata); hr = CreateStreamOnHGlobal(hjpegdata, FALSE, &jpegstream); - ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapDecoder_Initialize(decoder, jpegstream, WICDecodeMetadataCacheOnLoad); - ok(hr == S_OK, "Initialize failed, hr=%x\n", hr); + ok(hr == S_OK, "Initialize failed, hr=%lx\n", hr); hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guidresult); - ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_ContainerFormatJpeg), "unexpected container format\n"); hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); - ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %u\n", count); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); - ok(SUCCEEDED(hr), "GetFrame failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetFrame failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); - ok(SUCCEEDED(hr), "GetSize failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetSize failed, hr=%lx\n", hr); ok(width == 1, "expected width=1, got %u\n", width); ok(height == 5, "expected height=5, got %u\n", height); hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &guidresult); - ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&guidresult, &GUID_WICPixelFormat32bppCMYK) || broken(IsEqualGUID(&guidresult, &GUID_WICPixelFormat24bppBGR)), /* xp/2003 */ "unexpected pixel format: %s\n", wine_dbgstr_guid(&guidresult)); @@ -120,18 +126,32 @@ static void test_decode_adobe_cmyk(void) for(i=2; i>0; --i) { hr = IWICBitmapFrameDecode_CopyPixels(framedecode, NULL, 4, sizeof(imagedata), imagedata); - ok(SUCCEEDED(hr), "CopyPixels failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CopyPixels failed, hr=%lx\n", hr); ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)) || broken(!memcmp(imagedata, expected_imagedata_24bpp, sizeof(expected_imagedata))), /* xp/2003 */ "unexpected image data\n"); } + + hr = IWICImagingFactory_CreatePalette(factory, &palette); + ok(SUCCEEDED(hr), "CreatePalette failed, hr=%lx\n", hr); + + hr = IWICBitmapDecoder_CopyPalette(decoder, palette); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "Unexpected hr %#lx.\n", hr); + + hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "Unexpected hr %#lx.\n", hr); + + IWICPalette_Release(palette); + IWICBitmapFrameDecode_Release(framedecode); } IStream_Release(jpegstream); } GlobalFree(hjpegdata); } + IWICBitmapDecoder_Release(decoder); + IWICImagingFactory_Release(factory); } diff --git a/modules/rostests/winetests/windowscodecs/metadata.c b/modules/rostests/winetests/windowscodecs/metadata.c index 58da19cee47..7dd10f5ce9d 100644 --- a/modules/rostests/winetests/windowscodecs/metadata.c +++ b/modules/rostests/winetests/windowscodecs/metadata.c @@ -37,29 +37,93 @@ #include "initguid.h" DEFINE_GUID(IID_MdbrUnknown, 0x00240e6f,0x3f23,0x4432,0xb0,0xcc,0x48,0xd5,0xbb,0xff,0x6c,0x36); -#define expect_blob(propvar, data, length) do { \ - ok((propvar).vt == VT_BLOB, "unexpected vt: %i\n", (propvar).vt); \ - if ((propvar).vt == VT_BLOB) { \ - ok(U(propvar).blob.cbSize == (length), "expected size %u, got %u\n", (ULONG)(length), U(propvar).blob.cbSize); \ - if (U(propvar).blob.cbSize == (length)) { \ - ok(!memcmp(U(propvar).blob.pBlobData, (data), (length)), "unexpected data\n"); \ - } \ - } \ -} while (0) +#define expect_ref(obj,ref) expect_ref_((IUnknown *)obj, ref, __LINE__) +static void expect_ref_(IUnknown *obj, ULONG ref, int line) +{ + ULONG refcount; + IUnknown_AddRef(obj); + refcount = IUnknown_Release(obj); + ok_(__FILE__, line)(refcount == ref, "Expected refcount %ld, got %ld.\n", ref, refcount); +} -#define IFD_BYTE 1 -#define IFD_ASCII 2 -#define IFD_SHORT 3 -#define IFD_LONG 4 -#define IFD_RATIONAL 5 -#define IFD_SBYTE 6 -#define IFD_UNDEFINED 7 -#define IFD_SSHORT 8 -#define IFD_SLONG 9 -#define IFD_SRATIONAL 10 -#define IFD_FLOAT 11 -#define IFD_DOUBLE 12 -#define IFD_IFD 13 +#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c) +static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported) +{ + IUnknown *iface = iface_ptr; + HRESULT hr, expected_hr; + IUnknown *unk; + + expected_hr = supported ? S_OK : E_NOINTERFACE; + + hr = IUnknown_QueryInterface(iface, iid, (void **)&unk); + ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr); + if (SUCCEEDED(hr)) + IUnknown_Release(unk); +} + +#define check_persist_options(a, b) check_persist_options_(__LINE__, a, b) +static void check_persist_options_(unsigned int line, void *iface_ptr, DWORD expected_options) +{ + IWICStreamProvider *stream_provider; + IUnknown *iface = iface_ptr; + DWORD options; + HRESULT hr; + + if (SUCCEEDED(IUnknown_QueryInterface(iface, &IID_IWICStreamProvider, (void **)&stream_provider))) + { + hr = IWICStreamProvider_GetPersistOptions(stream_provider, &options); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (hr == S_OK) + ok_(__FILE__, line)(options == expected_options, "Unexpected options %#lx.\n", options); + IWICStreamProvider_Release(stream_provider); + } + else + ok_(__FILE__, line)(0, "IWICStreamProvider is not supported.\n"); +} + +static HRESULT get_persist_stream(void *iface_ptr, IStream **stream) +{ + IWICStreamProvider *stream_provider; + IUnknown *iface = iface_ptr; + HRESULT hr = E_UNEXPECTED; + + if (SUCCEEDED(IUnknown_QueryInterface(iface, &IID_IWICStreamProvider, (void **)&stream_provider))) + { + hr = IWICStreamProvider_GetStream(stream_provider, stream); + IWICStreamProvider_Release(stream_provider); + } + + return hr; +} + +#define compare_blob(a,b,c) compare_blob_(__LINE__,a,b,c) +static void compare_blob_(unsigned int line, const PROPVARIANT *propvar, const char *data, ULONG length) +{ + ok_(__FILE__, line)(propvar->vt == VT_BLOB, "Unexpected vt: %i\n", propvar->vt); + if (propvar->vt == VT_BLOB) + { + ok_(__FILE__, line)(propvar->blob.cbSize == length, "Expected size %lu, got %lu.\n", length, propvar->blob.cbSize); + if (propvar->blob.cbSize == length) + ok_(__FILE__, line)(!memcmp(propvar->blob.pBlobData, data, length), "Unexpected data.\n"); + } +} + +enum ifd_entry_type +{ + IFD_BYTE = 1, + IFD_ASCII = 2, + IFD_SHORT = 3, + IFD_LONG = 4, + IFD_RATIONAL = 5, + IFD_SBYTE = 6, + IFD_UNDEFINED = 7, + IFD_SSHORT = 8, + IFD_SLONG = 9, + IFD_SRATIONAL = 10, + IFD_FLOAT = 11, + IFD_DOUBLE = 12, + IFD_IFD = 13, +}; #include "pshpack2.h" struct IFD_entry @@ -161,6 +225,25 @@ static const char metadata_cHRM[] = { 0xff,0xff,0xff,0xff /* chunk CRC */ }; +static const char metadata_hIST[] = { + 0,0,0,40, /* chunk length */ + 'h','I','S','T', /* chunk type */ + 0,1, 0,2, 0,3, 0,4, + 0,5, 0,6, 0,7, 0,8, + 0,9, 0,10, 0,11, 0,12, + 0,13, 0,14, 0,15, 0,16, + 0,17, 0,18, 0,19, 0,20, + 0xff,0xff,0xff,0xff +}; + +static const char metadata_tIME[] = { + 0,0,0,7, /* chunk length */ + 't','I','M','E', /* chunk type */ + 0x07,0xd0,0x01,0x02, /* year (2 bytes), month, day */ + 0x0c,0x22,0x38, /* hour, minute, second */ + 0xff,0xff,0xff,0xff +}; + static const char pngimage[285] = { 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52, 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53, @@ -191,16 +274,23 @@ static const char animatedgif[] = { 0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81, 0xDE,0xDE,0xDE,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x4C,0x01,0x00, +0x21,0xF9,0x04,0x01,0x0A,0x00,0x01,0x00, 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','1',0x00, 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','1',0x00, -0x21,0xF9,0x04,0x01,0x0A,0x00,0x01,0x00,0x2C, -0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81, +0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81, 0x4D,0x4D,0x4D,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x44,0x01,0x00, 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','2',0x00, 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','2',0x00,0x3B }; +static ULONG get_refcount(void *iface) +{ + IUnknown *unknown = iface; + IUnknown_AddRef(unknown); + return IUnknown_Release(unknown); +} + static IStream *create_stream(const char *data, int data_size) { HRESULT hr; @@ -217,62 +307,293 @@ static IStream *create_stream(const char *data, int data_size) GlobalUnlock(hdata); hr = CreateStreamOnHGlobal(hdata, TRUE, &stream); - ok(hr == S_OK, "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateStreamOnHGlobal failed, hr=%lx\n", hr); return stream; } -static void load_stream(IUnknown *reader, const char *data, int data_size, DWORD persist_options) +static void load_stream(void *iface_ptr, const char *data, int data_size, DWORD persist_options) { + IWICStreamProvider *stream_provider; + IUnknown *iface = iface_ptr; HRESULT hr; IWICPersistStream *persist; - IStream *stream; + IStream *stream, *stream2; LARGE_INTEGER pos; ULARGE_INTEGER cur_pos; + DWORD flags; + GUID guid; stream = create_stream(data, data_size); if (!stream) return; - hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void**)&persist); - ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr); + hr = IUnknown_QueryInterface(iface, &IID_IWICPersistStream, (void **)&persist); + ok(hr == S_OK, "QueryInterface failed, hr=%lx\n", hr); - if (SUCCEEDED(hr)) + hr = IWICPersistStream_LoadEx(persist, NULL, NULL, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IUnknown_QueryInterface(iface, &IID_IWICStreamProvider, (void **)&stream_provider); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + memset(&guid, 0, sizeof(guid)); + hr = IWICStreamProvider_GetPreferredVendorGUID(stream_provider, &guid); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(IsEqualGUID(&guid, &GUID_VendorMicrosoft), "Unexpected vendor %s.\n", wine_dbgstr_guid(&guid)); + + hr = IWICStreamProvider_GetPreferredVendorGUID(stream_provider, NULL); + todo_wine + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = IWICStreamProvider_GetPersistOptions(stream_provider, NULL); + todo_wine + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + flags = 123; + hr = IWICStreamProvider_GetPersistOptions(stream_provider, &flags); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!flags, "Unexpected options %#lx.\n", flags); + + stream2 = (void *)0xdeadbeef; + hr = IWICStreamProvider_GetStream(stream_provider, &stream2); + todo_wine + ok(hr == WINCODEC_ERR_STREAMNOTAVAILABLE, "Unexpected hr %#lx.\n", hr); + ok(stream2 == (void *)0xdeadbeef, "Unexpected stream pointer.\n"); + + hr = IWICPersistStream_LoadEx(persist, stream, NULL, persist_options); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + memset(&guid, 0, sizeof(guid)); + hr = IWICStreamProvider_GetPreferredVendorGUID(stream_provider, &guid); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(IsEqualGUID(&guid, &GUID_VendorMicrosoft), "Unexpected vendor %s.\n", wine_dbgstr_guid(&guid)); + + flags = ~persist_options; + hr = IWICStreamProvider_GetPersistOptions(stream_provider, &flags); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(flags == persist_options, "Unexpected options %#lx.\n", flags); + + if (persist_options & WICPersistOptionNoCacheStream) { - hr = IWICPersistStream_LoadEx(persist, stream, NULL, persist_options); - ok(hr == S_OK, "LoadEx failed, hr=%x\n", hr); - - IWICPersistStream_Release(persist); + stream2 = (void *)0xdeadbeef; + hr = IWICStreamProvider_GetStream(stream_provider, &stream2); + todo_wine + ok(hr == WINCODEC_ERR_STREAMNOTAVAILABLE, "Unexpected hr %#lx.\n", hr); + ok(stream2 == (void *)0xdeadbeef, "Unexpected stream pointer.\n"); } + else + { + stream2 = NULL; + hr = IWICStreamProvider_GetStream(stream_provider, &stream2); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(stream2 == stream, "Unexpected stream pointer.\n"); + if (stream2) + IStream_Release(stream2); + } + + IWICStreamProvider_Release(stream_provider); + IWICPersistStream_Release(persist); pos.QuadPart = 0; hr = IStream_Seek(stream, pos, SEEK_CUR, &cur_pos); - ok(hr == S_OK, "IStream_Seek error %#x\n", hr); + ok(hr == S_OK, "IStream_Seek error %#lx\n", hr); /* IFD metadata reader doesn't rewind the stream to the start */ ok(cur_pos.QuadPart == 0 || cur_pos.QuadPart <= data_size, - "current stream pos is at %x/%x, data size %x\n", cur_pos.u.LowPart, cur_pos.u.HighPart, data_size); + "current stream pos is at %lx/%lx, data size %x\n", cur_pos.u.LowPart, cur_pos.u.HighPart, data_size); IStream_Release(stream); } +struct test_data +{ + ULONG type, id; + int count; /* if VT_VECTOR */ + LONGLONG value[13]; + const char *string; + const WCHAR id_string[32]; +}; + +static void compare_metadata(IWICMetadataReader *reader, const struct test_data *td, ULONG count) +{ + HRESULT hr; + IWICEnumMetadataItem *enumerator; + PROPVARIANT schema, id, value; + ULONG items_returned, i; + + hr = IWICMetadataReader_GetEnumerator(reader, NULL); + ok(hr == E_INVALIDARG, "GetEnumerator error %#lx\n", hr); + + hr = IWICMetadataReader_GetEnumerator(reader, &enumerator); + ok(hr == S_OK, "GetEnumerator error %#lx\n", hr); + + PropVariantInit(&schema); + PropVariantInit(&id); + PropVariantInit(&value); + + for (i = 0; i < count; i++) + { + winetest_push_context("%lu", i); + + hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned); + ok(hr == S_OK, "Next error %#lx\n", hr); + ok(items_returned == 1, "unexpected item count %lu\n", items_returned); + + ok(schema.vt == VT_EMPTY, "Unexpected vt: %u\n", schema.vt); + ok(id.vt == VT_UI2 || id.vt == VT_LPWSTR || id.vt == VT_EMPTY, "Unexpected vt: %u\n", id.vt); + if (id.vt == VT_UI2) + ok(id.uiVal == td[i].id, "Expected id %#lx, got %#x\n", td[i].id, id.uiVal); + else if (id.vt == VT_LPWSTR) + ok(!lstrcmpW(td[i].id_string, id.pwszVal), + "Expected %s, got %s\n", wine_dbgstr_w(td[i].id_string), wine_dbgstr_w(id.pwszVal)); + + ok(value.vt == td[i].type, "Expected vt %#lx, got %#x\n", td[i].type, value.vt); + if (value.vt & VT_VECTOR) + { + ULONG j; + switch (value.vt & ~VT_VECTOR) + { + case VT_I1: + case VT_UI1: + ok(td[i].count == value.caub.cElems, "Expected cElems %d, got %ld\n", td[i].count, value.caub.cElems); + for (j = 0; j < value.caub.cElems; j++) + ok(td[i].value[j] == value.caub.pElems[j], "Expected value[%ld] %#I64x, got %#x\n", j, td[i].value[j], value.caub.pElems[j]); + break; + case VT_I2: + case VT_UI2: + ok(td[i].count == value.caui.cElems, "Expected cElems %d, got %ld\n", td[i].count, value.caui.cElems); + for (j = 0; j < value.caui.cElems; j++) + ok(td[i].value[j] == value.caui.pElems[j], "Expected value[%ld] %#I64x, got %#x\n", j, td[i].value[j], value.caui.pElems[j]); + break; + case VT_I4: + case VT_UI4: + case VT_R4: + ok(td[i].count == value.caul.cElems, "Expected cElems %d, got %ld\n", td[i].count, value.caul.cElems); + for (j = 0; j < value.caul.cElems; j++) + ok(td[i].value[j] == value.caul.pElems[j], "Expected value[%ld] %#I64x, got %#lx\n", j, td[i].value[j], value.caul.pElems[j]); + break; + case VT_I8: + case VT_UI8: + case VT_R8: + ok(td[i].count == value.cauh.cElems, "Expected cElems %d, got %ld\n", td[i].count, value.cauh.cElems); + for (j = 0; j < value.cauh.cElems; j++) + ok(td[i].value[j] == value.cauh.pElems[j].QuadPart, "Expected value[%ld] %I64x, got %08lx/%08lx\n", j, td[i].value[j], value.cauh.pElems[j].u.LowPart, value.cauh.pElems[j].u.HighPart); + break; + case VT_LPSTR: + ok(td[i].count == value.calpstr.cElems, "Expected cElems %d, got %ld\n", td[i].count, value.caub.cElems); + for (j = 0; j < value.calpstr.cElems; j++) + trace("%lu: %s\n", j, value.calpstr.pElems[j]); + /* fall through to not handled message */ + default: + ok(0, "vector of type %d is not handled\n", value.vt & ~VT_VECTOR); + break; + } + } + else if (value.vt == VT_LPSTR) + { + ok(td[i].count == strlen(value.pszVal) || + broken(td[i].count == strlen(value.pszVal) + 1), /* before Win7 */ + "Expected count %d, got %d\n", td[i].count, lstrlenA(value.pszVal)); + if (td[i].count == strlen(value.pszVal)) + ok(!strcmp(td[i].string, value.pszVal), + "Expected %s, got %s\n", td[i].string, value.pszVal); + } + else if (value.vt == VT_BLOB) + { + ok(td[i].count == value.blob.cbSize, "Expected count %d, got %ld\n", td[i].count, value.blob.cbSize); + ok(!memcmp(td[i].string, value.blob.pBlobData, td[i].count), "Expected %s, got %s\n", td[i].string, value.blob.pBlobData); + } + else + ok(value.uhVal.QuadPart == td[i].value[0], "Eexpected value %#I64x got %#lx/%#lx\n", + td[i].value[0], value.uhVal.u.LowPart, value.uhVal.u.HighPart); + + PropVariantClear(&schema); + PropVariantClear(&id); + PropVariantClear(&value); + + winetest_pop_context(); + } + + hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned); + ok(hr == S_FALSE, "Next should fail\n"); + ok(items_returned == 0, "unexpected item count %lu\n", items_returned); + + IWICEnumMetadataItem_Release(enumerator); +} + +#define test_reader_container_format(a, b) _test_reader_container_format(a, b, __LINE__) +static void _test_reader_container_format(IWICMetadataReader *reader, const GUID *format, unsigned int line) +{ + IWICMetadataHandlerInfo *info; + BOOL found = FALSE; + GUID formats[8]; + UINT count; + HRESULT hr; + + hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IWICMetadataHandlerInfo_GetContainerFormats(info, ARRAY_SIZE(formats), formats, &count); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok_(__FILE__, line)(count > 0, "Unexpected count.\n"); + + for (unsigned i = 0; i < count; ++i) + { + if (IsEqualGUID(&formats[i], format)) + { + found = TRUE; + break; + } + } + ok_(__FILE__, line)(found, "Container format %s was not found.\n", wine_dbgstr_guid(format)); + + if (!found) + { + for (unsigned i = 0; i < count; ++i) + ok_(__FILE__, line)(0, "Available format %s.\n", wine_dbgstr_guid(&formats[i])); + } + + IWICMetadataHandlerInfo_Release(info); +} + + static void test_metadata_unknown(void) { HRESULT hr; IWICMetadataReader *reader; IWICEnumMetadataItem *enumerator; - IWICMetadataBlockReader *blockreader; PROPVARIANT schema, id, value; + IWICMetadataWriter *writer; + IWICPersistStream *persist; ULONG items_returned; + UINT count; hr = CoCreateInstance(&CLSID_WICUnknownMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void**)&reader); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; - load_stream((IUnknown*)reader, metadata_unknown, sizeof(metadata_unknown), WICPersistOptionDefault); + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + check_interface(reader, &IID_IWICMetadataBlockReader, FALSE); + + load_stream(reader, metadata_unknown, sizeof(metadata_unknown), WICPersistOptionDefault); hr = IWICMetadataReader_GetEnumerator(reader, &enumerator); - ok(hr == S_OK, "GetEnumerator failed, hr=%x\n", hr); + ok(hr == S_OK, "GetEnumerator failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { @@ -281,14 +602,14 @@ static void test_metadata_unknown(void) PropVariantInit(&value); hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned); - ok(hr == S_OK, "Next failed, hr=%x\n", hr); - ok(items_returned == 1, "unexpected item count %i\n", items_returned); + ok(hr == S_OK, "Next failed, hr=%lx\n", hr); + ok(items_returned == 1, "unexpected item count %li\n", items_returned); if (hr == S_OK && items_returned == 1) { ok(schema.vt == VT_EMPTY, "unexpected vt: %i\n", schema.vt); ok(id.vt == VT_EMPTY, "unexpected vt: %i\n", id.vt); - expect_blob(value, metadata_unknown, sizeof(metadata_unknown)); + compare_blob(&value, metadata_unknown, sizeof(metadata_unknown)); PropVariantClear(&schema); PropVariantClear(&id); @@ -296,28 +617,71 @@ static void test_metadata_unknown(void) } hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned); - ok(hr == S_FALSE, "Next failed, hr=%x\n", hr); - ok(items_returned == 0, "unexpected item count %i\n", items_returned); + ok(hr == S_FALSE, "Next failed, hr=%lx\n", hr); + ok(items_returned == 0, "unexpected item count %li\n", items_returned); + + hr = IWICEnumMetadataItem_Reset(enumerator); + ok(hr == S_OK, "Reset failed, hr=%lx\n", hr); + + hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, NULL, NULL); + ok(hr == S_OK, "Next failed, hr=%lx\n", hr); + + if (hr == S_OK) + { + ok(schema.vt == VT_EMPTY, "unexpected vt: %i\n", schema.vt); + ok(id.vt == VT_EMPTY, "unexpected vt: %i\n", id.vt); + + PropVariantClear(&schema); + PropVariantClear(&id); + } IWICEnumMetadataItem_Release(enumerator); } - hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICMetadataBlockReader, (void**)&blockreader); - ok(hr == E_NOINTERFACE, "QueryInterface failed, hr=%x\n", hr); - - if (SUCCEEDED(hr)) - IWICMetadataBlockReader_Release(blockreader); + hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %u.\n", count); + hr = IWICPersistStream_LoadEx(persist, NULL, NULL, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(count == 1, "Unexpected count %u.\n", count); + IWICPersistStream_Release(persist); IWICMetadataReader_Release(reader); + + hr = CoCreateInstance(&CLSID_WICUnknownMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, metadata_unknown, sizeof(metadata_unknown), 0); + load_stream(writer, metadata_unknown, sizeof(metadata_unknown), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } static void test_metadata_tEXt(void) { + IWICMetadataHandlerInfo *info; HRESULT hr; IWICMetadataReader *reader; IWICEnumMetadataItem *enumerator; PROPVARIANT schema, id, value; - ULONG items_returned, count; + IWICMetadataWriter *writer; + ULONG items_returned; + UINT count; GUID format; PropVariantInit(&schema); @@ -326,41 +690,53 @@ static void test_metadata_tEXt(void) hr = CoCreateInstance(&CLSID_WICPngTextMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void**)&reader); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + hr = IWICMetadataReader_GetCount(reader, NULL); - ok(hr == E_INVALIDARG, "GetCount failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetCount failed, hr=%lx\n", hr); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); ok(count == 0, "unexpected count %i\n", count); - load_stream((IUnknown*)reader, metadata_tEXt, sizeof(metadata_tEXt), WICPersistOptionDefault); + load_stream(reader, metadata_tEXt, sizeof(metadata_tEXt), WICPersistOptionDefault); + + hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); + todo_wine + ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + IWICMetadataHandlerInfo_Release(info); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %i\n", count); hr = IWICMetadataReader_GetEnumerator(reader, NULL); - ok(hr == E_INVALIDARG, "GetEnumerator failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetEnumerator failed, hr=%lx\n", hr); hr = IWICMetadataReader_GetEnumerator(reader, &enumerator); - ok(hr == S_OK, "GetEnumerator failed, hr=%x\n", hr); + ok(hr == S_OK, "GetEnumerator failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned); - ok(hr == S_OK, "Next failed, hr=%x\n", hr); - ok(items_returned == 1, "unexpected item count %i\n", items_returned); + ok(hr == S_OK, "Next failed, hr=%lx\n", hr); + ok(items_returned == 1, "unexpected item count %li\n", items_returned); if (hr == S_OK && items_returned == 1) { ok(schema.vt == VT_EMPTY, "unexpected vt: %i\n", schema.vt); ok(id.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt); - ok(!strcmp(U(id).pszVal, "winetest"), "unexpected id: %s\n", U(id).pszVal); + ok(!strcmp(id.pszVal, "winetest"), "unexpected id: %s\n", id.pszVal); ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", value.vt); - ok(!strcmp(U(value).pszVal, "value"), "unexpected value: %s\n", U(value).pszVal); + ok(!strcmp(value.pszVal, "value"), "unexpected value: %s\n", value.pszVal); PropVariantClear(&schema); PropVariantClear(&id); @@ -368,75 +744,94 @@ static void test_metadata_tEXt(void) } hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned); - ok(hr == S_FALSE, "Next failed, hr=%x\n", hr); - ok(items_returned == 0, "unexpected item count %i\n", items_returned); + ok(hr == S_FALSE, "Next failed, hr=%lx\n", hr); + ok(items_returned == 0, "unexpected item count %li\n", items_returned); IWICEnumMetadataItem_Release(enumerator); } hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktEXt), "unexpected format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetMetadataFormat(reader, NULL); - ok(hr == E_INVALIDARG, "GetMetadataFormat failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetMetadataFormat failed, hr=%lx\n", hr); id.vt = VT_LPSTR; - U(id).pszVal = CoTaskMemAlloc(strlen("winetest") + 1); - strcpy(U(id).pszVal, "winetest"); + id.pszVal = CoTaskMemAlloc(strlen("winetest") + 1); + strcpy(id.pszVal, "winetest"); hr = IWICMetadataReader_GetValue(reader, NULL, &id, NULL); - ok(hr == S_OK, "GetValue failed, hr=%x\n", hr); + ok(hr == S_OK, "GetValue failed, hr=%lx\n", hr); hr = IWICMetadataReader_GetValue(reader, &schema, NULL, &value); - ok(hr == E_INVALIDARG, "GetValue failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetValue failed, hr=%lx\n", hr); hr = IWICMetadataReader_GetValue(reader, &schema, &id, &value); - ok(hr == S_OK, "GetValue failed, hr=%x\n", hr); + ok(hr == S_OK, "GetValue failed, hr=%lx\n", hr); ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt); - ok(!strcmp(U(value).pszVal, "value"), "unexpected value: %s\n", U(value).pszVal); + ok(!strcmp(value.pszVal, "value"), "unexpected value: %s\n", value.pszVal); PropVariantClear(&value); - strcpy(U(id).pszVal, "test"); + strcpy(id.pszVal, "test"); hr = IWICMetadataReader_GetValue(reader, &schema, &id, &value); - ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "GetValue failed, hr=%x\n", hr); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "GetValue failed, hr=%lx\n", hr); PropVariantClear(&id); hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, NULL, NULL); - ok(hr == S_OK, "GetValueByIndex failed, hr=%x\n", hr); + ok(hr == S_OK, "GetValueByIndex failed, hr=%lx\n", hr); hr = IWICMetadataReader_GetValueByIndex(reader, 0, &schema, NULL, NULL); - ok(hr == S_OK, "GetValueByIndex failed, hr=%x\n", hr); + ok(hr == S_OK, "GetValueByIndex failed, hr=%lx\n", hr); ok(schema.vt == VT_EMPTY, "unexpected vt: %i\n", schema.vt); hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, &id, NULL); - ok(hr == S_OK, "GetValueByIndex failed, hr=%x\n", hr); + ok(hr == S_OK, "GetValueByIndex failed, hr=%lx\n", hr); ok(id.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt); - ok(!strcmp(U(id).pszVal, "winetest"), "unexpected id: %s\n", U(id).pszVal); + ok(!strcmp(id.pszVal, "winetest"), "unexpected id: %s\n", id.pszVal); PropVariantClear(&id); hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, NULL, &value); - ok(hr == S_OK, "GetValueByIndex failed, hr=%x\n", hr); + ok(hr == S_OK, "GetValueByIndex failed, hr=%lx\n", hr); ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", value.vt); - ok(!strcmp(U(value).pszVal, "value"), "unexpected value: %s\n", U(value).pszVal); + ok(!strcmp(value.pszVal, "value"), "unexpected value: %s\n", value.pszVal); PropVariantClear(&value); hr = IWICMetadataReader_GetValueByIndex(reader, 1, NULL, NULL, NULL); - ok(hr == E_INVALIDARG, "GetValueByIndex failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetValueByIndex failed, hr=%lx\n", hr); IWICMetadataReader_Release(reader); + + hr = CoCreateInstance(&CLSID_WICPngTextMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, metadata_tEXt, sizeof(metadata_tEXt), 0); + load_stream(writer, metadata_tEXt, sizeof(metadata_tEXt), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } static void test_metadata_gAMA(void) { + IWICMetadataHandlerInfo *info; HRESULT hr; IWICMetadataReader *reader; PROPVARIANT schema, id, value; - ULONG count; + IWICMetadataWriter *writer; + UINT count; GUID format; - static const WCHAR ImageGamma[] = {'I','m','a','g','e','G','a','m','m','a',0}; PropVariantInit(&schema); PropVariantInit(&id); @@ -444,34 +839,64 @@ static void test_metadata_gAMA(void) hr = CoCreateInstance(&CLSID_WICPngGamaMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void**)&reader); - ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /*winxp*/, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /*winxp*/, "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; - load_stream((IUnknown*)reader, metadata_gAMA, sizeof(metadata_gAMA), WICPersistOptionDefault); + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + + load_stream(reader, metadata_gAMA, sizeof(metadata_gAMA), WICPersistOptionDefault); + + hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); + todo_wine + ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + IWICMetadataHandlerInfo_Release(info); hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatChunkgAMA), "unexpected format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %i\n", count); hr = IWICMetadataReader_GetValueByIndex(reader, 0, &schema, &id, &value); - ok(hr == S_OK, "GetValue failed, hr=%x\n", hr); + ok(hr == S_OK, "GetValue failed, hr=%lx\n", hr); ok(schema.vt == VT_EMPTY, "unexpected vt: %i\n", schema.vt); PropVariantClear(&schema); ok(id.vt == VT_LPWSTR, "unexpected vt: %i\n", id.vt); - ok(!lstrcmpW(U(id).pwszVal, ImageGamma), "unexpected value: %s\n", wine_dbgstr_w(U(id).pwszVal)); + ok(!lstrcmpW(id.pwszVal, L"ImageGamma"), "unexpected value: %s\n", wine_dbgstr_w(id.pwszVal)); PropVariantClear(&id); ok(value.vt == VT_UI4, "unexpected vt: %i\n", value.vt); - ok(U(value).ulVal == 33333, "unexpected value: %u\n", U(value).ulVal); + ok(value.ulVal == 33333, "unexpected value: %lu\n", value.ulVal); PropVariantClear(&value); IWICMetadataReader_Release(reader); + + hr = CoCreateInstance(&CLSID_WICPngGamaMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, metadata_gAMA, sizeof(metadata_gAMA), 0); + load_stream(writer, metadata_gAMA, sizeof(metadata_gAMA), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } static void test_metadata_cHRM(void) @@ -479,18 +904,20 @@ static void test_metadata_cHRM(void) HRESULT hr; IWICMetadataReader *reader; PROPVARIANT schema, id, value; - ULONG count; + IWICMetadataWriter *writer; + UINT count; GUID format; int i; - static const WCHAR expected_names[8][12] = { - {'W','h','i','t','e','P','o','i','n','t','X',0}, - {'W','h','i','t','e','P','o','i','n','t','Y',0}, - {'R','e','d','X',0}, - {'R','e','d','Y',0}, - {'G','r','e','e','n','X',0}, - {'G','r','e','e','n','Y',0}, - {'B','l','u','e','X',0}, - {'B','l','u','e','Y',0}, + static const WCHAR *expected_names[8] = + { + L"WhitePointX", + L"WhitePointY", + L"RedX", + L"RedY", + L"GreenX", + L"GreenY", + L"BlueX", + L"BlueY", }; static const ULONG expected_vals[8] = { 31270,32900, 64000,33000, 30000,60000, 15000,6000 @@ -502,37 +929,193 @@ static void test_metadata_cHRM(void) hr = CoCreateInstance(&CLSID_WICPngChrmMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void**)&reader); - ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /*winxp*/, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /*winxp*/, "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; - load_stream((IUnknown*)reader, metadata_cHRM, sizeof(metadata_cHRM), WICPersistOptionDefault); + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + + load_stream(reader, metadata_cHRM, sizeof(metadata_cHRM), WICPersistOptionDefault); hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatChunkcHRM), "unexpected format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); ok(count == 8, "unexpected count %i\n", count); for (i=0; i<8; i++) { hr = IWICMetadataReader_GetValueByIndex(reader, i, &schema, &id, &value); - ok(hr == S_OK, "GetValue failed, hr=%x\n", hr); + ok(hr == S_OK, "GetValue failed, hr=%lx\n", hr); ok(schema.vt == VT_EMPTY, "unexpected vt: %i\n", schema.vt); PropVariantClear(&schema); ok(id.vt == VT_LPWSTR, "unexpected vt: %i\n", id.vt); - ok(!lstrcmpW(U(id).pwszVal, expected_names[i]), "got %s, expected %s\n", wine_dbgstr_w(U(id).pwszVal), wine_dbgstr_w(expected_names[i])); + ok(!lstrcmpW(id.pwszVal, expected_names[i]), "got %s, expected %s\n", wine_dbgstr_w(id.pwszVal), wine_dbgstr_w(expected_names[i])); PropVariantClear(&id); ok(value.vt == VT_UI4, "unexpected vt: %i\n", value.vt); - ok(U(value).ulVal == expected_vals[i], "got %u, expected %u\n", U(value).ulVal, expected_vals[i]); + ok(value.ulVal == expected_vals[i], "got %lu, expected %lu\n", value.ulVal, expected_vals[i]); PropVariantClear(&value); } IWICMetadataReader_Release(reader); + + hr = CoCreateInstance(&CLSID_WICPngChrmMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, metadata_cHRM, sizeof(metadata_cHRM), 0); + load_stream(writer, metadata_cHRM, sizeof(metadata_cHRM), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); +} + +static void test_metadata_hIST(void) +{ + HRESULT hr; + IWICMetadataReader *reader; + PROPVARIANT schema, id, value; + IWICMetadataWriter *writer; + UINT count, i; + GUID format; + + PropVariantInit(&schema); + PropVariantInit(&id); + PropVariantInit(&value); + + hr = CoCreateInstance(&CLSID_WICPngHistMetadataReader, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataReader, (void**)&reader); + ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /*winxp*/, "CoCreateInstance failed, hr=%lx\n", hr); + if (FAILED(hr)) return; + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + + load_stream(reader, metadata_hIST, sizeof(metadata_hIST), WICPersistOptionDefault); + + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%lx\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatChunkhIST), "unexpected format %s\n", wine_dbgstr_guid(&format)); + + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); + ok(count == 1, "unexpected count %i\n", count); + + hr = IWICMetadataReader_GetValueByIndex(reader, 0, &schema, &id, &value); + ok(hr == S_OK, "GetValue failed, hr=%lx\n", hr); + + ok(schema.vt == VT_EMPTY, "unexpected vt: %i\n", schema.vt); + PropVariantClear(&schema); + + ok(id.vt == VT_LPWSTR, "unexpected vt: %i\n", id.vt); + ok(!lstrcmpW(id.pwszVal, L"Frequencies"), "unexpected value: %s\n", wine_dbgstr_w(id.pwszVal)); + PropVariantClear(&id); + + ok(value.vt == (VT_UI2|VT_VECTOR), "unexpected vt: %i\n", value.vt); + ok(20 == value.caui.cElems, "expected cElems %d, got %ld\n", 20, value.caub.cElems); + for (i = 0; i < value.caui.cElems; i++) + ok(i+1 == value.caui.pElems[i], "%u: expected value %u, got %u\n", i, i+1, value.caui.pElems[i]); + PropVariantClear(&value); + + IWICMetadataReader_Release(reader); + + hr = CoCreateInstance(&CLSID_WICPngHistMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, metadata_hIST, sizeof(metadata_hIST), 0); + load_stream(writer, metadata_hIST, sizeof(metadata_hIST), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); +} + +static void test_metadata_tIME(void) +{ + HRESULT hr; + IWICMetadataReader *reader; + IWICMetadataWriter *writer; + UINT count; + GUID format; + static const struct test_data td[] = + { + { VT_UI2, 0, 0, { 2000 }, NULL, L"Year" }, + { VT_UI1, 0, 0, { 1 }, NULL, L"Month" }, + { VT_UI1, 0, 0, { 2 }, NULL, L"Day" }, + { VT_UI1, 0, 0, { 12 }, NULL, L"Hour" }, + { VT_UI1, 0, 0, { 34 }, NULL, L"Minute" }, + { VT_UI1, 0, 0, { 56 }, NULL, L"Second" }, + }; + + hr = CoCreateInstance(&CLSID_WICPngTimeMetadataReader, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataReader, (void**)&reader); + ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /*winxp*/, "CoCreateInstance failed, hr=%lx\n", hr); + if (FAILED(hr)) return; + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + + load_stream(reader, metadata_tIME, sizeof(metadata_tIME), WICPersistOptionDefault); + + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%lx\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktIME), "unexpected format %s\n", wine_dbgstr_guid(&format)); + + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); + ok(count == ARRAY_SIZE(td), "unexpected count %i\n", count); + + compare_metadata(reader, td, count); + + IWICMetadataReader_Release(reader); + + hr = CoCreateInstance(&CLSID_WICPngTimeMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, metadata_tIME, sizeof(metadata_tIME), 0); + load_stream(writer, metadata_tIME, sizeof(metadata_tIME), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } static inline USHORT ushort_bswap(USHORT s) @@ -643,119 +1226,7 @@ static void byte_swap_ifd_data(char *data) } } -struct test_data -{ - ULONG type, id; - int count; /* if VT_VECTOR */ - LONGLONG value[13]; - const char *string; - const WCHAR id_string[32]; -}; - -static void compare_metadata(IWICMetadataReader *reader, const struct test_data *td, ULONG count) -{ - HRESULT hr; - IWICEnumMetadataItem *enumerator; - PROPVARIANT schema, id, value; - ULONG items_returned, i; - - hr = IWICMetadataReader_GetEnumerator(reader, NULL); - ok(hr == E_INVALIDARG, "GetEnumerator error %#x\n", hr); - - hr = IWICMetadataReader_GetEnumerator(reader, &enumerator); - ok(hr == S_OK, "GetEnumerator error %#x\n", hr); - - PropVariantInit(&schema); - PropVariantInit(&id); - PropVariantInit(&value); - - for (i = 0; i < count; i++) - { - hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned); - ok(hr == S_OK, "Next error %#x\n", hr); - ok(items_returned == 1, "unexpected item count %u\n", items_returned); - - ok(schema.vt == VT_EMPTY, "%u: unexpected vt: %u\n", i, schema.vt); - ok(id.vt == VT_UI2 || id.vt == VT_LPWSTR || id.vt == VT_EMPTY, "%u: unexpected vt: %u\n", i, id.vt); - if (id.vt == VT_UI2) - ok(U(id).uiVal == td[i].id, "%u: expected id %#x, got %#x\n", i, td[i].id, U(id).uiVal); - else if (id.vt == VT_LPWSTR) - ok(!lstrcmpW(td[i].id_string, U(id).pwszVal), - "%u: expected %s, got %s\n", i, wine_dbgstr_w(td[i].id_string), wine_dbgstr_w(U(id).pwszVal)); - - ok(value.vt == td[i].type, "%u: expected vt %#x, got %#x\n", i, td[i].type, value.vt); - if (value.vt & VT_VECTOR) - { - ULONG j; - switch (value.vt & ~VT_VECTOR) - { - case VT_I1: - case VT_UI1: - ok(td[i].count == U(value).caub.cElems, "%u: expected cElems %d, got %d\n", i, td[i].count, U(value).caub.cElems); - for (j = 0; j < U(value).caub.cElems; j++) - ok(td[i].value[j] == U(value).caub.pElems[j], "%u: expected value[%d] %#x/%#x, got %#x\n", i, j, (ULONG)td[i].value[j], (ULONG)(td[i].value[j] >> 32), U(value).caub.pElems[j]); - break; - case VT_I2: - case VT_UI2: - ok(td[i].count == U(value).caui.cElems, "%u: expected cElems %d, got %d\n", i, td[i].count, U(value).caui.cElems); - for (j = 0; j < U(value).caui.cElems; j++) - ok(td[i].value[j] == U(value).caui.pElems[j], "%u: expected value[%d] %#x/%#x, got %#x\n", i, j, (ULONG)td[i].value[j], (ULONG)(td[i].value[j] >> 32), U(value).caui.pElems[j]); - break; - case VT_I4: - case VT_UI4: - case VT_R4: - ok(td[i].count == U(value).caul.cElems, "%u: expected cElems %d, got %d\n", i, td[i].count, U(value).caul.cElems); - for (j = 0; j < U(value).caul.cElems; j++) - ok(td[i].value[j] == U(value).caul.pElems[j], "%u: expected value[%d] %#x/%#x, got %#x\n", i, j, (ULONG)td[i].value[j], (ULONG)(td[i].value[j] >> 32), U(value).caul.pElems[j]); - break; - case VT_I8: - case VT_UI8: - case VT_R8: - ok(td[i].count == U(value).cauh.cElems, "%u: expected cElems %d, got %d\n", i, td[i].count, U(value).cauh.cElems); - for (j = 0; j < U(value).cauh.cElems; j++) - ok(td[i].value[j] == U(value).cauh.pElems[j].QuadPart, "%u: expected value[%d] %08x/%08x, got %08x/%08x\n", i, j, (ULONG)td[i].value[j], (ULONG)(td[i].value[j] >> 32), U(value).cauh.pElems[j].u.LowPart, U(value).cauh.pElems[j].u.HighPart); - break; - case VT_LPSTR: - ok(td[i].count == U(value).calpstr.cElems, "%u: expected cElems %d, got %d\n", i, td[i].count, U(value).caub.cElems); - for (j = 0; j < U(value).calpstr.cElems; j++) - trace("%u: %s\n", j, U(value).calpstr.pElems[j]); - /* fall through to not handled message */ - default: - ok(0, "%u: array of type %d is not handled\n", i, value.vt & ~VT_VECTOR); - break; - } - } - else if (value.vt == VT_LPSTR) - { - ok(td[i].count == strlen(U(value).pszVal) || - broken(td[i].count == strlen(U(value).pszVal) + 1), /* before Win7 */ - "%u: expected count %d, got %d\n", i, td[i].count, lstrlenA(U(value).pszVal)); - if (td[i].count == strlen(U(value).pszVal)) - ok(!strcmp(td[i].string, U(value).pszVal), - "%u: expected %s, got %s\n", i, td[i].string, U(value).pszVal); - } - else if (value.vt == VT_BLOB) - { - ok(td[i].count == U(value).blob.cbSize, "%u: expected count %d, got %d\n", i, td[i].count, U(value).blob.cbSize); - ok(!memcmp(td[i].string, U(value).blob.pBlobData, td[i].count), "%u: expected %s, got %s\n", i, td[i].string, U(value).blob.pBlobData); - } - else - ok(U(value).uhVal.QuadPart == td[i].value[0], "%u: expected value %#x/%#x got %#x/%#x\n", - i, (UINT)td[i].value[0], (UINT)(td[i].value[0] >> 32), U(value).uhVal.u.LowPart, U(value).uhVal.u.HighPart); - - PropVariantClear(&schema); - PropVariantClear(&id); - PropVariantClear(&value); - } - - hr = IWICEnumMetadataItem_Next(enumerator, 1, &schema, &id, &value, &items_returned); - ok(hr == S_FALSE, "Next should fail\n"); - ok(items_returned == 0, "unexpected item count %u\n", items_returned); - - IWICEnumMetadataItem_Release(enumerator); -} - -static void test_metadata_IFD(void) +static void test_ifd_content(IWICMetadataReader *reader) { static const struct test_data td[28] = { @@ -791,171 +1262,277 @@ static void test_metadata_IFD(void) ((LONGLONG)0x50607080 << 32) | 0x10203040, ((LONGLONG)0x55667788 << 32) | 0x11223344 } }, }; - HRESULT hr; - IWICMetadataReader *reader; - IWICMetadataBlockReader *blockreader; PROPVARIANT schema, id, value; - ULONG count; - GUID format; char *IFD_data_swapped; -#ifdef WORDS_BIGENDIAN - DWORD persist_options = WICPersistOptionBigEndian; -#else - DWORD persist_options = WICPersistOptionLittleEndian; -#endif - - hr = CoCreateInstance(&CLSID_WICIfdMetadataReader, NULL, CLSCTX_INPROC_SERVER, - &IID_IWICMetadataReader, (void**)&reader); - ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); - - hr = IWICMetadataReader_GetCount(reader, NULL); - ok(hr == E_INVALIDARG, "GetCount error %#x\n", hr); + UINT count; + HRESULT hr; hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == 0, "unexpected count %u\n", count); - load_stream((IUnknown*)reader, (const char *)&IFD_data, sizeof(IFD_data), persist_options); + load_stream(reader, (const char *)&IFD_data, sizeof(IFD_data), WICPersistOptionLittleEndian); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); compare_metadata(reader, td, count); - /* test IFD data with different endianness */ - if (persist_options == WICPersistOptionLittleEndian) - persist_options = WICPersistOptionBigEndian; - else - persist_options = WICPersistOptionLittleEndian; - + /* Test big-endian IFD data */ IFD_data_swapped = HeapAlloc(GetProcessHeap(), 0, sizeof(IFD_data)); memcpy(IFD_data_swapped, &IFD_data, sizeof(IFD_data)); byte_swap_ifd_data(IFD_data_swapped); - load_stream((IUnknown *)reader, IFD_data_swapped, sizeof(IFD_data), persist_options); + load_stream(reader, IFD_data_swapped, sizeof(IFD_data), WICPersistOptionBigEndian); + todo_wine + check_persist_options(reader, WICPersistOptionBigEndian); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); compare_metadata(reader, td, count); HeapFree(GetProcessHeap(), 0, IFD_data_swapped); - hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat error %#x\n", hr); - ok(IsEqualGUID(&format, &GUID_MetadataFormatIfd), "unexpected format %s\n", wine_dbgstr_guid(&format)); - - hr = IWICMetadataReader_GetMetadataFormat(reader, NULL); - ok(hr == E_INVALIDARG, "GetMetadataFormat should fail\n"); - hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, NULL, NULL); - ok(hr == S_OK, "GetValueByIndex error %#x\n", hr); + ok(hr == S_OK, "GetValueByIndex error %#lx\n", hr); PropVariantInit(&schema); PropVariantInit(&id); PropVariantInit(&value); hr = IWICMetadataReader_GetValueByIndex(reader, count - 1, NULL, NULL, NULL); - ok(hr == S_OK, "GetValueByIndex error %#x\n", hr); + ok(hr == S_OK, "GetValueByIndex error %#lx\n", hr); hr = IWICMetadataReader_GetValueByIndex(reader, 0, &schema, NULL, NULL); - ok(hr == S_OK, "GetValueByIndex error %#x\n", hr); + ok(hr == S_OK, "GetValueByIndex error %#lx\n", hr); ok(schema.vt == VT_EMPTY, "unexpected vt: %u\n", schema.vt); hr = IWICMetadataReader_GetValueByIndex(reader, count - 1, &schema, NULL, NULL); - ok(hr == S_OK, "GetValueByIndex error %#x\n", hr); + ok(hr == S_OK, "GetValueByIndex error %#lx\n", hr); ok(schema.vt == VT_EMPTY, "unexpected vt: %u\n", schema.vt); hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, &id, NULL); - ok(hr == S_OK, "GetValueByIndex error %#x\n", hr); + ok(hr == S_OK, "GetValueByIndex error %#lx\n", hr); ok(id.vt == VT_UI2, "unexpected vt: %u\n", id.vt); - ok(U(id).uiVal == 0xfe, "unexpected id: %#x\n", U(id).uiVal); + ok(id.uiVal == 0xfe, "unexpected id: %#x\n", id.uiVal); PropVariantClear(&id); hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, NULL, &value); - ok(hr == S_OK, "GetValueByIndex error %#x\n", hr); + ok(hr == S_OK, "GetValueByIndex error %#lx\n", hr); ok(value.vt == VT_UI2, "unexpected vt: %u\n", value.vt); - ok(U(value).uiVal == 1, "unexpected id: %#x\n", U(value).uiVal); + ok(value.uiVal == 1, "unexpected id: %#x\n", value.uiVal); PropVariantClear(&value); hr = IWICMetadataReader_GetValueByIndex(reader, count, &schema, NULL, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); PropVariantInit(&schema); PropVariantInit(&id); PropVariantInit(&value); hr = IWICMetadataReader_GetValue(reader, &schema, &id, &value); - ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "expected WINCODEC_ERR_PROPERTYNOTFOUND, got %#x\n", hr); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "expected WINCODEC_ERR_PROPERTYNOTFOUND, got %#lx\n", hr); hr = IWICMetadataReader_GetValue(reader, NULL, &id, NULL); - ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "expected WINCODEC_ERR_PROPERTYNOTFOUND, got %#x\n", hr); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "expected WINCODEC_ERR_PROPERTYNOTFOUND, got %#lx\n", hr); hr = IWICMetadataReader_GetValue(reader, &schema, NULL, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICMetadataReader_GetValue(reader, &schema, &id, NULL); - ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "expected WINCODEC_ERR_PROPERTYNOTFOUND, got %#x\n", hr); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "expected WINCODEC_ERR_PROPERTYNOTFOUND, got %#lx\n", hr); hr = IWICMetadataReader_GetValue(reader, &schema, NULL, &value); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); id.vt = VT_UI2; - U(id).uiVal = 0xf00e; + id.uiVal = 0xf00e; hr = IWICMetadataReader_GetValue(reader, NULL, &id, NULL); - ok(hr == S_OK, "GetValue error %#x\n", hr); + ok(hr == S_OK, "GetValue error %#lx\n", hr); /* schema is ignored by Ifd metadata reader */ schema.vt = VT_UI4; - U(schema).ulVal = 0xdeadbeef; + schema.ulVal = 0xdeadbeef; hr = IWICMetadataReader_GetValue(reader, &schema, &id, &value); - ok(hr == S_OK, "GetValue error %#x\n", hr); + ok(hr == S_OK, "GetValue error %#lx\n", hr); ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt); - ok(!strcmp(U(value).pszVal, "Hello World!"), "unexpected value: %s\n", U(value).pszVal); + ok(!strcmp(value.pszVal, "Hello World!"), "unexpected value: %s\n", value.pszVal); PropVariantClear(&value); hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value); - ok(hr == S_OK, "GetValue error %#x\n", hr); + ok(hr == S_OK, "GetValue error %#lx\n", hr); ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt); - ok(!strcmp(U(value).pszVal, "Hello World!"), "unexpected value: %s\n", U(value).pszVal); + ok(!strcmp(value.pszVal, "Hello World!"), "unexpected value: %s\n", value.pszVal); PropVariantClear(&value); +} - hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICMetadataBlockReader, (void**)&blockreader); - ok(hr == E_NOINTERFACE, "QueryInterface failed, hr=%x\n", hr); +static void test_metadata_Ifd(void) +{ + IWICMetadataReader *reader; + IWICMetadataWriter *writer; + GUID format; + UINT count; + HRESULT hr; - if (SUCCEEDED(hr)) - IWICMetadataBlockReader_Release(blockreader); + hr = CoCreateInstance(&CLSID_WICIfdMetadataReader, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataReader, (void**)&reader); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + check_interface(reader, &IID_IWICMetadataBlockReader, FALSE); + + hr = IWICMetadataReader_GetCount(reader, NULL); + ok(hr == E_INVALIDARG, "GetCount error %#lx\n", hr); + + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "GetCount error %#lx\n", hr); + ok(count == 0, "unexpected count %u\n", count); + + test_ifd_content(reader); + + test_reader_container_format(reader, &GUID_ContainerFormatTiff); + + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "GetMetadataFormat error %#lx\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatIfd), "unexpected format %s\n", wine_dbgstr_guid(&format)); + + hr = IWICMetadataReader_GetMetadataFormat(reader, NULL); + ok(hr == E_INVALIDARG, "GetMetadataFormat should fail\n"); IWICMetadataReader_Release(reader); + + hr = CoCreateInstance(&CLSID_WICIfdMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, (const char *)&IFD_data, sizeof(IFD_data), 0); + load_stream(writer, (const char *)&IFD_data, sizeof(IFD_data), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } static void test_metadata_Exif(void) { HRESULT hr; IWICMetadataReader *reader; - IWICMetadataBlockReader *blockreader; + IWICMetadataWriter *writer; UINT count=0; + GUID format; hr = CoCreateInstance(&CLSID_WICExifMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void**)&reader); - todo_wine ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + todo_wine ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); if (FAILED(hr)) return; + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + check_interface(reader, &IID_IWICMetadataBlockReader, FALSE); + hr = IWICMetadataReader_GetCount(reader, NULL); - ok(hr == E_INVALIDARG, "GetCount error %#x\n", hr); + ok(hr == E_INVALIDARG, "GetCount error %#lx\n", hr); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == 0, "unexpected count %u\n", count); - hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICMetadataBlockReader, (void**)&blockreader); - ok(hr == E_NOINTERFACE, "QueryInterface failed, hr=%x\n", hr); + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatExif), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); - if (SUCCEEDED(hr)) - IWICMetadataBlockReader_Release(blockreader); + test_reader_container_format(reader, &GUID_MetadataFormatIfd); + test_ifd_content(reader); IWICMetadataReader_Release(reader); + + hr = CoCreateInstance(&CLSID_WICExifMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + todo_wine + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, (const char *)&IFD_data, sizeof(IFD_data), 0); + load_stream(writer, (const char *)&IFD_data, sizeof(IFD_data), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } -static void test_create_reader(void) +static void test_metadata_Gps(void) +{ + IWICMetadataReader *reader; + IWICMetadataWriter *writer; + UINT count=0; + GUID format; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_WICGpsMetadataReader, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataReader, (void **)&reader); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + check_interface(reader, &IID_IWICMetadataBlockReader, FALSE); + + hr = IWICMetadataReader_GetCount(reader, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "GetCount error %#lx\n", hr); + ok(!count, "Unexpected count %u.\n", count); + + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatGps), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + + test_reader_container_format(reader, &GUID_MetadataFormatIfd); + test_ifd_content(reader); + + IWICMetadataReader_Release(reader); + + hr = CoCreateInstance(&CLSID_WICGpsMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, (const char *)&IFD_data, sizeof(IFD_data), 0); + load_stream(writer, (const char *)&IFD_data, sizeof(IFD_data), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); +} + +static void test_create_reader_from_container(void) { HRESULT hr; IWICComponentFactory *factory; @@ -966,38 +1543,44 @@ static void test_create_reader(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICComponentFactory, (void**)&factory); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); stream = create_stream(metadata_tEXt, sizeof(metadata_tEXt)); hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, NULL, NULL, WICPersistOptionDefault, stream, &reader); - ok(hr == E_INVALIDARG, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "CreateMetadataReaderFromContainer failed, hr=%lx\n", hr); hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, &GUID_ContainerFormatPng, NULL, WICPersistOptionDefault, NULL, &reader); - ok(hr == E_INVALIDARG, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "CreateMetadataReaderFromContainer failed, hr=%lx\n", hr); hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, &GUID_ContainerFormatPng, NULL, WICPersistOptionDefault, stream, NULL); - ok(hr == E_INVALIDARG, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "CreateMetadataReaderFromContainer failed, hr=%lx\n", hr); hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, &GUID_ContainerFormatPng, NULL, WICPersistOptionDefault, stream, &reader); - ok(hr == S_OK, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateMetadataReaderFromContainer failed, hr=%lx\n", hr); + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCount failed, hr=%lx\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(hr == S_OK, "GetMetadataFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktEXt), "unexpected format %s\n", wine_dbgstr_guid(&format)); IWICMetadataReader_Release(reader); @@ -1006,21 +1589,187 @@ static void test_create_reader(void) hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, &GUID_ContainerFormatWmp, NULL, WICPersistOptionDefault, stream, &reader); - ok(hr == S_OK, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateMetadataReaderFromContainer failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCount failed, hr=%lx\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(hr == S_OK, "GetMetadataFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatUnknown), "unexpected format %s\n", wine_dbgstr_guid(&format)); IWICMetadataReader_Release(reader); } + hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory, &GUID_ContainerFormatWmp, + NULL, WICMetadataCreationFailUnknown, stream, &reader); + ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "Unexpected hr %#lx.\n", hr); + + IStream_Release(stream); + + IWICComponentFactory_Release(factory); +} + +static void test_CreateMetadataReader(void) +{ + IWICPersistStream *persist_stream; + IWICComponentFactory *factory; + IWICMetadataReader *reader; + IStream *stream, *stream2; + LARGE_INTEGER pos; + UINT count = 0; + GUID format; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICComponentFactory, (void **)&factory); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + stream = create_stream(metadata_tEXt, sizeof(metadata_tEXt)); + + hr = IWICComponentFactory_CreateMetadataReader(factory, NULL, NULL, 0, stream, &reader); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + memset(&format, 0xcc, sizeof(format)); + hr = IWICComponentFactory_CreateMetadataReader(factory, &format, NULL, 0, stream, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = get_persist_stream(reader, &stream2); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + ok(stream == stream2, "Unexpected stream.\n"); + IStream_Release(stream2); + } + + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatUnknown), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + IWICMetadataReader_Release(reader); + + memset(&format, 0xcc, sizeof(format)); + hr = IWICComponentFactory_CreateMetadataReader(factory, &format, NULL, WICMetadataCreationFailUnknown, stream, &reader); + ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "Unexpected hr %#lx.\n", hr); + + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_MetadataFormatChunktEXt, + NULL, 0, NULL, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = get_persist_stream(reader, &stream2); + todo_wine + ok(hr == WINCODEC_ERR_STREAMNOTAVAILABLE, "Unexpected hr %#lx.\n", hr); + + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktEXt), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + IWICMetadataReader_Release(reader); + + pos.QuadPart = 0; + hr = IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_MetadataFormatChunktEXt, NULL, 0, + stream, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_ContainerFormatPng, NULL, 0, stream, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatUnknown), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + IWICMetadataReader_Release(reader); + + hr = IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_MetadataFormatChunktEXt, NULL, 0, stream, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IWICMetadataWriter, FALSE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %u.\n", count); + + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktEXt), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + + IWICMetadataReader_Release(reader); + + /* Invalid vendor. */ + hr = IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_MetadataFormatChunktEXt, &IID_IUnknown, 0, stream, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktEXt), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + IWICMetadataReader_Release(reader); + + /* Mismatching metadata format. */ + hr = IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_MetadataFormatApp1, NULL, 0, stream, &reader); + todo_wine + ok(hr == WINCODEC_ERR_BADMETADATAHEADER, "Unexpected hr %#lx.\n", hr); + + /* With and without caching */ + hr = IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_MetadataFormatChunktEXt, NULL, + WICPersistOptionNoCacheStream, stream, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %u.\n", count); + + hr = get_persist_stream(reader, &stream2); + todo_wine + ok(hr == WINCODEC_ERR_STREAMNOTAVAILABLE, "Unexpected hr %#lx.\n", hr); + + hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist_stream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IWICPersistStream_LoadEx(persist_stream, stream, NULL, 0); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = get_persist_stream(reader, &stream2); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + ok(stream == stream2, "Unexpected stream.\n"); + IStream_Release(stream2); + } + + /* Going from caching to no caching. */ + hr = IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICPersistStream_LoadEx(persist_stream, stream, NULL, WICPersistOptionNoCacheStream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = get_persist_stream(reader, &stream2); + todo_wine + ok(hr == WINCODEC_ERR_STREAMNOTAVAILABLE, "Unexpected hr %#lx.\n", hr); + todo_wine + check_persist_options(reader, WICPersistOptionNoCacheStream); + + IWICPersistStream_Release(persist_stream); + + IWICMetadataReader_Release(reader); + IStream_Release(stream); IWICComponentFactory_Release(factory); @@ -1030,12 +1779,12 @@ static void test_metadata_png(void) { static const struct test_data td[6] = { - { VT_UI2, 0, 0, { 2005 }, NULL, { 'Y','e','a','r',0 } }, - { VT_UI1, 0, 0, { 6 }, NULL, { 'M','o','n','t','h',0 } }, - { VT_UI1, 0, 0, { 3 }, NULL, { 'D','a','y',0 } }, - { VT_UI1, 0, 0, { 15 }, NULL, { 'H','o','u','r',0 } }, - { VT_UI1, 0, 0, { 7 }, NULL, { 'M','i','n','u','t','e',0 } }, - { VT_UI1, 0, 0, { 45 }, NULL, { 'S','e','c','o','n','d',0 } } + { VT_UI2, 0, 0, { 2005 }, NULL, L"Year" }, + { VT_UI1, 0, 0, { 6 }, NULL, L"Month" }, + { VT_UI1, 0, 0, { 3 }, NULL, L"Day" }, + { VT_UI1, 0, 0, { 15 }, NULL, L"Hour" }, + { VT_UI1, 0, 0, { 7 }, NULL, L"Minute" }, + { VT_UI1, 0, 0, { 45 }, NULL, L"Second" } }; IStream *stream; IWICBitmapDecoder *decoder; @@ -1050,61 +1799,62 @@ static void test_metadata_png(void) hr = CoCreateInstance(&CLSID_WICPngDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void**)&decoder); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); if (FAILED(hr)) return; stream = create_stream(pngimage, sizeof(pngimage)); hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnLoad); - ok(hr == S_OK, "Initialize failed, hr=%x\n", hr); + ok(hr == S_OK, "Initialize failed, hr=%lx\n", hr); - hr = IWICBitmapDecoder_QueryInterface(decoder, &IID_IWICMetadataBlockReader, (void**)&blockreader); - ok(hr == E_NOINTERFACE, "QueryInterface failed, hr=%x\n", hr); + check_interface(decoder, &IID_IWICMetadataBlockReader, FALSE); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame failed, hr=%x\n", hr); + ok(hr == S_OK, "GetFrame failed, hr=%lx\n", hr); hr = IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICMetadataBlockReader, (void**)&blockreader); - ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr); + ok(hr == S_OK, "QueryInterface failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, NULL); - ok(hr == E_INVALIDARG, "GetContainerFormat failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetContainerFormat failed, hr=%lx\n", hr); hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, &containerformat); - ok(hr == S_OK, "GetContainerFormat failed, hr=%x\n", hr); + ok(hr == S_OK, "GetContainerFormat failed, hr=%lx\n", hr); ok(IsEqualGUID(&containerformat, &GUID_ContainerFormatPng), "unexpected container format\n"); hr = IWICMetadataBlockReader_GetCount(blockreader, NULL); - ok(hr == E_INVALIDARG, "GetCount failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetCount failed, hr=%lx\n", hr); hr = IWICMetadataBlockReader_GetCount(blockreader, &count); - ok(hr == S_OK, "GetCount failed, hr=%x\n", hr); + ok(hr == S_OK, "GetCount failed, hr=%lx\n", hr); ok(count == 1, "unexpected count %d\n", count); if (0) { /* Crashes on Windows XP */ hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 0, NULL); - ok(hr == E_INVALIDARG, "GetReaderByIndex failed, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "GetReaderByIndex failed, hr=%lx\n", hr); } hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 0, &reader); - ok(hr == S_OK, "GetReaderByIndex failed, hr=%x\n", hr); + ok(hr == S_OK, "GetReaderByIndex failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetMetadataFormat(reader, &containerformat); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); - todo_wine ok(IsEqualGUID(&containerformat, &GUID_MetadataFormatChunktIME) || + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); + ok(IsEqualGUID(&containerformat, &GUID_MetadataFormatChunktIME) || broken(IsEqualGUID(&containerformat, &GUID_MetadataFormatUnknown)) /* Windows XP */, "unexpected container format\n"); + test_reader_container_format(reader, &GUID_ContainerFormatPng); + hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); - todo_wine ok(count == 6 || broken(count == 1) /* XP */, "expected 6, got %u\n", count); + ok(hr == S_OK, "GetCount error %#lx\n", hr); + ok(count == 6 || broken(count == 1) /* XP */, "expected 6, got %u\n", count); if (count == 6) compare_metadata(reader, td, count); @@ -1112,20 +1862,20 @@ static void test_metadata_png(void) } hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 1, &reader); - todo_wine ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "GetReaderByIndex failed, hr=%x\n", hr); + todo_wine ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "GetReaderByIndex failed, hr=%lx\n", hr); hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICComponentFactory, (void**)&factory); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); hr = IWICComponentFactory_CreateQueryReaderFromBlockReader(factory, NULL, &queryreader); - ok(hr == E_INVALIDARG, "CreateQueryReaderFromBlockReader should have failed: %08x\n", hr); + ok(hr == E_INVALIDARG, "CreateQueryReaderFromBlockReader should have failed: %08lx\n", hr); hr = IWICComponentFactory_CreateQueryReaderFromBlockReader(factory, blockreader, NULL); - ok(hr == E_INVALIDARG, "CreateQueryReaderFromBlockReader should have failed: %08x\n", hr); + ok(hr == E_INVALIDARG, "CreateQueryReaderFromBlockReader should have failed: %08lx\n", hr); hr = IWICComponentFactory_CreateQueryReaderFromBlockReader(factory, blockreader, &queryreader); - ok(hr == S_OK, "CreateQueryReaderFromBlockReader failed: %08x\n", hr); + ok(hr == S_OK, "CreateQueryReaderFromBlockReader failed: %08lx\n", hr); IWICMetadataQueryReader_Release(queryreader); @@ -1135,7 +1885,7 @@ static void test_metadata_png(void) } hr = IWICBitmapFrameDecode_GetMetadataQueryReader(frame, &queryreader); - ok(hr == S_OK, "GetMetadataQueryReader failed: %08x\n", hr); + ok(hr == S_OK, "GetMetadataQueryReader failed: %08lx\n", hr); if (SUCCEEDED(hr)) { @@ -1241,39 +1991,41 @@ static void test_metadata_gif(void) hr = CoCreateInstance(&CLSID_WICGifDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void **)&decoder); - ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnLoad); - ok(hr == S_OK, "Initialize error %#x\n", hr); + ok(hr == S_OK, "Initialize error %#lx\n", hr); IStream_Release(stream); /* global metadata block */ hr = IWICBitmapDecoder_QueryInterface(decoder, &IID_IWICMetadataBlockReader, (void **)&blockreader); - ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#x\n", hr); + ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataBlockReader_GetCount(blockreader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == 1, "expected 1, got %u\n", count); hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 0, &reader); - ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr); + ok(hr == S_OK, "GetReaderByIndex error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatLSD), /* Logical Screen Descriptor */ "wrong metadata format %s\n", wine_dbgstr_guid(&format)); + test_reader_container_format(reader, &GUID_ContainerFormatGif); + hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == ARRAY_SIZE(gif_LSD), "unexpected count %u\n", count); compare_metadata(reader, gif_LSD, count); @@ -1282,47 +2034,47 @@ static void test_metadata_gif(void) } hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 1, &reader); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); IWICMetadataBlockReader_Release(blockreader); } /* frame metadata block */ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICMetadataBlockReader, (void **)&blockreader); - ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#x\n", hr); + ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataBlockReader_GetCount(blockreader, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICMetadataBlockReader_GetCount(blockreader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == 1, "expected 1, got %u\n", count); hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 0, &reader); - ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr); + ok(hr == S_OK, "GetReaderByIndex error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatIMD), /* Image Descriptor */ "wrong metadata format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == ARRAY_SIZE(gif_IMD), "unexpected count %u\n", count); compare_metadata(reader, gif_IMD, count); @@ -1331,7 +2083,7 @@ static void test_metadata_gif(void) } hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 1, &reader); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); IWICMetadataBlockReader_Release(blockreader); } @@ -1344,39 +2096,39 @@ static void test_metadata_gif(void) hr = CoCreateInstance(&CLSID_WICGifDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (void **)&decoder); - ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnLoad); - ok(hr == S_OK, "Initialize error %#x\n", hr); + ok(hr == S_OK, "Initialize error %#lx\n", hr); IStream_Release(stream); /* global metadata block */ hr = IWICBitmapDecoder_QueryInterface(decoder, &IID_IWICMetadataBlockReader, (void **)&blockreader); - ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#x\n", hr); + ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataBlockReader_GetCount(blockreader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 0, &reader); - ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr); + ok(hr == S_OK, "GetReaderByIndex error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatLSD), /* Logical Screen Descriptor */ "wrong metadata format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == ARRAY_SIZE(animated_gif_LSD), "unexpected count %u\n", count); compare_metadata(reader, animated_gif_LSD, count); @@ -1385,17 +2137,17 @@ static void test_metadata_gif(void) } hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 1, &reader); - ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr); + ok(hr == S_OK, "GetReaderByIndex error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatAPE), /* Application Extension */ "wrong metadata format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == ARRAY_SIZE(animated_gif_APE), "unexpected count %u\n", count); compare_metadata(reader, animated_gif_APE, count); @@ -1404,17 +2156,17 @@ static void test_metadata_gif(void) } hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 2, &reader); - ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr); + ok(hr == S_OK, "GetReaderByIndex error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatGifComment), /* Comment Extension */ "wrong metadata format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == ARRAY_SIZE(animated_gif_comment_1), "unexpected count %u\n", count); compare_metadata(reader, animated_gif_comment_1, count); @@ -1423,17 +2175,17 @@ static void test_metadata_gif(void) } hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 3, &reader); - ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr); + ok(hr == S_OK, "GetReaderByIndex error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatUnknown), "wrong metadata format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == ARRAY_SIZE(animated_gif_plain_1), "unexpected count %u\n", count); compare_metadata(reader, animated_gif_plain_1, count); @@ -1442,47 +2194,47 @@ static void test_metadata_gif(void) } hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 4, &reader); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); IWICMetadataBlockReader_Release(blockreader); } /* frame metadata block */ hr = IWICBitmapDecoder_GetFrame(decoder, 1, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICMetadataBlockReader, (void **)&blockreader); - ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#x\n", hr); + ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* before Win7 */, "QueryInterface error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICMetadataBlockReader_GetContainerFormat(blockreader, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataBlockReader_GetCount(blockreader, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICMetadataBlockReader_GetCount(blockreader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 0, &reader); - ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr); + ok(hr == S_OK, "GetReaderByIndex error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatIMD), /* Image Descriptor */ "wrong metadata format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == ARRAY_SIZE(animated_gif_IMD), "unexpected count %u\n", count); compare_metadata(reader, animated_gif_IMD, count); @@ -1491,17 +2243,36 @@ static void test_metadata_gif(void) } hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 1, &reader); - ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr); + ok(hr == S_OK, "GetReaderByIndex error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatGCE), /* Graphic Control Extension */ + "wrong metadata format %s\n", wine_dbgstr_guid(&format)); + + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "GetCount error %#lx\n", hr); + ok(count == ARRAY_SIZE(animated_gif_GCE), "unexpected count %u\n", count); + + compare_metadata(reader, animated_gif_GCE, count); + + IWICMetadataReader_Release(reader); + } + + hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 2, &reader); + ok(hr == S_OK, "GetReaderByIndex error %#lx\n", hr); + + if (SUCCEEDED(hr)) + { + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatGifComment), /* Comment Extension */ "wrong metadata format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == ARRAY_SIZE(animated_gif_comment_2), "unexpected count %u\n", count); if (count == 1) @@ -1510,18 +2281,18 @@ static void test_metadata_gif(void) IWICMetadataReader_Release(reader); } - hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 2, &reader); - ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr); + hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 3, &reader); + ok(hr == S_OK, "GetReaderByIndex error %#lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); + ok(hr == S_OK, "GetMetadataFormat failed, hr=%#lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatUnknown), "wrong metadata format %s\n", wine_dbgstr_guid(&format)); hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); + ok(hr == S_OK, "GetCount error %#lx\n", hr); ok(count == ARRAY_SIZE(animated_gif_plain_2), "unexpected count %u\n", count); compare_metadata(reader, animated_gif_plain_2, count); @@ -1529,34 +2300,15 @@ static void test_metadata_gif(void) IWICMetadataReader_Release(reader); } - hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 3, &reader); - ok(hr == S_OK, "GetReaderByIndex error %#x\n", hr); - - if (SUCCEEDED(hr)) - { - hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat failed, hr=%#x\n", hr); - ok(IsEqualGUID(&format, &GUID_MetadataFormatGCE), /* Graphic Control Extension */ - "wrong metadata format %s\n", wine_dbgstr_guid(&format)); - - hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); - ok(count == ARRAY_SIZE(animated_gif_GCE), "unexpected count %u\n", count); - - compare_metadata(reader, animated_gif_GCE, count); - - IWICMetadataReader_Release(reader); - } - hr = IWICMetadataBlockReader_GetReaderByIndex(blockreader, 4, &reader); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); IWICMetadataBlockReader_Release(blockreader); } hr = IWICBitmapDecoder_GetMetadataQueryReader(decoder, &queryreader); ok(hr == S_OK || broken(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION) /* before Vista */, - "GetMetadataQueryReader error %#x\n", hr); + "GetMetadataQueryReader error %#lx\n", hr); if (SUCCEEDED(hr)) { static const struct @@ -1584,23 +2336,22 @@ static void test_metadata_gif(void) { "grctlext", WINCODEC_ERR_PROPERTYNOTSUPPORTED, 0 }, { "/imgdesc", WINCODEC_ERR_PROPERTYNOTFOUND, 0 }, }; - static const WCHAR rootW[] = {'/',0}; WCHAR name[256]; UINT len, i, j; PROPVARIANT value; IWICMetadataQueryReader *meta_reader; hr = IWICMetadataQueryReader_GetContainerFormat(queryreader, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); name[0] = 0; len = 0xdeadbeef; hr = IWICMetadataQueryReader_GetLocation(queryreader, 256, name, &len); - ok(hr == S_OK, "GetLocation error %#x\n", hr); + ok(hr == S_OK, "GetLocation error %#lx\n", hr); ok(len == 2, "expected 2, got %u\n", len); - ok(!lstrcmpW(name, rootW), "expected '/', got %s\n", wine_dbgstr_w(name)); + ok(!lstrcmpW(name, L"/"), "expected '/', got %s\n", wine_dbgstr_w(name)); for (i = 0; i < ARRAY_SIZE(decoder_data); i++) { @@ -1611,21 +2362,21 @@ static void test_metadata_gif(void) MultiByteToWideChar(CP_ACP, 0, decoder_data[i].query, -1, queryW, 256); hr = IWICMetadataQueryReader_GetMetadataByName(queryreader, queryW, NULL); - ok(hr == decoder_data[i].hr, "GetMetadataByName(%s) returned %#x, expected %#x\n", wine_dbgstr_w(queryW), hr, decoder_data[i].hr); + ok(hr == decoder_data[i].hr, "GetMetadataByName(%s) returned %#lx, expected %#lx\n", wine_dbgstr_w(queryW), hr, decoder_data[i].hr); PropVariantInit(&value); hr = IWICMetadataQueryReader_GetMetadataByName(queryreader, queryW, &value); - ok(hr == decoder_data[i].hr, "GetMetadataByName(%s) returned %#x, expected %#x\n", wine_dbgstr_w(queryW), hr, decoder_data[i].hr); + ok(hr == decoder_data[i].hr, "GetMetadataByName(%s) returned %#lx, expected %#lx\n", wine_dbgstr_w(queryW), hr, decoder_data[i].hr); ok(value.vt == decoder_data[i].vt, "expected %#x, got %#x\n", decoder_data[i].vt, value.vt); if (hr == S_OK && value.vt == VT_UNKNOWN) { hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataQueryReader, (void **)&meta_reader); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); name[0] = 0; len = 0xdeadbeef; hr = IWICMetadataQueryReader_GetLocation(meta_reader, 256, name, &len); - ok(hr == S_OK, "GetLocation error %#x\n", hr); + ok(hr == S_OK, "GetLocation error %#lx\n", hr); ok(len == lstrlenW(queryW) + 1, "expected %u, got %u\n", lstrlenW(queryW) + 1, len); ok(!lstrcmpW(name, queryW), "expected %s, got %s\n", wine_dbgstr_w(queryW), wine_dbgstr_w(name)); @@ -1639,7 +2390,7 @@ static void test_metadata_gif(void) trace("query: %s\n", wine_dbgstr_w(queryW + len - 1)); PropVariantClear(&value); hr = IWICMetadataQueryReader_GetMetadataByName(meta_reader, queryW + len - 1, &value); - ok(hr == decoder_data[j].hr, "GetMetadataByName(%s) returned %#x, expected %#x\n", wine_dbgstr_w(queryW + len - 1), hr, decoder_data[j].hr); + ok(hr == decoder_data[j].hr, "GetMetadataByName(%s) returned %#lx, expected %#lx\n", wine_dbgstr_w(queryW + len - 1), hr, decoder_data[j].hr); ok(value.vt == decoder_data[j].vt, "expected %#x, got %#x\n", decoder_data[j].vt, value.vt); } } @@ -1655,7 +2406,7 @@ static void test_metadata_gif(void) hr = IWICBitmapFrameDecode_GetMetadataQueryReader(frame, &queryreader); ok(hr == S_OK || broken(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION) /* before Vista */, - "GetMetadataQueryReader error %#x\n", hr); + "GetMetadataQueryReader error %#lx\n", hr); if (SUCCEEDED(hr)) { static const struct @@ -1684,26 +2435,23 @@ static void test_metadata_gif(void) { "/grctlext/{str=\\delay}", S_OK, VT_UI2 }, { "grctlext/Delay", WINCODEC_ERR_PROPERTYNOTSUPPORTED, 0 }, }; - static const WCHAR rootW[] = {'/',0}; static const WCHAR guidW[] = {'/','{','g','u','i','d','=','\\',0}; - static const WCHAR imgdescW[] = {'i','m','g','d','e','s','c',0}; - static const WCHAR ImgDescW[] = {'I','m','g','D','e','s','c',0}; WCHAR name[256], queryW[256]; UINT len, i; PROPVARIANT value; IWICMetadataQueryReader *meta_reader; hr = IWICMetadataQueryReader_GetContainerFormat(queryreader, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatGif), "wrong container format %s\n", wine_dbgstr_guid(&format)); name[0] = 0; len = 0xdeadbeef; hr = IWICMetadataQueryReader_GetLocation(queryreader, 256, name, &len); - ok(hr == S_OK, "GetLocation error %#x\n", hr); + ok(hr == S_OK, "GetLocation error %#lx\n", hr); ok(len == 2, "expected 2, got %u\n", len); - ok(!lstrcmpW(name, rootW), "expected '/', got %s\n", wine_dbgstr_w(name)); + ok(!lstrcmpW(name, L"/"), "expected '/', got %s\n", wine_dbgstr_w(name)); for (i = 0; i < ARRAY_SIZE(frame_data); i++) { @@ -1712,17 +2460,17 @@ static void test_metadata_gif(void) MultiByteToWideChar(CP_ACP, 0, frame_data[i].query, -1, queryW, 256); PropVariantInit(&value); hr = IWICMetadataQueryReader_GetMetadataByName(queryreader, queryW, &value); - ok(hr == frame_data[i].hr, "GetMetadataByName(%s) returned %#x, expected %#x\n", wine_dbgstr_w(queryW), hr, frame_data[i].hr); + ok(hr == frame_data[i].hr, "GetMetadataByName(%s) returned %#lx, expected %#lx\n", wine_dbgstr_w(queryW), hr, frame_data[i].hr); ok(value.vt == frame_data[i].vt, "expected %#x, got %#x\n", frame_data[i].vt, value.vt); if (hr == S_OK && value.vt == VT_UNKNOWN) { hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataQueryReader, (void **)&meta_reader); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); name[0] = 0; len = 0xdeadbeef; hr = IWICMetadataQueryReader_GetLocation(meta_reader, 256, name, &len); - ok(hr == S_OK, "GetLocation error %#x\n", hr); + ok(hr == S_OK, "GetLocation error %#lx\n", hr); ok(len == lstrlenW(queryW) + 1, "expected %u, got %u\n", lstrlenW(queryW) + 1, len); ok(!lstrcmpW(name, queryW), "expected %s, got %s\n", wine_dbgstr_w(queryW), wine_dbgstr_w(name)); @@ -1735,17 +2483,17 @@ static void test_metadata_gif(void) name[0] = 0; len = 0xdeadbeef; hr = WICMapGuidToShortName(&GUID_MetadataFormatIMD, 256, name, &len); - ok(hr == S_OK, "WICMapGuidToShortName error %#x\n", hr); - ok(!lstrcmpW(name, imgdescW), "wrong short name %s\n", wine_dbgstr_w(name)); + ok(hr == S_OK, "WICMapGuidToShortName error %#lx\n", hr); + ok(!lstrcmpW(name, L"imgdesc"), "wrong short name %s\n", wine_dbgstr_w(name)); format = GUID_NULL; - hr = WICMapShortNameToGuid(imgdescW, &format); - ok(hr == S_OK, "WICMapGuidToShortName error %#x\n", hr); + hr = WICMapShortNameToGuid(L"imgdesc", &format); + ok(hr == S_OK, "WICMapGuidToShortName error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatIMD), "wrong guid %s\n", wine_dbgstr_guid(&format)); format = GUID_NULL; - hr = WICMapShortNameToGuid(ImgDescW, &format); - ok(hr == S_OK, "WICMapGuidToShortName error %#x\n", hr); + hr = WICMapShortNameToGuid(L"ImgDesc", &format); + ok(hr == S_OK, "WICMapGuidToShortName error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_MetadataFormatIMD), "wrong guid %s\n", wine_dbgstr_guid(&format)); lstrcpyW(queryW, guidW); @@ -1755,7 +2503,7 @@ static void test_metadata_gif(void) trace("query: %s\n", wine_dbgstr_w(queryW)); PropVariantInit(&value); hr = IWICMetadataQueryReader_GetMetadataByName(queryreader, queryW, &value); - ok(hr == S_OK, "GetMetadataByName(%s) error %#x\n", wine_dbgstr_w(queryW), hr); + ok(hr == S_OK, "GetMetadataByName(%s) error %#lx\n", wine_dbgstr_w(queryW), hr); ok(value.vt == VT_UNKNOWN, "expected VT_UNKNOWN, got %#x\n", value.vt); PropVariantClear(&value); @@ -1768,25 +2516,25 @@ static void test_metadata_gif(void) static void test_metadata_LSD(void) { - static const WCHAR LSD_name[] = {'L','o','g','i','c','a','l',' ','S','c','r','e','e','n',' ','D','e','s','c','r','i','p','t','o','r',' ','R','e','a','d','e','r',0}; static const char LSD_data[] = "hello world!\x1\x2\x3\x4\xab\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf"; static const struct test_data td[9] = { - { VT_UI1|VT_VECTOR, 0, 6, {'w','o','r','l','d','!'}, NULL, { 'S','i','g','n','a','t','u','r','e',0 } }, - { VT_UI2, 0, 0, { 0x201 }, NULL, { 'W','i','d','t','h',0 } }, - { VT_UI2, 0, 0, { 0x403 }, NULL, { 'H','e','i','g','h','t',0 } }, - { VT_BOOL, 0, 0, { 1 }, NULL, { 'G','l','o','b','a','l','C','o','l','o','r','T','a','b','l','e','F','l','a','g',0 } }, - { VT_UI1, 0, 0, { 2 }, NULL, { 'C','o','l','o','r','R','e','s','o','l','u','t','i','o','n',0 } }, - { VT_BOOL, 0, 0, { 1 }, NULL, { 'S','o','r','t','F','l','a','g',0 } }, - { VT_UI1, 0, 0, { 3 }, NULL, { 'G','l','o','b','a','l','C','o','l','o','r','T','a','b','l','e','S','i','z','e',0 } }, - { VT_UI1, 0, 0, { 6 }, NULL, { 'B','a','c','k','g','r','o','u','n','d','C','o','l','o','r','I','n','d','e','x',0 } }, - { VT_UI1, 0, 0, { 7 }, NULL, { 'P','i','x','e','l','A','s','p','e','c','t','R','a','t','i','o',0 } } + { VT_UI1|VT_VECTOR, 0, 6, {'w','o','r','l','d','!'}, NULL, L"Signature" }, + { VT_UI2, 0, 0, { 0x201 }, NULL, L"Width" }, + { VT_UI2, 0, 0, { 0x403 }, NULL, L"Height" }, + { VT_BOOL, 0, 0, { 1 }, NULL, L"GlobalColorTableFlag" }, + { VT_UI1, 0, 0, { 2 }, NULL, L"ColorResolution" }, + { VT_BOOL, 0, 0, { 1 }, NULL, L"SortFlag" }, + { VT_UI1, 0, 0, { 3 }, NULL, L"GlobalColorTableSize" }, + { VT_UI1, 0, 0, { 6 }, NULL, L"BackgroundColorIndex" }, + { VT_UI1, 0, 0, { 7 }, NULL, L"PixelAspectRatio" } }; LARGE_INTEGER pos; HRESULT hr; IStream *stream; IWICPersistStream *persist; IWICMetadataReader *reader; + IWICMetadataWriter *writer; IWICMetadataHandlerInfo *info; WCHAR name[64]; UINT count, dummy; @@ -1796,75 +2544,98 @@ static void test_metadata_LSD(void) hr = CoCreateInstance(&CLSID_WICLSDMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void **)&reader); ok(hr == S_OK || broken(hr == E_NOINTERFACE || hr == REGDB_E_CLASSNOTREG) /* before Win7 */, - "CoCreateInstance error %#x\n", hr); + "CoCreateInstance error %#lx\n", hr); + if (FAILED(hr)) return; + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); stream = create_stream(LSD_data, sizeof(LSD_data)); - if (SUCCEEDED(hr)) - { - pos.QuadPart = 6; - hr = IStream_Seek(stream, pos, SEEK_SET, NULL); - ok(hr == S_OK, "IStream_Seek error %#x\n", hr); + test_reader_container_format(reader, &GUID_ContainerFormatGif); - hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + pos.QuadPart = 6; + hr = IStream_Seek(stream, pos, SEEK_SET, NULL); + ok(hr == S_OK, "IStream_Seek error %#lx\n", hr); - hr = IWICPersistStream_Load(persist, stream); - ok(hr == S_OK, "Load error %#x\n", hr); + hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); - IWICPersistStream_Release(persist); - } + hr = IWICPersistStream_Load(persist, stream); + ok(hr == S_OK, "Load error %#lx\n", hr); + todo_wine + check_persist_options(reader, 0); - if (SUCCEEDED(hr)) - { - hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); - ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); + IWICPersistStream_Release(persist); - compare_metadata(reader, td, count); + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "GetCount error %#lx\n", hr); + ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); - hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat error %#x\n", hr); - ok(IsEqualGUID(&format, &GUID_MetadataFormatLSD), "wrong format %s\n", wine_dbgstr_guid(&format)); + compare_metadata(reader, td, count); - hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); - ok(hr == S_OK, "GetMetadataHandlerInfo error %#x\n", hr); + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "GetMetadataFormat error %#lx\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatLSD), "wrong format %s\n", wine_dbgstr_guid(&format)); - hr = IWICMetadataHandlerInfo_GetCLSID(info, &id); - ok(hr == S_OK, "GetCLSID error %#x\n", hr); - ok(IsEqualGUID(&id, &CLSID_WICLSDMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&id)); + hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); + ok(hr == S_OK, "GetMetadataHandlerInfo error %#lx\n", hr); - hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy); - ok(hr == S_OK, "GetFriendlyName error %#x\n", hr); - ok(lstrcmpW(name, LSD_name) == 0, "wrong LSD reader name %s\n", wine_dbgstr_w(name)); + hr = IWICMetadataHandlerInfo_GetCLSID(info, &id); + ok(hr == S_OK, "GetCLSID error %#lx\n", hr); + ok(IsEqualGUID(&id, &CLSID_WICLSDMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&id)); - IWICMetadataHandlerInfo_Release(info); - IWICMetadataReader_Release(reader); - } + hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy); + ok(hr == S_OK, "GetFriendlyName error %#lx\n", hr); + ok(!lstrcmpW(name, L"Logical Screen Descriptor Reader"), "wrong LSD reader name %s\n", wine_dbgstr_w(name)); + + IWICMetadataHandlerInfo_Release(info); + IWICMetadataReader_Release(reader); IStream_Release(stream); + + hr = CoCreateInstance(&CLSID_WICLSDMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, LSD_data, sizeof(LSD_data), 0); + load_stream(writer, LSD_data, sizeof(LSD_data), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } static void test_metadata_IMD(void) { - static const WCHAR IMD_name[] = {'I','m','a','g','e',' ','D','e','s','c','r','i','p','t','o','r',' ','R','e','a','d','e','r',0}; static const char IMD_data[] = "hello world!\x1\x2\x3\x4\x5\x6\x7\x8\xed\xa\xb\xc\xd\xe\xf"; static const struct test_data td[8] = { - { VT_UI2, 0, 0, { 0x201 }, NULL, { 'L','e','f','t',0 } }, - { VT_UI2, 0, 0, { 0x403 }, NULL, { 'T','o','p',0 } }, - { VT_UI2, 0, 0, { 0x605 }, NULL, { 'W','i','d','t','h',0 } }, - { VT_UI2, 0, 0, { 0x807 }, NULL, { 'H','e','i','g','h','t',0 } }, - { VT_BOOL, 0, 0, { 1 }, NULL, { 'L','o','c','a','l','C','o','l','o','r','T','a','b','l','e','F','l','a','g',0 } }, - { VT_BOOL, 0, 0, { 1 }, NULL, { 'I','n','t','e','r','l','a','c','e','F','l','a','g',0 } }, - { VT_BOOL, 0, 0, { 1 }, NULL, { 'S','o','r','t','F','l','a','g',0 } }, - { VT_UI1, 0, 0, { 5 }, NULL, { 'L','o','c','a','l','C','o','l','o','r','T','a','b','l','e','S','i','z','e',0 } } + { VT_UI2, 0, 0, { 0x201 }, NULL, L"Left" }, + { VT_UI2, 0, 0, { 0x403 }, NULL, L"Top" }, + { VT_UI2, 0, 0, { 0x605 }, NULL, L"Width" }, + { VT_UI2, 0, 0, { 0x807 }, NULL, L"Height" }, + { VT_BOOL, 0, 0, { 1 }, NULL, L"LocalColorTableFlag" }, + { VT_BOOL, 0, 0, { 1 }, NULL, L"InterlaceFlag" }, + { VT_BOOL, 0, 0, { 1 }, NULL, L"SortFlag" }, + { VT_UI1, 0, 0, { 5 }, NULL, L"LocalColorTableSize" } }; LARGE_INTEGER pos; HRESULT hr; IStream *stream; IWICPersistStream *persist; IWICMetadataReader *reader; + IWICMetadataWriter *writer; IWICMetadataHandlerInfo *info; WCHAR name[64]; UINT count, dummy; @@ -1874,72 +2645,95 @@ static void test_metadata_IMD(void) hr = CoCreateInstance(&CLSID_WICIMDMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void **)&reader); ok(hr == S_OK || broken(hr == E_NOINTERFACE || hr == REGDB_E_CLASSNOTREG) /* before Win7 */, - "CoCreateInstance error %#x\n", hr); + "CoCreateInstance error %#lx\n", hr); + if (FAILED(hr)) return; + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + + test_reader_container_format(reader, &GUID_ContainerFormatGif); stream = create_stream(IMD_data, sizeof(IMD_data)); - if (SUCCEEDED(hr)) - { - pos.QuadPart = 12; - hr = IStream_Seek(stream, pos, SEEK_SET, NULL); - ok(hr == S_OK, "IStream_Seek error %#x\n", hr); + pos.QuadPart = 12; + hr = IStream_Seek(stream, pos, SEEK_SET, NULL); + ok(hr == S_OK, "IStream_Seek error %#lx\n", hr); - hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); - hr = IWICPersistStream_Load(persist, stream); - ok(hr == S_OK, "Load error %#x\n", hr); + hr = IWICPersistStream_Load(persist, stream); + ok(hr == S_OK, "Load error %#lx\n", hr); + todo_wine + check_persist_options(reader, 0); - IWICPersistStream_Release(persist); - } + IWICPersistStream_Release(persist); - if (SUCCEEDED(hr)) - { - hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); - ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "GetCount error %#lx\n", hr); + ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); - compare_metadata(reader, td, count); + compare_metadata(reader, td, count); - hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat error %#x\n", hr); - ok(IsEqualGUID(&format, &GUID_MetadataFormatIMD), "wrong format %s\n", wine_dbgstr_guid(&format)); + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "GetMetadataFormat error %#lx\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatIMD), "wrong format %s\n", wine_dbgstr_guid(&format)); - hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); - ok(hr == S_OK, "GetMetadataHandlerInfo error %#x\n", hr); + hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); + ok(hr == S_OK, "GetMetadataHandlerInfo error %#lx\n", hr); - hr = IWICMetadataHandlerInfo_GetCLSID(info, &id); - ok(hr == S_OK, "GetCLSID error %#x\n", hr); - ok(IsEqualGUID(&id, &CLSID_WICIMDMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&id)); + hr = IWICMetadataHandlerInfo_GetCLSID(info, &id); + ok(hr == S_OK, "GetCLSID error %#lx\n", hr); + ok(IsEqualGUID(&id, &CLSID_WICIMDMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&id)); - hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy); - ok(hr == S_OK, "GetFriendlyName error %#x\n", hr); - ok(lstrcmpW(name, IMD_name) == 0, "wrong IMD reader name %s\n", wine_dbgstr_w(name)); + hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy); + ok(hr == S_OK, "GetFriendlyName error %#lx\n", hr); + ok(!lstrcmpW(name, L"Image Descriptor Reader"), "wrong IMD reader name %s\n", wine_dbgstr_w(name)); - IWICMetadataHandlerInfo_Release(info); - IWICMetadataReader_Release(reader); - } + IWICMetadataHandlerInfo_Release(info); + IWICMetadataReader_Release(reader); IStream_Release(stream); + + hr = CoCreateInstance(&CLSID_WICIMDMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, IMD_data, sizeof(IMD_data), 0); + load_stream(writer, IMD_data, sizeof(IMD_data), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } static void test_metadata_GCE(void) { - static const WCHAR GCE_name[] = {'G','r','a','p','h','i','c',' ','C','o','n','t','r','o','l',' ','E','x','t','e','n','s','i','o','n',' ','R','e','a','d','e','r',0}; static const char GCE_data[] = "hello world!\xa\x2\x3\x4\x5\x6\x7\x8\xed\xa\xb\xc\xd\xe\xf"; static const struct test_data td[5] = { - { VT_UI1, 0, 0, { 2 }, NULL, { 'D','i','s','p','o','s','a','l',0 } }, - { VT_BOOL, 0, 0, { 1 }, NULL, { 'U','s','e','r','I','n','p','u','t','F','l','a','g',0 } }, - { VT_BOOL, 0, 0, { 0 }, NULL, { 'T','r','a','n','s','p','a','r','e','n','c','y','F','l','a','g',0 } }, - { VT_UI2, 0, 0, { 0x302 }, NULL, { 'D','e','l','a','y',0 } }, - { VT_UI1, 0, 0, { 4 }, NULL, { 'T','r','a','n','s','p','a','r','e','n','t','C','o','l','o','r','I','n','d','e','x',0 } } + { VT_UI1, 0, 0, { 2 }, NULL, L"Disposal" }, + { VT_BOOL, 0, 0, { 1 }, NULL, L"UserInputFlag" }, + { VT_BOOL, 0, 0, { 0 }, NULL, L"TransparencyFlag" }, + { VT_UI2, 0, 0, { 0x302 }, NULL, L"Delay" }, + { VT_UI1, 0, 0, { 4 }, NULL, L"TransparentColorIndex" } }; LARGE_INTEGER pos; HRESULT hr; IStream *stream; IWICPersistStream *persist; IWICMetadataReader *reader; + IWICMetadataWriter *writer; IWICMetadataHandlerInfo *info; WCHAR name[64]; UINT count, dummy; @@ -1949,58 +2743,80 @@ static void test_metadata_GCE(void) hr = CoCreateInstance(&CLSID_WICGCEMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void **)&reader); ok(hr == S_OK || broken(hr == E_NOINTERFACE || hr == REGDB_E_CLASSNOTREG) /* before Win7 */, - "CoCreateInstance error %#x\n", hr); + "CoCreateInstance error %#lx\n", hr); + if (FAILED(hr)) return; + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + + test_reader_container_format(reader, &GUID_ContainerFormatGif); stream = create_stream(GCE_data, sizeof(GCE_data)); - if (SUCCEEDED(hr)) - { - pos.QuadPart = 12; - hr = IStream_Seek(stream, pos, SEEK_SET, NULL); - ok(hr == S_OK, "IStream_Seek error %#x\n", hr); + pos.QuadPart = 12; + hr = IStream_Seek(stream, pos, SEEK_SET, NULL); + ok(hr == S_OK, "IStream_Seek error %#lx\n", hr); - hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); - hr = IWICPersistStream_Load(persist, stream); - ok(hr == S_OK, "Load error %#x\n", hr); + hr = IWICPersistStream_Load(persist, stream); + ok(hr == S_OK, "Load error %#lx\n", hr); + todo_wine + check_persist_options(reader, 0); - IWICPersistStream_Release(persist); - } + IWICPersistStream_Release(persist); - if (SUCCEEDED(hr)) - { - hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); - ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "GetCount error %#lx\n", hr); + ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); - compare_metadata(reader, td, count); + compare_metadata(reader, td, count); - hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat error %#x\n", hr); - ok(IsEqualGUID(&format, &GUID_MetadataFormatGCE), "wrong format %s\n", wine_dbgstr_guid(&format)); + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "GetMetadataFormat error %#lx\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatGCE), "wrong format %s\n", wine_dbgstr_guid(&format)); - hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); - ok(hr == S_OK, "GetMetadataHandlerInfo error %#x\n", hr); + hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); + ok(hr == S_OK, "GetMetadataHandlerInfo error %#lx\n", hr); - hr = IWICMetadataHandlerInfo_GetCLSID(info, &id); - ok(hr == S_OK, "GetCLSID error %#x\n", hr); - ok(IsEqualGUID(&id, &CLSID_WICGCEMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&id)); + hr = IWICMetadataHandlerInfo_GetCLSID(info, &id); + ok(hr == S_OK, "GetCLSID error %#lx\n", hr); + ok(IsEqualGUID(&id, &CLSID_WICGCEMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&id)); - hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy); - ok(hr == S_OK, "GetFriendlyName error %#x\n", hr); - ok(lstrcmpW(name, GCE_name) == 0, "wrong GCE reader name %s\n", wine_dbgstr_w(name)); + hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy); + ok(hr == S_OK, "GetFriendlyName error %#lx\n", hr); + ok(!lstrcmpW(name, L"Graphic Control Extension Reader"), "wrong GCE reader name %s\n", wine_dbgstr_w(name)); - IWICMetadataHandlerInfo_Release(info); - IWICMetadataReader_Release(reader); - } + IWICMetadataHandlerInfo_Release(info); + IWICMetadataReader_Release(reader); IStream_Release(stream); + + hr = CoCreateInstance(&CLSID_WICGCEMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, GCE_data, sizeof(GCE_data), 0); + load_stream(writer, GCE_data, sizeof(GCE_data), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } static void test_metadata_APE(void) { - static const WCHAR APE_name[] = {'A','p','p','l','i','c','a','t','i','o','n',' ','E','x','t','e','n','s','i','o','n',' ','R','e','a','d','e','r',0}; static const char APE_data[] = { 0x21,0xff,0x0b,'H','e','l','l','o',' ','W','o','r','l','d', /*sub-block*/1,0x11, /*sub-block*/2,0x22,0x33, @@ -2008,14 +2824,15 @@ static void test_metadata_APE(void) /*terminator*/0 }; static const struct test_data td[2] = { - { VT_UI1|VT_VECTOR, 0, 11, { 'H','e','l','l','o',' ','W','o','r','l','d' }, NULL, { 'A','p','p','l','i','c','a','t','i','o','n',0 } }, - { VT_UI1|VT_VECTOR, 0, 10, { 1,0x11,2,0x22,0x33,4,0x44,0x55,0x66,0x77 }, NULL, { 'D','a','t','a',0 } } + { VT_UI1|VT_VECTOR, 0, 11, { 'H','e','l','l','o',' ','W','o','r','l','d' }, NULL, L"Application" }, + { VT_UI1|VT_VECTOR, 0, 10, { 1,0x11,2,0x22,0x33,4,0x44,0x55,0x66,0x77 }, NULL, L"Data" } }; WCHAR dataW[] = { 'd','a','t','a',0 }; HRESULT hr; IStream *stream; IWICPersistStream *persist; IWICMetadataReader *reader; + IWICMetadataWriter *writer; IWICMetadataHandlerInfo *info; WCHAR name[64]; UINT count, dummy, i; @@ -2026,66 +2843,88 @@ static void test_metadata_APE(void) hr = CoCreateInstance(&CLSID_WICAPEMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void **)&reader); ok(hr == S_OK || broken(hr == E_NOINTERFACE || hr == REGDB_E_CLASSNOTREG) /* before Win7 */, - "CoCreateInstance error %#x\n", hr); + "CoCreateInstance error %#lx\n", hr); + if (FAILED(hr)) return; + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + + test_reader_container_format(reader, &GUID_ContainerFormatGif); stream = create_stream(APE_data, sizeof(APE_data)); - if (SUCCEEDED(hr)) - { - hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); - hr = IWICPersistStream_Load(persist, stream); - ok(hr == S_OK, "Load error %#x\n", hr); + hr = IWICPersistStream_Load(persist, stream); + ok(hr == S_OK, "Load error %#lx\n", hr); + todo_wine + check_persist_options(reader, 0); - IWICPersistStream_Release(persist); - } + IWICPersistStream_Release(persist); - if (SUCCEEDED(hr)) - { - hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); - ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "GetCount error %#lx\n", hr); + ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); - compare_metadata(reader, td, count); + compare_metadata(reader, td, count); - hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat error %#x\n", hr); - ok(IsEqualGUID(&format, &GUID_MetadataFormatAPE), "wrong format %s\n", wine_dbgstr_guid(&format)); + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "GetMetadataFormat error %#lx\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatAPE), "wrong format %s\n", wine_dbgstr_guid(&format)); - PropVariantInit(&value); - id.vt = VT_LPWSTR; - U(id).pwszVal = dataW; + PropVariantInit(&value); + id.vt = VT_LPWSTR; + id.pwszVal = dataW; - hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value); - ok(hr == S_OK, "GetValue error %#x\n", hr); - ok(value.vt == (VT_UI1|VT_VECTOR), "unexpected vt: %i\n", id.vt); - ok(td[1].count == U(value).caub.cElems, "expected cElems %d, got %d\n", td[1].count, U(value).caub.cElems); - for (i = 0; i < U(value).caub.cElems; i++) - ok(td[1].value[i] == U(value).caub.pElems[i], "%u: expected value %#x/%#x, got %#x\n", i, (ULONG)td[1].value[i], (ULONG)(td[1].value[i] >> 32), U(value).caub.pElems[i]); - PropVariantClear(&value); + hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value); + ok(hr == S_OK, "GetValue error %#lx\n", hr); + ok(value.vt == (VT_UI1|VT_VECTOR), "unexpected vt: %i\n", id.vt); + ok(td[1].count == value.caub.cElems, "expected cElems %d, got %ld\n", td[1].count, value.caub.cElems); + for (i = 0; i < value.caub.cElems; i++) + ok(td[1].value[i] == value.caub.pElems[i], "%u: expected value %#I64x, got %#x\n", i, td[1].value[i], value.caub.pElems[i]); + PropVariantClear(&value); - hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); - ok(hr == S_OK, "GetMetadataHandlerInfo error %#x\n", hr); + hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); + ok(hr == S_OK, "GetMetadataHandlerInfo error %#lx\n", hr); - hr = IWICMetadataHandlerInfo_GetCLSID(info, &clsid); - ok(hr == S_OK, "GetCLSID error %#x\n", hr); - ok(IsEqualGUID(&clsid, &CLSID_WICAPEMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&clsid)); + hr = IWICMetadataHandlerInfo_GetCLSID(info, &clsid); + ok(hr == S_OK, "GetCLSID error %#lx\n", hr); + ok(IsEqualGUID(&clsid, &CLSID_WICAPEMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&clsid)); - hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy); - ok(hr == S_OK, "GetFriendlyName error %#x\n", hr); - ok(lstrcmpW(name, APE_name) == 0, "wrong APE reader name %s\n", wine_dbgstr_w(name)); + hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy); + ok(hr == S_OK, "GetFriendlyName error %#lx\n", hr); + ok(!lstrcmpW(name, L"Application Extension Reader"), "wrong APE reader name %s\n", wine_dbgstr_w(name)); - IWICMetadataHandlerInfo_Release(info); - IWICMetadataReader_Release(reader); - } + IWICMetadataHandlerInfo_Release(info); + IWICMetadataReader_Release(reader); IStream_Release(stream); + + hr = CoCreateInstance(&CLSID_WICAPEMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, APE_data, sizeof(APE_data), 0); + load_stream(writer, APE_data, sizeof(APE_data), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } static void test_metadata_GIF_comment(void) { - static const WCHAR GIF_comment_name[] = {'C','o','m','m','e','n','t',' ','E','x','t','e','n','s','i','o','n',' ','R','e','a','d','e','r',0}; static const char GIF_comment_data[] = { 0x21,0xfe, /*sub-block*/5,'H','e','l','l','o', /*sub-block*/1,' ', @@ -2093,13 +2932,14 @@ static void test_metadata_GIF_comment(void) /*terminator*/0 }; static const struct test_data td[1] = { - { VT_LPSTR, 0, 12, { 0 }, "Hello World!", { 'T','e','x','t','E','n','t','r','y',0 } } + { VT_LPSTR, 0, 12, { 0 }, "Hello World!", L"TextEntry" } }; - WCHAR text_entryW[] = { 'T','E','X','T','E','N','T','R','Y',0 }; + WCHAR text_entryW[] = L"TEXTENTRY"; HRESULT hr; IStream *stream; IWICPersistStream *persist; IWICMetadataReader *reader; + IWICMetadataWriter *writer; IWICMetadataHandlerInfo *info; WCHAR name[64]; UINT count, dummy; @@ -2110,65 +2950,86 @@ static void test_metadata_GIF_comment(void) hr = CoCreateInstance(&CLSID_WICGifCommentMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void **)&reader); ok(hr == S_OK || broken(hr == E_NOINTERFACE || hr == REGDB_E_CLASSNOTREG) /* before Win7 */, - "CoCreateInstance error %#x\n", hr); + "CoCreateInstance error %#lx\n", hr); + if (FAILED(hr)) return; + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + + test_reader_container_format(reader, &GUID_ContainerFormatGif); stream = create_stream(GIF_comment_data, sizeof(GIF_comment_data)); - if (SUCCEEDED(hr)) - { - hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void **)&persist); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); - hr = IWICPersistStream_Load(persist, stream); - ok(hr == S_OK, "Load error %#x\n", hr); + hr = IWICPersistStream_Load(persist, stream); + ok(hr == S_OK, "Load error %#lx\n", hr); + todo_wine + check_persist_options(reader, 0); - IWICPersistStream_Release(persist); - } + IWICPersistStream_Release(persist); - if (SUCCEEDED(hr)) - { - hr = IWICMetadataReader_GetCount(reader, &count); - ok(hr == S_OK, "GetCount error %#x\n", hr); - ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "GetCount error %#lx\n", hr); + ok(count == ARRAY_SIZE(td), "unexpected count %u\n", count); - compare_metadata(reader, td, count); + compare_metadata(reader, td, count); - hr = IWICMetadataReader_GetMetadataFormat(reader, &format); - ok(hr == S_OK, "GetMetadataFormat error %#x\n", hr); - ok(IsEqualGUID(&format, &GUID_MetadataFormatGifComment), "wrong format %s\n", wine_dbgstr_guid(&format)); + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "GetMetadataFormat error %#lx\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatGifComment), "wrong format %s\n", wine_dbgstr_guid(&format)); - PropVariantInit(&value); - id.vt = VT_LPWSTR; - U(id).pwszVal = text_entryW; + PropVariantInit(&value); + id.vt = VT_LPWSTR; + id.pwszVal = text_entryW; - hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value); - ok(hr == S_OK, "GetValue error %#x\n", hr); - ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt); - ok(!strcmp(U(value).pszVal, "Hello World!"), "unexpected value: %s\n", U(value).pszVal); - PropVariantClear(&value); + hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value); + ok(hr == S_OK, "GetValue error %#lx\n", hr); + ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt); + ok(!strcmp(value.pszVal, "Hello World!"), "unexpected value: %s\n", value.pszVal); + PropVariantClear(&value); - hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); - ok(hr == S_OK, "GetMetadataHandlerInfo error %#x\n", hr); + hr = IWICMetadataReader_GetMetadataHandlerInfo(reader, &info); + ok(hr == S_OK, "GetMetadataHandlerInfo error %#lx\n", hr); - hr = IWICMetadataHandlerInfo_GetCLSID(info, &clsid); - ok(hr == S_OK, "GetCLSID error %#x\n", hr); - ok(IsEqualGUID(&clsid, &CLSID_WICGifCommentMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&clsid)); + hr = IWICMetadataHandlerInfo_GetCLSID(info, &clsid); + ok(hr == S_OK, "GetCLSID error %#lx\n", hr); + ok(IsEqualGUID(&clsid, &CLSID_WICGifCommentMetadataReader), "wrong CLSID %s\n", wine_dbgstr_guid(&clsid)); - hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy); - ok(hr == S_OK, "GetFriendlyName error %#x\n", hr); - ok(lstrcmpW(name, GIF_comment_name) == 0, "wrong APE reader name %s\n", wine_dbgstr_w(name)); + hr = IWICMetadataHandlerInfo_GetFriendlyName(info, 64, name, &dummy); + ok(hr == S_OK, "GetFriendlyName error %#lx\n", hr); + ok(!lstrcmpW(name, L"Comment Extension Reader"), "wrong APE reader name %s\n", wine_dbgstr_w(name)); - IWICMetadataHandlerInfo_Release(info); - IWICMetadataReader_Release(reader); - } + IWICMetadataHandlerInfo_Release(info); + IWICMetadataReader_Release(reader); IStream_Release(stream); + + hr = CoCreateInstance(&CLSID_WICGifCommentMetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + load_stream(writer, GIF_comment_data, sizeof(GIF_comment_data), 0); + load_stream(writer, GIF_comment_data, sizeof(GIF_comment_data), WICPersistOptionNoCacheStream); + + IWICMetadataWriter_Release(writer); } static void test_WICMapGuidToShortName(void) { - static const WCHAR unkW[] = { 'u','n','k',0 }; - static const WCHAR unknownW[] = { 'u','n','k','n','o','w','n',0 }; HRESULT hr; UINT len; WCHAR name[16]; @@ -2176,84 +3037,80 @@ static void test_WICMapGuidToShortName(void) name[0] = 0; len = 0xdeadbeef; hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 8, name, &len); - ok(hr == S_OK, "got %#x\n", hr); + ok(hr == S_OK, "got %#lx\n", hr); ok(len == 8, "got %u\n", len); - ok(!lstrcmpW(name, unknownW), "got %s\n", wine_dbgstr_w(name)); + ok(!lstrcmpW(name, L"unknown"), "got %s\n", wine_dbgstr_w(name)); name[0] = 0; hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 8, name, NULL); - ok(hr == S_OK, "got %#x\n", hr); - ok(!lstrcmpW(name, unknownW), "got %s\n", wine_dbgstr_w(name)); + ok(hr == S_OK, "got %#lx\n", hr); + ok(!lstrcmpW(name, L"unknown"), "got %s\n", wine_dbgstr_w(name)); len = 0xdeadbeef; hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 8, NULL, &len); - ok(hr == S_OK, "got %#x\n", hr); + ok(hr == S_OK, "got %#lx\n", hr); ok(len == 8, "got %u\n", len); len = 0xdeadbeef; hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 0, NULL, &len); - ok(hr == S_OK, "got %#x\n", hr); + ok(hr == S_OK, "got %#lx\n", hr); ok(len == 8, "got %u\n", len); hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 0, NULL, NULL); - ok(hr == S_OK, "got %#x\n", hr); + ok(hr == S_OK, "got %#lx\n", hr); hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 8, NULL, NULL); - ok(hr == S_OK, "got %#x\n", hr); + ok(hr == S_OK, "got %#lx\n", hr); hr = WICMapGuidToShortName(&GUID_NULL, 0, NULL, NULL); - ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "got %#x\n", hr); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "got %#lx\n", hr); name[0] = 0; len = 0xdeadbeef; hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 4, name, &len); - ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "got %#x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "got %#lx\n", hr); ok(len == 0xdeadbeef, "got %u\n", len); - ok(!lstrcmpW(name, unkW), "got %s\n", wine_dbgstr_w(name)); + ok(!lstrcmpW(name, L"unk"), "got %s\n", wine_dbgstr_w(name)); name[0] = 0; len = 0xdeadbeef; hr = WICMapGuidToShortName(&GUID_MetadataFormatUnknown, 0, name, &len); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); ok(len == 0xdeadbeef, "got %u\n", len); ok(!name[0], "got %s\n", wine_dbgstr_w(name)); hr = WICMapGuidToShortName(NULL, 8, name, NULL); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); } static void test_WICMapShortNameToGuid(void) { - static const WCHAR unkW[] = { 'u','n','k',0 }; - static const WCHAR xmpW[] = { 'x','m','p',0 }; - static const WCHAR XmPW[] = { 'X','m','P',0 }; - static const WCHAR unknownW[] = { 'u','n','k','n','o','w','n',0 }; HRESULT hr; GUID guid; hr = WICMapShortNameToGuid(NULL, NULL); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); hr = WICMapShortNameToGuid(NULL, &guid); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); - hr = WICMapShortNameToGuid(unknownW, NULL); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + hr = WICMapShortNameToGuid(L"unknown", NULL); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); - hr = WICMapShortNameToGuid(unkW, &guid); - ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "got %#x\n", hr); + hr = WICMapShortNameToGuid(L"unk", &guid); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "got %#lx\n", hr); - hr = WICMapShortNameToGuid(unknownW, &guid); - ok(hr == S_OK, "got %#x\n", hr); + hr = WICMapShortNameToGuid(L"unknown", &guid); + ok(hr == S_OK, "got %#lx\n", hr); ok(IsEqualGUID(&guid, &GUID_MetadataFormatUnknown), "got %s\n", wine_dbgstr_guid(&guid)); - hr = WICMapShortNameToGuid(xmpW, &guid); - ok(hr == S_OK, "got %#x\n", hr); + hr = WICMapShortNameToGuid(L"xmp", &guid); + ok(hr == S_OK, "got %#lx\n", hr); ok(IsEqualGUID(&guid, &GUID_MetadataFormatXMP), "got %s\n", wine_dbgstr_guid(&guid)); guid = GUID_NULL; - hr = WICMapShortNameToGuid(XmPW, &guid); - ok(hr == S_OK, "got %#x\n", hr); + hr = WICMapShortNameToGuid(L"XmP", &guid); + ok(hr == S_OK, "got %#lx\n", hr); ok(IsEqualGUID(&guid, &GUID_MetadataFormatXMP), "got %s\n", wine_dbgstr_guid(&guid)); } @@ -2364,65 +3221,63 @@ static WCHAR *schema_list[] = static void test_WICMapSchemaToName(void) { - static const WCHAR xmW[] = { 'x','m',0 }; - static const WCHAR xmpW[] = { 'x','m','p',0 }; - static WCHAR schemaW[] = { 'h','t','t','p',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/',0 }; - static WCHAR SCHEMAW[] = { 'H','T','T','P',':','/','/','n','s','.','a','d','o','b','e','.','c','o','m','/','x','a','p','/','1','.','0','/',0 }; + static WCHAR schemaW[] = L"http://ns.adobe.com/xap/1.0/"; + static WCHAR SCHEMAW[] = L"HTTP://ns.adobe.com/xap/1.0/"; HRESULT hr; UINT len, i, j; WCHAR name[16]; hr = WICMapSchemaToName(&GUID_MetadataFormatUnknown, NULL, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); hr = WICMapSchemaToName(&GUID_MetadataFormatUnknown, schemaW, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); hr = WICMapSchemaToName(&GUID_MetadataFormatUnknown, schemaW, 0, NULL, &len); - ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "got %#x\n", hr); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "got %#lx\n", hr); hr = WICMapSchemaToName(NULL, schemaW, 0, NULL, &len); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schemaW, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); len = 0xdeadbeef; hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schemaW, 0, NULL, &len); - ok(hr == S_OK, "got %#x\n", hr); + ok(hr == S_OK, "got %#lx\n", hr); ok(len == 4, "got %u\n", len); len = 0xdeadbeef; hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schemaW, 4, NULL, &len); - ok(hr == S_OK, "got %#x\n", hr); + ok(hr == S_OK, "got %#lx\n", hr); ok(len == 4, "got %u\n", len); len = 0xdeadbeef; hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, SCHEMAW, 0, NULL, &len); - ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "got %#x\n", hr); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "got %#lx\n", hr); ok(len == 0xdeadbeef, "got %u\n", len); name[0] = 0; len = 0xdeadbeef; hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schemaW, 4, name, &len); - ok(hr == S_OK, "got %#x\n", hr); + ok(hr == S_OK, "got %#lx\n", hr); ok(len == 4, "got %u\n", len); - ok(!lstrcmpW(name, xmpW), "got %s\n", wine_dbgstr_w(name)); + ok(!lstrcmpW(name, L"xmp"), "got %s\n", wine_dbgstr_w(name)); len = 0xdeadbeef; hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schemaW, 0, name, &len); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); ok(len == 0xdeadbeef, "got %u\n", len); name[0] = 0; len = 0xdeadbeef; hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schemaW, 3, name, &len); - ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "got %#x\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "got %#lx\n", hr); ok(len == 0xdeadbeef, "got %u\n", len); - ok(!lstrcmpW(name, xmW), "got %s\n", wine_dbgstr_w(name)); + ok(!lstrcmpW(name, L"xm"), "got %s\n", wine_dbgstr_w(name)); hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schemaW, 4, name, NULL); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); /* Check whether modern schemas are supported */ hr = WICMapSchemaToName(&GUID_MetadataFormatXMP, schema_list[0], 0, NULL, &len); @@ -2480,8 +3335,6 @@ static char the_worst[] = "The Worst"; static HRESULT WINAPI mdr_QueryInterface(IWICMetadataReader *iface, REFIID iid, void **out) { - trace("%p,%s,%p\n", iface, wine_dbgstr_guid(iid), out); - if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IWICMetadataReader)) { @@ -2507,8 +3360,6 @@ static ULONG WINAPI mdr_Release(IWICMetadataReader *iface) static HRESULT WINAPI mdr_GetMetadataFormat(IWICMetadataReader *iface, GUID *format) { - trace("%p,%p\n", iface, format); - ok(current_metadata_block != NULL, "current_metadata_block can't be NULL\n"); if (!current_metadata_block) return E_POINTER; @@ -2524,8 +3375,6 @@ static HRESULT WINAPI mdr_GetMetadataHandlerInfo(IWICMetadataReader *iface, IWIC static HRESULT WINAPI mdr_GetCount(IWICMetadataReader *iface, UINT *count) { - trace("%p,%p\n", iface, count); - ok(current_metadata_block != NULL, "current_metadata_block can't be NULL\n"); if (!current_metadata_block) return E_POINTER; @@ -2539,46 +3388,6 @@ static HRESULT WINAPI mdr_GetValueByIndex(IWICMetadataReader *iface, UINT index, return E_NOTIMPL; } -static char *get_temp_buffer(int size) -{ - static char buf[16][256]; - static int idx; - char *p; - - assert(size < 256); - - p = buf[idx & 0x0f]; - idx++; - return p; -} - -static const char *wine_dbgstr_propvariant(const PROPVARIANT *var) -{ - char *ret; - - if (!var) return "(null)"; - - switch (var->vt) - { - case VT_LPWSTR: - ret = get_temp_buffer(lstrlenW(U(*var).pwszVal) + 16); - sprintf(ret, "(VT_LPWSTR:%s)", wine_dbgstr_w(U(*var).pwszVal)); - break; - - case VT_LPSTR: - ret = get_temp_buffer(lstrlenA(U(*var).pszVal) + 16); - sprintf(ret, "(VT_LPSTR:%s)", U(*var).pszVal); - break; - - default: - ret = get_temp_buffer(16); - sprintf(ret, "(vt:%u)", var->vt); - break; - } - - return ret; -} - static int propvar_cmp(const PROPVARIANT *v1, LONGLONG value2) { LONGLONG value1; @@ -2594,8 +3403,6 @@ static HRESULT WINAPI mdr_GetValue(IWICMetadataReader *iface, const PROPVARIANT { UINT i; - trace("%p,%s,%s,%s\n", iface, wine_dbgstr_propvariant(schema), wine_dbgstr_propvariant(id), wine_dbgstr_propvariant(value)); - ok(current_metadata_block != NULL, "current_metadata_block can't be NULL\n"); if (!current_metadata_block) return E_POINTER; @@ -2611,14 +3418,14 @@ static HRESULT WINAPI mdr_GetValue(IWICMetadataReader *iface, const PROPVARIANT switch (schema->vt) { case VT_LPSTR: - if (lstrcmpA(U(*schema).pszVal, current_metadata_block->item[i].schema) != 0) + if (lstrcmpA(schema->pszVal, current_metadata_block->item[i].schema) != 0) continue; break; case VT_LPWSTR: { char schemaA[256]; - WideCharToMultiByte(CP_ACP, 0, U(*schema).pwszVal, -1, schemaA, sizeof(schemaA), NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, schema->pwszVal, -1, schemaA, sizeof(schemaA), NULL, NULL); if (lstrcmpA(schemaA, current_metadata_block->item[i].schema) != 0) continue; break; @@ -2637,10 +3444,10 @@ static HRESULT WINAPI mdr_GetValue(IWICMetadataReader *iface, const PROPVARIANT case VT_LPSTR: if (current_metadata_block->item[i].id_str) { - if (!lstrcmpA(U(*id).pszVal, current_metadata_block->item[i].id_str)) + if (!lstrcmpA(id->pszVal, current_metadata_block->item[i].id_str)) { value->vt = VT_LPSTR; - U(*value).pszVal = the_best; + value->pszVal = the_best; return S_OK; } break; @@ -2651,11 +3458,11 @@ static HRESULT WINAPI mdr_GetValue(IWICMetadataReader *iface, const PROPVARIANT if (current_metadata_block->item[i].id_str) { char idA[256]; - WideCharToMultiByte(CP_ACP, 0, U(*id).pwszVal, -1, idA, sizeof(idA), NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, id->pwszVal, -1, idA, sizeof(idA), NULL, NULL); if (!lstrcmpA(idA, current_metadata_block->item[i].id_str)) { value->vt = VT_LPSTR; - U(*value).pszVal = the_worst; + value->pszVal = the_worst; return S_OK; } break; @@ -2663,8 +3470,8 @@ static HRESULT WINAPI mdr_GetValue(IWICMetadataReader *iface, const PROPVARIANT break; case VT_CLSID: - if (IsEqualGUID(U(*id).puuid, &GUID_MetadataFormatXMP) || - IsEqualGUID(U(*id).puuid, &GUID_ContainerFormatTiff)) + if (IsEqualGUID(id->puuid, &GUID_MetadataFormatXMP) || + IsEqualGUID(id->puuid, &GUID_ContainerFormatTiff)) { value->vt = VT_UNKNOWN; value->punkVal = (IUnknown *)iface; @@ -2676,7 +3483,7 @@ static HRESULT WINAPI mdr_GetValue(IWICMetadataReader *iface, const PROPVARIANT if (!propvar_cmp(id, current_metadata_block->item[i].id)) { value->vt = current_metadata_block->item[i].type; - U(*value).uiVal = current_metadata_block->item[i].value; + value->uiVal = current_metadata_block->item[i].value; return S_OK; } break; @@ -2736,8 +3543,6 @@ static ULONG WINAPI mdbr_Release(IWICMetadataBlockReader *iface) static HRESULT WINAPI mdbr_GetContainerFormat(IWICMetadataBlockReader *iface, GUID *format) { - trace("%p,%p\n", iface, format); - ok(current_metadata != NULL, "current_metadata can't be NULL\n"); if (!current_metadata) return E_POINTER; @@ -2747,8 +3552,6 @@ static HRESULT WINAPI mdbr_GetContainerFormat(IWICMetadataBlockReader *iface, GU static HRESULT WINAPI mdbr_GetCount(IWICMetadataBlockReader *iface, UINT *count) { - trace("%p,%p\n", iface, count); - ok(current_metadata != NULL, "current_metadata can't be NULL\n"); if (!current_metadata) return E_POINTER; @@ -2758,8 +3561,6 @@ static HRESULT WINAPI mdbr_GetCount(IWICMetadataBlockReader *iface, UINT *count) static HRESULT WINAPI mdbr_GetReaderByIndex(IWICMetadataBlockReader *iface, UINT index, IWICMetadataReader **out) { - trace("%p,%u,%p\n", iface, index, out); - *out = NULL; ok(current_metadata != NULL, "current_metadata can't be NULL\n"); @@ -2870,88 +3671,52 @@ static const struct metadata data3 = static void test_queryreader(void) { - static const char q1[] = "/ifd/{uchar=1}"; - static const char q2[] = "/ifd/xmp:{long=4}"; - static const char q3[] = "/ifd/{str=xmp}:{uint=4}"; - static const char q4[] = "/xmp/{char=7}"; - static const char q5[] = "/[1]xmp/{short=7}"; - static const char q6[] = "/[1]ifd/{str=dc}:{uint=7}"; - static const char q7[] = "/[1]ifd/{str=http://purl.org/dc/elements/1.1/}:{longlong=7}"; - static const char q8[] = "/[1]ifd/{str=http://ns.adobe.com/tiff/1.0/}:{int=10}"; - static const char q9[] = "/[2]xmp/xmp:{ulong=4}"; - static const char q10[] = "/[2]xmp/{str=xmp}:{ulong=4}"; - static const char q11[] = "/xmp"; - static const char q12[] = "/ifd/xmp"; - static const char q13[] = "/ifd/xmp/tiff"; - static const char q14[] = "/[0]ifd/[0]xmp/[0]tiff"; - static const char q15[] = "/[*]xmp"; - - static const char q20[] = "/ifd/\\Rating"; - static const char q21[] = "/[0]ifd/Rating"; - static const char q22[] = "/[2]xmp/xmp:{str=Rating}"; - static const char q23[] = "/[2]xmp/xmp:Rating"; - - static const char q24[] = "/[1]ifd/{str=http://ns.adobe.com/xap/1.0/}:Rating"; - static const char q25[] = "/[1]ifd/{str=http://ns.adobe.com/xap/1.0/}:{str=Rating}"; - static const char q26[] = "/[1]ifd/{wstr=\\RATING}"; - static const char q27[] = "/[1]ifd/{str=R\\ATING}"; - static const char q28[] = "/[1]ifd/{str=R\\}ATING}"; - - static const char q40[] = "[0]/ifd/Rating"; - static const char q41[] = "/[+1]ifd/Rating"; - static const char q42[] = "/[-1]ifd/Rating"; - static const char q43[] = "/ifd/{\\str=Rating}"; - static const char q44[] = "/ifd/{badtype=0}"; - static const char q45[] = "/ifd/{uint=0x1234}"; - static const char q46[] = "/ifd/[0]Rating"; - static const char q47[] = "/ifd/[*]Rating"; static const struct { BOOL todo; const struct metadata *data; - const char *query; + const WCHAR *query; HRESULT hr; UINT vt, value; const char *str_value; } test_data[] = { - { FALSE, &data1, q1, S_OK, 2, 3, NULL }, - { FALSE, &data2, q2, S_OK, 5, 6, NULL }, - { FALSE, &data2, q3, S_OK, 5, 6, NULL }, - { FALSE, &data3, q4, 0xdeadbeef }, - { FALSE, &data3, q5, S_OK, 8, 9, NULL }, - { FALSE, &data3, q6, 0xdeadbeef }, - { FALSE, &data3, q7, S_OK, 8, 9, NULL }, - { FALSE, &data3, q8, S_OK, 11, 12, NULL }, - { FALSE, &data3, q9, S_OK, 5, 6, NULL }, - { FALSE, &data3, q10, 0xdeadbeef }, + { FALSE, &data1, L"/ifd/{uchar=1}", S_OK, 2, 3, NULL }, + { FALSE, &data2, L"/ifd/xmp:{long=4}", S_OK, 5, 6, NULL }, + { FALSE, &data2, L"/ifd/{str=xmp}:{uint=4}", S_OK, 5, 6, NULL }, + { FALSE, &data3, L"/xmp/{char=7}", 0xdeadbeef }, + { FALSE, &data3, L"/[1]xmp/{short=7}", S_OK, 8, 9, NULL }, + { FALSE, &data3, L"/[1]ifd/{str=dc}:{uint=7}", 0xdeadbeef }, + { FALSE, &data3, L"/[1]ifd/{str=http://purl.org/dc/elements/1.1/}:{longlong=7}", S_OK, 8, 9, NULL }, + { FALSE, &data3, L"/[1]ifd/{str=http://ns.adobe.com/tiff/1.0/}:{int=10}", S_OK, 11, 12, NULL }, + { FALSE, &data3, L"/[2]xmp/xmp:{ulong=4}", S_OK, 5, 6, NULL }, + { FALSE, &data3, L"/[2]xmp/{str=xmp}:{ulong=4}", 0xdeadbeef }, - { FALSE, &data3, q11, S_OK, VT_UNKNOWN, 0, NULL }, - { FALSE, &data3, q12, S_OK, VT_UNKNOWN, 0, NULL }, - { FALSE, &data3, q13, S_OK, VT_UNKNOWN, 0, NULL }, - { FALSE, &data3, q14, S_OK, VT_UNKNOWN, 0, NULL }, - { TRUE, &data3, q15, S_OK, VT_LPSTR, 0, the_worst }, + { FALSE, &data3, L"/xmp", S_OK, VT_UNKNOWN, 0, NULL }, + { FALSE, &data3, L"/ifd/xmp", S_OK, VT_UNKNOWN, 0, NULL }, + { FALSE, &data3, L"/ifd/xmp/tiff", S_OK, VT_UNKNOWN, 0, NULL }, + { FALSE, &data3, L"/[0]ifd/[0]xmp/[0]tiff", S_OK, VT_UNKNOWN, 0, NULL }, + { TRUE, &data3, L"/[*]xmp", S_OK, VT_LPSTR, 0, the_worst }, - { FALSE, &data3, q20, S_OK, VT_LPSTR, 0, the_worst }, - { FALSE, &data3, q21, S_OK, VT_LPSTR, 0, the_worst }, - { FALSE, &data3, q22, S_OK, VT_LPSTR, 0, the_best }, - { FALSE, &data3, q23, S_OK, VT_LPSTR, 0, the_worst }, - { FALSE, &data3, q24, S_OK, VT_LPSTR, 0, the_worst }, - { FALSE, &data3, q25, S_OK, VT_LPSTR, 0, the_best }, - { FALSE, &data3, q26, S_OK, VT_LPSTR, 0, the_worst }, - { FALSE, &data3, q27, S_OK, VT_LPSTR, 0, the_best }, - { FALSE, &data3, q28, S_OK, VT_LPSTR, 0, the_best }, + { FALSE, &data3, L"/ifd/\\Rating", S_OK, VT_LPSTR, 0, the_worst }, + { FALSE, &data3, L"/[0]ifd/Rating", S_OK, VT_LPSTR, 0, the_worst }, + { FALSE, &data3, L"/[2]xmp/xmp:{str=Rating}", S_OK, VT_LPSTR, 0, the_best }, + { FALSE, &data3, L"/[2]xmp/xmp:Rating", S_OK, VT_LPSTR, 0, the_worst }, + { FALSE, &data3, L"/[1]ifd/{str=http://ns.adobe.com/xap/1.0/}:Rating", S_OK, VT_LPSTR, 0, the_worst }, + { FALSE, &data3, L"/[1]ifd/{str=http://ns.adobe.com/xap/1.0/}:{str=Rating}", S_OK, VT_LPSTR, 0, the_best }, + { FALSE, &data3, L"/[1]ifd/{wstr=\\RATING}", S_OK, VT_LPSTR, 0, the_worst }, + { FALSE, &data3, L"/[1]ifd/{str=R\\ATING}", S_OK, VT_LPSTR, 0, the_best }, + { FALSE, &data3, L"/[1]ifd/{str=R\\}ATING}", S_OK, VT_LPSTR, 0, the_best }, - { FALSE, &data1, q40, WINCODEC_ERR_PROPERTYNOTSUPPORTED }, - { TRUE, &data1, q41, WINCODEC_ERR_INVALIDQUERYCHARACTER }, - { TRUE, &data1, q42, WINCODEC_ERR_INVALIDQUERYCHARACTER }, - { FALSE, &data1, q43, WINCODEC_ERR_WRONGSTATE }, - { FALSE, &data1, q44, WINCODEC_ERR_WRONGSTATE }, - { TRUE, &data1, q45, DISP_E_TYPEMISMATCH }, - { TRUE, &data1, q46, E_INVALIDARG }, - { TRUE, &data1, q47, WINCODEC_ERR_REQUESTONLYVALIDATMETADATAROOT }, + { FALSE, &data1, L"[0]/ifd/Rating", WINCODEC_ERR_PROPERTYNOTSUPPORTED }, + { TRUE, &data1, L"/[+1]ifd/Rating", WINCODEC_ERR_INVALIDQUERYCHARACTER }, + { TRUE, &data1, L"/[-1]ifd/Rating", WINCODEC_ERR_INVALIDQUERYCHARACTER }, + { FALSE, &data1, L"/ifd/{\\str=Rating}", WINCODEC_ERR_WRONGSTATE }, + { FALSE, &data1, L"/ifd/{badtype=0}", WINCODEC_ERR_WRONGSTATE }, + { TRUE, &data1, L"/ifd/{uint=0x1234}", DISP_E_TYPEMISMATCH }, + { TRUE, &data1, L"/ifd/[0]Rating", E_INVALIDARG }, + { TRUE, &data1, L"/ifd/[*]Rating", WINCODEC_ERR_REQUESTONLYVALIDATMETADATAROOT }, }; - WCHAR queryW[256]; HRESULT hr; IWICComponentFactory *factory; IWICMetadataQueryReader *reader; @@ -2961,28 +3726,29 @@ static void test_queryreader(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICComponentFactory, (void **)&factory); - ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); hr = IWICComponentFactory_CreateQueryReaderFromBlockReader(factory, &mdbr, &reader); - ok(hr == S_OK, "CreateQueryReaderFromBlockReader error %#x\n", hr); + ok(hr == S_OK, "CreateQueryReaderFromBlockReader error %#lx\n", hr); for (i = 0; i < ARRAY_SIZE(test_data); i++) { + winetest_push_context("%u", i); + current_metadata = test_data[i].data; hr = IWICMetadataQueryReader_GetContainerFormat(reader, &format); - ok(hr == S_OK, "%u: GetContainerFormat error %#x\n", i, hr); - ok(IsEqualGUID(&format, test_data[i].data->container_format), "%u: expected %s, got %s\n", - i, wine_dbgstr_guid(test_data[i].data->container_format), wine_dbgstr_guid(&format)); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, test_data[i].data->container_format), "Expected %s, got %s.\n", + wine_dbgstr_guid(test_data[i].data->container_format), wine_dbgstr_guid(&format)); - MultiByteToWideChar(CP_ACP, 0, test_data[i].query, -1, queryW, 256); PropVariantInit(&value); - hr = IWICMetadataQueryReader_GetMetadataByName(reader, queryW, &value); + hr = IWICMetadataQueryReader_GetMetadataByName(reader, test_data[i].query, &value); todo_wine_if(test_data[i].todo) - ok(hr == test_data[i].hr, "%u: expected %#x, got %#x\n", i, test_data[i].hr, hr); + ok(hr == test_data[i].hr, "Expected %#lx, got %#lx.\n", test_data[i].hr, hr); if (hr == S_OK) { - ok(value.vt == test_data[i].vt, "%u: expected %u, got %u\n", i, test_data[i].vt, value.vt); + ok(value.vt == test_data[i].vt, "Expected %u, got %u.\n", test_data[i].vt, value.vt); if (test_data[i].vt == value.vt) { if (value.vt == VT_UNKNOWN) @@ -2992,66 +3758,718 @@ static void test_queryreader(void) UINT len; hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataQueryReader, (void **)&new_reader); - ok(hr == S_OK, "QueryInterface error %#x\n", hr); + ok(hr == S_OK, "QueryInterface error %#lx\n", hr); location[0] = 0; len = 0xdeadbeef; hr = IWICMetadataQueryReader_GetLocation(new_reader, 256, location, &len); - ok(hr == S_OK, "GetLocation error %#x\n", hr); - ok(len == lstrlenW(queryW) + 1, "expected %u, got %u\n", lstrlenW(queryW) + 1, len); - ok(!lstrcmpW(location, queryW), "expected %s, got %s\n", wine_dbgstr_w(queryW), wine_dbgstr_w(location)); + ok(hr == S_OK, "GetLocation error %#lx\n", hr); + ok(len == lstrlenW(test_data[i].query) + 1, "expected %u, got %u\n", lstrlenW(test_data[i].query) + 1, len); + ok(!lstrcmpW(location, test_data[i].query), "expected %s, got %s\n", wine_dbgstr_w(test_data[i].query), wine_dbgstr_w(location)); hr = IWICMetadataQueryReader_GetLocation(new_reader, 256, location, NULL); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); location[0] = 0; len = 0xdeadbeef; hr = IWICMetadataQueryReader_GetLocation(new_reader, 3, location, &len); - ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "got %#x\n", hr); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "got %#lx\n", hr); ok(len == 0xdeadbeef, "got %u\n", len); ok(!location[0], "got %s\n", wine_dbgstr_w(location)); location[0] = 0; len = 0xdeadbeef; hr = IWICMetadataQueryReader_GetLocation(new_reader, 0, location, &len); - ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "got %#x\n", hr); + ok(hr == WINCODEC_ERR_INSUFFICIENTBUFFER, "got %#lx\n", hr); ok(len == 0xdeadbeef, "got %u\n", len); ok(!location[0], "got %s\n", wine_dbgstr_w(location)); len = 0xdeadbeef; hr = IWICMetadataQueryReader_GetLocation(new_reader, 0, NULL, &len); - ok(hr == S_OK, "GetLocation error %#x\n", hr); - ok(len == lstrlenW(queryW) + 1, "expected %u, got %u\n", lstrlenW(queryW) + 1, len); + ok(hr == S_OK, "GetLocation error %#lx\n", hr); + ok(len == lstrlenW(test_data[i].query) + 1, "expected %u, got %u\n", lstrlenW(test_data[i].query) + 1, len); len = 0xdeadbeef; hr = IWICMetadataQueryReader_GetLocation(new_reader, 3, NULL, &len); - ok(hr == S_OK, "GetLocation error %#x\n", hr); - ok(len == lstrlenW(queryW) + 1, "expected %u, got %u\n", lstrlenW(queryW) + 1, len); + ok(hr == S_OK, "GetLocation error %#lx\n", hr); + ok(len == lstrlenW(test_data[i].query) + 1, "expected %u, got %u\n", lstrlenW(test_data[i].query) + 1, len); hr = IWICMetadataQueryReader_GetLocation(new_reader, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "got %#x\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); IWICMetadataQueryReader_Release(new_reader); PropVariantClear(&value); } else if (value.vt == VT_LPSTR) - ok(!lstrcmpA(U(value).pszVal, test_data[i].str_value), "%u: expected %s, got %s\n", - i, test_data[i].str_value, U(value).pszVal); + ok(!lstrcmpA(value.pszVal, test_data[i].str_value), "Expected %s, got %s.\n", + test_data[i].str_value, value.pszVal); else - ok(U(value).uiVal == test_data[i].value, "%u: expected %u, got %u\n", - i, test_data[i].value, U(value).uiVal); + ok(value.uiVal == test_data[i].value, "Expected %u, got %u\n", + test_data[i].value, value.uiVal); } /* * Do NOT call PropVariantClear(&value) for fake value types. */ } + + winetest_pop_context(); } IWICMetadataQueryReader_Release(reader); IWICComponentFactory_Release(factory); } +static void test_metadata_writer(void) +{ + static struct + { + REFCLSID rclsid; + BOOL wine_supports_encoder; + BOOL metadata_supported; + BOOL succeeds_uninitialized; + } + tests[] = + { + {&CLSID_WICBmpEncoder, TRUE, FALSE}, + {&CLSID_WICPngEncoder, TRUE, TRUE}, + {&CLSID_WICJpegEncoder, TRUE, TRUE}, + {&CLSID_WICGifEncoder, TRUE, TRUE}, + {&CLSID_WICTiffEncoder, TRUE, TRUE}, + {&CLSID_WICWmpEncoder, FALSE, TRUE, TRUE}, + }; + + IWICMetadataQueryWriter *querywriter, *querywriter2; + IWICMetadataBlockWriter *blockwriter; + IWICBitmapFrameEncode *frameencode; + IWICComponentFactory *factory; + IWICBitmapEncoder *encoder; + IEnumString *enumstring; + LPOLESTR olestring; + ULONG ref, count; + IStream *stream; + unsigned int i; + HRESULT hr; + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + winetest_push_context("%u", i); + + hr = CoCreateInstance(tests[i].rclsid, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICBitmapEncoder, (void **)&encoder); + todo_wine_if(!tests[i].wine_supports_encoder) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + if (FAILED(hr)) + { + winetest_pop_context(); + continue; + } + + blockwriter = NULL; + querywriter = querywriter2 = NULL; + + hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frameencode, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = IWICBitmapFrameEncode_QueryInterface(frameencode, &IID_IWICMetadataBlockWriter, (void**)&blockwriter); + ok(hr == (tests[i].metadata_supported ? S_OK : E_NOINTERFACE), "Got unexpected hr %#lx.\n", hr); + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICComponentFactory, (void**)&factory); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = IWICComponentFactory_CreateQueryWriterFromBlockWriter(factory, blockwriter, &querywriter); + ok(hr == (tests[i].metadata_supported ? S_OK : E_INVALIDARG), "Got unexpected hr %#lx.\n", hr); + + hr = IWICBitmapFrameEncode_GetMetadataQueryWriter(frameencode, &querywriter2); + ok(hr == (tests[i].succeeds_uninitialized ? S_OK : WINCODEC_ERR_NOTINITIALIZED), + "Got unexpected hr %#lx.\n", hr); + if (hr == S_OK) + IWICMetadataQueryWriter_Release(querywriter2); + + hr = IWICBitmapFrameEncode_Initialize(frameencode, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = IWICBitmapFrameEncode_GetMetadataQueryWriter(frameencode, &querywriter2); + ok(hr == (tests[i].metadata_supported ? S_OK : WINCODEC_ERR_UNSUPPORTEDOPERATION), + "Got unexpected hr %#lx.\n", hr); + + if (tests[i].metadata_supported) + ok(querywriter2 != querywriter, "Got unexpected interfaces %p, %p.\n", querywriter, querywriter2); + + IWICComponentFactory_Release(factory); + if (querywriter) + { + ref = get_refcount(querywriter); + ok(ref == 1, "Got unexpected ref %lu.\n", ref); + + hr = IWICMetadataQueryWriter_QueryInterface(querywriter, &IID_IEnumString, (void **)&enumstring); + ok(hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr); + + hr = IWICMetadataQueryWriter_GetEnumerator(querywriter, &enumstring); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + ref = get_refcount(querywriter); + ok(ref == 1, "Got unexpected ref %lu.\n", ref); + + hr = IEnumString_Skip(enumstring, 0); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + count = 0xdeadbeef; + hr = IEnumString_Next(enumstring, 0, NULL, &count); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + ok(count == 0xdeadbeef, "Got unexpected count %lu.\n", count); + + hr = IEnumString_Next(enumstring, 0, &olestring, &count); + ok(hr == S_OK || hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Got unexpected hr %#lx.\n", hr); + + count = 0xdeadbeef; + hr = IEnumString_Next(enumstring, 1, &olestring, &count); + ok(hr == S_OK || hr == S_FALSE, "Got unexpected hr %#lx, i %u.\n", hr, i); + ok((hr && !count) || (!hr && count == 1), "Got unexpected hr %#lx, count %lu.\n", hr, count); + if (count) + { + CoTaskMemFree(olestring); + + /* IEnumString_Skip() crashes at least on Win7 when + * trying to skip past the string count. */ + hr = IEnumString_Reset(enumstring); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = IEnumString_Skip(enumstring, 1); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + } + IEnumString_Release(enumstring); + + IWICMetadataQueryWriter_Release(querywriter); + IWICMetadataQueryWriter_Release(querywriter2); + IWICMetadataBlockWriter_Release(blockwriter); + } + IWICBitmapFrameEncode_Release(frameencode); + IStream_Release(stream); + IWICBitmapEncoder_Release(encoder); + + winetest_pop_context(); + } +} + +#include "pshpack2.h" +static const struct app1_data +{ + BYTE exif_header[6]; + BYTE bom[2]; + USHORT marker; + ULONG ifd0_offset; + + USHORT ifd0_count; + struct IFD_entry ifd0[4]; + ULONG next_IFD; + + USHORT exif_ifd_count; + struct IFD_entry exif_ifd[1]; + ULONG next_IFD_2; + + USHORT gps_ifd_count; + struct IFD_entry gps_ifd[1]; + ULONG next_IFD_3; +} +app1_data = +{ + { 'E','x','i','f',0,0 }, + { 'I','I' }, + 0x002a, + 0x8, + + /* IFD 0 */ + 4, + { + { 0x100, IFD_LONG, 1, 222 }, /* IMAGEWIDTH */ + { 0x101, IFD_LONG, 1, 333 }, /* IMAGELENGTH */ + /* Exif IFD pointer */ + { 0x8769, IFD_LONG, 1, FIELD_OFFSET(struct app1_data, exif_ifd_count) - 6 }, + /* GPS IFD pointer */ + { 0x8825, IFD_LONG, 1, FIELD_OFFSET(struct app1_data, gps_ifd_count) - 6 }, + }, + 0, + + /* Exif IFD */ + 1, + { + { 0x200, IFD_SHORT, 1, 444 }, + }, + 0, + + /* GPS IFD */ + 1, + { + { 0x300, IFD_SHORT, 1, 555 }, + }, + 0, +}; +#include "poppack.h" + +static void test_metadata_App1(void) +{ + IWICMetadataReader *reader, *ifd_reader, *exif_reader, *gps_reader; + IStream *app1_stream, *stream2; + IWICMetadataWriter *writer; + PROPVARIANT id, value; + GUID format; + HRESULT hr; + UINT count; + + hr = CoCreateInstance(&CLSID_WICApp1MetadataReader, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataReader, (void **)&reader); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(reader, &IID_IWICMetadataReader, TRUE); + check_interface(reader, &IID_IPersist, TRUE); + check_interface(reader, &IID_IPersistStream, TRUE); + check_interface(reader, &IID_IWICPersistStream, TRUE); + check_interface(reader, &IID_IWICStreamProvider, TRUE); + check_interface(reader, &IID_IWICMetadataBlockReader, FALSE); + + hr = IWICMetadataReader_GetCount(reader, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + count = 1; + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!count, "Unexpected count %u.\n", count); + + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatApp1), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + + test_reader_container_format(reader, &GUID_ContainerFormatJpeg); + + load_stream(reader, (const char *)&app1_data, sizeof(app1_data), 0); + check_persist_options(reader, 0); + hr = get_persist_stream(reader, &app1_stream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %u.\n", count); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + /* Top level IFD reader. */ + ok(id.vt == VT_UI2, "Unexpected id type: %u.\n", id.vt); + ok(id.uiVal == 0, "Unexpected id %u.\n", id.uiVal); + + ok(value.vt == VT_UNKNOWN, "Unexpected value type: %u.\n", value.vt); + ok(!!value.punkVal, "Unexpected value.\n"); + + hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataReader, (void **)&ifd_reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + PropVariantClear(&value); + + hr = IWICMetadataReader_GetMetadataFormat(ifd_reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatIfd), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + check_persist_options(ifd_reader, 0); + + hr = get_persist_stream(ifd_reader, &stream2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!!stream2 && stream2 != app1_stream, "Unexpected stream %p.\n", stream2); + IStream_Release(stream2); + + hr = IWICMetadataReader_GetCount(ifd_reader, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 4, "Unexpected count %u.\n", count); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataReader_GetValueByIndex(ifd_reader, 0, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + ok(id.vt == VT_UI2, "Unexpected id type: %u.\n", id.vt); + ok(id.uiVal == 0x100, "Unexpected id %#x.\n", id.uiVal); + ok(value.vt == VT_UI4, "Unexpected value type: %u.\n", value.vt); + ok(value.ulVal == 222, "Unexpected value %lu.\n", value.ulVal); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataReader_GetValueByIndex(ifd_reader, 1, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + ok(id.vt == VT_UI2, "Unexpected id type: %u.\n", id.vt); + ok(id.uiVal == 0x101, "Unexpected id %#x.\n", id.uiVal); + ok(value.vt == VT_UI4, "Unexpected value type: %u.\n", value.vt); + ok(value.ulVal == 333, "Unexpected value %lu.\n", value.ulVal); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataReader_GetValueByIndex(ifd_reader, 2, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + ok(id.vt == VT_UI2, "Unexpected id type: %u.\n", id.vt); + ok(id.uiVal == 0x8769, "Unexpected id %#x.\n", id.uiVal); + ok(value.vt == VT_UNKNOWN, "Unexpected value type: %u.\n", value.vt); + hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataReader, (void **)&exif_reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + PropVariantClear(&value); + + /* Exif IFD */ + hr = IWICMetadataReader_GetMetadataFormat(exif_reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatExif), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + check_persist_options(exif_reader, 0); + + hr = get_persist_stream(exif_reader, &stream2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!!stream2 && stream2 != app1_stream, "Unexpected stream.\n"); + IStream_Release(stream2); + + hr = IWICMetadataReader_GetCount(exif_reader, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %u.\n", count); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataReader_GetValueByIndex(exif_reader, 0, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + ok(id.vt == VT_UI2, "Unexpected id type: %u.\n", id.vt); + ok(id.uiVal == 0x200, "Unexpected id %#x.\n", id.uiVal); + ok(value.vt == VT_UI2, "Unexpected value type: %u.\n", value.vt); + ok(value.ulVal == 444, "Unexpected value %lu.\n", value.ulVal); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataReader_GetValueByIndex(ifd_reader, 3, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + ok(id.vt == VT_UI2, "Unexpected id type: %u.\n", id.vt); + ok(id.uiVal == 0x8825, "Unexpected id %#x.\n", id.uiVal); + ok(value.vt == VT_UNKNOWN, "Unexpected value type: %u.\n", value.vt); + hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataReader, (void **)&gps_reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + PropVariantClear(&value); + + /* GPS IFD */ + hr = IWICMetadataReader_GetMetadataFormat(gps_reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatGps), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + check_persist_options(gps_reader, 0); + + hr = get_persist_stream(gps_reader, &stream2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!!stream2 && stream2 != app1_stream, "Unexpected stream.\n"); + IStream_Release(stream2); + + hr = IWICMetadataReader_GetCount(gps_reader, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %u.\n", count); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataReader_GetValueByIndex(gps_reader, 0, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + ok(id.vt == VT_UI2, "Unexpected id type: %u.\n", id.vt); + ok(id.uiVal == 0x300, "Unexpected id %#x.\n", id.uiVal); + ok(value.vt == VT_UI2, "Unexpected value type: %u.\n", value.vt); + ok(value.ulVal == 555, "Unexpected value %lu.\n", value.ulVal); + + IWICMetadataReader_Release(gps_reader); + IWICMetadataReader_Release(exif_reader); + IWICMetadataReader_Release(ifd_reader); + + IStream_Release(app1_stream); + IWICMetadataReader_Release(reader); + + hr = CoCreateInstance(&CLSID_WICApp1MetadataWriter, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICMetadataWriter, (void **)&writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) return; + + check_interface(writer, &IID_IWICMetadataWriter, TRUE); + check_interface(writer, &IID_IWICMetadataReader, TRUE); + check_interface(writer, &IID_IPersist, TRUE); + check_interface(writer, &IID_IPersistStream, TRUE); + check_interface(writer, &IID_IWICPersistStream, TRUE); + check_interface(writer, &IID_IWICStreamProvider, TRUE); + + IWICMetadataWriter_Release(writer); +} + +static void test_CreateMetadataWriterFromReader(void) +{ + IWICComponentFactory *factory; + IWICMetadataReader *reader; + IWICMetadataWriter *writer; + IStream *stream, *stream2; + PROPVARIANT id, value; + GUID format; + HRESULT hr; + UINT count; + char *data; + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICComponentFactory, (void **)&factory); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + /* tEXt, uninitialized */ + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_MetadataFormatChunktEXt, + NULL, 0, NULL, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + check_persist_options(reader, 0); + + hr = IWICComponentFactory_CreateMetadataWriterFromReader(factory, reader, NULL, &writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) + { + IWICMetadataReader_Release(reader); + IWICComponentFactory_Release(factory); + return; + } + + IWICMetadataReader_Release(reader); + + check_persist_options(writer, 0); + IWICMetadataWriter_Release(writer); + + /* tEXt, loaded */ + stream = create_stream(metadata_tEXt, sizeof(metadata_tEXt)); + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_MetadataFormatChunktEXt, + NULL, 0, stream, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + check_persist_options(reader, 0); + IStream_Release(stream); + + hr = IWICComponentFactory_CreateMetadataWriterFromReader(factory, NULL, NULL, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = IWICComponentFactory_CreateMetadataWriterFromReader(factory, NULL, NULL, &writer); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = IWICComponentFactory_CreateMetadataWriterFromReader(factory, reader, NULL, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + expect_ref(reader, 1); + hr = IWICComponentFactory_CreateMetadataWriterFromReader(factory, reader, NULL, &writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + expect_ref(reader, 1); + + hr = IWICMetadataReader_GetCount(reader, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %u.\n", count); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(id.vt == VT_LPSTR, "Unexpected id type %u.\n", id.vt); + ok(!strcmp(id.pszVal, "winetest"), "Unexpected id %s.\n", wine_dbgstr_a(id.pszVal)); + ok(value.vt == VT_LPSTR, "Unexpected value type %u.\n", value.vt); + ok(!strcmp(value.pszVal, "value"), "Unexpected value %s.\n", wine_dbgstr_a(value.pszVal)); + PropVariantClear(&id); + PropVariantClear(&value); + + hr = IWICMetadataWriter_GetMetadataFormat(writer, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktEXt), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + + hr = IWICMetadataWriter_GetCount(writer, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %u.\n", count); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataWriter_GetValueByIndex(writer, 0, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(id.vt == VT_LPSTR, "Unexpected id type %u.\n", id.vt); + ok(!strcmp(id.pszVal, "winetest"), "Unexpected id %s.\n", wine_dbgstr_a(id.pszVal)); + ok(value.vt == VT_LPSTR, "Unexpected value type %u.\n", value.vt); + ok(!strcmp(value.pszVal, "value"), "Unexpected value %s.\n", wine_dbgstr_a(value.pszVal)); + PropVariantClear(&id); + PropVariantClear(&value); + + IWICMetadataWriter_Release(writer); + IWICMetadataReader_Release(reader); + + /* App1 reader */ + stream = create_stream((const char *)&app1_data, sizeof(app1_data)); + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_MetadataFormatApp1, + NULL, 0, stream, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IWICComponentFactory_CreateMetadataWriterFromReader(factory, reader, NULL, &writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatApp1), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + + hr = IWICMetadataWriter_GetCount(writer, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %u.\n", count); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataReader_GetValueByIndex(reader, 0, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(id.vt == VT_UI2, "Unexpected id type %u.\n", id.vt); + ok(value.vt == VT_UNKNOWN, "Unexpected value type %u.\n", value.vt); + check_interface(value.punkVal, &IID_IWICMetadataReader, TRUE); + check_interface(value.punkVal, &IID_IWICMetadataWriter, FALSE); + PropVariantClear(&value); + + hr = IWICMetadataWriter_GetMetadataFormat(writer, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatApp1), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + + hr = IWICMetadataWriter_GetCount(writer, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %u.\n", count); + + PropVariantInit(&id); + PropVariantInit(&value); + hr = IWICMetadataWriter_GetValueByIndex(writer, 0, NULL, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(id.vt == VT_UI2, "Unexpected id type %u.\n", id.vt); + ok(value.vt == VT_UNKNOWN, "Unexpected value type %u.\n", value.vt); + check_interface(value.punkVal, &IID_IWICMetadataReader, TRUE); + check_interface(value.punkVal, &IID_IWICMetadataWriter, TRUE); + check_persist_options(value.punkVal, 0); + PropVariantClear(&value); + + hr = get_persist_stream(writer, &stream2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(stream2 != stream, "Unexpected stream.\n"); + IStream_Release(stream2); + + IWICMetadataWriter_Release(writer); + IWICMetadataReader_Release(reader); + IStream_Release(stream); + + /* Big-endian IFD */ + data = malloc(sizeof(IFD_data)); + memcpy(data, &IFD_data, sizeof(IFD_data)); + byte_swap_ifd_data(data); + + hr = IWICComponentFactory_CreateMetadataReader(factory, &GUID_MetadataFormatIfd, + NULL, 0, NULL, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + load_stream(reader, data, sizeof(IFD_data), WICPersistOptionBigEndian); + check_persist_options(reader, WICPersistOptionBigEndian); + free(data); + + hr = IWICComponentFactory_CreateMetadataWriterFromReader(factory, reader, NULL, &writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + check_persist_options(writer, WICPersistOptionBigEndian); + IWICMetadataWriter_Release(writer); + + IWICMetadataReader_Release(reader); + + IWICComponentFactory_Release(factory); +} + +static void test_CreateMetadataWriter(void) +{ + static const struct options_test + { + const GUID *clsid; + DWORD options; + } + options_tests[] = + { + { &GUID_MetadataFormatApp1, WICPersistOptionBigEndian }, + { &GUID_MetadataFormatIfd, WICPersistOptionBigEndian }, + { &GUID_MetadataFormatChunktEXt, WICPersistOptionBigEndian }, + { &GUID_MetadataFormatApp1, WICPersistOptionNoCacheStream }, + { &GUID_MetadataFormatIfd, WICPersistOptionNoCacheStream }, + { &GUID_MetadataFormatChunktEXt, WICPersistOptionNoCacheStream }, + { &GUID_MetadataFormatApp1, 0x100 }, + }; + IWICStreamProvider *stream_provider; + IWICComponentFactory *factory; + IWICMetadataWriter *writer; + IStream *stream; + unsigned int i; + GUID format; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICComponentFactory, (void **)&factory); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + for (i = 0; i < ARRAY_SIZE(options_tests); ++i) + { + const struct options_test *test = &options_tests[i]; + + hr = IWICComponentFactory_CreateMetadataWriter(factory, test->clsid, NULL, test->options, &writer); + todo_wine + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + } + + hr = IWICComponentFactory_CreateMetadataWriter(factory, &GUID_MetadataFormatChunktEXt, NULL, 0, &writer); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) + { + IWICComponentFactory_Release(factory); + return; + } + check_persist_options(writer, 0); + + hr = IWICMetadataWriter_QueryInterface(writer, &IID_IWICStreamProvider, (void **)&stream_provider); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + stream = (void *)0xdeadbeef; + hr = IWICStreamProvider_GetStream(stream_provider, &stream); + ok(hr == WINCODEC_ERR_STREAMNOTAVAILABLE, "Unexpected hr %#lx.\n", hr); + ok(stream == (void *)0xdeadbeef, "Unexpected stream.\n"); + + IWICStreamProvider_Release(stream_provider); + + hr = IWICMetadataWriter_GetMetadataFormat(writer, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktEXt), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + + IWICMetadataWriter_Release(writer); + + /* Invalid format */ + hr = IWICComponentFactory_CreateMetadataWriter(factory, &IID_IUnknown, NULL, 0, &writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICMetadataWriter_GetMetadataFormat(writer, &format); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&format, &GUID_MetadataFormatUnknown), "Unexpected format %s.\n", wine_dbgstr_guid(&format)); + IWICMetadataWriter_Release(writer); + + writer = (void *)0xdeadbeef; + hr = IWICComponentFactory_CreateMetadataWriter(factory, &IID_IUnknown, NULL, WICMetadataCreationFailUnknown, &writer); + ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "Unexpected hr %#lx.\n", hr); + ok(writer == (void *)0xdeadbeef, "Unexpected pointer.\n"); + + /* App1 */ + hr = IWICComponentFactory_CreateMetadataWriter(factory, &GUID_MetadataFormatApp1, NULL, 0, &writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + check_persist_options(writer, 0); + IWICMetadataWriter_Release(writer); + + /* Ifd */ + hr = IWICComponentFactory_CreateMetadataWriter(factory, &GUID_MetadataFormatIfd, NULL, 0, &writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + check_persist_options(writer, 0); + IWICMetadataWriter_Release(writer); + + IWICComponentFactory_Release(factory); +} + START_TEST(metadata) { CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); @@ -3064,9 +4482,13 @@ START_TEST(metadata) test_metadata_tEXt(); test_metadata_gAMA(); test_metadata_cHRM(); - test_metadata_IFD(); + test_metadata_hIST(); + test_metadata_tIME(); + test_metadata_Ifd(); test_metadata_Exif(); - test_create_reader(); + test_metadata_Gps(); + test_create_reader_from_container(); + test_CreateMetadataReader(); test_metadata_png(); test_metadata_gif(); test_metadata_LSD(); @@ -3074,6 +4496,10 @@ START_TEST(metadata) test_metadata_GCE(); test_metadata_APE(); test_metadata_GIF_comment(); + test_metadata_writer(); + test_metadata_App1(); + test_CreateMetadataWriterFromReader(); + test_CreateMetadataWriter(); CoUninitialize(); } diff --git a/modules/rostests/winetests/windowscodecs/palette.c b/modules/rostests/winetests/windowscodecs/palette.c index 583fa66c80e..85860b3d03b 100644 --- a/modules/rostests/winetests/windowscodecs/palette.c +++ b/modules/rostests/winetests/windowscodecs/palette.c @@ -40,172 +40,172 @@ static void test_custom_palette(void) BOOL boolresult; hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreatePalette failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { hr = IWICPalette_GetType(palette, &type); - ok(SUCCEEDED(hr), "GetType failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetType failed, hr=%lx\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %x\n", type); hr = IWICPalette_GetColorCount(palette, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 0, "expected 0, got %u\n", count); hr = IWICPalette_GetColors(palette, 0, colors, &count); - ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColors failed, hr=%lx\n", hr); ok(count == 0, "expected 0, got %u\n", count); hr = IWICPalette_GetColors(palette, 4, colors, &count); - ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColors failed, hr=%lx\n", hr); ok(count == 0, "expected 0, got %u\n", count); memcpy(colors, initcolors, sizeof(initcolors)); hr = IWICPalette_InitializeCustom(palette, colors, 4); - ok(SUCCEEDED(hr), "InitializeCustom failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "InitializeCustom failed, hr=%lx\n", hr); hr = IWICPalette_GetType(palette, &type); - ok(SUCCEEDED(hr), "GetType failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetType failed, hr=%lx\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %x\n", type); hr = IWICPalette_GetColorCount(palette, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); memset(colors, 0, sizeof(colors)); count = 0; hr = IWICPalette_GetColors(palette, 4, colors, &count); - ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColors failed, hr=%lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); ok(!memcmp(colors, initcolors, sizeof(colors)), "got unexpected palette data\n"); memset(colors, 0, sizeof(colors)); count = 0; hr = IWICPalette_GetColors(palette, 2, colors, &count); - ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColors failed, hr=%lx\n", hr); ok(count == 2, "expected 2, got %u\n", count); ok(!memcmp(colors, initcolors, sizeof(WICColor)*2), "got unexpected palette data\n"); count = 0; hr = IWICPalette_GetColors(palette, 6, colors, &count); - ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColors failed, hr=%lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); hr = IWICPalette_HasAlpha(palette, &boolresult); - ok(SUCCEEDED(hr), "HasAlpha failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "HasAlpha failed, hr=%lx\n", hr); ok(!boolresult, "expected FALSE, got TRUE\n"); hr = IWICPalette_IsBlackWhite(palette, &boolresult); - ok(SUCCEEDED(hr), "IsBlackWhite failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "IsBlackWhite failed, hr=%lx\n", hr); ok(!boolresult, "expected FALSE, got TRUE\n"); hr = IWICPalette_IsGrayscale(palette, &boolresult); - ok(SUCCEEDED(hr), "IsGrayscale failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "IsGrayscale failed, hr=%lx\n", hr); ok(!boolresult, "expected FALSE, got TRUE\n"); hr = IWICImagingFactory_CreatePalette(factory, &palette2); - ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "CreatePalette failed, hr=%lx\n", hr); hr = IWICPalette_InitializeFromPalette(palette2, palette); - ok(SUCCEEDED(hr), "InitializeFromPalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "InitializeFromPalette failed, hr=%lx\n", hr); type = 0xdeadbeef; hr = IWICPalette_GetType(palette2, &type); - ok(SUCCEEDED(hr), "GetType failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetType failed, hr=%lx\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %x\n", type); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette2, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); memset(colors, 0, sizeof(colors)); count = 0xdeadbeef; hr = IWICPalette_GetColors(palette2, 4, colors, &count); - ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColors failed, hr=%lx\n", hr); ok(count == 4, "expected 4, got %u\n", count); ok(!memcmp(colors, initcolors, sizeof(colors)), "got unexpected palette data\n"); /* try a palette with some alpha in it */ colors[2] = 0x80ffffff; hr = IWICPalette_InitializeCustom(palette, colors, 4); - ok(SUCCEEDED(hr), "InitializeCustom failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "InitializeCustom failed, hr=%lx\n", hr); hr = IWICPalette_HasAlpha(palette, &boolresult); - ok(SUCCEEDED(hr), "HasAlpha failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "HasAlpha failed, hr=%lx\n", hr); ok(boolresult, "expected TRUE, got FALSE\n"); /* setting to a 0-color palette is acceptable */ hr = IWICPalette_InitializeCustom(palette, NULL, 0); - ok(SUCCEEDED(hr), "InitializeCustom failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "InitializeCustom failed, hr=%lx\n", hr); type = 0xdeadbeef; hr = IWICPalette_GetType(palette, &type); - ok(SUCCEEDED(hr), "GetType failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetType failed, hr=%lx\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %x\n", type); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 0, "expected 0, got %u\n", count); count = 0xdeadbeef; hr = IWICPalette_GetColors(palette, 4, colors, &count); - ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColors failed, hr=%lx\n", hr); ok(count == 0, "expected 0, got %u\n", count); hr = IWICPalette_InitializeFromPalette(palette2, palette); - ok(SUCCEEDED(hr), "InitializeFromPalette failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "InitializeFromPalette failed, hr=%lx\n", hr); type = 0xdeadbeef; hr = IWICPalette_GetType(palette2, &type); - ok(SUCCEEDED(hr), "GetType failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetType failed, hr=%lx\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %x\n", type); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette2, &count); - ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColorCount failed, hr=%lx\n", hr); ok(count == 0, "expected 0, got %u\n", count); memset(colors, 0, sizeof(colors)); count = 0xdeadbeef; hr = IWICPalette_GetColors(palette2, 4, colors, &count); - ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr); + ok(SUCCEEDED(hr), "GetColors failed, hr=%lx\n", hr); ok(count == 0, "expected 0, got %u\n", count); /* IWICPalette is paranoid about NULL pointers */ hr = IWICPalette_GetType(palette, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); hr = IWICPalette_GetColorCount(palette, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); hr = IWICPalette_InitializeCustom(palette, NULL, 4); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); hr = IWICPalette_GetColors(palette, 4, NULL, &count); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); hr = IWICPalette_GetColors(palette, 4, colors, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); hr = IWICPalette_HasAlpha(palette, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); hr = IWICPalette_IsBlackWhite(palette, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); hr = IWICPalette_IsGrayscale(palette, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); hr = IWICPalette_InitializeFromPalette(palette, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %lx\n", hr); IWICPalette_Release(palette2); IWICPalette_Release(palette); } } -static void generate_gray16_palette(DWORD *entries, UINT count) +static void generate_gray16_palette(WICColor *entries, UINT count) { UINT i; @@ -218,7 +218,7 @@ static void generate_gray16_palette(DWORD *entries, UINT count) } } -static void generate_gray256_palette(DWORD *entries, UINT count) +static void generate_gray256_palette(WICColor *entries, UINT count) { UINT i; @@ -231,7 +231,7 @@ static void generate_gray256_palette(DWORD *entries, UINT count) } } -static void generate_halftone8_palette(DWORD *entries, UINT count, BOOL add_transparent) +static void generate_halftone8_palette(WICColor *entries, UINT count, BOOL add_transparent) { UINT i; @@ -260,7 +260,7 @@ static void generate_halftone8_palette(DWORD *entries, UINT count, BOOL add_tran entries[i] = 0; } -static void generate_halftone27_palette(DWORD *entries, UINT count, BOOL add_transparent) +static void generate_halftone27_palette(WICColor *entries, UINT count, BOOL add_transparent) { static const BYTE halftone_values[4] = { 0x00,0x80,0xff }; UINT i; @@ -283,7 +283,7 @@ static void generate_halftone27_palette(DWORD *entries, UINT count, BOOL add_tra entries[i] = 0; } -static void generate_halftone64_palette(DWORD *entries, UINT count, BOOL add_transparent) +static void generate_halftone64_palette(WICColor *entries, UINT count, BOOL add_transparent) { static const BYTE halftone_values[4] = { 0x00,0x55,0xaa,0xff }; UINT i; @@ -313,7 +313,7 @@ static void generate_halftone64_palette(DWORD *entries, UINT count, BOOL add_tra entries[i] = 0; } -static void generate_halftone125_palette(DWORD *entries, UINT count, BOOL add_transparent) +static void generate_halftone125_palette(WICColor *entries, UINT count, BOOL add_transparent) { static const BYTE halftone_values[5] = { 0x00, 0x40, 0x80, 0xbf, 0xff }; UINT i; @@ -336,7 +336,7 @@ static void generate_halftone125_palette(DWORD *entries, UINT count, BOOL add_tr entries[i] = 0; } -static void generate_halftone216_palette(DWORD *entries, UINT count, BOOL add_transparent) +static void generate_halftone216_palette(WICColor *entries, UINT count, BOOL add_transparent) { static const BYTE halftone_values[6] = { 0x00,0x33,0x66,0x99,0xcc,0xff }; UINT i; @@ -366,7 +366,7 @@ static void generate_halftone216_palette(DWORD *entries, UINT count, BOOL add_tr entries[i] = 0; } -static void generate_halftone252_palette(DWORD *entries, UINT count, BOOL add_transparent) +static void generate_halftone252_palette(WICColor *entries, UINT count, BOOL add_transparent) { static const BYTE halftone_values_rb[6] = { 0x00,0x33,0x66,0x99,0xcc,0xff }; static const BYTE halftone_values_g[7] = { 0x00,0x2b,0x55,0x80,0xaa,0xd5,0xff }; @@ -389,7 +389,7 @@ static void generate_halftone252_palette(DWORD *entries, UINT count, BOOL add_tr entries[i] = 0; } -static void generate_halftone256_palette(DWORD *entries, UINT count, BOOL add_transparent) +static void generate_halftone256_palette(WICColor *entries, UINT count, BOOL add_transparent) { static const BYTE halftone_values_b[4] = { 0x00,0x55,0xaa,0xff }; static const BYTE halftone_values_gr[8] = { 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff }; @@ -453,47 +453,47 @@ static void test_predefined_palette(void) WICColor color[256]; hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeCustom, FALSE); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeMedianCut, FALSE); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICPalette_InitializePredefined(palette, 0x0f, FALSE); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); IWICPalette_Release(palette); for (i = 0; i < ARRAY_SIZE(td); i++) { hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "%u: CreatePalette error %#x\n", i, hr); + ok(hr == S_OK, "%u: CreatePalette error %#lx\n", i, hr); hr = IWICPalette_InitializePredefined(palette, td[i].type, td[i].add_transparent); - ok(hr == S_OK, "%u: InitializePredefined error %#x\n", i, hr); + ok(hr == S_OK, "%u: InitializePredefined error %#lx\n", i, hr); bret = -1; hr = IWICPalette_IsBlackWhite(palette, &bret); - ok(hr == S_OK, "%u: IsBlackWhite error %#x\n", i, hr); + ok(hr == S_OK, "%u: IsBlackWhite error %#lx\n", i, hr); ok(bret == td[i].is_bw || broken(td[i].type == WICBitmapPaletteTypeFixedBW && bret != td[i].is_bw), /* XP */ "%u: expected %d, got %d\n",i, td[i].is_bw, bret); bret = -1; hr = IWICPalette_IsGrayscale(palette, &bret); - ok(hr == S_OK, "%u: IsGrayscale error %#x\n", i, hr); + ok(hr == S_OK, "%u: IsGrayscale error %#lx\n", i, hr); ok(bret == td[i].is_gray, "%u: expected %d, got %d\n", i, td[i].is_gray, bret); type = -1; hr = IWICPalette_GetType(palette, &type); - ok(hr == S_OK, "%u: GetType error %#x\n", i, hr); + ok(hr == S_OK, "%u: GetType error %#lx\n", i, hr); ok(type == td[i].type, "%u: expected %#x, got %#x\n", i, td[i].type, type); count = 0xdeadbeef; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "%u: GetColorCount error %#x\n", i, hr); + ok(hr == S_OK, "%u: GetColorCount error %#lx\n", i, hr); ok(count == td[i].count, "%u: expected %u, got %u\n", i, td[i].count, count); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "%u: GetColors error %#x\n", i, hr); + ok(hr == S_OK, "%u: GetColors error %#lx\n", i, hr); ok(ret == count, "%u: expected %u, got %u\n", i, count, ret); if (ret == td[i].count) { @@ -571,68 +571,68 @@ static void test_palette_from_bitmap(void) hr = IWICImagingFactory_CreateBitmapFromMemory(factory, width, height, &GUID_WICPixelFormat24bppRGB, stride, stride * height, data, &bitmap); - ok(hr == S_OK, "CreateBitmapFromMemory error %#x\n", hr); + ok(hr == S_OK, "CreateBitmapFromMemory error %#lx\n", hr); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 0, FALSE); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 1, FALSE); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 257, FALSE); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICPalette_InitializeFromBitmap(palette, NULL, 16, FALSE); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 2, FALSE); - ok(hr == S_OK, "InitializeFromBitmap error %#x\n", hr); + ok(hr == S_OK, "InitializeFromBitmap error %#lx\n", hr); count = 0; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 2, "expected 2, got %u\n", count); hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 2, TRUE); - ok(hr == S_OK, "InitializeFromBitmap error %#x\n", hr); + ok(hr == S_OK, "InitializeFromBitmap error %#lx\n", hr); count = 0; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 2, "expected 2, got %u\n", count); /* without transparent color */ hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 16, FALSE); - ok(hr == S_OK, "InitializeFromBitmap error %#x\n", hr); + ok(hr == S_OK, "InitializeFromBitmap error %#lx\n", hr); type = -1; hr = IWICPalette_GetType(palette, &type); - ok(hr == S_OK, "GetType error %#x\n", hr); + ok(hr == S_OK, "GetType error %#lx\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type); count = 0; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 16, "expected 16, got %u\n", count); memset(color, 0, sizeof(color)); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[count - 1] != 0, "expected !0, got %08x\n", color[count - 1]); /* with transparent color */ hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 16, TRUE); - ok(hr == S_OK, "InitializeFromBitmap error %#x\n", hr); + ok(hr == S_OK, "InitializeFromBitmap error %#lx\n", hr); type = -1; hr = IWICPalette_GetType(palette, &type); - ok(hr == S_OK, "GetType error %#x\n", hr); + ok(hr == S_OK, "GetType error %#lx\n", hr); ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type); count = 0; hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 16, "expected 16, got %u\n", count); memset(color, 0xff, sizeof(color)); hr = IWICPalette_GetColors(palette, count, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[count - 1] == 0, "expected 0, got %08x\n", color[count - 1]); @@ -650,7 +650,7 @@ START_TEST(palette) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void **)&factory); - ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); test_custom_palette(); test_predefined_palette(); diff --git a/modules/rostests/winetests/windowscodecs/pngformat.c b/modules/rostests/winetests/windowscodecs/pngformat.c index 8c33d3b9645..ca5a220d40d 100644 --- a/modules/rostests/winetests/windowscodecs/pngformat.c +++ b/modules/rostests/winetests/windowscodecs/pngformat.c @@ -294,14 +294,14 @@ static HRESULT create_decoder(const void *image_data, UINT image_size, IWICBitma if (hr == S_OK) { hr = IWICBitmapDecoder_GetContainerFormat(*decoder, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatPng), "wrong container format %s\n", wine_dbgstr_guid(&format)); zero.QuadPart = 0; IStream_Seek (stream, zero, STREAM_SEEK_CUR, &pos); - ok(pos.QuadPart < image_size, "seek beyond the end of stream: %x%08x >= %x\n", - (UINT)(pos.QuadPart >> 32), (UINT)pos.QuadPart, image_size); + ok(pos.QuadPart < image_size, "seek beyond the end of stream: %I64x >= %x\n", + pos.QuadPart, image_size); refcount = IStream_Release(stream); ok(refcount > 0, "expected stream refcount > 0\n"); @@ -346,182 +346,182 @@ static void test_color_contexts(void) BOOL ret; hr = create_decoder(png_no_color_profile, sizeof(png_no_color_profile), &decoder); - ok(hr == S_OK, "Failed to load PNG image data %#x\n", hr); + ok(hr == S_OK, "Failed to load PNG image data %#lx\n", hr); if (hr != S_OK) return; /* global color context */ hr = IWICBitmapDecoder_GetColorContexts(decoder, 0, NULL, NULL); - ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts error %#x\n", hr); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts error %#lx\n", hr); count = 0xdeadbeef; hr = IWICBitmapDecoder_GetColorContexts(decoder, 0, NULL, &count); - ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts error %#x\n", hr); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts error %#lx\n", hr); ok(count == 0xdeadbeef, "unexpected count %u\n", count); /* frame color context */ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); count = 0xdeadbeef; hr = IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, &count); - ok(hr == S_OK, "GetColorContexts error %#x\n", hr); + ok(hr == S_OK, "GetColorContexts error %#lx\n", hr); ok(!count, "unexpected count %u\n", count); IWICBitmapFrameDecode_Release(frame); IWICBitmapDecoder_Release(decoder); hr = create_decoder(png_color_profile, sizeof(png_color_profile), &decoder); - ok(hr == S_OK, "Failed to load PNG image data %#x\n", hr); + ok(hr == S_OK, "Failed to load PNG image data %#lx\n", hr); if (hr != S_OK) return; /* global color context */ count = 0xdeadbeef; hr = IWICBitmapDecoder_GetColorContexts(decoder, 0, NULL, &count); - ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts error %#x\n", hr); + ok(hr == WINCODEC_ERR_UNSUPPORTEDOPERATION, "GetColorContexts error %#lx\n", hr); ok(count == 0xdeadbeef, "unexpected count %u\n", count); /* frame color context */ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); count = 0xdeadbeef; hr = IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, &count); - ok(hr == S_OK, "GetColorContexts error %#x\n", hr); + ok(hr == S_OK, "GetColorContexts error %#lx\n", hr); ok(count == 1, "unexpected count %u\n", count); hr = IWICImagingFactory_CreateColorContext(factory, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); hr = IWICImagingFactory_CreateColorContext(factory, &context); - ok(hr == S_OK, "CreateColorContext error %#x\n", hr); + ok(hr == S_OK, "CreateColorContext error %#lx\n", hr); hr = IWICColorContext_GetType(context, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); type = 0xdeadbeef; hr = IWICColorContext_GetType(context, &type); - ok(hr == S_OK, "GetType error %#x\n", hr); + ok(hr == S_OK, "GetType error %#lx\n", hr); ok(type == WICColorContextUninitialized, "unexpected type %u\n", type); hr = IWICColorContext_GetProfileBytes(context, 0, NULL, NULL); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetProfileBytes error %#x\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetProfileBytes error %#lx\n", hr); size = 0; hr = IWICColorContext_GetProfileBytes(context, 0, NULL, &size); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetProfileBytes error %#x\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetProfileBytes error %#lx\n", hr); ok(!size, "unexpected size %u\n", size); hr = IWICColorContext_GetExifColorSpace(context, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); colorspace = 0xdeadbeef; hr = IWICColorContext_GetExifColorSpace(context, &colorspace); - ok(hr == S_OK, "GetExifColorSpace error %#x\n", hr); + ok(hr == S_OK, "GetExifColorSpace error %#lx\n", hr); ok(colorspace == 0xffffffff, "unexpected color space %u\n", colorspace); hr = IWICColorContext_InitializeFromExifColorSpace(context, 0); - ok(hr == S_OK, "InitializeFromExifColorSpace error %#x\n", hr); + ok(hr == S_OK, "InitializeFromExifColorSpace error %#lx\n", hr); hr = IWICColorContext_InitializeFromExifColorSpace(context, 1); - ok(hr == S_OK, "InitializeFromExifColorSpace error %#x\n", hr); + ok(hr == S_OK, "InitializeFromExifColorSpace error %#lx\n", hr); hr = IWICColorContext_InitializeFromExifColorSpace(context, 2); - ok(hr == S_OK, "InitializeFromExifColorSpace error %#x\n", hr); + ok(hr == S_OK, "InitializeFromExifColorSpace error %#lx\n", hr); colorspace = 0xdeadbeef; hr = IWICColorContext_GetExifColorSpace(context, &colorspace); - ok(hr == S_OK, "GetExifColorSpace error %#x\n", hr); + ok(hr == S_OK, "GetExifColorSpace error %#lx\n", hr); ok(colorspace == 2, "unexpected color space %u\n", colorspace); size = 0; hr = IWICColorContext_GetProfileBytes(context, 0, NULL, &size); - ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetProfileBytes error %#x\n", hr); + ok(hr == WINCODEC_ERR_NOTINITIALIZED, "GetProfileBytes error %#lx\n", hr); ok(!size, "unexpected size %u\n", size); type = 0xdeadbeef; hr = IWICColorContext_GetType(context, &type); - ok(hr == S_OK, "GetType error %#x\n", hr); + ok(hr == S_OK, "GetType error %#lx\n", hr); ok(type == WICColorContextExifColorSpace, "unexpected type %u\n", type); hr = IWICBitmapFrameDecode_GetColorContexts(frame, count, &context, &count); - ok(hr == WINCODEC_ERR_WRONGSTATE, "GetColorContexts error %#x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "GetColorContexts error %#lx\n", hr); IWICColorContext_Release(context); IWICBitmapFrameDecode_Release(frame); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICImagingFactory_CreateColorContext(factory, &context); - ok(hr == S_OK, "CreateColorContext error %#x\n", hr); + ok(hr == S_OK, "CreateColorContext error %#lx\n", hr); count = 1; hr = IWICBitmapFrameDecode_GetColorContexts(frame, count, &context, &count); - ok(hr == S_OK, "GetColorContexts error %#x\n", hr); + ok(hr == S_OK, "GetColorContexts error %#lx\n", hr); hr = IWICColorContext_GetProfileBytes(context, 0, NULL, NULL); - ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#lx\n", hr); size = 0; hr = IWICColorContext_GetProfileBytes(context, 0, NULL, &size); - ok(hr == S_OK, "GetProfileBytes error %#x\n", hr); + ok(hr == S_OK, "GetProfileBytes error %#lx\n", hr); ok(size, "unexpected size %u\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); hr = IWICColorContext_GetProfileBytes(context, size, buffer, &size); - ok(hr == S_OK, "GetProfileBytes error %#x\n", hr); + ok(hr == S_OK, "GetProfileBytes error %#lx\n", hr); tmpfile = save_profile( buffer, size ); HeapFree(GetProcessHeap(), 0, buffer); type = 0xdeadbeef; hr = IWICColorContext_GetType(context, &type); - ok(hr == S_OK, "GetType error %#x\n", hr); + ok(hr == S_OK, "GetType error %#lx\n", hr); ok(type == WICColorContextProfile, "unexpected type %u\n", type); colorspace = 0xdeadbeef; hr = IWICColorContext_GetExifColorSpace(context, &colorspace); - ok(hr == S_OK, "GetExifColorSpace error %#x\n", hr); + ok(hr == S_OK, "GetExifColorSpace error %#lx\n", hr); ok(colorspace == 0xffffffff, "unexpected color space %u\n", colorspace); hr = IWICColorContext_InitializeFromExifColorSpace(context, 1); - ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromExifColorSpace error %#x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromExifColorSpace error %#lx\n", hr); if (tmpfile) { hr = IWICColorContext_InitializeFromFilename(context, NULL); - ok(hr == E_INVALIDARG, "InitializeFromFilename error %#x\n", hr); + ok(hr == E_INVALIDARG, "InitializeFromFilename error %#lx\n", hr); hr = IWICColorContext_InitializeFromFilename(context, tmpfile); - ok(hr == S_OK, "InitializeFromFilename error %#x\n", hr); + ok(hr == S_OK, "InitializeFromFilename error %#lx\n", hr); ret = DeleteFileW(tmpfile); - ok(ret, "DeleteFileW failed %u\n", GetLastError()); + ok(ret, "DeleteFileW failed %lu\n", GetLastError()); type = 0xdeadbeef; hr = IWICColorContext_GetType(context, &type); - ok(hr == S_OK, "GetType error %#x\n", hr); + ok(hr == S_OK, "GetType error %#lx\n", hr); ok(type == WICColorContextProfile, "unexpected type %u\n", type); colorspace = 0xdeadbeef; hr = IWICColorContext_GetExifColorSpace(context, &colorspace); - ok(hr == S_OK, "GetExifColorSpace error %#x\n", hr); + ok(hr == S_OK, "GetExifColorSpace error %#lx\n", hr); ok(colorspace == 0xffffffff, "unexpected color space %u\n", colorspace); hr = IWICColorContext_InitializeFromExifColorSpace(context, 1); - ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromExifColorSpace error %#x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromExifColorSpace error %#lx\n", hr); size = 0; hr = IWICColorContext_GetProfileBytes(context, 0, NULL, &size); - ok(hr == S_OK, "GetProfileBytes error %#x\n", hr); + ok(hr == S_OK, "GetProfileBytes error %#lx\n", hr); ok(size, "unexpected size %u\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); hr = IWICColorContext_GetProfileBytes(context, size, buffer, &size); - ok(hr == S_OK, "GetProfileBytes error %#x\n", hr); + ok(hr == S_OK, "GetProfileBytes error %#lx\n", hr); HeapFree(GetProcessHeap(), 0, buffer); HeapFree(GetProcessHeap(), 0, tmpfile); @@ -562,28 +562,28 @@ static void test_png_palette(void) char *buf; hr = create_decoder(png_PLTE_tRNS, sizeof(png_PLTE_tRNS), &decoder); - ok(hr == S_OK, "Failed to load PNG image data %#x\n", hr); + ok(hr == S_OK, "Failed to load PNG image data %#lx\n", hr); if (hr != S_OK) return; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat1bppIndexed), "got wrong format %s\n", wine_dbgstr_guid(&format)); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 2, "expected 2, got %u\n", count); hr = IWICPalette_GetColors(palette, 256, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff010203, "expected 0xff010203, got %#x\n", color[0]); ok(color[1] == 0x00040506, "expected 0x00040506, got %#x\n", color[1]); @@ -593,21 +593,21 @@ static void test_png_palette(void) IWICBitmapDecoder_Release(decoder); hr = create_decoder(png_gray_tRNS, sizeof(png_gray_tRNS), &decoder); - ok(hr == S_OK, "Failed to load PNG image data %#x\n", hr); + ok(hr == S_OK, "Failed to load PNG image data %#lx\n", hr); if (hr != S_OK) return; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat64bppRGBA), "got wrong format %s\n", wine_dbgstr_guid(&format)); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); - ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "CopyPalette error %#x\n", hr); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "CopyPalette error %#lx\n", hr); IWICPalette_Release(palette); IWICBitmapFrameDecode_Release(frame); @@ -619,28 +619,28 @@ static void test_png_palette(void) buf[24] = 8; /* override bit depth */ hr = create_decoder(buf, sizeof(png_gray_tRNS), &decoder); - ok(hr == S_OK, "Failed to load PNG image data %#x\n", hr); + ok(hr == S_OK, "Failed to load PNG image data %#lx\n", hr); if (hr != S_OK) return; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), "got wrong format %s\n", wine_dbgstr_guid(&format)); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 256, "expected 256, got %u\n", count); hr = IWICPalette_GetColors(palette, 256, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0x00000000, "expected 0x00000000, got %#x\n", color[0]); ok(color[1] == 0xff010101, "expected 0xff010101, got %#x\n", color[1]); @@ -813,18 +813,18 @@ static void test_color_formats(void) hr = create_decoder(buf, sizeof(buf), &decoder); if (!is_valid_png_type_depth(td[i].color_type, td[i].bit_depth, TRUE)) - ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#x\n", i, hr); + ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#lx\n", i, hr); else -todo_wine_if(td[i].todo_load) - ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#x\n", i, td[i].color_type, td[i].bit_depth, hr); + todo_wine_if(td[i].todo_load) + ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#lx\n", i, td[i].color_type, td[i].bit_depth, hr); if (hr != S_OK) goto next_1; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); -todo_wine_if(td[i].todo) + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); + todo_wine_if(td[i].todo) ok(IsEqualGUID(&format, td[i].format_PLTE_tRNS), "PLTE+tRNS: expected %s, got %s (type %d, bpp %d)\n", wine_dbgstr_guid(td[i].format_PLTE_tRNS), wine_dbgstr_guid(&format), td[i].color_type, td[i].bit_depth); @@ -841,17 +841,17 @@ next_1: hr = create_decoder(buf, sizeof(buf), &decoder); if (!is_valid_png_type_depth(td[i].color_type, td[i].bit_depth, TRUE)) - ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#x\n", i, hr); + ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#lx\n", i, hr); else -todo_wine_if(td[i].todo_load) - ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#x\n", i, td[i].color_type, td[i].bit_depth, hr); + todo_wine_if(td[i].todo_load) + ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#lx\n", i, td[i].color_type, td[i].bit_depth, hr); if (hr != S_OK) goto next_2; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, td[i].format_PLTE), "PLTE: expected %s, got %s (type %d, bpp %d)\n", wine_dbgstr_guid(td[i].format_PLTE), wine_dbgstr_guid(&format), td[i].color_type, td[i].bit_depth); @@ -869,17 +869,17 @@ next_2: hr = create_decoder(buf, sizeof(buf), &decoder); if (!is_valid_png_type_depth(td[i].color_type, td[i].bit_depth, FALSE)) - ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#x\n", i, hr); + ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#lx\n", i, hr); else -todo_wine_if(td[i].todo_load) - ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#x\n", i, td[i].color_type, td[i].bit_depth, hr); + todo_wine_if(td[i].todo_load) + ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#lx\n", i, td[i].color_type, td[i].bit_depth, hr); if (hr != S_OK) goto next_3; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, td[i].format), "expected %s, got %s (type %d, bpp %d)\n", wine_dbgstr_guid(td[i].format), wine_dbgstr_guid(&format), td[i].color_type, td[i].bit_depth); @@ -896,18 +896,18 @@ next_3: hr = create_decoder(buf, sizeof(buf), &decoder); if (!is_valid_png_type_depth(td[i].color_type, td[i].bit_depth, FALSE)) - ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#x\n", i, hr); + ok(hr == WINCODEC_ERR_UNKNOWNIMAGEFORMAT, "%d: wrong error %#lx\n", i, hr); else -todo_wine_if(td[i].todo_load) - ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#x\n", i, td[i].color_type, td[i].bit_depth, hr); + todo_wine_if(td[i].todo_load) + ok(hr == S_OK, "%d: Failed to load PNG image data (type %d, bpp %d) %#lx\n", i, td[i].color_type, td[i].bit_depth, hr); if (hr != S_OK) continue; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); -todo_wine_if(td[i].todo) + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); + todo_wine_if(td[i].todo) ok(IsEqualGUID(&format, td[i].format_PLTE_tRNS), "tRNS: expected %s, got %s (type %d, bpp %d)\n", wine_dbgstr_guid(td[i].format_PLTE_tRNS), wine_dbgstr_guid(&format), td[i].color_type, td[i].bit_depth); @@ -922,6 +922,34 @@ todo_wine_if(td[i].todo) #undef PNG_COLOR_TYPE_GRAY_ALPHA #undef PNG_COLOR_TYPE_RGB_ALPHA +/* 1 bpp 1x1 pixel PNG image with 8 MiB comment */ +static const char png_8M_tEXt_start[] = { + 0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a, + 0x00,0x00,0x00,0x0d,'I','H','D','R',0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x37,0x6e,0xf9,0x24, + 0x00,0x80,0x00,0x08,'t','E','X','t','C','o','m','m','e','n','t',0x00 /* ,[0x800030]=0x00,0x1e,0x13,0xe2,0xc7 */ +}; +static const char png_8M_tEXt_end[] = { + /* 0x00,0x80,0x00,0x08,'t','E','X','t','C','o','m','m','e','n','t',0x00,[0x800030]=0x00, */ 0x1e,0x13,0xe2,0xc7, + 0x00,0x00,0x00,0x0c,'I','D','A','T',0x78,0x9c,0x63,0x68,0x00,0x00,0x00,0x82,0x00,0x81,0x77,0xcd,0x72,0xb6, + 0x00,0x00,0x00,0x00,'I','E','N','D',0xae,0x42,0x60,0x82 +}; + +static void test_chunk_size(void) +{ + static char png_8M_tEXt[sizeof(png_8M_tEXt_start) + 0x800000 + sizeof(png_8M_tEXt_end)] = {0}; + HRESULT hr; + IWICBitmapDecoder *decoder; + + memcpy(png_8M_tEXt, png_8M_tEXt_start, sizeof(png_8M_tEXt_start)); + memcpy(png_8M_tEXt + sizeof(png_8M_tEXt) - sizeof(png_8M_tEXt_end), png_8M_tEXt_end, sizeof(png_8M_tEXt_end)); + + hr = create_decoder(png_8M_tEXt, sizeof(png_8M_tEXt), &decoder); + ok(hr == S_OK, "Failed to load PNG image data %#lx\n", hr); + if (hr != S_OK) return; + + IWICBitmapDecoder_Release(decoder); +} + START_TEST(pngformat) { HRESULT hr; @@ -929,12 +957,13 @@ START_TEST(pngformat) CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void **)&factory); - ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); if (FAILED(hr)) return; test_color_contexts(); test_png_palette(); test_color_formats(); + test_chunk_size(); IWICImagingFactory_Release(factory); CoUninitialize(); diff --git a/modules/rostests/winetests/windowscodecs/propertybag.c b/modules/rostests/winetests/windowscodecs/propertybag.c index fd57073d912..1e0baf48052 100644 --- a/modules/rostests/winetests/windowscodecs/propertybag.c +++ b/modules/rostests/winetests/windowscodecs/propertybag.c @@ -41,36 +41,36 @@ static void test_propertybag_getpropertyinfo(IPropertyBag2 *property, ULONG expe /* iProperty: Out of bounce */ hr = IPropertyBag2_GetPropertyInfo(property, expected_count, 1, pb, &out_count); ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, - "GetPropertyInfo handled iProperty out of bounce wrong, hr=%x\n", hr); + "GetPropertyInfo handled iProperty out of bounce wrong, hr=%lx\n", hr); /* cProperty: Out of bounce */ hr = IPropertyBag2_GetPropertyInfo(property, 0, expected_count+1, pb, &out_count); ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, - "GetPropertyInfo handled cProperty out of bounce wrong, hr=%x\n", hr); + "GetPropertyInfo handled cProperty out of bounce wrong, hr=%lx\n", hr); /* GetPropertyInfo can be called for zero items on Windows 8 but not on Windows 7 (wine behaves like Win8) */ if (expected_count == 0) return; hr = IPropertyBag2_GetPropertyInfo(property, 0, expected_count, pb, &out_count); - ok(hr == S_OK, "GetPropertyInfo failed, hr=%x\n", hr); + ok(hr == S_OK, "GetPropertyInfo failed, hr=%lx\n", hr); if (FAILED(hr)) return; ok(expected_count == out_count, - "GetPropertyInfo returned unexpected property count, %i != %i)\n", + "GetPropertyInfo returned unexpected property count, %li != %li)\n", expected_count, out_count); if(expected_count != 2) return; ok(pb[0].vt == VT_UI1, "Invalid variant type, pb[0].vt=%x\n", pb[0].vt); - ok(pb[0].dwType == PROPBAG2_TYPE_DATA, "Invalid variant type, pb[0].dwType=%x\n", pb[0].dwType); + ok(pb[0].dwType == PROPBAG2_TYPE_DATA, "Invalid variant type, pb[0].dwType=%lx\n", pb[0].dwType); ok(lstrcmpW(pb[0].pstrName, wszTestProperty1) == 0, "Invalid property name, pb[0].pstrName=%s\n", wine_dbgstr_w(pb[0].pstrName)); CoTaskMemFree(pb[0].pstrName); ok(pb[1].vt == VT_R4, "Invalid variant type, pb[1].vt=%x\n", pb[1].vt); - ok(pb[1].dwType == PROPBAG2_TYPE_DATA, "Invalid variant type, pb[1].dwType=%x\n", pb[1].dwType); + ok(pb[1].dwType == PROPBAG2_TYPE_DATA, "Invalid variant type, pb[1].dwType=%lx\n", pb[1].dwType); ok(lstrcmpW(pb[1].pstrName, wszTestProperty2) == 0, "Invalid property name, pb[1].pstrName=%s\n", wine_dbgstr_w(pb[1].pstrName)); CoTaskMemFree(pb[1].pstrName); } @@ -81,15 +81,15 @@ static void test_propertybag_countproperties(IPropertyBag2 *property, ULONG expe HRESULT hr; hr = IPropertyBag2_CountProperties(property, NULL); - ok(hr == E_INVALIDARG, "CountProperties returned unexpected result, hr=%x\n", hr); + ok(hr == E_INVALIDARG, "CountProperties returned unexpected result, hr=%lx\n", hr); hr = IPropertyBag2_CountProperties(property, &count); - ok(hr == S_OK, "CountProperties failed, hr=%x\n", hr); + ok(hr == S_OK, "CountProperties failed, hr=%lx\n", hr); if (FAILED(hr)) return; - ok(count == expected_count, "CountProperties returned invalid value, count=%i\n", count); + ok(count == expected_count, "CountProperties returned invalid value, count=%li\n", count); } static void test_propertybag_read(IPropertyBag2 *property) @@ -103,17 +103,17 @@ static void test_propertybag_read(IPropertyBag2 *property) options[0].pstrName = (LPOLESTR)wszTestInvalidProperty; hr = IPropertyBag2_Read(property, 1, options, NULL, values, itm_hr); ok(hr == E_FAIL, - "Read for an unknown property did not fail with expected code, hr=%x\n", hr); + "Read for an unknown property did not fail with expected code, hr=%lx\n", hr); /* 2. One known property */ options[0].pstrName = (LPOLESTR)wszTestProperty1; itm_hr[0] = E_FAIL; hr = IPropertyBag2_Read(property, 1, options, NULL, values, itm_hr); - ok(hr == S_OK, "Read failed, hr=%x\n", hr); + ok(hr == S_OK, "Read failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { ok(itm_hr[0] == S_OK, - "Read failed, itm_hr[0]=%x\n", itm_hr[0]); + "Read failed, itm_hr[0]=%lx\n", itm_hr[0]); ok(V_VT(&values[0]) == VT_UI1, "Read failed, V_VT(&values[0])=%x\n", V_VT(&values[0])); ok(V_UNION(&values[0], bVal) == 12, @@ -128,14 +128,14 @@ static void test_propertybag_read(IPropertyBag2 *property) itm_hr[0] = E_FAIL; itm_hr[1] = E_FAIL; hr = IPropertyBag2_Read(property, 2, options, NULL, values, itm_hr); - ok(hr == S_OK, "Read failed, hr=%x\n", hr); + ok(hr == S_OK, "Read failed, hr=%lx\n", hr); if (SUCCEEDED(hr)) { - ok(itm_hr[0] == S_OK, "Read failed, itm_hr[0]=%x\n", itm_hr[0]); + ok(itm_hr[0] == S_OK, "Read failed, itm_hr[0]=%lx\n", itm_hr[0]); ok(V_VT(&values[0]) == VT_UI1, "Read failed, V_VT(&values[0])=%x\n", V_VT(&values[0])); ok(V_UNION(&values[0], bVal) == 12, "Read failed, &values[0]=%i\n", V_UNION(&values[0], bVal)); - ok(itm_hr[1] == S_OK, "Read failed, itm_hr[1]=%x\n", itm_hr[1]); + ok(itm_hr[1] == S_OK, "Read failed, itm_hr[1]=%lx\n", itm_hr[1]); ok(V_VT(&values[1]) == VT_R4, "Read failed, V_VT(&values[1])=%x\n", V_VT(&values[1])); ok(V_UNION(&values[1], fltVal) == (float)3.14, "Read failed, &values[1]=%f\n", V_UNION(&values[1], fltVal)); @@ -160,12 +160,12 @@ static void test_propertybag_read(IPropertyBag2 *property) options[2].pstrName = (LPOLESTR)wszTestProperty2; hr = IPropertyBag2_Read(property, 3, options, NULL, values, itm_hr); - ok(hr == E_FAIL, "Read failed, hr=%x\n", hr); + ok(hr == E_FAIL, "Read failed, hr=%lx\n", hr); if (hr == E_FAIL) { - ok(itm_hr[0] == S_OK, "Read error code has unexpected value, itm_hr[0]=%x\n", itm_hr[0]); - ok(itm_hr[1] == -1, "Read error code has unexpected value, itm_hr[1]=%x\n", itm_hr[1]); - ok(itm_hr[2] == -1, "Read error code has unexpected value, itm_hr[2]=%x\n", itm_hr[2]); + ok(itm_hr[0] == S_OK, "Read error code has unexpected value, itm_hr[0]=%lx\n", itm_hr[0]); + ok(itm_hr[1] == -1, "Read error code has unexpected value, itm_hr[1]=%lx\n", itm_hr[1]); + ok(itm_hr[2] == -1, "Read error code has unexpected value, itm_hr[2]=%lx\n", itm_hr[2]); ok(V_VT(&values[0]) == VT_UI1, "Read variant has unexpected type, V_VT(&values[0])=%x\n", V_VT(&values[0])); ok(V_VT(&values[1]) == VT_NULL, "Read variant has unexpected type, V_VT(&values[1])=%x\n", V_VT(&values[1])); @@ -189,14 +189,14 @@ static void test_propertybag_write(IPropertyBag2 *property) /* 1. One unknown property */ options[0].pstrName = (LPOLESTR)wszTestInvalidProperty; hr = IPropertyBag2_Write(property, 1, options, values); - ok(hr == E_FAIL, "Write for an unknown property did not fail with expected code, hr=%x\n", hr); + ok(hr == E_FAIL, "Write for an unknown property did not fail with expected code, hr=%lx\n", hr); /* 2. One property without correct type */ options[0].pstrName = (LPOLESTR)wszTestProperty1; V_VT(&values[0]) = VT_UI1; V_UNION(&values[0], bVal) = 1; hr = IPropertyBag2_Write(property, 1, options, values); - ok(hr == S_OK, "Write for one property failed, hr=%x\n", hr); + ok(hr == S_OK, "Write for one property failed, hr=%lx\n", hr); /* 3. One property with mismatching type */ options[0].pstrName = (LPOLESTR)wszTestProperty1; @@ -204,14 +204,14 @@ static void test_propertybag_write(IPropertyBag2 *property) V_UNION(&values[0], bVal) = 2; hr = IPropertyBag2_Write(property, 1, options, values); ok(hr == WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE, - "Write with mismatching type did not fail with expected code hr=%x\n", hr); + "Write with mismatching type did not fail with expected code hr=%lx\n", hr); /* 4. Reset one property to empty */ options[0].pstrName = (LPOLESTR)wszTestProperty1; VariantClear(&values[0]); hr = IPropertyBag2_Write(property, 1, options, values); ok(hr == WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE, - "Write to reset to empty value does not fail with expected code, hr=%x\n", hr); + "Write to reset to empty value does not fail with expected code, hr=%lx\n", hr); /* 5. Set two properties */ options[0].pstrName = (LPOLESTR)wszTestProperty1; @@ -221,7 +221,7 @@ static void test_propertybag_write(IPropertyBag2 *property) V_VT(&values[1]) = VT_R4; V_UNION(&values[1], fltVal) = (float)3.14; hr = IPropertyBag2_Write(property, 2, options, values); - ok(hr == S_OK, "Write for two properties failed, hr=%x\n", hr); + ok(hr == S_OK, "Write for two properties failed, hr=%lx\n", hr); } static void test_empty_propertybag(void) @@ -232,11 +232,11 @@ static void test_empty_propertybag(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICComponentFactory, (void**)&factory); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); hr = IWICComponentFactory_CreateEncoderPropertyBag(factory, NULL, 0, &property); - ok(hr == S_OK, "Creating EncoderPropertyBag failed, hr=%x\n", hr); + ok(hr == S_OK, "Creating EncoderPropertyBag failed, hr=%lx\n", hr); if (FAILED(hr)) return; test_propertybag_countproperties(property, 0); @@ -260,11 +260,11 @@ static void test_filled_propertybag(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICComponentFactory, (void**)&factory); - ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%lx\n", hr); hr = IWICComponentFactory_CreateEncoderPropertyBag(factory, opts, 2, &property); - ok(hr == S_OK, "Creating EncoderPropertyBag failed, hr=%x\n", hr); + ok(hr == S_OK, "Creating EncoderPropertyBag failed, hr=%lx\n", hr); if (FAILED(hr)) return; test_propertybag_countproperties(property, 2); diff --git a/modules/rostests/winetests/windowscodecs/stream.c b/modules/rostests/winetests/windowscodecs/stream.c index 048f1326be0..2a1b3e30928 100644 --- a/modules/rostests/winetests/windowscodecs/stream.c +++ b/modules/rostests/winetests/windowscodecs/stream.c @@ -31,8 +31,8 @@ static void _check_cur_pos(IStream *stream, ULONGLONG expected_pos, BOOL todo, u offset.QuadPart = 0; hr = IStream_Seek(stream, offset, STREAM_SEEK_CUR, &pos); - ok_(__FILE__, line)(hr == S_OK, "Failed to get current position, hr %#x.\n", hr); -todo_wine_if(todo) + ok_(__FILE__, line)(hr == S_OK, "Failed to get current position, hr %#lx.\n", hr); + todo_wine_if(todo) ok_(__FILE__, line)(pos.QuadPart == expected_pos, "Unexpected stream position %s.\n", wine_dbgstr_longlong(pos.QuadPart)); } @@ -69,12 +69,12 @@ static void test_StreamOnMemory(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&pFactory); if(FAILED(hr)) { - skip("CoCreateInstance returned with %#x, expected %#x\n", hr, S_OK); + skip("CoCreateInstance returned with %#lx, expected %#lx\n", hr, S_OK); return; } hr = IWICImagingFactory_CreateStream(pFactory, &pStream); - ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "CreateStream returned with %#lx, expected %#lx\n", hr, S_OK); if(FAILED(hr)) { skip("Failed to create stream\n"); return; @@ -82,73 +82,73 @@ static void test_StreamOnMemory(void) /* InitializeFromMemory */ hr = IWICStream_InitializeFromMemory(pStream, NULL, sizeof(Memory)); /* memory = NULL */ - ok(hr == E_INVALIDARG, "InitializeFromMemory returned with %#x, expected %#x\n", hr, E_INVALIDARG); + ok(hr == E_INVALIDARG, "InitializeFromMemory returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); hr = IWICStream_InitializeFromMemory(pStream, Memory, 0); /* size = 0 */ - ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "InitializeFromMemory returned with %#lx, expected %#lx\n", hr, S_OK); hr = IWICStream_InitializeFromMemory(pStream, Memory, sizeof(Memory)); /* stream already initialized */ - ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromMemory returned with %#x, expected %#x\n", hr, WINCODEC_ERR_WRONGSTATE); + ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromMemory returned with %#lx, expected %#lx\n", hr, WINCODEC_ERR_WRONGSTATE); /* recreate stream */ IWICStream_Release(pStream); hr = IWICImagingFactory_CreateStream(pFactory, &pStream); - ok(hr == S_OK, "CreateStream failed with %#x\n", hr); + ok(hr == S_OK, "CreateStream failed with %#lx\n", hr); hr = IWICStream_InitializeFromMemory(pStream, Memory, sizeof(Memory)); - ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "InitializeFromMemory returned with %#lx, expected %#lx\n", hr, S_OK); /* IWICStream does not maintain an independent copy of the backing memory buffer. */ memcpy(Memory, ZeroMem, sizeof(ZeroMem)); hr = IWICStream_Read(pStream, MemBuf, sizeof(ZeroMem), &uBytesRead); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == sizeof(ZeroMem), "Read %u bytes\n", uBytesRead); + ok(uBytesRead == sizeof(ZeroMem), "Read %lu bytes\n", uBytesRead); ok(memcmp(MemBuf, ZeroMem, sizeof(ZeroMem)) == 0, "Read returned invalid data!\n"); } IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL); hr = IWICStream_Write(pStream, CmpMem, sizeof(CmpMem), &uBytesWritten); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); /* Seek */ hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, &uNewPos); - ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK); - ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0); + ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK); + ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0); hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL); - ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK); LargeInt.u.HighPart = 1; LargeInt.u.LowPart = 0; uNewPos.u.HighPart = 0xdeadbeef; uNewPos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_SET, &uNewPos); - ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "Seek returned with %#x, expected %#x\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW)); - ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); + ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "Seek returned with %#lx, expected %#lx\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW)); + ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); CHECK_CUR_POS(pStream, 0); LargeInt.QuadPart = sizeof(Memory) + 10; uNewPos.u.HighPart = 0xdeadbeef; uNewPos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_SET, &uNewPos); - ok(hr == E_INVALIDARG, "Seek returned with %#x, expected %#x\n", hr, E_INVALIDARG); - ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); + ok(hr == E_INVALIDARG, "Seek returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); + ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); CHECK_CUR_POS(pStream, 0); LargeInt.QuadPart = 1; uNewPos.u.HighPart = 0xdeadbeef; uNewPos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_END, &uNewPos); - ok(hr == E_INVALIDARG, "Seek returned with %#x, expected %#x\n", hr, E_INVALIDARG); - ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); + ok(hr == E_INVALIDARG, "Seek returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); + ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); CHECK_CUR_POS(pStream, 0); LargeInt.QuadPart = -1; hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_END, &uNewPos); - ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK); - ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == sizeof(Memory) - 1, "bSeek cursor moved to position (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart); + ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK); + ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == sizeof(Memory) - 1, "bSeek cursor moved to position (%lu;%lu)\n", uNewPos.u.HighPart, uNewPos.u.LowPart); IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, &uNewPos); /* reset seek pointer */ LargeInt.QuadPart = -(LONGLONG)sizeof(Memory) - 5; @@ -156,16 +156,16 @@ static void test_StreamOnMemory(void) uNewPos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_END, &uNewPos); ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), - "Seek returned with %#x, expected %#x\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW)); - ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); + "Seek returned with %#lx, expected %#lx\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW)); + ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); CHECK_CUR_POS(pStream, 0); IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL); /* Read */ hr = IWICStream_Read(pStream, MemBuf, 12, &uBytesRead); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == 12, "Read %u bytes, expected %u\n", uBytesRead, 12); + ok(uBytesRead == 12, "Read %lu bytes, expected %u\n", uBytesRead, 12); ok(memcmp(MemBuf, CmpMem, 12) == 0, "Read returned invalid data!\n"); /* check whether the seek pointer has moved correctly */ @@ -175,18 +175,18 @@ static void test_StreamOnMemory(void) IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL); hr = IWICStream_Read(pStream, Memory, 10, &uBytesRead); /* source = dest */ - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == 10, "Read %u bytes, expected %u\n", uBytesRead, 10); + ok(uBytesRead == 10, "Read %lu bytes, expected %u\n", uBytesRead, 10); ok(memcmp(Memory, CmpMem, uBytesRead) == 0, "Read returned invalid data!\n"); } IWICStream_Seek(pStream, SeekPos, STREAM_SEEK_SET, NULL); hr = IWICStream_Read(pStream, Memory, 10, &uBytesRead); /* source and dest overlap */ - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == 10, "Read %u bytes, expected %u\n", uBytesRead, 10); + ok(uBytesRead == 10, "Read %lu bytes, expected %u\n", uBytesRead, 10); ok(memcmp(Memory, CmpMemOverlap, uBytesRead) == 0, "Read returned invalid data!\n"); } @@ -195,33 +195,33 @@ static void test_StreamOnMemory(void) IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL); hr = IWICStream_Read(pStream, Memory, sizeof(Memory) + 10, &uBytesRead); /* request too many bytes */ - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == sizeof(Memory), "Read %u bytes\n", uBytesRead); + ok(uBytesRead == sizeof(Memory), "Read %lu bytes\n", uBytesRead); ok(memcmp(Memory, CmpMem, uBytesRead) == 0, "Read returned invalid data!\n"); } hr = IWICStream_Read(pStream, NULL, 1, &uBytesRead); /* destination buffer = NULL */ - ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG); + ok(hr == E_INVALIDARG, "Read returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); hr = IWICStream_Read(pStream, MemBuf, 0, &uBytesRead); /* read 0 bytes */ - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); hr = IWICStream_Read(pStream, NULL, 0, &uBytesRead); - ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG); + ok(hr == E_INVALIDARG, "Read returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); hr = IWICStream_Read(pStream, NULL, 0, NULL); - ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG); + ok(hr == E_INVALIDARG, "Read returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); hr = IWICStream_Read(pStream, MemBuf, 1, NULL); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL); ZeroMemory(MemBuf, sizeof(MemBuf)); hr = IWICStream_Read(pStream, MemBuf, sizeof(Memory) + 10, &uBytesRead); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == sizeof(Memory), "Read %u bytes\n", uBytesRead); + ok(uBytesRead == sizeof(Memory), "Read %lu bytes\n", uBytesRead); ok(memcmp(Memory, CmpMem, 64) == 0, "Read returned invalid data!\n"); } IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL); @@ -232,9 +232,9 @@ static void test_StreamOnMemory(void) MemBuf[1] = CmpMem[1] + 1; MemBuf[2] = CmpMem[2] + 1; hr = IWICStream_Write(pStream, MemBuf, 3, &uBytesWritten); - ok(hr == S_OK, "Write returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Write returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesWritten == 3, "Wrote %u bytes, expected %u\n", uBytesWritten, 3); + ok(uBytesWritten == 3, "Wrote %lu bytes, expected %u\n", uBytesWritten, 3); ok(memcmp(MemBuf, Memory, 3) == 0, "Wrote returned invalid data!\n"); /* make sure we're writing directly */ /* check whether the seek pointer has moved correctly */ @@ -243,19 +243,19 @@ static void test_StreamOnMemory(void) IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL); hr = IWICStream_Write(pStream, MemBuf, 0, &uBytesWritten); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); /* Restore the original contents of the memory stream. */ hr = IWICStream_Write(pStream, CmpMem, sizeof(CmpMem), &uBytesWritten); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL); /* Source and destination overlap. */ hr = IWICStream_Write(pStream, Memory + 5, 10, &uBytesWritten); - ok(hr == S_OK, "Write returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Write returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesWritten == 10, "Wrote %u bytes, expected %u\n", uBytesWritten, 10); + ok(uBytesWritten == 10, "Wrote %lu bytes, expected %u\n", uBytesWritten, 10); ok(memcmp(CmpMemOverlap, Memory, sizeof(CmpMemOverlap)) == 0, "Wrote returned invalid data!\n"); } @@ -263,20 +263,20 @@ static void test_StreamOnMemory(void) uBytesWritten = 0xdeadbeef; hr = IWICStream_Write(pStream, NULL, 3, &uBytesWritten); - ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG); - ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten); + ok(hr == E_INVALIDARG, "Write returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); + ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %lu\n", uBytesWritten); CHECK_CUR_POS(pStream, 0); uBytesWritten = 0xdeadbeef; hr = IWICStream_Write(pStream, NULL, 0, &uBytesWritten); - ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG); - ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten); + ok(hr == E_INVALIDARG, "Write returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); + ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %lu\n", uBytesWritten); CHECK_CUR_POS(pStream, 0); uBytesWritten = 0xdeadbeef; hr = IWICStream_Write(pStream, CmpMem, sizeof(Memory) + 10, &uBytesWritten); - ok(hr == STG_E_MEDIUMFULL, "Write returned with %#x, expected %#x\n", hr, STG_E_MEDIUMFULL); - ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten); + ok(hr == STG_E_MEDIUMFULL, "Write returned with %#lx, expected %#lx\n", hr, STG_E_MEDIUMFULL); + ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %lu\n", uBytesWritten); CHECK_CUR_POS(pStream, 0); IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL); @@ -285,97 +285,97 @@ static void test_StreamOnMemory(void) uNewPos.u.HighPart = 0; uNewPos.u.LowPart = sizeof(Memory) + 10; hr = IWICStream_SetSize(pStream, uNewPos); - ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL); uNewPos.u.HighPart = 0; uNewPos.u.LowPart = sizeof(Memory); hr = IWICStream_SetSize(pStream, uNewPos); - ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL); uNewPos.u.HighPart = 0; uNewPos.u.LowPart = sizeof(Memory) - 10; hr = IWICStream_SetSize(pStream, uNewPos); - ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL); uNewPos.u.HighPart = 0; uNewPos.u.LowPart = 0; hr = IWICStream_SetSize(pStream, uNewPos); - ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL); uNewPos.QuadPart = -10; hr = IWICStream_SetSize(pStream, uNewPos); - ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL); /* CopyTo */ uNewPos.u.HighPart = 0; uNewPos.u.LowPart = 5; hr = IWICStream_CopyTo(pStream, NULL, uNewPos, NULL, NULL); - ok(hr == E_NOTIMPL, "CopyTo returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "CopyTo returned %#lx, expected %#lx\n", hr, E_NOTIMPL); hr = IWICImagingFactory_CreateStream(pFactory, &pBufStream); - ok(hr == S_OK, "CreateStream failed with %#x\n", hr); + ok(hr == S_OK, "CreateStream failed with %#lx\n", hr); hr = IWICStream_InitializeFromMemory(pBufStream, Memory, sizeof(Memory)); - ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "InitializeFromMemory returned with %#lx, expected %#lx\n", hr, S_OK); hr = IWICStream_CopyTo(pStream, (IStream*)pBufStream, uNewPos, NULL, NULL); - ok(hr == E_NOTIMPL, "CopyTo returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "CopyTo returned %#lx, expected %#lx\n", hr, E_NOTIMPL); IWICStream_Release(pBufStream); /* Commit */ hr = IWICStream_Commit(pStream, STGC_DEFAULT); - ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(pStream, STGC_OVERWRITE); - ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(pStream, STGC_ONLYIFCURRENT); - ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(pStream, STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE); - ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(pStream, STGC_CONSOLIDATE); - ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); /* Revert */ IWICStream_Write(pStream, &MemBuf[5], 6, NULL); hr = IWICStream_Revert(pStream); - ok(hr == E_NOTIMPL, "Revert returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "Revert returned %#lx, expected %#lx\n", hr, E_NOTIMPL); memcpy(Memory, CmpMem, sizeof(Memory)); /* LockRegion/UnlockRegion */ hr = IWICStream_LockRegion(pStream, uLargeNull, uLargeNull, 0); - ok(hr == E_NOTIMPL, "LockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "LockRegion returned %#lx, expected %#lx\n", hr, E_NOTIMPL); hr = IWICStream_UnlockRegion(pStream, uLargeNull, uLargeNull, 0); - ok(hr == E_NOTIMPL, "UnlockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "UnlockRegion returned %#lx, expected %#lx\n", hr, E_NOTIMPL); /* Stat */ hr = IWICStream_Stat(pStream, NULL, 0); - ok(hr == E_INVALIDARG, "Stat returned %#x, expected %#x\n", hr, E_INVALIDARG); + ok(hr == E_INVALIDARG, "Stat returned %#lx, expected %#lx\n", hr, E_INVALIDARG); hr = IWICStream_Stat(pStream, &Stats, 0); - ok(hr == S_OK, "Stat returned %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Stat returned %#lx, expected %#lx\n", hr, S_OK); ok(Stats.pwcsName == NULL, "Stat returned name %p, expected %p\n", Stats.pwcsName, NULL); - ok(Stats.type == STGTY_STREAM, "Stat returned type %d, expected %d\n", Stats.type, STGTY_STREAM); - ok(Stats.cbSize.u.HighPart == 0 && Stats.cbSize.u.LowPart == sizeof(Memory), "Stat returned size (%u;%u)\n", Stats.cbSize.u.HighPart, Stats.cbSize.u.LowPart); - ok(Stats.mtime.dwHighDateTime == 0 && Stats.mtime.dwLowDateTime == 0, "Stat returned mtime (%u;%u), expected (%u;%u)\n", Stats.mtime.dwHighDateTime, Stats.mtime.dwLowDateTime, 0, 0); - ok(Stats.ctime.dwHighDateTime == 0 && Stats.ctime.dwLowDateTime == 0, "Stat returned ctime (%u;%u), expected (%u;%u)\n", Stats.ctime.dwHighDateTime, Stats.ctime.dwLowDateTime, 0, 0); - ok(Stats.atime.dwHighDateTime == 0 && Stats.atime.dwLowDateTime == 0, "Stat returned atime (%u;%u), expected (%u;%u)\n", Stats.atime.dwHighDateTime, Stats.atime.dwLowDateTime, 0, 0); - ok(Stats.grfMode == 0, "Stat returned access mode %d, expected %d\n", Stats.grfMode, 0); - ok(Stats.grfLocksSupported == 0, "Stat returned supported locks %#x, expected %#x\n", Stats.grfLocksSupported, 0); - ok(Stats.grfStateBits == 0, "Stat returned state bits %#x, expected %#x\n", Stats.grfStateBits, 0); + ok(Stats.type == STGTY_STREAM, "Stat returned type %ld, expected %d\n", Stats.type, STGTY_STREAM); + ok(Stats.cbSize.u.HighPart == 0 && Stats.cbSize.u.LowPart == sizeof(Memory), "Stat returned size (%lu;%lu)\n", Stats.cbSize.u.HighPart, Stats.cbSize.u.LowPart); + ok(Stats.mtime.dwHighDateTime == 0 && Stats.mtime.dwLowDateTime == 0, "Stat returned mtime (%lu;%lu), expected (%u;%u)\n", Stats.mtime.dwHighDateTime, Stats.mtime.dwLowDateTime, 0, 0); + ok(Stats.ctime.dwHighDateTime == 0 && Stats.ctime.dwLowDateTime == 0, "Stat returned ctime (%lu;%lu), expected (%u;%u)\n", Stats.ctime.dwHighDateTime, Stats.ctime.dwLowDateTime, 0, 0); + ok(Stats.atime.dwHighDateTime == 0 && Stats.atime.dwLowDateTime == 0, "Stat returned atime (%lu;%lu), expected (%u;%u)\n", Stats.atime.dwHighDateTime, Stats.atime.dwLowDateTime, 0, 0); + ok(Stats.grfMode == 0, "Stat returned access mode %ld, expected %d\n", Stats.grfMode, 0); + ok(Stats.grfLocksSupported == 0, "Stat returned supported locks %#lx, expected %#x\n", Stats.grfLocksSupported, 0); + ok(Stats.grfStateBits == 0, "Stat returned state bits %#lx, expected %#x\n", Stats.grfStateBits, 0); /* Clone */ hr = IWICStream_Clone(pStream, (IStream**)&pBufStream); - ok(hr == E_NOTIMPL, "UnlockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "UnlockRegion returned %#lx, expected %#lx\n", hr, E_NOTIMPL); IWICStream_Release(pStream); @@ -409,27 +409,27 @@ static void test_StreamOnStreamRange(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&pFactory); if(FAILED(hr)) { - skip("CoCreateInstance returned with %#x, expected %#x\n", hr, S_OK); + skip("CoCreateInstance returned with %#lx, expected %#lx\n", hr, S_OK); return; } hr = IWICImagingFactory_CreateStream(pFactory, &pStream); - ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "CreateStream returned with %#lx, expected %#lx\n", hr, S_OK); if(FAILED(hr)) { skip("Failed to create stream\n"); return; } hr = IWICStream_InitializeFromMemory(pStream, Memory, sizeof(Memory)); - ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "InitializeFromMemory returned with %#lx, expected %#lx\n", hr, S_OK); hr = IWICImagingFactory_CreateStream(pFactory, &pSubStream); - ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "CreateStream returned with %#lx, expected %#lx\n", hr, S_OK); uNewPos.QuadPart = 20; uSize.QuadPart = 20; hr = IWICStream_InitializeFromIStreamRegion(pSubStream, (IStream*)pStream, uNewPos, uSize); - ok(hr == S_OK, "InitializeFromIStreamRegion returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "InitializeFromIStreamRegion returned with %#lx, expected %#lx\n", hr, S_OK); if(FAILED(hr)) { skip("InitializeFromIStreamRegion unimplemented\n"); IWICStream_Release(pSubStream); @@ -442,47 +442,47 @@ static void test_StreamOnStreamRange(void) /* Seek */ CHECK_CUR_POS(pStream, 0); hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_END, &uNewPos); - ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 20, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 20); - ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK); + ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 20, "Seek cursor moved to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 20); + ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK); CHECK_CUR_POS(pStream, 0); hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, &uNewPos); - ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK); - ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0); + ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK); + ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0); CHECK_CUR_POS(pStream, 0); hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); - ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK); LargeInt.u.HighPart = 1; LargeInt.u.LowPart = 0; uNewPos.u.HighPart = 0xdeadbeef; uNewPos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_SET, &uNewPos); - ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#x, expected %#x\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE); - ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); + ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#lx, expected %#lx\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE); + ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); CHECK_CUR_POS(pStream, 0); LargeInt.QuadPart = 30; uNewPos.u.HighPart = 0xdeadbeef; uNewPos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_SET, &uNewPos); - ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#x, expected %#x\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE); - ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); + ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#lx, expected %#lx\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE); + ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); CHECK_CUR_POS(pStream, 0); LargeInt.QuadPart = 1; uNewPos.u.HighPart = 0xdeadbeef; uNewPos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_END, &uNewPos); - ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#x, expected %#x\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE); - ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); + ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#lx, expected %#lx\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE); + ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); CHECK_CUR_POS(pStream, 0); LargeInt.QuadPart = -1; hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_END, &uNewPos); - ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK); - ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 19, "bSeek cursor moved to position (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart); + ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK); + ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 19, "bSeek cursor moved to position (%lu;%lu)\n", uNewPos.u.HighPart, uNewPos.u.LowPart); CHECK_CUR_POS(pStream, 0); IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, &uNewPos); /* reset seek pointer */ @@ -491,17 +491,17 @@ static void test_StreamOnStreamRange(void) uNewPos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_END, &uNewPos); ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, - "Seek returned with %#x, expected %#x\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW)); - ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); + "Seek returned with %#lx, expected %#lx\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW)); + ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef); CHECK_CUR_POS(pStream, 0); IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); /* Read */ hr = IWICStream_Read(pSubStream, MemBuf, 12, &uBytesRead); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == 12, "Read %u bytes, expected %u\n", uBytesRead, 12); + ok(uBytesRead == 12, "Read %lu bytes, expected %u\n", uBytesRead, 12); ok(memcmp(MemBuf, CmpMem+20, 12) == 0, "Read returned invalid data!\n"); /* check whether the seek pointer has moved correctly */ @@ -512,9 +512,9 @@ static void test_StreamOnStreamRange(void) IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); hr = IWICStream_Read(pSubStream, Memory, 10, &uBytesRead); /* source = dest */ - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == 10, "Read %u bytes, expected %u\n", uBytesRead, 10); + ok(uBytesRead == 10, "Read %lu bytes, expected %u\n", uBytesRead, 10); ok(memcmp(Memory, CmpMem+20, uBytesRead) == 0, "Read returned invalid data!\n"); } CHECK_CUR_POS(pStream, 0); @@ -522,9 +522,9 @@ static void test_StreamOnStreamRange(void) IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); hr = IWICStream_Read(pSubStream, Memory, 30, &uBytesRead); /* request too many bytes */ - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == 20, "Read %u bytes\n", uBytesRead); + ok(uBytesRead == 20, "Read %lu bytes\n", uBytesRead); ok(memcmp(Memory, CmpMem+20, uBytesRead) == 0, "Read returned invalid data!\n"); } CHECK_CUR_POS(pStream, 0); @@ -532,29 +532,29 @@ static void test_StreamOnStreamRange(void) IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); uBytesRead = 0xdeadbeef; hr = IWICStream_Read(pSubStream, NULL, 1, &uBytesRead); /* destination buffer = NULL */ - ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG); - ok(uBytesRead == 0xdeadbeef, "Expected uBytesRead to be unchanged, got %u\n", uBytesRead); + ok(hr == E_INVALIDARG, "Read returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); + ok(uBytesRead == 0xdeadbeef, "Expected uBytesRead to be unchanged, got %lu\n", uBytesRead); hr = IWICStream_Read(pSubStream, MemBuf, 0, &uBytesRead); /* read 0 bytes */ - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); uBytesRead = 0xdeadbeef; hr = IWICStream_Read(pSubStream, NULL, 0, &uBytesRead); - ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG); - ok(uBytesRead == 0xdeadbeef, "Expected uBytesRead to be unchanged, got %u\n", uBytesRead); + ok(hr == E_INVALIDARG, "Read returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); + ok(uBytesRead == 0xdeadbeef, "Expected uBytesRead to be unchanged, got %lu\n", uBytesRead); hr = IWICStream_Read(pSubStream, NULL, 0, NULL); - ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG); + ok(hr == E_INVALIDARG, "Read returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); hr = IWICStream_Read(pSubStream, MemBuf, 1, NULL); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); ZeroMemory(MemBuf, sizeof(MemBuf)); hr = IWICStream_Read(pSubStream, MemBuf, 30, &uBytesRead); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == 20, "Read %u bytes\n", uBytesRead); + ok(uBytesRead == 20, "Read %lu bytes\n", uBytesRead); ok(memcmp(Memory, CmpMem+20, 20) == 0, "Read returned invalid data!\n"); } IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); @@ -565,9 +565,9 @@ static void test_StreamOnStreamRange(void) MemBuf[1] = CmpMem[1] + 1; MemBuf[2] = CmpMem[2] + 1; hr = IWICStream_Write(pSubStream, MemBuf, 3, &uBytesWritten); - ok(hr == S_OK, "Write returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Write returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesWritten == 3, "Wrote %u bytes, expected %u\n", uBytesWritten, 3); + ok(uBytesWritten == 3, "Wrote %lu bytes, expected %u\n", uBytesWritten, 3); ok(memcmp(MemBuf, Memory+20, 3) == 0, "Wrote returned invalid data!\n"); /* make sure we're writing directly */ /* check whether the seek pointer has moved correctly */ @@ -577,25 +577,25 @@ static void test_StreamOnStreamRange(void) IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); hr = IWICStream_Write(pSubStream, MemBuf, 0, &uBytesWritten); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); uBytesWritten = 0xdeadbeef; hr = IWICStream_Write(pSubStream, NULL, 3, &uBytesWritten); - ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG); - ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten); + ok(hr == E_INVALIDARG, "Write returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); + ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %lu\n", uBytesWritten); CHECK_CUR_POS(pSubStream, 0); CHECK_CUR_POS(pStream, 0); uBytesWritten = 0xdeadbeef; hr = IWICStream_Write(pSubStream, NULL, 0, &uBytesWritten); - ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG); - ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten); + ok(hr == E_INVALIDARG, "Write returned with %#lx, expected %#lx\n", hr, E_INVALIDARG); + ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %lu\n", uBytesWritten); CHECK_CUR_POS(pSubStream, 0); CHECK_CUR_POS(pStream, 0); hr = IWICStream_Write(pSubStream, CmpMem, 30, &uBytesWritten); - ok(hr == S_OK, "Write returned with %#x, expected %#x\n", hr, STG_E_MEDIUMFULL); - ok(uBytesWritten == 20, "Wrote %u bytes, expected %u\n", uBytesWritten, 0); + ok(hr == S_OK, "Write returned with %#lx, expected %#lx\n", hr, STG_E_MEDIUMFULL); + ok(uBytesWritten == 20, "Wrote %lu bytes, expected %u\n", uBytesWritten, 0); CHECK_CUR_POS(pSubStream, uBytesWritten); CHECK_CUR_POS(pStream, 0); IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); @@ -605,94 +605,94 @@ static void test_StreamOnStreamRange(void) uNewPos.u.HighPart = 0; uNewPos.u.LowPart = sizeof(Memory) + 10; hr = IWICStream_SetSize(pSubStream, uNewPos); - ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL); uNewPos.u.HighPart = 0; uNewPos.u.LowPart = sizeof(Memory); hr = IWICStream_SetSize(pSubStream, uNewPos); - ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL); uNewPos.u.HighPart = 0; uNewPos.u.LowPart = sizeof(Memory) - 10; hr = IWICStream_SetSize(pSubStream, uNewPos); - ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL); uNewPos.u.HighPart = 0; uNewPos.u.LowPart = 0; hr = IWICStream_SetSize(pSubStream, uNewPos); - ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL); uNewPos.QuadPart = -10; hr = IWICStream_SetSize(pSubStream, uNewPos); - ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL); /* CopyTo */ uNewPos.u.HighPart = 0; uNewPos.u.LowPart = 30; hr = IWICStream_CopyTo(pSubStream, NULL, uNewPos, NULL, NULL); - ok(hr == E_NOTIMPL, "CopyTo returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "CopyTo returned %#lx, expected %#lx\n", hr, E_NOTIMPL); hr = CreateStreamOnHGlobal(NULL, TRUE, &CopyStream); - ok(hr == S_OK, "CreateStream failed with %#x\n", hr); + ok(hr == S_OK, "CreateStream failed with %#lx\n", hr); hr = IWICStream_CopyTo(pSubStream, CopyStream, uNewPos, NULL, NULL); - ok(hr == E_NOTIMPL, "CopyTo returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "CopyTo returned %#lx, expected %#lx\n", hr, E_NOTIMPL); IStream_Release(CopyStream); /* Commit */ hr = IWICStream_Commit(pSubStream, STGC_DEFAULT); - ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(pSubStream, STGC_OVERWRITE); - ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(pSubStream, STGC_ONLYIFCURRENT); - ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(pSubStream, STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE); - ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(pSubStream, STGC_CONSOLIDATE); - ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); /* Revert */ IWICStream_Write(pSubStream, &MemBuf[5], 6, NULL); hr = IWICStream_Revert(pSubStream); - ok(hr == E_NOTIMPL, "Revert returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "Revert returned %#lx, expected %#lx\n", hr, E_NOTIMPL); memcpy(Memory, CmpMem, sizeof(Memory)); /* LockRegion/UnlockRegion */ hr = IWICStream_LockRegion(pSubStream, uLargeNull, uLargeNull, 0); - ok(hr == E_NOTIMPL, "LockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "LockRegion returned %#lx, expected %#lx\n", hr, E_NOTIMPL); hr = IWICStream_UnlockRegion(pSubStream, uLargeNull, uLargeNull, 0); - ok(hr == E_NOTIMPL, "UnlockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "UnlockRegion returned %#lx, expected %#lx\n", hr, E_NOTIMPL); /* Stat */ hr = IWICStream_Stat(pSubStream, NULL, 0); - ok(hr == E_INVALIDARG, "Stat returned %#x, expected %#x\n", hr, E_INVALIDARG); + ok(hr == E_INVALIDARG, "Stat returned %#lx, expected %#lx\n", hr, E_INVALIDARG); hr = IWICStream_Stat(pSubStream, &Stats, 0); - ok(hr == S_OK, "Stat returned %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Stat returned %#lx, expected %#lx\n", hr, S_OK); ok(Stats.pwcsName == NULL, "Stat returned name %p, expected %p\n", Stats.pwcsName, NULL); - ok(Stats.type == STGTY_STREAM, "Stat returned type %d, expected %d\n", Stats.type, STGTY_STREAM); - ok(Stats.cbSize.u.HighPart == 0 && Stats.cbSize.u.LowPart == 20, "Stat returned size (%u;%u)\n", Stats.cbSize.u.HighPart, Stats.cbSize.u.LowPart); - ok(Stats.mtime.dwHighDateTime == 0 && Stats.mtime.dwLowDateTime == 0, "Stat returned mtime (%u;%u), expected (%u;%u)\n", Stats.mtime.dwHighDateTime, Stats.mtime.dwLowDateTime, 0, 0); - ok(Stats.ctime.dwHighDateTime == 0 && Stats.ctime.dwLowDateTime == 0, "Stat returned ctime (%u;%u), expected (%u;%u)\n", Stats.ctime.dwHighDateTime, Stats.ctime.dwLowDateTime, 0, 0); - ok(Stats.atime.dwHighDateTime == 0 && Stats.atime.dwLowDateTime == 0, "Stat returned atime (%u;%u), expected (%u;%u)\n", Stats.atime.dwHighDateTime, Stats.atime.dwLowDateTime, 0, 0); - ok(Stats.grfMode == 0, "Stat returned access mode %d, expected %d\n", Stats.grfMode, 0); - ok(Stats.grfLocksSupported == 0, "Stat returned supported locks %#x, expected %#x\n", Stats.grfLocksSupported, 0); - ok(Stats.grfStateBits == 0, "Stat returned state bits %#x, expected %#x\n", Stats.grfStateBits, 0); + ok(Stats.type == STGTY_STREAM, "Stat returned type %ld, expected %d\n", Stats.type, STGTY_STREAM); + ok(Stats.cbSize.u.HighPart == 0 && Stats.cbSize.u.LowPart == 20, "Stat returned size (%lu;%lu)\n", Stats.cbSize.u.HighPart, Stats.cbSize.u.LowPart); + ok(Stats.mtime.dwHighDateTime == 0 && Stats.mtime.dwLowDateTime == 0, "Stat returned mtime (%lu;%lu), expected (%u;%u)\n", Stats.mtime.dwHighDateTime, Stats.mtime.dwLowDateTime, 0, 0); + ok(Stats.ctime.dwHighDateTime == 0 && Stats.ctime.dwLowDateTime == 0, "Stat returned ctime (%lu;%lu), expected (%u;%u)\n", Stats.ctime.dwHighDateTime, Stats.ctime.dwLowDateTime, 0, 0); + ok(Stats.atime.dwHighDateTime == 0 && Stats.atime.dwLowDateTime == 0, "Stat returned atime (%lu;%lu), expected (%u;%u)\n", Stats.atime.dwHighDateTime, Stats.atime.dwLowDateTime, 0, 0); + ok(Stats.grfMode == 0, "Stat returned access mode %ld, expected %d\n", Stats.grfMode, 0); + ok(Stats.grfLocksSupported == 0, "Stat returned supported locks %#lx, expected %#x\n", Stats.grfLocksSupported, 0); + ok(Stats.grfStateBits == 0, "Stat returned state bits %#lx, expected %#x\n", Stats.grfStateBits, 0); /* Clone */ hr = IWICStream_Clone(pSubStream, &CopyStream); - ok(hr == E_NOTIMPL, "Clone returned %#x, expected %#x\n", hr, E_NOTIMPL); + ok(hr == E_NOTIMPL, "Clone returned %#lx, expected %#lx\n", hr, E_NOTIMPL); IWICStream_Release(pSubStream); @@ -700,30 +700,30 @@ static void test_StreamOnStreamRange(void) /* Recreate, this time larger than the original. */ hr = IWICImagingFactory_CreateStream(pFactory, &pSubStream); - ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "CreateStream returned with %#lx, expected %#lx\n", hr, S_OK); uNewPos.QuadPart = 48; uSize.QuadPart = 32; hr = IWICStream_InitializeFromIStreamRegion(pSubStream, (IStream*)pStream, uNewPos, uSize); - ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "InitializeFromMemory returned with %#lx, expected %#lx\n", hr, S_OK); hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_END, &uNewPos); - ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK); - ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 16, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 16); + ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK); + ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 16, "Seek cursor moved to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 16); IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); hr = IWICStream_Read(pSubStream, Memory, 48, &uBytesRead); - ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK); + ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK); if(SUCCEEDED(hr)) { - ok(uBytesRead == 16, "Read %u bytes\n", uBytesRead); + ok(uBytesRead == 16, "Read %lu bytes\n", uBytesRead); ok(memcmp(Memory, CmpMem+48, uBytesRead) == 0, "Read returned invalid data!\n"); } IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL); uBytesWritten = 0xdeadbeef; hr = IWICStream_Write(pSubStream, CmpMem, 32, &uBytesWritten); - ok(hr == STG_E_MEDIUMFULL, "Write returned with %#x, expected %#x\n", hr, STG_E_MEDIUMFULL); - ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten); + ok(hr == STG_E_MEDIUMFULL, "Write returned with %#lx, expected %#lx\n", hr, STG_E_MEDIUMFULL); + ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %lu\n", uBytesWritten); CHECK_CUR_POS(pSubStream, 0); CHECK_CUR_POS(pStream, 0); @@ -759,49 +759,49 @@ static void test_StreamOnIStream(void) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void **)&factory); - ok(hr == S_OK, "Failed to create a factory, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create a factory, hr %#lx.\n", hr); hr = IWICImagingFactory_CreateStream(factory, &stream); - ok(hr == S_OK, "Failed to create a stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create a stream, hr %#lx.\n", hr); hr = IWICStream_InitializeFromMemory(stream, memory, sizeof(memory)); - ok(hr == S_OK, "Failed to initialize stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to initialize stream, hr %#lx.\n", hr); hr = IWICImagingFactory_CreateStream(factory, &substream); - ok(hr == S_OK, "Failed to create a stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create a stream, hr %#lx.\n", hr); pos.QuadPart = 1; hr = IWICStream_Seek(stream, pos, STREAM_SEEK_SET, &newpos); - ok(hr == S_OK, "Failed to set position, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to set position, hr %#lx.\n", hr); CHECK_CUR_POS(stream, 1); hr = IWICStream_InitializeFromIStream(substream, (IStream *)stream); - ok(hr == S_OK, "Failed to initialize stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to initialize stream, hr %#lx.\n", hr); CHECK_CUR_POS(substream, 1); /* Seek */ CHECK_CUR_POS(stream, 1); hr = IWICStream_Seek(substream, zero_pos, STREAM_SEEK_END, &newpos); - ok(hr == S_OK, "Failed to seek a stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to seek a stream, hr %#lx.\n", hr); ok(newpos.QuadPart == sizeof(memory), "Unexpected position %s.\n", wine_dbgstr_longlong(newpos.QuadPart)); CHECK_CUR_POS(substream, sizeof(memory)); CHECK_CUR_POS(stream, sizeof(memory)); hr = IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, &newpos); - ok(hr == S_OK, "Failed to seek a stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to seek a stream, hr %#lx.\n", hr); ok(newpos.QuadPart == 0, "Unexpected position %s.\n", wine_dbgstr_longlong(newpos.QuadPart)); CHECK_CUR_POS(stream, 0); CHECK_CUR_POS(substream, 0); hr = IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, NULL); - ok(hr == S_OK, "Failed to seek a stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to seek a stream, hr %#lx.\n", hr); pos.u.HighPart = 1; pos.u.LowPart = 0; newpos.u.HighPart = 0xdeadbeef; newpos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(substream, pos, STREAM_SEEK_SET, &newpos); - ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "Unexpected hr %#x.\n", hr); + ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "Unexpected hr %#lx.\n", hr); ok(newpos.u.HighPart == 0xdeadbeef && newpos.u.LowPart == 0xdeadbeef, "Unexpected position %s.\n", wine_dbgstr_longlong(newpos.QuadPart)); CHECK_CUR_POS(stream, 0); @@ -811,7 +811,7 @@ static void test_StreamOnIStream(void) newpos.u.HighPart = 0xdeadbeef; newpos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(substream, pos, STREAM_SEEK_SET, &newpos); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); ok(newpos.u.HighPart == 0xdeadbeef && newpos.u.LowPart == 0xdeadbeef, "Unexpected position %s.\n", wine_dbgstr_longlong(newpos.QuadPart)); CHECK_CUR_POS(stream, 0); @@ -821,7 +821,7 @@ static void test_StreamOnIStream(void) newpos.u.HighPart = 0xdeadbeef; newpos.u.LowPart = 0xdeadbeef; hr = IWICStream_Seek(substream, pos, STREAM_SEEK_END, &newpos); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); ok(newpos.u.HighPart == 0xdeadbeef && newpos.u.LowPart == 0xdeadbeef, "Unexpected position %s.\n", wine_dbgstr_longlong(newpos.QuadPart)); CHECK_CUR_POS(stream, 0); @@ -829,7 +829,7 @@ static void test_StreamOnIStream(void) pos.QuadPart = -1; hr = IWICStream_Seek(substream, pos, STREAM_SEEK_END, &newpos); - ok(hr == S_OK, "Failed to seek a stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to seek a stream, hr %#lx.\n", hr); ok(newpos.QuadPart == sizeof(memory) - 1, "Unexpected position %s.\n", wine_dbgstr_longlong(newpos.QuadPart)); CHECK_CUR_POS(stream, sizeof(memory) - 1); CHECK_CUR_POS(substream, sizeof(memory) - 1); @@ -838,8 +838,8 @@ static void test_StreamOnIStream(void) /* Read */ hr = IWICStream_Read(substream, buff, 12, &read_len); - ok(hr == S_OK, "Failed to read from stream, hr %#x.\n", hr); - ok(read_len == 12, "Unexpected read length %u.\n", read_len); + ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr); + ok(read_len == 12, "Unexpected read length %lu.\n", read_len); ok(!memcmp(buff, data, 12), "Unexpected data.\n"); CHECK_CUR_POS(substream, read_len); CHECK_CUR_POS(stream, read_len); @@ -848,39 +848,39 @@ static void test_StreamOnIStream(void) CHECK_CUR_POS(stream, 0); hr = IWICStream_Read(substream, memory, 10, &read_len); /* source = dest */ - ok(hr == S_OK, "Failed to read from stream, hr %#x.\n", hr); - ok(read_len == 10, "Unexpected read length %u.\n", read_len); + ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr); + ok(read_len == 10, "Unexpected read length %lu.\n", read_len); ok(!memcmp(memory, data, read_len), "Unexpected data.\n"); CHECK_CUR_POS(stream, 10); IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, NULL); hr = IWICStream_Read(substream, memory, 2 * sizeof(data), &read_len); /* request too many bytes */ - ok(hr == S_OK, "Failed to read from stream, hr %#x.\n", hr); - ok(read_len == 64, "Unexpected read length %u.\n", read_len); + ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr); + ok(read_len == 64, "Unexpected read length %lu.\n", read_len); ok(!memcmp(memory, data, read_len), "Unexpected data.\n"); CHECK_CUR_POS(stream, sizeof(data)); IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, NULL); read_len = 0xdeadbeef; hr = IWICStream_Read(substream, NULL, 1, &read_len); /* destination buffer = NULL */ - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); - ok(read_len == 0xdeadbeef, "Unexpected read length %u.\n", read_len); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(read_len == 0xdeadbeef, "Unexpected read length %lu.\n", read_len); read_len = 1; hr = IWICStream_Read(substream, buff, 0, &read_len); /* read 0 bytes */ - ok(hr == S_OK, "Failed to read from stream, hr %#x.\n", hr); - ok(read_len == 0, "Unexpected read length %u.\n", read_len); + ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr); + ok(read_len == 0, "Unexpected read length %lu.\n", read_len); read_len = 0xdeadbeef; hr = IWICStream_Read(substream, NULL, 0, &read_len); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); - ok(read_len == 0xdeadbeef, "Unexpected read length %u.\n", read_len); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(read_len == 0xdeadbeef, "Unexpected read length %lu.\n", read_len); hr = IWICStream_Read(substream, NULL, 0, NULL); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICStream_Read(substream, buff, 1, NULL); - ok(hr == S_OK, "Failed to read from stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr); CHECK_CUR_POS(substream, 1); CHECK_CUR_POS(stream, 1); IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, NULL); @@ -890,27 +890,27 @@ static void test_StreamOnIStream(void) buff[i] = data[i] + 1; hr = IWICStream_Write(substream, buff, 3, &written); - ok(hr == S_OK, "Failed to write to stream, hr %#x.\n", hr); - ok(written == 3, "Unexpected written length %u.\n", written); + ok(hr == S_OK, "Failed to write to stream, hr %#lx.\n", hr); + ok(written == 3, "Unexpected written length %lu.\n", written); ok(!memcmp(buff, memory, 3), "Unexpected stream data.\n"); CHECK_CUR_POS(substream, written); CHECK_CUR_POS(stream, written); IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, NULL); hr = IWICStream_Write(substream, buff, 0, &written); - ok(hr == S_OK, "Failed to write to stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to write to stream, hr %#lx.\n", hr); written = 0xdeadbeef; hr = IWICStream_Write(substream, NULL, 3, &written); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); - ok(written == 0xdeadbeef, "Unexpected written length %u.\n", written); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(written == 0xdeadbeef, "Unexpected written length %lu.\n", written); CHECK_CUR_POS(substream, 0); CHECK_CUR_POS(stream, 0); written = 0xdeadbeef; hr = IWICStream_Write(substream, NULL, 0, &written); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); - ok(written == 0xdeadbeef, "Unexpected written length %u.\n", written); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(written == 0xdeadbeef, "Unexpected written length %lu.\n", written); CHECK_CUR_POS(substream, 0); CHECK_CUR_POS(stream, 0); @@ -918,90 +918,90 @@ static void test_StreamOnIStream(void) newpos.u.HighPart = 0; newpos.u.LowPart = sizeof(memory) + 10; hr = IWICStream_SetSize(substream, newpos); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); newpos.u.HighPart = 0; newpos.u.LowPart = sizeof(memory); hr = IWICStream_SetSize(substream, newpos); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); newpos.u.HighPart = 0; newpos.u.LowPart = sizeof(memory) - 10; hr = IWICStream_SetSize(substream, newpos); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); newpos.QuadPart = 0; hr = IWICStream_SetSize(substream, newpos); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); newpos.QuadPart = -10; hr = IWICStream_SetSize(substream, newpos); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); /* CopyTo */ newpos.u.HighPart = 0; newpos.u.LowPart = 30; hr = IWICStream_CopyTo(substream, NULL, newpos, NULL, NULL); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); hr = CreateStreamOnHGlobal(NULL, TRUE, ©_stream); - ok(hr == S_OK, "Failed to create a stream, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to create a stream, hr %#lx.\n", hr); hr = IWICStream_CopyTo(substream, copy_stream, newpos, NULL, NULL); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); IStream_Release(copy_stream); /* Commit */ hr = IWICStream_Commit(substream, STGC_DEFAULT); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(substream, STGC_OVERWRITE); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(substream, STGC_ONLYIFCURRENT); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(substream, STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); hr = IWICStream_Commit(substream, STGC_CONSOLIDATE); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr); /* Revert */ IWICStream_Write(substream, buff + 5, 6, NULL); hr = IWICStream_Revert(substream); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); memcpy(memory, data, sizeof(memory)); /* LockRegion/UnlockRegion */ hr = IWICStream_LockRegion(substream, uzero, uzero, 0); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); hr = IWICStream_UnlockRegion(substream, uzero, uzero, 0); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); /* Stat */ hr = IWICStream_Stat(substream, NULL, 0); - ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IWICStream_Stat(substream, &stats, 0); - ok(hr == S_OK, "Failed to get stream stats, hr %#x.\n", hr); + ok(hr == S_OK, "Failed to get stream stats, hr %#lx.\n", hr); ok(stats.pwcsName == NULL, "Unexpected name %p.\n", stats.pwcsName); - ok(stats.type == STGTY_STREAM, "Unexpected type %d.\n", stats.type); + ok(stats.type == STGTY_STREAM, "Unexpected type %ld.\n", stats.type); ok(stats.cbSize.QuadPart == sizeof(data), "Unexpected size %s.\n", wine_dbgstr_longlong(stats.cbSize.QuadPart)); - ok(stats.mtime.dwHighDateTime == 0 && stats.mtime.dwLowDateTime == 0, "Unexpected mtime (%u;%u).\n", + ok(stats.mtime.dwHighDateTime == 0 && stats.mtime.dwLowDateTime == 0, "Unexpected mtime (%lu;%lu).\n", stats.mtime.dwHighDateTime, stats.mtime.dwLowDateTime); - ok(stats.ctime.dwHighDateTime == 0 && stats.ctime.dwLowDateTime == 0, "Unexpected ctime (%u;%u).\n", + ok(stats.ctime.dwHighDateTime == 0 && stats.ctime.dwLowDateTime == 0, "Unexpected ctime (%lu;%lu).\n", stats.ctime.dwHighDateTime, stats.ctime.dwLowDateTime); - ok(stats.atime.dwHighDateTime == 0 && stats.atime.dwLowDateTime == 0, "Unexpected atime (%u;%u).\n", + ok(stats.atime.dwHighDateTime == 0 && stats.atime.dwLowDateTime == 0, "Unexpected atime (%lu;%lu).\n", stats.atime.dwHighDateTime, stats.atime.dwLowDateTime); - ok(stats.grfMode == 0, "Unexpected mode %d.\n", stats.grfMode); - ok(stats.grfLocksSupported == 0, "Unexpected locks support %#x.\n", stats.grfLocksSupported); - ok(stats.grfStateBits == 0, "Unexpected state bits %#x.\n", stats.grfStateBits); + ok(stats.grfMode == 0, "Unexpected mode %ld.\n", stats.grfMode); + ok(stats.grfLocksSupported == 0, "Unexpected locks support %#lx.\n", stats.grfLocksSupported); + ok(stats.grfStateBits == 0, "Unexpected state bits %#lx.\n", stats.grfStateBits); /* Clone */ hr = IWICStream_Clone(substream, ©_stream); - ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); IWICStream_Release(substream); IWICStream_Release(stream); diff --git a/modules/rostests/winetests/windowscodecs/testlist.c b/modules/rostests/winetests/windowscodecs/testlist.c index 6ea28ad82b1..f310eba12db 100644 --- a/modules/rostests/winetests/windowscodecs/testlist.c +++ b/modules/rostests/winetests/windowscodecs/testlist.c @@ -6,6 +6,7 @@ extern void func_bitmap(void); extern void func_bmpformat(void); extern void func_converter(void); +extern void func_ddsformat(void); extern void func_gifformat(void); extern void func_icoformat(void); extern void func_info(void); @@ -16,12 +17,14 @@ extern void func_pngformat(void); extern void func_propertybag(void); extern void func_stream(void); extern void func_tiffformat(void); +extern void func_wmpformat(void); const struct test winetest_testlist[] = { { "bitmap", func_bitmap }, { "bmpformat", func_bmpformat }, { "converter", func_converter }, + { "ddsformat", func_ddsformat }, { "gifformat", func_gifformat }, { "icoformat", func_icoformat }, { "info", func_info }, @@ -32,5 +35,6 @@ const struct test winetest_testlist[] = { "propertybag", func_propertybag }, { "stream", func_stream }, { "tiffformat", func_tiffformat }, + { "wmpformat", func_wmpformat }, { 0, 0 } }; diff --git a/modules/rostests/winetests/windowscodecs/tiffformat.c b/modules/rostests/winetests/windowscodecs/tiffformat.c index 0c68904abad..9fb2ab6216c 100644 --- a/modules/rostests/winetests/windowscodecs/tiffformat.c +++ b/modules/rostests/winetests/windowscodecs/tiffformat.c @@ -32,7 +32,7 @@ static void _expect_ref(IUnknown* obj, ULONG ref, int line) ULONG rc; IUnknown_AddRef(obj); rc = IUnknown_Release(obj); - ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc); + ok_(__FILE__,line)(rc == ref, "expected refcount %ld, got %ld\n", ref, rc); } #define IFD_BYTE 1 @@ -75,11 +75,7 @@ static const struct tiff_1bpp_data BYTE pixel_data[4]; } tiff_1bpp_data = { -#ifdef WORDS_BIGENDIAN - 'M' | 'M' << 8, -#else 'I' | 'I' << 8, -#endif 42, FIELD_OFFSET(struct tiff_1bpp_data, number_of_entries), 13, @@ -115,11 +111,7 @@ static const struct tiff_8bpp_alpha BYTE pixel_data[8]; } tiff_8bpp_alpha = { -#ifdef WORDS_BIGENDIAN - 'M' | 'M' << 8, -#else 'I' | 'I' << 8, -#endif 42, FIELD_OFFSET(struct tiff_8bpp_alpha, number_of_entries), 15, @@ -158,11 +150,7 @@ static const struct tiff_8bpp_data BYTE pixel_data[4]; } tiff_8bpp_data = { -#ifdef WORDS_BIGENDIAN - 'M' | 'M' << 8, -#else 'I' | 'I' << 8, -#endif 42, FIELD_OFFSET(struct tiff_8bpp_data, number_of_entries), 14, @@ -234,11 +222,7 @@ static struct tiff_resolution_image_data BYTE pixel_data[4]; } tiff_resolution_image_data = { -#ifdef WORDS_BIGENDIAN - 'M' | 'M' << 8, -#else 'I' | 'I' << 8, -#endif 42, FIELD_OFFSET(struct tiff_resolution_image_data, number_of_entries), 13, @@ -275,11 +259,7 @@ static const struct tiff_24bpp_data BYTE pixel_data[3]; } tiff_24bpp_data = { -#ifdef WORDS_BIGENDIAN - 'M' | 'M' << 8, -#else 'I' | 'I' << 8, -#endif 42, FIELD_OFFSET(struct tiff_1bpp_data, number_of_entries), 13, @@ -315,11 +295,7 @@ static const struct tiff_4bps_bgra BYTE pixel_data[4]; } tiff_4bps_bgra = { -#ifdef WORDS_BIGENDIAN - 'M' | 'M' << 8, -#else 'I' | 'I' << 8, -#endif 42, FIELD_OFFSET(struct tiff_4bps_bgra, number_of_entries), 14, @@ -363,7 +339,7 @@ static IStream *create_stream(const void *data, int data_size) GlobalUnlock(hdata); hr = CreateStreamOnHGlobal(hdata, TRUE, &stream); - ok(hr == S_OK, "CreateStreamOnHGlobal failed, hr=%x\n", hr); + ok(hr == S_OK, "CreateStreamOnHGlobal failed, hr=%lx\n", hr); return stream; } @@ -385,13 +361,13 @@ static HRESULT create_decoder(const void *image_data, UINT image_size, IWICBitma GlobalUnlock(hmem); hr = CreateStreamOnHGlobal(hmem, TRUE, &stream); - ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr); + ok(hr == S_OK, "CreateStreamOnHGlobal error %#lx\n", hr); hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, decoder); if (hr == S_OK) { hr = IWICBitmapDecoder_GetContainerFormat(*decoder, &format); - ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); + ok(hr == S_OK, "GetContainerFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_ContainerFormatTiff), "wrong container format %s\n", wine_dbgstr_guid(&format)); @@ -402,30 +378,30 @@ static HRESULT create_decoder(const void *image_data, UINT image_size, IWICBitma return hr; } -static HRESULT get_pixelformat_info(const GUID *format, UINT *bpp, UINT *channels, BOOL *trasparency) +static HRESULT get_pixelformat_info(const GUID *format, UINT *bpp, UINT *channels, BOOL *transparency) { HRESULT hr; IWICComponentInfo *info; IWICPixelFormatInfo2 *formatinfo; hr = IWICImagingFactory_CreateComponentInfo(factory, format, &info); - ok(hr == S_OK, "CreateComponentInfo(%s) error %#x\n", wine_dbgstr_guid(format), hr); + ok(hr == S_OK, "CreateComponentInfo(%s) error %#lx\n", wine_dbgstr_guid(format), hr); if (hr == S_OK) { hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo2, (void **)&formatinfo); if (hr == S_OK) { - hr = IWICPixelFormatInfo2_SupportsTransparency(formatinfo, trasparency); - ok(hr == S_OK, "SupportsTransparency error %#x\n", hr); + hr = IWICPixelFormatInfo2_SupportsTransparency(formatinfo, transparency); + ok(hr == S_OK, "SupportsTransparency error %#lx\n", hr); IWICPixelFormatInfo2_Release(formatinfo); } hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo, (void **)&formatinfo); if (hr == S_OK) { hr = IWICPixelFormatInfo2_GetBitsPerPixel(formatinfo, bpp); - ok(hr == S_OK, "GetBitsPerPixel error %#x\n", hr); + ok(hr == S_OK, "GetBitsPerPixel error %#lx\n", hr); hr = IWICPixelFormatInfo2_GetChannelCount(formatinfo, channels); - ok(hr == S_OK, "GetChannelCount error %#x\n", hr); + ok(hr == S_OK, "GetChannelCount error %#lx\n", hr); IWICPixelFormatInfo2_Release(formatinfo); } IWICComponentInfo_Release(info); @@ -445,7 +421,7 @@ static void dump_tiff(void *buf) for (i = 0; i < count; i++) { - printf("tag %u: id %04x, type %04x, count %u, value %d", + printf("tag %u: id %04x, type %04x, count %lu, value %ld", i, tag[i].id, tag[i].type, tag[i].count, tag[i].value); if (tag[i].id == 0x102 && tag[i].count > 2) { @@ -466,22 +442,22 @@ static void test_tiff_1bpp_palette(void) GUID format; hr = create_decoder(&tiff_1bpp_data, sizeof(tiff_1bpp_data), &decoder); - ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); + ok(hr == S_OK, "Failed to load TIFF image data %#lx\n", hr); if (hr != S_OK) return; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormatBlackWhite), "got wrong format %s\n", wine_dbgstr_guid(&format)); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, - "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#x\n", hr); + "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#lx\n", hr); IWICPalette_Release(palette); IWICBitmapFrameDecode_Release(frame); @@ -501,85 +477,83 @@ static void test_QueryCapability(void) WICBitmapDecoderCapabilityCanDecodeSomeImages; DWORD capability; LARGE_INTEGER pos; - ULARGE_INTEGER cur_pos; UINT frame_count; stream = create_stream(&tiff_1bpp_data, sizeof(tiff_1bpp_data)); if (!stream) return; hr = IWICImagingFactory_CreateDecoder(factory, &GUID_ContainerFormatTiff, NULL, &decoder); - ok(hr == S_OK, "CreateDecoder error %#x\n", hr); + ok(hr == S_OK, "CreateDecoder error %#lx\n", hr); if (FAILED(hr)) return; frame_count = 0xdeadbeef; hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); - ok(hr == S_OK || broken(hr == E_POINTER) /* XP */, "GetFrameCount error %#x\n", hr); + ok(hr == S_OK || broken(hr == E_POINTER) /* XP */, "GetFrameCount error %#lx\n", hr); ok(frame_count == 0, "expected 0, got %u\n", frame_count); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == WINCODEC_ERR_FRAMEMISSING || broken(hr == E_POINTER) /* XP */, "expected WINCODEC_ERR_FRAMEMISSING, got %#x\n", hr); + ok(hr == WINCODEC_ERR_FRAMEMISSING || broken(hr == E_POINTER) /* XP */, "expected WINCODEC_ERR_FRAMEMISSING, got %#lx\n", hr); pos.QuadPart = 4; hr = IStream_Seek(stream, pos, SEEK_SET, NULL); - ok(hr == S_OK, "IStream_Seek error %#x\n", hr); + ok(hr == S_OK, "IStream_Seek error %#lx\n", hr); capability = 0xdeadbeef; hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability); - ok(hr == S_OK, "QueryCapability error %#x\n", hr); + ok(hr == S_OK, "QueryCapability error %#lx\n", hr); ok(capability == exp_caps || capability == exp_caps_xp, - "expected %#x, got %#x\n", exp_caps, capability); + "expected %#lx, got %#lx\n", exp_caps, capability); frame_count = 0xdeadbeef; hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); - ok(hr == S_OK, "GetFrameCount error %#x\n", hr); + ok(hr == S_OK, "GetFrameCount error %#lx\n", hr); ok(frame_count == 1, "expected 1, got %u\n", frame_count); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); IWICBitmapFrameDecode_Release(frame); - pos.QuadPart = 0; - hr = IStream_Seek(stream, pos, SEEK_CUR, &cur_pos); - ok(hr == S_OK, "IStream_Seek error %#x\n", hr); - ok(cur_pos.QuadPart > 4 && cur_pos.QuadPart < sizeof(tiff_1bpp_data), - "current stream pos is at %x/%x\n", cur_pos.u.LowPart, cur_pos.u.HighPart); + pos.QuadPart = 5; + hr = IStream_Seek(stream, pos, SEEK_SET, NULL); + ok(hr == S_OK, "IStream_Seek error %#lx\n", hr); hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability); - ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#lx\n", hr); hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand); - ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#lx\n", hr); IWICBitmapDecoder_Release(decoder); + /* CreateDecoderFromStream fails if seeked past the start */ hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder); -todo_wine - ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "expected WINCODEC_ERR_COMPONENTNOTFOUND, got %#x\n", hr); + todo_wine + ok(hr == WINCODEC_ERR_COMPONENTNOTFOUND, "expected WINCODEC_ERR_COMPONENTNOTFOUND, got %#lx\n", hr); if (SUCCEEDED(hr)) IWICBitmapDecoder_Release(decoder); pos.QuadPart = 0; hr = IStream_Seek(stream, pos, SEEK_SET, NULL); - ok(hr == S_OK, "IStream_Seek error %#x\n", hr); + ok(hr == S_OK, "IStream_Seek error %#lx\n", hr); hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder); - ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr); + ok(hr == S_OK, "CreateDecoderFromStream error %#lx\n", hr); frame_count = 0xdeadbeef; hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); - ok(hr == S_OK, "GetFrameCount error %#x\n", hr); + ok(hr == S_OK, "GetFrameCount error %#lx\n", hr); ok(frame_count == 1, "expected 1, got %u\n", frame_count); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); IWICBitmapFrameDecode_Release(frame); hr = IWICBitmapDecoder_Initialize(decoder, stream, WICDecodeMetadataCacheOnDemand); - ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#lx\n", hr); hr = IWICBitmapDecoder_QueryCapability(decoder, stream, &capability); - ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#x\n", hr); + ok(hr == WINCODEC_ERR_WRONGSTATE, "expected WINCODEC_ERR_WRONGSTATE, got %#lx\n", hr); IWICBitmapDecoder_Release(decoder); IStream_Release(stream); @@ -600,39 +574,39 @@ static void test_tiff_8bpp_alpha(void) 0x55,0x55,0x55,0x66,0x77,0x77,0x77,0x88 }; hr = create_decoder(&tiff_8bpp_alpha, sizeof(tiff_8bpp_alpha), &decoder); - ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); + ok(hr == S_OK, "Failed to load TIFF image data %#lx\n", hr); if (hr != S_OK) return; hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); - ok(hr == S_OK, "GetFrameCount error %#x\n", hr); + ok(hr == S_OK, "GetFrameCount error %#lx\n", hr); ok(frame_count == 1, "expected 1, got %u\n", frame_count); EXPECT_REF(decoder, 1); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); EXPECT_REF(decoder, 2); IWICBitmapDecoder_Release(decoder); hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height); - ok(hr == S_OK, "GetSize error %#x\n", hr); + ok(hr == S_OK, "GetSize error %#lx\n", hr); ok(width == 2, "expected 2, got %u\n", width); ok(height == 2, "expected 2, got %u\n", height); hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y); - ok(hr == S_OK, "GetResolution error %#x\n", hr); + ok(hr == S_OK, "GetResolution error %#lx\n", hr); ok(dpi_x == 96.0, "expected 96.0, got %f\n", dpi_x); ok(dpi_y == 96.0, "expected 96.0, got %f\n", dpi_y); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppPBGRA), "got wrong format %s\n", wine_dbgstr_guid(&format)); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, - "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#x\n", hr); + "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#lx\n", hr); IWICPalette_Release(palette); rc.X = 0; @@ -640,7 +614,7 @@ static void test_tiff_8bpp_alpha(void) rc.Width = 2; rc.Height = 2; hr = IWICBitmapFrameDecode_CopyPixels(frame, &rc, 8, sizeof(data), data); - ok(hr == S_OK, "CopyPixels error %#x\n", hr); + ok(hr == S_OK, "CopyPixels error %#lx\n", hr); for (i = 0; i < sizeof(data); i++) ok(data[i] == expected_data[i], "%u: expected %02x, got %02x\n", i, expected_data[i], data[i]); @@ -693,28 +667,28 @@ static void test_tiff_8bpp_palette(void) generate_tiff_palette(buf + FIELD_OFFSET(struct tiff_8bpp_data, palette_data), 256); hr = create_decoder(buf, sizeof(buf), &decoder); - ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); + ok(hr == S_OK, "Failed to load TIFF image data %#lx\n", hr); if (hr != S_OK) return; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), "expected GUID_WICPixelFormat8bppIndexed, got %s\n", wine_dbgstr_guid(&format)); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); - ok(hr == S_OK, "CopyPalette error %#x\n", hr); + ok(hr == S_OK, "CopyPalette error %#lx\n", hr); hr = IWICPalette_GetColorCount(palette, &count); - ok(hr == S_OK, "GetColorCount error %#x\n", hr); + ok(hr == S_OK, "GetColorCount error %#lx\n", hr); ok(count == 256, "expected 256, got %u\n", count); hr = IWICPalette_GetColors(palette, 256, color, &ret); - ok(hr == S_OK, "GetColors error %#x\n", hr); + ok(hr == S_OK, "GetColors error %#lx\n", hr); ok(ret == count, "expected %u, got %u\n", count, ret); ok(color[0] == 0xff112233, "got %#x\n", color[0]); ok(color[1] == 0xff445566, "got %#x\n", color[1]); @@ -742,14 +716,14 @@ static void test_tiff_resolution(void) tiff_resolution_image_data.entry[12].value = test_data->resolution_unit; hr = create_decoder(&tiff_resolution_image_data, sizeof(tiff_resolution_image_data), &decoder); - ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); + ok(hr == S_OK, "Failed to load TIFF image data %#lx\n", hr); if (hr != S_OK) return; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "%d: GetFrame error %#x\n", i, hr); + ok(hr == S_OK, "%d: GetFrame error %#lx\n", i, hr); hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y); - ok(hr == S_OK, "%d: GetResolution error %#x\n", i, hr); + ok(hr == S_OK, "%d: GetResolution error %#lx\n", i, hr); if (test_data->broken_dpi_x != 0) { @@ -791,29 +765,29 @@ static void test_tiff_24bpp(void) static const BYTE expected_data[] = { 0x33,0x22,0x11 }; hr = create_decoder(&tiff_24bpp_data, sizeof(tiff_24bpp_data), &decoder); - ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); + ok(hr == S_OK, "Failed to load TIFF image data %#lx\n", hr); if (hr != S_OK) return; ok(decoder != NULL, "Failed to load TIFF image data\n"); hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); - ok(hr == S_OK, "GetFrameCount error %#x\n", hr); + ok(hr == S_OK, "GetFrameCount error %#lx\n", hr); ok(count == 1, "got %u\n", count); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height); - ok(hr == S_OK, "GetSize error %#x\n", hr); + ok(hr == S_OK, "GetSize error %#lx\n", hr); ok(width == 1, "got %u\n", width); ok(height == 1, "got %u\n", height); hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y); - ok(hr == S_OK, "GetResolution error %#x\n", hr); + ok(hr == S_OK, "GetResolution error %#lx\n", hr); ok(dpi_x == 300.0, "got %f\n", dpi_x); ok(dpi_y == 300.0, "got %f\n", dpi_y); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat24bppBGR), "got wrong format %s\n", wine_dbgstr_guid(&format)); @@ -826,10 +800,10 @@ static void test_tiff_24bpp(void) rc.Height = 1; hr = IWICBitmapFrameDecode_CopyPixels(frame, &rc, stride, sizeof(data), data); if (stride < 3) - ok(hr == E_INVALIDARG, "CopyPixels(%u) should fail: %#x\n", stride, hr); + ok(hr == E_INVALIDARG, "CopyPixels(%u) should fail: %#lx\n", stride, hr); else { - ok(hr == S_OK, "CopyPixels(%u) error %#x\n", stride, hr); + ok(hr == S_OK, "CopyPixels(%u) error %#lx\n", stride, hr); for (i = 0; i < sizeof(data); i++) ok(data[i] == expected_data[i], "%u: expected %02x, got %02x\n", i, expected_data[i], data[i]); @@ -847,7 +821,7 @@ static const struct tiff_1x1_data USHORT version; ULONG dir_offset; USHORT number_of_entries; - struct IFD_entry entry[12]; + struct IFD_entry entry[13]; ULONG next_IFD; struct IFD_rational res; short palette_data[3][256]; @@ -855,14 +829,10 @@ static const struct tiff_1x1_data BYTE pixel_data[32]; } tiff_1x1_data = { -#ifdef WORDS_BIGENDIAN - 'M' | 'M' << 8, -#else 'I' | 'I' << 8, -#endif 42, FIELD_OFFSET(struct tiff_1x1_data, number_of_entries), - 12, + 13, { { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */ { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */ @@ -875,7 +845,8 @@ static const struct tiff_1x1_data { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) }, { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) }, { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */ - { 0x140, IFD_SHORT, 256*3, FIELD_OFFSET(struct tiff_1x1_data, palette_data) } /* COLORMAP */ + { 0x140, IFD_SHORT, 256*3, FIELD_OFFSET(struct tiff_1x1_data, palette_data) }, /* COLORMAP */ + { 0x152, IFD_SHORT, 1, 1 } /* EXTRASAMPLES: 1 - Associated alpha with pre-multiplied color */ }, 0, { 96, 1 }, @@ -925,21 +896,37 @@ static void test_color_formats(void) { 32, 5, 2, &GUID_WICPixelFormat32bppBGRA, bits_1bpsBGRA }; + static const struct bitmap_data data_1bpsPBGRA = + { + 32, 5, 2, &GUID_WICPixelFormat32bppPBGRA, bits_1bpsBGRA + }; static const BYTE bits_4bpsBGRA[] = { 204,85,85,51,85,136,187,85,0,68,0,85,0,102,0,119,0,136,0,153,0,0,0,17,0,34,0,51 }; static const struct bitmap_data data_4bpsBGRA = { 32, 5, 2, &GUID_WICPixelFormat32bppBGRA, bits_4bpsBGRA }; + static const struct bitmap_data data_4bpsPBGRA = + { + 32, 5, 2, &GUID_WICPixelFormat32bppPBGRA, bits_4bpsBGRA + }; static const BYTE bits_8bpsBGRA[] = { 2,0,1,3,6,5,4,7,0,9,8,1,4,3,2,5 }; static const struct bitmap_data data_8bpsBGRA = { 32, 4, 1, &GUID_WICPixelFormat32bppBGRA, bits_8bpsBGRA }; + static const struct bitmap_data data_8bpsPBGRA = + { + 32, 4, 1, &GUID_WICPixelFormat32bppPBGRA, bits_8bpsBGRA + }; static const BYTE bits_64bppRGBA[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 }; static const struct bitmap_data data_64bppRGBA = { 64, 2, 1, &GUID_WICPixelFormat64bppRGBA, bits_64bppRGBA }; + static const struct bitmap_data data_64bppPRGBA = + { + 64, 2, 1, &GUID_WICPixelFormat64bppPRGBA, bits_64bppRGBA + }; static const BYTE bits_BlackWhite[] = { 85,195,184,85 }; static const struct bitmap_data data_BlackWhite = { @@ -975,18 +962,20 @@ static void test_color_formats(void) { 32, 3, 1, &GUID_WICPixelFormat32bppGrayFloat, bits_32bppGrayFloat }; -#if 0 /* FIXME */ - static const BYTE bits_96bpp3Channels[] = { 0 }; - static const struct bitmap_data data_96bpp3Channels = + static const BYTE bits_96bppRGBFloat[] = { 1,0,2,3,4,5,6,7,8,9,0,1 }; + static const struct bitmap_data data_96bppRGBFloat = { - 64, 1, 1, &GUID_WICPixelFormat96bpp3Channels, bits_96bpp3Channels + 96, 1, 1, &GUID_WICPixelFormat96bppRGBFloat, bits_96bppRGBFloat }; -#endif static const BYTE bits_128bppRGBAFloat[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 }; static const struct bitmap_data data_128bppRGBAFloat = { 128, 1, 1, &GUID_WICPixelFormat128bppRGBAFloat, bits_128bppRGBAFloat }; + static const struct bitmap_data data_128bppPRGBAFloat = + { + 128, 1, 1, &GUID_WICPixelFormat128bppPRGBAFloat, bits_128bppRGBAFloat + }; static const BYTE bits_1bppIndexed[] = { 85,195,184,85 }; static const struct bitmap_data data_1bppIndexed = { @@ -1022,48 +1011,52 @@ static void test_color_formats(void) int photometric; /* PhotometricInterpretation */ int samples; /* SamplesPerPixel */ int bps; /* BitsPerSample */ + int extra_samples; /* ExtraSamples */ const struct bitmap_data *data; const struct bitmap_data *alt_data; } td[] = { /* 2 - RGB */ - { 2, 3, 1, &data_1bpsBGR }, - { 2, 3, 4, &data_4bpsBGR }, - { 2, 3, 8, &data_8bpsBGR }, - { 2, 3, 16, &data_48bppRGB }, - { 2, 3, 24, NULL }, -#if 0 /* FIXME */ - { 2, 3, 32, &data_96bpp3Channels }, -#endif - { 2, 4, 1, &data_1bpsBGRA }, - { 2, 4, 4, &data_4bpsBGRA }, - { 2, 4, 8, &data_8bpsBGRA }, - { 2, 4, 16, &data_64bppRGBA }, - { 2, 4, 24, NULL }, - { 2, 4, 32, &data_128bppRGBAFloat }, + { 2, 3, 1, 0, &data_1bpsBGR }, + { 2, 3, 4, 0, &data_4bpsBGR }, + { 2, 3, 8, 0, &data_8bpsBGR }, + { 2, 3, 16, 0, &data_48bppRGB }, + { 2, 3, 24, 0, NULL }, + { 2, 3, 32, 0, &data_96bppRGBFloat }, + { 2, 4, 1, 0, &data_1bpsBGRA }, + { 2, 4, 1, 1, &data_1bpsPBGRA }, + { 2, 4, 4, 0, &data_4bpsBGRA }, + { 2, 4, 4, 1, &data_4bpsPBGRA }, + { 2, 4, 8, 0, &data_8bpsBGRA }, + { 2, 4, 8, 1, &data_8bpsPBGRA }, + { 2, 4, 16, 0, &data_64bppRGBA }, + { 2, 4, 16, 1, &data_64bppPRGBA }, + { 2, 4, 24, 0, NULL }, + { 2, 4, 32, 0, &data_128bppRGBAFloat }, + { 2, 4, 32, 1, &data_128bppPRGBAFloat }, /* 1 - BlackIsZero (Bilevel) */ - { 1, 1, 1, &data_BlackWhite, &data_BlackWhite_xp }, - { 1, 1, 4, &data_4bppGray, &data_4bppGray_xp }, - { 1, 1, 8, &data_8bppGray }, - { 1, 1, 16, &data_16bppGray }, - { 1, 1, 24, NULL }, - { 1, 1, 32, &data_32bppGrayFloat }, + { 1, 1, 1, 0, &data_BlackWhite, &data_BlackWhite_xp }, + { 1, 1, 4, 0, &data_4bppGray, &data_4bppGray_xp }, + { 1, 1, 8, 0, &data_8bppGray }, + { 1, 1, 16, 0, &data_16bppGray }, + { 1, 1, 24, 0, NULL }, + { 1, 1, 32, 0, &data_32bppGrayFloat }, /* 3 - Palette Color */ - { 3, 1, 1, &data_1bppIndexed }, - { 3, 1, 4, &data_4bppIndexed, &data_4bppIndexed_xp }, - { 3, 1, 8, &data_8bppIndexed }, + { 3, 1, 1, 0, &data_1bppIndexed }, + { 3, 1, 4, 0, &data_4bppIndexed, &data_4bppIndexed_xp }, + { 3, 1, 8, 0, &data_8bppIndexed }, #if 0 /* FIXME: for some reason libtiff replaces photometric 3 by 1 for bps > 8 */ - { 3, 1, 16, &data_8bppIndexed }, - { 3, 1, 24, &data_8bppIndexed }, - { 3, 1, 32, &data_8bppIndexed }, + { 3, 1, 16, 0, &data_8bppIndexed }, + { 3, 1, 24, 0, &data_8bppIndexed }, + { 3, 1, 32, 0, &data_8bppIndexed }, #endif /* 5 - Separated */ - { 5, 4, 1, NULL }, - { 5, 4, 4, NULL }, - { 5, 4, 8, &data_32bppCMYK }, - { 5, 4, 16, &data_64bppCMYK }, - { 5, 4, 24, NULL }, - { 5, 4, 32, NULL }, + { 5, 4, 1, 0, NULL }, + { 5, 4, 4, 0, NULL }, + { 5, 4, 8, 0, &data_32bppCMYK }, + { 5, 4, 16, 0, &data_64bppCMYK }, + { 5, 4, 24, 0, NULL }, + { 5, 4, 32, 0, NULL }, }; BYTE buf[sizeof(tiff_1x1_data)]; BYTE pixels[256]; @@ -1072,9 +1065,9 @@ static void test_color_formats(void) IWICBitmapFrameDecode *frame; GUID format; UINT count, i, bpp, channels, ret; - BOOL trasparency; + BOOL transparency; struct IFD_entry *tag, *tag_photo = NULL, *tag_bps = NULL, *tag_samples = NULL, *tag_colormap = NULL; - struct IFD_entry *tag_width = NULL, *tag_height = NULL; + struct IFD_entry *tag_width = NULL, *tag_height = NULL, *tag_extra_samples = NULL; short *bps; memcpy(buf, &tiff_1x1_data, sizeof(tiff_1x1_data)); @@ -1098,23 +1091,26 @@ static void test_color_formats(void) tag_samples = &tag[i]; else if (tag[i].id == 0x140) /* ColorMap */ tag_colormap = &tag[i]; + else if (tag[i].id == 0x152) /* ExtraSamples */ + tag_extra_samples = &tag[i]; } - ok(tag_bps && tag_photo && tag_samples && tag_colormap, "tag 0x102,0x106,0x115 or 0x140 is missing\n"); - if (!tag_bps || !tag_photo || !tag_samples || !tag_colormap) return; + ok(tag_bps && tag_photo && tag_samples && tag_colormap && tag_extra_samples, "tag 0x102,0x106,0x115,0x140 or 0x152 is missing\n"); + if (!tag_bps || !tag_photo || !tag_samples || !tag_colormap || !tag_extra_samples) return; ok(tag_bps->type == IFD_SHORT, "tag 0x102 should have type IFD_SHORT\n"); bps = (short *)(buf + tag_bps->value); ok(bps[0] == 8 && bps[1] == 8 && bps[2] == 8 && bps[3] == 0, "expected bps 8,8,8,0 got %d,%d,%d,%d\n", bps[0], bps[1], bps[2], bps[3]); - for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) + for (i = 0; i < ARRAY_SIZE(td); i++) { if (td[i].data) { bpp = td[i].samples * td[i].bps; if (winetest_debug > 1) - trace("samples %u, bps %u, bpp %u, width %u => width_bytes %u\n", td[i].samples, td[i].bps, bpp, + trace("photometric %d, samples %d, extra samples %d, bps %d, bpp %u, width %u => width_bytes %u\n", + td[i].photometric, td[i].samples, td[i].extra_samples, td[i].bps, bpp, td[i].data->width, width_bytes(td[i].data->width, bpp)); tag_width->value = td[i].data->width; tag_height->value = td[i].data->height; @@ -1166,11 +1162,22 @@ static void test_color_formats(void) continue; } + if (td[i].extra_samples) + { + tag_extra_samples->id = 0x152; /* ExtraSamples */ + tag_extra_samples->value = td[i].extra_samples; + } + else /* remove ExtraSamples tag */ + { + tag_extra_samples->id = 0x14e; /* NumberOfInks */ + tag_extra_samples->value = td[i].samples; + } + hr = create_decoder(buf, sizeof(buf), &decoder); if (!td[i].data) { - ok(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT || hr == WINCODEC_ERR_COMPONENTNOTFOUND /* win8+ */ || WINCODEC_ERR_BADIMAGE /* XP */, - "%u: (%d,%d,%d) wrong error %#x\n", i, td[i].photometric, td[i].samples, td[i].bps, hr); + ok(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT || hr == WINCODEC_ERR_COMPONENTNOTFOUND /* win8+ */ || hr == WINCODEC_ERR_BADIMAGE /* XP */, + "%u: (%d,%d,%d,%d) wrong error %#lx\n", i, td[i].photometric, td[i].samples, td[i].extra_samples, td[i].bps, hr); if (hr == S_OK) { IWICBitmapDecoder_Release(decoder); @@ -1180,34 +1187,41 @@ static void test_color_formats(void) } else ok(hr == S_OK || broken(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT || hr == WINCODEC_ERR_BADIMAGE) /* XP */, - "%u: failed to load TIFF image data (%d,%d,%d) %#x\n", - i, td[i].photometric, td[i].samples, td[i].bps, hr); + "%u: failed to load TIFF image data (%d,%d,%d,%d) %#lx\n", + i, td[i].photometric, td[i].samples, td[i].extra_samples, td[i].bps, hr); if (hr != S_OK) continue; hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "%u: GetFrame error %#x\n", i, hr); + ok(hr == S_OK, "%u: GetFrame error %#lx\n", i, hr); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "%u: GetPixelFormat error %#x\n", i, hr); + ok(hr == S_OK, "%u: GetPixelFormat error %#lx\n", i, hr); + if (IsEqualGUID(td[i].data->format, &GUID_WICPixelFormat96bppRGBFloat) && IsEqualGUID(&format, &GUID_WICPixelFormat128bppRGBFloat)) + { + win_skip("Windows Server 2008 misinterprets 96bppRGBFloat as 128bppRGBFloat, skipping the tests\n"); + IWICBitmapFrameDecode_Release(frame); + IWICBitmapDecoder_Release(decoder); + continue; + } ok(IsEqualGUID(&format, td[i].data->format), - "%u (%d,%d,%d): expected %s, got %s\n", - i, td[i].photometric, td[i].samples, td[i].bps, + "%u (%d,%d,%d,%d): expected %s, got %s\n", + i, td[i].photometric, td[i].samples, td[i].extra_samples, td[i].bps, wine_dbgstr_guid(td[i].data->format), wine_dbgstr_guid(&format)); - trasparency = (td[i].photometric == 2 && td[i].samples == 4); /* for XP */ - hr = get_pixelformat_info(&format, &bpp, &channels, &trasparency); - ok(hr == S_OK, "%u: get_pixelformat_bpp error %#x\n", i, hr); + transparency = (td[i].photometric == 2 && td[i].samples == 4); /* for XP */ + hr = get_pixelformat_info(&format, &bpp, &channels, &transparency); + ok(hr == S_OK, "%u: get_pixelformat_bpp error %#lx\n", i, hr); ok(bpp == td[i].data->bpp, "%u: expected %u, got %u\n", i, td[i].data->bpp, bpp); ok(channels == td[i].samples, "%u: expected %u, got %u\n", i, td[i].samples, channels); - ok(trasparency == (td[i].photometric == 2 && td[i].samples == 4), "%u: got %u\n", i, trasparency); + ok(transparency == (td[i].photometric == 2 && td[i].samples == 4), "%u: got %u\n", i, transparency); memset(pixels, 0, sizeof(pixels)); hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, width_bytes(td[i].data->width, bpp), sizeof(pixels), pixels); - ok(hr == S_OK, "%u: CopyPixels error %#x\n", i, hr); + ok(hr == S_OK, "%u: CopyPixels error %#lx\n", i, hr); ret = memcmp(pixels, td[i].data->bits, width_bytes(td[i].data->width, bpp)); if (ret && td[i].alt_data) ret = memcmp(pixels, td[i].alt_data->bits, width_bytes(td[i].data->width, bpp)); - ok(ret == 0, "%u: (%d,%d,%d) wrong pixel data\n", i, td[i].photometric, td[i].samples, td[i].bps); + ok(ret == 0, "%u: (%d,%d,%d,%d) wrong pixel data\n", i, td[i].photometric, td[i].samples, td[i].extra_samples, td[i].bps); if (ret) { UINT j, n = width_bytes(td[i].data->width, bpp); @@ -1235,36 +1249,36 @@ static void test_tiff_4bps_bgra(void) 0,0xff,0,0, 0xff,0xff,0,0xff, 0xff,0xff,0xff,0 }; hr = create_decoder(&tiff_4bps_bgra, sizeof(tiff_4bps_bgra), &decoder); - ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); + ok(hr == S_OK, "Failed to load TIFF image data %#lx\n", hr); if (hr != S_OK) return; hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); - ok(hr == S_OK, "GetFrameCount error %#x\n", hr); + ok(hr == S_OK, "GetFrameCount error %#lx\n", hr); ok(frame_count == 1, "expected 1, got %u\n", frame_count); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - ok(hr == S_OK, "GetFrame error %#x\n", hr); + ok(hr == S_OK, "GetFrame error %#lx\n", hr); hr = IWICBitmapFrameDecode_GetSize(frame, &width, &height); - ok(hr == S_OK, "GetSize error %#x\n", hr); + ok(hr == S_OK, "GetSize error %#lx\n", hr); ok(width == 3, "got %u\n", width); ok(height == 2, "got %u\n", height); hr = IWICBitmapFrameDecode_GetResolution(frame, &dpi_x, &dpi_y); - ok(hr == S_OK, "GetResolution error %#x\n", hr); + ok(hr == S_OK, "GetResolution error %#lx\n", hr); ok(dpi_x == 96.0, "expected 96.0, got %f\n", dpi_x); ok(dpi_y == 96.0, "expected 96.0, got %f\n", dpi_y); hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); - ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); + ok(hr == S_OK, "GetPixelFormat error %#lx\n", hr); ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppBGRA), "got wrong format %s\n", wine_dbgstr_guid(&format)); hr = IWICImagingFactory_CreatePalette(factory, &palette); - ok(hr == S_OK, "CreatePalette error %#x\n", hr); + ok(hr == S_OK, "CreatePalette error %#lx\n", hr); hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, - "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#x\n", hr); + "expected WINCODEC_ERR_PALETTEUNAVAILABLE, got %#lx\n", hr); IWICPalette_Release(palette); memset(data, 0xaa, sizeof(data)); @@ -1273,7 +1287,7 @@ static void test_tiff_4bps_bgra(void) rc.Width = 3; rc.Height = 2; hr = IWICBitmapFrameDecode_CopyPixels(frame, &rc, 12, sizeof(data), data); - ok(hr == S_OK, "CopyPixels error %#x\n", hr); + ok(hr == S_OK, "CopyPixels error %#lx\n", hr); for (i = 0; i < sizeof(data); i++) ok(data[i] == expected_data[i], "%u: expected %02x, got %02x\n", i, expected_data[i], data[i]); @@ -1290,7 +1304,7 @@ START_TEST(tiffformat) hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void **)&factory); - ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + ok(hr == S_OK, "CoCreateInstance error %#lx\n", hr); if (FAILED(hr)) return; test_tiff_4bps_bgra(); diff --git a/modules/rostests/winetests/windowscodecs/wmpformat.c b/modules/rostests/winetests/windowscodecs/wmpformat.c new file mode 100644 index 00000000000..365902b3172 --- /dev/null +++ b/modules/rostests/winetests/windowscodecs/wmpformat.c @@ -0,0 +1,182 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include "objbase.h" +#include "wincodec.h" +#include "wine/test.h" + +/* generated with JxrEncApp -i image.bmp -o image.jxr -q 1 -c 22 */ +unsigned char wmp_imagedata[] = { + 0x49, 0x49, 0xbc, 0x01, 0x20, 0x00, 0x00, 0x00, 0x24, 0xc3, 0xdd, 0x6f, + 0x03, 0x4e, 0xfe, 0x4b, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0xbc, + 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0xbc, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xbc, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x81, 0xbc, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x82, 0xbc, + 0x0b, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x42, 0x83, 0xbc, + 0x0b, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x42, 0xc0, 0xbc, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0xc1, 0xbc, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0xc2, 0xbc, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4e, 0x01, 0x00, 0x00, 0xc3, 0xbc, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x57, 0x4d, 0x50, 0x48, 0x4f, 0x54, 0x4f, 0x00, 0x11, 0x45, + 0xc0, 0x71, 0x00, 0x00, 0x00, 0x04, 0x60, 0x00, 0xc0, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x26, 0xff, 0xff, 0x00, 0x00, 0x01, 0x01, 0x51, 0x40, 0xc2, + 0x51, 0x88, 0x00, 0x00, 0x01, 0x02, 0x02, 0x10, 0x08, 0x62, 0x18, 0x84, + 0x21, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x18, 0x00, 0x00, 0x80, 0x40, 0x30, 0x00, 0x00, 0x00, 0x01, 0x03, 0x19, + 0x0d, 0x34, 0xd2, 0x77, 0x06, 0x62, 0xe8, 0x89, 0x8b, 0xa2, 0x26, 0x2f, + 0x11, 0xba, 0xbc, 0x46, 0xea, 0xa3, 0x6e, 0xdd, 0x72, 0x23, 0x75, 0x86, + 0xcd, 0x48, 0x73, 0xae, 0x43, 0xb9, 0x67, 0x8d, 0xfd, 0x98, 0xb0, 0xd5, + 0x52, 0x1d, 0xcb, 0x0d, 0x81, 0x06, 0xb4, 0x7d, 0xb8, 0x92, 0x5f, 0xf3, + 0x75, 0xc0, 0x3b, 0xd5, 0x07, 0xcb, 0xd0, 0xec, 0xde, 0x54, 0x1f, 0x7a, + 0x9a, 0x21, 0x8e, 0xcd, 0xe5, 0x4c, 0xdc, 0xce, 0xb8, 0x3e, 0xfa, 0x1d, + 0x8d, 0xca, 0x32, 0x94, 0xd2, 0x93, 0x2c, 0x76, 0x37, 0x2a, 0x63, 0x77, + 0x72, 0xd4, 0xd7, 0x66, 0x5a, 0xdb, 0x66, 0xed, 0x60, 0x00, 0x57, 0x4d, + 0x50, 0x48, 0x4f, 0x54, 0x4f, 0x00, 0x11, 0x45, 0xc0, 0x01, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x80, 0x20, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x13, 0xff, 0xff, 0x00, 0x00, 0x01, 0x01, 0x91, 0xe2, 0x00, + 0x00, 0x01, 0x02, 0x00, 0x86, 0x00, 0x00, 0x20, 0x10, 0x0c, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x03, 0xad, 0xcf, 0xf4, 0x6b, 0x64, 0x45, 0xe1, 0x91, + 0x17, 0x8e, 0x9a, 0x51, 0x32, 0x1f, 0xe2, 0x02, 0xfa, 0x69, 0x44, 0x3b, + 0xfc, 0x7b, 0xab, 0x20, 0xfe, 0x9d, 0x35, 0xd4, 0xda, 0xb7, 0xcb, 0x77, + 0x5f, 0x4d, 0xe5, 0x0e, 0xee, 0x39, 0x97, 0x6f, 0xb9, 0x99, 0x6b, 0x6d, + 0xcc, 0xb9, 0x60}; + +static void test_decode(void) +{ + IWICBitmapDecoder *decoder; + IWICBitmapFrameDecode *framedecode; + IWICImagingFactory *factory; + IWICPalette *palette; + HRESULT hr; + HGLOBAL hwmpdata; + char *wmpdata; + IStream *wmpstream; + GUID format; + UINT count = 0, width = 0, height = 0; + BYTE imagedata[5 * 4] = {1}; + UINT i, j; + + const BYTE expected_imagedata[5 * 4] = { + 0x6d, 0xb0, 0xfc, 0x00, 0x6d, 0xb0, 0xfc, 0x00, 0x6d, 0xb0, + 0xfc, 0x00, 0x6d, 0xb0, 0xfc, 0x00, 0x6d, 0xb0, 0xfc, 0x00, + }; + + const BYTE broken_imagedata[5 * 4] = { + 0x74, 0xa2, 0xd6, 0x28, 0x73, 0xa1, 0xd4, 0x29, 0x71, 0xa9, + 0xe7, 0x16, 0x71, 0xa9, 0xe7, 0x16, 0x70, 0xa7, 0xe5, 0x17 + }; + + hr = CoCreateInstance(&CLSID_WICWmpDecoder, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICBitmapDecoder, (void **)&decoder); + if (FAILED(hr)) + { + win_skip("WmpDecoder isn't available, skipping test\n"); + return; + } + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICImagingFactory, (void **)&factory); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%lx\n", hr); + + hwmpdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(wmp_imagedata)); + ok(hwmpdata != 0, "GlobalAlloc failed\n"); + + wmpdata = GlobalLock(hwmpdata); + memcpy(wmpdata, wmp_imagedata, sizeof(wmp_imagedata)); + GlobalUnlock(hwmpdata); + + hr = CreateStreamOnHGlobal(hwmpdata, FALSE, &wmpstream); + ok(SUCCEEDED(hr), "CreateStreamOnHGlobal failed, hr=%lx\n", hr); + + hr = IWICBitmapDecoder_Initialize(decoder, wmpstream, WICDecodeMetadataCacheOnLoad); + ok(hr == S_OK, "Initialize failed, hr=%lx\n", hr); + + hr = IWICBitmapDecoder_Initialize(decoder, wmpstream, WICDecodeMetadataCacheOnLoad); + ok(hr == WINCODEC_ERR_WRONGSTATE, "Initialize returned %lx\n", hr); + + hr = IWICBitmapDecoder_GetContainerFormat(decoder, &format); + ok(SUCCEEDED(hr), "GetContainerFormat failed, hr=%lx\n", hr); + ok(IsEqualGUID(&format, &GUID_ContainerFormatWmp), + "unexpected container format\n"); + + hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); + ok(SUCCEEDED(hr), "GetFrameCount failed, hr=%lx\n", hr); + ok(count == 1, "unexpected count %u\n", count); + + hr = IWICBitmapDecoder_GetFrame(decoder, 0, NULL); + ok(hr == E_INVALIDARG, "GetFrame(NULL) returned hr=%lx\n", hr); + + for (j = 2; j > 0; --j) + { + hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); + ok(SUCCEEDED(hr), "GetFrame failed, hr=%lx\n", hr); + + hr = IWICBitmapFrameDecode_GetSize(framedecode, &width, &height); + ok(SUCCEEDED(hr), "GetSize failed, hr=%lx\n", hr); + ok(width == 1, "expected width=1, got %u\n", width); + ok(height == 5, "expected height=5, got %u\n", height); + + hr = IWICBitmapFrameDecode_GetPixelFormat(framedecode, &format); + ok(SUCCEEDED(hr), "GetPixelFormat failed, hr=%lx\n", hr); + ok(IsEqualGUID(&format, &GUID_WICPixelFormat32bppBGRA), + "unexpected pixel format: %s\n", wine_dbgstr_guid(&format)); + + for (i = 2; i > 0; --i) + { + memset(imagedata, 0, sizeof(imagedata)); + hr = IWICBitmapFrameDecode_CopyPixels( + framedecode, NULL, 4, sizeof(imagedata), imagedata); + ok(SUCCEEDED(hr), "CopyPixels failed, hr=%lx\n", hr); + ok(!memcmp(imagedata, expected_imagedata, sizeof(imagedata)) || + broken(!memcmp(imagedata, broken_imagedata, sizeof(imagedata)) /* w2008s64 */), + "unexpected image data\n"); + } + + hr = IWICImagingFactory_CreatePalette(factory, &palette); + ok(SUCCEEDED(hr), "CreatePalette failed, hr=%lx\n", hr); + + hr = IWICBitmapDecoder_CopyPalette(decoder, palette); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "Unexpected hr %#lx.\n", hr); + + hr = IWICBitmapFrameDecode_CopyPalette(framedecode, palette); + ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "Unexpected hr %#lx.\n", hr); + + IWICPalette_Release(palette); + + IWICBitmapFrameDecode_Release(framedecode); + } + + IStream_Release(wmpstream); + GlobalFree(hwmpdata); + + IWICBitmapDecoder_Release(decoder); + IWICImagingFactory_Release(factory); +} + +START_TEST(wmpformat) +{ + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + + test_decode(); + + CoUninitialize(); +} diff --git a/modules/rostests/winetests/windowscodecsext/CMakeLists.txt b/modules/rostests/winetests/windowscodecsext/CMakeLists.txt index 80af9711a45..a037859937c 100644 --- a/modules/rostests/winetests/windowscodecsext/CMakeLists.txt +++ b/modules/rostests/winetests/windowscodecsext/CMakeLists.txt @@ -1,4 +1,5 @@ +remove_definitions(-D__ROS_LONG64__) add_executable(windowscodecsext_winetest transform.c testlist.c) set_module_type(windowscodecsext_winetest win32cui) add_importlibs(windowscodecsext_winetest ole32 windowscodecsext msvcrt kernel32) diff --git a/modules/rostests/winetests/windowscodecsext/transform.c b/modules/rostests/winetests/windowscodecsext/transform.c index e76f9fe8a4f..01f0d8a289e 100644 --- a/modules/rostests/winetests/windowscodecsext/transform.c +++ b/modules/rostests/winetests/windowscodecsext/transform.c @@ -32,28 +32,28 @@ static void test_WICCreateColorTransform_Proxy(void) IWICColorTransform *transform; hr = WICCreateColorTransform_Proxy( NULL ); - ok( hr == E_INVALIDARG, "got %08x\n", hr ); + ok( hr == E_INVALIDARG, "got %08lx\n", hr ); transform = NULL; hr = WICCreateColorTransform_Proxy( &transform ); - ok( hr == S_OK, "got %08x\n", hr ); + ok( hr == S_OK, "got %08lx\n", hr ); if (transform) IWICColorTransform_Release( transform ); hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED ); - ok( hr == S_OK, "got %08x\n", hr ); + ok( hr == S_OK, "got %08lx\n", hr ); transform = NULL; hr = WICCreateColorTransform_Proxy( &transform ); - ok( hr == S_OK, "got %08x\n", hr ); + ok( hr == S_OK, "got %08lx\n", hr ); if (transform) IWICColorTransform_Release( transform ); CoUninitialize(); hr = CoInitializeEx( NULL, COINIT_MULTITHREADED ); - ok( hr == S_OK, "got %08x\n", hr ); + ok( hr == S_OK, "got %08lx\n", hr ); transform = NULL; hr = WICCreateColorTransform_Proxy( &transform ); - ok( hr == S_OK, "got %08x\n", hr ); + ok( hr == S_OK, "got %08lx\n", hr ); if (transform) IWICColorTransform_Release( transform ); CoUninitialize(); } diff --git a/sdk/include/psdk/CMakeLists.txt b/sdk/include/psdk/CMakeLists.txt index 360082e103b..f54a53926f0 100644 --- a/sdk/include/psdk/CMakeLists.txt +++ b/sdk/include/psdk/CMakeLists.txt @@ -45,6 +45,7 @@ list(APPEND SOURCE docobjectservice.idl downloadmgr.idl drmexternals.idl + dxgiformat.idl # dyngraph.idl endpointvolume.idl exdisp.idl diff --git a/sdk/include/psdk/dxgiformat.idl b/sdk/include/psdk/dxgiformat.idl new file mode 100644 index 00000000000..5f85064d0dd --- /dev/null +++ b/sdk/include/psdk/dxgiformat.idl @@ -0,0 +1,145 @@ +/* + * Copyright 2016 Józef Kucia for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +const unsigned int DXGI_FORMAT_DEFINED = 1; + +typedef enum DXGI_FORMAT +{ + DXGI_FORMAT_UNKNOWN = 0x00, + DXGI_FORMAT_R32G32B32A32_TYPELESS = 0x01, + DXGI_FORMAT_R32G32B32A32_FLOAT = 0x02, + DXGI_FORMAT_R32G32B32A32_UINT = 0x03, + DXGI_FORMAT_R32G32B32A32_SINT = 0x04, + DXGI_FORMAT_R32G32B32_TYPELESS = 0x05, + DXGI_FORMAT_R32G32B32_FLOAT = 0x06, + DXGI_FORMAT_R32G32B32_UINT = 0x07, + DXGI_FORMAT_R32G32B32_SINT = 0x08, + DXGI_FORMAT_R16G16B16A16_TYPELESS = 0x09, + DXGI_FORMAT_R16G16B16A16_FLOAT = 0x0a, + DXGI_FORMAT_R16G16B16A16_UNORM = 0x0b, + DXGI_FORMAT_R16G16B16A16_UINT = 0x0c, + DXGI_FORMAT_R16G16B16A16_SNORM = 0x0d, + DXGI_FORMAT_R16G16B16A16_SINT = 0x0e, + DXGI_FORMAT_R32G32_TYPELESS = 0x0f, + DXGI_FORMAT_R32G32_FLOAT = 0x10, + DXGI_FORMAT_R32G32_UINT = 0x11, + DXGI_FORMAT_R32G32_SINT = 0x12, + DXGI_FORMAT_R32G8X24_TYPELESS = 0x13, + DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 0x14, + DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 0x15, + DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 0x16, + DXGI_FORMAT_R10G10B10A2_TYPELESS = 0x17, + DXGI_FORMAT_R10G10B10A2_UNORM = 0x18, + DXGI_FORMAT_R10G10B10A2_UINT = 0x19, + DXGI_FORMAT_R11G11B10_FLOAT = 0x1a, + DXGI_FORMAT_R8G8B8A8_TYPELESS = 0x1b, + DXGI_FORMAT_R8G8B8A8_UNORM = 0x1c, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 0x1d, + DXGI_FORMAT_R8G8B8A8_UINT = 0x1e, + DXGI_FORMAT_R8G8B8A8_SNORM = 0x1f, + DXGI_FORMAT_R8G8B8A8_SINT = 0x20, + DXGI_FORMAT_R16G16_TYPELESS = 0x21, + DXGI_FORMAT_R16G16_FLOAT = 0x22, + DXGI_FORMAT_R16G16_UNORM = 0x23, + DXGI_FORMAT_R16G16_UINT = 0x24, + DXGI_FORMAT_R16G16_SNORM = 0x25, + DXGI_FORMAT_R16G16_SINT = 0x26, + DXGI_FORMAT_R32_TYPELESS = 0x27, + DXGI_FORMAT_D32_FLOAT = 0x28, + DXGI_FORMAT_R32_FLOAT = 0x29, + DXGI_FORMAT_R32_UINT = 0x2a, + DXGI_FORMAT_R32_SINT = 0x2b, + DXGI_FORMAT_R24G8_TYPELESS = 0x2c, + DXGI_FORMAT_D24_UNORM_S8_UINT = 0x2d, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 0x2e, + DXGI_FORMAT_X24_TYPELESS_G8_UINT = 0x2f, + DXGI_FORMAT_R8G8_TYPELESS = 0x30, + DXGI_FORMAT_R8G8_UNORM = 0x31, + DXGI_FORMAT_R8G8_UINT = 0x32, + DXGI_FORMAT_R8G8_SNORM = 0x33, + DXGI_FORMAT_R8G8_SINT = 0x34, + DXGI_FORMAT_R16_TYPELESS = 0x35, + DXGI_FORMAT_R16_FLOAT = 0x36, + DXGI_FORMAT_D16_UNORM = 0x37, + DXGI_FORMAT_R16_UNORM = 0x38, + DXGI_FORMAT_R16_UINT = 0x39, + DXGI_FORMAT_R16_SNORM = 0x3a, + DXGI_FORMAT_R16_SINT = 0x3b, + DXGI_FORMAT_R8_TYPELESS = 0x3c, + DXGI_FORMAT_R8_UNORM = 0x3d, + DXGI_FORMAT_R8_UINT = 0x3e, + DXGI_FORMAT_R8_SNORM = 0x3f, + DXGI_FORMAT_R8_SINT = 0x40, + DXGI_FORMAT_A8_UNORM = 0x41, + DXGI_FORMAT_R1_UNORM = 0x42, + DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 0x43, + DXGI_FORMAT_R8G8_B8G8_UNORM = 0x44, + DXGI_FORMAT_G8R8_G8B8_UNORM = 0x45, + DXGI_FORMAT_BC1_TYPELESS = 0x46, + DXGI_FORMAT_BC1_UNORM = 0x47, + DXGI_FORMAT_BC1_UNORM_SRGB = 0x48, + DXGI_FORMAT_BC2_TYPELESS = 0x49, + DXGI_FORMAT_BC2_UNORM = 0x4a, + DXGI_FORMAT_BC2_UNORM_SRGB = 0x4b, + DXGI_FORMAT_BC3_TYPELESS = 0x4c, + DXGI_FORMAT_BC3_UNORM = 0x4d, + DXGI_FORMAT_BC3_UNORM_SRGB = 0x4e, + DXGI_FORMAT_BC4_TYPELESS = 0x4f, + DXGI_FORMAT_BC4_UNORM = 0x50, + DXGI_FORMAT_BC4_SNORM = 0x51, + DXGI_FORMAT_BC5_TYPELESS = 0x52, + DXGI_FORMAT_BC5_UNORM = 0x53, + DXGI_FORMAT_BC5_SNORM = 0x54, + DXGI_FORMAT_B5G6R5_UNORM = 0x55, + DXGI_FORMAT_B5G5R5A1_UNORM = 0x56, + DXGI_FORMAT_B8G8R8A8_UNORM = 0x57, + DXGI_FORMAT_B8G8R8X8_UNORM = 0x58, + DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 0x59, + DXGI_FORMAT_B8G8R8A8_TYPELESS = 0x5a, + DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 0x5b, + DXGI_FORMAT_B8G8R8X8_TYPELESS = 0x5c, + DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 0x5d, + DXGI_FORMAT_BC6H_TYPELESS = 0x5e, + DXGI_FORMAT_BC6H_UF16 = 0x5f, + DXGI_FORMAT_BC6H_SF16 = 0x60, + DXGI_FORMAT_BC7_TYPELESS = 0x61, + DXGI_FORMAT_BC7_UNORM = 0x62, + DXGI_FORMAT_BC7_UNORM_SRGB = 0x63, + DXGI_FORMAT_AYUV = 0x64, + DXGI_FORMAT_Y410 = 0x65, + DXGI_FORMAT_Y416 = 0x66, + DXGI_FORMAT_NV12 = 0x67, + DXGI_FORMAT_P010 = 0x68, + DXGI_FORMAT_P016 = 0x69, + DXGI_FORMAT_420_OPAQUE = 0x6a, + DXGI_FORMAT_YUY2 = 0x6b, + DXGI_FORMAT_Y210 = 0x6c, + DXGI_FORMAT_Y216 = 0x6d, + DXGI_FORMAT_NV11 = 0x6e, + DXGI_FORMAT_AI44 = 0x6f, + DXGI_FORMAT_IA44 = 0x70, + DXGI_FORMAT_P8 = 0x71, + DXGI_FORMAT_A8P8 = 0x72, + DXGI_FORMAT_B4G4R4A4_UNORM = 0x73, + + DXGI_FORMAT_P208 = 0x82, + DXGI_FORMAT_V208 = 0x83, + DXGI_FORMAT_V408 = 0x84, + + DXGI_FORMAT_FORCE_UINT = 0xffffffff, +} DXGI_FORMAT; diff --git a/sdk/include/psdk/wincodec.idl b/sdk/include/psdk/wincodec.idl index c35ef755746..32a0f335813 100644 --- a/sdk/include/psdk/wincodec.idl +++ b/sdk/include/psdk/wincodec.idl @@ -19,6 +19,7 @@ import "wtypes.idl"; import "propidl.idl"; import "ocidl.idl"; +import "dxgiformat.idl"; cpp_quote("#define WINCODEC_SDK_VERSION 0x0236") @@ -193,6 +194,23 @@ typedef enum WICSectionAccessLevel { WICSectionAccessLevel_FORCE_DWORD = CODEC_FORCE_DWORD } WICSectionAccessLevel; +typedef enum WICDdsDimension { + WICDdsTexture1D = 0x00000000, + WICDdsTexture2D = 0x00000001, + WICDdsTexture3D = 0x00000002, + WICDdsTextureCube = 0x00000003, + WICDDSTEXTURE_FORCE_DWORD = CODEC_FORCE_DWORD +} WICDdsDimension; + +typedef enum WICDdsAlphaMode { + WICDdsAlphaModeUnknown = 0x00000000, + WICDdsAlphaModeStraight = 0x00000001, + WICDdsAlphaModePremultiplied = 0x00000002, + WICDdsAlphaModeOpaque = 0x00000003, + WICDdsAlphaModeCustom = 0x00000004, + WICDDSALPHAMODE_FORCE_DWORD = CODEC_FORCE_DWORD +} WICDdsAlphaMode; + typedef GUID WICPixelFormatGUID; typedef REFGUID REFWICPixelFormatGUID; @@ -227,6 +245,7 @@ cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppGrayFloat, 0x6fddc324,0x4e03,0x4b cpp_quote("DEFINE_GUID(GUID_WICPixelFormat48bppRGB, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x15);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat48bppBGR, 0xe605a384,0xb468,0x46ce,0xbb,0x2e,0x36,0xf1,0x80,0xe6,0x43,0x13);") +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat64bppRGB, 0xa1182111,0x186d,0x4d42,0xbc,0x6a,0x9c,0x83,0x03,0xa8,0xdf,0xf9);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat64bppRGBA, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x16);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat64bppBGRA, 0x1562ff7c,0xd352,0x46f9,0x97,0x9e,0x42,0x97,0x6b,0x79,0x22,0x46);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat64bppPRGBA, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x17);") @@ -237,6 +256,7 @@ cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppBGR101010, 0x6fddc324,0x4e03,0x4b cpp_quote("DEFINE_GUID(GUID_WICPixelFormat48bppRGBFixedPoint, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x12);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat48bppBGRFixedPoint, 0x49ca140e,0xcab6,0x493b,0x9d,0xdf,0x60,0x18,0x7c,0x37,0x53,0x2a);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat96bppRGBFixedPoint, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x18);") +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat96bppRGBFloat, 0xe3fed78f,0xe8db,0x4acf,0x84,0xc1,0xe9,0x7f,0x61,0x36,0xb3,0x27);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat128bppRGBAFloat, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x19);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat128bppPRGBAFloat, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x1a);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat128bppRGBFloat, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x1b);") @@ -250,6 +270,7 @@ cpp_quote("DEFINE_GUID(GUID_WICPixelFormat128bppRGBAFixedPoint, 0x6fddc324,0x4e0 cpp_quote("DEFINE_GUID(GUID_WICPixelFormat128bppRGBFixedPoint, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x41);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat64bppRGBAHalf, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x3a);") +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat64bppPRGBAHalf, 0x58ad26c2,0xc623,0x4d9d,0xb3,0x20,0x38,0x7e,0x49,0xf8,0xc4,0x42);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat64bppRGBHalf, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x42);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat48bppRGBHalf, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x3b);") @@ -261,6 +282,10 @@ cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppGrayFixedPoint, 0x6fddc324,0x4e03 cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppRGBA1010102, 0x25238d72,0xfcf9,0x4522,0xb5,0x14,0x55,0x78,0xe5,0xad,0x55,0xe0);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppRGBA1010102XR, 0x00de6b9a,0xc101,0x434b,0xb5,0x02,0xd0,0x16,0x5e,0xe1,0x12,0x2c);") +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppR10G10B10A2, 0x604e1bb5,0x8a3c,0x4b65,0xb1,0x1c,0xbc,0x0b,0x8d,0xd7,0x5b,0x7f);") + +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppR10G10B10A2HDR10, 0x9c215c5d,0x1acc,0x4f0e,0xa4,0xbc,0x70,0xfb,0x3a,0xe8,0xfd,0x28);") + cpp_quote("DEFINE_GUID(GUID_WICPixelFormat64bppCMYK, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x1f);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat24bpp3Channels, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x20);") @@ -294,6 +319,15 @@ cpp_quote("DEFINE_GUID(GUID_WICPixelFormat112bpp6ChannelsAlpha, 0x6fddc324,0x4e0 cpp_quote("DEFINE_GUID(GUID_WICPixelFormat128bpp7ChannelsAlpha, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x38);") cpp_quote("DEFINE_GUID(GUID_WICPixelFormat144bpp8ChannelsAlpha, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x39);") +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat8bppY, 0x91b4db54,0x2df9,0x42f0,0xb4,0x49,0x29,0x09,0xbb,0x3d,0xf8,0x8e);") +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat8bppCb, 0x1339f224,0x6bfe,0x4c3e,0x93,0x02,0xe4,0xf3,0xa6,0xd0,0xca,0x2a);") +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat8bppCr, 0xb8145053,0x2116,0x49f0,0x88,0x35,0xed,0x84,0x4b,0x20,0x5c,0x51);") +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat16bppCbCr, 0xff95ba6e,0x11e0,0x4263,0xbb,0x45,0x01,0x72,0x1f,0x34,0x60,0xa4);") + +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat16bppYQuantizedDctCoefficients, 0xa355f433,0x48e8,0x4a42,0x84,0xd8,0xe2,0xaa,0x26,0xca,0x80,0xa4);") +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat16bppCbQuantizedDctCoefficients, 0xd2c4ff61,0x56a5,0x49c2,0x8b,0x5c,0x4c,0x19,0x25,0x96,0x48,0x37);") +cpp_quote("DEFINE_GUID(GUID_WICPixelFormat16bppCrQuantizedDctCoefficients, 0x2fe354f0,0x1680,0x42d8,0x92,0x31,0xe7,0x3c,0x05,0x65,0xbf,0xc1);") + typedef struct WICRect { INT X; INT Y; @@ -309,6 +343,24 @@ typedef struct WICBitmapPattern { BOOL EndOfStream; } WICBitmapPattern; +typedef struct WICDdsParameters { + UINT Width; + UINT Height; + UINT Depth; + UINT MipLevels; + UINT ArraySize; + DXGI_FORMAT DxgiFormat; + WICDdsDimension Dimension; + WICDdsAlphaMode AlphaMode; +} WICDdsParameters; + +typedef struct WICDdsFormatInfo { + DXGI_FORMAT DxgiFormat; + UINT BytesPerBlock; + UINT BlockWidth; + UINT BlockHeight; +} WICDdsFormatInfo; + typedef UINT32 WICColor; interface IWICPalette; @@ -1083,6 +1135,72 @@ interface IWICEnumMetadataItem : IUnknown [out] IWICEnumMetadataItem **ppIEnumMetadataItem); } +[ + object, + uuid(409cd537-8532-40cb-9774-e2feb2df4e9c) +] +interface IWICDdsDecoder : IUnknown +{ + HRESULT GetParameters( + [out] WICDdsParameters *parameters); + + HRESULT GetFrame( + [in] UINT arrayIndex, + [in] UINT mipLevel, + [in] UINT sliceIndex, + [out, retval] IWICBitmapFrameDecode **bitmapFrame); +}; + +[ + object, + uuid(5cacdb4c-407e-41b3-b936-d0f010cd6732) +] +interface IWICDdsEncoder : IUnknown +{ + HRESULT SetParameters( + [in] WICDdsParameters *parameters); + + HRESULT GetParameters( + [out] WICDdsParameters *parameters); + + HRESULT CreateNewFrame( + [out] IWICBitmapFrameEncode **frameEncode, + [out, optional] UINT *arrayIndex, + [out, optional] UINT *mipLevel, + [out, optional] UINT *sliceIndex); +}; + +[ + object, + uuid(3d4c0c61-18a4-41e4-bd80-481a4fc9f464) +] +interface IWICDdsFrameDecode : IUnknown +{ + HRESULT GetSizeInBlocks( + [out] UINT *widthInBlocks, + [out] UINT *heightInBlocks); + + HRESULT GetFormatInfo( + [out] WICDdsFormatInfo *formatInfo); + + HRESULT CopyBlocks( + [in, unique] const WICRect *boundsInBlocks, + [in] UINT stride, + [in] UINT bufferSize, + [out, size_is(bufferSize)] BYTE *buffer); +}; + +[ + object, + uuid(b9bd430d-28a8-41d3-a1f5-f36ee02840bf) +] +interface IWICWineDecoder : IUnknown +{ + HRESULT Initialize( + [in] IStream *stream, + [in] WICDecodeOptions options); +}; + cpp_quote("HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst);") cpp_quote("HRESULT WINAPI WICCreateBitmapFromSection(UINT width, UINT height, REFWICPixelFormatGUID format, HANDLE section, UINT stride, UINT offset, IWICBitmap **bitmap);") cpp_quote("HRESULT WINAPI WICCreateBitmapFromSectionEx(UINT width, UINT height, REFWICPixelFormatGUID format, HANDLE section, UINT stride, UINT offset, WICSectionAccessLevel access, IWICBitmap **bitmap);") @@ -1093,11 +1211,14 @@ cpp_quote("HRESULT WINAPI WICMapSchemaToName(REFGUID,LPWSTR,UINT,WCHAR *,UINT *) cpp_quote("DEFINE_GUID(CLSID_WICBmpDecoder, 0x6b462062,0x7cbf,0x400d,0x9f,0xdb,0x81,0x3d,0xd1,0x0f,0x27,0x78);") cpp_quote("DEFINE_GUID(CLSID_WICPngDecoder, 0x389ea17b,0x5078,0x4cde,0xb6,0xef,0x25,0xc1,0x51,0x75,0xc7,0x51);") +cpp_quote("DEFINE_GUID(CLSID_WICPngDecoder1, 0x389ea17b,0x5078,0x4cde,0xb6,0xef,0x25,0xc1,0x51,0x75,0xc7,0x51);") +cpp_quote("DEFINE_GUID(CLSID_WICPngDecoder2, 0xe018945b,0xaa86,0x4008,0x9b,0xd4,0x67,0x77,0xa1,0xe4,0x0c,0x11);") cpp_quote("DEFINE_GUID(CLSID_WICIcoDecoder, 0xc61bfcdf,0x2e0f,0x4aad,0xa8,0xd7,0xe0,0x6b,0xaf,0xeb,0xcd,0xfe);") cpp_quote("DEFINE_GUID(CLSID_WICJpegDecoder, 0x9456a480,0xe88b,0x43ea,0x9e,0x73,0x0b,0x2d,0x9b,0x71,0xb1,0xca);") cpp_quote("DEFINE_GUID(CLSID_WICGifDecoder, 0x381dda3c,0x9ce9,0x4834,0xa2,0x3e,0x1f,0x98,0xf8,0xfc,0x52,0xbe);") cpp_quote("DEFINE_GUID(CLSID_WICTiffDecoder, 0xb54e85d9,0xfe23,0x499f,0x8b,0x88,0x6a,0xce,0xa7,0x13,0x75,0x2b);") cpp_quote("DEFINE_GUID(CLSID_WICWmpDecoder, 0xa26cec36,0x234c,0x4950,0xae,0x16,0xe3,0x4a,0xac,0xe7,0x1d,0x0d);") +cpp_quote("DEFINE_GUID(CLSID_WICDdsDecoder, 0x9053699f,0xa341,0x429d,0x9e,0x90,0xee,0x43,0x7c,0xf8,0x0c,0x73);") cpp_quote("DEFINE_GUID(CLSID_WICBmpEncoder, 0x69be8bb4,0xd66d,0x47c8,0x86,0x5a,0xed,0x15,0x89,0x43,0x37,0x82);") cpp_quote("DEFINE_GUID(CLSID_WICPngEncoder, 0x27949969,0x876a,0x41d7,0x94,0x47,0x56,0x8f,0x6a,0x35,0xa4,0xdc);") @@ -1105,11 +1226,22 @@ cpp_quote("DEFINE_GUID(CLSID_WICJpegEncoder, 0x1a34f5c1,0x4a5a,0x46dc,0xb6,0x44, cpp_quote("DEFINE_GUID(CLSID_WICGifEncoder, 0x114f5598,0x0b22,0x40a0,0x86,0xa1,0xc8,0x3e,0xa4,0x95,0xad,0xbd);") cpp_quote("DEFINE_GUID(CLSID_WICTiffEncoder, 0x0131be10,0x2001,0x4c5f,0xa9,0xb0,0xcc,0x88,0xfa,0xb6,0x4c,0xe8);") cpp_quote("DEFINE_GUID(CLSID_WICWmpEncoder, 0xac4ce3cb,0xe1c1,0x44cd,0x82,0x15,0x5a,0x16,0x65,0x50,0x9e,0xc2);") +cpp_quote("DEFINE_GUID(CLSID_WICDdsEncoder, 0xa61dde94,0x66ce,0x4ac1,0x88,0x1b,0x71,0x68,0x05,0x88,0x89,0x5e);") +cpp_quote("DEFINE_GUID(CLSID_WICAdngDecoder, 0x981d9411,0x909e,0x42a7,0x8f,0x5d,0xa7,0x47,0xff,0x05,0x2e,0xdb);") + +cpp_quote("DEFINE_GUID(CLSID_WICJpegQualcommPhoneEncoder, 0x68ed5c62,0xf534,0x4979,0xb2,0xb3,0x68,0x6a,0x12,0xb2,0xb3,0x4c);") + +cpp_quote("DEFINE_GUID(CLSID_WICHeifDecoder, 0xe9a4a80a,0x44fe,0x4de4,0x89,0x71,0x71,0x50,0xb1,0x0a,0x51,0x99);") +cpp_quote("DEFINE_GUID(CLSID_WICHeifEncoder, 0x0dbecec1,0x9eb3,0x4860,0x9c,0x6f,0xdd,0xbe,0x86,0x63,0x45,0x75);") + +cpp_quote("DEFINE_GUID(CLSID_WICWebpDecoder, 0x7693e886,0x51c9,0x4070,0x84,0x19,0x9f,0x70,0x73,0x8e,0xc8,0xfa);") +cpp_quote("DEFINE_GUID(CLSID_WICRAWDecoder, 0x41945702,0x8302,0x44a6,0x94,0x45,0xac,0x98,0xe8,0xaf,0xa0,0x86);") cpp_quote("DEFINE_GUID(CLSID_WICDefaultFormatConverter, 0x1a3f11dc,0xb514,0x4b17,0x8c,0x5f,0x21,0x54,0x51,0x38,0x52,0xf1);") cpp_quote("DEFINE_GUID(CLSID_WICFormatConverterHighColor, 0xac75d454,0x9f37,0x48f8,0xb9,0x72,0x4e,0x19,0xbc,0x85,0x60,0x11);") cpp_quote("DEFINE_GUID(CLSID_WICFormatConverterNChannel, 0xc17cabb2,0xd4a3,0x47d7,0xa5,0x57,0x33,0x9b,0x2e,0xfb,0xd4,0xf1);") cpp_quote("DEFINE_GUID(CLSID_WICFormatConverterWMPhoto, 0x9cb5172b,0xd600,0x46ba,0xab,0x77,0x77,0xbb,0x7e,0x3a,0x00,0xd9);") +cpp_quote("DEFINE_GUID(CLSID_WICPlanarFormatConverter, 0x184132b8,0x32f8,0x4784,0x91,0x31,0xdd,0x72,0x24,0xb2,0x34,0x38);") cpp_quote("DEFINE_GUID(GUID_ContainerFormatBmp, 0x0af1d87e,0xfcfe,0x4188,0xbd,0xeb,0xa7,0x90,0x64,0x71,0xcb,0xe3);") cpp_quote("DEFINE_GUID(GUID_ContainerFormatPng, 0x1b7cfaf4,0x713f,0x473c,0xbb,0xcd,0x61,0x37,0x42,0x5f,0xae,0xaf);") @@ -1118,6 +1250,11 @@ cpp_quote("DEFINE_GUID(GUID_ContainerFormatJpeg, 0x19e4a5aa,0x5662,0x4fc5,0xa0,0 cpp_quote("DEFINE_GUID(GUID_ContainerFormatTiff, 0x163bcc30,0xe2e9,0x4f0b,0x96,0x1d,0xa3,0xe9,0xfd,0xb7,0x88,0xa3);") cpp_quote("DEFINE_GUID(GUID_ContainerFormatGif, 0x1f8a5601,0x7d4d,0x4cbd,0x9c,0x82,0x1b,0xc8,0xd4,0xee,0xb9,0xa5);") cpp_quote("DEFINE_GUID(GUID_ContainerFormatWmp, 0x57a37caa,0x367a,0x4540,0x91,0x6b,0xf1,0x83,0xc5,0x09,0x3a,0x4b);") +cpp_quote("DEFINE_GUID(GUID_ContainerFormatDds, 0x9967cb95,0x2e85,0x4ac8,0x8c,0xa2,0x83,0xd7,0xcc,0xd4,0x25,0xc9);") +cpp_quote("DEFINE_GUID(GUID_ContainerFormatAdng, 0xf3ff6d0d,0x38c0,0x41c4,0xb1,0xfe,0x1f,0x38,0x24,0xf1,0x7b,0x84);") +cpp_quote("DEFINE_GUID(GUID_ContainerFormatHeif, 0xe1e62521,0x6787,0x405b,0xa3,0x39,0x50,0x07,0x15,0xb5,0x76,0x3f);") +cpp_quote("DEFINE_GUID(GUID_ContainerFormatWebp, 0xe094b0e2,0x67f2,0x45b3,0xb0,0xea,0x11,0x53,0x37,0xca,0x7c,0xf3);") +cpp_quote("DEFINE_GUID(GUID_ContainerFormatRaw, 0xfe99ce60,0xf19c,0x433c,0xa3,0xae,0x00,0xac,0xef,0xa9,0xca,0x21);") cpp_quote("DEFINE_GUID(GUID_VendorMicrosoft, 0xf0e749ca,0xedef,0x4589,0xa7,0x3a,0xee,0x0e,0x62,0x6a,0x2a,0x2b);") cpp_quote("DEFINE_GUID(GUID_VendorMicrosoftBuiltIn, 0x257a30fd,0x6b6,0x462b,0xae,0xa4,0x63,0xf7,0xb,0x86,0xe5,0x33);") diff --git a/sdk/include/psdk/wincodecsdk.idl b/sdk/include/psdk/wincodecsdk.idl index 75492774f31..a12ca9226d1 100644 --- a/sdk/include/psdk/wincodecsdk.idl +++ b/sdk/include/psdk/wincodecsdk.idl @@ -73,17 +73,44 @@ cpp_quote("DEFINE_GUID(GUID_MetadataFormatChunkiTXt, 0xc2bec729,0xb68,0x4b77,0xa cpp_quote("DEFINE_GUID(GUID_MetadataFormatChunkhIST, 0xc59a82da,0xdb74,0x48a4,0xbd,0x6a,0xb6,0x9c,0x49,0x31,0xef,0x95);") cpp_quote("DEFINE_GUID(GUID_MetadataFormatChunkiCCP, 0xeb4349ab,0xb685,0x450f,0x91,0xb5,0xe8,0x2,0xe8,0x92,0x53,0x6c);") cpp_quote("DEFINE_GUID(GUID_MetadataFormatChunksRGB, 0xc115fd36,0xcc6f,0x4e3f,0x83,0x63,0x52,0x4b,0x87,0xc6,0xb0,0xd9);") +cpp_quote("DEFINE_GUID(GUID_MetadataFormatDds, 0x4a064603,0x8c33,0x4e60,0x9c,0x29,0x13,0x62,0x31,0x70,0x2d,0x08);") +cpp_quote("DEFINE_GUID(GUID_MetadataFormatHeif, 0x817ef3e1,0x1288,0x45f4,0xa8,0x52,0x26,0x0d,0x9e,0x7c,0xce,0x83);") +cpp_quote("DEFINE_GUID(GUID_MetadataFormatHeifHDR, 0x568b8d8a,0x1e65,0x438c,0x89,0x68,0xd6,0x0e,0x10,0x12,0xbe,0xb9);") +cpp_quote("DEFINE_GUID(GUID_MetadataFormatWebpANIM, 0x6dc4fda6,0x78e6,0x4102,0xae,0x35,0xbc,0xfa,0x1e,0xdc,0xc7,0x8b);") +cpp_quote("DEFINE_GUID(GUID_MetadataFormatWebpANMF, 0x43c105ee,0xb93b,0x4abb,0xb0,0x03,0xa0,0x8c,0x0d,0x87,0x04,0x71);") cpp_quote("DEFINE_GUID(CLSID_WICUnknownMetadataReader, 0x699745c2,0x5066,0x4b82,0xa8,0xe3,0xd4,0x04,0x78,0xdb,0xec,0x8c);") cpp_quote("DEFINE_GUID(CLSID_WICUnknownMetadataWriter, 0xa09cca86,0x27ba,0x4f39,0x90,0x53,0x12,0x1f,0xa4,0xdc,0x08,0xfc);") +cpp_quote("DEFINE_GUID(CLSID_WICPngBkgdMetadataReader, 0x0ce7a4a6,0x03e8,0x4a60,0x9d,0x15,0x28,0x2e,0xf3,0x2e,0xe7,0xda);") +cpp_quote("DEFINE_GUID(CLSID_WICPngBkgdMetadataWriter, 0x68e3f2fd,0x31ae,0x4441,0xbb,0x6a,0xfd,0x70,0x47,0x52,0x5f,0x90);") cpp_quote("DEFINE_GUID(CLSID_WICPngChrmMetadataReader, 0xf90b5f36,0x367b,0x402a,0x9d,0xd1,0xbc,0x0f,0xd5,0x9d,0x8f,0x62);") +cpp_quote("DEFINE_GUID(CLSID_WICPngChrmMetadataWriter, 0xe23ce3eb,0x5608,0x4e83,0xbc,0xef,0x27,0xb1,0x98,0x7e,0x51,0xd7);") cpp_quote("DEFINE_GUID(CLSID_WICPngGamaMetadataReader, 0x3692ca39,0xe082,0x4350,0x9e,0x1f,0x37,0x04,0xcb,0x08,0x3c,0xd5);") +cpp_quote("DEFINE_GUID(CLSID_WICPngGamaMetadataWriter, 0xff036d13,0x5d4b,0x46dd,0xb1,0x0f,0x10,0x66,0x93,0xd9,0xfe,0x4f);") +cpp_quote("DEFINE_GUID(CLSID_WICPngHistMetadataReader, 0x877a0bb7,0xa313,0x4491,0x87,0xb5,0x2e,0x6d,0x05,0x94,0xf5,0x20);") +cpp_quote("DEFINE_GUID(CLSID_WICPngHistMetadataWriter, 0x8a03e749,0x672e,0x446e,0xbf,0x1f,0x2c,0x11,0xd2,0x33,0xb6,0xff);") +cpp_quote("DEFINE_GUID(CLSID_WICPngIccpMetadataReader, 0xf5d3e63b,0xcb0f,0x4628,0xa4,0x78,0x6d,0x82,0x44,0xbe,0x36,0xb1);") +cpp_quote("DEFINE_GUID(CLSID_WICPngIccpMetadataWriter, 0x16671e5f,0x0ce6,0x4cc4,0x97,0x68,0xe8,0x9f,0xe5,0x01,0x8a,0xde);") +cpp_quote("DEFINE_GUID(CLSID_WICPngItxtMetadataReader, 0xaabfb2fa,0x3e1e,0x4a8f,0x89,0x77,0x55,0x56,0xfb,0x94,0xea,0x23);") +cpp_quote("DEFINE_GUID(CLSID_WICPngItxtMetadataWriter, 0x31879719,0xe751,0x4df8,0x98,0x1d,0x68,0xdf,0xf6,0x77,0x04,0xed);") +cpp_quote("DEFINE_GUID(CLSID_WICPngSrgbMetadataReader, 0xfb40360c,0x547e,0x4956,0xa3,0xb9,0xd4,0x41,0x88,0x59,0xba,0x66);") +cpp_quote("DEFINE_GUID(CLSID_WICPngSrgbMetadataWriter, 0xa6ee35c6,0x87ec,0x47df,0x9f,0x22,0x1d,0x5a,0xad,0x84,0x0c,0x82);") cpp_quote("DEFINE_GUID(CLSID_WICPngTextMetadataReader, 0x4b59afcc,0xb8c3,0x408a,0xb6,0x70,0x89,0xe5,0xfa,0xb6,0xfd,0xa7);") cpp_quote("DEFINE_GUID(CLSID_WICPngTextMetadataWriter, 0xb5ebafb9,0x253e,0x4a72,0xa7,0x44,0x07,0x62,0xd2,0x68,0x56,0x83);") +cpp_quote("DEFINE_GUID(CLSID_WICPngTimeMetadataReader, 0xd94edf02,0xefe5,0x4f0d,0x85,0xc8,0xf5,0xa6,0x8b,0x30,0x00,0xb1);") +cpp_quote("DEFINE_GUID(CLSID_WICPngTimeMetadataWriter, 0x1ab78400,0xb5a3,0x4d91,0x8a,0xce,0x33,0xfc,0xd1,0x49,0x9b,0xe6);") cpp_quote("DEFINE_GUID(CLSID_WICIfdMetadataReader, 0x8f914656,0x9d0a,0x4eb2,0x90,0x19,0x0b,0xf9,0x6d,0x8a,0x9e,0xe6);") cpp_quote("DEFINE_GUID(CLSID_WICIfdMetadataWriter, 0xb1ebfc28,0xc9bd,0x47a2,0x8d,0x33,0xb9,0x48,0x76,0x97,0x77,0xa7);") cpp_quote("DEFINE_GUID(CLSID_WICExifMetadataReader, 0xd9403860,0x297f,0x4a49,0xbf,0x9b,0x77,0x89,0x81,0x50,0xa4,0x42);") cpp_quote("DEFINE_GUID(CLSID_WICExifMetadataWriter, 0xc9a14cda,0xc339,0x460b,0x90,0x78,0xd4,0xde,0xbc,0xfa,0xbe,0x91);") +cpp_quote("DEFINE_GUID(CLSID_WICXMPMetadataReader, 0x72b624df,0xae11,0x4948,0xa6,0x5c,0x35,0x1e,0xb0,0x82,0x94,0x19);") +cpp_quote("DEFINE_GUID(CLSID_WICXMPMetadataWriter, 0x1765e14e,0x1bd4,0x462e,0xb6,0xb1,0x59,0x0b,0xf1,0x26,0x2a,0xc6);") +cpp_quote("DEFINE_GUID(CLSID_WICXMPAltMetadataReader, 0xaa94dcc2,0xb8b0,0x4898,0xb8,0x35,0x00,0x0a,0xab,0xd7,0x43,0x93);") +cpp_quote("DEFINE_GUID(CLSID_WICXMPAltMetadataWriter, 0x076c2a6c,0xf78f,0x4c46,0xa7,0x23,0x35,0x83,0xe7,0x08,0x76,0xea);") +cpp_quote("DEFINE_GUID(CLSID_WICXMPBagMetadataReader, 0xe7e79a30,0x4f2c,0x4fab,0x8d,0x00,0x39,0x4f,0x2d,0x6b,0xbe,0xbe);") +cpp_quote("DEFINE_GUID(CLSID_WICXMPBagMetadataWriter, 0xed822c8c,0xd6be,0x4301,0xa6,0x31,0x0e,0x14,0x16,0xba,0xd2,0x8f);") +cpp_quote("DEFINE_GUID(CLSID_WICXMPSeqMetadataReader, 0x7f12e753,0xfc71,0x43d7,0xa5,0x1d,0x92,0xf3,0x59,0x77,0xab,0xb5);") +cpp_quote("DEFINE_GUID(CLSID_WICXMPSeqMetadataWriter, 0x6d68d1de,0xd432,0x4b0f,0x92,0x3a,0x09,0x11,0x83,0xa9,0xbd,0xa7);") cpp_quote("DEFINE_GUID(CLSID_WICXMPStructMetadataReader, 0x01b90d9a,0x8209,0x47f7,0x9c,0x52,0xe1,0x24,0x4b,0xf5,0x0c,0xed);") cpp_quote("DEFINE_GUID(CLSID_WICXMPStructMetadataWriter, 0x22c21f93,0x7ddb,0x411c,0x9b,0x17,0xc5,0xb7,0xbd,0x06,0x4a,0xbc);") cpp_quote("DEFINE_GUID(CLSID_WICLSDMetadataReader, 0x41070793,0x59e4,0x479a,0xa1,0xf7,0x95,0x4a,0xdc,0x2e,0xf5,0xfc);") @@ -96,6 +123,43 @@ cpp_quote("DEFINE_GUID(CLSID_WICAPEMetadataReader, 0x1767b93a,0xb021,0x44ea,0x92 cpp_quote("DEFINE_GUID(CLSID_WICAPEMetadataWriter, 0xbd6edfca,0x2890,0x482f,0xb2,0x33,0x8d,0x73,0x39,0xa1,0xcf,0x8d);") cpp_quote("DEFINE_GUID(CLSID_WICGifCommentMetadataReader, 0x32557d3b,0x69dc,0x4f95,0x83,0x6e,0xf5,0x97,0x2b,0x2f,0x61,0x59);") cpp_quote("DEFINE_GUID(CLSID_WICGifCommentMetadataWriter, 0xa02797fc,0xc4ae,0x418c,0xaf,0x95,0xe6,0x37,0xc7,0xea,0xd2,0xa1);") +cpp_quote("DEFINE_GUID(CLSID_WICApp0MetadataWriter, 0xf3c633a2,0x46c8,0x498e,0x8f,0xbb,0xcc,0x6f,0x72,0x1b,0xbc,0xde);") +cpp_quote("DEFINE_GUID(CLSID_WICApp0MetadataReader, 0x43324b33,0xa78f,0x480f,0x91,0x11,0x96,0x38,0xaa,0xcc,0xc8,0x32);") +cpp_quote("DEFINE_GUID(CLSID_WICApp1MetadataWriter, 0xee366069,0x1832,0x420f,0xb3,0x81,0x04,0x79,0xad,0x06,0x6f,0x19);") +cpp_quote("DEFINE_GUID(CLSID_WICApp1MetadataReader, 0xdde33513,0x774e,0x4bcd,0xae,0x79,0x02,0xf4,0xad,0xfe,0x62,0xfc);") +cpp_quote("DEFINE_GUID(CLSID_WICApp13MetadataWriter, 0x7b19a919,0xa9d6,0x49e5,0xbd,0x45,0x02,0xc3,0x4e,0x4e,0x4c,0xd5);") +cpp_quote("DEFINE_GUID(CLSID_WICApp13MetadataReader, 0xaa7e3c50,0x864c,0x4604,0xbc,0x04,0x8b,0x0b,0x76,0xe6,0x37,0xf6);") +cpp_quote("DEFINE_GUID(CLSID_WICSubIfdMetadataReader, 0x50d42f09,0xecd1,0x4b41,0xb6,0x5d,0xda,0x1f,0xda,0xa7,0x56,0x63);" ) +cpp_quote("DEFINE_GUID(CLSID_WICSubIfdMetadataWriter, 0x8ade5386,0x8e9b,0x4f4c,0xac,0xf2,0xf0,0x00,0x87,0x06,0xb2,0x38);" ) +cpp_quote("DEFINE_GUID(CLSID_WICGpsMetadataReader, 0x3697790b,0x223b,0x484e,0x99,0x25,0xc4,0x86,0x92,0x18,0xf1,0x7a);" ) +cpp_quote("DEFINE_GUID(CLSID_WICGpsMetadataWriter, 0xcb8c13e4,0x62b5,0x4c96,0xa4,0x8b,0x6b,0xa6,0xac,0xe3,0x9c,0x76);") +cpp_quote("DEFINE_GUID(CLSID_WICInteropMetadataReader, 0xb5c8b898,0x0074,0x459f,0xb7,0x00,0x86,0x0d,0x46,0x51,0xea,0x14);") +cpp_quote("DEFINE_GUID(CLSID_WICInteropMetadataWriter, 0x122ec645,0xcd7e,0x44d8,0xb1,0x86,0x2c,0x8c,0x20,0xc3,0xb5,0x0f);") +cpp_quote("DEFINE_GUID(CLSID_WICThumbnailMetadataReader, 0xfb012959,0xf4f6,0x44d7,0x9d,0x09,0xda,0xa0,0x87,0xa9,0xdb,0x57);") +cpp_quote("DEFINE_GUID(CLSID_WICThumbnailMetadataWriter, 0xd049b20c,0x5dd0,0x44fe,0xb0,0xb3,0x8f,0x92,0xc8,0xe6,0xd0,0x80);") +cpp_quote("DEFINE_GUID(CLSID_WICIPTCMetadataReader, 0x03012959,0xf4f6,0x44d7,0x9d,0x09,0xda,0xa0,0x87,0xa9,0xdb,0x57);") +cpp_quote("DEFINE_GUID(CLSID_WICIPTCMetadataWriter, 0x1249b20c,0x5dd0,0x44fe,0xb0,0xb3,0x8f,0x92,0xc8,0xe6,0xd0,0x80);") +cpp_quote("DEFINE_GUID(CLSID_WICIRBMetadataReader, 0xd4dcd3d7,0xb4c2,0x47d9,0xa6,0xbf,0xb8,0x9b,0xa3,0x96,0xa4,0xa3);") +cpp_quote("DEFINE_GUID(CLSID_WICIRBMetadataWriter, 0x5c5c1935,0x0235,0x4434,0x80,0xbc,0x25,0x1b,0xc1,0xec,0x39,0xc6);") +cpp_quote("DEFINE_GUID(CLSID_WIC8BIMIPTCMetadataReader, 0x0010668c,0x0801,0x4da6,0xa4,0xa4,0x82,0x65,0x22,0xb6,0xd2,0x8f);") +cpp_quote("DEFINE_GUID(CLSID_WIC8BIMIPTCMetadataWriter, 0x00108226,0xee41,0x44a2,0x9e,0x9c,0x4b,0xe4,0xd5,0xb1,0xd2,0xcd);") +cpp_quote("DEFINE_GUID(CLSID_WIC8BIMIPTCDigestMetadataReader, 0x02805f1e,0xd5aa,0x415b,0x82,0xc5,0x61,0xc0,0x33,0xa9,0x88,0xa6);") +cpp_quote("DEFINE_GUID(CLSID_WIC8BIMIPTCDigestMetadataWriter, 0x2db5e62b,0x0d67,0x495f,0x8f,0x9d,0xc2,0xf0,0x18,0x86,0x47,0xac);") +cpp_quote("DEFINE_GUID(CLSID_WIC8BIMResolutionInfoMetadataReader, 0x5805137a,0xe348,0x4f7c,0xb3,0xcc,0x6d,0xb9,0x96,0x5a,0x05,0x99);") +cpp_quote("DEFINE_GUID(CLSID_WIC8BIMResolutionInfoMetadataWriter, 0x4ff2fe0e,0xe74a,0x4b71,0x98,0xc4,0xab,0x7d,0xc1,0x67,0x07,0xba);") +cpp_quote("DEFINE_GUID(CLSID_WICJpegChrominanceMetadataReader, 0x50b1904b,0xf28f,0x4574,0x93,0xf4,0x0b,0xad,0xe8,0x2c,0x69,0xe9);") +cpp_quote("DEFINE_GUID(CLSID_WICJpegChrominanceMetadataWriter, 0x3ff566f0,0x6e6b,0x49d4,0x96,0xe6,0xb7,0x88,0x86,0x69,0x2c,0x62);") +cpp_quote("DEFINE_GUID(CLSID_WICJpegCommentMetadataReader, 0x9f66347c,0x60c4,0x4c4d,0xab,0x58,0xd2,0x35,0x86,0x85,0xf6,0x07);") +cpp_quote("DEFINE_GUID(CLSID_WICJpegCommentMetadataWriter, 0xe573236f,0x55b1,0x4eda,0x81,0xea,0x9f,0x65,0xdb,0x02,0x90,0xd3);") +cpp_quote("DEFINE_GUID(CLSID_WICJpegLuminanceMetadataReader, 0x356f2f88,0x05a6,0x4728,0xb9,0xa4,0x1b,0xfb,0xce,0x04,0xd8,0x38);") +cpp_quote("DEFINE_GUID(CLSID_WICJpegLuminanceMetadataWriter, 0x1d583abc,0x8a0e,0x4657,0x99,0x82,0xa3,0x80,0xca,0x58,0xfb,0x4b);") +cpp_quote("DEFINE_GUID(CLSID_WICDdsMetadataReader, 0x276c88ca,0x7533,0x4a86,0xb6,0x76,0x66,0xb3,0x60,0x80,0xd4,0x84);") +cpp_quote("DEFINE_GUID(CLSID_WICDdsMetadataWriter, 0xfd688bbd,0x31ed,0x4db7,0xa7,0x23,0x93,0x49,0x27,0xd3,0x83,0x67);") +cpp_quote("DEFINE_GUID(CLSID_WICHeifMetadataReader, 0xacddfc3f,0x85ec,0x41bc,0xbd,0xef,0x1b,0xc2,0x62,0xe4,0xdb,0x05);") +cpp_quote("DEFINE_GUID(CLSID_WICHeifMetadataWriter, 0x3ae45e79,0x40bc,0x4401,0xac,0xe5,0xdd,0x3c,0xb1,0x6e,0x6a,0xfe);") +cpp_quote("DEFINE_GUID(CLSID_WICHeifHDRMetadataReader, 0x2438de3d,0x94d9,0x4be8,0x84,0xa8,0x4d,0xe9,0x5a,0x57,0x5e,0x75);") +cpp_quote("DEFINE_GUID(CLSID_WICWebpAnimMetadataReader, 0x076f9911,0xa348,0x465c,0xa8,0x07,0xa2,0x52,0xf3,0xf2,0xd3,0xde);") +cpp_quote("DEFINE_GUID(CLSID_WICWebpAnmfMetadataReader, 0x85a10b03,0xc9f6,0x439f,0xbe,0x5e,0xc0,0xfb,0xef,0x67,0x80,0x7c);") typedef struct WICMetadataPattern { ULARGE_INTEGER Position; @@ -302,6 +366,24 @@ interface IWICPersistStream : IPersistStream [in] BOOL fClearDirty); } +[ + object, + uuid(449494bc-b468-4927-96d7-ba90d31ab505) +] +interface IWICStreamProvider : IUnknown +{ + HRESULT GetStream( + [out] IStream **stream); + + HRESULT GetPersistOptions( + [out] DWORD *options); + + HRESULT GetPreferredVendorGUID( + [out] GUID *guid); + + HRESULT RefreshStream(); +} + [ object, uuid(412d0c3a-9650-44fa-af5b-dd2a06c8e8fb) diff --git a/sdk/tools/winesync/windowscodecs.cfg b/sdk/tools/winesync/windowscodecs.cfg new file mode 100644 index 00000000000..533d3fe488d --- /dev/null +++ b/sdk/tools/winesync/windowscodecs.cfg @@ -0,0 +1,10 @@ +directories: + dlls/windowscodecs: dll/win32/windowscodecs + dlls/windowscodecsext: dll/win32/windowscodecsext + dlls/windowscodecs/tests: modules/rostests/winetests/windowscodecs + dlls/windowscodecsext/tests: modules/rostests/winetests/windowscodecsext +files: + include/wincodec.idl: sdk/include/psdk/wincodec.idl + include/wincodecsdk.idl: sdk/include/psdk/wincodecsdk.idl +tags: + wine: wine-10.0