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
, sizeof(bufferW
)/sizeof(bufferW
[0]));
59 WideCharToMultiByte(CP_ACP
, 0, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]), buffer
, sizeof(buffer
), NULL
, NULL
);
60 StringFromGUID2(expected
, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]));
61 WideCharToMultiByte(CP_ACP
, 0, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]), 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 GdipBitmapGetPixel(bm
, 0, 0, &color
);
371 expect(0xffffffff, color
);
373 GdipDisposeImage((GpImage
*)bm
);
376 static void test_LoadingImages(void)
381 static const WCHAR nonexistentW
[] = {'n','o','n','e','x','i','s','t','e','n','t',0};
383 stat
= GdipCreateBitmapFromFile(0, 0);
384 expect(InvalidParameter
, stat
);
386 bm
= (GpBitmap
*)0xdeadbeef;
387 stat
= GdipCreateBitmapFromFile(0, &bm
);
388 expect(InvalidParameter
, stat
);
389 ok(bm
== (GpBitmap
*)0xdeadbeef, "returned %p\n", bm
);
391 bm
= (GpBitmap
*)0xdeadbeef;
392 stat
= GdipCreateBitmapFromFile(nonexistentW
, &bm
);
393 todo_wine
expect(InvalidParameter
, stat
);
394 ok(!bm
, "returned %p\n", bm
);
396 stat
= GdipLoadImageFromFile(0, 0);
397 expect(InvalidParameter
, stat
);
399 img
= (GpImage
*)0xdeadbeef;
400 stat
= GdipLoadImageFromFile(0, &img
);
401 expect(InvalidParameter
, stat
);
402 ok(img
== (GpImage
*)0xdeadbeef, "returned %p\n", img
);
404 img
= (GpImage
*)0xdeadbeef;
405 stat
= GdipLoadImageFromFile(nonexistentW
, &img
);
406 todo_wine
expect(OutOfMemory
, stat
);
407 ok(!img
, "returned %p\n", img
);
409 stat
= GdipLoadImageFromFileICM(0, 0);
410 expect(InvalidParameter
, stat
);
412 img
= (GpImage
*)0xdeadbeef;
413 stat
= GdipLoadImageFromFileICM(0, &img
);
414 expect(InvalidParameter
, stat
);
415 ok(img
== (GpImage
*)0xdeadbeef, "returned %p\n", img
);
417 img
= (GpImage
*)0xdeadbeef;
418 stat
= GdipLoadImageFromFileICM(nonexistentW
, &img
);
419 todo_wine
expect(OutOfMemory
, stat
);
420 ok(!img
, "returned %p\n", img
);
423 static void test_SavingImages(void)
429 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
431 ImageCodecInfo
*codecs
;
432 static const CHAR filenameA
[] = "a.bmp";
433 static const WCHAR filename
[] = { 'a','.','b','m','p',0 };
437 stat
= GdipSaveImageToFile(0, 0, 0, 0);
438 expect(InvalidParameter
, stat
);
441 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
447 stat
= GdipSaveImageToFile((GpImage
*)bm
, 0, 0, 0);
448 expect(InvalidParameter
, stat
);
450 stat
= GdipSaveImageToFile((GpImage
*)bm
, filename
, 0, 0);
451 expect(InvalidParameter
, stat
);
453 /* encoder tests should succeed -- already tested */
454 stat
= GdipGetImageEncodersSize(&n
, &s
);
455 if (stat
!= Ok
|| n
== 0) goto cleanup
;
457 codecs
= GdipAlloc(s
);
458 if (!codecs
) goto cleanup
;
460 stat
= GdipGetImageEncoders(n
, s
, codecs
);
461 if (stat
!= Ok
) goto cleanup
;
463 stat
= GdipSaveImageToFile((GpImage
*)bm
, filename
, &codecs
[0].Clsid
, 0);
466 GdipDisposeImage((GpImage
*)bm
);
469 /* re-load and check image stats */
470 stat
= GdipLoadImageFromFile(filename
, (GpImage
**)&bm
);
472 if (stat
!= Ok
) goto cleanup
;
474 stat
= GdipGetImageDimension((GpImage
*)bm
, &w
, &h
);
475 if (stat
!= Ok
) goto cleanup
;
483 GdipDisposeImage((GpImage
*)bm
);
484 ok(DeleteFileA(filenameA
), "Delete failed.\n");
487 static void test_encoders(void)
492 ImageCodecInfo
*codecs
;
496 static const CHAR bmp_format
[] = "BMP";
498 stat
= GdipGetImageEncodersSize(&n
, &s
);
501 codecs
= GdipAlloc(s
);
505 stat
= GdipGetImageEncoders(n
, s
, NULL
);
506 expect(GenericError
, stat
);
508 stat
= GdipGetImageEncoders(0, s
, codecs
);
509 expect(GenericError
, stat
);
511 stat
= GdipGetImageEncoders(n
, s
-1, codecs
);
512 expect(GenericError
, stat
);
514 stat
= GdipGetImageEncoders(n
, s
+1, codecs
);
515 expect(GenericError
, stat
);
517 stat
= GdipGetImageEncoders(n
, s
, codecs
);
521 for (i
= 0; i
< n
; i
++)
525 WideCharToMultiByte(CP_ACP
, 0, codecs
[i
].FormatDescription
, -1,
528 if (CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0,
530 bmp_format
, -1) == CSTR_EQUAL
) {
536 ok(FALSE
, "No BMP codec found.\n");
541 static void test_LockBits(void)
547 const INT WIDTH
= 10, HEIGHT
= 20;
552 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
560 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffc30000);
563 stat
= GdipBitmapSetPixel(bm
, 2, 8, 0xff480000);
567 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
571 expect(0xc3, ((BYTE
*)bd
.Scan0
)[2]);
572 expect(0x48, ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5]);
574 ((char*)bd
.Scan0
)[2] = 0xff;
576 stat
= GdipBitmapUnlockBits(bm
, &bd
);
580 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
582 expect(0xffff0000, color
);
584 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffc30000);
587 /* read-only, with NULL rect -> whole bitmap lock */
588 stat
= GdipBitmapLockBits(bm
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
590 expect(bd
.Width
, WIDTH
);
591 expect(bd
.Height
, HEIGHT
);
594 ((char*)bd
.Scan0
)[2 + 2*3 + 3*bd
.Stride
] = 0xff;
596 stat
= GdipBitmapUnlockBits(bm
, &bd
);
600 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
602 expect(0xffff0000, color
);
604 /* read-only, consecutive */
605 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
609 stat
= GdipBitmapUnlockBits(bm
, &bd
);
613 stat
= GdipDisposeImage((GpImage
*)bm
);
615 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
619 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
621 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
622 expect(WrongState
, stat
);
624 stat
= GdipBitmapUnlockBits(bm
, &bd
);
627 stat
= GdipDisposeImage((GpImage
*)bm
);
629 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
632 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffff0000);
635 stat
= GdipBitmapSetPixel(bm
, 2, 8, 0xffc30000);
638 /* write, no conversion */
639 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
643 /* all bits are readable, inside the rect or not */
644 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
645 expect(0xc3, ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5]);
647 stat
= GdipBitmapUnlockBits(bm
, &bd
);
651 /* read, conversion */
652 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat32bppARGB
, &bd
);
656 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
658 /* Areas outside the rectangle appear to be uninitialized */
659 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
661 ((BYTE
*)bd
.Scan0
)[2] = 0xc3;
663 stat
= GdipBitmapUnlockBits(bm
, &bd
);
667 /* writes do not work in read mode if there was a conversion */
668 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
670 expect(0xffff0000, color
);
672 /* read/write, conversion */
673 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeWrite
, PixelFormat32bppARGB
, &bd
);
677 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
678 ((BYTE
*)bd
.Scan0
)[1] = 0x88;
680 /* Areas outside the rectangle appear to be uninitialized */
681 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
683 stat
= GdipBitmapUnlockBits(bm
, &bd
);
687 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
689 expect(0xffff8800, color
);
691 /* write, conversion */
692 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat32bppARGB
, &bd
);
698 /* This is completely uninitialized. */
699 ok(0xff != ((BYTE
*)bd
.Scan0
)[2], "original image bits are readable\n");
700 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
703 /* Initialize the buffer so the unlock doesn't access undefined memory */
705 memset(((BYTE
*)bd
.Scan0
) + bd
.Stride
* y
, 0, 12);
707 ((BYTE
*)bd
.Scan0
)[0] = 0x12;
708 ((BYTE
*)bd
.Scan0
)[1] = 0x34;
709 ((BYTE
*)bd
.Scan0
)[2] = 0x56;
711 stat
= GdipBitmapUnlockBits(bm
, &bd
);
715 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
717 expect(0xff563412, color
);
719 stat
= GdipBitmapGetPixel(bm
, 2, 8, &color
);
721 expect(0xffc30000, color
);
723 stat
= GdipDisposeImage((GpImage
*)bm
);
725 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
728 /* write, no modification */
729 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
733 stat
= GdipBitmapUnlockBits(bm
, &bd
);
737 /* write, consecutive */
738 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
742 stat
= GdipBitmapUnlockBits(bm
, &bd
);
746 stat
= GdipDisposeImage((GpImage
*)bm
);
748 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
752 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
757 ((char*)bd
.Scan0
)[2] = 0xff;
759 stat
= GdipBitmapUnlockBits(bm
, &bd
);
763 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
765 expect(0xffff0000, color
);
767 stat
= GdipDisposeImage((GpImage
*)bm
);
771 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
773 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
775 stat
= GdipDisposeImage((GpImage
*)bm
);
779 static void test_LockBits_UserBuf(void)
785 const INT WIDTH
= 10, HEIGHT
= 20;
790 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat32bppARGB
, NULL
, &bm
);
793 memset(bits
, 0xaa, sizeof(bits
));
802 bd
.Stride
= WIDTH
* 4;
803 bd
.PixelFormat
= PixelFormat32bppARGB
;
804 bd
.Scan0
= &bits
[2+3*WIDTH
];
805 bd
.Reserved
= 0xaaaaaaaa;
808 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
811 expect(0xaaaaaaaa, bits
[0]);
812 expect(0, bits
[2+3*WIDTH
]);
814 bits
[2+3*WIDTH
] = 0xdeadbeef;
817 stat
= GdipBitmapUnlockBits(bm
, &bd
);
821 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
826 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
829 expect(0xdeadbeef, bits
[2+3*WIDTH
]);
830 bits
[2+3*WIDTH
] = 0x12345678;
833 stat
= GdipBitmapUnlockBits(bm
, &bd
);
837 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
839 expect(0x12345678, color
);
844 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeWrite
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
847 expect(0x12345678, bits
[2+3*WIDTH
]);
848 bits
[2+3*WIDTH
] = 0xdeadbeef;
851 stat
= GdipBitmapUnlockBits(bm
, &bd
);
855 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
857 expect(0xdeadbeef, color
);
859 stat
= GdipDisposeImage((GpImage
*)bm
);
863 struct BITMAPINFOWITHBITFIELDS
865 BITMAPINFOHEADER bmiHeader
;
869 union BITMAPINFOUNION
872 struct BITMAPINFOWITHBITFIELDS bf
;
875 static void test_GdipCreateBitmapFromHBITMAP(void)
877 GpBitmap
* gpbm
= NULL
;
879 HPALETTE hpal
= NULL
;
882 LOGPALETTE
* LogPal
= NULL
;
884 const REAL WIDTH1
= 5;
885 const REAL HEIGHT1
= 15;
886 const REAL WIDTH2
= 10;
887 const REAL HEIGHT2
= 20;
889 union BITMAPINFOUNION bmi
;
893 stat
= GdipCreateBitmapFromHBITMAP(NULL
, NULL
, NULL
);
894 expect(InvalidParameter
, stat
);
896 hbm
= CreateBitmap(WIDTH1
, HEIGHT1
, 1, 1, NULL
);
897 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, NULL
);
898 expect(InvalidParameter
, stat
);
900 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
902 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
903 expectf(WIDTH1
, width
);
904 expectf(HEIGHT1
, height
);
906 GdipDisposeImage((GpImage
*)gpbm
);
909 memset(buff
, 0, sizeof(buff
));
910 hbm
= CreateBitmap(WIDTH2
, HEIGHT2
, 1, 1, &buff
);
911 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
914 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)gpbm
, __LINE__
, FALSE
);
916 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
917 expectf(WIDTH2
, width
);
918 expectf(HEIGHT2
, height
);
920 GdipDisposeImage((GpImage
*)gpbm
);
923 hdc
= CreateCompatibleDC(0);
924 ok(hdc
!= NULL
, "CreateCompatibleDC failed\n");
925 bmi
.bi
.bmiHeader
.biSize
= sizeof(bmi
.bi
.bmiHeader
);
926 bmi
.bi
.bmiHeader
.biHeight
= HEIGHT1
;
927 bmi
.bi
.bmiHeader
.biWidth
= WIDTH1
;
928 bmi
.bi
.bmiHeader
.biBitCount
= 24;
929 bmi
.bi
.bmiHeader
.biPlanes
= 1;
930 bmi
.bi
.bmiHeader
.biCompression
= BI_RGB
;
931 bmi
.bi
.bmiHeader
.biClrUsed
= 0;
933 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
934 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
938 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
940 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
941 expectf(WIDTH1
, width
);
942 expectf(HEIGHT1
, height
);
945 /* test whether writing to the bitmap affects the original */
946 stat
= GdipBitmapSetPixel(gpbm
, 0, 0, 0xffffffff);
951 GdipDisposeImage((GpImage
*)gpbm
);
954 LogPal
= GdipAlloc(sizeof(LOGPALETTE
));
955 ok(LogPal
!= NULL
, "unable to allocate LOGPALETTE\n");
956 LogPal
->palVersion
= 0x300;
957 LogPal
->palNumEntries
= 1;
958 hpal
= CreatePalette(LogPal
);
959 ok(hpal
!= NULL
, "CreatePalette failed\n");
962 stat
= GdipCreateBitmapFromHBITMAP(hbm
, hpal
, &gpbm
);
966 GdipDisposeImage((GpImage
*)gpbm
);
971 /* 16-bit 555 dib, rgb */
972 bmi
.bi
.bmiHeader
.biBitCount
= 16;
973 bmi
.bi
.bmiHeader
.biCompression
= BI_RGB
;
975 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
976 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
980 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
985 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
987 expectf(WIDTH1
, width
);
988 expectf(HEIGHT1
, height
);
990 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
992 expect(PixelFormat16bppRGB555
, format
);
994 GdipDisposeImage((GpImage
*)gpbm
);
998 /* 16-bit 555 dib, with bitfields */
999 bmi
.bi
.bmiHeader
.biSize
= sizeof(bmi
);
1000 bmi
.bi
.bmiHeader
.biCompression
= BI_BITFIELDS
;
1001 bmi
.bf
.masks
[0] = 0x7c00;
1002 bmi
.bf
.masks
[1] = 0x3e0;
1003 bmi
.bf
.masks
[2] = 0x1f;
1005 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1006 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1010 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1015 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1017 expectf(WIDTH1
, width
);
1018 expectf(HEIGHT1
, height
);
1020 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1022 expect(PixelFormat16bppRGB555
, format
);
1024 GdipDisposeImage((GpImage
*)gpbm
);
1028 /* 16-bit 565 dib, with bitfields */
1029 bmi
.bf
.masks
[0] = 0xf800;
1030 bmi
.bf
.masks
[1] = 0x7e0;
1031 bmi
.bf
.masks
[2] = 0x1f;
1033 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1034 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1038 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1043 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1045 expectf(WIDTH1
, width
);
1046 expectf(HEIGHT1
, height
);
1048 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1050 expect(PixelFormat16bppRGB565
, format
);
1052 GdipDisposeImage((GpImage
*)gpbm
);
1059 static void test_GdipGetImageFlags(void)
1065 img
= (GpImage
*)0xdeadbeef;
1067 stat
= GdipGetImageFlags(NULL
, NULL
);
1068 expect(InvalidParameter
, stat
);
1070 stat
= GdipGetImageFlags(NULL
, &flags
);
1071 expect(InvalidParameter
, stat
);
1073 stat
= GdipGetImageFlags(img
, NULL
);
1074 expect(InvalidParameter
, stat
);
1076 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat1bppIndexed
, NULL
, (GpBitmap
**)&img
);
1078 stat
= GdipGetImageFlags(img
, &flags
);
1080 expect(ImageFlagsHasAlpha
, flags
);
1081 GdipDisposeImage(img
);
1083 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat4bppIndexed
, NULL
, (GpBitmap
**)&img
);
1085 stat
= GdipGetImageFlags(img
, &flags
);
1087 expect(ImageFlagsHasAlpha
, flags
);
1088 GdipDisposeImage(img
);
1090 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat8bppIndexed
, NULL
, (GpBitmap
**)&img
);
1092 stat
= GdipGetImageFlags(img
, &flags
);
1094 expect(ImageFlagsHasAlpha
, flags
);
1095 GdipDisposeImage(img
);
1097 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppGrayScale
, NULL
, (GpBitmap
**)&img
);
1099 stat
= GdipGetImageFlags(img
, &flags
);
1101 expect(ImageFlagsNone
, flags
);
1102 GdipDisposeImage(img
);
1104 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB555
, NULL
, (GpBitmap
**)&img
);
1106 stat
= GdipGetImageFlags(img
, &flags
);
1108 expect(ImageFlagsNone
, flags
);
1109 GdipDisposeImage(img
);
1111 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB565
, NULL
, (GpBitmap
**)&img
);
1113 stat
= GdipGetImageFlags(img
, &flags
);
1115 expect(ImageFlagsNone
, flags
);
1116 GdipDisposeImage(img
);
1118 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppARGB1555
, NULL
, (GpBitmap
**)&img
);
1120 stat
= GdipGetImageFlags(img
, &flags
);
1122 expect(ImageFlagsHasAlpha
, flags
);
1123 GdipDisposeImage(img
);
1125 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, NULL
, (GpBitmap
**)&img
);
1127 stat
= GdipGetImageFlags(img
, &flags
);
1129 expect(ImageFlagsNone
, flags
);
1130 GdipDisposeImage(img
);
1132 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&img
);
1134 stat
= GdipGetImageFlags(img
, &flags
);
1136 expect(ImageFlagsNone
, flags
);
1137 GdipDisposeImage(img
);
1139 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppARGB
, NULL
, (GpBitmap
**)&img
);
1141 stat
= GdipGetImageFlags(img
, &flags
);
1143 expect(ImageFlagsHasAlpha
, flags
);
1144 GdipDisposeImage(img
);
1146 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppPARGB
, NULL
, (GpBitmap
**)&img
);
1148 stat
= GdipGetImageFlags(img
, &flags
);
1150 expect(ImageFlagsHasAlpha
, flags
);
1151 GdipDisposeImage(img
);
1153 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat48bppRGB
, NULL
, (GpBitmap
**)&img
);
1157 stat
= GdipGetImageFlags(img
, &flags
);
1159 expect(ImageFlagsNone
, flags
);
1160 GdipDisposeImage(img
);
1163 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB
, NULL
, (GpBitmap
**)&img
);
1168 stat
= GdipGetImageFlags(img
, &flags
);
1170 expect(ImageFlagsHasAlpha
, flags
);
1171 GdipDisposeImage(img
);
1174 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB
, NULL
, (GpBitmap
**)&img
);
1179 stat
= GdipGetImageFlags(img
, &flags
);
1181 expect(ImageFlagsHasAlpha
, flags
);
1182 GdipDisposeImage(img
);
1186 static void test_GdipCloneImage(void)
1192 GpImage
*image_src
, *image_dest
= NULL
;
1193 const INT WIDTH
= 10, HEIGHT
= 20;
1195 /* Create an image, clone it, delete the original, make sure the copy works */
1196 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
1198 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bm
, __LINE__
, FALSE
);
1200 image_src
= ((GpImage
*)bm
);
1201 stat
= GdipCloneImage(image_src
, &image_dest
);
1203 expect_rawformat(&ImageFormatMemoryBMP
, image_dest
, __LINE__
, FALSE
);
1205 stat
= GdipDisposeImage((GpImage
*)bm
);
1207 stat
= GdipGetImageBounds(image_dest
, &rectF
, &unit
);
1210 /* Treat FP values carefully */
1211 expectf((REAL
)WIDTH
, rectF
.Width
);
1212 expectf((REAL
)HEIGHT
, rectF
.Height
);
1214 stat
= GdipDisposeImage(image_dest
);
1218 static void test_testcontrol(void)
1224 stat
= GdipTestControl(TestControlGetBuildNumber
, ¶m
);
1226 ok(param
!= 0, "Build number expected, got %u\n", param
);
1229 static void test_fromhicon(void)
1231 static const BYTE bmp_bits
[1024];
1232 HBITMAP hbmMask
, hbmColor
;
1236 GpBitmap
*bitmap
= NULL
;
1242 stat
= GdipCreateBitmapFromHICON(NULL
, NULL
);
1243 expect(InvalidParameter
, stat
);
1244 stat
= GdipCreateBitmapFromHICON(NULL
, &bitmap
);
1245 expect(InvalidParameter
, stat
);
1247 /* color icon 1 bit */
1248 hbmMask
= CreateBitmap(16, 16, 1, 1, bmp_bits
);
1249 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1250 hbmColor
= CreateBitmap(16, 16, 1, 1, bmp_bits
);
1251 ok(hbmColor
!= 0, "CreateBitmap failed\n");
1255 info
.hbmMask
= hbmMask
;
1256 info
.hbmColor
= hbmColor
;
1257 hIcon
= CreateIconIndirect(&info
);
1258 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
1259 DeleteObject(hbmMask
);
1260 DeleteObject(hbmColor
);
1262 stat
= GdipCreateBitmapFromHICON(hIcon
, &bitmap
);
1264 broken(stat
== InvalidParameter
), /* Win98 */
1265 "Expected Ok, got %.8x\n", stat
);
1267 /* check attributes */
1268 stat
= GdipGetImageHeight((GpImage
*)bitmap
, &dim
);
1271 stat
= GdipGetImageWidth((GpImage
*)bitmap
, &dim
);
1274 stat
= GdipGetImageType((GpImage
*)bitmap
, &type
);
1276 expect(ImageTypeBitmap
, type
);
1277 stat
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
1279 expect(PixelFormat32bppARGB
, format
);
1281 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bitmap
, __LINE__
, FALSE
);
1282 GdipDisposeImage((GpImage
*)bitmap
);
1286 /* color icon 8 bpp */
1287 hbmMask
= CreateBitmap(16, 16, 1, 8, bmp_bits
);
1288 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1289 hbmColor
= CreateBitmap(16, 16, 1, 8, bmp_bits
);
1290 ok(hbmColor
!= 0, "CreateBitmap failed\n");
1294 info
.hbmMask
= hbmMask
;
1295 info
.hbmColor
= hbmColor
;
1296 hIcon
= CreateIconIndirect(&info
);
1297 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
1298 DeleteObject(hbmMask
);
1299 DeleteObject(hbmColor
);
1301 stat
= GdipCreateBitmapFromHICON(hIcon
, &bitmap
);
1304 /* check attributes */
1305 stat
= GdipGetImageHeight((GpImage
*)bitmap
, &dim
);
1308 stat
= GdipGetImageWidth((GpImage
*)bitmap
, &dim
);
1311 stat
= GdipGetImageType((GpImage
*)bitmap
, &type
);
1313 expect(ImageTypeBitmap
, type
);
1314 stat
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
1316 expect(PixelFormat32bppARGB
, format
);
1318 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bitmap
, __LINE__
, FALSE
);
1319 GdipDisposeImage((GpImage
*)bitmap
);
1325 static const unsigned char pngimage
[285] = {
1326 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
1327 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
1328 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
1329 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
1330 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
1331 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
1332 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
1335 static const unsigned char gifimage
[35] = {
1336 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
1337 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
1340 /* 1x1 pixel transparent gif */
1341 static const unsigned char transparentgif
[] = {
1342 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,
1343 0x00,0x00,0x00,0x21,0xf9,0x04,0x01,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,
1344 0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
1347 static const unsigned char bmpimage
[66] = {
1348 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
1349 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
1350 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
1351 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
1355 static const unsigned char jpgimage
[285] = {
1356 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
1357 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
1358 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
1359 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
1360 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
1361 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
1362 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
1363 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,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,0xff,0xc0,
1366 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
1367 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1368 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
1369 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
1370 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1371 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
1372 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
1373 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
1375 /* 1x1 pixel tiff */
1376 static const unsigned char tiffimage
[] = {
1377 0x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00,
1378 0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00,
1379 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1380 0x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01,
1381 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00,
1382 0x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00,
1383 0x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01,
1384 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00,
1385 0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00,
1386 0x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01,
1387 0x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00,
1388 0x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1389 0x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
1390 0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65,
1391 0x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74,
1392 0x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,
1395 /* 320x320 twip wmf */
1396 static const unsigned char wmfimage
[180] = {
1397 0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05,
1398 0x00,0x00,0x00,0x00,0xb1,0x52,0x01,0x00,0x09,0x00,0x00,0x03,0x4f,0x00,0x00,0x00,
1399 0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0b,0x02,0x00,0x00,
1400 0x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x02,0x40,0x01,0x40,0x01,0x04,0x00,0x00,0x00,
1401 0x02,0x01,0x01,0x00,0x04,0x00,0x00,0x00,0x04,0x01,0x0d,0x00,0x08,0x00,0x00,0x00,
1402 0xfa,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
1403 0x2d,0x01,0x00,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,0x01,0x00,0x00,0x00,0x00,0x00,
1404 0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x01,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,
1405 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x02,0x00,
1406 0x07,0x00,0x00,0x00,0x1b,0x04,0x40,0x01,0x40,0x01,0x00,0x00,0x00,0x00,0x04,0x00,
1407 0x00,0x00,0xf0,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0xf0,0x01,0x01,0x00,0x03,0x00,
1410 static void test_getrawformat(void)
1412 test_bufferrawformat((void*)pngimage
, sizeof(pngimage
), &ImageFormatPNG
, __LINE__
, FALSE
);
1413 test_bufferrawformat((void*)gifimage
, sizeof(gifimage
), &ImageFormatGIF
, __LINE__
, FALSE
);
1414 test_bufferrawformat((void*)bmpimage
, sizeof(bmpimage
), &ImageFormatBMP
, __LINE__
, FALSE
);
1415 test_bufferrawformat((void*)jpgimage
, sizeof(jpgimage
), &ImageFormatJPEG
, __LINE__
, FALSE
);
1416 test_bufferrawformat((void*)tiffimage
, sizeof(tiffimage
), &ImageFormatTIFF
, __LINE__
, FALSE
);
1417 test_bufferrawformat((void*)wmfimage
, sizeof(wmfimage
), &ImageFormatWMF
, __LINE__
, FALSE
);
1420 static void test_loadwmf(void)
1431 MetafileHeader header
;
1433 hglob
= GlobalAlloc (0, sizeof(wmfimage
));
1434 data
= GlobalLock (hglob
);
1435 memcpy(data
, wmfimage
, sizeof(wmfimage
));
1436 GlobalUnlock(hglob
); data
= NULL
;
1438 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
1439 ok(hres
== S_OK
, "Failed to create a stream\n");
1440 if(hres
!= S_OK
) return;
1442 stat
= GdipLoadImageFromStream(stream
, &img
);
1443 ok(stat
== Ok
, "Failed to create a Bitmap\n");
1445 IStream_Release(stream
);
1449 IStream_Release(stream
);
1451 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1453 expect(UnitPixel
, unit
);
1454 expectf(0.0, bounds
.X
);
1455 expectf(0.0, bounds
.Y
);
1456 expectf(320.0, bounds
.Width
);
1457 expectf(320.0, bounds
.Height
);
1459 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1461 expectf(1440.0, res
);
1463 stat
= GdipGetImageVerticalResolution(img
, &res
);
1465 expectf(1440.0, res
);
1467 memset(&header
, 0, sizeof(header
));
1468 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1472 expect(MetafileTypeWmfPlaceable
, header
.Type
);
1473 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1474 todo_wine
expect(0x300, header
.Version
);
1475 expect(0, header
.EmfPlusFlags
);
1476 expectf(1440.0, header
.DpiX
);
1477 expectf(1440.0, header
.DpiY
);
1478 expect(0, header
.X
);
1479 expect(0, header
.Y
);
1480 expect(320, header
.Width
);
1481 expect(320, header
.Height
);
1482 expect(1, U(header
).WmfHeader
.mtType
);
1483 expect(0, header
.EmfPlusHeaderSize
);
1484 expect(0, header
.LogicalDpiX
);
1485 expect(0, header
.LogicalDpiY
);
1488 GdipDisposeImage(img
);
1491 static void test_createfromwmf(void)
1499 MetafileHeader header
;
1501 hwmf
= SetMetaFileBitsEx(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
),
1502 wmfimage
+sizeof(WmfPlaceableFileHeader
));
1503 ok(hwmf
!= 0, "SetMetaFileBitsEx failed\n");
1505 stat
= GdipCreateMetafileFromWmf(hwmf
, TRUE
,
1506 (WmfPlaceableFileHeader
*)wmfimage
, (GpMetafile
**)&img
);
1509 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1511 expect(UnitPixel
, unit
);
1512 expectf(0.0, bounds
.X
);
1513 expectf(0.0, bounds
.Y
);
1514 expectf(320.0, bounds
.Width
);
1515 expectf(320.0, bounds
.Height
);
1517 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1519 expectf(1440.0, res
);
1521 stat
= GdipGetImageVerticalResolution(img
, &res
);
1523 expectf(1440.0, res
);
1525 memset(&header
, 0, sizeof(header
));
1526 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1530 expect(MetafileTypeWmfPlaceable
, header
.Type
);
1531 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1532 todo_wine
expect(0x300, header
.Version
);
1533 expect(0, header
.EmfPlusFlags
);
1534 expectf(1440.0, header
.DpiX
);
1535 expectf(1440.0, header
.DpiY
);
1536 expect(0, header
.X
);
1537 expect(0, header
.Y
);
1538 expect(320, header
.Width
);
1539 expect(320, header
.Height
);
1540 expect(1, U(header
).WmfHeader
.mtType
);
1541 expect(0, header
.EmfPlusHeaderSize
);
1542 expect(0, header
.LogicalDpiX
);
1543 expect(0, header
.LogicalDpiY
);
1546 GdipDisposeImage(img
);
1549 static void test_createfromwmf_noplaceable(void)
1555 hwmf
= SetMetaFileBitsEx(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
),
1556 wmfimage
+sizeof(WmfPlaceableFileHeader
));
1557 ok(hwmf
!= 0, "SetMetaFileBitsEx failed\n");
1559 stat
= GdipCreateMetafileFromWmf(hwmf
, TRUE
, NULL
, (GpMetafile
**)&img
);
1562 GdipDisposeImage(img
);
1565 static void test_resolution(void)
1569 GpGraphics
*graphics
;
1572 int screenxres
, screenyres
;
1575 stat
= GdipCreateBitmapFromScan0(1, 1, 32, PixelFormat24bppRGB
, NULL
, &bitmap
);
1578 /* test invalid values */
1579 stat
= GdipGetImageHorizontalResolution(NULL
, &res
);
1580 expect(InvalidParameter
, stat
);
1582 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, NULL
);
1583 expect(InvalidParameter
, stat
);
1585 stat
= GdipGetImageVerticalResolution(NULL
, &res
);
1586 expect(InvalidParameter
, stat
);
1588 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, NULL
);
1589 expect(InvalidParameter
, stat
);
1591 stat
= GdipBitmapSetResolution(NULL
, 96.0, 96.0);
1592 expect(InvalidParameter
, stat
);
1594 stat
= GdipBitmapSetResolution(bitmap
, 0.0, 0.0);
1595 expect(InvalidParameter
, stat
);
1597 /* defaults to screen resolution */
1598 screendc
= GetDC(0);
1600 screenxres
= GetDeviceCaps(screendc
, LOGPIXELSX
);
1601 screenyres
= GetDeviceCaps(screendc
, LOGPIXELSY
);
1603 ReleaseDC(0, screendc
);
1605 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1607 expectf((REAL
)screenxres
, res
);
1609 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1611 expectf((REAL
)screenyres
, res
);
1613 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1615 stat
= GdipGetDpiX(graphics
, &res
);
1617 expectf((REAL
)screenxres
, res
);
1618 stat
= GdipGetDpiY(graphics
, &res
);
1620 expectf((REAL
)screenyres
, res
);
1622 /* test changing the resolution */
1623 stat
= GdipBitmapSetResolution(bitmap
, screenxres
*2.0, screenyres
*3.0);
1626 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1628 expectf(screenxres
*2.0, res
);
1630 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1632 expectf(screenyres
*3.0, res
);
1634 stat
= GdipGetDpiX(graphics
, &res
);
1636 expectf((REAL
)screenxres
, res
);
1637 stat
= GdipGetDpiY(graphics
, &res
);
1639 expectf((REAL
)screenyres
, res
);
1641 stat
= GdipDeleteGraphics(graphics
);
1644 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1646 stat
= GdipGetDpiX(graphics
, &res
);
1648 expectf(screenxres
*2.0, res
);
1649 stat
= GdipGetDpiY(graphics
, &res
);
1651 expectf(screenyres
*3.0, res
);
1652 stat
= GdipDeleteGraphics(graphics
);
1655 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1659 static void test_createhbitmap(void)
1663 HBITMAP hbitmap
, oldhbitmap
;
1669 BitmapData lockeddata
;
1671 memset(bits
, 0x68, 640);
1674 stat
= GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB
, bits
, &bitmap
);
1677 /* test NULL values */
1678 stat
= GdipCreateHBITMAPFromBitmap(NULL
, &hbitmap
, 0);
1679 expect(InvalidParameter
, stat
);
1681 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, NULL
, 0);
1682 expect(InvalidParameter
, stat
);
1684 /* create HBITMAP */
1685 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1690 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1691 expect(sizeof(BITMAP
), ret
);
1693 expect(0, bm
.bmType
);
1694 expect(10, bm
.bmWidth
);
1695 expect(20, bm
.bmHeight
);
1696 expect(40, bm
.bmWidthBytes
);
1697 expect(1, bm
.bmPlanes
);
1698 expect(32, bm
.bmBitsPixel
);
1699 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1703 DWORD val
= *(DWORD
*)bm
.bmBits
;
1704 ok(val
== 0xff686868, "got %x, expected 0xff686868\n", val
);
1707 hdc
= CreateCompatibleDC(NULL
);
1709 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1710 pixel
= GetPixel(hdc
, 5, 5);
1711 SelectObject(hdc
, oldhbitmap
);
1715 expect(0x686868, pixel
);
1717 DeleteObject(hbitmap
);
1720 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1723 /* make (1,0) have no alpha and (2,0) a different blue value. */
1727 /* create alpha Bitmap */
1728 stat
= GdipCreateBitmapFromScan0(8, 20, 32, PixelFormat32bppARGB
, bits
, &bitmap
);
1731 /* create HBITMAP */
1732 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1737 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1738 expect(sizeof(BITMAP
), ret
);
1740 expect(0, bm
.bmType
);
1741 expect(8, bm
.bmWidth
);
1742 expect(20, bm
.bmHeight
);
1743 expect(32, bm
.bmWidthBytes
);
1744 expect(1, bm
.bmPlanes
);
1745 expect(32, bm
.bmBitsPixel
);
1746 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1750 DWORD val
= *(DWORD
*)bm
.bmBits
;
1751 ok(val
== 0x682a2a2a, "got %x, expected 0x682a2a2a\n", val
);
1752 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1753 ok(val
== 0x0, "got %x, expected 0x682a2a2a\n", val
);
1756 hdc
= CreateCompatibleDC(NULL
);
1758 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1759 pixel
= GetPixel(hdc
, 5, 5);
1760 expect(0x2a2a2a, pixel
);
1761 pixel
= GetPixel(hdc
, 1, 0);
1764 SelectObject(hdc
, oldhbitmap
);
1769 DeleteObject(hbitmap
);
1772 /* create HBITMAP with bkgnd colour */
1773 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0xff00ff);
1778 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1779 expect(sizeof(BITMAP
), ret
);
1781 expect(0, bm
.bmType
);
1782 expect(8, bm
.bmWidth
);
1783 expect(20, bm
.bmHeight
);
1784 expect(32, bm
.bmWidthBytes
);
1785 expect(1, bm
.bmPlanes
);
1786 expect(32, bm
.bmBitsPixel
);
1787 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1791 DWORD val
= *(DWORD
*)bm
.bmBits
;
1792 ok(val
== 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val
);
1793 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1794 ok(val
== 0xff00ff, "got %x, expected 0x682a2a2a\n", val
);
1797 hdc
= CreateCompatibleDC(NULL
);
1799 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1800 pixel
= GetPixel(hdc
, 5, 5);
1801 expect(0xc12ac1, pixel
);
1802 pixel
= GetPixel(hdc
, 1, 0);
1803 expect(0xff00ff, pixel
);
1804 pixel
= GetPixel(hdc
, 2, 0);
1805 expect(0xb12ac1, pixel
);
1807 SelectObject(hdc
, oldhbitmap
);
1809 DeleteObject(hbitmap
);
1812 /* create HBITMAP with bkgnd colour with alpha and show it behaves with no alpha. */
1813 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0x80ff00ff);
1818 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1819 expect(sizeof(BITMAP
), ret
);
1821 expect(0, bm
.bmType
);
1822 expect(8, bm
.bmWidth
);
1823 expect(20, bm
.bmHeight
);
1824 expect(32, bm
.bmWidthBytes
);
1825 expect(1, bm
.bmPlanes
);
1826 expect(32, bm
.bmBitsPixel
);
1827 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1831 DWORD val
= *(DWORD
*)bm
.bmBits
;
1832 ok(val
== 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val
);
1833 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1834 ok(val
== 0xff00ff, "got %x, expected 0x682a2a2a\n", val
);
1837 hdc
= CreateCompatibleDC(NULL
);
1839 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1840 pixel
= GetPixel(hdc
, 5, 5);
1841 expect(0xc12ac1, pixel
);
1842 pixel
= GetPixel(hdc
, 1, 0);
1843 expect(0xff00ff, pixel
);
1844 pixel
= GetPixel(hdc
, 2, 0);
1845 expect(0xb12ac1, pixel
);
1847 SelectObject(hdc
, oldhbitmap
);
1849 DeleteObject(hbitmap
);
1852 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1855 /* create HBITMAP from locked data */
1856 memset(bits
, 0x68, 640);
1857 stat
= GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB
, bits
, &bitmap
);
1860 memset(&lockeddata
, 0, sizeof(lockeddata
));
1861 stat
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
| ImageLockModeWrite
,
1862 PixelFormat32bppRGB
, &lockeddata
);
1864 ((DWORD
*)lockeddata
.Scan0
)[0] = 0xff242424;
1865 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1867 stat
= GdipBitmapUnlockBits(bitmap
, &lockeddata
);
1869 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1872 hdc
= CreateCompatibleDC(NULL
);
1873 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1874 pixel
= GetPixel(hdc
, 0, 0);
1875 expect(0x686868, pixel
);
1876 SelectObject(hdc
, oldhbitmap
);
1880 static void test_getthumbnail(void)
1883 GpImage
*bitmap1
, *bitmap2
;
1886 stat
= GdipGetImageThumbnail(NULL
, 0, 0, &bitmap2
, NULL
, NULL
);
1887 expect(InvalidParameter
, stat
);
1889 stat
= GdipCreateBitmapFromScan0(128, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1892 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, NULL
, NULL
, NULL
);
1893 expect(InvalidParameter
, stat
);
1895 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, &bitmap2
, NULL
, NULL
);
1900 stat
= GdipGetImageWidth(bitmap2
, &width
);
1904 stat
= GdipGetImageHeight(bitmap2
, &height
);
1906 expect(120, height
);
1908 GdipDisposeImage(bitmap2
);
1911 GdipDisposeImage(bitmap1
);
1914 stat
= GdipCreateBitmapFromScan0(64, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1917 stat
= GdipGetImageThumbnail(bitmap1
, 32, 32, &bitmap2
, NULL
, NULL
);
1922 stat
= GdipGetImageWidth(bitmap2
, &width
);
1926 stat
= GdipGetImageHeight(bitmap2
, &height
);
1930 GdipDisposeImage(bitmap2
);
1933 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, &bitmap2
, NULL
, NULL
);
1938 stat
= GdipGetImageWidth(bitmap2
, &width
);
1942 stat
= GdipGetImageHeight(bitmap2
, &height
);
1944 expect(120, height
);
1946 GdipDisposeImage(bitmap2
);
1949 GdipDisposeImage(bitmap1
);
1952 static void test_getsetpixel(void)
1957 BYTE bits
[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00,
1958 0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00};
1960 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, bits
, &bitmap
);
1963 /* null parameters */
1964 stat
= GdipBitmapGetPixel(NULL
, 1, 1, &color
);
1965 expect(InvalidParameter
, stat
);
1967 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, NULL
);
1968 expect(InvalidParameter
, stat
);
1970 stat
= GdipBitmapSetPixel(NULL
, 1, 1, 0);
1971 expect(InvalidParameter
, stat
);
1974 stat
= GdipBitmapGetPixel(bitmap
, -1, 1, &color
);
1975 expect(InvalidParameter
, stat
);
1977 stat
= GdipBitmapSetPixel(bitmap
, -1, 1, 0);
1978 expect(InvalidParameter
, stat
);
1980 stat
= GdipBitmapGetPixel(bitmap
, 1, -1, &color
);
1981 ok(stat
== InvalidParameter
||
1982 broken(stat
== Ok
), /* Older gdiplus */
1983 "Expected InvalidParameter, got %.8x\n", stat
);
1985 if (0) /* crashes some gdiplus implementations */
1987 stat
= GdipBitmapSetPixel(bitmap
, 1, -1, 0);
1988 ok(stat
== InvalidParameter
||
1989 broken(stat
== Ok
), /* Older gdiplus */
1990 "Expected InvalidParameter, got %.8x\n", stat
);
1993 stat
= GdipBitmapGetPixel(bitmap
, 2, 1, &color
);
1994 expect(InvalidParameter
, stat
);
1996 stat
= GdipBitmapSetPixel(bitmap
, 2, 1, 0);
1997 expect(InvalidParameter
, stat
);
1999 stat
= GdipBitmapGetPixel(bitmap
, 1, 2, &color
);
2000 expect(InvalidParameter
, stat
);
2002 stat
= GdipBitmapSetPixel(bitmap
, 1, 2, 0);
2003 expect(InvalidParameter
, stat
);
2006 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
2008 expect(0xffffffff, color
);
2010 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2012 expect(0xff0000ff, color
);
2014 stat
= GdipBitmapSetPixel(bitmap
, 1, 1, 0xff676869);
2017 stat
= GdipBitmapSetPixel(bitmap
, 0, 0, 0xff474849);
2020 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
2022 expect(0xff676869, color
);
2024 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2026 expect(0xff474849, color
);
2028 stat
= GdipDisposeImage((GpImage
*)bitmap
);
2032 static void check_halftone_palette(ColorPalette
*palette
)
2034 static const BYTE halftone_values
[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
2037 for (i
=0; i
<palette
->Count
; i
++)
2039 ARGB expected
=0xff000000;
2042 if (i
&1) expected
|= 0x800000;
2043 if (i
&2) expected
|= 0x8000;
2044 if (i
&4) expected
|= 0x80;
2048 expected
= 0xffc0c0c0;
2052 if (i
&1) expected
|= 0xff0000;
2053 if (i
&2) expected
|= 0xff00;
2054 if (i
&4) expected
|= 0xff;
2058 expected
= 0x00000000;
2062 expected
|= halftone_values
[(i
-40)%6];
2063 expected
|= halftone_values
[((i
-40)/6)%6] << 8;
2064 expected
|= halftone_values
[((i
-40)/36)%6] << 16;
2066 ok(expected
== palette
->Entries
[i
], "Expected %.8x, got %.8x, i=%u/%u\n",
2067 expected
, palette
->Entries
[i
], i
, palette
->Count
);
2071 static void test_palette(void)
2077 ColorPalette
*palette
=(ColorPalette
*)buffer
;
2078 ARGB
*entries
= palette
->Entries
;
2081 /* test initial palette from non-indexed bitmap */
2082 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, NULL
, &bitmap
);
2085 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2087 expect(sizeof(UINT
)*2+sizeof(ARGB
), size
);
2089 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2091 expect(0, palette
->Count
);
2093 /* test setting palette on not-indexed bitmap */
2096 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2099 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2101 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2103 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2105 expect(3, palette
->Count
);
2107 GdipDisposeImage((GpImage
*)bitmap
);
2109 /* test initial palette on 1-bit bitmap */
2110 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat1bppIndexed
, NULL
, &bitmap
);
2113 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2115 expect(sizeof(UINT
)*2+sizeof(ARGB
)*2, size
);
2117 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2119 expect(PaletteFlagsGrayScale
, palette
->Flags
);
2120 expect(2, palette
->Count
);
2122 expect(0xff000000, entries
[0]);
2123 expect(0xffffffff, entries
[1]);
2125 /* test getting/setting pixels */
2126 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2128 expect(0xff000000, color
);
2130 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffffffff);
2132 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2136 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2138 expect(0xffffffff, color
);
2141 GdipDisposeImage((GpImage
*)bitmap
);
2143 /* test initial palette on 4-bit bitmap */
2144 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat4bppIndexed
, NULL
, &bitmap
);
2147 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2149 expect(sizeof(UINT
)*2+sizeof(ARGB
)*16, size
);
2151 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2153 expect(0, palette
->Flags
);
2154 expect(16, palette
->Count
);
2156 check_halftone_palette(palette
);
2158 /* test getting/setting pixels */
2159 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2161 expect(0xff000000, color
);
2163 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffff00ff);
2165 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2169 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2171 expect(0xffff00ff, color
);
2174 GdipDisposeImage((GpImage
*)bitmap
);
2176 /* test initial palette on 8-bit bitmap */
2177 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat8bppIndexed
, NULL
, &bitmap
);
2180 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2182 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2184 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2186 expect(PaletteFlagsHalftone
, palette
->Flags
);
2187 expect(256, palette
->Count
);
2189 check_halftone_palette(palette
);
2191 /* test getting/setting pixels */
2192 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2194 expect(0xff000000, color
);
2196 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffcccccc);
2198 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2202 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2204 expect(0xffcccccc, color
);
2207 /* test setting/getting a different palette */
2208 entries
[1] = 0xffcccccc;
2210 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2215 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2217 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2219 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2221 expect(PaletteFlagsHalftone
, palette
->Flags
);
2222 expect(256, palette
->Count
);
2223 expect(0xffcccccc, entries
[1]);
2225 /* test count < 256 */
2226 palette
->Flags
= 12345;
2229 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2233 entries
[3] = 0xdeadbeef;
2235 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2237 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2239 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2241 expect(12345, palette
->Flags
);
2242 expect(3, palette
->Count
);
2243 expect(0xffcccccc, entries
[1]);
2244 expect(0xdeadbeef, entries
[3]);
2246 /* test count > 256 */
2247 palette
->Count
= 257;
2249 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2250 ok(stat
== InvalidParameter
||
2251 broken(stat
== Ok
), /* Old gdiplus behavior */
2252 "Expected %.8x, got %.8x\n", InvalidParameter
, stat
);
2254 GdipDisposeImage((GpImage
*)bitmap
);
2257 static void test_colormatrix(void)
2260 ColorMatrix colormatrix
, graymatrix
;
2261 GpImageAttributes
*imageattr
;
2262 const ColorMatrix identity
= {{
2263 {1.0,0.0,0.0,0.0,0.0},
2264 {0.0,1.0,0.0,0.0,0.0},
2265 {0.0,0.0,1.0,0.0,0.0},
2266 {0.0,0.0,0.0,1.0,0.0},
2267 {0.0,0.0,0.0,0.0,1.0}}};
2268 const ColorMatrix double_red
= {{
2269 {2.0,0.0,0.0,0.0,0.0},
2270 {0.0,1.0,0.0,0.0,0.0},
2271 {0.0,0.0,1.0,0.0,0.0},
2272 {0.0,0.0,0.0,1.0,0.0},
2273 {0.0,0.0,0.0,0.0,1.0}}};
2274 const ColorMatrix asymmetric
= {{
2275 {0.0,1.0,0.0,0.0,0.0},
2276 {0.0,0.0,1.0,0.0,0.0},
2277 {0.0,0.0,0.0,1.0,0.0},
2278 {1.0,0.0,0.0,0.0,0.0},
2279 {0.0,0.0,0.0,0.0,1.0}}};
2280 GpBitmap
*bitmap1
, *bitmap2
;
2281 GpGraphics
*graphics
;
2284 colormatrix
= identity
;
2285 graymatrix
= identity
;
2287 stat
= GdipSetImageAttributesColorMatrix(NULL
, ColorAdjustTypeDefault
,
2288 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2289 expect(InvalidParameter
, stat
);
2291 stat
= GdipCreateImageAttributes(&imageattr
);
2294 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2295 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2298 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2299 TRUE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2300 expect(InvalidParameter
, stat
);
2302 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2303 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2306 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2307 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsSkipGrays
);
2310 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2311 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsAltGray
);
2312 expect(InvalidParameter
, stat
);
2314 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2315 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsAltGray
);
2318 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2319 TRUE
, &colormatrix
, &graymatrix
, 3);
2320 expect(InvalidParameter
, stat
);
2322 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeCount
,
2323 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2324 expect(InvalidParameter
, stat
);
2326 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeAny
,
2327 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2328 expect(InvalidParameter
, stat
);
2330 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2331 FALSE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2334 /* Drawing a bitmap transforms the colors */
2335 colormatrix
= double_red
;
2336 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2337 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2340 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
2343 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
2346 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff40ccee);
2349 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2352 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2353 UnitPixel
, imageattr
, NULL
, NULL
);
2356 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2358 expect(0xff80ccee, color
);
2360 colormatrix
= asymmetric
;
2361 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2362 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2365 stat
= GdipBitmapSetPixel(bitmap2
, 0, 0, 0);
2368 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2369 UnitPixel
, imageattr
, NULL
, NULL
);
2372 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2374 ok(color_match(0xeeff40cc, color
, 3), "expected 0xeeff40cc, got 0x%08x\n", color
);
2376 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2379 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2380 UnitPixel
, imageattr
, NULL
, NULL
);
2383 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2385 ok(color_match(0xff40ccee, color
, 1), "Expected ff40ccee, got %.8x\n", color
);
2387 GdipDeleteGraphics(graphics
);
2388 GdipDisposeImage((GpImage
*)bitmap1
);
2389 GdipDisposeImage((GpImage
*)bitmap2
);
2390 GdipDisposeImageAttributes(imageattr
);
2393 static void test_gamma(void)
2396 GpImageAttributes
*imageattr
;
2397 GpBitmap
*bitmap1
, *bitmap2
;
2398 GpGraphics
*graphics
;
2401 stat
= GdipSetImageAttributesGamma(NULL
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2402 expect(InvalidParameter
, stat
);
2404 stat
= GdipCreateImageAttributes(&imageattr
);
2407 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2410 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeAny
, TRUE
, 1.0);
2411 expect(InvalidParameter
, stat
);
2413 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, -1.0);
2414 expect(InvalidParameter
, stat
);
2416 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.0);
2417 expect(InvalidParameter
, stat
);
2419 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.5);
2422 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0.0);
2425 /* Drawing a bitmap transforms the colors */
2426 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 3.0);
2429 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
2432 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
2435 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff80ffff);
2438 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2441 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2442 UnitPixel
, imageattr
, NULL
, NULL
);
2445 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2447 ok(color_match(0xff20ffff, color
, 1), "Expected ff20ffff, got %.8x\n", color
);
2449 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2452 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2453 UnitPixel
, imageattr
, NULL
, NULL
);
2456 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2458 ok(color_match(0xff80ffff, color
, 1), "Expected ff80ffff, got %.8x\n", color
);
2460 GdipDeleteGraphics(graphics
);
2461 GdipDisposeImage((GpImage
*)bitmap1
);
2462 GdipDisposeImage((GpImage
*)bitmap2
);
2463 GdipDisposeImageAttributes(imageattr
);
2466 /* 1x1 pixel gif, 2 frames; first frame is white, second is black */
2467 static const unsigned char gifanimation
[72] = {
2468 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
2469 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0xf9,0x04,0x00,0x0a,0x00,0xff,
2470 0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x4c,0x01,0x00,
2471 0x21,0xf9,0x04,0x01,0x0a,0x00,0x01,0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,
2472 0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
2475 /* Generated with ImageMagick:
2476 * convert -transparent black -delay 100 -size 8x2 xc:black \
2477 * -dispose none -page +0+0 -size 2x2 xc:red \
2478 * -dispose background -page +2+0 -size 2x2 xc:blue \
2479 * -dispose previous -page +4+0 -size 2x2 xc:green \
2480 * -dispose undefined -page +6+0 -size 2x2 xc:gray \
2483 static const unsigned char gifanimation2
[] = {
2484 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x08, 0x00,
2485 0x02, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
2486 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x64,
2487 0x00, 0x00, 0x00, 0x21, 0xff, 0x0b, 0x4e, 0x45,
2488 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e,
2489 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00,
2490 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
2491 0x02, 0x04, 0x84, 0x8f, 0x09, 0x05, 0x00, 0x21,
2492 0xf9, 0x04, 0x04, 0x64, 0x00, 0x00, 0x00, 0x2c,
2493 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2494 0x81, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
2495 0x00, 0x00, 0xff, 0x00, 0x00, 0x02, 0x03, 0x44,
2496 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x08, 0x64,
2497 0x00, 0x00, 0x00, 0x2c, 0x02, 0x00, 0x00, 0x00,
2498 0x02, 0x00, 0x02, 0x00, 0x81, 0x00, 0x00, 0xff,
2499 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
2500 0xff, 0x02, 0x03, 0x44, 0x34, 0x05, 0x00, 0x21,
2501 0xf9, 0x04, 0x0c, 0x64, 0x00, 0x00, 0x00, 0x2c,
2502 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2503 0x81, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00,
2504 0x80, 0x00, 0x00, 0x80, 0x00, 0x02, 0x03, 0x44,
2505 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x64,
2506 0x00, 0x00, 0x00, 0x2c, 0x06, 0x00, 0x00, 0x00,
2507 0x02, 0x00, 0x02, 0x00, 0x80, 0x7e, 0x7e, 0x7e,
2508 0x00, 0x00, 0x00, 0x02, 0x02, 0x84, 0x51, 0x00,
2512 static ARGB gifanimation2_pixels
[5][4] = {
2514 {0xffff0000, 0, 0, 0},
2515 {0xffff0000, 0xff0000ff, 0, 0},
2516 {0xffff0000, 0, 0xff008000, 0},
2517 {0xffff0000, 0, 0, 0xff7e7e7e}
2520 static void test_multiframegif(void)
2531 PixelFormat pixel_format
;
2532 INT palette_size
, i
, j
;
2533 char palette_buf
[256];
2534 ColorPalette
*palette
;
2535 ARGB
*palette_entries
;
2537 /* Test frame functions with an animated GIF */
2538 hglob
= GlobalAlloc (0, sizeof(gifanimation
));
2539 data
= GlobalLock (hglob
);
2540 memcpy(data
, gifanimation
, sizeof(gifanimation
));
2541 GlobalUnlock(hglob
);
2543 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2544 ok(hres
== S_OK
, "Failed to create a stream\n");
2545 if(hres
!= S_OK
) return;
2547 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2548 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2550 IStream_Release(stream
);
2554 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2556 expect(PixelFormat32bppARGB
, pixel_format
);
2558 stat
= GdipGetImagePaletteSize((GpImage
*)bmp
, &palette_size
);
2560 ok(palette_size
== sizeof(ColorPalette
) ||
2561 broken(palette_size
== sizeof(ColorPalette
)+sizeof(ARGB
[3])),
2562 "palette_size = %d\n", palette_size
);
2564 /* Bitmap starts at frame 0 */
2566 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2568 expect(0xffffffff, color
);
2570 /* Check that we get correct metadata */
2571 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2575 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2577 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2580 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2584 /* SelectActiveFrame overwrites our current data */
2585 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2589 GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2591 expect(0xff000000, color
);
2593 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2597 GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2599 expect(0xffffffff, color
);
2601 /* Write over the image data */
2602 stat
= GdipBitmapSetPixel(bmp
, 0, 0, 0xff000000);
2605 /* Switching to the same frame does not overwrite our changes */
2606 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2609 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2611 expect(0xff000000, color
);
2613 /* But switching to another frame and back does */
2614 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2617 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2620 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2622 expect(0xffffffff, color
);
2624 /* rotate/flip discards the information about other frames */
2625 stat
= GdipImageRotateFlip((GpImage
*)bmp
, Rotate90FlipNone
);
2629 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2633 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bmp
, __LINE__
, FALSE
);
2635 GdipDisposeImage((GpImage
*)bmp
);
2636 IStream_Release(stream
);
2638 /* Test with a non-animated gif */
2639 hglob
= GlobalAlloc (0, sizeof(gifimage
));
2640 data
= GlobalLock (hglob
);
2641 memcpy(data
, gifimage
, sizeof(gifimage
));
2642 GlobalUnlock(hglob
);
2644 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2645 ok(hres
== S_OK
, "Failed to create a stream\n");
2646 if(hres
!= S_OK
) return;
2648 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2649 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2651 IStream_Release(stream
);
2655 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2657 expect(PixelFormat8bppIndexed
, pixel_format
);
2659 /* Check metadata */
2660 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2664 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2666 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2669 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2673 GdipDisposeImage((GpImage
*)bmp
);
2674 IStream_Release(stream
);
2676 /* Test with a non-animated transparent gif */
2677 hglob
= GlobalAlloc (0, sizeof(transparentgif
));
2678 data
= GlobalLock (hglob
);
2679 memcpy(data
, transparentgif
, sizeof(transparentgif
));
2680 GlobalUnlock(hglob
);
2682 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2683 ok(hres
== S_OK
, "Failed to create a stream\n");
2685 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2686 IStream_Release(stream
);
2687 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2689 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2691 expect(PixelFormat8bppIndexed
, pixel_format
);
2693 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2697 stat
= GdipGetImagePaletteSize((GpImage
*)bmp
, &palette_size
);
2699 ok(palette_size
== sizeof(ColorPalette
)+sizeof(ARGB
),
2700 "palette_size = %d\n", palette_size
);
2702 memset(palette_buf
, 0xfe, sizeof(palette_buf
));
2703 palette
= (ColorPalette
*)palette_buf
;
2704 stat
= GdipGetImagePalette((GpImage
*)bmp
, palette
,
2705 sizeof(ColorPalette
)+sizeof(ARGB
));
2706 palette_entries
= palette
->Entries
;
2708 expect(PaletteFlagsHasAlpha
, palette
->Flags
);
2709 expect(2, palette
->Count
);
2710 expect(0, palette_entries
[0]);
2711 expect(0xff000000, palette_entries
[1]);
2714 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2718 GdipDisposeImage((GpImage
*)bmp
);
2720 /* Test frame dispose methods */
2721 hglob
= GlobalAlloc (0, sizeof(gifanimation2
));
2722 data
= GlobalLock (hglob
);
2723 memcpy(data
, gifanimation2
, sizeof(gifanimation2
));
2724 GlobalUnlock(hglob
);
2726 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2727 ok(hres
== S_OK
, "Failed to create a stream\n");
2729 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2730 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2731 IStream_Release(stream
);
2733 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2735 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2737 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2741 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2745 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 3);
2747 stat
= GdipBitmapGetPixel(bmp
, 2, 0, &color
);
2749 ok(color
==0 || broken(color
==0xff0000ff), "color = %x\n", color
);
2751 win_skip("broken animated gif support\n");
2752 GdipDisposeImage((GpImage
*)bmp
);
2756 for(i
=0; i
<6; i
++) {
2757 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, i
%5);
2760 for(j
=0; j
<4; j
++) {
2761 stat
= GdipBitmapGetPixel(bmp
, j
*2, 0, &color
);
2763 ok(gifanimation2_pixels
[i
%5][j
] == color
, "at %d,%d got %x, expected %x\n", i
, j
, color
, gifanimation2_pixels
[i
%5][j
]);
2767 GdipDisposeImage((GpImage
*)bmp
);
2770 static void test_rotateflip(void)
2775 static const BYTE orig_bits
[24] = {
2776 0,0,0xff, 0,0xff,0, 0xff,0,0, 23,23,23,
2777 0xff,0xff,0, 0xff,0,0xff, 0,0xff,0xff, 23,23,23};
2781 memcpy(bits
, orig_bits
, sizeof(bits
));
2782 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2785 stat
= GdipImageRotateFlip(bitmap
, Rotate90FlipNone
);
2788 stat
= GdipGetImageWidth(bitmap
, &width
);
2790 stat
= GdipGetImageHeight(bitmap
, &height
);
2795 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2797 expect(0xff00ffff, color
);
2799 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 0, &color
);
2801 expect(0xffff0000, color
);
2803 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 2, &color
);
2805 expect(0xffffff00, color
);
2807 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 2, &color
);
2809 expect(0xff0000ff, color
);
2813 expect(0xff, bits
[2]);
2815 GdipDisposeImage(bitmap
);
2817 memcpy(bits
, orig_bits
, sizeof(bits
));
2818 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2821 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipX
);
2824 stat
= GdipGetImageWidth(bitmap
, &width
);
2826 stat
= GdipGetImageHeight(bitmap
, &height
);
2831 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2833 expect(0xff0000ff, color
);
2835 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
2837 expect(0xffff0000, color
);
2839 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
2841 expect(0xffffff00, color
);
2843 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
2845 expect(0xff00ffff, color
);
2849 expect(0xff, bits
[2]);
2851 GdipDisposeImage(bitmap
);
2853 memcpy(bits
, orig_bits
, sizeof(bits
));
2854 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2857 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipY
);
2860 stat
= GdipGetImageWidth(bitmap
, &width
);
2862 stat
= GdipGetImageHeight(bitmap
, &height
);
2867 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2869 expect(0xff00ffff, color
);
2871 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
2873 expect(0xffffff00, color
);
2875 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
2877 expect(0xffff0000, color
);
2879 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
2881 expect(0xff0000ff, color
);
2885 expect(0xff, bits
[2]);
2887 GdipDisposeImage(bitmap
);
2890 static void test_remaptable(void)
2893 GpImageAttributes
*imageattr
;
2894 GpBitmap
*bitmap1
, *bitmap2
;
2895 GpGraphics
*graphics
;
2899 map
= GdipAlloc(sizeof(ColorMap
));
2901 map
->oldColor
.Argb
= 0xff00ff00;
2902 map
->newColor
.Argb
= 0xffff00ff;
2904 stat
= GdipSetImageAttributesRemapTable(NULL
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
2905 expect(InvalidParameter
, stat
);
2907 stat
= GdipCreateImageAttributes(&imageattr
);
2910 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, NULL
);
2911 expect(InvalidParameter
, stat
);
2913 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeCount
, TRUE
, 1, map
);
2914 expect(InvalidParameter
, stat
);
2916 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeAny
, TRUE
, 1, map
);
2917 expect(InvalidParameter
, stat
);
2919 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0, map
);
2920 expect(InvalidParameter
, stat
);
2922 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0, NULL
);
2925 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
2928 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
2931 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
2934 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff00ff00);
2937 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2940 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2941 UnitPixel
, imageattr
, NULL
, NULL
);
2944 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2946 ok(color_match(0xffff00ff, color
, 1), "Expected ffff00ff, got %.8x\n", color
);
2948 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2951 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2952 UnitPixel
, imageattr
, NULL
, NULL
);
2955 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2957 ok(color_match(0xff00ff00, color
, 1), "Expected ff00ff00, got %.8x\n", color
);
2959 GdipDeleteGraphics(graphics
);
2960 GdipDisposeImage((GpImage
*)bitmap1
);
2961 GdipDisposeImage((GpImage
*)bitmap2
);
2962 GdipDisposeImageAttributes(imageattr
);
2966 static void test_colorkey(void)
2969 GpImageAttributes
*imageattr
;
2970 GpBitmap
*bitmap1
, *bitmap2
;
2971 GpGraphics
*graphics
;
2974 stat
= GdipSetImageAttributesColorKeys(NULL
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
2975 expect(InvalidParameter
, stat
);
2977 stat
= GdipCreateImageAttributes(&imageattr
);
2980 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeCount
, TRUE
, 0xff405060, 0xff708090);
2981 expect(InvalidParameter
, stat
);
2983 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeAny
, TRUE
, 0xff405060, 0xff708090);
2984 expect(InvalidParameter
, stat
);
2986 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
2989 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
2992 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
2995 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0x20405060);
2998 stat
= GdipBitmapSetPixel(bitmap1
, 0, 1, 0x40506070);
3001 stat
= GdipBitmapSetPixel(bitmap1
, 1, 0, 0x60708090);
3004 stat
= GdipBitmapSetPixel(bitmap1
, 1, 1, 0xffffffff);
3007 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
3010 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
3011 UnitPixel
, imageattr
, NULL
, NULL
);
3014 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
3016 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
3018 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
3020 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
3022 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
3024 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
3026 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
3028 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
3030 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
3033 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
3034 UnitPixel
, imageattr
, NULL
, NULL
);
3037 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
3039 ok(color_match(0x20405060, color
, 1), "Expected 20405060, got %.8x\n", color
);
3041 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
3043 ok(color_match(0x40506070, color
, 1), "Expected 40506070, got %.8x\n", color
);
3045 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
3047 ok(color_match(0x60708090, color
, 1), "Expected 60708090, got %.8x\n", color
);
3049 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
3051 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
3054 GdipDeleteGraphics(graphics
);
3055 GdipDisposeImage((GpImage
*)bitmap1
);
3056 GdipDisposeImage((GpImage
*)bitmap2
);
3057 GdipDisposeImageAttributes(imageattr
);
3060 static void test_dispose(void)
3064 char invalid_image
[256];
3066 stat
= GdipDisposeImage(NULL
);
3067 expect(InvalidParameter
, stat
);
3069 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, (GpBitmap
**)&image
);
3072 stat
= GdipDisposeImage(image
);
3075 stat
= GdipDisposeImage(image
);
3076 expect(ObjectBusy
, stat
);
3078 memset(invalid_image
, 0, 256);
3079 stat
= GdipDisposeImage((GpImage
*)invalid_image
);
3080 expect(ObjectBusy
, stat
);
3083 static LONG
obj_refcount(void *obj
)
3085 IUnknown_AddRef((IUnknown
*)obj
);
3086 return IUnknown_Release((IUnknown
*)obj
);
3089 static GpImage
*load_image(const BYTE
*image_data
, UINT image_size
)
3096 GpImage
*image
= NULL
, *clone
;
3097 ImageType image_type
;
3098 LONG refcount
, old_refcount
;
3100 hmem
= GlobalAlloc(0, image_size
);
3101 data
= GlobalLock(hmem
);
3102 memcpy(data
, image_data
, image_size
);
3105 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
3106 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
3107 if (hr
!= S_OK
) return NULL
;
3109 refcount
= obj_refcount(stream
);
3110 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3112 status
= GdipLoadImageFromStream(stream
, &image
);
3113 ok(status
== Ok
|| broken(status
== InvalidParameter
), /* XP */
3114 "GdipLoadImageFromStream error %d\n", status
);
3117 IStream_Release(stream
);
3121 status
= GdipGetImageType(image
, &image_type
);
3122 ok(status
== Ok
, "GdipGetImageType error %d\n", status
);
3124 refcount
= obj_refcount(stream
);
3125 if (image_type
== ImageTypeBitmap
)
3126 ok(refcount
> 1, "expected stream refcount > 1, got %d\n", refcount
);
3128 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3129 old_refcount
= refcount
;
3131 status
= GdipCloneImage(image
, &clone
);
3132 ok(status
== Ok
, "GdipCloneImage error %d\n", status
);
3133 refcount
= obj_refcount(stream
);
3134 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3135 status
= GdipDisposeImage(clone
);
3136 ok(status
== Ok
, "GdipDisposeImage error %d\n", status
);
3137 refcount
= obj_refcount(stream
);
3138 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3140 refcount
= IStream_Release(stream
);
3141 if (image_type
== ImageTypeBitmap
)
3142 ok(refcount
>= 1, "expected stream refcount != 0\n");
3144 ok(refcount
== 0, "expected stream refcount 0, got %d\n", refcount
);
3149 static void test_image_properties(void)
3151 static const struct test_data
3153 const BYTE
*image_data
;
3155 ImageType image_type
;
3157 UINT prop_count2
; /* if win7 behaves differently */
3158 /* 1st property attributes */
3160 UINT prop_size2
; /* if win7 behaves differently */
3162 UINT prop_id2
; /* if win7 behaves differently */
3166 { pngimage
, sizeof(pngimage
), ImageTypeBitmap
, 4, ~0, 1, 20, 0x5110, 0x132 },
3167 { jpgimage
, sizeof(jpgimage
), ImageTypeBitmap
, 2, ~0, 128, 0, 0x5090, 0x5091 },
3168 { tiffimage
, sizeof(tiffimage
), ImageTypeBitmap
, 16, 0, 4, 0, 0xfe, 0 },
3169 { bmpimage
, sizeof(bmpimage
), ImageTypeBitmap
, 0, 0, 0, 0, 0, 0 },
3170 { wmfimage
, sizeof(wmfimage
), ImageTypeMetafile
, 0, 0, 0, 0, 0, 0 }
3174 UINT prop_count
, prop_size
, i
;
3175 PROPID prop_id
[16] = { 0 };
3176 ImageType image_type
;
3183 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
3185 image
= load_image(td
[i
].image_data
, td
[i
].image_size
);
3188 trace("%u: failed to load image data\n", i
);
3192 status
= GdipGetImageType(image
, &image_type
);
3193 ok(status
== Ok
, "%u: GdipGetImageType error %d\n", i
, status
);
3194 ok(td
[i
].image_type
== image_type
, "%u: expected image_type %d, got %d\n",
3195 i
, td
[i
].image_type
, image_type
);
3197 status
= GdipGetPropertyCount(image
, &prop_count
);
3198 ok(status
== Ok
, "%u: GdipGetPropertyCount error %d\n", i
, status
);
3199 todo_wine_if(td
[i
].image_data
== pngimage
|| td
[i
].image_data
== jpgimage
)
3200 ok(td
[i
].prop_count
== prop_count
|| td
[i
].prop_count2
== prop_count
,
3201 " %u: expected property count %u or %u, got %u\n",
3202 i
, td
[i
].prop_count
, td
[i
].prop_count2
, prop_count
);
3204 status
= GdipGetPropertyItemSize(NULL
, 0, &prop_size
);
3205 expect(InvalidParameter
, status
);
3206 status
= GdipGetPropertyItemSize(image
, 0, NULL
);
3207 expect(InvalidParameter
, status
);
3208 status
= GdipGetPropertyItemSize(image
, 0, &prop_size
);
3209 if (image_type
== ImageTypeMetafile
)
3210 expect(NotImplemented
, status
);
3212 expect(PropertyNotFound
, status
);
3214 status
= GdipGetPropertyItem(NULL
, 0, 0, &item
.data
);
3215 expect(InvalidParameter
, status
);
3216 status
= GdipGetPropertyItem(image
, 0, 0, NULL
);
3217 expect(InvalidParameter
, status
);
3218 status
= GdipGetPropertyItem(image
, 0, 0, &item
.data
);
3219 if (image_type
== ImageTypeMetafile
)
3220 expect(NotImplemented
, status
);
3222 expect(PropertyNotFound
, status
);
3224 /* FIXME: remove once Wine is fixed */
3225 if (td
[i
].prop_count
!= prop_count
)
3227 GdipDisposeImage(image
);
3231 status
= GdipGetPropertyIdList(NULL
, prop_count
, prop_id
);
3232 expect(InvalidParameter
, status
);
3233 status
= GdipGetPropertyIdList(image
, prop_count
, NULL
);
3234 expect(InvalidParameter
, status
);
3235 status
= GdipGetPropertyIdList(image
, 0, prop_id
);
3236 if (image_type
== ImageTypeMetafile
)
3237 expect(NotImplemented
, status
);
3238 else if (prop_count
== 0)
3241 expect(InvalidParameter
, status
);
3242 status
= GdipGetPropertyIdList(image
, prop_count
- 1, prop_id
);
3243 if (image_type
== ImageTypeMetafile
)
3244 expect(NotImplemented
, status
);
3246 expect(InvalidParameter
, status
);
3247 status
= GdipGetPropertyIdList(image
, prop_count
+ 1, prop_id
);
3248 if (image_type
== ImageTypeMetafile
)
3249 expect(NotImplemented
, status
);
3251 expect(InvalidParameter
, status
);
3252 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3253 if (image_type
== ImageTypeMetafile
)
3254 expect(NotImplemented
, status
);
3258 if (prop_count
!= 0)
3259 ok(td
[i
].prop_id
== prop_id
[0] || td
[i
].prop_id2
== prop_id
[0],
3260 " %u: expected property id %#x or %#x, got %#x\n",
3261 i
, td
[i
].prop_id
, td
[i
].prop_id2
, prop_id
[0]);
3266 status
= GdipGetPropertyItemSize(image
, prop_id
[0], &prop_size
);
3267 if (prop_count
== 0)
3268 expect(PropertyNotFound
, status
);
3273 assert(sizeof(item
) >= prop_size
);
3274 ok(prop_size
> sizeof(PropertyItem
), "%u: got too small prop_size %u\n",
3276 ok(td
[i
].prop_size
+ sizeof(PropertyItem
) == prop_size
||
3277 td
[i
].prop_size2
+ sizeof(PropertyItem
) == prop_size
,
3278 " %u: expected property size %u or %u, got %u\n",
3279 i
, td
[i
].prop_size
, td
[i
].prop_size2
, prop_size
);
3281 status
= GdipGetPropertyItem(image
, prop_id
[0], 0, &item
.data
);
3282 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3283 "%u: expected InvalidParameter, got %d\n", i
, status
);
3284 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
- 1, &item
.data
);
3285 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3286 "%u: expected InvalidParameter, got %d\n", i
, status
);
3287 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
+ 1, &item
.data
);
3288 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3289 "%u: expected InvalidParameter, got %d\n", i
, status
);
3290 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
, &item
.data
);
3292 ok(prop_id
[0] == item
.data
.id
,
3293 "%u: expected property id %#x, got %#x\n", i
, prop_id
[0], item
.data
.id
);
3297 GdipDisposeImage(image
);
3305 #define IFD_RATIONAL 5
3307 #define IFD_UNDEFINED 7
3308 #define IFD_SSHORT 8
3310 #define IFD_SRATIONAL 10
3311 #define IFD_FLOAT 11
3312 #define IFD_DOUBLE 12
3314 #ifndef PropertyTagTypeSByte
3315 #define PropertyTagTypeSByte 6
3316 #define PropertyTagTypeSShort 8
3317 #define PropertyTagTypeFloat 11
3318 #define PropertyTagTypeDouble 12
3321 static UINT
documented_type(UINT type
)
3325 case PropertyTagTypeSByte
: return PropertyTagTypeByte
;
3326 case PropertyTagTypeSShort
: return PropertyTagTypeShort
;
3327 case PropertyTagTypeFloat
: return PropertyTagTypeUndefined
;
3328 case PropertyTagTypeDouble
: return PropertyTagTypeUndefined
;
3329 default: return type
;
3333 #include "pshpack2.h"
3348 static const struct tiff_data
3353 USHORT number_of_entries
;
3354 struct IFD_entry entry
[40];
3356 struct IFD_rational xres
;
3358 struct IFD_rational srational_val
;
3363 struct IFD_rational rational
[3];
3367 #ifdef WORDS_BIGENDIAN
3373 FIELD_OFFSET(struct tiff_data
, number_of_entries
),
3376 { 0xff, IFD_SHORT
, 1, 0 }, /* SUBFILETYPE */
3377 { 0x100, IFD_LONG
, 1, 1 }, /* IMAGEWIDTH */
3378 { 0x101, IFD_LONG
, 1, 1 }, /* IMAGELENGTH */
3379 { 0x102, IFD_SHORT
, 1, 1 }, /* BITSPERSAMPLE */
3380 { 0x103, IFD_SHORT
, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
3381 { 0x106, IFD_SHORT
, 1, 1 }, /* PHOTOMETRIC */
3382 { 0x111, IFD_LONG
, 1, FIELD_OFFSET(struct tiff_data
, pixel_data
) }, /* STRIPOFFSETS */
3383 { 0x115, IFD_SHORT
, 1, 1 }, /* SAMPLESPERPIXEL */
3384 { 0x116, IFD_LONG
, 1, 1 }, /* ROWSPERSTRIP */
3385 { 0x117, IFD_LONG
, 1, 1 }, /* STRIPBYTECOUNT */
3386 { 0x11a, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3387 { 0x11b, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3388 { 0x128, IFD_SHORT
, 1, 2 }, /* RESOLUTIONUNIT */
3389 { 0xf001, IFD_BYTE
, 1, 0x11223344 },
3390 { 0xf002, IFD_BYTE
, 4, 0x11223344 },
3391 { 0xf003, IFD_SBYTE
, 1, 0x11223344 },
3392 { 0xf004, IFD_SSHORT
, 1, 0x11223344 },
3393 { 0xf005, IFD_SSHORT
, 2, 0x11223344 },
3394 { 0xf006, IFD_SLONG
, 1, 0x11223344 },
3395 { 0xf007, IFD_FLOAT
, 1, 0x11223344 },
3396 { 0xf008, IFD_DOUBLE
, 1, FIELD_OFFSET(struct tiff_data
, double_val
) },
3397 { 0xf009, IFD_SRATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, srational_val
) },
3398 { 0xf00a, IFD_BYTE
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3399 { 0xf00b, IFD_SSHORT
, 4, FIELD_OFFSET(struct tiff_data
, short_val
) },
3400 { 0xf00c, IFD_SLONG
, 2, FIELD_OFFSET(struct tiff_data
, long_val
) },
3401 { 0xf00e, IFD_ASCII
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3402 { 0xf00f, IFD_ASCII
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3403 { 0xf010, IFD_UNDEFINED
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3404 { 0xf011, IFD_UNDEFINED
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3405 /* Some gdiplus versions ignore these fields.
3406 { 0xf012, IFD_BYTE, 0, 0x11223344 },
3407 { 0xf013, IFD_SHORT, 0, 0x11223344 },
3408 { 0xf014, IFD_LONG, 0, 0x11223344 },
3409 { 0xf015, IFD_FLOAT, 0, 0x11223344 },*/
3410 { 0xf016, IFD_SRATIONAL
, 3, FIELD_OFFSET(struct tiff_data
, rational
) },
3411 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3412 { 0xf017, IFD_FLOAT
, 2, FIELD_OFFSET(struct tiff_data
, float_val
) },
3416 1234567890.0987654321,
3417 { 0x1a2b3c4d, 0x5a6b7c8d },
3419 { 0x0101, 0x0202, 0x0303, 0x0404 },
3420 { 0x11223344, 0x55667788 },
3421 { (FLOAT
)1234.5678, (FLOAT
)8765.4321 },
3422 { { 0x01020304, 0x05060708 }, { 0x10203040, 0x50607080 }, { 0x11223344, 0x55667788 } },
3423 { 0x11, 0x22, 0x33, 0 }
3425 #include "poppack.h"
3427 static void test_tiff_properties(void)
3429 static const struct test_data
3431 ULONG type
, id
, length
;
3432 const BYTE value
[24];
3435 { PropertyTagTypeShort
, 0xff, 2, { 0 } },
3436 { PropertyTagTypeLong
, 0x100, 4, { 1 } },
3437 { PropertyTagTypeLong
, 0x101, 4, { 1 } },
3438 { PropertyTagTypeShort
, 0x102, 2, { 1 } },
3439 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3440 { PropertyTagTypeShort
, 0x106, 2, { 1 } },
3441 { PropertyTagTypeLong
, 0x111, 4, { 0x44,0x02 } },
3442 { PropertyTagTypeShort
, 0x115, 2, { 1 } },
3443 { PropertyTagTypeLong
, 0x116, 4, { 1 } },
3444 { PropertyTagTypeLong
, 0x117, 4, { 1 } },
3445 { PropertyTagTypeRational
, 0x11a, 8, { 0x84,0x03,0,0,0x03 } },
3446 { PropertyTagTypeRational
, 0x11b, 8, { 0x84,0x03,0,0,0x03 } },
3447 { PropertyTagTypeShort
, 0x128, 2, { 2 } },
3448 { PropertyTagTypeByte
, 0xf001, 1, { 0x44 } },
3449 { PropertyTagTypeByte
, 0xf002, 4, { 0x44,0x33,0x22,0x11 } },
3450 { PropertyTagTypeSByte
, 0xf003, 1, { 0x44 } },
3451 { PropertyTagTypeSShort
, 0xf004, 2, { 0x44,0x33 } },
3452 { PropertyTagTypeSShort
, 0xf005, 4, { 0x44,0x33,0x22,0x11 } },
3453 { PropertyTagTypeSLONG
, 0xf006, 4, { 0x44,0x33,0x22,0x11 } },
3454 { PropertyTagTypeFloat
, 0xf007, 4, { 0x44,0x33,0x22,0x11 } },
3455 { PropertyTagTypeDouble
, 0xf008, 8, { 0x2c,0x52,0x86,0xb4,0x80,0x65,0xd2,0x41 } },
3456 { PropertyTagTypeSRational
, 0xf009, 8, { 0x4d, 0x3c, 0x2b, 0x1a, 0x8d, 0x7c, 0x6b, 0x5a } },
3457 { PropertyTagTypeByte
, 0xf00a, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3458 { PropertyTagTypeSShort
, 0xf00b, 8, { 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04 } },
3459 { PropertyTagTypeSLONG
, 0xf00c, 8, { 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3460 { PropertyTagTypeASCII
, 0xf00e, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3461 { PropertyTagTypeASCII
, 0xf00f, 5, { 'a','b','c','d' } },
3462 { PropertyTagTypeUndefined
, 0xf010, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3463 { PropertyTagTypeUndefined
, 0xf011, 4, { 'a','b','c','d' } },
3464 { PropertyTagTypeSRational
, 0xf016, 24,
3465 { 0x04,0x03,0x02,0x01,0x08,0x07,0x06,0x05,
3466 0x40,0x30,0x20,0x10,0x80,0x70,0x60,0x50,
3467 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3468 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3469 { PropertyTagTypeFloat
, 0xf017, 8, { 0x2b,0x52,0x9a,0x44,0xba,0xf5,0x08,0x46 } },
3474 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3476 PropertyItem
*prop_item
;
3478 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
));
3481 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3485 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3487 expect(1, dim_count
);
3489 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3491 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3493 frame_count
= 0xdeadbeef;
3494 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3496 expect(1, frame_count
);
3498 prop_count
= 0xdeadbeef;
3499 status
= GdipGetPropertyCount(image
, &prop_count
);
3501 ok(prop_count
== sizeof(td
)/sizeof(td
[0]) ||
3502 broken(prop_count
== sizeof(td
)/sizeof(td
[0]) - 1) /* Win7 SP0 */,
3503 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
3505 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3507 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3510 for (i
= 0; i
< prop_count
; i
++)
3512 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &prop_size
);
3514 if (status
!= Ok
) break;
3515 ok(prop_size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, prop_size
);
3517 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, prop_size
);
3518 status
= GdipGetPropertyItem(image
, prop_id
[i
], prop_size
, prop_item
);
3520 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3521 ok(td
[i
].type
== prop_item
->type
||
3522 /* Win7 stopped using proper but not documented types, and it
3523 looks broken since TypeFloat and TypeDouble now reported as
3524 TypeUndefined, and signed types reported as unsigned. */
3525 broken(prop_item
->type
== documented_type(td
[i
].type
)),
3526 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3527 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3528 prop_size
-= sizeof(*prop_item
);
3529 ok(prop_item
->length
== prop_size
, "%u: expected length %u, got %u\n", i
, prop_size
, prop_item
->length
);
3530 ok(td
[i
].length
== prop_item
->length
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_item
->length
+1) /* XP */,
3531 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3532 ok(td
[i
].length
== prop_size
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_size
+1) /* XP */,
3533 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_size
);
3534 if (td
[i
].length
== prop_item
->length
)
3536 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3537 ok(match
|| broken(td
[i
].length
<= 4 && !match
), "%u: data mismatch\n", i
);
3541 BYTE
*data
= prop_item
->value
;
3542 trace("id %#x:", prop_item
->id
);
3543 for (j
= 0; j
< prop_item
->length
; j
++)
3544 trace(" %02x", data
[j
]);
3548 HeapFree(GetProcessHeap(), 0, prop_item
);
3551 HeapFree(GetProcessHeap(), 0, prop_id
);
3553 GdipDisposeImage(image
);
3556 static void test_GdipGetAllPropertyItems(void)
3558 static const struct test_data
3560 ULONG type
, id
, length
;
3564 { PropertyTagTypeLong
, 0xfe, 4, { 0 } },
3565 { PropertyTagTypeShort
, 0x100, 2, { 1 } },
3566 { PropertyTagTypeShort
, 0x101, 2, { 1 } },
3567 { PropertyTagTypeShort
, 0x102, 6, { 8,0,8,0,8,0 } },
3568 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3569 { PropertyTagTypeShort
, 0x106, 2, { 2,0 } },
3570 { PropertyTagTypeASCII
, 0x10d, 27, "/home/meh/Desktop/test.tif" },
3571 { PropertyTagTypeLong
, 0x111, 4, { 8,0,0,0 } },
3572 { PropertyTagTypeShort
, 0x112, 2, { 1 } },
3573 { PropertyTagTypeShort
, 0x115, 2, { 3,0 } },
3574 { PropertyTagTypeShort
, 0x116, 2, { 0x40,0 } },
3575 { PropertyTagTypeLong
, 0x117, 4, { 3,0,0,0 } },
3576 { PropertyTagTypeRational
, 0x11a, 8, { 0,0,0,72,0,0,0,1 } },
3577 { PropertyTagTypeRational
, 0x11b, 8, { 0,0,0,72,0,0,0,1 } },
3578 { PropertyTagTypeShort
, 0x11c, 2, { 1 } },
3579 { PropertyTagTypeShort
, 0x128, 2, { 2 } }
3584 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3585 UINT total_size
, total_count
;
3587 PropertyItem
*prop_item
;
3588 const char *item_data
;
3590 image
= load_image(tiffimage
, sizeof(tiffimage
));
3591 ok(image
!= 0, "Failed to load TIFF image data\n");
3594 dim_count
= 0xdeadbeef;
3595 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3597 expect(1, dim_count
);
3599 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3601 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3603 frame_count
= 0xdeadbeef;
3604 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3606 expect(1, frame_count
);
3608 prop_count
= 0xdeadbeef;
3609 status
= GdipGetPropertyCount(image
, &prop_count
);
3611 ok(prop_count
== sizeof(td
)/sizeof(td
[0]),
3612 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
3614 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3616 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3620 for (i
= 0; i
< prop_count
; i
++)
3623 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
3625 if (status
!= Ok
) break;
3626 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
3630 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
3631 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
3633 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3634 ok(td
[i
].type
== prop_item
->type
,
3635 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3636 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3637 size
-= sizeof(*prop_item
);
3638 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
3639 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3640 if (td
[i
].length
== prop_item
->length
)
3642 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3643 ok(match
, "%u: data mismatch\n", i
);
3647 BYTE
*data
= prop_item
->value
;
3648 trace("id %#x:", prop_item
->id
);
3649 for (j
= 0; j
< prop_item
->length
; j
++)
3650 trace(" %02x", data
[j
]);
3654 HeapFree(GetProcessHeap(), 0, prop_item
);
3657 HeapFree(GetProcessHeap(), 0, prop_id
);
3659 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
3660 expect(InvalidParameter
, status
);
3661 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
3662 expect(InvalidParameter
, status
);
3663 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
3664 expect(InvalidParameter
, status
);
3665 status
= GdipGetPropertySize(image
, NULL
, NULL
);
3666 expect(InvalidParameter
, status
);
3667 total_size
= 0xdeadbeef;
3668 total_count
= 0xdeadbeef;
3669 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
3671 ok(prop_count
== total_count
,
3672 "expected total property count %u, got %u\n", prop_count
, total_count
);
3673 ok(prop_size
== total_size
,
3674 "expected total property size %u, got %u\n", prop_size
, total_size
);
3676 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
3678 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
3679 expect(InvalidParameter
, status
);
3680 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
3681 expect(InvalidParameter
, status
);
3682 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3683 expect(InvalidParameter
, status
);
3684 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3685 expect(InvalidParameter
, status
);
3686 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
3687 expect(InvalidParameter
, status
);
3688 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
3689 expect(InvalidParameter
, status
);
3690 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
3693 item_data
= (const char *)(prop_item
+ prop_count
);
3694 for (i
= 0; i
< prop_count
; i
++)
3696 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
3697 i
, item_data
, prop_item
[i
].value
);
3698 ok(td
[i
].type
== prop_item
[i
].type
,
3699 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
3700 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
3701 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
3702 if (td
[i
].length
== prop_item
[i
].length
)
3704 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
3705 ok(match
, "%u: data mismatch\n", i
);
3709 BYTE
*data
= prop_item
[i
].value
;
3710 trace("id %#x:", prop_item
[i
].id
);
3711 for (j
= 0; j
< prop_item
[i
].length
; j
++)
3712 trace(" %02x", data
[j
]);
3716 item_data
+= prop_item
[i
].length
;
3719 HeapFree(GetProcessHeap(), 0, prop_item
);
3721 GdipDisposeImage(image
);
3724 static void test_tiff_palette(void)
3735 ARGB
*entries
= palette
.pal
.Entries
;
3737 /* 1bpp TIFF without palette */
3738 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
));
3741 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3745 status
= GdipGetImagePixelFormat(image
, &format
);
3747 ok(format
== PixelFormat1bppIndexed
, "expected PixelFormat1bppIndexed, got %#x\n", format
);
3749 status
= GdipGetImagePaletteSize(image
, &size
);
3750 ok(status
== Ok
|| broken(status
== GenericError
), /* XP */
3751 "GdipGetImagePaletteSize error %d\n", status
);
3752 if (status
== GenericError
)
3754 GdipDisposeImage(image
);
3757 expect(sizeof(ColorPalette
) + sizeof(ARGB
), size
);
3759 status
= GdipGetImagePalette(image
, &palette
.pal
, size
);
3761 expect(0, palette
.pal
.Flags
);
3762 expect(2, palette
.pal
.Count
);
3763 if (palette
.pal
.Count
== 2)
3765 ok(entries
[0] == 0xff000000, "expected 0xff000000, got %#x\n", entries
[0]);
3766 ok(entries
[1] == 0xffffffff, "expected 0xffffffff, got %#x\n", entries
[1]);
3769 GdipDisposeImage(image
);
3772 static void test_bitmapbits(void)
3775 static const BYTE pixels_24
[48] =
3777 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3778 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3779 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3780 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0
3782 static const BYTE pixels_00
[48] =
3784 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3785 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3786 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3787 0,0,0, 0,0,0, 0,0,0, 0,0,0
3789 static const BYTE pixels_24_77
[64] =
3791 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3792 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3793 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3794 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3795 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3796 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3798 static const BYTE pixels_77
[64] =
3800 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3801 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3802 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3803 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3804 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3805 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3806 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3807 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3809 static const BYTE pixels_8
[16] =
3811 0x01,0,0x01,0,0x01,0,0x01,0,
3812 0x01,0,0x01,0,0x01,0,0x01,0
3814 static const BYTE pixels_8_77
[64] =
3816 0x01,0,0x01,0,0x01,0,0x01,0,
3817 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3818 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3819 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3820 0x01,0,0x01,0,0x01,0,0x01,0,
3821 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3822 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3823 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3825 static const BYTE pixels_1_77
[64] =
3827 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3828 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3829 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3830 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3831 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3832 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3833 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3834 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3836 static const BYTE pixels_1
[8] = {0xaa,0,0,0,0xaa,0,0,0};
3837 static const struct test_data
3844 const BYTE
*pixels_unlocked
;
3848 { PixelFormat24bppRGB
, 24, 0xfff0, 24, 48, pixels_24
, pixels_00
},
3850 { PixelFormat24bppRGB
, 24, 0, 24, 48, pixels_24
, pixels_00
},
3851 { PixelFormat24bppRGB
, 24, ImageLockModeRead
, 24, 48, pixels_24
, pixels_00
},
3852 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
3853 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
3854 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_24_77
, pixels_24
},
3855 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3856 { PixelFormat24bppRGB
, 24, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3858 { PixelFormat8bppIndexed
, 8, 0, 8, 16, pixels_8
, pixels_24
},
3859 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
, 8, 16, pixels_8
, pixels_24
},
3860 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
3861 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
3862 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_8_77
, pixels_24
},
3863 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3864 { PixelFormat8bppIndexed
, 8, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3866 { PixelFormat1bppIndexed
, 1, 0, 4, 8, pixels_1
, pixels_24
},
3867 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
, 4, 8, pixels_1
, pixels_24
},
3868 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
3869 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
3870 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_1_77
, pixels_24
},
3871 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3872 { PixelFormat1bppIndexed
, 1, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3884 ARGB
*entries
= palette
.pal
.Entries
;
3886 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
3888 BYTE pixels
[sizeof(pixels_24
)];
3889 memcpy(pixels
, pixels_24
, sizeof(pixels_24
));
3890 status
= GdipCreateBitmapFromScan0(8, 2, 24, PixelFormat24bppRGB
, pixels
, &bitmap
);
3893 /* associate known palette with pixel data */
3894 palette
.pal
.Flags
= PaletteFlagsGrayScale
;
3895 palette
.pal
.Count
= 2;
3896 entries
[0] = 0xff000000;
3897 entries
[1] = 0xffffffff;
3898 status
= GdipSetImagePalette((GpImage
*)bitmap
, &palette
.pal
);
3901 memset(&data
, 0xfe, sizeof(data
));
3902 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
3904 memset(buf
, 0x77, sizeof(buf
));
3908 status
= GdipBitmapLockBits(bitmap
, NULL
, td
[i
].mode
, td
[i
].format
, &data
);
3909 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* XP */, "%u: GdipBitmapLockBits error %d\n", i
, status
);
3912 GdipDisposeImage((GpImage
*)bitmap
);
3915 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
3916 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
3917 ok(td
[i
].stride
== data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].stride
, data
.Stride
);
3918 ok(td
[i
].format
== data
.PixelFormat
, "%u: expected %d, got %d\n", i
, td
[i
].format
, data
.PixelFormat
);
3919 ok(td
[i
].size
== data
.Height
* data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].size
, data
.Height
* data
.Stride
);
3920 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
3921 ok(data
.Scan0
== buf
, "%u: got wrong buffer\n", i
);
3922 if (td
[i
].size
== data
.Height
* data
.Stride
)
3924 UINT j
, match
, width_bytes
= (data
.Width
* td
[i
].bpp
) / 8;
3927 for (j
= 0; j
< data
.Height
; j
++)
3929 if (memcmp((const BYTE
*)data
.Scan0
+ j
* data
.Stride
, td
[i
].pixels
+ j
* data
.Stride
, width_bytes
) != 0)
3935 if ((td
[i
].mode
& (ImageLockModeRead
|ImageLockModeUserInputBuf
)) || td
[i
].format
== PixelFormat24bppRGB
)
3938 "%u: data should match\n", i
);
3941 BYTE
*bits
= data
.Scan0
;
3942 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
3943 for (j
= 0; j
< td
[i
].size
; j
++)
3944 trace(" %02x", bits
[j
]);
3949 ok(!match
, "%u: data shouldn't match\n", i
);
3951 memset(data
.Scan0
, 0, td
[i
].size
);
3954 status
= GdipBitmapUnlockBits(bitmap
, &data
);
3955 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
3957 memset(&data
, 0xfe, sizeof(data
));
3958 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
3959 ok(status
== Ok
, "%u: GdipBitmapLockBits error %d\n", i
, status
);
3960 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
3961 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
3962 ok(data
.Stride
== 24, "%u: expected 24, got %d\n", i
, data
.Stride
);
3963 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "%u: got wrong pixel format %d\n", i
, data
.PixelFormat
);
3964 ok(data
.Height
* data
.Stride
== 48, "%u: expected 48, got %d\n", i
, data
.Height
* data
.Stride
);
3965 if (data
.Height
* data
.Stride
== 48)
3967 int match
= memcmp(data
.Scan0
, td
[i
].pixels_unlocked
, 48) == 0;
3968 ok(match
, "%u: data should match\n", i
);
3972 BYTE
*bits
= data
.Scan0
;
3973 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
3974 for (j
= 0; j
< 48; j
++)
3975 trace(" %02x", bits
[j
]);
3980 status
= GdipBitmapUnlockBits(bitmap
, &data
);
3981 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
3983 status
= GdipDisposeImage((GpImage
*)bitmap
);
3988 static void test_DrawImage(void)
3990 BYTE black_1x1
[4] = { 0,0,0,0 };
3991 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
3992 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
3993 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
3994 0,0,0,0,0,0,0xff,0xff };
4001 GpGraphics
*graphics
;
4004 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
4006 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4009 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
4011 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
4013 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4015 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4018 status
= GdipDrawImageI(graphics
, u1
.image
, 0, 0);
4021 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
4022 ok(match
, "data should match\n");
4025 UINT i
, size
= sizeof(white_2x2
);
4026 BYTE
*bits
= white_2x2
;
4027 for (i
= 0; i
< size
; i
++)
4028 trace(" %02x", bits
[i
]);
4032 status
= GdipDeleteGraphics(graphics
);
4034 status
= GdipDisposeImage(u1
.image
);
4036 status
= GdipDisposeImage(u2
.image
);
4040 static void test_DrawImage_SourceCopy(void)
4042 DWORD dst_pixels
[4] = { 0xffffffff, 0xffffffff,
4043 0xffffffff, 0xffffffff };
4044 DWORD src_pixels
[4] = { 0, 0xffff0000,
4053 GpGraphics
*graphics
;
4055 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB
, (BYTE
*)dst_pixels
, &u1
.bitmap
);
4058 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB
, (BYTE
*)src_pixels
, &u2
.bitmap
);
4060 status
= GdipGetImageGraphicsContext(u1
.image
, &graphics
);
4062 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4065 status
= GdipSetCompositingMode(graphics
, CompositingModeSourceCopy
);
4068 status
= GdipDrawImageI(graphics
, u2
.image
, 0, 0);
4071 todo_wine
expect(0, dst_pixels
[0]);
4072 expect(0xffff0000, dst_pixels
[1]);
4073 todo_wine
expect(0, dst_pixels
[2]);
4074 todo_wine
expect(0, dst_pixels
[3]);
4076 status
= GdipDeleteGraphics(graphics
);
4078 status
= GdipDisposeImage(u1
.image
);
4080 status
= GdipDisposeImage(u2
.image
);
4084 static void test_GdipDrawImagePointRect(void)
4086 BYTE black_1x1
[4] = { 0,0,0,0 };
4087 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
4088 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
4089 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
4090 0,0,0,0,0,0,0xff,0xff };
4097 GpGraphics
*graphics
;
4100 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
4102 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4105 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
4107 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
4109 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4111 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4114 status
= GdipDrawImagePointRectI(graphics
, u1
.image
, 0, 0, 0, 0, 1, 1, UnitPixel
);
4117 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
4118 ok(match
, "data should match\n");
4121 UINT i
, size
= sizeof(white_2x2
);
4122 BYTE
*bits
= white_2x2
;
4123 for (i
= 0; i
< size
; i
++)
4124 trace(" %02x", bits
[i
]);
4128 status
= GdipDeleteGraphics(graphics
);
4130 status
= GdipDisposeImage(u1
.image
);
4132 status
= GdipDisposeImage(u2
.image
);
4136 static void test_image_format(void)
4138 static const PixelFormat fmt
[] =
4140 PixelFormat1bppIndexed
, PixelFormat4bppIndexed
, PixelFormat8bppIndexed
,
4141 PixelFormat16bppGrayScale
, PixelFormat16bppRGB555
, PixelFormat16bppRGB565
,
4142 PixelFormat16bppARGB1555
, PixelFormat24bppRGB
, PixelFormat32bppRGB
,
4143 PixelFormat32bppARGB
, PixelFormat32bppPARGB
, PixelFormat48bppRGB
,
4144 PixelFormat64bppARGB
, PixelFormat64bppPARGB
, PixelFormat32bppCMYK
4155 for (i
= 0; i
< sizeof(fmt
)/sizeof(fmt
[0]); i
++)
4157 status
= GdipCreateBitmapFromScan0(1, 1, 0, fmt
[i
], NULL
, &bitmap
);
4158 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* before win7 */,
4159 "GdipCreateBitmapFromScan0 error %d\n", status
);
4160 if (status
!= Ok
) continue;
4162 status
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
4164 expect(fmt
[i
], format
);
4166 status
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
4167 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4168 todo_wine
expect(InvalidParameter
, status
);
4172 ret
= GetObjectW(hbitmap
, sizeof(bm
), &bm
);
4173 expect(sizeof(bm
), ret
);
4174 expect(0, bm
.bmType
);
4175 expect(1, bm
.bmWidth
);
4176 expect(1, bm
.bmHeight
);
4177 expect(4, bm
.bmWidthBytes
);
4178 expect(1, bm
.bmPlanes
);
4179 expect(32, bm
.bmBitsPixel
);
4180 DeleteObject(hbitmap
);
4183 status
= GdipGetImageThumbnail((GpImage
*)bitmap
, 0, 0, &thumb
, NULL
, NULL
);
4184 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4186 ok(status
== OutOfMemory
|| broken(status
== InvalidParameter
) /* before win7 */,
4187 "expected OutOfMemory, got %d\n", status
);
4192 status
= GdipGetImagePixelFormat(thumb
, &format
);
4194 ok(format
== PixelFormat32bppPARGB
|| broken(format
!= PixelFormat32bppPARGB
) /* before win7 */,
4195 "expected PixelFormat32bppPARGB, got %#x\n", format
);
4196 status
= GdipDisposeImage(thumb
);
4200 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4201 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4202 todo_wine
expect(InvalidParameter
, status
);
4206 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4210 status
= GdipDisposeImage((GpImage
*)bitmap
);
4215 static void test_DrawImage_scale(void)
4217 static const BYTE back_8x1
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
4218 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4219 static const BYTE image_080
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,
4220 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4221 static const BYTE image_100
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,
4222 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4223 static const BYTE image_120
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,
4224 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4225 static const BYTE image_150
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4226 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4227 static const BYTE image_180
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4228 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4229 static const BYTE image_200
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4230 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4231 static const BYTE image_250
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,
4232 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4233 static const BYTE image_120_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4234 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4235 static const BYTE image_150_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4236 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4237 static const BYTE image_200_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4238 0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40 };
4239 static const BYTE image_250_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4240 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4241 static const struct test_data
4244 PixelOffsetMode pixel_offset_mode
;
4249 { 0.8, PixelOffsetModeNone
, image_080
}, /* 0 */
4250 { 1.0, PixelOffsetModeNone
, image_100
},
4251 { 1.2, PixelOffsetModeNone
, image_120
},
4252 { 1.5, PixelOffsetModeNone
, image_150
},
4253 { 1.8, PixelOffsetModeNone
, image_180
},
4254 { 2.0, PixelOffsetModeNone
, image_200
},
4255 { 2.5, PixelOffsetModeNone
, image_250
},
4257 { 0.8, PixelOffsetModeHighSpeed
, image_080
}, /* 7 */
4258 { 1.0, PixelOffsetModeHighSpeed
, image_100
},
4259 { 1.2, PixelOffsetModeHighSpeed
, image_120
},
4260 { 1.5, PixelOffsetModeHighSpeed
, image_150
},
4261 { 1.8, PixelOffsetModeHighSpeed
, image_180
},
4262 { 2.0, PixelOffsetModeHighSpeed
, image_200
},
4263 { 2.5, PixelOffsetModeHighSpeed
, image_250
},
4265 { 0.8, PixelOffsetModeHalf
, image_080
}, /* 14 */
4266 { 1.0, PixelOffsetModeHalf
, image_100
},
4267 { 1.2, PixelOffsetModeHalf
, image_120_half
, TRUE
},
4268 { 1.5, PixelOffsetModeHalf
, image_150_half
, TRUE
},
4269 { 1.8, PixelOffsetModeHalf
, image_180
},
4270 { 2.0, PixelOffsetModeHalf
, image_200_half
, TRUE
},
4271 { 2.5, PixelOffsetModeHalf
, image_250_half
, TRUE
},
4273 { 0.8, PixelOffsetModeHighQuality
, image_080
}, /* 21 */
4274 { 1.0, PixelOffsetModeHighQuality
, image_100
},
4275 { 1.2, PixelOffsetModeHighQuality
, image_120_half
, TRUE
},
4276 { 1.5, PixelOffsetModeHighQuality
, image_150_half
, TRUE
},
4277 { 1.8, PixelOffsetModeHighQuality
, image_180
},
4278 { 2.0, PixelOffsetModeHighQuality
, image_200_half
, TRUE
},
4279 { 2.5, PixelOffsetModeHighQuality
, image_250_half
, TRUE
},
4281 BYTE src_2x1
[6] = { 0x80,0x80,0x80,0x80,0x80,0x80 };
4289 GpGraphics
*graphics
;
4293 status
= GdipCreateBitmapFromScan0(2, 1, 4, PixelFormat24bppRGB
, src_2x1
, &u1
.bitmap
);
4295 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4298 status
= GdipCreateBitmapFromScan0(8, 1, 24, PixelFormat24bppRGB
, dst_8x1
, &u2
.bitmap
);
4300 status
= GdipBitmapSetResolution(u2
.bitmap
, 100.0, 100.0);
4302 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4304 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4307 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
4309 status
= GdipSetPixelOffsetMode(graphics
, td
[i
].pixel_offset_mode
);
4312 status
= GdipCreateMatrix2(td
[i
].scale_x
, 0.0, 0.0, 1.0, 0.0, 0.0, &matrix
);
4314 status
= GdipSetWorldTransform(graphics
, matrix
);
4316 GdipDeleteMatrix(matrix
);
4318 memcpy(dst_8x1
, back_8x1
, sizeof(dst_8x1
));
4319 status
= GdipDrawImageI(graphics
, u1
.image
, 1, 0);
4322 match
= memcmp(dst_8x1
, td
[i
].image
, sizeof(dst_8x1
)) == 0;
4323 todo_wine_if (!match
&& td
[i
].todo
)
4324 ok(match
, "%d: data should match\n", i
);
4327 UINT i
, size
= sizeof(dst_8x1
);
4328 const BYTE
*bits
= dst_8x1
;
4329 for (i
= 0; i
< size
; i
++)
4330 trace(" %02x", bits
[i
]);
4335 status
= GdipDeleteGraphics(graphics
);
4337 status
= GdipDisposeImage(u1
.image
);
4339 status
= GdipDisposeImage(u2
.image
);
4343 static const BYTE animatedgif
[] = {
4344 'G','I','F','8','9','a',0x01,0x00,0x01,0x00,0xA1,0x02,0x00,
4345 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
4346 /*0x21,0xFF,0x0B,'A','N','I','M','E','X','T','S','1','.','0',*/
4347 0x21,0xFF,0x0B,'N','E','T','S','C','A','P','E','2','.','0',
4348 0x03,0x01,0x05,0x00,0x00,
4349 0x21,0xFE,0x0C,'H','e','l','l','o',' ','W','o','r','l','d','!',0x00,
4350 0x21,0x01,0x0D,'a','n','i','m','a','t','i','o','n','.','g','i','f',0x00,
4351 0x21,0xF9,0x04,0xff,0x0A,0x00,0x08,0x00,
4352 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4353 0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,
4354 0x02,0x02,0x4C,0x01,0x00,
4355 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','1',0x00,
4356 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','1',0x00,
4357 0x21,0xF9,0x04,0x00,0x14,0x00,0x01,0x00,
4358 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4359 0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,
4360 0x02,0x02,0x44,0x01,0x00,
4361 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','2',0x00,
4362 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','2',0x00,0x3B
4365 static void test_gif_properties(void)
4367 static const struct test_data
4369 ULONG type
, id
, length
;
4370 const BYTE value
[13];
4373 { PropertyTagTypeLong
, PropertyTagFrameDelay
, 8, { 10,0,0,0,20,0,0,0 } },
4374 { PropertyTagTypeASCII
, PropertyTagExifUserComment
, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
4375 { PropertyTagTypeShort
, PropertyTagLoopCount
, 2, { 5,0 } },
4376 { PropertyTagTypeByte
, PropertyTagGlobalPalette
, 12, { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c } },
4377 { PropertyTagTypeByte
, PropertyTagIndexBackground
, 1, { 2 } },
4378 { PropertyTagTypeByte
, PropertyTagIndexTransparent
, 1, { 8 } }
4383 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
4384 UINT total_size
, total_count
;
4386 PropertyItem
*prop_item
;
4387 const char *item_data
;
4389 image
= load_image(animatedgif
, sizeof(animatedgif
));
4390 if (!image
) /* XP fails to load this GIF image */
4392 trace("Failed to load GIF image data\n");
4396 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
4398 expect(1, dim_count
);
4400 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
4402 expect_guid(&FrameDimensionTime
, &guid
, __LINE__
, FALSE
);
4404 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
4406 expect(2, frame_count
);
4408 status
= GdipImageSelectActiveFrame(image
, &guid
, 1);
4411 status
= GdipGetPropertyCount(image
, &prop_count
);
4413 ok(prop_count
== sizeof(td
)/sizeof(td
[0]) || broken(prop_count
== 1) /* before win7 */,
4414 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
4416 if (prop_count
!= sizeof(td
)/sizeof(td
[0]))
4418 GdipDisposeImage(image
);
4422 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
4424 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
4428 for (i
= 0; i
< prop_count
; i
++)
4431 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
4433 if (status
!= Ok
) break;
4434 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
4438 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
4439 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
4441 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
4442 ok(td
[i
].type
== prop_item
->type
,
4443 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
4444 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
4445 size
-= sizeof(*prop_item
);
4446 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
4447 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
4448 if (td
[i
].length
== prop_item
->length
)
4450 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
4451 ok(match
, "%u: data mismatch\n", i
);
4455 BYTE
*data
= prop_item
->value
;
4456 trace("id %#x:", prop_item
->id
);
4457 for (j
= 0; j
< prop_item
->length
; j
++)
4458 trace(" %02x", data
[j
]);
4462 HeapFree(GetProcessHeap(), 0, prop_item
);
4465 HeapFree(GetProcessHeap(), 0, prop_id
);
4467 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
4468 expect(InvalidParameter
, status
);
4469 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
4470 expect(InvalidParameter
, status
);
4471 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
4472 expect(InvalidParameter
, status
);
4473 status
= GdipGetPropertySize(image
, NULL
, NULL
);
4474 expect(InvalidParameter
, status
);
4475 total_size
= 0xdeadbeef;
4476 total_count
= 0xdeadbeef;
4477 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
4479 ok(prop_count
== total_count
,
4480 "expected total property count %u, got %u\n", prop_count
, total_count
);
4481 ok(prop_size
== total_size
,
4482 "expected total property size %u, got %u\n", prop_size
, total_size
);
4484 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
4486 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
4487 expect(InvalidParameter
, status
);
4488 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
4489 expect(InvalidParameter
, status
);
4490 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4491 expect(InvalidParameter
, status
);
4492 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4493 expect(InvalidParameter
, status
);
4494 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
4495 expect(InvalidParameter
, status
);
4496 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
4497 expect(InvalidParameter
, status
);
4498 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
4501 item_data
= (const char *)(prop_item
+ prop_count
);
4502 for (i
= 0; i
< prop_count
; i
++)
4504 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
4505 i
, item_data
, prop_item
[i
].value
);
4506 ok(td
[i
].type
== prop_item
[i
].type
,
4507 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
4508 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
4509 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
4510 if (td
[i
].length
== prop_item
[i
].length
)
4512 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
4513 ok(match
, "%u: data mismatch\n", i
);
4517 BYTE
*data
= prop_item
[i
].value
;
4518 trace("id %#x:", prop_item
[i
].id
);
4519 for (j
= 0; j
< prop_item
[i
].length
; j
++)
4520 trace(" %02x", data
[j
]);
4524 item_data
+= prop_item
[i
].length
;
4527 HeapFree(GetProcessHeap(), 0, prop_item
);
4529 GdipDisposeImage(image
);
4532 static void test_ARGB_conversion(void)
4534 BYTE argb
[8] = { 0x11,0x22,0x33,0x80, 0xff,0xff,0xff,0 };
4535 BYTE pargb
[8] = { 0x09,0x11,0x1a,0x80, 0,0,0,0 };
4536 BYTE rgb32_xp
[8] = { 0x11,0x22,0x33,0xff, 0xff,0xff,0xff,0xff };
4537 BYTE rgb24
[6] = { 0x11,0x22,0x33, 0xff,0xff,0xff };
4544 status
= GdipCreateBitmapFromScan0(2, 1, 8, PixelFormat32bppARGB
, argb
, &bitmap
);
4547 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4549 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4550 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4551 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4552 ok(data
.PixelFormat
== PixelFormat32bppPARGB
, "expected PixelFormat32bppPARGB, got %d\n", data
.PixelFormat
);
4553 match
= !memcmp(data
.Scan0
, pargb
, sizeof(pargb
));
4554 ok(match
, "bits don't match\n");
4558 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppPARGB
,
4559 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4561 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4564 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppRGB
, &data
);
4566 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4567 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4568 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4569 ok(data
.PixelFormat
== PixelFormat32bppRGB
, "expected PixelFormat32bppRGB, got %d\n", data
.PixelFormat
);
4570 match
= !memcmp(data
.Scan0
, argb
, sizeof(argb
)) ||
4571 !memcmp(data
.Scan0
, rgb32_xp
, sizeof(rgb32_xp
));
4572 ok(match
, "bits don't match\n");
4576 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppRGB
,
4577 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4579 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4582 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
4584 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4585 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4586 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4587 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "expected PixelFormat24bppRGB, got %d\n", data
.PixelFormat
);
4588 match
= !memcmp(data
.Scan0
, rgb24
, sizeof(rgb24
));
4589 ok(match
, "bits don't match\n");
4593 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat24bppRGB
,
4594 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4596 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4599 GdipDisposeImage((GpImage
*)bitmap
);
4603 static void test_CloneBitmapArea(void)
4606 GpBitmap
*bitmap
, *copy
;
4607 BitmapData data
, data2
;
4609 status
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB
, NULL
, &bitmap
);
4612 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
| ImageLockModeWrite
, PixelFormat24bppRGB
, &data
);
4615 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data2
);
4616 expect(WrongState
, status
);
4618 status
= GdipCloneBitmapAreaI(0, 0, 1, 1, PixelFormat24bppRGB
, bitmap
, ©
);
4621 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4624 GdipDisposeImage((GpImage
*)copy
);
4625 GdipDisposeImage((GpImage
*)bitmap
);
4628 static BOOL
get_encoder_clsid(LPCWSTR mime
, GUID
*format
, CLSID
*clsid
)
4631 UINT n_codecs
, info_size
, i
;
4632 ImageCodecInfo
*info
;
4635 status
= GdipGetImageEncodersSize(&n_codecs
, &info_size
);
4638 info
= GdipAlloc(info_size
);
4640 status
= GdipGetImageEncoders(n_codecs
, info_size
, info
);
4643 for (i
= 0; i
< n_codecs
; i
++)
4645 if (!lstrcmpW(info
[i
].MimeType
, mime
))
4647 *format
= info
[i
].FormatID
;
4648 *clsid
= info
[i
].Clsid
;
4658 static void test_supported_encoders(void)
4660 static const WCHAR bmp_mimetype
[] = { 'i', 'm', 'a','g', 'e', '/', 'b', 'm', 'p',0 };
4661 static const WCHAR jpeg_mimetype
[] = { 'i','m','a','g','e','/','j','p','e','g',0 };
4662 static const WCHAR gif_mimetype
[] = { 'i','m','a','g','e','/','g','i','f',0 };
4663 static const WCHAR tiff_mimetype
[] = { 'i','m','a','g','e','/','t','i','f','f',0 };
4664 static const WCHAR png_mimetype
[] = { 'i','m','a','g','e','/','p','n','g',0 };
4665 static const struct test_data
4672 { bmp_mimetype
, &ImageFormatBMP
, FALSE
},
4673 { jpeg_mimetype
, &ImageFormatJPEG
, FALSE
},
4674 { gif_mimetype
, &ImageFormatGIF
, TRUE
},
4675 { tiff_mimetype
, &ImageFormatTIFF
, FALSE
},
4676 { png_mimetype
, &ImageFormatPNG
, FALSE
}
4687 status
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB
, NULL
, &bm
);
4688 ok(status
== Ok
, "GdipCreateBitmapFromScan0 error %d\n", status
);
4690 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
4692 ret
= get_encoder_clsid(td
[i
].mime
, &format
, &clsid
);
4693 ok(ret
, "%s encoder is not in the list\n", wine_dbgstr_w(td
[i
].mime
));
4694 expect_guid(td
[i
].format
, &format
, __LINE__
, FALSE
);
4696 hmem
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_NODISCARD
, 16);
4698 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
4699 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
4701 status
= GdipSaveImageToStream((GpImage
*)bm
, stream
, &clsid
, NULL
);
4702 todo_wine_if (td
[i
].todo
)
4703 ok(status
== Ok
, "GdipSaveImageToStream error %d\n", status
);
4705 IStream_Release(stream
);
4708 GdipDisposeImage((GpImage
*)bm
);
4711 static void test_createeffect(void)
4713 static const GUID noneffect
= { 0xcd0c3d4b, 0xe15e, 0x4cf2, { 0x9e, 0xa8, 0x6e, 0x1d, 0x65, 0x48, 0xc5, 0xa5 } };
4714 GpStatus (WINAPI
*pGdipCreateEffect
)( const GUID guid
, CGpEffect
**effect
);
4715 GpStatus (WINAPI
*pGdipDeleteEffect
)( CGpEffect
*effect
);
4718 HMODULE mod
= GetModuleHandleA("gdiplus.dll");
4720 const GUID
* const effectlist
[] =
4721 {&BlurEffectGuid
, &SharpenEffectGuid
, &ColorMatrixEffectGuid
, &ColorLUTEffectGuid
,
4722 &BrightnessContrastEffectGuid
, &HueSaturationLightnessEffectGuid
, &LevelsEffectGuid
,
4723 &TintEffectGuid
, &ColorBalanceEffectGuid
, &RedEyeCorrectionEffectGuid
, &ColorCurveEffectGuid
};
4725 pGdipCreateEffect
= (void*)GetProcAddress( mod
, "GdipCreateEffect");
4726 pGdipDeleteEffect
= (void*)GetProcAddress( mod
, "GdipDeleteEffect");
4727 if(!pGdipCreateEffect
|| !pGdipDeleteEffect
)
4729 /* GdipCreateEffect/GdipDeleteEffect was introduced in Windows Vista. */
4730 win_skip("GDIPlus version 1.1 not available\n");
4734 stat
= pGdipCreateEffect(BlurEffectGuid
, NULL
);
4735 expect(InvalidParameter
, stat
);
4737 stat
= pGdipCreateEffect(noneffect
, &effect
);
4738 todo_wine
expect(Win32Error
, stat
);
4740 for(i
=0; i
< sizeof(effectlist
) / sizeof(effectlist
[0]); i
++)
4742 stat
= pGdipCreateEffect(*effectlist
[i
], &effect
);
4743 todo_wine
expect(Ok
, stat
);
4746 stat
= pGdipDeleteEffect(effect
);
4752 static void test_getadjustedpalette(void)
4755 GpImageAttributes
*imageattributes
;
4756 ColorPalette
*palette
;
4759 stat
= GdipCreateImageAttributes(&imageattributes
);
4762 colormap
.oldColor
.Argb
= 0xffffff00;
4763 colormap
.newColor
.Argb
= 0xffff00ff;
4764 stat
= GdipSetImageAttributesRemapTable(imageattributes
, ColorAdjustTypeBitmap
,
4765 TRUE
, 1, &colormap
);
4768 colormap
.oldColor
.Argb
= 0xffffff80;
4769 colormap
.newColor
.Argb
= 0xffff80ff;
4770 stat
= GdipSetImageAttributesRemapTable(imageattributes
, ColorAdjustTypeDefault
,
4771 TRUE
, 1, &colormap
);
4774 palette
= GdipAlloc(sizeof(*palette
) + sizeof(ARGB
) * 2);
4777 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeBitmap
);
4778 expect(InvalidParameter
, stat
);
4781 palette
->Entries
[0] = 0xffffff00;
4782 palette
->Entries
[1] = 0xffffff80;
4783 palette
->Entries
[2] = 0xffffffff;
4785 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeBitmap
);
4787 expect(0xffff00ff, palette
->Entries
[0]);
4788 expect(0xffffff80, palette
->Entries
[1]);
4789 expect(0xffffffff, palette
->Entries
[2]);
4791 palette
->Entries
[0] = 0xffffff00;
4792 palette
->Entries
[1] = 0xffffff80;
4793 palette
->Entries
[2] = 0xffffffff;
4795 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeBrush
);
4797 expect(0xffffff00, palette
->Entries
[0]);
4798 expect(0xffff80ff, palette
->Entries
[1]);
4799 expect(0xffffffff, palette
->Entries
[2]);
4801 stat
= GdipGetImageAttributesAdjustedPalette(NULL
, palette
, ColorAdjustTypeBitmap
);
4802 expect(InvalidParameter
, stat
);
4804 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, NULL
, ColorAdjustTypeBitmap
);
4805 expect(InvalidParameter
, stat
);
4807 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, -1);
4808 expect(InvalidParameter
, stat
);
4810 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeDefault
);
4811 expect(InvalidParameter
, stat
);
4814 GdipDisposeImageAttributes(imageattributes
);
4817 static void test_histogram(void)
4819 UINT ch0
[256], ch1
[256], ch2
[256], ch3
[256];
4820 HistogramFormat test_formats
[] =
4822 HistogramFormatARGB
,
4823 HistogramFormatPARGB
,
4825 HistogramFormatGray
,
4831 const UINT WIDTH
= 8, HEIGHT
= 16;
4836 if (!pGdipBitmapGetHistogramSize
)
4838 win_skip("GdipBitmapGetHistogramSize is not supported\n");
4842 stat
= pGdipBitmapGetHistogramSize(HistogramFormatARGB
, NULL
);
4843 expect(InvalidParameter
, stat
);
4845 stat
= pGdipBitmapGetHistogramSize(0xff, NULL
);
4846 expect(InvalidParameter
, stat
);
4849 stat
= pGdipBitmapGetHistogramSize(10, &num
);
4853 for (i
= 0; i
< sizeof(test_formats
)/sizeof(test_formats
[0]); i
++)
4856 stat
= pGdipBitmapGetHistogramSize(test_formats
[i
], &num
);
4862 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
4865 /* Three solid rgb rows, next three rows are rgb shades. */
4866 for (x
= 0; x
< WIDTH
; x
++)
4868 GdipBitmapSetPixel(bm
, x
, 0, 0xffff0000);
4869 GdipBitmapSetPixel(bm
, x
, 1, 0xff00ff00);
4870 GdipBitmapSetPixel(bm
, x
, 2, 0xff0000ff);
4872 GdipBitmapSetPixel(bm
, x
, 3, 0xff010000);
4873 GdipBitmapSetPixel(bm
, x
, 4, 0xff003f00);
4874 GdipBitmapSetPixel(bm
, x
, 5, 0xff000020);
4877 stat
= pGdipBitmapGetHistogram(NULL
, HistogramFormatRGB
, 256, ch0
, ch1
, ch2
, ch3
);
4878 expect(InvalidParameter
, stat
);
4880 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, ch1
, ch2
, ch3
);
4881 expect(InvalidParameter
, stat
);
4883 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, ch1
, ch2
, NULL
);
4884 expect(InvalidParameter
, stat
);
4886 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, ch1
, NULL
, NULL
);
4887 expect(InvalidParameter
, stat
);
4889 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, NULL
, NULL
, NULL
);
4890 expect(InvalidParameter
, stat
);
4892 /* Requested format matches bitmap format */
4893 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 256, ch0
, ch1
, ch2
, ch3
);
4894 expect(InvalidParameter
, stat
);
4896 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 100, ch0
, ch1
, ch2
, NULL
);
4897 expect(InvalidParameter
, stat
);
4899 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 257, ch0
, ch1
, ch2
, NULL
);
4900 expect(InvalidParameter
, stat
);
4902 /* Channel 3 is not used, must be NULL */
4903 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 256, ch0
, ch1
, ch2
, NULL
);
4906 ok(ch0
[0xff] == WIDTH
, "Got red (0xff) %u\n", ch0
[0xff]);
4907 ok(ch1
[0xff] == WIDTH
, "Got green (0xff) %u\n", ch1
[0xff]);
4908 ok(ch2
[0xff] == WIDTH
, "Got blue (0xff) %u\n", ch1
[0xff]);
4909 ok(ch0
[0x01] == WIDTH
, "Got red (0x01) %u\n", ch0
[0x01]);
4910 ok(ch1
[0x3f] == WIDTH
, "Got green (0x3f) %u\n", ch1
[0x3f]);
4911 ok(ch2
[0x20] == WIDTH
, "Got blue (0x20) %u\n", ch1
[0x20]);
4913 /* ARGB histogram from RGB data. */
4914 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatARGB
, 256, ch0
, ch1
, ch2
, NULL
);
4915 expect(InvalidParameter
, stat
);
4917 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatARGB
, 256, ch0
, ch1
, ch2
, ch3
);
4920 ok(ch1
[0xff] == WIDTH
, "Got red (0xff) %u\n", ch1
[0xff]);
4921 ok(ch2
[0xff] == WIDTH
, "Got green (0xff) %u\n", ch2
[0xff]);
4922 ok(ch3
[0xff] == WIDTH
, "Got blue (0xff) %u\n", ch3
[0xff]);
4923 ok(ch1
[0x01] == WIDTH
, "Got red (0x01) %u\n", ch1
[0x01]);
4924 ok(ch2
[0x3f] == WIDTH
, "Got green (0x3f) %u\n", ch2
[0x3f]);
4925 ok(ch3
[0x20] == WIDTH
, "Got blue (0x20) %u\n", ch3
[0x20]);
4927 ok(ch0
[0xff] == WIDTH
* HEIGHT
, "Got alpha (0xff) %u\n", ch0
[0xff]);
4929 /* Request grayscale histogram from RGB bitmap. */
4930 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, ch1
, ch2
, ch3
);
4931 expect(InvalidParameter
, stat
);
4933 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, ch1
, ch2
, NULL
);
4934 expect(InvalidParameter
, stat
);
4936 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, ch1
, NULL
, NULL
);
4937 expect(InvalidParameter
, stat
);
4939 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, NULL
, NULL
, NULL
);
4942 GdipDisposeImage((GpImage
*)bm
);
4945 static void test_imageabort(void)
4950 if (!pGdipImageSetAbort
)
4952 win_skip("GdipImageSetAbort() is not supported.\n");
4957 stat
= GdipCreateBitmapFromScan0(8, 8, 0, PixelFormat24bppRGB
, NULL
, &bm
);
4960 stat
= pGdipImageSetAbort(NULL
, NULL
);
4961 expect(InvalidParameter
, stat
);
4963 stat
= pGdipImageSetAbort((GpImage
*)bm
, NULL
);
4966 GdipDisposeImage((GpImage
*)bm
);
4969 /* RGB 24 bpp 1x1 pixel PNG image */
4970 static const char png_1x1_data
[] = {
4971 0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,
4972 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,
4973 0x00,0x00,0x00,0x0c,'I','D','A','T',0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,0xe7,
4974 0x00,0x00,0x00,0x00,'I','E','N','D',0xae,0x42,0x60,0x82
4977 static void test_png_color_formats(void)
4981 char bit_depth
, color_type
;
4985 /* 2 - PNG_COLOR_TYPE_RGB */
4986 { 8, 2, PixelFormat24bppRGB
},
4987 /* 0 - PNG_COLOR_TYPE_GRAY */
4988 { 1, 0, PixelFormat1bppIndexed
},
4989 { 2, 0, PixelFormat32bppARGB
},
4990 { 4, 0, PixelFormat32bppARGB
},
4991 { 8, 0, PixelFormat32bppARGB
},
4992 { 16, 0, PixelFormat32bppARGB
},
4994 BYTE buf
[sizeof(png_1x1_data
)];
5001 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
5003 memcpy(buf
, png_1x1_data
, sizeof(png_1x1_data
));
5004 buf
[24] = td
[i
].bit_depth
;
5005 buf
[25] = td
[i
].color_type
;
5007 image
= load_image(buf
, sizeof(buf
));
5008 ok(image
!= NULL
, "%d: failed to load image data\n", i
);
5009 if (!image
) continue;
5011 status
= GdipGetImageType(image
, &type
);
5012 ok(status
== Ok
, "%u: GdipGetImageType error %d\n", i
, status
);
5013 ok(type
== ImageTypeBitmap
, "%d: wrong image type %d\n", i
, type
);
5015 status
= GdipGetImagePixelFormat(image
, &format
);
5017 todo_wine_if(td
[i
].bit_depth
== 8 && td
[i
].color_type
== 0)
5018 ok(format
== td
[i
].format
||
5019 broken(td
[i
].bit_depth
== 1 && td
[i
].color_type
== 0 && format
== PixelFormat32bppARGB
), /* XP */
5020 "%d: expected %#x, got %#x\n", i
, td
[i
].format
, format
);
5022 GdipDisposeImage(image
);
5028 HMODULE mod
= GetModuleHandleA("gdiplus.dll");
5029 struct GdiplusStartupInput gdiplusStartupInput
;
5030 ULONG_PTR gdiplusToken
;
5032 int (CDECL
* _controlfp_s
)(unsigned int *cur
, unsigned int newval
, unsigned int mask
);
5034 /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */
5035 hmsvcrt
= LoadLibraryA("msvcrt");
5036 _controlfp_s
= (void*)GetProcAddress(hmsvcrt
, "_controlfp_s");
5037 if (_controlfp_s
) _controlfp_s(0, 0, 0x0008001e);
5039 gdiplusStartupInput
.GdiplusVersion
= 1;
5040 gdiplusStartupInput
.DebugEventCallback
= NULL
;
5041 gdiplusStartupInput
.SuppressBackgroundThread
= 0;
5042 gdiplusStartupInput
.SuppressExternalCodecs
= 0;
5044 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, NULL
);
5046 pGdipBitmapGetHistogramSize
= (void*)GetProcAddress(mod
, "GdipBitmapGetHistogramSize");
5047 pGdipBitmapGetHistogram
= (void*)GetProcAddress(mod
, "GdipBitmapGetHistogram");
5048 pGdipImageSetAbort
= (void*)GetProcAddress(mod
, "GdipImageSetAbort");
5050 test_png_color_formats();
5051 test_supported_encoders();
5052 test_CloneBitmapArea();
5053 test_ARGB_conversion();
5054 test_DrawImage_scale();
5055 test_image_format();
5057 test_DrawImage_SourceCopy();
5058 test_GdipDrawImagePointRect();
5060 test_tiff_palette();
5061 test_GdipGetAllPropertyItems();
5062 test_tiff_properties();
5063 test_gif_properties();
5064 test_image_properties();
5067 test_GetImageDimension();
5068 test_GdipImageGetFrameDimensionsCount();
5069 test_LoadingImages();
5070 test_SavingImages();
5073 test_LockBits_UserBuf();
5074 test_GdipCreateBitmapFromHBITMAP();
5075 test_GdipGetImageFlags();
5076 test_GdipCloneImage();
5079 test_getrawformat();
5081 test_createfromwmf();
5082 test_createfromwmf_noplaceable();
5084 test_createhbitmap();
5085 test_getthumbnail();
5090 test_multiframegif();
5095 test_createeffect();
5096 test_getadjustedpalette();
5100 GdiplusShutdown(gdiplusToken
);