2 * Unit test suite for images
4 * Copyright (C) 2007 Google (Evan Stade)
5 * Copyright (C) 2012, 2016 Dmitry Timoshkov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 #include "wine/test.h"
37 /* FIXME: They belong to gdipluseffects.h */
38 DEFINE_GUID(BlurEffectGuid
, 0x633c80a4, 0x1843, 0x482b, 0x9e, 0xf2, 0xbe, 0x28, 0x34, 0xc5, 0xfd, 0xd4);
39 DEFINE_GUID(SharpenEffectGuid
, 0x63cbf3ee, 0xc526, 0x402c, 0x8f, 0x71, 0x62, 0xc5, 0x40, 0xbf, 0x51, 0x42);
40 DEFINE_GUID(ColorMatrixEffectGuid
, 0x718f2615, 0x7933, 0x40e3, 0xa5, 0x11, 0x5f, 0x68, 0xfe, 0x14, 0xdd, 0x74);
41 DEFINE_GUID(ColorLUTEffectGuid
, 0xa7ce72a9, 0x0f7f, 0x40d7, 0xb3, 0xcc, 0xd0, 0xc0, 0x2d, 0x5c, 0x32, 0x12);
42 DEFINE_GUID(BrightnessContrastEffectGuid
, 0xd3a1dbe1, 0x8ec4, 0x4c17, 0x9f, 0x4c, 0xea, 0x97, 0xad, 0x1c, 0x34, 0x3d);
43 DEFINE_GUID(HueSaturationLightnessEffectGuid
, 0x8b2dd6c3, 0xeb07, 0x4d87, 0xa5, 0xf0, 0x71, 0x08, 0xe2, 0x6a, 0x9c, 0x5f);
44 DEFINE_GUID(LevelsEffectGuid
, 0x99c354ec, 0x2a31, 0x4f3a, 0x8c, 0x34, 0x17, 0xa8, 0x03, 0xb3, 0x3a, 0x25);
45 DEFINE_GUID(TintEffectGuid
, 0x1077af00, 0x2848, 0x4441, 0x94, 0x89, 0x44, 0xad, 0x4c, 0x2d, 0x7a, 0x2c);
46 DEFINE_GUID(ColorBalanceEffectGuid
, 0x537e597d, 0x251e, 0x48da, 0x96, 0x64, 0x29, 0xca, 0x49, 0x6b, 0x70, 0xf8);
47 DEFINE_GUID(RedEyeCorrectionEffectGuid
, 0x74d29d05, 0x69a4, 0x4266, 0x95, 0x49, 0x3c, 0xc5, 0x28, 0x36, 0xb6, 0x32);
48 DEFINE_GUID(ColorCurveEffectGuid
, 0xdd6a0022, 0x58e4, 0x4a67, 0x9d, 0x9b, 0xd4, 0x8e, 0xb8, 0x81, 0xa5, 0x3d);
50 static GpStatus (WINAPI
*pGdipBitmapGetHistogramSize
)(HistogramFormat
,UINT
*);
51 static GpStatus (WINAPI
*pGdipBitmapGetHistogram
)(GpBitmap
*,HistogramFormat
,UINT
,UINT
*,UINT
*,UINT
*,UINT
*);
52 static GpStatus (WINAPI
*pGdipImageSetAbort
)(GpImage
*,GdiplusAbort
*);
54 static GpStatus (WINGDIPAPI
*pGdipInitializePalette
)(ColorPalette
*,PaletteType
,INT
,BOOL
,GpBitmap
*);
56 #define expect(expected, got) ok((got) == (expected), "Expected %d, got %d\n", (UINT)(expected), (UINT)(got))
57 #define expectf(expected, got) ok(fabs((expected) - (got)) < 0.0001, "Expected %f, got %f\n", (expected), (got))
59 static BOOL
color_match(ARGB c1
, ARGB c2
, BYTE max_diff
)
61 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
63 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
65 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
67 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
71 static void expect_guid(REFGUID expected
, REFGUID got
, int line
, BOOL todo
)
77 StringFromGUID2(got
, bufferW
, ARRAY_SIZE(bufferW
));
78 WideCharToMultiByte(CP_ACP
, 0, bufferW
, ARRAY_SIZE(bufferW
), buffer
, sizeof(buffer
), NULL
, NULL
);
79 StringFromGUID2(expected
, bufferW
, ARRAY_SIZE(bufferW
));
80 WideCharToMultiByte(CP_ACP
, 0, bufferW
, ARRAY_SIZE(bufferW
), buffer2
, sizeof(buffer2
), NULL
, NULL
);
82 ok_(__FILE__
, line
)(IsEqualGUID(expected
, got
), "Expected %s, got %s\n", buffer2
, buffer
);
85 static void expect_rawformat(REFGUID expected
, GpImage
*img
, int line
, BOOL todo
)
90 stat
= GdipGetImageRawFormat(img
, &raw
);
91 ok_(__FILE__
, line
)(stat
== Ok
, "GdipGetImageRawFormat failed with %d\n", stat
);
92 if(stat
!= Ok
) return;
93 expect_guid(expected
, &raw
, line
, todo
);
96 static void test_bufferrawformat(void* buff
, int size
, REFGUID expected
, int line
, BOOL todo
)
105 hglob
= GlobalAlloc (0, size
);
106 data
= GlobalLock (hglob
);
107 memcpy(data
, buff
, size
);
108 GlobalUnlock(hglob
); data
= NULL
;
110 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
111 ok_(__FILE__
, line
)(hres
== S_OK
, "Failed to create a stream\n");
112 if(hres
!= S_OK
) return;
114 stat
= GdipLoadImageFromStream(stream
, &img
);
115 ok_(__FILE__
, line
)(stat
== Ok
, "Failed to create a Bitmap\n");
117 IStream_Release(stream
);
121 expect_rawformat(expected
, img
, line
, todo
);
123 GdipDisposeImage(img
);
124 IStream_Release(stream
);
127 static void test_Scan0(void)
134 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
136 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
138 GdipDisposeImage((GpImage
*)bm
);
140 bm
= (GpBitmap
*)0xdeadbeef;
141 stat
= GdipCreateBitmapFromScan0(10, -10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
142 expect(InvalidParameter
, stat
);
143 ok( !bm
, "expected null bitmap\n" );
145 bm
= (GpBitmap
*)0xdeadbeef;
146 stat
= GdipCreateBitmapFromScan0(-10, 10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
147 expect(InvalidParameter
, stat
);
148 ok( !bm
, "expected null bitmap\n" );
150 bm
= (GpBitmap
*)0xdeadbeef;
151 stat
= GdipCreateBitmapFromScan0(10, 0, 10, PixelFormat24bppRGB
, NULL
, &bm
);
152 expect(InvalidParameter
, stat
);
153 ok( !bm
, "expected null bitmap\n" );
156 stat
= GdipCreateBitmapFromScan0(10, 10, 12, PixelFormat24bppRGB
, buff
, &bm
);
158 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
160 GdipDisposeImage((GpImage
*)bm
);
162 bm
= (GpBitmap
*) 0xdeadbeef;
163 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, buff
, &bm
);
164 expect(InvalidParameter
, stat
);
165 ok( !bm
, "expected null bitmap\n" );
167 bm
= (GpBitmap
*)0xdeadbeef;
168 stat
= GdipCreateBitmapFromScan0(10, 10, 0, PixelFormat24bppRGB
, buff
, &bm
);
169 expect(InvalidParameter
, stat
);
170 ok( bm
== (GpBitmap
*)0xdeadbeef, "expected deadbeef bitmap\n" );
173 stat
= GdipCreateBitmapFromScan0(10, 10, -8, PixelFormat24bppRGB
, buff
, &bm
);
175 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
177 GdipDisposeImage((GpImage
*)bm
);
179 bm
= (GpBitmap
*)0xdeadbeef;
180 stat
= GdipCreateBitmapFromScan0(10, 10, -10, PixelFormat24bppRGB
, buff
, &bm
);
181 expect(InvalidParameter
, stat
);
182 ok( !bm
, "expected null bitmap\n" );
185 static void test_FromGdiDib(void)
190 BYTE rbmi
[sizeof(BITMAPINFOHEADER
)+256*sizeof(RGBQUAD
)];
191 BITMAPINFO
*bmi
= (BITMAPINFO
*)rbmi
;
196 memset(rbmi
, 0, sizeof(rbmi
));
198 bmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
199 bmi
->bmiHeader
.biWidth
= 10;
200 bmi
->bmiHeader
.biHeight
= 10;
201 bmi
->bmiHeader
.biPlanes
= 1;
202 bmi
->bmiHeader
.biBitCount
= 32;
203 bmi
->bmiHeader
.biCompression
= BI_RGB
;
205 stat
= GdipCreateBitmapFromGdiDib(NULL
, buff
, &bm
);
206 expect(InvalidParameter
, stat
);
208 stat
= GdipCreateBitmapFromGdiDib(bmi
, NULL
, &bm
);
209 expect(InvalidParameter
, stat
);
211 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, NULL
);
212 expect(InvalidParameter
, stat
);
214 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
216 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
219 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
221 expect(PixelFormat32bppRGB
, format
);
223 GdipDisposeImage((GpImage
*)bm
);
226 bmi
->bmiHeader
.biBitCount
= 24;
227 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
229 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
232 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
234 expect(PixelFormat24bppRGB
, format
);
236 GdipDisposeImage((GpImage
*)bm
);
239 bmi
->bmiHeader
.biBitCount
= 16;
240 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
242 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
245 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
247 expect(PixelFormat16bppRGB555
, format
);
249 GdipDisposeImage((GpImage
*)bm
);
252 bmi
->bmiHeader
.biBitCount
= 8;
253 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
255 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
258 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
260 expect(PixelFormat8bppIndexed
, format
);
262 GdipDisposeImage((GpImage
*)bm
);
265 bmi
->bmiHeader
.biBitCount
= 4;
266 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
268 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
271 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
273 expect(PixelFormat4bppIndexed
, format
);
275 GdipDisposeImage((GpImage
*)bm
);
278 bmi
->bmiHeader
.biBitCount
= 1;
279 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
281 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
284 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
286 expect(PixelFormat1bppIndexed
, format
);
288 GdipDisposeImage((GpImage
*)bm
);
291 bmi
->bmiHeader
.biBitCount
= 0;
292 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
293 expect(InvalidParameter
, stat
);
296 static void test_GetImageDimension(void)
300 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
303 bm
= (GpBitmap
*)0xdeadbeef;
304 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
,NULL
, &bm
);
306 ok((GpBitmap
*)0xdeadbeef != bm
, "Expected bitmap to not be 0xdeadbeef\n");
307 ok(NULL
!= bm
, "Expected bitmap to not be NULL\n");
309 stat
= GdipGetImageDimension(NULL
,&w
,&h
);
310 expect(InvalidParameter
, stat
);
312 stat
= GdipGetImageDimension((GpImage
*)bm
,NULL
,&h
);
313 expect(InvalidParameter
, stat
);
315 stat
= GdipGetImageDimension((GpImage
*)bm
,&w
,NULL
);
316 expect(InvalidParameter
, stat
);
320 stat
= GdipGetImageDimension((GpImage
*)bm
,&w
,&h
);
324 GdipDisposeImage((GpImage
*)bm
);
327 static void test_GdipImageGetFrameDimensionsCount(void)
331 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
333 GUID dimension
= {0};
337 bm
= (GpBitmap
*)0xdeadbeef;
338 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
,NULL
, &bm
);
340 ok((GpBitmap
*)0xdeadbeef != bm
, "Expected bitmap to not be 0xdeadbeef\n");
341 ok(NULL
!= bm
, "Expected bitmap to not be NULL\n");
343 stat
= GdipImageGetFrameDimensionsCount(NULL
,&w
);
344 expect(InvalidParameter
, stat
);
346 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bm
,NULL
);
347 expect(InvalidParameter
, stat
);
350 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bm
,&w
);
354 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 1);
356 expect_guid(&FrameDimensionPage
, &dimension
, __LINE__
, FALSE
);
358 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 2);
359 expect(InvalidParameter
, stat
);
361 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 0);
362 expect(InvalidParameter
, stat
);
364 stat
= GdipImageGetFrameCount(NULL
, &dimension
, &count
);
365 expect(InvalidParameter
, stat
);
367 /* WinXP crashes on this test */
370 stat
= GdipImageGetFrameCount((GpImage
*)bm
, &dimension
, NULL
);
371 expect(InvalidParameter
, stat
);
374 stat
= GdipImageGetFrameCount((GpImage
*)bm
, NULL
, &count
);
378 stat
= GdipImageGetFrameCount((GpImage
*)bm
, &dimension
, &count
);
382 GdipBitmapSetPixel(bm
, 0, 0, 0xffffffff);
384 stat
= GdipImageSelectActiveFrame((GpImage
*)bm
, &dimension
, 0);
387 /* SelectActiveFrame has no effect on image data of memory bitmaps */
389 stat
= GdipBitmapGetPixel(bm
, 0, 0, &color
);
391 expect(0xffffffff, color
);
393 GdipDisposeImage((GpImage
*)bm
);
396 static void test_LoadingImages(void)
401 static const WCHAR nonexistentW
[] = {'n','o','n','e','x','i','s','t','e','n','t',0};
403 stat
= GdipCreateBitmapFromFile(0, 0);
404 expect(InvalidParameter
, stat
);
406 bm
= (GpBitmap
*)0xdeadbeef;
407 stat
= GdipCreateBitmapFromFile(0, &bm
);
408 expect(InvalidParameter
, stat
);
409 ok(bm
== (GpBitmap
*)0xdeadbeef, "returned %p\n", bm
);
411 bm
= (GpBitmap
*)0xdeadbeef;
412 stat
= GdipCreateBitmapFromFile(nonexistentW
, &bm
);
413 todo_wine
expect(InvalidParameter
, stat
);
414 ok(!bm
, "returned %p\n", bm
);
416 stat
= GdipLoadImageFromFile(0, 0);
417 expect(InvalidParameter
, stat
);
419 img
= (GpImage
*)0xdeadbeef;
420 stat
= GdipLoadImageFromFile(0, &img
);
421 expect(InvalidParameter
, stat
);
422 ok(img
== (GpImage
*)0xdeadbeef, "returned %p\n", img
);
424 img
= (GpImage
*)0xdeadbeef;
425 stat
= GdipLoadImageFromFile(nonexistentW
, &img
);
426 todo_wine
expect(OutOfMemory
, stat
);
427 ok(!img
, "returned %p\n", img
);
429 stat
= GdipLoadImageFromFileICM(0, 0);
430 expect(InvalidParameter
, stat
);
432 img
= (GpImage
*)0xdeadbeef;
433 stat
= GdipLoadImageFromFileICM(0, &img
);
434 expect(InvalidParameter
, stat
);
435 ok(img
== (GpImage
*)0xdeadbeef, "returned %p\n", img
);
437 img
= (GpImage
*)0xdeadbeef;
438 stat
= GdipLoadImageFromFileICM(nonexistentW
, &img
);
439 todo_wine
expect(OutOfMemory
, stat
);
440 ok(!img
, "returned %p\n", img
);
443 static void test_SavingImages(void)
449 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
451 ImageCodecInfo
*codecs
;
452 static const CHAR filenameA
[] = "a.bmp";
453 static const WCHAR filename
[] = { 'a','.','b','m','p',0 };
457 stat
= GdipSaveImageToFile(0, 0, 0, 0);
458 expect(InvalidParameter
, stat
);
461 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
467 stat
= GdipSaveImageToFile((GpImage
*)bm
, 0, 0, 0);
468 expect(InvalidParameter
, stat
);
470 stat
= GdipSaveImageToFile((GpImage
*)bm
, filename
, 0, 0);
471 expect(InvalidParameter
, stat
);
473 /* encoder tests should succeed -- already tested */
474 stat
= GdipGetImageEncodersSize(&n
, &s
);
475 if (stat
!= Ok
|| n
== 0) goto cleanup
;
477 codecs
= GdipAlloc(s
);
478 if (!codecs
) goto cleanup
;
480 stat
= GdipGetImageEncoders(n
, s
, codecs
);
481 if (stat
!= Ok
) goto cleanup
;
483 stat
= GdipSaveImageToFile((GpImage
*)bm
, filename
, &codecs
[0].Clsid
, 0);
486 GdipDisposeImage((GpImage
*)bm
);
489 /* re-load and check image stats */
490 stat
= GdipLoadImageFromFile(filename
, (GpImage
**)&bm
);
492 if (stat
!= Ok
) goto cleanup
;
494 stat
= GdipGetImageDimension((GpImage
*)bm
, &w
, &h
);
495 if (stat
!= Ok
) goto cleanup
;
503 GdipDisposeImage((GpImage
*)bm
);
504 ok(DeleteFileA(filenameA
), "Delete failed.\n");
507 static void test_encoders(void)
512 ImageCodecInfo
*codecs
;
516 static const CHAR bmp_format
[] = "BMP";
518 stat
= GdipGetImageEncodersSize(&n
, &s
);
521 codecs
= GdipAlloc(s
);
525 stat
= GdipGetImageEncoders(n
, s
, NULL
);
526 expect(GenericError
, stat
);
528 stat
= GdipGetImageEncoders(0, s
, codecs
);
529 expect(GenericError
, stat
);
531 stat
= GdipGetImageEncoders(n
, s
-1, codecs
);
532 expect(GenericError
, stat
);
534 stat
= GdipGetImageEncoders(n
, s
+1, codecs
);
535 expect(GenericError
, stat
);
537 stat
= GdipGetImageEncoders(n
, s
, codecs
);
541 for (i
= 0; i
< n
; i
++)
545 WideCharToMultiByte(CP_ACP
, 0, codecs
[i
].FormatDescription
, -1,
548 if (CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0,
550 bmp_format
, -1) == CSTR_EQUAL
) {
556 ok(FALSE
, "No BMP codec found.\n");
561 static void test_LockBits(void)
567 const INT WIDTH
= 10, HEIGHT
= 20;
572 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
580 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffc30000);
583 stat
= GdipBitmapSetPixel(bm
, 2, 8, 0xff480000);
587 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
591 expect(0xc3, ((BYTE
*)bd
.Scan0
)[2]);
592 expect(0x48, ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5]);
594 ((char*)bd
.Scan0
)[2] = 0xff;
596 stat
= GdipBitmapUnlockBits(bm
, &bd
);
600 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
602 expect(0xffff0000, color
);
604 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffc30000);
607 /* read-only, with NULL rect -> whole bitmap lock */
608 stat
= GdipBitmapLockBits(bm
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
610 expect(bd
.Width
, WIDTH
);
611 expect(bd
.Height
, HEIGHT
);
614 ((char*)bd
.Scan0
)[2 + 2*3 + 3*bd
.Stride
] = 0xff;
616 stat
= GdipBitmapUnlockBits(bm
, &bd
);
620 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
622 expect(0xffff0000, color
);
624 /* read-only, consecutive */
625 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
629 stat
= GdipBitmapUnlockBits(bm
, &bd
);
633 stat
= GdipDisposeImage((GpImage
*)bm
);
635 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
639 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
641 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
642 expect(WrongState
, stat
);
644 stat
= GdipBitmapUnlockBits(bm
, &bd
);
647 stat
= GdipDisposeImage((GpImage
*)bm
);
649 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
652 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffff0000);
655 stat
= GdipBitmapSetPixel(bm
, 2, 8, 0xffc30000);
658 /* write, no conversion */
659 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
663 /* all bits are readable, inside the rect or not */
664 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
665 expect(0xc3, ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5]);
667 stat
= GdipBitmapUnlockBits(bm
, &bd
);
671 /* read, conversion */
672 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat32bppARGB
, &bd
);
676 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
678 /* Areas outside the rectangle appear to be uninitialized */
679 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
681 ((BYTE
*)bd
.Scan0
)[2] = 0xc3;
683 stat
= GdipBitmapUnlockBits(bm
, &bd
);
687 /* writes do not work in read mode if there was a conversion */
688 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
690 expect(0xffff0000, color
);
692 /* read/write, conversion */
693 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeWrite
, PixelFormat32bppARGB
, &bd
);
697 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
698 ((BYTE
*)bd
.Scan0
)[1] = 0x88;
700 /* Areas outside the rectangle appear to be uninitialized */
701 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
703 stat
= GdipBitmapUnlockBits(bm
, &bd
);
707 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
709 expect(0xffff8800, color
);
711 /* write, conversion */
712 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat32bppARGB
, &bd
);
718 /* This is completely uninitialized. */
719 ok(0xff != ((BYTE
*)bd
.Scan0
)[2], "original image bits are readable\n");
720 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
723 /* Initialize the buffer so the unlock doesn't access undefined memory */
725 memset(((BYTE
*)bd
.Scan0
) + bd
.Stride
* y
, 0, 12);
727 ((BYTE
*)bd
.Scan0
)[0] = 0x12;
728 ((BYTE
*)bd
.Scan0
)[1] = 0x34;
729 ((BYTE
*)bd
.Scan0
)[2] = 0x56;
731 stat
= GdipBitmapUnlockBits(bm
, &bd
);
735 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
737 expect(0xff563412, color
);
739 stat
= GdipBitmapGetPixel(bm
, 2, 8, &color
);
741 expect(0xffc30000, color
);
743 stat
= GdipDisposeImage((GpImage
*)bm
);
745 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
748 /* write, no modification */
749 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
753 stat
= GdipBitmapUnlockBits(bm
, &bd
);
757 /* write, consecutive */
758 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
762 stat
= GdipBitmapUnlockBits(bm
, &bd
);
766 stat
= GdipDisposeImage((GpImage
*)bm
);
768 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
772 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
777 ((char*)bd
.Scan0
)[2] = 0xff;
779 stat
= GdipBitmapUnlockBits(bm
, &bd
);
783 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
785 expect(0xffff0000, color
);
787 stat
= GdipDisposeImage((GpImage
*)bm
);
791 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
793 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
795 stat
= GdipDisposeImage((GpImage
*)bm
);
799 static void test_LockBits_UserBuf(void)
805 const INT WIDTH
= 10, HEIGHT
= 20;
810 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat32bppARGB
, NULL
, &bm
);
813 memset(bits
, 0xaa, sizeof(bits
));
822 bd
.Stride
= WIDTH
* 4;
823 bd
.PixelFormat
= PixelFormat32bppARGB
;
824 bd
.Scan0
= &bits
[2+3*WIDTH
];
825 bd
.Reserved
= 0xaaaaaaaa;
828 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
831 expect(0xaaaaaaaa, bits
[0]);
832 expect(0, bits
[2+3*WIDTH
]);
834 bits
[2+3*WIDTH
] = 0xdeadbeef;
837 stat
= GdipBitmapUnlockBits(bm
, &bd
);
841 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
846 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
849 expect(0xdeadbeef, bits
[2+3*WIDTH
]);
850 bits
[2+3*WIDTH
] = 0x12345678;
853 stat
= GdipBitmapUnlockBits(bm
, &bd
);
857 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
859 expect(0x12345678, color
);
864 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeWrite
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
867 expect(0x12345678, bits
[2+3*WIDTH
]);
868 bits
[2+3*WIDTH
] = 0xdeadbeef;
871 stat
= GdipBitmapUnlockBits(bm
, &bd
);
875 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
877 expect(0xdeadbeef, color
);
879 stat
= GdipDisposeImage((GpImage
*)bm
);
883 struct BITMAPINFOWITHBITFIELDS
885 BITMAPINFOHEADER bmiHeader
;
889 union BITMAPINFOUNION
892 struct BITMAPINFOWITHBITFIELDS bf
;
895 static void test_GdipCreateBitmapFromHBITMAP(void)
897 GpBitmap
* gpbm
= NULL
;
899 HPALETTE hpal
= NULL
;
902 LOGPALETTE
* LogPal
= NULL
;
904 const REAL WIDTH1
= 5;
905 const REAL HEIGHT1
= 15;
906 const REAL WIDTH2
= 10;
907 const REAL HEIGHT2
= 20;
909 union BITMAPINFOUNION bmi
;
913 stat
= GdipCreateBitmapFromHBITMAP(NULL
, NULL
, NULL
);
914 expect(InvalidParameter
, stat
);
916 hbm
= CreateBitmap(WIDTH1
, HEIGHT1
, 1, 1, NULL
);
917 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, NULL
);
918 expect(InvalidParameter
, stat
);
920 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
922 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
923 expectf(WIDTH1
, width
);
924 expectf(HEIGHT1
, height
);
926 GdipDisposeImage((GpImage
*)gpbm
);
929 memset(buff
, 0, sizeof(buff
));
930 hbm
= CreateBitmap(WIDTH2
, HEIGHT2
, 1, 1, &buff
);
931 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
934 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)gpbm
, __LINE__
, FALSE
);
936 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
937 expectf(WIDTH2
, width
);
938 expectf(HEIGHT2
, height
);
940 GdipDisposeImage((GpImage
*)gpbm
);
943 hdc
= CreateCompatibleDC(0);
944 ok(hdc
!= NULL
, "CreateCompatibleDC failed\n");
945 bmi
.bi
.bmiHeader
.biSize
= sizeof(bmi
.bi
.bmiHeader
);
946 bmi
.bi
.bmiHeader
.biHeight
= HEIGHT1
;
947 bmi
.bi
.bmiHeader
.biWidth
= WIDTH1
;
948 bmi
.bi
.bmiHeader
.biBitCount
= 24;
949 bmi
.bi
.bmiHeader
.biPlanes
= 1;
950 bmi
.bi
.bmiHeader
.biCompression
= BI_RGB
;
951 bmi
.bi
.bmiHeader
.biClrUsed
= 0;
953 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
954 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
958 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
960 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
961 expectf(WIDTH1
, width
);
962 expectf(HEIGHT1
, height
);
965 /* test whether writing to the bitmap affects the original */
966 stat
= GdipBitmapSetPixel(gpbm
, 0, 0, 0xffffffff);
971 GdipDisposeImage((GpImage
*)gpbm
);
974 LogPal
= GdipAlloc(sizeof(LOGPALETTE
));
975 ok(LogPal
!= NULL
, "unable to allocate LOGPALETTE\n");
976 LogPal
->palVersion
= 0x300;
977 LogPal
->palNumEntries
= 1;
978 hpal
= CreatePalette(LogPal
);
979 ok(hpal
!= NULL
, "CreatePalette failed\n");
982 stat
= GdipCreateBitmapFromHBITMAP(hbm
, hpal
, &gpbm
);
986 GdipDisposeImage((GpImage
*)gpbm
);
991 /* 16-bit 555 dib, rgb */
992 bmi
.bi
.bmiHeader
.biBitCount
= 16;
993 bmi
.bi
.bmiHeader
.biCompression
= BI_RGB
;
995 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
996 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1000 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1005 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1007 expectf(WIDTH1
, width
);
1008 expectf(HEIGHT1
, height
);
1010 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1012 expect(PixelFormat16bppRGB555
, format
);
1014 GdipDisposeImage((GpImage
*)gpbm
);
1018 /* 16-bit 555 dib, with bitfields */
1019 bmi
.bi
.bmiHeader
.biSize
= sizeof(bmi
);
1020 bmi
.bi
.bmiHeader
.biCompression
= BI_BITFIELDS
;
1021 bmi
.bf
.masks
[0] = 0x7c00;
1022 bmi
.bf
.masks
[1] = 0x3e0;
1023 bmi
.bf
.masks
[2] = 0x1f;
1025 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1026 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1030 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1035 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1037 expectf(WIDTH1
, width
);
1038 expectf(HEIGHT1
, height
);
1040 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1042 expect(PixelFormat16bppRGB555
, format
);
1044 GdipDisposeImage((GpImage
*)gpbm
);
1048 /* 16-bit 565 dib, with bitfields */
1049 bmi
.bf
.masks
[0] = 0xf800;
1050 bmi
.bf
.masks
[1] = 0x7e0;
1051 bmi
.bf
.masks
[2] = 0x1f;
1053 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1054 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1058 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1063 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1065 expectf(WIDTH1
, width
);
1066 expectf(HEIGHT1
, height
);
1068 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1070 expect(PixelFormat16bppRGB565
, format
);
1072 GdipDisposeImage((GpImage
*)gpbm
);
1079 static void test_GdipGetImageFlags(void)
1085 img
= (GpImage
*)0xdeadbeef;
1087 stat
= GdipGetImageFlags(NULL
, NULL
);
1088 expect(InvalidParameter
, stat
);
1090 stat
= GdipGetImageFlags(NULL
, &flags
);
1091 expect(InvalidParameter
, stat
);
1093 stat
= GdipGetImageFlags(img
, NULL
);
1094 expect(InvalidParameter
, stat
);
1096 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat1bppIndexed
, NULL
, (GpBitmap
**)&img
);
1098 stat
= GdipGetImageFlags(img
, &flags
);
1100 expect(ImageFlagsHasAlpha
, flags
);
1101 GdipDisposeImage(img
);
1103 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat4bppIndexed
, NULL
, (GpBitmap
**)&img
);
1105 stat
= GdipGetImageFlags(img
, &flags
);
1107 expect(ImageFlagsHasAlpha
, flags
);
1108 GdipDisposeImage(img
);
1110 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat8bppIndexed
, NULL
, (GpBitmap
**)&img
);
1112 stat
= GdipGetImageFlags(img
, &flags
);
1114 expect(ImageFlagsHasAlpha
, flags
);
1115 GdipDisposeImage(img
);
1117 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppGrayScale
, NULL
, (GpBitmap
**)&img
);
1119 stat
= GdipGetImageFlags(img
, &flags
);
1121 expect(ImageFlagsNone
, flags
);
1122 GdipDisposeImage(img
);
1124 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB555
, NULL
, (GpBitmap
**)&img
);
1126 stat
= GdipGetImageFlags(img
, &flags
);
1128 expect(ImageFlagsNone
, flags
);
1129 GdipDisposeImage(img
);
1131 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB565
, NULL
, (GpBitmap
**)&img
);
1133 stat
= GdipGetImageFlags(img
, &flags
);
1135 expect(ImageFlagsNone
, flags
);
1136 GdipDisposeImage(img
);
1138 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppARGB1555
, NULL
, (GpBitmap
**)&img
);
1140 stat
= GdipGetImageFlags(img
, &flags
);
1142 expect(ImageFlagsHasAlpha
, flags
);
1143 GdipDisposeImage(img
);
1145 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, NULL
, (GpBitmap
**)&img
);
1147 stat
= GdipGetImageFlags(img
, &flags
);
1149 expect(ImageFlagsNone
, flags
);
1150 GdipDisposeImage(img
);
1152 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&img
);
1154 stat
= GdipGetImageFlags(img
, &flags
);
1156 expect(ImageFlagsNone
, flags
);
1157 GdipDisposeImage(img
);
1159 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppARGB
, NULL
, (GpBitmap
**)&img
);
1161 stat
= GdipGetImageFlags(img
, &flags
);
1163 expect(ImageFlagsHasAlpha
, flags
);
1164 GdipDisposeImage(img
);
1166 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppPARGB
, NULL
, (GpBitmap
**)&img
);
1168 stat
= GdipGetImageFlags(img
, &flags
);
1170 expect(ImageFlagsHasAlpha
, flags
);
1171 GdipDisposeImage(img
);
1173 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat48bppRGB
, NULL
, (GpBitmap
**)&img
);
1177 stat
= GdipGetImageFlags(img
, &flags
);
1179 expect(ImageFlagsNone
, flags
);
1180 GdipDisposeImage(img
);
1183 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB
, NULL
, (GpBitmap
**)&img
);
1188 stat
= GdipGetImageFlags(img
, &flags
);
1190 expect(ImageFlagsHasAlpha
, flags
);
1191 GdipDisposeImage(img
);
1194 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB
, NULL
, (GpBitmap
**)&img
);
1199 stat
= GdipGetImageFlags(img
, &flags
);
1201 expect(ImageFlagsHasAlpha
, flags
);
1202 GdipDisposeImage(img
);
1206 static void test_GdipCloneImage(void)
1212 GpImage
*image_src
, *image_dest
= NULL
;
1213 const INT WIDTH
= 10, HEIGHT
= 20;
1215 /* Create an image, clone it, delete the original, make sure the copy works */
1216 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
1218 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bm
, __LINE__
, FALSE
);
1220 image_src
= ((GpImage
*)bm
);
1221 stat
= GdipCloneImage(image_src
, &image_dest
);
1223 expect_rawformat(&ImageFormatMemoryBMP
, image_dest
, __LINE__
, FALSE
);
1225 stat
= GdipDisposeImage((GpImage
*)bm
);
1227 stat
= GdipGetImageBounds(image_dest
, &rectF
, &unit
);
1230 /* Treat FP values carefully */
1231 expectf((REAL
)WIDTH
, rectF
.Width
);
1232 expectf((REAL
)HEIGHT
, rectF
.Height
);
1234 stat
= GdipDisposeImage(image_dest
);
1238 static void test_testcontrol(void)
1244 stat
= GdipTestControl(TestControlGetBuildNumber
, ¶m
);
1246 ok(param
!= 0, "Build number expected, got %u\n", param
);
1249 static void test_fromhicon(void)
1251 static const BYTE bmp_bits
[1024];
1252 HBITMAP hbmMask
, hbmColor
;
1256 GpBitmap
*bitmap
= NULL
;
1262 stat
= GdipCreateBitmapFromHICON(NULL
, NULL
);
1263 expect(InvalidParameter
, stat
);
1264 stat
= GdipCreateBitmapFromHICON(NULL
, &bitmap
);
1265 expect(InvalidParameter
, stat
);
1267 /* color icon 1 bit */
1268 hbmMask
= CreateBitmap(16, 16, 1, 1, bmp_bits
);
1269 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1270 hbmColor
= CreateBitmap(16, 16, 1, 1, bmp_bits
);
1271 ok(hbmColor
!= 0, "CreateBitmap failed\n");
1275 info
.hbmMask
= hbmMask
;
1276 info
.hbmColor
= hbmColor
;
1277 hIcon
= CreateIconIndirect(&info
);
1278 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
1279 DeleteObject(hbmMask
);
1280 DeleteObject(hbmColor
);
1282 stat
= GdipCreateBitmapFromHICON(hIcon
, &bitmap
);
1284 broken(stat
== InvalidParameter
), /* Win98 */
1285 "Expected Ok, got %.8x\n", stat
);
1287 /* check attributes */
1288 stat
= GdipGetImageHeight((GpImage
*)bitmap
, &dim
);
1291 stat
= GdipGetImageWidth((GpImage
*)bitmap
, &dim
);
1294 stat
= GdipGetImageType((GpImage
*)bitmap
, &type
);
1296 expect(ImageTypeBitmap
, type
);
1297 stat
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
1299 expect(PixelFormat32bppARGB
, format
);
1301 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bitmap
, __LINE__
, FALSE
);
1302 GdipDisposeImage((GpImage
*)bitmap
);
1306 /* color icon 8 bpp */
1307 hbmMask
= CreateBitmap(16, 16, 1, 8, bmp_bits
);
1308 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1309 hbmColor
= CreateBitmap(16, 16, 1, 8, bmp_bits
);
1310 ok(hbmColor
!= 0, "CreateBitmap failed\n");
1314 info
.hbmMask
= hbmMask
;
1315 info
.hbmColor
= hbmColor
;
1316 hIcon
= CreateIconIndirect(&info
);
1317 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
1318 DeleteObject(hbmMask
);
1319 DeleteObject(hbmColor
);
1321 stat
= GdipCreateBitmapFromHICON(hIcon
, &bitmap
);
1324 /* check attributes */
1325 stat
= GdipGetImageHeight((GpImage
*)bitmap
, &dim
);
1328 stat
= GdipGetImageWidth((GpImage
*)bitmap
, &dim
);
1331 stat
= GdipGetImageType((GpImage
*)bitmap
, &type
);
1333 expect(ImageTypeBitmap
, type
);
1334 stat
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
1336 expect(PixelFormat32bppARGB
, format
);
1338 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bitmap
, __LINE__
, FALSE
);
1339 GdipDisposeImage((GpImage
*)bitmap
);
1345 static const unsigned char pngimage
[285] = {
1346 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
1347 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
1348 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
1349 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
1350 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
1351 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
1352 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
1355 static const unsigned char gifimage
[35] = {
1356 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
1357 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
1360 /* 1x1 pixel transparent gif */
1361 static const unsigned char transparentgif
[] = {
1362 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,
1363 0x00,0x00,0x00,0x21,0xf9,0x04,0x01,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,
1364 0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
1367 static const unsigned char bmpimage
[66] = {
1368 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
1369 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
1370 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
1371 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
1375 static const unsigned char jpgimage
[285] = {
1376 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
1377 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
1378 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
1379 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
1380 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
1381 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
1382 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
1383 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1384 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1385 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
1386 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
1387 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1388 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
1389 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
1390 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1391 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
1392 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
1393 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
1395 /* 1x1 pixel tiff */
1396 static const unsigned char tiffimage
[] = {
1397 0x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00,
1398 0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00,
1399 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1400 0x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01,
1401 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00,
1402 0x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00,
1403 0x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01,
1404 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00,
1405 0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00,
1406 0x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01,
1407 0x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00,
1408 0x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1409 0x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
1410 0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65,
1411 0x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74,
1412 0x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,
1415 /* 320x320 twip wmf */
1416 static const unsigned char wmfimage
[180] = {
1417 0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05,
1418 0x00,0x00,0x00,0x00,0xb1,0x52,0x01,0x00,0x09,0x00,0x00,0x03,0x4f,0x00,0x00,0x00,
1419 0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0b,0x02,0x00,0x00,
1420 0x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x02,0x40,0x01,0x40,0x01,0x04,0x00,0x00,0x00,
1421 0x02,0x01,0x01,0x00,0x04,0x00,0x00,0x00,0x04,0x01,0x0d,0x00,0x08,0x00,0x00,0x00,
1422 0xfa,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
1423 0x2d,0x01,0x00,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,0x01,0x00,0x00,0x00,0x00,0x00,
1424 0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x01,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,
1425 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x02,0x00,
1426 0x07,0x00,0x00,0x00,0x1b,0x04,0x40,0x01,0x40,0x01,0x00,0x00,0x00,0x00,0x04,0x00,
1427 0x00,0x00,0xf0,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0xf0,0x01,0x01,0x00,0x03,0x00,
1430 static void test_getrawformat(void)
1432 test_bufferrawformat((void*)pngimage
, sizeof(pngimage
), &ImageFormatPNG
, __LINE__
, FALSE
);
1433 test_bufferrawformat((void*)gifimage
, sizeof(gifimage
), &ImageFormatGIF
, __LINE__
, FALSE
);
1434 test_bufferrawformat((void*)bmpimage
, sizeof(bmpimage
), &ImageFormatBMP
, __LINE__
, FALSE
);
1435 test_bufferrawformat((void*)jpgimage
, sizeof(jpgimage
), &ImageFormatJPEG
, __LINE__
, FALSE
);
1436 test_bufferrawformat((void*)tiffimage
, sizeof(tiffimage
), &ImageFormatTIFF
, __LINE__
, FALSE
);
1437 test_bufferrawformat((void*)wmfimage
, sizeof(wmfimage
), &ImageFormatWMF
, __LINE__
, FALSE
);
1440 static void test_loadwmf(void)
1451 MetafileHeader header
;
1453 hglob
= GlobalAlloc (0, sizeof(wmfimage
));
1454 data
= GlobalLock (hglob
);
1455 memcpy(data
, wmfimage
, sizeof(wmfimage
));
1456 GlobalUnlock(hglob
); data
= NULL
;
1458 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
1459 ok(hres
== S_OK
, "Failed to create a stream\n");
1460 if(hres
!= S_OK
) return;
1462 stat
= GdipLoadImageFromStream(stream
, &img
);
1463 ok(stat
== Ok
, "Failed to create a Bitmap\n");
1465 IStream_Release(stream
);
1469 IStream_Release(stream
);
1471 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1473 expect(UnitPixel
, unit
);
1474 expectf(0.0, bounds
.X
);
1475 expectf(0.0, bounds
.Y
);
1476 expectf(320.0, bounds
.Width
);
1477 expectf(320.0, bounds
.Height
);
1479 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1481 expectf(1440.0, res
);
1483 stat
= GdipGetImageVerticalResolution(img
, &res
);
1485 expectf(1440.0, res
);
1487 memset(&header
, 0, sizeof(header
));
1488 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1492 expect(MetafileTypeWmfPlaceable
, header
.Type
);
1493 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1494 todo_wine
expect(0x300, header
.Version
);
1495 expect(0, header
.EmfPlusFlags
);
1496 expectf(1440.0, header
.DpiX
);
1497 expectf(1440.0, header
.DpiY
);
1498 expect(0, header
.X
);
1499 expect(0, header
.Y
);
1500 expect(320, header
.Width
);
1501 expect(320, header
.Height
);
1502 expect(1, U(header
).WmfHeader
.mtType
);
1503 expect(0, header
.EmfPlusHeaderSize
);
1504 expect(0, header
.LogicalDpiX
);
1505 expect(0, header
.LogicalDpiY
);
1508 GdipDisposeImage(img
);
1511 static void test_createfromwmf(void)
1519 MetafileHeader header
;
1521 hwmf
= SetMetaFileBitsEx(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
),
1522 wmfimage
+sizeof(WmfPlaceableFileHeader
));
1523 ok(hwmf
!= 0, "SetMetaFileBitsEx failed\n");
1525 stat
= GdipCreateMetafileFromWmf(hwmf
, TRUE
,
1526 (WmfPlaceableFileHeader
*)wmfimage
, (GpMetafile
**)&img
);
1529 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1531 expect(UnitPixel
, unit
);
1532 expectf(0.0, bounds
.X
);
1533 expectf(0.0, bounds
.Y
);
1534 expectf(320.0, bounds
.Width
);
1535 expectf(320.0, bounds
.Height
);
1537 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1539 expectf(1440.0, res
);
1541 stat
= GdipGetImageVerticalResolution(img
, &res
);
1543 expectf(1440.0, res
);
1545 memset(&header
, 0, sizeof(header
));
1546 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1550 expect(MetafileTypeWmfPlaceable
, header
.Type
);
1551 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1552 todo_wine
expect(0x300, header
.Version
);
1553 expect(0, header
.EmfPlusFlags
);
1554 expectf(1440.0, header
.DpiX
);
1555 expectf(1440.0, header
.DpiY
);
1556 expect(0, header
.X
);
1557 expect(0, header
.Y
);
1558 expect(320, header
.Width
);
1559 expect(320, header
.Height
);
1560 expect(1, U(header
).WmfHeader
.mtType
);
1561 expect(0, header
.EmfPlusHeaderSize
);
1562 expect(0, header
.LogicalDpiX
);
1563 expect(0, header
.LogicalDpiY
);
1566 GdipDisposeImage(img
);
1569 static void test_createfromwmf_noplaceable(void)
1575 hwmf
= SetMetaFileBitsEx(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
),
1576 wmfimage
+sizeof(WmfPlaceableFileHeader
));
1577 ok(hwmf
!= 0, "SetMetaFileBitsEx failed\n");
1579 stat
= GdipCreateMetafileFromWmf(hwmf
, TRUE
, NULL
, (GpMetafile
**)&img
);
1582 GdipDisposeImage(img
);
1585 static void test_resolution(void)
1589 GpGraphics
*graphics
;
1592 int screenxres
, screenyres
;
1595 stat
= GdipCreateBitmapFromScan0(1, 1, 32, PixelFormat24bppRGB
, NULL
, &bitmap
);
1598 /* test invalid values */
1599 stat
= GdipGetImageHorizontalResolution(NULL
, &res
);
1600 expect(InvalidParameter
, stat
);
1602 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, NULL
);
1603 expect(InvalidParameter
, stat
);
1605 stat
= GdipGetImageVerticalResolution(NULL
, &res
);
1606 expect(InvalidParameter
, stat
);
1608 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, NULL
);
1609 expect(InvalidParameter
, stat
);
1611 stat
= GdipBitmapSetResolution(NULL
, 96.0, 96.0);
1612 expect(InvalidParameter
, stat
);
1614 stat
= GdipBitmapSetResolution(bitmap
, 0.0, 0.0);
1615 expect(InvalidParameter
, stat
);
1617 /* defaults to screen resolution */
1618 screendc
= GetDC(0);
1620 screenxres
= GetDeviceCaps(screendc
, LOGPIXELSX
);
1621 screenyres
= GetDeviceCaps(screendc
, LOGPIXELSY
);
1623 ReleaseDC(0, screendc
);
1625 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1627 expectf((REAL
)screenxres
, res
);
1629 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1631 expectf((REAL
)screenyres
, res
);
1633 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1635 stat
= GdipGetDpiX(graphics
, &res
);
1637 expectf((REAL
)screenxres
, res
);
1638 stat
= GdipGetDpiY(graphics
, &res
);
1640 expectf((REAL
)screenyres
, res
);
1642 /* test changing the resolution */
1643 stat
= GdipBitmapSetResolution(bitmap
, screenxres
*2.0, screenyres
*3.0);
1646 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1648 expectf(screenxres
*2.0, res
);
1650 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1652 expectf(screenyres
*3.0, res
);
1654 stat
= GdipGetDpiX(graphics
, &res
);
1656 expectf((REAL
)screenxres
, res
);
1657 stat
= GdipGetDpiY(graphics
, &res
);
1659 expectf((REAL
)screenyres
, res
);
1661 stat
= GdipDeleteGraphics(graphics
);
1664 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1666 stat
= GdipGetDpiX(graphics
, &res
);
1668 expectf(screenxres
*2.0, res
);
1669 stat
= GdipGetDpiY(graphics
, &res
);
1671 expectf(screenyres
*3.0, res
);
1672 stat
= GdipDeleteGraphics(graphics
);
1675 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1679 static void test_createhbitmap(void)
1683 HBITMAP hbitmap
, oldhbitmap
;
1689 BitmapData lockeddata
;
1691 memset(bits
, 0x68, 640);
1694 stat
= GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB
, bits
, &bitmap
);
1697 /* test NULL values */
1698 stat
= GdipCreateHBITMAPFromBitmap(NULL
, &hbitmap
, 0);
1699 expect(InvalidParameter
, stat
);
1701 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, NULL
, 0);
1702 expect(InvalidParameter
, stat
);
1704 /* create HBITMAP */
1705 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1710 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1711 expect(sizeof(BITMAP
), ret
);
1713 expect(0, bm
.bmType
);
1714 expect(10, bm
.bmWidth
);
1715 expect(20, bm
.bmHeight
);
1716 expect(40, bm
.bmWidthBytes
);
1717 expect(1, bm
.bmPlanes
);
1718 expect(32, bm
.bmBitsPixel
);
1719 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1723 DWORD val
= *(DWORD
*)bm
.bmBits
;
1724 ok(val
== 0xff686868, "got %x, expected 0xff686868\n", val
);
1727 hdc
= CreateCompatibleDC(NULL
);
1729 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1730 pixel
= GetPixel(hdc
, 5, 5);
1731 SelectObject(hdc
, oldhbitmap
);
1735 expect(0x686868, pixel
);
1737 DeleteObject(hbitmap
);
1740 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1743 /* make (1,0) have no alpha and (2,0) a different blue value. */
1747 /* create alpha Bitmap */
1748 stat
= GdipCreateBitmapFromScan0(8, 20, 32, PixelFormat32bppARGB
, bits
, &bitmap
);
1751 /* create HBITMAP */
1752 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1757 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1758 expect(sizeof(BITMAP
), ret
);
1760 expect(0, bm
.bmType
);
1761 expect(8, bm
.bmWidth
);
1762 expect(20, bm
.bmHeight
);
1763 expect(32, bm
.bmWidthBytes
);
1764 expect(1, bm
.bmPlanes
);
1765 expect(32, bm
.bmBitsPixel
);
1766 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1770 DWORD val
= *(DWORD
*)bm
.bmBits
;
1771 ok(val
== 0x682a2a2a, "got %x, expected 0x682a2a2a\n", val
);
1772 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1773 ok(val
== 0x0, "got %x, expected 0x682a2a2a\n", val
);
1776 hdc
= CreateCompatibleDC(NULL
);
1778 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1779 pixel
= GetPixel(hdc
, 5, 5);
1780 expect(0x2a2a2a, pixel
);
1781 pixel
= GetPixel(hdc
, 1, 0);
1784 SelectObject(hdc
, oldhbitmap
);
1789 DeleteObject(hbitmap
);
1792 /* create HBITMAP with bkgnd colour */
1793 /* gdiplus.dll 5.1 is broken and only applies the blue value */
1794 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0xff00ff);
1799 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1800 expect(sizeof(BITMAP
), ret
);
1802 expect(0, bm
.bmType
);
1803 expect(8, bm
.bmWidth
);
1804 expect(20, bm
.bmHeight
);
1805 expect(32, bm
.bmWidthBytes
);
1806 expect(1, bm
.bmPlanes
);
1807 expect(32, bm
.bmBitsPixel
);
1808 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1812 DWORD val
= *(DWORD
*)bm
.bmBits
;
1813 ok(val
== 0x68c12ac1 || broken(val
== 0x682a2ac1), "got %x, expected 0x68c12ac1\n", val
);
1814 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1815 ok(val
== 0xff00ff || broken(val
== 0xff), "got %x, expected 0xff00ff\n", val
);
1818 hdc
= CreateCompatibleDC(NULL
);
1820 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1821 pixel
= GetPixel(hdc
, 5, 5);
1822 ok(pixel
== 0xc12ac1 || broken(pixel
== 0xc12a2a), "got %x, expected 0xc12ac1\n", pixel
);
1823 pixel
= GetPixel(hdc
, 1, 0);
1824 ok(pixel
== 0xff00ff || broken(pixel
== 0xff0000), "got %x, expected 0xff00ff\n", pixel
);
1825 pixel
= GetPixel(hdc
, 2, 0);
1826 ok(pixel
== 0xb12ac1 || broken(pixel
== 0xb12a2a), "got %x, expected 0xb12ac1\n", pixel
);
1828 SelectObject(hdc
, oldhbitmap
);
1830 DeleteObject(hbitmap
);
1833 /* create HBITMAP with bkgnd colour with alpha and show it behaves with no alpha. */
1834 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0x80ff00ff);
1839 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1840 expect(sizeof(BITMAP
), ret
);
1842 expect(0, bm
.bmType
);
1843 expect(8, bm
.bmWidth
);
1844 expect(20, bm
.bmHeight
);
1845 expect(32, bm
.bmWidthBytes
);
1846 expect(1, bm
.bmPlanes
);
1847 expect(32, bm
.bmBitsPixel
);
1848 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1852 DWORD val
= *(DWORD
*)bm
.bmBits
;
1853 ok(val
== 0x68c12ac1 || broken(val
== 0x682a2ac1), "got %x, expected 0x68c12ac1\n", val
);
1854 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1855 ok(val
== 0xff00ff || broken(val
== 0xff), "got %x, expected 0xff00ff\n", val
);
1858 hdc
= CreateCompatibleDC(NULL
);
1860 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1861 pixel
= GetPixel(hdc
, 5, 5);
1862 ok(pixel
== 0xc12ac1 || broken(pixel
== 0xc12a2a), "got %x, expected 0xc12ac1\n", pixel
);
1863 pixel
= GetPixel(hdc
, 1, 0);
1864 ok(pixel
== 0xff00ff || broken(pixel
== 0xff0000), "got %x, expected 0xff00ff\n", pixel
);
1865 pixel
= GetPixel(hdc
, 2, 0);
1866 ok(pixel
== 0xb12ac1 || broken(pixel
== 0xb12a2a), "got %x, expected 0xb12ac1\n", pixel
);
1868 SelectObject(hdc
, oldhbitmap
);
1870 DeleteObject(hbitmap
);
1873 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1876 /* create HBITMAP from locked data */
1877 memset(bits
, 0x68, 640);
1878 stat
= GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB
, bits
, &bitmap
);
1881 memset(&lockeddata
, 0, sizeof(lockeddata
));
1882 stat
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
| ImageLockModeWrite
,
1883 PixelFormat32bppRGB
, &lockeddata
);
1885 ((DWORD
*)lockeddata
.Scan0
)[0] = 0xff242424;
1886 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1888 stat
= GdipBitmapUnlockBits(bitmap
, &lockeddata
);
1890 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1893 hdc
= CreateCompatibleDC(NULL
);
1894 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1895 pixel
= GetPixel(hdc
, 0, 0);
1896 expect(0x686868, pixel
);
1897 SelectObject(hdc
, oldhbitmap
);
1901 static void test_getthumbnail(void)
1904 GpImage
*bitmap1
, *bitmap2
;
1907 stat
= GdipGetImageThumbnail(NULL
, 0, 0, &bitmap2
, NULL
, NULL
);
1908 expect(InvalidParameter
, stat
);
1910 stat
= GdipCreateBitmapFromScan0(128, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1913 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, NULL
, NULL
, NULL
);
1914 expect(InvalidParameter
, stat
);
1916 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, &bitmap2
, NULL
, NULL
);
1921 stat
= GdipGetImageWidth(bitmap2
, &width
);
1925 stat
= GdipGetImageHeight(bitmap2
, &height
);
1927 expect(120, height
);
1929 GdipDisposeImage(bitmap2
);
1932 GdipDisposeImage(bitmap1
);
1935 stat
= GdipCreateBitmapFromScan0(64, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1938 stat
= GdipGetImageThumbnail(bitmap1
, 32, 32, &bitmap2
, NULL
, NULL
);
1943 stat
= GdipGetImageWidth(bitmap2
, &width
);
1947 stat
= GdipGetImageHeight(bitmap2
, &height
);
1951 GdipDisposeImage(bitmap2
);
1954 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, &bitmap2
, NULL
, NULL
);
1959 stat
= GdipGetImageWidth(bitmap2
, &width
);
1963 stat
= GdipGetImageHeight(bitmap2
, &height
);
1965 expect(120, height
);
1967 GdipDisposeImage(bitmap2
);
1970 GdipDisposeImage(bitmap1
);
1973 static void test_getsetpixel(void)
1978 BYTE bits
[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00,
1979 0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00};
1981 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, bits
, &bitmap
);
1984 /* null parameters */
1985 stat
= GdipBitmapGetPixel(NULL
, 1, 1, &color
);
1986 expect(InvalidParameter
, stat
);
1988 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, NULL
);
1989 expect(InvalidParameter
, stat
);
1991 stat
= GdipBitmapSetPixel(NULL
, 1, 1, 0);
1992 expect(InvalidParameter
, stat
);
1995 stat
= GdipBitmapGetPixel(bitmap
, -1, 1, &color
);
1996 expect(InvalidParameter
, stat
);
1998 stat
= GdipBitmapSetPixel(bitmap
, -1, 1, 0);
1999 expect(InvalidParameter
, stat
);
2001 stat
= GdipBitmapGetPixel(bitmap
, 1, -1, &color
);
2002 ok(stat
== InvalidParameter
||
2003 broken(stat
== Ok
), /* Older gdiplus */
2004 "Expected InvalidParameter, got %.8x\n", stat
);
2006 if (0) /* crashes some gdiplus implementations */
2008 stat
= GdipBitmapSetPixel(bitmap
, 1, -1, 0);
2009 ok(stat
== InvalidParameter
||
2010 broken(stat
== Ok
), /* Older gdiplus */
2011 "Expected InvalidParameter, got %.8x\n", stat
);
2014 stat
= GdipBitmapGetPixel(bitmap
, 2, 1, &color
);
2015 expect(InvalidParameter
, stat
);
2017 stat
= GdipBitmapSetPixel(bitmap
, 2, 1, 0);
2018 expect(InvalidParameter
, stat
);
2020 stat
= GdipBitmapGetPixel(bitmap
, 1, 2, &color
);
2021 expect(InvalidParameter
, stat
);
2023 stat
= GdipBitmapSetPixel(bitmap
, 1, 2, 0);
2024 expect(InvalidParameter
, stat
);
2027 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
2029 expect(0xffffffff, color
);
2031 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2033 expect(0xff0000ff, color
);
2035 stat
= GdipBitmapSetPixel(bitmap
, 1, 1, 0xff676869);
2038 stat
= GdipBitmapSetPixel(bitmap
, 0, 0, 0xff474849);
2041 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
2043 expect(0xff676869, color
);
2045 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2047 expect(0xff474849, color
);
2049 stat
= GdipDisposeImage((GpImage
*)bitmap
);
2053 static void check_halftone_palette(ColorPalette
*palette
)
2055 static const BYTE halftone_values
[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
2058 for (i
=0; i
<palette
->Count
; i
++)
2060 ARGB expected
=0xff000000;
2063 if (i
&1) expected
|= 0x800000;
2064 if (i
&2) expected
|= 0x8000;
2065 if (i
&4) expected
|= 0x80;
2069 expected
= 0xffc0c0c0;
2073 if (i
&1) expected
|= 0xff0000;
2074 if (i
&2) expected
|= 0xff00;
2075 if (i
&4) expected
|= 0xff;
2079 expected
= 0x00000000;
2083 expected
|= halftone_values
[(i
-40)%6];
2084 expected
|= halftone_values
[((i
-40)/6)%6] << 8;
2085 expected
|= halftone_values
[((i
-40)/36)%6] << 16;
2087 ok(expected
== palette
->Entries
[i
], "Expected %.8x, got %.8x, i=%u/%u\n",
2088 expected
, palette
->Entries
[i
], i
, palette
->Count
);
2092 static void test_palette(void)
2098 ColorPalette
*palette
=(ColorPalette
*)buffer
;
2099 ARGB
*entries
= palette
->Entries
;
2102 /* test initial palette from non-indexed bitmap */
2103 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, NULL
, &bitmap
);
2106 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2108 expect(sizeof(UINT
)*2+sizeof(ARGB
), size
);
2110 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2112 expect(0, palette
->Count
);
2114 /* test setting palette on not-indexed bitmap */
2117 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2120 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2122 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2124 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2126 expect(3, palette
->Count
);
2128 GdipDisposeImage((GpImage
*)bitmap
);
2130 /* test initial palette on 1-bit bitmap */
2131 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat1bppIndexed
, NULL
, &bitmap
);
2134 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2136 expect(sizeof(UINT
)*2+sizeof(ARGB
)*2, size
);
2138 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2140 expect(PaletteFlagsGrayScale
, palette
->Flags
);
2141 expect(2, palette
->Count
);
2143 expect(0xff000000, entries
[0]);
2144 expect(0xffffffff, entries
[1]);
2146 /* test getting/setting pixels */
2147 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2149 expect(0xff000000, color
);
2151 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffffffff);
2153 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2157 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2159 expect(0xffffffff, color
);
2162 GdipDisposeImage((GpImage
*)bitmap
);
2164 /* test initial palette on 4-bit bitmap */
2165 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat4bppIndexed
, NULL
, &bitmap
);
2168 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2170 expect(sizeof(UINT
)*2+sizeof(ARGB
)*16, size
);
2172 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2174 expect(0, palette
->Flags
);
2175 expect(16, palette
->Count
);
2177 check_halftone_palette(palette
);
2179 /* test getting/setting pixels */
2180 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2182 expect(0xff000000, color
);
2184 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffff00ff);
2186 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2190 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2192 expect(0xffff00ff, color
);
2195 GdipDisposeImage((GpImage
*)bitmap
);
2197 /* test initial palette on 8-bit bitmap */
2198 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat8bppIndexed
, NULL
, &bitmap
);
2201 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2203 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2205 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2207 expect(PaletteFlagsHalftone
, palette
->Flags
);
2208 expect(256, palette
->Count
);
2210 check_halftone_palette(palette
);
2212 /* test getting/setting pixels */
2213 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2215 expect(0xff000000, color
);
2217 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffcccccc);
2219 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2223 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2225 expect(0xffcccccc, color
);
2228 /* test setting/getting a different palette */
2229 entries
[1] = 0xffcccccc;
2231 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2236 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2238 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2240 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2242 expect(PaletteFlagsHalftone
, palette
->Flags
);
2243 expect(256, palette
->Count
);
2244 expect(0xffcccccc, entries
[1]);
2246 /* test count < 256 */
2247 palette
->Flags
= 12345;
2250 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2254 entries
[3] = 0xdeadbeef;
2256 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2258 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2260 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2262 expect(12345, palette
->Flags
);
2263 expect(3, palette
->Count
);
2264 expect(0xffcccccc, entries
[1]);
2265 expect(0xdeadbeef, entries
[3]);
2267 /* test count > 256 */
2268 palette
->Count
= 257;
2270 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2271 ok(stat
== InvalidParameter
||
2272 broken(stat
== Ok
), /* Old gdiplus behavior */
2273 "Expected %.8x, got %.8x\n", InvalidParameter
, stat
);
2275 GdipDisposeImage((GpImage
*)bitmap
);
2278 static void test_colormatrix(void)
2281 ColorMatrix colormatrix
, graymatrix
;
2282 GpImageAttributes
*imageattr
;
2283 const ColorMatrix identity
= {{
2284 {1.0,0.0,0.0,0.0,0.0},
2285 {0.0,1.0,0.0,0.0,0.0},
2286 {0.0,0.0,1.0,0.0,0.0},
2287 {0.0,0.0,0.0,1.0,0.0},
2288 {0.0,0.0,0.0,0.0,1.0}}};
2289 const ColorMatrix double_red
= {{
2290 {2.0,0.0,0.0,0.0,0.0},
2291 {0.0,1.0,0.0,0.0,0.0},
2292 {0.0,0.0,1.0,0.0,0.0},
2293 {0.0,0.0,0.0,1.0,0.0},
2294 {0.0,0.0,0.0,0.0,1.0}}};
2295 const ColorMatrix asymmetric
= {{
2296 {0.0,1.0,0.0,0.0,0.0},
2297 {0.0,0.0,1.0,0.0,0.0},
2298 {0.0,0.0,0.0,1.0,0.0},
2299 {1.0,0.0,0.0,0.0,0.0},
2300 {0.0,0.0,0.0,0.0,1.0}}};
2301 GpBitmap
*bitmap1
, *bitmap2
;
2302 GpGraphics
*graphics
;
2305 colormatrix
= identity
;
2306 graymatrix
= identity
;
2308 stat
= GdipSetImageAttributesColorMatrix(NULL
, ColorAdjustTypeDefault
,
2309 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2310 expect(InvalidParameter
, stat
);
2312 stat
= GdipCreateImageAttributes(&imageattr
);
2315 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2316 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2319 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2320 TRUE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2321 expect(InvalidParameter
, stat
);
2323 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2324 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2327 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2328 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsSkipGrays
);
2331 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2332 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsAltGray
);
2333 expect(InvalidParameter
, stat
);
2335 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2336 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsAltGray
);
2339 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2340 TRUE
, &colormatrix
, &graymatrix
, 3);
2341 expect(InvalidParameter
, stat
);
2343 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeCount
,
2344 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2345 expect(InvalidParameter
, stat
);
2347 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeAny
,
2348 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2349 expect(InvalidParameter
, stat
);
2351 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2352 FALSE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2355 /* Drawing a bitmap transforms the colors */
2356 colormatrix
= double_red
;
2357 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2358 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2361 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
2364 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
2367 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff40ccee);
2370 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2373 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2374 UnitPixel
, imageattr
, NULL
, NULL
);
2377 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2379 expect(0xff80ccee, color
);
2381 colormatrix
= asymmetric
;
2382 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2383 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2386 stat
= GdipBitmapSetPixel(bitmap2
, 0, 0, 0);
2389 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2390 UnitPixel
, imageattr
, NULL
, NULL
);
2393 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2395 ok(color_match(0xeeff40cc, color
, 3), "expected 0xeeff40cc, got 0x%08x\n", color
);
2398 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeDefault
, FALSE
);
2401 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2402 UnitPixel
, imageattr
, NULL
, NULL
);
2405 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2407 ok(color_match(0xfefe40cc, color
, 3), "expected 0xfefe40cc, got 0x%08x\n", color
);
2409 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeDefault
, TRUE
);
2412 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2413 UnitPixel
, imageattr
, NULL
, NULL
);
2416 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2418 ok(color_match(0xff40ccee, color
, 3), "expected 0xff40ccee, got 0x%08x\n", color
);
2420 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2423 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeDefault
, FALSE
);
2426 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2427 UnitPixel
, imageattr
, NULL
, NULL
);
2430 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2432 ok(color_match(0xff40ccee, color
, 3), "expected 0xff40ccee, got 0x%08x\n", color
);
2434 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2435 UnitPixel
, imageattr
, NULL
, NULL
);
2438 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2440 ok(color_match(0xff40ccee, color
, 1), "Expected ff40ccee, got %.8x\n", color
);
2442 /* Disable adjustment, toggle NoOp */
2443 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2444 FALSE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2447 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeDefault
, FALSE
);
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(0xff40ccee, color
, 3), "expected 0xff40ccee, got 0x%08x\n", color
);
2458 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeDefault
, TRUE
);
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(0xff40ccee, color
, 3), "expected 0xff40ccee, got 0x%08x\n", color
);
2469 /* Reset with NoOp on, enable adjustment. */
2470 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2473 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2474 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2477 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2478 UnitPixel
, imageattr
, NULL
, NULL
);
2481 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2483 ok(color_match(0xfff24ace, color
, 3), "expected 0xfff24ace, got 0x%08x\n", color
);
2485 /* Now inhibit specific category. */
2486 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2489 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeBitmap
,
2490 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2493 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2494 UnitPixel
, imageattr
, NULL
, NULL
);
2497 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2499 ok(color_match(0xfffe41cc, color
, 3), "expected 0xfffe41cc, got 0x%08x\n", color
);
2501 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeBitmap
, TRUE
);
2504 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2505 UnitPixel
, imageattr
, NULL
, NULL
);
2508 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2510 ok(color_match(0xff40ccee, color
, 3), "expected 0xff40ccee, got 0x%08x\n", color
);
2512 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeBitmap
, FALSE
);
2515 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeDefault
, TRUE
);
2518 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2519 UnitPixel
, imageattr
, NULL
, NULL
);
2522 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2524 ok(color_match(0xfff24ace, color
, 3), "expected 0xfff24ace, got 0x%08x\n", color
);
2526 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeBitmap
);
2529 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2530 UnitPixel
, imageattr
, NULL
, NULL
);
2533 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2535 ok(color_match(0xff40ccee, color
, 3), "expected 0xff40ccee, got 0x%08x\n", color
);
2537 GdipDeleteGraphics(graphics
);
2538 GdipDisposeImage((GpImage
*)bitmap1
);
2539 GdipDisposeImage((GpImage
*)bitmap2
);
2540 GdipDisposeImageAttributes(imageattr
);
2543 static void test_gamma(void)
2546 GpImageAttributes
*imageattr
;
2547 GpBitmap
*bitmap1
, *bitmap2
;
2548 GpGraphics
*graphics
;
2551 stat
= GdipSetImageAttributesGamma(NULL
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2552 expect(InvalidParameter
, stat
);
2554 stat
= GdipCreateImageAttributes(&imageattr
);
2557 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2560 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeAny
, TRUE
, 1.0);
2561 expect(InvalidParameter
, stat
);
2563 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, -1.0);
2564 expect(InvalidParameter
, stat
);
2566 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.0);
2567 expect(InvalidParameter
, stat
);
2569 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.5);
2572 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0.0);
2575 /* Drawing a bitmap transforms the colors */
2576 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 3.0);
2579 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
2582 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
2585 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff80ffff);
2588 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2591 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2592 UnitPixel
, imageattr
, NULL
, NULL
);
2595 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2597 ok(color_match(0xff20ffff, color
, 1), "Expected ff20ffff, got %.8x\n", color
);
2599 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2602 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2603 UnitPixel
, imageattr
, NULL
, NULL
);
2606 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2608 ok(color_match(0xff80ffff, color
, 1), "Expected ff80ffff, got %.8x\n", color
);
2610 GdipDeleteGraphics(graphics
);
2611 GdipDisposeImage((GpImage
*)bitmap1
);
2612 GdipDisposeImage((GpImage
*)bitmap2
);
2613 GdipDisposeImageAttributes(imageattr
);
2616 /* 1x1 pixel gif, 2 frames; first frame is white, second is black */
2617 static const unsigned char gifanimation
[72] = {
2618 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
2619 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0xf9,0x04,0x00,0x0a,0x00,0xff,
2620 0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x4c,0x01,0x00,
2621 0x21,0xf9,0x04,0x01,0x0a,0x00,0x01,0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,
2622 0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
2625 /* Generated with ImageMagick:
2626 * convert -transparent black -delay 100 -size 8x2 xc:black \
2627 * -dispose none -page +0+0 -size 2x2 xc:red \
2628 * -dispose background -page +2+0 -size 2x2 xc:blue \
2629 * -dispose previous -page +4+0 -size 2x2 xc:green \
2630 * -dispose undefined -page +6+0 -size 2x2 xc:gray \
2633 static const unsigned char gifanimation2
[] = {
2634 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x08, 0x00,
2635 0x02, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
2636 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x64,
2637 0x00, 0x00, 0x00, 0x21, 0xff, 0x0b, 0x4e, 0x45,
2638 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e,
2639 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00,
2640 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
2641 0x02, 0x04, 0x84, 0x8f, 0x09, 0x05, 0x00, 0x21,
2642 0xf9, 0x04, 0x04, 0x64, 0x00, 0x00, 0x00, 0x2c,
2643 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2644 0x81, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
2645 0x00, 0x00, 0xff, 0x00, 0x00, 0x02, 0x03, 0x44,
2646 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x08, 0x64,
2647 0x00, 0x00, 0x00, 0x2c, 0x02, 0x00, 0x00, 0x00,
2648 0x02, 0x00, 0x02, 0x00, 0x81, 0x00, 0x00, 0xff,
2649 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
2650 0xff, 0x02, 0x03, 0x44, 0x34, 0x05, 0x00, 0x21,
2651 0xf9, 0x04, 0x0c, 0x64, 0x00, 0x00, 0x00, 0x2c,
2652 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2653 0x81, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00,
2654 0x80, 0x00, 0x00, 0x80, 0x00, 0x02, 0x03, 0x44,
2655 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x64,
2656 0x00, 0x00, 0x00, 0x2c, 0x06, 0x00, 0x00, 0x00,
2657 0x02, 0x00, 0x02, 0x00, 0x80, 0x7e, 0x7e, 0x7e,
2658 0x00, 0x00, 0x00, 0x02, 0x02, 0x84, 0x51, 0x00,
2662 static ARGB gifanimation2_pixels
[5][4] = {
2664 {0xffff0000, 0, 0, 0},
2665 {0xffff0000, 0xff0000ff, 0, 0},
2666 {0xffff0000, 0, 0xff008000, 0},
2667 {0xffff0000, 0, 0, 0xff7e7e7e}
2670 static void test_multiframegif(void)
2681 PixelFormat pixel_format
;
2682 INT palette_size
, i
, j
;
2683 char palette_buf
[256];
2684 ColorPalette
*palette
;
2685 ARGB
*palette_entries
;
2687 /* Test frame functions with an animated GIF */
2688 hglob
= GlobalAlloc (0, sizeof(gifanimation
));
2689 data
= GlobalLock (hglob
);
2690 memcpy(data
, gifanimation
, sizeof(gifanimation
));
2691 GlobalUnlock(hglob
);
2693 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2694 ok(hres
== S_OK
, "Failed to create a stream\n");
2695 if(hres
!= S_OK
) return;
2697 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2698 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2700 IStream_Release(stream
);
2704 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2706 expect(PixelFormat32bppARGB
, pixel_format
);
2708 stat
= GdipGetImagePaletteSize((GpImage
*)bmp
, &palette_size
);
2710 ok(palette_size
== sizeof(ColorPalette
) ||
2711 broken(palette_size
== sizeof(ColorPalette
)+sizeof(ARGB
[3])),
2712 "palette_size = %d\n", palette_size
);
2714 /* Bitmap starts at frame 0 */
2716 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2718 expect(0xffffffff, color
);
2720 /* Check that we get correct metadata */
2721 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2725 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2727 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2730 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2734 /* SelectActiveFrame overwrites our current data */
2735 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2739 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2741 expect(0xff000000, color
);
2743 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2747 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2749 expect(0xffffffff, color
);
2751 /* Write over the image data */
2752 stat
= GdipBitmapSetPixel(bmp
, 0, 0, 0xff000000);
2755 /* Switching to the same frame does not overwrite our changes */
2756 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2759 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2761 expect(0xff000000, color
);
2763 /* But switching to another frame and back does */
2764 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2767 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2770 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2772 expect(0xffffffff, color
);
2774 /* rotate/flip discards the information about other frames */
2775 stat
= GdipImageRotateFlip((GpImage
*)bmp
, Rotate90FlipNone
);
2779 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2783 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bmp
, __LINE__
, FALSE
);
2785 GdipDisposeImage((GpImage
*)bmp
);
2786 IStream_Release(stream
);
2788 /* Test with a non-animated gif */
2789 hglob
= GlobalAlloc (0, sizeof(gifimage
));
2790 data
= GlobalLock (hglob
);
2791 memcpy(data
, gifimage
, sizeof(gifimage
));
2792 GlobalUnlock(hglob
);
2794 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2795 ok(hres
== S_OK
, "Failed to create a stream\n");
2796 if(hres
!= S_OK
) return;
2798 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2799 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2801 IStream_Release(stream
);
2805 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2807 expect(PixelFormat8bppIndexed
, pixel_format
);
2809 /* Check metadata */
2810 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2814 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2816 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2819 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2823 GdipDisposeImage((GpImage
*)bmp
);
2824 IStream_Release(stream
);
2826 /* Test with a non-animated transparent gif */
2827 hglob
= GlobalAlloc (0, sizeof(transparentgif
));
2828 data
= GlobalLock (hglob
);
2829 memcpy(data
, transparentgif
, sizeof(transparentgif
));
2830 GlobalUnlock(hglob
);
2832 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2833 ok(hres
== S_OK
, "Failed to create a stream\n");
2835 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2836 IStream_Release(stream
);
2837 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2839 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2841 expect(PixelFormat8bppIndexed
, pixel_format
);
2843 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2847 stat
= GdipGetImagePaletteSize((GpImage
*)bmp
, &palette_size
);
2849 ok(palette_size
== sizeof(ColorPalette
)+sizeof(ARGB
),
2850 "palette_size = %d\n", palette_size
);
2852 memset(palette_buf
, 0xfe, sizeof(palette_buf
));
2853 palette
= (ColorPalette
*)palette_buf
;
2854 stat
= GdipGetImagePalette((GpImage
*)bmp
, palette
,
2855 sizeof(ColorPalette
)+sizeof(ARGB
));
2856 palette_entries
= palette
->Entries
;
2858 expect(PaletteFlagsHasAlpha
, palette
->Flags
);
2859 expect(2, palette
->Count
);
2860 expect(0, palette_entries
[0]);
2861 expect(0xff000000, palette_entries
[1]);
2864 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2868 GdipDisposeImage((GpImage
*)bmp
);
2870 /* Test frame dispose methods */
2871 hglob
= GlobalAlloc (0, sizeof(gifanimation2
));
2872 data
= GlobalLock (hglob
);
2873 memcpy(data
, gifanimation2
, sizeof(gifanimation2
));
2874 GlobalUnlock(hglob
);
2876 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2877 ok(hres
== S_OK
, "Failed to create a stream\n");
2879 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2880 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2881 IStream_Release(stream
);
2883 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2885 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2887 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2891 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2895 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 3);
2897 stat
= GdipBitmapGetPixel(bmp
, 2, 0, &color
);
2899 ok(color
==0 || broken(color
==0xff0000ff), "color = %x\n", color
);
2901 win_skip("broken animated gif support\n");
2902 GdipDisposeImage((GpImage
*)bmp
);
2906 for(i
=0; i
<6; i
++) {
2907 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, i
%5);
2910 for(j
=0; j
<4; j
++) {
2911 stat
= GdipBitmapGetPixel(bmp
, j
*2, 0, &color
);
2913 ok(gifanimation2_pixels
[i
%5][j
] == color
, "at %d,%d got %x, expected %x\n", i
, j
, color
, gifanimation2_pixels
[i
%5][j
]);
2917 GdipDisposeImage((GpImage
*)bmp
);
2920 static void test_rotateflip(void)
2925 static const BYTE orig_bits
[24] = {
2926 0,0,0xff, 0,0xff,0, 0xff,0,0, 23,23,23,
2927 0xff,0xff,0, 0xff,0,0xff, 0,0xff,0xff, 23,23,23};
2931 memcpy(bits
, orig_bits
, sizeof(bits
));
2932 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2935 stat
= GdipImageRotateFlip(bitmap
, Rotate90FlipNone
);
2938 stat
= GdipGetImageWidth(bitmap
, &width
);
2940 stat
= GdipGetImageHeight(bitmap
, &height
);
2945 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2947 expect(0xff00ffff, color
);
2949 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 0, &color
);
2951 expect(0xffff0000, color
);
2953 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 2, &color
);
2955 expect(0xffffff00, color
);
2957 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 2, &color
);
2959 expect(0xff0000ff, color
);
2963 expect(0xff, bits
[2]);
2965 GdipDisposeImage(bitmap
);
2967 memcpy(bits
, orig_bits
, sizeof(bits
));
2968 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2971 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipX
);
2974 stat
= GdipGetImageWidth(bitmap
, &width
);
2976 stat
= GdipGetImageHeight(bitmap
, &height
);
2981 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2983 expect(0xff0000ff, color
);
2985 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
2987 expect(0xffff0000, color
);
2989 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
2991 expect(0xffffff00, color
);
2993 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
2995 expect(0xff00ffff, color
);
2999 expect(0xff, bits
[2]);
3001 GdipDisposeImage(bitmap
);
3003 memcpy(bits
, orig_bits
, sizeof(bits
));
3004 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
3007 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipY
);
3010 stat
= GdipGetImageWidth(bitmap
, &width
);
3012 stat
= GdipGetImageHeight(bitmap
, &height
);
3017 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
3019 expect(0xff00ffff, color
);
3021 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
3023 expect(0xffffff00, color
);
3025 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
3027 expect(0xffff0000, color
);
3029 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
3031 expect(0xff0000ff, color
);
3035 expect(0xff, bits
[2]);
3037 GdipDisposeImage(bitmap
);
3040 static void test_remaptable(void)
3043 GpImageAttributes
*imageattr
;
3044 GpBitmap
*bitmap1
, *bitmap2
;
3045 GpGraphics
*graphics
;
3049 map
= GdipAlloc(sizeof(ColorMap
));
3051 map
->oldColor
.Argb
= 0xff00ff00;
3052 map
->newColor
.Argb
= 0xffff00ff;
3054 stat
= GdipSetImageAttributesRemapTable(NULL
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
3055 expect(InvalidParameter
, stat
);
3057 stat
= GdipCreateImageAttributes(&imageattr
);
3060 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, NULL
);
3061 expect(InvalidParameter
, stat
);
3063 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeCount
, TRUE
, 1, map
);
3064 expect(InvalidParameter
, stat
);
3066 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeAny
, TRUE
, 1, map
);
3067 expect(InvalidParameter
, stat
);
3069 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0, map
);
3070 expect(InvalidParameter
, stat
);
3072 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0, NULL
);
3075 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
3078 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
3081 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
3084 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff00ff00);
3087 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
3090 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
3091 UnitPixel
, imageattr
, NULL
, NULL
);
3094 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
3096 ok(color_match(0xffff00ff, color
, 1), "Expected ffff00ff, got %.8x\n", color
);
3098 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
3101 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
3102 UnitPixel
, imageattr
, NULL
, NULL
);
3105 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
3107 ok(color_match(0xff00ff00, color
, 1), "Expected ff00ff00, got %.8x\n", color
);
3109 GdipDeleteGraphics(graphics
);
3110 GdipDisposeImage((GpImage
*)bitmap1
);
3111 GdipDisposeImage((GpImage
*)bitmap2
);
3112 GdipDisposeImageAttributes(imageattr
);
3116 static void test_colorkey(void)
3119 GpImageAttributes
*imageattr
;
3120 GpBitmap
*bitmap1
, *bitmap2
;
3121 GpGraphics
*graphics
;
3124 stat
= GdipSetImageAttributesColorKeys(NULL
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
3125 expect(InvalidParameter
, stat
);
3127 stat
= GdipCreateImageAttributes(&imageattr
);
3130 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeCount
, TRUE
, 0xff405060, 0xff708090);
3131 expect(InvalidParameter
, stat
);
3133 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeAny
, TRUE
, 0xff405060, 0xff708090);
3134 expect(InvalidParameter
, stat
);
3136 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
3139 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
3142 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
3145 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0x20405060);
3148 stat
= GdipBitmapSetPixel(bitmap1
, 0, 1, 0x40506070);
3151 stat
= GdipBitmapSetPixel(bitmap1
, 1, 0, 0x60708090);
3154 stat
= GdipBitmapSetPixel(bitmap1
, 1, 1, 0xffffffff);
3157 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
3160 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
3161 UnitPixel
, imageattr
, NULL
, NULL
);
3164 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
3166 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
3168 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
3170 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
3172 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
3174 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
3176 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
3178 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
3180 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
3183 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
3184 UnitPixel
, imageattr
, NULL
, NULL
);
3187 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
3189 ok(color_match(0x20405060, color
, 1), "Expected 20405060, got %.8x\n", color
);
3191 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
3193 ok(color_match(0x40506070, color
, 1), "Expected 40506070, got %.8x\n", color
);
3195 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
3197 ok(color_match(0x60708090, color
, 1), "Expected 60708090, got %.8x\n", color
);
3199 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
3201 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
3204 GdipDeleteGraphics(graphics
);
3205 GdipDisposeImage((GpImage
*)bitmap1
);
3206 GdipDisposeImage((GpImage
*)bitmap2
);
3207 GdipDisposeImageAttributes(imageattr
);
3210 static void test_dispose(void)
3214 char invalid_image
[256];
3216 stat
= GdipDisposeImage(NULL
);
3217 expect(InvalidParameter
, stat
);
3219 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, (GpBitmap
**)&image
);
3222 stat
= GdipDisposeImage(image
);
3225 stat
= GdipDisposeImage(image
);
3226 expect(ObjectBusy
, stat
);
3228 memset(invalid_image
, 0, 256);
3229 stat
= GdipDisposeImage((GpImage
*)invalid_image
);
3230 expect(ObjectBusy
, stat
);
3233 static LONG
obj_refcount(void *obj
)
3235 IUnknown_AddRef((IUnknown
*)obj
);
3236 return IUnknown_Release((IUnknown
*)obj
);
3239 static GpImage
*load_image(const BYTE
*image_data
, UINT image_size
, BOOL valid_data
, BOOL todo_load
)
3246 GpImage
*image
= NULL
, *clone
;
3247 ImageType image_type
;
3248 LONG refcount
, old_refcount
;
3250 hmem
= GlobalAlloc(0, image_size
);
3251 data
= GlobalLock(hmem
);
3252 memcpy(data
, image_data
, image_size
);
3255 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
3256 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
3257 if (hr
!= S_OK
) return NULL
;
3259 refcount
= obj_refcount(stream
);
3260 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3262 status
= GdipLoadImageFromStream(stream
, &image
);
3263 todo_wine_if(todo_load
)
3265 ok(status
== Ok
|| broken(status
== InvalidParameter
), /* XP */
3266 "GdipLoadImageFromStream error %d\n", status
);
3268 ok(status
!= Ok
, "GdipLoadImageFromStream should fail\n");
3271 IStream_Release(stream
);
3275 status
= GdipGetImageType(image
, &image_type
);
3276 ok(status
== Ok
, "GdipGetImageType error %d\n", status
);
3278 refcount
= obj_refcount(stream
);
3279 if (image_type
== ImageTypeBitmap
)
3280 ok(refcount
> 1, "expected stream refcount > 1, got %d\n", refcount
);
3282 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3283 old_refcount
= refcount
;
3285 status
= GdipCloneImage(image
, &clone
);
3286 ok(status
== Ok
, "GdipCloneImage error %d\n", status
);
3287 refcount
= obj_refcount(stream
);
3288 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3289 status
= GdipDisposeImage(clone
);
3290 ok(status
== Ok
, "GdipDisposeImage error %d\n", status
);
3291 refcount
= obj_refcount(stream
);
3292 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3294 refcount
= IStream_Release(stream
);
3295 if (image_type
== ImageTypeBitmap
)
3296 ok(refcount
>= 1, "expected stream refcount != 0\n");
3298 ok(refcount
== 0, "expected stream refcount 0, got %d\n", refcount
);
3303 static void test_image_properties(void)
3305 static const struct test_data
3307 const BYTE
*image_data
;
3309 ImageType image_type
;
3311 UINT prop_count2
; /* if win7 behaves differently */
3312 /* 1st property attributes */
3314 UINT prop_size2
; /* if win7 behaves differently */
3316 UINT prop_id2
; /* if win7 behaves differently */
3320 { pngimage
, sizeof(pngimage
), ImageTypeBitmap
, 4, ~0, 1, 20, 0x5110, 0x132 },
3321 { jpgimage
, sizeof(jpgimage
), ImageTypeBitmap
, 2, ~0, 128, 0, 0x5090, 0x5091 },
3322 { tiffimage
, sizeof(tiffimage
), ImageTypeBitmap
, 16, 0, 4, 0, 0xfe, 0 },
3323 { bmpimage
, sizeof(bmpimage
), ImageTypeBitmap
, 0, 0, 0, 0, 0, 0 },
3324 { wmfimage
, sizeof(wmfimage
), ImageTypeMetafile
, 0, 0, 0, 0, 0, 0 }
3328 UINT prop_count
, prop_size
, i
;
3329 PROPID prop_id
[16] = { 0 };
3330 ImageType image_type
;
3337 for (i
= 0; i
< ARRAY_SIZE(td
); i
++)
3339 image
= load_image(td
[i
].image_data
, td
[i
].image_size
, TRUE
, FALSE
);
3342 trace("%u: failed to load image data\n", i
);
3346 status
= GdipGetImageType(image
, &image_type
);
3347 ok(status
== Ok
, "%u: GdipGetImageType error %d\n", i
, status
);
3348 ok(td
[i
].image_type
== image_type
, "%u: expected image_type %d, got %d\n",
3349 i
, td
[i
].image_type
, image_type
);
3351 status
= GdipGetPropertyCount(image
, &prop_count
);
3352 ok(status
== Ok
, "%u: GdipGetPropertyCount error %d\n", i
, status
);
3353 todo_wine_if(td
[i
].image_data
== pngimage
|| td
[i
].image_data
== jpgimage
)
3354 ok(td
[i
].prop_count
== prop_count
|| td
[i
].prop_count2
== prop_count
,
3355 " %u: expected property count %u or %u, got %u\n",
3356 i
, td
[i
].prop_count
, td
[i
].prop_count2
, prop_count
);
3358 status
= GdipGetPropertyItemSize(NULL
, 0, &prop_size
);
3359 expect(InvalidParameter
, status
);
3360 status
= GdipGetPropertyItemSize(image
, 0, NULL
);
3361 expect(InvalidParameter
, status
);
3362 status
= GdipGetPropertyItemSize(image
, 0, &prop_size
);
3363 if (image_type
== ImageTypeMetafile
)
3364 expect(NotImplemented
, status
);
3366 expect(PropertyNotFound
, status
);
3368 status
= GdipGetPropertyItem(NULL
, 0, 0, &item
.data
);
3369 expect(InvalidParameter
, status
);
3370 status
= GdipGetPropertyItem(image
, 0, 0, NULL
);
3371 expect(InvalidParameter
, status
);
3372 status
= GdipGetPropertyItem(image
, 0, 0, &item
.data
);
3373 if (image_type
== ImageTypeMetafile
)
3374 expect(NotImplemented
, status
);
3376 expect(PropertyNotFound
, status
);
3378 /* FIXME: remove once Wine is fixed */
3379 if (td
[i
].prop_count
!= prop_count
)
3381 GdipDisposeImage(image
);
3385 status
= GdipGetPropertyIdList(NULL
, prop_count
, prop_id
);
3386 expect(InvalidParameter
, status
);
3387 status
= GdipGetPropertyIdList(image
, prop_count
, NULL
);
3388 expect(InvalidParameter
, status
);
3389 status
= GdipGetPropertyIdList(image
, 0, prop_id
);
3390 if (image_type
== ImageTypeMetafile
)
3391 expect(NotImplemented
, status
);
3392 else if (prop_count
== 0)
3395 expect(InvalidParameter
, status
);
3396 status
= GdipGetPropertyIdList(image
, prop_count
- 1, prop_id
);
3397 if (image_type
== ImageTypeMetafile
)
3398 expect(NotImplemented
, status
);
3400 expect(InvalidParameter
, status
);
3401 status
= GdipGetPropertyIdList(image
, prop_count
+ 1, prop_id
);
3402 if (image_type
== ImageTypeMetafile
)
3403 expect(NotImplemented
, status
);
3405 expect(InvalidParameter
, status
);
3406 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3407 if (image_type
== ImageTypeMetafile
)
3408 expect(NotImplemented
, status
);
3412 if (prop_count
!= 0)
3413 ok(td
[i
].prop_id
== prop_id
[0] || td
[i
].prop_id2
== prop_id
[0],
3414 " %u: expected property id %#x or %#x, got %#x\n",
3415 i
, td
[i
].prop_id
, td
[i
].prop_id2
, prop_id
[0]);
3420 status
= GdipGetPropertyItemSize(image
, prop_id
[0], &prop_size
);
3421 if (prop_count
== 0)
3422 expect(PropertyNotFound
, status
);
3427 assert(sizeof(item
) >= prop_size
);
3428 ok(prop_size
> sizeof(PropertyItem
), "%u: got too small prop_size %u\n",
3430 ok(td
[i
].prop_size
+ sizeof(PropertyItem
) == prop_size
||
3431 td
[i
].prop_size2
+ sizeof(PropertyItem
) == prop_size
,
3432 " %u: expected property size %u or %u, got %u\n",
3433 i
, td
[i
].prop_size
, td
[i
].prop_size2
, prop_size
);
3435 status
= GdipGetPropertyItem(image
, prop_id
[0], 0, &item
.data
);
3436 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3437 "%u: expected InvalidParameter, got %d\n", i
, status
);
3438 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
- 1, &item
.data
);
3439 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3440 "%u: expected InvalidParameter, got %d\n", i
, status
);
3441 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
+ 1, &item
.data
);
3442 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3443 "%u: expected InvalidParameter, got %d\n", i
, status
);
3444 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
, &item
.data
);
3446 ok(prop_id
[0] == item
.data
.id
,
3447 "%u: expected property id %#x, got %#x\n", i
, prop_id
[0], item
.data
.id
);
3451 GdipDisposeImage(image
);
3459 #define IFD_RATIONAL 5
3461 #define IFD_UNDEFINED 7
3462 #define IFD_SSHORT 8
3464 #define IFD_SRATIONAL 10
3465 #define IFD_FLOAT 11
3466 #define IFD_DOUBLE 12
3468 #ifndef PropertyTagTypeSByte
3469 #define PropertyTagTypeSByte 6
3470 #define PropertyTagTypeSShort 8
3471 #define PropertyTagTypeFloat 11
3472 #define PropertyTagTypeDouble 12
3475 static UINT
documented_type(UINT type
)
3479 case PropertyTagTypeSByte
: return PropertyTagTypeByte
;
3480 case PropertyTagTypeSShort
: return PropertyTagTypeShort
;
3481 case PropertyTagTypeFloat
: return PropertyTagTypeUndefined
;
3482 case PropertyTagTypeDouble
: return PropertyTagTypeUndefined
;
3483 default: return type
;
3487 #include "pshpack2.h"
3502 static const struct tiff_data
3507 USHORT number_of_entries
;
3508 struct IFD_entry entry
[40];
3510 struct IFD_rational xres
;
3512 struct IFD_rational srational_val
;
3517 struct IFD_rational rational
[3];
3521 #ifdef WORDS_BIGENDIAN
3527 FIELD_OFFSET(struct tiff_data
, number_of_entries
),
3530 { 0xff, IFD_SHORT
, 1, 0 }, /* SUBFILETYPE */
3531 { 0x100, IFD_LONG
, 1, 1 }, /* IMAGEWIDTH */
3532 { 0x101, IFD_LONG
, 1, 1 }, /* IMAGELENGTH */
3533 { 0x102, IFD_SHORT
, 1, 1 }, /* BITSPERSAMPLE */
3534 { 0x103, IFD_SHORT
, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
3535 { 0x106, IFD_SHORT
, 1, 1 }, /* PHOTOMETRIC */
3536 { 0x111, IFD_LONG
, 1, FIELD_OFFSET(struct tiff_data
, pixel_data
) }, /* STRIPOFFSETS */
3537 { 0x115, IFD_SHORT
, 1, 1 }, /* SAMPLESPERPIXEL */
3538 { 0x116, IFD_LONG
, 1, 1 }, /* ROWSPERSTRIP */
3539 { 0x117, IFD_LONG
, 1, 1 }, /* STRIPBYTECOUNT */
3540 { 0x11a, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3541 { 0x11b, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3542 { 0x128, IFD_SHORT
, 1, 2 }, /* RESOLUTIONUNIT */
3543 { 0xf001, IFD_BYTE
, 1, 0x11223344 },
3544 { 0xf002, IFD_BYTE
, 4, 0x11223344 },
3545 { 0xf003, IFD_SBYTE
, 1, 0x11223344 },
3546 { 0xf004, IFD_SSHORT
, 1, 0x11223344 },
3547 { 0xf005, IFD_SSHORT
, 2, 0x11223344 },
3548 { 0xf006, IFD_SLONG
, 1, 0x11223344 },
3549 { 0xf007, IFD_FLOAT
, 1, 0x11223344 },
3550 { 0xf008, IFD_DOUBLE
, 1, FIELD_OFFSET(struct tiff_data
, double_val
) },
3551 { 0xf009, IFD_SRATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, srational_val
) },
3552 { 0xf00a, IFD_BYTE
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3553 { 0xf00b, IFD_SSHORT
, 4, FIELD_OFFSET(struct tiff_data
, short_val
) },
3554 { 0xf00c, IFD_SLONG
, 2, FIELD_OFFSET(struct tiff_data
, long_val
) },
3555 { 0xf00e, IFD_ASCII
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3556 { 0xf00f, IFD_ASCII
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3557 { 0xf010, IFD_UNDEFINED
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3558 { 0xf011, IFD_UNDEFINED
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3559 /* Some gdiplus versions ignore these fields.
3560 { 0xf012, IFD_BYTE, 0, 0x11223344 },
3561 { 0xf013, IFD_SHORT, 0, 0x11223344 },
3562 { 0xf014, IFD_LONG, 0, 0x11223344 },
3563 { 0xf015, IFD_FLOAT, 0, 0x11223344 },*/
3564 { 0xf016, IFD_SRATIONAL
, 3, FIELD_OFFSET(struct tiff_data
, rational
) },
3565 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3566 { 0xf017, IFD_FLOAT
, 2, FIELD_OFFSET(struct tiff_data
, float_val
) },
3570 1234567890.0987654321,
3571 { 0x1a2b3c4d, 0x5a6b7c8d },
3573 { 0x0101, 0x0202, 0x0303, 0x0404 },
3574 { 0x11223344, 0x55667788 },
3575 { (FLOAT
)1234.5678, (FLOAT
)8765.4321 },
3576 { { 0x01020304, 0x05060708 }, { 0x10203040, 0x50607080 }, { 0x11223344, 0x55667788 } },
3577 { 0x11, 0x22, 0x33, 0 }
3579 #include "poppack.h"
3581 static void test_tiff_properties(void)
3583 static const struct test_data
3585 ULONG type
, id
, length
;
3586 const BYTE value
[24];
3589 { PropertyTagTypeShort
, 0xff, 2, { 0 } },
3590 { PropertyTagTypeLong
, 0x100, 4, { 1 } },
3591 { PropertyTagTypeLong
, 0x101, 4, { 1 } },
3592 { PropertyTagTypeShort
, 0x102, 2, { 1 } },
3593 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3594 { PropertyTagTypeShort
, 0x106, 2, { 1 } },
3595 { PropertyTagTypeLong
, 0x111, 4, { 0x44,0x02 } },
3596 { PropertyTagTypeShort
, 0x115, 2, { 1 } },
3597 { PropertyTagTypeLong
, 0x116, 4, { 1 } },
3598 { PropertyTagTypeLong
, 0x117, 4, { 1 } },
3599 { PropertyTagTypeRational
, 0x11a, 8, { 0x84,0x03,0,0,0x03 } },
3600 { PropertyTagTypeRational
, 0x11b, 8, { 0x84,0x03,0,0,0x03 } },
3601 { PropertyTagTypeShort
, 0x128, 2, { 2 } },
3602 { PropertyTagTypeByte
, 0xf001, 1, { 0x44 } },
3603 { PropertyTagTypeByte
, 0xf002, 4, { 0x44,0x33,0x22,0x11 } },
3604 { PropertyTagTypeSByte
, 0xf003, 1, { 0x44 } },
3605 { PropertyTagTypeSShort
, 0xf004, 2, { 0x44,0x33 } },
3606 { PropertyTagTypeSShort
, 0xf005, 4, { 0x44,0x33,0x22,0x11 } },
3607 { PropertyTagTypeSLONG
, 0xf006, 4, { 0x44,0x33,0x22,0x11 } },
3608 { PropertyTagTypeFloat
, 0xf007, 4, { 0x44,0x33,0x22,0x11 } },
3609 { PropertyTagTypeDouble
, 0xf008, 8, { 0x2c,0x52,0x86,0xb4,0x80,0x65,0xd2,0x41 } },
3610 { PropertyTagTypeSRational
, 0xf009, 8, { 0x4d, 0x3c, 0x2b, 0x1a, 0x8d, 0x7c, 0x6b, 0x5a } },
3611 { PropertyTagTypeByte
, 0xf00a, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3612 { PropertyTagTypeSShort
, 0xf00b, 8, { 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04 } },
3613 { PropertyTagTypeSLONG
, 0xf00c, 8, { 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3614 { PropertyTagTypeASCII
, 0xf00e, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3615 { PropertyTagTypeASCII
, 0xf00f, 5, { 'a','b','c','d' } },
3616 { PropertyTagTypeUndefined
, 0xf010, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3617 { PropertyTagTypeUndefined
, 0xf011, 4, { 'a','b','c','d' } },
3618 { PropertyTagTypeSRational
, 0xf016, 24,
3619 { 0x04,0x03,0x02,0x01,0x08,0x07,0x06,0x05,
3620 0x40,0x30,0x20,0x10,0x80,0x70,0x60,0x50,
3621 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3622 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3623 { PropertyTagTypeFloat
, 0xf017, 8, { 0x2b,0x52,0x9a,0x44,0xba,0xf5,0x08,0x46 } },
3628 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3630 PropertyItem
*prop_item
;
3632 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
), TRUE
, FALSE
);
3635 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3639 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3641 expect(1, dim_count
);
3643 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3645 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3647 frame_count
= 0xdeadbeef;
3648 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3650 expect(1, frame_count
);
3652 prop_count
= 0xdeadbeef;
3653 status
= GdipGetPropertyCount(image
, &prop_count
);
3655 ok(prop_count
== ARRAY_SIZE(td
) ||
3656 broken(prop_count
== ARRAY_SIZE(td
) - 1) /* Win7 SP0 */,
3657 "expected property count %u, got %u\n", (UINT
) ARRAY_SIZE(td
), prop_count
);
3659 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3661 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3664 for (i
= 0; i
< prop_count
; i
++)
3666 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &prop_size
);
3668 if (status
!= Ok
) break;
3669 ok(prop_size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, prop_size
);
3671 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, prop_size
);
3672 status
= GdipGetPropertyItem(image
, prop_id
[i
], prop_size
, prop_item
);
3674 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3675 ok(td
[i
].type
== prop_item
->type
||
3676 /* Win7 stopped using proper but not documented types, and it
3677 looks broken since TypeFloat and TypeDouble now reported as
3678 TypeUndefined, and signed types reported as unsigned. */
3679 broken(prop_item
->type
== documented_type(td
[i
].type
)),
3680 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3681 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3682 prop_size
-= sizeof(*prop_item
);
3683 ok(prop_item
->length
== prop_size
, "%u: expected length %u, got %u\n", i
, prop_size
, prop_item
->length
);
3684 ok(td
[i
].length
== prop_item
->length
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_item
->length
+1) /* XP */,
3685 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3686 ok(td
[i
].length
== prop_size
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_size
+1) /* XP */,
3687 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_size
);
3688 if (td
[i
].length
== prop_item
->length
)
3690 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3691 ok(match
|| broken(td
[i
].length
<= 4 && !match
), "%u: data mismatch\n", i
);
3695 BYTE
*data
= prop_item
->value
;
3696 trace("id %#x:", prop_item
->id
);
3697 for (j
= 0; j
< prop_item
->length
; j
++)
3698 trace(" %02x", data
[j
]);
3702 HeapFree(GetProcessHeap(), 0, prop_item
);
3705 HeapFree(GetProcessHeap(), 0, prop_id
);
3707 GdipDisposeImage(image
);
3710 static void test_GdipGetAllPropertyItems(void)
3712 static const struct test_data
3714 ULONG type
, id
, length
;
3718 { PropertyTagTypeLong
, 0xfe, 4, { 0 } },
3719 { PropertyTagTypeShort
, 0x100, 2, { 1 } },
3720 { PropertyTagTypeShort
, 0x101, 2, { 1 } },
3721 { PropertyTagTypeShort
, 0x102, 6, { 8,0,8,0,8,0 } },
3722 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3723 { PropertyTagTypeShort
, 0x106, 2, { 2,0 } },
3724 { PropertyTagTypeASCII
, 0x10d, 27, "/home/meh/Desktop/test.tif" },
3725 { PropertyTagTypeLong
, 0x111, 4, { 8,0,0,0 } },
3726 { PropertyTagTypeShort
, 0x112, 2, { 1 } },
3727 { PropertyTagTypeShort
, 0x115, 2, { 3,0 } },
3728 { PropertyTagTypeShort
, 0x116, 2, { 0x40,0 } },
3729 { PropertyTagTypeLong
, 0x117, 4, { 3,0,0,0 } },
3730 { PropertyTagTypeRational
, 0x11a, 8, { 0,0,0,72,0,0,0,1 } },
3731 { PropertyTagTypeRational
, 0x11b, 8, { 0,0,0,72,0,0,0,1 } },
3732 { PropertyTagTypeShort
, 0x11c, 2, { 1 } },
3733 { PropertyTagTypeShort
, 0x128, 2, { 2 } }
3738 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3739 UINT total_size
, total_count
;
3741 PropertyItem
*prop_item
;
3742 const char *item_data
;
3744 image
= load_image(tiffimage
, sizeof(tiffimage
), TRUE
, FALSE
);
3745 ok(image
!= 0, "Failed to load TIFF image data\n");
3748 dim_count
= 0xdeadbeef;
3749 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3751 expect(1, dim_count
);
3753 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3755 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3757 frame_count
= 0xdeadbeef;
3758 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3760 expect(1, frame_count
);
3762 prop_count
= 0xdeadbeef;
3763 status
= GdipGetPropertyCount(image
, &prop_count
);
3765 ok(prop_count
== ARRAY_SIZE(td
),
3766 "expected property count %u, got %u\n", (UINT
) ARRAY_SIZE(td
), prop_count
);
3768 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3770 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3774 for (i
= 0; i
< prop_count
; i
++)
3777 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
3779 if (status
!= Ok
) break;
3780 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
3784 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
3785 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
3787 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3788 ok(td
[i
].type
== prop_item
->type
,
3789 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3790 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3791 size
-= sizeof(*prop_item
);
3792 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
3793 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3794 if (td
[i
].length
== prop_item
->length
)
3796 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3797 ok(match
, "%u: data mismatch\n", i
);
3801 BYTE
*data
= prop_item
->value
;
3802 trace("id %#x:", prop_item
->id
);
3803 for (j
= 0; j
< prop_item
->length
; j
++)
3804 trace(" %02x", data
[j
]);
3808 HeapFree(GetProcessHeap(), 0, prop_item
);
3811 HeapFree(GetProcessHeap(), 0, prop_id
);
3813 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
3814 expect(InvalidParameter
, status
);
3815 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
3816 expect(InvalidParameter
, status
);
3817 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
3818 expect(InvalidParameter
, status
);
3819 status
= GdipGetPropertySize(image
, NULL
, NULL
);
3820 expect(InvalidParameter
, status
);
3821 total_size
= 0xdeadbeef;
3822 total_count
= 0xdeadbeef;
3823 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
3825 ok(prop_count
== total_count
,
3826 "expected total property count %u, got %u\n", prop_count
, total_count
);
3827 ok(prop_size
== total_size
,
3828 "expected total property size %u, got %u\n", prop_size
, total_size
);
3830 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
3832 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
3833 expect(InvalidParameter
, status
);
3834 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
3835 expect(InvalidParameter
, status
);
3836 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3837 expect(InvalidParameter
, status
);
3838 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3839 expect(InvalidParameter
, status
);
3840 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
3841 expect(InvalidParameter
, status
);
3842 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
3843 expect(InvalidParameter
, status
);
3844 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
3847 item_data
= (const char *)(prop_item
+ prop_count
);
3848 for (i
= 0; i
< prop_count
; i
++)
3850 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
3851 i
, item_data
, prop_item
[i
].value
);
3852 ok(td
[i
].type
== prop_item
[i
].type
,
3853 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
3854 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
3855 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
3856 if (td
[i
].length
== prop_item
[i
].length
)
3858 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
3859 ok(match
, "%u: data mismatch\n", i
);
3863 BYTE
*data
= prop_item
[i
].value
;
3864 trace("id %#x:", prop_item
[i
].id
);
3865 for (j
= 0; j
< prop_item
[i
].length
; j
++)
3866 trace(" %02x", data
[j
]);
3870 item_data
+= prop_item
[i
].length
;
3873 HeapFree(GetProcessHeap(), 0, prop_item
);
3875 GdipDisposeImage(image
);
3878 static void test_tiff_palette(void)
3889 ARGB
*entries
= palette
.pal
.Entries
;
3891 /* 1bpp TIFF without palette */
3892 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
), TRUE
, FALSE
);
3895 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3899 status
= GdipGetImagePixelFormat(image
, &format
);
3901 ok(format
== PixelFormat1bppIndexed
, "expected PixelFormat1bppIndexed, got %#x\n", format
);
3903 status
= GdipGetImagePaletteSize(image
, &size
);
3904 ok(status
== Ok
|| broken(status
== GenericError
), /* XP */
3905 "GdipGetImagePaletteSize error %d\n", status
);
3906 if (status
== GenericError
)
3908 GdipDisposeImage(image
);
3911 expect(sizeof(ColorPalette
) + sizeof(ARGB
), size
);
3913 status
= GdipGetImagePalette(image
, &palette
.pal
, size
);
3915 expect(0, palette
.pal
.Flags
);
3916 expect(2, palette
.pal
.Count
);
3917 if (palette
.pal
.Count
== 2)
3919 ok(entries
[0] == 0xff000000, "expected 0xff000000, got %#x\n", entries
[0]);
3920 ok(entries
[1] == 0xffffffff, "expected 0xffffffff, got %#x\n", entries
[1]);
3923 GdipDisposeImage(image
);
3926 static void test_bitmapbits(void)
3929 static const BYTE pixels_24
[48] =
3931 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3932 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3933 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3934 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0
3936 static const BYTE pixels_00
[48] =
3938 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3939 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3940 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3941 0,0,0, 0,0,0, 0,0,0, 0,0,0
3943 static const BYTE pixels_24_77
[64] =
3945 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3946 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3947 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3948 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3949 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3950 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3952 static const BYTE pixels_77
[64] =
3954 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3955 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3956 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3957 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3958 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3959 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3960 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3961 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3963 static const BYTE pixels_8
[16] =
3965 0x01,0,0x01,0,0x01,0,0x01,0,
3966 0x01,0,0x01,0,0x01,0,0x01,0
3968 static const BYTE pixels_8_77
[64] =
3970 0x01,0,0x01,0,0x01,0,0x01,0,
3971 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3972 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3973 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3974 0x01,0,0x01,0,0x01,0,0x01,0,
3975 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3976 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3977 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3979 static const BYTE pixels_1_77
[64] =
3981 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3982 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3983 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3984 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3985 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3986 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3987 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3988 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3990 static const BYTE pixels_1
[8] = {0xaa,0,0,0,0xaa,0,0,0};
3991 static const struct test_data
3998 const BYTE
*pixels_unlocked
;
4002 { PixelFormat24bppRGB
, 24, 0xfff0, 24, 48, pixels_24
, pixels_00
},
4004 { PixelFormat24bppRGB
, 24, 0, 24, 48, pixels_24
, pixels_00
},
4005 { PixelFormat24bppRGB
, 24, ImageLockModeRead
, 24, 48, pixels_24
, pixels_00
},
4006 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
4007 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
4008 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_24_77
, pixels_24
},
4009 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
4010 { PixelFormat24bppRGB
, 24, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
4012 { PixelFormat8bppIndexed
, 8, 0, 8, 16, pixels_8
, pixels_24
},
4013 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
, 8, 16, pixels_8
, pixels_24
},
4014 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
4015 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
4016 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_8_77
, pixels_24
},
4017 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
4018 { PixelFormat8bppIndexed
, 8, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
4020 { PixelFormat1bppIndexed
, 1, 0, 4, 8, pixels_1
, pixels_24
},
4021 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
, 4, 8, pixels_1
, pixels_24
},
4022 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
4023 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
4024 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_1_77
, pixels_24
},
4025 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
4026 { PixelFormat1bppIndexed
, 1, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
4038 ARGB
*entries
= palette
.pal
.Entries
;
4040 for (i
= 0; i
< ARRAY_SIZE(td
); i
++)
4042 BYTE pixels
[sizeof(pixels_24
)];
4043 memcpy(pixels
, pixels_24
, sizeof(pixels_24
));
4044 status
= GdipCreateBitmapFromScan0(8, 2, 24, PixelFormat24bppRGB
, pixels
, &bitmap
);
4047 /* associate known palette with pixel data */
4048 palette
.pal
.Flags
= PaletteFlagsGrayScale
;
4049 palette
.pal
.Count
= 2;
4050 entries
[0] = 0xff000000;
4051 entries
[1] = 0xffffffff;
4052 status
= GdipSetImagePalette((GpImage
*)bitmap
, &palette
.pal
);
4055 memset(&data
, 0xfe, sizeof(data
));
4056 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
4058 memset(buf
, 0x77, sizeof(buf
));
4062 status
= GdipBitmapLockBits(bitmap
, NULL
, td
[i
].mode
, td
[i
].format
, &data
);
4063 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* XP */, "%u: GdipBitmapLockBits error %d\n", i
, status
);
4066 GdipDisposeImage((GpImage
*)bitmap
);
4069 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
4070 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
4071 ok(td
[i
].stride
== data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].stride
, data
.Stride
);
4072 ok(td
[i
].format
== data
.PixelFormat
, "%u: expected %d, got %d\n", i
, td
[i
].format
, data
.PixelFormat
);
4073 ok(td
[i
].size
== data
.Height
* data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].size
, data
.Height
* data
.Stride
);
4074 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
4075 ok(data
.Scan0
== buf
, "%u: got wrong buffer\n", i
);
4076 if (td
[i
].size
== data
.Height
* data
.Stride
)
4078 UINT j
, match
, width_bytes
= (data
.Width
* td
[i
].bpp
) / 8;
4081 for (j
= 0; j
< data
.Height
; j
++)
4083 if (memcmp((const BYTE
*)data
.Scan0
+ j
* data
.Stride
, td
[i
].pixels
+ j
* data
.Stride
, width_bytes
) != 0)
4089 if ((td
[i
].mode
& (ImageLockModeRead
|ImageLockModeUserInputBuf
)) || td
[i
].format
== PixelFormat24bppRGB
)
4092 "%u: data should match\n", i
);
4095 BYTE
*bits
= data
.Scan0
;
4096 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
4097 for (j
= 0; j
< td
[i
].size
; j
++)
4098 trace(" %02x", bits
[j
]);
4103 ok(!match
, "%u: data shouldn't match\n", i
);
4105 memset(data
.Scan0
, 0, td
[i
].size
);
4108 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4109 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
4111 memset(&data
, 0xfe, sizeof(data
));
4112 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
4113 ok(status
== Ok
, "%u: GdipBitmapLockBits error %d\n", i
, status
);
4114 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
4115 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
4116 ok(data
.Stride
== 24, "%u: expected 24, got %d\n", i
, data
.Stride
);
4117 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "%u: got wrong pixel format %d\n", i
, data
.PixelFormat
);
4118 ok(data
.Height
* data
.Stride
== 48, "%u: expected 48, got %d\n", i
, data
.Height
* data
.Stride
);
4119 if (data
.Height
* data
.Stride
== 48)
4121 int match
= memcmp(data
.Scan0
, td
[i
].pixels_unlocked
, 48) == 0;
4122 ok(match
, "%u: data should match\n", i
);
4126 BYTE
*bits
= data
.Scan0
;
4127 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
4128 for (j
= 0; j
< 48; j
++)
4129 trace(" %02x", bits
[j
]);
4134 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4135 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
4137 status
= GdipDisposeImage((GpImage
*)bitmap
);
4142 static void test_DrawImage(void)
4144 BYTE black_1x1
[4] = { 0,0,0,0 };
4145 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
4146 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
4147 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
4148 0,0,0,0,0,0,0xff,0xff };
4155 GpGraphics
*graphics
;
4158 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
4160 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4163 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
4165 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
4167 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4169 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4172 status
= GdipDrawImageI(graphics
, u1
.image
, 0, 0);
4175 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
4176 ok(match
, "data should match\n");
4179 UINT i
, size
= sizeof(white_2x2
);
4180 BYTE
*bits
= white_2x2
;
4181 for (i
= 0; i
< size
; i
++)
4182 trace(" %02x", bits
[i
]);
4186 status
= GdipDeleteGraphics(graphics
);
4188 status
= GdipDisposeImage(u1
.image
);
4190 status
= GdipDisposeImage(u2
.image
);
4194 static void test_DrawImage_SourceCopy(void)
4196 DWORD dst_pixels
[4] = { 0xffffffff, 0xffffffff,
4197 0xffffffff, 0xffffffff };
4198 DWORD src_pixels
[4] = { 0, 0xffff0000,
4207 GpGraphics
*graphics
;
4209 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB
, (BYTE
*)dst_pixels
, &u1
.bitmap
);
4212 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB
, (BYTE
*)src_pixels
, &u2
.bitmap
);
4214 status
= GdipGetImageGraphicsContext(u1
.image
, &graphics
);
4216 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4219 status
= GdipSetCompositingMode(graphics
, CompositingModeSourceCopy
);
4222 status
= GdipDrawImageI(graphics
, u2
.image
, 0, 0);
4225 todo_wine
expect(0, dst_pixels
[0]);
4226 expect(0xffff0000, dst_pixels
[1]);
4227 todo_wine
expect(0, dst_pixels
[2]);
4228 todo_wine
expect(0, dst_pixels
[3]);
4230 status
= GdipDeleteGraphics(graphics
);
4232 status
= GdipDisposeImage(u1
.image
);
4234 status
= GdipDisposeImage(u2
.image
);
4238 static void test_GdipDrawImagePointRect(void)
4240 BYTE black_1x1
[4] = { 0,0,0,0 };
4241 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
4242 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
4243 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
4244 0,0,0,0,0,0,0xff,0xff };
4251 GpGraphics
*graphics
;
4254 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
4256 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4259 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
4261 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
4263 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4265 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4268 status
= GdipDrawImagePointRectI(graphics
, u1
.image
, 0, 0, 0, 0, 1, 1, UnitPixel
);
4271 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
4272 ok(match
, "data should match\n");
4275 UINT i
, size
= sizeof(white_2x2
);
4276 BYTE
*bits
= white_2x2
;
4277 for (i
= 0; i
< size
; i
++)
4278 trace(" %02x", bits
[i
]);
4282 status
= GdipDeleteGraphics(graphics
);
4284 status
= GdipDisposeImage(u1
.image
);
4286 status
= GdipDisposeImage(u2
.image
);
4290 static void test_image_format(void)
4292 static const PixelFormat fmt
[] =
4294 PixelFormat1bppIndexed
, PixelFormat4bppIndexed
, PixelFormat8bppIndexed
,
4295 PixelFormat16bppGrayScale
, PixelFormat16bppRGB555
, PixelFormat16bppRGB565
,
4296 PixelFormat16bppARGB1555
, PixelFormat24bppRGB
, PixelFormat32bppRGB
,
4297 PixelFormat32bppARGB
, PixelFormat32bppPARGB
, PixelFormat48bppRGB
,
4298 PixelFormat64bppARGB
, PixelFormat64bppPARGB
, PixelFormat32bppCMYK
4309 for (i
= 0; i
< ARRAY_SIZE(fmt
); i
++)
4311 status
= GdipCreateBitmapFromScan0(1, 1, 0, fmt
[i
], NULL
, &bitmap
);
4312 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* before win7 */,
4313 "GdipCreateBitmapFromScan0 error %d\n", status
);
4314 if (status
!= Ok
) continue;
4316 status
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
4318 expect(fmt
[i
], format
);
4320 status
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
4321 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4322 todo_wine
expect(InvalidParameter
, status
);
4326 ret
= GetObjectW(hbitmap
, sizeof(bm
), &bm
);
4327 expect(sizeof(bm
), ret
);
4328 expect(0, bm
.bmType
);
4329 expect(1, bm
.bmWidth
);
4330 expect(1, bm
.bmHeight
);
4331 expect(4, bm
.bmWidthBytes
);
4332 expect(1, bm
.bmPlanes
);
4333 expect(32, bm
.bmBitsPixel
);
4334 DeleteObject(hbitmap
);
4337 status
= GdipGetImageThumbnail((GpImage
*)bitmap
, 0, 0, &thumb
, NULL
, NULL
);
4338 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4340 ok(status
== OutOfMemory
|| broken(status
== InvalidParameter
) /* before win7 */,
4341 "expected OutOfMemory, got %d\n", status
);
4346 status
= GdipGetImagePixelFormat(thumb
, &format
);
4348 ok(format
== PixelFormat32bppPARGB
|| broken(format
!= PixelFormat32bppPARGB
) /* before win7 */,
4349 "expected PixelFormat32bppPARGB, got %#x\n", format
);
4350 status
= GdipDisposeImage(thumb
);
4354 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4355 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4356 todo_wine
expect(InvalidParameter
, status
);
4360 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4364 status
= GdipDisposeImage((GpImage
*)bitmap
);
4369 static void test_DrawImage_scale(void)
4371 static const BYTE back_8x1
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
4372 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4373 static const BYTE image_080
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,
4374 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4375 static const BYTE image_100
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,
4376 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4377 static const BYTE image_120
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,
4378 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4379 static const BYTE image_150
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4380 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4381 static const BYTE image_180
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4382 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4383 static const BYTE image_200
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4384 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4385 static const BYTE image_250
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,
4386 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4387 static const BYTE image_120_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4388 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4389 static const BYTE image_150_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4390 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4391 static const BYTE image_200_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4392 0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40 };
4393 static const BYTE image_250_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4394 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4395 static const struct test_data
4398 PixelOffsetMode pixel_offset_mode
;
4403 { 0.8, PixelOffsetModeNone
, image_080
}, /* 0 */
4404 { 1.0, PixelOffsetModeNone
, image_100
},
4405 { 1.2, PixelOffsetModeNone
, image_120
},
4406 { 1.5, PixelOffsetModeNone
, image_150
},
4407 { 1.8, PixelOffsetModeNone
, image_180
},
4408 { 2.0, PixelOffsetModeNone
, image_200
},
4409 { 2.5, PixelOffsetModeNone
, image_250
},
4411 { 0.8, PixelOffsetModeHighSpeed
, image_080
}, /* 7 */
4412 { 1.0, PixelOffsetModeHighSpeed
, image_100
},
4413 { 1.2, PixelOffsetModeHighSpeed
, image_120
},
4414 { 1.5, PixelOffsetModeHighSpeed
, image_150
},
4415 { 1.8, PixelOffsetModeHighSpeed
, image_180
},
4416 { 2.0, PixelOffsetModeHighSpeed
, image_200
},
4417 { 2.5, PixelOffsetModeHighSpeed
, image_250
},
4419 { 0.8, PixelOffsetModeHalf
, image_080
}, /* 14 */
4420 { 1.0, PixelOffsetModeHalf
, image_100
},
4421 { 1.2, PixelOffsetModeHalf
, image_120_half
, TRUE
},
4422 { 1.5, PixelOffsetModeHalf
, image_150_half
, TRUE
},
4423 { 1.8, PixelOffsetModeHalf
, image_180
},
4424 { 2.0, PixelOffsetModeHalf
, image_200_half
, TRUE
},
4425 { 2.5, PixelOffsetModeHalf
, image_250_half
, TRUE
},
4427 { 0.8, PixelOffsetModeHighQuality
, image_080
}, /* 21 */
4428 { 1.0, PixelOffsetModeHighQuality
, image_100
},
4429 { 1.2, PixelOffsetModeHighQuality
, image_120_half
, TRUE
},
4430 { 1.5, PixelOffsetModeHighQuality
, image_150_half
, TRUE
},
4431 { 1.8, PixelOffsetModeHighQuality
, image_180
},
4432 { 2.0, PixelOffsetModeHighQuality
, image_200_half
, TRUE
},
4433 { 2.5, PixelOffsetModeHighQuality
, image_250_half
, TRUE
},
4435 BYTE src_2x1
[6] = { 0x80,0x80,0x80,0x80,0x80,0x80 };
4443 GpGraphics
*graphics
;
4447 status
= GdipCreateBitmapFromScan0(2, 1, 4, PixelFormat24bppRGB
, src_2x1
, &u1
.bitmap
);
4449 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4452 status
= GdipCreateBitmapFromScan0(8, 1, 24, PixelFormat24bppRGB
, dst_8x1
, &u2
.bitmap
);
4454 status
= GdipBitmapSetResolution(u2
.bitmap
, 100.0, 100.0);
4456 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4458 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4461 for (i
= 0; i
< ARRAY_SIZE(td
); i
++)
4463 status
= GdipSetPixelOffsetMode(graphics
, td
[i
].pixel_offset_mode
);
4466 status
= GdipCreateMatrix2(td
[i
].scale_x
, 0.0, 0.0, 1.0, 0.0, 0.0, &matrix
);
4468 status
= GdipSetWorldTransform(graphics
, matrix
);
4470 GdipDeleteMatrix(matrix
);
4472 memcpy(dst_8x1
, back_8x1
, sizeof(dst_8x1
));
4473 status
= GdipDrawImageI(graphics
, u1
.image
, 1, 0);
4476 match
= memcmp(dst_8x1
, td
[i
].image
, sizeof(dst_8x1
)) == 0;
4477 todo_wine_if (!match
&& td
[i
].todo
)
4478 ok(match
, "%d: data should match\n", i
);
4481 UINT i
, size
= sizeof(dst_8x1
);
4482 const BYTE
*bits
= dst_8x1
;
4483 for (i
= 0; i
< size
; i
++)
4484 trace(" %02x", bits
[i
]);
4489 status
= GdipDeleteGraphics(graphics
);
4491 status
= GdipDisposeImage(u1
.image
);
4493 status
= GdipDisposeImage(u2
.image
);
4497 static const BYTE animatedgif
[] = {
4498 'G','I','F','8','9','a',0x01,0x00,0x01,0x00,0xA1,0x02,0x00,
4499 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
4500 /*0x21,0xFF,0x0B,'A','N','I','M','E','X','T','S','1','.','0',*/
4501 0x21,0xFF,0x0B,'N','E','T','S','C','A','P','E','2','.','0',
4502 0x03,0x01,0x05,0x00,0x00,
4503 0x21,0xFE,0x0C,'H','e','l','l','o',' ','W','o','r','l','d','!',0x00,
4504 0x21,0x01,0x0D,'a','n','i','m','a','t','i','o','n','.','g','i','f',0x00,
4505 0x21,0xF9,0x04,0xff,0x0A,0x00,0x08,0x00,
4506 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4507 0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,
4508 0x02,0x02,0x4C,0x01,0x00,
4509 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','1',0x00,
4510 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','1',0x00,
4511 0x21,0xF9,0x04,0x00,0x14,0x00,0x01,0x00,
4512 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4513 0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,
4514 0x02,0x02,0x44,0x01,0x00,
4515 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','2',0x00,
4516 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','2',0x00,0x3B
4519 static void test_gif_properties(void)
4521 static const struct test_data
4523 ULONG type
, id
, length
;
4524 const BYTE value
[13];
4527 { PropertyTagTypeLong
, PropertyTagFrameDelay
, 8, { 10,0,0,0,20,0,0,0 } },
4528 { PropertyTagTypeASCII
, PropertyTagExifUserComment
, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
4529 { PropertyTagTypeShort
, PropertyTagLoopCount
, 2, { 5,0 } },
4530 { PropertyTagTypeByte
, PropertyTagGlobalPalette
, 12, { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c } },
4531 { PropertyTagTypeByte
, PropertyTagIndexBackground
, 1, { 2 } },
4532 { PropertyTagTypeByte
, PropertyTagIndexTransparent
, 1, { 8 } }
4537 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
4538 UINT total_size
, total_count
;
4540 PropertyItem
*prop_item
;
4541 const char *item_data
;
4543 image
= load_image(animatedgif
, sizeof(animatedgif
), TRUE
, FALSE
);
4544 if (!image
) /* XP fails to load this GIF image */
4546 trace("Failed to load GIF image data\n");
4550 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
4552 expect(1, dim_count
);
4554 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
4556 expect_guid(&FrameDimensionTime
, &guid
, __LINE__
, FALSE
);
4558 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
4560 expect(2, frame_count
);
4562 status
= GdipImageSelectActiveFrame(image
, &guid
, 1);
4565 status
= GdipGetPropertyCount(image
, &prop_count
);
4567 ok(prop_count
== ARRAY_SIZE(td
) || broken(prop_count
== 1) /* before win7 */,
4568 "expected property count %u, got %u\n", (UINT
) ARRAY_SIZE(td
), prop_count
);
4570 if (prop_count
!= ARRAY_SIZE(td
))
4572 GdipDisposeImage(image
);
4576 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
4578 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
4582 for (i
= 0; i
< prop_count
; i
++)
4585 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
4587 if (status
!= Ok
) break;
4588 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
4592 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
4593 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
4595 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
4596 ok(td
[i
].type
== prop_item
->type
,
4597 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
4598 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
4599 size
-= sizeof(*prop_item
);
4600 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
4601 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
4602 if (td
[i
].length
== prop_item
->length
)
4604 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
4605 ok(match
, "%u: data mismatch\n", i
);
4609 BYTE
*data
= prop_item
->value
;
4610 trace("id %#x:", prop_item
->id
);
4611 for (j
= 0; j
< prop_item
->length
; j
++)
4612 trace(" %02x", data
[j
]);
4616 HeapFree(GetProcessHeap(), 0, prop_item
);
4619 HeapFree(GetProcessHeap(), 0, prop_id
);
4621 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
4622 expect(InvalidParameter
, status
);
4623 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
4624 expect(InvalidParameter
, status
);
4625 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
4626 expect(InvalidParameter
, status
);
4627 status
= GdipGetPropertySize(image
, NULL
, NULL
);
4628 expect(InvalidParameter
, status
);
4629 total_size
= 0xdeadbeef;
4630 total_count
= 0xdeadbeef;
4631 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
4633 ok(prop_count
== total_count
,
4634 "expected total property count %u, got %u\n", prop_count
, total_count
);
4635 ok(prop_size
== total_size
,
4636 "expected total property size %u, got %u\n", prop_size
, total_size
);
4638 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
4640 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
4641 expect(InvalidParameter
, status
);
4642 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
4643 expect(InvalidParameter
, status
);
4644 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4645 expect(InvalidParameter
, status
);
4646 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4647 expect(InvalidParameter
, status
);
4648 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
4649 expect(InvalidParameter
, status
);
4650 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
4651 expect(InvalidParameter
, status
);
4652 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
4655 item_data
= (const char *)(prop_item
+ prop_count
);
4656 for (i
= 0; i
< prop_count
; i
++)
4658 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
4659 i
, item_data
, prop_item
[i
].value
);
4660 ok(td
[i
].type
== prop_item
[i
].type
,
4661 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
4662 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
4663 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
4664 if (td
[i
].length
== prop_item
[i
].length
)
4666 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
4667 ok(match
, "%u: data mismatch\n", i
);
4671 BYTE
*data
= prop_item
[i
].value
;
4672 trace("id %#x:", prop_item
[i
].id
);
4673 for (j
= 0; j
< prop_item
[i
].length
; j
++)
4674 trace(" %02x", data
[j
]);
4678 item_data
+= prop_item
[i
].length
;
4681 HeapFree(GetProcessHeap(), 0, prop_item
);
4683 GdipDisposeImage(image
);
4686 static void test_ARGB_conversion(void)
4688 BYTE argb
[8] = { 0x11,0x22,0x33,0x80, 0xff,0xff,0xff,0 };
4689 BYTE pargb
[8] = { 0x09,0x11,0x1a,0x80, 0,0,0,0 };
4690 BYTE rgb32_xp
[8] = { 0x11,0x22,0x33,0xff, 0xff,0xff,0xff,0xff };
4691 BYTE rgb24
[6] = { 0x11,0x22,0x33, 0xff,0xff,0xff };
4698 status
= GdipCreateBitmapFromScan0(2, 1, 8, PixelFormat32bppARGB
, argb
, &bitmap
);
4701 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4703 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4704 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4705 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4706 ok(data
.PixelFormat
== PixelFormat32bppPARGB
, "expected PixelFormat32bppPARGB, got %d\n", data
.PixelFormat
);
4707 match
= !memcmp(data
.Scan0
, pargb
, sizeof(pargb
));
4708 ok(match
, "bits don't match\n");
4712 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppPARGB
,
4713 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4715 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4718 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppRGB
, &data
);
4720 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4721 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4722 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4723 ok(data
.PixelFormat
== PixelFormat32bppRGB
, "expected PixelFormat32bppRGB, got %d\n", data
.PixelFormat
);
4724 match
= !memcmp(data
.Scan0
, argb
, sizeof(argb
)) ||
4725 !memcmp(data
.Scan0
, rgb32_xp
, sizeof(rgb32_xp
));
4726 ok(match
, "bits don't match\n");
4730 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppRGB
,
4731 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4733 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4736 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
4738 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4739 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4740 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4741 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "expected PixelFormat24bppRGB, got %d\n", data
.PixelFormat
);
4742 match
= !memcmp(data
.Scan0
, rgb24
, sizeof(rgb24
));
4743 ok(match
, "bits don't match\n");
4747 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat24bppRGB
,
4748 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4750 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4753 GdipDisposeImage((GpImage
*)bitmap
);
4757 static void test_CloneBitmapArea(void)
4760 GpBitmap
*bitmap
, *copy
;
4761 BitmapData data
, data2
;
4763 status
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB
, NULL
, &bitmap
);
4766 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
| ImageLockModeWrite
, PixelFormat24bppRGB
, &data
);
4769 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data2
);
4770 expect(WrongState
, status
);
4772 status
= GdipCloneBitmapAreaI(0, 0, 1, 1, PixelFormat24bppRGB
, bitmap
, ©
);
4775 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4778 GdipDisposeImage((GpImage
*)copy
);
4779 GdipDisposeImage((GpImage
*)bitmap
);
4782 static BOOL
get_encoder_clsid(LPCWSTR mime
, GUID
*format
, CLSID
*clsid
)
4785 UINT n_codecs
, info_size
, i
;
4786 ImageCodecInfo
*info
;
4789 status
= GdipGetImageEncodersSize(&n_codecs
, &info_size
);
4792 info
= GdipAlloc(info_size
);
4794 status
= GdipGetImageEncoders(n_codecs
, info_size
, info
);
4797 for (i
= 0; i
< n_codecs
; i
++)
4799 if (!lstrcmpW(info
[i
].MimeType
, mime
))
4801 *format
= info
[i
].FormatID
;
4802 *clsid
= info
[i
].Clsid
;
4812 static void test_supported_encoders(void)
4814 static const WCHAR bmp_mimetype
[] = { 'i', 'm', 'a','g', 'e', '/', 'b', 'm', 'p',0 };
4815 static const WCHAR jpeg_mimetype
[] = { 'i','m','a','g','e','/','j','p','e','g',0 };
4816 static const WCHAR gif_mimetype
[] = { 'i','m','a','g','e','/','g','i','f',0 };
4817 static const WCHAR tiff_mimetype
[] = { 'i','m','a','g','e','/','t','i','f','f',0 };
4818 static const WCHAR png_mimetype
[] = { 'i','m','a','g','e','/','p','n','g',0 };
4819 static const struct test_data
4825 { bmp_mimetype
, &ImageFormatBMP
},
4826 { jpeg_mimetype
, &ImageFormatJPEG
},
4827 { gif_mimetype
, &ImageFormatGIF
},
4828 { tiff_mimetype
, &ImageFormatTIFF
},
4829 { png_mimetype
, &ImageFormatPNG
}
4840 status
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB
, NULL
, &bm
);
4841 ok(status
== Ok
, "GdipCreateBitmapFromScan0 error %d\n", status
);
4843 for (i
= 0; i
< ARRAY_SIZE(td
); i
++)
4845 ret
= get_encoder_clsid(td
[i
].mime
, &format
, &clsid
);
4846 ok(ret
, "%s encoder is not in the list\n", wine_dbgstr_w(td
[i
].mime
));
4847 expect_guid(td
[i
].format
, &format
, __LINE__
, FALSE
);
4849 hmem
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_NODISCARD
, 16);
4851 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
4852 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
4854 status
= GdipSaveImageToStream((GpImage
*)bm
, stream
, &clsid
, NULL
);
4855 ok(status
== Ok
, "GdipSaveImageToStream error %d\n", status
);
4857 IStream_Release(stream
);
4860 GdipDisposeImage((GpImage
*)bm
);
4863 static void test_createeffect(void)
4865 static const GUID noneffect
= { 0xcd0c3d4b, 0xe15e, 0x4cf2, { 0x9e, 0xa8, 0x6e, 0x1d, 0x65, 0x48, 0xc5, 0xa5 } };
4866 GpStatus (WINAPI
*pGdipCreateEffect
)( const GUID guid
, CGpEffect
**effect
);
4867 GpStatus (WINAPI
*pGdipDeleteEffect
)( CGpEffect
*effect
);
4870 HMODULE mod
= GetModuleHandleA("gdiplus.dll");
4872 const GUID
* const effectlist
[] =
4873 {&BlurEffectGuid
, &SharpenEffectGuid
, &ColorMatrixEffectGuid
, &ColorLUTEffectGuid
,
4874 &BrightnessContrastEffectGuid
, &HueSaturationLightnessEffectGuid
, &LevelsEffectGuid
,
4875 &TintEffectGuid
, &ColorBalanceEffectGuid
, &RedEyeCorrectionEffectGuid
, &ColorCurveEffectGuid
};
4877 pGdipCreateEffect
= (void*)GetProcAddress( mod
, "GdipCreateEffect");
4878 pGdipDeleteEffect
= (void*)GetProcAddress( mod
, "GdipDeleteEffect");
4879 if(!pGdipCreateEffect
|| !pGdipDeleteEffect
)
4881 /* GdipCreateEffect/GdipDeleteEffect was introduced in Windows Vista. */
4882 win_skip("GDIPlus version 1.1 not available\n");
4886 stat
= pGdipCreateEffect(BlurEffectGuid
, NULL
);
4887 expect(InvalidParameter
, stat
);
4889 stat
= pGdipCreateEffect(noneffect
, &effect
);
4890 todo_wine
expect(Win32Error
, stat
);
4892 for(i
=0; i
< ARRAY_SIZE(effectlist
); i
++)
4894 stat
= pGdipCreateEffect(*effectlist
[i
], &effect
);
4895 todo_wine
expect(Ok
, stat
);
4898 stat
= pGdipDeleteEffect(effect
);
4904 static void test_getadjustedpalette(void)
4907 GpImageAttributes
*imageattributes
;
4908 ColorPalette
*palette
;
4911 stat
= GdipCreateImageAttributes(&imageattributes
);
4914 colormap
.oldColor
.Argb
= 0xffffff00;
4915 colormap
.newColor
.Argb
= 0xffff00ff;
4916 stat
= GdipSetImageAttributesRemapTable(imageattributes
, ColorAdjustTypeBitmap
,
4917 TRUE
, 1, &colormap
);
4920 colormap
.oldColor
.Argb
= 0xffffff80;
4921 colormap
.newColor
.Argb
= 0xffff80ff;
4922 stat
= GdipSetImageAttributesRemapTable(imageattributes
, ColorAdjustTypeDefault
,
4923 TRUE
, 1, &colormap
);
4926 palette
= GdipAlloc(sizeof(*palette
) + sizeof(ARGB
) * 2);
4929 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeBitmap
);
4930 expect(InvalidParameter
, stat
);
4933 palette
->Entries
[0] = 0xffffff00;
4934 palette
->Entries
[1] = 0xffffff80;
4935 palette
->Entries
[2] = 0xffffffff;
4937 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeBitmap
);
4939 expect(0xffff00ff, palette
->Entries
[0]);
4940 expect(0xffffff80, palette
->Entries
[1]);
4941 expect(0xffffffff, palette
->Entries
[2]);
4943 palette
->Entries
[0] = 0xffffff00;
4944 palette
->Entries
[1] = 0xffffff80;
4945 palette
->Entries
[2] = 0xffffffff;
4947 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeBrush
);
4949 expect(0xffffff00, palette
->Entries
[0]);
4950 expect(0xffff80ff, palette
->Entries
[1]);
4951 expect(0xffffffff, palette
->Entries
[2]);
4953 stat
= GdipGetImageAttributesAdjustedPalette(NULL
, palette
, ColorAdjustTypeBitmap
);
4954 expect(InvalidParameter
, stat
);
4956 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, NULL
, ColorAdjustTypeBitmap
);
4957 expect(InvalidParameter
, stat
);
4959 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, -1);
4960 expect(InvalidParameter
, stat
);
4962 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeDefault
);
4963 expect(InvalidParameter
, stat
);
4966 GdipDisposeImageAttributes(imageattributes
);
4969 static void test_histogram(void)
4971 UINT ch0
[256], ch1
[256], ch2
[256], ch3
[256];
4972 HistogramFormat test_formats
[] =
4974 HistogramFormatARGB
,
4975 HistogramFormatPARGB
,
4977 HistogramFormatGray
,
4983 const UINT WIDTH
= 8, HEIGHT
= 16;
4988 if (!pGdipBitmapGetHistogramSize
)
4990 win_skip("GdipBitmapGetHistogramSize is not supported\n");
4994 stat
= pGdipBitmapGetHistogramSize(HistogramFormatARGB
, NULL
);
4995 expect(InvalidParameter
, stat
);
4997 stat
= pGdipBitmapGetHistogramSize(0xff, NULL
);
4998 expect(InvalidParameter
, stat
);
5001 stat
= pGdipBitmapGetHistogramSize(10, &num
);
5005 for (i
= 0; i
< ARRAY_SIZE(test_formats
); i
++)
5008 stat
= pGdipBitmapGetHistogramSize(test_formats
[i
], &num
);
5014 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
5017 /* Three solid rgb rows, next three rows are rgb shades. */
5018 for (x
= 0; x
< WIDTH
; x
++)
5020 GdipBitmapSetPixel(bm
, x
, 0, 0xffff0000);
5021 GdipBitmapSetPixel(bm
, x
, 1, 0xff00ff00);
5022 GdipBitmapSetPixel(bm
, x
, 2, 0xff0000ff);
5024 GdipBitmapSetPixel(bm
, x
, 3, 0xff010000);
5025 GdipBitmapSetPixel(bm
, x
, 4, 0xff003f00);
5026 GdipBitmapSetPixel(bm
, x
, 5, 0xff000020);
5029 stat
= pGdipBitmapGetHistogram(NULL
, HistogramFormatRGB
, 256, ch0
, ch1
, ch2
, ch3
);
5030 expect(InvalidParameter
, stat
);
5032 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, ch1
, ch2
, ch3
);
5033 expect(InvalidParameter
, stat
);
5035 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, ch1
, ch2
, NULL
);
5036 expect(InvalidParameter
, stat
);
5038 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, ch1
, NULL
, NULL
);
5039 expect(InvalidParameter
, stat
);
5041 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, NULL
, NULL
, NULL
);
5042 expect(InvalidParameter
, stat
);
5044 /* Requested format matches bitmap format */
5045 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 256, ch0
, ch1
, ch2
, ch3
);
5046 expect(InvalidParameter
, stat
);
5048 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 100, ch0
, ch1
, ch2
, NULL
);
5049 expect(InvalidParameter
, stat
);
5051 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 257, ch0
, ch1
, ch2
, NULL
);
5052 expect(InvalidParameter
, stat
);
5054 /* Channel 3 is not used, must be NULL */
5055 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 256, ch0
, ch1
, ch2
, NULL
);
5058 ok(ch0
[0xff] == WIDTH
, "Got red (0xff) %u\n", ch0
[0xff]);
5059 ok(ch1
[0xff] == WIDTH
, "Got green (0xff) %u\n", ch1
[0xff]);
5060 ok(ch2
[0xff] == WIDTH
, "Got blue (0xff) %u\n", ch1
[0xff]);
5061 ok(ch0
[0x01] == WIDTH
, "Got red (0x01) %u\n", ch0
[0x01]);
5062 ok(ch1
[0x3f] == WIDTH
, "Got green (0x3f) %u\n", ch1
[0x3f]);
5063 ok(ch2
[0x20] == WIDTH
, "Got blue (0x20) %u\n", ch1
[0x20]);
5065 /* ARGB histogram from RGB data. */
5066 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatARGB
, 256, ch0
, ch1
, ch2
, NULL
);
5067 expect(InvalidParameter
, stat
);
5069 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatARGB
, 256, ch0
, ch1
, ch2
, ch3
);
5072 ok(ch1
[0xff] == WIDTH
, "Got red (0xff) %u\n", ch1
[0xff]);
5073 ok(ch2
[0xff] == WIDTH
, "Got green (0xff) %u\n", ch2
[0xff]);
5074 ok(ch3
[0xff] == WIDTH
, "Got blue (0xff) %u\n", ch3
[0xff]);
5075 ok(ch1
[0x01] == WIDTH
, "Got red (0x01) %u\n", ch1
[0x01]);
5076 ok(ch2
[0x3f] == WIDTH
, "Got green (0x3f) %u\n", ch2
[0x3f]);
5077 ok(ch3
[0x20] == WIDTH
, "Got blue (0x20) %u\n", ch3
[0x20]);
5079 ok(ch0
[0xff] == WIDTH
* HEIGHT
, "Got alpha (0xff) %u\n", ch0
[0xff]);
5081 /* Request grayscale histogram from RGB bitmap. */
5082 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, ch1
, ch2
, ch3
);
5083 expect(InvalidParameter
, stat
);
5085 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, ch1
, ch2
, NULL
);
5086 expect(InvalidParameter
, stat
);
5088 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, ch1
, NULL
, NULL
);
5089 expect(InvalidParameter
, stat
);
5091 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, NULL
, NULL
, NULL
);
5094 GdipDisposeImage((GpImage
*)bm
);
5097 static void test_imageabort(void)
5102 if (!pGdipImageSetAbort
)
5104 win_skip("GdipImageSetAbort() is not supported.\n");
5109 stat
= GdipCreateBitmapFromScan0(8, 8, 0, PixelFormat24bppRGB
, NULL
, &bm
);
5112 stat
= pGdipImageSetAbort(NULL
, NULL
);
5113 expect(InvalidParameter
, stat
);
5115 stat
= pGdipImageSetAbort((GpImage
*)bm
, NULL
);
5118 GdipDisposeImage((GpImage
*)bm
);
5121 /* RGB 24 bpp 1x1 pixel PNG image */
5122 static const char png_1x1_data
[] = {
5123 0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,
5124 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,
5125 0x00,0x00,0x03,0x00,'P','L','T','E',
5126 0x01,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,
5127 0x09,0x09,0x09,0x0a,0x0a,0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0c,0x0d,0x0d,0x0d,0x0e,0x0e,0x0e,0x0f,0x0f,0x0f,0x10,0x10,0x10,
5128 0x11,0x11,0x11,0x12,0x12,0x12,0x13,0x13,0x13,0x14,0x14,0x14,0x15,0x15,0x15,0x16,0x16,0x16,0x17,0x17,0x17,0x18,0x18,0x18,
5129 0x19,0x19,0x19,0x1a,0x1a,0x1a,0x1b,0x1b,0x1b,0x1c,0x1c,0x1c,0x1d,0x1d,0x1d,0x1e,0x1e,0x1e,0x1f,0x1f,0x1f,0x20,0x20,0x20,
5130 0x21,0x21,0x21,0x22,0x22,0x22,0x23,0x23,0x23,0x24,0x24,0x24,0x25,0x25,0x25,0x26,0x26,0x26,0x27,0x27,0x27,0x28,0x28,0x28,
5131 0x29,0x29,0x29,0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,0x2c,0x2c,0x2c,0x2d,0x2d,0x2d,0x2e,0x2e,0x2e,0x2f,0x2f,0x2f,0x30,0x30,0x30,
5132 0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x37,0x37,0x37,0x38,0x38,0x38,
5133 0x39,0x39,0x39,0x3a,0x3a,0x3a,0x3b,0x3b,0x3b,0x3c,0x3c,0x3c,0x3d,0x3d,0x3d,0x3e,0x3e,0x3e,0x3f,0x3f,0x3f,0x40,0x40,0x40,
5134 0x41,0x41,0x41,0x42,0x42,0x42,0x43,0x43,0x43,0x44,0x44,0x44,0x45,0x45,0x45,0x46,0x46,0x46,0x47,0x47,0x47,0x48,0x48,0x48,
5135 0x49,0x49,0x49,0x4a,0x4a,0x4a,0x4b,0x4b,0x4b,0x4c,0x4c,0x4c,0x4d,0x4d,0x4d,0x4e,0x4e,0x4e,0x4f,0x4f,0x4f,0x50,0x50,0x50,
5136 0x51,0x51,0x51,0x52,0x52,0x52,0x53,0x53,0x53,0x54,0x54,0x54,0x55,0x55,0x55,0x56,0x56,0x56,0x57,0x57,0x57,0x58,0x58,0x58,
5137 0x59,0x59,0x59,0x5a,0x5a,0x5a,0x5b,0x5b,0x5b,0x5c,0x5c,0x5c,0x5d,0x5d,0x5d,0x5e,0x5e,0x5e,0x5f,0x5f,0x5f,0x60,0x60,0x60,
5138 0x61,0x61,0x61,0x62,0x62,0x62,0x63,0x63,0x63,0x64,0x64,0x64,0x65,0x65,0x65,0x66,0x66,0x66,0x67,0x67,0x67,0x68,0x68,0x68,
5139 0x69,0x69,0x69,0x6a,0x6a,0x6a,0x6b,0x6b,0x6b,0x6c,0x6c,0x6c,0x6d,0x6d,0x6d,0x6e,0x6e,0x6e,0x6f,0x6f,0x6f,0x70,0x70,0x70,
5140 0x71,0x71,0x71,0x72,0x72,0x72,0x73,0x73,0x73,0x74,0x74,0x74,0x75,0x75,0x75,0x76,0x76,0x76,0x77,0x77,0x77,0x78,0x78,0x78,
5141 0x79,0x79,0x79,0x7a,0x7a,0x7a,0x7b,0x7b,0x7b,0x7c,0x7c,0x7c,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x80,0x80,0x80,
5142 0x01,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,
5143 0x09,0x09,0x09,0x0a,0x0a,0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0c,0x0d,0x0d,0x0d,0x0e,0x0e,0x0e,0x0f,0x0f,0x0f,0x10,0x10,0x10,
5144 0x11,0x11,0x11,0x12,0x12,0x12,0x13,0x13,0x13,0x14,0x14,0x14,0x15,0x15,0x15,0x16,0x16,0x16,0x17,0x17,0x17,0x18,0x18,0x18,
5145 0x19,0x19,0x19,0x1a,0x1a,0x1a,0x1b,0x1b,0x1b,0x1c,0x1c,0x1c,0x1d,0x1d,0x1d,0x1e,0x1e,0x1e,0x1f,0x1f,0x1f,0x20,0x20,0x20,
5146 0x21,0x21,0x21,0x22,0x22,0x22,0x23,0x23,0x23,0x24,0x24,0x24,0x25,0x25,0x25,0x26,0x26,0x26,0x27,0x27,0x27,0x28,0x28,0x28,
5147 0x29,0x29,0x29,0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,0x2c,0x2c,0x2c,0x2d,0x2d,0x2d,0x2e,0x2e,0x2e,0x2f,0x2f,0x2f,0x30,0x30,0x30,
5148 0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x37,0x37,0x37,0x38,0x38,0x38,
5149 0x39,0x39,0x39,0x3a,0x3a,0x3a,0x3b,0x3b,0x3b,0x3c,0x3c,0x3c,0x3d,0x3d,0x3d,0x3e,0x3e,0x3e,0x3f,0x3f,0x3f,0x40,0x40,0x40,
5150 0x41,0x41,0x41,0x42,0x42,0x42,0x43,0x43,0x43,0x44,0x44,0x44,0x45,0x45,0x45,0x46,0x46,0x46,0x47,0x47,0x47,0x48,0x48,0x48,
5151 0x49,0x49,0x49,0x4a,0x4a,0x4a,0x4b,0x4b,0x4b,0x4c,0x4c,0x4c,0x4d,0x4d,0x4d,0x4e,0x4e,0x4e,0x4f,0x4f,0x4f,0x50,0x50,0x50,
5152 0x51,0x51,0x51,0x52,0x52,0x52,0x53,0x53,0x53,0x54,0x54,0x54,0x55,0x55,0x55,0x56,0x56,0x56,0x57,0x57,0x57,0x58,0x58,0x58,
5153 0x59,0x59,0x59,0x5a,0x5a,0x5a,0x5b,0x5b,0x5b,0x5c,0x5c,0x5c,0x5d,0x5d,0x5d,0x5e,0x5e,0x5e,0x5f,0x5f,0x5f,0x60,0x60,0x60,
5154 0x61,0x61,0x61,0x62,0x62,0x62,0x63,0x63,0x63,0x64,0x64,0x64,0x65,0x65,0x65,0x66,0x66,0x66,0x67,0x67,0x67,0x68,0x68,0x68,
5155 0x69,0x69,0x69,0x6a,0x6a,0x6a,0x6b,0x6b,0x6b,0x6c,0x6c,0x6c,0x6d,0x6d,0x6d,0x6e,0x6e,0x6e,0x6f,0x6f,0x6f,0x70,0x70,0x70,
5156 0x71,0x71,0x71,0x72,0x72,0x72,0x73,0x73,0x73,0x74,0x74,0x74,0x75,0x75,0x75,0x76,0x76,0x76,0x77,0x77,0x77,0x78,0x78,0x78,
5157 0x79,0x79,0x79,0x7a,0x7a,0x7a,0x7b,0x7b,0x7b,0x7c,0x7c,0x7c,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x80,0x80,0x80,
5158 0x76,0xb6,0x24,0x31,
5159 0x00,0x00,0x00,0x02,'t','R','N','S',0xff,0x00,0xe5,0xb7,0x30,0x4a,
5160 0x00,0x00,0x00,0x0c,'I','D','A','T',0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,0xe7,
5161 0x00,0x00,0x00,0x00,'I','E','N','D',0xae,0x42,0x60,0x82
5164 #define PNG_COLOR_TYPE_GRAY 0
5165 #define PNG_COLOR_TYPE_RGB 2
5166 #define PNG_COLOR_TYPE_PALETTE 3
5167 #define PNG_COLOR_TYPE_GRAY_ALPHA 4
5168 #define PNG_COLOR_TYPE_RGB_ALPHA 6
5170 static void test_png_color_formats(void)
5174 char bit_depth
, color_type
;
5184 { 1, PNG_COLOR_TYPE_RGB
},
5185 { 2, PNG_COLOR_TYPE_RGB
},
5186 { 4, PNG_COLOR_TYPE_RGB
},
5187 { 8, PNG_COLOR_TYPE_RGB
,
5188 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
},
5189 { PixelFormat24bppRGB
, ImageFlagsColorSpaceRGB
},
5190 { PixelFormat24bppRGB
, ImageFlagsColorSpaceRGB
}}},
5191 /* libpng refuses to load our test image complaining about extra compressed data,
5192 * but libpng is still able to load the image with other combination of type/depth
5193 * making RGB 16 bpp case special for some reason. Therefore todo = TRUE.
5195 { 16, PNG_COLOR_TYPE_RGB
,
5196 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
, TRUE
, TRUE
},
5197 { PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
, TRUE
, TRUE
},
5198 { PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
, TRUE
, TRUE
}}},
5201 { 1, PNG_COLOR_TYPE_GRAY
,
5202 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
},
5203 { PixelFormat1bppIndexed
, ImageFlagsColorSpaceRGB
},
5204 { PixelFormat1bppIndexed
, ImageFlagsColorSpaceRGB
}}},
5205 { 2, PNG_COLOR_TYPE_GRAY
,
5206 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
},
5207 { PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
},
5208 { PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
}}},
5209 { 4, PNG_COLOR_TYPE_GRAY
,
5210 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
},
5211 { PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
},
5212 { PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
}}},
5213 { 8, PNG_COLOR_TYPE_GRAY
,
5214 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
},
5215 { PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
},
5216 { PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
}}},
5217 { 16, PNG_COLOR_TYPE_GRAY
,
5218 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
},
5219 { PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
},
5220 { PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
}}},
5223 { 1, PNG_COLOR_TYPE_PALETTE
,
5224 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
},
5225 { PixelFormat1bppIndexed
, ImageFlagsColorSpaceRGB
},
5227 { 2, PNG_COLOR_TYPE_PALETTE
,
5228 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
},
5229 { PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
},
5231 { 4, PNG_COLOR_TYPE_PALETTE
,
5232 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
},
5233 { PixelFormat4bppIndexed
, ImageFlagsColorSpaceRGB
},
5235 { 8, PNG_COLOR_TYPE_PALETTE
,
5236 {{ PixelFormat32bppARGB
, ImageFlagsColorSpaceRGB
},
5237 { PixelFormat8bppIndexed
, ImageFlagsColorSpaceRGB
},
5239 { 16, PNG_COLOR_TYPE_PALETTE
},
5241 BYTE buf
[sizeof(png_1x1_data
)];
5248 int i
, j
, PLTE_off
= 0, tRNS_off
= 0;
5249 const ImageFlags color_space_mask
= ImageFlagsColorSpaceRGB
| ImageFlagsColorSpaceCMYK
| ImageFlagsColorSpaceGRAY
| ImageFlagsColorSpaceYCBCR
| ImageFlagsColorSpaceYCCK
;
5251 memcpy(buf
, png_1x1_data
, sizeof(png_1x1_data
));
5253 buf
[25] = PNG_COLOR_TYPE_PALETTE
;
5254 image
= load_image(buf
, sizeof(buf
), TRUE
, FALSE
);
5255 status
= GdipGetImageFlags(image
, &flags
);
5257 ok((flags
& color_space_mask
) == ImageFlagsColorSpaceRGB
|| broken(flags
== 0x12006) /* before win7 */,
5258 "flags = %#x\n", flags
);
5259 if ((flags
& color_space_mask
) != ImageFlagsColorSpaceRGB
) {
5260 GdipDisposeImage(image
);
5261 win_skip("broken PNG color space support\n");
5264 GdipDisposeImage(image
);
5266 for (i
= 0; i
< sizeof(png_1x1_data
) - 4; i
++)
5268 if (!memcmp(buf
+ i
, "tRNS", 4))
5270 else if (!memcmp(buf
+ i
, "PLTE", 4))
5274 ok(PLTE_off
&& tRNS_off
, "PLTE offset %d, tRNS offset %d\n", PLTE_off
, tRNS_off
);
5275 if (!PLTE_off
|| !tRNS_off
) return;
5277 /* In order to test the image data with and without PLTE and tRNS
5278 * chunks, we mask the chunk name with private one (tEST).
5281 for (i
= 0; i
< ARRAY_SIZE(td
); i
++)
5283 for (j
= 0; j
< 3; j
++)
5285 memcpy(buf
, png_1x1_data
, sizeof(png_1x1_data
));
5286 buf
[24] = td
[i
].bit_depth
;
5287 buf
[25] = td
[i
].color_type
;
5288 if (j
>=1) memcpy(buf
+ tRNS_off
, "tEST", 4);
5289 if (j
>=2) memcpy(buf
+ PLTE_off
, "tEST", 4);
5291 valid
= (td
[i
].t
[j
].format
!= 0) || (td
[i
].t
[j
].flags
!= 0);
5292 image
= load_image(buf
, sizeof(buf
), valid
, td
[i
].t
[j
].todo_load
);
5293 todo_wine_if(td
[i
].t
[j
].todo_load
)
5295 ok(image
!= NULL
, "%d %d: failed to load image data\n", i
, j
);
5298 ok(image
== NULL
, "%d %d: succeed to load image data\n", i
, j
);
5299 if (image
) GdipDisposeImage(image
);
5302 if (!image
) continue;
5304 status
= GdipGetImageType(image
, &type
);
5305 ok(status
== Ok
, "%d %d: GdipGetImageType error %d\n", i
, j
, status
);
5306 ok(type
== ImageTypeBitmap
, "%d %d: wrong image type %d\n", i
, j
, type
);
5308 status
= GdipGetImagePixelFormat(image
, &format
);
5310 todo_wine_if(td
[i
].t
[j
].todo
)
5311 ok(format
== td
[i
].t
[j
].format
,
5312 "%d %d: expected %#x, got %#x\n", i
, j
, td
[i
].t
[j
].format
, format
);
5314 status
= GdipGetImageFlags(image
, &flags
);
5316 ok((flags
& color_space_mask
) == td
[i
].t
[j
].flags
,
5317 "%d %d: expected %#x, got %#x\n", i
, j
, td
[i
].t
[j
].flags
, flags
);
5318 GdipDisposeImage(image
);
5322 #undef PNG_COLOR_TYPE_GRAY
5323 #undef PNG_COLOR_TYPE_RGB
5324 #undef PNG_COLOR_TYPE_PALETTE
5325 #undef PNG_COLOR_TYPE_GRAY_ALPHA
5326 #undef PNG_COLOR_TYPE_RGB_ALPHA
5328 static void test_GdipLoadImageFromStream(void)
5337 status
= GdipLoadImageFromStream(NULL
, NULL
);
5338 ok(status
== InvalidParameter
, "Unexpected return value %d.\n", status
);
5340 image
= (void *)0xdeadbeef;
5341 status
= GdipLoadImageFromStream(NULL
, &image
);
5342 ok(status
== InvalidParameter
, "Unexpected return value %d.\n", status
);
5343 ok(image
== (void *)0xdeadbeef, "Unexpected image pointer.\n");
5345 hglob
= GlobalAlloc(0, sizeof(pngimage
));
5346 data
= GlobalLock (hglob
);
5347 memcpy(data
, pngimage
, sizeof(pngimage
));
5348 GlobalUnlock(hglob
);
5350 hr
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
5351 ok(hr
== S_OK
, "Failed to create a stream.\n");
5353 status
= GdipLoadImageFromStream(stream
, NULL
);
5354 ok(status
== InvalidParameter
, "Unexpected return value %d.\n", status
);
5356 IStream_Release(stream
);
5359 static BYTE
*init_bitmap(UINT
*width
, UINT
*height
, UINT
*stride
)
5366 *stride
= (*width
* 3 + 3) & ~3;
5367 trace("width %d, height %d, stride %d\n", *width
, *height
, *stride
);
5369 src
= HeapAlloc(GetProcessHeap(), 0, *stride
* *height
);
5371 scale
= 256 / *width
;
5372 if (!scale
) scale
= 1;
5374 for (i
= 0; i
< *height
; i
++)
5376 for (j
= 0; j
< *width
; j
++)
5378 src
[i
* *stride
+ j
*3 + 0] = scale
* i
;
5379 src
[i
* *stride
+ j
*3 + 1] = scale
* (255 - (i
+j
)/2);
5380 src
[i
* *stride
+ j
*3 + 2] = scale
* j
;
5387 static void test_GdipInitializePalette(void)
5392 ColorPalette
*palette
;
5393 UINT width
, height
, stride
;
5395 pGdipInitializePalette
= (void *)GetProcAddress(GetModuleHandleA("gdiplus.dll"), "GdipInitializePalette");
5396 if (!pGdipInitializePalette
)
5398 win_skip("GdipInitializePalette is not supported on this platform\n");
5402 data
= init_bitmap(&width
, &height
, &stride
);
5404 status
= GdipCreateBitmapFromScan0(width
, height
, stride
, PixelFormat24bppRGB
, data
, &bitmap
);
5407 palette
= GdipAlloc(sizeof(*palette
) + sizeof(ARGB
) * 255);
5410 palette
->Count
= 15;
5411 status
= pGdipInitializePalette(palette
, PaletteTypeOptimal
, 16, FALSE
, bitmap
);
5412 expect(GenericError
, status
);
5415 palette
->Count
= 256;
5416 status
= pGdipInitializePalette(palette
, PaletteTypeOptimal
, 16, FALSE
, NULL
);
5417 expect(InvalidParameter
, status
);
5419 memset(palette
->Entries
, 0x11, sizeof(ARGB
) * 256);
5421 palette
->Count
= 256;
5422 status
= pGdipInitializePalette(palette
, PaletteTypeCustom
, 16, FALSE
, NULL
);
5424 expect(0, palette
->Flags
);
5425 expect(256, palette
->Count
);
5426 expect(0x11111111, palette
->Entries
[0]);
5427 expect(0x11111111, palette
->Entries
[128]);
5428 expect(0x11111111, palette
->Entries
[255]);
5430 memset(palette
->Entries
, 0x11, sizeof(ARGB
) * 256);
5432 palette
->Count
= 256;
5433 status
= pGdipInitializePalette(palette
, PaletteTypeFixedBW
, 0, FALSE
, bitmap
);
5436 expect(0x200, palette
->Flags
);
5437 expect(2, palette
->Count
);
5438 expect(0xff000000, palette
->Entries
[0]);
5439 expect(0xffffffff, palette
->Entries
[1]);
5441 memset(palette
->Entries
, 0x11, sizeof(ARGB
) * 256);
5443 palette
->Count
= 256;
5444 status
= pGdipInitializePalette(palette
, PaletteTypeFixedHalftone8
, 1, FALSE
, NULL
);
5447 expect(0x300, palette
->Flags
);
5448 expect(16, palette
->Count
);
5449 expect(0xff000000, palette
->Entries
[0]);
5450 expect(0xffc0c0c0, palette
->Entries
[8]);
5451 expect(0xff008080, palette
->Entries
[15]);
5453 memset(palette
->Entries
, 0x11, sizeof(ARGB
) * 256);
5455 palette
->Count
= 256;
5456 status
= pGdipInitializePalette(palette
, PaletteTypeFixedHalftone8
, 1, FALSE
, bitmap
);
5459 expect(0x300, palette
->Flags
);
5460 expect(16, palette
->Count
);
5461 expect(0xff000000, palette
->Entries
[0]);
5462 expect(0xffc0c0c0, palette
->Entries
[8]);
5463 expect(0xff008080, palette
->Entries
[15]);
5465 memset(palette
->Entries
, 0x11, sizeof(ARGB
) * 256);
5467 palette
->Count
= 256;
5468 status
= pGdipInitializePalette(palette
, PaletteTypeFixedHalftone252
, 1, FALSE
, bitmap
);
5471 expect(0x800, palette
->Flags
);
5472 expect(252, palette
->Count
);
5473 expect(0xff000000, palette
->Entries
[0]);
5474 expect(0xff990066, palette
->Entries
[128]);
5475 expect(0xffffffff, palette
->Entries
[251]);
5478 palette
->Count
= 256;
5479 status
= pGdipInitializePalette(palette
, PaletteTypeOptimal
, 1, FALSE
, bitmap
);
5480 expect(InvalidParameter
, status
);
5483 palette
->Count
= 256;
5484 status
= pGdipInitializePalette(palette
, PaletteTypeOptimal
, 2, FALSE
, bitmap
);
5486 expect(0, palette
->Flags
);
5487 expect(2, palette
->Count
);
5490 palette
->Count
= 256;
5491 status
= pGdipInitializePalette(palette
, PaletteTypeOptimal
, 16, FALSE
, bitmap
);
5493 expect(0, palette
->Flags
);
5494 expect(16, palette
->Count
);
5496 /* passing invalid enumeration palette type crashes under most Windows versions */
5499 GdipDisposeImage((GpImage
*)bitmap
);
5502 #include "pshpack2.h"
5503 static const struct tiff_1x1_data
5508 USHORT number_of_entries
;
5509 struct IFD_entry entry
[12];
5511 struct IFD_rational res
;
5512 short palette_data
[3][256];
5514 BYTE pixel_data
[32];
5517 #ifdef WORDS_BIGENDIAN
5523 FIELD_OFFSET(struct tiff_1x1_data
, number_of_entries
),
5526 { 0xff, IFD_SHORT
, 1, 0 }, /* SUBFILETYPE */
5527 { 0x100, IFD_LONG
, 1, 1 }, /* IMAGEWIDTH */
5528 { 0x101, IFD_LONG
, 1, 1 }, /* IMAGELENGTH */
5529 { 0x102, IFD_SHORT
, 3, FIELD_OFFSET(struct tiff_1x1_data
, bps_data
) }, /* BITSPERSAMPLE */
5530 { 0x103, IFD_SHORT
, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
5531 { 0x106, IFD_SHORT
, 1, 2 }, /* PHOTOMETRIC */
5532 { 0x111, IFD_LONG
, 1, FIELD_OFFSET(struct tiff_1x1_data
, pixel_data
) }, /* STRIPOFFSETS */
5533 { 0x115, IFD_SHORT
, 1, 3 }, /* SAMPLESPERPIXEL */
5534 { 0x11a, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_1x1_data
, res
) },
5535 { 0x11b, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_1x1_data
, res
) },
5536 { 0x128, IFD_SHORT
, 1, 2 }, /* RESOLUTIONUNIT */
5537 { 0x140, IFD_SHORT
, 256*3, FIELD_OFFSET(struct tiff_1x1_data
, palette_data
) } /* COLORMAP */
5543 { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 }
5545 #include "poppack.h"
5547 static void test_tiff_color_formats(void)
5551 int photometric
; /* PhotometricInterpretation */
5552 int samples
; /* SamplesPerPixel */
5553 int bps
; /* BitsPerSample */
5558 { 2, 3, 1, PixelFormat24bppRGB
},
5559 { 2, 3, 4, PixelFormat24bppRGB
},
5560 { 2, 3, 8, PixelFormat24bppRGB
},
5561 { 2, 3, 16, PixelFormat48bppRGB
},
5566 { 2, 4, 1, PixelFormat32bppARGB
},
5567 { 2, 4, 4, PixelFormat32bppARGB
},
5568 { 2, 4, 8, PixelFormat32bppARGB
},
5569 { 2, 4, 16, PixelFormat48bppRGB
},
5572 /* 1 - BlackIsZero (Bilevel) */
5573 { 1, 1, 1, PixelFormat1bppIndexed
},
5574 #if 0 /* FIXME: PNG vs TIFF mismatch */
5575 { 1, 1, 4, PixelFormat8bppIndexed
},
5577 { 1, 1, 8, PixelFormat8bppIndexed
},
5578 { 1, 1, 16, PixelFormat32bppARGB
},
5580 { 1, 1, 32, PixelFormat32bppARGB
},
5581 /* 3 - Palette Color */
5582 { 3, 1, 1, PixelFormat1bppIndexed
},
5583 { 3, 1, 4, PixelFormat4bppIndexed
},
5584 { 3, 1, 8, PixelFormat8bppIndexed
},
5585 #if 0 /* FIXME: for some reason libtiff replaces photometric 3 by 1 for bps > 8 */
5593 { 5, 4, 8, PixelFormat32bppCMYK
},
5594 { 5, 4, 16, PixelFormat48bppRGB
},
5598 BYTE buf
[sizeof(tiff_1x1_data
)];
5602 struct IFD_entry
*tag
, *tag_photo
= NULL
, *tag_bps
= NULL
, *tag_samples
= NULL
, *tag_colormap
= NULL
;
5607 memcpy(buf
, &tiff_1x1_data
, sizeof(tiff_1x1_data
));
5609 count
= *(short *)(buf
+ tiff_1x1_data
.dir_offset
);
5610 tag
= (struct IFD_entry
*)(buf
+ tiff_1x1_data
.dir_offset
+ sizeof(short));
5612 /* verify the TIFF structure */
5613 for (i
= 0; i
< count
; i
++)
5615 if (tag
[i
].id
== 0x102) /* BitsPerSample */
5617 else if (tag
[i
].id
== 0x106) /* PhotometricInterpretation */
5618 tag_photo
= &tag
[i
];
5619 else if (tag
[i
].id
== 0x115) /* SamplesPerPixel */
5620 tag_samples
= &tag
[i
];
5621 else if (tag
[i
].id
== 0x140) /* ColorMap */
5622 tag_colormap
= &tag
[i
];
5625 ok(tag_bps
&& tag_photo
&& tag_samples
&& tag_colormap
, "tag 0x102,0x106,0x115 or 0x140 is missing\n");
5626 if (!tag_bps
|| !tag_photo
|| !tag_samples
|| !tag_colormap
) return;
5628 ok(tag_bps
->type
== IFD_SHORT
, "tag 0x102 should have type IFD_SHORT\n");
5629 bps
= (short *)(buf
+ tag_bps
->value
);
5630 ok(bps
[0] == 8 && bps
[1] == 8 && bps
[2] == 8 && bps
[3] == 0,
5631 "expected bps 8,8,8,0 got %d,%d,%d,%d\n", bps
[0], bps
[1], bps
[2], bps
[3]);
5633 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
5635 tag_colormap
->count
= (1 << td
[i
].bps
) * 3;
5636 tag_photo
->value
= td
[i
].photometric
;
5637 tag_bps
->count
= td
[i
].samples
;
5638 tag_samples
->value
= td
[i
].samples
;
5640 if (td
[i
].samples
== 1)
5641 tag_bps
->value
= td
[i
].bps
;
5642 else if (td
[i
].samples
== 2)
5643 tag_bps
->value
= MAKELONG(td
[i
].bps
, td
[i
].bps
);
5644 else if (td
[i
].samples
== 3)
5646 tag_bps
->value
= (BYTE
*)bps
- buf
;
5647 bps
[0] = bps
[1] = bps
[2] = td
[i
].bps
;
5649 else if (td
[i
].samples
== 4)
5651 tag_bps
->value
= (BYTE
*)bps
- buf
;
5652 bps
[0] = bps
[1] = bps
[2] = bps
[3] = td
[i
].bps
;
5656 ok(0, "%u: unsupported samples count %d\n", i
, td
[i
].samples
);
5660 image
= load_image(buf
, sizeof(buf
), TRUE
, FALSE
);
5663 ok(!image
|| (((GetVersion() & 0xFF) < 6) &&
5664 (i
== 19 || i
== 20)),
5668 "%u: (%d,%d,%d) TIFF image loading should have failed\n", i
, td
[i
].photometric
, td
[i
].samples
, td
[i
].bps
);
5670 ok(image
!= NULL
|| broken(!image
) /* XP */, "%u: failed to load TIFF image data (%d,%d,%d)\n",
5671 i
, td
[i
].photometric
, td
[i
].samples
, td
[i
].bps
);
5672 if (!image
) continue;
5674 status
= GdipGetImageType(image
, &type
);
5675 ok(status
== Ok
, "%u: GdipGetImageType error %d\n", i
, status
);
5676 ok(type
== ImageTypeBitmap
, "%u: wrong image type %d\n", i
, type
);
5678 status
= GdipGetImagePixelFormat(image
, &format
);
5681 ok(format
== td
[i
].format
|| (((GetVersion() & 0xFF) < 6) &&
5682 ((i
== 0 && format
== 0) ||
5683 (i
== 1 && format
== 0) ||
5684 (i
== 5 && format
== 0) ||
5685 (i
== 6 && format
== 0) ||
5686 (i
== 13 && format
== 0) ||
5687 (i
== 19 && format
== PixelFormat32bppARGB
) ||
5688 (i
== 20 && format
== PixelFormat32bppARGB
) ||
5689 (i
== 21 && format
== PixelFormat32bppARGB
) ||
5690 (i
== 22 && format
== PixelFormat32bppARGB
))),
5692 ok(format
== td
[i
].format
,
5694 "%u: expected %#x, got %#x\n", i
, td
[i
].format
, format
);
5696 GdipDisposeImage(image
);
5702 HMODULE mod
= GetModuleHandleA("gdiplus.dll");
5703 struct GdiplusStartupInput gdiplusStartupInput
;
5704 ULONG_PTR gdiplusToken
;
5706 int (CDECL
* _controlfp_s
)(unsigned int *cur
, unsigned int newval
, unsigned int mask
);
5708 /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */
5709 hmsvcrt
= LoadLibraryA("msvcrt");
5710 _controlfp_s
= (void*)GetProcAddress(hmsvcrt
, "_controlfp_s");
5711 if (_controlfp_s
) _controlfp_s(0, 0, 0x0008001e);
5713 gdiplusStartupInput
.GdiplusVersion
= 1;
5714 gdiplusStartupInput
.DebugEventCallback
= NULL
;
5715 gdiplusStartupInput
.SuppressBackgroundThread
= 0;
5716 gdiplusStartupInput
.SuppressExternalCodecs
= 0;
5718 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, NULL
);
5720 pGdipBitmapGetHistogramSize
= (void*)GetProcAddress(mod
, "GdipBitmapGetHistogramSize");
5721 pGdipBitmapGetHistogram
= (void*)GetProcAddress(mod
, "GdipBitmapGetHistogram");
5722 pGdipImageSetAbort
= (void*)GetProcAddress(mod
, "GdipImageSetAbort");
5724 test_tiff_color_formats();
5725 test_GdipInitializePalette();
5726 test_png_color_formats();
5727 test_supported_encoders();
5728 test_CloneBitmapArea();
5729 test_ARGB_conversion();
5730 test_DrawImage_scale();
5731 test_image_format();
5733 test_DrawImage_SourceCopy();
5734 test_GdipDrawImagePointRect();
5736 test_tiff_palette();
5737 test_GdipGetAllPropertyItems();
5738 test_tiff_properties();
5739 test_gif_properties();
5740 test_image_properties();
5743 test_GetImageDimension();
5744 test_GdipImageGetFrameDimensionsCount();
5745 test_LoadingImages();
5746 test_SavingImages();
5749 test_LockBits_UserBuf();
5750 test_GdipCreateBitmapFromHBITMAP();
5751 test_GdipGetImageFlags();
5752 test_GdipCloneImage();
5755 test_getrawformat();
5757 test_createfromwmf();
5758 test_createfromwmf_noplaceable();
5760 test_createhbitmap();
5761 test_getthumbnail();
5766 test_multiframegif();
5771 test_createeffect();
5772 test_getadjustedpalette();
5775 test_GdipLoadImageFromStream();
5777 GdiplusShutdown(gdiplusToken
);