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
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.