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