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