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
29 #define WIN32_NO_STATUS
31 #define COM_NO_WINDOWS_H
33 //#include "windows.h"
34 #include <wine/test.h>
40 #define expect(expected, got) ok((got) == (expected), "Expected %d, got %d\n", (UINT)(expected), (UINT)(got))
41 #define expectf(expected, got) ok(fabs((expected) - (got)) < 0.0001, "Expected %f, got %f\n", (expected), (got))
43 static BOOL
color_match(ARGB c1
, ARGB c2
, BYTE max_diff
)
45 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
47 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
49 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
51 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
55 static void expect_guid(REFGUID expected
, REFGUID got
, int line
, BOOL todo
)
61 StringFromGUID2(got
, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]));
62 WideCharToMultiByte(CP_ACP
, 0, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]), buffer
, sizeof(buffer
), NULL
, NULL
);
63 StringFromGUID2(expected
, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]));
64 WideCharToMultiByte(CP_ACP
, 0, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]), buffer2
, sizeof(buffer2
), NULL
, NULL
);
66 todo_wine
ok_(__FILE__
, line
)(IsEqualGUID(expected
, got
), "Expected %s, got %s\n", buffer2
, buffer
);
68 ok_(__FILE__
, line
)(IsEqualGUID(expected
, got
), "Expected %s, got %s\n", buffer2
, buffer
);
71 static void expect_rawformat(REFGUID expected
, GpImage
*img
, int line
, BOOL todo
)
76 stat
= GdipGetImageRawFormat(img
, &raw
);
77 ok_(__FILE__
, line
)(stat
== Ok
, "GdipGetImageRawFormat failed with %d\n", stat
);
78 if(stat
!= Ok
) return;
79 expect_guid(expected
, &raw
, line
, todo
);
82 static void test_bufferrawformat(void* buff
, int size
, REFGUID expected
, int line
, BOOL todo
)
91 hglob
= GlobalAlloc (0, size
);
92 data
= GlobalLock (hglob
);
93 memcpy(data
, buff
, size
);
94 GlobalUnlock(hglob
); data
= NULL
;
96 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
97 ok_(__FILE__
, line
)(hres
== S_OK
, "Failed to create a stream\n");
98 if(hres
!= S_OK
) return;
100 stat
= GdipLoadImageFromStream(stream
, &img
);
101 ok_(__FILE__
, line
)(stat
== Ok
, "Failed to create a Bitmap\n");
103 IStream_Release(stream
);
107 expect_rawformat(expected
, img
, line
, todo
);
109 GdipDisposeImage(img
);
110 IStream_Release(stream
);
113 static void test_Scan0(void)
120 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
122 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
124 GdipDisposeImage((GpImage
*)bm
);
126 bm
= (GpBitmap
*)0xdeadbeef;
127 stat
= GdipCreateBitmapFromScan0(10, -10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
128 expect(InvalidParameter
, stat
);
129 ok( !bm
, "expected null bitmap\n" );
131 bm
= (GpBitmap
*)0xdeadbeef;
132 stat
= GdipCreateBitmapFromScan0(-10, 10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
133 expect(InvalidParameter
, stat
);
134 ok( !bm
, "expected null bitmap\n" );
136 bm
= (GpBitmap
*)0xdeadbeef;
137 stat
= GdipCreateBitmapFromScan0(10, 0, 10, PixelFormat24bppRGB
, NULL
, &bm
);
138 expect(InvalidParameter
, stat
);
139 ok( !bm
, "expected null bitmap\n" );
142 stat
= GdipCreateBitmapFromScan0(10, 10, 12, PixelFormat24bppRGB
, buff
, &bm
);
144 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
146 GdipDisposeImage((GpImage
*)bm
);
148 bm
= (GpBitmap
*) 0xdeadbeef;
149 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, buff
, &bm
);
150 expect(InvalidParameter
, stat
);
151 ok( !bm
, "expected null bitmap\n" );
153 bm
= (GpBitmap
*)0xdeadbeef;
154 stat
= GdipCreateBitmapFromScan0(10, 10, 0, PixelFormat24bppRGB
, buff
, &bm
);
155 expect(InvalidParameter
, stat
);
156 ok( bm
== (GpBitmap
*)0xdeadbeef, "expected deadbeef bitmap\n" );
159 stat
= GdipCreateBitmapFromScan0(10, 10, -8, PixelFormat24bppRGB
, buff
, &bm
);
161 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
163 GdipDisposeImage((GpImage
*)bm
);
165 bm
= (GpBitmap
*)0xdeadbeef;
166 stat
= GdipCreateBitmapFromScan0(10, 10, -10, PixelFormat24bppRGB
, buff
, &bm
);
167 expect(InvalidParameter
, stat
);
168 ok( !bm
, "expected null bitmap\n" );
171 static void test_FromGdiDib(void)
176 BYTE rbmi
[sizeof(BITMAPINFOHEADER
)+256*sizeof(RGBQUAD
)];
177 BITMAPINFO
*bmi
= (BITMAPINFO
*)rbmi
;
182 memset(rbmi
, 0, sizeof(rbmi
));
184 bmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
185 bmi
->bmiHeader
.biWidth
= 10;
186 bmi
->bmiHeader
.biHeight
= 10;
187 bmi
->bmiHeader
.biPlanes
= 1;
188 bmi
->bmiHeader
.biBitCount
= 32;
189 bmi
->bmiHeader
.biCompression
= BI_RGB
;
191 stat
= GdipCreateBitmapFromGdiDib(NULL
, buff
, &bm
);
192 expect(InvalidParameter
, stat
);
194 stat
= GdipCreateBitmapFromGdiDib(bmi
, NULL
, &bm
);
195 expect(InvalidParameter
, stat
);
197 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, NULL
);
198 expect(InvalidParameter
, stat
);
200 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
202 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
205 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
207 expect(PixelFormat32bppRGB
, format
);
209 GdipDisposeImage((GpImage
*)bm
);
212 bmi
->bmiHeader
.biBitCount
= 24;
213 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
215 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
218 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
220 expect(PixelFormat24bppRGB
, format
);
222 GdipDisposeImage((GpImage
*)bm
);
225 bmi
->bmiHeader
.biBitCount
= 16;
226 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
228 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
231 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
233 expect(PixelFormat16bppRGB555
, format
);
235 GdipDisposeImage((GpImage
*)bm
);
238 bmi
->bmiHeader
.biBitCount
= 8;
239 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
241 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
244 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
246 expect(PixelFormat8bppIndexed
, format
);
248 GdipDisposeImage((GpImage
*)bm
);
251 bmi
->bmiHeader
.biBitCount
= 4;
252 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
254 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
257 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
259 expect(PixelFormat4bppIndexed
, format
);
261 GdipDisposeImage((GpImage
*)bm
);
264 bmi
->bmiHeader
.biBitCount
= 1;
265 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
267 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
270 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
272 expect(PixelFormat1bppIndexed
, format
);
274 GdipDisposeImage((GpImage
*)bm
);
277 bmi
->bmiHeader
.biBitCount
= 0;
278 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
279 expect(InvalidParameter
, stat
);
282 static void test_GetImageDimension(void)
286 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
289 bm
= (GpBitmap
*)0xdeadbeef;
290 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
,NULL
, &bm
);
292 ok((GpBitmap
*)0xdeadbeef != bm
, "Expected bitmap to not be 0xdeadbeef\n");
293 ok(NULL
!= bm
, "Expected bitmap to not be NULL\n");
295 stat
= GdipGetImageDimension(NULL
,&w
,&h
);
296 expect(InvalidParameter
, stat
);
298 stat
= GdipGetImageDimension((GpImage
*)bm
,NULL
,&h
);
299 expect(InvalidParameter
, stat
);
301 stat
= GdipGetImageDimension((GpImage
*)bm
,&w
,NULL
);
302 expect(InvalidParameter
, stat
);
306 stat
= GdipGetImageDimension((GpImage
*)bm
,&w
,&h
);
310 GdipDisposeImage((GpImage
*)bm
);
313 static void test_GdipImageGetFrameDimensionsCount(void)
317 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
319 GUID dimension
= {0};
323 bm
= (GpBitmap
*)0xdeadbeef;
324 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
,NULL
, &bm
);
326 ok((GpBitmap
*)0xdeadbeef != bm
, "Expected bitmap to not be 0xdeadbeef\n");
327 ok(NULL
!= bm
, "Expected bitmap to not be NULL\n");
329 stat
= GdipImageGetFrameDimensionsCount(NULL
,&w
);
330 expect(InvalidParameter
, stat
);
332 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bm
,NULL
);
333 expect(InvalidParameter
, stat
);
336 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bm
,&w
);
340 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 1);
342 expect_guid(&FrameDimensionPage
, &dimension
, __LINE__
, FALSE
);
344 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 2);
345 expect(InvalidParameter
, stat
);
347 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 0);
348 expect(InvalidParameter
, stat
);
350 stat
= GdipImageGetFrameCount(NULL
, &dimension
, &count
);
351 expect(InvalidParameter
, stat
);
353 /* WinXP crashes on this test */
356 stat
= GdipImageGetFrameCount((GpImage
*)bm
, &dimension
, NULL
);
357 expect(InvalidParameter
, stat
);
360 stat
= GdipImageGetFrameCount((GpImage
*)bm
, NULL
, &count
);
364 stat
= GdipImageGetFrameCount((GpImage
*)bm
, &dimension
, &count
);
368 GdipBitmapSetPixel(bm
, 0, 0, 0xffffffff);
370 stat
= GdipImageSelectActiveFrame((GpImage
*)bm
, &dimension
, 0);
373 /* SelectActiveFrame has no effect on image data of memory bitmaps */
375 GdipBitmapGetPixel(bm
, 0, 0, &color
);
376 expect(0xffffffff, color
);
378 GdipDisposeImage((GpImage
*)bm
);
381 static void test_LoadingImages(void)
386 static const WCHAR nonexistentW
[] = {'n','o','n','e','x','i','s','t','e','n','t',0};
388 stat
= GdipCreateBitmapFromFile(0, 0);
389 expect(InvalidParameter
, stat
);
391 bm
= (GpBitmap
*)0xdeadbeef;
392 stat
= GdipCreateBitmapFromFile(0, &bm
);
393 expect(InvalidParameter
, stat
);
394 ok(bm
== (GpBitmap
*)0xdeadbeef, "returned %p\n", bm
);
396 bm
= (GpBitmap
*)0xdeadbeef;
397 stat
= GdipCreateBitmapFromFile(nonexistentW
, &bm
);
398 todo_wine
expect(InvalidParameter
, stat
);
399 ok(!bm
, "returned %p\n", bm
);
401 stat
= GdipLoadImageFromFile(0, 0);
402 expect(InvalidParameter
, stat
);
404 img
= (GpImage
*)0xdeadbeef;
405 stat
= GdipLoadImageFromFile(0, &img
);
406 expect(InvalidParameter
, stat
);
407 ok(img
== (GpImage
*)0xdeadbeef, "returned %p\n", img
);
409 img
= (GpImage
*)0xdeadbeef;
410 stat
= GdipLoadImageFromFile(nonexistentW
, &img
);
411 todo_wine
expect(OutOfMemory
, stat
);
412 ok(!img
, "returned %p\n", img
);
414 stat
= GdipLoadImageFromFileICM(0, 0);
415 expect(InvalidParameter
, stat
);
417 img
= (GpImage
*)0xdeadbeef;
418 stat
= GdipLoadImageFromFileICM(0, &img
);
419 expect(InvalidParameter
, stat
);
420 ok(img
== (GpImage
*)0xdeadbeef, "returned %p\n", img
);
422 img
= (GpImage
*)0xdeadbeef;
423 stat
= GdipLoadImageFromFileICM(nonexistentW
, &img
);
424 todo_wine
expect(OutOfMemory
, stat
);
425 ok(!img
, "returned %p\n", img
);
428 static void test_SavingImages(void)
434 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
436 ImageCodecInfo
*codecs
;
437 static const CHAR filenameA
[] = "a.bmp";
438 static const WCHAR filename
[] = { 'a','.','b','m','p',0 };
442 stat
= GdipSaveImageToFile(0, 0, 0, 0);
443 expect(InvalidParameter
, stat
);
446 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
452 stat
= GdipSaveImageToFile((GpImage
*)bm
, 0, 0, 0);
453 expect(InvalidParameter
, stat
);
455 stat
= GdipSaveImageToFile((GpImage
*)bm
, filename
, 0, 0);
456 expect(InvalidParameter
, stat
);
458 /* encoder tests should succeed -- already tested */
459 stat
= GdipGetImageEncodersSize(&n
, &s
);
460 if (stat
!= Ok
|| n
== 0) goto cleanup
;
462 codecs
= GdipAlloc(s
);
463 if (!codecs
) goto cleanup
;
465 stat
= GdipGetImageEncoders(n
, s
, codecs
);
466 if (stat
!= Ok
) goto cleanup
;
468 stat
= GdipSaveImageToFile((GpImage
*)bm
, filename
, &codecs
[0].Clsid
, 0);
471 GdipDisposeImage((GpImage
*)bm
);
474 /* re-load and check image stats */
475 stat
= GdipLoadImageFromFile(filename
, (GpImage
**)&bm
);
477 if (stat
!= Ok
) goto cleanup
;
479 stat
= GdipGetImageDimension((GpImage
*)bm
, &w
, &h
);
480 if (stat
!= Ok
) goto cleanup
;
488 GdipDisposeImage((GpImage
*)bm
);
489 ok(DeleteFileA(filenameA
), "Delete failed.\n");
492 static void test_encoders(void)
497 ImageCodecInfo
*codecs
;
501 static const CHAR bmp_format
[] = "BMP";
503 stat
= GdipGetImageEncodersSize(&n
, &s
);
506 codecs
= GdipAlloc(s
);
510 stat
= GdipGetImageEncoders(n
, s
, NULL
);
511 expect(GenericError
, stat
);
513 stat
= GdipGetImageEncoders(0, s
, codecs
);
514 expect(GenericError
, stat
);
516 stat
= GdipGetImageEncoders(n
, s
-1, codecs
);
517 expect(GenericError
, stat
);
519 stat
= GdipGetImageEncoders(n
, s
+1, codecs
);
520 expect(GenericError
, stat
);
522 stat
= GdipGetImageEncoders(n
, s
, codecs
);
526 for (i
= 0; i
< n
; i
++)
530 WideCharToMultiByte(CP_ACP
, 0, codecs
[i
].FormatDescription
, -1,
533 if (CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0,
535 bmp_format
, -1) == CSTR_EQUAL
) {
541 ok(FALSE
, "No BMP codec found.\n");
546 static void test_LockBits(void)
552 const INT WIDTH
= 10, HEIGHT
= 20;
557 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
565 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffc30000);
568 stat
= GdipBitmapSetPixel(bm
, 2, 8, 0xff480000);
572 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
576 expect(0xc3, ((BYTE
*)bd
.Scan0
)[2]);
577 expect(0x48, ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5]);
579 ((char*)bd
.Scan0
)[2] = 0xff;
581 stat
= GdipBitmapUnlockBits(bm
, &bd
);
585 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
587 expect(0xffff0000, color
);
589 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffc30000);
592 /* read-only, with NULL rect -> whole bitmap lock */
593 stat
= GdipBitmapLockBits(bm
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
595 expect(bd
.Width
, WIDTH
);
596 expect(bd
.Height
, HEIGHT
);
599 ((char*)bd
.Scan0
)[2 + 2*3 + 3*bd
.Stride
] = 0xff;
601 stat
= GdipBitmapUnlockBits(bm
, &bd
);
605 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
607 expect(0xffff0000, color
);
609 /* read-only, consecutive */
610 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
614 stat
= GdipBitmapUnlockBits(bm
, &bd
);
618 stat
= GdipDisposeImage((GpImage
*)bm
);
620 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
624 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
626 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
627 expect(WrongState
, stat
);
629 stat
= GdipBitmapUnlockBits(bm
, &bd
);
632 stat
= GdipDisposeImage((GpImage
*)bm
);
634 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
637 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffff0000);
640 stat
= GdipBitmapSetPixel(bm
, 2, 8, 0xffc30000);
643 /* write, no conversion */
644 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
648 /* all bits are readable, inside the rect or not */
649 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
650 expect(0xc3, ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5]);
652 stat
= GdipBitmapUnlockBits(bm
, &bd
);
656 /* read, conversion */
657 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat32bppARGB
, &bd
);
661 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
663 /* Areas outside the rectangle appear to be uninitialized */
664 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
666 ((BYTE
*)bd
.Scan0
)[2] = 0xc3;
668 stat
= GdipBitmapUnlockBits(bm
, &bd
);
672 /* writes do not work in read mode if there was a conversion */
673 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
675 expect(0xffff0000, color
);
677 /* read/write, conversion */
678 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeWrite
, PixelFormat32bppARGB
, &bd
);
682 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
683 ((BYTE
*)bd
.Scan0
)[1] = 0x88;
685 /* Areas outside the rectangle appear to be uninitialized */
686 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
688 stat
= GdipBitmapUnlockBits(bm
, &bd
);
692 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
694 expect(0xffff8800, color
);
696 /* write, conversion */
697 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat32bppARGB
, &bd
);
703 /* This is completely uninitialized. */
704 ok(0xff != ((BYTE
*)bd
.Scan0
)[2], "original image bits are readable\n");
705 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
708 /* Initialize the buffer so the unlock doesn't access undefined memory */
710 memset(((BYTE
*)bd
.Scan0
) + bd
.Stride
* y
, 0, 12);
712 ((BYTE
*)bd
.Scan0
)[0] = 0x12;
713 ((BYTE
*)bd
.Scan0
)[1] = 0x34;
714 ((BYTE
*)bd
.Scan0
)[2] = 0x56;
716 stat
= GdipBitmapUnlockBits(bm
, &bd
);
720 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
722 expect(0xff563412, color
);
724 stat
= GdipBitmapGetPixel(bm
, 2, 8, &color
);
726 expect(0xffc30000, color
);
728 stat
= GdipDisposeImage((GpImage
*)bm
);
730 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
733 /* write, no modification */
734 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
738 stat
= GdipBitmapUnlockBits(bm
, &bd
);
742 /* write, consecutive */
743 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
747 stat
= GdipBitmapUnlockBits(bm
, &bd
);
751 stat
= GdipDisposeImage((GpImage
*)bm
);
753 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
757 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
762 ((char*)bd
.Scan0
)[2] = 0xff;
764 stat
= GdipBitmapUnlockBits(bm
, &bd
);
768 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
770 expect(0xffff0000, color
);
772 stat
= GdipDisposeImage((GpImage
*)bm
);
776 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
778 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
780 stat
= GdipDisposeImage((GpImage
*)bm
);
784 static void test_LockBits_UserBuf(void)
790 const INT WIDTH
= 10, HEIGHT
= 20;
795 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat32bppARGB
, NULL
, &bm
);
798 memset(bits
, 0xaa, sizeof(bits
));
807 bd
.Stride
= WIDTH
* 4;
808 bd
.PixelFormat
= PixelFormat32bppARGB
;
809 bd
.Scan0
= &bits
[2+3*WIDTH
];
810 bd
.Reserved
= 0xaaaaaaaa;
813 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
816 expect(0xaaaaaaaa, bits
[0]);
817 expect(0, bits
[2+3*WIDTH
]);
819 bits
[2+3*WIDTH
] = 0xdeadbeef;
822 stat
= GdipBitmapUnlockBits(bm
, &bd
);
826 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
831 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
834 expect(0xdeadbeef, bits
[2+3*WIDTH
]);
835 bits
[2+3*WIDTH
] = 0x12345678;
838 stat
= GdipBitmapUnlockBits(bm
, &bd
);
842 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
844 expect(0x12345678, color
);
849 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeWrite
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
852 expect(0x12345678, bits
[2+3*WIDTH
]);
853 bits
[2+3*WIDTH
] = 0xdeadbeef;
856 stat
= GdipBitmapUnlockBits(bm
, &bd
);
860 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
862 expect(0xdeadbeef, color
);
864 stat
= GdipDisposeImage((GpImage
*)bm
);
868 struct BITMAPINFOWITHBITFIELDS
870 BITMAPINFOHEADER bmiHeader
;
874 union BITMAPINFOUNION
877 struct BITMAPINFOWITHBITFIELDS bf
;
880 static void test_GdipCreateBitmapFromHBITMAP(void)
882 GpBitmap
* gpbm
= NULL
;
884 HPALETTE hpal
= NULL
;
887 LOGPALETTE
* LogPal
= NULL
;
889 const REAL WIDTH1
= 5;
890 const REAL HEIGHT1
= 15;
891 const REAL WIDTH2
= 10;
892 const REAL HEIGHT2
= 20;
894 union BITMAPINFOUNION bmi
;
898 stat
= GdipCreateBitmapFromHBITMAP(NULL
, NULL
, NULL
);
899 expect(InvalidParameter
, stat
);
901 hbm
= CreateBitmap(WIDTH1
, HEIGHT1
, 1, 1, NULL
);
902 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, NULL
);
903 expect(InvalidParameter
, stat
);
905 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
907 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
908 expectf(WIDTH1
, width
);
909 expectf(HEIGHT1
, height
);
911 GdipDisposeImage((GpImage
*)gpbm
);
914 memset(buff
, 0, sizeof(buff
));
915 hbm
= CreateBitmap(WIDTH2
, HEIGHT2
, 1, 1, &buff
);
916 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
919 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)gpbm
, __LINE__
, FALSE
);
921 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
922 expectf(WIDTH2
, width
);
923 expectf(HEIGHT2
, height
);
925 GdipDisposeImage((GpImage
*)gpbm
);
928 hdc
= CreateCompatibleDC(0);
929 ok(hdc
!= NULL
, "CreateCompatibleDC failed\n");
930 bmi
.bi
.bmiHeader
.biSize
= sizeof(bmi
.bi
.bmiHeader
);
931 bmi
.bi
.bmiHeader
.biHeight
= HEIGHT1
;
932 bmi
.bi
.bmiHeader
.biWidth
= WIDTH1
;
933 bmi
.bi
.bmiHeader
.biBitCount
= 24;
934 bmi
.bi
.bmiHeader
.biPlanes
= 1;
935 bmi
.bi
.bmiHeader
.biCompression
= BI_RGB
;
936 bmi
.bi
.bmiHeader
.biClrUsed
= 0;
938 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
939 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
943 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
945 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
946 expectf(WIDTH1
, width
);
947 expectf(HEIGHT1
, height
);
950 /* test whether writing to the bitmap affects the original */
951 stat
= GdipBitmapSetPixel(gpbm
, 0, 0, 0xffffffff);
956 GdipDisposeImage((GpImage
*)gpbm
);
959 LogPal
= GdipAlloc(sizeof(LOGPALETTE
));
960 ok(LogPal
!= NULL
, "unable to allocate LOGPALETTE\n");
961 LogPal
->palVersion
= 0x300;
962 LogPal
->palNumEntries
= 1;
963 hpal
= CreatePalette(LogPal
);
964 ok(hpal
!= NULL
, "CreatePalette failed\n");
967 stat
= GdipCreateBitmapFromHBITMAP(hbm
, hpal
, &gpbm
);
971 GdipDisposeImage((GpImage
*)gpbm
);
976 /* 16-bit 555 dib, rgb */
977 bmi
.bi
.bmiHeader
.biBitCount
= 16;
978 bmi
.bi
.bmiHeader
.biCompression
= BI_RGB
;
980 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
981 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
985 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
990 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
992 expectf(WIDTH1
, width
);
993 expectf(HEIGHT1
, height
);
995 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
997 expect(PixelFormat16bppRGB555
, format
);
999 GdipDisposeImage((GpImage
*)gpbm
);
1003 /* 16-bit 555 dib, with bitfields */
1004 bmi
.bi
.bmiHeader
.biSize
= sizeof(bmi
);
1005 bmi
.bi
.bmiHeader
.biCompression
= BI_BITFIELDS
;
1006 bmi
.bf
.masks
[0] = 0x7c00;
1007 bmi
.bf
.masks
[1] = 0x3e0;
1008 bmi
.bf
.masks
[2] = 0x1f;
1010 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1011 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1015 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1020 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1022 expectf(WIDTH1
, width
);
1023 expectf(HEIGHT1
, height
);
1025 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1027 expect(PixelFormat16bppRGB555
, format
);
1029 GdipDisposeImage((GpImage
*)gpbm
);
1033 /* 16-bit 565 dib, with bitfields */
1034 bmi
.bf
.masks
[0] = 0xf800;
1035 bmi
.bf
.masks
[1] = 0x7e0;
1036 bmi
.bf
.masks
[2] = 0x1f;
1038 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1039 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1043 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1048 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1050 expectf(WIDTH1
, width
);
1051 expectf(HEIGHT1
, height
);
1053 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1055 expect(PixelFormat16bppRGB565
, format
);
1057 GdipDisposeImage((GpImage
*)gpbm
);
1064 static void test_GdipGetImageFlags(void)
1070 img
= (GpImage
*)0xdeadbeef;
1072 stat
= GdipGetImageFlags(NULL
, NULL
);
1073 expect(InvalidParameter
, stat
);
1075 stat
= GdipGetImageFlags(NULL
, &flags
);
1076 expect(InvalidParameter
, stat
);
1078 stat
= GdipGetImageFlags(img
, NULL
);
1079 expect(InvalidParameter
, stat
);
1081 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat1bppIndexed
, NULL
, (GpBitmap
**)&img
);
1083 stat
= GdipGetImageFlags(img
, &flags
);
1085 expect(ImageFlagsHasAlpha
, flags
);
1086 GdipDisposeImage(img
);
1088 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat4bppIndexed
, NULL
, (GpBitmap
**)&img
);
1090 stat
= GdipGetImageFlags(img
, &flags
);
1092 expect(ImageFlagsHasAlpha
, flags
);
1093 GdipDisposeImage(img
);
1095 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat8bppIndexed
, NULL
, (GpBitmap
**)&img
);
1097 stat
= GdipGetImageFlags(img
, &flags
);
1099 expect(ImageFlagsHasAlpha
, flags
);
1100 GdipDisposeImage(img
);
1102 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppGrayScale
, NULL
, (GpBitmap
**)&img
);
1104 stat
= GdipGetImageFlags(img
, &flags
);
1106 expect(ImageFlagsNone
, flags
);
1107 GdipDisposeImage(img
);
1109 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB555
, NULL
, (GpBitmap
**)&img
);
1111 stat
= GdipGetImageFlags(img
, &flags
);
1113 expect(ImageFlagsNone
, flags
);
1114 GdipDisposeImage(img
);
1116 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB565
, NULL
, (GpBitmap
**)&img
);
1118 stat
= GdipGetImageFlags(img
, &flags
);
1120 expect(ImageFlagsNone
, flags
);
1121 GdipDisposeImage(img
);
1123 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppARGB1555
, NULL
, (GpBitmap
**)&img
);
1125 stat
= GdipGetImageFlags(img
, &flags
);
1127 expect(ImageFlagsHasAlpha
, flags
);
1128 GdipDisposeImage(img
);
1130 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, NULL
, (GpBitmap
**)&img
);
1132 stat
= GdipGetImageFlags(img
, &flags
);
1134 expect(ImageFlagsNone
, flags
);
1135 GdipDisposeImage(img
);
1137 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&img
);
1139 stat
= GdipGetImageFlags(img
, &flags
);
1141 expect(ImageFlagsNone
, flags
);
1142 GdipDisposeImage(img
);
1144 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppARGB
, NULL
, (GpBitmap
**)&img
);
1146 stat
= GdipGetImageFlags(img
, &flags
);
1148 expect(ImageFlagsHasAlpha
, flags
);
1149 GdipDisposeImage(img
);
1151 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppPARGB
, NULL
, (GpBitmap
**)&img
);
1153 stat
= GdipGetImageFlags(img
, &flags
);
1155 expect(ImageFlagsHasAlpha
, flags
);
1156 GdipDisposeImage(img
);
1158 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat48bppRGB
, NULL
, (GpBitmap
**)&img
);
1162 stat
= GdipGetImageFlags(img
, &flags
);
1164 expect(ImageFlagsNone
, flags
);
1165 GdipDisposeImage(img
);
1168 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB
, NULL
, (GpBitmap
**)&img
);
1173 stat
= GdipGetImageFlags(img
, &flags
);
1175 expect(ImageFlagsHasAlpha
, flags
);
1176 GdipDisposeImage(img
);
1179 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB
, NULL
, (GpBitmap
**)&img
);
1184 stat
= GdipGetImageFlags(img
, &flags
);
1186 expect(ImageFlagsHasAlpha
, flags
);
1187 GdipDisposeImage(img
);
1191 static void test_GdipCloneImage(void)
1197 GpImage
*image_src
, *image_dest
= NULL
;
1198 const INT WIDTH
= 10, HEIGHT
= 20;
1200 /* Create an image, clone it, delete the original, make sure the copy works */
1201 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
1203 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bm
, __LINE__
, FALSE
);
1205 image_src
= ((GpImage
*)bm
);
1206 stat
= GdipCloneImage(image_src
, &image_dest
);
1208 expect_rawformat(&ImageFormatMemoryBMP
, image_dest
, __LINE__
, FALSE
);
1210 stat
= GdipDisposeImage((GpImage
*)bm
);
1212 stat
= GdipGetImageBounds(image_dest
, &rectF
, &unit
);
1215 /* Treat FP values carefully */
1216 expectf((REAL
)WIDTH
, rectF
.Width
);
1217 expectf((REAL
)HEIGHT
, rectF
.Height
);
1219 stat
= GdipDisposeImage(image_dest
);
1223 static void test_testcontrol(void)
1229 stat
= GdipTestControl(TestControlGetBuildNumber
, ¶m
);
1231 ok(param
!= 0, "Build number expected, got %u\n", param
);
1234 static void test_fromhicon(void)
1236 static const BYTE bmp_bits
[1024];
1237 HBITMAP hbmMask
, hbmColor
;
1241 GpBitmap
*bitmap
= NULL
;
1247 stat
= GdipCreateBitmapFromHICON(NULL
, NULL
);
1248 expect(InvalidParameter
, stat
);
1249 stat
= GdipCreateBitmapFromHICON(NULL
, &bitmap
);
1250 expect(InvalidParameter
, stat
);
1252 /* color icon 1 bit */
1253 hbmMask
= CreateBitmap(16, 16, 1, 1, bmp_bits
);
1254 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1255 hbmColor
= CreateBitmap(16, 16, 1, 1, bmp_bits
);
1256 ok(hbmColor
!= 0, "CreateBitmap failed\n");
1260 info
.hbmMask
= hbmMask
;
1261 info
.hbmColor
= hbmColor
;
1262 hIcon
= CreateIconIndirect(&info
);
1263 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
1264 DeleteObject(hbmMask
);
1265 DeleteObject(hbmColor
);
1267 stat
= GdipCreateBitmapFromHICON(hIcon
, &bitmap
);
1269 broken(stat
== InvalidParameter
), /* Win98 */
1270 "Expected Ok, got %.8x\n", stat
);
1272 /* check attributes */
1273 stat
= GdipGetImageHeight((GpImage
*)bitmap
, &dim
);
1276 stat
= GdipGetImageWidth((GpImage
*)bitmap
, &dim
);
1279 stat
= GdipGetImageType((GpImage
*)bitmap
, &type
);
1281 expect(ImageTypeBitmap
, type
);
1282 stat
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
1284 expect(PixelFormat32bppARGB
, format
);
1286 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bitmap
, __LINE__
, FALSE
);
1287 GdipDisposeImage((GpImage
*)bitmap
);
1291 /* color icon 8 bpp */
1292 hbmMask
= CreateBitmap(16, 16, 1, 8, bmp_bits
);
1293 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1294 hbmColor
= CreateBitmap(16, 16, 1, 8, bmp_bits
);
1295 ok(hbmColor
!= 0, "CreateBitmap failed\n");
1299 info
.hbmMask
= hbmMask
;
1300 info
.hbmColor
= hbmColor
;
1301 hIcon
= CreateIconIndirect(&info
);
1302 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
1303 DeleteObject(hbmMask
);
1304 DeleteObject(hbmColor
);
1306 stat
= GdipCreateBitmapFromHICON(hIcon
, &bitmap
);
1309 /* check attributes */
1310 stat
= GdipGetImageHeight((GpImage
*)bitmap
, &dim
);
1313 stat
= GdipGetImageWidth((GpImage
*)bitmap
, &dim
);
1316 stat
= GdipGetImageType((GpImage
*)bitmap
, &type
);
1318 expect(ImageTypeBitmap
, type
);
1319 stat
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
1321 expect(PixelFormat32bppARGB
, format
);
1323 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bitmap
, __LINE__
, FALSE
);
1324 GdipDisposeImage((GpImage
*)bitmap
);
1330 static const unsigned char pngimage
[285] = {
1331 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
1332 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
1333 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
1334 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
1335 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
1336 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
1337 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
1340 static const unsigned char gifimage
[35] = {
1341 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
1342 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
1345 /* 1x1 pixel transparent gif */
1346 static const unsigned char transparentgif
[] = {
1347 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,
1348 0x00,0x00,0x00,0x21,0xf9,0x04,0x01,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,
1349 0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
1352 static const unsigned char bmpimage
[66] = {
1353 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
1354 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
1355 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
1356 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
1360 static const unsigned char jpgimage
[285] = {
1361 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
1362 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
1363 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
1364 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
1365 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
1366 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
1367 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
1368 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1369 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1370 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
1371 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
1372 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1373 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
1374 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
1375 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1376 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
1377 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
1378 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
1380 /* 1x1 pixel tiff */
1381 static const unsigned char tiffimage
[] = {
1382 0x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00,
1383 0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00,
1384 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1385 0x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01,
1386 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00,
1387 0x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00,
1388 0x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01,
1389 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00,
1390 0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00,
1391 0x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01,
1392 0x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00,
1393 0x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1394 0x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
1395 0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65,
1396 0x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74,
1397 0x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,
1400 /* 320x320 twip wmf */
1401 static const unsigned char wmfimage
[180] = {
1402 0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05,
1403 0x00,0x00,0x00,0x00,0xb1,0x52,0x01,0x00,0x09,0x00,0x00,0x03,0x4f,0x00,0x00,0x00,
1404 0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0b,0x02,0x00,0x00,
1405 0x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x02,0x40,0x01,0x40,0x01,0x04,0x00,0x00,0x00,
1406 0x02,0x01,0x01,0x00,0x04,0x00,0x00,0x00,0x04,0x01,0x0d,0x00,0x08,0x00,0x00,0x00,
1407 0xfa,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
1408 0x2d,0x01,0x00,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,0x01,0x00,0x00,0x00,0x00,0x00,
1409 0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x01,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,
1410 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x02,0x00,
1411 0x07,0x00,0x00,0x00,0x1b,0x04,0x40,0x01,0x40,0x01,0x00,0x00,0x00,0x00,0x04,0x00,
1412 0x00,0x00,0xf0,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0xf0,0x01,0x01,0x00,0x03,0x00,
1415 static void test_getrawformat(void)
1417 test_bufferrawformat((void*)pngimage
, sizeof(pngimage
), &ImageFormatPNG
, __LINE__
, FALSE
);
1418 test_bufferrawformat((void*)gifimage
, sizeof(gifimage
), &ImageFormatGIF
, __LINE__
, FALSE
);
1419 test_bufferrawformat((void*)bmpimage
, sizeof(bmpimage
), &ImageFormatBMP
, __LINE__
, FALSE
);
1420 test_bufferrawformat((void*)jpgimage
, sizeof(jpgimage
), &ImageFormatJPEG
, __LINE__
, FALSE
);
1421 test_bufferrawformat((void*)tiffimage
, sizeof(tiffimage
), &ImageFormatTIFF
, __LINE__
, FALSE
);
1422 test_bufferrawformat((void*)wmfimage
, sizeof(wmfimage
), &ImageFormatWMF
, __LINE__
, FALSE
);
1425 static void test_loadwmf(void)
1436 MetafileHeader header
;
1438 hglob
= GlobalAlloc (0, sizeof(wmfimage
));
1439 data
= GlobalLock (hglob
);
1440 memcpy(data
, wmfimage
, sizeof(wmfimage
));
1441 GlobalUnlock(hglob
); data
= NULL
;
1443 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
1444 ok(hres
== S_OK
, "Failed to create a stream\n");
1445 if(hres
!= S_OK
) return;
1447 stat
= GdipLoadImageFromStream(stream
, &img
);
1448 ok(stat
== Ok
, "Failed to create a Bitmap\n");
1450 IStream_Release(stream
);
1454 IStream_Release(stream
);
1456 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1458 todo_wine
expect(UnitPixel
, unit
);
1459 expectf(0.0, bounds
.X
);
1460 expectf(0.0, bounds
.Y
);
1461 todo_wine
expectf(320.0, bounds
.Width
);
1462 todo_wine
expectf(320.0, bounds
.Height
);
1464 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1466 todo_wine
expectf(1440.0, res
);
1468 stat
= GdipGetImageVerticalResolution(img
, &res
);
1470 todo_wine
expectf(1440.0, res
);
1472 memset(&header
, 0, sizeof(header
));
1473 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1477 todo_wine
expect(MetafileTypeWmfPlaceable
, header
.Type
);
1478 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1479 todo_wine
expect(0x300, header
.Version
);
1480 expect(0, header
.EmfPlusFlags
);
1481 todo_wine
expectf(1440.0, header
.DpiX
);
1482 todo_wine
expectf(1440.0, header
.DpiY
);
1483 expect(0, header
.X
);
1484 expect(0, header
.Y
);
1485 todo_wine
expect(320, header
.Width
);
1486 todo_wine
expect(320, header
.Height
);
1487 todo_wine
expect(1, U(header
).WmfHeader
.mtType
);
1488 expect(0, header
.EmfPlusHeaderSize
);
1489 expect(0, header
.LogicalDpiX
);
1490 expect(0, header
.LogicalDpiY
);
1493 GdipDisposeImage(img
);
1496 static void test_createfromwmf(void)
1504 MetafileHeader header
;
1506 hwmf
= SetMetaFileBitsEx(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
),
1507 wmfimage
+sizeof(WmfPlaceableFileHeader
));
1508 ok(hwmf
!= 0, "SetMetaFileBitsEx failed\n");
1510 stat
= GdipCreateMetafileFromWmf(hwmf
, TRUE
,
1511 (WmfPlaceableFileHeader
*)wmfimage
, (GpMetafile
**)&img
);
1514 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1516 expect(UnitPixel
, unit
);
1517 expectf(0.0, bounds
.X
);
1518 expectf(0.0, bounds
.Y
);
1519 expectf(320.0, bounds
.Width
);
1520 expectf(320.0, bounds
.Height
);
1522 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1524 expectf(1440.0, res
);
1526 stat
= GdipGetImageVerticalResolution(img
, &res
);
1528 expectf(1440.0, res
);
1530 memset(&header
, 0, sizeof(header
));
1531 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1535 todo_wine
expect(MetafileTypeWmfPlaceable
, header
.Type
);
1536 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1537 todo_wine
expect(0x300, header
.Version
);
1538 expect(0, header
.EmfPlusFlags
);
1539 todo_wine
expectf(1440.0, header
.DpiX
);
1540 todo_wine
expectf(1440.0, header
.DpiY
);
1541 expect(0, header
.X
);
1542 expect(0, header
.Y
);
1543 todo_wine
expect(320, header
.Width
);
1544 todo_wine
expect(320, header
.Height
);
1545 todo_wine
expect(1, U(header
).WmfHeader
.mtType
);
1546 expect(0, header
.EmfPlusHeaderSize
);
1547 expect(0, header
.LogicalDpiX
);
1548 expect(0, header
.LogicalDpiY
);
1551 GdipDisposeImage(img
);
1554 static void test_resolution(void)
1558 GpGraphics
*graphics
;
1561 int screenxres
, screenyres
;
1564 stat
= GdipCreateBitmapFromScan0(1, 1, 32, PixelFormat24bppRGB
, NULL
, &bitmap
);
1567 /* test invalid values */
1568 stat
= GdipGetImageHorizontalResolution(NULL
, &res
);
1569 expect(InvalidParameter
, stat
);
1571 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, NULL
);
1572 expect(InvalidParameter
, stat
);
1574 stat
= GdipGetImageVerticalResolution(NULL
, &res
);
1575 expect(InvalidParameter
, stat
);
1577 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, NULL
);
1578 expect(InvalidParameter
, stat
);
1580 stat
= GdipBitmapSetResolution(NULL
, 96.0, 96.0);
1581 expect(InvalidParameter
, stat
);
1583 stat
= GdipBitmapSetResolution(bitmap
, 0.0, 0.0);
1584 expect(InvalidParameter
, stat
);
1586 /* defaults to screen resolution */
1587 screendc
= GetDC(0);
1589 screenxres
= GetDeviceCaps(screendc
, LOGPIXELSX
);
1590 screenyres
= GetDeviceCaps(screendc
, LOGPIXELSY
);
1592 ReleaseDC(0, screendc
);
1594 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1596 expectf((REAL
)screenxres
, res
);
1598 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1600 expectf((REAL
)screenyres
, res
);
1602 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1604 stat
= GdipGetDpiX(graphics
, &res
);
1606 expectf((REAL
)screenxres
, res
);
1607 stat
= GdipGetDpiY(graphics
, &res
);
1609 expectf((REAL
)screenyres
, res
);
1611 /* test changing the resolution */
1612 stat
= GdipBitmapSetResolution(bitmap
, screenxres
*2.0, screenyres
*3.0);
1615 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1617 expectf(screenxres
*2.0, res
);
1619 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1621 expectf(screenyres
*3.0, res
);
1623 stat
= GdipGetDpiX(graphics
, &res
);
1625 expectf((REAL
)screenxres
, res
);
1626 stat
= GdipGetDpiY(graphics
, &res
);
1628 expectf((REAL
)screenyres
, res
);
1630 stat
= GdipDeleteGraphics(graphics
);
1633 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1635 stat
= GdipGetDpiX(graphics
, &res
);
1637 expectf(screenxres
*2.0, res
);
1638 stat
= GdipGetDpiY(graphics
, &res
);
1640 expectf(screenyres
*3.0, res
);
1641 stat
= GdipDeleteGraphics(graphics
);
1644 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1648 static void test_createhbitmap(void)
1652 HBITMAP hbitmap
, oldhbitmap
;
1659 memset(bits
, 0x68, 640);
1662 stat
= GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB
, bits
, &bitmap
);
1665 /* test NULL values */
1666 stat
= GdipCreateHBITMAPFromBitmap(NULL
, &hbitmap
, 0);
1667 expect(InvalidParameter
, stat
);
1669 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, NULL
, 0);
1670 expect(InvalidParameter
, stat
);
1672 /* create HBITMAP */
1673 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1678 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1679 expect(sizeof(BITMAP
), ret
);
1681 expect(0, bm
.bmType
);
1682 expect(10, bm
.bmWidth
);
1683 expect(20, bm
.bmHeight
);
1684 expect(40, bm
.bmWidthBytes
);
1685 expect(1, bm
.bmPlanes
);
1686 expect(32, bm
.bmBitsPixel
);
1687 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1691 DWORD val
= *(DWORD
*)bm
.bmBits
;
1692 ok(val
== 0xff686868, "got %x, expected 0xff686868\n", val
);
1695 hdc
= CreateCompatibleDC(NULL
);
1697 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1698 pixel
= GetPixel(hdc
, 5, 5);
1699 SelectObject(hdc
, oldhbitmap
);
1703 expect(0x686868, pixel
);
1705 DeleteObject(hbitmap
);
1708 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1711 /* make (1,0) have no alpha and (2,0) a different blue value. */
1715 /* create alpha Bitmap */
1716 stat
= GdipCreateBitmapFromScan0(8, 20, 32, PixelFormat32bppARGB
, bits
, &bitmap
);
1719 /* create HBITMAP */
1720 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1725 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1726 expect(sizeof(BITMAP
), ret
);
1728 expect(0, bm
.bmType
);
1729 expect(8, bm
.bmWidth
);
1730 expect(20, bm
.bmHeight
);
1731 expect(32, bm
.bmWidthBytes
);
1732 expect(1, bm
.bmPlanes
);
1733 expect(32, bm
.bmBitsPixel
);
1734 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1738 DWORD val
= *(DWORD
*)bm
.bmBits
;
1739 ok(val
== 0x682a2a2a, "got %x, expected 0x682a2a2a\n", val
);
1740 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1741 ok(val
== 0x0, "got %x, expected 0x682a2a2a\n", val
);
1744 hdc
= CreateCompatibleDC(NULL
);
1746 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1747 pixel
= GetPixel(hdc
, 5, 5);
1748 expect(0x2a2a2a, pixel
);
1749 pixel
= GetPixel(hdc
, 1, 0);
1752 SelectObject(hdc
, oldhbitmap
);
1757 DeleteObject(hbitmap
);
1760 /* create HBITMAP with bkgnd colour */
1761 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0xff00ff);
1766 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1767 expect(sizeof(BITMAP
), ret
);
1769 expect(0, bm
.bmType
);
1770 expect(8, bm
.bmWidth
);
1771 expect(20, bm
.bmHeight
);
1772 expect(32, bm
.bmWidthBytes
);
1773 expect(1, bm
.bmPlanes
);
1774 expect(32, bm
.bmBitsPixel
);
1775 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1779 DWORD val
= *(DWORD
*)bm
.bmBits
;
1780 ok(val
== 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val
);
1781 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1782 ok(val
== 0xff00ff, "got %x, expected 0x682a2a2a\n", val
);
1785 hdc
= CreateCompatibleDC(NULL
);
1787 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1788 pixel
= GetPixel(hdc
, 5, 5);
1789 expect(0xc12ac1, pixel
);
1790 pixel
= GetPixel(hdc
, 1, 0);
1791 expect(0xff00ff, pixel
);
1792 pixel
= GetPixel(hdc
, 2, 0);
1793 expect(0xb12ac1, pixel
);
1795 SelectObject(hdc
, oldhbitmap
);
1797 DeleteObject(hbitmap
);
1800 /* create HBITMAP with bkgnd colour with alpha and show it behaves with no alpha. */
1801 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0x80ff00ff);
1806 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1807 expect(sizeof(BITMAP
), ret
);
1809 expect(0, bm
.bmType
);
1810 expect(8, bm
.bmWidth
);
1811 expect(20, bm
.bmHeight
);
1812 expect(32, bm
.bmWidthBytes
);
1813 expect(1, bm
.bmPlanes
);
1814 expect(32, bm
.bmBitsPixel
);
1815 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1819 DWORD val
= *(DWORD
*)bm
.bmBits
;
1820 ok(val
== 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val
);
1821 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1822 ok(val
== 0xff00ff, "got %x, expected 0x682a2a2a\n", val
);
1825 hdc
= CreateCompatibleDC(NULL
);
1827 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1828 pixel
= GetPixel(hdc
, 5, 5);
1829 expect(0xc12ac1, pixel
);
1830 pixel
= GetPixel(hdc
, 1, 0);
1831 expect(0xff00ff, pixel
);
1832 pixel
= GetPixel(hdc
, 2, 0);
1833 expect(0xb12ac1, pixel
);
1835 SelectObject(hdc
, oldhbitmap
);
1837 DeleteObject(hbitmap
);
1840 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1844 static void test_getthumbnail(void)
1847 GpImage
*bitmap1
, *bitmap2
;
1850 stat
= GdipGetImageThumbnail(NULL
, 0, 0, &bitmap2
, NULL
, NULL
);
1851 expect(InvalidParameter
, stat
);
1853 stat
= GdipCreateBitmapFromScan0(128, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1856 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, NULL
, NULL
, NULL
);
1857 expect(InvalidParameter
, stat
);
1859 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, &bitmap2
, NULL
, NULL
);
1864 stat
= GdipGetImageWidth(bitmap2
, &width
);
1868 stat
= GdipGetImageHeight(bitmap2
, &height
);
1870 expect(120, height
);
1872 GdipDisposeImage(bitmap2
);
1875 GdipDisposeImage(bitmap1
);
1878 stat
= GdipCreateBitmapFromScan0(64, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1881 stat
= GdipGetImageThumbnail(bitmap1
, 32, 32, &bitmap2
, NULL
, NULL
);
1886 stat
= GdipGetImageWidth(bitmap2
, &width
);
1890 stat
= GdipGetImageHeight(bitmap2
, &height
);
1894 GdipDisposeImage(bitmap2
);
1897 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, &bitmap2
, NULL
, NULL
);
1902 stat
= GdipGetImageWidth(bitmap2
, &width
);
1906 stat
= GdipGetImageHeight(bitmap2
, &height
);
1908 expect(120, height
);
1910 GdipDisposeImage(bitmap2
);
1913 GdipDisposeImage(bitmap1
);
1916 static void test_getsetpixel(void)
1921 BYTE bits
[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00,
1922 0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00};
1924 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, bits
, &bitmap
);
1927 /* null parameters */
1928 stat
= GdipBitmapGetPixel(NULL
, 1, 1, &color
);
1929 expect(InvalidParameter
, stat
);
1931 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, NULL
);
1932 expect(InvalidParameter
, stat
);
1934 stat
= GdipBitmapSetPixel(NULL
, 1, 1, 0);
1935 expect(InvalidParameter
, stat
);
1938 stat
= GdipBitmapGetPixel(bitmap
, -1, 1, &color
);
1939 expect(InvalidParameter
, stat
);
1941 stat
= GdipBitmapSetPixel(bitmap
, -1, 1, 0);
1942 expect(InvalidParameter
, stat
);
1944 stat
= GdipBitmapGetPixel(bitmap
, 1, -1, &color
);
1945 ok(stat
== InvalidParameter
||
1946 broken(stat
== Ok
), /* Older gdiplus */
1947 "Expected InvalidParameter, got %.8x\n", stat
);
1949 if (0) /* crashes some gdiplus implementations */
1951 stat
= GdipBitmapSetPixel(bitmap
, 1, -1, 0);
1952 ok(stat
== InvalidParameter
||
1953 broken(stat
== Ok
), /* Older gdiplus */
1954 "Expected InvalidParameter, got %.8x\n", stat
);
1957 stat
= GdipBitmapGetPixel(bitmap
, 2, 1, &color
);
1958 expect(InvalidParameter
, stat
);
1960 stat
= GdipBitmapSetPixel(bitmap
, 2, 1, 0);
1961 expect(InvalidParameter
, stat
);
1963 stat
= GdipBitmapGetPixel(bitmap
, 1, 2, &color
);
1964 expect(InvalidParameter
, stat
);
1966 stat
= GdipBitmapSetPixel(bitmap
, 1, 2, 0);
1967 expect(InvalidParameter
, stat
);
1970 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
1972 expect(0xffffffff, color
);
1974 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
1976 expect(0xff0000ff, color
);
1978 stat
= GdipBitmapSetPixel(bitmap
, 1, 1, 0xff676869);
1981 stat
= GdipBitmapSetPixel(bitmap
, 0, 0, 0xff474849);
1984 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
1986 expect(0xff676869, color
);
1988 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
1990 expect(0xff474849, color
);
1992 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1996 static void check_halftone_palette(ColorPalette
*palette
)
1998 static const BYTE halftone_values
[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
2001 for (i
=0; i
<palette
->Count
; i
++)
2003 ARGB expected
=0xff000000;
2006 if (i
&1) expected
|= 0x800000;
2007 if (i
&2) expected
|= 0x8000;
2008 if (i
&4) expected
|= 0x80;
2012 expected
= 0xffc0c0c0;
2016 if (i
&1) expected
|= 0xff0000;
2017 if (i
&2) expected
|= 0xff00;
2018 if (i
&4) expected
|= 0xff;
2022 expected
= 0x00000000;
2026 expected
|= halftone_values
[(i
-40)%6];
2027 expected
|= halftone_values
[((i
-40)/6)%6] << 8;
2028 expected
|= halftone_values
[((i
-40)/36)%6] << 16;
2030 ok(expected
== palette
->Entries
[i
], "Expected %.8x, got %.8x, i=%u/%u\n",
2031 expected
, palette
->Entries
[i
], i
, palette
->Count
);
2035 static void test_palette(void)
2041 ColorPalette
*palette
=(ColorPalette
*)buffer
;
2042 ARGB
*entries
= palette
->Entries
;
2045 /* test initial palette from non-indexed bitmap */
2046 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, NULL
, &bitmap
);
2049 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2051 expect(sizeof(UINT
)*2+sizeof(ARGB
), size
);
2053 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2055 expect(0, palette
->Count
);
2057 /* test setting palette on not-indexed bitmap */
2060 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2063 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2065 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2067 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2069 expect(3, palette
->Count
);
2071 GdipDisposeImage((GpImage
*)bitmap
);
2073 /* test initial palette on 1-bit bitmap */
2074 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat1bppIndexed
, NULL
, &bitmap
);
2077 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2079 expect(sizeof(UINT
)*2+sizeof(ARGB
)*2, size
);
2081 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2083 expect(PaletteFlagsGrayScale
, palette
->Flags
);
2084 expect(2, palette
->Count
);
2086 expect(0xff000000, entries
[0]);
2087 expect(0xffffffff, entries
[1]);
2089 /* test getting/setting pixels */
2090 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2092 expect(0xff000000, color
);
2094 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffffffff);
2096 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2100 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2102 expect(0xffffffff, color
);
2105 GdipDisposeImage((GpImage
*)bitmap
);
2107 /* test initial palette on 4-bit bitmap */
2108 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat4bppIndexed
, NULL
, &bitmap
);
2111 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2113 expect(sizeof(UINT
)*2+sizeof(ARGB
)*16, size
);
2115 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2117 expect(0, palette
->Flags
);
2118 expect(16, palette
->Count
);
2120 check_halftone_palette(palette
);
2122 /* test getting/setting pixels */
2123 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2125 expect(0xff000000, color
);
2127 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffff00ff);
2129 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2133 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2135 expect(0xffff00ff, color
);
2138 GdipDisposeImage((GpImage
*)bitmap
);
2140 /* test initial palette on 8-bit bitmap */
2141 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat8bppIndexed
, NULL
, &bitmap
);
2144 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2146 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2148 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2150 expect(PaletteFlagsHalftone
, palette
->Flags
);
2151 expect(256, palette
->Count
);
2153 check_halftone_palette(palette
);
2155 /* test getting/setting pixels */
2156 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2158 expect(0xff000000, color
);
2160 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffcccccc);
2162 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2166 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2168 expect(0xffcccccc, color
);
2171 /* test setting/getting a different palette */
2172 entries
[1] = 0xffcccccc;
2174 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2179 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2181 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2183 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2185 expect(PaletteFlagsHalftone
, palette
->Flags
);
2186 expect(256, palette
->Count
);
2187 expect(0xffcccccc, entries
[1]);
2189 /* test count < 256 */
2190 palette
->Flags
= 12345;
2193 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2197 entries
[3] = 0xdeadbeef;
2199 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2201 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2203 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2205 expect(12345, palette
->Flags
);
2206 expect(3, palette
->Count
);
2207 expect(0xffcccccc, entries
[1]);
2208 expect(0xdeadbeef, entries
[3]);
2210 /* test count > 256 */
2211 palette
->Count
= 257;
2213 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2214 ok(stat
== InvalidParameter
||
2215 broken(stat
== Ok
), /* Old gdiplus behavior */
2216 "Expected %.8x, got %.8x\n", InvalidParameter
, stat
);
2218 GdipDisposeImage((GpImage
*)bitmap
);
2221 static void test_colormatrix(void)
2224 ColorMatrix colormatrix
, graymatrix
;
2225 GpImageAttributes
*imageattr
;
2226 const ColorMatrix identity
= {{
2227 {1.0,0.0,0.0,0.0,0.0},
2228 {0.0,1.0,0.0,0.0,0.0},
2229 {0.0,0.0,1.0,0.0,0.0},
2230 {0.0,0.0,0.0,1.0,0.0},
2231 {0.0,0.0,0.0,0.0,1.0}}};
2232 const ColorMatrix double_red
= {{
2233 {2.0,0.0,0.0,0.0,0.0},
2234 {0.0,1.0,0.0,0.0,0.0},
2235 {0.0,0.0,1.0,0.0,0.0},
2236 {0.0,0.0,0.0,1.0,0.0},
2237 {0.0,0.0,0.0,0.0,1.0}}};
2238 const ColorMatrix asymmetric
= {{
2239 {0.0,1.0,0.0,0.0,0.0},
2240 {0.0,0.0,1.0,0.0,0.0},
2241 {0.0,0.0,0.0,1.0,0.0},
2242 {1.0,0.0,0.0,0.0,0.0},
2243 {0.0,0.0,0.0,0.0,1.0}}};
2244 GpBitmap
*bitmap1
, *bitmap2
;
2245 GpGraphics
*graphics
;
2248 colormatrix
= identity
;
2249 graymatrix
= identity
;
2251 stat
= GdipSetImageAttributesColorMatrix(NULL
, ColorAdjustTypeDefault
,
2252 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2253 expect(InvalidParameter
, stat
);
2255 stat
= GdipCreateImageAttributes(&imageattr
);
2258 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2259 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2262 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2263 TRUE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2264 expect(InvalidParameter
, stat
);
2266 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2267 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2270 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2271 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsSkipGrays
);
2274 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2275 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsAltGray
);
2276 expect(InvalidParameter
, stat
);
2278 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2279 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsAltGray
);
2282 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2283 TRUE
, &colormatrix
, &graymatrix
, 3);
2284 expect(InvalidParameter
, stat
);
2286 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeCount
,
2287 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2288 expect(InvalidParameter
, stat
);
2290 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeAny
,
2291 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2292 expect(InvalidParameter
, stat
);
2294 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2295 FALSE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2298 /* Drawing a bitmap transforms the colors */
2299 colormatrix
= double_red
;
2300 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2301 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2304 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
2307 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
2310 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff40ccee);
2313 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2316 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2317 UnitPixel
, imageattr
, NULL
, NULL
);
2320 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2322 expect(0xff80ccee, color
);
2324 colormatrix
= asymmetric
;
2325 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2326 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2329 stat
= GdipBitmapSetPixel(bitmap2
, 0, 0, 0);
2332 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2333 UnitPixel
, imageattr
, NULL
, NULL
);
2336 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2338 ok(color_match(0xeeff40cc, color
, 3), "expected 0xeeff40cc, got 0x%08x\n", color
);
2340 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2343 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2344 UnitPixel
, imageattr
, NULL
, NULL
);
2347 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2349 ok(color_match(0xff40ccee, color
, 1), "Expected ff40ccee, got %.8x\n", color
);
2351 GdipDeleteGraphics(graphics
);
2352 GdipDisposeImage((GpImage
*)bitmap1
);
2353 GdipDisposeImage((GpImage
*)bitmap2
);
2354 GdipDisposeImageAttributes(imageattr
);
2357 static void test_gamma(void)
2360 GpImageAttributes
*imageattr
;
2361 GpBitmap
*bitmap1
, *bitmap2
;
2362 GpGraphics
*graphics
;
2365 stat
= GdipSetImageAttributesGamma(NULL
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2366 expect(InvalidParameter
, stat
);
2368 stat
= GdipCreateImageAttributes(&imageattr
);
2371 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2374 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeAny
, TRUE
, 1.0);
2375 expect(InvalidParameter
, stat
);
2377 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, -1.0);
2378 expect(InvalidParameter
, stat
);
2380 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.0);
2381 expect(InvalidParameter
, stat
);
2383 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.5);
2386 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0.0);
2389 /* Drawing a bitmap transforms the colors */
2390 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 3.0);
2393 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
2396 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
2399 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff80ffff);
2402 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2405 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2406 UnitPixel
, imageattr
, NULL
, NULL
);
2409 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2411 ok(color_match(0xff20ffff, color
, 1), "Expected ff20ffff, got %.8x\n", color
);
2413 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2416 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2417 UnitPixel
, imageattr
, NULL
, NULL
);
2420 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2422 ok(color_match(0xff80ffff, color
, 1), "Expected ff80ffff, got %.8x\n", color
);
2424 GdipDeleteGraphics(graphics
);
2425 GdipDisposeImage((GpImage
*)bitmap1
);
2426 GdipDisposeImage((GpImage
*)bitmap2
);
2427 GdipDisposeImageAttributes(imageattr
);
2430 /* 1x1 pixel gif, 2 frames; first frame is white, second is black */
2431 static const unsigned char gifanimation
[72] = {
2432 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
2433 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0xf9,0x04,0x00,0x0a,0x00,0xff,
2434 0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x4c,0x01,0x00,
2435 0x21,0xf9,0x04,0x01,0x0a,0x00,0x01,0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,
2436 0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
2439 /* Generated with ImageMagick:
2440 * convert -transparent black -delay 100 -size 8x2 xc:black \
2441 * -dispose none -page +0+0 -size 2x2 xc:red \
2442 * -dispose background -page +2+0 -size 2x2 xc:blue \
2443 * -dispose previous -page +4+0 -size 2x2 xc:green \
2444 * -dispose undefined -page +6+0 -size 2x2 xc:gray \
2447 static const unsigned char gifanimation2
[] = {
2448 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x08, 0x00,
2449 0x02, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
2450 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x64,
2451 0x00, 0x00, 0x00, 0x21, 0xff, 0x0b, 0x4e, 0x45,
2452 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e,
2453 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00,
2454 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
2455 0x02, 0x04, 0x84, 0x8f, 0x09, 0x05, 0x00, 0x21,
2456 0xf9, 0x04, 0x04, 0x64, 0x00, 0x00, 0x00, 0x2c,
2457 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2458 0x81, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
2459 0x00, 0x00, 0xff, 0x00, 0x00, 0x02, 0x03, 0x44,
2460 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x08, 0x64,
2461 0x00, 0x00, 0x00, 0x2c, 0x02, 0x00, 0x00, 0x00,
2462 0x02, 0x00, 0x02, 0x00, 0x81, 0x00, 0x00, 0xff,
2463 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
2464 0xff, 0x02, 0x03, 0x44, 0x34, 0x05, 0x00, 0x21,
2465 0xf9, 0x04, 0x0c, 0x64, 0x00, 0x00, 0x00, 0x2c,
2466 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2467 0x81, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00,
2468 0x80, 0x00, 0x00, 0x80, 0x00, 0x02, 0x03, 0x44,
2469 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x64,
2470 0x00, 0x00, 0x00, 0x2c, 0x06, 0x00, 0x00, 0x00,
2471 0x02, 0x00, 0x02, 0x00, 0x80, 0x7e, 0x7e, 0x7e,
2472 0x00, 0x00, 0x00, 0x02, 0x02, 0x84, 0x51, 0x00,
2476 static ARGB gifanimation2_pixels
[5][4] = {
2478 {0xffff0000, 0, 0, 0},
2479 {0xffff0000, 0xff0000ff, 0, 0},
2480 {0xffff0000, 0, 0xff008000, 0},
2481 {0xffff0000, 0, 0, 0xff7e7e7e}
2484 static void test_multiframegif(void)
2495 PixelFormat pixel_format
;
2496 INT palette_size
, i
, j
;
2497 char palette_buf
[256];
2498 ColorPalette
*palette
;
2499 ARGB
*palette_entries
;
2501 /* Test frame functions with an animated GIF */
2502 hglob
= GlobalAlloc (0, sizeof(gifanimation
));
2503 data
= GlobalLock (hglob
);
2504 memcpy(data
, gifanimation
, sizeof(gifanimation
));
2505 GlobalUnlock(hglob
);
2507 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2508 ok(hres
== S_OK
, "Failed to create a stream\n");
2509 if(hres
!= S_OK
) return;
2511 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2512 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2514 IStream_Release(stream
);
2518 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2520 expect(PixelFormat32bppARGB
, pixel_format
);
2522 stat
= GdipGetImagePaletteSize((GpImage
*)bmp
, &palette_size
);
2524 ok(palette_size
== sizeof(ColorPalette
) ||
2525 broken(palette_size
== sizeof(ColorPalette
)+sizeof(ARGB
[3])),
2526 "palette_size = %d\n", palette_size
);
2528 /* Bitmap starts at frame 0 */
2530 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2532 expect(0xffffffff, color
);
2534 /* Check that we get correct metadata */
2535 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2539 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2541 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2544 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2548 /* SelectActiveFrame overwrites our current data */
2549 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2553 GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2555 expect(0xff000000, color
);
2557 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2561 GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2563 expect(0xffffffff, color
);
2565 /* Write over the image data */
2566 stat
= GdipBitmapSetPixel(bmp
, 0, 0, 0xff000000);
2569 /* Switching to the same frame does not overwrite our changes */
2570 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2573 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2575 expect(0xff000000, color
);
2577 /* But switching to another frame and back does */
2578 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2581 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2584 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2586 expect(0xffffffff, color
);
2588 /* rotate/flip discards the information about other frames */
2589 stat
= GdipImageRotateFlip((GpImage
*)bmp
, Rotate90FlipNone
);
2593 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2597 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bmp
, __LINE__
, FALSE
);
2599 GdipDisposeImage((GpImage
*)bmp
);
2600 IStream_Release(stream
);
2602 /* Test with a non-animated gif */
2603 hglob
= GlobalAlloc (0, sizeof(gifimage
));
2604 data
= GlobalLock (hglob
);
2605 memcpy(data
, gifimage
, sizeof(gifimage
));
2606 GlobalUnlock(hglob
);
2608 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2609 ok(hres
== S_OK
, "Failed to create a stream\n");
2610 if(hres
!= S_OK
) return;
2612 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2613 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2615 IStream_Release(stream
);
2619 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2621 expect(PixelFormat8bppIndexed
, pixel_format
);
2623 /* Check metadata */
2624 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2628 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2630 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2633 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2637 GdipDisposeImage((GpImage
*)bmp
);
2638 IStream_Release(stream
);
2640 /* Test with a non-animated transparent gif */
2641 hglob
= GlobalAlloc (0, sizeof(transparentgif
));
2642 data
= GlobalLock (hglob
);
2643 memcpy(data
, transparentgif
, sizeof(transparentgif
));
2644 GlobalUnlock(hglob
);
2646 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2647 ok(hres
== S_OK
, "Failed to create a stream\n");
2649 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2650 IStream_Release(stream
);
2651 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2653 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2655 expect(PixelFormat8bppIndexed
, pixel_format
);
2657 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2661 stat
= GdipGetImagePaletteSize((GpImage
*)bmp
, &palette_size
);
2663 ok(palette_size
== sizeof(ColorPalette
)+sizeof(ARGB
),
2664 "palette_size = %d\n", palette_size
);
2666 memset(palette_buf
, 0xfe, sizeof(palette_buf
));
2667 palette
= (ColorPalette
*)palette_buf
;
2668 stat
= GdipGetImagePalette((GpImage
*)bmp
, palette
,
2669 sizeof(ColorPalette
)+sizeof(ARGB
));
2670 palette_entries
= palette
->Entries
;
2672 expect(PaletteFlagsHasAlpha
, palette
->Flags
);
2673 expect(2, palette
->Count
);
2674 expect(0, palette_entries
[0]);
2675 expect(0xff000000, palette_entries
[1]);
2678 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2682 GdipDisposeImage((GpImage
*)bmp
);
2684 /* Test frame dispose methods */
2685 hglob
= GlobalAlloc (0, sizeof(gifanimation2
));
2686 data
= GlobalLock (hglob
);
2687 memcpy(data
, gifanimation2
, sizeof(gifanimation2
));
2688 GlobalUnlock(hglob
);
2690 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2691 ok(hres
== S_OK
, "Failed to create a stream\n");
2693 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2694 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2695 IStream_Release(stream
);
2697 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2699 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2701 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2705 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2709 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 3);
2710 stat
= GdipBitmapGetPixel(bmp
, 2, 0, &color
);
2712 ok(color
==0 || broken(color
==0xff0000ff), "color = %x\n", color
);
2714 win_skip("broken animated gif support\n");
2715 GdipDisposeImage((GpImage
*)bmp
);
2719 for(i
=0; i
<6; i
++) {
2720 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, i
%5);
2723 for(j
=0; j
<4; j
++) {
2724 stat
= GdipBitmapGetPixel(bmp
, j
*2, 0, &color
);
2726 ok(gifanimation2_pixels
[i
%5][j
] == color
, "at %d,%d got %x, expected %x\n", i
, j
, color
, gifanimation2_pixels
[i
%5][j
]);
2730 GdipDisposeImage((GpImage
*)bmp
);
2733 static void test_rotateflip(void)
2738 static const BYTE orig_bits
[24] = {
2739 0,0,0xff, 0,0xff,0, 0xff,0,0, 23,23,23,
2740 0xff,0xff,0, 0xff,0,0xff, 0,0xff,0xff, 23,23,23};
2744 memcpy(bits
, orig_bits
, sizeof(bits
));
2745 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2748 stat
= GdipImageRotateFlip(bitmap
, Rotate90FlipNone
);
2751 stat
= GdipGetImageWidth(bitmap
, &width
);
2753 stat
= GdipGetImageHeight(bitmap
, &height
);
2758 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2760 expect(0xff00ffff, color
);
2762 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 0, &color
);
2764 expect(0xffff0000, color
);
2766 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 2, &color
);
2768 expect(0xffffff00, color
);
2770 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 2, &color
);
2772 expect(0xff0000ff, color
);
2776 expect(0xff, bits
[2]);
2778 GdipDisposeImage(bitmap
);
2780 memcpy(bits
, orig_bits
, sizeof(bits
));
2781 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2784 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipX
);
2787 stat
= GdipGetImageWidth(bitmap
, &width
);
2789 stat
= GdipGetImageHeight(bitmap
, &height
);
2794 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2796 expect(0xff0000ff, color
);
2798 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
2800 expect(0xffff0000, color
);
2802 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
2804 expect(0xffffff00, color
);
2806 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
2808 expect(0xff00ffff, color
);
2812 expect(0xff, bits
[2]);
2814 GdipDisposeImage(bitmap
);
2816 memcpy(bits
, orig_bits
, sizeof(bits
));
2817 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2820 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipY
);
2823 stat
= GdipGetImageWidth(bitmap
, &width
);
2825 stat
= GdipGetImageHeight(bitmap
, &height
);
2830 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2832 expect(0xff00ffff, color
);
2834 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
2836 expect(0xffffff00, color
);
2838 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
2840 expect(0xffff0000, color
);
2842 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
2844 expect(0xff0000ff, color
);
2848 expect(0xff, bits
[2]);
2850 GdipDisposeImage(bitmap
);
2853 static void test_remaptable(void)
2856 GpImageAttributes
*imageattr
;
2857 GpBitmap
*bitmap1
, *bitmap2
;
2858 GpGraphics
*graphics
;
2862 map
= GdipAlloc(sizeof(ColorMap
));
2864 map
->oldColor
.Argb
= 0xff00ff00;
2865 map
->newColor
.Argb
= 0xffff00ff;
2867 stat
= GdipSetImageAttributesRemapTable(NULL
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
2868 expect(InvalidParameter
, stat
);
2870 stat
= GdipCreateImageAttributes(&imageattr
);
2873 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, NULL
);
2874 expect(InvalidParameter
, stat
);
2876 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeCount
, TRUE
, 1, map
);
2877 expect(InvalidParameter
, stat
);
2879 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeAny
, TRUE
, 1, map
);
2880 expect(InvalidParameter
, stat
);
2882 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0, map
);
2883 expect(InvalidParameter
, stat
);
2885 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0, NULL
);
2888 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
2891 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
2894 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
2897 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff00ff00);
2900 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2903 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2904 UnitPixel
, imageattr
, NULL
, NULL
);
2907 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2909 ok(color_match(0xffff00ff, color
, 1), "Expected ffff00ff, got %.8x\n", color
);
2911 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2914 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2915 UnitPixel
, imageattr
, NULL
, NULL
);
2918 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2920 ok(color_match(0xff00ff00, color
, 1), "Expected ff00ff00, got %.8x\n", color
);
2922 GdipDeleteGraphics(graphics
);
2923 GdipDisposeImage((GpImage
*)bitmap1
);
2924 GdipDisposeImage((GpImage
*)bitmap2
);
2925 GdipDisposeImageAttributes(imageattr
);
2929 static void test_colorkey(void)
2932 GpImageAttributes
*imageattr
;
2933 GpBitmap
*bitmap1
, *bitmap2
;
2934 GpGraphics
*graphics
;
2937 stat
= GdipSetImageAttributesColorKeys(NULL
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
2938 expect(InvalidParameter
, stat
);
2940 stat
= GdipCreateImageAttributes(&imageattr
);
2943 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeCount
, TRUE
, 0xff405060, 0xff708090);
2944 expect(InvalidParameter
, stat
);
2946 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeAny
, TRUE
, 0xff405060, 0xff708090);
2947 expect(InvalidParameter
, stat
);
2949 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
2952 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
2955 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
2958 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0x20405060);
2961 stat
= GdipBitmapSetPixel(bitmap1
, 0, 1, 0x40506070);
2964 stat
= GdipBitmapSetPixel(bitmap1
, 1, 0, 0x60708090);
2967 stat
= GdipBitmapSetPixel(bitmap1
, 1, 1, 0xffffffff);
2970 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2973 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
2974 UnitPixel
, imageattr
, NULL
, NULL
);
2977 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2979 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
2981 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
2983 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
2985 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
2987 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
2989 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
2991 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
2993 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2996 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
2997 UnitPixel
, imageattr
, NULL
, NULL
);
3000 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
3002 ok(color_match(0x20405060, color
, 1), "Expected 20405060, got %.8x\n", color
);
3004 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
3006 ok(color_match(0x40506070, color
, 1), "Expected 40506070, got %.8x\n", color
);
3008 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
3010 ok(color_match(0x60708090, color
, 1), "Expected 60708090, got %.8x\n", color
);
3012 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
3014 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
3017 GdipDeleteGraphics(graphics
);
3018 GdipDisposeImage((GpImage
*)bitmap1
);
3019 GdipDisposeImage((GpImage
*)bitmap2
);
3020 GdipDisposeImageAttributes(imageattr
);
3023 static void test_dispose(void)
3027 char invalid_image
[256];
3029 stat
= GdipDisposeImage(NULL
);
3030 expect(InvalidParameter
, stat
);
3032 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, (GpBitmap
**)&image
);
3035 stat
= GdipDisposeImage(image
);
3038 stat
= GdipDisposeImage(image
);
3039 expect(ObjectBusy
, stat
);
3041 memset(invalid_image
, 0, 256);
3042 stat
= GdipDisposeImage((GpImage
*)invalid_image
);
3043 expect(ObjectBusy
, stat
);
3046 static LONG
obj_refcount(void *obj
)
3048 IUnknown_AddRef((IUnknown
*)obj
);
3049 return IUnknown_Release((IUnknown
*)obj
);
3052 static GpImage
*load_image(const BYTE
*image_data
, UINT image_size
)
3059 GpImage
*image
= NULL
, *clone
;
3060 ImageType image_type
;
3061 LONG refcount
, old_refcount
;
3063 hmem
= GlobalAlloc(0, image_size
);
3064 data
= GlobalLock(hmem
);
3065 memcpy(data
, image_data
, image_size
);
3068 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
3069 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
3070 if (hr
!= S_OK
) return NULL
;
3072 refcount
= obj_refcount(stream
);
3073 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3075 status
= GdipLoadImageFromStream(stream
, &image
);
3076 ok(status
== Ok
|| broken(status
== InvalidParameter
), /* XP */
3077 "GdipLoadImageFromStream error %d\n", status
);
3080 IStream_Release(stream
);
3084 status
= GdipGetImageType(image
, &image_type
);
3085 ok(status
== Ok
, "GdipGetImageType error %d\n", status
);
3087 refcount
= obj_refcount(stream
);
3088 if (image_type
== ImageTypeBitmap
)
3089 ok(refcount
> 1, "expected stream refcount > 1, got %d\n", refcount
);
3091 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3092 old_refcount
= refcount
;
3094 status
= GdipCloneImage(image
, &clone
);
3095 ok(status
== Ok
, "GdipCloneImage error %d\n", status
);
3096 refcount
= obj_refcount(stream
);
3097 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3098 status
= GdipDisposeImage(clone
);
3099 ok(status
== Ok
, "GdipDisposeImage error %d\n", status
);
3100 refcount
= obj_refcount(stream
);
3101 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3103 refcount
= IStream_Release(stream
);
3104 if (image_type
== ImageTypeBitmap
)
3105 ok(refcount
>= 1, "expected stream refcount != 0\n");
3107 ok(refcount
== 0, "expected stream refcount 0, got %d\n", refcount
);
3112 static void test_image_properties(void)
3114 static const struct test_data
3116 const BYTE
*image_data
;
3118 ImageType image_type
;
3120 UINT prop_count2
; /* if win7 behaves differently */
3121 /* 1st property attributes */
3123 UINT prop_size2
; /* if win7 behaves differently */
3125 UINT prop_id2
; /* if win7 behaves differently */
3129 { pngimage
, sizeof(pngimage
), ImageTypeBitmap
, 4, ~0, 1, 20, 0x5110, 0x132 },
3130 { jpgimage
, sizeof(jpgimage
), ImageTypeBitmap
, 2, ~0, 128, 0, 0x5090, 0x5091 },
3131 { tiffimage
, sizeof(tiffimage
), ImageTypeBitmap
, 16, 0, 4, 0, 0xfe, 0 },
3132 { bmpimage
, sizeof(bmpimage
), ImageTypeBitmap
, 0, 0, 0, 0, 0, 0 },
3133 { wmfimage
, sizeof(wmfimage
), ImageTypeMetafile
, 0, 0, 0, 0, 0, 0 }
3137 UINT prop_count
, prop_size
, i
;
3138 PROPID prop_id
[16] = { 0 };
3139 ImageType image_type
;
3146 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
3148 image
= load_image(td
[i
].image_data
, td
[i
].image_size
);
3151 trace("%u: failed to load image data\n", i
);
3155 status
= GdipGetImageType(image
, &image_type
);
3156 ok(status
== Ok
, "%u: GdipGetImageType error %d\n", i
, status
);
3157 ok(td
[i
].image_type
== image_type
, "%u: expected image_type %d, got %d\n",
3158 i
, td
[i
].image_type
, image_type
);
3160 status
= GdipGetPropertyCount(image
, &prop_count
);
3161 ok(status
== Ok
, "%u: GdipGetPropertyCount error %d\n", i
, status
);
3162 if (td
[i
].image_data
== pngimage
|| td
[i
].image_data
== jpgimage
)
3164 ok(td
[i
].prop_count
== prop_count
|| td
[i
].prop_count2
== prop_count
,
3165 " %u: expected property count %u or %u, got %u\n",
3166 i
, td
[i
].prop_count
, td
[i
].prop_count2
, prop_count
);
3168 ok(td
[i
].prop_count
== prop_count
|| td
[i
].prop_count2
== prop_count
,
3169 " %u: expected property count %u or %u, got %u\n",
3170 i
, td
[i
].prop_count
, td
[i
].prop_count2
, prop_count
);
3172 status
= GdipGetPropertyItemSize(NULL
, 0, &prop_size
);
3173 expect(InvalidParameter
, status
);
3174 status
= GdipGetPropertyItemSize(image
, 0, NULL
);
3175 expect(InvalidParameter
, status
);
3176 status
= GdipGetPropertyItemSize(image
, 0, &prop_size
);
3177 if (image_type
== ImageTypeMetafile
)
3178 expect(NotImplemented
, status
);
3180 expect(PropertyNotFound
, status
);
3182 status
= GdipGetPropertyItem(NULL
, 0, 0, &item
.data
);
3183 expect(InvalidParameter
, status
);
3184 status
= GdipGetPropertyItem(image
, 0, 0, NULL
);
3185 expect(InvalidParameter
, status
);
3186 status
= GdipGetPropertyItem(image
, 0, 0, &item
.data
);
3187 if (image_type
== ImageTypeMetafile
)
3188 expect(NotImplemented
, status
);
3190 expect(PropertyNotFound
, status
);
3192 /* FIXME: remove once Wine is fixed */
3193 if (td
[i
].prop_count
!= prop_count
)
3195 GdipDisposeImage(image
);
3199 status
= GdipGetPropertyIdList(NULL
, prop_count
, prop_id
);
3200 expect(InvalidParameter
, status
);
3201 status
= GdipGetPropertyIdList(image
, prop_count
, NULL
);
3202 expect(InvalidParameter
, status
);
3203 status
= GdipGetPropertyIdList(image
, 0, prop_id
);
3204 if (image_type
== ImageTypeMetafile
)
3205 expect(NotImplemented
, status
);
3206 else if (prop_count
== 0)
3209 expect(InvalidParameter
, status
);
3210 status
= GdipGetPropertyIdList(image
, prop_count
- 1, prop_id
);
3211 if (image_type
== ImageTypeMetafile
)
3212 expect(NotImplemented
, status
);
3214 expect(InvalidParameter
, status
);
3215 status
= GdipGetPropertyIdList(image
, prop_count
+ 1, prop_id
);
3216 if (image_type
== ImageTypeMetafile
)
3217 expect(NotImplemented
, status
);
3219 expect(InvalidParameter
, status
);
3220 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3221 if (image_type
== ImageTypeMetafile
)
3222 expect(NotImplemented
, status
);
3226 if (prop_count
!= 0)
3227 ok(td
[i
].prop_id
== prop_id
[0] || td
[i
].prop_id2
== prop_id
[0],
3228 " %u: expected property id %#x or %#x, got %#x\n",
3229 i
, td
[i
].prop_id
, td
[i
].prop_id2
, prop_id
[0]);
3234 status
= GdipGetPropertyItemSize(image
, prop_id
[0], &prop_size
);
3235 if (prop_count
== 0)
3236 expect(PropertyNotFound
, status
);
3241 assert(sizeof(item
) >= prop_size
);
3242 ok(prop_size
> sizeof(PropertyItem
), "%u: got too small prop_size %u\n",
3244 ok(td
[i
].prop_size
+ sizeof(PropertyItem
) == prop_size
||
3245 td
[i
].prop_size2
+ sizeof(PropertyItem
) == prop_size
,
3246 " %u: expected property size %u or %u, got %u\n",
3247 i
, td
[i
].prop_size
, td
[i
].prop_size2
, prop_size
);
3249 status
= GdipGetPropertyItem(image
, prop_id
[0], 0, &item
.data
);
3250 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3251 "%u: expected InvalidParameter, got %d\n", i
, status
);
3252 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
- 1, &item
.data
);
3253 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3254 "%u: expected InvalidParameter, got %d\n", i
, status
);
3255 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
+ 1, &item
.data
);
3256 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3257 "%u: expected InvalidParameter, got %d\n", i
, status
);
3258 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
, &item
.data
);
3260 ok(prop_id
[0] == item
.data
.id
,
3261 "%u: expected property id %#x, got %#x\n", i
, prop_id
[0], item
.data
.id
);
3265 GdipDisposeImage(image
);
3273 #define IFD_RATIONAL 5
3275 #define IFD_UNDEFINED 7
3276 #define IFD_SSHORT 8
3278 #define IFD_SRATIONAL 10
3279 #define IFD_FLOAT 11
3280 #define IFD_DOUBLE 12
3282 #ifndef PropertyTagTypeSByte
3283 #define PropertyTagTypeSByte 6
3284 #define PropertyTagTypeSShort 8
3285 #define PropertyTagTypeFloat 11
3286 #define PropertyTagTypeDouble 12
3289 static UINT
documented_type(UINT type
)
3293 case PropertyTagTypeSByte
: return PropertyTagTypeByte
;
3294 case PropertyTagTypeSShort
: return PropertyTagTypeShort
;
3295 case PropertyTagTypeFloat
: return PropertyTagTypeUndefined
;
3296 case PropertyTagTypeDouble
: return PropertyTagTypeUndefined
;
3297 default: return type
;
3301 #include "pshpack2.h"
3316 static const struct tiff_data
3321 USHORT number_of_entries
;
3322 struct IFD_entry entry
[40];
3324 struct IFD_rational xres
;
3326 struct IFD_rational srational_val
;
3331 struct IFD_rational rational
[3];
3335 #ifdef WORDS_BIGENDIAN
3341 FIELD_OFFSET(struct tiff_data
, number_of_entries
),
3344 { 0xff, IFD_SHORT
, 1, 0 }, /* SUBFILETYPE */
3345 { 0x100, IFD_LONG
, 1, 1 }, /* IMAGEWIDTH */
3346 { 0x101, IFD_LONG
, 1, 1 }, /* IMAGELENGTH */
3347 { 0x102, IFD_SHORT
, 1, 1 }, /* BITSPERSAMPLE */
3348 { 0x103, IFD_SHORT
, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
3349 { 0x106, IFD_SHORT
, 1, 1 }, /* PHOTOMETRIC */
3350 { 0x111, IFD_LONG
, 1, FIELD_OFFSET(struct tiff_data
, pixel_data
) }, /* STRIPOFFSETS */
3351 { 0x115, IFD_SHORT
, 1, 1 }, /* SAMPLESPERPIXEL */
3352 { 0x116, IFD_LONG
, 1, 1 }, /* ROWSPERSTRIP */
3353 { 0x117, IFD_LONG
, 1, 1 }, /* STRIPBYTECOUNT */
3354 { 0x11a, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3355 { 0x11b, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3356 { 0x128, IFD_SHORT
, 1, 2 }, /* RESOLUTIONUNIT */
3357 { 0xf001, IFD_BYTE
, 1, 0x11223344 },
3358 { 0xf002, IFD_BYTE
, 4, 0x11223344 },
3359 { 0xf003, IFD_SBYTE
, 1, 0x11223344 },
3360 { 0xf004, IFD_SSHORT
, 1, 0x11223344 },
3361 { 0xf005, IFD_SSHORT
, 2, 0x11223344 },
3362 { 0xf006, IFD_SLONG
, 1, 0x11223344 },
3363 { 0xf007, IFD_FLOAT
, 1, 0x11223344 },
3364 { 0xf008, IFD_DOUBLE
, 1, FIELD_OFFSET(struct tiff_data
, double_val
) },
3365 { 0xf009, IFD_SRATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, srational_val
) },
3366 { 0xf00a, IFD_BYTE
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3367 { 0xf00b, IFD_SSHORT
, 4, FIELD_OFFSET(struct tiff_data
, short_val
) },
3368 { 0xf00c, IFD_SLONG
, 2, FIELD_OFFSET(struct tiff_data
, long_val
) },
3369 { 0xf00e, IFD_ASCII
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3370 { 0xf00f, IFD_ASCII
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3371 { 0xf010, IFD_UNDEFINED
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3372 { 0xf011, IFD_UNDEFINED
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3373 /* Some gdiplus versions ignore these fields.
3374 { 0xf012, IFD_BYTE, 0, 0x11223344 },
3375 { 0xf013, IFD_SHORT, 0, 0x11223344 },
3376 { 0xf014, IFD_LONG, 0, 0x11223344 },
3377 { 0xf015, IFD_FLOAT, 0, 0x11223344 },*/
3378 { 0xf016, IFD_SRATIONAL
, 3, FIELD_OFFSET(struct tiff_data
, rational
) },
3379 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3380 { 0xf017, IFD_FLOAT
, 2, FIELD_OFFSET(struct tiff_data
, float_val
) },
3384 1234567890.0987654321,
3385 { 0x1a2b3c4d, 0x5a6b7c8d },
3387 { 0x0101, 0x0202, 0x0303, 0x0404 },
3388 { 0x11223344, 0x55667788 },
3389 { (FLOAT
)1234.5678, (FLOAT
)8765.4321 },
3390 { { 0x01020304, 0x05060708 }, { 0x10203040, 0x50607080 }, { 0x11223344, 0x55667788 } },
3391 { 0x11, 0x22, 0x33, 0 }
3393 #include "poppack.h"
3395 static void test_tiff_properties(void)
3397 static const struct test_data
3399 ULONG type
, id
, length
;
3400 const BYTE value
[24];
3403 { PropertyTagTypeShort
, 0xff, 2, { 0 } },
3404 { PropertyTagTypeLong
, 0x100, 4, { 1 } },
3405 { PropertyTagTypeLong
, 0x101, 4, { 1 } },
3406 { PropertyTagTypeShort
, 0x102, 2, { 1 } },
3407 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3408 { PropertyTagTypeShort
, 0x106, 2, { 1 } },
3409 { PropertyTagTypeLong
, 0x111, 4, { 0x44,0x02 } },
3410 { PropertyTagTypeShort
, 0x115, 2, { 1 } },
3411 { PropertyTagTypeLong
, 0x116, 4, { 1 } },
3412 { PropertyTagTypeLong
, 0x117, 4, { 1 } },
3413 { PropertyTagTypeRational
, 0x11a, 8, { 0x84,0x03,0,0,0x03 } },
3414 { PropertyTagTypeRational
, 0x11b, 8, { 0x84,0x03,0,0,0x03 } },
3415 { PropertyTagTypeShort
, 0x128, 2, { 2 } },
3416 { PropertyTagTypeByte
, 0xf001, 1, { 0x44 } },
3417 { PropertyTagTypeByte
, 0xf002, 4, { 0x44,0x33,0x22,0x11 } },
3418 { PropertyTagTypeSByte
, 0xf003, 1, { 0x44 } },
3419 { PropertyTagTypeSShort
, 0xf004, 2, { 0x44,0x33 } },
3420 { PropertyTagTypeSShort
, 0xf005, 4, { 0x44,0x33,0x22,0x11 } },
3421 { PropertyTagTypeSLONG
, 0xf006, 4, { 0x44,0x33,0x22,0x11 } },
3422 { PropertyTagTypeFloat
, 0xf007, 4, { 0x44,0x33,0x22,0x11 } },
3423 { PropertyTagTypeDouble
, 0xf008, 8, { 0x2c,0x52,0x86,0xb4,0x80,0x65,0xd2,0x41 } },
3424 { PropertyTagTypeSRational
, 0xf009, 8, { 0x4d, 0x3c, 0x2b, 0x1a, 0x8d, 0x7c, 0x6b, 0x5a } },
3425 { PropertyTagTypeByte
, 0xf00a, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3426 { PropertyTagTypeSShort
, 0xf00b, 8, { 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04 } },
3427 { PropertyTagTypeSLONG
, 0xf00c, 8, { 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3428 { PropertyTagTypeASCII
, 0xf00e, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3429 { PropertyTagTypeASCII
, 0xf00f, 5, { 'a','b','c','d' } },
3430 { PropertyTagTypeUndefined
, 0xf010, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3431 { PropertyTagTypeUndefined
, 0xf011, 4, { 'a','b','c','d' } },
3432 { PropertyTagTypeSRational
, 0xf016, 24,
3433 { 0x04,0x03,0x02,0x01,0x08,0x07,0x06,0x05,
3434 0x40,0x30,0x20,0x10,0x80,0x70,0x60,0x50,
3435 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3436 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3437 { PropertyTagTypeFloat
, 0xf017, 8, { 0x2b,0x52,0x9a,0x44,0xba,0xf5,0x08,0x46 } },
3442 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3444 PropertyItem
*prop_item
;
3446 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
));
3449 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3453 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3455 expect(1, dim_count
);
3457 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3459 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3461 frame_count
= 0xdeadbeef;
3462 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3464 expect(1, frame_count
);
3466 prop_count
= 0xdeadbeef;
3467 status
= GdipGetPropertyCount(image
, &prop_count
);
3469 ok(prop_count
== sizeof(td
)/sizeof(td
[0]) ||
3470 broken(prop_count
== sizeof(td
)/sizeof(td
[0]) - 1) /* Win7 SP0 */,
3471 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
3473 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3475 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3478 for (i
= 0; i
< prop_count
; i
++)
3480 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &prop_size
);
3482 if (status
!= Ok
) break;
3483 ok(prop_size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, prop_size
);
3485 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, prop_size
);
3486 status
= GdipGetPropertyItem(image
, prop_id
[i
], prop_size
, prop_item
);
3488 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3489 ok(td
[i
].type
== prop_item
->type
||
3490 /* Win7 stopped using proper but not documented types, and it
3491 looks broken since TypeFloat and TypeDouble now reported as
3492 TypeUndefined, and signed types reported as unsigned. */
3493 broken(prop_item
->type
== documented_type(td
[i
].type
)),
3494 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3495 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3496 prop_size
-= sizeof(*prop_item
);
3497 ok(prop_item
->length
== prop_size
, "%u: expected length %u, got %u\n", i
, prop_size
, prop_item
->length
);
3498 ok(td
[i
].length
== prop_item
->length
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_item
->length
+1) /* XP */,
3499 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3500 ok(td
[i
].length
== prop_size
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_size
+1) /* XP */,
3501 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_size
);
3502 if (td
[i
].length
== prop_item
->length
)
3504 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3505 ok(match
|| broken(td
[i
].length
<= 4 && !match
), "%u: data mismatch\n", i
);
3509 BYTE
*data
= prop_item
->value
;
3510 trace("id %#x:", prop_item
->id
);
3511 for (j
= 0; j
< prop_item
->length
; j
++)
3512 trace(" %02x", data
[j
]);
3516 HeapFree(GetProcessHeap(), 0, prop_item
);
3519 HeapFree(GetProcessHeap(), 0, prop_id
);
3521 GdipDisposeImage(image
);
3524 static void test_GdipGetAllPropertyItems(void)
3526 static const struct test_data
3528 ULONG type
, id
, length
;
3532 { PropertyTagTypeLong
, 0xfe, 4, { 0 } },
3533 { PropertyTagTypeShort
, 0x100, 2, { 1 } },
3534 { PropertyTagTypeShort
, 0x101, 2, { 1 } },
3535 { PropertyTagTypeShort
, 0x102, 6, { 8,0,8,0,8,0 } },
3536 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3537 { PropertyTagTypeShort
, 0x106, 2, { 2,0 } },
3538 { PropertyTagTypeASCII
, 0x10d, 27, "/home/meh/Desktop/test.tif" },
3539 { PropertyTagTypeLong
, 0x111, 4, { 8,0,0,0 } },
3540 { PropertyTagTypeShort
, 0x112, 2, { 1 } },
3541 { PropertyTagTypeShort
, 0x115, 2, { 3,0 } },
3542 { PropertyTagTypeShort
, 0x116, 2, { 0x40,0 } },
3543 { PropertyTagTypeLong
, 0x117, 4, { 3,0,0,0 } },
3544 { PropertyTagTypeRational
, 0x11a, 8, { 0,0,0,72,0,0,0,1 } },
3545 { PropertyTagTypeRational
, 0x11b, 8, { 0,0,0,72,0,0,0,1 } },
3546 { PropertyTagTypeShort
, 0x11c, 2, { 1 } },
3547 { PropertyTagTypeShort
, 0x128, 2, { 2 } }
3552 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3553 UINT total_size
, total_count
;
3555 PropertyItem
*prop_item
;
3556 const char *item_data
;
3558 image
= load_image(tiffimage
, sizeof(tiffimage
));
3559 ok(image
!= 0, "Failed to load TIFF image data\n");
3562 dim_count
= 0xdeadbeef;
3563 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3565 expect(1, dim_count
);
3567 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3569 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3571 frame_count
= 0xdeadbeef;
3572 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3574 expect(1, frame_count
);
3576 prop_count
= 0xdeadbeef;
3577 status
= GdipGetPropertyCount(image
, &prop_count
);
3579 ok(prop_count
== sizeof(td
)/sizeof(td
[0]),
3580 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
3582 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3584 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3588 for (i
= 0; i
< prop_count
; i
++)
3591 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
3593 if (status
!= Ok
) break;
3594 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
3598 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
3599 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
3601 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3602 ok(td
[i
].type
== prop_item
->type
,
3603 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3604 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3605 size
-= sizeof(*prop_item
);
3606 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
3607 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3608 if (td
[i
].length
== prop_item
->length
)
3610 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3611 ok(match
, "%u: data mismatch\n", i
);
3615 BYTE
*data
= prop_item
->value
;
3616 trace("id %#x:", prop_item
->id
);
3617 for (j
= 0; j
< prop_item
->length
; j
++)
3618 trace(" %02x", data
[j
]);
3622 HeapFree(GetProcessHeap(), 0, prop_item
);
3625 HeapFree(GetProcessHeap(), 0, prop_id
);
3627 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
3628 expect(InvalidParameter
, status
);
3629 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
3630 expect(InvalidParameter
, status
);
3631 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
3632 expect(InvalidParameter
, status
);
3633 status
= GdipGetPropertySize(image
, NULL
, NULL
);
3634 expect(InvalidParameter
, status
);
3635 total_size
= 0xdeadbeef;
3636 total_count
= 0xdeadbeef;
3637 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
3639 ok(prop_count
== total_count
,
3640 "expected total property count %u, got %u\n", prop_count
, total_count
);
3641 ok(prop_size
== total_size
,
3642 "expected total property size %u, got %u\n", prop_size
, total_size
);
3644 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
3646 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
3647 expect(InvalidParameter
, status
);
3648 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
3649 expect(InvalidParameter
, status
);
3650 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3651 expect(InvalidParameter
, status
);
3652 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3653 expect(InvalidParameter
, status
);
3654 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
3655 expect(InvalidParameter
, status
);
3656 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
3657 expect(InvalidParameter
, status
);
3658 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
3661 item_data
= (const char *)(prop_item
+ prop_count
);
3662 for (i
= 0; i
< prop_count
; i
++)
3664 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
3665 i
, item_data
, prop_item
[i
].value
);
3666 ok(td
[i
].type
== prop_item
[i
].type
,
3667 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
3668 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
3669 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
3670 if (td
[i
].length
== prop_item
[i
].length
)
3672 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
3673 ok(match
, "%u: data mismatch\n", i
);
3677 BYTE
*data
= prop_item
[i
].value
;
3678 trace("id %#x:", prop_item
[i
].id
);
3679 for (j
= 0; j
< prop_item
[i
].length
; j
++)
3680 trace(" %02x", data
[j
]);
3684 item_data
+= prop_item
[i
].length
;
3687 HeapFree(GetProcessHeap(), 0, prop_item
);
3689 GdipDisposeImage(image
);
3692 static void test_tiff_palette(void)
3703 ARGB
*entries
= palette
.pal
.Entries
;
3705 /* 1bpp TIFF without palette */
3706 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
));
3709 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3713 status
= GdipGetImagePixelFormat(image
, &format
);
3715 ok(format
== PixelFormat1bppIndexed
, "expected PixelFormat1bppIndexed, got %#x\n", format
);
3717 status
= GdipGetImagePaletteSize(image
, &size
);
3718 ok(status
== Ok
|| broken(status
== GenericError
), /* XP */
3719 "GdipGetImagePaletteSize error %d\n", status
);
3720 if (status
== GenericError
)
3722 GdipDisposeImage(image
);
3725 expect(sizeof(ColorPalette
) + sizeof(ARGB
), size
);
3727 status
= GdipGetImagePalette(image
, &palette
.pal
, size
);
3729 expect(0, palette
.pal
.Flags
);
3730 expect(2, palette
.pal
.Count
);
3731 if (palette
.pal
.Count
== 2)
3733 ok(entries
[0] == 0xff000000, "expected 0xff000000, got %#x\n", entries
[0]);
3734 ok(entries
[1] == 0xffffffff, "expected 0xffffffff, got %#x\n", entries
[1]);
3737 GdipDisposeImage(image
);
3740 static void test_bitmapbits(void)
3743 static const BYTE pixels_24
[48] =
3745 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3746 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3747 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3748 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0
3750 static const BYTE pixels_00
[48] =
3752 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3753 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3754 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3755 0,0,0, 0,0,0, 0,0,0, 0,0,0
3757 static const BYTE pixels_24_77
[64] =
3759 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3760 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3761 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3762 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3763 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3764 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3766 static const BYTE pixels_77
[64] =
3768 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3769 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3770 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3771 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3772 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3773 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3774 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3775 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3777 static const BYTE pixels_8
[16] =
3779 0x01,0,0x01,0,0x01,0,0x01,0,
3780 0x01,0,0x01,0,0x01,0,0x01,0
3782 static const BYTE pixels_8_77
[64] =
3784 0x01,0,0x01,0,0x01,0,0x01,0,
3785 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3786 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3787 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3788 0x01,0,0x01,0,0x01,0,0x01,0,
3789 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3790 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3791 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3793 static const BYTE pixels_1_77
[64] =
3795 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3796 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3797 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3798 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3799 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3800 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3801 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3802 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3804 static const BYTE pixels_1
[8] = {0xaa,0,0,0,0xaa,0,0,0};
3805 static const struct test_data
3812 const BYTE
*pixels_unlocked
;
3816 { PixelFormat24bppRGB
, 24, 0xfff0, 24, 48, pixels_24
, pixels_00
},
3818 { PixelFormat24bppRGB
, 24, 0, 24, 48, pixels_24
, pixels_00
},
3819 { PixelFormat24bppRGB
, 24, ImageLockModeRead
, 24, 48, pixels_24
, pixels_00
},
3820 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
3821 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
3822 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_24_77
, pixels_24
},
3823 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3824 { PixelFormat24bppRGB
, 24, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3826 { PixelFormat8bppIndexed
, 8, 0, 8, 16, pixels_8
, pixels_24
},
3827 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
, 8, 16, pixels_8
, pixels_24
},
3828 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
3829 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
3830 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_8_77
, pixels_24
},
3831 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3832 { PixelFormat8bppIndexed
, 8, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3834 { PixelFormat1bppIndexed
, 1, 0, 4, 8, pixels_1
, pixels_24
},
3835 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
, 4, 8, pixels_1
, pixels_24
},
3836 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
3837 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
3838 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_1_77
, pixels_24
},
3839 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3840 { PixelFormat1bppIndexed
, 1, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3852 ARGB
*entries
= palette
.pal
.Entries
;
3854 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
3856 BYTE pixels
[sizeof(pixels_24
)];
3857 memcpy(pixels
, pixels_24
, sizeof(pixels_24
));
3858 status
= GdipCreateBitmapFromScan0(8, 2, 24, PixelFormat24bppRGB
, pixels
, &bitmap
);
3861 /* associate known palette with pixel data */
3862 palette
.pal
.Flags
= PaletteFlagsGrayScale
;
3863 palette
.pal
.Count
= 2;
3864 entries
[0] = 0xff000000;
3865 entries
[1] = 0xffffffff;
3866 status
= GdipSetImagePalette((GpImage
*)bitmap
, &palette
.pal
);
3869 memset(&data
, 0xfe, sizeof(data
));
3870 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
3872 memset(buf
, 0x77, sizeof(buf
));
3876 status
= GdipBitmapLockBits(bitmap
, NULL
, td
[i
].mode
, td
[i
].format
, &data
);
3877 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* XP */, "%u: GdipBitmapLockBits error %d\n", i
, status
);
3880 GdipDisposeImage((GpImage
*)bitmap
);
3883 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
3884 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
3885 ok(td
[i
].stride
== data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].stride
, data
.Stride
);
3886 ok(td
[i
].format
== data
.PixelFormat
, "%u: expected %d, got %d\n", i
, td
[i
].format
, data
.PixelFormat
);
3887 ok(td
[i
].size
== data
.Height
* data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].size
, data
.Height
* data
.Stride
);
3888 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
3889 ok(data
.Scan0
== buf
, "%u: got wrong buffer\n", i
);
3890 if (td
[i
].size
== data
.Height
* data
.Stride
)
3892 UINT j
, match
, width_bytes
= (data
.Width
* td
[i
].bpp
) / 8;
3895 for (j
= 0; j
< data
.Height
; j
++)
3897 if (memcmp((const BYTE
*)data
.Scan0
+ j
* data
.Stride
, td
[i
].pixels
+ j
* data
.Stride
, width_bytes
) != 0)
3903 if ((td
[i
].mode
& (ImageLockModeRead
|ImageLockModeUserInputBuf
)) || td
[i
].format
== PixelFormat24bppRGB
)
3906 "%u: data should match\n", i
);
3909 BYTE
*bits
= data
.Scan0
;
3910 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
3911 for (j
= 0; j
< td
[i
].size
; j
++)
3912 trace(" %02x", bits
[j
]);
3917 ok(!match
, "%u: data shouldn't match\n", i
);
3919 memset(data
.Scan0
, 0, td
[i
].size
);
3922 status
= GdipBitmapUnlockBits(bitmap
, &data
);
3923 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
3925 memset(&data
, 0xfe, sizeof(data
));
3926 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
3927 ok(status
== Ok
, "%u: GdipBitmapLockBits error %d\n", i
, status
);
3928 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
3929 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
3930 ok(data
.Stride
== 24, "%u: expected 24, got %d\n", i
, data
.Stride
);
3931 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "%u: got wrong pixel format %d\n", i
, data
.PixelFormat
);
3932 ok(data
.Height
* data
.Stride
== 48, "%u: expected 48, got %d\n", i
, data
.Height
* data
.Stride
);
3933 if (data
.Height
* data
.Stride
== 48)
3935 int match
= memcmp(data
.Scan0
, td
[i
].pixels_unlocked
, 48) == 0;
3936 ok(match
, "%u: data should match\n", i
);
3940 BYTE
*bits
= data
.Scan0
;
3941 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
3942 for (j
= 0; j
< 48; j
++)
3943 trace(" %02x", bits
[j
]);
3948 status
= GdipBitmapUnlockBits(bitmap
, &data
);
3949 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
3951 status
= GdipDisposeImage((GpImage
*)bitmap
);
3956 static void test_DrawImage(void)
3958 BYTE black_1x1
[4] = { 0,0,0,0 };
3959 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
3960 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
3961 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
3962 0,0,0,0,0,0,0xff,0xff };
3969 GpGraphics
*graphics
;
3972 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
3974 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
3977 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
3979 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
3981 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
3983 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
3986 status
= GdipDrawImageI(graphics
, u1
.image
, 0, 0);
3989 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
3990 ok(match
, "data should match\n");
3993 UINT i
, size
= sizeof(white_2x2
);
3994 BYTE
*bits
= white_2x2
;
3995 for (i
= 0; i
< size
; i
++)
3996 trace(" %02x", bits
[i
]);
4000 status
= GdipDeleteGraphics(graphics
);
4002 status
= GdipDisposeImage(u1
.image
);
4004 status
= GdipDisposeImage(u2
.image
);
4008 static void test_GdipDrawImagePointRect(void)
4010 BYTE black_1x1
[4] = { 0,0,0,0 };
4011 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
4012 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
4013 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
4014 0,0,0,0,0,0,0xff,0xff };
4021 GpGraphics
*graphics
;
4024 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
4026 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4029 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
4031 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
4033 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4035 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4038 status
= GdipDrawImagePointRectI(graphics
, u1
.image
, 0, 0, 0, 0, 1, 1, UnitPixel
);
4041 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
4042 ok(match
, "data should match\n");
4045 UINT i
, size
= sizeof(white_2x2
);
4046 BYTE
*bits
= white_2x2
;
4047 for (i
= 0; i
< size
; i
++)
4048 trace(" %02x", bits
[i
]);
4052 status
= GdipDeleteGraphics(graphics
);
4054 status
= GdipDisposeImage(u1
.image
);
4056 status
= GdipDisposeImage(u2
.image
);
4060 static void test_image_format(void)
4062 static const PixelFormat fmt
[] =
4064 PixelFormat1bppIndexed
, PixelFormat4bppIndexed
, PixelFormat8bppIndexed
,
4065 PixelFormat16bppGrayScale
, PixelFormat16bppRGB555
, PixelFormat16bppRGB565
,
4066 PixelFormat16bppARGB1555
, PixelFormat24bppRGB
, PixelFormat32bppRGB
,
4067 PixelFormat32bppARGB
, PixelFormat32bppPARGB
, PixelFormat48bppRGB
,
4068 PixelFormat64bppARGB
, PixelFormat64bppPARGB
, PixelFormat32bppCMYK
4079 for (i
= 0; i
< sizeof(fmt
)/sizeof(fmt
[0]); i
++)
4081 status
= GdipCreateBitmapFromScan0(1, 1, 0, fmt
[i
], NULL
, &bitmap
);
4082 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* before win7 */,
4083 "GdipCreateBitmapFromScan0 error %d\n", status
);
4084 if (status
!= Ok
) continue;
4086 status
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
4088 expect(fmt
[i
], format
);
4090 status
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
4091 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4092 todo_wine
expect(InvalidParameter
, status
);
4096 ret
= GetObjectW(hbitmap
, sizeof(bm
), &bm
);
4097 expect(sizeof(bm
), ret
);
4098 expect(0, bm
.bmType
);
4099 expect(1, bm
.bmWidth
);
4100 expect(1, bm
.bmHeight
);
4101 expect(4, bm
.bmWidthBytes
);
4102 expect(1, bm
.bmPlanes
);
4103 expect(32, bm
.bmBitsPixel
);
4104 DeleteObject(hbitmap
);
4107 status
= GdipGetImageThumbnail((GpImage
*)bitmap
, 0, 0, &thumb
, NULL
, NULL
);
4108 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4110 ok(status
== OutOfMemory
|| broken(status
== InvalidParameter
) /* before win7 */,
4111 "expected OutOfMemory, got %d\n", status
);
4116 status
= GdipGetImagePixelFormat(thumb
, &format
);
4118 ok(format
== PixelFormat32bppPARGB
|| broken(format
!= PixelFormat32bppPARGB
) /* before win7 */,
4119 "expected PixelFormat32bppPARGB, got %#x\n", format
);
4120 status
= GdipDisposeImage(thumb
);
4124 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4125 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4126 todo_wine
expect(InvalidParameter
, status
);
4130 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4134 status
= GdipDisposeImage((GpImage
*)bitmap
);
4139 static void test_DrawImage_scale(void)
4141 static const BYTE back_8x1
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
4142 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4143 static const BYTE image_080
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,
4144 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4145 static const BYTE image_100
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,
4146 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4147 static const BYTE image_120
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,
4148 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4149 static const BYTE image_150
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4150 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4151 static const BYTE image_180
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4152 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4153 static const BYTE image_200
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4154 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4155 static const BYTE image_250
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,
4156 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4157 static const BYTE image_120_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4158 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4159 static const BYTE image_150_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4160 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4161 static const BYTE image_200_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4162 0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40 };
4163 static const BYTE image_250_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4164 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4165 static const struct test_data
4168 PixelOffsetMode pixel_offset_mode
;
4173 { 0.8, PixelOffsetModeNone
, image_080
}, /* 0 */
4174 { 1.0, PixelOffsetModeNone
, image_100
},
4175 { 1.2, PixelOffsetModeNone
, image_120
},
4176 { 1.5, PixelOffsetModeNone
, image_150
},
4177 { 1.8, PixelOffsetModeNone
, image_180
},
4178 { 2.0, PixelOffsetModeNone
, image_200
},
4179 { 2.5, PixelOffsetModeNone
, image_250
},
4181 { 0.8, PixelOffsetModeHighSpeed
, image_080
}, /* 7 */
4182 { 1.0, PixelOffsetModeHighSpeed
, image_100
},
4183 { 1.2, PixelOffsetModeHighSpeed
, image_120
},
4184 { 1.5, PixelOffsetModeHighSpeed
, image_150
},
4185 { 1.8, PixelOffsetModeHighSpeed
, image_180
},
4186 { 2.0, PixelOffsetModeHighSpeed
, image_200
},
4187 { 2.5, PixelOffsetModeHighSpeed
, image_250
},
4189 { 0.8, PixelOffsetModeHalf
, image_080
}, /* 14 */
4190 { 1.0, PixelOffsetModeHalf
, image_100
},
4191 { 1.2, PixelOffsetModeHalf
, image_120_half
, TRUE
},
4192 { 1.5, PixelOffsetModeHalf
, image_150_half
, TRUE
},
4193 { 1.8, PixelOffsetModeHalf
, image_180
},
4194 { 2.0, PixelOffsetModeHalf
, image_200_half
, TRUE
},
4195 { 2.5, PixelOffsetModeHalf
, image_250_half
, TRUE
},
4197 { 0.8, PixelOffsetModeHighQuality
, image_080
}, /* 21 */
4198 { 1.0, PixelOffsetModeHighQuality
, image_100
},
4199 { 1.2, PixelOffsetModeHighQuality
, image_120_half
, TRUE
},
4200 { 1.5, PixelOffsetModeHighQuality
, image_150_half
, TRUE
},
4201 { 1.8, PixelOffsetModeHighQuality
, image_180
},
4202 { 2.0, PixelOffsetModeHighQuality
, image_200_half
, TRUE
},
4203 { 2.5, PixelOffsetModeHighQuality
, image_250_half
, TRUE
},
4205 BYTE src_2x1
[6] = { 0x80,0x80,0x80,0x80,0x80,0x80 };
4213 GpGraphics
*graphics
;
4217 status
= GdipCreateBitmapFromScan0(2, 1, 4, PixelFormat24bppRGB
, src_2x1
, &u1
.bitmap
);
4219 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4222 status
= GdipCreateBitmapFromScan0(8, 1, 24, PixelFormat24bppRGB
, dst_8x1
, &u2
.bitmap
);
4224 status
= GdipBitmapSetResolution(u2
.bitmap
, 100.0, 100.0);
4226 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4228 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4231 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
4233 status
= GdipSetPixelOffsetMode(graphics
, td
[i
].pixel_offset_mode
);
4236 status
= GdipCreateMatrix2(td
[i
].scale_x
, 0.0, 0.0, 1.0, 0.0, 0.0, &matrix
);
4238 status
= GdipSetWorldTransform(graphics
, matrix
);
4240 GdipDeleteMatrix(matrix
);
4242 memcpy(dst_8x1
, back_8x1
, sizeof(dst_8x1
));
4243 status
= GdipDrawImageI(graphics
, u1
.image
, 1, 0);
4246 match
= memcmp(dst_8x1
, td
[i
].image
, sizeof(dst_8x1
)) == 0;
4247 if (!match
&& td
[i
].todo
)
4248 todo_wine
ok(match
, "%d: data should match\n", i
);
4250 ok(match
, "%d: data should match\n", i
);
4253 UINT i
, size
= sizeof(dst_8x1
);
4254 const BYTE
*bits
= dst_8x1
;
4255 for (i
= 0; i
< size
; i
++)
4256 trace(" %02x", bits
[i
]);
4261 status
= GdipDeleteGraphics(graphics
);
4263 status
= GdipDisposeImage(u1
.image
);
4265 status
= GdipDisposeImage(u2
.image
);
4269 static const BYTE animatedgif
[] = {
4270 'G','I','F','8','9','a',0x01,0x00,0x01,0x00,0xA1,0x02,0x00,
4271 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
4272 /*0x21,0xFF,0x0B,'A','N','I','M','E','X','T','S','1','.','0',*/
4273 0x21,0xFF,0x0B,'N','E','T','S','C','A','P','E','2','.','0',
4274 0x03,0x01,0x05,0x00,0x00,
4275 0x21,0xFE,0x0C,'H','e','l','l','o',' ','W','o','r','l','d','!',0x00,
4276 0x21,0x01,0x0D,'a','n','i','m','a','t','i','o','n','.','g','i','f',0x00,
4277 0x21,0xF9,0x04,0xff,0x0A,0x00,0x08,0x00,
4278 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4279 0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,
4280 0x02,0x02,0x4C,0x01,0x00,
4281 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','1',0x00,
4282 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','1',0x00,
4283 0x21,0xF9,0x04,0x00,0x14,0x00,0x01,0x00,
4284 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4285 0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,
4286 0x02,0x02,0x44,0x01,0x00,
4287 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','2',0x00,
4288 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','2',0x00,0x3B
4291 static void test_gif_properties(void)
4293 static const struct test_data
4295 ULONG type
, id
, length
;
4296 const BYTE value
[13];
4299 { PropertyTagTypeLong
, PropertyTagFrameDelay
, 8, { 10,0,0,0,20,0,0,0 } },
4300 { PropertyTagTypeASCII
, PropertyTagExifUserComment
, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
4301 { PropertyTagTypeShort
, PropertyTagLoopCount
, 2, { 5,0 } },
4302 { PropertyTagTypeByte
, PropertyTagGlobalPalette
, 12, { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c } },
4303 { PropertyTagTypeByte
, PropertyTagIndexBackground
, 1, { 2 } },
4304 { PropertyTagTypeByte
, PropertyTagIndexTransparent
, 1, { 8 } }
4309 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
4310 UINT total_size
, total_count
;
4312 PropertyItem
*prop_item
;
4313 const char *item_data
;
4315 image
= load_image(animatedgif
, sizeof(animatedgif
));
4316 if (!image
) /* XP fails to load this GIF image */
4318 trace("Failed to load GIF image data\n");
4322 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
4324 expect(1, dim_count
);
4326 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
4328 expect_guid(&FrameDimensionTime
, &guid
, __LINE__
, FALSE
);
4330 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
4332 expect(2, frame_count
);
4334 status
= GdipImageSelectActiveFrame(image
, &guid
, 1);
4337 status
= GdipGetPropertyCount(image
, &prop_count
);
4339 ok(prop_count
== sizeof(td
)/sizeof(td
[0]) || broken(prop_count
== 1) /* before win7 */,
4340 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
4342 if (prop_count
!= sizeof(td
)/sizeof(td
[0]))
4344 GdipDisposeImage(image
);
4348 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
4350 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
4354 for (i
= 0; i
< prop_count
; i
++)
4357 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
4359 if (status
!= Ok
) break;
4360 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
4364 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
4365 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
4367 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
4368 ok(td
[i
].type
== prop_item
->type
,
4369 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
4370 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
4371 size
-= sizeof(*prop_item
);
4372 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
4373 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
4374 if (td
[i
].length
== prop_item
->length
)
4376 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
4377 ok(match
, "%u: data mismatch\n", i
);
4381 BYTE
*data
= prop_item
->value
;
4382 trace("id %#x:", prop_item
->id
);
4383 for (j
= 0; j
< prop_item
->length
; j
++)
4384 trace(" %02x", data
[j
]);
4388 HeapFree(GetProcessHeap(), 0, prop_item
);
4391 HeapFree(GetProcessHeap(), 0, prop_id
);
4393 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
4394 expect(InvalidParameter
, status
);
4395 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
4396 expect(InvalidParameter
, status
);
4397 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
4398 expect(InvalidParameter
, status
);
4399 status
= GdipGetPropertySize(image
, NULL
, NULL
);
4400 expect(InvalidParameter
, status
);
4401 total_size
= 0xdeadbeef;
4402 total_count
= 0xdeadbeef;
4403 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
4405 ok(prop_count
== total_count
,
4406 "expected total property count %u, got %u\n", prop_count
, total_count
);
4407 ok(prop_size
== total_size
,
4408 "expected total property size %u, got %u\n", prop_size
, total_size
);
4410 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
4412 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
4413 expect(InvalidParameter
, status
);
4414 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
4415 expect(InvalidParameter
, status
);
4416 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4417 expect(InvalidParameter
, status
);
4418 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4419 expect(InvalidParameter
, status
);
4420 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
4421 expect(InvalidParameter
, status
);
4422 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
4423 expect(InvalidParameter
, status
);
4424 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
4427 item_data
= (const char *)(prop_item
+ prop_count
);
4428 for (i
= 0; i
< prop_count
; i
++)
4430 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
4431 i
, item_data
, prop_item
[i
].value
);
4432 ok(td
[i
].type
== prop_item
[i
].type
,
4433 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
4434 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
4435 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
4436 if (td
[i
].length
== prop_item
[i
].length
)
4438 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
4439 ok(match
, "%u: data mismatch\n", i
);
4443 BYTE
*data
= prop_item
[i
].value
;
4444 trace("id %#x:", prop_item
[i
].id
);
4445 for (j
= 0; j
< prop_item
[i
].length
; j
++)
4446 trace(" %02x", data
[j
]);
4450 item_data
+= prop_item
[i
].length
;
4453 HeapFree(GetProcessHeap(), 0, prop_item
);
4455 GdipDisposeImage(image
);
4458 static void test_ARGB_conversion(void)
4460 BYTE argb
[8] = { 0x11,0x22,0x33,0x80, 0xff,0xff,0xff,0 };
4461 BYTE pargb
[8] = { 0x09,0x11,0x1a,0x80, 0,0,0,0 };
4462 BYTE rgb32_xp
[8] = { 0x11,0x22,0x33,0xff, 0xff,0xff,0xff,0xff };
4463 BYTE rgb24
[6] = { 0x11,0x22,0x33, 0xff,0xff,0xff };
4470 status
= GdipCreateBitmapFromScan0(2, 1, 8, PixelFormat32bppARGB
, argb
, &bitmap
);
4473 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4475 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4476 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4477 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4478 ok(data
.PixelFormat
== PixelFormat32bppPARGB
, "expected PixelFormat32bppPARGB, got %d\n", data
.PixelFormat
);
4479 match
= !memcmp(data
.Scan0
, pargb
, sizeof(pargb
));
4480 ok(match
, "bits don't match\n");
4484 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppPARGB
,
4485 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4487 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4490 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppRGB
, &data
);
4492 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4493 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4494 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4495 ok(data
.PixelFormat
== PixelFormat32bppRGB
, "expected PixelFormat32bppRGB, got %d\n", data
.PixelFormat
);
4496 match
= !memcmp(data
.Scan0
, argb
, sizeof(argb
)) ||
4497 !memcmp(data
.Scan0
, rgb32_xp
, sizeof(rgb32_xp
));
4498 ok(match
, "bits don't match\n");
4502 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppRGB
,
4503 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4505 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4508 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
4510 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4511 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4512 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4513 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "expected PixelFormat24bppRGB, got %d\n", data
.PixelFormat
);
4514 match
= !memcmp(data
.Scan0
, rgb24
, sizeof(rgb24
));
4515 ok(match
, "bits don't match\n");
4519 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat24bppRGB
,
4520 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4522 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4525 GdipDisposeImage((GpImage
*)bitmap
);
4529 static void test_CloneBitmapArea(void)
4532 GpBitmap
*bitmap
, *copy
;
4533 BitmapData data
, data2
;
4535 status
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB
, NULL
, &bitmap
);
4538 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
| ImageLockModeWrite
, PixelFormat24bppRGB
, &data
);
4541 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data2
);
4542 expect(WrongState
, status
);
4544 status
= GdipCloneBitmapAreaI(0, 0, 1, 1, PixelFormat24bppRGB
, bitmap
, ©
);
4547 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4550 GdipDisposeImage((GpImage
*)copy
);
4551 GdipDisposeImage((GpImage
*)bitmap
);
4554 static BOOL
get_encoder_clsid(LPCWSTR mime
, GUID
*format
, CLSID
*clsid
)
4557 UINT n_codecs
, info_size
, i
;
4558 ImageCodecInfo
*info
;
4561 status
= GdipGetImageEncodersSize(&n_codecs
, &info_size
);
4564 info
= GdipAlloc(info_size
);
4566 status
= GdipGetImageEncoders(n_codecs
, info_size
, info
);
4569 for (i
= 0; i
< n_codecs
; i
++)
4571 if (!lstrcmpW(info
[i
].MimeType
, mime
))
4573 *format
= info
[i
].FormatID
;
4574 *clsid
= info
[i
].Clsid
;
4584 static void test_supported_encoders(void)
4586 static const WCHAR bmp_mimetype
[] = {'i', 'm', 'a','g', 'e', '/', 'b', 'm', 'p', 0};
4587 static const WCHAR jpeg_mimetype
[] = {'i','m','a','g','e','/','j','p','e','g', 0};
4588 static const WCHAR gif_mimetype
[] = {'i','m','a','g','e','/','g','i','f', 0};
4589 static const WCHAR tiff_mimetype
[] = {'i','m','a','g','e','/','t','i','f','f', 0};
4590 static const WCHAR png_mimetype
[] = {'i','m','a','g','e','/','p','n','g', 0};
4591 static const struct test_data
4598 { bmp_mimetype
, &ImageFormatBMP
, FALSE
},
4599 { jpeg_mimetype
, &ImageFormatJPEG
, FALSE
},
4600 { gif_mimetype
, &ImageFormatGIF
, TRUE
},
4601 { tiff_mimetype
, &ImageFormatTIFF
, FALSE
},
4602 { png_mimetype
, &ImageFormatPNG
, FALSE
}
4613 status
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB
, NULL
, &bm
);
4614 ok(status
== Ok
, "GdipCreateBitmapFromScan0 error %d\n", status
);
4616 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
4618 ret
= get_encoder_clsid(td
[i
].mime
, &format
, &clsid
);
4619 ok(ret
, "%s encoder is not in the list\n", wine_dbgstr_w(td
[i
].mime
));
4620 expect_guid(td
[i
].format
, &format
, __LINE__
, FALSE
);
4622 hmem
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_NODISCARD
, 16);
4624 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
4625 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
4627 status
= GdipSaveImageToStream((GpImage
*)bm
, stream
, &clsid
, NULL
);
4629 todo_wine
ok(status
== Ok
, "GdipSaveImageToStream error %d\n", status
);
4631 ok(status
== Ok
, "GdipSaveImageToStream error %d\n", status
);
4633 IStream_Release(stream
);
4636 GdipDisposeImage((GpImage
*)bm
);
4641 struct GdiplusStartupInput gdiplusStartupInput
;
4642 ULONG_PTR gdiplusToken
;
4644 gdiplusStartupInput
.GdiplusVersion
= 1;
4645 gdiplusStartupInput
.DebugEventCallback
= NULL
;
4646 gdiplusStartupInput
.SuppressBackgroundThread
= 0;
4647 gdiplusStartupInput
.SuppressExternalCodecs
= 0;
4649 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, NULL
);
4651 test_supported_encoders();
4652 test_CloneBitmapArea();
4653 test_ARGB_conversion();
4654 test_DrawImage_scale();
4655 test_image_format();
4657 test_GdipDrawImagePointRect();
4659 test_tiff_palette();
4660 test_GdipGetAllPropertyItems();
4661 test_tiff_properties();
4662 test_gif_properties();
4663 test_image_properties();
4666 test_GetImageDimension();
4667 test_GdipImageGetFrameDimensionsCount();
4668 test_LoadingImages();
4669 test_SavingImages();
4672 test_LockBits_UserBuf();
4673 test_GdipCreateBitmapFromHBITMAP();
4674 test_GdipGetImageFlags();
4675 test_GdipCloneImage();
4678 test_getrawformat();
4680 test_createfromwmf();
4682 test_createhbitmap();
4683 test_getthumbnail();
4688 test_multiframegif();
4694 GdiplusShutdown(gdiplusToken
);