From c2001c2b53b75045c1645ed1b23e7c4d711a7acd Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Tue, 14 Aug 2012 11:28:32 -0500 Subject: [PATCH] windowscodecs: Add tests for IWICBitmap. --- dlls/windowscodecs/tests/Makefile.in | 1 + dlls/windowscodecs/tests/bitmap.c | 279 +++++++++++++++++++++++++++ include/wincodec.idl | 7 + 3 files changed, 287 insertions(+) create mode 100644 dlls/windowscodecs/tests/bitmap.c diff --git a/dlls/windowscodecs/tests/Makefile.in b/dlls/windowscodecs/tests/Makefile.in index e70af9661d1..325c28e4d96 100644 --- a/dlls/windowscodecs/tests/Makefile.in +++ b/dlls/windowscodecs/tests/Makefile.in @@ -2,6 +2,7 @@ TESTDLL = windowscodecs.dll IMPORTS = ole32 windowscodecs C_SRCS = \ + bitmap.c \ bmpformat.c \ converter.c \ icoformat.c \ diff --git a/dlls/windowscodecs/tests/bitmap.c b/dlls/windowscodecs/tests/bitmap.c new file mode 100644 index 00000000000..ebcefb9ea6c --- /dev/null +++ b/dlls/windowscodecs/tests/bitmap.c @@ -0,0 +1,279 @@ +/* + * Copyright 2012 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 + +#define COBJMACROS + +#include "windef.h" +#include "objbase.h" +#include "wincodec.h" +#include "wine/test.h" + +static IWICImagingFactory *factory; + +static void test_createbitmap(void) +{ + HRESULT hr; + IWICBitmap *bitmap; + IWICPalette *palette; + IWICBitmapLock *lock, *lock2; + WICBitmapPaletteType palettetype; + int i; + WICRect rc; + const BYTE bitmap_data[27] = { + 128,128,255, 128,128,128, 128,255,128, + 128,128,128, 128,128,128, 255,255,255, + 255,128,128, 255,255,255, 255,255,255}; + BYTE returned_data[27] = {0}; + BYTE *lock_buffer=NULL, *base_lock_buffer=NULL; + UINT lock_buffer_size=0; + UINT lock_buffer_stride=0; + WICPixelFormatGUID pixelformat = {0}; + UINT width=0, height=0; + double dpix=10.0, dpiy=10.0; + int can_lock_null = 1; + + hr = IWICImagingFactory_CreateBitmap(factory, 3, 3, &GUID_WICPixelFormat24bppBGR, + WICBitmapCacheOnLoad, &bitmap); + todo_wine ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%x\n", hr); + + if (FAILED(hr)) + return; + + hr = IWICImagingFactory_CreatePalette(factory, &palette); + ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\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); + + hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray256, FALSE); + ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr); + + hr = IWICBitmap_SetPalette(bitmap, palette); + ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%x\n", hr); + + hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray4, FALSE); + ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr); + + hr = IWICBitmap_CopyPalette(bitmap, palette); + ok(hr == S_OK, "IWICBitmap_CopyPalette failed hr=%x\n", hr); + + hr = IWICPalette_GetType(palette, &palettetype); + ok(hr == S_OK, "IWICPalette_GetType failed hr=%x\n", hr); + ok(palettetype == WICBitmapPaletteTypeFixedGray256, + "expected WICBitmapPaletteTypeFixedGray256, got %x\n", palettetype); + + IWICPalette_Release(palette); + + /* 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); + + for (i=0; i<27; i++) + ok(returned_data[i] == 0, "returned_data[%i] == %i\n", i, returned_data[i]); + + /* Invalid lock rects */ + rc.X = rc.Y = 0; + rc.Width = 4; + rc.Height = 3; + hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock); + ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%x\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); + 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); + 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); + 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); + + 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(width == 3, "got %d, expected 3\n", width); + ok(height == 3, "got %d, expected 3\n", height); + + IWICBitmapLock_Release(lock); + } + else + can_lock_null = 0; + + /* 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); + if (SUCCEEDED(hr)) + { + hr = IWICBitmapLock_GetStride(lock, &lock_buffer_stride); + ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%x\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); + /* 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(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(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); + + if (SUCCEEDED(hr)) + { + hr = IWICBitmapLock_GetDataPointer(lock2, &lock_buffer_size, &lock_buffer); + ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%x\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); + + IWICBitmapLock_Release(lock2); + } + + if (can_lock_null) /* this hangs on xp/vista */ + { + /* 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); + } + + /* But we don't need a write lock to write */ + for (i=0; i<3; i++) + memcpy(base_lock_buffer + lock_buffer_stride*i, bitmap_data + i*9, 9); + + IWICBitmapLock_Release(lock); + } + + /* 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); + + for (i=0; i<27; i++) + ok(returned_data[i] == bitmap_data[i], "returned_data[%i] == %i\n", i, returned_data[i]); + + /* try a valid partial rect, and write mode */ + rc.X = 2; + rc.Y = 0; + rc.Width = 1; + rc.Height = 2; + hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockWrite, &lock); + ok(hr == S_OK, "IWICBitmap_Lock failed hr=%x\n", hr); + + if (SUCCEEDED(hr)) + { + if (can_lock_null) /* this hangs on xp/vista */ + { + /* 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); + + hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock2); + ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%x\n", hr); + } + + hr = IWICBitmapLock_GetStride(lock, &lock_buffer_stride); + ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%x\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(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(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(width == 1, "got %d, expected 1\n", width); + ok(height == 2, "got %d, expected 2\n", height); + + IWICBitmapLock_Release(lock); + } + + hr = IWICBitmap_GetPixelFormat(bitmap, &pixelformat); + ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%x\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(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); + + hr = IWICBitmap_GetResolution(bitmap, &dpix, &dpiy); + ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%x\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(width == 3, "got %d, expected 3\n", width); + ok(height == 3, "got %d, expected 3\n", height); + + IWICBitmap_Release(bitmap); +} + +START_TEST(bitmap) +{ + HRESULT hr; + + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICImagingFactory, (void**)&factory); + ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr); + + test_createbitmap(); + + IWICImagingFactory_Release(factory); + + CoUninitialize(); +} diff --git a/include/wincodec.idl b/include/wincodec.idl index ab1e49012f6..a878b2f276c 100644 --- a/include/wincodec.idl +++ b/include/wincodec.idl @@ -81,6 +81,12 @@ typedef enum WICBitmapInterpolationMode { WICBITMAPINTERPOLATIONMODE_FORCE_DWORD = CODEC_FORCE_DWORD } WICBitmapInterpolationMode; +typedef enum WICBitmapLockFlags { + WICBitmapLockRead = 0x00000001, + WICBitmapLockWrite = 0x00000002, + WICBITMAPLOCKFLAGS_FORCE_DWORD = CODEC_FORCE_DWORD +} WICBitmapLockFlags; + typedef enum WICBitmapPaletteType { WICBitmapPaletteTypeCustom = 0x00000000, WICBitmapPaletteTypeMedianCut = 0x00000001, @@ -201,6 +207,7 @@ typedef UINT32 WICColor; cpp_quote("#define WINCODEC_ERR_WRONGSTATE 0x88982f04") cpp_quote("#define WINCODEC_ERR_VALUEOUTOFRANGE 0x88982f05") cpp_quote("#define WINCODEC_ERR_NOTINITIALIZED 0x88982f0c") +cpp_quote("#define WINCODEC_ERR_ALREADYLOCKED 0x88982f0d") cpp_quote("#define WINCODEC_ERR_PROPERTYNOTFOUND 0x88982f40") cpp_quote("#define WINCODEC_ERR_CODECNOTHUMBNAIL 0x88982f44") cpp_quote("#define WINCODEC_ERR_PALETTEUNAVAILABLE 0x88982f45")