ReactOS  r76032
bitmap.c
Go to the documentation of this file.
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 <stdarg.h>
23 #include <assert.h>
24 #include <string.h>
25 
26 #include "ntstatus.h"
27 #define WIN32_NO_STATUS
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winerror.h"
31 #include "wingdi.h"
32 #include "winuser.h"
33 #include "mmsystem.h"
34 #include "wine/winternl.h"
35 #ifndef __REACTOS__ /* CORE-11331 */
36 #include "wine/ddk/d3dkmthk.h"
37 #endif
38 
39 #include "wine/test.h"
40 
41 #ifndef __REACTOS__ /* CORE-11331 */
42 static NTSTATUS (WINAPI *pD3DKMTCreateDCFromMemory)( D3DKMT_CREATEDCFROMMEMORY *desc );
43 static NTSTATUS (WINAPI *pD3DKMTDestroyDCFromMemory)( const D3DKMT_DESTROYDCFROMMEMORY *desc );
44 #endif
45 static BOOL (WINAPI *pGdiAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION);
46 static BOOL (WINAPI *pGdiGradientFill)(HDC,TRIVERTEX*,ULONG,void*,ULONG,ULONG);
47 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
48 
49 static inline int get_bitmap_stride( int width, int bpp )
50 {
51  return ((width * bpp + 15) >> 3) & ~1;
52 }
53 
54 static inline int get_dib_stride( int width, int bpp )
55 {
56  return ((width * bpp + 31) >> 3) & ~3;
57 }
58 
59 static inline int get_dib_image_size( const BITMAPINFO *info )
60 {
61  return get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount )
62  * abs( info->bmiHeader.biHeight );
63 }
64 
65 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
66 {
67  BITMAP bm;
68  BITMAP bma[2];
69  INT ret, width_bytes, i;
70  BYTE buf[512], buf_cmp[512];
71  INT test_size[] = {0 /*first value will be changed */, 0, -1, -1000, ~0, sizeof(buf)};
72 
73  ret = GetObjectW(hbm, sizeof(bm), &bm);
74  ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
75 
76  ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
77  ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
78  ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
79  width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
80  ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
81  ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
82  ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
83  ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
84 
85  assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
86  assert(sizeof(buf) == sizeof(buf_cmp));
87 
88  SetLastError(0xdeadbeef);
89  test_size[0] = bm.bmWidthBytes * bm.bmHeight;
90  /* NULL output buffer with different count values */
91  for (i = 0; i < sizeof(test_size) / sizeof(test_size[0]); i++)
92  {
93  ret = GetBitmapBits(hbm, test_size[i], NULL);
94  ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
95  }
96 
97  memset(buf_cmp, 0xAA, sizeof(buf_cmp));
98  memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
99 
100  /* Correct output buffer with different count values */
101  for (i = 0; i < sizeof(test_size) / sizeof(test_size[0]); i++)
102  {
103  int expect = i == 1 ? 0 : bm.bmWidthBytes * bm.bmHeight;
104  memset(buf, 0xAA, sizeof(buf));
105  ret = GetBitmapBits(hbm, test_size[i], buf);
106  ok(ret == expect, "Test[%d]: %d != %d\n", i, ret, expect);
107  if (expect)
108  ok(!memcmp(buf, buf_cmp, sizeof(buf)),
109  "Test[%d]: buffers do not match, depth %d\n", i, bmih->biBitCount);
110  }
111 
112  /* test various buffer sizes for GetObject */
113  ret = GetObjectW(hbm, sizeof(*bma) * 2, bma);
114  ok(ret == sizeof(*bma), "wrong size %d\n", ret);
115 
116  ret = GetObjectW(hbm, sizeof(bm) / 2, &bm);
117  ok(ret == 0, "%d != 0\n", ret);
118 
119  ret = GetObjectW(hbm, 0, &bm);
120  ok(ret == 0, "%d != 0\n", ret);
121 
122  ret = GetObjectW(hbm, 1, &bm);
123  ok(ret == 0, "%d != 0\n", ret);
124 
125  ret = GetObjectW(hbm, 0, NULL);
126  ok(ret == sizeof(bm), "wrong size %d\n", ret);
127 }
128 
129 static void test_createdibitmap(void)
130 {
131  HDC hdc, hdcmem;
132  BITMAPINFOHEADER bmih;
133  BITMAPINFO bm;
134  HBITMAP hbm, hbm_colour, hbm_old;
135  INT screen_depth;
136  DWORD pixel;
137 
138  hdc = GetDC(0);
139  screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
140  memset(&bmih, 0, sizeof(bmih));
141  bmih.biSize = sizeof(bmih);
142  bmih.biWidth = 10;
143  bmih.biHeight = 10;
144  bmih.biPlanes = 1;
145  bmih.biBitCount = 32;
146  bmih.biCompression = BI_RGB;
147 
148  hbm = CreateDIBitmap(hdc, NULL, CBM_INIT, NULL, NULL, 0);
149  ok(hbm == NULL, "CreateDIBitmap should fail\n");
150  hbm = CreateDIBitmap(hdc, NULL, 0, NULL, NULL, 0);
151  ok(hbm == NULL, "CreateDIBitmap should fail\n");
152 
153  /* First create an un-initialised bitmap. The depth of the bitmap
154  should match that of the hdc and not that supplied in bmih.
155  */
156 
157  /* First try 32 bits */
158  hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
159  ok(hbm != NULL, "CreateDIBitmap failed\n");
160  test_bitmap_info(hbm, screen_depth, &bmih);
161  DeleteObject(hbm);
162 
163  /* Then 16 */
164  bmih.biBitCount = 16;
165  hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
166  ok(hbm != NULL, "CreateDIBitmap failed\n");
167  test_bitmap_info(hbm, screen_depth, &bmih);
168  DeleteObject(hbm);
169 
170  /* Then 1 */
171  bmih.biBitCount = 1;
172  hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
173  ok(hbm != NULL, "CreateDIBitmap failed\n");
174  test_bitmap_info(hbm, screen_depth, &bmih);
175  DeleteObject(hbm);
176 
177  /* Now with a monochrome dc we expect a monochrome bitmap */
178  hdcmem = CreateCompatibleDC(hdc);
179 
180  /* First try 32 bits */
181  bmih.biBitCount = 32;
182  hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
183  ok(hbm != NULL, "CreateDIBitmap failed\n");
184  test_bitmap_info(hbm, 1, &bmih);
185  DeleteObject(hbm);
186 
187  /* Then 16 */
188  bmih.biBitCount = 16;
189  hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
190  ok(hbm != NULL, "CreateDIBitmap failed\n");
191  test_bitmap_info(hbm, 1, &bmih);
192  DeleteObject(hbm);
193 
194  /* Then 1 */
195  bmih.biBitCount = 1;
196  hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
197  ok(hbm != NULL, "CreateDIBitmap failed\n");
198  test_bitmap_info(hbm, 1, &bmih);
199  DeleteObject(hbm);
200 
201  /* Now select a polychrome bitmap into the dc and we expect
202  screen_depth bitmaps again */
203  hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight);
204  test_bitmap_info(hbm_colour, screen_depth, &bmih);
205  hbm_old = SelectObject(hdcmem, hbm_colour);
206 
207  /* First try 32 bits */
208  bmih.biBitCount = 32;
209  hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
210  ok(hbm != NULL, "CreateDIBitmap failed\n");
211  test_bitmap_info(hbm, screen_depth, &bmih);
212  DeleteObject(hbm);
213 
214  /* Then 16 */
215  bmih.biBitCount = 16;
216  hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
217  ok(hbm != NULL, "CreateDIBitmap failed\n");
218  test_bitmap_info(hbm, screen_depth, &bmih);
219  DeleteObject(hbm);
220 
221  /* Then 1 */
222  bmih.biBitCount = 1;
223  hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
224  ok(hbm != NULL, "CreateDIBitmap failed\n");
225  test_bitmap_info(hbm, screen_depth, &bmih);
226  DeleteObject(hbm);
227 
228  SelectObject(hdcmem, hbm_old);
229  DeleteObject(hbm_colour);
230  DeleteDC(hdcmem);
231 
232  bmih.biBitCount = 32;
233  hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
234  ok(hbm != NULL, "CreateDIBitmap failed\n");
235  test_bitmap_info(hbm, 1, &bmih);
236  DeleteObject(hbm);
237 
238  /* Test how formats are converted */
239  pixel = 0xffffffff;
240  bmih.biBitCount = 1;
241  bmih.biWidth = 1;
242  bmih.biHeight = 1;
243 
244  memset(&bm, 0, sizeof(bm));
245  bm.bmiHeader.biSize = sizeof(bm.bmiHeader);
246  bm.bmiHeader.biWidth = 1;
247  bm.bmiHeader.biHeight = 1;
248  bm.bmiHeader.biPlanes = 1;
249  bm.bmiHeader.biBitCount= 24;
251  bm.bmiHeader.biSizeImage = 0;
252  hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS);
253  ok(hbm != NULL, "CreateDIBitmap failed\n");
254 
255  pixel = 0xdeadbeef;
256  bm.bmiHeader.biBitCount= 32;
257  GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS);
258  ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel);
259  DeleteObject(hbm);
260 
261  ReleaseDC(0, hdc);
262 }
263 
264 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
265 {
266  BITMAP bm;
267  BITMAP bma[2];
268  DIBSECTION ds;
269  DIBSECTION dsa[2];
270  INT ret, bm_width_bytes, dib_width_bytes;
271  BYTE *buf;
272 
273  ret = GetObjectW(hbm, sizeof(bm), &bm);
274  ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
275 
276  ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
277  ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
278  ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
279  dib_width_bytes = get_dib_stride(bm.bmWidth, bm.bmBitsPixel);
280  bm_width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
281  if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
282  ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
283  else
284  ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
285  ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
286  ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
287  ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
288 
289  buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
290 
291  /* GetBitmapBits returns not 32-bit aligned data */
292  SetLastError(0xdeadbeef);
293  ret = GetBitmapBits(hbm, 0, NULL);
294  ok(ret == bm_width_bytes * bm.bmHeight,
295  "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
296 
297  memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
298  ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
299  ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
300 
301  HeapFree(GetProcessHeap(), 0, buf);
302 
303  /* test various buffer sizes for GetObject */
304  memset(&ds, 0xAA, sizeof(ds));
305  ret = GetObjectW(hbm, sizeof(*bma) * 2, bma);
306  ok(ret == sizeof(*bma), "wrong size %d\n", ret);
307  ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
308  ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
309  ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
310 
311  ret = GetObjectW(hbm, sizeof(bm) / 2, &bm);
312  ok(ret == 0, "%d != 0\n", ret);
313 
314  ret = GetObjectW(hbm, 0, &bm);
315  ok(ret == 0, "%d != 0\n", ret);
316 
317  ret = GetObjectW(hbm, 1, &bm);
318  ok(ret == 0, "%d != 0\n", ret);
319 
320  /* test various buffer sizes for GetObject */
321  ret = GetObjectW(hbm, 0, NULL);
322  ok(ret == sizeof(bm), "wrong size %d\n", ret);
323 
324  ret = GetObjectW(hbm, sizeof(*dsa) * 2, dsa);
325  ok(ret == sizeof(*dsa), "wrong size %d\n", ret);
326 
327  memset(&ds, 0xAA, sizeof(ds));
328  ret = GetObjectW(hbm, sizeof(ds), &ds);
329  ok(ret == sizeof(ds), "wrong size %d\n", ret);
330 
331  ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
332  if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
333  ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
334  ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
335  ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
336  ds.dsBmih.biSizeImage = 0;
337 
338  ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
339  ok(ds.dsBmih.biWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
340  ok(ds.dsBmih.biHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
341  ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
342  ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
343  ok(ds.dsBmih.biCompression == bmih->biCompression ||
344  ((bmih->biBitCount == 32) && broken(ds.dsBmih.biCompression == BI_BITFIELDS)), /* nt4 sp1 and 2 */
345  "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
346  ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
347  ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%d != %d\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
348  ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%d != %d\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
349 
350  memset(&ds, 0xAA, sizeof(ds));
351  ret = GetObjectW(hbm, sizeof(ds) - 4, &ds);
352  ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
353  ok(ds.dsBm.bmWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
354  ok(ds.dsBm.bmHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
355  ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
356 
357  ret = GetObjectW(hbm, 0, &ds);
358  ok(ret == 0, "%d != 0\n", ret);
359 
360  ret = GetObjectW(hbm, 1, &ds);
361  ok(ret == 0, "%d != 0\n", ret);
362 }
363 
365 {
366  COLORREF c;
367  c = SetPixel(hdc, 0, 0, color);
368  ok_(__FILE__, line)(c == exp, "SetPixel failed: got 0x%06x expected 0x%06x\n", c, exp);
369  c = GetPixel(hdc, 0, 0);
370  ok_(__FILE__, line)(c == exp, "GetPixel failed: got 0x%06x expected 0x%06x\n", c, exp);
371  c = GetNearestColor(hdc, color);
372  ok_(__FILE__, line)(c == exp, "GetNearestColor failed: got 0x%06x expected 0x%06x\n", c, exp);
373 }
374 #define test_color(hdc, color, exp) _test_color( __LINE__, hdc, color, exp )
375 
376 
377 static void test_dib_bits_access( HBITMAP hdib, void *bits )
378 {
380  char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
381  DWORD data[256];
382  BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
383  HDC hdc;
384  char filename[MAX_PATH];
385  HANDLE file;
386  DWORD written;
387  INT ret;
388 
389  ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
390  "VirtualQuery failed\n");
391  ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
392  ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
393  ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
394  ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
395  ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
396  ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
397 
398  memset( pbmi, 0, sizeof(bmibuf) );
399  memset( data, 0xcc, sizeof(data) );
400  pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
401  pbmi->bmiHeader.biHeight = 16;
402  pbmi->bmiHeader.biWidth = 16;
403  pbmi->bmiHeader.biBitCount = 32;
404  pbmi->bmiHeader.biPlanes = 1;
406 
407  hdc = GetDC(0);
408 
409  ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
410  ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
411 
412  ReleaseDC(0, hdc);
413 
414  ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
415  "VirtualQuery failed\n");
416  ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
417  ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
418  ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
419  ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
420  ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
421  ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
422 
423  /* try writing protected bits to a file */
424 
425  GetTempFileNameA( ".", "dib", 0, filename );
427  CREATE_ALWAYS, 0, 0 );
428  ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
429  ret = WriteFile( file, bits, 8192, &written, NULL );
430  ok( ret, "WriteFile failed error %u\n", GetLastError() );
431  if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
432  CloseHandle( file );
433  DeleteFileA( filename );
434 }
435 
436 static void test_dibsections(void)
437 {
438  HDC hdc, hdcmem, hdcmem2;
439  HBITMAP hdib, oldbm, hdib2, oldbm2;
440  char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
441  char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
442  BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
443  BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
444  RGBQUAD *colors = pbmi->bmiColors;
445  RGBTRIPLE *ccolors = pbci->bmciColors;
446  HBITMAP hcoredib;
447  char coreBits[256];
448  BYTE *bits;
449  RGBQUAD rgb[256];
450  int ret;
451  char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
452  LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
453  PALETTEENTRY *palent = plogpal->palPalEntry;
454  WORD *index;
455  DWORD *bits32;
456  HPALETTE hpal, oldpal;
457  DIBSECTION dibsec;
458  COLORREF c0, c1;
459  int i;
461 
462  hdc = GetDC(0);
463 
464  memset(pbmi, 0, sizeof(bmibuf));
465  pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
466  pbmi->bmiHeader.biHeight = 100;
467  pbmi->bmiHeader.biWidth = 512;
468  pbmi->bmiHeader.biBitCount = 24;
469  pbmi->bmiHeader.biPlanes = 1;
471 
472  SetLastError(0xdeadbeef);
473 
474  /* invalid pointer for BITMAPINFO
475  (*bits should be NULL on error) */
476  bits = (BYTE*)0xdeadbeef;
477  hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
478  ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
479 
480  hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
481  ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
482  ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
483  ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
484 
485  /* test the DIB memory */
486  ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
487  "VirtualQuery failed\n");
488  ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
489  ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
490  ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
491  ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
492  ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
493  ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
494  ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
495 
496  test_dib_bits_access( hdib, bits );
497 
498  test_dib_info(hdib, bits, &pbmi->bmiHeader);
499  DeleteObject(hdib);
500 
501  /* Test a top-down DIB. */
502  pbmi->bmiHeader.biHeight = -100;
503  hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
504  ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
505  test_dib_info(hdib, bits, &pbmi->bmiHeader);
506  DeleteObject(hdib);
507 
508  pbmi->bmiHeader.biHeight = 100;
509  pbmi->bmiHeader.biBitCount = 8;
511  SetLastError(0xdeadbeef);
512  hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
513  ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
514  ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
515 
516  pbmi->bmiHeader.biBitCount = 16;
518  ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
519  ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
520  ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
521  SetLastError(0xdeadbeef);
522  hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
523  ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
524 
525  /* test the DIB memory */
526  ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
527  "VirtualQuery failed\n");
528  ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
529  ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
530  ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
531  ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
532  ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
533  ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
534  ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
535 
536  test_dib_info(hdib, bits, &pbmi->bmiHeader);
537  DeleteObject(hdib);
538 
539  memset(pbmi, 0, sizeof(bmibuf));
540  pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
541  pbmi->bmiHeader.biHeight = 16;
542  pbmi->bmiHeader.biWidth = 16;
543  pbmi->bmiHeader.biBitCount = 1;
544  pbmi->bmiHeader.biPlanes = 1;
546  colors[0].rgbRed = 0xff;
547  colors[0].rgbGreen = 0;
548  colors[0].rgbBlue = 0;
549  colors[1].rgbRed = 0;
550  colors[1].rgbGreen = 0;
551  colors[1].rgbBlue = 0xff;
552 
553  hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
554  ok(hdib != NULL, "CreateDIBSection failed\n");
555  ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
556  ok(dibsec.dsBmih.biClrUsed == 2,
557  "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
558 
559  /* Test if the old BITMAPCOREINFO structure is supported */
560 
561  pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
562  pbci->bmciHeader.bcBitCount = 0;
563 
564  ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
565  ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
566  ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
567  && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
568  "GetDIBits didn't fill in the BITMAPCOREHEADER structure properly\n");
569 
570  ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
571  ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
572  ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) &&
573  (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) &&
574  (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff),
575  "The color table has not been translated to the old BITMAPCOREINFO format\n");
576 
577  hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
578  ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
579 
580  ZeroMemory(ccolors, 256 * sizeof(RGBTRIPLE));
581  ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
582  ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
583  ok((ccolors[0].rgbtRed == 0xff) && (ccolors[0].rgbtGreen == 0) &&
584  (ccolors[0].rgbtBlue == 0) && (ccolors[1].rgbtRed == 0) &&
585  (ccolors[1].rgbtGreen == 0) && (ccolors[1].rgbtBlue == 0xff),
586  "The color table has not been translated to the old BITMAPCOREINFO format\n");
587 
588  DeleteObject(hcoredib);
589 
590  hdcmem = CreateCompatibleDC(hdc);
591  oldbm = SelectObject(hdcmem, hdib);
592 
593  ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
594  ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
595  ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
596  "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
597  rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
598  rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
599 
600  c0 = RGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue);
601  c1 = RGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue);
602 
603  test_color(hdcmem, DIBINDEX(0), c0);
604  test_color(hdcmem, DIBINDEX(1), c1);
605  test_color(hdcmem, DIBINDEX(2), c0);
606  test_color(hdcmem, PALETTEINDEX(0), c0);
607  test_color(hdcmem, PALETTEINDEX(1), c0);
608  test_color(hdcmem, PALETTEINDEX(2), c0);
609  test_color(hdcmem, PALETTERGB(colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue), c0);
610  test_color(hdcmem, PALETTERGB(colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue), c1);
611  test_color(hdcmem, PALETTERGB(0, 0, 0), c0);
612  test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
613  test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1);
614 
615  SelectObject(hdcmem, oldbm);
616  DeleteObject(hdib);
617 
618  colors[0].rgbRed = 0xff;
619  colors[0].rgbGreen = 0xff;
620  colors[0].rgbBlue = 0xff;
621  colors[1].rgbRed = 0;
622  colors[1].rgbGreen = 0;
623  colors[1].rgbBlue = 0;
624 
625  hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
626  ok(hdib != NULL, "CreateDIBSection failed\n");
627 
628  test_dib_info(hdib, bits, &pbmi->bmiHeader);
629 
630  oldbm = SelectObject(hdcmem, hdib);
631 
632  ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
633  ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
634  ok(!memcmp(rgb, colors, 2 * sizeof(RGBQUAD)),
635  "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
636  rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
637  rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
638 
639  SelectObject(hdcmem, oldbm);
640  test_dib_info(hdib, bits, &pbmi->bmiHeader);
641  DeleteObject(hdib);
642 
643  pbmi->bmiHeader.biBitCount = 4;
644  for (i = 0; i < 16; i++) {
645  colors[i].rgbRed = i;
646  colors[i].rgbGreen = 16-i;
647  colors[i].rgbBlue = 0;
648  }
649  hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
650  ok(hdib != NULL, "CreateDIBSection failed\n");
651  ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
652  ok(dibsec.dsBmih.biClrUsed == 16,
653  "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
654  test_dib_info(hdib, bits, &pbmi->bmiHeader);
655  DeleteObject(hdib);
656 
657  pbmi->bmiHeader.biBitCount = 8;
658 
659  for (i = 0; i < 128; i++) {
660  colors[i].rgbRed = 255 - i * 2;
661  colors[i].rgbGreen = i * 2;
662  colors[i].rgbBlue = 0;
663  colors[255 - i].rgbRed = 0;
664  colors[255 - i].rgbGreen = i * 2;
665  colors[255 - i].rgbBlue = 255 - i * 2;
666  }
667  hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
668  ok(hdib != NULL, "CreateDIBSection failed\n");
669  ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
670  ok(dibsec.dsBmih.biClrUsed == 256,
671  "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
672 
673  oldbm = SelectObject(hdcmem, hdib);
674 
675  for (i = 0; i < 256; i++) {
676  test_color(hdcmem, DIBINDEX(i), RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue));
677  test_color(hdcmem, PALETTERGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue),
678  RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue));
679  }
680 
681  SelectObject(hdcmem, oldbm);
682  test_dib_info(hdib, bits, &pbmi->bmiHeader);
683  DeleteObject(hdib);
684 
685  pbmi->bmiHeader.biBitCount = 1;
686 
687  /* Now create a palette and a palette indexed dib section */
688  memset(plogpal, 0, sizeof(logpalbuf));
689  plogpal->palVersion = 0x300;
690  plogpal->palNumEntries = 2;
691  palent[0].peRed = 0xff;
692  palent[0].peBlue = 0xff;
693  palent[1].peGreen = 0xff;
694 
695  index = (WORD*)pbmi->bmiColors;
696  *index++ = 0;
697  *index = 1;
698  hpal = CreatePalette(plogpal);
699  ok(hpal != NULL, "CreatePalette failed\n");
700  oldpal = SelectPalette(hdc, hpal, TRUE);
701  hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
702  ok(hdib != NULL, "CreateDIBSection failed\n");
703  ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
704  ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
705 
706  /* The colour table has already been grabbed from the dc, so we select back the
707  old palette */
708 
709  SelectPalette(hdc, oldpal, TRUE);
710  oldbm = SelectObject(hdcmem, hdib);
711  oldpal = SelectPalette(hdcmem, hpal, TRUE);
712 
713  ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
714  ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
715  ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
716  rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
717  "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
718  rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
719  rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
720 
721  c0 = RGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue);
722  c1 = RGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue);
723 
724  test_color(hdcmem, DIBINDEX(0), c0);
725  test_color(hdcmem, DIBINDEX(1), c1);
726  test_color(hdcmem, DIBINDEX(2), c0);
727  test_color(hdcmem, PALETTEINDEX(0), c0);
728  test_color(hdcmem, PALETTEINDEX(1), c1);
729  test_color(hdcmem, PALETTEINDEX(2), c0);
730  test_color(hdcmem, PALETTERGB(palent[0].peRed, palent[0].peGreen, palent[0].peBlue), c0);
731  test_color(hdcmem, PALETTERGB(palent[1].peRed, palent[1].peGreen, palent[1].peBlue), c1);
732  test_color(hdcmem, PALETTERGB(0, 0, 0), c1);
733  test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0);
734  test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0);
735  test_color(hdcmem, PALETTERGB(0, 1, 0), c1);
736  test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1);
737  test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0);
738 
739  /* Bottom and 2nd row from top green, everything else magenta */
740  bits[0] = bits[1] = 0xff;
741  bits[13 * 4] = bits[13*4 + 1] = 0xff;
742 
743  test_dib_info(hdib, bits, &pbmi->bmiHeader);
744 
745  pbmi->bmiHeader.biBitCount = 32;
746 
747  hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
748  ok(hdib2 != NULL, "CreateDIBSection failed\n");
749  hdcmem2 = CreateCompatibleDC(hdc);
750  oldbm2 = SelectObject(hdcmem2, hdib2);
751 
752  BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
753 
754  ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
755  ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
756 
757  SelectObject(hdcmem2, oldbm2);
758  test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
759  DeleteObject(hdib2);
760 
761  SelectObject(hdcmem, oldbm);
762  SelectPalette(hdcmem, oldpal, TRUE);
763  DeleteObject(hdib);
764  DeleteObject(hpal);
765 
766 
767  pbmi->bmiHeader.biBitCount = 8;
768 
769  memset(plogpal, 0, sizeof(logpalbuf));
770  plogpal->palVersion = 0x300;
771  plogpal->palNumEntries = 256;
772 
773  for (i = 0; i < 128; i++) {
774  palent[i].peRed = 255 - i * 2;
775  palent[i].peBlue = i * 2;
776  palent[i].peGreen = 0;
777  palent[255 - i].peRed = 0;
778  palent[255 - i].peGreen = i * 2;
779  palent[255 - i].peBlue = 255 - i * 2;
780  }
781 
782  index = (WORD*)pbmi->bmiColors;
783  for (i = 0; i < 256; i++) {
784  *index++ = i;
785  }
786 
787  hpal = CreatePalette(plogpal);
788  ok(hpal != NULL, "CreatePalette failed\n");
789  oldpal = SelectPalette(hdc, hpal, TRUE);
790  hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
791  ok(hdib != NULL, "CreateDIBSection failed\n");
792  ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
793  ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
794 
795  test_dib_info(hdib, bits, &pbmi->bmiHeader);
796 
797  SelectPalette(hdc, oldpal, TRUE);
798  oldbm = SelectObject(hdcmem, hdib);
799  oldpal = SelectPalette(hdcmem, hpal, TRUE);
800 
801  ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
802  ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
803  for (i = 0; i < 256; i++) {
804  ok(rgb[i].rgbRed == palent[i].peRed &&
805  rgb[i].rgbBlue == palent[i].peBlue &&
806  rgb[i].rgbGreen == palent[i].peGreen,
807  "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
808  i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
809  }
810 
811  for (i = 0; i < 256; i++) {
812  test_color(hdcmem, DIBINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
813  test_color(hdcmem, PALETTEINDEX(i), RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
814  test_color(hdcmem, PALETTERGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue),
815  RGB(palent[i].peRed, palent[i].peGreen, palent[i].peBlue));
816  }
817 
818  SelectPalette(hdcmem, oldpal, TRUE);
819  SelectObject(hdcmem, oldbm);
820  DeleteObject(hdib);
821  DeleteObject(hpal);
822 
823  plogpal->palNumEntries = 37;
824  hpal = CreatePalette(plogpal);
825  ok(hpal != NULL, "CreatePalette failed\n");
826  oldpal = SelectPalette(hdc, hpal, TRUE);
827  pbmi->bmiHeader.biClrUsed = 142;
828  hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
829  ok(hdib != NULL, "CreateDIBSection failed\n");
830  ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
831  ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
832 
833  test_dib_info(hdib, bits, &pbmi->bmiHeader);
834 
835  SelectPalette(hdc, oldpal, TRUE);
836  oldbm = SelectObject(hdcmem, hdib);
837 
838  memset( rgb, 0xcc, sizeof(rgb) );
839  ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
840  ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
841  for (i = 0; i < 256; i++)
842  {
843  if (i < pbmi->bmiHeader.biClrUsed)
844  {
845  ok(rgb[i].rgbRed == palent[i % 37].peRed &&
846  rgb[i].rgbBlue == palent[i % 37].peBlue &&
847  rgb[i].rgbGreen == palent[i % 37].peGreen,
848  "GetDIBColorTable returns table %d: r %02x g %02x b %02x res%02x\n",
849  i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
850  test_color(hdcmem, DIBINDEX(i),
851  RGB(palent[i % 37].peRed, palent[i % 37].peGreen, palent[i % 37].peBlue));
852  }
853  else
854  {
855  ok(rgb[i].rgbRed == 0 && rgb[i].rgbBlue == 0 && rgb[i].rgbGreen == 0,
856  "GetDIBColorTable returns table %d: r %02x g %02x b %02x res%02x\n",
857  i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
858  test_color(hdcmem, DIBINDEX(i), 0 );
859  }
860  }
861  pbmi->bmiHeader.biClrUsed = 173;
862  memset( pbmi->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
863  GetDIBits( hdc, hdib, 0, 1, NULL, pbmi, DIB_RGB_COLORS );
864  ok( pbmi->bmiHeader.biClrUsed == 0, "wrong colors %u\n", pbmi->bmiHeader.biClrUsed );
865  for (i = 0; i < 256; i++)
866  {
867  if (i < 142)
868  ok(colors[i].rgbRed == palent[i % 37].peRed &&
869  colors[i].rgbBlue == palent[i % 37].peBlue &&
870  colors[i].rgbGreen == palent[i % 37].peGreen,
871  "GetDIBits returns table %d: r %02x g %02x b %02x res%02x\n",
872  i, colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
873  else
874  ok(colors[i].rgbRed == 0 && colors[i].rgbBlue == 0 && colors[i].rgbGreen == 0,
875  "GetDIBits returns table %d: r %02x g %02x b %02x res%02x\n",
876  i, colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
877  }
878 
879  rgb[0].rgbRed = 1;
880  rgb[0].rgbGreen = 2;
881  rgb[0].rgbBlue = 3;
882  rgb[0].rgbReserved = 123;
883  ret = SetDIBColorTable( hdcmem, 0, 1, rgb );
884  ok( ret == 1, "SetDIBColorTable returned unexpected result %u\n", ret );
885  ok( rgb[0].rgbReserved == 123, "Expected rgbReserved = 123, got %u\n", rgb[0].rgbReserved );
886 
887  rgb[0].rgbRed = rgb[0].rgbGreen = rgb[0].rgbBlue = rgb[0].rgbReserved = -1;
888  ret = GetDIBColorTable( hdcmem, 0, 1, rgb );
889  ok( ret == 1, "GetDIBColorTable returned unexpected result %u\n", ret );
890  ok( rgb[0].rgbRed == 1, "Expected rgbRed = 1, got %u\n", rgb[0].rgbRed );
891  ok( rgb[0].rgbGreen == 2, "Expected rgbGreen = 2, got %u\n", rgb[0].rgbGreen );
892  ok( rgb[0].rgbBlue == 3, "Expected rgbBlue = 3, got %u\n", rgb[0].rgbBlue );
893  ok( rgb[0].rgbReserved == 0, "Expected rgbReserved = 0, got %u\n", rgb[0].rgbReserved );
894 
895  SelectObject(hdcmem, oldbm);
896  DeleteObject(hdib);
897  DeleteObject(hpal);
898 
899  /* ClrUsed ignored on > 8bpp */
900  pbmi->bmiHeader.biBitCount = 16;
901  pbmi->bmiHeader.biClrUsed = 37;
902  hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
903  ok(hdib != NULL, "CreateDIBSection failed\n");
904  ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
905  ok(dibsec.dsBmih.biClrUsed == 0, "created DIBSection: wrong biClrUsed field: %u\n", dibsec.dsBmih.biClrUsed);
906  oldbm = SelectObject(hdcmem, hdib);
907  ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
908  ok(ret == 0, "GetDIBColorTable returned %d\n", ret);
909  SelectObject(hdcmem, oldbm);
910  DeleteObject(hdib);
911 
912  DeleteDC(hdcmem);
913  DeleteDC(hdcmem2);
914  ReleaseDC(0, hdc);
915 }
916 
917 static void test_dib_formats(void)
918 {
919  BITMAPINFO *bi;
920  char data[256];
921  void *bits;
922  int planes, bpp, compr, format;
923  HBITMAP hdib, hbmp;
924  HDC hdc, memdc;
925  UINT ret;
926  BOOL format_ok, expect_ok;
927 
928  bi = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
929  hdc = GetDC( 0 );
930  memdc = CreateCompatibleDC( 0 );
931  hbmp = CreateCompatibleBitmap( hdc, 10, 10 );
932 
933  memset( data, 0xaa, sizeof(data) );
934 
936  skip("ROSTESTS-152: Skipping loop in test_dib_formats because it's too big and causes too many failures\n");
937  else
938  for (bpp = 0; bpp <= 64; bpp++)
939  {
940  for (planes = 0; planes <= 64; planes++)
941  {
942  for (compr = 0; compr < 8; compr++)
943  {
944  for (format = DIB_RGB_COLORS; format <= DIB_PAL_COLORS; format++)
945  {
946  switch (bpp)
947  {
948  case 1:
949  case 4:
950  case 8:
951  case 24: expect_ok = (compr == BI_RGB); break;
952  case 16:
953  case 32: expect_ok = (compr == BI_RGB || compr == BI_BITFIELDS); break;
954  default: expect_ok = FALSE; break;
955  }
956 
957  memset( bi, 0, sizeof(bi->bmiHeader) );
958  bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
959  bi->bmiHeader.biWidth = 2;
960  bi->bmiHeader.biHeight = 2;
961  bi->bmiHeader.biPlanes = planes;
962  bi->bmiHeader.biBitCount = bpp;
964  bi->bmiHeader.biSizeImage = 0;
965  memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
966  ret = GetDIBits(hdc, hbmp, 0, 0, data, bi, format);
967  if (expect_ok || (!bpp && compr != BI_JPEG && compr != BI_PNG) ||
968  (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
969  ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
970  else
971  ok( !ret || broken(!bpp && (compr == BI_JPEG || compr == BI_PNG)), /* nt4 */
972  "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
973 
974  /* all functions check planes except GetDIBits with 0 lines */
975  format_ok = expect_ok;
976  if (!planes) expect_ok = FALSE;
977  memset( bi, 0, sizeof(bi->bmiHeader) );
978  bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
979  bi->bmiHeader.biWidth = 2;
980  bi->bmiHeader.biHeight = 2;
981  bi->bmiHeader.biPlanes = planes;
982  bi->bmiHeader.biBitCount = bpp;
984  bi->bmiHeader.biSizeImage = 0;
985  memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
986 
987  hdib = CreateDIBSection(hdc, bi, format, &bits, NULL, 0);
988  if (expect_ok && (planes == 1 || planes * bpp <= 16) &&
989  (compr != BI_BITFIELDS || format != DIB_PAL_COLORS))
990  ok( hdib != NULL, "CreateDIBSection failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
991  else
992  ok( hdib == NULL, "CreateDIBSection succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
993  if (hdib) DeleteObject( hdib );
994 
995  hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, data, bi, format );
996  /* no sanity checks in CreateDIBitmap except compression */
997  if (compr == BI_JPEG || compr == BI_PNG)
998  ok( hdib == NULL || broken(hdib != NULL), /* nt4 */
999  "CreateDIBitmap succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1000  else
1001  ok( hdib != NULL, "CreateDIBitmap failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1002  if (hdib) DeleteObject( hdib );
1003 
1004  /* RLE needs a size */
1005  bi->bmiHeader.biSizeImage = 0;
1006  ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, format);
1007  if (expect_ok)
1008  ok( ret, "SetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1009  else
1010  ok( !ret ||
1011  broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
1012  "SetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1013  ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, format );
1014  if (expect_ok)
1015  ok( ret, "SetDIBitsToDevice failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1016  else
1017  ok( !ret ||
1018  broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
1019  "SetDIBitsToDevice succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1020  ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, format, SRCCOPY );
1021  if (expect_ok)
1022  ok( ret, "StretchDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1023  else
1024  ok( !ret ||
1025  broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
1026  "StretchDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1027 
1028  ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, format);
1029  if (expect_ok)
1030  ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1031  else
1032  ok( !ret, "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1033  ok( bi->bmiHeader.biBitCount == bpp, "GetDIBits modified bpp %u/%u\n",
1034  bpp, bi->bmiHeader.biBitCount );
1035 
1036  bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1037  bi->bmiHeader.biWidth = 2;
1038  bi->bmiHeader.biHeight = 2;
1039  bi->bmiHeader.biPlanes = planes;
1040  bi->bmiHeader.biBitCount = bpp;
1042  bi->bmiHeader.biSizeImage = 1;
1043  memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
1044  /* RLE allowed with valid biSizeImage */
1045  if ((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)) expect_ok = TRUE;
1046 
1047  ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, format);
1048  if (expect_ok)
1049  ok( ret, "SetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1050  else
1051  ok( !ret, "SetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1052  ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, format );
1053  if (expect_ok)
1054  ok( ret, "SetDIBitsToDevice failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1055  else
1056  ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1057  ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, format, SRCCOPY );
1058  if (expect_ok)
1059  ok( ret, "StretchDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1060  else
1061  ok( !ret, "StretchDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1062 
1063  bi->bmiHeader.biSizeImage = 0;
1064  ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, format);
1065  if (expect_ok || !bpp)
1066  ok( ret, "GetDIBits failed for %u/%u/%u/%u\n", bpp, planes, compr, format );
1067  else
1068  ok( !ret || broken(format_ok && !planes), /* nt4 */
1069  "GetDIBits succeeded for %u/%u/%u/%u\n", bpp, planes, compr, format );
1070  }
1071  }
1072  }
1073  }
1074 
1075  memset( bi, 0, sizeof(bi->bmiHeader) );
1076  bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1077  bi->bmiHeader.biWidth = 2;
1078  bi->bmiHeader.biHeight = 2;
1079  bi->bmiHeader.biPlanes = 1;
1080  bi->bmiHeader.biBitCount = 16;
1082  bi->bmiHeader.biSizeImage = 0;
1083  *(DWORD *)&bi->bmiColors[0] = 0;
1084  *(DWORD *)&bi->bmiColors[1] = 0;
1085  *(DWORD *)&bi->bmiColors[2] = 0;
1086 
1087  hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1088  ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1089  ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1090  ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1091  /* other functions don't check */
1092  hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1093  ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" );
1094  DeleteObject( hdib );
1095  ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1096  ok( ret, "SetDIBitsToDevice failed with null bitfields\n" );
1097  ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1098  ok( ret, "StretchDIBits failed with null bitfields\n" );
1099  ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1100  ok( ret, "GetDIBits failed with null bitfields\n" );
1101  bi->bmiHeader.biPlanes = 1;
1102  bi->bmiHeader.biBitCount = 16;
1104  bi->bmiHeader.biSizeImage = 0;
1105  *(DWORD *)&bi->bmiColors[0] = 0;
1106  *(DWORD *)&bi->bmiColors[1] = 0;
1107  *(DWORD *)&bi->bmiColors[2] = 0;
1108  ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1109  ok( ret, "GetDIBits failed with null bitfields\n" );
1110 
1111  /* all fields must be non-zero */
1112  *(DWORD *)&bi->bmiColors[0] = 3;
1113  *(DWORD *)&bi->bmiColors[1] = 0;
1114  *(DWORD *)&bi->bmiColors[2] = 7;
1115  hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1116  ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1117  ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1118  ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1119 
1120  /* garbage is ok though */
1121  *(DWORD *)&bi->bmiColors[0] = 0x55;
1122  *(DWORD *)&bi->bmiColors[1] = 0x44;
1123  *(DWORD *)&bi->bmiColors[2] = 0x33;
1124  hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1125  ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" );
1126  if (hdib) DeleteObject( hdib );
1127  ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1128  ok( ret, "SetDIBits failed with bad bitfields\n" );
1129 
1130  bi->bmiHeader.biWidth = -2;
1131  bi->bmiHeader.biHeight = 2;
1132  bi->bmiHeader.biBitCount = 32;
1134  hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1135  ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" );
1136  hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1137  ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" );
1138  ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1139  ok( !ret, "SetDIBits succeeded with negative width\n" );
1140  ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1141  ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" );
1142  ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1143  ok( !ret, "StretchDIBits succeeded with negative width\n" );
1144  ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1145  ok( !ret, "GetDIBits succeeded with negative width\n" );
1146  bi->bmiHeader.biWidth = -2;
1147  bi->bmiHeader.biHeight = 2;
1148  bi->bmiHeader.biBitCount = 32;
1150  ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1151  ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with negative width\n" );
1152 
1153  bi->bmiHeader.biWidth = 0;
1154  bi->bmiHeader.biHeight = 2;
1155  bi->bmiHeader.biBitCount = 32;
1157  hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1158  ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" );
1159  hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1160  ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" );
1161  DeleteObject( hdib );
1162  ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1163  ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" );
1164  ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1165  ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" );
1166  ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1167  ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" );
1168  ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1169  ok( !ret, "GetDIBits succeeded with zero width\n" );
1170  bi->bmiHeader.biWidth = 0;
1171  bi->bmiHeader.biHeight = 2;
1172  bi->bmiHeader.biBitCount = 32;
1174  ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1175  ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero width\n" );
1176 
1177  bi->bmiHeader.biWidth = 2;
1178  bi->bmiHeader.biHeight = 0;
1179  bi->bmiHeader.biBitCount = 32;
1181  hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1182  ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" );
1183  hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1184  ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" );
1185  DeleteObject( hdib );
1186  ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1187  ok( !ret, "SetDIBits succeeded with zero height\n" );
1188  ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1189  ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" );
1190  ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1191  ok( !ret, "StretchDIBits succeeded with zero height\n" );
1192  ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1193  ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1194  bi->bmiHeader.biWidth = 2;
1195  bi->bmiHeader.biHeight = 0;
1196  bi->bmiHeader.biBitCount = 32;
1198  ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1199  ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1200 
1201  /* some functions accept DIB_PAL_COLORS+1, but not beyond */
1202 
1203  bi->bmiHeader.biWidth = 2;
1204  bi->bmiHeader.biHeight = 2;
1205  bi->bmiHeader.biBitCount = 1;
1207  hdib = CreateDIBSection(hdc, bi, DIB_PAL_COLORS+1, &bits, NULL, 0);
1208  ok( hdib == NULL, "CreateDIBSection succeeded with DIB_PAL_COLORS+1\n" );
1209  hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_PAL_COLORS+1 );
1210  ok( hdib != NULL, "CreateDIBitmap failed with DIB_PAL_COLORS+1\n" );
1211  DeleteObject( hdib );
1212  ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_PAL_COLORS+1);
1213  ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+1\n" );
1214  ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_PAL_COLORS+1 );
1215  ok( ret, "SetDIBitsToDevice failed with DIB_PAL_COLORS+1\n" );
1216  ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_PAL_COLORS+1, SRCCOPY );
1217  ok( ret, "StretchDIBits failed with DIB_PAL_COLORS+1\n" );
1218  ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_PAL_COLORS+1);
1219  ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+1\n" );
1220  bi->bmiHeader.biWidth = 2;
1221  bi->bmiHeader.biHeight = 2;
1222  bi->bmiHeader.biBitCount = 1;
1224  ret = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS+1);
1225  ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+1\n" );
1226 
1227  bi->bmiHeader.biWidth = 2;
1228  bi->bmiHeader.biHeight = 2;
1229  bi->bmiHeader.biBitCount = 1;
1231  hdib = CreateDIBSection(hdc, bi, DIB_PAL_COLORS+2, &bits, NULL, 0);
1232  ok( hdib == NULL, "CreateDIBSection succeeded with DIB_PAL_COLORS+2\n" );
1233  hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_PAL_COLORS+2 );
1234  ok( hdib == NULL, "CreateDIBitmap succeeded with DIB_PAL_COLORS+2\n" );
1235  DeleteObject( hdib );
1236  ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_PAL_COLORS+2);
1237  ok( !ret, "SetDIBits succeeded with DIB_PAL_COLORS+2\n" );
1238  ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_PAL_COLORS+2 );
1239  ok( !ret, "SetDIBitsToDevice succeeded with DIB_PAL_COLORS+2\n" );
1240  ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_PAL_COLORS+2, SRCCOPY );
1241  ok( !ret, "StretchDIBits succeeded with DIB_PAL_COLORS+2\n" );
1242  ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_PAL_COLORS+2);
1243  ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+2\n" );
1244  bi->bmiHeader.biWidth = 2;
1245  bi->bmiHeader.biHeight = 2;
1246  bi->bmiHeader.biBitCount = 1;
1248  ret = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS+2);
1249  ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+2\n" );
1250 
1251  bi->bmiHeader.biWidth = 0x4000;
1252  bi->bmiHeader.biHeight = 0x4000;
1253  bi->bmiHeader.biBitCount = 1;
1255  hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1256  ok( hdib != NULL, "CreateDIBSection failed with large size\n" );
1257  DeleteObject( hdib );
1258 
1259  bi->bmiHeader.biWidth = 0x8001;
1260  bi->bmiHeader.biHeight = 0x8001;
1261  bi->bmiHeader.biBitCount = 32;
1263  hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1264  ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" );
1265 
1266  bi->bmiHeader.biWidth = 1;
1267  bi->bmiHeader.biHeight = 0x40000001;
1268  bi->bmiHeader.biBitCount = 32;
1270  hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1271  ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" );
1272 
1273  bi->bmiHeader.biWidth = 2;
1274  bi->bmiHeader.biHeight = 0x40000001;
1275  bi->bmiHeader.biBitCount = 16;
1277  hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1278  ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" );
1279 
1280  bi->bmiHeader.biWidth = 0x40000001;
1281  bi->bmiHeader.biHeight = 1;
1282  bi->bmiHeader.biBitCount = 32;
1284  hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1285  ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" );
1286 
1287  bi->bmiHeader.biWidth = 0x40000001;
1288  bi->bmiHeader.biHeight = 4;
1289  bi->bmiHeader.biBitCount = 8;
1291  hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1292  ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" );
1293 
1294  DeleteDC( memdc );
1295  DeleteObject( hbmp );
1296  ReleaseDC( 0, hdc );
1297  HeapFree( GetProcessHeap(), 0, bi );
1298 }
1299 
1300 static void test_mono_dibsection(void)
1301 {
1302  HDC hdc, memdc;
1303  HBITMAP old_bm, mono_ds;
1304  char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1305  BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1306  RGBQUAD *colors = pbmi->bmiColors;
1307  BYTE bits[10 * 4];
1308  BYTE *ds_bits;
1309  int num;
1310 
1311  hdc = GetDC(0);
1312 
1313  memdc = CreateCompatibleDC(hdc);
1314 
1315  memset(pbmi, 0, sizeof(bmibuf));
1316  pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1317  pbmi->bmiHeader.biHeight = 10;
1318  pbmi->bmiHeader.biWidth = 10;
1319  pbmi->bmiHeader.biBitCount = 1;
1320  pbmi->bmiHeader.biPlanes = 1;
1321  pbmi->bmiHeader.biCompression = BI_RGB;
1322  colors[0].rgbRed = 0xff;
1323  colors[0].rgbGreen = 0xff;
1324  colors[0].rgbBlue = 0xff;
1325  colors[1].rgbRed = 0x0;
1326  colors[1].rgbGreen = 0x0;
1327  colors[1].rgbBlue = 0x0;
1328 
1329  /*
1330  * First dib section is 'inverted' ie color[0] is white, color[1] is black
1331  */
1332 
1333  mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1334  ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1335  old_bm = SelectObject(memdc, mono_ds);
1336 
1337  /* black border, white interior */
1338  Rectangle(memdc, 0, 0, 10, 10);
1339  ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1340  ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1341 
1342  /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1343 
1344  memset(bits, 0, sizeof(bits));
1345  bits[0] = 0xaa;
1346 
1347  SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1348  ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1349 
1350  /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1351 
1352  colors[0].rgbRed = 0x0;
1353  colors[0].rgbGreen = 0x0;
1354  colors[0].rgbBlue = 0x0;
1355  colors[1].rgbRed = 0xff;
1356  colors[1].rgbGreen = 0xff;
1357  colors[1].rgbBlue = 0xff;
1358 
1359  SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1360  ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1361 
1362  SelectObject(memdc, old_bm);
1363  DeleteObject(mono_ds);
1364 
1365  /*
1366  * Next dib section is 'normal' ie color[0] is black, color[1] is white
1367  */
1368 
1369  colors[0].rgbRed = 0x0;
1370  colors[0].rgbGreen = 0x0;
1371  colors[0].rgbBlue = 0x0;
1372  colors[1].rgbRed = 0xff;
1373  colors[1].rgbGreen = 0xff;
1374  colors[1].rgbBlue = 0xff;
1375 
1376  mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1377  ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1378  old_bm = SelectObject(memdc, mono_ds);
1379 
1380  /* black border, white interior */
1381  Rectangle(memdc, 0, 0, 10, 10);
1382  ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1383  ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1384 
1385  /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1386 
1387  SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1388  ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1389 
1390  /* SetDIBitsToDevice with an inverted bmi -> normal dib section */
1391 
1392  colors[0].rgbRed = 0xff;
1393  colors[0].rgbGreen = 0xff;
1394  colors[0].rgbBlue = 0xff;
1395  colors[1].rgbRed = 0x0;
1396  colors[1].rgbGreen = 0x0;
1397  colors[1].rgbBlue = 0x0;
1398 
1399  SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1400  ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1401 
1402  /*
1403  * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1404  */
1405 
1406  colors[0].rgbRed = 0xff;
1407  colors[0].rgbGreen = 0xff;
1408  colors[0].rgbBlue = 0xff;
1409  colors[1].rgbRed = 0x0;
1410  colors[1].rgbGreen = 0x0;
1411  colors[1].rgbBlue = 0x0;
1412  num = SetDIBColorTable(memdc, 0, 2, colors);
1413  ok(num == 2, "num = %d\n", num);
1414 
1415  /* black border, white interior */
1416  Rectangle(memdc, 0, 0, 10, 10);
1417  ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1418  ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1419 
1420  /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1421 
1422  memset(bits, 0, sizeof(bits));
1423  bits[0] = 0xaa;
1424 
1425  SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1426  ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1427 
1428  /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1429 
1430  colors[0].rgbRed = 0x0;
1431  colors[0].rgbGreen = 0x0;
1432  colors[0].rgbBlue = 0x0;
1433  colors[1].rgbRed = 0xff;
1434  colors[1].rgbGreen = 0xff;
1435  colors[1].rgbBlue = 0xff;
1436 
1437  SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1438  ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1439 
1440  SelectObject(memdc, old_bm);
1441  DeleteObject(mono_ds);
1442 
1443  /*
1444  * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1445  */
1446 
1447  colors[0].rgbRed = 0xff;
1448  colors[0].rgbGreen = 0x0;
1449  colors[0].rgbBlue = 0x0;
1450  colors[1].rgbRed = 0xfe;
1451  colors[1].rgbGreen = 0x0;
1452  colors[1].rgbBlue = 0x0;
1453 
1454  mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1455  ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1456  old_bm = SelectObject(memdc, mono_ds);
1457 
1458  /* black border, white interior */
1459  Rectangle(memdc, 0, 0, 10, 10);
1460  ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1461  ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1462 
1463  /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1464 
1465  colors[0].rgbRed = 0x0;
1466  colors[0].rgbGreen = 0x0;
1467  colors[0].rgbBlue = 0x0;
1468  colors[1].rgbRed = 0xff;
1469  colors[1].rgbGreen = 0xff;
1470  colors[1].rgbBlue = 0xff;
1471 
1472  SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1473  ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1474 
1475  /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1476 
1477  colors[0].rgbRed = 0xff;
1478  colors[0].rgbGreen = 0xff;
1479  colors[0].rgbBlue = 0xff;
1480  colors[1].rgbRed = 0x0;
1481  colors[1].rgbGreen = 0x0;
1482  colors[1].rgbBlue = 0x0;
1483 
1484  SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1485  ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1486 
1487  SelectObject(memdc, old_bm);
1488  DeleteObject(mono_ds);
1489 
1490  DeleteDC(memdc);
1491  ReleaseDC(0, hdc);
1492 }
1493 
1494 static void test_bitmap(void)
1495 {
1496  char buf[256], buf_cmp[256];
1497  HBITMAP hbmp, hbmp_old;
1498  HDC hdc;
1499  BITMAP bm;
1500  BITMAP bma[2];
1501  INT ret;
1502 
1503  hdc = CreateCompatibleDC(0);
1504  assert(hdc != 0);
1505 
1506  SetLastError(0xdeadbeef);
1507  hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1508  if (!hbmp)
1509  {
1510  ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1511  GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1512  "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1513  }
1514  else
1515  DeleteObject(hbmp);
1516 
1517  SetLastError(0xdeadbeef);
1518  hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1519  if (!hbmp)
1520  {
1521  ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1522  GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1523  "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1524  }
1525  else
1526  DeleteObject(hbmp);
1527 
1528  SetLastError(0xdeadbeef);
1529  hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1530  ok(!hbmp, "CreateBitmap should fail\n");
1531  if (!hbmp)
1533  "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1534  else
1535  DeleteObject(hbmp);
1536 
1537  hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1538  assert(hbmp != NULL);
1539 
1540  ret = GetObjectW(hbmp, sizeof(bm), &bm);
1541  ok(ret == sizeof(bm), "wrong size %d\n", ret);
1542 
1543  ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1544  ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1545  ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1546  ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1547  ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1548  ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1549  ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1550 
1551  assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1552  assert(sizeof(buf) == sizeof(buf_cmp));
1553 
1554  ret = GetBitmapBits(hbmp, 0, NULL);
1555  ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1556 
1557  memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1558  memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1559 
1560  memset(buf, 0xAA, sizeof(buf));
1561  ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1562  ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1563  ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1564 
1565  hbmp_old = SelectObject(hdc, hbmp);
1566 
1567  ret = GetObjectW(hbmp, sizeof(bm), &bm);
1568  ok(ret == sizeof(bm), "wrong size %d\n", ret);
1569 
1570  ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1571  ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1572  ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1573  ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1574  ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1575  ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1576  ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1577 
1578  memset(buf, 0xAA, sizeof(buf));
1579  ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1580  ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1581  ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1582 
1583  hbmp_old = SelectObject(hdc, hbmp_old);
1584  ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1585 
1586  /* test various buffer sizes for GetObject */
1587  ret = GetObjectW(hbmp, sizeof(*bma) * 2, bma);
1588  ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1589 
1590  ret = GetObjectW(hbmp, sizeof(bm) / 2, &bm);
1591  ok(ret == 0, "%d != 0\n", ret);
1592 
1593  ret = GetObjectW(hbmp, 0, &bm);
1594  ok(ret == 0, "%d != 0\n", ret);
1595 
1596  ret = GetObjectW(hbmp, 1, &bm);
1597  ok(ret == 0, "%d != 0\n", ret);
1598 
1599  DeleteObject(hbmp);
1600  DeleteDC(hdc);
1601 }
1602 
1603 static COLORREF get_nearest( int r, int g, int b )
1604 {
1605  return (r*r + g*g + b*b < (255-r)*(255-r) + (255-g)*(255-g) + (255-b)*(255-b)) ? 0x000000 : 0xffffff;
1606 }
1607 
1608 static BOOL is_black_pen( COLORREF fg, COLORREF bg, int r, int g, int b )
1609 {
1610  if (fg == 0 || bg == 0xffffff) return RGB(r,g,b) != 0xffffff && RGB(r,g,b) != bg;
1611  return RGB(r,g,b) == 0x000000 || RGB(r,g,b) == bg;
1612 }
1613 
1614 static void test_bitmap_colors( HDC hdc, COLORREF fg, COLORREF bg, int r, int g, int b )
1615 {
1616  static const WORD pattern_bits[] = { 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa };
1617  char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors ) + 256 * sizeof(RGBQUAD)];
1619  RGBQUAD *colors = info->bmiColors;
1620  WORD bits[16];
1621  void *bits_ptr;
1622  COLORREF res;
1623  HBRUSH old_brush;
1624  HPEN old_pen;
1625  HBITMAP bitmap;
1626  HDC memdc;
1627 
1628  res = SetPixel( hdc, 0, 0, RGB(r,g,b) );
1629  ok( res == get_nearest( r, g, b ),
1630  "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1631  res = GetPixel( hdc, 0, 0 );
1632  ok( res == get_nearest( r, g, b ),
1633  "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1634  res = GetNearestColor( hdc, RGB(r,g,b) );
1635  ok( res == get_nearest( r, g, b ),
1636  "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1637 
1638  /* solid pen */
1639  old_pen = SelectObject( hdc, CreatePen( PS_SOLID, 1, RGB(r,g,b) ));
1640  MoveToEx( hdc, 0, 0, NULL );
1641  LineTo( hdc, 16, 0 );
1642  res = GetPixel( hdc, 0, 0 );
1643  ok( res == (is_black_pen( fg, bg, r, g, b ) ? 0 : 0xffffff),
1644  "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg );
1645  GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1646  ok( bits[0] == (is_black_pen( fg, bg, r, g, b ) ? 0x00 : 0xffff),
1647  "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1648  DeleteObject( SelectObject( hdc, old_pen ));
1649 
1650  /* mono DDB pattern brush */
1651  bitmap = CreateBitmap( 16, 8, 1, 1, pattern_bits );
1652  old_brush = SelectObject( hdc, CreatePatternBrush( bitmap ));
1653  PatBlt( hdc, 0, 0, 16, 16, PATCOPY );
1654  GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1655  ok( bits[0] == 0x5555 || broken(bits[0] == 0xaada) /* XP SP1 & 2003 SP0 */,
1656  "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1657  DeleteObject( SelectObject( hdc, old_brush ));
1658 
1659  /* mono DDB bitmap */
1660  memdc = CreateCompatibleDC( hdc );
1661  SelectObject( memdc, bitmap );
1662  BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1663  GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1664  ok( bits[0] == 0x5555,
1665  "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1666  SetTextColor( memdc, RGB(255,255,255) );
1667  SetBkColor( memdc, RGB(0,0,0) );
1668  BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1669  GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1670  ok( bits[0] == 0x5555,
1671  "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1672 
1673  /* mono DIB section */
1674  memset( buffer, 0, sizeof(buffer) );
1675  info->bmiHeader.biSize = sizeof(info->bmiHeader);
1676  info->bmiHeader.biHeight = -16;
1677  info->bmiHeader.biWidth = 16;
1678  info->bmiHeader.biBitCount = 1;
1679  info->bmiHeader.biPlanes = 1;
1680  info->bmiHeader.biCompression = BI_RGB;
1681  colors[0].rgbRed = 0xff;
1682  colors[0].rgbGreen = 0xff;
1683  colors[0].rgbBlue = 0xf0;
1684  colors[1].rgbRed = 0x20;
1685  colors[1].rgbGreen = 0x0;
1686  colors[1].rgbBlue = 0x0;
1687  bitmap = CreateDIBSection( 0, info, DIB_RGB_COLORS, &bits_ptr, NULL, 0 );
1688  memset( bits_ptr, 0x55, 64 );
1689  DeleteObject( SelectObject( memdc, bitmap ));
1690  BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1691  GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1692  ok( bits[0] == 0x5555,
1693  "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1694 
1695  colors[0].rgbRed = 0x0;
1696  colors[0].rgbGreen = 0x0;
1697  colors[0].rgbBlue = 0x10;
1698  colors[1].rgbRed = 0xff;
1699  colors[1].rgbGreen = 0xf0;
1700  colors[1].rgbBlue = 0xff;
1701  bitmap = CreateDIBSection( 0, info, DIB_RGB_COLORS, &bits_ptr, NULL, 0 );
1702  memset( bits_ptr, 0x55, 64 );
1703  DeleteObject( SelectObject( memdc, bitmap ));
1704  BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1705  GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1706  ok( bits[0] == 0xaaaa,
1707  "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1708 
1709  SetTextColor( memdc, RGB(0,20,0) );
1710  SetBkColor( memdc, RGB(240,240,240) );
1711  BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1712  GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1713  ok( bits[0] == 0x5555,
1714  "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1715 
1716  SetTextColor( memdc, RGB(250,250,250) );
1717  SetBkColor( memdc, RGB(10,10,10) );
1718  BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY );
1719  GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits );
1720  ok( bits[0] == 0xaaaa,
1721  "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
1722  DeleteDC( memdc );
1723  DeleteObject( bitmap );
1724 }
1725 
1726 static void test_mono_bitmap(void)
1727 {
1728  static const COLORREF colors[][2] =
1729  {
1730  { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff) },
1731  { RGB(0xff,0xff,0xff), RGB(0x00,0x00,0x00) },
1732  { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xfe) },
1733  { RGB(0x00,0x01,0x00), RGB(0xff,0xff,0xff) },
1734  { RGB(0x00,0x00,0x00), RGB(0x80,0x80,0x80) },
1735  { RGB(0x80,0x80,0x80), RGB(0xff,0xff,0xff) },
1736  { RGB(0x30,0x40,0x50), RGB(0x60,0x70,0x80) },
1737  { RGB(0xa0,0xa0,0xa0), RGB(0x20,0x30,0x10) },
1738  { PALETTEINDEX(0), PALETTEINDEX(255) },
1739  { PALETTEINDEX(1), PALETTEINDEX(2) },
1740  };
1741 
1742  HBITMAP hbmp;
1743  HDC hdc;
1744  DWORD col;
1745  int i, r, g, b;
1746 
1747  if (!winetest_interactive)
1748  {
1749  skip("ROSTESTS-153: Skipping test_mono_bitmap because it causes too many failures and takes too long\n");
1750  return;
1751  }
1752 
1753  hdc = CreateCompatibleDC(0);
1754  assert(hdc != 0);
1755 
1756  hbmp = CreateBitmap(16, 16, 1, 1, NULL);
1757  assert(hbmp != NULL);
1758 
1759  SelectObject( hdc, hbmp );
1760 
1761  for (col = 0; col < sizeof(colors) / sizeof(colors[0]); col++)
1762  {
1763  SetTextColor( hdc, colors[col][0] );
1764  SetBkColor( hdc, colors[col][1] );
1765 
1766  for (i = 0; i < 256; i++)
1767  {
1768  HPALETTE pal = GetCurrentObject( hdc, OBJ_PAL );
1769  PALETTEENTRY ent;
1770 
1771  if (!GetPaletteEntries( pal, i, 1, &ent )) GetPaletteEntries( pal, 0, 1, &ent );
1772  test_color( hdc, PALETTEINDEX(i), get_nearest( ent.peRed, ent.peGreen, ent.peBlue ));
1773  test_color( hdc, DIBINDEX(i), (i == 1) ? 0xffffff : 0x000000 );
1774  }
1775 
1776  for (r = 0; r < 256; r += 15)
1777  for (g = 0; g < 256; g += 15)
1778  for (b = 0; b < 256; b += 15)
1779  test_bitmap_colors( hdc, colors[col][0], colors[col][1], r, g, b );
1780  }
1781 
1782  DeleteDC(hdc);
1783  DeleteObject(hbmp);
1784 }
1785 
1786 static void test_bmBits(void)
1787 {
1788  BYTE bits[4];
1789  HBITMAP hbmp;
1790  BITMAP bmp;
1791 
1792  memset(bits, 0, sizeof(bits));
1793  hbmp = CreateBitmap(2, 2, 1, 4, bits);
1794  ok(hbmp != NULL, "CreateBitmap failed\n");
1795 
1796  memset(&bmp, 0xFF, sizeof(bmp));
1797  ok(GetObjectW(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1798  "GetObject failed or returned a wrong structure size\n");
1799  ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1800 
1801  DeleteObject(hbmp);
1802 }
1803 
1805 {
1806  HBITMAP dib;
1807  BITMAPINFO *info;
1808  BITMAPINFO *info2;
1809  void * bits;
1810  void * bits2;
1811  UINT dib_size, dib32_size;
1812  DWORD pixel;
1813  HDC dib_dc, dc;
1814  HBITMAP old_bmp;
1815  UINT i;
1816  int res;
1817 
1818  info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1819  info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1820 
1821  /* Create a DIB section with a color table */
1822 
1823  info->bmiHeader.biSize = sizeof(info->bmiHeader);
1824  info->bmiHeader.biWidth = 32;
1825  info->bmiHeader.biHeight = 32;
1826  info->bmiHeader.biPlanes = 1;
1827  info->bmiHeader.biBitCount = bpp;
1828  info->bmiHeader.biCompression = BI_RGB;
1829  info->bmiHeader.biXPelsPerMeter = 0;
1830  info->bmiHeader.biYPelsPerMeter = 0;
1831  info->bmiHeader.biClrUsed = 0;
1832  info->bmiHeader.biClrImportant = 0;
1833 
1834  for (i=0; i < (1u << bpp); i++)
1835  {
1836  BYTE c = i * (1 << (8 - bpp));
1837  info->bmiColors[i].rgbRed = c;
1838  info->bmiColors[i].rgbGreen = c;
1839  info->bmiColors[i].rgbBlue = c;
1840  info->bmiColors[i].rgbReserved = 0;
1841  }
1842 
1843  dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1844  dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1845  dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1846 
1847  /* Set the bits of the DIB section */
1848  for (i=0; i < dib_size; i++)
1849  {
1850  ((BYTE *)bits)[i] = i % 256;
1851  }
1852 
1853  /* Select the DIB into a DC */
1854  dib_dc = CreateCompatibleDC(NULL);
1855  old_bmp = SelectObject(dib_dc, dib);
1856  dc = CreateCompatibleDC(NULL);
1857  bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1858 
1859  /* Copy the DIB attributes but not the color table */
1860  memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1861 
1862  res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1863  ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1864 
1865  /* Compare the color table and the bits */
1866  for (i=0; i < (1u << bpp); i++)
1867  ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1868  info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1869  info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1870  info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1871  "color table entry %d differs (bpp %d)\n", i, bpp );
1872 
1873  ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1874 
1875  /* Test various combinations of lines = 0 and bits2 = NULL */
1876  memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1877  res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1878  ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1879  ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1880  "color table mismatch (bpp %d)\n", bpp );
1881 
1882  memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1883  res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1884  ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1885  ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1886  "color table mismatch (bpp %d)\n", bpp );
1887 
1888  memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1889  res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1890  ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1891  ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1892  "color table mismatch (bpp %d)\n", bpp );
1893 
1894  /* Map into a 32bit-DIB */
1895  info2->bmiHeader.biBitCount = 32;
1896  res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1897  ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1898 
1899  /* Check if last pixel was set */
1900  pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1901  ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1902 
1903  HeapFree(GetProcessHeap(), 0, bits2);
1904  DeleteDC(dc);
1905 
1906  SelectObject(dib_dc, old_bmp);
1907  DeleteDC(dib_dc);
1908  DeleteObject(dib);
1909  HeapFree(GetProcessHeap(), 0, info2);
1910  HeapFree(GetProcessHeap(), 0, info);
1911 }
1912 
1913 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1914 {
1915  HBITMAP ddb;
1916  BITMAPINFO *info;
1917  BITMAPINFO *info2;
1918  void * bits;
1919  void * bits2;
1920  HDC ddb_dc, dc;
1921  HBITMAP old_bmp;
1922  UINT width, height;
1923  UINT bpp;
1924  UINT i, j;
1925  int res;
1926 
1927  info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1928  info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1929 
1930  width = height = 16;
1931 
1932  /* Create a DDB (device-dependent bitmap) */
1933  if (monochrome)
1934  {
1935  bpp = 1;
1936  ddb = CreateBitmap(width, height, 1, 1, NULL);
1937  }
1938  else
1939  {
1940  HDC screen_dc = GetDC(NULL);
1941  bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1942  ddb = CreateCompatibleBitmap(screen_dc, width, height);
1943  ReleaseDC(NULL, screen_dc);
1944  }
1945 
1946  /* Set the pixels */
1947  ddb_dc = CreateCompatibleDC(NULL);
1948  old_bmp = SelectObject(ddb_dc, ddb);
1949  for (i = 0; i < width; i++)
1950  {
1951  for (j=0; j < height; j++)
1952  {
1953  BYTE c = (i * width + j) % 256;
1954  SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1955  }
1956  }
1957  SelectObject(ddb_dc, old_bmp);
1958 
1959  info->bmiHeader.biSize = sizeof(info->bmiHeader);
1960  info->bmiHeader.biWidth = width;
1961  info->bmiHeader.biHeight = height;
1962  info->bmiHeader.biPlanes = 1;
1963  info->bmiHeader.biBitCount = bpp;
1964  info->bmiHeader.biCompression = BI_RGB;
1965 
1966  dc = CreateCompatibleDC(NULL);
1967 
1968  /* Fill in biSizeImage */
1969  GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1970  ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1971 
1974 
1975  /* Get the bits */
1976  res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1977  ok( res == height, "got %d (bpp %d)\n", res, bpp );
1978 
1979  /* Copy the DIB attributes but not the color table */
1980  memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1981 
1982  /* Select the DDB into another DC */
1983  old_bmp = SelectObject(ddb_dc, ddb);
1984 
1985  /* Get the bits */
1986  res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1987  ok( res == height, "got %d (bpp %d)\n", res, bpp );
1988 
1989  /* Compare the color table and the bits */
1990  if (bpp <= 8)
1991  {
1992  for (i=0; i < (1u << bpp); i++)
1993  ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1994  info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1995  info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1996  info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1997  "color table entry %d differs (bpp %d)\n", i, bpp );
1998  }
1999 
2000  ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
2001 
2002  /* Test the palette */
2003  if (info2->bmiHeader.biBitCount <= 8)
2004  {
2005  WORD *colors = (WORD*)info2->bmiColors;
2006 
2007  /* Get the palette indices */
2008  res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
2009  ok( res == 1, "got %d (bpp %d)\n", res, bpp );
2010 
2011  for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
2012  ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
2013  }
2014 
2015  HeapFree(GetProcessHeap(), 0, bits2);
2016  HeapFree(GetProcessHeap(), 0, bits);
2017  DeleteDC(dc);
2018 
2019  SelectObject(ddb_dc, old_bmp);
2020  DeleteDC(ddb_dc);
2021  DeleteObject(ddb);
2022  HeapFree(GetProcessHeap(), 0, info2);
2023  HeapFree(GetProcessHeap(), 0, info);
2024 }
2025 
2026 static void test_GetDIBits(void)
2027 {
2028  /* 2-bytes aligned 1-bit bitmap data: 16x16 */
2029  static const BYTE bmp_bits_1[16 * 2] =
2030  {
2031  0xff,0xff, 0,0, 0xff,0xff, 0,0,
2032  0xff,0xff, 0,0, 0xff,0xff, 0,0,
2033  0xff,0xff, 0,0, 0xff,0xff, 0,0,
2034  0xff,0xff, 0,0, 0xff,0xff, 0,0
2035  };
2036  /* 4-bytes aligned 1-bit DIB data: 16x16 */
2037  static const BYTE dib_bits_1[16 * 4] =
2038  {
2039  0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
2040  0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
2041  0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
2042  0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
2043  };
2044  /* 2-bytes aligned 24-bit bitmap data: 16x16 */
2045  static const BYTE bmp_bits_24[16 * 16*3] =
2046  {
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  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2067  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2068  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2069  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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  };
2080  /* 4-bytes aligned 24-bit DIB data: 16x16 */
2081  static const BYTE dib_bits_24[16 * 16*3] =
2082  {
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  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
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  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2103  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2104  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2105  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2106  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2107  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2108  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2109  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2110  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2111  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2112  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2113  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2114  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
2115  };
2116  HBITMAP hbmp;
2117  BITMAP bm;
2118  HDC hdc;
2119  int i, bytes, lines;
2120  BYTE buf[1024];
2121  char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
2122  BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
2123  RGBQUAD *colors = bi->bmiColors;
2124  PALETTEENTRY pal_ents[20];
2125 
2126  hdc = GetDC(0);
2127 
2128  /* 1-bit source bitmap data */
2129  hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
2130  ok(hbmp != 0, "CreateBitmap failed\n");
2131 
2132  memset(&bm, 0xAA, sizeof(bm));
2133  bytes = GetObjectW(hbmp, sizeof(bm), &bm);
2134  ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2135  ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2136  ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
2137  ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
2138  ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2139  ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
2140  ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2141  ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2142 
2143  bytes = GetBitmapBits(hbmp, 0, NULL);
2144  ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
2145  bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
2146  ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
2147  ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
2148 
2149  /* retrieve 1-bit DIB data */
2150  memset(bi, 0, sizeof(*bi));
2151  bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2152  bi->bmiHeader.biWidth = bm.bmWidth;
2153  bi->bmiHeader.biHeight = bm.bmHeight;
2154  bi->bmiHeader.biPlanes = 1;
2155  bi->bmiHeader.biBitCount = 1;
2157  bi->bmiHeader.biClrUsed = 37;
2158  bi->bmiHeader.biSizeImage = 0;
2159  memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2160  SetLastError(0xdeadbeef);
2161  lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2162  ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
2164  broken(GetLastError() == 0xdeadbeef), /* winnt */
2165  "wrong error %u\n", GetLastError());
2166  ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
2167  ok(bi->bmiHeader.biClrUsed == 37 || broken(bi->bmiHeader.biClrUsed == 0),
2168  "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2169 
2170  memset(buf, 0xAA, sizeof(buf));
2171  SetLastError(0xdeadbeef);
2172  lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2173  ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2174  lines, bm.bmHeight, GetLastError());
2175  ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
2176  ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2177 
2178  /* the color table consists of black and white */
2179  ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
2180  colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
2181  "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
2182  colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
2183  ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
2184  colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
2185  "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
2186  colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
2187  for (i = 2; i < 256; i++)
2188  {
2189  ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2190  colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2191  "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2192  colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2193  }
2194 
2195  /* returned bits are DWORD aligned and upside down */
2196  ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
2197 
2198  /* Test the palette indices */
2199  memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2200  SetLastError(0xdeadbeef);
2201  lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
2202  ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
2203  ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
2204  for (i = 2; i < 256; i++)
2205  ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[1]);
2206 
2207  /* retrieve 24-bit DIB data */
2208  memset(bi, 0, sizeof(*bi));
2209  bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2210  bi->bmiHeader.biWidth = bm.bmWidth;
2211  bi->bmiHeader.biHeight = bm.bmHeight;
2212  bi->bmiHeader.biPlanes = 1;
2213  bi->bmiHeader.biBitCount = 24;
2215  bi->bmiHeader.biClrUsed = 37;
2216  bi->bmiHeader.biSizeImage = 0;
2217  memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2218  memset(buf, 0xAA, sizeof(buf));
2219  SetLastError(0xdeadbeef);
2220  lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2221  ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2222  lines, bm.bmHeight, GetLastError());
2223  ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2224  ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2225 
2226  /* the color table doesn't exist for 24-bit images */
2227  for (i = 0; i < 256; i++)
2228  {
2229  ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2230  colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2231  "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2232  colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2233  }
2234 
2235  /* returned bits are DWORD aligned and upside down */
2236  ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2237  DeleteObject(hbmp);
2238 
2239  /* 24-bit source bitmap data */
2240  hbmp = CreateCompatibleBitmap(hdc, 16, 16);
2241  ok(hbmp != 0, "CreateBitmap failed\n");
2242  SetLastError(0xdeadbeef);
2243  bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
2244  lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
2245  ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
2246  lines, bm.bmHeight, GetLastError());
2247 
2248  memset(&bm, 0xAA, sizeof(bm));
2249  bytes = GetObjectW(hbmp, sizeof(bm), &bm);
2250  ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2251  ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2252  ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
2253  ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
2254  ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2255  ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
2256  ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2257  ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2258 
2259  bytes = GetBitmapBits(hbmp, 0, NULL);
2260  ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
2261  bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
2262  ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
2263  bm.bmWidthBytes * bm.bmHeight, bytes);
2264 
2265  /* retrieve 1-bit DIB data */
2266  memset(bi, 0, sizeof(*bi));
2267  bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2268  bi->bmiHeader.biWidth = bm.bmWidth;
2269  bi->bmiHeader.biHeight = bm.bmHeight;
2270  bi->bmiHeader.biPlanes = 1;
2271  bi->bmiHeader.biBitCount = 1;
2273  bi->bmiHeader.biClrUsed = 37;
2274  bi->bmiHeader.biSizeImage = 0;
2275  memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2276  memset(buf, 0xAA, sizeof(buf));
2277  SetLastError(0xdeadbeef);
2278  lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2279  ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2280  lines, bm.bmHeight, GetLastError());
2281  ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
2282  ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2283 
2284  /* the color table consists of black and white */
2285  ok(colors[0].rgbRed == 0 && colors[0].rgbGreen == 0 &&
2286  colors[0].rgbBlue == 0 && colors[0].rgbReserved == 0,
2287  "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
2288  colors[0].rgbRed, colors[0].rgbGreen, colors[0].rgbBlue, colors[0].rgbReserved);
2289  ok(colors[1].rgbRed == 0xff && colors[1].rgbGreen == 0xff &&
2290  colors[1].rgbBlue == 0xff && colors[1].rgbReserved == 0,
2291  "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
2292  colors[1].rgbRed, colors[1].rgbGreen, colors[1].rgbBlue, colors[1].rgbReserved);
2293  for (i = 2; i < 256; i++)
2294  {
2295  ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2296  colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2297  "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2298  colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2299  }
2300 
2301  /* returned bits are DWORD aligned and upside down */
2302  ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
2303 
2304  /* Test the palette indices */
2305  memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2306  SetLastError(0xdeadbeef);
2307  lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
2308  ok(((WORD*)colors)[0] == 0, "Color 0 is %d\n", ((WORD*)colors)[0]);
2309  ok(((WORD*)colors)[1] == 1, "Color 1 is %d\n", ((WORD*)colors)[1]);
2310  for (i = 2; i < 256; i++)
2311  ok(((WORD*)colors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)colors)[i]);
2312 
2313  /* retrieve 4-bit DIB data */
2314  memset(bi, 0, sizeof(*bi));
2315  bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2316  bi->bmiHeader.biWidth = bm.bmWidth;
2317  bi->bmiHeader.biHeight = bm.bmHeight;
2318  bi->bmiHeader.biPlanes = 1;
2319  bi->bmiHeader.biBitCount = 4;
2321  bi->bmiHeader.biClrUsed = 37;
2322  bi->bmiHeader.biSizeImage = 0;
2323  memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2324  memset(buf, 0xAA, sizeof(buf));
2325  SetLastError(0xdeadbeef);
2326  lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2327  ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2328  lines, bm.bmHeight, GetLastError());
2329  ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2330 
2331  GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2332 
2333  for (i = 0; i < 16; i++)
2334  {
2335  RGBQUAD expect;
2336  int entry = i < 8 ? i : i + 4;
2337 
2338  if(entry == 7) entry = 12;
2339  else if(entry == 12) entry = 7;
2340 
2341  expect.rgbRed = pal_ents[entry].peRed;
2342  expect.rgbGreen = pal_ents[entry].peGreen;
2343  expect.rgbBlue = pal_ents[entry].peBlue;
2344  expect.rgbReserved = 0;
2345 
2346  ok(!memcmp(colors + i, &expect, sizeof(expect)),
2347  "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2348  expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2349  colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2350  }
2351 
2352  /* retrieve 8-bit DIB data */
2353  memset(bi, 0, sizeof(*bi));
2354  bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2355  bi->bmiHeader.biWidth = bm.bmWidth;
2356  bi->bmiHeader.biHeight = bm.bmHeight;
2357  bi->bmiHeader.biPlanes = 1;
2358  bi->bmiHeader.biBitCount = 8;
2360  bi->bmiHeader.biClrUsed = 37;
2361  bi->bmiHeader.biSizeImage = 0;
2362  memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2363  memset(buf, 0xAA, sizeof(buf));
2364  SetLastError(0xdeadbeef);
2365  lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2366  ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2367  lines, bm.bmHeight, GetLastError());
2368  ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2369 
2370  GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2371 
2372  for (i = 0; i < 256; i++)
2373  {
2374  RGBQUAD expect;
2375 
2376  if (i < 10 || i >= 246)
2377  {
2378  int entry = i < 10 ? i : i - 236;
2379  expect.rgbRed = pal_ents[entry].peRed;
2380  expect.rgbGreen = pal_ents[entry].peGreen;
2381  expect.rgbBlue = pal_ents[entry].peBlue;
2382  }
2383  else
2384  {
2385  expect.rgbRed = (i & 0x07) << 5;
2386  expect.rgbGreen = (i & 0x38) << 2;
2387  expect.rgbBlue = i & 0xc0;
2388  }
2389  expect.rgbReserved = 0;
2390 
2391  ok(!memcmp(colors + i, &expect, sizeof(expect)),
2392  "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2393  expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2394  colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2395  }
2396 
2397  /* retrieve 24-bit DIB data */
2398  memset(bi, 0, sizeof(*bi));
2399  bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2400  bi->bmiHeader.biWidth = bm.bmWidth;
2401  bi->bmiHeader.biHeight = bm.bmHeight;
2402  bi->bmiHeader.biPlanes = 1;
2403  bi->bmiHeader.biBitCount = 24;
2405  bi->bmiHeader.biClrUsed = 37;
2406  bi->bmiHeader.biSizeImage = 0;
2407  memset(colors, 0xAA, sizeof(RGBQUAD) * 256);
2408  memset(buf, 0xAA, sizeof(buf));
2409  SetLastError(0xdeadbeef);
2410  lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2411  ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2412  lines, bm.bmHeight, GetLastError());
2413  ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2414  ok(bi->bmiHeader.biClrUsed == 0, "wrong biClrUsed %u\n", bi->bmiHeader.biClrUsed);
2415 
2416  /* the color table doesn't exist for 24-bit images */
2417  for (i = 0; i < 256; i++)
2418  {
2419  ok(colors[i].rgbRed == 0xAA && colors[i].rgbGreen == 0xAA &&
2420  colors[i].rgbBlue == 0xAA && colors[i].rgbReserved == 0xAA,
2421  "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2422  colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue, colors[i].rgbReserved);
2423  }
2424 
2425  /* returned bits are DWORD aligned and upside down */
2426  ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2427  DeleteObject(hbmp);
2428 
2429  ReleaseDC(0, hdc);
2430 }
2431 
2433 {
2434  /* Try a screen resolution detection technique
2435  * from the September 1999 issue of Windows Developer's Journal
2436  * which seems to be in widespread use.
2437  * http://www.lesher.ws/highcolor.html
2438  * http://www.lesher.ws/vidfmt.c
2439  * It hinges on being able to retrieve the bitmaps
2440  * for the three primary colors in non-paletted 16 bit mode.
2441  */
2442  char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2443  DWORD bits[32];
2444  LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2445  DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2446  HDC hdc;
2447  HBITMAP hbm;
2448  int ret;
2449  void *ptr;
2450 
2451  memset(dibinfo, 0, sizeof(dibinfo_buf));
2452  dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2453 
2454  hdc = GetDC(NULL);
2455  ok(hdc != NULL, "GetDC failed?\n");
2456  hbm = CreateCompatibleBitmap(hdc, 1, 1);
2457  ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2458 
2459  /* Call GetDIBits to fill in bmiHeader. */
2460  ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2461  ok(ret == 1, "GetDIBits failed\n");
2462  if (dibinfo->bmiHeader.biBitCount > 8)
2463  {
2464  ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2465  broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2466  "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2467 
2468  if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2469  {
2470  ok( !bitmasks[0], "red mask is set\n" );
2471  ok( !bitmasks[1], "green mask is set\n" );
2472  ok( !bitmasks[2], "blue mask is set\n" );
2473 
2474  /* test with NULL bits pointer and correct bpp */
2475  dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2476  ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2477  ok(ret == 1, "GetDIBits failed\n");
2478 
2479  ok( bitmasks[0] != 0, "red mask is not set\n" );
2480  ok( bitmasks[1] != 0, "green mask is not set\n" );
2481  ok( bitmasks[2] != 0, "blue mask is not set\n" );
2482  ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2483 
2484  /* test with valid bits pointer */
2485  memset(dibinfo, 0, sizeof(dibinfo_buf));
2486  dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2487  ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2488  ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2489  dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2490  ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2491  ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2492 
2493  ok( bitmasks[0] != 0, "red mask is not set\n" );
2494  ok( bitmasks[1] != 0, "green mask is not set\n" );
2495  ok( bitmasks[2] != 0, "blue mask is not set\n" );
2496  ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2497 
2498  /* now with bits and 0 lines */
2499  memset(dibinfo, 0, sizeof(dibinfo_buf));
2500  dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2501  dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2502  SetLastError(0xdeadbeef);
2503  ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2504  ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2505 
2506  ok( !bitmasks[0], "red mask is set\n" );
2507  ok( !bitmasks[1], "green mask is set\n" );
2508  ok( !bitmasks[2], "blue mask is set\n" );
2509  ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2510 
2511  memset(bitmasks, 0, 3*sizeof(DWORD));
2512  dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2513  ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2514  ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2515 
2516  ok( bitmasks[0] != 0, "red mask is not set\n" );
2517  ok( bitmasks[1] != 0, "green mask is not set\n" );
2518  ok( bitmasks[2] != 0, "blue mask is not set\n" );
2519  ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2520  }
2521  }
2522  else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2523 
2524  DeleteObject(hbm);
2525 
2526  /* same thing now with a 32-bpp DIB section */
2527 
2528  dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2529  dibinfo->bmiHeader.biWidth = 1;
2530  dibinfo->bmiHeader.biHeight = 1;
2531  dibinfo->bmiHeader.biPlanes = 1;
2532  dibinfo->bmiHeader.biBitCount = 32;
2533  dibinfo->bmiHeader.biCompression = BI_RGB;
2534  dibinfo->bmiHeader.biSizeImage = 0;
2535  dibinfo->bmiHeader.biXPelsPerMeter = 0;
2536  dibinfo->bmiHeader.biYPelsPerMeter = 0;
2537  dibinfo->bmiHeader.biClrUsed = 0;
2538  dibinfo->bmiHeader.biClrImportant = 0;
2539  bitmasks[0] = 0x0000ff;
2540  bitmasks[1] = 0x00ff00;
2541  bitmasks[2] = 0xff0000;
2542  hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2543  ok( hbm != 0, "failed to create bitmap\n" );
2544 
2545  memset(dibinfo, 0, sizeof(dibinfo_buf));
2546  dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2547  ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2548  ok(ret == 1, "GetDIBits failed\n");
2549  ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2550 
2551  ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2552  broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2553  "compression is %u\n", dibinfo->bmiHeader.biCompression );
2554  ok( !bitmasks[0], "red mask is set\n" );
2555  ok( !bitmasks[1], "green mask is set\n" );
2556  ok( !bitmasks[2], "blue mask is set\n" );
2557 
2558  dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2559  ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2560  ok(ret == 1, "GetDIBits failed\n");
2561  ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2562  ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2563  broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2564  "compression is %u\n", dibinfo->bmiHeader.biCompression );
2565  if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2566  {
2567  ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2568  ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2569  ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2570  }
2571  ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2572 
2573  DeleteObject(hbm);
2574 
2575  dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2576  dibinfo->bmiHeader.biWidth = 1;
2577  dibinfo->bmiHeader.biHeight = 1;
2578  dibinfo->bmiHeader.biPlanes = 1;
2579  dibinfo->bmiHeader.biBitCount = 32;
2581  dibinfo->bmiHeader.biSizeImage = 0;
2582  dibinfo->bmiHeader.biXPelsPerMeter = 0;
2583  dibinfo->bmiHeader.biYPelsPerMeter = 0;
2584  dibinfo->bmiHeader.biClrUsed = 0;
2585  dibinfo->bmiHeader.biClrImportant = 0;
2586  bitmasks[0] = 0x0000ff;
2587  bitmasks[1] = 0x00ff00;
2588  bitmasks[2] = 0xff0000;
2589  hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2590  ok( hbm != 0, "failed to create bitmap\n" );
2591 
2592  if (hbm)
2593  {
2594  memset(dibinfo, 0, sizeof(dibinfo_buf));
2595  dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2596  ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2597  ok(ret == 1, "GetDIBits failed\n");
2598 
2599  ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2600  "compression is %u\n", dibinfo->bmiHeader.biCompression );
2601  ok( !bitmasks[0], "red mask is set\n" );
2602  ok( !bitmasks[1], "green mask is set\n" );
2603  ok( !bitmasks[2], "blue mask is set\n" );
2604 
2605  dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2606  ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2607  ok(ret == 1, "GetDIBits failed\n");
2608  ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2609  ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2610  ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2611  ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2612 
2613  DeleteObject(hbm);
2614  }
2615 
2616  /* 24-bpp DIB sections don't have bitfields */
2617 
2618  dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2619  dibinfo->bmiHeader.biWidth = 1;
2620  dibinfo->bmiHeader.biHeight = 1;
2621  dibinfo->bmiHeader.biPlanes = 1;
2622  dibinfo->bmiHeader.biBitCount = 24;
2624  dibinfo->bmiHeader.biSizeImage = 0;
2625  dibinfo->bmiHeader.biXPelsPerMeter = 0;
2626  dibinfo->bmiHeader.biYPelsPerMeter = 0;
2627  dibinfo->bmiHeader.biClrUsed = 0;
2628  dibinfo->bmiHeader.biClrImportant = 0;
2629  hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2630  ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2631  dibinfo->bmiHeader.biCompression = BI_RGB;
2632  hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2633  ok( hbm != 0, "failed to create bitmap\n" );
2634 
2635  memset(dibinfo, 0, sizeof(dibinfo_buf));
2636  dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2637  ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2638  ok(ret == 1, "GetDIBits failed\n");
2639  ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2640 
2641  ok( dibinfo->bmiHeader.biCompression == BI_RGB,
2642  "compression is %u\n", dibinfo->bmiHeader.biCompression );
2643  ok( !bitmasks[0], "red mask is set\n" );
2644  ok( !bitmasks[1], "green mask is set\n" );
2645  ok( !bitmasks[2], "blue mask is set\n" );
2646 
2647  dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2648  ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2649  ok(ret == 1, "GetDIBits failed\n");
2650  ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2651  ok( !bitmasks[0], "red mask is set\n" );
2652  ok( !bitmasks[1], "green mask is set\n" );
2653  ok( !bitmasks[2], "blue mask is set\n" );
2654  ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2655 
2656  DeleteObject(hbm);
2657  ReleaseDC(NULL, hdc);
2658 }
2659 
2660 static void test_select_object(void)
2661 {
2662  HDC hdc;
2663  HBITMAP hbm, hbm_old;
2664  INT planes, bpp, i;
2665  DWORD depths[] = {8, 15, 16, 24, 32};
2666  BITMAP bm;
2667  DWORD bytes;
2668 
2669  hdc = GetDC(0);
2670  ok(hdc != 0, "GetDC(0) failed\n");
2671  hbm = CreateCompatibleBitmap(hdc, 10, 10);
2672  ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2673 
2674  hbm_old = SelectObject(hdc, hbm);
2675  ok(hbm_old == 0, "SelectObject should fail\n");
2676 
2677  DeleteObject(hbm);
2678  ReleaseDC(0, hdc);
2679 
2680  hdc = CreateCompatibleDC(0);
2681  ok(hdc != 0, "GetDC(0) failed\n");
2682  hbm = CreateCompatibleBitmap(hdc, 10, 10);
2683  ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2684 
2685  hbm_old = SelectObject(hdc, hbm);
2686  ok(hbm_old != 0, "SelectObject failed\n");
2687  hbm_old = SelectObject(hdc, hbm_old);
2688  ok(hbm_old == hbm, "SelectObject failed\n");
2689 
2690  DeleteObject(hbm);
2691 
2692  /* test an 1-bpp bitmap */
2693  planes = GetDeviceCaps(hdc, PLANES);
2694  bpp = 1;
2695 
2696  hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2697  ok(hbm != 0, "CreateBitmap failed\n");
2698 
2699  hbm_old = SelectObject(hdc, hbm);
2700  ok(hbm_old != 0, "SelectObject failed\n");
2701  hbm_old = SelectObject(hdc, hbm_old);
2702  ok(hbm_old == hbm, "SelectObject failed\n");
2703 
2704  DeleteObject(hbm);
2705 
2706  for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2707  /* test a color bitmap to dc bpp matching */
2708  planes = GetDeviceCaps(hdc, PLANES);
2709  bpp = GetDeviceCaps(hdc, BITSPIXEL);
2710 
2711  hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2712  ok(hbm != 0, "CreateBitmap failed\n");
2713 
2714  hbm_old = SelectObject(hdc, hbm);
2715  if(depths[i] == bpp ||
2716  (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2717  ) {
2718  ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2719  SelectObject(hdc, hbm_old);
2720  } else {
2721  ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2722  }
2723 
2724  memset(&bm, 0xAA, sizeof(bm));
2725  bytes = GetObjectW(hbm, sizeof(bm), &bm);
2726  ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2727  ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2728  ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2729  ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2730  ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2731  ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2732  if(depths[i] == 15) {
2733  ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2734  } else {
2735  ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2736  }
2737  ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2738 
2739  DeleteObject(hbm);
2740  }
2741 
2742  DeleteDC(hdc);
2743 }
2744 
2746 {
2747  INT ret;
2748  BITMAP bm;
2749 
2750  ret = GetObjectType(hbmp);
2751  ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2752 
2753  ret = GetObjectW(hbmp, 0, 0);
2754  ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2755 
2756  memset(&bm, 0xDA, sizeof(bm));
2757  SetLastError(0xdeadbeef);
2758  ret = GetObjectW(hbmp, sizeof(bm), &bm);
2759  if (!ret) /* XP, only for curObj2 */ return;
2760  ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2761  ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2762  ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2763  ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2764  ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2765  ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2766  ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2767  ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2768 }
2769 
2770 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2771 
2772 static void test_CreateBitmap(void)
2773 {
2774  BITMAP bmp;
2775  HDC screenDC = GetDC(0);
2776  HDC hdc = CreateCompatibleDC(screenDC);
2777  UINT i, expect = 0;
2778 
2779  /* all of these are the stock monochrome bitmap */
2780  HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2781  HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2782  HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2783  HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2784  HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2785  HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2786 
2787  /* these 2 are not the stock monochrome bitmap */
2788  HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2789  HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2790 
2791  HBITMAP old1 = SelectObject(hdc, bm2);
2792  HBITMAP old2 = SelectObject(screenDC, bm3);
2793  SelectObject(hdc, old1);
2794  SelectObject(screenDC, old2);
2795 
2796  ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2797  "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2798  bm, bm1, bm4, bm5, curObj1, old1);
2799  ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2800 todo_wine
2801  ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2802  ok(old2 == 0, "old2 %p\n", old2);
2803 
2804  test_mono_1x1_bmp(bm);
2805  test_mono_1x1_bmp(bm1);
2806  test_mono_1x1_bmp(bm2);
2807  test_mono_1x1_bmp(bm3);
2808  test_mono_1x1_bmp(bm4);
2809  test_mono_1x1_bmp(bm5);
2810  test_mono_1x1_bmp(old1);
2811  test_mono_1x1_bmp(curObj1);
2812 
2813  DeleteObject(bm);
2814  DeleteObject(bm1);
2815  DeleteObject(bm2);
2816  DeleteObject(bm3);
2817  DeleteObject(bm4);
2818  DeleteObject(bm5);
2819 
2820  DeleteDC(hdc);
2821  ReleaseDC(0, screenDC);
2822 
2823  /* show that Windows ignores the provided bm.bmWidthBytes */
2824  bmp.bmType = 0;
2825  bmp.bmWidth = 1;
2826  bmp.bmHeight = 1;
2827  bmp.bmWidthBytes = 28;
2828  bmp.bmPlanes = 1;
2829  bmp.bmBitsPixel = 1;
2830  bmp.bmBits = NULL;
2831  bm = CreateBitmapIndirect(&bmp);
2832  ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2833  test_mono_1x1_bmp(bm);
2834  DeleteObject(bm);
2835 
2836  /* Test how the bmBitsPixel field is treated */
2837  for(i = 1; i <= 33; i++) {
2838  bmp.bmType = 0;
2839  bmp.bmWidth = 1;
2840  bmp.bmHeight = 1;
2841  bmp.bmWidthBytes = 28;
2842  bmp.bmPlanes = 1;
2843  bmp.bmBitsPixel = i;
2844  bmp.bmBits = NULL;
2845  SetLastError(0xdeadbeef);
2846  bm = CreateBitmapIndirect(&bmp);
2847  if(i > 32) {
2848  DWORD error = GetLastError();
2849  ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2850  ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2851  DeleteObject(bm);
2852  continue;
2853  }
2854  ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2855  GetObjectW(bm, sizeof(bmp), &bmp);
2856  if(i == 1) {
2857  expect = 1;
2858  } else if(i <= 4) {
2859  expect = 4;
2860  } else if(i <= 8) {
2861  expect = 8;
2862  } else if(i <= 16) {
2863  expect = 16;
2864  } else if(i <= 24) {
2865  expect = 24;
2866  } else if(i <= 32) {
2867  expect = 32;
2868  }
2869  ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2870  i, bmp.bmBitsPixel, expect);
2871  DeleteObject(bm);
2872  }
2873 }
2874 
2875 static void test_bitmapinfoheadersize(void)
2876 {
2877  HBITMAP hdib;
2878  BITMAPINFO bmi;
2879  BITMAPCOREINFO bci;
2880  HDC hdc = GetDC(0);
2881 
2882  memset(&bmi, 0, sizeof(BITMAPINFO));
2883  bmi.bmiHeader.biHeight = 100;
2884  bmi.bmiHeader.biWidth = 512;
2885  bmi.bmiHeader.biBitCount = 24;
2886  bmi.bmiHeader.biPlanes = 1;
2887 
2888  bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2889 
2890  hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2891  ok(hdib == NULL, "CreateDIBSection succeeded\n");
2892 
2893  bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2894 
2895  SetLastError(0xdeadbeef);
2896  hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2897  ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2898  DeleteObject(hdib);
2899 
2900  bmi.bmiHeader.biSize++;
2901 
2902  SetLastError(0xdeadbeef);
2903  hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2904  ok(hdib != NULL ||
2905  broken(!hdib), /* Win98, WinMe */
2906  "CreateDIBSection error %d\n", GetLastError());
2907  DeleteObject(hdib);
2908 
2909  bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2910 
2911  SetLastError(0xdeadbeef);
2912  hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2913  ok(hdib != NULL ||
2914  broken(!hdib), /* Win98, WinMe */
2915  "CreateDIBSection error %d\n", GetLastError());
2916  DeleteObject(hdib);
2917 
2918  bmi.bmiHeader.biSize++;
2919 
2920  SetLastError(0xdeadbeef);
2921  hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2922  ok(hdib != NULL ||
2923  broken(!hdib), /* Win98, WinMe */
2924  "CreateDIBSection error %d\n", GetLastError());
2925  DeleteObject(hdib);
2926 
2927  bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2928 
2929  SetLastError(0xdeadbeef);
2930  hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2931  ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2932  DeleteObject(hdib);
2933 
2934  bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2935 
2936  SetLastError(0xdeadbeef);
2937  hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2938  ok(hdib != NULL ||
2939  broken(!hdib), /* Win95 */
2940  "CreateDIBSection error %d\n", GetLastError());
2941  DeleteObject(hdib);
2942 
2943  memset(&bci, 0, sizeof(BITMAPCOREINFO));
2944  bci.bmciHeader.bcHeight = 100;
2945  bci.bmciHeader.bcWidth = 512;
2946  bci.bmciHeader.bcBitCount = 24;
2947  bci.bmciHeader.bcPlanes = 1;
2948 
2949  bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2950 
2951  hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2952  ok(hdib == NULL, "CreateDIBSection succeeded\n");
2953 
2954  bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2955 
2956  SetLastError(0xdeadbeef);
2957  hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2958  ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2959  DeleteObject(hdib);
2960 
2961  bci.bmciHeader.bcSize++;
2962 
2963  hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2964  ok(hdib == NULL, "CreateDIBSection succeeded\n");
2965 
2966  bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2967 
2968  hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2969  ok(hdib == NULL, "CreateDIBSection succeeded\n");
2970 
2971  ReleaseDC(0, hdc);
2972 }
2973 
2974 static void test_get16dibits(void)
2975 {
2976  BYTE bits[4 * (16 / sizeof(BYTE))];
2977  HBITMAP hbmp;
2978  HDC screen_dc = GetDC(NULL);
2979  int ret;
2980  BITMAPINFO * info;
2981  int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2982  BYTE *p;
2983  int overwritten_bytes = 0;
2984 
2985  memset(bits, 0, sizeof(bits));
2986  hbmp = CreateBitmap(2, 2, 1, 16, bits);
2987  ok(hbmp != NULL, "CreateBitmap failed\n");
2988 
2989  info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2990  assert(info);
2991 
2992  memset(info, '!', info_len);
2993  memset(info, 0, sizeof(info->bmiHeader));
2994 
2995  info->bmiHeader.biSize = sizeof(info->bmiHeader);
2996  info->bmiHeader.biWidth = 2;
2997  info->bmiHeader.biHeight = 2;
2998  info->bmiHeader.biPlanes = 1;
2999  info->bmiHeader.biCompression = BI_RGB;
3000 
3001  ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
3002  ok(ret != 0, "GetDIBits failed got %d\n", ret);
3003 
3004  for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
3005  if (*p != '!')
3006  overwritten_bytes++;
3007  ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
3008 
3009  HeapFree(GetProcessHeap(), 0, info);
3010  DeleteObject(hbmp);
3011  ReleaseDC(NULL, screen_dc);
3012 }
3013 
3014 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
3015  DWORD dwRop, UINT32 expected, int line)
3016 {
3017  *srcBuffer = 0xFEDCBA98;
3018  *dstBuffer = 0x89ABCDEF;
3019  BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
3020  ok(expected == *dstBuffer,
3021  "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3022  dwRop, expected, *dstBuffer, line);
3023 }
3024 
3025 static void test_BitBlt(void)
3026 {
3027  HBITMAP bmpDst, bmpSrc;
3028  HBITMAP oldDst, oldSrc;
3029  HDC hdcScreen, hdcDst, hdcSrc;
3030  UINT32 *dstBuffer, *srcBuffer;
3031  HBRUSH hBrush, hOldBrush;
3032  BITMAPINFO bitmapInfo;
3033 
3034  memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3035  bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3036  bitmapInfo.bmiHeader.biWidth = 1;
3037  bitmapInfo.bmiHeader.biHeight = 1;
3038  bitmapInfo.bmiHeader.biPlanes = 1;
3039  bitmapInfo.bmiHeader.biBitCount = 32;
3040  bitmapInfo.bmiHeader.biCompression = BI_RGB;
3041  bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
3042 
3043  hdcScreen = CreateCompatibleDC(0);
3044  hdcDst = CreateCompatibleDC(hdcScreen);
3045  hdcSrc = CreateCompatibleDC(hdcDst);
3046 
3047  /* Setup the destination dib section */
3048  bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
3049  NULL, 0);
3050  oldDst = SelectObject(hdcDst, bmpDst);
3051 
3052  hBrush = CreateSolidBrush(0x12345678);
3053  hOldBrush = SelectObject(hdcDst, hBrush);
3054 
3055  /* Setup the source dib section */
3056  bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
3057  NULL, 0);
3058  oldSrc = SelectObject(hdcSrc, bmpSrc);
3059 
3060  check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3061  check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3062  check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3063  check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3064  check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3065  check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3066  check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3067  check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3068  check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3069  check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3070  check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3071  check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3072  check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3073  check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3074  check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3075 
3076  /* Tidy up */
3077  SelectObject(hdcSrc, oldSrc);
3078  DeleteObject(bmpSrc);
3079  DeleteDC(hdcSrc);
3080 
3081  SelectObject(hdcDst, hOldBrush);
3082  DeleteObject(hBrush);
3083  SelectObject(hdcDst, oldDst);
3084  DeleteObject(bmpDst);
3085  DeleteDC(hdcDst);
3086 
3087 
3088  DeleteDC(hdcScreen);
3089 }
3090 
3091 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
3092  DWORD dwRop, UINT32 expected, int line)
3093 {
3094  *srcBuffer = 0xFEDCBA98;
3095  *dstBuffer = 0x89ABCDEF;
3096  StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
3097  ok(expected == *dstBuffer,
3098  "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3099  dwRop, expected, *dstBuffer, line);
3100 }
3101 
3102 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, BITMAPINFO *dst_info, UINT32 *dstBuffer, UINT32 *srcBuffer,
3103  int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3104  int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3105  UINT32 *expected, int line)
3106 {
3107  int dst_size = get_dib_image_size( dst_info );
3108 
3109  memset(dstBuffer, 0, dst_size);
3110  StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3111  hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
3112  ok(memcmp(dstBuffer, expected, dst_size) == 0,
3113  "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3114  "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3115  expected[0], expected[1], expected[2], expected[3],
3116  dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3117  nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3118  nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3119 }
3120 
3121 static void test_StretchBlt(void)
3122 {
3123  HBITMAP bmpDst, bmpSrc;
3124  HBITMAP oldDst, oldSrc;
3125  HDC hdcScreen, hdcDst, hdcSrc;
3126  UINT32 *dstBuffer, *srcBuffer;
3127  HBRUSH hBrush, hOldBrush;
3128  BITMAPINFO biDst, biSrc;
3129  UINT32 expected[256];
3130  RGBQUAD colors[2];
3131 
3132  memset(&biDst, 0, sizeof(BITMAPINFO));
3133  biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3134  biDst.bmiHeader.biWidth = 16;
3135  biDst.bmiHeader.biHeight = -16;
3136  biDst.bmiHeader.biPlanes = 1;
3137  biDst.bmiHeader.biBitCount = 32;
3138  biDst.bmiHeader.biCompression = BI_RGB;
3139  memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
3140 
3141  hdcScreen = CreateCompatibleDC(0);
3142  hdcDst = CreateCompatibleDC(hdcScreen);
3143  hdcSrc = CreateCompatibleDC(hdcDst);
3144 
3145  /* Pixel Tests */
3146  bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3147  NULL, 0);
3148  oldDst = SelectObject(hdcDst, bmpDst);
3149 
3150  bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
3151  NULL, 0);
3152  oldSrc = SelectObject(hdcSrc, bmpSrc);
3153 
3154  hBrush = CreateSolidBrush(0x012345678);
3155  hOldBrush = SelectObject(hdcDst, hBrush);
3156 
3157  check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3158  check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3159  check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3160  check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3161  check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3162  check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3163  check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3164  check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3165  check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3166  check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3167  check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3168  check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3169  check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3170  check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3171  check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3172 
3173  SelectObject(hdcDst, hOldBrush);
3174  DeleteObject(hBrush);
3175 
3176  /* Top-down to top-down tests */
3177  srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3178  srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
3179 
3180  memset( expected, 0, get_dib_image_size( &biDst ) );
3181  expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3182  expected[16] = 0xFEDCBA98, expected[17] = 0x76543210;
3183  check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3184  0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3185 
3186  expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3187  expected[16] = 0x00000000, expected[17] = 0x00000000;
3188  check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3189  0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
3190 
3191  expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
3192  expected[16] = 0xCAFED00D, expected[17] = 0xCAFED00D;
3193  check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3194  0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
3195 
3196  /* This is an example of the dst width (height) == 1 exception, explored below */
3197  expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3198  expected[16] = 0x00000000, expected[17] = 0x00000000;
3199  check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3200  0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
3201 
3202  expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
3203  expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
3204  check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3205  0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3206 
3207  expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
3208  expected[16] = 0xFEEDFACE, expected[17] = 0xCAFED00D;
3209  check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3210  1, 1, -2, -2, 0, 0, 2, 2, expected, __LINE__);
3211 
3212  expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3213  expected[16] = 0x00000000, expected[17] = 0x00000000;
3214  todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3215  1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
3216 
3217  expected[0] = 0x00000000, expected[1] = 0x00000000;
3218  expected[16] = 0x00000000, expected[17] = 0xCAFED00D, expected[18] = 0xFEEDFACE;
3219  expected[32] = 0x00000000, expected[33] = 0xFEDCBA98, expected[34] = 0x76543210;
3220 
3221  check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3222  1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3223 
3224  /* when dst width is 1 merge src width - 1 pixels */
3225  memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
3226  srcBuffer[0] = 0x0000ff00, srcBuffer[1] = 0x0000f0f0, srcBuffer[2] = 0x0000cccc, srcBuffer[3] = 0x0000aaaa;
3227  srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
3228 
3229  memset( expected, 0, get_dib_image_size( &biDst ) );
3230  expected[0] = srcBuffer[0];
3231  check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3232  0, 0, 1, 1, 0, 0, 2, 1, expected, __LINE__);
3233 
3234  expected[0] = srcBuffer[0] & srcBuffer[1];
3235  check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3236  0, 0, 1, 1, 0, 0, 3, 1, expected, __LINE__);
3237 
3238  expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
3239  check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3240  0, 0, 1, 1, 0, 0, 4, 1, expected, __LINE__);
3241 
3242  /* this doesn't happen if the src width is -ve */
3243  expected[0] = srcBuffer[1] & srcBuffer[2];
3244  check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3245  0, 0, 1, 1, 2, 0, -2, 1, expected, __LINE__);
3246 
3247  /* when dst width > 1 behaviour reverts to what one would expect */
3248  expected[0] = srcBuffer[0] & srcBuffer[1], expected[1] = srcBuffer[2] & srcBuffer[3];
3249  check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3250  0, 0, 2, 1, 0, 0, 4, 1, expected, __LINE__);
3251 
3252  /* similarly in the vertical direction */
3253  memset( expected, 0, get_dib_image_size( &biDst ) );
3254  expected[0] = srcBuffer[0];
3255  check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3256  0, 0, 1, 1, 0, 0, 1, 2, expected, __LINE__);
3257 
3258  /* check that it's the dst size in device units that needs to be 1 */
3259  SetMapMode( hdcDst, MM_ISOTROPIC );
3260  SetWindowExtEx( hdcDst, 200, 200, NULL );
3261  SetViewportExtEx( hdcDst, 100, 100, NULL );
3262 
3263  expected[0] = srcBuffer[0] & srcBuffer[1] & srcBuffer[2];
3264  check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3265  0, 0, 2, 2, 0, 0, 4, 1, expected, __LINE__);
3266  SetMapMode( hdcDst, MM_TEXT );
3267 
3268  SelectObject(hdcDst, oldDst);
3269  DeleteObject(bmpDst);
3270 
3271  /* Top-down to bottom-up tests */
3272  memset( srcBuffer, 0, get_dib_image_size( &biSrc ) );
3273  srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3274  srcBuffer[16] = 0xFEDCBA98, srcBuffer[17] = 0x76543210;
3275 
3276  biDst.bmiHeader.biHeight = 16;
3277  bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3278  NULL, 0);
3279  oldDst = SelectObject(hdcDst, bmpDst);
3280 
3281  memset( expected, 0, get_dib_image_size( &biDst ) );
3282 
3283  expected[224] = 0xFEDCBA98, expected[225] = 0x76543210;
3284  expected[240] = 0xCAFED00D, expected[241] = 0xFEEDFACE;
3285  check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3286  0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3287 
3288  expected[224] = 0xFEEDFACE, expected[225] = 0xCAFED00D;
3289  expected[240] = 0x76543210, expected[241] = 0xFEDCBA98;
3290  check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3291  0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3292 
3293  SelectObject(hdcSrc, oldSrc);
3294  DeleteObject(bmpSrc);
3295 
3296  /* Bottom-up to bottom-up tests */
3297  biSrc.bmiHeader.biHeight = 16;
3298  bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
3299  NULL, 0);
3300  srcBuffer[224] = 0xCAFED00D, srcBuffer[225] = 0xFEEDFACE;
3301  srcBuffer[240] = 0xFEDCBA98, srcBuffer[241] = 0x76543210;
3302  oldSrc = SelectObject(hdcSrc, bmpSrc);
3303 
3304  memset( expected, 0, get_dib_image_size( &biDst ) );
3305 
3306  expected[224] = 0xCAFED00D, expected[225] = 0xFEEDFACE;
3307  expected[240] = 0xFEDCBA98, expected[241] = 0x76543210;
3308  check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3309  0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3310 
3311  expected[224] = 0x76543210, expected[225] = 0xFEDCBA98;
3312  expected[240] = 0xFEEDFACE, expected[241] = 0xCAFED00D;
3313  check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3314  0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3315 
3316  SelectObject(hdcDst, oldDst);
3317  DeleteObject(bmpDst);
3318 
3319  /* Bottom-up to top-down tests */
3320  biDst.bmiHeader.biHeight = -16;
3321  bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3322  NULL, 0);
3323  oldDst = SelectObject(hdcDst, bmpDst);
3324 
3325  memset( expected, 0, get_dib_image_size( &biDst ) );
3326  expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3327  expected[16] = 0xCAFED00D, expected[17] = 0xFEEDFACE;
3328  check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3329  0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3330 
3331  expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3332  expected[16] = 0x76543210, expected[17] = 0xFEDCBA98;
3333  check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer,
3334  0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3335 
3336  SelectObject(hdcSrc, oldSrc);
3337  DeleteObject(bmpSrc);
3338 
3339  biSrc.bmiHeader.biHeight = -2;
3340  biSrc.bmiHeader.biBitCount = 24;
3341  bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3342  oldSrc = SelectObject(hdcSrc, bmpSrc);
3343 
3344  memset( expected, 0, get_dib_image_size( &biDst ) );
3345  expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3346  expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3347  memcpy(dstBuffer, expected, 4 * sizeof(*dstBuffer));
3348  StretchBlt(hdcSrc, 0, 0, 4, 1, hdcDst, 0, 0, 4, 1, SRCCOPY );
3349  memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3350  StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3351  expected[0] = 0x00EDFACE, expected[1] = 0x00FED00D;
3352  expected[2] = 0x00543210, expected[3] = 0x00DCBA98;
3353  ok(!memcmp(dstBuffer, expected, 16),
3354  "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3355  expected[0], expected[1], expected[2], expected[3],
3356  dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3357 
3358  expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
3359  expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
3360  memcpy(srcBuffer, expected, 4 * sizeof(*dstBuffer));
3361  memset(dstBuffer, 0x55, 4 * sizeof(*dstBuffer));
3362  StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3363  expected[0] = 0x00EDFACE, expected[1] = 0x00D00DFE;
3364  expected[2] = 0x0010CAFE, expected[3] = 0x00765432;
3365  ok(!memcmp(dstBuffer, expected, 16),
3366  "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3367  expected[0], expected[1], expected[2], expected[3],
3368  dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3369 
3370  SelectObject(hdcSrc, oldSrc);
3371  DeleteObject(bmpSrc);
3372 
3373  biSrc.bmiHeader.biBitCount = 1;
3374  bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer, NULL, 0);
3375  oldSrc = SelectObject(hdcSrc, bmpSrc);
3376  *((DWORD *)colors + 0) = 0x123456;
3377  *((DWORD *)colors + 1) = 0x335577;
3378  SetDIBColorTable( hdcSrc, 0, 2, colors );
3379  srcBuffer[0] = 0x55555555;
3380  memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3381  SetTextColor( hdcDst, 0 );
3382  SetBkColor( hdcDst, 0 );
3383  StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3384  expected[0] = expected[2] = 0x00123456;
3385  expected[1] = expected[3] = 0x00335577;
3386  ok(!memcmp(dstBuffer, expected, 16),
3387  "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3388  expected[0], expected[1], expected[2], expected[3],
3389  dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3390 
3391  SelectObject(hdcSrc, oldSrc);
3392  DeleteObject(bmpSrc);
3393 
3394  bmpSrc = CreateBitmap( 16, 16, 1, 1, 0 );
3395  oldSrc = SelectObject(hdcSrc, bmpSrc);
3396  SetPixel( hdcSrc, 0, 0, 0 );
3397  SetPixel( hdcSrc, 1, 0, 0xffffff );
3398  SetPixel( hdcSrc, 2, 0, 0xffffff );
3399  SetPixel( hdcSrc, 3, 0, 0 );
3400  memset(dstBuffer, 0xcc, 4 * sizeof(*dstBuffer));
3401  SetTextColor( hdcDst, RGB(0x22,0x44,0x66) );
3402  SetBkColor( hdcDst, RGB(0x65,0x43,0x21) );
3403  StretchBlt(hdcDst, 0, 0, 4, 1, hdcSrc, 0, 0, 4, 1, SRCCOPY );
3404  expected[0] = expected[3] = 0x00224466;
3405  expected[1] = expected[2] = 0x00654321;
3406  ok(!memcmp(dstBuffer, expected, 16),
3407  "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X }\n",
3408  expected[0], expected[1], expected[2], expected[3],
3409  dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3] );
3410 
3411  SelectObject(hdcSrc, oldSrc);
3412  DeleteObject(bmpSrc);
3413 
3414  DeleteDC(hdcSrc);
3415 
3416  SelectObject(hdcDst, oldDst);
3417  DeleteObject(bmpDst);
3418  DeleteDC(hdcDst);
3419 
3420  DeleteDC(hdcScreen);
3421 }
3422 
3423 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3424  DWORD dwRop, UINT32 expected, int line)
3425 {
3426  const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
3427  BITMAPINFO bitmapInfo;
3428 
3429  memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3430  bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3431  bitmapInfo.bmiHeader.biWidth = 2;
3432  bitmapInfo.bmiHeader.biHeight = 1;
3433  bitmapInfo.bmiHeader.biPlanes = 1;
3434  bitmapInfo.bmiHeader.biBitCount = 32;
3435  bitmapInfo.bmiHeader.biCompression = BI_RGB;
3436  bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
3437 
3438  *dstBuffer = 0x89ABCDEF;
3439 
3440  StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
3441  ok(expected == *dstBuffer,
3442  "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
3443  dwRop, expected, *dstBuffer, line);
3444 }
3445 
3446 static INT check_StretchDIBits_stretch( HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
3447  int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
3448  int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
3449  UINT32 expected[4], int line)
3450 {
3451  BITMAPINFO bitmapInfo;
3452  INT ret;
3453 
3454  memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
3455  bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3456  bitmapInfo.bmiHeader.biWidth = 2;
3457  bitmapInfo.bmiHeader.biHeight = -2;
3458  bitmapInfo.bmiHeader.biPlanes = 1;
3459  bitmapInfo.bmiHeader.biBitCount = 32;
3460  bitmapInfo.bmiHeader.biCompression = BI_RGB;
3461 
3462  memset(dstBuffer, 0, 16);
3463  ret = StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
3464  nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3465  srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
3466  ok(memcmp(dstBuffer, expected, 16) == 0,
3467  "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
3468  "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
3469  expected[0], expected[1], expected[2], expected[3],
3470  dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
3471  nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
3472  nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
3473  return ret;
3474 }
3475 
3476 static void test_StretchDIBits(void)
3477 {
3478  HBITMAP bmpDst;
3479  HBITMAP oldDst;
3480  HDC hdcScreen, hdcDst;
3481  UINT32 *dstBuffer, srcBuffer[4];
3482  HBRUSH hBrush, hOldBrush;
3483  BITMAPINFO biDst;
3484  UINT32 expected[4];
3485  INT ret;
3486 
3487  memset(&biDst, 0, sizeof(BITMAPINFO));
3488  biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3489  biDst.bmiHeader.biWidth = 2;
3490  biDst.bmiHeader.biHeight = -2;
3491  biDst.bmiHeader.biPlanes = 1;
3492  biDst.bmiHeader.biBitCount = 32;
3493  biDst.bmiHeader.biCompression = BI_RGB;
3494 
3495  hdcScreen = CreateCompatibleDC(0);
3496  hdcDst = CreateCompatibleDC(hdcScreen);
3497 
3498  /* Pixel Tests */
3499  bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3500  NULL, 0);
3501  oldDst = SelectObject(hdcDst, bmpDst);
3502 
3503  hBrush = CreateSolidBrush(0x012345678);
3504  hOldBrush = SelectObject(hdcDst, hBrush);
3505 
3506  check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
3507  check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
3508  check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
3509  check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
3510  check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
3511  check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
3512  check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
3513  check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
3514  check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
3515  check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
3516  check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
3517  check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
3518  check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
3519  check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
3520  check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
3521 
3522  SelectObject(hdcDst, hOldBrush);
3523  DeleteObject(hBrush);
3524 
3525  /* Top-down destination tests */
3526  srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
3527  srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
3528 
3529  expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
3530  expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
3531  ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3532  0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3533  ok( ret == 2, "got ret %d\n", ret );
3534 
3535  expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
3536  expected[2] = 0x00000000, expected[3] = 0x00000000;
3537  ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3538  0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__);
3539  todo_wine ok( ret == 1, "got ret %d\n", ret );
3540 
3541  expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
3542  expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
3543  ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3544  0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__);
3545  ok( ret == 2, "got ret %d\n", ret );
3546 
3547  expected[0] = 0x42441000, expected[1] = 0x00000000;
3548  expected[2] = 0x00000000, expected[3] = 0x00000000;
3549  ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3550  0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__);
3551  ok( ret == 2, "got ret %d\n", ret );
3552 
3553  expected[0] = 0x00000000, expected[1] = 0x00000000;
3554  expected[2] = 0x00000000, expected[3] = 0x00000000;
3555  ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3556  0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3557  ok( ret == 0, "got ret %d\n", ret );
3558 
3559  expected[0] = 0x00000000, expected[1] = 0x00000000;
3560  expected[2] = 0x00000000, expected[3] = 0x00000000;
3561  ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3562  0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__);
3563  ok( ret == 0, "got ret %d\n", ret );
3564 
3565  expected[0] = 0x00000000, expected[1] = 0x00000000;
3566  expected[2] = 0x00000000, expected[3] = 0x00000000;
3567  ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3568  1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__);
3569  ok( ret == 0, "got ret %d\n", ret );
3570 
3571  expected[0] = 0x00000000, expected[1] = 0x00000000;
3572  expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
3573  ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3574  1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3575  ok( ret == 2, "got ret %d\n", ret );
3576 
3577  expected[0] = 0x00000000, expected[1] = 0x00000000;
3578  expected[2] = 0x00000000, expected[3] = 0x00000000;
3579  ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3580  2, 2, 4, 4, 0, 0, 2, 2, expected, __LINE__);
3581  ok( ret == 2, "got ret %d\n", ret );
3582 
3583  expected[0] = 0x00000000, expected[1] = 0x00000000;
3584  expected[2] = 0x00000000, expected[3] = 0x00000000;
3585  ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3586  -4, -4, 4, 4, 0, 0, 4, 4, expected, __LINE__);
3587  ok( ret == 2, "got ret %d\n", ret );
3588 
3589  SelectObject(hdcDst, oldDst);
3590  DeleteObject(bmpDst);
3591 
3592  /* Bottom up destination tests */
3593  biDst.bmiHeader.biHeight = 2;
3594  bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
3595  NULL, 0);
3596  oldDst = SelectObject(hdcDst, bmpDst);
3597 
3598  expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
3599  expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
3600  check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
3601  0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__);
3602 
3603  /* Tidy up */
3604  SelectObject(hdcDst, oldDst);
3605  DeleteObject(bmpDst);
3606  DeleteDC(hdcDst);
3607 
3608  DeleteDC(hdcScreen);
3609 }
3610 
3611 static void test_GdiAlphaBlend(void)
3612 {
3613  HDC hdcNull;
3614  HDC hdcDst;
3615  HBITMAP bmpDst;
3616  BITMAPINFO *bmi;
3617  HDC hdcSrc;
3618  HBITMAP bmpSrc;
3619  HBITMAP oldSrc;
3620  LPVOID bits;
3621  BOOL ret;
3622  BLENDFUNCTION blend;
3623 
3624  if (!pGdiAlphaBlend)
3625  {
3626  win_skip("GdiAlphaBlend() is not implemented\n");
3627  return;
3628  }
3629 
3630  hdcNull = GetDC(NULL);
3631  hdcDst = CreateCompatibleDC(hdcNull);
3632  bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
3633  hdcSrc = CreateCompatibleDC(hdcNull);
3634 
3635  bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3636  bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3637  bmi->bmiHeader.biHeight = 20;
3638  bmi->bmiHeader.biWidth = 20;
3639  bmi->bmiHeader.biBitCount = 32;
3640  bmi->bmiHeader.biPlanes = 1;
3642  bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3643  ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3644 
3645  SelectObject(hdcDst, bmpDst);
3646  oldSrc = SelectObject(hdcSrc, bmpSrc);
3647 
3648  blend.BlendOp = AC_SRC_OVER;
3649  blend.BlendFlags = 0;
3650  blend.SourceConstantAlpha = 128;
3651  blend.AlphaFormat = 0;
3652 
3653  SetLastError(0xdeadbeef);
3654  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3655  ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3656 
3657  SetLastError(0xdeadbeef);
3658  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3659  ok( !ret, "GdiAlphaBlend succeeded\n" );
3660  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3661 
3662  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3663  ok( !ret, "GdiAlphaBlend succeeded\n" );
3664  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend);
3665  ok( !ret, "GdiAlphaBlend succeeded\n" );
3666  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3667  ok( !ret, "GdiAlphaBlend succeeded\n" );
3668  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend);
3669  ok( !ret, "GdiAlphaBlend succeeded\n" );
3670 
3671  SetWindowOrgEx(hdcSrc, -10, -10, NULL);
3672  SetLastError(0xdeadbeef);
3673  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend);
3674  ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3675  SetLastError(0xdeadbeef);
3676  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend);
3677  ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3678  SetMapMode(hdcSrc, MM_ANISOTROPIC);
3679  ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
3680  SetLastError(0xdeadbeef);
3681  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend);
3682  ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3683  SetLastError(0xdeadbeef);
3684  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend);
3685  ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3686 
3687  SetMapMode(hdcDst, MM_ANISOTROPIC);
3688  SetViewportExtEx(hdcDst, -1, -1, NULL);
3689  SetLastError(0xdeadbeef);
3690  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 50, 50, blend);
3691  todo_wine
3692  ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3693  SetLastError(0xdeadbeef);
3694  ret = pGdiAlphaBlend(hdcDst, -20, -20, 20, 20, hdcSrc, 0, -1, 50, 50, blend);
3695  ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() );
3696  SetLastError(0xdeadbeef);
3697  ret = pGdiAlphaBlend(hdcDst, -20, -20, -20, -20, hdcSrc, 0, -1, 50, 50, blend);
3698  ok( !ret, "GdiAlphaBlend succeeded\n" );
3699  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3700  SetLastError(0xdeadbeef);
3701  ret = pGdiAlphaBlend(hdcDst, -20, 0, -20, 20, hdcSrc, 0, -1, 50, 50, blend);
3702  ok( !ret, "GdiAlphaBlend succeeded\n" );
3703  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3704  SetLastError(0xdeadbeef);
3705  ret = pGdiAlphaBlend(hdcDst, 0, -20, 20, -20, hdcSrc, 0, -1, 50, 50, blend);
3706  ok( !ret, "GdiAlphaBlend succeeded\n" );
3707  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3708  SetMapMode(hdcDst, MM_TEXT);
3709 
3710  SetViewportExtEx(hdcSrc, -1, -1, NULL);
3711  SetLastError(0xdeadbeef);
3712  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, -30, -30, blend);
3713  ok( !ret, "GdiAlphaBlend succeeded\n" );
3714  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3715  SetLastError(0xdeadbeef);
3716  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, 30, -30, blend);
3717  ok( !ret, "GdiAlphaBlend succeeded\n" );
3718  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3719  SetLastError(0xdeadbeef);
3720  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, -30, 30, blend);
3721  ok( !ret, "GdiAlphaBlend succeeded\n" );
3722  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3723  SetLastError(0xdeadbeef);
3724  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -20, -20, 30, 30, blend);
3725  ok( !ret, "GdiAlphaBlend succeeded\n" );
3726  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3727  SetLastError(0xdeadbeef);
3728  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 20, 20, 30, 30, blend);
3729  ok( !ret, "GdiAlphaBlend succeeded\n" );
3730  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3731  SetLastError(0xdeadbeef);
3732  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -60, -60, 30, 30, blend);
3733  ok( !ret, "GdiAlphaBlend succeeded\n" );
3734  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3735  SetViewportExtEx(hdcSrc, 1, 1, NULL);
3736 
3737  SetLastError(0xdeadbeef);
3738  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend);
3739  ok( !ret, "GdiAlphaBlend succeeded\n" );
3740  ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3741 
3742  /* overlapping source and dest not allowed */
3743 
3744  SetLastError(0xdeadbeef);
3745  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 19, 19, 20, 20, blend);
3746  ok( !ret, "GdiAlphaBlend succeeded\n" );
3747  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3748 
3749  SetLastError(0xdeadbeef);
3750  ret = pGdiAlphaBlend(hdcDst, 20, 20, 20, 20, hdcDst, 1, 1, 20, 20, blend);
3751  ok( !ret, "GdiAlphaBlend succeeded\n" );
3752  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3753 
3754  SetLastError(0xdeadbeef);
3755  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 20, 10, 20, 20, blend);
3756  ok( ret, "GdiAlphaBlend succeeded\n" );
3757  SetLastError(0xdeadbeef);
3758  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcDst, 10, 20, 20, 20, blend);
3759  ok( ret, "GdiAlphaBlend succeeded\n" );
3760 
3761  /* AC_SRC_ALPHA requires 32-bpp BI_RGB format */
3762 
3763  blend.AlphaFormat = AC_SRC_ALPHA;
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 
3769  ((DWORD *)bmi->bmiColors)[0] = 0xff0000;
3770  ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3771  ((DWORD *)bmi->bmiColors)[2] = 0x0000ff;
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 failed err %u\n", GetLastError() );
3780 
3782  ((DWORD *)bmi->bmiColors)[0] = 0x0000ff;
3783  ((DWORD *)bmi->bmiColors)[1] = 0x00ff00;
3784  ((DWORD *)bmi->bmiColors)[2] = 0xff0000;
3785  bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3786  ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3787  oldSrc = SelectObject(hdcSrc, bmpSrc);
3788  DeleteObject( oldSrc );
3789 
3790  SetLastError(0xdeadbeef);
3791  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3792  ok( !ret, "GdiAlphaBlend succeeded\n" );
3793  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3794 
3795  bmi->bmiHeader.biBitCount = 24;
3797  bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3798  ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3799  oldSrc = SelectObject(hdcSrc, bmpSrc);
3800  DeleteObject( oldSrc );
3801 
3802  SetLastError(0xdeadbeef);
3803  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3804  ok( !ret, "GdiAlphaBlend succeeded\n" );
3805  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3806 
3807  bmi->bmiHeader.biBitCount = 1;
3808  bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3809  ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3810  oldSrc = SelectObject(hdcSrc, bmpSrc);
3811  DeleteObject( oldSrc );
3812 
3813  SetLastError(0xdeadbeef);
3814  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3815  ok( !ret, "GdiAlphaBlend succeeded\n" );
3816  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3817 
3818  bmpSrc = CreateBitmap( 100, 100, 1, 1, NULL );
3819  ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3820  oldSrc = SelectObject(hdcSrc, bmpSrc);
3821  DeleteObject( oldSrc );
3822 
3823  SetLastError(0xdeadbeef);
3824  ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend);
3825  ok( !ret, "GdiAlphaBlend succeeded\n" );
3826  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3827 
3828  DeleteDC(hdcDst);
3829  DeleteDC(hdcSrc);
3830  DeleteObject(bmpSrc);
3831  DeleteObject(bmpDst);
3832 
3833  ReleaseDC(NULL, hdcNull);
3834  HeapFree(GetProcessHeap(), 0, bmi);
3835 }
3836 
3837 static void test_GdiGradientFill(void)
3838 {
3839  HDC hdc;
3840  BOOL ret;
3841  HBITMAP bmp;
3842  BITMAPINFO *bmi;
3843  void *bits;
3844  GRADIENT_RECT rect[] = { { 0, 0 }, { 0, 1 }, { 2, 3 } };
3845  GRADIENT_TRIANGLE tri[] = { { 0, 0, 0 }, { 0, 1, 2 }, { 0, 2, 1 }, { 0, 1, 3 } };
3846  TRIVERTEX vt[3] = { { 2, 2, 0xff00, 0x0000, 0x0000, 0x8000 },
3847  { 10, 10, 0x0000, 0xff00, 0x0000, 0x8000 },
3848  { 20, 10, 0x0000, 0x0000, 0xff00, 0xff00 } };
3849 
3850  if (!pGdiGradientFill)
3851  {
3852  win_skip( "GdiGradientFill is not implemented\n" );
3853  return;
3854  }
3855 
3856  hdc = CreateCompatibleDC( NULL );
3857  bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[3] ));
3858  bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
3859  bmi->bmiHeader.biHeight = 20;
3860  bmi->bmiHeader.biWidth = 20;
3861  bmi->bmiHeader.biBitCount = 32;
3862  bmi->bmiHeader.biPlanes = 1;
3864  bmp = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
3865  ok( bmp != NULL, "couldn't create bitmap\n" );
3866  SelectObject( hdc, bmp );
3867 
3868  SetLastError( 0xdeadbeef );
3869  ret = pGdiGradientFill( hdc, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3870  ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3871  SetLastError( 0xdeadbeef );
3872  ret = pGdiGradientFill( hdc, vt, 3, rect, 1, 3 );
3873  ok( !ret, "GdiGradientFill succeeded\n" );
3874  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3875  SetLastError( 0xdeadbeef );
3876  ret = pGdiGradientFill( (HDC)0xdead, vt, 3, rect, 1, GRADIENT_FILL_RECT_H );
3877  ok( !ret, "GdiGradientFill succeeded\n" );
3878  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3879  SetLastError( 0xdeadbeef );
3880  ret = pGdiGradientFill( NULL, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3881  ok( !ret, "GdiGradientFill succeeded\n" );
3882  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3883  ret = pGdiGradientFill( hdc, NULL, 0, rect, 1, GRADIENT_FILL_RECT_H );
3884  ok( !ret, "GdiGradientFill succeeded\n" );
3885  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3886  SetLastError( 0xdeadbeef );
3887  ret = pGdiGradientFill( hdc, NULL, 3, rect, 1, GRADIENT_FILL_RECT_H );
3888  ok( !ret, "GdiGradientFill succeeded\n" );
3889  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3890  SetLastError( 0xdeadbeef );
3891  ret = pGdiGradientFill( hdc, vt, 3, NULL, 0, GRADIENT_FILL_RECT_H );
3892  ok( !ret, "GdiGradientFill succeeded\n" );
3893  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3894  SetLastError( 0xdeadbeef );
3895  ret = pGdiGradientFill( hdc, vt, 3, NULL, 1, GRADIENT_FILL_RECT_H );
3896  ok( !ret, "GdiGradientFill succeeded\n" );
3897  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3898  SetLastError( 0xdeadbeef );
3899  ret = pGdiGradientFill( hdc, vt, 3, rect, 0, GRADIENT_FILL_RECT_H );
3900  ok( !ret, "GdiGradientFill succeeded\n" );
3901  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3902  SetLastError( 0xdeadbeef );
3903  ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3904  ok( !ret, "GdiGradientFill succeeded\n" );
3905  ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3906  rect[2].UpperLeft = rect[2].LowerRight = 1;
3907  SetLastError( 0xdeadbeef );
3908  ret = pGdiGradientFill( hdc, vt, 3, rect, 3, GRADIENT_FILL_RECT_H );
3909  ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3910  SetLastError( 0xdeadbeef );
3911  ret = pGdiGradientFill( hdc, vt, 1, rect, 1, GRADIENT_FILL_RECT_H );
3912  ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3913  SetLastError( 0xdeadbeef );
3914  ret = pGdiGradientFill( hdc, vt, 1, tri, 0, GRADIENT_FILL_TRIANGLE );
3915  ok( !ret, "GdiGradientFill succeeded\n" );
3916  ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3917  SetLastError( 0xdeadbeef );
3918  ret = pGdiGradientFill( hdc, vt, 1, tri, 1, GRADIENT_FILL_TRIANGLE );
3919  ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3920  SetLastError( 0xdeadbeef );
3921  ret = pGdiGradientFill( hdc, vt, 3, tri, 2, GRADIENT_FILL_TRIANGLE );
3922  ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3923  SetLastError( 0xdeadbeef );
3924  ret = pGdiGradientFill( hdc, vt, 3, tri, 3, GRADIENT_FILL_TRIANGLE );
3925  ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3926  SetLastError( 0xdeadbeef );
3927  ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3928  ok( !ret, "GdiGradientFill succeeded\n" );
3929  ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3930  tri[3].Vertex3 = 1;
3931  SetLastError( 0xdeadbeef );
3932  ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3933  ok( !ret, "GdiGradientFill succeeded\n" );
3934  ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3935  tri[3].Vertex3 = 0;
3936  SetLastError( 0xdeadbeef );
3937  ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3938  ok( !ret, "GdiGradientFill succeeded\n" );
3939  ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
3940  tri[3].Vertex1 = tri[3].Vertex2 = tri[3].Vertex3 = 1;
3941  SetLastError( 0xdeadbeef );
3942  ret = pGdiGradientFill( hdc, vt, 3, tri, 4, GRADIENT_FILL_TRIANGLE );
3943  ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3944 
3945  DeleteDC( hdc );
3946  DeleteObject( bmp );
3947  HeapFree(GetProcessHeap(), 0, bmi);
3948 }
3949 
3950 static void test_clipping(void)
3951 {
3952  HBITMAP bmpDst;
3953  HBITMAP bmpSrc;
3954  HRGN hRgn;
3955  LPVOID bits;
3956  BOOL result;
3957 
3960 
3961  BITMAPINFO bmpinfo={{0}};
3962  bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3963  bmpinfo.bmiHeader.biWidth = 100;
3964  bmpinfo.bmiHeader.biHeight = 100;
3965  bmpinfo.bmiHeader.biPlanes = 1;
3966  bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3967  bmpinfo.bmiHeader.biCompression = BI_RGB;
3968 
3969  bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3970  ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3971  SelectObject( hdcDst, bmpDst );
3972 
3973  bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3974  ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3975  SelectObject( hdcSrc, bmpSrc );
3976 
3977  result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3978  ok(result, "BitBlt failed\n");
3979 
3980  hRgn = CreateRectRgn( 0,0,0,0 );
3981  SelectClipRgn( hdcDst, hRgn );
3982 
3983  result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3984  ok(result, "BitBlt failed\n");
3985 
3986  DeleteObject( bmpDst );
3987  DeleteObject( bmpSrc );
3988  DeleteObject( hRgn );
3989  DeleteDC( hdcDst );
3990  DeleteDC( hdcSrc );
3991 }
3992 
3993 static void test_32bit_ddb(void)
3994 {
3995  char buffer[sizeof(BITMAPINFOHEADER) + sizeof(DWORD)];
3996  BITMAPINFO *biDst = (BITMAPINFO *)buffer;
3997  HBITMAP bmpSrc, bmpDst;
3998  HBITMAP oldSrc, oldDst;
3999  HDC hdcSrc, hdcDst, hdcScreen;
4000  HBRUSH brush;
4001  DWORD *dstBuffer, *data;
4002  DWORD colorSrc = 0x40201008;
4003 
4004  memset(biDst, 0, sizeof(BITMAPINFOHEADER));
4005  biDst->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
4006  biDst->bmiHeader.biWidth = 1;
4007  biDst->bmiHeader.biHeight = -1;
4008  biDst->bmiHeader.biPlanes = 1;
4009  biDst->bmiHeader.biBitCount = 32;
4010  biDst->bmiHeader.biCompression = BI_RGB;
4011 
4012  hdcScreen = CreateCompatibleDC(0);
4013  if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
4014  {
4015  DeleteDC(hdcScreen);
4016  trace("Skipping 32-bit DDB test\n");
4017  return;
4018  }
4019 
4020  hdcSrc = CreateCompatibleDC(hdcScreen);
4021  bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
4022  oldSrc = SelectObject(hdcSrc, bmpSrc);
4023 
4024