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