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
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
;
40 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
42 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
44 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
48 static void expect_guid(REFGUID expected
, REFGUID got
, int line
, BOOL todo
)
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
);
59 todo_wine
ok_(__FILE__
, line
)(IsEqualGUID(expected
, got
), "Expected %s, got %s\n", buffer2
, buffer
);
61 ok_(__FILE__
, line
)(IsEqualGUID(expected
, got
), "Expected %s, got %s\n", buffer2
, buffer
);
64 static void expect_rawformat(REFGUID expected
, GpImage
*img
, int line
, BOOL todo
)
69 stat
= GdipGetImageRawFormat(img
, &raw
);
70 ok_(__FILE__
, line
)(stat
== Ok
, "GdipGetImageRawFormat failed with %d\n", stat
);
71 if(stat
!= Ok
) return;
72 expect_guid(expected
, &raw
, line
, todo
);
75 static void test_bufferrawformat(void* buff
, int size
, REFGUID expected
, int line
, BOOL todo
)
84 hglob
= GlobalAlloc (0, size
);
85 data
= GlobalLock (hglob
);
86 memcpy(data
, buff
, size
);
87 GlobalUnlock(hglob
); data
= NULL
;
89 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
90 ok_(__FILE__
, line
)(hres
== S_OK
, "Failed to create a stream\n");
91 if(hres
!= S_OK
) return;
93 stat
= GdipLoadImageFromStream(stream
, &img
);
94 ok_(__FILE__
, line
)(stat
== Ok
, "Failed to create a Bitmap\n");
96 IStream_Release(stream
);
100 expect_rawformat(expected
, img
, line
, todo
);
102 GdipDisposeImage(img
);
103 IStream_Release(stream
);
106 static void test_Scan0(void)
113 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
115 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
117 GdipDisposeImage((GpImage
*)bm
);
119 bm
= (GpBitmap
*)0xdeadbeef;
120 stat
= GdipCreateBitmapFromScan0(10, -10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
121 expect(InvalidParameter
, stat
);
122 ok( !bm
, "expected null bitmap\n" );
124 bm
= (GpBitmap
*)0xdeadbeef;
125 stat
= GdipCreateBitmapFromScan0(-10, 10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
126 expect(InvalidParameter
, stat
);
127 ok( !bm
, "expected null bitmap\n" );
129 bm
= (GpBitmap
*)0xdeadbeef;
130 stat
= GdipCreateBitmapFromScan0(10, 0, 10, PixelFormat24bppRGB
, NULL
, &bm
);
131 expect(InvalidParameter
, stat
);
132 ok( !bm
, "expected null bitmap\n" );
135 stat
= GdipCreateBitmapFromScan0(10, 10, 12, PixelFormat24bppRGB
, buff
, &bm
);
137 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
139 GdipDisposeImage((GpImage
*)bm
);
141 bm
= (GpBitmap
*) 0xdeadbeef;
142 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, buff
, &bm
);
143 expect(InvalidParameter
, stat
);
144 ok( !bm
, "expected null bitmap\n" );
146 bm
= (GpBitmap
*)0xdeadbeef;
147 stat
= GdipCreateBitmapFromScan0(10, 10, 0, PixelFormat24bppRGB
, buff
, &bm
);
148 expect(InvalidParameter
, stat
);
149 ok( bm
== (GpBitmap
*)0xdeadbeef, "expected deadbeef bitmap\n" );
152 stat
= GdipCreateBitmapFromScan0(10, 10, -8, PixelFormat24bppRGB
, buff
, &bm
);
154 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
156 GdipDisposeImage((GpImage
*)bm
);
158 bm
= (GpBitmap
*)0xdeadbeef;
159 stat
= GdipCreateBitmapFromScan0(10, 10, -10, PixelFormat24bppRGB
, buff
, &bm
);
160 expect(InvalidParameter
, stat
);
161 ok( !bm
, "expected null bitmap\n" );
164 static void test_FromGdiDib(void)
169 BYTE rbmi
[sizeof(BITMAPINFOHEADER
)+256*sizeof(RGBQUAD
)];
170 BITMAPINFO
*bmi
= (BITMAPINFO
*)rbmi
;
175 memset(rbmi
, 0, sizeof(rbmi
));
177 bmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
178 bmi
->bmiHeader
.biWidth
= 10;
179 bmi
->bmiHeader
.biHeight
= 10;
180 bmi
->bmiHeader
.biPlanes
= 1;
181 bmi
->bmiHeader
.biBitCount
= 32;
182 bmi
->bmiHeader
.biCompression
= BI_RGB
;
184 stat
= GdipCreateBitmapFromGdiDib(NULL
, buff
, &bm
);
185 expect(InvalidParameter
, stat
);
187 stat
= GdipCreateBitmapFromGdiDib(bmi
, NULL
, &bm
);
188 expect(InvalidParameter
, stat
);
190 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, NULL
);
191 expect(InvalidParameter
, stat
);
193 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
195 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
198 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
200 expect(PixelFormat32bppRGB
, format
);
202 GdipDisposeImage((GpImage
*)bm
);
205 bmi
->bmiHeader
.biBitCount
= 24;
206 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
208 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
211 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
213 expect(PixelFormat24bppRGB
, format
);
215 GdipDisposeImage((GpImage
*)bm
);
218 bmi
->bmiHeader
.biBitCount
= 16;
219 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
221 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
224 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
226 expect(PixelFormat16bppRGB555
, format
);
228 GdipDisposeImage((GpImage
*)bm
);
231 bmi
->bmiHeader
.biBitCount
= 8;
232 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
234 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
237 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
239 expect(PixelFormat8bppIndexed
, format
);
241 GdipDisposeImage((GpImage
*)bm
);
244 bmi
->bmiHeader
.biBitCount
= 4;
245 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
247 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
250 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
252 expect(PixelFormat4bppIndexed
, format
);
254 GdipDisposeImage((GpImage
*)bm
);
257 bmi
->bmiHeader
.biBitCount
= 1;
258 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
260 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
263 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
265 expect(PixelFormat1bppIndexed
, format
);
267 GdipDisposeImage((GpImage
*)bm
);
270 bmi
->bmiHeader
.biBitCount
= 0;
271 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
272 expect(InvalidParameter
, stat
);
275 static void test_GetImageDimension(void)
279 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
282 bm
= (GpBitmap
*)0xdeadbeef;
283 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
,NULL
, &bm
);
285 ok((GpBitmap
*)0xdeadbeef != bm
, "Expected bitmap to not be 0xdeadbeef\n");
286 ok(NULL
!= bm
, "Expected bitmap to not be NULL\n");
288 stat
= GdipGetImageDimension(NULL
,&w
,&h
);
289 expect(InvalidParameter
, stat
);
291 stat
= GdipGetImageDimension((GpImage
*)bm
,NULL
,&h
);
292 expect(InvalidParameter
, stat
);
294 stat
= GdipGetImageDimension((GpImage
*)bm
,&w
,NULL
);
295 expect(InvalidParameter
, stat
);
299 stat
= GdipGetImageDimension((GpImage
*)bm
,&w
,&h
);
303 GdipDisposeImage((GpImage
*)bm
);
306 static void test_GdipImageGetFrameDimensionsCount(void)
310 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
312 GUID dimension
= {0};
316 bm
= (GpBitmap
*)0xdeadbeef;
317 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
,NULL
, &bm
);
319 ok((GpBitmap
*)0xdeadbeef != bm
, "Expected bitmap to not be 0xdeadbeef\n");
320 ok(NULL
!= bm
, "Expected bitmap to not be NULL\n");
322 stat
= GdipImageGetFrameDimensionsCount(NULL
,&w
);
323 expect(InvalidParameter
, stat
);
325 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bm
,NULL
);
326 expect(InvalidParameter
, stat
);
329 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bm
,&w
);
333 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 1);
335 expect_guid(&FrameDimensionPage
, &dimension
, __LINE__
, FALSE
);
337 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 2);
338 expect(InvalidParameter
, stat
);
340 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 0);
341 expect(InvalidParameter
, stat
);
343 stat
= GdipImageGetFrameCount(NULL
, &dimension
, &count
);
344 expect(InvalidParameter
, stat
);
346 /* WinXP crashes on this test */
349 stat
= GdipImageGetFrameCount((GpImage
*)bm
, &dimension
, NULL
);
350 expect(InvalidParameter
, stat
);
353 stat
= GdipImageGetFrameCount((GpImage
*)bm
, NULL
, &count
);
357 stat
= GdipImageGetFrameCount((GpImage
*)bm
, &dimension
, &count
);
361 GdipBitmapSetPixel(bm
, 0, 0, 0xffffffff);
363 stat
= GdipImageSelectActiveFrame((GpImage
*)bm
, &dimension
, 0);
366 /* SelectActiveFrame has no effect on image data of memory bitmaps */
368 GdipBitmapGetPixel(bm
, 0, 0, &color
);
369 expect(0xffffffff, color
);
371 GdipDisposeImage((GpImage
*)bm
);
374 static void test_LoadingImages(void)
379 static const WCHAR nonexistentW
[] = {'n','o','n','e','x','i','s','t','e','n','t',0};
381 stat
= GdipCreateBitmapFromFile(0, 0);
382 expect(InvalidParameter
, stat
);
384 bm
= (GpBitmap
*)0xdeadbeef;
385 stat
= GdipCreateBitmapFromFile(0, &bm
);
386 expect(InvalidParameter
, stat
);
387 ok(bm
== (GpBitmap
*)0xdeadbeef, "returned %p\n", bm
);
389 bm
= (GpBitmap
*)0xdeadbeef;
390 stat
= GdipCreateBitmapFromFile(nonexistentW
, &bm
);
391 todo_wine
expect(InvalidParameter
, stat
);
392 ok(!bm
, "returned %p\n", bm
);
394 stat
= GdipLoadImageFromFile(0, 0);
395 expect(InvalidParameter
, stat
);
397 img
= (GpImage
*)0xdeadbeef;
398 stat
= GdipLoadImageFromFile(0, &img
);
399 expect(InvalidParameter
, stat
);
400 ok(img
== (GpImage
*)0xdeadbeef, "returned %p\n", img
);
402 img
= (GpImage
*)0xdeadbeef;
403 stat
= GdipLoadImageFromFile(nonexistentW
, &img
);
404 todo_wine
expect(OutOfMemory
, stat
);
405 ok(!img
, "returned %p\n", img
);
407 stat
= GdipLoadImageFromFileICM(0, 0);
408 expect(InvalidParameter
, stat
);
410 img
= (GpImage
*)0xdeadbeef;
411 stat
= GdipLoadImageFromFileICM(0, &img
);
412 expect(InvalidParameter
, stat
);
413 ok(img
== (GpImage
*)0xdeadbeef, "returned %p\n", img
);
415 img
= (GpImage
*)0xdeadbeef;
416 stat
= GdipLoadImageFromFileICM(nonexistentW
, &img
);
417 todo_wine
expect(OutOfMemory
, stat
);
418 ok(!img
, "returned %p\n", img
);
421 static void test_SavingImages(void)
427 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
429 ImageCodecInfo
*codecs
;
430 static const CHAR filenameA
[] = "a.bmp";
431 static const WCHAR filename
[] = { 'a','.','b','m','p',0 };
435 stat
= GdipSaveImageToFile(0, 0, 0, 0);
436 expect(InvalidParameter
, stat
);
439 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
445 stat
= GdipSaveImageToFile((GpImage
*)bm
, 0, 0, 0);
446 expect(InvalidParameter
, stat
);
448 stat
= GdipSaveImageToFile((GpImage
*)bm
, filename
, 0, 0);
449 expect(InvalidParameter
, stat
);
451 /* encoder tests should succeed -- already tested */
452 stat
= GdipGetImageEncodersSize(&n
, &s
);
453 if (stat
!= Ok
|| n
== 0) goto cleanup
;
455 codecs
= GdipAlloc(s
);
456 if (!codecs
) goto cleanup
;
458 stat
= GdipGetImageEncoders(n
, s
, codecs
);
459 if (stat
!= Ok
) goto cleanup
;
461 stat
= GdipSaveImageToFile((GpImage
*)bm
, filename
, &codecs
[0].Clsid
, 0);
464 GdipDisposeImage((GpImage
*)bm
);
467 /* re-load and check image stats */
468 stat
= GdipLoadImageFromFile(filename
, (GpImage
**)&bm
);
470 if (stat
!= Ok
) goto cleanup
;
472 stat
= GdipGetImageDimension((GpImage
*)bm
, &w
, &h
);
473 if (stat
!= Ok
) goto cleanup
;
481 GdipDisposeImage((GpImage
*)bm
);
482 ok(DeleteFileA(filenameA
), "Delete failed.\n");
485 static void test_encoders(void)
490 ImageCodecInfo
*codecs
;
494 static const CHAR bmp_format
[] = "BMP";
496 stat
= GdipGetImageEncodersSize(&n
, &s
);
499 codecs
= GdipAlloc(s
);
503 stat
= GdipGetImageEncoders(n
, s
, NULL
);
504 expect(GenericError
, stat
);
506 stat
= GdipGetImageEncoders(0, s
, codecs
);
507 expect(GenericError
, stat
);
509 stat
= GdipGetImageEncoders(n
, s
-1, codecs
);
510 expect(GenericError
, stat
);
512 stat
= GdipGetImageEncoders(n
, s
+1, codecs
);
513 expect(GenericError
, stat
);
515 stat
= GdipGetImageEncoders(n
, s
, codecs
);
519 for (i
= 0; i
< n
; i
++)
523 WideCharToMultiByte(CP_ACP
, 0, codecs
[i
].FormatDescription
, -1,
526 if (CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0,
528 bmp_format
, -1) == CSTR_EQUAL
) {
534 ok(FALSE
, "No BMP codec found.\n");
539 static void test_LockBits(void)
545 const INT WIDTH
= 10, HEIGHT
= 20;
550 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
558 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffc30000);
561 stat
= GdipBitmapSetPixel(bm
, 2, 8, 0xff480000);
565 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
569 expect(0xc3, ((BYTE
*)bd
.Scan0
)[2]);
570 expect(0x48, ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5]);
572 ((char*)bd
.Scan0
)[2] = 0xff;
574 stat
= GdipBitmapUnlockBits(bm
, &bd
);
578 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
580 expect(0xffff0000, color
);
582 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffc30000);
585 /* read-only, with NULL rect -> whole bitmap lock */
586 stat
= GdipBitmapLockBits(bm
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
588 expect(bd
.Width
, WIDTH
);
589 expect(bd
.Height
, HEIGHT
);
592 ((char*)bd
.Scan0
)[2 + 2*3 + 3*bd
.Stride
] = 0xff;
594 stat
= GdipBitmapUnlockBits(bm
, &bd
);
598 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
600 expect(0xffff0000, color
);
602 /* read-only, consecutive */
603 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
607 stat
= GdipBitmapUnlockBits(bm
, &bd
);
611 stat
= GdipDisposeImage((GpImage
*)bm
);
613 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
617 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
619 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
620 expect(WrongState
, stat
);
622 stat
= GdipBitmapUnlockBits(bm
, &bd
);
625 stat
= GdipDisposeImage((GpImage
*)bm
);
627 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
630 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffff0000);
633 stat
= GdipBitmapSetPixel(bm
, 2, 8, 0xffc30000);
636 /* write, no conversion */
637 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
641 /* all bits are readable, inside the rect or not */
642 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
643 expect(0xc3, ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5]);
645 stat
= GdipBitmapUnlockBits(bm
, &bd
);
649 /* read, conversion */
650 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat32bppARGB
, &bd
);
654 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
656 /* Areas outside the rectangle appear to be uninitialized */
657 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
659 ((BYTE
*)bd
.Scan0
)[2] = 0xc3;
661 stat
= GdipBitmapUnlockBits(bm
, &bd
);
665 /* writes do not work in read mode if there was a conversion */
666 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
668 expect(0xffff0000, color
);
670 /* read/write, conversion */
671 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeWrite
, PixelFormat32bppARGB
, &bd
);
675 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
676 ((BYTE
*)bd
.Scan0
)[1] = 0x88;
678 /* Areas outside the rectangle appear to be uninitialized */
679 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
681 stat
= GdipBitmapUnlockBits(bm
, &bd
);
685 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
687 expect(0xffff8800, color
);
689 /* write, conversion */
690 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat32bppARGB
, &bd
);
696 /* This is completely uninitialized. */
697 ok(0xff != ((BYTE
*)bd
.Scan0
)[2], "original image bits are readable\n");
698 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
701 /* Initialize the buffer so the unlock doesn't access undefined memory */
703 memset(((BYTE
*)bd
.Scan0
) + bd
.Stride
* y
, 0, 12);
705 ((BYTE
*)bd
.Scan0
)[0] = 0x12;
706 ((BYTE
*)bd
.Scan0
)[1] = 0x34;
707 ((BYTE
*)bd
.Scan0
)[2] = 0x56;
709 stat
= GdipBitmapUnlockBits(bm
, &bd
);
713 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
715 expect(0xff563412, color
);
717 stat
= GdipBitmapGetPixel(bm
, 2, 8, &color
);
719 expect(0xffc30000, color
);
721 stat
= GdipDisposeImage((GpImage
*)bm
);
723 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
726 /* write, no modification */
727 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
731 stat
= GdipBitmapUnlockBits(bm
, &bd
);
735 /* write, consecutive */
736 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
740 stat
= GdipBitmapUnlockBits(bm
, &bd
);
744 stat
= GdipDisposeImage((GpImage
*)bm
);
746 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
750 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
755 ((char*)bd
.Scan0
)[2] = 0xff;
757 stat
= GdipBitmapUnlockBits(bm
, &bd
);
761 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
763 expect(0xffff0000, color
);
765 stat
= GdipDisposeImage((GpImage
*)bm
);
769 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
771 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
773 stat
= GdipDisposeImage((GpImage
*)bm
);
777 static void test_LockBits_UserBuf(void)
783 const INT WIDTH
= 10, HEIGHT
= 20;
788 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat32bppARGB
, NULL
, &bm
);
791 memset(bits
, 0xaa, sizeof(bits
));
800 bd
.Stride
= WIDTH
* 4;
801 bd
.PixelFormat
= PixelFormat32bppARGB
;
802 bd
.Scan0
= &bits
[2+3*WIDTH
];
803 bd
.Reserved
= 0xaaaaaaaa;
806 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
809 expect(0xaaaaaaaa, bits
[0]);
810 expect(0, bits
[2+3*WIDTH
]);
812 bits
[2+3*WIDTH
] = 0xdeadbeef;
815 stat
= GdipBitmapUnlockBits(bm
, &bd
);
819 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
824 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
827 expect(0xdeadbeef, bits
[2+3*WIDTH
]);
828 bits
[2+3*WIDTH
] = 0x12345678;
831 stat
= GdipBitmapUnlockBits(bm
, &bd
);
835 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
837 expect(0x12345678, color
);
842 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeWrite
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
845 expect(0x12345678, bits
[2+3*WIDTH
]);
846 bits
[2+3*WIDTH
] = 0xdeadbeef;
849 stat
= GdipBitmapUnlockBits(bm
, &bd
);
853 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
855 expect(0xdeadbeef, color
);
857 stat
= GdipDisposeImage((GpImage
*)bm
);
861 struct BITMAPINFOWITHBITFIELDS
863 BITMAPINFOHEADER bmiHeader
;
867 union BITMAPINFOUNION
870 struct BITMAPINFOWITHBITFIELDS bf
;
873 static void test_GdipCreateBitmapFromHBITMAP(void)
875 GpBitmap
* gpbm
= NULL
;
877 HPALETTE hpal
= NULL
;
880 LOGPALETTE
* LogPal
= NULL
;
882 const REAL WIDTH1
= 5;
883 const REAL HEIGHT1
= 15;
884 const REAL WIDTH2
= 10;
885 const REAL HEIGHT2
= 20;
887 union BITMAPINFOUNION bmi
;
891 stat
= GdipCreateBitmapFromHBITMAP(NULL
, NULL
, NULL
);
892 expect(InvalidParameter
, stat
);
894 hbm
= CreateBitmap(WIDTH1
, HEIGHT1
, 1, 1, NULL
);
895 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, NULL
);
896 expect(InvalidParameter
, stat
);
898 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
900 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
901 expectf(WIDTH1
, width
);
902 expectf(HEIGHT1
, height
);
904 GdipDisposeImage((GpImage
*)gpbm
);
907 memset(buff
, 0, sizeof(buff
));
908 hbm
= CreateBitmap(WIDTH2
, HEIGHT2
, 1, 1, &buff
);
909 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
912 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)gpbm
, __LINE__
, FALSE
);
914 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
915 expectf(WIDTH2
, width
);
916 expectf(HEIGHT2
, height
);
918 GdipDisposeImage((GpImage
*)gpbm
);
921 hdc
= CreateCompatibleDC(0);
922 ok(hdc
!= NULL
, "CreateCompatibleDC failed\n");
923 bmi
.bi
.bmiHeader
.biSize
= sizeof(bmi
.bi
.bmiHeader
);
924 bmi
.bi
.bmiHeader
.biHeight
= HEIGHT1
;
925 bmi
.bi
.bmiHeader
.biWidth
= WIDTH1
;
926 bmi
.bi
.bmiHeader
.biBitCount
= 24;
927 bmi
.bi
.bmiHeader
.biPlanes
= 1;
928 bmi
.bi
.bmiHeader
.biCompression
= BI_RGB
;
929 bmi
.bi
.bmiHeader
.biClrUsed
= 0;
931 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
932 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
936 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
938 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
939 expectf(WIDTH1
, width
);
940 expectf(HEIGHT1
, height
);
943 /* test whether writing to the bitmap affects the original */
944 stat
= GdipBitmapSetPixel(gpbm
, 0, 0, 0xffffffff);
949 GdipDisposeImage((GpImage
*)gpbm
);
952 LogPal
= GdipAlloc(sizeof(LOGPALETTE
));
953 ok(LogPal
!= NULL
, "unable to allocate LOGPALETTE\n");
954 LogPal
->palVersion
= 0x300;
955 LogPal
->palNumEntries
= 1;
956 hpal
= CreatePalette(LogPal
);
957 ok(hpal
!= NULL
, "CreatePalette failed\n");
960 stat
= GdipCreateBitmapFromHBITMAP(hbm
, hpal
, &gpbm
);
964 GdipDisposeImage((GpImage
*)gpbm
);
969 /* 16-bit 555 dib, rgb */
970 bmi
.bi
.bmiHeader
.biBitCount
= 16;
971 bmi
.bi
.bmiHeader
.biCompression
= BI_RGB
;
973 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
974 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
978 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
983 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
985 expectf(WIDTH1
, width
);
986 expectf(HEIGHT1
, height
);
988 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
990 expect(PixelFormat16bppRGB555
, format
);
992 GdipDisposeImage((GpImage
*)gpbm
);
996 /* 16-bit 555 dib, with bitfields */
997 bmi
.bi
.bmiHeader
.biSize
= sizeof(bmi
);
998 bmi
.bi
.bmiHeader
.biCompression
= BI_BITFIELDS
;
999 bmi
.bf
.masks
[0] = 0x7c00;
1000 bmi
.bf
.masks
[1] = 0x3e0;
1001 bmi
.bf
.masks
[2] = 0x1f;
1003 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1004 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1008 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1013 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1015 expectf(WIDTH1
, width
);
1016 expectf(HEIGHT1
, height
);
1018 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1020 expect(PixelFormat16bppRGB555
, format
);
1022 GdipDisposeImage((GpImage
*)gpbm
);
1026 /* 16-bit 565 dib, with bitfields */
1027 bmi
.bf
.masks
[0] = 0xf800;
1028 bmi
.bf
.masks
[1] = 0x7e0;
1029 bmi
.bf
.masks
[2] = 0x1f;
1031 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1032 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1036 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1041 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1043 expectf(WIDTH1
, width
);
1044 expectf(HEIGHT1
, height
);
1046 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1048 expect(PixelFormat16bppRGB565
, format
);
1050 GdipDisposeImage((GpImage
*)gpbm
);
1057 static void test_GdipGetImageFlags(void)
1063 img
= (GpImage
*)0xdeadbeef;
1065 stat
= GdipGetImageFlags(NULL
, NULL
);
1066 expect(InvalidParameter
, stat
);
1068 stat
= GdipGetImageFlags(NULL
, &flags
);
1069 expect(InvalidParameter
, stat
);
1071 stat
= GdipGetImageFlags(img
, NULL
);
1072 expect(InvalidParameter
, stat
);
1074 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat1bppIndexed
, NULL
, (GpBitmap
**)&img
);
1076 stat
= GdipGetImageFlags(img
, &flags
);
1078 expect(ImageFlagsHasAlpha
, flags
);
1079 GdipDisposeImage(img
);
1081 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat4bppIndexed
, NULL
, (GpBitmap
**)&img
);
1083 stat
= GdipGetImageFlags(img
, &flags
);
1085 expect(ImageFlagsHasAlpha
, flags
);
1086 GdipDisposeImage(img
);
1088 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat8bppIndexed
, NULL
, (GpBitmap
**)&img
);
1090 stat
= GdipGetImageFlags(img
, &flags
);
1092 expect(ImageFlagsHasAlpha
, flags
);
1093 GdipDisposeImage(img
);
1095 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppGrayScale
, NULL
, (GpBitmap
**)&img
);
1097 stat
= GdipGetImageFlags(img
, &flags
);
1099 expect(ImageFlagsNone
, flags
);
1100 GdipDisposeImage(img
);
1102 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB555
, NULL
, (GpBitmap
**)&img
);
1104 stat
= GdipGetImageFlags(img
, &flags
);
1106 expect(ImageFlagsNone
, flags
);
1107 GdipDisposeImage(img
);
1109 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB565
, NULL
, (GpBitmap
**)&img
);
1111 stat
= GdipGetImageFlags(img
, &flags
);
1113 expect(ImageFlagsNone
, flags
);
1114 GdipDisposeImage(img
);
1116 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppARGB1555
, NULL
, (GpBitmap
**)&img
);
1118 stat
= GdipGetImageFlags(img
, &flags
);
1120 expect(ImageFlagsHasAlpha
, flags
);
1121 GdipDisposeImage(img
);
1123 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, NULL
, (GpBitmap
**)&img
);
1125 stat
= GdipGetImageFlags(img
, &flags
);
1127 expect(ImageFlagsNone
, flags
);
1128 GdipDisposeImage(img
);
1130 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&img
);
1132 stat
= GdipGetImageFlags(img
, &flags
);
1134 expect(ImageFlagsNone
, flags
);
1135 GdipDisposeImage(img
);
1137 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppARGB
, NULL
, (GpBitmap
**)&img
);
1139 stat
= GdipGetImageFlags(img
, &flags
);
1141 expect(ImageFlagsHasAlpha
, flags
);
1142 GdipDisposeImage(img
);
1144 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppPARGB
, NULL
, (GpBitmap
**)&img
);
1146 stat
= GdipGetImageFlags(img
, &flags
);
1148 expect(ImageFlagsHasAlpha
, flags
);
1149 GdipDisposeImage(img
);
1151 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat48bppRGB
, NULL
, (GpBitmap
**)&img
);
1155 stat
= GdipGetImageFlags(img
, &flags
);
1157 expect(ImageFlagsNone
, flags
);
1158 GdipDisposeImage(img
);
1161 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB
, NULL
, (GpBitmap
**)&img
);
1166 stat
= GdipGetImageFlags(img
, &flags
);
1168 expect(ImageFlagsHasAlpha
, flags
);
1169 GdipDisposeImage(img
);
1172 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB
, NULL
, (GpBitmap
**)&img
);
1177 stat
= GdipGetImageFlags(img
, &flags
);
1179 expect(ImageFlagsHasAlpha
, flags
);
1180 GdipDisposeImage(img
);
1184 static void test_GdipCloneImage(void)
1190 GpImage
*image_src
, *image_dest
= NULL
;
1191 const INT WIDTH
= 10, HEIGHT
= 20;
1193 /* Create an image, clone it, delete the original, make sure the copy works */
1194 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
1196 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bm
, __LINE__
, FALSE
);
1198 image_src
= ((GpImage
*)bm
);
1199 stat
= GdipCloneImage(image_src
, &image_dest
);
1201 expect_rawformat(&ImageFormatMemoryBMP
, image_dest
, __LINE__
, FALSE
);
1203 stat
= GdipDisposeImage((GpImage
*)bm
);
1205 stat
= GdipGetImageBounds(image_dest
, &rectF
, &unit
);
1208 /* Treat FP values carefully */
1209 expectf((REAL
)WIDTH
, rectF
.Width
);
1210 expectf((REAL
)HEIGHT
, rectF
.Height
);
1212 stat
= GdipDisposeImage(image_dest
);
1216 static void test_testcontrol(void)
1222 stat
= GdipTestControl(TestControlGetBuildNumber
, ¶m
);
1224 ok(param
!= 0, "Build number expected, got %u\n", param
);
1227 static void test_fromhicon(void)
1229 static const BYTE bmp_bits
[1024];
1230 HBITMAP hbmMask
, hbmColor
;
1234 GpBitmap
*bitmap
= NULL
;
1240 stat
= GdipCreateBitmapFromHICON(NULL
, NULL
);
1241 expect(InvalidParameter
, stat
);
1242 stat
= GdipCreateBitmapFromHICON(NULL
, &bitmap
);
1243 expect(InvalidParameter
, stat
);
1245 /* color icon 1 bit */
1246 hbmMask
= CreateBitmap(16, 16, 1, 1, bmp_bits
);
1247 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1248 hbmColor
= CreateBitmap(16, 16, 1, 1, bmp_bits
);
1249 ok(hbmColor
!= 0, "CreateBitmap failed\n");
1253 info
.hbmMask
= hbmMask
;
1254 info
.hbmColor
= hbmColor
;
1255 hIcon
= CreateIconIndirect(&info
);
1256 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
1257 DeleteObject(hbmMask
);
1258 DeleteObject(hbmColor
);
1260 stat
= GdipCreateBitmapFromHICON(hIcon
, &bitmap
);
1262 broken(stat
== InvalidParameter
), /* Win98 */
1263 "Expected Ok, got %.8x\n", stat
);
1265 /* check attributes */
1266 stat
= GdipGetImageHeight((GpImage
*)bitmap
, &dim
);
1269 stat
= GdipGetImageWidth((GpImage
*)bitmap
, &dim
);
1272 stat
= GdipGetImageType((GpImage
*)bitmap
, &type
);
1274 expect(ImageTypeBitmap
, type
);
1275 stat
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
1277 expect(PixelFormat32bppARGB
, format
);
1279 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bitmap
, __LINE__
, FALSE
);
1280 GdipDisposeImage((GpImage
*)bitmap
);
1284 /* color icon 8 bpp */
1285 hbmMask
= CreateBitmap(16, 16, 1, 8, bmp_bits
);
1286 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1287 hbmColor
= CreateBitmap(16, 16, 1, 8, bmp_bits
);
1288 ok(hbmColor
!= 0, "CreateBitmap failed\n");
1292 info
.hbmMask
= hbmMask
;
1293 info
.hbmColor
= hbmColor
;
1294 hIcon
= CreateIconIndirect(&info
);
1295 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
1296 DeleteObject(hbmMask
);
1297 DeleteObject(hbmColor
);
1299 stat
= GdipCreateBitmapFromHICON(hIcon
, &bitmap
);
1302 /* check attributes */
1303 stat
= GdipGetImageHeight((GpImage
*)bitmap
, &dim
);
1306 stat
= GdipGetImageWidth((GpImage
*)bitmap
, &dim
);
1309 stat
= GdipGetImageType((GpImage
*)bitmap
, &type
);
1311 expect(ImageTypeBitmap
, type
);
1312 stat
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
1314 expect(PixelFormat32bppARGB
, format
);
1316 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bitmap
, __LINE__
, FALSE
);
1317 GdipDisposeImage((GpImage
*)bitmap
);
1323 static const unsigned char pngimage
[285] = {
1324 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
1325 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
1326 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
1327 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
1328 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
1329 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
1330 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
1333 static const unsigned char gifimage
[35] = {
1334 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
1335 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
1338 /* 1x1 pixel transparent gif */
1339 static const unsigned char transparentgif
[] = {
1340 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,
1341 0x00,0x00,0x00,0x21,0xf9,0x04,0x01,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,
1342 0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
1345 static const unsigned char bmpimage
[66] = {
1346 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
1347 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
1348 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
1349 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
1353 static const unsigned char jpgimage
[285] = {
1354 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
1355 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
1356 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
1357 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
1358 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
1359 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
1360 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
1361 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1362 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1363 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
1364 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
1365 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1366 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
1367 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
1368 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1369 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
1370 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
1371 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
1373 /* 1x1 pixel tiff */
1374 static const unsigned char tiffimage
[] = {
1375 0x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00,
1376 0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00,
1377 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1378 0x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01,
1379 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00,
1380 0x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00,
1381 0x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01,
1382 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00,
1383 0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00,
1384 0x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01,
1385 0x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00,
1386 0x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1387 0x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
1388 0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65,
1389 0x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74,
1390 0x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,
1393 /* 320x320 twip wmf */
1394 static const unsigned char wmfimage
[180] = {
1395 0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05,
1396 0x00,0x00,0x00,0x00,0xb1,0x52,0x01,0x00,0x09,0x00,0x00,0x03,0x4f,0x00,0x00,0x00,
1397 0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0b,0x02,0x00,0x00,
1398 0x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x02,0x40,0x01,0x40,0x01,0x04,0x00,0x00,0x00,
1399 0x02,0x01,0x01,0x00,0x04,0x00,0x00,0x00,0x04,0x01,0x0d,0x00,0x08,0x00,0x00,0x00,
1400 0xfa,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
1401 0x2d,0x01,0x00,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,0x01,0x00,0x00,0x00,0x00,0x00,
1402 0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x01,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,
1403 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x02,0x00,
1404 0x07,0x00,0x00,0x00,0x1b,0x04,0x40,0x01,0x40,0x01,0x00,0x00,0x00,0x00,0x04,0x00,
1405 0x00,0x00,0xf0,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0xf0,0x01,0x01,0x00,0x03,0x00,
1408 static void test_getrawformat(void)
1410 test_bufferrawformat((void*)pngimage
, sizeof(pngimage
), &ImageFormatPNG
, __LINE__
, FALSE
);
1411 test_bufferrawformat((void*)gifimage
, sizeof(gifimage
), &ImageFormatGIF
, __LINE__
, FALSE
);
1412 test_bufferrawformat((void*)bmpimage
, sizeof(bmpimage
), &ImageFormatBMP
, __LINE__
, FALSE
);
1413 test_bufferrawformat((void*)jpgimage
, sizeof(jpgimage
), &ImageFormatJPEG
, __LINE__
, FALSE
);
1414 test_bufferrawformat((void*)tiffimage
, sizeof(tiffimage
), &ImageFormatTIFF
, __LINE__
, FALSE
);
1415 test_bufferrawformat((void*)wmfimage
, sizeof(wmfimage
), &ImageFormatWMF
, __LINE__
, FALSE
);
1418 static void test_loadwmf(void)
1429 MetafileHeader header
;
1431 hglob
= GlobalAlloc (0, sizeof(wmfimage
));
1432 data
= GlobalLock (hglob
);
1433 memcpy(data
, wmfimage
, sizeof(wmfimage
));
1434 GlobalUnlock(hglob
); data
= NULL
;
1436 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
1437 ok(hres
== S_OK
, "Failed to create a stream\n");
1438 if(hres
!= S_OK
) return;
1440 stat
= GdipLoadImageFromStream(stream
, &img
);
1441 ok(stat
== Ok
, "Failed to create a Bitmap\n");
1443 IStream_Release(stream
);
1447 IStream_Release(stream
);
1449 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1451 todo_wine
expect(UnitPixel
, unit
);
1452 expectf(0.0, bounds
.X
);
1453 expectf(0.0, bounds
.Y
);
1454 todo_wine
expectf(320.0, bounds
.Width
);
1455 todo_wine
expectf(320.0, bounds
.Height
);
1457 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1459 todo_wine
expectf(1440.0, res
);
1461 stat
= GdipGetImageVerticalResolution(img
, &res
);
1463 todo_wine
expectf(1440.0, res
);
1465 memset(&header
, 0, sizeof(header
));
1466 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1470 todo_wine
expect(MetafileTypeWmfPlaceable
, header
.Type
);
1471 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1472 todo_wine
expect(0x300, header
.Version
);
1473 expect(0, header
.EmfPlusFlags
);
1474 todo_wine
expectf(1440.0, header
.DpiX
);
1475 todo_wine
expectf(1440.0, header
.DpiY
);
1476 expect(0, header
.X
);
1477 expect(0, header
.Y
);
1478 todo_wine
expect(320, header
.Width
);
1479 todo_wine
expect(320, header
.Height
);
1480 todo_wine
expect(1, U(header
).WmfHeader
.mtType
);
1481 expect(0, header
.EmfPlusHeaderSize
);
1482 expect(0, header
.LogicalDpiX
);
1483 expect(0, header
.LogicalDpiY
);
1486 GdipDisposeImage(img
);
1489 static void test_createfromwmf(void)
1497 MetafileHeader header
;
1499 hwmf
= SetMetaFileBitsEx(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
),
1500 wmfimage
+sizeof(WmfPlaceableFileHeader
));
1501 ok(hwmf
!= 0, "SetMetaFileBitsEx failed\n");
1503 stat
= GdipCreateMetafileFromWmf(hwmf
, TRUE
,
1504 (WmfPlaceableFileHeader
*)wmfimage
, (GpMetafile
**)&img
);
1507 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1509 expect(UnitPixel
, unit
);
1510 expectf(0.0, bounds
.X
);
1511 expectf(0.0, bounds
.Y
);
1512 expectf(320.0, bounds
.Width
);
1513 expectf(320.0, bounds
.Height
);
1515 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1517 expectf(1440.0, res
);
1519 stat
= GdipGetImageVerticalResolution(img
, &res
);
1521 expectf(1440.0, res
);
1523 memset(&header
, 0, sizeof(header
));
1524 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1528 todo_wine
expect(MetafileTypeWmfPlaceable
, header
.Type
);
1529 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1530 todo_wine
expect(0x300, header
.Version
);
1531 expect(0, header
.EmfPlusFlags
);
1532 todo_wine
expectf(1440.0, header
.DpiX
);
1533 todo_wine
expectf(1440.0, header
.DpiY
);
1534 expect(0, header
.X
);
1535 expect(0, header
.Y
);
1536 todo_wine
expect(320, header
.Width
);
1537 todo_wine
expect(320, header
.Height
);
1538 todo_wine
expect(1, U(header
).WmfHeader
.mtType
);
1539 expect(0, header
.EmfPlusHeaderSize
);
1540 expect(0, header
.LogicalDpiX
);
1541 expect(0, header
.LogicalDpiY
);
1544 GdipDisposeImage(img
);
1547 static void test_resolution(void)
1551 GpGraphics
*graphics
;
1554 int screenxres
, screenyres
;
1557 stat
= GdipCreateBitmapFromScan0(1, 1, 32, PixelFormat24bppRGB
, NULL
, &bitmap
);
1560 /* test invalid values */
1561 stat
= GdipGetImageHorizontalResolution(NULL
, &res
);
1562 expect(InvalidParameter
, stat
);
1564 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, NULL
);
1565 expect(InvalidParameter
, stat
);
1567 stat
= GdipGetImageVerticalResolution(NULL
, &res
);
1568 expect(InvalidParameter
, stat
);
1570 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, NULL
);
1571 expect(InvalidParameter
, stat
);
1573 stat
= GdipBitmapSetResolution(NULL
, 96.0, 96.0);
1574 expect(InvalidParameter
, stat
);
1576 stat
= GdipBitmapSetResolution(bitmap
, 0.0, 0.0);
1577 expect(InvalidParameter
, stat
);
1579 /* defaults to screen resolution */
1580 screendc
= GetDC(0);
1582 screenxres
= GetDeviceCaps(screendc
, LOGPIXELSX
);
1583 screenyres
= GetDeviceCaps(screendc
, LOGPIXELSY
);
1585 ReleaseDC(0, screendc
);
1587 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1589 expectf((REAL
)screenxres
, res
);
1591 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1593 expectf((REAL
)screenyres
, res
);
1595 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1597 stat
= GdipGetDpiX(graphics
, &res
);
1599 expectf((REAL
)screenxres
, res
);
1600 stat
= GdipGetDpiY(graphics
, &res
);
1602 expectf((REAL
)screenyres
, res
);
1604 /* test changing the resolution */
1605 stat
= GdipBitmapSetResolution(bitmap
, screenxres
*2.0, screenyres
*3.0);
1608 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1610 expectf(screenxres
*2.0, res
);
1612 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1614 expectf(screenyres
*3.0, res
);
1616 stat
= GdipGetDpiX(graphics
, &res
);
1618 expectf((REAL
)screenxres
, res
);
1619 stat
= GdipGetDpiY(graphics
, &res
);
1621 expectf((REAL
)screenyres
, res
);
1623 stat
= GdipDeleteGraphics(graphics
);
1626 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1628 stat
= GdipGetDpiX(graphics
, &res
);
1630 expectf(screenxres
*2.0, res
);
1631 stat
= GdipGetDpiY(graphics
, &res
);
1633 expectf(screenyres
*3.0, res
);
1634 stat
= GdipDeleteGraphics(graphics
);
1637 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1641 static void test_createhbitmap(void)
1645 HBITMAP hbitmap
, oldhbitmap
;
1652 memset(bits
, 0x68, 640);
1655 stat
= GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB
, bits
, &bitmap
);
1658 /* test NULL values */
1659 stat
= GdipCreateHBITMAPFromBitmap(NULL
, &hbitmap
, 0);
1660 expect(InvalidParameter
, stat
);
1662 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, NULL
, 0);
1663 expect(InvalidParameter
, stat
);
1665 /* create HBITMAP */
1666 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1671 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1672 expect(sizeof(BITMAP
), ret
);
1674 expect(0, bm
.bmType
);
1675 expect(10, bm
.bmWidth
);
1676 expect(20, bm
.bmHeight
);
1677 expect(40, bm
.bmWidthBytes
);
1678 expect(1, bm
.bmPlanes
);
1679 expect(32, bm
.bmBitsPixel
);
1680 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1684 DWORD val
= *(DWORD
*)bm
.bmBits
;
1685 ok(val
== 0xff686868, "got %x, expected 0xff686868\n", val
);
1688 hdc
= CreateCompatibleDC(NULL
);
1690 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1691 pixel
= GetPixel(hdc
, 5, 5);
1692 SelectObject(hdc
, oldhbitmap
);
1696 expect(0x686868, pixel
);
1698 DeleteObject(hbitmap
);
1701 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1704 /* make (1,0) have no alpha and (2,0) a different blue value. */
1708 /* create alpha Bitmap */
1709 stat
= GdipCreateBitmapFromScan0(8, 20, 32, PixelFormat32bppARGB
, bits
, &bitmap
);
1712 /* create HBITMAP */
1713 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1718 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1719 expect(sizeof(BITMAP
), ret
);
1721 expect(0, bm
.bmType
);
1722 expect(8, bm
.bmWidth
);
1723 expect(20, bm
.bmHeight
);
1724 expect(32, bm
.bmWidthBytes
);
1725 expect(1, bm
.bmPlanes
);
1726 expect(32, bm
.bmBitsPixel
);
1727 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1731 DWORD val
= *(DWORD
*)bm
.bmBits
;
1732 ok(val
== 0x682a2a2a, "got %x, expected 0x682a2a2a\n", val
);
1733 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1734 ok(val
== 0x0, "got %x, expected 0x682a2a2a\n", val
);
1737 hdc
= CreateCompatibleDC(NULL
);
1739 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1740 pixel
= GetPixel(hdc
, 5, 5);
1741 expect(0x2a2a2a, pixel
);
1742 pixel
= GetPixel(hdc
, 1, 0);
1745 SelectObject(hdc
, oldhbitmap
);
1750 DeleteObject(hbitmap
);
1753 /* create HBITMAP with bkgnd colour */
1754 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0xff00ff);
1759 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1760 expect(sizeof(BITMAP
), ret
);
1762 expect(0, bm
.bmType
);
1763 expect(8, bm
.bmWidth
);
1764 expect(20, bm
.bmHeight
);
1765 expect(32, bm
.bmWidthBytes
);
1766 expect(1, bm
.bmPlanes
);
1767 expect(32, bm
.bmBitsPixel
);
1768 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1772 DWORD val
= *(DWORD
*)bm
.bmBits
;
1773 ok(val
== 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val
);
1774 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1775 ok(val
== 0xff00ff, "got %x, expected 0x682a2a2a\n", val
);
1778 hdc
= CreateCompatibleDC(NULL
);
1780 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1781 pixel
= GetPixel(hdc
, 5, 5);
1782 expect(0xc12ac1, pixel
);
1783 pixel
= GetPixel(hdc
, 1, 0);
1784 expect(0xff00ff, pixel
);
1785 pixel
= GetPixel(hdc
, 2, 0);
1786 expect(0xb12ac1, pixel
);
1788 SelectObject(hdc
, oldhbitmap
);
1790 DeleteObject(hbitmap
);
1793 /* create HBITMAP with bkgnd colour with alpha and show it behaves with no alpha. */
1794 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0x80ff00ff);
1799 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1800 expect(sizeof(BITMAP
), ret
);
1802 expect(0, bm
.bmType
);
1803 expect(8, bm
.bmWidth
);
1804 expect(20, bm
.bmHeight
);
1805 expect(32, bm
.bmWidthBytes
);
1806 expect(1, bm
.bmPlanes
);
1807 expect(32, bm
.bmBitsPixel
);
1808 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1812 DWORD val
= *(DWORD
*)bm
.bmBits
;
1813 ok(val
== 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val
);
1814 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1815 ok(val
== 0xff00ff, "got %x, expected 0x682a2a2a\n", val
);
1818 hdc
= CreateCompatibleDC(NULL
);
1820 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1821 pixel
= GetPixel(hdc
, 5, 5);
1822 expect(0xc12ac1, pixel
);
1823 pixel
= GetPixel(hdc
, 1, 0);
1824 expect(0xff00ff, pixel
);
1825 pixel
= GetPixel(hdc
, 2, 0);
1826 expect(0xb12ac1, pixel
);
1828 SelectObject(hdc
, oldhbitmap
);
1830 DeleteObject(hbitmap
);
1833 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1837 static void test_getthumbnail(void)
1840 GpImage
*bitmap1
, *bitmap2
;
1843 stat
= GdipGetImageThumbnail(NULL
, 0, 0, &bitmap2
, NULL
, NULL
);
1844 expect(InvalidParameter
, stat
);
1846 stat
= GdipCreateBitmapFromScan0(128, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1849 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, NULL
, NULL
, NULL
);
1850 expect(InvalidParameter
, stat
);
1852 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, &bitmap2
, NULL
, NULL
);
1857 stat
= GdipGetImageWidth(bitmap2
, &width
);
1861 stat
= GdipGetImageHeight(bitmap2
, &height
);
1863 expect(120, height
);
1865 GdipDisposeImage(bitmap2
);
1868 GdipDisposeImage(bitmap1
);
1871 stat
= GdipCreateBitmapFromScan0(64, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1874 stat
= GdipGetImageThumbnail(bitmap1
, 32, 32, &bitmap2
, NULL
, NULL
);
1879 stat
= GdipGetImageWidth(bitmap2
, &width
);
1883 stat
= GdipGetImageHeight(bitmap2
, &height
);
1887 GdipDisposeImage(bitmap2
);
1890 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, &bitmap2
, NULL
, NULL
);
1895 stat
= GdipGetImageWidth(bitmap2
, &width
);
1899 stat
= GdipGetImageHeight(bitmap2
, &height
);
1901 expect(120, height
);
1903 GdipDisposeImage(bitmap2
);
1906 GdipDisposeImage(bitmap1
);
1909 static void test_getsetpixel(void)
1914 BYTE bits
[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00,
1915 0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00};
1917 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, bits
, &bitmap
);
1920 /* null parameters */
1921 stat
= GdipBitmapGetPixel(NULL
, 1, 1, &color
);
1922 expect(InvalidParameter
, stat
);
1924 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, NULL
);
1925 expect(InvalidParameter
, stat
);
1927 stat
= GdipBitmapSetPixel(NULL
, 1, 1, 0);
1928 expect(InvalidParameter
, stat
);
1931 stat
= GdipBitmapGetPixel(bitmap
, -1, 1, &color
);
1932 expect(InvalidParameter
, stat
);
1934 stat
= GdipBitmapSetPixel(bitmap
, -1, 1, 0);
1935 expect(InvalidParameter
, stat
);
1937 stat
= GdipBitmapGetPixel(bitmap
, 1, -1, &color
);
1938 ok(stat
== InvalidParameter
||
1939 broken(stat
== Ok
), /* Older gdiplus */
1940 "Expected InvalidParameter, got %.8x\n", stat
);
1942 if (0) /* crashes some gdiplus implementations */
1944 stat
= GdipBitmapSetPixel(bitmap
, 1, -1, 0);
1945 ok(stat
== InvalidParameter
||
1946 broken(stat
== Ok
), /* Older gdiplus */
1947 "Expected InvalidParameter, got %.8x\n", stat
);
1950 stat
= GdipBitmapGetPixel(bitmap
, 2, 1, &color
);
1951 expect(InvalidParameter
, stat
);
1953 stat
= GdipBitmapSetPixel(bitmap
, 2, 1, 0);
1954 expect(InvalidParameter
, stat
);
1956 stat
= GdipBitmapGetPixel(bitmap
, 1, 2, &color
);
1957 expect(InvalidParameter
, stat
);
1959 stat
= GdipBitmapSetPixel(bitmap
, 1, 2, 0);
1960 expect(InvalidParameter
, stat
);
1963 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
1965 expect(0xffffffff, color
);
1967 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
1969 expect(0xff0000ff, color
);
1971 stat
= GdipBitmapSetPixel(bitmap
, 1, 1, 0xff676869);
1974 stat
= GdipBitmapSetPixel(bitmap
, 0, 0, 0xff474849);
1977 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
1979 expect(0xff676869, color
);
1981 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
1983 expect(0xff474849, color
);
1985 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1989 static void check_halftone_palette(ColorPalette
*palette
)
1991 static const BYTE halftone_values
[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
1994 for (i
=0; i
<palette
->Count
; i
++)
1996 ARGB expected
=0xff000000;
1999 if (i
&1) expected
|= 0x800000;
2000 if (i
&2) expected
|= 0x8000;
2001 if (i
&4) expected
|= 0x80;
2005 expected
= 0xffc0c0c0;
2009 if (i
&1) expected
|= 0xff0000;
2010 if (i
&2) expected
|= 0xff00;
2011 if (i
&4) expected
|= 0xff;
2015 expected
= 0x00000000;
2019 expected
|= halftone_values
[(i
-40)%6];
2020 expected
|= halftone_values
[((i
-40)/6)%6] << 8;
2021 expected
|= halftone_values
[((i
-40)/36)%6] << 16;
2023 ok(expected
== palette
->Entries
[i
], "Expected %.8x, got %.8x, i=%u/%u\n",
2024 expected
, palette
->Entries
[i
], i
, palette
->Count
);
2028 static void test_palette(void)
2034 ColorPalette
*palette
=(ColorPalette
*)buffer
;
2035 ARGB
*entries
= palette
->Entries
;
2038 /* test initial palette from non-indexed bitmap */
2039 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, NULL
, &bitmap
);
2042 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2044 expect(sizeof(UINT
)*2+sizeof(ARGB
), size
);
2046 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2048 expect(0, palette
->Count
);
2050 /* test setting palette on not-indexed bitmap */
2053 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2056 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2058 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2060 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2062 expect(3, palette
->Count
);
2064 GdipDisposeImage((GpImage
*)bitmap
);
2066 /* test initial palette on 1-bit bitmap */
2067 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat1bppIndexed
, NULL
, &bitmap
);
2070 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2072 expect(sizeof(UINT
)*2+sizeof(ARGB
)*2, size
);
2074 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2076 expect(PaletteFlagsGrayScale
, palette
->Flags
);
2077 expect(2, palette
->Count
);
2079 expect(0xff000000, entries
[0]);
2080 expect(0xffffffff, entries
[1]);
2082 /* test getting/setting pixels */
2083 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2085 expect(0xff000000, color
);
2087 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffffffff);
2089 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2093 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2095 expect(0xffffffff, color
);
2098 GdipDisposeImage((GpImage
*)bitmap
);
2100 /* test initial palette on 4-bit bitmap */
2101 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat4bppIndexed
, NULL
, &bitmap
);
2104 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2106 expect(sizeof(UINT
)*2+sizeof(ARGB
)*16, size
);
2108 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2110 expect(0, palette
->Flags
);
2111 expect(16, palette
->Count
);
2113 check_halftone_palette(palette
);
2115 /* test getting/setting pixels */
2116 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2118 expect(0xff000000, color
);
2120 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffff00ff);
2122 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2126 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2128 expect(0xffff00ff, color
);
2131 GdipDisposeImage((GpImage
*)bitmap
);
2133 /* test initial palette on 8-bit bitmap */
2134 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat8bppIndexed
, NULL
, &bitmap
);
2137 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2139 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2141 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2143 expect(PaletteFlagsHalftone
, palette
->Flags
);
2144 expect(256, palette
->Count
);
2146 check_halftone_palette(palette
);
2148 /* test getting/setting pixels */
2149 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2151 expect(0xff000000, color
);
2153 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffcccccc);
2155 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2159 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2161 expect(0xffcccccc, color
);
2164 /* test setting/getting a different palette */
2165 entries
[1] = 0xffcccccc;
2167 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2172 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2174 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2176 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2178 expect(PaletteFlagsHalftone
, palette
->Flags
);
2179 expect(256, palette
->Count
);
2180 expect(0xffcccccc, entries
[1]);
2182 /* test count < 256 */
2183 palette
->Flags
= 12345;
2186 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2190 entries
[3] = 0xdeadbeef;
2192 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2194 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2196 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2198 expect(12345, palette
->Flags
);
2199 expect(3, palette
->Count
);
2200 expect(0xffcccccc, entries
[1]);
2201 expect(0xdeadbeef, entries
[3]);
2203 /* test count > 256 */
2204 palette
->Count
= 257;
2206 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2207 ok(stat
== InvalidParameter
||
2208 broken(stat
== Ok
), /* Old gdiplus behavior */
2209 "Expected %.8x, got %.8x\n", InvalidParameter
, stat
);
2211 GdipDisposeImage((GpImage
*)bitmap
);
2214 static void test_colormatrix(void)
2217 ColorMatrix colormatrix
, graymatrix
;
2218 GpImageAttributes
*imageattr
;
2219 const ColorMatrix identity
= {{
2220 {1.0,0.0,0.0,0.0,0.0},
2221 {0.0,1.0,0.0,0.0,0.0},
2222 {0.0,0.0,1.0,0.0,0.0},
2223 {0.0,0.0,0.0,1.0,0.0},
2224 {0.0,0.0,0.0,0.0,1.0}}};
2225 const ColorMatrix double_red
= {{
2226 {2.0,0.0,0.0,0.0,0.0},
2227 {0.0,1.0,0.0,0.0,0.0},
2228 {0.0,0.0,1.0,0.0,0.0},
2229 {0.0,0.0,0.0,1.0,0.0},
2230 {0.0,0.0,0.0,0.0,1.0}}};
2231 const ColorMatrix asymmetric
= {{
2232 {0.0,1.0,0.0,0.0,0.0},
2233 {0.0,0.0,1.0,0.0,0.0},
2234 {0.0,0.0,0.0,1.0,0.0},
2235 {1.0,0.0,0.0,0.0,0.0},
2236 {0.0,0.0,0.0,0.0,1.0}}};
2237 GpBitmap
*bitmap1
, *bitmap2
;
2238 GpGraphics
*graphics
;
2241 colormatrix
= identity
;
2242 graymatrix
= identity
;
2244 stat
= GdipSetImageAttributesColorMatrix(NULL
, ColorAdjustTypeDefault
,
2245 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2246 expect(InvalidParameter
, stat
);
2248 stat
= GdipCreateImageAttributes(&imageattr
);
2251 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2252 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2255 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2256 TRUE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2257 expect(InvalidParameter
, stat
);
2259 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2260 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2263 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2264 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsSkipGrays
);
2267 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2268 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsAltGray
);
2269 expect(InvalidParameter
, stat
);
2271 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2272 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsAltGray
);
2275 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2276 TRUE
, &colormatrix
, &graymatrix
, 3);
2277 expect(InvalidParameter
, stat
);
2279 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeCount
,
2280 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2281 expect(InvalidParameter
, stat
);
2283 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeAny
,
2284 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2285 expect(InvalidParameter
, stat
);
2287 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2288 FALSE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2291 /* Drawing a bitmap transforms the colors */
2292 colormatrix
= double_red
;
2293 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2294 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2297 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
2300 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
2303 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff40ccee);
2306 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2309 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2310 UnitPixel
, imageattr
, NULL
, NULL
);
2313 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2315 expect(0xff80ccee, color
);
2317 colormatrix
= asymmetric
;
2318 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2319 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2322 stat
= GdipBitmapSetPixel(bitmap2
, 0, 0, 0);
2325 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2326 UnitPixel
, imageattr
, NULL
, NULL
);
2329 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2331 ok(color_match(0xeeff40cc, color
, 3), "expected 0xeeff40cc, got 0x%08x\n", color
);
2333 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2336 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2337 UnitPixel
, imageattr
, NULL
, NULL
);
2340 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2342 ok(color_match(0xff40ccee, color
, 1), "Expected ff40ccee, got %.8x\n", color
);
2344 GdipDeleteGraphics(graphics
);
2345 GdipDisposeImage((GpImage
*)bitmap1
);
2346 GdipDisposeImage((GpImage
*)bitmap2
);
2347 GdipDisposeImageAttributes(imageattr
);
2350 static void test_gamma(void)
2353 GpImageAttributes
*imageattr
;
2354 GpBitmap
*bitmap1
, *bitmap2
;
2355 GpGraphics
*graphics
;
2358 stat
= GdipSetImageAttributesGamma(NULL
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2359 expect(InvalidParameter
, stat
);
2361 stat
= GdipCreateImageAttributes(&imageattr
);
2364 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2367 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeAny
, TRUE
, 1.0);
2368 expect(InvalidParameter
, stat
);
2370 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, -1.0);
2371 expect(InvalidParameter
, stat
);
2373 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.0);
2374 expect(InvalidParameter
, stat
);
2376 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.5);
2379 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0.0);
2382 /* Drawing a bitmap transforms the colors */
2383 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 3.0);
2386 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
2389 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
2392 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff80ffff);
2395 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2398 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2399 UnitPixel
, imageattr
, NULL
, NULL
);
2402 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2404 ok(color_match(0xff20ffff, color
, 1), "Expected ff20ffff, got %.8x\n", color
);
2406 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2409 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2410 UnitPixel
, imageattr
, NULL
, NULL
);
2413 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2415 ok(color_match(0xff80ffff, color
, 1), "Expected ff80ffff, got %.8x\n", color
);
2417 GdipDeleteGraphics(graphics
);
2418 GdipDisposeImage((GpImage
*)bitmap1
);
2419 GdipDisposeImage((GpImage
*)bitmap2
);
2420 GdipDisposeImageAttributes(imageattr
);
2423 /* 1x1 pixel gif, 2 frames; first frame is white, second is black */
2424 static const unsigned char gifanimation
[72] = {
2425 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
2426 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0xf9,0x04,0x00,0x0a,0x00,0xff,
2427 0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x4c,0x01,0x00,
2428 0x21,0xf9,0x04,0x01,0x0a,0x00,0x01,0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,
2429 0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
2432 /* Generated with ImageMagick:
2433 * convert -transparent black -delay 100 -size 8x2 xc:black \
2434 * -dispose none -page +0+0 -size 2x2 xc:red \
2435 * -dispose background -page +2+0 -size 2x2 xc:blue \
2436 * -dispose previous -page +4+0 -size 2x2 xc:green \
2437 * -dispose undefined -page +6+0 -size 2x2 xc:gray \
2440 static const unsigned char gifanimation2
[] = {
2441 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x08, 0x00,
2442 0x02, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
2443 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x64,
2444 0x00, 0x00, 0x00, 0x21, 0xff, 0x0b, 0x4e, 0x45,
2445 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e,
2446 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00,
2447 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
2448 0x02, 0x04, 0x84, 0x8f, 0x09, 0x05, 0x00, 0x21,
2449 0xf9, 0x04, 0x04, 0x64, 0x00, 0x00, 0x00, 0x2c,
2450 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2451 0x81, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
2452 0x00, 0x00, 0xff, 0x00, 0x00, 0x02, 0x03, 0x44,
2453 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x08, 0x64,
2454 0x00, 0x00, 0x00, 0x2c, 0x02, 0x00, 0x00, 0x00,
2455 0x02, 0x00, 0x02, 0x00, 0x81, 0x00, 0x00, 0xff,
2456 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
2457 0xff, 0x02, 0x03, 0x44, 0x34, 0x05, 0x00, 0x21,
2458 0xf9, 0x04, 0x0c, 0x64, 0x00, 0x00, 0x00, 0x2c,
2459 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2460 0x81, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00,
2461 0x80, 0x00, 0x00, 0x80, 0x00, 0x02, 0x03, 0x44,
2462 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x64,
2463 0x00, 0x00, 0x00, 0x2c, 0x06, 0x00, 0x00, 0x00,
2464 0x02, 0x00, 0x02, 0x00, 0x80, 0x7e, 0x7e, 0x7e,
2465 0x00, 0x00, 0x00, 0x02, 0x02, 0x84, 0x51, 0x00,
2469 static ARGB gifanimation2_pixels
[5][4] = {
2471 {0xffff0000, 0, 0, 0},
2472 {0xffff0000, 0xff0000ff, 0, 0},
2473 {0xffff0000, 0, 0xff008000, 0},
2474 {0xffff0000, 0, 0, 0xff7e7e7e}
2477 static void test_multiframegif(void)
2488 PixelFormat pixel_format
;
2489 INT palette_size
, i
, j
;
2490 char palette_buf
[256];
2491 ColorPalette
*palette
;
2492 ARGB
*palette_entries
;
2494 /* Test frame functions with an animated GIF */
2495 hglob
= GlobalAlloc (0, sizeof(gifanimation
));
2496 data
= GlobalLock (hglob
);
2497 memcpy(data
, gifanimation
, sizeof(gifanimation
));
2498 GlobalUnlock(hglob
);
2500 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2501 ok(hres
== S_OK
, "Failed to create a stream\n");
2502 if(hres
!= S_OK
) return;
2504 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2505 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2507 IStream_Release(stream
);
2511 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2513 expect(PixelFormat32bppARGB
, pixel_format
);
2515 stat
= GdipGetImagePaletteSize((GpImage
*)bmp
, &palette_size
);
2517 ok(palette_size
== sizeof(ColorPalette
) ||
2518 broken(palette_size
== sizeof(ColorPalette
)+sizeof(ARGB
[3])),
2519 "palette_size = %d\n", palette_size
);
2521 /* Bitmap starts at frame 0 */
2523 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2525 expect(0xffffffff, color
);
2527 /* Check that we get correct metadata */
2528 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2532 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2534 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2537 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2541 /* SelectActiveFrame overwrites our current data */
2542 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2546 GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2548 expect(0xff000000, color
);
2550 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2554 GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2556 expect(0xffffffff, color
);
2558 /* Write over the image data */
2559 stat
= GdipBitmapSetPixel(bmp
, 0, 0, 0xff000000);
2562 /* Switching to the same frame does not overwrite our changes */
2563 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2566 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2568 expect(0xff000000, color
);
2570 /* But switching to another frame and back does */
2571 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2574 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2577 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2579 expect(0xffffffff, color
);
2581 /* rotate/flip discards the information about other frames */
2582 stat
= GdipImageRotateFlip((GpImage
*)bmp
, Rotate90FlipNone
);
2586 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2590 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bmp
, __LINE__
, FALSE
);
2592 GdipDisposeImage((GpImage
*)bmp
);
2593 IStream_Release(stream
);
2595 /* Test with a non-animated gif */
2596 hglob
= GlobalAlloc (0, sizeof(gifimage
));
2597 data
= GlobalLock (hglob
);
2598 memcpy(data
, gifimage
, sizeof(gifimage
));
2599 GlobalUnlock(hglob
);
2601 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2602 ok(hres
== S_OK
, "Failed to create a stream\n");
2603 if(hres
!= S_OK
) return;
2605 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2606 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2608 IStream_Release(stream
);
2612 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2614 expect(PixelFormat8bppIndexed
, pixel_format
);
2616 /* Check metadata */
2617 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2621 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2623 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2626 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2630 GdipDisposeImage((GpImage
*)bmp
);
2631 IStream_Release(stream
);
2633 /* Test with a non-animated transparent gif */
2634 hglob
= GlobalAlloc (0, sizeof(transparentgif
));
2635 data
= GlobalLock (hglob
);
2636 memcpy(data
, transparentgif
, sizeof(transparentgif
));
2637 GlobalUnlock(hglob
);
2639 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2640 ok(hres
== S_OK
, "Failed to create a stream\n");
2642 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2643 IStream_Release(stream
);
2644 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2646 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2648 expect(PixelFormat8bppIndexed
, pixel_format
);
2650 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2654 stat
= GdipGetImagePaletteSize((GpImage
*)bmp
, &palette_size
);
2656 ok(palette_size
== sizeof(ColorPalette
)+sizeof(ARGB
),
2657 "palette_size = %d\n", palette_size
);
2659 memset(palette_buf
, 0xfe, sizeof(palette_buf
));
2660 palette
= (ColorPalette
*)palette_buf
;
2661 stat
= GdipGetImagePalette((GpImage
*)bmp
, palette
,
2662 sizeof(ColorPalette
)+sizeof(ARGB
));
2663 palette_entries
= palette
->Entries
;
2665 expect(PaletteFlagsHasAlpha
, palette
->Flags
);
2666 expect(2, palette
->Count
);
2667 expect(0, palette_entries
[0]);
2668 expect(0xff000000, palette_entries
[1]);
2671 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2675 GdipDisposeImage((GpImage
*)bmp
);
2677 /* Test frame dispose methods */
2678 hglob
= GlobalAlloc (0, sizeof(gifanimation2
));
2679 data
= GlobalLock (hglob
);
2680 memcpy(data
, gifanimation2
, sizeof(gifanimation2
));
2681 GlobalUnlock(hglob
);
2683 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2684 ok(hres
== S_OK
, "Failed to create a stream\n");
2686 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2687 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2688 IStream_Release(stream
);
2690 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2692 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2694 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2698 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2702 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 3);
2703 stat
= GdipBitmapGetPixel(bmp
, 2, 0, &color
);
2705 ok(color
==0 || broken(color
==0xff0000ff), "color = %x\n", color
);
2707 win_skip("broken animated gif support\n");
2708 GdipDisposeImage((GpImage
*)bmp
);
2712 for(i
=0; i
<6; i
++) {
2713 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, i
%5);
2716 for(j
=0; j
<4; j
++) {
2717 stat
= GdipBitmapGetPixel(bmp
, j
*2, 0, &color
);
2719 ok(gifanimation2_pixels
[i
%5][j
] == color
, "at %d,%d got %x, expected %x\n", i
, j
, color
, gifanimation2_pixels
[i
%5][j
]);
2723 GdipDisposeImage((GpImage
*)bmp
);
2726 static void test_rotateflip(void)
2731 static const BYTE orig_bits
[24] = {
2732 0,0,0xff, 0,0xff,0, 0xff,0,0, 23,23,23,
2733 0xff,0xff,0, 0xff,0,0xff, 0,0xff,0xff, 23,23,23};
2737 memcpy(bits
, orig_bits
, sizeof(bits
));
2738 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2741 stat
= GdipImageRotateFlip(bitmap
, Rotate90FlipNone
);
2744 stat
= GdipGetImageWidth(bitmap
, &width
);
2746 stat
= GdipGetImageHeight(bitmap
, &height
);
2751 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2753 expect(0xff00ffff, color
);
2755 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 0, &color
);
2757 expect(0xffff0000, color
);
2759 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 2, &color
);
2761 expect(0xffffff00, color
);
2763 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 2, &color
);
2765 expect(0xff0000ff, color
);
2769 expect(0xff, bits
[2]);
2771 GdipDisposeImage(bitmap
);
2773 memcpy(bits
, orig_bits
, sizeof(bits
));
2774 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2777 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipX
);
2780 stat
= GdipGetImageWidth(bitmap
, &width
);
2782 stat
= GdipGetImageHeight(bitmap
, &height
);
2787 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2789 expect(0xff0000ff, color
);
2791 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
2793 expect(0xffff0000, color
);
2795 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
2797 expect(0xffffff00, color
);
2799 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
2801 expect(0xff00ffff, color
);
2805 expect(0xff, bits
[2]);
2807 GdipDisposeImage(bitmap
);
2809 memcpy(bits
, orig_bits
, sizeof(bits
));
2810 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2813 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipY
);
2816 stat
= GdipGetImageWidth(bitmap
, &width
);
2818 stat
= GdipGetImageHeight(bitmap
, &height
);
2823 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2825 expect(0xff00ffff, color
);
2827 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
2829 expect(0xffffff00, color
);
2831 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
2833 expect(0xffff0000, color
);
2835 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
2837 expect(0xff0000ff, color
);
2841 expect(0xff, bits
[2]);
2843 GdipDisposeImage(bitmap
);
2846 static void test_remaptable(void)
2849 GpImageAttributes
*imageattr
;
2850 GpBitmap
*bitmap1
, *bitmap2
;
2851 GpGraphics
*graphics
;
2855 map
= GdipAlloc(sizeof(ColorMap
));
2857 map
->oldColor
.Argb
= 0xff00ff00;
2858 map
->newColor
.Argb
= 0xffff00ff;
2860 stat
= GdipSetImageAttributesRemapTable(NULL
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
2861 expect(InvalidParameter
, stat
);
2863 stat
= GdipCreateImageAttributes(&imageattr
);
2866 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, NULL
);
2867 expect(InvalidParameter
, stat
);
2869 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeCount
, TRUE
, 1, map
);
2870 expect(InvalidParameter
, stat
);
2872 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeAny
, TRUE
, 1, map
);
2873 expect(InvalidParameter
, stat
);
2875 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0, map
);
2876 expect(InvalidParameter
, stat
);
2878 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0, NULL
);
2881 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
2884 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
2887 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
2890 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff00ff00);
2893 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2896 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2897 UnitPixel
, imageattr
, NULL
, NULL
);
2900 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2902 ok(color_match(0xffff00ff, color
, 1), "Expected ffff00ff, got %.8x\n", color
);
2904 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2907 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2908 UnitPixel
, imageattr
, NULL
, NULL
);
2911 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2913 ok(color_match(0xff00ff00, color
, 1), "Expected ff00ff00, got %.8x\n", color
);
2915 GdipDeleteGraphics(graphics
);
2916 GdipDisposeImage((GpImage
*)bitmap1
);
2917 GdipDisposeImage((GpImage
*)bitmap2
);
2918 GdipDisposeImageAttributes(imageattr
);
2922 static void test_colorkey(void)
2925 GpImageAttributes
*imageattr
;
2926 GpBitmap
*bitmap1
, *bitmap2
;
2927 GpGraphics
*graphics
;
2930 stat
= GdipSetImageAttributesColorKeys(NULL
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
2931 expect(InvalidParameter
, stat
);
2933 stat
= GdipCreateImageAttributes(&imageattr
);
2936 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeCount
, TRUE
, 0xff405060, 0xff708090);
2937 expect(InvalidParameter
, stat
);
2939 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeAny
, TRUE
, 0xff405060, 0xff708090);
2940 expect(InvalidParameter
, stat
);
2942 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
2945 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
2948 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
2951 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0x20405060);
2954 stat
= GdipBitmapSetPixel(bitmap1
, 0, 1, 0x40506070);
2957 stat
= GdipBitmapSetPixel(bitmap1
, 1, 0, 0x60708090);
2960 stat
= GdipBitmapSetPixel(bitmap1
, 1, 1, 0xffffffff);
2963 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2966 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
2967 UnitPixel
, imageattr
, NULL
, NULL
);
2970 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2972 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
2974 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
2976 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
2978 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
2980 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
2982 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
2984 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
2986 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2989 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
2990 UnitPixel
, imageattr
, NULL
, NULL
);
2993 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2995 ok(color_match(0x20405060, color
, 1), "Expected 20405060, got %.8x\n", color
);
2997 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
2999 ok(color_match(0x40506070, color
, 1), "Expected 40506070, got %.8x\n", color
);
3001 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
3003 ok(color_match(0x60708090, color
, 1), "Expected 60708090, got %.8x\n", color
);
3005 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
3007 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
3010 GdipDeleteGraphics(graphics
);
3011 GdipDisposeImage((GpImage
*)bitmap1
);
3012 GdipDisposeImage((GpImage
*)bitmap2
);
3013 GdipDisposeImageAttributes(imageattr
);
3016 static void test_dispose(void)
3020 char invalid_image
[256];
3022 stat
= GdipDisposeImage(NULL
);
3023 expect(InvalidParameter
, stat
);
3025 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, (GpBitmap
**)&image
);
3028 stat
= GdipDisposeImage(image
);
3031 stat
= GdipDisposeImage(image
);
3032 expect(ObjectBusy
, stat
);
3034 memset(invalid_image
, 0, 256);
3035 stat
= GdipDisposeImage((GpImage
*)invalid_image
);
3036 expect(ObjectBusy
, stat
);
3039 static LONG
obj_refcount(void *obj
)
3041 IUnknown_AddRef((IUnknown
*)obj
);
3042 return IUnknown_Release((IUnknown
*)obj
);
3045 static GpImage
*load_image(const BYTE
*image_data
, UINT image_size
)
3052 GpImage
*image
= NULL
, *clone
;
3053 ImageType image_type
;
3054 LONG refcount
, old_refcount
;
3056 hmem
= GlobalAlloc(0, image_size
);
3057 data
= GlobalLock(hmem
);
3058 memcpy(data
, image_data
, image_size
);
3061 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
3062 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
3063 if (hr
!= S_OK
) return NULL
;
3065 refcount
= obj_refcount(stream
);
3066 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3068 status
= GdipLoadImageFromStream(stream
, &image
);
3069 ok(status
== Ok
|| broken(status
== InvalidParameter
), /* XP */
3070 "GdipLoadImageFromStream error %d\n", status
);
3073 IStream_Release(stream
);
3077 status
= GdipGetImageType(image
, &image_type
);
3078 ok(status
== Ok
, "GdipGetImageType error %d\n", status
);
3080 refcount
= obj_refcount(stream
);
3081 if (image_type
== ImageTypeBitmap
)
3082 ok(refcount
> 1, "expected stream refcount > 1, got %d\n", refcount
);
3084 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3085 old_refcount
= refcount
;
3087 status
= GdipCloneImage(image
, &clone
);
3088 ok(status
== Ok
, "GdipCloneImage error %d\n", status
);
3089 refcount
= obj_refcount(stream
);
3090 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3091 status
= GdipDisposeImage(clone
);
3092 ok(status
== Ok
, "GdipDisposeImage error %d\n", status
);
3093 refcount
= obj_refcount(stream
);
3094 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3096 refcount
= IStream_Release(stream
);
3097 if (image_type
== ImageTypeBitmap
)
3098 ok(refcount
>= 1, "expected stream refcount != 0\n");
3100 ok(refcount
== 0, "expected stream refcount 0, got %d\n", refcount
);
3105 static void test_image_properties(void)
3107 static const struct test_data
3109 const BYTE
*image_data
;
3111 ImageType image_type
;
3113 UINT prop_count2
; /* if win7 behaves differently */
3114 /* 1st property attributes */
3116 UINT prop_size2
; /* if win7 behaves differently */
3118 UINT prop_id2
; /* if win7 behaves differently */
3122 { pngimage
, sizeof(pngimage
), ImageTypeBitmap
, 4, ~0, 1, 20, 0x5110, 0x132 },
3123 { jpgimage
, sizeof(jpgimage
), ImageTypeBitmap
, 2, ~0, 128, 0, 0x5090, 0x5091 },
3124 { tiffimage
, sizeof(tiffimage
), ImageTypeBitmap
, 16, 0, 4, 0, 0xfe, 0 },
3125 { bmpimage
, sizeof(bmpimage
), ImageTypeBitmap
, 0, 0, 0, 0, 0, 0 },
3126 { wmfimage
, sizeof(wmfimage
), ImageTypeMetafile
, 0, 0, 0, 0, 0, 0 }
3130 UINT prop_count
, prop_size
, i
;
3131 PROPID prop_id
[16] = { 0 };
3132 ImageType image_type
;
3139 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
3141 image
= load_image(td
[i
].image_data
, td
[i
].image_size
);
3144 trace("%u: failed to load image data\n", i
);
3148 status
= GdipGetImageType(image
, &image_type
);
3149 ok(status
== Ok
, "%u: GdipGetImageType error %d\n", i
, status
);
3150 ok(td
[i
].image_type
== image_type
, "%u: expected image_type %d, got %d\n",
3151 i
, td
[i
].image_type
, image_type
);
3153 status
= GdipGetPropertyCount(image
, &prop_count
);
3154 ok(status
== Ok
, "%u: GdipGetPropertyCount error %d\n", i
, status
);
3155 if (td
[i
].image_data
== pngimage
|| td
[i
].image_data
== jpgimage
)
3157 ok(td
[i
].prop_count
== prop_count
|| td
[i
].prop_count2
== prop_count
,
3158 " %u: expected property count %u or %u, got %u\n",
3159 i
, td
[i
].prop_count
, td
[i
].prop_count2
, prop_count
);
3161 ok(td
[i
].prop_count
== prop_count
|| td
[i
].prop_count2
== prop_count
,
3162 " %u: expected property count %u or %u, got %u\n",
3163 i
, td
[i
].prop_count
, td
[i
].prop_count2
, prop_count
);
3165 status
= GdipGetPropertyItemSize(NULL
, 0, &prop_size
);
3166 expect(InvalidParameter
, status
);
3167 status
= GdipGetPropertyItemSize(image
, 0, NULL
);
3168 expect(InvalidParameter
, status
);
3169 status
= GdipGetPropertyItemSize(image
, 0, &prop_size
);
3170 if (image_type
== ImageTypeMetafile
)
3171 expect(NotImplemented
, status
);
3173 expect(PropertyNotFound
, status
);
3175 status
= GdipGetPropertyItem(NULL
, 0, 0, &item
.data
);
3176 expect(InvalidParameter
, status
);
3177 status
= GdipGetPropertyItem(image
, 0, 0, NULL
);
3178 expect(InvalidParameter
, status
);
3179 status
= GdipGetPropertyItem(image
, 0, 0, &item
.data
);
3180 if (image_type
== ImageTypeMetafile
)
3181 expect(NotImplemented
, status
);
3183 expect(PropertyNotFound
, status
);
3185 /* FIXME: remove once Wine is fixed */
3186 if (td
[i
].prop_count
!= prop_count
)
3188 GdipDisposeImage(image
);
3192 status
= GdipGetPropertyIdList(NULL
, prop_count
, prop_id
);
3193 expect(InvalidParameter
, status
);
3194 status
= GdipGetPropertyIdList(image
, prop_count
, NULL
);
3195 expect(InvalidParameter
, status
);
3196 status
= GdipGetPropertyIdList(image
, 0, prop_id
);
3197 if (image_type
== ImageTypeMetafile
)
3198 expect(NotImplemented
, status
);
3199 else if (prop_count
== 0)
3202 expect(InvalidParameter
, status
);
3203 status
= GdipGetPropertyIdList(image
, prop_count
- 1, prop_id
);
3204 if (image_type
== ImageTypeMetafile
)
3205 expect(NotImplemented
, status
);
3207 expect(InvalidParameter
, status
);
3208 status
= GdipGetPropertyIdList(image
, prop_count
+ 1, prop_id
);
3209 if (image_type
== ImageTypeMetafile
)
3210 expect(NotImplemented
, status
);
3212 expect(InvalidParameter
, status
);
3213 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3214 if (image_type
== ImageTypeMetafile
)
3215 expect(NotImplemented
, status
);
3219 if (prop_count
!= 0)
3220 ok(td
[i
].prop_id
== prop_id
[0] || td
[i
].prop_id2
== prop_id
[0],
3221 " %u: expected property id %#x or %#x, got %#x\n",
3222 i
, td
[i
].prop_id
, td
[i
].prop_id2
, prop_id
[0]);
3227 status
= GdipGetPropertyItemSize(image
, prop_id
[0], &prop_size
);
3228 if (prop_count
== 0)
3229 expect(PropertyNotFound
, status
);
3234 assert(sizeof(item
) >= prop_size
);
3235 ok(prop_size
> sizeof(PropertyItem
), "%u: got too small prop_size %u\n",
3237 ok(td
[i
].prop_size
+ sizeof(PropertyItem
) == prop_size
||
3238 td
[i
].prop_size2
+ sizeof(PropertyItem
) == prop_size
,
3239 " %u: expected property size %u or %u, got %u\n",
3240 i
, td
[i
].prop_size
, td
[i
].prop_size2
, prop_size
);
3242 status
= GdipGetPropertyItem(image
, prop_id
[0], 0, &item
.data
);
3243 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3244 "%u: expected InvalidParameter, got %d\n", i
, status
);
3245 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
- 1, &item
.data
);
3246 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3247 "%u: expected InvalidParameter, got %d\n", i
, status
);
3248 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
+ 1, &item
.data
);
3249 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3250 "%u: expected InvalidParameter, got %d\n", i
, status
);
3251 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
, &item
.data
);
3253 ok(prop_id
[0] == item
.data
.id
,
3254 "%u: expected property id %#x, got %#x\n", i
, prop_id
[0], item
.data
.id
);
3258 GdipDisposeImage(image
);
3266 #define IFD_RATIONAL 5
3268 #define IFD_UNDEFINED 7
3269 #define IFD_SSHORT 8
3271 #define IFD_SRATIONAL 10
3272 #define IFD_FLOAT 11
3273 #define IFD_DOUBLE 12
3275 #ifndef PropertyTagTypeSByte
3276 #define PropertyTagTypeSByte 6
3277 #define PropertyTagTypeSShort 8
3278 #define PropertyTagTypeFloat 11
3279 #define PropertyTagTypeDouble 12
3282 static UINT
documented_type(UINT type
)
3286 case PropertyTagTypeSByte
: return PropertyTagTypeByte
;
3287 case PropertyTagTypeSShort
: return PropertyTagTypeShort
;
3288 case PropertyTagTypeFloat
: return PropertyTagTypeUndefined
;
3289 case PropertyTagTypeDouble
: return PropertyTagTypeUndefined
;
3290 default: return type
;
3294 #include "pshpack2.h"
3309 static const struct tiff_data
3314 USHORT number_of_entries
;
3315 struct IFD_entry entry
[40];
3317 struct IFD_rational xres
;
3319 struct IFD_rational srational_val
;
3324 struct IFD_rational rational
[3];
3328 #ifdef WORDS_BIGENDIAN
3334 FIELD_OFFSET(struct tiff_data
, number_of_entries
),
3337 { 0xff, IFD_SHORT
, 1, 0 }, /* SUBFILETYPE */
3338 { 0x100, IFD_LONG
, 1, 1 }, /* IMAGEWIDTH */
3339 { 0x101, IFD_LONG
, 1, 1 }, /* IMAGELENGTH */
3340 { 0x102, IFD_SHORT
, 1, 1 }, /* BITSPERSAMPLE */
3341 { 0x103, IFD_SHORT
, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
3342 { 0x106, IFD_SHORT
, 1, 1 }, /* PHOTOMETRIC */
3343 { 0x111, IFD_LONG
, 1, FIELD_OFFSET(struct tiff_data
, pixel_data
) }, /* STRIPOFFSETS */
3344 { 0x115, IFD_SHORT
, 1, 1 }, /* SAMPLESPERPIXEL */
3345 { 0x116, IFD_LONG
, 1, 1 }, /* ROWSPERSTRIP */
3346 { 0x117, IFD_LONG
, 1, 1 }, /* STRIPBYTECOUNT */
3347 { 0x11a, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3348 { 0x11b, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3349 { 0x128, IFD_SHORT
, 1, 2 }, /* RESOLUTIONUNIT */
3350 { 0xf001, IFD_BYTE
, 1, 0x11223344 },
3351 { 0xf002, IFD_BYTE
, 4, 0x11223344 },
3352 { 0xf003, IFD_SBYTE
, 1, 0x11223344 },
3353 { 0xf004, IFD_SSHORT
, 1, 0x11223344 },
3354 { 0xf005, IFD_SSHORT
, 2, 0x11223344 },
3355 { 0xf006, IFD_SLONG
, 1, 0x11223344 },
3356 { 0xf007, IFD_FLOAT
, 1, 0x11223344 },
3357 { 0xf008, IFD_DOUBLE
, 1, FIELD_OFFSET(struct tiff_data
, double_val
) },
3358 { 0xf009, IFD_SRATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, srational_val
) },
3359 { 0xf00a, IFD_BYTE
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3360 { 0xf00b, IFD_SSHORT
, 4, FIELD_OFFSET(struct tiff_data
, short_val
) },
3361 { 0xf00c, IFD_SLONG
, 2, FIELD_OFFSET(struct tiff_data
, long_val
) },
3362 { 0xf00e, IFD_ASCII
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3363 { 0xf00f, IFD_ASCII
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3364 { 0xf010, IFD_UNDEFINED
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3365 { 0xf011, IFD_UNDEFINED
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3366 /* Some gdiplus versions ignore these fields.
3367 { 0xf012, IFD_BYTE, 0, 0x11223344 },
3368 { 0xf013, IFD_SHORT, 0, 0x11223344 },
3369 { 0xf014, IFD_LONG, 0, 0x11223344 },
3370 { 0xf015, IFD_FLOAT, 0, 0x11223344 },*/
3371 { 0xf016, IFD_SRATIONAL
, 3, FIELD_OFFSET(struct tiff_data
, rational
) },
3372 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3373 { 0xf017, IFD_FLOAT
, 2, FIELD_OFFSET(struct tiff_data
, float_val
) },
3377 1234567890.0987654321,
3378 { 0x1a2b3c4d, 0x5a6b7c8d },
3380 { 0x0101, 0x0202, 0x0303, 0x0404 },
3381 { 0x11223344, 0x55667788 },
3382 { (FLOAT
)1234.5678, (FLOAT
)8765.4321 },
3383 { { 0x01020304, 0x05060708 }, { 0x10203040, 0x50607080 }, { 0x11223344, 0x55667788 } },
3384 { 0x11, 0x22, 0x33, 0 }
3386 #include "poppack.h"
3388 static void test_tiff_properties(void)
3390 static const struct test_data
3392 ULONG type
, id
, length
;
3393 const BYTE value
[24];
3396 { PropertyTagTypeShort
, 0xff, 2, { 0 } },
3397 { PropertyTagTypeLong
, 0x100, 4, { 1 } },
3398 { PropertyTagTypeLong
, 0x101, 4, { 1 } },
3399 { PropertyTagTypeShort
, 0x102, 2, { 1 } },
3400 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3401 { PropertyTagTypeShort
, 0x106, 2, { 1 } },
3402 { PropertyTagTypeLong
, 0x111, 4, { 0x44,0x02 } },
3403 { PropertyTagTypeShort
, 0x115, 2, { 1 } },
3404 { PropertyTagTypeLong
, 0x116, 4, { 1 } },
3405 { PropertyTagTypeLong
, 0x117, 4, { 1 } },
3406 { PropertyTagTypeRational
, 0x11a, 8, { 0x84,0x03,0,0,0x03 } },
3407 { PropertyTagTypeRational
, 0x11b, 8, { 0x84,0x03,0,0,0x03 } },
3408 { PropertyTagTypeShort
, 0x128, 2, { 2 } },
3409 { PropertyTagTypeByte
, 0xf001, 1, { 0x44 } },
3410 { PropertyTagTypeByte
, 0xf002, 4, { 0x44,0x33,0x22,0x11 } },
3411 { PropertyTagTypeSByte
, 0xf003, 1, { 0x44 } },
3412 { PropertyTagTypeSShort
, 0xf004, 2, { 0x44,0x33 } },
3413 { PropertyTagTypeSShort
, 0xf005, 4, { 0x44,0x33,0x22,0x11 } },
3414 { PropertyTagTypeSLONG
, 0xf006, 4, { 0x44,0x33,0x22,0x11 } },
3415 { PropertyTagTypeFloat
, 0xf007, 4, { 0x44,0x33,0x22,0x11 } },
3416 { PropertyTagTypeDouble
, 0xf008, 8, { 0x2c,0x52,0x86,0xb4,0x80,0x65,0xd2,0x41 } },
3417 { PropertyTagTypeSRational
, 0xf009, 8, { 0x4d, 0x3c, 0x2b, 0x1a, 0x8d, 0x7c, 0x6b, 0x5a } },
3418 { PropertyTagTypeByte
, 0xf00a, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3419 { PropertyTagTypeSShort
, 0xf00b, 8, { 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04 } },
3420 { PropertyTagTypeSLONG
, 0xf00c, 8, { 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3421 { PropertyTagTypeASCII
, 0xf00e, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3422 { PropertyTagTypeASCII
, 0xf00f, 5, { 'a','b','c','d' } },
3423 { PropertyTagTypeUndefined
, 0xf010, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3424 { PropertyTagTypeUndefined
, 0xf011, 4, { 'a','b','c','d' } },
3425 { PropertyTagTypeSRational
, 0xf016, 24,
3426 { 0x04,0x03,0x02,0x01,0x08,0x07,0x06,0x05,
3427 0x40,0x30,0x20,0x10,0x80,0x70,0x60,0x50,
3428 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3429 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3430 { PropertyTagTypeFloat
, 0xf017, 8, { 0x2b,0x52,0x9a,0x44,0xba,0xf5,0x08,0x46 } },
3435 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3437 PropertyItem
*prop_item
;
3439 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
));
3442 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3446 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3448 expect(1, dim_count
);
3450 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3452 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3454 frame_count
= 0xdeadbeef;
3455 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3457 expect(1, frame_count
);
3459 prop_count
= 0xdeadbeef;
3460 status
= GdipGetPropertyCount(image
, &prop_count
);
3462 ok(prop_count
== sizeof(td
)/sizeof(td
[0]) ||
3463 broken(prop_count
== sizeof(td
)/sizeof(td
[0]) - 1) /* Win7 SP0 */,
3464 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
3466 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3468 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3471 for (i
= 0; i
< prop_count
; i
++)
3473 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &prop_size
);
3475 if (status
!= Ok
) break;
3476 ok(prop_size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, prop_size
);
3478 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, prop_size
);
3479 status
= GdipGetPropertyItem(image
, prop_id
[i
], prop_size
, prop_item
);
3481 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3482 ok(td
[i
].type
== prop_item
->type
||
3483 /* Win7 stopped using proper but not documented types, and it
3484 looks broken since TypeFloat and TypeDouble now reported as
3485 TypeUndefined, and signed types reported as unsigned. */
3486 broken(prop_item
->type
== documented_type(td
[i
].type
)),
3487 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3488 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3489 prop_size
-= sizeof(*prop_item
);
3490 ok(prop_item
->length
== prop_size
, "%u: expected length %u, got %u\n", i
, prop_size
, prop_item
->length
);
3491 ok(td
[i
].length
== prop_item
->length
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_item
->length
+1) /* XP */,
3492 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3493 ok(td
[i
].length
== prop_size
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_size
+1) /* XP */,
3494 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_size
);
3495 if (td
[i
].length
== prop_item
->length
)
3497 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3498 ok(match
|| broken(td
[i
].length
<= 4 && !match
), "%u: data mismatch\n", i
);
3502 BYTE
*data
= prop_item
->value
;
3503 trace("id %#x:", prop_item
->id
);
3504 for (j
= 0; j
< prop_item
->length
; j
++)
3505 trace(" %02x", data
[j
]);
3509 HeapFree(GetProcessHeap(), 0, prop_item
);
3512 HeapFree(GetProcessHeap(), 0, prop_id
);
3514 GdipDisposeImage(image
);
3517 static void test_GdipGetAllPropertyItems(void)
3519 static const struct test_data
3521 ULONG type
, id
, length
;
3525 { PropertyTagTypeLong
, 0xfe, 4, { 0 } },
3526 { PropertyTagTypeShort
, 0x100, 2, { 1 } },
3527 { PropertyTagTypeShort
, 0x101, 2, { 1 } },
3528 { PropertyTagTypeShort
, 0x102, 6, { 8,0,8,0,8,0 } },
3529 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3530 { PropertyTagTypeShort
, 0x106, 2, { 2,0 } },
3531 { PropertyTagTypeASCII
, 0x10d, 27, "/home/meh/Desktop/test.tif" },
3532 { PropertyTagTypeLong
, 0x111, 4, { 8,0,0,0 } },
3533 { PropertyTagTypeShort
, 0x112, 2, { 1 } },
3534 { PropertyTagTypeShort
, 0x115, 2, { 3,0 } },
3535 { PropertyTagTypeShort
, 0x116, 2, { 0x40,0 } },
3536 { PropertyTagTypeLong
, 0x117, 4, { 3,0,0,0 } },
3537 { PropertyTagTypeRational
, 0x11a, 8, { 0,0,0,72,0,0,0,1 } },
3538 { PropertyTagTypeRational
, 0x11b, 8, { 0,0,0,72,0,0,0,1 } },
3539 { PropertyTagTypeShort
, 0x11c, 2, { 1 } },
3540 { PropertyTagTypeShort
, 0x128, 2, { 2 } }
3545 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3546 UINT total_size
, total_count
;
3548 PropertyItem
*prop_item
;
3549 const char *item_data
;
3551 image
= load_image(tiffimage
, sizeof(tiffimage
));
3552 ok(image
!= 0, "Failed to load TIFF image data\n");
3555 dim_count
= 0xdeadbeef;
3556 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3558 expect(1, dim_count
);
3560 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3562 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3564 frame_count
= 0xdeadbeef;
3565 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3567 expect(1, frame_count
);
3569 prop_count
= 0xdeadbeef;
3570 status
= GdipGetPropertyCount(image
, &prop_count
);
3572 ok(prop_count
== sizeof(td
)/sizeof(td
[0]),
3573 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
3575 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3577 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3581 for (i
= 0; i
< prop_count
; i
++)
3584 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
3586 if (status
!= Ok
) break;
3587 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
3591 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
3592 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
3594 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3595 ok(td
[i
].type
== prop_item
->type
,
3596 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3597 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3598 size
-= sizeof(*prop_item
);
3599 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
3600 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3601 if (td
[i
].length
== prop_item
->length
)
3603 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3604 ok(match
, "%u: data mismatch\n", i
);
3608 BYTE
*data
= prop_item
->value
;
3609 trace("id %#x:", prop_item
->id
);
3610 for (j
= 0; j
< prop_item
->length
; j
++)
3611 trace(" %02x", data
[j
]);
3615 HeapFree(GetProcessHeap(), 0, prop_item
);
3618 HeapFree(GetProcessHeap(), 0, prop_id
);
3620 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
3621 expect(InvalidParameter
, status
);
3622 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
3623 expect(InvalidParameter
, status
);
3624 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
3625 expect(InvalidParameter
, status
);
3626 status
= GdipGetPropertySize(image
, NULL
, NULL
);
3627 expect(InvalidParameter
, status
);
3628 total_size
= 0xdeadbeef;
3629 total_count
= 0xdeadbeef;
3630 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
3632 ok(prop_count
== total_count
,
3633 "expected total property count %u, got %u\n", prop_count
, total_count
);
3634 ok(prop_size
== total_size
,
3635 "expected total property size %u, got %u\n", prop_size
, total_size
);
3637 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
3639 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
3640 expect(InvalidParameter
, status
);
3641 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
3642 expect(InvalidParameter
, status
);
3643 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3644 expect(InvalidParameter
, status
);
3645 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3646 expect(InvalidParameter
, status
);
3647 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
3648 expect(InvalidParameter
, status
);
3649 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
3650 expect(InvalidParameter
, status
);
3651 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
3654 item_data
= (const char *)(prop_item
+ prop_count
);
3655 for (i
= 0; i
< prop_count
; i
++)
3657 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
3658 i
, item_data
, prop_item
[i
].value
);
3659 ok(td
[i
].type
== prop_item
[i
].type
,
3660 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
3661 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
3662 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
3663 if (td
[i
].length
== prop_item
[i
].length
)
3665 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
3666 ok(match
, "%u: data mismatch\n", i
);
3670 BYTE
*data
= prop_item
[i
].value
;
3671 trace("id %#x:", prop_item
[i
].id
);
3672 for (j
= 0; j
< prop_item
[i
].length
; j
++)
3673 trace(" %02x", data
[j
]);
3677 item_data
+= prop_item
[i
].length
;
3680 HeapFree(GetProcessHeap(), 0, prop_item
);
3682 GdipDisposeImage(image
);
3685 static void test_tiff_palette(void)
3696 ARGB
*entries
= palette
.pal
.Entries
;
3698 /* 1bpp TIFF without palette */
3699 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
));
3702 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3706 status
= GdipGetImagePixelFormat(image
, &format
);
3708 ok(format
== PixelFormat1bppIndexed
, "expected PixelFormat1bppIndexed, got %#x\n", format
);
3710 status
= GdipGetImagePaletteSize(image
, &size
);
3711 ok(status
== Ok
|| broken(status
== GenericError
), /* XP */
3712 "GdipGetImagePaletteSize error %d\n", status
);
3713 if (status
== GenericError
)
3715 GdipDisposeImage(image
);
3718 expect(sizeof(ColorPalette
) + sizeof(ARGB
), size
);
3720 status
= GdipGetImagePalette(image
, &palette
.pal
, size
);
3722 expect(0, palette
.pal
.Flags
);
3723 expect(2, palette
.pal
.Count
);
3724 if (palette
.pal
.Count
== 2)
3726 ok(entries
[0] == 0xff000000, "expected 0xff000000, got %#x\n", entries
[0]);
3727 ok(entries
[1] == 0xffffffff, "expected 0xffffffff, got %#x\n", entries
[1]);
3730 GdipDisposeImage(image
);
3733 static void test_bitmapbits(void)
3736 static const BYTE pixels_24
[48] =
3738 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3739 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3740 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3741 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0
3743 static const BYTE pixels_00
[48] =
3745 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3746 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3747 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3748 0,0,0, 0,0,0, 0,0,0, 0,0,0
3750 static const BYTE pixels_24_77
[64] =
3752 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3753 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3754 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
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,
3757 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3759 static const BYTE pixels_77
[64] =
3761 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3762 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3763 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3764 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3765 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3766 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3767 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3768 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3770 static const BYTE pixels_8
[16] =
3772 0x01,0,0x01,0,0x01,0,0x01,0,
3773 0x01,0,0x01,0,0x01,0,0x01,0
3775 static const BYTE pixels_8_77
[64] =
3777 0x01,0,0x01,0,0x01,0,0x01,0,
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 0x01,0,0x01,0,0x01,0,0x01,0,
3782 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3783 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3784 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3786 static const BYTE pixels_1_77
[64] =
3788 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3789 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3790 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3791 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3792 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
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
3797 static const BYTE pixels_1
[8] = {0xaa,0,0,0,0xaa,0,0,0};
3798 static const struct test_data
3805 const BYTE
*pixels_unlocked
;
3809 { PixelFormat24bppRGB
, 24, 0xfff0, 24, 48, pixels_24
, pixels_00
},
3811 { PixelFormat24bppRGB
, 24, 0, 24, 48, pixels_24
, pixels_00
},
3812 { PixelFormat24bppRGB
, 24, ImageLockModeRead
, 24, 48, pixels_24
, pixels_00
},
3813 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
3814 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
3815 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_24_77
, pixels_24
},
3816 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3817 { PixelFormat24bppRGB
, 24, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3819 { PixelFormat8bppIndexed
, 8, 0, 8, 16, pixels_8
, pixels_24
},
3820 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
, 8, 16, pixels_8
, pixels_24
},
3821 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
3822 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
3823 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_8_77
, pixels_24
},
3824 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3825 { PixelFormat8bppIndexed
, 8, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3827 { PixelFormat1bppIndexed
, 1, 0, 4, 8, pixels_1
, pixels_24
},
3828 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
, 4, 8, pixels_1
, pixels_24
},
3829 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
3830 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
3831 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_1_77
, pixels_24
},
3832 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3833 { PixelFormat1bppIndexed
, 1, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3845 ARGB
*entries
= palette
.pal
.Entries
;
3847 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
3849 BYTE pixels
[sizeof(pixels_24
)];
3850 memcpy(pixels
, pixels_24
, sizeof(pixels_24
));
3851 status
= GdipCreateBitmapFromScan0(8, 2, 24, PixelFormat24bppRGB
, pixels
, &bitmap
);
3854 /* associate known palette with pixel data */
3855 palette
.pal
.Flags
= PaletteFlagsGrayScale
;
3856 palette
.pal
.Count
= 2;
3857 entries
[0] = 0xff000000;
3858 entries
[1] = 0xffffffff;
3859 status
= GdipSetImagePalette((GpImage
*)bitmap
, &palette
.pal
);
3862 memset(&data
, 0xfe, sizeof(data
));
3863 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
3865 memset(buf
, 0x77, sizeof(buf
));
3869 status
= GdipBitmapLockBits(bitmap
, NULL
, td
[i
].mode
, td
[i
].format
, &data
);
3870 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* XP */, "%u: GdipBitmapLockBits error %d\n", i
, status
);
3873 GdipDisposeImage((GpImage
*)bitmap
);
3876 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
3877 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
3878 ok(td
[i
].stride
== data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].stride
, data
.Stride
);
3879 ok(td
[i
].format
== data
.PixelFormat
, "%u: expected %d, got %d\n", i
, td
[i
].format
, data
.PixelFormat
);
3880 ok(td
[i
].size
== data
.Height
* data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].size
, data
.Height
* data
.Stride
);
3881 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
3882 ok(data
.Scan0
== buf
, "%u: got wrong buffer\n", i
);
3883 if (td
[i
].size
== data
.Height
* data
.Stride
)
3885 UINT j
, match
, width_bytes
= (data
.Width
* td
[i
].bpp
) / 8;
3888 for (j
= 0; j
< data
.Height
; j
++)
3890 if (memcmp((const BYTE
*)data
.Scan0
+ j
* data
.Stride
, td
[i
].pixels
+ j
* data
.Stride
, width_bytes
) != 0)
3896 if ((td
[i
].mode
& (ImageLockModeRead
|ImageLockModeUserInputBuf
)) || td
[i
].format
== PixelFormat24bppRGB
)
3899 "%u: data should match\n", i
);
3902 BYTE
*bits
= data
.Scan0
;
3903 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
3904 for (j
= 0; j
< td
[i
].size
; j
++)
3905 trace(" %02x", bits
[j
]);
3910 ok(!match
, "%u: data shouldn't match\n", i
);
3912 memset(data
.Scan0
, 0, td
[i
].size
);
3915 status
= GdipBitmapUnlockBits(bitmap
, &data
);
3916 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
3918 memset(&data
, 0xfe, sizeof(data
));
3919 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
3920 ok(status
== Ok
, "%u: GdipBitmapLockBits error %d\n", i
, status
);
3921 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
3922 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
3923 ok(data
.Stride
== 24, "%u: expected 24, got %d\n", i
, data
.Stride
);
3924 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "%u: got wrong pixel format %d\n", i
, data
.PixelFormat
);
3925 ok(data
.Height
* data
.Stride
== 48, "%u: expected 48, got %d\n", i
, data
.Height
* data
.Stride
);
3926 if (data
.Height
* data
.Stride
== 48)
3928 int match
= memcmp(data
.Scan0
, td
[i
].pixels_unlocked
, 48) == 0;
3929 ok(match
, "%u: data should match\n", i
);
3933 BYTE
*bits
= data
.Scan0
;
3934 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
3935 for (j
= 0; j
< 48; j
++)
3936 trace(" %02x", bits
[j
]);
3941 status
= GdipBitmapUnlockBits(bitmap
, &data
);
3942 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
3944 status
= GdipDisposeImage((GpImage
*)bitmap
);
3949 static void test_DrawImage(void)
3951 BYTE black_1x1
[4] = { 0,0,0,0 };
3952 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
3953 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
3954 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
3955 0,0,0,0,0,0,0xff,0xff };
3962 GpGraphics
*graphics
;
3965 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
3967 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
3970 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
3972 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
3974 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
3976 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
3979 status
= GdipDrawImageI(graphics
, u1
.image
, 0, 0);
3982 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
3983 ok(match
, "data should match\n");
3986 UINT i
, size
= sizeof(white_2x2
);
3987 BYTE
*bits
= white_2x2
;
3988 for (i
= 0; i
< size
; i
++)
3989 trace(" %02x", bits
[i
]);
3993 status
= GdipDeleteGraphics(graphics
);
3995 status
= GdipDisposeImage(u1
.image
);
3997 status
= GdipDisposeImage(u2
.image
);
4001 static void test_GdipDrawImagePointRect(void)
4003 BYTE black_1x1
[4] = { 0,0,0,0 };
4004 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
4005 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
4006 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
4007 0,0,0,0,0,0,0xff,0xff };
4014 GpGraphics
*graphics
;
4017 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
4019 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4022 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
4024 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
4026 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4028 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4031 status
= GdipDrawImagePointRectI(graphics
, u1
.image
, 0, 0, 0, 0, 1, 1, UnitPixel
);
4034 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
4035 ok(match
, "data should match\n");
4038 UINT i
, size
= sizeof(white_2x2
);
4039 BYTE
*bits
= white_2x2
;
4040 for (i
= 0; i
< size
; i
++)
4041 trace(" %02x", bits
[i
]);
4045 status
= GdipDeleteGraphics(graphics
);
4047 status
= GdipDisposeImage(u1
.image
);
4049 status
= GdipDisposeImage(u2
.image
);
4053 static void test_image_format(void)
4055 static const PixelFormat fmt
[] =
4057 PixelFormat1bppIndexed
, PixelFormat4bppIndexed
, PixelFormat8bppIndexed
,
4058 PixelFormat16bppGrayScale
, PixelFormat16bppRGB555
, PixelFormat16bppRGB565
,
4059 PixelFormat16bppARGB1555
, PixelFormat24bppRGB
, PixelFormat32bppRGB
,
4060 PixelFormat32bppARGB
, PixelFormat32bppPARGB
, PixelFormat48bppRGB
,
4061 PixelFormat64bppARGB
, PixelFormat64bppPARGB
, PixelFormat32bppCMYK
4072 for (i
= 0; i
< sizeof(fmt
)/sizeof(fmt
[0]); i
++)
4074 status
= GdipCreateBitmapFromScan0(1, 1, 0, fmt
[i
], NULL
, &bitmap
);
4075 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* before win7 */,
4076 "GdipCreateBitmapFromScan0 error %d\n", status
);
4077 if (status
!= Ok
) continue;
4079 status
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
4081 expect(fmt
[i
], format
);
4083 status
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
4084 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4085 todo_wine
expect(InvalidParameter
, status
);
4089 ret
= GetObjectW(hbitmap
, sizeof(bm
), &bm
);
4090 expect(sizeof(bm
), ret
);
4091 expect(0, bm
.bmType
);
4092 expect(1, bm
.bmWidth
);
4093 expect(1, bm
.bmHeight
);
4094 expect(4, bm
.bmWidthBytes
);
4095 expect(1, bm
.bmPlanes
);
4096 expect(32, bm
.bmBitsPixel
);
4097 DeleteObject(hbitmap
);
4100 status
= GdipGetImageThumbnail((GpImage
*)bitmap
, 0, 0, &thumb
, NULL
, NULL
);
4101 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4103 ok(status
== OutOfMemory
|| broken(status
== InvalidParameter
) /* before win7 */,
4104 "expected OutOfMemory, got %d\n", status
);
4109 status
= GdipGetImagePixelFormat(thumb
, &format
);
4111 ok(format
== PixelFormat32bppPARGB
|| broken(format
!= PixelFormat32bppPARGB
) /* before win7 */,
4112 "expected PixelFormat32bppPARGB, got %#x\n", format
);
4113 status
= GdipDisposeImage(thumb
);
4117 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4118 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4119 todo_wine
expect(InvalidParameter
, status
);
4123 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4127 status
= GdipDisposeImage((GpImage
*)bitmap
);
4132 static void test_DrawImage_scale(void)
4134 static const BYTE back_8x1
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
4135 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4136 static const BYTE image_080
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,
4137 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4138 static const BYTE image_100
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,
4139 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4140 static const BYTE image_120
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,
4141 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4142 static const BYTE image_150
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4143 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4144 static const BYTE image_180
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4145 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4146 static const BYTE image_200
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4147 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4148 static const BYTE image_250
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,
4149 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4150 static const BYTE image_120_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4151 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4152 static const BYTE image_150_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4153 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4154 static const BYTE image_200_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4155 0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40 };
4156 static const BYTE image_250_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4157 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4158 static const struct test_data
4161 PixelOffsetMode pixel_offset_mode
;
4166 { 0.8, PixelOffsetModeNone
, image_080
}, /* 0 */
4167 { 1.0, PixelOffsetModeNone
, image_100
},
4168 { 1.2, PixelOffsetModeNone
, image_120
},
4169 { 1.5, PixelOffsetModeNone
, image_150
},
4170 { 1.8, PixelOffsetModeNone
, image_180
},
4171 { 2.0, PixelOffsetModeNone
, image_200
},
4172 { 2.5, PixelOffsetModeNone
, image_250
},
4174 { 0.8, PixelOffsetModeHighSpeed
, image_080
}, /* 7 */
4175 { 1.0, PixelOffsetModeHighSpeed
, image_100
},
4176 { 1.2, PixelOffsetModeHighSpeed
, image_120
},
4177 { 1.5, PixelOffsetModeHighSpeed
, image_150
},
4178 { 1.8, PixelOffsetModeHighSpeed
, image_180
},
4179 { 2.0, PixelOffsetModeHighSpeed
, image_200
},
4180 { 2.5, PixelOffsetModeHighSpeed
, image_250
},
4182 { 0.8, PixelOffsetModeHalf
, image_080
}, /* 14 */
4183 { 1.0, PixelOffsetModeHalf
, image_100
},
4184 { 1.2, PixelOffsetModeHalf
, image_120_half
, TRUE
},
4185 { 1.5, PixelOffsetModeHalf
, image_150_half
, TRUE
},
4186 { 1.8, PixelOffsetModeHalf
, image_180
},
4187 { 2.0, PixelOffsetModeHalf
, image_200_half
, TRUE
},
4188 { 2.5, PixelOffsetModeHalf
, image_250_half
, TRUE
},
4190 { 0.8, PixelOffsetModeHighQuality
, image_080
}, /* 21 */
4191 { 1.0, PixelOffsetModeHighQuality
, image_100
},
4192 { 1.2, PixelOffsetModeHighQuality
, image_120_half
, TRUE
},
4193 { 1.5, PixelOffsetModeHighQuality
, image_150_half
, TRUE
},
4194 { 1.8, PixelOffsetModeHighQuality
, image_180
},
4195 { 2.0, PixelOffsetModeHighQuality
, image_200_half
, TRUE
},
4196 { 2.5, PixelOffsetModeHighQuality
, image_250_half
, TRUE
},
4198 BYTE src_2x1
[6] = { 0x80,0x80,0x80,0x80,0x80,0x80 };
4206 GpGraphics
*graphics
;
4210 status
= GdipCreateBitmapFromScan0(2, 1, 4, PixelFormat24bppRGB
, src_2x1
, &u1
.bitmap
);
4212 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4215 status
= GdipCreateBitmapFromScan0(8, 1, 24, PixelFormat24bppRGB
, dst_8x1
, &u2
.bitmap
);
4217 status
= GdipBitmapSetResolution(u2
.bitmap
, 100.0, 100.0);
4219 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4221 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4224 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
4226 status
= GdipSetPixelOffsetMode(graphics
, td
[i
].pixel_offset_mode
);
4229 status
= GdipCreateMatrix2(td
[i
].scale_x
, 0.0, 0.0, 1.0, 0.0, 0.0, &matrix
);
4231 status
= GdipSetWorldTransform(graphics
, matrix
);
4233 GdipDeleteMatrix(matrix
);
4235 memcpy(dst_8x1
, back_8x1
, sizeof(dst_8x1
));
4236 status
= GdipDrawImageI(graphics
, u1
.image
, 1, 0);
4239 match
= memcmp(dst_8x1
, td
[i
].image
, sizeof(dst_8x1
)) == 0;
4240 if (!match
&& td
[i
].todo
)
4241 todo_wine
ok(match
, "%d: data should match\n", i
);
4243 ok(match
, "%d: data should match\n", i
);
4246 UINT i
, size
= sizeof(dst_8x1
);
4247 const BYTE
*bits
= dst_8x1
;
4248 for (i
= 0; i
< size
; i
++)
4249 trace(" %02x", bits
[i
]);
4254 status
= GdipDeleteGraphics(graphics
);
4256 status
= GdipDisposeImage(u1
.image
);
4258 status
= GdipDisposeImage(u2
.image
);
4262 static const BYTE animatedgif
[] = {
4263 'G','I','F','8','9','a',0x01,0x00,0x01,0x00,0xA1,0x02,0x00,
4264 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
4265 /*0x21,0xFF,0x0B,'A','N','I','M','E','X','T','S','1','.','0',*/
4266 0x21,0xFF,0x0B,'N','E','T','S','C','A','P','E','2','.','0',
4267 0x03,0x01,0x05,0x00,0x00,
4268 0x21,0xFE,0x0C,'H','e','l','l','o',' ','W','o','r','l','d','!',0x00,
4269 0x21,0x01,0x0D,'a','n','i','m','a','t','i','o','n','.','g','i','f',0x00,
4270 0x21,0xF9,0x04,0xff,0x0A,0x00,0x08,0x00,
4271 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4272 0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,
4273 0x02,0x02,0x4C,0x01,0x00,
4274 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','1',0x00,
4275 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','1',0x00,
4276 0x21,0xF9,0x04,0x00,0x14,0x00,0x01,0x00,
4277 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4278 0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,
4279 0x02,0x02,0x44,0x01,0x00,
4280 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','2',0x00,
4281 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','2',0x00,0x3B
4284 static void test_gif_properties(void)
4286 static const struct test_data
4288 ULONG type
, id
, length
;
4289 const BYTE value
[13];
4292 { PropertyTagTypeLong
, PropertyTagFrameDelay
, 8, { 10,0,0,0,20,0,0,0 } },
4293 { PropertyTagTypeASCII
, PropertyTagExifUserComment
, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
4294 { PropertyTagTypeShort
, PropertyTagLoopCount
, 2, { 5,0 } },
4295 { PropertyTagTypeByte
, PropertyTagGlobalPalette
, 12, { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c } },
4296 { PropertyTagTypeByte
, PropertyTagIndexBackground
, 1, { 2 } },
4297 { PropertyTagTypeByte
, PropertyTagIndexTransparent
, 1, { 8 } }
4302 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
4303 UINT total_size
, total_count
;
4305 PropertyItem
*prop_item
;
4306 const char *item_data
;
4308 image
= load_image(animatedgif
, sizeof(animatedgif
));
4309 if (!image
) /* XP fails to load this GIF image */
4311 trace("Failed to load GIF image data\n");
4315 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
4317 expect(1, dim_count
);
4319 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
4321 expect_guid(&FrameDimensionTime
, &guid
, __LINE__
, FALSE
);
4323 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
4325 expect(2, frame_count
);
4327 status
= GdipImageSelectActiveFrame(image
, &guid
, 1);
4330 status
= GdipGetPropertyCount(image
, &prop_count
);
4332 ok(prop_count
== sizeof(td
)/sizeof(td
[0]) || broken(prop_count
== 1) /* before win7 */,
4333 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
4335 if (prop_count
!= sizeof(td
)/sizeof(td
[0]))
4337 GdipDisposeImage(image
);
4341 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
4343 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
4347 for (i
= 0; i
< prop_count
; i
++)
4350 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
4352 if (status
!= Ok
) break;
4353 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
4357 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
4358 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
4360 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
4361 ok(td
[i
].type
== prop_item
->type
,
4362 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
4363 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
4364 size
-= sizeof(*prop_item
);
4365 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
4366 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
4367 if (td
[i
].length
== prop_item
->length
)
4369 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
4370 ok(match
, "%u: data mismatch\n", i
);
4374 BYTE
*data
= prop_item
->value
;
4375 trace("id %#x:", prop_item
->id
);
4376 for (j
= 0; j
< prop_item
->length
; j
++)
4377 trace(" %02x", data
[j
]);
4381 HeapFree(GetProcessHeap(), 0, prop_item
);
4384 HeapFree(GetProcessHeap(), 0, prop_id
);
4386 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
4387 expect(InvalidParameter
, status
);
4388 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
4389 expect(InvalidParameter
, status
);
4390 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
4391 expect(InvalidParameter
, status
);
4392 status
= GdipGetPropertySize(image
, NULL
, NULL
);
4393 expect(InvalidParameter
, status
);
4394 total_size
= 0xdeadbeef;
4395 total_count
= 0xdeadbeef;
4396 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
4398 ok(prop_count
== total_count
,
4399 "expected total property count %u, got %u\n", prop_count
, total_count
);
4400 ok(prop_size
== total_size
,
4401 "expected total property size %u, got %u\n", prop_size
, total_size
);
4403 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
4405 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
4406 expect(InvalidParameter
, status
);
4407 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
4408 expect(InvalidParameter
, status
);
4409 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4410 expect(InvalidParameter
, status
);
4411 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4412 expect(InvalidParameter
, status
);
4413 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
4414 expect(InvalidParameter
, status
);
4415 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
4416 expect(InvalidParameter
, status
);
4417 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
4420 item_data
= (const char *)(prop_item
+ prop_count
);
4421 for (i
= 0; i
< prop_count
; i
++)
4423 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
4424 i
, item_data
, prop_item
[i
].value
);
4425 ok(td
[i
].type
== prop_item
[i
].type
,
4426 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
4427 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
4428 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
4429 if (td
[i
].length
== prop_item
[i
].length
)
4431 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
4432 ok(match
, "%u: data mismatch\n", i
);
4436 BYTE
*data
= prop_item
[i
].value
;
4437 trace("id %#x:", prop_item
[i
].id
);
4438 for (j
= 0; j
< prop_item
[i
].length
; j
++)
4439 trace(" %02x", data
[j
]);
4443 item_data
+= prop_item
[i
].length
;
4446 HeapFree(GetProcessHeap(), 0, prop_item
);
4448 GdipDisposeImage(image
);
4451 static void test_ARGB_conversion(void)
4453 BYTE argb
[8] = { 0x11,0x22,0x33,0x80, 0xff,0xff,0xff,0 };
4454 BYTE pargb
[8] = { 0x09,0x11,0x1a,0x80, 0,0,0,0 };
4455 BYTE rgb32_xp
[8] = { 0x11,0x22,0x33,0xff, 0xff,0xff,0xff,0xff };
4456 BYTE rgb24
[6] = { 0x11,0x22,0x33, 0xff,0xff,0xff };
4463 status
= GdipCreateBitmapFromScan0(2, 1, 8, PixelFormat32bppARGB
, argb
, &bitmap
);
4466 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4468 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4469 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4470 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4471 ok(data
.PixelFormat
== PixelFormat32bppPARGB
, "expected PixelFormat32bppPARGB, got %d\n", data
.PixelFormat
);
4472 match
= !memcmp(data
.Scan0
, pargb
, sizeof(pargb
));
4473 ok(match
, "bits don't match\n");
4477 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppPARGB
,
4478 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4480 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4483 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppRGB
, &data
);
4485 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4486 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4487 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4488 ok(data
.PixelFormat
== PixelFormat32bppRGB
, "expected PixelFormat32bppRGB, got %d\n", data
.PixelFormat
);
4489 match
= !memcmp(data
.Scan0
, argb
, sizeof(argb
)) ||
4490 !memcmp(data
.Scan0
, rgb32_xp
, sizeof(rgb32_xp
));
4491 ok(match
, "bits don't match\n");
4495 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppRGB
,
4496 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4498 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4501 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
4503 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4504 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4505 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4506 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "expected PixelFormat24bppRGB, got %d\n", data
.PixelFormat
);
4507 match
= !memcmp(data
.Scan0
, rgb24
, sizeof(rgb24
));
4508 ok(match
, "bits don't match\n");
4512 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat24bppRGB
,
4513 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4515 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4518 GdipDisposeImage((GpImage
*)bitmap
);
4522 static void test_CloneBitmapArea(void)
4525 GpBitmap
*bitmap
, *copy
;
4526 BitmapData data
, data2
;
4528 status
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB
, NULL
, &bitmap
);
4531 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
| ImageLockModeWrite
, PixelFormat24bppRGB
, &data
);
4534 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data2
);
4535 expect(WrongState
, status
);
4537 status
= GdipCloneBitmapAreaI(0, 0, 1, 1, PixelFormat24bppRGB
, bitmap
, ©
);
4540 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4543 GdipDisposeImage((GpImage
*)copy
);
4544 GdipDisposeImage((GpImage
*)bitmap
);
4549 struct GdiplusStartupInput gdiplusStartupInput
;
4550 ULONG_PTR gdiplusToken
;
4552 gdiplusStartupInput
.GdiplusVersion
= 1;
4553 gdiplusStartupInput
.DebugEventCallback
= NULL
;
4554 gdiplusStartupInput
.SuppressBackgroundThread
= 0;
4555 gdiplusStartupInput
.SuppressExternalCodecs
= 0;
4557 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, NULL
);
4559 test_CloneBitmapArea();
4560 test_ARGB_conversion();
4561 test_DrawImage_scale();
4562 test_image_format();
4564 test_GdipDrawImagePointRect();
4566 test_tiff_palette();
4567 test_GdipGetAllPropertyItems();
4568 test_tiff_properties();
4569 test_gif_properties();
4570 test_image_properties();
4573 test_GetImageDimension();
4574 test_GdipImageGetFrameDimensionsCount();
4575 test_LoadingImages();
4576 test_SavingImages();
4579 test_LockBits_UserBuf();
4580 test_GdipCreateBitmapFromHBITMAP();
4581 test_GdipGetImageFlags();
4582 test_GdipCloneImage();
4585 test_getrawformat();
4587 test_createfromwmf();
4589 test_createhbitmap();
4590 test_getthumbnail();
4595 test_multiframegif();
4601 GdiplusShutdown(gdiplusToken
);