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