comctl32: Add implementation of LVS_EX_ONECLICKACTIVATE.
[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 #include "windows.h"
22 #include "gdiplus.h"
23 #include "wine/test.h"
24 #include <math.h>
25 #include "wingdi.h"
26
27 #define expect(expected, got) ok(((UINT)got) == ((UINT)expected), "Expected %.8x, got %.8x\n", (UINT)expected, (UINT)got)
28
29 static void test_Scan0(void)
30 {
31     GpBitmap *bm;
32     GpStatus stat;
33     BYTE buff[360];
34
35     bm = NULL;
36     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, NULL, &bm);
37     expect(Ok, stat);
38     ok(NULL != bm, "Expected bitmap to be initialized\n");
39     if (stat == Ok)
40         GdipDisposeImage((GpImage*)bm);
41
42     bm = (GpBitmap*)0xdeadbeef;
43     stat = GdipCreateBitmapFromScan0(10, -10, 10, PixelFormat24bppRGB, NULL, &bm);
44     expect(InvalidParameter, stat);
45
46     expect(NULL, bm);
47
48     bm = (GpBitmap*)0xdeadbeef;
49     stat = GdipCreateBitmapFromScan0(-10, 10, 10, PixelFormat24bppRGB, NULL, &bm);
50     expect(InvalidParameter, stat);
51
52     expect(NULL, bm);
53
54     bm = (GpBitmap*)0xdeadbeef;
55     stat = GdipCreateBitmapFromScan0(10, 0, 10, PixelFormat24bppRGB, NULL, &bm);
56     expect(InvalidParameter, stat);
57
58     expect(NULL, bm);
59
60     bm = NULL;
61     stat = GdipCreateBitmapFromScan0(10, 10, 12, PixelFormat24bppRGB, buff, &bm);
62     expect(Ok, stat);
63     ok(NULL != bm, "Expected bitmap to be initialized\n");
64     if (stat == Ok)
65         GdipDisposeImage((GpImage*)bm);
66
67     bm = (GpBitmap*) 0xdeadbeef;
68     stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, buff, &bm);
69     expect(InvalidParameter, stat);
70     expect(NULL, bm);
71
72     bm = (GpBitmap*)0xdeadbeef;
73     stat = GdipCreateBitmapFromScan0(10, 10, 0, PixelFormat24bppRGB, buff, &bm);
74     expect(InvalidParameter, stat);
75     expect(0xdeadbeef, bm);
76
77     bm = NULL;
78     stat = GdipCreateBitmapFromScan0(10, 10, -8, PixelFormat24bppRGB, buff, &bm);
79     todo_wine{
80         expect(Ok, stat);
81         ok(NULL != bm, "Expected bitmap to be initialized\n");
82     }
83     if (stat == Ok)
84         GdipDisposeImage((GpImage*)bm);
85
86     bm = (GpBitmap*)0xdeadbeef;
87     stat = GdipCreateBitmapFromScan0(10, 10, -10, PixelFormat24bppRGB, buff, &bm);
88     expect(InvalidParameter, stat);
89     expect(NULL, bm);
90 }
91
92 static void test_GetImageDimension(void)
93 {
94     GpBitmap *bm;
95     GpStatus stat;
96     const REAL WIDTH = 10.0, HEIGHT = 20.0;
97     REAL w,h;
98
99     bm = (GpBitmap*)0xdeadbeef;
100     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB,NULL, &bm);
101     expect(Ok,stat);
102     ok((GpBitmap*)0xdeadbeef != bm, "Expected bitmap to not be 0xdeadbeef\n");
103     ok(NULL != bm, "Expected bitmap to not be NULL\n");
104
105     stat = GdipGetImageDimension(NULL,&w,&h);
106     expect(InvalidParameter, stat);
107
108     stat = GdipGetImageDimension((GpImage*)bm,NULL,&h);
109     expect(InvalidParameter, stat);
110
111     stat = GdipGetImageDimension((GpImage*)bm,&w,NULL);
112     expect(InvalidParameter, stat);
113
114     w = -1;
115     h = -1;
116     stat = GdipGetImageDimension((GpImage*)bm,&w,&h);
117     expect(Ok, stat);
118     ok(fabs(WIDTH - w) < 0.0001, "Width wrong\n");
119     ok(fabs(HEIGHT - h) < 0.0001, "Height wrong\n");
120     GdipDisposeImage((GpImage*)bm);
121 }
122
123 static void test_GdipImageGetFrameDimensionsCount(void)
124 {
125     GpBitmap *bm;
126     GpStatus stat;
127     const REAL WIDTH = 10.0, HEIGHT = 20.0;
128     UINT w;
129
130     bm = (GpBitmap*)0xdeadbeef;
131     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB,NULL, &bm);
132     expect(Ok,stat);
133     ok((GpBitmap*)0xdeadbeef != bm, "Expected bitmap to not be 0xdeadbeef\n");
134     ok(NULL != bm, "Expected bitmap to not be NULL\n");
135
136     stat = GdipImageGetFrameDimensionsCount(NULL,&w);
137     expect(InvalidParameter, stat);
138
139     stat = GdipImageGetFrameDimensionsCount((GpImage*)bm,NULL);
140     expect(InvalidParameter, stat);
141
142     w = -1;
143     stat = GdipImageGetFrameDimensionsCount((GpImage*)bm,&w);
144     expect(Ok, stat);
145     expect(1, w);
146     GdipDisposeImage((GpImage*)bm);
147 }
148
149 static void test_LoadingImages(void)
150 {
151     GpStatus stat;
152
153     stat = GdipCreateBitmapFromFile(0, 0);
154     expect(InvalidParameter, stat);
155
156     stat = GdipCreateBitmapFromFile(0, (GpBitmap**)0xdeadbeef);
157     expect(InvalidParameter, stat);
158
159     stat = GdipLoadImageFromFile(0, 0);
160     expect(InvalidParameter, stat);
161
162     stat = GdipLoadImageFromFile(0, (GpImage**)0xdeadbeef);
163     expect(InvalidParameter, stat);
164
165     stat = GdipLoadImageFromFileICM(0, 0);
166     expect(InvalidParameter, stat);
167
168     stat = GdipLoadImageFromFileICM(0, (GpImage**)0xdeadbeef);
169     expect(InvalidParameter, stat);
170 }
171
172 static void test_SavingImages(void)
173 {
174     GpStatus stat;
175     GpBitmap *bm;
176     UINT n;
177     UINT s;
178     const REAL WIDTH = 10.0, HEIGHT = 20.0;
179     REAL w, h;
180     ImageCodecInfo *codecs;
181     static const WCHAR filename[] = { 'a','.','b','m','p',0 };
182
183     codecs = NULL;
184
185     stat = GdipSaveImageToFile(0, 0, 0, 0);
186     expect(InvalidParameter, stat);
187
188     bm = NULL;
189     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
190     expect(Ok, stat);
191     if (!bm)
192         return;
193
194     /* invalid params */
195     stat = GdipSaveImageToFile((GpImage*)bm, 0, 0, 0);
196     expect(InvalidParameter, stat);
197
198     stat = GdipSaveImageToFile((GpImage*)bm, filename, 0, 0);
199     expect(InvalidParameter, stat);
200
201     /* encoder tests should succeed -- already tested */
202     stat = GdipGetImageEncodersSize(&n, &s);
203     if (stat != Ok || n == 0) goto cleanup;
204
205     codecs = GdipAlloc(s);
206     if (!codecs) goto cleanup;
207
208     stat = GdipGetImageEncoders(n, s, codecs);
209     if (stat != Ok) goto cleanup;
210
211     stat = GdipSaveImageToFile((GpImage*)bm, filename, &codecs[0].Clsid, 0);
212     expect(stat, Ok);
213
214     GdipDisposeImage((GpImage*)bm);
215     bm = 0;
216
217     /* re-load and check image stats */
218     stat = GdipLoadImageFromFile(filename, (GpImage**)&bm);
219     expect(stat, Ok);
220     if (stat != Ok) goto cleanup;
221
222     stat = GdipGetImageDimension((GpImage*)bm, &w, &h);
223     if (stat != Ok) goto cleanup;
224
225     ok((fabs(w - WIDTH) < 0.01) && (fabs(h - HEIGHT) < 0.01),
226        "Saved image dimensions are different!\n");
227
228  cleanup:
229     GdipFree(codecs);
230     if (bm)
231         GdipDisposeImage((GpImage*)bm);
232     ok(DeleteFileW(filename), "Delete failed.\n");
233 }
234
235 static void test_encoders(void)
236 {
237     GpStatus stat;
238     UINT n;
239     UINT s;
240     ImageCodecInfo *codecs;
241     int i;
242     int bmp_found;
243
244     static const WCHAR bmp_format[] = {'B', 'M', 'P', 0};
245
246     stat = GdipGetImageEncodersSize(&n, &s);
247     expect(stat, Ok);
248
249     codecs = GdipAlloc(s);
250     if (!codecs)
251         return;
252
253     stat = GdipGetImageEncoders(n, s, NULL);
254     expect(GenericError, stat);
255
256     stat = GdipGetImageEncoders(0, s, codecs);
257     expect(GenericError, stat);
258
259     stat = GdipGetImageEncoders(n, s-1, codecs);
260     expect(GenericError, stat);
261
262     stat = GdipGetImageEncoders(n, s+1, codecs);
263     expect(GenericError, stat);
264
265     stat = GdipGetImageEncoders(n, s, codecs);
266     expect(stat, Ok);
267
268     bmp_found = FALSE;
269     for (i = 0; i < n; i++)
270         {
271             if (CompareStringW(LOCALE_SYSTEM_DEFAULT, 0,
272                                codecs[i].FormatDescription, -1,
273                                bmp_format, -1) == CSTR_EQUAL) {
274                 bmp_found = TRUE;
275                 break;
276             }
277         }
278     if (!bmp_found)
279         ok(FALSE, "No BMP codec found.\n");
280
281     GdipFree(codecs);
282 }
283
284 static void test_LockBits(void)
285 {
286     GpStatus stat;
287     GpBitmap *bm;
288     GpRect rect;
289     BitmapData bd;
290     const INT WIDTH = 10, HEIGHT = 20;
291
292     bm = NULL;
293     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
294     expect(Ok, stat);
295
296     rect.X = 2;
297     rect.Y = 3;
298     rect.Width = 4;
299     rect.Height = 5;
300
301     /* read-only */
302     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
303     expect(Ok, stat);
304
305     if (stat == Ok) {
306         stat = GdipBitmapUnlockBits(bm, &bd);
307         expect(Ok, stat);
308     }
309
310     /* read-only, with NULL rect -> whole bitmap lock */
311     stat = GdipBitmapLockBits(bm, NULL, ImageLockModeRead, PixelFormat24bppRGB, &bd);
312     expect(Ok, stat);
313     expect(bd.Width,  WIDTH);
314     expect(bd.Height, HEIGHT);
315
316     if (stat == Ok) {
317         stat = GdipBitmapUnlockBits(bm, &bd);
318         expect(Ok, stat);
319     }
320
321     /* read-only, consecutive */
322     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
323     expect(Ok, stat);
324
325     if (stat == Ok) {
326         stat = GdipBitmapUnlockBits(bm, &bd);
327         expect(Ok, stat);
328     }
329
330     stat = GdipDisposeImage((GpImage*)bm);
331     expect(Ok, stat);
332     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
333     expect(Ok, stat);
334
335     /* read x2 */
336     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
337     expect(Ok, stat);
338     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
339     expect(WrongState, stat);
340
341     stat = GdipBitmapUnlockBits(bm, &bd);
342     expect(Ok, stat);
343
344     stat = GdipDisposeImage((GpImage*)bm);
345     expect(Ok, stat);
346     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
347     expect(Ok, stat);
348
349     /* write, no modification */
350     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
351     expect(Ok, stat);
352
353     if (stat == Ok) {
354         stat = GdipBitmapUnlockBits(bm, &bd);
355         expect(Ok, stat);
356     }
357
358     /* write, consecutive */
359     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
360     expect(Ok, stat);
361
362     if (stat == Ok) {
363         stat = GdipBitmapUnlockBits(bm, &bd);
364         expect(Ok, stat);
365     }
366
367     stat = GdipDisposeImage((GpImage*)bm);
368     expect(Ok, stat);
369     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
370     expect(Ok, stat);
371
372     /* write, modify */
373     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd);
374     expect(Ok, stat);
375
376     if (stat == Ok) {
377         if (bd.Scan0)
378             ((char*)bd.Scan0)[2] = 0xff;
379
380         stat = GdipBitmapUnlockBits(bm, &bd);
381         expect(Ok, stat);
382     }
383
384     stat = GdipDisposeImage((GpImage*)bm);
385     expect(Ok, stat);
386
387     /* dispose locked */
388     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
389     expect(Ok, stat);
390     stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd);
391     expect(Ok, stat);
392     stat = GdipDisposeImage((GpImage*)bm);
393     expect(Ok, stat);
394 }
395
396 static void test_GdipCreateBitmapFromHBITMAP(void)
397 {
398     GpBitmap* gpbm = NULL;
399     HBITMAP hbm = NULL;
400     HPALETTE hpal = NULL;
401     GpStatus stat;
402     BYTE buff[1000];
403     LOGPALETTE* LogPal = NULL;
404     REAL width, height;
405     const REAL WIDTH1 = 5;
406     const REAL HEIGHT1 = 15;
407     const REAL WIDTH2 = 10;
408     const REAL HEIGHT2 = 20;
409     HDC hdc;
410     BITMAPINFO bmi;
411
412     stat = GdipCreateBitmapFromHBITMAP(NULL, NULL, NULL);
413     expect(InvalidParameter, stat);
414
415     hbm = CreateBitmap(WIDTH1, HEIGHT1, 1, 1, NULL);
416     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, NULL);
417     expect(InvalidParameter, stat);
418
419     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
420     expect(Ok, stat);
421     expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
422     ok(fabs(WIDTH1 - width) < .0001, "width wrong\n");
423     ok(fabs(HEIGHT1 - height) < .0001, "height wrong\n");
424     if (stat == Ok)
425         GdipDisposeImage((GpImage*)gpbm);
426     GlobalFree(hbm);
427
428     hbm = CreateBitmap(WIDTH2, HEIGHT2, 1, 1, &buff);
429     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
430     expect(Ok, stat);
431     expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
432     ok(fabs(WIDTH2 - width) < .0001, "width wrong\n");
433     ok(fabs(HEIGHT2 - height) < .0001, "height wrong\n");
434     if (stat == Ok)
435         GdipDisposeImage((GpImage*)gpbm);
436     GlobalFree(hbm);
437
438     hdc = CreateCompatibleDC(0);
439     ok(hdc != NULL, "CreateCompatibleDC failed\n");
440     bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
441     bmi.bmiHeader.biHeight = HEIGHT1;
442     bmi.bmiHeader.biWidth = WIDTH1;
443     bmi.bmiHeader.biBitCount = 24;
444     bmi.bmiHeader.biPlanes = 1;
445     bmi.bmiHeader.biCompression = BI_RGB;
446
447     hbm = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, NULL, NULL, 0);
448     ok(hbm != NULL, "CreateDIBSection failed\n");
449
450     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
451     expect(Ok, stat);
452     expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
453     ok(fabs(WIDTH1 - width) < .0001, "width wrong\n");
454     ok(fabs(HEIGHT1 - height) < .0001, "height wrong\n");
455     if (stat == Ok)
456         GdipDisposeImage((GpImage*)gpbm);
457
458     LogPal = GdipAlloc(sizeof(LOGPALETTE));
459     ok(LogPal != NULL, "unable to allocate LOGPALETTE\n");
460     LogPal->palVersion = 0x300;
461     hpal = CreatePalette((const LOGPALETTE*) LogPal);
462     ok(hpal != NULL, "CreatePalette failed\n");
463     GdipFree(LogPal);
464
465     stat = GdipCreateBitmapFromHBITMAP(hbm, hpal, &gpbm);
466     todo_wine
467     {
468         expect(Ok, stat);
469     }
470     if (stat == Ok)
471         GdipDisposeImage((GpImage*)gpbm);
472
473     GlobalFree(hpal);
474     GlobalFree(hbm);
475 }
476
477 static void test_GdipGetImageFlags(void)
478 {
479     GpImage *img;
480     GpStatus stat;
481     UINT flags;
482
483     img = (GpImage*)0xdeadbeef;
484
485     stat = GdipGetImageFlags(NULL, NULL);
486     expect(InvalidParameter, stat);
487
488     stat = GdipGetImageFlags(NULL, &flags);
489     expect(InvalidParameter, stat);
490
491     stat = GdipGetImageFlags(img, NULL);
492     expect(InvalidParameter, stat);
493 }
494
495 static void test_GdipCloneImage(void)
496 {
497     GpStatus stat;
498     GpRectF rectF;
499     GpUnit unit;
500     GpBitmap *bm;
501     GpImage *image_src, *image_dest = NULL;
502     const INT WIDTH = 10, HEIGHT = 20;
503
504     /* Create an image, clone it, delete the original, make sure the copy works */
505     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
506     expect(Ok, stat);
507
508     image_src = ((GpImage*)bm);
509     stat = GdipCloneImage(image_src, &image_dest);
510     expect(Ok, stat);
511
512     stat = GdipDisposeImage((GpImage*)bm);
513     expect(Ok, stat);
514     stat = GdipGetImageBounds(image_dest, &rectF, &unit);
515     expect(Ok, stat);
516
517     /* Treat FP values carefully */
518     ok(fabsf(rectF.Width-WIDTH)<1e-5, "Expected: %d, got %.05f\n", WIDTH, rectF.Width);
519     ok(fabsf(rectF.Height-HEIGHT)<1e-5, "Expected: %d, got %.05f\n", HEIGHT, rectF.Height);
520
521     stat = GdipDisposeImage(image_dest);
522     expect(Ok, stat);
523 }
524
525 static void test_testcontrol(void)
526 {
527     GpStatus stat;
528     DWORD param;
529
530     param = 0;
531     stat = GdipTestControl(TestControlGetBuildNumber, &param);
532     expect(Ok, stat);
533     ok(param != 0, "Build number expected, got %u\n", param);
534 }
535
536 START_TEST(image)
537 {
538     struct GdiplusStartupInput gdiplusStartupInput;
539     ULONG_PTR gdiplusToken;
540
541     gdiplusStartupInput.GdiplusVersion              = 1;
542     gdiplusStartupInput.DebugEventCallback          = NULL;
543     gdiplusStartupInput.SuppressBackgroundThread    = 0;
544     gdiplusStartupInput.SuppressExternalCodecs      = 0;
545
546     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
547
548     test_Scan0();
549     test_GetImageDimension();
550     test_GdipImageGetFrameDimensionsCount();
551     test_LoadingImages();
552     test_SavingImages();
553     test_encoders();
554     test_LockBits();
555     test_GdipCreateBitmapFromHBITMAP();
556     test_GdipGetImageFlags();
557     test_GdipCloneImage();
558     test_testcontrol();
559
560     GdiplusShutdown(gdiplusToken);
561 }