dwrite: Fix recently added script properties.
[wine.git] / dlls / gdiplus / tests / image.c
blobbe93a20afbb8799153542f6cb2089a210f9bf68c
1 /*
2 * Unit test suite for images
4 * Copyright (C) 2007 Google (Evan Stade)
5 * Copyright (C) 2012 Dmitry Timoshkov
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.
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.
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
22 #define COBJMACROS
24 #include <math.h>
25 #include <assert.h>
26 #include <stdio.h>
28 #include "initguid.h"
29 #include "objbase.h"
30 #include "gdiplus.h"
31 #include "wine/test.h"
33 #define expect(expected, got) ok((got) == (expected), "Expected %d, got %d\n", (UINT)(expected), (UINT)(got))
34 #define expectf(expected, got) ok(fabs((expected) - (got)) < 0.0001, "Expected %f, got %f\n", (expected), (got))
36 static BOOL color_match(ARGB c1, ARGB c2, BYTE max_diff)
38 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
39 c1 >>= 8; c2 >>= 8;
40 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
41 c1 >>= 8; c2 >>= 8;
42 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
43 c1 >>= 8; c2 >>= 8;
44 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
45 return TRUE;
48 static void expect_guid(REFGUID expected, REFGUID got, int line, BOOL todo)
50 WCHAR bufferW[39];
51 char buffer[39];
52 char buffer2[39];
54 StringFromGUID2(got, bufferW, sizeof(bufferW)/sizeof(bufferW[0]));
55 WideCharToMultiByte(CP_ACP, 0, bufferW, sizeof(bufferW)/sizeof(bufferW[0]), buffer, sizeof(buffer), NULL, NULL);
56 StringFromGUID2(expected, bufferW, sizeof(bufferW)/sizeof(bufferW[0]));
57 WideCharToMultiByte(CP_ACP, 0, bufferW, sizeof(bufferW)/sizeof(bufferW[0]), buffer2, sizeof(buffer2), NULL, NULL);
58 todo_wine_if (todo)
59 ok_(__FILE__, line)(IsEqualGUID(expected, got), "Expected %s, got %s\n", buffer2, buffer);
62 static void expect_rawformat(REFGUID expected, GpImage *img, int line, BOOL todo)
64 GUID raw;
65 GpStatus stat;
67 stat = GdipGetImageRawFormat(img, &raw);
68 ok_(__FILE__, line)(stat == Ok, "GdipGetImageRawFormat failed with %d\n", stat);
69 if(stat != Ok) return;
70 expect_guid(expected, &raw, line, todo);
73 static void test_bufferrawformat(void* buff, int size, REFGUID expected, int line, BOOL todo)
75 LPSTREAM stream;
76 HGLOBAL hglob;
77 LPBYTE data;
78 HRESULT hres;
79 GpStatus stat;
80 GpImage *img;
82 hglob = GlobalAlloc (0, size);
83 data = GlobalLock (hglob);
84 memcpy(data, buff, size);
85 GlobalUnlock(hglob); data = NULL;
87 hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
88 ok_(__FILE__, line)(hres == S_OK, "Failed to create a stream\n");
89 if(hres != S_OK) return;
91 stat = GdipLoadImageFromStream(stream, &img);
92 ok_(__FILE__, line)(stat == Ok, "Failed to create a Bitmap\n");
93 if(stat != Ok){
94 IStream_Release(stream);
95 return;
98 expect_rawformat(expected, img, line, todo);
100 GdipDisposeImage(img);
101 IStream_Release(stream);
104 static void test_Scan0(void)
106 GpBitmap *bm;
107 GpStatus stat;
108 BYTE buff[360];
110 bm = NULL;
111 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, NULL, &bm);
112 expect(Ok, stat);
113 ok(NULL != bm, "Expected bitmap to be initialized\n");
114 if (stat == Ok)
115 GdipDisposeImage((GpImage*)bm);
117 bm = (GpBitmap*)0xdeadbeef;
118 stat = GdipCreateBitmapFromScan0(10, -10, 10, PixelFormat24bppRGB, NULL, &bm);
119 expect(InvalidParameter, stat);
120 ok( !bm, "expected null bitmap\n" );
122 bm = (GpBitmap*)0xdeadbeef;
123 stat = GdipCreateBitmapFromScan0(-10, 10, 10, PixelFormat24bppRGB, NULL, &bm);
124 expect(InvalidParameter, stat);
125 ok( !bm, "expected null bitmap\n" );
127 bm = (GpBitmap*)0xdeadbeef;
128 stat = GdipCreateBitmapFromScan0(10, 0, 10, PixelFormat24bppRGB, NULL, &bm);
129 expect(InvalidParameter, stat);
130 ok( !bm, "expected null bitmap\n" );
132 bm = NULL;
133 stat = GdipCreateBitmapFromScan0(10, 10, 12, PixelFormat24bppRGB, buff, &bm);
134 expect(Ok, stat);
135 ok(NULL != bm, "Expected bitmap to be initialized\n");
136 if (stat == Ok)
137 GdipDisposeImage((GpImage*)bm);
139 bm = (GpBitmap*) 0xdeadbeef;
140 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, buff, &bm);
141 expect(InvalidParameter, stat);
142 ok( !bm, "expected null bitmap\n" );
144 bm = (GpBitmap*)0xdeadbeef;
145 stat = GdipCreateBitmapFromScan0(10, 10, 0, PixelFormat24bppRGB, buff, &bm);
146 expect(InvalidParameter, stat);
147 ok( bm == (GpBitmap*)0xdeadbeef, "expected deadbeef bitmap\n" );
149 bm = NULL;
150 stat = GdipCreateBitmapFromScan0(10, 10, -8, PixelFormat24bppRGB, buff, &bm);
151 expect(Ok, stat);
152 ok(NULL != bm, "Expected bitmap to be initialized\n");
153 if (stat == Ok)
154 GdipDisposeImage((GpImage*)bm);
156 bm = (GpBitmap*)0xdeadbeef;
157 stat = GdipCreateBitmapFromScan0(10, 10, -10, PixelFormat24bppRGB, buff, &bm);
158 expect(InvalidParameter, stat);
159 ok( !bm, "expected null bitmap\n" );
162 static void test_FromGdiDib(void)
164 GpBitmap *bm;
165 GpStatus stat;
166 BYTE buff[400];
167 BYTE rbmi[sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)];
168 BITMAPINFO *bmi = (BITMAPINFO*)rbmi;
169 PixelFormat format;
171 bm = NULL;
173 memset(rbmi, 0, sizeof(rbmi));
175 bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
176 bmi->bmiHeader.biWidth = 10;
177 bmi->bmiHeader.biHeight = 10;
178 bmi->bmiHeader.biPlanes = 1;
179 bmi->bmiHeader.biBitCount = 32;
180 bmi->bmiHeader.biCompression = BI_RGB;
182 stat = GdipCreateBitmapFromGdiDib(NULL, buff, &bm);
183 expect(InvalidParameter, stat);
185 stat = GdipCreateBitmapFromGdiDib(bmi, NULL, &bm);
186 expect(InvalidParameter, stat);
188 stat = GdipCreateBitmapFromGdiDib(bmi, buff, NULL);
189 expect(InvalidParameter, stat);
191 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
192 expect(Ok, stat);
193 ok(NULL != bm, "Expected bitmap to be initialized\n");
194 if (stat == Ok)
196 stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
197 expect(Ok, stat);
198 expect(PixelFormat32bppRGB, format);
200 GdipDisposeImage((GpImage*)bm);
203 bmi->bmiHeader.biBitCount = 24;
204 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
205 expect(Ok, stat);
206 ok(NULL != bm, "Expected bitmap to be initialized\n");
207 if (stat == Ok)
209 stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
210 expect(Ok, stat);
211 expect(PixelFormat24bppRGB, format);
213 GdipDisposeImage((GpImage*)bm);
216 bmi->bmiHeader.biBitCount = 16;
217 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
218 expect(Ok, stat);
219 ok(NULL != bm, "Expected bitmap to be initialized\n");
220 if (stat == Ok)
222 stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
223 expect(Ok, stat);
224 expect(PixelFormat16bppRGB555, format);
226 GdipDisposeImage((GpImage*)bm);
229 bmi->bmiHeader.biBitCount = 8;
230 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
231 expect(Ok, stat);
232 ok(NULL != bm, "Expected bitmap to be initialized\n");
233 if (stat == Ok)
235 stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
236 expect(Ok, stat);
237 expect(PixelFormat8bppIndexed, format);
239 GdipDisposeImage((GpImage*)bm);
242 bmi->bmiHeader.biBitCount = 4;
243 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
244 expect(Ok, stat);
245 ok(NULL != bm, "Expected bitmap to be initialized\n");
246 if (stat == Ok)
248 stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
249 expect(Ok, stat);
250 expect(PixelFormat4bppIndexed, format);
252 GdipDisposeImage((GpImage*)bm);
255 bmi->bmiHeader.biBitCount = 1;
256 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
257 expect(Ok, stat);
258 ok(NULL != bm, "Expected bitmap to be initialized\n");
259 if (stat == Ok)
261 stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
262 expect(Ok, stat);
263 expect(PixelFormat1bppIndexed, format);
265 GdipDisposeImage((GpImage*)bm);
268 bmi->bmiHeader.biBitCount = 0;
269 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
270 expect(InvalidParameter, stat);
273 static void test_GetImageDimension(void)
275 GpBitmap *bm;
276 GpStatus stat;
277 const REAL WIDTH = 10.0, HEIGHT = 20.0;
278 REAL w,h;
280 bm = (GpBitmap*)0xdeadbeef;
281 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB,NULL, &bm);
282 expect(Ok,stat);
283 ok((GpBitmap*)0xdeadbeef != bm, "Expected bitmap to not be 0xdeadbeef\n");
284 ok(NULL != bm, "Expected bitmap to not be NULL\n");
286 stat = GdipGetImageDimension(NULL,&w,&h);
287 expect(InvalidParameter, stat);
289 stat = GdipGetImageDimension((GpImage*)bm,NULL,&h);
290 expect(InvalidParameter, stat);
292 stat = GdipGetImageDimension((GpImage*)bm,&w,NULL);
293 expect(InvalidParameter, stat);
295 w = -1;
296 h = -1;
297 stat = GdipGetImageDimension((GpImage*)bm,&w,&h);
298 expect(Ok, stat);
299 expectf(WIDTH, w);
300 expectf(HEIGHT, h);
301 GdipDisposeImage((GpImage*)bm);
304 static void test_GdipImageGetFrameDimensionsCount(void)
306 GpBitmap *bm;
307 GpStatus stat;
308 const REAL WIDTH = 10.0, HEIGHT = 20.0;
309 UINT w;
310 GUID dimension = {0};
311 UINT count;
312 ARGB color;
314 bm = (GpBitmap*)0xdeadbeef;
315 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB,NULL, &bm);
316 expect(Ok,stat);
317 ok((GpBitmap*)0xdeadbeef != bm, "Expected bitmap to not be 0xdeadbeef\n");
318 ok(NULL != bm, "Expected bitmap to not be NULL\n");
320 stat = GdipImageGetFrameDimensionsCount(NULL,&w);
321 expect(InvalidParameter, stat);
323 stat = GdipImageGetFrameDimensionsCount((GpImage*)bm,NULL);
324 expect(InvalidParameter, stat);
326 w = -1;
327 stat = GdipImageGetFrameDimensionsCount((GpImage*)bm,&w);
328 expect(Ok, stat);
329 expect(1, w);
331 stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 1);
332 expect(Ok, stat);
333 expect_guid(&FrameDimensionPage, &dimension, __LINE__, FALSE);
335 stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 2);
336 expect(InvalidParameter, stat);
338 stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 0);
339 expect(InvalidParameter, stat);
341 stat = GdipImageGetFrameCount(NULL, &dimension, &count);
342 expect(InvalidParameter, stat);
344 /* WinXP crashes on this test */
345 if(0)
347 stat = GdipImageGetFrameCount((GpImage*)bm, &dimension, NULL);
348 expect(InvalidParameter, stat);
351 stat = GdipImageGetFrameCount((GpImage*)bm, NULL, &count);
352 expect(Ok, stat);
354 count = 12345;
355 stat = GdipImageGetFrameCount((GpImage*)bm, &dimension, &count);
356 expect(Ok, stat);
357 expect(1, count);
359 GdipBitmapSetPixel(bm, 0, 0, 0xffffffff);
361 stat = GdipImageSelectActiveFrame((GpImage*)bm, &dimension, 0);
362 expect(Ok, stat);
364 /* SelectActiveFrame has no effect on image data of memory bitmaps */
365 color = 0xdeadbeef;
366 GdipBitmapGetPixel(bm, 0, 0, &color);
367 expect(0xffffffff, color);
369 GdipDisposeImage((GpImage*)bm);
372 static void test_LoadingImages(void)
374 GpStatus stat;
375 GpBitmap *bm;
376 GpImage *img;
377 static const WCHAR nonexistentW[] = {'n','o','n','e','x','i','s','t','e','n','t',0};
379 stat = GdipCreateBitmapFromFile(0, 0);
380 expect(InvalidParameter, stat);
382 bm = (GpBitmap *)0xdeadbeef;
383 stat = GdipCreateBitmapFromFile(0, &bm);
384 expect(InvalidParameter, stat);
385 ok(bm == (GpBitmap *)0xdeadbeef, "returned %p\n", bm);
387 bm = (GpBitmap *)0xdeadbeef;
388 stat = GdipCreateBitmapFromFile(nonexistentW, &bm);
389 todo_wine expect(InvalidParameter, stat);
390 ok(!bm, "returned %p\n", bm);
392 stat = GdipLoadImageFromFile(0, 0);
393 expect(InvalidParameter, stat);
395 img = (GpImage *)0xdeadbeef;
396 stat = GdipLoadImageFromFile(0, &img);
397 expect(InvalidParameter, stat);
398 ok(img == (GpImage *)0xdeadbeef, "returned %p\n", img);
400 img = (GpImage *)0xdeadbeef;
401 stat = GdipLoadImageFromFile(nonexistentW, &img);
402 todo_wine expect(OutOfMemory, stat);
403 ok(!img, "returned %p\n", img);
405 stat = GdipLoadImageFromFileICM(0, 0);
406 expect(InvalidParameter, stat);
408 img = (GpImage *)0xdeadbeef;
409 stat = GdipLoadImageFromFileICM(0, &img);
410 expect(InvalidParameter, stat);
411 ok(img == (GpImage *)0xdeadbeef, "returned %p\n", img);
413 img = (GpImage *)0xdeadbeef;
414 stat = GdipLoadImageFromFileICM(nonexistentW, &img);
415 todo_wine expect(OutOfMemory, stat);
416 ok(!img, "returned %p\n", img);
419 static void test_SavingImages(void)
421 GpStatus stat;
422 GpBitmap *bm;
423 UINT n;
424 UINT s;
425 const REAL WIDTH = 10.0, HEIGHT = 20.0;
426 REAL w, h;
427 ImageCodecInfo *codecs;
428 static const CHAR filenameA[] = "a.bmp";
429 static const WCHAR filename[] = { 'a','.','b','m','p',0 };
431 codecs = NULL;
433 stat = GdipSaveImageToFile(0, 0, 0, 0);
434 expect(InvalidParameter, stat);
436 bm = NULL;
437 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
438 expect(Ok, stat);
439 if (!bm)
440 return;
442 /* invalid params */
443 stat = GdipSaveImageToFile((GpImage*)bm, 0, 0, 0);
444 expect(InvalidParameter, stat);
446 stat = GdipSaveImageToFile((GpImage*)bm, filename, 0, 0);
447 expect(InvalidParameter, stat);
449 /* encoder tests should succeed -- already tested */
450 stat = GdipGetImageEncodersSize(&n, &s);
451 if (stat != Ok || n == 0) goto cleanup;
453 codecs = GdipAlloc(s);
454 if (!codecs) goto cleanup;
456 stat = GdipGetImageEncoders(n, s, codecs);
457 if (stat != Ok) goto cleanup;
459 stat = GdipSaveImageToFile((GpImage*)bm, filename, &codecs[0].Clsid, 0);
460 expect(Ok, stat);
462 GdipDisposeImage((GpImage*)bm);
463 bm = 0;
465 /* re-load and check image stats */
466 stat = GdipLoadImageFromFile(filename, (GpImage**)&bm);
467 expect(Ok, stat);
468 if (stat != Ok) goto cleanup;
470 stat = GdipGetImageDimension((GpImage*)bm, &w, &h);
471 if (stat != Ok) goto cleanup;
473 expectf(WIDTH, w);
474 expectf(HEIGHT, h);
476 cleanup:
477 GdipFree(codecs);
478 if (bm)
479 GdipDisposeImage((GpImage*)bm);
480 ok(DeleteFileA(filenameA), "Delete failed.\n");
483 static void test_encoders(void)
485 GpStatus stat;
486 UINT n;
487 UINT s;
488 ImageCodecInfo *codecs;
489 int i;
490 int bmp_found;
492 static const CHAR bmp_format[] = "BMP";
494 stat = GdipGetImageEncodersSize(&n, &s);
495 expect(stat, Ok);
497 codecs = GdipAlloc(s);
498 if (!codecs)
499 return;
501 stat = GdipGetImageEncoders(n, s, NULL);
502 expect(GenericError, stat);
504 stat = GdipGetImageEncoders(0, s, codecs);
505 expect(GenericError, stat);
507 stat = GdipGetImageEncoders(n, s-1, codecs);
508 expect(GenericError, stat);
510 stat = GdipGetImageEncoders(n, s+1, codecs);
511 expect(GenericError, stat);
513 stat = GdipGetImageEncoders(n, s, codecs);
514 expect(stat, Ok);
516 bmp_found = FALSE;
517 for (i = 0; i < n; i++)
519 CHAR desc[32];
521 WideCharToMultiByte(CP_ACP, 0, codecs[i].FormatDescription, -1,
522 desc, 32, 0, 0);
524 if (CompareStringA(LOCALE_SYSTEM_DEFAULT, 0,
525 desc, -1,
526 bmp_format, -1) == CSTR_EQUAL) {
527 bmp_found = TRUE;
528 break;
531 if (!bmp_found)
532 ok(FALSE, "No BMP codec found.\n");
534 GdipFree(codecs);
537 static void test_LockBits(void)
539 GpStatus stat;
540 GpBitmap *bm;
541 GpRect rect;
542 BitmapData bd;
543 const INT WIDTH = 10, HEIGHT = 20;
544 ARGB color;
545 int y;
547 bm = NULL;
548 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
549 expect(Ok, stat);
551 rect.X = 2;
552 rect.Y = 3;
553 rect.Width = 4;
554 rect.Height = 5;
556 stat = GdipBitmapSetPixel(bm, 2, 3, 0xffc30000);
557 expect(Ok, stat);
559 stat = GdipBitmapSetPixel(bm, 2, 8, 0xff480000);
560 expect(Ok, stat);
562 /* read-only */
563 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
564 expect(Ok, stat);
566 if (stat == Ok) {
567 expect(0xc3, ((BYTE*)bd.Scan0)[2]);
568 expect(0x48, ((BYTE*)bd.Scan0)[2 + bd.Stride * 5]);
570 ((char*)bd.Scan0)[2] = 0xff;
572 stat = GdipBitmapUnlockBits(bm, &bd);
573 expect(Ok, stat);
576 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
577 expect(Ok, stat);
578 expect(0xffff0000, color);
580 stat = GdipBitmapSetPixel(bm, 2, 3, 0xffc30000);
581 expect(Ok, stat);
583 /* read-only, with NULL rect -> whole bitmap lock */
584 stat = GdipBitmapLockBits(bm, NULL, ImageLockModeRead, PixelFormat24bppRGB, &bd);
585 expect(Ok, stat);
586 expect(bd.Width, WIDTH);
587 expect(bd.Height, HEIGHT);
589 if (stat == Ok) {
590 ((char*)bd.Scan0)[2 + 2*3 + 3*bd.Stride] = 0xff;
592 stat = GdipBitmapUnlockBits(bm, &bd);
593 expect(Ok, stat);
596 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
597 expect(Ok, stat);
598 expect(0xffff0000, color);
600 /* read-only, consecutive */
601 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
602 expect(Ok, stat);
604 if (stat == Ok) {
605 stat = GdipBitmapUnlockBits(bm, &bd);
606 expect(Ok, stat);
609 stat = GdipDisposeImage((GpImage*)bm);
610 expect(Ok, stat);
611 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
612 expect(Ok, stat);
614 /* read x2 */
615 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
616 expect(Ok, stat);
617 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
618 expect(WrongState, stat);
620 stat = GdipBitmapUnlockBits(bm, &bd);
621 expect(Ok, stat);
623 stat = GdipDisposeImage((GpImage*)bm);
624 expect(Ok, stat);
625 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
626 expect(Ok, stat);
628 stat = GdipBitmapSetPixel(bm, 2, 3, 0xffff0000);
629 expect(Ok, stat);
631 stat = GdipBitmapSetPixel(bm, 2, 8, 0xffc30000);
632 expect(Ok, stat);
634 /* write, no conversion */
635 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
636 expect(Ok, stat);
638 if (stat == Ok) {
639 /* all bits are readable, inside the rect or not */
640 expect(0xff, ((BYTE*)bd.Scan0)[2]);
641 expect(0xc3, ((BYTE*)bd.Scan0)[2 + bd.Stride * 5]);
643 stat = GdipBitmapUnlockBits(bm, &bd);
644 expect(Ok, stat);
647 /* read, conversion */
648 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat32bppARGB, &bd);
649 expect(Ok, stat);
651 if (stat == Ok) {
652 expect(0xff, ((BYTE*)bd.Scan0)[2]);
653 if (0)
654 /* Areas outside the rectangle appear to be uninitialized */
655 ok(0xc3 != ((BYTE*)bd.Scan0)[2 + bd.Stride * 5], "original image bits are readable\n");
657 ((BYTE*)bd.Scan0)[2] = 0xc3;
659 stat = GdipBitmapUnlockBits(bm, &bd);
660 expect(Ok, stat);
663 /* writes do not work in read mode if there was a conversion */
664 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
665 expect(Ok, stat);
666 expect(0xffff0000, color);
668 /* read/write, conversion */
669 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead|ImageLockModeWrite, PixelFormat32bppARGB, &bd);
670 expect(Ok, stat);
672 if (stat == Ok) {
673 expect(0xff, ((BYTE*)bd.Scan0)[2]);
674 ((BYTE*)bd.Scan0)[1] = 0x88;
675 if (0)
676 /* Areas outside the rectangle appear to be uninitialized */
677 ok(0xc3 != ((BYTE*)bd.Scan0)[2 + bd.Stride * 5], "original image bits are readable\n");
679 stat = GdipBitmapUnlockBits(bm, &bd);
680 expect(Ok, stat);
683 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
684 expect(Ok, stat);
685 expect(0xffff8800, color);
687 /* write, conversion */
688 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat32bppARGB, &bd);
689 expect(Ok, stat);
691 if (stat == Ok) {
692 if (0)
694 /* This is completely uninitialized. */
695 ok(0xff != ((BYTE*)bd.Scan0)[2], "original image bits are readable\n");
696 ok(0xc3 != ((BYTE*)bd.Scan0)[2 + bd.Stride * 5], "original image bits are readable\n");
699 /* Initialize the buffer so the unlock doesn't access undefined memory */
700 for (y=0; y<5; y++)
701 memset(((BYTE*)bd.Scan0) + bd.Stride * y, 0, 12);
703 ((BYTE*)bd.Scan0)[0] = 0x12;
704 ((BYTE*)bd.Scan0)[1] = 0x34;
705 ((BYTE*)bd.Scan0)[2] = 0x56;
707 stat = GdipBitmapUnlockBits(bm, &bd);
708 expect(Ok, stat);
711 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
712 expect(Ok, stat);
713 expect(0xff563412, color);
715 stat = GdipBitmapGetPixel(bm, 2, 8, &color);
716 expect(Ok, stat);
717 expect(0xffc30000, color);
719 stat = GdipDisposeImage((GpImage*)bm);
720 expect(Ok, stat);
721 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
722 expect(Ok, stat);
724 /* write, no modification */
725 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
726 expect(Ok, stat);
728 if (stat == Ok) {
729 stat = GdipBitmapUnlockBits(bm, &bd);
730 expect(Ok, stat);
733 /* write, consecutive */
734 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
735 expect(Ok, stat);
737 if (stat == Ok) {
738 stat = GdipBitmapUnlockBits(bm, &bd);
739 expect(Ok, stat);
742 stat = GdipDisposeImage((GpImage*)bm);
743 expect(Ok, stat);
744 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
745 expect(Ok, stat);
747 /* write, modify */
748 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
749 expect(Ok, stat);
751 if (stat == Ok) {
752 if (bd.Scan0)
753 ((char*)bd.Scan0)[2] = 0xff;
755 stat = GdipBitmapUnlockBits(bm, &bd);
756 expect(Ok, stat);
759 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
760 expect(Ok, stat);
761 expect(0xffff0000, color);
763 stat = GdipDisposeImage((GpImage*)bm);
764 expect(Ok, stat);
766 /* dispose locked */
767 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
768 expect(Ok, stat);
769 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
770 expect(Ok, stat);
771 stat = GdipDisposeImage((GpImage*)bm);
772 expect(Ok, stat);
775 static void test_LockBits_UserBuf(void)
777 GpStatus stat;
778 GpBitmap *bm;
779 GpRect rect;
780 BitmapData bd;
781 const INT WIDTH = 10, HEIGHT = 20;
782 DWORD bits[200];
783 ARGB color;
785 bm = NULL;
786 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat32bppARGB, NULL, &bm);
787 expect(Ok, stat);
789 memset(bits, 0xaa, sizeof(bits));
791 rect.X = 2;
792 rect.Y = 3;
793 rect.Width = 4;
794 rect.Height = 5;
796 bd.Width = 4;
797 bd.Height = 6;
798 bd.Stride = WIDTH * 4;
799 bd.PixelFormat = PixelFormat32bppARGB;
800 bd.Scan0 = &bits[2+3*WIDTH];
801 bd.Reserved = 0xaaaaaaaa;
803 /* read-only */
804 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead|ImageLockModeUserInputBuf, PixelFormat32bppARGB, &bd);
805 expect(Ok, stat);
807 expect(0xaaaaaaaa, bits[0]);
808 expect(0, bits[2+3*WIDTH]);
810 bits[2+3*WIDTH] = 0xdeadbeef;
812 if (stat == Ok) {
813 stat = GdipBitmapUnlockBits(bm, &bd);
814 expect(Ok, stat);
817 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
818 expect(Ok, stat);
819 expect(0, color);
821 /* write-only */
822 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite|ImageLockModeUserInputBuf, PixelFormat32bppARGB, &bd);
823 expect(Ok, stat);
825 expect(0xdeadbeef, bits[2+3*WIDTH]);
826 bits[2+3*WIDTH] = 0x12345678;
828 if (stat == Ok) {
829 stat = GdipBitmapUnlockBits(bm, &bd);
830 expect(Ok, stat);
833 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
834 expect(Ok, stat);
835 expect(0x12345678, color);
837 bits[2+3*WIDTH] = 0;
839 /* read/write */
840 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead|ImageLockModeWrite|ImageLockModeUserInputBuf, PixelFormat32bppARGB, &bd);
841 expect(Ok, stat);
843 expect(0x12345678, bits[2+3*WIDTH]);
844 bits[2+3*WIDTH] = 0xdeadbeef;
846 if (stat == Ok) {
847 stat = GdipBitmapUnlockBits(bm, &bd);
848 expect(Ok, stat);
851 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
852 expect(Ok, stat);
853 expect(0xdeadbeef, color);
855 stat = GdipDisposeImage((GpImage*)bm);
856 expect(Ok, stat);
859 struct BITMAPINFOWITHBITFIELDS
861 BITMAPINFOHEADER bmiHeader;
862 DWORD masks[3];
865 union BITMAPINFOUNION
867 BITMAPINFO bi;
868 struct BITMAPINFOWITHBITFIELDS bf;
871 static void test_GdipCreateBitmapFromHBITMAP(void)
873 GpBitmap* gpbm = NULL;
874 HBITMAP hbm = NULL;
875 HPALETTE hpal = NULL;
876 GpStatus stat;
877 BYTE buff[1000];
878 LOGPALETTE* LogPal = NULL;
879 REAL width, height;
880 const REAL WIDTH1 = 5;
881 const REAL HEIGHT1 = 15;
882 const REAL WIDTH2 = 10;
883 const REAL HEIGHT2 = 20;
884 HDC hdc;
885 union BITMAPINFOUNION bmi;
886 BYTE *bits;
887 PixelFormat format;
889 stat = GdipCreateBitmapFromHBITMAP(NULL, NULL, NULL);
890 expect(InvalidParameter, stat);
892 hbm = CreateBitmap(WIDTH1, HEIGHT1, 1, 1, NULL);
893 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, NULL);
894 expect(InvalidParameter, stat);
896 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
897 expect(Ok, stat);
898 expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
899 expectf(WIDTH1, width);
900 expectf(HEIGHT1, height);
901 if (stat == Ok)
902 GdipDisposeImage((GpImage*)gpbm);
903 DeleteObject(hbm);
905 memset(buff, 0, sizeof(buff));
906 hbm = CreateBitmap(WIDTH2, HEIGHT2, 1, 1, &buff);
907 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
908 expect(Ok, stat);
909 /* raw format */
910 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)gpbm, __LINE__, FALSE);
912 expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
913 expectf(WIDTH2, width);
914 expectf(HEIGHT2, height);
915 if (stat == Ok)
916 GdipDisposeImage((GpImage*)gpbm);
917 DeleteObject(hbm);
919 hdc = CreateCompatibleDC(0);
920 ok(hdc != NULL, "CreateCompatibleDC failed\n");
921 bmi.bi.bmiHeader.biSize = sizeof(bmi.bi.bmiHeader);
922 bmi.bi.bmiHeader.biHeight = HEIGHT1;
923 bmi.bi.bmiHeader.biWidth = WIDTH1;
924 bmi.bi.bmiHeader.biBitCount = 24;
925 bmi.bi.bmiHeader.biPlanes = 1;
926 bmi.bi.bmiHeader.biCompression = BI_RGB;
927 bmi.bi.bmiHeader.biClrUsed = 0;
929 hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
930 ok(hbm != NULL, "CreateDIBSection failed\n");
932 bits[0] = 0;
934 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
935 expect(Ok, stat);
936 expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
937 expectf(WIDTH1, width);
938 expectf(HEIGHT1, height);
939 if (stat == Ok)
941 /* test whether writing to the bitmap affects the original */
942 stat = GdipBitmapSetPixel(gpbm, 0, 0, 0xffffffff);
943 expect(Ok, stat);
945 expect(0, bits[0]);
947 GdipDisposeImage((GpImage*)gpbm);
950 LogPal = GdipAlloc(sizeof(LOGPALETTE));
951 ok(LogPal != NULL, "unable to allocate LOGPALETTE\n");
952 LogPal->palVersion = 0x300;
953 LogPal->palNumEntries = 1;
954 hpal = CreatePalette(LogPal);
955 ok(hpal != NULL, "CreatePalette failed\n");
956 GdipFree(LogPal);
958 stat = GdipCreateBitmapFromHBITMAP(hbm, hpal, &gpbm);
959 expect(Ok, stat);
961 if (stat == Ok)
962 GdipDisposeImage((GpImage*)gpbm);
964 DeleteObject(hpal);
965 DeleteObject(hbm);
967 /* 16-bit 555 dib, rgb */
968 bmi.bi.bmiHeader.biBitCount = 16;
969 bmi.bi.bmiHeader.biCompression = BI_RGB;
971 hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
972 ok(hbm != NULL, "CreateDIBSection failed\n");
974 bits[0] = 0;
976 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
977 expect(Ok, stat);
979 if (stat == Ok)
981 stat = GdipGetImageDimension((GpImage*) gpbm, &width, &height);
982 expect(Ok, stat);
983 expectf(WIDTH1, width);
984 expectf(HEIGHT1, height);
986 stat = GdipGetImagePixelFormat((GpImage*) gpbm, &format);
987 expect(Ok, stat);
988 expect(PixelFormat16bppRGB555, format);
990 GdipDisposeImage((GpImage*)gpbm);
992 DeleteObject(hbm);
994 /* 16-bit 555 dib, with bitfields */
995 bmi.bi.bmiHeader.biSize = sizeof(bmi);
996 bmi.bi.bmiHeader.biCompression = BI_BITFIELDS;
997 bmi.bf.masks[0] = 0x7c00;
998 bmi.bf.masks[1] = 0x3e0;
999 bmi.bf.masks[2] = 0x1f;
1001 hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1002 ok(hbm != NULL, "CreateDIBSection failed\n");
1004 bits[0] = 0;
1006 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
1007 expect(Ok, stat);
1009 if (stat == Ok)
1011 stat = GdipGetImageDimension((GpImage*) gpbm, &width, &height);
1012 expect(Ok, stat);
1013 expectf(WIDTH1, width);
1014 expectf(HEIGHT1, height);
1016 stat = GdipGetImagePixelFormat((GpImage*) gpbm, &format);
1017 expect(Ok, stat);
1018 expect(PixelFormat16bppRGB555, format);
1020 GdipDisposeImage((GpImage*)gpbm);
1022 DeleteObject(hbm);
1024 /* 16-bit 565 dib, with bitfields */
1025 bmi.bf.masks[0] = 0xf800;
1026 bmi.bf.masks[1] = 0x7e0;
1027 bmi.bf.masks[2] = 0x1f;
1029 hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1030 ok(hbm != NULL, "CreateDIBSection failed\n");
1032 bits[0] = 0;
1034 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
1035 expect(Ok, stat);
1037 if (stat == Ok)
1039 stat = GdipGetImageDimension((GpImage*) gpbm, &width, &height);
1040 expect(Ok, stat);
1041 expectf(WIDTH1, width);
1042 expectf(HEIGHT1, height);
1044 stat = GdipGetImagePixelFormat((GpImage*) gpbm, &format);
1045 expect(Ok, stat);
1046 expect(PixelFormat16bppRGB565, format);
1048 GdipDisposeImage((GpImage*)gpbm);
1050 DeleteObject(hbm);
1052 DeleteDC(hdc);
1055 static void test_GdipGetImageFlags(void)
1057 GpImage *img;
1058 GpStatus stat;
1059 UINT flags;
1061 img = (GpImage*)0xdeadbeef;
1063 stat = GdipGetImageFlags(NULL, NULL);
1064 expect(InvalidParameter, stat);
1066 stat = GdipGetImageFlags(NULL, &flags);
1067 expect(InvalidParameter, stat);
1069 stat = GdipGetImageFlags(img, NULL);
1070 expect(InvalidParameter, stat);
1072 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat1bppIndexed, NULL, (GpBitmap**)&img);
1073 expect(Ok, stat);
1074 stat = GdipGetImageFlags(img, &flags);
1075 expect(Ok, stat);
1076 expect(ImageFlagsHasAlpha, flags);
1077 GdipDisposeImage(img);
1079 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat4bppIndexed, NULL, (GpBitmap**)&img);
1080 expect(Ok, stat);
1081 stat = GdipGetImageFlags(img, &flags);
1082 expect(Ok, stat);
1083 expect(ImageFlagsHasAlpha, flags);
1084 GdipDisposeImage(img);
1086 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat8bppIndexed, NULL, (GpBitmap**)&img);
1087 expect(Ok, stat);
1088 stat = GdipGetImageFlags(img, &flags);
1089 expect(Ok, stat);
1090 expect(ImageFlagsHasAlpha, flags);
1091 GdipDisposeImage(img);
1093 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppGrayScale, NULL, (GpBitmap**)&img);
1094 expect(Ok, stat);
1095 stat = GdipGetImageFlags(img, &flags);
1096 expect(Ok, stat);
1097 expect(ImageFlagsNone, flags);
1098 GdipDisposeImage(img);
1100 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB555, NULL, (GpBitmap**)&img);
1101 expect(Ok, stat);
1102 stat = GdipGetImageFlags(img, &flags);
1103 expect(Ok, stat);
1104 expect(ImageFlagsNone, flags);
1105 GdipDisposeImage(img);
1107 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB565, NULL, (GpBitmap**)&img);
1108 expect(Ok, stat);
1109 stat = GdipGetImageFlags(img, &flags);
1110 expect(Ok, stat);
1111 expect(ImageFlagsNone, flags);
1112 GdipDisposeImage(img);
1114 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppARGB1555, NULL, (GpBitmap**)&img);
1115 expect(Ok, stat);
1116 stat = GdipGetImageFlags(img, &flags);
1117 expect(Ok, stat);
1118 expect(ImageFlagsHasAlpha, flags);
1119 GdipDisposeImage(img);
1121 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, NULL, (GpBitmap**)&img);
1122 expect(Ok, stat);
1123 stat = GdipGetImageFlags(img, &flags);
1124 expect(Ok, stat);
1125 expect(ImageFlagsNone, flags);
1126 GdipDisposeImage(img);
1128 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppRGB, NULL, (GpBitmap**)&img);
1129 expect(Ok, stat);
1130 stat = GdipGetImageFlags(img, &flags);
1131 expect(Ok, stat);
1132 expect(ImageFlagsNone, flags);
1133 GdipDisposeImage(img);
1135 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppARGB, NULL, (GpBitmap**)&img);
1136 expect(Ok, stat);
1137 stat = GdipGetImageFlags(img, &flags);
1138 expect(Ok, stat);
1139 expect(ImageFlagsHasAlpha, flags);
1140 GdipDisposeImage(img);
1142 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppPARGB, NULL, (GpBitmap**)&img);
1143 expect(Ok, stat);
1144 stat = GdipGetImageFlags(img, &flags);
1145 expect(Ok, stat);
1146 expect(ImageFlagsHasAlpha, flags);
1147 GdipDisposeImage(img);
1149 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat48bppRGB, NULL, (GpBitmap**)&img);
1150 expect(Ok, stat);
1151 if (stat == Ok)
1153 stat = GdipGetImageFlags(img, &flags);
1154 expect(Ok, stat);
1155 expect(ImageFlagsNone, flags);
1156 GdipDisposeImage(img);
1159 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB, NULL, (GpBitmap**)&img);
1160 expect(Ok, stat);
1161 if (stat == Ok)
1163 expect(Ok, stat);
1164 stat = GdipGetImageFlags(img, &flags);
1165 expect(Ok, stat);
1166 expect(ImageFlagsHasAlpha, flags);
1167 GdipDisposeImage(img);
1170 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB, NULL, (GpBitmap**)&img);
1171 expect(Ok, stat);
1172 if (stat == Ok)
1174 expect(Ok, stat);
1175 stat = GdipGetImageFlags(img, &flags);
1176 expect(Ok, stat);
1177 expect(ImageFlagsHasAlpha, flags);
1178 GdipDisposeImage(img);
1182 static void test_GdipCloneImage(void)
1184 GpStatus stat;
1185 GpRectF rectF;
1186 GpUnit unit;
1187 GpBitmap *bm;
1188 GpImage *image_src, *image_dest = NULL;
1189 const INT WIDTH = 10, HEIGHT = 20;
1191 /* Create an image, clone it, delete the original, make sure the copy works */
1192 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
1193 expect(Ok, stat);
1194 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bm, __LINE__, FALSE);
1196 image_src = ((GpImage*)bm);
1197 stat = GdipCloneImage(image_src, &image_dest);
1198 expect(Ok, stat);
1199 expect_rawformat(&ImageFormatMemoryBMP, image_dest, __LINE__, FALSE);
1201 stat = GdipDisposeImage((GpImage*)bm);
1202 expect(Ok, stat);
1203 stat = GdipGetImageBounds(image_dest, &rectF, &unit);
1204 expect(Ok, stat);
1206 /* Treat FP values carefully */
1207 expectf((REAL)WIDTH, rectF.Width);
1208 expectf((REAL)HEIGHT, rectF.Height);
1210 stat = GdipDisposeImage(image_dest);
1211 expect(Ok, stat);
1214 static void test_testcontrol(void)
1216 GpStatus stat;
1217 DWORD param;
1219 param = 0;
1220 stat = GdipTestControl(TestControlGetBuildNumber, &param);
1221 expect(Ok, stat);
1222 ok(param != 0, "Build number expected, got %u\n", param);
1225 static void test_fromhicon(void)
1227 static const BYTE bmp_bits[1024];
1228 HBITMAP hbmMask, hbmColor;
1229 ICONINFO info;
1230 HICON hIcon;
1231 GpStatus stat;
1232 GpBitmap *bitmap = NULL;
1233 UINT dim;
1234 ImageType type;
1235 PixelFormat format;
1237 /* NULL */
1238 stat = GdipCreateBitmapFromHICON(NULL, NULL);
1239 expect(InvalidParameter, stat);
1240 stat = GdipCreateBitmapFromHICON(NULL, &bitmap);
1241 expect(InvalidParameter, stat);
1243 /* color icon 1 bit */
1244 hbmMask = CreateBitmap(16, 16, 1, 1, bmp_bits);
1245 ok(hbmMask != 0, "CreateBitmap failed\n");
1246 hbmColor = CreateBitmap(16, 16, 1, 1, bmp_bits);
1247 ok(hbmColor != 0, "CreateBitmap failed\n");
1248 info.fIcon = TRUE;
1249 info.xHotspot = 8;
1250 info.yHotspot = 8;
1251 info.hbmMask = hbmMask;
1252 info.hbmColor = hbmColor;
1253 hIcon = CreateIconIndirect(&info);
1254 ok(hIcon != 0, "CreateIconIndirect failed\n");
1255 DeleteObject(hbmMask);
1256 DeleteObject(hbmColor);
1258 stat = GdipCreateBitmapFromHICON(hIcon, &bitmap);
1259 ok(stat == Ok ||
1260 broken(stat == InvalidParameter), /* Win98 */
1261 "Expected Ok, got %.8x\n", stat);
1262 if(stat == Ok){
1263 /* check attributes */
1264 stat = GdipGetImageHeight((GpImage*)bitmap, &dim);
1265 expect(Ok, stat);
1266 expect(16, dim);
1267 stat = GdipGetImageWidth((GpImage*)bitmap, &dim);
1268 expect(Ok, stat);
1269 expect(16, dim);
1270 stat = GdipGetImageType((GpImage*)bitmap, &type);
1271 expect(Ok, stat);
1272 expect(ImageTypeBitmap, type);
1273 stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format);
1274 expect(Ok, stat);
1275 expect(PixelFormat32bppARGB, format);
1276 /* raw format */
1277 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
1278 GdipDisposeImage((GpImage*)bitmap);
1280 DestroyIcon(hIcon);
1282 /* color icon 8 bpp */
1283 hbmMask = CreateBitmap(16, 16, 1, 8, bmp_bits);
1284 ok(hbmMask != 0, "CreateBitmap failed\n");
1285 hbmColor = CreateBitmap(16, 16, 1, 8, bmp_bits);
1286 ok(hbmColor != 0, "CreateBitmap failed\n");
1287 info.fIcon = TRUE;
1288 info.xHotspot = 8;
1289 info.yHotspot = 8;
1290 info.hbmMask = hbmMask;
1291 info.hbmColor = hbmColor;
1292 hIcon = CreateIconIndirect(&info);
1293 ok(hIcon != 0, "CreateIconIndirect failed\n");
1294 DeleteObject(hbmMask);
1295 DeleteObject(hbmColor);
1297 stat = GdipCreateBitmapFromHICON(hIcon, &bitmap);
1298 expect(Ok, stat);
1299 if(stat == Ok){
1300 /* check attributes */
1301 stat = GdipGetImageHeight((GpImage*)bitmap, &dim);
1302 expect(Ok, stat);
1303 expect(16, dim);
1304 stat = GdipGetImageWidth((GpImage*)bitmap, &dim);
1305 expect(Ok, stat);
1306 expect(16, dim);
1307 stat = GdipGetImageType((GpImage*)bitmap, &type);
1308 expect(Ok, stat);
1309 expect(ImageTypeBitmap, type);
1310 stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format);
1311 expect(Ok, stat);
1312 expect(PixelFormat32bppARGB, format);
1313 /* raw format */
1314 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
1315 GdipDisposeImage((GpImage*)bitmap);
1317 DestroyIcon(hIcon);
1320 /* 1x1 pixel png */
1321 static const unsigned char pngimage[285] = {
1322 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
1323 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
1324 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
1325 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
1326 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
1327 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
1328 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
1330 /* 1x1 pixel gif */
1331 static const unsigned char gifimage[35] = {
1332 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
1333 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
1334 0x01,0x00,0x3b
1336 /* 1x1 pixel transparent gif */
1337 static const unsigned char transparentgif[] = {
1338 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,
1339 0x00,0x00,0x00,0x21,0xf9,0x04,0x01,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,
1340 0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
1342 /* 1x1 pixel bmp */
1343 static const unsigned char bmpimage[66] = {
1344 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
1345 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
1346 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
1347 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
1348 0x00,0x00
1350 /* 1x1 pixel jpg */
1351 static const unsigned char jpgimage[285] = {
1352 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
1353 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
1354 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
1355 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
1356 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
1357 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
1358 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
1359 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1360 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1361 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
1362 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
1363 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1364 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
1365 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
1366 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1367 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
1368 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
1369 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
1371 /* 1x1 pixel tiff */
1372 static const unsigned char tiffimage[] = {
1373 0x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00,
1374 0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00,
1375 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1376 0x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01,
1377 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00,
1378 0x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00,
1379 0x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01,
1380 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00,
1381 0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00,
1382 0x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01,
1383 0x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00,
1384 0x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1385 0x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
1386 0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65,
1387 0x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74,
1388 0x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,
1389 0x00,0x00,0x00,0x01
1391 /* 320x320 twip wmf */
1392 static const unsigned char wmfimage[180] = {
1393 0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05,
1394 0x00,0x00,0x00,0x00,0xb1,0x52,0x01,0x00,0x09,0x00,0x00,0x03,0x4f,0x00,0x00,0x00,
1395 0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0b,0x02,0x00,0x00,
1396 0x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x02,0x40,0x01,0x40,0x01,0x04,0x00,0x00,0x00,
1397 0x02,0x01,0x01,0x00,0x04,0x00,0x00,0x00,0x04,0x01,0x0d,0x00,0x08,0x00,0x00,0x00,
1398 0xfa,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
1399 0x2d,0x01,0x00,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,0x01,0x00,0x00,0x00,0x00,0x00,
1400 0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x01,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,
1401 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x02,0x00,
1402 0x07,0x00,0x00,0x00,0x1b,0x04,0x40,0x01,0x40,0x01,0x00,0x00,0x00,0x00,0x04,0x00,
1403 0x00,0x00,0xf0,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0xf0,0x01,0x01,0x00,0x03,0x00,
1404 0x00,0x00,0x00,0x00
1406 static void test_getrawformat(void)
1408 test_bufferrawformat((void*)pngimage, sizeof(pngimage), &ImageFormatPNG, __LINE__, FALSE);
1409 test_bufferrawformat((void*)gifimage, sizeof(gifimage), &ImageFormatGIF, __LINE__, FALSE);
1410 test_bufferrawformat((void*)bmpimage, sizeof(bmpimage), &ImageFormatBMP, __LINE__, FALSE);
1411 test_bufferrawformat((void*)jpgimage, sizeof(jpgimage), &ImageFormatJPEG, __LINE__, FALSE);
1412 test_bufferrawformat((void*)tiffimage, sizeof(tiffimage), &ImageFormatTIFF, __LINE__, FALSE);
1413 test_bufferrawformat((void*)wmfimage, sizeof(wmfimage), &ImageFormatWMF, __LINE__, FALSE);
1416 static void test_loadwmf(void)
1418 LPSTREAM stream;
1419 HGLOBAL hglob;
1420 LPBYTE data;
1421 HRESULT hres;
1422 GpStatus stat;
1423 GpImage *img;
1424 GpRectF bounds;
1425 GpUnit unit;
1426 REAL res = 12345.0;
1427 MetafileHeader header;
1429 hglob = GlobalAlloc (0, sizeof(wmfimage));
1430 data = GlobalLock (hglob);
1431 memcpy(data, wmfimage, sizeof(wmfimage));
1432 GlobalUnlock(hglob); data = NULL;
1434 hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
1435 ok(hres == S_OK, "Failed to create a stream\n");
1436 if(hres != S_OK) return;
1438 stat = GdipLoadImageFromStream(stream, &img);
1439 ok(stat == Ok, "Failed to create a Bitmap\n");
1440 if(stat != Ok){
1441 IStream_Release(stream);
1442 return;
1445 IStream_Release(stream);
1447 stat = GdipGetImageBounds(img, &bounds, &unit);
1448 expect(Ok, stat);
1449 todo_wine expect(UnitPixel, unit);
1450 expectf(0.0, bounds.X);
1451 expectf(0.0, bounds.Y);
1452 todo_wine expectf(320.0, bounds.Width);
1453 todo_wine expectf(320.0, bounds.Height);
1455 stat = GdipGetImageHorizontalResolution(img, &res);
1456 expect(Ok, stat);
1457 todo_wine expectf(1440.0, res);
1459 stat = GdipGetImageVerticalResolution(img, &res);
1460 expect(Ok, stat);
1461 todo_wine expectf(1440.0, res);
1463 memset(&header, 0, sizeof(header));
1464 stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header);
1465 expect(Ok, stat);
1466 if (stat == Ok)
1468 todo_wine expect(MetafileTypeWmfPlaceable, header.Type);
1469 todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size);
1470 todo_wine expect(0x300, header.Version);
1471 expect(0, header.EmfPlusFlags);
1472 todo_wine expectf(1440.0, header.DpiX);
1473 todo_wine expectf(1440.0, header.DpiY);
1474 expect(0, header.X);
1475 expect(0, header.Y);
1476 todo_wine expect(320, header.Width);
1477 todo_wine expect(320, header.Height);
1478 todo_wine expect(1, U(header).WmfHeader.mtType);
1479 expect(0, header.EmfPlusHeaderSize);
1480 expect(0, header.LogicalDpiX);
1481 expect(0, header.LogicalDpiY);
1484 GdipDisposeImage(img);
1487 static void test_createfromwmf(void)
1489 HMETAFILE hwmf;
1490 GpImage *img;
1491 GpStatus stat;
1492 GpRectF bounds;
1493 GpUnit unit;
1494 REAL res = 12345.0;
1495 MetafileHeader header;
1497 hwmf = SetMetaFileBitsEx(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader),
1498 wmfimage+sizeof(WmfPlaceableFileHeader));
1499 ok(hwmf != 0, "SetMetaFileBitsEx failed\n");
1501 stat = GdipCreateMetafileFromWmf(hwmf, TRUE,
1502 (WmfPlaceableFileHeader*)wmfimage, (GpMetafile**)&img);
1503 expect(Ok, stat);
1505 stat = GdipGetImageBounds(img, &bounds, &unit);
1506 expect(Ok, stat);
1507 expect(UnitPixel, unit);
1508 expectf(0.0, bounds.X);
1509 expectf(0.0, bounds.Y);
1510 expectf(320.0, bounds.Width);
1511 expectf(320.0, bounds.Height);
1513 stat = GdipGetImageHorizontalResolution(img, &res);
1514 expect(Ok, stat);
1515 expectf(1440.0, res);
1517 stat = GdipGetImageVerticalResolution(img, &res);
1518 expect(Ok, stat);
1519 expectf(1440.0, res);
1521 memset(&header, 0, sizeof(header));
1522 stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header);
1523 expect(Ok, stat);
1524 if (stat == Ok)
1526 todo_wine expect(MetafileTypeWmfPlaceable, header.Type);
1527 todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size);
1528 todo_wine expect(0x300, header.Version);
1529 expect(0, header.EmfPlusFlags);
1530 todo_wine expectf(1440.0, header.DpiX);
1531 todo_wine expectf(1440.0, header.DpiY);
1532 expect(0, header.X);
1533 expect(0, header.Y);
1534 todo_wine expect(320, header.Width);
1535 todo_wine expect(320, header.Height);
1536 todo_wine expect(1, U(header).WmfHeader.mtType);
1537 expect(0, header.EmfPlusHeaderSize);
1538 expect(0, header.LogicalDpiX);
1539 expect(0, header.LogicalDpiY);
1542 GdipDisposeImage(img);
1545 static void test_createfromwmf_noplaceable(void)
1547 HMETAFILE hwmf;
1548 GpImage *img;
1549 GpStatus stat;
1551 hwmf = SetMetaFileBitsEx(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader),
1552 wmfimage+sizeof(WmfPlaceableFileHeader));
1553 ok(hwmf != 0, "SetMetaFileBitsEx failed\n");
1555 stat = GdipCreateMetafileFromWmf(hwmf, TRUE, NULL, (GpMetafile**)&img);
1556 expect(Ok, stat);
1558 GdipDisposeImage(img);
1561 static void test_resolution(void)
1563 GpStatus stat;
1564 GpBitmap *bitmap;
1565 GpGraphics *graphics;
1566 REAL res=-1.0;
1567 HDC screendc;
1568 int screenxres, screenyres;
1570 /* create Bitmap */
1571 stat = GdipCreateBitmapFromScan0(1, 1, 32, PixelFormat24bppRGB, NULL, &bitmap);
1572 expect(Ok, stat);
1574 /* test invalid values */
1575 stat = GdipGetImageHorizontalResolution(NULL, &res);
1576 expect(InvalidParameter, stat);
1578 stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, NULL);
1579 expect(InvalidParameter, stat);
1581 stat = GdipGetImageVerticalResolution(NULL, &res);
1582 expect(InvalidParameter, stat);
1584 stat = GdipGetImageVerticalResolution((GpImage*)bitmap, NULL);
1585 expect(InvalidParameter, stat);
1587 stat = GdipBitmapSetResolution(NULL, 96.0, 96.0);
1588 expect(InvalidParameter, stat);
1590 stat = GdipBitmapSetResolution(bitmap, 0.0, 0.0);
1591 expect(InvalidParameter, stat);
1593 /* defaults to screen resolution */
1594 screendc = GetDC(0);
1596 screenxres = GetDeviceCaps(screendc, LOGPIXELSX);
1597 screenyres = GetDeviceCaps(screendc, LOGPIXELSY);
1599 ReleaseDC(0, screendc);
1601 stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, &res);
1602 expect(Ok, stat);
1603 expectf((REAL)screenxres, res);
1605 stat = GdipGetImageVerticalResolution((GpImage*)bitmap, &res);
1606 expect(Ok, stat);
1607 expectf((REAL)screenyres, res);
1609 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
1610 expect(Ok, stat);
1611 stat = GdipGetDpiX(graphics, &res);
1612 expect(Ok, stat);
1613 expectf((REAL)screenxres, res);
1614 stat = GdipGetDpiY(graphics, &res);
1615 expect(Ok, stat);
1616 expectf((REAL)screenyres, res);
1618 /* test changing the resolution */
1619 stat = GdipBitmapSetResolution(bitmap, screenxres*2.0, screenyres*3.0);
1620 expect(Ok, stat);
1622 stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, &res);
1623 expect(Ok, stat);
1624 expectf(screenxres*2.0, res);
1626 stat = GdipGetImageVerticalResolution((GpImage*)bitmap, &res);
1627 expect(Ok, stat);
1628 expectf(screenyres*3.0, res);
1630 stat = GdipGetDpiX(graphics, &res);
1631 expect(Ok, stat);
1632 expectf((REAL)screenxres, res);
1633 stat = GdipGetDpiY(graphics, &res);
1634 expect(Ok, stat);
1635 expectf((REAL)screenyres, res);
1637 stat = GdipDeleteGraphics(graphics);
1638 expect(Ok, stat);
1640 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
1641 expect(Ok, stat);
1642 stat = GdipGetDpiX(graphics, &res);
1643 expect(Ok, stat);
1644 expectf(screenxres*2.0, res);
1645 stat = GdipGetDpiY(graphics, &res);
1646 expect(Ok, stat);
1647 expectf(screenyres*3.0, res);
1648 stat = GdipDeleteGraphics(graphics);
1649 expect(Ok, stat);
1651 stat = GdipDisposeImage((GpImage*)bitmap);
1652 expect(Ok, stat);
1655 static void test_createhbitmap(void)
1657 GpStatus stat;
1658 GpBitmap *bitmap;
1659 HBITMAP hbitmap, oldhbitmap;
1660 BITMAP bm;
1661 int ret;
1662 HDC hdc;
1663 COLORREF pixel;
1664 BYTE bits[640];
1666 memset(bits, 0x68, 640);
1668 /* create Bitmap */
1669 stat = GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB, bits, &bitmap);
1670 expect(Ok, stat);
1672 /* test NULL values */
1673 stat = GdipCreateHBITMAPFromBitmap(NULL, &hbitmap, 0);
1674 expect(InvalidParameter, stat);
1676 stat = GdipCreateHBITMAPFromBitmap(bitmap, NULL, 0);
1677 expect(InvalidParameter, stat);
1679 /* create HBITMAP */
1680 stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0);
1681 expect(Ok, stat);
1683 if (stat == Ok)
1685 ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
1686 expect(sizeof(BITMAP), ret);
1688 expect(0, bm.bmType);
1689 expect(10, bm.bmWidth);
1690 expect(20, bm.bmHeight);
1691 expect(40, bm.bmWidthBytes);
1692 expect(1, bm.bmPlanes);
1693 expect(32, bm.bmBitsPixel);
1694 ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
1696 if (bm.bmBits)
1698 DWORD val = *(DWORD*)bm.bmBits;
1699 ok(val == 0xff686868, "got %x, expected 0xff686868\n", val);
1702 hdc = CreateCompatibleDC(NULL);
1704 oldhbitmap = SelectObject(hdc, hbitmap);
1705 pixel = GetPixel(hdc, 5, 5);
1706 SelectObject(hdc, oldhbitmap);
1708 DeleteDC(hdc);
1710 expect(0x686868, pixel);
1712 DeleteObject(hbitmap);
1715 stat = GdipDisposeImage((GpImage*)bitmap);
1716 expect(Ok, stat);
1718 /* make (1,0) have no alpha and (2,0) a different blue value. */
1719 bits[7] = 0x00;
1720 bits[8] = 0x40;
1722 /* create alpha Bitmap */
1723 stat = GdipCreateBitmapFromScan0(8, 20, 32, PixelFormat32bppARGB, bits, &bitmap);
1724 expect(Ok, stat);
1726 /* create HBITMAP */
1727 stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0);
1728 expect(Ok, stat);
1730 if (stat == Ok)
1732 ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
1733 expect(sizeof(BITMAP), ret);
1735 expect(0, bm.bmType);
1736 expect(8, bm.bmWidth);
1737 expect(20, bm.bmHeight);
1738 expect(32, bm.bmWidthBytes);
1739 expect(1, bm.bmPlanes);
1740 expect(32, bm.bmBitsPixel);
1741 ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
1743 if (bm.bmBits)
1745 DWORD val = *(DWORD*)bm.bmBits;
1746 ok(val == 0x682a2a2a, "got %x, expected 0x682a2a2a\n", val);
1747 val = *((DWORD*)bm.bmBits + (bm.bmHeight-1) * bm.bmWidthBytes/4 + 1);
1748 ok(val == 0x0, "got %x, expected 0x682a2a2a\n", val);
1751 hdc = CreateCompatibleDC(NULL);
1753 oldhbitmap = SelectObject(hdc, hbitmap);
1754 pixel = GetPixel(hdc, 5, 5);
1755 expect(0x2a2a2a, pixel);
1756 pixel = GetPixel(hdc, 1, 0);
1757 expect(0x0, pixel);
1759 SelectObject(hdc, oldhbitmap);
1761 DeleteDC(hdc);
1764 DeleteObject(hbitmap);
1767 /* create HBITMAP with bkgnd colour */
1768 stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0xff00ff);
1769 expect(Ok, stat);
1771 if (stat == Ok)
1773 ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
1774 expect(sizeof(BITMAP), ret);
1776 expect(0, bm.bmType);
1777 expect(8, bm.bmWidth);
1778 expect(20, bm.bmHeight);
1779 expect(32, bm.bmWidthBytes);
1780 expect(1, bm.bmPlanes);
1781 expect(32, bm.bmBitsPixel);
1782 ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
1784 if (bm.bmBits)
1786 DWORD val = *(DWORD*)bm.bmBits;
1787 ok(val == 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val);
1788 val = *((DWORD*)bm.bmBits + (bm.bmHeight-1) * bm.bmWidthBytes/4 + 1);
1789 ok(val == 0xff00ff, "got %x, expected 0x682a2a2a\n", val);
1792 hdc = CreateCompatibleDC(NULL);
1794 oldhbitmap = SelectObject(hdc, hbitmap);
1795 pixel = GetPixel(hdc, 5, 5);
1796 expect(0xc12ac1, pixel);
1797 pixel = GetPixel(hdc, 1, 0);
1798 expect(0xff00ff, pixel);
1799 pixel = GetPixel(hdc, 2, 0);
1800 expect(0xb12ac1, pixel);
1802 SelectObject(hdc, oldhbitmap);
1803 DeleteDC(hdc);
1804 DeleteObject(hbitmap);
1807 /* create HBITMAP with bkgnd colour with alpha and show it behaves with no alpha. */
1808 stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0x80ff00ff);
1809 expect(Ok, stat);
1811 if (stat == Ok)
1813 ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
1814 expect(sizeof(BITMAP), ret);
1816 expect(0, bm.bmType);
1817 expect(8, bm.bmWidth);
1818 expect(20, bm.bmHeight);
1819 expect(32, bm.bmWidthBytes);
1820 expect(1, bm.bmPlanes);
1821 expect(32, bm.bmBitsPixel);
1822 ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
1824 if (bm.bmBits)
1826 DWORD val = *(DWORD*)bm.bmBits;
1827 ok(val == 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val);
1828 val = *((DWORD*)bm.bmBits + (bm.bmHeight-1) * bm.bmWidthBytes/4 + 1);
1829 ok(val == 0xff00ff, "got %x, expected 0x682a2a2a\n", val);
1832 hdc = CreateCompatibleDC(NULL);
1834 oldhbitmap = SelectObject(hdc, hbitmap);
1835 pixel = GetPixel(hdc, 5, 5);
1836 expect(0xc12ac1, pixel);
1837 pixel = GetPixel(hdc, 1, 0);
1838 expect(0xff00ff, pixel);
1839 pixel = GetPixel(hdc, 2, 0);
1840 expect(0xb12ac1, pixel);
1842 SelectObject(hdc, oldhbitmap);
1843 DeleteDC(hdc);
1844 DeleteObject(hbitmap);
1847 stat = GdipDisposeImage((GpImage*)bitmap);
1848 expect(Ok, stat);
1851 static void test_getthumbnail(void)
1853 GpStatus stat;
1854 GpImage *bitmap1, *bitmap2;
1855 UINT width, height;
1857 stat = GdipGetImageThumbnail(NULL, 0, 0, &bitmap2, NULL, NULL);
1858 expect(InvalidParameter, stat);
1860 stat = GdipCreateBitmapFromScan0(128, 128, 0, PixelFormat32bppRGB, NULL, (GpBitmap**)&bitmap1);
1861 expect(Ok, stat);
1863 stat = GdipGetImageThumbnail(bitmap1, 0, 0, NULL, NULL, NULL);
1864 expect(InvalidParameter, stat);
1866 stat = GdipGetImageThumbnail(bitmap1, 0, 0, &bitmap2, NULL, NULL);
1867 expect(Ok, stat);
1869 if (stat == Ok)
1871 stat = GdipGetImageWidth(bitmap2, &width);
1872 expect(Ok, stat);
1873 expect(120, width);
1875 stat = GdipGetImageHeight(bitmap2, &height);
1876 expect(Ok, stat);
1877 expect(120, height);
1879 GdipDisposeImage(bitmap2);
1882 GdipDisposeImage(bitmap1);
1885 stat = GdipCreateBitmapFromScan0(64, 128, 0, PixelFormat32bppRGB, NULL, (GpBitmap**)&bitmap1);
1886 expect(Ok, stat);
1888 stat = GdipGetImageThumbnail(bitmap1, 32, 32, &bitmap2, NULL, NULL);
1889 expect(Ok, stat);
1891 if (stat == Ok)
1893 stat = GdipGetImageWidth(bitmap2, &width);
1894 expect(Ok, stat);
1895 expect(32, width);
1897 stat = GdipGetImageHeight(bitmap2, &height);
1898 expect(Ok, stat);
1899 expect(32, height);
1901 GdipDisposeImage(bitmap2);
1904 stat = GdipGetImageThumbnail(bitmap1, 0, 0, &bitmap2, NULL, NULL);
1905 expect(Ok, stat);
1907 if (stat == Ok)
1909 stat = GdipGetImageWidth(bitmap2, &width);
1910 expect(Ok, stat);
1911 expect(120, width);
1913 stat = GdipGetImageHeight(bitmap2, &height);
1914 expect(Ok, stat);
1915 expect(120, height);
1917 GdipDisposeImage(bitmap2);
1920 GdipDisposeImage(bitmap1);
1923 static void test_getsetpixel(void)
1925 GpStatus stat;
1926 GpBitmap *bitmap;
1927 ARGB color;
1928 BYTE bits[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00,
1929 0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00};
1931 stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB, bits, &bitmap);
1932 expect(Ok, stat);
1934 /* null parameters */
1935 stat = GdipBitmapGetPixel(NULL, 1, 1, &color);
1936 expect(InvalidParameter, stat);
1938 stat = GdipBitmapGetPixel(bitmap, 1, 1, NULL);
1939 expect(InvalidParameter, stat);
1941 stat = GdipBitmapSetPixel(NULL, 1, 1, 0);
1942 expect(InvalidParameter, stat);
1944 /* out of bounds */
1945 stat = GdipBitmapGetPixel(bitmap, -1, 1, &color);
1946 expect(InvalidParameter, stat);
1948 stat = GdipBitmapSetPixel(bitmap, -1, 1, 0);
1949 expect(InvalidParameter, stat);
1951 stat = GdipBitmapGetPixel(bitmap, 1, -1, &color);
1952 ok(stat == InvalidParameter ||
1953 broken(stat == Ok), /* Older gdiplus */
1954 "Expected InvalidParameter, got %.8x\n", stat);
1956 if (0) /* crashes some gdiplus implementations */
1958 stat = GdipBitmapSetPixel(bitmap, 1, -1, 0);
1959 ok(stat == InvalidParameter ||
1960 broken(stat == Ok), /* Older gdiplus */
1961 "Expected InvalidParameter, got %.8x\n", stat);
1964 stat = GdipBitmapGetPixel(bitmap, 2, 1, &color);
1965 expect(InvalidParameter, stat);
1967 stat = GdipBitmapSetPixel(bitmap, 2, 1, 0);
1968 expect(InvalidParameter, stat);
1970 stat = GdipBitmapGetPixel(bitmap, 1, 2, &color);
1971 expect(InvalidParameter, stat);
1973 stat = GdipBitmapSetPixel(bitmap, 1, 2, 0);
1974 expect(InvalidParameter, stat);
1976 /* valid use */
1977 stat = GdipBitmapGetPixel(bitmap, 1, 1, &color);
1978 expect(Ok, stat);
1979 expect(0xffffffff, color);
1981 stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
1982 expect(Ok, stat);
1983 expect(0xff0000ff, color);
1985 stat = GdipBitmapSetPixel(bitmap, 1, 1, 0xff676869);
1986 expect(Ok, stat);
1988 stat = GdipBitmapSetPixel(bitmap, 0, 0, 0xff474849);
1989 expect(Ok, stat);
1991 stat = GdipBitmapGetPixel(bitmap, 1, 1, &color);
1992 expect(Ok, stat);
1993 expect(0xff676869, color);
1995 stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
1996 expect(Ok, stat);
1997 expect(0xff474849, color);
1999 stat = GdipDisposeImage((GpImage*)bitmap);
2000 expect(Ok, stat);
2003 static void check_halftone_palette(ColorPalette *palette)
2005 static const BYTE halftone_values[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
2006 UINT i;
2008 for (i=0; i<palette->Count; i++)
2010 ARGB expected=0xff000000;
2011 if (i<8)
2013 if (i&1) expected |= 0x800000;
2014 if (i&2) expected |= 0x8000;
2015 if (i&4) expected |= 0x80;
2017 else if (i == 8)
2019 expected = 0xffc0c0c0;
2021 else if (i < 16)
2023 if (i&1) expected |= 0xff0000;
2024 if (i&2) expected |= 0xff00;
2025 if (i&4) expected |= 0xff;
2027 else if (i < 40)
2029 expected = 0x00000000;
2031 else
2033 expected |= halftone_values[(i-40)%6];
2034 expected |= halftone_values[((i-40)/6)%6] << 8;
2035 expected |= halftone_values[((i-40)/36)%6] << 16;
2037 ok(expected == palette->Entries[i], "Expected %.8x, got %.8x, i=%u/%u\n",
2038 expected, palette->Entries[i], i, palette->Count);
2042 static void test_palette(void)
2044 GpStatus stat;
2045 GpBitmap *bitmap;
2046 INT size;
2047 BYTE buffer[1040];
2048 ColorPalette *palette=(ColorPalette*)buffer;
2049 ARGB *entries = palette->Entries;
2050 ARGB color=0;
2052 /* test initial palette from non-indexed bitmap */
2053 stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB, NULL, &bitmap);
2054 expect(Ok, stat);
2056 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
2057 expect(Ok, stat);
2058 expect(sizeof(UINT)*2+sizeof(ARGB), size);
2060 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
2061 expect(Ok, stat);
2062 expect(0, palette->Count);
2064 /* test setting palette on not-indexed bitmap */
2065 palette->Count = 3;
2067 stat = GdipSetImagePalette((GpImage*)bitmap, palette);
2068 expect(Ok, stat);
2070 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
2071 expect(Ok, stat);
2072 expect(sizeof(UINT)*2+sizeof(ARGB)*3, size);
2074 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
2075 expect(Ok, stat);
2076 expect(3, palette->Count);
2078 GdipDisposeImage((GpImage*)bitmap);
2080 /* test initial palette on 1-bit bitmap */
2081 stat = GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat1bppIndexed, NULL, &bitmap);
2082 expect(Ok, stat);
2084 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
2085 expect(Ok, stat);
2086 expect(sizeof(UINT)*2+sizeof(ARGB)*2, size);
2088 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
2089 expect(Ok, stat);
2090 expect(PaletteFlagsGrayScale, palette->Flags);
2091 expect(2, palette->Count);
2093 expect(0xff000000, entries[0]);
2094 expect(0xffffffff, entries[1]);
2096 /* test getting/setting pixels */
2097 stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
2098 expect(Ok, stat);
2099 expect(0xff000000, color);
2101 stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffffffff);
2102 ok((stat == Ok) ||
2103 broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
2105 if (stat == Ok)
2107 stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
2108 expect(Ok, stat);
2109 expect(0xffffffff, color);
2112 GdipDisposeImage((GpImage*)bitmap);
2114 /* test initial palette on 4-bit bitmap */
2115 stat = GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat4bppIndexed, NULL, &bitmap);
2116 expect(Ok, stat);
2118 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
2119 expect(Ok, stat);
2120 expect(sizeof(UINT)*2+sizeof(ARGB)*16, size);
2122 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
2123 expect(Ok, stat);
2124 expect(0, palette->Flags);
2125 expect(16, palette->Count);
2127 check_halftone_palette(palette);
2129 /* test getting/setting pixels */
2130 stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
2131 expect(Ok, stat);
2132 expect(0xff000000, color);
2134 stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffff00ff);
2135 ok((stat == Ok) ||
2136 broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
2138 if (stat == Ok)
2140 stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
2141 expect(Ok, stat);
2142 expect(0xffff00ff, color);
2145 GdipDisposeImage((GpImage*)bitmap);
2147 /* test initial palette on 8-bit bitmap */
2148 stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat8bppIndexed, NULL, &bitmap);
2149 expect(Ok, stat);
2151 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
2152 expect(Ok, stat);
2153 expect(sizeof(UINT)*2+sizeof(ARGB)*256, size);
2155 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
2156 expect(Ok, stat);
2157 expect(PaletteFlagsHalftone, palette->Flags);
2158 expect(256, palette->Count);
2160 check_halftone_palette(palette);
2162 /* test getting/setting pixels */
2163 stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
2164 expect(Ok, stat);
2165 expect(0xff000000, color);
2167 stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffcccccc);
2168 ok((stat == Ok) ||
2169 broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
2171 if (stat == Ok)
2173 stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
2174 expect(Ok, stat);
2175 expect(0xffcccccc, color);
2178 /* test setting/getting a different palette */
2179 entries[1] = 0xffcccccc;
2181 stat = GdipSetImagePalette((GpImage*)bitmap, palette);
2182 expect(Ok, stat);
2184 entries[1] = 0;
2186 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
2187 expect(Ok, stat);
2188 expect(sizeof(UINT)*2+sizeof(ARGB)*256, size);
2190 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
2191 expect(Ok, stat);
2192 expect(PaletteFlagsHalftone, palette->Flags);
2193 expect(256, palette->Count);
2194 expect(0xffcccccc, entries[1]);
2196 /* test count < 256 */
2197 palette->Flags = 12345;
2198 palette->Count = 3;
2200 stat = GdipSetImagePalette((GpImage*)bitmap, palette);
2201 expect(Ok, stat);
2203 entries[1] = 0;
2204 entries[3] = 0xdeadbeef;
2206 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
2207 expect(Ok, stat);
2208 expect(sizeof(UINT)*2+sizeof(ARGB)*3, size);
2210 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
2211 expect(Ok, stat);
2212 expect(12345, palette->Flags);
2213 expect(3, palette->Count);
2214 expect(0xffcccccc, entries[1]);
2215 expect(0xdeadbeef, entries[3]);
2217 /* test count > 256 */
2218 palette->Count = 257;
2220 stat = GdipSetImagePalette((GpImage*)bitmap, palette);
2221 ok(stat == InvalidParameter ||
2222 broken(stat == Ok), /* Old gdiplus behavior */
2223 "Expected %.8x, got %.8x\n", InvalidParameter, stat);
2225 GdipDisposeImage((GpImage*)bitmap);
2228 static void test_colormatrix(void)
2230 GpStatus stat;
2231 ColorMatrix colormatrix, graymatrix;
2232 GpImageAttributes *imageattr;
2233 const ColorMatrix identity = {{
2234 {1.0,0.0,0.0,0.0,0.0},
2235 {0.0,1.0,0.0,0.0,0.0},
2236 {0.0,0.0,1.0,0.0,0.0},
2237 {0.0,0.0,0.0,1.0,0.0},
2238 {0.0,0.0,0.0,0.0,1.0}}};
2239 const ColorMatrix double_red = {{
2240 {2.0,0.0,0.0,0.0,0.0},
2241 {0.0,1.0,0.0,0.0,0.0},
2242 {0.0,0.0,1.0,0.0,0.0},
2243 {0.0,0.0,0.0,1.0,0.0},
2244 {0.0,0.0,0.0,0.0,1.0}}};
2245 const ColorMatrix asymmetric = {{
2246 {0.0,1.0,0.0,0.0,0.0},
2247 {0.0,0.0,1.0,0.0,0.0},
2248 {0.0,0.0,0.0,1.0,0.0},
2249 {1.0,0.0,0.0,0.0,0.0},
2250 {0.0,0.0,0.0,0.0,1.0}}};
2251 GpBitmap *bitmap1, *bitmap2;
2252 GpGraphics *graphics;
2253 ARGB color;
2255 colormatrix = identity;
2256 graymatrix = identity;
2258 stat = GdipSetImageAttributesColorMatrix(NULL, ColorAdjustTypeDefault,
2259 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2260 expect(InvalidParameter, stat);
2262 stat = GdipCreateImageAttributes(&imageattr);
2263 expect(Ok, stat);
2265 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2266 TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2267 expect(Ok, stat);
2269 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2270 TRUE, NULL, NULL, ColorMatrixFlagsDefault);
2271 expect(InvalidParameter, stat);
2273 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2274 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2275 expect(Ok, stat);
2277 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2278 TRUE, &colormatrix, NULL, ColorMatrixFlagsSkipGrays);
2279 expect(Ok, stat);
2281 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2282 TRUE, &colormatrix, NULL, ColorMatrixFlagsAltGray);
2283 expect(InvalidParameter, stat);
2285 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2286 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsAltGray);
2287 expect(Ok, stat);
2289 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2290 TRUE, &colormatrix, &graymatrix, 3);
2291 expect(InvalidParameter, stat);
2293 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeCount,
2294 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2295 expect(InvalidParameter, stat);
2297 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeAny,
2298 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2299 expect(InvalidParameter, stat);
2301 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2302 FALSE, NULL, NULL, ColorMatrixFlagsDefault);
2303 expect(Ok, stat);
2305 /* Drawing a bitmap transforms the colors */
2306 colormatrix = double_red;
2307 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2308 TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2309 expect(Ok, stat);
2311 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB, NULL, &bitmap1);
2312 expect(Ok, stat);
2314 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB, NULL, &bitmap2);
2315 expect(Ok, stat);
2317 stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff40ccee);
2318 expect(Ok, stat);
2320 stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
2321 expect(Ok, stat);
2323 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2324 UnitPixel, imageattr, NULL, NULL);
2325 expect(Ok, stat);
2327 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2328 expect(Ok, stat);
2329 expect(0xff80ccee, color);
2331 colormatrix = asymmetric;
2332 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2333 TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2334 expect(Ok, stat);
2336 stat = GdipBitmapSetPixel(bitmap2, 0, 0, 0);
2337 expect(Ok, stat);
2339 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2340 UnitPixel, imageattr, NULL, NULL);
2341 expect(Ok, stat);
2343 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2344 expect(Ok, stat);
2345 ok(color_match(0xeeff40cc, color, 3), "expected 0xeeff40cc, got 0x%08x\n", color);
2347 stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeDefault);
2348 expect(Ok, stat);
2350 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2351 UnitPixel, imageattr, NULL, NULL);
2352 expect(Ok, stat);
2354 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2355 expect(Ok, stat);
2356 ok(color_match(0xff40ccee, color, 1), "Expected ff40ccee, got %.8x\n", color);
2358 GdipDeleteGraphics(graphics);
2359 GdipDisposeImage((GpImage*)bitmap1);
2360 GdipDisposeImage((GpImage*)bitmap2);
2361 GdipDisposeImageAttributes(imageattr);
2364 static void test_gamma(void)
2366 GpStatus stat;
2367 GpImageAttributes *imageattr;
2368 GpBitmap *bitmap1, *bitmap2;
2369 GpGraphics *graphics;
2370 ARGB color;
2372 stat = GdipSetImageAttributesGamma(NULL, ColorAdjustTypeDefault, TRUE, 1.0);
2373 expect(InvalidParameter, stat);
2375 stat = GdipCreateImageAttributes(&imageattr);
2376 expect(Ok, stat);
2378 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 1.0);
2379 expect(Ok, stat);
2381 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeAny, TRUE, 1.0);
2382 expect(InvalidParameter, stat);
2384 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, -1.0);
2385 expect(InvalidParameter, stat);
2387 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 0.0);
2388 expect(InvalidParameter, stat);
2390 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 0.5);
2391 expect(Ok, stat);
2393 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, FALSE, 0.0);
2394 expect(Ok, stat);
2396 /* Drawing a bitmap transforms the colors */
2397 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 3.0);
2398 expect(Ok, stat);
2400 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap1);
2401 expect(Ok, stat);
2403 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap2);
2404 expect(Ok, stat);
2406 stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff80ffff);
2407 expect(Ok, stat);
2409 stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
2410 expect(Ok, stat);
2412 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2413 UnitPixel, imageattr, NULL, NULL);
2414 expect(Ok, stat);
2416 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2417 expect(Ok, stat);
2418 ok(color_match(0xff20ffff, color, 1), "Expected ff20ffff, got %.8x\n", color);
2420 stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeDefault);
2421 expect(Ok, stat);
2423 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2424 UnitPixel, imageattr, NULL, NULL);
2425 expect(Ok, stat);
2427 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2428 expect(Ok, stat);
2429 ok(color_match(0xff80ffff, color, 1), "Expected ff80ffff, got %.8x\n", color);
2431 GdipDeleteGraphics(graphics);
2432 GdipDisposeImage((GpImage*)bitmap1);
2433 GdipDisposeImage((GpImage*)bitmap2);
2434 GdipDisposeImageAttributes(imageattr);
2437 /* 1x1 pixel gif, 2 frames; first frame is white, second is black */
2438 static const unsigned char gifanimation[72] = {
2439 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
2440 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0xf9,0x04,0x00,0x0a,0x00,0xff,
2441 0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x4c,0x01,0x00,
2442 0x21,0xf9,0x04,0x01,0x0a,0x00,0x01,0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,
2443 0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
2446 /* Generated with ImageMagick:
2447 * convert -transparent black -delay 100 -size 8x2 xc:black \
2448 * -dispose none -page +0+0 -size 2x2 xc:red \
2449 * -dispose background -page +2+0 -size 2x2 xc:blue \
2450 * -dispose previous -page +4+0 -size 2x2 xc:green \
2451 * -dispose undefined -page +6+0 -size 2x2 xc:gray \
2452 * test.gif
2454 static const unsigned char gifanimation2[] = {
2455 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x08, 0x00,
2456 0x02, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
2457 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x64,
2458 0x00, 0x00, 0x00, 0x21, 0xff, 0x0b, 0x4e, 0x45,
2459 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e,
2460 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00,
2461 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
2462 0x02, 0x04, 0x84, 0x8f, 0x09, 0x05, 0x00, 0x21,
2463 0xf9, 0x04, 0x04, 0x64, 0x00, 0x00, 0x00, 0x2c,
2464 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2465 0x81, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
2466 0x00, 0x00, 0xff, 0x00, 0x00, 0x02, 0x03, 0x44,
2467 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x08, 0x64,
2468 0x00, 0x00, 0x00, 0x2c, 0x02, 0x00, 0x00, 0x00,
2469 0x02, 0x00, 0x02, 0x00, 0x81, 0x00, 0x00, 0xff,
2470 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
2471 0xff, 0x02, 0x03, 0x44, 0x34, 0x05, 0x00, 0x21,
2472 0xf9, 0x04, 0x0c, 0x64, 0x00, 0x00, 0x00, 0x2c,
2473 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2474 0x81, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00,
2475 0x80, 0x00, 0x00, 0x80, 0x00, 0x02, 0x03, 0x44,
2476 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x64,
2477 0x00, 0x00, 0x00, 0x2c, 0x06, 0x00, 0x00, 0x00,
2478 0x02, 0x00, 0x02, 0x00, 0x80, 0x7e, 0x7e, 0x7e,
2479 0x00, 0x00, 0x00, 0x02, 0x02, 0x84, 0x51, 0x00,
2480 0x3b
2483 static ARGB gifanimation2_pixels[5][4] = {
2484 {0, 0, 0, 0},
2485 {0xffff0000, 0, 0, 0},
2486 {0xffff0000, 0xff0000ff, 0, 0},
2487 {0xffff0000, 0, 0xff008000, 0},
2488 {0xffff0000, 0, 0, 0xff7e7e7e}
2491 static void test_multiframegif(void)
2493 LPSTREAM stream;
2494 HGLOBAL hglob;
2495 LPBYTE data;
2496 HRESULT hres;
2497 GpStatus stat;
2498 GpBitmap *bmp;
2499 ARGB color;
2500 UINT count;
2501 GUID dimension;
2502 PixelFormat pixel_format;
2503 INT palette_size, i, j;
2504 char palette_buf[256];
2505 ColorPalette *palette;
2506 ARGB *palette_entries;
2508 /* Test frame functions with an animated GIF */
2509 hglob = GlobalAlloc (0, sizeof(gifanimation));
2510 data = GlobalLock (hglob);
2511 memcpy(data, gifanimation, sizeof(gifanimation));
2512 GlobalUnlock(hglob);
2514 hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
2515 ok(hres == S_OK, "Failed to create a stream\n");
2516 if(hres != S_OK) return;
2518 stat = GdipCreateBitmapFromStream(stream, &bmp);
2519 ok(stat == Ok, "Failed to create a Bitmap\n");
2520 if(stat != Ok){
2521 IStream_Release(stream);
2522 return;
2525 stat = GdipGetImagePixelFormat((GpImage*)bmp, &pixel_format);
2526 expect(Ok, stat);
2527 expect(PixelFormat32bppARGB, pixel_format);
2529 stat = GdipGetImagePaletteSize((GpImage*)bmp, &palette_size);
2530 expect(Ok, stat);
2531 ok(palette_size == sizeof(ColorPalette) ||
2532 broken(palette_size == sizeof(ColorPalette)+sizeof(ARGB[3])),
2533 "palette_size = %d\n", palette_size);
2535 /* Bitmap starts at frame 0 */
2536 color = 0xdeadbeef;
2537 stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2538 expect(Ok, stat);
2539 expect(0xffffffff, color);
2541 /* Check that we get correct metadata */
2542 stat = GdipImageGetFrameDimensionsCount((GpImage*)bmp,&count);
2543 expect(Ok, stat);
2544 expect(1, count);
2546 stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1);
2547 expect(Ok, stat);
2548 expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE);
2550 count = 12345;
2551 stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
2552 expect(Ok, stat);
2553 expect(2, count);
2555 /* SelectActiveFrame overwrites our current data */
2556 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 1);
2557 expect(Ok, stat);
2559 color = 0xdeadbeef;
2560 GdipBitmapGetPixel(bmp, 0, 0, &color);
2561 expect(Ok, stat);
2562 expect(0xff000000, color);
2564 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
2565 expect(Ok, stat);
2567 color = 0xdeadbeef;
2568 GdipBitmapGetPixel(bmp, 0, 0, &color);
2569 expect(Ok, stat);
2570 expect(0xffffffff, color);
2572 /* Write over the image data */
2573 stat = GdipBitmapSetPixel(bmp, 0, 0, 0xff000000);
2574 expect(Ok, stat);
2576 /* Switching to the same frame does not overwrite our changes */
2577 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
2578 expect(Ok, stat);
2580 stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2581 expect(Ok, stat);
2582 expect(0xff000000, color);
2584 /* But switching to another frame and back does */
2585 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 1);
2586 expect(Ok, stat);
2588 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
2589 expect(Ok, stat);
2591 stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2592 expect(Ok, stat);
2593 expect(0xffffffff, color);
2595 /* rotate/flip discards the information about other frames */
2596 stat = GdipImageRotateFlip((GpImage*)bmp, Rotate90FlipNone);
2597 expect(Ok, stat);
2599 count = 12345;
2600 stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
2601 expect(Ok, stat);
2602 expect(1, count);
2604 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bmp, __LINE__, FALSE);
2606 GdipDisposeImage((GpImage*)bmp);
2607 IStream_Release(stream);
2609 /* Test with a non-animated gif */
2610 hglob = GlobalAlloc (0, sizeof(gifimage));
2611 data = GlobalLock (hglob);
2612 memcpy(data, gifimage, sizeof(gifimage));
2613 GlobalUnlock(hglob);
2615 hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
2616 ok(hres == S_OK, "Failed to create a stream\n");
2617 if(hres != S_OK) return;
2619 stat = GdipCreateBitmapFromStream(stream, &bmp);
2620 ok(stat == Ok, "Failed to create a Bitmap\n");
2621 if(stat != Ok){
2622 IStream_Release(stream);
2623 return;
2626 stat = GdipGetImagePixelFormat((GpImage*)bmp, &pixel_format);
2627 expect(Ok, stat);
2628 expect(PixelFormat8bppIndexed, pixel_format);
2630 /* Check metadata */
2631 stat = GdipImageGetFrameDimensionsCount((GpImage*)bmp,&count);
2632 expect(Ok, stat);
2633 expect(1, count);
2635 stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1);
2636 expect(Ok, stat);
2637 expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE);
2639 count = 12345;
2640 stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
2641 expect(Ok, stat);
2642 expect(1, count);
2644 GdipDisposeImage((GpImage*)bmp);
2645 IStream_Release(stream);
2647 /* Test with a non-animated transparent gif */
2648 hglob = GlobalAlloc (0, sizeof(transparentgif));
2649 data = GlobalLock (hglob);
2650 memcpy(data, transparentgif, sizeof(transparentgif));
2651 GlobalUnlock(hglob);
2653 hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
2654 ok(hres == S_OK, "Failed to create a stream\n");
2656 stat = GdipCreateBitmapFromStream(stream, &bmp);
2657 IStream_Release(stream);
2658 ok(stat == Ok, "Failed to create a Bitmap\n");
2660 stat = GdipGetImagePixelFormat((GpImage*)bmp, &pixel_format);
2661 expect(Ok, stat);
2662 expect(PixelFormat8bppIndexed, pixel_format);
2664 stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2665 expect(Ok, stat);
2666 expect(0, color);
2668 stat = GdipGetImagePaletteSize((GpImage*)bmp, &palette_size);
2669 expect(Ok, stat);
2670 ok(palette_size == sizeof(ColorPalette)+sizeof(ARGB),
2671 "palette_size = %d\n", palette_size);
2673 memset(palette_buf, 0xfe, sizeof(palette_buf));
2674 palette = (ColorPalette*)palette_buf;
2675 stat = GdipGetImagePalette((GpImage*)bmp, palette,
2676 sizeof(ColorPalette)+sizeof(ARGB));
2677 palette_entries = palette->Entries;
2678 expect(Ok, stat);
2679 expect(PaletteFlagsHasAlpha, palette->Flags);
2680 expect(2, palette->Count);
2681 expect(0, palette_entries[0]);
2682 expect(0xff000000, palette_entries[1]);
2684 count = 12345;
2685 stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
2686 expect(Ok, stat);
2687 expect(1, count);
2689 GdipDisposeImage((GpImage*)bmp);
2691 /* Test frame dispose methods */
2692 hglob = GlobalAlloc (0, sizeof(gifanimation2));
2693 data = GlobalLock (hglob);
2694 memcpy(data, gifanimation2, sizeof(gifanimation2));
2695 GlobalUnlock(hglob);
2697 hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
2698 ok(hres == S_OK, "Failed to create a stream\n");
2700 stat = GdipCreateBitmapFromStream(stream, &bmp);
2701 ok(stat == Ok, "Failed to create a Bitmap\n");
2702 IStream_Release(stream);
2704 stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1);
2705 expect(Ok, stat);
2706 expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE);
2708 stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
2709 expect(Ok, stat);
2710 expect(5, count);
2712 stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2713 expect(Ok, stat);
2714 expect(0, color);
2716 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 3);
2717 expect(Ok, stat);
2718 stat = GdipBitmapGetPixel(bmp, 2, 0, &color);
2719 expect(Ok, stat);
2720 ok(color==0 || broken(color==0xff0000ff), "color = %x\n", color);
2721 if(color != 0) {
2722 win_skip("broken animated gif support\n");
2723 GdipDisposeImage((GpImage*)bmp);
2724 return;
2727 for(i=0; i<6; i++) {
2728 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, i%5);
2729 expect(Ok, stat);
2731 for(j=0; j<4; j++) {
2732 stat = GdipBitmapGetPixel(bmp, j*2, 0, &color);
2733 expect(Ok, stat);
2734 ok(gifanimation2_pixels[i%5][j] == color, "at %d,%d got %x, expected %x\n", i, j, color, gifanimation2_pixels[i%5][j]);
2738 GdipDisposeImage((GpImage*)bmp);
2741 static void test_rotateflip(void)
2743 GpImage *bitmap;
2744 GpStatus stat;
2745 BYTE bits[24];
2746 static const BYTE orig_bits[24] = {
2747 0,0,0xff, 0,0xff,0, 0xff,0,0, 23,23,23,
2748 0xff,0xff,0, 0xff,0,0xff, 0,0xff,0xff, 23,23,23};
2749 UINT width, height;
2750 ARGB color;
2752 memcpy(bits, orig_bits, sizeof(bits));
2753 stat = GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB, bits, (GpBitmap**)&bitmap);
2754 expect(Ok, stat);
2756 stat = GdipImageRotateFlip(bitmap, Rotate90FlipNone);
2757 expect(Ok, stat);
2759 stat = GdipGetImageWidth(bitmap, &width);
2760 expect(Ok, stat);
2761 stat = GdipGetImageHeight(bitmap, &height);
2762 expect(Ok, stat);
2763 expect(2, width);
2764 expect(3, height);
2766 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
2767 expect(Ok, stat);
2768 expect(0xff00ffff, color);
2770 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 1, 0, &color);
2771 expect(Ok, stat);
2772 expect(0xffff0000, color);
2774 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 2, &color);
2775 expect(Ok, stat);
2776 expect(0xffffff00, color);
2778 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 1, 2, &color);
2779 expect(Ok, stat);
2780 expect(0xff0000ff, color);
2782 expect(0, bits[0]);
2783 expect(0, bits[1]);
2784 expect(0xff, bits[2]);
2786 GdipDisposeImage(bitmap);
2788 memcpy(bits, orig_bits, sizeof(bits));
2789 stat = GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB, bits, (GpBitmap**)&bitmap);
2790 expect(Ok, stat);
2792 stat = GdipImageRotateFlip(bitmap, RotateNoneFlipX);
2793 expect(Ok, stat);
2795 stat = GdipGetImageWidth(bitmap, &width);
2796 expect(Ok, stat);
2797 stat = GdipGetImageHeight(bitmap, &height);
2798 expect(Ok, stat);
2799 expect(3, width);
2800 expect(2, height);
2802 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
2803 expect(Ok, stat);
2804 expect(0xff0000ff, color);
2806 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 0, &color);
2807 expect(Ok, stat);
2808 expect(0xffff0000, color);
2810 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 1, &color);
2811 expect(Ok, stat);
2812 expect(0xffffff00, color);
2814 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 1, &color);
2815 expect(Ok, stat);
2816 expect(0xff00ffff, color);
2818 expect(0, bits[0]);
2819 expect(0, bits[1]);
2820 expect(0xff, bits[2]);
2822 GdipDisposeImage(bitmap);
2824 memcpy(bits, orig_bits, sizeof(bits));
2825 stat = GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB, bits, (GpBitmap**)&bitmap);
2826 expect(Ok, stat);
2828 stat = GdipImageRotateFlip(bitmap, RotateNoneFlipY);
2829 expect(Ok, stat);
2831 stat = GdipGetImageWidth(bitmap, &width);
2832 expect(Ok, stat);
2833 stat = GdipGetImageHeight(bitmap, &height);
2834 expect(Ok, stat);
2835 expect(3, width);
2836 expect(2, height);
2838 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
2839 expect(Ok, stat);
2840 expect(0xff00ffff, color);
2842 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 0, &color);
2843 expect(Ok, stat);
2844 expect(0xffffff00, color);
2846 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 1, &color);
2847 expect(Ok, stat);
2848 expect(0xffff0000, color);
2850 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 1, &color);
2851 expect(Ok, stat);
2852 expect(0xff0000ff, color);
2854 expect(0, bits[0]);
2855 expect(0, bits[1]);
2856 expect(0xff, bits[2]);
2858 GdipDisposeImage(bitmap);
2861 static void test_remaptable(void)
2863 GpStatus stat;
2864 GpImageAttributes *imageattr;
2865 GpBitmap *bitmap1, *bitmap2;
2866 GpGraphics *graphics;
2867 ARGB color;
2868 ColorMap *map;
2870 map = GdipAlloc(sizeof(ColorMap));
2872 map->oldColor.Argb = 0xff00ff00;
2873 map->newColor.Argb = 0xffff00ff;
2875 stat = GdipSetImageAttributesRemapTable(NULL, ColorAdjustTypeDefault, TRUE, 1, map);
2876 expect(InvalidParameter, stat);
2878 stat = GdipCreateImageAttributes(&imageattr);
2879 expect(Ok, stat);
2881 stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, TRUE, 1, NULL);
2882 expect(InvalidParameter, stat);
2884 stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeCount, TRUE, 1, map);
2885 expect(InvalidParameter, stat);
2887 stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeAny, TRUE, 1, map);
2888 expect(InvalidParameter, stat);
2890 stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, TRUE, 0, map);
2891 expect(InvalidParameter, stat);
2893 stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, FALSE, 0, NULL);
2894 expect(Ok, stat);
2896 stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, TRUE, 1, map);
2897 expect(Ok, stat);
2899 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap1);
2900 expect(Ok, stat);
2902 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap2);
2903 expect(Ok, stat);
2905 stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff00ff00);
2906 expect(Ok, stat);
2908 stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
2909 expect(Ok, stat);
2911 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2912 UnitPixel, imageattr, NULL, NULL);
2913 expect(Ok, stat);
2915 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2916 expect(Ok, stat);
2917 ok(color_match(0xffff00ff, color, 1), "Expected ffff00ff, got %.8x\n", color);
2919 stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeDefault);
2920 expect(Ok, stat);
2922 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2923 UnitPixel, imageattr, NULL, NULL);
2924 expect(Ok, stat);
2926 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2927 expect(Ok, stat);
2928 ok(color_match(0xff00ff00, color, 1), "Expected ff00ff00, got %.8x\n", color);
2930 GdipDeleteGraphics(graphics);
2931 GdipDisposeImage((GpImage*)bitmap1);
2932 GdipDisposeImage((GpImage*)bitmap2);
2933 GdipDisposeImageAttributes(imageattr);
2934 GdipFree(map);
2937 static void test_colorkey(void)
2939 GpStatus stat;
2940 GpImageAttributes *imageattr;
2941 GpBitmap *bitmap1, *bitmap2;
2942 GpGraphics *graphics;
2943 ARGB color;
2945 stat = GdipSetImageAttributesColorKeys(NULL, ColorAdjustTypeDefault, TRUE, 0xff405060, 0xff708090);
2946 expect(InvalidParameter, stat);
2948 stat = GdipCreateImageAttributes(&imageattr);
2949 expect(Ok, stat);
2951 stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeCount, TRUE, 0xff405060, 0xff708090);
2952 expect(InvalidParameter, stat);
2954 stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeAny, TRUE, 0xff405060, 0xff708090);
2955 expect(InvalidParameter, stat);
2957 stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeDefault, TRUE, 0xff405060, 0xff708090);
2958 expect(Ok, stat);
2960 stat = GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB, NULL, &bitmap1);
2961 expect(Ok, stat);
2963 stat = GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB, NULL, &bitmap2);
2964 expect(Ok, stat);
2966 stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0x20405060);
2967 expect(Ok, stat);
2969 stat = GdipBitmapSetPixel(bitmap1, 0, 1, 0x40506070);
2970 expect(Ok, stat);
2972 stat = GdipBitmapSetPixel(bitmap1, 1, 0, 0x60708090);
2973 expect(Ok, stat);
2975 stat = GdipBitmapSetPixel(bitmap1, 1, 1, 0xffffffff);
2976 expect(Ok, stat);
2978 stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
2979 expect(Ok, stat);
2981 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,2,2, 0,0,2,2,
2982 UnitPixel, imageattr, NULL, NULL);
2983 expect(Ok, stat);
2985 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2986 expect(Ok, stat);
2987 ok(color_match(0x00000000, color, 1), "Expected 00000000, got %.8x\n", color);
2989 stat = GdipBitmapGetPixel(bitmap2, 0, 1, &color);
2990 expect(Ok, stat);
2991 ok(color_match(0x00000000, color, 1), "Expected 00000000, got %.8x\n", color);
2993 stat = GdipBitmapGetPixel(bitmap2, 1, 0, &color);
2994 expect(Ok, stat);
2995 ok(color_match(0x00000000, color, 1), "Expected 00000000, got %.8x\n", color);
2997 stat = GdipBitmapGetPixel(bitmap2, 1, 1, &color);
2998 expect(Ok, stat);
2999 ok(color_match(0xffffffff, color, 1), "Expected ffffffff, got %.8x\n", color);
3001 stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeDefault);
3002 expect(Ok, stat);
3004 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,2,2, 0,0,2,2,
3005 UnitPixel, imageattr, NULL, NULL);
3006 expect(Ok, stat);
3008 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
3009 expect(Ok, stat);
3010 ok(color_match(0x20405060, color, 1), "Expected 20405060, got %.8x\n", color);
3012 stat = GdipBitmapGetPixel(bitmap2, 0, 1, &color);
3013 expect(Ok, stat);
3014 ok(color_match(0x40506070, color, 1), "Expected 40506070, got %.8x\n", color);
3016 stat = GdipBitmapGetPixel(bitmap2, 1, 0, &color);
3017 expect(Ok, stat);
3018 ok(color_match(0x60708090, color, 1), "Expected 60708090, got %.8x\n", color);
3020 stat = GdipBitmapGetPixel(bitmap2, 1, 1, &color);
3021 expect(Ok, stat);
3022 ok(color_match(0xffffffff, color, 1), "Expected ffffffff, got %.8x\n", color);
3025 GdipDeleteGraphics(graphics);
3026 GdipDisposeImage((GpImage*)bitmap1);
3027 GdipDisposeImage((GpImage*)bitmap2);
3028 GdipDisposeImageAttributes(imageattr);
3031 static void test_dispose(void)
3033 GpStatus stat;
3034 GpImage *image;
3035 char invalid_image[256];
3037 stat = GdipDisposeImage(NULL);
3038 expect(InvalidParameter, stat);
3040 stat = GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB, NULL, (GpBitmap**)&image);
3041 expect(Ok, stat);
3043 stat = GdipDisposeImage(image);
3044 expect(Ok, stat);
3046 stat = GdipDisposeImage(image);
3047 expect(ObjectBusy, stat);
3049 memset(invalid_image, 0, 256);
3050 stat = GdipDisposeImage((GpImage*)invalid_image);
3051 expect(ObjectBusy, stat);
3054 static LONG obj_refcount(void *obj)
3056 IUnknown_AddRef((IUnknown *)obj);
3057 return IUnknown_Release((IUnknown *)obj);
3060 static GpImage *load_image(const BYTE *image_data, UINT image_size)
3062 IStream *stream;
3063 HGLOBAL hmem;
3064 BYTE *data;
3065 HRESULT hr;
3066 GpStatus status;
3067 GpImage *image = NULL, *clone;
3068 ImageType image_type;
3069 LONG refcount, old_refcount;
3071 hmem = GlobalAlloc(0, image_size);
3072 data = GlobalLock(hmem);
3073 memcpy(data, image_data, image_size);
3074 GlobalUnlock(hmem);
3076 hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
3077 ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr);
3078 if (hr != S_OK) return NULL;
3080 refcount = obj_refcount(stream);
3081 ok(refcount == 1, "expected stream refcount 1, got %d\n", refcount);
3083 status = GdipLoadImageFromStream(stream, &image);
3084 ok(status == Ok || broken(status == InvalidParameter), /* XP */
3085 "GdipLoadImageFromStream error %d\n", status);
3086 if (status != Ok)
3088 IStream_Release(stream);
3089 return NULL;
3092 status = GdipGetImageType(image, &image_type);
3093 ok(status == Ok, "GdipGetImageType error %d\n", status);
3095 refcount = obj_refcount(stream);
3096 if (image_type == ImageTypeBitmap)
3097 ok(refcount > 1, "expected stream refcount > 1, got %d\n", refcount);
3098 else
3099 ok(refcount == 1, "expected stream refcount 1, got %d\n", refcount);
3100 old_refcount = refcount;
3102 status = GdipCloneImage(image, &clone);
3103 ok(status == Ok, "GdipCloneImage error %d\n", status);
3104 refcount = obj_refcount(stream);
3105 ok(refcount == old_refcount, "expected stream refcount %d, got %d\n", old_refcount, refcount);
3106 status = GdipDisposeImage(clone);
3107 ok(status == Ok, "GdipDisposeImage error %d\n", status);
3108 refcount = obj_refcount(stream);
3109 ok(refcount == old_refcount, "expected stream refcount %d, got %d\n", old_refcount, refcount);
3111 refcount = IStream_Release(stream);
3112 if (image_type == ImageTypeBitmap)
3113 ok(refcount >= 1, "expected stream refcount != 0\n");
3114 else
3115 ok(refcount == 0, "expected stream refcount 0, got %d\n", refcount);
3117 return image;
3120 static void test_image_properties(void)
3122 static const struct test_data
3124 const BYTE *image_data;
3125 UINT image_size;
3126 ImageType image_type;
3127 UINT prop_count;
3128 UINT prop_count2; /* if win7 behaves differently */
3129 /* 1st property attributes */
3130 UINT prop_size;
3131 UINT prop_size2; /* if win7 behaves differently */
3132 UINT prop_id;
3133 UINT prop_id2; /* if win7 behaves differently */
3135 td[] =
3137 { pngimage, sizeof(pngimage), ImageTypeBitmap, 4, ~0, 1, 20, 0x5110, 0x132 },
3138 { jpgimage, sizeof(jpgimage), ImageTypeBitmap, 2, ~0, 128, 0, 0x5090, 0x5091 },
3139 { tiffimage, sizeof(tiffimage), ImageTypeBitmap, 16, 0, 4, 0, 0xfe, 0 },
3140 { bmpimage, sizeof(bmpimage), ImageTypeBitmap, 0, 0, 0, 0, 0, 0 },
3141 { wmfimage, sizeof(wmfimage), ImageTypeMetafile, 0, 0, 0, 0, 0, 0 }
3143 GpStatus status;
3144 GpImage *image;
3145 UINT prop_count, prop_size, i;
3146 PROPID prop_id[16] = { 0 };
3147 ImageType image_type;
3148 union
3150 PropertyItem data;
3151 char buf[256];
3152 } item;
3154 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
3156 image = load_image(td[i].image_data, td[i].image_size);
3157 if (!image)
3159 trace("%u: failed to load image data\n", i);
3160 continue;
3163 status = GdipGetImageType(image, &image_type);
3164 ok(status == Ok, "%u: GdipGetImageType error %d\n", i, status);
3165 ok(td[i].image_type == image_type, "%u: expected image_type %d, got %d\n",
3166 i, td[i].image_type, image_type);
3168 status = GdipGetPropertyCount(image, &prop_count);
3169 ok(status == Ok, "%u: GdipGetPropertyCount error %d\n", i, status);
3170 if (td[i].image_data == pngimage || td[i].image_data == jpgimage)
3171 todo_wine
3172 ok(td[i].prop_count == prop_count || td[i].prop_count2 == prop_count,
3173 " %u: expected property count %u or %u, got %u\n",
3174 i, td[i].prop_count, td[i].prop_count2, prop_count);
3175 else
3176 ok(td[i].prop_count == prop_count || td[i].prop_count2 == prop_count,
3177 " %u: expected property count %u or %u, got %u\n",
3178 i, td[i].prop_count, td[i].prop_count2, prop_count);
3180 status = GdipGetPropertyItemSize(NULL, 0, &prop_size);
3181 expect(InvalidParameter, status);
3182 status = GdipGetPropertyItemSize(image, 0, NULL);
3183 expect(InvalidParameter, status);
3184 status = GdipGetPropertyItemSize(image, 0, &prop_size);
3185 if (image_type == ImageTypeMetafile)
3186 expect(NotImplemented, status);
3187 else
3188 expect(PropertyNotFound, status);
3190 status = GdipGetPropertyItem(NULL, 0, 0, &item.data);
3191 expect(InvalidParameter, status);
3192 status = GdipGetPropertyItem(image, 0, 0, NULL);
3193 expect(InvalidParameter, status);
3194 status = GdipGetPropertyItem(image, 0, 0, &item.data);
3195 if (image_type == ImageTypeMetafile)
3196 expect(NotImplemented, status);
3197 else
3198 expect(PropertyNotFound, status);
3200 /* FIXME: remove once Wine is fixed */
3201 if (td[i].prop_count != prop_count)
3203 GdipDisposeImage(image);
3204 continue;
3207 status = GdipGetPropertyIdList(NULL, prop_count, prop_id);
3208 expect(InvalidParameter, status);
3209 status = GdipGetPropertyIdList(image, prop_count, NULL);
3210 expect(InvalidParameter, status);
3211 status = GdipGetPropertyIdList(image, 0, prop_id);
3212 if (image_type == ImageTypeMetafile)
3213 expect(NotImplemented, status);
3214 else if (prop_count == 0)
3215 expect(Ok, status);
3216 else
3217 expect(InvalidParameter, status);
3218 status = GdipGetPropertyIdList(image, prop_count - 1, prop_id);
3219 if (image_type == ImageTypeMetafile)
3220 expect(NotImplemented, status);
3221 else
3222 expect(InvalidParameter, status);
3223 status = GdipGetPropertyIdList(image, prop_count + 1, prop_id);
3224 if (image_type == ImageTypeMetafile)
3225 expect(NotImplemented, status);
3226 else
3227 expect(InvalidParameter, status);
3228 status = GdipGetPropertyIdList(image, prop_count, prop_id);
3229 if (image_type == ImageTypeMetafile)
3230 expect(NotImplemented, status);
3231 else
3233 expect(Ok, status);
3234 if (prop_count != 0)
3235 ok(td[i].prop_id == prop_id[0] || td[i].prop_id2 == prop_id[0],
3236 " %u: expected property id %#x or %#x, got %#x\n",
3237 i, td[i].prop_id, td[i].prop_id2, prop_id[0]);
3240 if (status == Ok)
3242 status = GdipGetPropertyItemSize(image, prop_id[0], &prop_size);
3243 if (prop_count == 0)
3244 expect(PropertyNotFound, status);
3245 else
3247 expect(Ok, status);
3249 assert(sizeof(item) >= prop_size);
3250 ok(prop_size > sizeof(PropertyItem), "%u: got too small prop_size %u\n",
3251 i, prop_size);
3252 ok(td[i].prop_size + sizeof(PropertyItem) == prop_size ||
3253 td[i].prop_size2 + sizeof(PropertyItem) == prop_size,
3254 " %u: expected property size %u or %u, got %u\n",
3255 i, td[i].prop_size, td[i].prop_size2, prop_size);
3257 status = GdipGetPropertyItem(image, prop_id[0], 0, &item.data);
3258 ok(status == InvalidParameter || status == GenericError /* Win7 */,
3259 "%u: expected InvalidParameter, got %d\n", i, status);
3260 status = GdipGetPropertyItem(image, prop_id[0], prop_size - 1, &item.data);
3261 ok(status == InvalidParameter || status == GenericError /* Win7 */,
3262 "%u: expected InvalidParameter, got %d\n", i, status);
3263 status = GdipGetPropertyItem(image, prop_id[0], prop_size + 1, &item.data);
3264 ok(status == InvalidParameter || status == GenericError /* Win7 */,
3265 "%u: expected InvalidParameter, got %d\n", i, status);
3266 status = GdipGetPropertyItem(image, prop_id[0], prop_size, &item.data);
3267 expect(Ok, status);
3268 ok(prop_id[0] == item.data.id,
3269 "%u: expected property id %#x, got %#x\n", i, prop_id[0], item.data.id);
3273 GdipDisposeImage(image);
3277 #define IFD_BYTE 1
3278 #define IFD_ASCII 2
3279 #define IFD_SHORT 3
3280 #define IFD_LONG 4
3281 #define IFD_RATIONAL 5
3282 #define IFD_SBYTE 6
3283 #define IFD_UNDEFINED 7
3284 #define IFD_SSHORT 8
3285 #define IFD_SLONG 9
3286 #define IFD_SRATIONAL 10
3287 #define IFD_FLOAT 11
3288 #define IFD_DOUBLE 12
3290 #ifndef PropertyTagTypeSByte
3291 #define PropertyTagTypeSByte 6
3292 #define PropertyTagTypeSShort 8
3293 #define PropertyTagTypeFloat 11
3294 #define PropertyTagTypeDouble 12
3295 #endif
3297 static UINT documented_type(UINT type)
3299 switch (type)
3301 case PropertyTagTypeSByte: return PropertyTagTypeByte;
3302 case PropertyTagTypeSShort: return PropertyTagTypeShort;
3303 case PropertyTagTypeFloat: return PropertyTagTypeUndefined;
3304 case PropertyTagTypeDouble: return PropertyTagTypeUndefined;
3305 default: return type;
3309 #include "pshpack2.h"
3310 struct IFD_entry
3312 SHORT id;
3313 SHORT type;
3314 ULONG count;
3315 LONG value;
3318 struct IFD_rational
3320 LONG numerator;
3321 LONG denominator;
3324 static const struct tiff_data
3326 USHORT byte_order;
3327 USHORT version;
3328 ULONG dir_offset;
3329 USHORT number_of_entries;
3330 struct IFD_entry entry[40];
3331 ULONG next_IFD;
3332 struct IFD_rational xres;
3333 DOUBLE double_val;
3334 struct IFD_rational srational_val;
3335 char string[14];
3336 SHORT short_val[4];
3337 LONG long_val[2];
3338 FLOAT float_val[2];
3339 struct IFD_rational rational[3];
3340 BYTE pixel_data[4];
3341 } TIFF_data =
3343 #ifdef WORDS_BIGENDIAN
3344 'M' | 'M' << 8,
3345 #else
3346 'I' | 'I' << 8,
3347 #endif
3349 FIELD_OFFSET(struct tiff_data, number_of_entries),
3352 { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */
3353 { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */
3354 { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */
3355 { 0x102, IFD_SHORT, 1, 1 }, /* BITSPERSAMPLE */
3356 { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
3357 { 0x106, IFD_SHORT, 1, 1 }, /* PHOTOMETRIC */
3358 { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_data, pixel_data) }, /* STRIPOFFSETS */
3359 { 0x115, IFD_SHORT, 1, 1 }, /* SAMPLESPERPIXEL */
3360 { 0x116, IFD_LONG, 1, 1 }, /* ROWSPERSTRIP */
3361 { 0x117, IFD_LONG, 1, 1 }, /* STRIPBYTECOUNT */
3362 { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_data, xres) },
3363 { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_data, xres) },
3364 { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */
3365 { 0xf001, IFD_BYTE, 1, 0x11223344 },
3366 { 0xf002, IFD_BYTE, 4, 0x11223344 },
3367 { 0xf003, IFD_SBYTE, 1, 0x11223344 },
3368 { 0xf004, IFD_SSHORT, 1, 0x11223344 },
3369 { 0xf005, IFD_SSHORT, 2, 0x11223344 },
3370 { 0xf006, IFD_SLONG, 1, 0x11223344 },
3371 { 0xf007, IFD_FLOAT, 1, 0x11223344 },
3372 { 0xf008, IFD_DOUBLE, 1, FIELD_OFFSET(struct tiff_data, double_val) },
3373 { 0xf009, IFD_SRATIONAL, 1, FIELD_OFFSET(struct tiff_data, srational_val) },
3374 { 0xf00a, IFD_BYTE, 13, FIELD_OFFSET(struct tiff_data, string) },
3375 { 0xf00b, IFD_SSHORT, 4, FIELD_OFFSET(struct tiff_data, short_val) },
3376 { 0xf00c, IFD_SLONG, 2, FIELD_OFFSET(struct tiff_data, long_val) },
3377 { 0xf00e, IFD_ASCII, 13, FIELD_OFFSET(struct tiff_data, string) },
3378 { 0xf00f, IFD_ASCII, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3379 { 0xf010, IFD_UNDEFINED, 13, FIELD_OFFSET(struct tiff_data, string) },
3380 { 0xf011, IFD_UNDEFINED, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3381 /* Some gdiplus versions ignore these fields.
3382 { 0xf012, IFD_BYTE, 0, 0x11223344 },
3383 { 0xf013, IFD_SHORT, 0, 0x11223344 },
3384 { 0xf014, IFD_LONG, 0, 0x11223344 },
3385 { 0xf015, IFD_FLOAT, 0, 0x11223344 },*/
3386 { 0xf016, IFD_SRATIONAL, 3, FIELD_OFFSET(struct tiff_data, rational) },
3387 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3388 { 0xf017, IFD_FLOAT, 2, FIELD_OFFSET(struct tiff_data, float_val) },
3391 { 900, 3 },
3392 1234567890.0987654321,
3393 { 0x1a2b3c4d, 0x5a6b7c8d },
3394 "Hello World!",
3395 { 0x0101, 0x0202, 0x0303, 0x0404 },
3396 { 0x11223344, 0x55667788 },
3397 { (FLOAT)1234.5678, (FLOAT)8765.4321 },
3398 { { 0x01020304, 0x05060708 }, { 0x10203040, 0x50607080 }, { 0x11223344, 0x55667788 } },
3399 { 0x11, 0x22, 0x33, 0 }
3401 #include "poppack.h"
3403 static void test_tiff_properties(void)
3405 static const struct test_data
3407 ULONG type, id, length;
3408 const BYTE value[24];
3409 } td[31] =
3411 { PropertyTagTypeShort, 0xff, 2, { 0 } },
3412 { PropertyTagTypeLong, 0x100, 4, { 1 } },
3413 { PropertyTagTypeLong, 0x101, 4, { 1 } },
3414 { PropertyTagTypeShort, 0x102, 2, { 1 } },
3415 { PropertyTagTypeShort, 0x103, 2, { 1 } },
3416 { PropertyTagTypeShort, 0x106, 2, { 1 } },
3417 { PropertyTagTypeLong, 0x111, 4, { 0x44,0x02 } },
3418 { PropertyTagTypeShort, 0x115, 2, { 1 } },
3419 { PropertyTagTypeLong, 0x116, 4, { 1 } },
3420 { PropertyTagTypeLong, 0x117, 4, { 1 } },
3421 { PropertyTagTypeRational, 0x11a, 8, { 0x84,0x03,0,0,0x03 } },
3422 { PropertyTagTypeRational, 0x11b, 8, { 0x84,0x03,0,0,0x03 } },
3423 { PropertyTagTypeShort, 0x128, 2, { 2 } },
3424 { PropertyTagTypeByte, 0xf001, 1, { 0x44 } },
3425 { PropertyTagTypeByte, 0xf002, 4, { 0x44,0x33,0x22,0x11 } },
3426 { PropertyTagTypeSByte, 0xf003, 1, { 0x44 } },
3427 { PropertyTagTypeSShort, 0xf004, 2, { 0x44,0x33 } },
3428 { PropertyTagTypeSShort, 0xf005, 4, { 0x44,0x33,0x22,0x11 } },
3429 { PropertyTagTypeSLONG, 0xf006, 4, { 0x44,0x33,0x22,0x11 } },
3430 { PropertyTagTypeFloat, 0xf007, 4, { 0x44,0x33,0x22,0x11 } },
3431 { PropertyTagTypeDouble, 0xf008, 8, { 0x2c,0x52,0x86,0xb4,0x80,0x65,0xd2,0x41 } },
3432 { PropertyTagTypeSRational, 0xf009, 8, { 0x4d, 0x3c, 0x2b, 0x1a, 0x8d, 0x7c, 0x6b, 0x5a } },
3433 { PropertyTagTypeByte, 0xf00a, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3434 { PropertyTagTypeSShort, 0xf00b, 8, { 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04 } },
3435 { PropertyTagTypeSLONG, 0xf00c, 8, { 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3436 { PropertyTagTypeASCII, 0xf00e, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3437 { PropertyTagTypeASCII, 0xf00f, 5, { 'a','b','c','d' } },
3438 { PropertyTagTypeUndefined, 0xf010, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3439 { PropertyTagTypeUndefined, 0xf011, 4, { 'a','b','c','d' } },
3440 { PropertyTagTypeSRational, 0xf016, 24,
3441 { 0x04,0x03,0x02,0x01,0x08,0x07,0x06,0x05,
3442 0x40,0x30,0x20,0x10,0x80,0x70,0x60,0x50,
3443 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3444 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3445 { PropertyTagTypeFloat, 0xf017, 8, { 0x2b,0x52,0x9a,0x44,0xba,0xf5,0x08,0x46 } },
3447 GpStatus status;
3448 GpImage *image;
3449 GUID guid;
3450 UINT dim_count, frame_count, prop_count, prop_size, i;
3451 PROPID *prop_id;
3452 PropertyItem *prop_item;
3454 image = load_image((const BYTE *)&TIFF_data, sizeof(TIFF_data));
3455 if (!image)
3457 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3458 return;
3461 status = GdipImageGetFrameDimensionsCount(image, &dim_count);
3462 expect(Ok, status);
3463 expect(1, dim_count);
3465 status = GdipImageGetFrameDimensionsList(image, &guid, 1);
3466 expect(Ok, status);
3467 expect_guid(&FrameDimensionPage, &guid, __LINE__, FALSE);
3469 frame_count = 0xdeadbeef;
3470 status = GdipImageGetFrameCount(image, &guid, &frame_count);
3471 expect(Ok, status);
3472 expect(1, frame_count);
3474 prop_count = 0xdeadbeef;
3475 status = GdipGetPropertyCount(image, &prop_count);
3476 expect(Ok, status);
3477 ok(prop_count == sizeof(td)/sizeof(td[0]) ||
3478 broken(prop_count == sizeof(td)/sizeof(td[0]) - 1) /* Win7 SP0 */,
3479 "expected property count %u, got %u\n", (UINT)(sizeof(td)/sizeof(td[0])), prop_count);
3481 prop_id = HeapAlloc(GetProcessHeap(), 0, prop_count * sizeof(*prop_id));
3483 status = GdipGetPropertyIdList(image, prop_count, prop_id);
3484 expect(Ok, status);
3486 for (i = 0; i < prop_count; i++)
3488 status = GdipGetPropertyItemSize(image, prop_id[i], &prop_size);
3489 expect(Ok, status);
3490 if (status != Ok) break;
3491 ok(prop_size > sizeof(*prop_item), "%u: too small item length %u\n", i, prop_size);
3493 prop_item = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, prop_size);
3494 status = GdipGetPropertyItem(image, prop_id[i], prop_size, prop_item);
3495 expect(Ok, status);
3496 ok(prop_item->value == prop_item + 1, "expected item->value %p, got %p\n", prop_item + 1, prop_item->value);
3497 ok(td[i].type == prop_item->type ||
3498 /* Win7 stopped using proper but not documented types, and it
3499 looks broken since TypeFloat and TypeDouble now reported as
3500 TypeUndefined, and signed types reported as unsigned. */
3501 broken(prop_item->type == documented_type(td[i].type)),
3502 "%u: expected type %u, got %u\n", i, td[i].type, prop_item->type);
3503 ok(td[i].id == prop_item->id, "%u: expected id %#x, got %#x\n", i, td[i].id, prop_item->id);
3504 prop_size -= sizeof(*prop_item);
3505 ok(prop_item->length == prop_size, "%u: expected length %u, got %u\n", i, prop_size, prop_item->length);
3506 ok(td[i].length == prop_item->length || broken(td[i].id == 0xf00f && td[i].length == prop_item->length+1) /* XP */,
3507 "%u: expected length %u, got %u\n", i, td[i].length, prop_item->length);
3508 ok(td[i].length == prop_size || broken(td[i].id == 0xf00f && td[i].length == prop_size+1) /* XP */,
3509 "%u: expected length %u, got %u\n", i, td[i].length, prop_size);
3510 if (td[i].length == prop_item->length)
3512 int match = memcmp(td[i].value, prop_item->value, td[i].length) == 0;
3513 ok(match || broken(td[i].length <= 4 && !match), "%u: data mismatch\n", i);
3514 if (!match)
3516 UINT j;
3517 BYTE *data = prop_item->value;
3518 trace("id %#x:", prop_item->id);
3519 for (j = 0; j < prop_item->length; j++)
3520 trace(" %02x", data[j]);
3521 trace("\n");
3524 HeapFree(GetProcessHeap(), 0, prop_item);
3527 HeapFree(GetProcessHeap(), 0, prop_id);
3529 GdipDisposeImage(image);
3532 static void test_GdipGetAllPropertyItems(void)
3534 static const struct test_data
3536 ULONG type, id, length;
3537 BYTE value[32];
3538 } td[16] =
3540 { PropertyTagTypeLong, 0xfe, 4, { 0 } },
3541 { PropertyTagTypeShort, 0x100, 2, { 1 } },
3542 { PropertyTagTypeShort, 0x101, 2, { 1 } },
3543 { PropertyTagTypeShort, 0x102, 6, { 8,0,8,0,8,0 } },
3544 { PropertyTagTypeShort, 0x103, 2, { 1 } },
3545 { PropertyTagTypeShort, 0x106, 2, { 2,0 } },
3546 { PropertyTagTypeASCII, 0x10d, 27, "/home/meh/Desktop/test.tif" },
3547 { PropertyTagTypeLong, 0x111, 4, { 8,0,0,0 } },
3548 { PropertyTagTypeShort, 0x112, 2, { 1 } },
3549 { PropertyTagTypeShort, 0x115, 2, { 3,0 } },
3550 { PropertyTagTypeShort, 0x116, 2, { 0x40,0 } },
3551 { PropertyTagTypeLong, 0x117, 4, { 3,0,0,0 } },
3552 { PropertyTagTypeRational, 0x11a, 8, { 0,0,0,72,0,0,0,1 } },
3553 { PropertyTagTypeRational, 0x11b, 8, { 0,0,0,72,0,0,0,1 } },
3554 { PropertyTagTypeShort, 0x11c, 2, { 1 } },
3555 { PropertyTagTypeShort, 0x128, 2, { 2 } }
3557 GpStatus status;
3558 GpImage *image;
3559 GUID guid;
3560 UINT dim_count, frame_count, prop_count, prop_size, i;
3561 UINT total_size, total_count;
3562 PROPID *prop_id;
3563 PropertyItem *prop_item;
3564 const char *item_data;
3566 image = load_image(tiffimage, sizeof(tiffimage));
3567 ok(image != 0, "Failed to load TIFF image data\n");
3568 if (!image) return;
3570 dim_count = 0xdeadbeef;
3571 status = GdipImageGetFrameDimensionsCount(image, &dim_count);
3572 expect(Ok, status);
3573 expect(1, dim_count);
3575 status = GdipImageGetFrameDimensionsList(image, &guid, 1);
3576 expect(Ok, status);
3577 expect_guid(&FrameDimensionPage, &guid, __LINE__, FALSE);
3579 frame_count = 0xdeadbeef;
3580 status = GdipImageGetFrameCount(image, &guid, &frame_count);
3581 expect(Ok, status);
3582 expect(1, frame_count);
3584 prop_count = 0xdeadbeef;
3585 status = GdipGetPropertyCount(image, &prop_count);
3586 expect(Ok, status);
3587 ok(prop_count == sizeof(td)/sizeof(td[0]),
3588 "expected property count %u, got %u\n", (UINT)(sizeof(td)/sizeof(td[0])), prop_count);
3590 prop_id = HeapAlloc(GetProcessHeap(), 0, prop_count * sizeof(*prop_id));
3592 status = GdipGetPropertyIdList(image, prop_count, prop_id);
3593 expect(Ok, status);
3595 prop_size = 0;
3596 for (i = 0; i < prop_count; i++)
3598 UINT size;
3599 status = GdipGetPropertyItemSize(image, prop_id[i], &size);
3600 expect(Ok, status);
3601 if (status != Ok) break;
3602 ok(size > sizeof(*prop_item), "%u: too small item length %u\n", i, size);
3604 prop_size += size;
3606 prop_item = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
3607 status = GdipGetPropertyItem(image, prop_id[i], size, prop_item);
3608 expect(Ok, status);
3609 ok(prop_item->value == prop_item + 1, "expected item->value %p, got %p\n", prop_item + 1, prop_item->value);
3610 ok(td[i].type == prop_item->type,
3611 "%u: expected type %u, got %u\n", i, td[i].type, prop_item->type);
3612 ok(td[i].id == prop_item->id, "%u: expected id %#x, got %#x\n", i, td[i].id, prop_item->id);
3613 size -= sizeof(*prop_item);
3614 ok(prop_item->length == size, "%u: expected length %u, got %u\n", i, size, prop_item->length);
3615 ok(td[i].length == prop_item->length, "%u: expected length %u, got %u\n", i, td[i].length, prop_item->length);
3616 if (td[i].length == prop_item->length)
3618 int match = memcmp(td[i].value, prop_item->value, td[i].length) == 0;
3619 ok(match, "%u: data mismatch\n", i);
3620 if (!match)
3622 UINT j;
3623 BYTE *data = prop_item->value;
3624 trace("id %#x:", prop_item->id);
3625 for (j = 0; j < prop_item->length; j++)
3626 trace(" %02x", data[j]);
3627 trace("\n");
3630 HeapFree(GetProcessHeap(), 0, prop_item);
3633 HeapFree(GetProcessHeap(), 0, prop_id);
3635 status = GdipGetPropertySize(NULL, &total_size, &total_count);
3636 expect(InvalidParameter, status);
3637 status = GdipGetPropertySize(image, &total_size, NULL);
3638 expect(InvalidParameter, status);
3639 status = GdipGetPropertySize(image, NULL, &total_count);
3640 expect(InvalidParameter, status);
3641 status = GdipGetPropertySize(image, NULL, NULL);
3642 expect(InvalidParameter, status);
3643 total_size = 0xdeadbeef;
3644 total_count = 0xdeadbeef;
3645 status = GdipGetPropertySize(image, &total_size, &total_count);
3646 expect(Ok, status);
3647 ok(prop_count == total_count,
3648 "expected total property count %u, got %u\n", prop_count, total_count);
3649 ok(prop_size == total_size,
3650 "expected total property size %u, got %u\n", prop_size, total_size);
3652 prop_item = HeapAlloc(GetProcessHeap(), 0, prop_size);
3654 status = GdipGetAllPropertyItems(image, 0, prop_count, prop_item);
3655 expect(InvalidParameter, status);
3656 status = GdipGetAllPropertyItems(image, prop_size, 1, prop_item);
3657 expect(InvalidParameter, status);
3658 status = GdipGetAllPropertyItems(image, prop_size, prop_count, NULL);
3659 expect(InvalidParameter, status);
3660 status = GdipGetAllPropertyItems(image, prop_size, prop_count, NULL);
3661 expect(InvalidParameter, status);
3662 status = GdipGetAllPropertyItems(image, 0, 0, NULL);
3663 expect(InvalidParameter, status);
3664 status = GdipGetAllPropertyItems(image, prop_size + 1, prop_count, prop_item);
3665 expect(InvalidParameter, status);
3666 status = GdipGetAllPropertyItems(image, prop_size, prop_count, prop_item);
3667 expect(Ok, status);
3669 item_data = (const char *)(prop_item + prop_count);
3670 for (i = 0; i < prop_count; i++)
3672 ok(prop_item[i].value == item_data, "%u: expected value %p, got %p\n",
3673 i, item_data, prop_item[i].value);
3674 ok(td[i].type == prop_item[i].type,
3675 "%u: expected type %u, got %u\n", i, td[i].type, prop_item[i].type);
3676 ok(td[i].id == prop_item[i].id, "%u: expected id %#x, got %#x\n", i, td[i].id, prop_item[i].id);
3677 ok(td[i].length == prop_item[i].length, "%u: expected length %u, got %u\n", i, td[i].length, prop_item[i].length);
3678 if (td[i].length == prop_item[i].length)
3680 int match = memcmp(td[i].value, prop_item[i].value, td[i].length) == 0;
3681 ok(match, "%u: data mismatch\n", i);
3682 if (!match)
3684 UINT j;
3685 BYTE *data = prop_item[i].value;
3686 trace("id %#x:", prop_item[i].id);
3687 for (j = 0; j < prop_item[i].length; j++)
3688 trace(" %02x", data[j]);
3689 trace("\n");
3692 item_data += prop_item[i].length;
3695 HeapFree(GetProcessHeap(), 0, prop_item);
3697 GdipDisposeImage(image);
3700 static void test_tiff_palette(void)
3702 GpStatus status;
3703 GpImage *image;
3704 PixelFormat format;
3705 INT size;
3706 struct
3708 ColorPalette pal;
3709 ARGB entry[256];
3710 } palette;
3711 ARGB *entries = palette.pal.Entries;
3713 /* 1bpp TIFF without palette */
3714 image = load_image((const BYTE *)&TIFF_data, sizeof(TIFF_data));
3715 if (!image)
3717 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3718 return;
3721 status = GdipGetImagePixelFormat(image, &format);
3722 expect(Ok, status);
3723 ok(format == PixelFormat1bppIndexed, "expected PixelFormat1bppIndexed, got %#x\n", format);
3725 status = GdipGetImagePaletteSize(image, &size);
3726 ok(status == Ok || broken(status == GenericError), /* XP */
3727 "GdipGetImagePaletteSize error %d\n", status);
3728 if (status == GenericError)
3730 GdipDisposeImage(image);
3731 return;
3733 expect(sizeof(ColorPalette) + sizeof(ARGB), size);
3735 status = GdipGetImagePalette(image, &palette.pal, size);
3736 expect(Ok, status);
3737 expect(0, palette.pal.Flags);
3738 expect(2, palette.pal.Count);
3739 if (palette.pal.Count == 2)
3741 ok(entries[0] == 0xff000000, "expected 0xff000000, got %#x\n", entries[0]);
3742 ok(entries[1] == 0xffffffff, "expected 0xffffffff, got %#x\n", entries[1]);
3745 GdipDisposeImage(image);
3748 static void test_bitmapbits(void)
3750 /* 8 x 2 bitmap */
3751 static const BYTE pixels_24[48] =
3753 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3754 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3755 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3756 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0
3758 static const BYTE pixels_00[48] =
3760 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3761 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3762 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3763 0,0,0, 0,0,0, 0,0,0, 0,0,0
3765 static const BYTE pixels_24_77[64] =
3767 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3768 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3769 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3770 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3771 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3772 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3774 static const BYTE pixels_77[64] =
3776 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3777 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3778 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3779 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3780 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3781 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3782 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3783 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3785 static const BYTE pixels_8[16] =
3787 0x01,0,0x01,0,0x01,0,0x01,0,
3788 0x01,0,0x01,0,0x01,0,0x01,0
3790 static const BYTE pixels_8_77[64] =
3792 0x01,0,0x01,0,0x01,0,0x01,0,
3793 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3794 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3795 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3796 0x01,0,0x01,0,0x01,0,0x01,0,
3797 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3798 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3799 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3801 static const BYTE pixels_1_77[64] =
3803 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3804 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3805 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3806 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3807 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3808 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3809 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3810 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3812 static const BYTE pixels_1[8] = {0xaa,0,0,0,0xaa,0,0,0};
3813 static const struct test_data
3815 PixelFormat format;
3816 UINT bpp;
3817 ImageLockMode mode;
3818 UINT stride, size;
3819 const BYTE *pixels;
3820 const BYTE *pixels_unlocked;
3821 } td[] =
3823 /* 0 */
3824 { PixelFormat24bppRGB, 24, 0xfff0, 24, 48, pixels_24, pixels_00 },
3826 { PixelFormat24bppRGB, 24, 0, 24, 48, pixels_24, pixels_00 },
3827 { PixelFormat24bppRGB, 24, ImageLockModeRead, 24, 48, pixels_24, pixels_00 },
3828 { PixelFormat24bppRGB, 24, ImageLockModeWrite, 24, 48, pixels_24, pixels_00 },
3829 { PixelFormat24bppRGB, 24, ImageLockModeRead|ImageLockModeWrite, 24, 48, pixels_24, pixels_00 },
3830 { PixelFormat24bppRGB, 24, ImageLockModeRead|ImageLockModeUserInputBuf, 32, 64, pixels_24_77, pixels_24 },
3831 { PixelFormat24bppRGB, 24, ImageLockModeWrite|ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_00 },
3832 { PixelFormat24bppRGB, 24, ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_24 },
3833 /* 8 */
3834 { PixelFormat8bppIndexed, 8, 0, 8, 16, pixels_8, pixels_24 },
3835 { PixelFormat8bppIndexed, 8, ImageLockModeRead, 8, 16, pixels_8, pixels_24 },
3836 { PixelFormat8bppIndexed, 8, ImageLockModeWrite, 8, 16, pixels_8, pixels_00 },
3837 { PixelFormat8bppIndexed, 8, ImageLockModeRead|ImageLockModeWrite, 8, 16, pixels_8, pixels_00 },
3838 { PixelFormat8bppIndexed, 8, ImageLockModeRead|ImageLockModeUserInputBuf, 32, 64, pixels_8_77, pixels_24 },
3839 { PixelFormat8bppIndexed, 8, ImageLockModeWrite|ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_00 },
3840 { PixelFormat8bppIndexed, 8, ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_24 },
3841 /* 15 */
3842 { PixelFormat1bppIndexed, 1, 0, 4, 8, pixels_1, pixels_24 },
3843 { PixelFormat1bppIndexed, 1, ImageLockModeRead, 4, 8, pixels_1, pixels_24 },
3844 { PixelFormat1bppIndexed, 1, ImageLockModeWrite, 4, 8, pixels_1, pixels_00 },
3845 { PixelFormat1bppIndexed, 1, ImageLockModeRead|ImageLockModeWrite, 4, 8, pixels_1, pixels_00 },
3846 { PixelFormat1bppIndexed, 1, ImageLockModeRead|ImageLockModeUserInputBuf, 32, 64, pixels_1_77, pixels_24 },
3847 { PixelFormat1bppIndexed, 1, ImageLockModeWrite|ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_00 },
3848 { PixelFormat1bppIndexed, 1, ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_24 },
3850 BYTE buf[64];
3851 GpStatus status;
3852 GpBitmap *bitmap;
3853 UINT i;
3854 BitmapData data;
3855 struct
3857 ColorPalette pal;
3858 ARGB entries[1];
3859 } palette;
3860 ARGB *entries = palette.pal.Entries;
3862 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
3864 BYTE pixels[sizeof(pixels_24)];
3865 memcpy(pixels, pixels_24, sizeof(pixels_24));
3866 status = GdipCreateBitmapFromScan0(8, 2, 24, PixelFormat24bppRGB, pixels, &bitmap);
3867 expect(Ok, status);
3869 /* associate known palette with pixel data */
3870 palette.pal.Flags = PaletteFlagsGrayScale;
3871 palette.pal.Count = 2;
3872 entries[0] = 0xff000000;
3873 entries[1] = 0xffffffff;
3874 status = GdipSetImagePalette((GpImage *)bitmap, &palette.pal);
3875 expect(Ok, status);
3877 memset(&data, 0xfe, sizeof(data));
3878 if (td[i].mode & ImageLockModeUserInputBuf)
3880 memset(buf, 0x77, sizeof(buf));
3881 data.Scan0 = buf;
3882 data.Stride = 32;
3884 status = GdipBitmapLockBits(bitmap, NULL, td[i].mode, td[i].format, &data);
3885 ok(status == Ok || broken(status == InvalidParameter) /* XP */, "%u: GdipBitmapLockBits error %d\n", i, status);
3886 if (status != Ok)
3888 GdipDisposeImage((GpImage *)bitmap);
3889 continue;
3891 ok(data.Width == 8, "%u: expected 8, got %d\n", i, data.Width);
3892 ok(data.Height == 2, "%u: expected 2, got %d\n", i, data.Height);
3893 ok(td[i].stride == data.Stride, "%u: expected %d, got %d\n", i, td[i].stride, data.Stride);
3894 ok(td[i].format == data.PixelFormat, "%u: expected %d, got %d\n", i, td[i].format, data.PixelFormat);
3895 ok(td[i].size == data.Height * data.Stride, "%u: expected %d, got %d\n", i, td[i].size, data.Height * data.Stride);
3896 if (td[i].mode & ImageLockModeUserInputBuf)
3897 ok(data.Scan0 == buf, "%u: got wrong buffer\n", i);
3898 if (td[i].size == data.Height * data.Stride)
3900 UINT j, match, width_bytes = (data.Width * td[i].bpp) / 8;
3902 match = 1;
3903 for (j = 0; j < data.Height; j++)
3905 if (memcmp((const BYTE *)data.Scan0 + j * data.Stride, td[i].pixels + j * data.Stride, width_bytes) != 0)
3907 match = 0;
3908 break;
3911 if ((td[i].mode & (ImageLockModeRead|ImageLockModeUserInputBuf)) || td[i].format == PixelFormat24bppRGB)
3913 ok(match,
3914 "%u: data should match\n", i);
3915 if (!match)
3917 BYTE *bits = data.Scan0;
3918 trace("%u: data mismatch for format %#x:", i, td[i].format);
3919 for (j = 0; j < td[i].size; j++)
3920 trace(" %02x", bits[j]);
3921 trace("\n");
3924 else
3925 ok(!match, "%u: data shouldn't match\n", i);
3927 memset(data.Scan0, 0, td[i].size);
3930 status = GdipBitmapUnlockBits(bitmap, &data);
3931 ok(status == Ok, "%u: GdipBitmapUnlockBits error %d\n", i, status);
3933 memset(&data, 0xfe, sizeof(data));
3934 status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat24bppRGB, &data);
3935 ok(status == Ok, "%u: GdipBitmapLockBits error %d\n", i, status);
3936 ok(data.Width == 8, "%u: expected 8, got %d\n", i, data.Width);
3937 ok(data.Height == 2, "%u: expected 2, got %d\n", i, data.Height);
3938 ok(data.Stride == 24, "%u: expected 24, got %d\n", i, data.Stride);
3939 ok(data.PixelFormat == PixelFormat24bppRGB, "%u: got wrong pixel format %d\n", i, data.PixelFormat);
3940 ok(data.Height * data.Stride == 48, "%u: expected 48, got %d\n", i, data.Height * data.Stride);
3941 if (data.Height * data.Stride == 48)
3943 int match = memcmp(data.Scan0, td[i].pixels_unlocked, 48) == 0;
3944 ok(match, "%u: data should match\n", i);
3945 if (!match)
3947 UINT j;
3948 BYTE *bits = data.Scan0;
3949 trace("%u: data mismatch for format %#x:", i, td[i].format);
3950 for (j = 0; j < 48; j++)
3951 trace(" %02x", bits[j]);
3952 trace("\n");
3956 status = GdipBitmapUnlockBits(bitmap, &data);
3957 ok(status == Ok, "%u: GdipBitmapUnlockBits error %d\n", i, status);
3959 status = GdipDisposeImage((GpImage *)bitmap);
3960 expect(Ok, status);
3964 static void test_DrawImage(void)
3966 BYTE black_1x1[4] = { 0,0,0,0 };
3967 BYTE white_2x2[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
3968 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
3969 BYTE black_2x2[16] = { 0,0,0,0,0,0,0xff,0xff,
3970 0,0,0,0,0,0,0xff,0xff };
3971 GpStatus status;
3972 union
3974 GpBitmap *bitmap;
3975 GpImage *image;
3976 } u1, u2;
3977 GpGraphics *graphics;
3978 int match;
3980 status = GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB, black_1x1, &u1.bitmap);
3981 expect(Ok, status);
3982 status = GdipBitmapSetResolution(u1.bitmap, 100.0, 100.0);
3983 expect(Ok, status);
3985 status = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB, white_2x2, &u2.bitmap);
3986 expect(Ok, status);
3987 status = GdipBitmapSetResolution(u2.bitmap, 300.0, 300.0);
3988 expect(Ok, status);
3989 status = GdipGetImageGraphicsContext(u2.image, &graphics);
3990 expect(Ok, status);
3991 status = GdipSetInterpolationMode(graphics, InterpolationModeNearestNeighbor);
3992 expect(Ok, status);
3994 status = GdipDrawImageI(graphics, u1.image, 0, 0);
3995 expect(Ok, status);
3997 match = memcmp(white_2x2, black_2x2, sizeof(black_2x2)) == 0;
3998 ok(match, "data should match\n");
3999 if (!match)
4001 UINT i, size = sizeof(white_2x2);
4002 BYTE *bits = white_2x2;
4003 for (i = 0; i < size; i++)
4004 trace(" %02x", bits[i]);
4005 trace("\n");
4008 status = GdipDeleteGraphics(graphics);
4009 expect(Ok, status);
4010 status = GdipDisposeImage(u1.image);
4011 expect(Ok, status);
4012 status = GdipDisposeImage(u2.image);
4013 expect(Ok, status);
4016 static void test_DrawImage_SourceCopy(void)
4018 DWORD dst_pixels[4] = { 0xffffffff, 0xffffffff,
4019 0xffffffff, 0xffffffff };
4020 DWORD src_pixels[4] = { 0, 0xffff0000,
4021 0, 0xff00ff };
4023 GpStatus status;
4024 union
4026 GpBitmap *bitmap;
4027 GpImage *image;
4028 } u1, u2;
4029 GpGraphics *graphics;
4031 status = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB, (BYTE*)dst_pixels, &u1.bitmap);
4032 expect(Ok, status);
4034 status = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB, (BYTE*)src_pixels, &u2.bitmap);
4035 expect(Ok, status);
4036 status = GdipGetImageGraphicsContext(u1.image, &graphics);
4037 expect(Ok, status);
4038 status = GdipSetInterpolationMode(graphics, InterpolationModeNearestNeighbor);
4039 expect(Ok, status);
4041 status = GdipSetCompositingMode(graphics, CompositingModeSourceCopy);
4042 expect(Ok, status);
4044 status = GdipDrawImageI(graphics, u2.image, 0, 0);
4045 expect(Ok, status);
4047 todo_wine expect(0, dst_pixels[0]);
4048 expect(0xffff0000, dst_pixels[1]);
4049 todo_wine expect(0, dst_pixels[2]);
4050 todo_wine expect(0, dst_pixels[3]);
4052 status = GdipDeleteGraphics(graphics);
4053 expect(Ok, status);
4054 status = GdipDisposeImage(u1.image);
4055 expect(Ok, status);
4056 status = GdipDisposeImage(u2.image);
4057 expect(Ok, status);
4060 static void test_GdipDrawImagePointRect(void)
4062 BYTE black_1x1[4] = { 0,0,0,0 };
4063 BYTE white_2x2[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
4064 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
4065 BYTE black_2x2[16] = { 0,0,0,0,0,0,0xff,0xff,
4066 0,0,0,0,0,0,0xff,0xff };
4067 GpStatus status;
4068 union
4070 GpBitmap *bitmap;
4071 GpImage *image;
4072 } u1, u2;
4073 GpGraphics *graphics;
4074 int match;
4076 status = GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB, black_1x1, &u1.bitmap);
4077 expect(Ok, status);
4078 status = GdipBitmapSetResolution(u1.bitmap, 100.0, 100.0);
4079 expect(Ok, status);
4081 status = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB, white_2x2, &u2.bitmap);
4082 expect(Ok, status);
4083 status = GdipBitmapSetResolution(u2.bitmap, 300.0, 300.0);
4084 expect(Ok, status);
4085 status = GdipGetImageGraphicsContext(u2.image, &graphics);
4086 expect(Ok, status);
4087 status = GdipSetInterpolationMode(graphics, InterpolationModeNearestNeighbor);
4088 expect(Ok, status);
4090 status = GdipDrawImagePointRectI(graphics, u1.image, 0, 0, 0, 0, 1, 1, UnitPixel);
4091 expect(Ok, status);
4093 match = memcmp(white_2x2, black_2x2, sizeof(black_2x2)) == 0;
4094 ok(match, "data should match\n");
4095 if (!match)
4097 UINT i, size = sizeof(white_2x2);
4098 BYTE *bits = white_2x2;
4099 for (i = 0; i < size; i++)
4100 trace(" %02x", bits[i]);
4101 trace("\n");
4104 status = GdipDeleteGraphics(graphics);
4105 expect(Ok, status);
4106 status = GdipDisposeImage(u1.image);
4107 expect(Ok, status);
4108 status = GdipDisposeImage(u2.image);
4109 expect(Ok, status);
4112 static void test_image_format(void)
4114 static const PixelFormat fmt[] =
4116 PixelFormat1bppIndexed, PixelFormat4bppIndexed, PixelFormat8bppIndexed,
4117 PixelFormat16bppGrayScale, PixelFormat16bppRGB555, PixelFormat16bppRGB565,
4118 PixelFormat16bppARGB1555, PixelFormat24bppRGB, PixelFormat32bppRGB,
4119 PixelFormat32bppARGB, PixelFormat32bppPARGB, PixelFormat48bppRGB,
4120 PixelFormat64bppARGB, PixelFormat64bppPARGB, PixelFormat32bppCMYK
4122 GpStatus status;
4123 GpBitmap *bitmap;
4124 GpImage *thumb;
4125 HBITMAP hbitmap;
4126 BITMAP bm;
4127 PixelFormat format;
4128 BitmapData data;
4129 UINT i, ret;
4131 for (i = 0; i < sizeof(fmt)/sizeof(fmt[0]); i++)
4133 status = GdipCreateBitmapFromScan0(1, 1, 0, fmt[i], NULL, &bitmap);
4134 ok(status == Ok || broken(status == InvalidParameter) /* before win7 */,
4135 "GdipCreateBitmapFromScan0 error %d\n", status);
4136 if (status != Ok) continue;
4138 status = GdipGetImagePixelFormat((GpImage *)bitmap, &format);
4139 expect(Ok, status);
4140 expect(fmt[i], format);
4142 status = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0);
4143 if (fmt[i] == PixelFormat16bppGrayScale || fmt[i] == PixelFormat32bppCMYK)
4144 todo_wine expect(InvalidParameter, status);
4145 else
4147 expect(Ok, status);
4148 ret = GetObjectW(hbitmap, sizeof(bm), &bm);
4149 expect(sizeof(bm), ret);
4150 expect(0, bm.bmType);
4151 expect(1, bm.bmWidth);
4152 expect(1, bm.bmHeight);
4153 expect(4, bm.bmWidthBytes);
4154 expect(1, bm.bmPlanes);
4155 expect(32, bm.bmBitsPixel);
4156 DeleteObject(hbitmap);
4159 status = GdipGetImageThumbnail((GpImage *)bitmap, 0, 0, &thumb, NULL, NULL);
4160 if (fmt[i] == PixelFormat16bppGrayScale || fmt[i] == PixelFormat32bppCMYK)
4161 todo_wine
4162 ok(status == OutOfMemory || broken(status == InvalidParameter) /* before win7 */,
4163 "expected OutOfMemory, got %d\n", status);
4164 else
4165 expect(Ok, status);
4166 if (status == Ok)
4168 status = GdipGetImagePixelFormat(thumb, &format);
4169 expect(Ok, status);
4170 ok(format == PixelFormat32bppPARGB || broken(format != PixelFormat32bppPARGB) /* before win7 */,
4171 "expected PixelFormat32bppPARGB, got %#x\n", format);
4172 status = GdipDisposeImage(thumb);
4173 expect(Ok, status);
4176 status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat32bppPARGB, &data);
4177 if (fmt[i] == PixelFormat16bppGrayScale || fmt[i] == PixelFormat32bppCMYK)
4178 todo_wine expect(InvalidParameter, status);
4179 else
4181 expect(Ok, status);
4182 status = GdipBitmapUnlockBits(bitmap, &data);
4183 expect(Ok, status);
4186 status = GdipDisposeImage((GpImage *)bitmap);
4187 expect(Ok, status);
4191 static void test_DrawImage_scale(void)
4193 static const BYTE back_8x1[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
4194 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4195 static const BYTE image_080[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,
4196 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4197 static const BYTE image_100[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,
4198 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4199 static const BYTE image_120[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,
4200 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4201 static const BYTE image_150[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4202 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4203 static const BYTE image_180[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4204 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4205 static const BYTE image_200[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4206 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4207 static const BYTE image_250[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,
4208 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4209 static const BYTE image_120_half[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4210 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4211 static const BYTE image_150_half[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4212 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4213 static const BYTE image_200_half[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4214 0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40 };
4215 static const BYTE image_250_half[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4216 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4217 static const struct test_data
4219 REAL scale_x;
4220 PixelOffsetMode pixel_offset_mode;
4221 const BYTE *image;
4222 BOOL todo;
4223 } td[] =
4225 { 0.8, PixelOffsetModeNone, image_080 }, /* 0 */
4226 { 1.0, PixelOffsetModeNone, image_100 },
4227 { 1.2, PixelOffsetModeNone, image_120 },
4228 { 1.5, PixelOffsetModeNone, image_150 },
4229 { 1.8, PixelOffsetModeNone, image_180 },
4230 { 2.0, PixelOffsetModeNone, image_200 },
4231 { 2.5, PixelOffsetModeNone, image_250 },
4233 { 0.8, PixelOffsetModeHighSpeed, image_080 }, /* 7 */
4234 { 1.0, PixelOffsetModeHighSpeed, image_100 },
4235 { 1.2, PixelOffsetModeHighSpeed, image_120 },
4236 { 1.5, PixelOffsetModeHighSpeed, image_150 },
4237 { 1.8, PixelOffsetModeHighSpeed, image_180 },
4238 { 2.0, PixelOffsetModeHighSpeed, image_200 },
4239 { 2.5, PixelOffsetModeHighSpeed, image_250 },
4241 { 0.8, PixelOffsetModeHalf, image_080 }, /* 14 */
4242 { 1.0, PixelOffsetModeHalf, image_100 },
4243 { 1.2, PixelOffsetModeHalf, image_120_half, TRUE },
4244 { 1.5, PixelOffsetModeHalf, image_150_half, TRUE },
4245 { 1.8, PixelOffsetModeHalf, image_180 },
4246 { 2.0, PixelOffsetModeHalf, image_200_half, TRUE },
4247 { 2.5, PixelOffsetModeHalf, image_250_half, TRUE },
4249 { 0.8, PixelOffsetModeHighQuality, image_080 }, /* 21 */
4250 { 1.0, PixelOffsetModeHighQuality, image_100 },
4251 { 1.2, PixelOffsetModeHighQuality, image_120_half, TRUE },
4252 { 1.5, PixelOffsetModeHighQuality, image_150_half, TRUE },
4253 { 1.8, PixelOffsetModeHighQuality, image_180 },
4254 { 2.0, PixelOffsetModeHighQuality, image_200_half, TRUE },
4255 { 2.5, PixelOffsetModeHighQuality, image_250_half, TRUE },
4257 BYTE src_2x1[6] = { 0x80,0x80,0x80,0x80,0x80,0x80 };
4258 BYTE dst_8x1[24];
4259 GpStatus status;
4260 union
4262 GpBitmap *bitmap;
4263 GpImage *image;
4264 } u1, u2;
4265 GpGraphics *graphics;
4266 GpMatrix *matrix;
4267 int i, match;
4269 status = GdipCreateBitmapFromScan0(2, 1, 4, PixelFormat24bppRGB, src_2x1, &u1.bitmap);
4270 expect(Ok, status);
4271 status = GdipBitmapSetResolution(u1.bitmap, 100.0, 100.0);
4272 expect(Ok, status);
4274 status = GdipCreateBitmapFromScan0(8, 1, 24, PixelFormat24bppRGB, dst_8x1, &u2.bitmap);
4275 expect(Ok, status);
4276 status = GdipBitmapSetResolution(u2.bitmap, 100.0, 100.0);
4277 expect(Ok, status);
4278 status = GdipGetImageGraphicsContext(u2.image, &graphics);
4279 expect(Ok, status);
4280 status = GdipSetInterpolationMode(graphics, InterpolationModeNearestNeighbor);
4281 expect(Ok, status);
4283 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
4285 status = GdipSetPixelOffsetMode(graphics, td[i].pixel_offset_mode);
4286 expect(Ok, status);
4288 status = GdipCreateMatrix2(td[i].scale_x, 0.0, 0.0, 1.0, 0.0, 0.0, &matrix);
4289 expect(Ok, status);
4290 status = GdipSetWorldTransform(graphics, matrix);
4291 expect(Ok, status);
4292 GdipDeleteMatrix(matrix);
4294 memcpy(dst_8x1, back_8x1, sizeof(dst_8x1));
4295 status = GdipDrawImageI(graphics, u1.image, 1, 0);
4296 expect(Ok, status);
4298 match = memcmp(dst_8x1, td[i].image, sizeof(dst_8x1)) == 0;
4299 todo_wine_if (!match && td[i].todo)
4300 ok(match, "%d: data should match\n", i);
4301 if (!match)
4303 UINT i, size = sizeof(dst_8x1);
4304 const BYTE *bits = dst_8x1;
4305 for (i = 0; i < size; i++)
4306 trace(" %02x", bits[i]);
4307 trace("\n");
4311 status = GdipDeleteGraphics(graphics);
4312 expect(Ok, status);
4313 status = GdipDisposeImage(u1.image);
4314 expect(Ok, status);
4315 status = GdipDisposeImage(u2.image);
4316 expect(Ok, status);
4319 static const BYTE animatedgif[] = {
4320 'G','I','F','8','9','a',0x01,0x00,0x01,0x00,0xA1,0x02,0x00,
4321 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
4322 /*0x21,0xFF,0x0B,'A','N','I','M','E','X','T','S','1','.','0',*/
4323 0x21,0xFF,0x0B,'N','E','T','S','C','A','P','E','2','.','0',
4324 0x03,0x01,0x05,0x00,0x00,
4325 0x21,0xFE,0x0C,'H','e','l','l','o',' ','W','o','r','l','d','!',0x00,
4326 0x21,0x01,0x0D,'a','n','i','m','a','t','i','o','n','.','g','i','f',0x00,
4327 0x21,0xF9,0x04,0xff,0x0A,0x00,0x08,0x00,
4328 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4329 0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,
4330 0x02,0x02,0x4C,0x01,0x00,
4331 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','1',0x00,
4332 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','1',0x00,
4333 0x21,0xF9,0x04,0x00,0x14,0x00,0x01,0x00,
4334 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4335 0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,
4336 0x02,0x02,0x44,0x01,0x00,
4337 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','2',0x00,
4338 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','2',0x00,0x3B
4341 static void test_gif_properties(void)
4343 static const struct test_data
4345 ULONG type, id, length;
4346 const BYTE value[13];
4347 } td[] =
4349 { PropertyTagTypeLong, PropertyTagFrameDelay, 8, { 10,0,0,0,20,0,0,0 } },
4350 { PropertyTagTypeASCII, PropertyTagExifUserComment, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
4351 { PropertyTagTypeShort, PropertyTagLoopCount, 2, { 5,0 } },
4352 { PropertyTagTypeByte, PropertyTagGlobalPalette, 12, { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c } },
4353 { PropertyTagTypeByte, PropertyTagIndexBackground, 1, { 2 } },
4354 { PropertyTagTypeByte, PropertyTagIndexTransparent, 1, { 8 } }
4356 GpStatus status;
4357 GpImage *image;
4358 GUID guid;
4359 UINT dim_count, frame_count, prop_count, prop_size, i;
4360 UINT total_size, total_count;
4361 PROPID *prop_id;
4362 PropertyItem *prop_item;
4363 const char *item_data;
4365 image = load_image(animatedgif, sizeof(animatedgif));
4366 if (!image) /* XP fails to load this GIF image */
4368 trace("Failed to load GIF image data\n");
4369 return;
4372 status = GdipImageGetFrameDimensionsCount(image, &dim_count);
4373 expect(Ok, status);
4374 expect(1, dim_count);
4376 status = GdipImageGetFrameDimensionsList(image, &guid, 1);
4377 expect(Ok, status);
4378 expect_guid(&FrameDimensionTime, &guid, __LINE__, FALSE);
4380 status = GdipImageGetFrameCount(image, &guid, &frame_count);
4381 expect(Ok, status);
4382 expect(2, frame_count);
4384 status = GdipImageSelectActiveFrame(image, &guid, 1);
4385 expect(Ok, status);
4387 status = GdipGetPropertyCount(image, &prop_count);
4388 expect(Ok, status);
4389 ok(prop_count == sizeof(td)/sizeof(td[0]) || broken(prop_count == 1) /* before win7 */,
4390 "expected property count %u, got %u\n", (UINT)(sizeof(td)/sizeof(td[0])), prop_count);
4392 if (prop_count != sizeof(td)/sizeof(td[0]))
4394 GdipDisposeImage(image);
4395 return;
4398 prop_id = HeapAlloc(GetProcessHeap(), 0, prop_count * sizeof(*prop_id));
4400 status = GdipGetPropertyIdList(image, prop_count, prop_id);
4401 expect(Ok, status);
4403 prop_size = 0;
4404 for (i = 0; i < prop_count; i++)
4406 UINT size;
4407 status = GdipGetPropertyItemSize(image, prop_id[i], &size);
4408 expect(Ok, status);
4409 if (status != Ok) break;
4410 ok(size > sizeof(*prop_item), "%u: too small item length %u\n", i, size);
4412 prop_size += size;
4414 prop_item = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
4415 status = GdipGetPropertyItem(image, prop_id[i], size, prop_item);
4416 expect(Ok, status);
4417 ok(prop_item->value == prop_item + 1, "expected item->value %p, got %p\n", prop_item + 1, prop_item->value);
4418 ok(td[i].type == prop_item->type,
4419 "%u: expected type %u, got %u\n", i, td[i].type, prop_item->type);
4420 ok(td[i].id == prop_item->id, "%u: expected id %#x, got %#x\n", i, td[i].id, prop_item->id);
4421 size -= sizeof(*prop_item);
4422 ok(prop_item->length == size, "%u: expected length %u, got %u\n", i, size, prop_item->length);
4423 ok(td[i].length == prop_item->length, "%u: expected length %u, got %u\n", i, td[i].length, prop_item->length);
4424 if (td[i].length == prop_item->length)
4426 int match = memcmp(td[i].value, prop_item->value, td[i].length) == 0;
4427 ok(match, "%u: data mismatch\n", i);
4428 if (!match)
4430 UINT j;
4431 BYTE *data = prop_item->value;
4432 trace("id %#x:", prop_item->id);
4433 for (j = 0; j < prop_item->length; j++)
4434 trace(" %02x", data[j]);
4435 trace("\n");
4438 HeapFree(GetProcessHeap(), 0, prop_item);
4441 HeapFree(GetProcessHeap(), 0, prop_id);
4443 status = GdipGetPropertySize(NULL, &total_size, &total_count);
4444 expect(InvalidParameter, status);
4445 status = GdipGetPropertySize(image, &total_size, NULL);
4446 expect(InvalidParameter, status);
4447 status = GdipGetPropertySize(image, NULL, &total_count);
4448 expect(InvalidParameter, status);
4449 status = GdipGetPropertySize(image, NULL, NULL);
4450 expect(InvalidParameter, status);
4451 total_size = 0xdeadbeef;
4452 total_count = 0xdeadbeef;
4453 status = GdipGetPropertySize(image, &total_size, &total_count);
4454 expect(Ok, status);
4455 ok(prop_count == total_count,
4456 "expected total property count %u, got %u\n", prop_count, total_count);
4457 ok(prop_size == total_size,
4458 "expected total property size %u, got %u\n", prop_size, total_size);
4460 prop_item = HeapAlloc(GetProcessHeap(), 0, prop_size);
4462 status = GdipGetAllPropertyItems(image, 0, prop_count, prop_item);
4463 expect(InvalidParameter, status);
4464 status = GdipGetAllPropertyItems(image, prop_size, 1, prop_item);
4465 expect(InvalidParameter, status);
4466 status = GdipGetAllPropertyItems(image, prop_size, prop_count, NULL);
4467 expect(InvalidParameter, status);
4468 status = GdipGetAllPropertyItems(image, prop_size, prop_count, NULL);
4469 expect(InvalidParameter, status);
4470 status = GdipGetAllPropertyItems(image, 0, 0, NULL);
4471 expect(InvalidParameter, status);
4472 status = GdipGetAllPropertyItems(image, prop_size + 1, prop_count, prop_item);
4473 expect(InvalidParameter, status);
4474 status = GdipGetAllPropertyItems(image, prop_size, prop_count, prop_item);
4475 expect(Ok, status);
4477 item_data = (const char *)(prop_item + prop_count);
4478 for (i = 0; i < prop_count; i++)
4480 ok(prop_item[i].value == item_data, "%u: expected value %p, got %p\n",
4481 i, item_data, prop_item[i].value);
4482 ok(td[i].type == prop_item[i].type,
4483 "%u: expected type %u, got %u\n", i, td[i].type, prop_item[i].type);
4484 ok(td[i].id == prop_item[i].id, "%u: expected id %#x, got %#x\n", i, td[i].id, prop_item[i].id);
4485 ok(td[i].length == prop_item[i].length, "%u: expected length %u, got %u\n", i, td[i].length, prop_item[i].length);
4486 if (td[i].length == prop_item[i].length)
4488 int match = memcmp(td[i].value, prop_item[i].value, td[i].length) == 0;
4489 ok(match, "%u: data mismatch\n", i);
4490 if (!match)
4492 UINT j;
4493 BYTE *data = prop_item[i].value;
4494 trace("id %#x:", prop_item[i].id);
4495 for (j = 0; j < prop_item[i].length; j++)
4496 trace(" %02x", data[j]);
4497 trace("\n");
4500 item_data += prop_item[i].length;
4503 HeapFree(GetProcessHeap(), 0, prop_item);
4505 GdipDisposeImage(image);
4508 static void test_ARGB_conversion(void)
4510 BYTE argb[8] = { 0x11,0x22,0x33,0x80, 0xff,0xff,0xff,0 };
4511 BYTE pargb[8] = { 0x09,0x11,0x1a,0x80, 0,0,0,0 };
4512 BYTE rgb32_xp[8] = { 0x11,0x22,0x33,0xff, 0xff,0xff,0xff,0xff };
4513 BYTE rgb24[6] = { 0x11,0x22,0x33, 0xff,0xff,0xff };
4514 BYTE *bits;
4515 GpBitmap *bitmap;
4516 BitmapData data;
4517 GpStatus status;
4518 int match;
4520 status = GdipCreateBitmapFromScan0(2, 1, 8, PixelFormat32bppARGB, argb, &bitmap);
4521 expect(Ok, status);
4523 status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat32bppPARGB, &data);
4524 expect(Ok, status);
4525 ok(data.Width == 2, "expected 2, got %d\n", data.Width);
4526 ok(data.Height == 1, "expected 1, got %d\n", data.Height);
4527 ok(data.Stride == 8, "expected 8, got %d\n", data.Stride);
4528 ok(data.PixelFormat == PixelFormat32bppPARGB, "expected PixelFormat32bppPARGB, got %d\n", data.PixelFormat);
4529 match = !memcmp(data.Scan0, pargb, sizeof(pargb));
4530 ok(match, "bits don't match\n");
4531 if (!match)
4533 bits = data.Scan0;
4534 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppPARGB,
4535 bits[0], bits[1], bits[2], bits[3], bits[4], bits[5], bits[6], bits[7]);
4537 status = GdipBitmapUnlockBits(bitmap, &data);
4538 expect(Ok, status);
4540 status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat32bppRGB, &data);
4541 expect(Ok, status);
4542 ok(data.Width == 2, "expected 2, got %d\n", data.Width);
4543 ok(data.Height == 1, "expected 1, got %d\n", data.Height);
4544 ok(data.Stride == 8, "expected 8, got %d\n", data.Stride);
4545 ok(data.PixelFormat == PixelFormat32bppRGB, "expected PixelFormat32bppRGB, got %d\n", data.PixelFormat);
4546 match = !memcmp(data.Scan0, argb, sizeof(argb)) ||
4547 !memcmp(data.Scan0, rgb32_xp, sizeof(rgb32_xp));
4548 ok(match, "bits don't match\n");
4549 if (!match)
4551 bits = data.Scan0;
4552 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppRGB,
4553 bits[0], bits[1], bits[2], bits[3], bits[4], bits[5], bits[6], bits[7]);
4555 status = GdipBitmapUnlockBits(bitmap, &data);
4556 expect(Ok, status);
4558 status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat24bppRGB, &data);
4559 expect(Ok, status);
4560 ok(data.Width == 2, "expected 2, got %d\n", data.Width);
4561 ok(data.Height == 1, "expected 1, got %d\n", data.Height);
4562 ok(data.Stride == 8, "expected 8, got %d\n", data.Stride);
4563 ok(data.PixelFormat == PixelFormat24bppRGB, "expected PixelFormat24bppRGB, got %d\n", data.PixelFormat);
4564 match = !memcmp(data.Scan0, rgb24, sizeof(rgb24));
4565 ok(match, "bits don't match\n");
4566 if (!match)
4568 bits = data.Scan0;
4569 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat24bppRGB,
4570 bits[0], bits[1], bits[2], bits[3], bits[4], bits[5], bits[6], bits[7]);
4572 status = GdipBitmapUnlockBits(bitmap, &data);
4573 expect(Ok, status);
4575 GdipDisposeImage((GpImage *)bitmap);
4579 static void test_CloneBitmapArea(void)
4581 GpStatus status;
4582 GpBitmap *bitmap, *copy;
4583 BitmapData data, data2;
4585 status = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB, NULL, &bitmap);
4586 expect(Ok, status);
4588 status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead | ImageLockModeWrite, PixelFormat24bppRGB, &data);
4589 expect(Ok, status);
4591 status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat24bppRGB, &data2);
4592 expect(WrongState, status);
4594 status = GdipCloneBitmapAreaI(0, 0, 1, 1, PixelFormat24bppRGB, bitmap, &copy);
4595 expect(Ok, status);
4597 status = GdipBitmapUnlockBits(bitmap, &data);
4598 expect(Ok, status);
4600 GdipDisposeImage((GpImage *)copy);
4601 GdipDisposeImage((GpImage *)bitmap);
4604 static BOOL get_encoder_clsid(LPCWSTR mime, GUID *format, CLSID *clsid)
4606 GpStatus status;
4607 UINT n_codecs, info_size, i;
4608 ImageCodecInfo *info;
4609 BOOL ret = FALSE;
4611 status = GdipGetImageEncodersSize(&n_codecs, &info_size);
4612 expect(Ok, status);
4614 info = GdipAlloc(info_size);
4616 status = GdipGetImageEncoders(n_codecs, info_size, info);
4617 expect(Ok, status);
4619 for (i = 0; i < n_codecs; i++)
4621 if (!lstrcmpW(info[i].MimeType, mime))
4623 *format = info[i].FormatID;
4624 *clsid = info[i].Clsid;
4625 ret = TRUE;
4626 break;
4630 GdipFree(info);
4631 return ret;
4634 static void test_supported_encoders(void)
4636 static const WCHAR bmp_mimetype[] = { 'i', 'm', 'a','g', 'e', '/', 'b', 'm', 'p',0 };
4637 static const WCHAR jpeg_mimetype[] = { 'i','m','a','g','e','/','j','p','e','g',0 };
4638 static const WCHAR gif_mimetype[] = { 'i','m','a','g','e','/','g','i','f',0 };
4639 static const WCHAR tiff_mimetype[] = { 'i','m','a','g','e','/','t','i','f','f',0 };
4640 static const WCHAR png_mimetype[] = { 'i','m','a','g','e','/','p','n','g',0 };
4641 static const struct test_data
4643 LPCWSTR mime;
4644 const GUID *format;
4645 BOOL todo;
4646 } td[] =
4648 { bmp_mimetype, &ImageFormatBMP, FALSE },
4649 { jpeg_mimetype, &ImageFormatJPEG, FALSE },
4650 { gif_mimetype, &ImageFormatGIF, TRUE },
4651 { tiff_mimetype, &ImageFormatTIFF, FALSE },
4652 { png_mimetype, &ImageFormatPNG, FALSE }
4654 GUID format, clsid;
4655 BOOL ret;
4656 HRESULT hr;
4657 GpStatus status;
4658 GpBitmap *bm;
4659 IStream *stream;
4660 HGLOBAL hmem;
4661 int i;
4663 status = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB, NULL, &bm);
4664 ok(status == Ok, "GdipCreateBitmapFromScan0 error %d\n", status);
4666 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
4668 ret = get_encoder_clsid(td[i].mime, &format, &clsid);
4669 ok(ret, "%s encoder is not in the list\n", wine_dbgstr_w(td[i].mime));
4670 expect_guid(td[i].format, &format, __LINE__, FALSE);
4672 hmem = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD, 16);
4674 hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
4675 ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr);
4677 status = GdipSaveImageToStream((GpImage *)bm, stream, &clsid, NULL);
4678 todo_wine_if (td[i].todo)
4679 ok(status == Ok, "GdipSaveImageToStream error %d\n", status);
4681 IStream_Release(stream);
4684 GdipDisposeImage((GpImage *)bm);
4687 static void test_createeffect(void)
4689 static const GUID noneffect = { 0xcd0c3d4b, 0xe15e, 0x4cf2, { 0x9e, 0xa8, 0x6e, 0x1d, 0x65, 0x48, 0xc5, 0xa5 } };
4690 GpStatus (WINAPI *pGdipCreateEffect)( const GUID guid, CGpEffect **effect);
4691 GpStatus (WINAPI *pGdipDeleteEffect)( CGpEffect *effect);
4692 GpStatus stat;
4693 CGpEffect *effect;
4694 HMODULE mod = GetModuleHandleA("gdiplus.dll");
4695 int i;
4696 const GUID * const effectlist[] =
4697 {&BlurEffectGuid, &SharpenEffectGuid, &ColorMatrixEffectGuid, &ColorLUTEffectGuid,
4698 &BrightnessContrastEffectGuid, &HueSaturationLightnessEffectGuid, &LevelsEffectGuid,
4699 &TintEffectGuid, &ColorBalanceEffectGuid, &RedEyeCorrectionEffectGuid, &ColorCurveEffectGuid};
4701 pGdipCreateEffect = (void*)GetProcAddress( mod, "GdipCreateEffect");
4702 pGdipDeleteEffect = (void*)GetProcAddress( mod, "GdipDeleteEffect");
4703 if(!pGdipCreateEffect || !pGdipDeleteEffect)
4705 /* GdipCreateEffect/GdipDeleteEffect was introduced in Windows Vista. */
4706 win_skip("GDIPlus version 1.1 not available\n");
4707 return;
4710 stat = pGdipCreateEffect(BlurEffectGuid, NULL);
4711 expect(InvalidParameter, stat);
4713 stat = pGdipCreateEffect(noneffect, &effect);
4714 todo_wine expect(Win32Error, stat);
4716 for(i=0; i < sizeof(effectlist) / sizeof(effectlist[0]); i++)
4718 stat = pGdipCreateEffect(*effectlist[i], &effect);
4719 todo_wine expect(Ok, stat);
4720 if(stat == Ok)
4722 stat = pGdipDeleteEffect(effect);
4723 expect(Ok, stat);
4728 static void test_getadjustedpalette(void)
4730 ColorMap colormap;
4731 GpImageAttributes *imageattributes;
4732 ColorPalette *palette;
4733 GpStatus stat;
4735 stat = GdipCreateImageAttributes(&imageattributes);
4736 expect(Ok, stat);
4738 colormap.oldColor.Argb = 0xffffff00;
4739 colormap.newColor.Argb = 0xffff00ff;
4740 stat = GdipSetImageAttributesRemapTable(imageattributes, ColorAdjustTypeBitmap,
4741 TRUE, 1, &colormap);
4742 expect(Ok, stat);
4744 colormap.oldColor.Argb = 0xffffff80;
4745 colormap.newColor.Argb = 0xffff80ff;
4746 stat = GdipSetImageAttributesRemapTable(imageattributes, ColorAdjustTypeDefault,
4747 TRUE, 1, &colormap);
4748 expect(Ok, stat);
4750 palette = GdipAlloc(sizeof(*palette) + sizeof(ARGB) * 2);
4751 palette->Count = 0;
4753 stat = GdipGetImageAttributesAdjustedPalette(imageattributes, palette, ColorAdjustTypeBitmap);
4754 expect(InvalidParameter, stat);
4756 palette->Count = 3;
4757 palette->Entries[0] = 0xffffff00;
4758 palette->Entries[1] = 0xffffff80;
4759 palette->Entries[2] = 0xffffffff;
4761 stat = GdipGetImageAttributesAdjustedPalette(imageattributes, palette, ColorAdjustTypeBitmap);
4762 expect(Ok, stat);
4763 expect(0xffff00ff, palette->Entries[0]);
4764 expect(0xffffff80, palette->Entries[1]);
4765 expect(0xffffffff, palette->Entries[2]);
4767 palette->Entries[0] = 0xffffff00;
4768 palette->Entries[1] = 0xffffff80;
4769 palette->Entries[2] = 0xffffffff;
4771 stat = GdipGetImageAttributesAdjustedPalette(imageattributes, palette, ColorAdjustTypeBrush);
4772 expect(Ok, stat);
4773 expect(0xffffff00, palette->Entries[0]);
4774 expect(0xffff80ff, palette->Entries[1]);
4775 expect(0xffffffff, palette->Entries[2]);
4777 stat = GdipGetImageAttributesAdjustedPalette(NULL, palette, ColorAdjustTypeBitmap);
4778 expect(InvalidParameter, stat);
4780 stat = GdipGetImageAttributesAdjustedPalette(imageattributes, NULL, ColorAdjustTypeBitmap);
4781 expect(InvalidParameter, stat);
4783 stat = GdipGetImageAttributesAdjustedPalette(imageattributes, palette, -1);
4784 expect(InvalidParameter, stat);
4786 stat = GdipGetImageAttributesAdjustedPalette(imageattributes, palette, ColorAdjustTypeDefault);
4787 expect(InvalidParameter, stat);
4789 GdipFree(palette);
4790 GdipDisposeImageAttributes(imageattributes);
4793 START_TEST(image)
4795 struct GdiplusStartupInput gdiplusStartupInput;
4796 ULONG_PTR gdiplusToken;
4798 gdiplusStartupInput.GdiplusVersion = 1;
4799 gdiplusStartupInput.DebugEventCallback = NULL;
4800 gdiplusStartupInput.SuppressBackgroundThread = 0;
4801 gdiplusStartupInput.SuppressExternalCodecs = 0;
4803 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
4805 test_supported_encoders();
4806 test_CloneBitmapArea();
4807 test_ARGB_conversion();
4808 test_DrawImage_scale();
4809 test_image_format();
4810 test_DrawImage();
4811 test_DrawImage_SourceCopy();
4812 test_GdipDrawImagePointRect();
4813 test_bitmapbits();
4814 test_tiff_palette();
4815 test_GdipGetAllPropertyItems();
4816 test_tiff_properties();
4817 test_gif_properties();
4818 test_image_properties();
4819 test_Scan0();
4820 test_FromGdiDib();
4821 test_GetImageDimension();
4822 test_GdipImageGetFrameDimensionsCount();
4823 test_LoadingImages();
4824 test_SavingImages();
4825 test_encoders();
4826 test_LockBits();
4827 test_LockBits_UserBuf();
4828 test_GdipCreateBitmapFromHBITMAP();
4829 test_GdipGetImageFlags();
4830 test_GdipCloneImage();
4831 test_testcontrol();
4832 test_fromhicon();
4833 test_getrawformat();
4834 test_loadwmf();
4835 test_createfromwmf();
4836 test_createfromwmf_noplaceable();
4837 test_resolution();
4838 test_createhbitmap();
4839 test_getthumbnail();
4840 test_getsetpixel();
4841 test_palette();
4842 test_colormatrix();
4843 test_gamma();
4844 test_multiframegif();
4845 test_rotateflip();
4846 test_remaptable();
4847 test_colorkey();
4848 test_dispose();
4849 test_createeffect();
4850 test_getadjustedpalette();
4852 GdiplusShutdown(gdiplusToken);