mshtml: Wine Gecko 1.4 release.
[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((UINT)(got) == (UINT)(expected), "Expected %.8x, got %.8x\n", (UINT)(expected), (UINT)(got))
31 #define expectf(expected, got) ok(fabs(expected - got) < 0.0001, "Expected %.2f, got %.2f\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(stat, Ok);
436
437     GdipDisposeImage((GpImage*)bm);
438     bm = 0;
439
440     /* re-load and check image stats */
441     stat = GdipLoadImageFromFile(filename, (GpImage**)&bm);
442     expect(stat, Ok);
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 static void test_GdipCreateBitmapFromHBITMAP(void)
835 {
836     GpBitmap* gpbm = NULL;
837     HBITMAP hbm = NULL;
838     HPALETTE hpal = NULL;
839     GpStatus stat;
840     BYTE buff[1000];
841     LOGPALETTE* LogPal = NULL;
842     REAL width, height;
843     const REAL WIDTH1 = 5;
844     const REAL HEIGHT1 = 15;
845     const REAL WIDTH2 = 10;
846     const REAL HEIGHT2 = 20;
847     HDC hdc;
848     BITMAPINFO bmi;
849     BYTE *bits;
850
851     stat = GdipCreateBitmapFromHBITMAP(NULL, NULL, NULL);
852     expect(InvalidParameter, stat);
853
854     hbm = CreateBitmap(WIDTH1, HEIGHT1, 1, 1, NULL);
855     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, NULL);
856     expect(InvalidParameter, stat);
857
858     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
859     expect(Ok, stat);
860     expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
861     expectf(WIDTH1,  width);
862     expectf(HEIGHT1, height);
863     if (stat == Ok)
864         GdipDisposeImage((GpImage*)gpbm);
865     DeleteObject(hbm);
866
867     memset(buff, 0, sizeof(buff));
868     hbm = CreateBitmap(WIDTH2, HEIGHT2, 1, 1, &buff);
869     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
870     expect(Ok, stat);
871     /* raw format */
872     expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)gpbm, __LINE__, FALSE);
873
874     expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
875     expectf(WIDTH2,  width);
876     expectf(HEIGHT2, height);
877     if (stat == Ok)
878         GdipDisposeImage((GpImage*)gpbm);
879     DeleteObject(hbm);
880
881     hdc = CreateCompatibleDC(0);
882     ok(hdc != NULL, "CreateCompatibleDC failed\n");
883     bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
884     bmi.bmiHeader.biHeight = HEIGHT1;
885     bmi.bmiHeader.biWidth = WIDTH1;
886     bmi.bmiHeader.biBitCount = 24;
887     bmi.bmiHeader.biPlanes = 1;
888     bmi.bmiHeader.biCompression = BI_RGB;
889     bmi.bmiHeader.biClrUsed = 0;
890
891     hbm = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
892     ok(hbm != NULL, "CreateDIBSection failed\n");
893
894     bits[0] = 0;
895
896     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
897     expect(Ok, stat);
898     expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
899     expectf(WIDTH1,  width);
900     expectf(HEIGHT1, height);
901     if (stat == Ok)
902     {
903         /* test whether writing to the bitmap affects the original */
904         stat = GdipBitmapSetPixel(gpbm, 0, 0, 0xffffffff);
905         expect(Ok, stat);
906
907         expect(0, bits[0]);
908
909         GdipDisposeImage((GpImage*)gpbm);
910     }
911
912     LogPal = GdipAlloc(sizeof(LOGPALETTE));
913     ok(LogPal != NULL, "unable to allocate LOGPALETTE\n");
914     LogPal->palVersion = 0x300;
915     LogPal->palNumEntries = 1;
916     hpal = CreatePalette(LogPal);
917     ok(hpal != NULL, "CreatePalette failed\n");
918     GdipFree(LogPal);
919
920     stat = GdipCreateBitmapFromHBITMAP(hbm, hpal, &gpbm);
921     expect(Ok, stat);
922
923     if (stat == Ok)
924         GdipDisposeImage((GpImage*)gpbm);
925
926     DeleteObject(hpal);
927     DeleteObject(hbm);
928 }
929
930 static void test_GdipGetImageFlags(void)
931 {
932     GpImage *img;
933     GpStatus stat;
934     UINT flags;
935
936     img = (GpImage*)0xdeadbeef;
937
938     stat = GdipGetImageFlags(NULL, NULL);
939     expect(InvalidParameter, stat);
940
941     stat = GdipGetImageFlags(NULL, &flags);
942     expect(InvalidParameter, stat);
943
944     stat = GdipGetImageFlags(img, NULL);
945     expect(InvalidParameter, stat);
946
947     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat1bppIndexed, NULL, (GpBitmap**)&img);
948     expect(Ok, stat);
949     stat = GdipGetImageFlags(img, &flags);
950     expect(Ok, stat);
951     expect(ImageFlagsHasAlpha, flags);
952     GdipDisposeImage(img);
953
954     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat4bppIndexed, NULL, (GpBitmap**)&img);
955     expect(Ok, stat);
956     stat = GdipGetImageFlags(img, &flags);
957     expect(Ok, stat);
958     expect(ImageFlagsHasAlpha, flags);
959     GdipDisposeImage(img);
960
961     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat8bppIndexed, NULL, (GpBitmap**)&img);
962     expect(Ok, stat);
963     stat = GdipGetImageFlags(img, &flags);
964     expect(Ok, stat);
965     expect(ImageFlagsHasAlpha, flags);
966     GdipDisposeImage(img);
967
968     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppGrayScale, NULL, (GpBitmap**)&img);
969     expect(Ok, stat);
970     stat = GdipGetImageFlags(img, &flags);
971     expect(Ok, stat);
972     expect(ImageFlagsNone, flags);
973     GdipDisposeImage(img);
974
975     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB555, NULL, (GpBitmap**)&img);
976     expect(Ok, stat);
977     stat = GdipGetImageFlags(img, &flags);
978     expect(Ok, stat);
979     expect(ImageFlagsNone, flags);
980     GdipDisposeImage(img);
981
982     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB565, NULL, (GpBitmap**)&img);
983     expect(Ok, stat);
984     stat = GdipGetImageFlags(img, &flags);
985     expect(Ok, stat);
986     expect(ImageFlagsNone, flags);
987     GdipDisposeImage(img);
988
989     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppARGB1555, NULL, (GpBitmap**)&img);
990     expect(Ok, stat);
991     stat = GdipGetImageFlags(img, &flags);
992     expect(Ok, stat);
993     expect(ImageFlagsHasAlpha, flags);
994     GdipDisposeImage(img);
995
996     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, NULL, (GpBitmap**)&img);
997     expect(Ok, stat);
998     stat = GdipGetImageFlags(img, &flags);
999     expect(Ok, stat);
1000     expect(ImageFlagsNone, flags);
1001     GdipDisposeImage(img);
1002
1003     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppRGB, NULL, (GpBitmap**)&img);
1004     expect(Ok, stat);
1005     stat = GdipGetImageFlags(img, &flags);
1006     expect(Ok, stat);
1007     expect(ImageFlagsNone, flags);
1008     GdipDisposeImage(img);
1009
1010     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppARGB, NULL, (GpBitmap**)&img);
1011     expect(Ok, stat);
1012     stat = GdipGetImageFlags(img, &flags);
1013     expect(Ok, stat);
1014     expect(ImageFlagsHasAlpha, flags);
1015     GdipDisposeImage(img);
1016
1017     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppPARGB, NULL, (GpBitmap**)&img);
1018     expect(Ok, stat);
1019     stat = GdipGetImageFlags(img, &flags);
1020     expect(Ok, stat);
1021     expect(ImageFlagsHasAlpha, flags);
1022     GdipDisposeImage(img);
1023
1024     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat48bppRGB, NULL, (GpBitmap**)&img);
1025     expect(Ok, stat);
1026     if (stat == Ok)
1027     {
1028         stat = GdipGetImageFlags(img, &flags);
1029         expect(Ok, stat);
1030         expect(ImageFlagsNone, flags);
1031         GdipDisposeImage(img);
1032     }
1033
1034     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB, NULL, (GpBitmap**)&img);
1035     expect(Ok, stat);
1036     if (stat == Ok)
1037     {
1038         expect(Ok, stat);
1039         stat = GdipGetImageFlags(img, &flags);
1040         expect(Ok, stat);
1041         expect(ImageFlagsHasAlpha, flags);
1042         GdipDisposeImage(img);
1043     }
1044
1045     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB, NULL, (GpBitmap**)&img);
1046     expect(Ok, stat);
1047     if (stat == Ok)
1048     {
1049         expect(Ok, stat);
1050         stat = GdipGetImageFlags(img, &flags);
1051         expect(Ok, stat);
1052         expect(ImageFlagsHasAlpha, flags);
1053         GdipDisposeImage(img);
1054     }
1055 }
1056
1057 static void test_GdipCloneImage(void)
1058 {
1059     GpStatus stat;
1060     GpRectF rectF;
1061     GpUnit unit;
1062     GpBitmap *bm;
1063     GpImage *image_src, *image_dest = NULL;
1064     const INT WIDTH = 10, HEIGHT = 20;
1065
1066     /* Create an image, clone it, delete the original, make sure the copy works */
1067     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
1068     expect(Ok, stat);
1069     expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bm, __LINE__, FALSE);
1070
1071     image_src = ((GpImage*)bm);
1072     stat = GdipCloneImage(image_src, &image_dest);
1073     expect(Ok, stat);
1074     expect_rawformat(&ImageFormatMemoryBMP, image_dest, __LINE__, FALSE);
1075
1076     stat = GdipDisposeImage((GpImage*)bm);
1077     expect(Ok, stat);
1078     stat = GdipGetImageBounds(image_dest, &rectF, &unit);
1079     expect(Ok, stat);
1080
1081     /* Treat FP values carefully */
1082     expectf((REAL)WIDTH, rectF.Width);
1083     expectf((REAL)HEIGHT, rectF.Height);
1084
1085     stat = GdipDisposeImage(image_dest);
1086     expect(Ok, stat);
1087 }
1088
1089 static void test_testcontrol(void)
1090 {
1091     GpStatus stat;
1092     DWORD param;
1093
1094     param = 0;
1095     stat = GdipTestControl(TestControlGetBuildNumber, &param);
1096     expect(Ok, stat);
1097     ok(param != 0, "Build number expected, got %u\n", param);
1098 }
1099
1100 static void test_fromhicon(void)
1101 {
1102     static const BYTE bmp_bits[1024];
1103     HBITMAP hbmMask, hbmColor;
1104     ICONINFO info;
1105     HICON hIcon;
1106     GpStatus stat;
1107     GpBitmap *bitmap = NULL;
1108     UINT dim;
1109     ImageType type;
1110     PixelFormat format;
1111
1112     /* NULL */
1113     stat = GdipCreateBitmapFromHICON(NULL, NULL);
1114     expect(InvalidParameter, stat);
1115     stat = GdipCreateBitmapFromHICON(NULL, &bitmap);
1116     expect(InvalidParameter, stat);
1117
1118     /* color icon 1 bit */
1119     hbmMask = CreateBitmap(16, 16, 1, 1, bmp_bits);
1120     ok(hbmMask != 0, "CreateBitmap failed\n");
1121     hbmColor = CreateBitmap(16, 16, 1, 1, bmp_bits);
1122     ok(hbmColor != 0, "CreateBitmap failed\n");
1123     info.fIcon = TRUE;
1124     info.xHotspot = 8;
1125     info.yHotspot = 8;
1126     info.hbmMask = hbmMask;
1127     info.hbmColor = hbmColor;
1128     hIcon = CreateIconIndirect(&info);
1129     ok(hIcon != 0, "CreateIconIndirect failed\n");
1130     DeleteObject(hbmMask);
1131     DeleteObject(hbmColor);
1132
1133     stat = GdipCreateBitmapFromHICON(hIcon, &bitmap);
1134     ok(stat == Ok ||
1135        broken(stat == InvalidParameter), /* Win98 */
1136        "Expected Ok, got %.8x\n", stat);
1137     if(stat == Ok){
1138        /* check attributes */
1139        stat = GdipGetImageHeight((GpImage*)bitmap, &dim);
1140        expect(Ok, stat);
1141        expect(16, dim);
1142        stat = GdipGetImageWidth((GpImage*)bitmap, &dim);
1143        expect(Ok, stat);
1144        expect(16, dim);
1145        stat = GdipGetImageType((GpImage*)bitmap, &type);
1146        expect(Ok, stat);
1147        expect(ImageTypeBitmap, type);
1148        stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format);
1149        expect(Ok, stat);
1150        expect(PixelFormat32bppARGB, format);
1151        /* raw format */
1152        expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
1153        GdipDisposeImage((GpImage*)bitmap);
1154     }
1155     DestroyIcon(hIcon);
1156
1157     /* color icon 8 bpp */
1158     hbmMask = CreateBitmap(16, 16, 1, 8, bmp_bits);
1159     ok(hbmMask != 0, "CreateBitmap failed\n");
1160     hbmColor = CreateBitmap(16, 16, 1, 8, bmp_bits);
1161     ok(hbmColor != 0, "CreateBitmap failed\n");
1162     info.fIcon = TRUE;
1163     info.xHotspot = 8;
1164     info.yHotspot = 8;
1165     info.hbmMask = hbmMask;
1166     info.hbmColor = hbmColor;
1167     hIcon = CreateIconIndirect(&info);
1168     ok(hIcon != 0, "CreateIconIndirect failed\n");
1169     DeleteObject(hbmMask);
1170     DeleteObject(hbmColor);
1171
1172     stat = GdipCreateBitmapFromHICON(hIcon, &bitmap);
1173     expect(Ok, stat);
1174     if(stat == Ok){
1175         /* check attributes */
1176         stat = GdipGetImageHeight((GpImage*)bitmap, &dim);
1177         expect(Ok, stat);
1178         expect(16, dim);
1179         stat = GdipGetImageWidth((GpImage*)bitmap, &dim);
1180         expect(Ok, stat);
1181         expect(16, dim);
1182         stat = GdipGetImageType((GpImage*)bitmap, &type);
1183         expect(Ok, stat);
1184         expect(ImageTypeBitmap, type);
1185         stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format);
1186         expect(Ok, stat);
1187         expect(PixelFormat32bppARGB, format);
1188         /* raw format */
1189         expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
1190         GdipDisposeImage((GpImage*)bitmap);
1191     }
1192     DestroyIcon(hIcon);
1193 }
1194
1195 /* 1x1 pixel png */
1196 static const unsigned char pngimage[285] = {
1197 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
1198 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
1199 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
1200 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
1201 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
1202 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
1203 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
1204 };
1205 /* 1x1 pixel gif */
1206 static const unsigned char gifimage[35] = {
1207 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
1208 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
1209 0x01,0x00,0x3b
1210 };
1211 /* 1x1 pixel bmp */
1212 static const unsigned char bmpimage[66] = {
1213 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
1214 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
1215 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
1216 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
1217 0x00,0x00
1218 };
1219 /* 1x1 pixel jpg */
1220 static const unsigned char jpgimage[285] = {
1221 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
1222 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
1223 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
1224 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
1225 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
1226 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
1227 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
1228 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1229 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1230 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
1231 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
1232 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1233 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
1234 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
1235 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1236 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
1237 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
1238 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
1239 };
1240 /* 1x1 pixel tiff */
1241 static const unsigned char tiffimage[] = {
1242 0x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00,
1243 0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00,
1244 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1245 0x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01,
1246 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00,
1247 0x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00,
1248 0x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01,
1249 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00,
1250 0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00,
1251 0x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01,
1252 0x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00,
1253 0x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1254 0x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
1255 0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65,
1256 0x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74,
1257 0x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,
1258 0x00,0x00,0x00,0x01
1259 };
1260 /* 320x320 twip wmf */
1261 static const unsigned char wmfimage[180] = {
1262 0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05,
1263 0x00,0x00,0x00,0x00,0xb1,0x52,0x01,0x00,0x09,0x00,0x00,0x03,0x4f,0x00,0x00,0x00,
1264 0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0b,0x02,0x00,0x00,
1265 0x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x02,0x40,0x01,0x40,0x01,0x04,0x00,0x00,0x00,
1266 0x02,0x01,0x01,0x00,0x04,0x00,0x00,0x00,0x04,0x01,0x0d,0x00,0x08,0x00,0x00,0x00,
1267 0xfa,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
1268 0x2d,0x01,0x00,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,0x01,0x00,0x00,0x00,0x00,0x00,
1269 0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x01,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,
1270 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x02,0x00,
1271 0x07,0x00,0x00,0x00,0x1b,0x04,0x40,0x01,0x40,0x01,0x00,0x00,0x00,0x00,0x04,0x00,
1272 0x00,0x00,0xf0,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0xf0,0x01,0x01,0x00,0x03,0x00,
1273 0x00,0x00,0x00,0x00
1274 };
1275 static void test_getrawformat(void)
1276 {
1277     test_bufferrawformat((void*)pngimage, sizeof(pngimage), &ImageFormatPNG,  __LINE__, FALSE);
1278     test_bufferrawformat((void*)gifimage, sizeof(gifimage), &ImageFormatGIF,  __LINE__, FALSE);
1279     test_bufferrawformat((void*)bmpimage, sizeof(bmpimage), &ImageFormatBMP,  __LINE__, FALSE);
1280     test_bufferrawformat((void*)jpgimage, sizeof(jpgimage), &ImageFormatJPEG, __LINE__, FALSE);
1281     test_bufferrawformat((void*)tiffimage, sizeof(tiffimage), &ImageFormatTIFF, __LINE__, FALSE);
1282     test_bufferrawformat((void*)wmfimage, sizeof(wmfimage), &ImageFormatWMF, __LINE__, FALSE);
1283 }
1284
1285 static void test_loadwmf(void)
1286 {
1287     LPSTREAM stream;
1288     HGLOBAL  hglob;
1289     LPBYTE   data;
1290     HRESULT  hres;
1291     GpStatus stat;
1292     GpImage *img;
1293     GpRectF bounds;
1294     GpUnit unit;
1295     REAL res = 12345.0;
1296     MetafileHeader header;
1297
1298     hglob = GlobalAlloc (0, sizeof(wmfimage));
1299     data = GlobalLock (hglob);
1300     memcpy(data, wmfimage, sizeof(wmfimage));
1301     GlobalUnlock(hglob); data = NULL;
1302
1303     hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
1304     ok(hres == S_OK, "Failed to create a stream\n");
1305     if(hres != S_OK) return;
1306
1307     stat = GdipLoadImageFromStream(stream, &img);
1308     ok(stat == Ok, "Failed to create a Bitmap\n");
1309     if(stat != Ok){
1310         IStream_Release(stream);
1311         return;
1312     }
1313
1314     IStream_Release(stream);
1315
1316     stat = GdipGetImageBounds(img, &bounds, &unit);
1317     expect(Ok, stat);
1318     todo_wine expect(UnitPixel, unit);
1319     expectf(0.0, bounds.X);
1320     expectf(0.0, bounds.Y);
1321     todo_wine expectf(320.0, bounds.Width);
1322     todo_wine expectf(320.0, bounds.Height);
1323
1324     stat = GdipGetImageHorizontalResolution(img, &res);
1325     expect(Ok, stat);
1326     todo_wine expectf(1440.0, res);
1327
1328     stat = GdipGetImageVerticalResolution(img, &res);
1329     expect(Ok, stat);
1330     todo_wine expectf(1440.0, res);
1331
1332     memset(&header, 0, sizeof(header));
1333     stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header);
1334     expect(Ok, stat);
1335     if (stat == Ok)
1336     {
1337         todo_wine expect(MetafileTypeWmfPlaceable, header.Type);
1338         todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size);
1339         todo_wine expect(0x300, header.Version);
1340         expect(0, header.EmfPlusFlags);
1341         todo_wine expectf(1440.0, header.DpiX);
1342         todo_wine expectf(1440.0, header.DpiY);
1343         expect(0, header.X);
1344         expect(0, header.Y);
1345         todo_wine expect(320, header.Width);
1346         todo_wine expect(320, header.Height);
1347         todo_wine expect(1, U(header).WmfHeader.mtType);
1348         expect(0, header.EmfPlusHeaderSize);
1349         expect(0, header.LogicalDpiX);
1350         expect(0, header.LogicalDpiY);
1351     }
1352
1353     GdipDisposeImage(img);
1354 }
1355
1356 static void test_createfromwmf(void)
1357 {
1358     HMETAFILE hwmf;
1359     GpImage *img;
1360     GpStatus stat;
1361     GpRectF bounds;
1362     GpUnit unit;
1363     REAL res = 12345.0;
1364     MetafileHeader header;
1365
1366     hwmf = SetMetaFileBitsEx(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader),
1367         wmfimage+sizeof(WmfPlaceableFileHeader));
1368     ok(hwmf != 0, "SetMetaFileBitsEx failed\n");
1369
1370     stat = GdipCreateMetafileFromWmf(hwmf, TRUE,
1371         (WmfPlaceableFileHeader*)wmfimage, (GpMetafile**)&img);
1372     expect(Ok, stat);
1373
1374     stat = GdipGetImageBounds(img, &bounds, &unit);
1375     expect(Ok, stat);
1376     expect(UnitPixel, unit);
1377     expectf(0.0, bounds.X);
1378     expectf(0.0, bounds.Y);
1379     expectf(320.0, bounds.Width);
1380     expectf(320.0, bounds.Height);
1381
1382     stat = GdipGetImageHorizontalResolution(img, &res);
1383     expect(Ok, stat);
1384     expectf(1440.0, res);
1385
1386     stat = GdipGetImageVerticalResolution(img, &res);
1387     expect(Ok, stat);
1388     expectf(1440.0, res);
1389
1390     memset(&header, 0, sizeof(header));
1391     stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header);
1392     expect(Ok, stat);
1393     if (stat == Ok)
1394     {
1395         todo_wine expect(MetafileTypeWmfPlaceable, header.Type);
1396         todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size);
1397         todo_wine expect(0x300, header.Version);
1398         expect(0, header.EmfPlusFlags);
1399         todo_wine expectf(1440.0, header.DpiX);
1400         todo_wine expectf(1440.0, header.DpiY);
1401         expect(0, header.X);
1402         expect(0, header.Y);
1403         todo_wine expect(320, header.Width);
1404         todo_wine expect(320, header.Height);
1405         todo_wine expect(1, U(header).WmfHeader.mtType);
1406         expect(0, header.EmfPlusHeaderSize);
1407         expect(0, header.LogicalDpiX);
1408         expect(0, header.LogicalDpiY);
1409     }
1410
1411     GdipDisposeImage(img);
1412 }
1413
1414 static void test_resolution(void)
1415 {
1416     GpStatus stat;
1417     GpBitmap *bitmap;
1418     REAL res=-1.0;
1419     HDC screendc;
1420     int screenxres, screenyres;
1421
1422     /* create Bitmap */
1423     stat = GdipCreateBitmapFromScan0(1, 1, 32, PixelFormat24bppRGB, NULL, &bitmap);
1424     expect(Ok, stat);
1425
1426     /* test invalid values */
1427     stat = GdipGetImageHorizontalResolution(NULL, &res);
1428     expect(InvalidParameter, stat);
1429
1430     stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, NULL);
1431     expect(InvalidParameter, stat);
1432
1433     stat = GdipGetImageVerticalResolution(NULL, &res);
1434     expect(InvalidParameter, stat);
1435
1436     stat = GdipGetImageVerticalResolution((GpImage*)bitmap, NULL);
1437     expect(InvalidParameter, stat);
1438
1439     stat = GdipBitmapSetResolution(NULL, 96.0, 96.0);
1440     expect(InvalidParameter, stat);
1441
1442     stat = GdipBitmapSetResolution(bitmap, 0.0, 0.0);
1443     expect(InvalidParameter, stat);
1444
1445     /* defaults to screen resolution */
1446     screendc = GetDC(0);
1447
1448     screenxres = GetDeviceCaps(screendc, LOGPIXELSX);
1449     screenyres = GetDeviceCaps(screendc, LOGPIXELSY);
1450
1451     ReleaseDC(0, screendc);
1452
1453     stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, &res);
1454     expect(Ok, stat);
1455     expectf((REAL)screenxres, res);
1456
1457     stat = GdipGetImageVerticalResolution((GpImage*)bitmap, &res);
1458     expect(Ok, stat);
1459     expectf((REAL)screenyres, res);
1460
1461     /* test changing the resolution */
1462     stat = GdipBitmapSetResolution(bitmap, screenxres*2.0, screenyres*3.0);
1463     expect(Ok, stat);
1464
1465     stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, &res);
1466     expect(Ok, stat);
1467     expectf(screenxres*2.0, res);
1468
1469     stat = GdipGetImageVerticalResolution((GpImage*)bitmap, &res);
1470     expect(Ok, stat);
1471     expectf(screenyres*3.0, res);
1472
1473     stat = GdipDisposeImage((GpImage*)bitmap);
1474     expect(Ok, stat);
1475 }
1476
1477 static void test_createhbitmap(void)
1478 {
1479     GpStatus stat;
1480     GpBitmap *bitmap;
1481     HBITMAP hbitmap, oldhbitmap;
1482     BITMAP bm;
1483     int ret;
1484     HDC hdc;
1485     COLORREF pixel;
1486     BYTE bits[640];
1487
1488     memset(bits, 0x68, 640);
1489
1490     /* create Bitmap */
1491     stat = GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB, bits, &bitmap);
1492     expect(Ok, stat);
1493
1494     /* test NULL values */
1495     stat = GdipCreateHBITMAPFromBitmap(NULL, &hbitmap, 0);
1496     expect(InvalidParameter, stat);
1497
1498     stat = GdipCreateHBITMAPFromBitmap(bitmap, NULL, 0);
1499     expect(InvalidParameter, stat);
1500
1501     /* create HBITMAP */
1502     stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0);
1503     expect(Ok, stat);
1504
1505     if (stat == Ok)
1506     {
1507         ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
1508         expect(sizeof(BITMAP), ret);
1509
1510         expect(0, bm.bmType);
1511         expect(10, bm.bmWidth);
1512         expect(20, bm.bmHeight);
1513         expect(40, bm.bmWidthBytes);
1514         expect(1, bm.bmPlanes);
1515         expect(32, bm.bmBitsPixel);
1516         ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
1517
1518         if (bm.bmBits)
1519         {
1520             DWORD val = *(DWORD*)bm.bmBits;
1521             ok(val == 0xff686868, "got %x, expected 0xff686868\n", val);
1522         }
1523
1524         hdc = CreateCompatibleDC(NULL);
1525
1526         oldhbitmap = SelectObject(hdc, hbitmap);
1527         pixel = GetPixel(hdc, 5, 5);
1528         SelectObject(hdc, oldhbitmap);
1529
1530         DeleteDC(hdc);
1531
1532         expect(0x686868, pixel);
1533
1534         DeleteObject(hbitmap);
1535     }
1536
1537     stat = GdipDisposeImage((GpImage*)bitmap);
1538     expect(Ok, stat);
1539
1540     /* create alpha Bitmap */
1541     stat = GdipCreateBitmapFromScan0(8, 20, 32, PixelFormat32bppARGB, bits, &bitmap);
1542     expect(Ok, stat);
1543
1544     /* create HBITMAP */
1545     stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0);
1546     expect(Ok, stat);
1547
1548     if (stat == Ok)
1549     {
1550         ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
1551         expect(sizeof(BITMAP), ret);
1552
1553         expect(0, bm.bmType);
1554         expect(8, bm.bmWidth);
1555         expect(20, bm.bmHeight);
1556         expect(32, bm.bmWidthBytes);
1557         expect(1, bm.bmPlanes);
1558         expect(32, bm.bmBitsPixel);
1559         ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
1560
1561         if (bm.bmBits)
1562         {
1563             DWORD val = *(DWORD*)bm.bmBits;
1564             ok(val == 0x682a2a2a, "got %x, expected 0x682a2a2a\n", val);
1565         }
1566
1567         hdc = CreateCompatibleDC(NULL);
1568
1569         oldhbitmap = SelectObject(hdc, hbitmap);
1570         pixel = GetPixel(hdc, 5, 5);
1571         SelectObject(hdc, oldhbitmap);
1572
1573         DeleteDC(hdc);
1574
1575         expect(0x2a2a2a, pixel);
1576
1577         DeleteObject(hbitmap);
1578     }
1579
1580     stat = GdipDisposeImage((GpImage*)bitmap);
1581     expect(Ok, stat);
1582 }
1583
1584 static void test_getthumbnail(void)
1585 {
1586     GpStatus stat;
1587     GpImage *bitmap1, *bitmap2;
1588     UINT width, height;
1589
1590     stat = GdipGetImageThumbnail(NULL, 0, 0, &bitmap2, NULL, NULL);
1591     expect(InvalidParameter, stat);
1592
1593     stat = GdipCreateBitmapFromScan0(128, 128, 0, PixelFormat32bppRGB, NULL, (GpBitmap**)&bitmap1);
1594     expect(Ok, stat);
1595
1596     stat = GdipGetImageThumbnail(bitmap1, 0, 0, NULL, NULL, NULL);
1597     expect(InvalidParameter, stat);
1598
1599     stat = GdipGetImageThumbnail(bitmap1, 0, 0, &bitmap2, NULL, NULL);
1600     expect(Ok, stat);
1601
1602     if (stat == Ok)
1603     {
1604         stat = GdipGetImageWidth(bitmap2, &width);
1605         expect(Ok, stat);
1606         expect(120, width);
1607
1608         stat = GdipGetImageHeight(bitmap2, &height);
1609         expect(Ok, stat);
1610         expect(120, height);
1611
1612         GdipDisposeImage(bitmap2);
1613     }
1614
1615     GdipDisposeImage(bitmap1);
1616
1617
1618     stat = GdipCreateBitmapFromScan0(64, 128, 0, PixelFormat32bppRGB, NULL, (GpBitmap**)&bitmap1);
1619     expect(Ok, stat);
1620
1621     stat = GdipGetImageThumbnail(bitmap1, 32, 32, &bitmap2, NULL, NULL);
1622     expect(Ok, stat);
1623
1624     if (stat == Ok)
1625     {
1626         stat = GdipGetImageWidth(bitmap2, &width);
1627         expect(Ok, stat);
1628         expect(32, width);
1629
1630         stat = GdipGetImageHeight(bitmap2, &height);
1631         expect(Ok, stat);
1632         expect(32, height);
1633
1634         GdipDisposeImage(bitmap2);
1635     }
1636
1637     stat = GdipGetImageThumbnail(bitmap1, 0, 0, &bitmap2, NULL, NULL);
1638     expect(Ok, stat);
1639
1640     if (stat == Ok)
1641     {
1642         stat = GdipGetImageWidth(bitmap2, &width);
1643         expect(Ok, stat);
1644         expect(120, width);
1645
1646         stat = GdipGetImageHeight(bitmap2, &height);
1647         expect(Ok, stat);
1648         expect(120, height);
1649
1650         GdipDisposeImage(bitmap2);
1651     }
1652
1653     GdipDisposeImage(bitmap1);
1654 }
1655
1656 static void test_getsetpixel(void)
1657 {
1658     GpStatus stat;
1659     GpBitmap *bitmap;
1660     ARGB color;
1661     BYTE bits[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00,
1662                      0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00};
1663
1664     stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB, bits, &bitmap);
1665     expect(Ok, stat);
1666
1667     /* null parameters */
1668     stat = GdipBitmapGetPixel(NULL, 1, 1, &color);
1669     expect(InvalidParameter, stat);
1670
1671     stat = GdipBitmapGetPixel(bitmap, 1, 1, NULL);
1672     expect(InvalidParameter, stat);
1673
1674     stat = GdipBitmapSetPixel(NULL, 1, 1, 0);
1675     expect(InvalidParameter, stat);
1676
1677     /* out of bounds */
1678     stat = GdipBitmapGetPixel(bitmap, -1, 1, &color);
1679     expect(InvalidParameter, stat);
1680
1681     stat = GdipBitmapSetPixel(bitmap, -1, 1, 0);
1682     expect(InvalidParameter, stat);
1683
1684     stat = GdipBitmapGetPixel(bitmap, 1, -1, &color);
1685     ok(stat == InvalidParameter ||
1686        broken(stat == Ok), /* Older gdiplus */
1687        "Expected InvalidParameter, got %.8x\n", stat);
1688
1689     stat = GdipBitmapSetPixel(bitmap, 1, -1, 0);
1690     ok(stat == InvalidParameter ||
1691        broken(stat == Ok), /* Older gdiplus */
1692        "Expected InvalidParameter, got %.8x\n", stat);
1693
1694     stat = GdipBitmapGetPixel(bitmap, 2, 1, &color);
1695     expect(InvalidParameter, stat);
1696
1697     stat = GdipBitmapSetPixel(bitmap, 2, 1, 0);
1698     expect(InvalidParameter, stat);
1699
1700     stat = GdipBitmapGetPixel(bitmap, 1, 2, &color);
1701     expect(InvalidParameter, stat);
1702
1703     stat = GdipBitmapSetPixel(bitmap, 1, 2, 0);
1704     expect(InvalidParameter, stat);
1705
1706     /* valid use */
1707     stat = GdipBitmapGetPixel(bitmap, 1, 1, &color);
1708     expect(Ok, stat);
1709     expect(0xffffffff, color);
1710
1711     stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
1712     expect(Ok, stat);
1713     expect(0xff0000ff, color);
1714
1715     stat = GdipBitmapSetPixel(bitmap, 1, 1, 0xff676869);
1716     expect(Ok, stat);
1717
1718     stat = GdipBitmapSetPixel(bitmap, 0, 0, 0xff474849);
1719     expect(Ok, stat);
1720
1721     stat = GdipBitmapGetPixel(bitmap, 1, 1, &color);
1722     expect(Ok, stat);
1723     expect(0xff676869, color);
1724
1725     stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
1726     expect(Ok, stat);
1727     expect(0xff474849, color);
1728
1729     stat = GdipDisposeImage((GpImage*)bitmap);
1730     expect(Ok, stat);
1731 }
1732
1733 static void check_halftone_palette(ColorPalette *palette)
1734 {
1735     static const BYTE halftone_values[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
1736     UINT i;
1737
1738     for (i=0; i<palette->Count; i++)
1739     {
1740         ARGB expected=0xff000000;
1741         if (i<8)
1742         {
1743             if (i&1) expected |= 0x800000;
1744             if (i&2) expected |= 0x8000;
1745             if (i&4) expected |= 0x80;
1746         }
1747         else if (i == 8)
1748         {
1749             expected = 0xffc0c0c0;
1750         }
1751         else if (i < 16)
1752         {
1753             if (i&1) expected |= 0xff0000;
1754             if (i&2) expected |= 0xff00;
1755             if (i&4) expected |= 0xff;
1756         }
1757         else if (i < 40)
1758         {
1759             expected = 0x00000000;
1760         }
1761         else
1762         {
1763             expected |= halftone_values[(i-40)%6];
1764             expected |= halftone_values[((i-40)/6)%6] << 8;
1765             expected |= halftone_values[((i-40)/36)%6] << 16;
1766         }
1767         ok(expected == palette->Entries[i], "Expected %.8x, got %.8x, i=%u/%u\n",
1768             expected, palette->Entries[i], i, palette->Count);
1769     }
1770 }
1771
1772 static void test_palette(void)
1773 {
1774     GpStatus stat;
1775     GpBitmap *bitmap;
1776     INT size;
1777     BYTE buffer[1040];
1778     ColorPalette *palette=(ColorPalette*)buffer;
1779     ARGB *entries = palette->Entries;
1780     ARGB color=0;
1781
1782     /* test initial palette from non-indexed bitmap */
1783     stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB, NULL, &bitmap);
1784     expect(Ok, stat);
1785
1786     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1787     expect(Ok, stat);
1788     expect(sizeof(UINT)*2+sizeof(ARGB), size);
1789
1790     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1791     expect(Ok, stat);
1792     expect(0, palette->Count);
1793
1794     /* test setting palette on not-indexed bitmap */
1795     palette->Count = 3;
1796
1797     stat = GdipSetImagePalette((GpImage*)bitmap, palette);
1798     expect(Ok, stat);
1799
1800     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1801     expect(Ok, stat);
1802     expect(sizeof(UINT)*2+sizeof(ARGB)*3, size);
1803
1804     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1805     expect(Ok, stat);
1806     expect(3, palette->Count);
1807
1808     GdipDisposeImage((GpImage*)bitmap);
1809
1810     /* test initial palette on 1-bit bitmap */
1811     stat = GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat1bppIndexed, NULL, &bitmap);
1812     expect(Ok, stat);
1813
1814     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1815     expect(Ok, stat);
1816     expect(sizeof(UINT)*2+sizeof(ARGB)*2, size);
1817
1818     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1819     expect(Ok, stat);
1820     expect(PaletteFlagsGrayScale, palette->Flags);
1821     expect(2, palette->Count);
1822
1823     expect(0xff000000, entries[0]);
1824     expect(0xffffffff, entries[1]);
1825
1826     /* test getting/setting pixels */
1827     stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
1828     expect(Ok, stat);
1829     expect(0xff000000, color);
1830
1831     stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffffffff);
1832     ok((stat == Ok) ||
1833        broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
1834
1835     if (stat == Ok)
1836     {
1837         stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
1838         expect(Ok, stat);
1839         expect(0xffffffff, color);
1840     }
1841
1842     GdipDisposeImage((GpImage*)bitmap);
1843
1844     /* test initial palette on 4-bit bitmap */
1845     stat = GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat4bppIndexed, NULL, &bitmap);
1846     expect(Ok, stat);
1847
1848     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1849     expect(Ok, stat);
1850     expect(sizeof(UINT)*2+sizeof(ARGB)*16, size);
1851
1852     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1853     expect(Ok, stat);
1854     expect(0, palette->Flags);
1855     expect(16, palette->Count);
1856
1857     check_halftone_palette(palette);
1858
1859     /* test getting/setting pixels */
1860     stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
1861     expect(Ok, stat);
1862     expect(0xff000000, color);
1863
1864     stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffff00ff);
1865     ok((stat == Ok) ||
1866        broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
1867
1868     if (stat == Ok)
1869     {
1870         stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
1871         expect(Ok, stat);
1872         expect(0xffff00ff, color);
1873     }
1874
1875     GdipDisposeImage((GpImage*)bitmap);
1876
1877     /* test initial palette on 8-bit bitmap */
1878     stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat8bppIndexed, NULL, &bitmap);
1879     expect(Ok, stat);
1880
1881     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1882     expect(Ok, stat);
1883     expect(sizeof(UINT)*2+sizeof(ARGB)*256, size);
1884
1885     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1886     expect(Ok, stat);
1887     expect(PaletteFlagsHalftone, palette->Flags);
1888     expect(256, palette->Count);
1889
1890     check_halftone_palette(palette);
1891
1892     /* test getting/setting pixels */
1893     stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
1894     expect(Ok, stat);
1895     expect(0xff000000, color);
1896
1897     stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffcccccc);
1898     ok((stat == Ok) ||
1899        broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
1900
1901     if (stat == Ok)
1902     {
1903         stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
1904         expect(Ok, stat);
1905         expect(0xffcccccc, color);
1906     }
1907
1908     /* test setting/getting a different palette */
1909     entries[1] = 0xffcccccc;
1910
1911     stat = GdipSetImagePalette((GpImage*)bitmap, palette);
1912     expect(Ok, stat);
1913
1914     entries[1] = 0;
1915
1916     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1917     expect(Ok, stat);
1918     expect(sizeof(UINT)*2+sizeof(ARGB)*256, size);
1919
1920     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1921     expect(Ok, stat);
1922     expect(PaletteFlagsHalftone, palette->Flags);
1923     expect(256, palette->Count);
1924     expect(0xffcccccc, entries[1]);
1925
1926     /* test count < 256 */
1927     palette->Flags = 12345;
1928     palette->Count = 3;
1929
1930     stat = GdipSetImagePalette((GpImage*)bitmap, palette);
1931     expect(Ok, stat);
1932
1933     entries[1] = 0;
1934     entries[3] = 0xdeadbeef;
1935
1936     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1937     expect(Ok, stat);
1938     expect(sizeof(UINT)*2+sizeof(ARGB)*3, size);
1939
1940     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1941     expect(Ok, stat);
1942     expect(12345, palette->Flags);
1943     expect(3, palette->Count);
1944     expect(0xffcccccc, entries[1]);
1945     expect(0xdeadbeef, entries[3]);
1946
1947     /* test count > 256 */
1948     palette->Count = 257;
1949
1950     stat = GdipSetImagePalette((GpImage*)bitmap, palette);
1951     ok(stat == InvalidParameter ||
1952        broken(stat == Ok), /* Old gdiplus behavior */
1953        "Expected %.8x, got %.8x\n", InvalidParameter, stat);
1954
1955     GdipDisposeImage((GpImage*)bitmap);
1956 }
1957
1958 static void test_colormatrix(void)
1959 {
1960     GpStatus stat;
1961     ColorMatrix colormatrix, graymatrix;
1962     GpImageAttributes *imageattr;
1963     const ColorMatrix identity = {{
1964         {1.0,0.0,0.0,0.0,0.0},
1965         {0.0,1.0,0.0,0.0,0.0},
1966         {0.0,0.0,1.0,0.0,0.0},
1967         {0.0,0.0,0.0,1.0,0.0},
1968         {0.0,0.0,0.0,0.0,1.0}}};
1969     const ColorMatrix double_red = {{
1970         {2.0,0.0,0.0,0.0,0.0},
1971         {0.0,1.0,0.0,0.0,0.0},
1972         {0.0,0.0,1.0,0.0,0.0},
1973         {0.0,0.0,0.0,1.0,0.0},
1974         {0.0,0.0,0.0,0.0,1.0}}};
1975     const ColorMatrix asymmetric = {{
1976         {0.0,1.0,0.0,0.0,0.0},
1977         {0.0,0.0,1.0,0.0,0.0},
1978         {0.0,0.0,0.0,1.0,0.0},
1979         {1.0,0.0,0.0,0.0,0.0},
1980         {0.0,0.0,0.0,0.0,1.0}}};
1981     GpBitmap *bitmap1, *bitmap2;
1982     GpGraphics *graphics;
1983     ARGB color;
1984
1985     colormatrix = identity;
1986     graymatrix = identity;
1987
1988     stat = GdipSetImageAttributesColorMatrix(NULL, ColorAdjustTypeDefault,
1989         TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
1990     expect(InvalidParameter, stat);
1991
1992     stat = GdipCreateImageAttributes(&imageattr);
1993     expect(Ok, stat);
1994
1995     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
1996         TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
1997     expect(Ok, stat);
1998
1999     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2000         TRUE, NULL, NULL, ColorMatrixFlagsDefault);
2001     expect(InvalidParameter, stat);
2002
2003     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2004         TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2005     expect(Ok, stat);
2006
2007     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2008         TRUE, &colormatrix, NULL, ColorMatrixFlagsSkipGrays);
2009     expect(Ok, stat);
2010
2011     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2012         TRUE, &colormatrix, NULL, ColorMatrixFlagsAltGray);
2013     expect(InvalidParameter, stat);
2014
2015     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2016         TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsAltGray);
2017     expect(Ok, stat);
2018
2019     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2020         TRUE, &colormatrix, &graymatrix, 3);
2021     expect(InvalidParameter, stat);
2022
2023     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeCount,
2024         TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2025     expect(InvalidParameter, stat);
2026
2027     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeAny,
2028         TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2029     expect(InvalidParameter, stat);
2030
2031     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2032         FALSE, NULL, NULL, ColorMatrixFlagsDefault);
2033     expect(Ok, stat);
2034
2035     /* Drawing a bitmap transforms the colors */
2036     colormatrix = double_red;
2037     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2038         TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2039     expect(Ok, stat);
2040
2041     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB, NULL, &bitmap1);
2042     expect(Ok, stat);
2043
2044     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB, NULL, &bitmap2);
2045     expect(Ok, stat);
2046
2047     stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff40ccee);
2048     expect(Ok, stat);
2049
2050     stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
2051     expect(Ok, stat);
2052
2053     stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2054         UnitPixel, imageattr, NULL, NULL);
2055     expect(Ok, stat);
2056
2057     stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2058     expect(Ok, stat);
2059     expect(0xff80ccee, color);
2060
2061     colormatrix = asymmetric;
2062     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
2063         TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2064     expect(Ok, stat);
2065
2066     stat = GdipBitmapSetPixel(bitmap2, 0, 0, 0);
2067     expect(Ok, stat);
2068
2069     stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2070         UnitPixel, imageattr, NULL, NULL);
2071     expect(Ok, stat);
2072
2073     stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2074     expect(Ok, stat);
2075     ok(color_match(0xeeff40cc, color, 3), "expected 0xeeff40cc, got 0x%08x\n", color);
2076
2077     GdipDeleteGraphics(graphics);
2078     GdipDisposeImage((GpImage*)bitmap1);
2079     GdipDisposeImage((GpImage*)bitmap2);
2080     GdipDisposeImageAttributes(imageattr);
2081 }
2082
2083 static void test_gamma(void)
2084 {
2085     GpStatus stat;
2086     GpImageAttributes *imageattr;
2087     GpBitmap *bitmap1, *bitmap2;
2088     GpGraphics *graphics;
2089     ARGB color;
2090
2091     stat = GdipSetImageAttributesGamma(NULL, ColorAdjustTypeDefault, TRUE, 1.0);
2092     expect(InvalidParameter, stat);
2093
2094     stat = GdipCreateImageAttributes(&imageattr);
2095     expect(Ok, stat);
2096
2097     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 1.0);
2098     expect(Ok, stat);
2099
2100     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeAny, TRUE, 1.0);
2101     expect(InvalidParameter, stat);
2102
2103     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, -1.0);
2104     expect(InvalidParameter, stat);
2105
2106     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 0.0);
2107     expect(InvalidParameter, stat);
2108
2109     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 0.5);
2110     expect(Ok, stat);
2111
2112     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, FALSE, 0.0);
2113     expect(Ok, stat);
2114
2115     /* Drawing a bitmap transforms the colors */
2116     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 3.0);
2117     expect(Ok, stat);
2118
2119     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap1);
2120     expect(Ok, stat);
2121
2122     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap2);
2123     expect(Ok, stat);
2124
2125     stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff80ffff);
2126     expect(Ok, stat);
2127
2128     stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
2129     expect(Ok, stat);
2130
2131     stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2132         UnitPixel, imageattr, NULL, NULL);
2133     expect(Ok, stat);
2134
2135     stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2136     expect(Ok, stat);
2137     ok(color_match(0xff20ffff, color, 1), "Expected ff20ffff, got %.8x\n", color);
2138
2139     GdipDeleteGraphics(graphics);
2140     GdipDisposeImage((GpImage*)bitmap1);
2141     GdipDisposeImage((GpImage*)bitmap2);
2142     GdipDisposeImageAttributes(imageattr);
2143 }
2144
2145 /* 1x1 pixel gif, 2 frames; first frame is white, second is black */
2146 static const unsigned char gifanimation[72] = {
2147 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
2148 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0xf9,0x04,0x00,0x0a,0x00,0xff,
2149 0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x4c,0x01,0x00,
2150 0x21,0xf9,0x04,0x01,0x0a,0x00,0x01,0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,
2151 0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
2152 };
2153
2154 static void test_multiframegif(void)
2155 {
2156     LPSTREAM stream;
2157     HGLOBAL hglob;
2158     LPBYTE data;
2159     HRESULT hres;
2160     GpStatus stat;
2161     GpBitmap *bmp;
2162     ARGB color;
2163     UINT count;
2164     GUID dimension;
2165
2166     /* Test frame functions with an animated GIF */
2167     hglob = GlobalAlloc (0, sizeof(gifanimation));
2168     data = GlobalLock (hglob);
2169     memcpy(data, gifanimation, sizeof(gifanimation));
2170     GlobalUnlock(hglob);
2171
2172     hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
2173     ok(hres == S_OK, "Failed to create a stream\n");
2174     if(hres != S_OK) return;
2175
2176     stat = GdipCreateBitmapFromStream(stream, &bmp);
2177     ok(stat == Ok, "Failed to create a Bitmap\n");
2178     if(stat != Ok){
2179         IStream_Release(stream);
2180         return;
2181     }
2182
2183     /* Bitmap starts at frame 0 */
2184     color = 0xdeadbeef;
2185     stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2186     expect(Ok, stat);
2187     expect(0xffffffff, color);
2188
2189     /* Check that we get correct metadata */
2190     stat = GdipImageGetFrameDimensionsCount((GpImage*)bmp,&count);
2191     expect(Ok, stat);
2192     expect(1, count);
2193
2194     stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1);
2195     expect(Ok, stat);
2196     expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE);
2197
2198     count = 12345;
2199     stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
2200     expect(Ok, stat);
2201     todo_wine expect(2, count);
2202
2203     /* SelectActiveFrame overwrites our current data */
2204     stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 1);
2205     expect(Ok, stat);
2206
2207     color = 0xdeadbeef;
2208     GdipBitmapGetPixel(bmp, 0, 0, &color);
2209     expect(Ok, stat);
2210     todo_wine expect(0xff000000, color);
2211
2212     stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
2213     expect(Ok, stat);
2214
2215     color = 0xdeadbeef;
2216     GdipBitmapGetPixel(bmp, 0, 0, &color);
2217     expect(Ok, stat);
2218     expect(0xffffffff, color);
2219
2220     /* Write over the image data */
2221     stat = GdipBitmapSetPixel(bmp, 0, 0, 0xff000000);
2222     expect(Ok, stat);
2223
2224     /* Switching to the same frame does not overwrite our changes */
2225     stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
2226     expect(Ok, stat);
2227
2228     stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2229     expect(Ok, stat);
2230     expect(0xff000000, color);
2231
2232     /* But switching to another frame and back does */
2233     stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 1);
2234     expect(Ok, stat);
2235
2236     stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
2237     expect(Ok, stat);
2238
2239     stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2240     expect(Ok, stat);
2241     todo_wine expect(0xffffffff, color);
2242
2243     GdipDisposeImage((GpImage*)bmp);
2244     IStream_Release(stream);
2245
2246     /* Test with a non-animated gif */
2247     hglob = GlobalAlloc (0, sizeof(gifimage));
2248     data = GlobalLock (hglob);
2249     memcpy(data, gifimage, sizeof(gifimage));
2250     GlobalUnlock(hglob);
2251
2252     hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
2253     ok(hres == S_OK, "Failed to create a stream\n");
2254     if(hres != S_OK) return;
2255
2256     stat = GdipCreateBitmapFromStream(stream, &bmp);
2257     ok(stat == Ok, "Failed to create a Bitmap\n");
2258     if(stat != Ok){
2259         IStream_Release(stream);
2260         return;
2261     }
2262
2263     /* Check metadata */
2264     stat = GdipImageGetFrameDimensionsCount((GpImage*)bmp,&count);
2265     expect(Ok, stat);
2266     expect(1, count);
2267
2268     stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1);
2269     expect(Ok, stat);
2270     expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE);
2271
2272     count = 12345;
2273     stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
2274     expect(Ok, stat);
2275     expect(1, count);
2276
2277     GdipDisposeImage((GpImage*)bmp);
2278     IStream_Release(stream);
2279 }
2280
2281 static void test_rotateflip(void)
2282 {
2283     GpImage *bitmap;
2284     GpStatus stat;
2285     BYTE bits[24];
2286     static const BYTE orig_bits[24] = {
2287         0,0,0xff,    0,0xff,0,    0xff,0,0,    23,23,23,
2288         0xff,0xff,0, 0xff,0,0xff, 0,0xff,0xff, 23,23,23};
2289     UINT width, height;
2290     ARGB color;
2291
2292     memcpy(bits, orig_bits, sizeof(bits));
2293     stat = GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB, bits, (GpBitmap**)&bitmap);
2294     expect(Ok, stat);
2295
2296     stat = GdipImageRotateFlip(bitmap, Rotate90FlipNone);
2297     expect(Ok, stat);
2298
2299     stat = GdipGetImageWidth(bitmap, &width);
2300     expect(Ok, stat);
2301     stat = GdipGetImageHeight(bitmap, &height);
2302     expect(Ok, stat);
2303     expect(2, width);
2304     expect(3, height);
2305
2306     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
2307     expect(Ok, stat);
2308     expect(0xff00ffff, color);
2309
2310     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 1, 0, &color);
2311     expect(Ok, stat);
2312     expect(0xffff0000, color);
2313
2314     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 2, &color);
2315     expect(Ok, stat);
2316     expect(0xffffff00, color);
2317
2318     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 1, 2, &color);
2319     expect(Ok, stat);
2320     expect(0xff0000ff, color);
2321
2322     expect(0, bits[0]);
2323     expect(0, bits[1]);
2324     expect(0xff, bits[2]);
2325
2326     GdipDisposeImage(bitmap);
2327
2328     memcpy(bits, orig_bits, sizeof(bits));
2329     stat = GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB, bits, (GpBitmap**)&bitmap);
2330     expect(Ok, stat);
2331
2332     stat = GdipImageRotateFlip(bitmap, RotateNoneFlipX);
2333     expect(Ok, stat);
2334
2335     stat = GdipGetImageWidth(bitmap, &width);
2336     expect(Ok, stat);
2337     stat = GdipGetImageHeight(bitmap, &height);
2338     expect(Ok, stat);
2339     expect(3, width);
2340     expect(2, height);
2341
2342     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
2343     expect(Ok, stat);
2344     expect(0xff0000ff, color);
2345
2346     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 0, &color);
2347     expect(Ok, stat);
2348     expect(0xffff0000, color);
2349
2350     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 1, &color);
2351     expect(Ok, stat);
2352     expect(0xffffff00, color);
2353
2354     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 1, &color);
2355     expect(Ok, stat);
2356     expect(0xff00ffff, color);
2357
2358     expect(0, bits[0]);
2359     expect(0, bits[1]);
2360     expect(0xff, bits[2]);
2361
2362     GdipDisposeImage(bitmap);
2363
2364     memcpy(bits, orig_bits, sizeof(bits));
2365     stat = GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB, bits, (GpBitmap**)&bitmap);
2366     expect(Ok, stat);
2367
2368     stat = GdipImageRotateFlip(bitmap, RotateNoneFlipY);
2369     expect(Ok, stat);
2370
2371     stat = GdipGetImageWidth(bitmap, &width);
2372     expect(Ok, stat);
2373     stat = GdipGetImageHeight(bitmap, &height);
2374     expect(Ok, stat);
2375     expect(3, width);
2376     expect(2, height);
2377
2378     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
2379     expect(Ok, stat);
2380     expect(0xff00ffff, color);
2381
2382     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 0, &color);
2383     expect(Ok, stat);
2384     expect(0xffffff00, color);
2385
2386     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 1, &color);
2387     expect(Ok, stat);
2388     expect(0xffff0000, color);
2389
2390     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 1, &color);
2391     expect(Ok, stat);
2392     expect(0xff0000ff, color);
2393
2394     expect(0, bits[0]);
2395     expect(0, bits[1]);
2396     expect(0xff, bits[2]);
2397
2398     GdipDisposeImage(bitmap);
2399 }
2400
2401 static void test_remaptable(void)
2402 {
2403     GpStatus stat;
2404     GpImageAttributes *imageattr;
2405     GpBitmap *bitmap1, *bitmap2;
2406     GpGraphics *graphics;
2407     ARGB color;
2408     ColorMap *map;
2409
2410     map = GdipAlloc(sizeof(ColorMap));
2411
2412     map->oldColor.Argb = 0xff00ff00;
2413     map->newColor.Argb = 0xffff00ff;
2414
2415     stat = GdipSetImageAttributesRemapTable(NULL, ColorAdjustTypeDefault, TRUE, 1, map);
2416     expect(InvalidParameter, stat);
2417
2418     stat = GdipCreateImageAttributes(&imageattr);
2419     expect(Ok, stat);
2420
2421     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, TRUE, 1, NULL);
2422     expect(InvalidParameter, stat);
2423
2424     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeCount, TRUE, 1, map);
2425     expect(InvalidParameter, stat);
2426
2427     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeAny, TRUE, 1, map);
2428     expect(InvalidParameter, stat);
2429
2430     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, TRUE, 0, map);
2431     expect(InvalidParameter, stat);
2432
2433     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, FALSE, 0, NULL);
2434     expect(Ok, stat);
2435
2436     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, TRUE, 1, map);
2437     expect(Ok, stat);
2438
2439     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap1);
2440     expect(Ok, stat);
2441
2442     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap2);
2443     expect(Ok, stat);
2444
2445     stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff00ff00);
2446     expect(Ok, stat);
2447
2448     stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
2449     expect(Ok, stat);
2450
2451     stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2452         UnitPixel, imageattr, NULL, NULL);
2453     expect(Ok, stat);
2454
2455     stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2456     expect(Ok, stat);
2457     ok(color_match(0xffff00ff, color, 1), "Expected ffff00ff, got %.8x\n", color);
2458
2459     GdipDeleteGraphics(graphics);
2460     GdipDisposeImage((GpImage*)bitmap1);
2461     GdipDisposeImage((GpImage*)bitmap2);
2462     GdipDisposeImageAttributes(imageattr);
2463     GdipFree(map);
2464 }
2465
2466 static void test_colorkey(void)
2467 {
2468     GpStatus stat;
2469     GpImageAttributes *imageattr;
2470     GpBitmap *bitmap1, *bitmap2;
2471     GpGraphics *graphics;
2472     ARGB color;
2473
2474     stat = GdipSetImageAttributesColorKeys(NULL, ColorAdjustTypeDefault, TRUE, 0xff405060, 0xff708090);
2475     expect(InvalidParameter, stat);
2476
2477     stat = GdipCreateImageAttributes(&imageattr);
2478     expect(Ok, stat);
2479
2480     stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeCount, TRUE, 0xff405060, 0xff708090);
2481     expect(InvalidParameter, stat);
2482
2483     stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeAny, TRUE, 0xff405060, 0xff708090);
2484     expect(InvalidParameter, stat);
2485
2486     stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeDefault, TRUE, 0xff405060, 0xff708090);
2487     expect(Ok, stat);
2488
2489     stat = GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB, NULL, &bitmap1);
2490     expect(Ok, stat);
2491
2492     stat = GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB, NULL, &bitmap2);
2493     expect(Ok, stat);
2494
2495     stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0x20405060);
2496     expect(Ok, stat);
2497
2498     stat = GdipBitmapSetPixel(bitmap1, 0, 1, 0x40506070);
2499     expect(Ok, stat);
2500
2501     stat = GdipBitmapSetPixel(bitmap1, 1, 0, 0x60708090);
2502     expect(Ok, stat);
2503
2504     stat = GdipBitmapSetPixel(bitmap1, 1, 1, 0xffffffff);
2505     expect(Ok, stat);
2506
2507     stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
2508     expect(Ok, stat);
2509
2510     stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,2,2, 0,0,2,2,
2511         UnitPixel, imageattr, NULL, NULL);
2512     expect(Ok, stat);
2513
2514     stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2515     expect(Ok, stat);
2516     ok(color_match(0x00000000, color, 1), "Expected ffff00ff, got %.8x\n", color);
2517
2518     stat = GdipBitmapGetPixel(bitmap2, 0, 1, &color);
2519     expect(Ok, stat);
2520     ok(color_match(0x00000000, color, 1), "Expected ffff00ff, got %.8x\n", color);
2521
2522     stat = GdipBitmapGetPixel(bitmap2, 1, 0, &color);
2523     expect(Ok, stat);
2524     ok(color_match(0x00000000, color, 1), "Expected ffff00ff, got %.8x\n", color);
2525
2526     stat = GdipBitmapGetPixel(bitmap2, 1, 1, &color);
2527     expect(Ok, stat);
2528     ok(color_match(0xffffffff, color, 1), "Expected ffff00ff, got %.8x\n", color);
2529
2530     GdipDeleteGraphics(graphics);
2531     GdipDisposeImage((GpImage*)bitmap1);
2532     GdipDisposeImage((GpImage*)bitmap2);
2533     GdipDisposeImageAttributes(imageattr);
2534 }
2535
2536 static void test_dispose(void)
2537 {
2538     GpStatus stat;
2539     GpImage *image;
2540     char invalid_image[256];
2541
2542     stat = GdipDisposeImage(NULL);
2543     expect(InvalidParameter, stat);
2544
2545     stat = GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB, NULL, (GpBitmap**)&image);
2546     expect(Ok, stat);
2547
2548     stat = GdipDisposeImage(image);
2549     expect(Ok, stat);
2550
2551     stat = GdipDisposeImage(image);
2552     expect(ObjectBusy, stat);
2553
2554     memset(invalid_image, 0, 256);
2555     stat = GdipDisposeImage((GpImage*)invalid_image);
2556     expect(ObjectBusy, stat);
2557 }
2558
2559 START_TEST(image)
2560 {
2561     struct GdiplusStartupInput gdiplusStartupInput;
2562     ULONG_PTR gdiplusToken;
2563
2564     gdiplusStartupInput.GdiplusVersion              = 1;
2565     gdiplusStartupInput.DebugEventCallback          = NULL;
2566     gdiplusStartupInput.SuppressBackgroundThread    = 0;
2567     gdiplusStartupInput.SuppressExternalCodecs      = 0;
2568
2569     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
2570
2571     test_Scan0();
2572     test_FromGdiDib();
2573     test_GetImageDimension();
2574     test_GdipImageGetFrameDimensionsCount();
2575     test_LoadingImages();
2576     test_SavingImages();
2577     test_encoders();
2578     test_LockBits();
2579     test_LockBits_UserBuf();
2580     test_GdipCreateBitmapFromHBITMAP();
2581     test_GdipGetImageFlags();
2582     test_GdipCloneImage();
2583     test_testcontrol();
2584     test_fromhicon();
2585     test_getrawformat();
2586     test_loadwmf();
2587     test_createfromwmf();
2588     test_resolution();
2589     test_createhbitmap();
2590     test_getthumbnail();
2591     test_getsetpixel();
2592     test_palette();
2593     test_colormatrix();
2594     test_gamma();
2595     test_multiframegif();
2596     test_rotateflip();
2597     test_remaptable();
2598     test_colorkey();
2599     test_dispose();
2600
2601     GdiplusShutdown(gdiplusToken);
2602 }