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 ok_(__FILE__
, line
)(IsEqualGUID(expected
, got
), "Expected %s, got %s\n", buffer2
, buffer
);
62 static void expect_rawformat(REFGUID expected
, GpImage
*img
, int line
, BOOL todo
)
67 stat
= GdipGetImageRawFormat(img
, &raw
);
68 ok_(__FILE__
, line
)(stat
== Ok
, "GdipGetImageRawFormat failed with %d\n", stat
);
69 if(stat
!= Ok
) return;
70 expect_guid(expected
, &raw
, line
, todo
);
73 static void test_bufferrawformat(void* buff
, int size
, REFGUID expected
, int line
, BOOL todo
)
82 hglob
= GlobalAlloc (0, size
);
83 data
= GlobalLock (hglob
);
84 memcpy(data
, buff
, size
);
85 GlobalUnlock(hglob
); data
= NULL
;
87 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
88 ok_(__FILE__
, line
)(hres
== S_OK
, "Failed to create a stream\n");
89 if(hres
!= S_OK
) return;
91 stat
= GdipLoadImageFromStream(stream
, &img
);
92 ok_(__FILE__
, line
)(stat
== Ok
, "Failed to create a Bitmap\n");
94 IStream_Release(stream
);
98 expect_rawformat(expected
, img
, line
, todo
);
100 GdipDisposeImage(img
);
101 IStream_Release(stream
);
104 static void test_Scan0(void)
111 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
113 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
115 GdipDisposeImage((GpImage
*)bm
);
117 bm
= (GpBitmap
*)0xdeadbeef;
118 stat
= GdipCreateBitmapFromScan0(10, -10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
119 expect(InvalidParameter
, stat
);
120 ok( !bm
, "expected null bitmap\n" );
122 bm
= (GpBitmap
*)0xdeadbeef;
123 stat
= GdipCreateBitmapFromScan0(-10, 10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
124 expect(InvalidParameter
, stat
);
125 ok( !bm
, "expected null bitmap\n" );
127 bm
= (GpBitmap
*)0xdeadbeef;
128 stat
= GdipCreateBitmapFromScan0(10, 0, 10, PixelFormat24bppRGB
, NULL
, &bm
);
129 expect(InvalidParameter
, stat
);
130 ok( !bm
, "expected null bitmap\n" );
133 stat
= GdipCreateBitmapFromScan0(10, 10, 12, PixelFormat24bppRGB
, buff
, &bm
);
135 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
137 GdipDisposeImage((GpImage
*)bm
);
139 bm
= (GpBitmap
*) 0xdeadbeef;
140 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, buff
, &bm
);
141 expect(InvalidParameter
, stat
);
142 ok( !bm
, "expected null bitmap\n" );
144 bm
= (GpBitmap
*)0xdeadbeef;
145 stat
= GdipCreateBitmapFromScan0(10, 10, 0, PixelFormat24bppRGB
, buff
, &bm
);
146 expect(InvalidParameter
, stat
);
147 ok( bm
== (GpBitmap
*)0xdeadbeef, "expected deadbeef bitmap\n" );
150 stat
= GdipCreateBitmapFromScan0(10, 10, -8, PixelFormat24bppRGB
, buff
, &bm
);
152 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
154 GdipDisposeImage((GpImage
*)bm
);
156 bm
= (GpBitmap
*)0xdeadbeef;
157 stat
= GdipCreateBitmapFromScan0(10, 10, -10, PixelFormat24bppRGB
, buff
, &bm
);
158 expect(InvalidParameter
, stat
);
159 ok( !bm
, "expected null bitmap\n" );
162 static void test_FromGdiDib(void)
167 BYTE rbmi
[sizeof(BITMAPINFOHEADER
)+256*sizeof(RGBQUAD
)];
168 BITMAPINFO
*bmi
= (BITMAPINFO
*)rbmi
;
173 memset(rbmi
, 0, sizeof(rbmi
));
175 bmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
176 bmi
->bmiHeader
.biWidth
= 10;
177 bmi
->bmiHeader
.biHeight
= 10;
178 bmi
->bmiHeader
.biPlanes
= 1;
179 bmi
->bmiHeader
.biBitCount
= 32;
180 bmi
->bmiHeader
.biCompression
= BI_RGB
;
182 stat
= GdipCreateBitmapFromGdiDib(NULL
, buff
, &bm
);
183 expect(InvalidParameter
, stat
);
185 stat
= GdipCreateBitmapFromGdiDib(bmi
, NULL
, &bm
);
186 expect(InvalidParameter
, stat
);
188 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, NULL
);
189 expect(InvalidParameter
, stat
);
191 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
193 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
196 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
198 expect(PixelFormat32bppRGB
, format
);
200 GdipDisposeImage((GpImage
*)bm
);
203 bmi
->bmiHeader
.biBitCount
= 24;
204 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
206 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
209 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
211 expect(PixelFormat24bppRGB
, format
);
213 GdipDisposeImage((GpImage
*)bm
);
216 bmi
->bmiHeader
.biBitCount
= 16;
217 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
219 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
222 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
224 expect(PixelFormat16bppRGB555
, format
);
226 GdipDisposeImage((GpImage
*)bm
);
229 bmi
->bmiHeader
.biBitCount
= 8;
230 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
232 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
235 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
237 expect(PixelFormat8bppIndexed
, format
);
239 GdipDisposeImage((GpImage
*)bm
);
242 bmi
->bmiHeader
.biBitCount
= 4;
243 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
245 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
248 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
250 expect(PixelFormat4bppIndexed
, format
);
252 GdipDisposeImage((GpImage
*)bm
);
255 bmi
->bmiHeader
.biBitCount
= 1;
256 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
258 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
261 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
263 expect(PixelFormat1bppIndexed
, format
);
265 GdipDisposeImage((GpImage
*)bm
);
268 bmi
->bmiHeader
.biBitCount
= 0;
269 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
270 expect(InvalidParameter
, stat
);
273 static void test_GetImageDimension(void)
277 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
280 bm
= (GpBitmap
*)0xdeadbeef;
281 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
,NULL
, &bm
);
283 ok((GpBitmap
*)0xdeadbeef != bm
, "Expected bitmap to not be 0xdeadbeef\n");
284 ok(NULL
!= bm
, "Expected bitmap to not be NULL\n");
286 stat
= GdipGetImageDimension(NULL
,&w
,&h
);
287 expect(InvalidParameter
, stat
);
289 stat
= GdipGetImageDimension((GpImage
*)bm
,NULL
,&h
);
290 expect(InvalidParameter
, stat
);
292 stat
= GdipGetImageDimension((GpImage
*)bm
,&w
,NULL
);
293 expect(InvalidParameter
, stat
);
297 stat
= GdipGetImageDimension((GpImage
*)bm
,&w
,&h
);
301 GdipDisposeImage((GpImage
*)bm
);
304 static void test_GdipImageGetFrameDimensionsCount(void)
308 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
310 GUID dimension
= {0};
314 bm
= (GpBitmap
*)0xdeadbeef;
315 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
,NULL
, &bm
);
317 ok((GpBitmap
*)0xdeadbeef != bm
, "Expected bitmap to not be 0xdeadbeef\n");
318 ok(NULL
!= bm
, "Expected bitmap to not be NULL\n");
320 stat
= GdipImageGetFrameDimensionsCount(NULL
,&w
);
321 expect(InvalidParameter
, stat
);
323 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bm
,NULL
);
324 expect(InvalidParameter
, stat
);
327 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bm
,&w
);
331 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 1);
333 expect_guid(&FrameDimensionPage
, &dimension
, __LINE__
, FALSE
);
335 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 2);
336 expect(InvalidParameter
, stat
);
338 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 0);
339 expect(InvalidParameter
, stat
);
341 stat
= GdipImageGetFrameCount(NULL
, &dimension
, &count
);
342 expect(InvalidParameter
, stat
);
344 /* WinXP crashes on this test */
347 stat
= GdipImageGetFrameCount((GpImage
*)bm
, &dimension
, NULL
);
348 expect(InvalidParameter
, stat
);
351 stat
= GdipImageGetFrameCount((GpImage
*)bm
, NULL
, &count
);
355 stat
= GdipImageGetFrameCount((GpImage
*)bm
, &dimension
, &count
);
359 GdipBitmapSetPixel(bm
, 0, 0, 0xffffffff);
361 stat
= GdipImageSelectActiveFrame((GpImage
*)bm
, &dimension
, 0);
364 /* SelectActiveFrame has no effect on image data of memory bitmaps */
366 GdipBitmapGetPixel(bm
, 0, 0, &color
);
367 expect(0xffffffff, color
);
369 GdipDisposeImage((GpImage
*)bm
);
372 static void test_LoadingImages(void)
377 static const WCHAR nonexistentW
[] = {'n','o','n','e','x','i','s','t','e','n','t',0};
379 stat
= GdipCreateBitmapFromFile(0, 0);
380 expect(InvalidParameter
, stat
);
382 bm
= (GpBitmap
*)0xdeadbeef;
383 stat
= GdipCreateBitmapFromFile(0, &bm
);
384 expect(InvalidParameter
, stat
);
385 ok(bm
== (GpBitmap
*)0xdeadbeef, "returned %p\n", bm
);
387 bm
= (GpBitmap
*)0xdeadbeef;
388 stat
= GdipCreateBitmapFromFile(nonexistentW
, &bm
);
389 todo_wine
expect(InvalidParameter
, stat
);
390 ok(!bm
, "returned %p\n", bm
);
392 stat
= GdipLoadImageFromFile(0, 0);
393 expect(InvalidParameter
, stat
);
395 img
= (GpImage
*)0xdeadbeef;
396 stat
= GdipLoadImageFromFile(0, &img
);
397 expect(InvalidParameter
, stat
);
398 ok(img
== (GpImage
*)0xdeadbeef, "returned %p\n", img
);
400 img
= (GpImage
*)0xdeadbeef;
401 stat
= GdipLoadImageFromFile(nonexistentW
, &img
);
402 todo_wine
expect(OutOfMemory
, stat
);
403 ok(!img
, "returned %p\n", img
);
405 stat
= GdipLoadImageFromFileICM(0, 0);
406 expect(InvalidParameter
, stat
);
408 img
= (GpImage
*)0xdeadbeef;
409 stat
= GdipLoadImageFromFileICM(0, &img
);
410 expect(InvalidParameter
, stat
);
411 ok(img
== (GpImage
*)0xdeadbeef, "returned %p\n", img
);
413 img
= (GpImage
*)0xdeadbeef;
414 stat
= GdipLoadImageFromFileICM(nonexistentW
, &img
);
415 todo_wine
expect(OutOfMemory
, stat
);
416 ok(!img
, "returned %p\n", img
);
419 static void test_SavingImages(void)
425 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
427 ImageCodecInfo
*codecs
;
428 static const CHAR filenameA
[] = "a.bmp";
429 static const WCHAR filename
[] = { 'a','.','b','m','p',0 };
433 stat
= GdipSaveImageToFile(0, 0, 0, 0);
434 expect(InvalidParameter
, stat
);
437 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
443 stat
= GdipSaveImageToFile((GpImage
*)bm
, 0, 0, 0);
444 expect(InvalidParameter
, stat
);
446 stat
= GdipSaveImageToFile((GpImage
*)bm
, filename
, 0, 0);
447 expect(InvalidParameter
, stat
);
449 /* encoder tests should succeed -- already tested */
450 stat
= GdipGetImageEncodersSize(&n
, &s
);
451 if (stat
!= Ok
|| n
== 0) goto cleanup
;
453 codecs
= GdipAlloc(s
);
454 if (!codecs
) goto cleanup
;
456 stat
= GdipGetImageEncoders(n
, s
, codecs
);
457 if (stat
!= Ok
) goto cleanup
;
459 stat
= GdipSaveImageToFile((GpImage
*)bm
, filename
, &codecs
[0].Clsid
, 0);
462 GdipDisposeImage((GpImage
*)bm
);
465 /* re-load and check image stats */
466 stat
= GdipLoadImageFromFile(filename
, (GpImage
**)&bm
);
468 if (stat
!= Ok
) goto cleanup
;
470 stat
= GdipGetImageDimension((GpImage
*)bm
, &w
, &h
);
471 if (stat
!= Ok
) goto cleanup
;
479 GdipDisposeImage((GpImage
*)bm
);
480 ok(DeleteFileA(filenameA
), "Delete failed.\n");
483 static void test_encoders(void)
488 ImageCodecInfo
*codecs
;
492 static const CHAR bmp_format
[] = "BMP";
494 stat
= GdipGetImageEncodersSize(&n
, &s
);
497 codecs
= GdipAlloc(s
);
501 stat
= GdipGetImageEncoders(n
, s
, NULL
);
502 expect(GenericError
, stat
);
504 stat
= GdipGetImageEncoders(0, s
, codecs
);
505 expect(GenericError
, stat
);
507 stat
= GdipGetImageEncoders(n
, s
-1, codecs
);
508 expect(GenericError
, stat
);
510 stat
= GdipGetImageEncoders(n
, s
+1, codecs
);
511 expect(GenericError
, stat
);
513 stat
= GdipGetImageEncoders(n
, s
, codecs
);
517 for (i
= 0; i
< n
; i
++)
521 WideCharToMultiByte(CP_ACP
, 0, codecs
[i
].FormatDescription
, -1,
524 if (CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0,
526 bmp_format
, -1) == CSTR_EQUAL
) {
532 ok(FALSE
, "No BMP codec found.\n");
537 static void test_LockBits(void)
543 const INT WIDTH
= 10, HEIGHT
= 20;
548 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
556 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffc30000);
559 stat
= GdipBitmapSetPixel(bm
, 2, 8, 0xff480000);
563 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
567 expect(0xc3, ((BYTE
*)bd
.Scan0
)[2]);
568 expect(0x48, ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5]);
570 ((char*)bd
.Scan0
)[2] = 0xff;
572 stat
= GdipBitmapUnlockBits(bm
, &bd
);
576 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
578 expect(0xffff0000, color
);
580 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffc30000);
583 /* read-only, with NULL rect -> whole bitmap lock */
584 stat
= GdipBitmapLockBits(bm
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
586 expect(bd
.Width
, WIDTH
);
587 expect(bd
.Height
, HEIGHT
);
590 ((char*)bd
.Scan0
)[2 + 2*3 + 3*bd
.Stride
] = 0xff;
592 stat
= GdipBitmapUnlockBits(bm
, &bd
);
596 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
598 expect(0xffff0000, color
);
600 /* read-only, consecutive */
601 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
605 stat
= GdipBitmapUnlockBits(bm
, &bd
);
609 stat
= GdipDisposeImage((GpImage
*)bm
);
611 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
615 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
617 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
618 expect(WrongState
, stat
);
620 stat
= GdipBitmapUnlockBits(bm
, &bd
);
623 stat
= GdipDisposeImage((GpImage
*)bm
);
625 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
628 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffff0000);
631 stat
= GdipBitmapSetPixel(bm
, 2, 8, 0xffc30000);
634 /* write, no conversion */
635 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
639 /* all bits are readable, inside the rect or not */
640 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
641 expect(0xc3, ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5]);
643 stat
= GdipBitmapUnlockBits(bm
, &bd
);
647 /* read, conversion */
648 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat32bppARGB
, &bd
);
652 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
654 /* Areas outside the rectangle appear to be uninitialized */
655 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
657 ((BYTE
*)bd
.Scan0
)[2] = 0xc3;
659 stat
= GdipBitmapUnlockBits(bm
, &bd
);
663 /* writes do not work in read mode if there was a conversion */
664 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
666 expect(0xffff0000, color
);
668 /* read/write, conversion */
669 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeWrite
, PixelFormat32bppARGB
, &bd
);
673 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
674 ((BYTE
*)bd
.Scan0
)[1] = 0x88;
676 /* Areas outside the rectangle appear to be uninitialized */
677 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
679 stat
= GdipBitmapUnlockBits(bm
, &bd
);
683 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
685 expect(0xffff8800, color
);
687 /* write, conversion */
688 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat32bppARGB
, &bd
);
694 /* This is completely uninitialized. */
695 ok(0xff != ((BYTE
*)bd
.Scan0
)[2], "original image bits are readable\n");
696 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
699 /* Initialize the buffer so the unlock doesn't access undefined memory */
701 memset(((BYTE
*)bd
.Scan0
) + bd
.Stride
* y
, 0, 12);
703 ((BYTE
*)bd
.Scan0
)[0] = 0x12;
704 ((BYTE
*)bd
.Scan0
)[1] = 0x34;
705 ((BYTE
*)bd
.Scan0
)[2] = 0x56;
707 stat
= GdipBitmapUnlockBits(bm
, &bd
);
711 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
713 expect(0xff563412, color
);
715 stat
= GdipBitmapGetPixel(bm
, 2, 8, &color
);
717 expect(0xffc30000, color
);
719 stat
= GdipDisposeImage((GpImage
*)bm
);
721 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
724 /* write, no modification */
725 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
729 stat
= GdipBitmapUnlockBits(bm
, &bd
);
733 /* write, consecutive */
734 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
738 stat
= GdipBitmapUnlockBits(bm
, &bd
);
742 stat
= GdipDisposeImage((GpImage
*)bm
);
744 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
748 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
753 ((char*)bd
.Scan0
)[2] = 0xff;
755 stat
= GdipBitmapUnlockBits(bm
, &bd
);
759 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
761 expect(0xffff0000, color
);
763 stat
= GdipDisposeImage((GpImage
*)bm
);
767 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
769 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
771 stat
= GdipDisposeImage((GpImage
*)bm
);
775 static void test_LockBits_UserBuf(void)
781 const INT WIDTH
= 10, HEIGHT
= 20;
786 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat32bppARGB
, NULL
, &bm
);
789 memset(bits
, 0xaa, sizeof(bits
));
798 bd
.Stride
= WIDTH
* 4;
799 bd
.PixelFormat
= PixelFormat32bppARGB
;
800 bd
.Scan0
= &bits
[2+3*WIDTH
];
801 bd
.Reserved
= 0xaaaaaaaa;
804 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
807 expect(0xaaaaaaaa, bits
[0]);
808 expect(0, bits
[2+3*WIDTH
]);
810 bits
[2+3*WIDTH
] = 0xdeadbeef;
813 stat
= GdipBitmapUnlockBits(bm
, &bd
);
817 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
822 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
825 expect(0xdeadbeef, bits
[2+3*WIDTH
]);
826 bits
[2+3*WIDTH
] = 0x12345678;
829 stat
= GdipBitmapUnlockBits(bm
, &bd
);
833 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
835 expect(0x12345678, color
);
840 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeWrite
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
843 expect(0x12345678, bits
[2+3*WIDTH
]);
844 bits
[2+3*WIDTH
] = 0xdeadbeef;
847 stat
= GdipBitmapUnlockBits(bm
, &bd
);
851 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
853 expect(0xdeadbeef, color
);
855 stat
= GdipDisposeImage((GpImage
*)bm
);
859 struct BITMAPINFOWITHBITFIELDS
861 BITMAPINFOHEADER bmiHeader
;
865 union BITMAPINFOUNION
868 struct BITMAPINFOWITHBITFIELDS bf
;
871 static void test_GdipCreateBitmapFromHBITMAP(void)
873 GpBitmap
* gpbm
= NULL
;
875 HPALETTE hpal
= NULL
;
878 LOGPALETTE
* LogPal
= NULL
;
880 const REAL WIDTH1
= 5;
881 const REAL HEIGHT1
= 15;
882 const REAL WIDTH2
= 10;
883 const REAL HEIGHT2
= 20;
885 union BITMAPINFOUNION bmi
;
889 stat
= GdipCreateBitmapFromHBITMAP(NULL
, NULL
, NULL
);
890 expect(InvalidParameter
, stat
);
892 hbm
= CreateBitmap(WIDTH1
, HEIGHT1
, 1, 1, NULL
);
893 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, NULL
);
894 expect(InvalidParameter
, stat
);
896 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
898 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
899 expectf(WIDTH1
, width
);
900 expectf(HEIGHT1
, height
);
902 GdipDisposeImage((GpImage
*)gpbm
);
905 memset(buff
, 0, sizeof(buff
));
906 hbm
= CreateBitmap(WIDTH2
, HEIGHT2
, 1, 1, &buff
);
907 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
910 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)gpbm
, __LINE__
, FALSE
);
912 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
913 expectf(WIDTH2
, width
);
914 expectf(HEIGHT2
, height
);
916 GdipDisposeImage((GpImage
*)gpbm
);
919 hdc
= CreateCompatibleDC(0);
920 ok(hdc
!= NULL
, "CreateCompatibleDC failed\n");
921 bmi
.bi
.bmiHeader
.biSize
= sizeof(bmi
.bi
.bmiHeader
);
922 bmi
.bi
.bmiHeader
.biHeight
= HEIGHT1
;
923 bmi
.bi
.bmiHeader
.biWidth
= WIDTH1
;
924 bmi
.bi
.bmiHeader
.biBitCount
= 24;
925 bmi
.bi
.bmiHeader
.biPlanes
= 1;
926 bmi
.bi
.bmiHeader
.biCompression
= BI_RGB
;
927 bmi
.bi
.bmiHeader
.biClrUsed
= 0;
929 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
930 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
934 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
936 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
937 expectf(WIDTH1
, width
);
938 expectf(HEIGHT1
, height
);
941 /* test whether writing to the bitmap affects the original */
942 stat
= GdipBitmapSetPixel(gpbm
, 0, 0, 0xffffffff);
947 GdipDisposeImage((GpImage
*)gpbm
);
950 LogPal
= GdipAlloc(sizeof(LOGPALETTE
));
951 ok(LogPal
!= NULL
, "unable to allocate LOGPALETTE\n");
952 LogPal
->palVersion
= 0x300;
953 LogPal
->palNumEntries
= 1;
954 hpal
= CreatePalette(LogPal
);
955 ok(hpal
!= NULL
, "CreatePalette failed\n");
958 stat
= GdipCreateBitmapFromHBITMAP(hbm
, hpal
, &gpbm
);
962 GdipDisposeImage((GpImage
*)gpbm
);
967 /* 16-bit 555 dib, rgb */
968 bmi
.bi
.bmiHeader
.biBitCount
= 16;
969 bmi
.bi
.bmiHeader
.biCompression
= BI_RGB
;
971 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
972 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
976 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
981 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
983 expectf(WIDTH1
, width
);
984 expectf(HEIGHT1
, height
);
986 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
988 expect(PixelFormat16bppRGB555
, format
);
990 GdipDisposeImage((GpImage
*)gpbm
);
994 /* 16-bit 555 dib, with bitfields */
995 bmi
.bi
.bmiHeader
.biSize
= sizeof(bmi
);
996 bmi
.bi
.bmiHeader
.biCompression
= BI_BITFIELDS
;
997 bmi
.bf
.masks
[0] = 0x7c00;
998 bmi
.bf
.masks
[1] = 0x3e0;
999 bmi
.bf
.masks
[2] = 0x1f;
1001 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1002 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1006 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1011 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1013 expectf(WIDTH1
, width
);
1014 expectf(HEIGHT1
, height
);
1016 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1018 expect(PixelFormat16bppRGB555
, format
);
1020 GdipDisposeImage((GpImage
*)gpbm
);
1024 /* 16-bit 565 dib, with bitfields */
1025 bmi
.bf
.masks
[0] = 0xf800;
1026 bmi
.bf
.masks
[1] = 0x7e0;
1027 bmi
.bf
.masks
[2] = 0x1f;
1029 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1030 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1034 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1039 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1041 expectf(WIDTH1
, width
);
1042 expectf(HEIGHT1
, height
);
1044 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1046 expect(PixelFormat16bppRGB565
, format
);
1048 GdipDisposeImage((GpImage
*)gpbm
);
1055 static void test_GdipGetImageFlags(void)
1061 img
= (GpImage
*)0xdeadbeef;
1063 stat
= GdipGetImageFlags(NULL
, NULL
);
1064 expect(InvalidParameter
, stat
);
1066 stat
= GdipGetImageFlags(NULL
, &flags
);
1067 expect(InvalidParameter
, stat
);
1069 stat
= GdipGetImageFlags(img
, NULL
);
1070 expect(InvalidParameter
, stat
);
1072 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat1bppIndexed
, NULL
, (GpBitmap
**)&img
);
1074 stat
= GdipGetImageFlags(img
, &flags
);
1076 expect(ImageFlagsHasAlpha
, flags
);
1077 GdipDisposeImage(img
);
1079 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat4bppIndexed
, NULL
, (GpBitmap
**)&img
);
1081 stat
= GdipGetImageFlags(img
, &flags
);
1083 expect(ImageFlagsHasAlpha
, flags
);
1084 GdipDisposeImage(img
);
1086 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat8bppIndexed
, NULL
, (GpBitmap
**)&img
);
1088 stat
= GdipGetImageFlags(img
, &flags
);
1090 expect(ImageFlagsHasAlpha
, flags
);
1091 GdipDisposeImage(img
);
1093 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppGrayScale
, NULL
, (GpBitmap
**)&img
);
1095 stat
= GdipGetImageFlags(img
, &flags
);
1097 expect(ImageFlagsNone
, flags
);
1098 GdipDisposeImage(img
);
1100 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB555
, NULL
, (GpBitmap
**)&img
);
1102 stat
= GdipGetImageFlags(img
, &flags
);
1104 expect(ImageFlagsNone
, flags
);
1105 GdipDisposeImage(img
);
1107 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB565
, NULL
, (GpBitmap
**)&img
);
1109 stat
= GdipGetImageFlags(img
, &flags
);
1111 expect(ImageFlagsNone
, flags
);
1112 GdipDisposeImage(img
);
1114 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppARGB1555
, NULL
, (GpBitmap
**)&img
);
1116 stat
= GdipGetImageFlags(img
, &flags
);
1118 expect(ImageFlagsHasAlpha
, flags
);
1119 GdipDisposeImage(img
);
1121 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, NULL
, (GpBitmap
**)&img
);
1123 stat
= GdipGetImageFlags(img
, &flags
);
1125 expect(ImageFlagsNone
, flags
);
1126 GdipDisposeImage(img
);
1128 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&img
);
1130 stat
= GdipGetImageFlags(img
, &flags
);
1132 expect(ImageFlagsNone
, flags
);
1133 GdipDisposeImage(img
);
1135 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppARGB
, NULL
, (GpBitmap
**)&img
);
1137 stat
= GdipGetImageFlags(img
, &flags
);
1139 expect(ImageFlagsHasAlpha
, flags
);
1140 GdipDisposeImage(img
);
1142 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppPARGB
, NULL
, (GpBitmap
**)&img
);
1144 stat
= GdipGetImageFlags(img
, &flags
);
1146 expect(ImageFlagsHasAlpha
, flags
);
1147 GdipDisposeImage(img
);
1149 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat48bppRGB
, NULL
, (GpBitmap
**)&img
);
1153 stat
= GdipGetImageFlags(img
, &flags
);
1155 expect(ImageFlagsNone
, flags
);
1156 GdipDisposeImage(img
);
1159 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB
, NULL
, (GpBitmap
**)&img
);
1164 stat
= GdipGetImageFlags(img
, &flags
);
1166 expect(ImageFlagsHasAlpha
, flags
);
1167 GdipDisposeImage(img
);
1170 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB
, NULL
, (GpBitmap
**)&img
);
1175 stat
= GdipGetImageFlags(img
, &flags
);
1177 expect(ImageFlagsHasAlpha
, flags
);
1178 GdipDisposeImage(img
);
1182 static void test_GdipCloneImage(void)
1188 GpImage
*image_src
, *image_dest
= NULL
;
1189 const INT WIDTH
= 10, HEIGHT
= 20;
1191 /* Create an image, clone it, delete the original, make sure the copy works */
1192 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
1194 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bm
, __LINE__
, FALSE
);
1196 image_src
= ((GpImage
*)bm
);
1197 stat
= GdipCloneImage(image_src
, &image_dest
);
1199 expect_rawformat(&ImageFormatMemoryBMP
, image_dest
, __LINE__
, FALSE
);
1201 stat
= GdipDisposeImage((GpImage
*)bm
);
1203 stat
= GdipGetImageBounds(image_dest
, &rectF
, &unit
);
1206 /* Treat FP values carefully */
1207 expectf((REAL
)WIDTH
, rectF
.Width
);
1208 expectf((REAL
)HEIGHT
, rectF
.Height
);
1210 stat
= GdipDisposeImage(image_dest
);
1214 static void test_testcontrol(void)
1220 stat
= GdipTestControl(TestControlGetBuildNumber
, ¶m
);
1222 ok(param
!= 0, "Build number expected, got %u\n", param
);
1225 static void test_fromhicon(void)
1227 static const BYTE bmp_bits
[1024];
1228 HBITMAP hbmMask
, hbmColor
;
1232 GpBitmap
*bitmap
= NULL
;
1238 stat
= GdipCreateBitmapFromHICON(NULL
, NULL
);
1239 expect(InvalidParameter
, stat
);
1240 stat
= GdipCreateBitmapFromHICON(NULL
, &bitmap
);
1241 expect(InvalidParameter
, stat
);
1243 /* color icon 1 bit */
1244 hbmMask
= CreateBitmap(16, 16, 1, 1, bmp_bits
);
1245 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1246 hbmColor
= CreateBitmap(16, 16, 1, 1, bmp_bits
);
1247 ok(hbmColor
!= 0, "CreateBitmap failed\n");
1251 info
.hbmMask
= hbmMask
;
1252 info
.hbmColor
= hbmColor
;
1253 hIcon
= CreateIconIndirect(&info
);
1254 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
1255 DeleteObject(hbmMask
);
1256 DeleteObject(hbmColor
);
1258 stat
= GdipCreateBitmapFromHICON(hIcon
, &bitmap
);
1260 broken(stat
== InvalidParameter
), /* Win98 */
1261 "Expected Ok, got %.8x\n", stat
);
1263 /* check attributes */
1264 stat
= GdipGetImageHeight((GpImage
*)bitmap
, &dim
);
1267 stat
= GdipGetImageWidth((GpImage
*)bitmap
, &dim
);
1270 stat
= GdipGetImageType((GpImage
*)bitmap
, &type
);
1272 expect(ImageTypeBitmap
, type
);
1273 stat
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
1275 expect(PixelFormat32bppARGB
, format
);
1277 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bitmap
, __LINE__
, FALSE
);
1278 GdipDisposeImage((GpImage
*)bitmap
);
1282 /* color icon 8 bpp */
1283 hbmMask
= CreateBitmap(16, 16, 1, 8, bmp_bits
);
1284 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1285 hbmColor
= CreateBitmap(16, 16, 1, 8, bmp_bits
);
1286 ok(hbmColor
!= 0, "CreateBitmap failed\n");
1290 info
.hbmMask
= hbmMask
;
1291 info
.hbmColor
= hbmColor
;
1292 hIcon
= CreateIconIndirect(&info
);
1293 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
1294 DeleteObject(hbmMask
);
1295 DeleteObject(hbmColor
);
1297 stat
= GdipCreateBitmapFromHICON(hIcon
, &bitmap
);
1300 /* check attributes */
1301 stat
= GdipGetImageHeight((GpImage
*)bitmap
, &dim
);
1304 stat
= GdipGetImageWidth((GpImage
*)bitmap
, &dim
);
1307 stat
= GdipGetImageType((GpImage
*)bitmap
, &type
);
1309 expect(ImageTypeBitmap
, type
);
1310 stat
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
1312 expect(PixelFormat32bppARGB
, format
);
1314 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bitmap
, __LINE__
, FALSE
);
1315 GdipDisposeImage((GpImage
*)bitmap
);
1321 static const unsigned char pngimage
[285] = {
1322 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
1323 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
1324 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
1325 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
1326 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
1327 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
1328 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
1331 static const unsigned char gifimage
[35] = {
1332 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
1333 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
1336 /* 1x1 pixel transparent gif */
1337 static const unsigned char transparentgif
[] = {
1338 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,
1339 0x00,0x00,0x00,0x21,0xf9,0x04,0x01,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,
1340 0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
1343 static const unsigned char bmpimage
[66] = {
1344 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
1345 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
1346 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
1347 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
1351 static const unsigned char jpgimage
[285] = {
1352 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
1353 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
1354 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
1355 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
1356 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
1357 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
1358 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
1359 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1360 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1361 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
1362 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
1363 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1364 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
1365 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
1366 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1367 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
1368 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
1369 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
1371 /* 1x1 pixel tiff */
1372 static const unsigned char tiffimage
[] = {
1373 0x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00,
1374 0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00,
1375 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1376 0x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01,
1377 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00,
1378 0x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00,
1379 0x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01,
1380 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00,
1381 0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00,
1382 0x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01,
1383 0x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00,
1384 0x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1385 0x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
1386 0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65,
1387 0x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74,
1388 0x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,
1391 /* 320x320 twip wmf */
1392 static const unsigned char wmfimage
[180] = {
1393 0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05,
1394 0x00,0x00,0x00,0x00,0xb1,0x52,0x01,0x00,0x09,0x00,0x00,0x03,0x4f,0x00,0x00,0x00,
1395 0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0b,0x02,0x00,0x00,
1396 0x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x02,0x40,0x01,0x40,0x01,0x04,0x00,0x00,0x00,
1397 0x02,0x01,0x01,0x00,0x04,0x00,0x00,0x00,0x04,0x01,0x0d,0x00,0x08,0x00,0x00,0x00,
1398 0xfa,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
1399 0x2d,0x01,0x00,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,0x01,0x00,0x00,0x00,0x00,0x00,
1400 0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x01,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,
1401 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x02,0x00,
1402 0x07,0x00,0x00,0x00,0x1b,0x04,0x40,0x01,0x40,0x01,0x00,0x00,0x00,0x00,0x04,0x00,
1403 0x00,0x00,0xf0,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0xf0,0x01,0x01,0x00,0x03,0x00,
1406 static void test_getrawformat(void)
1408 test_bufferrawformat((void*)pngimage
, sizeof(pngimage
), &ImageFormatPNG
, __LINE__
, FALSE
);
1409 test_bufferrawformat((void*)gifimage
, sizeof(gifimage
), &ImageFormatGIF
, __LINE__
, FALSE
);
1410 test_bufferrawformat((void*)bmpimage
, sizeof(bmpimage
), &ImageFormatBMP
, __LINE__
, FALSE
);
1411 test_bufferrawformat((void*)jpgimage
, sizeof(jpgimage
), &ImageFormatJPEG
, __LINE__
, FALSE
);
1412 test_bufferrawformat((void*)tiffimage
, sizeof(tiffimage
), &ImageFormatTIFF
, __LINE__
, FALSE
);
1413 test_bufferrawformat((void*)wmfimage
, sizeof(wmfimage
), &ImageFormatWMF
, __LINE__
, FALSE
);
1416 static void test_loadwmf(void)
1427 MetafileHeader header
;
1429 hglob
= GlobalAlloc (0, sizeof(wmfimage
));
1430 data
= GlobalLock (hglob
);
1431 memcpy(data
, wmfimage
, sizeof(wmfimage
));
1432 GlobalUnlock(hglob
); data
= NULL
;
1434 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
1435 ok(hres
== S_OK
, "Failed to create a stream\n");
1436 if(hres
!= S_OK
) return;
1438 stat
= GdipLoadImageFromStream(stream
, &img
);
1439 ok(stat
== Ok
, "Failed to create a Bitmap\n");
1441 IStream_Release(stream
);
1445 IStream_Release(stream
);
1447 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1449 todo_wine
expect(UnitPixel
, unit
);
1450 expectf(0.0, bounds
.X
);
1451 expectf(0.0, bounds
.Y
);
1452 todo_wine
expectf(320.0, bounds
.Width
);
1453 todo_wine
expectf(320.0, bounds
.Height
);
1455 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1457 todo_wine
expectf(1440.0, res
);
1459 stat
= GdipGetImageVerticalResolution(img
, &res
);
1461 todo_wine
expectf(1440.0, res
);
1463 memset(&header
, 0, sizeof(header
));
1464 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1468 todo_wine
expect(MetafileTypeWmfPlaceable
, header
.Type
);
1469 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1470 todo_wine
expect(0x300, header
.Version
);
1471 expect(0, header
.EmfPlusFlags
);
1472 todo_wine
expectf(1440.0, header
.DpiX
);
1473 todo_wine
expectf(1440.0, header
.DpiY
);
1474 expect(0, header
.X
);
1475 expect(0, header
.Y
);
1476 todo_wine
expect(320, header
.Width
);
1477 todo_wine
expect(320, header
.Height
);
1478 todo_wine
expect(1, U(header
).WmfHeader
.mtType
);
1479 expect(0, header
.EmfPlusHeaderSize
);
1480 expect(0, header
.LogicalDpiX
);
1481 expect(0, header
.LogicalDpiY
);
1484 GdipDisposeImage(img
);
1487 static void test_createfromwmf(void)
1495 MetafileHeader header
;
1497 hwmf
= SetMetaFileBitsEx(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
),
1498 wmfimage
+sizeof(WmfPlaceableFileHeader
));
1499 ok(hwmf
!= 0, "SetMetaFileBitsEx failed\n");
1501 stat
= GdipCreateMetafileFromWmf(hwmf
, TRUE
,
1502 (WmfPlaceableFileHeader
*)wmfimage
, (GpMetafile
**)&img
);
1505 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1507 expect(UnitPixel
, unit
);
1508 expectf(0.0, bounds
.X
);
1509 expectf(0.0, bounds
.Y
);
1510 expectf(320.0, bounds
.Width
);
1511 expectf(320.0, bounds
.Height
);
1513 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1515 expectf(1440.0, res
);
1517 stat
= GdipGetImageVerticalResolution(img
, &res
);
1519 expectf(1440.0, res
);
1521 memset(&header
, 0, sizeof(header
));
1522 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1526 todo_wine
expect(MetafileTypeWmfPlaceable
, header
.Type
);
1527 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1528 todo_wine
expect(0x300, header
.Version
);
1529 expect(0, header
.EmfPlusFlags
);
1530 todo_wine
expectf(1440.0, header
.DpiX
);
1531 todo_wine
expectf(1440.0, header
.DpiY
);
1532 expect(0, header
.X
);
1533 expect(0, header
.Y
);
1534 todo_wine
expect(320, header
.Width
);
1535 todo_wine
expect(320, header
.Height
);
1536 todo_wine
expect(1, U(header
).WmfHeader
.mtType
);
1537 expect(0, header
.EmfPlusHeaderSize
);
1538 expect(0, header
.LogicalDpiX
);
1539 expect(0, header
.LogicalDpiY
);
1542 GdipDisposeImage(img
);
1545 static void test_createfromwmf_noplaceable(void)
1551 hwmf
= SetMetaFileBitsEx(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
),
1552 wmfimage
+sizeof(WmfPlaceableFileHeader
));
1553 ok(hwmf
!= 0, "SetMetaFileBitsEx failed\n");
1555 stat
= GdipCreateMetafileFromWmf(hwmf
, TRUE
, NULL
, (GpMetafile
**)&img
);
1558 GdipDisposeImage(img
);
1561 static void test_resolution(void)
1565 GpGraphics
*graphics
;
1568 int screenxres
, screenyres
;
1571 stat
= GdipCreateBitmapFromScan0(1, 1, 32, PixelFormat24bppRGB
, NULL
, &bitmap
);
1574 /* test invalid values */
1575 stat
= GdipGetImageHorizontalResolution(NULL
, &res
);
1576 expect(InvalidParameter
, stat
);
1578 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, NULL
);
1579 expect(InvalidParameter
, stat
);
1581 stat
= GdipGetImageVerticalResolution(NULL
, &res
);
1582 expect(InvalidParameter
, stat
);
1584 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, NULL
);
1585 expect(InvalidParameter
, stat
);
1587 stat
= GdipBitmapSetResolution(NULL
, 96.0, 96.0);
1588 expect(InvalidParameter
, stat
);
1590 stat
= GdipBitmapSetResolution(bitmap
, 0.0, 0.0);
1591 expect(InvalidParameter
, stat
);
1593 /* defaults to screen resolution */
1594 screendc
= GetDC(0);
1596 screenxres
= GetDeviceCaps(screendc
, LOGPIXELSX
);
1597 screenyres
= GetDeviceCaps(screendc
, LOGPIXELSY
);
1599 ReleaseDC(0, screendc
);
1601 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1603 expectf((REAL
)screenxres
, res
);
1605 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1607 expectf((REAL
)screenyres
, res
);
1609 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1611 stat
= GdipGetDpiX(graphics
, &res
);
1613 expectf((REAL
)screenxres
, res
);
1614 stat
= GdipGetDpiY(graphics
, &res
);
1616 expectf((REAL
)screenyres
, res
);
1618 /* test changing the resolution */
1619 stat
= GdipBitmapSetResolution(bitmap
, screenxres
*2.0, screenyres
*3.0);
1622 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1624 expectf(screenxres
*2.0, res
);
1626 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1628 expectf(screenyres
*3.0, res
);
1630 stat
= GdipGetDpiX(graphics
, &res
);
1632 expectf((REAL
)screenxres
, res
);
1633 stat
= GdipGetDpiY(graphics
, &res
);
1635 expectf((REAL
)screenyres
, res
);
1637 stat
= GdipDeleteGraphics(graphics
);
1640 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1642 stat
= GdipGetDpiX(graphics
, &res
);
1644 expectf(screenxres
*2.0, res
);
1645 stat
= GdipGetDpiY(graphics
, &res
);
1647 expectf(screenyres
*3.0, res
);
1648 stat
= GdipDeleteGraphics(graphics
);
1651 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1655 static void test_createhbitmap(void)
1659 HBITMAP hbitmap
, oldhbitmap
;
1666 memset(bits
, 0x68, 640);
1669 stat
= GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB
, bits
, &bitmap
);
1672 /* test NULL values */
1673 stat
= GdipCreateHBITMAPFromBitmap(NULL
, &hbitmap
, 0);
1674 expect(InvalidParameter
, stat
);
1676 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, NULL
, 0);
1677 expect(InvalidParameter
, stat
);
1679 /* create HBITMAP */
1680 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1685 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1686 expect(sizeof(BITMAP
), ret
);
1688 expect(0, bm
.bmType
);
1689 expect(10, bm
.bmWidth
);
1690 expect(20, bm
.bmHeight
);
1691 expect(40, bm
.bmWidthBytes
);
1692 expect(1, bm
.bmPlanes
);
1693 expect(32, bm
.bmBitsPixel
);
1694 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1698 DWORD val
= *(DWORD
*)bm
.bmBits
;
1699 ok(val
== 0xff686868, "got %x, expected 0xff686868\n", val
);
1702 hdc
= CreateCompatibleDC(NULL
);
1704 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1705 pixel
= GetPixel(hdc
, 5, 5);
1706 SelectObject(hdc
, oldhbitmap
);
1710 expect(0x686868, pixel
);
1712 DeleteObject(hbitmap
);
1715 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1718 /* make (1,0) have no alpha and (2,0) a different blue value. */
1722 /* create alpha Bitmap */
1723 stat
= GdipCreateBitmapFromScan0(8, 20, 32, PixelFormat32bppARGB
, bits
, &bitmap
);
1726 /* create HBITMAP */
1727 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1732 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1733 expect(sizeof(BITMAP
), ret
);
1735 expect(0, bm
.bmType
);
1736 expect(8, bm
.bmWidth
);
1737 expect(20, bm
.bmHeight
);
1738 expect(32, bm
.bmWidthBytes
);
1739 expect(1, bm
.bmPlanes
);
1740 expect(32, bm
.bmBitsPixel
);
1741 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1745 DWORD val
= *(DWORD
*)bm
.bmBits
;
1746 ok(val
== 0x682a2a2a, "got %x, expected 0x682a2a2a\n", val
);
1747 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1748 ok(val
== 0x0, "got %x, expected 0x682a2a2a\n", val
);
1751 hdc
= CreateCompatibleDC(NULL
);
1753 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1754 pixel
= GetPixel(hdc
, 5, 5);
1755 expect(0x2a2a2a, pixel
);
1756 pixel
= GetPixel(hdc
, 1, 0);
1759 SelectObject(hdc
, oldhbitmap
);
1764 DeleteObject(hbitmap
);
1767 /* create HBITMAP with bkgnd colour */
1768 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0xff00ff);
1773 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1774 expect(sizeof(BITMAP
), ret
);
1776 expect(0, bm
.bmType
);
1777 expect(8, bm
.bmWidth
);
1778 expect(20, bm
.bmHeight
);
1779 expect(32, bm
.bmWidthBytes
);
1780 expect(1, bm
.bmPlanes
);
1781 expect(32, bm
.bmBitsPixel
);
1782 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1786 DWORD val
= *(DWORD
*)bm
.bmBits
;
1787 ok(val
== 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val
);
1788 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1789 ok(val
== 0xff00ff, "got %x, expected 0x682a2a2a\n", val
);
1792 hdc
= CreateCompatibleDC(NULL
);
1794 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1795 pixel
= GetPixel(hdc
, 5, 5);
1796 expect(0xc12ac1, pixel
);
1797 pixel
= GetPixel(hdc
, 1, 0);
1798 expect(0xff00ff, pixel
);
1799 pixel
= GetPixel(hdc
, 2, 0);
1800 expect(0xb12ac1, pixel
);
1802 SelectObject(hdc
, oldhbitmap
);
1804 DeleteObject(hbitmap
);
1807 /* create HBITMAP with bkgnd colour with alpha and show it behaves with no alpha. */
1808 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0x80ff00ff);
1813 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1814 expect(sizeof(BITMAP
), ret
);
1816 expect(0, bm
.bmType
);
1817 expect(8, bm
.bmWidth
);
1818 expect(20, bm
.bmHeight
);
1819 expect(32, bm
.bmWidthBytes
);
1820 expect(1, bm
.bmPlanes
);
1821 expect(32, bm
.bmBitsPixel
);
1822 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1826 DWORD val
= *(DWORD
*)bm
.bmBits
;
1827 ok(val
== 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val
);
1828 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1829 ok(val
== 0xff00ff, "got %x, expected 0x682a2a2a\n", val
);
1832 hdc
= CreateCompatibleDC(NULL
);
1834 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1835 pixel
= GetPixel(hdc
, 5, 5);
1836 expect(0xc12ac1, pixel
);
1837 pixel
= GetPixel(hdc
, 1, 0);
1838 expect(0xff00ff, pixel
);
1839 pixel
= GetPixel(hdc
, 2, 0);
1840 expect(0xb12ac1, pixel
);
1842 SelectObject(hdc
, oldhbitmap
);
1844 DeleteObject(hbitmap
);
1847 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1851 static void test_getthumbnail(void)
1854 GpImage
*bitmap1
, *bitmap2
;
1857 stat
= GdipGetImageThumbnail(NULL
, 0, 0, &bitmap2
, NULL
, NULL
);
1858 expect(InvalidParameter
, stat
);
1860 stat
= GdipCreateBitmapFromScan0(128, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1863 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, NULL
, NULL
, NULL
);
1864 expect(InvalidParameter
, stat
);
1866 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, &bitmap2
, NULL
, NULL
);
1871 stat
= GdipGetImageWidth(bitmap2
, &width
);
1875 stat
= GdipGetImageHeight(bitmap2
, &height
);
1877 expect(120, height
);
1879 GdipDisposeImage(bitmap2
);
1882 GdipDisposeImage(bitmap1
);
1885 stat
= GdipCreateBitmapFromScan0(64, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1888 stat
= GdipGetImageThumbnail(bitmap1
, 32, 32, &bitmap2
, NULL
, NULL
);
1893 stat
= GdipGetImageWidth(bitmap2
, &width
);
1897 stat
= GdipGetImageHeight(bitmap2
, &height
);
1901 GdipDisposeImage(bitmap2
);
1904 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, &bitmap2
, NULL
, NULL
);
1909 stat
= GdipGetImageWidth(bitmap2
, &width
);
1913 stat
= GdipGetImageHeight(bitmap2
, &height
);
1915 expect(120, height
);
1917 GdipDisposeImage(bitmap2
);
1920 GdipDisposeImage(bitmap1
);
1923 static void test_getsetpixel(void)
1928 BYTE bits
[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00,
1929 0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00};
1931 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, bits
, &bitmap
);
1934 /* null parameters */
1935 stat
= GdipBitmapGetPixel(NULL
, 1, 1, &color
);
1936 expect(InvalidParameter
, stat
);
1938 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, NULL
);
1939 expect(InvalidParameter
, stat
);
1941 stat
= GdipBitmapSetPixel(NULL
, 1, 1, 0);
1942 expect(InvalidParameter
, stat
);
1945 stat
= GdipBitmapGetPixel(bitmap
, -1, 1, &color
);
1946 expect(InvalidParameter
, stat
);
1948 stat
= GdipBitmapSetPixel(bitmap
, -1, 1, 0);
1949 expect(InvalidParameter
, stat
);
1951 stat
= GdipBitmapGetPixel(bitmap
, 1, -1, &color
);
1952 ok(stat
== InvalidParameter
||
1953 broken(stat
== Ok
), /* Older gdiplus */
1954 "Expected InvalidParameter, got %.8x\n", stat
);
1956 if (0) /* crashes some gdiplus implementations */
1958 stat
= GdipBitmapSetPixel(bitmap
, 1, -1, 0);
1959 ok(stat
== InvalidParameter
||
1960 broken(stat
== Ok
), /* Older gdiplus */
1961 "Expected InvalidParameter, got %.8x\n", stat
);
1964 stat
= GdipBitmapGetPixel(bitmap
, 2, 1, &color
);
1965 expect(InvalidParameter
, stat
);
1967 stat
= GdipBitmapSetPixel(bitmap
, 2, 1, 0);
1968 expect(InvalidParameter
, stat
);
1970 stat
= GdipBitmapGetPixel(bitmap
, 1, 2, &color
);
1971 expect(InvalidParameter
, stat
);
1973 stat
= GdipBitmapSetPixel(bitmap
, 1, 2, 0);
1974 expect(InvalidParameter
, stat
);
1977 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
1979 expect(0xffffffff, color
);
1981 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
1983 expect(0xff0000ff, color
);
1985 stat
= GdipBitmapSetPixel(bitmap
, 1, 1, 0xff676869);
1988 stat
= GdipBitmapSetPixel(bitmap
, 0, 0, 0xff474849);
1991 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
1993 expect(0xff676869, color
);
1995 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
1997 expect(0xff474849, color
);
1999 stat
= GdipDisposeImage((GpImage
*)bitmap
);
2003 static void check_halftone_palette(ColorPalette
*palette
)
2005 static const BYTE halftone_values
[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
2008 for (i
=0; i
<palette
->Count
; i
++)
2010 ARGB expected
=0xff000000;
2013 if (i
&1) expected
|= 0x800000;
2014 if (i
&2) expected
|= 0x8000;
2015 if (i
&4) expected
|= 0x80;
2019 expected
= 0xffc0c0c0;
2023 if (i
&1) expected
|= 0xff0000;
2024 if (i
&2) expected
|= 0xff00;
2025 if (i
&4) expected
|= 0xff;
2029 expected
= 0x00000000;
2033 expected
|= halftone_values
[(i
-40)%6];
2034 expected
|= halftone_values
[((i
-40)/6)%6] << 8;
2035 expected
|= halftone_values
[((i
-40)/36)%6] << 16;
2037 ok(expected
== palette
->Entries
[i
], "Expected %.8x, got %.8x, i=%u/%u\n",
2038 expected
, palette
->Entries
[i
], i
, palette
->Count
);
2042 static void test_palette(void)
2048 ColorPalette
*palette
=(ColorPalette
*)buffer
;
2049 ARGB
*entries
= palette
->Entries
;
2052 /* test initial palette from non-indexed bitmap */
2053 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, NULL
, &bitmap
);
2056 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2058 expect(sizeof(UINT
)*2+sizeof(ARGB
), size
);
2060 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2062 expect(0, palette
->Count
);
2064 /* test setting palette on not-indexed bitmap */
2067 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2070 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2072 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2074 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2076 expect(3, palette
->Count
);
2078 GdipDisposeImage((GpImage
*)bitmap
);
2080 /* test initial palette on 1-bit bitmap */
2081 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat1bppIndexed
, NULL
, &bitmap
);
2084 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2086 expect(sizeof(UINT
)*2+sizeof(ARGB
)*2, size
);
2088 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2090 expect(PaletteFlagsGrayScale
, palette
->Flags
);
2091 expect(2, palette
->Count
);
2093 expect(0xff000000, entries
[0]);
2094 expect(0xffffffff, entries
[1]);
2096 /* test getting/setting pixels */
2097 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2099 expect(0xff000000, color
);
2101 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffffffff);
2103 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2107 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2109 expect(0xffffffff, color
);
2112 GdipDisposeImage((GpImage
*)bitmap
);
2114 /* test initial palette on 4-bit bitmap */
2115 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat4bppIndexed
, NULL
, &bitmap
);
2118 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2120 expect(sizeof(UINT
)*2+sizeof(ARGB
)*16, size
);
2122 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2124 expect(0, palette
->Flags
);
2125 expect(16, palette
->Count
);
2127 check_halftone_palette(palette
);
2129 /* test getting/setting pixels */
2130 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2132 expect(0xff000000, color
);
2134 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffff00ff);
2136 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2140 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2142 expect(0xffff00ff, color
);
2145 GdipDisposeImage((GpImage
*)bitmap
);
2147 /* test initial palette on 8-bit bitmap */
2148 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat8bppIndexed
, NULL
, &bitmap
);
2151 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2153 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2155 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2157 expect(PaletteFlagsHalftone
, palette
->Flags
);
2158 expect(256, palette
->Count
);
2160 check_halftone_palette(palette
);
2162 /* test getting/setting pixels */
2163 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2165 expect(0xff000000, color
);
2167 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffcccccc);
2169 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2173 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2175 expect(0xffcccccc, color
);
2178 /* test setting/getting a different palette */
2179 entries
[1] = 0xffcccccc;
2181 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2186 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2188 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2190 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2192 expect(PaletteFlagsHalftone
, palette
->Flags
);
2193 expect(256, palette
->Count
);
2194 expect(0xffcccccc, entries
[1]);
2196 /* test count < 256 */
2197 palette
->Flags
= 12345;
2200 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2204 entries
[3] = 0xdeadbeef;
2206 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2208 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2210 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2212 expect(12345, palette
->Flags
);
2213 expect(3, palette
->Count
);
2214 expect(0xffcccccc, entries
[1]);
2215 expect(0xdeadbeef, entries
[3]);
2217 /* test count > 256 */
2218 palette
->Count
= 257;
2220 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2221 ok(stat
== InvalidParameter
||
2222 broken(stat
== Ok
), /* Old gdiplus behavior */
2223 "Expected %.8x, got %.8x\n", InvalidParameter
, stat
);
2225 GdipDisposeImage((GpImage
*)bitmap
);
2228 static void test_colormatrix(void)
2231 ColorMatrix colormatrix
, graymatrix
;
2232 GpImageAttributes
*imageattr
;
2233 const ColorMatrix identity
= {{
2234 {1.0,0.0,0.0,0.0,0.0},
2235 {0.0,1.0,0.0,0.0,0.0},
2236 {0.0,0.0,1.0,0.0,0.0},
2237 {0.0,0.0,0.0,1.0,0.0},
2238 {0.0,0.0,0.0,0.0,1.0}}};
2239 const ColorMatrix double_red
= {{
2240 {2.0,0.0,0.0,0.0,0.0},
2241 {0.0,1.0,0.0,0.0,0.0},
2242 {0.0,0.0,1.0,0.0,0.0},
2243 {0.0,0.0,0.0,1.0,0.0},
2244 {0.0,0.0,0.0,0.0,1.0}}};
2245 const ColorMatrix asymmetric
= {{
2246 {0.0,1.0,0.0,0.0,0.0},
2247 {0.0,0.0,1.0,0.0,0.0},
2248 {0.0,0.0,0.0,1.0,0.0},
2249 {1.0,0.0,0.0,0.0,0.0},
2250 {0.0,0.0,0.0,0.0,1.0}}};
2251 GpBitmap
*bitmap1
, *bitmap2
;
2252 GpGraphics
*graphics
;
2255 colormatrix
= identity
;
2256 graymatrix
= identity
;
2258 stat
= GdipSetImageAttributesColorMatrix(NULL
, ColorAdjustTypeDefault
,
2259 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2260 expect(InvalidParameter
, stat
);
2262 stat
= GdipCreateImageAttributes(&imageattr
);
2265 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2266 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2269 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2270 TRUE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2271 expect(InvalidParameter
, stat
);
2273 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2274 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2277 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2278 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsSkipGrays
);
2281 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2282 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsAltGray
);
2283 expect(InvalidParameter
, stat
);
2285 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2286 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsAltGray
);
2289 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2290 TRUE
, &colormatrix
, &graymatrix
, 3);
2291 expect(InvalidParameter
, stat
);
2293 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeCount
,
2294 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2295 expect(InvalidParameter
, stat
);
2297 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeAny
,
2298 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2299 expect(InvalidParameter
, stat
);
2301 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2302 FALSE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2305 /* Drawing a bitmap transforms the colors */
2306 colormatrix
= double_red
;
2307 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2308 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2311 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
2314 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
2317 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff40ccee);
2320 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2323 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2324 UnitPixel
, imageattr
, NULL
, NULL
);
2327 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2329 expect(0xff80ccee, color
);
2331 colormatrix
= asymmetric
;
2332 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2333 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2336 stat
= GdipBitmapSetPixel(bitmap2
, 0, 0, 0);
2339 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2340 UnitPixel
, imageattr
, NULL
, NULL
);
2343 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2345 ok(color_match(0xeeff40cc, color
, 3), "expected 0xeeff40cc, got 0x%08x\n", color
);
2347 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2350 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2351 UnitPixel
, imageattr
, NULL
, NULL
);
2354 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2356 ok(color_match(0xff40ccee, color
, 1), "Expected ff40ccee, got %.8x\n", color
);
2358 GdipDeleteGraphics(graphics
);
2359 GdipDisposeImage((GpImage
*)bitmap1
);
2360 GdipDisposeImage((GpImage
*)bitmap2
);
2361 GdipDisposeImageAttributes(imageattr
);
2364 static void test_gamma(void)
2367 GpImageAttributes
*imageattr
;
2368 GpBitmap
*bitmap1
, *bitmap2
;
2369 GpGraphics
*graphics
;
2372 stat
= GdipSetImageAttributesGamma(NULL
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2373 expect(InvalidParameter
, stat
);
2375 stat
= GdipCreateImageAttributes(&imageattr
);
2378 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2381 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeAny
, TRUE
, 1.0);
2382 expect(InvalidParameter
, stat
);
2384 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, -1.0);
2385 expect(InvalidParameter
, stat
);
2387 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.0);
2388 expect(InvalidParameter
, stat
);
2390 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.5);
2393 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0.0);
2396 /* Drawing a bitmap transforms the colors */
2397 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 3.0);
2400 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
2403 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
2406 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff80ffff);
2409 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2412 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2413 UnitPixel
, imageattr
, NULL
, NULL
);
2416 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2418 ok(color_match(0xff20ffff, color
, 1), "Expected ff20ffff, got %.8x\n", color
);
2420 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2423 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2424 UnitPixel
, imageattr
, NULL
, NULL
);
2427 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2429 ok(color_match(0xff80ffff, color
, 1), "Expected ff80ffff, got %.8x\n", color
);
2431 GdipDeleteGraphics(graphics
);
2432 GdipDisposeImage((GpImage
*)bitmap1
);
2433 GdipDisposeImage((GpImage
*)bitmap2
);
2434 GdipDisposeImageAttributes(imageattr
);
2437 /* 1x1 pixel gif, 2 frames; first frame is white, second is black */
2438 static const unsigned char gifanimation
[72] = {
2439 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
2440 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0xf9,0x04,0x00,0x0a,0x00,0xff,
2441 0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x4c,0x01,0x00,
2442 0x21,0xf9,0x04,0x01,0x0a,0x00,0x01,0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,
2443 0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
2446 /* Generated with ImageMagick:
2447 * convert -transparent black -delay 100 -size 8x2 xc:black \
2448 * -dispose none -page +0+0 -size 2x2 xc:red \
2449 * -dispose background -page +2+0 -size 2x2 xc:blue \
2450 * -dispose previous -page +4+0 -size 2x2 xc:green \
2451 * -dispose undefined -page +6+0 -size 2x2 xc:gray \
2454 static const unsigned char gifanimation2
[] = {
2455 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x08, 0x00,
2456 0x02, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
2457 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x64,
2458 0x00, 0x00, 0x00, 0x21, 0xff, 0x0b, 0x4e, 0x45,
2459 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e,
2460 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00,
2461 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
2462 0x02, 0x04, 0x84, 0x8f, 0x09, 0x05, 0x00, 0x21,
2463 0xf9, 0x04, 0x04, 0x64, 0x00, 0x00, 0x00, 0x2c,
2464 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2465 0x81, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
2466 0x00, 0x00, 0xff, 0x00, 0x00, 0x02, 0x03, 0x44,
2467 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x08, 0x64,
2468 0x00, 0x00, 0x00, 0x2c, 0x02, 0x00, 0x00, 0x00,
2469 0x02, 0x00, 0x02, 0x00, 0x81, 0x00, 0x00, 0xff,
2470 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
2471 0xff, 0x02, 0x03, 0x44, 0x34, 0x05, 0x00, 0x21,
2472 0xf9, 0x04, 0x0c, 0x64, 0x00, 0x00, 0x00, 0x2c,
2473 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2474 0x81, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00,
2475 0x80, 0x00, 0x00, 0x80, 0x00, 0x02, 0x03, 0x44,
2476 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x64,
2477 0x00, 0x00, 0x00, 0x2c, 0x06, 0x00, 0x00, 0x00,
2478 0x02, 0x00, 0x02, 0x00, 0x80, 0x7e, 0x7e, 0x7e,
2479 0x00, 0x00, 0x00, 0x02, 0x02, 0x84, 0x51, 0x00,
2483 static ARGB gifanimation2_pixels
[5][4] = {
2485 {0xffff0000, 0, 0, 0},
2486 {0xffff0000, 0xff0000ff, 0, 0},
2487 {0xffff0000, 0, 0xff008000, 0},
2488 {0xffff0000, 0, 0, 0xff7e7e7e}
2491 static void test_multiframegif(void)
2502 PixelFormat pixel_format
;
2503 INT palette_size
, i
, j
;
2504 char palette_buf
[256];
2505 ColorPalette
*palette
;
2506 ARGB
*palette_entries
;
2508 /* Test frame functions with an animated GIF */
2509 hglob
= GlobalAlloc (0, sizeof(gifanimation
));
2510 data
= GlobalLock (hglob
);
2511 memcpy(data
, gifanimation
, sizeof(gifanimation
));
2512 GlobalUnlock(hglob
);
2514 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2515 ok(hres
== S_OK
, "Failed to create a stream\n");
2516 if(hres
!= S_OK
) return;
2518 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2519 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2521 IStream_Release(stream
);
2525 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2527 expect(PixelFormat32bppARGB
, pixel_format
);
2529 stat
= GdipGetImagePaletteSize((GpImage
*)bmp
, &palette_size
);
2531 ok(palette_size
== sizeof(ColorPalette
) ||
2532 broken(palette_size
== sizeof(ColorPalette
)+sizeof(ARGB
[3])),
2533 "palette_size = %d\n", palette_size
);
2535 /* Bitmap starts at frame 0 */
2537 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2539 expect(0xffffffff, color
);
2541 /* Check that we get correct metadata */
2542 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2546 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2548 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2551 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2555 /* SelectActiveFrame overwrites our current data */
2556 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2560 GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2562 expect(0xff000000, color
);
2564 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2568 GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2570 expect(0xffffffff, color
);
2572 /* Write over the image data */
2573 stat
= GdipBitmapSetPixel(bmp
, 0, 0, 0xff000000);
2576 /* Switching to the same frame does not overwrite our changes */
2577 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2580 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2582 expect(0xff000000, color
);
2584 /* But switching to another frame and back does */
2585 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2588 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2591 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2593 expect(0xffffffff, color
);
2595 /* rotate/flip discards the information about other frames */
2596 stat
= GdipImageRotateFlip((GpImage
*)bmp
, Rotate90FlipNone
);
2600 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2604 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bmp
, __LINE__
, FALSE
);
2606 GdipDisposeImage((GpImage
*)bmp
);
2607 IStream_Release(stream
);
2609 /* Test with a non-animated gif */
2610 hglob
= GlobalAlloc (0, sizeof(gifimage
));
2611 data
= GlobalLock (hglob
);
2612 memcpy(data
, gifimage
, sizeof(gifimage
));
2613 GlobalUnlock(hglob
);
2615 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2616 ok(hres
== S_OK
, "Failed to create a stream\n");
2617 if(hres
!= S_OK
) return;
2619 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2620 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2622 IStream_Release(stream
);
2626 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2628 expect(PixelFormat8bppIndexed
, pixel_format
);
2630 /* Check metadata */
2631 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2635 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2637 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2640 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2644 GdipDisposeImage((GpImage
*)bmp
);
2645 IStream_Release(stream
);
2647 /* Test with a non-animated transparent gif */
2648 hglob
= GlobalAlloc (0, sizeof(transparentgif
));
2649 data
= GlobalLock (hglob
);
2650 memcpy(data
, transparentgif
, sizeof(transparentgif
));
2651 GlobalUnlock(hglob
);
2653 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2654 ok(hres
== S_OK
, "Failed to create a stream\n");
2656 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2657 IStream_Release(stream
);
2658 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2660 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2662 expect(PixelFormat8bppIndexed
, pixel_format
);
2664 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2668 stat
= GdipGetImagePaletteSize((GpImage
*)bmp
, &palette_size
);
2670 ok(palette_size
== sizeof(ColorPalette
)+sizeof(ARGB
),
2671 "palette_size = %d\n", palette_size
);
2673 memset(palette_buf
, 0xfe, sizeof(palette_buf
));
2674 palette
= (ColorPalette
*)palette_buf
;
2675 stat
= GdipGetImagePalette((GpImage
*)bmp
, palette
,
2676 sizeof(ColorPalette
)+sizeof(ARGB
));
2677 palette_entries
= palette
->Entries
;
2679 expect(PaletteFlagsHasAlpha
, palette
->Flags
);
2680 expect(2, palette
->Count
);
2681 expect(0, palette_entries
[0]);
2682 expect(0xff000000, palette_entries
[1]);
2685 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2689 GdipDisposeImage((GpImage
*)bmp
);
2691 /* Test frame dispose methods */
2692 hglob
= GlobalAlloc (0, sizeof(gifanimation2
));
2693 data
= GlobalLock (hglob
);
2694 memcpy(data
, gifanimation2
, sizeof(gifanimation2
));
2695 GlobalUnlock(hglob
);
2697 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2698 ok(hres
== S_OK
, "Failed to create a stream\n");
2700 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2701 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2702 IStream_Release(stream
);
2704 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2706 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2708 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2712 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2716 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 3);
2718 stat
= GdipBitmapGetPixel(bmp
, 2, 0, &color
);
2720 ok(color
==0 || broken(color
==0xff0000ff), "color = %x\n", color
);
2722 win_skip("broken animated gif support\n");
2723 GdipDisposeImage((GpImage
*)bmp
);
2727 for(i
=0; i
<6; i
++) {
2728 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, i
%5);
2731 for(j
=0; j
<4; j
++) {
2732 stat
= GdipBitmapGetPixel(bmp
, j
*2, 0, &color
);
2734 ok(gifanimation2_pixels
[i
%5][j
] == color
, "at %d,%d got %x, expected %x\n", i
, j
, color
, gifanimation2_pixels
[i
%5][j
]);
2738 GdipDisposeImage((GpImage
*)bmp
);
2741 static void test_rotateflip(void)
2746 static const BYTE orig_bits
[24] = {
2747 0,0,0xff, 0,0xff,0, 0xff,0,0, 23,23,23,
2748 0xff,0xff,0, 0xff,0,0xff, 0,0xff,0xff, 23,23,23};
2752 memcpy(bits
, orig_bits
, sizeof(bits
));
2753 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2756 stat
= GdipImageRotateFlip(bitmap
, Rotate90FlipNone
);
2759 stat
= GdipGetImageWidth(bitmap
, &width
);
2761 stat
= GdipGetImageHeight(bitmap
, &height
);
2766 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2768 expect(0xff00ffff, color
);
2770 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 0, &color
);
2772 expect(0xffff0000, color
);
2774 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 2, &color
);
2776 expect(0xffffff00, color
);
2778 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 2, &color
);
2780 expect(0xff0000ff, color
);
2784 expect(0xff, bits
[2]);
2786 GdipDisposeImage(bitmap
);
2788 memcpy(bits
, orig_bits
, sizeof(bits
));
2789 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2792 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipX
);
2795 stat
= GdipGetImageWidth(bitmap
, &width
);
2797 stat
= GdipGetImageHeight(bitmap
, &height
);
2802 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2804 expect(0xff0000ff, color
);
2806 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
2808 expect(0xffff0000, color
);
2810 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
2812 expect(0xffffff00, color
);
2814 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
2816 expect(0xff00ffff, color
);
2820 expect(0xff, bits
[2]);
2822 GdipDisposeImage(bitmap
);
2824 memcpy(bits
, orig_bits
, sizeof(bits
));
2825 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2828 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipY
);
2831 stat
= GdipGetImageWidth(bitmap
, &width
);
2833 stat
= GdipGetImageHeight(bitmap
, &height
);
2838 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2840 expect(0xff00ffff, color
);
2842 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
2844 expect(0xffffff00, color
);
2846 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
2848 expect(0xffff0000, color
);
2850 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
2852 expect(0xff0000ff, color
);
2856 expect(0xff, bits
[2]);
2858 GdipDisposeImage(bitmap
);
2861 static void test_remaptable(void)
2864 GpImageAttributes
*imageattr
;
2865 GpBitmap
*bitmap1
, *bitmap2
;
2866 GpGraphics
*graphics
;
2870 map
= GdipAlloc(sizeof(ColorMap
));
2872 map
->oldColor
.Argb
= 0xff00ff00;
2873 map
->newColor
.Argb
= 0xffff00ff;
2875 stat
= GdipSetImageAttributesRemapTable(NULL
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
2876 expect(InvalidParameter
, stat
);
2878 stat
= GdipCreateImageAttributes(&imageattr
);
2881 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, NULL
);
2882 expect(InvalidParameter
, stat
);
2884 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeCount
, TRUE
, 1, map
);
2885 expect(InvalidParameter
, stat
);
2887 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeAny
, TRUE
, 1, map
);
2888 expect(InvalidParameter
, stat
);
2890 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0, map
);
2891 expect(InvalidParameter
, stat
);
2893 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0, NULL
);
2896 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
2899 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
2902 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
2905 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff00ff00);
2908 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2911 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2912 UnitPixel
, imageattr
, NULL
, NULL
);
2915 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2917 ok(color_match(0xffff00ff, color
, 1), "Expected ffff00ff, got %.8x\n", color
);
2919 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2922 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2923 UnitPixel
, imageattr
, NULL
, NULL
);
2926 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2928 ok(color_match(0xff00ff00, color
, 1), "Expected ff00ff00, got %.8x\n", color
);
2930 GdipDeleteGraphics(graphics
);
2931 GdipDisposeImage((GpImage
*)bitmap1
);
2932 GdipDisposeImage((GpImage
*)bitmap2
);
2933 GdipDisposeImageAttributes(imageattr
);
2937 static void test_colorkey(void)
2940 GpImageAttributes
*imageattr
;
2941 GpBitmap
*bitmap1
, *bitmap2
;
2942 GpGraphics
*graphics
;
2945 stat
= GdipSetImageAttributesColorKeys(NULL
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
2946 expect(InvalidParameter
, stat
);
2948 stat
= GdipCreateImageAttributes(&imageattr
);
2951 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeCount
, TRUE
, 0xff405060, 0xff708090);
2952 expect(InvalidParameter
, stat
);
2954 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeAny
, TRUE
, 0xff405060, 0xff708090);
2955 expect(InvalidParameter
, stat
);
2957 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
2960 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
2963 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
2966 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0x20405060);
2969 stat
= GdipBitmapSetPixel(bitmap1
, 0, 1, 0x40506070);
2972 stat
= GdipBitmapSetPixel(bitmap1
, 1, 0, 0x60708090);
2975 stat
= GdipBitmapSetPixel(bitmap1
, 1, 1, 0xffffffff);
2978 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2981 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
2982 UnitPixel
, imageattr
, NULL
, NULL
);
2985 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2987 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
2989 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
2991 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
2993 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
2995 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
2997 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
2999 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
3001 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
3004 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
3005 UnitPixel
, imageattr
, NULL
, NULL
);
3008 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
3010 ok(color_match(0x20405060, color
, 1), "Expected 20405060, got %.8x\n", color
);
3012 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
3014 ok(color_match(0x40506070, color
, 1), "Expected 40506070, got %.8x\n", color
);
3016 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
3018 ok(color_match(0x60708090, color
, 1), "Expected 60708090, got %.8x\n", color
);
3020 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
3022 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
3025 GdipDeleteGraphics(graphics
);
3026 GdipDisposeImage((GpImage
*)bitmap1
);
3027 GdipDisposeImage((GpImage
*)bitmap2
);
3028 GdipDisposeImageAttributes(imageattr
);
3031 static void test_dispose(void)
3035 char invalid_image
[256];
3037 stat
= GdipDisposeImage(NULL
);
3038 expect(InvalidParameter
, stat
);
3040 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, (GpBitmap
**)&image
);
3043 stat
= GdipDisposeImage(image
);
3046 stat
= GdipDisposeImage(image
);
3047 expect(ObjectBusy
, stat
);
3049 memset(invalid_image
, 0, 256);
3050 stat
= GdipDisposeImage((GpImage
*)invalid_image
);
3051 expect(ObjectBusy
, stat
);
3054 static LONG
obj_refcount(void *obj
)
3056 IUnknown_AddRef((IUnknown
*)obj
);
3057 return IUnknown_Release((IUnknown
*)obj
);
3060 static GpImage
*load_image(const BYTE
*image_data
, UINT image_size
)
3067 GpImage
*image
= NULL
, *clone
;
3068 ImageType image_type
;
3069 LONG refcount
, old_refcount
;
3071 hmem
= GlobalAlloc(0, image_size
);
3072 data
= GlobalLock(hmem
);
3073 memcpy(data
, image_data
, image_size
);
3076 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
3077 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
3078 if (hr
!= S_OK
) return NULL
;
3080 refcount
= obj_refcount(stream
);
3081 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3083 status
= GdipLoadImageFromStream(stream
, &image
);
3084 ok(status
== Ok
|| broken(status
== InvalidParameter
), /* XP */
3085 "GdipLoadImageFromStream error %d\n", status
);
3088 IStream_Release(stream
);
3092 status
= GdipGetImageType(image
, &image_type
);
3093 ok(status
== Ok
, "GdipGetImageType error %d\n", status
);
3095 refcount
= obj_refcount(stream
);
3096 if (image_type
== ImageTypeBitmap
)
3097 ok(refcount
> 1, "expected stream refcount > 1, got %d\n", refcount
);
3099 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3100 old_refcount
= refcount
;
3102 status
= GdipCloneImage(image
, &clone
);
3103 ok(status
== Ok
, "GdipCloneImage error %d\n", status
);
3104 refcount
= obj_refcount(stream
);
3105 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3106 status
= GdipDisposeImage(clone
);
3107 ok(status
== Ok
, "GdipDisposeImage error %d\n", status
);
3108 refcount
= obj_refcount(stream
);
3109 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3111 refcount
= IStream_Release(stream
);
3112 if (image_type
== ImageTypeBitmap
)
3113 ok(refcount
>= 1, "expected stream refcount != 0\n");
3115 ok(refcount
== 0, "expected stream refcount 0, got %d\n", refcount
);
3120 static void test_image_properties(void)
3122 static const struct test_data
3124 const BYTE
*image_data
;
3126 ImageType image_type
;
3128 UINT prop_count2
; /* if win7 behaves differently */
3129 /* 1st property attributes */
3131 UINT prop_size2
; /* if win7 behaves differently */
3133 UINT prop_id2
; /* if win7 behaves differently */
3137 { pngimage
, sizeof(pngimage
), ImageTypeBitmap
, 4, ~0, 1, 20, 0x5110, 0x132 },
3138 { jpgimage
, sizeof(jpgimage
), ImageTypeBitmap
, 2, ~0, 128, 0, 0x5090, 0x5091 },
3139 { tiffimage
, sizeof(tiffimage
), ImageTypeBitmap
, 16, 0, 4, 0, 0xfe, 0 },
3140 { bmpimage
, sizeof(bmpimage
), ImageTypeBitmap
, 0, 0, 0, 0, 0, 0 },
3141 { wmfimage
, sizeof(wmfimage
), ImageTypeMetafile
, 0, 0, 0, 0, 0, 0 }
3145 UINT prop_count
, prop_size
, i
;
3146 PROPID prop_id
[16] = { 0 };
3147 ImageType image_type
;
3154 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
3156 image
= load_image(td
[i
].image_data
, td
[i
].image_size
);
3159 trace("%u: failed to load image data\n", i
);
3163 status
= GdipGetImageType(image
, &image_type
);
3164 ok(status
== Ok
, "%u: GdipGetImageType error %d\n", i
, status
);
3165 ok(td
[i
].image_type
== image_type
, "%u: expected image_type %d, got %d\n",
3166 i
, td
[i
].image_type
, image_type
);
3168 status
= GdipGetPropertyCount(image
, &prop_count
);
3169 ok(status
== Ok
, "%u: GdipGetPropertyCount error %d\n", i
, status
);
3170 if (td
[i
].image_data
== pngimage
|| td
[i
].image_data
== jpgimage
)
3172 ok(td
[i
].prop_count
== prop_count
|| td
[i
].prop_count2
== prop_count
,
3173 " %u: expected property count %u or %u, got %u\n",
3174 i
, td
[i
].prop_count
, td
[i
].prop_count2
, prop_count
);
3176 ok(td
[i
].prop_count
== prop_count
|| td
[i
].prop_count2
== prop_count
,
3177 " %u: expected property count %u or %u, got %u\n",
3178 i
, td
[i
].prop_count
, td
[i
].prop_count2
, prop_count
);
3180 status
= GdipGetPropertyItemSize(NULL
, 0, &prop_size
);
3181 expect(InvalidParameter
, status
);
3182 status
= GdipGetPropertyItemSize(image
, 0, NULL
);
3183 expect(InvalidParameter
, status
);
3184 status
= GdipGetPropertyItemSize(image
, 0, &prop_size
);
3185 if (image_type
== ImageTypeMetafile
)
3186 expect(NotImplemented
, status
);
3188 expect(PropertyNotFound
, status
);
3190 status
= GdipGetPropertyItem(NULL
, 0, 0, &item
.data
);
3191 expect(InvalidParameter
, status
);
3192 status
= GdipGetPropertyItem(image
, 0, 0, NULL
);
3193 expect(InvalidParameter
, status
);
3194 status
= GdipGetPropertyItem(image
, 0, 0, &item
.data
);
3195 if (image_type
== ImageTypeMetafile
)
3196 expect(NotImplemented
, status
);
3198 expect(PropertyNotFound
, status
);
3200 /* FIXME: remove once Wine is fixed */
3201 if (td
[i
].prop_count
!= prop_count
)
3203 GdipDisposeImage(image
);
3207 status
= GdipGetPropertyIdList(NULL
, prop_count
, prop_id
);
3208 expect(InvalidParameter
, status
);
3209 status
= GdipGetPropertyIdList(image
, prop_count
, NULL
);
3210 expect(InvalidParameter
, status
);
3211 status
= GdipGetPropertyIdList(image
, 0, prop_id
);
3212 if (image_type
== ImageTypeMetafile
)
3213 expect(NotImplemented
, status
);
3214 else if (prop_count
== 0)
3217 expect(InvalidParameter
, status
);
3218 status
= GdipGetPropertyIdList(image
, prop_count
- 1, prop_id
);
3219 if (image_type
== ImageTypeMetafile
)
3220 expect(NotImplemented
, status
);
3222 expect(InvalidParameter
, status
);
3223 status
= GdipGetPropertyIdList(image
, prop_count
+ 1, prop_id
);
3224 if (image_type
== ImageTypeMetafile
)
3225 expect(NotImplemented
, status
);
3227 expect(InvalidParameter
, status
);
3228 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3229 if (image_type
== ImageTypeMetafile
)
3230 expect(NotImplemented
, status
);
3234 if (prop_count
!= 0)
3235 ok(td
[i
].prop_id
== prop_id
[0] || td
[i
].prop_id2
== prop_id
[0],
3236 " %u: expected property id %#x or %#x, got %#x\n",
3237 i
, td
[i
].prop_id
, td
[i
].prop_id2
, prop_id
[0]);
3242 status
= GdipGetPropertyItemSize(image
, prop_id
[0], &prop_size
);
3243 if (prop_count
== 0)
3244 expect(PropertyNotFound
, status
);
3249 assert(sizeof(item
) >= prop_size
);
3250 ok(prop_size
> sizeof(PropertyItem
), "%u: got too small prop_size %u\n",
3252 ok(td
[i
].prop_size
+ sizeof(PropertyItem
) == prop_size
||
3253 td
[i
].prop_size2
+ sizeof(PropertyItem
) == prop_size
,
3254 " %u: expected property size %u or %u, got %u\n",
3255 i
, td
[i
].prop_size
, td
[i
].prop_size2
, prop_size
);
3257 status
= GdipGetPropertyItem(image
, prop_id
[0], 0, &item
.data
);
3258 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3259 "%u: expected InvalidParameter, got %d\n", i
, status
);
3260 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
- 1, &item
.data
);
3261 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3262 "%u: expected InvalidParameter, got %d\n", i
, status
);
3263 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
+ 1, &item
.data
);
3264 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3265 "%u: expected InvalidParameter, got %d\n", i
, status
);
3266 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
, &item
.data
);
3268 ok(prop_id
[0] == item
.data
.id
,
3269 "%u: expected property id %#x, got %#x\n", i
, prop_id
[0], item
.data
.id
);
3273 GdipDisposeImage(image
);
3281 #define IFD_RATIONAL 5
3283 #define IFD_UNDEFINED 7
3284 #define IFD_SSHORT 8
3286 #define IFD_SRATIONAL 10
3287 #define IFD_FLOAT 11
3288 #define IFD_DOUBLE 12
3290 #ifndef PropertyTagTypeSByte
3291 #define PropertyTagTypeSByte 6
3292 #define PropertyTagTypeSShort 8
3293 #define PropertyTagTypeFloat 11
3294 #define PropertyTagTypeDouble 12
3297 static UINT
documented_type(UINT type
)
3301 case PropertyTagTypeSByte
: return PropertyTagTypeByte
;
3302 case PropertyTagTypeSShort
: return PropertyTagTypeShort
;
3303 case PropertyTagTypeFloat
: return PropertyTagTypeUndefined
;
3304 case PropertyTagTypeDouble
: return PropertyTagTypeUndefined
;
3305 default: return type
;
3309 #include "pshpack2.h"
3324 static const struct tiff_data
3329 USHORT number_of_entries
;
3330 struct IFD_entry entry
[40];
3332 struct IFD_rational xres
;
3334 struct IFD_rational srational_val
;
3339 struct IFD_rational rational
[3];
3343 #ifdef WORDS_BIGENDIAN
3349 FIELD_OFFSET(struct tiff_data
, number_of_entries
),
3352 { 0xff, IFD_SHORT
, 1, 0 }, /* SUBFILETYPE */
3353 { 0x100, IFD_LONG
, 1, 1 }, /* IMAGEWIDTH */
3354 { 0x101, IFD_LONG
, 1, 1 }, /* IMAGELENGTH */
3355 { 0x102, IFD_SHORT
, 1, 1 }, /* BITSPERSAMPLE */
3356 { 0x103, IFD_SHORT
, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
3357 { 0x106, IFD_SHORT
, 1, 1 }, /* PHOTOMETRIC */
3358 { 0x111, IFD_LONG
, 1, FIELD_OFFSET(struct tiff_data
, pixel_data
) }, /* STRIPOFFSETS */
3359 { 0x115, IFD_SHORT
, 1, 1 }, /* SAMPLESPERPIXEL */
3360 { 0x116, IFD_LONG
, 1, 1 }, /* ROWSPERSTRIP */
3361 { 0x117, IFD_LONG
, 1, 1 }, /* STRIPBYTECOUNT */
3362 { 0x11a, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3363 { 0x11b, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3364 { 0x128, IFD_SHORT
, 1, 2 }, /* RESOLUTIONUNIT */
3365 { 0xf001, IFD_BYTE
, 1, 0x11223344 },
3366 { 0xf002, IFD_BYTE
, 4, 0x11223344 },
3367 { 0xf003, IFD_SBYTE
, 1, 0x11223344 },
3368 { 0xf004, IFD_SSHORT
, 1, 0x11223344 },
3369 { 0xf005, IFD_SSHORT
, 2, 0x11223344 },
3370 { 0xf006, IFD_SLONG
, 1, 0x11223344 },
3371 { 0xf007, IFD_FLOAT
, 1, 0x11223344 },
3372 { 0xf008, IFD_DOUBLE
, 1, FIELD_OFFSET(struct tiff_data
, double_val
) },
3373 { 0xf009, IFD_SRATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, srational_val
) },
3374 { 0xf00a, IFD_BYTE
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3375 { 0xf00b, IFD_SSHORT
, 4, FIELD_OFFSET(struct tiff_data
, short_val
) },
3376 { 0xf00c, IFD_SLONG
, 2, FIELD_OFFSET(struct tiff_data
, long_val
) },
3377 { 0xf00e, IFD_ASCII
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3378 { 0xf00f, IFD_ASCII
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3379 { 0xf010, IFD_UNDEFINED
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3380 { 0xf011, IFD_UNDEFINED
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3381 /* Some gdiplus versions ignore these fields.
3382 { 0xf012, IFD_BYTE, 0, 0x11223344 },
3383 { 0xf013, IFD_SHORT, 0, 0x11223344 },
3384 { 0xf014, IFD_LONG, 0, 0x11223344 },
3385 { 0xf015, IFD_FLOAT, 0, 0x11223344 },*/
3386 { 0xf016, IFD_SRATIONAL
, 3, FIELD_OFFSET(struct tiff_data
, rational
) },
3387 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3388 { 0xf017, IFD_FLOAT
, 2, FIELD_OFFSET(struct tiff_data
, float_val
) },
3392 1234567890.0987654321,
3393 { 0x1a2b3c4d, 0x5a6b7c8d },
3395 { 0x0101, 0x0202, 0x0303, 0x0404 },
3396 { 0x11223344, 0x55667788 },
3397 { (FLOAT
)1234.5678, (FLOAT
)8765.4321 },
3398 { { 0x01020304, 0x05060708 }, { 0x10203040, 0x50607080 }, { 0x11223344, 0x55667788 } },
3399 { 0x11, 0x22, 0x33, 0 }
3401 #include "poppack.h"
3403 static void test_tiff_properties(void)
3405 static const struct test_data
3407 ULONG type
, id
, length
;
3408 const BYTE value
[24];
3411 { PropertyTagTypeShort
, 0xff, 2, { 0 } },
3412 { PropertyTagTypeLong
, 0x100, 4, { 1 } },
3413 { PropertyTagTypeLong
, 0x101, 4, { 1 } },
3414 { PropertyTagTypeShort
, 0x102, 2, { 1 } },
3415 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3416 { PropertyTagTypeShort
, 0x106, 2, { 1 } },
3417 { PropertyTagTypeLong
, 0x111, 4, { 0x44,0x02 } },
3418 { PropertyTagTypeShort
, 0x115, 2, { 1 } },
3419 { PropertyTagTypeLong
, 0x116, 4, { 1 } },
3420 { PropertyTagTypeLong
, 0x117, 4, { 1 } },
3421 { PropertyTagTypeRational
, 0x11a, 8, { 0x84,0x03,0,0,0x03 } },
3422 { PropertyTagTypeRational
, 0x11b, 8, { 0x84,0x03,0,0,0x03 } },
3423 { PropertyTagTypeShort
, 0x128, 2, { 2 } },
3424 { PropertyTagTypeByte
, 0xf001, 1, { 0x44 } },
3425 { PropertyTagTypeByte
, 0xf002, 4, { 0x44,0x33,0x22,0x11 } },
3426 { PropertyTagTypeSByte
, 0xf003, 1, { 0x44 } },
3427 { PropertyTagTypeSShort
, 0xf004, 2, { 0x44,0x33 } },
3428 { PropertyTagTypeSShort
, 0xf005, 4, { 0x44,0x33,0x22,0x11 } },
3429 { PropertyTagTypeSLONG
, 0xf006, 4, { 0x44,0x33,0x22,0x11 } },
3430 { PropertyTagTypeFloat
, 0xf007, 4, { 0x44,0x33,0x22,0x11 } },
3431 { PropertyTagTypeDouble
, 0xf008, 8, { 0x2c,0x52,0x86,0xb4,0x80,0x65,0xd2,0x41 } },
3432 { PropertyTagTypeSRational
, 0xf009, 8, { 0x4d, 0x3c, 0x2b, 0x1a, 0x8d, 0x7c, 0x6b, 0x5a } },
3433 { PropertyTagTypeByte
, 0xf00a, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3434 { PropertyTagTypeSShort
, 0xf00b, 8, { 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04 } },
3435 { PropertyTagTypeSLONG
, 0xf00c, 8, { 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3436 { PropertyTagTypeASCII
, 0xf00e, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3437 { PropertyTagTypeASCII
, 0xf00f, 5, { 'a','b','c','d' } },
3438 { PropertyTagTypeUndefined
, 0xf010, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3439 { PropertyTagTypeUndefined
, 0xf011, 4, { 'a','b','c','d' } },
3440 { PropertyTagTypeSRational
, 0xf016, 24,
3441 { 0x04,0x03,0x02,0x01,0x08,0x07,0x06,0x05,
3442 0x40,0x30,0x20,0x10,0x80,0x70,0x60,0x50,
3443 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3444 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3445 { PropertyTagTypeFloat
, 0xf017, 8, { 0x2b,0x52,0x9a,0x44,0xba,0xf5,0x08,0x46 } },
3450 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3452 PropertyItem
*prop_item
;
3454 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
));
3457 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3461 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3463 expect(1, dim_count
);
3465 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3467 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3469 frame_count
= 0xdeadbeef;
3470 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3472 expect(1, frame_count
);
3474 prop_count
= 0xdeadbeef;
3475 status
= GdipGetPropertyCount(image
, &prop_count
);
3477 ok(prop_count
== sizeof(td
)/sizeof(td
[0]) ||
3478 broken(prop_count
== sizeof(td
)/sizeof(td
[0]) - 1) /* Win7 SP0 */,
3479 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
3481 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3483 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3486 for (i
= 0; i
< prop_count
; i
++)
3488 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &prop_size
);
3490 if (status
!= Ok
) break;
3491 ok(prop_size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, prop_size
);
3493 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, prop_size
);
3494 status
= GdipGetPropertyItem(image
, prop_id
[i
], prop_size
, prop_item
);
3496 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3497 ok(td
[i
].type
== prop_item
->type
||
3498 /* Win7 stopped using proper but not documented types, and it
3499 looks broken since TypeFloat and TypeDouble now reported as
3500 TypeUndefined, and signed types reported as unsigned. */
3501 broken(prop_item
->type
== documented_type(td
[i
].type
)),
3502 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3503 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3504 prop_size
-= sizeof(*prop_item
);
3505 ok(prop_item
->length
== prop_size
, "%u: expected length %u, got %u\n", i
, prop_size
, prop_item
->length
);
3506 ok(td
[i
].length
== prop_item
->length
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_item
->length
+1) /* XP */,
3507 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3508 ok(td
[i
].length
== prop_size
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_size
+1) /* XP */,
3509 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_size
);
3510 if (td
[i
].length
== prop_item
->length
)
3512 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3513 ok(match
|| broken(td
[i
].length
<= 4 && !match
), "%u: data mismatch\n", i
);
3517 BYTE
*data
= prop_item
->value
;
3518 trace("id %#x:", prop_item
->id
);
3519 for (j
= 0; j
< prop_item
->length
; j
++)
3520 trace(" %02x", data
[j
]);
3524 HeapFree(GetProcessHeap(), 0, prop_item
);
3527 HeapFree(GetProcessHeap(), 0, prop_id
);
3529 GdipDisposeImage(image
);
3532 static void test_GdipGetAllPropertyItems(void)
3534 static const struct test_data
3536 ULONG type
, id
, length
;
3540 { PropertyTagTypeLong
, 0xfe, 4, { 0 } },
3541 { PropertyTagTypeShort
, 0x100, 2, { 1 } },
3542 { PropertyTagTypeShort
, 0x101, 2, { 1 } },
3543 { PropertyTagTypeShort
, 0x102, 6, { 8,0,8,0,8,0 } },
3544 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3545 { PropertyTagTypeShort
, 0x106, 2, { 2,0 } },
3546 { PropertyTagTypeASCII
, 0x10d, 27, "/home/meh/Desktop/test.tif" },
3547 { PropertyTagTypeLong
, 0x111, 4, { 8,0,0,0 } },
3548 { PropertyTagTypeShort
, 0x112, 2, { 1 } },
3549 { PropertyTagTypeShort
, 0x115, 2, { 3,0 } },
3550 { PropertyTagTypeShort
, 0x116, 2, { 0x40,0 } },
3551 { PropertyTagTypeLong
, 0x117, 4, { 3,0,0,0 } },
3552 { PropertyTagTypeRational
, 0x11a, 8, { 0,0,0,72,0,0,0,1 } },
3553 { PropertyTagTypeRational
, 0x11b, 8, { 0,0,0,72,0,0,0,1 } },
3554 { PropertyTagTypeShort
, 0x11c, 2, { 1 } },
3555 { PropertyTagTypeShort
, 0x128, 2, { 2 } }
3560 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3561 UINT total_size
, total_count
;
3563 PropertyItem
*prop_item
;
3564 const char *item_data
;
3566 image
= load_image(tiffimage
, sizeof(tiffimage
));
3567 ok(image
!= 0, "Failed to load TIFF image data\n");
3570 dim_count
= 0xdeadbeef;
3571 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3573 expect(1, dim_count
);
3575 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3577 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3579 frame_count
= 0xdeadbeef;
3580 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3582 expect(1, frame_count
);
3584 prop_count
= 0xdeadbeef;
3585 status
= GdipGetPropertyCount(image
, &prop_count
);
3587 ok(prop_count
== sizeof(td
)/sizeof(td
[0]),
3588 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
3590 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3592 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3596 for (i
= 0; i
< prop_count
; i
++)
3599 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
3601 if (status
!= Ok
) break;
3602 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
3606 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
3607 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
3609 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3610 ok(td
[i
].type
== prop_item
->type
,
3611 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3612 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3613 size
-= sizeof(*prop_item
);
3614 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
3615 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3616 if (td
[i
].length
== prop_item
->length
)
3618 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3619 ok(match
, "%u: data mismatch\n", i
);
3623 BYTE
*data
= prop_item
->value
;
3624 trace("id %#x:", prop_item
->id
);
3625 for (j
= 0; j
< prop_item
->length
; j
++)
3626 trace(" %02x", data
[j
]);
3630 HeapFree(GetProcessHeap(), 0, prop_item
);
3633 HeapFree(GetProcessHeap(), 0, prop_id
);
3635 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
3636 expect(InvalidParameter
, status
);
3637 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
3638 expect(InvalidParameter
, status
);
3639 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
3640 expect(InvalidParameter
, status
);
3641 status
= GdipGetPropertySize(image
, NULL
, NULL
);
3642 expect(InvalidParameter
, status
);
3643 total_size
= 0xdeadbeef;
3644 total_count
= 0xdeadbeef;
3645 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
3647 ok(prop_count
== total_count
,
3648 "expected total property count %u, got %u\n", prop_count
, total_count
);
3649 ok(prop_size
== total_size
,
3650 "expected total property size %u, got %u\n", prop_size
, total_size
);
3652 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
3654 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
3655 expect(InvalidParameter
, status
);
3656 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
3657 expect(InvalidParameter
, status
);
3658 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3659 expect(InvalidParameter
, status
);
3660 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3661 expect(InvalidParameter
, status
);
3662 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
3663 expect(InvalidParameter
, status
);
3664 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
3665 expect(InvalidParameter
, status
);
3666 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
3669 item_data
= (const char *)(prop_item
+ prop_count
);
3670 for (i
= 0; i
< prop_count
; i
++)
3672 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
3673 i
, item_data
, prop_item
[i
].value
);
3674 ok(td
[i
].type
== prop_item
[i
].type
,
3675 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
3676 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
3677 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
3678 if (td
[i
].length
== prop_item
[i
].length
)
3680 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
3681 ok(match
, "%u: data mismatch\n", i
);
3685 BYTE
*data
= prop_item
[i
].value
;
3686 trace("id %#x:", prop_item
[i
].id
);
3687 for (j
= 0; j
< prop_item
[i
].length
; j
++)
3688 trace(" %02x", data
[j
]);
3692 item_data
+= prop_item
[i
].length
;
3695 HeapFree(GetProcessHeap(), 0, prop_item
);
3697 GdipDisposeImage(image
);
3700 static void test_tiff_palette(void)
3711 ARGB
*entries
= palette
.pal
.Entries
;
3713 /* 1bpp TIFF without palette */
3714 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
));
3717 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3721 status
= GdipGetImagePixelFormat(image
, &format
);
3723 ok(format
== PixelFormat1bppIndexed
, "expected PixelFormat1bppIndexed, got %#x\n", format
);
3725 status
= GdipGetImagePaletteSize(image
, &size
);
3726 ok(status
== Ok
|| broken(status
== GenericError
), /* XP */
3727 "GdipGetImagePaletteSize error %d\n", status
);
3728 if (status
== GenericError
)
3730 GdipDisposeImage(image
);
3733 expect(sizeof(ColorPalette
) + sizeof(ARGB
), size
);
3735 status
= GdipGetImagePalette(image
, &palette
.pal
, size
);
3737 expect(0, palette
.pal
.Flags
);
3738 expect(2, palette
.pal
.Count
);
3739 if (palette
.pal
.Count
== 2)
3741 ok(entries
[0] == 0xff000000, "expected 0xff000000, got %#x\n", entries
[0]);
3742 ok(entries
[1] == 0xffffffff, "expected 0xffffffff, got %#x\n", entries
[1]);
3745 GdipDisposeImage(image
);
3748 static void test_bitmapbits(void)
3751 static const BYTE pixels_24
[48] =
3753 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3754 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3755 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3756 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0
3758 static const BYTE pixels_00
[48] =
3760 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3761 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3762 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3763 0,0,0, 0,0,0, 0,0,0, 0,0,0
3765 static const BYTE pixels_24_77
[64] =
3767 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3768 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3769 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3770 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3771 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3772 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3774 static const BYTE pixels_77
[64] =
3776 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3777 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3778 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3779 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3780 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3781 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3782 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3783 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3785 static const BYTE pixels_8
[16] =
3787 0x01,0,0x01,0,0x01,0,0x01,0,
3788 0x01,0,0x01,0,0x01,0,0x01,0
3790 static const BYTE pixels_8_77
[64] =
3792 0x01,0,0x01,0,0x01,0,0x01,0,
3793 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3794 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3795 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3796 0x01,0,0x01,0,0x01,0,0x01,0,
3797 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3798 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3799 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3801 static const BYTE pixels_1_77
[64] =
3803 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3804 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3805 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3806 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3807 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3808 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3809 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3810 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3812 static const BYTE pixels_1
[8] = {0xaa,0,0,0,0xaa,0,0,0};
3813 static const struct test_data
3820 const BYTE
*pixels_unlocked
;
3824 { PixelFormat24bppRGB
, 24, 0xfff0, 24, 48, pixels_24
, pixels_00
},
3826 { PixelFormat24bppRGB
, 24, 0, 24, 48, pixels_24
, pixels_00
},
3827 { PixelFormat24bppRGB
, 24, ImageLockModeRead
, 24, 48, pixels_24
, pixels_00
},
3828 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
3829 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
3830 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_24_77
, pixels_24
},
3831 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3832 { PixelFormat24bppRGB
, 24, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3834 { PixelFormat8bppIndexed
, 8, 0, 8, 16, pixels_8
, pixels_24
},
3835 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
, 8, 16, pixels_8
, pixels_24
},
3836 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
3837 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
3838 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_8_77
, pixels_24
},
3839 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3840 { PixelFormat8bppIndexed
, 8, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3842 { PixelFormat1bppIndexed
, 1, 0, 4, 8, pixels_1
, pixels_24
},
3843 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
, 4, 8, pixels_1
, pixels_24
},
3844 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
3845 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
3846 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_1_77
, pixels_24
},
3847 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3848 { PixelFormat1bppIndexed
, 1, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3860 ARGB
*entries
= palette
.pal
.Entries
;
3862 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
3864 BYTE pixels
[sizeof(pixels_24
)];
3865 memcpy(pixels
, pixels_24
, sizeof(pixels_24
));
3866 status
= GdipCreateBitmapFromScan0(8, 2, 24, PixelFormat24bppRGB
, pixels
, &bitmap
);
3869 /* associate known palette with pixel data */
3870 palette
.pal
.Flags
= PaletteFlagsGrayScale
;
3871 palette
.pal
.Count
= 2;
3872 entries
[0] = 0xff000000;
3873 entries
[1] = 0xffffffff;
3874 status
= GdipSetImagePalette((GpImage
*)bitmap
, &palette
.pal
);
3877 memset(&data
, 0xfe, sizeof(data
));
3878 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
3880 memset(buf
, 0x77, sizeof(buf
));
3884 status
= GdipBitmapLockBits(bitmap
, NULL
, td
[i
].mode
, td
[i
].format
, &data
);
3885 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* XP */, "%u: GdipBitmapLockBits error %d\n", i
, status
);
3888 GdipDisposeImage((GpImage
*)bitmap
);
3891 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
3892 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
3893 ok(td
[i
].stride
== data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].stride
, data
.Stride
);
3894 ok(td
[i
].format
== data
.PixelFormat
, "%u: expected %d, got %d\n", i
, td
[i
].format
, data
.PixelFormat
);
3895 ok(td
[i
].size
== data
.Height
* data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].size
, data
.Height
* data
.Stride
);
3896 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
3897 ok(data
.Scan0
== buf
, "%u: got wrong buffer\n", i
);
3898 if (td
[i
].size
== data
.Height
* data
.Stride
)
3900 UINT j
, match
, width_bytes
= (data
.Width
* td
[i
].bpp
) / 8;
3903 for (j
= 0; j
< data
.Height
; j
++)
3905 if (memcmp((const BYTE
*)data
.Scan0
+ j
* data
.Stride
, td
[i
].pixels
+ j
* data
.Stride
, width_bytes
) != 0)
3911 if ((td
[i
].mode
& (ImageLockModeRead
|ImageLockModeUserInputBuf
)) || td
[i
].format
== PixelFormat24bppRGB
)
3914 "%u: data should match\n", i
);
3917 BYTE
*bits
= data
.Scan0
;
3918 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
3919 for (j
= 0; j
< td
[i
].size
; j
++)
3920 trace(" %02x", bits
[j
]);
3925 ok(!match
, "%u: data shouldn't match\n", i
);
3927 memset(data
.Scan0
, 0, td
[i
].size
);
3930 status
= GdipBitmapUnlockBits(bitmap
, &data
);
3931 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
3933 memset(&data
, 0xfe, sizeof(data
));
3934 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
3935 ok(status
== Ok
, "%u: GdipBitmapLockBits error %d\n", i
, status
);
3936 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
3937 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
3938 ok(data
.Stride
== 24, "%u: expected 24, got %d\n", i
, data
.Stride
);
3939 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "%u: got wrong pixel format %d\n", i
, data
.PixelFormat
);
3940 ok(data
.Height
* data
.Stride
== 48, "%u: expected 48, got %d\n", i
, data
.Height
* data
.Stride
);
3941 if (data
.Height
* data
.Stride
== 48)
3943 int match
= memcmp(data
.Scan0
, td
[i
].pixels_unlocked
, 48) == 0;
3944 ok(match
, "%u: data should match\n", i
);
3948 BYTE
*bits
= data
.Scan0
;
3949 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
3950 for (j
= 0; j
< 48; j
++)
3951 trace(" %02x", bits
[j
]);
3956 status
= GdipBitmapUnlockBits(bitmap
, &data
);
3957 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
3959 status
= GdipDisposeImage((GpImage
*)bitmap
);
3964 static void test_DrawImage(void)
3966 BYTE black_1x1
[4] = { 0,0,0,0 };
3967 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
3968 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
3969 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
3970 0,0,0,0,0,0,0xff,0xff };
3977 GpGraphics
*graphics
;
3980 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
3982 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
3985 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
3987 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
3989 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
3991 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
3994 status
= GdipDrawImageI(graphics
, u1
.image
, 0, 0);
3997 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
3998 ok(match
, "data should match\n");
4001 UINT i
, size
= sizeof(white_2x2
);
4002 BYTE
*bits
= white_2x2
;
4003 for (i
= 0; i
< size
; i
++)
4004 trace(" %02x", bits
[i
]);
4008 status
= GdipDeleteGraphics(graphics
);
4010 status
= GdipDisposeImage(u1
.image
);
4012 status
= GdipDisposeImage(u2
.image
);
4016 static void test_DrawImage_SourceCopy(void)
4018 DWORD dst_pixels
[4] = { 0xffffffff, 0xffffffff,
4019 0xffffffff, 0xffffffff };
4020 DWORD src_pixels
[4] = { 0, 0xffff0000,
4029 GpGraphics
*graphics
;
4031 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB
, (BYTE
*)dst_pixels
, &u1
.bitmap
);
4034 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB
, (BYTE
*)src_pixels
, &u2
.bitmap
);
4036 status
= GdipGetImageGraphicsContext(u1
.image
, &graphics
);
4038 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4041 status
= GdipSetCompositingMode(graphics
, CompositingModeSourceCopy
);
4044 status
= GdipDrawImageI(graphics
, u2
.image
, 0, 0);
4047 todo_wine
expect(0, dst_pixels
[0]);
4048 expect(0xffff0000, dst_pixels
[1]);
4049 todo_wine
expect(0, dst_pixels
[2]);
4050 todo_wine
expect(0, dst_pixels
[3]);
4052 status
= GdipDeleteGraphics(graphics
);
4054 status
= GdipDisposeImage(u1
.image
);
4056 status
= GdipDisposeImage(u2
.image
);
4060 static void test_GdipDrawImagePointRect(void)
4062 BYTE black_1x1
[4] = { 0,0,0,0 };
4063 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
4064 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
4065 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
4066 0,0,0,0,0,0,0xff,0xff };
4073 GpGraphics
*graphics
;
4076 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
4078 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4081 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
4083 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
4085 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4087 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4090 status
= GdipDrawImagePointRectI(graphics
, u1
.image
, 0, 0, 0, 0, 1, 1, UnitPixel
);
4093 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
4094 ok(match
, "data should match\n");
4097 UINT i
, size
= sizeof(white_2x2
);
4098 BYTE
*bits
= white_2x2
;
4099 for (i
= 0; i
< size
; i
++)
4100 trace(" %02x", bits
[i
]);
4104 status
= GdipDeleteGraphics(graphics
);
4106 status
= GdipDisposeImage(u1
.image
);
4108 status
= GdipDisposeImage(u2
.image
);
4112 static void test_image_format(void)
4114 static const PixelFormat fmt
[] =
4116 PixelFormat1bppIndexed
, PixelFormat4bppIndexed
, PixelFormat8bppIndexed
,
4117 PixelFormat16bppGrayScale
, PixelFormat16bppRGB555
, PixelFormat16bppRGB565
,
4118 PixelFormat16bppARGB1555
, PixelFormat24bppRGB
, PixelFormat32bppRGB
,
4119 PixelFormat32bppARGB
, PixelFormat32bppPARGB
, PixelFormat48bppRGB
,
4120 PixelFormat64bppARGB
, PixelFormat64bppPARGB
, PixelFormat32bppCMYK
4131 for (i
= 0; i
< sizeof(fmt
)/sizeof(fmt
[0]); i
++)
4133 status
= GdipCreateBitmapFromScan0(1, 1, 0, fmt
[i
], NULL
, &bitmap
);
4134 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* before win7 */,
4135 "GdipCreateBitmapFromScan0 error %d\n", status
);
4136 if (status
!= Ok
) continue;
4138 status
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
4140 expect(fmt
[i
], format
);
4142 status
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
4143 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4144 todo_wine
expect(InvalidParameter
, status
);
4148 ret
= GetObjectW(hbitmap
, sizeof(bm
), &bm
);
4149 expect(sizeof(bm
), ret
);
4150 expect(0, bm
.bmType
);
4151 expect(1, bm
.bmWidth
);
4152 expect(1, bm
.bmHeight
);
4153 expect(4, bm
.bmWidthBytes
);
4154 expect(1, bm
.bmPlanes
);
4155 expect(32, bm
.bmBitsPixel
);
4156 DeleteObject(hbitmap
);
4159 status
= GdipGetImageThumbnail((GpImage
*)bitmap
, 0, 0, &thumb
, NULL
, NULL
);
4160 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4162 ok(status
== OutOfMemory
|| broken(status
== InvalidParameter
) /* before win7 */,
4163 "expected OutOfMemory, got %d\n", status
);
4168 status
= GdipGetImagePixelFormat(thumb
, &format
);
4170 ok(format
== PixelFormat32bppPARGB
|| broken(format
!= PixelFormat32bppPARGB
) /* before win7 */,
4171 "expected PixelFormat32bppPARGB, got %#x\n", format
);
4172 status
= GdipDisposeImage(thumb
);
4176 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4177 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4178 todo_wine
expect(InvalidParameter
, status
);
4182 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4186 status
= GdipDisposeImage((GpImage
*)bitmap
);
4191 static void test_DrawImage_scale(void)
4193 static const BYTE back_8x1
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
4194 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4195 static const BYTE image_080
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,
4196 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4197 static const BYTE image_100
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,
4198 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4199 static const BYTE image_120
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,
4200 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4201 static const BYTE image_150
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4202 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4203 static const BYTE image_180
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4204 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4205 static const BYTE image_200
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4206 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4207 static const BYTE image_250
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,
4208 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4209 static const BYTE image_120_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4210 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4211 static const BYTE image_150_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4212 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4213 static const BYTE image_200_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4214 0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40 };
4215 static const BYTE image_250_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4216 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4217 static const struct test_data
4220 PixelOffsetMode pixel_offset_mode
;
4225 { 0.8, PixelOffsetModeNone
, image_080
}, /* 0 */
4226 { 1.0, PixelOffsetModeNone
, image_100
},
4227 { 1.2, PixelOffsetModeNone
, image_120
},
4228 { 1.5, PixelOffsetModeNone
, image_150
},
4229 { 1.8, PixelOffsetModeNone
, image_180
},
4230 { 2.0, PixelOffsetModeNone
, image_200
},
4231 { 2.5, PixelOffsetModeNone
, image_250
},
4233 { 0.8, PixelOffsetModeHighSpeed
, image_080
}, /* 7 */
4234 { 1.0, PixelOffsetModeHighSpeed
, image_100
},
4235 { 1.2, PixelOffsetModeHighSpeed
, image_120
},
4236 { 1.5, PixelOffsetModeHighSpeed
, image_150
},
4237 { 1.8, PixelOffsetModeHighSpeed
, image_180
},
4238 { 2.0, PixelOffsetModeHighSpeed
, image_200
},
4239 { 2.5, PixelOffsetModeHighSpeed
, image_250
},
4241 { 0.8, PixelOffsetModeHalf
, image_080
}, /* 14 */
4242 { 1.0, PixelOffsetModeHalf
, image_100
},
4243 { 1.2, PixelOffsetModeHalf
, image_120_half
, TRUE
},
4244 { 1.5, PixelOffsetModeHalf
, image_150_half
, TRUE
},
4245 { 1.8, PixelOffsetModeHalf
, image_180
},
4246 { 2.0, PixelOffsetModeHalf
, image_200_half
, TRUE
},
4247 { 2.5, PixelOffsetModeHalf
, image_250_half
, TRUE
},
4249 { 0.8, PixelOffsetModeHighQuality
, image_080
}, /* 21 */
4250 { 1.0, PixelOffsetModeHighQuality
, image_100
},
4251 { 1.2, PixelOffsetModeHighQuality
, image_120_half
, TRUE
},
4252 { 1.5, PixelOffsetModeHighQuality
, image_150_half
, TRUE
},
4253 { 1.8, PixelOffsetModeHighQuality
, image_180
},
4254 { 2.0, PixelOffsetModeHighQuality
, image_200_half
, TRUE
},
4255 { 2.5, PixelOffsetModeHighQuality
, image_250_half
, TRUE
},
4257 BYTE src_2x1
[6] = { 0x80,0x80,0x80,0x80,0x80,0x80 };
4265 GpGraphics
*graphics
;
4269 status
= GdipCreateBitmapFromScan0(2, 1, 4, PixelFormat24bppRGB
, src_2x1
, &u1
.bitmap
);
4271 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4274 status
= GdipCreateBitmapFromScan0(8, 1, 24, PixelFormat24bppRGB
, dst_8x1
, &u2
.bitmap
);
4276 status
= GdipBitmapSetResolution(u2
.bitmap
, 100.0, 100.0);
4278 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4280 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4283 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
4285 status
= GdipSetPixelOffsetMode(graphics
, td
[i
].pixel_offset_mode
);
4288 status
= GdipCreateMatrix2(td
[i
].scale_x
, 0.0, 0.0, 1.0, 0.0, 0.0, &matrix
);
4290 status
= GdipSetWorldTransform(graphics
, matrix
);
4292 GdipDeleteMatrix(matrix
);
4294 memcpy(dst_8x1
, back_8x1
, sizeof(dst_8x1
));
4295 status
= GdipDrawImageI(graphics
, u1
.image
, 1, 0);
4298 match
= memcmp(dst_8x1
, td
[i
].image
, sizeof(dst_8x1
)) == 0;
4299 todo_wine_if (!match
&& td
[i
].todo
)
4300 ok(match
, "%d: data should match\n", i
);
4303 UINT i
, size
= sizeof(dst_8x1
);
4304 const BYTE
*bits
= dst_8x1
;
4305 for (i
= 0; i
< size
; i
++)
4306 trace(" %02x", bits
[i
]);
4311 status
= GdipDeleteGraphics(graphics
);
4313 status
= GdipDisposeImage(u1
.image
);
4315 status
= GdipDisposeImage(u2
.image
);
4319 static const BYTE animatedgif
[] = {
4320 'G','I','F','8','9','a',0x01,0x00,0x01,0x00,0xA1,0x02,0x00,
4321 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
4322 /*0x21,0xFF,0x0B,'A','N','I','M','E','X','T','S','1','.','0',*/
4323 0x21,0xFF,0x0B,'N','E','T','S','C','A','P','E','2','.','0',
4324 0x03,0x01,0x05,0x00,0x00,
4325 0x21,0xFE,0x0C,'H','e','l','l','o',' ','W','o','r','l','d','!',0x00,
4326 0x21,0x01,0x0D,'a','n','i','m','a','t','i','o','n','.','g','i','f',0x00,
4327 0x21,0xF9,0x04,0xff,0x0A,0x00,0x08,0x00,
4328 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4329 0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,
4330 0x02,0x02,0x4C,0x01,0x00,
4331 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','1',0x00,
4332 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','1',0x00,
4333 0x21,0xF9,0x04,0x00,0x14,0x00,0x01,0x00,
4334 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4335 0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,
4336 0x02,0x02,0x44,0x01,0x00,
4337 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','2',0x00,
4338 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','2',0x00,0x3B
4341 static void test_gif_properties(void)
4343 static const struct test_data
4345 ULONG type
, id
, length
;
4346 const BYTE value
[13];
4349 { PropertyTagTypeLong
, PropertyTagFrameDelay
, 8, { 10,0,0,0,20,0,0,0 } },
4350 { PropertyTagTypeASCII
, PropertyTagExifUserComment
, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
4351 { PropertyTagTypeShort
, PropertyTagLoopCount
, 2, { 5,0 } },
4352 { PropertyTagTypeByte
, PropertyTagGlobalPalette
, 12, { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c } },
4353 { PropertyTagTypeByte
, PropertyTagIndexBackground
, 1, { 2 } },
4354 { PropertyTagTypeByte
, PropertyTagIndexTransparent
, 1, { 8 } }
4359 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
4360 UINT total_size
, total_count
;
4362 PropertyItem
*prop_item
;
4363 const char *item_data
;
4365 image
= load_image(animatedgif
, sizeof(animatedgif
));
4366 if (!image
) /* XP fails to load this GIF image */
4368 trace("Failed to load GIF image data\n");
4372 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
4374 expect(1, dim_count
);
4376 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
4378 expect_guid(&FrameDimensionTime
, &guid
, __LINE__
, FALSE
);
4380 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
4382 expect(2, frame_count
);
4384 status
= GdipImageSelectActiveFrame(image
, &guid
, 1);
4387 status
= GdipGetPropertyCount(image
, &prop_count
);
4389 ok(prop_count
== sizeof(td
)/sizeof(td
[0]) || broken(prop_count
== 1) /* before win7 */,
4390 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
4392 if (prop_count
!= sizeof(td
)/sizeof(td
[0]))
4394 GdipDisposeImage(image
);
4398 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
4400 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
4404 for (i
= 0; i
< prop_count
; i
++)
4407 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
4409 if (status
!= Ok
) break;
4410 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
4414 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
4415 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
4417 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
4418 ok(td
[i
].type
== prop_item
->type
,
4419 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
4420 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
4421 size
-= sizeof(*prop_item
);
4422 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
4423 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
4424 if (td
[i
].length
== prop_item
->length
)
4426 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
4427 ok(match
, "%u: data mismatch\n", i
);
4431 BYTE
*data
= prop_item
->value
;
4432 trace("id %#x:", prop_item
->id
);
4433 for (j
= 0; j
< prop_item
->length
; j
++)
4434 trace(" %02x", data
[j
]);
4438 HeapFree(GetProcessHeap(), 0, prop_item
);
4441 HeapFree(GetProcessHeap(), 0, prop_id
);
4443 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
4444 expect(InvalidParameter
, status
);
4445 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
4446 expect(InvalidParameter
, status
);
4447 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
4448 expect(InvalidParameter
, status
);
4449 status
= GdipGetPropertySize(image
, NULL
, NULL
);
4450 expect(InvalidParameter
, status
);
4451 total_size
= 0xdeadbeef;
4452 total_count
= 0xdeadbeef;
4453 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
4455 ok(prop_count
== total_count
,
4456 "expected total property count %u, got %u\n", prop_count
, total_count
);
4457 ok(prop_size
== total_size
,
4458 "expected total property size %u, got %u\n", prop_size
, total_size
);
4460 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
4462 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
4463 expect(InvalidParameter
, status
);
4464 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
4465 expect(InvalidParameter
, status
);
4466 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4467 expect(InvalidParameter
, status
);
4468 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4469 expect(InvalidParameter
, status
);
4470 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
4471 expect(InvalidParameter
, status
);
4472 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
4473 expect(InvalidParameter
, status
);
4474 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
4477 item_data
= (const char *)(prop_item
+ prop_count
);
4478 for (i
= 0; i
< prop_count
; i
++)
4480 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
4481 i
, item_data
, prop_item
[i
].value
);
4482 ok(td
[i
].type
== prop_item
[i
].type
,
4483 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
4484 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
4485 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
4486 if (td
[i
].length
== prop_item
[i
].length
)
4488 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
4489 ok(match
, "%u: data mismatch\n", i
);
4493 BYTE
*data
= prop_item
[i
].value
;
4494 trace("id %#x:", prop_item
[i
].id
);
4495 for (j
= 0; j
< prop_item
[i
].length
; j
++)
4496 trace(" %02x", data
[j
]);
4500 item_data
+= prop_item
[i
].length
;
4503 HeapFree(GetProcessHeap(), 0, prop_item
);
4505 GdipDisposeImage(image
);
4508 static void test_ARGB_conversion(void)
4510 BYTE argb
[8] = { 0x11,0x22,0x33,0x80, 0xff,0xff,0xff,0 };
4511 BYTE pargb
[8] = { 0x09,0x11,0x1a,0x80, 0,0,0,0 };
4512 BYTE rgb32_xp
[8] = { 0x11,0x22,0x33,0xff, 0xff,0xff,0xff,0xff };
4513 BYTE rgb24
[6] = { 0x11,0x22,0x33, 0xff,0xff,0xff };
4520 status
= GdipCreateBitmapFromScan0(2, 1, 8, PixelFormat32bppARGB
, argb
, &bitmap
);
4523 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4525 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4526 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4527 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4528 ok(data
.PixelFormat
== PixelFormat32bppPARGB
, "expected PixelFormat32bppPARGB, got %d\n", data
.PixelFormat
);
4529 match
= !memcmp(data
.Scan0
, pargb
, sizeof(pargb
));
4530 ok(match
, "bits don't match\n");
4534 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppPARGB
,
4535 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4537 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4540 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppRGB
, &data
);
4542 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4543 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4544 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4545 ok(data
.PixelFormat
== PixelFormat32bppRGB
, "expected PixelFormat32bppRGB, got %d\n", data
.PixelFormat
);
4546 match
= !memcmp(data
.Scan0
, argb
, sizeof(argb
)) ||
4547 !memcmp(data
.Scan0
, rgb32_xp
, sizeof(rgb32_xp
));
4548 ok(match
, "bits don't match\n");
4552 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppRGB
,
4553 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4555 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4558 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
4560 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4561 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4562 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4563 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "expected PixelFormat24bppRGB, got %d\n", data
.PixelFormat
);
4564 match
= !memcmp(data
.Scan0
, rgb24
, sizeof(rgb24
));
4565 ok(match
, "bits don't match\n");
4569 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat24bppRGB
,
4570 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4572 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4575 GdipDisposeImage((GpImage
*)bitmap
);
4579 static void test_CloneBitmapArea(void)
4582 GpBitmap
*bitmap
, *copy
;
4583 BitmapData data
, data2
;
4585 status
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB
, NULL
, &bitmap
);
4588 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
| ImageLockModeWrite
, PixelFormat24bppRGB
, &data
);
4591 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data2
);
4592 expect(WrongState
, status
);
4594 status
= GdipCloneBitmapAreaI(0, 0, 1, 1, PixelFormat24bppRGB
, bitmap
, ©
);
4597 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4600 GdipDisposeImage((GpImage
*)copy
);
4601 GdipDisposeImage((GpImage
*)bitmap
);
4604 static BOOL
get_encoder_clsid(LPCWSTR mime
, GUID
*format
, CLSID
*clsid
)
4607 UINT n_codecs
, info_size
, i
;
4608 ImageCodecInfo
*info
;
4611 status
= GdipGetImageEncodersSize(&n_codecs
, &info_size
);
4614 info
= GdipAlloc(info_size
);
4616 status
= GdipGetImageEncoders(n_codecs
, info_size
, info
);
4619 for (i
= 0; i
< n_codecs
; i
++)
4621 if (!lstrcmpW(info
[i
].MimeType
, mime
))
4623 *format
= info
[i
].FormatID
;
4624 *clsid
= info
[i
].Clsid
;
4634 static void test_supported_encoders(void)
4636 static const WCHAR bmp_mimetype
[] = { 'i', 'm', 'a','g', 'e', '/', 'b', 'm', 'p',0 };
4637 static const WCHAR jpeg_mimetype
[] = { 'i','m','a','g','e','/','j','p','e','g',0 };
4638 static const WCHAR gif_mimetype
[] = { 'i','m','a','g','e','/','g','i','f',0 };
4639 static const WCHAR tiff_mimetype
[] = { 'i','m','a','g','e','/','t','i','f','f',0 };
4640 static const WCHAR png_mimetype
[] = { 'i','m','a','g','e','/','p','n','g',0 };
4641 static const struct test_data
4648 { bmp_mimetype
, &ImageFormatBMP
, FALSE
},
4649 { jpeg_mimetype
, &ImageFormatJPEG
, FALSE
},
4650 { gif_mimetype
, &ImageFormatGIF
, TRUE
},
4651 { tiff_mimetype
, &ImageFormatTIFF
, FALSE
},
4652 { png_mimetype
, &ImageFormatPNG
, FALSE
}
4663 status
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB
, NULL
, &bm
);
4664 ok(status
== Ok
, "GdipCreateBitmapFromScan0 error %d\n", status
);
4666 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
4668 ret
= get_encoder_clsid(td
[i
].mime
, &format
, &clsid
);
4669 ok(ret
, "%s encoder is not in the list\n", wine_dbgstr_w(td
[i
].mime
));
4670 expect_guid(td
[i
].format
, &format
, __LINE__
, FALSE
);
4672 hmem
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_NODISCARD
, 16);
4674 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
4675 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
4677 status
= GdipSaveImageToStream((GpImage
*)bm
, stream
, &clsid
, NULL
);
4678 todo_wine_if (td
[i
].todo
)
4679 ok(status
== Ok
, "GdipSaveImageToStream error %d\n", status
);
4681 IStream_Release(stream
);
4684 GdipDisposeImage((GpImage
*)bm
);
4687 static void test_createeffect(void)
4689 static const GUID noneffect
= { 0xcd0c3d4b, 0xe15e, 0x4cf2, { 0x9e, 0xa8, 0x6e, 0x1d, 0x65, 0x48, 0xc5, 0xa5 } };
4690 GpStatus (WINAPI
*pGdipCreateEffect
)( const GUID guid
, CGpEffect
**effect
);
4691 GpStatus (WINAPI
*pGdipDeleteEffect
)( CGpEffect
*effect
);
4694 HMODULE mod
= GetModuleHandleA("gdiplus.dll");
4696 const GUID
* const effectlist
[] =
4697 {&BlurEffectGuid
, &SharpenEffectGuid
, &ColorMatrixEffectGuid
, &ColorLUTEffectGuid
,
4698 &BrightnessContrastEffectGuid
, &HueSaturationLightnessEffectGuid
, &LevelsEffectGuid
,
4699 &TintEffectGuid
, &ColorBalanceEffectGuid
, &RedEyeCorrectionEffectGuid
, &ColorCurveEffectGuid
};
4701 pGdipCreateEffect
= (void*)GetProcAddress( mod
, "GdipCreateEffect");
4702 pGdipDeleteEffect
= (void*)GetProcAddress( mod
, "GdipDeleteEffect");
4703 if(!pGdipCreateEffect
|| !pGdipDeleteEffect
)
4705 /* GdipCreateEffect/GdipDeleteEffect was introduced in Windows Vista. */
4706 win_skip("GDIPlus version 1.1 not available\n");
4710 stat
= pGdipCreateEffect(BlurEffectGuid
, NULL
);
4711 expect(InvalidParameter
, stat
);
4713 stat
= pGdipCreateEffect(noneffect
, &effect
);
4714 todo_wine
expect(Win32Error
, stat
);
4716 for(i
=0; i
< sizeof(effectlist
) / sizeof(effectlist
[0]); i
++)
4718 stat
= pGdipCreateEffect(*effectlist
[i
], &effect
);
4719 todo_wine
expect(Ok
, stat
);
4722 stat
= pGdipDeleteEffect(effect
);
4728 static void test_getadjustedpalette(void)
4731 GpImageAttributes
*imageattributes
;
4732 ColorPalette
*palette
;
4735 stat
= GdipCreateImageAttributes(&imageattributes
);
4738 colormap
.oldColor
.Argb
= 0xffffff00;
4739 colormap
.newColor
.Argb
= 0xffff00ff;
4740 stat
= GdipSetImageAttributesRemapTable(imageattributes
, ColorAdjustTypeBitmap
,
4741 TRUE
, 1, &colormap
);
4744 colormap
.oldColor
.Argb
= 0xffffff80;
4745 colormap
.newColor
.Argb
= 0xffff80ff;
4746 stat
= GdipSetImageAttributesRemapTable(imageattributes
, ColorAdjustTypeDefault
,
4747 TRUE
, 1, &colormap
);
4750 palette
= GdipAlloc(sizeof(*palette
) + sizeof(ARGB
) * 2);
4753 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeBitmap
);
4754 expect(InvalidParameter
, stat
);
4757 palette
->Entries
[0] = 0xffffff00;
4758 palette
->Entries
[1] = 0xffffff80;
4759 palette
->Entries
[2] = 0xffffffff;
4761 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeBitmap
);
4763 expect(0xffff00ff, palette
->Entries
[0]);
4764 expect(0xffffff80, palette
->Entries
[1]);
4765 expect(0xffffffff, palette
->Entries
[2]);
4767 palette
->Entries
[0] = 0xffffff00;
4768 palette
->Entries
[1] = 0xffffff80;
4769 palette
->Entries
[2] = 0xffffffff;
4771 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeBrush
);
4773 expect(0xffffff00, palette
->Entries
[0]);
4774 expect(0xffff80ff, palette
->Entries
[1]);
4775 expect(0xffffffff, palette
->Entries
[2]);
4777 stat
= GdipGetImageAttributesAdjustedPalette(NULL
, palette
, ColorAdjustTypeBitmap
);
4778 expect(InvalidParameter
, stat
);
4780 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, NULL
, ColorAdjustTypeBitmap
);
4781 expect(InvalidParameter
, stat
);
4783 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, -1);
4784 expect(InvalidParameter
, stat
);
4786 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeDefault
);
4787 expect(InvalidParameter
, stat
);
4790 GdipDisposeImageAttributes(imageattributes
);
4795 struct GdiplusStartupInput gdiplusStartupInput
;
4796 ULONG_PTR gdiplusToken
;
4798 gdiplusStartupInput
.GdiplusVersion
= 1;
4799 gdiplusStartupInput
.DebugEventCallback
= NULL
;
4800 gdiplusStartupInput
.SuppressBackgroundThread
= 0;
4801 gdiplusStartupInput
.SuppressExternalCodecs
= 0;
4803 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, NULL
);
4805 test_supported_encoders();
4806 test_CloneBitmapArea();
4807 test_ARGB_conversion();
4808 test_DrawImage_scale();
4809 test_image_format();
4811 test_DrawImage_SourceCopy();
4812 test_GdipDrawImagePointRect();
4814 test_tiff_palette();
4815 test_GdipGetAllPropertyItems();
4816 test_tiff_properties();
4817 test_gif_properties();
4818 test_image_properties();
4821 test_GetImageDimension();
4822 test_GdipImageGetFrameDimensionsCount();
4823 test_LoadingImages();
4824 test_SavingImages();
4827 test_LockBits_UserBuf();
4828 test_GdipCreateBitmapFromHBITMAP();
4829 test_GdipGetImageFlags();
4830 test_GdipCloneImage();
4833 test_getrawformat();
4835 test_createfromwmf();
4836 test_createfromwmf_noplaceable();
4838 test_createhbitmap();
4839 test_getthumbnail();
4844 test_multiframegif();
4849 test_createeffect();
4850 test_getadjustedpalette();
4852 GdiplusShutdown(gdiplusToken
);