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