gdiplus: Add test for ImageLockModeUserInputBuf.
[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
520     bm = NULL;
521     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
522     expect(Ok, stat);
523
524     rect.X = 2;
525     rect.Y = 3;
526     rect.Width = 4;
527     rect.Height = 5;
528
529     /* read-only */
530     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
531     expect(Ok, stat);
532
533     if (stat == Ok) {
534         stat = GdipBitmapUnlockBits(bm, &bd);
535         expect(Ok, stat);
536     }
537
538     /* read-only, with NULL rect -> whole bitmap lock */
539     stat = GdipBitmapLockBits(bm, NULL, ImageLockModeRead, PixelFormat24bppRGB, &bd);
540     expect(Ok, stat);
541     expect(bd.Width,  WIDTH);
542     expect(bd.Height, HEIGHT);
543
544     if (stat == Ok) {
545         stat = GdipBitmapUnlockBits(bm, &bd);
546         expect(Ok, stat);
547     }
548
549     /* read-only, consecutive */
550     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
551     expect(Ok, stat);
552
553     if (stat == Ok) {
554         stat = GdipBitmapUnlockBits(bm, &bd);
555         expect(Ok, stat);
556     }
557
558     stat = GdipDisposeImage((GpImage*)bm);
559     expect(Ok, stat);
560     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
561     expect(Ok, stat);
562
563     /* read x2 */
564     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
565     expect(Ok, stat);
566     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
567     expect(WrongState, stat);
568
569     stat = GdipBitmapUnlockBits(bm, &bd);
570     expect(Ok, stat);
571
572     stat = GdipDisposeImage((GpImage*)bm);
573     expect(Ok, stat);
574     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
575     expect(Ok, stat);
576
577     /* write, no modification */
578     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
579     expect(Ok, stat);
580
581     if (stat == Ok) {
582         stat = GdipBitmapUnlockBits(bm, &bd);
583         expect(Ok, stat);
584     }
585
586     /* write, consecutive */
587     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
588     expect(Ok, stat);
589
590     if (stat == Ok) {
591         stat = GdipBitmapUnlockBits(bm, &bd);
592         expect(Ok, stat);
593     }
594
595     stat = GdipDisposeImage((GpImage*)bm);
596     expect(Ok, stat);
597     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
598     expect(Ok, stat);
599
600     /* write, modify */
601     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
602     expect(Ok, stat);
603
604     if (stat == Ok) {
605         if (bd.Scan0)
606             ((char*)bd.Scan0)[2] = 0xff;
607
608         stat = GdipBitmapUnlockBits(bm, &bd);
609         expect(Ok, stat);
610     }
611
612     stat = GdipDisposeImage((GpImage*)bm);
613     expect(Ok, stat);
614
615     /* dispose locked */
616     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
617     expect(Ok, stat);
618     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
619     expect(Ok, stat);
620     stat = GdipDisposeImage((GpImage*)bm);
621     expect(Ok, stat);
622 }
623
624 static void test_LockBits_UserBuf(void)
625 {
626     GpStatus stat;
627     GpBitmap *bm;
628     GpRect rect;
629     BitmapData bd;
630     const INT WIDTH = 10, HEIGHT = 20;
631     DWORD bits[200];
632     ARGB color;
633
634     bm = NULL;
635     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat32bppARGB, NULL, &bm);
636     expect(Ok, stat);
637
638     memset(bits, 0xaa, sizeof(bits));
639
640     rect.X = 2;
641     rect.Y = 3;
642     rect.Width = 4;
643     rect.Height = 5;
644
645     bd.Width = 4;
646     bd.Height = 6;
647     bd.Stride = WIDTH * 4;
648     bd.PixelFormat = PixelFormat32bppARGB;
649     bd.Scan0 = &bits[2+3*WIDTH];
650     bd.Reserved = 0xaaaaaaaa;
651
652     /* read-only */
653     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead|ImageLockModeUserInputBuf, PixelFormat32bppARGB, &bd);
654     todo_wine expect(Ok, stat);
655
656     expect(0xaaaaaaaa, bits[0]);
657     todo_wine expect(0, bits[2+3*WIDTH]);
658
659     bits[2+3*WIDTH] = 0xdeadbeef;
660
661     if (stat == Ok) {
662         stat = GdipBitmapUnlockBits(bm, &bd);
663         expect(Ok, stat);
664     }
665
666     stat = GdipBitmapGetPixel(bm, 2, 3, &color);
667     expect(Ok, stat);
668     expect(0, color);
669
670     /* write-only */
671     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite|ImageLockModeUserInputBuf, PixelFormat32bppARGB, &bd);
672     todo_wine expect(Ok, stat);
673
674     expect(0xdeadbeef, bits[2+3*WIDTH]);
675     bits[2+3*WIDTH] = 0x12345678;
676
677     if (stat == Ok) {
678         stat = GdipBitmapUnlockBits(bm, &bd);
679         expect(Ok, stat);
680     }
681
682     stat = GdipBitmapGetPixel(bm, 2, 3, &color);
683     expect(Ok, stat);
684     todo_wine expect(0x12345678, color);
685
686     bits[2+3*WIDTH] = 0;
687
688     /* read/write */
689     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead|ImageLockModeWrite|ImageLockModeUserInputBuf, PixelFormat32bppARGB, &bd);
690     todo_wine expect(Ok, stat);
691
692     todo_wine expect(0x12345678, bits[2+3*WIDTH]);
693     bits[2+3*WIDTH] = 0xdeadbeef;
694
695     if (stat == Ok) {
696         stat = GdipBitmapUnlockBits(bm, &bd);
697         expect(Ok, stat);
698     }
699
700     stat = GdipBitmapGetPixel(bm, 2, 3, &color);
701     expect(Ok, stat);
702     todo_wine expect(0xdeadbeef, color);
703
704     stat = GdipDisposeImage((GpImage*)bm);
705     expect(Ok, stat);
706 }
707
708 static void test_GdipCreateBitmapFromHBITMAP(void)
709 {
710     GpBitmap* gpbm = NULL;
711     HBITMAP hbm = NULL;
712     HPALETTE hpal = NULL;
713     GpStatus stat;
714     BYTE buff[1000];
715     LOGPALETTE* LogPal = NULL;
716     REAL width, height;
717     const REAL WIDTH1 = 5;
718     const REAL HEIGHT1 = 15;
719     const REAL WIDTH2 = 10;
720     const REAL HEIGHT2 = 20;
721     HDC hdc;
722     BITMAPINFO bmi;
723     BYTE *bits;
724
725     stat = GdipCreateBitmapFromHBITMAP(NULL, NULL, NULL);
726     expect(InvalidParameter, stat);
727
728     hbm = CreateBitmap(WIDTH1, HEIGHT1, 1, 1, NULL);
729     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, NULL);
730     expect(InvalidParameter, stat);
731
732     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
733     expect(Ok, stat);
734     expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
735     expectf(WIDTH1,  width);
736     expectf(HEIGHT1, height);
737     if (stat == Ok)
738         GdipDisposeImage((GpImage*)gpbm);
739     DeleteObject(hbm);
740
741     memset(buff, 0, sizeof(buff));
742     hbm = CreateBitmap(WIDTH2, HEIGHT2, 1, 1, &buff);
743     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
744     expect(Ok, stat);
745     /* raw format */
746     expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)gpbm, __LINE__, FALSE);
747
748     expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
749     expectf(WIDTH2,  width);
750     expectf(HEIGHT2, height);
751     if (stat == Ok)
752         GdipDisposeImage((GpImage*)gpbm);
753     DeleteObject(hbm);
754
755     hdc = CreateCompatibleDC(0);
756     ok(hdc != NULL, "CreateCompatibleDC failed\n");
757     bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
758     bmi.bmiHeader.biHeight = HEIGHT1;
759     bmi.bmiHeader.biWidth = WIDTH1;
760     bmi.bmiHeader.biBitCount = 24;
761     bmi.bmiHeader.biPlanes = 1;
762     bmi.bmiHeader.biCompression = BI_RGB;
763
764     hbm = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
765     ok(hbm != NULL, "CreateDIBSection failed\n");
766
767     bits[0] = 0;
768
769     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
770     expect(Ok, stat);
771     expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
772     expectf(WIDTH1,  width);
773     expectf(HEIGHT1, height);
774     if (stat == Ok)
775     {
776         /* test whether writing to the bitmap affects the original */
777         stat = GdipBitmapSetPixel(gpbm, 0, 0, 0xffffffff);
778         expect(Ok, stat);
779
780         expect(0, bits[0]);
781
782         GdipDisposeImage((GpImage*)gpbm);
783     }
784
785     LogPal = GdipAlloc(sizeof(LOGPALETTE));
786     ok(LogPal != NULL, "unable to allocate LOGPALETTE\n");
787     LogPal->palVersion = 0x300;
788     LogPal->palNumEntries = 1;
789     hpal = CreatePalette(LogPal);
790     ok(hpal != NULL, "CreatePalette failed\n");
791     GdipFree(LogPal);
792
793     stat = GdipCreateBitmapFromHBITMAP(hbm, hpal, &gpbm);
794     todo_wine
795     {
796         expect(Ok, stat);
797     }
798     if (stat == Ok)
799         GdipDisposeImage((GpImage*)gpbm);
800
801     DeleteObject(hpal);
802     DeleteObject(hbm);
803 }
804
805 static void test_GdipGetImageFlags(void)
806 {
807     GpImage *img;
808     GpStatus stat;
809     UINT flags;
810
811     img = (GpImage*)0xdeadbeef;
812
813     stat = GdipGetImageFlags(NULL, NULL);
814     expect(InvalidParameter, stat);
815
816     stat = GdipGetImageFlags(NULL, &flags);
817     expect(InvalidParameter, stat);
818
819     stat = GdipGetImageFlags(img, NULL);
820     expect(InvalidParameter, stat);
821
822     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat1bppIndexed, NULL, (GpBitmap**)&img);
823     expect(Ok, stat);
824     stat = GdipGetImageFlags(img, &flags);
825     expect(Ok, stat);
826     expect(ImageFlagsHasAlpha, flags);
827     GdipDisposeImage(img);
828
829     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat4bppIndexed, NULL, (GpBitmap**)&img);
830     expect(Ok, stat);
831     stat = GdipGetImageFlags(img, &flags);
832     expect(Ok, stat);
833     expect(ImageFlagsHasAlpha, flags);
834     GdipDisposeImage(img);
835
836     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat8bppIndexed, NULL, (GpBitmap**)&img);
837     expect(Ok, stat);
838     stat = GdipGetImageFlags(img, &flags);
839     expect(Ok, stat);
840     expect(ImageFlagsHasAlpha, flags);
841     GdipDisposeImage(img);
842
843     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppGrayScale, NULL, (GpBitmap**)&img);
844     expect(Ok, stat);
845     stat = GdipGetImageFlags(img, &flags);
846     expect(Ok, stat);
847     expect(ImageFlagsNone, flags);
848     GdipDisposeImage(img);
849
850     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB555, NULL, (GpBitmap**)&img);
851     expect(Ok, stat);
852     stat = GdipGetImageFlags(img, &flags);
853     expect(Ok, stat);
854     expect(ImageFlagsNone, flags);
855     GdipDisposeImage(img);
856
857     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB565, NULL, (GpBitmap**)&img);
858     expect(Ok, stat);
859     stat = GdipGetImageFlags(img, &flags);
860     expect(Ok, stat);
861     expect(ImageFlagsNone, flags);
862     GdipDisposeImage(img);
863
864     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppARGB1555, NULL, (GpBitmap**)&img);
865     expect(Ok, stat);
866     stat = GdipGetImageFlags(img, &flags);
867     expect(Ok, stat);
868     expect(ImageFlagsHasAlpha, flags);
869     GdipDisposeImage(img);
870
871     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, NULL, (GpBitmap**)&img);
872     expect(Ok, stat);
873     stat = GdipGetImageFlags(img, &flags);
874     expect(Ok, stat);
875     expect(ImageFlagsNone, flags);
876     GdipDisposeImage(img);
877
878     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppRGB, NULL, (GpBitmap**)&img);
879     expect(Ok, stat);
880     stat = GdipGetImageFlags(img, &flags);
881     expect(Ok, stat);
882     expect(ImageFlagsNone, flags);
883     GdipDisposeImage(img);
884
885     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppARGB, NULL, (GpBitmap**)&img);
886     expect(Ok, stat);
887     stat = GdipGetImageFlags(img, &flags);
888     expect(Ok, stat);
889     expect(ImageFlagsHasAlpha, flags);
890     GdipDisposeImage(img);
891
892     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppPARGB, NULL, (GpBitmap**)&img);
893     expect(Ok, stat);
894     stat = GdipGetImageFlags(img, &flags);
895     expect(Ok, stat);
896     expect(ImageFlagsHasAlpha, flags);
897     GdipDisposeImage(img);
898
899     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat48bppRGB, NULL, (GpBitmap**)&img);
900     expect(Ok, stat);
901     if (stat == Ok)
902     {
903         stat = GdipGetImageFlags(img, &flags);
904         expect(Ok, stat);
905         expect(ImageFlagsNone, flags);
906         GdipDisposeImage(img);
907     }
908
909     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB, NULL, (GpBitmap**)&img);
910     expect(Ok, stat);
911     if (stat == Ok)
912     {
913         expect(Ok, stat);
914         stat = GdipGetImageFlags(img, &flags);
915         expect(Ok, stat);
916         expect(ImageFlagsHasAlpha, flags);
917         GdipDisposeImage(img);
918     }
919
920     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB, NULL, (GpBitmap**)&img);
921     expect(Ok, stat);
922     if (stat == Ok)
923     {
924         expect(Ok, stat);
925         stat = GdipGetImageFlags(img, &flags);
926         expect(Ok, stat);
927         expect(ImageFlagsHasAlpha, flags);
928         GdipDisposeImage(img);
929     }
930 }
931
932 static void test_GdipCloneImage(void)
933 {
934     GpStatus stat;
935     GpRectF rectF;
936     GpUnit unit;
937     GpBitmap *bm;
938     GpImage *image_src, *image_dest = NULL;
939     const INT WIDTH = 10, HEIGHT = 20;
940
941     /* Create an image, clone it, delete the original, make sure the copy works */
942     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
943     expect(Ok, stat);
944     expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bm, __LINE__, FALSE);
945
946     image_src = ((GpImage*)bm);
947     stat = GdipCloneImage(image_src, &image_dest);
948     expect(Ok, stat);
949     expect_rawformat(&ImageFormatMemoryBMP, image_dest, __LINE__, FALSE);
950
951     stat = GdipDisposeImage((GpImage*)bm);
952     expect(Ok, stat);
953     stat = GdipGetImageBounds(image_dest, &rectF, &unit);
954     expect(Ok, stat);
955
956     /* Treat FP values carefully */
957     expectf((REAL)WIDTH, rectF.Width);
958     expectf((REAL)HEIGHT, rectF.Height);
959
960     stat = GdipDisposeImage(image_dest);
961     expect(Ok, stat);
962 }
963
964 static void test_testcontrol(void)
965 {
966     GpStatus stat;
967     DWORD param;
968
969     param = 0;
970     stat = GdipTestControl(TestControlGetBuildNumber, &param);
971     expect(Ok, stat);
972     ok(param != 0, "Build number expected, got %u\n", param);
973 }
974
975 static void test_fromhicon(void)
976 {
977     static const BYTE bmp_bits[1024];
978     HBITMAP hbmMask, hbmColor;
979     ICONINFO info;
980     HICON hIcon;
981     GpStatus stat;
982     GpBitmap *bitmap = NULL;
983     UINT dim;
984     ImageType type;
985     PixelFormat format;
986
987     /* NULL */
988     stat = GdipCreateBitmapFromHICON(NULL, NULL);
989     expect(InvalidParameter, stat);
990     stat = GdipCreateBitmapFromHICON(NULL, &bitmap);
991     expect(InvalidParameter, stat);
992
993     /* color icon 1 bit */
994     hbmMask = CreateBitmap(16, 16, 1, 1, bmp_bits);
995     ok(hbmMask != 0, "CreateBitmap failed\n");
996     hbmColor = CreateBitmap(16, 16, 1, 1, bmp_bits);
997     ok(hbmColor != 0, "CreateBitmap failed\n");
998     info.fIcon = TRUE;
999     info.xHotspot = 8;
1000     info.yHotspot = 8;
1001     info.hbmMask = hbmMask;
1002     info.hbmColor = hbmColor;
1003     hIcon = CreateIconIndirect(&info);
1004     ok(hIcon != 0, "CreateIconIndirect failed\n");
1005     DeleteObject(hbmMask);
1006     DeleteObject(hbmColor);
1007
1008     stat = GdipCreateBitmapFromHICON(hIcon, &bitmap);
1009     ok(stat == Ok ||
1010        broken(stat == InvalidParameter), /* Win98 */
1011        "Expected Ok, got %.8x\n", stat);
1012     if(stat == Ok){
1013        /* check attributes */
1014        stat = GdipGetImageHeight((GpImage*)bitmap, &dim);
1015        expect(Ok, stat);
1016        expect(16, dim);
1017        stat = GdipGetImageWidth((GpImage*)bitmap, &dim);
1018        expect(Ok, stat);
1019        expect(16, dim);
1020        stat = GdipGetImageType((GpImage*)bitmap, &type);
1021        expect(Ok, stat);
1022        expect(ImageTypeBitmap, type);
1023        stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format);
1024        expect(Ok, stat);
1025        expect(PixelFormat32bppARGB, format);
1026        /* raw format */
1027        expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
1028        GdipDisposeImage((GpImage*)bitmap);
1029     }
1030     DestroyIcon(hIcon);
1031
1032     /* color icon 8 bpp */
1033     hbmMask = CreateBitmap(16, 16, 1, 8, bmp_bits);
1034     ok(hbmMask != 0, "CreateBitmap failed\n");
1035     hbmColor = CreateBitmap(16, 16, 1, 8, bmp_bits);
1036     ok(hbmColor != 0, "CreateBitmap failed\n");
1037     info.fIcon = TRUE;
1038     info.xHotspot = 8;
1039     info.yHotspot = 8;
1040     info.hbmMask = hbmMask;
1041     info.hbmColor = hbmColor;
1042     hIcon = CreateIconIndirect(&info);
1043     ok(hIcon != 0, "CreateIconIndirect failed\n");
1044     DeleteObject(hbmMask);
1045     DeleteObject(hbmColor);
1046
1047     stat = GdipCreateBitmapFromHICON(hIcon, &bitmap);
1048     expect(Ok, stat);
1049     if(stat == Ok){
1050         /* check attributes */
1051         stat = GdipGetImageHeight((GpImage*)bitmap, &dim);
1052         expect(Ok, stat);
1053         expect(16, dim);
1054         stat = GdipGetImageWidth((GpImage*)bitmap, &dim);
1055         expect(Ok, stat);
1056         expect(16, dim);
1057         stat = GdipGetImageType((GpImage*)bitmap, &type);
1058         expect(Ok, stat);
1059         expect(ImageTypeBitmap, type);
1060         stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format);
1061         expect(Ok, stat);
1062         expect(PixelFormat32bppARGB, format);
1063         /* raw format */
1064         expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
1065         GdipDisposeImage((GpImage*)bitmap);
1066     }
1067     DestroyIcon(hIcon);
1068 }
1069
1070 /* 1x1 pixel png */
1071 static const unsigned char pngimage[285] = {
1072 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
1073 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
1074 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
1075 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
1076 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
1077 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
1078 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
1079 };
1080 /* 1x1 pixel gif */
1081 static const unsigned char gifimage[35] = {
1082 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
1083 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
1084 0x01,0x00,0x3b
1085 };
1086 /* 1x1 pixel bmp */
1087 static const unsigned char bmpimage[66] = {
1088 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
1089 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
1090 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
1091 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
1092 0x00,0x00
1093 };
1094 /* 1x1 pixel jpg */
1095 static const unsigned char jpgimage[285] = {
1096 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
1097 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
1098 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
1099 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
1100 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
1101 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
1102 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
1103 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1104 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1105 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
1106 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
1107 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1108 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
1109 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
1110 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1111 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
1112 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
1113 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
1114 };
1115 /* 1x1 pixel tiff */
1116 static const unsigned char tiffimage[] = {
1117 0x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00,
1118 0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00,
1119 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1120 0x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01,
1121 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00,
1122 0x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00,
1123 0x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01,
1124 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00,
1125 0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00,
1126 0x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01,
1127 0x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00,
1128 0x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1129 0x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
1130 0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65,
1131 0x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74,
1132 0x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,
1133 0x00,0x00,0x00,0x01
1134 };
1135 /* 320x320 twip wmf */
1136 static const unsigned char wmfimage[180] = {
1137 0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05,
1138 0x00,0x00,0x00,0x00,0xb1,0x52,0x01,0x00,0x09,0x00,0x00,0x03,0x4f,0x00,0x00,0x00,
1139 0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0b,0x02,0x00,0x00,
1140 0x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x02,0x40,0x01,0x40,0x01,0x04,0x00,0x00,0x00,
1141 0x02,0x01,0x01,0x00,0x04,0x00,0x00,0x00,0x04,0x01,0x0d,0x00,0x08,0x00,0x00,0x00,
1142 0xfa,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
1143 0x2d,0x01,0x00,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,0x01,0x00,0x00,0x00,0x00,0x00,
1144 0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x01,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,
1145 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x02,0x00,
1146 0x07,0x00,0x00,0x00,0x1b,0x04,0x40,0x01,0x40,0x01,0x00,0x00,0x00,0x00,0x04,0x00,
1147 0x00,0x00,0xf0,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0xf0,0x01,0x01,0x00,0x03,0x00,
1148 0x00,0x00,0x00,0x00
1149 };
1150 static void test_getrawformat(void)
1151 {
1152     test_bufferrawformat((void*)pngimage, sizeof(pngimage), &ImageFormatPNG,  __LINE__, FALSE);
1153     test_bufferrawformat((void*)gifimage, sizeof(gifimage), &ImageFormatGIF,  __LINE__, FALSE);
1154     test_bufferrawformat((void*)bmpimage, sizeof(bmpimage), &ImageFormatBMP,  __LINE__, FALSE);
1155     test_bufferrawformat((void*)jpgimage, sizeof(jpgimage), &ImageFormatJPEG, __LINE__, FALSE);
1156     test_bufferrawformat((void*)tiffimage, sizeof(tiffimage), &ImageFormatTIFF, __LINE__, FALSE);
1157     test_bufferrawformat((void*)wmfimage, sizeof(wmfimage), &ImageFormatWMF, __LINE__, FALSE);
1158 }
1159
1160 static void test_loadwmf(void)
1161 {
1162     LPSTREAM stream;
1163     HGLOBAL  hglob;
1164     LPBYTE   data;
1165     HRESULT  hres;
1166     GpStatus stat;
1167     GpImage *img;
1168     GpRectF bounds;
1169     GpUnit unit;
1170     REAL res = 12345.0;
1171     MetafileHeader header;
1172
1173     hglob = GlobalAlloc (0, sizeof(wmfimage));
1174     data = GlobalLock (hglob);
1175     memcpy(data, wmfimage, sizeof(wmfimage));
1176     GlobalUnlock(hglob); data = NULL;
1177
1178     hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
1179     ok(hres == S_OK, "Failed to create a stream\n");
1180     if(hres != S_OK) return;
1181
1182     stat = GdipLoadImageFromStream(stream, &img);
1183     ok(stat == Ok, "Failed to create a Bitmap\n");
1184     if(stat != Ok){
1185         IStream_Release(stream);
1186         return;
1187     }
1188
1189     IStream_Release(stream);
1190
1191     stat = GdipGetImageBounds(img, &bounds, &unit);
1192     expect(Ok, stat);
1193     todo_wine expect(UnitPixel, unit);
1194     expectf(0.0, bounds.X);
1195     expectf(0.0, bounds.Y);
1196     todo_wine expectf(320.0, bounds.Width);
1197     todo_wine expectf(320.0, bounds.Height);
1198
1199     stat = GdipGetImageHorizontalResolution(img, &res);
1200     expect(Ok, stat);
1201     todo_wine expectf(1440.0, res);
1202
1203     stat = GdipGetImageVerticalResolution(img, &res);
1204     expect(Ok, stat);
1205     todo_wine expectf(1440.0, res);
1206
1207     memset(&header, 0, sizeof(header));
1208     stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header);
1209     expect(Ok, stat);
1210     if (stat == Ok)
1211     {
1212         todo_wine expect(MetafileTypeWmfPlaceable, header.Type);
1213         todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size);
1214         todo_wine expect(0x300, header.Version);
1215         expect(0, header.EmfPlusFlags);
1216         todo_wine expectf(1440.0, header.DpiX);
1217         todo_wine expectf(1440.0, header.DpiY);
1218         expect(0, header.X);
1219         expect(0, header.Y);
1220         todo_wine expect(320, header.Width);
1221         todo_wine expect(320, header.Height);
1222         todo_wine expect(1, U(header).WmfHeader.mtType);
1223         expect(0, header.EmfPlusHeaderSize);
1224         expect(0, header.LogicalDpiX);
1225         expect(0, header.LogicalDpiY);
1226     }
1227
1228     GdipDisposeImage(img);
1229 }
1230
1231 static void test_createfromwmf(void)
1232 {
1233     HMETAFILE hwmf;
1234     GpImage *img;
1235     GpStatus stat;
1236     GpRectF bounds;
1237     GpUnit unit;
1238     REAL res = 12345.0;
1239     MetafileHeader header;
1240
1241     hwmf = SetMetaFileBitsEx(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader),
1242         wmfimage+sizeof(WmfPlaceableFileHeader));
1243     ok(hwmf != 0, "SetMetaFileBitsEx failed\n");
1244
1245     stat = GdipCreateMetafileFromWmf(hwmf, TRUE,
1246         (WmfPlaceableFileHeader*)wmfimage, (GpMetafile**)&img);
1247     expect(Ok, stat);
1248
1249     stat = GdipGetImageBounds(img, &bounds, &unit);
1250     expect(Ok, stat);
1251     expect(UnitPixel, unit);
1252     expectf(0.0, bounds.X);
1253     expectf(0.0, bounds.Y);
1254     expectf(320.0, bounds.Width);
1255     expectf(320.0, bounds.Height);
1256
1257     stat = GdipGetImageHorizontalResolution(img, &res);
1258     expect(Ok, stat);
1259     expectf(1440.0, res);
1260
1261     stat = GdipGetImageVerticalResolution(img, &res);
1262     expect(Ok, stat);
1263     expectf(1440.0, res);
1264
1265     memset(&header, 0, sizeof(header));
1266     stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header);
1267     expect(Ok, stat);
1268     if (stat == Ok)
1269     {
1270         todo_wine expect(MetafileTypeWmfPlaceable, header.Type);
1271         todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size);
1272         todo_wine expect(0x300, header.Version);
1273         expect(0, header.EmfPlusFlags);
1274         todo_wine expectf(1440.0, header.DpiX);
1275         todo_wine expectf(1440.0, header.DpiY);
1276         expect(0, header.X);
1277         expect(0, header.Y);
1278         todo_wine expect(320, header.Width);
1279         todo_wine expect(320, header.Height);
1280         todo_wine expect(1, U(header).WmfHeader.mtType);
1281         expect(0, header.EmfPlusHeaderSize);
1282         expect(0, header.LogicalDpiX);
1283         expect(0, header.LogicalDpiY);
1284     }
1285
1286     GdipDisposeImage(img);
1287 }
1288
1289 static void test_resolution(void)
1290 {
1291     GpStatus stat;
1292     GpBitmap *bitmap;
1293     REAL res=-1.0;
1294     HDC screendc;
1295     int screenxres, screenyres;
1296
1297     /* create Bitmap */
1298     stat = GdipCreateBitmapFromScan0(1, 1, 32, PixelFormat24bppRGB, NULL, &bitmap);
1299     expect(Ok, stat);
1300
1301     /* test invalid values */
1302     stat = GdipGetImageHorizontalResolution(NULL, &res);
1303     expect(InvalidParameter, stat);
1304
1305     stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, NULL);
1306     expect(InvalidParameter, stat);
1307
1308     stat = GdipGetImageVerticalResolution(NULL, &res);
1309     expect(InvalidParameter, stat);
1310
1311     stat = GdipGetImageVerticalResolution((GpImage*)bitmap, NULL);
1312     expect(InvalidParameter, stat);
1313
1314     stat = GdipBitmapSetResolution(NULL, 96.0, 96.0);
1315     expect(InvalidParameter, stat);
1316
1317     stat = GdipBitmapSetResolution(bitmap, 0.0, 0.0);
1318     expect(InvalidParameter, stat);
1319
1320     /* defaults to screen resolution */
1321     screendc = GetDC(0);
1322
1323     screenxres = GetDeviceCaps(screendc, LOGPIXELSX);
1324     screenyres = GetDeviceCaps(screendc, LOGPIXELSY);
1325
1326     ReleaseDC(0, screendc);
1327
1328     stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, &res);
1329     expect(Ok, stat);
1330     expectf((REAL)screenxres, res);
1331
1332     stat = GdipGetImageVerticalResolution((GpImage*)bitmap, &res);
1333     expect(Ok, stat);
1334     expectf((REAL)screenyres, res);
1335
1336     /* test changing the resolution */
1337     stat = GdipBitmapSetResolution(bitmap, screenxres*2.0, screenyres*3.0);
1338     expect(Ok, stat);
1339
1340     stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, &res);
1341     expect(Ok, stat);
1342     expectf(screenxres*2.0, res);
1343
1344     stat = GdipGetImageVerticalResolution((GpImage*)bitmap, &res);
1345     expect(Ok, stat);
1346     expectf(screenyres*3.0, res);
1347
1348     stat = GdipDisposeImage((GpImage*)bitmap);
1349     expect(Ok, stat);
1350 }
1351
1352 static void test_createhbitmap(void)
1353 {
1354     GpStatus stat;
1355     GpBitmap *bitmap;
1356     HBITMAP hbitmap, oldhbitmap;
1357     BITMAP bm;
1358     int ret;
1359     HDC hdc;
1360     COLORREF pixel;
1361     BYTE bits[640];
1362
1363     memset(bits, 0x68, 640);
1364
1365     /* create Bitmap */
1366     stat = GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB, bits, &bitmap);
1367     expect(Ok, stat);
1368
1369     /* test NULL values */
1370     stat = GdipCreateHBITMAPFromBitmap(NULL, &hbitmap, 0);
1371     expect(InvalidParameter, stat);
1372
1373     stat = GdipCreateHBITMAPFromBitmap(bitmap, NULL, 0);
1374     expect(InvalidParameter, stat);
1375
1376     /* create HBITMAP */
1377     stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0);
1378     expect(Ok, stat);
1379
1380     if (stat == Ok)
1381     {
1382         ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
1383         expect(sizeof(BITMAP), ret);
1384
1385         expect(0, bm.bmType);
1386         expect(10, bm.bmWidth);
1387         expect(20, bm.bmHeight);
1388         expect(40, bm.bmWidthBytes);
1389         expect(1, bm.bmPlanes);
1390         expect(32, bm.bmBitsPixel);
1391         ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
1392
1393         hdc = CreateCompatibleDC(NULL);
1394
1395         oldhbitmap = SelectObject(hdc, hbitmap);
1396         pixel = GetPixel(hdc, 5, 5);
1397         SelectObject(hdc, oldhbitmap);
1398
1399         DeleteDC(hdc);
1400
1401         expect(0x686868, pixel);
1402
1403         DeleteObject(hbitmap);
1404     }
1405
1406     stat = GdipDisposeImage((GpImage*)bitmap);
1407     expect(Ok, stat);
1408 }
1409
1410 static void test_getthumbnail(void)
1411 {
1412     GpStatus stat;
1413     GpImage *bitmap1, *bitmap2;
1414     UINT width, height;
1415
1416     stat = GdipGetImageThumbnail(NULL, 0, 0, &bitmap2, NULL, NULL);
1417     expect(InvalidParameter, stat);
1418
1419     stat = GdipCreateBitmapFromScan0(128, 128, 0, PixelFormat32bppRGB, NULL, (GpBitmap**)&bitmap1);
1420     expect(Ok, stat);
1421
1422     stat = GdipGetImageThumbnail(bitmap1, 0, 0, NULL, NULL, NULL);
1423     expect(InvalidParameter, stat);
1424
1425     stat = GdipGetImageThumbnail(bitmap1, 0, 0, &bitmap2, NULL, NULL);
1426     expect(Ok, stat);
1427
1428     if (stat == Ok)
1429     {
1430         stat = GdipGetImageWidth(bitmap2, &width);
1431         expect(Ok, stat);
1432         expect(120, width);
1433
1434         stat = GdipGetImageHeight(bitmap2, &height);
1435         expect(Ok, stat);
1436         expect(120, height);
1437
1438         GdipDisposeImage(bitmap2);
1439     }
1440
1441     GdipDisposeImage(bitmap1);
1442
1443
1444     stat = GdipCreateBitmapFromScan0(64, 128, 0, PixelFormat32bppRGB, NULL, (GpBitmap**)&bitmap1);
1445     expect(Ok, stat);
1446
1447     stat = GdipGetImageThumbnail(bitmap1, 32, 32, &bitmap2, NULL, NULL);
1448     expect(Ok, stat);
1449
1450     if (stat == Ok)
1451     {
1452         stat = GdipGetImageWidth(bitmap2, &width);
1453         expect(Ok, stat);
1454         expect(32, width);
1455
1456         stat = GdipGetImageHeight(bitmap2, &height);
1457         expect(Ok, stat);
1458         expect(32, height);
1459
1460         GdipDisposeImage(bitmap2);
1461     }
1462
1463     stat = GdipGetImageThumbnail(bitmap1, 0, 0, &bitmap2, NULL, NULL);
1464     expect(Ok, stat);
1465
1466     if (stat == Ok)
1467     {
1468         stat = GdipGetImageWidth(bitmap2, &width);
1469         expect(Ok, stat);
1470         expect(120, width);
1471
1472         stat = GdipGetImageHeight(bitmap2, &height);
1473         expect(Ok, stat);
1474         expect(120, height);
1475
1476         GdipDisposeImage(bitmap2);
1477     }
1478
1479     GdipDisposeImage(bitmap1);
1480 }
1481
1482 static void test_getsetpixel(void)
1483 {
1484     GpStatus stat;
1485     GpBitmap *bitmap;
1486     ARGB color;
1487     BYTE bits[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00,
1488                      0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00};
1489
1490     stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB, bits, &bitmap);
1491     expect(Ok, stat);
1492
1493     /* null parameters */
1494     stat = GdipBitmapGetPixel(NULL, 1, 1, &color);
1495     expect(InvalidParameter, stat);
1496
1497     stat = GdipBitmapGetPixel(bitmap, 1, 1, NULL);
1498     expect(InvalidParameter, stat);
1499
1500     stat = GdipBitmapSetPixel(NULL, 1, 1, 0);
1501     expect(InvalidParameter, stat);
1502
1503     /* out of bounds */
1504     stat = GdipBitmapGetPixel(bitmap, -1, 1, &color);
1505     expect(InvalidParameter, stat);
1506
1507     stat = GdipBitmapSetPixel(bitmap, -1, 1, 0);
1508     expect(InvalidParameter, stat);
1509
1510     stat = GdipBitmapGetPixel(bitmap, 1, -1, &color);
1511     ok(stat == InvalidParameter ||
1512        broken(stat == Ok), /* Older gdiplus */
1513        "Expected InvalidParameter, got %.8x\n", stat);
1514
1515     stat = GdipBitmapSetPixel(bitmap, 1, -1, 0);
1516     ok(stat == InvalidParameter ||
1517        broken(stat == Ok), /* Older gdiplus */
1518        "Expected InvalidParameter, got %.8x\n", stat);
1519
1520     stat = GdipBitmapGetPixel(bitmap, 2, 1, &color);
1521     expect(InvalidParameter, stat);
1522
1523     stat = GdipBitmapSetPixel(bitmap, 2, 1, 0);
1524     expect(InvalidParameter, stat);
1525
1526     stat = GdipBitmapGetPixel(bitmap, 1, 2, &color);
1527     expect(InvalidParameter, stat);
1528
1529     stat = GdipBitmapSetPixel(bitmap, 1, 2, 0);
1530     expect(InvalidParameter, stat);
1531
1532     /* valid use */
1533     stat = GdipBitmapGetPixel(bitmap, 1, 1, &color);
1534     expect(Ok, stat);
1535     expect(0xffffffff, color);
1536
1537     stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
1538     expect(Ok, stat);
1539     expect(0xff0000ff, color);
1540
1541     stat = GdipBitmapSetPixel(bitmap, 1, 1, 0xff676869);
1542     expect(Ok, stat);
1543
1544     stat = GdipBitmapSetPixel(bitmap, 0, 0, 0xff474849);
1545     expect(Ok, stat);
1546
1547     stat = GdipBitmapGetPixel(bitmap, 1, 1, &color);
1548     expect(Ok, stat);
1549     expect(0xff676869, color);
1550
1551     stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
1552     expect(Ok, stat);
1553     expect(0xff474849, color);
1554
1555     stat = GdipDisposeImage((GpImage*)bitmap);
1556     expect(Ok, stat);
1557 }
1558
1559 static void check_halftone_palette(ColorPalette *palette)
1560 {
1561     static const BYTE halftone_values[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
1562     UINT i;
1563
1564     for (i=0; i<palette->Count; i++)
1565     {
1566         ARGB expected=0xff000000;
1567         if (i<8)
1568         {
1569             if (i&1) expected |= 0x800000;
1570             if (i&2) expected |= 0x8000;
1571             if (i&4) expected |= 0x80;
1572         }
1573         else if (i == 8)
1574         {
1575             expected = 0xffc0c0c0;
1576         }
1577         else if (i < 16)
1578         {
1579             if (i&1) expected |= 0xff0000;
1580             if (i&2) expected |= 0xff00;
1581             if (i&4) expected |= 0xff;
1582         }
1583         else if (i < 40)
1584         {
1585             expected = 0x00000000;
1586         }
1587         else
1588         {
1589             expected |= halftone_values[(i-40)%6];
1590             expected |= halftone_values[((i-40)/6)%6] << 8;
1591             expected |= halftone_values[((i-40)/36)%6] << 16;
1592         }
1593         ok(expected == palette->Entries[i], "Expected %.8x, got %.8x, i=%u/%u\n",
1594             expected, palette->Entries[i], i, palette->Count);
1595     }
1596 }
1597
1598 static void test_palette(void)
1599 {
1600     GpStatus stat;
1601     GpBitmap *bitmap;
1602     INT size;
1603     BYTE buffer[1040];
1604     ColorPalette *palette=(ColorPalette*)buffer;
1605     ARGB color=0;
1606
1607     /* test initial palette from non-indexed bitmap */
1608     stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB, NULL, &bitmap);
1609     expect(Ok, stat);
1610
1611     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1612     expect(Ok, stat);
1613     expect(sizeof(UINT)*2+sizeof(ARGB), size);
1614
1615     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1616     expect(Ok, stat);
1617     expect(0, palette->Count);
1618
1619     /* test setting palette on not-indexed bitmap */
1620     palette->Count = 3;
1621
1622     stat = GdipSetImagePalette((GpImage*)bitmap, palette);
1623     expect(Ok, stat);
1624
1625     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1626     expect(Ok, stat);
1627     expect(sizeof(UINT)*2+sizeof(ARGB)*3, size);
1628
1629     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1630     expect(Ok, stat);
1631     expect(3, palette->Count);
1632
1633     GdipDisposeImage((GpImage*)bitmap);
1634
1635     /* test initial palette on 1-bit bitmap */
1636     stat = GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat1bppIndexed, NULL, &bitmap);
1637     expect(Ok, stat);
1638
1639     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1640     expect(Ok, stat);
1641     expect(sizeof(UINT)*2+sizeof(ARGB)*2, size);
1642
1643     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1644     expect(Ok, stat);
1645     expect(PaletteFlagsGrayScale, palette->Flags);
1646     expect(2, palette->Count);
1647
1648     expect(0xff000000, palette->Entries[0]);
1649     expect(0xffffffff, palette->Entries[1]);
1650
1651     /* test getting/setting pixels */
1652     stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
1653     expect(Ok, stat);
1654     expect(0xff000000, color);
1655
1656     stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffffffff);
1657     ok((stat == Ok) ||
1658        broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
1659
1660     if (stat == Ok)
1661     {
1662         stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
1663         expect(Ok, stat);
1664         expect(0xffffffff, color);
1665     }
1666
1667     GdipDisposeImage((GpImage*)bitmap);
1668
1669     /* test initial palette on 4-bit bitmap */
1670     stat = GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat4bppIndexed, NULL, &bitmap);
1671     expect(Ok, stat);
1672
1673     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1674     expect(Ok, stat);
1675     expect(sizeof(UINT)*2+sizeof(ARGB)*16, size);
1676
1677     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1678     expect(Ok, stat);
1679     expect(0, palette->Flags);
1680     expect(16, palette->Count);
1681
1682     check_halftone_palette(palette);
1683
1684     /* test getting/setting pixels */
1685     stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
1686     expect(Ok, stat);
1687     expect(0xff000000, color);
1688
1689     stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffff00ff);
1690     ok((stat == Ok) ||
1691        broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
1692
1693     if (stat == Ok)
1694     {
1695         stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
1696         expect(Ok, stat);
1697         expect(0xffff00ff, color);
1698     }
1699
1700     GdipDisposeImage((GpImage*)bitmap);
1701
1702     /* test initial palette on 8-bit bitmap */
1703     stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat8bppIndexed, NULL, &bitmap);
1704     expect(Ok, stat);
1705
1706     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1707     expect(Ok, stat);
1708     expect(sizeof(UINT)*2+sizeof(ARGB)*256, size);
1709
1710     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1711     expect(Ok, stat);
1712     expect(PaletteFlagsHalftone, palette->Flags);
1713     expect(256, palette->Count);
1714
1715     check_halftone_palette(palette);
1716
1717     /* test getting/setting pixels */
1718     stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
1719     expect(Ok, stat);
1720     expect(0xff000000, color);
1721
1722     stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffcccccc);
1723     ok((stat == Ok) ||
1724        broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
1725
1726     if (stat == Ok)
1727     {
1728         stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
1729         expect(Ok, stat);
1730         expect(0xffcccccc, color);
1731     }
1732
1733     /* test setting/getting a different palette */
1734     palette->Entries[1] = 0xffcccccc;
1735
1736     stat = GdipSetImagePalette((GpImage*)bitmap, palette);
1737     expect(Ok, stat);
1738
1739     palette->Entries[1] = 0;
1740
1741     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1742     expect(Ok, stat);
1743     expect(sizeof(UINT)*2+sizeof(ARGB)*256, size);
1744
1745     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1746     expect(Ok, stat);
1747     expect(PaletteFlagsHalftone, palette->Flags);
1748     expect(256, palette->Count);
1749     expect(0xffcccccc, palette->Entries[1]);
1750
1751     /* test count < 256 */
1752     palette->Flags = 12345;
1753     palette->Count = 3;
1754
1755     stat = GdipSetImagePalette((GpImage*)bitmap, palette);
1756     expect(Ok, stat);
1757
1758     palette->Entries[1] = 0;
1759     palette->Entries[3] = 0xdeadbeef;
1760
1761     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1762     expect(Ok, stat);
1763     expect(sizeof(UINT)*2+sizeof(ARGB)*3, size);
1764
1765     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1766     expect(Ok, stat);
1767     expect(12345, palette->Flags);
1768     expect(3, palette->Count);
1769     expect(0xffcccccc, palette->Entries[1]);
1770     expect(0xdeadbeef, palette->Entries[3]);
1771
1772     /* test count > 256 */
1773     palette->Count = 257;
1774
1775     stat = GdipSetImagePalette((GpImage*)bitmap, palette);
1776     ok(stat == InvalidParameter ||
1777        broken(stat == Ok), /* Old gdiplus behavior */
1778        "Expected %.8x, got %.8x\n", InvalidParameter, stat);
1779
1780     GdipDisposeImage((GpImage*)bitmap);
1781 }
1782
1783 static void test_colormatrix(void)
1784 {
1785     GpStatus stat;
1786     ColorMatrix colormatrix, graymatrix;
1787     GpImageAttributes *imageattr;
1788     const ColorMatrix identity = {{
1789         {1.0,0.0,0.0,0.0,0.0},
1790         {0.0,1.0,0.0,0.0,0.0},
1791         {0.0,0.0,1.0,0.0,0.0},
1792         {0.0,0.0,0.0,1.0,0.0},
1793         {0.0,0.0,0.0,0.0,1.0}}};
1794     const ColorMatrix double_red = {{
1795         {2.0,0.0,0.0,0.0,0.0},
1796         {0.0,1.0,0.0,0.0,0.0},
1797         {0.0,0.0,1.0,0.0,0.0},
1798         {0.0,0.0,0.0,1.0,0.0},
1799         {0.0,0.0,0.0,0.0,1.0}}};
1800     GpBitmap *bitmap1, *bitmap2;
1801     GpGraphics *graphics;
1802     ARGB color;
1803
1804     colormatrix = identity;
1805     graymatrix = identity;
1806
1807     stat = GdipSetImageAttributesColorMatrix(NULL, ColorAdjustTypeDefault,
1808         TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
1809     expect(InvalidParameter, stat);
1810
1811     stat = GdipCreateImageAttributes(&imageattr);
1812     expect(Ok, stat);
1813
1814     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
1815         TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
1816     expect(Ok, stat);
1817
1818     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
1819         TRUE, NULL, NULL, ColorMatrixFlagsDefault);
1820     expect(InvalidParameter, stat);
1821
1822     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
1823         TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
1824     expect(Ok, stat);
1825
1826     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
1827         TRUE, &colormatrix, NULL, ColorMatrixFlagsSkipGrays);
1828     expect(Ok, stat);
1829
1830     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
1831         TRUE, &colormatrix, NULL, ColorMatrixFlagsAltGray);
1832     expect(InvalidParameter, stat);
1833
1834     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
1835         TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsAltGray);
1836     expect(Ok, stat);
1837
1838     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
1839         TRUE, &colormatrix, &graymatrix, 3);
1840     expect(InvalidParameter, stat);
1841
1842     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeCount,
1843         TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
1844     expect(InvalidParameter, stat);
1845
1846     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeAny,
1847         TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
1848     expect(InvalidParameter, stat);
1849
1850     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
1851         FALSE, NULL, NULL, ColorMatrixFlagsDefault);
1852     expect(Ok, stat);
1853
1854     /* Drawing a bitmap transforms the colors */
1855     colormatrix = double_red;
1856     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
1857         TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
1858     expect(Ok, stat);
1859
1860     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap1);
1861     expect(Ok, stat);
1862
1863     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap2);
1864     expect(Ok, stat);
1865
1866     stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff40ffff);
1867     expect(Ok, stat);
1868
1869     stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
1870     expect(Ok, stat);
1871
1872     stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
1873         UnitPixel, imageattr, NULL, NULL);
1874     expect(Ok, stat);
1875
1876     stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
1877     expect(Ok, stat);
1878     todo_wine expect(0xff80ffff, color);
1879
1880     GdipDeleteGraphics(graphics);
1881     GdipDisposeImage((GpImage*)bitmap1);
1882     GdipDisposeImage((GpImage*)bitmap2);
1883     GdipDisposeImageAttributes(imageattr);
1884 }
1885
1886 static void test_gamma(void)
1887 {
1888     GpStatus stat;
1889     GpImageAttributes *imageattr;
1890     GpBitmap *bitmap1, *bitmap2;
1891     GpGraphics *graphics;
1892     ARGB color;
1893
1894     stat = GdipSetImageAttributesGamma(NULL, ColorAdjustTypeDefault, TRUE, 1.0);
1895     expect(InvalidParameter, stat);
1896
1897     stat = GdipCreateImageAttributes(&imageattr);
1898     expect(Ok, stat);
1899
1900     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 1.0);
1901     expect(Ok, stat);
1902
1903     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeAny, TRUE, 1.0);
1904     expect(InvalidParameter, stat);
1905
1906     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, -1.0);
1907     expect(InvalidParameter, stat);
1908
1909     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 0.0);
1910     expect(InvalidParameter, stat);
1911
1912     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 0.5);
1913     expect(Ok, stat);
1914
1915     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, FALSE, 0.0);
1916     expect(Ok, stat);
1917
1918     /* Drawing a bitmap transforms the colors */
1919     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 3.0);
1920     expect(Ok, stat);
1921
1922     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap1);
1923     expect(Ok, stat);
1924
1925     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap2);
1926     expect(Ok, stat);
1927
1928     stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff80ffff);
1929     expect(Ok, stat);
1930
1931     stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
1932     expect(Ok, stat);
1933
1934     stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
1935         UnitPixel, imageattr, NULL, NULL);
1936     expect(Ok, stat);
1937
1938     stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
1939     expect(Ok, stat);
1940     todo_wine ok(color_match(0xff20ffff, color, 1), "Expected ff20ffff, got %.8x\n", color);
1941
1942     GdipDeleteGraphics(graphics);
1943     GdipDisposeImage((GpImage*)bitmap1);
1944     GdipDisposeImage((GpImage*)bitmap2);
1945     GdipDisposeImageAttributes(imageattr);
1946 }
1947
1948 /* 1x1 pixel gif, 2 frames; first frame is white, second is black */
1949 static const unsigned char gifanimation[72] = {
1950 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
1951 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0xf9,0x04,0x00,0x0a,0x00,0xff,
1952 0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x4c,0x01,0x00,
1953 0x21,0xf9,0x04,0x01,0x0a,0x00,0x01,0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,
1954 0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
1955 };
1956
1957 static void test_multiframegif(void)
1958 {
1959     LPSTREAM stream;
1960     HGLOBAL hglob;
1961     LPBYTE data;
1962     HRESULT hres;
1963     GpStatus stat;
1964     GpBitmap *bmp;
1965     ARGB color;
1966     UINT count;
1967     GUID dimension;
1968
1969     /* Test frame functions with an animated GIF */
1970     hglob = GlobalAlloc (0, sizeof(gifanimation));
1971     data = GlobalLock (hglob);
1972     memcpy(data, gifanimation, sizeof(gifanimation));
1973     GlobalUnlock(hglob);
1974
1975     hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
1976     ok(hres == S_OK, "Failed to create a stream\n");
1977     if(hres != S_OK) return;
1978
1979     stat = GdipCreateBitmapFromStream(stream, &bmp);
1980     ok(stat == Ok, "Failed to create a Bitmap\n");
1981     if(stat != Ok){
1982         IStream_Release(stream);
1983         return;
1984     }
1985
1986     /* Bitmap starts at frame 0 */
1987     color = 0xdeadbeef;
1988     stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
1989     expect(Ok, stat);
1990     expect(0xffffffff, color);
1991
1992     /* Check that we get correct metadata */
1993     stat = GdipImageGetFrameDimensionsCount((GpImage*)bmp,&count);
1994     expect(Ok, stat);
1995     expect(1, count);
1996
1997     stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1);
1998     expect(Ok, stat);
1999     expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE);
2000
2001     count = 12345;
2002     stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
2003     expect(Ok, stat);
2004     todo_wine expect(2, count);
2005
2006     /* SelectActiveFrame overwrites our current data */
2007     stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 1);
2008     expect(Ok, stat);
2009
2010     color = 0xdeadbeef;
2011     GdipBitmapGetPixel(bmp, 0, 0, &color);
2012     expect(Ok, stat);
2013     todo_wine expect(0xff000000, color);
2014
2015     stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
2016     expect(Ok, stat);
2017
2018     color = 0xdeadbeef;
2019     GdipBitmapGetPixel(bmp, 0, 0, &color);
2020     expect(Ok, stat);
2021     expect(0xffffffff, color);
2022
2023     /* Write over the image data */
2024     stat = GdipBitmapSetPixel(bmp, 0, 0, 0xff000000);
2025     expect(Ok, stat);
2026
2027     /* Switching to the same frame does not overwrite our changes */
2028     stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
2029     expect(Ok, stat);
2030
2031     stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2032     expect(Ok, stat);
2033     expect(0xff000000, color);
2034
2035     /* But switching to another frame and back does */
2036     stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 1);
2037     expect(Ok, stat);
2038
2039     stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
2040     expect(Ok, stat);
2041
2042     stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2043     expect(Ok, stat);
2044     todo_wine expect(0xffffffff, color);
2045
2046     GdipDisposeImage((GpImage*)bmp);
2047     IStream_Release(stream);
2048
2049     /* Test with a non-animated gif */
2050     hglob = GlobalAlloc (0, sizeof(gifimage));
2051     data = GlobalLock (hglob);
2052     memcpy(data, gifimage, sizeof(gifimage));
2053     GlobalUnlock(hglob);
2054
2055     hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
2056     ok(hres == S_OK, "Failed to create a stream\n");
2057     if(hres != S_OK) return;
2058
2059     stat = GdipCreateBitmapFromStream(stream, &bmp);
2060     ok(stat == Ok, "Failed to create a Bitmap\n");
2061     if(stat != Ok){
2062         IStream_Release(stream);
2063         return;
2064     }
2065
2066     /* Check metadata */
2067     stat = GdipImageGetFrameDimensionsCount((GpImage*)bmp,&count);
2068     expect(Ok, stat);
2069     expect(1, count);
2070
2071     stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1);
2072     expect(Ok, stat);
2073     expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE);
2074
2075     count = 12345;
2076     stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
2077     expect(Ok, stat);
2078     expect(1, count);
2079
2080     GdipDisposeImage((GpImage*)bmp);
2081     IStream_Release(stream);
2082 }
2083
2084 static void test_rotateflip(void)
2085 {
2086     GpImage *bitmap;
2087     GpStatus stat;
2088     BYTE bits[24];
2089     static const BYTE orig_bits[24] = {
2090         0,0,0xff,    0,0xff,0,    0xff,0,0,    23,23,23,
2091         0xff,0xff,0, 0xff,0,0xff, 0,0xff,0xff, 23,23,23};
2092     UINT width, height;
2093     ARGB color;
2094
2095     memcpy(bits, orig_bits, sizeof(bits));
2096     stat = GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB, bits, (GpBitmap**)&bitmap);
2097     expect(Ok, stat);
2098
2099     stat = GdipImageRotateFlip(bitmap, Rotate90FlipNone);
2100     expect(Ok, stat);
2101
2102     stat = GdipGetImageWidth(bitmap, &width);
2103     expect(Ok, stat);
2104     stat = GdipGetImageHeight(bitmap, &height);
2105     expect(Ok, stat);
2106     expect(2, width);
2107     expect(3, height);
2108
2109     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
2110     expect(Ok, stat);
2111     expect(0xff00ffff, color);
2112
2113     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 1, 0, &color);
2114     expect(Ok, stat);
2115     expect(0xffff0000, color);
2116
2117     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 2, &color);
2118     expect(Ok, stat);
2119     expect(0xffffff00, color);
2120
2121     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 1, 2, &color);
2122     expect(Ok, stat);
2123     expect(0xff0000ff, color);
2124
2125     expect(0, bits[0]);
2126     expect(0, bits[1]);
2127     expect(0xff, bits[2]);
2128
2129     GdipDisposeImage(bitmap);
2130
2131     memcpy(bits, orig_bits, sizeof(bits));
2132     stat = GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB, bits, (GpBitmap**)&bitmap);
2133     expect(Ok, stat);
2134
2135     stat = GdipImageRotateFlip(bitmap, RotateNoneFlipX);
2136     expect(Ok, stat);
2137
2138     stat = GdipGetImageWidth(bitmap, &width);
2139     expect(Ok, stat);
2140     stat = GdipGetImageHeight(bitmap, &height);
2141     expect(Ok, stat);
2142     expect(3, width);
2143     expect(2, height);
2144
2145     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
2146     expect(Ok, stat);
2147     expect(0xff0000ff, color);
2148
2149     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 0, &color);
2150     expect(Ok, stat);
2151     expect(0xffff0000, color);
2152
2153     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 1, &color);
2154     expect(Ok, stat);
2155     expect(0xffffff00, color);
2156
2157     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 1, &color);
2158     expect(Ok, stat);
2159     expect(0xff00ffff, color);
2160
2161     expect(0, bits[0]);
2162     expect(0, bits[1]);
2163     expect(0xff, bits[2]);
2164
2165     GdipDisposeImage(bitmap);
2166
2167     memcpy(bits, orig_bits, sizeof(bits));
2168     stat = GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB, bits, (GpBitmap**)&bitmap);
2169     expect(Ok, stat);
2170
2171     stat = GdipImageRotateFlip(bitmap, RotateNoneFlipY);
2172     expect(Ok, stat);
2173
2174     stat = GdipGetImageWidth(bitmap, &width);
2175     expect(Ok, stat);
2176     stat = GdipGetImageHeight(bitmap, &height);
2177     expect(Ok, stat);
2178     expect(3, width);
2179     expect(2, height);
2180
2181     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
2182     expect(Ok, stat);
2183     expect(0xff00ffff, color);
2184
2185     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 0, &color);
2186     expect(Ok, stat);
2187     expect(0xffffff00, color);
2188
2189     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 1, &color);
2190     expect(Ok, stat);
2191     expect(0xffff0000, color);
2192
2193     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 1, &color);
2194     expect(Ok, stat);
2195     expect(0xff0000ff, color);
2196
2197     expect(0, bits[0]);
2198     expect(0, bits[1]);
2199     expect(0xff, bits[2]);
2200
2201     GdipDisposeImage(bitmap);
2202 }
2203
2204 static void test_remaptable(void)
2205 {
2206     GpStatus stat;
2207     GpImageAttributes *imageattr;
2208     GpBitmap *bitmap1, *bitmap2;
2209     GpGraphics *graphics;
2210     ARGB color;
2211     ColorMap *map;
2212
2213     map = GdipAlloc(sizeof(ColorMap));
2214
2215     map->oldColor.Argb = 0xff00ff00;
2216     map->newColor.Argb = 0xffff00ff;
2217
2218     stat = GdipSetImageAttributesRemapTable(NULL, ColorAdjustTypeDefault, TRUE, 1, map);
2219     expect(InvalidParameter, stat);
2220
2221     stat = GdipCreateImageAttributes(&imageattr);
2222     expect(Ok, stat);
2223
2224     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, TRUE, 1, NULL);
2225     expect(InvalidParameter, stat);
2226
2227     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeCount, TRUE, 1, map);
2228     expect(InvalidParameter, stat);
2229
2230     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeAny, TRUE, 1, map);
2231     expect(InvalidParameter, stat);
2232
2233     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, TRUE, 0, map);
2234     expect(InvalidParameter, stat);
2235
2236     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, FALSE, 0, NULL);
2237     expect(Ok, stat);
2238
2239     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, TRUE, 1, map);
2240     expect(Ok, stat);
2241
2242     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap1);
2243     expect(Ok, stat);
2244
2245     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap2);
2246     expect(Ok, stat);
2247
2248     stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff00ff00);
2249     expect(Ok, stat);
2250
2251     stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
2252     expect(Ok, stat);
2253
2254     stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2255         UnitPixel, imageattr, NULL, NULL);
2256     expect(Ok, stat);
2257
2258     stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2259     expect(Ok, stat);
2260     ok(color_match(0xffff00ff, color, 1), "Expected ffff00ff, got %.8x\n", color);
2261
2262     GdipDeleteGraphics(graphics);
2263     GdipDisposeImage((GpImage*)bitmap1);
2264     GdipDisposeImage((GpImage*)bitmap2);
2265     GdipDisposeImageAttributes(imageattr);
2266     GdipFree(map);
2267 }
2268
2269 static void test_colorkey(void)
2270 {
2271     GpStatus stat;
2272     GpImageAttributes *imageattr;
2273     GpBitmap *bitmap1, *bitmap2;
2274     GpGraphics *graphics;
2275     ARGB color;
2276
2277     stat = GdipSetImageAttributesColorKeys(NULL, ColorAdjustTypeDefault, TRUE, 0xff405060, 0xff708090);
2278     expect(InvalidParameter, stat);
2279
2280     stat = GdipCreateImageAttributes(&imageattr);
2281     expect(Ok, stat);
2282
2283     stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeCount, TRUE, 0xff405060, 0xff708090);
2284     expect(InvalidParameter, stat);
2285
2286     stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeAny, TRUE, 0xff405060, 0xff708090);
2287     expect(InvalidParameter, stat);
2288
2289     stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeDefault, TRUE, 0xff405060, 0xff708090);
2290     expect(Ok, stat);
2291
2292     stat = GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB, NULL, &bitmap1);
2293     expect(Ok, stat);
2294
2295     stat = GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB, NULL, &bitmap2);
2296     expect(Ok, stat);
2297
2298     stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0x20405060);
2299     expect(Ok, stat);
2300
2301     stat = GdipBitmapSetPixel(bitmap1, 0, 1, 0x40506070);
2302     expect(Ok, stat);
2303
2304     stat = GdipBitmapSetPixel(bitmap1, 1, 0, 0x60708090);
2305     expect(Ok, stat);
2306
2307     stat = GdipBitmapSetPixel(bitmap1, 1, 1, 0xffffffff);
2308     expect(Ok, stat);
2309
2310     stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
2311     expect(Ok, stat);
2312
2313     stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,2,2, 0,0,2,2,
2314         UnitPixel, imageattr, NULL, NULL);
2315     expect(Ok, stat);
2316
2317     stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2318     expect(Ok, stat);
2319     ok(color_match(0x00000000, color, 1), "Expected ffff00ff, got %.8x\n", color);
2320
2321     stat = GdipBitmapGetPixel(bitmap2, 0, 1, &color);
2322     expect(Ok, stat);
2323     ok(color_match(0x00000000, color, 1), "Expected ffff00ff, got %.8x\n", color);
2324
2325     stat = GdipBitmapGetPixel(bitmap2, 1, 0, &color);
2326     expect(Ok, stat);
2327     ok(color_match(0x00000000, color, 1), "Expected ffff00ff, got %.8x\n", color);
2328
2329     stat = GdipBitmapGetPixel(bitmap2, 1, 1, &color);
2330     expect(Ok, stat);
2331     ok(color_match(0xffffffff, color, 1), "Expected ffff00ff, got %.8x\n", color);
2332
2333     GdipDeleteGraphics(graphics);
2334     GdipDisposeImage((GpImage*)bitmap1);
2335     GdipDisposeImage((GpImage*)bitmap2);
2336     GdipDisposeImageAttributes(imageattr);
2337 }
2338
2339 static void test_dispose(void)
2340 {
2341     GpStatus stat;
2342     GpImage *image;
2343     char invalid_image[256];
2344
2345     stat = GdipDisposeImage(NULL);
2346     expect(InvalidParameter, stat);
2347
2348     stat = GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB, NULL, (GpBitmap**)&image);
2349     expect(Ok, stat);
2350
2351     stat = GdipDisposeImage(image);
2352     expect(Ok, stat);
2353
2354     stat = GdipDisposeImage(image);
2355     expect(ObjectBusy, stat);
2356
2357     memset(invalid_image, 0, 256);
2358     stat = GdipDisposeImage((GpImage*)invalid_image);
2359     expect(ObjectBusy, stat);
2360 }
2361
2362 START_TEST(image)
2363 {
2364     struct GdiplusStartupInput gdiplusStartupInput;
2365     ULONG_PTR gdiplusToken;
2366
2367     gdiplusStartupInput.GdiplusVersion              = 1;
2368     gdiplusStartupInput.DebugEventCallback          = NULL;
2369     gdiplusStartupInput.SuppressBackgroundThread    = 0;
2370     gdiplusStartupInput.SuppressExternalCodecs      = 0;
2371
2372     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
2373
2374     test_Scan0();
2375     test_FromGdiDib();
2376     test_GetImageDimension();
2377     test_GdipImageGetFrameDimensionsCount();
2378     test_LoadingImages();
2379     test_SavingImages();
2380     test_encoders();
2381     test_LockBits();
2382     test_LockBits_UserBuf();
2383     test_GdipCreateBitmapFromHBITMAP();
2384     test_GdipGetImageFlags();
2385     test_GdipCloneImage();
2386     test_testcontrol();
2387     test_fromhicon();
2388     test_getrawformat();
2389     test_loadwmf();
2390     test_createfromwmf();
2391     test_resolution();
2392     test_createhbitmap();
2393     test_getthumbnail();
2394     test_getsetpixel();
2395     test_palette();
2396     test_colormatrix();
2397     test_gamma();
2398     test_multiframegif();
2399     test_rotateflip();
2400     test_remaptable();
2401     test_colorkey();
2402     test_dispose();
2403
2404     GdiplusShutdown(gdiplusToken);
2405 }