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
29 #define WIN32_NO_STATUS
31 #define COM_NO_WINDOWS_H
33 //#include "windows.h"
34 #include <wine/test.h>
40 /* FIXME: They belong to gdipluseffects.h */
41 DEFINE_GUID(BlurEffectGuid
, 0x633c80a4, 0x1843, 0x482b, 0x9e, 0xf2, 0xbe, 0x28, 0x34, 0xc5, 0xfd, 0xd4);
42 DEFINE_GUID(SharpenEffectGuid
, 0x63cbf3ee, 0xc526, 0x402c, 0x8f, 0x71, 0x62, 0xc5, 0x40, 0xbf, 0x51, 0x42);
43 DEFINE_GUID(ColorMatrixEffectGuid
, 0x718f2615, 0x7933, 0x40e3, 0xa5, 0x11, 0x5f, 0x68, 0xfe, 0x14, 0xdd, 0x74);
44 DEFINE_GUID(ColorLUTEffectGuid
, 0xa7ce72a9, 0x0f7f, 0x40d7, 0xb3, 0xcc, 0xd0, 0xc0, 0x2d, 0x5c, 0x32, 0x12);
45 DEFINE_GUID(BrightnessContrastEffectGuid
, 0xd3a1dbe1, 0x8ec4, 0x4c17, 0x9f, 0x4c, 0xea, 0x97, 0xad, 0x1c, 0x34, 0x3d);
46 DEFINE_GUID(HueSaturationLightnessEffectGuid
, 0x8b2dd6c3, 0xeb07, 0x4d87, 0xa5, 0xf0, 0x71, 0x08, 0xe2, 0x6a, 0x9c, 0x5f);
47 DEFINE_GUID(LevelsEffectGuid
, 0x99c354ec, 0x2a31, 0x4f3a, 0x8c, 0x34, 0x17, 0xa8, 0x03, 0xb3, 0x3a, 0x25);
48 DEFINE_GUID(TintEffectGuid
, 0x1077af00, 0x2848, 0x4441, 0x94, 0x89, 0x44, 0xad, 0x4c, 0x2d, 0x7a, 0x2c);
49 DEFINE_GUID(ColorBalanceEffectGuid
, 0x537e597d, 0x251e, 0x48da, 0x96, 0x64, 0x29, 0xca, 0x49, 0x6b, 0x70, 0xf8);
50 DEFINE_GUID(RedEyeCorrectionEffectGuid
, 0x74d29d05, 0x69a4, 0x4266, 0x95, 0x49, 0x3c, 0xc5, 0x28, 0x36, 0xb6, 0x32);
51 DEFINE_GUID(ColorCurveEffectGuid
, 0xdd6a0022, 0x58e4, 0x4a67, 0x9d, 0x9b, 0xd4, 0x8e, 0xb8, 0x81, 0xa5, 0x3d);
53 static GpStatus (WINAPI
*pGdipBitmapGetHistogramSize
)(HistogramFormat
,UINT
*);
54 static GpStatus (WINAPI
*pGdipBitmapGetHistogram
)(GpBitmap
*,HistogramFormat
,UINT
,UINT
*,UINT
*,UINT
*,UINT
*);
55 static GpStatus (WINAPI
*pGdipImageSetAbort
)(GpImage
*,GdiplusAbort
*);
57 static GpStatus (WINGDIPAPI
*pGdipInitializePalette
)(ColorPalette
*,PaletteType
,INT
,BOOL
,GpBitmap
*);
59 #define expect(expected, got) ok((got) == (expected), "Expected %d, got %d\n", (UINT)(expected), (UINT)(got))
60 #define expectf(expected, got) ok(fabs((expected) - (got)) < 0.0001, "Expected %f, got %f\n", (expected), (got))
62 static BOOL
color_match(ARGB c1
, ARGB c2
, BYTE max_diff
)
64 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
66 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
68 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
70 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
74 static void expect_guid(REFGUID expected
, REFGUID got
, int line
, BOOL todo
)
80 StringFromGUID2(got
, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]));
81 WideCharToMultiByte(CP_ACP
, 0, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]), buffer
, sizeof(buffer
), NULL
, NULL
);
82 StringFromGUID2(expected
, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]));
83 WideCharToMultiByte(CP_ACP
, 0, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]), buffer2
, sizeof(buffer2
), NULL
, NULL
);
85 ok_(__FILE__
, line
)(IsEqualGUID(expected
, got
), "Expected %s, got %s\n", buffer2
, buffer
);
88 static void expect_rawformat(REFGUID expected
, GpImage
*img
, int line
, BOOL todo
)
93 stat
= GdipGetImageRawFormat(img
, &raw
);
94 ok_(__FILE__
, line
)(stat
== Ok
, "GdipGetImageRawFormat failed with %d\n", stat
);
95 if(stat
!= Ok
) return;
96 expect_guid(expected
, &raw
, line
, todo
);
99 static void test_bufferrawformat(void* buff
, int size
, REFGUID expected
, int line
, BOOL todo
)
108 hglob
= GlobalAlloc (0, size
);
109 data
= GlobalLock (hglob
);
110 memcpy(data
, buff
, size
);
111 GlobalUnlock(hglob
); data
= NULL
;
113 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
114 ok_(__FILE__
, line
)(hres
== S_OK
, "Failed to create a stream\n");
115 if(hres
!= S_OK
) return;
117 stat
= GdipLoadImageFromStream(stream
, &img
);
118 ok_(__FILE__
, line
)(stat
== Ok
, "Failed to create a Bitmap\n");
120 IStream_Release(stream
);
124 expect_rawformat(expected
, img
, line
, todo
);
126 GdipDisposeImage(img
);
127 IStream_Release(stream
);
130 static void test_Scan0(void)
137 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, NULL
, &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
, NULL
, &bm
);
145 expect(InvalidParameter
, stat
);
146 ok( !bm
, "expected null bitmap\n" );
148 bm
= (GpBitmap
*)0xdeadbeef;
149 stat
= GdipCreateBitmapFromScan0(-10, 10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
150 expect(InvalidParameter
, stat
);
151 ok( !bm
, "expected null bitmap\n" );
153 bm
= (GpBitmap
*)0xdeadbeef;
154 stat
= GdipCreateBitmapFromScan0(10, 0, 10, PixelFormat24bppRGB
, NULL
, &bm
);
155 expect(InvalidParameter
, stat
);
156 ok( !bm
, "expected null bitmap\n" );
159 stat
= GdipCreateBitmapFromScan0(10, 10, 12, PixelFormat24bppRGB
, buff
, &bm
);
161 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
163 GdipDisposeImage((GpImage
*)bm
);
165 bm
= (GpBitmap
*) 0xdeadbeef;
166 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, buff
, &bm
);
167 expect(InvalidParameter
, stat
);
168 ok( !bm
, "expected null bitmap\n" );
170 bm
= (GpBitmap
*)0xdeadbeef;
171 stat
= GdipCreateBitmapFromScan0(10, 10, 0, PixelFormat24bppRGB
, buff
, &bm
);
172 expect(InvalidParameter
, stat
);
173 ok( bm
== (GpBitmap
*)0xdeadbeef, "expected deadbeef bitmap\n" );
176 stat
= GdipCreateBitmapFromScan0(10, 10, -8, PixelFormat24bppRGB
, buff
, &bm
);
178 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
180 GdipDisposeImage((GpImage
*)bm
);
182 bm
= (GpBitmap
*)0xdeadbeef;
183 stat
= GdipCreateBitmapFromScan0(10, 10, -10, PixelFormat24bppRGB
, buff
, &bm
);
184 expect(InvalidParameter
, stat
);
185 ok( !bm
, "expected null bitmap\n" );
188 static void test_FromGdiDib(void)
193 BYTE rbmi
[sizeof(BITMAPINFOHEADER
)+256*sizeof(RGBQUAD
)];
194 BITMAPINFO
*bmi
= (BITMAPINFO
*)rbmi
;
199 memset(rbmi
, 0, sizeof(rbmi
));
201 bmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
202 bmi
->bmiHeader
.biWidth
= 10;
203 bmi
->bmiHeader
.biHeight
= 10;
204 bmi
->bmiHeader
.biPlanes
= 1;
205 bmi
->bmiHeader
.biBitCount
= 32;
206 bmi
->bmiHeader
.biCompression
= BI_RGB
;
208 stat
= GdipCreateBitmapFromGdiDib(NULL
, buff
, &bm
);
209 expect(InvalidParameter
, stat
);
211 stat
= GdipCreateBitmapFromGdiDib(bmi
, NULL
, &bm
);
212 expect(InvalidParameter
, stat
);
214 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, NULL
);
215 expect(InvalidParameter
, stat
);
217 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
219 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
222 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
224 expect(PixelFormat32bppRGB
, format
);
226 GdipDisposeImage((GpImage
*)bm
);
229 bmi
->bmiHeader
.biBitCount
= 24;
230 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
232 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
235 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
237 expect(PixelFormat24bppRGB
, format
);
239 GdipDisposeImage((GpImage
*)bm
);
242 bmi
->bmiHeader
.biBitCount
= 16;
243 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
245 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
248 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
250 expect(PixelFormat16bppRGB555
, format
);
252 GdipDisposeImage((GpImage
*)bm
);
255 bmi
->bmiHeader
.biBitCount
= 8;
256 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
258 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
261 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
263 expect(PixelFormat8bppIndexed
, format
);
265 GdipDisposeImage((GpImage
*)bm
);
268 bmi
->bmiHeader
.biBitCount
= 4;
269 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
271 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
274 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
276 expect(PixelFormat4bppIndexed
, format
);
278 GdipDisposeImage((GpImage
*)bm
);
281 bmi
->bmiHeader
.biBitCount
= 1;
282 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
284 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
287 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
289 expect(PixelFormat1bppIndexed
, format
);
291 GdipDisposeImage((GpImage
*)bm
);
294 bmi
->bmiHeader
.biBitCount
= 0;
295 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
296 expect(InvalidParameter
, stat
);
299 static void test_GetImageDimension(void)
303 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
306 bm
= (GpBitmap
*)0xdeadbeef;
307 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
,NULL
, &bm
);
309 ok((GpBitmap
*)0xdeadbeef != bm
, "Expected bitmap to not be 0xdeadbeef\n");
310 ok(NULL
!= bm
, "Expected bitmap to not be NULL\n");
312 stat
= GdipGetImageDimension(NULL
,&w
,&h
);
313 expect(InvalidParameter
, stat
);
315 stat
= GdipGetImageDimension((GpImage
*)bm
,NULL
,&h
);
316 expect(InvalidParameter
, stat
);
318 stat
= GdipGetImageDimension((GpImage
*)bm
,&w
,NULL
);
319 expect(InvalidParameter
, stat
);
323 stat
= GdipGetImageDimension((GpImage
*)bm
,&w
,&h
);
327 GdipDisposeImage((GpImage
*)bm
);
330 static void test_GdipImageGetFrameDimensionsCount(void)
334 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
336 GUID dimension
= {0};
340 bm
= (GpBitmap
*)0xdeadbeef;
341 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
,NULL
, &bm
);
343 ok((GpBitmap
*)0xdeadbeef != bm
, "Expected bitmap to not be 0xdeadbeef\n");
344 ok(NULL
!= bm
, "Expected bitmap to not be NULL\n");
346 stat
= GdipImageGetFrameDimensionsCount(NULL
,&w
);
347 expect(InvalidParameter
, stat
);
349 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bm
,NULL
);
350 expect(InvalidParameter
, stat
);
353 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bm
,&w
);
357 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 1);
359 expect_guid(&FrameDimensionPage
, &dimension
, __LINE__
, FALSE
);
361 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 2);
362 expect(InvalidParameter
, stat
);
364 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 0);
365 expect(InvalidParameter
, stat
);
367 stat
= GdipImageGetFrameCount(NULL
, &dimension
, &count
);
368 expect(InvalidParameter
, stat
);
370 /* WinXP crashes on this test */
373 stat
= GdipImageGetFrameCount((GpImage
*)bm
, &dimension
, NULL
);
374 expect(InvalidParameter
, stat
);
377 stat
= GdipImageGetFrameCount((GpImage
*)bm
, NULL
, &count
);
381 stat
= GdipImageGetFrameCount((GpImage
*)bm
, &dimension
, &count
);
385 GdipBitmapSetPixel(bm
, 0, 0, 0xffffffff);
387 stat
= GdipImageSelectActiveFrame((GpImage
*)bm
, &dimension
, 0);
390 /* SelectActiveFrame has no effect on image data of memory bitmaps */
392 GdipBitmapGetPixel(bm
, 0, 0, &color
);
393 expect(0xffffffff, color
);
395 GdipDisposeImage((GpImage
*)bm
);
398 static void test_LoadingImages(void)
403 static const WCHAR nonexistentW
[] = {'n','o','n','e','x','i','s','t','e','n','t',0};
405 stat
= GdipCreateBitmapFromFile(0, 0);
406 expect(InvalidParameter
, stat
);
408 bm
= (GpBitmap
*)0xdeadbeef;
409 stat
= GdipCreateBitmapFromFile(0, &bm
);
410 expect(InvalidParameter
, stat
);
411 ok(bm
== (GpBitmap
*)0xdeadbeef, "returned %p\n", bm
);
413 bm
= (GpBitmap
*)0xdeadbeef;
414 stat
= GdipCreateBitmapFromFile(nonexistentW
, &bm
);
415 todo_wine
expect(InvalidParameter
, stat
);
416 ok(!bm
, "returned %p\n", bm
);
418 stat
= GdipLoadImageFromFile(0, 0);
419 expect(InvalidParameter
, stat
);
421 img
= (GpImage
*)0xdeadbeef;
422 stat
= GdipLoadImageFromFile(0, &img
);
423 expect(InvalidParameter
, stat
);
424 ok(img
== (GpImage
*)0xdeadbeef, "returned %p\n", img
);
426 img
= (GpImage
*)0xdeadbeef;
427 stat
= GdipLoadImageFromFile(nonexistentW
, &img
);
428 todo_wine
expect(OutOfMemory
, stat
);
429 ok(!img
, "returned %p\n", img
);
431 stat
= GdipLoadImageFromFileICM(0, 0);
432 expect(InvalidParameter
, stat
);
434 img
= (GpImage
*)0xdeadbeef;
435 stat
= GdipLoadImageFromFileICM(0, &img
);
436 expect(InvalidParameter
, stat
);
437 ok(img
== (GpImage
*)0xdeadbeef, "returned %p\n", img
);
439 img
= (GpImage
*)0xdeadbeef;
440 stat
= GdipLoadImageFromFileICM(nonexistentW
, &img
);
441 todo_wine
expect(OutOfMemory
, stat
);
442 ok(!img
, "returned %p\n", img
);
445 static void test_SavingImages(void)
451 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
453 ImageCodecInfo
*codecs
;
454 static const CHAR filenameA
[] = "a.bmp";
455 static const WCHAR filename
[] = { 'a','.','b','m','p',0 };
459 stat
= GdipSaveImageToFile(0, 0, 0, 0);
460 expect(InvalidParameter
, stat
);
463 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
469 stat
= GdipSaveImageToFile((GpImage
*)bm
, 0, 0, 0);
470 expect(InvalidParameter
, stat
);
472 stat
= GdipSaveImageToFile((GpImage
*)bm
, filename
, 0, 0);
473 expect(InvalidParameter
, stat
);
475 /* encoder tests should succeed -- already tested */
476 stat
= GdipGetImageEncodersSize(&n
, &s
);
477 if (stat
!= Ok
|| n
== 0) goto cleanup
;
479 codecs
= GdipAlloc(s
);
480 if (!codecs
) goto cleanup
;
482 stat
= GdipGetImageEncoders(n
, s
, codecs
);
483 if (stat
!= Ok
) goto cleanup
;
485 stat
= GdipSaveImageToFile((GpImage
*)bm
, filename
, &codecs
[0].Clsid
, 0);
488 GdipDisposeImage((GpImage
*)bm
);
491 /* re-load and check image stats */
492 stat
= GdipLoadImageFromFile(filename
, (GpImage
**)&bm
);
494 if (stat
!= Ok
) goto cleanup
;
496 stat
= GdipGetImageDimension((GpImage
*)bm
, &w
, &h
);
497 if (stat
!= Ok
) goto cleanup
;
505 GdipDisposeImage((GpImage
*)bm
);
506 ok(DeleteFileA(filenameA
), "Delete failed.\n");
509 static void test_encoders(void)
514 ImageCodecInfo
*codecs
;
518 static const CHAR bmp_format
[] = "BMP";
520 stat
= GdipGetImageEncodersSize(&n
, &s
);
523 codecs
= GdipAlloc(s
);
527 stat
= GdipGetImageEncoders(n
, s
, NULL
);
528 expect(GenericError
, stat
);
530 stat
= GdipGetImageEncoders(0, s
, codecs
);
531 expect(GenericError
, stat
);
533 stat
= GdipGetImageEncoders(n
, s
-1, codecs
);
534 expect(GenericError
, stat
);
536 stat
= GdipGetImageEncoders(n
, s
+1, codecs
);
537 expect(GenericError
, stat
);
539 stat
= GdipGetImageEncoders(n
, s
, codecs
);
543 for (i
= 0; i
< n
; i
++)
547 WideCharToMultiByte(CP_ACP
, 0, codecs
[i
].FormatDescription
, -1,
550 if (CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0,
552 bmp_format
, -1) == CSTR_EQUAL
) {
558 ok(FALSE
, "No BMP codec found.\n");
563 static void test_LockBits(void)
569 const INT WIDTH
= 10, HEIGHT
= 20;
574 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
582 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffc30000);
585 stat
= GdipBitmapSetPixel(bm
, 2, 8, 0xff480000);
589 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
593 expect(0xc3, ((BYTE
*)bd
.Scan0
)[2]);
594 expect(0x48, ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5]);
596 ((char*)bd
.Scan0
)[2] = 0xff;
598 stat
= GdipBitmapUnlockBits(bm
, &bd
);
602 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
604 expect(0xffff0000, color
);
606 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffc30000);
609 /* read-only, with NULL rect -> whole bitmap lock */
610 stat
= GdipBitmapLockBits(bm
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
612 expect(bd
.Width
, WIDTH
);
613 expect(bd
.Height
, HEIGHT
);
616 ((char*)bd
.Scan0
)[2 + 2*3 + 3*bd
.Stride
] = 0xff;
618 stat
= GdipBitmapUnlockBits(bm
, &bd
);
622 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
624 expect(0xffff0000, color
);
626 /* read-only, consecutive */
627 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
631 stat
= GdipBitmapUnlockBits(bm
, &bd
);
635 stat
= GdipDisposeImage((GpImage
*)bm
);
637 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
641 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
643 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
644 expect(WrongState
, stat
);
646 stat
= GdipBitmapUnlockBits(bm
, &bd
);
649 stat
= GdipDisposeImage((GpImage
*)bm
);
651 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
654 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffff0000);
657 stat
= GdipBitmapSetPixel(bm
, 2, 8, 0xffc30000);
660 /* write, no conversion */
661 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
665 /* all bits are readable, inside the rect or not */
666 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
667 expect(0xc3, ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5]);
669 stat
= GdipBitmapUnlockBits(bm
, &bd
);
673 /* read, conversion */
674 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat32bppARGB
, &bd
);
678 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
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 ((BYTE
*)bd
.Scan0
)[2] = 0xc3;
685 stat
= GdipBitmapUnlockBits(bm
, &bd
);
689 /* writes do not work in read mode if there was a conversion */
690 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
692 expect(0xffff0000, color
);
694 /* read/write, conversion */
695 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeWrite
, PixelFormat32bppARGB
, &bd
);
699 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
700 ((BYTE
*)bd
.Scan0
)[1] = 0x88;
702 /* Areas outside the rectangle appear to be uninitialized */
703 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
705 stat
= GdipBitmapUnlockBits(bm
, &bd
);
709 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
711 expect(0xffff8800, color
);
713 /* write, conversion */
714 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat32bppARGB
, &bd
);
720 /* This is completely uninitialized. */
721 ok(0xff != ((BYTE
*)bd
.Scan0
)[2], "original image bits are readable\n");
722 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
725 /* Initialize the buffer so the unlock doesn't access undefined memory */
727 memset(((BYTE
*)bd
.Scan0
) + bd
.Stride
* y
, 0, 12);
729 ((BYTE
*)bd
.Scan0
)[0] = 0x12;
730 ((BYTE
*)bd
.Scan0
)[1] = 0x34;
731 ((BYTE
*)bd
.Scan0
)[2] = 0x56;
733 stat
= GdipBitmapUnlockBits(bm
, &bd
);
737 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
739 expect(0xff563412, color
);
741 stat
= GdipBitmapGetPixel(bm
, 2, 8, &color
);
743 expect(0xffc30000, color
);
745 stat
= GdipDisposeImage((GpImage
*)bm
);
747 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
750 /* write, no modification */
751 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
755 stat
= GdipBitmapUnlockBits(bm
, &bd
);
759 /* write, consecutive */
760 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
764 stat
= GdipBitmapUnlockBits(bm
, &bd
);
768 stat
= GdipDisposeImage((GpImage
*)bm
);
770 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
774 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
779 ((char*)bd
.Scan0
)[2] = 0xff;
781 stat
= GdipBitmapUnlockBits(bm
, &bd
);
785 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
787 expect(0xffff0000, color
);
789 stat
= GdipDisposeImage((GpImage
*)bm
);
793 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
795 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
797 stat
= GdipDisposeImage((GpImage
*)bm
);
801 static void test_LockBits_UserBuf(void)
807 const INT WIDTH
= 10, HEIGHT
= 20;
812 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat32bppARGB
, NULL
, &bm
);
815 memset(bits
, 0xaa, sizeof(bits
));
824 bd
.Stride
= WIDTH
* 4;
825 bd
.PixelFormat
= PixelFormat32bppARGB
;
826 bd
.Scan0
= &bits
[2+3*WIDTH
];
827 bd
.Reserved
= 0xaaaaaaaa;
830 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
833 expect(0xaaaaaaaa, bits
[0]);
834 expect(0, bits
[2+3*WIDTH
]);
836 bits
[2+3*WIDTH
] = 0xdeadbeef;
839 stat
= GdipBitmapUnlockBits(bm
, &bd
);
843 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
848 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
851 expect(0xdeadbeef, bits
[2+3*WIDTH
]);
852 bits
[2+3*WIDTH
] = 0x12345678;
855 stat
= GdipBitmapUnlockBits(bm
, &bd
);
859 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
861 expect(0x12345678, color
);
866 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeWrite
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
869 expect(0x12345678, bits
[2+3*WIDTH
]);
870 bits
[2+3*WIDTH
] = 0xdeadbeef;
873 stat
= GdipBitmapUnlockBits(bm
, &bd
);
877 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
879 expect(0xdeadbeef, color
);
881 stat
= GdipDisposeImage((GpImage
*)bm
);
885 struct BITMAPINFOWITHBITFIELDS
887 BITMAPINFOHEADER bmiHeader
;
891 union BITMAPINFOUNION
894 struct BITMAPINFOWITHBITFIELDS bf
;
897 static void test_GdipCreateBitmapFromHBITMAP(void)
899 GpBitmap
* gpbm
= NULL
;
901 HPALETTE hpal
= NULL
;
904 LOGPALETTE
* LogPal
= NULL
;
906 const REAL WIDTH1
= 5;
907 const REAL HEIGHT1
= 15;
908 const REAL WIDTH2
= 10;
909 const REAL HEIGHT2
= 20;
911 union BITMAPINFOUNION bmi
;
915 stat
= GdipCreateBitmapFromHBITMAP(NULL
, NULL
, NULL
);
916 expect(InvalidParameter
, stat
);
918 hbm
= CreateBitmap(WIDTH1
, HEIGHT1
, 1, 1, NULL
);
919 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, NULL
);
920 expect(InvalidParameter
, stat
);
922 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
924 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
925 expectf(WIDTH1
, width
);
926 expectf(HEIGHT1
, height
);
928 GdipDisposeImage((GpImage
*)gpbm
);
931 memset(buff
, 0, sizeof(buff
));
932 hbm
= CreateBitmap(WIDTH2
, HEIGHT2
, 1, 1, &buff
);
933 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
936 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)gpbm
, __LINE__
, FALSE
);
938 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
939 expectf(WIDTH2
, width
);
940 expectf(HEIGHT2
, height
);
942 GdipDisposeImage((GpImage
*)gpbm
);
945 hdc
= CreateCompatibleDC(0);
946 ok(hdc
!= NULL
, "CreateCompatibleDC failed\n");
947 bmi
.bi
.bmiHeader
.biSize
= sizeof(bmi
.bi
.bmiHeader
);
948 bmi
.bi
.bmiHeader
.biHeight
= HEIGHT1
;
949 bmi
.bi
.bmiHeader
.biWidth
= WIDTH1
;
950 bmi
.bi
.bmiHeader
.biBitCount
= 24;
951 bmi
.bi
.bmiHeader
.biPlanes
= 1;
952 bmi
.bi
.bmiHeader
.biCompression
= BI_RGB
;
953 bmi
.bi
.bmiHeader
.biClrUsed
= 0;
955 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
956 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
960 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
962 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
963 expectf(WIDTH1
, width
);
964 expectf(HEIGHT1
, height
);
967 /* test whether writing to the bitmap affects the original */
968 stat
= GdipBitmapSetPixel(gpbm
, 0, 0, 0xffffffff);
973 GdipDisposeImage((GpImage
*)gpbm
);
976 LogPal
= GdipAlloc(sizeof(LOGPALETTE
));
977 ok(LogPal
!= NULL
, "unable to allocate LOGPALETTE\n");
978 LogPal
->palVersion
= 0x300;
979 LogPal
->palNumEntries
= 1;
980 hpal
= CreatePalette(LogPal
);
981 ok(hpal
!= NULL
, "CreatePalette failed\n");
984 stat
= GdipCreateBitmapFromHBITMAP(hbm
, hpal
, &gpbm
);
988 GdipDisposeImage((GpImage
*)gpbm
);
993 /* 16-bit 555 dib, rgb */
994 bmi
.bi
.bmiHeader
.biBitCount
= 16;
995 bmi
.bi
.bmiHeader
.biCompression
= BI_RGB
;
997 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
998 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1002 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1007 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1009 expectf(WIDTH1
, width
);
1010 expectf(HEIGHT1
, height
);
1012 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1014 expect(PixelFormat16bppRGB555
, format
);
1016 GdipDisposeImage((GpImage
*)gpbm
);
1020 /* 16-bit 555 dib, with bitfields */
1021 bmi
.bi
.bmiHeader
.biSize
= sizeof(bmi
);
1022 bmi
.bi
.bmiHeader
.biCompression
= BI_BITFIELDS
;
1023 bmi
.bf
.masks
[0] = 0x7c00;
1024 bmi
.bf
.masks
[1] = 0x3e0;
1025 bmi
.bf
.masks
[2] = 0x1f;
1027 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1028 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1032 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1037 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1039 expectf(WIDTH1
, width
);
1040 expectf(HEIGHT1
, height
);
1042 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1044 expect(PixelFormat16bppRGB555
, format
);
1046 GdipDisposeImage((GpImage
*)gpbm
);
1050 /* 16-bit 565 dib, with bitfields */
1051 bmi
.bf
.masks
[0] = 0xf800;
1052 bmi
.bf
.masks
[1] = 0x7e0;
1053 bmi
.bf
.masks
[2] = 0x1f;
1055 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1056 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1060 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1065 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1067 expectf(WIDTH1
, width
);
1068 expectf(HEIGHT1
, height
);
1070 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1072 expect(PixelFormat16bppRGB565
, format
);
1074 GdipDisposeImage((GpImage
*)gpbm
);
1081 static void test_GdipGetImageFlags(void)
1087 img
= (GpImage
*)0xdeadbeef;
1089 stat
= GdipGetImageFlags(NULL
, NULL
);
1090 expect(InvalidParameter
, stat
);
1092 stat
= GdipGetImageFlags(NULL
, &flags
);
1093 expect(InvalidParameter
, stat
);
1095 stat
= GdipGetImageFlags(img
, NULL
);
1096 expect(InvalidParameter
, stat
);
1098 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat1bppIndexed
, NULL
, (GpBitmap
**)&img
);
1100 stat
= GdipGetImageFlags(img
, &flags
);
1102 expect(ImageFlagsHasAlpha
, flags
);
1103 GdipDisposeImage(img
);
1105 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat4bppIndexed
, NULL
, (GpBitmap
**)&img
);
1107 stat
= GdipGetImageFlags(img
, &flags
);
1109 expect(ImageFlagsHasAlpha
, flags
);
1110 GdipDisposeImage(img
);
1112 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat8bppIndexed
, NULL
, (GpBitmap
**)&img
);
1114 stat
= GdipGetImageFlags(img
, &flags
);
1116 expect(ImageFlagsHasAlpha
, flags
);
1117 GdipDisposeImage(img
);
1119 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppGrayScale
, NULL
, (GpBitmap
**)&img
);
1121 stat
= GdipGetImageFlags(img
, &flags
);
1123 expect(ImageFlagsNone
, flags
);
1124 GdipDisposeImage(img
);
1126 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB555
, NULL
, (GpBitmap
**)&img
);
1128 stat
= GdipGetImageFlags(img
, &flags
);
1130 expect(ImageFlagsNone
, flags
);
1131 GdipDisposeImage(img
);
1133 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB565
, NULL
, (GpBitmap
**)&img
);
1135 stat
= GdipGetImageFlags(img
, &flags
);
1137 expect(ImageFlagsNone
, flags
);
1138 GdipDisposeImage(img
);
1140 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppARGB1555
, NULL
, (GpBitmap
**)&img
);
1142 stat
= GdipGetImageFlags(img
, &flags
);
1144 expect(ImageFlagsHasAlpha
, flags
);
1145 GdipDisposeImage(img
);
1147 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, NULL
, (GpBitmap
**)&img
);
1149 stat
= GdipGetImageFlags(img
, &flags
);
1151 expect(ImageFlagsNone
, flags
);
1152 GdipDisposeImage(img
);
1154 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&img
);
1156 stat
= GdipGetImageFlags(img
, &flags
);
1158 expect(ImageFlagsNone
, flags
);
1159 GdipDisposeImage(img
);
1161 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppARGB
, NULL
, (GpBitmap
**)&img
);
1163 stat
= GdipGetImageFlags(img
, &flags
);
1165 expect(ImageFlagsHasAlpha
, flags
);
1166 GdipDisposeImage(img
);
1168 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppPARGB
, NULL
, (GpBitmap
**)&img
);
1170 stat
= GdipGetImageFlags(img
, &flags
);
1172 expect(ImageFlagsHasAlpha
, flags
);
1173 GdipDisposeImage(img
);
1175 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat48bppRGB
, NULL
, (GpBitmap
**)&img
);
1179 stat
= GdipGetImageFlags(img
, &flags
);
1181 expect(ImageFlagsNone
, flags
);
1182 GdipDisposeImage(img
);
1185 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB
, NULL
, (GpBitmap
**)&img
);
1190 stat
= GdipGetImageFlags(img
, &flags
);
1192 expect(ImageFlagsHasAlpha
, flags
);
1193 GdipDisposeImage(img
);
1196 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB
, NULL
, (GpBitmap
**)&img
);
1201 stat
= GdipGetImageFlags(img
, &flags
);
1203 expect(ImageFlagsHasAlpha
, flags
);
1204 GdipDisposeImage(img
);
1208 static void test_GdipCloneImage(void)
1214 GpImage
*image_src
, *image_dest
= NULL
;
1215 const INT WIDTH
= 10, HEIGHT
= 20;
1217 /* Create an image, clone it, delete the original, make sure the copy works */
1218 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
1220 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bm
, __LINE__
, FALSE
);
1222 image_src
= ((GpImage
*)bm
);
1223 stat
= GdipCloneImage(image_src
, &image_dest
);
1225 expect_rawformat(&ImageFormatMemoryBMP
, image_dest
, __LINE__
, FALSE
);
1227 stat
= GdipDisposeImage((GpImage
*)bm
);
1229 stat
= GdipGetImageBounds(image_dest
, &rectF
, &unit
);
1232 /* Treat FP values carefully */
1233 expectf((REAL
)WIDTH
, rectF
.Width
);
1234 expectf((REAL
)HEIGHT
, rectF
.Height
);
1236 stat
= GdipDisposeImage(image_dest
);
1240 static void test_testcontrol(void)
1246 stat
= GdipTestControl(TestControlGetBuildNumber
, ¶m
);
1248 ok(param
!= 0, "Build number expected, got %u\n", param
);
1251 static void test_fromhicon(void)
1253 static const BYTE bmp_bits
[1024];
1254 HBITMAP hbmMask
, hbmColor
;
1258 GpBitmap
*bitmap
= NULL
;
1264 stat
= GdipCreateBitmapFromHICON(NULL
, NULL
);
1265 expect(InvalidParameter
, stat
);
1266 stat
= GdipCreateBitmapFromHICON(NULL
, &bitmap
);
1267 expect(InvalidParameter
, stat
);
1269 /* color icon 1 bit */
1270 hbmMask
= CreateBitmap(16, 16, 1, 1, bmp_bits
);
1271 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1272 hbmColor
= CreateBitmap(16, 16, 1, 1, bmp_bits
);
1273 ok(hbmColor
!= 0, "CreateBitmap failed\n");
1277 info
.hbmMask
= hbmMask
;
1278 info
.hbmColor
= hbmColor
;
1279 hIcon
= CreateIconIndirect(&info
);
1280 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
1281 DeleteObject(hbmMask
);
1282 DeleteObject(hbmColor
);
1284 stat
= GdipCreateBitmapFromHICON(hIcon
, &bitmap
);
1286 broken(stat
== InvalidParameter
), /* Win98 */
1287 "Expected Ok, got %.8x\n", stat
);
1289 /* check attributes */
1290 stat
= GdipGetImageHeight((GpImage
*)bitmap
, &dim
);
1293 stat
= GdipGetImageWidth((GpImage
*)bitmap
, &dim
);
1296 stat
= GdipGetImageType((GpImage
*)bitmap
, &type
);
1298 expect(ImageTypeBitmap
, type
);
1299 stat
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
1301 expect(PixelFormat32bppARGB
, format
);
1303 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bitmap
, __LINE__
, FALSE
);
1304 GdipDisposeImage((GpImage
*)bitmap
);
1308 /* color icon 8 bpp */
1309 hbmMask
= CreateBitmap(16, 16, 1, 8, bmp_bits
);
1310 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1311 hbmColor
= CreateBitmap(16, 16, 1, 8, bmp_bits
);
1312 ok(hbmColor
!= 0, "CreateBitmap failed\n");
1316 info
.hbmMask
= hbmMask
;
1317 info
.hbmColor
= hbmColor
;
1318 hIcon
= CreateIconIndirect(&info
);
1319 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
1320 DeleteObject(hbmMask
);
1321 DeleteObject(hbmColor
);
1323 stat
= GdipCreateBitmapFromHICON(hIcon
, &bitmap
);
1326 /* check attributes */
1327 stat
= GdipGetImageHeight((GpImage
*)bitmap
, &dim
);
1330 stat
= GdipGetImageWidth((GpImage
*)bitmap
, &dim
);
1333 stat
= GdipGetImageType((GpImage
*)bitmap
, &type
);
1335 expect(ImageTypeBitmap
, type
);
1336 stat
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
1338 expect(PixelFormat32bppARGB
, format
);
1340 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bitmap
, __LINE__
, FALSE
);
1341 GdipDisposeImage((GpImage
*)bitmap
);
1347 static const unsigned char pngimage
[285] = {
1348 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
1349 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
1350 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
1351 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
1352 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
1353 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
1354 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
1357 static const unsigned char gifimage
[35] = {
1358 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
1359 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
1362 /* 1x1 pixel transparent gif */
1363 static const unsigned char transparentgif
[] = {
1364 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,
1365 0x00,0x00,0x00,0x21,0xf9,0x04,0x01,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,
1366 0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
1369 static const unsigned char bmpimage
[66] = {
1370 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
1371 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
1372 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
1373 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
1377 static const unsigned char jpgimage
[285] = {
1378 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
1379 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
1380 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
1381 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
1382 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
1383 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
1384 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
1385 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1386 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1387 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
1388 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
1389 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1390 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
1391 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
1392 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1393 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
1394 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
1395 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
1397 /* 1x1 pixel tiff */
1398 static const unsigned char tiffimage
[] = {
1399 0x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00,
1400 0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00,
1401 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1402 0x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01,
1403 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00,
1404 0x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00,
1405 0x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01,
1406 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00,
1407 0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00,
1408 0x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01,
1409 0x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00,
1410 0x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1411 0x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
1412 0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65,
1413 0x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74,
1414 0x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,
1417 /* 320x320 twip wmf */
1418 static const unsigned char wmfimage
[180] = {
1419 0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05,
1420 0x00,0x00,0x00,0x00,0xb1,0x52,0x01,0x00,0x09,0x00,0x00,0x03,0x4f,0x00,0x00,0x00,
1421 0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0b,0x02,0x00,0x00,
1422 0x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x02,0x40,0x01,0x40,0x01,0x04,0x00,0x00,0x00,
1423 0x02,0x01,0x01,0x00,0x04,0x00,0x00,0x00,0x04,0x01,0x0d,0x00,0x08,0x00,0x00,0x00,
1424 0xfa,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
1425 0x2d,0x01,0x00,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,0x01,0x00,0x00,0x00,0x00,0x00,
1426 0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x01,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,
1427 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x02,0x00,
1428 0x07,0x00,0x00,0x00,0x1b,0x04,0x40,0x01,0x40,0x01,0x00,0x00,0x00,0x00,0x04,0x00,
1429 0x00,0x00,0xf0,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0xf0,0x01,0x01,0x00,0x03,0x00,
1432 static void test_getrawformat(void)
1434 test_bufferrawformat((void*)pngimage
, sizeof(pngimage
), &ImageFormatPNG
, __LINE__
, FALSE
);
1435 test_bufferrawformat((void*)gifimage
, sizeof(gifimage
), &ImageFormatGIF
, __LINE__
, FALSE
);
1436 test_bufferrawformat((void*)bmpimage
, sizeof(bmpimage
), &ImageFormatBMP
, __LINE__
, FALSE
);
1437 test_bufferrawformat((void*)jpgimage
, sizeof(jpgimage
), &ImageFormatJPEG
, __LINE__
, FALSE
);
1438 test_bufferrawformat((void*)tiffimage
, sizeof(tiffimage
), &ImageFormatTIFF
, __LINE__
, FALSE
);
1439 test_bufferrawformat((void*)wmfimage
, sizeof(wmfimage
), &ImageFormatWMF
, __LINE__
, FALSE
);
1442 static void test_loadwmf(void)
1453 MetafileHeader header
;
1455 hglob
= GlobalAlloc (0, sizeof(wmfimage
));
1456 data
= GlobalLock (hglob
);
1457 memcpy(data
, wmfimage
, sizeof(wmfimage
));
1458 GlobalUnlock(hglob
); data
= NULL
;
1460 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
1461 ok(hres
== S_OK
, "Failed to create a stream\n");
1462 if(hres
!= S_OK
) return;
1464 stat
= GdipLoadImageFromStream(stream
, &img
);
1465 ok(stat
== Ok
, "Failed to create a Bitmap\n");
1467 IStream_Release(stream
);
1471 IStream_Release(stream
);
1473 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1475 expect(UnitPixel
, unit
);
1476 expectf(0.0, bounds
.X
);
1477 expectf(0.0, bounds
.Y
);
1478 expectf(320.0, bounds
.Width
);
1479 expectf(320.0, bounds
.Height
);
1481 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1483 expectf(1440.0, res
);
1485 stat
= GdipGetImageVerticalResolution(img
, &res
);
1487 expectf(1440.0, res
);
1489 memset(&header
, 0, sizeof(header
));
1490 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1494 expect(MetafileTypeWmfPlaceable
, header
.Type
);
1495 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1496 todo_wine
expect(0x300, header
.Version
);
1497 expect(0, header
.EmfPlusFlags
);
1498 expectf(1440.0, header
.DpiX
);
1499 expectf(1440.0, header
.DpiY
);
1500 expect(0, header
.X
);
1501 expect(0, header
.Y
);
1502 expect(320, header
.Width
);
1503 expect(320, header
.Height
);
1504 expect(1, U(header
).WmfHeader
.mtType
);
1505 expect(0, header
.EmfPlusHeaderSize
);
1506 expect(0, header
.LogicalDpiX
);
1507 expect(0, header
.LogicalDpiY
);
1510 GdipDisposeImage(img
);
1513 static void test_createfromwmf(void)
1521 MetafileHeader header
;
1523 hwmf
= SetMetaFileBitsEx(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
),
1524 wmfimage
+sizeof(WmfPlaceableFileHeader
));
1525 ok(hwmf
!= 0, "SetMetaFileBitsEx failed\n");
1527 stat
= GdipCreateMetafileFromWmf(hwmf
, TRUE
,
1528 (WmfPlaceableFileHeader
*)wmfimage
, (GpMetafile
**)&img
);
1531 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1533 expect(UnitPixel
, unit
);
1534 expectf(0.0, bounds
.X
);
1535 expectf(0.0, bounds
.Y
);
1536 expectf(320.0, bounds
.Width
);
1537 expectf(320.0, bounds
.Height
);
1539 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1541 expectf(1440.0, res
);
1543 stat
= GdipGetImageVerticalResolution(img
, &res
);
1545 expectf(1440.0, res
);
1547 memset(&header
, 0, sizeof(header
));
1548 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1552 expect(MetafileTypeWmfPlaceable
, header
.Type
);
1553 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1554 todo_wine
expect(0x300, header
.Version
);
1555 expect(0, header
.EmfPlusFlags
);
1556 expectf(1440.0, header
.DpiX
);
1557 expectf(1440.0, header
.DpiY
);
1558 expect(0, header
.X
);
1559 expect(0, header
.Y
);
1560 expect(320, header
.Width
);
1561 expect(320, header
.Height
);
1562 expect(1, U(header
).WmfHeader
.mtType
);
1563 expect(0, header
.EmfPlusHeaderSize
);
1564 expect(0, header
.LogicalDpiX
);
1565 expect(0, header
.LogicalDpiY
);
1568 GdipDisposeImage(img
);
1571 static void test_createfromwmf_noplaceable(void)
1577 hwmf
= SetMetaFileBitsEx(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
),
1578 wmfimage
+sizeof(WmfPlaceableFileHeader
));
1579 ok(hwmf
!= 0, "SetMetaFileBitsEx failed\n");
1581 stat
= GdipCreateMetafileFromWmf(hwmf
, TRUE
, NULL
, (GpMetafile
**)&img
);
1584 GdipDisposeImage(img
);
1587 static void test_resolution(void)
1591 GpGraphics
*graphics
;
1594 int screenxres
, screenyres
;
1597 stat
= GdipCreateBitmapFromScan0(1, 1, 32, PixelFormat24bppRGB
, NULL
, &bitmap
);
1600 /* test invalid values */
1601 stat
= GdipGetImageHorizontalResolution(NULL
, &res
);
1602 expect(InvalidParameter
, stat
);
1604 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, NULL
);
1605 expect(InvalidParameter
, stat
);
1607 stat
= GdipGetImageVerticalResolution(NULL
, &res
);
1608 expect(InvalidParameter
, stat
);
1610 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, NULL
);
1611 expect(InvalidParameter
, stat
);
1613 stat
= GdipBitmapSetResolution(NULL
, 96.0, 96.0);
1614 expect(InvalidParameter
, stat
);
1616 stat
= GdipBitmapSetResolution(bitmap
, 0.0, 0.0);
1617 expect(InvalidParameter
, stat
);
1619 /* defaults to screen resolution */
1620 screendc
= GetDC(0);
1622 screenxres
= GetDeviceCaps(screendc
, LOGPIXELSX
);
1623 screenyres
= GetDeviceCaps(screendc
, LOGPIXELSY
);
1625 ReleaseDC(0, screendc
);
1627 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1629 expectf((REAL
)screenxres
, res
);
1631 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1633 expectf((REAL
)screenyres
, res
);
1635 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1637 stat
= GdipGetDpiX(graphics
, &res
);
1639 expectf((REAL
)screenxres
, res
);
1640 stat
= GdipGetDpiY(graphics
, &res
);
1642 expectf((REAL
)screenyres
, res
);
1644 /* test changing the resolution */
1645 stat
= GdipBitmapSetResolution(bitmap
, screenxres
*2.0, screenyres
*3.0);
1648 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1650 expectf(screenxres
*2.0, res
);
1652 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1654 expectf(screenyres
*3.0, res
);
1656 stat
= GdipGetDpiX(graphics
, &res
);
1658 expectf((REAL
)screenxres
, res
);
1659 stat
= GdipGetDpiY(graphics
, &res
);
1661 expectf((REAL
)screenyres
, res
);
1663 stat
= GdipDeleteGraphics(graphics
);
1666 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1668 stat
= GdipGetDpiX(graphics
, &res
);
1670 expectf(screenxres
*2.0, res
);
1671 stat
= GdipGetDpiY(graphics
, &res
);
1673 expectf(screenyres
*3.0, res
);
1674 stat
= GdipDeleteGraphics(graphics
);
1677 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1681 static void test_createhbitmap(void)
1685 HBITMAP hbitmap
, oldhbitmap
;
1691 BitmapData lockeddata
;
1693 memset(bits
, 0x68, 640);
1696 stat
= GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB
, bits
, &bitmap
);
1699 /* test NULL values */
1700 stat
= GdipCreateHBITMAPFromBitmap(NULL
, &hbitmap
, 0);
1701 expect(InvalidParameter
, stat
);
1703 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, NULL
, 0);
1704 expect(InvalidParameter
, stat
);
1706 /* create HBITMAP */
1707 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1712 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1713 expect(sizeof(BITMAP
), ret
);
1715 expect(0, bm
.bmType
);
1716 expect(10, bm
.bmWidth
);
1717 expect(20, bm
.bmHeight
);
1718 expect(40, bm
.bmWidthBytes
);
1719 expect(1, bm
.bmPlanes
);
1720 expect(32, bm
.bmBitsPixel
);
1721 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1725 DWORD val
= *(DWORD
*)bm
.bmBits
;
1726 ok(val
== 0xff686868, "got %x, expected 0xff686868\n", val
);
1729 hdc
= CreateCompatibleDC(NULL
);
1731 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1732 pixel
= GetPixel(hdc
, 5, 5);
1733 SelectObject(hdc
, oldhbitmap
);
1737 expect(0x686868, pixel
);
1739 DeleteObject(hbitmap
);
1742 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1745 /* make (1,0) have no alpha and (2,0) a different blue value. */
1749 /* create alpha Bitmap */
1750 stat
= GdipCreateBitmapFromScan0(8, 20, 32, PixelFormat32bppARGB
, bits
, &bitmap
);
1753 /* create HBITMAP */
1754 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1759 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1760 expect(sizeof(BITMAP
), ret
);
1762 expect(0, bm
.bmType
);
1763 expect(8, bm
.bmWidth
);
1764 expect(20, bm
.bmHeight
);
1765 expect(32, bm
.bmWidthBytes
);
1766 expect(1, bm
.bmPlanes
);
1767 expect(32, bm
.bmBitsPixel
);
1768 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1772 DWORD val
= *(DWORD
*)bm
.bmBits
;
1773 ok(val
== 0x682a2a2a, "got %x, expected 0x682a2a2a\n", val
);
1774 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1775 ok(val
== 0x0, "got %x, expected 0x682a2a2a\n", val
);
1778 hdc
= CreateCompatibleDC(NULL
);
1780 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1781 pixel
= GetPixel(hdc
, 5, 5);
1782 expect(0x2a2a2a, pixel
);
1783 pixel
= GetPixel(hdc
, 1, 0);
1786 SelectObject(hdc
, oldhbitmap
);
1791 DeleteObject(hbitmap
);
1794 /* create HBITMAP with bkgnd colour */
1795 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0xff00ff);
1800 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1801 expect(sizeof(BITMAP
), ret
);
1803 expect(0, bm
.bmType
);
1804 expect(8, bm
.bmWidth
);
1805 expect(20, bm
.bmHeight
);
1806 expect(32, bm
.bmWidthBytes
);
1807 expect(1, bm
.bmPlanes
);
1808 expect(32, bm
.bmBitsPixel
);
1809 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1813 DWORD val
= *(DWORD
*)bm
.bmBits
;
1814 ok(val
== 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val
);
1815 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1816 ok(val
== 0xff00ff, "got %x, expected 0x682a2a2a\n", val
);
1819 hdc
= CreateCompatibleDC(NULL
);
1821 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1822 pixel
= GetPixel(hdc
, 5, 5);
1823 expect(0xc12ac1, pixel
);
1824 pixel
= GetPixel(hdc
, 1, 0);
1825 expect(0xff00ff, pixel
);
1826 pixel
= GetPixel(hdc
, 2, 0);
1827 expect(0xb12ac1, pixel
);
1829 SelectObject(hdc
, oldhbitmap
);
1831 DeleteObject(hbitmap
);
1834 /* create HBITMAP with bkgnd colour with alpha and show it behaves with no alpha. */
1835 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0x80ff00ff);
1840 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1841 expect(sizeof(BITMAP
), ret
);
1843 expect(0, bm
.bmType
);
1844 expect(8, bm
.bmWidth
);
1845 expect(20, bm
.bmHeight
);
1846 expect(32, bm
.bmWidthBytes
);
1847 expect(1, bm
.bmPlanes
);
1848 expect(32, bm
.bmBitsPixel
);
1849 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1853 DWORD val
= *(DWORD
*)bm
.bmBits
;
1854 ok(val
== 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val
);
1855 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1856 ok(val
== 0xff00ff, "got %x, expected 0x682a2a2a\n", val
);
1859 hdc
= CreateCompatibleDC(NULL
);
1861 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1862 pixel
= GetPixel(hdc
, 5, 5);
1863 expect(0xc12ac1, pixel
);
1864 pixel
= GetPixel(hdc
, 1, 0);
1865 expect(0xff00ff, pixel
);
1866 pixel
= GetPixel(hdc
, 2, 0);
1867 expect(0xb12ac1, pixel
);
1869 SelectObject(hdc
, oldhbitmap
);
1871 DeleteObject(hbitmap
);
1874 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1877 /* create HBITMAP from locked data */
1878 memset(bits
, 0x68, 640);
1879 stat
= GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB
, bits
, &bitmap
);
1882 memset(&lockeddata
, 0, sizeof(lockeddata
));
1883 stat
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
| ImageLockModeWrite
,
1884 PixelFormat32bppRGB
, &lockeddata
);
1886 ((DWORD
*)lockeddata
.Scan0
)[0] = 0xff242424;
1887 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1889 stat
= GdipBitmapUnlockBits(bitmap
, &lockeddata
);
1891 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1894 hdc
= CreateCompatibleDC(NULL
);
1895 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1896 pixel
= GetPixel(hdc
, 0, 0);
1897 expect(0x686868, pixel
);
1898 SelectObject(hdc
, oldhbitmap
);
1902 static void test_getthumbnail(void)
1905 GpImage
*bitmap1
, *bitmap2
;
1908 stat
= GdipGetImageThumbnail(NULL
, 0, 0, &bitmap2
, NULL
, NULL
);
1909 expect(InvalidParameter
, stat
);
1911 stat
= GdipCreateBitmapFromScan0(128, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1914 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, NULL
, NULL
, NULL
);
1915 expect(InvalidParameter
, stat
);
1917 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, &bitmap2
, NULL
, NULL
);
1922 stat
= GdipGetImageWidth(bitmap2
, &width
);
1926 stat
= GdipGetImageHeight(bitmap2
, &height
);
1928 expect(120, height
);
1930 GdipDisposeImage(bitmap2
);
1933 GdipDisposeImage(bitmap1
);
1936 stat
= GdipCreateBitmapFromScan0(64, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1939 stat
= GdipGetImageThumbnail(bitmap1
, 32, 32, &bitmap2
, NULL
, NULL
);
1944 stat
= GdipGetImageWidth(bitmap2
, &width
);
1948 stat
= GdipGetImageHeight(bitmap2
, &height
);
1952 GdipDisposeImage(bitmap2
);
1955 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, &bitmap2
, NULL
, NULL
);
1960 stat
= GdipGetImageWidth(bitmap2
, &width
);
1964 stat
= GdipGetImageHeight(bitmap2
, &height
);
1966 expect(120, height
);
1968 GdipDisposeImage(bitmap2
);
1971 GdipDisposeImage(bitmap1
);
1974 static void test_getsetpixel(void)
1979 BYTE bits
[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00,
1980 0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00};
1982 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, bits
, &bitmap
);
1985 /* null parameters */
1986 stat
= GdipBitmapGetPixel(NULL
, 1, 1, &color
);
1987 expect(InvalidParameter
, stat
);
1989 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, NULL
);
1990 expect(InvalidParameter
, stat
);
1992 stat
= GdipBitmapSetPixel(NULL
, 1, 1, 0);
1993 expect(InvalidParameter
, stat
);
1996 stat
= GdipBitmapGetPixel(bitmap
, -1, 1, &color
);
1997 expect(InvalidParameter
, stat
);
1999 stat
= GdipBitmapSetPixel(bitmap
, -1, 1, 0);
2000 expect(InvalidParameter
, stat
);
2002 stat
= GdipBitmapGetPixel(bitmap
, 1, -1, &color
);
2003 ok(stat
== InvalidParameter
||
2004 broken(stat
== Ok
), /* Older gdiplus */
2005 "Expected InvalidParameter, got %.8x\n", stat
);
2007 if (0) /* crashes some gdiplus implementations */
2009 stat
= GdipBitmapSetPixel(bitmap
, 1, -1, 0);
2010 ok(stat
== InvalidParameter
||
2011 broken(stat
== Ok
), /* Older gdiplus */
2012 "Expected InvalidParameter, got %.8x\n", stat
);
2015 stat
= GdipBitmapGetPixel(bitmap
, 2, 1, &color
);
2016 expect(InvalidParameter
, stat
);
2018 stat
= GdipBitmapSetPixel(bitmap
, 2, 1, 0);
2019 expect(InvalidParameter
, stat
);
2021 stat
= GdipBitmapGetPixel(bitmap
, 1, 2, &color
);
2022 expect(InvalidParameter
, stat
);
2024 stat
= GdipBitmapSetPixel(bitmap
, 1, 2, 0);
2025 expect(InvalidParameter
, stat
);
2028 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
2030 expect(0xffffffff, color
);
2032 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2034 expect(0xff0000ff, color
);
2036 stat
= GdipBitmapSetPixel(bitmap
, 1, 1, 0xff676869);
2039 stat
= GdipBitmapSetPixel(bitmap
, 0, 0, 0xff474849);
2042 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
2044 expect(0xff676869, color
);
2046 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2048 expect(0xff474849, color
);
2050 stat
= GdipDisposeImage((GpImage
*)bitmap
);
2054 static void check_halftone_palette(ColorPalette
*palette
)
2056 static const BYTE halftone_values
[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
2059 for (i
=0; i
<palette
->Count
; i
++)
2061 ARGB expected
=0xff000000;
2064 if (i
&1) expected
|= 0x800000;
2065 if (i
&2) expected
|= 0x8000;
2066 if (i
&4) expected
|= 0x80;
2070 expected
= 0xffc0c0c0;
2074 if (i
&1) expected
|= 0xff0000;
2075 if (i
&2) expected
|= 0xff00;
2076 if (i
&4) expected
|= 0xff;
2080 expected
= 0x00000000;
2084 expected
|= halftone_values
[(i
-40)%6];
2085 expected
|= halftone_values
[((i
-40)/6)%6] << 8;
2086 expected
|= halftone_values
[((i
-40)/36)%6] << 16;
2088 ok(expected
== palette
->Entries
[i
], "Expected %.8x, got %.8x, i=%u/%u\n",
2089 expected
, palette
->Entries
[i
], i
, palette
->Count
);
2093 static void test_palette(void)
2099 ColorPalette
*palette
=(ColorPalette
*)buffer
;
2100 ARGB
*entries
= palette
->Entries
;
2103 /* test initial palette from non-indexed bitmap */
2104 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, NULL
, &bitmap
);
2107 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2109 expect(sizeof(UINT
)*2+sizeof(ARGB
), size
);
2111 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2113 expect(0, palette
->Count
);
2115 /* test setting palette on not-indexed bitmap */
2118 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2121 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2123 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2125 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2127 expect(3, palette
->Count
);
2129 GdipDisposeImage((GpImage
*)bitmap
);
2131 /* test initial palette on 1-bit bitmap */
2132 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat1bppIndexed
, NULL
, &bitmap
);
2135 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2137 expect(sizeof(UINT
)*2+sizeof(ARGB
)*2, size
);
2139 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2141 expect(PaletteFlagsGrayScale
, palette
->Flags
);
2142 expect(2, palette
->Count
);
2144 expect(0xff000000, entries
[0]);
2145 expect(0xffffffff, entries
[1]);
2147 /* test getting/setting pixels */
2148 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2150 expect(0xff000000, color
);
2152 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffffffff);
2154 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2158 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2160 expect(0xffffffff, color
);
2163 GdipDisposeImage((GpImage
*)bitmap
);
2165 /* test initial palette on 4-bit bitmap */
2166 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat4bppIndexed
, NULL
, &bitmap
);
2169 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2171 expect(sizeof(UINT
)*2+sizeof(ARGB
)*16, size
);
2173 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2175 expect(0, palette
->Flags
);
2176 expect(16, palette
->Count
);
2178 check_halftone_palette(palette
);
2180 /* test getting/setting pixels */
2181 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2183 expect(0xff000000, color
);
2185 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffff00ff);
2187 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2191 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2193 expect(0xffff00ff, color
);
2196 GdipDisposeImage((GpImage
*)bitmap
);
2198 /* test initial palette on 8-bit bitmap */
2199 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat8bppIndexed
, NULL
, &bitmap
);
2202 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2204 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2206 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2208 expect(PaletteFlagsHalftone
, palette
->Flags
);
2209 expect(256, palette
->Count
);
2211 check_halftone_palette(palette
);
2213 /* test getting/setting pixels */
2214 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2216 expect(0xff000000, color
);
2218 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffcccccc);
2220 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2224 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2226 expect(0xffcccccc, color
);
2229 /* test setting/getting a different palette */
2230 entries
[1] = 0xffcccccc;
2232 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2237 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2239 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2241 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2243 expect(PaletteFlagsHalftone
, palette
->Flags
);
2244 expect(256, palette
->Count
);
2245 expect(0xffcccccc, entries
[1]);
2247 /* test count < 256 */
2248 palette
->Flags
= 12345;
2251 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2255 entries
[3] = 0xdeadbeef;
2257 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2259 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2261 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2263 expect(12345, palette
->Flags
);
2264 expect(3, palette
->Count
);
2265 expect(0xffcccccc, entries
[1]);
2266 expect(0xdeadbeef, entries
[3]);
2268 /* test count > 256 */
2269 palette
->Count
= 257;
2271 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2272 ok(stat
== InvalidParameter
||
2273 broken(stat
== Ok
), /* Old gdiplus behavior */
2274 "Expected %.8x, got %.8x\n", InvalidParameter
, stat
);
2276 GdipDisposeImage((GpImage
*)bitmap
);
2279 static void test_colormatrix(void)
2282 ColorMatrix colormatrix
, graymatrix
;
2283 GpImageAttributes
*imageattr
;
2284 const ColorMatrix identity
= {{
2285 {1.0,0.0,0.0,0.0,0.0},
2286 {0.0,1.0,0.0,0.0,0.0},
2287 {0.0,0.0,1.0,0.0,0.0},
2288 {0.0,0.0,0.0,1.0,0.0},
2289 {0.0,0.0,0.0,0.0,1.0}}};
2290 const ColorMatrix double_red
= {{
2291 {2.0,0.0,0.0,0.0,0.0},
2292 {0.0,1.0,0.0,0.0,0.0},
2293 {0.0,0.0,1.0,0.0,0.0},
2294 {0.0,0.0,0.0,1.0,0.0},
2295 {0.0,0.0,0.0,0.0,1.0}}};
2296 const ColorMatrix asymmetric
= {{
2297 {0.0,1.0,0.0,0.0,0.0},
2298 {0.0,0.0,1.0,0.0,0.0},
2299 {0.0,0.0,0.0,1.0,0.0},
2300 {1.0,0.0,0.0,0.0,0.0},
2301 {0.0,0.0,0.0,0.0,1.0}}};
2302 GpBitmap
*bitmap1
, *bitmap2
;
2303 GpGraphics
*graphics
;
2306 colormatrix
= identity
;
2307 graymatrix
= identity
;
2309 stat
= GdipSetImageAttributesColorMatrix(NULL
, ColorAdjustTypeDefault
,
2310 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2311 expect(InvalidParameter
, stat
);
2313 stat
= GdipCreateImageAttributes(&imageattr
);
2316 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2317 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2320 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2321 TRUE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2322 expect(InvalidParameter
, stat
);
2324 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2325 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2328 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2329 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsSkipGrays
);
2332 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2333 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsAltGray
);
2334 expect(InvalidParameter
, stat
);
2336 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2337 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsAltGray
);
2340 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2341 TRUE
, &colormatrix
, &graymatrix
, 3);
2342 expect(InvalidParameter
, stat
);
2344 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeCount
,
2345 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2346 expect(InvalidParameter
, stat
);
2348 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeAny
,
2349 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2350 expect(InvalidParameter
, stat
);
2352 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2353 FALSE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2356 /* Drawing a bitmap transforms the colors */
2357 colormatrix
= double_red
;
2358 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2359 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2362 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
2365 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
2368 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff40ccee);
2371 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2374 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2375 UnitPixel
, imageattr
, NULL
, NULL
);
2378 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2380 expect(0xff80ccee, color
);
2382 colormatrix
= asymmetric
;
2383 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2384 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2387 stat
= GdipBitmapSetPixel(bitmap2
, 0, 0, 0);
2390 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2391 UnitPixel
, imageattr
, NULL
, NULL
);
2394 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2396 ok(color_match(0xeeff40cc, color
, 3), "expected 0xeeff40cc, got 0x%08x\n", color
);
2398 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2401 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2402 UnitPixel
, imageattr
, NULL
, NULL
);
2405 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2407 ok(color_match(0xff40ccee, color
, 1), "Expected ff40ccee, got %.8x\n", color
);
2409 GdipDeleteGraphics(graphics
);
2410 GdipDisposeImage((GpImage
*)bitmap1
);
2411 GdipDisposeImage((GpImage
*)bitmap2
);
2412 GdipDisposeImageAttributes(imageattr
);
2415 static void test_gamma(void)
2418 GpImageAttributes
*imageattr
;
2419 GpBitmap
*bitmap1
, *bitmap2
;
2420 GpGraphics
*graphics
;
2423 stat
= GdipSetImageAttributesGamma(NULL
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2424 expect(InvalidParameter
, stat
);
2426 stat
= GdipCreateImageAttributes(&imageattr
);
2429 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2432 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeAny
, TRUE
, 1.0);
2433 expect(InvalidParameter
, stat
);
2435 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, -1.0);
2436 expect(InvalidParameter
, stat
);
2438 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.0);
2439 expect(InvalidParameter
, stat
);
2441 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.5);
2444 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0.0);
2447 /* Drawing a bitmap transforms the colors */
2448 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 3.0);
2451 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
2454 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
2457 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff80ffff);
2460 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2463 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2464 UnitPixel
, imageattr
, NULL
, NULL
);
2467 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2469 ok(color_match(0xff20ffff, color
, 1), "Expected ff20ffff, got %.8x\n", color
);
2471 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2474 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2475 UnitPixel
, imageattr
, NULL
, NULL
);
2478 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2480 ok(color_match(0xff80ffff, color
, 1), "Expected ff80ffff, got %.8x\n", color
);
2482 GdipDeleteGraphics(graphics
);
2483 GdipDisposeImage((GpImage
*)bitmap1
);
2484 GdipDisposeImage((GpImage
*)bitmap2
);
2485 GdipDisposeImageAttributes(imageattr
);
2488 /* 1x1 pixel gif, 2 frames; first frame is white, second is black */
2489 static const unsigned char gifanimation
[72] = {
2490 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
2491 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0xf9,0x04,0x00,0x0a,0x00,0xff,
2492 0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x4c,0x01,0x00,
2493 0x21,0xf9,0x04,0x01,0x0a,0x00,0x01,0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,
2494 0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
2497 /* Generated with ImageMagick:
2498 * convert -transparent black -delay 100 -size 8x2 xc:black \
2499 * -dispose none -page +0+0 -size 2x2 xc:red \
2500 * -dispose background -page +2+0 -size 2x2 xc:blue \
2501 * -dispose previous -page +4+0 -size 2x2 xc:green \
2502 * -dispose undefined -page +6+0 -size 2x2 xc:gray \
2505 static const unsigned char gifanimation2
[] = {
2506 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x08, 0x00,
2507 0x02, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
2508 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x64,
2509 0x00, 0x00, 0x00, 0x21, 0xff, 0x0b, 0x4e, 0x45,
2510 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e,
2511 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00,
2512 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
2513 0x02, 0x04, 0x84, 0x8f, 0x09, 0x05, 0x00, 0x21,
2514 0xf9, 0x04, 0x04, 0x64, 0x00, 0x00, 0x00, 0x2c,
2515 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2516 0x81, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
2517 0x00, 0x00, 0xff, 0x00, 0x00, 0x02, 0x03, 0x44,
2518 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x08, 0x64,
2519 0x00, 0x00, 0x00, 0x2c, 0x02, 0x00, 0x00, 0x00,
2520 0x02, 0x00, 0x02, 0x00, 0x81, 0x00, 0x00, 0xff,
2521 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
2522 0xff, 0x02, 0x03, 0x44, 0x34, 0x05, 0x00, 0x21,
2523 0xf9, 0x04, 0x0c, 0x64, 0x00, 0x00, 0x00, 0x2c,
2524 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2525 0x81, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00,
2526 0x80, 0x00, 0x00, 0x80, 0x00, 0x02, 0x03, 0x44,
2527 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x64,
2528 0x00, 0x00, 0x00, 0x2c, 0x06, 0x00, 0x00, 0x00,
2529 0x02, 0x00, 0x02, 0x00, 0x80, 0x7e, 0x7e, 0x7e,
2530 0x00, 0x00, 0x00, 0x02, 0x02, 0x84, 0x51, 0x00,
2534 static ARGB gifanimation2_pixels
[5][4] = {
2536 {0xffff0000, 0, 0, 0},
2537 {0xffff0000, 0xff0000ff, 0, 0},
2538 {0xffff0000, 0, 0xff008000, 0},
2539 {0xffff0000, 0, 0, 0xff7e7e7e}
2542 static void test_multiframegif(void)
2553 PixelFormat pixel_format
;
2554 INT palette_size
, i
, j
;
2555 char palette_buf
[256];
2556 ColorPalette
*palette
;
2557 ARGB
*palette_entries
;
2559 /* Test frame functions with an animated GIF */
2560 hglob
= GlobalAlloc (0, sizeof(gifanimation
));
2561 data
= GlobalLock (hglob
);
2562 memcpy(data
, gifanimation
, sizeof(gifanimation
));
2563 GlobalUnlock(hglob
);
2565 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2566 ok(hres
== S_OK
, "Failed to create a stream\n");
2567 if(hres
!= S_OK
) return;
2569 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2570 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2572 IStream_Release(stream
);
2576 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2578 expect(PixelFormat32bppARGB
, pixel_format
);
2580 stat
= GdipGetImagePaletteSize((GpImage
*)bmp
, &palette_size
);
2582 ok(palette_size
== sizeof(ColorPalette
) ||
2583 broken(palette_size
== sizeof(ColorPalette
)+sizeof(ARGB
[3])),
2584 "palette_size = %d\n", palette_size
);
2586 /* Bitmap starts at frame 0 */
2588 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2590 expect(0xffffffff, color
);
2592 /* Check that we get correct metadata */
2593 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2597 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2599 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2602 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2606 /* SelectActiveFrame overwrites our current data */
2607 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2611 GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2613 expect(0xff000000, color
);
2615 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2619 GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2621 expect(0xffffffff, color
);
2623 /* Write over the image data */
2624 stat
= GdipBitmapSetPixel(bmp
, 0, 0, 0xff000000);
2627 /* Switching to the same frame does not overwrite our changes */
2628 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2631 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2633 expect(0xff000000, color
);
2635 /* But switching to another frame and back does */
2636 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2639 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2642 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2644 expect(0xffffffff, color
);
2646 /* rotate/flip discards the information about other frames */
2647 stat
= GdipImageRotateFlip((GpImage
*)bmp
, Rotate90FlipNone
);
2651 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2655 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bmp
, __LINE__
, FALSE
);
2657 GdipDisposeImage((GpImage
*)bmp
);
2658 IStream_Release(stream
);
2660 /* Test with a non-animated gif */
2661 hglob
= GlobalAlloc (0, sizeof(gifimage
));
2662 data
= GlobalLock (hglob
);
2663 memcpy(data
, gifimage
, sizeof(gifimage
));
2664 GlobalUnlock(hglob
);
2666 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2667 ok(hres
== S_OK
, "Failed to create a stream\n");
2668 if(hres
!= S_OK
) return;
2670 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2671 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2673 IStream_Release(stream
);
2677 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2679 expect(PixelFormat8bppIndexed
, pixel_format
);
2681 /* Check metadata */
2682 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2686 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2688 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2691 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2695 GdipDisposeImage((GpImage
*)bmp
);
2696 IStream_Release(stream
);
2698 /* Test with a non-animated transparent gif */
2699 hglob
= GlobalAlloc (0, sizeof(transparentgif
));
2700 data
= GlobalLock (hglob
);
2701 memcpy(data
, transparentgif
, sizeof(transparentgif
));
2702 GlobalUnlock(hglob
);
2704 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2705 ok(hres
== S_OK
, "Failed to create a stream\n");
2707 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2708 IStream_Release(stream
);
2709 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2711 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2713 expect(PixelFormat8bppIndexed
, pixel_format
);
2715 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2719 stat
= GdipGetImagePaletteSize((GpImage
*)bmp
, &palette_size
);
2721 ok(palette_size
== sizeof(ColorPalette
)+sizeof(ARGB
),
2722 "palette_size = %d\n", palette_size
);
2724 memset(palette_buf
, 0xfe, sizeof(palette_buf
));
2725 palette
= (ColorPalette
*)palette_buf
;
2726 stat
= GdipGetImagePalette((GpImage
*)bmp
, palette
,
2727 sizeof(ColorPalette
)+sizeof(ARGB
));
2728 palette_entries
= palette
->Entries
;
2730 expect(PaletteFlagsHasAlpha
, palette
->Flags
);
2731 expect(2, palette
->Count
);
2732 expect(0, palette_entries
[0]);
2733 expect(0xff000000, palette_entries
[1]);
2736 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2740 GdipDisposeImage((GpImage
*)bmp
);
2742 /* Test frame dispose methods */
2743 hglob
= GlobalAlloc (0, sizeof(gifanimation2
));
2744 data
= GlobalLock (hglob
);
2745 memcpy(data
, gifanimation2
, sizeof(gifanimation2
));
2746 GlobalUnlock(hglob
);
2748 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2749 ok(hres
== S_OK
, "Failed to create a stream\n");
2751 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2752 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2753 IStream_Release(stream
);
2755 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2757 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2759 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2763 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2767 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 3);
2769 stat
= GdipBitmapGetPixel(bmp
, 2, 0, &color
);
2771 ok(color
==0 || broken(color
==0xff0000ff), "color = %x\n", color
);
2773 win_skip("broken animated gif support\n");
2774 GdipDisposeImage((GpImage
*)bmp
);
2778 for(i
=0; i
<6; i
++) {
2779 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, i
%5);
2782 for(j
=0; j
<4; j
++) {
2783 stat
= GdipBitmapGetPixel(bmp
, j
*2, 0, &color
);
2785 ok(gifanimation2_pixels
[i
%5][j
] == color
, "at %d,%d got %x, expected %x\n", i
, j
, color
, gifanimation2_pixels
[i
%5][j
]);
2789 GdipDisposeImage((GpImage
*)bmp
);
2792 static void test_rotateflip(void)
2797 static const BYTE orig_bits
[24] = {
2798 0,0,0xff, 0,0xff,0, 0xff,0,0, 23,23,23,
2799 0xff,0xff,0, 0xff,0,0xff, 0,0xff,0xff, 23,23,23};
2803 memcpy(bits
, orig_bits
, sizeof(bits
));
2804 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2807 stat
= GdipImageRotateFlip(bitmap
, Rotate90FlipNone
);
2810 stat
= GdipGetImageWidth(bitmap
, &width
);
2812 stat
= GdipGetImageHeight(bitmap
, &height
);
2817 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2819 expect(0xff00ffff, color
);
2821 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 0, &color
);
2823 expect(0xffff0000, color
);
2825 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 2, &color
);
2827 expect(0xffffff00, color
);
2829 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 2, &color
);
2831 expect(0xff0000ff, color
);
2835 expect(0xff, bits
[2]);
2837 GdipDisposeImage(bitmap
);
2839 memcpy(bits
, orig_bits
, sizeof(bits
));
2840 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2843 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipX
);
2846 stat
= GdipGetImageWidth(bitmap
, &width
);
2848 stat
= GdipGetImageHeight(bitmap
, &height
);
2853 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2855 expect(0xff0000ff, color
);
2857 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
2859 expect(0xffff0000, color
);
2861 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
2863 expect(0xffffff00, color
);
2865 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
2867 expect(0xff00ffff, color
);
2871 expect(0xff, bits
[2]);
2873 GdipDisposeImage(bitmap
);
2875 memcpy(bits
, orig_bits
, sizeof(bits
));
2876 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2879 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipY
);
2882 stat
= GdipGetImageWidth(bitmap
, &width
);
2884 stat
= GdipGetImageHeight(bitmap
, &height
);
2889 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2891 expect(0xff00ffff, color
);
2893 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
2895 expect(0xffffff00, color
);
2897 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
2899 expect(0xffff0000, color
);
2901 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
2903 expect(0xff0000ff, color
);
2907 expect(0xff, bits
[2]);
2909 GdipDisposeImage(bitmap
);
2912 static void test_remaptable(void)
2915 GpImageAttributes
*imageattr
;
2916 GpBitmap
*bitmap1
, *bitmap2
;
2917 GpGraphics
*graphics
;
2921 map
= GdipAlloc(sizeof(ColorMap
));
2923 map
->oldColor
.Argb
= 0xff00ff00;
2924 map
->newColor
.Argb
= 0xffff00ff;
2926 stat
= GdipSetImageAttributesRemapTable(NULL
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
2927 expect(InvalidParameter
, stat
);
2929 stat
= GdipCreateImageAttributes(&imageattr
);
2932 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, NULL
);
2933 expect(InvalidParameter
, stat
);
2935 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeCount
, TRUE
, 1, map
);
2936 expect(InvalidParameter
, stat
);
2938 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeAny
, TRUE
, 1, map
);
2939 expect(InvalidParameter
, stat
);
2941 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0, map
);
2942 expect(InvalidParameter
, stat
);
2944 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0, NULL
);
2947 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
2950 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
2953 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
2956 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff00ff00);
2959 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2962 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2963 UnitPixel
, imageattr
, NULL
, NULL
);
2966 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2968 ok(color_match(0xffff00ff, color
, 1), "Expected ffff00ff, got %.8x\n", color
);
2970 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2973 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2974 UnitPixel
, imageattr
, NULL
, NULL
);
2977 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2979 ok(color_match(0xff00ff00, color
, 1), "Expected ff00ff00, got %.8x\n", color
);
2981 GdipDeleteGraphics(graphics
);
2982 GdipDisposeImage((GpImage
*)bitmap1
);
2983 GdipDisposeImage((GpImage
*)bitmap2
);
2984 GdipDisposeImageAttributes(imageattr
);
2988 static void test_colorkey(void)
2991 GpImageAttributes
*imageattr
;
2992 GpBitmap
*bitmap1
, *bitmap2
;
2993 GpGraphics
*graphics
;
2996 stat
= GdipSetImageAttributesColorKeys(NULL
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
2997 expect(InvalidParameter
, stat
);
2999 stat
= GdipCreateImageAttributes(&imageattr
);
3002 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeCount
, TRUE
, 0xff405060, 0xff708090);
3003 expect(InvalidParameter
, stat
);
3005 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeAny
, TRUE
, 0xff405060, 0xff708090);
3006 expect(InvalidParameter
, stat
);
3008 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
3011 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
3014 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
3017 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0x20405060);
3020 stat
= GdipBitmapSetPixel(bitmap1
, 0, 1, 0x40506070);
3023 stat
= GdipBitmapSetPixel(bitmap1
, 1, 0, 0x60708090);
3026 stat
= GdipBitmapSetPixel(bitmap1
, 1, 1, 0xffffffff);
3029 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
3032 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
3033 UnitPixel
, imageattr
, NULL
, NULL
);
3036 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
3038 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
3040 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
3042 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
3044 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
3046 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
3048 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
3050 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
3052 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
3055 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
3056 UnitPixel
, imageattr
, NULL
, NULL
);
3059 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
3061 ok(color_match(0x20405060, color
, 1), "Expected 20405060, got %.8x\n", color
);
3063 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
3065 ok(color_match(0x40506070, color
, 1), "Expected 40506070, got %.8x\n", color
);
3067 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
3069 ok(color_match(0x60708090, color
, 1), "Expected 60708090, got %.8x\n", color
);
3071 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
3073 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
3076 GdipDeleteGraphics(graphics
);
3077 GdipDisposeImage((GpImage
*)bitmap1
);
3078 GdipDisposeImage((GpImage
*)bitmap2
);
3079 GdipDisposeImageAttributes(imageattr
);
3082 static void test_dispose(void)
3086 char invalid_image
[256];
3088 stat
= GdipDisposeImage(NULL
);
3089 expect(InvalidParameter
, stat
);
3091 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, (GpBitmap
**)&image
);
3094 stat
= GdipDisposeImage(image
);
3097 stat
= GdipDisposeImage(image
);
3098 expect(ObjectBusy
, stat
);
3100 memset(invalid_image
, 0, 256);
3101 stat
= GdipDisposeImage((GpImage
*)invalid_image
);
3102 expect(ObjectBusy
, stat
);
3105 static LONG
obj_refcount(void *obj
)
3107 IUnknown_AddRef((IUnknown
*)obj
);
3108 return IUnknown_Release((IUnknown
*)obj
);
3111 static GpImage
*load_image(const BYTE
*image_data
, UINT image_size
)
3118 GpImage
*image
= NULL
, *clone
;
3119 ImageType image_type
;
3120 LONG refcount
, old_refcount
;
3122 hmem
= GlobalAlloc(0, image_size
);
3123 data
= GlobalLock(hmem
);
3124 memcpy(data
, image_data
, image_size
);
3127 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
3128 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
3129 if (hr
!= S_OK
) return NULL
;
3131 refcount
= obj_refcount(stream
);
3132 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3134 status
= GdipLoadImageFromStream(stream
, &image
);
3137 IStream_Release(stream
);
3141 status
= GdipGetImageType(image
, &image_type
);
3142 ok(status
== Ok
, "GdipGetImageType error %d\n", status
);
3144 refcount
= obj_refcount(stream
);
3145 if (image_type
== ImageTypeBitmap
)
3146 ok(refcount
> 1, "expected stream refcount > 1, got %d\n", refcount
);
3148 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3149 old_refcount
= refcount
;
3151 status
= GdipCloneImage(image
, &clone
);
3152 ok(status
== Ok
, "GdipCloneImage error %d\n", status
);
3153 refcount
= obj_refcount(stream
);
3154 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3155 status
= GdipDisposeImage(clone
);
3156 ok(status
== Ok
, "GdipDisposeImage error %d\n", status
);
3157 refcount
= obj_refcount(stream
);
3158 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3160 refcount
= IStream_Release(stream
);
3161 if (image_type
== ImageTypeBitmap
)
3162 ok(refcount
>= 1, "expected stream refcount != 0\n");
3164 ok(refcount
== 0, "expected stream refcount 0, got %d\n", refcount
);
3169 static void test_image_properties(void)
3171 static const struct test_data
3173 const BYTE
*image_data
;
3175 ImageType image_type
;
3177 UINT prop_count2
; /* if win7 behaves differently */
3178 /* 1st property attributes */
3180 UINT prop_size2
; /* if win7 behaves differently */
3182 UINT prop_id2
; /* if win7 behaves differently */
3186 { pngimage
, sizeof(pngimage
), ImageTypeBitmap
, 4, ~0, 1, 20, 0x5110, 0x132 },
3187 { jpgimage
, sizeof(jpgimage
), ImageTypeBitmap
, 2, ~0, 128, 0, 0x5090, 0x5091 },
3188 { tiffimage
, sizeof(tiffimage
), ImageTypeBitmap
, 16, 0, 4, 0, 0xfe, 0 },
3189 { bmpimage
, sizeof(bmpimage
), ImageTypeBitmap
, 0, 0, 0, 0, 0, 0 },
3190 { wmfimage
, sizeof(wmfimage
), ImageTypeMetafile
, 0, 0, 0, 0, 0, 0 }
3194 UINT prop_count
, prop_size
, i
;
3195 PROPID prop_id
[16] = { 0 };
3196 ImageType image_type
;
3203 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
3205 image
= load_image(td
[i
].image_data
, td
[i
].image_size
);
3208 trace("%u: failed to load image data\n", i
);
3212 status
= GdipGetImageType(image
, &image_type
);
3213 ok(status
== Ok
, "%u: GdipGetImageType error %d\n", i
, status
);
3214 ok(td
[i
].image_type
== image_type
, "%u: expected image_type %d, got %d\n",
3215 i
, td
[i
].image_type
, image_type
);
3217 status
= GdipGetPropertyCount(image
, &prop_count
);
3218 ok(status
== Ok
, "%u: GdipGetPropertyCount error %d\n", i
, status
);
3219 todo_wine_if(td
[i
].image_data
== pngimage
|| td
[i
].image_data
== jpgimage
)
3220 ok(td
[i
].prop_count
== prop_count
|| td
[i
].prop_count2
== prop_count
,
3221 " %u: expected property count %u or %u, got %u\n",
3222 i
, td
[i
].prop_count
, td
[i
].prop_count2
, prop_count
);
3224 status
= GdipGetPropertyItemSize(NULL
, 0, &prop_size
);
3225 expect(InvalidParameter
, status
);
3226 status
= GdipGetPropertyItemSize(image
, 0, NULL
);
3227 expect(InvalidParameter
, status
);
3228 status
= GdipGetPropertyItemSize(image
, 0, &prop_size
);
3229 if (image_type
== ImageTypeMetafile
)
3230 expect(NotImplemented
, status
);
3232 expect(PropertyNotFound
, status
);
3234 status
= GdipGetPropertyItem(NULL
, 0, 0, &item
.data
);
3235 expect(InvalidParameter
, status
);
3236 status
= GdipGetPropertyItem(image
, 0, 0, NULL
);
3237 expect(InvalidParameter
, status
);
3238 status
= GdipGetPropertyItem(image
, 0, 0, &item
.data
);
3239 if (image_type
== ImageTypeMetafile
)
3240 expect(NotImplemented
, status
);
3242 expect(PropertyNotFound
, status
);
3244 /* FIXME: remove once Wine is fixed */
3245 if (td
[i
].prop_count
!= prop_count
)
3247 GdipDisposeImage(image
);
3251 status
= GdipGetPropertyIdList(NULL
, prop_count
, prop_id
);
3252 expect(InvalidParameter
, status
);
3253 status
= GdipGetPropertyIdList(image
, prop_count
, NULL
);
3254 expect(InvalidParameter
, status
);
3255 status
= GdipGetPropertyIdList(image
, 0, prop_id
);
3256 if (image_type
== ImageTypeMetafile
)
3257 expect(NotImplemented
, status
);
3258 else if (prop_count
== 0)
3261 expect(InvalidParameter
, status
);
3262 status
= GdipGetPropertyIdList(image
, prop_count
- 1, prop_id
);
3263 if (image_type
== ImageTypeMetafile
)
3264 expect(NotImplemented
, status
);
3266 expect(InvalidParameter
, status
);
3267 status
= GdipGetPropertyIdList(image
, prop_count
+ 1, prop_id
);
3268 if (image_type
== ImageTypeMetafile
)
3269 expect(NotImplemented
, status
);
3271 expect(InvalidParameter
, status
);
3272 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3273 if (image_type
== ImageTypeMetafile
)
3274 expect(NotImplemented
, status
);
3278 if (prop_count
!= 0)
3279 ok(td
[i
].prop_id
== prop_id
[0] || td
[i
].prop_id2
== prop_id
[0],
3280 " %u: expected property id %#x or %#x, got %#x\n",
3281 i
, td
[i
].prop_id
, td
[i
].prop_id2
, prop_id
[0]);
3286 status
= GdipGetPropertyItemSize(image
, prop_id
[0], &prop_size
);
3287 if (prop_count
== 0)
3288 expect(PropertyNotFound
, status
);
3293 assert(sizeof(item
) >= prop_size
);
3294 ok(prop_size
> sizeof(PropertyItem
), "%u: got too small prop_size %u\n",
3296 ok(td
[i
].prop_size
+ sizeof(PropertyItem
) == prop_size
||
3297 td
[i
].prop_size2
+ sizeof(PropertyItem
) == prop_size
,
3298 " %u: expected property size %u or %u, got %u\n",
3299 i
, td
[i
].prop_size
, td
[i
].prop_size2
, prop_size
);
3301 status
= GdipGetPropertyItem(image
, prop_id
[0], 0, &item
.data
);
3302 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3303 "%u: expected InvalidParameter, got %d\n", i
, status
);
3304 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
- 1, &item
.data
);
3305 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3306 "%u: expected InvalidParameter, got %d\n", i
, status
);
3307 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
+ 1, &item
.data
);
3308 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3309 "%u: expected InvalidParameter, got %d\n", i
, status
);
3310 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
, &item
.data
);
3312 ok(prop_id
[0] == item
.data
.id
,
3313 "%u: expected property id %#x, got %#x\n", i
, prop_id
[0], item
.data
.id
);
3317 GdipDisposeImage(image
);
3325 #define IFD_RATIONAL 5
3327 #define IFD_UNDEFINED 7
3328 #define IFD_SSHORT 8
3330 #define IFD_SRATIONAL 10
3331 #define IFD_FLOAT 11
3332 #define IFD_DOUBLE 12
3334 #ifndef PropertyTagTypeSByte
3335 #define PropertyTagTypeSByte 6
3336 #define PropertyTagTypeSShort 8
3337 #define PropertyTagTypeFloat 11
3338 #define PropertyTagTypeDouble 12
3341 static UINT
documented_type(UINT type
)
3345 case PropertyTagTypeSByte
: return PropertyTagTypeByte
;
3346 case PropertyTagTypeSShort
: return PropertyTagTypeShort
;
3347 case PropertyTagTypeFloat
: return PropertyTagTypeUndefined
;
3348 case PropertyTagTypeDouble
: return PropertyTagTypeUndefined
;
3349 default: return type
;
3353 #include "pshpack2.h"
3368 static const struct tiff_data
3373 USHORT number_of_entries
;
3374 struct IFD_entry entry
[40];
3376 struct IFD_rational xres
;
3378 struct IFD_rational srational_val
;
3383 struct IFD_rational rational
[3];
3387 #ifdef WORDS_BIGENDIAN
3393 FIELD_OFFSET(struct tiff_data
, number_of_entries
),
3396 { 0xff, IFD_SHORT
, 1, 0 }, /* SUBFILETYPE */
3397 { 0x100, IFD_LONG
, 1, 1 }, /* IMAGEWIDTH */
3398 { 0x101, IFD_LONG
, 1, 1 }, /* IMAGELENGTH */
3399 { 0x102, IFD_SHORT
, 1, 1 }, /* BITSPERSAMPLE */
3400 { 0x103, IFD_SHORT
, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
3401 { 0x106, IFD_SHORT
, 1, 1 }, /* PHOTOMETRIC */
3402 { 0x111, IFD_LONG
, 1, FIELD_OFFSET(struct tiff_data
, pixel_data
) }, /* STRIPOFFSETS */
3403 { 0x115, IFD_SHORT
, 1, 1 }, /* SAMPLESPERPIXEL */
3404 { 0x116, IFD_LONG
, 1, 1 }, /* ROWSPERSTRIP */
3405 { 0x117, IFD_LONG
, 1, 1 }, /* STRIPBYTECOUNT */
3406 { 0x11a, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3407 { 0x11b, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3408 { 0x128, IFD_SHORT
, 1, 2 }, /* RESOLUTIONUNIT */
3409 { 0xf001, IFD_BYTE
, 1, 0x11223344 },
3410 { 0xf002, IFD_BYTE
, 4, 0x11223344 },
3411 { 0xf003, IFD_SBYTE
, 1, 0x11223344 },
3412 { 0xf004, IFD_SSHORT
, 1, 0x11223344 },
3413 { 0xf005, IFD_SSHORT
, 2, 0x11223344 },
3414 { 0xf006, IFD_SLONG
, 1, 0x11223344 },
3415 { 0xf007, IFD_FLOAT
, 1, 0x11223344 },
3416 { 0xf008, IFD_DOUBLE
, 1, FIELD_OFFSET(struct tiff_data
, double_val
) },
3417 { 0xf009, IFD_SRATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, srational_val
) },
3418 { 0xf00a, IFD_BYTE
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3419 { 0xf00b, IFD_SSHORT
, 4, FIELD_OFFSET(struct tiff_data
, short_val
) },
3420 { 0xf00c, IFD_SLONG
, 2, FIELD_OFFSET(struct tiff_data
, long_val
) },
3421 { 0xf00e, IFD_ASCII
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3422 { 0xf00f, IFD_ASCII
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3423 { 0xf010, IFD_UNDEFINED
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3424 { 0xf011, IFD_UNDEFINED
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3425 /* Some gdiplus versions ignore these fields.
3426 { 0xf012, IFD_BYTE, 0, 0x11223344 },
3427 { 0xf013, IFD_SHORT, 0, 0x11223344 },
3428 { 0xf014, IFD_LONG, 0, 0x11223344 },
3429 { 0xf015, IFD_FLOAT, 0, 0x11223344 },*/
3430 { 0xf016, IFD_SRATIONAL
, 3, FIELD_OFFSET(struct tiff_data
, rational
) },
3431 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3432 { 0xf017, IFD_FLOAT
, 2, FIELD_OFFSET(struct tiff_data
, float_val
) },
3436 1234567890.0987654321,
3437 { 0x1a2b3c4d, 0x5a6b7c8d },
3439 { 0x0101, 0x0202, 0x0303, 0x0404 },
3440 { 0x11223344, 0x55667788 },
3441 { (FLOAT
)1234.5678, (FLOAT
)8765.4321 },
3442 { { 0x01020304, 0x05060708 }, { 0x10203040, 0x50607080 }, { 0x11223344, 0x55667788 } },
3443 { 0x11, 0x22, 0x33, 0 }
3445 #include "poppack.h"
3447 static void test_tiff_properties(void)
3449 static const struct test_data
3451 ULONG type
, id
, length
;
3452 const BYTE value
[24];
3455 { PropertyTagTypeShort
, 0xff, 2, { 0 } },
3456 { PropertyTagTypeLong
, 0x100, 4, { 1 } },
3457 { PropertyTagTypeLong
, 0x101, 4, { 1 } },
3458 { PropertyTagTypeShort
, 0x102, 2, { 1 } },
3459 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3460 { PropertyTagTypeShort
, 0x106, 2, { 1 } },
3461 { PropertyTagTypeLong
, 0x111, 4, { 0x44,0x02 } },
3462 { PropertyTagTypeShort
, 0x115, 2, { 1 } },
3463 { PropertyTagTypeLong
, 0x116, 4, { 1 } },
3464 { PropertyTagTypeLong
, 0x117, 4, { 1 } },
3465 { PropertyTagTypeRational
, 0x11a, 8, { 0x84,0x03,0,0,0x03 } },
3466 { PropertyTagTypeRational
, 0x11b, 8, { 0x84,0x03,0,0,0x03 } },
3467 { PropertyTagTypeShort
, 0x128, 2, { 2 } },
3468 { PropertyTagTypeByte
, 0xf001, 1, { 0x44 } },
3469 { PropertyTagTypeByte
, 0xf002, 4, { 0x44,0x33,0x22,0x11 } },
3470 { PropertyTagTypeSByte
, 0xf003, 1, { 0x44 } },
3471 { PropertyTagTypeSShort
, 0xf004, 2, { 0x44,0x33 } },
3472 { PropertyTagTypeSShort
, 0xf005, 4, { 0x44,0x33,0x22,0x11 } },
3473 { PropertyTagTypeSLONG
, 0xf006, 4, { 0x44,0x33,0x22,0x11 } },
3474 { PropertyTagTypeFloat
, 0xf007, 4, { 0x44,0x33,0x22,0x11 } },
3475 { PropertyTagTypeDouble
, 0xf008, 8, { 0x2c,0x52,0x86,0xb4,0x80,0x65,0xd2,0x41 } },
3476 { PropertyTagTypeSRational
, 0xf009, 8, { 0x4d, 0x3c, 0x2b, 0x1a, 0x8d, 0x7c, 0x6b, 0x5a } },
3477 { PropertyTagTypeByte
, 0xf00a, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3478 { PropertyTagTypeSShort
, 0xf00b, 8, { 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04 } },
3479 { PropertyTagTypeSLONG
, 0xf00c, 8, { 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3480 { PropertyTagTypeASCII
, 0xf00e, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3481 { PropertyTagTypeASCII
, 0xf00f, 5, { 'a','b','c','d' } },
3482 { PropertyTagTypeUndefined
, 0xf010, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3483 { PropertyTagTypeUndefined
, 0xf011, 4, { 'a','b','c','d' } },
3484 { PropertyTagTypeSRational
, 0xf016, 24,
3485 { 0x04,0x03,0x02,0x01,0x08,0x07,0x06,0x05,
3486 0x40,0x30,0x20,0x10,0x80,0x70,0x60,0x50,
3487 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3488 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3489 { PropertyTagTypeFloat
, 0xf017, 8, { 0x2b,0x52,0x9a,0x44,0xba,0xf5,0x08,0x46 } },
3494 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3496 PropertyItem
*prop_item
;
3498 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
));
3501 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3505 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3507 expect(1, dim_count
);
3509 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3511 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3513 frame_count
= 0xdeadbeef;
3514 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3516 expect(1, frame_count
);
3518 prop_count
= 0xdeadbeef;
3519 status
= GdipGetPropertyCount(image
, &prop_count
);
3521 ok(prop_count
== sizeof(td
)/sizeof(td
[0]) ||
3522 broken(prop_count
== sizeof(td
)/sizeof(td
[0]) - 1) /* Win7 SP0 */,
3523 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
3525 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3527 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3530 for (i
= 0; i
< prop_count
; i
++)
3532 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &prop_size
);
3534 if (status
!= Ok
) break;
3535 ok(prop_size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, prop_size
);
3537 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, prop_size
);
3538 status
= GdipGetPropertyItem(image
, prop_id
[i
], prop_size
, prop_item
);
3540 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3541 ok(td
[i
].type
== prop_item
->type
||
3542 /* Win7 stopped using proper but not documented types, and it
3543 looks broken since TypeFloat and TypeDouble now reported as
3544 TypeUndefined, and signed types reported as unsigned. */
3545 broken(prop_item
->type
== documented_type(td
[i
].type
)),
3546 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3547 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3548 prop_size
-= sizeof(*prop_item
);
3549 ok(prop_item
->length
== prop_size
, "%u: expected length %u, got %u\n", i
, prop_size
, prop_item
->length
);
3550 ok(td
[i
].length
== prop_item
->length
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_item
->length
+1) /* XP */,
3551 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3552 ok(td
[i
].length
== prop_size
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_size
+1) /* XP */,
3553 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_size
);
3554 if (td
[i
].length
== prop_item
->length
)
3556 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3557 ok(match
|| broken(td
[i
].length
<= 4 && !match
), "%u: data mismatch\n", i
);
3561 BYTE
*data
= prop_item
->value
;
3562 trace("id %#x:", prop_item
->id
);
3563 for (j
= 0; j
< prop_item
->length
; j
++)
3564 trace(" %02x", data
[j
]);
3568 HeapFree(GetProcessHeap(), 0, prop_item
);
3571 HeapFree(GetProcessHeap(), 0, prop_id
);
3573 GdipDisposeImage(image
);
3576 static void test_GdipGetAllPropertyItems(void)
3578 static const struct test_data
3580 ULONG type
, id
, length
;
3584 { PropertyTagTypeLong
, 0xfe, 4, { 0 } },
3585 { PropertyTagTypeShort
, 0x100, 2, { 1 } },
3586 { PropertyTagTypeShort
, 0x101, 2, { 1 } },
3587 { PropertyTagTypeShort
, 0x102, 6, { 8,0,8,0,8,0 } },
3588 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3589 { PropertyTagTypeShort
, 0x106, 2, { 2,0 } },
3590 { PropertyTagTypeASCII
, 0x10d, 27, "/home/meh/Desktop/test.tif" },
3591 { PropertyTagTypeLong
, 0x111, 4, { 8,0,0,0 } },
3592 { PropertyTagTypeShort
, 0x112, 2, { 1 } },
3593 { PropertyTagTypeShort
, 0x115, 2, { 3,0 } },
3594 { PropertyTagTypeShort
, 0x116, 2, { 0x40,0 } },
3595 { PropertyTagTypeLong
, 0x117, 4, { 3,0,0,0 } },
3596 { PropertyTagTypeRational
, 0x11a, 8, { 0,0,0,72,0,0,0,1 } },
3597 { PropertyTagTypeRational
, 0x11b, 8, { 0,0,0,72,0,0,0,1 } },
3598 { PropertyTagTypeShort
, 0x11c, 2, { 1 } },
3599 { PropertyTagTypeShort
, 0x128, 2, { 2 } }
3604 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3605 UINT total_size
, total_count
;
3607 PropertyItem
*prop_item
;
3608 const char *item_data
;
3610 image
= load_image(tiffimage
, sizeof(tiffimage
));
3611 ok(image
!= 0, "Failed to load TIFF image data\n");
3614 dim_count
= 0xdeadbeef;
3615 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3617 expect(1, dim_count
);
3619 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3621 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3623 frame_count
= 0xdeadbeef;
3624 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3626 expect(1, frame_count
);
3628 prop_count
= 0xdeadbeef;
3629 status
= GdipGetPropertyCount(image
, &prop_count
);
3631 ok(prop_count
== sizeof(td
)/sizeof(td
[0]),
3632 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
3634 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3636 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3640 for (i
= 0; i
< prop_count
; i
++)
3643 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
3645 if (status
!= Ok
) break;
3646 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
3650 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
3651 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
3653 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3654 ok(td
[i
].type
== prop_item
->type
,
3655 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3656 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3657 size
-= sizeof(*prop_item
);
3658 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
3659 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3660 if (td
[i
].length
== prop_item
->length
)
3662 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3663 ok(match
, "%u: data mismatch\n", i
);
3667 BYTE
*data
= prop_item
->value
;
3668 trace("id %#x:", prop_item
->id
);
3669 for (j
= 0; j
< prop_item
->length
; j
++)
3670 trace(" %02x", data
[j
]);
3674 HeapFree(GetProcessHeap(), 0, prop_item
);
3677 HeapFree(GetProcessHeap(), 0, prop_id
);
3679 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
3680 expect(InvalidParameter
, status
);
3681 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
3682 expect(InvalidParameter
, status
);
3683 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
3684 expect(InvalidParameter
, status
);
3685 status
= GdipGetPropertySize(image
, NULL
, NULL
);
3686 expect(InvalidParameter
, status
);
3687 total_size
= 0xdeadbeef;
3688 total_count
= 0xdeadbeef;
3689 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
3691 ok(prop_count
== total_count
,
3692 "expected total property count %u, got %u\n", prop_count
, total_count
);
3693 ok(prop_size
== total_size
,
3694 "expected total property size %u, got %u\n", prop_size
, total_size
);
3696 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
3698 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
3699 expect(InvalidParameter
, status
);
3700 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
3701 expect(InvalidParameter
, status
);
3702 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3703 expect(InvalidParameter
, status
);
3704 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3705 expect(InvalidParameter
, status
);
3706 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
3707 expect(InvalidParameter
, status
);
3708 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
3709 expect(InvalidParameter
, status
);
3710 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
3713 item_data
= (const char *)(prop_item
+ prop_count
);
3714 for (i
= 0; i
< prop_count
; i
++)
3716 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
3717 i
, item_data
, prop_item
[i
].value
);
3718 ok(td
[i
].type
== prop_item
[i
].type
,
3719 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
3720 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
3721 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
3722 if (td
[i
].length
== prop_item
[i
].length
)
3724 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
3725 ok(match
, "%u: data mismatch\n", i
);
3729 BYTE
*data
= prop_item
[i
].value
;
3730 trace("id %#x:", prop_item
[i
].id
);
3731 for (j
= 0; j
< prop_item
[i
].length
; j
++)
3732 trace(" %02x", data
[j
]);
3736 item_data
+= prop_item
[i
].length
;
3739 HeapFree(GetProcessHeap(), 0, prop_item
);
3741 GdipDisposeImage(image
);
3744 static void test_tiff_palette(void)
3755 ARGB
*entries
= palette
.pal
.Entries
;
3757 /* 1bpp TIFF without palette */
3758 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
));
3761 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3765 status
= GdipGetImagePixelFormat(image
, &format
);
3767 ok(format
== PixelFormat1bppIndexed
, "expected PixelFormat1bppIndexed, got %#x\n", format
);
3769 status
= GdipGetImagePaletteSize(image
, &size
);
3770 ok(status
== Ok
|| broken(status
== GenericError
), /* XP */
3771 "GdipGetImagePaletteSize error %d\n", status
);
3772 if (status
== GenericError
)
3774 GdipDisposeImage(image
);
3777 expect(sizeof(ColorPalette
) + sizeof(ARGB
), size
);
3779 status
= GdipGetImagePalette(image
, &palette
.pal
, size
);
3781 expect(0, palette
.pal
.Flags
);
3782 expect(2, palette
.pal
.Count
);
3783 if (palette
.pal
.Count
== 2)
3785 ok(entries
[0] == 0xff000000, "expected 0xff000000, got %#x\n", entries
[0]);
3786 ok(entries
[1] == 0xffffffff, "expected 0xffffffff, got %#x\n", entries
[1]);
3789 GdipDisposeImage(image
);
3792 static void test_bitmapbits(void)
3795 static const BYTE pixels_24
[48] =
3797 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3798 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3799 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3800 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0
3802 static const BYTE pixels_00
[48] =
3804 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3805 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3806 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3807 0,0,0, 0,0,0, 0,0,0, 0,0,0
3809 static const BYTE pixels_24_77
[64] =
3811 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3812 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3813 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3814 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3815 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3816 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3818 static const BYTE pixels_77
[64] =
3820 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
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,
3824 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3825 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3826 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3827 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3829 static const BYTE pixels_8
[16] =
3831 0x01,0,0x01,0,0x01,0,0x01,0,
3832 0x01,0,0x01,0,0x01,0,0x01,0
3834 static const BYTE pixels_8_77
[64] =
3836 0x01,0,0x01,0,0x01,0,0x01,0,
3837 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3838 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3839 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3840 0x01,0,0x01,0,0x01,0,0x01,0,
3841 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3842 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3843 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3845 static const BYTE pixels_1_77
[64] =
3847 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3848 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3849 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3850 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3851 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3852 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3853 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3854 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3856 static const BYTE pixels_1
[8] = {0xaa,0,0,0,0xaa,0,0,0};
3857 static const struct test_data
3864 const BYTE
*pixels_unlocked
;
3868 { PixelFormat24bppRGB
, 24, 0xfff0, 24, 48, pixels_24
, pixels_00
},
3870 { PixelFormat24bppRGB
, 24, 0, 24, 48, pixels_24
, pixels_00
},
3871 { PixelFormat24bppRGB
, 24, ImageLockModeRead
, 24, 48, pixels_24
, pixels_00
},
3872 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
3873 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
3874 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_24_77
, pixels_24
},
3875 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3876 { PixelFormat24bppRGB
, 24, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3878 { PixelFormat8bppIndexed
, 8, 0, 8, 16, pixels_8
, pixels_24
},
3879 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
, 8, 16, pixels_8
, pixels_24
},
3880 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
3881 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
3882 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_8_77
, pixels_24
},
3883 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3884 { PixelFormat8bppIndexed
, 8, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3886 { PixelFormat1bppIndexed
, 1, 0, 4, 8, pixels_1
, pixels_24
},
3887 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
, 4, 8, pixels_1
, pixels_24
},
3888 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
3889 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
3890 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_1_77
, pixels_24
},
3891 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3892 { PixelFormat1bppIndexed
, 1, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3904 ARGB
*entries
= palette
.pal
.Entries
;
3906 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
3908 BYTE pixels
[sizeof(pixels_24
)];
3909 memcpy(pixels
, pixels_24
, sizeof(pixels_24
));
3910 status
= GdipCreateBitmapFromScan0(8, 2, 24, PixelFormat24bppRGB
, pixels
, &bitmap
);
3913 /* associate known palette with pixel data */
3914 palette
.pal
.Flags
= PaletteFlagsGrayScale
;
3915 palette
.pal
.Count
= 2;
3916 entries
[0] = 0xff000000;
3917 entries
[1] = 0xffffffff;
3918 status
= GdipSetImagePalette((GpImage
*)bitmap
, &palette
.pal
);
3921 memset(&data
, 0xfe, sizeof(data
));
3922 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
3924 memset(buf
, 0x77, sizeof(buf
));
3928 status
= GdipBitmapLockBits(bitmap
, NULL
, td
[i
].mode
, td
[i
].format
, &data
);
3929 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* XP */, "%u: GdipBitmapLockBits error %d\n", i
, status
);
3932 GdipDisposeImage((GpImage
*)bitmap
);
3935 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
3936 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
3937 ok(td
[i
].stride
== data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].stride
, data
.Stride
);
3938 ok(td
[i
].format
== data
.PixelFormat
, "%u: expected %d, got %d\n", i
, td
[i
].format
, data
.PixelFormat
);
3939 ok(td
[i
].size
== data
.Height
* data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].size
, data
.Height
* data
.Stride
);
3940 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
3941 ok(data
.Scan0
== buf
, "%u: got wrong buffer\n", i
);
3942 if (td
[i
].size
== data
.Height
* data
.Stride
)
3944 UINT j
, match
, width_bytes
= (data
.Width
* td
[i
].bpp
) / 8;
3947 for (j
= 0; j
< data
.Height
; j
++)
3949 if (memcmp((const BYTE
*)data
.Scan0
+ j
* data
.Stride
, td
[i
].pixels
+ j
* data
.Stride
, width_bytes
) != 0)
3955 if ((td
[i
].mode
& (ImageLockModeRead
|ImageLockModeUserInputBuf
)) || td
[i
].format
== PixelFormat24bppRGB
)
3958 "%u: data should match\n", i
);
3961 BYTE
*bits
= data
.Scan0
;
3962 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
3963 for (j
= 0; j
< td
[i
].size
; j
++)
3964 trace(" %02x", bits
[j
]);
3969 ok(!match
, "%u: data shouldn't match\n", i
);
3971 memset(data
.Scan0
, 0, td
[i
].size
);
3974 status
= GdipBitmapUnlockBits(bitmap
, &data
);
3975 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
3977 memset(&data
, 0xfe, sizeof(data
));
3978 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
3979 ok(status
== Ok
, "%u: GdipBitmapLockBits error %d\n", i
, status
);
3980 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
3981 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
3982 ok(data
.Stride
== 24, "%u: expected 24, got %d\n", i
, data
.Stride
);
3983 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "%u: got wrong pixel format %d\n", i
, data
.PixelFormat
);
3984 ok(data
.Height
* data
.Stride
== 48, "%u: expected 48, got %d\n", i
, data
.Height
* data
.Stride
);
3985 if (data
.Height
* data
.Stride
== 48)
3987 int match
= memcmp(data
.Scan0
, td
[i
].pixels_unlocked
, 48) == 0;
3988 ok(match
, "%u: data should match\n", i
);
3992 BYTE
*bits
= data
.Scan0
;
3993 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
3994 for (j
= 0; j
< 48; j
++)
3995 trace(" %02x", bits
[j
]);
4000 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4001 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
4003 status
= GdipDisposeImage((GpImage
*)bitmap
);
4008 static void test_DrawImage(void)
4010 BYTE black_1x1
[4] = { 0,0,0,0 };
4011 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
4012 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
4013 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
4014 0,0,0,0,0,0,0xff,0xff };
4021 GpGraphics
*graphics
;
4024 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
4026 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4029 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
4031 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
4033 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4035 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4038 status
= GdipDrawImageI(graphics
, u1
.image
, 0, 0);
4041 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
4042 ok(match
, "data should match\n");
4045 UINT i
, size
= sizeof(white_2x2
);
4046 BYTE
*bits
= white_2x2
;
4047 for (i
= 0; i
< size
; i
++)
4048 trace(" %02x", bits
[i
]);
4052 status
= GdipDeleteGraphics(graphics
);
4054 status
= GdipDisposeImage(u1
.image
);
4056 status
= GdipDisposeImage(u2
.image
);
4060 static void test_DrawImage_SourceCopy(void)
4062 DWORD dst_pixels
[4] = { 0xffffffff, 0xffffffff,
4063 0xffffffff, 0xffffffff };
4064 DWORD src_pixels
[4] = { 0, 0xffff0000,
4073 GpGraphics
*graphics
;
4075 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB
, (BYTE
*)dst_pixels
, &u1
.bitmap
);
4078 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB
, (BYTE
*)src_pixels
, &u2
.bitmap
);
4080 status
= GdipGetImageGraphicsContext(u1
.image
, &graphics
);
4082 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4085 status
= GdipSetCompositingMode(graphics
, CompositingModeSourceCopy
);
4088 status
= GdipDrawImageI(graphics
, u2
.image
, 0, 0);
4091 todo_wine
expect(0, dst_pixels
[0]);
4092 expect(0xffff0000, dst_pixels
[1]);
4093 todo_wine
expect(0, dst_pixels
[2]);
4094 todo_wine
expect(0, dst_pixels
[3]);
4096 status
= GdipDeleteGraphics(graphics
);
4098 status
= GdipDisposeImage(u1
.image
);
4100 status
= GdipDisposeImage(u2
.image
);
4104 static void test_GdipDrawImagePointRect(void)
4106 BYTE black_1x1
[4] = { 0,0,0,0 };
4107 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
4108 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
4109 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
4110 0,0,0,0,0,0,0xff,0xff };
4117 GpGraphics
*graphics
;
4120 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
4122 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4125 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
4127 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
4129 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4131 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4134 status
= GdipDrawImagePointRectI(graphics
, u1
.image
, 0, 0, 0, 0, 1, 1, UnitPixel
);
4137 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
4138 ok(match
, "data should match\n");
4141 UINT i
, size
= sizeof(white_2x2
);
4142 BYTE
*bits
= white_2x2
;
4143 for (i
= 0; i
< size
; i
++)
4144 trace(" %02x", bits
[i
]);
4148 status
= GdipDeleteGraphics(graphics
);
4150 status
= GdipDisposeImage(u1
.image
);
4152 status
= GdipDisposeImage(u2
.image
);
4156 static void test_image_format(void)
4158 static const PixelFormat fmt
[] =
4160 PixelFormat1bppIndexed
, PixelFormat4bppIndexed
, PixelFormat8bppIndexed
,
4161 PixelFormat16bppGrayScale
, PixelFormat16bppRGB555
, PixelFormat16bppRGB565
,
4162 PixelFormat16bppARGB1555
, PixelFormat24bppRGB
, PixelFormat32bppRGB
,
4163 PixelFormat32bppARGB
, PixelFormat32bppPARGB
, PixelFormat48bppRGB
,
4164 PixelFormat64bppARGB
, PixelFormat64bppPARGB
, PixelFormat32bppCMYK
4175 for (i
= 0; i
< sizeof(fmt
)/sizeof(fmt
[0]); i
++)
4177 status
= GdipCreateBitmapFromScan0(1, 1, 0, fmt
[i
], NULL
, &bitmap
);
4178 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* before win7 */,
4179 "GdipCreateBitmapFromScan0 error %d\n", status
);
4180 if (status
!= Ok
) continue;
4182 status
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
4184 expect(fmt
[i
], format
);
4186 status
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
4187 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4188 todo_wine
expect(InvalidParameter
, status
);
4192 ret
= GetObjectW(hbitmap
, sizeof(bm
), &bm
);
4193 expect(sizeof(bm
), ret
);
4194 expect(0, bm
.bmType
);
4195 expect(1, bm
.bmWidth
);
4196 expect(1, bm
.bmHeight
);
4197 expect(4, bm
.bmWidthBytes
);
4198 expect(1, bm
.bmPlanes
);
4199 expect(32, bm
.bmBitsPixel
);
4200 DeleteObject(hbitmap
);
4203 status
= GdipGetImageThumbnail((GpImage
*)bitmap
, 0, 0, &thumb
, NULL
, NULL
);
4204 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4206 ok(status
== OutOfMemory
|| broken(status
== InvalidParameter
) /* before win7 */,
4207 "expected OutOfMemory, got %d\n", status
);
4212 status
= GdipGetImagePixelFormat(thumb
, &format
);
4214 ok(format
== PixelFormat32bppPARGB
|| broken(format
!= PixelFormat32bppPARGB
) /* before win7 */,
4215 "expected PixelFormat32bppPARGB, got %#x\n", format
);
4216 status
= GdipDisposeImage(thumb
);
4220 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4221 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4222 todo_wine
expect(InvalidParameter
, status
);
4226 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4230 status
= GdipDisposeImage((GpImage
*)bitmap
);
4235 static void test_DrawImage_scale(void)
4237 static const BYTE back_8x1
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
4238 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4239 static const BYTE image_080
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,
4240 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4241 static const BYTE image_100
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,
4242 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4243 static const BYTE image_120
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,
4244 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4245 static const BYTE image_150
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4246 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4247 static const BYTE image_180
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4248 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4249 static const BYTE image_200
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4250 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4251 static const BYTE image_250
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,
4252 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4253 static const BYTE image_120_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4254 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4255 static const BYTE image_150_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4256 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4257 static const BYTE image_200_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4258 0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40 };
4259 static const BYTE image_250_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4260 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4261 static const struct test_data
4264 PixelOffsetMode pixel_offset_mode
;
4269 { 0.8, PixelOffsetModeNone
, image_080
}, /* 0 */
4270 { 1.0, PixelOffsetModeNone
, image_100
},
4271 { 1.2, PixelOffsetModeNone
, image_120
},
4272 { 1.5, PixelOffsetModeNone
, image_150
},
4273 { 1.8, PixelOffsetModeNone
, image_180
},
4274 { 2.0, PixelOffsetModeNone
, image_200
},
4275 { 2.5, PixelOffsetModeNone
, image_250
},
4277 { 0.8, PixelOffsetModeHighSpeed
, image_080
}, /* 7 */
4278 { 1.0, PixelOffsetModeHighSpeed
, image_100
},
4279 { 1.2, PixelOffsetModeHighSpeed
, image_120
},
4280 { 1.5, PixelOffsetModeHighSpeed
, image_150
},
4281 { 1.8, PixelOffsetModeHighSpeed
, image_180
},
4282 { 2.0, PixelOffsetModeHighSpeed
, image_200
},
4283 { 2.5, PixelOffsetModeHighSpeed
, image_250
},
4285 { 0.8, PixelOffsetModeHalf
, image_080
}, /* 14 */
4286 { 1.0, PixelOffsetModeHalf
, image_100
},
4287 { 1.2, PixelOffsetModeHalf
, image_120_half
, TRUE
},
4288 { 1.5, PixelOffsetModeHalf
, image_150_half
, TRUE
},
4289 { 1.8, PixelOffsetModeHalf
, image_180
},
4290 { 2.0, PixelOffsetModeHalf
, image_200_half
, TRUE
},
4291 { 2.5, PixelOffsetModeHalf
, image_250_half
, TRUE
},
4293 { 0.8, PixelOffsetModeHighQuality
, image_080
}, /* 21 */
4294 { 1.0, PixelOffsetModeHighQuality
, image_100
},
4295 { 1.2, PixelOffsetModeHighQuality
, image_120_half
, TRUE
},
4296 { 1.5, PixelOffsetModeHighQuality
, image_150_half
, TRUE
},
4297 { 1.8, PixelOffsetModeHighQuality
, image_180
},
4298 { 2.0, PixelOffsetModeHighQuality
, image_200_half
, TRUE
},
4299 { 2.5, PixelOffsetModeHighQuality
, image_250_half
, TRUE
},
4301 BYTE src_2x1
[6] = { 0x80,0x80,0x80,0x80,0x80,0x80 };
4309 GpGraphics
*graphics
;
4313 status
= GdipCreateBitmapFromScan0(2, 1, 4, PixelFormat24bppRGB
, src_2x1
, &u1
.bitmap
);
4315 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4318 status
= GdipCreateBitmapFromScan0(8, 1, 24, PixelFormat24bppRGB
, dst_8x1
, &u2
.bitmap
);
4320 status
= GdipBitmapSetResolution(u2
.bitmap
, 100.0, 100.0);
4322 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4324 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4327 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
4329 status
= GdipSetPixelOffsetMode(graphics
, td
[i
].pixel_offset_mode
);
4332 status
= GdipCreateMatrix2(td
[i
].scale_x
, 0.0, 0.0, 1.0, 0.0, 0.0, &matrix
);
4334 status
= GdipSetWorldTransform(graphics
, matrix
);
4336 GdipDeleteMatrix(matrix
);
4338 memcpy(dst_8x1
, back_8x1
, sizeof(dst_8x1
));
4339 status
= GdipDrawImageI(graphics
, u1
.image
, 1, 0);
4342 match
= memcmp(dst_8x1
, td
[i
].image
, sizeof(dst_8x1
)) == 0;
4343 todo_wine_if (!match
&& td
[i
].todo
)
4344 ok(match
, "%d: data should match\n", i
);
4347 UINT i
, size
= sizeof(dst_8x1
);
4348 const BYTE
*bits
= dst_8x1
;
4349 for (i
= 0; i
< size
; i
++)
4350 trace(" %02x", bits
[i
]);
4355 status
= GdipDeleteGraphics(graphics
);
4357 status
= GdipDisposeImage(u1
.image
);
4359 status
= GdipDisposeImage(u2
.image
);
4363 static const BYTE animatedgif
[] = {
4364 'G','I','F','8','9','a',0x01,0x00,0x01,0x00,0xA1,0x02,0x00,
4365 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
4366 /*0x21,0xFF,0x0B,'A','N','I','M','E','X','T','S','1','.','0',*/
4367 0x21,0xFF,0x0B,'N','E','T','S','C','A','P','E','2','.','0',
4368 0x03,0x01,0x05,0x00,0x00,
4369 0x21,0xFE,0x0C,'H','e','l','l','o',' ','W','o','r','l','d','!',0x00,
4370 0x21,0x01,0x0D,'a','n','i','m','a','t','i','o','n','.','g','i','f',0x00,
4371 0x21,0xF9,0x04,0xff,0x0A,0x00,0x08,0x00,
4372 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4373 0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,
4374 0x02,0x02,0x4C,0x01,0x00,
4375 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','1',0x00,
4376 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','1',0x00,
4377 0x21,0xF9,0x04,0x00,0x14,0x00,0x01,0x00,
4378 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4379 0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,
4380 0x02,0x02,0x44,0x01,0x00,
4381 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','2',0x00,
4382 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','2',0x00,0x3B
4385 static void test_gif_properties(void)
4387 static const struct test_data
4389 ULONG type
, id
, length
;
4390 const BYTE value
[13];
4393 { PropertyTagTypeLong
, PropertyTagFrameDelay
, 8, { 10,0,0,0,20,0,0,0 } },
4394 { PropertyTagTypeASCII
, PropertyTagExifUserComment
, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
4395 { PropertyTagTypeShort
, PropertyTagLoopCount
, 2, { 5,0 } },
4396 { PropertyTagTypeByte
, PropertyTagGlobalPalette
, 12, { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c } },
4397 { PropertyTagTypeByte
, PropertyTagIndexBackground
, 1, { 2 } },
4398 { PropertyTagTypeByte
, PropertyTagIndexTransparent
, 1, { 8 } }
4403 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
4404 UINT total_size
, total_count
;
4406 PropertyItem
*prop_item
;
4407 const char *item_data
;
4409 image
= load_image(animatedgif
, sizeof(animatedgif
));
4410 if (!image
) /* XP fails to load this GIF image */
4412 trace("Failed to load GIF image data\n");
4416 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
4418 expect(1, dim_count
);
4420 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
4422 expect_guid(&FrameDimensionTime
, &guid
, __LINE__
, FALSE
);
4424 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
4426 expect(2, frame_count
);
4428 status
= GdipImageSelectActiveFrame(image
, &guid
, 1);
4431 status
= GdipGetPropertyCount(image
, &prop_count
);
4433 ok(prop_count
== sizeof(td
)/sizeof(td
[0]) || broken(prop_count
== 1) /* before win7 */,
4434 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
4436 if (prop_count
!= sizeof(td
)/sizeof(td
[0]))
4438 GdipDisposeImage(image
);
4442 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
4444 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
4448 for (i
= 0; i
< prop_count
; i
++)
4451 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
4453 if (status
!= Ok
) break;
4454 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
4458 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
4459 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
4461 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
4462 ok(td
[i
].type
== prop_item
->type
,
4463 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
4464 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
4465 size
-= sizeof(*prop_item
);
4466 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
4467 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
4468 if (td
[i
].length
== prop_item
->length
)
4470 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
4471 ok(match
, "%u: data mismatch\n", i
);
4475 BYTE
*data
= prop_item
->value
;
4476 trace("id %#x:", prop_item
->id
);
4477 for (j
= 0; j
< prop_item
->length
; j
++)
4478 trace(" %02x", data
[j
]);
4482 HeapFree(GetProcessHeap(), 0, prop_item
);
4485 HeapFree(GetProcessHeap(), 0, prop_id
);
4487 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
4488 expect(InvalidParameter
, status
);
4489 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
4490 expect(InvalidParameter
, status
);
4491 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
4492 expect(InvalidParameter
, status
);
4493 status
= GdipGetPropertySize(image
, NULL
, NULL
);
4494 expect(InvalidParameter
, status
);
4495 total_size
= 0xdeadbeef;
4496 total_count
= 0xdeadbeef;
4497 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
4499 ok(prop_count
== total_count
,
4500 "expected total property count %u, got %u\n", prop_count
, total_count
);
4501 ok(prop_size
== total_size
,
4502 "expected total property size %u, got %u\n", prop_size
, total_size
);
4504 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
4506 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
4507 expect(InvalidParameter
, status
);
4508 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
4509 expect(InvalidParameter
, status
);
4510 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4511 expect(InvalidParameter
, status
);
4512 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4513 expect(InvalidParameter
, status
);
4514 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
4515 expect(InvalidParameter
, status
);
4516 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
4517 expect(InvalidParameter
, status
);
4518 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
4521 item_data
= (const char *)(prop_item
+ prop_count
);
4522 for (i
= 0; i
< prop_count
; i
++)
4524 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
4525 i
, item_data
, prop_item
[i
].value
);
4526 ok(td
[i
].type
== prop_item
[i
].type
,
4527 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
4528 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
4529 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
4530 if (td
[i
].length
== prop_item
[i
].length
)
4532 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
4533 ok(match
, "%u: data mismatch\n", i
);
4537 BYTE
*data
= prop_item
[i
].value
;
4538 trace("id %#x:", prop_item
[i
].id
);
4539 for (j
= 0; j
< prop_item
[i
].length
; j
++)
4540 trace(" %02x", data
[j
]);
4544 item_data
+= prop_item
[i
].length
;
4547 HeapFree(GetProcessHeap(), 0, prop_item
);
4549 GdipDisposeImage(image
);
4552 static void test_ARGB_conversion(void)
4554 BYTE argb
[8] = { 0x11,0x22,0x33,0x80, 0xff,0xff,0xff,0 };
4555 BYTE pargb
[8] = { 0x09,0x11,0x1a,0x80, 0,0,0,0 };
4556 BYTE rgb32_xp
[8] = { 0x11,0x22,0x33,0xff, 0xff,0xff,0xff,0xff };
4557 BYTE rgb24
[6] = { 0x11,0x22,0x33, 0xff,0xff,0xff };
4564 status
= GdipCreateBitmapFromScan0(2, 1, 8, PixelFormat32bppARGB
, argb
, &bitmap
);
4567 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4569 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4570 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4571 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4572 ok(data
.PixelFormat
== PixelFormat32bppPARGB
, "expected PixelFormat32bppPARGB, got %d\n", data
.PixelFormat
);
4573 match
= !memcmp(data
.Scan0
, pargb
, sizeof(pargb
));
4574 ok(match
, "bits don't match\n");
4578 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppPARGB
,
4579 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4581 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4584 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppRGB
, &data
);
4586 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4587 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4588 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4589 ok(data
.PixelFormat
== PixelFormat32bppRGB
, "expected PixelFormat32bppRGB, got %d\n", data
.PixelFormat
);
4590 match
= !memcmp(data
.Scan0
, argb
, sizeof(argb
)) ||
4591 !memcmp(data
.Scan0
, rgb32_xp
, sizeof(rgb32_xp
));
4592 ok(match
, "bits don't match\n");
4596 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppRGB
,
4597 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4599 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4602 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
4604 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4605 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4606 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4607 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "expected PixelFormat24bppRGB, got %d\n", data
.PixelFormat
);
4608 match
= !memcmp(data
.Scan0
, rgb24
, sizeof(rgb24
));
4609 ok(match
, "bits don't match\n");
4613 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat24bppRGB
,
4614 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4616 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4619 GdipDisposeImage((GpImage
*)bitmap
);
4623 static void test_CloneBitmapArea(void)
4626 GpBitmap
*bitmap
, *copy
;
4627 BitmapData data
, data2
;
4629 status
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB
, NULL
, &bitmap
);
4632 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
| ImageLockModeWrite
, PixelFormat24bppRGB
, &data
);
4635 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data2
);
4636 expect(WrongState
, status
);
4638 status
= GdipCloneBitmapAreaI(0, 0, 1, 1, PixelFormat24bppRGB
, bitmap
, ©
);
4641 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4644 GdipDisposeImage((GpImage
*)copy
);
4645 GdipDisposeImage((GpImage
*)bitmap
);
4648 static BOOL
get_encoder_clsid(LPCWSTR mime
, GUID
*format
, CLSID
*clsid
)
4651 UINT n_codecs
, info_size
, i
;
4652 ImageCodecInfo
*info
;
4655 status
= GdipGetImageEncodersSize(&n_codecs
, &info_size
);
4658 info
= GdipAlloc(info_size
);
4660 status
= GdipGetImageEncoders(n_codecs
, info_size
, info
);
4663 for (i
= 0; i
< n_codecs
; i
++)
4665 if (!lstrcmpW(info
[i
].MimeType
, mime
))
4667 *format
= info
[i
].FormatID
;
4668 *clsid
= info
[i
].Clsid
;
4678 static void test_supported_encoders(void)
4680 static const WCHAR bmp_mimetype
[] = { 'i', 'm', 'a','g', 'e', '/', 'b', 'm', 'p',0 };
4681 static const WCHAR jpeg_mimetype
[] = { 'i','m','a','g','e','/','j','p','e','g',0 };
4682 static const WCHAR gif_mimetype
[] = { 'i','m','a','g','e','/','g','i','f',0 };
4683 static const WCHAR tiff_mimetype
[] = { 'i','m','a','g','e','/','t','i','f','f',0 };
4684 static const WCHAR png_mimetype
[] = { 'i','m','a','g','e','/','p','n','g',0 };
4685 static const struct test_data
4691 { bmp_mimetype
, &ImageFormatBMP
},
4692 { jpeg_mimetype
, &ImageFormatJPEG
},
4693 { gif_mimetype
, &ImageFormatGIF
},
4694 { tiff_mimetype
, &ImageFormatTIFF
},
4695 { png_mimetype
, &ImageFormatPNG
}
4706 status
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB
, NULL
, &bm
);
4707 ok(status
== Ok
, "GdipCreateBitmapFromScan0 error %d\n", status
);
4709 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
4711 ret
= get_encoder_clsid(td
[i
].mime
, &format
, &clsid
);
4712 ok(ret
, "%s encoder is not in the list\n", wine_dbgstr_w(td
[i
].mime
));
4713 expect_guid(td
[i
].format
, &format
, __LINE__
, FALSE
);
4715 hmem
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_NODISCARD
, 16);
4717 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
4718 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
4720 status
= GdipSaveImageToStream((GpImage
*)bm
, stream
, &clsid
, NULL
);
4721 ok(status
== Ok
, "GdipSaveImageToStream error %d\n", status
);
4723 IStream_Release(stream
);
4726 GdipDisposeImage((GpImage
*)bm
);
4729 static void test_createeffect(void)
4731 static const GUID noneffect
= { 0xcd0c3d4b, 0xe15e, 0x4cf2, { 0x9e, 0xa8, 0x6e, 0x1d, 0x65, 0x48, 0xc5, 0xa5 } };
4732 GpStatus (WINAPI
*pGdipCreateEffect
)( const GUID guid
, CGpEffect
**effect
);
4733 GpStatus (WINAPI
*pGdipDeleteEffect
)( CGpEffect
*effect
);
4736 HMODULE mod
= GetModuleHandleA("gdiplus.dll");
4738 const GUID
* const effectlist
[] =
4739 {&BlurEffectGuid
, &SharpenEffectGuid
, &ColorMatrixEffectGuid
, &ColorLUTEffectGuid
,
4740 &BrightnessContrastEffectGuid
, &HueSaturationLightnessEffectGuid
, &LevelsEffectGuid
,
4741 &TintEffectGuid
, &ColorBalanceEffectGuid
, &RedEyeCorrectionEffectGuid
, &ColorCurveEffectGuid
};
4743 pGdipCreateEffect
= (void*)GetProcAddress( mod
, "GdipCreateEffect");
4744 pGdipDeleteEffect
= (void*)GetProcAddress( mod
, "GdipDeleteEffect");
4745 if(!pGdipCreateEffect
|| !pGdipDeleteEffect
)
4747 /* GdipCreateEffect/GdipDeleteEffect was introduced in Windows Vista. */
4748 win_skip("GDIPlus version 1.1 not available\n");
4752 stat
= pGdipCreateEffect(BlurEffectGuid
, NULL
);
4753 expect(InvalidParameter
, stat
);
4755 stat
= pGdipCreateEffect(noneffect
, &effect
);
4756 todo_wine
expect(Win32Error
, stat
);
4758 for(i
=0; i
< sizeof(effectlist
) / sizeof(effectlist
[0]); i
++)
4760 stat
= pGdipCreateEffect(*effectlist
[i
], &effect
);
4761 todo_wine
expect(Ok
, stat
);
4764 stat
= pGdipDeleteEffect(effect
);
4770 static void test_getadjustedpalette(void)
4773 GpImageAttributes
*imageattributes
;
4774 ColorPalette
*palette
;
4777 stat
= GdipCreateImageAttributes(&imageattributes
);
4780 colormap
.oldColor
.Argb
= 0xffffff00;
4781 colormap
.newColor
.Argb
= 0xffff00ff;
4782 stat
= GdipSetImageAttributesRemapTable(imageattributes
, ColorAdjustTypeBitmap
,
4783 TRUE
, 1, &colormap
);
4786 colormap
.oldColor
.Argb
= 0xffffff80;
4787 colormap
.newColor
.Argb
= 0xffff80ff;
4788 stat
= GdipSetImageAttributesRemapTable(imageattributes
, ColorAdjustTypeDefault
,
4789 TRUE
, 1, &colormap
);
4792 palette
= GdipAlloc(sizeof(*palette
) + sizeof(ARGB
) * 2);
4795 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeBitmap
);
4796 expect(InvalidParameter
, stat
);
4799 palette
->Entries
[0] = 0xffffff00;
4800 palette
->Entries
[1] = 0xffffff80;
4801 palette
->Entries
[2] = 0xffffffff;
4803 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeBitmap
);
4805 expect(0xffff00ff, palette
->Entries
[0]);
4806 expect(0xffffff80, palette
->Entries
[1]);
4807 expect(0xffffffff, palette
->Entries
[2]);
4809 palette
->Entries
[0] = 0xffffff00;
4810 palette
->Entries
[1] = 0xffffff80;
4811 palette
->Entries
[2] = 0xffffffff;
4813 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeBrush
);
4815 expect(0xffffff00, palette
->Entries
[0]);
4816 expect(0xffff80ff, palette
->Entries
[1]);
4817 expect(0xffffffff, palette
->Entries
[2]);
4819 stat
= GdipGetImageAttributesAdjustedPalette(NULL
, palette
, ColorAdjustTypeBitmap
);
4820 expect(InvalidParameter
, stat
);
4822 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, NULL
, ColorAdjustTypeBitmap
);
4823 expect(InvalidParameter
, stat
);
4825 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, -1);
4826 expect(InvalidParameter
, stat
);
4828 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeDefault
);
4829 expect(InvalidParameter
, stat
);
4832 GdipDisposeImageAttributes(imageattributes
);
4835 static void test_histogram(void)
4837 UINT ch0
[256], ch1
[256], ch2
[256], ch3
[256];
4838 HistogramFormat test_formats
[] =
4840 HistogramFormatARGB
,
4841 HistogramFormatPARGB
,
4843 HistogramFormatGray
,
4849 const UINT WIDTH
= 8, HEIGHT
= 16;
4854 if (!pGdipBitmapGetHistogramSize
)
4856 win_skip("GdipBitmapGetHistogramSize is not supported\n");
4860 stat
= pGdipBitmapGetHistogramSize(HistogramFormatARGB
, NULL
);
4861 expect(InvalidParameter
, stat
);
4863 stat
= pGdipBitmapGetHistogramSize(0xff, NULL
);
4864 expect(InvalidParameter
, stat
);
4867 stat
= pGdipBitmapGetHistogramSize(10, &num
);
4871 for (i
= 0; i
< sizeof(test_formats
)/sizeof(test_formats
[0]); i
++)
4874 stat
= pGdipBitmapGetHistogramSize(test_formats
[i
], &num
);
4880 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
4883 /* Three solid rgb rows, next three rows are rgb shades. */
4884 for (x
= 0; x
< WIDTH
; x
++)
4886 GdipBitmapSetPixel(bm
, x
, 0, 0xffff0000);
4887 GdipBitmapSetPixel(bm
, x
, 1, 0xff00ff00);
4888 GdipBitmapSetPixel(bm
, x
, 2, 0xff0000ff);
4890 GdipBitmapSetPixel(bm
, x
, 3, 0xff010000);
4891 GdipBitmapSetPixel(bm
, x
, 4, 0xff003f00);
4892 GdipBitmapSetPixel(bm
, x
, 5, 0xff000020);
4895 stat
= pGdipBitmapGetHistogram(NULL
, HistogramFormatRGB
, 256, ch0
, ch1
, ch2
, ch3
);
4896 expect(InvalidParameter
, stat
);
4898 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, ch1
, ch2
, ch3
);
4899 expect(InvalidParameter
, stat
);
4901 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, ch1
, ch2
, NULL
);
4902 expect(InvalidParameter
, stat
);
4904 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, ch1
, NULL
, NULL
);
4905 expect(InvalidParameter
, stat
);
4907 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, NULL
, NULL
, NULL
);
4908 expect(InvalidParameter
, stat
);
4910 /* Requested format matches bitmap format */
4911 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 256, ch0
, ch1
, ch2
, ch3
);
4912 expect(InvalidParameter
, stat
);
4914 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 100, ch0
, ch1
, ch2
, NULL
);
4915 expect(InvalidParameter
, stat
);
4917 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 257, ch0
, ch1
, ch2
, NULL
);
4918 expect(InvalidParameter
, stat
);
4920 /* Channel 3 is not used, must be NULL */
4921 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 256, ch0
, ch1
, ch2
, NULL
);
4924 ok(ch0
[0xff] == WIDTH
, "Got red (0xff) %u\n", ch0
[0xff]);
4925 ok(ch1
[0xff] == WIDTH
, "Got green (0xff) %u\n", ch1
[0xff]);
4926 ok(ch2
[0xff] == WIDTH
, "Got blue (0xff) %u\n", ch1
[0xff]);
4927 ok(ch0
[0x01] == WIDTH
, "Got red (0x01) %u\n", ch0
[0x01]);
4928 ok(ch1
[0x3f] == WIDTH
, "Got green (0x3f) %u\n", ch1
[0x3f]);
4929 ok(ch2
[0x20] == WIDTH
, "Got blue (0x20) %u\n", ch1
[0x20]);
4931 /* ARGB histogram from RGB data. */
4932 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatARGB
, 256, ch0
, ch1
, ch2
, NULL
);
4933 expect(InvalidParameter
, stat
);
4935 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatARGB
, 256, ch0
, ch1
, ch2
, ch3
);
4938 ok(ch1
[0xff] == WIDTH
, "Got red (0xff) %u\n", ch1
[0xff]);
4939 ok(ch2
[0xff] == WIDTH
, "Got green (0xff) %u\n", ch2
[0xff]);
4940 ok(ch3
[0xff] == WIDTH
, "Got blue (0xff) %u\n", ch3
[0xff]);
4941 ok(ch1
[0x01] == WIDTH
, "Got red (0x01) %u\n", ch1
[0x01]);
4942 ok(ch2
[0x3f] == WIDTH
, "Got green (0x3f) %u\n", ch2
[0x3f]);
4943 ok(ch3
[0x20] == WIDTH
, "Got blue (0x20) %u\n", ch3
[0x20]);
4945 ok(ch0
[0xff] == WIDTH
* HEIGHT
, "Got alpha (0xff) %u\n", ch0
[0xff]);
4947 /* Request grayscale histogram from RGB bitmap. */
4948 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, ch1
, ch2
, ch3
);
4949 expect(InvalidParameter
, stat
);
4951 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, ch1
, ch2
, NULL
);
4952 expect(InvalidParameter
, stat
);
4954 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, ch1
, NULL
, NULL
);
4955 expect(InvalidParameter
, stat
);
4957 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, NULL
, NULL
, NULL
);
4960 GdipDisposeImage((GpImage
*)bm
);
4963 static void test_imageabort(void)
4968 if (!pGdipImageSetAbort
)
4970 win_skip("GdipImageSetAbort() is not supported.\n");
4975 stat
= GdipCreateBitmapFromScan0(8, 8, 0, PixelFormat24bppRGB
, NULL
, &bm
);
4978 stat
= pGdipImageSetAbort(NULL
, NULL
);
4979 expect(InvalidParameter
, stat
);
4981 stat
= pGdipImageSetAbort((GpImage
*)bm
, NULL
);
4984 GdipDisposeImage((GpImage
*)bm
);
4987 /* RGB 24 bpp 1x1 pixel PNG image */
4988 static const char png_1x1_data
[] = {
4989 0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,
4990 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,
4991 0x00,0x00,0x00,0x0c,'I','D','A','T',0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,0xe7,
4992 0x00,0x00,0x00,0x00,'I','E','N','D',0xae,0x42,0x60,0x82
4995 static void test_png_color_formats(void)
4999 char bit_depth
, color_type
;
5004 /* 2 - PNG_COLOR_TYPE_RGB */
5005 { 8, 2, PixelFormat24bppRGB
, ImageFlagsColorSpaceRGB
},
5006 /* 0 - PNG_COLOR_TYPE_GRAY */
5007 { 1, 0, PixelFormat1bppIndexed
, ImageFlagsColorSpaceRGB
},
5008 { 2, 0, PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
},
5009 { 4, 0, PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
},
5010 { 8, 0, PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
},
5011 { 16, 0, PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
},
5013 BYTE buf
[sizeof(png_1x1_data
)];
5021 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
5023 memcpy(buf
, png_1x1_data
, sizeof(png_1x1_data
));
5024 buf
[24] = td
[i
].bit_depth
;
5025 buf
[25] = td
[i
].color_type
;
5027 image
= load_image(buf
, sizeof(buf
));
5028 ok(image
!= NULL
, "%d: failed to load image data\n", i
);
5029 if (!image
) continue;
5031 status
= GdipGetImageType(image
, &type
);
5032 ok(status
== Ok
, "%u: GdipGetImageType error %d\n", i
, status
);
5033 ok(type
== ImageTypeBitmap
, "%d: wrong image type %d\n", i
, type
);
5035 status
= GdipGetImagePixelFormat(image
, &format
);
5037 ok(format
== td
[i
].format
||
5038 broken(td
[i
].bit_depth
== 1 && td
[i
].color_type
== 0 && format
== PixelFormat32bppARGB
), /* XP */
5039 "%d: expected %#x, got %#x\n", i
, td
[i
].format
, format
);
5041 status
= GdipGetImageFlags(image
, &flags
);
5043 ok((flags
& td
[i
].flags
) == td
[i
].flags
||
5044 broken(td
[i
].bit_depth
== 1 && td
[i
].color_type
== 0 && (flags
& ImageFlagsColorSpaceGRAY
)), /* XP */
5045 "%d: expected %#x, got %#x\n", i
, td
[i
].flags
, flags
);
5047 GdipDisposeImage(image
);
5051 static BYTE
*init_bitmap(UINT
*width
, UINT
*height
, UINT
*stride
)
5058 *stride
= (*width
* 3 + 3) & ~3;
5059 trace("width %d, height %d, stride %d\n", *width
, *height
, *stride
);
5061 src
= HeapAlloc(GetProcessHeap(), 0, *stride
* *height
);
5063 scale
= 256 / *width
;
5064 if (!scale
) scale
= 1;
5066 for (i
= 0; i
< *height
; i
++)
5068 for (j
= 0; j
< *width
; j
++)
5070 src
[i
* *stride
+ j
*3 + 0] = scale
* i
;
5071 src
[i
* *stride
+ j
*3 + 1] = scale
* (255 - (i
+j
)/2);
5072 src
[i
* *stride
+ j
*3 + 2] = scale
* j
;
5079 static void test_GdipInitializePalette(void)
5084 ColorPalette
*palette
;
5085 UINT width
, height
, stride
;
5087 pGdipInitializePalette
= (void *)GetProcAddress(GetModuleHandleA("gdiplus.dll"), "GdipInitializePalette");
5088 if (!pGdipInitializePalette
)
5090 win_skip("GdipInitializePalette is not supported on this platform\n");
5094 data
= init_bitmap(&width
, &height
, &stride
);
5096 status
= GdipCreateBitmapFromScan0(width
, height
, stride
, PixelFormat24bppRGB
, data
, &bitmap
);
5099 palette
= GdipAlloc(sizeof(*palette
) + sizeof(ARGB
) * 255);
5102 palette
->Count
= 15;
5103 status
= pGdipInitializePalette(palette
, PaletteTypeOptimal
, 16, FALSE
, bitmap
);
5104 expect(GenericError
, status
);
5107 palette
->Count
= 256;
5108 status
= pGdipInitializePalette(palette
, PaletteTypeOptimal
, 16, FALSE
, NULL
);
5109 expect(InvalidParameter
, status
);
5111 memset(palette
->Entries
, 0x11, sizeof(ARGB
) * 256);
5113 palette
->Count
= 256;
5114 status
= pGdipInitializePalette(palette
, PaletteTypeCustom
, 16, FALSE
, NULL
);
5116 expect(0, palette
->Flags
);
5117 expect(256, palette
->Count
);
5118 expect(0x11111111, palette
->Entries
[0]);
5119 expect(0x11111111, palette
->Entries
[128]);
5120 expect(0x11111111, palette
->Entries
[255]);
5122 memset(palette
->Entries
, 0x11, sizeof(ARGB
) * 256);
5124 palette
->Count
= 256;
5125 status
= pGdipInitializePalette(palette
, PaletteTypeFixedBW
, 0, FALSE
, bitmap
);
5128 expect(0x200, palette
->Flags
);
5129 expect(2, palette
->Count
);
5130 expect(0xff000000, palette
->Entries
[0]);
5131 expect(0xffffffff, palette
->Entries
[1]);
5133 memset(palette
->Entries
, 0x11, sizeof(ARGB
) * 256);
5135 palette
->Count
= 256;
5136 status
= pGdipInitializePalette(palette
, PaletteTypeFixedHalftone8
, 1, FALSE
, NULL
);
5139 expect(0x300, palette
->Flags
);
5140 expect(16, palette
->Count
);
5141 expect(0xff000000, palette
->Entries
[0]);
5142 expect(0xffc0c0c0, palette
->Entries
[8]);
5143 expect(0xff008080, palette
->Entries
[15]);
5145 memset(palette
->Entries
, 0x11, sizeof(ARGB
) * 256);
5147 palette
->Count
= 256;
5148 status
= pGdipInitializePalette(palette
, PaletteTypeFixedHalftone8
, 1, FALSE
, bitmap
);
5151 expect(0x300, palette
->Flags
);
5152 expect(16, palette
->Count
);
5153 expect(0xff000000, palette
->Entries
[0]);
5154 expect(0xffc0c0c0, palette
->Entries
[8]);
5155 expect(0xff008080, palette
->Entries
[15]);
5157 memset(palette
->Entries
, 0x11, sizeof(ARGB
) * 256);
5159 palette
->Count
= 256;
5160 status
= pGdipInitializePalette(palette
, PaletteTypeFixedHalftone252
, 1, FALSE
, bitmap
);
5163 expect(0x800, palette
->Flags
);
5164 expect(252, palette
->Count
);
5165 expect(0xff000000, palette
->Entries
[0]);
5166 expect(0xff990066, palette
->Entries
[128]);
5167 expect(0xffffffff, palette
->Entries
[251]);
5170 palette
->Count
= 256;
5171 status
= pGdipInitializePalette(palette
, PaletteTypeOptimal
, 1, FALSE
, bitmap
);
5172 expect(InvalidParameter
, status
);
5175 palette
->Count
= 256;
5176 status
= pGdipInitializePalette(palette
, PaletteTypeOptimal
, 2, FALSE
, bitmap
);
5178 expect(0, palette
->Flags
);
5179 expect(2, palette
->Count
);
5182 palette
->Count
= 256;
5183 status
= pGdipInitializePalette(palette
, PaletteTypeOptimal
, 16, FALSE
, bitmap
);
5185 expect(0, palette
->Flags
);
5186 expect(16, palette
->Count
);
5188 /* passing invalid enumeration palette type crashes under most Windows versions */
5191 GdipDisposeImage((GpImage
*)bitmap
);
5194 #include "pshpack2.h"
5195 static const struct tiff_1x1_data
5200 USHORT number_of_entries
;
5201 struct IFD_entry entry
[12];
5203 struct IFD_rational res
;
5204 short palette_data
[3][256];
5206 BYTE pixel_data
[32];
5209 #ifdef WORDS_BIGENDIAN
5215 FIELD_OFFSET(struct tiff_1x1_data
, number_of_entries
),
5218 { 0xff, IFD_SHORT
, 1, 0 }, /* SUBFILETYPE */
5219 { 0x100, IFD_LONG
, 1, 1 }, /* IMAGEWIDTH */
5220 { 0x101, IFD_LONG
, 1, 1 }, /* IMAGELENGTH */
5221 { 0x102, IFD_SHORT
, 3, FIELD_OFFSET(struct tiff_1x1_data
, bps_data
) }, /* BITSPERSAMPLE */
5222 { 0x103, IFD_SHORT
, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
5223 { 0x106, IFD_SHORT
, 1, 2 }, /* PHOTOMETRIC */
5224 { 0x111, IFD_LONG
, 1, FIELD_OFFSET(struct tiff_1x1_data
, pixel_data
) }, /* STRIPOFFSETS */
5225 { 0x115, IFD_SHORT
, 1, 3 }, /* SAMPLESPERPIXEL */
5226 { 0x11a, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_1x1_data
, res
) },
5227 { 0x11b, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_1x1_data
, res
) },
5228 { 0x128, IFD_SHORT
, 1, 2 }, /* RESOLUTIONUNIT */
5229 { 0x140, IFD_SHORT
, 256*3, FIELD_OFFSET(struct tiff_1x1_data
, palette_data
) } /* COLORMAP */
5235 { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 }
5237 #include "poppack.h"
5239 static void test_tiff_color_formats(void)
5243 int photometric
; /* PhotometricInterpretation */
5244 int samples
; /* SamplesPerPixel */
5245 int bps
; /* BitsPerSample */
5250 { 2, 3, 1, PixelFormat24bppRGB
},
5251 { 2, 3, 4, PixelFormat24bppRGB
},
5252 { 2, 3, 8, PixelFormat24bppRGB
},
5253 { 2, 3, 16, PixelFormat48bppRGB
},
5258 { 2, 4, 1, PixelFormat32bppARGB
},
5259 { 2, 4, 4, PixelFormat32bppARGB
},
5260 { 2, 4, 8, PixelFormat32bppARGB
},
5261 { 2, 4, 16, PixelFormat48bppRGB
},
5264 /* 1 - BlackIsZero (Bilevel) */
5265 { 1, 1, 1, PixelFormat1bppIndexed
},
5266 #if 0 /* FIXME: PNG vs TIFF mismatch */
5267 { 1, 1, 4, PixelFormat8bppIndexed
},
5269 { 1, 1, 8, PixelFormat8bppIndexed
},
5270 { 1, 1, 16, PixelFormat32bppARGB
},
5272 { 1, 1, 32, PixelFormat32bppARGB
},
5273 /* 3 - Palette Color */
5274 { 3, 1, 1, PixelFormat1bppIndexed
},
5275 { 3, 1, 4, PixelFormat4bppIndexed
},
5276 { 3, 1, 8, PixelFormat8bppIndexed
},
5277 #if 0 /* FIXME: for some reason libtiff replaces photometric 3 by 1 for bps > 8 */
5285 { 5, 4, 8, PixelFormat32bppCMYK
},
5286 { 5, 4, 16, PixelFormat48bppRGB
},
5290 BYTE buf
[sizeof(tiff_1x1_data
)];
5294 struct IFD_entry
*tag
, *tag_photo
= NULL
, *tag_bps
= NULL
, *tag_samples
= NULL
, *tag_colormap
= NULL
;
5299 memcpy(buf
, &tiff_1x1_data
, sizeof(tiff_1x1_data
));
5301 count
= *(short *)(buf
+ tiff_1x1_data
.dir_offset
);
5302 tag
= (struct IFD_entry
*)(buf
+ tiff_1x1_data
.dir_offset
+ sizeof(short));
5304 /* verify the TIFF structure */
5305 for (i
= 0; i
< count
; i
++)
5307 if (tag
[i
].id
== 0x102) /* BitsPerSample */
5309 else if (tag
[i
].id
== 0x106) /* PhotometricInterpretation */
5310 tag_photo
= &tag
[i
];
5311 else if (tag
[i
].id
== 0x115) /* SamplesPerPixel */
5312 tag_samples
= &tag
[i
];
5313 else if (tag
[i
].id
== 0x140) /* ColorMap */
5314 tag_colormap
= &tag
[i
];
5317 ok(tag_bps
&& tag_photo
&& tag_samples
&& tag_colormap
, "tag 0x102,0x106,0x115 or 0x140 is missing\n");
5318 if (!tag_bps
|| !tag_photo
|| !tag_samples
|| !tag_colormap
) return;
5320 ok(tag_bps
->type
== IFD_SHORT
, "tag 0x102 should have type IFD_SHORT\n");
5321 bps
= (short *)(buf
+ tag_bps
->value
);
5322 ok(bps
[0] == 8 && bps
[1] == 8 && bps
[2] == 8 && bps
[3] == 0,
5323 "expected bps 8,8,8,0 got %d,%d,%d,%d\n", bps
[0], bps
[1], bps
[2], bps
[3]);
5325 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
5327 tag_colormap
->count
= (1 << td
[i
].bps
) * 3;
5328 tag_photo
->value
= td
[i
].photometric
;
5329 tag_bps
->count
= td
[i
].samples
;
5330 tag_samples
->value
= td
[i
].samples
;
5332 if (td
[i
].samples
== 1)
5333 tag_bps
->value
= td
[i
].bps
;
5334 else if (td
[i
].samples
== 2)
5335 tag_bps
->value
= MAKELONG(td
[i
].bps
, td
[i
].bps
);
5336 else if (td
[i
].samples
== 3)
5338 tag_bps
->value
= (BYTE
*)bps
- buf
;
5339 bps
[0] = bps
[1] = bps
[2] = td
[i
].bps
;
5341 else if (td
[i
].samples
== 4)
5343 tag_bps
->value
= (BYTE
*)bps
- buf
;
5344 bps
[0] = bps
[1] = bps
[2] = bps
[3] = td
[i
].bps
;
5348 ok(0, "%u: unsupported samples count %d\n", i
, td
[i
].samples
);
5352 image
= load_image(buf
, sizeof(buf
));
5355 "%u: (%d,%d,%d) TIFF image loading should have failed\n", i
, td
[i
].photometric
, td
[i
].samples
, td
[i
].bps
);
5357 ok(image
!= NULL
|| broken(!image
) /* XP */, "%u: failed to load TIFF image data (%d,%d,%d)\n",
5358 i
, td
[i
].photometric
, td
[i
].samples
, td
[i
].bps
);
5359 if (!image
) continue;
5361 status
= GdipGetImageType(image
, &type
);
5362 ok(status
== Ok
, "%u: GdipGetImageType error %d\n", i
, status
);
5363 ok(type
== ImageTypeBitmap
, "%u: wrong image type %d\n", i
, type
);
5365 status
= GdipGetImagePixelFormat(image
, &format
);
5367 ok(format
== td
[i
].format
,
5368 "%u: expected %#x, got %#x\n", i
, td
[i
].format
, format
);
5370 GdipDisposeImage(image
);
5376 HMODULE mod
= GetModuleHandleA("gdiplus.dll");
5377 struct GdiplusStartupInput gdiplusStartupInput
;
5378 ULONG_PTR gdiplusToken
;
5380 int (CDECL
* _controlfp_s
)(unsigned int *cur
, unsigned int newval
, unsigned int mask
);
5382 /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */
5383 hmsvcrt
= LoadLibraryA("msvcrt");
5384 _controlfp_s
= (void*)GetProcAddress(hmsvcrt
, "_controlfp_s");
5385 if (_controlfp_s
) _controlfp_s(0, 0, 0x0008001e);
5387 gdiplusStartupInput
.GdiplusVersion
= 1;
5388 gdiplusStartupInput
.DebugEventCallback
= NULL
;
5389 gdiplusStartupInput
.SuppressBackgroundThread
= 0;
5390 gdiplusStartupInput
.SuppressExternalCodecs
= 0;
5392 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, NULL
);
5394 pGdipBitmapGetHistogramSize
= (void*)GetProcAddress(mod
, "GdipBitmapGetHistogramSize");
5395 pGdipBitmapGetHistogram
= (void*)GetProcAddress(mod
, "GdipBitmapGetHistogram");
5396 pGdipImageSetAbort
= (void*)GetProcAddress(mod
, "GdipImageSetAbort");
5398 test_tiff_color_formats();
5399 test_GdipInitializePalette();
5400 test_png_color_formats();
5401 test_supported_encoders();
5402 test_CloneBitmapArea();
5403 test_ARGB_conversion();
5404 test_DrawImage_scale();
5405 test_image_format();
5407 test_DrawImage_SourceCopy();
5408 test_GdipDrawImagePointRect();
5410 test_tiff_palette();
5411 test_GdipGetAllPropertyItems();
5412 test_tiff_properties();
5413 test_gif_properties();
5414 test_image_properties();
5417 test_GetImageDimension();
5418 test_GdipImageGetFrameDimensionsCount();
5419 test_LoadingImages();
5420 test_SavingImages();
5423 test_LockBits_UserBuf();
5424 test_GdipCreateBitmapFromHBITMAP();
5425 test_GdipGetImageFlags();
5426 test_GdipCloneImage();
5429 test_getrawformat();
5431 test_createfromwmf();
5432 test_createfromwmf_noplaceable();
5434 test_createhbitmap();
5435 test_getthumbnail();
5440 test_multiframegif();
5445 test_createeffect();
5446 test_getadjustedpalette();
5450 GdiplusShutdown(gdiplusToken
);