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