winex11: Always ignore alpha channel with XRender gradients.
[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, 1, tri, 0, GRADIENT_FILL_TRIANGLE );
3421     ok( !ret, "GdiGradientFill succeeded\n" );
3422     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3423     SetLastError( 0xdeadbeef );
3424     ret = pGdiGradientFill( hdc, vt, 1, tri, 1, GRADIENT_FILL_TRIANGLE );
3425     ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3426     SetLastError( 0xdeadbeef );
3427     ret = pGdiGradientFill( hdc, vt, 3, tri, 2, GRADIENT_FILL_TRIANGLE );
3428     ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3429     SetLastError( 0xdeadbeef );
3430     ret = pGdiGradientFill( hdc, vt, 3, tri, 3, GRADIENT_FILL_TRIANGLE );
3431     ok( ret, "GdiGradientFill failed err %u\n", GetLastError() );
3432
3433     DeleteDC( hdc );
3434     DeleteObject( bmp );
3435 }
3436
3437 static void test_clipping(void)
3438 {
3439     HBITMAP bmpDst;
3440     HBITMAP bmpSrc;
3441     HRGN hRgn;
3442     LPVOID bits;
3443     BOOL result;
3444
3445     HDC hdcDst = CreateCompatibleDC( NULL );
3446     HDC hdcSrc = CreateCompatibleDC( NULL );
3447
3448     BITMAPINFO bmpinfo={{0}};
3449     bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3450     bmpinfo.bmiHeader.biWidth = 100;
3451     bmpinfo.bmiHeader.biHeight = 100;
3452     bmpinfo.bmiHeader.biPlanes = 1;
3453     bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
3454     bmpinfo.bmiHeader.biCompression = BI_RGB;
3455
3456     bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3457     ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
3458     SelectObject( hdcDst, bmpDst );
3459
3460     bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
3461     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
3462     SelectObject( hdcSrc, bmpSrc );
3463
3464     result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
3465     ok(result, "BitBlt failed\n");
3466
3467     hRgn = CreateRectRgn( 0,0,0,0 );
3468     SelectClipRgn( hdcDst, hRgn );
3469
3470     result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
3471     ok(result, "BitBlt failed\n");
3472
3473     DeleteObject( bmpDst );
3474     DeleteObject( bmpSrc );
3475     DeleteObject( hRgn );
3476     DeleteDC( hdcDst );
3477     DeleteDC( hdcSrc );
3478 }
3479
3480 static void test_32bit_bitmap_blt(void)
3481 {
3482     BITMAPINFO biDst;
3483     HBITMAP bmpSrc, bmpDst;
3484     HBITMAP oldSrc, oldDst;
3485     HDC hdcSrc, hdcDst, hdcScreen;
3486     UINT32 *dstBuffer;
3487     DWORD colorSrc = 0x11223344;
3488
3489     memset(&biDst, 0, sizeof(BITMAPINFO));
3490     biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3491     biDst.bmiHeader.biWidth = 2;
3492     biDst.bmiHeader.biHeight = -2;
3493     biDst.bmiHeader.biPlanes = 1;
3494     biDst.bmiHeader.biBitCount = 32;
3495     biDst.bmiHeader.biCompression = BI_RGB;
3496
3497     hdcScreen = CreateCompatibleDC(0);
3498     if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
3499     {
3500         DeleteDC(hdcScreen);
3501         trace("Skipping 32-bit DDB test\n");
3502         return;
3503     }
3504
3505     hdcSrc = CreateCompatibleDC(hdcScreen);
3506     bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
3507     oldSrc = SelectObject(hdcSrc, bmpSrc);
3508
3509     hdcDst = CreateCompatibleDC(hdcScreen);
3510     bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
3511     oldDst = SelectObject(hdcDst, bmpDst);
3512
3513     StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
3514     ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
3515
3516     /* Tidy up */
3517     SelectObject(hdcDst, oldDst);
3518     DeleteObject(bmpDst);
3519     DeleteDC(hdcDst);
3520
3521     SelectObject(hdcSrc, oldSrc);
3522     DeleteObject(bmpSrc);
3523     DeleteDC(hdcSrc);
3524
3525     DeleteDC(hdcScreen);
3526 }
3527
3528 /*
3529  * Used by test_GetDIBits_top_down to create the bitmap to test against.
3530  */
3531 static void setup_picture(char *picture, int bpp)
3532 {
3533     int i;
3534
3535     switch(bpp)
3536     {
3537         case 16:
3538         case 32:
3539             /*Set the first byte in each pixel to the index of that pixel.*/
3540             for (i = 0; i < 4; i++)
3541                 picture[i * (bpp / 8)] = i;
3542             break;
3543         case 24:
3544             picture[0] = 0;
3545             picture[3] = 1;
3546             /*Each scanline in a bitmap must be a multiple of 4 bytes long.*/
3547             picture[8] = 2;
3548             picture[11] = 3;
3549             break;
3550     }
3551 }
3552
3553 static void test_GetDIBits_top_down(int bpp)
3554 {
3555     BITMAPINFO bi;
3556     HBITMAP bmptb, bmpbt;
3557     HDC hdc;
3558     int pictureOut[4];
3559     int *picture;
3560     int statusCode;
3561
3562     memset( &bi, 0, sizeof(bi) );
3563     bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
3564     bi.bmiHeader.biWidth=2;
3565     bi.bmiHeader.biHeight=2;
3566     bi.bmiHeader.biPlanes=1;
3567     bi.bmiHeader.biBitCount=bpp;
3568     bi.bmiHeader.biCompression=BI_RGB;
3569
3570     /*Get the device context for the screen.*/
3571     hdc = GetDC(NULL);
3572     ok(hdc != NULL, "Could not get a handle to a device context.\n");
3573
3574     /*Create the bottom to top image (image's bottom scan line is at the top in memory).*/
3575     bmpbt = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3576     ok(bmpbt != NULL, "Could not create a DIB section.\n");
3577     /*Now that we have a pointer to the pixels, we write to them.*/
3578     setup_picture((char*)picture, bpp);
3579     /*Create the top to bottom image (images' bottom scan line is at the bottom in memory).*/
3580     bi.bmiHeader.biHeight=-2; /*We specify that we want a top to bottom image by specifying a negative height.*/
3581     bmptb = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&picture, NULL, 0);
3582     ok(bmptb != NULL, "Could not create a DIB section.\n");
3583     /*Write to this top to bottom bitmap.*/
3584     setup_picture((char*)picture, bpp);
3585
3586     bi.bmiHeader.biWidth = 1;
3587
3588     bi.bmiHeader.biHeight = 2;
3589     statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3590     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3591     /*Check the first byte of the pixel.*/
3592     ok((char)pictureOut[0] == 0, "Bottom-up -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3593     statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3594     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3595     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3596     /*Check second scanline.*/
3597     statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3598     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3599     ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3600     statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3601     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3602     ok((char)pictureOut[0] == 2, "Bottom-up -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3603     /*Check both scanlines.*/
3604     statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3605     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3606     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3607     ok((char)pictureOut[1] == 0, "Top-down -> bottom-up: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3608     statusCode = GetDIBits(hdc, bmpbt, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3609     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3610     ok((char)pictureOut[0] == 0, "Bottom up -> bottom-up: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3611     ok((char)pictureOut[1] == 2, "Bottom up -> bottom-up: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3612
3613     /*Make destination bitmap top-down.*/
3614     bi.bmiHeader.biHeight = -2;
3615     statusCode = GetDIBits(hdc, bmpbt, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3616     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3617     ok((char)pictureOut[0] == 0, "Bottom-up -> top-down: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3618     statusCode = GetDIBits(hdc, bmptb, 0, 1, pictureOut, &bi, DIB_RGB_COLORS);
3619     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3620     ok((char)pictureOut[0] == 2, "Top-down -> top-down: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3621     /*Check second scanline.*/
3622     statusCode = GetDIBits(hdc, bmptb, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3623     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3624     ok((char)pictureOut[0] == 0, "Top-down -> bottom-up: first pixel should be 0 but was %d.\n", (char)pictureOut[0]);
3625     statusCode = GetDIBits(hdc, bmpbt, 1, 1, pictureOut, &bi, DIB_RGB_COLORS);
3626     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3627     ok((char)pictureOut[0] == 2, "Top-down -> bottom-up: first pixel should be 2 but was %d.\n", (char)pictureOut[0]);
3628     /*Check both scanlines.*/
3629     statusCode = GetDIBits(hdc, bmptb, 0, 2, pictureOut, &bi, DIB_RGB_COLORS);
3630     ok(statusCode, "Failed to call GetDIBits. Status code: %d.\n", statusCode);
3631     ok((char)pictureOut[0] == 0, "Top-down -> top-down: first scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3632     ok((char)pictureOut[1] == 2, "Top-down -> top-down: second scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3633     statusCode = GetDIBits(hdc, bmpbt, 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, "Bottom up -> top-down: first scanline should be 2 but was %d.\n", (char)pictureOut[0]);
3636     ok((char)pictureOut[1] == 0, "Bottom up -> top-down: second scanline should be 0 but was %d.\n", (char)pictureOut[0]);
3637
3638     DeleteObject(bmpbt);
3639     DeleteObject(bmptb);
3640 }
3641
3642 static void test_GetSetDIBits_rtl(void)
3643 {
3644     HDC hdc, hdc_mem;
3645     HBITMAP bitmap, orig_bitmap;
3646     BITMAPINFO info;
3647     int ret;
3648     DWORD bits_1[8 * 8], bits_2[8 * 8];
3649
3650     if(!pSetLayout)
3651     {
3652         win_skip("Don't have SetLayout\n");
3653         return;
3654     }
3655
3656     hdc = GetDC( NULL );
3657     hdc_mem = CreateCompatibleDC( hdc );
3658     pSetLayout( hdc_mem, LAYOUT_LTR );
3659
3660     bitmap = CreateCompatibleBitmap( hdc, 8, 8 );
3661     orig_bitmap = SelectObject( hdc_mem, bitmap );
3662     SetPixel( hdc_mem, 0, 0, RGB(0xff, 0, 0) );
3663     SelectObject( hdc_mem, orig_bitmap );
3664
3665     info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3666     info.bmiHeader.biWidth = 8;
3667     info.bmiHeader.biHeight = 8;
3668     info.bmiHeader.biPlanes = 1;
3669     info.bmiHeader.biBitCount = 32;
3670     info.bmiHeader.biCompression = BI_RGB;
3671
3672     /* First show that GetDIBits ignores the layout mode. */
3673
3674     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3675     ok(ret == 8, "got %d\n", ret);
3676     ok(bits_1[56] == 0xff0000, "got %08x\n", bits_1[56]); /* check we have a red pixel */
3677
3678     pSetLayout( hdc_mem, LAYOUT_RTL );
3679
3680     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3681     ok(ret == 8, "got %d\n", ret);
3682
3683     ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3684
3685     /* Now to show that SetDIBits also ignores the mode, we perform a SetDIBits
3686        followed by a GetDIBits and show that the bits remain unchanged. */
3687
3688     pSetLayout( hdc_mem, LAYOUT_LTR );
3689
3690     ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3691     ok(ret == 8, "got %d\n", ret);
3692     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3693     ok(ret == 8, "got %d\n", ret);
3694     ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3695
3696     pSetLayout( hdc_mem, LAYOUT_RTL );
3697
3698     ret = SetDIBits( hdc_mem, bitmap, 0, 8, bits_1, &info, DIB_RGB_COLORS );
3699     ok(ret == 8, "got %d\n", ret);
3700     ret = GetDIBits( hdc_mem, bitmap, 0, 8, bits_2, &info, DIB_RGB_COLORS );
3701     ok(ret == 8, "got %d\n", ret);
3702     ok(!memcmp( bits_1, bits_2, sizeof(bits_1) ), "bits differ\n");
3703
3704     DeleteObject( bitmap );
3705     DeleteDC( hdc_mem );
3706     ReleaseDC( NULL, hdc );
3707 }
3708
3709 static void test_GetDIBits_scanlines(void)
3710 {
3711     BITMAPINFO *info;
3712     DWORD *dib_bits;
3713     HDC hdc = GetDC( NULL );
3714     HBITMAP dib;
3715     DWORD data[128], inverted_bits[64];
3716     int i, ret;
3717
3718     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
3719
3720     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
3721     info->bmiHeader.biWidth       = 8;
3722     info->bmiHeader.biHeight      = 8;
3723     info->bmiHeader.biPlanes      = 1;
3724     info->bmiHeader.biBitCount    = 32;
3725     info->bmiHeader.biCompression = BI_RGB;
3726
3727     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3728
3729     for (i = 0; i < 64; i++)
3730     {
3731         dib_bits[i] = i;
3732         inverted_bits[56 - (i & ~7) + (i & 7)] = i;
3733     }
3734
3735     /* b-u -> b-u */
3736
3737     memset( data, 0xaa, sizeof(data) );
3738
3739     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3740     ok( ret == 8, "got %d\n", ret );
3741     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3742     memset( data, 0xaa, sizeof(data) );
3743
3744     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3745     ok( ret == 5, "got %d\n", ret );
3746     ok( !memcmp( data, dib_bits + 8, 40 * 4 ), "bits differ\n");
3747     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3748     memset( data, 0xaa, sizeof(data) );
3749
3750     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3751     ok( ret == 7, "got %d\n", ret );
3752     ok( !memcmp( data, dib_bits + 8, 56 * 4 ), "bits differ\n");
3753     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3754     memset( data, 0xaa, sizeof(data) );
3755
3756     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3757     ok( ret == 1, "got %d\n", ret );
3758     for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3759     memset( data, 0xaa, sizeof(data) );
3760
3761     info->bmiHeader.biHeight = 16;
3762     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3763     ok( ret == 5, "got %d\n", ret );
3764     for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3765     ok( !memcmp( data + 56, dib_bits, 40 * 4 ), "bits differ\n");
3766     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3767     memset( data, 0xaa, sizeof(data) );
3768
3769     ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
3770     ok( ret == 6, "got %d\n", ret );
3771     for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3772     ok( !memcmp( data + 48, dib_bits, 48 * 4 ), "bits differ\n");
3773     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3774     memset( data, 0xaa, sizeof(data) );
3775
3776     ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
3777     ok( ret == 0, "got %d\n", ret );
3778     for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3779     for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3780     memset( data, 0xaa, sizeof(data) );
3781
3782     info->bmiHeader.biHeight = 5;
3783     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3784     ok( ret == 2, "got %d\n", ret );
3785     ok( !memcmp( data, dib_bits + 32, 16 * 4 ), "bits differ\n");
3786     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3787     memset( data, 0xaa, sizeof(data) );
3788
3789     /* b-u -> t-d */
3790
3791     info->bmiHeader.biHeight = -8;
3792     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3793     ok( ret == 8, "got %d\n", ret );
3794     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3795     memset( data, 0xaa, sizeof(data) );
3796
3797     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3798     ok( ret == 5, "got %d\n", ret );
3799     ok( !memcmp( data, inverted_bits + 16, 40 * 4 ), "bits differ\n");
3800     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3801     memset( data, 0xaa, sizeof(data) );
3802
3803     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3804     ok( ret == 7, "got %d\n", ret );
3805     ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3806     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3807     memset( data, 0xaa, sizeof(data) );
3808
3809     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3810     ok( ret == 4, "got %d\n", ret );
3811     ok( !memcmp( data, inverted_bits, 32 * 4 ), "bits differ\n");
3812     for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3813     memset( data, 0xaa, sizeof(data) );
3814
3815     ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3816     ok( ret == 5, "got %d\n", ret );
3817     ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3818     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3819     memset( data, 0xaa, sizeof(data) );
3820
3821     ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3822     ok( ret == 5, "got %d\n", ret );
3823     ok( !memcmp( data, inverted_bits, 40 * 4 ), "bits differ\n");
3824     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3825     memset( data, 0xaa, sizeof(data) );
3826
3827     info->bmiHeader.biHeight = -16;
3828     ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3829     ok( ret == 8, "got %d\n", ret );
3830     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3831     for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3832     memset( data, 0xaa, sizeof(data) );
3833
3834     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3835     ok( ret == 5, "got %d\n", ret );
3836     ok( !memcmp( data, inverted_bits + 24, 40 * 4 ), "bits differ\n");
3837     for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3838     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3839     memset( data, 0xaa, sizeof(data) );
3840
3841     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3842     ok( ret == 8, "got %d\n", ret );
3843     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3844     for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3845     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3846     memset( data, 0xaa, sizeof(data) );
3847
3848     ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3849     ok( ret == 8, "got %d\n", ret );
3850     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3851     for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3852     for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3853     memset( data, 0xaa, sizeof(data) );
3854
3855     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3856     ok( ret == 7, "got %d\n", ret );
3857     ok( !memcmp( data, inverted_bits, 56 * 4 ), "bits differ\n");
3858     for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3859     memset( data, 0xaa, sizeof(data) );
3860
3861     ret = GetDIBits( hdc, dib, 18, 12, data, info, DIB_RGB_COLORS );
3862     ok( ret == 1, "got %d\n", ret );
3863     for (i = 0; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3864     memset( data, 0xaa, sizeof(data) );
3865
3866     info->bmiHeader.biHeight = -5;
3867     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3868     ok( ret == 2, "got %d\n", ret );
3869     ok( !memcmp( data, inverted_bits + 16, 16 * 4 ), "bits differ\n");
3870     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3871     memset( data, 0xaa, sizeof(data) );
3872
3873     DeleteObject( dib );
3874
3875     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
3876     info->bmiHeader.biWidth       = 8;
3877     info->bmiHeader.biHeight      = -8;
3878     info->bmiHeader.biPlanes      = 1;
3879     info->bmiHeader.biBitCount    = 32;
3880     info->bmiHeader.biCompression = BI_RGB;
3881
3882     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
3883
3884     for (i = 0; i < 64; i++) dib_bits[i] = i;
3885
3886     /* t-d -> t-d */
3887
3888     info->bmiHeader.biHeight = -8;
3889     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3890     ok( ret == 8, "got %d\n", ret );
3891     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3892     memset( data, 0xaa, sizeof(data) );
3893
3894     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3895     ok( ret == 5, "got %d\n", ret );
3896     ok( !memcmp( data, dib_bits + 16, 40 * 4 ), "bits differ\n");
3897     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3898     memset( data, 0xaa, sizeof(data) );
3899
3900     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3901     ok( ret == 7, "got %d\n", ret );
3902     ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3903     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3904     memset( data, 0xaa, sizeof(data) );
3905
3906     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3907     ok( ret == 4, "got %d\n", ret );
3908     ok( !memcmp( data, dib_bits, 32 * 4 ), "bits differ\n");
3909     for (i = 32; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3910     memset( data, 0xaa, sizeof(data) );
3911
3912     ret = GetDIBits( hdc, dib, 3, 12, data, info, DIB_RGB_COLORS );
3913     ok( ret == 5, "got %d\n", ret );
3914     ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3915     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3916     memset( data, 0xaa, sizeof(data) );
3917
3918     ret = GetDIBits( hdc, dib, 3, 13, data, info, DIB_RGB_COLORS );
3919     ok( ret == 5, "got %d\n", ret );
3920     ok( !memcmp( data, dib_bits, 40 * 4 ), "bits differ\n");
3921     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3922     memset( data, 0xaa, sizeof(data) );
3923
3924     info->bmiHeader.biHeight = -16;
3925     ret = GetDIBits( hdc, dib, 0, 16, data, info, DIB_RGB_COLORS );
3926     ok( ret == 8, "got %d\n", ret );
3927     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3928     for (i = 64; i < 128; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3929     memset( data, 0xaa, sizeof(data) );
3930
3931     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3932     ok( ret == 5, "got %d\n", ret );
3933     ok( !memcmp( data, dib_bits + 24, 40 * 4 ), "bits differ\n");
3934     for (i = 40; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3935     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3936     memset( data, 0xaa, sizeof(data) );
3937
3938     ret = GetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
3939     ok( ret == 8, "got %d\n", ret );
3940     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3941     for (i = 64; i < 96; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3942     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3943     memset( data, 0xaa, sizeof(data) );
3944
3945     ret = GetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
3946     ok( ret == 8, "got %d\n", ret );
3947     ok( !memcmp( data, dib_bits, 64 * 4 ), "bits differ\n");
3948     for (i = 64; i < 88; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3949     for (i = 88; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3950     memset( data, 0xaa, sizeof(data) );
3951
3952     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3953     ok( ret == 7, "got %d\n", ret );
3954     ok( !memcmp( data, dib_bits, 56 * 4 ), "bits differ\n");
3955     for (i = 56; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3956     memset( data, 0xaa, sizeof(data) );
3957
3958     info->bmiHeader.biHeight = -5;
3959     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
3960     ok( ret == 2, "got %d\n", ret );
3961     ok( !memcmp( data, dib_bits + 16, 16 * 4 ), "bits differ\n");
3962     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3963     memset( data, 0xaa, sizeof(data) );
3964
3965
3966     /* t-d -> b-u */
3967
3968     info->bmiHeader.biHeight = 8;
3969
3970     ret = GetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
3971     ok( ret == 8, "got %d\n", ret );
3972     ok( !memcmp( data, inverted_bits, 64 * 4 ), "bits differ\n");
3973     memset( data, 0xaa, sizeof(data) );
3974
3975     ret = GetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
3976     ok( ret == 5, "got %d\n", ret );
3977     ok( !memcmp( data, inverted_bits + 8, 40 * 4 ), "bits differ\n");
3978     for (i = 40; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3979     memset( data, 0xaa, sizeof(data) );
3980
3981     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3982     ok( ret == 7, "got %d\n", ret );
3983     ok( !memcmp( data, inverted_bits + 8, 56 * 4 ), "bits differ\n");
3984     for (i = 56; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3985     memset( data, 0xaa, sizeof(data) );
3986
3987     ret = GetDIBits( hdc, dib, 9, 12, data, info, DIB_RGB_COLORS );
3988     ok( ret == 1, "got %d\n", ret );
3989     for (i = 0; i < 64; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3990     memset( data, 0xaa, sizeof(data) );
3991
3992     info->bmiHeader.biHeight = 16;
3993     ret = GetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
3994     ok( ret == 5, "got %d\n", ret );
3995     for (i = 0; i < 56; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
3996     ok( !memcmp( data + 56, inverted_bits, 40 * 4 ), "bits differ\n");
3997     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
3998     memset( data, 0xaa, sizeof(data) );
3999
4000     ret = GetDIBits( hdc, dib, 2, 12, data, info, DIB_RGB_COLORS );
4001     ok( ret == 6, "got %d\n", ret );
4002     for (i = 0; i < 48; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4003     ok( !memcmp( data + 48, inverted_bits, 48 * 4 ), "bits differ\n");
4004     for (i = 96; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4005     memset( data, 0xaa, sizeof(data) );
4006
4007     ret = GetDIBits( hdc, dib, 2, 3, data, info, DIB_RGB_COLORS );
4008     ok( ret == 0, "got %d\n", ret );
4009     for (i = 0; i < 24; i++) ok( data[i] == 0, "%d: got %08x\n", i, data[i] );
4010     for (i = 24; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4011     memset( data, 0xaa, sizeof(data) );
4012
4013     info->bmiHeader.biHeight = 5;
4014     ret = GetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4015     ok( ret == 2, "got %d\n", ret );
4016     ok( !memcmp( data, inverted_bits + 32, 16 * 4 ), "bits differ\n");
4017     for (i = 16; i < 128; i++) ok( data[i] == 0xaaaaaaaa, "%d: got %08x\n", i, data[i] );
4018     memset( data, 0xaa, sizeof(data) );
4019
4020     DeleteObject( dib );
4021
4022     ReleaseDC( NULL, hdc );
4023     HeapFree( GetProcessHeap(), 0, info );
4024 }
4025
4026
4027 static void test_SetDIBits(void)
4028 {
4029     BITMAPINFO *info;
4030     DWORD *dib_bits;
4031     HDC hdc = GetDC( NULL );
4032     DWORD data[128], inverted_data[128];
4033     HBITMAP dib;
4034     int i, ret;
4035
4036     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4037
4038     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4039     info->bmiHeader.biWidth       = 8;
4040     info->bmiHeader.biHeight      = 8;
4041     info->bmiHeader.biPlanes      = 1;
4042     info->bmiHeader.biBitCount    = 32;
4043     info->bmiHeader.biCompression = BI_RGB;
4044
4045     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4046     memset( dib_bits, 0xaa, 64 * 4 );
4047
4048     for (i = 0; i < 128; i++)
4049     {
4050         data[i] = i;
4051         inverted_data[120 - (i & ~7) + (i & 7)] = i;
4052     }
4053
4054     /* b-u -> b-u */
4055
4056     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4057     ok( ret == 8, "got %d\n", ret );
4058     ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4059     memset( dib_bits, 0xaa, 64 * 4 );
4060
4061     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4062     ok( ret == 5, "got %d\n", ret );
4063     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4064     ok( !memcmp( dib_bits + 8, data, 40 * 4 ), "bits differ\n");
4065     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4066     memset( dib_bits, 0xaa, 64 * 4 );
4067
4068     /* top of dst is aligned with startscans down for the top of the src.
4069        Then starting from the bottom of src, lines rows are copied across. */
4070
4071     info->bmiHeader.biHeight = 16;
4072     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4073     ok( ret == 12, "got %d\n", ret );
4074     ok( !memcmp( dib_bits, data + 56,  40 * 4 ), "bits differ\n");
4075     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4076     memset( dib_bits, 0xaa, 64 * 4 );
4077
4078     info->bmiHeader.biHeight = 5;
4079     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4080     ok( ret == 2, "got %d\n", ret );
4081     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4082     ok( !memcmp( dib_bits + 32, data,  16 * 4 ), "bits differ\n");
4083     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4084     memset( dib_bits, 0xaa, 64 * 4 );
4085
4086     /* t-d -> b-u */
4087     info->bmiHeader.biHeight = -8;
4088     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4089     ok( ret == 8, "got %d\n", ret );
4090     ok( !memcmp( dib_bits, inverted_data + 64,  64 * 4 ), "bits differ\n");
4091     memset( dib_bits, 0xaa, 64 * 4 );
4092
4093     /* top of dst now lines up with -(abs(src_h) - startscan - lines) and
4094        we copy lines rows from the top of the src */
4095
4096     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4097     ok( ret == 5, "got %d\n", ret );
4098     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4099     ok( !memcmp( dib_bits + 8, inverted_data + 88, 40 * 4 ), "bits differ\n");
4100     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4101     memset( dib_bits, 0xaa, 64 * 4 );
4102
4103     info->bmiHeader.biHeight = -16;
4104     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4105     ok( ret == 12, "got %d\n", ret );
4106     ok( !memcmp( dib_bits, inverted_data + 88, 40 * 4 ), "bits differ\n");
4107     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4108     memset( dib_bits, 0xaa, 64 * 4 );
4109
4110     ret = SetDIBits( hdc, dib, 4, 12, data, info, DIB_RGB_COLORS );
4111     ok( ret == 12, "got %d\n", ret );
4112     ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4113     memset( dib_bits, 0xaa, 64 * 4 );
4114
4115     ret = SetDIBits( hdc, dib, 5, 12, data, info, DIB_RGB_COLORS );
4116     ok( ret == 12, "got %d\n", ret );
4117     ok( !memcmp( dib_bits, inverted_data + 56, 64 * 4 ), "bits differ\n");
4118     memset( dib_bits, 0xaa, 64 * 4 );
4119
4120     info->bmiHeader.biHeight = -5;
4121     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4122     ok( ret == 2, "got %d\n", ret );
4123     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4124     ok( !memcmp( dib_bits + 32, inverted_data + 112, 16 * 4 ), "bits differ\n");
4125     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4126     memset( dib_bits, 0xaa, 64 * 4 );
4127
4128     DeleteObject( dib );
4129
4130     info->bmiHeader.biHeight = -8;
4131
4132     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4133     memset( dib_bits, 0xaa, 16 * 16 * 4 );
4134
4135     /* t-d -> t-d */
4136
4137     /* like the t-d -> b-u case. */
4138
4139     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4140     ok( ret == 8, "got %d\n", ret );
4141     ok( !memcmp( dib_bits, data, 64 * 4 ), "bits differ\n");
4142     memset( dib_bits, 0xaa, 64 * 4 );
4143
4144     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4145     ok( ret == 5, "got %d\n", ret );
4146     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4147     ok( !memcmp( dib_bits + 16, data, 40 * 4 ), "bits differ\n");
4148     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4149     memset( dib_bits, 0xaa, 64 * 4 );
4150
4151     info->bmiHeader.biHeight = -16;
4152     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4153     ok( ret == 12, "got %d\n", ret );
4154     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4155     ok( !memcmp( dib_bits + 24, data,  40 * 4 ), "bits differ\n");
4156     memset( dib_bits, 0xaa, 64 * 4 );
4157
4158     info->bmiHeader.biHeight = -5;
4159     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4160     ok( ret == 2, "got %d\n", ret );
4161     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4162     ok( !memcmp( dib_bits + 16, data,  16 * 4 ), "bits differ\n");
4163     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4164     memset( dib_bits, 0xaa, 64 * 4 );
4165
4166     /* b-u -> t-d */
4167     /* like the b-u -> b-u case */
4168
4169     info->bmiHeader.biHeight = 8;
4170     ret = SetDIBits( hdc, dib, 0, 8, data, info, DIB_RGB_COLORS );
4171     ok( ret == 8, "got %d\n", ret );
4172     ok( !memcmp( dib_bits, inverted_data + 64, 64 * 4 ), "bits differ\n");
4173     memset( dib_bits, 0xaa, 64 * 4 );
4174
4175     ret = SetDIBits( hdc, dib, 1, 5, data, info, DIB_RGB_COLORS );
4176     ok( ret == 5, "got %d\n", ret );
4177     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4178     ok( !memcmp( dib_bits + 16, inverted_data + 88, 40 * 4 ), "bits differ\n");
4179     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4180     memset( dib_bits, 0xaa, 64 * 4 );
4181
4182     info->bmiHeader.biHeight = 16;
4183     ret = SetDIBits( hdc, dib, 1, 12, data, info, DIB_RGB_COLORS );
4184     ok( ret == 12, "got %d\n", ret );
4185     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4186     ok( !memcmp( dib_bits + 24, inverted_data + 32, 40 * 4 ), "bits differ\n");
4187     memset( dib_bits, 0xaa, 64 * 4 );
4188
4189     info->bmiHeader.biHeight = 5;
4190     ret = SetDIBits( hdc, dib, 1, 2, data, info, DIB_RGB_COLORS );
4191     ok( ret == 2, "got %d\n", ret );
4192     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4193     ok( !memcmp( dib_bits + 16, inverted_data + 112, 16 * 4 ), "bits differ\n");
4194     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4195     memset( dib_bits, 0xaa, 64 * 4 );
4196
4197     DeleteObject( dib );
4198     ReleaseDC( NULL, hdc );
4199     HeapFree( GetProcessHeap(), 0, info );
4200 }
4201
4202 static void test_SetDIBits_RLE4(void)
4203 {
4204     BITMAPINFO *info;
4205     DWORD *dib_bits;
4206     HDC hdc = GetDC( NULL );
4207     BYTE rle4_data[26] = { 0x03, 0x52, 0x07, 0x68, 0x00, 0x00,     /* 5, 2, 5, 6, 8, 6, 8, 6, (8, 6,) <eol> */
4208                            0x00, 0x03, 0x14, 0x50, 0x00, 0x05,
4209                            0x79, 0xfd, 0xb0, 0x00, 0x00, 0x00,     /* 1, 4, 5, 7, 9, f, d, b <pad> <eol> */
4210                            0x00, 0x02, 0x01, 0x02, 0x05, 0x87,     /* dx=1, dy=2, 8, 7, 8, 7, 8 */
4211                            0x00, 0x01 };                           /* <eod> */
4212     HBITMAP dib;
4213     int i, ret;
4214     DWORD bottom_up[64] = { 0x00050505, 0x00020202, 0x00050505, 0x00060606, 0x00080808, 0x00060606, 0x00080808, 0x00060606,
4215                             0x00010101, 0x00040404, 0x00050505, 0x00070707, 0x00090909, 0x000f0f0f, 0x000d0d0d, 0x000b0b0b,
4216                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4217                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4218                             0xaaaaaaaa, 0x00080808, 0x00070707, 0x00080808, 0x00070707, 0x00080808, 0xaaaaaaaa, 0xaaaaaaaa,
4219                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4220                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4221                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4222
4223     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4224
4225     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4226     info->bmiHeader.biWidth       = 8;
4227     info->bmiHeader.biHeight      = 8;
4228     info->bmiHeader.biPlanes      = 1;
4229     info->bmiHeader.biBitCount    = 32;
4230     info->bmiHeader.biCompression = BI_RGB;
4231
4232     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4233     memset( dib_bits, 0xaa, 64 * 4 );
4234
4235     info->bmiHeader.biBitCount    = 4;
4236     info->bmiHeader.biCompression = BI_RLE4;
4237     info->bmiHeader.biSizeImage   = sizeof(rle4_data);
4238
4239     for (i = 0; i < 16; i++)
4240     {
4241         info->bmiColors[i].rgbRed      = i;
4242         info->bmiColors[i].rgbGreen    = i;
4243         info->bmiColors[i].rgbBlue     = i;
4244         info->bmiColors[i].rgbReserved = 0;
4245     }
4246
4247     ret = SetDIBits( hdc, dib, 0, 8, rle4_data, info, DIB_RGB_COLORS );
4248     ok( ret == 8, "got %d\n", ret );
4249     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n" );
4250     memset( dib_bits, 0xaa, 64 * 4 );
4251
4252     DeleteObject( dib );
4253     ReleaseDC( NULL, hdc );
4254     HeapFree( GetProcessHeap(), 0, info );
4255 }
4256
4257 static void test_SetDIBits_RLE8(void)
4258 {
4259     BITMAPINFO *info;
4260     DWORD *dib_bits;
4261     HDC hdc = GetDC( NULL );
4262     BYTE rle8_data[20] = { 0x03, 0x02, 0x04, 0xf0, 0x00, 0x00,     /* 2, 2, 2, f0, f0, f0, f0, <eol> */
4263                            0x00, 0x03, 0x04, 0x05, 0x06, 0x00,     /* 4, 5, 6, <pad> */
4264                            0x00, 0x02, 0x01, 0x02, 0x05, 0x80,     /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4265                            0x00, 0x01 };                           /* <eod> */
4266     HBITMAP dib;
4267     int i, ret;
4268     DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4269                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4270                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4271                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4272                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4273                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4274                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4275                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4276     DWORD top_down[64]  = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4277                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4278                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4279                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4280                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4281                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4282                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4283                             0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4284
4285     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4286
4287     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4288     info->bmiHeader.biWidth       = 8;
4289     info->bmiHeader.biHeight      = 8;
4290     info->bmiHeader.biPlanes      = 1;
4291     info->bmiHeader.biBitCount    = 32;
4292     info->bmiHeader.biCompression = BI_RGB;
4293
4294     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4295     memset( dib_bits, 0xaa, 64 * 4 );
4296
4297     info->bmiHeader.biBitCount    = 8;
4298     info->bmiHeader.biCompression = BI_RLE8;
4299     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
4300
4301     for (i = 0; i < 256; i++)
4302     {
4303         info->bmiColors[i].rgbRed      = i;
4304         info->bmiColors[i].rgbGreen    = i;
4305         info->bmiColors[i].rgbBlue     = i;
4306         info->bmiColors[i].rgbReserved = 0;
4307     }
4308
4309     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4310     ok( ret == 8, "got %d\n", ret );
4311     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4312     memset( dib_bits, 0xaa, 64 * 4 );
4313
4314     /* startscan and lines are ignored, unless lines == 0 */
4315     ret = SetDIBits( hdc, dib, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4316     ok( ret == 8, "got %d\n", ret );
4317     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4318     memset( dib_bits, 0xaa, 64 * 4 );
4319
4320     ret = SetDIBits( hdc, dib, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4321     ok( ret == 8, "got %d\n", ret );
4322     ok( !memcmp( dib_bits, bottom_up, sizeof(bottom_up) ), "bits differ\n");
4323     memset( dib_bits, 0xaa, 64 * 4 );
4324
4325     ret = SetDIBits( hdc, dib, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4326     ok( ret == 0, "got %d\n", ret );
4327     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4328     memset( dib_bits, 0xaa, 64 * 4 );
4329
4330     /* reduce width to 4, left-hand side of dst is touched. */
4331     info->bmiHeader.biWidth = 4;
4332     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4333     ok( ret == 8, "got %d\n", ret );
4334     for (i = 0; i < 64; i++)
4335     {
4336         DWORD expect = (i & 4) ? 0xaaaaaaaa : bottom_up[i];
4337         ok( dib_bits[i] == expect, "%d: got %08x\n", i, dib_bits[i] );
4338     }
4339     memset( dib_bits, 0xaa, 64 * 4 );
4340
4341     /* Show that the top lines are aligned by adjusting the height of the src */
4342
4343     /* reduce the height to 4 -> top 4 lines of dst are touched (corresponding to last half of the bits). */
4344     info->bmiHeader.biWidth  = 8;
4345     info->bmiHeader.biHeight = 4;
4346     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4347     ok( ret == 4, "got %d\n", ret );
4348     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4349     ok( !memcmp( dib_bits + 32, bottom_up, 32 * 4 ), "bits differ\n");
4350     memset( dib_bits, 0xaa, 64 * 4 );
4351
4352     /* increase the height to 9 -> everything moves down one row. */
4353     info->bmiHeader.biHeight = 9;
4354     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4355     ok( ret == 9, "got %d\n", ret );
4356     ok( !memcmp( dib_bits, bottom_up + 8, 56 * 4 ), "bits differ\n");
4357     for (i = 0; i < 8; i++) ok( dib_bits[56 + i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[56 + i] );
4358     memset( dib_bits, 0xaa, 64 * 4 );
4359
4360     /* top-down compressed dibs are invalid */
4361     info->bmiHeader.biHeight = -8;
4362     SetLastError( 0xdeadbeef );
4363     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4364     ok( ret == 0, "got %d\n", ret );
4365     ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4366     DeleteObject( dib );
4367
4368     /* top-down dst */
4369
4370     info->bmiHeader.biHeight      = -8;
4371     info->bmiHeader.biBitCount    = 32;
4372     info->bmiHeader.biCompression = BI_RGB;
4373     info->bmiHeader.biSizeImage   = 0;
4374
4375     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4376     memset( dib_bits, 0xaa, 16 * 16 * 4 );
4377
4378     info->bmiHeader.biHeight      = 8;
4379     info->bmiHeader.biBitCount    = 8;
4380     info->bmiHeader.biCompression = BI_RLE8;
4381     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
4382
4383     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4384     ok( ret == 8, "got %d\n", ret );
4385     ok( !memcmp( dib_bits, top_down, sizeof(top_down) ), "bits differ\n");
4386     memset( dib_bits, 0xaa, 64 * 4 );
4387
4388     info->bmiHeader.biHeight = 4;
4389     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4390     ok( ret == 4, "got %d\n", ret );
4391     ok( !memcmp( dib_bits, top_down + 32, 32 * 4 ), "bits differ\n");
4392     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4393     memset( dib_bits, 0xaa, 64 * 4 );
4394
4395     info->bmiHeader.biHeight = 9;
4396     ret = SetDIBits( hdc, dib, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4397     ok( ret == 9, "got %d\n", ret );
4398     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4399     ok( !memcmp( dib_bits + 8, top_down, 56 * 4 ), "bits differ\n");
4400     memset( dib_bits, 0xaa, 64 * 4 );
4401
4402     DeleteObject( dib );
4403     ReleaseDC( NULL, hdc );
4404     HeapFree( GetProcessHeap(), 0, info );
4405 }
4406
4407 static void test_SetDIBitsToDevice(void)
4408 {
4409     BITMAPINFO *info;
4410     DWORD *dib_bits;
4411     HDC hdc = CreateCompatibleDC( 0 );
4412     DWORD data[128], inverted_data[128];
4413     HBITMAP dib;
4414     int i, ret;
4415
4416     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4417
4418     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4419     info->bmiHeader.biWidth       = 8;
4420     info->bmiHeader.biHeight      = 8;
4421     info->bmiHeader.biPlanes      = 1;
4422     info->bmiHeader.biBitCount    = 32;
4423     info->bmiHeader.biCompression = BI_RGB;
4424
4425     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4426     memset( dib_bits, 0xaa, 64 * 4 );
4427     SelectObject( hdc, dib );
4428
4429     for (i = 0; i < 128; i++)
4430     {
4431         data[i] = i;
4432         inverted_data[120 - (i & ~7) + (i & 7)] = i;
4433     }
4434
4435     /* b-u -> b-u */
4436
4437     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4438     ok( ret == 8, "got %d\n", ret );
4439     for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4440     memset( dib_bits, 0xaa, 64 * 4 );
4441
4442     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4443     ok( ret == 5, "got %d\n", ret );
4444     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4445     for (i = 8; i < 48; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4446     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4447     memset( dib_bits, 0xaa, 64 * 4 );
4448
4449     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 3, 1, 5, data, info, DIB_RGB_COLORS );
4450     ok( ret == 5, "got %d\n", ret );
4451     for (i = 0; i < 24; i++) ok( dib_bits[i] == data[i + 16], "%d: got %08x\n", i, dib_bits[i] );
4452     for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4453     memset( dib_bits, 0xaa, 64 * 4 );
4454
4455     info->bmiHeader.biHeight = 16;
4456     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4457     ok( ret == 7, "got %d\n", ret );
4458     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4459     for (i = 8; i < 64; i++) ok( dib_bits[i] == data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4460     memset( dib_bits, 0xaa, 64 * 4 );
4461
4462     ret = SetDIBitsToDevice( hdc, 0, 2, 8, 8, 0, 6, 1, 12, data, info, DIB_RGB_COLORS );
4463     ok( ret == 12, "got %d\n", ret );
4464     for (i = 0; i < 40; i++) ok( dib_bits[i] == data[i + 56], "%d: got %08x\n", i, dib_bits[i] );
4465     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4466     memset( dib_bits, 0xaa, 64 * 4 );
4467
4468     ret = SetDIBitsToDevice( hdc, 0, -4, 8, 8, 0, 3, 1, 12, data, info, DIB_RGB_COLORS );
4469     ok( ret == 10, "got %d\n", ret );
4470     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4471     for (i = 32; i < 64; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4472     memset( dib_bits, 0xaa, 64 * 4 );
4473
4474     ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, -3, 1, 12, data, info, DIB_RGB_COLORS );
4475     ok( ret == 4, "got %d\n", ret );
4476     for (i = 0; i < 32; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4477     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4478     memset( dib_bits, 0xaa, 64 * 4 );
4479
4480     ret = SetDIBitsToDevice( hdc, 0, 2, 8, 5, 0, -2, 1, 12, data, info, DIB_RGB_COLORS );
4481     ok( ret == 2, "got %d\n", ret );
4482     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4483     for (i = 32; i < 48; i++) ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4484     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4485     memset( dib_bits, 0xaa, 64 * 4 );
4486
4487     info->bmiHeader.biHeight = 5;
4488     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 2, 2, data, info, DIB_RGB_COLORS );
4489     ok( ret == 2, "got %d\n", ret );
4490     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4491     for (i = 16; i < 32; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4492     for (i = 32; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4493     memset( dib_bits, 0xaa, 64 * 4 );
4494
4495     ret = SetDIBitsToDevice( hdc, 3, 3, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4496     ok( ret == 3, "got %d\n", ret );
4497     for (i = 0; i < 64; i++)
4498         if (i == 27 || i == 28 || i == 35 || i == 36)
4499             ok( dib_bits[i] == data[i - 18], "%d: got %08x\n", i, dib_bits[i] );
4500         else
4501             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4502     memset( dib_bits, 0xaa, 64 * 4 );
4503
4504     ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4505     ok( ret == 5, "got %d\n", ret );
4506     for (i = 0; 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, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4510     ok( ret == 0, "got %d\n", ret );
4511     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4512     memset( dib_bits, 0xaa, 64 * 4 );
4513
4514     SetMapMode( hdc, MM_ANISOTROPIC );
4515     SetWindowExtEx( hdc, 3, 3, NULL );
4516     ret = SetDIBitsToDevice( hdc, 2, 2, 2, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4517     ok( ret == 3, "got %d\n", ret );
4518     for (i = 0; i < 64; i++)
4519         if (i == 41 || i == 42 || i == 49 || i == 50)
4520             ok( dib_bits[i] == data[i - 32], "%d: got %08x\n", i, dib_bits[i] );
4521         else
4522             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4523     memset( dib_bits, 0xaa, 64 * 4 );
4524
4525     SetWindowExtEx( hdc, -1, -1, NULL );
4526     ret = SetDIBitsToDevice( hdc, 2, 2, 4, 4, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4527     ok( ret == 4, "got %d\n", ret );
4528     for (i = 0; i < 64; i++)
4529         if (i == 48 || i == 49 || i == 56 || i == 57)
4530             ok( dib_bits[i] == data[i - 37], "%d: got %08x\n", i, dib_bits[i] );
4531         else
4532             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4533     memset( dib_bits, 0xaa, 64 * 4 );
4534     SetMapMode( hdc, MM_TEXT );
4535
4536     if (pSetLayout)
4537     {
4538         pSetLayout( hdc, LAYOUT_RTL );
4539         ret = SetDIBitsToDevice( hdc, 1, 2, 3, 2, 1, 2, 1, 5, data, info, DIB_RGB_COLORS );
4540         ok( ret == 3, "got %d\n", ret );
4541         for (i = 0; i < 64; i++)
4542             if (i == 36 || i == 37 || i == 38 || i == 44 || i == 45 || i == 46)
4543                 ok( dib_bits[i] == data[i - 27], "%d: got %08x\n", i, dib_bits[i] );
4544             else
4545                 ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4546         memset( dib_bits, 0xaa, 64 * 4 );
4547         pSetLayout( hdc, LAYOUT_LTR );
4548     }
4549
4550     /* t-d -> b-u */
4551     info->bmiHeader.biHeight = -8;
4552     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4553     ok( ret == 8, "got %d\n", ret );
4554     for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4555     memset( dib_bits, 0xaa, 64 * 4 );
4556
4557     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4558     ok( ret == 5, "got %d\n", ret );
4559     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4560     for (i = 8; i < 48; i++) ok( dib_bits[i] == inverted_data[i + 80], "%d: got %08x\n", i, dib_bits[i] );
4561     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4562     memset( dib_bits, 0xaa, 64 * 4 );
4563
4564     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 4, 1, 5, data, info, DIB_RGB_COLORS );
4565     ok( ret == 5, "got %d\n", ret );
4566     for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4567     for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4568     memset( dib_bits, 0xaa, 64 * 4 );
4569
4570     info->bmiHeader.biHeight = -16;
4571     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4572     ok( ret == 12, "got %d\n", ret );
4573     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4574     for (i = 8; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4575     memset( dib_bits, 0xaa, 64 * 4 );
4576
4577     ret = SetDIBitsToDevice( hdc, 0, 4, 8, 8, 0, 7, 1, 12, data, info, DIB_RGB_COLORS );
4578     ok( ret == 12, "got %d\n", ret );
4579     for (i = 0; i < 16; i++) ok( dib_bits[i] == inverted_data[i + 112], "%d: got %08x\n", i, dib_bits[i] );
4580     for (i = 16; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4581     memset( dib_bits, 0xaa, 64 * 4 );
4582
4583     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 4, 12, data, info, DIB_RGB_COLORS );
4584     ok( ret == 12, "got %d\n", ret );
4585     for (i = 0; i < 32; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4586     for (i = 32; i < 64; i++) ok( dib_bits[i] == inverted_data[i], "%d: got %08x\n", i, dib_bits[i] );
4587     memset( dib_bits, 0xaa, 64 * 4 );
4588
4589     ret = SetDIBitsToDevice( hdc, 0, -3, 8, 8, 0, 2, 4, 12, data, info, DIB_RGB_COLORS );
4590     ok( ret == 12, "got %d\n", ret );
4591     for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4592     for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4593     memset( dib_bits, 0xaa, 64 * 4 );
4594
4595     ret = SetDIBitsToDevice( hdc, 0, 3, 8, 8, 0, -2, 4, 12, data, info, DIB_RGB_COLORS );
4596     ok( ret == 12, "got %d\n", ret );
4597     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4598     for (i = 24; i < 40; i++) ok( dib_bits[i] == inverted_data[i + 8], "%d: got %08x\n", i, dib_bits[i] );
4599     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4600     memset( dib_bits, 0xaa, 64 * 4 );
4601
4602     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 5, 12, data, info, DIB_RGB_COLORS );
4603     ok( ret == 12, "got %d\n", ret );
4604     for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4605     for (i = 40; i < 64; i++) ok( dib_bits[i] == inverted_data[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4606     memset( dib_bits, 0xaa, 64 * 4 );
4607
4608     ret = SetDIBitsToDevice( hdc, 0, 2, 8, 4, 0, -1, 3, 12, data, info, DIB_RGB_COLORS );
4609     ok( ret == 12, "got %d\n", ret );
4610     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4611     memset( dib_bits, 0xaa, 64 * 4 );
4612
4613     ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS );
4614     ok( ret == 12, "got %d\n", ret );
4615     for (i = 0; i < 64; i++)
4616         if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63)
4617             ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] );
4618         else
4619             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4620     memset( dib_bits, 0xaa, 64 * 4 );
4621
4622     info->bmiHeader.biHeight = -5;
4623     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4624     ok( ret == 2, "got %d\n", ret );
4625     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4626     for (i = 8; i < 24; i++) ok( dib_bits[i] == inverted_data[i + 104], "%d: got %08x\n", i, dib_bits[i] );
4627     for (i = 24; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4628     memset( dib_bits, 0xaa, 64 * 4 );
4629
4630     ret = SetDIBitsToDevice( hdc, 5, 4, 2, 2, 6, 3, 1, 5, data, info, DIB_RGB_COLORS );
4631     ok( ret == 5, "got %d\n", ret );
4632     for (i = 0; i < 64; i++)
4633         if (i == 21 || i == 22 || i == 29 || i == 30)
4634             ok( dib_bits[i] == inverted_data[i + 89], "%d: got %08x\n", i, dib_bits[i] );
4635         else
4636             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4637     memset( dib_bits, 0xaa, 64 * 4 );
4638
4639     ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4640     ok( ret == 5, "got %d\n", ret );
4641     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4642     memset( dib_bits, 0xaa, 64 * 4 );
4643
4644     info->bmiHeader.biHeight = -8;
4645
4646     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4647     DeleteObject( SelectObject( hdc, dib ));
4648     memset( dib_bits, 0xaa, 16 * 16 * 4 );
4649
4650     /* t-d -> t-d */
4651
4652     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4653     ok( ret == 8, "got %d\n", ret );
4654     for (i = 0; i < 64; i++) ok( dib_bits[i] == data[i], "%d: got %08x\n", i, dib_bits[i] );
4655     memset( dib_bits, 0xaa, 64 * 4 );
4656
4657     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4658     ok( ret == 5, "got %d\n", ret );
4659     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4660     for (i = 16; i < 56; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4661     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4662     memset( dib_bits, 0xaa, 64 * 4 );
4663
4664     ret = SetDIBitsToDevice( hdc, 0, 3, 8, 3, 0, 2, 1, 5, data, info, DIB_RGB_COLORS );
4665     ok( ret == 5, "got %d\n", ret );
4666     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4667     for (i = 24; i < 48; i++) ok( dib_bits[i] == data[i - 16], "%d: got %08x\n", i, dib_bits[i] );
4668     for (i = 48; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4669     memset( dib_bits, 0xaa, 64 * 4 );
4670
4671     info->bmiHeader.biHeight = -16;
4672     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4673     ok( ret == 12, "got %d\n", ret );
4674     for (i = 0; i < 56; i++) ok( dib_bits[i] == data[i + 40], "%d: got %08x\n", i, dib_bits[i] );
4675     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4676     memset( dib_bits, 0xaa, 64 * 4 );
4677
4678     ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS );
4679     ok( ret == 12, "got %d\n", ret );
4680     for (i = 0; i < 64; i++)
4681         if (i == 6 || i == 7)
4682             ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] );
4683         else
4684             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4685     memset( dib_bits, 0xaa, 64 * 4 );
4686
4687     info->bmiHeader.biHeight = -5;
4688     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4689     ok( ret == 2, "got %d\n", ret );
4690     for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4691     for (i = 40; i < 56; i++) ok( dib_bits[i] == data[i - 40], "%d: got %08x\n", i, dib_bits[i] );
4692     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4693     memset( dib_bits, 0xaa, 64 * 4 );
4694
4695     ret = SetDIBitsToDevice( hdc, 7, 2, 8, 8, 1, 0, 0, 5, data, info, DIB_RGB_COLORS );
4696     ok( ret == 5, "got %d\n", ret );
4697     for (i = 0; i < 64; i++)
4698         if (i == 47 || i == 55 || i == 63)
4699             ok( dib_bits[i] == data[i - 46], "%d: got %08x\n", i, dib_bits[i] );
4700         else
4701             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4702     memset( dib_bits, 0xaa, 64 * 4 );
4703
4704     ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4705     ok( ret == 5, "got %d\n", ret );
4706     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4707     memset( dib_bits, 0xaa, 64 * 4 );
4708
4709     /* b-u -> t-d */
4710
4711     info->bmiHeader.biHeight = 8;
4712     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, data, info, DIB_RGB_COLORS );
4713     ok( ret == 8, "got %d\n", ret );
4714     for (i = 0; i < 64; i++) ok( dib_bits[i] == inverted_data[i + 64], "%d: got %08x\n", i, dib_bits[i] );
4715     memset( dib_bits, 0xaa, 64 * 4 );
4716
4717     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 5, data, info, DIB_RGB_COLORS );
4718     ok( ret == 5, "got %d\n", ret );
4719     for (i = 0; i < 16; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4720     for (i = 16; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%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     info->bmiHeader.biHeight = 16;
4725     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 12, data, info, DIB_RGB_COLORS );
4726     ok( ret == 7, "got %d\n", ret );
4727     for (i = 0; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4728     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4729     memset( dib_bits, 0xaa, 64 * 4 );
4730
4731     ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS );
4732     ok( ret == 3, "got %d\n", ret );
4733     for (i = 0; i < 64; i++)
4734         if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55))
4735             ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] );
4736         else
4737             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4738     memset( dib_bits, 0xaa, 64 * 4 );
4739
4740     ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS );
4741     ok( ret == 0, "got %d\n", ret );
4742     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4743     memset( dib_bits, 0xaa, 64 * 4 );
4744
4745     ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS );
4746     ok( ret == 8, "got %d\n", ret );
4747     for (i = 0; i < 64; i++)
4748         if (i == 7 || i == 15 || i == 23)
4749             ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] );
4750         else
4751             ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4752     memset( dib_bits, 0xaa, 64 * 4 );
4753
4754     info->bmiHeader.biHeight = 5;
4755     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS );
4756     ok( ret == 2, "got %d\n", ret );
4757     for (i = 0; i < 40; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4758     for (i = 40; i < 56; i++) ok( dib_bits[i] == inverted_data[i + 72], "%d: got %08x\n", i, dib_bits[i] );
4759     for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4760     memset( dib_bits, 0xaa, 64 * 4 );
4761
4762     ret = SetDIBitsToDevice( hdc, 0, 0, 16, 16, 0, 0, 0, 5, data, info, DIB_RGB_COLORS );
4763     ok( ret == 5, "got %d\n", ret );
4764     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4765     memset( dib_bits, 0xaa, 64 * 4 );
4766
4767     DeleteDC( hdc );
4768     DeleteObject( dib );
4769     HeapFree( GetProcessHeap(), 0, info );
4770 }
4771
4772 static void test_SetDIBitsToDevice_RLE8(void)
4773 {
4774     BITMAPINFO *info;
4775     DWORD *dib_bits;
4776     HDC hdc = CreateCompatibleDC( 0 );
4777     BYTE rle8_data[20] = { 0x04, 0x02, 0x03, 0xf0, 0x00, 0x00,     /* 2, 2, 2, 2, f0, f0, f0, <eol> */
4778                            0x00, 0x03, 0x04, 0x05, 0x06, 0x00,     /* 4, 5, 6, <pad> */
4779                            0x00, 0x02, 0x01, 0x02, 0x05, 0x80,     /* dx=1, dy=2, 80, 80, 80, 80, (80) */
4780                            0x00, 0x01 };                           /* <eod> */
4781     HBITMAP dib;
4782     int i, ret;
4783     DWORD bottom_up[64] = { 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa,
4784                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4785                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4786                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4787                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4788                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4789                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4790                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa };
4791     DWORD top_down[64]  = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4792                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4793                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4794                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4795                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x00808080, 0x00808080, 0x00808080, 0x00808080,
4796                             0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4797                             0x00040404, 0x00050505, 0x00060606, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
4798                             0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00f0f0f0, 0x00f0f0f0, 0x00f0f0f0, 0xaaaaaaaa };
4799
4800     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
4801
4802     info->bmiHeader.biSize        = sizeof(info->bmiHeader);
4803     info->bmiHeader.biWidth       = 8;
4804     info->bmiHeader.biHeight      = 8;
4805     info->bmiHeader.biPlanes      = 1;
4806     info->bmiHeader.biBitCount    = 32;
4807     info->bmiHeader.biCompression = BI_RGB;
4808
4809     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4810     memset( dib_bits, 0xaa, 64 * 4 );
4811     SelectObject( hdc, dib );
4812
4813     info->bmiHeader.biBitCount    = 8;
4814     info->bmiHeader.biCompression = BI_RLE8;
4815     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
4816
4817     for (i = 0; i < 256; i++)
4818     {
4819         info->bmiColors[i].rgbRed      = i;
4820         info->bmiColors[i].rgbGreen    = i;
4821         info->bmiColors[i].rgbBlue     = i;
4822         info->bmiColors[i].rgbReserved = 0;
4823     }
4824
4825     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4826     ok( ret == 8, "got %d\n", ret );
4827     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4828     memset( dib_bits, 0xaa, 64 * 4 );
4829
4830     /* startscan and lines are ignored, unless lines == 0 */
4831     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 8, rle8_data, info, DIB_RGB_COLORS );
4832     ok( ret == 8, "got %d\n", ret );
4833     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4834     memset( dib_bits, 0xaa, 64 * 4 );
4835
4836     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 1, rle8_data, info, DIB_RGB_COLORS );
4837     ok( ret == 8, "got %d\n", ret );
4838     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4839     memset( dib_bits, 0xaa, 64 * 4 );
4840
4841     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 0, rle8_data, info, DIB_RGB_COLORS );
4842     ok( ret == 0, "got %d\n", ret );
4843     for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4844     memset( dib_bits, 0xaa, 64 * 4 );
4845
4846     info->bmiHeader.biWidth = 2;
4847     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4848     ok( ret == 8, "got %d\n", ret );
4849     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4850     memset( dib_bits, 0xaa, 64 * 4 );
4851
4852     info->bmiHeader.biWidth  = 8;
4853     info->bmiHeader.biHeight = 2;
4854     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4855     ok( ret == 2, "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     info->bmiHeader.biHeight = 9;
4860     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4861     ok( ret == 9, "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, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4866     ok( ret == 9, "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     info->bmiHeader.biHeight = 8;
4871     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 9, rle8_data, info, DIB_RGB_COLORS );
4872     ok( ret == 8, "got %d\n", ret );
4873     for (i = 0; i < 64; i++) ok( dib_bits[i] == bottom_up[i], "%d: got %08x\n", i, dib_bits[i] );
4874     memset( dib_bits, 0xaa, 64 * 4 );
4875
4876     ret = SetDIBitsToDevice( hdc, 0, 3, 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 < 40; i++) ok( dib_bits[i] == bottom_up[i + 24], "%d: got %08x\n", i, dib_bits[i] );
4879     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4880     memset( dib_bits, 0xaa, 64 * 4 );
4881
4882     ret = SetDIBitsToDevice( hdc, 0, 3, 4, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4883     ok( ret == 8, "got %d\n", ret );
4884     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4885     for (i = 8; i < 40; i++)
4886         if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4887         else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4888     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4889     memset( dib_bits, 0xaa, 64 * 4 );
4890
4891     ret = SetDIBitsToDevice( hdc, 3, 3, 8, 4, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4892     ok( ret == 8, "got %d\n", ret );
4893     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4894     for (i = 8; i < 40; i++)
4895         if ((i & 7) < 3) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4896         else ok( dib_bits[i] == bottom_up[i - 11], "%d: got %08x\n", i, dib_bits[i] );
4897     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4898     memset( dib_bits, 0xaa, 64 * 4 );
4899
4900     ret = SetDIBitsToDevice( hdc, 2, 3, 8, 4, 2, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4901     ok( ret == 8, "got %d\n", ret );
4902     for (i = 0; i < 8; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4903     for (i = 8; i < 40; i++)
4904         if ((i & 7) < 2) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4905         else ok( dib_bits[i] == bottom_up[i - 8], "%d: got %08x\n", i, dib_bits[i] );
4906     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4907     memset( dib_bits, 0xaa, 64 * 4 );
4908
4909     info->bmiHeader.biWidth = 37;
4910     info->bmiHeader.biHeight = 37;
4911     ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4912     ok( ret == 37, "got %d\n", ret );
4913     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4914     for (i = 24; i < 64; i++)
4915         if (i == 52) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4916         else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4917         else ok( dib_bits[i] == bottom_up[i - 20], "%d: got %08x\n", i, dib_bits[i] );
4918     memset( dib_bits, 0xaa, 64 * 4 );
4919
4920     /* top-down compressed dibs are invalid */
4921     info->bmiHeader.biWidth = 8;
4922     info->bmiHeader.biHeight = -8;
4923     SetLastError( 0xdeadbeef );
4924     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4925     ok( ret == 0, "got %d\n", ret );
4926     ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %x\n", GetLastError() );
4927
4928     /* top-down dst */
4929
4930     info->bmiHeader.biHeight      = -8;
4931     info->bmiHeader.biBitCount    = 32;
4932     info->bmiHeader.biCompression = BI_RGB;
4933     info->bmiHeader.biSizeImage   = 0;
4934
4935     dib = CreateDIBSection( NULL, info, DIB_RGB_COLORS, (void**)&dib_bits, NULL, 0 );
4936     memset( dib_bits, 0xaa, 16 * 16 * 4 );
4937     DeleteObject( SelectObject( hdc, dib ));
4938
4939     info->bmiHeader.biHeight      = 8;
4940     info->bmiHeader.biBitCount    = 8;
4941     info->bmiHeader.biCompression = BI_RLE8;
4942     info->bmiHeader.biSizeImage   = sizeof(rle8_data);
4943
4944     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4945     ok( ret == 8, "got %d\n", ret );
4946     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4947     memset( dib_bits, 0xaa, 64 * 4 );
4948
4949     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4950     ok( ret == 8, "got %d\n", ret );
4951     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4952     memset( dib_bits, 0xaa, 64 * 4 );
4953
4954     info->bmiHeader.biHeight = 4;
4955     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4956     ok( ret == 4, "got %d\n", ret );
4957     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4958     memset( dib_bits, 0xaa, 64 * 4 );
4959
4960     info->bmiHeader.biHeight = 9;
4961     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4962     ok( ret == 9, "got %d\n", ret );
4963     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4964     memset( dib_bits, 0xaa, 64 * 4 );
4965
4966     ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 0, 9, rle8_data, info, DIB_RGB_COLORS );
4967     ok( ret == 9, "got %d\n", ret );
4968     for (i = 0; i < 64; i++) ok( dib_bits[i] == top_down[i], "%d: got %08x\n", i, dib_bits[i] );
4969     memset( dib_bits, 0xaa, 64 * 4 );
4970
4971     ret = SetDIBitsToDevice( hdc, 2, 3, 8, 6, 2, 2, 0, 8, rle8_data, info, DIB_RGB_COLORS );
4972     ok( ret == 9, "got %d\n", ret );
4973     for (i = 0; i < 24; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4974     for (i = 24; i < 64; i++) ok( dib_bits[i] == top_down[i - 24], "%d: got %08x\n", i, dib_bits[i] );
4975     memset( dib_bits, 0xaa, 64 * 4 );
4976
4977     info->bmiHeader.biWidth = 37;
4978     info->bmiHeader.biHeight = 37;
4979     ret = SetDIBitsToDevice( hdc, -2, 1, 10, 5, 2, -1, 12, 24, rle8_data, info, DIB_RGB_COLORS );
4980     ok( ret == 37, "got %d\n", ret );
4981     for (i = 0; i < 40; i++)
4982         if (i == 12) ok( dib_bits[i] == 0x00808080, "%d: got %08x\n", i, dib_bits[i] );
4983         else if (i & 4) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4984         else ok( dib_bits[i] == top_down[i + 28], "%d: got %08x\n", i, dib_bits[i] );
4985     for (i = 40; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] );
4986     memset( dib_bits, 0xaa, 64 * 4 );
4987
4988     DeleteDC( hdc );
4989     DeleteObject( dib );
4990     HeapFree( GetProcessHeap(), 0, info );
4991 }
4992
4993 START_TEST(bitmap)
4994 {
4995     HMODULE hdll;
4996
4997     hdll = GetModuleHandle("gdi32.dll");
4998     pGdiAlphaBlend   = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
4999     pGdiGradientFill = (void*)GetProcAddress(hdll, "GdiGradientFill");
5000     pSetLayout       = (void*)GetProcAddress(hdll, "SetLayout");
5001
5002     test_createdibitmap();
5003     test_dibsections();
5004     test_dib_formats();
5005     test_mono_dibsection();
5006     test_bitmap();
5007     test_bmBits();
5008     test_GetDIBits_selected_DIB(1);
5009     test_GetDIBits_selected_DIB(4);
5010     test_GetDIBits_selected_DIB(8);
5011     test_GetDIBits_selected_DDB(TRUE);
5012     test_GetDIBits_selected_DDB(FALSE);
5013     test_GetDIBits();
5014     test_GetDIBits_BI_BITFIELDS();
5015     test_select_object();
5016     test_CreateBitmap();
5017     test_BitBlt();
5018     test_StretchBlt();
5019     test_StretchDIBits();
5020     test_GdiAlphaBlend();
5021     test_GdiGradientFill();
5022     test_32bit_bitmap_blt();
5023     test_bitmapinfoheadersize();
5024     test_get16dibits();
5025     test_clipping();
5026     test_GetDIBits_top_down(16);
5027     test_GetDIBits_top_down(24);
5028     test_GetDIBits_top_down(32);
5029     test_GetSetDIBits_rtl();
5030     test_GetDIBits_scanlines();
5031     test_SetDIBits();
5032     test_SetDIBits_RLE4();
5033     test_SetDIBits_RLE8();
5034     test_SetDIBitsToDevice();
5035     test_SetDIBitsToDevice_RLE8();
5036 }