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