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