Rename GP_Context -> GP_Pixmap
[gfxprim.git] / tests / loaders / loaders_suite.c
blobbbe372a011a3cb710cd5b70e2b38c96d4f946f2b
1 /*****************************************************************************
2 * This file is part of gfxprim library. *
3 * *
4 * Gfxprim is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU Lesser General Public *
6 * License as published by the Free Software Foundation; either *
7 * version 2.1 of the License, or (at your option) any later version. *
8 * *
9 * Gfxprim is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12 * Lesser General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU Lesser General Public *
15 * License along with gfxprim; if not, write to the Free Software *
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
17 * Boston, MA 02110-1301 USA *
18 * *
19 * Copyright (C) 2009-2012 Cyril Hrubis <metan@ucw.cz> *
20 * *
21 *****************************************************************************/
23 #include <string.h>
24 #include <errno.h>
25 #include <sys/stat.h>
27 #include <core/GP_Pixmap.h>
28 #include <loaders/GP_Loaders.h>
30 #include "tst_test.h"
32 enum fmt {
33 PNG,
34 JPG,
35 GIF,
36 BMP,
39 static const char *strfmt(enum fmt fmt)
41 switch (fmt) {
42 case PNG:
43 return "PNG";
44 case JPG:
45 return "JPG";
46 case GIF:
47 return "GIF";
48 case BMP:
49 return "BMP";
52 return "INVALID";
55 static int save_img(enum fmt fmt, const GP_Pixmap *img, const char *name)
57 char buf[256];
59 snprintf(buf, sizeof(buf), "%s.%s", name, strfmt(fmt));
61 switch (fmt) {
62 case PNG:
63 return GP_SavePNG(img, buf, NULL);
64 case JPG:
65 return GP_SaveJPG(img, buf, NULL);
66 case BMP:
67 return GP_SaveBMP(img, buf, NULL);
68 default:
69 tst_err("Trying to save %s image", strfmt(fmt));
70 exit(TST_UNTESTED);
74 static GP_Pixmap *load(enum fmt fmt, const char *name)
76 char buf[256];
78 snprintf(buf, sizeof(buf), "%s.%s", name, strfmt(fmt));
80 switch (fmt) {
81 case PNG:
82 return GP_LoadPNG(buf, NULL);
83 case JPG:
84 return GP_LoadJPG(buf, NULL);
85 case GIF:
86 return GP_LoadGIF(buf, NULL);
87 case BMP:
88 return GP_LoadBMP(buf, NULL);
89 default:
90 tst_err("Trying to load %s image", strfmt(fmt));
91 exit(TST_UNTESTED);
95 static int save_load(enum fmt fmt, GP_Size w, GP_Size h)
97 GP_Pixmap *img, *res;
99 img = GP_PixmapAlloc(w, h, GP_PIXEL_RGB888);
101 if (img == NULL) {
102 tst_warn("GP_PixmapAlloc failed");
103 return TST_UNTESTED;
106 int ret = save_img(fmt, img, "test");
108 if (ret) {
109 if (errno == ENOSYS) {
110 tst_msg("Save %s: ENOSYS", strfmt(fmt));
111 return TST_SKIPPED;
114 tst_msg("Failed to save %s: %s",
115 strfmt(fmt), strerror(errno));
116 return TST_FAILED;
119 res = load(fmt, "test");
121 if (res == NULL) {
122 tst_msg("Failed to load %s: %s",
123 strfmt(fmt), strerror(errno));
124 return TST_FAILED;
127 GP_PixmapFree(img);
128 GP_PixmapFree(res);
130 return TST_SUCCESS;
133 static int test_PNG_Save_Load(void)
135 return save_load(PNG, 100, 100);
138 static int test_JPG_Save_Load(void)
140 return save_load(JPG, 100, 100);
143 static int test_PNG_stress(void)
145 return save_load(PNG, 2000, 2000);
148 static int test_JPG_stress(void)
150 return save_load(JPG, 2000, 2000);
153 static int test_BMP_Save_Load(void)
155 return save_load(BMP, 100, 100);
158 static int test_BMP_stress(void)
160 return save_load(BMP, 2000, 2000);
163 static int load_enoent(enum fmt fmt)
165 GP_Pixmap *img;
167 img = load(fmt, "nonexistent");
169 if (img != NULL) {
170 tst_msg("Test succedded unexpectedly");
171 return TST_FAILED;
174 if (errno == ENOSYS) {
175 tst_msg("Load %s: ENOSYS", strfmt(fmt));
176 return TST_SKIPPED;
179 if (errno != ENOENT) {
180 tst_msg("Expected errno = ENOENT, have %s", strerror(errno));
181 return TST_FAILED;
184 return TST_SUCCESS;
187 static int test_PNG_Load_ENOENT(void)
189 return load_enoent(PNG);
192 static int test_JPG_Load_ENOENT(void)
194 return load_enoent(JPG);
197 static int test_GIF_Load_ENOENT(void)
199 return load_enoent(GIF);
202 static int test_BMP_Load_ENOENT(void)
204 return load_enoent(BMP);
207 static int load_eacces(enum fmt fmt)
209 char buf[256];
210 GP_Pixmap *img;
212 snprintf(buf, sizeof(buf), "test.%s", strfmt(fmt));
214 FILE *f = fopen(buf, "w");
216 if (f == NULL) {
217 tst_err("Failed to create file 'test': %s", strerror(errno));
218 return TST_UNTESTED;
221 fclose(f);
223 if (chmod(buf, 200)) {
224 tst_err("chmod failed: %s", strerror(errno));
225 return TST_UNTESTED;
228 img = load(fmt, "test");
230 if (img != NULL) {
231 tst_msg("Test succedded unexpectedly");
232 return TST_FAILED;
235 if (errno == ENOSYS) {
236 tst_msg("Load %s: ENOSYS", strfmt(fmt));
237 return TST_SKIPPED;
240 if (errno != EACCES) {
241 tst_msg("Expected errno = EACCES, have %s",
242 strerror(errno));
243 return TST_FAILED;
246 return TST_SUCCESS;
249 static int test_PNG_Load_EACCES(void)
251 return load_eacces(PNG);
254 static int test_JPG_Load_EACCES(void)
256 return load_eacces(JPG);
259 static int test_GIF_Load_EACCES(void)
261 return load_eacces(GIF);
264 static int test_BMP_Load_EACCES(void)
266 return load_eacces(BMP);
269 static int load_eio(enum fmt fmt)
271 char buf[256];
272 GP_Pixmap *img;
274 snprintf(buf, sizeof(buf), "test.%s", strfmt(fmt));
276 FILE *f = fopen(buf, "w");
278 if (f == NULL) {
279 tst_err("Failed to create file 'test': %s", strerror(errno));
280 return TST_UNTESTED;
283 fclose(f);
285 img = load(fmt, "test");
287 if (img != NULL) {
288 tst_msg("Test succedded unexpectedly");
289 return TST_FAILED;
292 if (errno == ENOSYS) {
293 tst_msg("Load %s: ENOSYS", strfmt(fmt));
294 return TST_SKIPPED;
297 if (errno != EIO) {
298 tst_msg("Expected errno = EIO, have %s",
299 strerror(errno));
300 return TST_FAILED;
303 return TST_SUCCESS;
306 static int test_PNG_Load_EIO(void)
308 return load_eio(PNG);
311 static int test_JPG_Load_EIO(void)
313 return load_eio(JPG);
316 static int test_GIF_Load_EIO(void)
318 return load_eio(GIF);
321 static int test_BMP_Load_EIO(void)
323 return load_eio(BMP);
327 * We test that a correct cleanup is done after aborting the image load from a
328 * callback.
330 static int abort_callback(GP_ProgressCallback *self __attribute__((unused)))
332 return 1;
335 static int test_PNG_Save_abort(void)
337 GP_Pixmap *img;
339 img = GP_PixmapAlloc(100, 100, GP_PIXEL_RGB888);
341 GP_ProgressCallback callback = {.callback = abort_callback};
343 if (GP_SavePNG(img, "test.png", &callback) == 0) {
344 tst_msg("Failed to save PNG saving");
345 return TST_FAILED;
348 if (errno == ENOSYS) {
349 tst_msg("Load PNG: ENOSYS");
350 return TST_SKIPPED;
353 if (errno != ECANCELED) {
354 tst_msg("Expected errno = ECANCELED, have %s",
355 strerror(errno));
356 return TST_FAILED;
359 GP_PixmapFree(img);
361 return TST_SUCCESS;
364 static int test_PNG_Load_abort(void)
366 GP_Pixmap *img;
368 img = GP_PixmapAlloc(100, 100, GP_PIXEL_RGB888);
370 if (GP_SavePNG(img, "test.png", NULL)) {
372 if (errno == ENOSYS) {
373 tst_msg("Save PNG: ENOSYS");
374 return TST_SKIPPED;
377 tst_msg("Failed to save PNG: %s", strerror(errno));
378 return TST_FAILED;
381 GP_PixmapFree(img);
383 GP_ProgressCallback callback = {.callback = abort_callback};
385 img = GP_LoadPNG("test.png", &callback);
387 int saved_errno = errno;
389 if (img != NULL) {
390 tst_msg("Failed to abort PNG loading");
391 return TST_FAILED;
394 if (saved_errno != ECANCELED) {
395 tst_msg("Expected errno = ECANCELED, have %s",
396 strerror(saved_errno));
397 return TST_FAILED;
400 return TST_SUCCESS;
405 * Loaders test. Hammers the GP_LoadImage() interface with plenty of
406 * unexpected filenames.
408 struct file_testcase {
409 const char *filename;
410 int create;
411 int expected_errno;
414 enum file_flags {
415 FILE_CREATE = 0x01,
416 FILE_FILL = 0x02,
419 static struct file_testcase file_testcases[] = {
422 * Should fail the file signature based loader
423 * as the signature could have been loaded but
424 * the file format is unknown.
426 {"a", FILE_CREATE | FILE_FILL, ENOSYS},
427 {".a", FILE_CREATE | FILE_FILL, ENOSYS},
428 {"a.", FILE_CREATE | FILE_FILL, ENOSYS},
429 {".bc", FILE_CREATE | FILE_FILL, ENOSYS},
430 {"bc", FILE_CREATE | FILE_FILL, ENOSYS},
431 {"abc", FILE_CREATE | FILE_FILL, ENOSYS},
434 * Should fail the corresponding loader and
435 * then fail the signature based loader too.
437 {"wrong.png", FILE_CREATE | FILE_FILL, ENOSYS},
438 {"wrong.jpg", FILE_CREATE | FILE_FILL, ENOSYS},
439 {"wrong.gif", FILE_CREATE | FILE_FILL, ENOSYS},
440 {"wrong.jpeg", FILE_CREATE | FILE_FILL, ENOSYS},
441 {"wrong.bmp", FILE_CREATE | FILE_FILL, ENOSYS},
442 {"wrong.psp", FILE_CREATE | FILE_FILL, ENOSYS},
443 {"wrong.tif", FILE_CREATE | FILE_FILL, ENOSYS},
444 {"wrong.tiff", FILE_CREATE | FILE_FILL, ENOSYS},
447 * Should start signature-based loader and
448 * fail it to read start of the file.
450 {"b", FILE_CREATE, EIO},
451 {".b", FILE_CREATE, EIO},
452 {"b.", FILE_CREATE, EIO},
453 {".dc", FILE_CREATE, EIO},
454 {"dc", FILE_CREATE, EIO},
455 {"cba", FILE_CREATE, EIO},
458 * Dtto but for hits the extension based
459 * loader first and fail to read image header
460 * in the particular loader.
462 {"empty.jpg", FILE_CREATE, EIO},
463 {"empty.png", FILE_CREATE, EIO},
464 {"empty.gif", FILE_CREATE, EIO},
465 {"empty.jpeg", FILE_CREATE, EIO},
466 {"empty.bmp", FILE_CREATE, EIO},
467 {"empty.psp", FILE_CREATE, EIO},
468 {"empty.tif", FILE_CREATE, EIO},
469 {"empty.tiff", FILE_CREATE, EIO},
471 {".jpg", FILE_CREATE, EIO},
472 {".png", FILE_CREATE, EIO},
473 {".gif", FILE_CREATE, EIO},
474 {".jpeg", FILE_CREATE, EIO},
475 {".bmp", FILE_CREATE, EIO},
476 {".psp", FILE_CREATE, EIO},
477 {".tiff", FILE_CREATE, EIO},
479 {"not_here.jpg", 0, ENOENT},
481 //TODO: EACCES
483 {NULL, 0, 0}
486 static int test_Load(void)
488 unsigned int i, fail = 0, success = 0;
490 /* Create empty files */
491 for (i = 0; file_testcases[i].filename != NULL; i++) {
493 if (!(file_testcases[i].create & FILE_CREATE))
494 continue;
496 FILE *f = fopen(file_testcases[i].filename, "wb");
498 if (f != NULL) {
499 char buf[128] = {0};
501 if (file_testcases[i].create & FILE_FILL) {
502 if (fwrite(buf, sizeof(buf), 1, f) != 1)
503 tst_msg("Failed to write to '%s'",
504 file_testcases[i].filename);
507 fclose(f);
508 } else {
509 tst_msg("Failed to open file '%s' for writing",
510 file_testcases[i].filename);
514 for (i = 0; file_testcases[i].filename != NULL; i++) {
515 GP_Pixmap *ret;
516 errno = 0;
518 ret = GP_LoadImage(file_testcases[i].filename, NULL);
520 int saved_errno = errno;
522 if (ret != NULL) {
523 tst_msg("GP_LoadImage('%s') succeeded unexpectedly",
524 file_testcases[i].filename);
525 fail++;
526 continue;
529 if (file_testcases[i].expected_errno != ENOSYS && errno == ENOSYS) {
530 tst_msg("Load Image '%s': ENOSYS",
531 file_testcases[i].filename);
532 continue;
535 if (file_testcases[i].expected_errno != saved_errno) {
536 tst_msg("Expected errno %i (%s) got %i (%s) on '%s'",
537 file_testcases[i].expected_errno,
538 strerror(file_testcases[i].expected_errno),
539 saved_errno,
540 strerror(saved_errno),
541 file_testcases[i].filename);
542 fail++;
543 continue;
546 success++;
549 if (fail)
550 return TST_FAILED;
552 if (success)
553 return TST_SUCCESS;
555 return TST_SKIPPED;
558 static int test_load_BMP(const char *path)
560 GP_Pixmap *img;
562 img = GP_LoadBMP(path, NULL);
564 if (img == NULL) {
565 switch (errno) {
566 case ENOSYS:
567 tst_msg("Not Implemented");
568 return TST_SKIPPED;
569 default:
570 tst_msg("Got %s", strerror(errno));
571 return TST_FAILED;
576 * TODO: check correct data.
579 GP_PixmapFree(img);
581 return TST_SUCCESS;
584 /* Basic loading tests */
586 static int test_load_BMP_1bpp_1x1(void)
588 return test_load_BMP("1bpp-1x1.bmp");
591 static int test_load_BMP_4bpp_1x1(void)
593 return test_load_BMP("4bpp-1x1.bmp");
596 static int test_load_BMP_8bpp_1x1(void)
598 return test_load_BMP("8bpp-1x1.bmp");
601 static int test_load_BMP_24bpp_1x1(void)
603 return test_load_BMP("24bpp-1x1.bmp");
606 static int test_load_BMP_32bpp_1x1(void)
608 return test_load_BMP("32bpp-1x1.bmp");
611 static int test_load_BMP_555_1x1(void)
613 return test_load_BMP("555-1x1.bmp");
616 static int test_load_BMP_565_1x1(void)
618 return test_load_BMP("565-1x1.bmp");
621 static int test_load_BMP_8bpp_1x64000(void)
623 return test_load_BMP("8bpp-1x64000.bmp");
626 static int test_load_JPEG(const char *path)
628 GP_Pixmap *img;
630 img = GP_LoadJPG(path, NULL);
632 if (img == NULL) {
633 switch (errno) {
634 case ENOSYS:
635 tst_msg("Not Implemented");
636 return TST_SKIPPED;
637 default:
638 tst_msg("Got %s", strerror(errno));
639 return TST_FAILED;
644 * TODO: check correct data.
646 GP_PixmapFree(img);
648 return TST_SUCCESS;
651 static int test_load_JPEG_100x100(void)
653 return test_load_JPEG("100x100-red.jpeg");
656 const struct tst_suite tst_suite = {
657 .suite_name = "Image Loaders testsuite",
658 .tests = {
659 /* Correct errno tests */
660 {.name = "PNG Load ENOENT", .tst_fn = test_PNG_Load_ENOENT,
661 .flags = TST_TMPDIR},
662 {.name = "JPG Load ENOENT", .tst_fn = test_JPG_Load_ENOENT,
663 .flags = TST_TMPDIR},
664 {.name = "GIF Load ENOENT", .tst_fn = test_GIF_Load_ENOENT,
665 .flags = TST_TMPDIR},
666 {.name = "BMP Load ENOENT", .tst_fn = test_BMP_Load_ENOENT,
667 .flags = TST_TMPDIR},
669 {.name = "PNG Load EACCES", .tst_fn = test_PNG_Load_EACCES,
670 .flags = TST_TMPDIR},
671 {.name = "JPG Load EACCES", .tst_fn = test_JPG_Load_EACCES,
672 .flags = TST_TMPDIR},
673 {.name = "GIF Load EACCES", .tst_fn = test_GIF_Load_EACCES,
674 .flags = TST_TMPDIR},
675 {.name = "BMP Load EACCES", .tst_fn = test_BMP_Load_EACCES,
676 .flags = TST_TMPDIR},
678 {.name = "PNG Load EIO", .tst_fn = test_PNG_Load_EIO,
679 .flags = TST_TMPDIR},
680 {.name = "JPG Load EIO", .tst_fn = test_JPG_Load_EIO,
681 .flags = TST_TMPDIR},
682 {.name = "GIF Load EIO", .tst_fn = test_GIF_Load_EIO,
683 .flags = TST_TMPDIR},
684 {.name = "BMP Load EIO", .tst_fn = test_BMP_Load_EIO,
685 .flags = TST_TMPDIR},
687 /* Generic GP_LoadImage test */
688 {.name = "Image Load", .tst_fn = test_Load,
689 .flags = TST_TMPDIR | TST_CHECK_MALLOC},
691 /* Callback abort tests */
692 {.name = "PNG Load abort", .tst_fn = test_PNG_Load_abort,
693 .flags = TST_TMPDIR | TST_CHECK_MALLOC},
694 {.name = "PNG Save abort", .tst_fn = test_PNG_Save_abort,
695 .flags = TST_TMPDIR | TST_CHECK_MALLOC},
697 /* Basic Save Load tests */
698 {.name = "PNG Save Load", .tst_fn = test_PNG_Save_Load,
699 .flags = TST_TMPDIR | TST_CHECK_MALLOC},
700 {.name = "JPG Save Load", .tst_fn = test_JPG_Save_Load,
701 .flags = TST_TMPDIR | TST_CHECK_MALLOC},
702 {.name = "BMP Save Load", .tst_fn = test_BMP_Save_Load,
703 .flags = TST_TMPDIR | TST_CHECK_MALLOC},
705 /* Stress Save Load tests */
706 {.name = "PNG Stress", .tst_fn = test_PNG_stress,
707 .flags = TST_TMPDIR | TST_CHECK_MALLOC},
708 {.name = "JPG Stress", .tst_fn = test_JPG_stress,
709 .flags = TST_TMPDIR | TST_CHECK_MALLOC},
710 {.name = "BMP Stress", .tst_fn = test_BMP_stress,
711 .flags = TST_TMPDIR | TST_CHECK_MALLOC},
713 /* BPM loader tests */
714 {.name = "BMP Load 1bpp 1x1",
715 .tst_fn = test_load_BMP_1bpp_1x1,
716 .res_path = "data/bmp/bitmaps/valid/1bpp-1x1.bmp",
717 .flags = TST_TMPDIR},
719 {.name = "BMP Load 4bpp 1x1",
720 .tst_fn = test_load_BMP_4bpp_1x1,
721 .res_path = "data/bmp/bitmaps/valid/4bpp-1x1.bmp",
722 .flags = TST_TMPDIR},
724 {.name = "BMP Load 8bpp 1x1",
725 .tst_fn = test_load_BMP_8bpp_1x1,
726 .res_path = "data/bmp/bitmaps/valid/8bpp-1x1.bmp",
727 .flags = TST_TMPDIR},
729 {.name = "BMP 24bpp 1x1",
730 .tst_fn = test_load_BMP_24bpp_1x1,
731 .res_path = "data/bmp/bitmaps/valid/24bpp-1x1.bmp",
732 .flags = TST_TMPDIR},
734 {.name = "BMP 32bpp 1x1",
735 .tst_fn = test_load_BMP_32bpp_1x1,
736 .res_path = "data/bmp/bitmaps/valid/32bpp-1x1.bmp",
737 .flags = TST_TMPDIR},
739 {.name = "BMP 555 1x1",
740 .tst_fn = test_load_BMP_555_1x1,
741 .res_path = "data/bmp/bitmaps/valid/555-1x1.bmp",
742 .flags = TST_TMPDIR},
744 {.name = "BMP 565 1x1",
745 .tst_fn = test_load_BMP_565_1x1,
746 .res_path = "data/bmp/bitmaps/valid/565-1x1.bmp",
747 .flags = TST_TMPDIR},
749 {.name = "BMP 8bpp 1x64000",
750 .tst_fn = test_load_BMP_8bpp_1x64000,
751 .res_path = "data/bmp/bitmaps/valid/8bpp-1x64000.bmp",
752 .flags = TST_TMPDIR},
754 /* JPEG loader tests */
755 {.name = "JPEG 100x100", .tst_fn = test_load_JPEG_100x100,
756 .res_path = "data/jpeg/valid/100x100-red.jpeg",
757 .flags = TST_TMPDIR},
759 {.name = NULL},