gdiplus: Add a test for image stream refcount.
[wine] / dlls / gdiplus / tests / image.c
1 /*
2  * Unit test suite for images
3  *
4  * Copyright (C) 2007 Google (Evan Stade)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define COBJMACROS
22
23 #include <math.h>
24
25 #include "initguid.h"
26 #include "windows.h"
27 #include "gdiplus.h"
28 #include "wine/test.h"
29
30 #define expect(expected, got) ok((got) == (expected), "Expected %d, got %d\n", (UINT)(expected), (UINT)(got))
31 #define expectf(expected, got) ok(fabs((expected) - (got)) < 0.0001, "Expected %f, got %f\n", (expected), (got))
32
33 static BOOL color_match(ARGB c1, ARGB c2, BYTE max_diff)
34 {
35     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
36     c1 >>= 8; c2 >>= 8;
37     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
38     c1 >>= 8; c2 >>= 8;
39     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
40     c1 >>= 8; c2 >>= 8;
41     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
42     return TRUE;
43 }
44
45 static void expect_guid(REFGUID expected, REFGUID got, int line, BOOL todo)
46 {
47     WCHAR bufferW[39];
48     char buffer[39];
49     char buffer2[39];
50
51     StringFromGUID2(got, bufferW, sizeof(bufferW)/sizeof(bufferW[0]));
52     WideCharToMultiByte(CP_ACP, 0, bufferW, sizeof(bufferW)/sizeof(bufferW[0]), buffer, sizeof(buffer), NULL, NULL);
53     StringFromGUID2(expected, bufferW, sizeof(bufferW)/sizeof(bufferW[0]));
54     WideCharToMultiByte(CP_ACP, 0, bufferW, sizeof(bufferW)/sizeof(bufferW[0]), buffer2, sizeof(buffer2), NULL, NULL);
55     if(todo)
56         todo_wine ok_(__FILE__, line)(IsEqualGUID(expected, got), "Expected %s, got %s\n", buffer2, buffer);
57     else
58         ok_(__FILE__, line)(IsEqualGUID(expected, got), "Expected %s, got %s\n", buffer2, buffer);
59 }
60
61 static void expect_rawformat(REFGUID expected, GpImage *img, int line, BOOL todo)
62 {
63     GUID raw;
64     GpStatus stat;
65
66     stat = GdipGetImageRawFormat(img, &raw);
67     ok_(__FILE__, line)(stat == Ok, "GdipGetImageRawFormat failed with %d\n", stat);
68     if(stat != Ok) return;
69     expect_guid(expected, &raw, line, todo);
70 }
71
72 static void test_bufferrawformat(void* buff, int size, REFGUID expected, int line, BOOL todo)
73 {
74     LPSTREAM stream;
75     HGLOBAL  hglob;
76     LPBYTE   data;
77     HRESULT  hres;
78     GpStatus stat;
79     GpImage *img;
80
81     hglob = GlobalAlloc (0, size);
82     data = GlobalLock (hglob);
83     memcpy(data, buff, size);
84     GlobalUnlock(hglob); data = NULL;
85
86     hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
87     ok_(__FILE__, line)(hres == S_OK, "Failed to create a stream\n");
88     if(hres != S_OK) return;
89
90     stat = GdipLoadImageFromStream(stream, &img);
91     ok_(__FILE__, line)(stat == Ok, "Failed to create a Bitmap\n");
92     if(stat != Ok){
93         IStream_Release(stream);
94         return;
95     }
96
97     expect_rawformat(expected, img, line, todo);
98
99     GdipDisposeImage(img);
100     IStream_Release(stream);
101 }
102
103 static void test_Scan0(void)
104 {
105     GpBitmap *bm;
106     GpStatus stat;
107     BYTE buff[360];
108
109     bm = NULL;
110     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, NULL, &bm);
111     expect(Ok, stat);
112     ok(NULL != bm, "Expected bitmap to be initialized\n");
113     if (stat == Ok)
114         GdipDisposeImage((GpImage*)bm);
115
116     bm = (GpBitmap*)0xdeadbeef;
117     stat = GdipCreateBitmapFromScan0(10, -10, 10, PixelFormat24bppRGB, NULL, &bm);
118     expect(InvalidParameter, stat);
119     ok( !bm, "expected null bitmap\n" );
120
121     bm = (GpBitmap*)0xdeadbeef;
122     stat = GdipCreateBitmapFromScan0(-10, 10, 10, PixelFormat24bppRGB, NULL, &bm);
123     expect(InvalidParameter, stat);
124     ok( !bm, "expected null bitmap\n" );
125
126     bm = (GpBitmap*)0xdeadbeef;
127     stat = GdipCreateBitmapFromScan0(10, 0, 10, PixelFormat24bppRGB, NULL, &bm);
128     expect(InvalidParameter, stat);
129     ok( !bm, "expected null bitmap\n" );
130
131     bm = NULL;
132     stat = GdipCreateBitmapFromScan0(10, 10, 12, PixelFormat24bppRGB, buff, &bm);
133     expect(Ok, stat);
134     ok(NULL != bm, "Expected bitmap to be initialized\n");
135     if (stat == Ok)
136         GdipDisposeImage((GpImage*)bm);
137
138     bm = (GpBitmap*) 0xdeadbeef;
139     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, buff, &bm);
140     expect(InvalidParameter, stat);
141     ok( !bm, "expected null bitmap\n" );
142
143     bm = (GpBitmap*)0xdeadbeef;
144     stat = GdipCreateBitmapFromScan0(10, 10, 0, PixelFormat24bppRGB, buff, &bm);
145     expect(InvalidParameter, stat);
146     ok( bm == (GpBitmap*)0xdeadbeef, "expected deadbeef bitmap\n" );
147
148     bm = NULL;
149     stat = GdipCreateBitmapFromScan0(10, 10, -8, PixelFormat24bppRGB, buff, &bm);
150     expect(Ok, stat);
151     ok(NULL != bm, "Expected bitmap to be initialized\n");
152     if (stat == Ok)
153         GdipDisposeImage((GpImage*)bm);
154
155     bm = (GpBitmap*)0xdeadbeef;
156     stat = GdipCreateBitmapFromScan0(10, 10, -10, PixelFormat24bppRGB, buff, &bm);
157     expect(InvalidParameter, stat);
158     ok( !bm, "expected null bitmap\n" );
159 }
160
161 static void test_FromGdiDib(void)
162 {
163     GpBitmap *bm;
164     GpStatus stat;
165     BYTE buff[400];
166     BYTE rbmi[sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)];
167     BITMAPINFO *bmi = (BITMAPINFO*)rbmi;
168     PixelFormat format;
169
170     bm = NULL;
171
172     memset(rbmi, 0, sizeof(rbmi));
173
174     bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
175     bmi->bmiHeader.biWidth = 10;
176     bmi->bmiHeader.biHeight = 10;
177     bmi->bmiHeader.biPlanes = 1;
178     bmi->bmiHeader.biBitCount = 32;
179     bmi->bmiHeader.biCompression = BI_RGB;
180
181     stat = GdipCreateBitmapFromGdiDib(NULL, buff, &bm);
182     expect(InvalidParameter, stat);
183
184     stat = GdipCreateBitmapFromGdiDib(bmi, NULL, &bm);
185     expect(InvalidParameter, stat);
186
187     stat = GdipCreateBitmapFromGdiDib(bmi, buff, NULL);
188     expect(InvalidParameter, stat);
189
190     stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
191     expect(Ok, stat);
192     ok(NULL != bm, "Expected bitmap to be initialized\n");
193     if (stat == Ok)
194     {
195         stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
196         expect(Ok, stat);
197         expect(PixelFormat32bppRGB, format);
198
199         GdipDisposeImage((GpImage*)bm);
200     }
201
202     bmi->bmiHeader.biBitCount = 24;
203     stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
204     expect(Ok, stat);
205     ok(NULL != bm, "Expected bitmap to be initialized\n");
206     if (stat == Ok)
207     {
208         stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
209         expect(Ok, stat);
210         expect(PixelFormat24bppRGB, format);
211
212         GdipDisposeImage((GpImage*)bm);
213     }
214
215     bmi->bmiHeader.biBitCount = 16;
216     stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
217     expect(Ok, stat);
218     ok(NULL != bm, "Expected bitmap to be initialized\n");
219     if (stat == Ok)
220     {
221         stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
222         expect(Ok, stat);
223         expect(PixelFormat16bppRGB555, format);
224
225         GdipDisposeImage((GpImage*)bm);
226     }
227
228     bmi->bmiHeader.biBitCount = 8;
229     stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
230     expect(Ok, stat);
231     ok(NULL != bm, "Expected bitmap to be initialized\n");
232     if (stat == Ok)
233     {
234         stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
235         expect(Ok, stat);
236         expect(PixelFormat8bppIndexed, format);
237
238         GdipDisposeImage((GpImage*)bm);
239     }
240
241     bmi->bmiHeader.biBitCount = 4;
242     stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
243     expect(Ok, stat);
244     ok(NULL != bm, "Expected bitmap to be initialized\n");
245     if (stat == Ok)
246     {
247         stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
248         expect(Ok, stat);
249         expect(PixelFormat4bppIndexed, format);
250
251         GdipDisposeImage((GpImage*)bm);
252     }
253
254     bmi->bmiHeader.biBitCount = 1;
255     stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
256     expect(Ok, stat);
257     ok(NULL != bm, "Expected bitmap to be initialized\n");
258     if (stat == Ok)
259     {
260         stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
261         expect(Ok, stat);
262         expect(PixelFormat1bppIndexed, format);
263
264         GdipDisposeImage((GpImage*)bm);
265     }
266
267     bmi->bmiHeader.biBitCount = 0;
268     stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
269     expect(InvalidParameter, stat);
270 }
271
272 static void test_GetImageDimension(void)
273 {
274     GpBitmap *bm;
275     GpStatus stat;
276     const REAL WIDTH = 10.0, HEIGHT = 20.0;
277     REAL w,h;
278
279     bm = (GpBitmap*)0xdeadbeef;
280     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB,NULL, &bm);
281     expect(Ok,stat);
282     ok((GpBitmap*)0xdeadbeef != bm, "Expected bitmap to not be 0xdeadbeef\n");
283     ok(NULL != bm, "Expected bitmap to not be NULL\n");
284
285     stat = GdipGetImageDimension(NULL,&w,&h);
286     expect(InvalidParameter, stat);
287
288     stat = GdipGetImageDimension((GpImage*)bm,NULL,&h);
289     expect(InvalidParameter, stat);
290
291     stat = GdipGetImageDimension((GpImage*)bm,&w,NULL);
292     expect(InvalidParameter, stat);
293
294     w = -1;
295     h = -1;
296     stat = GdipGetImageDimension((GpImage*)bm,&w,&h);
297     expect(Ok, stat);
298     expectf(WIDTH,  w);
299     expectf(HEIGHT, h);
300     GdipDisposeImage((GpImage*)bm);
301 }
302
303 static void test_GdipImageGetFrameDimensionsCount(void)
304 {
305     GpBitmap *bm;
306     GpStatus stat;
307     const REAL WIDTH = 10.0, HEIGHT = 20.0;
308     UINT w;
309     GUID dimension = {0};
310     UINT count;
311     ARGB color;
312
313     bm = (GpBitmap*)0xdeadbeef;
314     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB,NULL, &bm);
315     expect(Ok,stat);
316     ok((GpBitmap*)0xdeadbeef != bm, "Expected bitmap to not be 0xdeadbeef\n");
317     ok(NULL != bm, "Expected bitmap to not be NULL\n");
318
319     stat = GdipImageGetFrameDimensionsCount(NULL,&w);
320     expect(InvalidParameter, stat);
321
322     stat = GdipImageGetFrameDimensionsCount((GpImage*)bm,NULL);
323     expect(InvalidParameter, stat);
324
325     w = -1;
326     stat = GdipImageGetFrameDimensionsCount((GpImage*)bm,&w);
327     expect(Ok, stat);
328     expect(1, w);
329
330     stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 1);
331     expect(Ok, stat);
332     expect_guid(&FrameDimensionPage, &dimension, __LINE__, FALSE);
333
334     stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 2);
335     expect(InvalidParameter, stat);
336
337     stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 0);
338     expect(InvalidParameter, stat);
339
340     stat = GdipImageGetFrameCount(NULL, &dimension, &count);
341     expect(InvalidParameter, stat);
342
343     /* WinXP crashes on this test */
344     if(0)
345     {
346         stat = GdipImageGetFrameCount((GpImage*)bm, &dimension, NULL);
347         expect(InvalidParameter, stat);
348     }
349
350     stat = GdipImageGetFrameCount((GpImage*)bm, NULL, &count);
351     expect(Ok, stat);
352
353     count = 12345;
354     stat = GdipImageGetFrameCount((GpImage*)bm, &dimension, &count);
355     expect(Ok, stat);
356     expect(1, count);
357
358     GdipBitmapSetPixel(bm, 0, 0, 0xffffffff);
359
360     stat = GdipImageSelectActiveFrame((GpImage*)bm, &dimension, 0);
361     expect(Ok, stat);
362
363     /* SelectActiveFrame has no effect on image data of memory bitmaps */
364     color = 0xdeadbeef;
365     GdipBitmapGetPixel(bm, 0, 0, &color);
366     expect(0xffffffff, color);
367
368     GdipDisposeImage((GpImage*)bm);
369 }
370
371 static void test_LoadingImages(void)
372 {
373     GpStatus stat;
374
375     stat = GdipCreateBitmapFromFile(0, 0);
376     expect(InvalidParameter, stat);
377
378     stat = GdipCreateBitmapFromFile(0, (GpBitmap**)0xdeadbeef);
379     expect(InvalidParameter, stat);
380
381     stat = GdipLoadImageFromFile(0, 0);
382     expect(InvalidParameter, stat);
383
384     stat = GdipLoadImageFromFile(0, (GpImage**)0xdeadbeef);
385     expect(InvalidParameter, stat);
386
387     stat = GdipLoadImageFromFileICM(0, 0);
388     expect(InvalidParameter, stat);
389
390     stat = GdipLoadImageFromFileICM(0, (GpImage**)0xdeadbeef);
391     expect(InvalidParameter, stat);
392 }
393
394 static void test_SavingImages(void)
395 {
396     GpStatus stat;
397     GpBitmap *bm;
398     UINT n;
399     UINT s;
400     const REAL WIDTH = 10.0, HEIGHT = 20.0;
401     REAL w, h;
402     ImageCodecInfo *codecs;
403     static const CHAR filenameA[] = "a.bmp";
404     static const WCHAR filename[] = { 'a','.','b','m','p',0 };
405
406     codecs = NULL;
407
408     stat = GdipSaveImageToFile(0, 0, 0, 0);
409     expect(InvalidParameter, stat);
410
411     bm = NULL;
412     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
413     expect(Ok, stat);
414     if (!bm)
415         return;
416
417     /* invalid params */
418     stat = GdipSaveImageToFile((GpImage*)bm, 0, 0, 0);
419     expect(InvalidParameter, stat);
420
421     stat = GdipSaveImageToFile((GpImage*)bm, filename, 0, 0);
422     expect(InvalidParameter, stat);
423
424     /* encoder tests should succeed -- already tested */
425     stat = GdipGetImageEncodersSize(&n, &s);
426     if (stat != Ok || n == 0) goto cleanup;
427
428     codecs = GdipAlloc(s);
429     if (!codecs) goto cleanup;
430
431     stat = GdipGetImageEncoders(n, s, codecs);
432     if (stat != Ok) goto cleanup;
433
434     stat = GdipSaveImageToFile((GpImage*)bm, filename, &codecs[0].Clsid, 0);
435     expect(Ok, stat);
436
437     GdipDisposeImage((GpImage*)bm);
438     bm = 0;
439
440     /* re-load and check image stats */
441     stat = GdipLoadImageFromFile(filename, (GpImage**)&bm);
442     expect(Ok, stat);
443     if (stat != Ok) goto cleanup;
444
445     stat = GdipGetImageDimension((GpImage*)bm, &w, &h);
446     if (stat != Ok) goto cleanup;
447
448     expectf(WIDTH, w);
449     expectf(HEIGHT, h);
450
451  cleanup:
452     GdipFree(codecs);
453     if (bm)
454         GdipDisposeImage((GpImage*)bm);
455     ok(DeleteFileA(filenameA), "Delete failed.\n");
456 }
457
458 static void test_encoders(void)
459 {
460     GpStatus stat;
461     UINT n;
462     UINT s;
463     ImageCodecInfo *codecs;
464     int i;
465     int bmp_found;
466
467     static const CHAR bmp_format[] = "BMP";
468
469     stat = GdipGetImageEncodersSize(&n, &s);
470     expect(stat, Ok);
471
472     codecs = GdipAlloc(s);
473     if (!codecs)
474         return;
475
476     stat = GdipGetImageEncoders(n, s, NULL);
477     expect(GenericError, stat);
478
479     stat = GdipGetImageEncoders(0, s, codecs);
480     expect(GenericError, stat);
481
482     stat = GdipGetImageEncoders(n, s-1, codecs);
483     expect(GenericError, stat);
484
485     stat = GdipGetImageEncoders(n, s+1, codecs);
486     expect(GenericError, stat);
487
488     stat = GdipGetImageEncoders(n, s, codecs);
489     expect(stat, Ok);
490
491     bmp_found = FALSE;
492     for (i = 0; i < n; i++)
493         {
494             CHAR desc[32];
495
496             WideCharToMultiByte(CP_ACP, 0, codecs[i].FormatDescription, -1,
497                                 desc, 32, 0, 0);
498
499             if (CompareStringA(LOCALE_SYSTEM_DEFAULT, 0,
500                                desc, -1,
501                                bmp_format, -1) == CSTR_EQUAL) {
502                 bmp_found = TRUE;
503                 break;
504             }
505         }
506     if (!bmp_found)
507         ok(FALSE, "No BMP codec found.\n");
508
509     GdipFree(codecs);
510 }
511
512 static void test_LockBits(void)
513 {
514     GpStatus stat;
515     GpBitmap *bm;
516     GpRect rect;
517     BitmapData bd;
518     const INT WIDTH = 10, HEIGHT = 20;
519     ARGB color;
520     int y;
521
522     bm = NULL;
523     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
524     expect(Ok, stat);
525
526     rect.X = 2;
527     rect.Y = 3;
528     rect.Width = 4;
529     rect.Height = 5;
530
531     stat = GdipBitmapSetPixel(bm, 2, 3, 0xffc30000);
532     expect(Ok, stat);
533
534     stat = GdipBitmapSetPixel(bm, 2, 8, 0xff480000);
535     expect(Ok, stat);
536
537     /* read-only */
538     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
539     expect(Ok, stat);
540
541     if (stat == Ok) {
542         expect(0xc3, ((BYTE*)bd.Scan0)[2]);
543         expect(0x48, ((BYTE*)bd.Scan0)[2 + bd.Stride * 5]);
544
545         ((char*)bd.Scan0)[2] = 0xff;
546
547         stat = GdipBitmapUnlockBits(bm, &bd);
548         expect(Ok, stat);
549     }
550
551     stat = GdipBitmapGetPixel(bm, 2, 3, &color);
552     expect(Ok, stat);
553     expect(0xffff0000, color);
554
555     stat = GdipBitmapSetPixel(bm, 2, 3, 0xffc30000);
556     expect(Ok, stat);
557
558     /* read-only, with NULL rect -> whole bitmap lock */
559     stat = GdipBitmapLockBits(bm, NULL, ImageLockModeRead, PixelFormat24bppRGB, &bd);
560     expect(Ok, stat);
561     expect(bd.Width,  WIDTH);
562     expect(bd.Height, HEIGHT);
563
564     if (stat == Ok) {
565         ((char*)bd.Scan0)[2 + 2*3 + 3*bd.Stride] = 0xff;
566
567         stat = GdipBitmapUnlockBits(bm, &bd);
568         expect(Ok, stat);
569     }
570
571     stat = GdipBitmapGetPixel(bm, 2, 3, &color);
572     expect(Ok, stat);
573     expect(0xffff0000, color);
574
575     /* read-only, consecutive */
576     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
577     expect(Ok, stat);
578
579     if (stat == Ok) {
580         stat = GdipBitmapUnlockBits(bm, &bd);
581         expect(Ok, stat);
582     }
583
584     stat = GdipDisposeImage((GpImage*)bm);
585     expect(Ok, stat);
586     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
587     expect(Ok, stat);
588
589     /* read x2 */
590     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
591     expect(Ok, stat);
592     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
593     expect(WrongState, stat);
594
595     stat = GdipBitmapUnlockBits(bm, &bd);
596     expect(Ok, stat);
597
598     stat = GdipDisposeImage((GpImage*)bm);
599     expect(Ok, stat);
600     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
601     expect(Ok, stat);
602
603     stat = GdipBitmapSetPixel(bm, 2, 3, 0xffff0000);
604     expect(Ok, stat);
605
606     stat = GdipBitmapSetPixel(bm, 2, 8, 0xffc30000);
607     expect(Ok, stat);
608
609     /* write, no conversion */
610     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
611     expect(Ok, stat);
612
613     if (stat == Ok) {
614         /* all bits are readable, inside the rect or not */
615         expect(0xff, ((BYTE*)bd.Scan0)[2]);
616         expect(0xc3, ((BYTE*)bd.Scan0)[2 + bd.Stride * 5]);
617
618         stat = GdipBitmapUnlockBits(bm, &bd);
619         expect(Ok, stat);
620     }
621
622     /* read, conversion */
623     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat32bppARGB, &bd);
624     expect(Ok, stat);
625
626     if (stat == Ok) {
627         expect(0xff, ((BYTE*)bd.Scan0)[2]);
628         if (0)
629             /* Areas outside the rectangle appear to be uninitialized */
630             ok(0xc3 != ((BYTE*)bd.Scan0)[2 + bd.Stride * 5], "original image bits are readable\n");
631
632         ((BYTE*)bd.Scan0)[2] = 0xc3;
633
634         stat = GdipBitmapUnlockBits(bm, &bd);
635         expect(Ok, stat);
636     }
637
638     /* writes do not work in read mode if there was a conversion */
639     stat = GdipBitmapGetPixel(bm, 2, 3, &color);
640     expect(Ok, stat);
641     expect(0xffff0000, color);
642
643     /* read/write, conversion */
644     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead|ImageLockModeWrite, PixelFormat32bppARGB, &bd);
645     expect(Ok, stat);
646
647     if (stat == Ok) {
648         expect(0xff, ((BYTE*)bd.Scan0)[2]);
649         ((BYTE*)bd.Scan0)[1] = 0x88;
650         if (0)
651             /* Areas outside the rectangle appear to be uninitialized */
652             ok(0xc3 != ((BYTE*)bd.Scan0)[2 + bd.Stride * 5], "original image bits are readable\n");
653
654         stat = GdipBitmapUnlockBits(bm, &bd);
655         expect(Ok, stat);
656     }
657
658     stat = GdipBitmapGetPixel(bm, 2, 3, &color);
659     expect(Ok, stat);
660     expect(0xffff8800, color);
661
662     /* write, conversion */
663     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat32bppARGB, &bd);
664     expect(Ok, stat);
665
666     if (stat == Ok) {
667         if (0)
668         {
669             /* This is completely uninitialized. */
670             ok(0xff != ((BYTE*)bd.Scan0)[2], "original image bits are readable\n");
671             ok(0xc3 != ((BYTE*)bd.Scan0)[2 + bd.Stride * 5], "original image bits are readable\n");
672         }
673
674         /* Initialize the buffer so the unlock doesn't access undefined memory */
675         for (y=0; y<5; y++)
676             memset(((BYTE*)bd.Scan0) + bd.Stride * y, 0, 12);
677
678         ((BYTE*)bd.Scan0)[0] = 0x12;
679         ((BYTE*)bd.Scan0)[1] = 0x34;
680         ((BYTE*)bd.Scan0)[2] = 0x56;
681
682         stat = GdipBitmapUnlockBits(bm, &bd);
683         expect(Ok, stat);
684     }
685
686     stat = GdipBitmapGetPixel(bm, 2, 3, &color);
687     expect(Ok, stat);
688     expect(0xff563412, color);
689
690     stat = GdipBitmapGetPixel(bm, 2, 8, &color);
691     expect(Ok, stat);
692     expect(0xffc30000, color);
693
694     stat = GdipDisposeImage((GpImage*)bm);
695     expect(Ok, stat);
696     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
697     expect(Ok, stat);
698
699     /* write, no modification */
700     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
701     expect(Ok, stat);
702
703     if (stat == Ok) {
704         stat = GdipBitmapUnlockBits(bm, &bd);
705         expect(Ok, stat);
706     }
707
708     /* write, consecutive */
709     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
710     expect(Ok, stat);
711
712     if (stat == Ok) {
713         stat = GdipBitmapUnlockBits(bm, &bd);
714         expect(Ok, stat);
715     }
716
717     stat = GdipDisposeImage((GpImage*)bm);
718     expect(Ok, stat);
719     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
720     expect(Ok, stat);
721
722     /* write, modify */
723     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
724     expect(Ok, stat);
725
726     if (stat == Ok) {
727         if (bd.Scan0)
728             ((char*)bd.Scan0)[2] = 0xff;
729
730         stat = GdipBitmapUnlockBits(bm, &bd);
731         expect(Ok, stat);
732     }
733
734     stat = GdipBitmapGetPixel(bm, 2, 3, &color);
735     expect(Ok, stat);
736     expect(0xffff0000, color);
737
738     stat = GdipDisposeImage((GpImage*)bm);
739     expect(Ok, stat);
740
741     /* dispose locked */
742     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
743     expect(Ok, stat);
744     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
745     expect(Ok, stat);
746     stat = GdipDisposeImage((GpImage*)bm);
747     expect(Ok, stat);
748 }
749
750 static void test_LockBits_UserBuf(void)
751 {
752     GpStatus stat;
753     GpBitmap *bm;
754     GpRect rect;
755     BitmapData bd;
756     const INT WIDTH = 10, HEIGHT = 20;
757     DWORD bits[200];
758     ARGB color;
759
760     bm = NULL;
761     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat32bppARGB, NULL, &bm);
762     expect(Ok, stat);
763
764     memset(bits, 0xaa, sizeof(bits));
765
766     rect.X = 2;
767     rect.Y = 3;
768     rect.Width = 4;
769     rect.Height = 5;
770
771     bd.Width = 4;
772     bd.Height = 6;
773     bd.Stride = WIDTH * 4;
774     bd.PixelFormat = PixelFormat32bppARGB;
775     bd.Scan0 = &bits[2+3*WIDTH];
776     bd.Reserved = 0xaaaaaaaa;
777
778     /* read-only */
779     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead|ImageLockModeUserInputBuf, PixelFormat32bppARGB, &bd);
780     expect(Ok, stat);
781
782     expect(0xaaaaaaaa, bits[0]);
783     expect(0, bits[2+3*WIDTH]);
784
785     bits[2+3*WIDTH] = 0xdeadbeef;
786
787     if (stat == Ok) {
788         stat = GdipBitmapUnlockBits(bm, &bd);
789         expect(Ok, stat);
790     }
791
792     stat = GdipBitmapGetPixel(bm, 2, 3, &color);
793     expect(Ok, stat);
794     expect(0, color);
795
796     /* write-only */
797     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite|ImageLockModeUserInputBuf, PixelFormat32bppARGB, &bd);
798     expect(Ok, stat);
799
800     expect(0xdeadbeef, bits[2+3*WIDTH]);
801     bits[2+3*WIDTH] = 0x12345678;
802
803     if (stat == Ok) {
804         stat = GdipBitmapUnlockBits(bm, &bd);
805         expect(Ok, stat);
806     }
807
808     stat = GdipBitmapGetPixel(bm, 2, 3, &color);
809     expect(Ok, stat);
810     expect(0x12345678, color);
811
812     bits[2+3*WIDTH] = 0;
813
814     /* read/write */
815     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead|ImageLockModeWrite|ImageLockModeUserInputBuf, PixelFormat32bppARGB, &bd);
816     expect(Ok, stat);
817
818     expect(0x12345678, bits[2+3*WIDTH]);
819     bits[2+3*WIDTH] = 0xdeadbeef;
820
821     if (stat == Ok) {
822         stat = GdipBitmapUnlockBits(bm, &bd);
823         expect(Ok, stat);
824     }
825
826     stat = GdipBitmapGetPixel(bm, 2, 3, &color);
827     expect(Ok, stat);
828     expect(0xdeadbeef, color);
829
830     stat = GdipDisposeImage((GpImage*)bm);
831     expect(Ok, stat);
832 }
833
834 struct BITMAPINFOWITHBITFIELDS
835 {
836     BITMAPINFOHEADER bmiHeader;
837     DWORD masks[3];
838 };
839
840 union BITMAPINFOUNION
841 {
842     BITMAPINFO bi;
843     struct BITMAPINFOWITHBITFIELDS bf;
844 };
845
846 static void test_GdipCreateBitmapFromHBITMAP(void)
847 {
848     GpBitmap* gpbm = NULL;
849     HBITMAP hbm = NULL;
850     HPALETTE hpal = NULL;
851     GpStatus stat;
852     BYTE buff[1000];
853     LOGPALETTE* LogPal = NULL;
854     REAL width, height;
855     const REAL WIDTH1 = 5;
856     const REAL HEIGHT1 = 15;
857     const REAL WIDTH2 = 10;
858     const REAL HEIGHT2 = 20;
859     HDC hdc;
860     union BITMAPINFOUNION bmi;
861     BYTE *bits;
862     PixelFormat format;
863
864     stat = GdipCreateBitmapFromHBITMAP(NULL, NULL, NULL);
865     expect(InvalidParameter, stat);
866
867     hbm = CreateBitmap(WIDTH1, HEIGHT1, 1, 1, NULL);
868     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, NULL);
869     expect(InvalidParameter, stat);
870
871     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
872     expect(Ok, stat);
873     expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
874     expectf(WIDTH1,  width);
875     expectf(HEIGHT1, height);
876     if (stat == Ok)
877         GdipDisposeImage((GpImage*)gpbm);
878     DeleteObject(hbm);
879
880     memset(buff, 0, sizeof(buff));
881     hbm = CreateBitmap(WIDTH2, HEIGHT2, 1, 1, &buff);
882     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
883     expect(Ok, stat);
884     /* raw format */
885     expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)gpbm, __LINE__, FALSE);
886
887     expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
888     expectf(WIDTH2,  width);
889     expectf(HEIGHT2, height);
890     if (stat == Ok)
891         GdipDisposeImage((GpImage*)gpbm);
892     DeleteObject(hbm);
893
894     hdc = CreateCompatibleDC(0);
895     ok(hdc != NULL, "CreateCompatibleDC failed\n");
896     bmi.bi.bmiHeader.biSize = sizeof(bmi.bi.bmiHeader);
897     bmi.bi.bmiHeader.biHeight = HEIGHT1;
898     bmi.bi.bmiHeader.biWidth = WIDTH1;
899     bmi.bi.bmiHeader.biBitCount = 24;
900     bmi.bi.bmiHeader.biPlanes = 1;
901     bmi.bi.bmiHeader.biCompression = BI_RGB;
902     bmi.bi.bmiHeader.biClrUsed = 0;
903
904     hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
905     ok(hbm != NULL, "CreateDIBSection failed\n");
906
907     bits[0] = 0;
908
909     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
910     expect(Ok, stat);
911     expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
912     expectf(WIDTH1,  width);
913     expectf(HEIGHT1, height);
914     if (stat == Ok)
915     {
916         /* test whether writing to the bitmap affects the original */
917         stat = GdipBitmapSetPixel(gpbm, 0, 0, 0xffffffff);
918         expect(Ok, stat);
919
920         expect(0, bits[0]);
921
922         GdipDisposeImage((GpImage*)gpbm);
923     }
924
925     LogPal = GdipAlloc(sizeof(LOGPALETTE));
926     ok(LogPal != NULL, "unable to allocate LOGPALETTE\n");
927     LogPal->palVersion = 0x300;
928     LogPal->palNumEntries = 1;
929     hpal = CreatePalette(LogPal);
930     ok(hpal != NULL, "CreatePalette failed\n");
931     GdipFree(LogPal);
932
933     stat = GdipCreateBitmapFromHBITMAP(hbm, hpal, &gpbm);
934     expect(Ok, stat);
935
936     if (stat == Ok)
937         GdipDisposeImage((GpImage*)gpbm);
938
939     DeleteObject(hpal);
940     DeleteObject(hbm);
941
942     /* 16-bit 555 dib, rgb */
943     bmi.bi.bmiHeader.biBitCount = 16;
944     bmi.bi.bmiHeader.biCompression = BI_RGB;
945
946     hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
947     ok(hbm != NULL, "CreateDIBSection failed\n");
948
949     bits[0] = 0;
950
951     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
952     expect(Ok, stat);
953
954     if (stat == Ok)
955     {
956         stat = GdipGetImageDimension((GpImage*) gpbm, &width, &height);
957         expect(Ok, stat);
958         expectf(WIDTH1,  width);
959         expectf(HEIGHT1, height);
960
961         stat = GdipGetImagePixelFormat((GpImage*) gpbm, &format);
962         expect(Ok, stat);
963         expect(PixelFormat16bppRGB555, format);
964
965         GdipDisposeImage((GpImage*)gpbm);
966     }
967     DeleteObject(hbm);
968
969     /* 16-bit 555 dib, with bitfields */
970     bmi.bi.bmiHeader.biSize = sizeof(bmi);
971     bmi.bi.bmiHeader.biCompression = BI_BITFIELDS;
972     bmi.bf.masks[0] = 0x7c00;
973     bmi.bf.masks[1] = 0x3e0;
974     bmi.bf.masks[2] = 0x1f;
975
976     hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
977     ok(hbm != NULL, "CreateDIBSection failed\n");
978
979     bits[0] = 0;
980
981     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
982     expect(Ok, stat);
983
984     if (stat == Ok)
985     {
986         stat = GdipGetImageDimension((GpImage*) gpbm, &width, &height);
987         expect(Ok, stat);
988         expectf(WIDTH1,  width);
989         expectf(HEIGHT1, height);
990
991         stat = GdipGetImagePixelFormat((GpImage*) gpbm, &format);
992         expect(Ok, stat);
993         expect(PixelFormat16bppRGB555, format);
994
995         GdipDisposeImage((GpImage*)gpbm);
996     }
997     DeleteObject(hbm);
998
999     /* 16-bit 565 dib, with bitfields */
1000     bmi.bf.masks[0] = 0xf800;
1001     bmi.bf.masks[1] = 0x7e0;
1002     bmi.bf.masks[2] = 0x1f;
1003
1004     hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1005     ok(hbm != NULL, "CreateDIBSection failed\n");
1006
1007     bits[0] = 0;
1008
1009     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
1010     expect(Ok, stat);
1011
1012     if (stat == Ok)
1013     {
1014         stat = GdipGetImageDimension((GpImage*) gpbm, &width, &height);
1015         expect(Ok, stat);
1016         expectf(WIDTH1,  width);
1017         expectf(HEIGHT1, height);
1018
1019         stat = GdipGetImagePixelFormat((GpImage*) gpbm, &format);
1020         expect(Ok, stat);
1021         expect(PixelFormat16bppRGB565, format);
1022
1023         GdipDisposeImage((GpImage*)gpbm);
1024     }
1025     DeleteObject(hbm);
1026
1027     DeleteDC(hdc);
1028 }
1029
1030 static void test_GdipGetImageFlags(void)
1031 {
1032     GpImage *img;
1033     GpStatus stat;
1034     UINT flags;
1035
1036     img = (GpImage*)0xdeadbeef;
1037
1038     stat = GdipGetImageFlags(NULL, NULL);
1039     expect(InvalidParameter, stat);
1040
1041     stat = GdipGetImageFlags(NULL, &flags);
1042     expect(InvalidParameter, stat);
1043
1044     stat = GdipGetImageFlags(img, NULL);
1045     expect(InvalidParameter, stat);
1046
1047     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat1bppIndexed, NULL, (GpBitmap**)&img);
1048     expect(Ok, stat);
1049     stat = GdipGetImageFlags(img, &flags);
1050     expect(Ok, stat);
1051     expect(ImageFlagsHasAlpha, flags);
1052     GdipDisposeImage(img);
1053
1054     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat4bppIndexed, NULL, (GpBitmap**)&img);
1055     expect(Ok, stat);
1056     stat = GdipGetImageFlags(img, &flags);
1057     expect(Ok, stat);
1058     expect(ImageFlagsHasAlpha, flags);
1059     GdipDisposeImage(img);
1060
1061     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat8bppIndexed, NULL, (GpBitmap**)&img);
1062     expect(Ok, stat);
1063     stat = GdipGetImageFlags(img, &flags);
1064     expect(Ok, stat);
1065     expect(ImageFlagsHasAlpha, flags);
1066     GdipDisposeImage(img);
1067
1068     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppGrayScale, NULL, (GpBitmap**)&img);
1069     expect(Ok, stat);
1070     stat = GdipGetImageFlags(img, &flags);
1071     expect(Ok, stat);
1072     expect(ImageFlagsNone, flags);
1073     GdipDisposeImage(img);
1074
1075     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB555, NULL, (GpBitmap**)&img);
1076     expect(Ok, stat);
1077     stat = GdipGetImageFlags(img, &flags);
1078     expect(Ok, stat);
1079     expect(ImageFlagsNone, flags);
1080     GdipDisposeImage(img);
1081
1082     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB565, NULL, (GpBitmap**)&img);
1083     expect(Ok, stat);
1084     stat = GdipGetImageFlags(img, &flags);
1085     expect(Ok, stat);
1086     expect(ImageFlagsNone, flags);
1087     GdipDisposeImage(img);
1088
1089     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppARGB1555, NULL, (GpBitmap**)&img);
1090     expect(Ok, stat);
1091     stat = GdipGetImageFlags(img, &flags);
1092     expect(Ok, stat);
1093     expect(ImageFlagsHasAlpha, flags);
1094     GdipDisposeImage(img);
1095
1096     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, NULL, (GpBitmap**)&img);
1097     expect(Ok, stat);
1098     stat = GdipGetImageFlags(img, &flags);
1099     expect(Ok, stat);
1100     expect(ImageFlagsNone, flags);
1101     GdipDisposeImage(img);
1102
1103     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppRGB, NULL, (GpBitmap**)&img);
1104     expect(Ok, stat);
1105     stat = GdipGetImageFlags(img, &flags);
1106     expect(Ok, stat);
1107     expect(ImageFlagsNone, flags);
1108     GdipDisposeImage(img);
1109
1110     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppARGB, NULL, (GpBitmap**)&img);
1111     expect(Ok, stat);
1112     stat = GdipGetImageFlags(img, &flags);
1113     expect(Ok, stat);
1114     expect(ImageFlagsHasAlpha, flags);
1115     GdipDisposeImage(img);
1116
1117     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppPARGB, NULL, (GpBitmap**)&img);
1118     expect(Ok, stat);
1119     stat = GdipGetImageFlags(img, &flags);
1120     expect(Ok, stat);
1121     expect(ImageFlagsHasAlpha, flags);
1122     GdipDisposeImage(img);
1123
1124     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat48bppRGB, NULL, (GpBitmap**)&img);
1125     expect(Ok, stat);
1126     if (stat == Ok)
1127     {
1128         stat = GdipGetImageFlags(img, &flags);
1129         expect(Ok, stat);
1130         expect(ImageFlagsNone, flags);
1131         GdipDisposeImage(img);
1132     }
1133
1134     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB, NULL, (GpBitmap**)&img);
1135     expect(Ok, stat);
1136     if (stat == Ok)
1137     {
1138         expect(Ok, stat);
1139         stat = GdipGetImageFlags(img, &flags);
1140         expect(Ok, stat);
1141         expect(ImageFlagsHasAlpha, flags);
1142         GdipDisposeImage(img);
1143     }
1144
1145     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB, NULL, (GpBitmap**)&img);
1146     expect(Ok, stat);
1147     if (stat == Ok)
1148     {
1149         expect(Ok, stat);
1150         stat = GdipGetImageFlags(img, &flags);
1151         expect(Ok, stat);
1152         expect(ImageFlagsHasAlpha, flags);
1153         GdipDisposeImage(img);
1154     }
1155 }
1156
1157 static void test_GdipCloneImage(void)
1158 {
1159     GpStatus stat;
1160     GpRectF rectF;
1161     GpUnit unit;
1162     GpBitmap *bm;
1163     GpImage *image_src, *image_dest = NULL;
1164     const INT WIDTH = 10, HEIGHT = 20;
1165
1166     /* Create an image, clone it, delete the original, make sure the copy works */
1167     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
1168     expect(Ok, stat);
1169     expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bm, __LINE__, FALSE);
1170
1171     image_src = ((GpImage*)bm);
1172     stat = GdipCloneImage(image_src, &image_dest);
1173     expect(Ok, stat);
1174     expect_rawformat(&ImageFormatMemoryBMP, image_dest, __LINE__, FALSE);
1175
1176     stat = GdipDisposeImage((GpImage*)bm);
1177     expect(Ok, stat);
1178     stat = GdipGetImageBounds(image_dest, &rectF, &unit);
1179     expect(Ok, stat);
1180
1181     /* Treat FP values carefully */
1182     expectf((REAL)WIDTH, rectF.Width);
1183     expectf((REAL)HEIGHT, rectF.Height);
1184
1185     stat = GdipDisposeImage(image_dest);
1186     expect(Ok, stat);
1187 }
1188
1189 static void test_testcontrol(void)
1190 {
1191     GpStatus stat;
1192     DWORD param;
1193
1194     param = 0;
1195     stat = GdipTestControl(TestControlGetBuildNumber, &param);
1196     expect(Ok, stat);
1197     ok(param != 0, "Build number expected, got %u\n", param);
1198 }
1199
1200 static void test_fromhicon(void)
1201 {
1202     static const BYTE bmp_bits[1024];
1203     HBITMAP hbmMask, hbmColor;
1204     ICONINFO info;
1205     HICON hIcon;
1206     GpStatus stat;
1207     GpBitmap *bitmap = NULL;
1208     UINT dim;
1209     ImageType type;
1210     PixelFormat format;
1211
1212     /* NULL */
1213     stat = GdipCreateBitmapFromHICON(NULL, NULL);
1214     expect(InvalidParameter, stat);
1215     stat = GdipCreateBitmapFromHICON(NULL, &bitmap);
1216     expect(InvalidParameter, stat);
1217
1218     /* color icon 1 bit */
1219     hbmMask = CreateBitmap(16, 16, 1, 1, bmp_bits);
1220     ok(hbmMask != 0, "CreateBitmap failed\n");
1221     hbmColor = CreateBitmap(16, 16, 1, 1, bmp_bits);
1222     ok(hbmColor != 0, "CreateBitmap failed\n");
1223     info.fIcon = TRUE;
1224     info.xHotspot = 8;
1225     info.yHotspot = 8;
1226     info.hbmMask = hbmMask;
1227     info.hbmColor = hbmColor;
1228     hIcon = CreateIconIndirect(&info);
1229     ok(hIcon != 0, "CreateIconIndirect failed\n");
1230     DeleteObject(hbmMask);
1231     DeleteObject(hbmColor);
1232
1233     stat = GdipCreateBitmapFromHICON(hIcon, &bitmap);
1234     ok(stat == Ok ||
1235        broken(stat == InvalidParameter), /* Win98 */
1236        "Expected Ok, got %.8x\n", stat);
1237     if(stat == Ok){
1238        /* check attributes */
1239        stat = GdipGetImageHeight((GpImage*)bitmap, &dim);
1240        expect(Ok, stat);
1241        expect(16, dim);
1242        stat = GdipGetImageWidth((GpImage*)bitmap, &dim);
1243        expect(Ok, stat);
1244        expect(16, dim);
1245        stat = GdipGetImageType((GpImage*)bitmap, &type);
1246        expect(Ok, stat);
1247        expect(ImageTypeBitmap, type);
1248        stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format);
1249        expect(Ok, stat);
1250        expect(PixelFormat32bppARGB, format);
1251        /* raw format */
1252        expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
1253        GdipDisposeImage((GpImage*)bitmap);
1254     }
1255     DestroyIcon(hIcon);
1256
1257     /* color icon 8 bpp */
1258     hbmMask = CreateBitmap(16, 16, 1, 8, bmp_bits);
1259     ok(hbmMask != 0, "CreateBitmap failed\n");
1260     hbmColor = CreateBitmap(16, 16, 1, 8, bmp_bits);
1261     ok(hbmColor != 0, "CreateBitmap failed\n");
1262     info.fIcon = TRUE;
1263     info.xHotspot = 8;
1264     info.yHotspot = 8;
1265     info.hbmMask = hbmMask;
1266     info.hbmColor = hbmColor;
1267     hIcon = CreateIconIndirect(&info);
1268     ok(hIcon != 0, "CreateIconIndirect failed\n");
1269     DeleteObject(hbmMask);
1270     DeleteObject(hbmColor);
1271
1272     stat = GdipCreateBitmapFromHICON(hIcon, &bitmap);
1273     expect(Ok, stat);
1274     if(stat == Ok){
1275         /* check attributes */
1276         stat = GdipGetImageHeight((GpImage*)bitmap, &dim);
1277         expect(Ok, stat);
1278         expect(16, dim);
1279         stat = GdipGetImageWidth((GpImage*)bitmap, &dim);
1280         expect(Ok, stat);
1281         expect(16, dim);
1282         stat = GdipGetImageType((GpImage*)bitmap, &type);
1283         expect(Ok, stat);
1284         expect(ImageTypeBitmap, type);
1285         stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format);
1286         expect(Ok, stat);
1287         expect(PixelFormat32bppARGB, format);
1288         /* raw format */
1289         expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
1290         GdipDisposeImage((GpImage*)bitmap);
1291     }
1292     DestroyIcon(hIcon);
1293 }
1294
1295 /* 1x1 pixel png */
1296 static const unsigned char pngimage[285] = {
1297 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
1298 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
1299 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
1300 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
1301 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
1302 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
1303 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
1304 };
1305 /* 1x1 pixel gif */
1306 static const unsigned char gifimage[35] = {
1307 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
1308 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
1309 0x01,0x00,0x3b
1310 };
1311 /* 1x1 pixel bmp */
1312 static const unsigned char bmpimage[66] = {
1313 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
1314 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
1315 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
1316 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
1317 0x00,0x00
1318 };
1319 /* 1x1 pixel jpg */
1320 static const unsigned char jpgimage[285] = {
1321 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
1322 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
1323 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
1324 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
1325 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
1326 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
1327 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
1328 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1329 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1330 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
1331 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
1332 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1333 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
1334 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
1335 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1336 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
1337 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
1338 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
1339 };
1340 /* 1x1 pixel tiff */
1341 static const unsigned char tiffimage[] = {
1342 0x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00,
1343 0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00,
1344 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1345 0x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01,
1346 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00,
1347 0x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00,
1348 0x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01,
1349 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00,
1350 0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00,
1351 0x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01,
1352 0x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00,
1353 0x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1354 0x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
1355 0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65,
1356 0x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74,
1357 0x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,
1358 0x00,0x00,0x00,0x01
1359 };
1360 /* 320x320 twip wmf */
1361 static const unsigned char wmfimage[180] = {
1362 0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05,
1363 0x00,0x00,0x00,0x00,0xb1,0x52,0x01,0x00,0x09,0x00,0x00,0x03,0x4f,0x00,0x00,0x00,
1364 0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0b,0x02,0x00,0x00,
1365 0x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x02,0x40,0x01,0x40,0x01,0x04,0x00,0x00,0x00,
1366 0x02,0x01,0x01,0x00,0x04,0x00,0x00,0x00,0x04,0x01,0x0d,0x00,0x08,0x00,0x00,0x00,
1367 0xfa,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
1368 0x2d,0x01,0x00,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,0x01,0x00,0x00,0x00,0x00,0x00,
1369 0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x01,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,
1370 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x02,0x00,
1371 0x07,0x00,0x00,0x00,0x1b,0x04,0x40,0x01,0x40,0x01,0x00,0x00,0x00,0x00,0x04,0x00,
1372 0x00,0x00,0xf0,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0xf0,0x01,0x01,0x00,0x03,0x00,
1373 0x00,0x00,0x00,0x00
1374 };
1375 static void test_getrawformat(void)
1376 {
1377     test_bufferrawformat((void*)pngimage, sizeof(pngimage), &ImageFormatPNG,  __LINE__, FALSE);
1378     test_bufferrawformat((void*)gifimage, sizeof(gifimage), &ImageFormatGIF,  __LINE__, FALSE);
1379     test_bufferrawformat((void*)bmpimage, sizeof(bmpimage), &ImageFormatBMP,  __LINE__, FALSE);
1380     test_bufferrawformat((void*)jpgimage, sizeof(jpgimage), &ImageFormatJPEG, __LINE__, FALSE);
1381     test_bufferrawformat((void*)tiffimage, sizeof(tiffimage), &ImageFormatTIFF, __LINE__, FALSE);
1382     test_bufferrawformat((void*)wmfimage, sizeof(wmfimage), &ImageFormatWMF, __LINE__, FALSE);
1383 }
1384
1385 static void test_loadwmf(void)
1386 {
1387     LPSTREAM stream;
1388     HGLOBAL  hglob;
1389     LPBYTE   data;
1390     HRESULT  hres;
1391     GpStatus stat;
1392     GpImage *img;
1393     GpRectF bounds;
1394     GpUnit unit;
1395     REAL res = 12345.0;
1396     MetafileHeader header;
1397
1398     hglob = GlobalAlloc (0, sizeof(wmfimage));
1399     data = GlobalLock (hglob);
1400     memcpy(data, wmfimage, sizeof(wmfimage));
1401     GlobalUnlock(hglob); data = NULL;
1402
1403     hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
1404     ok(hres == S_OK, "Failed to create a stream\n");
1405     if(hres != S_OK) return;
1406
1407     stat = GdipLoadImageFromStream(stream, &img);
1408     ok(stat == Ok, "Failed to create a Bitmap\n");
1409     if(stat != Ok){
1410         IStream_Release(stream);
1411         return;
1412     }
1413
1414     IStream_Release(stream);
1415
1416     stat = GdipGetImageBounds(img, &bounds, &unit);
1417     expect(Ok, stat);
1418     todo_wine expect(UnitPixel, unit);
1419     expectf(0.0, bounds.X);
1420     expectf(0.0, bounds.Y);
1421     todo_wine expectf(320.0, bounds.Width);
1422     todo_wine expectf(320.0, bounds.Height);
1423
1424     stat = GdipGetImageHorizontalResolution(img, &res);
1425     expect(Ok, stat);
1426     todo_wine expectf(1440.0, res);
1427
1428     stat = GdipGetImageVerticalResolution(img, &res);
1429     expect(Ok, stat);
1430     todo_wine expectf(1440.0, res);
1431
1432     memset(&header, 0, sizeof(header));
1433     stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header);
1434     expect(Ok, stat);
1435     if (stat == Ok)
1436     {
1437         todo_wine expect(MetafileTypeWmfPlaceable, header.Type);
1438         todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size);
1439         todo_wine expect(0x300, header.Version);
1440         expect(0, header.EmfPlusFlags);
1441         todo_wine expectf(1440.0, header.DpiX);
1442         todo_wine expectf(1440.0, header.DpiY);
1443         expect(0, header.X);
1444         expect(0, header.Y);
1445         todo_wine expect(320, header.Width);
1446         todo_wine expect(320, header.Height);
1447         todo_wine expect(1, U(header).WmfHeader.mtType);
1448         expect(0, header.EmfPlusHeaderSize);
1449         expect(0, header.LogicalDpiX);
1450         expect(0, header.LogicalDpiY);
1451     }
1452
1453     GdipDisposeImage(img);
1454 }
1455
1456 static void test_createfromwmf(void)
1457 {
1458     HMETAFILE hwmf;
1459     GpImage *img;
1460     GpStatus stat;
1461     GpRectF bounds;
1462     GpUnit unit;
1463     REAL res = 12345.0;
1464     MetafileHeader header;
1465
1466     hwmf = SetMetaFileBitsEx(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader),
1467         wmfimage+sizeof(WmfPlaceableFileHeader));
1468     ok(hwmf != 0, "SetMetaFileBitsEx failed\n");
1469
1470     stat = GdipCreateMetafileFromWmf(hwmf, TRUE,
1471         (WmfPlaceableFileHeader*)wmfimage, (GpMetafile**)&img);
1472     expect(Ok, stat);
1473
1474     stat = GdipGetImageBounds(img, &bounds, &unit);
1475     expect(Ok, stat);
1476     expect(UnitPixel, unit);
1477     expectf(0.0, bounds.X);
1478     expectf(0.0, bounds.Y);
1479     expectf(320.0, bounds.Width);
1480     expectf(320.0, bounds.Height);
1481
1482     stat = GdipGetImageHorizontalResolution(img, &res);
1483     expect(Ok, stat);
1484     expectf(1440.0, res);
1485
1486     stat = GdipGetImageVerticalResolution(img, &res);
1487     expect(Ok, stat);
1488     expectf(1440.0, res);
1489
1490     memset(&header, 0, sizeof(header));
1491     stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header);
1492     expect(Ok, stat);
1493     if (stat == Ok)
1494     {
1495         todo_wine expect(MetafileTypeWmfPlaceable, header.Type);
1496         todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size);
1497         todo_wine expect(0x300, header.Version);
1498         expect(0, header.EmfPlusFlags);
1499         todo_wine expectf(1440.0, header.DpiX);
1500         todo_wine expectf(1440.0, header.DpiY);
1501         expect(0, header.X);
1502         expect(0, header.Y);
1503         todo_wine expect(320, header.Width);
1504         todo_wine expect(320, header.Height);
1505         todo_wine expect(1, U(header).WmfHeader.mtType);
1506         expect(0, header.EmfPlusHeaderSize);
1507         expect(0, header.LogicalDpiX);
1508         expect(0, header.LogicalDpiY);
1509     }
1510
1511     GdipDisposeImage(img);
1512 }
1513
1514 static void test_resolution(void)
1515 {
1516     GpStatus stat;
1517     GpBitmap *bitmap;
1518     REAL res=-1.0;
1519     HDC screendc;
1520     int screenxres, screenyres;
1521
1522     /* create Bitmap */
1523     stat = GdipCreateBitmapFromScan0(1, 1, 32, PixelFormat24bppRGB, NULL, &bitmap);
1524     expect(Ok, stat);
1525
1526     /* test invalid values */
1527     stat = GdipGetImageHorizontalResolution(NULL, &res);
1528     expect(InvalidParameter, stat);
1529
1530     stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, NULL);
1531     expect(InvalidParameter, stat);
1532
1533     stat = GdipGetImageVerticalResolution(NULL, &res);
1534     expect(InvalidParameter, stat);
1535
1536     stat = GdipGetImageVerticalResolution((GpImage*)bitmap, NULL);
1537     expect(InvalidParameter, stat);
1538
1539     stat = GdipBitmapSetResolution(NULL, 96.0, 96.0);
1540     expect(InvalidParameter, stat);
1541
1542     stat = GdipBitmapSetResolution(bitmap, 0.0, 0.0);
1543     expect(InvalidParameter, stat);
1544
1545     /* defaults to screen resolution */
1546     screendc = GetDC(0);
1547
1548     screenxres = GetDeviceCaps(screendc, LOGPIXELSX);
1549     screenyres = GetDeviceCaps(screendc, LOGPIXELSY);
1550
1551     ReleaseDC(0, screendc);
1552
1553     stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, &res);
1554     expect(Ok, stat);
1555     expectf((REAL)screenxres, res);
1556
1557     stat = GdipGetImageVerticalResolution((GpImage*)bitmap, &res);
1558     expect(Ok, stat);
1559     expectf((REAL)screenyres, res);
1560
1561     /* test changing the resolution */
1562     stat = GdipBitmapSetResolution(bitmap, screenxres*2.0, screenyres*3.0);
1563     expect(Ok, stat);
1564
1565     stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, &res);
1566     expect(Ok, stat);
1567     expectf(screenxres*2.0, res);
1568
1569     stat = GdipGetImageVerticalResolution((GpImage*)bitmap, &res);
1570     expect(Ok, stat);
1571     expectf(screenyres*3.0, res);
1572
1573     stat = GdipDisposeImage((GpImage*)bitmap);
1574     expect(Ok, stat);
1575 }
1576
1577 static void test_createhbitmap(void)
1578 {
1579     GpStatus stat;
1580     GpBitmap *bitmap;
1581     HBITMAP hbitmap, oldhbitmap;
1582     BITMAP bm;
1583     int ret;
1584     HDC hdc;
1585     COLORREF pixel;
1586     BYTE bits[640];
1587
1588     memset(bits, 0x68, 640);
1589
1590     /* create Bitmap */
1591     stat = GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB, bits, &bitmap);
1592     expect(Ok, stat);
1593
1594     /* test NULL values */
1595     stat = GdipCreateHBITMAPFromBitmap(NULL, &hbitmap, 0);
1596     expect(InvalidParameter, stat);
1597
1598     stat = GdipCreateHBITMAPFromBitmap(bitmap, NULL, 0);
1599     expect(InvalidParameter, stat);
1600
1601     /* create HBITMAP */
1602     stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0);
1603     expect(Ok, stat);
1604
1605     if (stat == Ok)
1606     {
1607         ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
1608         expect(sizeof(BITMAP), ret);
1609
1610         expect(0, bm.bmType);
1611         expect(10, bm.bmWidth);
1612         expect(20, bm.bmHeight);
1613         expect(40, bm.bmWidthBytes);
1614         expect(1, bm.bmPlanes);
1615         expect(32, bm.bmBitsPixel);
1616         ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
1617
1618         if (bm.bmBits)
1619         {
1620             DWORD val = *(DWORD*)bm.bmBits;
1621             ok(val == 0xff686868, "got %x, expected 0xff686868\n", val);
1622         }
1623
1624         hdc = CreateCompatibleDC(NULL);
1625
1626         oldhbitmap = SelectObject(hdc, hbitmap);
1627         pixel = GetPixel(hdc, 5, 5);
1628         SelectObject(hdc, oldhbitmap);
1629
1630         DeleteDC(hdc);
1631
1632         expect(0x686868, pixel);
1633
1634         DeleteObject(hbitmap);
1635     }
1636
1637     stat = GdipDisposeImage((GpImage*)bitmap);
1638     expect(Ok, stat);
1639
1640     /* create alpha Bitmap */
1641     stat = GdipCreateBitmapFromScan0(8, 20, 32, PixelFormat32bppARGB, bits, &bitmap);
1642     expect(Ok, stat);
1643
1644     /* create HBITMAP */
1645     stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0);
1646     expect(Ok, stat);
1647
1648     if (stat == Ok)
1649     {
1650         ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
1651         expect(sizeof(BITMAP), ret);
1652
1653         expect(0, bm.bmType);
1654         expect(8, bm.bmWidth);
1655         expect(20, bm.bmHeight);
1656         expect(32, bm.bmWidthBytes);
1657         expect(1, bm.bmPlanes);
1658         expect(32, bm.bmBitsPixel);
1659         ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
1660
1661         if (bm.bmBits)
1662         {
1663             DWORD val = *(DWORD*)bm.bmBits;
1664             ok(val == 0x682a2a2a, "got %x, expected 0x682a2a2a\n", val);
1665         }
1666
1667         hdc = CreateCompatibleDC(NULL);
1668
1669         oldhbitmap = SelectObject(hdc, hbitmap);
1670         pixel = GetPixel(hdc, 5, 5);
1671         SelectObject(hdc, oldhbitmap);
1672
1673         DeleteDC(hdc);
1674
1675         expect(0x2a2a2a, pixel);
1676
1677         DeleteObject(hbitmap);
1678     }
1679
1680     stat = GdipDisposeImage((GpImage*)bitmap);
1681     expect(Ok, stat);
1682 }
1683
1684 static void test_getthumbnail(void)
1685 {
1686     GpStatus stat;
1687     GpImage *bitmap1, *bitmap2;
1688     UINT width, height;
1689
1690     stat = GdipGetImageThumbnail(NULL, 0, 0, &bitmap2, NULL, NULL);
1691     expect(InvalidParameter, stat);
1692
1693     stat = GdipCreateBitmapFromScan0(128, 128, 0, PixelFormat32bppRGB, NULL, (GpBitmap**)&bitmap1);
1694     expect(Ok, stat);
1695
1696     stat = GdipGetImageThumbnail(bitmap1, 0, 0, NULL, NULL, NULL);
1697     expect(InvalidParameter, stat);
1698
1699     stat = GdipGetImageThumbnail(bitmap1, 0, 0, &bitmap2, NULL, NULL);
1700     expect(Ok, stat);
1701
1702     if (stat == Ok)
1703     {
1704         stat = GdipGetImageWidth(bitmap2, &width);
1705         expect(Ok, stat);
1706         expect(120, width);
1707
1708         stat = GdipGetImageHeight(bitmap2, &height);
1709         expect(Ok, stat);
1710         expect(120, height);
1711
1712         GdipDisposeImage(bitmap2);
1713     }
1714
1715     GdipDisposeImage(bitmap1);
1716
1717
1718     stat = GdipCreateBitmapFromScan0(64, 128, 0, PixelFormat32bppRGB, NULL, (GpBitmap**)&bitmap1);
1719     expect(Ok, stat);
1720
1721     stat = GdipGetImageThumbnail(bitmap1, 32, 32, &bitmap2, NULL, NULL);
1722     expect(Ok, stat);
1723
1724     if (stat == Ok)
1725     {
1726         stat = GdipGetImageWidth(bitmap2, &width);
1727         expect(Ok, stat);
1728         expect(32, width);
1729
1730         stat = GdipGetImageHeight(bitmap2, &height);
1731         expect(Ok, stat);
1732         expect(32, height);
1733
1734         GdipDisposeImage(bitmap2);
1735     }
1736
1737     stat = GdipGetImageThumbnail(bitmap1, 0, 0, &bitmap2, NULL, NULL);
1738     expect(Ok, stat);
1739
1740     if (stat == Ok)
1741     {
1742         stat = GdipGetImageWidth(bitmap2, &width);
1743         expect(Ok, stat);
1744         expect(120, width);
1745
1746         stat = GdipGetImageHeight(bitmap2, &height);
1747         expect(Ok, stat);
1748         expect(120, height);
1749
1750         GdipDisposeImage(bitmap2);
1751     }
1752
1753     GdipDisposeImage(bitmap1);
1754 }
1755
1756 static void test_getsetpixel(void)
1757 {
1758     GpStatus stat;
1759     GpBitmap *bitmap;
1760     ARGB color;
1761     BYTE bits[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00,
1762                      0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00};
1763
1764     stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB, bits, &bitmap);
1765     expect(Ok, stat);
1766
1767     /* null parameters */
1768     stat = GdipBitmapGetPixel(NULL, 1, 1, &color);
1769     expect(InvalidParameter, stat);
1770
1771     stat = GdipBitmapGetPixel(bitmap, 1, 1, NULL);
1772     expect(InvalidParameter, stat);
1773
1774     stat = GdipBitmapSetPixel(NULL, 1, 1, 0);
1775     expect(InvalidParameter, stat);
1776
1777     /* out of bounds */
1778     stat = GdipBitmapGetPixel(bitmap, -1, 1, &color);
1779     expect(InvalidParameter, stat);
1780
1781     stat = GdipBitmapSetPixel(bitmap, -1, 1, 0);
1782     expect(InvalidParameter, stat);
1783
1784     stat = GdipBitmapGetPixel(bitmap, 1, -1, &color);
1785     ok(stat == InvalidParameter ||
1786        broken(stat == Ok), /* Older gdiplus */
1787        "Expected InvalidParameter, got %.8x\n", stat);
1788
1789     stat = GdipBitmapSetPixel(bitmap, 1, -1, 0);
1790     ok(stat == InvalidParameter ||
1791        broken(stat == Ok), /* Older gdiplus */
1792        "Expected InvalidParameter, got %.8x\n", stat);
1793
1794     stat = GdipBitmapGetPixel(bitmap, 2, 1, &color);
1795     expect(InvalidParameter, stat);
1796
1797     stat = GdipBitmapSetPixel(bitmap, 2, 1, 0);
1798     expect(InvalidParameter, stat);
1799
1800     stat = GdipBitmapGetPixel(bitmap, 1, 2, &color);
1801     expect(InvalidParameter, stat);
1802
1803     stat = GdipBitmapSetPixel(bitmap, 1, 2, 0);
1804     expect(InvalidParameter, stat);
1805
1806     /* valid use */
1807     stat = GdipBitmapGetPixel(bitmap, 1, 1, &color);
1808     expect(Ok, stat);
1809     expect(0xffffffff, color);
1810
1811     stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
1812     expect(Ok, stat);
1813     expect(0xff0000ff, color);
1814
1815     stat = GdipBitmapSetPixel(bitmap, 1, 1, 0xff676869);
1816     expect(Ok, stat);
1817
1818     stat = GdipBitmapSetPixel(bitmap, 0, 0, 0xff474849);
1819     expect(Ok, stat);
1820
1821     stat = GdipBitmapGetPixel(bitmap, 1, 1, &color);
1822     expect(Ok, stat);
1823     expect(0xff676869, color);
1824
1825     stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
1826     expect(Ok, stat);
1827     expect(0xff474849, color);
1828
1829     stat = GdipDisposeImage((GpImage*)bitmap);
1830     expect(Ok, stat);
1831 }
1832
1833 static void check_halftone_palette(ColorPalette *palette)
1834 {
1835     static const BYTE halftone_values[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
1836     UINT i;
1837
1838     for (i=0; i<palette->Count; i++)
1839     {
1840         ARGB expected=0xff000000;
1841         if (i<8)
1842         {
1843             if (i&1) expected |= 0x800000;
1844             if (i&2) expected |= 0x8000;
1845             if (i&4) expected |= 0x80;
1846         }
1847         else if (i == 8)
1848         {
1849             expected = 0xffc0c0c0;
1850         }
1851         else if (i < 16)
1852         {
1853             if (i&1) expected |= 0xff0000;
1854             if (i&2) expected |= 0xff00;
1855             if (i&4) expected |= 0xff;
1856         }
1857         else if (i < 40)
1858         {
1859             expected = 0x00000000;
1860         }
1861         else
1862         {
1863             expected |= halftone_values[(i-40)%6];
1864             expected |= halftone_values[((i-40)/6)%6] << 8;
1865             expected |= halftone_values[((i-40)/36)%6] << 16;
1866         }
1867         ok(expected == palette->Entries[i], "Expected %.8x, got %.8x, i=%u/%u\n",
1868             expected, palette->Entries[i], i, palette->Count);
1869     }
1870 }
1871
1872 static void test_palette(void)
1873 {
1874     GpStatus stat;
1875     GpBitmap *bitmap;
1876     INT size;
1877     BYTE buffer[1040];
1878     ColorPalette *palette=(ColorPalette*)buffer;
1879     ARGB *entries = palette->Entries;
1880     ARGB color=0;
1881
1882     /* test initial palette from non-indexed bitmap */
1883     stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB, NULL, &bitmap);
1884     expect(Ok, stat);
1885
1886     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1887     expect(Ok, stat);
1888     expect(sizeof(UINT)*2+sizeof(ARGB), size);
1889
1890     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1891     expect(Ok, stat);
1892     expect(0, palette->Count);
1893
1894     /* test setting palette on not-indexed bitmap */
1895     palette->Count = 3;
1896
1897     stat = GdipSetImagePalette((GpImage*)bitmap, palette);
1898     expect(Ok, stat);
1899
1900     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1901     expect(Ok, stat);
1902     expect(sizeof(UINT)*2+sizeof(ARGB)*3, size);
1903
1904     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1905     expect(Ok, stat);
1906     expect(3, palette->Count);
1907
1908     GdipDisposeImage((GpImage*)bitmap);
1909
1910     /* test initial palette on 1-bit bitmap */
1911     stat = GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat1bppIndexed, NULL, &bitmap);
1912     expect(Ok, stat);
1913
1914     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1915     expect(Ok, stat);
1916     expect(sizeof(UINT)*2+sizeof(ARGB)*2, size);
1917
1918     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1919     expect(Ok, stat);
1920     expect(PaletteFlagsGrayScale, palette->Flags);
1921     expect(2, palette->Count);
1922
1923     expect(0xff000000, entries[0]);
1924     expect(0xffffffff, entries[1]);
1925
1926     /* test getting/setting pixels */
1927     stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
1928     expect(Ok, stat);
1929     expect(0xff000000, color);
1930
1931     stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffffffff);
1932     ok((stat == Ok) ||
1933        broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
1934
1935     if (stat == Ok)
1936     {
1937         stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
1938         expect(Ok, stat);
1939         expect(0xffffffff, color);
1940     }
1941
1942     GdipDisposeImage((GpImage*)bitmap);
1943
1944     /* test initial palette on 4-bit bitmap */
1945     stat = GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat4bppIndexed, NULL, &bitmap);
1946     expect(Ok, stat);
1947
1948     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1949     expect(Ok, stat);
1950     expect(sizeof(UINT)*2+sizeof(ARGB)*16, size);
1951
1952     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1953     expect(Ok, stat);
1954     expect(0, palette->Flags);
1955     expect(16, palette->Count);
1956
1957     check_halftone_palette(palette);
1958
1959     /* test getting/setting pixels */
1960     stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
1961     expect(Ok, stat);
1962     expect(0xff000000, color);
1963
1964     stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffff00ff);
1965     ok((stat == Ok) ||
1966        broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
1967
1968     if (stat == Ok)
1969     {
1970         stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
1971         expect(Ok, stat);
1972         expect(0xffff00ff, color);
1973     }
1974
1975     GdipDisposeImage((GpImage*)bitmap);
1976
1977     /* test initial palette on 8-bit bitmap */
1978     stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat8bppIndexed, NULL, &bitmap);
1979     expect(Ok, stat);
1980
1981     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1982     expect(Ok, stat);
1983     expect(sizeof(UINT)*2+sizeof(ARGB)*256, size);
1984
1985     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1986     expect(Ok, stat);
1987     expect(PaletteFlagsHalftone, palette->Flags);
1988     expect(256, palette->Count);
1989
1990     check_halftone_palette(palette);
1991
1992     /* test getting/setting pixels */
1993     stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
1994     expect(Ok, stat);
1995     expect(0xff000000, color);
1996
1997     stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffcccccc);
1998     ok((stat == Ok) ||
1999        broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
2000
2001     if (stat == Ok)
2002     {
2003         stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
2004         expect(Ok, stat);
2005         expect(0xffcccccc, color);
2006     }
2007
2008     /* test setting/getting a different palette */
2009     entries[1] = 0xffcccccc;
2010
2011     stat = GdipSetImagePalette((GpImage*)bitmap, palette);
2012     expect(Ok, stat);
2013
2014     entries[1] = 0;
2015
2016     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
2017     expect(Ok, stat);
2018     expect(sizeof(UINT)*2+sizeof(ARGB)*256, size);
2019
2020     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
2021     expect(Ok, stat);
2022     expect(PaletteFlagsHalftone, palette->Flags);
2023     expect(256, palette->Count);
2024     expect(0xffcccccc, entries[1]);
2025
2026     /* test count < 256 */
2027     palette->Flags = 12345;
2028     palette->Count = 3;
2029
2030     stat = GdipSetImagePalette((GpImage*)bitmap, palette);
2031     expect(Ok, stat);
2032
2033     entries[1] = 0;
2034     entries[3] = 0xdeadbeef;
2035
2036     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
2037     expect(Ok, stat);
2038     expect(sizeof(UINT)*2+sizeof(ARGB)*3, size);
2039
2040     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
2041     expect(Ok, stat);
2042     expect(12345, palette->Flags);
2043     expect(3, palette->Count);
2044     expect(0xffcccccc, entries[1]);
2045     expect(0xdeadbeef, entries[3]);
2046
2047     /* test count > 256 */
2048     palette->Count = 257;
2049
2050     stat = GdipSetImagePalette((GpImage*)bitmap, palette);
2051     ok(stat == InvalidParameter ||
2052        broken(stat == Ok), /* Old gdiplus behavior */
2053        "Expected %.8x, got %.8x\n", InvalidParameter, stat);
2054
2055     GdipDisposeImage((GpImage*)bitmap);
2056 }
2057
2058 static void test_colormatrix(void)
2059 {
2060     GpStatus stat;
2061     ColorMatrix colormatrix, graymatrix;
2062     GpImageAttributes *imageattr;
2063     const ColorMatrix identity = {{
2064         {1.0,0.0,0.0,0.0,0.0},
2065         {0.0,1.0,0.0,0.0,0.0},
2066         {0.0,0.0,1.0,0.0,0.0},
2067         {0.0,0.0,0.0,1.0,0.0},
2068         {0.0,0.0,0.0,0.0,1.0}}};
2069     const ColorMatrix double_red = {{
2070         {2.0,0.0,0.0,0.0,0.0},
2071         {0.0,1.0,0.0,0.0,0.0},
2072         {0.0,0.0,1.0,0.0,0.0},
2073         {0.0,0.0,0.0,1.0,0.0},
2074         {0.0,0.0,0.0,0.0,1.0}}};
2075     const ColorMatrix asymmetric = {{
2076         {0.0,1.0,0.0,0.0,0.0},
2077         {0.0,0.0,1.0,0.0,0.0},
2078         {0.0,0.0,0.0,1.0,0.0},
2079         {1.0,0.0,0.0,0.0,0.0},
2080         {0.0,0.0,0.0,0.0,1.0}}};
2081     GpBitmap *bitmap1, *bitmap2;
2082     GpGraphics *graphics;
2083     ARGB color;
2084
2085     colormatrix = identity;
2086     graymatrix = identity;
2087
2088     stat = GdipSetImageAttributesColorMatrix(NULL, ColorAdjustTypeDefault,
2089         TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2090     expect(InvalidParameter, stat);
2091
2092     stat = GdipCreateImageAttributes(&imageattr);
2093     expect(Ok, stat);
2094
2095     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2096         TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2097     expect(Ok, stat);
2098
2099     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2100         TRUE, NULL, NULL, ColorMatrixFlagsDefault);
2101     expect(InvalidParameter, stat);
2102
2103     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2104         TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2105     expect(Ok, stat);
2106
2107     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2108         TRUE, &colormatrix, NULL, ColorMatrixFlagsSkipGrays);
2109     expect(Ok, stat);
2110
2111     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2112         TRUE, &colormatrix, NULL, ColorMatrixFlagsAltGray);
2113     expect(InvalidParameter, stat);
2114
2115     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2116         TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsAltGray);
2117     expect(Ok, stat);
2118
2119     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2120         TRUE, &colormatrix, &graymatrix, 3);
2121     expect(InvalidParameter, stat);
2122
2123     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeCount,
2124         TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2125     expect(InvalidParameter, stat);
2126
2127     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeAny,
2128         TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2129     expect(InvalidParameter, stat);
2130
2131     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2132         FALSE, NULL, NULL, ColorMatrixFlagsDefault);
2133     expect(Ok, stat);
2134
2135     /* Drawing a bitmap transforms the colors */
2136     colormatrix = double_red;
2137     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2138         TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2139     expect(Ok, stat);
2140
2141     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB, NULL, &bitmap1);
2142     expect(Ok, stat);
2143
2144     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB, NULL, &bitmap2);
2145     expect(Ok, stat);
2146
2147     stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff40ccee);
2148     expect(Ok, stat);
2149
2150     stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
2151     expect(Ok, stat);
2152
2153     stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2154         UnitPixel, imageattr, NULL, NULL);
2155     expect(Ok, stat);
2156
2157     stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2158     expect(Ok, stat);
2159     expect(0xff80ccee, color);
2160
2161     colormatrix = asymmetric;
2162     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2163         TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2164     expect(Ok, stat);
2165
2166     stat = GdipBitmapSetPixel(bitmap2, 0, 0, 0);
2167     expect(Ok, stat);
2168
2169     stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2170         UnitPixel, imageattr, NULL, NULL);
2171     expect(Ok, stat);
2172
2173     stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2174     expect(Ok, stat);
2175     ok(color_match(0xeeff40cc, color, 3), "expected 0xeeff40cc, got 0x%08x\n", color);
2176
2177     GdipDeleteGraphics(graphics);
2178     GdipDisposeImage((GpImage*)bitmap1);
2179     GdipDisposeImage((GpImage*)bitmap2);
2180     GdipDisposeImageAttributes(imageattr);
2181 }
2182
2183 static void test_gamma(void)
2184 {
2185     GpStatus stat;
2186     GpImageAttributes *imageattr;
2187     GpBitmap *bitmap1, *bitmap2;
2188     GpGraphics *graphics;
2189     ARGB color;
2190
2191     stat = GdipSetImageAttributesGamma(NULL, ColorAdjustTypeDefault, TRUE, 1.0);
2192     expect(InvalidParameter, stat);
2193
2194     stat = GdipCreateImageAttributes(&imageattr);
2195     expect(Ok, stat);
2196
2197     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 1.0);
2198     expect(Ok, stat);
2199
2200     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeAny, TRUE, 1.0);
2201     expect(InvalidParameter, stat);
2202
2203     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, -1.0);
2204     expect(InvalidParameter, stat);
2205
2206     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 0.0);
2207     expect(InvalidParameter, stat);
2208
2209     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 0.5);
2210     expect(Ok, stat);
2211
2212     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, FALSE, 0.0);
2213     expect(Ok, stat);
2214
2215     /* Drawing a bitmap transforms the colors */
2216     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 3.0);
2217     expect(Ok, stat);
2218
2219     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap1);
2220     expect(Ok, stat);
2221
2222     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap2);
2223     expect(Ok, stat);
2224
2225     stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff80ffff);
2226     expect(Ok, stat);
2227
2228     stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
2229     expect(Ok, stat);
2230
2231     stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2232         UnitPixel, imageattr, NULL, NULL);
2233     expect(Ok, stat);
2234
2235     stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2236     expect(Ok, stat);
2237     ok(color_match(0xff20ffff, color, 1), "Expected ff20ffff, got %.8x\n", color);
2238
2239     GdipDeleteGraphics(graphics);
2240     GdipDisposeImage((GpImage*)bitmap1);
2241     GdipDisposeImage((GpImage*)bitmap2);
2242     GdipDisposeImageAttributes(imageattr);
2243 }
2244
2245 /* 1x1 pixel gif, 2 frames; first frame is white, second is black */
2246 static const unsigned char gifanimation[72] = {
2247 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
2248 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0xf9,0x04,0x00,0x0a,0x00,0xff,
2249 0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x4c,0x01,0x00,
2250 0x21,0xf9,0x04,0x01,0x0a,0x00,0x01,0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,
2251 0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
2252 };
2253
2254 static void test_multiframegif(void)
2255 {
2256     LPSTREAM stream;
2257     HGLOBAL hglob;
2258     LPBYTE data;
2259     HRESULT hres;
2260     GpStatus stat;
2261     GpBitmap *bmp;
2262     ARGB color;
2263     UINT count;
2264     GUID dimension;
2265
2266     /* Test frame functions with an animated GIF */
2267     hglob = GlobalAlloc (0, sizeof(gifanimation));
2268     data = GlobalLock (hglob);
2269     memcpy(data, gifanimation, sizeof(gifanimation));
2270     GlobalUnlock(hglob);
2271
2272     hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
2273     ok(hres == S_OK, "Failed to create a stream\n");
2274     if(hres != S_OK) return;
2275
2276     stat = GdipCreateBitmapFromStream(stream, &bmp);
2277     ok(stat == Ok, "Failed to create a Bitmap\n");
2278     if(stat != Ok){
2279         IStream_Release(stream);
2280         return;
2281     }
2282
2283     /* Bitmap starts at frame 0 */
2284     color = 0xdeadbeef;
2285     stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2286     expect(Ok, stat);
2287     expect(0xffffffff, color);
2288
2289     /* Check that we get correct metadata */
2290     stat = GdipImageGetFrameDimensionsCount((GpImage*)bmp,&count);
2291     expect(Ok, stat);
2292     expect(1, count);
2293
2294     stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1);
2295     expect(Ok, stat);
2296     expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE);
2297
2298     count = 12345;
2299     stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
2300     expect(Ok, stat);
2301     expect(2, count);
2302
2303     /* SelectActiveFrame overwrites our current data */
2304     stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 1);
2305     expect(Ok, stat);
2306
2307     color = 0xdeadbeef;
2308     GdipBitmapGetPixel(bmp, 0, 0, &color);
2309     expect(Ok, stat);
2310     expect(0xff000000, color);
2311
2312     stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
2313     expect(Ok, stat);
2314
2315     color = 0xdeadbeef;
2316     GdipBitmapGetPixel(bmp, 0, 0, &color);
2317     expect(Ok, stat);
2318     expect(0xffffffff, color);
2319
2320     /* Write over the image data */
2321     stat = GdipBitmapSetPixel(bmp, 0, 0, 0xff000000);
2322     expect(Ok, stat);
2323
2324     /* Switching to the same frame does not overwrite our changes */
2325     stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
2326     expect(Ok, stat);
2327
2328     stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2329     expect(Ok, stat);
2330     expect(0xff000000, color);
2331
2332     /* But switching to another frame and back does */
2333     stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 1);
2334     expect(Ok, stat);
2335
2336     stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
2337     expect(Ok, stat);
2338
2339     stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2340     expect(Ok, stat);
2341     expect(0xffffffff, color);
2342
2343     GdipDisposeImage((GpImage*)bmp);
2344     IStream_Release(stream);
2345
2346     /* Test with a non-animated gif */
2347     hglob = GlobalAlloc (0, sizeof(gifimage));
2348     data = GlobalLock (hglob);
2349     memcpy(data, gifimage, sizeof(gifimage));
2350     GlobalUnlock(hglob);
2351
2352     hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
2353     ok(hres == S_OK, "Failed to create a stream\n");
2354     if(hres != S_OK) return;
2355
2356     stat = GdipCreateBitmapFromStream(stream, &bmp);
2357     ok(stat == Ok, "Failed to create a Bitmap\n");
2358     if(stat != Ok){
2359         IStream_Release(stream);
2360         return;
2361     }
2362
2363     /* Check metadata */
2364     stat = GdipImageGetFrameDimensionsCount((GpImage*)bmp,&count);
2365     expect(Ok, stat);
2366     expect(1, count);
2367
2368     stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1);
2369     expect(Ok, stat);
2370     expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE);
2371
2372     count = 12345;
2373     stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
2374     expect(Ok, stat);
2375     expect(1, count);
2376
2377     GdipDisposeImage((GpImage*)bmp);
2378     IStream_Release(stream);
2379 }
2380
2381 static void test_rotateflip(void)
2382 {
2383     GpImage *bitmap;
2384     GpStatus stat;
2385     BYTE bits[24];
2386     static const BYTE orig_bits[24] = {
2387         0,0,0xff,    0,0xff,0,    0xff,0,0,    23,23,23,
2388         0xff,0xff,0, 0xff,0,0xff, 0,0xff,0xff, 23,23,23};
2389     UINT width, height;
2390     ARGB color;
2391
2392     memcpy(bits, orig_bits, sizeof(bits));
2393     stat = GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB, bits, (GpBitmap**)&bitmap);
2394     expect(Ok, stat);
2395
2396     stat = GdipImageRotateFlip(bitmap, Rotate90FlipNone);
2397     expect(Ok, stat);
2398
2399     stat = GdipGetImageWidth(bitmap, &width);
2400     expect(Ok, stat);
2401     stat = GdipGetImageHeight(bitmap, &height);
2402     expect(Ok, stat);
2403     expect(2, width);
2404     expect(3, height);
2405
2406     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
2407     expect(Ok, stat);
2408     expect(0xff00ffff, color);
2409
2410     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 1, 0, &color);
2411     expect(Ok, stat);
2412     expect(0xffff0000, color);
2413
2414     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 2, &color);
2415     expect(Ok, stat);
2416     expect(0xffffff00, color);
2417
2418     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 1, 2, &color);
2419     expect(Ok, stat);
2420     expect(0xff0000ff, color);
2421
2422     expect(0, bits[0]);
2423     expect(0, bits[1]);
2424     expect(0xff, bits[2]);
2425
2426     GdipDisposeImage(bitmap);
2427
2428     memcpy(bits, orig_bits, sizeof(bits));
2429     stat = GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB, bits, (GpBitmap**)&bitmap);
2430     expect(Ok, stat);
2431
2432     stat = GdipImageRotateFlip(bitmap, RotateNoneFlipX);
2433     expect(Ok, stat);
2434
2435     stat = GdipGetImageWidth(bitmap, &width);
2436     expect(Ok, stat);
2437     stat = GdipGetImageHeight(bitmap, &height);
2438     expect(Ok, stat);
2439     expect(3, width);
2440     expect(2, height);
2441
2442     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
2443     expect(Ok, stat);
2444     expect(0xff0000ff, color);
2445
2446     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 0, &color);
2447     expect(Ok, stat);
2448     expect(0xffff0000, color);
2449
2450     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 1, &color);
2451     expect(Ok, stat);
2452     expect(0xffffff00, color);
2453
2454     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 1, &color);
2455     expect(Ok, stat);
2456     expect(0xff00ffff, color);
2457
2458     expect(0, bits[0]);
2459     expect(0, bits[1]);
2460     expect(0xff, bits[2]);
2461
2462     GdipDisposeImage(bitmap);
2463
2464     memcpy(bits, orig_bits, sizeof(bits));
2465     stat = GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB, bits, (GpBitmap**)&bitmap);
2466     expect(Ok, stat);
2467
2468     stat = GdipImageRotateFlip(bitmap, RotateNoneFlipY);
2469     expect(Ok, stat);
2470
2471     stat = GdipGetImageWidth(bitmap, &width);
2472     expect(Ok, stat);
2473     stat = GdipGetImageHeight(bitmap, &height);
2474     expect(Ok, stat);
2475     expect(3, width);
2476     expect(2, height);
2477
2478     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
2479     expect(Ok, stat);
2480     expect(0xff00ffff, color);
2481
2482     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 0, &color);
2483     expect(Ok, stat);
2484     expect(0xffffff00, color);
2485
2486     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 1, &color);
2487     expect(Ok, stat);
2488     expect(0xffff0000, color);
2489
2490     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 1, &color);
2491     expect(Ok, stat);
2492     expect(0xff0000ff, color);
2493
2494     expect(0, bits[0]);
2495     expect(0, bits[1]);
2496     expect(0xff, bits[2]);
2497
2498     GdipDisposeImage(bitmap);
2499 }
2500
2501 static void test_remaptable(void)
2502 {
2503     GpStatus stat;
2504     GpImageAttributes *imageattr;
2505     GpBitmap *bitmap1, *bitmap2;
2506     GpGraphics *graphics;
2507     ARGB color;
2508     ColorMap *map;
2509
2510     map = GdipAlloc(sizeof(ColorMap));
2511
2512     map->oldColor.Argb = 0xff00ff00;
2513     map->newColor.Argb = 0xffff00ff;
2514
2515     stat = GdipSetImageAttributesRemapTable(NULL, ColorAdjustTypeDefault, TRUE, 1, map);
2516     expect(InvalidParameter, stat);
2517
2518     stat = GdipCreateImageAttributes(&imageattr);
2519     expect(Ok, stat);
2520
2521     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, TRUE, 1, NULL);
2522     expect(InvalidParameter, stat);
2523
2524     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeCount, TRUE, 1, map);
2525     expect(InvalidParameter, stat);
2526
2527     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeAny, TRUE, 1, map);
2528     expect(InvalidParameter, stat);
2529
2530     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, TRUE, 0, map);
2531     expect(InvalidParameter, stat);
2532
2533     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, FALSE, 0, NULL);
2534     expect(Ok, stat);
2535
2536     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, TRUE, 1, map);
2537     expect(Ok, stat);
2538
2539     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap1);
2540     expect(Ok, stat);
2541
2542     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap2);
2543     expect(Ok, stat);
2544
2545     stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff00ff00);
2546     expect(Ok, stat);
2547
2548     stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
2549     expect(Ok, stat);
2550
2551     stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2552         UnitPixel, imageattr, NULL, NULL);
2553     expect(Ok, stat);
2554
2555     stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2556     expect(Ok, stat);
2557     ok(color_match(0xffff00ff, color, 1), "Expected ffff00ff, got %.8x\n", color);
2558
2559     GdipDeleteGraphics(graphics);
2560     GdipDisposeImage((GpImage*)bitmap1);
2561     GdipDisposeImage((GpImage*)bitmap2);
2562     GdipDisposeImageAttributes(imageattr);
2563     GdipFree(map);
2564 }
2565
2566 static void test_colorkey(void)
2567 {
2568     GpStatus stat;
2569     GpImageAttributes *imageattr;
2570     GpBitmap *bitmap1, *bitmap2;
2571     GpGraphics *graphics;
2572     ARGB color;
2573
2574     stat = GdipSetImageAttributesColorKeys(NULL, ColorAdjustTypeDefault, TRUE, 0xff405060, 0xff708090);
2575     expect(InvalidParameter, stat);
2576
2577     stat = GdipCreateImageAttributes(&imageattr);
2578     expect(Ok, stat);
2579
2580     stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeCount, TRUE, 0xff405060, 0xff708090);
2581     expect(InvalidParameter, stat);
2582
2583     stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeAny, TRUE, 0xff405060, 0xff708090);
2584     expect(InvalidParameter, stat);
2585
2586     stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeDefault, TRUE, 0xff405060, 0xff708090);
2587     expect(Ok, stat);
2588
2589     stat = GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB, NULL, &bitmap1);
2590     expect(Ok, stat);
2591
2592     stat = GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB, NULL, &bitmap2);
2593     expect(Ok, stat);
2594
2595     stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0x20405060);
2596     expect(Ok, stat);
2597
2598     stat = GdipBitmapSetPixel(bitmap1, 0, 1, 0x40506070);
2599     expect(Ok, stat);
2600
2601     stat = GdipBitmapSetPixel(bitmap1, 1, 0, 0x60708090);
2602     expect(Ok, stat);
2603
2604     stat = GdipBitmapSetPixel(bitmap1, 1, 1, 0xffffffff);
2605     expect(Ok, stat);
2606
2607     stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
2608     expect(Ok, stat);
2609
2610     stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,2,2, 0,0,2,2,
2611         UnitPixel, imageattr, NULL, NULL);
2612     expect(Ok, stat);
2613
2614     stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2615     expect(Ok, stat);
2616     ok(color_match(0x00000000, color, 1), "Expected ffff00ff, got %.8x\n", color);
2617
2618     stat = GdipBitmapGetPixel(bitmap2, 0, 1, &color);
2619     expect(Ok, stat);
2620     ok(color_match(0x00000000, color, 1), "Expected ffff00ff, got %.8x\n", color);
2621
2622     stat = GdipBitmapGetPixel(bitmap2, 1, 0, &color);
2623     expect(Ok, stat);
2624     ok(color_match(0x00000000, color, 1), "Expected ffff00ff, got %.8x\n", color);
2625
2626     stat = GdipBitmapGetPixel(bitmap2, 1, 1, &color);
2627     expect(Ok, stat);
2628     ok(color_match(0xffffffff, color, 1), "Expected ffff00ff, got %.8x\n", color);
2629
2630     GdipDeleteGraphics(graphics);
2631     GdipDisposeImage((GpImage*)bitmap1);
2632     GdipDisposeImage((GpImage*)bitmap2);
2633     GdipDisposeImageAttributes(imageattr);
2634 }
2635
2636 static void test_dispose(void)
2637 {
2638     GpStatus stat;
2639     GpImage *image;
2640     char invalid_image[256];
2641
2642     stat = GdipDisposeImage(NULL);
2643     expect(InvalidParameter, stat);
2644
2645     stat = GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB, NULL, (GpBitmap**)&image);
2646     expect(Ok, stat);
2647
2648     stat = GdipDisposeImage(image);
2649     expect(Ok, stat);
2650
2651     stat = GdipDisposeImage(image);
2652     expect(ObjectBusy, stat);
2653
2654     memset(invalid_image, 0, 256);
2655     stat = GdipDisposeImage((GpImage*)invalid_image);
2656     expect(ObjectBusy, stat);
2657 }
2658
2659 static LONG obj_refcount(void *obj)
2660 {
2661     IUnknown_AddRef((IUnknown *)obj);
2662     return IUnknown_Release((IUnknown *)obj);
2663 }
2664
2665 static GpImage *load_image(const BYTE *image_data, UINT image_size)
2666 {
2667     IStream *stream;
2668     HGLOBAL hmem;
2669     BYTE *data;
2670     HRESULT hr;
2671     GpStatus status;
2672     GpImage *image = NULL;
2673     ImageType image_type;
2674     LONG refcount;
2675
2676     hmem = GlobalAlloc(0, image_size);
2677     data = GlobalLock(hmem);
2678     memcpy(data, image_data, image_size);
2679     GlobalUnlock(hmem);
2680
2681     hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
2682     ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr);
2683     if (hr != S_OK) return NULL;
2684
2685     refcount = obj_refcount(stream);
2686     ok(refcount == 1, "expected stream refcount 1, got %d\n", refcount);
2687
2688     status = GdipLoadImageFromStream(stream, &image);
2689     ok(status == Ok, "GdipLoadImageFromStream error %d\n", status);
2690
2691     status = GdipGetImageType(image, &image_type);
2692     ok(status == Ok, "GdipGetImageType error %d\n", status);
2693
2694     refcount = IStream_Release(stream);
2695     if (image_type == ImageTypeBitmap)
2696         todo_wine ok(refcount >= 1, "expected stream refcount != 0\n");
2697     else
2698         ok(refcount == 0, "expected stream refcount 0, got %d\n", refcount);
2699
2700     return image;
2701 }
2702
2703 static void test_image_properties(void)
2704 {
2705     static const struct test_data
2706     {
2707         const BYTE *image_data;
2708         UINT image_size;
2709         ImageType image_type;
2710         UINT prop_count;
2711     }
2712     td[] =
2713     {
2714         { pngimage, sizeof(pngimage), ImageTypeBitmap, 4 },
2715         /* Win7 reports 4 properties, while everybody else just 1
2716         { gifimage, sizeof(gifimage), ImageTypeBitmap, 1 }, */
2717         { jpgimage, sizeof(jpgimage), ImageTypeBitmap, 2 },
2718         { tiffimage, sizeof(tiffimage), ImageTypeBitmap, 16 },
2719         { bmpimage, sizeof(bmpimage), ImageTypeBitmap, 0 },
2720         { wmfimage, sizeof(wmfimage), ImageTypeMetafile, 0 }
2721     };
2722     GpStatus status;
2723     GpImage *image;
2724     UINT prop_count, i;
2725     PROPID prop_id[16];
2726     ImageType image_type;
2727
2728     for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
2729     {
2730         image = load_image(td[i].image_data, td[i].image_size);
2731         ok(image != 0, "%u: failed to load image data\n", i);
2732         if (!image) continue;
2733
2734         status = GdipGetImageType(image, &image_type);
2735         ok(status == Ok, "%u: GdipGetImageType error %d\n", i, status);
2736         ok(td[i].image_type == image_type, "%u: expected image_type %d, got %d\n",
2737            i, td[i].image_type, image_type);
2738
2739         status = GdipGetPropertyCount(image, &prop_count);
2740         ok(status == Ok, "%u: GdipGetPropertyCount error %d\n", i, status);
2741         if (td[i].image_data == pngimage || td[i].image_data == gifimage ||
2742             td[i].image_data == jpgimage)
2743         todo_wine
2744         ok(td[i].prop_count == prop_count, " %u: expected property count %u, got %u\n",
2745            i, td[i].prop_count, prop_count);
2746         else
2747         ok(td[i].prop_count == prop_count, " %u: expected property count %u, got %u\n",
2748            i, td[i].prop_count, prop_count);
2749
2750         if (td[i].prop_count != prop_count)
2751         {
2752             GdipDisposeImage(image);
2753             continue;
2754         }
2755
2756         status = GdipGetPropertyIdList(NULL, prop_count, prop_id);
2757         expect(InvalidParameter, status);
2758         status = GdipGetPropertyIdList(image, prop_count, NULL);
2759         expect(InvalidParameter, status);
2760         status = GdipGetPropertyIdList(image, 0, prop_id);
2761         if (image_type == ImageTypeMetafile)
2762             expect(NotImplemented, status);
2763         else if (prop_count == 0)
2764             expect(Ok, status);
2765         else
2766             expect(InvalidParameter, status);
2767         status = GdipGetPropertyIdList(image, prop_count - 1, prop_id);
2768         if (image_type == ImageTypeMetafile)
2769             expect(NotImplemented, status);
2770         else
2771             expect(InvalidParameter, status);
2772         status = GdipGetPropertyIdList(image, prop_count + 1, prop_id);
2773         if (image_type == ImageTypeMetafile)
2774             expect(NotImplemented, status);
2775         else
2776             expect(InvalidParameter, status);
2777         status = GdipGetPropertyIdList(image, prop_count, prop_id);
2778         if (image_type == ImageTypeMetafile)
2779             expect(NotImplemented, status);
2780         else
2781             expect(Ok, status);
2782
2783         GdipDisposeImage(image);
2784     }
2785 }
2786
2787 START_TEST(image)
2788 {
2789     struct GdiplusStartupInput gdiplusStartupInput;
2790     ULONG_PTR gdiplusToken;
2791
2792     gdiplusStartupInput.GdiplusVersion              = 1;
2793     gdiplusStartupInput.DebugEventCallback          = NULL;
2794     gdiplusStartupInput.SuppressBackgroundThread    = 0;
2795     gdiplusStartupInput.SuppressExternalCodecs      = 0;
2796
2797     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
2798
2799     test_image_properties();
2800     test_Scan0();
2801     test_FromGdiDib();
2802     test_GetImageDimension();
2803     test_GdipImageGetFrameDimensionsCount();
2804     test_LoadingImages();
2805     test_SavingImages();
2806     test_encoders();
2807     test_LockBits();
2808     test_LockBits_UserBuf();
2809     test_GdipCreateBitmapFromHBITMAP();
2810     test_GdipGetImageFlags();
2811     test_GdipCloneImage();
2812     test_testcontrol();
2813     test_fromhicon();
2814     test_getrawformat();
2815     test_loadwmf();
2816     test_createfromwmf();
2817     test_resolution();
2818     test_createhbitmap();
2819     test_getthumbnail();
2820     test_getsetpixel();
2821     test_palette();
2822     test_colormatrix();
2823     test_gamma();
2824     test_multiframegif();
2825     test_rotateflip();
2826     test_remaptable();
2827     test_colorkey();
2828     test_dispose();
2829
2830     GdiplusShutdown(gdiplusToken);
2831 }