[GDIPLUS_WINETEST] Sync with Wine 3.0. CORE-14225
[reactos.git] / modules / rostests / winetests / gdiplus / image.c
1 /*
2 * Unit test suite for images
3 *
4 * Copyright (C) 2007 Google (Evan Stade)
5 * Copyright (C) 2012, 2016 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 "precomp.h"
23
24 #include <assert.h>
25 #include <ole2.h>
26
27 /* FIXME: They belong to gdipluseffects.h */
28 DEFINE_GUID(BlurEffectGuid, 0x633c80a4, 0x1843, 0x482b, 0x9e, 0xf2, 0xbe, 0x28, 0x34, 0xc5, 0xfd, 0xd4);
29 DEFINE_GUID(SharpenEffectGuid, 0x63cbf3ee, 0xc526, 0x402c, 0x8f, 0x71, 0x62, 0xc5, 0x40, 0xbf, 0x51, 0x42);
30 DEFINE_GUID(ColorMatrixEffectGuid, 0x718f2615, 0x7933, 0x40e3, 0xa5, 0x11, 0x5f, 0x68, 0xfe, 0x14, 0xdd, 0x74);
31 DEFINE_GUID(ColorLUTEffectGuid, 0xa7ce72a9, 0x0f7f, 0x40d7, 0xb3, 0xcc, 0xd0, 0xc0, 0x2d, 0x5c, 0x32, 0x12);
32 DEFINE_GUID(BrightnessContrastEffectGuid, 0xd3a1dbe1, 0x8ec4, 0x4c17, 0x9f, 0x4c, 0xea, 0x97, 0xad, 0x1c, 0x34, 0x3d);
33 DEFINE_GUID(HueSaturationLightnessEffectGuid, 0x8b2dd6c3, 0xeb07, 0x4d87, 0xa5, 0xf0, 0x71, 0x08, 0xe2, 0x6a, 0x9c, 0x5f);
34 DEFINE_GUID(LevelsEffectGuid, 0x99c354ec, 0x2a31, 0x4f3a, 0x8c, 0x34, 0x17, 0xa8, 0x03, 0xb3, 0x3a, 0x25);
35 DEFINE_GUID(TintEffectGuid, 0x1077af00, 0x2848, 0x4441, 0x94, 0x89, 0x44, 0xad, 0x4c, 0x2d, 0x7a, 0x2c);
36 DEFINE_GUID(ColorBalanceEffectGuid, 0x537e597d, 0x251e, 0x48da, 0x96, 0x64, 0x29, 0xca, 0x49, 0x6b, 0x70, 0xf8);
37 DEFINE_GUID(RedEyeCorrectionEffectGuid, 0x74d29d05, 0x69a4, 0x4266, 0x95, 0x49, 0x3c, 0xc5, 0x28, 0x36, 0xb6, 0x32);
38 DEFINE_GUID(ColorCurveEffectGuid, 0xdd6a0022, 0x58e4, 0x4a67, 0x9d, 0x9b, 0xd4, 0x8e, 0xb8, 0x81, 0xa5, 0x3d);
39
40 static GpStatus (WINAPI *pGdipBitmapGetHistogramSize)(HistogramFormat,UINT*);
41 static GpStatus (WINAPI *pGdipBitmapGetHistogram)(GpBitmap*,HistogramFormat,UINT,UINT*,UINT*,UINT*,UINT*);
42 static GpStatus (WINAPI *pGdipImageSetAbort)(GpImage*,GdiplusAbort*);
43
44 #define expect(expected, got) ok((got) == (expected), "Expected %d, got %d\n", (UINT)(expected), (UINT)(got))
45 #define expectf(expected, got) ok(fabs((expected) - (got)) < 0.0001, "Expected %f, got %f\n", (expected), (got))
46
47 static BOOL color_match(ARGB c1, ARGB c2, BYTE max_diff)
48 {
49 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
50 c1 >>= 8; c2 >>= 8;
51 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
52 c1 >>= 8; c2 >>= 8;
53 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
54 c1 >>= 8; c2 >>= 8;
55 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
56 return TRUE;
57 }
58
59 static void expect_guid(REFGUID expected, REFGUID got, int line, BOOL todo)
60 {
61 WCHAR bufferW[39];
62 char buffer[39];
63 char buffer2[39];
64
65 StringFromGUID2(got, bufferW, sizeof(bufferW)/sizeof(bufferW[0]));
66 WideCharToMultiByte(CP_ACP, 0, bufferW, sizeof(bufferW)/sizeof(bufferW[0]), buffer, sizeof(buffer), NULL, NULL);
67 StringFromGUID2(expected, bufferW, sizeof(bufferW)/sizeof(bufferW[0]));
68 WideCharToMultiByte(CP_ACP, 0, bufferW, sizeof(bufferW)/sizeof(bufferW[0]), buffer2, sizeof(buffer2), NULL, NULL);
69 todo_wine_if (todo)
70 ok_(__FILE__, line)(IsEqualGUID(expected, got), "Expected %s, got %s\n", buffer2, buffer);
71 }
72
73 static void expect_rawformat(REFGUID expected, GpImage *img, int line, BOOL todo)
74 {
75 GUID raw;
76 GpStatus stat;
77
78 stat = GdipGetImageRawFormat(img, &raw);
79 ok_(__FILE__, line)(stat == Ok, "GdipGetImageRawFormat failed with %d\n", stat);
80 if(stat != Ok) return;
81 expect_guid(expected, &raw, line, todo);
82 }
83
84 static void test_bufferrawformat(void* buff, int size, REFGUID expected, int line, BOOL todo)
85 {
86 LPSTREAM stream;
87 HGLOBAL hglob;
88 LPBYTE data;
89 HRESULT hres;
90 GpStatus stat;
91 GpImage *img;
92
93 hglob = GlobalAlloc (0, size);
94 data = GlobalLock (hglob);
95 memcpy(data, buff, size);
96 GlobalUnlock(hglob); data = NULL;
97
98 hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
99 ok_(__FILE__, line)(hres == S_OK, "Failed to create a stream\n");
100 if(hres != S_OK) return;
101
102 stat = GdipLoadImageFromStream(stream, &img);
103 ok_(__FILE__, line)(stat == Ok, "Failed to create a Bitmap\n");
104 if(stat != Ok){
105 IStream_Release(stream);
106 return;
107 }
108
109 expect_rawformat(expected, img, line, todo);
110
111 GdipDisposeImage(img);
112 IStream_Release(stream);
113 }
114
115 static void test_Scan0(void)
116 {
117 GpBitmap *bm;
118 GpStatus stat;
119 BYTE buff[360];
120
121 bm = NULL;
122 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, NULL, &bm);
123 expect(Ok, stat);
124 ok(NULL != bm, "Expected bitmap to be initialized\n");
125 if (stat == Ok)
126 GdipDisposeImage((GpImage*)bm);
127
128 bm = (GpBitmap*)0xdeadbeef;
129 stat = GdipCreateBitmapFromScan0(10, -10, 10, PixelFormat24bppRGB, NULL, &bm);
130 expect(InvalidParameter, stat);
131 ok( !bm, "expected null bitmap\n" );
132
133 bm = (GpBitmap*)0xdeadbeef;
134 stat = GdipCreateBitmapFromScan0(-10, 10, 10, PixelFormat24bppRGB, NULL, &bm);
135 expect(InvalidParameter, stat);
136 ok( !bm, "expected null bitmap\n" );
137
138 bm = (GpBitmap*)0xdeadbeef;
139 stat = GdipCreateBitmapFromScan0(10, 0, 10, PixelFormat24bppRGB, NULL, &bm);
140 expect(InvalidParameter, stat);
141 ok( !bm, "expected null bitmap\n" );
142
143 bm = NULL;
144 stat = GdipCreateBitmapFromScan0(10, 10, 12, PixelFormat24bppRGB, buff, &bm);
145 expect(Ok, stat);
146 ok(NULL != bm, "Expected bitmap to be initialized\n");
147 if (stat == Ok)
148 GdipDisposeImage((GpImage*)bm);
149
150 bm = (GpBitmap*) 0xdeadbeef;
151 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, buff, &bm);
152 expect(InvalidParameter, stat);
153 ok( !bm, "expected null bitmap\n" );
154
155 bm = (GpBitmap*)0xdeadbeef;
156 stat = GdipCreateBitmapFromScan0(10, 10, 0, PixelFormat24bppRGB, buff, &bm);
157 expect(InvalidParameter, stat);
158 ok( bm == (GpBitmap*)0xdeadbeef, "expected deadbeef bitmap\n" );
159
160 bm = NULL;
161 stat = GdipCreateBitmapFromScan0(10, 10, -8, PixelFormat24bppRGB, buff, &bm);
162 expect(Ok, stat);
163 ok(NULL != bm, "Expected bitmap to be initialized\n");
164 if (stat == Ok)
165 GdipDisposeImage((GpImage*)bm);
166
167 bm = (GpBitmap*)0xdeadbeef;
168 stat = GdipCreateBitmapFromScan0(10, 10, -10, PixelFormat24bppRGB, buff, &bm);
169 expect(InvalidParameter, stat);
170 ok( !bm, "expected null bitmap\n" );
171 }
172
173 static void test_FromGdiDib(void)
174 {
175 GpBitmap *bm;
176 GpStatus stat;
177 BYTE buff[400];
178 BYTE rbmi[sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)];
179 BITMAPINFO *bmi = (BITMAPINFO*)rbmi;
180 PixelFormat format;
181
182 bm = NULL;
183
184 memset(rbmi, 0, sizeof(rbmi));
185
186 bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
187 bmi->bmiHeader.biWidth = 10;
188 bmi->bmiHeader.biHeight = 10;
189 bmi->bmiHeader.biPlanes = 1;
190 bmi->bmiHeader.biBitCount = 32;
191 bmi->bmiHeader.biCompression = BI_RGB;
192
193 stat = GdipCreateBitmapFromGdiDib(NULL, buff, &bm);
194 expect(InvalidParameter, stat);
195
196 stat = GdipCreateBitmapFromGdiDib(bmi, NULL, &bm);
197 expect(InvalidParameter, stat);
198
199 stat = GdipCreateBitmapFromGdiDib(bmi, buff, NULL);
200 expect(InvalidParameter, stat);
201
202 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
203 expect(Ok, stat);
204 ok(NULL != bm, "Expected bitmap to be initialized\n");
205 if (stat == Ok)
206 {
207 stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
208 expect(Ok, stat);
209 expect(PixelFormat32bppRGB, format);
210
211 GdipDisposeImage((GpImage*)bm);
212 }
213
214 bmi->bmiHeader.biBitCount = 24;
215 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
216 expect(Ok, stat);
217 ok(NULL != bm, "Expected bitmap to be initialized\n");
218 if (stat == Ok)
219 {
220 stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
221 expect(Ok, stat);
222 expect(PixelFormat24bppRGB, format);
223
224 GdipDisposeImage((GpImage*)bm);
225 }
226
227 bmi->bmiHeader.biBitCount = 16;
228 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
229 expect(Ok, stat);
230 ok(NULL != bm, "Expected bitmap to be initialized\n");
231 if (stat == Ok)
232 {
233 stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
234 expect(Ok, stat);
235 expect(PixelFormat16bppRGB555, format);
236
237 GdipDisposeImage((GpImage*)bm);
238 }
239
240 bmi->bmiHeader.biBitCount = 8;
241 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
242 expect(Ok, stat);
243 ok(NULL != bm, "Expected bitmap to be initialized\n");
244 if (stat == Ok)
245 {
246 stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
247 expect(Ok, stat);
248 expect(PixelFormat8bppIndexed, format);
249
250 GdipDisposeImage((GpImage*)bm);
251 }
252
253 bmi->bmiHeader.biBitCount = 4;
254 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
255 expect(Ok, stat);
256 ok(NULL != bm, "Expected bitmap to be initialized\n");
257 if (stat == Ok)
258 {
259 stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
260 expect(Ok, stat);
261 expect(PixelFormat4bppIndexed, format);
262
263 GdipDisposeImage((GpImage*)bm);
264 }
265
266 bmi->bmiHeader.biBitCount = 1;
267 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
268 expect(Ok, stat);
269 ok(NULL != bm, "Expected bitmap to be initialized\n");
270 if (stat == Ok)
271 {
272 stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
273 expect(Ok, stat);
274 expect(PixelFormat1bppIndexed, format);
275
276 GdipDisposeImage((GpImage*)bm);
277 }
278
279 bmi->bmiHeader.biBitCount = 0;
280 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
281 expect(InvalidParameter, stat);
282 }
283
284 static void test_GetImageDimension(void)
285 {
286 GpBitmap *bm;
287 GpStatus stat;
288 const REAL WIDTH = 10.0, HEIGHT = 20.0;
289 REAL w,h;
290
291 bm = (GpBitmap*)0xdeadbeef;
292 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB,NULL, &bm);
293 expect(Ok,stat);
294 ok((GpBitmap*)0xdeadbeef != bm, "Expected bitmap to not be 0xdeadbeef\n");
295 ok(NULL != bm, "Expected bitmap to not be NULL\n");
296
297 stat = GdipGetImageDimension(NULL,&w,&h);
298 expect(InvalidParameter, stat);
299
300 stat = GdipGetImageDimension((GpImage*)bm,NULL,&h);
301 expect(InvalidParameter, stat);
302
303 stat = GdipGetImageDimension((GpImage*)bm,&w,NULL);
304 expect(InvalidParameter, stat);
305
306 w = -1;
307 h = -1;
308 stat = GdipGetImageDimension((GpImage*)bm,&w,&h);
309 expect(Ok, stat);
310 expectf(WIDTH, w);
311 expectf(HEIGHT, h);
312 GdipDisposeImage((GpImage*)bm);
313 }
314
315 static void test_GdipImageGetFrameDimensionsCount(void)
316 {
317 GpBitmap *bm;
318 GpStatus stat;
319 const REAL WIDTH = 10.0, HEIGHT = 20.0;
320 UINT w;
321 GUID dimension = {0};
322 UINT count;
323 ARGB color;
324
325 bm = (GpBitmap*)0xdeadbeef;
326 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB,NULL, &bm);
327 expect(Ok,stat);
328 ok((GpBitmap*)0xdeadbeef != bm, "Expected bitmap to not be 0xdeadbeef\n");
329 ok(NULL != bm, "Expected bitmap to not be NULL\n");
330
331 stat = GdipImageGetFrameDimensionsCount(NULL,&w);
332 expect(InvalidParameter, stat);
333
334 stat = GdipImageGetFrameDimensionsCount((GpImage*)bm,NULL);
335 expect(InvalidParameter, stat);
336
337 w = -1;
338 stat = GdipImageGetFrameDimensionsCount((GpImage*)bm,&w);
339 expect(Ok, stat);
340 expect(1, w);
341
342 stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 1);
343 expect(Ok, stat);
344 expect_guid(&FrameDimensionPage, &dimension, __LINE__, FALSE);
345
346 stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 2);
347 expect(InvalidParameter, stat);
348
349 stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 0);
350 expect(InvalidParameter, stat);
351
352 stat = GdipImageGetFrameCount(NULL, &dimension, &count);
353 expect(InvalidParameter, stat);
354
355 /* WinXP crashes on this test */
356 if(0)
357 {
358 stat = GdipImageGetFrameCount((GpImage*)bm, &dimension, NULL);
359 expect(InvalidParameter, stat);
360 }
361
362 stat = GdipImageGetFrameCount((GpImage*)bm, NULL, &count);
363 expect(Ok, stat);
364
365 count = 12345;
366 stat = GdipImageGetFrameCount((GpImage*)bm, &dimension, &count);
367 expect(Ok, stat);
368 expect(1, count);
369
370 GdipBitmapSetPixel(bm, 0, 0, 0xffffffff);
371
372 stat = GdipImageSelectActiveFrame((GpImage*)bm, &dimension, 0);
373 expect(Ok, stat);
374
375 /* SelectActiveFrame has no effect on image data of memory bitmaps */
376 color = 0xdeadbeef;
377 stat = GdipBitmapGetPixel(bm, 0, 0, &color);
378 expect(Ok, stat);
379 expect(0xffffffff, color);
380
381 GdipDisposeImage((GpImage*)bm);
382 }
383
384 static void test_LoadingImages(void)
385 {
386 GpStatus stat;
387 GpBitmap *bm;
388 GpImage *img;
389 static const WCHAR nonexistentW[] = {'n','o','n','e','x','i','s','t','e','n','t',0};
390
391 stat = GdipCreateBitmapFromFile(0, 0);
392 expect(InvalidParameter, stat);
393
394 bm = (GpBitmap *)0xdeadbeef;
395 stat = GdipCreateBitmapFromFile(0, &bm);
396 expect(InvalidParameter, stat);
397 ok(bm == (GpBitmap *)0xdeadbeef, "returned %p\n", bm);
398
399 bm = (GpBitmap *)0xdeadbeef;
400 stat = GdipCreateBitmapFromFile(nonexistentW, &bm);
401 todo_wine expect(InvalidParameter, stat);
402 ok(!bm, "returned %p\n", bm);
403
404 stat = GdipLoadImageFromFile(0, 0);
405 expect(InvalidParameter, stat);
406
407 img = (GpImage *)0xdeadbeef;
408 stat = GdipLoadImageFromFile(0, &img);
409 expect(InvalidParameter, stat);
410 ok(img == (GpImage *)0xdeadbeef, "returned %p\n", img);
411
412 img = (GpImage *)0xdeadbeef;
413 stat = GdipLoadImageFromFile(nonexistentW, &img);
414 todo_wine expect(OutOfMemory, stat);
415 ok(!img, "returned %p\n", img);
416
417 stat = GdipLoadImageFromFileICM(0, 0);
418 expect(InvalidParameter, stat);
419
420 img = (GpImage *)0xdeadbeef;
421 stat = GdipLoadImageFromFileICM(0, &img);
422 expect(InvalidParameter, stat);
423 ok(img == (GpImage *)0xdeadbeef, "returned %p\n", img);
424
425 img = (GpImage *)0xdeadbeef;
426 stat = GdipLoadImageFromFileICM(nonexistentW, &img);
427 todo_wine expect(OutOfMemory, stat);
428 ok(!img, "returned %p\n", img);
429 }
430
431 static void test_SavingImages(void)
432 {
433 GpStatus stat;
434 GpBitmap *bm;
435 UINT n;
436 UINT s;
437 const REAL WIDTH = 10.0, HEIGHT = 20.0;
438 REAL w, h;
439 ImageCodecInfo *codecs;
440 static const CHAR filenameA[] = "a.bmp";
441 static const WCHAR filename[] = { 'a','.','b','m','p',0 };
442
443 codecs = NULL;
444
445 stat = GdipSaveImageToFile(0, 0, 0, 0);
446 expect(InvalidParameter, stat);
447
448 bm = NULL;
449 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
450 expect(Ok, stat);
451 if (!bm)
452 return;
453
454 /* invalid params */
455 stat = GdipSaveImageToFile((GpImage*)bm, 0, 0, 0);
456 expect(InvalidParameter, stat);
457
458 stat = GdipSaveImageToFile((GpImage*)bm, filename, 0, 0);
459 expect(InvalidParameter, stat);
460
461 /* encoder tests should succeed -- already tested */
462 stat = GdipGetImageEncodersSize(&n, &s);
463 if (stat != Ok || n == 0) goto cleanup;
464
465 codecs = GdipAlloc(s);
466 if (!codecs) goto cleanup;
467
468 stat = GdipGetImageEncoders(n, s, codecs);
469 if (stat != Ok) goto cleanup;
470
471 stat = GdipSaveImageToFile((GpImage*)bm, filename, &codecs[0].Clsid, 0);
472 expect(Ok, stat);
473
474 GdipDisposeImage((GpImage*)bm);
475 bm = 0;
476
477 /* re-load and check image stats */
478 stat = GdipLoadImageFromFile(filename, (GpImage**)&bm);
479 expect(Ok, stat);
480 if (stat != Ok) goto cleanup;
481
482 stat = GdipGetImageDimension((GpImage*)bm, &w, &h);
483 if (stat != Ok) goto cleanup;
484
485 expectf(WIDTH, w);
486 expectf(HEIGHT, h);
487
488 cleanup:
489 GdipFree(codecs);
490 if (bm)
491 GdipDisposeImage((GpImage*)bm);
492 ok(DeleteFileA(filenameA), "Delete failed.\n");
493 }
494
495 static void test_encoders(void)
496 {
497 GpStatus stat;
498 UINT n;
499 UINT s;
500 ImageCodecInfo *codecs;
501 int i;
502 int bmp_found;
503
504 static const CHAR bmp_format[] = "BMP";
505
506 stat = GdipGetImageEncodersSize(&n, &s);
507 expect(stat, Ok);
508
509 codecs = GdipAlloc(s);
510 if (!codecs)
511 return;
512
513 stat = GdipGetImageEncoders(n, s, NULL);
514 expect(GenericError, stat);
515
516 stat = GdipGetImageEncoders(0, s, codecs);
517 expect(GenericError, stat);
518
519 stat = GdipGetImageEncoders(n, s-1, codecs);
520 expect(GenericError, stat);
521
522 stat = GdipGetImageEncoders(n, s+1, codecs);
523 expect(GenericError, stat);
524
525 stat = GdipGetImageEncoders(n, s, codecs);
526 expect(stat, Ok);
527
528 bmp_found = FALSE;
529 for (i = 0; i < n; i++)
530 {
531 CHAR desc[32];
532
533 WideCharToMultiByte(CP_ACP, 0, codecs[i].FormatDescription, -1,
534 desc, 32, 0, 0);
535
536 if (CompareStringA(LOCALE_SYSTEM_DEFAULT, 0,
537 desc, -1,
538 bmp_format, -1) == CSTR_EQUAL) {
539 bmp_found = TRUE;
540 break;
541 }
542 }
543 if (!bmp_found)
544 ok(FALSE, "No BMP codec found.\n");
545
546 GdipFree(codecs);
547 }
548
549 static void test_LockBits(void)
550 {
551 GpStatus stat;
552 GpBitmap *bm;
553 GpRect rect;
554 BitmapData bd;
555 const INT WIDTH = 10, HEIGHT = 20;
556 ARGB color;
557 int y;
558
559 bm = NULL;
560 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
561 expect(Ok, stat);
562
563 rect.X = 2;
564 rect.Y = 3;
565 rect.Width = 4;
566 rect.Height = 5;
567
568 stat = GdipBitmapSetPixel(bm, 2, 3, 0xffc30000);
569 expect(Ok, stat);
570
571 stat = GdipBitmapSetPixel(bm, 2, 8, 0xff480000);
572 expect(Ok, stat);
573
574 /* read-only */
575 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
576 expect(Ok, stat);
577
578 if (stat == Ok) {
579 expect(0xc3, ((BYTE*)bd.Scan0)[2]);
580 expect(0x48, ((BYTE*)bd.Scan0)[2 + bd.Stride * 5]);
581
582 ((char*)bd.Scan0)[2] = 0xff;
583
584 stat = GdipBitmapUnlockBits(bm, &bd);
585 expect(Ok, stat);
586 }
587
588 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
589 expect(Ok, stat);
590 expect(0xffff0000, color);
591
592 stat = GdipBitmapSetPixel(bm, 2, 3, 0xffc30000);
593 expect(Ok, stat);
594
595 /* read-only, with NULL rect -> whole bitmap lock */
596 stat = GdipBitmapLockBits(bm, NULL, ImageLockModeRead, PixelFormat24bppRGB, &bd);
597 expect(Ok, stat);
598 expect(bd.Width, WIDTH);
599 expect(bd.Height, HEIGHT);
600
601 if (stat == Ok) {
602 ((char*)bd.Scan0)[2 + 2*3 + 3*bd.Stride] = 0xff;
603
604 stat = GdipBitmapUnlockBits(bm, &bd);
605 expect(Ok, stat);
606 }
607
608 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
609 expect(Ok, stat);
610 expect(0xffff0000, color);
611
612 /* read-only, consecutive */
613 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
614 expect(Ok, stat);
615
616 if (stat == Ok) {
617 stat = GdipBitmapUnlockBits(bm, &bd);
618 expect(Ok, stat);
619 }
620
621 stat = GdipDisposeImage((GpImage*)bm);
622 expect(Ok, stat);
623 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
624 expect(Ok, stat);
625
626 /* read x2 */
627 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
628 expect(Ok, stat);
629 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
630 expect(WrongState, stat);
631
632 stat = GdipBitmapUnlockBits(bm, &bd);
633 expect(Ok, stat);
634
635 stat = GdipDisposeImage((GpImage*)bm);
636 expect(Ok, stat);
637 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
638 expect(Ok, stat);
639
640 stat = GdipBitmapSetPixel(bm, 2, 3, 0xffff0000);
641 expect(Ok, stat);
642
643 stat = GdipBitmapSetPixel(bm, 2, 8, 0xffc30000);
644 expect(Ok, stat);
645
646 /* write, no conversion */
647 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
648 expect(Ok, stat);
649
650 if (stat == Ok) {
651 /* all bits are readable, inside the rect or not */
652 expect(0xff, ((BYTE*)bd.Scan0)[2]);
653 expect(0xc3, ((BYTE*)bd.Scan0)[2 + bd.Stride * 5]);
654
655 stat = GdipBitmapUnlockBits(bm, &bd);
656 expect(Ok, stat);
657 }
658
659 /* read, conversion */
660 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat32bppARGB, &bd);
661 expect(Ok, stat);
662
663 if (stat == Ok) {
664 expect(0xff, ((BYTE*)bd.Scan0)[2]);
665 if (0)
666 /* Areas outside the rectangle appear to be uninitialized */
667 ok(0xc3 != ((BYTE*)bd.Scan0)[2 + bd.Stride * 5], "original image bits are readable\n");
668
669 ((BYTE*)bd.Scan0)[2] = 0xc3;
670
671 stat = GdipBitmapUnlockBits(bm, &bd);
672 expect(Ok, stat);
673 }
674
675 /* writes do not work in read mode if there was a conversion */
676 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
677 expect(Ok, stat);
678 expect(0xffff0000, color);
679
680 /* read/write, conversion */
681 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead|ImageLockModeWrite, PixelFormat32bppARGB, &bd);
682 expect(Ok, stat);
683
684 if (stat == Ok) {
685 expect(0xff, ((BYTE*)bd.Scan0)[2]);
686 ((BYTE*)bd.Scan0)[1] = 0x88;
687 if (0)
688 /* Areas outside the rectangle appear to be uninitialized */
689 ok(0xc3 != ((BYTE*)bd.Scan0)[2 + bd.Stride * 5], "original image bits are readable\n");
690
691 stat = GdipBitmapUnlockBits(bm, &bd);
692 expect(Ok, stat);
693 }
694
695 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
696 expect(Ok, stat);
697 expect(0xffff8800, color);
698
699 /* write, conversion */
700 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat32bppARGB, &bd);
701 expect(Ok, stat);
702
703 if (stat == Ok) {
704 if (0)
705 {
706 /* This is completely uninitialized. */
707 ok(0xff != ((BYTE*)bd.Scan0)[2], "original image bits are readable\n");
708 ok(0xc3 != ((BYTE*)bd.Scan0)[2 + bd.Stride * 5], "original image bits are readable\n");
709 }
710
711 /* Initialize the buffer so the unlock doesn't access undefined memory */
712 for (y=0; y<5; y++)
713 memset(((BYTE*)bd.Scan0) + bd.Stride * y, 0, 12);
714
715 ((BYTE*)bd.Scan0)[0] = 0x12;
716 ((BYTE*)bd.Scan0)[1] = 0x34;
717 ((BYTE*)bd.Scan0)[2] = 0x56;
718
719 stat = GdipBitmapUnlockBits(bm, &bd);
720 expect(Ok, stat);
721 }
722
723 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
724 expect(Ok, stat);
725 expect(0xff563412, color);
726
727 stat = GdipBitmapGetPixel(bm, 2, 8, &color);
728 expect(Ok, stat);
729 expect(0xffc30000, color);
730
731 stat = GdipDisposeImage((GpImage*)bm);
732 expect(Ok, stat);
733 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
734 expect(Ok, stat);
735
736 /* write, no modification */
737 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
738 expect(Ok, stat);
739
740 if (stat == Ok) {
741 stat = GdipBitmapUnlockBits(bm, &bd);
742 expect(Ok, stat);
743 }
744
745 /* write, consecutive */
746 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
747 expect(Ok, stat);
748
749 if (stat == Ok) {
750 stat = GdipBitmapUnlockBits(bm, &bd);
751 expect(Ok, stat);
752 }
753
754 stat = GdipDisposeImage((GpImage*)bm);
755 expect(Ok, stat);
756 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
757 expect(Ok, stat);
758
759 /* write, modify */
760 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
761 expect(Ok, stat);
762
763 if (stat == Ok) {
764 if (bd.Scan0)
765 ((char*)bd.Scan0)[2] = 0xff;
766
767 stat = GdipBitmapUnlockBits(bm, &bd);
768 expect(Ok, stat);
769 }
770
771 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
772 expect(Ok, stat);
773 expect(0xffff0000, color);
774
775 stat = GdipDisposeImage((GpImage*)bm);
776 expect(Ok, stat);
777
778 /* dispose locked */
779 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
780 expect(Ok, stat);
781 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
782 expect(Ok, stat);
783 stat = GdipDisposeImage((GpImage*)bm);
784 expect(Ok, stat);
785 }
786
787 static void test_LockBits_UserBuf(void)
788 {
789 GpStatus stat;
790 GpBitmap *bm;
791 GpRect rect;
792 BitmapData bd;
793 const INT WIDTH = 10, HEIGHT = 20;
794 DWORD bits[200];
795 ARGB color;
796
797 bm = NULL;
798 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat32bppARGB, NULL, &bm);
799 expect(Ok, stat);
800
801 memset(bits, 0xaa, sizeof(bits));
802
803 rect.X = 2;
804 rect.Y = 3;
805 rect.Width = 4;
806 rect.Height = 5;
807
808 bd.Width = 4;
809 bd.Height = 6;
810 bd.Stride = WIDTH * 4;
811 bd.PixelFormat = PixelFormat32bppARGB;
812 bd.Scan0 = &bits[2+3*WIDTH];
813 bd.Reserved = 0xaaaaaaaa;
814
815 /* read-only */
816 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead|ImageLockModeUserInputBuf, PixelFormat32bppARGB, &bd);
817 expect(Ok, stat);
818
819 expect(0xaaaaaaaa, bits[0]);
820 expect(0, bits[2+3*WIDTH]);
821
822 bits[2+3*WIDTH] = 0xdeadbeef;
823
824 if (stat == Ok) {
825 stat = GdipBitmapUnlockBits(bm, &bd);
826 expect(Ok, stat);
827 }
828
829 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
830 expect(Ok, stat);
831 expect(0, color);
832
833 /* write-only */
834 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite|ImageLockModeUserInputBuf, PixelFormat32bppARGB, &bd);
835 expect(Ok, stat);
836
837 expect(0xdeadbeef, bits[2+3*WIDTH]);
838 bits[2+3*WIDTH] = 0x12345678;
839
840 if (stat == Ok) {
841 stat = GdipBitmapUnlockBits(bm, &bd);
842 expect(Ok, stat);
843 }
844
845 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
846 expect(Ok, stat);
847 expect(0x12345678, color);
848
849 bits[2+3*WIDTH] = 0;
850
851 /* read/write */
852 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead|ImageLockModeWrite|ImageLockModeUserInputBuf, PixelFormat32bppARGB, &bd);
853 expect(Ok, stat);
854
855 expect(0x12345678, bits[2+3*WIDTH]);
856 bits[2+3*WIDTH] = 0xdeadbeef;
857
858 if (stat == Ok) {
859 stat = GdipBitmapUnlockBits(bm, &bd);
860 expect(Ok, stat);
861 }
862
863 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
864 expect(Ok, stat);
865 expect(0xdeadbeef, color);
866
867 stat = GdipDisposeImage((GpImage*)bm);
868 expect(Ok, stat);
869 }
870
871 struct BITMAPINFOWITHBITFIELDS
872 {
873 BITMAPINFOHEADER bmiHeader;
874 DWORD masks[3];
875 };
876
877 union BITMAPINFOUNION
878 {
879 BITMAPINFO bi;
880 struct BITMAPINFOWITHBITFIELDS bf;
881 };
882
883 static void test_GdipCreateBitmapFromHBITMAP(void)
884 {
885 GpBitmap* gpbm = NULL;
886 HBITMAP hbm = NULL;
887 HPALETTE hpal = NULL;
888 GpStatus stat;
889 BYTE buff[1000];
890 LOGPALETTE* LogPal = NULL;
891 REAL width, height;
892 const REAL WIDTH1 = 5;
893 const REAL HEIGHT1 = 15;
894 const REAL WIDTH2 = 10;
895 const REAL HEIGHT2 = 20;
896 HDC hdc;
897 union BITMAPINFOUNION bmi;
898 BYTE *bits;
899 PixelFormat format;
900
901 stat = GdipCreateBitmapFromHBITMAP(NULL, NULL, NULL);
902 expect(InvalidParameter, stat);
903
904 hbm = CreateBitmap(WIDTH1, HEIGHT1, 1, 1, NULL);
905 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, NULL);
906 expect(InvalidParameter, stat);
907
908 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
909 expect(Ok, stat);
910 expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
911 expectf(WIDTH1, width);
912 expectf(HEIGHT1, height);
913 if (stat == Ok)
914 GdipDisposeImage((GpImage*)gpbm);
915 DeleteObject(hbm);
916
917 memset(buff, 0, sizeof(buff));
918 hbm = CreateBitmap(WIDTH2, HEIGHT2, 1, 1, &buff);
919 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
920 expect(Ok, stat);
921 /* raw format */
922 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)gpbm, __LINE__, FALSE);
923
924 expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
925 expectf(WIDTH2, width);
926 expectf(HEIGHT2, height);
927 if (stat == Ok)
928 GdipDisposeImage((GpImage*)gpbm);
929 DeleteObject(hbm);
930
931 hdc = CreateCompatibleDC(0);
932 ok(hdc != NULL, "CreateCompatibleDC failed\n");
933 bmi.bi.bmiHeader.biSize = sizeof(bmi.bi.bmiHeader);
934 bmi.bi.bmiHeader.biHeight = HEIGHT1;
935 bmi.bi.bmiHeader.biWidth = WIDTH1;
936 bmi.bi.bmiHeader.biBitCount = 24;
937 bmi.bi.bmiHeader.biPlanes = 1;
938 bmi.bi.bmiHeader.biCompression = BI_RGB;
939 bmi.bi.bmiHeader.biClrUsed = 0;
940
941 hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
942 ok(hbm != NULL, "CreateDIBSection failed\n");
943
944 bits[0] = 0;
945
946 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
947 expect(Ok, stat);
948 expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
949 expectf(WIDTH1, width);
950 expectf(HEIGHT1, height);
951 if (stat == Ok)
952 {
953 /* test whether writing to the bitmap affects the original */
954 stat = GdipBitmapSetPixel(gpbm, 0, 0, 0xffffffff);
955 expect(Ok, stat);
956
957 expect(0, bits[0]);
958
959 GdipDisposeImage((GpImage*)gpbm);
960 }
961
962 LogPal = GdipAlloc(sizeof(LOGPALETTE));
963 ok(LogPal != NULL, "unable to allocate LOGPALETTE\n");
964 LogPal->palVersion = 0x300;
965 LogPal->palNumEntries = 1;
966 hpal = CreatePalette(LogPal);
967 ok(hpal != NULL, "CreatePalette failed\n");
968 GdipFree(LogPal);
969
970 stat = GdipCreateBitmapFromHBITMAP(hbm, hpal, &gpbm);
971 expect(Ok, stat);
972
973 if (stat == Ok)
974 GdipDisposeImage((GpImage*)gpbm);
975
976 DeleteObject(hpal);
977 DeleteObject(hbm);
978
979 /* 16-bit 555 dib, rgb */
980 bmi.bi.bmiHeader.biBitCount = 16;
981 bmi.bi.bmiHeader.biCompression = BI_RGB;
982
983 hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
984 ok(hbm != NULL, "CreateDIBSection failed\n");
985
986 bits[0] = 0;
987
988 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
989 expect(Ok, stat);
990
991 if (stat == Ok)
992 {
993 stat = GdipGetImageDimension((GpImage*) gpbm, &width, &height);
994 expect(Ok, stat);
995 expectf(WIDTH1, width);
996 expectf(HEIGHT1, height);
997
998 stat = GdipGetImagePixelFormat((GpImage*) gpbm, &format);
999 expect(Ok, stat);
1000 expect(PixelFormat16bppRGB555, format);
1001
1002 GdipDisposeImage((GpImage*)gpbm);
1003 }
1004 DeleteObject(hbm);
1005
1006 /* 16-bit 555 dib, with bitfields */
1007 bmi.bi.bmiHeader.biSize = sizeof(bmi);
1008 bmi.bi.bmiHeader.biCompression = BI_BITFIELDS;
1009 bmi.bf.masks[0] = 0x7c00;
1010 bmi.bf.masks[1] = 0x3e0;
1011 bmi.bf.masks[2] = 0x1f;
1012
1013 hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1014 ok(hbm != NULL, "CreateDIBSection failed\n");
1015
1016 bits[0] = 0;
1017
1018 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
1019 expect(Ok, stat);
1020
1021 if (stat == Ok)
1022 {
1023 stat = GdipGetImageDimension((GpImage*) gpbm, &width, &height);
1024 expect(Ok, stat);
1025 expectf(WIDTH1, width);
1026 expectf(HEIGHT1, height);
1027
1028 stat = GdipGetImagePixelFormat((GpImage*) gpbm, &format);
1029 expect(Ok, stat);
1030 expect(PixelFormat16bppRGB555, format);
1031
1032 GdipDisposeImage((GpImage*)gpbm);
1033 }
1034 DeleteObject(hbm);
1035
1036 /* 16-bit 565 dib, with bitfields */
1037 bmi.bf.masks[0] = 0xf800;
1038 bmi.bf.masks[1] = 0x7e0;
1039 bmi.bf.masks[2] = 0x1f;
1040
1041 hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1042 ok(hbm != NULL, "CreateDIBSection failed\n");
1043
1044 bits[0] = 0;
1045
1046 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
1047 expect(Ok, stat);
1048
1049 if (stat == Ok)
1050 {
1051 stat = GdipGetImageDimension((GpImage*) gpbm, &width, &height);
1052 expect(Ok, stat);
1053 expectf(WIDTH1, width);
1054 expectf(HEIGHT1, height);
1055
1056 stat = GdipGetImagePixelFormat((GpImage*) gpbm, &format);
1057 expect(Ok, stat);
1058 expect(PixelFormat16bppRGB565, format);
1059
1060 GdipDisposeImage((GpImage*)gpbm);
1061 }
1062 DeleteObject(hbm);
1063
1064 DeleteDC(hdc);
1065 }
1066
1067 static void test_GdipGetImageFlags(void)
1068 {
1069 GpImage *img;
1070 GpStatus stat;
1071 UINT flags;
1072
1073 img = (GpImage*)0xdeadbeef;
1074
1075 stat = GdipGetImageFlags(NULL, NULL);
1076 expect(InvalidParameter, stat);
1077
1078 stat = GdipGetImageFlags(NULL, &flags);
1079 expect(InvalidParameter, stat);
1080
1081 stat = GdipGetImageFlags(img, NULL);
1082 expect(InvalidParameter, stat);
1083
1084 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat1bppIndexed, NULL, (GpBitmap**)&img);
1085 expect(Ok, stat);
1086 stat = GdipGetImageFlags(img, &flags);
1087 expect(Ok, stat);
1088 expect(ImageFlagsHasAlpha, flags);
1089 GdipDisposeImage(img);
1090
1091 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat4bppIndexed, NULL, (GpBitmap**)&img);
1092 expect(Ok, stat);
1093 stat = GdipGetImageFlags(img, &flags);
1094 expect(Ok, stat);
1095 expect(ImageFlagsHasAlpha, flags);
1096 GdipDisposeImage(img);
1097
1098 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat8bppIndexed, NULL, (GpBitmap**)&img);
1099 expect(Ok, stat);
1100 stat = GdipGetImageFlags(img, &flags);
1101 expect(Ok, stat);
1102 expect(ImageFlagsHasAlpha, flags);
1103 GdipDisposeImage(img);
1104
1105 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppGrayScale, NULL, (GpBitmap**)&img);
1106 expect(Ok, stat);
1107 stat = GdipGetImageFlags(img, &flags);
1108 expect(Ok, stat);
1109 expect(ImageFlagsNone, flags);
1110 GdipDisposeImage(img);
1111
1112 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB555, NULL, (GpBitmap**)&img);
1113 expect(Ok, stat);
1114 stat = GdipGetImageFlags(img, &flags);
1115 expect(Ok, stat);
1116 expect(ImageFlagsNone, flags);
1117 GdipDisposeImage(img);
1118
1119 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB565, NULL, (GpBitmap**)&img);
1120 expect(Ok, stat);
1121 stat = GdipGetImageFlags(img, &flags);
1122 expect(Ok, stat);
1123 expect(ImageFlagsNone, flags);
1124 GdipDisposeImage(img);
1125
1126 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppARGB1555, NULL, (GpBitmap**)&img);
1127 expect(Ok, stat);
1128 stat = GdipGetImageFlags(img, &flags);
1129 expect(Ok, stat);
1130 expect(ImageFlagsHasAlpha, flags);
1131 GdipDisposeImage(img);
1132
1133 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, NULL, (GpBitmap**)&img);
1134 expect(Ok, stat);
1135 stat = GdipGetImageFlags(img, &flags);
1136 expect(Ok, stat);
1137 expect(ImageFlagsNone, flags);
1138 GdipDisposeImage(img);
1139
1140 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppRGB, NULL, (GpBitmap**)&img);
1141 expect(Ok, stat);
1142 stat = GdipGetImageFlags(img, &flags);
1143 expect(Ok, stat);
1144 expect(ImageFlagsNone, flags);
1145 GdipDisposeImage(img);
1146
1147 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppARGB, NULL, (GpBitmap**)&img);
1148 expect(Ok, stat);
1149 stat = GdipGetImageFlags(img, &flags);
1150 expect(Ok, stat);
1151 expect(ImageFlagsHasAlpha, flags);
1152 GdipDisposeImage(img);
1153
1154 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppPARGB, NULL, (GpBitmap**)&img);
1155 expect(Ok, stat);
1156 stat = GdipGetImageFlags(img, &flags);
1157 expect(Ok, stat);
1158 expect(ImageFlagsHasAlpha, flags);
1159 GdipDisposeImage(img);
1160
1161 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat48bppRGB, NULL, (GpBitmap**)&img);
1162 expect(Ok, stat);
1163 if (stat == Ok)
1164 {
1165 stat = GdipGetImageFlags(img, &flags);
1166 expect(Ok, stat);
1167 expect(ImageFlagsNone, flags);
1168 GdipDisposeImage(img);
1169 }
1170
1171 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB, NULL, (GpBitmap**)&img);
1172 expect(Ok, stat);
1173 if (stat == Ok)
1174 {
1175 expect(Ok, stat);
1176 stat = GdipGetImageFlags(img, &flags);
1177 expect(Ok, stat);
1178 expect(ImageFlagsHasAlpha, flags);
1179 GdipDisposeImage(img);
1180 }
1181
1182 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB, NULL, (GpBitmap**)&img);
1183 expect(Ok, stat);
1184 if (stat == Ok)
1185 {
1186 expect(Ok, stat);
1187 stat = GdipGetImageFlags(img, &flags);
1188 expect(Ok, stat);
1189 expect(ImageFlagsHasAlpha, flags);
1190 GdipDisposeImage(img);
1191 }
1192 }
1193
1194 static void test_GdipCloneImage(void)
1195 {
1196 GpStatus stat;
1197 GpRectF rectF;
1198 GpUnit unit;
1199 GpBitmap *bm;
1200 GpImage *image_src, *image_dest = NULL;
1201 const INT WIDTH = 10, HEIGHT = 20;
1202
1203 /* Create an image, clone it, delete the original, make sure the copy works */
1204 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
1205 expect(Ok, stat);
1206 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bm, __LINE__, FALSE);
1207
1208 image_src = ((GpImage*)bm);
1209 stat = GdipCloneImage(image_src, &image_dest);
1210 expect(Ok, stat);
1211 expect_rawformat(&ImageFormatMemoryBMP, image_dest, __LINE__, FALSE);
1212
1213 stat = GdipDisposeImage((GpImage*)bm);
1214 expect(Ok, stat);
1215 stat = GdipGetImageBounds(image_dest, &rectF, &unit);
1216 expect(Ok, stat);
1217
1218 /* Treat FP values carefully */
1219 expectf((REAL)WIDTH, rectF.Width);
1220 expectf((REAL)HEIGHT, rectF.Height);
1221
1222 stat = GdipDisposeImage(image_dest);
1223 expect(Ok, stat);
1224 }
1225
1226 static void test_testcontrol(void)
1227 {
1228 GpStatus stat;
1229 DWORD param;
1230
1231 param = 0;
1232 stat = GdipTestControl(TestControlGetBuildNumber, &param);
1233 expect(Ok, stat);
1234 ok(param != 0, "Build number expected, got %u\n", param);
1235 }
1236
1237 static void test_fromhicon(void)
1238 {
1239 static const BYTE bmp_bits[1024];
1240 HBITMAP hbmMask, hbmColor;
1241 ICONINFO info;
1242 HICON hIcon;
1243 GpStatus stat;
1244 GpBitmap *bitmap = NULL;
1245 UINT dim;
1246 ImageType type;
1247 PixelFormat format;
1248
1249 /* NULL */
1250 stat = GdipCreateBitmapFromHICON(NULL, NULL);
1251 expect(InvalidParameter, stat);
1252 stat = GdipCreateBitmapFromHICON(NULL, &bitmap);
1253 expect(InvalidParameter, stat);
1254
1255 /* color icon 1 bit */
1256 hbmMask = CreateBitmap(16, 16, 1, 1, bmp_bits);
1257 ok(hbmMask != 0, "CreateBitmap failed\n");
1258 hbmColor = CreateBitmap(16, 16, 1, 1, bmp_bits);
1259 ok(hbmColor != 0, "CreateBitmap failed\n");
1260 info.fIcon = TRUE;
1261 info.xHotspot = 8;
1262 info.yHotspot = 8;
1263 info.hbmMask = hbmMask;
1264 info.hbmColor = hbmColor;
1265 hIcon = CreateIconIndirect(&info);
1266 ok(hIcon != 0, "CreateIconIndirect failed\n");
1267 DeleteObject(hbmMask);
1268 DeleteObject(hbmColor);
1269
1270 stat = GdipCreateBitmapFromHICON(hIcon, &bitmap);
1271 ok(stat == Ok ||
1272 broken(stat == InvalidParameter), /* Win98 */
1273 "Expected Ok, got %.8x\n", stat);
1274 if(stat == Ok){
1275 /* check attributes */
1276 stat = GdipGetImageHeight((GpImage*)bitmap, &dim);
1277 expect(Ok, stat);
1278 expect(16, dim);
1279 stat = GdipGetImageWidth((GpImage*)bitmap, &dim);
1280 expect(Ok, stat);
1281 expect(16, dim);
1282 stat = GdipGetImageType((GpImage*)bitmap, &type);
1283 expect(Ok, stat);
1284 expect(ImageTypeBitmap, type);
1285 stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format);
1286 expect(Ok, stat);
1287 expect(PixelFormat32bppARGB, format);
1288 /* raw format */
1289 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
1290 GdipDisposeImage((GpImage*)bitmap);
1291 }
1292 DestroyIcon(hIcon);
1293
1294 /* color icon 8 bpp */
1295 hbmMask = CreateBitmap(16, 16, 1, 8, bmp_bits);
1296 ok(hbmMask != 0, "CreateBitmap failed\n");
1297 hbmColor = CreateBitmap(16, 16, 1, 8, bmp_bits);
1298 ok(hbmColor != 0, "CreateBitmap failed\n");
1299 info.fIcon = TRUE;
1300 info.xHotspot = 8;
1301 info.yHotspot = 8;
1302 info.hbmMask = hbmMask;
1303 info.hbmColor = hbmColor;
1304 hIcon = CreateIconIndirect(&info);
1305 ok(hIcon != 0, "CreateIconIndirect failed\n");
1306 DeleteObject(hbmMask);
1307 DeleteObject(hbmColor);
1308
1309 stat = GdipCreateBitmapFromHICON(hIcon, &bitmap);
1310 expect(Ok, stat);
1311 if(stat == Ok){
1312 /* check attributes */
1313 stat = GdipGetImageHeight((GpImage*)bitmap, &dim);
1314 expect(Ok, stat);
1315 expect(16, dim);
1316 stat = GdipGetImageWidth((GpImage*)bitmap, &dim);
1317 expect(Ok, stat);
1318 expect(16, dim);
1319 stat = GdipGetImageType((GpImage*)bitmap, &type);
1320 expect(Ok, stat);
1321 expect(ImageTypeBitmap, type);
1322 stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format);
1323 expect(Ok, stat);
1324 expect(PixelFormat32bppARGB, format);
1325 /* raw format */
1326 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
1327 GdipDisposeImage((GpImage*)bitmap);
1328 }
1329 DestroyIcon(hIcon);
1330 }
1331
1332 /* 1x1 pixel png */
1333 static const unsigned char pngimage[285] = {
1334 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
1335 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
1336 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
1337 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
1338 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
1339 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
1340 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
1341 };
1342 /* 1x1 pixel gif */
1343 static const unsigned char gifimage[35] = {
1344 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
1345 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
1346 0x01,0x00,0x3b
1347 };
1348 /* 1x1 pixel transparent gif */
1349 static const unsigned char transparentgif[] = {
1350 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,
1351 0x00,0x00,0x00,0x21,0xf9,0x04,0x01,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,
1352 0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
1353 };
1354 /* 1x1 pixel bmp */
1355 static const unsigned char bmpimage[66] = {
1356 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
1357 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
1358 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
1359 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
1360 0x00,0x00
1361 };
1362 /* 1x1 pixel jpg */
1363 static const unsigned char jpgimage[285] = {
1364 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
1365 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
1366 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
1367 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
1368 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
1369 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
1370 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
1371 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1372 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1373 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
1374 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
1375 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1376 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
1377 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
1378 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1379 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
1380 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
1381 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
1382 };
1383 /* 1x1 pixel tiff */
1384 static const unsigned char tiffimage[] = {
1385 0x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00,
1386 0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00,
1387 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1388 0x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01,
1389 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00,
1390 0x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00,
1391 0x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01,
1392 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00,
1393 0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00,
1394 0x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01,
1395 0x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00,
1396 0x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1397 0x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
1398 0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65,
1399 0x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74,
1400 0x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,
1401 0x00,0x00,0x00,0x01
1402 };
1403 /* 320x320 twip wmf */
1404 static const unsigned char wmfimage[180] = {
1405 0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05,
1406 0x00,0x00,0x00,0x00,0xb1,0x52,0x01,0x00,0x09,0x00,0x00,0x03,0x4f,0x00,0x00,0x00,
1407 0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0b,0x02,0x00,0x00,
1408 0x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x02,0x40,0x01,0x40,0x01,0x04,0x00,0x00,0x00,
1409 0x02,0x01,0x01,0x00,0x04,0x00,0x00,0x00,0x04,0x01,0x0d,0x00,0x08,0x00,0x00,0x00,
1410 0xfa,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
1411 0x2d,0x01,0x00,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,0x01,0x00,0x00,0x00,0x00,0x00,
1412 0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x01,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,
1413 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x02,0x00,
1414 0x07,0x00,0x00,0x00,0x1b,0x04,0x40,0x01,0x40,0x01,0x00,0x00,0x00,0x00,0x04,0x00,
1415 0x00,0x00,0xf0,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0xf0,0x01,0x01,0x00,0x03,0x00,
1416 0x00,0x00,0x00,0x00
1417 };
1418 static void test_getrawformat(void)
1419 {
1420 test_bufferrawformat((void*)pngimage, sizeof(pngimage), &ImageFormatPNG, __LINE__, FALSE);
1421 test_bufferrawformat((void*)gifimage, sizeof(gifimage), &ImageFormatGIF, __LINE__, FALSE);
1422 test_bufferrawformat((void*)bmpimage, sizeof(bmpimage), &ImageFormatBMP, __LINE__, FALSE);
1423 test_bufferrawformat((void*)jpgimage, sizeof(jpgimage), &ImageFormatJPEG, __LINE__, FALSE);
1424 test_bufferrawformat((void*)tiffimage, sizeof(tiffimage), &ImageFormatTIFF, __LINE__, FALSE);
1425 test_bufferrawformat((void*)wmfimage, sizeof(wmfimage), &ImageFormatWMF, __LINE__, FALSE);
1426 }
1427
1428 static void test_loadwmf(void)
1429 {
1430 LPSTREAM stream;
1431 HGLOBAL hglob;
1432 LPBYTE data;
1433 HRESULT hres;
1434 GpStatus stat;
1435 GpImage *img;
1436 GpRectF bounds;
1437 GpUnit unit;
1438 REAL res = 12345.0;
1439 MetafileHeader header;
1440
1441 hglob = GlobalAlloc (0, sizeof(wmfimage));
1442 data = GlobalLock (hglob);
1443 memcpy(data, wmfimage, sizeof(wmfimage));
1444 GlobalUnlock(hglob); data = NULL;
1445
1446 hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
1447 ok(hres == S_OK, "Failed to create a stream\n");
1448 if(hres != S_OK) return;
1449
1450 stat = GdipLoadImageFromStream(stream, &img);
1451 ok(stat == Ok, "Failed to create a Bitmap\n");
1452 if(stat != Ok){
1453 IStream_Release(stream);
1454 return;
1455 }
1456
1457 IStream_Release(stream);
1458
1459 stat = GdipGetImageBounds(img, &bounds, &unit);
1460 expect(Ok, stat);
1461 expect(UnitPixel, unit);
1462 expectf(0.0, bounds.X);
1463 expectf(0.0, bounds.Y);
1464 expectf(320.0, bounds.Width);
1465 expectf(320.0, bounds.Height);
1466
1467 stat = GdipGetImageHorizontalResolution(img, &res);
1468 expect(Ok, stat);
1469 expectf(1440.0, res);
1470
1471 stat = GdipGetImageVerticalResolution(img, &res);
1472 expect(Ok, stat);
1473 expectf(1440.0, res);
1474
1475 memset(&header, 0, sizeof(header));
1476 stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header);
1477 expect(Ok, stat);
1478 if (stat == Ok)
1479 {
1480 expect(MetafileTypeWmfPlaceable, header.Type);
1481 todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size);
1482 todo_wine expect(0x300, header.Version);
1483 expect(0, header.EmfPlusFlags);
1484 expectf(1440.0, header.DpiX);
1485 expectf(1440.0, header.DpiY);
1486 expect(0, header.X);
1487 expect(0, header.Y);
1488 expect(320, header.Width);
1489 expect(320, header.Height);
1490 expect(1, U(header).WmfHeader.mtType);
1491 expect(0, header.EmfPlusHeaderSize);
1492 expect(0, header.LogicalDpiX);
1493 expect(0, header.LogicalDpiY);
1494 }
1495
1496 GdipDisposeImage(img);
1497 }
1498
1499 static void test_createfromwmf(void)
1500 {
1501 HMETAFILE hwmf;
1502 GpImage *img;
1503 GpStatus stat;
1504 GpRectF bounds;
1505 GpUnit unit;
1506 REAL res = 12345.0;
1507 MetafileHeader header;
1508
1509 hwmf = SetMetaFileBitsEx(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader),
1510 wmfimage+sizeof(WmfPlaceableFileHeader));
1511 ok(hwmf != 0, "SetMetaFileBitsEx failed\n");
1512
1513 stat = GdipCreateMetafileFromWmf(hwmf, TRUE,
1514 (WmfPlaceableFileHeader*)wmfimage, (GpMetafile**)&img);
1515 expect(Ok, stat);
1516
1517 stat = GdipGetImageBounds(img, &bounds, &unit);
1518 expect(Ok, stat);
1519 expect(UnitPixel, unit);
1520 expectf(0.0, bounds.X);
1521 expectf(0.0, bounds.Y);
1522 expectf(320.0, bounds.Width);
1523 expectf(320.0, bounds.Height);
1524
1525 stat = GdipGetImageHorizontalResolution(img, &res);
1526 expect(Ok, stat);
1527 expectf(1440.0, res);
1528
1529 stat = GdipGetImageVerticalResolution(img, &res);
1530 expect(Ok, stat);
1531 expectf(1440.0, res);
1532
1533 memset(&header, 0, sizeof(header));
1534 stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header);
1535 expect(Ok, stat);
1536 if (stat == Ok)
1537 {
1538 expect(MetafileTypeWmfPlaceable, header.Type);
1539 todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size);
1540 todo_wine expect(0x300, header.Version);
1541 expect(0, header.EmfPlusFlags);
1542 expectf(1440.0, header.DpiX);
1543 expectf(1440.0, header.DpiY);
1544 expect(0, header.X);
1545 expect(0, header.Y);
1546 expect(320, header.Width);
1547 expect(320, header.Height);
1548 expect(1, U(header).WmfHeader.mtType);
1549 expect(0, header.EmfPlusHeaderSize);
1550 expect(0, header.LogicalDpiX);
1551 expect(0, header.LogicalDpiY);
1552 }
1553
1554 GdipDisposeImage(img);
1555 }
1556
1557 static void test_createfromwmf_noplaceable(void)
1558 {
1559 HMETAFILE hwmf;
1560 GpImage *img;
1561 GpStatus stat;
1562
1563 hwmf = SetMetaFileBitsEx(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader),
1564 wmfimage+sizeof(WmfPlaceableFileHeader));
1565 ok(hwmf != 0, "SetMetaFileBitsEx failed\n");
1566
1567 stat = GdipCreateMetafileFromWmf(hwmf, TRUE, NULL, (GpMetafile**)&img);
1568 expect(Ok, stat);
1569
1570 GdipDisposeImage(img);
1571 }
1572
1573 static void test_resolution(void)
1574 {
1575 GpStatus stat;
1576 GpBitmap *bitmap;
1577 GpGraphics *graphics;
1578 REAL res=-1.0;
1579 HDC screendc;
1580 int screenxres, screenyres;
1581
1582 /* create Bitmap */
1583 stat = GdipCreateBitmapFromScan0(1, 1, 32, PixelFormat24bppRGB, NULL, &bitmap);
1584 expect(Ok, stat);
1585
1586 /* test invalid values */
1587 stat = GdipGetImageHorizontalResolution(NULL, &res);
1588 expect(InvalidParameter, stat);
1589
1590 stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, NULL);
1591 expect(InvalidParameter, stat);
1592
1593 stat = GdipGetImageVerticalResolution(NULL, &res);
1594 expect(InvalidParameter, stat);
1595
1596 stat = GdipGetImageVerticalResolution((GpImage*)bitmap, NULL);
1597 expect(InvalidParameter, stat);
1598
1599 stat = GdipBitmapSetResolution(NULL, 96.0, 96.0);
1600 expect(InvalidParameter, stat);
1601
1602 stat = GdipBitmapSetResolution(bitmap, 0.0, 0.0);
1603 expect(InvalidParameter, stat);
1604
1605 /* defaults to screen resolution */
1606 screendc = GetDC(0);
1607
1608 screenxres = GetDeviceCaps(screendc, LOGPIXELSX);
1609 screenyres = GetDeviceCaps(screendc, LOGPIXELSY);
1610
1611 ReleaseDC(0, screendc);
1612
1613 stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, &res);
1614 expect(Ok, stat);
1615 expectf((REAL)screenxres, res);
1616
1617 stat = GdipGetImageVerticalResolution((GpImage*)bitmap, &res);
1618 expect(Ok, stat);
1619 expectf((REAL)screenyres, res);
1620
1621 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
1622 expect(Ok, stat);
1623 stat = GdipGetDpiX(graphics, &res);
1624 expect(Ok, stat);
1625 expectf((REAL)screenxres, res);
1626 stat = GdipGetDpiY(graphics, &res);
1627 expect(Ok, stat);
1628 expectf((REAL)screenyres, res);
1629
1630 /* test changing the resolution */
1631 stat = GdipBitmapSetResolution(bitmap, screenxres*2.0, screenyres*3.0);
1632 expect(Ok, stat);
1633
1634 stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, &res);
1635 expect(Ok, stat);
1636 expectf(screenxres*2.0, res);
1637
1638 stat = GdipGetImageVerticalResolution((GpImage*)bitmap, &res);
1639 expect(Ok, stat);
1640 expectf(screenyres*3.0, res);
1641
1642 stat = GdipGetDpiX(graphics, &res);
1643 expect(Ok, stat);
1644 expectf((REAL)screenxres, res);
1645 stat = GdipGetDpiY(graphics, &res);
1646 expect(Ok, stat);
1647 expectf((REAL)screenyres, res);
1648
1649 stat = GdipDeleteGraphics(graphics);
1650 expect(Ok, stat);
1651
1652 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
1653 expect(Ok, stat);
1654 stat = GdipGetDpiX(graphics, &res);
1655 expect(Ok, stat);
1656 expectf(screenxres*2.0, res);
1657 stat = GdipGetDpiY(graphics, &res);
1658 expect(Ok, stat);
1659 expectf(screenyres*3.0, res);
1660 stat = GdipDeleteGraphics(graphics);
1661 expect(Ok, stat);
1662
1663 stat = GdipDisposeImage((GpImage*)bitmap);
1664 expect(Ok, stat);
1665 }
1666
1667 static void test_createhbitmap(void)
1668 {
1669 GpStatus stat;
1670 GpBitmap *bitmap;
1671 HBITMAP hbitmap, oldhbitmap;
1672 BITMAP bm;
1673 int ret;
1674 HDC hdc;
1675 COLORREF pixel;
1676 BYTE bits[640];
1677 BitmapData lockeddata;
1678
1679 memset(bits, 0x68, 640);
1680
1681 /* create Bitmap */
1682 stat = GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB, bits, &bitmap);
1683 expect(Ok, stat);
1684
1685 /* test NULL values */
1686 stat = GdipCreateHBITMAPFromBitmap(NULL, &hbitmap, 0);
1687 expect(InvalidParameter, stat);
1688
1689 stat = GdipCreateHBITMAPFromBitmap(bitmap, NULL, 0);
1690 expect(InvalidParameter, stat);
1691
1692 /* create HBITMAP */
1693 stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0);
1694 expect(Ok, stat);
1695
1696 if (stat == Ok)
1697 {
1698 ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
1699 expect(sizeof(BITMAP), ret);
1700
1701 expect(0, bm.bmType);
1702 expect(10, bm.bmWidth);
1703 expect(20, bm.bmHeight);
1704 expect(40, bm.bmWidthBytes);
1705 expect(1, bm.bmPlanes);
1706 expect(32, bm.bmBitsPixel);
1707 ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
1708
1709 if (bm.bmBits)
1710 {
1711 DWORD val = *(DWORD*)bm.bmBits;
1712 ok(val == 0xff686868, "got %x, expected 0xff686868\n", val);
1713 }
1714
1715 hdc = CreateCompatibleDC(NULL);
1716
1717 oldhbitmap = SelectObject(hdc, hbitmap);
1718 pixel = GetPixel(hdc, 5, 5);
1719 SelectObject(hdc, oldhbitmap);
1720
1721 DeleteDC(hdc);
1722
1723 expect(0x686868, pixel);
1724
1725 DeleteObject(hbitmap);
1726 }
1727
1728 stat = GdipDisposeImage((GpImage*)bitmap);
1729 expect(Ok, stat);
1730
1731 /* make (1,0) have no alpha and (2,0) a different blue value. */
1732 bits[7] = 0x00;
1733 bits[8] = 0x40;
1734
1735 /* create alpha Bitmap */
1736 stat = GdipCreateBitmapFromScan0(8, 20, 32, PixelFormat32bppARGB, bits, &bitmap);
1737 expect(Ok, stat);
1738
1739 /* create HBITMAP */
1740 stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0);
1741 expect(Ok, stat);
1742
1743 if (stat == Ok)
1744 {
1745 ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
1746 expect(sizeof(BITMAP), ret);
1747
1748 expect(0, bm.bmType);
1749 expect(8, bm.bmWidth);
1750 expect(20, bm.bmHeight);
1751 expect(32, bm.bmWidthBytes);
1752 expect(1, bm.bmPlanes);
1753 expect(32, bm.bmBitsPixel);
1754 ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
1755
1756 if (bm.bmBits)
1757 {
1758 DWORD val = *(DWORD*)bm.bmBits;
1759 ok(val == 0x682a2a2a, "got %x, expected 0x682a2a2a\n", val);
1760 val = *((DWORD*)bm.bmBits + (bm.bmHeight-1) * bm.bmWidthBytes/4 + 1);
1761 ok(val == 0x0, "got %x, expected 0x682a2a2a\n", val);
1762 }
1763
1764 hdc = CreateCompatibleDC(NULL);
1765
1766 oldhbitmap = SelectObject(hdc, hbitmap);
1767 pixel = GetPixel(hdc, 5, 5);
1768 expect(0x2a2a2a, pixel);
1769 pixel = GetPixel(hdc, 1, 0);
1770 expect(0x0, pixel);
1771
1772 SelectObject(hdc, oldhbitmap);
1773
1774 DeleteDC(hdc);
1775
1776
1777 DeleteObject(hbitmap);
1778 }
1779
1780 /* create HBITMAP with bkgnd colour */
1781 /* gdiplus.dll 5.1 is broken and only applies the blue value */
1782 stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0xff00ff);
1783 expect(Ok, stat);
1784
1785 if (stat == Ok)
1786 {
1787 ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
1788 expect(sizeof(BITMAP), ret);
1789
1790 expect(0, bm.bmType);
1791 expect(8, bm.bmWidth);
1792 expect(20, bm.bmHeight);
1793 expect(32, bm.bmWidthBytes);
1794 expect(1, bm.bmPlanes);
1795 expect(32, bm.bmBitsPixel);
1796 ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
1797
1798 if (bm.bmBits)
1799 {
1800 DWORD val = *(DWORD*)bm.bmBits;
1801 ok(val == 0x68c12ac1 || broken(val == 0x682a2ac1), "got %x, expected 0x68c12ac1\n", val);
1802 val = *((DWORD*)bm.bmBits + (bm.bmHeight-1) * bm.bmWidthBytes/4 + 1);
1803 ok(val == 0xff00ff || broken(val == 0xff), "got %x, expected 0xff00ff\n", val);
1804 }
1805
1806 hdc = CreateCompatibleDC(NULL);
1807
1808 oldhbitmap = SelectObject(hdc, hbitmap);
1809 pixel = GetPixel(hdc, 5, 5);
1810 ok(pixel == 0xc12ac1 || broken(pixel == 0xc12a2a), "got %x, expected 0xc12ac1\n", pixel);
1811 pixel = GetPixel(hdc, 1, 0);
1812 ok(pixel == 0xff00ff || broken(pixel == 0xff0000), "got %x, expected 0xff00ff\n", pixel);
1813 pixel = GetPixel(hdc, 2, 0);
1814 ok(pixel == 0xb12ac1 || broken(pixel == 0xb12a2a), "got %x, expected 0xb12ac1\n", pixel);
1815
1816 SelectObject(hdc, oldhbitmap);
1817 DeleteDC(hdc);
1818 DeleteObject(hbitmap);
1819 }
1820
1821 /* create HBITMAP with bkgnd colour with alpha and show it behaves with no alpha. */
1822 stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0x80ff00ff);
1823 expect(Ok, stat);
1824
1825 if (stat == Ok)
1826 {
1827 ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
1828 expect(sizeof(BITMAP), ret);
1829
1830 expect(0, bm.bmType);
1831 expect(8, bm.bmWidth);
1832 expect(20, bm.bmHeight);
1833 expect(32, bm.bmWidthBytes);
1834 expect(1, bm.bmPlanes);
1835 expect(32, bm.bmBitsPixel);
1836 ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
1837
1838 if (bm.bmBits)
1839 {
1840 DWORD val = *(DWORD*)bm.bmBits;
1841 ok(val == 0x68c12ac1 || broken(val == 0x682a2ac1), "got %x, expected 0x68c12ac1\n", val);
1842 val = *((DWORD*)bm.bmBits + (bm.bmHeight-1) * bm.bmWidthBytes/4 + 1);
1843 ok(val == 0xff00ff || broken(val == 0xff), "got %x, expected 0xff00ff\n", val);
1844 }
1845
1846 hdc = CreateCompatibleDC(NULL);
1847
1848 oldhbitmap = SelectObject(hdc, hbitmap);
1849 pixel = GetPixel(hdc, 5, 5);
1850 ok(pixel == 0xc12ac1 || broken(pixel == 0xc12a2a), "got %x, expected 0xc12ac1\n", pixel);
1851 pixel = GetPixel(hdc, 1, 0);
1852 ok(pixel == 0xff00ff || broken(pixel == 0xff0000), "got %x, expected 0xff00ff\n", pixel);
1853 pixel = GetPixel(hdc, 2, 0);
1854 ok(pixel == 0xb12ac1 || broken(pixel == 0xb12a2a), "got %x, expected 0xb12ac1\n", pixel);
1855
1856 SelectObject(hdc, oldhbitmap);
1857 DeleteDC(hdc);
1858 DeleteObject(hbitmap);
1859 }
1860
1861 stat = GdipDisposeImage((GpImage*)bitmap);
1862 expect(Ok, stat);
1863
1864 /* create HBITMAP from locked data */
1865 memset(bits, 0x68, 640);
1866 stat = GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB, bits, &bitmap);
1867 expect(Ok, stat);
1868
1869 memset(&lockeddata, 0, sizeof(lockeddata));
1870 stat = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead | ImageLockModeWrite,
1871 PixelFormat32bppRGB, &lockeddata);
1872 expect(Ok, stat);
1873 ((DWORD*)lockeddata.Scan0)[0] = 0xff242424;
1874 stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0);
1875 expect(Ok, stat);
1876 stat = GdipBitmapUnlockBits(bitmap, &lockeddata);
1877 expect(Ok, stat);
1878 stat = GdipDisposeImage((GpImage*)bitmap);
1879 expect(Ok, stat);
1880
1881 hdc = CreateCompatibleDC(NULL);
1882 oldhbitmap = SelectObject(hdc, hbitmap);
1883 pixel = GetPixel(hdc, 0, 0);
1884 expect(0x686868, pixel);
1885 SelectObject(hdc, oldhbitmap);
1886 DeleteDC(hdc);
1887 }
1888
1889 static void test_getthumbnail(void)
1890 {
1891 GpStatus stat;
1892 GpImage *bitmap1, *bitmap2;
1893 UINT width, height;
1894
1895 stat = GdipGetImageThumbnail(NULL, 0, 0, &bitmap2, NULL, NULL);
1896 expect(InvalidParameter, stat);
1897
1898 stat = GdipCreateBitmapFromScan0(128, 128, 0, PixelFormat32bppRGB, NULL, (GpBitmap**)&bitmap1);
1899 expect(Ok, stat);
1900
1901 stat = GdipGetImageThumbnail(bitmap1, 0, 0, NULL, NULL, NULL);
1902 expect(InvalidParameter, stat);
1903
1904 stat = GdipGetImageThumbnail(bitmap1, 0, 0, &bitmap2, NULL, NULL);
1905 expect(Ok, stat);
1906
1907 if (stat == Ok)
1908 {
1909 stat = GdipGetImageWidth(bitmap2, &width);
1910 expect(Ok, stat);
1911 expect(120, width);
1912
1913 stat = GdipGetImageHeight(bitmap2, &height);
1914 expect(Ok, stat);
1915 expect(120, height);
1916
1917 GdipDisposeImage(bitmap2);
1918 }
1919
1920 GdipDisposeImage(bitmap1);
1921
1922
1923 stat = GdipCreateBitmapFromScan0(64, 128, 0, PixelFormat32bppRGB, NULL, (GpBitmap**)&bitmap1);
1924 expect(Ok, stat);
1925
1926 stat = GdipGetImageThumbnail(bitmap1, 32, 32, &bitmap2, NULL, NULL);
1927 expect(Ok, stat);
1928
1929 if (stat == Ok)
1930 {
1931 stat = GdipGetImageWidth(bitmap2, &width);
1932 expect(Ok, stat);
1933 expect(32, width);
1934
1935 stat = GdipGetImageHeight(bitmap2, &height);
1936 expect(Ok, stat);
1937 expect(32, height);
1938
1939 GdipDisposeImage(bitmap2);
1940 }
1941
1942 stat = GdipGetImageThumbnail(bitmap1, 0, 0, &bitmap2, NULL, NULL);
1943 expect(Ok, stat);
1944
1945 if (stat == Ok)
1946 {
1947 stat = GdipGetImageWidth(bitmap2, &width);
1948 expect(Ok, stat);
1949 expect(120, width);
1950
1951 stat = GdipGetImageHeight(bitmap2, &height);
1952 expect(Ok, stat);
1953 expect(120, height);
1954
1955 GdipDisposeImage(bitmap2);
1956 }
1957
1958 GdipDisposeImage(bitmap1);
1959 }
1960
1961 static void test_getsetpixel(void)
1962 {
1963 GpStatus stat;
1964 GpBitmap *bitmap;
1965 ARGB color;
1966 BYTE bits[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00,
1967 0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00};
1968
1969 stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB, bits, &bitmap);
1970 expect(Ok, stat);
1971
1972 /* null parameters */
1973 stat = GdipBitmapGetPixel(NULL, 1, 1, &color);
1974 expect(InvalidParameter, stat);
1975
1976 stat = GdipBitmapGetPixel(bitmap, 1, 1, NULL);
1977 expect(InvalidParameter, stat);
1978
1979 stat = GdipBitmapSetPixel(NULL, 1, 1, 0);
1980 expect(InvalidParameter, stat);
1981
1982 /* out of bounds */
1983 stat = GdipBitmapGetPixel(bitmap, -1, 1, &color);
1984 expect(InvalidParameter, stat);
1985
1986 stat = GdipBitmapSetPixel(bitmap, -1, 1, 0);
1987 expect(InvalidParameter, stat);
1988
1989 stat = GdipBitmapGetPixel(bitmap, 1, -1, &color);
1990 ok(stat == InvalidParameter ||
1991 broken(stat == Ok), /* Older gdiplus */
1992 "Expected InvalidParameter, got %.8x\n", stat);
1993
1994 if (0) /* crashes some gdiplus implementations */
1995 {
1996 stat = GdipBitmapSetPixel(bitmap, 1, -1, 0);
1997 ok(stat == InvalidParameter ||
1998 broken(stat == Ok), /* Older gdiplus */
1999 "Expected InvalidParameter, got %.8x\n", stat);
2000 }
2001
2002 stat = GdipBitmapGetPixel(bitmap, 2, 1, &color);
2003 expect(InvalidParameter, stat);
2004
2005 stat = GdipBitmapSetPixel(bitmap, 2, 1, 0);
2006 expect(InvalidParameter, stat);
2007
2008 stat = GdipBitmapGetPixel(bitmap, 1, 2, &color);
2009 expect(InvalidParameter, stat);
2010
2011 stat = GdipBitmapSetPixel(bitmap, 1, 2, 0);
2012 expect(InvalidParameter, stat);
2013
2014 /* valid use */
2015 stat = GdipBitmapGetPixel(bitmap, 1, 1, &color);
2016 expect(Ok, stat);
2017 expect(0xffffffff, color);
2018
2019 stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
2020 expect(Ok, stat);
2021 expect(0xff0000ff, color);
2022
2023 stat = GdipBitmapSetPixel(bitmap, 1, 1, 0xff676869);
2024 expect(Ok, stat);
2025
2026 stat = GdipBitmapSetPixel(bitmap, 0, 0, 0xff474849);
2027 expect(Ok, stat);
2028
2029 stat = GdipBitmapGetPixel(bitmap, 1, 1, &color);
2030 expect(Ok, stat);
2031 expect(0xff676869, color);
2032
2033 stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
2034 expect(Ok, stat);
2035 expect(0xff474849, color);
2036
2037 stat = GdipDisposeImage((GpImage*)bitmap);
2038 expect(Ok, stat);
2039 }
2040
2041 static void check_halftone_palette(ColorPalette *palette)
2042 {
2043 static const BYTE halftone_values[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
2044 UINT i;
2045
2046 for (i=0; i<palette->Count; i++)
2047 {
2048 ARGB expected=0xff000000;
2049 if (i<8)
2050 {
2051 if (i&1) expected |= 0x800000;
2052 if (i&2) expected |= 0x8000;
2053 if (i&4) expected |= 0x80;
2054 }
2055 else if (i == 8)
2056 {
2057 expected = 0xffc0c0c0;
2058 }
2059 else if (i < 16)
2060 {
2061 if (i&1) expected |= 0xff0000;
2062 if (i&2) expected |= 0xff00;
2063 if (i&4) expected |= 0xff;
2064 }
2065 else if (i < 40)
2066 {
2067 expected = 0x00000000;
2068 }
2069 else
2070 {
2071 expected |= halftone_values[(i-40)%6];
2072 expected |= halftone_values[((i-40)/6)%6] << 8;
2073 expected |= halftone_values[((i-40)/36)%6] << 16;
2074 }
2075 ok(expected == palette->Entries[i], "Expected %.8x, got %.8x, i=%u/%u\n",
2076 expected, palette->Entries[i], i, palette->Count);
2077 }
2078 }
2079
2080 static void test_palette(void)
2081 {
2082 GpStatus stat;
2083 GpBitmap *bitmap;
2084 INT size;
2085 BYTE buffer[1040];
2086 ColorPalette *palette=(ColorPalette*)buffer;
2087 ARGB *entries = palette->Entries;
2088 ARGB color=0;
2089
2090 /* test initial palette from non-indexed bitmap */
2091 stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB, NULL, &bitmap);
2092 expect(Ok, stat);
2093
2094 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
2095 expect(Ok, stat);
2096 expect(sizeof(UINT)*2+sizeof(ARGB), size);
2097
2098 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
2099 expect(Ok, stat);
2100 expect(0, palette->Count);
2101
2102 /* test setting palette on not-indexed bitmap */
2103 palette->Count = 3;
2104
2105 stat = GdipSetImagePalette((GpImage*)bitmap, palette);
2106 expect(Ok, stat);
2107
2108 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
2109 expect(Ok, stat);
2110 expect(sizeof(UINT)*2+sizeof(ARGB)*3, size);
2111
2112 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
2113 expect(Ok, stat);
2114 expect(3, palette->Count);
2115
2116 GdipDisposeImage((GpImage*)bitmap);
2117
2118 /* test initial palette on 1-bit bitmap */
2119 stat = GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat1bppIndexed, NULL, &bitmap);
2120 expect(Ok, stat);
2121
2122 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
2123 expect(Ok, stat);
2124 expect(sizeof(UINT)*2+sizeof(ARGB)*2, size);
2125
2126 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
2127 expect(Ok, stat);
2128 expect(PaletteFlagsGrayScale, palette->Flags);
2129 expect(2, palette->Count);
2130
2131 expect(0xff000000, entries[0]);
2132 expect(0xffffffff, entries[1]);
2133
2134 /* test getting/setting pixels */
2135 stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
2136 expect(Ok, stat);
2137 expect(0xff000000, color);
2138
2139 stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffffffff);
2140 ok((stat == Ok) ||
2141 broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
2142
2143 if (stat == Ok)
2144 {
2145 stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
2146 expect(Ok, stat);
2147 expect(0xffffffff, color);
2148 }
2149
2150 GdipDisposeImage((GpImage*)bitmap);
2151
2152 /* test initial palette on 4-bit bitmap */
2153 stat = GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat4bppIndexed, NULL, &bitmap);
2154 expect(Ok, stat);
2155
2156 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
2157 expect(Ok, stat);
2158 expect(sizeof(UINT)*2+sizeof(ARGB)*16, size);
2159
2160 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
2161 expect(Ok, stat);
2162 expect(0, palette->Flags);
2163 expect(16, palette->Count);
2164
2165 check_halftone_palette(palette);
2166
2167 /* test getting/setting pixels */
2168 stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
2169 expect(Ok, stat);
2170 expect(0xff000000, color);
2171
2172 stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffff00ff);
2173 ok((stat == Ok) ||
2174 broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
2175
2176 if (stat == Ok)
2177 {
2178 stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
2179 expect(Ok, stat);
2180 expect(0xffff00ff, color);
2181 }
2182
2183 GdipDisposeImage((GpImage*)bitmap);
2184
2185 /* test initial palette on 8-bit bitmap */
2186 stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat8bppIndexed, NULL, &bitmap);
2187 expect(Ok, stat);
2188
2189 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
2190 expect(Ok, stat);
2191 expect(sizeof(UINT)*2+sizeof(ARGB)*256, size);
2192
2193 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
2194 expect(Ok, stat);
2195 expect(PaletteFlagsHalftone, palette->Flags);
2196 expect(256, palette->Count);
2197
2198 check_halftone_palette(palette);
2199
2200 /* test getting/setting pixels */
2201 stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
2202 expect(Ok, stat);
2203 expect(0xff000000, color);
2204
2205 stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffcccccc);
2206 ok((stat == Ok) ||
2207 broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
2208
2209 if (stat == Ok)
2210 {
2211 stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
2212 expect(Ok, stat);
2213 expect(0xffcccccc, color);
2214 }
2215
2216 /* test setting/getting a different palette */
2217 entries[1] = 0xffcccccc;
2218
2219 stat = GdipSetImagePalette((GpImage*)bitmap, palette);
2220 expect(Ok, stat);
2221
2222 entries[1] = 0;
2223
2224 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
2225 expect(Ok, stat);
2226 expect(sizeof(UINT)*2+sizeof(ARGB)*256, size);
2227
2228 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
2229 expect(Ok, stat);
2230 expect(PaletteFlagsHalftone, palette->Flags);
2231 expect(256, palette->Count);
2232 expect(0xffcccccc, entries[1]);
2233
2234 /* test count < 256 */
2235 palette->Flags = 12345;
2236 palette->Count = 3;
2237
2238 stat = GdipSetImagePalette((GpImage*)bitmap, palette);
2239 expect(Ok, stat);
2240
2241 entries[1] = 0;
2242 entries[3] = 0xdeadbeef;
2243
2244 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
2245 expect(Ok, stat);
2246 expect(sizeof(UINT)*2+sizeof(ARGB)*3, size);
2247
2248 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
2249 expect(Ok, stat);
2250 expect(12345, palette->Flags);
2251 expect(3, palette->Count);
2252 expect(0xffcccccc, entries[1]);
2253 expect(0xdeadbeef, entries[3]);
2254
2255 /* test count > 256 */
2256 palette->Count = 257;
2257
2258 stat = GdipSetImagePalette((GpImage*)bitmap, palette);
2259 ok(stat == InvalidParameter ||
2260 broken(stat == Ok), /* Old gdiplus behavior */
2261 "Expected %.8x, got %.8x\n", InvalidParameter, stat);
2262
2263 GdipDisposeImage((GpImage*)bitmap);
2264 }
2265
2266 static void test_colormatrix(void)
2267 {
2268 GpStatus stat;
2269 ColorMatrix colormatrix, graymatrix;
2270 GpImageAttributes *imageattr;
2271 const ColorMatrix identity = {{
2272 {1.0,0.0,0.0,0.0,0.0},
2273 {0.0,1.0,0.0,0.0,0.0},
2274 {0.0,0.0,1.0,0.0,0.0},
2275 {0.0,0.0,0.0,1.0,0.0},
2276 {0.0,0.0,0.0,0.0,1.0}}};
2277 const ColorMatrix double_red = {{
2278 {2.0,0.0,0.0,0.0,0.0},
2279 {0.0,1.0,0.0,0.0,0.0},
2280 {0.0,0.0,1.0,0.0,0.0},
2281 {0.0,0.0,0.0,1.0,0.0},
2282 {0.0,0.0,0.0,0.0,1.0}}};
2283 const ColorMatrix asymmetric = {{
2284 {0.0,1.0,0.0,0.0,0.0},
2285 {0.0,0.0,1.0,0.0,0.0},
2286 {0.0,0.0,0.0,1.0,0.0},
2287 {1.0,0.0,0.0,0.0,0.0},
2288 {0.0,0.0,0.0,0.0,1.0}}};
2289 GpBitmap *bitmap1, *bitmap2;
2290 GpGraphics *graphics;
2291 ARGB color;
2292
2293 colormatrix = identity;
2294 graymatrix = identity;
2295
2296 stat = GdipSetImageAttributesColorMatrix(NULL, ColorAdjustTypeDefault,
2297 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2298 expect(InvalidParameter, stat);
2299
2300 stat = GdipCreateImageAttributes(&imageattr);
2301 expect(Ok, stat);
2302
2303 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2304 TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2305 expect(Ok, stat);
2306
2307 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2308 TRUE, NULL, NULL, ColorMatrixFlagsDefault);
2309 expect(InvalidParameter, stat);
2310
2311 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2312 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2313 expect(Ok, stat);
2314
2315 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2316 TRUE, &colormatrix, NULL, ColorMatrixFlagsSkipGrays);
2317 expect(Ok, stat);
2318
2319 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2320 TRUE, &colormatrix, NULL, ColorMatrixFlagsAltGray);
2321 expect(InvalidParameter, stat);
2322
2323 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2324 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsAltGray);
2325 expect(Ok, stat);
2326
2327 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2328 TRUE, &colormatrix, &graymatrix, 3);
2329 expect(InvalidParameter, stat);
2330
2331 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeCount,
2332 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2333 expect(InvalidParameter, stat);
2334
2335 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeAny,
2336 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2337 expect(InvalidParameter, stat);
2338
2339 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2340 FALSE, NULL, NULL, ColorMatrixFlagsDefault);
2341 expect(Ok, stat);
2342
2343 /* Drawing a bitmap transforms the colors */
2344 colormatrix = double_red;
2345 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2346 TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2347 expect(Ok, stat);
2348
2349 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB, NULL, &bitmap1);
2350 expect(Ok, stat);
2351
2352 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB, NULL, &bitmap2);
2353 expect(Ok, stat);
2354
2355 stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff40ccee);
2356 expect(Ok, stat);
2357
2358 stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
2359 expect(Ok, stat);
2360
2361 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2362 UnitPixel, imageattr, NULL, NULL);
2363 expect(Ok, stat);
2364
2365 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2366 expect(Ok, stat);
2367 expect(0xff80ccee, color);
2368
2369 colormatrix = asymmetric;
2370 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2371 TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2372 expect(Ok, stat);
2373
2374 stat = GdipBitmapSetPixel(bitmap2, 0, 0, 0);
2375 expect(Ok, stat);
2376
2377 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2378 UnitPixel, imageattr, NULL, NULL);
2379 expect(Ok, stat);
2380
2381 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2382 expect(Ok, stat);
2383 ok(color_match(0xeeff40cc, color, 3), "expected 0xeeff40cc, got 0x%08x\n", color);
2384
2385 /* Toggle NoOp */
2386 stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeDefault, FALSE);
2387 expect(Ok, stat);
2388
2389 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2390 UnitPixel, imageattr, NULL, NULL);
2391 expect(Ok, stat);
2392
2393 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2394 expect(Ok, stat);
2395 ok(color_match(0xfefe40cc, color, 3), "expected 0xfefe40cc, got 0x%08x\n", color);
2396
2397 stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeDefault, TRUE);
2398 expect(Ok, stat);
2399
2400 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2401 UnitPixel, imageattr, NULL, NULL);
2402 expect(Ok, stat);
2403
2404 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2405 expect(Ok, stat);
2406 ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color);
2407
2408 stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeDefault);
2409 expect(Ok, stat);
2410
2411 stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeDefault, FALSE);
2412 expect(Ok, stat);
2413
2414 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2415 UnitPixel, imageattr, NULL, NULL);
2416 expect(Ok, stat);
2417
2418 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2419 expect(Ok, stat);
2420 ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color);
2421
2422 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2423 UnitPixel, imageattr, NULL, NULL);
2424 expect(Ok, stat);
2425
2426 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2427 expect(Ok, stat);
2428 ok(color_match(0xff40ccee, color, 1), "Expected ff40ccee, got %.8x\n", color);
2429
2430 /* Disable adjustment, toggle NoOp */
2431 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2432 FALSE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2433 expect(Ok, stat);
2434
2435 stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeDefault, FALSE);
2436 expect(Ok, stat);
2437
2438 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2439 UnitPixel, imageattr, NULL, NULL);
2440 expect(Ok, stat);
2441
2442 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2443 expect(Ok, stat);
2444 ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color);
2445
2446 stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeDefault, TRUE);
2447 expect(Ok, stat);
2448
2449 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2450 UnitPixel, imageattr, NULL, NULL);
2451 expect(Ok, stat);
2452
2453 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2454 expect(Ok, stat);
2455 ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color);
2456
2457 /* Reset with NoOp on, enable adjustment. */
2458 stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeDefault);
2459 expect(Ok, stat);
2460
2461 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2462 TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2463 expect(Ok, stat);
2464
2465 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2466 UnitPixel, imageattr, NULL, NULL);
2467 expect(Ok, stat);
2468
2469 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2470 expect(Ok, stat);
2471 ok(color_match(0xfff24ace, color, 3), "expected 0xfff24ace, got 0x%08x\n", color);
2472
2473 /* Now inhibit specific category. */
2474 stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeDefault);
2475 expect(Ok, stat);
2476
2477 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeBitmap,
2478 TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2479 expect(Ok, stat);
2480
2481 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2482 UnitPixel, imageattr, NULL, NULL);
2483 expect(Ok, stat);
2484
2485 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2486 expect(Ok, stat);
2487 ok(color_match(0xfffe41cc, color, 3), "expected 0xfffe41cc, got 0x%08x\n", color);
2488
2489 stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeBitmap, TRUE);
2490 expect(Ok, stat);
2491
2492 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2493 UnitPixel, imageattr, NULL, NULL);
2494 expect(Ok, stat);
2495
2496 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2497 expect(Ok, stat);
2498 ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color);
2499
2500 stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeBitmap, FALSE);
2501 expect(Ok, stat);
2502
2503 stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeDefault, TRUE);
2504 expect(Ok, stat);
2505
2506 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2507 UnitPixel, imageattr, NULL, NULL);
2508 expect(Ok, stat);
2509
2510 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2511 expect(Ok, stat);
2512 ok(color_match(0xfff24ace, color, 3), "expected 0xfff24ace, got 0x%08x\n", color);
2513
2514 stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeBitmap);
2515 expect(Ok, stat);
2516
2517 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2518 UnitPixel, imageattr, NULL, NULL);
2519 expect(Ok, stat);
2520
2521 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2522 expect(Ok, stat);
2523 ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color);
2524
2525 GdipDeleteGraphics(graphics);
2526 GdipDisposeImage((GpImage*)bitmap1);
2527 GdipDisposeImage((GpImage*)bitmap2);
2528 GdipDisposeImageAttributes(imageattr);
2529 }
2530
2531 static void test_gamma(void)
2532 {
2533 GpStatus stat;
2534 GpImageAttributes *imageattr;
2535 GpBitmap *bitmap1, *bitmap2;
2536 GpGraphics *graphics;
2537 ARGB color;
2538
2539 stat = GdipSetImageAttributesGamma(NULL, ColorAdjustTypeDefault, TRUE, 1.0);
2540 expect(InvalidParameter, stat);
2541
2542 stat = GdipCreateImageAttributes(&imageattr);
2543 expect(Ok, stat);
2544
2545 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 1.0);
2546 expect(Ok, stat);
2547
2548 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeAny, TRUE, 1.0);
2549 expect(InvalidParameter, stat);
2550
2551 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, -1.0);
2552 expect(InvalidParameter, stat);
2553
2554 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 0.0);
2555 expect(InvalidParameter, stat);
2556
2557 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 0.5);
2558 expect(Ok, stat);
2559
2560 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, FALSE, 0.0);
2561 expect(Ok, stat);
2562
2563 /* Drawing a bitmap transforms the colors */
2564 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 3.0);
2565 expect(Ok, stat);
2566
2567 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap1);
2568 expect(Ok, stat);
2569
2570 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap2);
2571 expect(Ok, stat);
2572
2573 stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff80ffff);
2574 expect(Ok, stat);
2575
2576 stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
2577 expect(Ok, stat);
2578
2579 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2580 UnitPixel, imageattr, NULL, NULL);
2581 expect(Ok, stat);
2582
2583 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2584 expect(Ok, stat);
2585 ok(color_match(0xff20ffff, color, 1), "Expected ff20ffff, got %.8x\n", color);
2586
2587 stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeDefault);
2588 expect(Ok, stat);
2589
2590 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2591 UnitPixel, imageattr, NULL, NULL);
2592 expect(Ok, stat);
2593
2594 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2595 expect(Ok, stat);
2596 ok(color_match(0xff80ffff, color, 1), "Expected ff80ffff, got %.8x\n", color);
2597
2598 GdipDeleteGraphics(graphics);
2599 GdipDisposeImage((GpImage*)bitmap1);
2600 GdipDisposeImage((GpImage*)bitmap2);
2601 GdipDisposeImageAttributes(imageattr);
2602 }
2603
2604 /* 1x1 pixel gif, 2 frames; first frame is white, second is black */
2605 static const unsigned char gifanimation[72] = {
2606 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
2607 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0xf9,0x04,0x00,0x0a,0x00,0xff,
2608 0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x4c,0x01,0x00,
2609 0x21,0xf9,0x04,0x01,0x0a,0x00,0x01,0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,
2610 0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
2611 };
2612
2613 /* Generated with ImageMagick:
2614 * convert -transparent black -delay 100 -size 8x2 xc:black \
2615 * -dispose none -page +0+0 -size 2x2 xc:red \
2616 * -dispose background -page +2+0 -size 2x2 xc:blue \
2617 * -dispose previous -page +4+0 -size 2x2 xc:green \
2618 * -dispose undefined -page +6+0 -size 2x2 xc:gray \
2619 * test.gif
2620 */
2621 static const unsigned char gifanimation2[] = {
2622 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x08, 0x00,
2623 0x02, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
2624 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x64,
2625 0x00, 0x00, 0x00, 0x21, 0xff, 0x0b, 0x4e, 0x45,
2626 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e,
2627 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00,
2628 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
2629 0x02, 0x04, 0x84, 0x8f, 0x09, 0x05, 0x00, 0x21,
2630 0xf9, 0x04, 0x04, 0x64, 0x00, 0x00, 0x00, 0x2c,
2631 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2632 0x81, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
2633 0x00, 0x00, 0xff, 0x00,