2 * Unit test suite for images
4 * Copyright (C) 2007 Google (Evan Stade)
5 * Copyright (C) 2012 Dmitry Timoshkov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 #include "wine/test.h"
33 #define expect(expected, got) ok((got) == (expected), "Expected %d, got %d\n", (UINT)(expected), (UINT)(got))
34 #define expectf(expected, got) ok(fabs((expected) - (got)) < 0.0001, "Expected %f, got %f\n", (expected), (got))
36 static BOOL
color_match(ARGB c1
, ARGB c2
, BYTE max_diff
)
38 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
40 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
42 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
44 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
48 static void expect_guid(REFGUID expected
, REFGUID got
, int line
, BOOL todo
)
54 StringFromGUID2(got
, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]));
55 WideCharToMultiByte(CP_ACP
, 0, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]), buffer
, sizeof(buffer
), NULL
, NULL
);
56 StringFromGUID2(expected
, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]));
57 WideCharToMultiByte(CP_ACP
, 0, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]), buffer2
, sizeof(buffer2
), NULL
, NULL
);
59 todo_wine
ok_(__FILE__
, line
)(IsEqualGUID(expected
, got
), "Expected %s, got %s\n", buffer2
, buffer
);
61 ok_(__FILE__
, line
)(IsEqualGUID(expected
, got
), "Expected %s, got %s\n", buffer2
, buffer
);
64 static void expect_rawformat(REFGUID expected
, GpImage
*img
, int line
, BOOL todo
)
69 stat
= GdipGetImageRawFormat(img
, &raw
);
70 ok_(__FILE__
, line
)(stat
== Ok
, "GdipGetImageRawFormat failed with %d\n", stat
);
71 if(stat
!= Ok
) return;
72 expect_guid(expected
, &raw
, line
, todo
);
75 static void test_bufferrawformat(void* buff
, int size
, REFGUID expected
, int line
, BOOL todo
)
84 hglob
= GlobalAlloc (0, size
);
85 data
= GlobalLock (hglob
);
86 memcpy(data
, buff
, size
);
87 GlobalUnlock(hglob
); data
= NULL
;
89 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
90 ok_(__FILE__
, line
)(hres
== S_OK
, "Failed to create a stream\n");
91 if(hres
!= S_OK
) return;
93 stat
= GdipLoadImageFromStream(stream
, &img
);
94 ok_(__FILE__
, line
)(stat
== Ok
, "Failed to create a Bitmap\n");
96 IStream_Release(stream
);
100 expect_rawformat(expected
, img
, line
, todo
);
102 GdipDisposeImage(img
);
103 IStream_Release(stream
);
106 static void test_Scan0(void)
113 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
115 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
117 GdipDisposeImage((GpImage
*)bm
);
119 bm
= (GpBitmap
*)0xdeadbeef;
120 stat
= GdipCreateBitmapFromScan0(10, -10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
121 expect(InvalidParameter
, stat
);
122 ok( !bm
, "expected null bitmap\n" );
124 bm
= (GpBitmap
*)0xdeadbeef;
125 stat
= GdipCreateBitmapFromScan0(-10, 10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
126 expect(InvalidParameter
, stat
);
127 ok( !bm
, "expected null bitmap\n" );
129 bm
= (GpBitmap
*)0xdeadbeef;
130 stat
= GdipCreateBitmapFromScan0(10, 0, 10, PixelFormat24bppRGB
, NULL
, &bm
);
131 expect(InvalidParameter
, stat
);
132 ok( !bm
, "expected null bitmap\n" );
135 stat
= GdipCreateBitmapFromScan0(10, 10, 12, PixelFormat24bppRGB
, buff
, &bm
);
137 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
139 GdipDisposeImage((GpImage
*)bm
);
141 bm
= (GpBitmap
*) 0xdeadbeef;
142 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, buff
, &bm
);
143 expect(InvalidParameter
, stat
);
144 ok( !bm
, "expected null bitmap\n" );
146 bm
= (GpBitmap
*)0xdeadbeef;
147 stat
= GdipCreateBitmapFromScan0(10, 10, 0, PixelFormat24bppRGB
, buff
, &bm
);
148 expect(InvalidParameter
, stat
);
149 ok( bm
== (GpBitmap
*)0xdeadbeef, "expected deadbeef bitmap\n" );
152 stat
= GdipCreateBitmapFromScan0(10, 10, -8, PixelFormat24bppRGB
, buff
, &bm
);
154 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
156 GdipDisposeImage((GpImage
*)bm
);
158 bm
= (GpBitmap
*)0xdeadbeef;
159 stat
= GdipCreateBitmapFromScan0(10, 10, -10, PixelFormat24bppRGB
, buff
, &bm
);
160 expect(InvalidParameter
, stat
);
161 ok( !bm
, "expected null bitmap\n" );
164 static void test_FromGdiDib(void)
169 BYTE rbmi
[sizeof(BITMAPINFOHEADER
)+256*sizeof(RGBQUAD
)];
170 BITMAPINFO
*bmi
= (BITMAPINFO
*)rbmi
;
175 memset(rbmi
, 0, sizeof(rbmi
));
177 bmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
178 bmi
->bmiHeader
.biWidth
= 10;
179 bmi
->bmiHeader
.biHeight
= 10;
180 bmi
->bmiHeader
.biPlanes
= 1;
181 bmi
->bmiHeader
.biBitCount
= 32;
182 bmi
->bmiHeader
.biCompression
= BI_RGB
;
184 stat
= GdipCreateBitmapFromGdiDib(NULL
, buff
, &bm
);
185 expect(InvalidParameter
, stat
);
187 stat
= GdipCreateBitmapFromGdiDib(bmi
, NULL
, &bm
);
188 expect(InvalidParameter
, stat
);
190 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, NULL
);
191 expect(InvalidParameter
, stat
);
193 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
195 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
198 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
200 expect(PixelFormat32bppRGB
, format
);
202 GdipDisposeImage((GpImage
*)bm
);
205 bmi
->bmiHeader
.biBitCount
= 24;
206 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
208 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
211 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
213 expect(PixelFormat24bppRGB
, format
);
215 GdipDisposeImage((GpImage
*)bm
);
218 bmi
->bmiHeader
.biBitCount
= 16;
219 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
221 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
224 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
226 expect(PixelFormat16bppRGB555
, format
);
228 GdipDisposeImage((GpImage
*)bm
);
231 bmi
->bmiHeader
.biBitCount
= 8;
232 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
234 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
237 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
239 expect(PixelFormat8bppIndexed
, format
);
241 GdipDisposeImage((GpImage
*)bm
);
244 bmi
->bmiHeader
.biBitCount
= 4;
245 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
247 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
250 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
252 expect(PixelFormat4bppIndexed
, format
);
254 GdipDisposeImage((GpImage
*)bm
);
257 bmi
->bmiHeader
.biBitCount
= 1;
258 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
260 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
263 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
265 expect(PixelFormat1bppIndexed
, format
);
267 GdipDisposeImage((GpImage
*)bm
);
270 bmi
->bmiHeader
.biBitCount
= 0;
271 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
272 expect(InvalidParameter
, stat
);
275 static void test_GetImageDimension(void)
279 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
282 bm
= (GpBitmap
*)0xdeadbeef;
283 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
,NULL
, &bm
);
285 ok((GpBitmap
*)0xdeadbeef != bm
, "Expected bitmap to not be 0xdeadbeef\n");
286 ok(NULL
!= bm
, "Expected bitmap to not be NULL\n");
288 stat
= GdipGetImageDimension(NULL
,&w
,&h
);
289 expect(InvalidParameter
, stat
);
291 stat
= GdipGetImageDimension((GpImage
*)bm
,NULL
,&h
);
292 expect(InvalidParameter
, stat
);
294 stat
= GdipGetImageDimension((GpImage
*)bm
,&w
,NULL
);
295 expect(InvalidParameter
, stat
);
299 stat
= GdipGetImageDimension((GpImage
*)bm
,&w
,&h
);
303 GdipDisposeImage((GpImage
*)bm
);
306 static void test_GdipImageGetFrameDimensionsCount(void)
310 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
312 GUID dimension
= {0};
316 bm
= (GpBitmap
*)0xdeadbeef;
317 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
,NULL
, &bm
);
319 ok((GpBitmap
*)0xdeadbeef != bm
, "Expected bitmap to not be 0xdeadbeef\n");
320 ok(NULL
!= bm
, "Expected bitmap to not be NULL\n");
322 stat
= GdipImageGetFrameDimensionsCount(NULL
,&w
);
323 expect(InvalidParameter
, stat
);
325 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bm
,NULL
);
326 expect(InvalidParameter
, stat
);
329 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bm
,&w
);
333 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 1);
335 expect_guid(&FrameDimensionPage
, &dimension
, __LINE__
, FALSE
);
337 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 2);
338 expect(InvalidParameter
, stat
);
340 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 0);
341 expect(InvalidParameter
, stat
);
343 stat
= GdipImageGetFrameCount(NULL
, &dimension
, &count
);
344 expect(InvalidParameter
, stat
);
346 /* WinXP crashes on this test */
349 stat
= GdipImageGetFrameCount((GpImage
*)bm
, &dimension
, NULL
);
350 expect(InvalidParameter
, stat
);
353 stat
= GdipImageGetFrameCount((GpImage
*)bm
, NULL
, &count
);
357 stat
= GdipImageGetFrameCount((GpImage
*)bm
, &dimension
, &count
);
361 GdipBitmapSetPixel(bm
, 0, 0, 0xffffffff);
363 stat
= GdipImageSelectActiveFrame((GpImage
*)bm
, &dimension
, 0);
366 /* SelectActiveFrame has no effect on image data of memory bitmaps */
368 GdipBitmapGetPixel(bm
, 0, 0, &color
);
369 expect(0xffffffff, color
);
371 GdipDisposeImage((GpImage
*)bm
);
374 static void test_LoadingImages(void)
379 static const WCHAR nonexistentW
[] = {'n','o','n','e','x','i','s','t','e','n','t',0};
381 stat
= GdipCreateBitmapFromFile(0, 0);
382 expect(InvalidParameter
, stat
);
384 bm
= (GpBitmap
*)0xdeadbeef;
385 stat
= GdipCreateBitmapFromFile(0, &bm
);
386 expect(InvalidParameter
, stat
);
387 ok(bm
== (GpBitmap
*)0xdeadbeef, "returned %p\n", bm
);
389 bm
= (GpBitmap
*)0xdeadbeef;
390 stat
= GdipCreateBitmapFromFile(nonexistentW
, &bm
);
391 todo_wine
expect(InvalidParameter
, stat
);
392 ok(!bm
, "returned %p\n", bm
);
394 stat
= GdipLoadImageFromFile(0, 0);
395 expect(InvalidParameter
, stat
);
397 img
= (GpImage
*)0xdeadbeef;
398 stat
= GdipLoadImageFromFile(0, &img
);
399 expect(InvalidParameter
, stat
);
400 ok(img
== (GpImage
*)0xdeadbeef, "returned %p\n", img
);
402 img
= (GpImage
*)0xdeadbeef;
403 stat
= GdipLoadImageFromFile(nonexistentW
, &img
);
404 todo_wine
expect(OutOfMemory
, stat
);
405 ok(!img
, "returned %p\n", img
);
407 stat
= GdipLoadImageFromFileICM(0, 0);
408 expect(InvalidParameter
, stat
);
410 img
= (GpImage
*)0xdeadbeef;
411 stat
= GdipLoadImageFromFileICM(0, &img
);
412 expect(InvalidParameter
, stat
);
413 ok(img
== (GpImage
*)0xdeadbeef, "returned %p\n", img
);
415 img
= (GpImage
*)0xdeadbeef;
416 stat
= GdipLoadImageFromFileICM(nonexistentW
, &img
);
417 todo_wine
expect(OutOfMemory
, stat
);
418 ok(!img
, "returned %p\n", img
);
421 static void test_SavingImages(void)
427 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
429 ImageCodecInfo
*codecs
;
430 static const CHAR filenameA
[] = "a.bmp";
431 static const WCHAR filename
[] = { 'a','.','b','m','p',0 };
435 stat
= GdipSaveImageToFile(0, 0, 0, 0);
436 expect(InvalidParameter
, stat
);
439 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
445 stat
= GdipSaveImageToFile((GpImage
*)bm
, 0, 0, 0);
446 expect(InvalidParameter
, stat
);
448 stat
= GdipSaveImageToFile((GpImage
*)bm
, filename
, 0, 0);
449 expect(InvalidParameter
, stat
);
451 /* encoder tests should succeed -- already tested */
452 stat
= GdipGetImageEncodersSize(&n
, &s
);
453 if (stat
!= Ok
|| n
== 0) goto cleanup
;
455 codecs
= GdipAlloc(s
);
456 if (!codecs
) goto cleanup
;
458 stat
= GdipGetImageEncoders(n
, s
, codecs
);
459 if (stat
!= Ok
) goto cleanup
;
461 stat
= GdipSaveImageToFile((GpImage
*)bm
, filename
, &codecs
[0].Clsid
, 0);
464 GdipDisposeImage((GpImage
*)bm
);
467 /* re-load and check image stats */
468 stat
= GdipLoadImageFromFile(filename
, (GpImage
**)&bm
);
470 if (stat
!= Ok
) goto cleanup
;
472 stat
= GdipGetImageDimension((GpImage
*)bm
, &w
, &h
);
473 if (stat
!= Ok
) goto cleanup
;
481 GdipDisposeImage((GpImage
*)bm
);
482 ok(DeleteFileA(filenameA
), "Delete failed.\n");
485 static void test_encoders(void)
490 ImageCodecInfo
*codecs
;
494 static const CHAR bmp_format
[] = "BMP";
496 stat
= GdipGetImageEncodersSize(&n
, &s
);
499 codecs
= GdipAlloc(s
);
503 stat
= GdipGetImageEncoders(n
, s
, NULL
);
504 expect(GenericError
, stat
);
506 stat
= GdipGetImageEncoders(0, s
, codecs
);
507 expect(GenericError
, stat
);
509 stat
= GdipGetImageEncoders(n
, s
-1, codecs
);
510 expect(GenericError
, stat
);
512 stat
= GdipGetImageEncoders(n
, s
+1, codecs
);
513 expect(GenericError
, stat
);
515 stat
= GdipGetImageEncoders(n
, s
, codecs
);
519 for (i
= 0; i
< n
; i
++)
523 WideCharToMultiByte(CP_ACP
, 0, codecs
[i
].FormatDescription
, -1,
526 if (CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0,
528 bmp_format
, -1) == CSTR_EQUAL
) {
534 ok(FALSE
, "No BMP codec found.\n");
539 static void test_LockBits(void)
545 const INT WIDTH
= 10, HEIGHT
= 20;
550 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
558 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffc30000);
561 stat
= GdipBitmapSetPixel(bm
, 2, 8, 0xff480000);
565 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
569 expect(0xc3, ((BYTE
*)bd
.Scan0
)[2]);
570 expect(0x48, ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5]);
572 ((char*)bd
.Scan0
)[2] = 0xff;
574 stat
= GdipBitmapUnlockBits(bm
, &bd
);
578 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
580 expect(0xffff0000, color
);
582 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffc30000);
585 /* read-only, with NULL rect -> whole bitmap lock */
586 stat
= GdipBitmapLockBits(bm
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
588 expect(bd
.Width
, WIDTH
);
589 expect(bd
.Height
, HEIGHT
);
592 ((char*)bd
.Scan0
)[2 + 2*3 + 3*bd
.Stride
] = 0xff;
594 stat
= GdipBitmapUnlockBits(bm
, &bd
);
598 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
600 expect(0xffff0000, color
);
602 /* read-only, consecutive */
603 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
607 stat
= GdipBitmapUnlockBits(bm
, &bd
);
611 stat
= GdipDisposeImage((GpImage
*)bm
);
613 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
617 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
619 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
620 expect(WrongState
, stat
);
622 stat
= GdipBitmapUnlockBits(bm
, &bd
);
625 stat
= GdipDisposeImage((GpImage
*)bm
);
627 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
630 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffff0000);
633 stat
= GdipBitmapSetPixel(bm
, 2, 8, 0xffc30000);
636 /* write, no conversion */
637 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
641 /* all bits are readable, inside the rect or not */
642 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
643 expect(0xc3, ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5]);
645 stat
= GdipBitmapUnlockBits(bm
, &bd
);
649 /* read, conversion */
650 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat32bppARGB
, &bd
);
654 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
656 /* Areas outside the rectangle appear to be uninitialized */
657 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
659 ((BYTE
*)bd
.Scan0
)[2] = 0xc3;
661 stat
= GdipBitmapUnlockBits(bm
, &bd
);
665 /* writes do not work in read mode if there was a conversion */
666 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
668 expect(0xffff0000, color
);
670 /* read/write, conversion */
671 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeWrite
, PixelFormat32bppARGB
, &bd
);
675 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
676 ((BYTE
*)bd
.Scan0
)[1] = 0x88;
678 /* Areas outside the rectangle appear to be uninitialized */
679 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
681 stat
= GdipBitmapUnlockBits(bm
, &bd
);
685 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
687 expect(0xffff8800, color
);
689 /* write, conversion */
690 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat32bppARGB
, &bd
);
696 /* This is completely uninitialized. */
697 ok(0xff != ((BYTE
*)bd
.Scan0
)[2], "original image bits are readable\n");
698 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
701 /* Initialize the buffer so the unlock doesn't access undefined memory */
703 memset(((BYTE
*)bd
.Scan0
) + bd
.Stride
* y
, 0, 12);
705 ((BYTE
*)bd
.Scan0
)[0] = 0x12;
706 ((BYTE
*)bd
.Scan0
)[1] = 0x34;
707 ((BYTE
*)bd
.Scan0
)[2] = 0x56;
709 stat
= GdipBitmapUnlockBits(bm
, &bd
);
713 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
715 expect(0xff563412, color
);
717 stat
= GdipBitmapGetPixel(bm
, 2, 8, &color
);
719 expect(0xffc30000, color
);
721 stat
= GdipDisposeImage((GpImage
*)bm
);
723 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
726 /* write, no modification */
727 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
731 stat
= GdipBitmapUnlockBits(bm
, &bd
);
735 /* write, consecutive */
736 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
740 stat
= GdipBitmapUnlockBits(bm
, &bd
);
744 stat
= GdipDisposeImage((GpImage
*)bm
);
746 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
750 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
755 ((char*)bd
.Scan0
)[2] = 0xff;
757 stat
= GdipBitmapUnlockBits(bm
, &bd
);
761 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
763 expect(0xffff0000, color
);
765 stat
= GdipDisposeImage((GpImage
*)bm
);
769 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
771 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
773 stat
= GdipDisposeImage((GpImage
*)bm
);
777 static void test_LockBits_UserBuf(void)
783 const INT WIDTH
= 10, HEIGHT
= 20;
788 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat32bppARGB
, NULL
, &bm
);
791 memset(bits
, 0xaa, sizeof(bits
));
800 bd
.Stride
= WIDTH
* 4;
801 bd
.PixelFormat
= PixelFormat32bppARGB
;
802 bd
.Scan0
= &bits
[2+3*WIDTH
];
803 bd
.Reserved
= 0xaaaaaaaa;
806 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
809 expect(0xaaaaaaaa, bits
[0]);
810 expect(0, bits
[2+3*WIDTH
]);
812 bits
[2+3*WIDTH
] = 0xdeadbeef;
815 stat
= GdipBitmapUnlockBits(bm
, &bd
);
819 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
824 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
827 expect(0xdeadbeef, bits
[2+3*WIDTH
]);
828 bits
[2+3*WIDTH
] = 0x12345678;
831 stat
= GdipBitmapUnlockBits(bm
, &bd
);
835 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
837 expect(0x12345678, color
);
842 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeWrite
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
845 expect(0x12345678, bits
[2+3*WIDTH
]);
846 bits
[2+3*WIDTH
] = 0xdeadbeef;
849 stat
= GdipBitmapUnlockBits(bm
, &bd
);
853 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
855 expect(0xdeadbeef, color
);
857 stat
= GdipDisposeImage((GpImage
*)bm
);
861 struct BITMAPINFOWITHBITFIELDS
863 BITMAPINFOHEADER bmiHeader
;
867 union BITMAPINFOUNION
870 struct BITMAPINFOWITHBITFIELDS bf
;
873 static void test_GdipCreateBitmapFromHBITMAP(void)
875 GpBitmap
* gpbm
= NULL
;
877 HPALETTE hpal
= NULL
;
880 LOGPALETTE
* LogPal
= NULL
;
882 const REAL WIDTH1
= 5;
883 const REAL HEIGHT1
= 15;
884 const REAL WIDTH2
= 10;
885 const REAL HEIGHT2
= 20;
887 union BITMAPINFOUNION bmi
;
891 stat
= GdipCreateBitmapFromHBITMAP(NULL
, NULL
, NULL
);
892 expect(InvalidParameter
, stat
);
894 hbm
= CreateBitmap(WIDTH1
, HEIGHT1
, 1, 1, NULL
);
895 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, NULL
);
896 expect(InvalidParameter
, stat
);
898 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
900 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
901 expectf(WIDTH1
, width
);
902 expectf(HEIGHT1
, height
);
904 GdipDisposeImage((GpImage
*)gpbm
);
907 memset(buff
, 0, sizeof(buff
));
908 hbm
= CreateBitmap(WIDTH2
, HEIGHT2
, 1, 1, &buff
);
909 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
912 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)gpbm
, __LINE__
, FALSE
);
914 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
915 expectf(WIDTH2
, width
);
916 expectf(HEIGHT2
, height
);
918 GdipDisposeImage((GpImage
*)gpbm
);
921 hdc
= CreateCompatibleDC(0);
922 ok(hdc
!= NULL
, "CreateCompatibleDC failed\n");
923 bmi
.bi
.bmiHeader
.biSize
= sizeof(bmi
.bi
.bmiHeader
);
924 bmi
.bi
.bmiHeader
.biHeight
= HEIGHT1
;
925 bmi
.bi
.bmiHeader
.biWidth
= WIDTH1
;
926 bmi
.bi
.bmiHeader
.biBitCount
= 24;
927 bmi
.bi
.bmiHeader
.biPlanes
= 1;
928 bmi
.bi
.bmiHeader
.biCompression
= BI_RGB
;
929 bmi
.bi
.bmiHeader
.biClrUsed
= 0;
931 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
932 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
936 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
938 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
939 expectf(WIDTH1
, width
);
940 expectf(HEIGHT1
, height
);
943 /* test whether writing to the bitmap affects the original */
944 stat
= GdipBitmapSetPixel(gpbm
, 0, 0, 0xffffffff);
949 GdipDisposeImage((GpImage
*)gpbm
);
952 LogPal
= GdipAlloc(sizeof(LOGPALETTE
));
953 ok(LogPal
!= NULL
, "unable to allocate LOGPALETTE\n");
954 LogPal
->palVersion
= 0x300;
955 LogPal
->palNumEntries
= 1;
956 hpal
= CreatePalette(LogPal
);
957 ok(hpal
!= NULL
, "CreatePalette failed\n");
960 stat
= GdipCreateBitmapFromHBITMAP(hbm
, hpal
, &gpbm
);
964 GdipDisposeImage((GpImage
*)gpbm
);
969 /* 16-bit 555 dib, rgb */
970 bmi
.bi
.bmiHeader
.biBitCount
= 16;
971 bmi
.bi
.bmiHeader
.biCompression
= BI_RGB
;
973 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
974 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
978 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
983 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
985 expectf(WIDTH1
, width
);
986 expectf(HEIGHT1
, height
);
988 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
990 expect(PixelFormat16bppRGB555
, format
);
992 GdipDisposeImage((GpImage
*)gpbm
);
996 /* 16-bit 555 dib, with bitfields */
997 bmi
.bi
.bmiHeader
.biSize
= sizeof(bmi
);
998 bmi
.bi
.bmiHeader
.biCompression
= BI_BITFIELDS
;
999 bmi
.bf
.masks
[0] = 0x7c00;
1000 bmi
.bf
.masks
[1] = 0x3e0;
1001 bmi
.bf
.masks
[2] = 0x1f;
1003 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1004 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1008 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1013 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1015 expectf(WIDTH1
, width
);
1016 expectf(HEIGHT1
, height
);
1018 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1020 expect(PixelFormat16bppRGB555
, format
);
1022 GdipDisposeImage((GpImage
*)gpbm
);
1026 /* 16-bit 565 dib, with bitfields */
1027 bmi
.bf
.masks
[0] = 0xf800;
1028 bmi
.bf
.masks
[1] = 0x7e0;
1029 bmi
.bf
.masks
[2] = 0x1f;
1031 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1032 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1036 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1041 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1043 expectf(WIDTH1
, width
);
1044 expectf(HEIGHT1
, height
);
1046 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1048 expect(PixelFormat16bppRGB565
, format
);
1050 GdipDisposeImage((GpImage
*)gpbm
);
1057 static void test_GdipGetImageFlags(void)
1063 img
= (GpImage
*)0xdeadbeef;
1065 stat
= GdipGetImageFlags(NULL
, NULL
);
1066 expect(InvalidParameter
, stat
);
1068 stat
= GdipGetImageFlags(NULL
, &flags
);
1069 expect(InvalidParameter
, stat
);
1071 stat
= GdipGetImageFlags(img
, NULL
);
1072 expect(InvalidParameter
, stat
);
1074 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat1bppIndexed
, NULL
, (GpBitmap
**)&img
);
1076 stat
= GdipGetImageFlags(img
, &flags
);
1078 expect(ImageFlagsHasAlpha
, flags
);
1079 GdipDisposeImage(img
);
1081 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat4bppIndexed
, NULL
, (GpBitmap
**)&img
);
1083 stat
= GdipGetImageFlags(img
, &flags
);
1085 expect(ImageFlagsHasAlpha
, flags
);
1086 GdipDisposeImage(img
);
1088 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat8bppIndexed
, NULL
, (GpBitmap
**)&img
);
1090 stat
= GdipGetImageFlags(img
, &flags
);
1092 expect(ImageFlagsHasAlpha
, flags
);
1093 GdipDisposeImage(img
);
1095 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppGrayScale
, NULL
, (GpBitmap
**)&img
);
1097 stat
= GdipGetImageFlags(img
, &flags
);
1099 expect(ImageFlagsNone
, flags
);
1100 GdipDisposeImage(img
);
1102 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB555
, NULL
, (GpBitmap
**)&img
);
1104 stat
= GdipGetImageFlags(img
, &flags
);
1106 expect(ImageFlagsNone
, flags
);
1107 GdipDisposeImage(img
);
1109 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB565
, NULL
, (GpBitmap
**)&img
);
1111 stat
= GdipGetImageFlags(img
, &flags
);
1113 expect(ImageFlagsNone
, flags
);
1114 GdipDisposeImage(img
);
1116 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppARGB1555
, NULL
, (GpBitmap
**)&img
);
1118 stat
= GdipGetImageFlags(img
, &flags
);
1120 expect(ImageFlagsHasAlpha
, flags
);
1121 GdipDisposeImage(img
);
1123 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, NULL
, (GpBitmap
**)&img
);
1125 stat
= GdipGetImageFlags(img
, &flags
);
1127 expect(ImageFlagsNone
, flags
);
1128 GdipDisposeImage(img
);
1130 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&img
);
1132 stat
= GdipGetImageFlags(img
, &flags
);
1134 expect(ImageFlagsNone
, flags
);
1135 GdipDisposeImage(img
);
1137 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppARGB
, NULL
, (GpBitmap
**)&img
);
1139 stat
= GdipGetImageFlags(img
, &flags
);
1141 expect(ImageFlagsHasAlpha
, flags
);
1142 GdipDisposeImage(img
);
1144 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppPARGB
, NULL
, (GpBitmap
**)&img
);
1146 stat
= GdipGetImageFlags(img
, &flags
);
1148 expect(ImageFlagsHasAlpha
, flags
);
1149 GdipDisposeImage(img
);
1151 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat48bppRGB
, NULL
, (GpBitmap
**)&img
);
1155 stat
= GdipGetImageFlags(img
, &flags
);
1157 expect(ImageFlagsNone
, flags
);
1158 GdipDisposeImage(img
);
1161 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB
, NULL
, (GpBitmap
**)&img
);
1166 stat
= GdipGetImageFlags(img
, &flags
);
1168 expect(ImageFlagsHasAlpha
, flags
);
1169 GdipDisposeImage(img
);
1172 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB
, NULL
, (GpBitmap
**)&img
);
1177 stat
= GdipGetImageFlags(img
, &flags
);
1179 expect(ImageFlagsHasAlpha
, flags
);
1180 GdipDisposeImage(img
);
1184 static void test_GdipCloneImage(void)
1190 GpImage
*image_src
, *image_dest
= NULL
;
1191 const INT WIDTH
= 10, HEIGHT
= 20;
1193 /* Create an image, clone it, delete the original, make sure the copy works */
1194 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
1196 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bm
, __LINE__
, FALSE
);
1198 image_src
= ((GpImage
*)bm
);
1199 stat
= GdipCloneImage(image_src
, &image_dest
);
1201 expect_rawformat(&ImageFormatMemoryBMP
, image_dest
, __LINE__
, FALSE
);
1203 stat
= GdipDisposeImage((GpImage
*)bm
);
1205 stat
= GdipGetImageBounds(image_dest
, &rectF
, &unit
);
1208 /* Treat FP values carefully */
1209 expectf((REAL
)WIDTH
, rectF
.Width
);
1210 expectf((REAL
)HEIGHT
, rectF
.Height
);
1212 stat
= GdipDisposeImage(image_dest
);
1216 static void test_testcontrol(void)
1222 stat
= GdipTestControl(TestControlGetBuildNumber
, ¶m
);
1224 ok(param
!= 0, "Build number expected, got %u\n", param
);
1227 static void test_fromhicon(void)
1229 static const BYTE bmp_bits
[1024];
1230 HBITMAP hbmMask
, hbmColor
;
1234 GpBitmap
*bitmap
= NULL
;
1240 stat
= GdipCreateBitmapFromHICON(NULL
, NULL
);
1241 expect(InvalidParameter
, stat
);
1242 stat
= GdipCreateBitmapFromHICON(NULL
, &bitmap
);
1243 expect(InvalidParameter
, stat
);
1245 /* color icon 1 bit */
1246 hbmMask
= CreateBitmap(16, 16, 1, 1, bmp_bits
);
1247 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1248 hbmColor
= CreateBitmap(16, 16, 1, 1, bmp_bits
);
1249 ok(hbmColor
!= 0, "CreateBitmap failed\n");
1253 info
.hbmMask
= hbmMask
;
1254 info
.hbmColor
= hbmColor
;
1255 hIcon
= CreateIconIndirect(&info
);
1256 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
1257 DeleteObject(hbmMask
);
1258 DeleteObject(hbmColor
);
1260 stat
= GdipCreateBitmapFromHICON(hIcon
, &bitmap
);
1262 broken(stat
== InvalidParameter
), /* Win98 */
1263 "Expected Ok, got %.8x\n", stat
);
1265 /* check attributes */
1266 stat
= GdipGetImageHeight((GpImage
*)bitmap
, &dim
);
1269 stat
= GdipGetImageWidth((GpImage
*)bitmap
, &dim
);
1272 stat
= GdipGetImageType((GpImage
*)bitmap
, &type
);
1274 expect(ImageTypeBitmap
, type
);
1275 stat
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
1277 expect(PixelFormat32bppARGB
, format
);
1279 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bitmap
, __LINE__
, FALSE
);
1280 GdipDisposeImage((GpImage
*)bitmap
);
1284 /* color icon 8 bpp */
1285 hbmMask
= CreateBitmap(16, 16, 1, 8, bmp_bits
);
1286 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1287 hbmColor
= CreateBitmap(16, 16, 1, 8, bmp_bits
);
1288 ok(hbmColor
!= 0, "CreateBitmap failed\n");
1292 info
.hbmMask
= hbmMask
;
1293 info
.hbmColor
= hbmColor
;
1294 hIcon
= CreateIconIndirect(&info
);
1295 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
1296 DeleteObject(hbmMask
);
1297 DeleteObject(hbmColor
);
1299 stat
= GdipCreateBitmapFromHICON(hIcon
, &bitmap
);
1302 /* check attributes */
1303 stat
= GdipGetImageHeight((GpImage
*)bitmap
, &dim
);
1306 stat
= GdipGetImageWidth((GpImage
*)bitmap
, &dim
);
1309 stat
= GdipGetImageType((GpImage
*)bitmap
, &type
);
1311 expect(ImageTypeBitmap
, type
);
1312 stat
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
1314 expect(PixelFormat32bppARGB
, format
);
1316 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bitmap
, __LINE__
, FALSE
);
1317 GdipDisposeImage((GpImage
*)bitmap
);
1323 static const unsigned char pngimage
[285] = {
1324 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
1325 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
1326 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
1327 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
1328 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
1329 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
1330 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
1333 static const unsigned char gifimage
[35] = {
1334 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
1335 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
1338 /* 1x1 pixel transparent gif */
1339 static const unsigned char transparentgif
[] = {
1340 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,
1341 0x00,0x00,0x00,0x21,0xf9,0x04,0x01,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,
1342 0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
1345 static const unsigned char bmpimage
[66] = {
1346 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
1347 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
1348 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
1349 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
1353 static const unsigned char jpgimage
[285] = {
1354 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
1355 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
1356 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
1357 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
1358 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
1359 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
1360 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
1361 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1362 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1363 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
1364 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
1365 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1366 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
1367 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
1368 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1369 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
1370 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
1371 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
1373 /* 1x1 pixel tiff */
1374 static const unsigned char tiffimage
[] = {
1375 0x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00,
1376 0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00,
1377 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1378 0x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01,
1379 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00,
1380 0x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00,
1381 0x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01,
1382 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00,
1383 0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00,
1384 0x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01,
1385 0x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00,
1386 0x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1387 0x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
1388 0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65,
1389 0x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74,
1390 0x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,
1393 /* 320x320 twip wmf */
1394 static const unsigned char wmfimage
[180] = {
1395 0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05,
1396 0x00,0x00,0x00,0x00,0xb1,0x52,0x01,0x00,0x09,0x00,0x00,0x03,0x4f,0x00,0x00,0x00,
1397 0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0b,0x02,0x00,0x00,
1398 0x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x02,0x40,0x01,0x40,0x01,0x04,0x00,0x00,0x00,
1399 0x02,0x01,0x01,0x00,0x04,0x00,0x00,0x00,0x04,0x01,0x0d,0x00,0x08,0x00,0x00,0x00,
1400 0xfa,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
1401 0x2d,0x01,0x00,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,0x01,0x00,0x00,0x00,0x00,0x00,
1402 0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x01,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,
1403 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x02,0x00,
1404 0x07,0x00,0x00,0x00,0x1b,0x04,0x40,0x01,0x40,0x01,0x00,0x00,0x00,0x00,0x04,0x00,
1405 0x00,0x00,0xf0,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0xf0,0x01,0x01,0x00,0x03,0x00,
1408 static void test_getrawformat(void)
1410 test_bufferrawformat((void*)pngimage
, sizeof(pngimage
), &ImageFormatPNG
, __LINE__
, FALSE
);
1411 test_bufferrawformat((void*)gifimage
, sizeof(gifimage
), &ImageFormatGIF
, __LINE__
, FALSE
);
1412 test_bufferrawformat((void*)bmpimage
, sizeof(bmpimage
), &ImageFormatBMP
, __LINE__
, FALSE
);
1413 test_bufferrawformat((void*)jpgimage
, sizeof(jpgimage
), &ImageFormatJPEG
, __LINE__
, FALSE
);
1414 test_bufferrawformat((void*)tiffimage
, sizeof(tiffimage
), &ImageFormatTIFF
, __LINE__
, FALSE
);
1415 test_bufferrawformat((void*)wmfimage
, sizeof(wmfimage
), &ImageFormatWMF
, __LINE__
, FALSE
);
1418 static void test_loadwmf(void)
1429 MetafileHeader header
;
1431 hglob
= GlobalAlloc (0, sizeof(wmfimage
));
1432 data
= GlobalLock (hglob
);
1433 memcpy(data
, wmfimage
, sizeof(wmfimage
));
1434 GlobalUnlock(hglob
); data
= NULL
;
1436 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
1437 ok(hres
== S_OK
, "Failed to create a stream\n");
1438 if(hres
!= S_OK
) return;
1440 stat
= GdipLoadImageFromStream(stream
, &img
);
1441 ok(stat
== Ok
, "Failed to create a Bitmap\n");
1443 IStream_Release(stream
);
1447 IStream_Release(stream
);
1449 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1451 todo_wine
expect(UnitPixel
, unit
);
1452 expectf(0.0, bounds
.X
);
1453 expectf(0.0, bounds
.Y
);
1454 todo_wine
expectf(320.0, bounds
.Width
);
1455 todo_wine
expectf(320.0, bounds
.Height
);
1457 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1459 todo_wine
expectf(1440.0, res
);
1461 stat
= GdipGetImageVerticalResolution(img
, &res
);
1463 todo_wine
expectf(1440.0, res
);
1465 memset(&header
, 0, sizeof(header
));
1466 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1470 todo_wine
expect(MetafileTypeWmfPlaceable
, header
.Type
);
1471 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1472 todo_wine
expect(0x300, header
.Version
);
1473 expect(0, header
.EmfPlusFlags
);
1474 todo_wine
expectf(1440.0, header
.DpiX
);
1475 todo_wine
expectf(1440.0, header
.DpiY
);
1476 expect(0, header
.X
);
1477 expect(0, header
.Y
);
1478 todo_wine
expect(320, header
.Width
);
1479 todo_wine
expect(320, header
.Height
);
1480 todo_wine
expect(1, U(header
).WmfHeader
.mtType
);
1481 expect(0, header
.EmfPlusHeaderSize
);
1482 expect(0, header
.LogicalDpiX
);
1483 expect(0, header
.LogicalDpiY
);
1486 GdipDisposeImage(img
);
1489 static void test_createfromwmf(void)
1497 MetafileHeader header
;
1499 hwmf
= SetMetaFileBitsEx(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
),
1500 wmfimage
+sizeof(WmfPlaceableFileHeader
));
1501 ok(hwmf
!= 0, "SetMetaFileBitsEx failed\n");
1503 stat
= GdipCreateMetafileFromWmf(hwmf
, TRUE
,
1504 (WmfPlaceableFileHeader
*)wmfimage
, (GpMetafile
**)&img
);
1507 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1509 expect(UnitPixel
, unit
);
1510 expectf(0.0, bounds
.X
);
1511 expectf(0.0, bounds
.Y
);
1512 expectf(320.0, bounds
.Width
);
1513 expectf(320.0, bounds
.Height
);
1515 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1517 expectf(1440.0, res
);
1519 stat
= GdipGetImageVerticalResolution(img
, &res
);
1521 expectf(1440.0, res
);
1523 memset(&header
, 0, sizeof(header
));
1524 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1528 todo_wine
expect(MetafileTypeWmfPlaceable
, header
.Type
);
1529 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1530 todo_wine
expect(0x300, header
.Version
);
1531 expect(0, header
.EmfPlusFlags
);
1532 todo_wine
expectf(1440.0, header
.DpiX
);
1533 todo_wine
expectf(1440.0, header
.DpiY
);
1534 expect(0, header
.X
);
1535 expect(0, header
.Y
);
1536 todo_wine
expect(320, header
.Width
);
1537 todo_wine
expect(320, header
.Height
);
1538 todo_wine
expect(1, U(header
).WmfHeader
.mtType
);
1539 expect(0, header
.EmfPlusHeaderSize
);
1540 expect(0, header
.LogicalDpiX
);
1541 expect(0, header
.LogicalDpiY
);
1544 GdipDisposeImage(img
);
1547 static void test_createfromwmf_noplaceable(void)
1553 hwmf
= SetMetaFileBitsEx(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
),
1554 wmfimage
+sizeof(WmfPlaceableFileHeader
));
1555 ok(hwmf
!= 0, "SetMetaFileBitsEx failed\n");
1557 stat
= GdipCreateMetafileFromWmf(hwmf
, TRUE
, NULL
, (GpMetafile
**)&img
);
1560 GdipDisposeImage(img
);
1563 static void test_resolution(void)
1567 GpGraphics
*graphics
;
1570 int screenxres
, screenyres
;
1573 stat
= GdipCreateBitmapFromScan0(1, 1, 32, PixelFormat24bppRGB
, NULL
, &bitmap
);
1576 /* test invalid values */
1577 stat
= GdipGetImageHorizontalResolution(NULL
, &res
);
1578 expect(InvalidParameter
, stat
);
1580 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, NULL
);
1581 expect(InvalidParameter
, stat
);
1583 stat
= GdipGetImageVerticalResolution(NULL
, &res
);
1584 expect(InvalidParameter
, stat
);
1586 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, NULL
);
1587 expect(InvalidParameter
, stat
);
1589 stat
= GdipBitmapSetResolution(NULL
, 96.0, 96.0);
1590 expect(InvalidParameter
, stat
);
1592 stat
= GdipBitmapSetResolution(bitmap
, 0.0, 0.0);
1593 expect(InvalidParameter
, stat
);
1595 /* defaults to screen resolution */
1596 screendc
= GetDC(0);
1598 screenxres
= GetDeviceCaps(screendc
, LOGPIXELSX
);
1599 screenyres
= GetDeviceCaps(screendc
, LOGPIXELSY
);
1601 ReleaseDC(0, screendc
);
1603 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1605 expectf((REAL
)screenxres
, res
);
1607 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1609 expectf((REAL
)screenyres
, res
);
1611 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1613 stat
= GdipGetDpiX(graphics
, &res
);
1615 expectf((REAL
)screenxres
, res
);
1616 stat
= GdipGetDpiY(graphics
, &res
);
1618 expectf((REAL
)screenyres
, res
);
1620 /* test changing the resolution */
1621 stat
= GdipBitmapSetResolution(bitmap
, screenxres
*2.0, screenyres
*3.0);
1624 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1626 expectf(screenxres
*2.0, res
);
1628 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1630 expectf(screenyres
*3.0, res
);
1632 stat
= GdipGetDpiX(graphics
, &res
);
1634 expectf((REAL
)screenxres
, res
);
1635 stat
= GdipGetDpiY(graphics
, &res
);
1637 expectf((REAL
)screenyres
, res
);
1639 stat
= GdipDeleteGraphics(graphics
);
1642 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1644 stat
= GdipGetDpiX(graphics
, &res
);
1646 expectf(screenxres
*2.0, res
);
1647 stat
= GdipGetDpiY(graphics
, &res
);
1649 expectf(screenyres
*3.0, res
);
1650 stat
= GdipDeleteGraphics(graphics
);
1653 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1657 static void test_createhbitmap(void)
1661 HBITMAP hbitmap
, oldhbitmap
;
1668 memset(bits
, 0x68, 640);
1671 stat
= GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB
, bits
, &bitmap
);
1674 /* test NULL values */
1675 stat
= GdipCreateHBITMAPFromBitmap(NULL
, &hbitmap
, 0);
1676 expect(InvalidParameter
, stat
);
1678 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, NULL
, 0);
1679 expect(InvalidParameter
, stat
);
1681 /* create HBITMAP */
1682 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1687 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1688 expect(sizeof(BITMAP
), ret
);
1690 expect(0, bm
.bmType
);
1691 expect(10, bm
.bmWidth
);
1692 expect(20, bm
.bmHeight
);
1693 expect(40, bm
.bmWidthBytes
);
1694 expect(1, bm
.bmPlanes
);
1695 expect(32, bm
.bmBitsPixel
);
1696 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1700 DWORD val
= *(DWORD
*)bm
.bmBits
;
1701 ok(val
== 0xff686868, "got %x, expected 0xff686868\n", val
);
1704 hdc
= CreateCompatibleDC(NULL
);
1706 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1707 pixel
= GetPixel(hdc
, 5, 5);
1708 SelectObject(hdc
, oldhbitmap
);
1712 expect(0x686868, pixel
);
1714 DeleteObject(hbitmap
);
1717 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1720 /* make (1,0) have no alpha and (2,0) a different blue value. */
1724 /* create alpha Bitmap */
1725 stat
= GdipCreateBitmapFromScan0(8, 20, 32, PixelFormat32bppARGB
, bits
, &bitmap
);
1728 /* create HBITMAP */
1729 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1734 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1735 expect(sizeof(BITMAP
), ret
);
1737 expect(0, bm
.bmType
);
1738 expect(8, bm
.bmWidth
);
1739 expect(20, bm
.bmHeight
);
1740 expect(32, bm
.bmWidthBytes
);
1741 expect(1, bm
.bmPlanes
);
1742 expect(32, bm
.bmBitsPixel
);
1743 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1747 DWORD val
= *(DWORD
*)bm
.bmBits
;
1748 ok(val
== 0x682a2a2a, "got %x, expected 0x682a2a2a\n", val
);
1749 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1750 ok(val
== 0x0, "got %x, expected 0x682a2a2a\n", val
);
1753 hdc
= CreateCompatibleDC(NULL
);
1755 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1756 pixel
= GetPixel(hdc
, 5, 5);
1757 expect(0x2a2a2a, pixel
);
1758 pixel
= GetPixel(hdc
, 1, 0);
1761 SelectObject(hdc
, oldhbitmap
);
1766 DeleteObject(hbitmap
);
1769 /* create HBITMAP with bkgnd colour */
1770 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0xff00ff);
1775 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1776 expect(sizeof(BITMAP
), ret
);
1778 expect(0, bm
.bmType
);
1779 expect(8, bm
.bmWidth
);
1780 expect(20, bm
.bmHeight
);
1781 expect(32, bm
.bmWidthBytes
);
1782 expect(1, bm
.bmPlanes
);
1783 expect(32, bm
.bmBitsPixel
);
1784 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1788 DWORD val
= *(DWORD
*)bm
.bmBits
;
1789 ok(val
== 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val
);
1790 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1791 ok(val
== 0xff00ff, "got %x, expected 0x682a2a2a\n", val
);
1794 hdc
= CreateCompatibleDC(NULL
);
1796 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1797 pixel
= GetPixel(hdc
, 5, 5);
1798 expect(0xc12ac1, pixel
);
1799 pixel
= GetPixel(hdc
, 1, 0);
1800 expect(0xff00ff, pixel
);
1801 pixel
= GetPixel(hdc
, 2, 0);
1802 expect(0xb12ac1, pixel
);
1804 SelectObject(hdc
, oldhbitmap
);
1806 DeleteObject(hbitmap
);
1809 /* create HBITMAP with bkgnd colour with alpha and show it behaves with no alpha. */
1810 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0x80ff00ff);
1815 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1816 expect(sizeof(BITMAP
), ret
);
1818 expect(0, bm
.bmType
);
1819 expect(8, bm
.bmWidth
);
1820 expect(20, bm
.bmHeight
);
1821 expect(32, bm
.bmWidthBytes
);
1822 expect(1, bm
.bmPlanes
);
1823 expect(32, bm
.bmBitsPixel
);
1824 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1828 DWORD val
= *(DWORD
*)bm
.bmBits
;
1829 ok(val
== 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val
);
1830 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1831 ok(val
== 0xff00ff, "got %x, expected 0x682a2a2a\n", val
);
1834 hdc
= CreateCompatibleDC(NULL
);
1836 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1837 pixel
= GetPixel(hdc
, 5, 5);
1838 expect(0xc12ac1, pixel
);
1839 pixel
= GetPixel(hdc
, 1, 0);
1840 expect(0xff00ff, pixel
);
1841 pixel
= GetPixel(hdc
, 2, 0);
1842 expect(0xb12ac1, pixel
);
1844 SelectObject(hdc
, oldhbitmap
);
1846 DeleteObject(hbitmap
);
1849 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1853 static void test_getthumbnail(void)
1856 GpImage
*bitmap1
, *bitmap2
;
1859 stat
= GdipGetImageThumbnail(NULL
, 0, 0, &bitmap2
, NULL
, NULL
);
1860 expect(InvalidParameter
, stat
);
1862 stat
= GdipCreateBitmapFromScan0(128, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1865 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, NULL
, NULL
, NULL
);
1866 expect(InvalidParameter
, stat
);
1868 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, &bitmap2
, NULL
, NULL
);
1873 stat
= GdipGetImageWidth(bitmap2
, &width
);
1877 stat
= GdipGetImageHeight(bitmap2
, &height
);
1879 expect(120, height
);
1881 GdipDisposeImage(bitmap2
);
1884 GdipDisposeImage(bitmap1
);
1887 stat
= GdipCreateBitmapFromScan0(64, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1890 stat
= GdipGetImageThumbnail(bitmap1
, 32, 32, &bitmap2
, NULL
, NULL
);
1895 stat
= GdipGetImageWidth(bitmap2
, &width
);
1899 stat
= GdipGetImageHeight(bitmap2
, &height
);
1903 GdipDisposeImage(bitmap2
);
1906 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, &bitmap2
, NULL
, NULL
);
1911 stat
= GdipGetImageWidth(bitmap2
, &width
);
1915 stat
= GdipGetImageHeight(bitmap2
, &height
);
1917 expect(120, height
);
1919 GdipDisposeImage(bitmap2
);
1922 GdipDisposeImage(bitmap1
);
1925 static void test_getsetpixel(void)
1930 BYTE bits
[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00,
1931 0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00};
1933 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, bits
, &bitmap
);
1936 /* null parameters */
1937 stat
= GdipBitmapGetPixel(NULL
, 1, 1, &color
);
1938 expect(InvalidParameter
, stat
);
1940 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, NULL
);
1941 expect(InvalidParameter
, stat
);
1943 stat
= GdipBitmapSetPixel(NULL
, 1, 1, 0);
1944 expect(InvalidParameter
, stat
);
1947 stat
= GdipBitmapGetPixel(bitmap
, -1, 1, &color
);
1948 expect(InvalidParameter
, stat
);
1950 stat
= GdipBitmapSetPixel(bitmap
, -1, 1, 0);
1951 expect(InvalidParameter
, stat
);
1953 stat
= GdipBitmapGetPixel(bitmap
, 1, -1, &color
);
1954 ok(stat
== InvalidParameter
||
1955 broken(stat
== Ok
), /* Older gdiplus */
1956 "Expected InvalidParameter, got %.8x\n", stat
);
1958 if (0) /* crashes some gdiplus implementations */
1960 stat
= GdipBitmapSetPixel(bitmap
, 1, -1, 0);
1961 ok(stat
== InvalidParameter
||
1962 broken(stat
== Ok
), /* Older gdiplus */
1963 "Expected InvalidParameter, got %.8x\n", stat
);
1966 stat
= GdipBitmapGetPixel(bitmap
, 2, 1, &color
);
1967 expect(InvalidParameter
, stat
);
1969 stat
= GdipBitmapSetPixel(bitmap
, 2, 1, 0);
1970 expect(InvalidParameter
, stat
);
1972 stat
= GdipBitmapGetPixel(bitmap
, 1, 2, &color
);
1973 expect(InvalidParameter
, stat
);
1975 stat
= GdipBitmapSetPixel(bitmap
, 1, 2, 0);
1976 expect(InvalidParameter
, stat
);
1979 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
1981 expect(0xffffffff, color
);
1983 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
1985 expect(0xff0000ff, color
);
1987 stat
= GdipBitmapSetPixel(bitmap
, 1, 1, 0xff676869);
1990 stat
= GdipBitmapSetPixel(bitmap
, 0, 0, 0xff474849);
1993 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
1995 expect(0xff676869, color
);
1997 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
1999 expect(0xff474849, color
);
2001 stat
= GdipDisposeImage((GpImage
*)bitmap
);
2005 static void check_halftone_palette(ColorPalette
*palette
)
2007 static const BYTE halftone_values
[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
2010 for (i
=0; i
<palette
->Count
; i
++)
2012 ARGB expected
=0xff000000;
2015 if (i
&1) expected
|= 0x800000;
2016 if (i
&2) expected
|= 0x8000;
2017 if (i
&4) expected
|= 0x80;
2021 expected
= 0xffc0c0c0;
2025 if (i
&1) expected
|= 0xff0000;
2026 if (i
&2) expected
|= 0xff00;
2027 if (i
&4) expected
|= 0xff;
2031 expected
= 0x00000000;
2035 expected
|= halftone_values
[(i
-40)%6];
2036 expected
|= halftone_values
[((i
-40)/6)%6] << 8;
2037 expected
|= halftone_values
[((i
-40)/36)%6] << 16;
2039 ok(expected
== palette
->Entries
[i
], "Expected %.8x, got %.8x, i=%u/%u\n",
2040 expected
, palette
->Entries
[i
], i
, palette
->Count
);
2044 static void test_palette(void)
2050 ColorPalette
*palette
=(ColorPalette
*)buffer
;
2051 ARGB
*entries
= palette
->Entries
;
2054 /* test initial palette from non-indexed bitmap */
2055 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, NULL
, &bitmap
);
2058 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2060 expect(sizeof(UINT
)*2+sizeof(ARGB
), size
);
2062 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2064 expect(0, palette
->Count
);
2066 /* test setting palette on not-indexed bitmap */
2069 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2072 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2074 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2076 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2078 expect(3, palette
->Count
);
2080 GdipDisposeImage((GpImage
*)bitmap
);
2082 /* test initial palette on 1-bit bitmap */
2083 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat1bppIndexed
, NULL
, &bitmap
);
2086 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2088 expect(sizeof(UINT
)*2+sizeof(ARGB
)*2, size
);
2090 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2092 expect(PaletteFlagsGrayScale
, palette
->Flags
);
2093 expect(2, palette
->Count
);
2095 expect(0xff000000, entries
[0]);
2096 expect(0xffffffff, entries
[1]);
2098 /* test getting/setting pixels */
2099 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2101 expect(0xff000000, color
);
2103 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffffffff);
2105 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2109 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2111 expect(0xffffffff, color
);
2114 GdipDisposeImage((GpImage
*)bitmap
);
2116 /* test initial palette on 4-bit bitmap */
2117 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat4bppIndexed
, NULL
, &bitmap
);
2120 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2122 expect(sizeof(UINT
)*2+sizeof(ARGB
)*16, size
);
2124 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2126 expect(0, palette
->Flags
);
2127 expect(16, palette
->Count
);
2129 check_halftone_palette(palette
);
2131 /* test getting/setting pixels */
2132 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2134 expect(0xff000000, color
);
2136 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffff00ff);
2138 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2142 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2144 expect(0xffff00ff, color
);
2147 GdipDisposeImage((GpImage
*)bitmap
);
2149 /* test initial palette on 8-bit bitmap */
2150 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat8bppIndexed
, NULL
, &bitmap
);
2153 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2155 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2157 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2159 expect(PaletteFlagsHalftone
, palette
->Flags
);
2160 expect(256, palette
->Count
);
2162 check_halftone_palette(palette
);
2164 /* test getting/setting pixels */
2165 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2167 expect(0xff000000, color
);
2169 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffcccccc);
2171 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2175 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2177 expect(0xffcccccc, color
);
2180 /* test setting/getting a different palette */
2181 entries
[1] = 0xffcccccc;
2183 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2188 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2190 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2192 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2194 expect(PaletteFlagsHalftone
, palette
->Flags
);
2195 expect(256, palette
->Count
);
2196 expect(0xffcccccc, entries
[1]);
2198 /* test count < 256 */
2199 palette
->Flags
= 12345;
2202 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2206 entries
[3] = 0xdeadbeef;
2208 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2210 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2212 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2214 expect(12345, palette
->Flags
);
2215 expect(3, palette
->Count
);
2216 expect(0xffcccccc, entries
[1]);
2217 expect(0xdeadbeef, entries
[3]);
2219 /* test count > 256 */
2220 palette
->Count
= 257;
2222 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2223 ok(stat
== InvalidParameter
||
2224 broken(stat
== Ok
), /* Old gdiplus behavior */
2225 "Expected %.8x, got %.8x\n", InvalidParameter
, stat
);
2227 GdipDisposeImage((GpImage
*)bitmap
);
2230 static void test_colormatrix(void)
2233 ColorMatrix colormatrix
, graymatrix
;
2234 GpImageAttributes
*imageattr
;
2235 const ColorMatrix identity
= {{
2236 {1.0,0.0,0.0,0.0,0.0},
2237 {0.0,1.0,0.0,0.0,0.0},
2238 {0.0,0.0,1.0,0.0,0.0},
2239 {0.0,0.0,0.0,1.0,0.0},
2240 {0.0,0.0,0.0,0.0,1.0}}};
2241 const ColorMatrix double_red
= {{
2242 {2.0,0.0,0.0,0.0,0.0},
2243 {0.0,1.0,0.0,0.0,0.0},
2244 {0.0,0.0,1.0,0.0,0.0},
2245 {0.0,0.0,0.0,1.0,0.0},
2246 {0.0,0.0,0.0,0.0,1.0}}};
2247 const ColorMatrix asymmetric
= {{
2248 {0.0,1.0,0.0,0.0,0.0},
2249 {0.0,0.0,1.0,0.0,0.0},
2250 {0.0,0.0,0.0,1.0,0.0},
2251 {1.0,0.0,0.0,0.0,0.0},
2252 {0.0,0.0,0.0,0.0,1.0}}};
2253 GpBitmap
*bitmap1
, *bitmap2
;
2254 GpGraphics
*graphics
;
2257 colormatrix
= identity
;
2258 graymatrix
= identity
;
2260 stat
= GdipSetImageAttributesColorMatrix(NULL
, ColorAdjustTypeDefault
,
2261 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2262 expect(InvalidParameter
, stat
);
2264 stat
= GdipCreateImageAttributes(&imageattr
);
2267 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2268 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2271 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2272 TRUE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2273 expect(InvalidParameter
, stat
);
2275 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2276 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2279 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2280 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsSkipGrays
);
2283 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2284 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsAltGray
);
2285 expect(InvalidParameter
, stat
);
2287 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2288 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsAltGray
);
2291 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2292 TRUE
, &colormatrix
, &graymatrix
, 3);
2293 expect(InvalidParameter
, stat
);
2295 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeCount
,
2296 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2297 expect(InvalidParameter
, stat
);
2299 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeAny
,
2300 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2301 expect(InvalidParameter
, stat
);
2303 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2304 FALSE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2307 /* Drawing a bitmap transforms the colors */
2308 colormatrix
= double_red
;
2309 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2310 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2313 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
2316 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
2319 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff40ccee);
2322 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2325 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2326 UnitPixel
, imageattr
, NULL
, NULL
);
2329 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2331 expect(0xff80ccee, color
);
2333 colormatrix
= asymmetric
;
2334 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2335 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2338 stat
= GdipBitmapSetPixel(bitmap2
, 0, 0, 0);
2341 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2342 UnitPixel
, imageattr
, NULL
, NULL
);
2345 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2347 ok(color_match(0xeeff40cc, color
, 3), "expected 0xeeff40cc, got 0x%08x\n", color
);
2349 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2352 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2353 UnitPixel
, imageattr
, NULL
, NULL
);
2356 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2358 ok(color_match(0xff40ccee, color
, 1), "Expected ff40ccee, got %.8x\n", color
);
2360 GdipDeleteGraphics(graphics
);
2361 GdipDisposeImage((GpImage
*)bitmap1
);
2362 GdipDisposeImage((GpImage
*)bitmap2
);
2363 GdipDisposeImageAttributes(imageattr
);
2366 static void test_gamma(void)
2369 GpImageAttributes
*imageattr
;
2370 GpBitmap
*bitmap1
, *bitmap2
;
2371 GpGraphics
*graphics
;
2374 stat
= GdipSetImageAttributesGamma(NULL
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2375 expect(InvalidParameter
, stat
);
2377 stat
= GdipCreateImageAttributes(&imageattr
);
2380 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2383 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeAny
, TRUE
, 1.0);
2384 expect(InvalidParameter
, stat
);
2386 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, -1.0);
2387 expect(InvalidParameter
, stat
);
2389 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.0);
2390 expect(InvalidParameter
, stat
);
2392 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.5);
2395 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0.0);
2398 /* Drawing a bitmap transforms the colors */
2399 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 3.0);
2402 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
2405 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
2408 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff80ffff);
2411 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2414 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2415 UnitPixel
, imageattr
, NULL
, NULL
);
2418 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2420 ok(color_match(0xff20ffff, color
, 1), "Expected ff20ffff, got %.8x\n", color
);
2422 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2425 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2426 UnitPixel
, imageattr
, NULL
, NULL
);
2429 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2431 ok(color_match(0xff80ffff, color
, 1), "Expected ff80ffff, got %.8x\n", color
);
2433 GdipDeleteGraphics(graphics
);
2434 GdipDisposeImage((GpImage
*)bitmap1
);
2435 GdipDisposeImage((GpImage
*)bitmap2
);
2436 GdipDisposeImageAttributes(imageattr
);
2439 /* 1x1 pixel gif, 2 frames; first frame is white, second is black */
2440 static const unsigned char gifanimation
[72] = {
2441 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
2442 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0xf9,0x04,0x00,0x0a,0x00,0xff,
2443 0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x4c,0x01,0x00,
2444 0x21,0xf9,0x04,0x01,0x0a,0x00,0x01,0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,
2445 0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
2448 /* Generated with ImageMagick:
2449 * convert -transparent black -delay 100 -size 8x2 xc:black \
2450 * -dispose none -page +0+0 -size 2x2 xc:red \
2451 * -dispose background -page +2+0 -size 2x2 xc:blue \
2452 * -dispose previous -page +4+0 -size 2x2 xc:green \
2453 * -dispose undefined -page +6+0 -size 2x2 xc:gray \
2456 static const unsigned char gifanimation2
[] = {
2457 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x08, 0x00,
2458 0x02, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
2459 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x64,
2460 0x00, 0x00, 0x00, 0x21, 0xff, 0x0b, 0x4e, 0x45,
2461 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e,
2462 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00,
2463 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
2464 0x02, 0x04, 0x84, 0x8f, 0x09, 0x05, 0x00, 0x21,
2465 0xf9, 0x04, 0x04, 0x64, 0x00, 0x00, 0x00, 0x2c,
2466 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2467 0x81, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
2468 0x00, 0x00, 0xff, 0x00, 0x00, 0x02, 0x03, 0x44,
2469 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x08, 0x64,
2470 0x00, 0x00, 0x00, 0x2c, 0x02, 0x00, 0x00, 0x00,
2471 0x02, 0x00, 0x02, 0x00, 0x81, 0x00, 0x00, 0xff,
2472 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
2473 0xff, 0x02, 0x03, 0x44, 0x34, 0x05, 0x00, 0x21,
2474 0xf9, 0x04, 0x0c, 0x64, 0x00, 0x00, 0x00, 0x2c,
2475 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2476 0x81, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00,
2477 0x80, 0x00, 0x00, 0x80, 0x00, 0x02, 0x03, 0x44,
2478 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x64,
2479 0x00, 0x00, 0x00, 0x2c, 0x06, 0x00, 0x00, 0x00,
2480 0x02, 0x00, 0x02, 0x00, 0x80, 0x7e, 0x7e, 0x7e,
2481 0x00, 0x00, 0x00, 0x02, 0x02, 0x84, 0x51, 0x00,
2485 static ARGB gifanimation2_pixels
[5][4] = {
2487 {0xffff0000, 0, 0, 0},
2488 {0xffff0000, 0xff0000ff, 0, 0},
2489 {0xffff0000, 0, 0xff008000, 0},
2490 {0xffff0000, 0, 0, 0xff7e7e7e}
2493 static void test_multiframegif(void)
2504 PixelFormat pixel_format
;
2505 INT palette_size
, i
, j
;
2506 char palette_buf
[256];
2507 ColorPalette
*palette
;
2508 ARGB
*palette_entries
;
2510 /* Test frame functions with an animated GIF */
2511 hglob
= GlobalAlloc (0, sizeof(gifanimation
));
2512 data
= GlobalLock (hglob
);
2513 memcpy(data
, gifanimation
, sizeof(gifanimation
));
2514 GlobalUnlock(hglob
);
2516 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2517 ok(hres
== S_OK
, "Failed to create a stream\n");
2518 if(hres
!= S_OK
) return;
2520 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2521 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2523 IStream_Release(stream
);
2527 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2529 expect(PixelFormat32bppARGB
, pixel_format
);
2531 stat
= GdipGetImagePaletteSize((GpImage
*)bmp
, &palette_size
);
2533 ok(palette_size
== sizeof(ColorPalette
) ||
2534 broken(palette_size
== sizeof(ColorPalette
)+sizeof(ARGB
[3])),
2535 "palette_size = %d\n", palette_size
);
2537 /* Bitmap starts at frame 0 */
2539 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2541 expect(0xffffffff, color
);
2543 /* Check that we get correct metadata */
2544 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2548 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2550 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2553 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2557 /* SelectActiveFrame overwrites our current data */
2558 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2562 GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2564 expect(0xff000000, color
);
2566 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2570 GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2572 expect(0xffffffff, color
);
2574 /* Write over the image data */
2575 stat
= GdipBitmapSetPixel(bmp
, 0, 0, 0xff000000);
2578 /* Switching to the same frame does not overwrite our changes */
2579 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2582 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2584 expect(0xff000000, color
);
2586 /* But switching to another frame and back does */
2587 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2590 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2593 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2595 expect(0xffffffff, color
);
2597 /* rotate/flip discards the information about other frames */
2598 stat
= GdipImageRotateFlip((GpImage
*)bmp
, Rotate90FlipNone
);
2602 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2606 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bmp
, __LINE__
, FALSE
);
2608 GdipDisposeImage((GpImage
*)bmp
);
2609 IStream_Release(stream
);
2611 /* Test with a non-animated gif */
2612 hglob
= GlobalAlloc (0, sizeof(gifimage
));
2613 data
= GlobalLock (hglob
);
2614 memcpy(data
, gifimage
, sizeof(gifimage
));
2615 GlobalUnlock(hglob
);
2617 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2618 ok(hres
== S_OK
, "Failed to create a stream\n");
2619 if(hres
!= S_OK
) return;
2621 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2622 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2624 IStream_Release(stream
);
2628 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2630 expect(PixelFormat8bppIndexed
, pixel_format
);
2632 /* Check metadata */
2633 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2637 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2639 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2642 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2646 GdipDisposeImage((GpImage
*)bmp
);
2647 IStream_Release(stream
);
2649 /* Test with a non-animated transparent gif */
2650 hglob
= GlobalAlloc (0, sizeof(transparentgif
));
2651 data
= GlobalLock (hglob
);
2652 memcpy(data
, transparentgif
, sizeof(transparentgif
));
2653 GlobalUnlock(hglob
);
2655 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2656 ok(hres
== S_OK
, "Failed to create a stream\n");
2658 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2659 IStream_Release(stream
);
2660 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2662 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2664 expect(PixelFormat8bppIndexed
, pixel_format
);
2666 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2670 stat
= GdipGetImagePaletteSize((GpImage
*)bmp
, &palette_size
);
2672 ok(palette_size
== sizeof(ColorPalette
)+sizeof(ARGB
),
2673 "palette_size = %d\n", palette_size
);
2675 memset(palette_buf
, 0xfe, sizeof(palette_buf
));
2676 palette
= (ColorPalette
*)palette_buf
;
2677 stat
= GdipGetImagePalette((GpImage
*)bmp
, palette
,
2678 sizeof(ColorPalette
)+sizeof(ARGB
));
2679 palette_entries
= palette
->Entries
;
2681 expect(PaletteFlagsHasAlpha
, palette
->Flags
);
2682 expect(2, palette
->Count
);
2683 expect(0, palette_entries
[0]);
2684 expect(0xff000000, palette_entries
[1]);
2687 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2691 GdipDisposeImage((GpImage
*)bmp
);
2693 /* Test frame dispose methods */
2694 hglob
= GlobalAlloc (0, sizeof(gifanimation2
));
2695 data
= GlobalLock (hglob
);
2696 memcpy(data
, gifanimation2
, sizeof(gifanimation2
));
2697 GlobalUnlock(hglob
);
2699 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2700 ok(hres
== S_OK
, "Failed to create a stream\n");
2702 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2703 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2704 IStream_Release(stream
);
2706 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2708 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2710 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2714 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2718 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 3);
2720 stat
= GdipBitmapGetPixel(bmp
, 2, 0, &color
);
2722 ok(color
==0 || broken(color
==0xff0000ff), "color = %x\n", color
);
2724 win_skip("broken animated gif support\n");
2725 GdipDisposeImage((GpImage
*)bmp
);
2729 for(i
=0; i
<6; i
++) {
2730 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, i
%5);
2733 for(j
=0; j
<4; j
++) {
2734 stat
= GdipBitmapGetPixel(bmp
, j
*2, 0, &color
);
2736 ok(gifanimation2_pixels
[i
%5][j
] == color
, "at %d,%d got %x, expected %x\n", i
, j
, color
, gifanimation2_pixels
[i
%5][j
]);
2740 GdipDisposeImage((GpImage
*)bmp
);
2743 static void test_rotateflip(void)
2748 static const BYTE orig_bits
[24] = {
2749 0,0,0xff, 0,0xff,0, 0xff,0,0, 23,23,23,
2750 0xff,0xff,0, 0xff,0,0xff, 0,0xff,0xff, 23,23,23};
2754 memcpy(bits
, orig_bits
, sizeof(bits
));
2755 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2758 stat
= GdipImageRotateFlip(bitmap
, Rotate90FlipNone
);
2761 stat
= GdipGetImageWidth(bitmap
, &width
);
2763 stat
= GdipGetImageHeight(bitmap
, &height
);
2768 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2770 expect(0xff00ffff, color
);
2772 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 0, &color
);
2774 expect(0xffff0000, color
);
2776 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 2, &color
);
2778 expect(0xffffff00, color
);
2780 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 2, &color
);
2782 expect(0xff0000ff, color
);
2786 expect(0xff, bits
[2]);
2788 GdipDisposeImage(bitmap
);
2790 memcpy(bits
, orig_bits
, sizeof(bits
));
2791 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2794 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipX
);
2797 stat
= GdipGetImageWidth(bitmap
, &width
);
2799 stat
= GdipGetImageHeight(bitmap
, &height
);
2804 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2806 expect(0xff0000ff, color
);
2808 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
2810 expect(0xffff0000, color
);
2812 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
2814 expect(0xffffff00, color
);
2816 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
2818 expect(0xff00ffff, color
);
2822 expect(0xff, bits
[2]);
2824 GdipDisposeImage(bitmap
);
2826 memcpy(bits
, orig_bits
, sizeof(bits
));
2827 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2830 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipY
);
2833 stat
= GdipGetImageWidth(bitmap
, &width
);
2835 stat
= GdipGetImageHeight(bitmap
, &height
);
2840 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2842 expect(0xff00ffff, color
);
2844 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
2846 expect(0xffffff00, color
);
2848 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
2850 expect(0xffff0000, color
);
2852 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
2854 expect(0xff0000ff, color
);
2858 expect(0xff, bits
[2]);
2860 GdipDisposeImage(bitmap
);
2863 static void test_remaptable(void)
2866 GpImageAttributes
*imageattr
;
2867 GpBitmap
*bitmap1
, *bitmap2
;
2868 GpGraphics
*graphics
;
2872 map
= GdipAlloc(sizeof(ColorMap
));
2874 map
->oldColor
.Argb
= 0xff00ff00;
2875 map
->newColor
.Argb
= 0xffff00ff;
2877 stat
= GdipSetImageAttributesRemapTable(NULL
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
2878 expect(InvalidParameter
, stat
);
2880 stat
= GdipCreateImageAttributes(&imageattr
);
2883 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, NULL
);
2884 expect(InvalidParameter
, stat
);
2886 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeCount
, TRUE
, 1, map
);
2887 expect(InvalidParameter
, stat
);
2889 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeAny
, TRUE
, 1, map
);
2890 expect(InvalidParameter
, stat
);
2892 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0, map
);
2893 expect(InvalidParameter
, stat
);
2895 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0, NULL
);
2898 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
2901 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
2904 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
2907 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff00ff00);
2910 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2913 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2914 UnitPixel
, imageattr
, NULL
, NULL
);
2917 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2919 ok(color_match(0xffff00ff, color
, 1), "Expected ffff00ff, got %.8x\n", color
);
2921 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2924 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2925 UnitPixel
, imageattr
, NULL
, NULL
);
2928 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2930 ok(color_match(0xff00ff00, color
, 1), "Expected ff00ff00, got %.8x\n", color
);
2932 GdipDeleteGraphics(graphics
);
2933 GdipDisposeImage((GpImage
*)bitmap1
);
2934 GdipDisposeImage((GpImage
*)bitmap2
);
2935 GdipDisposeImageAttributes(imageattr
);
2939 static void test_colorkey(void)
2942 GpImageAttributes
*imageattr
;
2943 GpBitmap
*bitmap1
, *bitmap2
;
2944 GpGraphics
*graphics
;
2947 stat
= GdipSetImageAttributesColorKeys(NULL
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
2948 expect(InvalidParameter
, stat
);
2950 stat
= GdipCreateImageAttributes(&imageattr
);
2953 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeCount
, TRUE
, 0xff405060, 0xff708090);
2954 expect(InvalidParameter
, stat
);
2956 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeAny
, TRUE
, 0xff405060, 0xff708090);
2957 expect(InvalidParameter
, stat
);
2959 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
2962 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
2965 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
2968 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0x20405060);
2971 stat
= GdipBitmapSetPixel(bitmap1
, 0, 1, 0x40506070);
2974 stat
= GdipBitmapSetPixel(bitmap1
, 1, 0, 0x60708090);
2977 stat
= GdipBitmapSetPixel(bitmap1
, 1, 1, 0xffffffff);
2980 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2983 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
2984 UnitPixel
, imageattr
, NULL
, NULL
);
2987 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2989 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
2991 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
2993 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
2995 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
2997 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
2999 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
3001 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
3003 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
3006 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
3007 UnitPixel
, imageattr
, NULL
, NULL
);
3010 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
3012 ok(color_match(0x20405060, color
, 1), "Expected 20405060, got %.8x\n", color
);
3014 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
3016 ok(color_match(0x40506070, color
, 1), "Expected 40506070, got %.8x\n", color
);
3018 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
3020 ok(color_match(0x60708090, color
, 1), "Expected 60708090, got %.8x\n", color
);
3022 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
3024 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
3027 GdipDeleteGraphics(graphics
);
3028 GdipDisposeImage((GpImage
*)bitmap1
);
3029 GdipDisposeImage((GpImage
*)bitmap2
);
3030 GdipDisposeImageAttributes(imageattr
);
3033 static void test_dispose(void)
3037 char invalid_image
[256];
3039 stat
= GdipDisposeImage(NULL
);
3040 expect(InvalidParameter
, stat
);
3042 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, (GpBitmap
**)&image
);
3045 stat
= GdipDisposeImage(image
);
3048 stat
= GdipDisposeImage(image
);
3049 expect(ObjectBusy
, stat
);
3051 memset(invalid_image
, 0, 256);
3052 stat
= GdipDisposeImage((GpImage
*)invalid_image
);
3053 expect(ObjectBusy
, stat
);
3056 static LONG
obj_refcount(void *obj
)
3058 IUnknown_AddRef((IUnknown
*)obj
);
3059 return IUnknown_Release((IUnknown
*)obj
);
3062 static GpImage
*load_image(const BYTE
*image_data
, UINT image_size
)
3069 GpImage
*image
= NULL
, *clone
;
3070 ImageType image_type
;
3071 LONG refcount
, old_refcount
;
3073 hmem
= GlobalAlloc(0, image_size
);
3074 data
= GlobalLock(hmem
);
3075 memcpy(data
, image_data
, image_size
);
3078 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
3079 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
3080 if (hr
!= S_OK
) return NULL
;
3082 refcount
= obj_refcount(stream
);
3083 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3085 status
= GdipLoadImageFromStream(stream
, &image
);
3086 ok(status
== Ok
|| broken(status
== InvalidParameter
), /* XP */
3087 "GdipLoadImageFromStream error %d\n", status
);
3090 IStream_Release(stream
);
3094 status
= GdipGetImageType(image
, &image_type
);
3095 ok(status
== Ok
, "GdipGetImageType error %d\n", status
);
3097 refcount
= obj_refcount(stream
);
3098 if (image_type
== ImageTypeBitmap
)
3099 ok(refcount
> 1, "expected stream refcount > 1, got %d\n", refcount
);
3101 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3102 old_refcount
= refcount
;
3104 status
= GdipCloneImage(image
, &clone
);
3105 ok(status
== Ok
, "GdipCloneImage error %d\n", status
);
3106 refcount
= obj_refcount(stream
);
3107 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3108 status
= GdipDisposeImage(clone
);
3109 ok(status
== Ok
, "GdipDisposeImage error %d\n", status
);
3110 refcount
= obj_refcount(stream
);
3111 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3113 refcount
= IStream_Release(stream
);
3114 if (image_type
== ImageTypeBitmap
)
3115 ok(refcount
>= 1, "expected stream refcount != 0\n");
3117 ok(refcount
== 0, "expected stream refcount 0, got %d\n", refcount
);
3122 static void test_image_properties(void)
3124 static const struct test_data
3126 const BYTE
*image_data
;
3128 ImageType image_type
;
3130 UINT prop_count2
; /* if win7 behaves differently */
3131 /* 1st property attributes */
3133 UINT prop_size2
; /* if win7 behaves differently */
3135 UINT prop_id2
; /* if win7 behaves differently */
3139 { pngimage
, sizeof(pngimage
), ImageTypeBitmap
, 4, ~0, 1, 20, 0x5110, 0x132 },
3140 { jpgimage
, sizeof(jpgimage
), ImageTypeBitmap
, 2, ~0, 128, 0, 0x5090, 0x5091 },
3141 { tiffimage
, sizeof(tiffimage
), ImageTypeBitmap
, 16, 0, 4, 0, 0xfe, 0 },
3142 { bmpimage
, sizeof(bmpimage
), ImageTypeBitmap
, 0, 0, 0, 0, 0, 0 },
3143 { wmfimage
, sizeof(wmfimage
), ImageTypeMetafile
, 0, 0, 0, 0, 0, 0 }
3147 UINT prop_count
, prop_size
, i
;
3148 PROPID prop_id
[16] = { 0 };
3149 ImageType image_type
;
3156 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
3158 image
= load_image(td
[i
].image_data
, td
[i
].image_size
);
3161 trace("%u: failed to load image data\n", i
);
3165 status
= GdipGetImageType(image
, &image_type
);
3166 ok(status
== Ok
, "%u: GdipGetImageType error %d\n", i
, status
);
3167 ok(td
[i
].image_type
== image_type
, "%u: expected image_type %d, got %d\n",
3168 i
, td
[i
].image_type
, image_type
);
3170 status
= GdipGetPropertyCount(image
, &prop_count
);
3171 ok(status
== Ok
, "%u: GdipGetPropertyCount error %d\n", i
, status
);
3172 if (td
[i
].image_data
== pngimage
|| td
[i
].image_data
== jpgimage
)
3174 ok(td
[i
].prop_count
== prop_count
|| td
[i
].prop_count2
== prop_count
,
3175 " %u: expected property count %u or %u, got %u\n",
3176 i
, td
[i
].prop_count
, td
[i
].prop_count2
, prop_count
);
3178 ok(td
[i
].prop_count
== prop_count
|| td
[i
].prop_count2
== prop_count
,
3179 " %u: expected property count %u or %u, got %u\n",
3180 i
, td
[i
].prop_count
, td
[i
].prop_count2
, prop_count
);
3182 status
= GdipGetPropertyItemSize(NULL
, 0, &prop_size
);
3183 expect(InvalidParameter
, status
);
3184 status
= GdipGetPropertyItemSize(image
, 0, NULL
);
3185 expect(InvalidParameter
, status
);
3186 status
= GdipGetPropertyItemSize(image
, 0, &prop_size
);
3187 if (image_type
== ImageTypeMetafile
)
3188 expect(NotImplemented
, status
);
3190 expect(PropertyNotFound
, status
);
3192 status
= GdipGetPropertyItem(NULL
, 0, 0, &item
.data
);
3193 expect(InvalidParameter
, status
);
3194 status
= GdipGetPropertyItem(image
, 0, 0, NULL
);
3195 expect(InvalidParameter
, status
);
3196 status
= GdipGetPropertyItem(image
, 0, 0, &item
.data
);
3197 if (image_type
== ImageTypeMetafile
)
3198 expect(NotImplemented
, status
);
3200 expect(PropertyNotFound
, status
);
3202 /* FIXME: remove once Wine is fixed */
3203 if (td
[i
].prop_count
!= prop_count
)
3205 GdipDisposeImage(image
);
3209 status
= GdipGetPropertyIdList(NULL
, prop_count
, prop_id
);
3210 expect(InvalidParameter
, status
);
3211 status
= GdipGetPropertyIdList(image
, prop_count
, NULL
);
3212 expect(InvalidParameter
, status
);
3213 status
= GdipGetPropertyIdList(image
, 0, prop_id
);
3214 if (image_type
== ImageTypeMetafile
)
3215 expect(NotImplemented
, status
);
3216 else if (prop_count
== 0)
3219 expect(InvalidParameter
, status
);
3220 status
= GdipGetPropertyIdList(image
, prop_count
- 1, prop_id
);
3221 if (image_type
== ImageTypeMetafile
)
3222 expect(NotImplemented
, status
);
3224 expect(InvalidParameter
, status
);
3225 status
= GdipGetPropertyIdList(image
, prop_count
+ 1, prop_id
);
3226 if (image_type
== ImageTypeMetafile
)
3227 expect(NotImplemented
, status
);
3229 expect(InvalidParameter
, status
);
3230 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3231 if (image_type
== ImageTypeMetafile
)
3232 expect(NotImplemented
, status
);
3236 if (prop_count
!= 0)
3237 ok(td
[i
].prop_id
== prop_id
[0] || td
[i
].prop_id2
== prop_id
[0],
3238 " %u: expected property id %#x or %#x, got %#x\n",
3239 i
, td
[i
].prop_id
, td
[i
].prop_id2
, prop_id
[0]);
3244 status
= GdipGetPropertyItemSize(image
, prop_id
[0], &prop_size
);
3245 if (prop_count
== 0)
3246 expect(PropertyNotFound
, status
);
3251 assert(sizeof(item
) >= prop_size
);
3252 ok(prop_size
> sizeof(PropertyItem
), "%u: got too small prop_size %u\n",
3254 ok(td
[i
].prop_size
+ sizeof(PropertyItem
) == prop_size
||
3255 td
[i
].prop_size2
+ sizeof(PropertyItem
) == prop_size
,
3256 " %u: expected property size %u or %u, got %u\n",
3257 i
, td
[i
].prop_size
, td
[i
].prop_size2
, prop_size
);
3259 status
= GdipGetPropertyItem(image
, prop_id
[0], 0, &item
.data
);
3260 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3261 "%u: expected InvalidParameter, got %d\n", i
, status
);
3262 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
- 1, &item
.data
);
3263 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3264 "%u: expected InvalidParameter, got %d\n", i
, status
);
3265 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
+ 1, &item
.data
);
3266 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3267 "%u: expected InvalidParameter, got %d\n", i
, status
);
3268 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
, &item
.data
);
3270 ok(prop_id
[0] == item
.data
.id
,
3271 "%u: expected property id %#x, got %#x\n", i
, prop_id
[0], item
.data
.id
);
3275 GdipDisposeImage(image
);
3283 #define IFD_RATIONAL 5
3285 #define IFD_UNDEFINED 7
3286 #define IFD_SSHORT 8
3288 #define IFD_SRATIONAL 10
3289 #define IFD_FLOAT 11
3290 #define IFD_DOUBLE 12
3292 #ifndef PropertyTagTypeSByte
3293 #define PropertyTagTypeSByte 6
3294 #define PropertyTagTypeSShort 8
3295 #define PropertyTagTypeFloat 11
3296 #define PropertyTagTypeDouble 12
3299 static UINT
documented_type(UINT type
)
3303 case PropertyTagTypeSByte
: return PropertyTagTypeByte
;
3304 case PropertyTagTypeSShort
: return PropertyTagTypeShort
;
3305 case PropertyTagTypeFloat
: return PropertyTagTypeUndefined
;
3306 case PropertyTagTypeDouble
: return PropertyTagTypeUndefined
;
3307 default: return type
;
3311 #include "pshpack2.h"
3326 static const struct tiff_data
3331 USHORT number_of_entries
;
3332 struct IFD_entry entry
[40];
3334 struct IFD_rational xres
;
3336 struct IFD_rational srational_val
;
3341 struct IFD_rational rational
[3];
3345 #ifdef WORDS_BIGENDIAN
3351 FIELD_OFFSET(struct tiff_data
, number_of_entries
),
3354 { 0xff, IFD_SHORT
, 1, 0 }, /* SUBFILETYPE */
3355 { 0x100, IFD_LONG
, 1, 1 }, /* IMAGEWIDTH */
3356 { 0x101, IFD_LONG
, 1, 1 }, /* IMAGELENGTH */
3357 { 0x102, IFD_SHORT
, 1, 1 }, /* BITSPERSAMPLE */
3358 { 0x103, IFD_SHORT
, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
3359 { 0x106, IFD_SHORT
, 1, 1 }, /* PHOTOMETRIC */
3360 { 0x111, IFD_LONG
, 1, FIELD_OFFSET(struct tiff_data
, pixel_data
) }, /* STRIPOFFSETS */
3361 { 0x115, IFD_SHORT
, 1, 1 }, /* SAMPLESPERPIXEL */
3362 { 0x116, IFD_LONG
, 1, 1 }, /* ROWSPERSTRIP */
3363 { 0x117, IFD_LONG
, 1, 1 }, /* STRIPBYTECOUNT */
3364 { 0x11a, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3365 { 0x11b, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3366 { 0x128, IFD_SHORT
, 1, 2 }, /* RESOLUTIONUNIT */
3367 { 0xf001, IFD_BYTE
, 1, 0x11223344 },
3368 { 0xf002, IFD_BYTE
, 4, 0x11223344 },
3369 { 0xf003, IFD_SBYTE
, 1, 0x11223344 },
3370 { 0xf004, IFD_SSHORT
, 1, 0x11223344 },
3371 { 0xf005, IFD_SSHORT
, 2, 0x11223344 },
3372 { 0xf006, IFD_SLONG
, 1, 0x11223344 },
3373 { 0xf007, IFD_FLOAT
, 1, 0x11223344 },
3374 { 0xf008, IFD_DOUBLE
, 1, FIELD_OFFSET(struct tiff_data
, double_val
) },
3375 { 0xf009, IFD_SRATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, srational_val
) },
3376 { 0xf00a, IFD_BYTE
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3377 { 0xf00b, IFD_SSHORT
, 4, FIELD_OFFSET(struct tiff_data
, short_val
) },
3378 { 0xf00c, IFD_SLONG
, 2, FIELD_OFFSET(struct tiff_data
, long_val
) },
3379 { 0xf00e, IFD_ASCII
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3380 { 0xf00f, IFD_ASCII
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3381 { 0xf010, IFD_UNDEFINED
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3382 { 0xf011, IFD_UNDEFINED
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3383 /* Some gdiplus versions ignore these fields.
3384 { 0xf012, IFD_BYTE, 0, 0x11223344 },
3385 { 0xf013, IFD_SHORT, 0, 0x11223344 },
3386 { 0xf014, IFD_LONG, 0, 0x11223344 },
3387 { 0xf015, IFD_FLOAT, 0, 0x11223344 },*/
3388 { 0xf016, IFD_SRATIONAL
, 3, FIELD_OFFSET(struct tiff_data
, rational
) },
3389 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3390 { 0xf017, IFD_FLOAT
, 2, FIELD_OFFSET(struct tiff_data
, float_val
) },
3394 1234567890.0987654321,
3395 { 0x1a2b3c4d, 0x5a6b7c8d },
3397 { 0x0101, 0x0202, 0x0303, 0x0404 },
3398 { 0x11223344, 0x55667788 },
3399 { (FLOAT
)1234.5678, (FLOAT
)8765.4321 },
3400 { { 0x01020304, 0x05060708 }, { 0x10203040, 0x50607080 }, { 0x11223344, 0x55667788 } },
3401 { 0x11, 0x22, 0x33, 0 }
3403 #include "poppack.h"
3405 static void test_tiff_properties(void)
3407 static const struct test_data
3409 ULONG type
, id
, length
;
3410 const BYTE value
[24];
3413 { PropertyTagTypeShort
, 0xff, 2, { 0 } },
3414 { PropertyTagTypeLong
, 0x100, 4, { 1 } },
3415 { PropertyTagTypeLong
, 0x101, 4, { 1 } },
3416 { PropertyTagTypeShort
, 0x102, 2, { 1 } },
3417 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3418 { PropertyTagTypeShort
, 0x106, 2, { 1 } },
3419 { PropertyTagTypeLong
, 0x111, 4, { 0x44,0x02 } },
3420 { PropertyTagTypeShort
, 0x115, 2, { 1 } },
3421 { PropertyTagTypeLong
, 0x116, 4, { 1 } },
3422 { PropertyTagTypeLong
, 0x117, 4, { 1 } },
3423 { PropertyTagTypeRational
, 0x11a, 8, { 0x84,0x03,0,0,0x03 } },
3424 { PropertyTagTypeRational
, 0x11b, 8, { 0x84,0x03,0,0,0x03 } },
3425 { PropertyTagTypeShort
, 0x128, 2, { 2 } },
3426 { PropertyTagTypeByte
, 0xf001, 1, { 0x44 } },
3427 { PropertyTagTypeByte
, 0xf002, 4, { 0x44,0x33,0x22,0x11 } },
3428 { PropertyTagTypeSByte
, 0xf003, 1, { 0x44 } },
3429 { PropertyTagTypeSShort
, 0xf004, 2, { 0x44,0x33 } },
3430 { PropertyTagTypeSShort
, 0xf005, 4, { 0x44,0x33,0x22,0x11 } },
3431 { PropertyTagTypeSLONG
, 0xf006, 4, { 0x44,0x33,0x22,0x11 } },
3432 { PropertyTagTypeFloat
, 0xf007, 4, { 0x44,0x33,0x22,0x11 } },
3433 { PropertyTagTypeDouble
, 0xf008, 8, { 0x2c,0x52,0x86,0xb4,0x80,0x65,0xd2,0x41 } },
3434 { PropertyTagTypeSRational
, 0xf009, 8, { 0x4d, 0x3c, 0x2b, 0x1a, 0x8d, 0x7c, 0x6b, 0x5a } },
3435 { PropertyTagTypeByte
, 0xf00a, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3436 { PropertyTagTypeSShort
, 0xf00b, 8, { 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04 } },
3437 { PropertyTagTypeSLONG
, 0xf00c, 8, { 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3438 { PropertyTagTypeASCII
, 0xf00e, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3439 { PropertyTagTypeASCII
, 0xf00f, 5, { 'a','b','c','d' } },
3440 { PropertyTagTypeUndefined
, 0xf010, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3441 { PropertyTagTypeUndefined
, 0xf011, 4, { 'a','b','c','d' } },
3442 { PropertyTagTypeSRational
, 0xf016, 24,
3443 { 0x04,0x03,0x02,0x01,0x08,0x07,0x06,0x05,
3444 0x40,0x30,0x20,0x10,0x80,0x70,0x60,0x50,
3445 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3446 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3447 { PropertyTagTypeFloat
, 0xf017, 8, { 0x2b,0x52,0x9a,0x44,0xba,0xf5,0x08,0x46 } },
3452 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3454 PropertyItem
*prop_item
;
3456 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
));
3459 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3463 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3465 expect(1, dim_count
);
3467 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3469 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3471 frame_count
= 0xdeadbeef;
3472 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3474 expect(1, frame_count
);
3476 prop_count
= 0xdeadbeef;
3477 status
= GdipGetPropertyCount(image
, &prop_count
);
3479 ok(prop_count
== sizeof(td
)/sizeof(td
[0]) ||
3480 broken(prop_count
== sizeof(td
)/sizeof(td
[0]) - 1) /* Win7 SP0 */,
3481 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
3483 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3485 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3488 for (i
= 0; i
< prop_count
; i
++)
3490 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &prop_size
);
3492 if (status
!= Ok
) break;
3493 ok(prop_size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, prop_size
);
3495 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, prop_size
);
3496 status
= GdipGetPropertyItem(image
, prop_id
[i
], prop_size
, prop_item
);
3498 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3499 ok(td
[i
].type
== prop_item
->type
||
3500 /* Win7 stopped using proper but not documented types, and it
3501 looks broken since TypeFloat and TypeDouble now reported as
3502 TypeUndefined, and signed types reported as unsigned. */
3503 broken(prop_item
->type
== documented_type(td
[i
].type
)),
3504 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3505 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3506 prop_size
-= sizeof(*prop_item
);
3507 ok(prop_item
->length
== prop_size
, "%u: expected length %u, got %u\n", i
, prop_size
, prop_item
->length
);
3508 ok(td
[i
].length
== prop_item
->length
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_item
->length
+1) /* XP */,
3509 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3510 ok(td
[i
].length
== prop_size
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_size
+1) /* XP */,
3511 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_size
);
3512 if (td
[i
].length
== prop_item
->length
)
3514 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3515 ok(match
|| broken(td
[i
].length
<= 4 && !match
), "%u: data mismatch\n", i
);
3519 BYTE
*data
= prop_item
->value
;
3520 trace("id %#x:", prop_item
->id
);
3521 for (j
= 0; j
< prop_item
->length
; j
++)
3522 trace(" %02x", data
[j
]);
3526 HeapFree(GetProcessHeap(), 0, prop_item
);
3529 HeapFree(GetProcessHeap(), 0, prop_id
);
3531 GdipDisposeImage(image
);
3534 static void test_GdipGetAllPropertyItems(void)
3536 static const struct test_data
3538 ULONG type
, id
, length
;
3542 { PropertyTagTypeLong
, 0xfe, 4, { 0 } },
3543 { PropertyTagTypeShort
, 0x100, 2, { 1 } },
3544 { PropertyTagTypeShort
, 0x101, 2, { 1 } },
3545 { PropertyTagTypeShort
, 0x102, 6, { 8,0,8,0,8,0 } },
3546 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3547 { PropertyTagTypeShort
, 0x106, 2, { 2,0 } },
3548 { PropertyTagTypeASCII
, 0x10d, 27, "/home/meh/Desktop/test.tif" },
3549 { PropertyTagTypeLong
, 0x111, 4, { 8,0,0,0 } },
3550 { PropertyTagTypeShort
, 0x112, 2, { 1 } },
3551 { PropertyTagTypeShort
, 0x115, 2, { 3,0 } },
3552 { PropertyTagTypeShort
, 0x116, 2, { 0x40,0 } },
3553 { PropertyTagTypeLong
, 0x117, 4, { 3,0,0,0 } },
3554 { PropertyTagTypeRational
, 0x11a, 8, { 0,0,0,72,0,0,0,1 } },
3555 { PropertyTagTypeRational
, 0x11b, 8, { 0,0,0,72,0,0,0,1 } },
3556 { PropertyTagTypeShort
, 0x11c, 2, { 1 } },
3557 { PropertyTagTypeShort
, 0x128, 2, { 2 } }
3562 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3563 UINT total_size
, total_count
;
3565 PropertyItem
*prop_item
;
3566 const char *item_data
;
3568 image
= load_image(tiffimage
, sizeof(tiffimage
));
3569 ok(image
!= 0, "Failed to load TIFF image data\n");
3572 dim_count
= 0xdeadbeef;
3573 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3575 expect(1, dim_count
);
3577 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3579 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3581 frame_count
= 0xdeadbeef;
3582 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3584 expect(1, frame_count
);
3586 prop_count
= 0xdeadbeef;
3587 status
= GdipGetPropertyCount(image
, &prop_count
);
3589 ok(prop_count
== sizeof(td
)/sizeof(td
[0]),
3590 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
3592 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3594 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3598 for (i
= 0; i
< prop_count
; i
++)
3601 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
3603 if (status
!= Ok
) break;
3604 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
3608 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
3609 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
3611 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3612 ok(td
[i
].type
== prop_item
->type
,
3613 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3614 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3615 size
-= sizeof(*prop_item
);
3616 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
3617 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3618 if (td
[i
].length
== prop_item
->length
)
3620 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3621 ok(match
, "%u: data mismatch\n", i
);
3625 BYTE
*data
= prop_item
->value
;
3626 trace("id %#x:", prop_item
->id
);
3627 for (j
= 0; j
< prop_item
->length
; j
++)
3628 trace(" %02x", data
[j
]);
3632 HeapFree(GetProcessHeap(), 0, prop_item
);
3635 HeapFree(GetProcessHeap(), 0, prop_id
);
3637 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
3638 expect(InvalidParameter
, status
);
3639 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
3640 expect(InvalidParameter
, status
);
3641 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
3642 expect(InvalidParameter
, status
);
3643 status
= GdipGetPropertySize(image
, NULL
, NULL
);
3644 expect(InvalidParameter
, status
);
3645 total_size
= 0xdeadbeef;
3646 total_count
= 0xdeadbeef;
3647 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
3649 ok(prop_count
== total_count
,
3650 "expected total property count %u, got %u\n", prop_count
, total_count
);
3651 ok(prop_size
== total_size
,
3652 "expected total property size %u, got %u\n", prop_size
, total_size
);
3654 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
3656 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
3657 expect(InvalidParameter
, status
);
3658 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
3659 expect(InvalidParameter
, status
);
3660 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3661 expect(InvalidParameter
, status
);
3662 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3663 expect(InvalidParameter
, status
);
3664 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
3665 expect(InvalidParameter
, status
);
3666 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
3667 expect(InvalidParameter
, status
);
3668 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
3671 item_data
= (const char *)(prop_item
+ prop_count
);
3672 for (i
= 0; i
< prop_count
; i
++)
3674 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
3675 i
, item_data
, prop_item
[i
].value
);
3676 ok(td
[i
].type
== prop_item
[i
].type
,
3677 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
3678 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
3679 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
3680 if (td
[i
].length
== prop_item
[i
].length
)
3682 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
3683 ok(match
, "%u: data mismatch\n", i
);
3687 BYTE
*data
= prop_item
[i
].value
;
3688 trace("id %#x:", prop_item
[i
].id
);
3689 for (j
= 0; j
< prop_item
[i
].length
; j
++)
3690 trace(" %02x", data
[j
]);
3694 item_data
+= prop_item
[i
].length
;
3697 HeapFree(GetProcessHeap(), 0, prop_item
);
3699 GdipDisposeImage(image
);
3702 static void test_tiff_palette(void)
3713 ARGB
*entries
= palette
.pal
.Entries
;
3715 /* 1bpp TIFF without palette */
3716 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
));
3719 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3723 status
= GdipGetImagePixelFormat(image
, &format
);
3725 ok(format
== PixelFormat1bppIndexed
, "expected PixelFormat1bppIndexed, got %#x\n", format
);
3727 status
= GdipGetImagePaletteSize(image
, &size
);
3728 ok(status
== Ok
|| broken(status
== GenericError
), /* XP */
3729 "GdipGetImagePaletteSize error %d\n", status
);
3730 if (status
== GenericError
)
3732 GdipDisposeImage(image
);
3735 expect(sizeof(ColorPalette
) + sizeof(ARGB
), size
);
3737 status
= GdipGetImagePalette(image
, &palette
.pal
, size
);
3739 expect(0, palette
.pal
.Flags
);
3740 expect(2, palette
.pal
.Count
);
3741 if (palette
.pal
.Count
== 2)
3743 ok(entries
[0] == 0xff000000, "expected 0xff000000, got %#x\n", entries
[0]);
3744 ok(entries
[1] == 0xffffffff, "expected 0xffffffff, got %#x\n", entries
[1]);
3747 GdipDisposeImage(image
);
3750 static void test_bitmapbits(void)
3753 static const BYTE pixels_24
[48] =
3755 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3756 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3757 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3758 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0
3760 static const BYTE pixels_00
[48] =
3762 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3763 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3764 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3765 0,0,0, 0,0,0, 0,0,0, 0,0,0
3767 static const BYTE pixels_24_77
[64] =
3769 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3770 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3771 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3772 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3773 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3774 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3776 static const BYTE pixels_77
[64] =
3778 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3779 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3780 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3781 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3782 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3783 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3784 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3785 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3787 static const BYTE pixels_8
[16] =
3789 0x01,0,0x01,0,0x01,0,0x01,0,
3790 0x01,0,0x01,0,0x01,0,0x01,0
3792 static const BYTE pixels_8_77
[64] =
3794 0x01,0,0x01,0,0x01,0,0x01,0,
3795 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3796 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3797 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3798 0x01,0,0x01,0,0x01,0,0x01,0,
3799 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3800 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3801 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3803 static const BYTE pixels_1_77
[64] =
3805 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3806 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3807 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3808 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3809 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3810 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3811 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3812 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3814 static const BYTE pixels_1
[8] = {0xaa,0,0,0,0xaa,0,0,0};
3815 static const struct test_data
3822 const BYTE
*pixels_unlocked
;
3826 { PixelFormat24bppRGB
, 24, 0xfff0, 24, 48, pixels_24
, pixels_00
},
3828 { PixelFormat24bppRGB
, 24, 0, 24, 48, pixels_24
, pixels_00
},
3829 { PixelFormat24bppRGB
, 24, ImageLockModeRead
, 24, 48, pixels_24
, pixels_00
},
3830 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
3831 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
3832 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_24_77
, pixels_24
},
3833 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3834 { PixelFormat24bppRGB
, 24, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3836 { PixelFormat8bppIndexed
, 8, 0, 8, 16, pixels_8
, pixels_24
},
3837 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
, 8, 16, pixels_8
, pixels_24
},
3838 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
3839 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
3840 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_8_77
, pixels_24
},
3841 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3842 { PixelFormat8bppIndexed
, 8, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3844 { PixelFormat1bppIndexed
, 1, 0, 4, 8, pixels_1
, pixels_24
},
3845 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
, 4, 8, pixels_1
, pixels_24
},
3846 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
3847 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
3848 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_1_77
, pixels_24
},
3849 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3850 { PixelFormat1bppIndexed
, 1, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3862 ARGB
*entries
= palette
.pal
.Entries
;
3864 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
3866 BYTE pixels
[sizeof(pixels_24
)];
3867 memcpy(pixels
, pixels_24
, sizeof(pixels_24
));
3868 status
= GdipCreateBitmapFromScan0(8, 2, 24, PixelFormat24bppRGB
, pixels
, &bitmap
);
3871 /* associate known palette with pixel data */
3872 palette
.pal
.Flags
= PaletteFlagsGrayScale
;
3873 palette
.pal
.Count
= 2;
3874 entries
[0] = 0xff000000;
3875 entries
[1] = 0xffffffff;
3876 status
= GdipSetImagePalette((GpImage
*)bitmap
, &palette
.pal
);
3879 memset(&data
, 0xfe, sizeof(data
));
3880 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
3882 memset(buf
, 0x77, sizeof(buf
));
3886 status
= GdipBitmapLockBits(bitmap
, NULL
, td
[i
].mode
, td
[i
].format
, &data
);
3887 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* XP */, "%u: GdipBitmapLockBits error %d\n", i
, status
);
3890 GdipDisposeImage((GpImage
*)bitmap
);
3893 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
3894 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
3895 ok(td
[i
].stride
== data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].stride
, data
.Stride
);
3896 ok(td
[i
].format
== data
.PixelFormat
, "%u: expected %d, got %d\n", i
, td
[i
].format
, data
.PixelFormat
);
3897 ok(td
[i
].size
== data
.Height
* data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].size
, data
.Height
* data
.Stride
);
3898 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
3899 ok(data
.Scan0
== buf
, "%u: got wrong buffer\n", i
);
3900 if (td
[i
].size
== data
.Height
* data
.Stride
)
3902 UINT j
, match
, width_bytes
= (data
.Width
* td
[i
].bpp
) / 8;
3905 for (j
= 0; j
< data
.Height
; j
++)
3907 if (memcmp((const BYTE
*)data
.Scan0
+ j
* data
.Stride
, td
[i
].pixels
+ j
* data
.Stride
, width_bytes
) != 0)
3913 if ((td
[i
].mode
& (ImageLockModeRead
|ImageLockModeUserInputBuf
)) || td
[i
].format
== PixelFormat24bppRGB
)
3916 "%u: data should match\n", i
);
3919 BYTE
*bits
= data
.Scan0
;
3920 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
3921 for (j
= 0; j
< td
[i
].size
; j
++)
3922 trace(" %02x", bits
[j
]);
3927 ok(!match
, "%u: data shouldn't match\n", i
);
3929 memset(data
.Scan0
, 0, td
[i
].size
);
3932 status
= GdipBitmapUnlockBits(bitmap
, &data
);
3933 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
3935 memset(&data
, 0xfe, sizeof(data
));
3936 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
3937 ok(status
== Ok
, "%u: GdipBitmapLockBits error %d\n", i
, status
);
3938 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
3939 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
3940 ok(data
.Stride
== 24, "%u: expected 24, got %d\n", i
, data
.Stride
);
3941 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "%u: got wrong pixel format %d\n", i
, data
.PixelFormat
);
3942 ok(data
.Height
* data
.Stride
== 48, "%u: expected 48, got %d\n", i
, data
.Height
* data
.Stride
);
3943 if (data
.Height
* data
.Stride
== 48)
3945 int match
= memcmp(data
.Scan0
, td
[i
].pixels_unlocked
, 48) == 0;
3946 ok(match
, "%u: data should match\n", i
);
3950 BYTE
*bits
= data
.Scan0
;
3951 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
3952 for (j
= 0; j
< 48; j
++)
3953 trace(" %02x", bits
[j
]);
3958 status
= GdipBitmapUnlockBits(bitmap
, &data
);
3959 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
3961 status
= GdipDisposeImage((GpImage
*)bitmap
);
3966 static void test_DrawImage(void)
3968 BYTE black_1x1
[4] = { 0,0,0,0 };
3969 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
3970 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
3971 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
3972 0,0,0,0,0,0,0xff,0xff };
3979 GpGraphics
*graphics
;
3982 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
3984 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
3987 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
3989 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
3991 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
3993 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
3996 status
= GdipDrawImageI(graphics
, u1
.image
, 0, 0);
3999 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
4000 ok(match
, "data should match\n");
4003 UINT i
, size
= sizeof(white_2x2
);
4004 BYTE
*bits
= white_2x2
;
4005 for (i
= 0; i
< size
; i
++)
4006 trace(" %02x", bits
[i
]);
4010 status
= GdipDeleteGraphics(graphics
);
4012 status
= GdipDisposeImage(u1
.image
);
4014 status
= GdipDisposeImage(u2
.image
);
4018 static void test_DrawImage_SourceCopy(void)
4020 DWORD dst_pixels
[4] = { 0xffffffff, 0xffffffff,
4021 0xffffffff, 0xffffffff };
4022 DWORD src_pixels
[4] = { 0, 0xffff0000,
4031 GpGraphics
*graphics
;
4033 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB
, (BYTE
*)dst_pixels
, &u1
.bitmap
);
4036 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB
, (BYTE
*)src_pixels
, &u2
.bitmap
);
4038 status
= GdipGetImageGraphicsContext(u1
.image
, &graphics
);
4040 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4043 status
= GdipSetCompositingMode(graphics
, CompositingModeSourceCopy
);
4046 status
= GdipDrawImageI(graphics
, u2
.image
, 0, 0);
4049 todo_wine
expect(0, dst_pixels
[0]);
4050 expect(0xffff0000, dst_pixels
[1]);
4051 todo_wine
expect(0, dst_pixels
[2]);
4052 todo_wine
expect(0, dst_pixels
[3]);
4054 status
= GdipDeleteGraphics(graphics
);
4056 status
= GdipDisposeImage(u1
.image
);
4058 status
= GdipDisposeImage(u2
.image
);
4062 static void test_GdipDrawImagePointRect(void)
4064 BYTE black_1x1
[4] = { 0,0,0,0 };
4065 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
4066 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
4067 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
4068 0,0,0,0,0,0,0xff,0xff };
4075 GpGraphics
*graphics
;
4078 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
4080 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4083 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
4085 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
4087 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4089 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4092 status
= GdipDrawImagePointRectI(graphics
, u1
.image
, 0, 0, 0, 0, 1, 1, UnitPixel
);
4095 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
4096 ok(match
, "data should match\n");
4099 UINT i
, size
= sizeof(white_2x2
);
4100 BYTE
*bits
= white_2x2
;
4101 for (i
= 0; i
< size
; i
++)
4102 trace(" %02x", bits
[i
]);
4106 status
= GdipDeleteGraphics(graphics
);
4108 status
= GdipDisposeImage(u1
.image
);
4110 status
= GdipDisposeImage(u2
.image
);
4114 static void test_image_format(void)
4116 static const PixelFormat fmt
[] =
4118 PixelFormat1bppIndexed
, PixelFormat4bppIndexed
, PixelFormat8bppIndexed
,
4119 PixelFormat16bppGrayScale
, PixelFormat16bppRGB555
, PixelFormat16bppRGB565
,
4120 PixelFormat16bppARGB1555
, PixelFormat24bppRGB
, PixelFormat32bppRGB
,
4121 PixelFormat32bppARGB
, PixelFormat32bppPARGB
, PixelFormat48bppRGB
,
4122 PixelFormat64bppARGB
, PixelFormat64bppPARGB
, PixelFormat32bppCMYK
4133 for (i
= 0; i
< sizeof(fmt
)/sizeof(fmt
[0]); i
++)
4135 status
= GdipCreateBitmapFromScan0(1, 1, 0, fmt
[i
], NULL
, &bitmap
);
4136 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* before win7 */,
4137 "GdipCreateBitmapFromScan0 error %d\n", status
);
4138 if (status
!= Ok
) continue;
4140 status
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
4142 expect(fmt
[i
], format
);
4144 status
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
4145 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4146 todo_wine
expect(InvalidParameter
, status
);
4150 ret
= GetObjectW(hbitmap
, sizeof(bm
), &bm
);
4151 expect(sizeof(bm
), ret
);
4152 expect(0, bm
.bmType
);
4153 expect(1, bm
.bmWidth
);
4154 expect(1, bm
.bmHeight
);
4155 expect(4, bm
.bmWidthBytes
);
4156 expect(1, bm
.bmPlanes
);
4157 expect(32, bm
.bmBitsPixel
);
4158 DeleteObject(hbitmap
);
4161 status
= GdipGetImageThumbnail((GpImage
*)bitmap
, 0, 0, &thumb
, NULL
, NULL
);
4162 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4164 ok(status
== OutOfMemory
|| broken(status
== InvalidParameter
) /* before win7 */,
4165 "expected OutOfMemory, got %d\n", status
);
4170 status
= GdipGetImagePixelFormat(thumb
, &format
);
4172 ok(format
== PixelFormat32bppPARGB
|| broken(format
!= PixelFormat32bppPARGB
) /* before win7 */,
4173 "expected PixelFormat32bppPARGB, got %#x\n", format
);
4174 status
= GdipDisposeImage(thumb
);
4178 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4179 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4180 todo_wine
expect(InvalidParameter
, status
);
4184 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4188 status
= GdipDisposeImage((GpImage
*)bitmap
);
4193 static void test_DrawImage_scale(void)
4195 static const BYTE back_8x1
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
4196 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4197 static const BYTE image_080
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,
4198 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4199 static const BYTE image_100
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,
4200 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4201 static const BYTE image_120
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,
4202 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4203 static const BYTE image_150
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4204 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4205 static const BYTE image_180
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4206 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4207 static const BYTE image_200
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4208 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4209 static const BYTE image_250
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,
4210 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4211 static const BYTE image_120_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4212 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4213 static const BYTE image_150_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4214 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4215 static const BYTE image_200_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4216 0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40 };
4217 static const BYTE image_250_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4218 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4219 static const struct test_data
4222 PixelOffsetMode pixel_offset_mode
;
4227 { 0.8, PixelOffsetModeNone
, image_080
}, /* 0 */
4228 { 1.0, PixelOffsetModeNone
, image_100
},
4229 { 1.2, PixelOffsetModeNone
, image_120
},
4230 { 1.5, PixelOffsetModeNone
, image_150
},
4231 { 1.8, PixelOffsetModeNone
, image_180
},
4232 { 2.0, PixelOffsetModeNone
, image_200
},
4233 { 2.5, PixelOffsetModeNone
, image_250
},
4235 { 0.8, PixelOffsetModeHighSpeed
, image_080
}, /* 7 */
4236 { 1.0, PixelOffsetModeHighSpeed
, image_100
},
4237 { 1.2, PixelOffsetModeHighSpeed
, image_120
},
4238 { 1.5, PixelOffsetModeHighSpeed
, image_150
},
4239 { 1.8, PixelOffsetModeHighSpeed
, image_180
},
4240 { 2.0, PixelOffsetModeHighSpeed
, image_200
},
4241 { 2.5, PixelOffsetModeHighSpeed
, image_250
},
4243 { 0.8, PixelOffsetModeHalf
, image_080
}, /* 14 */
4244 { 1.0, PixelOffsetModeHalf
, image_100
},
4245 { 1.2, PixelOffsetModeHalf
, image_120_half
, TRUE
},
4246 { 1.5, PixelOffsetModeHalf
, image_150_half
, TRUE
},
4247 { 1.8, PixelOffsetModeHalf
, image_180
},
4248 { 2.0, PixelOffsetModeHalf
, image_200_half
, TRUE
},
4249 { 2.5, PixelOffsetModeHalf
, image_250_half
, TRUE
},
4251 { 0.8, PixelOffsetModeHighQuality
, image_080
}, /* 21 */
4252 { 1.0, PixelOffsetModeHighQuality
, image_100
},
4253 { 1.2, PixelOffsetModeHighQuality
, image_120_half
, TRUE
},
4254 { 1.5, PixelOffsetModeHighQuality
, image_150_half
, TRUE
},
4255 { 1.8, PixelOffsetModeHighQuality
, image_180
},
4256 { 2.0, PixelOffsetModeHighQuality
, image_200_half
, TRUE
},
4257 { 2.5, PixelOffsetModeHighQuality
, image_250_half
, TRUE
},
4259 BYTE src_2x1
[6] = { 0x80,0x80,0x80,0x80,0x80,0x80 };
4267 GpGraphics
*graphics
;
4271 status
= GdipCreateBitmapFromScan0(2, 1, 4, PixelFormat24bppRGB
, src_2x1
, &u1
.bitmap
);
4273 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4276 status
= GdipCreateBitmapFromScan0(8, 1, 24, PixelFormat24bppRGB
, dst_8x1
, &u2
.bitmap
);
4278 status
= GdipBitmapSetResolution(u2
.bitmap
, 100.0, 100.0);
4280 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4282 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4285 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
4287 status
= GdipSetPixelOffsetMode(graphics
, td
[i
].pixel_offset_mode
);
4290 status
= GdipCreateMatrix2(td
[i
].scale_x
, 0.0, 0.0, 1.0, 0.0, 0.0, &matrix
);
4292 status
= GdipSetWorldTransform(graphics
, matrix
);
4294 GdipDeleteMatrix(matrix
);
4296 memcpy(dst_8x1
, back_8x1
, sizeof(dst_8x1
));
4297 status
= GdipDrawImageI(graphics
, u1
.image
, 1, 0);
4300 match
= memcmp(dst_8x1
, td
[i
].image
, sizeof(dst_8x1
)) == 0;
4301 if (!match
&& td
[i
].todo
)
4302 todo_wine
ok(match
, "%d: data should match\n", i
);
4304 ok(match
, "%d: data should match\n", i
);
4307 UINT i
, size
= sizeof(dst_8x1
);
4308 const BYTE
*bits
= dst_8x1
;
4309 for (i
= 0; i
< size
; i
++)
4310 trace(" %02x", bits
[i
]);
4315 status
= GdipDeleteGraphics(graphics
);
4317 status
= GdipDisposeImage(u1
.image
);
4319 status
= GdipDisposeImage(u2
.image
);
4323 static const BYTE animatedgif
[] = {
4324 'G','I','F','8','9','a',0x01,0x00,0x01,0x00,0xA1,0x02,0x00,
4325 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
4326 /*0x21,0xFF,0x0B,'A','N','I','M','E','X','T','S','1','.','0',*/
4327 0x21,0xFF,0x0B,'N','E','T','S','C','A','P','E','2','.','0',
4328 0x03,0x01,0x05,0x00,0x00,
4329 0x21,0xFE,0x0C,'H','e','l','l','o',' ','W','o','r','l','d','!',0x00,
4330 0x21,0x01,0x0D,'a','n','i','m','a','t','i','o','n','.','g','i','f',0x00,
4331 0x21,0xF9,0x04,0xff,0x0A,0x00,0x08,0x00,
4332 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4333 0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,
4334 0x02,0x02,0x4C,0x01,0x00,
4335 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','1',0x00,
4336 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','1',0x00,
4337 0x21,0xF9,0x04,0x00,0x14,0x00,0x01,0x00,
4338 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4339 0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,
4340 0x02,0x02,0x44,0x01,0x00,
4341 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','2',0x00,
4342 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','2',0x00,0x3B
4345 static void test_gif_properties(void)
4347 static const struct test_data
4349 ULONG type
, id
, length
;
4350 const BYTE value
[13];
4353 { PropertyTagTypeLong
, PropertyTagFrameDelay
, 8, { 10,0,0,0,20,0,0,0 } },
4354 { PropertyTagTypeASCII
, PropertyTagExifUserComment
, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
4355 { PropertyTagTypeShort
, PropertyTagLoopCount
, 2, { 5,0 } },
4356 { PropertyTagTypeByte
, PropertyTagGlobalPalette
, 12, { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c } },
4357 { PropertyTagTypeByte
, PropertyTagIndexBackground
, 1, { 2 } },
4358 { PropertyTagTypeByte
, PropertyTagIndexTransparent
, 1, { 8 } }
4363 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
4364 UINT total_size
, total_count
;
4366 PropertyItem
*prop_item
;
4367 const char *item_data
;
4369 image
= load_image(animatedgif
, sizeof(animatedgif
));
4370 if (!image
) /* XP fails to load this GIF image */
4372 trace("Failed to load GIF image data\n");
4376 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
4378 expect(1, dim_count
);
4380 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
4382 expect_guid(&FrameDimensionTime
, &guid
, __LINE__
, FALSE
);
4384 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
4386 expect(2, frame_count
);
4388 status
= GdipImageSelectActiveFrame(image
, &guid
, 1);
4391 status
= GdipGetPropertyCount(image
, &prop_count
);
4393 ok(prop_count
== sizeof(td
)/sizeof(td
[0]) || broken(prop_count
== 1) /* before win7 */,
4394 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
4396 if (prop_count
!= sizeof(td
)/sizeof(td
[0]))
4398 GdipDisposeImage(image
);
4402 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
4404 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
4408 for (i
= 0; i
< prop_count
; i
++)
4411 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
4413 if (status
!= Ok
) break;
4414 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
4418 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
4419 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
4421 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
4422 ok(td
[i
].type
== prop_item
->type
,
4423 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
4424 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
4425 size
-= sizeof(*prop_item
);
4426 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
4427 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
4428 if (td
[i
].length
== prop_item
->length
)
4430 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
4431 ok(match
, "%u: data mismatch\n", i
);
4435 BYTE
*data
= prop_item
->value
;
4436 trace("id %#x:", prop_item
->id
);
4437 for (j
= 0; j
< prop_item
->length
; j
++)
4438 trace(" %02x", data
[j
]);
4442 HeapFree(GetProcessHeap(), 0, prop_item
);
4445 HeapFree(GetProcessHeap(), 0, prop_id
);
4447 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
4448 expect(InvalidParameter
, status
);
4449 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
4450 expect(InvalidParameter
, status
);
4451 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
4452 expect(InvalidParameter
, status
);
4453 status
= GdipGetPropertySize(image
, NULL
, NULL
);
4454 expect(InvalidParameter
, status
);
4455 total_size
= 0xdeadbeef;
4456 total_count
= 0xdeadbeef;
4457 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
4459 ok(prop_count
== total_count
,
4460 "expected total property count %u, got %u\n", prop_count
, total_count
);
4461 ok(prop_size
== total_size
,
4462 "expected total property size %u, got %u\n", prop_size
, total_size
);
4464 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
4466 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
4467 expect(InvalidParameter
, status
);
4468 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
4469 expect(InvalidParameter
, status
);
4470 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4471 expect(InvalidParameter
, status
);
4472 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4473 expect(InvalidParameter
, status
);
4474 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
4475 expect(InvalidParameter
, status
);
4476 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
4477 expect(InvalidParameter
, status
);
4478 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
4481 item_data
= (const char *)(prop_item
+ prop_count
);
4482 for (i
= 0; i
< prop_count
; i
++)
4484 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
4485 i
, item_data
, prop_item
[i
].value
);
4486 ok(td
[i
].type
== prop_item
[i
].type
,
4487 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
4488 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
4489 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
4490 if (td
[i
].length
== prop_item
[i
].length
)
4492 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
4493 ok(match
, "%u: data mismatch\n", i
);
4497 BYTE
*data
= prop_item
[i
].value
;
4498 trace("id %#x:", prop_item
[i
].id
);
4499 for (j
= 0; j
< prop_item
[i
].length
; j
++)
4500 trace(" %02x", data
[j
]);
4504 item_data
+= prop_item
[i
].length
;
4507 HeapFree(GetProcessHeap(), 0, prop_item
);
4509 GdipDisposeImage(image
);
4512 static void test_ARGB_conversion(void)
4514 BYTE argb
[8] = { 0x11,0x22,0x33,0x80, 0xff,0xff,0xff,0 };
4515 BYTE pargb
[8] = { 0x09,0x11,0x1a,0x80, 0,0,0,0 };
4516 BYTE rgb32_xp
[8] = { 0x11,0x22,0x33,0xff, 0xff,0xff,0xff,0xff };
4517 BYTE rgb24
[6] = { 0x11,0x22,0x33, 0xff,0xff,0xff };
4524 status
= GdipCreateBitmapFromScan0(2, 1, 8, PixelFormat32bppARGB
, argb
, &bitmap
);
4527 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4529 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4530 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4531 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4532 ok(data
.PixelFormat
== PixelFormat32bppPARGB
, "expected PixelFormat32bppPARGB, got %d\n", data
.PixelFormat
);
4533 match
= !memcmp(data
.Scan0
, pargb
, sizeof(pargb
));
4534 ok(match
, "bits don't match\n");
4538 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppPARGB
,
4539 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4541 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4544 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppRGB
, &data
);
4546 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4547 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4548 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4549 ok(data
.PixelFormat
== PixelFormat32bppRGB
, "expected PixelFormat32bppRGB, got %d\n", data
.PixelFormat
);
4550 match
= !memcmp(data
.Scan0
, argb
, sizeof(argb
)) ||
4551 !memcmp(data
.Scan0
, rgb32_xp
, sizeof(rgb32_xp
));
4552 ok(match
, "bits don't match\n");
4556 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppRGB
,
4557 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4559 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4562 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
4564 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4565 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4566 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4567 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "expected PixelFormat24bppRGB, got %d\n", data
.PixelFormat
);
4568 match
= !memcmp(data
.Scan0
, rgb24
, sizeof(rgb24
));
4569 ok(match
, "bits don't match\n");
4573 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat24bppRGB
,
4574 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4576 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4579 GdipDisposeImage((GpImage
*)bitmap
);
4583 static void test_CloneBitmapArea(void)
4586 GpBitmap
*bitmap
, *copy
;
4587 BitmapData data
, data2
;
4589 status
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB
, NULL
, &bitmap
);
4592 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
| ImageLockModeWrite
, PixelFormat24bppRGB
, &data
);
4595 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data2
);
4596 expect(WrongState
, status
);
4598 status
= GdipCloneBitmapAreaI(0, 0, 1, 1, PixelFormat24bppRGB
, bitmap
, ©
);
4601 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4604 GdipDisposeImage((GpImage
*)copy
);
4605 GdipDisposeImage((GpImage
*)bitmap
);
4608 static BOOL
get_encoder_clsid(LPCWSTR mime
, GUID
*format
, CLSID
*clsid
)
4611 UINT n_codecs
, info_size
, i
;
4612 ImageCodecInfo
*info
;
4615 status
= GdipGetImageEncodersSize(&n_codecs
, &info_size
);
4618 info
= GdipAlloc(info_size
);
4620 status
= GdipGetImageEncoders(n_codecs
, info_size
, info
);
4623 for (i
= 0; i
< n_codecs
; i
++)
4625 if (!lstrcmpW(info
[i
].MimeType
, mime
))
4627 *format
= info
[i
].FormatID
;
4628 *clsid
= info
[i
].Clsid
;
4638 static void test_supported_encoders(void)
4640 static const WCHAR bmp_mimetype
[] = { 'i', 'm', 'a','g', 'e', '/', 'b', 'm', 'p',0 };
4641 static const WCHAR jpeg_mimetype
[] = { 'i','m','a','g','e','/','j','p','e','g',0 };
4642 static const WCHAR gif_mimetype
[] = { 'i','m','a','g','e','/','g','i','f',0 };
4643 static const WCHAR tiff_mimetype
[] = { 'i','m','a','g','e','/','t','i','f','f',0 };
4644 static const WCHAR png_mimetype
[] = { 'i','m','a','g','e','/','p','n','g',0 };
4645 static const struct test_data
4652 { bmp_mimetype
, &ImageFormatBMP
, FALSE
},
4653 { jpeg_mimetype
, &ImageFormatJPEG
, FALSE
},
4654 { gif_mimetype
, &ImageFormatGIF
, TRUE
},
4655 { tiff_mimetype
, &ImageFormatTIFF
, FALSE
},
4656 { png_mimetype
, &ImageFormatPNG
, FALSE
}
4667 status
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB
, NULL
, &bm
);
4668 ok(status
== Ok
, "GdipCreateBitmapFromScan0 error %d\n", status
);
4670 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
4672 ret
= get_encoder_clsid(td
[i
].mime
, &format
, &clsid
);
4673 ok(ret
, "%s encoder is not in the list\n", wine_dbgstr_w(td
[i
].mime
));
4674 expect_guid(td
[i
].format
, &format
, __LINE__
, FALSE
);
4676 hmem
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_NODISCARD
, 16);
4678 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
4679 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
4681 status
= GdipSaveImageToStream((GpImage
*)bm
, stream
, &clsid
, NULL
);
4683 todo_wine
ok(status
== Ok
, "GdipSaveImageToStream error %d\n", status
);
4685 ok(status
== Ok
, "GdipSaveImageToStream error %d\n", status
);
4687 IStream_Release(stream
);
4690 GdipDisposeImage((GpImage
*)bm
);
4693 static void test_createeffect(void)
4695 static const GUID noneffect
= { 0xcd0c3d4b, 0xe15e, 0x4cf2, { 0x9e, 0xa8, 0x6e, 0x1d, 0x65, 0x48, 0xc5, 0xa5 } };
4696 GpStatus (WINAPI
*pGdipCreateEffect
)( const GUID guid
, CGpEffect
**effect
);
4697 GpStatus (WINAPI
*pGdipDeleteEffect
)( CGpEffect
*effect
);
4700 HMODULE mod
= GetModuleHandleA("gdiplus.dll");
4702 const GUID
* const effectlist
[] =
4703 {&BlurEffectGuid
, &SharpenEffectGuid
, &ColorMatrixEffectGuid
, &ColorLUTEffectGuid
,
4704 &BrightnessContrastEffectGuid
, &HueSaturationLightnessEffectGuid
, &LevelsEffectGuid
,
4705 &TintEffectGuid
, &ColorBalanceEffectGuid
, &RedEyeCorrectionEffectGuid
, &ColorCurveEffectGuid
};
4707 pGdipCreateEffect
= (void*)GetProcAddress( mod
, "GdipCreateEffect");
4708 pGdipDeleteEffect
= (void*)GetProcAddress( mod
, "GdipDeleteEffect");
4709 if(!pGdipCreateEffect
|| !pGdipDeleteEffect
)
4711 /* GdipCreateEffect/GdipDeleteEffect was introduced in Windows Vista. */
4712 win_skip("GDIPlus version 1.1 not available\n");
4716 stat
= pGdipCreateEffect(BlurEffectGuid
, NULL
);
4717 expect(InvalidParameter
, stat
);
4719 stat
= pGdipCreateEffect(noneffect
, &effect
);
4720 todo_wine
expect(Win32Error
, stat
);
4722 for(i
=0; i
< sizeof(effectlist
) / sizeof(effectlist
[0]); i
++)
4724 stat
= pGdipCreateEffect(*effectlist
[i
], &effect
);
4725 todo_wine
expect(Ok
, stat
);
4728 stat
= pGdipDeleteEffect(effect
);
4736 struct GdiplusStartupInput gdiplusStartupInput
;
4737 ULONG_PTR gdiplusToken
;
4739 gdiplusStartupInput
.GdiplusVersion
= 1;
4740 gdiplusStartupInput
.DebugEventCallback
= NULL
;
4741 gdiplusStartupInput
.SuppressBackgroundThread
= 0;
4742 gdiplusStartupInput
.SuppressExternalCodecs
= 0;
4744 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, NULL
);
4746 test_supported_encoders();
4747 test_CloneBitmapArea();
4748 test_ARGB_conversion();
4749 test_DrawImage_scale();
4750 test_image_format();
4752 test_DrawImage_SourceCopy();
4753 test_GdipDrawImagePointRect();
4755 test_tiff_palette();
4756 test_GdipGetAllPropertyItems();
4757 test_tiff_properties();
4758 test_gif_properties();
4759 test_image_properties();
4762 test_GetImageDimension();
4763 test_GdipImageGetFrameDimensionsCount();
4764 test_LoadingImages();
4765 test_SavingImages();
4768 test_LockBits_UserBuf();
4769 test_GdipCreateBitmapFromHBITMAP();
4770 test_GdipGetImageFlags();
4771 test_GdipCloneImage();
4774 test_getrawformat();
4776 test_createfromwmf();
4777 test_createfromwmf_noplaceable();
4779 test_createhbitmap();
4780 test_getthumbnail();
4785 test_multiframegif();
4790 test_createeffect();
4792 GdiplusShutdown(gdiplusToken
);