1 /*****************************************************************************
2 * This file is part of gfxprim library. *
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. *
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. *
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 *
19 * Copyright (C) 2009-2012 Cyril Hrubis <metan@ucw.cz> *
21 *****************************************************************************/
27 #include <core/GP_Pixmap.h>
28 #include <loaders/GP_Loaders.h>
39 static const char *strfmt(enum fmt fmt
)
55 static int save_img(enum fmt fmt
, const GP_Pixmap
*img
, const char *name
)
59 snprintf(buf
, sizeof(buf
), "%s.%s", name
, strfmt(fmt
));
63 return GP_SavePNG(img
, buf
, NULL
);
65 return GP_SaveJPG(img
, buf
, NULL
);
67 return GP_SaveBMP(img
, buf
, NULL
);
69 tst_err("Trying to save %s image", strfmt(fmt
));
74 static GP_Pixmap
*load(enum fmt fmt
, const char *name
)
78 snprintf(buf
, sizeof(buf
), "%s.%s", name
, strfmt(fmt
));
82 return GP_LoadPNG(buf
, NULL
);
84 return GP_LoadJPG(buf
, NULL
);
86 return GP_LoadGIF(buf
, NULL
);
88 return GP_LoadBMP(buf
, NULL
);
90 tst_err("Trying to load %s image", strfmt(fmt
));
95 static int save_load(enum fmt fmt
, GP_Size w
, GP_Size h
)
99 img
= GP_PixmapAlloc(w
, h
, GP_PIXEL_RGB888
);
102 tst_warn("GP_PixmapAlloc failed");
106 int ret
= save_img(fmt
, img
, "test");
109 if (errno
== ENOSYS
) {
110 tst_msg("Save %s: ENOSYS", strfmt(fmt
));
114 tst_msg("Failed to save %s: %s",
115 strfmt(fmt
), strerror(errno
));
119 res
= load(fmt
, "test");
122 tst_msg("Failed to load %s: %s",
123 strfmt(fmt
), strerror(errno
));
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
)
167 img
= load(fmt
, "nonexistent");
170 tst_msg("Test succedded unexpectedly");
174 if (errno
== ENOSYS
) {
175 tst_msg("Load %s: ENOSYS", strfmt(fmt
));
179 if (errno
!= ENOENT
) {
180 tst_msg("Expected errno = ENOENT, have %s", strerror(errno
));
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
)
212 snprintf(buf
, sizeof(buf
), "test.%s", strfmt(fmt
));
214 FILE *f
= fopen(buf
, "w");
217 tst_err("Failed to create file 'test': %s", strerror(errno
));
223 if (chmod(buf
, 200)) {
224 tst_err("chmod failed: %s", strerror(errno
));
228 img
= load(fmt
, "test");
231 tst_msg("Test succedded unexpectedly");
235 if (errno
== ENOSYS
) {
236 tst_msg("Load %s: ENOSYS", strfmt(fmt
));
240 if (errno
!= EACCES
) {
241 tst_msg("Expected errno = EACCES, have %s",
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
)
274 snprintf(buf
, sizeof(buf
), "test.%s", strfmt(fmt
));
276 FILE *f
= fopen(buf
, "w");
279 tst_err("Failed to create file 'test': %s", strerror(errno
));
285 img
= load(fmt
, "test");
288 tst_msg("Test succedded unexpectedly");
292 if (errno
== ENOSYS
) {
293 tst_msg("Load %s: ENOSYS", strfmt(fmt
));
298 tst_msg("Expected errno = EIO, have %s",
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
330 static int abort_callback(GP_ProgressCallback
*self
__attribute__((unused
)))
335 static int test_PNG_Save_abort(void)
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");
348 if (errno
== ENOSYS
) {
349 tst_msg("Load PNG: ENOSYS");
353 if (errno
!= ECANCELED
) {
354 tst_msg("Expected errno = ECANCELED, have %s",
364 static int test_PNG_Load_abort(void)
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");
377 tst_msg("Failed to save PNG: %s", strerror(errno
));
383 GP_ProgressCallback callback
= {.callback
= abort_callback
};
385 img
= GP_LoadPNG("test.png", &callback
);
387 int saved_errno
= errno
;
390 tst_msg("Failed to abort PNG loading");
394 if (saved_errno
!= ECANCELED
) {
395 tst_msg("Expected errno = ECANCELED, have %s",
396 strerror(saved_errno
));
405 * Loaders test. Hammers the GP_LoadImage() interface with plenty of
406 * unexpected filenames.
408 struct file_testcase
{
409 const char *filename
;
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
},
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
))
496 FILE *f
= fopen(file_testcases
[i
].filename
, "wb");
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
);
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
++) {
518 ret
= GP_LoadImage(file_testcases
[i
].filename
, NULL
);
520 int saved_errno
= errno
;
523 tst_msg("GP_LoadImage('%s') succeeded unexpectedly",
524 file_testcases
[i
].filename
);
529 if (file_testcases
[i
].expected_errno
!= ENOSYS
&& errno
== ENOSYS
) {
530 tst_msg("Load Image '%s': ENOSYS",
531 file_testcases
[i
].filename
);
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
),
540 strerror(saved_errno
),
541 file_testcases
[i
].filename
);
558 static int test_load_BMP(const char *path
)
562 img
= GP_LoadBMP(path
, NULL
);
567 tst_msg("Not Implemented");
570 tst_msg("Got %s", strerror(errno
));
576 * TODO: check correct data.
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
)
630 img
= GP_LoadJPG(path
, NULL
);
635 tst_msg("Not Implemented");
638 tst_msg("Got %s", strerror(errno
));
644 * TODO: check correct data.
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",
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
},