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