1 /* 2 * Unit test suite for bitmaps 3 * 4 * Copyright 2004 Huw Davies 5 * Copyright 2006 Dmitry Timoshkov 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #include "precomp.h" 23 24 #ifndef __REACTOS__ /* CORE-11331 */ 25 #include "wine/ddk/d3dkmthk.h" 26 #endif 27 28 #ifndef __REACTOS__ /* CORE-11331 */ 29 static NTSTATUS (WINAPI *pD3DKMTCreateDCFromMemory)( D3DKMT_CREATEDCFROMMEMORY *desc ); 30 static NTSTATUS (WINAPI *pD3DKMTDestroyDCFromMemory)( const D3DKMT_DESTROYDCFROMMEMORY *desc ); 31 #endif 32 static BOOL (WINAPI *pGdiAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION); 33 static BOOL (WINAPI *pGdiGradientFill)(HDC,TRIVERTEX*,ULONG,void*,ULONG,ULONG); 34 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout); 35 36 static inline int get_bitmap_stride( int width, int bpp ) 37 { 38 return ((width * bpp + 15) >> 3) & ~1; 39 } 40 41 static inline int get_dib_stride( int width, int bpp ) 42 { 43 return ((width * bpp + 31) >> 3) & ~3; 44 } 45 46 static inline int get_dib_image_size( const BITMAPINFO *info ) 47 { 48 return get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount ) 49 * abs( info->bmiHeader.biHeight ); 50 } 51 52 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih) 53 { 54 BITMAP bm; 55 BITMAP bma[2]; 56 INT ret, width_bytes, i; 57 BYTE buf[512], buf_cmp[512]; 58 INT test_size[] = {0 /*first value will be changed */, 0, -1, -1000, ~0, sizeof(buf)}; 59 60 ret = GetObjectW(hbm, sizeof(bm), &bm); 61 ok(ret == sizeof(bm), "GetObject returned %d\n", ret); 62 63 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType); 64 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth); 65 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight); 66 width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel); 67 ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes); 68 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes); 69 ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth); 70 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits); 71 72 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight); 73 assert(sizeof(buf) == sizeof(buf_cmp)); 74 75 SetLastError(0xdeadbeef); 76 test_size[0] = bm.bmWidthBytes * bm.bmHeight; 77 /* NULL output buffer with different count values */ 78 for (i = 0; i < sizeof(test_size) / sizeof(test_size[0]); i++) 79 { 80 ret = GetBitmapBits(hbm, test_size[i], NULL); 81 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight); 82 } 83 84 memset(buf_cmp, 0xAA, sizeof(buf_cmp)); 85 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight); 86 87 /* Correct output buffer with different count values */ 88 for (i = 0; i < sizeof(test_size) / sizeof(test_size[0]); i++) 89 { 90 int expect = i == 1 ? 0 : bm.bmWidthBytes * bm.bmHeight; 91 memset(buf, 0xAA, sizeof(buf)); 92 ret = GetBitmapBits(hbm, test_size[i], buf); 93 ok(ret == expect, "Test[%d]: %d != %d\n", i, ret, expect); 94 if (expect) 95 ok(!memcmp(buf, buf_cmp, sizeof(buf)), 96 "Test[%d]: buffers do not match, depth %d\n", i, bmih->biBitCount); 97 } 98 99 /* test various buffer sizes for GetObject */ 100 ret = GetObjectW(hbm, sizeof(*bma) * 2, bma); 101 ok(ret == sizeof(*bma), "wrong size %d\n", ret); 102 103 ret = GetObjectW(hbm, sizeof(bm) / 2, &bm); 104 ok(ret == 0, "%d != 0\n", ret); 105 106 ret = GetObjectW(hbm, 0, &bm); 107 ok(ret == 0, "%d != 0\n", ret); 108 109 ret = GetObjectW(hbm, 1, &bm); 110 ok(ret == 0, "%d != 0\n", ret); 111 112 ret = GetObjectW(hbm, 0, NULL); 113 ok(ret == sizeof(bm), "wrong size %d\n", ret); 114 } 115 116 static void test_createdibitmap(void) 117 { 118 HDC hdc, hdcmem; 119 BITMAPINFOHEADER bmih; 120 BITMAPINFO bm; 121 HBITMAP hbm, hbm_colour, hbm_old; 122 INT screen_depth; 123 DWORD pixel; 124 125 hdc = GetDC(0); 126 screen_depth = GetDeviceCaps(hdc, BITSPIXEL); 127 memset(&bmih, 0, sizeof(bmih)); 128 bmih.biSize = sizeof(bmih); 129 bmih.biWidth = 10; 130 bmih.biHeight = 10; 131 bmih.biPlanes = 1; 132 bmih.biBitCount = 32; 133 bmih.biCompression = BI_RGB; 134 135 hbm = CreateDIBitmap(hdc, NULL, CBM_INIT, NULL, NULL, 0); 136 ok(hbm == NULL, "CreateDIBitmap should fail\n"); 137 hbm = CreateDIBitmap(hdc, NULL, 0, NULL, NULL, 0); 138 ok(hbm == NULL, "CreateDIBitmap should fail\n"); 139 140 /* First create an un-initialised bitmap. The depth of the bitmap 141 should match that of the hdc and not that supplied in bmih. 142 */ 143 144 /* First try 32 bits */ 145 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0); 146 ok(hbm != NULL, "CreateDIBitmap failed\n"); 147 test_bitmap_info(hbm, screen_depth, &bmih); 148 DeleteObject(hbm); 149 150 /* Then 16 */ 151 bmih.biBitCount = 16; 152 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0); 153 ok(hbm != NULL, "CreateDIBitmap failed\n"); 154 test_bitmap_info(hbm, screen_depth, &bmih); 155 DeleteObject(hbm); 156 157 /* Then 1 */ 158 bmih.biBitCount = 1; 159 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0); 160 ok(hbm != NULL, "CreateDIBitmap failed\n"); 161 test_bitmap_info(hbm, screen_depth, &bmih); 162 DeleteObject(hbm); 163 164 /* Now with a monochrome dc we expect a monochrome bitmap */ 165 hdcmem = CreateCompatibleDC(hdc); 166 167 /* First try 32 bits */ 168 bmih.biBitCount = 32; 169 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); 170 ok(hbm != NULL, "CreateDIBitmap failed\n"); 171 test_bitmap_info(hbm, 1, &bmih); 172 DeleteObject(hbm); 173 174 /* Then 16 */ 175 bmih.biBitCount = 16; 176 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); 177 ok(hbm != NULL, "CreateDIBitmap failed\n"); 178 test_bitmap_info(hbm, 1, &bmih); 179 DeleteObject(hbm); 180 181 /* Then 1 */ 182 bmih.biBitCount = 1; 183 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); 184 ok(hbm != NULL, "CreateDIBitmap failed\n"); 185 test_bitmap_info(hbm, 1, &bmih); 186 DeleteObject(hbm); 187 188 /* Now select a polychrome bitmap into the dc and we expect 189 screen_depth bitmaps again */ 190 hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight); 191 test_bitmap_info(hbm_colour, screen_depth, &bmih); 192 hbm_old = SelectObject(hdcmem, hbm_colour); 193 194 /* First try 32 bits */ 195 bmih.biBitCount = 32; 196 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); 197 ok(hbm != NULL, "CreateDIBitmap failed\n"); 198 test_bitmap_info(hbm, screen_depth, &bmih); 199 DeleteObject(hbm); 200 201 /* Then 16 */ 202 bmih.biBitCount = 16; 203 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); 204 ok(hbm != NULL, "CreateDIBitmap failed\n"); 205 test_bitmap_info(hbm, screen_depth, &bmih); 206 DeleteObject(hbm); 207 208 /* Then 1 */ 209 bmih.biBitCount = 1; 210 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); 211 ok(hbm != NULL, "CreateDIBitmap failed\n"); 212 test_bitmap_info(hbm, screen_depth, &bmih); 213 DeleteObject(hbm); 214 215 SelectObject(hdcmem, hbm_old); 216 DeleteObject(hbm_colour); 217 DeleteDC(hdcmem); 218 219 bmih.biBitCount = 32; 220 hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0); 221 ok(hbm != NULL, "CreateDIBitmap failed\n"); 222 test_bitmap_info(hbm, 1, &bmih); 223 DeleteObject(hbm); 224 225 /* Test how formats are converted */ 226 pixel = 0xffffffff; 227 bmih.biBitCount = 1; 228 bmih.biWidth = 1; 229 bmih.biHeight = 1; 230 231 memset(&bm, 0, sizeof(bm)); 232 bm.bmiHeader.biSize = sizeof(bm.bmiHeader); 233 bm.bmiHeader.biWidth = 1; 234 bm.bmiHeader.biHeight = 1; 235 bm.bmiHeader.biPlanes = 1; 236 bm.bmiHeader.biBitCount= 24; 237 bm.bmiHeader.biCompression= BI_RGB; 238 bm.bmiHeader.biSizeImage = 0; 239 hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS); 240 ok(hbm != NULL, "CreateDIBitmap failed\n"); 241 242 pixel = 0xdeadbeef; 243 bm.bmiHeader.biBitCount= 32; 244 GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS); 245 ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel); 246 DeleteObject(hbm); 247 248 ReleaseDC(0, hdc); 249 } 250 251 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih) 252 { 253 BITMAP bm; 254 BITMAP bma[2]; 255 DIBSECTION ds; 256 DIBSECTION dsa[2]; 257 INT ret, bm_width_bytes, dib_width_bytes; 258 BYTE *buf; 259 260 ret = GetObjectW(hbm, sizeof(bm), &bm); 261 ok(ret == sizeof(bm), "GetObject returned %d\n", ret); 262 263 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType); 264 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth); 265 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight); 266 dib_width_bytes = get_dib_stride(bm.bmWidth, bm.bmBitsPixel); 267 bm_width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel); 268 if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */ 269 ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes); 270 else 271 ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes); 272 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes); 273 ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount); 274 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits); 275 276 buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096); 277 278 /* GetBitmapBits returns not 32-bit aligned data */ 279 SetLastError(0xdeadbeef); 280 ret = GetBitmapBits(hbm, 0, NULL); 281 ok(ret == bm_width_bytes * bm.bmHeight, 282 "%d != %d\n", ret, bm_width_bytes * bm.bmHeight); 283 284 memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096); 285 ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf); 286 ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight); 287 288 HeapFree(GetProcessHeap(), 0, buf); 289 290 /* test various buffer sizes for GetObject */ 291 memset(&ds, 0xAA, sizeof(ds)); 292 ret = GetObjectW(hbm, sizeof(*bma) * 2, bma); 293 ok(ret == sizeof(*bma), "wrong size %d\n", ret); 294 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth); 295 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight); 296 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits); 297 298 ret = GetObjectW(hbm, sizeof(bm) / 2, &bm); 299 ok(ret == 0, "%d != 0\n", ret); 300 301 ret = GetObjectW(hbm, 0, &bm); 302 ok(ret == 0, "%d != 0\n", ret); 303 304 ret = GetObjectW(hbm, 1, &bm); 305 ok(ret == 0, "%d != 0\n", ret); 306 307 /* test various buffer sizes for GetObject */ 308 ret = GetObjectW(hbm, 0, NULL); 309 ok(ret == sizeof(bm), "wrong size %d\n", ret); 310 311 ret = GetObjectW(hbm, sizeof(*dsa) * 2, dsa); 312 ok(ret == sizeof(*dsa), "wrong size %d\n", ret); 313 314 memset(&ds, 0xAA, sizeof(ds)); 315 ret = GetObjectW(hbm, sizeof(ds), &ds); 316 ok(ret == sizeof(ds), "wrong size %d\n", ret); 317 318 ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits); 319 if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */ 320 ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n", 321 ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight); 322 ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage); 323 ds.dsBmih.biSizeImage = 0; 324 325 ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize); 326 ok(ds.dsBmih.biWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth); 327 ok(ds.dsBmih.biHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight)); 328 ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes); 329 ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount); 330 ok(ds.dsBmih.biCompression == bmih->biCompression || 331 ((bmih->biBitCount == 32) && broken(ds.dsBmih.biCompression == BI_BITFIELDS)), /* nt4 sp1 and 2 */ 332 "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression); 333 ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage); 334 ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%d != %d\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter); 335 ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%d != %d\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter); 336 337 memset(&ds, 0xAA, sizeof(ds)); 338 ret = GetObjectW(hbm, sizeof(ds) - 4, &ds); 339 ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret); 340 ok(ds.dsBm.bmWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth); 341 ok(ds.dsBm.bmHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight)); 342 ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits); 343 344 ret = GetObjectW(hbm, 0, &ds); 345 ok(ret == 0, "%d != 0\n", ret); 346 347 ret = GetObjectW(hbm, 1, &ds); 348 ok(ret == 0, "%d != 0\n", ret); 349 } 350 351 static void _test_color( int line, HDC hdc, COLORREF color, COLORREF exp ) 352 { 353 COLORREF c; 354 c = SetPixel(hdc, 0, 0, color); 355 ok_(__FILE__, line)(c == exp, "SetPixel failed: got 0x%06x expected 0x%06x\n", c, exp); 356 c = GetPixel(hdc, 0, 0); 357 ok_(__FILE__, line)(c == exp, "GetPixel failed: got 0x%06x expected 0x%06x\n", c, exp); 358 c = GetNearestColor(hdc, color); 359 ok_(__FILE__, line)(c == exp, "GetNearestColor failed: got 0x%06x expected 0x%06x\n", c, exp); 360 } 361 #define test_color(hdc, color, exp) _test_color( __LINE__, hdc, color, exp ) 362 363 364 static void test_dib_bits_access( HBITMAP hdib, void *bits ) 365 { 366 MEMORY_BASIC_INFORMATION info; 367 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)]; 368 DWORD data[256]; 369 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf; 370 HDC hdc; 371 char filename[MAX_PATH]; 372 HANDLE file; 373 DWORD written; 374 INT ret; 375 376 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info), 377 "VirtualQuery failed\n"); 378 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits); 379 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits); 380 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect); 381 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State); 382 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect); 383 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type); 384 385 memset( pbmi, 0, sizeof(bmibuf) ); 386 memset( data, 0xcc, sizeof(data) ); 387 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader); 388 pbmi->bmiHeader.biHeight = 16; 389 pbmi->bmiHeader.biWidth = 16; 390 pbmi->bmiHeader.biBitCount = 32; 391 pbmi->bmiHeader.biPlanes = 1; 392 pbmi->bmiHeader.biCompression = BI_RGB; 393 394 hdc = GetDC(0); 395 396 ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS ); 397 ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret); 398 399 ReleaseDC(0, hdc); 400 401 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info), 402 "VirtualQuery failed\n"); 403 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits); 404 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits); 405 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect); 406 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State); 407 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type); 408 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect); 409 410 /* try writing protected bits to a file */ 411 412 GetTempFileNameA( ".", "dib", 0, filename ); 413 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, 414 CREATE_ALWAYS, 0, 0 ); 415 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() ); 416 ret = WriteFile( file, bits, 8192, &written, NULL ); 417 ok( ret, "WriteFile failed error %u\n", GetLastError() ); 418 if (ret) ok( written == 8192, "only wrote %u bytes\n", written ); 419 CloseHandle( file ); 420 DeleteFileA( filename ); 421 } 422 423 static void test_dibsections(void) 424 { 425 HDC hdc, hdcmem, hdcmem2; 426 HBITMAP hdib, oldbm, hdib2, oldbm2; 427 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)]; 428 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)]; 429 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf; 430 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf; 431 RGBQUAD *colors = pbmi->bmiColors; 432 RGBTRIPLE *ccolors = pbci->bmciColors; 433 HBITMAP hcoredib; 434 char coreBits[256]; 435 BYTE *bits; 436 RGBQUAD rgb[256]; 437 int ret; 438 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)]; 439 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf; 440 PALETTEENTRY *palent = plogpal->palPalEntry; 441 WORD *index; 442 DWORD *bits32; 443 HPALETTE hpal, oldpal; 444 DIBSECTION dibsec; 445 COLORREF c0, c1; 446 int i; 447 MEMORY_BASIC_INFORMATION info; 448 449 hdc = GetDC(0); 450 451 memset(pbmi, 0, sizeof(bmibuf)); 452 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader); 453 pbmi->bmiHeader.biHeight = 100; 454 pbmi->bmiHeader.biWidth = 512; 455 pbmi->bmiHeader.biBitCount = 24; 456 pbmi->bmiHeader.biPlanes = 1; 457 pbmi->bmiHeader.biCompression = BI_RGB; 458 459 SetLastError(0xdeadbeef); 460 461 /* invalid pointer for BITMAPINFO 462 (*bits should be NULL on error) */ 463 bits = (BYTE*)0xdeadbeef; 464 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0); 465 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n"); 466 467 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); 468 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError()); 469 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n"); 470 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits); 471 472 /* test the DIB memory */ 473 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info), 474 "VirtualQuery failed\n"); 475 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits); 476 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits); 477 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect); 478 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize); 479 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State); 480 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect); 481 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type); 482 483 test_dib_bits_access( hdib, bits ); 484 485 test_dib_info(hdib, bits, &pbmi->bmiHeader); 486 DeleteObject(hdib); 487 488 /* Test a top-down DIB. */ 489 pbmi->bmiHeader.biHeight = -100; 490 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); 491 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError()); 492 test_dib_info(hdib, bits, &pbmi->bmiHeader); 493 DeleteObject(hdib); 494 495 pbmi->bmiHeader.biHeight = 100; 496 pbmi->bmiHeader.biBitCount = 8; 497 pbmi->bmiHeader.biCompression = BI_RLE8; 498 SetLastError(0xdeadbeef); 499 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); 500 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n"); 501 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError()); 502 503 pbmi->bmiHeader.biBitCount = 16; 504 pbmi->bmiHeader.biCompression = BI_BITFIELDS; 505 ((PDWORD)pbmi->bmiColors)[0] = 0xf800; 506 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0; 507 ((PDWORD)pbmi->bmiColors)[2] = 0x001f; 508 SetLastError(0xdeadbeef); 509 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); 510 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError()); 511 512 /* test the DIB memory */ 513 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info), 514 "VirtualQuery failed\n"); 515 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits); 516 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits); 517 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect); 518 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize); 519 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State); 520 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect); 521 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type); 522 523 test_dib_info(hdib, bits, &pbmi->bmiHeader); 524 DeleteObject(hdib); 525 526 memset(pbmi, 0, sizeof(bmibuf)); 527 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader); 528 pbmi->bmiHeader.biHeight = 16; 529 pbmi->bmiHeader.biWidth = 16; 530 pbmi->bmiHeader.biBitCount = 1; 531 pbmi->bmiHeader.biPlanes = 1; 532 pbmi->bmiHeader.biCompression = BI_RGB; 533 colors[0].rgbRed = 0xff; 534 colors[0].rgbGreen = 0; 535 colors[0].rgbBlue = 0; 536 colors[1].rgbRed = 0; 537 colors[1].rgbGreen = 0; 538 colors[1].rgbBlue = 0xff; 539 540 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); 541 ok(hdib != NULL, "CreateDIBSection failed\n"); 542 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n"); 543 ok(dibsec.dsBmih.biClrUsed == 2, 544 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2); 545 546 /* Test if the old BITMAPCOREINFO structure is supported */ 547 548 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER); 549 pbci->bmciHeader.bcBitCount = 0; 550 551 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS); 552 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n"); 553 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16) 554 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1), 555 "GetDIBits didn't fill in the BITMAPCOREHEADER structure properly\n"); 556 557 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS); 558 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n"); 559 ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) && 560 (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) && 561 (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff), 562 "The color table has not been translated to the old BITMAPCOREINFO format\n"); 563 564 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0); 565 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n"); 566 567 ZeroMemory(ccolors, 256 * sizeof(RGBTRIPLE)); 568 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS); 569 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n"); 570 ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) && 571 (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) && 572 (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff), 573 "The color table has not been translated to the old BITMAPCOREINFO format\n"); 574 575 DeleteObject(hcoredib); 576 577 hdcmem = CreateCompatibleDC(hdc); 578 oldbm = SelectObject(hdcmem, hdib); 579 580 ret = GetDIBColorTable(hdcmem, 0, 2, rgb); 581 ok(ret == 2, "GetDIBColorTable returned %d\n", ret); 582 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)), 583 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n", 584 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved, 585 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved); 586 587 c0 = RGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue); 588 c1 = RGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue); 589 590 test_color(hdcmem, DIBINDEX(0), c0); 591 test_color(hdcmem, DIBINDEX(1), c1); 592 test_color(hdcmem, DIBINDEX(2), c0); 593 test_color(hdcmem, PALETTEINDEX(0), c0); 594 test_color(hdcmem, PALETTEINDEX(1), c0); 595 test_color(hdcmem, PALETTEINDEX(2), c0); 596 test_color(hdcmem, PALETTERGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue), c0); 597 test_color(hdcmem, PALETTERGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue), c1); 598 test_color(hdcmem, PALETTERGB(0, 0, 0), c0); 599 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0); 600 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1); 601 602 SelectObject(hdcmem, oldbm); 603 DeleteObject(hdib); 604 605 colors[0].rgbRed = 0xff; 606 colors[0].rgbGreen = 0xff; 607 colors[0].rgbBlue = 0xff; 608 colors[1].rgbRed = 0; 609 colors[1].rgbGreen = 0; 610 colors[1].rgbBlue = 0; 611 612 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); 613 ok(hdib != NULL, "CreateDIBSection failed\n"); 614 615 test_dib_info(hdib, bits, &pbmi->bmiHeader); 616 617 oldbm = SelectObject(hdcmem, hdib); 618 619 ret = GetDIBColorTable(hdcmem, 0, 2, rgb); 620 ok(ret == 2, "GetDIBColorTable returned %d\n", ret); 621 ok(!memcmp(rgb, colors, 2 * sizeof(RGBQUAD)), 622 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n", 623 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved, 624 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved); 625 626 SelectObject(hdcmem, oldbm); 627 test_dib_info(hdib, bits, &pbmi->bmiHeader); 628 DeleteObject(hdib); 629 630 pbmi->bmiHeader.biBitCount = 4; 631 for (i = 0; i < 16; i++) { 632 colors[i].rgbRed = i; 633 colors[i].rgbGreen = 16-i; 634 colors[i].rgbBlue = 0; 635 } 636 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); 637 ok(hdib != NULL, "CreateDIBSection failed\n"); 638 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n"); 639 ok(dibsec.dsBmih.biClrUsed == 16, 640 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16); 641 test_dib_info(hdib, bits, &pbmi->bmiHeader); 642 DeleteObject(hdib); 643 644 pbmi->bmiHeader.biBitCount = 8; 645 646 for (i = 0; i < 128; i++) { 647 colors[i].rgbRed = 255 - i * 2; 648 colors[i].rgbGreen = i * 2; 649 colors[i].rgbBlue = 0; 650 colors[255 - i].rgbRed = 0; 651 colors[255 - i].rgbGreen = i * 2; 652 colors[255 - i].rgbBlue = 255 - i * 2; 653 } 654 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); 655 ok(hdib != NULL, "CreateDIBSection failed\n"); 656 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n"); 657 ok(dibsec.dsBmih.biClrUsed == 256, 658 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256); 659 660 oldbm = SelectObject(hdcmem, hdib); 661 662 for (i = 0; i < 256; i++) { 663 test_color(hdcmem, DIBINDEX(i), RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue)); 664 test_color(hdcmem, PALETTERGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue), 665 RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue)); 666 } 667 668 SelectObject(hdcmem, oldbm); 669 test_dib_info(hdib, bits, &pbmi->bmiHeader); 670 DeleteObject(hdib); 671 672 pbmi->bmiHeader.biBitCount = 1; 673 674 /* Now create a palette and a palette indexed dib section */ 675 memset(plogpal, 0, sizeof(logpalbuf)); 676 plogpal->palVersion = 0x300; 677 plogpal->palNumEntries = 2; 678 palent[0].peRed = 0xff; 679 palent[0].peBlue = 0xff; 680 palent[1].peGreen = 0xff; 681 682 index = (WORD*)pbmi->bmiColors; 683 *index++ = 0; 684 *index = 1; 685 hpal = CreatePalette(plogpal); 686 ok(hpal != NULL, "CreatePalette failed\n"); 687 oldpal = SelectPalette(hdc, hpal, TRUE); 688 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0); 689 ok(hdib != NULL, "CreateDIBSection failed\n"); 690 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n"); 691 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2); 692 693 /* The colour table has already been grabbed from the dc, so we select back the 694 old palette */ 695 696 SelectPalette(hdc, oldpal, TRUE); 697 oldbm = SelectObject(hdcmem, hdib); 698 oldpal = SelectPalette(hdcmem, hpal, TRUE); 699 700 ret = GetDIBColorTable(hdcmem, 0, 2, rgb); 701 ok(ret == 2, "GetDIBColorTable returned %d\n", ret); 702 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 && 703 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff, 704 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n", 705 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved, 706 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved); 707 708 c0 = RGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue); 709 c1 = RGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue); 710 711 test_color(hdcmem, DIBINDEX(0), c0); 712 test_color(hdcmem, DIBINDEX(1), c1); 713 test_color(hdcmem, DIBINDEX(2), c0); 714 test_color(hdcmem, PALETTEINDEX(0), c0); 715 test_color(hdcmem, PALETTEINDEX(1), c1); 716 test_color(hdcmem, PALETTEINDEX(2), c0); 717 test_color(hdcmem, PALETTERGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue), c0); 718 test_color(hdcmem, PALETTERGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue), c1); 719 test_color(hdcmem, PALETTERGB(0, 0, 0), c1); 720 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0); 721 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0); 722 test_color(hdcmem, PALETTERGB(0, 1, 0), c1); 723 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1); 724 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0); 725 726 /* Bottom and 2nd row from top green, everything else magenta */ 727 bits[0] = bits[1] = 0xff; 728 bits[13 * 4] = bits[13*4 + 1] = 0xff; 729 730 test_dib_info(hdib, bits, &pbmi->bmiHeader); 731 732 pbmi->bmiHeader.biBitCount = 32; 733 734 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0); 735 ok(hdib2 != NULL, "CreateDIBSection failed\n"); 736 hdcmem2 = CreateCompatibleDC(hdc); 737 oldbm2 = SelectObject(hdcmem2, hdib2); 738 739 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY); 740 741 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]); 742 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]); 743 744 SelectObject(hdcmem2, oldbm2); 745 test_dib_info(hdib2, bits32, &pbmi->bmiHeader); 746 DeleteObject(hdib2); 747 748 SelectObject(hdcmem, oldbm); 749 SelectPalette(hdcmem, oldpal, TRUE); 750 DeleteObject(hdib); 751 DeleteObject(hpal); 752 753 754 pbmi->bmiHeader.biBitCount = 8; 755 756 memset(plogpal, 0, sizeof(logpalbuf)); 757 plogpal->palVersion = 0x300; 758 plogpal->palNumEntries = 256; 759 760 for (i = 0; i < 128; i++) { 761 palent[i].peRed = 255 - i * 2; 762 palent[i].peBlue = i * 2; 763 palent[i].peGreen = 0; 764 palent[255 - i].peRed = 0; 765 palent[255 - i].peGreen = i * 2; 766 palent[255 - i].peBlue = 255 - i * 2; 767 } 768 769 index = (WORD*)pbmi->bmiColors; 770 for (i = 0; i < 256; i++) { 771 *index++ = i; 772 } 773 774 hpal = CreatePalette(plogpal); 775 ok(hpal != NULL, "CreatePalette failed\n"); 776 oldpal = SelectPalette(hdc, hpal, TRUE); 777 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0); 778 ok(hdib != NULL, "CreateDIBSection failed\n"); 779 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n"); 780 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256); 781 782 test_dib_info(hdib, bits, &pbmi->bmiHeader); 783 784 SelectPalette(hdc, oldpal, TRUE); 785 oldbm = SelectObject(hdcmem, hdib); 786 oldpal = SelectPalette(hdcmem, hpal, TRUE); 787 788 ret = GetDIBColorTable(hdcmem, 0, 256, rgb); 789 ok(ret == 256, "GetDIBColorTable returned %d\n", ret); 790 for (i = 0; i < 256; i++) { 791 ok(rgb[i].rgbRed == palent[i].peRed && 792 rgb[i].rgbBlue == palent[i].peBlue && 793 rgb[i].rgbGreen == palent[i].peGreen, 794 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n", 795 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved); 796 } 797 798 for (i = 0; i < 256; i++) { 799 test_color(hdcmem, DIBINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue)); 800 test_color(hdcmem, PALETTEINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue)); 801 test_color(hdcmem, PALETTERGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue), 802 RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue)); 803 } 804 805 SelectPalette(hdcmem, oldpal, TRUE); 806 SelectObject(hdcmem, oldbm); 807 DeleteObject(hdib); 808 DeleteObject(hpal); 809 810 plogpal->palNumEntries = 37; 811 hpal = CreatePalette(plogpal); 812 ok(hpal != NULL, "CreatePalette failed\n"); 813 oldpal = SelectPalette(hdc, hpal, TRUE); 814 pbmi->bmiHeader.biClrUsed = 142; 815 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0); 816 ok(hdib != NULL, "CreateDIBSection failed\n"); 817 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n"); 818 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256); 819 820 test_dib_info(hdib, bits, &pbmi->bmiHeader); 821 822 SelectPalette(hdc, oldpal, TRUE); 823 oldbm = SelectObject(hdcmem, hdib); 824 825 memset( rgb, 0xcc, sizeof(rgb) ); 826 ret = GetDIBColorTable(hdcmem, 0, 256, rgb); 827 ok(ret == 256, "GetDIBColorTable returned %d\n", ret); 828 for (i = 0; i < 256; i++) 829 { 830 if (i < pbmi->bmiHeader.biClrUsed) 831 { 832 ok(rgb[i].rgbRed == palent[i % 37].peRed && 833 rgb[i].rgbBlue == palent[i % 37].peBlue && 834 rgb[i].rgbGreen == palent[i % 37].peGreen, 835 "GetDIBColorTable returns table %d: r %02x g %02x b %02x res%02x\n", 836 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved); 837 test_color(hdcmem, DIBINDEX(i), 838 RGB(palent[i % 37].peRed, palent[i % 37].peGreen, palent[i % 37].peBlue)); 839 } 840 else 841 { 842 ok(rgb[i].rgbRed == 0 && rgb[i].rgbBlue == 0 && rgb[i].rgbGreen == 0, 843 "GetDIBColorTable returns table %d: r %02x g %02x b %02x res%02x\n", 844 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved); 845 test_color(hdcmem, DIBINDEX(i), 0 ); 846 } 847 } 848 pbmi->bmiHeader.biClrUsed = 173; 849 memset( pbmi->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) ); 850 GetDIBits( hdc, hdib, 0, 1, NULL, pbmi, DIB_RGB_COLORS ); 851 ok( pbmi->bmiHeader.biClrUsed == 0, "wrong colors %u\n", pbmi->bmiHeader.biClrUsed ); 852 for (i = 0; i < 256; i++) 853 { 854 if (i < 142) 855 ok(colors[i].rgbRed == palent[i % 37].peRed && 856 colors[i].rgbBlue == palent[i % 37].peBlue && 857 colors[i].rgbGreen == palent[i % 37].peGreen, 858 "GetDIBits returns table %d: r %02x g %02x b %02x res%02x\n", 859 i, colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved); 860 else 861 ok(colors[i].rgbRed == 0 && colors[i].rgbBlue == 0 && colors[i].rgbGreen == 0, 862 "GetDIBits returns table %d: r %02x g %02x b %02x res%02x\n", 863 i, colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved); 864 } 865 866 rgb[0].rgbRed = 1; 867 rgb[0].rgbGreen = 2; 868 rgb[0].rgbBlue = 3; 869 rgb[0].rgbReserved = 123; 870 ret = SetDIBColorTable( hdcmem, 0, 1, rgb ); 871 ok( ret == 1, "SetDIBColorTable returned unexpected result %u\n", ret ); 872 ok( rgb[0].rgbReserved == 123, "Expected rgbReserved = 123, got %u\n", rgb[0].rgbReserved ); 873 874 rgb[0].rgbRed = rgb[0].rgbGreen = rgb[0].rgbBlue = rgb[0].rgbReserved = -1; 875 ret = GetDIBColorTable( hdcmem, 0, 1, rgb ); 876 ok( ret == 1, "GetDIBColorTable returned unexpected result %u\n", ret ); 877 ok( rgb[0].rgbRed == 1, "Expected rgbRed = 1, got %u\n", rgb[0].rgbRed ); 878 ok( rgb[0].rgbGreen == 2, "Expected rgbGreen = 2, got %u\n", rgb[0].rgbGreen ); 879 ok( rgb[0].rgbBlue == 3, "Expected rgbBlue = 3, got %u\n", rgb[0].rgbBlue ); 880 ok( rgb[0].rgbReserved == 0, "Expected rgbReserved = 0, got %u\n", rgb[0].rgbReserved ); 881 882 SelectObject(hdcmem, oldbm); 883 DeleteObject(hdib); 884 DeleteObject(hpal); 885 886 /* ClrUsed ignored on > 8bpp */ 887 pbmi->bmiHeader.biBitCount = 16; 888 pbmi->bmiHeader.biClrUsed = 37; 889 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0); 890 ok(hdib != NULL, "CreateDIBSection failed\n"); 891 ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n"); 892 ok(dibsec.dsBmih.biClrUsed == 0, "created DIBSection: wrong biClrUsed field: %u\n", dibsec.dsBmih.biClrUsed); 893 oldbm = SelectObject(hdcmem, hdib); 894 ret = GetDIBColorTable(hdcmem, 0, 256, rgb); 895 ok(ret == 0, "GetDIBColorTable returned %d\n", ret); 896 SelectObject(hdcmem, oldbm); 897 DeleteObject(hdib); 898 899 DeleteDC(hdcmem); 900 DeleteDC(hdcmem2); 901 ReleaseDC(0, hdc); 902 } 903 904 static void test_dib_formats(void) 905 { 906 BITMAPINFO *bi; 907 char data[256]; 908 void *bits; 909 int planes, bpp, compr, format; 910 HBITMAP hdib, hbmp; 911 HDC hdc, memdc; 912 UINT ret; 913 BOOL format_ok, expect_ok; 914 915 bi = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ); 916 hdc = GetDC( 0 ); 917 memdc = CreateCompatibleDC( 0 ); 918 hbmp = CreateCompatibleBitmap( hdc, 10, 10 ); 919 920 memset( data, 0xaa, sizeof(data) ); 921 922 if (!winetest_interactive) 923 skip("ROSTESTS-152: Skipping loop in test_dib_formats because it's too big and causes too many failures\n"); 924 else 925 for (bpp = 0; bpp <= 64; bpp++) 926 { 927 for (planes = 0; planes <= 64; planes++) 928 { 929 for (compr = 0; compr < 8; compr++) 930 { 931 for (format = DIB_RGB_COLORS; format <= DIB_PAL_COLORS; format++) 932 { 933 switch (bpp) 934 { 935 case 1: 936 case 4: 937 case 8: 938 case 24: expect_ok = (compr == BI_RGB); break; 939 case 16: 940 case 32: expect_ok = (compr == BI_RGB || compr == BI_BITFIELDS); break; 941 default: expect_ok = FALSE; break; 942 } 943 944 memset( bi, 0, sizeof(bi->bmiHeader) ); 945 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 946 bi->bmiHeader.biWidth = 2; 947 bi->bmiHeader.biHeight = 2; 948 bi->bmiHeader.biPlanes = planes; 949 bi->bmiHeader.biBitCount = bpp; 950 bi->bmiHeader.biCompression = compr; 951 bi->bmiHeader.biSizeImage = 0; 952 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 ); 953 ret = GetDIBits(hdc, hbmp, 0, 0, data, bi, format); 954 if (expect_ok || (!bpp && compr != BI_JPEG && compr != BI_PNG) || 955 (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)) 956 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format ); 957 else 958 ok( !ret || broken(!bpp && (compr == BI_JPEG || compr == BI_PNG)), /* nt4 */ 959 "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format ); 960 961 /* all functions check planes except GetDIBits with 0 lines */ 962 format_ok = expect_ok; 963 if (!planes) expect_ok = FALSE; 964 memset( bi, 0, sizeof(bi->bmiHeader) ); 965 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 966 bi->bmiHeader.biWidth = 2; 967 bi->bmiHeader.biHeight = 2; 968 bi->bmiHeader.biPlanes = planes; 969 bi->bmiHeader.biBitCount = bpp; 970 bi->bmiHeader.biCompression = compr; 971 bi->bmiHeader.biSizeImage = 0; 972 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 ); 973 974 hdib = CreateDIBSection(hdc, bi, format, &bits, NULL, 0); 975 if (expect_ok && (planes == 1 || planes * bpp <= 16) && 976 (compr != BI_BITFIELDS || format != DIB_PAL_COLORS)) 977 ok( hdib != NULL, "CreateDIBSection failed for %u/%u/%u/%u\n", bpp, planes, compr, format ); 978 else 979 ok( hdib == NULL, "CreateDIBSection succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format ); 980 if (hdib) DeleteObject( hdib ); 981 982 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, data, bi, format ); 983 /* no sanity checks in CreateDIBitmap except compression */ 984 if (compr == BI_JPEG || compr == BI_PNG) 985 ok( hdib == NULL || broken(hdib != NULL), /* nt4 */ 986 "CreateDIBitmap succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format ); 987 else 988 ok( hdib != NULL, "CreateDIBitmap failed for %u/%u/%u/%u\n", bpp, planes, compr, format ); 989 if (hdib) DeleteObject( hdib ); 990 991 /* RLE needs a size */ 992 bi->bmiHeader.biSizeImage = 0; 993 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, format); 994 if (expect_ok) 995 ok( ret, "SetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format ); 996 else 997 ok( !ret || 998 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */ 999 "SetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format ); 1000 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, format ); 1001 if (expect_ok) 1002 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u/%u\n", bpp, planes, compr, format ); 1003 else 1004 ok( !ret || 1005 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */ 1006 "SetDIBitsToDevice succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format ); 1007 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, format, SRCCOPY ); 1008 if (expect_ok) 1009 ok( ret, "StretchDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format ); 1010 else 1011 ok( !ret || 1012 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */ 1013 "StretchDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format ); 1014 1015 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, format); 1016 if (expect_ok) 1017 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format ); 1018 else 1019 ok( !ret, "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format ); 1020 ok( bi->bmiHeader.biBitCount == bpp, "GetDIBits modified bpp %u/%u\n", 1021 bpp, bi->bmiHeader.biBitCount ); 1022 1023 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 1024 bi->bmiHeader.biWidth = 2; 1025 bi->bmiHeader.biHeight = 2; 1026 bi->bmiHeader.biPlanes = planes; 1027 bi->bmiHeader.biBitCount = bpp; 1028 bi->bmiHeader.biCompression = compr; 1029 bi->bmiHeader.biSizeImage = 1; 1030 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 ); 1031 /* RLE allowed with valid biSizeImage */ 1032 if ((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)) expect_ok = TRUE; 1033 1034 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, format); 1035 if (expect_ok) 1036 ok( ret, "SetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format ); 1037 else 1038 ok( !ret, "SetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format ); 1039 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, format ); 1040 if (expect_ok) 1041 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u/%u\n", bpp, planes, compr, format ); 1042 else 1043 ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format ); 1044 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, format, SRCCOPY ); 1045 if (expect_ok) 1046 ok( ret, "StretchDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format ); 1047 else 1048 ok( !ret, "StretchDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format ); 1049 1050 bi->bmiHeader.biSizeImage = 0; 1051 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, format); 1052 if (expect_ok || !bpp) 1053 ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format ); 1054 else 1055 ok( !ret || broken(format_ok && !planes), /* nt4 */ 1056 "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format ); 1057 } 1058 } 1059 } 1060 } 1061 1062 memset( bi, 0, sizeof(bi->bmiHeader) ); 1063 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 1064 bi->bmiHeader.biWidth = 2; 1065 bi->bmiHeader.biHeight = 2; 1066 bi->bmiHeader.biPlanes = 1; 1067 bi->bmiHeader.biBitCount = 16; 1068 bi->bmiHeader.biCompression = BI_BITFIELDS; 1069 bi->bmiHeader.biSizeImage = 0; 1070 *(DWORD *)&bi->bmiColors[0] = 0; 1071 *(DWORD *)&bi->bmiColors[1] = 0; 1072 *(DWORD *)&bi->bmiColors[2] = 0; 1073 1074 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0); 1075 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" ); 1076 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS); 1077 ok( !ret, "SetDIBits succeeded with null bitfields\n" ); 1078 /* other functions don't check */ 1079 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS ); 1080 ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" ); 1081 DeleteObject( hdib ); 1082 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS ); 1083 ok( ret, "SetDIBitsToDevice failed with null bitfields\n" ); 1084 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY ); 1085 ok( ret, "StretchDIBits failed with null bitfields\n" ); 1086 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS); 1087 ok( ret, "GetDIBits failed with null bitfields\n" ); 1088 bi->bmiHeader.biPlanes = 1; 1089 bi->bmiHeader.biBitCount = 16; 1090 bi->bmiHeader.biCompression = BI_BITFIELDS; 1091 bi->bmiHeader.biSizeImage = 0; 1092 *(DWORD *)&bi->bmiColors[0] = 0; 1093 *(DWORD *)&bi->bmiColors[1] = 0; 1094 *(DWORD *)&bi->bmiColors[2] = 0; 1095 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS); 1096 ok( ret, "GetDIBits failed with null bitfields\n" ); 1097 1098 /* all fields must be non-zero */ 1099 *(DWORD *)&bi->bmiColors[0] = 3; 1100 *(DWORD *)&bi->bmiColors[1] = 0; 1101 *(DWORD *)&bi->bmiColors[2] = 7; 1102 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0); 1103 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" ); 1104 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS); 1105 ok( !ret, "SetDIBits succeeded with null bitfields\n" ); 1106 1107 /* garbage is ok though */ 1108 *(DWORD *)&bi->bmiColors[0] = 0x55; 1109 *(DWORD *)&bi->bmiColors[1] = 0x44; 1110 *(DWORD *)&bi->bmiColors[2] = 0x33; 1111 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0); 1112 ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" ); 1113 if (hdib) DeleteObject( hdib ); 1114 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS); 1115 ok( ret, "SetDIBits failed with bad bitfields\n" ); 1116 1117 bi->bmiHeader.biWidth = -2; 1118 bi->bmiHeader.biHeight = 2; 1119 bi->bmiHeader.biBitCount = 32; 1120 bi->bmiHeader.biCompression = BI_RGB; 1121 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0); 1122 ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" ); 1123 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS ); 1124 ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" ); 1125 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS); 1126 ok( !ret, "SetDIBits succeeded with negative width\n" ); 1127 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS ); 1128 ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" ); 1129 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY ); 1130 ok( !ret, "StretchDIBits succeeded with negative width\n" ); 1131 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS); 1132 ok( !ret, "GetDIBits succeeded with negative width\n" ); 1133 bi->bmiHeader.biWidth = -2; 1134 bi->bmiHeader.biHeight = 2; 1135 bi->bmiHeader.biBitCount = 32; 1136 bi->bmiHeader.biCompression = BI_RGB; 1137 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS); 1138 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with negative width\n" ); 1139 1140 bi->bmiHeader.biWidth = 0; 1141 bi->bmiHeader.biHeight = 2; 1142 bi->bmiHeader.biBitCount = 32; 1143 bi->bmiHeader.biCompression = BI_RGB; 1144 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0); 1145 ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" ); 1146 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS ); 1147 ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" ); 1148 DeleteObject( hdib ); 1149 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS); 1150 ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" ); 1151 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS ); 1152 ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" ); 1153 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY ); 1154 ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" ); 1155 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS); 1156 ok( !ret, "GetDIBits succeeded with zero width\n" ); 1157 bi->bmiHeader.biWidth = 0; 1158 bi->bmiHeader.biHeight = 2; 1159 bi->bmiHeader.biBitCount = 32; 1160 bi->bmiHeader.biCompression = BI_RGB; 1161 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS); 1162 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero width\n" ); 1163 1164 bi->bmiHeader.biWidth = 2; 1165 bi->bmiHeader.biHeight = 0; 1166 bi->bmiHeader.biBitCount = 32; 1167 bi->bmiHeader.biCompression = BI_RGB; 1168 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0); 1169 ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" ); 1170 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS ); 1171 ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" ); 1172 DeleteObject( hdib ); 1173 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS); 1174 ok( !ret, "SetDIBits succeeded with zero height\n" ); 1175 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS ); 1176 ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" ); 1177 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY ); 1178 ok( !ret, "StretchDIBits succeeded with zero height\n" ); 1179 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS); 1180 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" ); 1181 bi->bmiHeader.biWidth = 2; 1182 bi->bmiHeader.biHeight = 0; 1183 bi->bmiHeader.biBitCount = 32; 1184 bi->bmiHeader.biCompression = BI_RGB; 1185 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS); 1186 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" ); 1187 1188 /* some functions accept DIB_PAL_COLORS+1, but not beyond */ 1189 1190 bi->bmiHeader.biWidth = 2; 1191 bi->bmiHeader.biHeight = 2; 1192 bi->bmiHeader.biBitCount = 1; 1193 bi->bmiHeader.biCompression = BI_RGB; 1194 hdib = CreateDIBSection(hdc, bi, DIB_PAL_COLORS+1, &bits, NULL, 0); 1195 ok( hdib == NULL, "CreateDIBSection succeeded with DIB_PAL_COLORS+1\n" ); 1196 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_PAL_COLORS+1 ); 1197 ok( hdib != NULL, "CreateDIBitmap failed with DIB_PAL_COLORS+1\n" ); 1198 DeleteObject( hdib ); 1199 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_PAL_COLORS+1); 1200 ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+1\n" ); 1201 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_PAL_COLORS+1 ); 1202 ok( ret, "SetDIBitsToDevice failed with DIB_PAL_COLORS+1\n" ); 1203 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_PAL_COLORS+1, SRCCOPY ); 1204 ok( ret, "StretchDIBits failed with DIB_PAL_COLORS+1\n" ); 1205 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_PAL_COLORS+1); 1206 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+1\n" ); 1207 bi->bmiHeader.biWidth = 2; 1208 bi->bmiHeader.biHeight = 2; 1209 bi->bmiHeader.biBitCount = 1; 1210 bi->bmiHeader.biCompression = BI_RGB; 1211 ret = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS+1); 1212 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+1\n" ); 1213 1214 bi->bmiHeader.biWidth = 2; 1215 bi->bmiHeader.biHeight = 2; 1216 bi->bmiHeader.biBitCount = 1; 1217 bi->bmiHeader.biCompression = BI_RGB; 1218 hdib = CreateDIBSection(hdc, bi, DIB_PAL_COLORS+2, &bits, NULL, 0); 1219 ok( hdib == NULL, "CreateDIBSection succeeded with DIB_PAL_COLORS+2\n" ); 1220 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_PAL_COLORS+2 ); 1221 ok( hdib == NULL, "CreateDIBitmap succeeded with DIB_PAL_COLORS+2\n" ); 1222 DeleteObject( hdib ); 1223 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_PAL_COLORS+2); 1224 ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+2\n" ); 1225 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_PAL_COLORS+2 ); 1226 ok( !ret, "SetDIBitsToDevice succeeded with DIB_PAL_COLORS+2\n" ); 1227 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_PAL_COLORS+2, SRCCOPY ); 1228 ok( !ret, "StretchDIBits succeeded with DIB_PAL_COLORS+2\n" ); 1229 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_PAL_COLORS+2); 1230 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+2\n" ); 1231 bi->bmiHeader.biWidth = 2; 1232 bi->bmiHeader.biHeight = 2; 1233 bi->bmiHeader.biBitCount = 1; 1234 bi->bmiHeader.biCompression = BI_RGB; 1235 ret = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS+2); 1236 ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+2\n" ); 1237 1238 bi->bmiHeader.biWidth = 0x4000; 1239 bi->bmiHeader.biHeight = 0x4000; 1240 bi->bmiHeader.biBitCount = 1; 1241 bi->bmiHeader.biCompression = BI_RGB; 1242 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0); 1243 ok( hdib != NULL, "CreateDIBSection failed with large size\n" ); 1244 DeleteObject( hdib ); 1245 1246 bi->bmiHeader.biWidth = 0x8001; 1247 bi->bmiHeader.biHeight = 0x8001; 1248 bi->bmiHeader.biBitCount = 32; 1249 bi->bmiHeader.biCompression = BI_RGB; 1250 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0); 1251 ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" ); 1252 1253 bi->bmiHeader.biWidth = 1; 1254 bi->bmiHeader.biHeight = 0x40000001; 1255 bi->bmiHeader.biBitCount = 32; 1256 bi->bmiHeader.biCompression = BI_RGB; 1257 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0); 1258 ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" ); 1259 1260 bi->bmiHeader.biWidth = 2; 1261 bi->bmiHeader.biHeight = 0x40000001; 1262 bi->bmiHeader.biBitCount = 16; 1263 bi->bmiHeader.biCompression = BI_RGB; 1264 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0); 1265 ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" ); 1266 1267 bi->bmiHeader.biWidth = 0x40000001; 1268 bi->bmiHeader.biHeight = 1; 1269 bi->bmiHeader.biBitCount = 32; 1270 bi->bmiHeader.biCompression = BI_RGB; 1271 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0); 1272 ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" ); 1273 1274 bi->bmiHeader.biWidth = 0x40000001; 1275 bi->bmiHeader.biHeight = 4; 1276 bi->bmiHeader.biBitCount = 8; 1277 bi->bmiHeader.biCompression = BI_RGB; 1278 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0); 1279 ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" ); 1280 1281 DeleteDC( memdc ); 1282 DeleteObject( hbmp ); 1283 ReleaseDC( 0, hdc ); 1284 HeapFree( GetProcessHeap(), 0, bi ); 1285 } 1286 1287 static void test_mono_dibsection(void) 1288 { 1289 HDC hdc, memdc; 1290 HBITMAP old_bm, mono_ds; 1291 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)]; 1292 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf; 1293 RGBQUAD *colors = pbmi->bmiColors; 1294 BYTE bits[10 * 4]; 1295 BYTE *ds_bits; 1296 int num; 1297 1298 hdc = GetDC(0); 1299 1300 memdc = CreateCompatibleDC(hdc); 1301 1302 memset(pbmi, 0, sizeof(bmibuf)); 1303 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader); 1304 pbmi->bmiHeader.biHeight = 10; 1305 pbmi->bmiHeader.biWidth = 10; 1306 pbmi->bmiHeader.biBitCount = 1; 1307 pbmi->bmiHeader.biPlanes = 1; 1308 pbmi->bmiHeader.biCompression = BI_RGB; 1309 colors[0].rgbRed = 0xff; 1310 colors[0].rgbGreen = 0xff; 1311 colors[0].rgbBlue = 0xff; 1312 colors[1].rgbRed = 0x0; 1313 colors[1].rgbGreen = 0x0; 1314 colors[1].rgbBlue = 0x0; 1315 1316 /* 1317 * First dib section is 'inverted' ie color[0] is white, color[1] is black 1318 */ 1319 1320 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0); 1321 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n"); 1322 old_bm = SelectObject(memdc, mono_ds); 1323 1324 /* black border, white interior */ 1325 Rectangle(memdc, 0, 0, 10, 10); 1326 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]); 1327 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]); 1328 1329 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */ 1330 1331 memset(bits, 0, sizeof(bits)); 1332 bits[0] = 0xaa; 1333 1334 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS); 1335 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]); 1336 1337 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */ 1338 1339 colors[0].rgbRed = 0x0; 1340 colors[0].rgbGreen = 0x0; 1341 colors[0].rgbBlue = 0x0; 1342 colors[1].rgbRed = 0xff; 1343 colors[1].rgbGreen = 0xff; 1344 colors[1].rgbBlue = 0xff; 1345 1346 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS); 1347 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]); 1348 1349 SelectObject(memdc, old_bm); 1350 DeleteObject(mono_ds); 1351 1352 /* 1353 * Next dib section is 'normal' ie color[0] is black, color[1] is white 1354 */ 1355 1356 colors[0].rgbRed = 0x0; 1357 colors[0].rgbGreen = 0x0; 1358 colors[0].rgbBlue = 0x0; 1359 colors[1].rgbRed = 0xff; 1360 colors[1].rgbGreen = 0xff; 1361 colors[1].rgbBlue = 0xff; 1362 1363 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0); 1364 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n"); 1365 old_bm = SelectObject(memdc, mono_ds); 1366 1367 /* black border, white interior */ 1368 Rectangle(memdc, 0, 0, 10, 10); 1369 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]); 1370 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]); 1371 1372 /* SetDIBitsToDevice with a normal bmi -> normal dib section */ 1373 1374 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS); 1375 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]); 1376 1377 /* SetDIBitsToDevice with an inverted bmi -> normal dib section */ 1378 1379 colors[0].rgbRed = 0xff; 1380 colors[0].rgbGreen = 0xff; 1381 colors[0].rgbBlue = 0xff; 1382 colors[1].rgbRed = 0x0; 1383 colors[1].rgbGreen = 0x0; 1384 colors[1].rgbBlue = 0x0; 1385 1386 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS); 1387 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]); 1388 1389 /* 1390 * Take that 'normal' dibsection and change its colour table to an 'inverted' one 1391 */ 1392 1393 colors[0].rgbRed = 0xff; 1394 colors[0].rgbGreen = 0xff; 1395 colors[0].rgbBlue = 0xff; 1396 colors[1].rgbRed = 0x0; 1397 colors[1].rgbGreen = 0x0; 1398 colors[1].rgbBlue = 0x0; 1399 num = SetDIBColorTable(memdc, 0, 2, colors); 1400 ok(num == 2, "num = %d\n", num); 1401 1402 /* black border, white interior */ 1403 Rectangle(memdc, 0, 0, 10, 10); 1404 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]); 1405 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]); 1406 1407 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */ 1408 1409 memset(bits, 0, sizeof(bits)); 1410 bits[0] = 0xaa; 1411 1412 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS); 1413 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]); 1414 1415 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */ 1416 1417 colors[0].rgbRed = 0x0; 1418 colors[0].rgbGreen = 0x0; 1419 colors[0].rgbBlue = 0x0; 1420 colors[1].rgbRed = 0xff; 1421 colors[1].rgbGreen = 0xff; 1422 colors[1].rgbBlue = 0xff; 1423 1424 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS); 1425 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]); 1426 1427 SelectObject(memdc, old_bm); 1428 DeleteObject(mono_ds); 1429 1430 /* 1431 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one. 1432 */ 1433 1434 colors[0].rgbRed = 0xff; 1435 colors[0].rgbGreen = 0x0; 1436 colors[0].rgbBlue = 0x0; 1437 colors[1].rgbRed = 0xfe; 1438 colors[1].rgbGreen = 0x0; 1439 colors[1].rgbBlue = 0x0; 1440 1441 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0); 1442 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n"); 1443 old_bm = SelectObject(memdc, mono_ds); 1444 1445 /* black border, white interior */ 1446 Rectangle(memdc, 0, 0, 10, 10); 1447 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]); 1448 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]); 1449 1450 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */ 1451 1452 colors[0].rgbRed = 0x0; 1453 colors[0].rgbGreen = 0x0; 1454 colors[0].rgbBlue = 0x0; 1455 colors[1].rgbRed = 0xff; 1456 colors[1].rgbGreen = 0xff; 1457 colors[1].rgbBlue = 0xff; 1458 1459 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS); 1460 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]); 1461 1462 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */ 1463 1464 colors[0].rgbRed = 0xff; 1465 colors[0].rgbGreen = 0xff; 1466 colors[0].rgbBlue = 0xff; 1467 colors[1].rgbRed = 0x0; 1468 colors[1].rgbGreen = 0x0; 1469 colors[1].rgbBlue = 0x0; 1470 1471 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS); 1472 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]); 1473 1474 SelectObject(memdc, old_bm); 1475 DeleteObject(mono_ds); 1476 1477 DeleteDC(memdc); 1478 ReleaseDC(0, hdc); 1479 } 1480 1481 static void test_bitmap(void) 1482 { 1483 char buf[256], buf_cmp[256]; 1484 HBITMAP hbmp, hbmp_old; 1485 HDC hdc; 1486 BITMAP bm; 1487 BITMAP bma[2]; 1488 INT ret; 1489 1490 hdc = CreateCompatibleDC(0); 1491 assert(hdc != 0); 1492 1493 SetLastError(0xdeadbeef); 1494 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL); 1495 if (!hbmp) 1496 { 1497 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ || 1498 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */, 1499 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError()); 1500 } 1501 else 1502 DeleteObject(hbmp); 1503 1504 SetLastError(0xdeadbeef); 1505 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL); 1506 if (!hbmp) 1507 { 1508 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ || 1509 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */, 1510 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError()); 1511 } 1512 else 1513 DeleteObject(hbmp); 1514 1515 SetLastError(0xdeadbeef); 1516 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL); 1517 ok(!hbmp, "CreateBitmap should fail\n"); 1518 if (!hbmp) 1519 ok(GetLastError() == ERROR_INVALID_PARAMETER, 1520 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1521 else 1522 DeleteObject(hbmp); 1523 1524 hbmp = CreateBitmap(15, 15, 1, 1, NULL); 1525 assert(hbmp != NULL); 1526 1527 ret = GetObjectW(hbmp, sizeof(bm), &bm); 1528 ok(ret == sizeof(bm), "wrong size %d\n", ret); 1529 1530 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType); 1531 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth); 1532 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight); 1533 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes); 1534 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes); 1535 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel); 1536 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits); 1537 1538 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight); 1539 assert(sizeof(buf) == sizeof(buf_cmp)); 1540 1541 ret = GetBitmapBits(hbmp, 0, NULL); 1542 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight); 1543 1544 memset(buf_cmp, 0xAA, sizeof(buf_cmp)); 1545 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight); 1546 1547 memset(buf, 0xAA, sizeof(buf)); 1548 ret = GetBitmapBits(hbmp, sizeof(buf), buf); 1549 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight); 1550 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n"); 1551 1552 hbmp_old = SelectObject(hdc, hbmp); 1553 1554 ret = GetObjectW(hbmp, sizeof(bm), &bm); 1555 ok(ret == sizeof(bm), "wrong size %d\n", ret); 1556 1557 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType); 1558 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth); 1559 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight); 1560 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes); 1561 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes); 1562 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel); 1563 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits); 1564 1565 memset(buf, 0xAA, sizeof(buf)); 1566 ret = GetBitmapBits(hbmp, sizeof(buf), buf); 1567 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight); 1568 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n"); 1569 1570 hbmp_old = SelectObject(hdc, hbmp_old); 1571 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old); 1572 1573 /* test various buffer sizes for GetObject */ 1574 ret = GetObjectW(hbmp, sizeof(*bma) * 2, bma); 1575 ok(ret == sizeof(*bma), "wrong size %d\n", ret); 1576 1577 ret = GetObjectW(hbmp, sizeof(bm) / 2, &bm); 1578 ok(ret == 0, "%d != 0\n", ret); 1579 1580 ret = GetObjectW(hbmp, 0, &bm); 1581 ok(ret == 0, "%d != 0\n", ret); 1582 1583 ret = GetObjectW(hbmp, 1, &bm); 1584 ok(ret == 0, "%d != 0\n", ret); 1585 1586 DeleteObject(hbmp); 1587 DeleteDC(hdc); 1588 } 1589 1590 static COLORREF get_nearest( int r, int g, int b ) 1591 { 1592 return (r*r + g*g + b*b < (255-r)*(255-r) + (255-g)*(255-g) + (255-b)*(255-b)) ? 0x000000 : 0xffffff; 1593 } 1594 1595 static BOOL is_black_pen( COLORREF fg, COLORREF bg, int r, int g, int b ) 1596 { 1597 if (fg == 0 || bg == 0xffffff) return RGB(r,g,b) != 0xffffff && RGB(r,g,b) != bg; 1598 return RGB(r,g,b) == 0x000000 || RGB(r,g,b) == bg; 1599 } 1600 1601 static void test_bitmap_colors( HDC hdc, COLORREF fg, COLORREF bg, int r, int g, int b ) 1602 { 1603 static const WORD pattern_bits[] = { 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa }; 1604 char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors ) + 256 * sizeof(RGBQUAD)]; 1605 BITMAPINFO *info = (BITMAPINFO *)buffer; 1606 RGBQUAD *colors = info->bmiColors; 1607 WORD bits[16]; 1608 void *bits_ptr; 1609 COLORREF res; 1610 HBRUSH old_brush; 1611 HPEN old_pen; 1612 HBITMAP bitmap; 1613 HDC memdc; 1614 1615 res = SetPixel( hdc, 0, 0, RGB(r,g,b) ); 1616 ok( res == get_nearest( r, g, b ), 1617 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg ); 1618 res = GetPixel( hdc, 0, 0 ); 1619 ok( res == get_nearest( r, g, b ), 1620 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg ); 1621 res = GetNearestColor( hdc, RGB(r,g,b) ); 1622 ok( res == get_nearest( r, g, b ), 1623 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg ); 1624 1625 /* solid pen */ 1626 old_pen = SelectObject( hdc, CreatePen( PS_SOLID, 1, RGB(r,g,b) )); 1627 MoveToEx( hdc, 0, 0, NULL ); 1628 LineTo( hdc, 16, 0 ); 1629 res = GetPixel( hdc, 0, 0 ); 1630 ok( res == (is_black_pen( fg, bg, r, g, b ) ? 0 : 0xffffff), 1631 "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg ); 1632 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits ); 1633 ok( bits[0] == (is_black_pen( fg, bg, r, g, b ) ? 0x00 : 0xffff), 1634 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg ); 1635 DeleteObject( SelectObject( hdc, old_pen )); 1636 1637 /* mono DDB pattern brush */ 1638 bitmap = CreateBitmap( 16, 8, 1, 1, pattern_bits ); 1639 old_brush = SelectObject( hdc, CreatePatternBrush( bitmap )); 1640 PatBlt( hdc, 0, 0, 16, 16, PATCOPY ); 1641 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits ); 1642 ok( bits[0] == 0x5555 || broken(bits[0] == 0xaada) /* XP SP1 & 2003 SP0 */, 1643 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg ); 1644 DeleteObject( SelectObject( hdc, old_brush )); 1645 1646 /* mono DDB bitmap */ 1647 memdc = CreateCompatibleDC( hdc ); 1648 SelectObject( memdc, bitmap ); 1649 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY ); 1650 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits ); 1651 ok( bits[0] == 0x5555, 1652 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg ); 1653 SetTextColor( memdc, RGB(255,255,255) ); 1654 SetBkColor( memdc, RGB(0,0,0) ); 1655 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY ); 1656 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits ); 1657 ok( bits[0] == 0x5555, 1658 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg ); 1659 1660 /* mono DIB section */ 1661 memset( buffer, 0, sizeof(buffer) ); 1662 info->bmiHeader.biSize = sizeof(info->bmiHeader); 1663 info->bmiHeader.biHeight = -16; 1664 info->bmiHeader.biWidth = 16; 1665 info->bmiHeader.biBitCount = 1; 1666 info->bmiHeader.biPlanes = 1; 1667 info->bmiHeader.biCompression = BI_RGB; 1668 colors[0].rgbRed = 0xff; 1669 colors[0].rgbGreen = 0xff; 1670 colors[0].rgbBlue = 0xf0; 1671 colors[1].rgbRed = 0x20; 1672 colors[1].rgbGreen = 0x0; 1673 colors[1].rgbBlue = 0x0; 1674 bitmap = CreateDIBSection( 0, info, DIB_RGB_COLORS, &bits_ptr, NULL, 0 ); 1675 memset( bits_ptr, 0x55, 64 ); 1676 DeleteObject( SelectObject( memdc, bitmap )); 1677 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY ); 1678 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits ); 1679 ok( bits[0] == 0x5555, 1680 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg ); 1681 1682 colors[0].rgbRed = 0x0; 1683 colors[0].rgbGreen = 0x0; 1684 colors[0].rgbBlue = 0x10; 1685 colors[1].rgbRed = 0xff; 1686 colors[1].rgbGreen = 0xf0; 1687 colors[1].rgbBlue = 0xff; 1688 bitmap = CreateDIBSection( 0, info, DIB_RGB_COLORS, &bits_ptr, NULL, 0 ); 1689 memset( bits_ptr, 0x55, 64 ); 1690 DeleteObject( SelectObject( memdc, bitmap )); 1691 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY ); 1692 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits ); 1693 ok( bits[0] == 0xaaaa, 1694 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg ); 1695 1696 SetTextColor( memdc, RGB(0,20,0) ); 1697 SetBkColor( memdc, RGB(240,240,240) ); 1698 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY ); 1699 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits ); 1700 ok( bits[0] == 0x5555, 1701 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg ); 1702 1703 SetTextColor( memdc, RGB(250,250,250) ); 1704 SetBkColor( memdc, RGB(10,10,10) ); 1705 BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY ); 1706 GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits ); 1707 ok( bits[0] == 0xaaaa, 1708 "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg ); 1709 DeleteDC( memdc ); 1710 DeleteObject( bitmap ); 1711 } 1712 1713 static void test_mono_bitmap(void) 1714 { 1715 static const COLORREF colors[][2] = 1716 { 1717 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff) }, 1718 { RGB(0xff,0xff,0xff), RGB(0x00,0x00,0x00) }, 1719 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xfe) }, 1720 { RGB(0x00,0x01,0x00), RGB(0xff,0xff,0xff) }, 1721 { RGB(0x00,0x00,0x00), RGB(0x80,0x80,0x80) }, 1722 { RGB(0x80,0x80,0x80), RGB(0xff,0xff,0xff) }, 1723 { RGB(0x30,0x40,0x50), RGB(0x60,0x70,0x80) }, 1724 { RGB(0xa0,0xa0,0xa0), RGB(0x20,0x30,0x10) }, 1725 { PALETTEINDEX(0), PALETTEINDEX(255) }, 1726 { PALETTEINDEX(1), PALETTEINDEX(2) }, 1727 }; 1728 1729 HBITMAP hbmp; 1730 HDC hdc; 1731 DWORD col; 1732 int i, r, g, b; 1733 1734 if (!winetest_interactive) 1735 { 1736 skip("ROSTESTS-153: Skipping test_mono_bitmap because it causes too many failures and takes too long\n"); 1737 return; 1738 } 1739 1740 hdc = CreateCompatibleDC(0); 1741 assert(hdc != 0); 1742 1743 hbmp = CreateBitmap(16, 16, 1, 1, NULL); 1744 assert(hbmp != NULL); 1745 1746 SelectObject( hdc, hbmp ); 1747 1748 for (col = 0; col < sizeof(colors) / sizeof(colors[0]); col++) 1749 { 1750 SetTextColor( hdc, colors[col][0] ); 1751 SetBkColor( hdc, colors[col][1] ); 1752 1753 for (i = 0; i < 256; i++) 1754 { 1755 HPALETTE pal = GetCurrentObject( hdc, OBJ_PAL ); 1756 PALETTEENTRY ent; 1757 1758 if (!GetPaletteEntries( pal, i, 1, &ent )) GetPaletteEntries( pal, 0, 1, &ent ); 1759 test_color( hdc, PALETTEINDEX(i), get_nearest( ent.peRed, ent.peGreen, ent.peBlue )); 1760 test_color( hdc, DIBINDEX(i), (i == 1) ? 0xffffff : 0x000000 ); 1761 } 1762 1763 for (r = 0; r < 256; r += 15) 1764 for (g = 0; g < 256; g += 15) 1765 for (b = 0; b < 256; b += 15) 1766 test_bitmap_colors( hdc, colors[col][0], colors[col][1], r, g, b ); 1767 } 1768 1769 DeleteDC(hdc); 1770 DeleteObject(hbmp); 1771 } 1772 1773 static void test_bmBits(void) 1774 { 1775 BYTE bits[4]; 1776 HBITMAP hbmp; 1777 BITMAP bmp; 1778 1779 memset(bits, 0, sizeof(bits)); 1780 hbmp = CreateBitmap(2, 2, 1, 4, bits); 1781 ok(hbmp != NULL, "CreateBitmap failed\n"); 1782 1783 memset(&bmp, 0xFF, sizeof(bmp)); 1784 ok(GetObjectW(hbmp, sizeof(bmp), &bmp) == sizeof(bmp), 1785 "GetObject failed or returned a wrong structure size\n"); 1786 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n"); 1787 1788 DeleteObject(hbmp); 1789 } 1790 1791 static void test_GetDIBits_selected_DIB(UINT bpp) 1792 { 1793 HBITMAP dib; 1794 BITMAPINFO *info; 1795 BITMAPINFO *info2; 1796 void * bits; 1797 void * bits2; 1798 UINT dib_size, dib32_size; 1799 DWORD pixel; 1800 HDC dib_dc, dc; 1801 HBITMAP old_bmp; 1802 UINT i; 1803 int res; 1804 1805 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256])); 1806 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256])); 1807 1808 /* Create a DIB section with a color table */ 1809 1810 info->bmiHeader.biSize = sizeof(info->bmiHeader); 1811 info->bmiHeader.biWidth = 32; 1812 info->bmiHeader.biHeight = 32; 1813 info->bmiHeader.biPlanes = 1; 1814 info->bmiHeader.biBitCount = bpp; 1815 info->bmiHeader.biCompression = BI_RGB; 1816 info->bmiHeader.biXPelsPerMeter = 0; 1817 info->bmiHeader.biYPelsPerMeter = 0; 1818 info->bmiHeader.biClrUsed = 0; 1819 info->bmiHeader.biClrImportant = 0; 1820 1821 for (i=0; i < (1u << bpp); i++) 1822 { 1823 BYTE c = i * (1 << (8 - bpp)); 1824 info->bmiColors[i].rgbRed = c; 1825 info->bmiColors[i].rgbGreen = c; 1826 info->bmiColors[i].rgbBlue = c; 1827 info->bmiColors[i].rgbReserved = 0; 1828 } 1829 1830 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0); 1831 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8; 1832 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8; 1833 1834 /* Set the bits of the DIB section */ 1835 for (i=0; i < dib_size; i++) 1836 { 1837 ((BYTE *)bits)[i] = i % 256; 1838 } 1839 1840 /* Select the DIB into a DC */ 1841 dib_dc = CreateCompatibleDC(NULL); 1842 old_bmp = SelectObject(dib_dc, dib); 1843 dc = CreateCompatibleDC(NULL); 1844 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size); 1845 1846 /* Copy the DIB attributes but not the color table */ 1847 memcpy(info2, info, sizeof(BITMAPINFOHEADER)); 1848 1849 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS); 1850 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp ); 1851 1852 /* Compare the color table and the bits */ 1853 for (i=0; i < (1u << bpp); i++) 1854 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed && 1855 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen && 1856 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue && 1857 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved, 1858 "color table entry %d differs (bpp %d)\n", i, bpp ); 1859 1860 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp ); 1861 1862 /* Test various combinations of lines = 0 and bits2 = NULL */ 1863 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) ); 1864 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS ); 1865 ok( res == 1, "got %d (bpp %d)\n", res, bpp ); 1866 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ), 1867 "color table mismatch (bpp %d)\n", bpp ); 1868 1869 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) ); 1870 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS ); 1871 ok( res == 1, "got %d (bpp %d)\n", res, bpp ); 1872 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ), 1873 "color table mismatch (bpp %d)\n", bpp ); 1874 1875 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) ); 1876 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS ); 1877 ok( res == 1, "got %d (bpp %d)\n", res, bpp ); 1878 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ), 1879 "color table mismatch (bpp %d)\n", bpp ); 1880 1881 /* Map into a 32bit-DIB */ 1882 info2->bmiHeader.biBitCount = 32; 1883 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS); 1884 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp ); 1885 1886 /* Check if last pixel was set */ 1887 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1]; 1888 ok(pixel != 0, "Pixel: 0x%08x\n", pixel); 1889 1890 HeapFree(GetProcessHeap(), 0, bits2); 1891 DeleteDC(dc); 1892 1893 SelectObject(dib_dc, old_bmp); 1894 DeleteDC(dib_dc); 1895 DeleteObject(dib); 1896 HeapFree(GetProcessHeap(), 0, info2); 1897 HeapFree(GetProcessHeap(), 0, info); 1898 } 1899 1900 static void test_GetDIBits_selected_DDB(BOOL monochrome) 1901 { 1902 HBITMAP ddb; 1903 BITMAPINFO *info; 1904 BITMAPINFO *info2; 1905 void * bits; 1906 void * bits2; 1907 HDC ddb_dc, dc; 1908 HBITMAP old_bmp; 1909 UINT width, height; 1910 UINT bpp; 1911 UINT i, j; 1912 int res; 1913 1914 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256])); 1915 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256])); 1916 1917 width = height = 16; 1918 1919 /* Create a DDB (device-dependent bitmap) */ 1920 if (monochrome) 1921 { 1922 bpp = 1; 1923 ddb = CreateBitmap(width, height, 1, 1, NULL); 1924 } 1925 else 1926 { 1927 HDC screen_dc = GetDC(NULL); 1928 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES); 1929 ddb = CreateCompatibleBitmap(screen_dc, width, height); 1930 ReleaseDC(NULL, screen_dc); 1931 } 1932 1933 /* Set the pixels */ 1934 ddb_dc = CreateCompatibleDC(NULL); 1935 old_bmp = SelectObject(ddb_dc, ddb); 1936 for (i = 0; i < width; i++) 1937 { 1938 for (j=0; j < height; j++) 1939 { 1940 BYTE c = (i * width + j) % 256; 1941 SetPixelV(ddb_dc, i, j, RGB(c, c, c)); 1942 } 1943 } 1944 SelectObject(ddb_dc, old_bmp); 1945 1946 info->bmiHeader.biSize = sizeof(info->bmiHeader); 1947 info->bmiHeader.biWidth = width; 1948 info->bmiHeader.biHeight = height; 1949 info->bmiHeader.biPlanes = 1; 1950 info->bmiHeader.biBitCount = bpp; 1951 info->bmiHeader.biCompression = BI_RGB; 1952 1953 dc = CreateCompatibleDC(NULL); 1954 1955 /* Fill in biSizeImage */ 1956 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS); 1957 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n"); 1958 1959 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage); 1960 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage); 1961 1962 /* Get the bits */ 1963 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS); 1964 ok( res == height, "got %d (bpp %d)\n", res, bpp ); 1965 1966 /* Copy the DIB attributes but not the color table */ 1967 memcpy(info2, info, sizeof(BITMAPINFOHEADER)); 1968 1969 /* Select the DDB into another DC */ 1970 old_bmp = SelectObject(ddb_dc, ddb); 1971 1972 /* Get the bits */ 1973 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS); 1974 ok( res == height, "got %d (bpp %d)\n", res, bpp ); 1975 1976 /* Compare the color table and the bits */ 1977 if (bpp <= 8) 1978 { 1979 for (i=0; i < (1u << bpp); i++) 1980 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed && 1981 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen && 1982 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue && 1983 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved, 1984 "color table entry %d differs (bpp %d)\n", i, bpp ); 1985 } 1986 1987 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp ); 1988 1989 /* Test the palette */ 1990 if (info2->bmiHeader.biBitCount <= 8) 1991 { 1992 WORD *colors = (WORD*)info2->bmiColors; 1993 1994 /* Get the palette indices */ 1995 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS); 1996 ok( res == 1, "got %d (bpp %d)\n", res, bpp ); 1997 1998 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++) 1999 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp ); 2000 } 2001 2002 HeapFree(GetProcessHeap(), 0, bits2); 2003 HeapFree(GetProcessHeap(), 0, bits); 2004 DeleteDC(dc); 2005 2006 SelectObject(ddb_dc, old_bmp); 2007 DeleteDC(ddb_dc); 2008 DeleteObject(ddb); 2009 HeapFree(GetProcessHeap(), 0, info2); 2010 HeapFree(GetProcessHeap(), 0, info); 2011 } 2012 2013 static void test_GetDIBits(void) 2014 { 2015 /* 2-bytes aligned 1-bit bitmap data: 16x16 */ 2016 static const BYTE bmp_bits_1[16 * 2] = 2017 { 2018 0xff,0xff, 0,0, 0xff,0xff, 0,0, 2019 0xff,0xff, 0,0, 0xff,0xff, 0,0, 2020 0xff,0xff, 0,0, 0xff,0xff, 0,0, 2021 0xff,0xff, 0,0, 0xff,0xff, 0,0 2022 }; 2023 /* 4-bytes aligned 1-bit DIB data: 16x16 */ 2024 static const BYTE dib_bits_1[16 * 4] = 2025 { 2026 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0, 2027 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0, 2028 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0, 2029 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0 2030 }; 2031 /* 2-bytes aligned 24-bit bitmap data: 16x16 */ 2032 static const BYTE bmp_bits_24[16 * 16*3] = 2033 { 2034 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2035 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2036 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2037 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2038 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2039 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2040 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2041 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2042 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2043 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2044 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2045 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2046 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2047 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2048 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2049 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2050 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2051 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2052 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2053 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2054 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2055 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2056 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2057 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2058 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2059 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2060 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2061 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2062 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2063 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2064 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2065 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 2066 }; 2067 /* 4-bytes aligned 24-bit DIB data: 16x16 */ 2068 static const BYTE dib_bits_24[16 * 16*3] = 2069 { 2070 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2071 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2072 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2073 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2074 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2075 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2076 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2077 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2078 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2079 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2080 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2081 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2082 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2083 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2084 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2085 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2086 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2087 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2088 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2089 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2090 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2091 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2092 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2093 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2094 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2095 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2096 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2097 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2098 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2099 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2100 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 2101 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff 2102 }; 2103 HBITMAP hbmp; 2104 BITMAP bm; 2105 HDC hdc; 2106 int i, bytes, lines; 2107 BYTE buf[1024]; 2108 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256]; 2109 BITMAPINFO *bi = (BITMAPINFO *)bi_buf; 2110 RGBQUAD *colors = bi->bmiColors; 2111 PALETTEENTRY pal_ents[20]; 2112 2113 hdc = GetDC(0); 2114 2115 /* 1-bit source bitmap data */ 2116 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1); 2117 ok(hbmp != 0, "CreateBitmap failed\n"); 2118 2119 memset(&bm, 0xAA, sizeof(bm)); 2120 bytes = GetObjectW(hbmp, sizeof(bm), &bm); 2121 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes); 2122 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType); 2123 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth); 2124 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight); 2125 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes); 2126 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes); 2127 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel); 2128 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits); 2129 2130 bytes = GetBitmapBits(hbmp, 0, NULL); 2131 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes); 2132 bytes = GetBitmapBits(hbmp, sizeof(buf), buf); 2133 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes); 2134 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n"); 2135 2136 /* retrieve 1-bit DIB data */ 2137 memset(bi, 0, sizeof(*bi)); 2138 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 2139 bi->bmiHeader.biWidth = bm.bmWidth; 2140 bi->bmiHeader.biHeight = bm.bmHeight; 2141 bi->bmiHeader.biPlanes = 1; 2142 bi->bmiHeader.biBitCount = 1; 2143 bi->bmiHeader.biCompression = BI_RGB; 2144 bi->bmiHeader.biClrUsed = 37; 2145 bi->bmiHeader.biSizeImage = 0; 2146 memset(colors, 0xAA, sizeof(RGBQUAD) * 256); 2147 SetLastError(0xdeadbeef); 2148 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS); 2149 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines); 2150 ok(GetLastError() == ERROR_INVALID_PARAMETER || 2151 broken(GetLastError() == 0xdeadbeef), /* winnt */ 2152 "wrong error %u\n", GetLastError()); 2153 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage); 2154 ok(bi->bmiHeader.biClrUsed == 37 || broken(bi->bmiHeader.biClrUsed == 0), 2155 "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed); 2156 2157 memset(buf, 0xAA, sizeof(buf)); 2158 SetLastError(0xdeadbeef); 2159 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS); 2160 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n", 2161 lines, bm.bmHeight, GetLastError()); 2162 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage); 2163 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed); 2164 2165 /* the color table consists of black and white */ 2166 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 && 2167 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0, 2168 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n", 2169 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved); 2170 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff && 2171 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0, 2172 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n", 2173 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved); 2174 for (i = 2; i < 256; i++) 2175 { 2176 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA && 2177 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA, 2178 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i, 2179 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved); 2180 } 2181 2182 /* returned bits are DWORD aligned and upside down */ 2183 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n"); 2184 2185 /* Test the palette indices */ 2186 memset(colors, 0xAA, sizeof(RGBQUAD) * 256); 2187 SetLastError(0xdeadbeef); 2188 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS); 2189 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]); 2190 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]); 2191 for (i = 2; i < 256; i++) 2192 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[1]); 2193 2194 /* retrieve 24-bit DIB data */ 2195 memset(bi, 0, sizeof(*bi)); 2196 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 2197 bi->bmiHeader.biWidth = bm.bmWidth; 2198 bi->bmiHeader.biHeight = bm.bmHeight; 2199 bi->bmiHeader.biPlanes = 1; 2200 bi->bmiHeader.biBitCount = 24; 2201 bi->bmiHeader.biCompression = BI_RGB; 2202 bi->bmiHeader.biClrUsed = 37; 2203 bi->bmiHeader.biSizeImage = 0; 2204 memset(colors, 0xAA, sizeof(RGBQUAD) * 256); 2205 memset(buf, 0xAA, sizeof(buf)); 2206 SetLastError(0xdeadbeef); 2207 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS); 2208 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n", 2209 lines, bm.bmHeight, GetLastError()); 2210 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage); 2211 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed); 2212 2213 /* the color table doesn't exist for 24-bit images */ 2214 for (i = 0; i < 256; i++) 2215 { 2216 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA && 2217 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA, 2218 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i, 2219 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved); 2220 } 2221 2222 /* returned bits are DWORD aligned and upside down */ 2223 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n"); 2224 DeleteObject(hbmp); 2225 2226 /* 24-bit source bitmap data */ 2227 hbmp = CreateCompatibleBitmap(hdc, 16, 16); 2228 ok(hbmp != 0, "CreateBitmap failed\n"); 2229 SetLastError(0xdeadbeef); 2230 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */ 2231 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS); 2232 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n", 2233 lines, bm.bmHeight, GetLastError()); 2234 2235 memset(&bm, 0xAA, sizeof(bm)); 2236 bytes = GetObjectW(hbmp, sizeof(bm), &bm); 2237 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes); 2238 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType); 2239 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth); 2240 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight); 2241 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes); 2242 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes); 2243 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel); 2244 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits); 2245 2246 bytes = GetBitmapBits(hbmp, 0, NULL); 2247 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes); 2248 bytes = GetBitmapBits(hbmp, sizeof(buf), buf); 2249 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", 2250 bm.bmWidthBytes * bm.bmHeight, bytes); 2251 2252 /* retrieve 1-bit DIB data */ 2253 memset(bi, 0, sizeof(*bi)); 2254 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 2255 bi->bmiHeader.biWidth = bm.bmWidth; 2256 bi->bmiHeader.biHeight = bm.bmHeight; 2257 bi->bmiHeader.biPlanes = 1; 2258 bi->bmiHeader.biBitCount = 1; 2259 bi->bmiHeader.biCompression = BI_RGB; 2260 bi->bmiHeader.biClrUsed = 37; 2261 bi->bmiHeader.biSizeImage = 0; 2262 memset(colors, 0xAA, sizeof(RGBQUAD) * 256); 2263 memset(buf, 0xAA, sizeof(buf)); 2264 SetLastError(0xdeadbeef); 2265 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS); 2266 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n", 2267 lines, bm.bmHeight, GetLastError()); 2268 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage); 2269 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed); 2270 2271 /* the color table consists of black and white */ 2272 ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 && 2273 colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0, 2274 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n", 2275 colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved); 2276 ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff && 2277 colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0, 2278 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n", 2279 colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved); 2280 for (i = 2; i < 256; i++) 2281 { 2282 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA && 2283 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA, 2284 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i, 2285 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved); 2286 } 2287 2288 /* returned bits are DWORD aligned and upside down */ 2289 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n"); 2290 2291 /* Test the palette indices */ 2292 memset(colors, 0xAA, sizeof(RGBQUAD) * 256); 2293 SetLastError(0xdeadbeef); 2294 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS); 2295 ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]); 2296 ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]); 2297 for (i = 2; i < 256; i++) 2298 ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[i]); 2299 2300 /* retrieve 4-bit DIB data */ 2301 memset(bi, 0, sizeof(*bi)); 2302 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 2303 bi->bmiHeader.biWidth = bm.bmWidth; 2304 bi->bmiHeader.biHeight = bm.bmHeight; 2305 bi->bmiHeader.biPlanes = 1; 2306 bi->bmiHeader.biBitCount = 4; 2307 bi->bmiHeader.biCompression = BI_RGB; 2308 bi->bmiHeader.biClrUsed = 37; 2309 bi->bmiHeader.biSizeImage = 0; 2310 memset(colors, 0xAA, sizeof(RGBQUAD) * 256); 2311 memset(buf, 0xAA, sizeof(buf)); 2312 SetLastError(0xdeadbeef); 2313 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS); 2314 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n", 2315 lines, bm.bmHeight, GetLastError()); 2316 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed); 2317 2318 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents ); 2319 2320 for (i = 0; i < 16; i++) 2321 { 2322 RGBQUAD expect; 2323 int entry = i < 8 ? i : i + 4; 2324 2325 if(entry == 7) entry = 12; 2326 else if(entry == 12) entry = 7; 2327 2328 expect.rgbRed = pal_ents[entry].peRed; 2329 expect.rgbGreen = pal_ents[entry].peGreen; 2330 expect.rgbBlue = pal_ents[entry].peBlue; 2331 expect.rgbReserved = 0; 2332 2333 ok(!memcmp(colors + i, &expect, sizeof(expect)), 2334 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i, 2335 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved, 2336 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved); 2337 } 2338 2339 /* retrieve 8-bit DIB data */ 2340 memset(bi, 0, sizeof(*bi)); 2341 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 2342 bi->bmiHeader.biWidth = bm.bmWidth; 2343 bi->bmiHeader.biHeight = bm.bmHeight; 2344 bi->bmiHeader.biPlanes = 1; 2345 bi->bmiHeader.biBitCount = 8; 2346 bi->bmiHeader.biCompression = BI_RGB; 2347 bi->bmiHeader.biClrUsed = 37; 2348 bi->bmiHeader.biSizeImage = 0; 2349 memset(colors, 0xAA, sizeof(RGBQUAD) * 256); 2350 memset(buf, 0xAA, sizeof(buf)); 2351 SetLastError(0xdeadbeef); 2352 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS); 2353 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n", 2354 lines, bm.bmHeight, GetLastError()); 2355 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed); 2356 2357 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents ); 2358 2359 for (i = 0; i < 256; i++) 2360 { 2361 RGBQUAD expect; 2362 2363 if (i < 10 || i >= 246) 2364 { 2365 int entry = i < 10 ? i : i - 236; 2366 expect.rgbRed = pal_ents[entry].peRed; 2367 expect.rgbGreen = pal_ents[entry].peGreen; 2368 expect.rgbBlue = pal_ents[entry].peBlue; 2369 } 2370 else 2371 { 2372 expect.rgbRed = (i & 0x07) << 5; 2373 expect.rgbGreen = (i & 0x38) << 2; 2374 expect.rgbBlue = i & 0xc0; 2375 } 2376 expect.rgbReserved = 0; 2377 2378 ok(!memcmp(colors + i, &expect, sizeof(expect)), 2379 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i, 2380 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved, 2381 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved); 2382 } 2383 2384 /* retrieve 24-bit DIB data */ 2385 memset(bi, 0, sizeof(*bi)); 2386 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 2387 bi->bmiHeader.biWidth = bm.bmWidth; 2388 bi->bmiHeader.biHeight = bm.bmHeight; 2389 bi->bmiHeader.biPlanes = 1; 2390 bi->bmiHeader.biBitCount = 24; 2391 bi->bmiHeader.biCompression = BI_RGB; 2392 bi->bmiHeader.biClrUsed = 37; 2393 bi->bmiHeader.biSizeImage = 0; 2394 memset(colors, 0xAA, sizeof(RGBQUAD) * 256); 2395 memset(buf, 0xAA, sizeof(buf)); 2396 SetLastError(0xdeadbeef); 2397 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS); 2398 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n", 2399 lines, bm.bmHeight, GetLastError()); 2400 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage); 2401 ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed); 2402 2403 /* the color table doesn't exist for 24-bit images */ 2404 for (i = 0; i < 256; i++) 2405 { 2406 ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA && 2407 colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA, 2408 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i, 2409 colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved); 2410 } 2411 2412 /* returned bits are DWORD aligned and upside down */ 2413 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n"); 2414 DeleteObject(hbmp); 2415 2416 ReleaseDC(0, hdc); 2417 } 2418 2419 static void test_GetDIBits_BI_BITFIELDS(void) 2420 { 2421 /* Try a screen resolution detection technique 2422 * from the September 1999 issue of Windows Developer's Journal 2423 * which seems to be in widespread use. 2424 * http://www.lesher.ws/highcolor.html 2425 * http://www.lesher.ws/vidfmt.c 2426 * It hinges on being able to retrieve the bitmaps 2427 * for the three primary colors in non-paletted 16 bit mode. 2428 */ 2429 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)]; 2430 DWORD bits[32]; 2431 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf; 2432 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors; 2433 HDC hdc; 2434 HBITMAP hbm; 2435 int ret; 2436 void *ptr; 2437 2438 memset(dibinfo, 0, sizeof(dibinfo_buf)); 2439 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 2440 2441 hdc = GetDC(NULL); 2442 ok(hdc != NULL, "GetDC failed?\n"); 2443 hbm = CreateCompatibleBitmap(hdc, 1, 1); 2444 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n"); 2445 2446 /* Call GetDIBits to fill in bmiHeader. */ 2447 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS); 2448 ok(ret == 1, "GetDIBits failed\n"); 2449 if (dibinfo->bmiHeader.biBitCount > 8) 2450 { 2451 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS || 2452 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */ 2453 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount ); 2454 2455 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS) 2456 { 2457 ok( !bitmasks[0], "red mask is set\n" ); 2458 ok( !bitmasks[1], "green mask is set\n" ); 2459 ok( !bitmasks[2], "blue mask is set\n" ); 2460 2461 /* test with NULL bits pointer and correct bpp */ 2462 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef; 2463 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS); 2464 ok(ret == 1, "GetDIBits failed\n"); 2465 2466 ok( bitmasks[0] != 0, "red mask is not set\n" ); 2467 ok( bitmasks[1] != 0, "green mask is not set\n" ); 2468 ok( bitmasks[2] != 0, "blue mask is not set\n" ); 2469 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" ); 2470 2471 /* test with valid bits pointer */ 2472 memset(dibinfo, 0, sizeof(dibinfo_buf)); 2473 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 2474 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS); 2475 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError()); 2476 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef; 2477 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS); 2478 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError()); 2479 2480 ok( bitmasks[0] != 0, "red mask is not set\n" ); 2481 ok( bitmasks[1] != 0, "green mask is not set\n" ); 2482 ok( bitmasks[2] != 0, "blue mask is not set\n" ); 2483 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" ); 2484 2485 /* now with bits and 0 lines */ 2486 memset(dibinfo, 0, sizeof(dibinfo_buf)); 2487 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 2488 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef; 2489 SetLastError(0xdeadbeef); 2490 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS); 2491 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError()); 2492 2493 ok( !bitmasks[0], "red mask is set\n" ); 2494 ok( !bitmasks[1], "green mask is set\n" ); 2495 ok( !bitmasks[2], "blue mask is set\n" ); 2496 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" ); 2497 2498 memset(bitmasks, 0, 3*sizeof(DWORD)); 2499 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef; 2500 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS); 2501 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError()); 2502 2503 ok( bitmasks[0] != 0, "red mask is not set\n" ); 2504 ok( bitmasks[1] != 0, "green mask is not set\n" ); 2505 ok( bitmasks[2] != 0, "blue mask is not set\n" ); 2506 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" ); 2507 } 2508 } 2509 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n"); 2510 2511 DeleteObject(hbm); 2512 2513 /* same thing now with a 32-bpp DIB section */ 2514 2515 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 2516 dibinfo->bmiHeader.biWidth = 1; 2517 dibinfo->bmiHeader.biHeight = 1; 2518 dibinfo->bmiHeader.biPlanes = 1; 2519 dibinfo->bmiHeader.biBitCount = 32; 2520 dibinfo->bmiHeader.biCompression = BI_RGB; 2521 dibinfo->bmiHeader.biSizeImage = 0; 2522 dibinfo->bmiHeader.biXPelsPerMeter = 0; 2523 dibinfo->bmiHeader.biYPelsPerMeter = 0; 2524 dibinfo->bmiHeader.biClrUsed = 0; 2525 dibinfo->bmiHeader.biClrImportant = 0; 2526 bitmasks[0] = 0x0000ff; 2527 bitmasks[1] = 0x00ff00; 2528 bitmasks[2] = 0xff0000; 2529 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 ); 2530 ok( hbm != 0, "failed to create bitmap\n" ); 2531 2532 memset(dibinfo, 0, sizeof(dibinfo_buf)); 2533 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 2534 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS); 2535 ok(ret == 1, "GetDIBits failed\n"); 2536 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount ); 2537 2538 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS || 2539 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */ 2540 "compression is %u\n", dibinfo->bmiHeader.biCompression ); 2541 ok( !bitmasks[0], "red mask is set\n" ); 2542 ok( !bitmasks[1], "green mask is set\n" ); 2543 ok( !bitmasks[2], "blue mask is set\n" ); 2544 2545 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef; 2546 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS); 2547 ok(ret == 1, "GetDIBits failed\n"); 2548 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount ); 2549 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS || 2550 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */ 2551 "compression is %u\n", dibinfo->bmiHeader.biCompression ); 2552 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS) 2553 { 2554 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] ); 2555 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] ); 2556 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] ); 2557 } 2558 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" ); 2559 2560 DeleteObject(hbm); 2561 2562 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 2563 dibinfo->bmiHeader.biWidth = 1; 2564 dibinfo->bmiHeader.biHeight = 1; 2565 dibinfo->bmiHeader.biPlanes = 1; 2566 dibinfo->bmiHeader.biBitCount = 32; 2567 dibinfo->bmiHeader.biCompression = BI_BITFIELDS; 2568 dibinfo->bmiHeader.biSizeImage = 0; 2569 dibinfo->bmiHeader.biXPelsPerMeter = 0; 2570 dibinfo->bmiHeader.biYPelsPerMeter = 0; 2571 dibinfo->bmiHeader.biClrUsed = 0; 2572 dibinfo->bmiHeader.biClrImportant = 0; 2573 bitmasks[0] = 0x0000ff; 2574 bitmasks[1] = 0x00ff00; 2575 bitmasks[2] = 0xff0000; 2576 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 ); 2577 ok( hbm != 0, "failed to create bitmap\n" ); 2578 2579 if (hbm) 2580 { 2581 memset(dibinfo, 0, sizeof(dibinfo_buf)); 2582 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 2583 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS); 2584 ok(ret == 1, "GetDIBits failed\n"); 2585 2586 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS, 2587 "compression is %u\n", dibinfo->bmiHeader.biCompression ); 2588 ok( !bitmasks[0], "red mask is set\n" ); 2589 ok( !bitmasks[1], "green mask is set\n" ); 2590 ok( !bitmasks[2], "blue mask is set\n" ); 2591 2592 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef; 2593 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS); 2594 ok(ret == 1, "GetDIBits failed\n"); 2595 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] ); 2596 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] ); 2597 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] ); 2598 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" ); 2599 2600 DeleteObject(hbm); 2601 } 2602 2603 /* 24-bpp DIB sections don't have bitfields */ 2604 2605 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 2606 dibinfo->bmiHeader.biWidth = 1; 2607 dibinfo->bmiHeader.biHeight = 1; 2608 dibinfo->bmiHeader.biPlanes = 1; 2609 dibinfo->bmiHeader.biBitCount = 24; 2610 dibinfo->bmiHeader.biCompression = BI_BITFIELDS; 2611 dibinfo->bmiHeader.biSizeImage = 0; 2612 dibinfo->bmiHeader.biXPelsPerMeter = 0; 2613 dibinfo->bmiHeader.biYPelsPerMeter = 0; 2614 dibinfo->bmiHeader.biClrUsed = 0; 2615 dibinfo->bmiHeader.biClrImportant = 0; 2616 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 ); 2617 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" ); 2618 dibinfo->bmiHeader.biCompression = BI_RGB; 2619 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 ); 2620 ok( hbm != 0, "failed to create bitmap\n" ); 2621 2622 memset(dibinfo, 0, sizeof(dibinfo_buf)); 2623 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 2624 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS); 2625 ok(ret == 1, "GetDIBits failed\n"); 2626 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount ); 2627 2628 ok( dibinfo->bmiHeader.biCompression == BI_RGB, 2629 "compression is %u\n", dibinfo->bmiHeader.biCompression ); 2630 ok( !bitmasks[0], "red mask is set\n" ); 2631 ok( !bitmasks[1], "green mask is set\n" ); 2632 ok( !bitmasks[2], "blue mask is set\n" ); 2633 2634 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef; 2635 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS); 2636 ok(ret == 1, "GetDIBits failed\n"); 2637 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount ); 2638 ok( !bitmasks[0], "red mask is set\n" ); 2639 ok( !bitmasks[1], "green mask is set\n" ); 2640 ok( !bitmasks[2], "blue mask is set\n" ); 2641 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" ); 2642 2643 DeleteObject(hbm); 2644 ReleaseDC(NULL, hdc); 2645 } 2646 2647 static void test_select_object(void) 2648 { 2649 HDC hdc; 2650 HBITMAP hbm, hbm_old; 2651 INT planes, bpp, i; 2652 DWORD depths[] = {8, 15, 16, 24, 32}; 2653 BITMAP bm; 2654 DWORD bytes; 2655 2656 hdc = GetDC(0); 2657 ok(hdc != 0, "GetDC(0) failed\n"); 2658 hbm = CreateCompatibleBitmap(hdc, 10, 10); 2659 ok(hbm != 0, "CreateCompatibleBitmap failed\n"); 2660 2661 hbm_old = SelectObject(hdc, hbm); 2662 ok(hbm_old == 0, "SelectObject should fail\n"); 2663 2664 DeleteObject(hbm); 2665 ReleaseDC(0, hdc); 2666 2667 hdc = CreateCompatibleDC(0); 2668 ok(hdc != 0, "GetDC(0) failed\n"); 2669 hbm = CreateCompatibleBitmap(hdc, 10, 10); 2670 ok(hbm != 0, "CreateCompatibleBitmap failed\n"); 2671 2672 hbm_old = SelectObject(hdc, hbm); 2673 ok(hbm_old != 0, "SelectObject failed\n"); 2674 hbm_old = SelectObject(hdc, hbm_old); 2675 ok(hbm_old == hbm, "SelectObject failed\n"); 2676 2677 DeleteObject(hbm); 2678 2679 /* test an 1-bpp bitmap */ 2680 planes = GetDeviceCaps(hdc, PLANES); 2681 bpp = 1; 2682 2683 hbm = CreateBitmap(10, 10, planes, bpp, NULL); 2684 ok(hbm != 0, "CreateBitmap failed\n"); 2685 2686 hbm_old = SelectObject(hdc, hbm); 2687 ok(hbm_old != 0, "SelectObject failed\n"); 2688 hbm_old = SelectObject(hdc, hbm_old); 2689 ok(hbm_old == hbm, "SelectObject failed\n"); 2690 2691 DeleteObject(hbm); 2692 2693 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) { 2694 /* test a color bitmap to dc bpp matching */ 2695 planes = GetDeviceCaps(hdc, PLANES); 2696 bpp = GetDeviceCaps(hdc, BITSPIXEL); 2697 2698 hbm = CreateBitmap(10, 10, planes, depths[i], NULL); 2699 ok(hbm != 0, "CreateBitmap failed\n"); 2700 2701 hbm_old = SelectObject(hdc, hbm); 2702 if(depths[i] == bpp || 2703 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */ 2704 ) { 2705 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]); 2706 SelectObject(hdc, hbm_old); 2707 } else { 2708 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]); 2709 } 2710 2711 memset(&bm, 0xAA, sizeof(bm)); 2712 bytes = GetObjectW(hbm, sizeof(bm), &bm); 2713 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes); 2714 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType); 2715 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth); 2716 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight); 2717 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes); 2718 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes); 2719 if(depths[i] == 15) { 2720 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel); 2721 } else { 2722 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel); 2723 } 2724 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits); 2725 2726 DeleteObject(hbm); 2727 } 2728 2729 DeleteDC(hdc); 2730 } 2731 2732 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line) 2733 { 2734 INT ret; 2735 BITMAP bm; 2736 2737 ret = GetObjectType(hbmp); 2738 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp); 2739 2740 ret = GetObjectW(hbmp, 0, 0); 2741 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret); 2742 2743 memset(&bm, 0xDA, sizeof(bm)); 2744 SetLastError(0xdeadbeef); 2745 ret = GetObjectW(hbmp, sizeof(bm), &bm); 2746 if (!ret) /* XP, only for curObj2 */ return; 2747 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError()); 2748 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType); 2749 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth); 2750 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight); 2751 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes); 2752 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes); 2753 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel); 2754 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits); 2755 } 2756 2757 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__) 2758 2759 static void test_CreateBitmap(void) 2760 { 2761 BITMAP bmp; 2762 HDC screenDC = GetDC(0); 2763 HDC hdc = CreateCompatibleDC(screenDC); 2764 UINT i, expect = 0; 2765 2766 /* all of these are the stock monochrome bitmap */ 2767 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0); 2768 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0); 2769 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0); 2770 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0); 2771 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP); 2772 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP); 2773 2774 /* these 2 are not the stock monochrome bitmap */ 2775 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1); 2776 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0); 2777 2778 HBITMAP old1 = SelectObject(hdc, bm2); 2779 HBITMAP old2 = SelectObject(screenDC, bm3); 2780 SelectObject(hdc, old1); 2781 SelectObject(screenDC, old2); 2782 2783 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1, 2784 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n", 2785 bm, bm1, bm4, bm5, curObj1, old1); 2786 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3); 2787 todo_wine 2788 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2); 2789 ok(old2 == 0, "old2 %p\n", old2); 2790 2791 test_mono_1x1_bmp(bm); 2792 test_mono_1x1_bmp(bm1); 2793 test_mono_1x1_bmp(bm2); 2794 test_mono_1x1_bmp(bm3); 2795 test_mono_1x1_bmp(bm4); 2796 test_mono_1x1_bmp(bm5); 2797 test_mono_1x1_bmp(old1); 2798 test_mono_1x1_bmp(curObj1); 2799 2800 DeleteObject(bm); 2801 DeleteObject(bm1); 2802 DeleteObject(bm2); 2803 DeleteObject(bm3); 2804 DeleteObject(bm4); 2805 DeleteObject(bm5); 2806 2807 DeleteDC(hdc); 2808 ReleaseDC(0, screenDC); 2809 2810 /* show that Windows ignores the provided bm.bmWidthBytes */ 2811 bmp.bmType = 0; 2812 bmp.bmWidth = 1; 2813 bmp.bmHeight = 1; 2814 bmp.bmWidthBytes = 28; 2815 bmp.bmPlanes = 1; 2816 bmp.bmBitsPixel = 1; 2817 bmp.bmBits = NULL; 2818 bm = CreateBitmapIndirect(&bmp); 2819 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError()); 2820 test_mono_1x1_bmp(bm); 2821 DeleteObject(bm); 2822 2823 /* Test how the bmBitsPixel field is treated */ 2824 for(i = 1; i <= 33; i++) { 2825 bmp.bmType = 0; 2826 bmp.bmWidth = 1; 2827 bmp.bmHeight = 1; 2828 bmp.bmWidthBytes = 28; 2829 bmp.bmPlanes = 1; 2830 bmp.bmBitsPixel = i; 2831 bmp.bmBits = NULL; 2832 SetLastError(0xdeadbeef); 2833 bm = CreateBitmapIndirect(&bmp); 2834 if(i > 32) { 2835 DWORD error = GetLastError(); 2836 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i); 2837 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error); 2838 DeleteObject(bm); 2839 continue; 2840 } 2841 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError()); 2842 GetObjectW(bm, sizeof(bmp), &bmp); 2843 if(i == 1) { 2844 expect = 1; 2845 } else if(i <= 4) { 2846 expect = 4; 2847 } else if(i <= 8) { 2848 expect = 8; 2849 } else if(i <= 16) { 2850 expect = 16; 2851 } else if(i <= 24) { 2852 expect = 24; 2853 } else if(i <= 32) { 2854 expect = 32; 2855 } 2856 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n", 2857 i, bmp.bmBitsPixel, expect); 2858 DeleteObject(bm); 2859 } 2860 } 2861 2862 static void test_bitmapinfoheadersize(void) 2863 { 2864 HBITMAP hdib; 2865 BITMAPINFO bmi; 2866 BITMAPCOREINFO bci; 2867 HDC hdc = GetDC(0); 2868 2869 memset(&bmi, 0, sizeof(BITMAPINFO)); 2870 bmi.bmiHeader.biHeight = 100; 2871 bmi.bmiHeader.biWidth = 512; 2872 bmi.bmiHeader.biBitCount = 24; 2873 bmi.bmiHeader.biPlanes = 1; 2874 2875 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1; 2876 2877 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0); 2878 ok(hdib == NULL, "CreateDIBSection succeeded\n"); 2879 2880 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 2881 2882 SetLastError(0xdeadbeef); 2883 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0); 2884 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError()); 2885 DeleteObject(hdib); 2886 2887 bmi.bmiHeader.biSize++; 2888 2889 SetLastError(0xdeadbeef); 2890 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0); 2891 ok(hdib != NULL || 2892 broken(!hdib), /* Win98, WinMe */ 2893 "CreateDIBSection error %d\n", GetLastError()); 2894 DeleteObject(hdib); 2895 2896 bmi.bmiHeader.biSize = sizeof(BITMAPINFO); 2897 2898 SetLastError(0xdeadbeef); 2899 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0); 2900 ok(hdib != NULL || 2901 broken(!hdib), /* Win98, WinMe */ 2902 "CreateDIBSection error %d\n", GetLastError()); 2903 DeleteObject(hdib); 2904 2905 bmi.bmiHeader.biSize++; 2906 2907 SetLastError(0xdeadbeef); 2908 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0); 2909 ok(hdib != NULL || 2910 broken(!hdib), /* Win98, WinMe */ 2911 "CreateDIBSection error %d\n", GetLastError()); 2912 DeleteObject(hdib); 2913 2914 bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER); 2915 2916 SetLastError(0xdeadbeef); 2917 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0); 2918 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError()); 2919 DeleteObject(hdib); 2920 2921 bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER); 2922 2923 SetLastError(0xdeadbeef); 2924 hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0); 2925 ok(hdib != NULL || 2926 broken(!hdib), /* Win95 */ 2927 "CreateDIBSection error %d\n", GetLastError()); 2928 DeleteObject(hdib); 2929 2930 memset(&bci, 0, sizeof(BITMAPCOREINFO)); 2931 bci.bmciHeader.bcHeight = 100; 2932 bci.bmciHeader.bcWidth = 512; 2933 bci.bmciHeader.bcBitCount = 24; 2934 bci.bmciHeader.bcPlanes = 1; 2935 2936 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1; 2937 2938 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0); 2939 ok(hdib == NULL, "CreateDIBSection succeeded\n"); 2940 2941 bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER); 2942 2943 SetLastError(0xdeadbeef); 2944 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0); 2945 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError()); 2946 DeleteObject(hdib); 2947 2948 bci.bmciHeader.bcSize++; 2949 2950 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0); 2951 ok(hdib == NULL, "CreateDIBSection succeeded\n"); 2952 2953 bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO); 2954 2955 hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0); 2956 ok(hdib == NULL, "CreateDIBSection succeeded\n"); 2957 2958 ReleaseDC(0, hdc); 2959 } 2960 2961 static void test_get16dibits(void) 2962 { 2963 BYTE bits[4 * (16 / sizeof(BYTE))]; 2964 HBITMAP hbmp; 2965 HDC screen_dc = GetDC(NULL); 2966 int ret; 2967 BITMAPINFO * info; 2968 int info_len = sizeof(BITMAPINFOHEADER) + 1024; 2969 BYTE *p; 2970 int overwritten_bytes = 0; 2971 2972 memset(bits, 0, sizeof(bits)); 2973 hbmp = CreateBitmap(2, 2, 1, 16, bits); 2974 ok(hbmp != NULL, "CreateBitmap failed\n"); 2975 2976 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len); 2977 assert(info); 2978 2979 memset(info, '!', info_len); 2980 memset(info, 0, sizeof(info->bmiHeader)); 2981 2982 info->bmiHeader.biSize = sizeof(info->bmiHeader); 2983 info->bmiHeader.biWidth = 2; 2984 info->bmiHeader.biHeight = 2; 2985 info->bmiHeader.biPlanes = 1; 2986 info->bmiHeader.biCompression = BI_RGB; 2987 2988 ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0); 2989 ok(ret != 0, "GetDIBits failed got %d\n", ret); 2990 2991 for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++) 2992 if (*p != '!') 2993 overwritten_bytes++; 2994 ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n"); 2995 2996 HeapFree(GetProcessHeap(), 0, info); 2997 DeleteObject(hbmp); 2998 ReleaseDC(NULL, screen_dc); 2999 } 3000 3001 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer, 3002 DWORD dwRop, UINT32 expected, int line) 3003 { 3004 *srcBuffer = 0xFEDCBA98; 3005 *dstBuffer = 0x89ABCDEF; 3006 BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop); 3007 ok(expected == *dstBuffer, 3008 "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n", 3009 dwRop, expected, *dstBuffer, line); 3010 } 3011 3012 static void test_BitBlt(void) 3013 { 3014 HBITMAP bmpDst, bmpSrc; 3015 HBITMAP oldDst, oldSrc; 3016 HDC hdcScreen, hdcDst, hdcSrc; 3017 UINT32 *dstBuffer, *srcBuffer; 3018 HBRUSH hBrush, hOldBrush; 3019 BITMAPINFO bitmapInfo; 3020 3021 memset(&bitmapInfo, 0, sizeof(BITMAPINFO)); 3022 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 3023 bitmapInfo.bmiHeader.biWidth = 1; 3024 bitmapInfo.bmiHeader.biHeight = 1; 3025 bitmapInfo.bmiHeader.biPlanes = 1; 3026 bitmapInfo.bmiHeader.biBitCount = 32; 3027 bitmapInfo.bmiHeader.biCompression = BI_RGB; 3028 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32); 3029 3030 hdcScreen = CreateCompatibleDC(0); 3031 hdcDst = CreateCompatibleDC(hdcScreen); 3032 hdcSrc = CreateCompatibleDC(hdcDst); 3033 3034 /* Setup the destination dib section */ 3035 bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer, 3036 NULL, 0); 3037 oldDst = SelectObject(hdcDst, bmpDst); 3038 3039 hBrush = CreateSolidBrush(0x12345678); 3040 hOldBrush = SelectObject(hdcDst, hBrush); 3041 3042 /* Setup the source dib section */ 3043 bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer, 3044 NULL, 0); 3045 oldSrc = SelectObject(hdcSrc, bmpSrc); 3046 3047 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__); 3048 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__); 3049 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__); 3050 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__); 3051 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__); 3052 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__); 3053 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__); 3054 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__); 3055 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__); 3056 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__); 3057 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__); 3058 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__); 3059 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__); 3060 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__); 3061 check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__); 3062 3063 /* Tidy up */ 3064 SelectObject(hdcSrc, oldSrc); 3065 DeleteObject(bmpSrc); 3066 DeleteDC(hdcSrc); 3067 3068 SelectObject(hdcDst, hOldBrush); 3069 DeleteObject(hBrush); 3070 SelectObject(hdcDst, oldDst); 3071 DeleteObject(bmpDst); 3072 DeleteDC(hdcDst); 3073 3074 3075 DeleteDC(hdcScreen); 3076 } 3077 3078 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer, 3079 DWORD dwRop, UINT32 expected, int line) 3080 { 3081 *srcBuffer = 0xFEDCBA98; 3082 *dstBuffer = 0x89ABCDEF; 3083 StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop); 3084 ok(expected == *dstBuffer, 3085 "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n", 3086 dwRop, expected, *dstBuffer, line); 3087 } 3088 3089 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer, 3090 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, 3091 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, 3092 UINT32 *expected, int line) 3093 { 3094 int dst_size = get_dib_image_size( dst_info ); 3095 3096 memset(dstBuffer, 0, dst_size); 3097 StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, 3098 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY); 3099 ok(memcmp(dstBuffer, expected, dst_size) == 0, 3100 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } " 3101 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n", 3102 expected[0], expected[1], expected[2], expected[3], 3103 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3], 3104 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, 3105 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line); 3106 } 3107 3108 static void test_StretchBlt(void) 3109 { 3110 HBITMAP bmpDst, bmpSrc; 3111 HBITMAP oldDst, oldSrc; 3112 HDC hdcScreen, hdcDst, hdcSrc; 3113 UINT32 *dstBuffer, *srcBuffer; 3114 HBRUSH hBrush, hOldBrush; 3115 BITMAPINFO biDst, biSrc; 3116 UINT32 expected[256]; 3117 RGBQUAD colors[2]; 3118 3119 memset(&biDst, 0, sizeof(BITMAPINFO)); 3120 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 3121 biDst.bmiHeader.biWidth = 16; 3122 biDst.bmiHeader.biHeight = -16; 3123 biDst.bmiHeader.biPlanes = 1; 3124 biDst.bmiHeader.biBitCount = 32; 3125 biDst.bmiHeader.biCompression = BI_RGB; 3126 memcpy(&biSrc, &biDst, sizeof(BITMAPINFO)); 3127 3128 hdcScreen = CreateCompatibleDC(0); 3129 hdcDst = CreateCompatibleDC(hdcScreen); 3130 hdcSrc = CreateCompatibleDC(hdcDst); 3131 3132 /* Pixel Tests */ 3133 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, 3134 NULL, 0); 3135 oldDst = SelectObject(hdcDst, bmpDst); 3136 3137 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, 3138 NULL, 0); 3139 oldSrc = SelectObject(hdcSrc, bmpSrc); 3140 3141 hBrush = CreateSolidBrush(0x012345678); 3142 hOldBrush = SelectObject(hdcDst, hBrush); 3143 3144 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__); 3145 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__); 3146 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__); 3147 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__); 3148 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__); 3149 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__); 3150 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__); 3151 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__); 3152 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__); 3153 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__); 3154 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__); 3155 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__); 3156 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__); 3157 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__); 3158 check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__); 3159 3160 SelectObject(hdcDst, hOldBrush); 3161 DeleteObject(hBrush); 3162 3163 /* Top-down to top-down tests */ 3164 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE; 3165 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210; 3166 3167 memset( expected, 0, get_dib_image_size( &biDst ) ); 3168 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE; 3169 expected[16] = 0xFEDCBA98, expected[17] = 0x76543210; 3170 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 3171 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__); 3172 3173 expected[0] = 0xCAFED00D, expected[1] = 0x00000000; 3174 expected[16] = 0x00000000, expected[17] = 0x00000000; 3175 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 3176 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__); 3177 3178 expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D; 3179 expected[16] = 0xCAFED00D, expected[17] = 0xCAFED00D; 3180 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 3181 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__); 3182 3183 /* This is an example of the dst width (height) == 1 exception, explored below */ 3184 expected[0] = 0xCAFED00D, expected[1] = 0x00000000; 3185 expected[16] = 0x00000000, expected[17] = 0x00000000; 3186 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 3187 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__); 3188 3189 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98; 3190 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D; 3191 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 3192 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__); 3193 3194 expected[0] = 0x76543210, expected[1] = 0xFEDCBA98; 3195 expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D; 3196 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 3197 1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__); 3198 3199 expected[0] = 0xCAFED00D, expected[1] = 0x00000000; 3200 expected[16] = 0x00000000, expected[17] = 0x00000000; 3201 todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 3202 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__); 3203 3204 expected[0] = 0x00000000, expected[1] = 0x00000000; 3205 expected[16] = 0x00000000, expected[17] = 0xCAFED00D, expected[18] = 0xFEEDFACE; 3206 expected[32] = 0x00000000, expected[33] = 0xFEDCBA98, expected[34] = 0x76543210; 3207 3208 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 3209 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__); 3210 3211 /* when dst width is 1 merge src width - 1 pixels */ 3212 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) ); 3213 srcBuffer[0] = 0x0000ff00, srcBuffer[1] = 0x0000f0f0, srcBuffer[2] = 0x0000cccc, srcBuffer[3] = 0x0000aaaa; 3214 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210; 3215 3216 memset( expected, 0, get_dib_image_size( &biDst ) ); 3217 expected[0] = srcBuffer[0]; 3218 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 3219 0, 0, 1, 1, 0, 0, 2, 1, expected, __LINE__); 3220 3221 expected[0] = srcBuffer[0] & srcBuffer[1]; 3222 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 3223 0, 0, 1, 1, 0, 0, 3, 1, expected, __LINE__); 3224 3225 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2]; 3226 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 3227 0, 0, 1, 1, 0, 0, 4, 1, expected, __LINE__); 3228 3229 /* this doesn't happen if the src width is -ve */ 3230 expected[0] = srcBuffer[1] & srcBuffer[2]; 3231 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 3232 0, 0, 1, 1, 2, 0, -2, 1, expected, __LINE__); 3233 3234 /* when dst width > 1 behaviour reverts to what one would expect */ 3235 expected[0] = srcBuffer[0] & srcBuffer[1], expected[1] = srcBuffer[2] & srcBuffer[3]; 3236 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 3237 0, 0, 2, 1, 0, 0, 4, 1, expected, __LINE__); 3238 3239 /* similarly in the vertical direction */ 3240 memset( expected, 0, get_dib_image_size( &biDst ) ); 3241 expected[0] = srcBuffer[0]; 3242 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 3243 0, 0, 1, 1, 0, 0, 1, 2, expected, __LINE__); 3244 3245 /* check that it's the dst size in device units that needs to be 1 */ 3246 SetMapMode( hdcDst, MM_ISOTROPIC ); 3247 SetWindowExtEx( hdcDst, 200, 200, NULL ); 3248 SetViewportExtEx( hdcDst, 100, 100, NULL ); 3249 3250 expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2]; 3251 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 3252 0, 0, 2, 2, 0, 0, 4, 1, expected, __LINE__); 3253 SetMapMode( hdcDst, MM_TEXT ); 3254 3255 SelectObject(hdcDst, oldDst); 3256 DeleteObject(bmpDst); 3257 3258 /* Top-down to bottom-up tests */ 3259 memset( srcBuffer, 0, get_dib_image_size( &biSrc ) ); 3260 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE; 3261 srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210; 3262 3263 biDst.bmiHeader.biHeight = 16; 3264 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, 3265 NULL, 0); 3266 oldDst = SelectObject(hdcDst, bmpDst); 3267 3268 memset( expected, 0, get_dib_image_size( &biDst ) ); 3269 3270 expected[224] = 0xFEDCBA98, expected[225] = 0x76543210; 3271 expected[240] = 0xCAFED00D, expected[241] = 0xFEEDFACE; 3272 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 3273 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__); 3274 3275 expected[224] = 0xFEEDFACE, expected[225] = 0xCAFED00D; 3276 expected[240] = 0x76543210, expected[241] = 0xFEDCBA98; 3277 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 3278 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__); 3279 3280 SelectObject(hdcSrc, oldSrc); 3281 DeleteObject(bmpSrc); 3282 3283 /* Bottom-up to bottom-up tests */ 3284 biSrc.bmiHeader.biHeight = 16; 3285 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, 3286 NULL, 0); 3287 srcBuffer[224] = 0xCAFED00D, srcBuffer[225] = 0xFEEDFACE; 3288 srcBuffer[240] = 0xFEDCBA98, srcBuffer[241] = 0x76543210; 3289 oldSrc = SelectObject(hdcSrc, bmpSrc); 3290 3291 memset( expected, 0, get_dib_image_size( &biDst ) ); 3292 3293 expected[224] = 0xCAFED00D, expected[225] = 0xFEEDFACE; 3294 expected[240] = 0xFEDCBA98, expected[241] = 0x76543210; 3295 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 3296 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__); 3297 3298 expected[224] = 0x76543210, expected[225] = 0xFEDCBA98; 3299 expected[240] = 0xFEEDFACE, expected[241] = 0xCAFED00D; 3300 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 3301 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__); 3302 3303 SelectObject(hdcDst, oldDst); 3304 DeleteObject(bmpDst); 3305 3306 /* Bottom-up to top-down tests */ 3307 biDst.bmiHeader.biHeight = -16; 3308 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, 3309 NULL, 0); 3310 oldDst = SelectObject(hdcDst, bmpDst); 3311 3312 memset( expected, 0, get_dib_image_size( &biDst ) ); 3313 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210; 3314 expected[16] = 0xCAFED00D, expected[17] = 0xFEEDFACE; 3315 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 3316 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__); 3317 3318 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D; 3319 expected[16] = 0x76543210, expected[17] = 0xFEDCBA98; 3320 check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 3321 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__); 3322 3323 SelectObject(hdcSrc, oldSrc); 3324 DeleteObject(bmpSrc); 3325 3326 biSrc.bmiHeader.biHeight = -2; 3327 biSrc.bmiHeader.biBitCount = 24; 3328 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0); 3329 oldSrc = SelectObject(hdcSrc, bmpSrc); 3330 3331 memset( expected, 0, get_dib_image_size( &biDst ) ); 3332 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D; 3333 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98; 3334 memcpy(dstBuffer, expected, 4 * sizeof(*dstBuffer)); 3335 StretchBlt(hdcSrc, 0, 0, 4, 1, hdcDst, 0, 0, 4, 1, SRCCOPY ); 3336 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer)); 3337 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY ); 3338 expected[0] = 0x00EDFACE, expected[1] = 0x00FED00D; 3339 expected[2] = 0x00543210, expected[3] = 0x00DCBA98; 3340 ok(!memcmp(dstBuffer, expected, 16), 3341 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n", 3342 expected[0], expected[1], expected[2], expected[3], 3343 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] ); 3344 3345 expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D; 3346 expected[2] = 0x76543210, expected[3] = 0xFEDCBA98; 3347 memcpy(srcBuffer, expected, 4 * sizeof(*dstBuffer)); 3348 memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer)); 3349 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY ); 3350 expected[0] = 0x00EDFACE, expected[1] = 0x00D00DFE; 3351 expected[2] = 0x0010CAFE, expected[3] = 0x00765432; 3352 ok(!memcmp(dstBuffer, expected, 16), 3353 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n", 3354 expected[0], expected[1], expected[2], expected[3], 3355 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] ); 3356 3357 SelectObject(hdcSrc, oldSrc); 3358 DeleteObject(bmpSrc); 3359 3360 biSrc.bmiHeader.biBitCount = 1; 3361 bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0); 3362 oldSrc = SelectObject(hdcSrc, bmpSrc); 3363 *((DWORD *)colors + 0) = 0x123456; 3364 *((DWORD *)colors + 1) = 0x335577; 3365 SetDIBColorTable( hdcSrc, 0, 2, colors ); 3366 srcBuffer[0] = 0x55555555; 3367 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer)); 3368 SetTextColor( hdcDst, 0 ); 3369 SetBkColor( hdcDst, 0 ); 3370 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY ); 3371 expected[0] = expected[2] = 0x00123456; 3372 expected[1] = expected[3] = 0x00335577; 3373 ok(!memcmp(dstBuffer, expected, 16), 3374 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n", 3375 expected[0], expected[1], expected[2], expected[3], 3376 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] ); 3377 3378 SelectObject(hdcSrc, oldSrc); 3379 DeleteObject(bmpSrc); 3380 3381 bmpSrc = CreateBitmap( 16, 16, 1, 1, 0 ); 3382 oldSrc = SelectObject(hdcSrc, bmpSrc); 3383 SetPixel( hdcSrc, 0, 0, 0 ); 3384 SetPixel( hdcSrc, 1, 0, 0xffffff ); 3385 SetPixel( hdcSrc, 2, 0, 0xffffff ); 3386 SetPixel( hdcSrc, 3, 0, 0 ); 3387 memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer)); 3388 SetTextColor( hdcDst, RGB(0x22,0x44,0x66) ); 3389 SetBkColor( hdcDst, RGB(0x65,0x43,0x21) ); 3390 StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY ); 3391 expected[0] = expected[3] = 0x00224466; 3392 expected[1] = expected[2] = 0x00654321; 3393 ok(!memcmp(dstBuffer, expected, 16), 3394 "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n", 3395 expected[0], expected[1], expected[2], expected[3], 3396 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] ); 3397 3398 SelectObject(hdcSrc, oldSrc); 3399 DeleteObject(bmpSrc); 3400 3401 DeleteDC(hdcSrc); 3402 3403 SelectObject(hdcDst, oldDst); 3404 DeleteObject(bmpDst); 3405 DeleteDC(hdcDst); 3406 3407 DeleteDC(hdcScreen); 3408 } 3409 3410 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer, 3411 DWORD dwRop, UINT32 expected, int line) 3412 { 3413 const UINT32 buffer[2] = { 0xFEDCBA98, 0 }; 3414 BITMAPINFO bitmapInfo; 3415 3416 memset(&bitmapInfo, 0, sizeof(BITMAPINFO)); 3417 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 3418 bitmapInfo.bmiHeader.biWidth = 2; 3419 bitmapInfo.bmiHeader.biHeight = 1; 3420 bitmapInfo.bmiHeader.biPlanes = 1; 3421 bitmapInfo.bmiHeader.biBitCount = 32; 3422 bitmapInfo.bmiHeader.biCompression = BI_RGB; 3423 bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer); 3424 3425 *dstBuffer = 0x89ABCDEF; 3426 3427 StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop); 3428 ok(expected == *dstBuffer, 3429 "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n", 3430 dwRop, expected, *dstBuffer, line); 3431 } 3432 3433 static INT check_StretchDIBits_stretch( HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer, 3434 int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, 3435 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, 3436 UINT32 expected[4], int line) 3437 { 3438 BITMAPINFO bitmapInfo; 3439 INT ret; 3440 3441 memset(&bitmapInfo, 0, sizeof(BITMAPINFO)); 3442 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 3443 bitmapInfo.bmiHeader.biWidth = 2; 3444 bitmapInfo.bmiHeader.biHeight = -2; 3445 bitmapInfo.bmiHeader.biPlanes = 1; 3446 bitmapInfo.bmiHeader.biBitCount = 32; 3447 bitmapInfo.bmiHeader.biCompression = BI_RGB; 3448 3449 memset(dstBuffer, 0, 16); 3450 ret = StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, 3451 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, 3452 srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY); 3453 ok(memcmp(dstBuffer, expected, 16) == 0, 3454 "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } " 3455 "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n", 3456 expected[0], expected[1], expected[2], expected[3], 3457 dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3], 3458 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, 3459 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line); 3460 return ret; 3461 } 3462 3463 static void test_StretchDIBits(void) 3464 { 3465 HBITMAP bmpDst; 3466 HBITMAP oldDst; 3467 HDC hdcScreen, hdcDst; 3468 UINT32 *dstBuffer, srcBuffer[4]; 3469 HBRUSH hBrush, hOldBrush; 3470 BITMAPINFO biDst; 3471 UINT32 expected[4]; 3472 INT ret; 3473 3474 memset(&biDst, 0, sizeof(BITMAPINFO)); 3475 biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 3476 biDst.bmiHeader.biWidth = 2; 3477 biDst.bmiHeader.biHeight = -2; 3478 biDst.bmiHeader.biPlanes = 1; 3479 biDst.bmiHeader.biBitCount = 32; 3480 biDst.bmiHeader.biCompression = BI_RGB; 3481 3482 hdcScreen = CreateCompatibleDC(0); 3483 hdcDst = CreateCompatibleDC(hdcScreen); 3484 3485 /* Pixel Tests */ 3486 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, 3487 NULL, 0); 3488 oldDst = SelectObject(hdcDst, bmpDst); 3489 3490 hBrush = CreateSolidBrush(0x012345678); 3491 hOldBrush = SelectObject(hdcDst, hBrush); 3492 3493 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__); 3494 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__); 3495 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__); 3496 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__); 3497 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__); 3498 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__); 3499 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__); 3500 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__); 3501 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__); 3502 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__); 3503 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__); 3504 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__); 3505 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__); 3506 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__); 3507 check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__); 3508 3509 SelectObject(hdcDst, hOldBrush); 3510 DeleteObject(hBrush); 3511 3512 /* Top-down destination tests */ 3513 srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE; 3514 srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210; 3515 3516 expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE; 3517 expected[2] = 0xFEDCBA98, expected[3] = 0x76543210; 3518 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, 3519 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__); 3520 ok( ret == 2, "got ret %d\n", ret ); 3521 3522 expected[0] = 0xCAFED00D, expected[1] = 0x00000000; 3523 expected[2] = 0x00000000, expected[3] = 0x00000000; 3524 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, 3525 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__); 3526 todo_wine ok( ret == 1, "got ret %d\n", ret ); 3527 3528 expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98; 3529 expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98; 3530 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, 3531 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__); 3532 ok( ret == 2, "got ret %d\n", ret ); 3533 3534 expected[0] = 0x42441000, expected[1] = 0x00000000; 3535 expected[2] = 0x00000000, expected[3] = 0x00000000; 3536 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, 3537 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__); 3538 ok( ret == 2, "got ret %d\n", ret ); 3539 3540 expected[0] = 0x00000000, expected[1] = 0x00000000; 3541 expected[2] = 0x00000000, expected[3] = 0x00000000; 3542 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, 3543 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__); 3544 ok( ret == 0, "got ret %d\n", ret ); 3545 3546 expected[0] = 0x00000000, expected[1] = 0x00000000; 3547 expected[2] = 0x00000000, expected[3] = 0x00000000; 3548 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, 3549 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__); 3550 ok( ret == 0, "got ret %d\n", ret ); 3551 3552 expected[0] = 0x00000000, expected[1] = 0x00000000; 3553 expected[2] = 0x00000000, expected[3] = 0x00000000; 3554 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, 3555 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__); 3556 ok( ret == 0, "got ret %d\n", ret ); 3557 3558 expected[0] = 0x00000000, expected[1] = 0x00000000; 3559 expected[2] = 0x00000000, expected[3] = 0xCAFED00D; 3560 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, 3561 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__); 3562 ok( ret == 2, "got ret %d\n", ret ); 3563 3564 expected[0] = 0x00000000, expected[1] = 0x00000000; 3565 expected[2] = 0x00000000, expected[3] = 0x00000000; 3566 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, 3567 2, 2, 4, 4, 0, 0, 2, 2, expected, __LINE__); 3568 ok( ret == 2, "got ret %d\n", ret ); 3569 3570 expected[0] = 0x00000000, expected[1] = 0x00000000; 3571 expected[2] = 0x00000000, expected[3] = 0x00000000; 3572 ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, 3573 -4, -4, 4, 4, 0, 0, 4, 4, expected, __LINE__); 3574 ok( ret == 2, "got ret %d\n", ret ); 3575 3576 SelectObject(hdcDst, oldDst); 3577 DeleteObject(bmpDst); 3578 3579 /* Bottom up destination tests */ 3580 biDst.bmiHeader.biHeight = 2; 3581 bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, 3582 NULL, 0); 3583 oldDst = SelectObject(hdcDst, bmpDst); 3584 3585 expected[0] = 0xFEDCBA98, expected[1] = 0x76543210; 3586 expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE; 3587 check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, 3588 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__); 3589 3590 /* Tidy up */ 3591 SelectObject(hdcDst, oldDst); 3592 DeleteObject(bmpDst); 3593 DeleteDC(hdcDst); 3594 3595 DeleteDC(hdcScreen); 3596 } 3597 3598 static void test_GdiAlphaBlend(void) 3599 { 3600 HDC hdcNull; 3601 HDC hdcDst; 3602 HBITMAP bmpDst; 3603 BITMAPINFO *bmi; 3604 HDC hdcSrc; 3605 HBITMAP bmpSrc; 3606 HBITMAP oldSrc; 3607 LPVOID bits; 3608 BOOL ret; 3609 BLENDFUNCTION blend; 3610 3611 if (!pGdiAlphaBlend) 3612 { 3613 win_skip("GdiAlphaBlend() is not implemented\n"); 3614 return; 3615 } 3616 3617 hdcNull = GetDC(NULL); 3618 hdcDst = CreateCompatibleDC(hdcNull); 3619 bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100); 3620 hdcSrc = CreateCompatibleDC(hdcNull); 3621 3622 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] )); 3623 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader); 3624 bmi->bmiHeader.biHeight = 20; 3625 bmi->bmiHeader.biWidth = 20; 3626 bmi->bmiHeader.biBitCount = 32; 3627 bmi->bmiHeader.biPlanes = 1; 3628 bmi->bmiHeader.biCompression = BI_RGB; 3629 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0); 3630 ok(bmpSrc != NULL, "Couldn't create source bitmap\n"); 3631 3632 SelectObject(hdcDst, bmpDst); 3633 oldSrc = SelectObject(hdcSrc, bmpSrc); 3634 3635 blend.BlendOp = AC_SRC_OVER; 3636 blend.BlendFlags = 0; 3637 blend.SourceConstantAlpha = 128; 3638 blend.AlphaFormat = 0; 3639 3640 SetLastError(0xdeadbeef); 3641 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend); 3642 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() ); 3643 3644 SetLastError(0xdeadbeef); 3645 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend); 3646 ok( !ret, "GdiAlphaBlend succeeded\n" ); 3647 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3648 3649 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend); 3650 ok( !ret, "GdiAlphaBlend succeeded\n" ); 3651 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend); 3652 ok( !ret, "GdiAlphaBlend succeeded\n" ); 3653 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend); 3654 ok( !ret, "GdiAlphaBlend succeeded\n" ); 3655 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend); 3656 ok( !ret, "GdiAlphaBlend succeeded\n" ); 3657 3658 SetWindowOrgEx(hdcSrc, -10, -10, NULL); 3659 SetLastError(0xdeadbeef); 3660 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend); 3661 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() ); 3662 SetLastError(0xdeadbeef); 3663 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend); 3664 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() ); 3665 SetMapMode(hdcSrc, MM_ANISOTROPIC); 3666 ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL); 3667 SetLastError(0xdeadbeef); 3668 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend); 3669 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() ); 3670 SetLastError(0xdeadbeef); 3671 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend); 3672 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() ); 3673 3674 SetMapMode(hdcDst, MM_ANISOTROPIC); 3675 SetViewportExtEx(hdcDst, -1, -1, NULL); 3676 SetLastError(0xdeadbeef); 3677 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 50, 50, blend); 3678 todo_wine 3679 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() ); 3680 SetLastError(0xdeadbeef); 3681 ret = pGdiAlphaBlend(hdcDst, -20, -20, 20, 20, hdcSrc, 0, -1, 50, 50, blend); 3682 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() ); 3683 SetLastError(0xdeadbeef); 3684 ret = pGdiAlphaBlend(hdcDst, -20, -20, -20, -20, hdcSrc, 0, -1, 50, 50, blend); 3685 ok( !ret, "GdiAlphaBlend succeeded\n" ); 3686 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3687 SetLastError(0xdeadbeef); 3688 ret = pGdiAlphaBlend(hdcDst, -20, 0, -20, 20, hdcSrc, 0, -1, 50, 50, blend); 3689 ok( !ret, "GdiAlphaBlend succeeded\n" ); 3690 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3691 SetLastError(0xdeadbeef); 3692 ret = pGdiAlphaBlend(hdcDst, 0, -20, 20, -20, hdcSrc, 0, -1, 50, 50, blend); 3693 ok( !ret, "GdiAlphaBlend succeeded\n" ); 3694 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3695 SetMapMode(hdcDst, MM_TEXT); 3696 3697 SetViewportExtEx(hdcSrc, -1, -1, NULL); 3698 SetLastError(0xdeadbeef); 3699 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, -30, -30, blend); 3700 ok( !ret, "GdiAlphaBlend succeeded\n" ); 3701 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3702 SetLastError(0xdeadbeef); 3703 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, 30, -30, blend); 3704 ok( !ret, "GdiAlphaBlend succeeded\n" ); 3705 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3706 SetLastError(0xdeadbeef); 3707 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, -30, 30, blend); 3708 ok( !ret, "GdiAlphaBlend succeeded\n" ); 3709 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3710 SetLastError(0xdeadbeef); 3711 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, 30, 30, blend); 3712 ok( !ret, "GdiAlphaBlend succeeded\n" ); 3713 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3714 SetLastError(0xdeadbeef); 3715 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 20, 20, 30, 30, blend); 3716 ok( !ret, "GdiAlphaBlend succeeded\n" ); 3717 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3718 SetLastError(0xdeadbeef); 3719 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -60, -60, 30, 30, blend); 3720 ok( !ret, "GdiAlphaBlend succeeded\n" ); 3721 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3722 SetViewportExtEx(hdcSrc, 1, 1, NULL); 3723 3724 SetLastError(0xdeadbeef); 3725 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend); 3726 ok( !ret, "GdiAlphaBlend succeeded\n" ); 3727 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() ); 3728 3729 /* overlapping source and dest not allowed */ 3730 3731 SetLastError(0xdeadbeef); 3732 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 19, 19, 20, 20, blend); 3733 ok( !ret, "GdiAlphaBlend succeeded\n" ); 3734 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3735 3736 SetLastError(0xdeadbeef); 3737 ret = pGdiAlphaBlend(hdcDst, 20, 20, 20, 20, hdcDst, 1, 1, 20, 20, blend); 3738 ok( !ret, "GdiAlphaBlend succeeded\n" ); 3739 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3740 3741 SetLastError(0xdeadbeef); 3742 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 20, 10, 20, 20, blend); 3743 ok( ret, "GdiAlphaBlend succeeded\n" ); 3744 SetLastError(0xdeadbeef); 3745 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 10, 20, 20, 20, blend); 3746 ok( ret, "GdiAlphaBlend succeeded\n" ); 3747 3748 /* AC_SRC_ALPHA requires 32-bpp BI_RGB format */ 3749 3750 blend.AlphaFormat = AC_SRC_ALPHA; 3751 SetLastError(0xdeadbeef); 3752 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend); 3753 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() ); 3754 3755 bmi->bmiHeader.biCompression = BI_BITFIELDS; 3756 ((DWORD *)bmi->bmiColors)[0] = 0xff0000; 3757 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00; 3758 ((DWORD *)bmi->bmiColors)[2] = 0x0000ff; 3759 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0); 3760 ok(bmpSrc != NULL, "Couldn't create source bitmap\n"); 3761 oldSrc = SelectObject(hdcSrc, bmpSrc); 3762 DeleteObject( oldSrc ); 3763 3764 SetLastError(0xdeadbeef); 3765 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend); 3766 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() ); 3767 3768 bmi->bmiHeader.biCompression = BI_BITFIELDS; 3769 ((DWORD *)bmi->bmiColors)[0] = 0x0000ff; 3770 ((DWORD *)bmi->bmiColors)[1] = 0x00ff00; 3771 ((DWORD *)bmi->bmiColors)[2] = 0xff0000; 3772 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0); 3773 ok(bmpSrc != NULL, "Couldn't create source bitmap\n"); 3774 oldSrc = SelectObject(hdcSrc, bmpSrc); 3775 DeleteObject( oldSrc ); 3776 3777 SetLastError(0xdeadbeef); 3778 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend); 3779 ok( !ret, "GdiAlphaBlend succeeded\n" ); 3780 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3781 3782 bmi->bmiHeader.biBitCount = 24; 3783 bmi->bmiHeader.biCompression = BI_RGB; 3784 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0); 3785 ok(bmpSrc != NULL, "Couldn't create source bitmap\n"); 3786 oldSrc = SelectObject(hdcSrc, bmpSrc); 3787 DeleteObject( oldSrc ); 3788 3789 SetLastError(0xdeadbeef); 3790 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend); 3791 ok( !ret, "GdiAlphaBlend succeeded\n" ); 3792 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3793 3794 bmi->bmiHeader.biBitCount = 1; 3795 bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0); 3796 ok(bmpSrc != NULL, "Couldn't create source bitmap\n"); 3797 oldSrc = SelectObject(hdcSrc, bmpSrc); 3798 DeleteObject( oldSrc ); 3799 3800 SetLastError(0xdeadbeef); 3801 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend); 3802 ok( !ret, "GdiAlphaBlend succeeded\n" ); 3803 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3804 3805 bmpSrc = CreateBitmap( 100, 100, 1, 1, NULL ); 3806 ok(bmpSrc != NULL, "Couldn't create source bitmap\n"); 3807 oldSrc = SelectObject(hdcSrc, bmpSrc); 3808 DeleteObject( oldSrc ); 3809 3810 SetLastError(0xdeadbeef); 3811 ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend); 3812 ok( !ret, "GdiAlphaBlend succeeded\n" ); 3813 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3814 3815 DeleteDC(hdcDst); 3816 DeleteDC(hdcSrc); 3817 DeleteObject(bmpSrc); 3818 DeleteObject(bmpDst); 3819 3820 ReleaseDC(NULL, hdcNull); 3821 HeapFree(GetProcessHeap(), 0, bmi); 3822 } 3823 3824 static void test_GdiGradientFill(void) 3825 { 3826 HDC hdc; 3827 BOOL ret; 3828 HBITMAP bmp; 3829 BITMAPINFO *bmi; 3830 void *bits; 3831 GRADIENT_RECT rect[] = { { 0, 0 }, { 0, 1 }, { 2, 3 } }; 3832 GRADIENT_TRIANGLE tri[] = { { 0, 0, 0 }, { 0, 1, 2 }, { 0, 2, 1 }, { 0, 1, 3 } }; 3833 TRIVERTEX vt[3] = { { 2, 2, 0xff00, 0x0000, 0x0000, 0x8000 }, 3834 { 10, 10, 0x0000, 0xff00, 0x0000, 0x8000 }, 3835 { 20, 10, 0x0000, 0x0000, 0xff00, 0xff00 } }; 3836 3837 if (!pGdiGradientFill) 3838 { 3839 win_skip( "GdiGradientFill is not implemented\n" ); 3840 return; 3841 } 3842 3843 hdc = CreateCompatibleDC( NULL ); 3844 bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] )); 3845 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader); 3846 bmi->bmiHeader.biHeight = 20; 3847 bmi->bmiHeader.biWidth = 20; 3848 bmi->bmiHeader.biBitCount = 32; 3849 bmi->bmiHeader.biPlanes = 1; 3850 bmi->bmiHeader.biCompression = BI_RGB; 3851 bmp = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, &bits, NULL, 0); 3852 ok( bmp != NULL, "couldn't create bitmap\n" ); 3853 SelectObject( hdc, bmp ); 3854 3855 SetLastError( 0xdeadbeef ); 3856 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, GRADIENT_FILL_RECT_H ); 3857 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() ); 3858 SetLastError( 0xdeadbeef ); 3859 ret = pGdiGradientFill( hdc, vt, 3, rect, 1, 3 ); 3860 ok( !ret, "GdiGradientFill succeeded\n" ); 3861 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3862 SetLastError( 0xdeadbeef ); 3863 ret = pGdiGradientFill( (HDC)0xdead, vt, 3, rect, 1, GRADIENT_FILL_RECT_H ); 3864 ok( !ret, "GdiGradientFill succeeded\n" ); 3865 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3866 SetLastError( 0xdeadbeef ); 3867 ret = pGdiGradientFill( NULL, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H ); 3868 ok( !ret, "GdiGradientFill succeeded\n" ); 3869 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3870 ret = pGdiGradientFill( hdc, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H ); 3871 ok( !ret, "GdiGradientFill succeeded\n" ); 3872 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3873 SetLastError( 0xdeadbeef ); 3874 ret = pGdiGradientFill( hdc, NULL, 3, rect, 1, GRADIENT_FILL_RECT_H ); 3875 ok( !ret, "GdiGradientFill succeeded\n" ); 3876 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3877 SetLastError( 0xdeadbeef ); 3878 ret = pGdiGradientFill( hdc, vt, 3, NULL, 0, GRADIENT_FILL_RECT_H ); 3879 ok( !ret, "GdiGradientFill succeeded\n" ); 3880 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3881 SetLastError( 0xdeadbeef ); 3882 ret = pGdiGradientFill( hdc, vt, 3, NULL, 1, GRADIENT_FILL_RECT_H ); 3883 ok( !ret, "GdiGradientFill succeeded\n" ); 3884 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3885 SetLastError( 0xdeadbeef ); 3886 ret = pGdiGradientFill( hdc, vt, 3, rect, 0, GRADIENT_FILL_RECT_H ); 3887 ok( !ret, "GdiGradientFill succeeded\n" ); 3888 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3889 SetLastError( 0xdeadbeef ); 3890 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H ); 3891 ok( !ret, "GdiGradientFill succeeded\n" ); 3892 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() ); 3893 rect[2].UpperLeft = rect[2].LowerRight = 1; 3894 SetLastError( 0xdeadbeef ); 3895 ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H ); 3896 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() ); 3897 SetLastError( 0xdeadbeef ); 3898 ret = pGdiGradientFill( hdc, vt, 1, rect, 1, GRADIENT_FILL_RECT_H ); 3899 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() ); 3900 SetLastError( 0xdeadbeef ); 3901 ret = pGdiGradientFill( hdc, vt, 1, tri, 0, GRADIENT_FILL_TRIANGLE ); 3902 ok( !ret, "GdiGradientFill succeeded\n" ); 3903 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); 3904 SetLastError( 0xdeadbeef ); 3905 ret = pGdiGradientFill( hdc, vt, 1, tri, 1, GRADIENT_FILL_TRIANGLE ); 3906 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() ); 3907 SetLastError( 0xdeadbeef ); 3908 ret = pGdiGradientFill( hdc, vt, 3, tri, 2, GRADIENT_FILL_TRIANGLE ); 3909 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() ); 3910 SetLastError( 0xdeadbeef ); 3911 ret = pGdiGradientFill( hdc, vt, 3, tri, 3, GRADIENT_FILL_TRIANGLE ); 3912 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() ); 3913 SetLastError( 0xdeadbeef ); 3914 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE ); 3915 ok( !ret, "GdiGradientFill succeeded\n" ); 3916 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() ); 3917 tri[3].Vertex3 = 1; 3918 SetLastError( 0xdeadbeef ); 3919 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE ); 3920 ok( !ret, "GdiGradientFill succeeded\n" ); 3921 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() ); 3922 tri[3].Vertex3 = 0; 3923 SetLastError( 0xdeadbeef ); 3924 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE ); 3925 ok( !ret, "GdiGradientFill succeeded\n" ); 3926 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() ); 3927 tri[3].Vertex1 = tri[3].Vertex2 = tri[3].Vertex3 = 1; 3928 SetLastError( 0xdeadbeef ); 3929 ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE ); 3930 ok( ret, "GdiGradientFill failed err %u\n", GetLastError() ); 3931 3932 DeleteDC( hdc ); 3933 DeleteObject( bmp ); 3934 HeapFree(GetProcessHeap(), 0, bmi); 3935 } 3936 3937 static void test_clipping(void) 3938 { 3939 HBITMAP bmpDst; 3940 HBITMAP bmpSrc; 3941 HRGN hRgn; 3942 LPVOID bits; 3943 BOOL result; 3944 3945 HDC hdcDst = CreateCompatibleDC( NULL ); 3946 HDC hdcSrc = CreateCompatibleDC( NULL ); 3947 3948 BITMAPINFO bmpinfo={{0}}; 3949 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 3950 bmpinfo.bmiHeader.biWidth = 100; 3951 bmpinfo.bmiHeader.biHeight = 100; 3952 bmpinfo.bmiHeader.biPlanes = 1; 3953 bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL ); 3954 bmpinfo.bmiHeader.biCompression = BI_RGB; 3955 3956 bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 ); 3957 ok(bmpDst != NULL, "Couldn't create destination bitmap\n"); 3958 SelectObject( hdcDst, bmpDst ); 3959 3960 bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 ); 3961 ok(bmpSrc != NULL, "Couldn't create source bitmap\n"); 3962 SelectObject( hdcSrc, bmpSrc ); 3963 3964 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY ); 3965 ok(result, "BitBlt failed\n"); 3966 3967 hRgn = CreateRectRgn( 0,0,0,0 ); 3968 SelectClipRgn( hdcDst, hRgn ); 3969 3970 result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY ); 3971 ok(result, "BitBlt failed\n"); 3972 3973 DeleteObject( bmpDst ); 3974 DeleteObject( bmpSrc ); 3975 DeleteObject( hRgn ); 3976 DeleteDC( hdcDst ); 3977 DeleteDC( hdcSrc ); 3978 } 3979 3980 static void test_32bit_ddb(void) 3981 { 3982 char buffer[sizeof(BITMAPINFOHEADER) + sizeof(DWORD)]; 3983 BITMAPINFO *biDst = (BITMAPINFO *)buffer; 3984 HBITMAP bmpSrc, bmpDst; 3985 HBITMAP oldSrc, oldDst; 3986 HDC hdcSrc, hdcDst, hdcScreen; 3987 HBRUSH brush; 3988 DWORD *dstBuffer, *data; 3989 DWORD colorSrc = 0x40201008; 3990 3991 memset(biDst, 0, sizeof(BITMAPINFOHEADER)); 3992 biDst->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 3993 biDst->bmiHeader.biWidth = 1; 3994 biDst->bmiHeader.biHeight = -1; 3995 biDst->bmiHeader.biPlanes = 1; 3996 biDst->bmiHeader.biBitCount = 32; 3997 biDst->bmiHeader.biCompression = BI_RGB; 3998 3999 hdcScreen = CreateCompatibleDC(0); 4000 if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32) 4001 { 4002 DeleteDC(hdcScreen); 4003 trace("Skipping 32-bit DDB test\n"); 4004 return; 4005 } 4006 4007 hdcSrc = CreateCompatibleDC(hdcScreen); 4008 bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc); 4009 oldSrc = SelectObject(hdcSrc, bmpSrc); 4010 4011 hdcDst = CreateCompatibleDC(hdcScreen); 4012 bmpDst = CreateDIBSection(hdcDst, biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0); 4013 oldDst = SelectObject(hdcDst, bmpDst); 4014 4015 StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY); 4016 ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]); 4017 4018 if (pGdiAlphaBlend) 4019 { 4020 BLENDFUNCTION blend; 4021 BOOL ret; 4022 4023 blend.BlendOp = AC_SRC_OVER; 4024 blend.BlendFlags = 0; 4025 blend.SourceConstantAlpha = 128; 4026 blend.AlphaFormat = 0; 4027 dstBuffer[0] = 0x80808080; 4028 ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend ); 4029 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() ); 4030 ok(dstBuffer[0] == 0x60504844, "wrong color %x\n", dstBuffer[0]); 4031 blend.AlphaFormat = AC_SRC_ALPHA; 4032 dstBuffer[0] = 0x80808080; 4033 ret = pGdiAlphaBlend( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, blend ); 4034 ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() ); 4035 ok(dstBuffer[0] == 0x90807874, "wrong color %x\n", dstBuffer[0]); 4036 } 4037 4038 data = (DWORD *)biDst->bmiColors; 4039 data[0] = 0x20304050; 4040 brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS ); 4041 ok( brush != 0, "brush creation failed\n" ); 4042 SelectObject( hdcSrc, brush ); 4043 PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY ); 4044 BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY ); 4045 ok(dstBuffer[0] == data[0], "Expected color=%x, received color=%x\n", data[0], dstBuffer[0]); 4046 SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) ); 4047 DeleteObject( brush ); 4048 4049 biDst->bmiHeader.biBitCount = 24; 4050 brush = CreateDIBPatternBrushPt( biDst, DIB_RGB_COLORS ); 4051 ok( brush != 0, "brush creation failed\n" ); 4052 SelectObject( hdcSrc, brush ); 4053 PatBlt( hdcSrc, 0, 0, 1, 1, PATCOPY ); 4054 BitBlt( hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, SRCCOPY ); 4055 ok(dstBuffer[0] == (data[0] & ~0xff000000), 4056 "Expected color=%x, received color=%x\n", data[0] & 0xff000000, dstBuffer[0]); 4057 SelectObject( hdcSrc, GetStockObject(BLACK_BRUSH) ); 4058 DeleteObject( brush ); 4059 4060 /* Tidy up */ 4061 SelectObject(hdcDst, oldDst); 4062 DeleteObject(bmpDst); 4063 DeleteDC(hdcDst); 4064 4065 SelectObject(hdcSrc, oldSrc); 4066 DeleteObject(bmpSrc); 4067 DeleteDC(hdcSrc); 4068 4069 DeleteDC(hdcScreen); 4070 } 4071 4072 /* 4073 * Used by test_GetDIBits_top_down to create the bitmap to test against. 4074 */ 4075 static void setup_picture(char *picture, int bpp) 4076 { 4077 int i; 4078 4079 switch(bpp) 4080 { 4081 case 16: 4082 case 32: 4083 /*Set the first byte in each pixel to the index of that pixel.*/ 4084 for (i = 0; i < 4; i++) 4085 picture[i * (bpp / 8)] = i; 4086 break; 4087 case 24: 4088 picture[0] = 0; 4089 picture[3] = 1; 4090 /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/ 4091 picture[8] = 2; 4092 picture[11] = 3; 4093 break; 4094 } 4095 } 4096 4097 static void test_GetDIBits_top_down(int bpp) 4098 { 4099 BITMAPINFO bi; 4100 HBITMAP bmptb, bmpbt; 4101 HDC hdc; 4102 int pictureOut[4]; 4103 int *picture; 4104 int statusCode; 4105 4106 memset( &bi, 0, sizeof(bi) ); 4107 bi.bmiHeader.biSize=sizeof(bi.bmiHeader); 4108 bi.bmiHeader.biWidth=2; 4109 bi.bmiHeader.biHeight=2; 4110 bi.bmiHeader.biPlanes=1; 4111 bi.bmiHeader.biBitCount=bpp; 4112 bi.bmiHeader.biCompression=BI_RGB; 4113 4114 /*Get the device context for the screen.*/ 4115 hdc = GetDC(NULL); 4116 ok(hdc != NULL, "Could not get a handle to a device context.\n"); 4117 4118 /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/ 4119 bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0); 4120 ok(bmpbt != NULL, "Could not create a DIB section.\n"); 4121 /*Now that we have a pointer to the pixels, we write to them.*/ 4122 setup_picture((char*)picture, bpp); 4123 /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/ 4124 bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/ 4125 bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0); 4126 ok(bmptb != NULL, "Could not create a DIB section.\n"); 4127 /*Write to this top to bottom bitmap.*/ 4128 setup_picture((char*)picture, bpp); 4129 4130 bi.bmiHeader.biWidth = 1; 4131 4132 bi.bmiHeader.biHeight = 2; 4133 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS); 4134 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode); 4135 /*Check the first byte of the pixel.*/ 4136 ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]); 4137 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS); 4138 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode); 4139 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]); 4140 /*Check second scanline.*/ 4141 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS); 4142 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode); 4143 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]); 4144 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS); 4145 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode); 4146 ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]); 4147 /*Check both scanlines.*/ 4148 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS); 4149 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode); 4150 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]); 4151 ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]); 4152 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS); 4153 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode); 4154 ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]); 4155 ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]); 4156 4157 /*Make destination bitmap top-down.*/ 4158 bi.bmiHeader.biHeight = -2; 4159 statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS); 4160 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode); 4161 ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]); 4162 statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS); 4163 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode); 4164 ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]); 4165 /*Check second scanline.*/ 4166 statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS); 4167 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode); 4168 ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]); 4169 statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS); 4170 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode); 4171 ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]); 4172 /*Check both scanlines.*/ 4173 statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS); 4174 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode); 4175 ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]); 4176 ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]); 4177 statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS); 4178 ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode); 4179 ok((char)pictureOut[0] == 2, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]); 4180 ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]); 4181 4182 DeleteObject(bmpbt); 4183 DeleteObject(bmptb); 4184 } 4185 4186 static void test_GetSetDIBits_rtl(void) 4187 { 4188 HDC hdc, hdc_mem; 4189 HBITMAP bitmap, orig_bitmap; 4190 BITMAPINFO info; 4191 int ret; 4192 DWORD bits_1[8 * 8], bits_2[8 * 8]; 4193 4194 if(!pSetLayout) 4195 { 4196 win_skip("Don't have SetLayout\n"); 4197 return; 4198 } 4199 4200 hdc = GetDC( NULL ); 4201 hdc_mem = CreateCompatibleDC( hdc ); 4202 pSetLayout( hdc_mem, LAYOUT_LTR ); 4203 4204 bitmap = CreateCompatibleBitmap( hdc, 8, 8 ); 4205 orig_bitmap = SelectObject( hdc_mem, bitmap ); 4206 SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) ); 4207 SelectObject( hdc_mem, orig_bitmap ); 4208 4209 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 4210 info.bmiHeader.biWidth = 8; 4211 info.bmiHeader.biHeight = 8; 4212 info.bmiHeader.biPlanes = 1; 4213 info.bmiHeader.biBitCount = 32; 4214 info.bmiHeader.biCompression = BI_RGB; 4215 4216 /* First show that GetDIBits ignores the layout mode. */ 4217 4218 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS ); 4219 ok(ret == 8, "got %d\n", ret); 4220 ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */ 4221 4222 pSetLayout( hdc_mem, LAYOUT_RTL ); 4223 4224 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS ); 4225 ok(ret == 8, "got %d\n", ret); 4226 4227 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n"); 4228 4229 /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits 4230 followed by a GetDIBits and show that the bits remain unchanged. */ 4231 4232 pSetLayout( hdc_mem, LAYOUT_LTR ); 4233 4234 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS ); 4235 ok(ret == 8, "got %d\n", ret); 4236 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS ); 4237 ok(ret == 8, "got %d\n", ret); 4238 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n"); 4239 4240 pSetLayout( hdc_mem, LAYOUT_RTL ); 4241 4242 ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS ); 4243 ok(ret == 8, "got %d\n", ret); 4244 ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS ); 4245 ok(ret == 8, "got %d\n", ret); 4246 ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n"); 4247 4248 DeleteObject( bitmap ); 4249 DeleteDC( hdc_mem ); 4250 ReleaseDC( NULL, hdc ); 4251 } 4252 4253 static void test_GetDIBits_scanlines(void) 4254 { 4255 BITMAPINFO *info; 4256 DWORD *dib_bits; 4257 HDC hdc = GetDC( NULL ); 4258 HBITMAP dib; 4259 DWORD data[128], inverted_bits[64]; 4260 int i, ret; 4261 4262 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ); 4263 4264 info->bmiHeader.biSize = sizeof(info->bmiHeader); 4265 info->bmiHeader.biWidth = 8; 4266 info->bmiHeader.biHeight = 8; 4267 info->bmiHeader.biPlanes = 1; 4268 info->bmiHeader.biBitCount = 32; 4269 info->bmiHeader.biCompression = BI_RGB; 4270 4271 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 ); 4272 4273 for (i = 0; i < 64; i++) 4274 { 4275 dib_bits[i] = i; 4276 inverted_bits[56 - (i & ~7) + (i & 7)] = i; 4277 } 4278 4279 /* b-u -> b-u */ 4280 4281 memset( data, 0xaa, sizeof(data) ); 4282 4283 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS ); 4284 ok( ret == 8, "got %d\n", ret ); 4285 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n"); 4286 memset( data, 0xaa, sizeof(data) ); 4287 4288 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS ); 4289 ok( ret == 5, "got %d\n", ret ); 4290 ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n"); 4291 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4292 memset( data, 0xaa, sizeof(data) ); 4293 4294 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS ); 4295 ok( ret == 7, "got %d\n", ret ); 4296 ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n"); 4297 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4298 memset( data, 0xaa, sizeof(data) ); 4299 4300 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS ); 4301 ok( ret == 1, "got %d\n", ret ); 4302 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4303 memset( data, 0xaa, sizeof(data) ); 4304 4305 info->bmiHeader.biHeight = 16; 4306 info->bmiHeader.biSizeImage = 0; 4307 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS ); 4308 ok( ret == 5, "got %d\n", ret ); 4309 ok( info->bmiHeader.biSizeImage == 128 * 4, "got %d\n", info->bmiHeader.biSizeImage ); 4310 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] ); 4311 ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n"); 4312 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4313 memset( data, 0xaa, sizeof(data) ); 4314 4315 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS ); 4316 ok( ret == 6, "got %d\n", ret ); 4317 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] ); 4318 ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n"); 4319 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4320 memset( data, 0xaa, sizeof(data) ); 4321 4322 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS ); 4323 ok( ret == 0, "got %d\n", ret ); 4324 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] ); 4325 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4326 memset( data, 0xaa, sizeof(data) ); 4327 4328 info->bmiHeader.biHeight = 5; 4329 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS ); 4330 ok( ret == 2, "got %d\n", ret ); 4331 ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n"); 4332 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4333 memset( data, 0xaa, sizeof(data) ); 4334 4335 /* b-u -> t-d */ 4336 4337 info->bmiHeader.biHeight = -8; 4338 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS ); 4339 ok( ret == 8, "got %d\n", ret ); 4340 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n"); 4341 memset( data, 0xaa, sizeof(data) ); 4342 4343 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS ); 4344 ok( ret == 5, "got %d\n", ret ); 4345 ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n"); 4346 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4347 memset( data, 0xaa, sizeof(data) ); 4348 4349 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS ); 4350 ok( ret == 7, "got %d\n", ret ); 4351 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n"); 4352 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4353 memset( data, 0xaa, sizeof(data) ); 4354 4355 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS ); 4356 ok( ret == 4, "got %d\n", ret ); 4357 ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n"); 4358 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4359 memset( data, 0xaa, sizeof(data) ); 4360 4361 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS ); 4362 ok( ret == 5, "got %d\n", ret ); 4363 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n"); 4364 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4365 memset( data, 0xaa, sizeof(data) ); 4366 4367 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS ); 4368 ok( ret == 5, "got %d\n", ret ); 4369 ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n"); 4370 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4371 memset( data, 0xaa, sizeof(data) ); 4372 4373 info->bmiHeader.biHeight = -16; 4374 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS ); 4375 ok( ret == 8, "got %d\n", ret ); 4376 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n"); 4377 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] ); 4378 memset( data, 0xaa, sizeof(data) ); 4379 4380 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS ); 4381 ok( ret == 5, "got %d\n", ret ); 4382 ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n"); 4383 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] ); 4384 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4385 memset( data, 0xaa, sizeof(data) ); 4386 4387 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS ); 4388 ok( ret == 8, "got %d\n", ret ); 4389 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n"); 4390 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] ); 4391 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4392 memset( data, 0xaa, sizeof(data) ); 4393 4394 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS ); 4395 ok( ret == 8, "got %d\n", ret ); 4396 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n"); 4397 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] ); 4398 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4399 memset( data, 0xaa, sizeof(data) ); 4400 4401 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS ); 4402 ok( ret == 7, "got %d\n", ret ); 4403 ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n"); 4404 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4405 memset( data, 0xaa, sizeof(data) ); 4406 4407 ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS ); 4408 ok( ret == 1, "got %d\n", ret ); 4409 for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4410 memset( data, 0xaa, sizeof(data) ); 4411 4412 info->bmiHeader.biHeight = -5; 4413 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS ); 4414 ok( ret == 2, "got %d\n", ret ); 4415 ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n"); 4416 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4417 memset( data, 0xaa, sizeof(data) ); 4418 4419 DeleteObject( dib ); 4420 4421 info->bmiHeader.biSize = sizeof(info->bmiHeader); 4422 info->bmiHeader.biWidth = 8; 4423 info->bmiHeader.biHeight = -8; 4424 info->bmiHeader.biPlanes = 1; 4425 info->bmiHeader.biBitCount = 32; 4426 info->bmiHeader.biCompression = BI_RGB; 4427 4428 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 ); 4429 4430 for (i = 0; i < 64; i++) dib_bits[i] = i; 4431 4432 /* t-d -> t-d */ 4433 4434 info->bmiHeader.biHeight = -8; 4435 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS ); 4436 ok( ret == 8, "got %d\n", ret ); 4437 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n"); 4438 memset( data, 0xaa, sizeof(data) ); 4439 4440 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS ); 4441 ok( ret == 5, "got %d\n", ret ); 4442 ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n"); 4443 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4444 memset( data, 0xaa, sizeof(data) ); 4445 4446 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS ); 4447 ok( ret == 7, "got %d\n", ret ); 4448 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n"); 4449 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4450 memset( data, 0xaa, sizeof(data) ); 4451 4452 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS ); 4453 ok( ret == 4, "got %d\n", ret ); 4454 ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n"); 4455 for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4456 memset( data, 0xaa, sizeof(data) ); 4457 4458 ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS ); 4459 ok( ret == 5, "got %d\n", ret ); 4460 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n"); 4461 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4462 memset( data, 0xaa, sizeof(data) ); 4463 4464 ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS ); 4465 ok( ret == 5, "got %d\n", ret ); 4466 ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n"); 4467 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4468 memset( data, 0xaa, sizeof(data) ); 4469 4470 info->bmiHeader.biHeight = -16; 4471 ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS ); 4472 ok( ret == 8, "got %d\n", ret ); 4473 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n"); 4474 for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] ); 4475 memset( data, 0xaa, sizeof(data) ); 4476 4477 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS ); 4478 ok( ret == 5, "got %d\n", ret ); 4479 ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n"); 4480 for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] ); 4481 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4482 memset( data, 0xaa, sizeof(data) ); 4483 4484 ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS ); 4485 ok( ret == 8, "got %d\n", ret ); 4486 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n"); 4487 for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] ); 4488 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4489 memset( data, 0xaa, sizeof(data) ); 4490 4491 ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS ); 4492 ok( ret == 8, "got %d\n", ret ); 4493 ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n"); 4494 for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] ); 4495 for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4496 memset( data, 0xaa, sizeof(data) ); 4497 4498 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS ); 4499 ok( ret == 7, "got %d\n", ret ); 4500 ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n"); 4501 for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4502 memset( data, 0xaa, sizeof(data) ); 4503 4504 info->bmiHeader.biHeight = -5; 4505 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS ); 4506 ok( ret == 2, "got %d\n", ret ); 4507 ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n"); 4508 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4509 memset( data, 0xaa, sizeof(data) ); 4510 4511 4512 /* t-d -> b-u */ 4513 4514 info->bmiHeader.biHeight = 8; 4515 4516 ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS ); 4517 ok( ret == 8, "got %d\n", ret ); 4518 ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n"); 4519 memset( data, 0xaa, sizeof(data) ); 4520 4521 ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS ); 4522 ok( ret == 5, "got %d\n", ret ); 4523 ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n"); 4524 for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4525 memset( data, 0xaa, sizeof(data) ); 4526 4527 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS ); 4528 ok( ret == 7, "got %d\n", ret ); 4529 ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n"); 4530 for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4531 memset( data, 0xaa, sizeof(data) ); 4532 4533 ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS ); 4534 ok( ret == 1, "got %d\n", ret ); 4535 for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4536 memset( data, 0xaa, sizeof(data) ); 4537 4538 info->bmiHeader.biHeight = 16; 4539 ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS ); 4540 ok( ret == 5, "got %d\n", ret ); 4541 for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] ); 4542 ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n"); 4543 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4544 memset( data, 0xaa, sizeof(data) ); 4545 4546 ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS ); 4547 ok( ret == 6, "got %d\n", ret ); 4548 for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] ); 4549 ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n"); 4550 for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4551 memset( data, 0xaa, sizeof(data) ); 4552 4553 ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS ); 4554 ok( ret == 0, "got %d\n", ret ); 4555 for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] ); 4556 for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4557 memset( data, 0xaa, sizeof(data) ); 4558 4559 info->bmiHeader.biHeight = 5; 4560 ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS ); 4561 ok( ret == 2, "got %d\n", ret ); 4562 ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n"); 4563 for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] ); 4564 4565 DeleteObject( dib ); 4566 4567 ReleaseDC( NULL, hdc ); 4568 HeapFree( GetProcessHeap(), 0, info ); 4569 } 4570 4571 4572 static void test_SetDIBits(void) 4573 { 4574 char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)]; 4575 LOGPALETTE *pal = (LOGPALETTE *)palbuf; 4576 PALETTEENTRY *palent = pal->palPalEntry; 4577 HPALETTE palette; 4578 BITMAPINFO *info; 4579 DWORD *dib_bits; 4580 HDC hdc = GetDC( NULL ); 4581 DWORD data[128], inverted_data[128]; 4582 HBITMAP dib; 4583 int i, ret; 4584 4585 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ); 4586 4587 info->bmiHeader.biSize = sizeof(info->bmiHeader); 4588 info->bmiHeader.biWidth = 8; 4589 info->bmiHeader.biHeight = 8; 4590 info->bmiHeader.biPlanes = 1; 4591 info->bmiHeader.biBitCount = 32; 4592 info->bmiHeader.biCompression = BI_RGB; 4593 4594 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 ); 4595 memset( dib_bits, 0xaa, 64 * 4 ); 4596 4597 for (i = 0; i < 128; i++) 4598 { 4599 data[i] = i; 4600 inverted_data[120 - (i & ~7) + (i & 7)] = i; 4601 } 4602 4603 /* b-u -> b-u */ 4604 4605 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS ); 4606 ok( ret == 8, "got %d\n", ret ); 4607 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n"); 4608 memset( dib_bits, 0xaa, 64 * 4 ); 4609 4610 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS ); 4611 ok( ret == 5, "got %d\n", ret ); 4612 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4613 ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n"); 4614 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4615 memset( dib_bits, 0xaa, 64 * 4 ); 4616 4617 /* top of dst is aligned with startscans down for the top of the src. 4618 Then starting from the bottom of src, lines rows are copied across. */ 4619 4620 info->bmiHeader.biHeight = 16; 4621 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS ); 4622 ok( ret == 12, "got %d\n", ret ); 4623 ok( !memcmp( dib_bits, data + 56, 40 * 4 ), "bits differ\n"); 4624 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4625 memset( dib_bits, 0xaa, 64 * 4 ); 4626 4627 info->bmiHeader.biHeight = 5; 4628 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS ); 4629 ok( ret == 2, "got %d\n", ret ); 4630 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4631 ok( !memcmp( dib_bits + 32, data, 16 * 4 ), "bits differ\n"); 4632 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4633 memset( dib_bits, 0xaa, 64 * 4 ); 4634 4635 /* t-d -> b-u */ 4636 info->bmiHeader.biHeight = -8; 4637 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS ); 4638 ok( ret == 8, "got %d\n", ret ); 4639 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n"); 4640 memset( dib_bits, 0xaa, 64 * 4 ); 4641 4642 /* top of dst now lines up with -(abs(src_h) - startscan - lines) and 4643 we copy lines rows from the top of the src */ 4644 4645 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS ); 4646 ok( ret == 5, "got %d\n", ret ); 4647 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4648 ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n"); 4649 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4650 memset( dib_bits, 0xaa, 64 * 4 ); 4651 4652 info->bmiHeader.biHeight = -16; 4653 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS ); 4654 ok( ret == 12, "got %d\n", ret ); 4655 ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n"); 4656 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4657 memset( dib_bits, 0xaa, 64 * 4 ); 4658 4659 ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS ); 4660 ok( ret == 12, "got %d\n", ret ); 4661 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n"); 4662 memset( dib_bits, 0xaa, 64 * 4 ); 4663 4664 ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS ); 4665 ok( ret == 12, "got %d\n", ret ); 4666 ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n"); 4667 memset( dib_bits, 0xaa, 64 * 4 ); 4668 4669 info->bmiHeader.biHeight = -5; 4670 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS ); 4671 ok( ret == 2, "got %d\n", ret ); 4672 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4673 ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n"); 4674 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4675 memset( dib_bits, 0xaa, 64 * 4 ); 4676 4677 DeleteObject( dib ); 4678 4679 info->bmiHeader.biHeight = -8; 4680 4681 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 ); 4682 memset( dib_bits, 0xaa, 16 * 16 * 4 ); 4683 4684 /* t-d -> t-d */ 4685 4686 /* like the t-d -> b-u case. */ 4687 4688 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS ); 4689 ok( ret == 8, "got %d\n", ret ); 4690 ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n"); 4691 memset( dib_bits, 0xaa, 64 * 4 ); 4692 4693 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS ); 4694 ok( ret == 5, "got %d\n", ret ); 4695 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4696 ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n"); 4697 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4698 memset( dib_bits, 0xaa, 64 * 4 ); 4699 4700 info->bmiHeader.biHeight = -16; 4701 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS ); 4702 ok( ret == 12, "got %d\n", ret ); 4703 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4704 ok( !memcmp( dib_bits + 24, data, 40 * 4 ), "bits differ\n"); 4705 memset( dib_bits, 0xaa, 64 * 4 ); 4706 4707 info->bmiHeader.biHeight = -5; 4708 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS ); 4709 ok( ret == 2, "got %d\n", ret ); 4710 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4711 ok( !memcmp( dib_bits + 16, data, 16 * 4 ), "bits differ\n"); 4712 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4713 memset( dib_bits, 0xaa, 64 * 4 ); 4714 4715 /* b-u -> t-d */ 4716 /* like the b-u -> b-u case */ 4717 4718 info->bmiHeader.biHeight = 8; 4719 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS ); 4720 ok( ret == 8, "got %d\n", ret ); 4721 ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n"); 4722 memset( dib_bits, 0xaa, 64 * 4 ); 4723 4724 ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS ); 4725 ok( ret == 5, "got %d\n", ret ); 4726 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4727 ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n"); 4728 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4729 memset( dib_bits, 0xaa, 64 * 4 ); 4730 4731 info->bmiHeader.biHeight = 16; 4732 ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS ); 4733 ok( ret == 12, "got %d\n", ret ); 4734 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4735 ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n"); 4736 memset( dib_bits, 0xaa, 64 * 4 ); 4737 4738 info->bmiHeader.biHeight = 5; 4739 ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS ); 4740 ok( ret == 2, "got %d\n", ret ); 4741 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4742 ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n"); 4743 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4744 memset( dib_bits, 0xaa, 64 * 4 ); 4745 4746 /* handling of partial color table */ 4747 4748 info->bmiHeader.biHeight = -8; 4749 info->bmiHeader.biBitCount = 8; 4750 info->bmiHeader.biClrUsed = 137; 4751 for (i = 0; i < 256; i++) 4752 { 4753 info->bmiColors[i].rgbRed = 255 - i; 4754 info->bmiColors[i].rgbGreen = i * 2; 4755 info->bmiColors[i].rgbBlue = i; 4756 info->bmiColors[i].rgbReserved = 0; 4757 } 4758 for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1; 4759 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS ); 4760 ok( ret == 8, "got %d\n", ret ); 4761 for (i = 0; i < 64; i++) 4762 { 4763 int idx = i * 4 + 1; 4764 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 | 4765 info->bmiColors[idx].rgbGreen << 8 | 4766 info->bmiColors[idx].rgbBlue); 4767 ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect ); 4768 } 4769 memset( dib_bits, 0xaa, 64 * 4 ); 4770 4771 /* handling of DIB_PAL_COLORS */ 4772 4773 pal->palVersion = 0x300; 4774 pal->palNumEntries = 137; 4775 info->bmiHeader.biClrUsed = 221; 4776 for (i = 0; i < 256; i++) 4777 { 4778 palent[i].peRed = i * 2; 4779 palent[i].peGreen = 255 - i; 4780 palent[i].peBlue = i; 4781 } 4782 palette = CreatePalette( pal ); 4783 ok( palette != 0, "palette creation failed\n" ); 4784 SelectPalette( hdc, palette, FALSE ); 4785 for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i; 4786 ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_PAL_COLORS ); 4787 ok( ret == 8, "got %d\n", ret ); 4788 for (i = 0; i < 64; i++) 4789 { 4790 int idx = i * 4 + 1; 4791 int ent = (255 - idx) % pal->palNumEntries; 4792 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : 4793 (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue); 4794 ok( dib_bits[i] == expect || broken(dib_bits[i] == 0), /* various Windows versions get some values wrong */ 4795 "%d: got %08x instead of %08x\n", i, dib_bits[i], expect ); 4796 } 4797 memset( dib_bits, 0xaa, 64 * 4 ); 4798 4799 ReleaseDC( NULL, hdc ); 4800 DeleteObject( dib ); 4801 DeleteObject( palette ); 4802 HeapFree( GetProcessHeap(), 0, info ); 4803 } 4804 4805 static void test_SetDIBits_RLE4(void) 4806 { 4807 BITMAPINFO *info; 4808 DWORD *dib_bits; 4809 HDC hdc = GetDC( NULL ); 4810 BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00, /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */ 4811 0x00, 0x03, 0x14, 0x50, 0x00, 0x05, 4812 0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00, /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */ 4813 0x00, 0x02, 0x01, 0x02, 0x05, 0x87, /* dx=1, dy=2, 8, 7, 8, 7, 8 */ 4814 0x00, 0x01 }; /* <eod> */ 4815 HBITMAP dib; 4816 int i, ret; 4817 DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606, 4818 0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b, 4819 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 4820 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 4821 0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa, 4822 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 4823 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 4824 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa }; 4825 4826 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ); 4827 4828 info->bmiHeader.biSize = sizeof(info->bmiHeader); 4829 info->bmiHeader.biWidth = 8; 4830 info->bmiHeader.biHeight = 8; 4831 info->bmiHeader.biPlanes = 1; 4832 info->bmiHeader.biBitCount = 32; 4833 info->bmiHeader.biCompression = BI_RGB; 4834 4835 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 ); 4836 memset( dib_bits, 0xaa, 64 * 4 ); 4837 4838 info->bmiHeader.biBitCount = 4; 4839 info->bmiHeader.biCompression = BI_RLE4; 4840 info->bmiHeader.biSizeImage = sizeof(rle4_data); 4841 4842 for (i = 0; i < 16; i++) 4843 { 4844 info->bmiColors[i].rgbRed = i; 4845 info->bmiColors[i].rgbGreen = i; 4846 info->bmiColors[i].rgbBlue = i; 4847 info->bmiColors[i].rgbReserved = 0; 4848 } 4849 4850 ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS ); 4851 ok( ret == 8, "got %d\n", ret ); 4852 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" ); 4853 memset( dib_bits, 0xaa, 64 * 4 ); 4854 4855 DeleteObject( dib ); 4856 ReleaseDC( NULL, hdc ); 4857 HeapFree( GetProcessHeap(), 0, info ); 4858 } 4859 4860 static void test_SetDIBits_RLE8(void) 4861 { 4862 BITMAPINFO *info; 4863 DWORD *dib_bits; 4864 HDC hdc = GetDC( NULL ); 4865 BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00, /* 2, 2, 2, f0, f0, f0, f0, <eol> */ 4866 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */ 4867 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */ 4868 0x00, 0x01 }; /* <eod> */ 4869 HBITMAP dib; 4870 int i, ret; 4871 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa, 4872 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 4873 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 4874 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080, 4875 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 4876 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 4877 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 4878 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa }; 4879 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 4880 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 4881 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 4882 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 4883 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080, 4884 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 4885 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 4886 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa }; 4887 4888 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ); 4889 4890 info->bmiHeader.biSize = sizeof(info->bmiHeader); 4891 info->bmiHeader.biWidth = 8; 4892 info->bmiHeader.biHeight = 8; 4893 info->bmiHeader.biPlanes = 1; 4894 info->bmiHeader.biBitCount = 32; 4895 info->bmiHeader.biCompression = BI_RGB; 4896 4897 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 ); 4898 memset( dib_bits, 0xaa, 64 * 4 ); 4899 4900 info->bmiHeader.biBitCount = 8; 4901 info->bmiHeader.biCompression = BI_RLE8; 4902 info->bmiHeader.biSizeImage = sizeof(rle8_data); 4903 4904 for (i = 0; i < 256; i++) 4905 { 4906 info->bmiColors[i].rgbRed = i; 4907 info->bmiColors[i].rgbGreen = i; 4908 info->bmiColors[i].rgbBlue = i; 4909 info->bmiColors[i].rgbReserved = 0; 4910 } 4911 4912 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS ); 4913 ok( ret == 8, "got %d\n", ret ); 4914 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n"); 4915 memset( dib_bits, 0xaa, 64 * 4 ); 4916 4917 /* startscan and lines are ignored, unless lines == 0 */ 4918 ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS ); 4919 ok( ret == 8, "got %d\n", ret ); 4920 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n"); 4921 memset( dib_bits, 0xaa, 64 * 4 ); 4922 4923 ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS ); 4924 ok( ret == 8, "got %d\n", ret ); 4925 ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n"); 4926 memset( dib_bits, 0xaa, 64 * 4 ); 4927 4928 ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS ); 4929 ok( ret == 0, "got %d\n", ret ); 4930 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4931 memset( dib_bits, 0xaa, 64 * 4 ); 4932 4933 /* reduce width to 4, left-hand side of dst is touched. */ 4934 info->bmiHeader.biWidth = 4; 4935 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS ); 4936 ok( ret == 8, "got %d\n", ret ); 4937 for (i = 0; i < 64; i++) 4938 { 4939 DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i]; 4940 ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] ); 4941 } 4942 memset( dib_bits, 0xaa, 64 * 4 ); 4943 4944 /* Show that the top lines are aligned by adjusting the height of the src */ 4945 4946 /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */ 4947 info->bmiHeader.biWidth = 8; 4948 info->bmiHeader.biHeight = 4; 4949 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS ); 4950 ok( ret == 4, "got %d\n", ret ); 4951 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4952 ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n"); 4953 memset( dib_bits, 0xaa, 64 * 4 ); 4954 4955 /* increase the height to 9 -> everything moves down one row. */ 4956 info->bmiHeader.biHeight = 9; 4957 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS ); 4958 ok( ret == 9, "got %d\n", ret ); 4959 ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n"); 4960 for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] ); 4961 memset( dib_bits, 0xaa, 64 * 4 ); 4962 4963 /* top-down compressed dibs are invalid */ 4964 info->bmiHeader.biHeight = -8; 4965 SetLastError( 0xdeadbeef ); 4966 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS ); 4967 ok( ret == 0, "got %d\n", ret ); 4968 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() ); 4969 DeleteObject( dib ); 4970 4971 /* top-down dst */ 4972 4973 info->bmiHeader.biHeight = -8; 4974 info->bmiHeader.biBitCount = 32; 4975 info->bmiHeader.biCompression = BI_RGB; 4976 info->bmiHeader.biSizeImage = 0; 4977 4978 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 ); 4979 memset( dib_bits, 0xaa, 16 * 16 * 4 ); 4980 4981 info->bmiHeader.biHeight = 8; 4982 info->bmiHeader.biBitCount = 8; 4983 info->bmiHeader.biCompression = BI_RLE8; 4984 info->bmiHeader.biSizeImage = sizeof(rle8_data); 4985 4986 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS ); 4987 ok( ret == 8, "got %d\n", ret ); 4988 ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n"); 4989 memset( dib_bits, 0xaa, 64 * 4 ); 4990 4991 info->bmiHeader.biHeight = 4; 4992 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS ); 4993 ok( ret == 4, "got %d\n", ret ); 4994 ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n"); 4995 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 4996 memset( dib_bits, 0xaa, 64 * 4 ); 4997 4998 info->bmiHeader.biHeight = 9; 4999 ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS ); 5000 ok( ret == 9, "got %d\n", ret ); 5001 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5002 ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n"); 5003 memset( dib_bits, 0xaa, 64 * 4 ); 5004 5005 DeleteObject( dib ); 5006 ReleaseDC( NULL, hdc ); 5007 HeapFree( GetProcessHeap(), 0, info ); 5008 } 5009 5010 static void test_SetDIBitsToDevice(void) 5011 { 5012 char palbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)]; 5013 LOGPALETTE *pal = (LOGPALETTE *)palbuf; 5014 PALETTEENTRY *palent = pal->palPalEntry; 5015 HPALETTE palette; 5016 BITMAPINFO *info; 5017 DWORD *dib_bits; 5018 HDC hdc = CreateCompatibleDC( 0 ); 5019 DWORD data[128], inverted_data[128]; 5020 HBITMAP dib; 5021 int i, ret; 5022 5023 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ); 5024 5025 info->bmiHeader.biSize = sizeof(info->bmiHeader); 5026 info->bmiHeader.biWidth = 8; 5027 info->bmiHeader.biHeight = 8; 5028 info->bmiHeader.biPlanes = 1; 5029 info->bmiHeader.biBitCount = 32; 5030 info->bmiHeader.biCompression = BI_RGB; 5031 5032 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 ); 5033 memset( dib_bits, 0xaa, 64 * 4 ); 5034 SelectObject( hdc, dib ); 5035 5036 for (i = 0; i < 128; i++) 5037 { 5038 data[i] = i; 5039 inverted_data[120 - (i & ~7) + (i & 7)] = i; 5040 } 5041 5042 /* b-u -> b-u */ 5043 5044 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS ); 5045 ok( ret == 8, "got %d\n", ret ); 5046 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] ); 5047 memset( dib_bits, 0xaa, 64 * 4 ); 5048 5049 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS ); 5050 ok( ret == 5, "got %d\n", ret ); 5051 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5052 for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] ); 5053 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5054 memset( dib_bits, 0xaa, 64 * 4 ); 5055 5056 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS ); 5057 ok( ret == 5, "got %d\n", ret ); 5058 for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] ); 5059 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5060 memset( dib_bits, 0xaa, 64 * 4 ); 5061 5062 info->bmiHeader.biHeight = 16; 5063 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS ); 5064 ok( ret == 7, "got %d\n", ret ); 5065 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5066 for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] ); 5067 memset( dib_bits, 0xaa, 64 * 4 ); 5068 5069 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS ); 5070 ok( ret == 12, "got %d\n", ret ); 5071 for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] ); 5072 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5073 memset( dib_bits, 0xaa, 64 * 4 ); 5074 5075 ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS ); 5076 ok( ret == 10, "got %d\n", ret ); 5077 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5078 for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] ); 5079 memset( dib_bits, 0xaa, 64 * 4 ); 5080 5081 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS ); 5082 ok( ret == 4, "got %d\n", ret ); 5083 for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] ); 5084 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5085 memset( dib_bits, 0xaa, 64 * 4 ); 5086 5087 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS ); 5088 ok( ret == 2, "got %d\n", ret ); 5089 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5090 for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] ); 5091 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5092 memset( dib_bits, 0xaa, 64 * 4 ); 5093 5094 info->bmiHeader.biHeight = 5; 5095 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS ); 5096 ok( ret == 2, "got %d\n", ret ); 5097 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5098 for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] ); 5099 for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5100 memset( dib_bits, 0xaa, 64 * 4 ); 5101 5102 ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS ); 5103 ok( ret == 3, "got %d\n", ret ); 5104 for (i = 0; i < 64; i++) 5105 if (i == 27 || i == 28 || i == 35 || i == 36) 5106 ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] ); 5107 else 5108 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5109 memset( dib_bits, 0xaa, 64 * 4 ); 5110 5111 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS ); 5112 ok( ret == 5, "got %d\n", ret ); 5113 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5114 memset( dib_bits, 0xaa, 64 * 4 ); 5115 5116 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS ); 5117 ok( ret == 0, "got %d\n", ret ); 5118 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5119 memset( dib_bits, 0xaa, 64 * 4 ); 5120 5121 SetMapMode( hdc, MM_ANISOTROPIC ); 5122 SetWindowExtEx( hdc, 3, 3, NULL ); 5123 ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS ); 5124 ok( ret == 3, "got %d\n", ret ); 5125 for (i = 0; i < 64; i++) 5126 if (i == 41 || i == 42 || i == 49 || i == 50) 5127 ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] ); 5128 else 5129 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5130 memset( dib_bits, 0xaa, 64 * 4 ); 5131 5132 SetWindowExtEx( hdc, -1, -1, NULL ); 5133 ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS ); 5134 ok( ret == 4, "got %d\n", ret ); 5135 for (i = 0; i < 64; i++) 5136 if (i == 48 || i == 49 || i == 56 || i == 57) 5137 ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] ); 5138 else 5139 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5140 memset( dib_bits, 0xaa, 64 * 4 ); 5141 SetMapMode( hdc, MM_TEXT ); 5142 5143 if (pSetLayout) 5144 { 5145 pSetLayout( hdc, LAYOUT_RTL ); 5146 ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS ); 5147 ok( ret == 3, "got %d\n", ret ); 5148 for (i = 0; i < 64; i++) 5149 if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46) 5150 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] ); 5151 else 5152 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5153 memset( dib_bits, 0xaa, 64 * 4 ); 5154 pSetLayout( hdc, LAYOUT_LTR ); 5155 } 5156 5157 /* t-d -> b-u */ 5158 info->bmiHeader.biHeight = -8; 5159 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS ); 5160 ok( ret == 8, "got %d\n", ret ); 5161 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] ); 5162 memset( dib_bits, 0xaa, 64 * 4 ); 5163 5164 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS ); 5165 ok( ret == 5, "got %d\n", ret ); 5166 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5167 for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] ); 5168 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5169 memset( dib_bits, 0xaa, 64 * 4 ); 5170 5171 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS ); 5172 ok( ret == 5, "got %d\n", ret ); 5173 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] ); 5174 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5175 memset( dib_bits, 0xaa, 64 * 4 ); 5176 5177 info->bmiHeader.biHeight = -16; 5178 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS ); 5179 ok( ret == 12, "got %d\n", ret ); 5180 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5181 for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] ); 5182 memset( dib_bits, 0xaa, 64 * 4 ); 5183 5184 ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS ); 5185 ok( ret == 12, "got %d\n", ret ); 5186 for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] ); 5187 for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5188 memset( dib_bits, 0xaa, 64 * 4 ); 5189 5190 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS ); 5191 ok( ret == 12, "got %d\n", ret ); 5192 for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5193 for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] ); 5194 memset( dib_bits, 0xaa, 64 * 4 ); 5195 5196 ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS ); 5197 ok( ret == 12, "got %d\n", ret ); 5198 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5199 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] ); 5200 memset( dib_bits, 0xaa, 64 * 4 ); 5201 5202 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS ); 5203 ok( ret == 12, "got %d\n", ret ); 5204 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5205 for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] ); 5206 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5207 memset( dib_bits, 0xaa, 64 * 4 ); 5208 5209 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS ); 5210 ok( ret == 12, "got %d\n", ret ); 5211 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5212 for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] ); 5213 memset( dib_bits, 0xaa, 64 * 4 ); 5214 5215 ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS ); 5216 ok( ret == 12, "got %d\n", ret ); 5217 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5218 memset( dib_bits, 0xaa, 64 * 4 ); 5219 5220 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS ); 5221 ok( ret == 12, "got %d\n", ret ); 5222 for (i = 0; i < 64; i++) 5223 if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63) 5224 ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] ); 5225 else 5226 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5227 memset( dib_bits, 0xaa, 64 * 4 ); 5228 5229 info->bmiHeader.biHeight = -5; 5230 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS ); 5231 ok( ret == 2, "got %d\n", ret ); 5232 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5233 for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] ); 5234 for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5235 memset( dib_bits, 0xaa, 64 * 4 ); 5236 5237 ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS ); 5238 ok( ret == 5, "got %d\n", ret ); 5239 for (i = 0; i < 64; i++) 5240 if (i == 21 || i == 22 || i == 29 || i == 30) 5241 ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] ); 5242 else 5243 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5244 memset( dib_bits, 0xaa, 64 * 4 ); 5245 5246 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS ); 5247 ok( ret == 5, "got %d\n", ret ); 5248 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5249 memset( dib_bits, 0xaa, 64 * 4 ); 5250 5251 info->bmiHeader.biHeight = -8; 5252 5253 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 ); 5254 DeleteObject( SelectObject( hdc, dib )); 5255 memset( dib_bits, 0xaa, 16 * 16 * 4 ); 5256 5257 /* t-d -> t-d */ 5258 5259 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS ); 5260 ok( ret == 8, "got %d\n", ret ); 5261 for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] ); 5262 memset( dib_bits, 0xaa, 64 * 4 ); 5263 5264 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS ); 5265 ok( ret == 5, "got %d\n", ret ); 5266 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5267 for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] ); 5268 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5269 memset( dib_bits, 0xaa, 64 * 4 ); 5270 5271 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS ); 5272 ok( ret == 5, "got %d\n", ret ); 5273 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5274 for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] ); 5275 for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5276 memset( dib_bits, 0xaa, 64 * 4 ); 5277 5278 info->bmiHeader.biHeight = -16; 5279 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS ); 5280 ok( ret == 12, "got %d\n", ret ); 5281 for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] ); 5282 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5283 memset( dib_bits, 0xaa, 64 * 4 ); 5284 5285 ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS ); 5286 ok( ret == 12, "got %d\n", ret ); 5287 for (i = 0; i < 64; i++) 5288 if (i == 6 || i == 7) 5289 ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] ); 5290 else 5291 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5292 memset( dib_bits, 0xaa, 64 * 4 ); 5293 5294 info->bmiHeader.biHeight = -5; 5295 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS ); 5296 ok( ret == 2, "got %d\n", ret ); 5297 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5298 for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] ); 5299 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5300 memset( dib_bits, 0xaa, 64 * 4 ); 5301 5302 ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS ); 5303 ok( ret == 5, "got %d\n", ret ); 5304 for (i = 0; i < 64; i++) 5305 if (i == 47 || i == 55 || i == 63) 5306 ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] ); 5307 else 5308 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5309 memset( dib_bits, 0xaa, 64 * 4 ); 5310 5311 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS ); 5312 ok( ret == 5, "got %d\n", ret ); 5313 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5314 memset( dib_bits, 0xaa, 64 * 4 ); 5315 5316 /* b-u -> t-d */ 5317 5318 info->bmiHeader.biHeight = 8; 5319 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS ); 5320 ok( ret == 8, "got %d\n", ret ); 5321 for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] ); 5322 memset( dib_bits, 0xaa, 64 * 4 ); 5323 5324 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS ); 5325 ok( ret == 5, "got %d\n", ret ); 5326 for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5327 for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] ); 5328 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5329 memset( dib_bits, 0xaa, 64 * 4 ); 5330 5331 info->bmiHeader.biHeight = 16; 5332 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS ); 5333 ok( ret == 7, "got %d\n", ret ); 5334 for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] ); 5335 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5336 memset( dib_bits, 0xaa, 64 * 4 ); 5337 5338 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS ); 5339 ok( ret == 3, "got %d\n", ret ); 5340 for (i = 0; i < 64; i++) 5341 if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55)) 5342 ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] ); 5343 else 5344 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5345 memset( dib_bits, 0xaa, 64 * 4 ); 5346 5347 ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS ); 5348 ok( ret == 0, "got %d\n", ret ); 5349 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5350 memset( dib_bits, 0xaa, 64 * 4 ); 5351 5352 ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS ); 5353 ok( ret == 8, "got %d\n", ret ); 5354 for (i = 0; i < 64; i++) 5355 if (i == 7 || i == 15 || i == 23) 5356 ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] ); 5357 else 5358 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5359 memset( dib_bits, 0xaa, 64 * 4 ); 5360 5361 info->bmiHeader.biHeight = 5; 5362 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS ); 5363 ok( ret == 2, "got %d\n", ret ); 5364 for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5365 for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] ); 5366 for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5367 memset( dib_bits, 0xaa, 64 * 4 ); 5368 5369 ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS ); 5370 ok( ret == 5, "got %d\n", ret ); 5371 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5372 memset( dib_bits, 0xaa, 64 * 4 ); 5373 5374 /* handling of partial color table */ 5375 5376 info->bmiHeader.biHeight = -8; 5377 info->bmiHeader.biBitCount = 8; 5378 info->bmiHeader.biClrUsed = 137; 5379 for (i = 0; i < 256; i++) 5380 { 5381 info->bmiColors[i].rgbRed = 255 - i; 5382 info->bmiColors[i].rgbGreen = i * 2; 5383 info->bmiColors[i].rgbBlue = i; 5384 info->bmiColors[i].rgbReserved = 0; 5385 } 5386 for (i = 0; i < 64; i++) ((BYTE *)data)[i] = i * 4 + 1; 5387 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS ); 5388 ok( ret == 8, "got %d\n", ret ); 5389 for (i = 0; i < 64; i++) 5390 { 5391 int idx = i * 4 + 1; 5392 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : (info->bmiColors[idx].rgbRed << 16 | 5393 info->bmiColors[idx].rgbGreen << 8 | 5394 info->bmiColors[idx].rgbBlue); 5395 ok( dib_bits[i] == expect, "%d: got %08x instead of %08x\n", i, dib_bits[i], expect ); 5396 } 5397 memset( dib_bits, 0xaa, 64 * 4 ); 5398 5399 /* handling of DIB_PAL_COLORS */ 5400 5401 pal->palVersion = 0x300; 5402 pal->palNumEntries = 137; 5403 info->bmiHeader.biClrUsed = 221; 5404 for (i = 0; i < 256; i++) 5405 { 5406 palent[i].peRed = i * 2; 5407 palent[i].peGreen = 255 - i; 5408 palent[i].peBlue = i; 5409 } 5410 palette = CreatePalette( pal ); 5411 ok( palette != 0, "palette creation failed\n" ); 5412 SelectPalette( hdc, palette, FALSE ); 5413 for (i = 0; i < 256; i++) ((WORD *)info->bmiColors)[i] = 255 - i; 5414 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_PAL_COLORS ); 5415 ok( ret == 8, "got %d\n", ret ); 5416 for (i = 0; i < 64; i++) 5417 { 5418 int idx = i * 4 + 1; 5419 int ent = (255 - idx) % pal->palNumEntries; 5420 DWORD expect = idx >= info->bmiHeader.biClrUsed ? 0 : 5421 (palent[ent].peRed << 16 | palent[ent].peGreen << 8 | palent[ent].peBlue); 5422 ok( dib_bits[i] == expect || broken(dib_bits[i] == 0), 5423 "%d: got %08x instead of %08x\n", i, dib_bits[i], expect ); 5424 } 5425 memset( dib_bits, 0xaa, 64 * 4 ); 5426 5427 DeleteDC( hdc ); 5428 DeleteObject( dib ); 5429 DeleteObject( palette ); 5430 HeapFree( GetProcessHeap(), 0, info ); 5431 } 5432 5433 static void test_SetDIBitsToDevice_RLE8(void) 5434 { 5435 BITMAPINFO *info; 5436 DWORD *dib_bits; 5437 HDC hdc = CreateCompatibleDC( 0 ); 5438 BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00, /* 2, 2, 2, 2, f0, f0, f0, <eol> */ 5439 0x00, 0x03, 0x04, 0x05, 0x06, 0x00, /* 4, 5, 6, <pad> */ 5440 0x00, 0x02, 0x01, 0x02, 0x05, 0x80, /* dx=1, dy=2, 80, 80, 80, 80, (80) */ 5441 0x00, 0x01 }; /* <eod> */ 5442 HBITMAP dib; 5443 int i, ret; 5444 DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa, 5445 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 5446 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 5447 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080, 5448 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 5449 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 5450 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 5451 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa }; 5452 DWORD top_down[64] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 5453 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 5454 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 5455 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 5456 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080, 5457 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 5458 0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 5459 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa }; 5460 5461 info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ); 5462 5463 info->bmiHeader.biSize = sizeof(info->bmiHeader); 5464 info->bmiHeader.biWidth = 8; 5465 info->bmiHeader.biHeight = 8; 5466 info->bmiHeader.biPlanes = 1; 5467 info->bmiHeader.biBitCount = 32; 5468 info->bmiHeader.biCompression = BI_RGB; 5469 5470 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 ); 5471 memset( dib_bits, 0xaa, 64 * 4 ); 5472 SelectObject( hdc, dib ); 5473 5474 info->bmiHeader.biBitCount = 8; 5475 info->bmiHeader.biCompression = BI_RLE8; 5476 info->bmiHeader.biSizeImage = sizeof(rle8_data); 5477 5478 for (i = 0; i < 256; i++) 5479 { 5480 info->bmiColors[i].rgbRed = i; 5481 info->bmiColors[i].rgbGreen = i; 5482 info->bmiColors[i].rgbBlue = i; 5483 info->bmiColors[i].rgbReserved = 0; 5484 } 5485 5486 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS ); 5487 ok( ret == 8, "got %d\n", ret ); 5488 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] ); 5489 memset( dib_bits, 0xaa, 64 * 4 ); 5490 5491 /* startscan and lines are ignored, unless lines == 0 */ 5492 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS ); 5493 ok( ret == 8, "got %d\n", ret ); 5494 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] ); 5495 memset( dib_bits, 0xaa, 64 * 4 ); 5496 5497 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS ); 5498 ok( ret == 8, "got %d\n", ret ); 5499 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] ); 5500 memset( dib_bits, 0xaa, 64 * 4 ); 5501 5502 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS ); 5503 ok( ret == 0, "got %d\n", ret ); 5504 for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5505 memset( dib_bits, 0xaa, 64 * 4 ); 5506 5507 info->bmiHeader.biWidth = 2; 5508 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS ); 5509 ok( ret == 8, "got %d\n", ret ); 5510 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] ); 5511 memset( dib_bits, 0xaa, 64 * 4 ); 5512 5513 info->bmiHeader.biWidth = 8; 5514 info->bmiHeader.biHeight = 2; 5515 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS ); 5516 ok( ret == 2, "got %d\n", ret ); 5517 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] ); 5518 memset( dib_bits, 0xaa, 64 * 4 ); 5519 5520 info->bmiHeader.biHeight = 9; 5521 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS ); 5522 ok( ret == 9, "got %d\n", ret ); 5523 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] ); 5524 memset( dib_bits, 0xaa, 64 * 4 ); 5525 5526 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS ); 5527 ok( ret == 9, "got %d\n", ret ); 5528 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] ); 5529 memset( dib_bits, 0xaa, 64 * 4 ); 5530 5531 info->bmiHeader.biHeight = 8; 5532 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS ); 5533 ok( ret == 8, "got %d\n", ret ); 5534 for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] ); 5535 memset( dib_bits, 0xaa, 64 * 4 ); 5536 5537 ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS ); 5538 ok( ret == 8, "got %d\n", ret ); 5539 for (i = 0; i < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] ); 5540 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5541 memset( dib_bits, 0xaa, 64 * 4 ); 5542 5543 ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS ); 5544 ok( ret == 8, "got %d\n", ret ); 5545 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5546 for (i = 8; i < 40; i++) 5547 if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5548 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] ); 5549 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5550 memset( dib_bits, 0xaa, 64 * 4 ); 5551 5552 ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS ); 5553 ok( ret == 8, "got %d\n", ret ); 5554 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5555 for (i = 8; i < 40; i++) 5556 if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5557 else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] ); 5558 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5559 memset( dib_bits, 0xaa, 64 * 4 ); 5560 5561 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS ); 5562 ok( ret == 8, "got %d\n", ret ); 5563 for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5564 for (i = 8; i < 40; i++) 5565 if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5566 else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] ); 5567 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5568 memset( dib_bits, 0xaa, 64 * 4 ); 5569 5570 info->bmiHeader.biWidth = 37; 5571 info->bmiHeader.biHeight = 37; 5572 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS ); 5573 ok( ret == 37, "got %d\n", ret ); 5574 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5575 for (i = 24; i < 64; i++) 5576 if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] ); 5577 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5578 else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] ); 5579 memset( dib_bits, 0xaa, 64 * 4 ); 5580 5581 /* top-down compressed dibs are invalid */ 5582 info->bmiHeader.biWidth = 8; 5583 info->bmiHeader.biHeight = -8; 5584 SetLastError( 0xdeadbeef ); 5585 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS ); 5586 ok( ret == 0, "got %d\n", ret ); 5587 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() ); 5588 5589 /* top-down dst */ 5590 5591 info->bmiHeader.biHeight = -8; 5592 info->bmiHeader.biBitCount = 32; 5593 info->bmiHeader.biCompression = BI_RGB; 5594 info->bmiHeader.biSizeImage = 0; 5595 5596 dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 ); 5597 memset( dib_bits, 0xaa, 16 * 16 * 4 ); 5598 DeleteObject( SelectObject( hdc, dib )); 5599 5600 info->bmiHeader.biHeight = 8; 5601 info->bmiHeader.biBitCount = 8; 5602 info->bmiHeader.biCompression = BI_RLE8; 5603 info->bmiHeader.biSizeImage = sizeof(rle8_data); 5604 5605 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS ); 5606 ok( ret == 8, "got %d\n", ret ); 5607 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] ); 5608 memset( dib_bits, 0xaa, 64 * 4 ); 5609 5610 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS ); 5611 ok( ret == 8, "got %d\n", ret ); 5612 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] ); 5613 memset( dib_bits, 0xaa, 64 * 4 ); 5614 5615 info->bmiHeader.biHeight = 4; 5616 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS ); 5617 ok( ret == 4, "got %d\n", ret ); 5618 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] ); 5619 memset( dib_bits, 0xaa, 64 * 4 ); 5620 5621 info->bmiHeader.biHeight = 9; 5622 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS ); 5623 ok( ret == 9, "got %d\n", ret ); 5624 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] ); 5625 memset( dib_bits, 0xaa, 64 * 4 ); 5626 5627 ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS ); 5628 ok( ret == 9, "got %d\n", ret ); 5629 for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] ); 5630 memset( dib_bits, 0xaa, 64 * 4 ); 5631 5632 ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS ); 5633 ok( ret == 9, "got %d\n", ret ); 5634 for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5635 for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] ); 5636 memset( dib_bits, 0xaa, 64 * 4 ); 5637 5638 info->bmiHeader.biWidth = 37; 5639 info->bmiHeader.biHeight = 37; 5640 ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS ); 5641 ok( ret == 37, "got %d\n", ret ); 5642 for (i = 0; i < 40; i++) 5643 if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] ); 5644 else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5645 else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] ); 5646 for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); 5647 memset( dib_bits, 0xaa, 64 * 4 ); 5648 5649 DeleteDC( hdc ); 5650 DeleteObject( dib ); 5651 HeapFree( GetProcessHeap(), 0, info ); 5652 } 5653 5654 #ifndef __REACTOS__ /* CORE-11331 */ 5655 static void test_D3DKMTCreateDCFromMemory( void ) 5656 { 5657 D3DKMT_DESTROYDCFROMMEMORY destroy_desc; 5658 D3DKMT_CREATEDCFROMMEMORY create_desc; 5659 unsigned int width_bytes; 5660 unsigned int i, x, y, z; 5661 DWORD expected, colour; 5662 BYTE data[12][48]; 5663 NTSTATUS status; 5664 HGDIOBJ *bitmap; 5665 DIBSECTION dib; 5666 BOOL fail, ret; 5667 DWORD type, pixel; 5668 int size; 5669 HDC bmp_dc; 5670 HBITMAP bmp; 5671 5672 static const struct 5673 { 5674 const char *name; 5675 D3DDDIFORMAT format; 5676 unsigned int bit_count; 5677 DWORD mask_r, mask_g, mask_b; 5678 NTSTATUS status; 5679 } 5680 test_data[] = 5681 { 5682 { "R8G8B8", D3DDDIFMT_R8G8B8, 24, 0x00000000, 0x00000000, 0x00000000, STATUS_SUCCESS }, 5683 { "A8R8G8B8", D3DDDIFMT_A8R8G8B8, 32, 0x00000000, 0x00000000, 0x00000000, STATUS_SUCCESS }, 5684 { "X8R8G8B8", D3DDDIFMT_X8R8G8B8, 32, 0x00000000, 0x00000000, 0x00000000, STATUS_SUCCESS }, 5685 { "R5G6B5", D3DDDIFMT_R5G6B5, 16, 0x0000f800, 0x000007e0, 0x0000001f, STATUS_SUCCESS }, 5686 { "X1R5G5B5", D3DDDIFMT_X1R5G5B5, 16, 0x00007c00, 0x000003e0, 0x0000001f, STATUS_SUCCESS }, 5687 { "A1R5G5B5", D3DDDIFMT_A1R5G5B5, 16, 0x00007c00, 0x000003e0, 0x0000001f, STATUS_SUCCESS }, 5688 { "R3G3B2", D3DDDIFMT_R3G3B2, 8, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER }, 5689 { "A2B10G10R10", D3DDDIFMT_A2B10G10R10, 32, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER }, 5690 { "A8B8G8R8", D3DDDIFMT_A8B8G8R8, 32, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER }, 5691 { "X8B8G8R8", D3DDDIFMT_A8B8G8R8, 32, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER }, 5692 { "A2R10G10B10", D3DDDIFMT_A2R10G10B10, 32, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER }, 5693 { "P8", D3DDDIFMT_P8, 8, 0x00000000, 0x00000000, 0x00000000, STATUS_SUCCESS }, 5694 { "L8", D3DDDIFMT_L8, 8, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER }, 5695 { "A8L8", D3DDDIFMT_A8L8, 16, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER }, 5696 { "V8U8", D3DDDIFMT_V8U8, 16, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER }, 5697 { "Q8W8V8U8", D3DDDIFMT_Q8W8V8U8, 32, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER }, 5698 { "DXT1", D3DDDIFMT_DXT1, 4, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER }, 5699 { "DXT2", D3DDDIFMT_DXT2, 8, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER }, 5700 { "DXT3", D3DDDIFMT_DXT3, 8, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER }, 5701 { "DXT4", D3DDDIFMT_DXT4, 8, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER }, 5702 { "DXT5", D3DDDIFMT_DXT5, 8, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER }, 5703 }; 5704 5705 if (!pD3DKMTCreateDCFromMemory) 5706 { 5707 win_skip("D3DKMTCreateDCFromMemory() is not implemented.\n"); 5708 return; 5709 } 5710 5711 status = pD3DKMTCreateDCFromMemory( NULL ); 5712 ok(status == STATUS_INVALID_PARAMETER, "Got unexpected status %#x.\n", status); 5713 5714 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i) 5715 { 5716 memset( data, 0xaa, sizeof(data) ); 5717 5718 create_desc.pMemory = data; 5719 create_desc.Format = test_data[i].format; 5720 create_desc.Width = 9; 5721 create_desc.Height = 7; 5722 create_desc.Pitch = sizeof(*data); 5723 create_desc.hDeviceDc = NULL; 5724 create_desc.pColorTable = NULL; 5725 create_desc.hDc = (void *)0x010baade; 5726 create_desc.hBitmap = (void *)0x020baade; 5727 5728 status = pD3DKMTCreateDCFromMemory( &create_desc ); 5729 ok(status == STATUS_INVALID_PARAMETER, "%s: Got unexpected status %#x.\n", 5730 test_data[i].name, status); 5731 5732 create_desc.hDeviceDc = CreateCompatibleDC( NULL ); 5733 create_desc.pMemory = NULL; 5734 status = pD3DKMTCreateDCFromMemory( &create_desc ); 5735 ok(status == STATUS_INVALID_PARAMETER, "%s: Got unexpected status %#x.\n", 5736 test_data[i].name, status); 5737 5738 create_desc.pMemory = data; 5739 create_desc.Height = 0; 5740 status = pD3DKMTCreateDCFromMemory( &create_desc ); 5741 ok(status == STATUS_INVALID_PARAMETER, "%s: Got unexpected status %#x.\n", 5742 test_data[i].name, status); 5743 ok(create_desc.hDc == (void *)0x010baade, "%s: Got unexpected dc %p.\n", 5744 test_data[i].name, create_desc.hDc); 5745 ok(create_desc.hBitmap == (void *)0x020baade, "%s: Got unexpected bitmap %p.\n", 5746 test_data[i].name, create_desc.hBitmap); 5747 5748 create_desc.Height = 7; 5749 create_desc.Width = 0; 5750 status = pD3DKMTCreateDCFromMemory( &create_desc ); 5751 ok(status == test_data[i].status, "%s: Got unexpected status %#x, expected %#x.\n", 5752 test_data[i].name, status, test_data[i].status); 5753 if (status == STATUS_SUCCESS) 5754 { 5755 destroy_desc.hDc = create_desc.hDc; 5756 destroy_desc.hBitmap = create_desc.hBitmap; 5757 status = pD3DKMTDestroyDCFromMemory( &destroy_desc ); 5758 ok(status == STATUS_SUCCESS, "%s: Got unexpected status %#x.\n", test_data[i].name, status); 5759 create_desc.hDc = (void *)0x010baade; 5760 create_desc.hBitmap = (void *)0x020baade; 5761 } 5762 5763 create_desc.Pitch = 0; 5764 status = pD3DKMTCreateDCFromMemory( &create_desc ); 5765 ok(status == STATUS_INVALID_PARAMETER, "%s: Got unexpected status %#x.\n", 5766 test_data[i].name, status); 5767 ok(create_desc.hDc == (void *)0x010baade, "%s: Got unexpected dc %p.\n", 5768 test_data[i].name, create_desc.hDc); 5769 ok(create_desc.hBitmap == (void *)0x020baade, "%s: Got unexpected bitmap %p.\n", 5770 test_data[i].name, create_desc.hBitmap); 5771 5772 create_desc.Width = 9; 5773 create_desc.Pitch = sizeof(*data); 5774 status = pD3DKMTCreateDCFromMemory( &create_desc ); 5775 ok(status == test_data[i].status, "%s: Got unexpected status %#x, expected %#x.\n", 5776 test_data[i].name, status, test_data[i].status); 5777 if (status == STATUS_SUCCESS) 5778 { 5779 ok(!!create_desc.hDc, "%s: Got unexpected dc %p.\n", 5780 test_data[i].name, create_desc.hDc); 5781 ok(!!create_desc.hBitmap, "%s: Got unexpected bitmap %p.\n", 5782 test_data[i].name, create_desc.hBitmap); 5783 } 5784 else 5785 { 5786 ok(create_desc.hDc == (void *)0x010baade, "%s: Got unexpected dc %p.\n", 5787 test_data[i].name, create_desc.hDc); 5788 ok(create_desc.hBitmap == (void *)0x020baade, "%s: Got unexpected bitmap %p.\n", 5789 test_data[i].name, create_desc.hBitmap); 5790 continue; 5791 } 5792 5793 type = GetObjectType( create_desc.hDc ); 5794 ok(type == OBJ_MEMDC, "%s: Got unexpected object type %#x.\n", test_data[i].name, type); 5795 type = GetObjectType( create_desc.hBitmap ); 5796 ok(type == OBJ_BITMAP, "%s: Got unexpected object type %#x.\n", test_data[i].name, type); 5797 bitmap = GetCurrentObject( create_desc.hDc, OBJ_BITMAP ); 5798 ok(bitmap == create_desc.hBitmap, "%s: Got unexpected bitmap %p, expected %p.\n", 5799 test_data[i].name, bitmap, create_desc.hBitmap); 5800 5801 size = GetObjectA( bitmap, sizeof(dib), &dib ); 5802 ok(size == sizeof(dib), "%s: Got unexpected size %d.\n", test_data[i].name, size); 5803 ok(!dib.dsBm.bmType, "%s: Got unexpected type %#x.\n", 5804 test_data[i].name, dib.dsBm.bmType); 5805 ok(dib.dsBm.bmWidth == create_desc.Width, "%s: Got unexpected width %d.\n", 5806 test_data[i].name, dib.dsBm.bmWidth); 5807 ok(dib.dsBm.bmHeight == create_desc.Height, "%s: Got unexpected height %d.\n", 5808 test_data[i].name, dib.dsBm.bmHeight); 5809 width_bytes = get_dib_stride( create_desc.Width, test_data[i].bit_count ); 5810 ok(dib.dsBm.bmWidthBytes == width_bytes, "%s: Got unexpected width bytes %d.\n", 5811 test_data[i].name, dib.dsBm.bmWidthBytes); 5812 ok(dib.dsBm.bmPlanes == 1, "%s: Got unexpected plane count %d.\n", 5813 test_data[i].name, dib.dsBm.bmPlanes); 5814 ok(dib.dsBm.bmBitsPixel == test_data[i].bit_count, "%s: Got unexpected bit count %d.\n", 5815 test_data[i].name, dib.dsBm.bmBitsPixel); 5816 ok(dib.dsBm.bmBits == create_desc.pMemory, "%s: Got unexpected bits %p, expected %p.\n", 5817 test_data[i].name, dib.dsBm.bmBits, create_desc.pMemory); 5818 5819 ok(dib.dsBmih.biSize == sizeof(dib.dsBmih), "%s: Got unexpected size %u.\n", 5820 test_data[i].name, dib.dsBmih.biSize); 5821 ok(dib.dsBmih.biWidth == create_desc.Width, "%s: Got unexpected width %d.\n", 5822 test_data[i].name, dib.dsBmih.biHeight); 5823 ok(dib.dsBmih.biHeight == create_desc.Height, "%s: Got unexpected height %d.\n", 5824 test_data[i].name, dib.dsBmih.biHeight); 5825 ok(dib.dsBmih.biPlanes == 1, "%s: Got unexpected plane count %u.\n", 5826 test_data[i].name, dib.dsBmih.biPlanes); 5827 ok(dib.dsBmih.biBitCount == test_data[i].bit_count, "%s: Got unexpected bit count %u.\n", 5828 test_data[i].name, dib.dsBmih.biBitCount); 5829 ok(dib.dsBmih.biCompression == (test_data[i].bit_count == 16 ? BI_BITFIELDS : BI_RGB), 5830 "%s: Got unexpected compression %#x.\n", 5831 test_data[i].name, dib.dsBmih.biCompression); 5832 ok(!dib.dsBmih.biSizeImage, "%s: Got unexpected image size %u.\n", 5833 test_data[i].name, dib.dsBmih.biSizeImage); 5834 ok(!dib.dsBmih.biXPelsPerMeter, "%s: Got unexpected horizontal resolution %d.\n", 5835 test_data[i].name, dib.dsBmih.biXPelsPerMeter); 5836 ok(!dib.dsBmih.biYPelsPerMeter, "%s: Got unexpected vertical resolution %d.\n", 5837 test_data[i].name, dib.dsBmih.biYPelsPerMeter); 5838 if (test_data[i].format == D3DDDIFMT_P8) 5839 { 5840 ok(dib.dsBmih.biClrUsed == 256, "%s: Got unexpected used colour count %u.\n", 5841 test_data[i].name, dib.dsBmih.biClrUsed); 5842 ok(dib.dsBmih.biClrImportant == 256, "%s: Got unexpected important colour count %u.\n", 5843 test_data[i].name, dib.dsBmih.biClrImportant); 5844 } 5845 else 5846 { 5847 ok(!dib.dsBmih.biClrUsed, "%s: Got unexpected used colour count %u.\n", 5848 test_data[i].name, dib.dsBmih.biClrUsed); 5849 ok(!dib.dsBmih.biClrImportant, "%s: Got unexpected important colour count %u.\n", 5850 test_data[i].name, dib.dsBmih.biClrImportant); 5851 } 5852 5853 ok(dib.dsBitfields[0] == test_data[i].mask_r && dib.dsBitfields[1] == test_data[i].mask_g 5854 && dib.dsBitfields[2] == test_data[i].mask_b, 5855 "%s: Got unexpected colour masks 0x%08x 0x%08x 0x%08x.\n", 5856 test_data[i].name, dib.dsBitfields[0], dib.dsBitfields[1], dib.dsBitfields[2]); 5857 ok(!dib.dshSection, "%s: Got unexpected section %p.\n", test_data[i].name, dib.dshSection); 5858 ok(!dib.dsOffset, "%s: Got unexpected offset %u.\n", test_data[i].name, dib.dsOffset); 5859 5860 ret = BitBlt( create_desc.hDc, 0, 0, 4, 10, NULL, 0, 0, BLACKNESS ); 5861 ok(ret, "Failed to blit.\n"); 5862 ret = BitBlt( create_desc.hDc, 1, 1, 2, 2, NULL, 0, 0, WHITENESS ); 5863 ok(ret, "Failed to blit.\n"); 5864 5865 /* Also test blitting to a regular bitmap */ 5866 bmp_dc = CreateCompatibleDC( create_desc.hDeviceDc ); 5867 ok(bmp_dc != NULL, "failed to create DC\n"); 5868 bmp = CreateCompatibleBitmap( bmp_dc, create_desc.Width, create_desc.Height ); 5869 ok(bmp != NULL, "failed to create bmp\n"); 5870 bmp = SelectObject( bmp_dc, bmp ); 5871 ret = BitBlt( bmp_dc, 0, 0, create_desc.Width, create_desc.Height, create_desc.hDc, 0, 0, SRCCOPY ); 5872 ok(ret, "Failed to blit.\n"); 5873 5874 destroy_desc.hDc = create_desc.hDc; 5875 destroy_desc.hBitmap = create_desc.hBitmap; 5876 5877 status = pD3DKMTDestroyDCFromMemory( NULL ); 5878 ok(status == STATUS_INVALID_PARAMETER, "%s: Got unexpected status %#x.\n", test_data[i].name, status); 5879 status = pD3DKMTDestroyDCFromMemory( &destroy_desc ); 5880 ok(status == STATUS_SUCCESS, "%s: Got unexpected status %#x.\n", test_data[i].name, status); 5881 status = pD3DKMTDestroyDCFromMemory( &destroy_desc ); 5882 ok(status == STATUS_INVALID_PARAMETER, "%s: Got unexpected status %#x.\n", test_data[i].name, status); 5883 5884 ret = DeleteDC( create_desc.hDeviceDc ); 5885 ok(ret, "Failed to delete dc.\n"); 5886 5887 for (y = 0, fail = FALSE; y < 12 && !fail; ++y) 5888 { 5889 for (x = 0; x < sizeof(*data) / (test_data[i].bit_count / 8) && !fail; ++x) 5890 { 5891 for (z = 0, colour = 0; z < test_data[i].bit_count / 8; ++z) 5892 { 5893 colour = colour << 8 | data[y][x * (test_data[i].bit_count / 8) + z]; 5894 } 5895 5896 if ((x == 1 || x == 2) && (y == 1 || y == 2)) 5897 expected = 0xffffffff >> (32 - test_data[i].bit_count); 5898 else if (x < 4 && y < 7) 5899 expected = 0x00000000; 5900 else 5901 expected = 0xaaaaaaaa >> (32 - test_data[i].bit_count); 5902 ok(colour == expected, "%s: Got unexpected colour 0x%08x at %u, %u, expected 0x%08x.\n", 5903 test_data[i].name, colour, x, y, expected); 5904 if (colour != expected) 5905 fail = TRUE; 5906 5907 /* 'Xn' or 'An' formats don't successfully blit to the regular bmp */ 5908 if (test_data[i].format == D3DDDIFMT_R8G8B8 || test_data[i].format == D3DDDIFMT_R5G6B5) 5909 { 5910 pixel = GetPixel( bmp_dc, x, y ); 5911 if ((x == 1 || x == 2) && (y == 1 || y == 2)) 5912 expected = 0x00ffffff; 5913 else if (x < create_desc.Width && y < create_desc.Height) 5914 expected = 0x00000000; 5915 else 5916 expected = CLR_INVALID; 5917 ok(pixel == expected, "%s: got 0x%08x at %u, %u, expect 0x%08x\n", test_data[i].name, 5918 pixel, x, y, expected); 5919 } 5920 } 5921 } 5922 5923 DeleteObject( SelectObject( bmp_dc, bmp ) ); 5924 DeleteDC( bmp_dc ); 5925 } 5926 } 5927 #endif /* __REACTOS__ */ 5928 5929 START_TEST(bitmap) 5930 { 5931 HMODULE hdll; 5932 5933 hdll = GetModuleHandleA("gdi32.dll"); 5934 #ifndef __REACTOS__ /* CORE-11331 */ 5935 pD3DKMTCreateDCFromMemory = (void *)GetProcAddress( hdll, "D3DKMTCreateDCFromMemory" ); 5936 pD3DKMTDestroyDCFromMemory = (void *)GetProcAddress( hdll, "D3DKMTDestroyDCFromMemory" ); 5937 #endif 5938 pGdiAlphaBlend = (void *)GetProcAddress( hdll, "GdiAlphaBlend" ); 5939 pGdiGradientFill = (void *)GetProcAddress( hdll, "GdiGradientFill" ); 5940 pSetLayout = (void *)GetProcAddress( hdll, "SetLayout" ); 5941 5942 test_createdibitmap(); 5943 test_dibsections(); 5944 test_dib_formats(); 5945 test_mono_dibsection(); 5946 test_bitmap(); 5947 test_mono_bitmap(); 5948 test_bmBits(); 5949 test_GetDIBits_selected_DIB(1); 5950 test_GetDIBits_selected_DIB(4); 5951 test_GetDIBits_selected_DIB(8); 5952 test_GetDIBits_selected_DDB(TRUE); 5953 test_GetDIBits_selected_DDB(FALSE); 5954 test_GetDIBits(); 5955 test_GetDIBits_BI_BITFIELDS(); 5956 test_select_object(); 5957 test_CreateBitmap(); 5958 test_BitBlt(); 5959 test_StretchBlt(); 5960 test_StretchDIBits(); 5961 test_GdiAlphaBlend(); 5962 test_GdiGradientFill(); 5963 test_32bit_ddb(); 5964 test_bitmapinfoheadersize(); 5965 test_get16dibits(); 5966 test_clipping(); 5967 test_GetDIBits_top_down(16); 5968 test_GetDIBits_top_down(24); 5969 test_GetDIBits_top_down(32); 5970 test_GetSetDIBits_rtl(); 5971 test_GetDIBits_scanlines(); 5972 test_SetDIBits(); 5973 test_SetDIBits_RLE4(); 5974 test_SetDIBits_RLE8(); 5975 test_SetDIBitsToDevice(); 5976 test_SetDIBitsToDevice_RLE8(); 5977 #ifndef __REACTOS__ /* CORE-11331 */ 5978 test_D3DKMTCreateDCFromMemory(); 5979 #endif 5980 } 5981