/*====================================================================* - Copyright (C) 2001 Leptonica. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *====================================================================*/ /* * pngio_reg.c * * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * This is the Leptonica regression test for lossless read/write * I/O in png format. * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * * This tests reading and writing of images in png format for * various depths, with and without colormaps. * * This test is dependent on the following external libraries: * libpng, libz */ #ifdef HAVE_CONFIG_H #include #endif /* HAVE_CONFIG_H */ #include "allheaders.h" /* Needed for checking libraries */ #ifdef HAVE_CONFIG_H #include #endif /* HAVE_CONFIG_H */ #define FILE_1BPP "rabi.png" #define FILE_2BPP "speckle2.png" #define FILE_2BPP_C "weasel2.4g.png" #define FILE_4BPP "speckle4.png" #define FILE_4BPP_C "weasel4.16c.png" #define FILE_8BPP "dreyfus8.png" #define FILE_8BPP_C "weasel8.240c.png" #define FILE_16BPP "test16.png" #define FILE_32BPP "weasel32.png" #define FILE_32BPP_ALPHA "test32-alpha.png" #define FILE_CMAP_ALPHA "test-cmap-alpha.png" #define FILE_CMAP_ALPHA2 "test-cmap-alpha2.png" #define FILE_TRANS_ALPHA "test-fulltrans-alpha.png" #define FILE_GRAY_ALPHA "test-gray-alpha.png" static l_int32 test_mem_png(const char *fname); static l_int32 get_header_data(const char *filename); static l_int32 test_1bpp_trans(L_REGPARAMS *rp); static l_int32 test_1bpp_color(L_REGPARAMS *rp); static l_int32 test_1bpp_gray(L_REGPARAMS *rp); static l_int32 test_1bpp_bw1(L_REGPARAMS *rp); static l_int32 test_1bpp_bw2(L_REGPARAMS *rp); static l_int32 test_8bpp_trans(L_REGPARAMS *rp); LEPT_DLL extern const char *ImageFileFormatExtensions[]; int main(int argc, char **argv) { l_int32 success, failure; L_REGPARAMS *rp; #if !defined(HAVE_LIBPNG) L_ERROR("This test requires libpng to run.\n", "pngio_reg"); exit(77); #endif if (regTestSetup(argc, argv, &rp)) return 1; /* --------- Part 1: Test lossless r/w to file ---------*/ failure = FALSE; success = TRUE; lept_stderr("Test bmp 1 bpp file:\n"); if (ioFormatTest(FILE_1BPP)) success = FALSE; lept_stderr("\nTest 2 bpp file:\n"); if (ioFormatTest(FILE_2BPP)) success = FALSE; lept_stderr("\nTest 2 bpp file with cmap:\n"); if (ioFormatTest(FILE_2BPP_C)) success = FALSE; lept_stderr("\nTest 4 bpp file:\n"); if (ioFormatTest(FILE_4BPP)) success = FALSE; lept_stderr("\nTest 4 bpp file with cmap:\n"); if (ioFormatTest(FILE_4BPP_C)) success = FALSE; lept_stderr("\nTest 8 bpp grayscale file with cmap:\n"); if (ioFormatTest(FILE_8BPP)) success = FALSE; lept_stderr("\nTest 8 bpp color file with cmap:\n"); if (ioFormatTest(FILE_8BPP_C)) success = FALSE; lept_stderr("\nTest 16 bpp file:\n"); if (ioFormatTest(FILE_16BPP)) success = FALSE; lept_stderr("\nTest 32 bpp RGB file:\n"); if (ioFormatTest(FILE_32BPP)) success = FALSE; lept_stderr("\nTest 32 bpp RGBA file:\n"); if (ioFormatTest(FILE_32BPP_ALPHA)) success = FALSE; lept_stderr("\nTest spp = 1, cmap with alpha file:\n"); if (ioFormatTest(FILE_CMAP_ALPHA)) success = FALSE; lept_stderr("\nTest spp = 1, cmap with alpha (small alpha array):\n"); if (ioFormatTest(FILE_CMAP_ALPHA2)) success = FALSE; lept_stderr("\nTest spp = 1, fully transparent with alpha file:\n"); if (ioFormatTest(FILE_TRANS_ALPHA)) success = FALSE; lept_stderr("\nTest spp = 2, gray with alpha file:\n"); if (ioFormatTest(FILE_GRAY_ALPHA)) success = FALSE; if (success) { lept_stderr( "\n ********** Success on lossless r/w to file *********\n\n"); } else { lept_stderr( "\n ******* Failure on at least one r/w to file ******\n\n"); } if (!success) failure = TRUE; /* ------------ Part 2: Test lossless r/w to memory ------------ */ success = TRUE; if (test_mem_png(FILE_1BPP)) success = FALSE; if (test_mem_png(FILE_2BPP)) success = FALSE; if (test_mem_png(FILE_2BPP_C)) success = FALSE; if (test_mem_png(FILE_4BPP)) success = FALSE; if (test_mem_png(FILE_4BPP_C)) success = FALSE; if (test_mem_png(FILE_8BPP)) success = FALSE; if (test_mem_png(FILE_8BPP_C)) success = FALSE; if (test_mem_png(FILE_16BPP)) success = FALSE; if (test_mem_png(FILE_32BPP)) success = FALSE; if (test_mem_png(FILE_32BPP_ALPHA)) success = FALSE; if (test_mem_png(FILE_CMAP_ALPHA)) success = FALSE; if (test_mem_png(FILE_CMAP_ALPHA2)) success = FALSE; if (test_mem_png(FILE_TRANS_ALPHA)) success = FALSE; if (test_mem_png(FILE_GRAY_ALPHA)) success = FALSE; if (success) { lept_stderr( "\n ****** Success on lossless r/w to memory *****\n"); } else { lept_stderr( "\n ******* Failure on at least one r/w to memory ******\n"); } if (!success) failure = TRUE; /* ------------ Part 3: Test lossless 1 and 8 bpp r/w ------------ */ lept_stderr("\nTest lossless 1 and 8 bpp r/w\n"); success = TRUE; if (test_1bpp_trans(rp) == 0) success = FALSE; if (test_1bpp_color(rp) == 0) success = FALSE; if (test_1bpp_gray(rp) == 0) success = FALSE; if (test_1bpp_bw1(rp) == 0) success = FALSE; if (test_1bpp_bw2(rp) == 0) success = FALSE; if (test_8bpp_trans(rp) == 0) success = FALSE; if (success) { lept_stderr( "\n ******* Success on 1 and 8 bpp lossless *******\n\n"); } else { lept_stderr( "\n ******* Failure on 1 and 8 bpp lossless *******\n\n"); } if (!success) failure = TRUE; /* -------------- Part 4: Read header information -------------- */ success = TRUE; if (get_header_data(FILE_1BPP)) success = FALSE; if (get_header_data(FILE_2BPP)) success = FALSE; if (get_header_data(FILE_2BPP_C)) success = FALSE; if (get_header_data(FILE_4BPP)) success = FALSE; if (get_header_data(FILE_4BPP_C)) success = FALSE; if (get_header_data(FILE_8BPP)) success = FALSE; if (get_header_data(FILE_8BPP_C)) success = FALSE; if (get_header_data(FILE_16BPP)) success = FALSE; if (get_header_data(FILE_32BPP)) success = FALSE; if (get_header_data(FILE_32BPP_ALPHA)) success = FALSE; if (get_header_data(FILE_CMAP_ALPHA)) success = FALSE; if (get_header_data(FILE_CMAP_ALPHA2)) success = FALSE; if (get_header_data(FILE_TRANS_ALPHA)) success = FALSE; if (get_header_data(FILE_GRAY_ALPHA)) success = FALSE; if (success) { lept_stderr("\n ******* Success on reading headers *******\n\n"); } else { lept_stderr("\n ******* Failure on reading headers *******\n\n"); } if (!success) failure = TRUE; if (!failure) { lept_stderr(" ******* Success on all tests *******\n\n"); } else { lept_stderr(" ******* Failure on at least one test *******\n\n"); } if (failure) rp->success = FALSE; return regTestCleanup(rp); } /* Returns 1 on error */ static l_int32 test_mem_png(const char *fname) { l_uint8 *data = NULL; l_int32 same; size_t size = 0; PIX *pixs; PIX *pixd = NULL; if ((pixs = pixRead(fname)) == NULL) { lept_stderr("Failure to read %s\n", fname); return 1; } if (pixWriteMem(&data, &size, pixs, IFF_PNG)) { lept_stderr("Mem write fail for png\n"); return 1; } if ((pixd = pixReadMem(data, size)) == NULL) { lept_stderr("Mem read fail for png\n"); lept_free(data); return 1; } pixEqual(pixs, pixd, &same); if (!same) lept_stderr("Mem write/read fail for file %s\n", fname); pixDestroy(&pixs); pixDestroy(&pixd); lept_free(data); return (!same); } /* Retrieve header data from file and from array in memory */ static l_int32 get_header_data(const char *filename) { l_uint8 *data; l_int32 ret1, ret2, format1, format2; l_int32 w1, w2, h1, h2, d1, d2, bps1, bps2, spp1, spp2, iscmap1, iscmap2; size_t nbytes1, nbytes2; /* Read header from file */ nbytes1 = nbytesInFile(filename); ret1 = pixReadHeader(filename, &format1, &w1, &h1, &bps1, &spp1, &iscmap1); d1 = bps1 * spp1; if (d1 == 24) d1 = 32; if (ret1) { lept_stderr("Error: couldn't read header data from file: %s\n", filename); } else { lept_stderr("Format data for image %s with format %s:\n" " nbytes = %lu, size (w, h, d) = (%d, %d, %d)\n" " bps = %d, spp = %d, iscmap = %d\n", filename, ImageFileFormatExtensions[format1], (unsigned long)nbytes1, w1, h1, d1, bps1, spp1, iscmap1); if (format1 != IFF_PNG) { lept_stderr("Error: format is %d; should be %d\n", format1, IFF_PNG); ret1 = 1; } } /* Read header from array in memory */ data = l_binaryRead(filename, &nbytes2); ret2 = pixReadHeaderMem(data, nbytes2, &format2, &w2, &h2, &bps2, &spp2, &iscmap2); lept_free(data); d2 = bps2 * spp2; if (d2 == 24) d2 = 32; if (ret2) { lept_stderr("Error: couldn't mem-read header data: %s\n", filename); } else { if (nbytes1 != nbytes2 || format1 != format2 || w1 != w2 || h1 != h2 || d1 != d2 || bps1 != bps2 || spp1 != spp2 || iscmap1 != iscmap2) { lept_stderr("Incomsistency reading image %s with format %s\n", filename, ImageFileFormatExtensions[IFF_PNG]); ret2 = 1; } } return ret1 || ret2; } static l_int32 test_1bpp_trans(L_REGPARAMS *rp) { l_int32 same, transp; FILE *fp; PIX *pix1, *pix2; PIXCMAP *cmap; pix1 = pixRead("feyn-fract2.tif"); cmap = pixcmapCreate(1); pixSetColormap(pix1, cmap); pixcmapAddRGBA(cmap, 180, 130, 220, 0); /* transparent */ pixcmapAddRGBA(cmap, 20, 120, 0, 255); /* opaque */ pixWrite("/tmp/lept/regout/1bpp-trans.png", pix1, IFF_PNG); pix2 = pixRead("/tmp/lept/regout/1bpp-trans.png"); pixEqual(pix1, pix2, &same); if (same) lept_stderr("1bpp_trans: success\n"); else lept_stderr("1bpp_trans: bad output\n"); pixDisplayWithTitle(pix2, 700, 0, NULL, rp->display); pixDestroy(&pix1); pixDestroy(&pix2); fp = fopenReadStream("/tmp/lept/regout/1bpp-trans.png"); fgetPngColormapInfo(fp, &cmap, &transp); if (fp) fclose(fp); if (transp) lept_stderr("1bpp_trans: correct -- transparency found\n"); else lept_stderr("1bpp_trans: error -- no transparency found!\n"); if (rp->display) pixcmapWriteStream(stderr, cmap); pixcmapDestroy(&cmap); return same; } static l_int32 test_1bpp_color(L_REGPARAMS *rp) { l_int32 same, transp; FILE *fp; PIX *pix1, *pix2; PIXCMAP *cmap; pix1 = pixRead("feyn-fract2.tif"); cmap = pixcmapCreate(1); pixSetColormap(pix1, cmap); pixcmapAddRGBA(cmap, 180, 130, 220, 255); /* color, opaque */ pixcmapAddRGBA(cmap, 20, 120, 0, 255); /* color, opaque */ pixWrite("/tmp/lept/regout/1bpp-color.png", pix1, IFF_PNG); pix2 = pixRead("/tmp/lept/regout/1bpp-color.png"); pixEqual(pix1, pix2, &same); if (same) lept_stderr("1bpp_color: success\n"); else lept_stderr("1bpp_color: bad output\n"); pixDisplayWithTitle(pix2, 700, 100, NULL, rp->display); pixDestroy(&pix1); pixDestroy(&pix2); fp = fopenReadStream("/tmp/lept/regout/1bpp-color.png"); fgetPngColormapInfo(fp, &cmap, &transp); if (fp) fclose(fp); if (transp) lept_stderr("1bpp_color: error -- transparency found!\n"); else lept_stderr("1bpp_color: correct -- no transparency found\n"); if (rp->display) pixcmapWriteStream(stderr, cmap); pixcmapDestroy(&cmap); return same; } static l_int32 test_1bpp_gray(L_REGPARAMS *rp) { l_int32 same; PIX *pix1, *pix2; PIXCMAP *cmap; pix1 = pixRead("feyn-fract2.tif"); cmap = pixcmapCreate(1); pixSetColormap(pix1, cmap); pixcmapAddRGBA(cmap, 180, 180, 180, 255); /* light, opaque */ pixcmapAddRGBA(cmap, 60, 60, 60, 255); /* dark, opaque */ pixWrite("/tmp/lept/regout/1bpp-gray.png", pix1, IFF_PNG); pix2 = pixRead("/tmp/lept/regout/1bpp-gray.png"); pixEqual(pix1, pix2, &same); if (same) lept_stderr("1bpp_gray: success\n"); else lept_stderr("1bpp_gray: bad output\n"); pixDisplayWithTitle(pix2, 700, 200, NULL, rp->display); pixDestroy(&pix1); pixDestroy(&pix2); return same; } static l_int32 test_1bpp_bw1(L_REGPARAMS *rp) { l_int32 same; PIX *pix1, *pix2; PIXCMAP *cmap; pix1 = pixRead("feyn-fract2.tif"); cmap = pixcmapCreate(1); pixSetColormap(pix1, cmap); pixcmapAddRGBA(cmap, 0, 0, 0, 255); /* black, opaque */ pixcmapAddRGBA(cmap, 255, 255, 255, 255); /* white, opaque */ pixWrite("/tmp/lept/regout/1bpp-bw1.png", pix1, IFF_PNG); pix2 = pixRead("/tmp/lept/regout/1bpp-bw1.png"); pixEqual(pix1, pix2, &same); if (same) lept_stderr("1bpp_bw1: success\n"); else lept_stderr("1bpp_bw1: bad output\n"); pixDisplayWithTitle(pix2, 700, 300, NULL, rp->display); pixDestroy(&pix1); pixDestroy(&pix2); return same; } static l_int32 test_1bpp_bw2(L_REGPARAMS *rp) { l_int32 same; PIX *pix1, *pix2; PIXCMAP *cmap; pix1 = pixRead("feyn-fract2.tif"); cmap = pixcmapCreate(1); pixSetColormap(pix1, cmap); pixcmapAddRGBA(cmap, 255, 255, 255, 255); /* white, opaque */ pixcmapAddRGBA(cmap, 0, 0, 0, 255); /* black, opaque */ pixWrite("/tmp/lept/regout/1bpp-bw2.png", pix1, IFF_PNG); pix2 = pixRead("/tmp/lept/regout/1bpp-bw2.png"); pixEqual(pix1, pix2, &same); if (same) lept_stderr("1bpp_bw2: success\n"); else lept_stderr("1bpp_bw2: bad output\n"); pixDisplayWithTitle(pix2, 700, 400, NULL, rp->display); pixDestroy(&pix1); pixDestroy(&pix2); return same; } static l_int32 test_8bpp_trans(L_REGPARAMS *rp) { l_int32 same, transp; FILE *fp; PIX *pix1, *pix2, *pix3; PIXCMAP *cmap; pix1 = pixRead("wyom.jpg"); pix2 = pixColorSegment(pix1, 75, 10, 8, 7, 0); cmap = pixGetColormap(pix2); pixcmapSetAlpha(cmap, 0, 0); /* set blueish sky color to transparent */ pixWrite("/tmp/lept/regout/8bpp-trans.png", pix2, IFF_PNG); pix3 = pixRead("/tmp/lept/regout/8bpp-trans.png"); pixEqual(pix2, pix3, &same); if (same) lept_stderr("8bpp_trans: success\n"); else lept_stderr("8bpp_trans: bad output\n"); pixDisplayWithTitle(pix3, 700, 0, NULL, rp->display); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); fp = fopenReadStream("/tmp/lept/regout/8bpp-trans.png"); fgetPngColormapInfo(fp, &cmap, &transp); if (fp) fclose(fp); if (transp) lept_stderr("8bpp_trans: correct -- transparency found\n"); else lept_stderr("8bpp_trans: error -- no transparency found!\n"); if (rp->display) pixcmapWriteStream(stderr, cmap); pixcmapDestroy(&cmap); return same; }