vbscript: Added support for title and type arguments of MsgBox.
[wine.git] / dlls / gdiplus / tests / image.c
blobb88238bcd0ba64ee5e76ef2538f415daaecb6c37
1 /*
2 * Unit test suite for images
4 * Copyright (C) 2007 Google (Evan Stade)
5 * Copyright (C) 2012 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
22 #define COBJMACROS
24 #include <math.h>
25 #include <assert.h>
26 #include <stdio.h>
28 #include "initguid.h"
29 #include "objbase.h"
30 #include "gdiplus.h"
31 #include "wine/test.h"
33 #define expect(expected, got) ok((got) == (expected), "Expected %d, got %d\n", (UINT)(expected), (UINT)(got))
34 #define expectf(expected, got) ok(fabs((expected) - (got)) < 0.0001, "Expected %f, got %f\n", (expected), (got))
36 static BOOL color_match(ARGB c1, ARGB c2, BYTE max_diff)
38 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
39 c1 >>= 8; c2 >>= 8;
40 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
41 c1 >>= 8; c2 >>= 8;
42 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
43 c1 >>= 8; c2 >>= 8;
44 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
45 return TRUE;
48 static void expect_guid(REFGUID expected, REFGUID got, int line, BOOL todo)
50 WCHAR bufferW[39];
51 char buffer[39];
52 char buffer2[39];
54 StringFromGUID2(got, bufferW, sizeof(bufferW)/sizeof(bufferW[0]));
55 WideCharToMultiByte(CP_ACP, 0, bufferW, sizeof(bufferW)/sizeof(bufferW[0]), buffer, sizeof(buffer), NULL, NULL);
56 StringFromGUID2(expected, bufferW, sizeof(bufferW)/sizeof(bufferW[0]));
57 WideCharToMultiByte(CP_ACP, 0, bufferW, sizeof(bufferW)/sizeof(bufferW[0]), buffer2, sizeof(buffer2), NULL, NULL);
58 if(todo)
59 todo_wine ok_(__FILE__, line)(IsEqualGUID(expected, got), "Expected %s, got %s\n", buffer2, buffer);
60 else
61 ok_(__FILE__, line)(IsEqualGUID(expected, got), "Expected %s, got %s\n", buffer2, buffer);
64 static void expect_rawformat(REFGUID expected, GpImage *img, int line, BOOL todo)
66 GUID raw;
67 GpStatus stat;
69 stat = GdipGetImageRawFormat(img, &raw);
70 ok_(__FILE__, line)(stat == Ok, "GdipGetImageRawFormat failed with %d\n", stat);
71 if(stat != Ok) return;
72 expect_guid(expected, &raw, line, todo);
75 static void test_bufferrawformat(void* buff, int size, REFGUID expected, int line, BOOL todo)
77 LPSTREAM stream;
78 HGLOBAL hglob;
79 LPBYTE data;
80 HRESULT hres;
81 GpStatus stat;
82 GpImage *img;
84 hglob = GlobalAlloc (0, size);
85 data = GlobalLock (hglob);
86 memcpy(data, buff, size);
87 GlobalUnlock(hglob); data = NULL;
89 hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
90 ok_(__FILE__, line)(hres == S_OK, "Failed to create a stream\n");
91 if(hres != S_OK) return;
93 stat = GdipLoadImageFromStream(stream, &img);
94 ok_(__FILE__, line)(stat == Ok, "Failed to create a Bitmap\n");
95 if(stat != Ok){
96 IStream_Release(stream);
97 return;
100 expect_rawformat(expected, img, line, todo);
102 GdipDisposeImage(img);
103 IStream_Release(stream);
106 static void test_Scan0(void)
108 GpBitmap *bm;
109 GpStatus stat;
110 BYTE buff[360];
112 bm = NULL;
113 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, NULL, &bm);
114 expect(Ok, stat);
115 ok(NULL != bm, "Expected bitmap to be initialized\n");
116 if (stat == Ok)
117 GdipDisposeImage((GpImage*)bm);
119 bm = (GpBitmap*)0xdeadbeef;
120 stat = GdipCreateBitmapFromScan0(10, -10, 10, PixelFormat24bppRGB, NULL, &bm);
121 expect(InvalidParameter, stat);
122 ok( !bm, "expected null bitmap\n" );
124 bm = (GpBitmap*)0xdeadbeef;
125 stat = GdipCreateBitmapFromScan0(-10, 10, 10, PixelFormat24bppRGB, NULL, &bm);
126 expect(InvalidParameter, stat);
127 ok( !bm, "expected null bitmap\n" );
129 bm = (GpBitmap*)0xdeadbeef;
130 stat = GdipCreateBitmapFromScan0(10, 0, 10, PixelFormat24bppRGB, NULL, &bm);
131 expect(InvalidParameter, stat);
132 ok( !bm, "expected null bitmap\n" );
134 bm = NULL;
135 stat = GdipCreateBitmapFromScan0(10, 10, 12, PixelFormat24bppRGB, buff, &bm);
136 expect(Ok, stat);
137 ok(NULL != bm, "Expected bitmap to be initialized\n");
138 if (stat == Ok)
139 GdipDisposeImage((GpImage*)bm);
141 bm = (GpBitmap*) 0xdeadbeef;
142 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, buff, &bm);
143 expect(InvalidParameter, stat);
144 ok( !bm, "expected null bitmap\n" );
146 bm = (GpBitmap*)0xdeadbeef;
147 stat = GdipCreateBitmapFromScan0(10, 10, 0, PixelFormat24bppRGB, buff, &bm);
148 expect(InvalidParameter, stat);
149 ok( bm == (GpBitmap*)0xdeadbeef, "expected deadbeef bitmap\n" );
151 bm = NULL;
152 stat = GdipCreateBitmapFromScan0(10, 10, -8, PixelFormat24bppRGB, buff, &bm);
153 expect(Ok, stat);
154 ok(NULL != bm, "Expected bitmap to be initialized\n");
155 if (stat == Ok)
156 GdipDisposeImage((GpImage*)bm);
158 bm = (GpBitmap*)0xdeadbeef;
159 stat = GdipCreateBitmapFromScan0(10, 10, -10, PixelFormat24bppRGB, buff, &bm);
160 expect(InvalidParameter, stat);
161 ok( !bm, "expected null bitmap\n" );
164 static void test_FromGdiDib(void)
166 GpBitmap *bm;
167 GpStatus stat;
168 BYTE buff[400];
169 BYTE rbmi[sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)];
170 BITMAPINFO *bmi = (BITMAPINFO*)rbmi;
171 PixelFormat format;
173 bm = NULL;
175 memset(rbmi, 0, sizeof(rbmi));
177 bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
178 bmi->bmiHeader.biWidth = 10;
179 bmi->bmiHeader.biHeight = 10;
180 bmi->bmiHeader.biPlanes = 1;
181 bmi->bmiHeader.biBitCount = 32;
182 bmi->bmiHeader.biCompression = BI_RGB;
184 stat = GdipCreateBitmapFromGdiDib(NULL, buff, &bm);
185 expect(InvalidParameter, stat);
187 stat = GdipCreateBitmapFromGdiDib(bmi, NULL, &bm);
188 expect(InvalidParameter, stat);
190 stat = GdipCreateBitmapFromGdiDib(bmi, buff, NULL);
191 expect(InvalidParameter, stat);
193 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
194 expect(Ok, stat);
195 ok(NULL != bm, "Expected bitmap to be initialized\n");
196 if (stat == Ok)
198 stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
199 expect(Ok, stat);
200 expect(PixelFormat32bppRGB, format);
202 GdipDisposeImage((GpImage*)bm);
205 bmi->bmiHeader.biBitCount = 24;
206 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
207 expect(Ok, stat);
208 ok(NULL != bm, "Expected bitmap to be initialized\n");
209 if (stat == Ok)
211 stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
212 expect(Ok, stat);
213 expect(PixelFormat24bppRGB, format);
215 GdipDisposeImage((GpImage*)bm);
218 bmi->bmiHeader.biBitCount = 16;
219 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
220 expect(Ok, stat);
221 ok(NULL != bm, "Expected bitmap to be initialized\n");
222 if (stat == Ok)
224 stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
225 expect(Ok, stat);
226 expect(PixelFormat16bppRGB555, format);
228 GdipDisposeImage((GpImage*)bm);
231 bmi->bmiHeader.biBitCount = 8;
232 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
233 expect(Ok, stat);
234 ok(NULL != bm, "Expected bitmap to be initialized\n");
235 if (stat == Ok)
237 stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
238 expect(Ok, stat);
239 expect(PixelFormat8bppIndexed, format);
241 GdipDisposeImage((GpImage*)bm);
244 bmi->bmiHeader.biBitCount = 4;
245 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
246 expect(Ok, stat);
247 ok(NULL != bm, "Expected bitmap to be initialized\n");
248 if (stat == Ok)
250 stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
251 expect(Ok, stat);
252 expect(PixelFormat4bppIndexed, format);
254 GdipDisposeImage((GpImage*)bm);
257 bmi->bmiHeader.biBitCount = 1;
258 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
259 expect(Ok, stat);
260 ok(NULL != bm, "Expected bitmap to be initialized\n");
261 if (stat == Ok)
263 stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
264 expect(Ok, stat);
265 expect(PixelFormat1bppIndexed, format);
267 GdipDisposeImage((GpImage*)bm);
270 bmi->bmiHeader.biBitCount = 0;
271 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
272 expect(InvalidParameter, stat);
275 static void test_GetImageDimension(void)
277 GpBitmap *bm;
278 GpStatus stat;
279 const REAL WIDTH = 10.0, HEIGHT = 20.0;
280 REAL w,h;
282 bm = (GpBitmap*)0xdeadbeef;
283 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB,NULL, &bm);
284 expect(Ok,stat);
285 ok((GpBitmap*)0xdeadbeef != bm, "Expected bitmap to not be 0xdeadbeef\n");
286 ok(NULL != bm, "Expected bitmap to not be NULL\n");
288 stat = GdipGetImageDimension(NULL,&w,&h);
289 expect(InvalidParameter, stat);
291 stat = GdipGetImageDimension((GpImage*)bm,NULL,&h);
292 expect(InvalidParameter, stat);
294 stat = GdipGetImageDimension((GpImage*)bm,&w,NULL);
295 expect(InvalidParameter, stat);
297 w = -1;
298 h = -1;
299 stat = GdipGetImageDimension((GpImage*)bm,&w,&h);
300 expect(Ok, stat);
301 expectf(WIDTH, w);
302 expectf(HEIGHT, h);
303 GdipDisposeImage((GpImage*)bm);
306 static void test_GdipImageGetFrameDimensionsCount(void)
308 GpBitmap *bm;
309 GpStatus stat;
310 const REAL WIDTH = 10.0, HEIGHT = 20.0;
311 UINT w;
312 GUID dimension = {0};
313 UINT count;
314 ARGB color;
316 bm = (GpBitmap*)0xdeadbeef;
317 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB,NULL, &bm);
318 expect(Ok,stat);
319 ok((GpBitmap*)0xdeadbeef != bm, "Expected bitmap to not be 0xdeadbeef\n");
320 ok(NULL != bm, "Expected bitmap to not be NULL\n");
322 stat = GdipImageGetFrameDimensionsCount(NULL,&w);
323 expect(InvalidParameter, stat);
325 stat = GdipImageGetFrameDimensionsCount((GpImage*)bm,NULL);
326 expect(InvalidParameter, stat);
328 w = -1;
329 stat = GdipImageGetFrameDimensionsCount((GpImage*)bm,&w);
330 expect(Ok, stat);
331 expect(1, w);
333 stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 1);
334 expect(Ok, stat);
335 expect_guid(&FrameDimensionPage, &dimension, __LINE__, FALSE);
337 stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 2);
338 expect(InvalidParameter, stat);
340 stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 0);
341 expect(InvalidParameter, stat);
343 stat = GdipImageGetFrameCount(NULL, &dimension, &count);
344 expect(InvalidParameter, stat);
346 /* WinXP crashes on this test */
347 if(0)
349 stat = GdipImageGetFrameCount((GpImage*)bm, &dimension, NULL);
350 expect(InvalidParameter, stat);
353 stat = GdipImageGetFrameCount((GpImage*)bm, NULL, &count);
354 expect(Ok, stat);
356 count = 12345;
357 stat = GdipImageGetFrameCount((GpImage*)bm, &dimension, &count);
358 expect(Ok, stat);
359 expect(1, count);
361 GdipBitmapSetPixel(bm, 0, 0, 0xffffffff);
363 stat = GdipImageSelectActiveFrame((GpImage*)bm, &dimension, 0);
364 expect(Ok, stat);
366 /* SelectActiveFrame has no effect on image data of memory bitmaps */
367 color = 0xdeadbeef;
368 GdipBitmapGetPixel(bm, 0, 0, &color);
369 expect(0xffffffff, color);
371 GdipDisposeImage((GpImage*)bm);
374 static void test_LoadingImages(void)
376 GpStatus stat;
377 GpBitmap *bm;
378 GpImage *img;
379 static const WCHAR nonexistentW[] = {'n','o','n','e','x','i','s','t','e','n','t',0};
381 stat = GdipCreateBitmapFromFile(0, 0);
382 expect(InvalidParameter, stat);
384 bm = (GpBitmap *)0xdeadbeef;
385 stat = GdipCreateBitmapFromFile(0, &bm);
386 expect(InvalidParameter, stat);
387 ok(bm == (GpBitmap *)0xdeadbeef, "returned %p\n", bm);
389 bm = (GpBitmap *)0xdeadbeef;
390 stat = GdipCreateBitmapFromFile(nonexistentW, &bm);
391 todo_wine expect(InvalidParameter, stat);
392 ok(!bm, "returned %p\n", bm);
394 stat = GdipLoadImageFromFile(0, 0);
395 expect(InvalidParameter, stat);
397 img = (GpImage *)0xdeadbeef;
398 stat = GdipLoadImageFromFile(0, &img);
399 expect(InvalidParameter, stat);
400 ok(img == (GpImage *)0xdeadbeef, "returned %p\n", img);
402 img = (GpImage *)0xdeadbeef;
403 stat = GdipLoadImageFromFile(nonexistentW, &img);
404 todo_wine expect(OutOfMemory, stat);
405 ok(!img, "returned %p\n", img);
407 stat = GdipLoadImageFromFileICM(0, 0);
408 expect(InvalidParameter, stat);
410 img = (GpImage *)0xdeadbeef;
411 stat = GdipLoadImageFromFileICM(0, &img);
412 expect(InvalidParameter, stat);
413 ok(img == (GpImage *)0xdeadbeef, "returned %p\n", img);
415 img = (GpImage *)0xdeadbeef;
416 stat = GdipLoadImageFromFileICM(nonexistentW, &img);
417 todo_wine expect(OutOfMemory, stat);
418 ok(!img, "returned %p\n", img);
421 static void test_SavingImages(void)
423 GpStatus stat;
424 GpBitmap *bm;
425 UINT n;
426 UINT s;
427 const REAL WIDTH = 10.0, HEIGHT = 20.0;
428 REAL w, h;
429 ImageCodecInfo *codecs;
430 static const CHAR filenameA[] = "a.bmp";
431 static const WCHAR filename[] = { 'a','.','b','m','p',0 };
433 codecs = NULL;
435 stat = GdipSaveImageToFile(0, 0, 0, 0);
436 expect(InvalidParameter, stat);
438 bm = NULL;
439 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
440 expect(Ok, stat);
441 if (!bm)
442 return;
444 /* invalid params */
445 stat = GdipSaveImageToFile((GpImage*)bm, 0, 0, 0);
446 expect(InvalidParameter, stat);
448 stat = GdipSaveImageToFile((GpImage*)bm, filename, 0, 0);
449 expect(InvalidParameter, stat);
451 /* encoder tests should succeed -- already tested */
452 stat = GdipGetImageEncodersSize(&n, &s);
453 if (stat != Ok || n == 0) goto cleanup;
455 codecs = GdipAlloc(s);
456 if (!codecs) goto cleanup;
458 stat = GdipGetImageEncoders(n, s, codecs);
459 if (stat != Ok) goto cleanup;
461 stat = GdipSaveImageToFile((GpImage*)bm, filename, &codecs[0].Clsid, 0);
462 expect(Ok, stat);
464 GdipDisposeImage((GpImage*)bm);
465 bm = 0;
467 /* re-load and check image stats */
468 stat = GdipLoadImageFromFile(filename, (GpImage**)&bm);
469 expect(Ok, stat);
470 if (stat != Ok) goto cleanup;
472 stat = GdipGetImageDimension((GpImage*)bm, &w, &h);
473 if (stat != Ok) goto cleanup;
475 expectf(WIDTH, w);
476 expectf(HEIGHT, h);
478 cleanup:
479 GdipFree(codecs);
480 if (bm)
481 GdipDisposeImage((GpImage*)bm);
482 ok(DeleteFileA(filenameA), "Delete failed.\n");
485 static void test_encoders(void)
487 GpStatus stat;
488 UINT n;
489 UINT s;
490 ImageCodecInfo *codecs;
491 int i;
492 int bmp_found;
494 static const CHAR bmp_format[] = "BMP";
496 stat = GdipGetImageEncodersSize(&n, &s);
497 expect(stat, Ok);
499 codecs = GdipAlloc(s);
500 if (!codecs)
501 return;
503 stat = GdipGetImageEncoders(n, s, NULL);
504 expect(GenericError, stat);
506 stat = GdipGetImageEncoders(0, s, codecs);
507 expect(GenericError, stat);
509 stat = GdipGetImageEncoders(n, s-1, codecs);
510 expect(GenericError, stat);
512 stat = GdipGetImageEncoders(n, s+1, codecs);
513 expect(GenericError, stat);
515 stat = GdipGetImageEncoders(n, s, codecs);
516 expect(stat, Ok);
518 bmp_found = FALSE;
519 for (i = 0; i < n; i++)
521 CHAR desc[32];
523 WideCharToMultiByte(CP_ACP, 0, codecs[i].FormatDescription, -1,
524 desc, 32, 0, 0);
526 if (CompareStringA(LOCALE_SYSTEM_DEFAULT, 0,
527 desc, -1,
528 bmp_format, -1) == CSTR_EQUAL) {
529 bmp_found = TRUE;
530 break;
533 if (!bmp_found)
534 ok(FALSE, "No BMP codec found.\n");
536 GdipFree(codecs);
539 static void test_LockBits(void)
541 GpStatus stat;
542 GpBitmap *bm;
543 GpRect rect;
544 BitmapData bd;
545 const INT WIDTH = 10, HEIGHT = 20;
546 ARGB color;
547 int y;
549 bm = NULL;
550 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
551 expect(Ok, stat);
553 rect.X = 2;
554 rect.Y = 3;
555 rect.Width = 4;
556 rect.Height = 5;
558 stat = GdipBitmapSetPixel(bm, 2, 3, 0xffc30000);
559 expect(Ok, stat);
561 stat = GdipBitmapSetPixel(bm, 2, 8, 0xff480000);
562 expect(Ok, stat);
564 /* read-only */
565 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
566 expect(Ok, stat);
568 if (stat == Ok) {
569 expect(0xc3, ((BYTE*)bd.Scan0)[2]);
570 expect(0x48, ((BYTE*)bd.Scan0)[2 + bd.Stride * 5]);
572 ((char*)bd.Scan0)[2] = 0xff;
574 stat = GdipBitmapUnlockBits(bm, &bd);
575 expect(Ok, stat);
578 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
579 expect(Ok, stat);
580 expect(0xffff0000, color);
582 stat = GdipBitmapSetPixel(bm, 2, 3, 0xffc30000);
583 expect(Ok, stat);
585 /* read-only, with NULL rect -> whole bitmap lock */
586 stat = GdipBitmapLockBits(bm, NULL, ImageLockModeRead, PixelFormat24bppRGB, &bd);
587 expect(Ok, stat);
588 expect(bd.Width, WIDTH);
589 expect(bd.Height, HEIGHT);
591 if (stat == Ok) {
592 ((char*)bd.Scan0)[2 + 2*3 + 3*bd.Stride] = 0xff;
594 stat = GdipBitmapUnlockBits(bm, &bd);
595 expect(Ok, stat);
598 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
599 expect(Ok, stat);
600 expect(0xffff0000, color);
602 /* read-only, consecutive */
603 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
604 expect(Ok, stat);
606 if (stat == Ok) {
607 stat = GdipBitmapUnlockBits(bm, &bd);
608 expect(Ok, stat);
611 stat = GdipDisposeImage((GpImage*)bm);
612 expect(Ok, stat);
613 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
614 expect(Ok, stat);
616 /* read x2 */
617 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
618 expect(Ok, stat);
619 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
620 expect(WrongState, stat);
622 stat = GdipBitmapUnlockBits(bm, &bd);
623 expect(Ok, stat);
625 stat = GdipDisposeImage((GpImage*)bm);
626 expect(Ok, stat);
627 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
628 expect(Ok, stat);
630 stat = GdipBitmapSetPixel(bm, 2, 3, 0xffff0000);
631 expect(Ok, stat);
633 stat = GdipBitmapSetPixel(bm, 2, 8, 0xffc30000);
634 expect(Ok, stat);
636 /* write, no conversion */
637 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
638 expect(Ok, stat);
640 if (stat == Ok) {
641 /* all bits are readable, inside the rect or not */
642 expect(0xff, ((BYTE*)bd.Scan0)[2]);
643 expect(0xc3, ((BYTE*)bd.Scan0)[2 + bd.Stride * 5]);
645 stat = GdipBitmapUnlockBits(bm, &bd);
646 expect(Ok, stat);
649 /* read, conversion */
650 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat32bppARGB, &bd);
651 expect(Ok, stat);
653 if (stat == Ok) {
654 expect(0xff, ((BYTE*)bd.Scan0)[2]);
655 if (0)
656 /* Areas outside the rectangle appear to be uninitialized */
657 ok(0xc3 != ((BYTE*)bd.Scan0)[2 + bd.Stride * 5], "original image bits are readable\n");
659 ((BYTE*)bd.Scan0)[2] = 0xc3;
661 stat = GdipBitmapUnlockBits(bm, &bd);
662 expect(Ok, stat);
665 /* writes do not work in read mode if there was a conversion */
666 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
667 expect(Ok, stat);
668 expect(0xffff0000, color);
670 /* read/write, conversion */
671 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead|ImageLockModeWrite, PixelFormat32bppARGB, &bd);
672 expect(Ok, stat);
674 if (stat == Ok) {
675 expect(0xff, ((BYTE*)bd.Scan0)[2]);
676 ((BYTE*)bd.Scan0)[1] = 0x88;
677 if (0)
678 /* Areas outside the rectangle appear to be uninitialized */
679 ok(0xc3 != ((BYTE*)bd.Scan0)[2 + bd.Stride * 5], "original image bits are readable\n");
681 stat = GdipBitmapUnlockBits(bm, &bd);
682 expect(Ok, stat);
685 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
686 expect(Ok, stat);
687 expect(0xffff8800, color);
689 /* write, conversion */
690 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat32bppARGB, &bd);
691 expect(Ok, stat);
693 if (stat == Ok) {
694 if (0)
696 /* This is completely uninitialized. */
697 ok(0xff != ((BYTE*)bd.Scan0)[2], "original image bits are readable\n");
698 ok(0xc3 != ((BYTE*)bd.Scan0)[2 + bd.Stride * 5], "original image bits are readable\n");
701 /* Initialize the buffer so the unlock doesn't access undefined memory */
702 for (y=0; y<5; y++)
703 memset(((BYTE*)bd.Scan0) + bd.Stride * y, 0, 12);
705 ((BYTE*)bd.Scan0)[0] = 0x12;
706 ((BYTE*)bd.Scan0)[1] = 0x34;
707 ((BYTE*)bd.Scan0)[2] = 0x56;
709 stat = GdipBitmapUnlockBits(bm, &bd);
710 expect(Ok, stat);
713 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
714 expect(Ok, stat);
715 expect(0xff563412, color);
717 stat = GdipBitmapGetPixel(bm, 2, 8, &color);
718 expect(Ok, stat);
719 expect(0xffc30000, color);
721 stat = GdipDisposeImage((GpImage*)bm);
722 expect(Ok, stat);
723 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
724 expect(Ok, stat);
726 /* write, no modification */
727 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
728 expect(Ok, stat);
730 if (stat == Ok) {
731 stat = GdipBitmapUnlockBits(bm, &bd);
732 expect(Ok, stat);
735 /* write, consecutive */
736 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
737 expect(Ok, stat);
739 if (stat == Ok) {
740 stat = GdipBitmapUnlockBits(bm, &bd);
741 expect(Ok, stat);
744 stat = GdipDisposeImage((GpImage*)bm);
745 expect(Ok, stat);
746 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
747 expect(Ok, stat);
749 /* write, modify */
750 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
751 expect(Ok, stat);
753 if (stat == Ok) {
754 if (bd.Scan0)
755 ((char*)bd.Scan0)[2] = 0xff;
757 stat = GdipBitmapUnlockBits(bm, &bd);
758 expect(Ok, stat);
761 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
762 expect(Ok, stat);
763 expect(0xffff0000, color);
765 stat = GdipDisposeImage((GpImage*)bm);
766 expect(Ok, stat);
768 /* dispose locked */
769 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
770 expect(Ok, stat);
771 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
772 expect(Ok, stat);
773 stat = GdipDisposeImage((GpImage*)bm);
774 expect(Ok, stat);
777 static void test_LockBits_UserBuf(void)
779 GpStatus stat;
780 GpBitmap *bm;
781 GpRect rect;
782 BitmapData bd;
783 const INT WIDTH = 10, HEIGHT = 20;
784 DWORD bits[200];
785 ARGB color;
787 bm = NULL;
788 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat32bppARGB, NULL, &bm);
789 expect(Ok, stat);
791 memset(bits, 0xaa, sizeof(bits));
793 rect.X = 2;
794 rect.Y = 3;
795 rect.Width = 4;
796 rect.Height = 5;
798 bd.Width = 4;
799 bd.Height = 6;
800 bd.Stride = WIDTH * 4;
801 bd.PixelFormat = PixelFormat32bppARGB;
802 bd.Scan0 = &bits[2+3*WIDTH];
803 bd.Reserved = 0xaaaaaaaa;
805 /* read-only */
806 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead|ImageLockModeUserInputBuf, PixelFormat32bppARGB, &bd);
807 expect(Ok, stat);
809 expect(0xaaaaaaaa, bits[0]);
810 expect(0, bits[2+3*WIDTH]);
812 bits[2+3*WIDTH] = 0xdeadbeef;
814 if (stat == Ok) {
815 stat = GdipBitmapUnlockBits(bm, &bd);
816 expect(Ok, stat);
819 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
820 expect(Ok, stat);
821 expect(0, color);
823 /* write-only */
824 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite|ImageLockModeUserInputBuf, PixelFormat32bppARGB, &bd);
825 expect(Ok, stat);
827 expect(0xdeadbeef, bits[2+3*WIDTH]);
828 bits[2+3*WIDTH] = 0x12345678;
830 if (stat == Ok) {
831 stat = GdipBitmapUnlockBits(bm, &bd);
832 expect(Ok, stat);
835 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
836 expect(Ok, stat);
837 expect(0x12345678, color);
839 bits[2+3*WIDTH] = 0;
841 /* read/write */
842 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead|ImageLockModeWrite|ImageLockModeUserInputBuf, PixelFormat32bppARGB, &bd);
843 expect(Ok, stat);
845 expect(0x12345678, bits[2+3*WIDTH]);
846 bits[2+3*WIDTH] = 0xdeadbeef;
848 if (stat == Ok) {
849 stat = GdipBitmapUnlockBits(bm, &bd);
850 expect(Ok, stat);
853 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
854 expect(Ok, stat);
855 expect(0xdeadbeef, color);
857 stat = GdipDisposeImage((GpImage*)bm);
858 expect(Ok, stat);
861 struct BITMAPINFOWITHBITFIELDS
863 BITMAPINFOHEADER bmiHeader;
864 DWORD masks[3];
867 union BITMAPINFOUNION
869 BITMAPINFO bi;
870 struct BITMAPINFOWITHBITFIELDS bf;
873 static void test_GdipCreateBitmapFromHBITMAP(void)
875 GpBitmap* gpbm = NULL;
876 HBITMAP hbm = NULL;
877 HPALETTE hpal = NULL;
878 GpStatus stat;
879 BYTE buff[1000];
880 LOGPALETTE* LogPal = NULL;
881 REAL width, height;
882 const REAL WIDTH1 = 5;
883 const REAL HEIGHT1 = 15;
884 const REAL WIDTH2 = 10;
885 const REAL HEIGHT2 = 20;
886 HDC hdc;
887 union BITMAPINFOUNION bmi;
888 BYTE *bits;
889 PixelFormat format;
891 stat = GdipCreateBitmapFromHBITMAP(NULL, NULL, NULL);
892 expect(InvalidParameter, stat);
894 hbm = CreateBitmap(WIDTH1, HEIGHT1, 1, 1, NULL);
895 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, NULL);
896 expect(InvalidParameter, stat);
898 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
899 expect(Ok, stat);
900 expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
901 expectf(WIDTH1, width);
902 expectf(HEIGHT1, height);
903 if (stat == Ok)
904 GdipDisposeImage((GpImage*)gpbm);
905 DeleteObject(hbm);
907 memset(buff, 0, sizeof(buff));
908 hbm = CreateBitmap(WIDTH2, HEIGHT2, 1, 1, &buff);
909 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
910 expect(Ok, stat);
911 /* raw format */
912 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)gpbm, __LINE__, FALSE);
914 expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
915 expectf(WIDTH2, width);
916 expectf(HEIGHT2, height);
917 if (stat == Ok)
918 GdipDisposeImage((GpImage*)gpbm);
919 DeleteObject(hbm);
921 hdc = CreateCompatibleDC(0);
922 ok(hdc != NULL, "CreateCompatibleDC failed\n");
923 bmi.bi.bmiHeader.biSize = sizeof(bmi.bi.bmiHeader);
924 bmi.bi.bmiHeader.biHeight = HEIGHT1;
925 bmi.bi.bmiHeader.biWidth = WIDTH1;
926 bmi.bi.bmiHeader.biBitCount = 24;
927 bmi.bi.bmiHeader.biPlanes = 1;
928 bmi.bi.bmiHeader.biCompression = BI_RGB;
929 bmi.bi.bmiHeader.biClrUsed = 0;
931 hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
932 ok(hbm != NULL, "CreateDIBSection failed\n");
934 bits[0] = 0;
936 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
937 expect(Ok, stat);
938 expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
939 expectf(WIDTH1, width);
940 expectf(HEIGHT1, height);
941 if (stat == Ok)
943 /* test whether writing to the bitmap affects the original */
944 stat = GdipBitmapSetPixel(gpbm, 0, 0, 0xffffffff);
945 expect(Ok, stat);
947 expect(0, bits[0]);
949 GdipDisposeImage((GpImage*)gpbm);
952 LogPal = GdipAlloc(sizeof(LOGPALETTE));
953 ok(LogPal != NULL, "unable to allocate LOGPALETTE\n");
954 LogPal->palVersion = 0x300;
955 LogPal->palNumEntries = 1;
956 hpal = CreatePalette(LogPal);
957 ok(hpal != NULL, "CreatePalette failed\n");
958 GdipFree(LogPal);
960 stat = GdipCreateBitmapFromHBITMAP(hbm, hpal, &gpbm);
961 expect(Ok, stat);
963 if (stat == Ok)
964 GdipDisposeImage((GpImage*)gpbm);
966 DeleteObject(hpal);
967 DeleteObject(hbm);
969 /* 16-bit 555 dib, rgb */
970 bmi.bi.bmiHeader.biBitCount = 16;
971 bmi.bi.bmiHeader.biCompression = BI_RGB;
973 hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
974 ok(hbm != NULL, "CreateDIBSection failed\n");
976 bits[0] = 0;
978 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
979 expect(Ok, stat);
981 if (stat == Ok)
983 stat = GdipGetImageDimension((GpImage*) gpbm, &width, &height);
984 expect(Ok, stat);
985 expectf(WIDTH1, width);
986 expectf(HEIGHT1, height);
988 stat = GdipGetImagePixelFormat((GpImage*) gpbm, &format);
989 expect(Ok, stat);
990 expect(PixelFormat16bppRGB555, format);
992 GdipDisposeImage((GpImage*)gpbm);
994 DeleteObject(hbm);
996 /* 16-bit 555 dib, with bitfields */
997 bmi.bi.bmiHeader.biSize = sizeof(bmi);
998 bmi.bi.bmiHeader.biCompression = BI_BITFIELDS;
999 bmi.bf.masks[0] = 0x7c00;
1000 bmi.bf.masks[1] = 0x3e0;
1001 bmi.bf.masks[2] = 0x1f;
1003 hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1004 ok(hbm != NULL, "CreateDIBSection failed\n");
1006 bits[0] = 0;
1008 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
1009 expect(Ok, stat);
1011 if (stat == Ok)
1013 stat = GdipGetImageDimension((GpImage*) gpbm, &width, &height);
1014 expect(Ok, stat);
1015 expectf(WIDTH1, width);
1016 expectf(HEIGHT1, height);
1018 stat = GdipGetImagePixelFormat((GpImage*) gpbm, &format);
1019 expect(Ok, stat);
1020 expect(PixelFormat16bppRGB555, format);
1022 GdipDisposeImage((GpImage*)gpbm);
1024 DeleteObject(hbm);
1026 /* 16-bit 565 dib, with bitfields */
1027 bmi.bf.masks[0] = 0xf800;
1028 bmi.bf.masks[1] = 0x7e0;
1029 bmi.bf.masks[2] = 0x1f;
1031 hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1032 ok(hbm != NULL, "CreateDIBSection failed\n");
1034 bits[0] = 0;
1036 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
1037 expect(Ok, stat);
1039 if (stat == Ok)
1041 stat = GdipGetImageDimension((GpImage*) gpbm, &width, &height);
1042 expect(Ok, stat);
1043 expectf(WIDTH1, width);
1044 expectf(HEIGHT1, height);
1046 stat = GdipGetImagePixelFormat((GpImage*) gpbm, &format);
1047 expect(Ok, stat);
1048 expect(PixelFormat16bppRGB565, format);
1050 GdipDisposeImage((GpImage*)gpbm);
1052 DeleteObject(hbm);
1054 DeleteDC(hdc);
1057 static void test_GdipGetImageFlags(void)
1059 GpImage *img;
1060 GpStatus stat;
1061 UINT flags;
1063 img = (GpImage*)0xdeadbeef;
1065 stat = GdipGetImageFlags(NULL, NULL);
1066 expect(InvalidParameter, stat);
1068 stat = GdipGetImageFlags(NULL, &flags);
1069 expect(InvalidParameter, stat);
1071 stat = GdipGetImageFlags(img, NULL);
1072 expect(InvalidParameter, stat);
1074 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat1bppIndexed, NULL, (GpBitmap**)&img);
1075 expect(Ok, stat);
1076 stat = GdipGetImageFlags(img, &flags);
1077 expect(Ok, stat);
1078 expect(ImageFlagsHasAlpha, flags);
1079 GdipDisposeImage(img);
1081 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat4bppIndexed, NULL, (GpBitmap**)&img);
1082 expect(Ok, stat);
1083 stat = GdipGetImageFlags(img, &flags);
1084 expect(Ok, stat);
1085 expect(ImageFlagsHasAlpha, flags);
1086 GdipDisposeImage(img);
1088 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat8bppIndexed, NULL, (GpBitmap**)&img);
1089 expect(Ok, stat);
1090 stat = GdipGetImageFlags(img, &flags);
1091 expect(Ok, stat);
1092 expect(ImageFlagsHasAlpha, flags);
1093 GdipDisposeImage(img);
1095 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppGrayScale, NULL, (GpBitmap**)&img);
1096 expect(Ok, stat);
1097 stat = GdipGetImageFlags(img, &flags);
1098 expect(Ok, stat);
1099 expect(ImageFlagsNone, flags);
1100 GdipDisposeImage(img);
1102 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB555, NULL, (GpBitmap**)&img);
1103 expect(Ok, stat);
1104 stat = GdipGetImageFlags(img, &flags);
1105 expect(Ok, stat);
1106 expect(ImageFlagsNone, flags);
1107 GdipDisposeImage(img);
1109 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB565, NULL, (GpBitmap**)&img);
1110 expect(Ok, stat);
1111 stat = GdipGetImageFlags(img, &flags);
1112 expect(Ok, stat);
1113 expect(ImageFlagsNone, flags);
1114 GdipDisposeImage(img);
1116 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppARGB1555, NULL, (GpBitmap**)&img);
1117 expect(Ok, stat);
1118 stat = GdipGetImageFlags(img, &flags);
1119 expect(Ok, stat);
1120 expect(ImageFlagsHasAlpha, flags);
1121 GdipDisposeImage(img);
1123 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, NULL, (GpBitmap**)&img);
1124 expect(Ok, stat);
1125 stat = GdipGetImageFlags(img, &flags);
1126 expect(Ok, stat);
1127 expect(ImageFlagsNone, flags);
1128 GdipDisposeImage(img);
1130 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppRGB, NULL, (GpBitmap**)&img);
1131 expect(Ok, stat);
1132 stat = GdipGetImageFlags(img, &flags);
1133 expect(Ok, stat);
1134 expect(ImageFlagsNone, flags);
1135 GdipDisposeImage(img);
1137 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppARGB, NULL, (GpBitmap**)&img);
1138 expect(Ok, stat);
1139 stat = GdipGetImageFlags(img, &flags);
1140 expect(Ok, stat);
1141 expect(ImageFlagsHasAlpha, flags);
1142 GdipDisposeImage(img);
1144 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppPARGB, NULL, (GpBitmap**)&img);
1145 expect(Ok, stat);
1146 stat = GdipGetImageFlags(img, &flags);
1147 expect(Ok, stat);
1148 expect(ImageFlagsHasAlpha, flags);
1149 GdipDisposeImage(img);
1151 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat48bppRGB, NULL, (GpBitmap**)&img);
1152 expect(Ok, stat);
1153 if (stat == Ok)
1155 stat = GdipGetImageFlags(img, &flags);
1156 expect(Ok, stat);
1157 expect(ImageFlagsNone, flags);
1158 GdipDisposeImage(img);
1161 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB, NULL, (GpBitmap**)&img);
1162 expect(Ok, stat);
1163 if (stat == Ok)
1165 expect(Ok, stat);
1166 stat = GdipGetImageFlags(img, &flags);
1167 expect(Ok, stat);
1168 expect(ImageFlagsHasAlpha, flags);
1169 GdipDisposeImage(img);
1172 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB, NULL, (GpBitmap**)&img);
1173 expect(Ok, stat);
1174 if (stat == Ok)
1176 expect(Ok, stat);
1177 stat = GdipGetImageFlags(img, &flags);
1178 expect(Ok, stat);
1179 expect(ImageFlagsHasAlpha, flags);
1180 GdipDisposeImage(img);
1184 static void test_GdipCloneImage(void)
1186 GpStatus stat;
1187 GpRectF rectF;
1188 GpUnit unit;
1189 GpBitmap *bm;
1190 GpImage *image_src, *image_dest = NULL;
1191 const INT WIDTH = 10, HEIGHT = 20;
1193 /* Create an image, clone it, delete the original, make sure the copy works */
1194 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
1195 expect(Ok, stat);
1196 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bm, __LINE__, FALSE);
1198 image_src = ((GpImage*)bm);
1199 stat = GdipCloneImage(image_src, &image_dest);
1200 expect(Ok, stat);
1201 expect_rawformat(&ImageFormatMemoryBMP, image_dest, __LINE__, FALSE);
1203 stat = GdipDisposeImage((GpImage*)bm);
1204 expect(Ok, stat);
1205 stat = GdipGetImageBounds(image_dest, &rectF, &unit);
1206 expect(Ok, stat);
1208 /* Treat FP values carefully */
1209 expectf((REAL)WIDTH, rectF.Width);
1210 expectf((REAL)HEIGHT, rectF.Height);
1212 stat = GdipDisposeImage(image_dest);
1213 expect(Ok, stat);
1216 static void test_testcontrol(void)
1218 GpStatus stat;
1219 DWORD param;
1221 param = 0;
1222 stat = GdipTestControl(TestControlGetBuildNumber, &param);
1223 expect(Ok, stat);
1224 ok(param != 0, "Build number expected, got %u\n", param);
1227 static void test_fromhicon(void)
1229 static const BYTE bmp_bits[1024];
1230 HBITMAP hbmMask, hbmColor;
1231 ICONINFO info;
1232 HICON hIcon;
1233 GpStatus stat;
1234 GpBitmap *bitmap = NULL;
1235 UINT dim;
1236 ImageType type;
1237 PixelFormat format;
1239 /* NULL */
1240 stat = GdipCreateBitmapFromHICON(NULL, NULL);
1241 expect(InvalidParameter, stat);
1242 stat = GdipCreateBitmapFromHICON(NULL, &bitmap);
1243 expect(InvalidParameter, stat);
1245 /* color icon 1 bit */
1246 hbmMask = CreateBitmap(16, 16, 1, 1, bmp_bits);
1247 ok(hbmMask != 0, "CreateBitmap failed\n");
1248 hbmColor = CreateBitmap(16, 16, 1, 1, bmp_bits);
1249 ok(hbmColor != 0, "CreateBitmap failed\n");
1250 info.fIcon = TRUE;
1251 info.xHotspot = 8;
1252 info.yHotspot = 8;
1253 info.hbmMask = hbmMask;
1254 info.hbmColor = hbmColor;
1255 hIcon = CreateIconIndirect(&info);
1256 ok(hIcon != 0, "CreateIconIndirect failed\n");
1257 DeleteObject(hbmMask);
1258 DeleteObject(hbmColor);
1260 stat = GdipCreateBitmapFromHICON(hIcon, &bitmap);
1261 ok(stat == Ok ||
1262 broken(stat == InvalidParameter), /* Win98 */
1263 "Expected Ok, got %.8x\n", stat);
1264 if(stat == Ok){
1265 /* check attributes */
1266 stat = GdipGetImageHeight((GpImage*)bitmap, &dim);
1267 expect(Ok, stat);
1268 expect(16, dim);
1269 stat = GdipGetImageWidth((GpImage*)bitmap, &dim);
1270 expect(Ok, stat);
1271 expect(16, dim);
1272 stat = GdipGetImageType((GpImage*)bitmap, &type);
1273 expect(Ok, stat);
1274 expect(ImageTypeBitmap, type);
1275 stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format);
1276 expect(Ok, stat);
1277 expect(PixelFormat32bppARGB, format);
1278 /* raw format */
1279 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
1280 GdipDisposeImage((GpImage*)bitmap);
1282 DestroyIcon(hIcon);
1284 /* color icon 8 bpp */
1285 hbmMask = CreateBitmap(16, 16, 1, 8, bmp_bits);
1286 ok(hbmMask != 0, "CreateBitmap failed\n");
1287 hbmColor = CreateBitmap(16, 16, 1, 8, bmp_bits);
1288 ok(hbmColor != 0, "CreateBitmap failed\n");
1289 info.fIcon = TRUE;
1290 info.xHotspot = 8;
1291 info.yHotspot = 8;
1292 info.hbmMask = hbmMask;
1293 info.hbmColor = hbmColor;
1294 hIcon = CreateIconIndirect(&info);
1295 ok(hIcon != 0, "CreateIconIndirect failed\n");
1296 DeleteObject(hbmMask);
1297 DeleteObject(hbmColor);
1299 stat = GdipCreateBitmapFromHICON(hIcon, &bitmap);
1300 expect(Ok, stat);
1301 if(stat == Ok){
1302 /* check attributes */
1303 stat = GdipGetImageHeight((GpImage*)bitmap, &dim);
1304 expect(Ok, stat);
1305 expect(16, dim);
1306 stat = GdipGetImageWidth((GpImage*)bitmap, &dim);
1307 expect(Ok, stat);
1308 expect(16, dim);
1309 stat = GdipGetImageType((GpImage*)bitmap, &type);
1310 expect(Ok, stat);
1311 expect(ImageTypeBitmap, type);
1312 stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format);
1313 expect(Ok, stat);
1314 expect(PixelFormat32bppARGB, format);
1315 /* raw format */
1316 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
1317 GdipDisposeImage((GpImage*)bitmap);
1319 DestroyIcon(hIcon);
1322 /* 1x1 pixel png */
1323 static const unsigned char pngimage[285] = {
1324 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
1325 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
1326 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
1327 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
1328 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
1329 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
1330 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
1332 /* 1x1 pixel gif */
1333 static const unsigned char gifimage[35] = {
1334 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
1335 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
1336 0x01,0x00,0x3b
1338 /* 1x1 pixel bmp */
1339 static const unsigned char bmpimage[66] = {
1340 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
1341 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
1342 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
1343 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
1344 0x00,0x00
1346 /* 1x1 pixel jpg */
1347 static const unsigned char jpgimage[285] = {
1348 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
1349 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
1350 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
1351 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
1352 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
1353 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
1354 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
1355 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1356 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1357 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
1358 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
1359 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1360 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
1361 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
1362 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1363 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
1364 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
1365 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
1367 /* 1x1 pixel tiff */
1368 static const unsigned char tiffimage[] = {
1369 0x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00,
1370 0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00,
1371 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1372 0x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01,
1373 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00,
1374 0x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00,
1375 0x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01,
1376 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00,
1377 0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00,
1378 0x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01,
1379 0x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00,
1380 0x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1381 0x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
1382 0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65,
1383 0x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74,
1384 0x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,
1385 0x00,0x00,0x00,0x01
1387 /* 320x320 twip wmf */
1388 static const unsigned char wmfimage[180] = {
1389 0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05,
1390 0x00,0x00,0x00,0x00,0xb1,0x52,0x01,0x00,0x09,0x00,0x00,0x03,0x4f,0x00,0x00,0x00,
1391 0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0b,0x02,0x00,0x00,
1392 0x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x02,0x40,0x01,0x40,0x01,0x04,0x00,0x00,0x00,
1393 0x02,0x01,0x01,0x00,0x04,0x00,0x00,0x00,0x04,0x01,0x0d,0x00,0x08,0x00,0x00,0x00,
1394 0xfa,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
1395 0x2d,0x01,0x00,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,0x01,0x00,0x00,0x00,0x00,0x00,
1396 0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x01,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,
1397 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x02,0x00,
1398 0x07,0x00,0x00,0x00,0x1b,0x04,0x40,0x01,0x40,0x01,0x00,0x00,0x00,0x00,0x04,0x00,
1399 0x00,0x00,0xf0,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0xf0,0x01,0x01,0x00,0x03,0x00,
1400 0x00,0x00,0x00,0x00
1402 static void test_getrawformat(void)
1404 test_bufferrawformat((void*)pngimage, sizeof(pngimage), &ImageFormatPNG, __LINE__, FALSE);
1405 test_bufferrawformat((void*)gifimage, sizeof(gifimage), &ImageFormatGIF, __LINE__, FALSE);
1406 test_bufferrawformat((void*)bmpimage, sizeof(bmpimage), &ImageFormatBMP, __LINE__, FALSE);
1407 test_bufferrawformat((void*)jpgimage, sizeof(jpgimage), &ImageFormatJPEG, __LINE__, FALSE);
1408 test_bufferrawformat((void*)tiffimage, sizeof(tiffimage), &ImageFormatTIFF, __LINE__, FALSE);
1409 test_bufferrawformat((void*)wmfimage, sizeof(wmfimage), &ImageFormatWMF, __LINE__, FALSE);
1412 static void test_loadwmf(void)
1414 LPSTREAM stream;
1415 HGLOBAL hglob;
1416 LPBYTE data;
1417 HRESULT hres;
1418 GpStatus stat;
1419 GpImage *img;
1420 GpRectF bounds;
1421 GpUnit unit;
1422 REAL res = 12345.0;
1423 MetafileHeader header;
1425 hglob = GlobalAlloc (0, sizeof(wmfimage));
1426 data = GlobalLock (hglob);
1427 memcpy(data, wmfimage, sizeof(wmfimage));
1428 GlobalUnlock(hglob); data = NULL;
1430 hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
1431 ok(hres == S_OK, "Failed to create a stream\n");
1432 if(hres != S_OK) return;
1434 stat = GdipLoadImageFromStream(stream, &img);
1435 ok(stat == Ok, "Failed to create a Bitmap\n");
1436 if(stat != Ok){
1437 IStream_Release(stream);
1438 return;
1441 IStream_Release(stream);
1443 stat = GdipGetImageBounds(img, &bounds, &unit);
1444 expect(Ok, stat);
1445 todo_wine expect(UnitPixel, unit);
1446 expectf(0.0, bounds.X);
1447 expectf(0.0, bounds.Y);
1448 todo_wine expectf(320.0, bounds.Width);
1449 todo_wine expectf(320.0, bounds.Height);
1451 stat = GdipGetImageHorizontalResolution(img, &res);
1452 expect(Ok, stat);
1453 todo_wine expectf(1440.0, res);
1455 stat = GdipGetImageVerticalResolution(img, &res);
1456 expect(Ok, stat);
1457 todo_wine expectf(1440.0, res);
1459 memset(&header, 0, sizeof(header));
1460 stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header);
1461 expect(Ok, stat);
1462 if (stat == Ok)
1464 todo_wine expect(MetafileTypeWmfPlaceable, header.Type);
1465 todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size);
1466 todo_wine expect(0x300, header.Version);
1467 expect(0, header.EmfPlusFlags);
1468 todo_wine expectf(1440.0, header.DpiX);
1469 todo_wine expectf(1440.0, header.DpiY);
1470 expect(0, header.X);
1471 expect(0, header.Y);
1472 todo_wine expect(320, header.Width);
1473 todo_wine expect(320, header.Height);
1474 todo_wine expect(1, U(header).WmfHeader.mtType);
1475 expect(0, header.EmfPlusHeaderSize);
1476 expect(0, header.LogicalDpiX);
1477 expect(0, header.LogicalDpiY);
1480 GdipDisposeImage(img);
1483 static void test_createfromwmf(void)
1485 HMETAFILE hwmf;
1486 GpImage *img;
1487 GpStatus stat;
1488 GpRectF bounds;
1489 GpUnit unit;
1490 REAL res = 12345.0;
1491 MetafileHeader header;
1493 hwmf = SetMetaFileBitsEx(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader),
1494 wmfimage+sizeof(WmfPlaceableFileHeader));
1495 ok(hwmf != 0, "SetMetaFileBitsEx failed\n");
1497 stat = GdipCreateMetafileFromWmf(hwmf, TRUE,
1498 (WmfPlaceableFileHeader*)wmfimage, (GpMetafile**)&img);
1499 expect(Ok, stat);
1501 stat = GdipGetImageBounds(img, &bounds, &unit);
1502 expect(Ok, stat);
1503 expect(UnitPixel, unit);
1504 expectf(0.0, bounds.X);
1505 expectf(0.0, bounds.Y);
1506 expectf(320.0, bounds.Width);
1507 expectf(320.0, bounds.Height);
1509 stat = GdipGetImageHorizontalResolution(img, &res);
1510 expect(Ok, stat);
1511 expectf(1440.0, res);
1513 stat = GdipGetImageVerticalResolution(img, &res);
1514 expect(Ok, stat);
1515 expectf(1440.0, res);
1517 memset(&header, 0, sizeof(header));
1518 stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header);
1519 expect(Ok, stat);
1520 if (stat == Ok)
1522 todo_wine expect(MetafileTypeWmfPlaceable, header.Type);
1523 todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size);
1524 todo_wine expect(0x300, header.Version);
1525 expect(0, header.EmfPlusFlags);
1526 todo_wine expectf(1440.0, header.DpiX);
1527 todo_wine expectf(1440.0, header.DpiY);
1528 expect(0, header.X);
1529 expect(0, header.Y);
1530 todo_wine expect(320, header.Width);
1531 todo_wine expect(320, header.Height);
1532 todo_wine expect(1, U(header).WmfHeader.mtType);
1533 expect(0, header.EmfPlusHeaderSize);
1534 expect(0, header.LogicalDpiX);
1535 expect(0, header.LogicalDpiY);
1538 GdipDisposeImage(img);
1541 static void test_resolution(void)
1543 GpStatus stat;
1544 GpBitmap *bitmap;
1545 GpGraphics *graphics;
1546 REAL res=-1.0;
1547 HDC screendc;
1548 int screenxres, screenyres;
1550 /* create Bitmap */
1551 stat = GdipCreateBitmapFromScan0(1, 1, 32, PixelFormat24bppRGB, NULL, &bitmap);
1552 expect(Ok, stat);
1554 /* test invalid values */
1555 stat = GdipGetImageHorizontalResolution(NULL, &res);
1556 expect(InvalidParameter, stat);
1558 stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, NULL);
1559 expect(InvalidParameter, stat);
1561 stat = GdipGetImageVerticalResolution(NULL, &res);
1562 expect(InvalidParameter, stat);
1564 stat = GdipGetImageVerticalResolution((GpImage*)bitmap, NULL);
1565 expect(InvalidParameter, stat);
1567 stat = GdipBitmapSetResolution(NULL, 96.0, 96.0);
1568 expect(InvalidParameter, stat);
1570 stat = GdipBitmapSetResolution(bitmap, 0.0, 0.0);
1571 expect(InvalidParameter, stat);
1573 /* defaults to screen resolution */
1574 screendc = GetDC(0);
1576 screenxres = GetDeviceCaps(screendc, LOGPIXELSX);
1577 screenyres = GetDeviceCaps(screendc, LOGPIXELSY);
1579 ReleaseDC(0, screendc);
1581 stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, &res);
1582 expect(Ok, stat);
1583 expectf((REAL)screenxres, res);
1585 stat = GdipGetImageVerticalResolution((GpImage*)bitmap, &res);
1586 expect(Ok, stat);
1587 expectf((REAL)screenyres, res);
1589 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
1590 expect(Ok, stat);
1591 stat = GdipGetDpiX(graphics, &res);
1592 expect(Ok, stat);
1593 expectf((REAL)screenxres, res);
1594 stat = GdipGetDpiY(graphics, &res);
1595 expect(Ok, stat);
1596 expectf((REAL)screenyres, res);
1598 /* test changing the resolution */
1599 stat = GdipBitmapSetResolution(bitmap, screenxres*2.0, screenyres*3.0);
1600 expect(Ok, stat);
1602 stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, &res);
1603 expect(Ok, stat);
1604 expectf(screenxres*2.0, res);
1606 stat = GdipGetImageVerticalResolution((GpImage*)bitmap, &res);
1607 expect(Ok, stat);
1608 expectf(screenyres*3.0, res);
1610 stat = GdipGetDpiX(graphics, &res);
1611 expect(Ok, stat);
1612 expectf((REAL)screenxres, res);
1613 stat = GdipGetDpiY(graphics, &res);
1614 expect(Ok, stat);
1615 expectf((REAL)screenyres, res);
1617 stat = GdipDeleteGraphics(graphics);
1618 expect(Ok, stat);
1620 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
1621 expect(Ok, stat);
1622 stat = GdipGetDpiX(graphics, &res);
1623 expect(Ok, stat);
1624 expectf(screenxres*2.0, res);
1625 stat = GdipGetDpiY(graphics, &res);
1626 expect(Ok, stat);
1627 expectf(screenyres*3.0, res);
1628 stat = GdipDeleteGraphics(graphics);
1629 expect(Ok, stat);
1631 stat = GdipDisposeImage((GpImage*)bitmap);
1632 expect(Ok, stat);
1635 static void test_createhbitmap(void)
1637 GpStatus stat;
1638 GpBitmap *bitmap;
1639 HBITMAP hbitmap, oldhbitmap;
1640 BITMAP bm;
1641 int ret;
1642 HDC hdc;
1643 COLORREF pixel;
1644 BYTE bits[640];
1646 memset(bits, 0x68, 640);
1648 /* create Bitmap */
1649 stat = GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB, bits, &bitmap);
1650 expect(Ok, stat);
1652 /* test NULL values */
1653 stat = GdipCreateHBITMAPFromBitmap(NULL, &hbitmap, 0);
1654 expect(InvalidParameter, stat);
1656 stat = GdipCreateHBITMAPFromBitmap(bitmap, NULL, 0);
1657 expect(InvalidParameter, stat);
1659 /* create HBITMAP */
1660 stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0);
1661 expect(Ok, stat);
1663 if (stat == Ok)
1665 ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
1666 expect(sizeof(BITMAP), ret);
1668 expect(0, bm.bmType);
1669 expect(10, bm.bmWidth);
1670 expect(20, bm.bmHeight);
1671 expect(40, bm.bmWidthBytes);
1672 expect(1, bm.bmPlanes);
1673 expect(32, bm.bmBitsPixel);
1674 ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
1676 if (bm.bmBits)
1678 DWORD val = *(DWORD*)bm.bmBits;
1679 ok(val == 0xff686868, "got %x, expected 0xff686868\n", val);
1682 hdc = CreateCompatibleDC(NULL);
1684 oldhbitmap = SelectObject(hdc, hbitmap);
1685 pixel = GetPixel(hdc, 5, 5);
1686 SelectObject(hdc, oldhbitmap);
1688 DeleteDC(hdc);
1690 expect(0x686868, pixel);
1692 DeleteObject(hbitmap);
1695 stat = GdipDisposeImage((GpImage*)bitmap);
1696 expect(Ok, stat);
1698 /* create alpha Bitmap */
1699 stat = GdipCreateBitmapFromScan0(8, 20, 32, PixelFormat32bppARGB, bits, &bitmap);
1700 expect(Ok, stat);
1702 /* create HBITMAP */
1703 stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0);
1704 expect(Ok, stat);
1706 if (stat == Ok)
1708 ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
1709 expect(sizeof(BITMAP), ret);
1711 expect(0, bm.bmType);
1712 expect(8, bm.bmWidth);
1713 expect(20, bm.bmHeight);
1714 expect(32, bm.bmWidthBytes);
1715 expect(1, bm.bmPlanes);
1716 expect(32, bm.bmBitsPixel);
1717 ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
1719 if (bm.bmBits)
1721 DWORD val = *(DWORD*)bm.bmBits;
1722 ok(val == 0x682a2a2a, "got %x, expected 0x682a2a2a\n", val);
1725 hdc = CreateCompatibleDC(NULL);
1727 oldhbitmap = SelectObject(hdc, hbitmap);
1728 pixel = GetPixel(hdc, 5, 5);
1729 SelectObject(hdc, oldhbitmap);
1731 DeleteDC(hdc);
1733 expect(0x2a2a2a, pixel);
1735 DeleteObject(hbitmap);
1738 stat = GdipDisposeImage((GpImage*)bitmap);
1739 expect(Ok, stat);
1742 static void test_getthumbnail(void)
1744 GpStatus stat;
1745 GpImage *bitmap1, *bitmap2;
1746 UINT width, height;
1748 stat = GdipGetImageThumbnail(NULL, 0, 0, &bitmap2, NULL, NULL);
1749 expect(InvalidParameter, stat);
1751 stat = GdipCreateBitmapFromScan0(128, 128, 0, PixelFormat32bppRGB, NULL, (GpBitmap**)&bitmap1);
1752 expect(Ok, stat);
1754 stat = GdipGetImageThumbnail(bitmap1, 0, 0, NULL, NULL, NULL);
1755 expect(InvalidParameter, stat);
1757 stat = GdipGetImageThumbnail(bitmap1, 0, 0, &bitmap2, NULL, NULL);
1758 expect(Ok, stat);
1760 if (stat == Ok)
1762 stat = GdipGetImageWidth(bitmap2, &width);
1763 expect(Ok, stat);
1764 expect(120, width);
1766 stat = GdipGetImageHeight(bitmap2, &height);
1767 expect(Ok, stat);
1768 expect(120, height);
1770 GdipDisposeImage(bitmap2);
1773 GdipDisposeImage(bitmap1);
1776 stat = GdipCreateBitmapFromScan0(64, 128, 0, PixelFormat32bppRGB, NULL, (GpBitmap**)&bitmap1);
1777 expect(Ok, stat);
1779 stat = GdipGetImageThumbnail(bitmap1, 32, 32, &bitmap2, NULL, NULL);
1780 expect(Ok, stat);
1782 if (stat == Ok)
1784 stat = GdipGetImageWidth(bitmap2, &width);
1785 expect(Ok, stat);
1786 expect(32, width);
1788 stat = GdipGetImageHeight(bitmap2, &height);
1789 expect(Ok, stat);
1790 expect(32, height);
1792 GdipDisposeImage(bitmap2);
1795 stat = GdipGetImageThumbnail(bitmap1, 0, 0, &bitmap2, NULL, NULL);
1796 expect(Ok, stat);
1798 if (stat == Ok)
1800 stat = GdipGetImageWidth(bitmap2, &width);
1801 expect(Ok, stat);
1802 expect(120, width);
1804 stat = GdipGetImageHeight(bitmap2, &height);
1805 expect(Ok, stat);
1806 expect(120, height);
1808 GdipDisposeImage(bitmap2);
1811 GdipDisposeImage(bitmap1);
1814 static void test_getsetpixel(void)
1816 GpStatus stat;
1817 GpBitmap *bitmap;
1818 ARGB color;
1819 BYTE bits[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00,
1820 0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00};
1822 stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB, bits, &bitmap);
1823 expect(Ok, stat);
1825 /* null parameters */
1826 stat = GdipBitmapGetPixel(NULL, 1, 1, &color);
1827 expect(InvalidParameter, stat);
1829 stat = GdipBitmapGetPixel(bitmap, 1, 1, NULL);
1830 expect(InvalidParameter, stat);
1832 stat = GdipBitmapSetPixel(NULL, 1, 1, 0);
1833 expect(InvalidParameter, stat);
1835 /* out of bounds */
1836 stat = GdipBitmapGetPixel(bitmap, -1, 1, &color);
1837 expect(InvalidParameter, stat);
1839 stat = GdipBitmapSetPixel(bitmap, -1, 1, 0);
1840 expect(InvalidParameter, stat);
1842 stat = GdipBitmapGetPixel(bitmap, 1, -1, &color);
1843 ok(stat == InvalidParameter ||
1844 broken(stat == Ok), /* Older gdiplus */
1845 "Expected InvalidParameter, got %.8x\n", stat);
1847 if (0) /* crashes some gdiplus implementations */
1849 stat = GdipBitmapSetPixel(bitmap, 1, -1, 0);
1850 ok(stat == InvalidParameter ||
1851 broken(stat == Ok), /* Older gdiplus */
1852 "Expected InvalidParameter, got %.8x\n", stat);
1855 stat = GdipBitmapGetPixel(bitmap, 2, 1, &color);
1856 expect(InvalidParameter, stat);
1858 stat = GdipBitmapSetPixel(bitmap, 2, 1, 0);
1859 expect(InvalidParameter, stat);
1861 stat = GdipBitmapGetPixel(bitmap, 1, 2, &color);
1862 expect(InvalidParameter, stat);
1864 stat = GdipBitmapSetPixel(bitmap, 1, 2, 0);
1865 expect(InvalidParameter, stat);
1867 /* valid use */
1868 stat = GdipBitmapGetPixel(bitmap, 1, 1, &color);
1869 expect(Ok, stat);
1870 expect(0xffffffff, color);
1872 stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
1873 expect(Ok, stat);
1874 expect(0xff0000ff, color);
1876 stat = GdipBitmapSetPixel(bitmap, 1, 1, 0xff676869);
1877 expect(Ok, stat);
1879 stat = GdipBitmapSetPixel(bitmap, 0, 0, 0xff474849);
1880 expect(Ok, stat);
1882 stat = GdipBitmapGetPixel(bitmap, 1, 1, &color);
1883 expect(Ok, stat);
1884 expect(0xff676869, color);
1886 stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
1887 expect(Ok, stat);
1888 expect(0xff474849, color);
1890 stat = GdipDisposeImage((GpImage*)bitmap);
1891 expect(Ok, stat);
1894 static void check_halftone_palette(ColorPalette *palette)
1896 static const BYTE halftone_values[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
1897 UINT i;
1899 for (i=0; i<palette->Count; i++)
1901 ARGB expected=0xff000000;
1902 if (i<8)
1904 if (i&1) expected |= 0x800000;
1905 if (i&2) expected |= 0x8000;
1906 if (i&4) expected |= 0x80;
1908 else if (i == 8)
1910 expected = 0xffc0c0c0;
1912 else if (i < 16)
1914 if (i&1) expected |= 0xff0000;
1915 if (i&2) expected |= 0xff00;
1916 if (i&4) expected |= 0xff;
1918 else if (i < 40)
1920 expected = 0x00000000;
1922 else
1924 expected |= halftone_values[(i-40)%6];
1925 expected |= halftone_values[((i-40)/6)%6] << 8;
1926 expected |= halftone_values[((i-40)/36)%6] << 16;
1928 ok(expected == palette->Entries[i], "Expected %.8x, got %.8x, i=%u/%u\n",
1929 expected, palette->Entries[i], i, palette->Count);
1933 static void test_palette(void)
1935 GpStatus stat;
1936 GpBitmap *bitmap;
1937 INT size;
1938 BYTE buffer[1040];
1939 ColorPalette *palette=(ColorPalette*)buffer;
1940 ARGB *entries = palette->Entries;
1941 ARGB color=0;
1943 /* test initial palette from non-indexed bitmap */
1944 stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB, NULL, &bitmap);
1945 expect(Ok, stat);
1947 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1948 expect(Ok, stat);
1949 expect(sizeof(UINT)*2+sizeof(ARGB), size);
1951 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1952 expect(Ok, stat);
1953 expect(0, palette->Count);
1955 /* test setting palette on not-indexed bitmap */
1956 palette->Count = 3;
1958 stat = GdipSetImagePalette((GpImage*)bitmap, palette);
1959 expect(Ok, stat);
1961 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1962 expect(Ok, stat);
1963 expect(sizeof(UINT)*2+sizeof(ARGB)*3, size);
1965 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1966 expect(Ok, stat);
1967 expect(3, palette->Count);
1969 GdipDisposeImage((GpImage*)bitmap);
1971 /* test initial palette on 1-bit bitmap */
1972 stat = GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat1bppIndexed, NULL, &bitmap);
1973 expect(Ok, stat);
1975 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1976 expect(Ok, stat);
1977 expect(sizeof(UINT)*2+sizeof(ARGB)*2, size);
1979 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1980 expect(Ok, stat);
1981 expect(PaletteFlagsGrayScale, palette->Flags);
1982 expect(2, palette->Count);
1984 expect(0xff000000, entries[0]);
1985 expect(0xffffffff, entries[1]);
1987 /* test getting/setting pixels */
1988 stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
1989 expect(Ok, stat);
1990 expect(0xff000000, color);
1992 stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffffffff);
1993 ok((stat == Ok) ||
1994 broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
1996 if (stat == Ok)
1998 stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
1999 expect(Ok, stat);
2000 expect(0xffffffff, color);
2003 GdipDisposeImage((GpImage*)bitmap);
2005 /* test initial palette on 4-bit bitmap */
2006 stat = GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat4bppIndexed, NULL, &bitmap);
2007 expect(Ok, stat);
2009 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
2010 expect(Ok, stat);
2011 expect(sizeof(UINT)*2+sizeof(ARGB)*16, size);
2013 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
2014 expect(Ok, stat);
2015 expect(0, palette->Flags);
2016 expect(16, palette->Count);
2018 check_halftone_palette(palette);
2020 /* test getting/setting pixels */
2021 stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
2022 expect(Ok, stat);
2023 expect(0xff000000, color);
2025 stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffff00ff);
2026 ok((stat == Ok) ||
2027 broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
2029 if (stat == Ok)
2031 stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
2032 expect(Ok, stat);
2033 expect(0xffff00ff, color);
2036 GdipDisposeImage((GpImage*)bitmap);
2038 /* test initial palette on 8-bit bitmap */
2039 stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat8bppIndexed, NULL, &bitmap);
2040 expect(Ok, stat);
2042 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
2043 expect(Ok, stat);
2044 expect(sizeof(UINT)*2+sizeof(ARGB)*256, size);
2046 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
2047 expect(Ok, stat);
2048 expect(PaletteFlagsHalftone, palette->Flags);
2049 expect(256, palette->Count);
2051 check_halftone_palette(palette);
2053 /* test getting/setting pixels */
2054 stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
2055 expect(Ok, stat);
2056 expect(0xff000000, color);
2058 stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffcccccc);
2059 ok((stat == Ok) ||
2060 broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
2062 if (stat == Ok)
2064 stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
2065 expect(Ok, stat);
2066 expect(0xffcccccc, color);
2069 /* test setting/getting a different palette */
2070 entries[1] = 0xffcccccc;
2072 stat = GdipSetImagePalette((GpImage*)bitmap, palette);
2073 expect(Ok, stat);
2075 entries[1] = 0;
2077 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
2078 expect(Ok, stat);
2079 expect(sizeof(UINT)*2+sizeof(ARGB)*256, size);
2081 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
2082 expect(Ok, stat);
2083 expect(PaletteFlagsHalftone, palette->Flags);
2084 expect(256, palette->Count);
2085 expect(0xffcccccc, entries[1]);
2087 /* test count < 256 */
2088 palette->Flags = 12345;
2089 palette->Count = 3;
2091 stat = GdipSetImagePalette((GpImage*)bitmap, palette);
2092 expect(Ok, stat);
2094 entries[1] = 0;
2095 entries[3] = 0xdeadbeef;
2097 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
2098 expect(Ok, stat);
2099 expect(sizeof(UINT)*2+sizeof(ARGB)*3, size);
2101 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
2102 expect(Ok, stat);
2103 expect(12345, palette->Flags);
2104 expect(3, palette->Count);
2105 expect(0xffcccccc, entries[1]);
2106 expect(0xdeadbeef, entries[3]);
2108 /* test count > 256 */
2109 palette->Count = 257;
2111 stat = GdipSetImagePalette((GpImage*)bitmap, palette);
2112 ok(stat == InvalidParameter ||
2113 broken(stat == Ok), /* Old gdiplus behavior */
2114 "Expected %.8x, got %.8x\n", InvalidParameter, stat);
2116 GdipDisposeImage((GpImage*)bitmap);
2119 static void test_colormatrix(void)
2121 GpStatus stat;
2122 ColorMatrix colormatrix, graymatrix;
2123 GpImageAttributes *imageattr;
2124 const ColorMatrix identity = {{
2125 {1.0,0.0,0.0,0.0,0.0},
2126 {0.0,1.0,0.0,0.0,0.0},
2127 {0.0,0.0,1.0,0.0,0.0},
2128 {0.0,0.0,0.0,1.0,0.0},
2129 {0.0,0.0,0.0,0.0,1.0}}};
2130 const ColorMatrix double_red = {{
2131 {2.0,0.0,0.0,0.0,0.0},
2132 {0.0,1.0,0.0,0.0,0.0},
2133 {0.0,0.0,1.0,0.0,0.0},
2134 {0.0,0.0,0.0,1.0,0.0},
2135 {0.0,0.0,0.0,0.0,1.0}}};
2136 const ColorMatrix asymmetric = {{
2137 {0.0,1.0,0.0,0.0,0.0},
2138 {0.0,0.0,1.0,0.0,0.0},
2139 {0.0,0.0,0.0,1.0,0.0},
2140 {1.0,0.0,0.0,0.0,0.0},
2141 {0.0,0.0,0.0,0.0,1.0}}};
2142 GpBitmap *bitmap1, *bitmap2;
2143 GpGraphics *graphics;
2144 ARGB color;
2146 colormatrix = identity;
2147 graymatrix = identity;
2149 stat = GdipSetImageAttributesColorMatrix(NULL, ColorAdjustTypeDefault,
2150 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2151 expect(InvalidParameter, stat);
2153 stat = GdipCreateImageAttributes(&imageattr);
2154 expect(Ok, stat);
2156 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2157 TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2158 expect(Ok, stat);
2160 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2161 TRUE, NULL, NULL, ColorMatrixFlagsDefault);
2162 expect(InvalidParameter, stat);
2164 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2165 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2166 expect(Ok, stat);
2168 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2169 TRUE, &colormatrix, NULL, ColorMatrixFlagsSkipGrays);
2170 expect(Ok, stat);
2172 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2173 TRUE, &colormatrix, NULL, ColorMatrixFlagsAltGray);
2174 expect(InvalidParameter, stat);
2176 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2177 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsAltGray);
2178 expect(Ok, stat);
2180 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2181 TRUE, &colormatrix, &graymatrix, 3);
2182 expect(InvalidParameter, stat);
2184 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeCount,
2185 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2186 expect(InvalidParameter, stat);
2188 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeAny,
2189 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2190 expect(InvalidParameter, stat);
2192 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2193 FALSE, NULL, NULL, ColorMatrixFlagsDefault);
2194 expect(Ok, stat);
2196 /* Drawing a bitmap transforms the colors */
2197 colormatrix = double_red;
2198 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2199 TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2200 expect(Ok, stat);
2202 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB, NULL, &bitmap1);
2203 expect(Ok, stat);
2205 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB, NULL, &bitmap2);
2206 expect(Ok, stat);
2208 stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff40ccee);
2209 expect(Ok, stat);
2211 stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
2212 expect(Ok, stat);
2214 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2215 UnitPixel, imageattr, NULL, NULL);
2216 expect(Ok, stat);
2218 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2219 expect(Ok, stat);
2220 expect(0xff80ccee, color);
2222 colormatrix = asymmetric;
2223 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2224 TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2225 expect(Ok, stat);
2227 stat = GdipBitmapSetPixel(bitmap2, 0, 0, 0);
2228 expect(Ok, stat);
2230 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2231 UnitPixel, imageattr, NULL, NULL);
2232 expect(Ok, stat);
2234 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2235 expect(Ok, stat);
2236 ok(color_match(0xeeff40cc, color, 3), "expected 0xeeff40cc, got 0x%08x\n", color);
2238 stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeDefault);
2239 expect(Ok, stat);
2241 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2242 UnitPixel, imageattr, NULL, NULL);
2243 expect(Ok, stat);
2245 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2246 expect(Ok, stat);
2247 ok(color_match(0xff40ccee, color, 1), "Expected ff40ccee, got %.8x\n", color);
2249 GdipDeleteGraphics(graphics);
2250 GdipDisposeImage((GpImage*)bitmap1);
2251 GdipDisposeImage((GpImage*)bitmap2);
2252 GdipDisposeImageAttributes(imageattr);
2255 static void test_gamma(void)
2257 GpStatus stat;
2258 GpImageAttributes *imageattr;
2259 GpBitmap *bitmap1, *bitmap2;
2260 GpGraphics *graphics;
2261 ARGB color;
2263 stat = GdipSetImageAttributesGamma(NULL, ColorAdjustTypeDefault, TRUE, 1.0);
2264 expect(InvalidParameter, stat);
2266 stat = GdipCreateImageAttributes(&imageattr);
2267 expect(Ok, stat);
2269 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 1.0);
2270 expect(Ok, stat);
2272 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeAny, TRUE, 1.0);
2273 expect(InvalidParameter, stat);
2275 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, -1.0);
2276 expect(InvalidParameter, stat);
2278 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 0.0);
2279 expect(InvalidParameter, stat);
2281 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 0.5);
2282 expect(Ok, stat);
2284 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, FALSE, 0.0);
2285 expect(Ok, stat);
2287 /* Drawing a bitmap transforms the colors */
2288 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 3.0);
2289 expect(Ok, stat);
2291 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap1);
2292 expect(Ok, stat);
2294 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap2);
2295 expect(Ok, stat);
2297 stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff80ffff);
2298 expect(Ok, stat);
2300 stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
2301 expect(Ok, stat);
2303 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2304 UnitPixel, imageattr, NULL, NULL);
2305 expect(Ok, stat);
2307 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2308 expect(Ok, stat);
2309 ok(color_match(0xff20ffff, color, 1), "Expected ff20ffff, got %.8x\n", color);
2311 stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeDefault);
2312 expect(Ok, stat);
2314 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2315 UnitPixel, imageattr, NULL, NULL);
2316 expect(Ok, stat);
2318 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2319 expect(Ok, stat);
2320 ok(color_match(0xff80ffff, color, 1), "Expected ff80ffff, got %.8x\n", color);
2322 GdipDeleteGraphics(graphics);
2323 GdipDisposeImage((GpImage*)bitmap1);
2324 GdipDisposeImage((GpImage*)bitmap2);
2325 GdipDisposeImageAttributes(imageattr);
2328 /* 1x1 pixel gif, 2 frames; first frame is white, second is black */
2329 static const unsigned char gifanimation[72] = {
2330 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
2331 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0xf9,0x04,0x00,0x0a,0x00,0xff,
2332 0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x4c,0x01,0x00,
2333 0x21,0xf9,0x04,0x01,0x0a,0x00,0x01,0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,
2334 0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
2337 static void test_multiframegif(void)
2339 LPSTREAM stream;
2340 HGLOBAL hglob;
2341 LPBYTE data;
2342 HRESULT hres;
2343 GpStatus stat;
2344 GpBitmap *bmp;
2345 ARGB color;
2346 UINT count;
2347 GUID dimension;
2349 /* Test frame functions with an animated GIF */
2350 hglob = GlobalAlloc (0, sizeof(gifanimation));
2351 data = GlobalLock (hglob);
2352 memcpy(data, gifanimation, sizeof(gifanimation));
2353 GlobalUnlock(hglob);
2355 hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
2356 ok(hres == S_OK, "Failed to create a stream\n");
2357 if(hres != S_OK) return;
2359 stat = GdipCreateBitmapFromStream(stream, &bmp);
2360 ok(stat == Ok, "Failed to create a Bitmap\n");
2361 if(stat != Ok){
2362 IStream_Release(stream);
2363 return;
2366 /* Bitmap starts at frame 0 */
2367 color = 0xdeadbeef;
2368 stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2369 expect(Ok, stat);
2370 expect(0xffffffff, color);
2372 /* Check that we get correct metadata */
2373 stat = GdipImageGetFrameDimensionsCount((GpImage*)bmp,&count);
2374 expect(Ok, stat);
2375 expect(1, count);
2377 stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1);
2378 expect(Ok, stat);
2379 expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE);
2381 count = 12345;
2382 stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
2383 expect(Ok, stat);
2384 expect(2, count);
2386 /* SelectActiveFrame overwrites our current data */
2387 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 1);
2388 expect(Ok, stat);
2390 color = 0xdeadbeef;
2391 GdipBitmapGetPixel(bmp, 0, 0, &color);
2392 expect(Ok, stat);
2393 expect(0xff000000, color);
2395 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
2396 expect(Ok, stat);
2398 color = 0xdeadbeef;
2399 GdipBitmapGetPixel(bmp, 0, 0, &color);
2400 expect(Ok, stat);
2401 expect(0xffffffff, color);
2403 /* Write over the image data */
2404 stat = GdipBitmapSetPixel(bmp, 0, 0, 0xff000000);
2405 expect(Ok, stat);
2407 /* Switching to the same frame does not overwrite our changes */
2408 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
2409 expect(Ok, stat);
2411 stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2412 expect(Ok, stat);
2413 expect(0xff000000, color);
2415 /* But switching to another frame and back does */
2416 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 1);
2417 expect(Ok, stat);
2419 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
2420 expect(Ok, stat);
2422 stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2423 expect(Ok, stat);
2424 expect(0xffffffff, color);
2426 /* rotate/flip discards the information about other frames */
2427 stat = GdipImageRotateFlip((GpImage*)bmp, Rotate90FlipNone);
2428 expect(Ok, stat);
2430 count = 12345;
2431 stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
2432 expect(Ok, stat);
2433 expect(1, count);
2435 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bmp, __LINE__, FALSE);
2437 GdipDisposeImage((GpImage*)bmp);
2438 IStream_Release(stream);
2440 /* Test with a non-animated gif */
2441 hglob = GlobalAlloc (0, sizeof(gifimage));
2442 data = GlobalLock (hglob);
2443 memcpy(data, gifimage, sizeof(gifimage));
2444 GlobalUnlock(hglob);
2446 hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
2447 ok(hres == S_OK, "Failed to create a stream\n");
2448 if(hres != S_OK) return;
2450 stat = GdipCreateBitmapFromStream(stream, &bmp);
2451 ok(stat == Ok, "Failed to create a Bitmap\n");
2452 if(stat != Ok){
2453 IStream_Release(stream);
2454 return;
2457 /* Check metadata */
2458 stat = GdipImageGetFrameDimensionsCount((GpImage*)bmp,&count);
2459 expect(Ok, stat);
2460 expect(1, count);
2462 stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1);
2463 expect(Ok, stat);
2464 expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE);
2466 count = 12345;
2467 stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
2468 expect(Ok, stat);
2469 expect(1, count);
2471 GdipDisposeImage((GpImage*)bmp);
2472 IStream_Release(stream);
2475 static void test_rotateflip(void)
2477 GpImage *bitmap;
2478 GpStatus stat;
2479 BYTE bits[24];
2480 static const BYTE orig_bits[24] = {
2481 0,0,0xff, 0,0xff,0, 0xff,0,0, 23,23,23,
2482 0xff,0xff,0, 0xff,0,0xff, 0,0xff,0xff, 23,23,23};
2483 UINT width, height;
2484 ARGB color;
2486 memcpy(bits, orig_bits, sizeof(bits));
2487 stat = GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB, bits, (GpBitmap**)&bitmap);
2488 expect(Ok, stat);
2490 stat = GdipImageRotateFlip(bitmap, Rotate90FlipNone);
2491 expect(Ok, stat);
2493 stat = GdipGetImageWidth(bitmap, &width);
2494 expect(Ok, stat);
2495 stat = GdipGetImageHeight(bitmap, &height);
2496 expect(Ok, stat);
2497 expect(2, width);
2498 expect(3, height);
2500 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
2501 expect(Ok, stat);
2502 expect(0xff00ffff, color);
2504 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 1, 0, &color);
2505 expect(Ok, stat);
2506 expect(0xffff0000, color);
2508 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 2, &color);
2509 expect(Ok, stat);
2510 expect(0xffffff00, color);
2512 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 1, 2, &color);
2513 expect(Ok, stat);
2514 expect(0xff0000ff, color);
2516 expect(0, bits[0]);
2517 expect(0, bits[1]);
2518 expect(0xff, bits[2]);
2520 GdipDisposeImage(bitmap);
2522 memcpy(bits, orig_bits, sizeof(bits));
2523 stat = GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB, bits, (GpBitmap**)&bitmap);
2524 expect(Ok, stat);
2526 stat = GdipImageRotateFlip(bitmap, RotateNoneFlipX);
2527 expect(Ok, stat);
2529 stat = GdipGetImageWidth(bitmap, &width);
2530 expect(Ok, stat);
2531 stat = GdipGetImageHeight(bitmap, &height);
2532 expect(Ok, stat);
2533 expect(3, width);
2534 expect(2, height);
2536 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
2537 expect(Ok, stat);
2538 expect(0xff0000ff, color);
2540 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 0, &color);
2541 expect(Ok, stat);
2542 expect(0xffff0000, color);
2544 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 1, &color);
2545 expect(Ok, stat);
2546 expect(0xffffff00, color);
2548 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 1, &color);
2549 expect(Ok, stat);
2550 expect(0xff00ffff, color);
2552 expect(0, bits[0]);
2553 expect(0, bits[1]);
2554 expect(0xff, bits[2]);
2556 GdipDisposeImage(bitmap);
2558 memcpy(bits, orig_bits, sizeof(bits));
2559 stat = GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB, bits, (GpBitmap**)&bitmap);
2560 expect(Ok, stat);
2562 stat = GdipImageRotateFlip(bitmap, RotateNoneFlipY);
2563 expect(Ok, stat);
2565 stat = GdipGetImageWidth(bitmap, &width);
2566 expect(Ok, stat);
2567 stat = GdipGetImageHeight(bitmap, &height);
2568 expect(Ok, stat);
2569 expect(3, width);
2570 expect(2, height);
2572 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
2573 expect(Ok, stat);
2574 expect(0xff00ffff, color);
2576 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 0, &color);
2577 expect(Ok, stat);
2578 expect(0xffffff00, color);
2580 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 1, &color);
2581 expect(Ok, stat);
2582 expect(0xffff0000, color);
2584 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 1, &color);
2585 expect(Ok, stat);
2586 expect(0xff0000ff, color);
2588 expect(0, bits[0]);
2589 expect(0, bits[1]);
2590 expect(0xff, bits[2]);
2592 GdipDisposeImage(bitmap);
2595 static void test_remaptable(void)
2597 GpStatus stat;
2598 GpImageAttributes *imageattr;
2599 GpBitmap *bitmap1, *bitmap2;
2600 GpGraphics *graphics;
2601 ARGB color;
2602 ColorMap *map;
2604 map = GdipAlloc(sizeof(ColorMap));
2606 map->oldColor.Argb = 0xff00ff00;
2607 map->newColor.Argb = 0xffff00ff;
2609 stat = GdipSetImageAttributesRemapTable(NULL, ColorAdjustTypeDefault, TRUE, 1, map);
2610 expect(InvalidParameter, stat);
2612 stat = GdipCreateImageAttributes(&imageattr);
2613 expect(Ok, stat);
2615 stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, TRUE, 1, NULL);
2616 expect(InvalidParameter, stat);
2618 stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeCount, TRUE, 1, map);
2619 expect(InvalidParameter, stat);
2621 stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeAny, TRUE, 1, map);
2622 expect(InvalidParameter, stat);
2624 stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, TRUE, 0, map);
2625 expect(InvalidParameter, stat);
2627 stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, FALSE, 0, NULL);
2628 expect(Ok, stat);
2630 stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, TRUE, 1, map);
2631 expect(Ok, stat);
2633 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap1);
2634 expect(Ok, stat);
2636 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap2);
2637 expect(Ok, stat);
2639 stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff00ff00);
2640 expect(Ok, stat);
2642 stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
2643 expect(Ok, stat);
2645 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2646 UnitPixel, imageattr, NULL, NULL);
2647 expect(Ok, stat);
2649 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2650 expect(Ok, stat);
2651 ok(color_match(0xffff00ff, color, 1), "Expected ffff00ff, got %.8x\n", color);
2653 stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeDefault);
2654 expect(Ok, stat);
2656 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2657 UnitPixel, imageattr, NULL, NULL);
2658 expect(Ok, stat);
2660 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2661 expect(Ok, stat);
2662 ok(color_match(0xff00ff00, color, 1), "Expected ff00ff00, got %.8x\n", color);
2664 GdipDeleteGraphics(graphics);
2665 GdipDisposeImage((GpImage*)bitmap1);
2666 GdipDisposeImage((GpImage*)bitmap2);
2667 GdipDisposeImageAttributes(imageattr);
2668 GdipFree(map);
2671 static void test_colorkey(void)
2673 GpStatus stat;
2674 GpImageAttributes *imageattr;
2675 GpBitmap *bitmap1, *bitmap2;
2676 GpGraphics *graphics;
2677 ARGB color;
2679 stat = GdipSetImageAttributesColorKeys(NULL, ColorAdjustTypeDefault, TRUE, 0xff405060, 0xff708090);
2680 expect(InvalidParameter, stat);
2682 stat = GdipCreateImageAttributes(&imageattr);
2683 expect(Ok, stat);
2685 stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeCount, TRUE, 0xff405060, 0xff708090);
2686 expect(InvalidParameter, stat);
2688 stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeAny, TRUE, 0xff405060, 0xff708090);
2689 expect(InvalidParameter, stat);
2691 stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeDefault, TRUE, 0xff405060, 0xff708090);
2692 expect(Ok, stat);
2694 stat = GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB, NULL, &bitmap1);
2695 expect(Ok, stat);
2697 stat = GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB, NULL, &bitmap2);
2698 expect(Ok, stat);
2700 stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0x20405060);
2701 expect(Ok, stat);
2703 stat = GdipBitmapSetPixel(bitmap1, 0, 1, 0x40506070);
2704 expect(Ok, stat);
2706 stat = GdipBitmapSetPixel(bitmap1, 1, 0, 0x60708090);
2707 expect(Ok, stat);
2709 stat = GdipBitmapSetPixel(bitmap1, 1, 1, 0xffffffff);
2710 expect(Ok, stat);
2712 stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
2713 expect(Ok, stat);
2715 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,2,2, 0,0,2,2,
2716 UnitPixel, imageattr, NULL, NULL);
2717 expect(Ok, stat);
2719 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2720 expect(Ok, stat);
2721 ok(color_match(0x00000000, color, 1), "Expected 00000000, got %.8x\n", color);
2723 stat = GdipBitmapGetPixel(bitmap2, 0, 1, &color);
2724 expect(Ok, stat);
2725 ok(color_match(0x00000000, color, 1), "Expected 00000000, got %.8x\n", color);
2727 stat = GdipBitmapGetPixel(bitmap2, 1, 0, &color);
2728 expect(Ok, stat);
2729 ok(color_match(0x00000000, color, 1), "Expected 00000000, got %.8x\n", color);
2731 stat = GdipBitmapGetPixel(bitmap2, 1, 1, &color);
2732 expect(Ok, stat);
2733 ok(color_match(0xffffffff, color, 1), "Expected ffffffff, got %.8x\n", color);
2735 stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeDefault);
2736 expect(Ok, stat);
2738 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,2,2, 0,0,2,2,
2739 UnitPixel, imageattr, NULL, NULL);
2740 expect(Ok, stat);
2742 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2743 expect(Ok, stat);
2744 ok(color_match(0x20405060, color, 1), "Expected 20405060, got %.8x\n", color);
2746 stat = GdipBitmapGetPixel(bitmap2, 0, 1, &color);
2747 expect(Ok, stat);
2748 ok(color_match(0x40506070, color, 1), "Expected 40506070, got %.8x\n", color);
2750 stat = GdipBitmapGetPixel(bitmap2, 1, 0, &color);
2751 expect(Ok, stat);
2752 ok(color_match(0x60708090, color, 1), "Expected 60708090, got %.8x\n", color);
2754 stat = GdipBitmapGetPixel(bitmap2, 1, 1, &color);
2755 expect(Ok, stat);
2756 ok(color_match(0xffffffff, color, 1), "Expected ffffffff, got %.8x\n", color);
2759 GdipDeleteGraphics(graphics);
2760 GdipDisposeImage((GpImage*)bitmap1);
2761 GdipDisposeImage((GpImage*)bitmap2);
2762 GdipDisposeImageAttributes(imageattr);
2765 static void test_dispose(void)
2767 GpStatus stat;
2768 GpImage *image;
2769 char invalid_image[256];
2771 stat = GdipDisposeImage(NULL);
2772 expect(InvalidParameter, stat);
2774 stat = GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB, NULL, (GpBitmap**)&image);
2775 expect(Ok, stat);
2777 stat = GdipDisposeImage(image);
2778 expect(Ok, stat);
2780 stat = GdipDisposeImage(image);
2781 expect(ObjectBusy, stat);
2783 memset(invalid_image, 0, 256);
2784 stat = GdipDisposeImage((GpImage*)invalid_image);
2785 expect(ObjectBusy, stat);
2788 static LONG obj_refcount(void *obj)
2790 IUnknown_AddRef((IUnknown *)obj);
2791 return IUnknown_Release((IUnknown *)obj);
2794 static GpImage *load_image(const BYTE *image_data, UINT image_size)
2796 IStream *stream;
2797 HGLOBAL hmem;
2798 BYTE *data;
2799 HRESULT hr;
2800 GpStatus status;
2801 GpImage *image = NULL, *clone;
2802 ImageType image_type;
2803 LONG refcount, old_refcount;
2805 hmem = GlobalAlloc(0, image_size);
2806 data = GlobalLock(hmem);
2807 memcpy(data, image_data, image_size);
2808 GlobalUnlock(hmem);
2810 hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
2811 ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr);
2812 if (hr != S_OK) return NULL;
2814 refcount = obj_refcount(stream);
2815 ok(refcount == 1, "expected stream refcount 1, got %d\n", refcount);
2817 status = GdipLoadImageFromStream(stream, &image);
2818 ok(status == Ok || broken(status == InvalidParameter), /* XP */
2819 "GdipLoadImageFromStream error %d\n", status);
2820 if (status != Ok)
2822 IStream_Release(stream);
2823 return NULL;
2826 status = GdipGetImageType(image, &image_type);
2827 ok(status == Ok, "GdipGetImageType error %d\n", status);
2829 refcount = obj_refcount(stream);
2830 if (image_type == ImageTypeBitmap)
2831 ok(refcount > 1, "expected stream refcount > 1, got %d\n", refcount);
2832 else
2833 ok(refcount == 1, "expected stream refcount 1, got %d\n", refcount);
2834 old_refcount = refcount;
2836 status = GdipCloneImage(image, &clone);
2837 ok(status == Ok, "GdipCloneImage error %d\n", status);
2838 refcount = obj_refcount(stream);
2839 ok(refcount == old_refcount, "expected stream refcount %d, got %d\n", old_refcount, refcount);
2840 status = GdipDisposeImage(clone);
2841 ok(status == Ok, "GdipDisposeImage error %d\n", status);
2842 refcount = obj_refcount(stream);
2843 ok(refcount == old_refcount, "expected stream refcount %d, got %d\n", old_refcount, refcount);
2845 refcount = IStream_Release(stream);
2846 if (image_type == ImageTypeBitmap)
2847 ok(refcount >= 1, "expected stream refcount != 0\n");
2848 else
2849 ok(refcount == 0, "expected stream refcount 0, got %d\n", refcount);
2851 return image;
2854 static void test_image_properties(void)
2856 static const struct test_data
2858 const BYTE *image_data;
2859 UINT image_size;
2860 ImageType image_type;
2861 UINT prop_count;
2862 UINT prop_count2; /* if win7 behaves differently */
2863 /* 1st property attributes */
2864 UINT prop_size;
2865 UINT prop_size2; /* if win7 behaves differently */
2866 UINT prop_id;
2867 UINT prop_id2; /* if win7 behaves differently */
2869 td[] =
2871 { pngimage, sizeof(pngimage), ImageTypeBitmap, 4, ~0, 1, 20, 0x5110, 0x132 },
2872 { jpgimage, sizeof(jpgimage), ImageTypeBitmap, 2, ~0, 128, 0, 0x5090, 0x5091 },
2873 { tiffimage, sizeof(tiffimage), ImageTypeBitmap, 16, 0, 4, 0, 0xfe, 0 },
2874 { bmpimage, sizeof(bmpimage), ImageTypeBitmap, 0, 0, 0, 0, 0, 0 },
2875 { wmfimage, sizeof(wmfimage), ImageTypeMetafile, 0, 0, 0, 0, 0, 0 }
2877 GpStatus status;
2878 GpImage *image;
2879 UINT prop_count, prop_size, i;
2880 PROPID prop_id[16] = { 0 };
2881 ImageType image_type;
2882 union
2884 PropertyItem data;
2885 char buf[256];
2886 } item;
2888 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
2890 image = load_image(td[i].image_data, td[i].image_size);
2891 if (!image)
2893 trace("%u: failed to load image data\n", i);
2894 continue;
2897 status = GdipGetImageType(image, &image_type);
2898 ok(status == Ok, "%u: GdipGetImageType error %d\n", i, status);
2899 ok(td[i].image_type == image_type, "%u: expected image_type %d, got %d\n",
2900 i, td[i].image_type, image_type);
2902 status = GdipGetPropertyCount(image, &prop_count);
2903 ok(status == Ok, "%u: GdipGetPropertyCount error %d\n", i, status);
2904 if (td[i].image_data == pngimage || td[i].image_data == jpgimage)
2905 todo_wine
2906 ok(td[i].prop_count == prop_count || td[i].prop_count2 == prop_count,
2907 " %u: expected property count %u or %u, got %u\n",
2908 i, td[i].prop_count, td[i].prop_count2, prop_count);
2909 else
2910 ok(td[i].prop_count == prop_count || td[i].prop_count2 == prop_count,
2911 " %u: expected property count %u or %u, got %u\n",
2912 i, td[i].prop_count, td[i].prop_count2, prop_count);
2914 status = GdipGetPropertyItemSize(NULL, 0, &prop_size);
2915 expect(InvalidParameter, status);
2916 status = GdipGetPropertyItemSize(image, 0, NULL);
2917 expect(InvalidParameter, status);
2918 status = GdipGetPropertyItemSize(image, 0, &prop_size);
2919 if (image_type == ImageTypeMetafile)
2920 expect(NotImplemented, status);
2921 else
2922 expect(PropertyNotFound, status);
2924 status = GdipGetPropertyItem(NULL, 0, 0, &item.data);
2925 expect(InvalidParameter, status);
2926 status = GdipGetPropertyItem(image, 0, 0, NULL);
2927 expect(InvalidParameter, status);
2928 status = GdipGetPropertyItem(image, 0, 0, &item.data);
2929 if (image_type == ImageTypeMetafile)
2930 expect(NotImplemented, status);
2931 else
2932 expect(PropertyNotFound, status);
2934 /* FIXME: remove once Wine is fixed */
2935 if (td[i].prop_count != prop_count)
2937 GdipDisposeImage(image);
2938 continue;
2941 status = GdipGetPropertyIdList(NULL, prop_count, prop_id);
2942 expect(InvalidParameter, status);
2943 status = GdipGetPropertyIdList(image, prop_count, NULL);
2944 expect(InvalidParameter, status);
2945 status = GdipGetPropertyIdList(image, 0, prop_id);
2946 if (image_type == ImageTypeMetafile)
2947 expect(NotImplemented, status);
2948 else if (prop_count == 0)
2949 expect(Ok, status);
2950 else
2951 expect(InvalidParameter, status);
2952 status = GdipGetPropertyIdList(image, prop_count - 1, prop_id);
2953 if (image_type == ImageTypeMetafile)
2954 expect(NotImplemented, status);
2955 else
2956 expect(InvalidParameter, status);
2957 status = GdipGetPropertyIdList(image, prop_count + 1, prop_id);
2958 if (image_type == ImageTypeMetafile)
2959 expect(NotImplemented, status);
2960 else
2961 expect(InvalidParameter, status);
2962 status = GdipGetPropertyIdList(image, prop_count, prop_id);
2963 if (image_type == ImageTypeMetafile)
2964 expect(NotImplemented, status);
2965 else
2967 expect(Ok, status);
2968 if (prop_count != 0)
2969 ok(td[i].prop_id == prop_id[0] || td[i].prop_id2 == prop_id[0],
2970 " %u: expected property id %#x or %#x, got %#x\n",
2971 i, td[i].prop_id, td[i].prop_id2, prop_id[0]);
2974 if (status == Ok)
2976 status = GdipGetPropertyItemSize(image, prop_id[0], &prop_size);
2977 if (prop_count == 0)
2978 expect(PropertyNotFound, status);
2979 else
2981 expect(Ok, status);
2983 assert(sizeof(item) >= prop_size);
2984 ok(prop_size > sizeof(PropertyItem), "%u: got too small prop_size %u\n",
2985 i, prop_size);
2986 ok(td[i].prop_size + sizeof(PropertyItem) == prop_size ||
2987 td[i].prop_size2 + sizeof(PropertyItem) == prop_size,
2988 " %u: expected property size %u or %u, got %u\n",
2989 i, td[i].prop_size, td[i].prop_size2, prop_size);
2991 status = GdipGetPropertyItem(image, prop_id[0], 0, &item.data);
2992 ok(status == InvalidParameter || status == GenericError /* Win7 */,
2993 "%u: expected InvalidParameter, got %d\n", i, status);
2994 status = GdipGetPropertyItem(image, prop_id[0], prop_size - 1, &item.data);
2995 ok(status == InvalidParameter || status == GenericError /* Win7 */,
2996 "%u: expected InvalidParameter, got %d\n", i, status);
2997 status = GdipGetPropertyItem(image, prop_id[0], prop_size + 1, &item.data);
2998 ok(status == InvalidParameter || status == GenericError /* Win7 */,
2999 "%u: expected InvalidParameter, got %d\n", i, status);
3000 status = GdipGetPropertyItem(image, prop_id[0], prop_size, &item.data);
3001 expect(Ok, status);
3002 ok(prop_id[0] == item.data.id,
3003 "%u: expected property id %#x, got %#x\n", i, prop_id[0], item.data.id);
3007 GdipDisposeImage(image);
3011 #define IFD_BYTE 1
3012 #define IFD_ASCII 2
3013 #define IFD_SHORT 3
3014 #define IFD_LONG 4
3015 #define IFD_RATIONAL 5
3016 #define IFD_SBYTE 6
3017 #define IFD_UNDEFINED 7
3018 #define IFD_SSHORT 8
3019 #define IFD_SLONG 9
3020 #define IFD_SRATIONAL 10
3021 #define IFD_FLOAT 11
3022 #define IFD_DOUBLE 12
3024 #ifndef PropertyTagTypeSByte
3025 #define PropertyTagTypeSByte 6
3026 #define PropertyTagTypeSShort 8
3027 #define PropertyTagTypeFloat 11
3028 #define PropertyTagTypeDouble 12
3029 #endif
3031 static UINT documented_type(UINT type)
3033 switch (type)
3035 case PropertyTagTypeSByte: return PropertyTagTypeByte;
3036 case PropertyTagTypeSShort: return PropertyTagTypeShort;
3037 case PropertyTagTypeFloat: return PropertyTagTypeUndefined;
3038 case PropertyTagTypeDouble: return PropertyTagTypeUndefined;
3039 default: return type;
3043 #include "pshpack2.h"
3044 struct IFD_entry
3046 SHORT id;
3047 SHORT type;
3048 ULONG count;
3049 LONG value;
3052 struct IFD_rational
3054 LONG numerator;
3055 LONG denominator;
3058 static const struct tiff_data
3060 USHORT byte_order;
3061 USHORT version;
3062 ULONG dir_offset;
3063 USHORT number_of_entries;
3064 struct IFD_entry entry[40];
3065 ULONG next_IFD;
3066 struct IFD_rational xres;
3067 DOUBLE double_val;
3068 struct IFD_rational srational_val;
3069 char string[14];
3070 SHORT short_val[4];
3071 LONG long_val[2];
3072 FLOAT float_val[2];
3073 struct IFD_rational rational[3];
3074 BYTE pixel_data[4];
3075 } TIFF_data =
3077 #ifdef WORDS_BIGENDIAN
3078 'M' | 'M' << 8,
3079 #else
3080 'I' | 'I' << 8,
3081 #endif
3083 FIELD_OFFSET(struct tiff_data, number_of_entries),
3086 { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */
3087 { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */
3088 { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */
3089 { 0x102, IFD_SHORT, 1, 1 }, /* BITSPERSAMPLE */
3090 { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
3091 { 0x106, IFD_SHORT, 1, 1 }, /* PHOTOMETRIC */
3092 { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_data, pixel_data) }, /* STRIPOFFSETS */
3093 { 0x115, IFD_SHORT, 1, 1 }, /* SAMPLESPERPIXEL */
3094 { 0x116, IFD_LONG, 1, 1 }, /* ROWSPERSTRIP */
3095 { 0x117, IFD_LONG, 1, 1 }, /* STRIPBYTECOUNT */
3096 { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_data, xres) },
3097 { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_data, xres) },
3098 { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */
3099 { 0xf001, IFD_BYTE, 1, 0x11223344 },
3100 { 0xf002, IFD_BYTE, 4, 0x11223344 },
3101 { 0xf003, IFD_SBYTE, 1, 0x11223344 },
3102 { 0xf004, IFD_SSHORT, 1, 0x11223344 },
3103 { 0xf005, IFD_SSHORT, 2, 0x11223344 },
3104 { 0xf006, IFD_SLONG, 1, 0x11223344 },
3105 { 0xf007, IFD_FLOAT, 1, 0x11223344 },
3106 { 0xf008, IFD_DOUBLE, 1, FIELD_OFFSET(struct tiff_data, double_val) },
3107 { 0xf009, IFD_SRATIONAL, 1, FIELD_OFFSET(struct tiff_data, srational_val) },
3108 { 0xf00a, IFD_BYTE, 13, FIELD_OFFSET(struct tiff_data, string) },
3109 { 0xf00b, IFD_SSHORT, 4, FIELD_OFFSET(struct tiff_data, short_val) },
3110 { 0xf00c, IFD_SLONG, 2, FIELD_OFFSET(struct tiff_data, long_val) },
3111 { 0xf00e, IFD_ASCII, 13, FIELD_OFFSET(struct tiff_data, string) },
3112 { 0xf00f, IFD_ASCII, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3113 { 0xf010, IFD_UNDEFINED, 13, FIELD_OFFSET(struct tiff_data, string) },
3114 { 0xf011, IFD_UNDEFINED, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
3115 /* Some gdiplus versions ignore these fields.
3116 { 0xf012, IFD_BYTE, 0, 0x11223344 },
3117 { 0xf013, IFD_SHORT, 0, 0x11223344 },
3118 { 0xf014, IFD_LONG, 0, 0x11223344 },
3119 { 0xf015, IFD_FLOAT, 0, 0x11223344 },*/
3120 { 0xf016, IFD_SRATIONAL, 3, FIELD_OFFSET(struct tiff_data, rational) },
3121 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3122 { 0xf017, IFD_FLOAT, 2, FIELD_OFFSET(struct tiff_data, float_val) },
3125 { 900, 3 },
3126 1234567890.0987654321,
3127 { 0x1a2b3c4d, 0x5a6b7c8d },
3128 "Hello World!",
3129 { 0x0101, 0x0202, 0x0303, 0x0404 },
3130 { 0x11223344, 0x55667788 },
3131 { (FLOAT)1234.5678, (FLOAT)8765.4321 },
3132 { { 0x01020304, 0x05060708 }, { 0x10203040, 0x50607080 }, { 0x11223344, 0x55667788 } },
3133 { 0x11, 0x22, 0x33, 0 }
3135 #include "poppack.h"
3137 static void test_tiff_properties(void)
3139 static const struct test_data
3141 ULONG type, id, length;
3142 const BYTE value[24];
3143 } td[31] =
3145 { PropertyTagTypeShort, 0xff, 2, { 0 } },
3146 { PropertyTagTypeLong, 0x100, 4, { 1 } },
3147 { PropertyTagTypeLong, 0x101, 4, { 1 } },
3148 { PropertyTagTypeShort, 0x102, 2, { 1 } },
3149 { PropertyTagTypeShort, 0x103, 2, { 1 } },
3150 { PropertyTagTypeShort, 0x106, 2, { 1 } },
3151 { PropertyTagTypeLong, 0x111, 4, { 0x44,0x02 } },
3152 { PropertyTagTypeShort, 0x115, 2, { 1 } },
3153 { PropertyTagTypeLong, 0x116, 4, { 1 } },
3154 { PropertyTagTypeLong, 0x117, 4, { 1 } },
3155 { PropertyTagTypeRational, 0x11a, 8, { 0x84,0x03,0,0,0x03 } },
3156 { PropertyTagTypeRational, 0x11b, 8, { 0x84,0x03,0,0,0x03 } },
3157 { PropertyTagTypeShort, 0x128, 2, { 2 } },
3158 { PropertyTagTypeByte, 0xf001, 1, { 0x44 } },
3159 { PropertyTagTypeByte, 0xf002, 4, { 0x44,0x33,0x22,0x11 } },
3160 { PropertyTagTypeSByte, 0xf003, 1, { 0x44 } },
3161 { PropertyTagTypeSShort, 0xf004, 2, { 0x44,0x33 } },
3162 { PropertyTagTypeSShort, 0xf005, 4, { 0x44,0x33,0x22,0x11 } },
3163 { PropertyTagTypeSLONG, 0xf006, 4, { 0x44,0x33,0x22,0x11 } },
3164 { PropertyTagTypeFloat, 0xf007, 4, { 0x44,0x33,0x22,0x11 } },
3165 { PropertyTagTypeDouble, 0xf008, 8, { 0x2c,0x52,0x86,0xb4,0x80,0x65,0xd2,0x41 } },
3166 { PropertyTagTypeSRational, 0xf009, 8, { 0x4d, 0x3c, 0x2b, 0x1a, 0x8d, 0x7c, 0x6b, 0x5a } },
3167 { PropertyTagTypeByte, 0xf00a, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3168 { PropertyTagTypeSShort, 0xf00b, 8, { 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04 } },
3169 { PropertyTagTypeSLONG, 0xf00c, 8, { 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3170 { PropertyTagTypeASCII, 0xf00e, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3171 { PropertyTagTypeASCII, 0xf00f, 5, { 'a','b','c','d' } },
3172 { PropertyTagTypeUndefined, 0xf010, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
3173 { PropertyTagTypeUndefined, 0xf011, 4, { 'a','b','c','d' } },
3174 { PropertyTagTypeSRational, 0xf016, 24,
3175 { 0x04,0x03,0x02,0x01,0x08,0x07,0x06,0x05,
3176 0x40,0x30,0x20,0x10,0x80,0x70,0x60,0x50,
3177 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
3178 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
3179 { PropertyTagTypeFloat, 0xf017, 8, { 0x2b,0x52,0x9a,0x44,0xba,0xf5,0x08,0x46 } },
3181 GpStatus status;
3182 GpImage *image;
3183 GUID guid;
3184 UINT dim_count, frame_count, prop_count, prop_size, i;
3185 PROPID *prop_id;
3186 PropertyItem *prop_item;
3188 image = load_image((const BYTE *)&TIFF_data, sizeof(TIFF_data));
3189 if (!image)
3191 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3192 return;
3195 status = GdipImageGetFrameDimensionsCount(image, &dim_count);
3196 expect(Ok, status);
3197 expect(1, dim_count);
3199 status = GdipImageGetFrameDimensionsList(image, &guid, 1);
3200 expect(Ok, status);
3201 expect_guid(&FrameDimensionPage, &guid, __LINE__, FALSE);
3203 frame_count = 0xdeadbeef;
3204 status = GdipImageGetFrameCount(image, &guid, &frame_count);
3205 expect(Ok, status);
3206 expect(1, frame_count);
3208 prop_count = 0xdeadbeef;
3209 status = GdipGetPropertyCount(image, &prop_count);
3210 expect(Ok, status);
3211 ok(prop_count == sizeof(td)/sizeof(td[0]) ||
3212 broken(prop_count == sizeof(td)/sizeof(td[0]) - 1) /* Win7 SP0 */,
3213 "expected property count %u, got %u\n", (UINT)(sizeof(td)/sizeof(td[0])), prop_count);
3215 prop_id = HeapAlloc(GetProcessHeap(), 0, prop_count * sizeof(*prop_id));
3217 status = GdipGetPropertyIdList(image, prop_count, prop_id);
3218 expect(Ok, status);
3220 for (i = 0; i < prop_count; i++)
3222 status = GdipGetPropertyItemSize(image, prop_id[i], &prop_size);
3223 expect(Ok, status);
3224 if (status != Ok) break;
3225 ok(prop_size > sizeof(*prop_item), "%u: too small item length %u\n", i, prop_size);
3227 prop_item = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, prop_size);
3228 status = GdipGetPropertyItem(image, prop_id[i], prop_size, prop_item);
3229 expect(Ok, status);
3230 ok(prop_item->value == prop_item + 1, "expected item->value %p, got %p\n", prop_item + 1, prop_item->value);
3231 ok(td[i].type == prop_item->type ||
3232 /* Win7 stopped using proper but not documented types, and it
3233 looks broken since TypeFloat and TypeDouble now reported as
3234 TypeUndefined, and signed types reported as unsigned. */
3235 broken(prop_item->type == documented_type(td[i].type)),
3236 "%u: expected type %u, got %u\n", i, td[i].type, prop_item->type);
3237 ok(td[i].id == prop_item->id, "%u: expected id %#x, got %#x\n", i, td[i].id, prop_item->id);
3238 prop_size -= sizeof(*prop_item);
3239 ok(prop_item->length == prop_size, "%u: expected length %u, got %u\n", i, prop_size, prop_item->length);
3240 ok(td[i].length == prop_item->length || broken(td[i].id == 0xf00f && td[i].length == prop_item->length+1) /* XP */,
3241 "%u: expected length %u, got %u\n", i, td[i].length, prop_item->length);
3242 ok(td[i].length == prop_size || broken(td[i].id == 0xf00f && td[i].length == prop_size+1) /* XP */,
3243 "%u: expected length %u, got %u\n", i, td[i].length, prop_size);
3244 if (td[i].length == prop_item->length)
3246 int match = memcmp(td[i].value, prop_item->value, td[i].length) == 0;
3247 ok(match || broken(td[i].length <= 4 && !match), "%u: data mismatch\n", i);
3248 if (!match)
3250 UINT j;
3251 BYTE *data = prop_item->value;
3252 trace("id %#x:", prop_item->id);
3253 for (j = 0; j < prop_item->length; j++)
3254 trace(" %02x", data[j]);
3255 trace("\n");
3258 HeapFree(GetProcessHeap(), 0, prop_item);
3261 HeapFree(GetProcessHeap(), 0, prop_id);
3263 GdipDisposeImage(image);
3266 static void test_GdipGetAllPropertyItems(void)
3268 static const struct test_data
3270 ULONG type, id, length;
3271 BYTE value[32];
3272 } td[16] =
3274 { PropertyTagTypeLong, 0xfe, 4, { 0 } },
3275 { PropertyTagTypeShort, 0x100, 2, { 1 } },
3276 { PropertyTagTypeShort, 0x101, 2, { 1 } },
3277 { PropertyTagTypeShort, 0x102, 6, { 8,0,8,0,8,0 } },
3278 { PropertyTagTypeShort, 0x103, 2, { 1 } },
3279 { PropertyTagTypeShort, 0x106, 2, { 2,0 } },
3280 { PropertyTagTypeASCII, 0x10d, 27, "/home/meh/Desktop/test.tif" },
3281 { PropertyTagTypeLong, 0x111, 4, { 8,0,0,0 } },
3282 { PropertyTagTypeShort, 0x112, 2, { 1 } },
3283 { PropertyTagTypeShort, 0x115, 2, { 3,0 } },
3284 { PropertyTagTypeShort, 0x116, 2, { 0x40,0 } },
3285 { PropertyTagTypeLong, 0x117, 4, { 3,0,0,0 } },
3286 { PropertyTagTypeRational, 0x11a, 8, { 0,0,0,72,0,0,0,1 } },
3287 { PropertyTagTypeRational, 0x11b, 8, { 0,0,0,72,0,0,0,1 } },
3288 { PropertyTagTypeShort, 0x11c, 2, { 1 } },
3289 { PropertyTagTypeShort, 0x128, 2, { 2 } }
3291 GpStatus status;
3292 GpImage *image;
3293 GUID guid;
3294 UINT dim_count, frame_count, prop_count, prop_size, i;
3295 UINT total_size, total_count;
3296 PROPID *prop_id;
3297 PropertyItem *prop_item;
3298 const char *item_data;
3300 image = load_image(tiffimage, sizeof(tiffimage));
3301 ok(image != 0, "Failed to load TIFF image data\n");
3302 if (!image) return;
3304 dim_count = 0xdeadbeef;
3305 status = GdipImageGetFrameDimensionsCount(image, &dim_count);
3306 expect(Ok, status);
3307 expect(1, dim_count);
3309 status = GdipImageGetFrameDimensionsList(image, &guid, 1);
3310 expect(Ok, status);
3311 expect_guid(&FrameDimensionPage, &guid, __LINE__, FALSE);
3313 frame_count = 0xdeadbeef;
3314 status = GdipImageGetFrameCount(image, &guid, &frame_count);
3315 expect(Ok, status);
3316 expect(1, frame_count);
3318 prop_count = 0xdeadbeef;
3319 status = GdipGetPropertyCount(image, &prop_count);
3320 expect(Ok, status);
3321 ok(prop_count == sizeof(td)/sizeof(td[0]),
3322 "expected property count %u, got %u\n", (UINT)(sizeof(td)/sizeof(td[0])), prop_count);
3324 prop_id = HeapAlloc(GetProcessHeap(), 0, prop_count * sizeof(*prop_id));
3326 status = GdipGetPropertyIdList(image, prop_count, prop_id);
3327 expect(Ok, status);
3329 prop_size = 0;
3330 for (i = 0; i < prop_count; i++)
3332 UINT size;
3333 status = GdipGetPropertyItemSize(image, prop_id[i], &size);
3334 expect(Ok, status);
3335 if (status != Ok) break;
3336 ok(size > sizeof(*prop_item), "%u: too small item length %u\n", i, size);
3338 prop_size += size;
3340 prop_item = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
3341 status = GdipGetPropertyItem(image, prop_id[i], size, prop_item);
3342 expect(Ok, status);
3343 ok(prop_item->value == prop_item + 1, "expected item->value %p, got %p\n", prop_item + 1, prop_item->value);
3344 ok(td[i].type == prop_item->type,
3345 "%u: expected type %u, got %u\n", i, td[i].type, prop_item->type);
3346 ok(td[i].id == prop_item->id, "%u: expected id %#x, got %#x\n", i, td[i].id, prop_item->id);
3347 size -= sizeof(*prop_item);
3348 ok(prop_item->length == size, "%u: expected length %u, got %u\n", i, size, prop_item->length);
3349 ok(td[i].length == prop_item->length, "%u: expected length %u, got %u\n", i, td[i].length, prop_item->length);
3350 if (td[i].length == prop_item->length)
3352 int match = memcmp(td[i].value, prop_item->value, td[i].length) == 0;
3353 ok(match, "%u: data mismatch\n", i);
3354 if (!match)
3356 UINT j;
3357 BYTE *data = prop_item->value;
3358 trace("id %#x:", prop_item->id);
3359 for (j = 0; j < prop_item->length; j++)
3360 trace(" %02x", data[j]);
3361 trace("\n");
3364 HeapFree(GetProcessHeap(), 0, prop_item);
3367 HeapFree(GetProcessHeap(), 0, prop_id);
3369 status = GdipGetPropertySize(NULL, &total_size, &total_count);
3370 expect(InvalidParameter, status);
3371 status = GdipGetPropertySize(image, &total_size, NULL);
3372 expect(InvalidParameter, status);
3373 status = GdipGetPropertySize(image, NULL, &total_count);
3374 expect(InvalidParameter, status);
3375 status = GdipGetPropertySize(image, NULL, NULL);
3376 expect(InvalidParameter, status);
3377 total_size = 0xdeadbeef;
3378 total_count = 0xdeadbeef;
3379 status = GdipGetPropertySize(image, &total_size, &total_count);
3380 expect(Ok, status);
3381 ok(prop_count == total_count,
3382 "expected total property count %u, got %u\n", prop_count, total_count);
3383 ok(prop_size == total_size,
3384 "expected total property size %u, got %u\n", prop_size, total_size);
3386 prop_item = HeapAlloc(GetProcessHeap(), 0, prop_size);
3388 status = GdipGetAllPropertyItems(image, 0, prop_count, prop_item);
3389 expect(InvalidParameter, status);
3390 status = GdipGetAllPropertyItems(image, prop_size, 1, prop_item);
3391 expect(InvalidParameter, status);
3392 status = GdipGetAllPropertyItems(image, prop_size, prop_count, NULL);
3393 expect(InvalidParameter, status);
3394 status = GdipGetAllPropertyItems(image, prop_size, prop_count, NULL);
3395 expect(InvalidParameter, status);
3396 status = GdipGetAllPropertyItems(image, 0, 0, NULL);
3397 expect(InvalidParameter, status);
3398 status = GdipGetAllPropertyItems(image, prop_size + 1, prop_count, prop_item);
3399 expect(InvalidParameter, status);
3400 status = GdipGetAllPropertyItems(image, prop_size, prop_count, prop_item);
3401 expect(Ok, status);
3403 item_data = (const char *)(prop_item + prop_count);
3404 for (i = 0; i < prop_count; i++)
3406 ok(prop_item[i].value == item_data, "%u: expected value %p, got %p\n",
3407 i, item_data, prop_item[i].value);
3408 ok(td[i].type == prop_item[i].type,
3409 "%u: expected type %u, got %u\n", i, td[i].type, prop_item[i].type);
3410 ok(td[i].id == prop_item[i].id, "%u: expected id %#x, got %#x\n", i, td[i].id, prop_item[i].id);
3411 ok(td[i].length == prop_item[i].length, "%u: expected length %u, got %u\n", i, td[i].length, prop_item[i].length);
3412 if (td[i].length == prop_item[i].length)
3414 int match = memcmp(td[i].value, prop_item[i].value, td[i].length) == 0;
3415 ok(match, "%u: data mismatch\n", i);
3416 if (!match)
3418 UINT j;
3419 BYTE *data = prop_item[i].value;
3420 trace("id %#x:", prop_item[i].id);
3421 for (j = 0; j < prop_item[i].length; j++)
3422 trace(" %02x", data[j]);
3423 trace("\n");
3426 item_data += prop_item[i].length;
3429 HeapFree(GetProcessHeap(), 0, prop_item);
3431 GdipDisposeImage(image);
3434 static void test_tiff_palette(void)
3436 GpStatus status;
3437 GpImage *image;
3438 PixelFormat format;
3439 INT size;
3440 struct
3442 ColorPalette pal;
3443 ARGB entry[256];
3444 } palette;
3445 ARGB *entries = palette.pal.Entries;
3447 /* 1bpp TIFF without palette */
3448 image = load_image((const BYTE *)&TIFF_data, sizeof(TIFF_data));
3449 if (!image)
3451 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
3452 return;
3455 status = GdipGetImagePixelFormat(image, &format);
3456 expect(Ok, status);
3457 ok(format == PixelFormat1bppIndexed, "expected PixelFormat1bppIndexed, got %#x\n", format);
3459 status = GdipGetImagePaletteSize(image, &size);
3460 ok(status == Ok || broken(status == GenericError), /* XP */
3461 "GdipGetImagePaletteSize error %d\n", status);
3462 if (status == GenericError)
3464 GdipDisposeImage(image);
3465 return;
3467 expect(sizeof(ColorPalette) + sizeof(ARGB), size);
3469 status = GdipGetImagePalette(image, &palette.pal, size);
3470 expect(Ok, status);
3471 expect(0, palette.pal.Flags);
3472 expect(2, palette.pal.Count);
3473 if (palette.pal.Count == 2)
3475 ok(entries[0] == 0xff000000, "expected 0xff000000, got %#x\n", entries[0]);
3476 ok(entries[1] == 0xffffffff, "expected 0xffffffff, got %#x\n", entries[1]);
3479 GdipDisposeImage(image);
3482 static void test_bitmapbits(void)
3484 /* 8 x 2 bitmap */
3485 static const BYTE pixels_24[48] =
3487 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3488 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3489 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3490 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0
3492 static const BYTE pixels_00[48] =
3494 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3495 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3496 0,0,0, 0,0,0, 0,0,0, 0,0,0,
3497 0,0,0, 0,0,0, 0,0,0, 0,0,0
3499 static const BYTE pixels_24_77[64] =
3501 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3502 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3503 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3504 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3505 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
3506 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3508 static const BYTE pixels_77[64] =
3510 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3511 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3512 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3513 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3514 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3515 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3516 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3517 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3519 static const BYTE pixels_8[16] =
3521 0x01,0,0x01,0,0x01,0,0x01,0,
3522 0x01,0,0x01,0,0x01,0,0x01,0
3524 static const BYTE pixels_8_77[64] =
3526 0x01,0,0x01,0,0x01,0,0x01,0,
3527 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3528 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3529 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3530 0x01,0,0x01,0,0x01,0,0x01,0,
3531 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3532 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3533 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3535 static const BYTE pixels_1_77[64] =
3537 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3538 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3539 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3540 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3541 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3542 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3543 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
3544 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
3546 static const BYTE pixels_1[8] = {0xaa,0,0,0,0xaa,0,0,0};
3547 static const struct test_data
3549 PixelFormat format;
3550 UINT bpp;
3551 ImageLockMode mode;
3552 UINT stride, size;
3553 const BYTE *pixels;
3554 const BYTE *pixels_unlocked;
3555 } td[] =
3557 /* 0 */
3558 { PixelFormat24bppRGB, 24, 0xfff0, 24, 48, pixels_24, pixels_00 },
3560 { PixelFormat24bppRGB, 24, 0, 24, 48, pixels_24, pixels_00 },
3561 { PixelFormat24bppRGB, 24, ImageLockModeRead, 24, 48, pixels_24, pixels_00 },
3562 { PixelFormat24bppRGB, 24, ImageLockModeWrite, 24, 48, pixels_24, pixels_00 },
3563 { PixelFormat24bppRGB, 24, ImageLockModeRead|ImageLockModeWrite, 24, 48, pixels_24, pixels_00 },
3564 { PixelFormat24bppRGB, 24, ImageLockModeRead|ImageLockModeUserInputBuf, 32, 64, pixels_24_77, pixels_24 },
3565 { PixelFormat24bppRGB, 24, ImageLockModeWrite|ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_00 },
3566 { PixelFormat24bppRGB, 24, ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_24 },
3567 /* 8 */
3568 { PixelFormat8bppIndexed, 8, 0, 8, 16, pixels_8, pixels_24 },
3569 { PixelFormat8bppIndexed, 8, ImageLockModeRead, 8, 16, pixels_8, pixels_24 },
3570 { PixelFormat8bppIndexed, 8, ImageLockModeWrite, 8, 16, pixels_8, pixels_00 },
3571 { PixelFormat8bppIndexed, 8, ImageLockModeRead|ImageLockModeWrite, 8, 16, pixels_8, pixels_00 },
3572 { PixelFormat8bppIndexed, 8, ImageLockModeRead|ImageLockModeUserInputBuf, 32, 64, pixels_8_77, pixels_24 },
3573 { PixelFormat8bppIndexed, 8, ImageLockModeWrite|ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_00 },
3574 { PixelFormat8bppIndexed, 8, ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_24 },
3575 /* 15 */
3576 { PixelFormat1bppIndexed, 1, 0, 4, 8, pixels_1, pixels_24 },
3577 { PixelFormat1bppIndexed, 1, ImageLockModeRead, 4, 8, pixels_1, pixels_24 },
3578 { PixelFormat1bppIndexed, 1, ImageLockModeWrite, 4, 8, pixels_1, pixels_00 },
3579 { PixelFormat1bppIndexed, 1, ImageLockModeRead|ImageLockModeWrite, 4, 8, pixels_1, pixels_00 },
3580 { PixelFormat1bppIndexed, 1, ImageLockModeRead|ImageLockModeUserInputBuf, 32, 64, pixels_1_77, pixels_24 },
3581 { PixelFormat1bppIndexed, 1, ImageLockModeWrite|ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_00 },
3582 { PixelFormat1bppIndexed, 1, ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_24 },
3584 BYTE buf[64];
3585 GpStatus status;
3586 GpBitmap *bitmap;
3587 UINT i;
3588 BitmapData data;
3589 struct
3591 ColorPalette pal;
3592 ARGB entries[1];
3593 } palette;
3594 ARGB *entries = palette.pal.Entries;
3596 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
3598 BYTE pixels[sizeof(pixels_24)];
3599 memcpy(pixels, pixels_24, sizeof(pixels_24));
3600 status = GdipCreateBitmapFromScan0(8, 2, 24, PixelFormat24bppRGB, pixels, &bitmap);
3601 expect(Ok, status);
3603 /* associate known palette with pixel data */
3604 palette.pal.Flags = PaletteFlagsGrayScale;
3605 palette.pal.Count = 2;
3606 entries[0] = 0xff000000;
3607 entries[1] = 0xffffffff;
3608 status = GdipSetImagePalette((GpImage *)bitmap, &palette.pal);
3609 expect(Ok, status);
3611 memset(&data, 0xfe, sizeof(data));
3612 if (td[i].mode & ImageLockModeUserInputBuf)
3614 memset(buf, 0x77, sizeof(buf));
3615 data.Scan0 = buf;
3616 data.Stride = 32;
3618 status = GdipBitmapLockBits(bitmap, NULL, td[i].mode, td[i].format, &data);
3619 ok(status == Ok || broken(status == InvalidParameter) /* XP */, "%u: GdipBitmapLockBits error %d\n", i, status);
3620 if (status != Ok)
3622 GdipDisposeImage((GpImage *)bitmap);
3623 continue;
3625 ok(data.Width == 8, "%u: expected 8, got %d\n", i, data.Width);
3626 ok(data.Height == 2, "%u: expected 2, got %d\n", i, data.Height);
3627 ok(td[i].stride == data.Stride, "%u: expected %d, got %d\n", i, td[i].stride, data.Stride);
3628 ok(td[i].format == data.PixelFormat, "%u: expected %d, got %d\n", i, td[i].format, data.PixelFormat);
3629 ok(td[i].size == data.Height * data.Stride, "%u: expected %d, got %d\n", i, td[i].size, data.Height * data.Stride);
3630 if (td[i].mode & ImageLockModeUserInputBuf)
3631 ok(data.Scan0 == buf, "%u: got wrong buffer\n", i);
3632 if (td[i].size == data.Height * data.Stride)
3634 UINT j, match, width_bytes = (data.Width * td[i].bpp) / 8;
3636 match = 1;
3637 for (j = 0; j < data.Height; j++)
3639 if (memcmp((const BYTE *)data.Scan0 + j * data.Stride, td[i].pixels + j * data.Stride, width_bytes) != 0)
3641 match = 0;
3642 break;
3645 if ((td[i].mode & (ImageLockModeRead|ImageLockModeUserInputBuf)) || td[i].format == PixelFormat24bppRGB)
3647 ok(match,
3648 "%u: data should match\n", i);
3649 if (!match)
3651 BYTE *bits = data.Scan0;
3652 trace("%u: data mismatch for format %#x:", i, td[i].format);
3653 for (j = 0; j < td[i].size; j++)
3654 trace(" %02x", bits[j]);
3655 trace("\n");
3658 else
3659 ok(!match, "%u: data shouldn't match\n", i);
3661 memset(data.Scan0, 0, td[i].size);
3664 status = GdipBitmapUnlockBits(bitmap, &data);
3665 ok(status == Ok, "%u: GdipBitmapUnlockBits error %d\n", i, status);
3667 memset(&data, 0xfe, sizeof(data));
3668 status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat24bppRGB, &data);
3669 ok(status == Ok, "%u: GdipBitmapLockBits error %d\n", i, status);
3670 ok(data.Width == 8, "%u: expected 8, got %d\n", i, data.Width);
3671 ok(data.Height == 2, "%u: expected 2, got %d\n", i, data.Height);
3672 ok(data.Stride == 24, "%u: expected 24, got %d\n", i, data.Stride);
3673 ok(data.PixelFormat == PixelFormat24bppRGB, "%u: got wrong pixel format %d\n", i, data.PixelFormat);
3674 ok(data.Height * data.Stride == 48, "%u: expected 48, got %d\n", i, data.Height * data.Stride);
3675 if (data.Height * data.Stride == 48)
3677 int match = memcmp(data.Scan0, td[i].pixels_unlocked, 48) == 0;
3678 ok(match, "%u: data should match\n", i);
3679 if (!match)
3681 UINT j;
3682 BYTE *bits = data.Scan0;
3683 trace("%u: data mismatch for format %#x:", i, td[i].format);
3684 for (j = 0; j < 48; j++)
3685 trace(" %02x", bits[j]);
3686 trace("\n");
3690 status = GdipBitmapUnlockBits(bitmap, &data);
3691 ok(status == Ok, "%u: GdipBitmapUnlockBits error %d\n", i, status);
3693 status = GdipDisposeImage((GpImage *)bitmap);
3694 expect(Ok, status);
3698 static void test_DrawImage(void)
3700 BYTE black_1x1[4] = { 0,0,0,0 };
3701 BYTE white_2x2[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
3702 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
3703 BYTE black_2x2[16] = { 0,0,0,0,0,0,0xff,0xff,
3704 0,0,0,0,0,0,0xff,0xff };
3705 GpStatus status;
3706 union
3708 GpBitmap *bitmap;
3709 GpImage *image;
3710 } u1, u2;
3711 GpGraphics *graphics;
3712 int match;
3714 status = GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB, black_1x1, &u1.bitmap);
3715 expect(Ok, status);
3716 status = GdipBitmapSetResolution(u1.bitmap, 100.0, 100.0);
3717 expect(Ok, status);
3719 status = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB, white_2x2, &u2.bitmap);
3720 expect(Ok, status);
3721 status = GdipBitmapSetResolution(u2.bitmap, 300.0, 300.0);
3722 expect(Ok, status);
3723 status = GdipGetImageGraphicsContext(u2.image, &graphics);
3724 expect(Ok, status);
3725 status = GdipSetInterpolationMode(graphics, InterpolationModeNearestNeighbor);
3726 expect(Ok, status);
3728 status = GdipDrawImageI(graphics, u1.image, 0, 0);
3729 expect(Ok, status);
3731 match = memcmp(white_2x2, black_2x2, sizeof(black_2x2)) == 0;
3732 ok(match, "data should match\n");
3733 if (!match)
3735 UINT i, size = sizeof(white_2x2);
3736 BYTE *bits = white_2x2;
3737 for (i = 0; i < size; i++)
3738 trace(" %02x", bits[i]);
3739 trace("\n");
3742 status = GdipDeleteGraphics(graphics);
3743 expect(Ok, status);
3744 status = GdipDisposeImage(u1.image);
3745 expect(Ok, status);
3746 status = GdipDisposeImage(u2.image);
3747 expect(Ok, status);
3750 static void test_GdipDrawImagePointRect(void)
3752 BYTE black_1x1[4] = { 0,0,0,0 };
3753 BYTE white_2x2[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
3754 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
3755 BYTE black_2x2[16] = { 0,0,0,0,0,0,0xff,0xff,
3756 0,0,0,0,0,0,0xff,0xff };
3757 GpStatus status;
3758 union
3760 GpBitmap *bitmap;
3761 GpImage *image;
3762 } u1, u2;
3763 GpGraphics *graphics;
3764 int match;
3766 status = GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB, black_1x1, &u1.bitmap);
3767 expect(Ok, status);
3768 status = GdipBitmapSetResolution(u1.bitmap, 100.0, 100.0);
3769 expect(Ok, status);
3771 status = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB, white_2x2, &u2.bitmap);
3772 expect(Ok, status);
3773 status = GdipBitmapSetResolution(u2.bitmap, 300.0, 300.0);
3774 expect(Ok, status);
3775 status = GdipGetImageGraphicsContext(u2.image, &graphics);
3776 expect(Ok, status);
3777 status = GdipSetInterpolationMode(graphics, InterpolationModeNearestNeighbor);
3778 expect(Ok, status);
3780 status = GdipDrawImagePointRectI(graphics, u1.image, 0, 0, 0, 0, 1, 1, UnitPixel);
3781 expect(Ok, status);
3783 match = memcmp(white_2x2, black_2x2, sizeof(black_2x2)) == 0;
3784 ok(match, "data should match\n");
3785 if (!match)
3787 UINT i, size = sizeof(white_2x2);
3788 BYTE *bits = white_2x2;
3789 for (i = 0; i < size; i++)
3790 trace(" %02x", bits[i]);
3791 trace("\n");
3794 status = GdipDeleteGraphics(graphics);
3795 expect(Ok, status);
3796 status = GdipDisposeImage(u1.image);
3797 expect(Ok, status);
3798 status = GdipDisposeImage(u2.image);
3799 expect(Ok, status);
3802 static void test_image_format(void)
3804 static const PixelFormat fmt[] =
3806 PixelFormat1bppIndexed, PixelFormat4bppIndexed, PixelFormat8bppIndexed,
3807 PixelFormat16bppGrayScale, PixelFormat16bppRGB555, PixelFormat16bppRGB565,
3808 PixelFormat16bppARGB1555, PixelFormat24bppRGB, PixelFormat32bppRGB,
3809 PixelFormat32bppARGB, PixelFormat32bppPARGB, PixelFormat48bppRGB,
3810 PixelFormat64bppARGB, PixelFormat64bppPARGB, PixelFormat32bppCMYK
3812 GpStatus status;
3813 GpBitmap *bitmap;
3814 GpImage *thumb;
3815 HBITMAP hbitmap;
3816 BITMAP bm;
3817 PixelFormat format;
3818 BitmapData data;
3819 UINT i, ret;
3821 for (i = 0; i < sizeof(fmt)/sizeof(fmt[0]); i++)
3823 status = GdipCreateBitmapFromScan0(1, 1, 0, fmt[i], NULL, &bitmap);
3824 ok(status == Ok || broken(status == InvalidParameter) /* before win7 */,
3825 "GdipCreateBitmapFromScan0 error %d\n", status);
3826 if (status != Ok) continue;
3828 status = GdipGetImagePixelFormat((GpImage *)bitmap, &format);
3829 expect(Ok, status);
3830 expect(fmt[i], format);
3832 status = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0);
3833 if (fmt[i] == PixelFormat16bppGrayScale || fmt[i] == PixelFormat32bppCMYK)
3834 todo_wine expect(InvalidParameter, status);
3835 else
3837 expect(Ok, status);
3838 ret = GetObjectW(hbitmap, sizeof(bm), &bm);
3839 expect(sizeof(bm), ret);
3840 expect(0, bm.bmType);
3841 expect(1, bm.bmWidth);
3842 expect(1, bm.bmHeight);
3843 expect(4, bm.bmWidthBytes);
3844 expect(1, bm.bmPlanes);
3845 expect(32, bm.bmBitsPixel);
3846 DeleteObject(hbitmap);
3849 status = GdipGetImageThumbnail((GpImage *)bitmap, 0, 0, &thumb, NULL, NULL);
3850 if (fmt[i] == PixelFormat16bppGrayScale || fmt[i] == PixelFormat32bppCMYK)
3851 todo_wine
3852 ok(status == OutOfMemory || broken(status == InvalidParameter) /* before win7 */,
3853 "expected OutOfMemory, got %d\n", status);
3854 else
3856 expect(Ok, status);
3857 status = GdipGetImagePixelFormat(thumb, &format);
3858 expect(Ok, status);
3859 ok(format == PixelFormat32bppPARGB || broken(format != PixelFormat32bppPARGB) /* before win7 */,
3860 "expected PixelFormat32bppPARGB, got %#x\n", format);
3861 status = GdipDisposeImage(thumb);
3862 expect(Ok, status);
3865 status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat32bppPARGB, &data);
3866 if (fmt[i] == PixelFormat16bppGrayScale || fmt[i] == PixelFormat32bppCMYK)
3867 todo_wine expect(InvalidParameter, status);
3868 else
3870 expect(Ok, status);
3871 status = GdipBitmapUnlockBits(bitmap, &data);
3872 expect(Ok, status);
3875 status = GdipDisposeImage((GpImage *)bitmap);
3876 expect(Ok, status);
3880 static void test_DrawImage_scale(void)
3882 static const BYTE back_8x1[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
3883 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
3884 static const BYTE image_080[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,
3885 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
3886 static const BYTE image_100[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,
3887 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
3888 static const BYTE image_120[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,
3889 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
3890 static const BYTE image_150[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
3891 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
3892 static const BYTE image_180[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
3893 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
3894 static const BYTE image_200[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
3895 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
3896 static const BYTE image_250[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,
3897 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
3898 static const BYTE image_120_half[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
3899 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
3900 static const BYTE image_150_half[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
3901 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
3902 static const BYTE image_200_half[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
3903 0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40 };
3904 static const BYTE image_250_half[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
3905 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 };
3906 static const struct test_data
3908 REAL scale_x;
3909 PixelOffsetMode pixel_offset_mode;
3910 const BYTE *image;
3911 BOOL todo;
3912 } td[] =
3914 { 0.8, PixelOffsetModeNone, image_080 }, /* 0 */
3915 { 1.0, PixelOffsetModeNone, image_100 },
3916 { 1.2, PixelOffsetModeNone, image_120 },
3917 { 1.5, PixelOffsetModeNone, image_150 },
3918 { 1.8, PixelOffsetModeNone, image_180 },
3919 { 2.0, PixelOffsetModeNone, image_200 },
3920 { 2.5, PixelOffsetModeNone, image_250 },
3922 { 0.8, PixelOffsetModeHighSpeed, image_080 }, /* 7 */
3923 { 1.0, PixelOffsetModeHighSpeed, image_100 },
3924 { 1.2, PixelOffsetModeHighSpeed, image_120 },
3925 { 1.5, PixelOffsetModeHighSpeed, image_150 },
3926 { 1.8, PixelOffsetModeHighSpeed, image_180 },
3927 { 2.0, PixelOffsetModeHighSpeed, image_200 },
3928 { 2.5, PixelOffsetModeHighSpeed, image_250 },
3930 { 0.8, PixelOffsetModeHalf, image_080 }, /* 14 */
3931 { 1.0, PixelOffsetModeHalf, image_100 },
3932 { 1.2, PixelOffsetModeHalf, image_120_half, TRUE },
3933 { 1.5, PixelOffsetModeHalf, image_150_half, TRUE },
3934 { 1.8, PixelOffsetModeHalf, image_180 },
3935 { 2.0, PixelOffsetModeHalf, image_200_half, TRUE },
3936 { 2.5, PixelOffsetModeHalf, image_250_half, TRUE },
3938 { 0.8, PixelOffsetModeHighQuality, image_080 }, /* 21 */
3939 { 1.0, PixelOffsetModeHighQuality, image_100 },
3940 { 1.2, PixelOffsetModeHighQuality, image_120_half, TRUE },
3941 { 1.5, PixelOffsetModeHighQuality, image_150_half, TRUE },
3942 { 1.8, PixelOffsetModeHighQuality, image_180 },
3943 { 2.0, PixelOffsetModeHighQuality, image_200_half, TRUE },
3944 { 2.5, PixelOffsetModeHighQuality, image_250_half, TRUE },
3946 BYTE src_2x1[6] = { 0x80,0x80,0x80,0x80,0x80,0x80 };
3947 BYTE dst_8x1[24];
3948 GpStatus status;
3949 union
3951 GpBitmap *bitmap;
3952 GpImage *image;
3953 } u1, u2;
3954 GpGraphics *graphics;
3955 GpMatrix *matrix;
3956 int i, match;
3958 status = GdipCreateBitmapFromScan0(2, 1, 4, PixelFormat24bppRGB, src_2x1, &u1.bitmap);
3959 expect(Ok, status);
3960 status = GdipBitmapSetResolution(u1.bitmap, 100.0, 100.0);
3961 expect(Ok, status);
3963 status = GdipCreateBitmapFromScan0(8, 1, 24, PixelFormat24bppRGB, dst_8x1, &u2.bitmap);
3964 expect(Ok, status);
3965 status = GdipBitmapSetResolution(u2.bitmap, 100.0, 100.0);
3966 expect(Ok, status);
3967 status = GdipGetImageGraphicsContext(u2.image, &graphics);
3968 expect(Ok, status);
3969 status = GdipSetInterpolationMode(graphics, InterpolationModeNearestNeighbor);
3970 expect(Ok, status);
3972 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
3974 status = GdipSetPixelOffsetMode(graphics, td[i].pixel_offset_mode);
3975 expect(Ok, status);
3977 status = GdipCreateMatrix2(td[i].scale_x, 0.0, 0.0, 1.0, 0.0, 0.0, &matrix);
3978 expect(Ok, status);
3979 status = GdipSetWorldTransform(graphics, matrix);
3980 expect(Ok, status);
3981 GdipDeleteMatrix(matrix);
3983 memcpy(dst_8x1, back_8x1, sizeof(dst_8x1));
3984 status = GdipDrawImageI(graphics, u1.image, 1, 0);
3985 expect(Ok, status);
3987 match = memcmp(dst_8x1, td[i].image, sizeof(dst_8x1)) == 0;
3988 if (!match && td[i].todo)
3989 todo_wine ok(match, "%d: data should match\n", i);
3990 else
3991 ok(match, "%d: data should match\n", i);
3992 if (!match)
3994 UINT i, size = sizeof(dst_8x1);
3995 const BYTE *bits = dst_8x1;
3996 for (i = 0; i < size; i++)
3997 trace(" %02x", bits[i]);
3998 trace("\n");
4002 status = GdipDeleteGraphics(graphics);
4003 expect(Ok, status);
4004 status = GdipDisposeImage(u1.image);
4005 expect(Ok, status);
4006 status = GdipDisposeImage(u2.image);
4007 expect(Ok, status);
4010 static const BYTE animatedgif[] = {
4011 'G','I','F','8','9','a',0x01,0x00,0x01,0x00,0xA1,0x02,0x00,
4012 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
4013 /*0x21,0xFF,0x0B,'A','N','I','M','E','X','T','S','1','.','0',*/
4014 0x21,0xFF,0x0B,'N','E','T','S','C','A','P','E','2','.','0',
4015 0x03,0x01,0x05,0x00,0x00,
4016 0x21,0xFE,0x0C,'H','e','l','l','o',' ','W','o','r','l','d','!',0x00,
4017 0x21,0x01,0x0D,'a','n','i','m','a','t','i','o','n','.','g','i','f',0x00,
4018 0x21,0xF9,0x04,0xff,0x0A,0x00,0x08,0x00,
4019 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4020 0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,
4021 0x02,0x02,0x4C,0x01,0x00,
4022 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','1',0x00,
4023 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','1',0x00,
4024 0x21,0xF9,0x04,0x00,0x14,0x00,0x01,0x00,
4025 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
4026 0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,
4027 0x02,0x02,0x44,0x01,0x00,
4028 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','2',0x00,
4029 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','2',0x00,0x3B
4032 static void test_gif_properties(void)
4034 static const struct test_data
4036 ULONG type, id, length;
4037 const BYTE value[13];
4038 } td[] =
4040 { PropertyTagTypeLong, PropertyTagFrameDelay, 8, { 10,0,0,0,20,0,0,0 } },
4041 { PropertyTagTypeASCII, PropertyTagExifUserComment, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } },
4042 { PropertyTagTypeShort, PropertyTagLoopCount, 2, { 5,0 } },
4043 { PropertyTagTypeByte, PropertyTagGlobalPalette, 12, { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c } },
4044 { PropertyTagTypeByte, PropertyTagIndexBackground, 1, { 2 } },
4045 { PropertyTagTypeByte, PropertyTagIndexTransparent, 1, { 8 } }
4047 GpStatus status;
4048 GpImage *image;
4049 GUID guid;
4050 UINT dim_count, frame_count, prop_count, prop_size, i;
4051 UINT total_size, total_count;
4052 PROPID *prop_id;
4053 PropertyItem *prop_item;
4054 const char *item_data;
4056 image = load_image(animatedgif, sizeof(animatedgif));
4057 if (!image) /* XP fails to load this GIF image */
4059 trace("Failed to load GIF image data\n");
4060 return;
4063 status = GdipImageGetFrameDimensionsCount(image, &dim_count);
4064 expect(Ok, status);
4065 expect(1, dim_count);
4067 status = GdipImageGetFrameDimensionsList(image, &guid, 1);
4068 expect(Ok, status);
4069 expect_guid(&FrameDimensionTime, &guid, __LINE__, FALSE);
4071 status = GdipImageGetFrameCount(image, &guid, &frame_count);
4072 expect(Ok, status);
4073 expect(2, frame_count);
4075 status = GdipImageSelectActiveFrame(image, &guid, 1);
4076 expect(Ok, status);
4078 status = GdipGetPropertyCount(image, &prop_count);
4079 expect(Ok, status);
4080 ok(prop_count == sizeof(td)/sizeof(td[0]) || broken(prop_count == 1) /* before win7 */,
4081 "expected property count %u, got %u\n", (UINT)(sizeof(td)/sizeof(td[0])), prop_count);
4083 if (prop_count != sizeof(td)/sizeof(td[0]))
4085 GdipDisposeImage(image);
4086 return;
4089 prop_id = HeapAlloc(GetProcessHeap(), 0, prop_count * sizeof(*prop_id));
4091 status = GdipGetPropertyIdList(image, prop_count, prop_id);
4092 expect(Ok, status);
4094 prop_size = 0;
4095 for (i = 0; i < prop_count; i++)
4097 UINT size;
4098 status = GdipGetPropertyItemSize(image, prop_id[i], &size);
4099 expect(Ok, status);
4100 if (status != Ok) break;
4101 ok(size > sizeof(*prop_item), "%u: too small item length %u\n", i, size);
4103 prop_size += size;
4105 prop_item = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
4106 status = GdipGetPropertyItem(image, prop_id[i], size, prop_item);
4107 expect(Ok, status);
4108 ok(prop_item->value == prop_item + 1, "expected item->value %p, got %p\n", prop_item + 1, prop_item->value);
4109 ok(td[i].type == prop_item->type,
4110 "%u: expected type %u, got %u\n", i, td[i].type, prop_item->type);
4111 ok(td[i].id == prop_item->id, "%u: expected id %#x, got %#x\n", i, td[i].id, prop_item->id);
4112 size -= sizeof(*prop_item);
4113 ok(prop_item->length == size, "%u: expected length %u, got %u\n", i, size, prop_item->length);
4114 ok(td[i].length == prop_item->length, "%u: expected length %u, got %u\n", i, td[i].length, prop_item->length);
4115 if (td[i].length == prop_item->length)
4117 int match = memcmp(td[i].value, prop_item->value, td[i].length) == 0;
4118 ok(match, "%u: data mismatch\n", i);
4119 if (!match)
4121 UINT j;
4122 BYTE *data = prop_item->value;
4123 trace("id %#x:", prop_item->id);
4124 for (j = 0; j < prop_item->length; j++)
4125 trace(" %02x", data[j]);
4126 trace("\n");
4129 HeapFree(GetProcessHeap(), 0, prop_item);
4132 HeapFree(GetProcessHeap(), 0, prop_id);
4134 status = GdipGetPropertySize(NULL, &total_size, &total_count);
4135 expect(InvalidParameter, status);
4136 status = GdipGetPropertySize(image, &total_size, NULL);
4137 expect(InvalidParameter, status);
4138 status = GdipGetPropertySize(image, NULL, &total_count);
4139 expect(InvalidParameter, status);
4140 status = GdipGetPropertySize(image, NULL, NULL);
4141 expect(InvalidParameter, status);
4142 total_size = 0xdeadbeef;
4143 total_count = 0xdeadbeef;
4144 status = GdipGetPropertySize(image, &total_size, &total_count);
4145 expect(Ok, status);
4146 ok(prop_count == total_count,
4147 "expected total property count %u, got %u\n", prop_count, total_count);
4148 ok(prop_size == total_size,
4149 "expected total property size %u, got %u\n", prop_size, total_size);
4151 prop_item = HeapAlloc(GetProcessHeap(), 0, prop_size);
4153 status = GdipGetAllPropertyItems(image, 0, prop_count, prop_item);
4154 expect(InvalidParameter, status);
4155 status = GdipGetAllPropertyItems(image, prop_size, 1, prop_item);
4156 expect(InvalidParameter, status);
4157 status = GdipGetAllPropertyItems(image, prop_size, prop_count, NULL);
4158 expect(InvalidParameter, status);
4159 status = GdipGetAllPropertyItems(image, prop_size, prop_count, NULL);
4160 expect(InvalidParameter, status);
4161 status = GdipGetAllPropertyItems(image, 0, 0, NULL);
4162 expect(InvalidParameter, status);
4163 status = GdipGetAllPropertyItems(image, prop_size + 1, prop_count, prop_item);
4164 expect(InvalidParameter, status);
4165 status = GdipGetAllPropertyItems(image, prop_size, prop_count, prop_item);
4166 expect(Ok, status);
4168 item_data = (const char *)(prop_item + prop_count);
4169 for (i = 0; i < prop_count; i++)
4171 ok(prop_item[i].value == item_data, "%u: expected value %p, got %p\n",
4172 i, item_data, prop_item[i].value);
4173 ok(td[i].type == prop_item[i].type,
4174 "%u: expected type %u, got %u\n", i, td[i].type, prop_item[i].type);
4175 ok(td[i].id == prop_item[i].id, "%u: expected id %#x, got %#x\n", i, td[i].id, prop_item[i].id);
4176 ok(td[i].length == prop_item[i].length, "%u: expected length %u, got %u\n", i, td[i].length, prop_item[i].length);
4177 if (td[i].length == prop_item[i].length)
4179 int match = memcmp(td[i].value, prop_item[i].value, td[i].length) == 0;
4180 ok(match, "%u: data mismatch\n", i);
4181 if (!match)
4183 UINT j;
4184 BYTE *data = prop_item[i].value;
4185 trace("id %#x:", prop_item[i].id);
4186 for (j = 0; j < prop_item[i].length; j++)
4187 trace(" %02x", data[j]);
4188 trace("\n");
4191 item_data += prop_item[i].length;
4194 HeapFree(GetProcessHeap(), 0, prop_item);
4196 GdipDisposeImage(image);
4199 static void test_ARGB_conversion(void)
4201 BYTE argb[8] = { 0x11,0x22,0x33,0x80, 0xff,0xff,0xff,0 };
4202 BYTE pargb[8] = { 0x09,0x11,0x1a,0x80, 0,0,0,0 };
4203 BYTE rgb32_xp[8] = { 0x11,0x22,0x33,0xff, 0xff,0xff,0xff,0xff };
4204 BYTE rgb24[6] = { 0x11,0x22,0x33, 0xff,0xff,0xff };
4205 BYTE *bits;
4206 GpBitmap *bitmap;
4207 BitmapData data;
4208 GpStatus status;
4209 int match;
4211 status = GdipCreateBitmapFromScan0(2, 1, 8, PixelFormat32bppARGB, argb, &bitmap);
4212 expect(Ok, status);
4214 status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat32bppPARGB, &data);
4215 expect(Ok, status);
4216 ok(data.Width == 2, "expected 2, got %d\n", data.Width);
4217 ok(data.Height == 1, "expected 1, got %d\n", data.Height);
4218 ok(data.Stride == 8, "expected 8, got %d\n", data.Stride);
4219 ok(data.PixelFormat == PixelFormat32bppPARGB, "expected PixelFormat32bppPARGB, got %d\n", data.PixelFormat);
4220 match = !memcmp(data.Scan0, pargb, sizeof(pargb));
4221 ok(match, "bits don't match\n");
4222 if (!match)
4224 bits = data.Scan0;
4225 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppPARGB,
4226 bits[0], bits[1], bits[2], bits[3], bits[4], bits[5], bits[6], bits[7]);
4228 status = GdipBitmapUnlockBits(bitmap, &data);
4229 expect(Ok, status);
4231 status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat32bppRGB, &data);
4232 expect(Ok, status);
4233 ok(data.Width == 2, "expected 2, got %d\n", data.Width);
4234 ok(data.Height == 1, "expected 1, got %d\n", data.Height);
4235 ok(data.Stride == 8, "expected 8, got %d\n", data.Stride);
4236 ok(data.PixelFormat == PixelFormat32bppRGB, "expected PixelFormat32bppRGB, got %d\n", data.PixelFormat);
4237 match = !memcmp(data.Scan0, argb, sizeof(argb)) ||
4238 !memcmp(data.Scan0, rgb32_xp, sizeof(rgb32_xp));
4239 ok(match, "bits don't match\n");
4240 if (!match)
4242 bits = data.Scan0;
4243 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppRGB,
4244 bits[0], bits[1], bits[2], bits[3], bits[4], bits[5], bits[6], bits[7]);
4246 status = GdipBitmapUnlockBits(bitmap, &data);
4247 expect(Ok, status);
4249 status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat24bppRGB, &data);
4250 expect(Ok, status);
4251 ok(data.Width == 2, "expected 2, got %d\n", data.Width);
4252 ok(data.Height == 1, "expected 1, got %d\n", data.Height);
4253 ok(data.Stride == 8, "expected 8, got %d\n", data.Stride);
4254 ok(data.PixelFormat == PixelFormat24bppRGB, "expected PixelFormat24bppRGB, got %d\n", data.PixelFormat);
4255 match = !memcmp(data.Scan0, rgb24, sizeof(rgb24));
4256 ok(match, "bits don't match\n");
4257 if (!match)
4259 bits = data.Scan0;
4260 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat24bppRGB,
4261 bits[0], bits[1], bits[2], bits[3], bits[4], bits[5], bits[6], bits[7]);
4263 status = GdipBitmapUnlockBits(bitmap, &data);
4264 expect(Ok, status);
4266 GdipDisposeImage((GpImage *)bitmap);
4270 static void test_CloneBitmapArea(void)
4272 GpStatus status;
4273 GpBitmap *bitmap, *copy;
4274 BitmapData data, data2;
4276 status = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB, NULL, &bitmap);
4277 expect(Ok, status);
4279 status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead | ImageLockModeWrite, PixelFormat24bppRGB, &data);
4280 expect(Ok, status);
4282 status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat24bppRGB, &data2);
4283 expect(WrongState, status);
4285 status = GdipCloneBitmapAreaI(0, 0, 1, 1, PixelFormat24bppRGB, bitmap, &copy);
4286 expect(Ok, status);
4288 status = GdipBitmapUnlockBits(bitmap, &data);
4289 expect(Ok, status);
4291 GdipDisposeImage((GpImage *)copy);
4292 GdipDisposeImage((GpImage *)bitmap);
4295 START_TEST(image)
4297 struct GdiplusStartupInput gdiplusStartupInput;
4298 ULONG_PTR gdiplusToken;
4300 gdiplusStartupInput.GdiplusVersion = 1;
4301 gdiplusStartupInput.DebugEventCallback = NULL;
4302 gdiplusStartupInput.SuppressBackgroundThread = 0;
4303 gdiplusStartupInput.SuppressExternalCodecs = 0;
4305 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
4307 test_CloneBitmapArea();
4308 test_ARGB_conversion();
4309 test_DrawImage_scale();
4310 test_image_format();
4311 test_DrawImage();
4312 test_GdipDrawImagePointRect();
4313 test_bitmapbits();
4314 test_tiff_palette();
4315 test_GdipGetAllPropertyItems();
4316 test_tiff_properties();
4317 test_gif_properties();
4318 test_image_properties();
4319 test_Scan0();
4320 test_FromGdiDib();
4321 test_GetImageDimension();
4322 test_GdipImageGetFrameDimensionsCount();
4323 test_LoadingImages();
4324 test_SavingImages();
4325 test_encoders();
4326 test_LockBits();
4327 test_LockBits_UserBuf();
4328 test_GdipCreateBitmapFromHBITMAP();
4329 test_GdipGetImageFlags();
4330 test_GdipCloneImage();
4331 test_testcontrol();
4332 test_fromhicon();
4333 test_getrawformat();
4334 test_loadwmf();
4335 test_createfromwmf();
4336 test_resolution();
4337 test_createhbitmap();
4338 test_getthumbnail();
4339 test_getsetpixel();
4340 test_palette();
4341 test_colormatrix();
4342 test_gamma();
4343 test_multiframegif();
4344 test_rotateflip();
4345 test_remaptable();
4346 test_colorkey();
4347 test_dispose();
4349 GdiplusShutdown(gdiplusToken);