hlink: Implement IHlinkBrowseContext::GetBrowseWindowInfo.
[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_GetImageDimension(void)
162 {
163     GpBitmap *bm;
164     GpStatus stat;
165     const REAL WIDTH = 10.0, HEIGHT = 20.0;
166     REAL w,h;
167
168     bm = (GpBitmap*)0xdeadbeef;
169     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB,NULL, &bm);
170     expect(Ok,stat);
171     ok((GpBitmap*)0xdeadbeef != bm, "Expected bitmap to not be 0xdeadbeef\n");
172     ok(NULL != bm, "Expected bitmap to not be NULL\n");
173
174     stat = GdipGetImageDimension(NULL,&w,&h);
175     expect(InvalidParameter, stat);
176
177     stat = GdipGetImageDimension((GpImage*)bm,NULL,&h);
178     expect(InvalidParameter, stat);
179
180     stat = GdipGetImageDimension((GpImage*)bm,&w,NULL);
181     expect(InvalidParameter, stat);
182
183     w = -1;
184     h = -1;
185     stat = GdipGetImageDimension((GpImage*)bm,&w,&h);
186     expect(Ok, stat);
187     expectf(WIDTH,  w);
188     expectf(HEIGHT, h);
189     GdipDisposeImage((GpImage*)bm);
190 }
191
192 static void test_GdipImageGetFrameDimensionsCount(void)
193 {
194     GpBitmap *bm;
195     GpStatus stat;
196     const REAL WIDTH = 10.0, HEIGHT = 20.0;
197     UINT w;
198     GUID dimension = {0};
199     UINT count;
200     ARGB color;
201
202     bm = (GpBitmap*)0xdeadbeef;
203     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB,NULL, &bm);
204     expect(Ok,stat);
205     ok((GpBitmap*)0xdeadbeef != bm, "Expected bitmap to not be 0xdeadbeef\n");
206     ok(NULL != bm, "Expected bitmap to not be NULL\n");
207
208     stat = GdipImageGetFrameDimensionsCount(NULL,&w);
209     expect(InvalidParameter, stat);
210
211     stat = GdipImageGetFrameDimensionsCount((GpImage*)bm,NULL);
212     expect(InvalidParameter, stat);
213
214     w = -1;
215     stat = GdipImageGetFrameDimensionsCount((GpImage*)bm,&w);
216     expect(Ok, stat);
217     expect(1, w);
218
219     stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 1);
220     expect(Ok, stat);
221     expect_guid(&FrameDimensionPage, &dimension, __LINE__, FALSE);
222
223     stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 2);
224     expect(InvalidParameter, stat);
225
226     stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 0);
227     expect(InvalidParameter, stat);
228
229     stat = GdipImageGetFrameCount(NULL, &dimension, &count);
230     expect(InvalidParameter, stat);
231
232     /* WinXP crashes on this test */
233     if(0)
234     {
235         stat = GdipImageGetFrameCount((GpImage*)bm, &dimension, NULL);
236         expect(InvalidParameter, stat);
237     }
238
239     stat = GdipImageGetFrameCount((GpImage*)bm, NULL, &count);
240     expect(Ok, stat);
241
242     count = 12345;
243     stat = GdipImageGetFrameCount((GpImage*)bm, &dimension, &count);
244     expect(Ok, stat);
245     expect(1, count);
246
247     GdipBitmapSetPixel(bm, 0, 0, 0xffffffff);
248
249     stat = GdipImageSelectActiveFrame((GpImage*)bm, &dimension, 0);
250     expect(Ok, stat);
251
252     /* SelectActiveFrame has no effect on image data of memory bitmaps */
253     color = 0xdeadbeef;
254     GdipBitmapGetPixel(bm, 0, 0, &color);
255     expect(0xffffffff, color);
256
257     GdipDisposeImage((GpImage*)bm);
258 }
259
260 static void test_LoadingImages(void)
261 {
262     GpStatus stat;
263
264     stat = GdipCreateBitmapFromFile(0, 0);
265     expect(InvalidParameter, stat);
266
267     stat = GdipCreateBitmapFromFile(0, (GpBitmap**)0xdeadbeef);
268     expect(InvalidParameter, stat);
269
270     stat = GdipLoadImageFromFile(0, 0);
271     expect(InvalidParameter, stat);
272
273     stat = GdipLoadImageFromFile(0, (GpImage**)0xdeadbeef);
274     expect(InvalidParameter, stat);
275
276     stat = GdipLoadImageFromFileICM(0, 0);
277     expect(InvalidParameter, stat);
278
279     stat = GdipLoadImageFromFileICM(0, (GpImage**)0xdeadbeef);
280     expect(InvalidParameter, stat);
281 }
282
283 static void test_SavingImages(void)
284 {
285     GpStatus stat;
286     GpBitmap *bm;
287     UINT n;
288     UINT s;
289     const REAL WIDTH = 10.0, HEIGHT = 20.0;
290     REAL w, h;
291     ImageCodecInfo *codecs;
292     static const CHAR filenameA[] = "a.bmp";
293     static const WCHAR filename[] = { 'a','.','b','m','p',0 };
294
295     codecs = NULL;
296
297     stat = GdipSaveImageToFile(0, 0, 0, 0);
298     expect(InvalidParameter, stat);
299
300     bm = NULL;
301     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
302     expect(Ok, stat);
303     if (!bm)
304         return;
305
306     /* invalid params */
307     stat = GdipSaveImageToFile((GpImage*)bm, 0, 0, 0);
308     expect(InvalidParameter, stat);
309
310     stat = GdipSaveImageToFile((GpImage*)bm, filename, 0, 0);
311     expect(InvalidParameter, stat);
312
313     /* encoder tests should succeed -- already tested */
314     stat = GdipGetImageEncodersSize(&n, &s);
315     if (stat != Ok || n == 0) goto cleanup;
316
317     codecs = GdipAlloc(s);
318     if (!codecs) goto cleanup;
319
320     stat = GdipGetImageEncoders(n, s, codecs);
321     if (stat != Ok) goto cleanup;
322
323     stat = GdipSaveImageToFile((GpImage*)bm, filename, &codecs[0].Clsid, 0);
324     expect(stat, Ok);
325
326     GdipDisposeImage((GpImage*)bm);
327     bm = 0;
328
329     /* re-load and check image stats */
330     stat = GdipLoadImageFromFile(filename, (GpImage**)&bm);
331     expect(stat, Ok);
332     if (stat != Ok) goto cleanup;
333
334     stat = GdipGetImageDimension((GpImage*)bm, &w, &h);
335     if (stat != Ok) goto cleanup;
336
337     expectf(WIDTH, w);
338     expectf(HEIGHT, h);
339
340  cleanup:
341     GdipFree(codecs);
342     if (bm)
343         GdipDisposeImage((GpImage*)bm);
344     ok(DeleteFileA(filenameA), "Delete failed.\n");
345 }
346
347 static void test_encoders(void)
348 {
349     GpStatus stat;
350     UINT n;
351     UINT s;
352     ImageCodecInfo *codecs;
353     int i;
354     int bmp_found;
355
356     static const CHAR bmp_format[] = "BMP";
357
358     stat = GdipGetImageEncodersSize(&n, &s);
359     expect(stat, Ok);
360
361     codecs = GdipAlloc(s);
362     if (!codecs)
363         return;
364
365     stat = GdipGetImageEncoders(n, s, NULL);
366     expect(GenericError, stat);
367
368     stat = GdipGetImageEncoders(0, s, codecs);
369     expect(GenericError, stat);
370
371     stat = GdipGetImageEncoders(n, s-1, codecs);
372     expect(GenericError, stat);
373
374     stat = GdipGetImageEncoders(n, s+1, codecs);
375     expect(GenericError, stat);
376
377     stat = GdipGetImageEncoders(n, s, codecs);
378     expect(stat, Ok);
379
380     bmp_found = FALSE;
381     for (i = 0; i < n; i++)
382         {
383             CHAR desc[32];
384
385             WideCharToMultiByte(CP_ACP, 0, codecs[i].FormatDescription, -1,
386                                 desc, 32, 0, 0);
387
388             if (CompareStringA(LOCALE_SYSTEM_DEFAULT, 0,
389                                desc, -1,
390                                bmp_format, -1) == CSTR_EQUAL) {
391                 bmp_found = TRUE;
392                 break;
393             }
394         }
395     if (!bmp_found)
396         ok(FALSE, "No BMP codec found.\n");
397
398     GdipFree(codecs);
399 }
400
401 static void test_LockBits(void)
402 {
403     GpStatus stat;
404     GpBitmap *bm;
405     GpRect rect;
406     BitmapData bd;
407     const INT WIDTH = 10, HEIGHT = 20;
408
409     bm = NULL;
410     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
411     expect(Ok, stat);
412
413     rect.X = 2;
414     rect.Y = 3;
415     rect.Width = 4;
416     rect.Height = 5;
417
418     /* read-only */
419     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
420     expect(Ok, stat);
421
422     if (stat == Ok) {
423         stat = GdipBitmapUnlockBits(bm, &bd);
424         expect(Ok, stat);
425     }
426
427     /* read-only, with NULL rect -> whole bitmap lock */
428     stat = GdipBitmapLockBits(bm, NULL, ImageLockModeRead, PixelFormat24bppRGB, &bd);
429     expect(Ok, stat);
430     expect(bd.Width,  WIDTH);
431     expect(bd.Height, HEIGHT);
432
433     if (stat == Ok) {
434         stat = GdipBitmapUnlockBits(bm, &bd);
435         expect(Ok, stat);
436     }
437
438     /* read-only, consecutive */
439     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
440     expect(Ok, stat);
441
442     if (stat == Ok) {
443         stat = GdipBitmapUnlockBits(bm, &bd);
444         expect(Ok, stat);
445     }
446
447     stat = GdipDisposeImage((GpImage*)bm);
448     expect(Ok, stat);
449     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
450     expect(Ok, stat);
451
452     /* read x2 */
453     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
454     expect(Ok, stat);
455     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
456     expect(WrongState, stat);
457
458     stat = GdipBitmapUnlockBits(bm, &bd);
459     expect(Ok, stat);
460
461     stat = GdipDisposeImage((GpImage*)bm);
462     expect(Ok, stat);
463     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
464     expect(Ok, stat);
465
466     /* write, no modification */
467     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
468     expect(Ok, stat);
469
470     if (stat == Ok) {
471         stat = GdipBitmapUnlockBits(bm, &bd);
472         expect(Ok, stat);
473     }
474
475     /* write, consecutive */
476     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
477     expect(Ok, stat);
478
479     if (stat == Ok) {
480         stat = GdipBitmapUnlockBits(bm, &bd);
481         expect(Ok, stat);
482     }
483
484     stat = GdipDisposeImage((GpImage*)bm);
485     expect(Ok, stat);
486     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
487     expect(Ok, stat);
488
489     /* write, modify */
490     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
491     expect(Ok, stat);
492
493     if (stat == Ok) {
494         if (bd.Scan0)
495             ((char*)bd.Scan0)[2] = 0xff;
496
497         stat = GdipBitmapUnlockBits(bm, &bd);
498         expect(Ok, stat);
499     }
500
501     stat = GdipDisposeImage((GpImage*)bm);
502     expect(Ok, stat);
503
504     /* dispose locked */
505     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
506     expect(Ok, stat);
507     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
508     expect(Ok, stat);
509     stat = GdipDisposeImage((GpImage*)bm);
510     expect(Ok, stat);
511 }
512
513 static void test_GdipCreateBitmapFromHBITMAP(void)
514 {
515     GpBitmap* gpbm = NULL;
516     HBITMAP hbm = NULL;
517     HPALETTE hpal = NULL;
518     GpStatus stat;
519     BYTE buff[1000];
520     LOGPALETTE* LogPal = NULL;
521     REAL width, height;
522     const REAL WIDTH1 = 5;
523     const REAL HEIGHT1 = 15;
524     const REAL WIDTH2 = 10;
525     const REAL HEIGHT2 = 20;
526     HDC hdc;
527     BITMAPINFO bmi;
528     BYTE *bits;
529
530     stat = GdipCreateBitmapFromHBITMAP(NULL, NULL, NULL);
531     expect(InvalidParameter, stat);
532
533     hbm = CreateBitmap(WIDTH1, HEIGHT1, 1, 1, NULL);
534     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, NULL);
535     expect(InvalidParameter, stat);
536
537     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
538     expect(Ok, stat);
539     expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
540     expectf(WIDTH1,  width);
541     expectf(HEIGHT1, height);
542     if (stat == Ok)
543         GdipDisposeImage((GpImage*)gpbm);
544     DeleteObject(hbm);
545
546     memset(buff, 0, sizeof(buff));
547     hbm = CreateBitmap(WIDTH2, HEIGHT2, 1, 1, &buff);
548     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
549     expect(Ok, stat);
550     /* raw format */
551     expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)gpbm, __LINE__, FALSE);
552
553     expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
554     expectf(WIDTH2,  width);
555     expectf(HEIGHT2, height);
556     if (stat == Ok)
557         GdipDisposeImage((GpImage*)gpbm);
558     DeleteObject(hbm);
559
560     hdc = CreateCompatibleDC(0);
561     ok(hdc != NULL, "CreateCompatibleDC failed\n");
562     bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
563     bmi.bmiHeader.biHeight = HEIGHT1;
564     bmi.bmiHeader.biWidth = WIDTH1;
565     bmi.bmiHeader.biBitCount = 24;
566     bmi.bmiHeader.biPlanes = 1;
567     bmi.bmiHeader.biCompression = BI_RGB;
568
569     hbm = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
570     ok(hbm != NULL, "CreateDIBSection failed\n");
571
572     bits[0] = 0;
573
574     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
575     expect(Ok, stat);
576     expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
577     expectf(WIDTH1,  width);
578     expectf(HEIGHT1, height);
579     if (stat == Ok)
580     {
581         /* test whether writing to the bitmap affects the original */
582         stat = GdipBitmapSetPixel(gpbm, 0, 0, 0xffffffff);
583         expect(Ok, stat);
584
585         expect(0, bits[0]);
586
587         GdipDisposeImage((GpImage*)gpbm);
588     }
589
590     LogPal = GdipAlloc(sizeof(LOGPALETTE));
591     ok(LogPal != NULL, "unable to allocate LOGPALETTE\n");
592     LogPal->palVersion = 0x300;
593     LogPal->palNumEntries = 1;
594     hpal = CreatePalette(LogPal);
595     ok(hpal != NULL, "CreatePalette failed\n");
596     GdipFree(LogPal);
597
598     stat = GdipCreateBitmapFromHBITMAP(hbm, hpal, &gpbm);
599     todo_wine
600     {
601         expect(Ok, stat);
602     }
603     if (stat == Ok)
604         GdipDisposeImage((GpImage*)gpbm);
605
606     DeleteObject(hpal);
607     DeleteObject(hbm);
608 }
609
610 static void test_GdipGetImageFlags(void)
611 {
612     GpImage *img;
613     GpStatus stat;
614     UINT flags;
615
616     img = (GpImage*)0xdeadbeef;
617
618     stat = GdipGetImageFlags(NULL, NULL);
619     expect(InvalidParameter, stat);
620
621     stat = GdipGetImageFlags(NULL, &flags);
622     expect(InvalidParameter, stat);
623
624     stat = GdipGetImageFlags(img, NULL);
625     expect(InvalidParameter, stat);
626 }
627
628 static void test_GdipCloneImage(void)
629 {
630     GpStatus stat;
631     GpRectF rectF;
632     GpUnit unit;
633     GpBitmap *bm;
634     GpImage *image_src, *image_dest = NULL;
635     const INT WIDTH = 10, HEIGHT = 20;
636
637     /* Create an image, clone it, delete the original, make sure the copy works */
638     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
639     expect(Ok, stat);
640     expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bm, __LINE__, FALSE);
641
642     image_src = ((GpImage*)bm);
643     stat = GdipCloneImage(image_src, &image_dest);
644     expect(Ok, stat);
645     expect_rawformat(&ImageFormatMemoryBMP, image_dest, __LINE__, FALSE);
646
647     stat = GdipDisposeImage((GpImage*)bm);
648     expect(Ok, stat);
649     stat = GdipGetImageBounds(image_dest, &rectF, &unit);
650     expect(Ok, stat);
651
652     /* Treat FP values carefully */
653     expectf((REAL)WIDTH, rectF.Width);
654     expectf((REAL)HEIGHT, rectF.Height);
655
656     stat = GdipDisposeImage(image_dest);
657     expect(Ok, stat);
658 }
659
660 static void test_testcontrol(void)
661 {
662     GpStatus stat;
663     DWORD param;
664
665     param = 0;
666     stat = GdipTestControl(TestControlGetBuildNumber, &param);
667     expect(Ok, stat);
668     ok(param != 0, "Build number expected, got %u\n", param);
669 }
670
671 static void test_fromhicon(void)
672 {
673     static const BYTE bmp_bits[1024];
674     HBITMAP hbmMask, hbmColor;
675     ICONINFO info;
676     HICON hIcon;
677     GpStatus stat;
678     GpBitmap *bitmap = NULL;
679     UINT dim;
680     ImageType type;
681     PixelFormat format;
682
683     /* NULL */
684     stat = GdipCreateBitmapFromHICON(NULL, NULL);
685     expect(InvalidParameter, stat);
686     stat = GdipCreateBitmapFromHICON(NULL, &bitmap);
687     expect(InvalidParameter, stat);
688
689     /* color icon 1 bit */
690     hbmMask = CreateBitmap(16, 16, 1, 1, bmp_bits);
691     ok(hbmMask != 0, "CreateBitmap failed\n");
692     hbmColor = CreateBitmap(16, 16, 1, 1, bmp_bits);
693     ok(hbmColor != 0, "CreateBitmap failed\n");
694     info.fIcon = TRUE;
695     info.xHotspot = 8;
696     info.yHotspot = 8;
697     info.hbmMask = hbmMask;
698     info.hbmColor = hbmColor;
699     hIcon = CreateIconIndirect(&info);
700     ok(hIcon != 0, "CreateIconIndirect failed\n");
701     DeleteObject(hbmMask);
702     DeleteObject(hbmColor);
703
704     stat = GdipCreateBitmapFromHICON(hIcon, &bitmap);
705     ok(stat == Ok ||
706        broken(stat == InvalidParameter), /* Win98 */
707        "Expected Ok, got %.8x\n", stat);
708     if(stat == Ok){
709        /* check attributes */
710        stat = GdipGetImageHeight((GpImage*)bitmap, &dim);
711        expect(Ok, stat);
712        expect(16, dim);
713        stat = GdipGetImageWidth((GpImage*)bitmap, &dim);
714        expect(Ok, stat);
715        expect(16, dim);
716        stat = GdipGetImageType((GpImage*)bitmap, &type);
717        expect(Ok, stat);
718        expect(ImageTypeBitmap, type);
719        stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format);
720        expect(PixelFormat32bppARGB, format);
721        /* raw format */
722        expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
723        GdipDisposeImage((GpImage*)bitmap);
724     }
725     DestroyIcon(hIcon);
726
727     /* color icon 8 bpp */
728     hbmMask = CreateBitmap(16, 16, 1, 8, bmp_bits);
729     ok(hbmMask != 0, "CreateBitmap failed\n");
730     hbmColor = CreateBitmap(16, 16, 1, 8, bmp_bits);
731     ok(hbmColor != 0, "CreateBitmap failed\n");
732     info.fIcon = TRUE;
733     info.xHotspot = 8;
734     info.yHotspot = 8;
735     info.hbmMask = hbmMask;
736     info.hbmColor = hbmColor;
737     hIcon = CreateIconIndirect(&info);
738     ok(hIcon != 0, "CreateIconIndirect failed\n");
739     DeleteObject(hbmMask);
740     DeleteObject(hbmColor);
741
742     stat = GdipCreateBitmapFromHICON(hIcon, &bitmap);
743     expect(Ok, stat);
744     if(stat == Ok){
745         /* check attributes */
746         stat = GdipGetImageHeight((GpImage*)bitmap, &dim);
747         expect(Ok, stat);
748         expect(16, dim);
749         stat = GdipGetImageWidth((GpImage*)bitmap, &dim);
750         expect(Ok, stat);
751         expect(16, dim);
752         stat = GdipGetImageType((GpImage*)bitmap, &type);
753         expect(Ok, stat);
754         expect(ImageTypeBitmap, type);
755         stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format);
756         expect(PixelFormat32bppARGB, format);
757         /* raw format */
758         expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
759         GdipDisposeImage((GpImage*)bitmap);
760     }
761     DestroyIcon(hIcon);
762 }
763
764 /* 1x1 pixel png */
765 static const unsigned char pngimage[285] = {
766 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
767 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
768 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
769 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
770 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
771 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
772 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
773 };
774 /* 1x1 pixel gif */
775 static const unsigned char gifimage[35] = {
776 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
777 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
778 0x01,0x00,0x3b
779 };
780 /* 1x1 pixel bmp */
781 static const unsigned char bmpimage[66] = {
782 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
783 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
784 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
785 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
786 0x00,0x00
787 };
788 /* 1x1 pixel jpg */
789 static const unsigned char jpgimage[285] = {
790 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
791 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
792 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
793 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
794 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
795 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
796 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
797 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
798 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
799 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
800 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
801 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
802 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
803 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
804 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
805 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
806 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
807 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
808 };
809 /* 320x320 twip wmf */
810 static const unsigned char wmfimage[180] = {
811 0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05,
812 0x00,0x00,0x00,0x00,0xb1,0x52,0x01,0x00,0x09,0x00,0x00,0x03,0x4f,0x00,0x00,0x00,
813 0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0b,0x02,0x00,0x00,
814 0x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x02,0x40,0x01,0x40,0x01,0x04,0x00,0x00,0x00,
815 0x02,0x01,0x01,0x00,0x04,0x00,0x00,0x00,0x04,0x01,0x0d,0x00,0x08,0x00,0x00,0x00,
816 0xfa,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
817 0x2d,0x01,0x00,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,0x01,0x00,0x00,0x00,0x00,0x00,
818 0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x01,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,
819 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x02,0x00,
820 0x07,0x00,0x00,0x00,0x1b,0x04,0x40,0x01,0x40,0x01,0x00,0x00,0x00,0x00,0x04,0x00,
821 0x00,0x00,0xf0,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0xf0,0x01,0x01,0x00,0x03,0x00,
822 0x00,0x00,0x00,0x00
823 };
824 static void test_getrawformat(void)
825 {
826     test_bufferrawformat((void*)pngimage, sizeof(pngimage), &ImageFormatPNG,  __LINE__, FALSE);
827     test_bufferrawformat((void*)gifimage, sizeof(gifimage), &ImageFormatGIF,  __LINE__, FALSE);
828     test_bufferrawformat((void*)bmpimage, sizeof(bmpimage), &ImageFormatBMP,  __LINE__, FALSE);
829     test_bufferrawformat((void*)jpgimage, sizeof(jpgimage), &ImageFormatJPEG, __LINE__, FALSE);
830     test_bufferrawformat((void*)wmfimage, sizeof(wmfimage), &ImageFormatWMF, __LINE__, FALSE);
831 }
832
833 static void test_loadwmf(void)
834 {
835     LPSTREAM stream;
836     HGLOBAL  hglob;
837     LPBYTE   data;
838     HRESULT  hres;
839     GpStatus stat;
840     GpImage *img;
841     GpRectF bounds;
842     GpUnit unit;
843     REAL res = 12345.0;
844     MetafileHeader header;
845
846     hglob = GlobalAlloc (0, sizeof(wmfimage));
847     data = GlobalLock (hglob);
848     memcpy(data, wmfimage, sizeof(wmfimage));
849     GlobalUnlock(hglob); data = NULL;
850
851     hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
852     ok(hres == S_OK, "Failed to create a stream\n");
853     if(hres != S_OK) return;
854
855     stat = GdipLoadImageFromStream(stream, &img);
856     ok(stat == Ok, "Failed to create a Bitmap\n");
857     if(stat != Ok){
858         IStream_Release(stream);
859         return;
860     }
861
862     IStream_Release(stream);
863
864     stat = GdipGetImageBounds(img, &bounds, &unit);
865     expect(Ok, stat);
866     todo_wine expect(UnitPixel, unit);
867     expectf(0.0, bounds.X);
868     expectf(0.0, bounds.Y);
869     todo_wine expectf(320.0, bounds.Width);
870     todo_wine expectf(320.0, bounds.Height);
871
872     stat = GdipGetImageHorizontalResolution(img, &res);
873     expect(Ok, stat);
874     todo_wine expectf(1440.0, res);
875
876     stat = GdipGetImageVerticalResolution(img, &res);
877     expect(Ok, stat);
878     todo_wine expectf(1440.0, res);
879
880     memset(&header, 0, sizeof(header));
881     stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header);
882     expect(Ok, stat);
883     if (stat == Ok)
884     {
885         todo_wine expect(MetafileTypeWmfPlaceable, header.Type);
886         todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size);
887         todo_wine expect(0x300, header.Version);
888         expect(0, header.EmfPlusFlags);
889         todo_wine expectf(1440.0, header.DpiX);
890         todo_wine expectf(1440.0, header.DpiY);
891         expect(0, header.X);
892         expect(0, header.Y);
893         todo_wine expect(320, header.Width);
894         todo_wine expect(320, header.Height);
895         todo_wine expect(1, header.WmfHeader.mtType);
896         expect(0, header.EmfPlusHeaderSize);
897         expect(0, header.LogicalDpiX);
898         expect(0, header.LogicalDpiY);
899     }
900
901     GdipDisposeImage(img);
902 }
903
904 static void test_createfromwmf(void)
905 {
906     HMETAFILE hwmf;
907     GpImage *img;
908     GpStatus stat;
909     GpRectF bounds;
910     GpUnit unit;
911     REAL res = 12345.0;
912     MetafileHeader header;
913
914     hwmf = SetMetaFileBitsEx(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader),
915         wmfimage+sizeof(WmfPlaceableFileHeader));
916     ok(hwmf != 0, "SetMetaFileBitsEx failed\n");
917
918     stat = GdipCreateMetafileFromWmf(hwmf, TRUE,
919         (WmfPlaceableFileHeader*)wmfimage, (GpMetafile**)&img);
920     expect(Ok, stat);
921
922     stat = GdipGetImageBounds(img, &bounds, &unit);
923     expect(Ok, stat);
924     todo_wine expect(UnitPixel, unit);
925     expectf(0.0, bounds.X);
926     expectf(0.0, bounds.Y);
927     todo_wine expectf(320.0, bounds.Width);
928     todo_wine expectf(320.0, bounds.Height);
929
930     stat = GdipGetImageHorizontalResolution(img, &res);
931     expect(Ok, stat);
932     expectf(1440.0, res);
933
934     stat = GdipGetImageVerticalResolution(img, &res);
935     expect(Ok, stat);
936     expectf(1440.0, res);
937
938     memset(&header, 0, sizeof(header));
939     stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header);
940     expect(Ok, stat);
941     if (stat == Ok)
942     {
943         todo_wine expect(MetafileTypeWmfPlaceable, header.Type);
944         todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size);
945         todo_wine expect(0x300, header.Version);
946         expect(0, header.EmfPlusFlags);
947         todo_wine expectf(1440.0, header.DpiX);
948         todo_wine expectf(1440.0, header.DpiY);
949         expect(0, header.X);
950         expect(0, header.Y);
951         todo_wine expect(320, header.Width);
952         todo_wine expect(320, header.Height);
953         todo_wine expect(1, header.WmfHeader.mtType);
954         expect(0, header.EmfPlusHeaderSize);
955         expect(0, header.LogicalDpiX);
956         expect(0, header.LogicalDpiY);
957     }
958
959     GdipDisposeImage(img);
960 }
961
962 static void test_resolution(void)
963 {
964     GpStatus stat;
965     GpBitmap *bitmap;
966     REAL res=-1.0;
967     HDC screendc;
968     int screenxres, screenyres;
969
970     /* create Bitmap */
971     stat = GdipCreateBitmapFromScan0(1, 1, 32, PixelFormat24bppRGB, NULL, &bitmap);
972     expect(Ok, stat);
973
974     /* test invalid values */
975     stat = GdipGetImageHorizontalResolution(NULL, &res);
976     expect(InvalidParameter, stat);
977
978     stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, NULL);
979     expect(InvalidParameter, stat);
980
981     stat = GdipGetImageVerticalResolution(NULL, &res);
982     expect(InvalidParameter, stat);
983
984     stat = GdipGetImageVerticalResolution((GpImage*)bitmap, NULL);
985     expect(InvalidParameter, stat);
986
987     stat = GdipBitmapSetResolution(NULL, 96.0, 96.0);
988     expect(InvalidParameter, stat);
989
990     stat = GdipBitmapSetResolution(bitmap, 0.0, 0.0);
991     expect(InvalidParameter, stat);
992
993     /* defaults to screen resolution */
994     screendc = GetDC(0);
995
996     screenxres = GetDeviceCaps(screendc, LOGPIXELSX);
997     screenyres = GetDeviceCaps(screendc, LOGPIXELSY);
998
999     ReleaseDC(0, screendc);
1000
1001     stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, &res);
1002     expect(Ok, stat);
1003     expectf((REAL)screenxres, res);
1004
1005     stat = GdipGetImageVerticalResolution((GpImage*)bitmap, &res);
1006     expect(Ok, stat);
1007     expectf((REAL)screenyres, res);
1008
1009     /* test changing the resolution */
1010     stat = GdipBitmapSetResolution(bitmap, screenxres*2.0, screenyres*3.0);
1011     expect(Ok, stat);
1012
1013     stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, &res);
1014     expect(Ok, stat);
1015     expectf(screenxres*2.0, res);
1016
1017     stat = GdipGetImageVerticalResolution((GpImage*)bitmap, &res);
1018     expect(Ok, stat);
1019     expectf(screenyres*3.0, res);
1020
1021     stat = GdipDisposeImage((GpImage*)bitmap);
1022     expect(Ok, stat);
1023 }
1024
1025 static void test_createhbitmap(void)
1026 {
1027     GpStatus stat;
1028     GpBitmap *bitmap;
1029     HBITMAP hbitmap, oldhbitmap;
1030     BITMAP bm;
1031     int ret;
1032     HDC hdc;
1033     COLORREF pixel;
1034     BYTE bits[640];
1035
1036     memset(bits, 0x68, 640);
1037
1038     /* create Bitmap */
1039     stat = GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB, bits, &bitmap);
1040     expect(Ok, stat);
1041
1042     /* test NULL values */
1043     stat = GdipCreateHBITMAPFromBitmap(NULL, &hbitmap, 0);
1044     expect(InvalidParameter, stat);
1045
1046     stat = GdipCreateHBITMAPFromBitmap(bitmap, NULL, 0);
1047     expect(InvalidParameter, stat);
1048
1049     /* create HBITMAP */
1050     stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0);
1051     expect(Ok, stat);
1052
1053     if (stat == Ok)
1054     {
1055         ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
1056         expect(sizeof(BITMAP), ret);
1057
1058         expect(0, bm.bmType);
1059         expect(10, bm.bmWidth);
1060         expect(20, bm.bmHeight);
1061         expect(40, bm.bmWidthBytes);
1062         expect(1, bm.bmPlanes);
1063         expect(32, bm.bmBitsPixel);
1064         ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
1065
1066         hdc = CreateCompatibleDC(NULL);
1067
1068         oldhbitmap = SelectObject(hdc, hbitmap);
1069         pixel = GetPixel(hdc, 5, 5);
1070         SelectObject(hdc, oldhbitmap);
1071
1072         DeleteDC(hdc);
1073
1074         expect(0x686868, pixel);
1075
1076         DeleteObject(hbitmap);
1077     }
1078
1079     stat = GdipDisposeImage((GpImage*)bitmap);
1080     expect(Ok, stat);
1081 }
1082
1083 static void test_getsetpixel(void)
1084 {
1085     GpStatus stat;
1086     GpBitmap *bitmap;
1087     ARGB color;
1088     BYTE bits[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00,
1089                      0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00};
1090
1091     stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB, bits, &bitmap);
1092     expect(Ok, stat);
1093
1094     /* null parameters */
1095     stat = GdipBitmapGetPixel(NULL, 1, 1, &color);
1096     expect(InvalidParameter, stat);
1097
1098     stat = GdipBitmapGetPixel(bitmap, 1, 1, NULL);
1099     expect(InvalidParameter, stat);
1100
1101     stat = GdipBitmapSetPixel(NULL, 1, 1, 0);
1102     expect(InvalidParameter, stat);
1103
1104     /* out of bounds */
1105     stat = GdipBitmapGetPixel(bitmap, -1, 1, &color);
1106     expect(InvalidParameter, stat);
1107
1108     stat = GdipBitmapSetPixel(bitmap, -1, 1, 0);
1109     expect(InvalidParameter, stat);
1110
1111     stat = GdipBitmapGetPixel(bitmap, 1, -1, &color);
1112     ok(stat == InvalidParameter ||
1113        broken(stat == Ok), /* Older gdiplus */
1114        "Expected InvalidParameter, got %.8x\n", stat);
1115
1116     stat = GdipBitmapSetPixel(bitmap, 1, -1, 0);
1117     ok(stat == InvalidParameter ||
1118        broken(stat == Ok), /* Older gdiplus */
1119        "Expected InvalidParameter, got %.8x\n", stat);
1120
1121     stat = GdipBitmapGetPixel(bitmap, 2, 1, &color);
1122     expect(InvalidParameter, stat);
1123
1124     stat = GdipBitmapSetPixel(bitmap, 2, 1, 0);
1125     expect(InvalidParameter, stat);
1126
1127     stat = GdipBitmapGetPixel(bitmap, 1, 2, &color);
1128     expect(InvalidParameter, stat);
1129
1130     stat = GdipBitmapSetPixel(bitmap, 1, 2, 0);
1131     expect(InvalidParameter, stat);
1132
1133     /* valid use */
1134     stat = GdipBitmapGetPixel(bitmap, 1, 1, &color);
1135     expect(Ok, stat);
1136     expect(0xffffffff, color);
1137
1138     stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
1139     expect(Ok, stat);
1140     expect(0xff0000ff, color);
1141
1142     stat = GdipBitmapSetPixel(bitmap, 1, 1, 0xff676869);
1143     expect(Ok, stat);
1144
1145     stat = GdipBitmapSetPixel(bitmap, 0, 0, 0xff474849);
1146     expect(Ok, stat);
1147
1148     stat = GdipBitmapGetPixel(bitmap, 1, 1, &color);
1149     expect(Ok, stat);
1150     expect(0xff676869, color);
1151
1152     stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
1153     expect(Ok, stat);
1154     expect(0xff474849, color);
1155
1156     stat = GdipDisposeImage((GpImage*)bitmap);
1157     expect(Ok, stat);
1158 }
1159
1160 static void check_halftone_palette(ColorPalette *palette)
1161 {
1162     static const BYTE halftone_values[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
1163     UINT i;
1164
1165     for (i=0; i<palette->Count; i++)
1166     {
1167         ARGB expected=0xff000000;
1168         if (i<8)
1169         {
1170             if (i&1) expected |= 0x800000;
1171             if (i&2) expected |= 0x8000;
1172             if (i&4) expected |= 0x80;
1173         }
1174         else if (i == 8)
1175         {
1176             expected = 0xffc0c0c0;
1177         }
1178         else if (i < 16)
1179         {
1180             if (i&1) expected |= 0xff0000;
1181             if (i&2) expected |= 0xff00;
1182             if (i&4) expected |= 0xff;
1183         }
1184         else if (i < 40)
1185         {
1186             expected = 0x00000000;
1187         }
1188         else
1189         {
1190             expected |= halftone_values[(i-40)%6];
1191             expected |= halftone_values[((i-40)/6)%6] << 8;
1192             expected |= halftone_values[((i-40)/36)%6] << 16;
1193         }
1194         ok(expected == palette->Entries[i], "Expected %.8x, got %.8x, i=%u/%u\n",
1195             expected, palette->Entries[i], i, palette->Count);
1196     }
1197 }
1198
1199 static void test_palette(void)
1200 {
1201     GpStatus stat;
1202     GpBitmap *bitmap;
1203     INT size;
1204     BYTE buffer[1040];
1205     ColorPalette *palette=(ColorPalette*)buffer;
1206     ARGB color=0;
1207
1208     /* test initial palette from non-indexed bitmap */
1209     stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB, NULL, &bitmap);
1210     expect(Ok, stat);
1211
1212     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1213     expect(Ok, stat);
1214     expect(sizeof(UINT)*2+sizeof(ARGB), size);
1215
1216     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1217     expect(Ok, stat);
1218     expect(0, palette->Count);
1219
1220     /* test setting palette on not-indexed bitmap */
1221     palette->Count = 3;
1222
1223     stat = GdipSetImagePalette((GpImage*)bitmap, palette);
1224     expect(Ok, stat);
1225
1226     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1227     expect(Ok, stat);
1228     expect(sizeof(UINT)*2+sizeof(ARGB)*3, size);
1229
1230     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1231     expect(Ok, stat);
1232     expect(3, palette->Count);
1233
1234     GdipDisposeImage((GpImage*)bitmap);
1235
1236     /* test initial palette on 1-bit bitmap */
1237     stat = GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat1bppIndexed, NULL, &bitmap);
1238     expect(Ok, stat);
1239
1240     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1241     expect(Ok, stat);
1242     expect(sizeof(UINT)*2+sizeof(ARGB)*2, size);
1243
1244     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1245     expect(Ok, stat);
1246     expect(PaletteFlagsGrayScale, palette->Flags);
1247     expect(2, palette->Count);
1248
1249     expect(0xff000000, palette->Entries[0]);
1250     expect(0xffffffff, palette->Entries[1]);
1251
1252     /* test getting/setting pixels */
1253     stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
1254     expect(Ok, stat);
1255     expect(0xff000000, color);
1256
1257     stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffffffff);
1258     todo_wine ok((stat == Ok) ||
1259        broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
1260
1261     if (stat == Ok)
1262     {
1263         stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
1264         expect(Ok, stat);
1265         expect(0xffffffff, color);
1266     }
1267
1268     GdipDisposeImage((GpImage*)bitmap);
1269
1270     /* test initial palette on 4-bit bitmap */
1271     stat = GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat4bppIndexed, NULL, &bitmap);
1272     expect(Ok, stat);
1273
1274     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1275     expect(Ok, stat);
1276     expect(sizeof(UINT)*2+sizeof(ARGB)*16, size);
1277
1278     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1279     expect(Ok, stat);
1280     expect(0, palette->Flags);
1281     expect(16, palette->Count);
1282
1283     check_halftone_palette(palette);
1284
1285     /* test getting/setting pixels */
1286     stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
1287     expect(Ok, stat);
1288     expect(0xff000000, color);
1289
1290     stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffff00ff);
1291     todo_wine ok((stat == Ok) ||
1292        broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
1293
1294     if (stat == Ok)
1295     {
1296         stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
1297         expect(Ok, stat);
1298         expect(0xffff00ff, color);
1299     }
1300
1301     GdipDisposeImage((GpImage*)bitmap);
1302
1303     /* test initial palette on 8-bit bitmap */
1304     stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat8bppIndexed, NULL, &bitmap);
1305     expect(Ok, stat);
1306
1307     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1308     expect(Ok, stat);
1309     expect(sizeof(UINT)*2+sizeof(ARGB)*256, size);
1310
1311     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1312     expect(Ok, stat);
1313     expect(PaletteFlagsHalftone, palette->Flags);
1314     expect(256, palette->Count);
1315
1316     check_halftone_palette(palette);
1317
1318     /* test getting/setting pixels */
1319     stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
1320     expect(Ok, stat);
1321     expect(0xff000000, color);
1322
1323     stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffcccccc);
1324     todo_wine ok((stat == Ok) ||
1325        broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
1326
1327     if (stat == Ok)
1328     {
1329         stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
1330         expect(Ok, stat);
1331         expect(0xffcccccc, color);
1332     }
1333
1334     /* test setting/getting a different palette */
1335     palette->Entries[1] = 0xffcccccc;
1336
1337     stat = GdipSetImagePalette((GpImage*)bitmap, palette);
1338     expect(Ok, stat);
1339
1340     palette->Entries[1] = 0;
1341
1342     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1343     expect(Ok, stat);
1344     expect(sizeof(UINT)*2+sizeof(ARGB)*256, size);
1345
1346     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1347     expect(Ok, stat);
1348     expect(PaletteFlagsHalftone, palette->Flags);
1349     expect(256, palette->Count);
1350     expect(0xffcccccc, palette->Entries[1]);
1351
1352     /* test count < 256 */
1353     palette->Flags = 12345;
1354     palette->Count = 3;
1355
1356     stat = GdipSetImagePalette((GpImage*)bitmap, palette);
1357     expect(Ok, stat);
1358
1359     palette->Entries[1] = 0;
1360     palette->Entries[3] = 0xdeadbeef;
1361
1362     stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
1363     expect(Ok, stat);
1364     expect(sizeof(UINT)*2+sizeof(ARGB)*3, size);
1365
1366     stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
1367     expect(Ok, stat);
1368     expect(12345, palette->Flags);
1369     expect(3, palette->Count);
1370     expect(0xffcccccc, palette->Entries[1]);
1371     expect(0xdeadbeef, palette->Entries[3]);
1372
1373     /* test count > 256 */
1374     palette->Count = 257;
1375
1376     stat = GdipSetImagePalette((GpImage*)bitmap, palette);
1377     ok(stat == InvalidParameter ||
1378        broken(stat == Ok), /* Old gdiplus behavior */
1379        "Expected %.8x, got %.8x\n", InvalidParameter, stat);
1380
1381     GdipDisposeImage((GpImage*)bitmap);
1382 }
1383
1384 static void test_colormatrix(void)
1385 {
1386     GpStatus stat;
1387     ColorMatrix colormatrix, graymatrix;
1388     GpImageAttributes *imageattr;
1389     const ColorMatrix identity = {{
1390         {1.0,0.0,0.0,0.0,0.0},
1391         {0.0,1.0,0.0,0.0,0.0},
1392         {0.0,0.0,1.0,0.0,0.0},
1393         {0.0,0.0,0.0,1.0,0.0},
1394         {0.0,0.0,0.0,0.0,1.0}}};
1395     const ColorMatrix double_red = {{
1396         {2.0,0.0,0.0,0.0,0.0},
1397         {0.0,1.0,0.0,0.0,0.0},
1398         {0.0,0.0,1.0,0.0,0.0},
1399         {0.0,0.0,0.0,1.0,0.0},
1400         {0.0,0.0,0.0,0.0,1.0}}};
1401     GpBitmap *bitmap1, *bitmap2;
1402     GpGraphics *graphics;
1403     ARGB color;
1404
1405     colormatrix = identity;
1406     graymatrix = identity;
1407
1408     stat = GdipSetImageAttributesColorMatrix(NULL, ColorAdjustTypeDefault,
1409         TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
1410     expect(InvalidParameter, stat);
1411
1412     stat = GdipCreateImageAttributes(&imageattr);
1413     expect(Ok, stat);
1414
1415     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
1416         TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
1417     expect(Ok, stat);
1418
1419     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
1420         TRUE, NULL, NULL, ColorMatrixFlagsDefault);
1421     expect(InvalidParameter, stat);
1422
1423     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
1424         TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
1425     expect(Ok, stat);
1426
1427     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
1428         TRUE, &colormatrix, NULL, ColorMatrixFlagsSkipGrays);
1429     expect(Ok, stat);
1430
1431     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
1432         TRUE, &colormatrix, NULL, ColorMatrixFlagsAltGray);
1433     expect(InvalidParameter, stat);
1434
1435     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
1436         TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsAltGray);
1437     expect(Ok, stat);
1438
1439     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
1440         TRUE, &colormatrix, &graymatrix, 3);
1441     expect(InvalidParameter, stat);
1442
1443     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeCount,
1444         TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
1445     expect(InvalidParameter, stat);
1446
1447     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeAny,
1448         TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
1449     expect(InvalidParameter, stat);
1450
1451     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
1452         FALSE, NULL, NULL, ColorMatrixFlagsDefault);
1453     expect(Ok, stat);
1454
1455     /* Drawing a bitmap transforms the colors */
1456     colormatrix = double_red;
1457     stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault,
1458         TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
1459     expect(Ok, stat);
1460
1461     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap1);
1462     expect(Ok, stat);
1463
1464     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap2);
1465     expect(Ok, stat);
1466
1467     stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff40ffff);
1468     expect(Ok, stat);
1469
1470     stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
1471     expect(Ok, stat);
1472
1473     stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
1474         UnitPixel, imageattr, NULL, NULL);
1475     expect(Ok, stat);
1476
1477     stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
1478     expect(Ok, stat);
1479     todo_wine expect(0xff80ffff, color);
1480
1481     GdipDeleteGraphics(graphics);
1482     GdipDisposeImage((GpImage*)bitmap1);
1483     GdipDisposeImage((GpImage*)bitmap2);
1484     GdipDisposeImageAttributes(imageattr);
1485 }
1486
1487 static void test_gamma(void)
1488 {
1489     GpStatus stat;
1490     GpImageAttributes *imageattr;
1491     GpBitmap *bitmap1, *bitmap2;
1492     GpGraphics *graphics;
1493     ARGB color;
1494
1495     stat = GdipSetImageAttributesGamma(NULL, ColorAdjustTypeDefault, TRUE, 1.0);
1496     expect(InvalidParameter, stat);
1497
1498     stat = GdipCreateImageAttributes(&imageattr);
1499     expect(Ok, stat);
1500
1501     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 1.0);
1502     expect(Ok, stat);
1503
1504     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeAny, TRUE, 1.0);
1505     expect(InvalidParameter, stat);
1506
1507     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, -1.0);
1508     expect(InvalidParameter, stat);
1509
1510     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 0.0);
1511     expect(InvalidParameter, stat);
1512
1513     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 0.5);
1514     expect(Ok, stat);
1515
1516     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, FALSE, 0.0);
1517     expect(Ok, stat);
1518
1519     /* Drawing a bitmap transforms the colors */
1520     stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 3.0);
1521     expect(Ok, stat);
1522
1523     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap1);
1524     expect(Ok, stat);
1525
1526     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap2);
1527     expect(Ok, stat);
1528
1529     stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff80ffff);
1530     expect(Ok, stat);
1531
1532     stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
1533     expect(Ok, stat);
1534
1535     stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
1536         UnitPixel, imageattr, NULL, NULL);
1537     expect(Ok, stat);
1538
1539     stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
1540     expect(Ok, stat);
1541     todo_wine ok(color_match(0xff20ffff, color, 1), "Expected ff20ffff, got %.8x\n", color);
1542
1543     GdipDeleteGraphics(graphics);
1544     GdipDisposeImage((GpImage*)bitmap1);
1545     GdipDisposeImage((GpImage*)bitmap2);
1546     GdipDisposeImageAttributes(imageattr);
1547 }
1548
1549 /* 1x1 pixel gif, 2 frames; first frame is white, second is black */
1550 static const unsigned char gifanimation[72] = {
1551 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
1552 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0xf9,0x04,0x00,0x0a,0x00,0xff,
1553 0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x4c,0x01,0x00,
1554 0x21,0xf9,0x04,0x01,0x0a,0x00,0x01,0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,
1555 0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
1556 };
1557
1558 static void test_multiframegif(void)
1559 {
1560     LPSTREAM stream;
1561     HGLOBAL hglob;
1562     LPBYTE data;
1563     HRESULT hres;
1564     GpStatus stat;
1565     GpBitmap *bmp;
1566     ARGB color;
1567     UINT count;
1568     GUID dimension;
1569
1570     /* Test frame functions with an animated GIF */
1571     hglob = GlobalAlloc (0, sizeof(gifanimation));
1572     data = GlobalLock (hglob);
1573     memcpy(data, gifanimation, sizeof(gifanimation));
1574     GlobalUnlock(hglob);
1575
1576     hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
1577     ok(hres == S_OK, "Failed to create a stream\n");
1578     if(hres != S_OK) return;
1579
1580     stat = GdipCreateBitmapFromStream(stream, &bmp);
1581     ok(stat == Ok, "Failed to create a Bitmap\n");
1582     if(stat != Ok){
1583         IStream_Release(stream);
1584         return;
1585     }
1586
1587     /* Bitmap starts at frame 0 */
1588     color = 0xdeadbeef;
1589     stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
1590     expect(Ok, stat);
1591     expect(0xffffffff, color);
1592
1593     /* Check that we get correct metadata */
1594     stat = GdipImageGetFrameDimensionsCount((GpImage*)bmp,&count);
1595     expect(Ok, stat);
1596     expect(1, count);
1597
1598     stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1);
1599     expect(Ok, stat);
1600     expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE);
1601
1602     count = 12345;
1603     stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
1604     expect(Ok, stat);
1605     todo_wine expect(2, count);
1606
1607     /* SelectActiveFrame overwrites our current data */
1608     stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 1);
1609     expect(Ok, stat);
1610
1611     color = 0xdeadbeef;
1612     GdipBitmapGetPixel(bmp, 0, 0, &color);
1613     expect(Ok, stat);
1614     todo_wine expect(0xff000000, color);
1615
1616     stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
1617     expect(Ok, stat);
1618
1619     color = 0xdeadbeef;
1620     GdipBitmapGetPixel(bmp, 0, 0, &color);
1621     expect(Ok, stat);
1622     expect(0xffffffff, color);
1623
1624     /* Write over the image data */
1625     stat = GdipBitmapSetPixel(bmp, 0, 0, 0xff000000);
1626     expect(Ok, stat);
1627
1628     /* Switching to the same frame does not overwrite our changes */
1629     stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
1630     expect(Ok, stat);
1631
1632     stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
1633     expect(Ok, stat);
1634     expect(0xff000000, color);
1635
1636     /* But switching to another frame and back does */
1637     stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 1);
1638     expect(Ok, stat);
1639
1640     stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
1641     expect(Ok, stat);
1642
1643     stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
1644     expect(Ok, stat);
1645     todo_wine expect(0xffffffff, color);
1646
1647     GdipDisposeImage((GpImage*)bmp);
1648     IStream_Release(stream);
1649
1650     /* Test with a non-animated gif */
1651     hglob = GlobalAlloc (0, sizeof(gifimage));
1652     data = GlobalLock (hglob);
1653     memcpy(data, gifimage, sizeof(gifimage));
1654     GlobalUnlock(hglob);
1655
1656     hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
1657     ok(hres == S_OK, "Failed to create a stream\n");
1658     if(hres != S_OK) return;
1659
1660     stat = GdipCreateBitmapFromStream(stream, &bmp);
1661     ok(stat == Ok, "Failed to create a Bitmap\n");
1662     if(stat != Ok){
1663         IStream_Release(stream);
1664         return;
1665     }
1666
1667     /* Check metadata */
1668     stat = GdipImageGetFrameDimensionsCount((GpImage*)bmp,&count);
1669     expect(Ok, stat);
1670     expect(1, count);
1671
1672     stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1);
1673     expect(Ok, stat);
1674     expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE);
1675
1676     count = 12345;
1677     stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
1678     expect(Ok, stat);
1679     expect(1, count);
1680
1681     GdipDisposeImage((GpImage*)bmp);
1682     IStream_Release(stream);
1683 }
1684
1685 static void test_rotateflip(void)
1686 {
1687     GpImage *bitmap;
1688     GpStatus stat;
1689     BYTE bits[24];
1690     static const BYTE orig_bits[24] = {
1691         0,0,0xff,    0,0xff,0,    0xff,0,0,    23,23,23,
1692         0xff,0xff,0, 0xff,0,0xff, 0,0xff,0xff, 23,23,23};
1693     UINT width, height;
1694     ARGB color;
1695
1696     memcpy(bits, orig_bits, sizeof(bits));
1697     stat = GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB, bits, (GpBitmap**)&bitmap);
1698     expect(Ok, stat);
1699
1700     stat = GdipImageRotateFlip(bitmap, Rotate90FlipNone);
1701     todo_wine expect(Ok, stat);
1702
1703     stat = GdipGetImageWidth(bitmap, &width);
1704     expect(Ok, stat);
1705     stat = GdipGetImageHeight(bitmap, &height);
1706     expect(Ok, stat);
1707     todo_wine expect(2, width);
1708     todo_wine expect(3, height);
1709
1710     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
1711     expect(Ok, stat);
1712     todo_wine expect(0xff00ffff, color);
1713
1714     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 1, 0, &color);
1715     expect(Ok, stat);
1716     todo_wine expect(0xffff0000, color);
1717
1718     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 2, &color);
1719     todo_wine expect(Ok, stat);
1720     todo_wine expect(0xffffff00, color);
1721
1722     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 1, 2, &color);
1723     todo_wine expect(Ok, stat);
1724     todo_wine expect(0xff0000ff, color);
1725
1726     expect(0, bits[0]);
1727     expect(0, bits[1]);
1728     expect(0xff, bits[2]);
1729
1730     GdipDisposeImage(bitmap);
1731
1732     memcpy(bits, orig_bits, sizeof(bits));
1733     stat = GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB, bits, (GpBitmap**)&bitmap);
1734     expect(Ok, stat);
1735
1736     stat = GdipImageRotateFlip(bitmap, RotateNoneFlipX);
1737     todo_wine expect(Ok, stat);
1738
1739     stat = GdipGetImageWidth(bitmap, &width);
1740     expect(Ok, stat);
1741     stat = GdipGetImageHeight(bitmap, &height);
1742     expect(Ok, stat);
1743     expect(3, width);
1744     expect(2, height);
1745
1746     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
1747     expect(Ok, stat);
1748     todo_wine expect(0xff0000ff, color);
1749
1750     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 0, &color);
1751     expect(Ok, stat);
1752     todo_wine expect(0xffff0000, color);
1753
1754     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 1, &color);
1755     expect(Ok, stat);
1756     todo_wine expect(0xffffff00, color);
1757
1758     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 1, &color);
1759     expect(Ok, stat);
1760     todo_wine expect(0xff00ffff, color);
1761
1762     expect(0, bits[0]);
1763     expect(0, bits[1]);
1764     expect(0xff, bits[2]);
1765
1766     GdipDisposeImage(bitmap);
1767
1768     memcpy(bits, orig_bits, sizeof(bits));
1769     stat = GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB, bits, (GpBitmap**)&bitmap);
1770     expect(Ok, stat);
1771
1772     stat = GdipImageRotateFlip(bitmap, RotateNoneFlipY);
1773     todo_wine expect(Ok, stat);
1774
1775     stat = GdipGetImageWidth(bitmap, &width);
1776     expect(Ok, stat);
1777     stat = GdipGetImageHeight(bitmap, &height);
1778     expect(Ok, stat);
1779     expect(3, width);
1780     expect(2, height);
1781
1782     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
1783     expect(Ok, stat);
1784     todo_wine expect(0xff00ffff, color);
1785
1786     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 0, &color);
1787     expect(Ok, stat);
1788     todo_wine expect(0xffffff00, color);
1789
1790     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 1, &color);
1791     expect(Ok, stat);
1792     todo_wine expect(0xffff0000, color);
1793
1794     stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 1, &color);
1795     expect(Ok, stat);
1796     todo_wine expect(0xff0000ff, color);
1797
1798     expect(0, bits[0]);
1799     expect(0, bits[1]);
1800     expect(0xff, bits[2]);
1801
1802     GdipDisposeImage(bitmap);
1803 }
1804
1805 static void test_remaptable(void)
1806 {
1807     GpStatus stat;
1808     GpImageAttributes *imageattr;
1809     GpBitmap *bitmap1, *bitmap2;
1810     GpGraphics *graphics;
1811     ARGB color;
1812     ColorMap *map;
1813
1814     map = GdipAlloc(sizeof(ColorMap));
1815
1816     map->oldColor.Argb = 0xff00ff00;
1817     map->newColor.Argb = 0xffff00ff;
1818
1819     stat = GdipSetImageAttributesRemapTable(NULL, ColorAdjustTypeDefault, TRUE, 1, map);
1820     expect(InvalidParameter, stat);
1821
1822     stat = GdipCreateImageAttributes(&imageattr);
1823     expect(Ok, stat);
1824
1825     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, TRUE, 1, NULL);
1826     expect(InvalidParameter, stat);
1827
1828     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeCount, TRUE, 1, map);
1829     expect(InvalidParameter, stat);
1830
1831     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeAny, TRUE, 1, map);
1832     expect(InvalidParameter, stat);
1833
1834     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, TRUE, 0, map);
1835     expect(InvalidParameter, stat);
1836
1837     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, FALSE, 0, NULL);
1838     expect(Ok, stat);
1839
1840     stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, TRUE, 1, map);
1841     expect(Ok, stat);
1842
1843     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap1);
1844     expect(Ok, stat);
1845
1846     stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap2);
1847     expect(Ok, stat);
1848
1849     stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff00ff00);
1850     expect(Ok, stat);
1851
1852     stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
1853     expect(Ok, stat);
1854
1855     stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
1856         UnitPixel, imageattr, NULL, NULL);
1857     expect(Ok, stat);
1858
1859     stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
1860     expect(Ok, stat);
1861     todo_wine ok(color_match(0xffff00ff, color, 1), "Expected ffff00ff, got %.8x\n", color);
1862
1863     GdipDeleteGraphics(graphics);
1864     GdipDisposeImage((GpImage*)bitmap1);
1865     GdipDisposeImage((GpImage*)bitmap2);
1866     GdipDisposeImageAttributes(imageattr);
1867     GdipFree(map);
1868 }
1869
1870 START_TEST(image)
1871 {
1872     struct GdiplusStartupInput gdiplusStartupInput;
1873     ULONG_PTR gdiplusToken;
1874
1875     gdiplusStartupInput.GdiplusVersion              = 1;
1876     gdiplusStartupInput.DebugEventCallback          = NULL;
1877     gdiplusStartupInput.SuppressBackgroundThread    = 0;
1878     gdiplusStartupInput.SuppressExternalCodecs      = 0;
1879
1880     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
1881
1882     test_Scan0();
1883     test_GetImageDimension();
1884     test_GdipImageGetFrameDimensionsCount();
1885     test_LoadingImages();
1886     test_SavingImages();
1887     test_encoders();
1888     test_LockBits();
1889     test_GdipCreateBitmapFromHBITMAP();
1890     test_GdipGetImageFlags();
1891     test_GdipCloneImage();
1892     test_testcontrol();
1893     test_fromhicon();
1894     test_getrawformat();
1895     test_loadwmf();
1896     test_createfromwmf();
1897     test_resolution();
1898     test_createhbitmap();
1899     test_getsetpixel();
1900     test_palette();
1901     test_colormatrix();
1902     test_gamma();
1903     test_multiframegif();
1904     test_rotateflip();
1905     test_remaptable();
1906
1907     GdiplusShutdown(gdiplusToken);
1908 }