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,
1339 static const unsigned char bmpimage
[66] = {
1340 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
1341 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
1342 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
1343 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
1347 static const unsigned char jpgimage
[285] = {
1348 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
1349 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
1350 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
1351 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
1352 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
1353 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
1354 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
1355 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1356 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1357 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
1358 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
1359 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1360 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
1361 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
1362 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1363 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
1364 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
1365 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
1367 /* 1x1 pixel tiff */
1368 static const unsigned char tiffimage
[] = {
1369 0x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00,
1370 0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00,
1371 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1372 0x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01,
1373 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00,
1374 0x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00,
1375 0x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01,
1376 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00,
1377 0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00,
1378 0x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01,
1379 0x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00,
1380 0x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1381 0x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
1382 0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65,
1383 0x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74,
1384 0x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,
1387 /* 320x320 twip wmf */
1388 static const unsigned char wmfimage
[180] = {
1389 0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05,
1390 0x00,0x00,0x00,0x00,0xb1,0x52,0x01,0x00,0x09,0x00,0x00,0x03,0x4f,0x00,0x00,0x00,
1391 0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0b,0x02,0x00,0x00,
1392 0x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x02,0x40,0x01,0x40,0x01,0x04,0x00,0x00,0x00,
1393 0x02,0x01,0x01,0x00,0x04,0x00,0x00,0x00,0x04,0x01,0x0d,0x00,0x08,0x00,0x00,0x00,
1394 0xfa,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
1395 0x2d,0x01,0x00,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,0x01,0x00,0x00,0x00,0x00,0x00,
1396 0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x01,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,
1397 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x02,0x00,
1398 0x07,0x00,0x00,0x00,0x1b,0x04,0x40,0x01,0x40,0x01,0x00,0x00,0x00,0x00,0x04,0x00,
1399 0x00,0x00,0xf0,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0xf0,0x01,0x01,0x00,0x03,0x00,
1402 static void test_getrawformat(void)
1404 test_bufferrawformat((void*)pngimage
, sizeof(pngimage
), &ImageFormatPNG
, __LINE__
, FALSE
);
1405 test_bufferrawformat((void*)gifimage
, sizeof(gifimage
), &ImageFormatGIF
, __LINE__
, FALSE
);
1406 test_bufferrawformat((void*)bmpimage
, sizeof(bmpimage
), &ImageFormatBMP
, __LINE__
, FALSE
);
1407 test_bufferrawformat((void*)jpgimage
, sizeof(jpgimage
), &ImageFormatJPEG
, __LINE__
, FALSE
);
1408 test_bufferrawformat((void*)tiffimage
, sizeof(tiffimage
), &ImageFormatTIFF
, __LINE__
, FALSE
);
1409 test_bufferrawformat((void*)wmfimage
, sizeof(wmfimage
), &ImageFormatWMF
, __LINE__
, FALSE
);
1412 static void test_loadwmf(void)
1423 MetafileHeader header
;
1425 hglob
= GlobalAlloc (0, sizeof(wmfimage
));
1426 data
= GlobalLock (hglob
);
1427 memcpy(data
, wmfimage
, sizeof(wmfimage
));
1428 GlobalUnlock(hglob
); data
= NULL
;
1430 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
1431 ok(hres
== S_OK
, "Failed to create a stream\n");
1432 if(hres
!= S_OK
) return;
1434 stat
= GdipLoadImageFromStream(stream
, &img
);
1435 ok(stat
== Ok
, "Failed to create a Bitmap\n");
1437 IStream_Release(stream
);
1441 IStream_Release(stream
);
1443 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1445 todo_wine
expect(UnitPixel
, unit
);
1446 expectf(0.0, bounds
.X
);
1447 expectf(0.0, bounds
.Y
);
1448 todo_wine
expectf(320.0, bounds
.Width
);
1449 todo_wine
expectf(320.0, bounds
.Height
);
1451 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1453 todo_wine
expectf(1440.0, res
);
1455 stat
= GdipGetImageVerticalResolution(img
, &res
);
1457 todo_wine
expectf(1440.0, res
);
1459 memset(&header
, 0, sizeof(header
));
1460 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1464 todo_wine
expect(MetafileTypeWmfPlaceable
, header
.Type
);
1465 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1466 todo_wine
expect(0x300, header
.Version
);
1467 expect(0, header
.EmfPlusFlags
);
1468 todo_wine
expectf(1440.0, header
.DpiX
);
1469 todo_wine
expectf(1440.0, header
.DpiY
);
1470 expect(0, header
.X
);
1471 expect(0, header
.Y
);
1472 todo_wine
expect(320, header
.Width
);
1473 todo_wine
expect(320, header
.Height
);
1474 todo_wine
expect(1, U(header
).WmfHeader
.mtType
);
1475 expect(0, header
.EmfPlusHeaderSize
);
1476 expect(0, header
.LogicalDpiX
);
1477 expect(0, header
.LogicalDpiY
);
1480 GdipDisposeImage(img
);
1483 static void test_createfromwmf(void)
1491 MetafileHeader header
;
1493 hwmf
= SetMetaFileBitsEx(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
),
1494 wmfimage
+sizeof(WmfPlaceableFileHeader
));
1495 ok(hwmf
!= 0, "SetMetaFileBitsEx failed\n");
1497 stat
= GdipCreateMetafileFromWmf(hwmf
, TRUE
,
1498 (WmfPlaceableFileHeader
*)wmfimage
, (GpMetafile
**)&img
);
1501 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1503 expect(UnitPixel
, unit
);
1504 expectf(0.0, bounds
.X
);
1505 expectf(0.0, bounds
.Y
);
1506 expectf(320.0, bounds
.Width
);
1507 expectf(320.0, bounds
.Height
);
1509 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1511 expectf(1440.0, res
);
1513 stat
= GdipGetImageVerticalResolution(img
, &res
);
1515 expectf(1440.0, res
);
1517 memset(&header
, 0, sizeof(header
));
1518 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1522 todo_wine
expect(MetafileTypeWmfPlaceable
, header
.Type
);
1523 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1524 todo_wine
expect(0x300, header
.Version
);
1525 expect(0, header
.EmfPlusFlags
);
1526 todo_wine
expectf(1440.0, header
.DpiX
);
1527 todo_wine
expectf(1440.0, header
.DpiY
);
1528 expect(0, header
.X
);
1529 expect(0, header
.Y
);
1530 todo_wine
expect(320, header
.Width
);
1531 todo_wine
expect(320, header
.Height
);
1532 todo_wine
expect(1, U(header
).WmfHeader
.mtType
);
1533 expect(0, header
.EmfPlusHeaderSize
);
1534 expect(0, header
.LogicalDpiX
);
1535 expect(0, header
.LogicalDpiY
);
1538 GdipDisposeImage(img
);
1541 static void test_resolution(void)
1545 GpGraphics
*graphics
;
1548 int screenxres
, screenyres
;
1551 stat
= GdipCreateBitmapFromScan0(1, 1, 32, PixelFormat24bppRGB
, NULL
, &bitmap
);
1554 /* test invalid values */
1555 stat
= GdipGetImageHorizontalResolution(NULL
, &res
);
1556 expect(InvalidParameter
, stat
);
1558 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, NULL
);
1559 expect(InvalidParameter
, stat
);
1561 stat
= GdipGetImageVerticalResolution(NULL
, &res
);
1562 expect(InvalidParameter
, stat
);
1564 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, NULL
);
1565 expect(InvalidParameter
, stat
);
1567 stat
= GdipBitmapSetResolution(NULL
, 96.0, 96.0);
1568 expect(InvalidParameter
, stat
);
1570 stat
= GdipBitmapSetResolution(bitmap
, 0.0, 0.0);
1571 expect(InvalidParameter
, stat
);
1573 /* defaults to screen resolution */
1574 screendc
= GetDC(0);
1576 screenxres
= GetDeviceCaps(screendc
, LOGPIXELSX
);
1577 screenyres
= GetDeviceCaps(screendc
, LOGPIXELSY
);
1579 ReleaseDC(0, screendc
);
1581 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1583 expectf((REAL
)screenxres
, res
);
1585 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1587 expectf((REAL
)screenyres
, res
);
1589 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1591 stat
= GdipGetDpiX(graphics
, &res
);
1593 expectf((REAL
)screenxres
, res
);
1594 stat
= GdipGetDpiY(graphics
, &res
);
1596 expectf((REAL
)screenyres
, res
);
1598 /* test changing the resolution */
1599 stat
= GdipBitmapSetResolution(bitmap
, screenxres
*2.0, screenyres
*3.0);
1602 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1604 expectf(screenxres
*2.0, res
);
1606 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1608 expectf(screenyres
*3.0, res
);
1610 stat
= GdipGetDpiX(graphics
, &res
);
1612 expectf((REAL
)screenxres
, res
);
1613 stat
= GdipGetDpiY(graphics
, &res
);
1615 expectf((REAL
)screenyres
, res
);
1617 stat
= GdipDeleteGraphics(graphics
);
1620 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1622 stat
= GdipGetDpiX(graphics
, &res
);
1624 expectf(screenxres
*2.0, res
);
1625 stat
= GdipGetDpiY(graphics
, &res
);
1627 expectf(screenyres
*3.0, res
);
1628 stat
= GdipDeleteGraphics(graphics
);
1631 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1635 static void test_createhbitmap(void)
1639 HBITMAP hbitmap
, oldhbitmap
;
1646 memset(bits
, 0x68, 640);
1649 stat
= GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB
, bits
, &bitmap
);
1652 /* test NULL values */
1653 stat
= GdipCreateHBITMAPFromBitmap(NULL
, &hbitmap
, 0);
1654 expect(InvalidParameter
, stat
);
1656 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, NULL
, 0);
1657 expect(InvalidParameter
, stat
);
1659 /* create HBITMAP */
1660 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1665 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1666 expect(sizeof(BITMAP
), ret
);
1668 expect(0, bm
.bmType
);
1669 expect(10, bm
.bmWidth
);
1670 expect(20, bm
.bmHeight
);
1671 expect(40, bm
.bmWidthBytes
);
1672 expect(1, bm
.bmPlanes
);
1673 expect(32, bm
.bmBitsPixel
);
1674 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1678 DWORD val
= *(DWORD
*)bm
.bmBits
;
1679 ok(val
== 0xff686868, "got %x, expected 0xff686868\n", val
);
1682 hdc
= CreateCompatibleDC(NULL
);
1684 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1685 pixel
= GetPixel(hdc
, 5, 5);
1686 SelectObject(hdc
, oldhbitmap
);
1690 expect(0x686868, pixel
);
1692 DeleteObject(hbitmap
);
1695 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1698 /* make (1,0) have no alpha and (2,0) a different blue value. */
1702 /* create alpha Bitmap */
1703 stat
= GdipCreateBitmapFromScan0(8, 20, 32, PixelFormat32bppARGB
, bits
, &bitmap
);
1706 /* create HBITMAP */
1707 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1712 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1713 expect(sizeof(BITMAP
), ret
);
1715 expect(0, bm
.bmType
);
1716 expect(8, bm
.bmWidth
);
1717 expect(20, bm
.bmHeight
);
1718 expect(32, bm
.bmWidthBytes
);
1719 expect(1, bm
.bmPlanes
);
1720 expect(32, bm
.bmBitsPixel
);
1721 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1725 DWORD val
= *(DWORD
*)bm
.bmBits
;
1726 ok(val
== 0x682a2a2a, "got %x, expected 0x682a2a2a\n", val
);
1727 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1728 ok(val
== 0x0, "got %x, expected 0x682a2a2a\n", val
);
1731 hdc
= CreateCompatibleDC(NULL
);
1733 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1734 pixel
= GetPixel(hdc
, 5, 5);
1735 expect(0x2a2a2a, pixel
);
1736 pixel
= GetPixel(hdc
, 1, 0);
1739 SelectObject(hdc
, oldhbitmap
);
1744 DeleteObject(hbitmap
);
1747 /* create HBITMAP with bkgnd colour */
1748 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0xff00ff);
1753 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1754 expect(sizeof(BITMAP
), ret
);
1756 expect(0, bm
.bmType
);
1757 expect(8, bm
.bmWidth
);
1758 expect(20, bm
.bmHeight
);
1759 expect(32, bm
.bmWidthBytes
);
1760 expect(1, bm
.bmPlanes
);
1761 expect(32, bm
.bmBitsPixel
);
1762 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1766 DWORD val
= *(DWORD
*)bm
.bmBits
;
1767 ok(val
== 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val
);
1768 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1769 ok(val
== 0xff00ff, "got %x, expected 0x682a2a2a\n", val
);
1772 hdc
= CreateCompatibleDC(NULL
);
1774 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1775 pixel
= GetPixel(hdc
, 5, 5);
1776 expect(0xc12ac1, pixel
);
1777 pixel
= GetPixel(hdc
, 1, 0);
1778 expect(0xff00ff, pixel
);
1779 pixel
= GetPixel(hdc
, 2, 0);
1780 expect(0xb12ac1, pixel
);
1782 SelectObject(hdc
, oldhbitmap
);
1784 DeleteObject(hbitmap
);
1787 /* create HBITMAP with bkgnd colour with alpha and show it behaves with no alpha. */
1788 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0x80ff00ff);
1793 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1794 expect(sizeof(BITMAP
), ret
);
1796 expect(0, bm
.bmType
);
1797 expect(8, bm
.bmWidth
);
1798 expect(20, bm
.bmHeight
);
1799 expect(32, bm
.bmWidthBytes
);
1800 expect(1, bm
.bmPlanes
);
1801 expect(32, bm
.bmBitsPixel
);
1802 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1806 DWORD val
= *(DWORD
*)bm
.bmBits
;
1807 ok(val
== 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val
);
1808 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1809 ok(val
== 0xff00ff, "got %x, expected 0x682a2a2a\n", val
);
1812 hdc
= CreateCompatibleDC(NULL
);
1814 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1815 pixel
= GetPixel(hdc
, 5, 5);
1816 expect(0xc12ac1, pixel
);
1817 pixel
= GetPixel(hdc
, 1, 0);
1818 expect(0xff00ff, pixel
);
1819 pixel
= GetPixel(hdc
, 2, 0);
1820 expect(0xb12ac1, pixel
);
1822 SelectObject(hdc
, oldhbitmap
);
1824 DeleteObject(hbitmap
);
1827 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1831 static void test_getthumbnail(void)
1834 GpImage
*bitmap1
, *bitmap2
;
1837 stat
= GdipGetImageThumbnail(NULL
, 0, 0, &bitmap2
, NULL
, NULL
);
1838 expect(InvalidParameter
, stat
);
1840 stat
= GdipCreateBitmapFromScan0(128, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1843 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, NULL
, NULL
, NULL
);
1844 expect(InvalidParameter
, stat
);
1846 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, &bitmap2
, NULL
, NULL
);
1851 stat
= GdipGetImageWidth(bitmap2
, &width
);
1855 stat
= GdipGetImageHeight(bitmap2
, &height
);
1857 expect(120, height
);
1859 GdipDisposeImage(bitmap2
);
1862 GdipDisposeImage(bitmap1
);
1865 stat
= GdipCreateBitmapFromScan0(64, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1868 stat
= GdipGetImageThumbnail(bitmap1
, 32, 32, &bitmap2
, NULL
, NULL
);
1873 stat
= GdipGetImageWidth(bitmap2
, &width
);
1877 stat
= GdipGetImageHeight(bitmap2
, &height
);
1881 GdipDisposeImage(bitmap2
);
1884 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, &bitmap2
, NULL
, NULL
);
1889 stat
= GdipGetImageWidth(bitmap2
, &width
);
1893 stat
= GdipGetImageHeight(bitmap2
, &height
);
1895 expect(120, height
);
1897 GdipDisposeImage(bitmap2
);
1900 GdipDisposeImage(bitmap1
);
1903 static void test_getsetpixel(void)
1908 BYTE bits
[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00,
1909 0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00};
1911 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, bits
, &bitmap
);
1914 /* null parameters */
1915 stat
= GdipBitmapGetPixel(NULL
, 1, 1, &color
);
1916 expect(InvalidParameter
, stat
);
1918 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, NULL
);
1919 expect(InvalidParameter
, stat
);
1921 stat
= GdipBitmapSetPixel(NULL
, 1, 1, 0);
1922 expect(InvalidParameter
, stat
);
1925 stat
= GdipBitmapGetPixel(bitmap
, -1, 1, &color
);
1926 expect(InvalidParameter
, stat
);
1928 stat
= GdipBitmapSetPixel(bitmap
, -1, 1, 0);
1929 expect(InvalidParameter
, stat
);
1931 stat
= GdipBitmapGetPixel(bitmap
, 1, -1, &color
);
1932 ok(stat
== InvalidParameter
||
1933 broken(stat
== Ok
), /* Older gdiplus */
1934 "Expected InvalidParameter, got %.8x\n", stat
);
1936 if (0) /* crashes some gdiplus implementations */
1938 stat
= GdipBitmapSetPixel(bitmap
, 1, -1, 0);
1939 ok(stat
== InvalidParameter
||
1940 broken(stat
== Ok
), /* Older gdiplus */
1941 "Expected InvalidParameter, got %.8x\n", stat
);
1944 stat
= GdipBitmapGetPixel(bitmap
, 2, 1, &color
);
1945 expect(InvalidParameter
, stat
);
1947 stat
= GdipBitmapSetPixel(bitmap
, 2, 1, 0);
1948 expect(InvalidParameter
, stat
);
1950 stat
= GdipBitmapGetPixel(bitmap
, 1, 2, &color
);
1951 expect(InvalidParameter
, stat
);
1953 stat
= GdipBitmapSetPixel(bitmap
, 1, 2, 0);
1954 expect(InvalidParameter
, stat
);
1957 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
1959 expect(0xffffffff, color
);
1961 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
1963 expect(0xff0000ff, color
);
1965 stat
= GdipBitmapSetPixel(bitmap
, 1, 1, 0xff676869);
1968 stat
= GdipBitmapSetPixel(bitmap
, 0, 0, 0xff474849);
1971 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
1973 expect(0xff676869, color
);
1975 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
1977 expect(0xff474849, color
);
1979 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1983 static void check_halftone_palette(ColorPalette
*palette
)
1985 static const BYTE halftone_values
[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
1988 for (i
=0; i
<palette
->Count
; i
++)
1990 ARGB expected
=0xff000000;
1993 if (i
&1) expected
|= 0x800000;
1994 if (i
&2) expected
|= 0x8000;
1995 if (i
&4) expected
|= 0x80;
1999 expected
= 0xffc0c0c0;
2003 if (i
&1) expected
|= 0xff0000;
2004 if (i
&2) expected
|= 0xff00;
2005 if (i
&4) expected
|= 0xff;
2009 expected
= 0x00000000;
2013 expected
|= halftone_values
[(i
-40)%6];
2014 expected
|= halftone_values
[((i
-40)/6)%6] << 8;
2015 expected
|= halftone_values
[((i
-40)/36)%6] << 16;
2017 ok(expected
== palette
->Entries
[i
], "Expected %.8x, got %.8x, i=%u/%u\n",
2018 expected
, palette
->Entries
[i
], i
, palette
->Count
);
2022 static void test_palette(void)
2028 ColorPalette
*palette
=(ColorPalette
*)buffer
;
2029 ARGB
*entries
= palette
->Entries
;
2032 /* test initial palette from non-indexed bitmap */
2033 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, NULL
, &bitmap
);
2036 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2038 expect(sizeof(UINT
)*2+sizeof(ARGB
), size
);
2040 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2042 expect(0, palette
->Count
);
2044 /* test setting palette on not-indexed bitmap */
2047 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2050 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2052 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2054 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2056 expect(3, palette
->Count
);
2058 GdipDisposeImage((GpImage
*)bitmap
);
2060 /* test initial palette on 1-bit bitmap */
2061 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat1bppIndexed
, NULL
, &bitmap
);
2064 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2066 expect(sizeof(UINT
)*2+sizeof(ARGB
)*2, size
);
2068 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2070 expect(PaletteFlagsGrayScale
, palette
->Flags
);
2071 expect(2, palette
->Count
);
2073 expect(0xff000000, entries
[0]);
2074 expect(0xffffffff, entries
[1]);
2076 /* test getting/setting pixels */
2077 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2079 expect(0xff000000, color
);
2081 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffffffff);
2083 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2087 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2089 expect(0xffffffff, color
);
2092 GdipDisposeImage((GpImage
*)bitmap
);
2094 /* test initial palette on 4-bit bitmap */
2095 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat4bppIndexed
, NULL
, &bitmap
);
2098 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2100 expect(sizeof(UINT
)*2+sizeof(ARGB
)*16, size
);
2102 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2104 expect(0, palette
->Flags
);
2105 expect(16, palette
->Count
);
2107 check_halftone_palette(palette
);
2109 /* test getting/setting pixels */
2110 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2112 expect(0xff000000, color
);
2114 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffff00ff);
2116 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2120 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2122 expect(0xffff00ff, color
);
2125 GdipDisposeImage((GpImage
*)bitmap
);
2127 /* test initial palette on 8-bit bitmap */
2128 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat8bppIndexed
, NULL
, &bitmap
);
2131 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2133 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2135 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2137 expect(PaletteFlagsHalftone
, palette
->Flags
);
2138 expect(256, palette
->Count
);
2140 check_halftone_palette(palette
);
2142 /* test getting/setting pixels */
2143 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2145 expect(0xff000000, color
);
2147 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffcccccc);
2149 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2153 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2155 expect(0xffcccccc, color
);
2158 /* test setting/getting a different palette */
2159 entries
[1] = 0xffcccccc;
2161 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2166 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2168 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2170 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2172 expect(PaletteFlagsHalftone
, palette
->Flags
);
2173 expect(256, palette
->Count
);
2174 expect(0xffcccccc, entries
[1]);
2176 /* test count < 256 */
2177 palette
->Flags
= 12345;
2180 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2184 entries
[3] = 0xdeadbeef;
2186 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2188 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2190 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2192 expect(12345, palette
->Flags
);
2193 expect(3, palette
->Count
);
2194 expect(0xffcccccc, entries
[1]);
2195 expect(0xdeadbeef, entries
[3]);
2197 /* test count > 256 */
2198 palette
->Count
= 257;
2200 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2201 ok(stat
== InvalidParameter
||
2202 broken(stat
== Ok
), /* Old gdiplus behavior */
2203 "Expected %.8x, got %.8x\n", InvalidParameter
, stat
);
2205 GdipDisposeImage((GpImage
*)bitmap
);
2208 static void test_colormatrix(void)
2211 ColorMatrix colormatrix
, graymatrix
;
2212 GpImageAttributes
*imageattr
;
2213 const ColorMatrix identity
= {{
2214 {1.0,0.0,0.0,0.0,0.0},
2215 {0.0,1.0,0.0,0.0,0.0},
2216 {0.0,0.0,1.0,0.0,0.0},
2217 {0.0,0.0,0.0,1.0,0.0},
2218 {0.0,0.0,0.0,0.0,1.0}}};
2219 const ColorMatrix double_red
= {{
2220 {2.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 asymmetric
= {{
2226 {0.0,1.0,0.0,0.0,0.0},
2227 {0.0,0.0,1.0,0.0,0.0},
2228 {0.0,0.0,0.0,1.0,0.0},
2229 {1.0,0.0,0.0,0.0,0.0},
2230 {0.0,0.0,0.0,0.0,1.0}}};
2231 GpBitmap
*bitmap1
, *bitmap2
;
2232 GpGraphics
*graphics
;
2235 colormatrix
= identity
;
2236 graymatrix
= identity
;
2238 stat
= GdipSetImageAttributesColorMatrix(NULL
, ColorAdjustTypeDefault
,
2239 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2240 expect(InvalidParameter
, stat
);
2242 stat
= GdipCreateImageAttributes(&imageattr
);
2245 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2246 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2249 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2250 TRUE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2251 expect(InvalidParameter
, stat
);
2253 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2254 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2257 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2258 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsSkipGrays
);
2261 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2262 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsAltGray
);
2263 expect(InvalidParameter
, stat
);
2265 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2266 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsAltGray
);
2269 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2270 TRUE
, &colormatrix
, &graymatrix
, 3);
2271 expect(InvalidParameter
, stat
);
2273 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeCount
,
2274 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2275 expect(InvalidParameter
, stat
);
2277 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeAny
,
2278 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2279 expect(InvalidParameter
, stat
);
2281 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2282 FALSE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2285 /* Drawing a bitmap transforms the colors */
2286 colormatrix
= double_red
;
2287 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2288 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2291 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
2294 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
2297 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff40ccee);
2300 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2303 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2304 UnitPixel
, imageattr
, NULL
, NULL
);
2307 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2309 expect(0xff80ccee, color
);
2311 colormatrix
= asymmetric
;
2312 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2313 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2316 stat
= GdipBitmapSetPixel(bitmap2
, 0, 0, 0);
2319 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2320 UnitPixel
, imageattr
, NULL
, NULL
);
2323 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2325 ok(color_match(0xeeff40cc, color
, 3), "expected 0xeeff40cc, got 0x%08x\n", color
);
2327 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2330 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2331 UnitPixel
, imageattr
, NULL
, NULL
);
2334 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2336 ok(color_match(0xff40ccee, color
, 1), "Expected ff40ccee, got %.8x\n", color
);
2338 GdipDeleteGraphics(graphics
);
2339 GdipDisposeImage((GpImage
*)bitmap1
);
2340 GdipDisposeImage((GpImage
*)bitmap2
);
2341 GdipDisposeImageAttributes(imageattr
);
2344 static void test_gamma(void)
2347 GpImageAttributes
*imageattr
;
2348 GpBitmap
*bitmap1
, *bitmap2
;
2349 GpGraphics
*graphics
;
2352 stat
= GdipSetImageAttributesGamma(NULL
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2353 expect(InvalidParameter
, stat
);
2355 stat
= GdipCreateImageAttributes(&imageattr
);
2358 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2361 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeAny
, TRUE
, 1.0);
2362 expect(InvalidParameter
, stat
);
2364 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, -1.0);
2365 expect(InvalidParameter
, stat
);
2367 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.0);
2368 expect(InvalidParameter
, stat
);
2370 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.5);
2373 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0.0);
2376 /* Drawing a bitmap transforms the colors */
2377 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 3.0);
2380 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
2383 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
2386 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff80ffff);
2389 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2392 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2393 UnitPixel
, imageattr
, NULL
, NULL
);
2396 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2398 ok(color_match(0xff20ffff, color
, 1), "Expected ff20ffff, got %.8x\n", color
);
2400 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2403 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2404 UnitPixel
, imageattr
, NULL
, NULL
);
2407 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2409 ok(color_match(0xff80ffff, color
, 1), "Expected ff80ffff, got %.8x\n", color
);
2411 GdipDeleteGraphics(graphics
);
2412 GdipDisposeImage((GpImage
*)bitmap1
);
2413 GdipDisposeImage((GpImage
*)bitmap2
);
2414 GdipDisposeImageAttributes(imageattr
);
2417 /* 1x1 pixel gif, 2 frames; first frame is white, second is black */
2418 static const unsigned char gifanimation
[72] = {
2419 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
2420 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0xf9,0x04,0x00,0x0a,0x00,0xff,
2421 0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x4c,0x01,0x00,
2422 0x21,0xf9,0x04,0x01,0x0a,0x00,0x01,0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,
2423 0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
2426 /* Generated with ImageMagick:
2427 * convert -transparent black -delay 100 -size 8x2 xc:black \
2428 * -dispose none -page +0+0 -size 2x2 xc:red \
2429 * -dispose background -page +2+0 -size 2x2 xc:blue \
2430 * -dispose previous -page +4+0 -size 2x2 xc:green \
2431 * -dispose undefined -page +6+0 -size 2x2 xc:gray \
2434 static const unsigned char gifanimation2
[] = {
2435 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x08, 0x00,
2436 0x02, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
2437 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x64,
2438 0x00, 0x00, 0x00, 0x21, 0xff, 0x0b, 0x4e, 0x45,
2439 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e,
2440 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00,
2441 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
2442 0x02, 0x04, 0x84, 0x8f, 0x09, 0x05, 0x00, 0x21,
2443 0xf9, 0x04, 0x04, 0x64, 0x00, 0x00, 0x00, 0x2c,
2444 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2445 0x81, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
2446 0x00, 0x00, 0xff, 0x00, 0x00, 0x02, 0x03, 0x44,
2447 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x08, 0x64,
2448 0x00, 0x00, 0x00, 0x2c, 0x02, 0x00, 0x00, 0x00,
2449 0x02, 0x00, 0x02, 0x00, 0x81, 0x00, 0x00, 0xff,
2450 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
2451 0xff, 0x02, 0x03, 0x44, 0x34, 0x05, 0x00, 0x21,
2452 0xf9, 0x04, 0x0c, 0x64, 0x00, 0x00, 0x00, 0x2c,
2453 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2454 0x81, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00,
2455 0x80, 0x00, 0x00, 0x80, 0x00, 0x02, 0x03, 0x44,
2456 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x64,
2457 0x00, 0x00, 0x00, 0x2c, 0x06, 0x00, 0x00, 0x00,
2458 0x02, 0x00, 0x02, 0x00, 0x80, 0x7e, 0x7e, 0x7e,
2459 0x00, 0x00, 0x00, 0x02, 0x02, 0x84, 0x51, 0x00,
2463 static ARGB gifanimation2_pixels
[5][4] = {
2465 {0xffff0000, 0, 0, 0},
2466 {0xffff0000, 0xff0000ff, 0, 0},
2467 {0xffff0000, 0, 0xff008000, 0},
2468 {0xffff0000, 0, 0, 0xff7e7e7e}
2471 static void test_multiframegif(void)
2482 PixelFormat pixel_format
;
2483 INT palette_size
, i
, j
;
2485 /* Test frame functions with an animated GIF */
2486 hglob
= GlobalAlloc (0, sizeof(gifanimation
));
2487 data
= GlobalLock (hglob
);
2488 memcpy(data
, gifanimation
, sizeof(gifanimation
));
2489 GlobalUnlock(hglob
);
2491 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2492 ok(hres
== S_OK
, "Failed to create a stream\n");
2493 if(hres
!= S_OK
) return;
2495 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2496 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2498 IStream_Release(stream
);
2502 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2504 expect(PixelFormat32bppARGB
, pixel_format
);
2506 stat
= GdipGetImagePaletteSize((GpImage
*)bmp
, &palette_size
);
2508 ok(palette_size
== sizeof(ColorPalette
) ||
2509 broken(palette_size
== sizeof(ColorPalette
)+sizeof(ARGB
[3])),
2510 "palette_size = %d\n", palette_size
);
2512 /* Bitmap starts at frame 0 */
2514 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2516 expect(0xffffffff, color
);
2518 /* Check that we get correct metadata */
2519 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2523 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2525 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2528 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2532 /* SelectActiveFrame overwrites our current data */
2533 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2537 GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2539 expect(0xff000000, color
);
2541 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2545 GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2547 expect(0xffffffff, color
);
2549 /* Write over the image data */
2550 stat
= GdipBitmapSetPixel(bmp
, 0, 0, 0xff000000);
2553 /* Switching to the same frame does not overwrite our changes */
2554 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2557 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2559 expect(0xff000000, color
);
2561 /* But switching to another frame and back does */
2562 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2565 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2568 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2570 expect(0xffffffff, color
);
2572 /* rotate/flip discards the information about other frames */
2573 stat
= GdipImageRotateFlip((GpImage
*)bmp
, Rotate90FlipNone
);
2577 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2581 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bmp
, __LINE__
, FALSE
);
2583 GdipDisposeImage((GpImage
*)bmp
);
2584 IStream_Release(stream
);
2586 /* Test with a non-animated gif */
2587 hglob
= GlobalAlloc (0, sizeof(gifimage
));
2588 data
= GlobalLock (hglob
);
2589 memcpy(data
, gifimage
, sizeof(gifimage
));
2590 GlobalUnlock(hglob
);
2592 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2593 ok(hres
== S_OK
, "Failed to create a stream\n");
2594 if(hres
!= S_OK
) return;
2596 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2597 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2599 IStream_Release(stream
);
2603 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2605 expect(PixelFormat8bppIndexed
, pixel_format
);
2607 /* Check metadata */
2608 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2612 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2614 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2617 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2621 GdipDisposeImage((GpImage
*)bmp
);
2622 IStream_Release(stream
);
2624 /* Test frame dispose methods */
2625 hglob
= GlobalAlloc (0, sizeof(gifanimation2
));
2626 data
= GlobalLock (hglob
);
2627 memcpy(data
, gifanimation2
, sizeof(gifanimation2
));
2628 GlobalUnlock(hglob
);
2630 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2631 ok(hres
== S_OK
, "Failed to create a stream\n");
2633 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2634 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2635 IStream_Release(stream
);
2637 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2639 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2641 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2645 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2649 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 3);
2650 stat
= GdipBitmapGetPixel(bmp
, 2, 0, &color
);
2652 ok(color
==0 || broken(color
==0xff0000ff), "color = %x\n", color
);
2654 win_skip("broken animated gif support\n");
2655 GdipDisposeImage((GpImage
*)bmp
);
2659 for(i
=0; i
<6; i
++) {
2660 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, i
%5);
2663 for(j
=0; j
<4; j
++) {
2664 stat
= GdipBitmapGetPixel(bmp
, j
*2, 0, &color
);
2666 ok(gifanimation2_pixels
[i
%5][j
] == color
, "at %d,%d got %x, expected %x\n", i
, j
, color
, gifanimation2_pixels
[i
%5][j
]);
2670 GdipDisposeImage((GpImage
*)bmp
);
2673 static void test_rotateflip(void)
2678 static const BYTE orig_bits
[24] = {
2679 0,0,0xff, 0,0xff,0, 0xff,0,0, 23,23,23,
2680 0xff,0xff,0, 0xff,0,0xff, 0,0xff,0xff, 23,23,23};
2684 memcpy(bits
, orig_bits
, sizeof(bits
));
2685 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2688 stat
= GdipImageRotateFlip(bitmap
, Rotate90FlipNone
);
2691 stat
= GdipGetImageWidth(bitmap
, &width
);
2693 stat
= GdipGetImageHeight(bitmap
, &height
);
2698 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2700 expect(0xff00ffff, color
);
2702 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 0, &color
);
2704 expect(0xffff0000, color
);
2706 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 2, &color
);
2708 expect(0xffffff00, color
);
2710 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 2, &color
);
2712 expect(0xff0000ff, color
);
2716 expect(0xff, bits
[2]);
2718 GdipDisposeImage(bitmap
);
2720 memcpy(bits
, orig_bits
, sizeof(bits
));
2721 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2724 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipX
);
2727 stat
= GdipGetImageWidth(bitmap
, &width
);
2729 stat
= GdipGetImageHeight(bitmap
, &height
);
2734 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2736 expect(0xff0000ff, color
);
2738 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
2740 expect(0xffff0000, color
);
2742 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
2744 expect(0xffffff00, color
);
2746 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
2748 expect(0xff00ffff, color
);
2752 expect(0xff, bits
[2]);
2754 GdipDisposeImage(bitmap
);
2756 memcpy(bits
, orig_bits
, sizeof(bits
));
2757 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2760 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipY
);
2763 stat
= GdipGetImageWidth(bitmap
, &width
);
2765 stat
= GdipGetImageHeight(bitmap
, &height
);
2770 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2772 expect(0xff00ffff, color
);
2774 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
2776 expect(0xffffff00, color
);
2778 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
2780 expect(0xffff0000, color
);
2782 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
2784 expect(0xff0000ff, color
);
2788 expect(0xff, bits
[2]);
2790 GdipDisposeImage(bitmap
);
2793 static void test_remaptable(void)
2796 GpImageAttributes
*imageattr
;
2797 GpBitmap
*bitmap1
, *bitmap2
;
2798 GpGraphics
*graphics
;
2802 map
= GdipAlloc(sizeof(ColorMap
));
2804 map
->oldColor
.Argb
= 0xff00ff00;
2805 map
->newColor
.Argb
= 0xffff00ff;
2807 stat
= GdipSetImageAttributesRemapTable(NULL
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
2808 expect(InvalidParameter
, stat
);
2810 stat
= GdipCreateImageAttributes(&imageattr
);
2813 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, NULL
);
2814 expect(InvalidParameter
, stat
);
2816 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeCount
, TRUE
, 1, map
);
2817 expect(InvalidParameter
, stat
);
2819 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeAny
, TRUE
, 1, map
);
2820 expect(InvalidParameter
, stat
);
2822 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0, map
);
2823 expect(InvalidParameter
, stat
);
2825 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0, NULL
);
2828 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
2831 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
2834 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
2837 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff00ff00);
2840 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2843 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2844 UnitPixel
, imageattr
, NULL
, NULL
);
2847 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2849 ok(color_match(0xffff00ff, color
, 1), "Expected ffff00ff, got %.8x\n", color
);
2851 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2854 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2855 UnitPixel
, imageattr
, NULL
, NULL
);
2858 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2860 ok(color_match(0xff00ff00, color
, 1), "Expected ff00ff00, got %.8x\n", color
);
2862 GdipDeleteGraphics(graphics
);
2863 GdipDisposeImage((GpImage
*)bitmap1
);
2864 GdipDisposeImage((GpImage
*)bitmap2
);
2865 GdipDisposeImageAttributes(imageattr
);
2869 static void test_colorkey(void)
2872 GpImageAttributes
*imageattr
;
2873 GpBitmap
*bitmap1
, *bitmap2
;
2874 GpGraphics
*graphics
;
2877 stat
= GdipSetImageAttributesColorKeys(NULL
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
2878 expect(InvalidParameter
, stat
);
2880 stat
= GdipCreateImageAttributes(&imageattr
);
2883 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeCount
, TRUE
, 0xff405060, 0xff708090);
2884 expect(InvalidParameter
, stat
);
2886 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeAny
, TRUE
, 0xff405060, 0xff708090);
2887 expect(InvalidParameter
, stat
);
2889 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
2892 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
2895 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
2898 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0x20405060);
2901 stat
= GdipBitmapSetPixel(bitmap1
, 0, 1, 0x40506070);
2904 stat
= GdipBitmapSetPixel(bitmap1
, 1, 0, 0x60708090);
2907 stat
= GdipBitmapSetPixel(bitmap1
, 1, 1, 0xffffffff);
2910 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2913 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
2914 UnitPixel
, imageattr
, NULL
, NULL
);
2917 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2919 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
2921 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
2923 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
2925 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
2927 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
2929 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
2931 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
2933 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2936 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
2937 UnitPixel
, imageattr
, NULL
, NULL
);
2940 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2942 ok(color_match(0x20405060, color
, 1), "Expected 20405060, got %.8x\n", color
);
2944 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
2946 ok(color_match(0x40506070, color
, 1), "Expected 40506070, got %.8x\n", color
);
2948 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
2950 ok(color_match(0x60708090, color
, 1), "Expected 60708090, got %.8x\n", color
);
2952 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
2954 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
2957 GdipDeleteGraphics(graphics
);
2958 GdipDisposeImage((GpImage
*)bitmap1
);
2959 GdipDisposeImage((GpImage
*)bitmap2
);
2960 GdipDisposeImageAttributes(imageattr
);
2963 static void test_dispose(void)
2967 char invalid_image
[256];
2969 stat
= GdipDisposeImage(NULL
);
2970 expect(InvalidParameter
, stat
);
2972 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, (GpBitmap
**)&image
);
2975 stat
= GdipDisposeImage(image
);
2978 stat
= GdipDisposeImage(image
);
2979 expect(ObjectBusy
, stat
);
2981 memset(invalid_image
, 0, 256);
2982 stat
= GdipDisposeImage((GpImage
*)invalid_image
);
2983 expect(ObjectBusy
, stat
);
2986 static LONG
obj_refcount(void *obj
)
2988 IUnknown_AddRef((IUnknown
*)obj
);
2989 return IUnknown_Release((IUnknown
*)obj
);
2992 static GpImage
*load_image(const BYTE
*image_data
, UINT image_size
)
2999 GpImage
*image
= NULL
, *clone
;
3000 ImageType image_type
;
3001 LONG refcount
, old_refcount
;
3003 hmem
= GlobalAlloc(0, image_size
);
3004 data
= GlobalLock(hmem
);
3005 memcpy(data
, image_data
, image_size
);
3008 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
3009 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
3010 if (hr
!= S_OK
) return NULL
;
3012 refcount
= obj_refcount(stream
);
3013 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3015 status
= GdipLoadImageFromStream(stream
, &image
);
3016 ok(status
== Ok
|| broken(status
== InvalidParameter
), /* XP */
3017 "GdipLoadImageFromStream error %d\n", status
);
3020 IStream_Release(stream
);
3024 status
= GdipGetImageType(image
, &image_type
);
3025 ok(status
== Ok
, "GdipGetImageType error %d\n", status
);
3027 refcount
= obj_refcount(stream
);
3028 if (image_type
== ImageTypeBitmap
)
3029 ok(refcount
> 1, "expected stream refcount > 1, got %d\n", refcount
);
3031 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3032 old_refcount
= refcount
;
3034 status
= GdipCloneImage(image
, &clone
);
3035 ok(status
== Ok
, "GdipCloneImage error %d\n", status
);
3036 refcount
= obj_refcount(stream
);
3037 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3038 status
= GdipDisposeImage(clone
);
3039 ok(status
== Ok
, "GdipDisposeImage error %d\n", status
);
3040 refcount
= obj_refcount(stream
);
3041 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3043 refcount
= IStream_Release(stream
);
3044 if (image_type
== ImageTypeBitmap
)
3045 ok(refcount
>= 1, "expected stream refcount != 0\n");
3047 ok(refcount
== 0, "expected stream refcount 0, got %d\n", refcount
);
3052 static void test_image_properties(void)
3054 static const struct test_data
3056 const BYTE
*image_data
;
3058 ImageType image_type
;
3060 UINT prop_count2
; /* if win7 behaves differently */
3061 /* 1st property attributes */
3063 UINT prop_size2
; /* if win7 behaves differently */
3065 UINT prop_id2
; /* if win7 behaves differently */
3069 { pngimage
, sizeof(pngimage
), ImageTypeBitmap
, 4, ~0, 1, 20, 0x5110, 0x132 },
3070 { jpgimage
, sizeof(jpgimage
), ImageTypeBitmap
, 2, ~0, 128, 0, 0x5090, 0x5091 },
3071 { tiffimage
, sizeof(tiffimage
), ImageTypeBitmap
, 16, 0, 4, 0, 0xfe, 0 },
3072 { bmpimage
, sizeof(bmpimage
), ImageTypeBitmap
, 0, 0, 0, 0, 0, 0 },
3073 { wmfimage
, sizeof(wmfimage
), ImageTypeMetafile
, 0, 0, 0, 0, 0, 0 }
3077 UINT prop_count
, prop_size
, i
;
3078 PROPID prop_id
[16] = { 0 };
3079 ImageType image_type
;
3086 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
3088 image
= load_image(td
[i
].image_data
, td
[i
].image_size
);
3091 trace("%u: failed to load image data\n", i
);
3095 status
= GdipGetImageType(image
, &image_type
);
3096 ok(status
== Ok
, "%u: GdipGetImageType error %d\n", i
, status
);
3097 ok(td
[i
].image_type
== image_type
, "%u: expected image_type %d, got %d\n",
3098 i
, td
[i
].image_type
, image_type
);
3100 status
= GdipGetPropertyCount(image
, &prop_count
);
3101 ok(status
== Ok
, "%u: GdipGetPropertyCount error %d\n", i
, status
);
3102 if (td
[i
].image_data
== pngimage
|| td
[i
].image_data
== jpgimage
)
3104 ok(td
[i
].prop_count
== prop_count
|| td
[i
].prop_count2
== prop_count
,
3105 " %u: expected property count %u or %u, got %u\n",
3106 i
, td
[i
].prop_count
, td
[i
].prop_count2
, prop_count
);
3108 ok(td
[i
].prop_count
== prop_count
|| td
[i
].prop_count2
== prop_count
,
3109 " %u: expected property count %u or %u, got %u\n",
3110 i
, td
[i
].prop_count
, td
[i
].prop_count2
, prop_count
);
3112 status
= GdipGetPropertyItemSize(NULL
, 0, &prop_size
);
3113 expect(InvalidParameter
, status
);
3114 status
= GdipGetPropertyItemSize(image
, 0, NULL
);
3115 expect(InvalidParameter
, status
);
3116 status
= GdipGetPropertyItemSize(image
, 0, &prop_size
);
3117 if (image_type
== ImageTypeMetafile
)
3118 expect(NotImplemented
, status
);
3120 expect(PropertyNotFound
, status
);
3122 status
= GdipGetPropertyItem(NULL
, 0, 0, &item
.data
);
3123 expect(InvalidParameter
, status
);
3124 status
= GdipGetPropertyItem(image
, 0, 0, NULL
);
3125 expect(InvalidParameter
, status
);
3126 status
= GdipGetPropertyItem(image
, 0, 0, &item
.data
);
3127 if (image_type
== ImageTypeMetafile
)
3128 expect(NotImplemented
, status
);
3130 expect(PropertyNotFound
, status
);
3132 /* FIXME: remove once Wine is fixed */
3133 if (td
[i
].prop_count
!= prop_count
)
3135 GdipDisposeImage(image
);
3139 status
= GdipGetPropertyIdList(NULL
, prop_count
, prop_id
);
3140 expect(InvalidParameter
, status
);
3141 status
= GdipGetPropertyIdList(image
, prop_count
, NULL
);
3142 expect(InvalidParameter
, status
);
3143 status
= GdipGetPropertyIdList(image
, 0, prop_id
);
3144 if (image_type
== ImageTypeMetafile
)
3145 expect(NotImplemented
, status
);
3146 else if (prop_count
== 0)
3149 expect(InvalidParameter
, status
);
3150 status
= GdipGetPropertyIdList(image
, prop_count
- 1, prop_id
);
3151 if (image_type
== ImageTypeMetafile
)
3152 expect(NotImplemented
, status
);
3154 expect(InvalidParameter
, status
);
3155 status
= GdipGetPropertyIdList(image
, prop_count
+ 1, prop_id
);
3156 if (image_type
== ImageTypeMetafile
)
3157 expect(NotImplemented
, status
);
3159 expect(InvalidParameter
, status
);
3160 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3161 if (image_type
== ImageTypeMetafile
)
3162 expect(NotImplemented
, status
);
3166 if (prop_count
!= 0)
3167 ok(td
[i
].prop_id
== prop_id
[0] || td
[i
].prop_id2
== prop_id
[0],
3168 " %u: expected property id %#x or %#x, got %#x\n",
3169 i
, td
[i
].prop_id
, td
[i
].prop_id2
, prop_id
[0]);
3174 status
= GdipGetPropertyItemSize(image
, prop_id
[0], &prop_size
);
3175 if (prop_count
== 0)
3176 expect(PropertyNotFound
, status
);
3181 assert(sizeof(item
) >= prop_size
);
3182 ok(prop_size
> sizeof(PropertyItem
), "%u: got too small prop_size %u\n",
3184 ok(td
[i
].prop_size
+ sizeof(PropertyItem
) == prop_size
||
3185 td
[i
].prop_size2
+ sizeof(PropertyItem
) == prop_size
,
3186 " %u: expected property size %u or %u, got %u\n",
3187 i
, td
[i
].prop_size
, td
[i
].prop_size2
, prop_size
);
3189 status
= GdipGetPropertyItem(image
, prop_id
[0], 0, &item
.data
);
3190 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3191 "%u: expected InvalidParameter, got %d\n", i
, status
);
3192 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
- 1, &item
.data
);
3193 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3194 "%u: expected InvalidParameter, got %d\n", i
, status
);
3195 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
+ 1, &item
.data
);
3196 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3197 "%u: expected InvalidParameter, got %d\n", i
, status
);
3198 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
, &item
.data
);
3200 ok(prop_id
[0] == item
.data
.id
,
3201 "%u: expected property id %#x, got %#x\n", i
, prop_id
[0], item
.data
.id
);
3205 GdipDisposeImage(image
);
3213 #define IFD_RATIONAL 5
3215 #define IFD_UNDEFINED 7
3216 #define IFD_SSHORT 8
3218 #define IFD_SRATIONAL 10
3219 #define IFD_FLOAT 11
3220 #define IFD_DOUBLE 12
3222 #ifndef PropertyTagTypeSByte
3223 #define PropertyTagTypeSByte 6
3224 #define PropertyTagTypeSShort 8
3225 #define PropertyTagTypeFloat 11
3226 #define PropertyTagTypeDouble 12
3229 static UINT
documented_type(UINT type
)
3233 case PropertyTagTypeSByte
: return PropertyTagTypeByte
;
3234 case PropertyTagTypeSShort
: return PropertyTagTypeShort
;
3235 case PropertyTagTypeFloat
: return PropertyTagTypeUndefined
;
3236 case PropertyTagTypeDouble
: return PropertyTagTypeUndefined
;
3237 default: return type
;
3241 #include "pshpack2.h"
3256 static const struct tiff_data
3261 USHORT number_of_entries
;
3262 struct IFD_entry entry
[40];
3264 struct IFD_rational xres
;
3266 struct IFD_rational srational_val
;
3271 struct IFD_rational rational
[3];
3275 #ifdef WORDS_BIGENDIAN
3281 FIELD_OFFSET(struct tiff_data
, number_of_entries
),
3284 { 0xff, IFD_SHORT
, 1, 0 }, /* SUBFILETYPE */
3285 { 0x100, IFD_LONG
, 1, 1 }, /* IMAGEWIDTH */
3286 { 0x101, IFD_LONG
, 1, 1 }, /* IMAGELENGTH */
3287 { 0x102, IFD_SHORT
, 1, 1 }, /* BITSPERSAMPLE */
3288 { 0x103, IFD_SHORT
, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
3289 { 0x106, IFD_SHORT
, 1, 1 }, /* PHOTOMETRIC */
3290 { 0x111, IFD_LONG
, 1, FIELD_OFFSET(struct tiff_data
, pixel_data
) }, /* STRIPOFFSETS */
3291 { 0x115, IFD_SHORT
, 1, 1 }, /* SAMPLESPERPIXEL */
3292 { 0x116, IFD_LONG
, 1, 1 }, /* ROWSPERSTRIP */
3293 { 0x117, IFD_LONG
, 1, 1 }, /* STRIPBYTECOUNT */
3294 { 0x11a, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3295 { 0x11b, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3296 { 0x128, IFD_SHORT
, 1, 2 }, /* RESOLUTIONUNIT */
3297 { 0xf001, IFD_BYTE
, 1, 0x11223344 },
3298 { 0xf002, IFD_BYTE
, 4, 0x11223344 },
3299 { 0xf003, IFD_SBYTE
, 1, 0x11223344 },
3300 { 0xf004, IFD_SSHORT
, 1, 0x11223344 },
3301 { 0xf005, IFD_SSHORT
, 2, 0x11223344 },
3302 { 0xf006, IFD_SLONG
, 1, 0x11223344 },
3303 { 0xf007, IFD_FLOAT
, 1, 0x11223344 },
3304 { 0xf008, IFD_DOUBLE
, 1, FIELD_OFFSET(struct tiff_data
, double_val
) },
3305 { 0xf009, IFD_SRATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, srational_val
) },
3306 { 0xf00a, IFD_BYTE
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3307 { 0xf00b, IFD_SSHORT
, 4, FIELD_OFFSET(struct tiff_data
, short_val
) },
3308 { 0xf00c, IFD_SLONG
, 2, FIELD_OFFSET(struct tiff_data
, long_val
) },
3309 { 0xf00e, IFD_ASCII
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3310 { 0xf00f, IFD_ASCII
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3311 { 0xf010, IFD_UNDEFINED
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3312 { 0xf011, IFD_UNDEFINED
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3313 /* Some gdiplus versions ignore these fields.
3314 { 0xf012, IFD_BYTE, 0, 0x11223344 },
3315 { 0xf013, IFD_SHORT, 0, 0x11223344 },
3316 { 0xf014, IFD_LONG, 0, 0x11223344 },
3317 { 0xf015, IFD_FLOAT, 0, 0x11223344 },*/
3318 { 0xf016, IFD_SRATIONAL
, 3, FIELD_OFFSET(struct tiff_data
, rational
) },
3319 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3320 { 0xf017, IFD_FLOAT
, 2, FIELD_OFFSET(struct tiff_data
, float_val
) },
3324 1234567890.0987654321,
3325 { 0x1a2b3c4d, 0x5a6b7c8d },
3327 { 0x0101, 0x0202, 0x0303, 0x0404 },
3328 { 0x11223344, 0x55667788 },
3329 { (FLOAT
)1234.5678, (FLOAT
)8765.4321 },
3330 { { 0x01020304, 0x05060708 }, { 0x10203040, 0x50607080 }, { 0x11223344, 0x55667788 } },
3331 { 0x11, 0x22, 0x33, 0 }
3333 #include "poppack.h"
3335 static void test_tiff_properties(void)
3337 static const struct test_data
3339 ULONG type
, id
, length
;
3340 const BYTE value
[24];
3343 { PropertyTagTypeShort
, 0xff, 2, { 0 } },
3344 { PropertyTagTypeLong
, 0x100, 4, { 1 } },
3345 { PropertyTagTypeLong
, 0x101, 4, { 1 } },
3346 { PropertyTagTypeShort
, 0x102, 2, { 1 } },
3347 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3348 { PropertyTagTypeShort
, 0x106, 2, { 1 } },
3349 { PropertyTagTypeLong
, 0x111, 4, { 0x44,0x02 } },
3350 { PropertyTagTypeShort
, 0x115, 2, { 1 } },
3351 { PropertyTagTypeLong
, 0x116, 4, { 1 } },
3352 { PropertyTagTypeLong
, 0x117, 4, { 1 } },
3353 { PropertyTagTypeRational
, 0x11a, 8, { 0x84,0x03,0,0,0x03 } },
3354 { PropertyTagTypeRational
, 0x11b, 8, { 0x84,0x03,0,0,0x03 } },
3355 { PropertyTagTypeShort
, 0x128, 2, { 2 } },
3356 { PropertyTagTypeByte
, 0xf001, 1, { 0x44 } },
3357 { PropertyTagTypeByte
, 0xf002, 4, { 0x44,0x33,0x22,0x11 } },
3358 { PropertyTagTypeSByte
, 0xf003, 1, { 0x44 } },
3359 { PropertyTagTypeSShort
, 0xf004, 2, { 0x44,0x33 } },
3360 { PropertyTagTypeSShort
, 0xf005, 4, { 0x44,0x33,0x22,0x11 } },
3361 { PropertyTagTypeSLONG
, 0xf006, 4, { 0x44,0x33,0x22,0x11 } },
3362 { PropertyTagTypeFloat
, 0xf007, 4, { 0x44,0x33,0x22,0x11 } },
3363 { PropertyTagTypeDouble
, 0xf008, 8, { 0x2c,0x52,0x86,0xb4,0x80,0x65,0xd2,0x41 } },
3364 { PropertyTagTypeSRational
, 0xf009, 8, { 0x4d, 0x3c, 0x2b, 0x1a, 0x8d, 0x7c, 0x6b, 0x5a } },
3365 { PropertyTagTypeByte
, 0xf00a, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3366 { PropertyTagTypeSShort
, 0xf00b, 8, { 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04 } },
3367 { PropertyTagTypeSLONG
, 0xf00c, 8, { 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3368 { PropertyTagTypeASCII
, 0xf00e, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3369 { PropertyTagTypeASCII
, 0xf00f, 5, { 'a','b','c','d' } },
3370 { PropertyTagTypeUndefined
, 0xf010, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3371 { PropertyTagTypeUndefined
, 0xf011, 4, { 'a','b','c','d' } },
3372 { PropertyTagTypeSRational
, 0xf016, 24,
3373 { 0x04,0x03,0x02,0x01,0x08,0x07,0x06,0x05,
3374 0x40,0x30,0x20,0x10,0x80,0x70,0x60,0x50,
3375 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3376 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3377 { PropertyTagTypeFloat
, 0xf017, 8, { 0x2b,0x52,0x9a,0x44,0xba,0xf5,0x08,0x46 } },
3382 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3384 PropertyItem
*prop_item
;
3386 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
));
3389 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3393 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3395 expect(1, dim_count
);
3397 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3399 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3401 frame_count
= 0xdeadbeef;
3402 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3404 expect(1, frame_count
);
3406 prop_count
= 0xdeadbeef;
3407 status
= GdipGetPropertyCount(image
, &prop_count
);
3409 ok(prop_count
== sizeof(td
)/sizeof(td
[0]) ||
3410 broken(prop_count
== sizeof(td
)/sizeof(td
[0]) - 1) /* Win7 SP0 */,
3411 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
3413 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3415 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3418 for (i
= 0; i
< prop_count
; i
++)
3420 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &prop_size
);
3422 if (status
!= Ok
) break;
3423 ok(prop_size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, prop_size
);
3425 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, prop_size
);
3426 status
= GdipGetPropertyItem(image
, prop_id
[i
], prop_size
, prop_item
);
3428 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3429 ok(td
[i
].type
== prop_item
->type
||
3430 /* Win7 stopped using proper but not documented types, and it
3431 looks broken since TypeFloat and TypeDouble now reported as
3432 TypeUndefined, and signed types reported as unsigned. */
3433 broken(prop_item
->type
== documented_type(td
[i
].type
)),
3434 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3435 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3436 prop_size
-= sizeof(*prop_item
);
3437 ok(prop_item
->length
== prop_size
, "%u: expected length %u, got %u\n", i
, prop_size
, prop_item
->length
);
3438 ok(td
[i
].length
== prop_item
->length
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_item
->length
+1) /* XP */,
3439 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3440 ok(td
[i
].length
== prop_size
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_size
+1) /* XP */,
3441 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_size
);
3442 if (td
[i
].length
== prop_item
->length
)
3444 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3445 ok(match
|| broken(td
[i
].length
<= 4 && !match
), "%u: data mismatch\n", i
);
3449 BYTE
*data
= prop_item
->value
;
3450 trace("id %#x:", prop_item
->id
);
3451 for (j
= 0; j
< prop_item
->length
; j
++)
3452 trace(" %02x", data
[j
]);
3456 HeapFree(GetProcessHeap(), 0, prop_item
);
3459 HeapFree(GetProcessHeap(), 0, prop_id
);
3461 GdipDisposeImage(image
);
3464 static void test_GdipGetAllPropertyItems(void)
3466 static const struct test_data
3468 ULONG type
, id
, length
;
3472 { PropertyTagTypeLong
, 0xfe, 4, { 0 } },
3473 { PropertyTagTypeShort
, 0x100, 2, { 1 } },
3474 { PropertyTagTypeShort
, 0x101, 2, { 1 } },
3475 { PropertyTagTypeShort
, 0x102, 6, { 8,0,8,0,8,0 } },
3476 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3477 { PropertyTagTypeShort
, 0x106, 2, { 2,0 } },
3478 { PropertyTagTypeASCII
, 0x10d, 27, "/home/meh/Desktop/test.tif" },
3479 { PropertyTagTypeLong
, 0x111, 4, { 8,0,0,0 } },
3480 { PropertyTagTypeShort
, 0x112, 2, { 1 } },
3481 { PropertyTagTypeShort
, 0x115, 2, { 3,0 } },
3482 { PropertyTagTypeShort
, 0x116, 2, { 0x40,0 } },
3483 { PropertyTagTypeLong
, 0x117, 4, { 3,0,0,0 } },
3484 { PropertyTagTypeRational
, 0x11a, 8, { 0,0,0,72,0,0,0,1 } },
3485 { PropertyTagTypeRational
, 0x11b, 8, { 0,0,0,72,0,0,0,1 } },
3486 { PropertyTagTypeShort
, 0x11c, 2, { 1 } },
3487 { PropertyTagTypeShort
, 0x128, 2, { 2 } }
3492 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3493 UINT total_size
, total_count
;
3495 PropertyItem
*prop_item
;
3496 const char *item_data
;
3498 image
= load_image(tiffimage
, sizeof(tiffimage
));
3499 ok(image
!= 0, "Failed to load TIFF image data\n");
3502 dim_count
= 0xdeadbeef;
3503 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3505 expect(1, dim_count
);
3507 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3509 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3511 frame_count
= 0xdeadbeef;
3512 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3514 expect(1, frame_count
);
3516 prop_count
= 0xdeadbeef;
3517 status
= GdipGetPropertyCount(image
, &prop_count
);
3519 ok(prop_count
== sizeof(td
)/sizeof(td
[0]),
3520 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
3522 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3524 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3528 for (i
= 0; i
< prop_count
; i
++)
3531 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
3533 if (status
!= Ok
) break;
3534 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
3538 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
3539 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
3541 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3542 ok(td
[i
].type
== prop_item
->type
,
3543 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3544 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3545 size
-= sizeof(*prop_item
);
3546 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
3547 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3548 if (td
[i
].length
== prop_item
->length
)
3550 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3551 ok(match
, "%u: data mismatch\n", i
);
3555 BYTE
*data
= prop_item
->value
;
3556 trace("id %#x:", prop_item
->id
);
3557 for (j
= 0; j
< prop_item
->length
; j
++)
3558 trace(" %02x", data
[j
]);
3562 HeapFree(GetProcessHeap(), 0, prop_item
);
3565 HeapFree(GetProcessHeap(), 0, prop_id
);
3567 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
3568 expect(InvalidParameter
, status
);
3569 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
3570 expect(InvalidParameter
, status
);
3571 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
3572 expect(InvalidParameter
, status
);
3573 status
= GdipGetPropertySize(image
, NULL
, NULL
);
3574 expect(InvalidParameter
, status
);
3575 total_size
= 0xdeadbeef;
3576 total_count
= 0xdeadbeef;
3577 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
3579 ok(prop_count
== total_count
,
3580 "expected total property count %u, got %u\n", prop_count
, total_count
);
3581 ok(prop_size
== total_size
,
3582 "expected total property size %u, got %u\n", prop_size
, total_size
);
3584 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
3586 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
3587 expect(InvalidParameter
, status
);
3588 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
3589 expect(InvalidParameter
, status
);
3590 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3591 expect(InvalidParameter
, status
);
3592 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3593 expect(InvalidParameter
, status
);
3594 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
3595 expect(InvalidParameter
, status
);
3596 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
3597 expect(InvalidParameter
, status
);
3598 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
3601 item_data
= (const char *)(prop_item
+ prop_count
);
3602 for (i
= 0; i
< prop_count
; i
++)
3604 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
3605 i
, item_data
, prop_item
[i
].value
);
3606 ok(td
[i
].type
== prop_item
[i
].type
,
3607 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
3608 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
3609 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
3610 if (td
[i
].length
== prop_item
[i
].length
)
3612 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
3613 ok(match
, "%u: data mismatch\n", i
);
3617 BYTE
*data
= prop_item
[i
].value
;
3618 trace("id %#x:", prop_item
[i
].id
);
3619 for (j
= 0; j
< prop_item
[i
].length
; j
++)
3620 trace(" %02x", data
[j
]);
3624 item_data
+= prop_item
[i
].length
;
3627 HeapFree(GetProcessHeap(), 0, prop_item
);
3629 GdipDisposeImage(image
);
3632 static void test_tiff_palette(void)
3643 ARGB
*entries
= palette
.pal
.Entries
;
3645 /* 1bpp TIFF without palette */
3646 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
));
3649 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3653 status
= GdipGetImagePixelFormat(image
, &format
);
3655 ok(format
== PixelFormat1bppIndexed
, "expected PixelFormat1bppIndexed, got %#x\n", format
);
3657 status
= GdipGetImagePaletteSize(image
, &size
);
3658 ok(status
== Ok
|| broken(status
== GenericError
), /* XP */
3659 "GdipGetImagePaletteSize error %d\n", status
);
3660 if (status
== GenericError
)
3662 GdipDisposeImage(image
);
3665 expect(sizeof(ColorPalette
) + sizeof(ARGB
), size
);
3667 status
= GdipGetImagePalette(image
, &palette
.pal
, size
);
3669 expect(0, palette
.pal
.Flags
);
3670 expect(2, palette
.pal
.Count
);
3671 if (palette
.pal
.Count
== 2)
3673 ok(entries
[0] == 0xff000000, "expected 0xff000000, got %#x\n", entries
[0]);
3674 ok(entries
[1] == 0xffffffff, "expected 0xffffffff, got %#x\n", entries
[1]);
3677 GdipDisposeImage(image
);
3680 static void test_bitmapbits(void)
3683 static const BYTE pixels_24
[48] =
3685 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3686 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3687 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3688 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0
3690 static const BYTE pixels_00
[48] =
3692 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3693 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3694 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3695 0,0,0, 0,0,0, 0,0,0, 0,0,0
3697 static const BYTE pixels_24_77
[64] =
3699 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3700 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3701 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3702 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3703 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3704 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3706 static const BYTE pixels_77
[64] =
3708 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3709 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3710 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3711 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3712 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3713 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3714 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3715 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3717 static const BYTE pixels_8
[16] =
3719 0x01,0,0x01,0,0x01,0,0x01,0,
3720 0x01,0,0x01,0,0x01,0,0x01,0
3722 static const BYTE pixels_8_77
[64] =
3724 0x01,0,0x01,0,0x01,0,0x01,0,
3725 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3726 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3727 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3728 0x01,0,0x01,0,0x01,0,0x01,0,
3729 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3730 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3731 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3733 static const BYTE pixels_1_77
[64] =
3735 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3736 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3737 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3738 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3739 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3740 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3741 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3742 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3744 static const BYTE pixels_1
[8] = {0xaa,0,0,0,0xaa,0,0,0};
3745 static const struct test_data
3752 const BYTE
*pixels_unlocked
;
3756 { PixelFormat24bppRGB
, 24, 0xfff0, 24, 48, pixels_24
, pixels_00
},
3758 { PixelFormat24bppRGB
, 24, 0, 24, 48, pixels_24
, pixels_00
},
3759 { PixelFormat24bppRGB
, 24, ImageLockModeRead
, 24, 48, pixels_24
, pixels_00
},
3760 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
3761 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
3762 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_24_77
, pixels_24
},
3763 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3764 { PixelFormat24bppRGB
, 24, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3766 { PixelFormat8bppIndexed
, 8, 0, 8, 16, pixels_8
, pixels_24
},
3767 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
, 8, 16, pixels_8
, pixels_24
},
3768 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
3769 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
3770 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_8_77
, pixels_24
},
3771 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3772 { PixelFormat8bppIndexed
, 8, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3774 { PixelFormat1bppIndexed
, 1, 0, 4, 8, pixels_1
, pixels_24
},
3775 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
, 4, 8, pixels_1
, pixels_24
},
3776 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
3777 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
3778 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_1_77
, pixels_24
},
3779 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3780 { PixelFormat1bppIndexed
, 1, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3792 ARGB
*entries
= palette
.pal
.Entries
;
3794 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
3796 BYTE pixels
[sizeof(pixels_24
)];
3797 memcpy(pixels
, pixels_24
, sizeof(pixels_24
));
3798 status
= GdipCreateBitmapFromScan0(8, 2, 24, PixelFormat24bppRGB
, pixels
, &bitmap
);
3801 /* associate known palette with pixel data */
3802 palette
.pal
.Flags
= PaletteFlagsGrayScale
;
3803 palette
.pal
.Count
= 2;
3804 entries
[0] = 0xff000000;
3805 entries
[1] = 0xffffffff;
3806 status
= GdipSetImagePalette((GpImage
*)bitmap
, &palette
.pal
);
3809 memset(&data
, 0xfe, sizeof(data
));
3810 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
3812 memset(buf
, 0x77, sizeof(buf
));
3816 status
= GdipBitmapLockBits(bitmap
, NULL
, td
[i
].mode
, td
[i
].format
, &data
);
3817 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* XP */, "%u: GdipBitmapLockBits error %d\n", i
, status
);
3820 GdipDisposeImage((GpImage
*)bitmap
);
3823 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
3824 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
3825 ok(td
[i
].stride
== data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].stride
, data
.Stride
);
3826 ok(td
[i
].format
== data
.PixelFormat
, "%u: expected %d, got %d\n", i
, td
[i
].format
, data
.PixelFormat
);
3827 ok(td
[i
].size
== data
.Height
* data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].size
, data
.Height
* data
.Stride
);
3828 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
3829 ok(data
.Scan0
== buf
, "%u: got wrong buffer\n", i
);
3830 if (td
[i
].size
== data
.Height
* data
.Stride
)
3832 UINT j
, match
, width_bytes
= (data
.Width
* td
[i
].bpp
) / 8;
3835 for (j
= 0; j
< data
.Height
; j
++)
3837 if (memcmp((const BYTE
*)data
.Scan0
+ j
* data
.Stride
, td
[i
].pixels
+ j
* data
.Stride
, width_bytes
) != 0)
3843 if ((td
[i
].mode
& (ImageLockModeRead
|ImageLockModeUserInputBuf
)) || td
[i
].format
== PixelFormat24bppRGB
)
3846 "%u: data should match\n", i
);
3849 BYTE
*bits
= data
.Scan0
;
3850 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
3851 for (j
= 0; j
< td
[i
].size
; j
++)
3852 trace(" %02x", bits
[j
]);
3857 ok(!match
, "%u: data shouldn't match\n", i
);
3859 memset(data
.Scan0
, 0, td
[i
].size
);
3862 status
= GdipBitmapUnlockBits(bitmap
, &data
);
3863 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
3865 memset(&data
, 0xfe, sizeof(data
));
3866 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
3867 ok(status
== Ok
, "%u: GdipBitmapLockBits error %d\n", i
, status
);
3868 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
3869 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
3870 ok(data
.Stride
== 24, "%u: expected 24, got %d\n", i
, data
.Stride
);
3871 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "%u: got wrong pixel format %d\n", i
, data
.PixelFormat
);
3872 ok(data
.Height
* data
.Stride
== 48, "%u: expected 48, got %d\n", i
, data
.Height
* data
.Stride
);
3873 if (data
.Height
* data
.Stride
== 48)
3875 int match
= memcmp(data
.Scan0
, td
[i
].pixels_unlocked
, 48) == 0;
3876 ok(match
, "%u: data should match\n", i
);
3880 BYTE
*bits
= data
.Scan0
;
3881 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
3882 for (j
= 0; j
< 48; j
++)
3883 trace(" %02x", bits
[j
]);
3888 status
= GdipBitmapUnlockBits(bitmap
, &data
);
3889 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
3891 status
= GdipDisposeImage((GpImage
*)bitmap
);
3896 static void test_DrawImage(void)
3898 BYTE black_1x1
[4] = { 0,0,0,0 };
3899 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
3900 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
3901 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
3902 0,0,0,0,0,0,0xff,0xff };
3909 GpGraphics
*graphics
;
3912 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
3914 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
3917 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
3919 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
3921 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
3923 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
3926 status
= GdipDrawImageI(graphics
, u1
.image
, 0, 0);
3929 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
3930 ok(match
, "data should match\n");
3933 UINT i
, size
= sizeof(white_2x2
);
3934 BYTE
*bits
= white_2x2
;
3935 for (i
= 0; i
< size
; i
++)
3936 trace(" %02x", bits
[i
]);
3940 status
= GdipDeleteGraphics(graphics
);
3942 status
= GdipDisposeImage(u1
.image
);
3944 status
= GdipDisposeImage(u2
.image
);
3948 static void test_GdipDrawImagePointRect(void)
3950 BYTE black_1x1
[4] = { 0,0,0,0 };
3951 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
3952 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
3953 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
3954 0,0,0,0,0,0,0xff,0xff };
3961 GpGraphics
*graphics
;
3964 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
3966 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
3969 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
3971 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
3973 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
3975 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
3978 status
= GdipDrawImagePointRectI(graphics
, u1
.image
, 0, 0, 0, 0, 1, 1, UnitPixel
);
3981 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
3982 ok(match
, "data should match\n");
3985 UINT i
, size
= sizeof(white_2x2
);
3986 BYTE
*bits
= white_2x2
;
3987 for (i
= 0; i
< size
; i
++)
3988 trace(" %02x", bits
[i
]);
3992 status
= GdipDeleteGraphics(graphics
);
3994 status
= GdipDisposeImage(u1
.image
);
3996 status
= GdipDisposeImage(u2
.image
);
4000 static void test_image_format(void)
4002 static const PixelFormat fmt
[] =
4004 PixelFormat1bppIndexed
, PixelFormat4bppIndexed
, PixelFormat8bppIndexed
,
4005 PixelFormat16bppGrayScale
, PixelFormat16bppRGB555
, PixelFormat16bppRGB565
,
4006 PixelFormat16bppARGB1555
, PixelFormat24bppRGB
, PixelFormat32bppRGB
,
4007 PixelFormat32bppARGB
, PixelFormat32bppPARGB
, PixelFormat48bppRGB
,
4008 PixelFormat64bppARGB
, PixelFormat64bppPARGB
, PixelFormat32bppCMYK
4019 for (i
= 0; i
< sizeof(fmt
)/sizeof(fmt
[0]); i
++)
4021 status
= GdipCreateBitmapFromScan0(1, 1, 0, fmt
[i
], NULL
, &bitmap
);
4022 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* before win7 */,
4023 "GdipCreateBitmapFromScan0 error %d\n", status
);
4024 if (status
!= Ok
) continue;
4026 status
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
4028 expect(fmt
[i
], format
);
4030 status
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
4031 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4032 todo_wine
expect(InvalidParameter
, status
);
4036 ret
= GetObjectW(hbitmap
, sizeof(bm
), &bm
);
4037 expect(sizeof(bm
), ret
);
4038 expect(0, bm
.bmType
);
4039 expect(1, bm
.bmWidth
);
4040 expect(1, bm
.bmHeight
);
4041 expect(4, bm
.bmWidthBytes
);
4042 expect(1, bm
.bmPlanes
);
4043 expect(32, bm
.bmBitsPixel
);
4044 DeleteObject(hbitmap
);
4047 status
= GdipGetImageThumbnail((GpImage
*)bitmap
, 0, 0, &thumb
, NULL
, NULL
);
4048 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4050 ok(status
== OutOfMemory
|| broken(status
== InvalidParameter
) /* before win7 */,
4051 "expected OutOfMemory, got %d\n", status
);
4055 status
= GdipGetImagePixelFormat(thumb
, &format
);
4057 ok(format
== PixelFormat32bppPARGB
|| broken(format
!= PixelFormat32bppPARGB
) /* before win7 */,
4058 "expected PixelFormat32bppPARGB, got %#x\n", format
);
4059 status
= GdipDisposeImage(thumb
);
4063 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4064 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4065 todo_wine
expect(InvalidParameter
, status
);
4069 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4073 status
= GdipDisposeImage((GpImage
*)bitmap
);
4078 static void test_DrawImage_scale(void)
4080 static const BYTE back_8x1
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
4081 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4082 static const BYTE image_080
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,
4083 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4084 static const BYTE image_100
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,
4085 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4086 static const BYTE image_120
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,
4087 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4088 static const BYTE image_150
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4089 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4090 static const BYTE image_180
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4091 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4092 static const BYTE image_200
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4093 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4094 static const BYTE image_250
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,
4095 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4096 static const BYTE image_120_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4097 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4098 static const BYTE image_150_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4099 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4100 static const BYTE image_200_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4101 0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40 };
4102 static const BYTE image_250_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4103 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4104 static const struct test_data
4107 PixelOffsetMode pixel_offset_mode
;
4112 { 0.8, PixelOffsetModeNone
, image_080
}, /* 0 */
4113 { 1.0, PixelOffsetModeNone
, image_100
},
4114 { 1.2, PixelOffsetModeNone
, image_120
},
4115 { 1.5, PixelOffsetModeNone
, image_150
},
4116 { 1.8, PixelOffsetModeNone
, image_180
},
4117 { 2.0, PixelOffsetModeNone
, image_200
},
4118 { 2.5, PixelOffsetModeNone
, image_250
},
4120 { 0.8, PixelOffsetModeHighSpeed
, image_080
}, /* 7 */
4121 { 1.0, PixelOffsetModeHighSpeed
, image_100
},
4122 { 1.2, PixelOffsetModeHighSpeed
, image_120
},
4123 { 1.5, PixelOffsetModeHighSpeed
, image_150
},
4124 { 1.8, PixelOffsetModeHighSpeed
, image_180
},
4125 { 2.0, PixelOffsetModeHighSpeed
, image_200
},
4126 { 2.5, PixelOffsetModeHighSpeed
, image_250
},
4128 { 0.8, PixelOffsetModeHalf
, image_080
}, /* 14 */
4129 { 1.0, PixelOffsetModeHalf
, image_100
},
4130 { 1.2, PixelOffsetModeHalf
, image_120_half
, TRUE
},
4131 { 1.5, PixelOffsetModeHalf
, image_150_half
, TRUE
},
4132 { 1.8, PixelOffsetModeHalf
, image_180
},
4133 { 2.0, PixelOffsetModeHalf
, image_200_half
, TRUE
},
4134 { 2.5, PixelOffsetModeHalf
, image_250_half
, TRUE
},
4136 { 0.8, PixelOffsetModeHighQuality
, image_080
}, /* 21 */
4137 { 1.0, PixelOffsetModeHighQuality
, image_100
},
4138 { 1.2, PixelOffsetModeHighQuality
, image_120_half
, TRUE
},
4139 { 1.5, PixelOffsetModeHighQuality
, image_150_half
, TRUE
},
4140 { 1.8, PixelOffsetModeHighQuality
, image_180
},
4141 { 2.0, PixelOffsetModeHighQuality
, image_200_half
, TRUE
},
4142 { 2.5, PixelOffsetModeHighQuality
, image_250_half
, TRUE
},
4144 BYTE src_2x1
[6] = { 0x80,0x80,0x80,0x80,0x80,0x80 };
4152 GpGraphics
*graphics
;
4156 status
= GdipCreateBitmapFromScan0(2, 1, 4, PixelFormat24bppRGB
, src_2x1
, &u1
.bitmap
);
4158 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4161 status
= GdipCreateBitmapFromScan0(8, 1, 24, PixelFormat24bppRGB
, dst_8x1
, &u2
.bitmap
);
4163 status
= GdipBitmapSetResolution(u2
.bitmap
, 100.0, 100.0);
4165 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4167 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4170 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
4172 status
= GdipSetPixelOffsetMode(graphics
, td
[i
].pixel_offset_mode
);
4175 status
= GdipCreateMatrix2(td
[i
].scale_x
, 0.0, 0.0, 1.0, 0.0, 0.0, &matrix
);
4177 status
= GdipSetWorldTransform(graphics
, matrix
);
4179 GdipDeleteMatrix(matrix
);
4181 memcpy(dst_8x1
, back_8x1
, sizeof(dst_8x1
));
4182 status
= GdipDrawImageI(graphics
, u1
.image
, 1, 0);
4185 match
= memcmp(dst_8x1
, td
[i
].image
, sizeof(dst_8x1
)) == 0;
4186 if (!match
&& td
[i
].todo
)
4187 todo_wine
ok(match
, "%d: data should match\n", i
);
4189 ok(match
, "%d: data should match\n", i
);
4192 UINT i
, size
= sizeof(dst_8x1
);
4193 const BYTE
*bits
= dst_8x1
;
4194 for (i
= 0; i
< size
; i
++)
4195 trace(" %02x", bits
[i
]);
4200 status
= GdipDeleteGraphics(graphics
);
4202 status
= GdipDisposeImage(u1
.image
);
4204 status
= GdipDisposeImage(u2
.image
);
4208 static const BYTE animatedgif
[] = {
4209 'G','I','F','8','9','a',0x01,0x00,0x01,0x00,0xA1,0x02,0x00,
4210 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
4211 /*0x21,0xFF,0x0B,'A','N','I','M','E','X','T','S','1','.','0',*/
4212 0x21,0xFF,0x0B,'N','E','T','S','C','A','P','E','2','.','0',
4213 0x03,0x01,0x05,0x00,0x00,
4214 0x21,0xFE,0x0C,'H','e','l','l','o',' ','W','o','r','l','d','!',0x00,
4215 0x21,0x01,0x0D,'a','n','i','m','a','t','i','o','n','.','g','i','f',0x00,
4216 0x21,0xF9,0x04,0xff,0x0A,0x00,0x08,0x00,
4217 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4218 0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,
4219 0x02,0x02,0x4C,0x01,0x00,
4220 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','1',0x00,
4221 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','1',0x00,
4222 0x21,0xF9,0x04,0x00,0x14,0x00,0x01,0x00,
4223 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4224 0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,
4225 0x02,0x02,0x44,0x01,0x00,
4226 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','2',0x00,
4227 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','2',0x00,0x3B
4230 static void test_gif_properties(void)
4232 static const struct test_data
4234 ULONG type
, id
, length
;
4235 const BYTE value
[13];
4238 { PropertyTagTypeLong
, PropertyTagFrameDelay
, 8, { 10,0,0,0,20,0,0,0 } },
4239 { PropertyTagTypeASCII
, PropertyTagExifUserComment
, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
4240 { PropertyTagTypeShort
, PropertyTagLoopCount
, 2, { 5,0 } },
4241 { PropertyTagTypeByte
, PropertyTagGlobalPalette
, 12, { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c } },
4242 { PropertyTagTypeByte
, PropertyTagIndexBackground
, 1, { 2 } },
4243 { PropertyTagTypeByte
, PropertyTagIndexTransparent
, 1, { 8 } }
4248 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
4249 UINT total_size
, total_count
;
4251 PropertyItem
*prop_item
;
4252 const char *item_data
;
4254 image
= load_image(animatedgif
, sizeof(animatedgif
));
4255 if (!image
) /* XP fails to load this GIF image */
4257 trace("Failed to load GIF image data\n");
4261 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
4263 expect(1, dim_count
);
4265 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
4267 expect_guid(&FrameDimensionTime
, &guid
, __LINE__
, FALSE
);
4269 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
4271 expect(2, frame_count
);
4273 status
= GdipImageSelectActiveFrame(image
, &guid
, 1);
4276 status
= GdipGetPropertyCount(image
, &prop_count
);
4278 ok(prop_count
== sizeof(td
)/sizeof(td
[0]) || broken(prop_count
== 1) /* before win7 */,
4279 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
4281 if (prop_count
!= sizeof(td
)/sizeof(td
[0]))
4283 GdipDisposeImage(image
);
4287 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
4289 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
4293 for (i
= 0; i
< prop_count
; i
++)
4296 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
4298 if (status
!= Ok
) break;
4299 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
4303 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
4304 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
4306 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
4307 ok(td
[i
].type
== prop_item
->type
,
4308 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
4309 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
4310 size
-= sizeof(*prop_item
);
4311 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
4312 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
4313 if (td
[i
].length
== prop_item
->length
)
4315 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
4316 ok(match
, "%u: data mismatch\n", i
);
4320 BYTE
*data
= prop_item
->value
;
4321 trace("id %#x:", prop_item
->id
);
4322 for (j
= 0; j
< prop_item
->length
; j
++)
4323 trace(" %02x", data
[j
]);
4327 HeapFree(GetProcessHeap(), 0, prop_item
);
4330 HeapFree(GetProcessHeap(), 0, prop_id
);
4332 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
4333 expect(InvalidParameter
, status
);
4334 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
4335 expect(InvalidParameter
, status
);
4336 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
4337 expect(InvalidParameter
, status
);
4338 status
= GdipGetPropertySize(image
, NULL
, NULL
);
4339 expect(InvalidParameter
, status
);
4340 total_size
= 0xdeadbeef;
4341 total_count
= 0xdeadbeef;
4342 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
4344 ok(prop_count
== total_count
,
4345 "expected total property count %u, got %u\n", prop_count
, total_count
);
4346 ok(prop_size
== total_size
,
4347 "expected total property size %u, got %u\n", prop_size
, total_size
);
4349 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
4351 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
4352 expect(InvalidParameter
, status
);
4353 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
4354 expect(InvalidParameter
, status
);
4355 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4356 expect(InvalidParameter
, status
);
4357 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4358 expect(InvalidParameter
, status
);
4359 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
4360 expect(InvalidParameter
, status
);
4361 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
4362 expect(InvalidParameter
, status
);
4363 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
4366 item_data
= (const char *)(prop_item
+ prop_count
);
4367 for (i
= 0; i
< prop_count
; i
++)
4369 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
4370 i
, item_data
, prop_item
[i
].value
);
4371 ok(td
[i
].type
== prop_item
[i
].type
,
4372 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
4373 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
4374 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
4375 if (td
[i
].length
== prop_item
[i
].length
)
4377 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
4378 ok(match
, "%u: data mismatch\n", i
);
4382 BYTE
*data
= prop_item
[i
].value
;
4383 trace("id %#x:", prop_item
[i
].id
);
4384 for (j
= 0; j
< prop_item
[i
].length
; j
++)
4385 trace(" %02x", data
[j
]);
4389 item_data
+= prop_item
[i
].length
;
4392 HeapFree(GetProcessHeap(), 0, prop_item
);
4394 GdipDisposeImage(image
);
4397 static void test_ARGB_conversion(void)
4399 BYTE argb
[8] = { 0x11,0x22,0x33,0x80, 0xff,0xff,0xff,0 };
4400 BYTE pargb
[8] = { 0x09,0x11,0x1a,0x80, 0,0,0,0 };
4401 BYTE rgb32_xp
[8] = { 0x11,0x22,0x33,0xff, 0xff,0xff,0xff,0xff };
4402 BYTE rgb24
[6] = { 0x11,0x22,0x33, 0xff,0xff,0xff };
4409 status
= GdipCreateBitmapFromScan0(2, 1, 8, PixelFormat32bppARGB
, argb
, &bitmap
);
4412 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4414 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4415 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4416 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4417 ok(data
.PixelFormat
== PixelFormat32bppPARGB
, "expected PixelFormat32bppPARGB, got %d\n", data
.PixelFormat
);
4418 match
= !memcmp(data
.Scan0
, pargb
, sizeof(pargb
));
4419 ok(match
, "bits don't match\n");
4423 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppPARGB
,
4424 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4426 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4429 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppRGB
, &data
);
4431 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4432 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4433 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4434 ok(data
.PixelFormat
== PixelFormat32bppRGB
, "expected PixelFormat32bppRGB, got %d\n", data
.PixelFormat
);
4435 match
= !memcmp(data
.Scan0
, argb
, sizeof(argb
)) ||
4436 !memcmp(data
.Scan0
, rgb32_xp
, sizeof(rgb32_xp
));
4437 ok(match
, "bits don't match\n");
4441 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppRGB
,
4442 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4444 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4447 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
4449 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4450 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4451 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4452 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "expected PixelFormat24bppRGB, got %d\n", data
.PixelFormat
);
4453 match
= !memcmp(data
.Scan0
, rgb24
, sizeof(rgb24
));
4454 ok(match
, "bits don't match\n");
4458 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat24bppRGB
,
4459 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4461 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4464 GdipDisposeImage((GpImage
*)bitmap
);
4468 static void test_CloneBitmapArea(void)
4471 GpBitmap
*bitmap
, *copy
;
4472 BitmapData data
, data2
;
4474 status
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB
, NULL
, &bitmap
);
4477 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
| ImageLockModeWrite
, PixelFormat24bppRGB
, &data
);
4480 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data2
);
4481 expect(WrongState
, status
);
4483 status
= GdipCloneBitmapAreaI(0, 0, 1, 1, PixelFormat24bppRGB
, bitmap
, ©
);
4486 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4489 GdipDisposeImage((GpImage
*)copy
);
4490 GdipDisposeImage((GpImage
*)bitmap
);
4495 struct GdiplusStartupInput gdiplusStartupInput
;
4496 ULONG_PTR gdiplusToken
;
4498 gdiplusStartupInput
.GdiplusVersion
= 1;
4499 gdiplusStartupInput
.DebugEventCallback
= NULL
;
4500 gdiplusStartupInput
.SuppressBackgroundThread
= 0;
4501 gdiplusStartupInput
.SuppressExternalCodecs
= 0;
4503 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, NULL
);
4505 test_CloneBitmapArea();
4506 test_ARGB_conversion();
4507 test_DrawImage_scale();
4508 test_image_format();
4510 test_GdipDrawImagePointRect();
4512 test_tiff_palette();
4513 test_GdipGetAllPropertyItems();
4514 test_tiff_properties();
4515 test_gif_properties();
4516 test_image_properties();
4519 test_GetImageDimension();
4520 test_GdipImageGetFrameDimensionsCount();
4521 test_LoadingImages();
4522 test_SavingImages();
4525 test_LockBits_UserBuf();
4526 test_GdipCreateBitmapFromHBITMAP();
4527 test_GdipGetImageFlags();
4528 test_GdipCloneImage();
4531 test_getrawformat();
4533 test_createfromwmf();
4535 test_createhbitmap();
4536 test_getthumbnail();
4541 test_multiframegif();
4547 GdiplusShutdown(gdiplusToken
);