b0b85621811842923821062366181095048ec38c
[reactos.git] / rostests / winetests / gdi32 / bitmap.c
1 /*
2 * Unit test suite for bitmaps
3 *
4 * Copyright 2004 Huw Davies
5 * Copyright 2006 Dmitry Timoshkov
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include <stdarg.h>
23 #include <assert.h>
24 #include <string.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winerror.h"
29 #include "wingdi.h"
30 #include "winuser.h"
31 #include "mmsystem.h"
32
33 #include "wine/test.h"
34
35 static BOOL (WINAPI *pGdiAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION);
36 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
37
38 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
39
40 static inline int get_bitmap_stride( int width, int bpp )
41 {
42 return ((width * bpp + 15) >> 3) & ~1;
43 }
44
45 static inline int get_dib_stride( int width, int bpp )
46 {
47 return ((width * bpp + 31) >> 3) & ~3;
48 }
49
50 static inline int get_dib_image_size( const BITMAPINFO *info )
51 {
52 return get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount )
53 * abs( info->bmiHeader.biHeight );
54 }
55
56 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
57 {
58 BITMAP bm;
59 BITMAP bma[2];
60 INT ret, width_bytes;
61 BYTE buf[512], buf_cmp[512];
62
63 ret = GetObject(hbm, sizeof(bm), &bm);
64 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
65
66 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
67 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
68 ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
69 width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
70 ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
71 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
72 ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
73 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
74
75 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
76 assert(sizeof(buf) == sizeof(buf_cmp));
77
78 SetLastError(0xdeadbeef);
79 ret = GetBitmapBits(hbm, 0, NULL);
80 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
81
82 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
83 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
84
85 memset(buf, 0xAA, sizeof(buf));
86 ret = GetBitmapBits(hbm, sizeof(buf), buf);
87 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
88 ok(!memcmp(buf, buf_cmp, sizeof(buf)),
89 "buffers do not match, depth %d\n", bmih->biBitCount);
90
91 /* test various buffer sizes for GetObject */
92 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
93 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
94
95 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
96 ok(ret == 0, "%d != 0\n", ret);
97
98 ret = GetObject(hbm, 0, &bm);
99 ok(ret == 0, "%d != 0\n", ret);
100
101 ret = GetObject(hbm, 1, &bm);
102 ok(ret == 0, "%d != 0\n", ret);
103
104 ret = GetObject(hbm, 0, NULL);
105 ok(ret == sizeof(bm), "wrong size %d\n", ret);
106 }
107
108 static void test_createdibitmap(void)
109 {
110 HDC hdc, hdcmem;
111 BITMAPINFOHEADER bmih;
112 BITMAPINFO bm;
113 HBITMAP hbm, hbm_colour, hbm_old;
114 INT screen_depth;
115 DWORD pixel;
116
117 hdc = GetDC(0);
118 screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
119 memset(&bmih, 0, sizeof(bmih));
120 bmih.biSize = sizeof(bmih);
121 bmih.biWidth = 10;
122 bmih.biHeight = 10;
123 bmih.biPlanes = 1;
124 bmih.biBitCount = 32;
125 bmih.biCompression = BI_RGB;
126
127 hbm = CreateDIBitmap(hdc, NULL, CBM_INIT, NULL, NULL, 0);
128 ok(hbm == NULL, "CreateDIBitmap should fail\n");
129 hbm = CreateDIBitmap(hdc, NULL, 0, NULL, NULL, 0);
130 ok(hbm == NULL, "CreateDIBitmap should fail\n");
131
132 /* First create an un-initialised bitmap. The depth of the bitmap
133 should match that of the hdc and not that supplied in bmih.
134 */
135
136 /* First try 32 bits */
137 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
138 ok(hbm != NULL, "CreateDIBitmap failed\n");
139 test_bitmap_info(hbm, screen_depth, &bmih);
140 DeleteObject(hbm);
141
142 /* Then 16 */
143 bmih.biBitCount = 16;
144 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
145 ok(hbm != NULL, "CreateDIBitmap failed\n");
146 test_bitmap_info(hbm, screen_depth, &bmih);
147 DeleteObject(hbm);
148
149 /* Then 1 */
150 bmih.biBitCount = 1;
151 hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
152 ok(hbm != NULL, "CreateDIBitmap failed\n");
153 test_bitmap_info(hbm, screen_depth, &bmih);
154 DeleteObject(hbm);
155
156 /* Now with a monochrome dc we expect a monochrome bitmap */
157 hdcmem = CreateCompatibleDC(hdc);
158
159 /* First try 32 bits */
160 bmih.biBitCount = 32;
161 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
162 ok(hbm != NULL, "CreateDIBitmap failed\n");
163 test_bitmap_info(hbm, 1, &bmih);
164 DeleteObject(hbm);
165
166 /* Then 16 */
167 bmih.biBitCount = 16;
168 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
169 ok(hbm != NULL, "CreateDIBitmap failed\n");
170 test_bitmap_info(hbm, 1, &bmih);
171 DeleteObject(hbm);
172
173 /* Then 1 */
174 bmih.biBitCount = 1;
175 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
176 ok(hbm != NULL, "CreateDIBitmap failed\n");
177 test_bitmap_info(hbm, 1, &bmih);
178 DeleteObject(hbm);
179
180 /* Now select a polychrome bitmap into the dc and we expect
181 screen_depth bitmaps again */
182 hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight);
183 test_bitmap_info(hbm_colour, screen_depth, &bmih);
184 hbm_old = SelectObject(hdcmem, hbm_colour);
185
186 /* First try 32 bits */
187 bmih.biBitCount = 32;
188 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
189 ok(hbm != NULL, "CreateDIBitmap failed\n");
190 test_bitmap_info(hbm, screen_depth, &bmih);
191 DeleteObject(hbm);
192
193 /* Then 16 */
194 bmih.biBitCount = 16;
195 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
196 ok(hbm != NULL, "CreateDIBitmap failed\n");
197 test_bitmap_info(hbm, screen_depth, &bmih);
198 DeleteObject(hbm);
199
200 /* Then 1 */
201 bmih.biBitCount = 1;
202 hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
203 ok(hbm != NULL, "CreateDIBitmap failed\n");
204 test_bitmap_info(hbm, screen_depth, &bmih);
205 DeleteObject(hbm);
206
207 SelectObject(hdcmem, hbm_old);
208 DeleteObject(hbm_colour);
209 DeleteDC(hdcmem);
210
211 bmih.biBitCount = 32;
212 hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
213 ok(hbm != NULL, "CreateDIBitmap failed\n");
214 test_bitmap_info(hbm, 1, &bmih);
215 DeleteObject(hbm);
216
217 /* Test how formats are converted */
218 pixel = 0xffffffff;
219 bmih.biBitCount = 1;
220 bmih.biWidth = 1;
221 bmih.biHeight = 1;
222
223 memset(&bm, 0, sizeof(bm));
224 bm.bmiHeader.biSize = sizeof(bm.bmiHeader);
225 bm.bmiHeader.biWidth = 1;
226 bm.bmiHeader.biHeight = 1;
227 bm.bmiHeader.biPlanes = 1;
228 bm.bmiHeader.biBitCount= 24;
229 bm.bmiHeader.biCompression= BI_RGB;
230 bm.bmiHeader.biSizeImage = 0;
231 hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS);
232 ok(hbm != NULL, "CreateDIBitmap failed\n");
233
234 pixel = 0xdeadbeef;
235 bm.bmiHeader.biBitCount= 32;
236 GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS);
237 ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel);
238 DeleteObject(hbm);
239
240 ReleaseDC(0, hdc);
241 }
242
243 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
244 {
245 BITMAP bm;
246 BITMAP bma[2];
247 DIBSECTION ds;
248 DIBSECTION dsa[2];
249 INT ret, bm_width_bytes, dib_width_bytes;
250 BYTE *buf;
251
252 ret = GetObject(hbm, sizeof(bm), &bm);
253 ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
254
255 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
256 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
257 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
258 dib_width_bytes = get_dib_stride(bm.bmWidth, bm.bmBitsPixel);
259 bm_width_bytes = get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel);
260 if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
261 ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
262 else
263 ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
264 ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
265 ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
266 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
267
268 buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
269
270 /* GetBitmapBits returns not 32-bit aligned data */
271 SetLastError(0xdeadbeef);
272 ret = GetBitmapBits(hbm, 0, NULL);
273 ok(ret == bm_width_bytes * bm.bmHeight,
274 "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
275
276 memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
277 ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
278 ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
279
280 HeapFree(GetProcessHeap(), 0, buf);
281
282 /* test various buffer sizes for GetObject */
283 memset(&ds, 0xAA, sizeof(ds));
284 ret = GetObject(hbm, sizeof(*bma) * 2, bma);
285 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
286 ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
287 ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
288 ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
289
290 ret = GetObject(hbm, sizeof(bm) / 2, &bm);
291 ok(ret == 0, "%d != 0\n", ret);
292
293 ret = GetObject(hbm, 0, &bm);
294 ok(ret == 0, "%d != 0\n", ret);
295
296 ret = GetObject(hbm, 1, &bm);
297 ok(ret == 0, "%d != 0\n", ret);
298
299 /* test various buffer sizes for GetObject */
300 ret = GetObject(hbm, 0, NULL);
301 ok(ret == sizeof(bm), "wrong size %d\n", ret);
302
303 ret = GetObject(hbm, sizeof(*dsa) * 2, dsa);
304 ok(ret == sizeof(*dsa), "wrong size %d\n", ret);
305
306 memset(&ds, 0xAA, sizeof(ds));
307 ret = GetObject(hbm, sizeof(ds), &ds);
308 ok(ret == sizeof(ds), "wrong size %d\n", ret);
309
310 ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
311 if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
312 ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
313 ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
314 ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
315 ds.dsBmih.biSizeImage = 0;
316
317 ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
318 ok(ds.dsBmih.biWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
319 ok(ds.dsBmih.biHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
320 ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
321 ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
322 ok(ds.dsBmih.biCompression == bmih->biCompression ||
323 ((bmih->biBitCount == 32) && broken(ds.dsBmih.biCompression == BI_BITFIELDS)), /* nt4 sp1 and 2 */
324 "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
325 ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
326 ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%d != %d\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
327 ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%d != %d\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
328
329 memset(&ds, 0xAA, sizeof(ds));
330 ret = GetObject(hbm, sizeof(ds) - 4, &ds);
331 ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
332 ok(ds.dsBm.bmWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
333 ok(ds.dsBm.bmHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
334 ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
335
336 ret = GetObject(hbm, 0, &ds);
337 ok(ret == 0, "%d != 0\n", ret);
338
339 ret = GetObject(hbm, 1, &ds);
340 ok(ret == 0, "%d != 0\n", ret);
341 }
342
343 #define test_color_todo(got, exp, txt, todo) \
344 if (!todo && got != exp && screen_depth < 24) { \
345 todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
346 screen_depth, (UINT)got, (UINT)exp); \
347 return; \
348 } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
349 else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \
350
351 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
352 { \
353 COLORREF c; \
354 c = SetPixel(hdc, 0, 0, color); \
355 test_color_todo(c, exp, SetPixel, todo_setp); \
356 c = GetPixel(hdc, 0, 0); \
357 test_color_todo(c, exp, GetPixel, todo_getp); \
358 }
359
360 static void test_dib_bits_access( HBITMAP hdib, void *bits )
361 {
362 MEMORY_BASIC_INFORMATION info;
363 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
364 DWORD data[256];
365 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
366 HDC hdc;
367 char filename[MAX_PATH];
368 HANDLE file;
369 DWORD written;
370 INT ret;
371
372 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
373 "VirtualQuery failed\n");
374 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
375 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
376 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
377 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
378 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
379 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
380
381 memset( pbmi, 0, sizeof(bmibuf) );
382 memset( data, 0xcc, sizeof(data) );
383 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
384 pbmi->bmiHeader.biHeight = 16;
385 pbmi->bmiHeader.biWidth = 16;
386 pbmi->bmiHeader.biBitCount = 32;
387 pbmi->bmiHeader.biPlanes = 1;
388 pbmi->bmiHeader.biCompression = BI_RGB;
389
390 hdc = GetDC(0);
391
392 ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
393 ok(ret == 16, "SetDIBits failed: expected 16 got %d\n", ret);
394
395 ReleaseDC(0, hdc);
396
397 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
398 "VirtualQuery failed\n");
399 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
400 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
401 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
402 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
403 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
404 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
405
406 /* try writing protected bits to a file */
407
408 GetTempFileNameA( ".", "dib", 0, filename );
409 file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
410 CREATE_ALWAYS, 0, 0 );
411 ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
412 ret = WriteFile( file, bits, 8192, &written, NULL );
413 ok( ret, "WriteFile failed error %u\n", GetLastError() );
414 if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
415 CloseHandle( file );
416 DeleteFileA( filename );
417 }
418
419 static void test_dibsections(void)
420 {
421 HDC hdc, hdcmem, hdcmem2;
422 HBITMAP hdib, oldbm, hdib2, oldbm2;
423 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
424 char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
425 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
426 BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
427 HBITMAP hcoredib;
428 char coreBits[256];
429 BYTE *bits;
430 RGBQUAD rgb[256];
431 int ret;
432 char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
433 LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
434 WORD *index;
435 DWORD *bits32;
436 HPALETTE hpal, oldpal;
437 DIBSECTION dibsec;
438 COLORREF c0, c1;
439 int i;
440 int screen_depth;
441 MEMORY_BASIC_INFORMATION info;
442
443 hdc = GetDC(0);
444 screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
445
446 memset(pbmi, 0, sizeof(bmibuf));
447 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
448 pbmi->bmiHeader.biHeight = 100;
449 pbmi->bmiHeader.biWidth = 512;
450 pbmi->bmiHeader.biBitCount = 24;
451 pbmi->bmiHeader.biPlanes = 1;
452 pbmi->bmiHeader.biCompression = BI_RGB;
453
454 SetLastError(0xdeadbeef);
455
456 /* invalid pointer for BITMAPINFO
457 (*bits should be NULL on error) */
458 bits = (BYTE*)0xdeadbeef;
459 hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
460 ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
461
462 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
463 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
464 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
465 ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
466
467 /* test the DIB memory */
468 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
469 "VirtualQuery failed\n");
470 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
471 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
472 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
473 ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
474 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
475 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
476 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
477
478 test_dib_bits_access( hdib, bits );
479
480 test_dib_info(hdib, bits, &pbmi->bmiHeader);
481 DeleteObject(hdib);
482
483 /* Test a top-down DIB. */
484 pbmi->bmiHeader.biHeight = -100;
485 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
486 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
487 test_dib_info(hdib, bits, &pbmi->bmiHeader);
488 DeleteObject(hdib);
489
490 pbmi->bmiHeader.biHeight = 100;
491 pbmi->bmiHeader.biBitCount = 8;
492 pbmi->bmiHeader.biCompression = BI_RLE8;
493 SetLastError(0xdeadbeef);
494 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
495 ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
496 ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
497
498 pbmi->bmiHeader.biBitCount = 16;
499 pbmi->bmiHeader.biCompression = BI_BITFIELDS;
500 ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
501 ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
502 ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
503 SetLastError(0xdeadbeef);
504 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
505 ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
506
507 /* test the DIB memory */
508 ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
509 "VirtualQuery failed\n");
510 ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
511 ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
512 ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
513 ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
514 ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
515 ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
516 ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
517
518 test_dib_info(hdib, bits, &pbmi->bmiHeader);
519 DeleteObject(hdib);
520
521 memset(pbmi, 0, sizeof(bmibuf));
522 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
523 pbmi->bmiHeader.biHeight = 16;
524 pbmi->bmiHeader.biWidth = 16;
525 pbmi->bmiHeader.biBitCount = 1;
526 pbmi->bmiHeader.biPlanes = 1;
527 pbmi->bmiHeader.biCompression = BI_RGB;
528 pbmi->bmiColors[0].rgbRed = 0xff;
529 pbmi->bmiColors[0].rgbGreen = 0;
530 pbmi->bmiColors[0].rgbBlue = 0;
531 pbmi->bmiColors[1].rgbRed = 0;
532 pbmi->bmiColors[1].rgbGreen = 0;
533 pbmi->bmiColors[1].rgbBlue = 0xff;
534
535 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
536 ok(hdib != NULL, "CreateDIBSection failed\n");
537 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
538 ok(dibsec.dsBmih.biClrUsed == 2,
539 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
540
541 /* Test if the old BITMAPCOREINFO structure is supported */
542
543 pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
544 pbci->bmciHeader.bcBitCount = 0;
545
546 ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
547 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
548 ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
549 && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
550 "GetDIBits didn't fill in the BITMAPCOREHEADER structure properly\n");
551
552 ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
553 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
554 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
555 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
556 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
557 "The color table has not been translated to the old BITMAPCOREINFO format\n");
558
559 hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
560 ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
561
562 ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
563 ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
564 ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
565 ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
566 (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
567 (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
568 "The color table has not been translated to the old BITMAPCOREINFO format\n");
569
570 DeleteObject(hcoredib);
571
572 hdcmem = CreateCompatibleDC(hdc);
573 oldbm = SelectObject(hdcmem, hdib);
574
575 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
576 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
577 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
578 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
579 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
580 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
581
582 c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
583 c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
584
585 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
586 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
587 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
588 test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
589 test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
590 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
591 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
592 pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
593 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
594 pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
595 test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
596 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
597 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
598
599 SelectObject(hdcmem, oldbm);
600 DeleteObject(hdib);
601
602 pbmi->bmiColors[0].rgbRed = 0xff;
603 pbmi->bmiColors[0].rgbGreen = 0xff;
604 pbmi->bmiColors[0].rgbBlue = 0xff;
605 pbmi->bmiColors[1].rgbRed = 0;
606 pbmi->bmiColors[1].rgbGreen = 0;
607 pbmi->bmiColors[1].rgbBlue = 0;
608
609 hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
610 ok(hdib != NULL, "CreateDIBSection failed\n");
611
612 test_dib_info(hdib, bits, &pbmi->bmiHeader);
613
614 oldbm = SelectObject(hdcmem, hdib);
615
616 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
617 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
618 ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
619 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
620 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
621 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
622
623 SelectObject(hdcmem, oldbm);
624 test_dib_info(hdib, bits, &pbmi->bmiHeader);
625 DeleteObject(hdib);
626
627 pbmi->bmiHeader.biBitCount = 4;
628 for (i = 0; i < 16; i++) {
629 pbmi->bmiColors[i].rgbRed = i;
630 pbmi->bmiColors[i].rgbGreen = 16-i;
631 pbmi->bmiColors[i].rgbBlue = 0;
632 }
633 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
634 ok(hdib != NULL, "CreateDIBSection failed\n");
635 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
636 ok(dibsec.dsBmih.biClrUsed == 16,
637 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
638 test_dib_info(hdib, bits, &pbmi->bmiHeader);
639 DeleteObject(hdib);
640
641 pbmi->bmiHeader.biBitCount = 8;
642
643 for (i = 0; i < 128; i++) {
644 pbmi->bmiColors[i].rgbRed = 255 - i * 2;
645 pbmi->bmiColors[i].rgbGreen = i * 2;
646 pbmi->bmiColors[i].rgbBlue = 0;
647 pbmi->bmiColors[255 - i].rgbRed = 0;
648 pbmi->bmiColors[255 - i].rgbGreen = i * 2;
649 pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
650 }
651 hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
652 ok(hdib != NULL, "CreateDIBSection failed\n");
653 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
654 ok(dibsec.dsBmih.biClrUsed == 256,
655 "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
656
657 oldbm = SelectObject(hdcmem, hdib);
658
659 for (i = 0; i < 256; i++) {
660 test_color(hdcmem, DIBINDEX(i),
661 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
662 test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue),
663 RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
664 }
665
666 SelectObject(hdcmem, oldbm);
667 test_dib_info(hdib, bits, &pbmi->bmiHeader);
668 DeleteObject(hdib);
669
670 pbmi->bmiHeader.biBitCount = 1;
671
672 /* Now create a palette and a palette indexed dib section */
673 memset(plogpal, 0, sizeof(logpalbuf));
674 plogpal->palVersion = 0x300;
675 plogpal->palNumEntries = 2;
676 plogpal->palPalEntry[0].peRed = 0xff;
677 plogpal->palPalEntry[0].peBlue = 0xff;
678 plogpal->palPalEntry[1].peGreen = 0xff;
679
680 index = (WORD*)pbmi->bmiColors;
681 *index++ = 0;
682 *index = 1;
683 hpal = CreatePalette(plogpal);
684 ok(hpal != NULL, "CreatePalette failed\n");
685 oldpal = SelectPalette(hdc, hpal, TRUE);
686 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
687 ok(hdib != NULL, "CreateDIBSection failed\n");
688 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
689 ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
690
691 /* The colour table has already been grabbed from the dc, so we select back the
692 old palette */
693
694 SelectPalette(hdc, oldpal, TRUE);
695 oldbm = SelectObject(hdcmem, hdib);
696 oldpal = SelectPalette(hdcmem, hpal, TRUE);
697
698 ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
699 ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
700 ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
701 rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
702 "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
703 rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
704 rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
705
706 c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
707 c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
708
709 test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
710 test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
711 test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
712 test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
713 test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
714 test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
715 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
716 plogpal->palPalEntry[0].peBlue), c0, 1, 1);
717 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
718 plogpal->palPalEntry[1].peBlue), c1, 1, 1);
719 test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
720 test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
721 test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
722 test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
723 test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
724 test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
725
726 /* Bottom and 2nd row from top green, everything else magenta */
727 bits[0] = bits[1] = 0xff;
728 bits[13 * 4] = bits[13*4 + 1] = 0xff;
729
730 test_dib_info(hdib, bits, &pbmi->bmiHeader);
731
732 pbmi->bmiHeader.biBitCount = 32;
733
734 hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
735 ok(hdib2 != NULL, "CreateDIBSection failed\n");
736 hdcmem2 = CreateCompatibleDC(hdc);
737 oldbm2 = SelectObject(hdcmem2, hdib2);
738
739 BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
740
741 ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
742 ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
743
744 SelectObject(hdcmem2, oldbm2);
745 test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
746 DeleteObject(hdib2);
747
748 SelectObject(hdcmem, oldbm);
749 SelectPalette(hdcmem, oldpal, TRUE);
750 DeleteObject(hdib);
751 DeleteObject(hpal);
752
753
754 pbmi->bmiHeader.biBitCount = 8;
755
756 memset(plogpal, 0, sizeof(logpalbuf));
757 plogpal->palVersion = 0x300;
758 plogpal->palNumEntries = 256;
759
760 for (i = 0; i < 128; i++) {
761 plogpal->palPalEntry[i].peRed = 255 - i * 2;
762 plogpal->palPalEntry[i].peBlue = i * 2;
763 plogpal->palPalEntry[i].peGreen = 0;
764 plogpal->palPalEntry[255 - i].peRed = 0;
765 plogpal->palPalEntry[255 - i].peGreen = i * 2;
766 plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
767 }
768
769 index = (WORD*)pbmi->bmiColors;
770 for (i = 0; i < 256; i++) {
771 *index++ = i;
772 }
773
774 hpal = CreatePalette(plogpal);
775 ok(hpal != NULL, "CreatePalette failed\n");
776 oldpal = SelectPalette(hdc, hpal, TRUE);
777 hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
778 ok(hdib != NULL, "CreateDIBSection failed\n");
779 ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
780 ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
781
782 test_dib_info(hdib, bits, &pbmi->bmiHeader);
783
784 SelectPalette(hdc, oldpal, TRUE);
785 oldbm = SelectObject(hdcmem, hdib);
786 oldpal = SelectPalette(hdcmem, hpal, TRUE);
787
788 ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
789 ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
790 for (i = 0; i < 256; i++) {
791 ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed &&
792 rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue &&
793 rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen,
794 "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
795 i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
796 }
797
798 for (i = 0; i < 256; i++) {
799 test_color(hdcmem, DIBINDEX(i),
800 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
801 test_color(hdcmem, PALETTEINDEX(i),
802 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
803 test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue),
804 RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
805 }
806
807 SelectPalette(hdcmem, oldpal, TRUE);
808 SelectObject(hdcmem, oldbm);
809 DeleteObject(hdib);
810 DeleteObject(hpal);
811
812 DeleteDC(hdcmem);
813 DeleteDC(hdcmem2);
814 ReleaseDC(0, hdc);
815 }
816
817 static void test_dib_formats(void)
818 {
819 BITMAPINFO *bi;
820 char data[256];
821 void *bits;
822 //int planes, bpp, compr;
823 HBITMAP hdib, hbmp;
824 HDC hdc, memdc;
825 UINT ret;
826 //BOOL expect_ok, todo;
827
828 bi = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) );
829 hdc = GetDC( 0 );
830 memdc = CreateCompatibleDC( 0 );
831 hbmp = CreateCompatibleBitmap( hdc, 10, 10 );
832
833 memset( data, 0xaa, sizeof(data) );
834
835 #if 0 // FIXME: ReactOS Bug 6527
836 for (bpp = 0; bpp <= 64; bpp++)
837 {
838 for (planes = 0; planes <= 64; planes++)
839 {
840 for (compr = 0; compr < 8; compr++)
841 {
842 switch (bpp)
843 {
844 case 1:
845 case 4:
846 case 8:
847 case 24: expect_ok = (compr == BI_RGB); break;
848 case 16:
849 case 32: expect_ok = (compr == BI_RGB || compr == BI_BITFIELDS); break;
850 default: expect_ok = FALSE; break;
851 }
852 todo = (compr == BI_BITFIELDS); /* wine doesn't like strange bitfields */
853
854 memset( bi, 0, sizeof(bi->bmiHeader) );
855 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
856 bi->bmiHeader.biWidth = 2;
857 bi->bmiHeader.biHeight = 2;
858 bi->bmiHeader.biPlanes = planes;
859 bi->bmiHeader.biBitCount = bpp;
860 bi->bmiHeader.biCompression = compr;
861 bi->bmiHeader.biSizeImage = 0;
862 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
863 ret = GetDIBits(hdc, hbmp, 0, 0, data, bi, DIB_RGB_COLORS);
864 if (expect_ok || (!bpp && compr != BI_JPEG && compr != BI_PNG) ||
865 (bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8))
866 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
867 else
868 ok( !ret || broken(!bpp && (compr == BI_JPEG || compr == BI_PNG)), /* nt4 */
869 "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
870
871 /* all functions check planes except GetDIBits with 0 lines */
872 if (!planes) expect_ok = FALSE;
873 memset( bi, 0, sizeof(bi->bmiHeader) );
874 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
875 bi->bmiHeader.biWidth = 2;
876 bi->bmiHeader.biHeight = 2;
877 bi->bmiHeader.biPlanes = planes;
878 bi->bmiHeader.biBitCount = bpp;
879 bi->bmiHeader.biCompression = compr;
880 bi->bmiHeader.biSizeImage = 0;
881 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
882
883 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
884 if (expect_ok && (planes == 1 || planes * bpp <= 16))
885 ok( hdib != NULL, "CreateDIBSection failed for %u/%u/%u\n", bpp, planes, compr );
886 else
887 ok( hdib == NULL, "CreateDIBSection succeeded for %u/%u/%u\n", bpp, planes, compr );
888 if (hdib) DeleteObject( hdib );
889
890 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, data, bi, DIB_RGB_COLORS );
891 /* no sanity checks in CreateDIBitmap except compression */
892 if (compr == BI_JPEG || compr == BI_PNG)
893 ok( hdib == NULL || broken(hdib != NULL), /* nt4 */
894 "CreateDIBitmap succeeded for %u/%u/%u\n", bpp, planes, compr );
895 else
896 ok( hdib != NULL, "CreateDIBitmap failed for %u/%u/%u\n", bpp, planes, compr );
897 if (hdib) DeleteObject( hdib );
898
899 /* RLE needs a size */
900 bi->bmiHeader.biSizeImage = 0;
901 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
902 if (expect_ok)
903 {
904 if (todo)
905 todo_wine ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
906 else
907 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
908 }
909 else
910 ok( !ret ||
911 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
912 "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
913 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
914 if (expect_ok)
915 {
916 if (todo)
917 todo_wine ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
918 else
919 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
920 }
921 else
922 ok( !ret ||
923 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
924 "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
925 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
926 if (expect_ok)
927 {
928 if (todo)
929 todo_wine ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
930 else
931 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
932 }
933 else
934 ok( !ret ||
935 broken((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)), /* nt4 */
936 "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
937
938 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
939 if (expect_ok)
940 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
941 else
942 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
943 ok( bi->bmiHeader.biBitCount == bpp, "GetDIBits modified bpp %u/%u\n",
944 bpp, bi->bmiHeader.biBitCount );
945
946 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
947 bi->bmiHeader.biWidth = 2;
948 bi->bmiHeader.biHeight = 2;
949 bi->bmiHeader.biPlanes = planes;
950 bi->bmiHeader.biBitCount = bpp;
951 bi->bmiHeader.biCompression = compr;
952 bi->bmiHeader.biSizeImage = 1;
953 memset( bi->bmiColors, 0xaa, sizeof(RGBQUAD) * 256 );
954 /* RLE allowed with valid biSizeImage */
955 if ((bpp == 4 && compr == BI_RLE4) || (bpp == 8 && compr == BI_RLE8)) expect_ok = TRUE;
956
957 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
958 if (expect_ok)
959 {
960 if (todo)
961 todo_wine ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
962 else
963 ok( ret, "SetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
964 }
965 else
966 ok( !ret, "SetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
967 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
968 if (expect_ok)
969 {
970 if (todo)
971 todo_wine ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
972 else
973 ok( ret, "SetDIBitsToDevice failed for %u/%u/%u\n", bpp, planes, compr );
974 }
975 else
976 ok( !ret, "SetDIBitsToDevice succeeded for %u/%u/%u\n", bpp, planes, compr );
977 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
978 if (expect_ok)
979 {
980 if (todo)
981 todo_wine ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
982 else
983 ok( ret, "StretchDIBits failed for %u/%u/%u\n", bpp, planes, compr );
984 }
985 else
986 ok( !ret, "StretchDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
987
988 bi->bmiHeader.biSizeImage = 0;
989 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
990 if (expect_ok || !bpp)
991 ok( ret, "GetDIBits failed for %u/%u/%u\n", bpp, planes, compr );
992 else
993 ok( !ret, "GetDIBits succeeded for %u/%u/%u\n", bpp, planes, compr );
994 }
995 }
996 }
997 #endif
998
999 memset( bi, 0, sizeof(bi->bmiHeader) );
1000 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1001 bi->bmiHeader.biWidth = 2;
1002 bi->bmiHeader.biHeight = 2;
1003 bi->bmiHeader.biPlanes = 1;
1004 bi->bmiHeader.biBitCount = 16;
1005 bi->bmiHeader.biCompression = BI_BITFIELDS;
1006 bi->bmiHeader.biSizeImage = 0;
1007 *(DWORD *)&bi->bmiColors[0] = 0;
1008 *(DWORD *)&bi->bmiColors[1] = 0;
1009 *(DWORD *)&bi->bmiColors[2] = 0;
1010
1011 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1012 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1013 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1014 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1015 /* other functions don't check */
1016 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1017 ok( hdib != NULL, "CreateDIBitmap failed with null bitfields\n" );
1018 DeleteObject( hdib );
1019 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1020 todo_wine ok( ret, "SetDIBitsToDevice failed with null bitfields\n" );
1021 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1022 todo_wine ok( ret, "StretchDIBits failed with null bitfields\n" );
1023 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1024 ok( ret, "GetDIBits failed with null bitfields\n" );
1025 bi->bmiHeader.biPlanes = 1;
1026 bi->bmiHeader.biBitCount = 16;
1027 bi->bmiHeader.biCompression = BI_BITFIELDS;
1028 bi->bmiHeader.biSizeImage = 0;
1029 *(DWORD *)&bi->bmiColors[0] = 0;
1030 *(DWORD *)&bi->bmiColors[1] = 0;
1031 *(DWORD *)&bi->bmiColors[2] = 0;
1032 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1033 ok( ret, "GetDIBits failed with null bitfields\n" );
1034
1035 /* all fields must be non-zero */
1036 *(DWORD *)&bi->bmiColors[0] = 3;
1037 *(DWORD *)&bi->bmiColors[1] = 0;
1038 *(DWORD *)&bi->bmiColors[2] = 7;
1039 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1040 ok( hdib == NULL, "CreateDIBSection succeeded with null bitfields\n" );
1041 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1042 ok( !ret, "SetDIBits succeeded with null bitfields\n" );
1043
1044 /* garbage is ok though */
1045 *(DWORD *)&bi->bmiColors[0] = 0x55;
1046 *(DWORD *)&bi->bmiColors[1] = 0x44;
1047 *(DWORD *)&bi->bmiColors[2] = 0x33;
1048 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1049 ok( hdib != NULL, "CreateDIBSection failed with bad bitfields\n" );
1050 if (hdib) DeleteObject( hdib );
1051 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1052 todo_wine ok( ret, "SetDIBits failed with bad bitfields\n" );
1053
1054 bi->bmiHeader.biWidth = -2;
1055 bi->bmiHeader.biHeight = 2;
1056 bi->bmiHeader.biBitCount = 32;
1057 bi->bmiHeader.biCompression = BI_RGB;
1058 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1059 ok( hdib == NULL, "CreateDIBSection succeeded with negative width\n" );
1060 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1061 ok( hdib == NULL, "CreateDIBitmap succeeded with negative width\n" );
1062 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1063 ok( !ret, "SetDIBits succeeded with negative width\n" );
1064 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1065 ok( !ret, "SetDIBitsToDevice succeeded with negative width\n" );
1066 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1067 ok( !ret, "StretchDIBits succeeded with negative width\n" );
1068 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1069 ok( !ret, "GetDIBits succeeded with negative width\n" );
1070 bi->bmiHeader.biWidth = -2;
1071 bi->bmiHeader.biHeight = 2;
1072 bi->bmiHeader.biBitCount = 32;
1073 bi->bmiHeader.biCompression = BI_RGB;
1074 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1075 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with negative width\n" );
1076
1077 bi->bmiHeader.biWidth = 0;
1078 bi->bmiHeader.biHeight = 2;
1079 bi->bmiHeader.biBitCount = 32;
1080 bi->bmiHeader.biCompression = BI_RGB;
1081 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1082 ok( hdib == NULL, "CreateDIBSection succeeded with zero width\n" );
1083 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1084 ok( hdib != NULL, "CreateDIBitmap failed with zero width\n" );
1085 DeleteObject( hdib );
1086 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1087 ok( !ret || broken(ret), /* nt4 */ "SetDIBits succeeded with zero width\n" );
1088 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1089 ok( !ret || broken(ret), /* nt4 */ "SetDIBitsToDevice succeeded with zero width\n" );
1090 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1091 ok( !ret || broken(ret), /* nt4 */ "StretchDIBits succeeded with zero width\n" );
1092 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1093 ok( !ret, "GetDIBits succeeded with zero width\n" );
1094 bi->bmiHeader.biWidth = 0;
1095 bi->bmiHeader.biHeight = 2;
1096 bi->bmiHeader.biBitCount = 32;
1097 bi->bmiHeader.biCompression = BI_RGB;
1098 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1099 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero width\n" );
1100
1101 bi->bmiHeader.biWidth = 2;
1102 bi->bmiHeader.biHeight = 0;
1103 bi->bmiHeader.biBitCount = 32;
1104 bi->bmiHeader.biCompression = BI_RGB;
1105 hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1106 ok( hdib == NULL, "CreateDIBSection succeeded with zero height\n" );
1107 hdib = CreateDIBitmap( hdc, &bi->bmiHeader, 0, bits, bi, DIB_RGB_COLORS );
1108 ok( hdib != NULL, "CreateDIBitmap failed with zero height\n" );
1109 DeleteObject( hdib );
1110 ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
1111 ok( !ret, "SetDIBits succeeded with zero height\n" );
1112 ret = SetDIBitsToDevice( memdc, 0, 0, 1, 1, 0, 0, 0, 1, data, bi, DIB_RGB_COLORS );
1113 ok( !ret, "SetDIBitsToDevice succeeded with zero height\n" );
1114 ret = StretchDIBits( memdc, 0, 0, 1, 1, 0, 0, 1, 1, data, bi, DIB_RGB_COLORS, SRCCOPY );
1115 ok( !ret, "StretchDIBits succeeded with zero height\n" );
1116 ret = GetDIBits(hdc, hbmp, 0, 2, data, bi, DIB_RGB_COLORS);
1117 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1118 bi->bmiHeader.biWidth = 2;
1119 bi->bmiHeader.biHeight = 0;
1120 bi->bmiHeader.biBitCount = 32;
1121 bi->bmiHeader.biCompression = BI_RGB;
1122 ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
1123 ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero height\n" );
1124
1125 DeleteDC( memdc );
1126 DeleteObject( hbmp );
1127 ReleaseDC( 0, hdc );
1128 HeapFree( GetProcessHeap(), 0, bi );
1129 }
1130
1131 static void test_mono_dibsection(void)
1132 {
1133 HDC hdc, memdc;
1134 HBITMAP old_bm, mono_ds;
1135 char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1136 BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
1137 BYTE bits[10 * 4];
1138 BYTE *ds_bits;
1139 int num;
1140
1141 hdc = GetDC(0);
1142
1143 memdc = CreateCompatibleDC(hdc);
1144
1145 memset(pbmi, 0, sizeof(bmibuf));
1146 pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
1147 pbmi->bmiHeader.biHeight = 10;
1148 pbmi->bmiHeader.biWidth = 10;
1149 pbmi->bmiHeader.biBitCount = 1;
1150 pbmi->bmiHeader.biPlanes = 1;
1151 pbmi->bmiHeader.biCompression = BI_RGB;
1152 pbmi->bmiColors[0].rgbRed = 0xff;
1153 pbmi->bmiColors[0].rgbGreen = 0xff;
1154 pbmi->bmiColors[0].rgbBlue = 0xff;
1155 pbmi->bmiColors[1].rgbRed = 0x0;
1156 pbmi->bmiColors[1].rgbGreen = 0x0;
1157 pbmi->bmiColors[1].rgbBlue = 0x0;
1158
1159 /*
1160 * First dib section is 'inverted' ie color[0] is white, color[1] is black
1161 */
1162
1163 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1164 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1165 old_bm = SelectObject(memdc, mono_ds);
1166
1167 /* black border, white interior */
1168 Rectangle(memdc, 0, 0, 10, 10);
1169 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1170 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1171
1172 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1173
1174 memset(bits, 0, sizeof(bits));
1175 bits[0] = 0xaa;
1176
1177 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1178 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1179
1180 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1181
1182 pbmi->bmiColors[0].rgbRed = 0x0;
1183 pbmi->bmiColors[0].rgbGreen = 0x0;
1184 pbmi->bmiColors[0].rgbBlue = 0x0;
1185 pbmi->bmiColors[1].rgbRed = 0xff;
1186 pbmi->bmiColors[1].rgbGreen = 0xff;
1187 pbmi->bmiColors[1].rgbBlue = 0xff;
1188
1189 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1190 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1191
1192 SelectObject(memdc, old_bm);
1193 DeleteObject(mono_ds);
1194
1195 /*
1196 * Next dib section is 'normal' ie color[0] is black, color[1] is white
1197 */
1198
1199 pbmi->bmiColors[0].rgbRed = 0x0;
1200 pbmi->bmiColors[0].rgbGreen = 0x0;
1201 pbmi->bmiColors[0].rgbBlue = 0x0;
1202 pbmi->bmiColors[1].rgbRed = 0xff;
1203 pbmi->bmiColors[1].rgbGreen = 0xff;
1204 pbmi->bmiColors[1].rgbBlue = 0xff;
1205
1206 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1207 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1208 old_bm = SelectObject(memdc, mono_ds);
1209
1210 /* black border, white interior */
1211 Rectangle(memdc, 0, 0, 10, 10);
1212 ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
1213 ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
1214
1215 /* SetDIBitsToDevice with a normal bmi -> normal dib section */
1216
1217 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1218 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1219
1220 /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
1221
1222 pbmi->bmiColors[0].rgbRed = 0xff;
1223 pbmi->bmiColors[0].rgbGreen = 0xff;
1224 pbmi->bmiColors[0].rgbBlue = 0xff;
1225 pbmi->bmiColors[1].rgbRed = 0x0;
1226 pbmi->bmiColors[1].rgbGreen = 0x0;
1227 pbmi->bmiColors[1].rgbBlue = 0x0;
1228
1229 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1230 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1231
1232 /*
1233 * Take that 'normal' dibsection and change its colour table to an 'inverted' one
1234 */
1235
1236 pbmi->bmiColors[0].rgbRed = 0xff;
1237 pbmi->bmiColors[0].rgbGreen = 0xff;
1238 pbmi->bmiColors[0].rgbBlue = 0xff;
1239 pbmi->bmiColors[1].rgbRed = 0x0;
1240 pbmi->bmiColors[1].rgbGreen = 0x0;
1241 pbmi->bmiColors[1].rgbBlue = 0x0;
1242 num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
1243 ok(num == 2, "num = %d\n", num);
1244
1245 /* black border, white interior */
1246 Rectangle(memdc, 0, 0, 10, 10);
1247 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1248 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1249
1250 /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
1251
1252 memset(bits, 0, sizeof(bits));
1253 bits[0] = 0xaa;
1254
1255 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1256 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1257
1258 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1259
1260 pbmi->bmiColors[0].rgbRed = 0x0;
1261 pbmi->bmiColors[0].rgbGreen = 0x0;
1262 pbmi->bmiColors[0].rgbBlue = 0x0;
1263 pbmi->bmiColors[1].rgbRed = 0xff;
1264 pbmi->bmiColors[1].rgbGreen = 0xff;
1265 pbmi->bmiColors[1].rgbBlue = 0xff;
1266
1267 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1268 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1269
1270 SelectObject(memdc, old_bm);
1271 DeleteObject(mono_ds);
1272
1273 /*
1274 * Now a dib section with a strange colour map just for fun. This behaves just like an inverted one.
1275 */
1276
1277 pbmi->bmiColors[0].rgbRed = 0xff;
1278 pbmi->bmiColors[0].rgbGreen = 0x0;
1279 pbmi->bmiColors[0].rgbBlue = 0x0;
1280 pbmi->bmiColors[1].rgbRed = 0xfe;
1281 pbmi->bmiColors[1].rgbGreen = 0x0;
1282 pbmi->bmiColors[1].rgbBlue = 0x0;
1283
1284 mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1285 ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1286 old_bm = SelectObject(memdc, mono_ds);
1287
1288 /* black border, white interior */
1289 Rectangle(memdc, 0, 0, 10, 10);
1290 ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1291 ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1292
1293 /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1294
1295 pbmi->bmiColors[0].rgbRed = 0x0;
1296 pbmi->bmiColors[0].rgbGreen = 0x0;
1297 pbmi->bmiColors[0].rgbBlue = 0x0;
1298 pbmi->bmiColors[1].rgbRed = 0xff;
1299 pbmi->bmiColors[1].rgbGreen = 0xff;
1300 pbmi->bmiColors[1].rgbBlue = 0xff;
1301
1302 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1303 ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1304
1305 /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1306
1307 pbmi->bmiColors[0].rgbRed = 0xff;
1308 pbmi->bmiColors[0].rgbGreen = 0xff;
1309 pbmi->bmiColors[0].rgbBlue = 0xff;
1310 pbmi->bmiColors[1].rgbRed = 0x0;
1311 pbmi->bmiColors[1].rgbGreen = 0x0;
1312 pbmi->bmiColors[1].rgbBlue = 0x0;
1313
1314 SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1315 ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1316
1317 SelectObject(memdc, old_bm);
1318 DeleteObject(mono_ds);
1319
1320 DeleteDC(memdc);
1321 ReleaseDC(0, hdc);
1322 }
1323
1324 static void test_bitmap(void)
1325 {
1326 char buf[256], buf_cmp[256];
1327 HBITMAP hbmp, hbmp_old;
1328 HDC hdc;
1329 BITMAP bm;
1330 BITMAP bma[2];
1331 INT ret;
1332
1333 hdc = CreateCompatibleDC(0);
1334 assert(hdc != 0);
1335
1336 SetLastError(0xdeadbeef);
1337 hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1338 if (!hbmp)
1339 {
1340 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1341 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1342 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1343 }
1344 else
1345 DeleteObject(hbmp);
1346
1347 SetLastError(0xdeadbeef);
1348 hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1349 if (!hbmp)
1350 {
1351 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1352 GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1353 "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1354 }
1355 else
1356 DeleteObject(hbmp);
1357
1358 SetLastError(0xdeadbeef);
1359 hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1360 ok(!hbmp, "CreateBitmap should fail\n");
1361 if (!hbmp)
1362 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1363 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1364 else
1365 DeleteObject(hbmp);
1366
1367 hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1368 assert(hbmp != NULL);
1369
1370 ret = GetObject(hbmp, sizeof(bm), &bm);
1371 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1372
1373 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1374 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1375 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1376 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1377 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1378 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1379 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1380
1381 assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1382 assert(sizeof(buf) == sizeof(buf_cmp));
1383
1384 ret = GetBitmapBits(hbmp, 0, NULL);
1385 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1386
1387 memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1388 memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1389
1390 memset(buf, 0xAA, sizeof(buf));
1391 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1392 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1393 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1394
1395 hbmp_old = SelectObject(hdc, hbmp);
1396
1397 ret = GetObject(hbmp, sizeof(bm), &bm);
1398 ok(ret == sizeof(bm), "wrong size %d\n", ret);
1399
1400 ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1401 ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1402 ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1403 ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1404 ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1405 ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1406 ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1407
1408 memset(buf, 0xAA, sizeof(buf));
1409 ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1410 ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1411 ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
1412
1413 hbmp_old = SelectObject(hdc, hbmp_old);
1414 ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1415
1416 /* test various buffer sizes for GetObject */
1417 ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1418 ok(ret == sizeof(*bma), "wrong size %d\n", ret);
1419
1420 ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1421 ok(ret == 0, "%d != 0\n", ret);
1422
1423 ret = GetObject(hbmp, 0, &bm);
1424 ok(ret == 0, "%d != 0\n", ret);
1425
1426 ret = GetObject(hbmp, 1, &bm);
1427 ok(ret == 0, "%d != 0\n", ret);
1428
1429 DeleteObject(hbmp);
1430 DeleteDC(hdc);
1431 }
1432
1433 static void test_bmBits(void)
1434 {
1435 BYTE bits[4];
1436 HBITMAP hbmp;
1437 BITMAP bmp;
1438
1439 memset(bits, 0, sizeof(bits));
1440 hbmp = CreateBitmap(2, 2, 1, 4, bits);
1441 ok(hbmp != NULL, "CreateBitmap failed\n");
1442
1443 memset(&bmp, 0xFF, sizeof(bmp));
1444 ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1445 "GetObject failed or returned a wrong structure size\n");
1446 ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1447
1448 DeleteObject(hbmp);
1449 }
1450
1451 static void test_GetDIBits_selected_DIB(UINT bpp)
1452 {
1453 HBITMAP dib;
1454 BITMAPINFO *info;
1455 BITMAPINFO *info2;
1456 void * bits;
1457 void * bits2;
1458 UINT dib_size, dib32_size;
1459 DWORD pixel;
1460 HDC dib_dc, dc;
1461 HBITMAP old_bmp;
1462 UINT i;
1463 int res;
1464
1465 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1466 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1467
1468 /* Create a DIB section with a color table */
1469
1470 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1471 info->bmiHeader.biWidth = 32;
1472 info->bmiHeader.biHeight = 32;
1473 info->bmiHeader.biPlanes = 1;
1474 info->bmiHeader.biBitCount = bpp;
1475 info->bmiHeader.biCompression = BI_RGB;
1476 info->bmiHeader.biXPelsPerMeter = 0;
1477 info->bmiHeader.biYPelsPerMeter = 0;
1478 info->bmiHeader.biClrUsed = 0;
1479 info->bmiHeader.biClrImportant = 0;
1480
1481 for (i=0; i < (1u << bpp); i++)
1482 {
1483 BYTE c = i * (1 << (8 - bpp));
1484 info->bmiColors[i].rgbRed = c;
1485 info->bmiColors[i].rgbGreen = c;
1486 info->bmiColors[i].rgbBlue = c;
1487 info->bmiColors[i].rgbReserved = 0;
1488 }
1489
1490 dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1491 dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1492 dib32_size = 32 * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1493
1494 /* Set the bits of the DIB section */
1495 for (i=0; i < dib_size; i++)
1496 {
1497 ((BYTE *)bits)[i] = i % 256;
1498 }
1499
1500 /* Select the DIB into a DC */
1501 dib_dc = CreateCompatibleDC(NULL);
1502 old_bmp = SelectObject(dib_dc, dib);
1503 dc = CreateCompatibleDC(NULL);
1504 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib32_size);
1505
1506 /* Copy the DIB attributes but not the color table */
1507 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1508
1509 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1510 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1511
1512 /* Compare the color table and the bits */
1513 for (i=0; i < (1u << bpp); i++)
1514 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1515 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1516 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1517 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1518 "color table entry %d differs (bpp %d)\n", i, bpp );
1519
1520 ok( !memcmp( bits, bits2, dib_size ), "bit mismatch (bpp %d)\n", bpp );
1521
1522 /* Test various combinations of lines = 0 and bits2 = NULL */
1523 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1524 res = GetDIBits( dc, dib, 0, 0, bits2, info2, DIB_RGB_COLORS );
1525 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1526 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1527 "color table mismatch (bpp %d)\n", bpp );
1528
1529 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1530 res = GetDIBits( dc, dib, 0, 0, NULL, info2, DIB_RGB_COLORS );
1531 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1532 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1533 "color table mismatch (bpp %d)\n", bpp );
1534
1535 memset( info2->bmiColors, 0xcc, 256 * sizeof(RGBQUAD) );
1536 res = GetDIBits( dc, dib, 0, info->bmiHeader.biHeight, NULL, info2, DIB_RGB_COLORS );
1537 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1538 ok( !memcmp( info->bmiColors, info2->bmiColors, (1 << bpp) * sizeof(RGBQUAD) ),
1539 "color table mismatch (bpp %d)\n", bpp );
1540
1541 /* Map into a 32bit-DIB */
1542 info2->bmiHeader.biBitCount = 32;
1543 res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1544 ok( res == info->bmiHeader.biHeight, "got %d (bpp %d)\n", res, bpp );
1545
1546 /* Check if last pixel was set */
1547 pixel = ((DWORD *)bits2)[info->bmiHeader.biWidth * info->bmiHeader.biHeight - 1];
1548 ok(pixel != 0, "Pixel: 0x%08x\n", pixel);
1549
1550 HeapFree(GetProcessHeap(), 0, bits2);
1551 DeleteDC(dc);
1552
1553 SelectObject(dib_dc, old_bmp);
1554 DeleteDC(dib_dc);
1555 DeleteObject(dib);
1556 HeapFree(GetProcessHeap(), 0, info2);
1557 HeapFree(GetProcessHeap(), 0, info);
1558 }
1559
1560 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1561 {
1562 HBITMAP ddb;
1563 BITMAPINFO *info;
1564 BITMAPINFO *info2;
1565 void * bits;
1566 void * bits2;
1567 HDC ddb_dc, dc;
1568 HBITMAP old_bmp;
1569 UINT width, height;
1570 UINT bpp;
1571 UINT i, j;
1572 int res;
1573
1574 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1575 info2 = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
1576
1577 width = height = 16;
1578
1579 /* Create a DDB (device-dependent bitmap) */
1580 if (monochrome)
1581 {
1582 bpp = 1;
1583 ddb = CreateBitmap(width, height, 1, 1, NULL);
1584 }
1585 else
1586 {
1587 HDC screen_dc = GetDC(NULL);
1588 bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1589 ddb = CreateCompatibleBitmap(screen_dc, width, height);
1590 ReleaseDC(NULL, screen_dc);
1591 }
1592
1593 /* Set the pixels */
1594 ddb_dc = CreateCompatibleDC(NULL);
1595 old_bmp = SelectObject(ddb_dc, ddb);
1596 for (i = 0; i < width; i++)
1597 {
1598 for (j=0; j < height; j++)
1599 {
1600 BYTE c = (i * width + j) % 256;
1601 SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1602 }
1603 }
1604 SelectObject(ddb_dc, old_bmp);
1605
1606 info->bmiHeader.biSize = sizeof(info->bmiHeader);
1607 info->bmiHeader.biWidth = width;
1608 info->bmiHeader.biHeight = height;
1609 info->bmiHeader.biPlanes = 1;
1610 info->bmiHeader.biBitCount = bpp;
1611 info->bmiHeader.biCompression = BI_RGB;
1612
1613 dc = CreateCompatibleDC(NULL);
1614
1615 /* Fill in biSizeImage */
1616 GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1617 ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1618
1619 bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1620 bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1621
1622 /* Get the bits */
1623 res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1624 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1625
1626 /* Copy the DIB attributes but not the color table */
1627 memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1628
1629 /* Select the DDB into another DC */
1630 old_bmp = SelectObject(ddb_dc, ddb);
1631
1632 /* Get the bits */
1633 res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1634 ok( res == height, "got %d (bpp %d)\n", res, bpp );
1635
1636 /* Compare the color table and the bits */
1637 if (bpp <= 8)
1638 {
1639 for (i=0; i < (1u << bpp); i++)
1640 ok( info->bmiColors[i].rgbRed == info2->bmiColors[i].rgbRed &&
1641 info->bmiColors[i].rgbGreen == info2->bmiColors[i].rgbGreen &&
1642 info->bmiColors[i].rgbBlue == info2->bmiColors[i].rgbBlue &&
1643 info->bmiColors[i].rgbReserved == info2->bmiColors[i].rgbReserved,
1644 "color table entry %d differs (bpp %d)\n", i, bpp );
1645 }
1646
1647 ok( !memcmp( bits, bits2, info->bmiHeader.biSizeImage ), "bit mismatch (bpp %d)\n", bpp );
1648
1649 /* Test the palette */
1650 if (info2->bmiHeader.biBitCount <= 8)
1651 {
1652 WORD *colors = (WORD*)info2->bmiColors;
1653
1654 /* Get the palette indices */
1655 res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1656 ok( res == 1, "got %d (bpp %d)\n", res, bpp );
1657
1658 for (i = 0; i < (1 << info->bmiHeader.biBitCount); i++)
1659 ok( colors[i] == i, "%d: got %d (bpp %d)\n", i, colors[i], bpp );
1660 }
1661
1662 HeapFree(GetProcessHeap(), 0, bits2);
1663 HeapFree(GetProcessHeap(), 0, bits);
1664 DeleteDC(dc);
1665
1666 SelectObject(ddb_dc, old_bmp);
1667 DeleteDC(ddb_dc);
1668 DeleteObject(ddb);
1669 HeapFree(GetProcessHeap(), 0, info2);
1670 HeapFree(GetProcessHeap(), 0, info);
1671 }
1672
1673 static void test_GetDIBits(void)
1674 {
1675 /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1676 static const BYTE bmp_bits_1[16 * 2] =
1677 {
1678 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1679 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1680 0xff,0xff, 0,0, 0xff,0xff, 0,0,
1681 0xff,0xff, 0,0, 0xff,0xff, 0,0
1682 };
1683 /* 4-bytes aligned 1-bit DIB data: 16x16 */
1684 static const BYTE dib_bits_1[16 * 4] =
1685 {
1686 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1687 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1688 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1689 0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1690 };
1691 /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1692 static const BYTE bmp_bits_24[16 * 16*3] =
1693 {
1694 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1695 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1696 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1697 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1698 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1699 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1700 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1701 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1702 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1703 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1704 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1705 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1706 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1707 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1708 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1709 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1710 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1711 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1712 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1713 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1714 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1715 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1716 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1717 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1718 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1719 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1720 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1721 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1722 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1723 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1724 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1725 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1726 };
1727 /* 4-bytes aligned 24-bit DIB data: 16x16 */
1728 static const BYTE dib_bits_24[16 * 16*3] =
1729 {
1730 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1731 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1732 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1733 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1734 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1735 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1736 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1737 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1738 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1739 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1740 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1741 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1742 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1743 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1744 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1745 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1746 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1747 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1748 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1749 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1750 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1751 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1752 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1753 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1754 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1755 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1756 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1757 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1758 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1759 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1760 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1761 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1762 };
1763 HBITMAP hbmp;
1764 BITMAP bm;
1765 HDC hdc;
1766 int i, bytes, lines;
1767 BYTE buf[1024];
1768 char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1769 BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1770 PALETTEENTRY pal_ents[20];
1771
1772 hdc = GetDC(0);
1773
1774 /* 1-bit source bitmap data */
1775 hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1776 ok(hbmp != 0, "CreateBitmap failed\n");
1777
1778 memset(&bm, 0xAA, sizeof(bm));
1779 bytes = GetObject(hbmp, sizeof(bm), &bm);
1780 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1781 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1782 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1783 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1784 ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1785 ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1786 ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1787 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1788
1789 bytes = GetBitmapBits(hbmp, 0, NULL);
1790 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1791 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1792 ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1793 ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1794
1795 /* retrieve 1-bit DIB data */
1796 memset(bi, 0, sizeof(*bi));
1797 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1798 bi->bmiHeader.biWidth = bm.bmWidth;
1799 bi->bmiHeader.biHeight = bm.bmHeight;
1800 bi->bmiHeader.biPlanes = 1;
1801 bi->bmiHeader.biBitCount = 1;
1802 bi->bmiHeader.biCompression = BI_RGB;
1803 bi->bmiHeader.biSizeImage = 0;
1804 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1805 SetLastError(0xdeadbeef);
1806 lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1807 ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1808 ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1809 broken(GetLastError() == 0xdeadbeef), /* winnt */
1810 "wrong error %u\n", GetLastError());
1811 ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1812
1813 memset(buf, 0xAA, sizeof(buf));
1814 SetLastError(0xdeadbeef);
1815 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1816 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1817 lines, bm.bmHeight, GetLastError());
1818 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1819
1820 /* the color table consists of black and white */
1821 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1822 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1823 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1824 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1825 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1826 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1827 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1828 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1829 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1830 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1831 for (i = 2; i < 256; i++)
1832 {
1833 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1834 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1835 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1836 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1837 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1838 }
1839
1840 /* returned bits are DWORD aligned and upside down */
1841 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1842
1843 /* Test the palette indices */
1844 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1845 SetLastError(0xdeadbeef);
1846 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1847 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1848 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1849 for (i = 2; i < 256; i++)
1850 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
1851
1852 /* retrieve 24-bit DIB data */
1853 memset(bi, 0, sizeof(*bi));
1854 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1855 bi->bmiHeader.biWidth = bm.bmWidth;
1856 bi->bmiHeader.biHeight = bm.bmHeight;
1857 bi->bmiHeader.biPlanes = 1;
1858 bi->bmiHeader.biBitCount = 24;
1859 bi->bmiHeader.biCompression = BI_RGB;
1860 bi->bmiHeader.biSizeImage = 0;
1861 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1862 memset(buf, 0xAA, sizeof(buf));
1863 SetLastError(0xdeadbeef);
1864 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1865 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1866 lines, bm.bmHeight, GetLastError());
1867 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1868
1869 /* the color table doesn't exist for 24-bit images */
1870 for (i = 0; i < 256; i++)
1871 {
1872 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1873 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1874 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1875 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1876 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1877 }
1878
1879 /* returned bits are DWORD aligned and upside down */
1880 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1881 DeleteObject(hbmp);
1882
1883 /* 24-bit source bitmap data */
1884 hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1885 ok(hbmp != 0, "CreateBitmap failed\n");
1886 SetLastError(0xdeadbeef);
1887 bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1888 lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1889 ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1890 lines, bm.bmHeight, GetLastError());
1891
1892 memset(&bm, 0xAA, sizeof(bm));
1893 bytes = GetObject(hbmp, sizeof(bm), &bm);
1894 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1895 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1896 ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1897 ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1898 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1899 ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1900 ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1901 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1902
1903 bytes = GetBitmapBits(hbmp, 0, NULL);
1904 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1905 bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1906 ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1907 bm.bmWidthBytes * bm.bmHeight, bytes);
1908
1909 /* retrieve 1-bit DIB data */
1910 memset(bi, 0, sizeof(*bi));
1911 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1912 bi->bmiHeader.biWidth = bm.bmWidth;
1913 bi->bmiHeader.biHeight = bm.bmHeight;
1914 bi->bmiHeader.biPlanes = 1;
1915 bi->bmiHeader.biBitCount = 1;
1916 bi->bmiHeader.biCompression = BI_RGB;
1917 bi->bmiHeader.biSizeImage = 0;
1918 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1919 memset(buf, 0xAA, sizeof(buf));
1920 SetLastError(0xdeadbeef);
1921 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1922 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1923 lines, bm.bmHeight, GetLastError());
1924 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1925
1926 /* the color table consists of black and white */
1927 ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1928 bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1929 "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1930 bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1931 bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1932 ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1933 bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1934 "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1935 bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1936 bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1937 for (i = 2; i < 256; i++)
1938 {
1939 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1940 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1941 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1942 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1943 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1944 }
1945
1946 /* returned bits are DWORD aligned and upside down */
1947 ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1948
1949 /* Test the palette indices */
1950 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1951 SetLastError(0xdeadbeef);
1952 lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1953 ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1954 ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1955 for (i = 2; i < 256; i++)
1956 ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
1957
1958 /* retrieve 4-bit DIB data */
1959 memset(bi, 0, sizeof(*bi));
1960 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1961 bi->bmiHeader.biWidth = bm.bmWidth;
1962 bi->bmiHeader.biHeight = bm.bmHeight;
1963 bi->bmiHeader.biPlanes = 1;
1964 bi->bmiHeader.biBitCount = 4;
1965 bi->bmiHeader.biCompression = BI_RGB;
1966 bi->bmiHeader.biSizeImage = 0;
1967 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1968 memset(buf, 0xAA, sizeof(buf));
1969 SetLastError(0xdeadbeef);
1970 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1971 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1972 lines, bm.bmHeight, GetLastError());
1973
1974 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
1975
1976 for (i = 0; i < 16; i++)
1977 {
1978 RGBQUAD expect;
1979 int entry = i < 8 ? i : i + 4;
1980
1981 if(entry == 7) entry = 12;
1982 else if(entry == 12) entry = 7;
1983
1984 expect.rgbRed = pal_ents[entry].peRed;
1985 expect.rgbGreen = pal_ents[entry].peGreen;
1986 expect.rgbBlue = pal_ents[entry].peBlue;
1987 expect.rgbReserved = 0;
1988
1989 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
1990 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
1991 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
1992 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1993 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1994 }
1995
1996 /* retrieve 8-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 = 8;
2003 bi->bmiHeader.biCompression = BI_RGB;
2004 bi->bmiHeader.biSizeImage = 0;
2005 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
2006 memset(buf, 0xAA, sizeof(buf));
2007 SetLastError(0xdeadbeef);
2008 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2009 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2010 lines, bm.bmHeight, GetLastError());
2011
2012 GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, pal_ents );
2013
2014 for (i = 0; i < 256; i++)
2015 {
2016 RGBQUAD expect;
2017
2018 if (i < 10 || i >= 246)
2019 {
2020 int entry = i < 10 ? i : i - 236;
2021 expect.rgbRed = pal_ents[entry].peRed;
2022 expect.rgbGreen = pal_ents[entry].peGreen;
2023 expect.rgbBlue = pal_ents[entry].peBlue;
2024 }
2025 else
2026 {
2027 expect.rgbRed = (i & 0x07) << 5;
2028 expect.rgbGreen = (i & 0x38) << 2;
2029 expect.rgbBlue = i & 0xc0;
2030 }
2031 expect.rgbReserved = 0;
2032
2033 ok(!memcmp(bi->bmiColors + i, &expect, sizeof(expect)),
2034 "expected bmiColors[%d] %x %x %x %x - got %x %x %x %x\n", i,
2035 expect.rgbRed, expect.rgbGreen, expect.rgbBlue, expect.rgbReserved,
2036 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2037 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2038 }
2039
2040 /* retrieve 24-bit DIB data */
2041 memset(bi, 0, sizeof(*bi));
2042 bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2043 bi->bmiHeader.biWidth = bm.bmWidth;
2044 bi->bmiHeader.biHeight = bm.bmHeight;
2045 bi->bmiHeader.biPlanes = 1;
2046 bi->bmiHeader.biBitCount = 24;
2047 bi->bmiHeader.biCompression = BI_RGB;
2048 bi->bmiHeader.biSizeImage = 0;
2049 memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
2050 memset(buf, 0xAA, sizeof(buf));
2051 SetLastError(0xdeadbeef);
2052 lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
2053 ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
2054 lines, bm.bmHeight, GetLastError());
2055 ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
2056
2057 /* the color table doesn't exist for 24-bit images */
2058 for (i = 0; i < 256; i++)
2059 {
2060 ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
2061 bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
2062 "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
2063 bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
2064 bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
2065 }
2066
2067 /* returned bits are DWORD aligned and upside down */
2068 ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
2069 DeleteObject(hbmp);
2070
2071 ReleaseDC(0, hdc);
2072 }
2073
2074 static void test_GetDIBits_BI_BITFIELDS(void)
2075 {
2076 /* Try a screen resolution detection technique
2077 * from the September 1999 issue of Windows Developer's Journal
2078 * which seems to be in widespread use.
2079 * http://www.lesher.ws/highcolor.html
2080 * http://www.lesher.ws/vidfmt.c
2081 * It hinges on being able to retrieve the bitmaps
2082 * for the three primary colors in non-paletted 16 bit mode.
2083 */
2084 char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
2085 DWORD bits[32];
2086 LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
2087 DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
2088 HDC hdc;
2089 HBITMAP hbm;
2090 int ret;
2091 void *ptr;
2092
2093 memset(dibinfo, 0, sizeof(dibinfo_buf));
2094 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2095
2096 hdc = GetDC(NULL);
2097 ok(hdc != NULL, "GetDC failed?\n");
2098 hbm = CreateCompatibleBitmap(hdc, 1, 1);
2099 ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
2100
2101 /* Call GetDIBits to fill in bmiHeader. */
2102 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2103 ok(ret == 1, "GetDIBits failed\n");
2104 if (dibinfo->bmiHeader.biBitCount > 8)
2105 {
2106 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2107 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2108 "compression is %u (%d bpp)\n", dibinfo->bmiHeader.biCompression, dibinfo->bmiHeader.biBitCount );
2109
2110 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2111 {
2112 ok( !bitmasks[0], "red mask is set\n" );
2113 ok( !bitmasks[1], "green mask is set\n" );
2114 ok( !bitmasks[2], "blue mask is set\n" );
2115
2116 /* test with NULL bits pointer and correct bpp */
2117 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2118 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2119 ok(ret == 1, "GetDIBits failed\n");
2120
2121 ok( bitmasks[0] != 0, "red mask is not set\n" );
2122 ok( bitmasks[1] != 0, "green mask is not set\n" );
2123 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2124 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2125
2126 /* test with valid bits pointer */
2127 memset(dibinfo, 0, sizeof(dibinfo_buf));
2128 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2129 ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
2130 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2131 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2132 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2133 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2134
2135 ok( bitmasks[0] != 0, "red mask is not set\n" );
2136 ok( bitmasks[1] != 0, "green mask is not set\n" );
2137 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2138 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2139
2140 /* now with bits and 0 lines */
2141 memset(dibinfo, 0, sizeof(dibinfo_buf));
2142 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2143 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2144 SetLastError(0xdeadbeef);
2145 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2146 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2147
2148 ok( !bitmasks[0], "red mask is set\n" );
2149 ok( !bitmasks[1], "green mask is set\n" );
2150 ok( !bitmasks[2], "blue mask is set\n" );
2151 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2152
2153 memset(bitmasks, 0, 3*sizeof(DWORD));
2154 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2155 ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
2156 ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
2157
2158 ok( bitmasks[0] != 0, "red mask is not set\n" );
2159 ok( bitmasks[1] != 0, "green mask is not set\n" );
2160 ok( bitmasks[2] != 0, "blue mask is not set\n" );
2161 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2162 }
2163 }
2164 else skip("bitmap in colortable mode, skipping BI_BITFIELDS tests\n");
2165
2166 DeleteObject(hbm);
2167
2168 /* same thing now with a 32-bpp DIB section */
2169
2170 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2171 dibinfo->bmiHeader.biWidth = 1;
2172 dibinfo->bmiHeader.biHeight = 1;
2173 dibinfo->bmiHeader.biPlanes = 1;
2174 dibinfo->bmiHeader.biBitCount = 32;
2175 dibinfo->bmiHeader.biCompression = BI_RGB;
2176 dibinfo->bmiHeader.biSizeImage = 0;
2177 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2178 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2179 dibinfo->bmiHeader.biClrUsed = 0;
2180 dibinfo->bmiHeader.biClrImportant = 0;
2181 bitmasks[0] = 0x0000ff;
2182 bitmasks[1] = 0x00ff00;
2183 bitmasks[2] = 0xff0000;
2184 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2185 ok( hbm != 0, "failed to create bitmap\n" );
2186
2187 memset(dibinfo, 0, sizeof(dibinfo_buf));
2188 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2189 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2190 ok(ret == 1, "GetDIBits failed\n");
2191 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2192
2193 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2194 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2195 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2196 ok( !bitmasks[0], "red mask is set\n" );
2197 ok( !bitmasks[1], "green mask is set\n" );
2198 ok( !bitmasks[2], "blue mask is set\n" );
2199
2200 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2201 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2202 ok(ret == 1, "GetDIBits failed\n");
2203 ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2204 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS ||
2205 broken( dibinfo->bmiHeader.biCompression == BI_RGB ), /* nt4 sp3 */
2206 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2207 if (dibinfo->bmiHeader.biCompression == BI_BITFIELDS)
2208 {
2209 ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
2210 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2211 ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
2212 }
2213 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2214
2215 DeleteObject(hbm);
2216
2217 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2218 dibinfo->bmiHeader.biWidth = 1;
2219 dibinfo->bmiHeader.biHeight = 1;
2220 dibinfo->bmiHeader.biPlanes = 1;
2221 dibinfo->bmiHeader.biBitCount = 32;
2222 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2223 dibinfo->bmiHeader.biSizeImage = 0;
2224 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2225 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2226 dibinfo->bmiHeader.biClrUsed = 0;
2227 dibinfo->bmiHeader.biClrImportant = 0;
2228 bitmasks[0] = 0x0000ff;
2229 bitmasks[1] = 0x00ff00;
2230 bitmasks[2] = 0xff0000;
2231 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2232 ok( hbm != 0, "failed to create bitmap\n" );
2233
2234 if (hbm)
2235 {
2236 memset(dibinfo, 0, sizeof(dibinfo_buf));
2237 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2238 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2239 ok(ret == 1, "GetDIBits failed\n");
2240
2241 ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
2242 "compression is %u\n", dibinfo->bmiHeader.biCompression );
2243 ok( !bitmasks[0], "red mask is set\n" );
2244 ok( !bitmasks[1], "green mask is set\n" );
2245 ok( !bitmasks[2], "blue mask is set\n" );
2246
2247 dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
2248 ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
2249 ok(ret == 1, "GetDIBits failed\n");
2250 ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
2251 ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
2252 ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
2253 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2254
2255 DeleteObject(hbm);
2256 }
2257
2258 /* 24-bpp DIB sections don't have bitfields */
2259
2260 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2261 dibinfo->bmiHeader.biWidth = 1;
2262 dibinfo->bmiHeader.biHeight = 1;
2263 dibinfo->bmiHeader.biPlanes = 1;
2264 dibinfo->bmiHeader.biBitCount = 24;
2265 dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
2266 dibinfo->bmiHeader.biSizeImage = 0;
2267 dibinfo->bmiHeader.biXPelsPerMeter = 0;
2268 dibinfo->bmiHeader.biYPelsPerMeter = 0;
2269 dibinfo->bmiHeader.biClrUsed = 0;
2270 dibinfo->bmiHeader.biClrImportant = 0;
2271 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2272 ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
2273 dibinfo->bmiHeader.biCompression = BI_RGB;
2274 hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
2275 ok( hbm != 0, "failed to create bitmap\n" );
2276
2277 memset(dibinfo, 0, sizeof(dibinfo_buf));
2278 dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2279 ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
2280 ok(ret == 1, "GetDIBits failed\n");
2281 ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2282
2283 ok( dibinfo->bmiHeader.biCompression == BI_RGB,
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 == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
2293 ok( !bitmasks[0], "red mask is set\n" );
2294 ok( !bitmasks[1], "green mask is set\n" );
2295 ok( !bitmasks[2], "blue mask is set\n" );
2296 ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
2297
2298 DeleteObject(hbm);
2299 ReleaseDC(NULL, hdc);
2300 }
2301
2302 static void test_select_object(void)
2303 {
2304 HDC hdc;
2305 HBITMAP hbm, hbm_old;
2306 INT planes, bpp, i;
2307 DWORD depths[] = {8, 15, 16, 24, 32};
2308 BITMAP bm;
2309 DWORD bytes;
2310
2311 hdc = GetDC(0);
2312 ok(hdc != 0, "GetDC(0) failed\n");
2313 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2314 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2315
2316 hbm_old = SelectObject(hdc, hbm);
2317 ok(hbm_old == 0, "SelectObject should fail\n");
2318
2319 DeleteObject(hbm);
2320 ReleaseDC(0, hdc);
2321
2322 hdc = CreateCompatibleDC(0);
2323 ok(hdc != 0, "GetDC(0) failed\n");
2324 hbm = CreateCompatibleBitmap(hdc, 10, 10);
2325 ok(hbm != 0, "CreateCompatibleBitmap failed\n");
2326
2327 hbm_old = SelectObject(hdc, hbm);
2328 ok(hbm_old != 0, "SelectObject failed\n");
2329 hbm_old = SelectObject(hdc, hbm_old);
2330 ok(hbm_old == hbm, "SelectObject failed\n");
2331
2332 DeleteObject(hbm);
2333
2334 /* test an 1-bpp bitmap */
2335 planes = GetDeviceCaps(hdc, PLANES);
2336 bpp = 1;
2337
2338 hbm = CreateBitmap(10, 10, planes, bpp, NULL);
2339 ok(hbm != 0, "CreateBitmap failed\n");
2340
2341 hbm_old = SelectObject(hdc, hbm);
2342 ok(hbm_old != 0, "SelectObject failed\n");
2343 hbm_old = SelectObject(hdc, hbm_old);
2344 ok(hbm_old == hbm, "SelectObject failed\n");
2345
2346 DeleteObject(hbm);
2347
2348 for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
2349 /* test a color bitmap to dc bpp matching */
2350 planes = GetDeviceCaps(hdc, PLANES);
2351 bpp = GetDeviceCaps(hdc, BITSPIXEL);
2352
2353 hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
2354 ok(hbm != 0, "CreateBitmap failed\n");
2355
2356 hbm_old = SelectObject(hdc, hbm);
2357 if(depths[i] == bpp ||
2358 (bpp == 16 && depths[i] == 15) /* 16 and 15 bpp are compatible */
2359 ) {
2360 ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
2361 SelectObject(hdc, hbm_old);
2362 } else {
2363 ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
2364 }
2365
2366 memset(&bm, 0xAA, sizeof(bm));
2367 bytes = GetObject(hbm, sizeof(bm), &bm);
2368 ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
2369 ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
2370 ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
2371 ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
2372 ok(bm.bmWidthBytes == get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
2373 ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
2374 if(depths[i] == 15) {
2375 ok(bm.bmBitsPixel == 16, "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
2376 } else {
2377 ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
2378 }
2379 ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2380
2381 DeleteObject(hbm);
2382 }
2383
2384 DeleteDC(hdc);
2385 }
2386
2387 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
2388 {
2389 INT ret;
2390 BITMAP bm;
2391
2392 ret = GetObjectType(hbmp);
2393 ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
2394
2395 ret = GetObject(hbmp, 0, 0);
2396 ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
2397
2398 memset(&bm, 0xDA, sizeof(bm));
2399 SetLastError(0xdeadbeef);
2400 ret = GetObject(hbmp, sizeof(bm), &bm);
2401 if (!ret) /* XP, only for curObj2 */ return;
2402 ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
2403 ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2404 ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2405 ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2406 ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2407 ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2408 ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2409 ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2410 }
2411
2412 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2413
2414 static void test_CreateBitmap(void)
2415 {
2416 BITMAP bmp;
2417 HDC screenDC = GetDC(0);
2418 HDC hdc = CreateCompatibleDC(screenDC);
2419 UINT i, expect = 0;
2420
2421 /* all of these are the stock monochrome bitmap */
2422 HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2423 HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2424 HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2425 HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2426 HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2427 HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2428
2429 /* these 2 are not the stock monochrome bitmap */
2430 HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2431 HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2432
2433 HBITMAP old1 = SelectObject(hdc, bm2);
2434 HBITMAP old2 = SelectObject(screenDC, bm3);
2435 SelectObject(hdc, old1);
2436 SelectObject(screenDC, old2);
2437
2438 ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2439 "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2440 bm, bm1, bm4, bm5, curObj1, old1);
2441 ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2442 todo_wine
2443 ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
2444 ok(old2 == 0, "old2 %p\n", old2);
2445
2446 test_mono_1x1_bmp(bm);
2447 test_mono_1x1_bmp(bm1);
2448 test_mono_1x1_bmp(bm2);
2449 test_mono_1x1_bmp(bm3);
2450 test_mono_1x1_bmp(bm4);
2451 test_mono_1x1_bmp(bm5);
2452 test_mono_1x1_bmp(old1);
2453 test_mono_1x1_bmp(curObj1);
2454
2455 DeleteObject(bm);
2456 DeleteObject(bm1);
2457 DeleteObject(bm2);
2458 DeleteObject(bm3);
2459 DeleteObject(bm4);
2460 DeleteObject(bm5);
2461
2462 DeleteDC(hdc);
2463 ReleaseDC(0, screenDC);
2464
2465 /* show that Windows ignores the provided bm.bmWidthBytes */
2466 bmp.bmType = 0;
2467 bmp.bmWidth = 1;
2468 bmp.bmHeight = 1;
2469 bmp.bmWidthBytes = 28;
2470 bmp.bmPlanes = 1;
2471 bmp.bmBitsPixel = 1;
2472 bmp.bmBits = NULL;
2473 bm = CreateBitmapIndirect(&bmp);
2474 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2475 test_mono_1x1_bmp(bm);
2476 DeleteObject(bm);
2477
2478 /* Test how the bmBitsPixel field is treated */
2479 for(i = 1; i <= 33; i++) {
2480 bmp.bmType = 0;
2481 bmp.bmWidth = 1;
2482 bmp.bmHeight = 1;
2483 bmp.bmWidthBytes = 28;
2484 bmp.bmPlanes = 1;
2485 bmp.bmBitsPixel = i;
2486 bmp.bmBits = NULL;
2487 SetLastError(0xdeadbeef);
2488 bm = CreateBitmapIndirect(&bmp);
2489 if(i > 32) {
2490 DWORD error = GetLastError();
2491 ok(bm == 0, "CreateBitmapIndirect for %d bpp succeeded\n", i);
2492 ok(error == ERROR_INVALID_PARAMETER, "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2493 DeleteObject(bm);
2494 continue;
2495 }
2496 ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2497 GetObject(bm, sizeof(bmp), &bmp);
2498 if(i == 1) {
2499 expect = 1;
2500 } else if(i <= 4) {
2501 expect = 4;
2502 } else if(i <= 8) {
2503 expect = 8;
2504 } else if(i <= 16) {
2505 expect = 16;
2506 } else if(i <= 24) {
2507 expect = 24;
2508 } else if(i <= 32) {
2509 expect = 32;
2510 }
2511 ok(bmp.bmBitsPixel == expect, "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2512 i, bmp.bmBitsPixel, expect);
2513 DeleteObject(bm);
2514 }
2515 }
2516
2517 static void test_bitmapinfoheadersize(void)
2518 {
2519 HBITMAP hdib;
2520 BITMAPINFO bmi;
2521 BITMAPCOREINFO bci