2 * Unit test suite for images
4 * Copyright (C) 2007 Google (Evan Stade)
5 * Copyright (C) 2012, 2016 Dmitry Timoshkov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 #include "wine/test.h"
33 static GpStatus (WINAPI
*pGdipBitmapGetHistogramSize
)(HistogramFormat
,UINT
*);
34 static GpStatus (WINAPI
*pGdipBitmapGetHistogram
)(GpBitmap
*,HistogramFormat
,UINT
,UINT
*,UINT
*,UINT
*,UINT
*);
35 static GpStatus (WINAPI
*pGdipImageSetAbort
)(GpImage
*,GdiplusAbort
*);
37 #define expect(expected, got) ok((got) == (expected), "Expected %d, got %d\n", (UINT)(expected), (UINT)(got))
38 #define expectf(expected, got) ok(fabs((expected) - (got)) < 0.0001, "Expected %f, got %f\n", (expected), (got))
40 static BOOL
color_match(ARGB c1
, ARGB c2
, BYTE max_diff
)
42 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
44 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
46 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
48 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
52 static void expect_guid(REFGUID expected
, REFGUID got
, int line
, BOOL todo
)
58 StringFromGUID2(got
, bufferW
, ARRAY_SIZE(bufferW
));
59 WideCharToMultiByte(CP_ACP
, 0, bufferW
, ARRAY_SIZE(bufferW
), buffer
, sizeof(buffer
), NULL
, NULL
);
60 StringFromGUID2(expected
, bufferW
, ARRAY_SIZE(bufferW
));
61 WideCharToMultiByte(CP_ACP
, 0, bufferW
, ARRAY_SIZE(bufferW
), buffer2
, sizeof(buffer2
), NULL
, NULL
);
63 ok_(__FILE__
, line
)(IsEqualGUID(expected
, got
), "Expected %s, got %s\n", buffer2
, buffer
);
66 static void expect_rawformat(REFGUID expected
, GpImage
*img
, int line
, BOOL todo
)
71 stat
= GdipGetImageRawFormat(img
, &raw
);
72 ok_(__FILE__
, line
)(stat
== Ok
, "GdipGetImageRawFormat failed with %d\n", stat
);
73 if(stat
!= Ok
) return;
74 expect_guid(expected
, &raw
, line
, todo
);
77 static void test_bufferrawformat(void* buff
, int size
, REFGUID expected
, int line
, BOOL todo
)
86 hglob
= GlobalAlloc (0, size
);
87 data
= GlobalLock (hglob
);
88 memcpy(data
, buff
, size
);
89 GlobalUnlock(hglob
); data
= NULL
;
91 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
92 ok_(__FILE__
, line
)(hres
== S_OK
, "Failed to create a stream\n");
93 if(hres
!= S_OK
) return;
95 stat
= GdipLoadImageFromStream(stream
, &img
);
96 ok_(__FILE__
, line
)(stat
== Ok
, "Failed to create a Bitmap\n");
98 IStream_Release(stream
);
102 expect_rawformat(expected
, img
, line
, todo
);
104 GdipDisposeImage(img
);
105 IStream_Release(stream
);
108 static void test_Scan0(void)
115 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
117 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
119 GdipDisposeImage((GpImage
*)bm
);
121 bm
= (GpBitmap
*)0xdeadbeef;
122 stat
= GdipCreateBitmapFromScan0(10, -10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
123 expect(InvalidParameter
, stat
);
124 ok( !bm
, "expected null bitmap\n" );
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, 0, 10, PixelFormat24bppRGB
, NULL
, &bm
);
133 expect(InvalidParameter
, stat
);
134 ok( !bm
, "expected null bitmap\n" );
137 stat
= GdipCreateBitmapFromScan0(10, 10, 12, PixelFormat24bppRGB
, buff
, &bm
);
139 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
141 GdipDisposeImage((GpImage
*)bm
);
143 bm
= (GpBitmap
*) 0xdeadbeef;
144 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, buff
, &bm
);
145 expect(InvalidParameter
, stat
);
146 ok( !bm
, "expected null bitmap\n" );
148 bm
= (GpBitmap
*)0xdeadbeef;
149 stat
= GdipCreateBitmapFromScan0(10, 10, 0, PixelFormat24bppRGB
, buff
, &bm
);
150 expect(InvalidParameter
, stat
);
151 ok( bm
== (GpBitmap
*)0xdeadbeef, "expected deadbeef bitmap\n" );
154 stat
= GdipCreateBitmapFromScan0(10, 10, -8, PixelFormat24bppRGB
, buff
, &bm
);
156 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
158 GdipDisposeImage((GpImage
*)bm
);
160 bm
= (GpBitmap
*)0xdeadbeef;
161 stat
= GdipCreateBitmapFromScan0(10, 10, -10, PixelFormat24bppRGB
, buff
, &bm
);
162 expect(InvalidParameter
, stat
);
163 ok( !bm
, "expected null bitmap\n" );
166 static void test_FromGdiDib(void)
171 BYTE rbmi
[sizeof(BITMAPINFOHEADER
)+256*sizeof(RGBQUAD
)];
172 BITMAPINFO
*bmi
= (BITMAPINFO
*)rbmi
;
177 memset(rbmi
, 0, sizeof(rbmi
));
179 bmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
180 bmi
->bmiHeader
.biWidth
= 10;
181 bmi
->bmiHeader
.biHeight
= 10;
182 bmi
->bmiHeader
.biPlanes
= 1;
183 bmi
->bmiHeader
.biBitCount
= 32;
184 bmi
->bmiHeader
.biCompression
= BI_RGB
;
186 stat
= GdipCreateBitmapFromGdiDib(NULL
, buff
, &bm
);
187 expect(InvalidParameter
, stat
);
189 stat
= GdipCreateBitmapFromGdiDib(bmi
, NULL
, &bm
);
190 expect(InvalidParameter
, stat
);
192 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, NULL
);
193 expect(InvalidParameter
, stat
);
195 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
197 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
200 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
202 expect(PixelFormat32bppRGB
, format
);
204 GdipDisposeImage((GpImage
*)bm
);
207 bmi
->bmiHeader
.biBitCount
= 24;
208 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
210 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
213 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
215 expect(PixelFormat24bppRGB
, format
);
217 GdipDisposeImage((GpImage
*)bm
);
220 bmi
->bmiHeader
.biBitCount
= 16;
221 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
223 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
226 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
228 expect(PixelFormat16bppRGB555
, format
);
230 GdipDisposeImage((GpImage
*)bm
);
233 bmi
->bmiHeader
.biBitCount
= 8;
234 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
236 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
239 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
241 expect(PixelFormat8bppIndexed
, format
);
243 GdipDisposeImage((GpImage
*)bm
);
246 bmi
->bmiHeader
.biBitCount
= 4;
247 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
249 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
252 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
254 expect(PixelFormat4bppIndexed
, format
);
256 GdipDisposeImage((GpImage
*)bm
);
259 bmi
->bmiHeader
.biBitCount
= 1;
260 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
262 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
265 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
267 expect(PixelFormat1bppIndexed
, format
);
269 GdipDisposeImage((GpImage
*)bm
);
272 bmi
->bmiHeader
.biBitCount
= 0;
273 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
274 expect(InvalidParameter
, stat
);
277 static void test_GetImageDimension(void)
281 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
284 bm
= (GpBitmap
*)0xdeadbeef;
285 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
,NULL
, &bm
);
287 ok((GpBitmap
*)0xdeadbeef != bm
, "Expected bitmap to not be 0xdeadbeef\n");
288 ok(NULL
!= bm
, "Expected bitmap to not be NULL\n");
290 stat
= GdipGetImageDimension(NULL
,&w
,&h
);
291 expect(InvalidParameter
, stat
);
293 stat
= GdipGetImageDimension((GpImage
*)bm
,NULL
,&h
);
294 expect(InvalidParameter
, stat
);
296 stat
= GdipGetImageDimension((GpImage
*)bm
,&w
,NULL
);
297 expect(InvalidParameter
, stat
);
301 stat
= GdipGetImageDimension((GpImage
*)bm
,&w
,&h
);
305 GdipDisposeImage((GpImage
*)bm
);
308 static void test_GdipImageGetFrameDimensionsCount(void)
312 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
314 GUID dimension
= {0};
318 bm
= (GpBitmap
*)0xdeadbeef;
319 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
,NULL
, &bm
);
321 ok((GpBitmap
*)0xdeadbeef != bm
, "Expected bitmap to not be 0xdeadbeef\n");
322 ok(NULL
!= bm
, "Expected bitmap to not be NULL\n");
324 stat
= GdipImageGetFrameDimensionsCount(NULL
,&w
);
325 expect(InvalidParameter
, stat
);
327 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bm
,NULL
);
328 expect(InvalidParameter
, stat
);
331 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bm
,&w
);
335 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 1);
337 expect_guid(&FrameDimensionPage
, &dimension
, __LINE__
, FALSE
);
339 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 2);
340 expect(InvalidParameter
, stat
);
342 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 0);
343 expect(InvalidParameter
, stat
);
345 stat
= GdipImageGetFrameCount(NULL
, &dimension
, &count
);
346 expect(InvalidParameter
, stat
);
348 /* WinXP crashes on this test */
351 stat
= GdipImageGetFrameCount((GpImage
*)bm
, &dimension
, NULL
);
352 expect(InvalidParameter
, stat
);
355 stat
= GdipImageGetFrameCount((GpImage
*)bm
, NULL
, &count
);
359 stat
= GdipImageGetFrameCount((GpImage
*)bm
, &dimension
, &count
);
363 GdipBitmapSetPixel(bm
, 0, 0, 0xffffffff);
365 stat
= GdipImageSelectActiveFrame((GpImage
*)bm
, &dimension
, 0);
368 /* SelectActiveFrame has no effect on image data of memory bitmaps */
370 stat
= GdipBitmapGetPixel(bm
, 0, 0, &color
);
372 expect(0xffffffff, color
);
374 GdipDisposeImage((GpImage
*)bm
);
377 static void test_LoadingImages(void)
382 static const WCHAR nonexistentW
[] = {'n','o','n','e','x','i','s','t','e','n','t',0};
384 stat
= GdipCreateBitmapFromFile(0, 0);
385 expect(InvalidParameter
, stat
);
387 bm
= (GpBitmap
*)0xdeadbeef;
388 stat
= GdipCreateBitmapFromFile(0, &bm
);
389 expect(InvalidParameter
, stat
);
390 ok(bm
== (GpBitmap
*)0xdeadbeef, "returned %p\n", bm
);
392 bm
= (GpBitmap
*)0xdeadbeef;
393 stat
= GdipCreateBitmapFromFile(nonexistentW
, &bm
);
394 todo_wine
expect(InvalidParameter
, stat
);
395 ok(!bm
, "returned %p\n", bm
);
397 stat
= GdipLoadImageFromFile(0, 0);
398 expect(InvalidParameter
, stat
);
400 img
= (GpImage
*)0xdeadbeef;
401 stat
= GdipLoadImageFromFile(0, &img
);
402 expect(InvalidParameter
, stat
);
403 ok(img
== (GpImage
*)0xdeadbeef, "returned %p\n", img
);
405 img
= (GpImage
*)0xdeadbeef;
406 stat
= GdipLoadImageFromFile(nonexistentW
, &img
);
407 todo_wine
expect(OutOfMemory
, stat
);
408 ok(!img
, "returned %p\n", img
);
410 stat
= GdipLoadImageFromFileICM(0, 0);
411 expect(InvalidParameter
, stat
);
413 img
= (GpImage
*)0xdeadbeef;
414 stat
= GdipLoadImageFromFileICM(0, &img
);
415 expect(InvalidParameter
, stat
);
416 ok(img
== (GpImage
*)0xdeadbeef, "returned %p\n", img
);
418 img
= (GpImage
*)0xdeadbeef;
419 stat
= GdipLoadImageFromFileICM(nonexistentW
, &img
);
420 todo_wine
expect(OutOfMemory
, stat
);
421 ok(!img
, "returned %p\n", img
);
424 static void test_SavingImages(void)
430 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
432 ImageCodecInfo
*codecs
;
433 static const CHAR filenameA
[] = "a.bmp";
434 static const WCHAR filename
[] = { 'a','.','b','m','p',0 };
438 stat
= GdipSaveImageToFile(0, 0, 0, 0);
439 expect(InvalidParameter
, stat
);
442 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
448 stat
= GdipSaveImageToFile((GpImage
*)bm
, 0, 0, 0);
449 expect(InvalidParameter
, stat
);
451 stat
= GdipSaveImageToFile((GpImage
*)bm
, filename
, 0, 0);
452 expect(InvalidParameter
, stat
);
454 /* encoder tests should succeed -- already tested */
455 stat
= GdipGetImageEncodersSize(&n
, &s
);
456 if (stat
!= Ok
|| n
== 0) goto cleanup
;
458 codecs
= GdipAlloc(s
);
459 if (!codecs
) goto cleanup
;
461 stat
= GdipGetImageEncoders(n
, s
, codecs
);
462 if (stat
!= Ok
) goto cleanup
;
464 stat
= GdipSaveImageToFile((GpImage
*)bm
, filename
, &codecs
[0].Clsid
, 0);
467 GdipDisposeImage((GpImage
*)bm
);
470 /* re-load and check image stats */
471 stat
= GdipLoadImageFromFile(filename
, (GpImage
**)&bm
);
473 if (stat
!= Ok
) goto cleanup
;
475 stat
= GdipGetImageDimension((GpImage
*)bm
, &w
, &h
);
476 if (stat
!= Ok
) goto cleanup
;
484 GdipDisposeImage((GpImage
*)bm
);
485 ok(DeleteFileA(filenameA
), "Delete failed.\n");
488 static void test_encoders(void)
493 ImageCodecInfo
*codecs
;
497 static const CHAR bmp_format
[] = "BMP";
499 stat
= GdipGetImageEncodersSize(&n
, &s
);
502 codecs
= GdipAlloc(s
);
506 stat
= GdipGetImageEncoders(n
, s
, NULL
);
507 expect(GenericError
, stat
);
509 stat
= GdipGetImageEncoders(0, s
, codecs
);
510 expect(GenericError
, stat
);
512 stat
= GdipGetImageEncoders(n
, s
-1, codecs
);
513 expect(GenericError
, stat
);
515 stat
= GdipGetImageEncoders(n
, s
+1, codecs
);
516 expect(GenericError
, stat
);
518 stat
= GdipGetImageEncoders(n
, s
, codecs
);
522 for (i
= 0; i
< n
; i
++)
526 WideCharToMultiByte(CP_ACP
, 0, codecs
[i
].FormatDescription
, -1,
529 if (CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0,
531 bmp_format
, -1) == CSTR_EQUAL
) {
537 ok(FALSE
, "No BMP codec found.\n");
542 static void test_LockBits(void)
548 const INT WIDTH
= 10, HEIGHT
= 20;
553 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
561 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffc30000);
564 stat
= GdipBitmapSetPixel(bm
, 2, 8, 0xff480000);
568 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
572 expect(0xc3, ((BYTE
*)bd
.Scan0
)[2]);
573 expect(0x48, ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5]);
575 ((char*)bd
.Scan0
)[2] = 0xff;
577 stat
= GdipBitmapUnlockBits(bm
, &bd
);
581 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
583 expect(0xffff0000, color
);
585 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffc30000);
588 /* read-only, with NULL rect -> whole bitmap lock */
589 stat
= GdipBitmapLockBits(bm
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
591 expect(bd
.Width
, WIDTH
);
592 expect(bd
.Height
, HEIGHT
);
595 ((char*)bd
.Scan0
)[2 + 2*3 + 3*bd
.Stride
] = 0xff;
597 stat
= GdipBitmapUnlockBits(bm
, &bd
);
601 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
603 expect(0xffff0000, color
);
605 /* read-only, consecutive */
606 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
610 stat
= GdipBitmapUnlockBits(bm
, &bd
);
614 stat
= GdipDisposeImage((GpImage
*)bm
);
616 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
620 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
622 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
623 expect(WrongState
, stat
);
625 stat
= GdipBitmapUnlockBits(bm
, &bd
);
628 stat
= GdipDisposeImage((GpImage
*)bm
);
630 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
633 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffff0000);
636 stat
= GdipBitmapSetPixel(bm
, 2, 8, 0xffc30000);
639 /* write, no conversion */
640 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
644 /* all bits are readable, inside the rect or not */
645 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
646 expect(0xc3, ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5]);
648 stat
= GdipBitmapUnlockBits(bm
, &bd
);
652 /* read, conversion */
653 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat32bppARGB
, &bd
);
657 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
659 /* Areas outside the rectangle appear to be uninitialized */
660 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
662 ((BYTE
*)bd
.Scan0
)[2] = 0xc3;
664 stat
= GdipBitmapUnlockBits(bm
, &bd
);
668 /* writes do not work in read mode if there was a conversion */
669 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
671 expect(0xffff0000, color
);
673 /* read/write, conversion */
674 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeWrite
, PixelFormat32bppARGB
, &bd
);
678 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
679 ((BYTE
*)bd
.Scan0
)[1] = 0x88;
681 /* Areas outside the rectangle appear to be uninitialized */
682 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
684 stat
= GdipBitmapUnlockBits(bm
, &bd
);
688 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
690 expect(0xffff8800, color
);
692 /* write, conversion */
693 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat32bppARGB
, &bd
);
699 /* This is completely uninitialized. */
700 ok(0xff != ((BYTE
*)bd
.Scan0
)[2], "original image bits are readable\n");
701 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
704 /* Initialize the buffer so the unlock doesn't access undefined memory */
706 memset(((BYTE
*)bd
.Scan0
) + bd
.Stride
* y
, 0, 12);
708 ((BYTE
*)bd
.Scan0
)[0] = 0x12;
709 ((BYTE
*)bd
.Scan0
)[1] = 0x34;
710 ((BYTE
*)bd
.Scan0
)[2] = 0x56;
712 stat
= GdipBitmapUnlockBits(bm
, &bd
);
716 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
718 expect(0xff563412, color
);
720 stat
= GdipBitmapGetPixel(bm
, 2, 8, &color
);
722 expect(0xffc30000, color
);
724 stat
= GdipDisposeImage((GpImage
*)bm
);
726 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
729 /* write, no modification */
730 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
734 stat
= GdipBitmapUnlockBits(bm
, &bd
);
738 /* write, consecutive */
739 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
743 stat
= GdipBitmapUnlockBits(bm
, &bd
);
747 stat
= GdipDisposeImage((GpImage
*)bm
);
749 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
753 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
758 ((char*)bd
.Scan0
)[2] = 0xff;
760 stat
= GdipBitmapUnlockBits(bm
, &bd
);
764 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
766 expect(0xffff0000, color
);
768 stat
= GdipDisposeImage((GpImage
*)bm
);
772 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
774 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
776 stat
= GdipDisposeImage((GpImage
*)bm
);
780 static void test_LockBits_UserBuf(void)
786 const INT WIDTH
= 10, HEIGHT
= 20;
791 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat32bppARGB
, NULL
, &bm
);
794 memset(bits
, 0xaa, sizeof(bits
));
803 bd
.Stride
= WIDTH
* 4;
804 bd
.PixelFormat
= PixelFormat32bppARGB
;
805 bd
.Scan0
= &bits
[2+3*WIDTH
];
806 bd
.Reserved
= 0xaaaaaaaa;
809 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
812 expect(0xaaaaaaaa, bits
[0]);
813 expect(0, bits
[2+3*WIDTH
]);
815 bits
[2+3*WIDTH
] = 0xdeadbeef;
818 stat
= GdipBitmapUnlockBits(bm
, &bd
);
822 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
827 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
830 expect(0xdeadbeef, bits
[2+3*WIDTH
]);
831 bits
[2+3*WIDTH
] = 0x12345678;
834 stat
= GdipBitmapUnlockBits(bm
, &bd
);
838 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
840 expect(0x12345678, color
);
845 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeWrite
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
848 expect(0x12345678, bits
[2+3*WIDTH
]);
849 bits
[2+3*WIDTH
] = 0xdeadbeef;
852 stat
= GdipBitmapUnlockBits(bm
, &bd
);
856 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
858 expect(0xdeadbeef, color
);
860 stat
= GdipDisposeImage((GpImage
*)bm
);
864 struct BITMAPINFOWITHBITFIELDS
866 BITMAPINFOHEADER bmiHeader
;
870 union BITMAPINFOUNION
873 struct BITMAPINFOWITHBITFIELDS bf
;
876 static void test_GdipCreateBitmapFromHBITMAP(void)
878 GpBitmap
* gpbm
= NULL
;
880 HPALETTE hpal
= NULL
;
883 LOGPALETTE
* LogPal
= NULL
;
885 const REAL WIDTH1
= 5;
886 const REAL HEIGHT1
= 15;
887 const REAL WIDTH2
= 10;
888 const REAL HEIGHT2
= 20;
890 union BITMAPINFOUNION bmi
;
894 stat
= GdipCreateBitmapFromHBITMAP(NULL
, NULL
, NULL
);
895 expect(InvalidParameter
, stat
);
897 hbm
= CreateBitmap(WIDTH1
, HEIGHT1
, 1, 1, NULL
);
898 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, NULL
);
899 expect(InvalidParameter
, stat
);
901 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
903 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
904 expectf(WIDTH1
, width
);
905 expectf(HEIGHT1
, height
);
907 GdipDisposeImage((GpImage
*)gpbm
);
910 memset(buff
, 0, sizeof(buff
));
911 hbm
= CreateBitmap(WIDTH2
, HEIGHT2
, 1, 1, &buff
);
912 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
915 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)gpbm
, __LINE__
, FALSE
);
917 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
918 expectf(WIDTH2
, width
);
919 expectf(HEIGHT2
, height
);
921 GdipDisposeImage((GpImage
*)gpbm
);
924 hdc
= CreateCompatibleDC(0);
925 ok(hdc
!= NULL
, "CreateCompatibleDC failed\n");
926 bmi
.bi
.bmiHeader
.biSize
= sizeof(bmi
.bi
.bmiHeader
);
927 bmi
.bi
.bmiHeader
.biHeight
= HEIGHT1
;
928 bmi
.bi
.bmiHeader
.biWidth
= WIDTH1
;
929 bmi
.bi
.bmiHeader
.biBitCount
= 24;
930 bmi
.bi
.bmiHeader
.biPlanes
= 1;
931 bmi
.bi
.bmiHeader
.biCompression
= BI_RGB
;
932 bmi
.bi
.bmiHeader
.biClrUsed
= 0;
934 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
935 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
939 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
941 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
942 expectf(WIDTH1
, width
);
943 expectf(HEIGHT1
, height
);
946 /* test whether writing to the bitmap affects the original */
947 stat
= GdipBitmapSetPixel(gpbm
, 0, 0, 0xffffffff);
952 GdipDisposeImage((GpImage
*)gpbm
);
955 LogPal
= GdipAlloc(sizeof(LOGPALETTE
));
956 ok(LogPal
!= NULL
, "unable to allocate LOGPALETTE\n");
957 LogPal
->palVersion
= 0x300;
958 LogPal
->palNumEntries
= 1;
959 hpal
= CreatePalette(LogPal
);
960 ok(hpal
!= NULL
, "CreatePalette failed\n");
963 stat
= GdipCreateBitmapFromHBITMAP(hbm
, hpal
, &gpbm
);
967 GdipDisposeImage((GpImage
*)gpbm
);
972 /* 16-bit 555 dib, rgb */
973 bmi
.bi
.bmiHeader
.biBitCount
= 16;
974 bmi
.bi
.bmiHeader
.biCompression
= BI_RGB
;
976 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
977 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
981 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
986 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
988 expectf(WIDTH1
, width
);
989 expectf(HEIGHT1
, height
);
991 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
993 expect(PixelFormat16bppRGB555
, format
);
995 GdipDisposeImage((GpImage
*)gpbm
);
999 /* 16-bit 555 dib, with bitfields */
1000 bmi
.bi
.bmiHeader
.biSize
= sizeof(bmi
);
1001 bmi
.bi
.bmiHeader
.biCompression
= BI_BITFIELDS
;
1002 bmi
.bf
.masks
[0] = 0x7c00;
1003 bmi
.bf
.masks
[1] = 0x3e0;
1004 bmi
.bf
.masks
[2] = 0x1f;
1006 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1007 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1011 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1016 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1018 expectf(WIDTH1
, width
);
1019 expectf(HEIGHT1
, height
);
1021 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1023 expect(PixelFormat16bppRGB555
, format
);
1025 GdipDisposeImage((GpImage
*)gpbm
);
1029 /* 16-bit 565 dib, with bitfields */
1030 bmi
.bf
.masks
[0] = 0xf800;
1031 bmi
.bf
.masks
[1] = 0x7e0;
1032 bmi
.bf
.masks
[2] = 0x1f;
1034 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1035 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1039 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1044 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1046 expectf(WIDTH1
, width
);
1047 expectf(HEIGHT1
, height
);
1049 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1051 expect(PixelFormat16bppRGB565
, format
);
1053 GdipDisposeImage((GpImage
*)gpbm
);
1060 static void test_GdipGetImageFlags(void)
1066 img
= (GpImage
*)0xdeadbeef;
1068 stat
= GdipGetImageFlags(NULL
, NULL
);
1069 expect(InvalidParameter
, stat
);
1071 stat
= GdipGetImageFlags(NULL
, &flags
);
1072 expect(InvalidParameter
, stat
);
1074 stat
= GdipGetImageFlags(img
, NULL
);
1075 expect(InvalidParameter
, stat
);
1077 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat1bppIndexed
, NULL
, (GpBitmap
**)&img
);
1079 stat
= GdipGetImageFlags(img
, &flags
);
1081 expect(ImageFlagsHasAlpha
, flags
);
1082 GdipDisposeImage(img
);
1084 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat4bppIndexed
, NULL
, (GpBitmap
**)&img
);
1086 stat
= GdipGetImageFlags(img
, &flags
);
1088 expect(ImageFlagsHasAlpha
, flags
);
1089 GdipDisposeImage(img
);
1091 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat8bppIndexed
, NULL
, (GpBitmap
**)&img
);
1093 stat
= GdipGetImageFlags(img
, &flags
);
1095 expect(ImageFlagsHasAlpha
, flags
);
1096 GdipDisposeImage(img
);
1098 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppGrayScale
, NULL
, (GpBitmap
**)&img
);
1100 stat
= GdipGetImageFlags(img
, &flags
);
1102 expect(ImageFlagsNone
, flags
);
1103 GdipDisposeImage(img
);
1105 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB555
, NULL
, (GpBitmap
**)&img
);
1107 stat
= GdipGetImageFlags(img
, &flags
);
1109 expect(ImageFlagsNone
, flags
);
1110 GdipDisposeImage(img
);
1112 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB565
, NULL
, (GpBitmap
**)&img
);
1114 stat
= GdipGetImageFlags(img
, &flags
);
1116 expect(ImageFlagsNone
, flags
);
1117 GdipDisposeImage(img
);
1119 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppARGB1555
, NULL
, (GpBitmap
**)&img
);
1121 stat
= GdipGetImageFlags(img
, &flags
);
1123 expect(ImageFlagsHasAlpha
, flags
);
1124 GdipDisposeImage(img
);
1126 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, NULL
, (GpBitmap
**)&img
);
1128 stat
= GdipGetImageFlags(img
, &flags
);
1130 expect(ImageFlagsNone
, flags
);
1131 GdipDisposeImage(img
);
1133 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&img
);
1135 stat
= GdipGetImageFlags(img
, &flags
);
1137 expect(ImageFlagsNone
, flags
);
1138 GdipDisposeImage(img
);
1140 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppARGB
, NULL
, (GpBitmap
**)&img
);
1142 stat
= GdipGetImageFlags(img
, &flags
);
1144 expect(ImageFlagsHasAlpha
, flags
);
1145 GdipDisposeImage(img
);
1147 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppPARGB
, NULL
, (GpBitmap
**)&img
);
1149 stat
= GdipGetImageFlags(img
, &flags
);
1151 expect(ImageFlagsHasAlpha
, flags
);
1152 GdipDisposeImage(img
);
1154 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat48bppRGB
, NULL
, (GpBitmap
**)&img
);
1158 stat
= GdipGetImageFlags(img
, &flags
);
1160 expect(ImageFlagsNone
, flags
);
1161 GdipDisposeImage(img
);
1164 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB
, NULL
, (GpBitmap
**)&img
);
1169 stat
= GdipGetImageFlags(img
, &flags
);
1171 expect(ImageFlagsHasAlpha
, flags
);
1172 GdipDisposeImage(img
);
1175 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB
, NULL
, (GpBitmap
**)&img
);
1180 stat
= GdipGetImageFlags(img
, &flags
);
1182 expect(ImageFlagsHasAlpha
, flags
);
1183 GdipDisposeImage(img
);
1187 static void test_GdipCloneImage(void)
1193 GpImage
*image_src
, *image_dest
= NULL
;
1194 const INT WIDTH
= 10, HEIGHT
= 20;
1196 /* Create an image, clone it, delete the original, make sure the copy works */
1197 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
1199 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bm
, __LINE__
, FALSE
);
1201 image_src
= ((GpImage
*)bm
);
1202 stat
= GdipCloneImage(image_src
, &image_dest
);
1204 expect_rawformat(&ImageFormatMemoryBMP
, image_dest
, __LINE__
, FALSE
);
1206 stat
= GdipDisposeImage((GpImage
*)bm
);
1208 stat
= GdipGetImageBounds(image_dest
, &rectF
, &unit
);
1211 /* Treat FP values carefully */
1212 expectf((REAL
)WIDTH
, rectF
.Width
);
1213 expectf((REAL
)HEIGHT
, rectF
.Height
);
1215 stat
= GdipDisposeImage(image_dest
);
1219 static void test_testcontrol(void)
1225 stat
= GdipTestControl(TestControlGetBuildNumber
, ¶m
);
1227 ok(param
!= 0, "Build number expected, got %u\n", param
);
1230 static void test_fromhicon(void)
1232 static const BYTE bmp_bits
[1024];
1233 HBITMAP hbmMask
, hbmColor
;
1237 GpBitmap
*bitmap
= NULL
;
1243 stat
= GdipCreateBitmapFromHICON(NULL
, NULL
);
1244 expect(InvalidParameter
, stat
);
1245 stat
= GdipCreateBitmapFromHICON(NULL
, &bitmap
);
1246 expect(InvalidParameter
, stat
);
1248 /* color icon 1 bit */
1249 hbmMask
= CreateBitmap(16, 16, 1, 1, bmp_bits
);
1250 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1251 hbmColor
= CreateBitmap(16, 16, 1, 1, bmp_bits
);
1252 ok(hbmColor
!= 0, "CreateBitmap failed\n");
1256 info
.hbmMask
= hbmMask
;
1257 info
.hbmColor
= hbmColor
;
1258 hIcon
= CreateIconIndirect(&info
);
1259 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
1260 DeleteObject(hbmMask
);
1261 DeleteObject(hbmColor
);
1263 stat
= GdipCreateBitmapFromHICON(hIcon
, &bitmap
);
1265 broken(stat
== InvalidParameter
), /* Win98 */
1266 "Expected Ok, got %.8x\n", stat
);
1268 /* check attributes */
1269 stat
= GdipGetImageHeight((GpImage
*)bitmap
, &dim
);
1272 stat
= GdipGetImageWidth((GpImage
*)bitmap
, &dim
);
1275 stat
= GdipGetImageType((GpImage
*)bitmap
, &type
);
1277 expect(ImageTypeBitmap
, type
);
1278 stat
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
1280 expect(PixelFormat32bppARGB
, format
);
1282 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bitmap
, __LINE__
, FALSE
);
1283 GdipDisposeImage((GpImage
*)bitmap
);
1287 /* color icon 8 bpp */
1288 hbmMask
= CreateBitmap(16, 16, 1, 8, bmp_bits
);
1289 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1290 hbmColor
= CreateBitmap(16, 16, 1, 8, bmp_bits
);
1291 ok(hbmColor
!= 0, "CreateBitmap failed\n");
1295 info
.hbmMask
= hbmMask
;
1296 info
.hbmColor
= hbmColor
;
1297 hIcon
= CreateIconIndirect(&info
);
1298 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
1299 DeleteObject(hbmMask
);
1300 DeleteObject(hbmColor
);
1302 stat
= GdipCreateBitmapFromHICON(hIcon
, &bitmap
);
1305 /* check attributes */
1306 stat
= GdipGetImageHeight((GpImage
*)bitmap
, &dim
);
1309 stat
= GdipGetImageWidth((GpImage
*)bitmap
, &dim
);
1312 stat
= GdipGetImageType((GpImage
*)bitmap
, &type
);
1314 expect(ImageTypeBitmap
, type
);
1315 stat
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
1317 expect(PixelFormat32bppARGB
, format
);
1319 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bitmap
, __LINE__
, FALSE
);
1320 GdipDisposeImage((GpImage
*)bitmap
);
1326 static const unsigned char pngimage
[285] = {
1327 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
1328 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
1329 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
1330 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
1331 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
1332 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
1333 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
1336 static const unsigned char gifimage
[35] = {
1337 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
1338 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
1341 /* 1x1 pixel transparent gif */
1342 static const unsigned char transparentgif
[] = {
1343 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,
1344 0x00,0x00,0x00,0x21,0xf9,0x04,0x01,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,
1345 0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
1348 static const unsigned char bmpimage
[66] = {
1349 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
1350 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
1351 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
1352 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
1356 static const unsigned char jpgimage
[285] = {
1357 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
1358 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
1359 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
1360 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
1361 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
1362 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
1363 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
1364 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1365 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1366 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
1367 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
1368 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1369 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
1370 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
1371 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1372 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
1373 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
1374 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
1376 /* 1x1 pixel tiff */
1377 static const unsigned char tiffimage
[] = {
1378 0x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00,
1379 0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00,
1380 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1381 0x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01,
1382 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00,
1383 0x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00,
1384 0x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01,
1385 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00,
1386 0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00,
1387 0x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01,
1388 0x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00,
1389 0x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1390 0x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
1391 0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65,
1392 0x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74,
1393 0x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,
1396 /* 320x320 twip wmf */
1397 static const unsigned char wmfimage
[180] = {
1398 0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05,
1399 0x00,0x00,0x00,0x00,0xb1,0x52,0x01,0x00,0x09,0x00,0x00,0x03,0x4f,0x00,0x00,0x00,
1400 0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0b,0x02,0x00,0x00,
1401 0x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x02,0x40,0x01,0x40,0x01,0x04,0x00,0x00,0x00,
1402 0x02,0x01,0x01,0x00,0x04,0x00,0x00,0x00,0x04,0x01,0x0d,0x00,0x08,0x00,0x00,0x00,
1403 0xfa,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
1404 0x2d,0x01,0x00,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,0x01,0x00,0x00,0x00,0x00,0x00,
1405 0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x01,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,
1406 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x02,0x00,
1407 0x07,0x00,0x00,0x00,0x1b,0x04,0x40,0x01,0x40,0x01,0x00,0x00,0x00,0x00,0x04,0x00,
1408 0x00,0x00,0xf0,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0xf0,0x01,0x01,0x00,0x03,0x00,
1411 static void test_getrawformat(void)
1413 test_bufferrawformat((void*)pngimage
, sizeof(pngimage
), &ImageFormatPNG
, __LINE__
, FALSE
);
1414 test_bufferrawformat((void*)gifimage
, sizeof(gifimage
), &ImageFormatGIF
, __LINE__
, FALSE
);
1415 test_bufferrawformat((void*)bmpimage
, sizeof(bmpimage
), &ImageFormatBMP
, __LINE__
, FALSE
);
1416 test_bufferrawformat((void*)jpgimage
, sizeof(jpgimage
), &ImageFormatJPEG
, __LINE__
, FALSE
);
1417 test_bufferrawformat((void*)tiffimage
, sizeof(tiffimage
), &ImageFormatTIFF
, __LINE__
, FALSE
);
1418 test_bufferrawformat((void*)wmfimage
, sizeof(wmfimage
), &ImageFormatWMF
, __LINE__
, FALSE
);
1421 static void test_loadwmf(void)
1432 MetafileHeader header
;
1434 hglob
= GlobalAlloc (0, sizeof(wmfimage
));
1435 data
= GlobalLock (hglob
);
1436 memcpy(data
, wmfimage
, sizeof(wmfimage
));
1437 GlobalUnlock(hglob
); data
= NULL
;
1439 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
1440 ok(hres
== S_OK
, "Failed to create a stream\n");
1441 if(hres
!= S_OK
) return;
1443 stat
= GdipLoadImageFromStream(stream
, &img
);
1444 ok(stat
== Ok
, "Failed to create a Bitmap\n");
1446 IStream_Release(stream
);
1450 IStream_Release(stream
);
1452 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1454 expect(UnitPixel
, unit
);
1455 expectf(0.0, bounds
.X
);
1456 expectf(0.0, bounds
.Y
);
1457 expectf(320.0, bounds
.Width
);
1458 expectf(320.0, bounds
.Height
);
1460 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1462 expectf(1440.0, res
);
1464 stat
= GdipGetImageVerticalResolution(img
, &res
);
1466 expectf(1440.0, res
);
1468 memset(&header
, 0, sizeof(header
));
1469 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1473 expect(MetafileTypeWmfPlaceable
, header
.Type
);
1474 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1475 todo_wine
expect(0x300, header
.Version
);
1476 expect(0, header
.EmfPlusFlags
);
1477 expectf(1440.0, header
.DpiX
);
1478 expectf(1440.0, header
.DpiY
);
1479 expect(0, header
.X
);
1480 expect(0, header
.Y
);
1481 expect(320, header
.Width
);
1482 expect(320, header
.Height
);
1483 expect(1, U(header
).WmfHeader
.mtType
);
1484 expect(0, header
.EmfPlusHeaderSize
);
1485 expect(0, header
.LogicalDpiX
);
1486 expect(0, header
.LogicalDpiY
);
1489 GdipDisposeImage(img
);
1492 static void test_createfromwmf(void)
1500 MetafileHeader header
;
1502 hwmf
= SetMetaFileBitsEx(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
),
1503 wmfimage
+sizeof(WmfPlaceableFileHeader
));
1504 ok(hwmf
!= 0, "SetMetaFileBitsEx failed\n");
1506 stat
= GdipCreateMetafileFromWmf(hwmf
, TRUE
,
1507 (WmfPlaceableFileHeader
*)wmfimage
, (GpMetafile
**)&img
);
1510 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1512 expect(UnitPixel
, unit
);
1513 expectf(0.0, bounds
.X
);
1514 expectf(0.0, bounds
.Y
);
1515 expectf(320.0, bounds
.Width
);
1516 expectf(320.0, bounds
.Height
);
1518 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1520 expectf(1440.0, res
);
1522 stat
= GdipGetImageVerticalResolution(img
, &res
);
1524 expectf(1440.0, res
);
1526 memset(&header
, 0, sizeof(header
));
1527 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1531 expect(MetafileTypeWmfPlaceable
, header
.Type
);
1532 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1533 todo_wine
expect(0x300, header
.Version
);
1534 expect(0, header
.EmfPlusFlags
);
1535 expectf(1440.0, header
.DpiX
);
1536 expectf(1440.0, header
.DpiY
);
1537 expect(0, header
.X
);
1538 expect(0, header
.Y
);
1539 expect(320, header
.Width
);
1540 expect(320, header
.Height
);
1541 expect(1, U(header
).WmfHeader
.mtType
);
1542 expect(0, header
.EmfPlusHeaderSize
);
1543 expect(0, header
.LogicalDpiX
);
1544 expect(0, header
.LogicalDpiY
);
1547 GdipDisposeImage(img
);
1550 static void test_createfromwmf_noplaceable(void)
1556 hwmf
= SetMetaFileBitsEx(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
),
1557 wmfimage
+sizeof(WmfPlaceableFileHeader
));
1558 ok(hwmf
!= 0, "SetMetaFileBitsEx failed\n");
1560 stat
= GdipCreateMetafileFromWmf(hwmf
, TRUE
, NULL
, (GpMetafile
**)&img
);
1563 GdipDisposeImage(img
);
1566 static void test_resolution(void)
1570 GpGraphics
*graphics
;
1573 int screenxres
, screenyres
;
1576 stat
= GdipCreateBitmapFromScan0(1, 1, 32, PixelFormat24bppRGB
, NULL
, &bitmap
);
1579 /* test invalid values */
1580 stat
= GdipGetImageHorizontalResolution(NULL
, &res
);
1581 expect(InvalidParameter
, stat
);
1583 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, NULL
);
1584 expect(InvalidParameter
, stat
);
1586 stat
= GdipGetImageVerticalResolution(NULL
, &res
);
1587 expect(InvalidParameter
, stat
);
1589 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, NULL
);
1590 expect(InvalidParameter
, stat
);
1592 stat
= GdipBitmapSetResolution(NULL
, 96.0, 96.0);
1593 expect(InvalidParameter
, stat
);
1595 stat
= GdipBitmapSetResolution(bitmap
, 0.0, 0.0);
1596 expect(InvalidParameter
, stat
);
1598 /* defaults to screen resolution */
1599 screendc
= GetDC(0);
1601 screenxres
= GetDeviceCaps(screendc
, LOGPIXELSX
);
1602 screenyres
= GetDeviceCaps(screendc
, LOGPIXELSY
);
1604 ReleaseDC(0, screendc
);
1606 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1608 expectf((REAL
)screenxres
, res
);
1610 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1612 expectf((REAL
)screenyres
, res
);
1614 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1616 stat
= GdipGetDpiX(graphics
, &res
);
1618 expectf((REAL
)screenxres
, res
);
1619 stat
= GdipGetDpiY(graphics
, &res
);
1621 expectf((REAL
)screenyres
, res
);
1623 /* test changing the resolution */
1624 stat
= GdipBitmapSetResolution(bitmap
, screenxres
*2.0, screenyres
*3.0);
1627 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1629 expectf(screenxres
*2.0, res
);
1631 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1633 expectf(screenyres
*3.0, res
);
1635 stat
= GdipGetDpiX(graphics
, &res
);
1637 expectf((REAL
)screenxres
, res
);
1638 stat
= GdipGetDpiY(graphics
, &res
);
1640 expectf((REAL
)screenyres
, res
);
1642 stat
= GdipDeleteGraphics(graphics
);
1645 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1647 stat
= GdipGetDpiX(graphics
, &res
);
1649 expectf(screenxres
*2.0, res
);
1650 stat
= GdipGetDpiY(graphics
, &res
);
1652 expectf(screenyres
*3.0, res
);
1653 stat
= GdipDeleteGraphics(graphics
);
1656 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1660 static void test_createhbitmap(void)
1664 HBITMAP hbitmap
, oldhbitmap
;
1670 BitmapData lockeddata
;
1672 memset(bits
, 0x68, 640);
1675 stat
= GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB
, bits
, &bitmap
);
1678 /* test NULL values */
1679 stat
= GdipCreateHBITMAPFromBitmap(NULL
, &hbitmap
, 0);
1680 expect(InvalidParameter
, stat
);
1682 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, NULL
, 0);
1683 expect(InvalidParameter
, stat
);
1685 /* create HBITMAP */
1686 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1691 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1692 expect(sizeof(BITMAP
), ret
);
1694 expect(0, bm
.bmType
);
1695 expect(10, bm
.bmWidth
);
1696 expect(20, bm
.bmHeight
);
1697 expect(40, bm
.bmWidthBytes
);
1698 expect(1, bm
.bmPlanes
);
1699 expect(32, bm
.bmBitsPixel
);
1700 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1704 DWORD val
= *(DWORD
*)bm
.bmBits
;
1705 ok(val
== 0xff686868, "got %x, expected 0xff686868\n", val
);
1708 hdc
= CreateCompatibleDC(NULL
);
1710 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1711 pixel
= GetPixel(hdc
, 5, 5);
1712 SelectObject(hdc
, oldhbitmap
);
1716 expect(0x686868, pixel
);
1718 DeleteObject(hbitmap
);
1721 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1724 /* make (1,0) have no alpha and (2,0) a different blue value. */
1728 /* create alpha Bitmap */
1729 stat
= GdipCreateBitmapFromScan0(8, 20, 32, PixelFormat32bppARGB
, bits
, &bitmap
);
1732 /* create HBITMAP */
1733 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1738 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1739 expect(sizeof(BITMAP
), ret
);
1741 expect(0, bm
.bmType
);
1742 expect(8, bm
.bmWidth
);
1743 expect(20, bm
.bmHeight
);
1744 expect(32, bm
.bmWidthBytes
);
1745 expect(1, bm
.bmPlanes
);
1746 expect(32, bm
.bmBitsPixel
);
1747 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1751 DWORD val
= *(DWORD
*)bm
.bmBits
;
1752 ok(val
== 0x682a2a2a, "got %x, expected 0x682a2a2a\n", val
);
1753 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1754 ok(val
== 0x0, "got %x, expected 0x682a2a2a\n", val
);
1757 hdc
= CreateCompatibleDC(NULL
);
1759 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1760 pixel
= GetPixel(hdc
, 5, 5);
1761 expect(0x2a2a2a, pixel
);
1762 pixel
= GetPixel(hdc
, 1, 0);
1765 SelectObject(hdc
, oldhbitmap
);
1770 DeleteObject(hbitmap
);
1773 /* create HBITMAP with bkgnd colour */
1774 /* gdiplus.dll 5.1 is broken and only applies the blue value */
1775 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0xff00ff);
1780 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1781 expect(sizeof(BITMAP
), ret
);
1783 expect(0, bm
.bmType
);
1784 expect(8, bm
.bmWidth
);
1785 expect(20, bm
.bmHeight
);
1786 expect(32, bm
.bmWidthBytes
);
1787 expect(1, bm
.bmPlanes
);
1788 expect(32, bm
.bmBitsPixel
);
1789 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1793 DWORD val
= *(DWORD
*)bm
.bmBits
;
1794 ok(val
== 0x68c12ac1 || broken(val
== 0x682a2ac1), "got %x, expected 0x68c12ac1\n", val
);
1795 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1796 ok(val
== 0xff00ff || broken(val
== 0xff), "got %x, expected 0xff00ff\n", val
);
1799 hdc
= CreateCompatibleDC(NULL
);
1801 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1802 pixel
= GetPixel(hdc
, 5, 5);
1803 ok(pixel
== 0xc12ac1 || broken(pixel
== 0xc12a2a), "got %x, expected 0xc12ac1\n", pixel
);
1804 pixel
= GetPixel(hdc
, 1, 0);
1805 ok(pixel
== 0xff00ff || broken(pixel
== 0xff0000), "got %x, expected 0xff00ff\n", pixel
);
1806 pixel
= GetPixel(hdc
, 2, 0);
1807 ok(pixel
== 0xb12ac1 || broken(pixel
== 0xb12a2a), "got %x, expected 0xb12ac1\n", pixel
);
1809 SelectObject(hdc
, oldhbitmap
);
1811 DeleteObject(hbitmap
);
1814 /* create HBITMAP with bkgnd colour with alpha and show it behaves with no alpha. */
1815 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0x80ff00ff);
1820 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1821 expect(sizeof(BITMAP
), ret
);
1823 expect(0, bm
.bmType
);
1824 expect(8, bm
.bmWidth
);
1825 expect(20, bm
.bmHeight
);
1826 expect(32, bm
.bmWidthBytes
);
1827 expect(1, bm
.bmPlanes
);
1828 expect(32, bm
.bmBitsPixel
);
1829 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1833 DWORD val
= *(DWORD
*)bm
.bmBits
;
1834 ok(val
== 0x68c12ac1 || broken(val
== 0x682a2ac1), "got %x, expected 0x68c12ac1\n", val
);
1835 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1836 ok(val
== 0xff00ff || broken(val
== 0xff), "got %x, expected 0xff00ff\n", val
);
1839 hdc
= CreateCompatibleDC(NULL
);
1841 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1842 pixel
= GetPixel(hdc
, 5, 5);
1843 ok(pixel
== 0xc12ac1 || broken(pixel
== 0xc12a2a), "got %x, expected 0xc12ac1\n", pixel
);
1844 pixel
= GetPixel(hdc
, 1, 0);
1845 ok(pixel
== 0xff00ff || broken(pixel
== 0xff0000), "got %x, expected 0xff00ff\n", pixel
);
1846 pixel
= GetPixel(hdc
, 2, 0);
1847 ok(pixel
== 0xb12ac1 || broken(pixel
== 0xb12a2a), "got %x, expected 0xb12ac1\n", pixel
);
1849 SelectObject(hdc
, oldhbitmap
);
1851 DeleteObject(hbitmap
);
1854 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1857 /* create HBITMAP from locked data */
1858 memset(bits
, 0x68, 640);
1859 stat
= GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB
, bits
, &bitmap
);
1862 memset(&lockeddata
, 0, sizeof(lockeddata
));
1863 stat
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
| ImageLockModeWrite
,
1864 PixelFormat32bppRGB
, &lockeddata
);
1866 ((DWORD
*)lockeddata
.Scan0
)[0] = 0xff242424;
1867 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1869 stat
= GdipBitmapUnlockBits(bitmap
, &lockeddata
);
1871 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1874 hdc
= CreateCompatibleDC(NULL
);
1875 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1876 pixel
= GetPixel(hdc
, 0, 0);
1877 expect(0x686868, pixel
);
1878 SelectObject(hdc
, oldhbitmap
);
1882 static void test_getthumbnail(void)
1885 GpImage
*bitmap1
, *bitmap2
;
1888 stat
= GdipGetImageThumbnail(NULL
, 0, 0, &bitmap2
, NULL
, NULL
);
1889 expect(InvalidParameter
, stat
);
1891 stat
= GdipCreateBitmapFromScan0(128, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1894 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, NULL
, NULL
, NULL
);
1895 expect(InvalidParameter
, stat
);
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 stat
= GdipCreateBitmapFromScan0(64, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1919 stat
= GdipGetImageThumbnail(bitmap1
, 32, 32, &bitmap2
, NULL
, NULL
);
1924 stat
= GdipGetImageWidth(bitmap2
, &width
);
1928 stat
= GdipGetImageHeight(bitmap2
, &height
);
1932 GdipDisposeImage(bitmap2
);
1935 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, &bitmap2
, NULL
, NULL
);
1940 stat
= GdipGetImageWidth(bitmap2
, &width
);
1944 stat
= GdipGetImageHeight(bitmap2
, &height
);
1946 expect(120, height
);
1948 GdipDisposeImage(bitmap2
);
1951 GdipDisposeImage(bitmap1
);
1954 static void test_getsetpixel(void)
1959 BYTE bits
[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00,
1960 0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00};
1962 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, bits
, &bitmap
);
1965 /* null parameters */
1966 stat
= GdipBitmapGetPixel(NULL
, 1, 1, &color
);
1967 expect(InvalidParameter
, stat
);
1969 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, NULL
);
1970 expect(InvalidParameter
, stat
);
1972 stat
= GdipBitmapSetPixel(NULL
, 1, 1, 0);
1973 expect(InvalidParameter
, stat
);
1976 stat
= GdipBitmapGetPixel(bitmap
, -1, 1, &color
);
1977 expect(InvalidParameter
, stat
);
1979 stat
= GdipBitmapSetPixel(bitmap
, -1, 1, 0);
1980 expect(InvalidParameter
, stat
);
1982 stat
= GdipBitmapGetPixel(bitmap
, 1, -1, &color
);
1983 ok(stat
== InvalidParameter
||
1984 broken(stat
== Ok
), /* Older gdiplus */
1985 "Expected InvalidParameter, got %.8x\n", stat
);
1987 if (0) /* crashes some gdiplus implementations */
1989 stat
= GdipBitmapSetPixel(bitmap
, 1, -1, 0);
1990 ok(stat
== InvalidParameter
||
1991 broken(stat
== Ok
), /* Older gdiplus */
1992 "Expected InvalidParameter, got %.8x\n", stat
);
1995 stat
= GdipBitmapGetPixel(bitmap
, 2, 1, &color
);
1996 expect(InvalidParameter
, stat
);
1998 stat
= GdipBitmapSetPixel(bitmap
, 2, 1, 0);
1999 expect(InvalidParameter
, stat
);
2001 stat
= GdipBitmapGetPixel(bitmap
, 1, 2, &color
);
2002 expect(InvalidParameter
, stat
);
2004 stat
= GdipBitmapSetPixel(bitmap
, 1, 2, 0);
2005 expect(InvalidParameter
, stat
);
2008 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
2010 expect(0xffffffff, color
);
2012 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2014 expect(0xff0000ff, color
);
2016 stat
= GdipBitmapSetPixel(bitmap
, 1, 1, 0xff676869);
2019 stat
= GdipBitmapSetPixel(bitmap
, 0, 0, 0xff474849);
2022 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
2024 expect(0xff676869, color
);
2026 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2028 expect(0xff474849, color
);
2030 stat
= GdipDisposeImage((GpImage
*)bitmap
);
2034 static void check_halftone_palette(ColorPalette
*palette
)
2036 static const BYTE halftone_values
[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
2039 for (i
=0; i
<palette
->Count
; i
++)
2041 ARGB expected
=0xff000000;
2044 if (i
&1) expected
|= 0x800000;
2045 if (i
&2) expected
|= 0x8000;
2046 if (i
&4) expected
|= 0x80;
2050 expected
= 0xffc0c0c0;
2054 if (i
&1) expected
|= 0xff0000;
2055 if (i
&2) expected
|= 0xff00;
2056 if (i
&4) expected
|= 0xff;
2060 expected
= 0x00000000;
2064 expected
|= halftone_values
[(i
-40)%6];
2065 expected
|= halftone_values
[((i
-40)/6)%6] << 8;
2066 expected
|= halftone_values
[((i
-40)/36)%6] << 16;
2068 ok(expected
== palette
->Entries
[i
], "Expected %.8x, got %.8x, i=%u/%u\n",
2069 expected
, palette
->Entries
[i
], i
, palette
->Count
);
2073 static void test_palette(void)
2079 ColorPalette
*palette
=(ColorPalette
*)buffer
;
2080 ARGB
*entries
= palette
->Entries
;
2083 /* test initial palette from non-indexed bitmap */
2084 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, NULL
, &bitmap
);
2087 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2089 expect(sizeof(UINT
)*2+sizeof(ARGB
), size
);
2091 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2093 expect(0, palette
->Count
);
2095 /* test setting palette on not-indexed bitmap */
2098 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2101 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2103 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2105 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2107 expect(3, palette
->Count
);
2109 GdipDisposeImage((GpImage
*)bitmap
);
2111 /* test initial palette on 1-bit bitmap */
2112 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat1bppIndexed
, NULL
, &bitmap
);
2115 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2117 expect(sizeof(UINT
)*2+sizeof(ARGB
)*2, size
);
2119 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2121 expect(PaletteFlagsGrayScale
, palette
->Flags
);
2122 expect(2, palette
->Count
);
2124 expect(0xff000000, entries
[0]);
2125 expect(0xffffffff, entries
[1]);
2127 /* test getting/setting pixels */
2128 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2130 expect(0xff000000, color
);
2132 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffffffff);
2134 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2138 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2140 expect(0xffffffff, color
);
2143 GdipDisposeImage((GpImage
*)bitmap
);
2145 /* test initial palette on 4-bit bitmap */
2146 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat4bppIndexed
, NULL
, &bitmap
);
2149 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2151 expect(sizeof(UINT
)*2+sizeof(ARGB
)*16, size
);
2153 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2155 expect(0, palette
->Flags
);
2156 expect(16, palette
->Count
);
2158 check_halftone_palette(palette
);
2160 /* test getting/setting pixels */
2161 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2163 expect(0xff000000, color
);
2165 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffff00ff);
2167 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2171 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2173 expect(0xffff00ff, color
);
2176 GdipDisposeImage((GpImage
*)bitmap
);
2178 /* test initial palette on 8-bit bitmap */
2179 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat8bppIndexed
, NULL
, &bitmap
);
2182 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2184 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2186 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2188 expect(PaletteFlagsHalftone
, palette
->Flags
);
2189 expect(256, palette
->Count
);
2191 check_halftone_palette(palette
);
2193 /* test getting/setting pixels */
2194 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2196 expect(0xff000000, color
);
2198 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffcccccc);
2200 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2204 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2206 expect(0xffcccccc, color
);
2209 /* test setting/getting a different palette */
2210 entries
[1] = 0xffcccccc;
2212 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2217 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2219 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2221 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2223 expect(PaletteFlagsHalftone
, palette
->Flags
);
2224 expect(256, palette
->Count
);
2225 expect(0xffcccccc, entries
[1]);
2227 /* test count < 256 */
2228 palette
->Flags
= 12345;
2231 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2235 entries
[3] = 0xdeadbeef;
2237 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2239 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2241 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2243 expect(12345, palette
->Flags
);
2244 expect(3, palette
->Count
);
2245 expect(0xffcccccc, entries
[1]);
2246 expect(0xdeadbeef, entries
[3]);
2248 /* test count > 256 */
2249 palette
->Count
= 257;
2251 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2252 ok(stat
== InvalidParameter
||
2253 broken(stat
== Ok
), /* Old gdiplus behavior */
2254 "Expected %.8x, got %.8x\n", InvalidParameter
, stat
);
2256 GdipDisposeImage((GpImage
*)bitmap
);
2259 static void test_colormatrix(void)
2262 ColorMatrix colormatrix
, graymatrix
;
2263 GpImageAttributes
*imageattr
;
2264 const ColorMatrix identity
= {{
2265 {1.0,0.0,0.0,0.0,0.0},
2266 {0.0,1.0,0.0,0.0,0.0},
2267 {0.0,0.0,1.0,0.0,0.0},
2268 {0.0,0.0,0.0,1.0,0.0},
2269 {0.0,0.0,0.0,0.0,1.0}}};
2270 const ColorMatrix double_red
= {{
2271 {2.0,0.0,0.0,0.0,0.0},
2272 {0.0,1.0,0.0,0.0,0.0},
2273 {0.0,0.0,1.0,0.0,0.0},
2274 {0.0,0.0,0.0,1.0,0.0},
2275 {0.0,0.0,0.0,0.0,1.0}}};
2276 const ColorMatrix asymmetric
= {{
2277 {0.0,1.0,0.0,0.0,0.0},
2278 {0.0,0.0,1.0,0.0,0.0},
2279 {0.0,0.0,0.0,1.0,0.0},
2280 {1.0,0.0,0.0,0.0,0.0},
2281 {0.0,0.0,0.0,0.0,1.0}}};
2282 GpBitmap
*bitmap1
, *bitmap2
;
2283 GpGraphics
*graphics
;
2286 colormatrix
= identity
;
2287 graymatrix
= identity
;
2289 stat
= GdipSetImageAttributesColorMatrix(NULL
, ColorAdjustTypeDefault
,
2290 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2291 expect(InvalidParameter
, stat
);
2293 stat
= GdipCreateImageAttributes(&imageattr
);
2296 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2297 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2300 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2301 TRUE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2302 expect(InvalidParameter
, stat
);
2304 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2305 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2308 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2309 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsSkipGrays
);
2312 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2313 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsAltGray
);
2314 expect(InvalidParameter
, stat
);
2316 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2317 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsAltGray
);
2320 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2321 TRUE
, &colormatrix
, &graymatrix
, 3);
2322 expect(InvalidParameter
, stat
);
2324 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeCount
,
2325 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2326 expect(InvalidParameter
, stat
);
2328 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeAny
,
2329 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2330 expect(InvalidParameter
, stat
);
2332 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2333 FALSE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2336 /* Drawing a bitmap transforms the colors */
2337 colormatrix
= double_red
;
2338 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2339 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2342 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
2345 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
2348 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff40ccee);
2351 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2354 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2355 UnitPixel
, imageattr
, NULL
, NULL
);
2358 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2360 expect(0xff80ccee, color
);
2362 colormatrix
= asymmetric
;
2363 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2364 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2367 stat
= GdipBitmapSetPixel(bitmap2
, 0, 0, 0);
2370 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2371 UnitPixel
, imageattr
, NULL
, NULL
);
2374 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2376 ok(color_match(0xeeff40cc, color
, 3), "expected 0xeeff40cc, got 0x%08x\n", color
);
2379 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeDefault
, FALSE
);
2382 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2383 UnitPixel
, imageattr
, NULL
, NULL
);
2386 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2388 ok(color_match(0xfefe40cc, color
, 3), "expected 0xfefe40cc, got 0x%08x\n", color
);
2390 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeDefault
, TRUE
);
2393 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2394 UnitPixel
, imageattr
, NULL
, NULL
);
2397 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2399 ok(color_match(0xff40ccee, color
, 3), "expected 0xff40ccee, got 0x%08x\n", color
);
2401 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2404 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeDefault
, FALSE
);
2407 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2408 UnitPixel
, imageattr
, NULL
, NULL
);
2411 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2413 ok(color_match(0xff40ccee, color
, 3), "expected 0xff40ccee, got 0x%08x\n", color
);
2415 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2416 UnitPixel
, imageattr
, NULL
, NULL
);
2419 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2421 ok(color_match(0xff40ccee, color
, 1), "Expected ff40ccee, got %.8x\n", color
);
2423 /* Disable adjustment, toggle NoOp */
2424 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2425 FALSE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2428 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeDefault
, FALSE
);
2431 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2432 UnitPixel
, imageattr
, NULL
, NULL
);
2435 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2437 ok(color_match(0xff40ccee, color
, 3), "expected 0xff40ccee, got 0x%08x\n", color
);
2439 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeDefault
, TRUE
);
2442 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2443 UnitPixel
, imageattr
, NULL
, NULL
);
2446 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2448 ok(color_match(0xff40ccee, color
, 3), "expected 0xff40ccee, got 0x%08x\n", color
);
2450 /* Reset with NoOp on, enable adjustment. */
2451 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2454 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2455 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2458 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2459 UnitPixel
, imageattr
, NULL
, NULL
);
2462 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2464 ok(color_match(0xfff24ace, color
, 3), "expected 0xfff24ace, got 0x%08x\n", color
);
2466 /* Now inhibit specific category. */
2467 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2470 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeBitmap
,
2471 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2474 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2475 UnitPixel
, imageattr
, NULL
, NULL
);
2478 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2480 ok(color_match(0xfffe41cc, color
, 3), "expected 0xfffe41cc, got 0x%08x\n", color
);
2482 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeBitmap
, TRUE
);
2485 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2486 UnitPixel
, imageattr
, NULL
, NULL
);
2489 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2491 ok(color_match(0xff40ccee, color
, 3), "expected 0xff40ccee, got 0x%08x\n", color
);
2493 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeBitmap
, FALSE
);
2496 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeDefault
, TRUE
);
2499 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2500 UnitPixel
, imageattr
, NULL
, NULL
);
2503 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2505 ok(color_match(0xfff24ace, color
, 3), "expected 0xfff24ace, got 0x%08x\n", color
);
2507 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeBitmap
);
2510 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2511 UnitPixel
, imageattr
, NULL
, NULL
);
2514 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2516 ok(color_match(0xff40ccee, color
, 3), "expected 0xff40ccee, got 0x%08x\n", color
);
2518 GdipDeleteGraphics(graphics
);
2519 GdipDisposeImage((GpImage
*)bitmap1
);
2520 GdipDisposeImage((GpImage
*)bitmap2
);
2521 GdipDisposeImageAttributes(imageattr
);
2524 static void test_gamma(void)
2527 GpImageAttributes
*imageattr
;
2528 GpBitmap
*bitmap1
, *bitmap2
;
2529 GpGraphics
*graphics
;
2532 stat
= GdipSetImageAttributesGamma(NULL
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2533 expect(InvalidParameter
, stat
);
2535 stat
= GdipCreateImageAttributes(&imageattr
);
2538 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2541 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeAny
, TRUE
, 1.0);
2542 expect(InvalidParameter
, stat
);
2544 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, -1.0);
2545 expect(InvalidParameter
, stat
);
2547 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.0);
2548 expect(InvalidParameter
, stat
);
2550 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.5);
2553 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0.0);
2556 /* Drawing a bitmap transforms the colors */
2557 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 3.0);
2560 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
2563 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
2566 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff80ffff);
2569 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2572 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2573 UnitPixel
, imageattr
, NULL
, NULL
);
2576 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2578 ok(color_match(0xff20ffff, color
, 1), "Expected ff20ffff, got %.8x\n", color
);
2580 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2583 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2584 UnitPixel
, imageattr
, NULL
, NULL
);
2587 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2589 ok(color_match(0xff80ffff, color
, 1), "Expected ff80ffff, got %.8x\n", color
);
2591 GdipDeleteGraphics(graphics
);
2592 GdipDisposeImage((GpImage
*)bitmap1
);
2593 GdipDisposeImage((GpImage
*)bitmap2
);
2594 GdipDisposeImageAttributes(imageattr
);
2597 /* 1x1 pixel gif, 2 frames; first frame is white, second is black */
2598 static const unsigned char gifanimation
[72] = {
2599 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
2600 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0xf9,0x04,0x00,0x0a,0x00,0xff,
2601 0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x4c,0x01,0x00,
2602 0x21,0xf9,0x04,0x01,0x0a,0x00,0x01,0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,
2603 0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
2606 /* Generated with ImageMagick:
2607 * convert -transparent black -delay 100 -size 8x2 xc:black \
2608 * -dispose none -page +0+0 -size 2x2 xc:red \
2609 * -dispose background -page +2+0 -size 2x2 xc:blue \
2610 * -dispose previous -page +4+0 -size 2x2 xc:green \
2611 * -dispose undefined -page +6+0 -size 2x2 xc:gray \
2614 static const unsigned char gifanimation2
[] = {
2615 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x08, 0x00,
2616 0x02, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
2617 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x64,
2618 0x00, 0x00, 0x00, 0x21, 0xff, 0x0b, 0x4e, 0x45,
2619 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e,
2620 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00,
2621 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
2622 0x02, 0x04, 0x84, 0x8f, 0x09, 0x05, 0x00, 0x21,
2623 0xf9, 0x04, 0x04, 0x64, 0x00, 0x00, 0x00, 0x2c,
2624 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2625 0x81, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
2626 0x00, 0x00, 0xff, 0x00, 0x00, 0x02, 0x03, 0x44,
2627 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x08, 0x64,
2628 0x00, 0x00, 0x00, 0x2c, 0x02, 0x00, 0x00, 0x00,
2629 0x02, 0x00, 0x02, 0x00, 0x81, 0x00, 0x00, 0xff,
2630 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
2631 0xff, 0x02, 0x03, 0x44, 0x34, 0x05, 0x00, 0x21,
2632 0xf9, 0x04, 0x0c, 0x64, 0x00, 0x00, 0x00, 0x2c,
2633 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2634 0x81, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00,
2635 0x80, 0x00, 0x00, 0x80, 0x00, 0x02, 0x03, 0x44,
2636 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x64,
2637 0x00, 0x00, 0x00, 0x2c, 0x06, 0x00, 0x00, 0x00,
2638 0x02, 0x00, 0x02, 0x00, 0x80, 0x7e, 0x7e, 0x7e,
2639 0x00, 0x00, 0x00, 0x02, 0x02, 0x84, 0x51, 0x00,
2643 static ARGB gifanimation2_pixels
[5][4] = {
2645 {0xffff0000, 0, 0, 0},
2646 {0xffff0000, 0xff0000ff, 0, 0},
2647 {0xffff0000, 0, 0xff008000, 0},
2648 {0xffff0000, 0, 0, 0xff7e7e7e}
2651 static void test_multiframegif(void)
2662 PixelFormat pixel_format
;
2663 INT palette_size
, i
, j
;
2664 char palette_buf
[256];
2665 ColorPalette
*palette
;
2666 ARGB
*palette_entries
;
2668 /* Test frame functions with an animated GIF */
2669 hglob
= GlobalAlloc (0, sizeof(gifanimation
));
2670 data
= GlobalLock (hglob
);
2671 memcpy(data
, gifanimation
, sizeof(gifanimation
));
2672 GlobalUnlock(hglob
);
2674 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2675 ok(hres
== S_OK
, "Failed to create a stream\n");
2676 if(hres
!= S_OK
) return;
2678 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2679 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2681 IStream_Release(stream
);
2685 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2687 expect(PixelFormat32bppARGB
, pixel_format
);
2689 stat
= GdipGetImagePaletteSize((GpImage
*)bmp
, &palette_size
);
2691 ok(palette_size
== sizeof(ColorPalette
) ||
2692 broken(palette_size
== sizeof(ColorPalette
)+sizeof(ARGB
[3])),
2693 "palette_size = %d\n", palette_size
);
2695 /* Bitmap starts at frame 0 */
2697 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2699 expect(0xffffffff, color
);
2701 /* Check that we get correct metadata */
2702 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2706 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2708 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2711 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2715 /* SelectActiveFrame overwrites our current data */
2716 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2720 GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2722 expect(0xff000000, color
);
2724 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2728 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2730 expect(0xffffffff, color
);
2732 /* Write over the image data */
2733 stat
= GdipBitmapSetPixel(bmp
, 0, 0, 0xff000000);
2736 /* Switching to the same frame does not overwrite our changes */
2737 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2740 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2742 expect(0xff000000, color
);
2744 /* But switching to another frame and back does */
2745 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2748 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2751 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2753 expect(0xffffffff, color
);
2755 /* rotate/flip discards the information about other frames */
2756 stat
= GdipImageRotateFlip((GpImage
*)bmp
, Rotate90FlipNone
);
2760 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2764 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bmp
, __LINE__
, FALSE
);
2766 GdipDisposeImage((GpImage
*)bmp
);
2767 IStream_Release(stream
);
2769 /* Test with a non-animated gif */
2770 hglob
= GlobalAlloc (0, sizeof(gifimage
));
2771 data
= GlobalLock (hglob
);
2772 memcpy(data
, gifimage
, sizeof(gifimage
));
2773 GlobalUnlock(hglob
);
2775 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2776 ok(hres
== S_OK
, "Failed to create a stream\n");
2777 if(hres
!= S_OK
) return;
2779 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2780 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2782 IStream_Release(stream
);
2786 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2788 expect(PixelFormat8bppIndexed
, pixel_format
);
2790 /* Check metadata */
2791 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2795 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2797 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2800 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2804 GdipDisposeImage((GpImage
*)bmp
);
2805 IStream_Release(stream
);
2807 /* Test with a non-animated transparent gif */
2808 hglob
= GlobalAlloc (0, sizeof(transparentgif
));
2809 data
= GlobalLock (hglob
);
2810 memcpy(data
, transparentgif
, sizeof(transparentgif
));
2811 GlobalUnlock(hglob
);
2813 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2814 ok(hres
== S_OK
, "Failed to create a stream\n");
2816 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2817 IStream_Release(stream
);
2818 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2820 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2822 expect(PixelFormat8bppIndexed
, pixel_format
);
2824 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2828 stat
= GdipGetImagePaletteSize((GpImage
*)bmp
, &palette_size
);
2830 ok(palette_size
== sizeof(ColorPalette
)+sizeof(ARGB
),
2831 "palette_size = %d\n", palette_size
);
2833 memset(palette_buf
, 0xfe, sizeof(palette_buf
));
2834 palette
= (ColorPalette
*)palette_buf
;
2835 stat
= GdipGetImagePalette((GpImage
*)bmp
, palette
,
2836 sizeof(ColorPalette
)+sizeof(ARGB
));
2837 palette_entries
= palette
->Entries
;
2839 expect(PaletteFlagsHasAlpha
, palette
->Flags
);
2840 expect(2, palette
->Count
);
2841 expect(0, palette_entries
[0]);
2842 expect(0xff000000, palette_entries
[1]);
2845 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2849 GdipDisposeImage((GpImage
*)bmp
);
2851 /* Test frame dispose methods */
2852 hglob
= GlobalAlloc (0, sizeof(gifanimation2
));
2853 data
= GlobalLock (hglob
);
2854 memcpy(data
, gifanimation2
, sizeof(gifanimation2
));
2855 GlobalUnlock(hglob
);
2857 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2858 ok(hres
== S_OK
, "Failed to create a stream\n");
2860 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2861 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2862 IStream_Release(stream
);
2864 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2866 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2868 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2872 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2876 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 3);
2878 stat
= GdipBitmapGetPixel(bmp
, 2, 0, &color
);
2880 ok(color
==0 || broken(color
==0xff0000ff), "color = %x\n", color
);
2882 win_skip("broken animated gif support\n");
2883 GdipDisposeImage((GpImage
*)bmp
);
2887 for(i
=0; i
<6; i
++) {
2888 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, i
%5);
2891 for(j
=0; j
<4; j
++) {
2892 stat
= GdipBitmapGetPixel(bmp
, j
*2, 0, &color
);
2894 ok(gifanimation2_pixels
[i
%5][j
] == color
, "at %d,%d got %x, expected %x\n", i
, j
, color
, gifanimation2_pixels
[i
%5][j
]);
2898 GdipDisposeImage((GpImage
*)bmp
);
2901 static void test_rotateflip(void)
2906 static const BYTE orig_bits
[24] = {
2907 0,0,0xff, 0,0xff,0, 0xff,0,0, 23,23,23,
2908 0xff,0xff,0, 0xff,0,0xff, 0,0xff,0xff, 23,23,23};
2912 memcpy(bits
, orig_bits
, sizeof(bits
));
2913 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2916 stat
= GdipImageRotateFlip(bitmap
, Rotate90FlipNone
);
2919 stat
= GdipGetImageWidth(bitmap
, &width
);
2921 stat
= GdipGetImageHeight(bitmap
, &height
);
2926 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2928 expect(0xff00ffff, color
);
2930 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 0, &color
);
2932 expect(0xffff0000, color
);
2934 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 2, &color
);
2936 expect(0xffffff00, color
);
2938 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 2, &color
);
2940 expect(0xff0000ff, color
);
2944 expect(0xff, bits
[2]);
2946 GdipDisposeImage(bitmap
);
2948 memcpy(bits
, orig_bits
, sizeof(bits
));
2949 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2952 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipX
);
2955 stat
= GdipGetImageWidth(bitmap
, &width
);
2957 stat
= GdipGetImageHeight(bitmap
, &height
);
2962 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2964 expect(0xff0000ff, color
);
2966 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
2968 expect(0xffff0000, color
);
2970 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
2972 expect(0xffffff00, color
);
2974 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
2976 expect(0xff00ffff, color
);
2980 expect(0xff, bits
[2]);
2982 GdipDisposeImage(bitmap
);
2984 memcpy(bits
, orig_bits
, sizeof(bits
));
2985 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2988 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipY
);
2991 stat
= GdipGetImageWidth(bitmap
, &width
);
2993 stat
= GdipGetImageHeight(bitmap
, &height
);
2998 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
3000 expect(0xff00ffff, color
);
3002 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
3004 expect(0xffffff00, color
);
3006 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
3008 expect(0xffff0000, color
);
3010 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
3012 expect(0xff0000ff, color
);
3016 expect(0xff, bits
[2]);
3018 GdipDisposeImage(bitmap
);
3021 static void test_remaptable(void)
3024 GpImageAttributes
*imageattr
;
3025 GpBitmap
*bitmap1
, *bitmap2
;
3026 GpGraphics
*graphics
;
3030 map
= GdipAlloc(sizeof(ColorMap
));
3032 map
->oldColor
.Argb
= 0xff00ff00;
3033 map
->newColor
.Argb
= 0xffff00ff;
3035 stat
= GdipSetImageAttributesRemapTable(NULL
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
3036 expect(InvalidParameter
, stat
);
3038 stat
= GdipCreateImageAttributes(&imageattr
);
3041 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, NULL
);
3042 expect(InvalidParameter
, stat
);
3044 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeCount
, TRUE
, 1, map
);
3045 expect(InvalidParameter
, stat
);
3047 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeAny
, TRUE
, 1, map
);
3048 expect(InvalidParameter
, stat
);
3050 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0, map
);
3051 expect(InvalidParameter
, stat
);
3053 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0, NULL
);
3056 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
3059 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
3062 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
3065 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff00ff00);
3068 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
3071 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
3072 UnitPixel
, imageattr
, NULL
, NULL
);
3075 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
3077 ok(color_match(0xffff00ff, color
, 1), "Expected ffff00ff, got %.8x\n", color
);
3079 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
3082 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
3083 UnitPixel
, imageattr
, NULL
, NULL
);
3086 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
3088 ok(color_match(0xff00ff00, color
, 1), "Expected ff00ff00, got %.8x\n", color
);
3090 GdipDeleteGraphics(graphics
);
3091 GdipDisposeImage((GpImage
*)bitmap1
);
3092 GdipDisposeImage((GpImage
*)bitmap2
);
3093 GdipDisposeImageAttributes(imageattr
);
3097 static void test_colorkey(void)
3100 GpImageAttributes
*imageattr
;
3101 GpBitmap
*bitmap1
, *bitmap2
;
3102 GpGraphics
*graphics
;
3105 stat
= GdipSetImageAttributesColorKeys(NULL
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
3106 expect(InvalidParameter
, stat
);
3108 stat
= GdipCreateImageAttributes(&imageattr
);
3111 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeCount
, TRUE
, 0xff405060, 0xff708090);
3112 expect(InvalidParameter
, stat
);
3114 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeAny
, TRUE
, 0xff405060, 0xff708090);
3115 expect(InvalidParameter
, stat
);
3117 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
3120 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
3123 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
3126 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0x20405060);
3129 stat
= GdipBitmapSetPixel(bitmap1
, 0, 1, 0x40506070);
3132 stat
= GdipBitmapSetPixel(bitmap1
, 1, 0, 0x60708090);
3135 stat
= GdipBitmapSetPixel(bitmap1
, 1, 1, 0xffffffff);
3138 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
3141 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
3142 UnitPixel
, imageattr
, NULL
, NULL
);
3145 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
3147 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
3149 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
3151 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
3153 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
3155 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
3157 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
3159 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
3161 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
3164 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
3165 UnitPixel
, imageattr
, NULL
, NULL
);
3168 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
3170 ok(color_match(0x20405060, color
, 1), "Expected 20405060, got %.8x\n", color
);
3172 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
3174 ok(color_match(0x40506070, color
, 1), "Expected 40506070, got %.8x\n", color
);
3176 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
3178 ok(color_match(0x60708090, color
, 1), "Expected 60708090, got %.8x\n", color
);
3180 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
3182 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
3185 GdipDeleteGraphics(graphics
);
3186 GdipDisposeImage((GpImage
*)bitmap1
);
3187 GdipDisposeImage((GpImage
*)bitmap2
);
3188 GdipDisposeImageAttributes(imageattr
);
3191 static void test_dispose(void)
3195 char invalid_image
[256];
3197 stat
= GdipDisposeImage(NULL
);
3198 expect(InvalidParameter
, stat
);
3200 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, (GpBitmap
**)&image
);
3203 stat
= GdipDisposeImage(image
);
3206 stat
= GdipDisposeImage(image
);
3207 expect(ObjectBusy
, stat
);
3209 memset(invalid_image
, 0, 256);
3210 stat
= GdipDisposeImage((GpImage
*)invalid_image
);
3211 expect(ObjectBusy
, stat
);
3214 static LONG
obj_refcount(void *obj
)
3216 IUnknown_AddRef((IUnknown
*)obj
);
3217 return IUnknown_Release((IUnknown
*)obj
);
3220 static GpImage
*load_image(const BYTE
*image_data
, UINT image_size
, BOOL valid_data
, BOOL todo_load
)
3227 GpImage
*image
= NULL
, *clone
;
3228 ImageType image_type
;
3229 LONG refcount
, old_refcount
;
3231 hmem
= GlobalAlloc(0, image_size
);
3232 data
= GlobalLock(hmem
);
3233 memcpy(data
, image_data
, image_size
);
3236 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
3237 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
3238 if (hr
!= S_OK
) return NULL
;
3240 refcount
= obj_refcount(stream
);
3241 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3243 status
= GdipLoadImageFromStream(stream
, &image
);
3244 todo_wine_if(todo_load
)
3246 ok(status
== Ok
|| broken(status
== InvalidParameter
), /* XP */
3247 "GdipLoadImageFromStream error %d\n", status
);
3249 ok(status
!= Ok
, "GdipLoadImageFromStream should fail\n");
3252 IStream_Release(stream
);
3256 status
= GdipGetImageType(image
, &image_type
);
3257 ok(status
== Ok
, "GdipGetImageType error %d\n", status
);
3259 refcount
= obj_refcount(stream
);
3260 if (image_type
== ImageTypeBitmap
)
3261 ok(refcount
> 1, "expected stream refcount > 1, got %d\n", refcount
);
3263 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3264 old_refcount
= refcount
;
3266 status
= GdipCloneImage(image
, &clone
);
3267 ok(status
== Ok
, "GdipCloneImage error %d\n", status
);
3268 refcount
= obj_refcount(stream
);
3269 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3270 status
= GdipDisposeImage(clone
);
3271 ok(status
== Ok
, "GdipDisposeImage error %d\n", status
);
3272 refcount
= obj_refcount(stream
);
3273 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3275 refcount
= IStream_Release(stream
);
3276 if (image_type
== ImageTypeBitmap
)
3277 ok(refcount
>= 1, "expected stream refcount != 0\n");
3279 ok(refcount
== 0, "expected stream refcount 0, got %d\n", refcount
);
3284 static void test_image_properties(void)
3286 static const struct test_data
3288 const BYTE
*image_data
;
3290 ImageType image_type
;
3292 UINT prop_count2
; /* if win7 behaves differently */
3293 /* 1st property attributes */
3295 UINT prop_size2
; /* if win7 behaves differently */
3297 UINT prop_id2
; /* if win7 behaves differently */
3301 { pngimage
, sizeof(pngimage
), ImageTypeBitmap
, 4, ~0, 1, 20, 0x5110, 0x132 },
3302 { jpgimage
, sizeof(jpgimage
), ImageTypeBitmap
, 2, ~0, 128, 0, 0x5090, 0x5091 },
3303 { tiffimage
, sizeof(tiffimage
), ImageTypeBitmap
, 16, 0, 4, 0, 0xfe, 0 },
3304 { bmpimage
, sizeof(bmpimage
), ImageTypeBitmap
, 0, 0, 0, 0, 0, 0 },
3305 { wmfimage
, sizeof(wmfimage
), ImageTypeMetafile
, 0, 0, 0, 0, 0, 0 }
3309 UINT prop_count
, prop_size
, i
;
3310 PROPID prop_id
[16] = { 0 };
3311 ImageType image_type
;
3318 for (i
= 0; i
< ARRAY_SIZE(td
); i
++)
3320 image
= load_image(td
[i
].image_data
, td
[i
].image_size
, TRUE
, FALSE
);
3323 trace("%u: failed to load image data\n", i
);
3327 status
= GdipGetImageType(image
, &image_type
);
3328 ok(status
== Ok
, "%u: GdipGetImageType error %d\n", i
, status
);
3329 ok(td
[i
].image_type
== image_type
, "%u: expected image_type %d, got %d\n",
3330 i
, td
[i
].image_type
, image_type
);
3332 status
= GdipGetPropertyCount(image
, &prop_count
);
3333 ok(status
== Ok
, "%u: GdipGetPropertyCount error %d\n", i
, status
);
3334 todo_wine_if(td
[i
].image_data
== pngimage
|| td
[i
].image_data
== jpgimage
)
3335 ok(td
[i
].prop_count
== prop_count
|| td
[i
].prop_count2
== prop_count
,
3336 " %u: expected property count %u or %u, got %u\n",
3337 i
, td
[i
].prop_count
, td
[i
].prop_count2
, prop_count
);
3339 status
= GdipGetPropertyItemSize(NULL
, 0, &prop_size
);
3340 expect(InvalidParameter
, status
);
3341 status
= GdipGetPropertyItemSize(image
, 0, NULL
);
3342 expect(InvalidParameter
, status
);
3343 status
= GdipGetPropertyItemSize(image
, 0, &prop_size
);
3344 if (image_type
== ImageTypeMetafile
)
3345 expect(NotImplemented
, status
);
3347 expect(PropertyNotFound
, status
);
3349 status
= GdipGetPropertyItem(NULL
, 0, 0, &item
.data
);
3350 expect(InvalidParameter
, status
);
3351 status
= GdipGetPropertyItem(image
, 0, 0, NULL
);
3352 expect(InvalidParameter
, status
);
3353 status
= GdipGetPropertyItem(image
, 0, 0, &item
.data
);
3354 if (image_type
== ImageTypeMetafile
)
3355 expect(NotImplemented
, status
);
3357 expect(PropertyNotFound
, status
);
3359 /* FIXME: remove once Wine is fixed */
3360 if (td
[i
].prop_count
!= prop_count
)
3362 GdipDisposeImage(image
);
3366 status
= GdipGetPropertyIdList(NULL
, prop_count
, prop_id
);
3367 expect(InvalidParameter
, status
);
3368 status
= GdipGetPropertyIdList(image
, prop_count
, NULL
);
3369 expect(InvalidParameter
, status
);
3370 status
= GdipGetPropertyIdList(image
, 0, prop_id
);
3371 if (image_type
== ImageTypeMetafile
)
3372 expect(NotImplemented
, status
);
3373 else if (prop_count
== 0)
3376 expect(InvalidParameter
, status
);
3377 status
= GdipGetPropertyIdList(image
, prop_count
- 1, prop_id
);
3378 if (image_type
== ImageTypeMetafile
)
3379 expect(NotImplemented
, status
);
3381 expect(InvalidParameter
, status
);
3382 status
= GdipGetPropertyIdList(image
, prop_count
+ 1, prop_id
);
3383 if (image_type
== ImageTypeMetafile
)
3384 expect(NotImplemented
, status
);
3386 expect(InvalidParameter
, status
);
3387 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3388 if (image_type
== ImageTypeMetafile
)
3389 expect(NotImplemented
, status
);
3393 if (prop_count
!= 0)
3394 ok(td
[i
].prop_id
== prop_id
[0] || td
[i
].prop_id2
== prop_id
[0],
3395 " %u: expected property id %#x or %#x, got %#x\n",
3396 i
, td
[i
].prop_id
, td
[i
].prop_id2
, prop_id
[0]);
3401 status
= GdipGetPropertyItemSize(image
, prop_id
[0], &prop_size
);
3402 if (prop_count
== 0)
3403 expect(PropertyNotFound
, status
);
3408 assert(sizeof(item
) >= prop_size
);
3409 ok(prop_size
> sizeof(PropertyItem
), "%u: got too small prop_size %u\n",
3411 ok(td
[i
].prop_size
+ sizeof(PropertyItem
) == prop_size
||
3412 td
[i
].prop_size2
+ sizeof(PropertyItem
) == prop_size
,
3413 " %u: expected property size %u or %u, got %u\n",
3414 i
, td
[i
].prop_size
, td
[i
].prop_size2
, prop_size
);
3416 status
= GdipGetPropertyItem(image
, prop_id
[0], 0, &item
.data
);
3417 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3418 "%u: expected InvalidParameter, got %d\n", i
, status
);
3419 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
- 1, &item
.data
);
3420 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3421 "%u: expected InvalidParameter, got %d\n", i
, status
);
3422 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
+ 1, &item
.data
);
3423 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3424 "%u: expected InvalidParameter, got %d\n", i
, status
);
3425 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
, &item
.data
);
3427 ok(prop_id
[0] == item
.data
.id
,
3428 "%u: expected property id %#x, got %#x\n", i
, prop_id
[0], item
.data
.id
);
3432 GdipDisposeImage(image
);
3440 #define IFD_RATIONAL 5
3442 #define IFD_UNDEFINED 7
3443 #define IFD_SSHORT 8
3445 #define IFD_SRATIONAL 10
3446 #define IFD_FLOAT 11
3447 #define IFD_DOUBLE 12
3449 #ifndef PropertyTagTypeSByte
3450 #define PropertyTagTypeSByte 6
3451 #define PropertyTagTypeSShort 8
3452 #define PropertyTagTypeFloat 11
3453 #define PropertyTagTypeDouble 12
3456 static UINT
documented_type(UINT type
)
3460 case PropertyTagTypeSByte
: return PropertyTagTypeByte
;
3461 case PropertyTagTypeSShort
: return PropertyTagTypeShort
;
3462 case PropertyTagTypeFloat
: return PropertyTagTypeUndefined
;
3463 case PropertyTagTypeDouble
: return PropertyTagTypeUndefined
;
3464 default: return type
;
3468 #include "pshpack2.h"
3483 static const struct tiff_data
3488 USHORT number_of_entries
;
3489 struct IFD_entry entry
[40];
3491 struct IFD_rational xres
;
3493 struct IFD_rational srational_val
;
3498 struct IFD_rational rational
[3];
3502 #ifdef WORDS_BIGENDIAN
3508 FIELD_OFFSET(struct tiff_data
, number_of_entries
),
3511 { 0xff, IFD_SHORT
, 1, 0 }, /* SUBFILETYPE */
3512 { 0x100, IFD_LONG
, 1, 1 }, /* IMAGEWIDTH */
3513 { 0x101, IFD_LONG
, 1, 1 }, /* IMAGELENGTH */
3514 { 0x102, IFD_SHORT
, 1, 1 }, /* BITSPERSAMPLE */
3515 { 0x103, IFD_SHORT
, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
3516 { 0x106, IFD_SHORT
, 1, 1 }, /* PHOTOMETRIC */
3517 { 0x111, IFD_LONG
, 1, FIELD_OFFSET(struct tiff_data
, pixel_data
) }, /* STRIPOFFSETS */
3518 { 0x115, IFD_SHORT
, 1, 1 }, /* SAMPLESPERPIXEL */
3519 { 0x116, IFD_LONG
, 1, 1 }, /* ROWSPERSTRIP */
3520 { 0x117, IFD_LONG
, 1, 1 }, /* STRIPBYTECOUNT */
3521 { 0x11a, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3522 { 0x11b, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3523 { 0x128, IFD_SHORT
, 1, 2 }, /* RESOLUTIONUNIT */
3524 { 0xf001, IFD_BYTE
, 1, 0x11223344 },
3525 { 0xf002, IFD_BYTE
, 4, 0x11223344 },
3526 { 0xf003, IFD_SBYTE
, 1, 0x11223344 },
3527 { 0xf004, IFD_SSHORT
, 1, 0x11223344 },
3528 { 0xf005, IFD_SSHORT
, 2, 0x11223344 },
3529 { 0xf006, IFD_SLONG
, 1, 0x11223344 },
3530 { 0xf007, IFD_FLOAT
, 1, 0x11223344 },
3531 { 0xf008, IFD_DOUBLE
, 1, FIELD_OFFSET(struct tiff_data
, double_val
) },
3532 { 0xf009, IFD_SRATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, srational_val
) },
3533 { 0xf00a, IFD_BYTE
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3534 { 0xf00b, IFD_SSHORT
, 4, FIELD_OFFSET(struct tiff_data
, short_val
) },
3535 { 0xf00c, IFD_SLONG
, 2, FIELD_OFFSET(struct tiff_data
, long_val
) },
3536 { 0xf00e, IFD_ASCII
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3537 { 0xf00f, IFD_ASCII
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3538 { 0xf010, IFD_UNDEFINED
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3539 { 0xf011, IFD_UNDEFINED
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3540 /* Some gdiplus versions ignore these fields.
3541 { 0xf012, IFD_BYTE, 0, 0x11223344 },
3542 { 0xf013, IFD_SHORT, 0, 0x11223344 },
3543 { 0xf014, IFD_LONG, 0, 0x11223344 },
3544 { 0xf015, IFD_FLOAT, 0, 0x11223344 },*/
3545 { 0xf016, IFD_SRATIONAL
, 3, FIELD_OFFSET(struct tiff_data
, rational
) },
3546 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3547 { 0xf017, IFD_FLOAT
, 2, FIELD_OFFSET(struct tiff_data
, float_val
) },
3551 1234567890.0987654321,
3552 { 0x1a2b3c4d, 0x5a6b7c8d },
3554 { 0x0101, 0x0202, 0x0303, 0x0404 },
3555 { 0x11223344, 0x55667788 },
3556 { (FLOAT
)1234.5678, (FLOAT
)8765.4321 },
3557 { { 0x01020304, 0x05060708 }, { 0x10203040, 0x50607080 }, { 0x11223344, 0x55667788 } },
3558 { 0x11, 0x22, 0x33, 0 }
3560 #include "poppack.h"
3562 static void test_tiff_properties(void)
3564 static const struct test_data
3566 ULONG type
, id
, length
;
3567 const BYTE value
[24];
3570 { PropertyTagTypeShort
, 0xff, 2, { 0 } },
3571 { PropertyTagTypeLong
, 0x100, 4, { 1 } },
3572 { PropertyTagTypeLong
, 0x101, 4, { 1 } },
3573 { PropertyTagTypeShort
, 0x102, 2, { 1 } },
3574 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3575 { PropertyTagTypeShort
, 0x106, 2, { 1 } },
3576 { PropertyTagTypeLong
, 0x111, 4, { 0x44,0x02 } },
3577 { PropertyTagTypeShort
, 0x115, 2, { 1 } },
3578 { PropertyTagTypeLong
, 0x116, 4, { 1 } },
3579 { PropertyTagTypeLong
, 0x117, 4, { 1 } },
3580 { PropertyTagTypeRational
, 0x11a, 8, { 0x84,0x03,0,0,0x03 } },
3581 { PropertyTagTypeRational
, 0x11b, 8, { 0x84,0x03,0,0,0x03 } },
3582 { PropertyTagTypeShort
, 0x128, 2, { 2 } },
3583 { PropertyTagTypeByte
, 0xf001, 1, { 0x44 } },
3584 { PropertyTagTypeByte
, 0xf002, 4, { 0x44,0x33,0x22,0x11 } },
3585 { PropertyTagTypeSByte
, 0xf003, 1, { 0x44 } },
3586 { PropertyTagTypeSShort
, 0xf004, 2, { 0x44,0x33 } },
3587 { PropertyTagTypeSShort
, 0xf005, 4, { 0x44,0x33,0x22,0x11 } },
3588 { PropertyTagTypeSLONG
, 0xf006, 4, { 0x44,0x33,0x22,0x11 } },
3589 { PropertyTagTypeFloat
, 0xf007, 4, { 0x44,0x33,0x22,0x11 } },
3590 { PropertyTagTypeDouble
, 0xf008, 8, { 0x2c,0x52,0x86,0xb4,0x80,0x65,0xd2,0x41 } },
3591 { PropertyTagTypeSRational
, 0xf009, 8, { 0x4d, 0x3c, 0x2b, 0x1a, 0x8d, 0x7c, 0x6b, 0x5a } },
3592 { PropertyTagTypeByte
, 0xf00a, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3593 { PropertyTagTypeSShort
, 0xf00b, 8, { 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04 } },
3594 { PropertyTagTypeSLONG
, 0xf00c, 8, { 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3595 { PropertyTagTypeASCII
, 0xf00e, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3596 { PropertyTagTypeASCII
, 0xf00f, 5, { 'a','b','c','d' } },
3597 { PropertyTagTypeUndefined
, 0xf010, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3598 { PropertyTagTypeUndefined
, 0xf011, 4, { 'a','b','c','d' } },
3599 { PropertyTagTypeSRational
, 0xf016, 24,
3600 { 0x04,0x03,0x02,0x01,0x08,0x07,0x06,0x05,
3601 0x40,0x30,0x20,0x10,0x80,0x70,0x60,0x50,
3602 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3603 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3604 { PropertyTagTypeFloat
, 0xf017, 8, { 0x2b,0x52,0x9a,0x44,0xba,0xf5,0x08,0x46 } },
3609 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3611 PropertyItem
*prop_item
;
3613 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
), TRUE
, FALSE
);
3616 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3620 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3622 expect(1, dim_count
);
3624 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3626 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3628 frame_count
= 0xdeadbeef;
3629 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3631 expect(1, frame_count
);
3633 prop_count
= 0xdeadbeef;
3634 status
= GdipGetPropertyCount(image
, &prop_count
);
3636 ok(prop_count
== ARRAY_SIZE(td
) ||
3637 broken(prop_count
== ARRAY_SIZE(td
) - 1) /* Win7 SP0 */,
3638 "expected property count %u, got %u\n", (UINT
) ARRAY_SIZE(td
), prop_count
);
3640 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3642 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3645 for (i
= 0; i
< prop_count
; i
++)
3647 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &prop_size
);
3649 if (status
!= Ok
) break;
3650 ok(prop_size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, prop_size
);
3652 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, prop_size
);
3653 status
= GdipGetPropertyItem(image
, prop_id
[i
], prop_size
, prop_item
);
3655 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3656 ok(td
[i
].type
== prop_item
->type
||
3657 /* Win7 stopped using proper but not documented types, and it
3658 looks broken since TypeFloat and TypeDouble now reported as
3659 TypeUndefined, and signed types reported as unsigned. */
3660 broken(prop_item
->type
== documented_type(td
[i
].type
)),
3661 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3662 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3663 prop_size
-= sizeof(*prop_item
);
3664 ok(prop_item
->length
== prop_size
, "%u: expected length %u, got %u\n", i
, prop_size
, prop_item
->length
);
3665 ok(td
[i
].length
== prop_item
->length
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_item
->length
+1) /* XP */,
3666 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3667 ok(td
[i
].length
== prop_size
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_size
+1) /* XP */,
3668 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_size
);
3669 if (td
[i
].length
== prop_item
->length
)
3671 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3672 ok(match
|| broken(td
[i
].length
<= 4 && !match
), "%u: data mismatch\n", i
);
3676 BYTE
*data
= prop_item
->value
;
3677 trace("id %#x:", prop_item
->id
);
3678 for (j
= 0; j
< prop_item
->length
; j
++)
3679 trace(" %02x", data
[j
]);
3683 HeapFree(GetProcessHeap(), 0, prop_item
);
3686 HeapFree(GetProcessHeap(), 0, prop_id
);
3688 GdipDisposeImage(image
);
3691 static void test_GdipGetAllPropertyItems(void)
3693 static const struct test_data
3695 ULONG type
, id
, length
;
3699 { PropertyTagTypeLong
, 0xfe, 4, { 0 } },
3700 { PropertyTagTypeShort
, 0x100, 2, { 1 } },
3701 { PropertyTagTypeShort
, 0x101, 2, { 1 } },
3702 { PropertyTagTypeShort
, 0x102, 6, { 8,0,8,0,8,0 } },
3703 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3704 { PropertyTagTypeShort
, 0x106, 2, { 2,0 } },
3705 { PropertyTagTypeASCII
, 0x10d, 27, "/home/meh/Desktop/test.tif" },
3706 { PropertyTagTypeLong
, 0x111, 4, { 8,0,0,0 } },
3707 { PropertyTagTypeShort
, 0x112, 2, { 1 } },
3708 { PropertyTagTypeShort
, 0x115, 2, { 3,0 } },
3709 { PropertyTagTypeShort
, 0x116, 2, { 0x40,0 } },
3710 { PropertyTagTypeLong
, 0x117, 4, { 3,0,0,0 } },
3711 { PropertyTagTypeRational
, 0x11a, 8, { 0,0,0,72,0,0,0,1 } },
3712 { PropertyTagTypeRational
, 0x11b, 8, { 0,0,0,72,0,0,0,1 } },
3713 { PropertyTagTypeShort
, 0x11c, 2, { 1 } },
3714 { PropertyTagTypeShort
, 0x128, 2, { 2 } }
3719 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3720 UINT total_size
, total_count
;
3722 PropertyItem
*prop_item
;
3723 const char *item_data
;
3725 image
= load_image(tiffimage
, sizeof(tiffimage
), TRUE
, FALSE
);
3726 ok(image
!= 0, "Failed to load TIFF image data\n");
3729 dim_count
= 0xdeadbeef;
3730 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3732 expect(1, dim_count
);
3734 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3736 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3738 frame_count
= 0xdeadbeef;
3739 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3741 expect(1, frame_count
);
3743 prop_count
= 0xdeadbeef;
3744 status
= GdipGetPropertyCount(image
, &prop_count
);
3746 ok(prop_count
== ARRAY_SIZE(td
),
3747 "expected property count %u, got %u\n", (UINT
) ARRAY_SIZE(td
), prop_count
);
3749 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3751 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3755 for (i
= 0; i
< prop_count
; i
++)
3758 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
3760 if (status
!= Ok
) break;
3761 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
3765 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
3766 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
3768 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3769 ok(td
[i
].type
== prop_item
->type
,
3770 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3771 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3772 size
-= sizeof(*prop_item
);
3773 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
3774 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3775 if (td
[i
].length
== prop_item
->length
)
3777 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3778 ok(match
, "%u: data mismatch\n", i
);
3782 BYTE
*data
= prop_item
->value
;
3783 trace("id %#x:", prop_item
->id
);
3784 for (j
= 0; j
< prop_item
->length
; j
++)
3785 trace(" %02x", data
[j
]);
3789 HeapFree(GetProcessHeap(), 0, prop_item
);
3792 HeapFree(GetProcessHeap(), 0, prop_id
);
3794 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
3795 expect(InvalidParameter
, status
);
3796 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
3797 expect(InvalidParameter
, status
);
3798 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
3799 expect(InvalidParameter
, status
);
3800 status
= GdipGetPropertySize(image
, NULL
, NULL
);
3801 expect(InvalidParameter
, status
);
3802 total_size
= 0xdeadbeef;
3803 total_count
= 0xdeadbeef;
3804 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
3806 ok(prop_count
== total_count
,
3807 "expected total property count %u, got %u\n", prop_count
, total_count
);
3808 ok(prop_size
== total_size
,
3809 "expected total property size %u, got %u\n", prop_size
, total_size
);
3811 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
3813 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
3814 expect(InvalidParameter
, status
);
3815 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
3816 expect(InvalidParameter
, status
);
3817 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3818 expect(InvalidParameter
, status
);
3819 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3820 expect(InvalidParameter
, status
);
3821 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
3822 expect(InvalidParameter
, status
);
3823 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
3824 expect(InvalidParameter
, status
);
3825 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
3828 item_data
= (const char *)(prop_item
+ prop_count
);
3829 for (i
= 0; i
< prop_count
; i
++)
3831 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
3832 i
, item_data
, prop_item
[i
].value
);
3833 ok(td
[i
].type
== prop_item
[i
].type
,
3834 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
3835 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
3836 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
3837 if (td
[i
].length
== prop_item
[i
].length
)
3839 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
3840 ok(match
, "%u: data mismatch\n", i
);
3844 BYTE
*data
= prop_item
[i
].value
;
3845 trace("id %#x:", prop_item
[i
].id
);
3846 for (j
= 0; j
< prop_item
[i
].length
; j
++)
3847 trace(" %02x", data
[j
]);
3851 item_data
+= prop_item
[i
].length
;
3854 HeapFree(GetProcessHeap(), 0, prop_item
);
3856 GdipDisposeImage(image
);
3859 static void test_tiff_palette(void)
3870 ARGB
*entries
= palette
.pal
.Entries
;
3872 /* 1bpp TIFF without palette */
3873 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
), TRUE
, FALSE
);
3876 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3880 status
= GdipGetImagePixelFormat(image
, &format
);
3882 ok(format
== PixelFormat1bppIndexed
, "expected PixelFormat1bppIndexed, got %#x\n", format
);
3884 status
= GdipGetImagePaletteSize(image
, &size
);
3885 ok(status
== Ok
|| broken(status
== GenericError
), /* XP */
3886 "GdipGetImagePaletteSize error %d\n", status
);
3887 if (status
== GenericError
)
3889 GdipDisposeImage(image
);
3892 expect(sizeof(ColorPalette
) + sizeof(ARGB
), size
);
3894 status
= GdipGetImagePalette(image
, &palette
.pal
, size
);
3896 expect(0, palette
.pal
.Flags
);
3897 expect(2, palette
.pal
.Count
);
3898 if (palette
.pal
.Count
== 2)
3900 ok(entries
[0] == 0xff000000, "expected 0xff000000, got %#x\n", entries
[0]);
3901 ok(entries
[1] == 0xffffffff, "expected 0xffffffff, got %#x\n", entries
[1]);
3904 GdipDisposeImage(image
);
3907 static void test_bitmapbits(void)
3910 static const BYTE pixels_24
[48] =
3912 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3913 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3914 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3915 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0
3917 static const BYTE pixels_00
[48] =
3919 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3920 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3921 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3922 0,0,0, 0,0,0, 0,0,0, 0,0,0
3924 static const BYTE pixels_24_77
[64] =
3926 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3927 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3928 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3929 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3930 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3931 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3933 static const BYTE pixels_77
[64] =
3935 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3936 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3937 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3938 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3939 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3940 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3941 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3942 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3944 static const BYTE pixels_8
[16] =
3946 0x01,0,0x01,0,0x01,0,0x01,0,
3947 0x01,0,0x01,0,0x01,0,0x01,0
3949 static const BYTE pixels_8_77
[64] =
3951 0x01,0,0x01,0,0x01,0,0x01,0,
3952 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3953 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3954 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3955 0x01,0,0x01,0,0x01,0,0x01,0,
3956 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3957 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3958 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3960 static const BYTE pixels_1_77
[64] =
3962 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3963 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3964 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3965 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3966 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3967 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3968 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3969 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3971 static const BYTE pixels_1
[8] = {0xaa,0,0,0,0xaa,0,0,0};
3972 static const struct test_data
3979 const BYTE
*pixels_unlocked
;
3983 { PixelFormat24bppRGB
, 24, 0xfff0, 24, 48, pixels_24
, pixels_00
},
3985 { PixelFormat24bppRGB
, 24, 0, 24, 48, pixels_24
, pixels_00
},
3986 { PixelFormat24bppRGB
, 24, ImageLockModeRead
, 24, 48, pixels_24
, pixels_00
},
3987 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
3988 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
3989 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_24_77
, pixels_24
},
3990 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3991 { PixelFormat24bppRGB
, 24, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3993 { PixelFormat8bppIndexed
, 8, 0, 8, 16, pixels_8
, pixels_24
},
3994 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
, 8, 16, pixels_8
, pixels_24
},
3995 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
3996 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
3997 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_8_77
, pixels_24
},
3998 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3999 { PixelFormat8bppIndexed
, 8, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
4001 { PixelFormat1bppIndexed
, 1, 0, 4, 8, pixels_1
, pixels_24
},
4002 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
, 4, 8, pixels_1
, pixels_24
},
4003 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
4004 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
4005 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_1_77
, pixels_24
},
4006 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
4007 { PixelFormat1bppIndexed
, 1, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
4019 ARGB
*entries
= palette
.pal
.Entries
;
4021 for (i
= 0; i
< ARRAY_SIZE(td
); i
++)
4023 BYTE pixels
[sizeof(pixels_24
)];
4024 memcpy(pixels
, pixels_24
, sizeof(pixels_24
));
4025 status
= GdipCreateBitmapFromScan0(8, 2, 24, PixelFormat24bppRGB
, pixels
, &bitmap
);
4028 /* associate known palette with pixel data */
4029 palette
.pal
.Flags
= PaletteFlagsGrayScale
;
4030 palette
.pal
.Count
= 2;
4031 entries
[0] = 0xff000000;
4032 entries
[1] = 0xffffffff;
4033 status
= GdipSetImagePalette((GpImage
*)bitmap
, &palette
.pal
);
4036 memset(&data
, 0xfe, sizeof(data
));
4037 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
4039 memset(buf
, 0x77, sizeof(buf
));
4043 status
= GdipBitmapLockBits(bitmap
, NULL
, td
[i
].mode
, td
[i
].format
, &data
);
4044 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* XP */, "%u: GdipBitmapLockBits error %d\n", i
, status
);
4047 GdipDisposeImage((GpImage
*)bitmap
);
4050 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
4051 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
4052 ok(td
[i
].stride
== data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].stride
, data
.Stride
);
4053 ok(td
[i
].format
== data
.PixelFormat
, "%u: expected %d, got %d\n", i
, td
[i
].format
, data
.PixelFormat
);
4054 ok(td
[i
].size
== data
.Height
* data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].size
, data
.Height
* data
.Stride
);
4055 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
4056 ok(data
.Scan0
== buf
, "%u: got wrong buffer\n", i
);
4057 if (td
[i
].size
== data
.Height
* data
.Stride
)
4059 UINT j
, match
, width_bytes
= (data
.Width
* td
[i
].bpp
) / 8;
4062 for (j
= 0; j
< data
.Height
; j
++)
4064 if (memcmp((const BYTE
*)data
.Scan0
+ j
* data
.Stride
, td
[i
].pixels
+ j
* data
.Stride
, width_bytes
) != 0)
4070 if ((td
[i
].mode
& (ImageLockModeRead
|ImageLockModeUserInputBuf
)) || td
[i
].format
== PixelFormat24bppRGB
)
4073 "%u: data should match\n", i
);
4076 BYTE
*bits
= data
.Scan0
;
4077 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
4078 for (j
= 0; j
< td
[i
].size
; j
++)
4079 trace(" %02x", bits
[j
]);
4084 ok(!match
, "%u: data shouldn't match\n", i
);
4086 memset(data
.Scan0
, 0, td
[i
].size
);
4089 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4090 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
4092 memset(&data
, 0xfe, sizeof(data
));
4093 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
4094 ok(status
== Ok
, "%u: GdipBitmapLockBits error %d\n", i
, status
);
4095 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
4096 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
4097 ok(data
.Stride
== 24, "%u: expected 24, got %d\n", i
, data
.Stride
);
4098 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "%u: got wrong pixel format %d\n", i
, data
.PixelFormat
);
4099 ok(data
.Height
* data
.Stride
== 48, "%u: expected 48, got %d\n", i
, data
.Height
* data
.Stride
);
4100 if (data
.Height
* data
.Stride
== 48)
4102 int match
= memcmp(data
.Scan0
, td
[i
].pixels_unlocked
, 48) == 0;
4103 ok(match
, "%u: data should match\n", i
);
4107 BYTE
*bits
= data
.Scan0
;
4108 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
4109 for (j
= 0; j
< 48; j
++)
4110 trace(" %02x", bits
[j
]);
4115 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4116 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
4118 status
= GdipDisposeImage((GpImage
*)bitmap
);
4123 static void test_DrawImage(void)
4125 BYTE black_1x1
[4] = { 0,0,0,0 };
4126 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
4127 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
4128 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
4129 0,0,0,0,0,0,0xff,0xff };
4136 GpGraphics
*graphics
;
4139 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
4141 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4144 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
4146 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
4148 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4150 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4153 status
= GdipDrawImageI(graphics
, u1
.image
, 0, 0);
4156 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
4157 ok(match
, "data should match\n");
4160 UINT i
, size
= sizeof(white_2x2
);
4161 BYTE
*bits
= white_2x2
;
4162 for (i
= 0; i
< size
; i
++)
4163 trace(" %02x", bits
[i
]);
4167 status
= GdipDeleteGraphics(graphics
);
4169 status
= GdipDisposeImage(u1
.image
);
4171 status
= GdipDisposeImage(u2
.image
);
4175 static void test_DrawImage_SourceCopy(void)
4177 DWORD dst_pixels
[4] = { 0xffffffff, 0xffffffff,
4178 0xffffffff, 0xffffffff };
4179 DWORD src_pixels
[4] = { 0, 0xffff0000,
4188 GpGraphics
*graphics
;
4190 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB
, (BYTE
*)dst_pixels
, &u1
.bitmap
);
4193 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB
, (BYTE
*)src_pixels
, &u2
.bitmap
);
4195 status
= GdipGetImageGraphicsContext(u1
.image
, &graphics
);
4197 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4200 status
= GdipSetCompositingMode(graphics
, CompositingModeSourceCopy
);
4203 status
= GdipDrawImageI(graphics
, u2
.image
, 0, 0);
4206 todo_wine
expect(0, dst_pixels
[0]);
4207 expect(0xffff0000, dst_pixels
[1]);
4208 todo_wine
expect(0, dst_pixels
[2]);
4209 todo_wine
expect(0, dst_pixels
[3]);
4211 status
= GdipDeleteGraphics(graphics
);
4213 status
= GdipDisposeImage(u1
.image
);
4215 status
= GdipDisposeImage(u2
.image
);
4219 static void test_GdipDrawImagePointRect(void)
4221 BYTE black_1x1
[4] = { 0,0,0,0 };
4222 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
4223 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
4224 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
4225 0,0,0,0,0,0,0xff,0xff };
4232 GpGraphics
*graphics
;
4235 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
4237 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4240 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
4242 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
4244 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4246 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4249 status
= GdipDrawImagePointRectI(graphics
, u1
.image
, 0, 0, 0, 0, 1, 1, UnitPixel
);
4252 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
4253 ok(match
, "data should match\n");
4256 UINT i
, size
= sizeof(white_2x2
);
4257 BYTE
*bits
= white_2x2
;
4258 for (i
= 0; i
< size
; i
++)
4259 trace(" %02x", bits
[i
]);
4263 status
= GdipDeleteGraphics(graphics
);
4265 status
= GdipDisposeImage(u1
.image
);
4267 status
= GdipDisposeImage(u2
.image
);
4271 static void test_image_format(void)
4273 static const PixelFormat fmt
[] =
4275 PixelFormat1bppIndexed
, PixelFormat4bppIndexed
, PixelFormat8bppIndexed
,
4276 PixelFormat16bppGrayScale
, PixelFormat16bppRGB555
, PixelFormat16bppRGB565
,
4277 PixelFormat16bppARGB1555
, PixelFormat24bppRGB
, PixelFormat32bppRGB
,
4278 PixelFormat32bppARGB
, PixelFormat32bppPARGB
, PixelFormat48bppRGB
,
4279 PixelFormat64bppARGB
, PixelFormat64bppPARGB
, PixelFormat32bppCMYK
4290 for (i
= 0; i
< ARRAY_SIZE(fmt
); i
++)
4292 status
= GdipCreateBitmapFromScan0(1, 1, 0, fmt
[i
], NULL
, &bitmap
);
4293 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* before win7 */,
4294 "GdipCreateBitmapFromScan0 error %d\n", status
);
4295 if (status
!= Ok
) continue;
4297 status
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
4299 expect(fmt
[i
], format
);
4301 status
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
4302 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4303 todo_wine
expect(InvalidParameter
, status
);
4307 ret
= GetObjectW(hbitmap
, sizeof(bm
), &bm
);
4308 expect(sizeof(bm
), ret
);
4309 expect(0, bm
.bmType
);
4310 expect(1, bm
.bmWidth
);
4311 expect(1, bm
.bmHeight
);
4312 expect(4, bm
.bmWidthBytes
);
4313 expect(1, bm
.bmPlanes
);
4314 expect(32, bm
.bmBitsPixel
);
4315 DeleteObject(hbitmap
);
4318 status
= GdipGetImageThumbnail((GpImage
*)bitmap
, 0, 0, &thumb
, NULL
, NULL
);
4319 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4321 ok(status
== OutOfMemory
|| broken(status
== InvalidParameter
) /* before win7 */,
4322 "expected OutOfMemory, got %d\n", status
);
4327 status
= GdipGetImagePixelFormat(thumb
, &format
);
4329 ok(format
== PixelFormat32bppPARGB
|| broken(format
!= PixelFormat32bppPARGB
) /* before win7 */,
4330 "expected PixelFormat32bppPARGB, got %#x\n", format
);
4331 status
= GdipDisposeImage(thumb
);
4335 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4336 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4337 todo_wine
expect(InvalidParameter
, status
);
4341 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4345 status
= GdipDisposeImage((GpImage
*)bitmap
);
4350 static void test_DrawImage_scale(void)
4352 static const BYTE back_8x1
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
4353 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4354 static const BYTE image_080
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,
4355 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4356 static const BYTE image_100
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,
4357 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4358 static const BYTE image_120
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,
4359 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4360 static const BYTE image_150
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4361 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4362 static const BYTE image_180
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4363 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4364 static const BYTE image_200
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4365 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4366 static const BYTE image_250
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,
4367 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4368 static const BYTE image_120_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4369 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4370 static const BYTE image_150_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4371 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4372 static const BYTE image_200_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4373 0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40 };
4374 static const BYTE image_250_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4375 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4376 static const struct test_data
4379 PixelOffsetMode pixel_offset_mode
;
4384 { 0.8, PixelOffsetModeNone
, image_080
}, /* 0 */
4385 { 1.0, PixelOffsetModeNone
, image_100
},
4386 { 1.2, PixelOffsetModeNone
, image_120
},
4387 { 1.5, PixelOffsetModeNone
, image_150
},
4388 { 1.8, PixelOffsetModeNone
, image_180
},
4389 { 2.0, PixelOffsetModeNone
, image_200
},
4390 { 2.5, PixelOffsetModeNone
, image_250
},
4392 { 0.8, PixelOffsetModeHighSpeed
, image_080
}, /* 7 */
4393 { 1.0, PixelOffsetModeHighSpeed
, image_100
},
4394 { 1.2, PixelOffsetModeHighSpeed
, image_120
},
4395 { 1.5, PixelOffsetModeHighSpeed
, image_150
},
4396 { 1.8, PixelOffsetModeHighSpeed
, image_180
},
4397 { 2.0, PixelOffsetModeHighSpeed
, image_200
},
4398 { 2.5, PixelOffsetModeHighSpeed
, image_250
},
4400 { 0.8, PixelOffsetModeHalf
, image_080
}, /* 14 */
4401 { 1.0, PixelOffsetModeHalf
, image_100
},
4402 { 1.2, PixelOffsetModeHalf
, image_120_half
, TRUE
},
4403 { 1.5, PixelOffsetModeHalf
, image_150_half
, TRUE
},
4404 { 1.8, PixelOffsetModeHalf
, image_180
},
4405 { 2.0, PixelOffsetModeHalf
, image_200_half
, TRUE
},
4406 { 2.5, PixelOffsetModeHalf
, image_250_half
, TRUE
},
4408 { 0.8, PixelOffsetModeHighQuality
, image_080
}, /* 21 */
4409 { 1.0, PixelOffsetModeHighQuality
, image_100
},
4410 { 1.2, PixelOffsetModeHighQuality
, image_120_half
, TRUE
},
4411 { 1.5, PixelOffsetModeHighQuality
, image_150_half
, TRUE
},
4412 { 1.8, PixelOffsetModeHighQuality
, image_180
},
4413 { 2.0, PixelOffsetModeHighQuality
, image_200_half
, TRUE
},
4414 { 2.5, PixelOffsetModeHighQuality
, image_250_half
, TRUE
},
4416 BYTE src_2x1
[6] = { 0x80,0x80,0x80,0x80,0x80,0x80 };
4424 GpGraphics
*graphics
;
4428 status
= GdipCreateBitmapFromScan0(2, 1, 4, PixelFormat24bppRGB
, src_2x1
, &u1
.bitmap
);
4430 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4433 status
= GdipCreateBitmapFromScan0(8, 1, 24, PixelFormat24bppRGB
, dst_8x1
, &u2
.bitmap
);
4435 status
= GdipBitmapSetResolution(u2
.bitmap
, 100.0, 100.0);
4437 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4439 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4442 for (i
= 0; i
< ARRAY_SIZE(td
); i
++)
4444 status
= GdipSetPixelOffsetMode(graphics
, td
[i
].pixel_offset_mode
);
4447 status
= GdipCreateMatrix2(td
[i
].scale_x
, 0.0, 0.0, 1.0, 0.0, 0.0, &matrix
);
4449 status
= GdipSetWorldTransform(graphics
, matrix
);
4451 GdipDeleteMatrix(matrix
);
4453 memcpy(dst_8x1
, back_8x1
, sizeof(dst_8x1
));
4454 status
= GdipDrawImageI(graphics
, u1
.image
, 1, 0);
4457 match
= memcmp(dst_8x1
, td
[i
].image
, sizeof(dst_8x1
)) == 0;
4458 todo_wine_if (!match
&& td
[i
].todo
)
4459 ok(match
, "%d: data should match\n", i
);
4462 UINT i
, size
= sizeof(dst_8x1
);
4463 const BYTE
*bits
= dst_8x1
;
4464 for (i
= 0; i
< size
; i
++)
4465 trace(" %02x", bits
[i
]);
4470 status
= GdipDeleteGraphics(graphics
);
4472 status
= GdipDisposeImage(u1
.image
);
4474 status
= GdipDisposeImage(u2
.image
);
4478 static const BYTE animatedgif
[] = {
4479 'G','I','F','8','9','a',0x01,0x00,0x01,0x00,0xA1,0x02,0x00,
4480 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
4481 /*0x21,0xFF,0x0B,'A','N','I','M','E','X','T','S','1','.','0',*/
4482 0x21,0xFF,0x0B,'N','E','T','S','C','A','P','E','2','.','0',
4483 0x03,0x01,0x05,0x00,0x00,
4484 0x21,0xFE,0x0C,'H','e','l','l','o',' ','W','o','r','l','d','!',0x00,
4485 0x21,0x01,0x0D,'a','n','i','m','a','t','i','o','n','.','g','i','f',0x00,
4486 0x21,0xF9,0x04,0xff,0x0A,0x00,0x08,0x00,
4487 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4488 0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,
4489 0x02,0x02,0x4C,0x01,0x00,
4490 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','1',0x00,
4491 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','1',0x00,
4492 0x21,0xF9,0x04,0x00,0x14,0x00,0x01,0x00,
4493 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4494 0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,
4495 0x02,0x02,0x44,0x01,0x00,
4496 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','2',0x00,
4497 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','2',0x00,0x3B
4500 static void test_gif_properties(void)
4502 static const struct test_data
4504 ULONG type
, id
, length
;
4505 const BYTE value
[13];
4508 { PropertyTagTypeLong
, PropertyTagFrameDelay
, 8, { 10,0,0,0,20,0,0,0 } },
4509 { PropertyTagTypeASCII
, PropertyTagExifUserComment
, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
4510 { PropertyTagTypeShort
, PropertyTagLoopCount
, 2, { 5,0 } },
4511 { PropertyTagTypeByte
, PropertyTagGlobalPalette
, 12, { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c } },
4512 { PropertyTagTypeByte
, PropertyTagIndexBackground
, 1, { 2 } },
4513 { PropertyTagTypeByte
, PropertyTagIndexTransparent
, 1, { 8 } }
4518 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
4519 UINT total_size
, total_count
;
4521 PropertyItem
*prop_item
;
4522 const char *item_data
;
4524 image
= load_image(animatedgif
, sizeof(animatedgif
), TRUE
, FALSE
);
4525 if (!image
) /* XP fails to load this GIF image */
4527 trace("Failed to load GIF image data\n");
4531 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
4533 expect(1, dim_count
);
4535 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
4537 expect_guid(&FrameDimensionTime
, &guid
, __LINE__
, FALSE
);
4539 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
4541 expect(2, frame_count
);
4543 status
= GdipImageSelectActiveFrame(image
, &guid
, 1);
4546 status
= GdipGetPropertyCount(image
, &prop_count
);
4548 ok(prop_count
== ARRAY_SIZE(td
) || broken(prop_count
== 1) /* before win7 */,
4549 "expected property count %u, got %u\n", (UINT
) ARRAY_SIZE(td
), prop_count
);
4551 if (prop_count
!= ARRAY_SIZE(td
))
4553 GdipDisposeImage(image
);
4557 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
4559 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
4563 for (i
= 0; i
< prop_count
; i
++)
4566 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
4568 if (status
!= Ok
) break;
4569 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
4573 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
4574 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
4576 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
4577 ok(td
[i
].type
== prop_item
->type
,
4578 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
4579 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
4580 size
-= sizeof(*prop_item
);
4581 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
4582 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
4583 if (td
[i
].length
== prop_item
->length
)
4585 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
4586 ok(match
, "%u: data mismatch\n", i
);
4590 BYTE
*data
= prop_item
->value
;
4591 trace("id %#x:", prop_item
->id
);
4592 for (j
= 0; j
< prop_item
->length
; j
++)
4593 trace(" %02x", data
[j
]);
4597 HeapFree(GetProcessHeap(), 0, prop_item
);
4600 HeapFree(GetProcessHeap(), 0, prop_id
);
4602 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
4603 expect(InvalidParameter
, status
);
4604 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
4605 expect(InvalidParameter
, status
);
4606 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
4607 expect(InvalidParameter
, status
);
4608 status
= GdipGetPropertySize(image
, NULL
, NULL
);
4609 expect(InvalidParameter
, status
);
4610 total_size
= 0xdeadbeef;
4611 total_count
= 0xdeadbeef;
4612 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
4614 ok(prop_count
== total_count
,
4615 "expected total property count %u, got %u\n", prop_count
, total_count
);
4616 ok(prop_size
== total_size
,
4617 "expected total property size %u, got %u\n", prop_size
, total_size
);
4619 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
4621 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
4622 expect(InvalidParameter
, status
);
4623 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
4624 expect(InvalidParameter
, status
);
4625 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4626 expect(InvalidParameter
, status
);
4627 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4628 expect(InvalidParameter
, status
);
4629 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
4630 expect(InvalidParameter
, status
);
4631 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
4632 expect(InvalidParameter
, status
);
4633 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
4636 item_data
= (const char *)(prop_item
+ prop_count
);
4637 for (i
= 0; i
< prop_count
; i
++)
4639 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
4640 i
, item_data
, prop_item
[i
].value
);
4641 ok(td
[i
].type
== prop_item
[i
].type
,
4642 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
4643 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
4644 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
4645 if (td
[i
].length
== prop_item
[i
].length
)
4647 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
4648 ok(match
, "%u: data mismatch\n", i
);
4652 BYTE
*data
= prop_item
[i
].value
;
4653 trace("id %#x:", prop_item
[i
].id
);
4654 for (j
= 0; j
< prop_item
[i
].length
; j
++)
4655 trace(" %02x", data
[j
]);
4659 item_data
+= prop_item
[i
].length
;
4662 HeapFree(GetProcessHeap(), 0, prop_item
);
4664 GdipDisposeImage(image
);
4667 static void test_ARGB_conversion(void)
4669 BYTE argb
[8] = { 0x11,0x22,0x33,0x80, 0xff,0xff,0xff,0 };
4670 BYTE pargb
[8] = { 0x09,0x11,0x1a,0x80, 0,0,0,0 };
4671 BYTE rgb32_xp
[8] = { 0x11,0x22,0x33,0xff, 0xff,0xff,0xff,0xff };
4672 BYTE rgb24
[6] = { 0x11,0x22,0x33, 0xff,0xff,0xff };
4679 status
= GdipCreateBitmapFromScan0(2, 1, 8, PixelFormat32bppARGB
, argb
, &bitmap
);
4682 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4684 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4685 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4686 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4687 ok(data
.PixelFormat
== PixelFormat32bppPARGB
, "expected PixelFormat32bppPARGB, got %d\n", data
.PixelFormat
);
4688 match
= !memcmp(data
.Scan0
, pargb
, sizeof(pargb
));
4689 ok(match
, "bits don't match\n");
4693 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppPARGB
,
4694 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4696 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4699 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppRGB
, &data
);
4701 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4702 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4703 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4704 ok(data
.PixelFormat
== PixelFormat32bppRGB
, "expected PixelFormat32bppRGB, got %d\n", data
.PixelFormat
);
4705 match
= !memcmp(data
.Scan0
, argb
, sizeof(argb
)) ||
4706 !memcmp(data
.Scan0
, rgb32_xp
, sizeof(rgb32_xp
));
4707 ok(match
, "bits don't match\n");
4711 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppRGB
,
4712 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4714 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4717 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
4719 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4720 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4721 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4722 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "expected PixelFormat24bppRGB, got %d\n", data
.PixelFormat
);
4723 match
= !memcmp(data
.Scan0
, rgb24
, sizeof(rgb24
));
4724 ok(match
, "bits don't match\n");
4728 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat24bppRGB
,
4729 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4731 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4734 GdipDisposeImage((GpImage
*)bitmap
);
4738 static void test_CloneBitmapArea(void)
4741 GpBitmap
*bitmap
, *copy
;
4742 BitmapData data
, data2
;
4744 status
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB
, NULL
, &bitmap
);
4747 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
| ImageLockModeWrite
, PixelFormat24bppRGB
, &data
);
4750 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data2
);
4751 expect(WrongState
, status
);
4753 status
= GdipCloneBitmapAreaI(0, 0, 1, 1, PixelFormat24bppRGB
, bitmap
, ©
);
4756 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4759 GdipDisposeImage((GpImage
*)copy
);
4760 GdipDisposeImage((GpImage
*)bitmap
);
4763 static BOOL
get_encoder_clsid(LPCWSTR mime
, GUID
*format
, CLSID
*clsid
)
4766 UINT n_codecs
, info_size
, i
;
4767 ImageCodecInfo
*info
;
4770 status
= GdipGetImageEncodersSize(&n_codecs
, &info_size
);
4773 info
= GdipAlloc(info_size
);
4775 status
= GdipGetImageEncoders(n_codecs
, info_size
, info
);
4778 for (i
= 0; i
< n_codecs
; i
++)
4780 if (!lstrcmpW(info
[i
].MimeType
, mime
))
4782 *format
= info
[i
].FormatID
;
4783 *clsid
= info
[i
].Clsid
;
4793 static void test_supported_encoders(void)
4795 static const WCHAR bmp_mimetype
[] = { 'i', 'm', 'a','g', 'e', '/', 'b', 'm', 'p',0 };
4796 static const WCHAR jpeg_mimetype
[] = { 'i','m','a','g','e','/','j','p','e','g',0 };
4797 static const WCHAR gif_mimetype
[] = { 'i','m','a','g','e','/','g','i','f',0 };
4798 static const WCHAR tiff_mimetype
[] = { 'i','m','a','g','e','/','t','i','f','f',0 };
4799 static const WCHAR png_mimetype
[] = { 'i','m','a','g','e','/','p','n','g',0 };
4800 static const struct test_data
4807 { bmp_mimetype
, &ImageFormatBMP
, FALSE
},
4808 { jpeg_mimetype
, &ImageFormatJPEG
, FALSE
},
4809 { gif_mimetype
, &ImageFormatGIF
, TRUE
},
4810 { tiff_mimetype
, &ImageFormatTIFF
, FALSE
},
4811 { png_mimetype
, &ImageFormatPNG
, FALSE
}
4822 status
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB
, NULL
, &bm
);
4823 ok(status
== Ok
, "GdipCreateBitmapFromScan0 error %d\n", status
);
4825 for (i
= 0; i
< ARRAY_SIZE(td
); i
++)
4827 ret
= get_encoder_clsid(td
[i
].mime
, &format
, &clsid
);
4828 ok(ret
, "%s encoder is not in the list\n", wine_dbgstr_w(td
[i
].mime
));
4829 expect_guid(td
[i
].format
, &format
, __LINE__
, FALSE
);
4831 hmem
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_NODISCARD
, 16);
4833 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
4834 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
4836 status
= GdipSaveImageToStream((GpImage
*)bm
, stream
, &clsid
, NULL
);
4837 todo_wine_if (td
[i
].todo
)
4838 ok(status
== Ok
, "GdipSaveImageToStream error %d\n", status
);
4840 IStream_Release(stream
);
4843 GdipDisposeImage((GpImage
*)bm
);
4846 static void test_createeffect(void)
4848 static const GUID noneffect
= { 0xcd0c3d4b, 0xe15e, 0x4cf2, { 0x9e, 0xa8, 0x6e, 0x1d, 0x65, 0x48, 0xc5, 0xa5 } };
4849 GpStatus (WINAPI
*pGdipCreateEffect
)( const GUID guid
, CGpEffect
**effect
);
4850 GpStatus (WINAPI
*pGdipDeleteEffect
)( CGpEffect
*effect
);
4853 HMODULE mod
= GetModuleHandleA("gdiplus.dll");
4855 const GUID
* const effectlist
[] =
4856 {&BlurEffectGuid
, &SharpenEffectGuid
, &ColorMatrixEffectGuid
, &ColorLUTEffectGuid
,
4857 &BrightnessContrastEffectGuid
, &HueSaturationLightnessEffectGuid
, &LevelsEffectGuid
,
4858 &TintEffectGuid
, &ColorBalanceEffectGuid
, &RedEyeCorrectionEffectGuid
, &ColorCurveEffectGuid
};
4860 pGdipCreateEffect
= (void*)GetProcAddress( mod
, "GdipCreateEffect");
4861 pGdipDeleteEffect
= (void*)GetProcAddress( mod
, "GdipDeleteEffect");
4862 if(!pGdipCreateEffect
|| !pGdipDeleteEffect
)
4864 /* GdipCreateEffect/GdipDeleteEffect was introduced in Windows Vista. */
4865 win_skip("GDIPlus version 1.1 not available\n");
4869 stat
= pGdipCreateEffect(BlurEffectGuid
, NULL
);
4870 expect(InvalidParameter
, stat
);
4872 stat
= pGdipCreateEffect(noneffect
, &effect
);
4873 todo_wine
expect(Win32Error
, stat
);
4875 for(i
=0; i
< ARRAY_SIZE(effectlist
); i
++)
4877 stat
= pGdipCreateEffect(*effectlist
[i
], &effect
);
4878 todo_wine
expect(Ok
, stat
);
4881 stat
= pGdipDeleteEffect(effect
);
4887 static void test_getadjustedpalette(void)
4890 GpImageAttributes
*imageattributes
;
4891 ColorPalette
*palette
;
4894 stat
= GdipCreateImageAttributes(&imageattributes
);
4897 colormap
.oldColor
.Argb
= 0xffffff00;
4898 colormap
.newColor
.Argb
= 0xffff00ff;
4899 stat
= GdipSetImageAttributesRemapTable(imageattributes
, ColorAdjustTypeBitmap
,
4900 TRUE
, 1, &colormap
);
4903 colormap
.oldColor
.Argb
= 0xffffff80;
4904 colormap
.newColor
.Argb
= 0xffff80ff;
4905 stat
= GdipSetImageAttributesRemapTable(imageattributes
, ColorAdjustTypeDefault
,
4906 TRUE
, 1, &colormap
);
4909 palette
= GdipAlloc(sizeof(*palette
) + sizeof(ARGB
) * 2);
4912 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeBitmap
);
4913 expect(InvalidParameter
, stat
);
4916 palette
->Entries
[0] = 0xffffff00;
4917 palette
->Entries
[1] = 0xffffff80;
4918 palette
->Entries
[2] = 0xffffffff;
4920 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeBitmap
);
4922 expect(0xffff00ff, palette
->Entries
[0]);
4923 expect(0xffffff80, palette
->Entries
[1]);
4924 expect(0xffffffff, palette
->Entries
[2]);
4926 palette
->Entries
[0] = 0xffffff00;
4927 palette
->Entries
[1] = 0xffffff80;
4928 palette
->Entries
[2] = 0xffffffff;
4930 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeBrush
);
4932 expect(0xffffff00, palette
->Entries
[0]);
4933 expect(0xffff80ff, palette
->Entries
[1]);
4934 expect(0xffffffff, palette
->Entries
[2]);
4936 stat
= GdipGetImageAttributesAdjustedPalette(NULL
, palette
, ColorAdjustTypeBitmap
);
4937 expect(InvalidParameter
, stat
);
4939 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, NULL
, ColorAdjustTypeBitmap
);
4940 expect(InvalidParameter
, stat
);
4942 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, -1);
4943 expect(InvalidParameter
, stat
);
4945 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeDefault
);
4946 expect(InvalidParameter
, stat
);
4949 GdipDisposeImageAttributes(imageattributes
);
4952 static void test_histogram(void)
4954 UINT ch0
[256], ch1
[256], ch2
[256], ch3
[256];
4955 HistogramFormat test_formats
[] =
4957 HistogramFormatARGB
,
4958 HistogramFormatPARGB
,
4960 HistogramFormatGray
,
4966 const UINT WIDTH
= 8, HEIGHT
= 16;
4971 if (!pGdipBitmapGetHistogramSize
)
4973 win_skip("GdipBitmapGetHistogramSize is not supported\n");
4977 stat
= pGdipBitmapGetHistogramSize(HistogramFormatARGB
, NULL
);
4978 expect(InvalidParameter
, stat
);
4980 stat
= pGdipBitmapGetHistogramSize(0xff, NULL
);
4981 expect(InvalidParameter
, stat
);
4984 stat
= pGdipBitmapGetHistogramSize(10, &num
);
4988 for (i
= 0; i
< ARRAY_SIZE(test_formats
); i
++)
4991 stat
= pGdipBitmapGetHistogramSize(test_formats
[i
], &num
);
4997 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
5000 /* Three solid rgb rows, next three rows are rgb shades. */
5001 for (x
= 0; x
< WIDTH
; x
++)
5003 GdipBitmapSetPixel(bm
, x
, 0, 0xffff0000);
5004 GdipBitmapSetPixel(bm
, x
, 1, 0xff00ff00);
5005 GdipBitmapSetPixel(bm
, x
, 2, 0xff0000ff);
5007 GdipBitmapSetPixel(bm
, x
, 3, 0xff010000);
5008 GdipBitmapSetPixel(bm
, x
, 4, 0xff003f00);
5009 GdipBitmapSetPixel(bm
, x
, 5, 0xff000020);
5012 stat
= pGdipBitmapGetHistogram(NULL
, HistogramFormatRGB
, 256, ch0
, ch1
, ch2
, ch3
);
5013 expect(InvalidParameter
, stat
);
5015 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, ch1
, ch2
, ch3
);
5016 expect(InvalidParameter
, stat
);
5018 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, ch1
, ch2
, NULL
);
5019 expect(InvalidParameter
, stat
);
5021 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, ch1
, NULL
, NULL
);
5022 expect(InvalidParameter
, stat
);
5024 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, NULL
, NULL
, NULL
);
5025 expect(InvalidParameter
, stat
);
5027 /* Requested format matches bitmap format */
5028 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 256, ch0
, ch1
, ch2
, ch3
);
5029 expect(InvalidParameter
, stat
);
5031 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 100, ch0
, ch1
, ch2
, NULL
);
5032 expect(InvalidParameter
, stat
);
5034 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 257, ch0
, ch1
, ch2
, NULL
);
5035 expect(InvalidParameter
, stat
);
5037 /* Channel 3 is not used, must be NULL */
5038 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 256, ch0
, ch1
, ch2
, NULL
);
5041 ok(ch0
[0xff] == WIDTH
, "Got red (0xff) %u\n", ch0
[0xff]);
5042 ok(ch1
[0xff] == WIDTH
, "Got green (0xff) %u\n", ch1
[0xff]);
5043 ok(ch2
[0xff] == WIDTH
, "Got blue (0xff) %u\n", ch1
[0xff]);
5044 ok(ch0
[0x01] == WIDTH
, "Got red (0x01) %u\n", ch0
[0x01]);
5045 ok(ch1
[0x3f] == WIDTH
, "Got green (0x3f) %u\n", ch1
[0x3f]);
5046 ok(ch2
[0x20] == WIDTH
, "Got blue (0x20) %u\n", ch1
[0x20]);
5048 /* ARGB histogram from RGB data. */
5049 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatARGB
, 256, ch0
, ch1
, ch2
, NULL
);
5050 expect(InvalidParameter
, stat
);
5052 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatARGB
, 256, ch0
, ch1
, ch2
, ch3
);
5055 ok(ch1
[0xff] == WIDTH
, "Got red (0xff) %u\n", ch1
[0xff]);
5056 ok(ch2
[0xff] == WIDTH
, "Got green (0xff) %u\n", ch2
[0xff]);
5057 ok(ch3
[0xff] == WIDTH
, "Got blue (0xff) %u\n", ch3
[0xff]);
5058 ok(ch1
[0x01] == WIDTH
, "Got red (0x01) %u\n", ch1
[0x01]);
5059 ok(ch2
[0x3f] == WIDTH
, "Got green (0x3f) %u\n", ch2
[0x3f]);
5060 ok(ch3
[0x20] == WIDTH
, "Got blue (0x20) %u\n", ch3
[0x20]);
5062 ok(ch0
[0xff] == WIDTH
* HEIGHT
, "Got alpha (0xff) %u\n", ch0
[0xff]);
5064 /* Request grayscale histogram from RGB bitmap. */
5065 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, ch1
, ch2
, ch3
);
5066 expect(InvalidParameter
, stat
);
5068 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, ch1
, ch2
, NULL
);
5069 expect(InvalidParameter
, stat
);
5071 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, ch1
, NULL
, NULL
);
5072 expect(InvalidParameter
, stat
);
5074 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, NULL
, NULL
, NULL
);
5077 GdipDisposeImage((GpImage
*)bm
);
5080 static void test_imageabort(void)
5085 if (!pGdipImageSetAbort
)
5087 win_skip("GdipImageSetAbort() is not supported.\n");
5092 stat
= GdipCreateBitmapFromScan0(8, 8, 0, PixelFormat24bppRGB
, NULL
, &bm
);
5095 stat
= pGdipImageSetAbort(NULL
, NULL
);
5096 expect(InvalidParameter
, stat
);
5098 stat
= pGdipImageSetAbort((GpImage
*)bm
, NULL
);
5101 GdipDisposeImage((GpImage
*)bm
);
5104 /* RGB 24 bpp 1x1 pixel PNG image */
5105 static const char png_1x1_data
[] = {
5106 0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,
5107 0x00,0x00,0x00,0x0d,'I','H','D','R',0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,0xde,
5108 0x00,0x00,0x03,0x00,'P','L','T','E',
5109 0x01,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,
5110 0x09,0x09,0x09,0x0a,0x0a,0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0c,0x0d,0x0d,0x0d,0x0e,0x0e,0x0e,0x0f,0x0f,0x0f,0x10,0x10,0x10,
5111 0x11,0x11,0x11,0x12,0x12,0x12,0x13,0x13,0x13,0x14,0x14,0x14,0x15,0x15,0x15,0x16,0x16,0x16,0x17,0x17,0x17,0x18,0x18,0x18,
5112 0x19,0x19,0x19,0x1a,0x1a,0x1a,0x1b,0x1b,0x1b,0x1c,0x1c,0x1c,0x1d,0x1d,0x1d,0x1e,0x1e,0x1e,0x1f,0x1f,0x1f,0x20,0x20,0x20,
5113 0x21,0x21,0x21,0x22,0x22,0x22,0x23,0x23,0x23,0x24,0x24,0x24,0x25,0x25,0x25,0x26,0x26,0x26,0x27,0x27,0x27,0x28,0x28,0x28,
5114 0x29,0x29,0x29,0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,0x2c,0x2c,0x2c,0x2d,0x2d,0x2d,0x2e,0x2e,0x2e,0x2f,0x2f,0x2f,0x30,0x30,0x30,
5115 0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x37,0x37,0x37,0x38,0x38,0x38,
5116 0x39,0x39,0x39,0x3a,0x3a,0x3a,0x3b,0x3b,0x3b,0x3c,0x3c,0x3c,0x3d,0x3d,0x3d,0x3e,0x3e,0x3e,0x3f,0x3f,0x3f,0x40,0x40,0x40,
5117 0x41,0x41,0x41,0x42,0x42,0x42,0x43,0x43,0x43,0x44,0x44,0x44,0x45,0x45,0x45,0x46,0x46,0x46,0x47,0x47,0x47,0x48,0x48,0x48,
5118 0x49,0x49,0x49,0x4a,0x4a,0x4a,0x4b,0x4b,0x4b,0x4c,0x4c,0x4c,0x4d,0x4d,0x4d,0x4e,0x4e,0x4e,0x4f,0x4f,0x4f,0x50,0x50,0x50,
5119 0x51,0x51,0x51,0x52,0x52,0x52,0x53,0x53,0x53,0x54,0x54,0x54,0x55,0x55,0x55,0x56,0x56,0x56,0x57,0x57,0x57,0x58,0x58,0x58,
5120 0x59,0x59,0x59,0x5a,0x5a,0x5a,0x5b,0x5b,0x5b,0x5c,0x5c,0x5c,0x5d,0x5d,0x5d,0x5e,0x5e,0x5e,0x5f,0x5f,0x5f,0x60,0x60,0x60,
5121 0x61,0x61,0x61,0x62,0x62,0x62,0x63,0x63,0x63,0x64,0x64,0x64,0x65,0x65,0x65,0x66,0x66,0x66,0x67,0x67,0x67,0x68,0x68,0x68,
5122 0x69,0x69,0x69,0x6a,0x6a,0x6a,0x6b,0x6b,0x6b,0x6c,0x6c,0x6c,0x6d,0x6d,0x6d,0x6e,0x6e,0x6e,0x6f,0x6f,0x6f,0x70,0x70,0x70,
5123 0x71,0x71,0x71,0x72,0x72,0x72,0x73,0x73,0x73,0x74,0x74,0x74,0x75,0x75,0x75,0x76,0x76,0x76,0x77,0x77,0x77,0x78,0x78,0x78,
5124 0x79,0x79,0x79,0x7a,0x7a,0x7a,0x7b,0x7b,0x7b,0x7c,0x7c,0x7c,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x80,0x80,0x80,
5125 0x01,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,
5126 0x09,0x09,0x09,0x0a,0x0a,0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0c,0x0d,0x0d,0x0d,0x0e,0x0e,0x0e,0x0f,0x0f,0x0f,0x10,0x10,0x10,
5127 0x11,0x11,0x11,0x12,0x12,0x12,0x13,0x13,0x13,0x14,0x14,0x14,0x15,0x15,0x15,0x16,0x16,0x16,0x17,0x17,0x17,0x18,0x18,0x18,
5128 0x19,0x19,0x19,0x1a,0x1a,0x1a,0x1b,0x1b,0x1b,0x1c,0x1c,0x1c,0x1d,0x1d,0x1d,0x1e,0x1e,0x1e,0x1f,0x1f,0x1f,0x20,0x20,0x20,
5129 0x21,0x21,0x21,0x22,0x22,0x22,0x23,0x23,0x23,0x24,0x24,0x24,0x25,0x25,0x25,0x26,0x26,0x26,0x27,0x27,0x27,0x28,0x28,0x28,
5130 0x29,0x29,0x29,0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,0x2c,0x2c,0x2c,0x2d,0x2d,0x2d,0x2e,0x2e,0x2e,0x2f,0x2f,0x2f,0x30,0x30,0x30,
5131 0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x37,0x37,0x37,0x38,0x38,0x38,
5132 0x39,0x39,0x39,0x3a,0x3a,0x3a,0x3b,0x3b,0x3b,0x3c,0x3c,0x3c,0x3d,0x3d,0x3d,0x3e,0x3e,0x3e,0x3f,0x3f,0x3f,0x40,0x40,0x40,
5133 0x41,0x41,0x41,0x42,0x42,0x42,0x43,0x43,0x43,0x44,0x44,0x44,0x45,0x45,0x45,0x46,0x46,0x46,0x47,0x47,0x47,0x48,0x48,0x48,
5134 0x49,0x49,0x49,0x4a,0x4a,0x4a,0x4b,0x4b,0x4b,0x4c,0x4c,0x4c,0x4d,0x4d,0x4d,0x4e,0x4e,0x4e,0x4f,0x4f,0x4f,0x50,0x50,0x50,
5135 0x51,0x51,0x51,0x52,0x52,0x52,0x53,0x53,0x53,0x54,0x54,0x54,0x55,0x55,0x55,0x56,0x56,0x56,0x57,0x57,0x57,0x58,0x58,0x58,
5136 0x59,0x59,0x59,0x5a,0x5a,0x5a,0x5b,0x5b,0x5b,0x5c,0x5c,0x5c,0x5d,0x5d,0x5d,0x5e,0x5e,0x5e,0x5f,0x5f,0x5f,0x60,0x60,0x60,
5137 0x61,0x61,0x61,0x62,0x62,0x62,0x63,0x63,0x63,0x64,0x64,0x64,0x65,0x65,0x65,0x66,0x66,0x66,0x67,0x67,0x67,0x68,0x68,0x68,
5138 0x69,0x69,0x69,0x6a,0x6a,0x6a,0x6b,0x6b,0x6b,0x6c,0x6c,0x6c,0x6d,0x6d,0x6d,0x6e,0x6e,0x6e,0x6f,0x6f,0x6f,0x70,0x70,0x70,
5139 0x71,0x71,0x71,0x72,0x72,0x72,0x73,0x73,0x73,0x74,0x74,0x74,0x75,0x75,0x75,0x76,0x76,0x76,0x77,0x77,0x77,0x78,0x78,0x78,
5140 0x79,0x79,0x79,0x7a,0x7a,0x7a,0x7b,0x7b,0x7b,0x7c,0x7c,0x7c,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x80,0x80,0x80,
5141 0x76,0xb6,0x24,0x31,
5142 0x00,0x00,0x00,0x02,'t','R','N','S',0xff,0x00,0xe5,0xb7,0x30,0x4a,
5143 0x00,0x00,0x00,0x0c,'I','D','A','T',0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,0xe7,
5144 0x00,0x00,0x00,0x00,'I','E','N','D',0xae,0x42,0x60,0x82
5147 #define PNG_COLOR_TYPE_GRAY 0
5148 #define PNG_COLOR_TYPE_RGB 2
5149 #define PNG_COLOR_TYPE_PALETTE 3
5150 #define PNG_COLOR_TYPE_GRAY_ALPHA 4
5151 #define PNG_COLOR_TYPE_RGB_ALPHA 6
5153 static void test_png_color_formats(void)
5157 char bit_depth
, color_type
;
5167 { 1, PNG_COLOR_TYPE_RGB
},
5168 { 2, PNG_COLOR_TYPE_RGB
},
5169 { 4, PNG_COLOR_TYPE_RGB
},
5170 { 8, PNG_COLOR_TYPE_RGB
,
5171 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
, TRUE
},
5172 { PixelFormat24bppRGB
, ImageFlagsColorSpaceRGB
},
5173 { PixelFormat24bppRGB
, ImageFlagsColorSpaceRGB
}}},
5174 /* libpng refuses to load our test image complaining about extra compressed data,
5175 * but libpng is still able to load the image with other combination of type/depth
5176 * making RGB 16 bpp case special for some reason. Therefore todo = TRUE.
5178 { 16, PNG_COLOR_TYPE_RGB
,
5179 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
, TRUE
, TRUE
},
5180 { PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
, TRUE
, TRUE
},
5181 { PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
, TRUE
, TRUE
}}},
5184 { 1, PNG_COLOR_TYPE_GRAY
,
5185 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
, TRUE
},
5186 { PixelFormat1bppIndexed
, ImageFlagsColorSpaceRGB
},
5187 { PixelFormat1bppIndexed
, ImageFlagsColorSpaceRGB
}}},
5188 { 2, PNG_COLOR_TYPE_GRAY
,
5189 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
},
5190 { PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
},
5191 { PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
}}},
5192 { 4, PNG_COLOR_TYPE_GRAY
,
5193 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
},
5194 { PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
},
5195 { PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
}}},
5196 { 8, PNG_COLOR_TYPE_GRAY
,
5197 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
, TRUE
},
5198 { PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
},
5199 { PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
}}},
5200 { 16, PNG_COLOR_TYPE_GRAY
,
5201 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
},
5202 { PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
},
5203 { PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
}}},
5206 { 1, PNG_COLOR_TYPE_PALETTE
,
5207 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
, TRUE
},
5208 { PixelFormat1bppIndexed
, ImageFlagsColorSpaceRGB
},
5210 { 2, PNG_COLOR_TYPE_PALETTE
,
5211 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
},
5212 { PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
},
5214 { 4, PNG_COLOR_TYPE_PALETTE
,
5215 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
},
5216 { PixelFormat4bppIndexed
, ImageFlagsColorSpaceRGB
, TRUE
},
5218 { 8, PNG_COLOR_TYPE_PALETTE
,
5219 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
, TRUE
},
5220 { PixelFormat8bppIndexed
, ImageFlagsColorSpaceRGB
},
5222 { 16, PNG_COLOR_TYPE_PALETTE
},
5224 BYTE buf
[sizeof(png_1x1_data
)];
5231 int i
, j
, PLTE_off
= 0, tRNS_off
= 0;
5232 const ImageFlags color_space_mask
= ImageFlagsColorSpaceRGB
| ImageFlagsColorSpaceCMYK
| ImageFlagsColorSpaceGRAY
| ImageFlagsColorSpaceYCBCR
| ImageFlagsColorSpaceYCCK
;
5234 memcpy(buf
, png_1x1_data
, sizeof(png_1x1_data
));
5236 buf
[25] = PNG_COLOR_TYPE_PALETTE
;
5237 image
= load_image(buf
, sizeof(buf
), TRUE
, FALSE
);
5238 status
= GdipGetImageFlags(image
, &flags
);
5240 ok((flags
& color_space_mask
) == ImageFlagsColorSpaceRGB
|| broken(flags
== 0x12006) /* before win7 */,
5241 "flags = %#x\n", flags
);
5242 if ((flags
& color_space_mask
) != ImageFlagsColorSpaceRGB
) {
5243 GdipDisposeImage(image
);
5244 win_skip("broken PNG color space support\n");
5247 GdipDisposeImage(image
);
5249 for (i
= 0; i
< sizeof(png_1x1_data
) - 4; i
++)
5251 if (!memcmp(buf
+ i
, "tRNS", 4))
5253 else if (!memcmp(buf
+ i
, "PLTE", 4))
5257 ok(PLTE_off
&& tRNS_off
, "PLTE offset %d, tRNS offset %d\n", PLTE_off
, tRNS_off
);
5258 if (!PLTE_off
|| !tRNS_off
) return;
5260 /* In order to test the image data with and without PLTE and tRNS
5261 * chunks, we mask the chunk name with private one (tEST).
5264 for (i
= 0; i
< ARRAY_SIZE(td
); i
++)
5266 for (j
= 0; j
< 3; j
++)
5268 memcpy(buf
, png_1x1_data
, sizeof(png_1x1_data
));
5269 buf
[24] = td
[i
].bit_depth
;
5270 buf
[25] = td
[i
].color_type
;
5271 if (j
>=1) memcpy(buf
+ tRNS_off
, "tEST", 4);
5272 if (j
>=2) memcpy(buf
+ PLTE_off
, "tEST", 4);
5274 valid
= (td
[i
].t
[j
].format
!= 0) || (td
[i
].t
[j
].flags
!= 0);
5275 image
= load_image(buf
, sizeof(buf
), valid
, td
[i
].t
[j
].todo_load
);
5276 todo_wine_if(td
[i
].t
[j
].todo_load
)
5278 ok(image
!= NULL
, "%d %d: failed to load image data\n", i
, j
);
5281 ok(image
== NULL
, "%d %d: succeed to load image data\n", i
, j
);
5282 if (image
) GdipDisposeImage(image
);
5285 if (!image
) continue;
5287 status
= GdipGetImageType(image
, &type
);
5288 ok(status
== Ok
, "%d %d: GdipGetImageType error %d\n", i
, j
, status
);
5289 ok(type
== ImageTypeBitmap
, "%d %d: wrong image type %d\n", i
, j
, type
);
5291 status
= GdipGetImagePixelFormat(image
, &format
);
5293 todo_wine_if(td
[i
].t
[j
].todo
)
5294 ok(format
== td
[i
].t
[j
].format
,
5295 "%d %d: expected %#x, got %#x\n", i
, j
, td
[i
].t
[j
].format
, format
);
5297 status
= GdipGetImageFlags(image
, &flags
);
5299 ok((flags
& color_space_mask
) == td
[i
].t
[j
].flags
,
5300 "%d %d: expected %#x, got %#x\n", i
, j
, td
[i
].t
[j
].flags
, flags
);
5301 GdipDisposeImage(image
);
5305 #undef PNG_COLOR_TYPE_GRAY
5306 #undef PNG_COLOR_TYPE_RGB
5307 #undef PNG_COLOR_TYPE_PALETTE
5308 #undef PNG_COLOR_TYPE_GRAY_ALPHA
5309 #undef PNG_COLOR_TYPE_RGB_ALPHA
5311 static void test_GdipLoadImageFromStream(void)
5320 status
= GdipLoadImageFromStream(NULL
, NULL
);
5321 ok(status
== InvalidParameter
, "Unexpected return value %d.\n", status
);
5323 image
= (void *)0xdeadbeef;
5324 status
= GdipLoadImageFromStream(NULL
, &image
);
5325 ok(status
== InvalidParameter
, "Unexpected return value %d.\n", status
);
5326 ok(image
== (void *)0xdeadbeef, "Unexpected image pointer.\n");
5328 hglob
= GlobalAlloc(0, sizeof(pngimage
));
5329 data
= GlobalLock (hglob
);
5330 memcpy(data
, pngimage
, sizeof(pngimage
));
5331 GlobalUnlock(hglob
);
5333 hr
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
5334 ok(hr
== S_OK
, "Failed to create a stream.\n");
5336 status
= GdipLoadImageFromStream(stream
, NULL
);
5337 ok(status
== InvalidParameter
, "Unexpected return value %d.\n", status
);
5339 IStream_Release(stream
);
5344 HMODULE mod
= GetModuleHandleA("gdiplus.dll");
5345 struct GdiplusStartupInput gdiplusStartupInput
;
5346 ULONG_PTR gdiplusToken
;
5348 int (CDECL
* _controlfp_s
)(unsigned int *cur
, unsigned int newval
, unsigned int mask
);
5350 /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */
5351 hmsvcrt
= LoadLibraryA("msvcrt");
5352 _controlfp_s
= (void*)GetProcAddress(hmsvcrt
, "_controlfp_s");
5353 if (_controlfp_s
) _controlfp_s(0, 0, 0x0008001e);
5355 gdiplusStartupInput
.GdiplusVersion
= 1;
5356 gdiplusStartupInput
.DebugEventCallback
= NULL
;
5357 gdiplusStartupInput
.SuppressBackgroundThread
= 0;
5358 gdiplusStartupInput
.SuppressExternalCodecs
= 0;
5360 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, NULL
);
5362 pGdipBitmapGetHistogramSize
= (void*)GetProcAddress(mod
, "GdipBitmapGetHistogramSize");
5363 pGdipBitmapGetHistogram
= (void*)GetProcAddress(mod
, "GdipBitmapGetHistogram");
5364 pGdipImageSetAbort
= (void*)GetProcAddress(mod
, "GdipImageSetAbort");
5366 test_png_color_formats();
5367 test_supported_encoders();
5368 test_CloneBitmapArea();
5369 test_ARGB_conversion();
5370 test_DrawImage_scale();
5371 test_image_format();
5373 test_DrawImage_SourceCopy();
5374 test_GdipDrawImagePointRect();
5376 test_tiff_palette();
5377 test_GdipGetAllPropertyItems();
5378 test_tiff_properties();
5379 test_gif_properties();
5380 test_image_properties();
5383 test_GetImageDimension();
5384 test_GdipImageGetFrameDimensionsCount();
5385 test_LoadingImages();
5386 test_SavingImages();
5389 test_LockBits_UserBuf();
5390 test_GdipCreateBitmapFromHBITMAP();
5391 test_GdipGetImageFlags();
5392 test_GdipCloneImage();
5395 test_getrawformat();
5397 test_createfromwmf();
5398 test_createfromwmf_noplaceable();
5400 test_createhbitmap();
5401 test_getthumbnail();
5406 test_multiframegif();
5411 test_createeffect();
5412 test_getadjustedpalette();
5415 test_GdipLoadImageFromStream();
5417 GdiplusShutdown(gdiplusToken
);