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