Leptonica 1.83.1
Image processing and image analysis suite
Loading...
Searching...
No Matches
readfile.c
Go to the documentation of this file.
1/*====================================================================*
2 - Copyright (C) 2001 Leptonica. All rights reserved.
3 -
4 - Redistribution and use in source and binary forms, with or without
5 - modification, are permitted provided that the following conditions
6 - are met:
7 - 1. Redistributions of source code must retain the above copyright
8 - notice, this list of conditions and the following disclaimer.
9 - 2. Redistributions in binary form must reproduce the above
10 - copyright notice, this list of conditions and the following
11 - disclaimer in the documentation and/or other materials
12 - provided with the distribution.
13 -
14 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18 - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *====================================================================*/
26
73
74#ifdef HAVE_CONFIG_H
75#include <config_auto.h>
76#endif /* HAVE_CONFIG_H */
77
78#include <string.h>
79#include "allheaders.h"
80
81 /* Output files for ioFormatTest(). */
82static const char *FILE_BMP = "/tmp/lept/format/file.bmp";
83static const char *FILE_PNG = "/tmp/lept/format/file.png";
84static const char *FILE_PNM = "/tmp/lept/format/file.pnm";
85static const char *FILE_G3 = "/tmp/lept/format/file_g3.tif";
86static const char *FILE_G4 = "/tmp/lept/format/file_g4.tif";
87static const char *FILE_RLE = "/tmp/lept/format/file_rle.tif";
88static const char *FILE_PB = "/tmp/lept/format/file_packbits.tif";
89static const char *FILE_LZW = "/tmp/lept/format/file_lzw.tif";
90static const char *FILE_ZIP = "/tmp/lept/format/file_zip.tif";
91static const char *FILE_TIFF_JPEG = "/tmp/lept/format/file_jpeg.tif";
92static const char *FILE_TIFF = "/tmp/lept/format/file.tif";
93static const char *FILE_JPG = "/tmp/lept/format/file.jpg";
94static const char *FILE_GIF = "/tmp/lept/format/file.gif";
95static const char *FILE_WEBP = "/tmp/lept/format/file.webp";
96static const char *FILE_JP2K = "/tmp/lept/format/file.jp2";
97
98 /* There are two jp2 formats, and two codecs associated with them:
99 * OPJ_CODEC_J2K (L_J2K_CODEC) is associated with JP2K_CODESTREAM
100 * OPJ_CODEC_JP2 (L_JP2_CODEC) is associated with JP2K_IMAGE_DATA */
101static const unsigned char JP2K_CODESTREAM[4] = { 0xff, 0x4f, 0xff, 0x51 };
102static const unsigned char JP2K_IMAGE_DATA[12] = { 0x00, 0x00, 0x00, 0x0c,
103 0x6a, 0x50, 0x20, 0x20,
104 0x0d, 0x0a, 0x87, 0x0a };
105
106
107/*---------------------------------------------------------------------*
108 * Top-level functions for reading images from file *
109 *---------------------------------------------------------------------*/
126PIXA *
127pixaReadFiles(const char *dirname,
128 const char *substr)
129{
130PIXA *pixa;
131SARRAY *sa;
132
133 if (!dirname)
134 return (PIXA *)ERROR_PTR("dirname not defined", __func__, NULL);
135
136 if ((sa = getSortedPathnamesInDirectory(dirname, substr, 0, 0)) == NULL)
137 return (PIXA *)ERROR_PTR("sa not made", __func__, NULL);
138
139 pixa = pixaReadFilesSA(sa);
140 sarrayDestroy(&sa);
141 return pixa;
142}
143
144
151PIXA *
153{
154char *str;
155l_int32 i, n;
156PIX *pix;
157PIXA *pixa;
158
159 if (!sa)
160 return (PIXA *)ERROR_PTR("sa not defined", __func__, NULL);
161
162 n = sarrayGetCount(sa);
163 pixa = pixaCreate(n);
164 for (i = 0; i < n; i++) {
165 str = sarrayGetString(sa, i, L_NOCOPY);
166 if ((pix = pixRead(str)) == NULL) {
167 L_WARNING("pix not read from file %s\n", __func__, str);
168 continue;
169 }
170 pixaAddPix(pixa, pix, L_INSERT);
171 }
172
173 return pixa;
174}
175
176
188PIX *
189pixRead(const char *filename)
190{
191FILE *fp;
192PIX *pix;
193
194 if (!filename)
195 return (PIX *)ERROR_PTR("filename not defined", __func__, NULL);
196
197 if ((fp = fopenReadStream(filename)) == NULL) {
198 L_ERROR("image file not found: %s\n", __func__, filename);
199 return NULL;
200 }
201 pix = pixReadStream(fp, 0);
202 fclose(fp);
203 if (!pix)
204 return (PIX *)ERROR_PTR("pix not read", __func__, NULL);
205 return pix;
206}
207
208
223PIX *
224pixReadWithHint(const char *filename,
225 l_int32 hint)
226{
227FILE *fp;
228PIX *pix;
229
230 if (!filename)
231 return (PIX *)ERROR_PTR("filename not defined", __func__, NULL);
232
233 if ((fp = fopenReadStream(filename)) == NULL)
234 return (PIX *)ERROR_PTR("image file not found", __func__, NULL);
235 pix = pixReadStream(fp, hint);
236 fclose(fp);
237
238 if (!pix)
239 return (PIX *)ERROR_PTR("image not returned", __func__, NULL);
240 return pix;
241}
242
243
272PIX *
274 l_int32 index)
275{
276char *fname;
277l_int32 n;
278PIX *pix;
279
280 if (!sa)
281 return (PIX *)ERROR_PTR("sa not defined", __func__, NULL);
282 n = sarrayGetCount(sa);
283 if (index < 0 || index >= n)
284 return (PIX *)ERROR_PTR("index out of bounds", __func__, NULL);
285
286 fname = sarrayGetString(sa, index, L_NOCOPY);
287 if (fname[0] == '\0')
288 return NULL;
289
290 if ((pix = pixRead(fname)) == NULL) {
291 L_ERROR("pix not read from file %s\n", __func__, fname);
292 return NULL;
293 }
294
295 return pix;
296}
297
298
311PIX *
313 l_int32 hint)
314{
315l_int32 format, ret, valid;
316l_uint8 *comment;
317PIX *pix;
318PIXCMAP *cmap;
319
320 if (!fp)
321 return (PIX *)ERROR_PTR("stream not defined", __func__, NULL);
322 pix = NULL;
323
324 findFileFormatStream(fp, &format);
325 switch (format)
326 {
327 case IFF_BMP:
328 if ((pix = pixReadStreamBmp(fp)) == NULL )
329 return (PIX *)ERROR_PTR( "bmp: no pix returned", __func__, NULL);
330 break;
331
332 case IFF_JFIF_JPEG:
333 if ((pix = pixReadStreamJpeg(fp, 0, 1, NULL, hint)) == NULL)
334 return (PIX *)ERROR_PTR( "jpeg: no pix returned", __func__, NULL);
335 ret = fgetJpegComment(fp, &comment);
336 if (!ret && comment)
337 pixSetText(pix, (char *)comment);
338 LEPT_FREE(comment);
339 break;
340
341 case IFF_PNG:
342 if ((pix = pixReadStreamPng(fp)) == NULL)
343 return (PIX *)ERROR_PTR("png: no pix returned", __func__, NULL);
344 break;
345
346 case IFF_TIFF:
347 case IFF_TIFF_PACKBITS:
348 case IFF_TIFF_RLE:
349 case IFF_TIFF_G3:
350 case IFF_TIFF_G4:
351 case IFF_TIFF_LZW:
352 case IFF_TIFF_ZIP:
353 case IFF_TIFF_JPEG:
354 if ((pix = pixReadStreamTiff(fp, 0)) == NULL) /* page 0 by default */
355 return (PIX *)ERROR_PTR("tiff: no pix returned", __func__, NULL);
356 break;
357
358 case IFF_PNM:
359 if ((pix = pixReadStreamPnm(fp)) == NULL)
360 return (PIX *)ERROR_PTR("pnm: no pix returned", __func__, NULL);
361 break;
362
363 case IFF_GIF:
364 if ((pix = pixReadStreamGif(fp)) == NULL)
365 return (PIX *)ERROR_PTR("gif: no pix returned", __func__, NULL);
366 break;
367
368 case IFF_JP2:
369 if ((pix = pixReadStreamJp2k(fp, 1, NULL, 0, 0)) == NULL)
370 return (PIX *)ERROR_PTR("jp2: no pix returned", __func__, NULL);
371 break;
372
373 case IFF_WEBP:
374 if ((pix = pixReadStreamWebP(fp)) == NULL)
375 return (PIX *)ERROR_PTR("webp: no pix returned", __func__, NULL);
376 break;
377
378 case IFF_PS:
379 L_ERROR("PostScript reading is not supported\n", __func__);
380 return NULL;
381
382 case IFF_LPDF:
383 L_ERROR("Pdf reading is not supported\n", __func__);
384 return NULL;
385
386 case IFF_SPIX:
387 if ((pix = pixReadStreamSpix(fp)) == NULL)
388 return (PIX *)ERROR_PTR("spix: no pix returned", __func__, NULL);
389 break;
390
391 case IFF_UNKNOWN:
392 return (PIX *)ERROR_PTR( "Unknown format: no pix returned",
393 __func__, NULL);
394 break;
395 }
396
397 if (pix) {
398 pixSetInputFormat(pix, format);
399 if ((cmap = pixGetColormap(pix))) {
400 pixcmapIsValid(cmap, pix, &valid);
401 if (!valid) {
402 pixDestroy(&pix);
403 return (PIX *)ERROR_PTR("invalid colormap", __func__, NULL);
404 }
405 }
406 }
407 return pix;
408}
409
410
411
412/*---------------------------------------------------------------------*
413 * Read header information from file *
414 *---------------------------------------------------------------------*/
433l_ok
434pixReadHeader(const char *filename,
435 l_int32 *pformat,
436 l_int32 *pw,
437 l_int32 *ph,
438 l_int32 *pbps,
439 l_int32 *pspp,
440 l_int32 *piscmap)
441{
442l_int32 format, ret, w, h, d, bps, spp, iscmap;
443l_int32 type; /* ignored */
444FILE *fp;
445PIX *pix;
446
447 if (pw) *pw = 0;
448 if (ph) *ph = 0;
449 if (pbps) *pbps = 0;
450 if (pspp) *pspp = 0;
451 if (piscmap) *piscmap = 0;
452 if (pformat) *pformat = 0;
453 iscmap = 0; /* init to false */
454 if (!filename)
455 return ERROR_INT("filename not defined", __func__, 1);
456
457 if ((fp = fopenReadStream(filename)) == NULL)
458 return ERROR_INT("image file not found", __func__, 1);
459 findFileFormatStream(fp, &format);
460 fclose(fp);
461
462 switch (format)
463 {
464 case IFF_BMP: /* cheating: reading the entire file */
465 if ((pix = pixRead(filename)) == NULL)
466 return ERROR_INT( "bmp: pix not read", __func__, 1);
467 pixGetDimensions(pix, &w, &h, &d);
468 if (pixGetColormap(pix))
469 iscmap = 1;
470 pixDestroy(&pix);
471 bps = (d == 32) ? 8 : d;
472 spp = (d == 32) ? 3 : 1;
473 break;
474
475 case IFF_JFIF_JPEG:
476 ret = readHeaderJpeg(filename, &w, &h, &spp, NULL, NULL);
477 bps = 8;
478 if (ret)
479 return ERROR_INT( "jpeg: no header info returned", __func__, 1);
480 break;
481
482 case IFF_PNG:
483 ret = readHeaderPng(filename, &w, &h, &bps, &spp, &iscmap);
484 if (ret)
485 return ERROR_INT( "png: no header info returned", __func__, 1);
486 break;
487
488 case IFF_TIFF:
489 case IFF_TIFF_PACKBITS:
490 case IFF_TIFF_RLE:
491 case IFF_TIFF_G3:
492 case IFF_TIFF_G4:
493 case IFF_TIFF_LZW:
494 case IFF_TIFF_ZIP:
495 case IFF_TIFF_JPEG:
496 /* Reading page 0 by default; possibly redefine format */
497 ret = readHeaderTiff(filename, 0, &w, &h, &bps, &spp, NULL, &iscmap,
498 &format);
499 if (ret)
500 return ERROR_INT( "tiff: no header info returned", __func__, 1);
501 break;
502
503 case IFF_PNM:
504 ret = readHeaderPnm(filename, &w, &h, &d, &type, &bps, &spp);
505 if (ret)
506 return ERROR_INT( "pnm: no header info returned", __func__, 1);
507 break;
508
509 case IFF_GIF: /* cheating: reading the entire file */
510 if ((pix = pixRead(filename)) == NULL)
511 return ERROR_INT( "gif: pix not read", __func__, 1);
512 pixGetDimensions(pix, &w, &h, &d);
513 pixDestroy(&pix);
514 iscmap = 1; /* always colormapped; max 256 colors */
515 spp = 1;
516 bps = d;
517 break;
518
519 case IFF_JP2:
520 ret = readHeaderJp2k(filename, &w, &h, &bps, &spp, NULL);
521 break;
522
523 case IFF_WEBP:
524 if (readHeaderWebP(filename, &w, &h, &spp))
525 return ERROR_INT( "webp: no header info returned", __func__, 1);
526 bps = 8;
527 break;
528
529 case IFF_PS:
530 if (pformat) *pformat = format;
531 return ERROR_INT("PostScript reading is not supported\n", __func__, 1);
532
533 case IFF_LPDF:
534 if (pformat) *pformat = format;
535 return ERROR_INT("Pdf reading is not supported\n", __func__, 1);
536
537 case IFF_SPIX:
538 ret = readHeaderSpix(filename, &w, &h, &bps, &spp, &iscmap);
539 if (ret)
540 return ERROR_INT( "spix: no header info returned", __func__, 1);
541 break;
542
543 case IFF_UNKNOWN:
544 L_ERROR("unknown format in file %s\n", __func__, filename);
545 return 1;
546 break;
547 }
548
549 if (pw) *pw = w;
550 if (ph) *ph = h;
551 if (pbps) *pbps = bps;
552 if (pspp) *pspp = spp;
553 if (piscmap) *piscmap = iscmap;
554 if (pformat) *pformat = format;
555 return 0;
556}
557
558
559/*---------------------------------------------------------------------*
560 * Format finders *
561 *---------------------------------------------------------------------*/
569l_ok
570findFileFormat(const char *filename,
571 l_int32 *pformat)
572{
573l_int32 ret;
574FILE *fp;
575
576 if (!pformat)
577 return ERROR_INT("&format not defined", __func__, 1);
578 *pformat = IFF_UNKNOWN;
579 if (!filename)
580 return ERROR_INT("filename not defined", __func__, 1);
581
582 if ((fp = fopenReadStream(filename)) == NULL)
583 return ERROR_INT("image file not found", __func__, 1);
584 ret = findFileFormatStream(fp, pformat);
585 fclose(fp);
586 return ret;
587}
588
589
602l_ok
604 l_int32 *pformat)
605{
606l_uint8 firstbytes[13];
607l_int32 format;
608
609 if (!pformat)
610 return ERROR_INT("&format not defined", __func__, 1);
611 *pformat = IFF_UNKNOWN;
612 if (!fp)
613 return ERROR_INT("stream not defined", __func__, 1);
614
615 rewind(fp);
616 if (fnbytesInFile(fp) < 12)
617 return ERROR_INT("truncated file", __func__, 1);
618
619 if (fread(&firstbytes, 1, 12, fp) != 12)
620 return ERROR_INT("failed to read first 12 bytes of file", __func__, 1);
621 firstbytes[12] = 0;
622 rewind(fp);
623
624 findFileFormatBuffer(firstbytes, &format);
625 if (format == IFF_TIFF) {
626 findTiffCompression(fp, &format);
627 rewind(fp);
628 }
629 *pformat = format;
630 if (format == IFF_UNKNOWN)
631 return 1;
632 else
633 return 0;
634}
635
636
652l_ok
653findFileFormatBuffer(const l_uint8 *buf,
654 l_int32 *pformat)
655{
656l_uint16 twobytepw;
657
658 if (!pformat)
659 return ERROR_INT("&format not defined", __func__, 1);
660 *pformat = IFF_UNKNOWN;
661 if (!buf)
662 return ERROR_INT("byte buffer not defined", __func__, 0);
663
664 /* Check the bmp and tiff 2-byte header ids */
665 ((char *)(&twobytepw))[0] = buf[0];
666 ((char *)(&twobytepw))[1] = buf[1];
667
668 if (convertOnBigEnd16(twobytepw) == BMP_ID) {
669 *pformat = IFF_BMP;
670 return 0;
671 }
672
673 if (twobytepw == TIFF_BIGEND_ID || twobytepw == TIFF_LITTLEEND_ID) {
674 *pformat = IFF_TIFF;
675 return 0;
676 }
677
678 /* Check for the p*m 2-byte header ids */
679 if ((buf[0] == 'P' && buf[1] == '4') || /* newer packed */
680 (buf[0] == 'P' && buf[1] == '1')) { /* old ASCII format */
681 *pformat = IFF_PNM;
682 return 0;
683 }
684
685 if ((buf[0] == 'P' && buf[1] == '5') || /* newer */
686 (buf[0] == 'P' && buf[1] == '2')) { /* old */
687 *pformat = IFF_PNM;
688 return 0;
689 }
690
691 if ((buf[0] == 'P' && buf[1] == '6') || /* newer */
692 (buf[0] == 'P' && buf[1] == '3')) { /* old */
693 *pformat = IFF_PNM;
694 return 0;
695 }
696
697 if (buf[0] == 'P' && buf[1] == '7') { /* new arbitrary (PAM) */
698 *pformat = IFF_PNM;
699 return 0;
700 }
701
702 /* Consider the first 11 bytes of the standard JFIF JPEG header:
703 * - The first two bytes are the most important: 0xffd8.
704 * - The next two bytes are the jfif marker: 0xffe0.
705 * Not all jpeg files have this marker.
706 * - The next two bytes are the header length.
707 * - The next 5 bytes are a null-terminated string.
708 * For JFIF, the string is "JFIF", naturally. For others it
709 * can be "Exif" or just about anything else.
710 * - Because of all this variability, we only check the first
711 * two byte marker. All jpeg files are identified as
712 * IFF_JFIF_JPEG. */
713 if (buf[0] == 0xff && buf[1] == 0xd8) {
714 *pformat = IFF_JFIF_JPEG;
715 return 0;
716 }
717
718 /* Check for the 8 byte PNG signature (png_signature in png.c):
719 * {137, 80, 78, 71, 13, 10, 26, 10} */
720 if (buf[0] == 137 && buf[1] == 80 && buf[2] == 78 && buf[3] == 71 &&
721 buf[4] == 13 && buf[5] == 10 && buf[6] == 26 && buf[7] == 10) {
722 *pformat = IFF_PNG;
723 return 0;
724 }
725
726 /* Look for "GIF87a" or "GIF89a" */
727 if (buf[0] == 'G' && buf[1] == 'I' && buf[2] == 'F' && buf[3] == '8' &&
728 (buf[4] == '7' || buf[4] == '9') && buf[5] == 'a') {
729 *pformat = IFF_GIF;
730 return 0;
731 }
732
733 /* Check for both types of jp2k file */
734 if (memcmp(buf, JP2K_CODESTREAM, 4) == 0 ||
735 memcmp(buf, JP2K_IMAGE_DATA, 12) == 0) {
736 *pformat = IFF_JP2;
737 return 0;
738 }
739
740 /* Check for webp */
741 if (buf[0] == 'R' && buf[1] == 'I' && buf[2] == 'F' && buf[3] == 'F' &&
742 buf[8] == 'W' && buf[9] == 'E' && buf[10] == 'B' && buf[11] == 'P') {
743 *pformat = IFF_WEBP;
744 return 0;
745 }
746
747 /* Check for ps */
748 if (buf[0] == '%' && buf[1] == '!' && buf[2] == 'P' && buf[3] == 'S' &&
749 buf[4] == '-' && buf[5] == 'A' && buf[6] == 'd' && buf[7] == 'o' &&
750 buf[8] == 'b' && buf[9] == 'e') {
751 *pformat = IFF_PS;
752 return 0;
753 }
754
755 /* Check for pdf */
756 if (buf[0] == '%' && buf[1] == 'P' && buf[2] == 'D' && buf[3] == 'F' &&
757 buf[4] == '-' && buf[5] == '1') {
758 *pformat = IFF_LPDF;
759 return 0;
760 }
761
762 /* Check for "spix" serialized pix */
763 if (buf[0] == 's' && buf[1] == 'p' && buf[2] == 'i' && buf[3] == 'x') {
764 *pformat = IFF_SPIX;
765 return 0;
766 }
767
768 /* File format identifier not found; unknown */
769 return 1;
770}
771
772
779l_int32
781{
782l_int32 format;
783
784 if (!fp)
785 return ERROR_INT("stream not defined", __func__, 0);
786
787 findFileFormatStream(fp, &format);
788 if (format == IFF_TIFF || format == IFF_TIFF_PACKBITS ||
789 format == IFF_TIFF_RLE || format == IFF_TIFF_G3 ||
790 format == IFF_TIFF_G4 || format == IFF_TIFF_LZW ||
791 format == IFF_TIFF_ZIP || format == IFF_TIFF_JPEG)
792 return 1;
793 else
794 return 0;
795}
796
797
798/*---------------------------------------------------------------------*
799 * Read from memory *
800 *---------------------------------------------------------------------*/
821PIX *
822pixReadMem(const l_uint8 *data,
823 size_t size)
824{
825l_int32 format, valid;
826PIX *pix;
827PIXCMAP *cmap;
828
829 if (!data)
830 return (PIX *)ERROR_PTR("data not defined", __func__, NULL);
831 if (size < 12)
832 return (PIX *)ERROR_PTR("size < 12", __func__, NULL);
833 pix = NULL;
834
835 findFileFormatBuffer(data, &format);
836 switch (format)
837 {
838 case IFF_BMP:
839 if ((pix = pixReadMemBmp(data, size)) == NULL )
840 return (PIX *)ERROR_PTR( "bmp: no pix returned", __func__, NULL);
841 break;
842
843 case IFF_JFIF_JPEG:
844 if ((pix = pixReadMemJpeg(data, size, 0, 1, NULL, 0)) == NULL)
845 return (PIX *)ERROR_PTR( "jpeg: no pix returned", __func__, NULL);
846 break;
847
848 case IFF_PNG:
849 if ((pix = pixReadMemPng(data, size)) == NULL)
850 return (PIX *)ERROR_PTR("png: no pix returned", __func__, NULL);
851 break;
852
853 case IFF_TIFF:
854 case IFF_TIFF_PACKBITS:
855 case IFF_TIFF_RLE:
856 case IFF_TIFF_G3:
857 case IFF_TIFF_G4:
858 case IFF_TIFF_LZW:
859 case IFF_TIFF_ZIP:
860 /* Reading page 0 by default */
861 if ((pix = pixReadMemTiff(data, size, 0)) == NULL)
862 return (PIX *)ERROR_PTR("tiff: no pix returned", __func__, NULL);
863 break;
864
865 case IFF_PNM:
866 if ((pix = pixReadMemPnm(data, size)) == NULL)
867 return (PIX *)ERROR_PTR("pnm: no pix returned", __func__, NULL);
868 break;
869
870 case IFF_GIF:
871 if ((pix = pixReadMemGif(data, size)) == NULL)
872 return (PIX *)ERROR_PTR("gif: no pix returned", __func__, NULL);
873 break;
874
875 case IFF_JP2:
876 if ((pix = pixReadMemJp2k(data, size, 1, NULL, 0, 0)) == NULL)
877 return (PIX *)ERROR_PTR("jp2k: no pix returned", __func__, NULL);
878 break;
879
880 case IFF_WEBP:
881 if ((pix = pixReadMemWebP(data, size)) == NULL)
882 return (PIX *)ERROR_PTR("webp: no pix returned", __func__, NULL);
883 break;
884
885 case IFF_PS:
886 L_ERROR("PostScript reading is not supported\n", __func__);
887 return NULL;
888
889 case IFF_LPDF:
890 L_ERROR("Pdf reading is not supported\n", __func__);
891 return NULL;
892
893 case IFF_SPIX:
894 if ((pix = pixReadMemSpix(data, size)) == NULL)
895 return (PIX *)ERROR_PTR("spix: no pix returned", __func__, NULL);
896 break;
897
898 case IFF_UNKNOWN:
899 return (PIX *)ERROR_PTR("Unknown format: no pix returned",
900 __func__, NULL);
901 break;
902 }
903
904 /* Set the input format. For tiff reading from memory we lose
905 * the actual input format; for 1 bpp, default to G4. Also
906 * verify that the colormap is valid. */
907 if (pix) {
908 if (format == IFF_TIFF && pixGetDepth(pix) == 1)
909 format = IFF_TIFF_G4;
910 pixSetInputFormat(pix, format);
911 if ((cmap = pixGetColormap(pix))) {
912 pixcmapIsValid(cmap, pix, &valid);
913 if (!valid) {
914 pixDestroy(&pix);
915 return (PIX *)ERROR_PTR("invalid colormap", __func__, NULL);
916 }
917 }
918 pixSetPadBits(pix, 0);
919 }
920 return pix;
921}
922
923
949l_ok
950pixReadHeaderMem(const l_uint8 *data,
951 size_t size,
952 l_int32 *pformat,
953 l_int32 *pw,
954 l_int32 *ph,
955 l_int32 *pbps,
956 l_int32 *pspp,
957 l_int32 *piscmap)
958{
959l_int32 format, ret, w, h, d, bps, spp, iscmap;
960l_int32 type; /* not used */
961PIX *pix;
962
963 if (pw) *pw = 0;
964 if (ph) *ph = 0;
965 if (pbps) *pbps = 0;
966 if (pspp) *pspp = 0;
967 if (piscmap) *piscmap = 0;
968 if (pformat) *pformat = 0;
969 iscmap = 0; /* init to false */
970 if (!data)
971 return ERROR_INT("data not defined", __func__, 1);
972 if (size < 12)
973 return ERROR_INT("size < 12", __func__, 1);
974
975 findFileFormatBuffer(data, &format);
976
977 switch (format)
978 {
979 case IFF_BMP: /* cheating: read the pix */
980 if ((pix = pixReadMemBmp(data, size)) == NULL)
981 return ERROR_INT( "bmp: pix not read", __func__, 1);
982 pixGetDimensions(pix, &w, &h, &d);
983 pixDestroy(&pix);
984 bps = (d == 32) ? 8 : d;
985 spp = (d == 32) ? 3 : 1;
986 break;
987
988 case IFF_JFIF_JPEG:
989 ret = readHeaderMemJpeg(data, size, &w, &h, &spp, NULL, NULL);
990 bps = 8;
991 if (ret)
992 return ERROR_INT( "jpeg: no header info returned", __func__, 1);
993 break;
994
995 case IFF_PNG:
996 ret = readHeaderMemPng(data, size, &w, &h, &bps, &spp, &iscmap);
997 if (ret)
998 return ERROR_INT( "png: no header info returned", __func__, 1);
999 break;
1000
1001 case IFF_TIFF:
1002 case IFF_TIFF_PACKBITS:
1003 case IFF_TIFF_RLE:
1004 case IFF_TIFF_G3:
1005 case IFF_TIFF_G4:
1006 case IFF_TIFF_LZW:
1007 case IFF_TIFF_ZIP:
1008 case IFF_TIFF_JPEG:
1009 /* Reading page 0 by default; possibly redefine format */
1010 ret = readHeaderMemTiff(data, size, 0, &w, &h, &bps, &spp,
1011 NULL, &iscmap, &format);
1012 if (ret)
1013 return ERROR_INT( "tiff: no header info returned", __func__, 1);
1014 break;
1015
1016 case IFF_PNM:
1017 ret = readHeaderMemPnm(data, size, &w, &h, &d, &type, &bps, &spp);
1018 if (ret)
1019 return ERROR_INT( "pnm: no header info returned", __func__, 1);
1020 break;
1021
1022 case IFF_GIF: /* cheating: read the pix */
1023 if ((pix = pixReadMemGif(data, size)) == NULL)
1024 return ERROR_INT( "gif: pix not read", __func__, 1);
1025 pixGetDimensions(pix, &w, &h, &d);
1026 pixDestroy(&pix);
1027 iscmap = 1; /* always colormapped; max 256 colors */
1028 spp = 1;
1029 bps = d;
1030 break;
1031
1032 case IFF_JP2:
1033 ret = readHeaderMemJp2k(data, size, &w, &h, &bps, &spp, NULL);
1034 break;
1035
1036 case IFF_WEBP:
1037 bps = 8;
1038 ret = readHeaderMemWebP(data, size, &w, &h, &spp);
1039 break;
1040
1041 case IFF_PS:
1042 if (pformat) *pformat = format;
1043 return ERROR_INT("PostScript reading is not supported\n", __func__, 1);
1044
1045 case IFF_LPDF:
1046 if (pformat) *pformat = format;
1047 return ERROR_INT("Pdf reading is not supported\n", __func__, 1);
1048
1049 case IFF_SPIX:
1050 ret = sreadHeaderSpix((l_uint32 *)data, size, &w, &h, &bps,
1051 &spp, &iscmap);
1052 if (ret)
1053 return ERROR_INT( "pnm: no header info returned", __func__, 1);
1054 break;
1055
1056 case IFF_UNKNOWN:
1057 return ERROR_INT("unknown format; no data returned", __func__, 1);
1058 break;
1059 }
1060
1061 if (pw) *pw = w;
1062 if (ph) *ph = h;
1063 if (pbps) *pbps = bps;
1064 if (pspp) *pspp = spp;
1065 if (piscmap) *piscmap = iscmap;
1066 if (pformat) *pformat = format;
1067 return 0;
1068}
1069
1070
1071/*---------------------------------------------------------------------*
1072 * Output image file information *
1073 *---------------------------------------------------------------------*/
1074extern const char *ImageFileFormatExtensions[];
1075
1094l_ok
1095writeImageFileInfo(const char *filename,
1096 FILE *fpout,
1097 l_int32 headeronly)
1098{
1099char *text;
1100l_int32 w, h, d, wpl, count, npages, color;
1101l_int32 format, bps, spp, iscmap, xres, yres, transparency;
1102FILE *fpin;
1103PIX *pix, *pixt;
1104PIXCMAP *cmap;
1105
1106 if (!filename)
1107 return ERROR_INT("filename not defined", __func__, 1);
1108 if (!fpout)
1109 return ERROR_INT("stream not defined", __func__, 1);
1110
1111 /* Read the header */
1112 if (pixReadHeader(filename, &format, &w, &h, &bps, &spp, &iscmap)) {
1113 L_ERROR("failure to read header of %s\n", __func__, filename);
1114 return 1;
1115 }
1116 fprintf(fpout, "===============================================\n"
1117 "Reading the header:\n");
1118 fprintf(fpout, " input image format type: %s\n",
1119 ImageFileFormatExtensions[format]);
1120 fprintf(fpout, " w = %d, h = %d, bps = %d, spp = %d, iscmap = %d\n",
1121 w, h, bps, spp, iscmap);
1122
1123 findFileFormat(filename, &format);
1124 if (format == IFF_JP2) {
1125 fpin = lept_fopen(filename, "rb");
1126 fgetJp2kResolution(fpin, &xres, &yres);
1127 fclose(fpin);
1128 fprintf(fpout, " xres = %d, yres = %d\n", xres, yres);
1129 } else if (format == IFF_PNG) {
1130 fpin = lept_fopen(filename, "rb");
1131 fgetPngResolution(fpin, &xres, &yres);
1132 fclose(fpin);
1133 fprintf(fpout, " xres = %d, yres = %d\n", xres, yres);
1134 if (iscmap) {
1135 fpin = lept_fopen(filename, "rb");
1136 fgetPngColormapInfo(fpin, &cmap, &transparency);
1137 fclose(fpin);
1138 if (transparency)
1139 fprintf(fpout, " colormap has transparency\n");
1140 else
1141 fprintf(fpout, " colormap does not have transparency\n");
1142 pixcmapWriteStream(fpout, cmap);
1143 pixcmapDestroy(&cmap);
1144 }
1145 } else if (format == IFF_JFIF_JPEG) {
1146 fpin = lept_fopen(filename, "rb");
1147 fgetJpegResolution(fpin, &xres, &yres);
1148 fclose(fpin);
1149 fprintf(fpout, " xres = %d, yres = %d\n", xres, yres);
1150 }
1151
1152 if (headeronly)
1153 return 0;
1154
1155 /* Read the full image. Note that when we read an image that
1156 * has transparency in a colormap, we convert it to RGBA. */
1157 fprintf(fpout, "===============================================\n"
1158 "Reading the full image:\n");
1159
1160 /* Preserve 16 bpp if the format is png */
1161 if (format == IFF_PNG && bps == 16)
1162 l_pngSetReadStrip16To8(0);
1163
1164 if ((pix = pixRead(filename)) == NULL) {
1165 L_ERROR("failure to read full image of %s\n", __func__, filename);
1166 return 1;
1167 }
1168
1169 format = pixGetInputFormat(pix);
1170 pixGetDimensions(pix, &w, &h, &d);
1171 wpl = pixGetWpl(pix);
1172 spp = pixGetSpp(pix);
1173 fprintf(fpout, " input image format type: %s\n",
1174 ImageFileFormatExtensions[format]);
1175 fprintf(fpout, " w = %d, h = %d, d = %d, spp = %d, wpl = %d\n",
1176 w, h, d, spp, wpl);
1177 fprintf(fpout, " xres = %d, yres = %d\n",
1178 pixGetXRes(pix), pixGetYRes(pix));
1179
1180 text = pixGetText(pix);
1181 if (text) /* not null */
1182 fprintf(fpout, " text: %s\n", text);
1183
1184 cmap = pixGetColormap(pix);
1185 if (cmap) {
1186 pixcmapHasColor(cmap, &color);
1187 if (color)
1188 fprintf(fpout, " colormap exists and has color values:");
1189 else
1190 fprintf(fpout, " colormap exists and has only gray values:");
1191 pixcmapWriteStream(fpout, pixGetColormap(pix));
1192 }
1193 else
1194 fprintf(fpout, " colormap does not exist\n");
1195
1196 if (format == IFF_TIFF || format == IFF_TIFF_G4 ||
1197 format == IFF_TIFF_G3 || format == IFF_TIFF_PACKBITS) {
1198 fprintf(fpout, " Tiff header information:\n");
1199 fpin = lept_fopen(filename, "rb");
1200 tiffGetCount(fpin, &npages);
1201 lept_fclose(fpin);
1202 if (npages == 1)
1203 fprintf(fpout, " One page in file\n");
1204 else
1205 fprintf(fpout, " %d pages in file\n", npages);
1206 fprintTiffInfo(fpout, filename);
1207 }
1208
1209 if (d == 1) {
1210 pixCountPixels(pix, &count, NULL);
1211 pixGetDimensions(pix, &w, &h, NULL);
1212 fprintf(fpout, " 1 bpp: foreground pixel fraction ON/Total = %g\n",
1213 (l_float32)count / (l_float32)(w * h));
1214 }
1215 fprintf(fpout, "===============================================\n");
1216
1217 /* If there is an alpha component, visualize it. Note that when
1218 * alpha == 0, the rgb layer is transparent. We visualize the
1219 * result when a white background is visible through the
1220 * transparency layer. */
1221 if (pixGetSpp(pix) == 4) {
1222 pixt = pixDisplayLayersRGBA(pix, 0xffffff00, 600.0);
1223 pixDisplay(pixt, 100, 100);
1224 pixDestroy(&pixt);
1225 }
1226
1227 if (format == IFF_PNG && bps == 16)
1228 l_pngSetReadStrip16To8(1); /* return to default if format is png */
1229
1230 pixDestroy(&pix);
1231 return 0;
1232}
1233
1234
1235/*---------------------------------------------------------------------*
1236 * Test function for I/O with different formats *
1237 *---------------------------------------------------------------------*/
1260l_ok
1261ioFormatTest(const char *filename)
1262{
1263l_int32 w, h, d, depth, equal, problems;
1264l_float32 diff;
1265BOX *box;
1266PIX *pixs, *pixc, *pix1, *pix2;
1267PIXCMAP *cmap;
1268
1269 if (!filename)
1270 return ERROR_INT("filename not defined", __func__, 1);
1271
1272 /* Read the input file and limit the size */
1273 if ((pix1 = pixRead(filename)) == NULL)
1274 return ERROR_INT("pix1 not made", __func__, 1);
1275 pixGetDimensions(pix1, &w, &h, NULL);
1276 if (w > 250 && h > 250) { /* take the central 250 x 250 region */
1277 box = boxCreate(w / 2 - 125, h / 2 - 125, 250, 250);
1278 pixs = pixClipRectangle(pix1, box, NULL);
1279 boxDestroy(&box);
1280 } else {
1281 pixs = pixClone(pix1);
1282 }
1283 pixDestroy(&pix1);
1284
1285 lept_mkdir("lept/format");
1286
1287 /* Note that the reader automatically removes colormaps
1288 * from 1 bpp BMP images, but not from 8 bpp BMP images.
1289 * Therefore, if our 8 bpp image initially doesn't have a
1290 * colormap, we are going to need to remove it from any
1291 * pix read from a BMP file. */
1292 pixc = pixClone(pixs); /* laziness */
1293
1294 /* This does not test the alpha layer pixels, because most
1295 * formats don't support it. Remove any alpha. */
1296 if (pixGetSpp(pixc) == 4)
1297 pixSetSpp(pixc, 3);
1298 cmap = pixGetColormap(pixc); /* colormap; can be NULL */
1299 d = pixGetDepth(pixc);
1300
1301 problems = FALSE;
1302
1303 /* ----------------------- BMP -------------------------- */
1304
1305 /* BMP works for 1, 2, 4, 8 and 32 bpp images.
1306 * It always writes colormaps for 1 and 8 bpp, so we must
1307 * remove it after readback if the input image doesn't have
1308 * a colormap. Although we can write/read 2 bpp BMP, nobody
1309 * else can read them! */
1310 if (d == 1 || d == 8) {
1311 L_INFO("write/read bmp\n", __func__);
1312 pixWrite(FILE_BMP, pixc, IFF_BMP);
1313 pix1 = pixRead(FILE_BMP);
1314 if (!cmap)
1315 pix2 = pixRemoveColormap(pix1, REMOVE_CMAP_BASED_ON_SRC);
1316 else
1317 pix2 = pixClone(pix1);
1318 pixEqual(pixc, pix2, &equal);
1319 if (!equal) {
1320 L_INFO(" **** bad bmp image: d = %d ****\n", __func__, d);
1321 problems = TRUE;
1322 }
1323 pixDestroy(&pix1);
1324 pixDestroy(&pix2);
1325 }
1326
1327 if (d == 2 || d == 4 || d == 32) {
1328 L_INFO("write/read bmp\n", __func__);
1329 pixWrite(FILE_BMP, pixc, IFF_BMP);
1330 pix1 = pixRead(FILE_BMP);
1331 pixEqual(pixc, pix1, &equal);
1332 if (!equal) {
1333 L_INFO(" **** bad bmp image: d = %d ****\n", __func__, d);
1334 problems = TRUE;
1335 }
1336 pixDestroy(&pix1);
1337 }
1338
1339 /* ----------------------- PNG -------------------------- */
1340#if HAVE_LIBPNG
1341 /* PNG works for all depths, but here, because we strip
1342 * 16 --> 8 bpp on reading, we don't test png for 16 bpp. */
1343 if (d != 16) {
1344 L_INFO("write/read png\n", __func__);
1345 pixWrite(FILE_PNG, pixc, IFF_PNG);
1346 pix1 = pixRead(FILE_PNG);
1347 pixEqual(pixc, pix1, &equal);
1348 if (!equal) {
1349 L_INFO(" **** bad png image: d = %d ****\n", __func__, d);
1350 problems = TRUE;
1351 }
1352 pixDestroy(&pix1);
1353 }
1354#endif /* HAVE_LIBPNG */
1355
1356 /* ----------------------- TIFF -------------------------- */
1357#if HAVE_LIBTIFF
1358 /* TIFF works for 1, 2, 4, 8, 16 and 32 bpp images.
1359 * Because 8 bpp tiff always writes 256 entry colormaps, the
1360 * colormap sizes may be different for 8 bpp images with
1361 * colormap; we are testing if the image content is the same.
1362 * Likewise, the 2 and 4 bpp tiff images with colormaps
1363 * have colormap sizes 4 and 16, rsp. This test should
1364 * work properly on the content, regardless of the number
1365 * of color entries in pixc. */
1366
1367 /* tiff uncompressed works for all pixel depths */
1368 L_INFO("write/read uncompressed tiff\n", __func__);
1369 pixWrite(FILE_TIFF, pixc, IFF_TIFF);
1370 pix1 = pixRead(FILE_TIFF);
1371 pixEqual(pixc, pix1, &equal);
1372 if (!equal) {
1373 L_INFO(" **** bad tiff uncompressed image: d = %d ****\n",
1374 __func__, d);
1375 problems = TRUE;
1376 }
1377 pixDestroy(&pix1);
1378
1379 /* tiff lzw works for all pixel depths */
1380 L_INFO("write/read lzw compressed tiff\n", __func__);
1381 pixWrite(FILE_LZW, pixc, IFF_TIFF_LZW);
1382 pix1 = pixRead(FILE_LZW);
1383 pixEqual(pixc, pix1, &equal);
1384 if (!equal) {
1385 L_INFO(" **** bad tiff lzw compressed image: d = %d ****\n",
1386 __func__, d);
1387 problems = TRUE;
1388 }
1389 pixDestroy(&pix1);
1390
1391 /* tiff adobe deflate (zip) works for all pixel depths */
1392 L_INFO("write/read zip compressed tiff\n", __func__);
1393 pixWrite(FILE_ZIP, pixc, IFF_TIFF_ZIP);
1394 pix1 = pixRead(FILE_ZIP);
1395 pixEqual(pixc, pix1, &equal);
1396 if (!equal) {
1397 L_INFO(" **** bad tiff zip compressed image: d = %d ****\n",
1398 __func__, d);
1399 problems = TRUE;
1400 }
1401 pixDestroy(&pix1);
1402
1403 /* tiff jpeg encoding works for grayscale and rgb */
1404 if (d == 8 || d == 32) {
1405 PIX *pixc1;
1406 L_INFO("write/read jpeg compressed tiff\n", __func__);
1407 if (d == 8 && pixGetColormap(pixc)) {
1408 pixc1 = pixRemoveColormap(pixc, REMOVE_CMAP_BASED_ON_SRC);
1409 pixWrite(FILE_TIFF_JPEG, pixc1, IFF_TIFF_JPEG);
1410 if ((pix1 = pixRead(FILE_TIFF_JPEG)) == NULL) {
1411 L_INFO(" did not read FILE_TIFF_JPEG\n", __func__);
1412 problems = TRUE;
1413 }
1414 pixDestroy(&pixc1);
1415 } else {
1416 pixWrite(FILE_TIFF_JPEG, pixc, IFF_TIFF_JPEG);
1417 pix1 = pixRead(FILE_TIFF_JPEG);
1418 if (d == 8) {
1419 pixCompareGray(pix1, pixc, L_COMPARE_ABS_DIFF, 0, NULL, &diff,
1420 NULL, NULL);
1421 } else {
1422 pixCompareRGB(pix1, pixc, L_COMPARE_ABS_DIFF, 0, NULL, &diff,
1423 NULL, NULL);
1424 }
1425 if (diff > 8.0) {
1426 L_INFO(" **** bad tiff jpeg compressed image: "
1427 "d = %d, diff = %5.2f ****\n", __func__, d, diff);
1428 problems = TRUE;
1429 }
1430 }
1431 pixDestroy(&pix1);
1432 }
1433
1434 /* tiff g4, g3, rle and packbits work for 1 bpp */
1435 if (d == 1) {
1436 L_INFO("write/read g4 compressed tiff\n", __func__);
1437 pixWrite(FILE_G4, pixc, IFF_TIFF_G4);
1438 pix1 = pixRead(FILE_G4);
1439 pixEqual(pixc, pix1, &equal);
1440 if (!equal) {
1441 L_INFO(" **** bad tiff g4 image ****\n", __func__);
1442 problems = TRUE;
1443 }
1444 pixDestroy(&pix1);
1445
1446 L_INFO("write/read g3 compressed tiff\n", __func__);
1447 pixWrite(FILE_G3, pixc, IFF_TIFF_G3);
1448 pix1 = pixRead(FILE_G3);
1449 pixEqual(pixc, pix1, &equal);
1450 if (!equal) {
1451 L_INFO(" **** bad tiff g3 image ****\n", __func__);
1452 problems = TRUE;
1453 }
1454 pixDestroy(&pix1);
1455
1456 L_INFO("write/read rle compressed tiff\n", __func__);
1457 pixWrite(FILE_RLE, pixc, IFF_TIFF_RLE);
1458 pix1 = pixRead(FILE_RLE);
1459 pixEqual(pixc, pix1, &equal);
1460 if (!equal) {
1461 L_INFO(" **** bad tiff rle image: d = %d ****\n", __func__, d);
1462 problems = TRUE;
1463 }
1464 pixDestroy(&pix1);
1465
1466 L_INFO("write/read packbits compressed tiff\n", __func__);
1467 pixWrite(FILE_PB, pixc, IFF_TIFF_PACKBITS);
1468 pix1 = pixRead(FILE_PB);
1469 pixEqual(pixc, pix1, &equal);
1470 if (!equal) {
1471 L_INFO(" **** bad tiff packbits image: d = %d ****\n",
1472 __func__, d);
1473 problems = TRUE;
1474 }
1475 pixDestroy(&pix1);
1476 }
1477#endif /* HAVE_LIBTIFF */
1478
1479 /* ----------------------- PNM -------------------------- */
1480
1481 /* pnm works for 1, 2, 4, 8, 16 and 32 bpp.
1482 * pnm doesn't have colormaps, so when we write colormapped
1483 * pix out as pnm, the colormap is removed. Thus for the test,
1484 * we must remove the colormap from pixc before testing. */
1485 L_INFO("write/read pnm\n", __func__);
1486 pixWrite(FILE_PNM, pixc, IFF_PNM);
1487 pix1 = pixRead(FILE_PNM);
1488 if (cmap)
1489 pix2 = pixRemoveColormap(pixc, REMOVE_CMAP_BASED_ON_SRC);
1490 else
1491 pix2 = pixClone(pixc);
1492 pixEqual(pix1, pix2, &equal);
1493 if (!equal) {
1494 L_INFO(" **** bad pnm image: d = %d ****\n", __func__, d);
1495 problems = TRUE;
1496 }
1497 pixDestroy(&pix1);
1498 pixDestroy(&pix2);
1499
1500 /* ----------------------- GIF -------------------------- */
1501#if HAVE_LIBGIF
1502 /* GIF works for only 1 and 8 bpp, colormapped */
1503 if (d != 8 || !cmap)
1504 pix1 = pixConvertTo8(pixc, 1);
1505 else
1506 pix1 = pixClone(pixc);
1507 L_INFO("write/read gif\n", __func__);
1508 pixWrite(FILE_GIF, pix1, IFF_GIF);
1509 pix2 = pixRead(FILE_GIF);
1510 pixEqual(pix1, pix2, &equal);
1511 if (!equal) {
1512 L_INFO(" **** bad gif image: d = %d ****\n", __func__, d);
1513 problems = TRUE;
1514 }
1515 pixDestroy(&pix1);
1516 pixDestroy(&pix2);
1517#endif /* HAVE_LIBGIF */
1518
1519 /* ----------------------- JPEG ------------------------- */
1520#if HAVE_LIBJPEG
1521 /* JPEG works for only 8 bpp gray and rgb */
1522 if (cmap || d > 8)
1523 pix1 = pixConvertTo32(pixc);
1524 else
1525 pix1 = pixConvertTo8(pixc, 0);
1526 depth = pixGetDepth(pix1);
1527 L_INFO("write/read jpeg\n", __func__);
1528 pixWrite(FILE_JPG, pix1, IFF_JFIF_JPEG);
1529 pix2 = pixRead(FILE_JPG);
1530 if (depth == 8) {
1531 pixCompareGray(pix1, pix2, L_COMPARE_ABS_DIFF, 0, NULL, &diff,
1532 NULL, NULL);
1533 } else {
1534 pixCompareRGB(pix1, pix2, L_COMPARE_ABS_DIFF, 0, NULL, &diff,
1535 NULL, NULL);
1536 }
1537 if (diff > 8.0) {
1538 L_INFO(" **** bad jpeg image: d = %d, diff = %5.2f ****\n",
1539 __func__, depth, diff);
1540 problems = TRUE;
1541 }
1542 pixDestroy(&pix1);
1543 pixDestroy(&pix2);
1544#endif /* HAVE_LIBJPEG */
1545
1546 /* ----------------------- WEBP ------------------------- */
1547#if HAVE_LIBWEBP
1548 /* WEBP works for rgb and rgba */
1549 if (cmap || d <= 16)
1550 pix1 = pixConvertTo32(pixc);
1551 else
1552 pix1 = pixClone(pixc);
1553 depth = pixGetDepth(pix1);
1554 L_INFO("write/read webp\n", __func__);
1555 pixWrite(FILE_WEBP, pix1, IFF_WEBP);
1556 pix2 = pixRead(FILE_WEBP);
1557 pixCompareRGB(pix1, pix2, L_COMPARE_ABS_DIFF, 0, NULL, &diff, NULL, NULL);
1558 if (diff > 5.0) {
1559 L_INFO(" **** bad webp image: d = %d, diff = %5.2f ****\n",
1560 __func__, depth, diff);
1561 problems = TRUE;
1562 }
1563 pixDestroy(&pix1);
1564 pixDestroy(&pix2);
1565#endif /* HAVE_LIBWEBP */
1566
1567 /* ----------------------- JP2K ------------------------- */
1568#if HAVE_LIBJP2K
1569 /* JP2K works for only 8 bpp gray, rgb and rgba */
1570 if (cmap || d > 8)
1571 pix1 = pixConvertTo32(pixc);
1572 else
1573 pix1 = pixConvertTo8(pixc, 0);
1574 depth = pixGetDepth(pix1);
1575 L_INFO("write/read jp2k\n", __func__);
1576 pixWrite(FILE_JP2K, pix1, IFF_JP2);
1577 pix2 = pixRead(FILE_JP2K);
1578 if (depth == 8) {
1579 pixCompareGray(pix1, pix2, L_COMPARE_ABS_DIFF, 0, NULL, &diff,
1580 NULL, NULL);
1581 } else {
1582 pixCompareRGB(pix1, pix2, L_COMPARE_ABS_DIFF, 0, NULL, &diff,
1583 NULL, NULL);
1584 }
1585 lept_stderr("diff = %7.3f\n", diff);
1586 if (diff > 7.0) {
1587 L_INFO(" **** bad jp2k image: d = %d, diff = %5.2f ****\n",
1588 __func__, depth, diff);
1589 problems = TRUE;
1590 }
1591 pixDestroy(&pix1);
1592 pixDestroy(&pix2);
1593#endif /* HAVE_LIBJP2K */
1594
1595 if (problems == FALSE)
1596 L_INFO("All formats read and written OK!\n", __func__);
1597
1598 pixDestroy(&pixc);
1599 pixDestroy(&pixs);
1600 return problems;
1601}
struct Sarray SARRAY
Definition array.h:81
@ TIFF_LITTLEEND_ID
Definition imageio.h:128
@ TIFF_BIGEND_ID
Definition imageio.h:127
@ BMP_ID
Definition imageio.h:126
@ REMOVE_CMAP_BASED_ON_SRC
Definition pix.h:384
@ L_NOCOPY
Definition pix.h:503
@ L_INSERT
Definition pix.h:504
struct Pix PIX
Definition pix.h:228
struct Box BOX
Definition pix.h:252
struct PixColormap PIXCMAP
Definition pix.h:231
struct Pixa PIXA
Definition pix.h:243
PIX * pixReadIndexed(SARRAY *sa, l_int32 index)
pixReadIndexed()
Definition readfile.c:273
PIX * pixRead(const char *filename)
pixRead()
Definition readfile.c:189
l_ok pixReadHeader(const char *filename, l_int32 *pformat, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp, l_int32 *piscmap)
pixReadHeader()
Definition readfile.c:434
PIXA * pixaReadFiles(const char *dirname, const char *substr)
pixaReadFiles()
Definition readfile.c:127
l_ok findFileFormat(const char *filename, l_int32 *pformat)
findFileFormat()
Definition readfile.c:570
PIXA * pixaReadFilesSA(SARRAY *sa)
pixaReadFilesSA()
Definition readfile.c:152
l_ok writeImageFileInfo(const char *filename, FILE *fpout, l_int32 headeronly)
writeImageFileInfo()
Definition readfile.c:1095
l_ok findFileFormatStream(FILE *fp, l_int32 *pformat)
findFileFormatStream()
Definition readfile.c:603
PIX * pixReadStream(FILE *fp, l_int32 hint)
pixReadStream()
Definition readfile.c:312
PIX * pixReadWithHint(const char *filename, l_int32 hint)
pixReadWithHint()
Definition readfile.c:224
l_ok findFileFormatBuffer(const l_uint8 *buf, l_int32 *pformat)
findFileFormatBuffer()
Definition readfile.c:653
PIX * pixReadMem(const l_uint8 *data, size_t size)
pixReadMem()
Definition readfile.c:822
l_ok ioFormatTest(const char *filename)
ioFormatTest()
Definition readfile.c:1261
l_int32 fileFormatIsTiff(FILE *fp)
fileFormatIsTiff()
Definition readfile.c:780
l_ok pixReadHeaderMem(const l_uint8 *data, size_t size, l_int32 *pformat, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp, l_int32 *piscmap)
pixReadHeaderMem()
Definition readfile.c:950