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
27 /* FIXME: They belong to gdipluseffects.h */
28 DEFINE_GUID(BlurEffectGuid
, 0x633c80a4, 0x1843, 0x482b, 0x9e, 0xf2, 0xbe, 0x28, 0x34, 0xc5, 0xfd, 0xd4);
29 DEFINE_GUID(SharpenEffectGuid
, 0x63cbf3ee, 0xc526, 0x402c, 0x8f, 0x71, 0x62, 0xc5, 0x40, 0xbf, 0x51, 0x42);
30 DEFINE_GUID(ColorMatrixEffectGuid
, 0x718f2615, 0x7933, 0x40e3, 0xa5, 0x11, 0x5f, 0x68, 0xfe, 0x14, 0xdd, 0x74);
31 DEFINE_GUID(ColorLUTEffectGuid
, 0xa7ce72a9, 0x0f7f, 0x40d7, 0xb3, 0xcc, 0xd0, 0xc0, 0x2d, 0x5c, 0x32, 0x12);
32 DEFINE_GUID(BrightnessContrastEffectGuid
, 0xd3a1dbe1, 0x8ec4, 0x4c17, 0x9f, 0x4c, 0xea, 0x97, 0xad, 0x1c, 0x34, 0x3d);
33 DEFINE_GUID(HueSaturationLightnessEffectGuid
, 0x8b2dd6c3, 0xeb07, 0x4d87, 0xa5, 0xf0, 0x71, 0x08, 0xe2, 0x6a, 0x9c, 0x5f);
34 DEFINE_GUID(LevelsEffectGuid
, 0x99c354ec, 0x2a31, 0x4f3a, 0x8c, 0x34, 0x17, 0xa8, 0x03, 0xb3, 0x3a, 0x25);
35 DEFINE_GUID(TintEffectGuid
, 0x1077af00, 0x2848, 0x4441, 0x94, 0x89, 0x44, 0xad, 0x4c, 0x2d, 0x7a, 0x2c);
36 DEFINE_GUID(ColorBalanceEffectGuid
, 0x537e597d, 0x251e, 0x48da, 0x96, 0x64, 0x29, 0xca, 0x49, 0x6b, 0x70, 0xf8);
37 DEFINE_GUID(RedEyeCorrectionEffectGuid
, 0x74d29d05, 0x69a4, 0x4266, 0x95, 0x49, 0x3c, 0xc5, 0x28, 0x36, 0xb6, 0x32);
38 DEFINE_GUID(ColorCurveEffectGuid
, 0xdd6a0022, 0x58e4, 0x4a67, 0x9d, 0x9b, 0xd4, 0x8e, 0xb8, 0x81, 0xa5, 0x3d);
40 static GpStatus (WINAPI
*pGdipBitmapGetHistogramSize
)(HistogramFormat
,UINT
*);
41 static GpStatus (WINAPI
*pGdipBitmapGetHistogram
)(GpBitmap
*,HistogramFormat
,UINT
,UINT
*,UINT
*,UINT
*,UINT
*);
42 static GpStatus (WINAPI
*pGdipImageSetAbort
)(GpImage
*,GdiplusAbort
*);
44 static GpStatus (WINGDIPAPI
*pGdipInitializePalette
)(ColorPalette
*,PaletteType
,INT
,BOOL
,GpBitmap
*);
46 #define expect(expected, got) ok((got) == (expected), "Expected %d, got %d\n", (UINT)(expected), (UINT)(got))
47 #define expectf(expected, got) ok(fabs((expected) - (got)) < 0.0001, "Expected %f, got %f\n", (expected), (got))
49 static BOOL
color_match(ARGB c1
, ARGB c2
, BYTE max_diff
)
51 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
53 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
55 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
57 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
61 static void expect_guid(REFGUID expected
, REFGUID got
, int line
, BOOL todo
)
67 StringFromGUID2(got
, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]));
68 WideCharToMultiByte(CP_ACP
, 0, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]), buffer
, sizeof(buffer
), NULL
, NULL
);
69 StringFromGUID2(expected
, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]));
70 WideCharToMultiByte(CP_ACP
, 0, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]), buffer2
, sizeof(buffer2
), NULL
, NULL
);
72 ok_(__FILE__
, line
)(IsEqualGUID(expected
, got
), "Expected %s, got %s\n", buffer2
, buffer
);
75 static void expect_rawformat(REFGUID expected
, GpImage
*img
, int line
, BOOL todo
)
80 stat
= GdipGetImageRawFormat(img
, &raw
);
81 ok_(__FILE__
, line
)(stat
== Ok
, "GdipGetImageRawFormat failed with %d\n", stat
);
82 if(stat
!= Ok
) return;
83 expect_guid(expected
, &raw
, line
, todo
);
86 static void test_bufferrawformat(void* buff
, int size
, REFGUID expected
, int line
, BOOL todo
)
95 hglob
= GlobalAlloc (0, size
);
96 data
= GlobalLock (hglob
);
97 memcpy(data
, buff
, size
);
98 GlobalUnlock(hglob
); data
= NULL
;
100 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
101 ok_(__FILE__
, line
)(hres
== S_OK
, "Failed to create a stream\n");
102 if(hres
!= S_OK
) return;
104 stat
= GdipLoadImageFromStream(stream
, &img
);
105 ok_(__FILE__
, line
)(stat
== Ok
, "Failed to create a Bitmap\n");
107 IStream_Release(stream
);
111 expect_rawformat(expected
, img
, line
, todo
);
113 GdipDisposeImage(img
);
114 IStream_Release(stream
);
117 static void test_Scan0(void)
124 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
126 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
128 GdipDisposeImage((GpImage
*)bm
);
130 bm
= (GpBitmap
*)0xdeadbeef;
131 stat
= GdipCreateBitmapFromScan0(10, -10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
132 expect(InvalidParameter
, stat
);
133 ok( !bm
, "expected null bitmap\n" );
135 bm
= (GpBitmap
*)0xdeadbeef;
136 stat
= GdipCreateBitmapFromScan0(-10, 10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
137 expect(InvalidParameter
, stat
);
138 ok( !bm
, "expected null bitmap\n" );
140 bm
= (GpBitmap
*)0xdeadbeef;
141 stat
= GdipCreateBitmapFromScan0(10, 0, 10, PixelFormat24bppRGB
, NULL
, &bm
);
142 expect(InvalidParameter
, stat
);
143 ok( !bm
, "expected null bitmap\n" );
146 stat
= GdipCreateBitmapFromScan0(10, 10, 12, PixelFormat24bppRGB
, buff
, &bm
);
148 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
150 GdipDisposeImage((GpImage
*)bm
);
152 bm
= (GpBitmap
*) 0xdeadbeef;
153 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, buff
, &bm
);
154 expect(InvalidParameter
, stat
);
155 ok( !bm
, "expected null bitmap\n" );
157 bm
= (GpBitmap
*)0xdeadbeef;
158 stat
= GdipCreateBitmapFromScan0(10, 10, 0, PixelFormat24bppRGB
, buff
, &bm
);
159 expect(InvalidParameter
, stat
);
160 ok( bm
== (GpBitmap
*)0xdeadbeef, "expected deadbeef bitmap\n" );
163 stat
= GdipCreateBitmapFromScan0(10, 10, -8, PixelFormat24bppRGB
, buff
, &bm
);
165 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
167 GdipDisposeImage((GpImage
*)bm
);
169 bm
= (GpBitmap
*)0xdeadbeef;
170 stat
= GdipCreateBitmapFromScan0(10, 10, -10, PixelFormat24bppRGB
, buff
, &bm
);
171 expect(InvalidParameter
, stat
);
172 ok( !bm
, "expected null bitmap\n" );
175 static void test_FromGdiDib(void)
180 BYTE rbmi
[sizeof(BITMAPINFOHEADER
)+256*sizeof(RGBQUAD
)];
181 BITMAPINFO
*bmi
= (BITMAPINFO
*)rbmi
;
186 memset(rbmi
, 0, sizeof(rbmi
));
188 bmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
189 bmi
->bmiHeader
.biWidth
= 10;
190 bmi
->bmiHeader
.biHeight
= 10;
191 bmi
->bmiHeader
.biPlanes
= 1;
192 bmi
->bmiHeader
.biBitCount
= 32;
193 bmi
->bmiHeader
.biCompression
= BI_RGB
;
195 stat
= GdipCreateBitmapFromGdiDib(NULL
, buff
, &bm
);
196 expect(InvalidParameter
, stat
);
198 stat
= GdipCreateBitmapFromGdiDib(bmi
, NULL
, &bm
);
199 expect(InvalidParameter
, stat
);
201 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, NULL
);
202 expect(InvalidParameter
, stat
);
204 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
206 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
209 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
211 expect(PixelFormat32bppRGB
, format
);
213 GdipDisposeImage((GpImage
*)bm
);
216 bmi
->bmiHeader
.biBitCount
= 24;
217 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
219 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
222 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
224 expect(PixelFormat24bppRGB
, format
);
226 GdipDisposeImage((GpImage
*)bm
);
229 bmi
->bmiHeader
.biBitCount
= 16;
230 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
232 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
235 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
237 expect(PixelFormat16bppRGB555
, format
);
239 GdipDisposeImage((GpImage
*)bm
);
242 bmi
->bmiHeader
.biBitCount
= 8;
243 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
245 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
248 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
250 expect(PixelFormat8bppIndexed
, format
);
252 GdipDisposeImage((GpImage
*)bm
);
255 bmi
->bmiHeader
.biBitCount
= 4;
256 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
258 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
261 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
263 expect(PixelFormat4bppIndexed
, format
);
265 GdipDisposeImage((GpImage
*)bm
);
268 bmi
->bmiHeader
.biBitCount
= 1;
269 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
271 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
274 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
276 expect(PixelFormat1bppIndexed
, format
);
278 GdipDisposeImage((GpImage
*)bm
);
281 bmi
->bmiHeader
.biBitCount
= 0;
282 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
283 expect(InvalidParameter
, stat
);
286 static void test_GetImageDimension(void)
290 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
293 bm
= (GpBitmap
*)0xdeadbeef;
294 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
,NULL
, &bm
);
296 ok((GpBitmap
*)0xdeadbeef != bm
, "Expected bitmap to not be 0xdeadbeef\n");
297 ok(NULL
!= bm
, "Expected bitmap to not be NULL\n");
299 stat
= GdipGetImageDimension(NULL
,&w
,&h
);
300 expect(InvalidParameter
, stat
);
302 stat
= GdipGetImageDimension((GpImage
*)bm
,NULL
,&h
);
303 expect(InvalidParameter
, stat
);
305 stat
= GdipGetImageDimension((GpImage
*)bm
,&w
,NULL
);
306 expect(InvalidParameter
, stat
);
310 stat
= GdipGetImageDimension((GpImage
*)bm
,&w
,&h
);
314 GdipDisposeImage((GpImage
*)bm
);
317 static void test_GdipImageGetFrameDimensionsCount(void)
321 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
323 GUID dimension
= {0};
327 bm
= (GpBitmap
*)0xdeadbeef;
328 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
,NULL
, &bm
);
330 ok((GpBitmap
*)0xdeadbeef != bm
, "Expected bitmap to not be 0xdeadbeef\n");
331 ok(NULL
!= bm
, "Expected bitmap to not be NULL\n");
333 stat
= GdipImageGetFrameDimensionsCount(NULL
,&w
);
334 expect(InvalidParameter
, stat
);
336 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bm
,NULL
);
337 expect(InvalidParameter
, stat
);
340 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bm
,&w
);
344 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 1);
346 expect_guid(&FrameDimensionPage
, &dimension
, __LINE__
, FALSE
);
348 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 2);
349 expect(InvalidParameter
, stat
);
351 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 0);
352 expect(InvalidParameter
, stat
);
354 stat
= GdipImageGetFrameCount(NULL
, &dimension
, &count
);
355 expect(InvalidParameter
, stat
);
357 /* WinXP crashes on this test */
360 stat
= GdipImageGetFrameCount((GpImage
*)bm
, &dimension
, NULL
);
361 expect(InvalidParameter
, stat
);
364 stat
= GdipImageGetFrameCount((GpImage
*)bm
, NULL
, &count
);
368 stat
= GdipImageGetFrameCount((GpImage
*)bm
, &dimension
, &count
);
372 GdipBitmapSetPixel(bm
, 0, 0, 0xffffffff);
374 stat
= GdipImageSelectActiveFrame((GpImage
*)bm
, &dimension
, 0);
377 /* SelectActiveFrame has no effect on image data of memory bitmaps */
379 GdipBitmapGetPixel(bm
, 0, 0, &color
);
380 expect(0xffffffff, color
);
382 GdipDisposeImage((GpImage
*)bm
);
385 static void test_LoadingImages(void)
390 static const WCHAR nonexistentW
[] = {'n','o','n','e','x','i','s','t','e','n','t',0};
392 stat
= GdipCreateBitmapFromFile(0, 0);
393 expect(InvalidParameter
, stat
);
395 bm
= (GpBitmap
*)0xdeadbeef;
396 stat
= GdipCreateBitmapFromFile(0, &bm
);
397 expect(InvalidParameter
, stat
);
398 ok(bm
== (GpBitmap
*)0xdeadbeef, "returned %p\n", bm
);
400 bm
= (GpBitmap
*)0xdeadbeef;
401 stat
= GdipCreateBitmapFromFile(nonexistentW
, &bm
);
402 todo_wine
expect(InvalidParameter
, stat
);
403 ok(!bm
, "returned %p\n", bm
);
405 stat
= GdipLoadImageFromFile(0, 0);
406 expect(InvalidParameter
, stat
);
408 img
= (GpImage
*)0xdeadbeef;
409 stat
= GdipLoadImageFromFile(0, &img
);
410 expect(InvalidParameter
, stat
);
411 ok(img
== (GpImage
*)0xdeadbeef, "returned %p\n", img
);
413 img
= (GpImage
*)0xdeadbeef;
414 stat
= GdipLoadImageFromFile(nonexistentW
, &img
);
415 todo_wine
expect(OutOfMemory
, stat
);
416 ok(!img
, "returned %p\n", img
);
418 stat
= GdipLoadImageFromFileICM(0, 0);
419 expect(InvalidParameter
, stat
);
421 img
= (GpImage
*)0xdeadbeef;
422 stat
= GdipLoadImageFromFileICM(0, &img
);
423 expect(InvalidParameter
, stat
);
424 ok(img
== (GpImage
*)0xdeadbeef, "returned %p\n", img
);
426 img
= (GpImage
*)0xdeadbeef;
427 stat
= GdipLoadImageFromFileICM(nonexistentW
, &img
);
428 todo_wine
expect(OutOfMemory
, stat
);
429 ok(!img
, "returned %p\n", img
);
432 static void test_SavingImages(void)
438 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
440 ImageCodecInfo
*codecs
;
441 static const CHAR filenameA
[] = "a.bmp";
442 static const WCHAR filename
[] = { 'a','.','b','m','p',0 };
446 stat
= GdipSaveImageToFile(0, 0, 0, 0);
447 expect(InvalidParameter
, stat
);
450 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
456 stat
= GdipSaveImageToFile((GpImage
*)bm
, 0, 0, 0);
457 expect(InvalidParameter
, stat
);
459 stat
= GdipSaveImageToFile((GpImage
*)bm
, filename
, 0, 0);
460 expect(InvalidParameter
, stat
);
462 /* encoder tests should succeed -- already tested */
463 stat
= GdipGetImageEncodersSize(&n
, &s
);
464 if (stat
!= Ok
|| n
== 0) goto cleanup
;
466 codecs
= GdipAlloc(s
);
467 if (!codecs
) goto cleanup
;
469 stat
= GdipGetImageEncoders(n
, s
, codecs
);
470 if (stat
!= Ok
) goto cleanup
;
472 stat
= GdipSaveImageToFile((GpImage
*)bm
, filename
, &codecs
[0].Clsid
, 0);
475 GdipDisposeImage((GpImage
*)bm
);
478 /* re-load and check image stats */
479 stat
= GdipLoadImageFromFile(filename
, (GpImage
**)&bm
);
481 if (stat
!= Ok
) goto cleanup
;
483 stat
= GdipGetImageDimension((GpImage
*)bm
, &w
, &h
);
484 if (stat
!= Ok
) goto cleanup
;
492 GdipDisposeImage((GpImage
*)bm
);
493 ok(DeleteFileA(filenameA
), "Delete failed.\n");
496 static void test_encoders(void)
501 ImageCodecInfo
*codecs
;
505 static const CHAR bmp_format
[] = "BMP";
507 stat
= GdipGetImageEncodersSize(&n
, &s
);
510 codecs
= GdipAlloc(s
);
514 stat
= GdipGetImageEncoders(n
, s
, NULL
);
515 expect(GenericError
, stat
);
517 stat
= GdipGetImageEncoders(0, s
, codecs
);
518 expect(GenericError
, stat
);
520 stat
= GdipGetImageEncoders(n
, s
-1, codecs
);
521 expect(GenericError
, stat
);
523 stat
= GdipGetImageEncoders(n
, s
+1, codecs
);
524 expect(GenericError
, stat
);
526 stat
= GdipGetImageEncoders(n
, s
, codecs
);
530 for (i
= 0; i
< n
; i
++)
534 WideCharToMultiByte(CP_ACP
, 0, codecs
[i
].FormatDescription
, -1,
537 if (CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0,
539 bmp_format
, -1) == CSTR_EQUAL
) {
545 ok(FALSE
, "No BMP codec found.\n");
550 static void test_LockBits(void)
556 const INT WIDTH
= 10, HEIGHT
= 20;
561 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
569 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffc30000);
572 stat
= GdipBitmapSetPixel(bm
, 2, 8, 0xff480000);
576 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
580 expect(0xc3, ((BYTE
*)bd
.Scan0
)[2]);
581 expect(0x48, ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5]);
583 ((char*)bd
.Scan0
)[2] = 0xff;
585 stat
= GdipBitmapUnlockBits(bm
, &bd
);
589 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
591 expect(0xffff0000, color
);
593 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffc30000);
596 /* read-only, with NULL rect -> whole bitmap lock */
597 stat
= GdipBitmapLockBits(bm
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
599 expect(bd
.Width
, WIDTH
);
600 expect(bd
.Height
, HEIGHT
);
603 ((char*)bd
.Scan0
)[2 + 2*3 + 3*bd
.Stride
] = 0xff;
605 stat
= GdipBitmapUnlockBits(bm
, &bd
);
609 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
611 expect(0xffff0000, color
);
613 /* read-only, consecutive */
614 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
618 stat
= GdipBitmapUnlockBits(bm
, &bd
);
622 stat
= GdipDisposeImage((GpImage
*)bm
);
624 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
628 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
630 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
631 expect(WrongState
, stat
);
633 stat
= GdipBitmapUnlockBits(bm
, &bd
);
636 stat
= GdipDisposeImage((GpImage
*)bm
);
638 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
641 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffff0000);
644 stat
= GdipBitmapSetPixel(bm
, 2, 8, 0xffc30000);
647 /* write, no conversion */
648 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
652 /* all bits are readable, inside the rect or not */
653 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
654 expect(0xc3, ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5]);
656 stat
= GdipBitmapUnlockBits(bm
, &bd
);
660 /* read, conversion */
661 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat32bppARGB
, &bd
);
665 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
667 /* Areas outside the rectangle appear to be uninitialized */
668 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
670 ((BYTE
*)bd
.Scan0
)[2] = 0xc3;
672 stat
= GdipBitmapUnlockBits(bm
, &bd
);
676 /* writes do not work in read mode if there was a conversion */
677 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
679 expect(0xffff0000, color
);
681 /* read/write, conversion */
682 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeWrite
, PixelFormat32bppARGB
, &bd
);
686 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
687 ((BYTE
*)bd
.Scan0
)[1] = 0x88;
689 /* Areas outside the rectangle appear to be uninitialized */
690 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
692 stat
= GdipBitmapUnlockBits(bm
, &bd
);
696 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
698 expect(0xffff8800, color
);
700 /* write, conversion */
701 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat32bppARGB
, &bd
);
707 /* This is completely uninitialized. */
708 ok(0xff != ((BYTE
*)bd
.Scan0
)[2], "original image bits are readable\n");
709 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
712 /* Initialize the buffer so the unlock doesn't access undefined memory */
714 memset(((BYTE
*)bd
.Scan0
) + bd
.Stride
* y
, 0, 12);
716 ((BYTE
*)bd
.Scan0
)[0] = 0x12;
717 ((BYTE
*)bd
.Scan0
)[1] = 0x34;
718 ((BYTE
*)bd
.Scan0
)[2] = 0x56;
720 stat
= GdipBitmapUnlockBits(bm
, &bd
);
724 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
726 expect(0xff563412, color
);
728 stat
= GdipBitmapGetPixel(bm
, 2, 8, &color
);
730 expect(0xffc30000, color
);
732 stat
= GdipDisposeImage((GpImage
*)bm
);
734 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
737 /* write, no modification */
738 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
742 stat
= GdipBitmapUnlockBits(bm
, &bd
);
746 /* write, consecutive */
747 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
751 stat
= GdipBitmapUnlockBits(bm
, &bd
);
755 stat
= GdipDisposeImage((GpImage
*)bm
);
757 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
761 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
766 ((char*)bd
.Scan0
)[2] = 0xff;
768 stat
= GdipBitmapUnlockBits(bm
, &bd
);
772 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
774 expect(0xffff0000, color
);
776 stat
= GdipDisposeImage((GpImage
*)bm
);
780 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
782 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
784 stat
= GdipDisposeImage((GpImage
*)bm
);
788 static void test_LockBits_UserBuf(void)
794 const INT WIDTH
= 10, HEIGHT
= 20;
799 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat32bppARGB
, NULL
, &bm
);
802 memset(bits
, 0xaa, sizeof(bits
));
811 bd
.Stride
= WIDTH
* 4;
812 bd
.PixelFormat
= PixelFormat32bppARGB
;
813 bd
.Scan0
= &bits
[2+3*WIDTH
];
814 bd
.Reserved
= 0xaaaaaaaa;
817 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
820 expect(0xaaaaaaaa, bits
[0]);
821 expect(0, bits
[2+3*WIDTH
]);
823 bits
[2+3*WIDTH
] = 0xdeadbeef;
826 stat
= GdipBitmapUnlockBits(bm
, &bd
);
830 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
835 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
838 expect(0xdeadbeef, bits
[2+3*WIDTH
]);
839 bits
[2+3*WIDTH
] = 0x12345678;
842 stat
= GdipBitmapUnlockBits(bm
, &bd
);
846 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
848 expect(0x12345678, color
);
853 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeWrite
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
856 expect(0x12345678, bits
[2+3*WIDTH
]);
857 bits
[2+3*WIDTH
] = 0xdeadbeef;
860 stat
= GdipBitmapUnlockBits(bm
, &bd
);
864 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
866 expect(0xdeadbeef, color
);
868 stat
= GdipDisposeImage((GpImage
*)bm
);
872 struct BITMAPINFOWITHBITFIELDS
874 BITMAPINFOHEADER bmiHeader
;
878 union BITMAPINFOUNION
881 struct BITMAPINFOWITHBITFIELDS bf
;
884 static void test_GdipCreateBitmapFromHBITMAP(void)
886 GpBitmap
* gpbm
= NULL
;
888 HPALETTE hpal
= NULL
;
891 LOGPALETTE
* LogPal
= NULL
;
893 const REAL WIDTH1
= 5;
894 const REAL HEIGHT1
= 15;
895 const REAL WIDTH2
= 10;
896 const REAL HEIGHT2
= 20;
898 union BITMAPINFOUNION bmi
;
902 stat
= GdipCreateBitmapFromHBITMAP(NULL
, NULL
, NULL
);
903 expect(InvalidParameter
, stat
);
905 hbm
= CreateBitmap(WIDTH1
, HEIGHT1
, 1, 1, NULL
);
906 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, NULL
);
907 expect(InvalidParameter
, stat
);
909 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
911 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
912 expectf(WIDTH1
, width
);
913 expectf(HEIGHT1
, height
);
915 GdipDisposeImage((GpImage
*)gpbm
);
918 memset(buff
, 0, sizeof(buff
));
919 hbm
= CreateBitmap(WIDTH2
, HEIGHT2
, 1, 1, &buff
);
920 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
923 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)gpbm
, __LINE__
, FALSE
);
925 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
926 expectf(WIDTH2
, width
);
927 expectf(HEIGHT2
, height
);
929 GdipDisposeImage((GpImage
*)gpbm
);
932 hdc
= CreateCompatibleDC(0);
933 ok(hdc
!= NULL
, "CreateCompatibleDC failed\n");
934 bmi
.bi
.bmiHeader
.biSize
= sizeof(bmi
.bi
.bmiHeader
);
935 bmi
.bi
.bmiHeader
.biHeight
= HEIGHT1
;
936 bmi
.bi
.bmiHeader
.biWidth
= WIDTH1
;
937 bmi
.bi
.bmiHeader
.biBitCount
= 24;
938 bmi
.bi
.bmiHeader
.biPlanes
= 1;
939 bmi
.bi
.bmiHeader
.biCompression
= BI_RGB
;
940 bmi
.bi
.bmiHeader
.biClrUsed
= 0;
942 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
943 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
947 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
949 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
950 expectf(WIDTH1
, width
);
951 expectf(HEIGHT1
, height
);
954 /* test whether writing to the bitmap affects the original */
955 stat
= GdipBitmapSetPixel(gpbm
, 0, 0, 0xffffffff);
960 GdipDisposeImage((GpImage
*)gpbm
);
963 LogPal
= GdipAlloc(sizeof(LOGPALETTE
));
964 ok(LogPal
!= NULL
, "unable to allocate LOGPALETTE\n");
965 LogPal
->palVersion
= 0x300;
966 LogPal
->palNumEntries
= 1;
967 hpal
= CreatePalette(LogPal
);
968 ok(hpal
!= NULL
, "CreatePalette failed\n");
971 stat
= GdipCreateBitmapFromHBITMAP(hbm
, hpal
, &gpbm
);
975 GdipDisposeImage((GpImage
*)gpbm
);
980 /* 16-bit 555 dib, rgb */
981 bmi
.bi
.bmiHeader
.biBitCount
= 16;
982 bmi
.bi
.bmiHeader
.biCompression
= BI_RGB
;
984 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
985 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
989 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
994 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
996 expectf(WIDTH1
, width
);
997 expectf(HEIGHT1
, height
);
999 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1001 expect(PixelFormat16bppRGB555
, format
);
1003 GdipDisposeImage((GpImage
*)gpbm
);
1007 /* 16-bit 555 dib, with bitfields */
1008 bmi
.bi
.bmiHeader
.biSize
= sizeof(bmi
);
1009 bmi
.bi
.bmiHeader
.biCompression
= BI_BITFIELDS
;
1010 bmi
.bf
.masks
[0] = 0x7c00;
1011 bmi
.bf
.masks
[1] = 0x3e0;
1012 bmi
.bf
.masks
[2] = 0x1f;
1014 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1015 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1019 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1024 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1026 expectf(WIDTH1
, width
);
1027 expectf(HEIGHT1
, height
);
1029 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1031 expect(PixelFormat16bppRGB555
, format
);
1033 GdipDisposeImage((GpImage
*)gpbm
);
1037 /* 16-bit 565 dib, with bitfields */
1038 bmi
.bf
.masks
[0] = 0xf800;
1039 bmi
.bf
.masks
[1] = 0x7e0;
1040 bmi
.bf
.masks
[2] = 0x1f;
1042 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1043 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1047 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1052 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1054 expectf(WIDTH1
, width
);
1055 expectf(HEIGHT1
, height
);
1057 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1059 expect(PixelFormat16bppRGB565
, format
);
1061 GdipDisposeImage((GpImage
*)gpbm
);
1068 static void test_GdipGetImageFlags(void)
1074 img
= (GpImage
*)0xdeadbeef;
1076 stat
= GdipGetImageFlags(NULL
, NULL
);
1077 expect(InvalidParameter
, stat
);
1079 stat
= GdipGetImageFlags(NULL
, &flags
);
1080 expect(InvalidParameter
, stat
);
1082 stat
= GdipGetImageFlags(img
, NULL
);
1083 expect(InvalidParameter
, stat
);
1085 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat1bppIndexed
, NULL
, (GpBitmap
**)&img
);
1087 stat
= GdipGetImageFlags(img
, &flags
);
1089 expect(ImageFlagsHasAlpha
, flags
);
1090 GdipDisposeImage(img
);
1092 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat4bppIndexed
, NULL
, (GpBitmap
**)&img
);
1094 stat
= GdipGetImageFlags(img
, &flags
);
1096 expect(ImageFlagsHasAlpha
, flags
);
1097 GdipDisposeImage(img
);
1099 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat8bppIndexed
, NULL
, (GpBitmap
**)&img
);
1101 stat
= GdipGetImageFlags(img
, &flags
);
1103 expect(ImageFlagsHasAlpha
, flags
);
1104 GdipDisposeImage(img
);
1106 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppGrayScale
, NULL
, (GpBitmap
**)&img
);
1108 stat
= GdipGetImageFlags(img
, &flags
);
1110 expect(ImageFlagsNone
, flags
);
1111 GdipDisposeImage(img
);
1113 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB555
, NULL
, (GpBitmap
**)&img
);
1115 stat
= GdipGetImageFlags(img
, &flags
);
1117 expect(ImageFlagsNone
, flags
);
1118 GdipDisposeImage(img
);
1120 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB565
, NULL
, (GpBitmap
**)&img
);
1122 stat
= GdipGetImageFlags(img
, &flags
);
1124 expect(ImageFlagsNone
, flags
);
1125 GdipDisposeImage(img
);
1127 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppARGB1555
, NULL
, (GpBitmap
**)&img
);
1129 stat
= GdipGetImageFlags(img
, &flags
);
1131 expect(ImageFlagsHasAlpha
, flags
);
1132 GdipDisposeImage(img
);
1134 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, NULL
, (GpBitmap
**)&img
);
1136 stat
= GdipGetImageFlags(img
, &flags
);
1138 expect(ImageFlagsNone
, flags
);
1139 GdipDisposeImage(img
);
1141 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&img
);
1143 stat
= GdipGetImageFlags(img
, &flags
);
1145 expect(ImageFlagsNone
, flags
);
1146 GdipDisposeImage(img
);
1148 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppARGB
, NULL
, (GpBitmap
**)&img
);
1150 stat
= GdipGetImageFlags(img
, &flags
);
1152 expect(ImageFlagsHasAlpha
, flags
);
1153 GdipDisposeImage(img
);
1155 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppPARGB
, NULL
, (GpBitmap
**)&img
);
1157 stat
= GdipGetImageFlags(img
, &flags
);
1159 expect(ImageFlagsHasAlpha
, flags
);
1160 GdipDisposeImage(img
);
1162 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat48bppRGB
, NULL
, (GpBitmap
**)&img
);
1166 stat
= GdipGetImageFlags(img
, &flags
);
1168 expect(ImageFlagsNone
, flags
);
1169 GdipDisposeImage(img
);
1172 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB
, NULL
, (GpBitmap
**)&img
);
1177 stat
= GdipGetImageFlags(img
, &flags
);
1179 expect(ImageFlagsHasAlpha
, flags
);
1180 GdipDisposeImage(img
);
1183 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB
, NULL
, (GpBitmap
**)&img
);
1188 stat
= GdipGetImageFlags(img
, &flags
);
1190 expect(ImageFlagsHasAlpha
, flags
);
1191 GdipDisposeImage(img
);
1195 static void test_GdipCloneImage(void)
1201 GpImage
*image_src
, *image_dest
= NULL
;
1202 const INT WIDTH
= 10, HEIGHT
= 20;
1204 /* Create an image, clone it, delete the original, make sure the copy works */
1205 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
1207 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bm
, __LINE__
, FALSE
);
1209 image_src
= ((GpImage
*)bm
);
1210 stat
= GdipCloneImage(image_src
, &image_dest
);
1212 expect_rawformat(&ImageFormatMemoryBMP
, image_dest
, __LINE__
, FALSE
);
1214 stat
= GdipDisposeImage((GpImage
*)bm
);
1216 stat
= GdipGetImageBounds(image_dest
, &rectF
, &unit
);
1219 /* Treat FP values carefully */
1220 expectf((REAL
)WIDTH
, rectF
.Width
);
1221 expectf((REAL
)HEIGHT
, rectF
.Height
);
1223 stat
= GdipDisposeImage(image_dest
);
1227 static void test_testcontrol(void)
1233 stat
= GdipTestControl(TestControlGetBuildNumber
, ¶m
);
1235 ok(param
!= 0, "Build number expected, got %u\n", param
);
1238 static void test_fromhicon(void)
1240 static const BYTE bmp_bits
[1024];
1241 HBITMAP hbmMask
, hbmColor
;
1245 GpBitmap
*bitmap
= NULL
;
1251 stat
= GdipCreateBitmapFromHICON(NULL
, NULL
);
1252 expect(InvalidParameter
, stat
);
1253 stat
= GdipCreateBitmapFromHICON(NULL
, &bitmap
);
1254 expect(InvalidParameter
, stat
);
1256 /* color icon 1 bit */
1257 hbmMask
= CreateBitmap(16, 16, 1, 1, bmp_bits
);
1258 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1259 hbmColor
= CreateBitmap(16, 16, 1, 1, bmp_bits
);
1260 ok(hbmColor
!= 0, "CreateBitmap failed\n");
1264 info
.hbmMask
= hbmMask
;
1265 info
.hbmColor
= hbmColor
;
1266 hIcon
= CreateIconIndirect(&info
);
1267 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
1268 DeleteObject(hbmMask
);
1269 DeleteObject(hbmColor
);
1271 stat
= GdipCreateBitmapFromHICON(hIcon
, &bitmap
);
1273 broken(stat
== InvalidParameter
), /* Win98 */
1274 "Expected Ok, got %.8x\n", stat
);
1276 /* check attributes */
1277 stat
= GdipGetImageHeight((GpImage
*)bitmap
, &dim
);
1280 stat
= GdipGetImageWidth((GpImage
*)bitmap
, &dim
);
1283 stat
= GdipGetImageType((GpImage
*)bitmap
, &type
);
1285 expect(ImageTypeBitmap
, type
);
1286 stat
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
1288 expect(PixelFormat32bppARGB
, format
);
1290 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bitmap
, __LINE__
, FALSE
);
1291 GdipDisposeImage((GpImage
*)bitmap
);
1295 /* color icon 8 bpp */
1296 hbmMask
= CreateBitmap(16, 16, 1, 8, bmp_bits
);
1297 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1298 hbmColor
= CreateBitmap(16, 16, 1, 8, bmp_bits
);
1299 ok(hbmColor
!= 0, "CreateBitmap failed\n");
1303 info
.hbmMask
= hbmMask
;
1304 info
.hbmColor
= hbmColor
;
1305 hIcon
= CreateIconIndirect(&info
);
1306 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
1307 DeleteObject(hbmMask
);
1308 DeleteObject(hbmColor
);
1310 stat
= GdipCreateBitmapFromHICON(hIcon
, &bitmap
);
1313 /* check attributes */
1314 stat
= GdipGetImageHeight((GpImage
*)bitmap
, &dim
);
1317 stat
= GdipGetImageWidth((GpImage
*)bitmap
, &dim
);
1320 stat
= GdipGetImageType((GpImage
*)bitmap
, &type
);
1322 expect(ImageTypeBitmap
, type
);
1323 stat
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
1325 expect(PixelFormat32bppARGB
, format
);
1327 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bitmap
, __LINE__
, FALSE
);
1328 GdipDisposeImage((GpImage
*)bitmap
);
1334 static const unsigned char pngimage
[285] = {
1335 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
1336 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
1337 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
1338 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
1339 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
1340 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
1341 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
1344 static const unsigned char gifimage
[35] = {
1345 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
1346 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
1349 /* 1x1 pixel transparent gif */
1350 static const unsigned char transparentgif
[] = {
1351 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,
1352 0x00,0x00,0x00,0x21,0xf9,0x04,0x01,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,
1353 0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
1356 static const unsigned char bmpimage
[66] = {
1357 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
1358 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
1359 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
1360 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
1364 static const unsigned char jpgimage
[285] = {
1365 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
1366 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
1367 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
1368 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
1369 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
1370 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
1371 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
1372 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1373 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1374 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
1375 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
1376 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1377 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
1378 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
1379 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1380 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
1381 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
1382 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
1384 /* 1x1 pixel tiff */
1385 static const unsigned char tiffimage
[] = {
1386 0x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00,
1387 0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00,
1388 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1389 0x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01,
1390 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00,
1391 0x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00,
1392 0x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01,
1393 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00,
1394 0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00,
1395 0x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01,
1396 0x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00,
1397 0x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1398 0x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
1399 0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65,
1400 0x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74,
1401 0x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,
1404 /* 320x320 twip wmf */
1405 static const unsigned char wmfimage
[180] = {
1406 0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05,
1407 0x00,0x00,0x00,0x00,0xb1,0x52,0x01,0x00,0x09,0x00,0x00,0x03,0x4f,0x00,0x00,0x00,
1408 0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0b,0x02,0x00,0x00,
1409 0x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x02,0x40,0x01,0x40,0x01,0x04,0x00,0x00,0x00,
1410 0x02,0x01,0x01,0x00,0x04,0x00,0x00,0x00,0x04,0x01,0x0d,0x00,0x08,0x00,0x00,0x00,
1411 0xfa,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
1412 0x2d,0x01,0x00,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,0x01,0x00,0x00,0x00,0x00,0x00,
1413 0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x01,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,
1414 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x02,0x00,
1415 0x07,0x00,0x00,0x00,0x1b,0x04,0x40,0x01,0x40,0x01,0x00,0x00,0x00,0x00,0x04,0x00,
1416 0x00,0x00,0xf0,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0xf0,0x01,0x01,0x00,0x03,0x00,
1419 static void test_getrawformat(void)
1421 test_bufferrawformat((void*)pngimage
, sizeof(pngimage
), &ImageFormatPNG
, __LINE__
, FALSE
);
1422 test_bufferrawformat((void*)gifimage
, sizeof(gifimage
), &ImageFormatGIF
, __LINE__
, FALSE
);
1423 test_bufferrawformat((void*)bmpimage
, sizeof(bmpimage
), &ImageFormatBMP
, __LINE__
, FALSE
);
1424 test_bufferrawformat((void*)jpgimage
, sizeof(jpgimage
), &ImageFormatJPEG
, __LINE__
, FALSE
);
1425 test_bufferrawformat((void*)tiffimage
, sizeof(tiffimage
), &ImageFormatTIFF
, __LINE__
, FALSE
);
1426 test_bufferrawformat((void*)wmfimage
, sizeof(wmfimage
), &ImageFormatWMF
, __LINE__
, FALSE
);
1429 static void test_loadwmf(void)
1440 MetafileHeader header
;
1442 hglob
= GlobalAlloc (0, sizeof(wmfimage
));
1443 data
= GlobalLock (hglob
);
1444 memcpy(data
, wmfimage
, sizeof(wmfimage
));
1445 GlobalUnlock(hglob
); data
= NULL
;
1447 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
1448 ok(hres
== S_OK
, "Failed to create a stream\n");
1449 if(hres
!= S_OK
) return;
1451 stat
= GdipLoadImageFromStream(stream
, &img
);
1452 ok(stat
== Ok
, "Failed to create a Bitmap\n");
1454 IStream_Release(stream
);
1458 IStream_Release(stream
);
1460 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1462 expect(UnitPixel
, unit
);
1463 expectf(0.0, bounds
.X
);
1464 expectf(0.0, bounds
.Y
);
1465 expectf(320.0, bounds
.Width
);
1466 expectf(320.0, bounds
.Height
);
1468 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1470 expectf(1440.0, res
);
1472 stat
= GdipGetImageVerticalResolution(img
, &res
);
1474 expectf(1440.0, res
);
1476 memset(&header
, 0, sizeof(header
));
1477 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1481 expect(MetafileTypeWmfPlaceable
, header
.Type
);
1482 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1483 todo_wine
expect(0x300, header
.Version
);
1484 expect(0, header
.EmfPlusFlags
);
1485 expectf(1440.0, header
.DpiX
);
1486 expectf(1440.0, header
.DpiY
);
1487 expect(0, header
.X
);
1488 expect(0, header
.Y
);
1489 expect(320, header
.Width
);
1490 expect(320, header
.Height
);
1491 expect(1, U(header
).WmfHeader
.mtType
);
1492 expect(0, header
.EmfPlusHeaderSize
);
1493 expect(0, header
.LogicalDpiX
);
1494 expect(0, header
.LogicalDpiY
);
1497 GdipDisposeImage(img
);
1500 static void test_createfromwmf(void)
1508 MetafileHeader header
;
1510 hwmf
= SetMetaFileBitsEx(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
),
1511 wmfimage
+sizeof(WmfPlaceableFileHeader
));
1512 ok(hwmf
!= 0, "SetMetaFileBitsEx failed\n");
1514 stat
= GdipCreateMetafileFromWmf(hwmf
, TRUE
,
1515 (WmfPlaceableFileHeader
*)wmfimage
, (GpMetafile
**)&img
);
1518 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1520 expect(UnitPixel
, unit
);
1521 expectf(0.0, bounds
.X
);
1522 expectf(0.0, bounds
.Y
);
1523 expectf(320.0, bounds
.Width
);
1524 expectf(320.0, bounds
.Height
);
1526 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1528 expectf(1440.0, res
);
1530 stat
= GdipGetImageVerticalResolution(img
, &res
);
1532 expectf(1440.0, res
);
1534 memset(&header
, 0, sizeof(header
));
1535 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1539 expect(MetafileTypeWmfPlaceable
, header
.Type
);
1540 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1541 todo_wine
expect(0x300, header
.Version
);
1542 expect(0, header
.EmfPlusFlags
);
1543 expectf(1440.0, header
.DpiX
);
1544 expectf(1440.0, header
.DpiY
);
1545 expect(0, header
.X
);
1546 expect(0, header
.Y
);
1547 expect(320, header
.Width
);
1548 expect(320, header
.Height
);
1549 expect(1, U(header
).WmfHeader
.mtType
);
1550 expect(0, header
.EmfPlusHeaderSize
);
1551 expect(0, header
.LogicalDpiX
);
1552 expect(0, header
.LogicalDpiY
);
1555 GdipDisposeImage(img
);
1558 static void test_createfromwmf_noplaceable(void)
1564 hwmf
= SetMetaFileBitsEx(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
),
1565 wmfimage
+sizeof(WmfPlaceableFileHeader
));
1566 ok(hwmf
!= 0, "SetMetaFileBitsEx failed\n");
1568 stat
= GdipCreateMetafileFromWmf(hwmf
, TRUE
, NULL
, (GpMetafile
**)&img
);
1571 GdipDisposeImage(img
);
1574 static void test_resolution(void)
1578 GpGraphics
*graphics
;
1581 int screenxres
, screenyres
;
1584 stat
= GdipCreateBitmapFromScan0(1, 1, 32, PixelFormat24bppRGB
, NULL
, &bitmap
);
1587 /* test invalid values */
1588 stat
= GdipGetImageHorizontalResolution(NULL
, &res
);
1589 expect(InvalidParameter
, stat
);
1591 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, NULL
);
1592 expect(InvalidParameter
, stat
);
1594 stat
= GdipGetImageVerticalResolution(NULL
, &res
);
1595 expect(InvalidParameter
, stat
);
1597 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, NULL
);
1598 expect(InvalidParameter
, stat
);
1600 stat
= GdipBitmapSetResolution(NULL
, 96.0, 96.0);
1601 expect(InvalidParameter
, stat
);
1603 stat
= GdipBitmapSetResolution(bitmap
, 0.0, 0.0);
1604 expect(InvalidParameter
, stat
);
1606 /* defaults to screen resolution */
1607 screendc
= GetDC(0);
1609 screenxres
= GetDeviceCaps(screendc
, LOGPIXELSX
);
1610 screenyres
= GetDeviceCaps(screendc
, LOGPIXELSY
);
1612 ReleaseDC(0, screendc
);
1614 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1616 expectf((REAL
)screenxres
, res
);
1618 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1620 expectf((REAL
)screenyres
, res
);
1622 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1624 stat
= GdipGetDpiX(graphics
, &res
);
1626 expectf((REAL
)screenxres
, res
);
1627 stat
= GdipGetDpiY(graphics
, &res
);
1629 expectf((REAL
)screenyres
, res
);
1631 /* test changing the resolution */
1632 stat
= GdipBitmapSetResolution(bitmap
, screenxres
*2.0, screenyres
*3.0);
1635 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1637 expectf(screenxres
*2.0, res
);
1639 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1641 expectf(screenyres
*3.0, res
);
1643 stat
= GdipGetDpiX(graphics
, &res
);
1645 expectf((REAL
)screenxres
, res
);
1646 stat
= GdipGetDpiY(graphics
, &res
);
1648 expectf((REAL
)screenyres
, res
);
1650 stat
= GdipDeleteGraphics(graphics
);
1653 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1655 stat
= GdipGetDpiX(graphics
, &res
);
1657 expectf(screenxres
*2.0, res
);
1658 stat
= GdipGetDpiY(graphics
, &res
);
1660 expectf(screenyres
*3.0, res
);
1661 stat
= GdipDeleteGraphics(graphics
);
1664 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1668 static void test_createhbitmap(void)
1672 HBITMAP hbitmap
, oldhbitmap
;
1678 BitmapData lockeddata
;
1680 memset(bits
, 0x68, 640);
1683 stat
= GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB
, bits
, &bitmap
);
1686 /* test NULL values */
1687 stat
= GdipCreateHBITMAPFromBitmap(NULL
, &hbitmap
, 0);
1688 expect(InvalidParameter
, stat
);
1690 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, NULL
, 0);
1691 expect(InvalidParameter
, stat
);
1693 /* create HBITMAP */
1694 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1699 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1700 expect(sizeof(BITMAP
), ret
);
1702 expect(0, bm
.bmType
);
1703 expect(10, bm
.bmWidth
);
1704 expect(20, bm
.bmHeight
);
1705 expect(40, bm
.bmWidthBytes
);
1706 expect(1, bm
.bmPlanes
);
1707 expect(32, bm
.bmBitsPixel
);
1708 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1712 DWORD val
= *(DWORD
*)bm
.bmBits
;
1713 ok(val
== 0xff686868, "got %x, expected 0xff686868\n", val
);
1716 hdc
= CreateCompatibleDC(NULL
);
1718 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1719 pixel
= GetPixel(hdc
, 5, 5);
1720 SelectObject(hdc
, oldhbitmap
);
1724 expect(0x686868, pixel
);
1726 DeleteObject(hbitmap
);
1729 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1732 /* make (1,0) have no alpha and (2,0) a different blue value. */
1736 /* create alpha Bitmap */
1737 stat
= GdipCreateBitmapFromScan0(8, 20, 32, PixelFormat32bppARGB
, bits
, &bitmap
);
1740 /* create HBITMAP */
1741 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1746 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1747 expect(sizeof(BITMAP
), ret
);
1749 expect(0, bm
.bmType
);
1750 expect(8, bm
.bmWidth
);
1751 expect(20, bm
.bmHeight
);
1752 expect(32, bm
.bmWidthBytes
);
1753 expect(1, bm
.bmPlanes
);
1754 expect(32, bm
.bmBitsPixel
);
1755 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1759 DWORD val
= *(DWORD
*)bm
.bmBits
;
1760 ok(val
== 0x682a2a2a, "got %x, expected 0x682a2a2a\n", val
);
1761 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1762 ok(val
== 0x0, "got %x, expected 0x682a2a2a\n", val
);
1765 hdc
= CreateCompatibleDC(NULL
);
1767 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1768 pixel
= GetPixel(hdc
, 5, 5);
1769 expect(0x2a2a2a, pixel
);
1770 pixel
= GetPixel(hdc
, 1, 0);
1773 SelectObject(hdc
, oldhbitmap
);
1778 DeleteObject(hbitmap
);
1781 /* create HBITMAP with bkgnd colour */
1782 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0xff00ff);
1787 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1788 expect(sizeof(BITMAP
), ret
);
1790 expect(0, bm
.bmType
);
1791 expect(8, bm
.bmWidth
);
1792 expect(20, bm
.bmHeight
);
1793 expect(32, bm
.bmWidthBytes
);
1794 expect(1, bm
.bmPlanes
);
1795 expect(32, bm
.bmBitsPixel
);
1796 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1800 DWORD val
= *(DWORD
*)bm
.bmBits
;
1801 ok(val
== 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val
);
1802 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1803 ok(val
== 0xff00ff, "got %x, expected 0x682a2a2a\n", val
);
1806 hdc
= CreateCompatibleDC(NULL
);
1808 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1809 pixel
= GetPixel(hdc
, 5, 5);
1810 expect(0xc12ac1, pixel
);
1811 pixel
= GetPixel(hdc
, 1, 0);
1812 expect(0xff00ff, pixel
);
1813 pixel
= GetPixel(hdc
, 2, 0);
1814 expect(0xb12ac1, pixel
);
1816 SelectObject(hdc
, oldhbitmap
);
1818 DeleteObject(hbitmap
);
1821 /* create HBITMAP with bkgnd colour with alpha and show it behaves with no alpha. */
1822 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0x80ff00ff);
1827 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1828 expect(sizeof(BITMAP
), ret
);
1830 expect(0, bm
.bmType
);
1831 expect(8, bm
.bmWidth
);
1832 expect(20, bm
.bmHeight
);
1833 expect(32, bm
.bmWidthBytes
);
1834 expect(1, bm
.bmPlanes
);
1835 expect(32, bm
.bmBitsPixel
);
1836 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1840 DWORD val
= *(DWORD
*)bm
.bmBits
;
1841 ok(val
== 0x68c12ac1, "got %x, expected 0x682a2a2a\n", val
);
1842 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1843 ok(val
== 0xff00ff, "got %x, expected 0x682a2a2a\n", val
);
1846 hdc
= CreateCompatibleDC(NULL
);
1848 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1849 pixel
= GetPixel(hdc
, 5, 5);
1850 expect(0xc12ac1, pixel
);
1851 pixel
= GetPixel(hdc
, 1, 0);
1852 expect(0xff00ff, pixel
);
1853 pixel
= GetPixel(hdc
, 2, 0);
1854 expect(0xb12ac1, pixel
);
1856 SelectObject(hdc
, oldhbitmap
);
1858 DeleteObject(hbitmap
);
1861 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1864 /* create HBITMAP from locked data */
1865 memset(bits
, 0x68, 640);
1866 stat
= GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB
, bits
, &bitmap
);
1869 memset(&lockeddata
, 0, sizeof(lockeddata
));
1870 stat
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
| ImageLockModeWrite
,
1871 PixelFormat32bppRGB
, &lockeddata
);
1873 ((DWORD
*)lockeddata
.Scan0
)[0] = 0xff242424;
1874 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1876 stat
= GdipBitmapUnlockBits(bitmap
, &lockeddata
);
1878 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1881 hdc
= CreateCompatibleDC(NULL
);
1882 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1883 pixel
= GetPixel(hdc
, 0, 0);
1884 expect(0x686868, pixel
);
1885 SelectObject(hdc
, oldhbitmap
);
1889 static void test_getthumbnail(void)
1892 GpImage
*bitmap1
, *bitmap2
;
1895 stat
= GdipGetImageThumbnail(NULL
, 0, 0, &bitmap2
, NULL
, NULL
);
1896 expect(InvalidParameter
, stat
);
1898 stat
= GdipCreateBitmapFromScan0(128, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1901 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, NULL
, NULL
, NULL
);
1902 expect(InvalidParameter
, stat
);
1904 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, &bitmap2
, NULL
, NULL
);
1909 stat
= GdipGetImageWidth(bitmap2
, &width
);
1913 stat
= GdipGetImageHeight(bitmap2
, &height
);
1915 expect(120, height
);
1917 GdipDisposeImage(bitmap2
);
1920 GdipDisposeImage(bitmap1
);
1923 stat
= GdipCreateBitmapFromScan0(64, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1926 stat
= GdipGetImageThumbnail(bitmap1
, 32, 32, &bitmap2
, NULL
, NULL
);
1931 stat
= GdipGetImageWidth(bitmap2
, &width
);
1935 stat
= GdipGetImageHeight(bitmap2
, &height
);
1939 GdipDisposeImage(bitmap2
);
1942 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, &bitmap2
, NULL
, NULL
);
1947 stat
= GdipGetImageWidth(bitmap2
, &width
);
1951 stat
= GdipGetImageHeight(bitmap2
, &height
);
1953 expect(120, height
);
1955 GdipDisposeImage(bitmap2
);
1958 GdipDisposeImage(bitmap1
);
1961 static void test_getsetpixel(void)
1966 BYTE bits
[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00,
1967 0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00};
1969 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, bits
, &bitmap
);
1972 /* null parameters */
1973 stat
= GdipBitmapGetPixel(NULL
, 1, 1, &color
);
1974 expect(InvalidParameter
, stat
);
1976 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, NULL
);
1977 expect(InvalidParameter
, stat
);
1979 stat
= GdipBitmapSetPixel(NULL
, 1, 1, 0);
1980 expect(InvalidParameter
, stat
);
1983 stat
= GdipBitmapGetPixel(bitmap
, -1, 1, &color
);
1984 expect(InvalidParameter
, stat
);
1986 stat
= GdipBitmapSetPixel(bitmap
, -1, 1, 0);
1987 expect(InvalidParameter
, stat
);
1989 stat
= GdipBitmapGetPixel(bitmap
, 1, -1, &color
);
1990 ok(stat
== InvalidParameter
||
1991 broken(stat
== Ok
), /* Older gdiplus */
1992 "Expected InvalidParameter, got %.8x\n", stat
);
1994 if (0) /* crashes some gdiplus implementations */
1996 stat
= GdipBitmapSetPixel(bitmap
, 1, -1, 0);
1997 ok(stat
== InvalidParameter
||
1998 broken(stat
== Ok
), /* Older gdiplus */
1999 "Expected InvalidParameter, got %.8x\n", stat
);
2002 stat
= GdipBitmapGetPixel(bitmap
, 2, 1, &color
);
2003 expect(InvalidParameter
, stat
);
2005 stat
= GdipBitmapSetPixel(bitmap
, 2, 1, 0);
2006 expect(InvalidParameter
, stat
);
2008 stat
= GdipBitmapGetPixel(bitmap
, 1, 2, &color
);
2009 expect(InvalidParameter
, stat
);
2011 stat
= GdipBitmapSetPixel(bitmap
, 1, 2, 0);
2012 expect(InvalidParameter
, stat
);
2015 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
2017 expect(0xffffffff, color
);
2019 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2021 expect(0xff0000ff, color
);
2023 stat
= GdipBitmapSetPixel(bitmap
, 1, 1, 0xff676869);
2026 stat
= GdipBitmapSetPixel(bitmap
, 0, 0, 0xff474849);
2029 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
2031 expect(0xff676869, color
);
2033 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2035 expect(0xff474849, color
);
2037 stat
= GdipDisposeImage((GpImage
*)bitmap
);
2041 static void check_halftone_palette(ColorPalette
*palette
)
2043 static const BYTE halftone_values
[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
2046 for (i
=0; i
<palette
->Count
; i
++)
2048 ARGB expected
=0xff000000;
2051 if (i
&1) expected
|= 0x800000;
2052 if (i
&2) expected
|= 0x8000;
2053 if (i
&4) expected
|= 0x80;
2057 expected
= 0xffc0c0c0;
2061 if (i
&1) expected
|= 0xff0000;
2062 if (i
&2) expected
|= 0xff00;
2063 if (i
&4) expected
|= 0xff;
2067 expected
= 0x00000000;
2071 expected
|= halftone_values
[(i
-40)%6];
2072 expected
|= halftone_values
[((i
-40)/6)%6] << 8;
2073 expected
|= halftone_values
[((i
-40)/36)%6] << 16;
2075 ok(expected
== palette
->Entries
[i
], "Expected %.8x, got %.8x, i=%u/%u\n",
2076 expected
, palette
->Entries
[i
], i
, palette
->Count
);
2080 static void test_palette(void)
2086 ColorPalette
*palette
=(ColorPalette
*)buffer
;
2087 ARGB
*entries
= palette
->Entries
;
2090 /* test initial palette from non-indexed bitmap */
2091 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, NULL
, &bitmap
);
2094 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2096 expect(sizeof(UINT
)*2+sizeof(ARGB
), size
);
2098 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2100 expect(0, palette
->Count
);
2102 /* test setting palette on not-indexed bitmap */
2105 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2108 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2110 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2112 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2114 expect(3, palette
->Count
);
2116 GdipDisposeImage((GpImage
*)bitmap
);
2118 /* test initial palette on 1-bit bitmap */
2119 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat1bppIndexed
, NULL
, &bitmap
);
2122 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2124 expect(sizeof(UINT
)*2+sizeof(ARGB
)*2, size
);
2126 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2128 expect(PaletteFlagsGrayScale
, palette
->Flags
);
2129 expect(2, palette
->Count
);
2131 expect(0xff000000, entries
[0]);
2132 expect(0xffffffff, entries
[1]);
2134 /* test getting/setting pixels */
2135 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2137 expect(0xff000000, color
);
2139 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffffffff);
2141 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2145 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2147 expect(0xffffffff, color
);
2150 GdipDisposeImage((GpImage
*)bitmap
);
2152 /* test initial palette on 4-bit bitmap */
2153 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat4bppIndexed
, NULL
, &bitmap
);
2156 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2158 expect(sizeof(UINT
)*2+sizeof(ARGB
)*16, size
);
2160 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2162 expect(0, palette
->Flags
);
2163 expect(16, palette
->Count
);
2165 check_halftone_palette(palette
);
2167 /* test getting/setting pixels */
2168 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2170 expect(0xff000000, color
);
2172 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffff00ff);
2174 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2178 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2180 expect(0xffff00ff, color
);
2183 GdipDisposeImage((GpImage
*)bitmap
);
2185 /* test initial palette on 8-bit bitmap */
2186 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat8bppIndexed
, NULL
, &bitmap
);
2189 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2191 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2193 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2195 expect(PaletteFlagsHalftone
, palette
->Flags
);
2196 expect(256, palette
->Count
);
2198 check_halftone_palette(palette
);
2200 /* test getting/setting pixels */
2201 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2203 expect(0xff000000, color
);
2205 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffcccccc);
2207 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2211 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2213 expect(0xffcccccc, color
);
2216 /* test setting/getting a different palette */
2217 entries
[1] = 0xffcccccc;
2219 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2224 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2226 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2228 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2230 expect(PaletteFlagsHalftone
, palette
->Flags
);
2231 expect(256, palette
->Count
);
2232 expect(0xffcccccc, entries
[1]);
2234 /* test count < 256 */
2235 palette
->Flags
= 12345;
2238 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2242 entries
[3] = 0xdeadbeef;
2244 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2246 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2248 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2250 expect(12345, palette
->Flags
);
2251 expect(3, palette
->Count
);
2252 expect(0xffcccccc, entries
[1]);
2253 expect(0xdeadbeef, entries
[3]);
2255 /* test count > 256 */
2256 palette
->Count
= 257;
2258 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2259 ok(stat
== InvalidParameter
||
2260 broken(stat
== Ok
), /* Old gdiplus behavior */
2261 "Expected %.8x, got %.8x\n", InvalidParameter
, stat
);
2263 GdipDisposeImage((GpImage
*)bitmap
);
2266 static void test_colormatrix(void)
2269 ColorMatrix colormatrix
, graymatrix
;
2270 GpImageAttributes
*imageattr
;
2271 const ColorMatrix identity
= {{
2272 {1.0,0.0,0.0,0.0,0.0},
2273 {0.0,1.0,0.0,0.0,0.0},
2274 {0.0,0.0,1.0,0.0,0.0},
2275 {0.0,0.0,0.0,1.0,0.0},
2276 {0.0,0.0,0.0,0.0,1.0}}};
2277 const ColorMatrix double_red
= {{
2278 {2.0,0.0,0.0,0.0,0.0},
2279 {0.0,1.0,0.0,0.0,0.0},
2280 {0.0,0.0,1.0,0.0,0.0},
2281 {0.0,0.0,0.0,1.0,0.0},
2282 {0.0,0.0,0.0,0.0,1.0}}};
2283 const ColorMatrix asymmetric
= {{
2284 {0.0,1.0,0.0,0.0,0.0},
2285 {0.0,0.0,1.0,0.0,0.0},
2286 {0.0,0.0,0.0,1.0,0.0},
2287 {1.0,0.0,0.0,0.0,0.0},
2288 {0.0,0.0,0.0,0.0,1.0}}};
2289 GpBitmap
*bitmap1
, *bitmap2
;
2290 GpGraphics
*graphics
;
2293 colormatrix
= identity
;
2294 graymatrix
= identity
;
2296 stat
= GdipSetImageAttributesColorMatrix(NULL
, ColorAdjustTypeDefault
,
2297 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2298 expect(InvalidParameter
, stat
);
2300 stat
= GdipCreateImageAttributes(&imageattr
);
2303 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2304 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2307 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2308 TRUE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2309 expect(InvalidParameter
, stat
);
2311 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2312 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2315 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2316 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsSkipGrays
);
2319 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2320 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsAltGray
);
2321 expect(InvalidParameter
, stat
);
2323 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2324 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsAltGray
);
2327 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2328 TRUE
, &colormatrix
, &graymatrix
, 3);
2329 expect(InvalidParameter
, stat
);
2331 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeCount
,
2332 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2333 expect(InvalidParameter
, stat
);
2335 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeAny
,
2336 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2337 expect(InvalidParameter
, stat
);
2339 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2340 FALSE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2343 /* Drawing a bitmap transforms the colors */
2344 colormatrix
= double_red
;
2345 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2346 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2349 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
2352 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
2355 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff40ccee);
2358 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2361 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2362 UnitPixel
, imageattr
, NULL
, NULL
);
2365 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2367 expect(0xff80ccee, color
);
2369 colormatrix
= asymmetric
;
2370 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2371 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2374 stat
= GdipBitmapSetPixel(bitmap2
, 0, 0, 0);
2377 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2378 UnitPixel
, imageattr
, NULL
, NULL
);
2381 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2383 ok(color_match(0xeeff40cc, color
, 3), "expected 0xeeff40cc, got 0x%08x\n", color
);
2385 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2388 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2389 UnitPixel
, imageattr
, NULL
, NULL
);
2392 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2394 ok(color_match(0xff40ccee, color
, 1), "Expected ff40ccee, got %.8x\n", color
);
2396 GdipDeleteGraphics(graphics
);
2397 GdipDisposeImage((GpImage
*)bitmap1
);
2398 GdipDisposeImage((GpImage
*)bitmap2
);
2399 GdipDisposeImageAttributes(imageattr
);
2402 static void test_gamma(void)
2405 GpImageAttributes
*imageattr
;
2406 GpBitmap
*bitmap1
, *bitmap2
;
2407 GpGraphics
*graphics
;
2410 stat
= GdipSetImageAttributesGamma(NULL
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2411 expect(InvalidParameter
, stat
);
2413 stat
= GdipCreateImageAttributes(&imageattr
);
2416 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2419 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeAny
, TRUE
, 1.0);
2420 expect(InvalidParameter
, stat
);
2422 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, -1.0);
2423 expect(InvalidParameter
, stat
);
2425 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.0);
2426 expect(InvalidParameter
, stat
);
2428 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.5);
2431 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0.0);
2434 /* Drawing a bitmap transforms the colors */
2435 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 3.0);
2438 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
2441 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
2444 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff80ffff);
2447 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2450 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2451 UnitPixel
, imageattr
, NULL
, NULL
);
2454 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2456 ok(color_match(0xff20ffff, color
, 1), "Expected ff20ffff, got %.8x\n", color
);
2458 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2461 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2462 UnitPixel
, imageattr
, NULL
, NULL
);
2465 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2467 ok(color_match(0xff80ffff, color
, 1), "Expected ff80ffff, got %.8x\n", color
);
2469 GdipDeleteGraphics(graphics
);
2470 GdipDisposeImage((GpImage
*)bitmap1
);
2471 GdipDisposeImage((GpImage
*)bitmap2
);
2472 GdipDisposeImageAttributes(imageattr
);
2475 /* 1x1 pixel gif, 2 frames; first frame is white, second is black */
2476 static const unsigned char gifanimation
[72] = {
2477 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
2478 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0xf9,0x04,0x00,0x0a,0x00,0xff,
2479 0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x4c,0x01,0x00,
2480 0x21,0xf9,0x04,0x01,0x0a,0x00,0x01,0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,
2481 0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
2484 /* Generated with ImageMagick:
2485 * convert -transparent black -delay 100 -size 8x2 xc:black \
2486 * -dispose none -page +0+0 -size 2x2 xc:red \
2487 * -dispose background -page +2+0 -size 2x2 xc:blue \
2488 * -dispose previous -page +4+0 -size 2x2 xc:green \
2489 * -dispose undefined -page +6+0 -size 2x2 xc:gray \
2492 static const unsigned char gifanimation2
[] = {
2493 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x08, 0x00,
2494 0x02, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
2495 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x64,
2496 0x00, 0x00, 0x00, 0x21, 0xff, 0x0b, 0x4e, 0x45,
2497 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e,
2498 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00,
2499 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
2500 0x02, 0x04, 0x84, 0x8f, 0x09, 0x05, 0x00, 0x21,
2501 0xf9, 0x04, 0x04, 0x64, 0x00, 0x00, 0x00, 0x2c,
2502 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2503 0x81, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
2504 0x00, 0x00, 0xff, 0x00, 0x00, 0x02, 0x03, 0x44,
2505 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x08, 0x64,
2506 0x00, 0x00, 0x00, 0x2c, 0x02, 0x00, 0x00, 0x00,
2507 0x02, 0x00, 0x02, 0x00, 0x81, 0x00, 0x00, 0xff,
2508 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
2509 0xff, 0x02, 0x03, 0x44, 0x34, 0x05, 0x00, 0x21,
2510 0xf9, 0x04, 0x0c, 0x64, 0x00, 0x00, 0x00, 0x2c,
2511 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2512 0x81, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00,
2513 0x80, 0x00, 0x00, 0x80, 0x00, 0x02, 0x03, 0x44,
2514 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x64,
2515 0x00, 0x00, 0x00, 0x2c, 0x06, 0x00, 0x00, 0x00,
2516 0x02, 0x00, 0x02, 0x00, 0x80, 0x7e, 0x7e, 0x7e,
2517 0x00, 0x00, 0x00, 0x02, 0x02, 0x84, 0x51, 0x00,
2521 static ARGB gifanimation2_pixels
[5][4] = {
2523 {0xffff0000, 0, 0, 0},
2524 {0xffff0000, 0xff0000ff, 0, 0},
2525 {0xffff0000, 0, 0xff008000, 0},
2526 {0xffff0000, 0, 0, 0xff7e7e7e}
2529 static void test_multiframegif(void)
2540 PixelFormat pixel_format
;
2541 INT palette_size
, i
, j
;
2542 char palette_buf
[256];
2543 ColorPalette
*palette
;
2544 ARGB
*palette_entries
;
2546 /* Test frame functions with an animated GIF */
2547 hglob
= GlobalAlloc (0, sizeof(gifanimation
));
2548 data
= GlobalLock (hglob
);
2549 memcpy(data
, gifanimation
, sizeof(gifanimation
));
2550 GlobalUnlock(hglob
);
2552 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2553 ok(hres
== S_OK
, "Failed to create a stream\n");
2554 if(hres
!= S_OK
) return;
2556 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2557 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2559 IStream_Release(stream
);
2563 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2565 expect(PixelFormat32bppARGB
, pixel_format
);
2567 stat
= GdipGetImagePaletteSize((GpImage
*)bmp
, &palette_size
);
2569 ok(palette_size
== sizeof(ColorPalette
) ||
2570 broken(palette_size
== sizeof(ColorPalette
)+sizeof(ARGB
[3])),
2571 "palette_size = %d\n", palette_size
);
2573 /* Bitmap starts at frame 0 */
2575 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2577 expect(0xffffffff, color
);
2579 /* Check that we get correct metadata */
2580 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2584 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2586 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2589 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2593 /* SelectActiveFrame overwrites our current data */
2594 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2598 GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2600 expect(0xff000000, color
);
2602 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2606 GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2608 expect(0xffffffff, color
);
2610 /* Write over the image data */
2611 stat
= GdipBitmapSetPixel(bmp
, 0, 0, 0xff000000);
2614 /* Switching to the same frame does not overwrite our changes */
2615 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2618 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2620 expect(0xff000000, color
);
2622 /* But switching to another frame and back does */
2623 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2626 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2629 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2631 expect(0xffffffff, color
);
2633 /* rotate/flip discards the information about other frames */
2634 stat
= GdipImageRotateFlip((GpImage
*)bmp
, Rotate90FlipNone
);
2638 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2642 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bmp
, __LINE__
, FALSE
);
2644 GdipDisposeImage((GpImage
*)bmp
);
2645 IStream_Release(stream
);
2647 /* Test with a non-animated gif */
2648 hglob
= GlobalAlloc (0, sizeof(gifimage
));
2649 data
= GlobalLock (hglob
);
2650 memcpy(data
, gifimage
, sizeof(gifimage
));
2651 GlobalUnlock(hglob
);
2653 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2654 ok(hres
== S_OK
, "Failed to create a stream\n");
2655 if(hres
!= S_OK
) return;
2657 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2658 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2660 IStream_Release(stream
);
2664 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2666 expect(PixelFormat8bppIndexed
, pixel_format
);
2668 /* Check metadata */
2669 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2673 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2675 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2678 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2682 GdipDisposeImage((GpImage
*)bmp
);
2683 IStream_Release(stream
);
2685 /* Test with a non-animated transparent gif */
2686 hglob
= GlobalAlloc (0, sizeof(transparentgif
));
2687 data
= GlobalLock (hglob
);
2688 memcpy(data
, transparentgif
, sizeof(transparentgif
));
2689 GlobalUnlock(hglob
);
2691 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2692 ok(hres
== S_OK
, "Failed to create a stream\n");
2694 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2695 IStream_Release(stream
);
2696 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2698 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2700 expect(PixelFormat8bppIndexed
, pixel_format
);
2702 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2706 stat
= GdipGetImagePaletteSize((GpImage
*)bmp
, &palette_size
);
2708 ok(palette_size
== sizeof(ColorPalette
)+sizeof(ARGB
),
2709 "palette_size = %d\n", palette_size
);
2711 memset(palette_buf
, 0xfe, sizeof(palette_buf
));
2712 palette
= (ColorPalette
*)palette_buf
;
2713 stat
= GdipGetImagePalette((GpImage
*)bmp
, palette
,
2714 sizeof(ColorPalette
)+sizeof(ARGB
));
2715 palette_entries
= palette
->Entries
;
2717 expect(PaletteFlagsHasAlpha
, palette
->Flags
);
2718 expect(2, palette
->Count
);
2719 expect(0, palette_entries
[0]);
2720 expect(0xff000000, palette_entries
[1]);
2723 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2727 GdipDisposeImage((GpImage
*)bmp
);
2729 /* Test frame dispose methods */
2730 hglob
= GlobalAlloc (0, sizeof(gifanimation2
));
2731 data
= GlobalLock (hglob
);
2732 memcpy(data
, gifanimation2
, sizeof(gifanimation2
));
2733 GlobalUnlock(hglob
);
2735 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2736 ok(hres
== S_OK
, "Failed to create a stream\n");
2738 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2739 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2740 IStream_Release(stream
);
2742 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2744 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2746 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2750 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2754 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 3);
2756 stat
= GdipBitmapGetPixel(bmp
, 2, 0, &color
);
2758 ok(color
==0 || broken(color
==0xff0000ff), "color = %x\n", color
);
2760 win_skip("broken animated gif support\n");
2761 GdipDisposeImage((GpImage
*)bmp
);
2765 for(i
=0; i
<6; i
++) {
2766 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, i
%5);
2769 for(j
=0; j
<4; j
++) {
2770 stat
= GdipBitmapGetPixel(bmp
, j
*2, 0, &color
);
2772 ok(gifanimation2_pixels
[i
%5][j
] == color
, "at %d,%d got %x, expected %x\n", i
, j
, color
, gifanimation2_pixels
[i
%5][j
]);
2776 GdipDisposeImage((GpImage
*)bmp
);
2779 static void test_rotateflip(void)
2784 static const BYTE orig_bits
[24] = {
2785 0,0,0xff, 0,0xff,0, 0xff,0,0, 23,23,23,
2786 0xff,0xff,0, 0xff,0,0xff, 0,0xff,0xff, 23,23,23};
2790 memcpy(bits
, orig_bits
, sizeof(bits
));
2791 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2794 stat
= GdipImageRotateFlip(bitmap
, Rotate90FlipNone
);
2797 stat
= GdipGetImageWidth(bitmap
, &width
);
2799 stat
= GdipGetImageHeight(bitmap
, &height
);
2804 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2806 expect(0xff00ffff, color
);
2808 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 0, &color
);
2810 expect(0xffff0000, color
);
2812 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 2, &color
);
2814 expect(0xffffff00, color
);
2816 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 2, &color
);
2818 expect(0xff0000ff, color
);
2822 expect(0xff, bits
[2]);
2824 GdipDisposeImage(bitmap
);
2826 memcpy(bits
, orig_bits
, sizeof(bits
));
2827 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2830 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipX
);
2833 stat
= GdipGetImageWidth(bitmap
, &width
);
2835 stat
= GdipGetImageHeight(bitmap
, &height
);
2840 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2842 expect(0xff0000ff, color
);
2844 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
2846 expect(0xffff0000, color
);
2848 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
2850 expect(0xffffff00, color
);
2852 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
2854 expect(0xff00ffff, color
);
2858 expect(0xff, bits
[2]);
2860 GdipDisposeImage(bitmap
);
2862 memcpy(bits
, orig_bits
, sizeof(bits
));
2863 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2866 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipY
);
2869 stat
= GdipGetImageWidth(bitmap
, &width
);
2871 stat
= GdipGetImageHeight(bitmap
, &height
);
2876 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2878 expect(0xff00ffff, color
);
2880 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
2882 expect(0xffffff00, color
);
2884 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
2886 expect(0xffff0000, color
);
2888 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
2890 expect(0xff0000ff, color
);
2894 expect(0xff, bits
[2]);
2896 GdipDisposeImage(bitmap
);
2899 static void test_remaptable(void)
2902 GpImageAttributes
*imageattr
;
2903 GpBitmap
*bitmap1
, *bitmap2
;
2904 GpGraphics
*graphics
;
2908 map
= GdipAlloc(sizeof(ColorMap
));
2910 map
->oldColor
.Argb
= 0xff00ff00;
2911 map
->newColor
.Argb
= 0xffff00ff;
2913 stat
= GdipSetImageAttributesRemapTable(NULL
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
2914 expect(InvalidParameter
, stat
);
2916 stat
= GdipCreateImageAttributes(&imageattr
);
2919 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, NULL
);
2920 expect(InvalidParameter
, stat
);
2922 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeCount
, TRUE
, 1, map
);
2923 expect(InvalidParameter
, stat
);
2925 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeAny
, TRUE
, 1, map
);
2926 expect(InvalidParameter
, stat
);
2928 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0, map
);
2929 expect(InvalidParameter
, stat
);
2931 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0, NULL
);
2934 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
2937 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
2940 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
2943 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff00ff00);
2946 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2949 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2950 UnitPixel
, imageattr
, NULL
, NULL
);
2953 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2955 ok(color_match(0xffff00ff, color
, 1), "Expected ffff00ff, got %.8x\n", color
);
2957 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2960 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2961 UnitPixel
, imageattr
, NULL
, NULL
);
2964 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2966 ok(color_match(0xff00ff00, color
, 1), "Expected ff00ff00, got %.8x\n", color
);
2968 GdipDeleteGraphics(graphics
);
2969 GdipDisposeImage((GpImage
*)bitmap1
);
2970 GdipDisposeImage((GpImage
*)bitmap2
);
2971 GdipDisposeImageAttributes(imageattr
);
2975 static void test_colorkey(void)
2978 GpImageAttributes
*imageattr
;
2979 GpBitmap
*bitmap1
, *bitmap2
;
2980 GpGraphics
*graphics
;
2983 stat
= GdipSetImageAttributesColorKeys(NULL
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
2984 expect(InvalidParameter
, stat
);
2986 stat
= GdipCreateImageAttributes(&imageattr
);
2989 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeCount
, TRUE
, 0xff405060, 0xff708090);
2990 expect(InvalidParameter
, stat
);
2992 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeAny
, TRUE
, 0xff405060, 0xff708090);
2993 expect(InvalidParameter
, stat
);
2995 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
2998 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
3001 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
3004 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0x20405060);
3007 stat
= GdipBitmapSetPixel(bitmap1
, 0, 1, 0x40506070);
3010 stat
= GdipBitmapSetPixel(bitmap1
, 1, 0, 0x60708090);
3013 stat
= GdipBitmapSetPixel(bitmap1
, 1, 1, 0xffffffff);
3016 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
3019 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
3020 UnitPixel
, imageattr
, NULL
, NULL
);
3023 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
3025 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
3027 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
3029 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
3031 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
3033 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
3035 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
3037 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
3039 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
3042 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
3043 UnitPixel
, imageattr
, NULL
, NULL
);
3046 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
3048 ok(color_match(0x20405060, color
, 1), "Expected 20405060, got %.8x\n", color
);
3050 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
3052 ok(color_match(0x40506070, color
, 1), "Expected 40506070, got %.8x\n", color
);
3054 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
3056 ok(color_match(0x60708090, color
, 1), "Expected 60708090, got %.8x\n", color
);
3058 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
3060 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
3063 GdipDeleteGraphics(graphics
);
3064 GdipDisposeImage((GpImage
*)bitmap1
);
3065 GdipDisposeImage((GpImage
*)bitmap2
);
3066 GdipDisposeImageAttributes(imageattr
);
3069 static void test_dispose(void)
3073 char invalid_image
[256];
3075 stat
= GdipDisposeImage(NULL
);
3076 expect(InvalidParameter
, stat
);
3078 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, (GpBitmap
**)&image
);
3081 stat
= GdipDisposeImage(image
);
3084 stat
= GdipDisposeImage(image
);
3085 expect(ObjectBusy
, stat
);
3087 memset(invalid_image
, 0, 256);
3088 stat
= GdipDisposeImage((GpImage
*)invalid_image
);
3089 expect(ObjectBusy
, stat
);
3092 static LONG
obj_refcount(void *obj
)
3094 IUnknown_AddRef((IUnknown
*)obj
);
3095 return IUnknown_Release((IUnknown
*)obj
);
3098 static GpImage
*load_image(const BYTE
*image_data
, UINT image_size
)
3105 GpImage
*image
= NULL
, *clone
;
3106 ImageType image_type
;
3107 LONG refcount
, old_refcount
;
3109 hmem
= GlobalAlloc(0, image_size
);
3110 data
= GlobalLock(hmem
);
3111 memcpy(data
, image_data
, image_size
);
3114 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
3115 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
3116 if (hr
!= S_OK
) return NULL
;
3118 refcount
= obj_refcount(stream
);
3119 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3121 status
= GdipLoadImageFromStream(stream
, &image
);
3124 IStream_Release(stream
);
3128 status
= GdipGetImageType(image
, &image_type
);
3129 ok(status
== Ok
, "GdipGetImageType error %d\n", status
);
3131 refcount
= obj_refcount(stream
);
3132 if (image_type
== ImageTypeBitmap
)
3133 ok(refcount
> 1, "expected stream refcount > 1, got %d\n", refcount
);
3135 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3136 old_refcount
= refcount
;
3138 status
= GdipCloneImage(image
, &clone
);
3139 ok(status
== Ok
, "GdipCloneImage error %d\n", status
);
3140 refcount
= obj_refcount(stream
);
3141 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3142 status
= GdipDisposeImage(clone
);
3143 ok(status
== Ok
, "GdipDisposeImage error %d\n", status
);
3144 refcount
= obj_refcount(stream
);
3145 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3147 refcount
= IStream_Release(stream
);
3148 if (image_type
== ImageTypeBitmap
)
3149 ok(refcount
>= 1, "expected stream refcount != 0\n");
3151 ok(refcount
== 0, "expected stream refcount 0, got %d\n", refcount
);
3156 static void test_image_properties(void)
3158 static const struct test_data
3160 const BYTE
*image_data
;
3162 ImageType image_type
;
3164 UINT prop_count2
; /* if win7 behaves differently */
3165 /* 1st property attributes */
3167 UINT prop_size2
; /* if win7 behaves differently */
3169 UINT prop_id2
; /* if win7 behaves differently */
3173 { pngimage
, sizeof(pngimage
), ImageTypeBitmap
, 4, ~0, 1, 20, 0x5110, 0x132 },
3174 { jpgimage
, sizeof(jpgimage
), ImageTypeBitmap
, 2, ~0, 128, 0, 0x5090, 0x5091 },
3175 { tiffimage
, sizeof(tiffimage
), ImageTypeBitmap
, 16, 0, 4, 0, 0xfe, 0 },
3176 { bmpimage
, sizeof(bmpimage
), ImageTypeBitmap
, 0, 0, 0, 0, 0, 0 },
3177 { wmfimage
, sizeof(wmfimage
), ImageTypeMetafile
, 0, 0, 0, 0, 0, 0 }
3181 UINT prop_count
, prop_size
, i
;
3182 PROPID prop_id
[16] = { 0 };
3183 ImageType image_type
;
3190 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
3192 image
= load_image(td
[i
].image_data
, td
[i
].image_size
);
3195 trace("%u: failed to load image data\n", i
);
3199 status
= GdipGetImageType(image
, &image_type
);
3200 ok(status
== Ok
, "%u: GdipGetImageType error %d\n", i
, status
);
3201 ok(td
[i
].image_type
== image_type
, "%u: expected image_type %d, got %d\n",
3202 i
, td
[i
].image_type
, image_type
);
3204 status
= GdipGetPropertyCount(image
, &prop_count
);
3205 ok(status
== Ok
, "%u: GdipGetPropertyCount error %d\n", i
, status
);
3206 todo_wine_if(td
[i
].image_data
== pngimage
|| td
[i
].image_data
== jpgimage
)
3207 ok(td
[i
].prop_count
== prop_count
|| td
[i
].prop_count2
== prop_count
,
3208 " %u: expected property count %u or %u, got %u\n",
3209 i
, td
[i
].prop_count
, td
[i
].prop_count2
, prop_count
);
3211 status
= GdipGetPropertyItemSize(NULL
, 0, &prop_size
);
3212 expect(InvalidParameter
, status
);
3213 status
= GdipGetPropertyItemSize(image
, 0, NULL
);
3214 expect(InvalidParameter
, status
);
3215 status
= GdipGetPropertyItemSize(image
, 0, &prop_size
);
3216 if (image_type
== ImageTypeMetafile
)
3217 expect(NotImplemented
, status
);
3219 expect(PropertyNotFound
, status
);
3221 status
= GdipGetPropertyItem(NULL
, 0, 0, &item
.data
);
3222 expect(InvalidParameter
, status
);
3223 status
= GdipGetPropertyItem(image
, 0, 0, NULL
);
3224 expect(InvalidParameter
, status
);
3225 status
= GdipGetPropertyItem(image
, 0, 0, &item
.data
);
3226 if (image_type
== ImageTypeMetafile
)
3227 expect(NotImplemented
, status
);
3229 expect(PropertyNotFound
, status
);
3231 /* FIXME: remove once Wine is fixed */
3232 if (td
[i
].prop_count
!= prop_count
)
3234 GdipDisposeImage(image
);
3238 status
= GdipGetPropertyIdList(NULL
, prop_count
, prop_id
);
3239 expect(InvalidParameter
, status
);
3240 status
= GdipGetPropertyIdList(image
, prop_count
, NULL
);
3241 expect(InvalidParameter
, status
);
3242 status
= GdipGetPropertyIdList(image
, 0, prop_id
);
3243 if (image_type
== ImageTypeMetafile
)
3244 expect(NotImplemented
, status
);
3245 else if (prop_count
== 0)
3248 expect(InvalidParameter
, status
);
3249 status
= GdipGetPropertyIdList(image
, prop_count
- 1, prop_id
);
3250 if (image_type
== ImageTypeMetafile
)
3251 expect(NotImplemented
, status
);
3253 expect(InvalidParameter
, status
);
3254 status
= GdipGetPropertyIdList(image
, prop_count
+ 1, prop_id
);
3255 if (image_type
== ImageTypeMetafile
)
3256 expect(NotImplemented
, status
);
3258 expect(InvalidParameter
, status
);
3259 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3260 if (image_type
== ImageTypeMetafile
)
3261 expect(NotImplemented
, status
);
3265 if (prop_count
!= 0)
3266 ok(td
[i
].prop_id
== prop_id
[0] || td
[i
].prop_id2
== prop_id
[0],
3267 " %u: expected property id %#x or %#x, got %#x\n",
3268 i
, td
[i
].prop_id
, td
[i
].prop_id2
, prop_id
[0]);
3273 status
= GdipGetPropertyItemSize(image
, prop_id
[0], &prop_size
);
3274 if (prop_count
== 0)
3275 expect(PropertyNotFound
, status
);
3280 assert(sizeof(item
) >= prop_size
);
3281 ok(prop_size
> sizeof(PropertyItem
), "%u: got too small prop_size %u\n",
3283 ok(td
[i
].prop_size
+ sizeof(PropertyItem
) == prop_size
||
3284 td
[i
].prop_size2
+ sizeof(PropertyItem
) == prop_size
,
3285 " %u: expected property size %u or %u, got %u\n",
3286 i
, td
[i
].prop_size
, td
[i
].prop_size2
, prop_size
);
3288 status
= GdipGetPropertyItem(image
, prop_id
[0], 0, &item
.data
);
3289 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3290 "%u: expected InvalidParameter, got %d\n", i
, status
);
3291 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
- 1, &item
.data
);
3292 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3293 "%u: expected InvalidParameter, got %d\n", i
, status
);
3294 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
+ 1, &item
.data
);
3295 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3296 "%u: expected InvalidParameter, got %d\n", i
, status
);
3297 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
, &item
.data
);
3299 ok(prop_id
[0] == item
.data
.id
,
3300 "%u: expected property id %#x, got %#x\n", i
, prop_id
[0], item
.data
.id
);
3304 GdipDisposeImage(image
);
3312 #define IFD_RATIONAL 5
3314 #define IFD_UNDEFINED 7
3315 #define IFD_SSHORT 8
3317 #define IFD_SRATIONAL 10
3318 #define IFD_FLOAT 11
3319 #define IFD_DOUBLE 12
3321 #ifndef PropertyTagTypeSByte
3322 #define PropertyTagTypeSByte 6
3323 #define PropertyTagTypeSShort 8
3324 #define PropertyTagTypeFloat 11
3325 #define PropertyTagTypeDouble 12
3328 static UINT
documented_type(UINT type
)
3332 case PropertyTagTypeSByte
: return PropertyTagTypeByte
;
3333 case PropertyTagTypeSShort
: return PropertyTagTypeShort
;
3334 case PropertyTagTypeFloat
: return PropertyTagTypeUndefined
;
3335 case PropertyTagTypeDouble
: return PropertyTagTypeUndefined
;
3336 default: return type
;
3340 #include "pshpack2.h"
3355 static const struct tiff_data
3360 USHORT number_of_entries
;
3361 struct IFD_entry entry
[40];
3363 struct IFD_rational xres
;
3365 struct IFD_rational srational_val
;
3370 struct IFD_rational rational
[3];
3374 #ifdef WORDS_BIGENDIAN
3380 FIELD_OFFSET(struct tiff_data
, number_of_entries
),
3383 { 0xff, IFD_SHORT
, 1, 0 }, /* SUBFILETYPE */
3384 { 0x100, IFD_LONG
, 1, 1 }, /* IMAGEWIDTH */
3385 { 0x101, IFD_LONG
, 1, 1 }, /* IMAGELENGTH */
3386 { 0x102, IFD_SHORT
, 1, 1 }, /* BITSPERSAMPLE */
3387 { 0x103, IFD_SHORT
, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
3388 { 0x106, IFD_SHORT
, 1, 1 }, /* PHOTOMETRIC */
3389 { 0x111, IFD_LONG
, 1, FIELD_OFFSET(struct tiff_data
, pixel_data
) }, /* STRIPOFFSETS */
3390 { 0x115, IFD_SHORT
, 1, 1 }, /* SAMPLESPERPIXEL */
3391 { 0x116, IFD_LONG
, 1, 1 }, /* ROWSPERSTRIP */
3392 { 0x117, IFD_LONG
, 1, 1 }, /* STRIPBYTECOUNT */
3393 { 0x11a, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3394 { 0x11b, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3395 { 0x128, IFD_SHORT
, 1, 2 }, /* RESOLUTIONUNIT */
3396 { 0xf001, IFD_BYTE
, 1, 0x11223344 },
3397 { 0xf002, IFD_BYTE
, 4, 0x11223344 },
3398 { 0xf003, IFD_SBYTE
, 1, 0x11223344 },
3399 { 0xf004, IFD_SSHORT
, 1, 0x11223344 },
3400 { 0xf005, IFD_SSHORT
, 2, 0x11223344 },
3401 { 0xf006, IFD_SLONG
, 1, 0x11223344 },
3402 { 0xf007, IFD_FLOAT
, 1, 0x11223344 },
3403 { 0xf008, IFD_DOUBLE
, 1, FIELD_OFFSET(struct tiff_data
, double_val
) },
3404 { 0xf009, IFD_SRATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, srational_val
) },
3405 { 0xf00a, IFD_BYTE
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3406 { 0xf00b, IFD_SSHORT
, 4, FIELD_OFFSET(struct tiff_data
, short_val
) },
3407 { 0xf00c, IFD_SLONG
, 2, FIELD_OFFSET(struct tiff_data
, long_val
) },
3408 { 0xf00e, IFD_ASCII
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3409 { 0xf00f, IFD_ASCII
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3410 { 0xf010, IFD_UNDEFINED
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3411 { 0xf011, IFD_UNDEFINED
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3412 /* Some gdiplus versions ignore these fields.
3413 { 0xf012, IFD_BYTE, 0, 0x11223344 },
3414 { 0xf013, IFD_SHORT, 0, 0x11223344 },
3415 { 0xf014, IFD_LONG, 0, 0x11223344 },
3416 { 0xf015, IFD_FLOAT, 0, 0x11223344 },*/
3417 { 0xf016, IFD_SRATIONAL
, 3, FIELD_OFFSET(struct tiff_data
, rational
) },
3418 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3419 { 0xf017, IFD_FLOAT
, 2, FIELD_OFFSET(struct tiff_data
, float_val
) },
3423 1234567890.0987654321,
3424 { 0x1a2b3c4d, 0x5a6b7c8d },
3426 { 0x0101, 0x0202, 0x0303, 0x0404 },
3427 { 0x11223344, 0x55667788 },
3428 { (FLOAT
)1234.5678, (FLOAT
)8765.4321 },
3429 { { 0x01020304, 0x05060708 }, { 0x10203040, 0x50607080 }, { 0x11223344, 0x55667788 } },
3430 { 0x11, 0x22, 0x33, 0 }
3432 #include "poppack.h"
3434 static void test_tiff_properties(void)
3436 static const struct test_data
3438 ULONG type
, id
, length
;
3439 const BYTE value
[24];
3442 { PropertyTagTypeShort
, 0xff, 2, { 0 } },
3443 { PropertyTagTypeLong
, 0x100, 4, { 1 } },
3444 { PropertyTagTypeLong
, 0x101, 4, { 1 } },
3445 { PropertyTagTypeShort
, 0x102, 2, { 1 } },
3446 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3447 { PropertyTagTypeShort
, 0x106, 2, { 1 } },
3448 { PropertyTagTypeLong
, 0x111, 4, { 0x44,0x02 } },
3449 { PropertyTagTypeShort
, 0x115, 2, { 1 } },
3450 { PropertyTagTypeLong
, 0x116, 4, { 1 } },
3451 { PropertyTagTypeLong
, 0x117, 4, { 1 } },
3452 { PropertyTagTypeRational
, 0x11a, 8, { 0x84,0x03,0,0,0x03 } },
3453 { PropertyTagTypeRational
, 0x11b, 8, { 0x84,0x03,0,0,0x03 } },
3454 { PropertyTagTypeShort
, 0x128, 2, { 2 } },
3455 { PropertyTagTypeByte
, 0xf001, 1, { 0x44 } },
3456 { PropertyTagTypeByte
, 0xf002, 4, { 0x44,0x33,0x22,0x11 } },
3457 { PropertyTagTypeSByte
, 0xf003, 1, { 0x44 } },
3458 { PropertyTagTypeSShort
, 0xf004, 2, { 0x44,0x33 } },
3459 { PropertyTagTypeSShort
, 0xf005, 4, { 0x44,0x33,0x22,0x11 } },
3460 { PropertyTagTypeSLONG
, 0xf006, 4, { 0x44,0x33,0x22,0x11 } },
3461 { PropertyTagTypeFloat
, 0xf007, 4, { 0x44,0x33,0x22,0x11 } },
3462 { PropertyTagTypeDouble
, 0xf008, 8, { 0x2c,0x52,0x86,0xb4,0x80,0x65,0xd2,0x41 } },
3463 { PropertyTagTypeSRational
, 0xf009, 8, { 0x4d, 0x3c, 0x2b, 0x1a, 0x8d, 0x7c, 0x6b, 0x5a } },
3464 { PropertyTagTypeByte
, 0xf00a, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3465 { PropertyTagTypeSShort
, 0xf00b, 8, { 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04 } },
3466 { PropertyTagTypeSLONG
, 0xf00c, 8, { 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3467 { PropertyTagTypeASCII
, 0xf00e, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3468 { PropertyTagTypeASCII
, 0xf00f, 5, { 'a','b','c','d' } },
3469 { PropertyTagTypeUndefined
, 0xf010, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3470 { PropertyTagTypeUndefined
, 0xf011, 4, { 'a','b','c','d' } },
3471 { PropertyTagTypeSRational
, 0xf016, 24,
3472 { 0x04,0x03,0x02,0x01,0x08,0x07,0x06,0x05,
3473 0x40,0x30,0x20,0x10,0x80,0x70,0x60,0x50,
3474 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3475 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3476 { PropertyTagTypeFloat
, 0xf017, 8, { 0x2b,0x52,0x9a,0x44,0xba,0xf5,0x08,0x46 } },
3481 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3483 PropertyItem
*prop_item
;
3485 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
));
3488 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3492 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3494 expect(1, dim_count
);
3496 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3498 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3500 frame_count
= 0xdeadbeef;
3501 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3503 expect(1, frame_count
);
3505 prop_count
= 0xdeadbeef;
3506 status
= GdipGetPropertyCount(image
, &prop_count
);
3508 ok(prop_count
== sizeof(td
)/sizeof(td
[0]) ||
3509 broken(prop_count
== sizeof(td
)/sizeof(td
[0]) - 1) /* Win7 SP0 */,
3510 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
3512 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3514 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3517 for (i
= 0; i
< prop_count
; i
++)
3519 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &prop_size
);
3521 if (status
!= Ok
) break;
3522 ok(prop_size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, prop_size
);
3524 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, prop_size
);
3525 status
= GdipGetPropertyItem(image
, prop_id
[i
], prop_size
, prop_item
);
3527 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3528 ok(td
[i
].type
== prop_item
->type
||
3529 /* Win7 stopped using proper but not documented types, and it
3530 looks broken since TypeFloat and TypeDouble now reported as
3531 TypeUndefined, and signed types reported as unsigned. */
3532 broken(prop_item
->type
== documented_type(td
[i
].type
)),
3533 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3534 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3535 prop_size
-= sizeof(*prop_item
);
3536 ok(prop_item
->length
== prop_size
, "%u: expected length %u, got %u\n", i
, prop_size
, prop_item
->length
);
3537 ok(td
[i
].length
== prop_item
->length
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_item
->length
+1) /* XP */,
3538 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3539 ok(td
[i
].length
== prop_size
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_size
+1) /* XP */,
3540 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_size
);
3541 if (td
[i
].length
== prop_item
->length
)
3543 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3544 ok(match
|| broken(td
[i
].length
<= 4 && !match
), "%u: data mismatch\n", i
);
3548 BYTE
*data
= prop_item
->value
;
3549 trace("id %#x:", prop_item
->id
);
3550 for (j
= 0; j
< prop_item
->length
; j
++)
3551 trace(" %02x", data
[j
]);
3555 HeapFree(GetProcessHeap(), 0, prop_item
);
3558 HeapFree(GetProcessHeap(), 0, prop_id
);
3560 GdipDisposeImage(image
);
3563 static void test_GdipGetAllPropertyItems(void)
3565 static const struct test_data
3567 ULONG type
, id
, length
;
3571 { PropertyTagTypeLong
, 0xfe, 4, { 0 } },
3572 { PropertyTagTypeShort
, 0x100, 2, { 1 } },
3573 { PropertyTagTypeShort
, 0x101, 2, { 1 } },
3574 { PropertyTagTypeShort
, 0x102, 6, { 8,0,8,0,8,0 } },
3575 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3576 { PropertyTagTypeShort
, 0x106, 2, { 2,0 } },
3577 { PropertyTagTypeASCII
, 0x10d, 27, "/home/meh/Desktop/test.tif" },
3578 { PropertyTagTypeLong
, 0x111, 4, { 8,0,0,0 } },
3579 { PropertyTagTypeShort
, 0x112, 2, { 1 } },
3580 { PropertyTagTypeShort
, 0x115, 2, { 3,0 } },
3581 { PropertyTagTypeShort
, 0x116, 2, { 0x40,0 } },
3582 { PropertyTagTypeLong
, 0x117, 4, { 3,0,0,0 } },
3583 { PropertyTagTypeRational
, 0x11a, 8, { 0,0,0,72,0,0,0,1 } },
3584 { PropertyTagTypeRational
, 0x11b, 8, { 0,0,0,72,0,0,0,1 } },
3585 { PropertyTagTypeShort
, 0x11c, 2, { 1 } },
3586 { PropertyTagTypeShort
, 0x128, 2, { 2 } }
3591 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3592 UINT total_size
, total_count
;
3594 PropertyItem
*prop_item
;
3595 const char *item_data
;
3597 image
= load_image(tiffimage
, sizeof(tiffimage
));
3598 ok(image
!= 0, "Failed to load TIFF image data\n");
3601 dim_count
= 0xdeadbeef;
3602 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3604 expect(1, dim_count
);
3606 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3608 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3610 frame_count
= 0xdeadbeef;
3611 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3613 expect(1, frame_count
);
3615 prop_count
= 0xdeadbeef;
3616 status
= GdipGetPropertyCount(image
, &prop_count
);
3618 ok(prop_count
== sizeof(td
)/sizeof(td
[0]),
3619 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
3621 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3623 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3627 for (i
= 0; i
< prop_count
; i
++)
3630 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
3632 if (status
!= Ok
) break;
3633 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
3637 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
3638 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
3640 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3641 ok(td
[i
].type
== prop_item
->type
,
3642 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3643 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3644 size
-= sizeof(*prop_item
);
3645 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
3646 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3647 if (td
[i
].length
== prop_item
->length
)
3649 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3650 ok(match
, "%u: data mismatch\n", i
);
3654 BYTE
*data
= prop_item
->value
;
3655 trace("id %#x:", prop_item
->id
);
3656 for (j
= 0; j
< prop_item
->length
; j
++)
3657 trace(" %02x", data
[j
]);
3661 HeapFree(GetProcessHeap(), 0, prop_item
);
3664 HeapFree(GetProcessHeap(), 0, prop_id
);
3666 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
3667 expect(InvalidParameter
, status
);
3668 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
3669 expect(InvalidParameter
, status
);
3670 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
3671 expect(InvalidParameter
, status
);
3672 status
= GdipGetPropertySize(image
, NULL
, NULL
);
3673 expect(InvalidParameter
, status
);
3674 total_size
= 0xdeadbeef;
3675 total_count
= 0xdeadbeef;
3676 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
3678 ok(prop_count
== total_count
,
3679 "expected total property count %u, got %u\n", prop_count
, total_count
);
3680 ok(prop_size
== total_size
,
3681 "expected total property size %u, got %u\n", prop_size
, total_size
);
3683 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
3685 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
3686 expect(InvalidParameter
, status
);
3687 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
3688 expect(InvalidParameter
, status
);
3689 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3690 expect(InvalidParameter
, status
);
3691 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3692 expect(InvalidParameter
, status
);
3693 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
3694 expect(InvalidParameter
, status
);
3695 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
3696 expect(InvalidParameter
, status
);
3697 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
3700 item_data
= (const char *)(prop_item
+ prop_count
);
3701 for (i
= 0; i
< prop_count
; i
++)
3703 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
3704 i
, item_data
, prop_item
[i
].value
);
3705 ok(td
[i
].type
== prop_item
[i
].type
,
3706 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
3707 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
3708 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
3709 if (td
[i
].length
== prop_item
[i
].length
)
3711 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
3712 ok(match
, "%u: data mismatch\n", i
);
3716 BYTE
*data
= prop_item
[i
].value
;
3717 trace("id %#x:", prop_item
[i
].id
);
3718 for (j
= 0; j
< prop_item
[i
].length
; j
++)
3719 trace(" %02x", data
[j
]);
3723 item_data
+= prop_item
[i
].length
;
3726 HeapFree(GetProcessHeap(), 0, prop_item
);
3728 GdipDisposeImage(image
);
3731 static void test_tiff_palette(void)
3742 ARGB
*entries
= palette
.pal
.Entries
;
3744 /* 1bpp TIFF without palette */
3745 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
));
3748 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3752 status
= GdipGetImagePixelFormat(image
, &format
);
3754 ok(format
== PixelFormat1bppIndexed
, "expected PixelFormat1bppIndexed, got %#x\n", format
);
3756 status
= GdipGetImagePaletteSize(image
, &size
);
3757 ok(status
== Ok
|| broken(status
== GenericError
), /* XP */
3758 "GdipGetImagePaletteSize error %d\n", status
);
3759 if (status
== GenericError
)
3761 GdipDisposeImage(image
);
3764 expect(sizeof(ColorPalette
) + sizeof(ARGB
), size
);
3766 status
= GdipGetImagePalette(image
, &palette
.pal
, size
);
3768 expect(0, palette
.pal
.Flags
);
3769 expect(2, palette
.pal
.Count
);
3770 if (palette
.pal
.Count
== 2)
3772 ok(entries
[0] == 0xff000000, "expected 0xff000000, got %#x\n", entries
[0]);
3773 ok(entries
[1] == 0xffffffff, "expected 0xffffffff, got %#x\n", entries
[1]);
3776 GdipDisposeImage(image
);
3779 static void test_bitmapbits(void)
3782 static const BYTE pixels_24
[48] =
3784 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3785 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3786 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3787 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0
3789 static const BYTE pixels_00
[48] =
3791 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3792 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3793 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3794 0,0,0, 0,0,0, 0,0,0, 0,0,0
3796 static const BYTE pixels_24_77
[64] =
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 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3801 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3802 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3803 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3805 static const BYTE pixels_77
[64] =
3807 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3808 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3809 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3810 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3811 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3812 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3813 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3814 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3816 static const BYTE pixels_8
[16] =
3818 0x01,0,0x01,0,0x01,0,0x01,0,
3819 0x01,0,0x01,0,0x01,0,0x01,0
3821 static const BYTE pixels_8_77
[64] =
3823 0x01,0,0x01,0,0x01,0,0x01,0,
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 0x01,0,0x01,0,0x01,0,0x01,0,
3828 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3829 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3830 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3832 static const BYTE pixels_1_77
[64] =
3834 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3835 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3836 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3837 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3838 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3839 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3840 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3841 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3843 static const BYTE pixels_1
[8] = {0xaa,0,0,0,0xaa,0,0,0};
3844 static const struct test_data
3851 const BYTE
*pixels_unlocked
;
3855 { PixelFormat24bppRGB
, 24, 0xfff0, 24, 48, pixels_24
, pixels_00
},
3857 { PixelFormat24bppRGB
, 24, 0, 24, 48, pixels_24
, pixels_00
},
3858 { PixelFormat24bppRGB
, 24, ImageLockModeRead
, 24, 48, pixels_24
, pixels_00
},
3859 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
3860 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
3861 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_24_77
, pixels_24
},
3862 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3863 { PixelFormat24bppRGB
, 24, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3865 { PixelFormat8bppIndexed
, 8, 0, 8, 16, pixels_8
, pixels_24
},
3866 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
, 8, 16, pixels_8
, pixels_24
},
3867 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
3868 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
3869 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_8_77
, pixels_24
},
3870 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3871 { PixelFormat8bppIndexed
, 8, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3873 { PixelFormat1bppIndexed
, 1, 0, 4, 8, pixels_1
, pixels_24
},
3874 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
, 4, 8, pixels_1
, pixels_24
},
3875 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
3876 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
3877 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_1_77
, pixels_24
},
3878 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3879 { PixelFormat1bppIndexed
, 1, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3891 ARGB
*entries
= palette
.pal
.Entries
;
3893 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
3895 BYTE pixels
[sizeof(pixels_24
)];
3896 memcpy(pixels
, pixels_24
, sizeof(pixels_24
));
3897 status
= GdipCreateBitmapFromScan0(8, 2, 24, PixelFormat24bppRGB
, pixels
, &bitmap
);
3900 /* associate known palette with pixel data */
3901 palette
.pal
.Flags
= PaletteFlagsGrayScale
;
3902 palette
.pal
.Count
= 2;
3903 entries
[0] = 0xff000000;
3904 entries
[1] = 0xffffffff;
3905 status
= GdipSetImagePalette((GpImage
*)bitmap
, &palette
.pal
);
3908 memset(&data
, 0xfe, sizeof(data
));
3909 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
3911 memset(buf
, 0x77, sizeof(buf
));
3915 status
= GdipBitmapLockBits(bitmap
, NULL
, td
[i
].mode
, td
[i
].format
, &data
);
3916 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* XP */, "%u: GdipBitmapLockBits error %d\n", i
, status
);
3919 GdipDisposeImage((GpImage
*)bitmap
);
3922 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
3923 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
3924 ok(td
[i
].stride
== data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].stride
, data
.Stride
);
3925 ok(td
[i
].format
== data
.PixelFormat
, "%u: expected %d, got %d\n", i
, td
[i
].format
, data
.PixelFormat
);
3926 ok(td
[i
].size
== data
.Height
* data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].size
, data
.Height
* data
.Stride
);
3927 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
3928 ok(data
.Scan0
== buf
, "%u: got wrong buffer\n", i
);
3929 if (td
[i
].size
== data
.Height
* data
.Stride
)
3931 UINT j
, match
, width_bytes
= (data
.Width
* td
[i
].bpp
) / 8;
3934 for (j
= 0; j
< data
.Height
; j
++)
3936 if (memcmp((const BYTE
*)data
.Scan0
+ j
* data
.Stride
, td
[i
].pixels
+ j
* data
.Stride
, width_bytes
) != 0)
3942 if ((td
[i
].mode
& (ImageLockModeRead
|ImageLockModeUserInputBuf
)) || td
[i
].format
== PixelFormat24bppRGB
)
3945 "%u: data should match\n", i
);
3948 BYTE
*bits
= data
.Scan0
;
3949 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
3950 for (j
= 0; j
< td
[i
].size
; j
++)
3951 trace(" %02x", bits
[j
]);
3956 ok(!match
, "%u: data shouldn't match\n", i
);
3958 memset(data
.Scan0
, 0, td
[i
].size
);
3961 status
= GdipBitmapUnlockBits(bitmap
, &data
);
3962 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
3964 memset(&data
, 0xfe, sizeof(data
));
3965 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
3966 ok(status
== Ok
, "%u: GdipBitmapLockBits error %d\n", i
, status
);
3967 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
3968 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
3969 ok(data
.Stride
== 24, "%u: expected 24, got %d\n", i
, data
.Stride
);
3970 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "%u: got wrong pixel format %d\n", i
, data
.PixelFormat
);
3971 ok(data
.Height
* data
.Stride
== 48, "%u: expected 48, got %d\n", i
, data
.Height
* data
.Stride
);
3972 if (data
.Height
* data
.Stride
== 48)
3974 int match
= memcmp(data
.Scan0
, td
[i
].pixels_unlocked
, 48) == 0;
3975 ok(match
, "%u: data should match\n", i
);
3979 BYTE
*bits
= data
.Scan0
;
3980 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
3981 for (j
= 0; j
< 48; j
++)
3982 trace(" %02x", bits
[j
]);
3987 status
= GdipBitmapUnlockBits(bitmap
, &data
);
3988 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
3990 status
= GdipDisposeImage((GpImage
*)bitmap
);
3995 static void test_DrawImage(void)
3997 BYTE black_1x1
[4] = { 0,0,0,0 };
3998 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
3999 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
4000 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
4001 0,0,0,0,0,0,0xff,0xff };
4008 GpGraphics
*graphics
;
4011 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
4013 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4016 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
4018 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
4020 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4022 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4025 status
= GdipDrawImageI(graphics
, u1
.image
, 0, 0);
4028 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
4029 ok(match
, "data should match\n");
4032 UINT i
, size
= sizeof(white_2x2
);
4033 BYTE
*bits
= white_2x2
;
4034 for (i
= 0; i
< size
; i
++)
4035 trace(" %02x", bits
[i
]);
4039 status
= GdipDeleteGraphics(graphics
);
4041 status
= GdipDisposeImage(u1
.image
);
4043 status
= GdipDisposeImage(u2
.image
);
4047 static void test_DrawImage_SourceCopy(void)
4049 DWORD dst_pixels
[4] = { 0xffffffff, 0xffffffff,
4050 0xffffffff, 0xffffffff };
4051 DWORD src_pixels
[4] = { 0, 0xffff0000,
4060 GpGraphics
*graphics
;
4062 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB
, (BYTE
*)dst_pixels
, &u1
.bitmap
);
4065 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB
, (BYTE
*)src_pixels
, &u2
.bitmap
);
4067 status
= GdipGetImageGraphicsContext(u1
.image
, &graphics
);
4069 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4072 status
= GdipSetCompositingMode(graphics
, CompositingModeSourceCopy
);
4075 status
= GdipDrawImageI(graphics
, u2
.image
, 0, 0);
4078 todo_wine
expect(0, dst_pixels
[0]);
4079 expect(0xffff0000, dst_pixels
[1]);
4080 todo_wine
expect(0, dst_pixels
[2]);
4081 todo_wine
expect(0, dst_pixels
[3]);
4083 status
= GdipDeleteGraphics(graphics
);
4085 status
= GdipDisposeImage(u1
.image
);
4087 status
= GdipDisposeImage(u2
.image
);
4091 static void test_GdipDrawImagePointRect(void)
4093 BYTE black_1x1
[4] = { 0,0,0,0 };
4094 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
4095 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
4096 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
4097 0,0,0,0,0,0,0xff,0xff };
4104 GpGraphics
*graphics
;
4107 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
4109 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4112 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
4114 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
4116 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4118 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4121 status
= GdipDrawImagePointRectI(graphics
, u1
.image
, 0, 0, 0, 0, 1, 1, UnitPixel
);
4124 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
4125 ok(match
, "data should match\n");
4128 UINT i
, size
= sizeof(white_2x2
);
4129 BYTE
*bits
= white_2x2
;
4130 for (i
= 0; i
< size
; i
++)
4131 trace(" %02x", bits
[i
]);
4135 status
= GdipDeleteGraphics(graphics
);
4137 status
= GdipDisposeImage(u1
.image
);
4139 status
= GdipDisposeImage(u2
.image
);
4143 static void test_image_format(void)
4145 static const PixelFormat fmt
[] =
4147 PixelFormat1bppIndexed
, PixelFormat4bppIndexed
, PixelFormat8bppIndexed
,
4148 PixelFormat16bppGrayScale
, PixelFormat16bppRGB555
, PixelFormat16bppRGB565
,
4149 PixelFormat16bppARGB1555
, PixelFormat24bppRGB
, PixelFormat32bppRGB
,
4150 PixelFormat32bppARGB
, PixelFormat32bppPARGB
, PixelFormat48bppRGB
,
4151 PixelFormat64bppARGB
, PixelFormat64bppPARGB
, PixelFormat32bppCMYK
4162 for (i
= 0; i
< sizeof(fmt
)/sizeof(fmt
[0]); i
++)
4164 status
= GdipCreateBitmapFromScan0(1, 1, 0, fmt
[i
], NULL
, &bitmap
);
4165 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* before win7 */,
4166 "GdipCreateBitmapFromScan0 error %d\n", status
);
4167 if (status
!= Ok
) continue;
4169 status
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
4171 expect(fmt
[i
], format
);
4173 status
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
4174 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4175 todo_wine
expect(InvalidParameter
, status
);
4179 ret
= GetObjectW(hbitmap
, sizeof(bm
), &bm
);
4180 expect(sizeof(bm
), ret
);
4181 expect(0, bm
.bmType
);
4182 expect(1, bm
.bmWidth
);
4183 expect(1, bm
.bmHeight
);
4184 expect(4, bm
.bmWidthBytes
);
4185 expect(1, bm
.bmPlanes
);
4186 expect(32, bm
.bmBitsPixel
);
4187 DeleteObject(hbitmap
);
4190 status
= GdipGetImageThumbnail((GpImage
*)bitmap
, 0, 0, &thumb
, NULL
, NULL
);
4191 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4193 ok(status
== OutOfMemory
|| broken(status
== InvalidParameter
) /* before win7 */,
4194 "expected OutOfMemory, got %d\n", status
);
4199 status
= GdipGetImagePixelFormat(thumb
, &format
);
4201 ok(format
== PixelFormat32bppPARGB
|| broken(format
!= PixelFormat32bppPARGB
) /* before win7 */,
4202 "expected PixelFormat32bppPARGB, got %#x\n", format
);
4203 status
= GdipDisposeImage(thumb
);
4207 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4208 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4209 todo_wine
expect(InvalidParameter
, status
);
4213 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4217 status
= GdipDisposeImage((GpImage
*)bitmap
);
4222 static void test_DrawImage_scale(void)
4224 static const BYTE back_8x1
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
4225 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4226 static const BYTE image_080
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,
4227 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4228 static const BYTE image_100
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,
4229 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4230 static const BYTE image_120
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,
4231 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4232 static const BYTE image_150
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4233 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4234 static const BYTE image_180
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4235 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4236 static const BYTE image_200
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4237 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4238 static const BYTE image_250
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,
4239 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4240 static const BYTE image_120_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4241 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4242 static const BYTE image_150_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4243 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4244 static const BYTE image_200_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4245 0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40 };
4246 static const BYTE image_250_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4247 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4248 static const struct test_data
4251 PixelOffsetMode pixel_offset_mode
;
4256 { 0.8, PixelOffsetModeNone
, image_080
}, /* 0 */
4257 { 1.0, PixelOffsetModeNone
, image_100
},
4258 { 1.2, PixelOffsetModeNone
, image_120
},
4259 { 1.5, PixelOffsetModeNone
, image_150
},
4260 { 1.8, PixelOffsetModeNone
, image_180
},
4261 { 2.0, PixelOffsetModeNone
, image_200
},
4262 { 2.5, PixelOffsetModeNone
, image_250
},
4264 { 0.8, PixelOffsetModeHighSpeed
, image_080
}, /* 7 */
4265 { 1.0, PixelOffsetModeHighSpeed
, image_100
},
4266 { 1.2, PixelOffsetModeHighSpeed
, image_120
},
4267 { 1.5, PixelOffsetModeHighSpeed
, image_150
},
4268 { 1.8, PixelOffsetModeHighSpeed
, image_180
},
4269 { 2.0, PixelOffsetModeHighSpeed
, image_200
},
4270 { 2.5, PixelOffsetModeHighSpeed
, image_250
},
4272 { 0.8, PixelOffsetModeHalf
, image_080
}, /* 14 */
4273 { 1.0, PixelOffsetModeHalf
, image_100
},
4274 { 1.2, PixelOffsetModeHalf
, image_120_half
, TRUE
},
4275 { 1.5, PixelOffsetModeHalf
, image_150_half
, TRUE
},
4276 { 1.8, PixelOffsetModeHalf
, image_180
},
4277 { 2.0, PixelOffsetModeHalf
, image_200_half
, TRUE
},
4278 { 2.5, PixelOffsetModeHalf
, image_250_half
, TRUE
},
4280 { 0.8, PixelOffsetModeHighQuality
, image_080
}, /* 21 */
4281 { 1.0, PixelOffsetModeHighQuality
, image_100
},
4282 { 1.2, PixelOffsetModeHighQuality
, image_120_half
, TRUE
},
4283 { 1.5, PixelOffsetModeHighQuality
, image_150_half
, TRUE
},
4284 { 1.8, PixelOffsetModeHighQuality
, image_180
},
4285 { 2.0, PixelOffsetModeHighQuality
, image_200_half
, TRUE
},
4286 { 2.5, PixelOffsetModeHighQuality
, image_250_half
, TRUE
},
4288 BYTE src_2x1
[6] = { 0x80,0x80,0x80,0x80,0x80,0x80 };
4296 GpGraphics
*graphics
;
4300 status
= GdipCreateBitmapFromScan0(2, 1, 4, PixelFormat24bppRGB
, src_2x1
, &u1
.bitmap
);
4302 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4305 status
= GdipCreateBitmapFromScan0(8, 1, 24, PixelFormat24bppRGB
, dst_8x1
, &u2
.bitmap
);
4307 status
= GdipBitmapSetResolution(u2
.bitmap
, 100.0, 100.0);
4309 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4311 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4314 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
4316 status
= GdipSetPixelOffsetMode(graphics
, td
[i
].pixel_offset_mode
);
4319 status
= GdipCreateMatrix2(td
[i
].scale_x
, 0.0, 0.0, 1.0, 0.0, 0.0, &matrix
);
4321 status
= GdipSetWorldTransform(graphics
, matrix
);
4323 GdipDeleteMatrix(matrix
);
4325 memcpy(dst_8x1
, back_8x1
, sizeof(dst_8x1
));
4326 status
= GdipDrawImageI(graphics
, u1
.image
, 1, 0);
4329 match
= memcmp(dst_8x1
, td
[i
].image
, sizeof(dst_8x1
)) == 0;
4330 todo_wine_if (!match
&& td
[i
].todo
)
4331 ok(match
, "%d: data should match\n", i
);
4334 UINT i
, size
= sizeof(dst_8x1
);
4335 const BYTE
*bits
= dst_8x1
;
4336 for (i
= 0; i
< size
; i
++)
4337 trace(" %02x", bits
[i
]);
4342 status
= GdipDeleteGraphics(graphics
);
4344 status
= GdipDisposeImage(u1
.image
);
4346 status
= GdipDisposeImage(u2
.image
);
4350 static const BYTE animatedgif
[] = {
4351 'G','I','F','8','9','a',0x01,0x00,0x01,0x00,0xA1,0x02,0x00,
4352 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
4353 /*0x21,0xFF,0x0B,'A','N','I','M','E','X','T','S','1','.','0',*/
4354 0x21,0xFF,0x0B,'N','E','T','S','C','A','P','E','2','.','0',
4355 0x03,0x01,0x05,0x00,0x00,
4356 0x21,0xFE,0x0C,'H','e','l','l','o',' ','W','o','r','l','d','!',0x00,
4357 0x21,0x01,0x0D,'a','n','i','m','a','t','i','o','n','.','g','i','f',0x00,
4358 0x21,0xF9,0x04,0xff,0x0A,0x00,0x08,0x00,
4359 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4360 0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,
4361 0x02,0x02,0x4C,0x01,0x00,
4362 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','1',0x00,
4363 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','1',0x00,
4364 0x21,0xF9,0x04,0x00,0x14,0x00,0x01,0x00,
4365 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4366 0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,
4367 0x02,0x02,0x44,0x01,0x00,
4368 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','2',0x00,
4369 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','2',0x00,0x3B
4372 static void test_gif_properties(void)
4374 static const struct test_data
4376 ULONG type
, id
, length
;
4377 const BYTE value
[13];
4380 { PropertyTagTypeLong
, PropertyTagFrameDelay
, 8, { 10,0,0,0,20,0,0,0 } },
4381 { PropertyTagTypeASCII
, PropertyTagExifUserComment
, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
4382 { PropertyTagTypeShort
, PropertyTagLoopCount
, 2, { 5,0 } },
4383 { PropertyTagTypeByte
, PropertyTagGlobalPalette
, 12, { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c } },
4384 { PropertyTagTypeByte
, PropertyTagIndexBackground
, 1, { 2 } },
4385 { PropertyTagTypeByte
, PropertyTagIndexTransparent
, 1, { 8 } }
4390 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
4391 UINT total_size
, total_count
;
4393 PropertyItem
*prop_item
;
4394 const char *item_data
;
4396 image
= load_image(animatedgif
, sizeof(animatedgif
));
4397 if (!image
) /* XP fails to load this GIF image */
4399 trace("Failed to load GIF image data\n");
4403 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
4405 expect(1, dim_count
);
4407 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
4409 expect_guid(&FrameDimensionTime
, &guid
, __LINE__
, FALSE
);
4411 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
4413 expect(2, frame_count
);
4415 status
= GdipImageSelectActiveFrame(image
, &guid
, 1);
4418 status
= GdipGetPropertyCount(image
, &prop_count
);
4420 ok(prop_count
== sizeof(td
)/sizeof(td
[0]) || broken(prop_count
== 1) /* before win7 */,
4421 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
4423 if (prop_count
!= sizeof(td
)/sizeof(td
[0]))
4425 GdipDisposeImage(image
);
4429 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
4431 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
4435 for (i
= 0; i
< prop_count
; i
++)
4438 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
4440 if (status
!= Ok
) break;
4441 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
4445 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
4446 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
4448 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
4449 ok(td
[i
].type
== prop_item
->type
,
4450 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
4451 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
4452 size
-= sizeof(*prop_item
);
4453 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
4454 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
4455 if (td
[i
].length
== prop_item
->length
)
4457 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
4458 ok(match
, "%u: data mismatch\n", i
);
4462 BYTE
*data
= prop_item
->value
;
4463 trace("id %#x:", prop_item
->id
);
4464 for (j
= 0; j
< prop_item
->length
; j
++)
4465 trace(" %02x", data
[j
]);
4469 HeapFree(GetProcessHeap(), 0, prop_item
);
4472 HeapFree(GetProcessHeap(), 0, prop_id
);
4474 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
4475 expect(InvalidParameter
, status
);
4476 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
4477 expect(InvalidParameter
, status
);
4478 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
4479 expect(InvalidParameter
, status
);
4480 status
= GdipGetPropertySize(image
, NULL
, NULL
);
4481 expect(InvalidParameter
, status
);
4482 total_size
= 0xdeadbeef;
4483 total_count
= 0xdeadbeef;
4484 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
4486 ok(prop_count
== total_count
,
4487 "expected total property count %u, got %u\n", prop_count
, total_count
);
4488 ok(prop_size
== total_size
,
4489 "expected total property size %u, got %u\n", prop_size
, total_size
);
4491 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
4493 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
4494 expect(InvalidParameter
, status
);
4495 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
4496 expect(InvalidParameter
, status
);
4497 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4498 expect(InvalidParameter
, status
);
4499 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4500 expect(InvalidParameter
, status
);
4501 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
4502 expect(InvalidParameter
, status
);
4503 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
4504 expect(InvalidParameter
, status
);
4505 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
4508 item_data
= (const char *)(prop_item
+ prop_count
);
4509 for (i
= 0; i
< prop_count
; i
++)
4511 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
4512 i
, item_data
, prop_item
[i
].value
);
4513 ok(td
[i
].type
== prop_item
[i
].type
,
4514 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
4515 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
4516 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
4517 if (td
[i
].length
== prop_item
[i
].length
)
4519 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
4520 ok(match
, "%u: data mismatch\n", i
);
4524 BYTE
*data
= prop_item
[i
].value
;
4525 trace("id %#x:", prop_item
[i
].id
);
4526 for (j
= 0; j
< prop_item
[i
].length
; j
++)
4527 trace(" %02x", data
[j
]);
4531 item_data
+= prop_item
[i
].length
;
4534 HeapFree(GetProcessHeap(), 0, prop_item
);
4536 GdipDisposeImage(image
);
4539 static void test_ARGB_conversion(void)
4541 BYTE argb
[8] = { 0x11,0x22,0x33,0x80, 0xff,0xff,0xff,0 };
4542 BYTE pargb
[8] = { 0x09,0x11,0x1a,0x80, 0,0,0,0 };
4543 BYTE rgb32_xp
[8] = { 0x11,0x22,0x33,0xff, 0xff,0xff,0xff,0xff };
4544 BYTE rgb24
[6] = { 0x11,0x22,0x33, 0xff,0xff,0xff };
4551 status
= GdipCreateBitmapFromScan0(2, 1, 8, PixelFormat32bppARGB
, argb
, &bitmap
);
4554 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4556 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4557 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4558 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4559 ok(data
.PixelFormat
== PixelFormat32bppPARGB
, "expected PixelFormat32bppPARGB, got %d\n", data
.PixelFormat
);
4560 match
= !memcmp(data
.Scan0
, pargb
, sizeof(pargb
));
4561 ok(match
, "bits don't match\n");
4565 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppPARGB
,
4566 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4568 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4571 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppRGB
, &data
);
4573 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4574 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4575 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4576 ok(data
.PixelFormat
== PixelFormat32bppRGB
, "expected PixelFormat32bppRGB, got %d\n", data
.PixelFormat
);
4577 match
= !memcmp(data
.Scan0
, argb
, sizeof(argb
)) ||
4578 !memcmp(data
.Scan0
, rgb32_xp
, sizeof(rgb32_xp
));
4579 ok(match
, "bits don't match\n");
4583 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppRGB
,
4584 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4586 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4589 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
4591 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4592 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4593 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4594 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "expected PixelFormat24bppRGB, got %d\n", data
.PixelFormat
);
4595 match
= !memcmp(data
.Scan0
, rgb24
, sizeof(rgb24
));
4596 ok(match
, "bits don't match\n");
4600 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat24bppRGB
,
4601 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4603 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4606 GdipDisposeImage((GpImage
*)bitmap
);
4610 static void test_CloneBitmapArea(void)
4613 GpBitmap
*bitmap
, *copy
;
4614 BitmapData data
, data2
;
4616 status
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB
, NULL
, &bitmap
);
4619 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
| ImageLockModeWrite
, PixelFormat24bppRGB
, &data
);
4622 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data2
);
4623 expect(WrongState
, status
);
4625 status
= GdipCloneBitmapAreaI(0, 0, 1, 1, PixelFormat24bppRGB
, bitmap
, ©
);
4628 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4631 GdipDisposeImage((GpImage
*)copy
);
4632 GdipDisposeImage((GpImage
*)bitmap
);
4635 static BOOL
get_encoder_clsid(LPCWSTR mime
, GUID
*format
, CLSID
*clsid
)
4638 UINT n_codecs
, info_size
, i
;
4639 ImageCodecInfo
*info
;
4642 status
= GdipGetImageEncodersSize(&n_codecs
, &info_size
);
4645 info
= GdipAlloc(info_size
);
4647 status
= GdipGetImageEncoders(n_codecs
, info_size
, info
);
4650 for (i
= 0; i
< n_codecs
; i
++)
4652 if (!lstrcmpW(info
[i
].MimeType
, mime
))
4654 *format
= info
[i
].FormatID
;
4655 *clsid
= info
[i
].Clsid
;
4665 static void test_supported_encoders(void)
4667 static const WCHAR bmp_mimetype
[] = { 'i', 'm', 'a','g', 'e', '/', 'b', 'm', 'p',0 };
4668 static const WCHAR jpeg_mimetype
[] = { 'i','m','a','g','e','/','j','p','e','g',0 };
4669 static const WCHAR gif_mimetype
[] = { 'i','m','a','g','e','/','g','i','f',0 };
4670 static const WCHAR tiff_mimetype
[] = { 'i','m','a','g','e','/','t','i','f','f',0 };
4671 static const WCHAR png_mimetype
[] = { 'i','m','a','g','e','/','p','n','g',0 };
4672 static const struct test_data
4678 { bmp_mimetype
, &ImageFormatBMP
},
4679 { jpeg_mimetype
, &ImageFormatJPEG
},
4680 { gif_mimetype
, &ImageFormatGIF
},
4681 { tiff_mimetype
, &ImageFormatTIFF
},
4682 { png_mimetype
, &ImageFormatPNG
}
4693 status
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB
, NULL
, &bm
);
4694 ok(status
== Ok
, "GdipCreateBitmapFromScan0 error %d\n", status
);
4696 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
4698 ret
= get_encoder_clsid(td
[i
].mime
, &format
, &clsid
);
4699 ok(ret
, "%s encoder is not in the list\n", wine_dbgstr_w(td
[i
].mime
));
4700 expect_guid(td
[i
].format
, &format
, __LINE__
, FALSE
);
4702 hmem
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_NODISCARD
, 16);
4704 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
4705 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
4707 status
= GdipSaveImageToStream((GpImage
*)bm
, stream
, &clsid
, NULL
);
4708 ok(status
== Ok
, "GdipSaveImageToStream error %d\n", status
);
4710 IStream_Release(stream
);
4713 GdipDisposeImage((GpImage
*)bm
);
4716 static void test_createeffect(void)
4718 static const GUID noneffect
= { 0xcd0c3d4b, 0xe15e, 0x4cf2, { 0x9e, 0xa8, 0x6e, 0x1d, 0x65, 0x48, 0xc5, 0xa5 } };
4719 GpStatus (WINAPI
*pGdipCreateEffect
)( const GUID guid
, CGpEffect
**effect
);
4720 GpStatus (WINAPI
*pGdipDeleteEffect
)( CGpEffect
*effect
);
4723 HMODULE mod
= GetModuleHandleA("gdiplus.dll");
4725 const GUID
* const effectlist
[] =
4726 {&BlurEffectGuid
, &SharpenEffectGuid
, &ColorMatrixEffectGuid
, &ColorLUTEffectGuid
,
4727 &BrightnessContrastEffectGuid
, &HueSaturationLightnessEffectGuid
, &LevelsEffectGuid
,
4728 &TintEffectGuid
, &ColorBalanceEffectGuid
, &RedEyeCorrectionEffectGuid
, &ColorCurveEffectGuid
};
4730 pGdipCreateEffect
= (void*)GetProcAddress( mod
, "GdipCreateEffect");
4731 pGdipDeleteEffect
= (void*)GetProcAddress( mod
, "GdipDeleteEffect");
4732 if(!pGdipCreateEffect
|| !pGdipDeleteEffect
)
4734 /* GdipCreateEffect/GdipDeleteEffect was introduced in Windows Vista. */
4735 win_skip("GDIPlus version 1.1 not available\n");
4739 stat
= pGdipCreateEffect(BlurEffectGuid
, NULL
);
4740 expect(InvalidParameter
, stat
);
4742 stat
= pGdipCreateEffect(noneffect
, &effect
);
4743 todo_wine
expect(Win32Error
, stat
);
4745 for(i
=0; i
< sizeof(effectlist
) / sizeof(effectlist
[0]); i
++)
4747 stat
= pGdipCreateEffect(*effectlist
[i
], &effect
);
4748 todo_wine
expect(Ok
, stat
);
4751 stat
= pGdipDeleteEffect(effect
);
4757 static void test_getadjustedpalette(void)
4760 GpImageAttributes
*imageattributes
;
4761 ColorPalette
*palette
;
4764 stat
= GdipCreateImageAttributes(&imageattributes
);
4767 colormap
.oldColor
.Argb
= 0xffffff00;
4768 colormap
.newColor
.Argb
= 0xffff00ff;
4769 stat
= GdipSetImageAttributesRemapTable(imageattributes
, ColorAdjustTypeBitmap
,
4770 TRUE
, 1, &colormap
);
4773 colormap
.oldColor
.Argb
= 0xffffff80;
4774 colormap
.newColor
.Argb
= 0xffff80ff;
4775 stat
= GdipSetImageAttributesRemapTable(imageattributes
, ColorAdjustTypeDefault
,
4776 TRUE
, 1, &colormap
);
4779 palette
= GdipAlloc(sizeof(*palette
) + sizeof(ARGB
) * 2);
4782 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeBitmap
);
4783 expect(InvalidParameter
, stat
);
4786 palette
->Entries
[0] = 0xffffff00;
4787 palette
->Entries
[1] = 0xffffff80;
4788 palette
->Entries
[2] = 0xffffffff;
4790 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeBitmap
);
4792 expect(0xffff00ff, palette
->Entries
[0]);
4793 expect(0xffffff80, palette
->Entries
[1]);
4794 expect(0xffffffff, palette
->Entries
[2]);
4796 palette
->Entries
[0] = 0xffffff00;
4797 palette
->Entries
[1] = 0xffffff80;
4798 palette
->Entries
[2] = 0xffffffff;
4800 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeBrush
);
4802 expect(0xffffff00, palette
->Entries
[0]);
4803 expect(0xffff80ff, palette
->Entries
[1]);
4804 expect(0xffffffff, palette
->Entries
[2]);
4806 stat
= GdipGetImageAttributesAdjustedPalette(NULL
, palette
, ColorAdjustTypeBitmap
);
4807 expect(InvalidParameter
, stat
);
4809 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, NULL
, ColorAdjustTypeBitmap
);
4810 expect(InvalidParameter
, stat
);
4812 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, -1);
4813 expect(InvalidParameter
, stat
);
4815 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeDefault
);
4816 expect(InvalidParameter
, stat
);
4819 GdipDisposeImageAttributes(imageattributes
);
4822 static void test_histogram(void)
4824 UINT ch0
[256], ch1
[256], ch2
[256], ch3
[256];
4825 HistogramFormat test_formats
[] =
4827 HistogramFormatARGB
,
4828 HistogramFormatPARGB
,
4830 HistogramFormatGray
,
4836 const UINT WIDTH
= 8, HEIGHT
= 16;
4841 if (!pGdipBitmapGetHistogramSize
)
4843 win_skip("GdipBitmapGetHistogramSize is not supported\n");
4847 stat
= pGdipBitmapGetHistogramSize(HistogramFormatARGB
, NULL
);
4848 expect(InvalidParameter
, stat
);
4850 stat
= pGdipBitmapGetHistogramSize(0xff, NULL
);
4851 expect(InvalidParameter
, stat
);
4854 stat
= pGdipBitmapGetHistogramSize(10, &num
);
4858 for (i
= 0; i
< sizeof(test_formats
)/sizeof(test_formats
[0]); i
++)
4861 stat
= pGdipBitmapGetHistogramSize(test_formats
[i
], &num
);
4867 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
4870 /* Three solid rgb rows, next three rows are rgb shades. */
4871 for (x
= 0; x
< WIDTH
; x
++)
4873 GdipBitmapSetPixel(bm
, x
, 0, 0xffff0000);
4874 GdipBitmapSetPixel(bm
, x
, 1, 0xff00ff00);
4875 GdipBitmapSetPixel(bm
, x
, 2, 0xff0000ff);
4877 GdipBitmapSetPixel(bm
, x
, 3, 0xff010000);
4878 GdipBitmapSetPixel(bm
, x
, 4, 0xff003f00);
4879 GdipBitmapSetPixel(bm
, x
, 5, 0xff000020);
4882 stat
= pGdipBitmapGetHistogram(NULL
, HistogramFormatRGB
, 256, ch0
, ch1
, ch2
, ch3
);
4883 expect(InvalidParameter
, stat
);
4885 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, ch1
, ch2
, ch3
);
4886 expect(InvalidParameter
, stat
);
4888 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, ch1
, ch2
, NULL
);
4889 expect(InvalidParameter
, stat
);
4891 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, ch1
, NULL
, NULL
);
4892 expect(InvalidParameter
, stat
);
4894 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, NULL
, NULL
, NULL
);
4895 expect(InvalidParameter
, stat
);
4897 /* Requested format matches bitmap format */
4898 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 256, ch0
, ch1
, ch2
, ch3
);
4899 expect(InvalidParameter
, stat
);
4901 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 100, ch0
, ch1
, ch2
, NULL
);
4902 expect(InvalidParameter
, stat
);
4904 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 257, ch0
, ch1
, ch2
, NULL
);
4905 expect(InvalidParameter
, stat
);
4907 /* Channel 3 is not used, must be NULL */
4908 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 256, ch0
, ch1
, ch2
, NULL
);
4911 ok(ch0
[0xff] == WIDTH
, "Got red (0xff) %u\n", ch0
[0xff]);
4912 ok(ch1
[0xff] == WIDTH
, "Got green (0xff) %u\n", ch1
[0xff]);
4913 ok(ch2
[0xff] == WIDTH
, "Got blue (0xff) %u\n", ch1
[0xff]);
4914 ok(ch0
[0x01] == WIDTH
, "Got red (0x01) %u\n", ch0
[0x01]);
4915 ok(ch1
[0x3f] == WIDTH
, "Got green (0x3f) %u\n", ch1
[0x3f]);
4916 ok(ch2
[0x20] == WIDTH
, "Got blue (0x20) %u\n", ch1
[0x20]);
4918 /* ARGB histogram from RGB data. */
4919 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatARGB
, 256, ch0
, ch1
, ch2
, NULL
);
4920 expect(InvalidParameter
, stat
);
4922 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatARGB
, 256, ch0
, ch1
, ch2
, ch3
);
4925 ok(ch1
[0xff] == WIDTH
, "Got red (0xff) %u\n", ch1
[0xff]);
4926 ok(ch2
[0xff] == WIDTH
, "Got green (0xff) %u\n", ch2
[0xff]);
4927 ok(ch3
[0xff] == WIDTH
, "Got blue (0xff) %u\n", ch3
[0xff]);
4928 ok(ch1
[0x01] == WIDTH
, "Got red (0x01) %u\n", ch1
[0x01]);
4929 ok(ch2
[0x3f] == WIDTH
, "Got green (0x3f) %u\n", ch2
[0x3f]);
4930 ok(ch3
[0x20] == WIDTH
, "Got blue (0x20) %u\n", ch3
[0x20]);
4932 ok(ch0
[0xff] == WIDTH
* HEIGHT
, "Got alpha (0xff) %u\n", ch0
[0xff]);
4934 /* Request grayscale histogram from RGB bitmap. */
4935 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, ch1
, ch2
, ch3
);
4936 expect(InvalidParameter
, stat
);
4938 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, ch1
, ch2
, NULL
);
4939 expect(InvalidParameter
, stat
);
4941 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, ch1
, NULL
, NULL
);
4942 expect(InvalidParameter
, stat
);
4944 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, NULL
, NULL
, NULL
);
4947 GdipDisposeImage((GpImage
*)bm
);
4950 static void test_imageabort(void)
4955 if (!pGdipImageSetAbort
)
4957 win_skip("GdipImageSetAbort() is not supported.\n");
4962 stat
= GdipCreateBitmapFromScan0(8, 8, 0, PixelFormat24bppRGB
, NULL
, &bm
);
4965 stat
= pGdipImageSetAbort(NULL
, NULL
);
4966 expect(InvalidParameter
, stat
);
4968 stat
= pGdipImageSetAbort((GpImage
*)bm
, NULL
);
4971 GdipDisposeImage((GpImage
*)bm
);
4974 /* RGB 24 bpp 1x1 pixel PNG image */
4975 static const char png_1x1_data
[] = {
4976 0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,
4977 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,
4978 0x00,0x00,0x00,0x0c,'I','D','A','T',0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,0xe7,
4979 0x00,0x00,0x00,0x00,'I','E','N','D',0xae,0x42,0x60,0x82
4982 static void test_png_color_formats(void)
4986 char bit_depth
, color_type
;
4991 /* 2 - PNG_COLOR_TYPE_RGB */
4992 { 8, 2, PixelFormat24bppRGB
, ImageFlagsColorSpaceRGB
},
4993 /* 0 - PNG_COLOR_TYPE_GRAY */
4994 { 1, 0, PixelFormat1bppIndexed
, ImageFlagsColorSpaceRGB
},
4995 { 2, 0, PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
},
4996 { 4, 0, PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
},
4997 { 8, 0, PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
},
4998 { 16, 0, PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
},
5000 BYTE buf
[sizeof(png_1x1_data
)];
5008 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
5010 memcpy(buf
, png_1x1_data
, sizeof(png_1x1_data
));
5011 buf
[24] = td
[i
].bit_depth
;
5012 buf
[25] = td
[i
].color_type
;
5014 image
= load_image(buf
, sizeof(buf
));
5015 ok(image
!= NULL
, "%d: failed to load image data\n", i
);
5016 if (!image
) continue;
5018 status
= GdipGetImageType(image
, &type
);
5019 ok(status
== Ok
, "%u: GdipGetImageType error %d\n", i
, status
);
5020 ok(type
== ImageTypeBitmap
, "%d: wrong image type %d\n", i
, type
);
5022 status
= GdipGetImagePixelFormat(image
, &format
);
5024 ok(format
== td
[i
].format
||
5025 broken(td
[i
].bit_depth
== 1 && td
[i
].color_type
== 0 && format
== PixelFormat32bppARGB
), /* XP */
5026 "%d: expected %#x, got %#x\n", i
, td
[i
].format
, format
);
5028 status
= GdipGetImageFlags(image
, &flags
);
5030 ok((flags
& td
[i
].flags
) == td
[i
].flags
||
5031 broken(td
[i
].bit_depth
== 1 && td
[i
].color_type
== 0 && (flags
& ImageFlagsColorSpaceGRAY
)), /* XP */
5032 "%d: expected %#x, got %#x\n", i
, td
[i
].flags
, flags
);
5034 GdipDisposeImage(image
);
5038 static BYTE
*init_bitmap(UINT
*width
, UINT
*height
, UINT
*stride
)
5045 *stride
= (*width
* 3 + 3) & ~3;
5046 trace("width %d, height %d, stride %d\n", *width
, *height
, *stride
);
5048 src
= HeapAlloc(GetProcessHeap(), 0, *stride
* *height
);
5050 scale
= 256 / *width
;
5051 if (!scale
) scale
= 1;
5053 for (i
= 0; i
< *height
; i
++)
5055 for (j
= 0; j
< *width
; j
++)
5057 src
[i
* *stride
+ j
*3 + 0] = scale
* i
;
5058 src
[i
* *stride
+ j
*3 + 1] = scale
* (255 - (i
+j
)/2);
5059 src
[i
* *stride
+ j
*3 + 2] = scale
* j
;
5066 static void test_GdipInitializePalette(void)
5071 ColorPalette
*palette
;
5072 UINT width
, height
, stride
;
5074 pGdipInitializePalette
= (void *)GetProcAddress(GetModuleHandleA("gdiplus.dll"), "GdipInitializePalette");
5075 if (!pGdipInitializePalette
)
5077 win_skip("GdipInitializePalette is not supported on this platform\n");
5081 data
= init_bitmap(&width
, &height
, &stride
);
5083 status
= GdipCreateBitmapFromScan0(width
, height
, stride
, PixelFormat24bppRGB
, data
, &bitmap
);
5086 palette
= GdipAlloc(sizeof(*palette
) + sizeof(ARGB
) * 255);
5089 palette
->Count
= 15;
5090 status
= pGdipInitializePalette(palette
, PaletteTypeOptimal
, 16, FALSE
, bitmap
);
5091 expect(GenericError
, status
);
5094 palette
->Count
= 256;
5095 status
= pGdipInitializePalette(palette
, PaletteTypeOptimal
, 16, FALSE
, NULL
);
5096 expect(InvalidParameter
, status
);
5098 memset(palette
->Entries
, 0x11, sizeof(ARGB
) * 256);
5100 palette
->Count
= 256;
5101 status
= pGdipInitializePalette(palette
, PaletteTypeCustom
, 16, FALSE
, NULL
);
5103 expect(0, palette
->Flags
);
5104 expect(256, palette
->Count
);
5105 expect(0x11111111, palette
->Entries
[0]);
5106 expect(0x11111111, palette
->Entries
[128]);
5107 expect(0x11111111, palette
->Entries
[255]);
5109 memset(palette
->Entries
, 0x11, sizeof(ARGB
) * 256);
5111 palette
->Count
= 256;
5112 status
= pGdipInitializePalette(palette
, PaletteTypeFixedBW
, 0, FALSE
, bitmap
);
5115 expect(0x200, palette
->Flags
);
5116 expect(2, palette
->Count
);
5117 expect(0xff000000, palette
->Entries
[0]);
5118 expect(0xffffffff, palette
->Entries
[1]);
5120 memset(palette
->Entries
, 0x11, sizeof(ARGB
) * 256);
5122 palette
->Count
= 256;
5123 status
= pGdipInitializePalette(palette
, PaletteTypeFixedHalftone8
, 1, FALSE
, NULL
);
5126 expect(0x300, palette
->Flags
);
5127 expect(16, palette
->Count
);
5128 expect(0xff000000, palette
->Entries
[0]);
5129 expect(0xffc0c0c0, palette
->Entries
[8]);
5130 expect(0xff008080, palette
->Entries
[15]);
5132 memset(palette
->Entries
, 0x11, sizeof(ARGB
) * 256);
5134 palette
->Count
= 256;
5135 status
= pGdipInitializePalette(palette
, PaletteTypeFixedHalftone8
, 1, FALSE
, bitmap
);
5138 expect(0x300, palette
->Flags
);
5139 expect(16, palette
->Count
);
5140 expect(0xff000000, palette
->Entries
[0]);
5141 expect(0xffc0c0c0, palette
->Entries
[8]);
5142 expect(0xff008080, palette
->Entries
[15]);
5144 memset(palette
->Entries
, 0x11, sizeof(ARGB
) * 256);
5146 palette
->Count
= 256;
5147 status
= pGdipInitializePalette(palette
, PaletteTypeFixedHalftone252
, 1, FALSE
, bitmap
);
5150 expect(0x800, palette
->Flags
);
5151 expect(252, palette
->Count
);
5152 expect(0xff000000, palette
->Entries
[0]);
5153 expect(0xff990066, palette
->Entries
[128]);
5154 expect(0xffffffff, palette
->Entries
[251]);
5157 palette
->Count
= 256;
5158 status
= pGdipInitializePalette(palette
, PaletteTypeOptimal
, 1, FALSE
, bitmap
);
5159 expect(InvalidParameter
, status
);
5162 palette
->Count
= 256;
5163 status
= pGdipInitializePalette(palette
, PaletteTypeOptimal
, 2, FALSE
, bitmap
);
5165 expect(0, palette
->Flags
);
5166 expect(2, palette
->Count
);
5169 palette
->Count
= 256;
5170 status
= pGdipInitializePalette(palette
, PaletteTypeOptimal
, 16, FALSE
, bitmap
);
5172 expect(0, palette
->Flags
);
5173 expect(16, palette
->Count
);
5175 /* passing invalid enumeration palette type crashes under most Windows versions */
5178 GdipDisposeImage((GpImage
*)bitmap
);
5181 #include "pshpack2.h"
5182 static const struct tiff_1x1_data
5187 USHORT number_of_entries
;
5188 struct IFD_entry entry
[12];
5190 struct IFD_rational res
;
5191 short palette_data
[3][256];
5193 BYTE pixel_data
[32];
5196 #ifdef WORDS_BIGENDIAN
5202 FIELD_OFFSET(struct tiff_1x1_data
, number_of_entries
),
5205 { 0xff, IFD_SHORT
, 1, 0 }, /* SUBFILETYPE */
5206 { 0x100, IFD_LONG
, 1, 1 }, /* IMAGEWIDTH */
5207 { 0x101, IFD_LONG
, 1, 1 }, /* IMAGELENGTH */
5208 { 0x102, IFD_SHORT
, 3, FIELD_OFFSET(struct tiff_1x1_data
, bps_data
) }, /* BITSPERSAMPLE */
5209 { 0x103, IFD_SHORT
, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
5210 { 0x106, IFD_SHORT
, 1, 2 }, /* PHOTOMETRIC */
5211 { 0x111, IFD_LONG
, 1, FIELD_OFFSET(struct tiff_1x1_data
, pixel_data
) }, /* STRIPOFFSETS */
5212 { 0x115, IFD_SHORT
, 1, 3 }, /* SAMPLESPERPIXEL */
5213 { 0x11a, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_1x1_data
, res
) },
5214 { 0x11b, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_1x1_data
, res
) },
5215 { 0x128, IFD_SHORT
, 1, 2 }, /* RESOLUTIONUNIT */
5216 { 0x140, IFD_SHORT
, 256*3, FIELD_OFFSET(struct tiff_1x1_data
, palette_data
) } /* COLORMAP */
5222 { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 }
5224 #include "poppack.h"
5226 static void test_tiff_color_formats(void)
5230 int photometric
; /* PhotometricInterpretation */
5231 int samples
; /* SamplesPerPixel */
5232 int bps
; /* BitsPerSample */
5237 { 2, 3, 1, PixelFormat24bppRGB
},
5238 { 2, 3, 4, PixelFormat24bppRGB
},
5239 { 2, 3, 8, PixelFormat24bppRGB
},
5240 { 2, 3, 16, PixelFormat48bppRGB
},
5245 { 2, 4, 1, PixelFormat32bppARGB
},
5246 { 2, 4, 4, PixelFormat32bppARGB
},
5247 { 2, 4, 8, PixelFormat32bppARGB
},
5248 { 2, 4, 16, PixelFormat48bppRGB
},
5251 /* 1 - BlackIsZero (Bilevel) */
5252 { 1, 1, 1, PixelFormat1bppIndexed
},
5253 #if 0 /* FIXME: PNG vs TIFF mismatch */
5254 { 1, 1, 4, PixelFormat8bppIndexed
},
5256 { 1, 1, 8, PixelFormat8bppIndexed
},
5257 { 1, 1, 16, PixelFormat32bppARGB
},
5259 { 1, 1, 32, PixelFormat32bppARGB
},
5260 /* 3 - Palette Color */
5261 { 3, 1, 1, PixelFormat1bppIndexed
},
5262 { 3, 1, 4, PixelFormat4bppIndexed
},
5263 { 3, 1, 8, PixelFormat8bppIndexed
},
5264 #if 0 /* FIXME: for some reason libtiff replaces photometric 3 by 1 for bps > 8 */
5272 { 5, 4, 8, PixelFormat32bppCMYK
},
5273 { 5, 4, 16, PixelFormat48bppRGB
},
5277 BYTE buf
[sizeof(tiff_1x1_data
)];
5281 struct IFD_entry
*tag
, *tag_photo
= NULL
, *tag_bps
= NULL
, *tag_samples
= NULL
, *tag_colormap
= NULL
;
5286 memcpy(buf
, &tiff_1x1_data
, sizeof(tiff_1x1_data
));
5288 count
= *(short *)(buf
+ tiff_1x1_data
.dir_offset
);
5289 tag
= (struct IFD_entry
*)(buf
+ tiff_1x1_data
.dir_offset
+ sizeof(short));
5291 /* verify the TIFF structure */
5292 for (i
= 0; i
< count
; i
++)
5294 if (tag
[i
].id
== 0x102) /* BitsPerSample */
5296 else if (tag
[i
].id
== 0x106) /* PhotometricInterpretation */
5297 tag_photo
= &tag
[i
];
5298 else if (tag
[i
].id
== 0x115) /* SamplesPerPixel */
5299 tag_samples
= &tag
[i
];
5300 else if (tag
[i
].id
== 0x140) /* ColorMap */
5301 tag_colormap
= &tag
[i
];
5304 ok(tag_bps
&& tag_photo
&& tag_samples
&& tag_colormap
, "tag 0x102,0x106,0x115 or 0x140 is missing\n");
5305 if (!tag_bps
|| !tag_photo
|| !tag_samples
|| !tag_colormap
) return;
5307 ok(tag_bps
->type
== IFD_SHORT
, "tag 0x102 should have type IFD_SHORT\n");
5308 bps
= (short *)(buf
+ tag_bps
->value
);
5309 ok(bps
[0] == 8 && bps
[1] == 8 && bps
[2] == 8 && bps
[3] == 0,
5310 "expected bps 8,8,8,0 got %d,%d,%d,%d\n", bps
[0], bps
[1], bps
[2], bps
[3]);
5312 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
5314 tag_colormap
->count
= (1 << td
[i
].bps
) * 3;
5315 tag_photo
->value
= td
[i
].photometric
;
5316 tag_bps
->count
= td
[i
].samples
;
5317 tag_samples
->value
= td
[i
].samples
;
5319 if (td
[i
].samples
== 1)
5320 tag_bps
->value
= td
[i
].bps
;
5321 else if (td
[i
].samples
== 2)
5322 tag_bps
->value
= MAKELONG(td
[i
].bps
, td
[i
].bps
);
5323 else if (td
[i
].samples
== 3)
5325 tag_bps
->value
= (BYTE
*)bps
- buf
;
5326 bps
[0] = bps
[1] = bps
[2] = td
[i
].bps
;
5328 else if (td
[i
].samples
== 4)
5330 tag_bps
->value
= (BYTE
*)bps
- buf
;
5331 bps
[0] = bps
[1] = bps
[2] = bps
[3] = td
[i
].bps
;
5335 ok(0, "%u: unsupported samples count %d\n", i
, td
[i
].samples
);
5339 image
= load_image(buf
, sizeof(buf
));
5342 "%u: (%d,%d,%d) TIFF image loading should have failed\n", i
, td
[i
].photometric
, td
[i
].samples
, td
[i
].bps
);
5344 ok(image
!= NULL
|| broken(!image
) /* XP */, "%u: failed to load TIFF image data (%d,%d,%d)\n",
5345 i
, td
[i
].photometric
, td
[i
].samples
, td
[i
].bps
);
5346 if (!image
) continue;
5348 status
= GdipGetImageType(image
, &type
);
5349 ok(status
== Ok
, "%u: GdipGetImageType error %d\n", i
, status
);
5350 ok(type
== ImageTypeBitmap
, "%u: wrong image type %d\n", i
, type
);
5352 status
= GdipGetImagePixelFormat(image
, &format
);
5354 ok(format
== td
[i
].format
,
5355 "%u: expected %#x, got %#x\n", i
, td
[i
].format
, format
);
5357 GdipDisposeImage(image
);
5363 HMODULE mod
= GetModuleHandleA("gdiplus.dll");
5364 struct GdiplusStartupInput gdiplusStartupInput
;
5365 ULONG_PTR gdiplusToken
;
5367 int (CDECL
* _controlfp_s
)(unsigned int *cur
, unsigned int newval
, unsigned int mask
);
5369 /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */
5370 hmsvcrt
= LoadLibraryA("msvcrt");
5371 _controlfp_s
= (void*)GetProcAddress(hmsvcrt
, "_controlfp_s");
5372 if (_controlfp_s
) _controlfp_s(0, 0, 0x0008001e);
5374 gdiplusStartupInput
.GdiplusVersion
= 1;
5375 gdiplusStartupInput
.DebugEventCallback
= NULL
;
5376 gdiplusStartupInput
.SuppressBackgroundThread
= 0;
5377 gdiplusStartupInput
.SuppressExternalCodecs
= 0;
5379 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, NULL
);
5381 pGdipBitmapGetHistogramSize
= (void*)GetProcAddress(mod
, "GdipBitmapGetHistogramSize");
5382 pGdipBitmapGetHistogram
= (void*)GetProcAddress(mod
, "GdipBitmapGetHistogram");
5383 pGdipImageSetAbort
= (void*)GetProcAddress(mod
, "GdipImageSetAbort");
5385 test_tiff_color_formats();
5386 test_GdipInitializePalette();
5387 test_png_color_formats();
5388 test_supported_encoders();
5389 test_CloneBitmapArea();
5390 test_ARGB_conversion();
5391 test_DrawImage_scale();
5392 test_image_format();
5394 test_DrawImage_SourceCopy();
5395 test_GdipDrawImagePointRect();
5397 test_tiff_palette();
5398 test_GdipGetAllPropertyItems();
5399 test_tiff_properties();
5400 test_gif_properties();
5401 test_image_properties();
5404 test_GetImageDimension();
5405 test_GdipImageGetFrameDimensionsCount();
5406 test_LoadingImages();
5407 test_SavingImages();
5410 test_LockBits_UserBuf();
5411 test_GdipCreateBitmapFromHBITMAP();
5412 test_GdipGetImageFlags();
5413 test_GdipCloneImage();
5416 test_getrawformat();
5418 test_createfromwmf();
5419 test_createfromwmf_noplaceable();
5421 test_createhbitmap();
5422 test_getthumbnail();
5427 test_multiframegif();
5432 test_createeffect();
5433 test_getadjustedpalette();
5437 GdiplusShutdown(gdiplusToken
);