0a69fe41ddf8e1c887b3b7c17149a7e1caa32268
[reactos.git] / modules / rostests / apitests / win32nt / ntgdi / NtGdiCreateDIBSection.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: Test for NtGdiCreateDIBSection
5 * PROGRAMMERS:
6 */
7
8 #include <win32nt.h>
9
10 /*
11 HBITMAP
12 APIENTRY
13 NtGdiCreateDIBSection(
14 IN HDC hDC,
15 IN OPTIONAL HANDLE hSection,
16 IN DWORD dwOffset,
17 IN LPBITMAPINFO pbmi,
18 IN DWORD iUsage,
19 IN UINT cjHeader,
20 IN FLONG fl,
21 IN ULONG_PTR dwColorSpace,
22 OUT PVOID *ppvBits)
23 */
24
25 ULONG
26 GetBitmapSize(BITMAPINFOHEADER *pbih)
27 {
28 ULONG WidthBits, WidthBytes;
29
30 WidthBits = pbih->biWidth * pbih->biBitCount * pbih->biPlanes;
31 WidthBytes = ((WidthBits + 31) & ~ 31) >> 3;
32
33 return pbih->biHeight * WidthBytes;
34 }
35
36
37 START_TEST(NtGdiCreateDIBSection)
38 {
39 HBITMAP hbmp;
40 HDC hDC;
41 ULONG cjHeader;
42 PVOID pvBits = NULL;
43 ULONG cEntries;
44 DIBSECTION dibsection;
45
46 struct
47 {
48 BITMAPINFOHEADER bmiHeader;
49 RGBQUAD bmiColors[100];
50 } bmi;
51 PBITMAPINFO pbmi = (PBITMAPINFO)&bmi;
52 PBITMAPINFOHEADER pbih = (PBITMAPINFOHEADER)&bmi.bmiHeader;
53 PBITMAPV4HEADER pbV4h = (PBITMAPV4HEADER)&bmi.bmiHeader;
54 PBITMAPV5HEADER pbV5h = (PBITMAPV5HEADER)&bmi.bmiHeader;
55
56 HANDLE hSection;
57 NTSTATUS Status;
58 LARGE_INTEGER MaximumSize;
59
60 hDC = GetDC(0);
61 pbih->biSize = sizeof(BITMAPINFOHEADER);
62 pbih->biWidth = 2;
63 pbih->biHeight = 2;
64 pbih->biPlanes = 1;
65 pbih->biBitCount = 1;
66 pbih->biCompression = BI_RGB;
67 pbih->biSizeImage = 0;
68 pbih->biXPelsPerMeter = 100;
69 pbih->biYPelsPerMeter = 100;
70 pbih->biClrUsed = 2;
71 pbih->biClrImportant = 2;
72
73 cEntries = 0;
74
75 /** iUsage = 0 (DIB_RGB_COLORS) ***********************************************/
76
77 cjHeader = bmi.bmiHeader.biSize + cEntries * 4 + 8;
78
79 /* Test something simple */
80 SetLastError(0);
81 pvBits = 0;
82 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
83 TEST(pvBits != NULL);
84 TEST(hbmp != 0);
85 // TEST(GetLastError() == 0);
86 TEST(GetObject(hbmp, sizeof(DIBSECTION), &dibsection) == sizeof(DIBSECTION));
87 TEST(dibsection.dsBitfields[0] == 0);
88 TEST(dibsection.dsBitfields[1] == 0);
89 TEST(dibsection.dsBitfields[2] == 0);
90 TEST(dibsection.dshSection == 0);
91 TEST(dibsection.dsOffset == 0);
92 if (hbmp) DeleteObject(hbmp);
93
94
95 /* Test a 0 HDC */
96 SetLastError(0);
97 pvBits = 0;
98 hbmp = NtGdiCreateDIBSection(0, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
99 TEST(pvBits != NULL);
100 TEST(hbmp != 0);
101 TEST(GetLastError() == ERROR_NOT_ENOUGH_MEMORY);
102 if (hbmp) DeleteObject(hbmp);
103
104 /* Test a wrong HDC */
105 SetLastError(0);
106 pvBits = 0;
107 hbmp = NtGdiCreateDIBSection((HDC)0xdeadbeef, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
108 TEST(pvBits != 0);
109 TEST(hbmp != 0);
110 TEST(GetLastError() == 8);
111 if (hbmp) DeleteObject(hbmp);
112
113 /* Test pbmi = NULL */
114 SetLastError(0);
115 pvBits = (PVOID)-1;
116 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, NULL, 0, cjHeader, 0, 0, &pvBits);
117 TEST(pvBits == (PVOID)-1);
118 TEST(hbmp == 0);
119 TEST(GetLastError() == 0);
120 if (hbmp) DeleteObject(hbmp);
121
122 /* Test invalid pbmi */
123 SetLastError(0);
124 pvBits = (PVOID)-1;
125 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, (PVOID)0x80001234, 0, cjHeader, 0, 0, &pvBits);
126 TEST(pvBits == (PVOID)-1);
127 TEST(hbmp == 0);
128 TEST(GetLastError() == ERROR_INVALID_PARAMETER);
129 if (hbmp) DeleteObject(hbmp);
130
131 /* Test invalid pbmi */
132 SetLastError(0);
133 pvBits = (PVOID)-1;
134 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, (PVOID)1, 0, cjHeader, 0, 0, &pvBits);
135 TEST(pvBits == (PVOID)-1);
136 TEST(hbmp == 0);
137 TEST(GetLastError() == ERROR_INVALID_PARAMETER);
138 if (hbmp) DeleteObject(hbmp);
139
140 /* Test ppvBits = NULL */
141 SetLastError(0);
142 hbmp = NtGdiCreateDIBSection(0, NULL, 0, pbmi, 0, cjHeader, 0, 0, NULL);
143 TEST(hbmp == 0);
144 TEST(GetLastError() == ERROR_INVALID_PARAMETER);
145 if (hbmp) DeleteObject(hbmp);
146
147 /* Test ppvBits = NULL and pbmi == 0*/
148 SetLastError(0);
149 hbmp = NtGdiCreateDIBSection(0, NULL, 0, NULL, 0, cjHeader, 0, 0, NULL);
150 TEST(hbmp == 0);
151 TEST(GetLastError() == 0);
152 if (hbmp) DeleteObject(hbmp);
153
154 /* Test ppvBits = NULL and wrong cjHeader */
155 SetLastError(0);
156 hbmp = NtGdiCreateDIBSection(0, NULL, 0, pbmi, 0, cjHeader+4, 0, 0, NULL);
157 TEST(hbmp == 0);
158 TEST(GetLastError() == 0);
159 if (hbmp) DeleteObject(hbmp);
160
161 /* Test ppvBits = NULL and cjHeader = 0 */
162 SetLastError(0);
163 hbmp = NtGdiCreateDIBSection(0, NULL, 0, pbmi, 0, 0, 0, 0, NULL);
164 TEST(hbmp == 0);
165 TEST(GetLastError() == 0);
166 if (hbmp) DeleteObject(hbmp);
167
168 /* Test wrong cjHeader */
169 SetLastError(0);
170 pvBits = (PVOID)-1;
171 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader+4, 0, 0, &pvBits);
172 pvBits = (PVOID)-1;
173 TEST(hbmp == 0);
174 TEST(GetLastError() == 0);
175 if (hbmp) DeleteObject(hbmp);
176
177 /* Test different bitcount */
178 pbih->biBitCount = 4;
179 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
180 TEST(hbmp != 0);
181 if (hbmp) DeleteObject(hbmp);
182
183 pbih->biBitCount = 8;
184 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
185 TEST(hbmp != 0);
186 if (hbmp) DeleteObject(hbmp);
187
188 cjHeader = pbih->biSize;
189 pbih->biBitCount = 16;
190 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
191 TEST(hbmp != 0);
192 if (hbmp) DeleteObject(hbmp);
193
194 pbih->biBitCount = 24;
195 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
196 TEST(hbmp != 0);
197 if (hbmp) DeleteObject(hbmp);
198
199 pbih->biBitCount = 32;
200 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
201 TEST(hbmp != 0);
202 if (hbmp) DeleteObject(hbmp);
203
204 /* Test BI_BITFIELDS */
205 cEntries = 3;
206 cjHeader = pbih->biSize + cEntries * sizeof(DWORD);
207 pbih->biBitCount = 16;
208 pbih->biCompression = BI_BITFIELDS;
209 ((DWORD*)pbmi->bmiColors)[0] = 0x0007;
210 ((DWORD*)pbmi->bmiColors)[1] = 0x0038;
211 ((DWORD*)pbmi->bmiColors)[2] = 0x01C0;
212 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
213 TEST(hbmp != 0);
214 TEST(GetObject(hbmp, sizeof(DIBSECTION), &dibsection) == sizeof(DIBSECTION));
215 TEST(dibsection.dsBm.bmType == 0);
216 TEST(dibsection.dsBm.bmWidth == 2);
217 TEST(dibsection.dsBm.bmHeight == 2);
218 TEST(dibsection.dsBm.bmWidthBytes == 4);
219 TEST(dibsection.dsBm.bmPlanes == 1);
220 TEST(dibsection.dsBm.bmBitsPixel == 16);
221 TEST(dibsection.dsBm.bmBits == pvBits);
222 TEST(dibsection.dsBmih.biSize == sizeof(BITMAPINFOHEADER));
223 TEST(dibsection.dsBmih.biWidth == 2);
224 TEST(dibsection.dsBmih.biHeight == 2);
225 TEST(dibsection.dsBmih.biPlanes == 1);
226 TEST(dibsection.dsBmih.biBitCount == 16);
227 TEST(dibsection.dsBmih.biCompression == BI_BITFIELDS);
228 TEST(dibsection.dsBmih.biSizeImage == 8);
229 TEST(dibsection.dsBmih.biXPelsPerMeter == 0);
230 TEST(dibsection.dsBmih.biYPelsPerMeter == 0);
231 TEST(dibsection.dsBmih.biClrUsed == 0);
232 TEST(dibsection.dsBmih.biClrImportant == 0);
233 TEST(dibsection.dsBitfields[0] == 0x0007);
234 TEST(dibsection.dsBitfields[1] == 0x0038);
235 TEST(dibsection.dsBitfields[2] == 0x01C0);
236 TEST(dibsection.dshSection == 0);
237 TEST(dibsection.dsOffset == 0);
238
239 printf("dib with bitfileds: %p\n", hbmp);
240 //system("PAUSE");
241
242 if (hbmp) DeleteObject(hbmp);
243
244
245 /* Test BI_BITFIELDS */
246 SetLastError(0);
247 pvBits = 0;
248
249 pbih->biSize = sizeof(BITMAPINFOHEADER);
250 pbih->biWidth = 2;
251 pbih->biHeight = 2;
252 pbih->biPlanes = 1;
253 pbih->biBitCount = 4;
254 pbih->biCompression = BI_RGB;
255 pbih->biSizeImage = 0;
256 pbih->biXPelsPerMeter = 100;
257 pbih->biYPelsPerMeter = 100;
258 pbih->biClrUsed = 0;
259 pbih->biClrImportant = 0;
260 ((DWORD*)pbmi->bmiColors)[0] = 0xF800;
261 ((DWORD*)pbmi->bmiColors)[1] = 0x00ff00;
262 ((DWORD*)pbmi->bmiColors)[2] = 0x0000ff;
263 cEntries = 0;
264 cjHeader = bmi.bmiHeader.biSize + cEntries * 4 + 20;
265
266
267 /** iUsage = 1 (DIB_PAL_COLORS) ***********************************************/
268
269 pbmi->bmiHeader.biClrUsed = 2;
270 pbmi->bmiHeader.biClrImportant = 2;
271
272 cEntries = 2;
273 cjHeader = bmi.bmiHeader.biSize + cEntries * 4 + 8;
274
275 /* Test iUsage = 1 */
276 SetLastError(0);
277 pvBits = (PVOID)-1;
278 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 1, cjHeader, 0, 0, &pvBits);
279 TEST(pvBits == (PVOID)-1);
280 TEST(hbmp == 0);
281 TEST(GetLastError() == 0);
282 if (hbmp) DeleteObject(hbmp);
283
284
285
286 /** iUsage = 2 (???) **********************************************************/
287
288 /* Test iUsage = 2 */
289 SetLastError(0);
290 pvBits = (PVOID)-1;
291 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 2, cjHeader, 0, 0, &pvBits);
292 TEST(pvBits == (PVOID)-1);
293 TEST(hbmp == 0);
294 TEST(GetLastError() == 0);
295 if (hbmp) DeleteObject(hbmp);
296
297
298 /** wrong iUsage **************************************************************/
299
300 cEntries = 0;
301 cjHeader = bmi.bmiHeader.biSize + cEntries * 4 + 8;
302
303 /* Test iUsage = 3 */
304 SetLastError(0);
305 pvBits = (PVOID)-1;
306 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 3, cjHeader, 0, 0, &pvBits);
307 TEST(pvBits == (PVOID)-1);
308 TEST(hbmp == 0);
309 TEST(GetLastError() == ERROR_INVALID_PARAMETER);
310 if (hbmp) DeleteObject(hbmp);
311
312 /* Test iUsage = 3 */
313 SetLastError(0);
314 pvBits = (PVOID)-1;
315 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 3, cjHeader+4, 0, 0, &pvBits);
316 TEST(pvBits == (PVOID)-1);
317 TEST(hbmp == 0);
318 TEST(GetLastError() == 0);
319 if (hbmp) DeleteObject(hbmp);
320
321 /* Test wrong iUsage */
322 SetLastError(0);
323 pvBits = (PVOID)-1;
324 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, -55, cjHeader, 0, 0, &pvBits);
325 TEST(pvBits == (PVOID)-1);
326 TEST(hbmp == 0);
327 TEST(GetLastError() == ERROR_INVALID_PARAMETER);
328 if (hbmp) DeleteObject(hbmp);
329
330 /* Test wrong iUsage and wrong cjHeader */
331 SetLastError(0);
332 pvBits = (PVOID)-1;
333 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, -55, cjHeader+4, 0, 0, &pvBits);
334 TEST(pvBits == (PVOID)-1);
335 TEST(hbmp == 0);
336 TEST(GetLastError() == 0);
337 if (hbmp) DeleteObject(hbmp);
338
339 /* increased header size */
340 pbih->biSize = sizeof(BITMAPINFOHEADER) + 4;
341 cjHeader = pbih->biSize + cEntries * 4 + 8;
342 SetLastError(0);
343 pvBits = 0;
344 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
345 TEST(pvBits != NULL);
346 TEST(hbmp != 0);
347 TEST(GetLastError() == 8);
348 if (hbmp) DeleteObject(hbmp);
349
350 /* increased header size */
351 pbih->biSize = sizeof(BITMAPINFOHEADER) + 2;
352 cjHeader = pbih->biSize + cEntries * 4 + 8;
353 SetLastError(0);
354 pvBits = (PVOID)-1;
355 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
356 TEST(pvBits == (PVOID)-1);
357 TEST(hbmp == 0);
358 TEST(GetLastError() == 0);
359 if (hbmp) DeleteObject(hbmp);
360
361 /* decreased header size */
362 pbih->biSize = sizeof(BITMAPINFOHEADER) - 4;
363 cjHeader = pbih->biSize + cEntries * 4 + 8;
364 SetLastError(0);
365 pvBits = (PVOID)-1;
366 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
367 TEST(pvBits == (PVOID)-1);
368 TEST(hbmp == 0);
369 TEST(GetLastError() == 0);
370 if (hbmp) DeleteObject(hbmp);
371
372
373 /** BITMAPV4HEADER ************************************************************/
374
375 pbV4h->bV4Size = sizeof(BITMAPV4HEADER);
376 pbV4h->bV4Width = 2;
377 pbV4h->bV4Height = 3;
378 pbV4h->bV4Planes = 1;
379 pbV4h->bV4BitCount = 1;
380 pbV4h->bV4V4Compression = BI_RGB;
381 pbV4h->bV4SizeImage = 0;
382 pbV4h->bV4XPelsPerMeter = 100;
383 pbV4h->bV4YPelsPerMeter = 100;
384 pbV4h->bV4ClrUsed = 0;
385 pbV4h->bV4ClrImportant = 0;
386 pbV4h->bV4RedMask = 0;
387 pbV4h->bV4GreenMask = 0;
388 pbV4h->bV4BlueMask = 0;
389 pbV4h->bV4AlphaMask = 0;
390 pbV4h->bV4CSType = 0;
391 memset(&pbV4h->bV4Endpoints, 0, sizeof(CIEXYZTRIPLE));
392 pbV4h->bV4GammaRed = 0;
393 pbV4h->bV4GammaGreen = 0;
394 pbV4h->bV4GammaBlue = 0;
395
396 cEntries = 0;
397 cjHeader = bmi.bmiHeader.biSize + cEntries * 4 + 8;
398
399 /* Test something simple */
400 SetLastError(0);
401 pvBits = 0;
402 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
403 TEST(pvBits != NULL);
404 TEST(hbmp != 0);
405 TEST(GetLastError() == 8);
406 if (hbmp) DeleteObject(hbmp);
407
408
409 /** BITMAPV5HEADER ************************************************************/
410
411 pbV5h->bV5Size = sizeof(BITMAPV5HEADER);
412 pbV5h->bV5Width = 2;
413 pbV5h->bV5Height = 3;
414 pbV5h->bV5Planes = 1;
415 pbV5h->bV5BitCount = 1;
416 pbV5h->bV5Compression = BI_RGB;
417 pbV5h->bV5SizeImage = 0;
418 pbV5h->bV5XPelsPerMeter = 100;
419 pbV5h->bV5YPelsPerMeter = 100;
420 pbV5h->bV5ClrUsed = 2;
421 pbV5h->bV5ClrImportant = 2;
422 pbV5h->bV5RedMask = 0;
423 pbV5h->bV5GreenMask = 0;
424 pbV5h->bV5BlueMask = 0;
425 pbV5h->bV5AlphaMask = 0;
426 pbV5h->bV5CSType = 0;
427 memset(&pbV5h->bV5Endpoints, 0, sizeof(CIEXYZTRIPLE));
428 pbV5h->bV5GammaRed = 0;
429 pbV5h->bV5GammaGreen = 0;
430 pbV5h->bV5GammaBlue = 0;
431 pbV5h->bV5Intent = 0;
432 pbV5h->bV5ProfileData = 0;
433 pbV5h->bV5ProfileSize = 0;
434 pbV5h->bV5Reserved = 0;
435
436 cEntries = 0;
437 cjHeader = pbV5h->bV5Size + cEntries * 4 + 8;
438
439 /* Test something simple */
440 SetLastError(0);
441 pvBits = 0;
442 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
443 TEST(pvBits != NULL);
444 TEST(hbmp != 0);
445 TEST(GetLastError() == 8);
446 if (hbmp) DeleteObject(hbmp);
447
448 /* increased header size */
449 pbV5h->bV5Size = sizeof(BITMAPV5HEADER) + 64;
450 cjHeader = pbV5h->bV5Size + cEntries * 4 + 8;
451 SetLastError(0);
452 pvBits = 0;
453 hbmp = NtGdiCreateDIBSection(hDC, NULL, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
454 TEST(pvBits != NULL);
455 TEST(hbmp != 0);
456 TEST(GetLastError() == 8);
457 if (hbmp) DeleteObject(hbmp);
458
459 /* Test section */
460 MaximumSize.QuadPart = 4096;
461 Status = NtCreateSection(&hSection,
462 SECTION_ALL_ACCESS,
463 NULL,
464 &MaximumSize,
465 PAGE_READWRITE,
466 SEC_COMMIT,
467 NULL);
468 ASSERT(NT_SUCCESS(Status));
469
470 SetLastError(0);
471 pvBits = 0;
472 hbmp = NtGdiCreateDIBSection(hDC, hSection, 0, pbmi, 0, cjHeader, 0, 0, &pvBits);
473 TEST(pvBits != NULL);
474 TEST(hbmp != 0);
475 // TEST(GetLastError() == 0);
476 printf("hbmp = %p, pvBits = %p, hSection = %p\n", hbmp, pvBits, hSection);
477 //system("PAUSE");
478 if (hbmp) DeleteObject(hbmp);
479 }