2 * Unit test suite for images
4 * Copyright (C) 2007 Google (Evan Stade)
5 * Copyright (C) 2012, 2016 Dmitry Timoshkov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 /* FIXME: They belong to gdipluseffects.h */
28 DEFINE_GUID(BlurEffectGuid
, 0x633c80a4, 0x1843, 0x482b, 0x9e, 0xf2, 0xbe, 0x28, 0x34, 0xc5, 0xfd, 0xd4);
29 DEFINE_GUID(SharpenEffectGuid
, 0x63cbf3ee, 0xc526, 0x402c, 0x8f, 0x71, 0x62, 0xc5, 0x40, 0xbf, 0x51, 0x42);
30 DEFINE_GUID(ColorMatrixEffectGuid
, 0x718f2615, 0x7933, 0x40e3, 0xa5, 0x11, 0x5f, 0x68, 0xfe, 0x14, 0xdd, 0x74);
31 DEFINE_GUID(ColorLUTEffectGuid
, 0xa7ce72a9, 0x0f7f, 0x40d7, 0xb3, 0xcc, 0xd0, 0xc0, 0x2d, 0x5c, 0x32, 0x12);
32 DEFINE_GUID(BrightnessContrastEffectGuid
, 0xd3a1dbe1, 0x8ec4, 0x4c17, 0x9f, 0x4c, 0xea, 0x97, 0xad, 0x1c, 0x34, 0x3d);
33 DEFINE_GUID(HueSaturationLightnessEffectGuid
, 0x8b2dd6c3, 0xeb07, 0x4d87, 0xa5, 0xf0, 0x71, 0x08, 0xe2, 0x6a, 0x9c, 0x5f);
34 DEFINE_GUID(LevelsEffectGuid
, 0x99c354ec, 0x2a31, 0x4f3a, 0x8c, 0x34, 0x17, 0xa8, 0x03, 0xb3, 0x3a, 0x25);
35 DEFINE_GUID(TintEffectGuid
, 0x1077af00, 0x2848, 0x4441, 0x94, 0x89, 0x44, 0xad, 0x4c, 0x2d, 0x7a, 0x2c);
36 DEFINE_GUID(ColorBalanceEffectGuid
, 0x537e597d, 0x251e, 0x48da, 0x96, 0x64, 0x29, 0xca, 0x49, 0x6b, 0x70, 0xf8);
37 DEFINE_GUID(RedEyeCorrectionEffectGuid
, 0x74d29d05, 0x69a4, 0x4266, 0x95, 0x49, 0x3c, 0xc5, 0x28, 0x36, 0xb6, 0x32);
38 DEFINE_GUID(ColorCurveEffectGuid
, 0xdd6a0022, 0x58e4, 0x4a67, 0x9d, 0x9b, 0xd4, 0x8e, 0xb8, 0x81, 0xa5, 0x3d);
40 static GpStatus (WINAPI
*pGdipBitmapGetHistogramSize
)(HistogramFormat
,UINT
*);
41 static GpStatus (WINAPI
*pGdipBitmapGetHistogram
)(GpBitmap
*,HistogramFormat
,UINT
,UINT
*,UINT
*,UINT
*,UINT
*);
42 static GpStatus (WINAPI
*pGdipImageSetAbort
)(GpImage
*,GdiplusAbort
*);
44 #define expect(expected, got) ok((got) == (expected), "Expected %d, got %d\n", (UINT)(expected), (UINT)(got))
45 #define expectf(expected, got) ok(fabs((expected) - (got)) < 0.0001, "Expected %f, got %f\n", (expected), (got))
47 static BOOL
color_match(ARGB c1
, ARGB c2
, BYTE max_diff
)
49 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
51 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
53 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
55 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
59 static void expect_guid(REFGUID expected
, REFGUID got
, int line
, BOOL todo
)
65 StringFromGUID2(got
, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]));
66 WideCharToMultiByte(CP_ACP
, 0, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]), buffer
, sizeof(buffer
), NULL
, NULL
);
67 StringFromGUID2(expected
, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]));
68 WideCharToMultiByte(CP_ACP
, 0, bufferW
, sizeof(bufferW
)/sizeof(bufferW
[0]), buffer2
, sizeof(buffer2
), NULL
, NULL
);
70 ok_(__FILE__
, line
)(IsEqualGUID(expected
, got
), "Expected %s, got %s\n", buffer2
, buffer
);
73 static void expect_rawformat(REFGUID expected
, GpImage
*img
, int line
, BOOL todo
)
78 stat
= GdipGetImageRawFormat(img
, &raw
);
79 ok_(__FILE__
, line
)(stat
== Ok
, "GdipGetImageRawFormat failed with %d\n", stat
);
80 if(stat
!= Ok
) return;
81 expect_guid(expected
, &raw
, line
, todo
);
84 static void test_bufferrawformat(void* buff
, int size
, REFGUID expected
, int line
, BOOL todo
)
93 hglob
= GlobalAlloc (0, size
);
94 data
= GlobalLock (hglob
);
95 memcpy(data
, buff
, size
);
96 GlobalUnlock(hglob
); data
= NULL
;
98 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
99 ok_(__FILE__
, line
)(hres
== S_OK
, "Failed to create a stream\n");
100 if(hres
!= S_OK
) return;
102 stat
= GdipLoadImageFromStream(stream
, &img
);
103 ok_(__FILE__
, line
)(stat
== Ok
, "Failed to create a Bitmap\n");
105 IStream_Release(stream
);
109 expect_rawformat(expected
, img
, line
, todo
);
111 GdipDisposeImage(img
);
112 IStream_Release(stream
);
115 static void test_Scan0(void)
122 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
124 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
126 GdipDisposeImage((GpImage
*)bm
);
128 bm
= (GpBitmap
*)0xdeadbeef;
129 stat
= GdipCreateBitmapFromScan0(10, -10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
130 expect(InvalidParameter
, stat
);
131 ok( !bm
, "expected null bitmap\n" );
133 bm
= (GpBitmap
*)0xdeadbeef;
134 stat
= GdipCreateBitmapFromScan0(-10, 10, 10, PixelFormat24bppRGB
, NULL
, &bm
);
135 expect(InvalidParameter
, stat
);
136 ok( !bm
, "expected null bitmap\n" );
138 bm
= (GpBitmap
*)0xdeadbeef;
139 stat
= GdipCreateBitmapFromScan0(10, 0, 10, PixelFormat24bppRGB
, NULL
, &bm
);
140 expect(InvalidParameter
, stat
);
141 ok( !bm
, "expected null bitmap\n" );
144 stat
= GdipCreateBitmapFromScan0(10, 10, 12, PixelFormat24bppRGB
, buff
, &bm
);
146 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
148 GdipDisposeImage((GpImage
*)bm
);
150 bm
= (GpBitmap
*) 0xdeadbeef;
151 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, buff
, &bm
);
152 expect(InvalidParameter
, stat
);
153 ok( !bm
, "expected null bitmap\n" );
155 bm
= (GpBitmap
*)0xdeadbeef;
156 stat
= GdipCreateBitmapFromScan0(10, 10, 0, PixelFormat24bppRGB
, buff
, &bm
);
157 expect(InvalidParameter
, stat
);
158 ok( bm
== (GpBitmap
*)0xdeadbeef, "expected deadbeef bitmap\n" );
161 stat
= GdipCreateBitmapFromScan0(10, 10, -8, PixelFormat24bppRGB
, buff
, &bm
);
163 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
165 GdipDisposeImage((GpImage
*)bm
);
167 bm
= (GpBitmap
*)0xdeadbeef;
168 stat
= GdipCreateBitmapFromScan0(10, 10, -10, PixelFormat24bppRGB
, buff
, &bm
);
169 expect(InvalidParameter
, stat
);
170 ok( !bm
, "expected null bitmap\n" );
173 static void test_FromGdiDib(void)
178 BYTE rbmi
[sizeof(BITMAPINFOHEADER
)+256*sizeof(RGBQUAD
)];
179 BITMAPINFO
*bmi
= (BITMAPINFO
*)rbmi
;
184 memset(rbmi
, 0, sizeof(rbmi
));
186 bmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
187 bmi
->bmiHeader
.biWidth
= 10;
188 bmi
->bmiHeader
.biHeight
= 10;
189 bmi
->bmiHeader
.biPlanes
= 1;
190 bmi
->bmiHeader
.biBitCount
= 32;
191 bmi
->bmiHeader
.biCompression
= BI_RGB
;
193 stat
= GdipCreateBitmapFromGdiDib(NULL
, buff
, &bm
);
194 expect(InvalidParameter
, stat
);
196 stat
= GdipCreateBitmapFromGdiDib(bmi
, NULL
, &bm
);
197 expect(InvalidParameter
, stat
);
199 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, NULL
);
200 expect(InvalidParameter
, stat
);
202 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
204 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
207 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
209 expect(PixelFormat32bppRGB
, format
);
211 GdipDisposeImage((GpImage
*)bm
);
214 bmi
->bmiHeader
.biBitCount
= 24;
215 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
217 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
220 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
222 expect(PixelFormat24bppRGB
, format
);
224 GdipDisposeImage((GpImage
*)bm
);
227 bmi
->bmiHeader
.biBitCount
= 16;
228 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
230 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
233 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
235 expect(PixelFormat16bppRGB555
, format
);
237 GdipDisposeImage((GpImage
*)bm
);
240 bmi
->bmiHeader
.biBitCount
= 8;
241 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
243 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
246 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
248 expect(PixelFormat8bppIndexed
, format
);
250 GdipDisposeImage((GpImage
*)bm
);
253 bmi
->bmiHeader
.biBitCount
= 4;
254 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
256 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
259 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
261 expect(PixelFormat4bppIndexed
, format
);
263 GdipDisposeImage((GpImage
*)bm
);
266 bmi
->bmiHeader
.biBitCount
= 1;
267 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
269 ok(NULL
!= bm
, "Expected bitmap to be initialized\n");
272 stat
= GdipGetImagePixelFormat((GpImage
*)bm
, &format
);
274 expect(PixelFormat1bppIndexed
, format
);
276 GdipDisposeImage((GpImage
*)bm
);
279 bmi
->bmiHeader
.biBitCount
= 0;
280 stat
= GdipCreateBitmapFromGdiDib(bmi
, buff
, &bm
);
281 expect(InvalidParameter
, stat
);
284 static void test_GetImageDimension(void)
288 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
291 bm
= (GpBitmap
*)0xdeadbeef;
292 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
,NULL
, &bm
);
294 ok((GpBitmap
*)0xdeadbeef != bm
, "Expected bitmap to not be 0xdeadbeef\n");
295 ok(NULL
!= bm
, "Expected bitmap to not be NULL\n");
297 stat
= GdipGetImageDimension(NULL
,&w
,&h
);
298 expect(InvalidParameter
, stat
);
300 stat
= GdipGetImageDimension((GpImage
*)bm
,NULL
,&h
);
301 expect(InvalidParameter
, stat
);
303 stat
= GdipGetImageDimension((GpImage
*)bm
,&w
,NULL
);
304 expect(InvalidParameter
, stat
);
308 stat
= GdipGetImageDimension((GpImage
*)bm
,&w
,&h
);
312 GdipDisposeImage((GpImage
*)bm
);
315 static void test_GdipImageGetFrameDimensionsCount(void)
319 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
321 GUID dimension
= {0};
325 bm
= (GpBitmap
*)0xdeadbeef;
326 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
,NULL
, &bm
);
328 ok((GpBitmap
*)0xdeadbeef != bm
, "Expected bitmap to not be 0xdeadbeef\n");
329 ok(NULL
!= bm
, "Expected bitmap to not be NULL\n");
331 stat
= GdipImageGetFrameDimensionsCount(NULL
,&w
);
332 expect(InvalidParameter
, stat
);
334 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bm
,NULL
);
335 expect(InvalidParameter
, stat
);
338 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bm
,&w
);
342 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 1);
344 expect_guid(&FrameDimensionPage
, &dimension
, __LINE__
, FALSE
);
346 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 2);
347 expect(InvalidParameter
, stat
);
349 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bm
, &dimension
, 0);
350 expect(InvalidParameter
, stat
);
352 stat
= GdipImageGetFrameCount(NULL
, &dimension
, &count
);
353 expect(InvalidParameter
, stat
);
355 /* WinXP crashes on this test */
358 stat
= GdipImageGetFrameCount((GpImage
*)bm
, &dimension
, NULL
);
359 expect(InvalidParameter
, stat
);
362 stat
= GdipImageGetFrameCount((GpImage
*)bm
, NULL
, &count
);
366 stat
= GdipImageGetFrameCount((GpImage
*)bm
, &dimension
, &count
);
370 GdipBitmapSetPixel(bm
, 0, 0, 0xffffffff);
372 stat
= GdipImageSelectActiveFrame((GpImage
*)bm
, &dimension
, 0);
375 /* SelectActiveFrame has no effect on image data of memory bitmaps */
377 stat
= GdipBitmapGetPixel(bm
, 0, 0, &color
);
379 expect(0xffffffff, color
);
381 GdipDisposeImage((GpImage
*)bm
);
384 static void test_LoadingImages(void)
389 static const WCHAR nonexistentW
[] = {'n','o','n','e','x','i','s','t','e','n','t',0};
391 stat
= GdipCreateBitmapFromFile(0, 0);
392 expect(InvalidParameter
, stat
);
394 bm
= (GpBitmap
*)0xdeadbeef;
395 stat
= GdipCreateBitmapFromFile(0, &bm
);
396 expect(InvalidParameter
, stat
);
397 ok(bm
== (GpBitmap
*)0xdeadbeef, "returned %p\n", bm
);
399 bm
= (GpBitmap
*)0xdeadbeef;
400 stat
= GdipCreateBitmapFromFile(nonexistentW
, &bm
);
401 todo_wine
expect(InvalidParameter
, stat
);
402 ok(!bm
, "returned %p\n", bm
);
404 stat
= GdipLoadImageFromFile(0, 0);
405 expect(InvalidParameter
, stat
);
407 img
= (GpImage
*)0xdeadbeef;
408 stat
= GdipLoadImageFromFile(0, &img
);
409 expect(InvalidParameter
, stat
);
410 ok(img
== (GpImage
*)0xdeadbeef, "returned %p\n", img
);
412 img
= (GpImage
*)0xdeadbeef;
413 stat
= GdipLoadImageFromFile(nonexistentW
, &img
);
414 todo_wine
expect(OutOfMemory
, stat
);
415 ok(!img
, "returned %p\n", img
);
417 stat
= GdipLoadImageFromFileICM(0, 0);
418 expect(InvalidParameter
, stat
);
420 img
= (GpImage
*)0xdeadbeef;
421 stat
= GdipLoadImageFromFileICM(0, &img
);
422 expect(InvalidParameter
, stat
);
423 ok(img
== (GpImage
*)0xdeadbeef, "returned %p\n", img
);
425 img
= (GpImage
*)0xdeadbeef;
426 stat
= GdipLoadImageFromFileICM(nonexistentW
, &img
);
427 todo_wine
expect(OutOfMemory
, stat
);
428 ok(!img
, "returned %p\n", img
);
431 static void test_SavingImages(void)
437 const REAL WIDTH
= 10.0, HEIGHT
= 20.0;
439 ImageCodecInfo
*codecs
;
440 static const CHAR filenameA
[] = "a.bmp";
441 static const WCHAR filename
[] = { 'a','.','b','m','p',0 };
445 stat
= GdipSaveImageToFile(0, 0, 0, 0);
446 expect(InvalidParameter
, stat
);
449 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
455 stat
= GdipSaveImageToFile((GpImage
*)bm
, 0, 0, 0);
456 expect(InvalidParameter
, stat
);
458 stat
= GdipSaveImageToFile((GpImage
*)bm
, filename
, 0, 0);
459 expect(InvalidParameter
, stat
);
461 /* encoder tests should succeed -- already tested */
462 stat
= GdipGetImageEncodersSize(&n
, &s
);
463 if (stat
!= Ok
|| n
== 0) goto cleanup
;
465 codecs
= GdipAlloc(s
);
466 if (!codecs
) goto cleanup
;
468 stat
= GdipGetImageEncoders(n
, s
, codecs
);
469 if (stat
!= Ok
) goto cleanup
;
471 stat
= GdipSaveImageToFile((GpImage
*)bm
, filename
, &codecs
[0].Clsid
, 0);
474 GdipDisposeImage((GpImage
*)bm
);
477 /* re-load and check image stats */
478 stat
= GdipLoadImageFromFile(filename
, (GpImage
**)&bm
);
480 if (stat
!= Ok
) goto cleanup
;
482 stat
= GdipGetImageDimension((GpImage
*)bm
, &w
, &h
);
483 if (stat
!= Ok
) goto cleanup
;
491 GdipDisposeImage((GpImage
*)bm
);
492 ok(DeleteFileA(filenameA
), "Delete failed.\n");
495 static void test_encoders(void)
500 ImageCodecInfo
*codecs
;
504 static const CHAR bmp_format
[] = "BMP";
506 stat
= GdipGetImageEncodersSize(&n
, &s
);
509 codecs
= GdipAlloc(s
);
513 stat
= GdipGetImageEncoders(n
, s
, NULL
);
514 expect(GenericError
, stat
);
516 stat
= GdipGetImageEncoders(0, s
, codecs
);
517 expect(GenericError
, stat
);
519 stat
= GdipGetImageEncoders(n
, s
-1, codecs
);
520 expect(GenericError
, stat
);
522 stat
= GdipGetImageEncoders(n
, s
+1, codecs
);
523 expect(GenericError
, stat
);
525 stat
= GdipGetImageEncoders(n
, s
, codecs
);
529 for (i
= 0; i
< n
; i
++)
533 WideCharToMultiByte(CP_ACP
, 0, codecs
[i
].FormatDescription
, -1,
536 if (CompareStringA(LOCALE_SYSTEM_DEFAULT
, 0,
538 bmp_format
, -1) == CSTR_EQUAL
) {
544 ok(FALSE
, "No BMP codec found.\n");
549 static void test_LockBits(void)
555 const INT WIDTH
= 10, HEIGHT
= 20;
560 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
568 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffc30000);
571 stat
= GdipBitmapSetPixel(bm
, 2, 8, 0xff480000);
575 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
579 expect(0xc3, ((BYTE
*)bd
.Scan0
)[2]);
580 expect(0x48, ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5]);
582 ((char*)bd
.Scan0
)[2] = 0xff;
584 stat
= GdipBitmapUnlockBits(bm
, &bd
);
588 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
590 expect(0xffff0000, color
);
592 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffc30000);
595 /* read-only, with NULL rect -> whole bitmap lock */
596 stat
= GdipBitmapLockBits(bm
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
598 expect(bd
.Width
, WIDTH
);
599 expect(bd
.Height
, HEIGHT
);
602 ((char*)bd
.Scan0
)[2 + 2*3 + 3*bd
.Stride
] = 0xff;
604 stat
= GdipBitmapUnlockBits(bm
, &bd
);
608 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
610 expect(0xffff0000, color
);
612 /* read-only, consecutive */
613 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
617 stat
= GdipBitmapUnlockBits(bm
, &bd
);
621 stat
= GdipDisposeImage((GpImage
*)bm
);
623 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
627 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
629 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
630 expect(WrongState
, stat
);
632 stat
= GdipBitmapUnlockBits(bm
, &bd
);
635 stat
= GdipDisposeImage((GpImage
*)bm
);
637 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
640 stat
= GdipBitmapSetPixel(bm
, 2, 3, 0xffff0000);
643 stat
= GdipBitmapSetPixel(bm
, 2, 8, 0xffc30000);
646 /* write, no conversion */
647 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
651 /* all bits are readable, inside the rect or not */
652 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
653 expect(0xc3, ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5]);
655 stat
= GdipBitmapUnlockBits(bm
, &bd
);
659 /* read, conversion */
660 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat32bppARGB
, &bd
);
664 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
666 /* Areas outside the rectangle appear to be uninitialized */
667 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
669 ((BYTE
*)bd
.Scan0
)[2] = 0xc3;
671 stat
= GdipBitmapUnlockBits(bm
, &bd
);
675 /* writes do not work in read mode if there was a conversion */
676 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
678 expect(0xffff0000, color
);
680 /* read/write, conversion */
681 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeWrite
, PixelFormat32bppARGB
, &bd
);
685 expect(0xff, ((BYTE
*)bd
.Scan0
)[2]);
686 ((BYTE
*)bd
.Scan0
)[1] = 0x88;
688 /* Areas outside the rectangle appear to be uninitialized */
689 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
691 stat
= GdipBitmapUnlockBits(bm
, &bd
);
695 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
697 expect(0xffff8800, color
);
699 /* write, conversion */
700 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat32bppARGB
, &bd
);
706 /* This is completely uninitialized. */
707 ok(0xff != ((BYTE
*)bd
.Scan0
)[2], "original image bits are readable\n");
708 ok(0xc3 != ((BYTE
*)bd
.Scan0
)[2 + bd
.Stride
* 5], "original image bits are readable\n");
711 /* Initialize the buffer so the unlock doesn't access undefined memory */
713 memset(((BYTE
*)bd
.Scan0
) + bd
.Stride
* y
, 0, 12);
715 ((BYTE
*)bd
.Scan0
)[0] = 0x12;
716 ((BYTE
*)bd
.Scan0
)[1] = 0x34;
717 ((BYTE
*)bd
.Scan0
)[2] = 0x56;
719 stat
= GdipBitmapUnlockBits(bm
, &bd
);
723 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
725 expect(0xff563412, color
);
727 stat
= GdipBitmapGetPixel(bm
, 2, 8, &color
);
729 expect(0xffc30000, color
);
731 stat
= GdipDisposeImage((GpImage
*)bm
);
733 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
736 /* write, no modification */
737 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
741 stat
= GdipBitmapUnlockBits(bm
, &bd
);
745 /* write, consecutive */
746 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
750 stat
= GdipBitmapUnlockBits(bm
, &bd
);
754 stat
= GdipDisposeImage((GpImage
*)bm
);
756 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
760 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
, PixelFormat24bppRGB
, &bd
);
765 ((char*)bd
.Scan0
)[2] = 0xff;
767 stat
= GdipBitmapUnlockBits(bm
, &bd
);
771 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
773 expect(0xffff0000, color
);
775 stat
= GdipDisposeImage((GpImage
*)bm
);
779 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
781 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
, PixelFormat24bppRGB
, &bd
);
783 stat
= GdipDisposeImage((GpImage
*)bm
);
787 static void test_LockBits_UserBuf(void)
793 const INT WIDTH
= 10, HEIGHT
= 20;
798 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat32bppARGB
, NULL
, &bm
);
801 memset(bits
, 0xaa, sizeof(bits
));
810 bd
.Stride
= WIDTH
* 4;
811 bd
.PixelFormat
= PixelFormat32bppARGB
;
812 bd
.Scan0
= &bits
[2+3*WIDTH
];
813 bd
.Reserved
= 0xaaaaaaaa;
816 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
819 expect(0xaaaaaaaa, bits
[0]);
820 expect(0, bits
[2+3*WIDTH
]);
822 bits
[2+3*WIDTH
] = 0xdeadbeef;
825 stat
= GdipBitmapUnlockBits(bm
, &bd
);
829 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
834 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeWrite
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
837 expect(0xdeadbeef, bits
[2+3*WIDTH
]);
838 bits
[2+3*WIDTH
] = 0x12345678;
841 stat
= GdipBitmapUnlockBits(bm
, &bd
);
845 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
847 expect(0x12345678, color
);
852 stat
= GdipBitmapLockBits(bm
, &rect
, ImageLockModeRead
|ImageLockModeWrite
|ImageLockModeUserInputBuf
, PixelFormat32bppARGB
, &bd
);
855 expect(0x12345678, bits
[2+3*WIDTH
]);
856 bits
[2+3*WIDTH
] = 0xdeadbeef;
859 stat
= GdipBitmapUnlockBits(bm
, &bd
);
863 stat
= GdipBitmapGetPixel(bm
, 2, 3, &color
);
865 expect(0xdeadbeef, color
);
867 stat
= GdipDisposeImage((GpImage
*)bm
);
871 struct BITMAPINFOWITHBITFIELDS
873 BITMAPINFOHEADER bmiHeader
;
877 union BITMAPINFOUNION
880 struct BITMAPINFOWITHBITFIELDS bf
;
883 static void test_GdipCreateBitmapFromHBITMAP(void)
885 GpBitmap
* gpbm
= NULL
;
887 HPALETTE hpal
= NULL
;
890 LOGPALETTE
* LogPal
= NULL
;
892 const REAL WIDTH1
= 5;
893 const REAL HEIGHT1
= 15;
894 const REAL WIDTH2
= 10;
895 const REAL HEIGHT2
= 20;
897 union BITMAPINFOUNION bmi
;
901 stat
= GdipCreateBitmapFromHBITMAP(NULL
, NULL
, NULL
);
902 expect(InvalidParameter
, stat
);
904 hbm
= CreateBitmap(WIDTH1
, HEIGHT1
, 1, 1, NULL
);
905 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, NULL
);
906 expect(InvalidParameter
, stat
);
908 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
910 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
911 expectf(WIDTH1
, width
);
912 expectf(HEIGHT1
, height
);
914 GdipDisposeImage((GpImage
*)gpbm
);
917 memset(buff
, 0, sizeof(buff
));
918 hbm
= CreateBitmap(WIDTH2
, HEIGHT2
, 1, 1, &buff
);
919 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
922 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)gpbm
, __LINE__
, FALSE
);
924 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
925 expectf(WIDTH2
, width
);
926 expectf(HEIGHT2
, height
);
928 GdipDisposeImage((GpImage
*)gpbm
);
931 hdc
= CreateCompatibleDC(0);
932 ok(hdc
!= NULL
, "CreateCompatibleDC failed\n");
933 bmi
.bi
.bmiHeader
.biSize
= sizeof(bmi
.bi
.bmiHeader
);
934 bmi
.bi
.bmiHeader
.biHeight
= HEIGHT1
;
935 bmi
.bi
.bmiHeader
.biWidth
= WIDTH1
;
936 bmi
.bi
.bmiHeader
.biBitCount
= 24;
937 bmi
.bi
.bmiHeader
.biPlanes
= 1;
938 bmi
.bi
.bmiHeader
.biCompression
= BI_RGB
;
939 bmi
.bi
.bmiHeader
.biClrUsed
= 0;
941 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
942 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
946 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
948 expect(Ok
, GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
));
949 expectf(WIDTH1
, width
);
950 expectf(HEIGHT1
, height
);
953 /* test whether writing to the bitmap affects the original */
954 stat
= GdipBitmapSetPixel(gpbm
, 0, 0, 0xffffffff);
959 GdipDisposeImage((GpImage
*)gpbm
);
962 LogPal
= GdipAlloc(sizeof(LOGPALETTE
));
963 ok(LogPal
!= NULL
, "unable to allocate LOGPALETTE\n");
964 LogPal
->palVersion
= 0x300;
965 LogPal
->palNumEntries
= 1;
966 hpal
= CreatePalette(LogPal
);
967 ok(hpal
!= NULL
, "CreatePalette failed\n");
970 stat
= GdipCreateBitmapFromHBITMAP(hbm
, hpal
, &gpbm
);
974 GdipDisposeImage((GpImage
*)gpbm
);
979 /* 16-bit 555 dib, rgb */
980 bmi
.bi
.bmiHeader
.biBitCount
= 16;
981 bmi
.bi
.bmiHeader
.biCompression
= BI_RGB
;
983 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
984 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
988 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
993 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
995 expectf(WIDTH1
, width
);
996 expectf(HEIGHT1
, height
);
998 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1000 expect(PixelFormat16bppRGB555
, format
);
1002 GdipDisposeImage((GpImage
*)gpbm
);
1006 /* 16-bit 555 dib, with bitfields */
1007 bmi
.bi
.bmiHeader
.biSize
= sizeof(bmi
);
1008 bmi
.bi
.bmiHeader
.biCompression
= BI_BITFIELDS
;
1009 bmi
.bf
.masks
[0] = 0x7c00;
1010 bmi
.bf
.masks
[1] = 0x3e0;
1011 bmi
.bf
.masks
[2] = 0x1f;
1013 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1014 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1018 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1023 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1025 expectf(WIDTH1
, width
);
1026 expectf(HEIGHT1
, height
);
1028 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1030 expect(PixelFormat16bppRGB555
, format
);
1032 GdipDisposeImage((GpImage
*)gpbm
);
1036 /* 16-bit 565 dib, with bitfields */
1037 bmi
.bf
.masks
[0] = 0xf800;
1038 bmi
.bf
.masks
[1] = 0x7e0;
1039 bmi
.bf
.masks
[2] = 0x1f;
1041 hbm
= CreateDIBSection(hdc
, &bmi
.bi
, DIB_RGB_COLORS
, (void**)&bits
, NULL
, 0);
1042 ok(hbm
!= NULL
, "CreateDIBSection failed\n");
1046 stat
= GdipCreateBitmapFromHBITMAP(hbm
, NULL
, &gpbm
);
1051 stat
= GdipGetImageDimension((GpImage
*) gpbm
, &width
, &height
);
1053 expectf(WIDTH1
, width
);
1054 expectf(HEIGHT1
, height
);
1056 stat
= GdipGetImagePixelFormat((GpImage
*) gpbm
, &format
);
1058 expect(PixelFormat16bppRGB565
, format
);
1060 GdipDisposeImage((GpImage
*)gpbm
);
1067 static void test_GdipGetImageFlags(void)
1073 img
= (GpImage
*)0xdeadbeef;
1075 stat
= GdipGetImageFlags(NULL
, NULL
);
1076 expect(InvalidParameter
, stat
);
1078 stat
= GdipGetImageFlags(NULL
, &flags
);
1079 expect(InvalidParameter
, stat
);
1081 stat
= GdipGetImageFlags(img
, NULL
);
1082 expect(InvalidParameter
, stat
);
1084 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat1bppIndexed
, NULL
, (GpBitmap
**)&img
);
1086 stat
= GdipGetImageFlags(img
, &flags
);
1088 expect(ImageFlagsHasAlpha
, flags
);
1089 GdipDisposeImage(img
);
1091 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat4bppIndexed
, NULL
, (GpBitmap
**)&img
);
1093 stat
= GdipGetImageFlags(img
, &flags
);
1095 expect(ImageFlagsHasAlpha
, flags
);
1096 GdipDisposeImage(img
);
1098 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat8bppIndexed
, NULL
, (GpBitmap
**)&img
);
1100 stat
= GdipGetImageFlags(img
, &flags
);
1102 expect(ImageFlagsHasAlpha
, flags
);
1103 GdipDisposeImage(img
);
1105 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppGrayScale
, NULL
, (GpBitmap
**)&img
);
1107 stat
= GdipGetImageFlags(img
, &flags
);
1109 expect(ImageFlagsNone
, flags
);
1110 GdipDisposeImage(img
);
1112 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB555
, NULL
, (GpBitmap
**)&img
);
1114 stat
= GdipGetImageFlags(img
, &flags
);
1116 expect(ImageFlagsNone
, flags
);
1117 GdipDisposeImage(img
);
1119 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB565
, NULL
, (GpBitmap
**)&img
);
1121 stat
= GdipGetImageFlags(img
, &flags
);
1123 expect(ImageFlagsNone
, flags
);
1124 GdipDisposeImage(img
);
1126 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppARGB1555
, NULL
, (GpBitmap
**)&img
);
1128 stat
= GdipGetImageFlags(img
, &flags
);
1130 expect(ImageFlagsHasAlpha
, flags
);
1131 GdipDisposeImage(img
);
1133 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB
, NULL
, (GpBitmap
**)&img
);
1135 stat
= GdipGetImageFlags(img
, &flags
);
1137 expect(ImageFlagsNone
, flags
);
1138 GdipDisposeImage(img
);
1140 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&img
);
1142 stat
= GdipGetImageFlags(img
, &flags
);
1144 expect(ImageFlagsNone
, flags
);
1145 GdipDisposeImage(img
);
1147 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppARGB
, NULL
, (GpBitmap
**)&img
);
1149 stat
= GdipGetImageFlags(img
, &flags
);
1151 expect(ImageFlagsHasAlpha
, flags
);
1152 GdipDisposeImage(img
);
1154 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppPARGB
, NULL
, (GpBitmap
**)&img
);
1156 stat
= GdipGetImageFlags(img
, &flags
);
1158 expect(ImageFlagsHasAlpha
, flags
);
1159 GdipDisposeImage(img
);
1161 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat48bppRGB
, NULL
, (GpBitmap
**)&img
);
1165 stat
= GdipGetImageFlags(img
, &flags
);
1167 expect(ImageFlagsNone
, flags
);
1168 GdipDisposeImage(img
);
1171 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB
, NULL
, (GpBitmap
**)&img
);
1176 stat
= GdipGetImageFlags(img
, &flags
);
1178 expect(ImageFlagsHasAlpha
, flags
);
1179 GdipDisposeImage(img
);
1182 stat
= GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB
, NULL
, (GpBitmap
**)&img
);
1187 stat
= GdipGetImageFlags(img
, &flags
);
1189 expect(ImageFlagsHasAlpha
, flags
);
1190 GdipDisposeImage(img
);
1194 static void test_GdipCloneImage(void)
1200 GpImage
*image_src
, *image_dest
= NULL
;
1201 const INT WIDTH
= 10, HEIGHT
= 20;
1203 /* Create an image, clone it, delete the original, make sure the copy works */
1204 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
1206 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bm
, __LINE__
, FALSE
);
1208 image_src
= ((GpImage
*)bm
);
1209 stat
= GdipCloneImage(image_src
, &image_dest
);
1211 expect_rawformat(&ImageFormatMemoryBMP
, image_dest
, __LINE__
, FALSE
);
1213 stat
= GdipDisposeImage((GpImage
*)bm
);
1215 stat
= GdipGetImageBounds(image_dest
, &rectF
, &unit
);
1218 /* Treat FP values carefully */
1219 expectf((REAL
)WIDTH
, rectF
.Width
);
1220 expectf((REAL
)HEIGHT
, rectF
.Height
);
1222 stat
= GdipDisposeImage(image_dest
);
1226 static void test_testcontrol(void)
1232 stat
= GdipTestControl(TestControlGetBuildNumber
, ¶m
);
1234 ok(param
!= 0, "Build number expected, got %u\n", param
);
1237 static void test_fromhicon(void)
1239 static const BYTE bmp_bits
[1024];
1240 HBITMAP hbmMask
, hbmColor
;
1244 GpBitmap
*bitmap
= NULL
;
1250 stat
= GdipCreateBitmapFromHICON(NULL
, NULL
);
1251 expect(InvalidParameter
, stat
);
1252 stat
= GdipCreateBitmapFromHICON(NULL
, &bitmap
);
1253 expect(InvalidParameter
, stat
);
1255 /* color icon 1 bit */
1256 hbmMask
= CreateBitmap(16, 16, 1, 1, bmp_bits
);
1257 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1258 hbmColor
= CreateBitmap(16, 16, 1, 1, bmp_bits
);
1259 ok(hbmColor
!= 0, "CreateBitmap failed\n");
1263 info
.hbmMask
= hbmMask
;
1264 info
.hbmColor
= hbmColor
;
1265 hIcon
= CreateIconIndirect(&info
);
1266 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
1267 DeleteObject(hbmMask
);
1268 DeleteObject(hbmColor
);
1270 stat
= GdipCreateBitmapFromHICON(hIcon
, &bitmap
);
1272 broken(stat
== InvalidParameter
), /* Win98 */
1273 "Expected Ok, got %.8x\n", stat
);
1275 /* check attributes */
1276 stat
= GdipGetImageHeight((GpImage
*)bitmap
, &dim
);
1279 stat
= GdipGetImageWidth((GpImage
*)bitmap
, &dim
);
1282 stat
= GdipGetImageType((GpImage
*)bitmap
, &type
);
1284 expect(ImageTypeBitmap
, type
);
1285 stat
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
1287 expect(PixelFormat32bppARGB
, format
);
1289 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bitmap
, __LINE__
, FALSE
);
1290 GdipDisposeImage((GpImage
*)bitmap
);
1294 /* color icon 8 bpp */
1295 hbmMask
= CreateBitmap(16, 16, 1, 8, bmp_bits
);
1296 ok(hbmMask
!= 0, "CreateBitmap failed\n");
1297 hbmColor
= CreateBitmap(16, 16, 1, 8, bmp_bits
);
1298 ok(hbmColor
!= 0, "CreateBitmap failed\n");
1302 info
.hbmMask
= hbmMask
;
1303 info
.hbmColor
= hbmColor
;
1304 hIcon
= CreateIconIndirect(&info
);
1305 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
1306 DeleteObject(hbmMask
);
1307 DeleteObject(hbmColor
);
1309 stat
= GdipCreateBitmapFromHICON(hIcon
, &bitmap
);
1312 /* check attributes */
1313 stat
= GdipGetImageHeight((GpImage
*)bitmap
, &dim
);
1316 stat
= GdipGetImageWidth((GpImage
*)bitmap
, &dim
);
1319 stat
= GdipGetImageType((GpImage
*)bitmap
, &type
);
1321 expect(ImageTypeBitmap
, type
);
1322 stat
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
1324 expect(PixelFormat32bppARGB
, format
);
1326 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bitmap
, __LINE__
, FALSE
);
1327 GdipDisposeImage((GpImage
*)bitmap
);
1333 static const unsigned char pngimage
[285] = {
1334 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
1335 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
1336 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
1337 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
1338 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
1339 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
1340 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
1343 static const unsigned char gifimage
[35] = {
1344 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
1345 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
1348 /* 1x1 pixel transparent gif */
1349 static const unsigned char transparentgif
[] = {
1350 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,
1351 0x00,0x00,0x00,0x21,0xf9,0x04,0x01,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,
1352 0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
1355 static const unsigned char bmpimage
[66] = {
1356 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
1357 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
1358 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
1359 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
1363 static const unsigned char jpgimage
[285] = {
1364 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
1365 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
1366 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
1367 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
1368 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
1369 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
1370 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
1371 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1372 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1373 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
1374 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
1375 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1376 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
1377 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
1378 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1379 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
1380 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
1381 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
1383 /* 1x1 pixel tiff */
1384 static const unsigned char tiffimage
[] = {
1385 0x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00,
1386 0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00,
1387 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1388 0x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01,
1389 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00,
1390 0x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00,
1391 0x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01,
1392 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00,
1393 0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00,
1394 0x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01,
1395 0x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00,
1396 0x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1397 0x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
1398 0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65,
1399 0x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74,
1400 0x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,
1403 /* 320x320 twip wmf */
1404 static const unsigned char wmfimage
[180] = {
1405 0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05,
1406 0x00,0x00,0x00,0x00,0xb1,0x52,0x01,0x00,0x09,0x00,0x00,0x03,0x4f,0x00,0x00,0x00,
1407 0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0b,0x02,0x00,0x00,
1408 0x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x02,0x40,0x01,0x40,0x01,0x04,0x00,0x00,0x00,
1409 0x02,0x01,0x01,0x00,0x04,0x00,0x00,0x00,0x04,0x01,0x0d,0x00,0x08,0x00,0x00,0x00,
1410 0xfa,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
1411 0x2d,0x01,0x00,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,0x01,0x00,0x00,0x00,0x00,0x00,
1412 0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x01,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,
1413 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x02,0x00,
1414 0x07,0x00,0x00,0x00,0x1b,0x04,0x40,0x01,0x40,0x01,0x00,0x00,0x00,0x00,0x04,0x00,
1415 0x00,0x00,0xf0,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0xf0,0x01,0x01,0x00,0x03,0x00,
1418 static void test_getrawformat(void)
1420 test_bufferrawformat((void*)pngimage
, sizeof(pngimage
), &ImageFormatPNG
, __LINE__
, FALSE
);
1421 test_bufferrawformat((void*)gifimage
, sizeof(gifimage
), &ImageFormatGIF
, __LINE__
, FALSE
);
1422 test_bufferrawformat((void*)bmpimage
, sizeof(bmpimage
), &ImageFormatBMP
, __LINE__
, FALSE
);
1423 test_bufferrawformat((void*)jpgimage
, sizeof(jpgimage
), &ImageFormatJPEG
, __LINE__
, FALSE
);
1424 test_bufferrawformat((void*)tiffimage
, sizeof(tiffimage
), &ImageFormatTIFF
, __LINE__
, FALSE
);
1425 test_bufferrawformat((void*)wmfimage
, sizeof(wmfimage
), &ImageFormatWMF
, __LINE__
, FALSE
);
1428 static void test_loadwmf(void)
1439 MetafileHeader header
;
1441 hglob
= GlobalAlloc (0, sizeof(wmfimage
));
1442 data
= GlobalLock (hglob
);
1443 memcpy(data
, wmfimage
, sizeof(wmfimage
));
1444 GlobalUnlock(hglob
); data
= NULL
;
1446 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
1447 ok(hres
== S_OK
, "Failed to create a stream\n");
1448 if(hres
!= S_OK
) return;
1450 stat
= GdipLoadImageFromStream(stream
, &img
);
1451 ok(stat
== Ok
, "Failed to create a Bitmap\n");
1453 IStream_Release(stream
);
1457 IStream_Release(stream
);
1459 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1461 expect(UnitPixel
, unit
);
1462 expectf(0.0, bounds
.X
);
1463 expectf(0.0, bounds
.Y
);
1464 expectf(320.0, bounds
.Width
);
1465 expectf(320.0, bounds
.Height
);
1467 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1469 expectf(1440.0, res
);
1471 stat
= GdipGetImageVerticalResolution(img
, &res
);
1473 expectf(1440.0, res
);
1475 memset(&header
, 0, sizeof(header
));
1476 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1480 expect(MetafileTypeWmfPlaceable
, header
.Type
);
1481 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1482 todo_wine
expect(0x300, header
.Version
);
1483 expect(0, header
.EmfPlusFlags
);
1484 expectf(1440.0, header
.DpiX
);
1485 expectf(1440.0, header
.DpiY
);
1486 expect(0, header
.X
);
1487 expect(0, header
.Y
);
1488 expect(320, header
.Width
);
1489 expect(320, header
.Height
);
1490 expect(1, U(header
).WmfHeader
.mtType
);
1491 expect(0, header
.EmfPlusHeaderSize
);
1492 expect(0, header
.LogicalDpiX
);
1493 expect(0, header
.LogicalDpiY
);
1496 GdipDisposeImage(img
);
1499 static void test_createfromwmf(void)
1507 MetafileHeader header
;
1509 hwmf
= SetMetaFileBitsEx(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
),
1510 wmfimage
+sizeof(WmfPlaceableFileHeader
));
1511 ok(hwmf
!= 0, "SetMetaFileBitsEx failed\n");
1513 stat
= GdipCreateMetafileFromWmf(hwmf
, TRUE
,
1514 (WmfPlaceableFileHeader
*)wmfimage
, (GpMetafile
**)&img
);
1517 stat
= GdipGetImageBounds(img
, &bounds
, &unit
);
1519 expect(UnitPixel
, unit
);
1520 expectf(0.0, bounds
.X
);
1521 expectf(0.0, bounds
.Y
);
1522 expectf(320.0, bounds
.Width
);
1523 expectf(320.0, bounds
.Height
);
1525 stat
= GdipGetImageHorizontalResolution(img
, &res
);
1527 expectf(1440.0, res
);
1529 stat
= GdipGetImageVerticalResolution(img
, &res
);
1531 expectf(1440.0, res
);
1533 memset(&header
, 0, sizeof(header
));
1534 stat
= GdipGetMetafileHeaderFromMetafile((GpMetafile
*)img
, &header
);
1538 expect(MetafileTypeWmfPlaceable
, header
.Type
);
1539 todo_wine
expect(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
), header
.Size
);
1540 todo_wine
expect(0x300, header
.Version
);
1541 expect(0, header
.EmfPlusFlags
);
1542 expectf(1440.0, header
.DpiX
);
1543 expectf(1440.0, header
.DpiY
);
1544 expect(0, header
.X
);
1545 expect(0, header
.Y
);
1546 expect(320, header
.Width
);
1547 expect(320, header
.Height
);
1548 expect(1, U(header
).WmfHeader
.mtType
);
1549 expect(0, header
.EmfPlusHeaderSize
);
1550 expect(0, header
.LogicalDpiX
);
1551 expect(0, header
.LogicalDpiY
);
1554 GdipDisposeImage(img
);
1557 static void test_createfromwmf_noplaceable(void)
1563 hwmf
= SetMetaFileBitsEx(sizeof(wmfimage
)-sizeof(WmfPlaceableFileHeader
),
1564 wmfimage
+sizeof(WmfPlaceableFileHeader
));
1565 ok(hwmf
!= 0, "SetMetaFileBitsEx failed\n");
1567 stat
= GdipCreateMetafileFromWmf(hwmf
, TRUE
, NULL
, (GpMetafile
**)&img
);
1570 GdipDisposeImage(img
);
1573 static void test_resolution(void)
1577 GpGraphics
*graphics
;
1580 int screenxres
, screenyres
;
1583 stat
= GdipCreateBitmapFromScan0(1, 1, 32, PixelFormat24bppRGB
, NULL
, &bitmap
);
1586 /* test invalid values */
1587 stat
= GdipGetImageHorizontalResolution(NULL
, &res
);
1588 expect(InvalidParameter
, stat
);
1590 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, NULL
);
1591 expect(InvalidParameter
, stat
);
1593 stat
= GdipGetImageVerticalResolution(NULL
, &res
);
1594 expect(InvalidParameter
, stat
);
1596 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, NULL
);
1597 expect(InvalidParameter
, stat
);
1599 stat
= GdipBitmapSetResolution(NULL
, 96.0, 96.0);
1600 expect(InvalidParameter
, stat
);
1602 stat
= GdipBitmapSetResolution(bitmap
, 0.0, 0.0);
1603 expect(InvalidParameter
, stat
);
1605 /* defaults to screen resolution */
1606 screendc
= GetDC(0);
1608 screenxres
= GetDeviceCaps(screendc
, LOGPIXELSX
);
1609 screenyres
= GetDeviceCaps(screendc
, LOGPIXELSY
);
1611 ReleaseDC(0, screendc
);
1613 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1615 expectf((REAL
)screenxres
, res
);
1617 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1619 expectf((REAL
)screenyres
, res
);
1621 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1623 stat
= GdipGetDpiX(graphics
, &res
);
1625 expectf((REAL
)screenxres
, res
);
1626 stat
= GdipGetDpiY(graphics
, &res
);
1628 expectf((REAL
)screenyres
, res
);
1630 /* test changing the resolution */
1631 stat
= GdipBitmapSetResolution(bitmap
, screenxres
*2.0, screenyres
*3.0);
1634 stat
= GdipGetImageHorizontalResolution((GpImage
*)bitmap
, &res
);
1636 expectf(screenxres
*2.0, res
);
1638 stat
= GdipGetImageVerticalResolution((GpImage
*)bitmap
, &res
);
1640 expectf(screenyres
*3.0, res
);
1642 stat
= GdipGetDpiX(graphics
, &res
);
1644 expectf((REAL
)screenxres
, res
);
1645 stat
= GdipGetDpiY(graphics
, &res
);
1647 expectf((REAL
)screenyres
, res
);
1649 stat
= GdipDeleteGraphics(graphics
);
1652 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap
, &graphics
);
1654 stat
= GdipGetDpiX(graphics
, &res
);
1656 expectf(screenxres
*2.0, res
);
1657 stat
= GdipGetDpiY(graphics
, &res
);
1659 expectf(screenyres
*3.0, res
);
1660 stat
= GdipDeleteGraphics(graphics
);
1663 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1667 static void test_createhbitmap(void)
1671 HBITMAP hbitmap
, oldhbitmap
;
1677 BitmapData lockeddata
;
1679 memset(bits
, 0x68, 640);
1682 stat
= GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB
, bits
, &bitmap
);
1685 /* test NULL values */
1686 stat
= GdipCreateHBITMAPFromBitmap(NULL
, &hbitmap
, 0);
1687 expect(InvalidParameter
, stat
);
1689 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, NULL
, 0);
1690 expect(InvalidParameter
, stat
);
1692 /* create HBITMAP */
1693 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1698 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1699 expect(sizeof(BITMAP
), ret
);
1701 expect(0, bm
.bmType
);
1702 expect(10, bm
.bmWidth
);
1703 expect(20, bm
.bmHeight
);
1704 expect(40, bm
.bmWidthBytes
);
1705 expect(1, bm
.bmPlanes
);
1706 expect(32, bm
.bmBitsPixel
);
1707 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1711 DWORD val
= *(DWORD
*)bm
.bmBits
;
1712 ok(val
== 0xff686868, "got %x, expected 0xff686868\n", val
);
1715 hdc
= CreateCompatibleDC(NULL
);
1717 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1718 pixel
= GetPixel(hdc
, 5, 5);
1719 SelectObject(hdc
, oldhbitmap
);
1723 expect(0x686868, pixel
);
1725 DeleteObject(hbitmap
);
1728 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1731 /* make (1,0) have no alpha and (2,0) a different blue value. */
1735 /* create alpha Bitmap */
1736 stat
= GdipCreateBitmapFromScan0(8, 20, 32, PixelFormat32bppARGB
, bits
, &bitmap
);
1739 /* create HBITMAP */
1740 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1745 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1746 expect(sizeof(BITMAP
), ret
);
1748 expect(0, bm
.bmType
);
1749 expect(8, bm
.bmWidth
);
1750 expect(20, bm
.bmHeight
);
1751 expect(32, bm
.bmWidthBytes
);
1752 expect(1, bm
.bmPlanes
);
1753 expect(32, bm
.bmBitsPixel
);
1754 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1758 DWORD val
= *(DWORD
*)bm
.bmBits
;
1759 ok(val
== 0x682a2a2a, "got %x, expected 0x682a2a2a\n", val
);
1760 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1761 ok(val
== 0x0, "got %x, expected 0x682a2a2a\n", val
);
1764 hdc
= CreateCompatibleDC(NULL
);
1766 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1767 pixel
= GetPixel(hdc
, 5, 5);
1768 expect(0x2a2a2a, pixel
);
1769 pixel
= GetPixel(hdc
, 1, 0);
1772 SelectObject(hdc
, oldhbitmap
);
1777 DeleteObject(hbitmap
);
1780 /* create HBITMAP with bkgnd colour */
1781 /* gdiplus.dll 5.1 is broken and only applies the blue value */
1782 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0xff00ff);
1787 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1788 expect(sizeof(BITMAP
), ret
);
1790 expect(0, bm
.bmType
);
1791 expect(8, bm
.bmWidth
);
1792 expect(20, bm
.bmHeight
);
1793 expect(32, bm
.bmWidthBytes
);
1794 expect(1, bm
.bmPlanes
);
1795 expect(32, bm
.bmBitsPixel
);
1796 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1800 DWORD val
= *(DWORD
*)bm
.bmBits
;
1801 ok(val
== 0x68c12ac1 || broken(val
== 0x682a2ac1), "got %x, expected 0x68c12ac1\n", val
);
1802 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1803 ok(val
== 0xff00ff || broken(val
== 0xff), "got %x, expected 0xff00ff\n", val
);
1806 hdc
= CreateCompatibleDC(NULL
);
1808 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1809 pixel
= GetPixel(hdc
, 5, 5);
1810 ok(pixel
== 0xc12ac1 || broken(pixel
== 0xc12a2a), "got %x, expected 0xc12ac1\n", pixel
);
1811 pixel
= GetPixel(hdc
, 1, 0);
1812 ok(pixel
== 0xff00ff || broken(pixel
== 0xff0000), "got %x, expected 0xff00ff\n", pixel
);
1813 pixel
= GetPixel(hdc
, 2, 0);
1814 ok(pixel
== 0xb12ac1 || broken(pixel
== 0xb12a2a), "got %x, expected 0xb12ac1\n", pixel
);
1816 SelectObject(hdc
, oldhbitmap
);
1818 DeleteObject(hbitmap
);
1821 /* create HBITMAP with bkgnd colour with alpha and show it behaves with no alpha. */
1822 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0x80ff00ff);
1827 ret
= GetObjectA(hbitmap
, sizeof(BITMAP
), &bm
);
1828 expect(sizeof(BITMAP
), ret
);
1830 expect(0, bm
.bmType
);
1831 expect(8, bm
.bmWidth
);
1832 expect(20, bm
.bmHeight
);
1833 expect(32, bm
.bmWidthBytes
);
1834 expect(1, bm
.bmPlanes
);
1835 expect(32, bm
.bmBitsPixel
);
1836 ok(bm
.bmBits
!= NULL
, "got DDB, expected DIB\n");
1840 DWORD val
= *(DWORD
*)bm
.bmBits
;
1841 ok(val
== 0x68c12ac1 || broken(val
== 0x682a2ac1), "got %x, expected 0x68c12ac1\n", val
);
1842 val
= *((DWORD
*)bm
.bmBits
+ (bm
.bmHeight
-1) * bm
.bmWidthBytes
/4 + 1);
1843 ok(val
== 0xff00ff || broken(val
== 0xff), "got %x, expected 0xff00ff\n", val
);
1846 hdc
= CreateCompatibleDC(NULL
);
1848 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1849 pixel
= GetPixel(hdc
, 5, 5);
1850 ok(pixel
== 0xc12ac1 || broken(pixel
== 0xc12a2a), "got %x, expected 0xc12ac1\n", pixel
);
1851 pixel
= GetPixel(hdc
, 1, 0);
1852 ok(pixel
== 0xff00ff || broken(pixel
== 0xff0000), "got %x, expected 0xff00ff\n", pixel
);
1853 pixel
= GetPixel(hdc
, 2, 0);
1854 ok(pixel
== 0xb12ac1 || broken(pixel
== 0xb12a2a), "got %x, expected 0xb12ac1\n", pixel
);
1856 SelectObject(hdc
, oldhbitmap
);
1858 DeleteObject(hbitmap
);
1861 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1864 /* create HBITMAP from locked data */
1865 memset(bits
, 0x68, 640);
1866 stat
= GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB
, bits
, &bitmap
);
1869 memset(&lockeddata
, 0, sizeof(lockeddata
));
1870 stat
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
| ImageLockModeWrite
,
1871 PixelFormat32bppRGB
, &lockeddata
);
1873 ((DWORD
*)lockeddata
.Scan0
)[0] = 0xff242424;
1874 stat
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
1876 stat
= GdipBitmapUnlockBits(bitmap
, &lockeddata
);
1878 stat
= GdipDisposeImage((GpImage
*)bitmap
);
1881 hdc
= CreateCompatibleDC(NULL
);
1882 oldhbitmap
= SelectObject(hdc
, hbitmap
);
1883 pixel
= GetPixel(hdc
, 0, 0);
1884 expect(0x686868, pixel
);
1885 SelectObject(hdc
, oldhbitmap
);
1889 static void test_getthumbnail(void)
1892 GpImage
*bitmap1
, *bitmap2
;
1895 stat
= GdipGetImageThumbnail(NULL
, 0, 0, &bitmap2
, NULL
, NULL
);
1896 expect(InvalidParameter
, stat
);
1898 stat
= GdipCreateBitmapFromScan0(128, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1901 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, NULL
, NULL
, NULL
);
1902 expect(InvalidParameter
, stat
);
1904 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, &bitmap2
, NULL
, NULL
);
1909 stat
= GdipGetImageWidth(bitmap2
, &width
);
1913 stat
= GdipGetImageHeight(bitmap2
, &height
);
1915 expect(120, height
);
1917 GdipDisposeImage(bitmap2
);
1920 GdipDisposeImage(bitmap1
);
1923 stat
= GdipCreateBitmapFromScan0(64, 128, 0, PixelFormat32bppRGB
, NULL
, (GpBitmap
**)&bitmap1
);
1926 stat
= GdipGetImageThumbnail(bitmap1
, 32, 32, &bitmap2
, NULL
, NULL
);
1931 stat
= GdipGetImageWidth(bitmap2
, &width
);
1935 stat
= GdipGetImageHeight(bitmap2
, &height
);
1939 GdipDisposeImage(bitmap2
);
1942 stat
= GdipGetImageThumbnail(bitmap1
, 0, 0, &bitmap2
, NULL
, NULL
);
1947 stat
= GdipGetImageWidth(bitmap2
, &width
);
1951 stat
= GdipGetImageHeight(bitmap2
, &height
);
1953 expect(120, height
);
1955 GdipDisposeImage(bitmap2
);
1958 GdipDisposeImage(bitmap1
);
1961 static void test_getsetpixel(void)
1966 BYTE bits
[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00,
1967 0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00};
1969 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, bits
, &bitmap
);
1972 /* null parameters */
1973 stat
= GdipBitmapGetPixel(NULL
, 1, 1, &color
);
1974 expect(InvalidParameter
, stat
);
1976 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, NULL
);
1977 expect(InvalidParameter
, stat
);
1979 stat
= GdipBitmapSetPixel(NULL
, 1, 1, 0);
1980 expect(InvalidParameter
, stat
);
1983 stat
= GdipBitmapGetPixel(bitmap
, -1, 1, &color
);
1984 expect(InvalidParameter
, stat
);
1986 stat
= GdipBitmapSetPixel(bitmap
, -1, 1, 0);
1987 expect(InvalidParameter
, stat
);
1989 stat
= GdipBitmapGetPixel(bitmap
, 1, -1, &color
);
1990 ok(stat
== InvalidParameter
||
1991 broken(stat
== Ok
), /* Older gdiplus */
1992 "Expected InvalidParameter, got %.8x\n", stat
);
1994 if (0) /* crashes some gdiplus implementations */
1996 stat
= GdipBitmapSetPixel(bitmap
, 1, -1, 0);
1997 ok(stat
== InvalidParameter
||
1998 broken(stat
== Ok
), /* Older gdiplus */
1999 "Expected InvalidParameter, got %.8x\n", stat
);
2002 stat
= GdipBitmapGetPixel(bitmap
, 2, 1, &color
);
2003 expect(InvalidParameter
, stat
);
2005 stat
= GdipBitmapSetPixel(bitmap
, 2, 1, 0);
2006 expect(InvalidParameter
, stat
);
2008 stat
= GdipBitmapGetPixel(bitmap
, 1, 2, &color
);
2009 expect(InvalidParameter
, stat
);
2011 stat
= GdipBitmapSetPixel(bitmap
, 1, 2, 0);
2012 expect(InvalidParameter
, stat
);
2015 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
2017 expect(0xffffffff, color
);
2019 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2021 expect(0xff0000ff, color
);
2023 stat
= GdipBitmapSetPixel(bitmap
, 1, 1, 0xff676869);
2026 stat
= GdipBitmapSetPixel(bitmap
, 0, 0, 0xff474849);
2029 stat
= GdipBitmapGetPixel(bitmap
, 1, 1, &color
);
2031 expect(0xff676869, color
);
2033 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2035 expect(0xff474849, color
);
2037 stat
= GdipDisposeImage((GpImage
*)bitmap
);
2041 static void check_halftone_palette(ColorPalette
*palette
)
2043 static const BYTE halftone_values
[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
2046 for (i
=0; i
<palette
->Count
; i
++)
2048 ARGB expected
=0xff000000;
2051 if (i
&1) expected
|= 0x800000;
2052 if (i
&2) expected
|= 0x8000;
2053 if (i
&4) expected
|= 0x80;
2057 expected
= 0xffc0c0c0;
2061 if (i
&1) expected
|= 0xff0000;
2062 if (i
&2) expected
|= 0xff00;
2063 if (i
&4) expected
|= 0xff;
2067 expected
= 0x00000000;
2071 expected
|= halftone_values
[(i
-40)%6];
2072 expected
|= halftone_values
[((i
-40)/6)%6] << 8;
2073 expected
|= halftone_values
[((i
-40)/36)%6] << 16;
2075 ok(expected
== palette
->Entries
[i
], "Expected %.8x, got %.8x, i=%u/%u\n",
2076 expected
, palette
->Entries
[i
], i
, palette
->Count
);
2080 static void test_palette(void)
2086 ColorPalette
*palette
=(ColorPalette
*)buffer
;
2087 ARGB
*entries
= palette
->Entries
;
2090 /* test initial palette from non-indexed bitmap */
2091 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB
, NULL
, &bitmap
);
2094 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2096 expect(sizeof(UINT
)*2+sizeof(ARGB
), size
);
2098 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2100 expect(0, palette
->Count
);
2102 /* test setting palette on not-indexed bitmap */
2105 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2108 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2110 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2112 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2114 expect(3, palette
->Count
);
2116 GdipDisposeImage((GpImage
*)bitmap
);
2118 /* test initial palette on 1-bit bitmap */
2119 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat1bppIndexed
, NULL
, &bitmap
);
2122 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2124 expect(sizeof(UINT
)*2+sizeof(ARGB
)*2, size
);
2126 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2128 expect(PaletteFlagsGrayScale
, palette
->Flags
);
2129 expect(2, palette
->Count
);
2131 expect(0xff000000, entries
[0]);
2132 expect(0xffffffff, entries
[1]);
2134 /* test getting/setting pixels */
2135 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2137 expect(0xff000000, color
);
2139 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffffffff);
2141 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2145 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2147 expect(0xffffffff, color
);
2150 GdipDisposeImage((GpImage
*)bitmap
);
2152 /* test initial palette on 4-bit bitmap */
2153 stat
= GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat4bppIndexed
, NULL
, &bitmap
);
2156 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2158 expect(sizeof(UINT
)*2+sizeof(ARGB
)*16, size
);
2160 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2162 expect(0, palette
->Flags
);
2163 expect(16, palette
->Count
);
2165 check_halftone_palette(palette
);
2167 /* test getting/setting pixels */
2168 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2170 expect(0xff000000, color
);
2172 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffff00ff);
2174 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2178 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2180 expect(0xffff00ff, color
);
2183 GdipDisposeImage((GpImage
*)bitmap
);
2185 /* test initial palette on 8-bit bitmap */
2186 stat
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat8bppIndexed
, NULL
, &bitmap
);
2189 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2191 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2193 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2195 expect(PaletteFlagsHalftone
, palette
->Flags
);
2196 expect(256, palette
->Count
);
2198 check_halftone_palette(palette
);
2200 /* test getting/setting pixels */
2201 stat
= GdipBitmapGetPixel(bitmap
, 0, 0, &color
);
2203 expect(0xff000000, color
);
2205 stat
= GdipBitmapSetPixel(bitmap
, 0, 1, 0xffcccccc);
2207 broken(stat
== InvalidParameter
) /* pre-win7 */, "stat=%.8x\n", stat
);
2211 stat
= GdipBitmapGetPixel(bitmap
, 0, 1, &color
);
2213 expect(0xffcccccc, color
);
2216 /* test setting/getting a different palette */
2217 entries
[1] = 0xffcccccc;
2219 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2224 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2226 expect(sizeof(UINT
)*2+sizeof(ARGB
)*256, size
);
2228 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2230 expect(PaletteFlagsHalftone
, palette
->Flags
);
2231 expect(256, palette
->Count
);
2232 expect(0xffcccccc, entries
[1]);
2234 /* test count < 256 */
2235 palette
->Flags
= 12345;
2238 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2242 entries
[3] = 0xdeadbeef;
2244 stat
= GdipGetImagePaletteSize((GpImage
*)bitmap
, &size
);
2246 expect(sizeof(UINT
)*2+sizeof(ARGB
)*3, size
);
2248 stat
= GdipGetImagePalette((GpImage
*)bitmap
, palette
, size
);
2250 expect(12345, palette
->Flags
);
2251 expect(3, palette
->Count
);
2252 expect(0xffcccccc, entries
[1]);
2253 expect(0xdeadbeef, entries
[3]);
2255 /* test count > 256 */
2256 palette
->Count
= 257;
2258 stat
= GdipSetImagePalette((GpImage
*)bitmap
, palette
);
2259 ok(stat
== InvalidParameter
||
2260 broken(stat
== Ok
), /* Old gdiplus behavior */
2261 "Expected %.8x, got %.8x\n", InvalidParameter
, stat
);
2263 GdipDisposeImage((GpImage
*)bitmap
);
2266 static void test_colormatrix(void)
2269 ColorMatrix colormatrix
, graymatrix
;
2270 GpImageAttributes
*imageattr
;
2271 const ColorMatrix identity
= {{
2272 {1.0,0.0,0.0,0.0,0.0},
2273 {0.0,1.0,0.0,0.0,0.0},
2274 {0.0,0.0,1.0,0.0,0.0},
2275 {0.0,0.0,0.0,1.0,0.0},
2276 {0.0,0.0,0.0,0.0,1.0}}};
2277 const ColorMatrix double_red
= {{
2278 {2.0,0.0,0.0,0.0,0.0},
2279 {0.0,1.0,0.0,0.0,0.0},
2280 {0.0,0.0,1.0,0.0,0.0},
2281 {0.0,0.0,0.0,1.0,0.0},
2282 {0.0,0.0,0.0,0.0,1.0}}};
2283 const ColorMatrix asymmetric
= {{
2284 {0.0,1.0,0.0,0.0,0.0},
2285 {0.0,0.0,1.0,0.0,0.0},
2286 {0.0,0.0,0.0,1.0,0.0},
2287 {1.0,0.0,0.0,0.0,0.0},
2288 {0.0,0.0,0.0,0.0,1.0}}};
2289 GpBitmap
*bitmap1
, *bitmap2
;
2290 GpGraphics
*graphics
;
2293 colormatrix
= identity
;
2294 graymatrix
= identity
;
2296 stat
= GdipSetImageAttributesColorMatrix(NULL
, ColorAdjustTypeDefault
,
2297 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2298 expect(InvalidParameter
, stat
);
2300 stat
= GdipCreateImageAttributes(&imageattr
);
2303 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2304 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2307 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2308 TRUE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2309 expect(InvalidParameter
, stat
);
2311 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2312 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2315 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2316 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsSkipGrays
);
2319 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2320 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsAltGray
);
2321 expect(InvalidParameter
, stat
);
2323 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2324 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsAltGray
);
2327 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2328 TRUE
, &colormatrix
, &graymatrix
, 3);
2329 expect(InvalidParameter
, stat
);
2331 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeCount
,
2332 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2333 expect(InvalidParameter
, stat
);
2335 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeAny
,
2336 TRUE
, &colormatrix
, &graymatrix
, ColorMatrixFlagsDefault
);
2337 expect(InvalidParameter
, stat
);
2339 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2340 FALSE
, NULL
, NULL
, ColorMatrixFlagsDefault
);
2343 /* Drawing a bitmap transforms the colors */
2344 colormatrix
= double_red
;
2345 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2346 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2349 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
2352 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
2355 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff40ccee);
2358 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2361 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2362 UnitPixel
, imageattr
, NULL
, NULL
);
2365 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2367 expect(0xff80ccee, color
);
2369 colormatrix
= asymmetric
;
2370 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2371 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2374 stat
= GdipBitmapSetPixel(bitmap2
, 0, 0, 0);
2377 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2378 UnitPixel
, imageattr
, NULL
, NULL
);
2381 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2383 ok(color_match(0xeeff40cc, color
, 3), "expected 0xeeff40cc, got 0x%08x\n", color
);
2386 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeDefault
, FALSE
);
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(0xfefe40cc, color
, 3), "expected 0xfefe40cc, got 0x%08x\n", color
);
2397 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeDefault
, TRUE
);
2400 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2401 UnitPixel
, imageattr
, NULL
, NULL
);
2404 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2406 ok(color_match(0xff40ccee, color
, 3), "expected 0xff40ccee, got 0x%08x\n", color
);
2408 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2411 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeDefault
, FALSE
);
2414 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2415 UnitPixel
, imageattr
, NULL
, NULL
);
2418 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2420 ok(color_match(0xff40ccee, color
, 3), "expected 0xff40ccee, got 0x%08x\n", color
);
2422 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2423 UnitPixel
, imageattr
, NULL
, NULL
);
2426 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2428 ok(color_match(0xff40ccee, color
, 1), "Expected ff40ccee, got %.8x\n", color
);
2430 /* Disable adjustment, toggle NoOp */
2431 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2432 FALSE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2435 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeDefault
, FALSE
);
2438 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2439 UnitPixel
, imageattr
, NULL
, NULL
);
2442 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2444 ok(color_match(0xff40ccee, color
, 3), "expected 0xff40ccee, got 0x%08x\n", color
);
2446 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeDefault
, TRUE
);
2449 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2450 UnitPixel
, imageattr
, NULL
, NULL
);
2453 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2455 ok(color_match(0xff40ccee, color
, 3), "expected 0xff40ccee, got 0x%08x\n", color
);
2457 /* Reset with NoOp on, enable adjustment. */
2458 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2461 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeDefault
,
2462 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2465 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2466 UnitPixel
, imageattr
, NULL
, NULL
);
2469 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2471 ok(color_match(0xfff24ace, color
, 3), "expected 0xfff24ace, got 0x%08x\n", color
);
2473 /* Now inhibit specific category. */
2474 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2477 stat
= GdipSetImageAttributesColorMatrix(imageattr
, ColorAdjustTypeBitmap
,
2478 TRUE
, &colormatrix
, NULL
, ColorMatrixFlagsDefault
);
2481 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2482 UnitPixel
, imageattr
, NULL
, NULL
);
2485 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2487 ok(color_match(0xfffe41cc, color
, 3), "expected 0xfffe41cc, got 0x%08x\n", color
);
2489 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeBitmap
, TRUE
);
2492 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2493 UnitPixel
, imageattr
, NULL
, NULL
);
2496 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2498 ok(color_match(0xff40ccee, color
, 3), "expected 0xff40ccee, got 0x%08x\n", color
);
2500 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeBitmap
, FALSE
);
2503 stat
= GdipSetImageAttributesNoOp(imageattr
, ColorAdjustTypeDefault
, TRUE
);
2506 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2507 UnitPixel
, imageattr
, NULL
, NULL
);
2510 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2512 ok(color_match(0xfff24ace, color
, 3), "expected 0xfff24ace, got 0x%08x\n", color
);
2514 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeBitmap
);
2517 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0, 0, 1, 1, 0, 0, 1, 1,
2518 UnitPixel
, imageattr
, NULL
, NULL
);
2521 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2523 ok(color_match(0xff40ccee, color
, 3), "expected 0xff40ccee, got 0x%08x\n", color
);
2525 GdipDeleteGraphics(graphics
);
2526 GdipDisposeImage((GpImage
*)bitmap1
);
2527 GdipDisposeImage((GpImage
*)bitmap2
);
2528 GdipDisposeImageAttributes(imageattr
);
2531 static void test_gamma(void)
2534 GpImageAttributes
*imageattr
;
2535 GpBitmap
*bitmap1
, *bitmap2
;
2536 GpGraphics
*graphics
;
2539 stat
= GdipSetImageAttributesGamma(NULL
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2540 expect(InvalidParameter
, stat
);
2542 stat
= GdipCreateImageAttributes(&imageattr
);
2545 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1.0);
2548 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeAny
, TRUE
, 1.0);
2549 expect(InvalidParameter
, stat
);
2551 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, -1.0);
2552 expect(InvalidParameter
, stat
);
2554 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.0);
2555 expect(InvalidParameter
, stat
);
2557 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0.5);
2560 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0.0);
2563 /* Drawing a bitmap transforms the colors */
2564 stat
= GdipSetImageAttributesGamma(imageattr
, ColorAdjustTypeDefault
, TRUE
, 3.0);
2567 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
2570 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
2573 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff80ffff);
2576 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
2579 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2580 UnitPixel
, imageattr
, NULL
, NULL
);
2583 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2585 ok(color_match(0xff20ffff, color
, 1), "Expected ff20ffff, got %.8x\n", color
);
2587 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
2590 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
2591 UnitPixel
, imageattr
, NULL
, NULL
);
2594 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
2596 ok(color_match(0xff80ffff, color
, 1), "Expected ff80ffff, got %.8x\n", color
);
2598 GdipDeleteGraphics(graphics
);
2599 GdipDisposeImage((GpImage
*)bitmap1
);
2600 GdipDisposeImage((GpImage
*)bitmap2
);
2601 GdipDisposeImageAttributes(imageattr
);
2604 /* 1x1 pixel gif, 2 frames; first frame is white, second is black */
2605 static const unsigned char gifanimation
[72] = {
2606 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
2607 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0xf9,0x04,0x00,0x0a,0x00,0xff,
2608 0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x4c,0x01,0x00,
2609 0x21,0xf9,0x04,0x01,0x0a,0x00,0x01,0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,
2610 0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
2613 /* Generated with ImageMagick:
2614 * convert -transparent black -delay 100 -size 8x2 xc:black \
2615 * -dispose none -page +0+0 -size 2x2 xc:red \
2616 * -dispose background -page +2+0 -size 2x2 xc:blue \
2617 * -dispose previous -page +4+0 -size 2x2 xc:green \
2618 * -dispose undefined -page +6+0 -size 2x2 xc:gray \
2621 static const unsigned char gifanimation2
[] = {
2622 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x08, 0x00,
2623 0x02, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
2624 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x64,
2625 0x00, 0x00, 0x00, 0x21, 0xff, 0x0b, 0x4e, 0x45,
2626 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e,
2627 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00,
2628 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
2629 0x02, 0x04, 0x84, 0x8f, 0x09, 0x05, 0x00, 0x21,
2630 0xf9, 0x04, 0x04, 0x64, 0x00, 0x00, 0x00, 0x2c,
2631 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2632 0x81, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
2633 0x00, 0x00, 0xff, 0x00, 0x00, 0x02, 0x03, 0x44,
2634 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x08, 0x64,
2635 0x00, 0x00, 0x00, 0x2c, 0x02, 0x00, 0x00, 0x00,
2636 0x02, 0x00, 0x02, 0x00, 0x81, 0x00, 0x00, 0xff,
2637 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
2638 0xff, 0x02, 0x03, 0x44, 0x34, 0x05, 0x00, 0x21,
2639 0xf9, 0x04, 0x0c, 0x64, 0x00, 0x00, 0x00, 0x2c,
2640 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2641 0x81, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00,
2642 0x80, 0x00, 0x00, 0x80, 0x00, 0x02, 0x03, 0x44,
2643 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x64,
2644 0x00, 0x00, 0x00, 0x2c, 0x06, 0x00, 0x00, 0x00,
2645 0x02, 0x00, 0x02, 0x00, 0x80, 0x7e, 0x7e, 0x7e,
2646 0x00, 0x00, 0x00, 0x02, 0x02, 0x84, 0x51, 0x00,
2650 static ARGB gifanimation2_pixels
[5][4] = {
2652 {0xffff0000, 0, 0, 0},
2653 {0xffff0000, 0xff0000ff, 0, 0},
2654 {0xffff0000, 0, 0xff008000, 0},
2655 {0xffff0000, 0, 0, 0xff7e7e7e}
2658 static void test_multiframegif(void)
2669 PixelFormat pixel_format
;
2670 INT palette_size
, i
, j
;
2671 char palette_buf
[256];
2672 ColorPalette
*palette
;
2673 ARGB
*palette_entries
;
2675 /* Test frame functions with an animated GIF */
2676 hglob
= GlobalAlloc (0, sizeof(gifanimation
));
2677 data
= GlobalLock (hglob
);
2678 memcpy(data
, gifanimation
, sizeof(gifanimation
));
2679 GlobalUnlock(hglob
);
2681 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2682 ok(hres
== S_OK
, "Failed to create a stream\n");
2683 if(hres
!= S_OK
) return;
2685 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2686 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2688 IStream_Release(stream
);
2692 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2694 expect(PixelFormat32bppARGB
, pixel_format
);
2696 stat
= GdipGetImagePaletteSize((GpImage
*)bmp
, &palette_size
);
2698 ok(palette_size
== sizeof(ColorPalette
) ||
2699 broken(palette_size
== sizeof(ColorPalette
)+sizeof(ARGB
[3])),
2700 "palette_size = %d\n", palette_size
);
2702 /* Bitmap starts at frame 0 */
2704 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2706 expect(0xffffffff, color
);
2708 /* Check that we get correct metadata */
2709 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2713 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2715 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2718 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2722 /* SelectActiveFrame overwrites our current data */
2723 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2727 GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2729 expect(0xff000000, color
);
2731 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2735 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2737 expect(0xffffffff, color
);
2739 /* Write over the image data */
2740 stat
= GdipBitmapSetPixel(bmp
, 0, 0, 0xff000000);
2743 /* Switching to the same frame does not overwrite our changes */
2744 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2747 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2749 expect(0xff000000, color
);
2751 /* But switching to another frame and back does */
2752 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 1);
2755 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 0);
2758 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2760 expect(0xffffffff, color
);
2762 /* rotate/flip discards the information about other frames */
2763 stat
= GdipImageRotateFlip((GpImage
*)bmp
, Rotate90FlipNone
);
2767 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2771 expect_rawformat(&ImageFormatMemoryBMP
, (GpImage
*)bmp
, __LINE__
, FALSE
);
2773 GdipDisposeImage((GpImage
*)bmp
);
2774 IStream_Release(stream
);
2776 /* Test with a non-animated gif */
2777 hglob
= GlobalAlloc (0, sizeof(gifimage
));
2778 data
= GlobalLock (hglob
);
2779 memcpy(data
, gifimage
, sizeof(gifimage
));
2780 GlobalUnlock(hglob
);
2782 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2783 ok(hres
== S_OK
, "Failed to create a stream\n");
2784 if(hres
!= S_OK
) return;
2786 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2787 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2789 IStream_Release(stream
);
2793 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2795 expect(PixelFormat8bppIndexed
, pixel_format
);
2797 /* Check metadata */
2798 stat
= GdipImageGetFrameDimensionsCount((GpImage
*)bmp
,&count
);
2802 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2804 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2807 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2811 GdipDisposeImage((GpImage
*)bmp
);
2812 IStream_Release(stream
);
2814 /* Test with a non-animated transparent gif */
2815 hglob
= GlobalAlloc (0, sizeof(transparentgif
));
2816 data
= GlobalLock (hglob
);
2817 memcpy(data
, transparentgif
, sizeof(transparentgif
));
2818 GlobalUnlock(hglob
);
2820 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2821 ok(hres
== S_OK
, "Failed to create a stream\n");
2823 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2824 IStream_Release(stream
);
2825 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2827 stat
= GdipGetImagePixelFormat((GpImage
*)bmp
, &pixel_format
);
2829 expect(PixelFormat8bppIndexed
, pixel_format
);
2831 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2835 stat
= GdipGetImagePaletteSize((GpImage
*)bmp
, &palette_size
);
2837 ok(palette_size
== sizeof(ColorPalette
)+sizeof(ARGB
),
2838 "palette_size = %d\n", palette_size
);
2840 memset(palette_buf
, 0xfe, sizeof(palette_buf
));
2841 palette
= (ColorPalette
*)palette_buf
;
2842 stat
= GdipGetImagePalette((GpImage
*)bmp
, palette
,
2843 sizeof(ColorPalette
)+sizeof(ARGB
));
2844 palette_entries
= palette
->Entries
;
2846 expect(PaletteFlagsHasAlpha
, palette
->Flags
);
2847 expect(2, palette
->Count
);
2848 expect(0, palette_entries
[0]);
2849 expect(0xff000000, palette_entries
[1]);
2852 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2856 GdipDisposeImage((GpImage
*)bmp
);
2858 /* Test frame dispose methods */
2859 hglob
= GlobalAlloc (0, sizeof(gifanimation2
));
2860 data
= GlobalLock (hglob
);
2861 memcpy(data
, gifanimation2
, sizeof(gifanimation2
));
2862 GlobalUnlock(hglob
);
2864 hres
= CreateStreamOnHGlobal(hglob
, TRUE
, &stream
);
2865 ok(hres
== S_OK
, "Failed to create a stream\n");
2867 stat
= GdipCreateBitmapFromStream(stream
, &bmp
);
2868 ok(stat
== Ok
, "Failed to create a Bitmap\n");
2869 IStream_Release(stream
);
2871 stat
= GdipImageGetFrameDimensionsList((GpImage
*)bmp
, &dimension
, 1);
2873 expect_guid(&FrameDimensionTime
, &dimension
, __LINE__
, FALSE
);
2875 stat
= GdipImageGetFrameCount((GpImage
*)bmp
, &dimension
, &count
);
2879 stat
= GdipBitmapGetPixel(bmp
, 0, 0, &color
);
2883 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, 3);
2885 stat
= GdipBitmapGetPixel(bmp
, 2, 0, &color
);
2887 ok(color
==0 || broken(color
==0xff0000ff), "color = %x\n", color
);
2889 win_skip("broken animated gif support\n");
2890 GdipDisposeImage((GpImage
*)bmp
);
2894 for(i
=0; i
<6; i
++) {
2895 stat
= GdipImageSelectActiveFrame((GpImage
*)bmp
, &dimension
, i
%5);
2898 for(j
=0; j
<4; j
++) {
2899 stat
= GdipBitmapGetPixel(bmp
, j
*2, 0, &color
);
2901 ok(gifanimation2_pixels
[i
%5][j
] == color
, "at %d,%d got %x, expected %x\n", i
, j
, color
, gifanimation2_pixels
[i
%5][j
]);
2905 GdipDisposeImage((GpImage
*)bmp
);
2908 static void test_rotateflip(void)
2913 static const BYTE orig_bits
[24] = {
2914 0,0,0xff, 0,0xff,0, 0xff,0,0, 23,23,23,
2915 0xff,0xff,0, 0xff,0,0xff, 0,0xff,0xff, 23,23,23};
2919 memcpy(bits
, orig_bits
, sizeof(bits
));
2920 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2923 stat
= GdipImageRotateFlip(bitmap
, Rotate90FlipNone
);
2926 stat
= GdipGetImageWidth(bitmap
, &width
);
2928 stat
= GdipGetImageHeight(bitmap
, &height
);
2933 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2935 expect(0xff00ffff, color
);
2937 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 0, &color
);
2939 expect(0xffff0000, color
);
2941 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 2, &color
);
2943 expect(0xffffff00, color
);
2945 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 1, 2, &color
);
2947 expect(0xff0000ff, color
);
2951 expect(0xff, bits
[2]);
2953 GdipDisposeImage(bitmap
);
2955 memcpy(bits
, orig_bits
, sizeof(bits
));
2956 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2959 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipX
);
2962 stat
= GdipGetImageWidth(bitmap
, &width
);
2964 stat
= GdipGetImageHeight(bitmap
, &height
);
2969 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
2971 expect(0xff0000ff, color
);
2973 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
2975 expect(0xffff0000, color
);
2977 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
2979 expect(0xffffff00, color
);
2981 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
2983 expect(0xff00ffff, color
);
2987 expect(0xff, bits
[2]);
2989 GdipDisposeImage(bitmap
);
2991 memcpy(bits
, orig_bits
, sizeof(bits
));
2992 stat
= GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB
, bits
, (GpBitmap
**)&bitmap
);
2995 stat
= GdipImageRotateFlip(bitmap
, RotateNoneFlipY
);
2998 stat
= GdipGetImageWidth(bitmap
, &width
);
3000 stat
= GdipGetImageHeight(bitmap
, &height
);
3005 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 0, &color
);
3007 expect(0xff00ffff, color
);
3009 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 0, &color
);
3011 expect(0xffffff00, color
);
3013 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 0, 1, &color
);
3015 expect(0xffff0000, color
);
3017 stat
= GdipBitmapGetPixel((GpBitmap
*)bitmap
, 2, 1, &color
);
3019 expect(0xff0000ff, color
);
3023 expect(0xff, bits
[2]);
3025 GdipDisposeImage(bitmap
);
3028 static void test_remaptable(void)
3031 GpImageAttributes
*imageattr
;
3032 GpBitmap
*bitmap1
, *bitmap2
;
3033 GpGraphics
*graphics
;
3037 map
= GdipAlloc(sizeof(ColorMap
));
3039 map
->oldColor
.Argb
= 0xff00ff00;
3040 map
->newColor
.Argb
= 0xffff00ff;
3042 stat
= GdipSetImageAttributesRemapTable(NULL
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
3043 expect(InvalidParameter
, stat
);
3045 stat
= GdipCreateImageAttributes(&imageattr
);
3048 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, NULL
);
3049 expect(InvalidParameter
, stat
);
3051 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeCount
, TRUE
, 1, map
);
3052 expect(InvalidParameter
, stat
);
3054 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeAny
, TRUE
, 1, map
);
3055 expect(InvalidParameter
, stat
);
3057 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0, map
);
3058 expect(InvalidParameter
, stat
);
3060 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, FALSE
, 0, NULL
);
3063 stat
= GdipSetImageAttributesRemapTable(imageattr
, ColorAdjustTypeDefault
, TRUE
, 1, map
);
3066 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap1
);
3069 stat
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB
, NULL
, &bitmap2
);
3072 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0xff00ff00);
3075 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
3078 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
3079 UnitPixel
, imageattr
, NULL
, NULL
);
3082 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
3084 ok(color_match(0xffff00ff, color
, 1), "Expected ffff00ff, got %.8x\n", color
);
3086 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
3089 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,1,1, 0,0,1,1,
3090 UnitPixel
, imageattr
, NULL
, NULL
);
3093 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
3095 ok(color_match(0xff00ff00, color
, 1), "Expected ff00ff00, got %.8x\n", color
);
3097 GdipDeleteGraphics(graphics
);
3098 GdipDisposeImage((GpImage
*)bitmap1
);
3099 GdipDisposeImage((GpImage
*)bitmap2
);
3100 GdipDisposeImageAttributes(imageattr
);
3104 static void test_colorkey(void)
3107 GpImageAttributes
*imageattr
;
3108 GpBitmap
*bitmap1
, *bitmap2
;
3109 GpGraphics
*graphics
;
3112 stat
= GdipSetImageAttributesColorKeys(NULL
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
3113 expect(InvalidParameter
, stat
);
3115 stat
= GdipCreateImageAttributes(&imageattr
);
3118 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeCount
, TRUE
, 0xff405060, 0xff708090);
3119 expect(InvalidParameter
, stat
);
3121 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeAny
, TRUE
, 0xff405060, 0xff708090);
3122 expect(InvalidParameter
, stat
);
3124 stat
= GdipSetImageAttributesColorKeys(imageattr
, ColorAdjustTypeDefault
, TRUE
, 0xff405060, 0xff708090);
3127 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap1
);
3130 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, &bitmap2
);
3133 stat
= GdipBitmapSetPixel(bitmap1
, 0, 0, 0x20405060);
3136 stat
= GdipBitmapSetPixel(bitmap1
, 0, 1, 0x40506070);
3139 stat
= GdipBitmapSetPixel(bitmap1
, 1, 0, 0x60708090);
3142 stat
= GdipBitmapSetPixel(bitmap1
, 1, 1, 0xffffffff);
3145 stat
= GdipGetImageGraphicsContext((GpImage
*)bitmap2
, &graphics
);
3148 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
3149 UnitPixel
, imageattr
, NULL
, NULL
);
3152 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
3154 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
3156 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
3158 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
3160 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
3162 ok(color_match(0x00000000, color
, 1), "Expected 00000000, got %.8x\n", color
);
3164 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
3166 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
3168 stat
= GdipResetImageAttributes(imageattr
, ColorAdjustTypeDefault
);
3171 stat
= GdipDrawImageRectRectI(graphics
, (GpImage
*)bitmap1
, 0,0,2,2, 0,0,2,2,
3172 UnitPixel
, imageattr
, NULL
, NULL
);
3175 stat
= GdipBitmapGetPixel(bitmap2
, 0, 0, &color
);
3177 ok(color_match(0x20405060, color
, 1), "Expected 20405060, got %.8x\n", color
);
3179 stat
= GdipBitmapGetPixel(bitmap2
, 0, 1, &color
);
3181 ok(color_match(0x40506070, color
, 1), "Expected 40506070, got %.8x\n", color
);
3183 stat
= GdipBitmapGetPixel(bitmap2
, 1, 0, &color
);
3185 ok(color_match(0x60708090, color
, 1), "Expected 60708090, got %.8x\n", color
);
3187 stat
= GdipBitmapGetPixel(bitmap2
, 1, 1, &color
);
3189 ok(color_match(0xffffffff, color
, 1), "Expected ffffffff, got %.8x\n", color
);
3192 GdipDeleteGraphics(graphics
);
3193 GdipDisposeImage((GpImage
*)bitmap1
);
3194 GdipDisposeImage((GpImage
*)bitmap2
);
3195 GdipDisposeImageAttributes(imageattr
);
3198 static void test_dispose(void)
3202 char invalid_image
[256];
3204 stat
= GdipDisposeImage(NULL
);
3205 expect(InvalidParameter
, stat
);
3207 stat
= GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB
, NULL
, (GpBitmap
**)&image
);
3210 stat
= GdipDisposeImage(image
);
3213 stat
= GdipDisposeImage(image
);
3214 expect(ObjectBusy
, stat
);
3216 memset(invalid_image
, 0, 256);
3217 stat
= GdipDisposeImage((GpImage
*)invalid_image
);
3218 expect(ObjectBusy
, stat
);
3221 static LONG
obj_refcount(void *obj
)
3223 IUnknown_AddRef((IUnknown
*)obj
);
3224 return IUnknown_Release((IUnknown
*)obj
);
3227 static GpImage
*load_image(const BYTE
*image_data
, UINT image_size
)
3234 GpImage
*image
= NULL
, *clone
;
3235 ImageType image_type
;
3236 LONG refcount
, old_refcount
;
3238 hmem
= GlobalAlloc(0, image_size
);
3239 data
= GlobalLock(hmem
);
3240 memcpy(data
, image_data
, image_size
);
3243 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
3244 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
3245 if (hr
!= S_OK
) return NULL
;
3247 refcount
= obj_refcount(stream
);
3248 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3250 status
= GdipLoadImageFromStream(stream
, &image
);
3251 ok(status
== Ok
|| broken(status
== InvalidParameter
), /* XP */
3252 "GdipLoadImageFromStream error %d\n", status
);
3255 IStream_Release(stream
);
3259 status
= GdipGetImageType(image
, &image_type
);
3260 ok(status
== Ok
, "GdipGetImageType error %d\n", status
);
3262 refcount
= obj_refcount(stream
);
3263 if (image_type
== ImageTypeBitmap
)
3264 ok(refcount
> 1, "expected stream refcount > 1, got %d\n", refcount
);
3266 ok(refcount
== 1, "expected stream refcount 1, got %d\n", refcount
);
3267 old_refcount
= refcount
;
3269 status
= GdipCloneImage(image
, &clone
);
3270 ok(status
== Ok
, "GdipCloneImage error %d\n", status
);
3271 refcount
= obj_refcount(stream
);
3272 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3273 status
= GdipDisposeImage(clone
);
3274 ok(status
== Ok
, "GdipDisposeImage error %d\n", status
);
3275 refcount
= obj_refcount(stream
);
3276 ok(refcount
== old_refcount
, "expected stream refcount %d, got %d\n", old_refcount
, refcount
);
3278 refcount
= IStream_Release(stream
);
3279 if (image_type
== ImageTypeBitmap
)
3280 ok(refcount
>= 1, "expected stream refcount != 0\n");
3282 ok(refcount
== 0, "expected stream refcount 0, got %d\n", refcount
);
3287 static void test_image_properties(void)
3289 static const struct test_data
3291 const BYTE
*image_data
;
3293 ImageType image_type
;
3295 UINT prop_count2
; /* if win7 behaves differently */
3296 /* 1st property attributes */
3298 UINT prop_size2
; /* if win7 behaves differently */
3300 UINT prop_id2
; /* if win7 behaves differently */
3304 { pngimage
, sizeof(pngimage
), ImageTypeBitmap
, 4, ~0, 1, 20, 0x5110, 0x132 },
3305 { jpgimage
, sizeof(jpgimage
), ImageTypeBitmap
, 2, ~0, 128, 0, 0x5090, 0x5091 },
3306 { tiffimage
, sizeof(tiffimage
), ImageTypeBitmap
, 16, 0, 4, 0, 0xfe, 0 },
3307 { bmpimage
, sizeof(bmpimage
), ImageTypeBitmap
, 0, 0, 0, 0, 0, 0 },
3308 { wmfimage
, sizeof(wmfimage
), ImageTypeMetafile
, 0, 0, 0, 0, 0, 0 }
3312 UINT prop_count
, prop_size
, i
;
3313 PROPID prop_id
[16] = { 0 };
3314 ImageType image_type
;
3321 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
3323 image
= load_image(td
[i
].image_data
, td
[i
].image_size
);
3326 trace("%u: failed to load image data\n", i
);
3330 status
= GdipGetImageType(image
, &image_type
);
3331 ok(status
== Ok
, "%u: GdipGetImageType error %d\n", i
, status
);
3332 ok(td
[i
].image_type
== image_type
, "%u: expected image_type %d, got %d\n",
3333 i
, td
[i
].image_type
, image_type
);
3335 status
= GdipGetPropertyCount(image
, &prop_count
);
3336 ok(status
== Ok
, "%u: GdipGetPropertyCount error %d\n", i
, status
);
3337 todo_wine_if(td
[i
].image_data
== pngimage
|| td
[i
].image_data
== jpgimage
)
3338 ok(td
[i
].prop_count
== prop_count
|| td
[i
].prop_count2
== prop_count
,
3339 " %u: expected property count %u or %u, got %u\n",
3340 i
, td
[i
].prop_count
, td
[i
].prop_count2
, prop_count
);
3342 status
= GdipGetPropertyItemSize(NULL
, 0, &prop_size
);
3343 expect(InvalidParameter
, status
);
3344 status
= GdipGetPropertyItemSize(image
, 0, NULL
);
3345 expect(InvalidParameter
, status
);
3346 status
= GdipGetPropertyItemSize(image
, 0, &prop_size
);
3347 if (image_type
== ImageTypeMetafile
)
3348 expect(NotImplemented
, status
);
3350 expect(PropertyNotFound
, status
);
3352 status
= GdipGetPropertyItem(NULL
, 0, 0, &item
.data
);
3353 expect(InvalidParameter
, status
);
3354 status
= GdipGetPropertyItem(image
, 0, 0, NULL
);
3355 expect(InvalidParameter
, status
);
3356 status
= GdipGetPropertyItem(image
, 0, 0, &item
.data
);
3357 if (image_type
== ImageTypeMetafile
)
3358 expect(NotImplemented
, status
);
3360 expect(PropertyNotFound
, status
);
3362 /* FIXME: remove once Wine is fixed */
3363 if (td
[i
].prop_count
!= prop_count
)
3365 GdipDisposeImage(image
);
3369 status
= GdipGetPropertyIdList(NULL
, prop_count
, prop_id
);
3370 expect(InvalidParameter
, status
);
3371 status
= GdipGetPropertyIdList(image
, prop_count
, NULL
);
3372 expect(InvalidParameter
, status
);
3373 status
= GdipGetPropertyIdList(image
, 0, prop_id
);
3374 if (image_type
== ImageTypeMetafile
)
3375 expect(NotImplemented
, status
);
3376 else if (prop_count
== 0)
3379 expect(InvalidParameter
, status
);
3380 status
= GdipGetPropertyIdList(image
, prop_count
- 1, prop_id
);
3381 if (image_type
== ImageTypeMetafile
)
3382 expect(NotImplemented
, status
);
3384 expect(InvalidParameter
, status
);
3385 status
= GdipGetPropertyIdList(image
, prop_count
+ 1, prop_id
);
3386 if (image_type
== ImageTypeMetafile
)
3387 expect(NotImplemented
, status
);
3389 expect(InvalidParameter
, status
);
3390 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3391 if (image_type
== ImageTypeMetafile
)
3392 expect(NotImplemented
, status
);
3396 if (prop_count
!= 0)
3397 ok(td
[i
].prop_id
== prop_id
[0] || td
[i
].prop_id2
== prop_id
[0],
3398 " %u: expected property id %#x or %#x, got %#x\n",
3399 i
, td
[i
].prop_id
, td
[i
].prop_id2
, prop_id
[0]);
3404 status
= GdipGetPropertyItemSize(image
, prop_id
[0], &prop_size
);
3405 if (prop_count
== 0)
3406 expect(PropertyNotFound
, status
);
3411 assert(sizeof(item
) >= prop_size
);
3412 ok(prop_size
> sizeof(PropertyItem
), "%u: got too small prop_size %u\n",
3414 ok(td
[i
].prop_size
+ sizeof(PropertyItem
) == prop_size
||
3415 td
[i
].prop_size2
+ sizeof(PropertyItem
) == prop_size
,
3416 " %u: expected property size %u or %u, got %u\n",
3417 i
, td
[i
].prop_size
, td
[i
].prop_size2
, prop_size
);
3419 status
= GdipGetPropertyItem(image
, prop_id
[0], 0, &item
.data
);
3420 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3421 "%u: expected InvalidParameter, got %d\n", i
, status
);
3422 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
- 1, &item
.data
);
3423 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3424 "%u: expected InvalidParameter, got %d\n", i
, status
);
3425 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
+ 1, &item
.data
);
3426 ok(status
== InvalidParameter
|| status
== GenericError
/* Win7 */,
3427 "%u: expected InvalidParameter, got %d\n", i
, status
);
3428 status
= GdipGetPropertyItem(image
, prop_id
[0], prop_size
, &item
.data
);
3430 ok(prop_id
[0] == item
.data
.id
,
3431 "%u: expected property id %#x, got %#x\n", i
, prop_id
[0], item
.data
.id
);
3435 GdipDisposeImage(image
);
3443 #define IFD_RATIONAL 5
3445 #define IFD_UNDEFINED 7
3446 #define IFD_SSHORT 8
3448 #define IFD_SRATIONAL 10
3449 #define IFD_FLOAT 11
3450 #define IFD_DOUBLE 12
3452 #ifndef PropertyTagTypeSByte
3453 #define PropertyTagTypeSByte 6
3454 #define PropertyTagTypeSShort 8
3455 #define PropertyTagTypeFloat 11
3456 #define PropertyTagTypeDouble 12
3459 static UINT
documented_type(UINT type
)
3463 case PropertyTagTypeSByte
: return PropertyTagTypeByte
;
3464 case PropertyTagTypeSShort
: return PropertyTagTypeShort
;
3465 case PropertyTagTypeFloat
: return PropertyTagTypeUndefined
;
3466 case PropertyTagTypeDouble
: return PropertyTagTypeUndefined
;
3467 default: return type
;
3471 #include "pshpack2.h"
3486 static const struct tiff_data
3491 USHORT number_of_entries
;
3492 struct IFD_entry entry
[40];
3494 struct IFD_rational xres
;
3496 struct IFD_rational srational_val
;
3501 struct IFD_rational rational
[3];
3505 #ifdef WORDS_BIGENDIAN
3511 FIELD_OFFSET(struct tiff_data
, number_of_entries
),
3514 { 0xff, IFD_SHORT
, 1, 0 }, /* SUBFILETYPE */
3515 { 0x100, IFD_LONG
, 1, 1 }, /* IMAGEWIDTH */
3516 { 0x101, IFD_LONG
, 1, 1 }, /* IMAGELENGTH */
3517 { 0x102, IFD_SHORT
, 1, 1 }, /* BITSPERSAMPLE */
3518 { 0x103, IFD_SHORT
, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
3519 { 0x106, IFD_SHORT
, 1, 1 }, /* PHOTOMETRIC */
3520 { 0x111, IFD_LONG
, 1, FIELD_OFFSET(struct tiff_data
, pixel_data
) }, /* STRIPOFFSETS */
3521 { 0x115, IFD_SHORT
, 1, 1 }, /* SAMPLESPERPIXEL */
3522 { 0x116, IFD_LONG
, 1, 1 }, /* ROWSPERSTRIP */
3523 { 0x117, IFD_LONG
, 1, 1 }, /* STRIPBYTECOUNT */
3524 { 0x11a, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3525 { 0x11b, IFD_RATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, xres
) },
3526 { 0x128, IFD_SHORT
, 1, 2 }, /* RESOLUTIONUNIT */
3527 { 0xf001, IFD_BYTE
, 1, 0x11223344 },
3528 { 0xf002, IFD_BYTE
, 4, 0x11223344 },
3529 { 0xf003, IFD_SBYTE
, 1, 0x11223344 },
3530 { 0xf004, IFD_SSHORT
, 1, 0x11223344 },
3531 { 0xf005, IFD_SSHORT
, 2, 0x11223344 },
3532 { 0xf006, IFD_SLONG
, 1, 0x11223344 },
3533 { 0xf007, IFD_FLOAT
, 1, 0x11223344 },
3534 { 0xf008, IFD_DOUBLE
, 1, FIELD_OFFSET(struct tiff_data
, double_val
) },
3535 { 0xf009, IFD_SRATIONAL
, 1, FIELD_OFFSET(struct tiff_data
, srational_val
) },
3536 { 0xf00a, IFD_BYTE
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3537 { 0xf00b, IFD_SSHORT
, 4, FIELD_OFFSET(struct tiff_data
, short_val
) },
3538 { 0xf00c, IFD_SLONG
, 2, FIELD_OFFSET(struct tiff_data
, long_val
) },
3539 { 0xf00e, IFD_ASCII
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3540 { 0xf00f, IFD_ASCII
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3541 { 0xf010, IFD_UNDEFINED
, 13, FIELD_OFFSET(struct tiff_data
, string
) },
3542 { 0xf011, IFD_UNDEFINED
, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3543 /* Some gdiplus versions ignore these fields.
3544 { 0xf012, IFD_BYTE, 0, 0x11223344 },
3545 { 0xf013, IFD_SHORT, 0, 0x11223344 },
3546 { 0xf014, IFD_LONG, 0, 0x11223344 },
3547 { 0xf015, IFD_FLOAT, 0, 0x11223344 },*/
3548 { 0xf016, IFD_SRATIONAL
, 3, FIELD_OFFSET(struct tiff_data
, rational
) },
3549 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3550 { 0xf017, IFD_FLOAT
, 2, FIELD_OFFSET(struct tiff_data
, float_val
) },
3554 1234567890.0987654321,
3555 { 0x1a2b3c4d, 0x5a6b7c8d },
3557 { 0x0101, 0x0202, 0x0303, 0x0404 },
3558 { 0x11223344, 0x55667788 },
3559 { (FLOAT
)1234.5678, (FLOAT
)8765.4321 },
3560 { { 0x01020304, 0x05060708 }, { 0x10203040, 0x50607080 }, { 0x11223344, 0x55667788 } },
3561 { 0x11, 0x22, 0x33, 0 }
3563 #include "poppack.h"
3565 static void test_tiff_properties(void)
3567 static const struct test_data
3569 ULONG type
, id
, length
;
3570 const BYTE value
[24];
3573 { PropertyTagTypeShort
, 0xff, 2, { 0 } },
3574 { PropertyTagTypeLong
, 0x100, 4, { 1 } },
3575 { PropertyTagTypeLong
, 0x101, 4, { 1 } },
3576 { PropertyTagTypeShort
, 0x102, 2, { 1 } },
3577 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3578 { PropertyTagTypeShort
, 0x106, 2, { 1 } },
3579 { PropertyTagTypeLong
, 0x111, 4, { 0x44,0x02 } },
3580 { PropertyTagTypeShort
, 0x115, 2, { 1 } },
3581 { PropertyTagTypeLong
, 0x116, 4, { 1 } },
3582 { PropertyTagTypeLong
, 0x117, 4, { 1 } },
3583 { PropertyTagTypeRational
, 0x11a, 8, { 0x84,0x03,0,0,0x03 } },
3584 { PropertyTagTypeRational
, 0x11b, 8, { 0x84,0x03,0,0,0x03 } },
3585 { PropertyTagTypeShort
, 0x128, 2, { 2 } },
3586 { PropertyTagTypeByte
, 0xf001, 1, { 0x44 } },
3587 { PropertyTagTypeByte
, 0xf002, 4, { 0x44,0x33,0x22,0x11 } },
3588 { PropertyTagTypeSByte
, 0xf003, 1, { 0x44 } },
3589 { PropertyTagTypeSShort
, 0xf004, 2, { 0x44,0x33 } },
3590 { PropertyTagTypeSShort
, 0xf005, 4, { 0x44,0x33,0x22,0x11 } },
3591 { PropertyTagTypeSLONG
, 0xf006, 4, { 0x44,0x33,0x22,0x11 } },
3592 { PropertyTagTypeFloat
, 0xf007, 4, { 0x44,0x33,0x22,0x11 } },
3593 { PropertyTagTypeDouble
, 0xf008, 8, { 0x2c,0x52,0x86,0xb4,0x80,0x65,0xd2,0x41 } },
3594 { PropertyTagTypeSRational
, 0xf009, 8, { 0x4d, 0x3c, 0x2b, 0x1a, 0x8d, 0x7c, 0x6b, 0x5a } },
3595 { PropertyTagTypeByte
, 0xf00a, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3596 { PropertyTagTypeSShort
, 0xf00b, 8, { 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04 } },
3597 { PropertyTagTypeSLONG
, 0xf00c, 8, { 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3598 { PropertyTagTypeASCII
, 0xf00e, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3599 { PropertyTagTypeASCII
, 0xf00f, 5, { 'a','b','c','d' } },
3600 { PropertyTagTypeUndefined
, 0xf010, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3601 { PropertyTagTypeUndefined
, 0xf011, 4, { 'a','b','c','d' } },
3602 { PropertyTagTypeSRational
, 0xf016, 24,
3603 { 0x04,0x03,0x02,0x01,0x08,0x07,0x06,0x05,
3604 0x40,0x30,0x20,0x10,0x80,0x70,0x60,0x50,
3605 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3606 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3607 { PropertyTagTypeFloat
, 0xf017, 8, { 0x2b,0x52,0x9a,0x44,0xba,0xf5,0x08,0x46 } },
3612 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3614 PropertyItem
*prop_item
;
3616 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
));
3619 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3623 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3625 expect(1, dim_count
);
3627 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3629 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3631 frame_count
= 0xdeadbeef;
3632 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3634 expect(1, frame_count
);
3636 prop_count
= 0xdeadbeef;
3637 status
= GdipGetPropertyCount(image
, &prop_count
);
3639 ok(prop_count
== sizeof(td
)/sizeof(td
[0]) ||
3640 broken(prop_count
== sizeof(td
)/sizeof(td
[0]) - 1) /* Win7 SP0 */,
3641 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
3643 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3645 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3648 for (i
= 0; i
< prop_count
; i
++)
3650 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &prop_size
);
3652 if (status
!= Ok
) break;
3653 ok(prop_size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, prop_size
);
3655 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, prop_size
);
3656 status
= GdipGetPropertyItem(image
, prop_id
[i
], prop_size
, prop_item
);
3658 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3659 ok(td
[i
].type
== prop_item
->type
||
3660 /* Win7 stopped using proper but not documented types, and it
3661 looks broken since TypeFloat and TypeDouble now reported as
3662 TypeUndefined, and signed types reported as unsigned. */
3663 broken(prop_item
->type
== documented_type(td
[i
].type
)),
3664 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3665 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3666 prop_size
-= sizeof(*prop_item
);
3667 ok(prop_item
->length
== prop_size
, "%u: expected length %u, got %u\n", i
, prop_size
, prop_item
->length
);
3668 ok(td
[i
].length
== prop_item
->length
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_item
->length
+1) /* XP */,
3669 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3670 ok(td
[i
].length
== prop_size
|| broken(td
[i
].id
== 0xf00f && td
[i
].length
== prop_size
+1) /* XP */,
3671 "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_size
);
3672 if (td
[i
].length
== prop_item
->length
)
3674 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3675 ok(match
|| broken(td
[i
].length
<= 4 && !match
), "%u: data mismatch\n", i
);
3679 BYTE
*data
= prop_item
->value
;
3680 trace("id %#x:", prop_item
->id
);
3681 for (j
= 0; j
< prop_item
->length
; j
++)
3682 trace(" %02x", data
[j
]);
3686 HeapFree(GetProcessHeap(), 0, prop_item
);
3689 HeapFree(GetProcessHeap(), 0, prop_id
);
3691 GdipDisposeImage(image
);
3694 static void test_GdipGetAllPropertyItems(void)
3696 static const struct test_data
3698 ULONG type
, id
, length
;
3702 { PropertyTagTypeLong
, 0xfe, 4, { 0 } },
3703 { PropertyTagTypeShort
, 0x100, 2, { 1 } },
3704 { PropertyTagTypeShort
, 0x101, 2, { 1 } },
3705 { PropertyTagTypeShort
, 0x102, 6, { 8,0,8,0,8,0 } },
3706 { PropertyTagTypeShort
, 0x103, 2, { 1 } },
3707 { PropertyTagTypeShort
, 0x106, 2, { 2,0 } },
3708 { PropertyTagTypeASCII
, 0x10d, 27, "/home/meh/Desktop/test.tif" },
3709 { PropertyTagTypeLong
, 0x111, 4, { 8,0,0,0 } },
3710 { PropertyTagTypeShort
, 0x112, 2, { 1 } },
3711 { PropertyTagTypeShort
, 0x115, 2, { 3,0 } },
3712 { PropertyTagTypeShort
, 0x116, 2, { 0x40,0 } },
3713 { PropertyTagTypeLong
, 0x117, 4, { 3,0,0,0 } },
3714 { PropertyTagTypeRational
, 0x11a, 8, { 0,0,0,72,0,0,0,1 } },
3715 { PropertyTagTypeRational
, 0x11b, 8, { 0,0,0,72,0,0,0,1 } },
3716 { PropertyTagTypeShort
, 0x11c, 2, { 1 } },
3717 { PropertyTagTypeShort
, 0x128, 2, { 2 } }
3722 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
3723 UINT total_size
, total_count
;
3725 PropertyItem
*prop_item
;
3726 const char *item_data
;
3728 image
= load_image(tiffimage
, sizeof(tiffimage
));
3729 ok(image
!= 0, "Failed to load TIFF image data\n");
3732 dim_count
= 0xdeadbeef;
3733 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
3735 expect(1, dim_count
);
3737 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
3739 expect_guid(&FrameDimensionPage
, &guid
, __LINE__
, FALSE
);
3741 frame_count
= 0xdeadbeef;
3742 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
3744 expect(1, frame_count
);
3746 prop_count
= 0xdeadbeef;
3747 status
= GdipGetPropertyCount(image
, &prop_count
);
3749 ok(prop_count
== sizeof(td
)/sizeof(td
[0]),
3750 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
3752 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
3754 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
3758 for (i
= 0; i
< prop_count
; i
++)
3761 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
3763 if (status
!= Ok
) break;
3764 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
3768 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
3769 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
3771 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
3772 ok(td
[i
].type
== prop_item
->type
,
3773 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
3774 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
3775 size
-= sizeof(*prop_item
);
3776 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
3777 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
3778 if (td
[i
].length
== prop_item
->length
)
3780 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
3781 ok(match
, "%u: data mismatch\n", i
);
3785 BYTE
*data
= prop_item
->value
;
3786 trace("id %#x:", prop_item
->id
);
3787 for (j
= 0; j
< prop_item
->length
; j
++)
3788 trace(" %02x", data
[j
]);
3792 HeapFree(GetProcessHeap(), 0, prop_item
);
3795 HeapFree(GetProcessHeap(), 0, prop_id
);
3797 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
3798 expect(InvalidParameter
, status
);
3799 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
3800 expect(InvalidParameter
, status
);
3801 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
3802 expect(InvalidParameter
, status
);
3803 status
= GdipGetPropertySize(image
, NULL
, NULL
);
3804 expect(InvalidParameter
, status
);
3805 total_size
= 0xdeadbeef;
3806 total_count
= 0xdeadbeef;
3807 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
3809 ok(prop_count
== total_count
,
3810 "expected total property count %u, got %u\n", prop_count
, total_count
);
3811 ok(prop_size
== total_size
,
3812 "expected total property size %u, got %u\n", prop_size
, total_size
);
3814 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
3816 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
3817 expect(InvalidParameter
, status
);
3818 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
3819 expect(InvalidParameter
, status
);
3820 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3821 expect(InvalidParameter
, status
);
3822 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
3823 expect(InvalidParameter
, status
);
3824 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
3825 expect(InvalidParameter
, status
);
3826 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
3827 expect(InvalidParameter
, status
);
3828 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
3831 item_data
= (const char *)(prop_item
+ prop_count
);
3832 for (i
= 0; i
< prop_count
; i
++)
3834 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
3835 i
, item_data
, prop_item
[i
].value
);
3836 ok(td
[i
].type
== prop_item
[i
].type
,
3837 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
3838 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
3839 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
3840 if (td
[i
].length
== prop_item
[i
].length
)
3842 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
3843 ok(match
, "%u: data mismatch\n", i
);
3847 BYTE
*data
= prop_item
[i
].value
;
3848 trace("id %#x:", prop_item
[i
].id
);
3849 for (j
= 0; j
< prop_item
[i
].length
; j
++)
3850 trace(" %02x", data
[j
]);
3854 item_data
+= prop_item
[i
].length
;
3857 HeapFree(GetProcessHeap(), 0, prop_item
);
3859 GdipDisposeImage(image
);
3862 static void test_tiff_palette(void)
3873 ARGB
*entries
= palette
.pal
.Entries
;
3875 /* 1bpp TIFF without palette */
3876 image
= load_image((const BYTE
*)&TIFF_data
, sizeof(TIFF_data
));
3879 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3883 status
= GdipGetImagePixelFormat(image
, &format
);
3885 ok(format
== PixelFormat1bppIndexed
, "expected PixelFormat1bppIndexed, got %#x\n", format
);
3887 status
= GdipGetImagePaletteSize(image
, &size
);
3888 ok(status
== Ok
|| broken(status
== GenericError
), /* XP */
3889 "GdipGetImagePaletteSize error %d\n", status
);
3890 if (status
== GenericError
)
3892 GdipDisposeImage(image
);
3895 expect(sizeof(ColorPalette
) + sizeof(ARGB
), size
);
3897 status
= GdipGetImagePalette(image
, &palette
.pal
, size
);
3899 expect(0, palette
.pal
.Flags
);
3900 expect(2, palette
.pal
.Count
);
3901 if (palette
.pal
.Count
== 2)
3903 ok(entries
[0] == 0xff000000, "expected 0xff000000, got %#x\n", entries
[0]);
3904 ok(entries
[1] == 0xffffffff, "expected 0xffffffff, got %#x\n", entries
[1]);
3907 GdipDisposeImage(image
);
3910 static void test_bitmapbits(void)
3913 static const BYTE pixels_24
[48] =
3915 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3916 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3917 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3918 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0
3920 static const BYTE pixels_00
[48] =
3922 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3923 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3924 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3925 0,0,0, 0,0,0, 0,0,0, 0,0,0
3927 static const BYTE pixels_24_77
[64] =
3929 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3930 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3931 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
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 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3936 static const BYTE pixels_77
[64] =
3938 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3939 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3940 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3941 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3942 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3943 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3944 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3945 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3947 static const BYTE pixels_8
[16] =
3949 0x01,0,0x01,0,0x01,0,0x01,0,
3950 0x01,0,0x01,0,0x01,0,0x01,0
3952 static const BYTE pixels_8_77
[64] =
3954 0x01,0,0x01,0,0x01,0,0x01,0,
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 0x01,0,0x01,0,0x01,0,0x01,0,
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_1_77
[64] =
3965 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3966 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3967 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3968 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3969 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3970 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3971 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3972 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3974 static const BYTE pixels_1
[8] = {0xaa,0,0,0,0xaa,0,0,0};
3975 static const struct test_data
3982 const BYTE
*pixels_unlocked
;
3986 { PixelFormat24bppRGB
, 24, 0xfff0, 24, 48, pixels_24
, pixels_00
},
3988 { PixelFormat24bppRGB
, 24, 0, 24, 48, pixels_24
, pixels_00
},
3989 { PixelFormat24bppRGB
, 24, ImageLockModeRead
, 24, 48, pixels_24
, pixels_00
},
3990 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
3991 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeWrite
, 24, 48, pixels_24
, pixels_00
},
3992 { PixelFormat24bppRGB
, 24, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_24_77
, pixels_24
},
3993 { PixelFormat24bppRGB
, 24, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
3994 { PixelFormat24bppRGB
, 24, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
3996 { PixelFormat8bppIndexed
, 8, 0, 8, 16, pixels_8
, pixels_24
},
3997 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
, 8, 16, pixels_8
, pixels_24
},
3998 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
3999 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeWrite
, 8, 16, pixels_8
, pixels_00
},
4000 { PixelFormat8bppIndexed
, 8, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_8_77
, pixels_24
},
4001 { PixelFormat8bppIndexed
, 8, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
4002 { PixelFormat8bppIndexed
, 8, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
4004 { PixelFormat1bppIndexed
, 1, 0, 4, 8, pixels_1
, pixels_24
},
4005 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
, 4, 8, pixels_1
, pixels_24
},
4006 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
4007 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeWrite
, 4, 8, pixels_1
, pixels_00
},
4008 { PixelFormat1bppIndexed
, 1, ImageLockModeRead
|ImageLockModeUserInputBuf
, 32, 64, pixels_1_77
, pixels_24
},
4009 { PixelFormat1bppIndexed
, 1, ImageLockModeWrite
|ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_00
},
4010 { PixelFormat1bppIndexed
, 1, ImageLockModeUserInputBuf
, 32, 64, pixels_77
, pixels_24
},
4022 ARGB
*entries
= palette
.pal
.Entries
;
4024 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
4026 BYTE pixels
[sizeof(pixels_24
)];
4027 memcpy(pixels
, pixels_24
, sizeof(pixels_24
));
4028 status
= GdipCreateBitmapFromScan0(8, 2, 24, PixelFormat24bppRGB
, pixels
, &bitmap
);
4031 /* associate known palette with pixel data */
4032 palette
.pal
.Flags
= PaletteFlagsGrayScale
;
4033 palette
.pal
.Count
= 2;
4034 entries
[0] = 0xff000000;
4035 entries
[1] = 0xffffffff;
4036 status
= GdipSetImagePalette((GpImage
*)bitmap
, &palette
.pal
);
4039 memset(&data
, 0xfe, sizeof(data
));
4040 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
4042 memset(buf
, 0x77, sizeof(buf
));
4046 status
= GdipBitmapLockBits(bitmap
, NULL
, td
[i
].mode
, td
[i
].format
, &data
);
4047 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* XP */, "%u: GdipBitmapLockBits error %d\n", i
, status
);
4050 GdipDisposeImage((GpImage
*)bitmap
);
4053 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
4054 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
4055 ok(td
[i
].stride
== data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].stride
, data
.Stride
);
4056 ok(td
[i
].format
== data
.PixelFormat
, "%u: expected %d, got %d\n", i
, td
[i
].format
, data
.PixelFormat
);
4057 ok(td
[i
].size
== data
.Height
* data
.Stride
, "%u: expected %d, got %d\n", i
, td
[i
].size
, data
.Height
* data
.Stride
);
4058 if (td
[i
].mode
& ImageLockModeUserInputBuf
)
4059 ok(data
.Scan0
== buf
, "%u: got wrong buffer\n", i
);
4060 if (td
[i
].size
== data
.Height
* data
.Stride
)
4062 UINT j
, match
, width_bytes
= (data
.Width
* td
[i
].bpp
) / 8;
4065 for (j
= 0; j
< data
.Height
; j
++)
4067 if (memcmp((const BYTE
*)data
.Scan0
+ j
* data
.Stride
, td
[i
].pixels
+ j
* data
.Stride
, width_bytes
) != 0)
4073 if ((td
[i
].mode
& (ImageLockModeRead
|ImageLockModeUserInputBuf
)) || td
[i
].format
== PixelFormat24bppRGB
)
4076 "%u: data should match\n", i
);
4079 BYTE
*bits
= data
.Scan0
;
4080 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
4081 for (j
= 0; j
< td
[i
].size
; j
++)
4082 trace(" %02x", bits
[j
]);
4087 ok(!match
, "%u: data shouldn't match\n", i
);
4089 memset(data
.Scan0
, 0, td
[i
].size
);
4092 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4093 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
4095 memset(&data
, 0xfe, sizeof(data
));
4096 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
4097 ok(status
== Ok
, "%u: GdipBitmapLockBits error %d\n", i
, status
);
4098 ok(data
.Width
== 8, "%u: expected 8, got %d\n", i
, data
.Width
);
4099 ok(data
.Height
== 2, "%u: expected 2, got %d\n", i
, data
.Height
);
4100 ok(data
.Stride
== 24, "%u: expected 24, got %d\n", i
, data
.Stride
);
4101 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "%u: got wrong pixel format %d\n", i
, data
.PixelFormat
);
4102 ok(data
.Height
* data
.Stride
== 48, "%u: expected 48, got %d\n", i
, data
.Height
* data
.Stride
);
4103 if (data
.Height
* data
.Stride
== 48)
4105 int match
= memcmp(data
.Scan0
, td
[i
].pixels_unlocked
, 48) == 0;
4106 ok(match
, "%u: data should match\n", i
);
4110 BYTE
*bits
= data
.Scan0
;
4111 trace("%u: data mismatch for format %#x:", i
, td
[i
].format
);
4112 for (j
= 0; j
< 48; j
++)
4113 trace(" %02x", bits
[j
]);
4118 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4119 ok(status
== Ok
, "%u: GdipBitmapUnlockBits error %d\n", i
, status
);
4121 status
= GdipDisposeImage((GpImage
*)bitmap
);
4126 static void test_DrawImage(void)
4128 BYTE black_1x1
[4] = { 0,0,0,0 };
4129 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
4130 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
4131 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
4132 0,0,0,0,0,0,0xff,0xff };
4139 GpGraphics
*graphics
;
4142 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
4144 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4147 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
4149 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
4151 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4153 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4156 status
= GdipDrawImageI(graphics
, u1
.image
, 0, 0);
4159 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
4160 ok(match
, "data should match\n");
4163 UINT i
, size
= sizeof(white_2x2
);
4164 BYTE
*bits
= white_2x2
;
4165 for (i
= 0; i
< size
; i
++)
4166 trace(" %02x", bits
[i
]);
4170 status
= GdipDeleteGraphics(graphics
);
4172 status
= GdipDisposeImage(u1
.image
);
4174 status
= GdipDisposeImage(u2
.image
);
4178 static void test_DrawImage_SourceCopy(void)
4180 DWORD dst_pixels
[4] = { 0xffffffff, 0xffffffff,
4181 0xffffffff, 0xffffffff };
4182 DWORD src_pixels
[4] = { 0, 0xffff0000,
4191 GpGraphics
*graphics
;
4193 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB
, (BYTE
*)dst_pixels
, &u1
.bitmap
);
4196 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB
, (BYTE
*)src_pixels
, &u2
.bitmap
);
4198 status
= GdipGetImageGraphicsContext(u1
.image
, &graphics
);
4200 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4203 status
= GdipSetCompositingMode(graphics
, CompositingModeSourceCopy
);
4206 status
= GdipDrawImageI(graphics
, u2
.image
, 0, 0);
4209 todo_wine
expect(0, dst_pixels
[0]);
4210 expect(0xffff0000, dst_pixels
[1]);
4211 todo_wine
expect(0, dst_pixels
[2]);
4212 todo_wine
expect(0, dst_pixels
[3]);
4214 status
= GdipDeleteGraphics(graphics
);
4216 status
= GdipDisposeImage(u1
.image
);
4218 status
= GdipDisposeImage(u2
.image
);
4222 static void test_GdipDrawImagePointRect(void)
4224 BYTE black_1x1
[4] = { 0,0,0,0 };
4225 BYTE white_2x2
[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
4226 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
4227 BYTE black_2x2
[16] = { 0,0,0,0,0,0,0xff,0xff,
4228 0,0,0,0,0,0,0xff,0xff };
4235 GpGraphics
*graphics
;
4238 status
= GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB
, black_1x1
, &u1
.bitmap
);
4240 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4243 status
= GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB
, white_2x2
, &u2
.bitmap
);
4245 status
= GdipBitmapSetResolution(u2
.bitmap
, 300.0, 300.0);
4247 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4249 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4252 status
= GdipDrawImagePointRectI(graphics
, u1
.image
, 0, 0, 0, 0, 1, 1, UnitPixel
);
4255 match
= memcmp(white_2x2
, black_2x2
, sizeof(black_2x2
)) == 0;
4256 ok(match
, "data should match\n");
4259 UINT i
, size
= sizeof(white_2x2
);
4260 BYTE
*bits
= white_2x2
;
4261 for (i
= 0; i
< size
; i
++)
4262 trace(" %02x", bits
[i
]);
4266 status
= GdipDeleteGraphics(graphics
);
4268 status
= GdipDisposeImage(u1
.image
);
4270 status
= GdipDisposeImage(u2
.image
);
4274 static void test_image_format(void)
4276 static const PixelFormat fmt
[] =
4278 PixelFormat1bppIndexed
, PixelFormat4bppIndexed
, PixelFormat8bppIndexed
,
4279 PixelFormat16bppGrayScale
, PixelFormat16bppRGB555
, PixelFormat16bppRGB565
,
4280 PixelFormat16bppARGB1555
, PixelFormat24bppRGB
, PixelFormat32bppRGB
,
4281 PixelFormat32bppARGB
, PixelFormat32bppPARGB
, PixelFormat48bppRGB
,
4282 PixelFormat64bppARGB
, PixelFormat64bppPARGB
, PixelFormat32bppCMYK
4293 for (i
= 0; i
< sizeof(fmt
)/sizeof(fmt
[0]); i
++)
4295 status
= GdipCreateBitmapFromScan0(1, 1, 0, fmt
[i
], NULL
, &bitmap
);
4296 ok(status
== Ok
|| broken(status
== InvalidParameter
) /* before win7 */,
4297 "GdipCreateBitmapFromScan0 error %d\n", status
);
4298 if (status
!= Ok
) continue;
4300 status
= GdipGetImagePixelFormat((GpImage
*)bitmap
, &format
);
4302 expect(fmt
[i
], format
);
4304 status
= GdipCreateHBITMAPFromBitmap(bitmap
, &hbitmap
, 0);
4305 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4306 todo_wine
expect(InvalidParameter
, status
);
4310 ret
= GetObjectW(hbitmap
, sizeof(bm
), &bm
);
4311 expect(sizeof(bm
), ret
);
4312 expect(0, bm
.bmType
);
4313 expect(1, bm
.bmWidth
);
4314 expect(1, bm
.bmHeight
);
4315 expect(4, bm
.bmWidthBytes
);
4316 expect(1, bm
.bmPlanes
);
4317 expect(32, bm
.bmBitsPixel
);
4318 DeleteObject(hbitmap
);
4321 status
= GdipGetImageThumbnail((GpImage
*)bitmap
, 0, 0, &thumb
, NULL
, NULL
);
4322 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4324 ok(status
== OutOfMemory
|| broken(status
== InvalidParameter
) /* before win7 */,
4325 "expected OutOfMemory, got %d\n", status
);
4330 status
= GdipGetImagePixelFormat(thumb
, &format
);
4332 ok(format
== PixelFormat32bppPARGB
|| broken(format
!= PixelFormat32bppPARGB
) /* before win7 */,
4333 "expected PixelFormat32bppPARGB, got %#x\n", format
);
4334 status
= GdipDisposeImage(thumb
);
4338 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4339 if (fmt
[i
] == PixelFormat16bppGrayScale
|| fmt
[i
] == PixelFormat32bppCMYK
)
4340 todo_wine
expect(InvalidParameter
, status
);
4344 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4348 status
= GdipDisposeImage((GpImage
*)bitmap
);
4353 static void test_DrawImage_scale(void)
4355 static const BYTE back_8x1
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
4356 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4357 static const BYTE image_080
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,
4358 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4359 static const BYTE image_100
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,
4360 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4361 static const BYTE image_120
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,
4362 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4363 static const BYTE image_150
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4364 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4365 static const BYTE image_180
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4366 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4367 static const BYTE image_200
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4368 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4369 static const BYTE image_250
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,
4370 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4371 static const BYTE image_120_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4372 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4373 static const BYTE image_150_half
[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
4374 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
4375 static const BYTE image_200_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4376 0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40 };
4377 static const BYTE image_250_half
[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
4378 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
4379 static const struct test_data
4382 PixelOffsetMode pixel_offset_mode
;
4387 { 0.8, PixelOffsetModeNone
, image_080
}, /* 0 */
4388 { 1.0, PixelOffsetModeNone
, image_100
},
4389 { 1.2, PixelOffsetModeNone
, image_120
},
4390 { 1.5, PixelOffsetModeNone
, image_150
},
4391 { 1.8, PixelOffsetModeNone
, image_180
},
4392 { 2.0, PixelOffsetModeNone
, image_200
},
4393 { 2.5, PixelOffsetModeNone
, image_250
},
4395 { 0.8, PixelOffsetModeHighSpeed
, image_080
}, /* 7 */
4396 { 1.0, PixelOffsetModeHighSpeed
, image_100
},
4397 { 1.2, PixelOffsetModeHighSpeed
, image_120
},
4398 { 1.5, PixelOffsetModeHighSpeed
, image_150
},
4399 { 1.8, PixelOffsetModeHighSpeed
, image_180
},
4400 { 2.0, PixelOffsetModeHighSpeed
, image_200
},
4401 { 2.5, PixelOffsetModeHighSpeed
, image_250
},
4403 { 0.8, PixelOffsetModeHalf
, image_080
}, /* 14 */
4404 { 1.0, PixelOffsetModeHalf
, image_100
},
4405 { 1.2, PixelOffsetModeHalf
, image_120_half
, TRUE
},
4406 { 1.5, PixelOffsetModeHalf
, image_150_half
, TRUE
},
4407 { 1.8, PixelOffsetModeHalf
, image_180
},
4408 { 2.0, PixelOffsetModeHalf
, image_200_half
, TRUE
},
4409 { 2.5, PixelOffsetModeHalf
, image_250_half
, TRUE
},
4411 { 0.8, PixelOffsetModeHighQuality
, image_080
}, /* 21 */
4412 { 1.0, PixelOffsetModeHighQuality
, image_100
},
4413 { 1.2, PixelOffsetModeHighQuality
, image_120_half
, TRUE
},
4414 { 1.5, PixelOffsetModeHighQuality
, image_150_half
, TRUE
},
4415 { 1.8, PixelOffsetModeHighQuality
, image_180
},
4416 { 2.0, PixelOffsetModeHighQuality
, image_200_half
, TRUE
},
4417 { 2.5, PixelOffsetModeHighQuality
, image_250_half
, TRUE
},
4419 BYTE src_2x1
[6] = { 0x80,0x80,0x80,0x80,0x80,0x80 };
4427 GpGraphics
*graphics
;
4431 status
= GdipCreateBitmapFromScan0(2, 1, 4, PixelFormat24bppRGB
, src_2x1
, &u1
.bitmap
);
4433 status
= GdipBitmapSetResolution(u1
.bitmap
, 100.0, 100.0);
4436 status
= GdipCreateBitmapFromScan0(8, 1, 24, PixelFormat24bppRGB
, dst_8x1
, &u2
.bitmap
);
4438 status
= GdipBitmapSetResolution(u2
.bitmap
, 100.0, 100.0);
4440 status
= GdipGetImageGraphicsContext(u2
.image
, &graphics
);
4442 status
= GdipSetInterpolationMode(graphics
, InterpolationModeNearestNeighbor
);
4445 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
4447 status
= GdipSetPixelOffsetMode(graphics
, td
[i
].pixel_offset_mode
);
4450 status
= GdipCreateMatrix2(td
[i
].scale_x
, 0.0, 0.0, 1.0, 0.0, 0.0, &matrix
);
4452 status
= GdipSetWorldTransform(graphics
, matrix
);
4454 GdipDeleteMatrix(matrix
);
4456 memcpy(dst_8x1
, back_8x1
, sizeof(dst_8x1
));
4457 status
= GdipDrawImageI(graphics
, u1
.image
, 1, 0);
4460 match
= memcmp(dst_8x1
, td
[i
].image
, sizeof(dst_8x1
)) == 0;
4461 todo_wine_if (!match
&& td
[i
].todo
)
4462 ok(match
, "%d: data should match\n", i
);
4465 UINT i
, size
= sizeof(dst_8x1
);
4466 const BYTE
*bits
= dst_8x1
;
4467 for (i
= 0; i
< size
; i
++)
4468 trace(" %02x", bits
[i
]);
4473 status
= GdipDeleteGraphics(graphics
);
4475 status
= GdipDisposeImage(u1
.image
);
4477 status
= GdipDisposeImage(u2
.image
);
4481 static const BYTE animatedgif
[] = {
4482 'G','I','F','8','9','a',0x01,0x00,0x01,0x00,0xA1,0x02,0x00,
4483 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
4484 /*0x21,0xFF,0x0B,'A','N','I','M','E','X','T','S','1','.','0',*/
4485 0x21,0xFF,0x0B,'N','E','T','S','C','A','P','E','2','.','0',
4486 0x03,0x01,0x05,0x00,0x00,
4487 0x21,0xFE,0x0C,'H','e','l','l','o',' ','W','o','r','l','d','!',0x00,
4488 0x21,0x01,0x0D,'a','n','i','m','a','t','i','o','n','.','g','i','f',0x00,
4489 0x21,0xF9,0x04,0xff,0x0A,0x00,0x08,0x00,
4490 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4491 0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,
4492 0x02,0x02,0x4C,0x01,0x00,
4493 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','1',0x00,
4494 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','1',0x00,
4495 0x21,0xF9,0x04,0x00,0x14,0x00,0x01,0x00,
4496 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4497 0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,
4498 0x02,0x02,0x44,0x01,0x00,
4499 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','2',0x00,
4500 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','2',0x00,0x3B
4503 static void test_gif_properties(void)
4505 static const struct test_data
4507 ULONG type
, id
, length
;
4508 const BYTE value
[13];
4511 { PropertyTagTypeLong
, PropertyTagFrameDelay
, 8, { 10,0,0,0,20,0,0,0 } },
4512 { PropertyTagTypeASCII
, PropertyTagExifUserComment
, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
4513 { PropertyTagTypeShort
, PropertyTagLoopCount
, 2, { 5,0 } },
4514 { PropertyTagTypeByte
, PropertyTagGlobalPalette
, 12, { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c } },
4515 { PropertyTagTypeByte
, PropertyTagIndexBackground
, 1, { 2 } },
4516 { PropertyTagTypeByte
, PropertyTagIndexTransparent
, 1, { 8 } }
4521 UINT dim_count
, frame_count
, prop_count
, prop_size
, i
;
4522 UINT total_size
, total_count
;
4524 PropertyItem
*prop_item
;
4525 const char *item_data
;
4527 image
= load_image(animatedgif
, sizeof(animatedgif
));
4528 if (!image
) /* XP fails to load this GIF image */
4530 trace("Failed to load GIF image data\n");
4534 status
= GdipImageGetFrameDimensionsCount(image
, &dim_count
);
4536 expect(1, dim_count
);
4538 status
= GdipImageGetFrameDimensionsList(image
, &guid
, 1);
4540 expect_guid(&FrameDimensionTime
, &guid
, __LINE__
, FALSE
);
4542 status
= GdipImageGetFrameCount(image
, &guid
, &frame_count
);
4544 expect(2, frame_count
);
4546 status
= GdipImageSelectActiveFrame(image
, &guid
, 1);
4549 status
= GdipGetPropertyCount(image
, &prop_count
);
4551 ok(prop_count
== sizeof(td
)/sizeof(td
[0]) || broken(prop_count
== 1) /* before win7 */,
4552 "expected property count %u, got %u\n", (UINT
)(sizeof(td
)/sizeof(td
[0])), prop_count
);
4554 if (prop_count
!= sizeof(td
)/sizeof(td
[0]))
4556 GdipDisposeImage(image
);
4560 prop_id
= HeapAlloc(GetProcessHeap(), 0, prop_count
* sizeof(*prop_id
));
4562 status
= GdipGetPropertyIdList(image
, prop_count
, prop_id
);
4566 for (i
= 0; i
< prop_count
; i
++)
4569 status
= GdipGetPropertyItemSize(image
, prop_id
[i
], &size
);
4571 if (status
!= Ok
) break;
4572 ok(size
> sizeof(*prop_item
), "%u: too small item length %u\n", i
, size
);
4576 prop_item
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
4577 status
= GdipGetPropertyItem(image
, prop_id
[i
], size
, prop_item
);
4579 ok(prop_item
->value
== prop_item
+ 1, "expected item->value %p, got %p\n", prop_item
+ 1, prop_item
->value
);
4580 ok(td
[i
].type
== prop_item
->type
,
4581 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
->type
);
4582 ok(td
[i
].id
== prop_item
->id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
->id
);
4583 size
-= sizeof(*prop_item
);
4584 ok(prop_item
->length
== size
, "%u: expected length %u, got %u\n", i
, size
, prop_item
->length
);
4585 ok(td
[i
].length
== prop_item
->length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
->length
);
4586 if (td
[i
].length
== prop_item
->length
)
4588 int match
= memcmp(td
[i
].value
, prop_item
->value
, td
[i
].length
) == 0;
4589 ok(match
, "%u: data mismatch\n", i
);
4593 BYTE
*data
= prop_item
->value
;
4594 trace("id %#x:", prop_item
->id
);
4595 for (j
= 0; j
< prop_item
->length
; j
++)
4596 trace(" %02x", data
[j
]);
4600 HeapFree(GetProcessHeap(), 0, prop_item
);
4603 HeapFree(GetProcessHeap(), 0, prop_id
);
4605 status
= GdipGetPropertySize(NULL
, &total_size
, &total_count
);
4606 expect(InvalidParameter
, status
);
4607 status
= GdipGetPropertySize(image
, &total_size
, NULL
);
4608 expect(InvalidParameter
, status
);
4609 status
= GdipGetPropertySize(image
, NULL
, &total_count
);
4610 expect(InvalidParameter
, status
);
4611 status
= GdipGetPropertySize(image
, NULL
, NULL
);
4612 expect(InvalidParameter
, status
);
4613 total_size
= 0xdeadbeef;
4614 total_count
= 0xdeadbeef;
4615 status
= GdipGetPropertySize(image
, &total_size
, &total_count
);
4617 ok(prop_count
== total_count
,
4618 "expected total property count %u, got %u\n", prop_count
, total_count
);
4619 ok(prop_size
== total_size
,
4620 "expected total property size %u, got %u\n", prop_size
, total_size
);
4622 prop_item
= HeapAlloc(GetProcessHeap(), 0, prop_size
);
4624 status
= GdipGetAllPropertyItems(image
, 0, prop_count
, prop_item
);
4625 expect(InvalidParameter
, status
);
4626 status
= GdipGetAllPropertyItems(image
, prop_size
, 1, prop_item
);
4627 expect(InvalidParameter
, status
);
4628 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4629 expect(InvalidParameter
, status
);
4630 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, NULL
);
4631 expect(InvalidParameter
, status
);
4632 status
= GdipGetAllPropertyItems(image
, 0, 0, NULL
);
4633 expect(InvalidParameter
, status
);
4634 status
= GdipGetAllPropertyItems(image
, prop_size
+ 1, prop_count
, prop_item
);
4635 expect(InvalidParameter
, status
);
4636 status
= GdipGetAllPropertyItems(image
, prop_size
, prop_count
, prop_item
);
4639 item_data
= (const char *)(prop_item
+ prop_count
);
4640 for (i
= 0; i
< prop_count
; i
++)
4642 ok(prop_item
[i
].value
== item_data
, "%u: expected value %p, got %p\n",
4643 i
, item_data
, prop_item
[i
].value
);
4644 ok(td
[i
].type
== prop_item
[i
].type
,
4645 "%u: expected type %u, got %u\n", i
, td
[i
].type
, prop_item
[i
].type
);
4646 ok(td
[i
].id
== prop_item
[i
].id
, "%u: expected id %#x, got %#x\n", i
, td
[i
].id
, prop_item
[i
].id
);
4647 ok(td
[i
].length
== prop_item
[i
].length
, "%u: expected length %u, got %u\n", i
, td
[i
].length
, prop_item
[i
].length
);
4648 if (td
[i
].length
== prop_item
[i
].length
)
4650 int match
= memcmp(td
[i
].value
, prop_item
[i
].value
, td
[i
].length
) == 0;
4651 ok(match
, "%u: data mismatch\n", i
);
4655 BYTE
*data
= prop_item
[i
].value
;
4656 trace("id %#x:", prop_item
[i
].id
);
4657 for (j
= 0; j
< prop_item
[i
].length
; j
++)
4658 trace(" %02x", data
[j
]);
4662 item_data
+= prop_item
[i
].length
;
4665 HeapFree(GetProcessHeap(), 0, prop_item
);
4667 GdipDisposeImage(image
);
4670 static void test_ARGB_conversion(void)
4672 BYTE argb
[8] = { 0x11,0x22,0x33,0x80, 0xff,0xff,0xff,0 };
4673 BYTE pargb
[8] = { 0x09,0x11,0x1a,0x80, 0,0,0,0 };
4674 BYTE rgb32_xp
[8] = { 0x11,0x22,0x33,0xff, 0xff,0xff,0xff,0xff };
4675 BYTE rgb24
[6] = { 0x11,0x22,0x33, 0xff,0xff,0xff };
4682 status
= GdipCreateBitmapFromScan0(2, 1, 8, PixelFormat32bppARGB
, argb
, &bitmap
);
4685 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppPARGB
, &data
);
4687 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4688 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4689 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4690 ok(data
.PixelFormat
== PixelFormat32bppPARGB
, "expected PixelFormat32bppPARGB, got %d\n", data
.PixelFormat
);
4691 match
= !memcmp(data
.Scan0
, pargb
, sizeof(pargb
));
4692 ok(match
, "bits don't match\n");
4696 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppPARGB
,
4697 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4699 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4702 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat32bppRGB
, &data
);
4704 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4705 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4706 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4707 ok(data
.PixelFormat
== PixelFormat32bppRGB
, "expected PixelFormat32bppRGB, got %d\n", data
.PixelFormat
);
4708 match
= !memcmp(data
.Scan0
, argb
, sizeof(argb
)) ||
4709 !memcmp(data
.Scan0
, rgb32_xp
, sizeof(rgb32_xp
));
4710 ok(match
, "bits don't match\n");
4714 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppRGB
,
4715 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4717 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4720 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data
);
4722 ok(data
.Width
== 2, "expected 2, got %d\n", data
.Width
);
4723 ok(data
.Height
== 1, "expected 1, got %d\n", data
.Height
);
4724 ok(data
.Stride
== 8, "expected 8, got %d\n", data
.Stride
);
4725 ok(data
.PixelFormat
== PixelFormat24bppRGB
, "expected PixelFormat24bppRGB, got %d\n", data
.PixelFormat
);
4726 match
= !memcmp(data
.Scan0
, rgb24
, sizeof(rgb24
));
4727 ok(match
, "bits don't match\n");
4731 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat24bppRGB
,
4732 bits
[0], bits
[1], bits
[2], bits
[3], bits
[4], bits
[5], bits
[6], bits
[7]);
4734 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4737 GdipDisposeImage((GpImage
*)bitmap
);
4741 static void test_CloneBitmapArea(void)
4744 GpBitmap
*bitmap
, *copy
;
4745 BitmapData data
, data2
;
4747 status
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB
, NULL
, &bitmap
);
4750 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
| ImageLockModeWrite
, PixelFormat24bppRGB
, &data
);
4753 status
= GdipBitmapLockBits(bitmap
, NULL
, ImageLockModeRead
, PixelFormat24bppRGB
, &data2
);
4754 expect(WrongState
, status
);
4756 status
= GdipCloneBitmapAreaI(0, 0, 1, 1, PixelFormat24bppRGB
, bitmap
, ©
);
4759 status
= GdipBitmapUnlockBits(bitmap
, &data
);
4762 GdipDisposeImage((GpImage
*)copy
);
4763 GdipDisposeImage((GpImage
*)bitmap
);
4766 static BOOL
get_encoder_clsid(LPCWSTR mime
, GUID
*format
, CLSID
*clsid
)
4769 UINT n_codecs
, info_size
, i
;
4770 ImageCodecInfo
*info
;
4773 status
= GdipGetImageEncodersSize(&n_codecs
, &info_size
);
4776 info
= GdipAlloc(info_size
);
4778 status
= GdipGetImageEncoders(n_codecs
, info_size
, info
);
4781 for (i
= 0; i
< n_codecs
; i
++)
4783 if (!lstrcmpW(info
[i
].MimeType
, mime
))
4785 *format
= info
[i
].FormatID
;
4786 *clsid
= info
[i
].Clsid
;
4796 static void test_supported_encoders(void)
4798 static const WCHAR bmp_mimetype
[] = { 'i', 'm', 'a','g', 'e', '/', 'b', 'm', 'p',0 };
4799 static const WCHAR jpeg_mimetype
[] = { 'i','m','a','g','e','/','j','p','e','g',0 };
4800 static const WCHAR gif_mimetype
[] = { 'i','m','a','g','e','/','g','i','f',0 };
4801 static const WCHAR tiff_mimetype
[] = { 'i','m','a','g','e','/','t','i','f','f',0 };
4802 static const WCHAR png_mimetype
[] = { 'i','m','a','g','e','/','p','n','g',0 };
4803 static const struct test_data
4810 { bmp_mimetype
, &ImageFormatBMP
, FALSE
},
4811 { jpeg_mimetype
, &ImageFormatJPEG
, FALSE
},
4812 { gif_mimetype
, &ImageFormatGIF
, TRUE
},
4813 { tiff_mimetype
, &ImageFormatTIFF
, FALSE
},
4814 { png_mimetype
, &ImageFormatPNG
, FALSE
}
4825 status
= GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB
, NULL
, &bm
);
4826 ok(status
== Ok
, "GdipCreateBitmapFromScan0 error %d\n", status
);
4828 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
4830 ret
= get_encoder_clsid(td
[i
].mime
, &format
, &clsid
);
4831 ok(ret
, "%s encoder is not in the list\n", wine_dbgstr_w(td
[i
].mime
));
4832 expect_guid(td
[i
].format
, &format
, __LINE__
, FALSE
);
4834 hmem
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_NODISCARD
, 16);
4836 hr
= CreateStreamOnHGlobal(hmem
, TRUE
, &stream
);
4837 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
4839 status
= GdipSaveImageToStream((GpImage
*)bm
, stream
, &clsid
, NULL
);
4840 todo_wine_if (td
[i
].todo
)
4841 ok(status
== Ok
, "GdipSaveImageToStream error %d\n", status
);
4843 IStream_Release(stream
);
4846 GdipDisposeImage((GpImage
*)bm
);
4849 static void test_createeffect(void)
4851 static const GUID noneffect
= { 0xcd0c3d4b, 0xe15e, 0x4cf2, { 0x9e, 0xa8, 0x6e, 0x1d, 0x65, 0x48, 0xc5, 0xa5 } };
4852 GpStatus (WINAPI
*pGdipCreateEffect
)( const GUID guid
, CGpEffect
**effect
);
4853 GpStatus (WINAPI
*pGdipDeleteEffect
)( CGpEffect
*effect
);
4856 HMODULE mod
= GetModuleHandleA("gdiplus.dll");
4858 const GUID
* const effectlist
[] =
4859 {&BlurEffectGuid
, &SharpenEffectGuid
, &ColorMatrixEffectGuid
, &ColorLUTEffectGuid
,
4860 &BrightnessContrastEffectGuid
, &HueSaturationLightnessEffectGuid
, &LevelsEffectGuid
,
4861 &TintEffectGuid
, &ColorBalanceEffectGuid
, &RedEyeCorrectionEffectGuid
, &ColorCurveEffectGuid
};
4863 pGdipCreateEffect
= (void*)GetProcAddress( mod
, "GdipCreateEffect");
4864 pGdipDeleteEffect
= (void*)GetProcAddress( mod
, "GdipDeleteEffect");
4865 if(!pGdipCreateEffect
|| !pGdipDeleteEffect
)
4867 /* GdipCreateEffect/GdipDeleteEffect was introduced in Windows Vista. */
4868 win_skip("GDIPlus version 1.1 not available\n");
4872 stat
= pGdipCreateEffect(BlurEffectGuid
, NULL
);
4873 expect(InvalidParameter
, stat
);
4875 stat
= pGdipCreateEffect(noneffect
, &effect
);
4876 todo_wine
expect(Win32Error
, stat
);
4878 for(i
=0; i
< sizeof(effectlist
) / sizeof(effectlist
[0]); i
++)
4880 stat
= pGdipCreateEffect(*effectlist
[i
], &effect
);
4881 todo_wine
expect(Ok
, stat
);
4884 stat
= pGdipDeleteEffect(effect
);
4890 static void test_getadjustedpalette(void)
4893 GpImageAttributes
*imageattributes
;
4894 ColorPalette
*palette
;
4897 stat
= GdipCreateImageAttributes(&imageattributes
);
4900 colormap
.oldColor
.Argb
= 0xffffff00;
4901 colormap
.newColor
.Argb
= 0xffff00ff;
4902 stat
= GdipSetImageAttributesRemapTable(imageattributes
, ColorAdjustTypeBitmap
,
4903 TRUE
, 1, &colormap
);
4906 colormap
.oldColor
.Argb
= 0xffffff80;
4907 colormap
.newColor
.Argb
= 0xffff80ff;
4908 stat
= GdipSetImageAttributesRemapTable(imageattributes
, ColorAdjustTypeDefault
,
4909 TRUE
, 1, &colormap
);
4912 palette
= GdipAlloc(sizeof(*palette
) + sizeof(ARGB
) * 2);
4915 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeBitmap
);
4916 expect(InvalidParameter
, stat
);
4919 palette
->Entries
[0] = 0xffffff00;
4920 palette
->Entries
[1] = 0xffffff80;
4921 palette
->Entries
[2] = 0xffffffff;
4923 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeBitmap
);
4925 expect(0xffff00ff, palette
->Entries
[0]);
4926 expect(0xffffff80, palette
->Entries
[1]);
4927 expect(0xffffffff, palette
->Entries
[2]);
4929 palette
->Entries
[0] = 0xffffff00;
4930 palette
->Entries
[1] = 0xffffff80;
4931 palette
->Entries
[2] = 0xffffffff;
4933 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeBrush
);
4935 expect(0xffffff00, palette
->Entries
[0]);
4936 expect(0xffff80ff, palette
->Entries
[1]);
4937 expect(0xffffffff, palette
->Entries
[2]);
4939 stat
= GdipGetImageAttributesAdjustedPalette(NULL
, palette
, ColorAdjustTypeBitmap
);
4940 expect(InvalidParameter
, stat
);
4942 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, NULL
, ColorAdjustTypeBitmap
);
4943 expect(InvalidParameter
, stat
);
4945 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, -1);
4946 expect(InvalidParameter
, stat
);
4948 stat
= GdipGetImageAttributesAdjustedPalette(imageattributes
, palette
, ColorAdjustTypeDefault
);
4949 expect(InvalidParameter
, stat
);
4952 GdipDisposeImageAttributes(imageattributes
);
4955 static void test_histogram(void)
4957 UINT ch0
[256], ch1
[256], ch2
[256], ch3
[256];
4958 HistogramFormat test_formats
[] =
4960 HistogramFormatARGB
,
4961 HistogramFormatPARGB
,
4963 HistogramFormatGray
,
4969 const UINT WIDTH
= 8, HEIGHT
= 16;
4974 if (!pGdipBitmapGetHistogramSize
)
4976 win_skip("GdipBitmapGetHistogramSize is not supported\n");
4980 stat
= pGdipBitmapGetHistogramSize(HistogramFormatARGB
, NULL
);
4981 expect(InvalidParameter
, stat
);
4983 stat
= pGdipBitmapGetHistogramSize(0xff, NULL
);
4984 expect(InvalidParameter
, stat
);
4987 stat
= pGdipBitmapGetHistogramSize(10, &num
);
4991 for (i
= 0; i
< sizeof(test_formats
)/sizeof(test_formats
[0]); i
++)
4994 stat
= pGdipBitmapGetHistogramSize(test_formats
[i
], &num
);
5000 stat
= GdipCreateBitmapFromScan0(WIDTH
, HEIGHT
, 0, PixelFormat24bppRGB
, NULL
, &bm
);
5003 /* Three solid rgb rows, next three rows are rgb shades. */
5004 for (x
= 0; x
< WIDTH
; x
++)
5006 GdipBitmapSetPixel(bm
, x
, 0, 0xffff0000);
5007 GdipBitmapSetPixel(bm
, x
, 1, 0xff00ff00);
5008 GdipBitmapSetPixel(bm
, x
, 2, 0xff0000ff);
5010 GdipBitmapSetPixel(bm
, x
, 3, 0xff010000);
5011 GdipBitmapSetPixel(bm
, x
, 4, 0xff003f00);
5012 GdipBitmapSetPixel(bm
, x
, 5, 0xff000020);
5015 stat
= pGdipBitmapGetHistogram(NULL
, HistogramFormatRGB
, 256, ch0
, ch1
, ch2
, ch3
);
5016 expect(InvalidParameter
, stat
);
5018 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, ch1
, ch2
, ch3
);
5019 expect(InvalidParameter
, stat
);
5021 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, ch1
, ch2
, NULL
);
5022 expect(InvalidParameter
, stat
);
5024 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, ch1
, NULL
, NULL
);
5025 expect(InvalidParameter
, stat
);
5027 stat
= pGdipBitmapGetHistogram(bm
, 123, 256, ch0
, NULL
, NULL
, NULL
);
5028 expect(InvalidParameter
, stat
);
5030 /* Requested format matches bitmap format */
5031 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 256, ch0
, ch1
, ch2
, ch3
);
5032 expect(InvalidParameter
, stat
);
5034 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 100, ch0
, ch1
, ch2
, NULL
);
5035 expect(InvalidParameter
, stat
);
5037 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 257, ch0
, ch1
, ch2
, NULL
);
5038 expect(InvalidParameter
, stat
);
5040 /* Channel 3 is not used, must be NULL */
5041 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatRGB
, 256, ch0
, ch1
, ch2
, NULL
);
5044 ok(ch0
[0xff] == WIDTH
, "Got red (0xff) %u\n", ch0
[0xff]);
5045 ok(ch1
[0xff] == WIDTH
, "Got green (0xff) %u\n", ch1
[0xff]);
5046 ok(ch2
[0xff] == WIDTH
, "Got blue (0xff) %u\n", ch1
[0xff]);
5047 ok(ch0
[0x01] == WIDTH
, "Got red (0x01) %u\n", ch0
[0x01]);
5048 ok(ch1
[0x3f] == WIDTH
, "Got green (0x3f) %u\n", ch1
[0x3f]);
5049 ok(ch2
[0x20] == WIDTH
, "Got blue (0x20) %u\n", ch1
[0x20]);
5051 /* ARGB histogram from RGB data. */
5052 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatARGB
, 256, ch0
, ch1
, ch2
, NULL
);
5053 expect(InvalidParameter
, stat
);
5055 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatARGB
, 256, ch0
, ch1
, ch2
, ch3
);
5058 ok(ch1
[0xff] == WIDTH
, "Got red (0xff) %u\n", ch1
[0xff]);
5059 ok(ch2
[0xff] == WIDTH
, "Got green (0xff) %u\n", ch2
[0xff]);
5060 ok(ch3
[0xff] == WIDTH
, "Got blue (0xff) %u\n", ch3
[0xff]);
5061 ok(ch1
[0x01] == WIDTH
, "Got red (0x01) %u\n", ch1
[0x01]);
5062 ok(ch2
[0x3f] == WIDTH
, "Got green (0x3f) %u\n", ch2
[0x3f]);
5063 ok(ch3
[0x20] == WIDTH
, "Got blue (0x20) %u\n", ch3
[0x20]);
5065 ok(ch0
[0xff] == WIDTH
* HEIGHT
, "Got alpha (0xff) %u\n", ch0
[0xff]);
5067 /* Request grayscale histogram from RGB bitmap. */
5068 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, ch1
, ch2
, ch3
);
5069 expect(InvalidParameter
, stat
);
5071 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, ch1
, ch2
, NULL
);
5072 expect(InvalidParameter
, stat
);
5074 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, ch1
, NULL
, NULL
);
5075 expect(InvalidParameter
, stat
);
5077 stat
= pGdipBitmapGetHistogram(bm
, HistogramFormatGray
, 256, ch0
, NULL
, NULL
, NULL
);
5080 GdipDisposeImage((GpImage
*)bm
);
5083 static void test_imageabort(void)
5088 if (!pGdipImageSetAbort
)
5090 win_skip("GdipImageSetAbort() is not supported.\n");
5095 stat
= GdipCreateBitmapFromScan0(8, 8, 0, PixelFormat24bppRGB
, NULL
, &bm
);
5098 stat
= pGdipImageSetAbort(NULL
, NULL
);
5099 expect(InvalidParameter
, stat
);
5101 stat
= pGdipImageSetAbort((GpImage
*)bm
, NULL
);
5104 GdipDisposeImage((GpImage
*)bm
);
5107 /* RGB 24 bpp 1x1 pixel PNG image */
5108 static const char png_1x1_data
[] = {
5109 0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,
5110 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,
5111 0x00,0x00,0x00,0x0c,'I','D','A','T',0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,0xe7,
5112 0x00,0x00,0x00,0x00,'I','E','N','D',0xae,0x42,0x60,0x82
5115 static void test_png_color_formats(void)
5119 char bit_depth
, color_type
;
5124 /* 2 - PNG_COLOR_TYPE_RGB */
5125 { 8, 2, PixelFormat24bppRGB
, ImageFlagsColorSpaceRGB
},
5126 /* 0 - PNG_COLOR_TYPE_GRAY */
5127 { 1, 0, PixelFormat1bppIndexed
, ImageFlagsColorSpaceRGB
},
5128 { 2, 0, PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
},
5129 { 4, 0, PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
},
5130 { 8, 0, PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
},
5131 { 16, 0, PixelFormat32bppARGB
, ImageFlagsColorSpaceGRAY
},
5133 BYTE buf
[sizeof(png_1x1_data
)];
5141 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
5143 memcpy(buf
, png_1x1_data
, sizeof(png_1x1_data
));
5144 buf
[24] = td
[i
].bit_depth
;
5145 buf
[25] = td
[i
].color_type
;
5147 image
= load_image(buf
, sizeof(buf
));
5148 ok(image
!= NULL
, "%d: failed to load image data\n", i
);
5149 if (!image
) continue;
5151 status
= GdipGetImageType(image
, &type
);
5152 ok(status
== Ok
, "%u: GdipGetImageType error %d\n", i
, status
);
5153 ok(type
== ImageTypeBitmap
, "%d: wrong image type %d\n", i
, type
);
5155 status
= GdipGetImagePixelFormat(image
, &format
);
5157 ok(format
== td
[i
].format
||
5158 broken(td
[i
].bit_depth
== 1 && td
[i
].color_type
== 0 && format
== PixelFormat32bppARGB
), /* XP */
5159 "%d: expected %#x, got %#x\n", i
, td
[i
].format
, format
);
5161 status
= GdipGetImageFlags(image
, &flags
);
5163 ok((flags
& td
[i
].flags
) == td
[i
].flags
||
5164 broken(td
[i
].bit_depth
== 1 && td
[i
].color_type
== 0 && (flags
& ImageFlagsColorSpaceGRAY
)), /* XP */
5165 "%d: expected %#x, got %#x\n", i
, td
[i
].flags
, flags
);
5167 GdipDisposeImage(image
);
5173 HMODULE mod
= GetModuleHandleA("gdiplus.dll");
5174 struct GdiplusStartupInput gdiplusStartupInput
;
5175 ULONG_PTR gdiplusToken
;
5177 int (CDECL
* _controlfp_s
)(unsigned int *cur
, unsigned int newval
, unsigned int mask
);
5179 /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */
5180 hmsvcrt
= LoadLibraryA("msvcrt");
5181 _controlfp_s
= (void*)GetProcAddress(hmsvcrt
, "_controlfp_s");
5182 if (_controlfp_s
) _controlfp_s(0, 0, 0x0008001e);
5184 gdiplusStartupInput
.GdiplusVersion
= 1;
5185 gdiplusStartupInput
.DebugEventCallback
= NULL
;
5186 gdiplusStartupInput
.SuppressBackgroundThread
= 0;
5187 gdiplusStartupInput
.SuppressExternalCodecs
= 0;
5189 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, NULL
);
5191 pGdipBitmapGetHistogramSize
= (void*)GetProcAddress(mod
, "GdipBitmapGetHistogramSize");
5192 pGdipBitmapGetHistogram
= (void*)GetProcAddress(mod
, "GdipBitmapGetHistogram");
5193 pGdipImageSetAbort
= (void*)GetProcAddress(mod
, "GdipImageSetAbort");
5195 test_png_color_formats();
5196 test_supported_encoders();
5197 test_CloneBitmapArea();
5198 test_ARGB_conversion();
5199 test_DrawImage_scale();
5200 test_image_format();
5202 test_DrawImage_SourceCopy();
5203 test_GdipDrawImagePointRect();
5205 test_tiff_palette();
5206 test_GdipGetAllPropertyItems();
5207 test_tiff_properties();
5208 test_gif_properties();
5209 test_image_properties();
5212 test_GetImageDimension();
5213 test_GdipImageGetFrameDimensionsCount();
5214 test_LoadingImages();
5215 test_SavingImages();
5218 test_LockBits_UserBuf();
5219 test_GdipCreateBitmapFromHBITMAP();
5220 test_GdipGetImageFlags();
5221 test_GdipCloneImage();
5224 test_getrawformat();
5226 test_createfromwmf();
5227 test_createfromwmf_noplaceable();
5229 test_createhbitmap();
5230 test_getthumbnail();
5235 test_multiframegif();
5240 test_createeffect();
5241 test_getadjustedpalette();
5245 GdiplusShutdown(gdiplusToken
);