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