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