~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/gdi32/tests/bitmap.c

Version: ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.