Leptonica 1.82.0
Image processing and image analysis suite
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 PROCNAME("pixaReadFiles");
134
135 if (!dirname)
136 return (PIXA *)ERROR_PTR("dirname not defined", procName, NULL);
137
138 if ((sa = getSortedPathnamesInDirectory(dirname, substr, 0, 0)) == NULL)
139 return (PIXA *)ERROR_PTR("sa not made", procName, NULL);
140
141 pixa = pixaReadFilesSA(sa);
142 sarrayDestroy(&sa);
143 return pixa;
144}
145
146
153PIXA *
155{
156char *str;
157l_int32 i, n;
158PIX *pix;
159PIXA *pixa;
160
161 PROCNAME("pixaReadFilesSA");
162
163 if (!sa)
164 return (PIXA *)ERROR_PTR("sa not defined", procName, NULL);
165
166 n = sarrayGetCount(sa);
167 pixa = pixaCreate(n);
168 for (i = 0; i < n; i++) {
169 str = sarrayGetString(sa, i, L_NOCOPY);
170 if ((pix = pixRead(str)) == NULL) {
171 L_WARNING("pix not read from file %s\n", procName, str);
172 continue;
173 }
174 pixaAddPix(pixa, pix, L_INSERT);
175 }
176
177 return pixa;
178}
179
180
192PIX *
193pixRead(const char *filename)
194{
195FILE *fp;
196PIX *pix;
197
198 PROCNAME("pixRead");
199
200 if (!filename)
201 return (PIX *)ERROR_PTR("filename not defined", procName, NULL);
202
203 if ((fp = fopenReadStream(filename)) == NULL) {
204 L_ERROR("image file not found: %s\n", procName, filename);
205 return NULL;
206 }
207 pix = pixReadStream(fp, 0);
208 fclose(fp);
209 if (!pix)
210 return (PIX *)ERROR_PTR("pix not read", procName, NULL);
211 return pix;
212}
213
214
229PIX *
230pixReadWithHint(const char *filename,
231 l_int32 hint)
232{
233FILE *fp;
234PIX *pix;
235
236 PROCNAME("pixReadWithHint");
237
238 if (!filename)
239 return (PIX *)ERROR_PTR("filename not defined", procName, NULL);
240
241 if ((fp = fopenReadStream(filename)) == NULL)
242 return (PIX *)ERROR_PTR("image file not found", procName, NULL);
243 pix = pixReadStream(fp, hint);
244 fclose(fp);
245
246 if (!pix)
247 return (PIX *)ERROR_PTR("image not returned", procName, NULL);
248 return pix;
249}
250
251
280PIX *
282 l_int32 index)
283{
284char *fname;
285l_int32 n;
286PIX *pix;
287
288 PROCNAME("pixReadIndexed");
289
290 if (!sa)
291 return (PIX *)ERROR_PTR("sa not defined", procName, NULL);
292 n = sarrayGetCount(sa);
293 if (index < 0 || index >= n)
294 return (PIX *)ERROR_PTR("index out of bounds", procName, NULL);
295
296 fname = sarrayGetString(sa, index, L_NOCOPY);
297 if (fname[0] == '\0')
298 return NULL;
299
300 if ((pix = pixRead(fname)) == NULL) {
301 L_ERROR("pix not read from file %s\n", procName, fname);
302 return NULL;
303 }
304
305 return pix;
306}
307
308
321PIX *
323 l_int32 hint)
324{
325l_int32 format, ret, valid;
326l_uint8 *comment;
327PIX *pix;
328PIXCMAP *cmap;
329
330 PROCNAME("pixReadStream");
331
332 if (!fp)
333 return (PIX *)ERROR_PTR("stream not defined", procName, NULL);
334 pix = NULL;
335
336 findFileFormatStream(fp, &format);
337 switch (format)
338 {
339 case IFF_BMP:
340 if ((pix = pixReadStreamBmp(fp)) == NULL )
341 return (PIX *)ERROR_PTR( "bmp: no pix returned", procName, NULL);
342 break;
343
344 case IFF_JFIF_JPEG:
345 if ((pix = pixReadStreamJpeg(fp, 0, 1, NULL, hint)) == NULL)
346 return (PIX *)ERROR_PTR( "jpeg: no pix returned", procName, NULL);
347 ret = fgetJpegComment(fp, &comment);
348 if (!ret && comment)
349 pixSetText(pix, (char *)comment);
350 LEPT_FREE(comment);
351 break;
352
353 case IFF_PNG:
354 if ((pix = pixReadStreamPng(fp)) == NULL)
355 return (PIX *)ERROR_PTR("png: no pix returned", procName, NULL);
356 break;
357
358 case IFF_TIFF:
359 case IFF_TIFF_PACKBITS:
360 case IFF_TIFF_RLE:
361 case IFF_TIFF_G3:
362 case IFF_TIFF_G4:
363 case IFF_TIFF_LZW:
364 case IFF_TIFF_ZIP:
365 case IFF_TIFF_JPEG:
366 if ((pix = pixReadStreamTiff(fp, 0)) == NULL) /* page 0 by default */
367 return (PIX *)ERROR_PTR("tiff: no pix returned", procName, NULL);
368 break;
369
370 case IFF_PNM:
371 if ((pix = pixReadStreamPnm(fp)) == NULL)
372 return (PIX *)ERROR_PTR("pnm: no pix returned", procName, NULL);
373 break;
374
375 case IFF_GIF:
376 if ((pix = pixReadStreamGif(fp)) == NULL)
377 return (PIX *)ERROR_PTR("gif: no pix returned", procName, NULL);
378 break;
379
380 case IFF_JP2:
381 if ((pix = pixReadStreamJp2k(fp, 1, NULL, 0, 0)) == NULL)
382 return (PIX *)ERROR_PTR("jp2: no pix returned", procName, NULL);
383 break;
384
385 case IFF_WEBP:
386 if ((pix = pixReadStreamWebP(fp)) == NULL)
387 return (PIX *)ERROR_PTR("webp: no pix returned", procName, NULL);
388 break;
389
390 case IFF_PS:
391 L_ERROR("PostScript reading is not supported\n", procName);
392 return NULL;
393
394 case IFF_LPDF:
395 L_ERROR("Pdf reading is not supported\n", procName);
396 return NULL;
397
398 case IFF_SPIX:
399 if ((pix = pixReadStreamSpix(fp)) == NULL)
400 return (PIX *)ERROR_PTR("spix: no pix returned", procName, NULL);
401 break;
402
403 case IFF_UNKNOWN:
404 return (PIX *)ERROR_PTR( "Unknown format: no pix returned",
405 procName, NULL);
406 break;
407 }
408
409 if (pix) {
410 pixSetInputFormat(pix, format);
411 if ((cmap = pixGetColormap(pix))) {
412 pixcmapIsValid(cmap, pix, &valid);
413 if (!valid) {
414 pixDestroy(&pix);
415 return (PIX *)ERROR_PTR("invalid colormap", procName, NULL);
416 }
417 }
418 }
419 return pix;
420}
421
422
423
424/*---------------------------------------------------------------------*
425 * Read header information from file *
426 *---------------------------------------------------------------------*/
445l_ok
446pixReadHeader(const char *filename,
447 l_int32 *pformat,
448 l_int32 *pw,
449 l_int32 *ph,
450 l_int32 *pbps,
451 l_int32 *pspp,
452 l_int32 *piscmap)
453{
454l_int32 format, ret, w, h, d, bps, spp, iscmap;
455l_int32 type; /* ignored */
456FILE *fp;
457PIX *pix;
458
459 PROCNAME("pixReadHeader");
460
461 if (pw) *pw = 0;
462 if (ph) *ph = 0;
463 if (pbps) *pbps = 0;
464 if (pspp) *pspp = 0;
465 if (piscmap) *piscmap = 0;
466 if (pformat) *pformat = 0;
467 iscmap = 0; /* init to false */
468 if (!filename)
469 return ERROR_INT("filename not defined", procName, 1);
470
471 if ((fp = fopenReadStream(filename)) == NULL)
472 return ERROR_INT("image file not found", procName, 1);
473 findFileFormatStream(fp, &format);
474 fclose(fp);
475
476 switch (format)
477 {
478 case IFF_BMP: /* cheating: reading the entire file */
479 if ((pix = pixRead(filename)) == NULL)
480 return ERROR_INT( "bmp: pix not read", procName, 1);
481 pixGetDimensions(pix, &w, &h, &d);
482 if (pixGetColormap(pix))
483 iscmap = 1;
484 pixDestroy(&pix);
485 bps = (d == 32) ? 8 : d;
486 spp = (d == 32) ? 3 : 1;
487 break;
488
489 case IFF_JFIF_JPEG:
490 ret = readHeaderJpeg(filename, &w, &h, &spp, NULL, NULL);
491 bps = 8;
492 if (ret)
493 return ERROR_INT( "jpeg: no header info returned", procName, 1);
494 break;
495
496 case IFF_PNG:
497 ret = readHeaderPng(filename, &w, &h, &bps, &spp, &iscmap);
498 if (ret)
499 return ERROR_INT( "png: no header info returned", procName, 1);
500 break;
501
502 case IFF_TIFF:
503 case IFF_TIFF_PACKBITS:
504 case IFF_TIFF_RLE:
505 case IFF_TIFF_G3:
506 case IFF_TIFF_G4:
507 case IFF_TIFF_LZW:
508 case IFF_TIFF_ZIP:
509 case IFF_TIFF_JPEG:
510 /* Reading page 0 by default; possibly redefine format */
511 ret = readHeaderTiff(filename, 0, &w, &h, &bps, &spp, NULL, &iscmap,
512 &format);
513 if (ret)
514 return ERROR_INT( "tiff: no header info returned", procName, 1);
515 break;
516
517 case IFF_PNM:
518 ret = readHeaderPnm(filename, &w, &h, &d, &type, &bps, &spp);
519 if (ret)
520 return ERROR_INT( "pnm: no header info returned", procName, 1);
521 break;
522
523 case IFF_GIF: /* cheating: reading the entire file */
524 if ((pix = pixRead(filename)) == NULL)
525 return ERROR_INT( "gif: pix not read", procName, 1);
526 pixGetDimensions(pix, &w, &h, &d);
527 pixDestroy(&pix);
528 iscmap = 1; /* always colormapped; max 256 colors */
529 spp = 1;
530 bps = d;
531 break;
532
533 case IFF_JP2:
534 ret = readHeaderJp2k(filename, &w, &h, &bps, &spp, NULL);
535 break;
536
537 case IFF_WEBP:
538 if (readHeaderWebP(filename, &w, &h, &spp))
539 return ERROR_INT( "webp: no header info returned", procName, 1);
540 bps = 8;
541 break;
542
543 case IFF_PS:
544 if (pformat) *pformat = format;
545 return ERROR_INT("PostScript reading is not supported\n", procName, 1);
546
547 case IFF_LPDF:
548 if (pformat) *pformat = format;
549 return ERROR_INT("Pdf reading is not supported\n", procName, 1);
550
551 case IFF_SPIX:
552 ret = readHeaderSpix(filename, &w, &h, &bps, &spp, &iscmap);
553 if (ret)
554 return ERROR_INT( "spix: no header info returned", procName, 1);
555 break;
556
557 case IFF_UNKNOWN:
558 L_ERROR("unknown format in file %s\n", procName, filename);
559 return 1;
560 break;
561 }
562
563 if (pw) *pw = w;
564 if (ph) *ph = h;
565 if (pbps) *pbps = bps;
566 if (pspp) *pspp = spp;
567 if (piscmap) *piscmap = iscmap;
568 if (pformat) *pformat = format;
569 return 0;
570}
571
572
573/*---------------------------------------------------------------------*
574 * Format finders *
575 *---------------------------------------------------------------------*/
583l_ok
584findFileFormat(const char *filename,
585 l_int32 *pformat)
586{
587l_int32 ret;
588FILE *fp;
589
590 PROCNAME("findFileFormat");
591
592 if (!pformat)
593 return ERROR_INT("&format not defined", procName, 1);
594 *pformat = IFF_UNKNOWN;
595 if (!filename)
596 return ERROR_INT("filename not defined", procName, 1);
597
598 if ((fp = fopenReadStream(filename)) == NULL)
599 return ERROR_INT("image file not found", procName, 1);
600 ret = findFileFormatStream(fp, pformat);
601 fclose(fp);
602 return ret;
603}
604
605
618l_ok
620 l_int32 *pformat)
621{
622l_uint8 firstbytes[13];
623l_int32 format;
624
625 PROCNAME("findFileFormatStream");
626
627 if (!pformat)
628 return ERROR_INT("&format not defined", procName, 1);
629 *pformat = IFF_UNKNOWN;
630 if (!fp)
631 return ERROR_INT("stream not defined", procName, 1);
632
633 rewind(fp);
634 if (fnbytesInFile(fp) < 12)
635 return ERROR_INT("truncated file", procName, 1);
636
637 if (fread(&firstbytes, 1, 12, fp) != 12)
638 return ERROR_INT("failed to read first 12 bytes of file", procName, 1);
639 firstbytes[12] = 0;
640 rewind(fp);
641
642 findFileFormatBuffer(firstbytes, &format);
643 if (format == IFF_TIFF) {
644 findTiffCompression(fp, &format);
645 rewind(fp);
646 }
647 *pformat = format;
648 if (format == IFF_UNKNOWN)
649 return 1;
650 else
651 return 0;
652}
653
654
670l_ok
671findFileFormatBuffer(const l_uint8 *buf,
672 l_int32 *pformat)
673{
674l_uint16 twobytepw;
675
676 PROCNAME("findFileFormatBuffer");
677
678 if (!pformat)
679 return ERROR_INT("&format not defined", procName, 1);
680 *pformat = IFF_UNKNOWN;
681 if (!buf)
682 return ERROR_INT("byte buffer not defined", procName, 0);
683
684 /* Check the bmp and tiff 2-byte header ids */
685 ((char *)(&twobytepw))[0] = buf[0];
686 ((char *)(&twobytepw))[1] = buf[1];
687
688 if (convertOnBigEnd16(twobytepw) == BMP_ID) {
689 *pformat = IFF_BMP;
690 return 0;
691 }
692
693 if (twobytepw == TIFF_BIGEND_ID || twobytepw == TIFF_LITTLEEND_ID) {
694 *pformat = IFF_TIFF;
695 return 0;
696 }
697
698 /* Check for the p*m 2-byte header ids */
699 if ((buf[0] == 'P' && buf[1] == '4') || /* newer packed */
700 (buf[0] == 'P' && buf[1] == '1')) { /* old ASCII format */
701 *pformat = IFF_PNM;
702 return 0;
703 }
704
705 if ((buf[0] == 'P' && buf[1] == '5') || /* newer */
706 (buf[0] == 'P' && buf[1] == '2')) { /* old */
707 *pformat = IFF_PNM;
708 return 0;
709 }
710
711 if ((buf[0] == 'P' && buf[1] == '6') || /* newer */
712 (buf[0] == 'P' && buf[1] == '3')) { /* old */
713 *pformat = IFF_PNM;
714 return 0;
715 }
716
717 if (buf[0] == 'P' && buf[1] == '7') { /* new arbitrary (PAM) */
718 *pformat = IFF_PNM;
719 return 0;
720 }
721
722 /* Consider the first 11 bytes of the standard JFIF JPEG header:
723 * - The first two bytes are the most important: 0xffd8.
724 * - The next two bytes are the jfif marker: 0xffe0.
725 * Not all jpeg files have this marker.
726 * - The next two bytes are the header length.
727 * - The next 5 bytes are a null-terminated string.
728 * For JFIF, the string is "JFIF", naturally. For others it
729 * can be "Exif" or just about anything else.
730 * - Because of all this variability, we only check the first
731 * two byte marker. All jpeg files are identified as
732 * IFF_JFIF_JPEG. */
733 if (buf[0] == 0xff && buf[1] == 0xd8) {
734 *pformat = IFF_JFIF_JPEG;
735 return 0;
736 }
737
738 /* Check for the 8 byte PNG signature (png_signature in png.c):
739 * {137, 80, 78, 71, 13, 10, 26, 10} */
740 if (buf[0] == 137 && buf[1] == 80 && buf[2] == 78 && buf[3] == 71 &&
741 buf[4] == 13 && buf[5] == 10 && buf[6] == 26 && buf[7] == 10) {
742 *pformat = IFF_PNG;
743 return 0;
744 }
745
746 /* Look for "GIF87a" or "GIF89a" */
747 if (buf[0] == 'G' && buf[1] == 'I' && buf[2] == 'F' && buf[3] == '8' &&
748 (buf[4] == '7' || buf[4] == '9') && buf[5] == 'a') {
749 *pformat = IFF_GIF;
750 return 0;
751 }
752
753 /* Check for both types of jp2k file */
754 if (memcmp(buf, JP2K_CODESTREAM, 4) == 0 ||
755 memcmp(buf, JP2K_IMAGE_DATA, 12) == 0) {
756 *pformat = IFF_JP2;
757 return 0;
758 }
759
760 /* Check for webp */
761 if (buf[0] == 'R' && buf[1] == 'I' && buf[2] == 'F' && buf[3] == 'F' &&
762 buf[8] == 'W' && buf[9] == 'E' && buf[10] == 'B' && buf[11] == 'P') {
763 *pformat = IFF_WEBP;
764 return 0;
765 }
766
767 /* Check for ps */
768 if (buf[0] == '%' && buf[1] == '!' && buf[2] == 'P' && buf[3] == 'S' &&
769 buf[4] == '-' && buf[5] == 'A' && buf[6] == 'd' && buf[7] == 'o' &&
770 buf[8] == 'b' && buf[9] == 'e') {
771 *pformat = IFF_PS;
772 return 0;
773 }
774
775 /* Check for pdf */
776 if (buf[0] == '%' && buf[1] == 'P' && buf[2] == 'D' && buf[3] == 'F' &&
777 buf[4] == '-' && buf[5] == '1') {
778 *pformat = IFF_LPDF;
779 return 0;
780 }
781
782 /* Check for "spix" serialized pix */
783 if (buf[0] == 's' && buf[1] == 'p' && buf[2] == 'i' && buf[3] == 'x') {
784 *pformat = IFF_SPIX;
785 return 0;
786 }
787
788 /* File format identifier not found; unknown */
789 return 1;
790}
791
792
799l_int32
801{
802l_int32 format;
803
804 PROCNAME("fileFormatIsTiff");
805
806 if (!fp)
807 return ERROR_INT("stream not defined", procName, 0);
808
809 findFileFormatStream(fp, &format);
810 if (format == IFF_TIFF || format == IFF_TIFF_PACKBITS ||
811 format == IFF_TIFF_RLE || format == IFF_TIFF_G3 ||
812 format == IFF_TIFF_G4 || format == IFF_TIFF_LZW ||
813 format == IFF_TIFF_ZIP || format == IFF_TIFF_JPEG)
814 return 1;
815 else
816 return 0;
817}
818
819
820/*---------------------------------------------------------------------*
821 * Read from memory *
822 *---------------------------------------------------------------------*/
843PIX *
844pixReadMem(const l_uint8 *data,
845 size_t size)
846{
847l_int32 format, valid;
848PIX *pix;
849PIXCMAP *cmap;
850
851 PROCNAME("pixReadMem");
852
853 if (!data)
854 return (PIX *)ERROR_PTR("data not defined", procName, NULL);
855 if (size < 12)
856 return (PIX *)ERROR_PTR("size < 12", procName, NULL);
857 pix = NULL;
858
859 findFileFormatBuffer(data, &format);
860 switch (format)
861 {
862 case IFF_BMP:
863 if ((pix = pixReadMemBmp(data, size)) == NULL )
864 return (PIX *)ERROR_PTR( "bmp: no pix returned", procName, NULL);
865 break;
866
867 case IFF_JFIF_JPEG:
868 if ((pix = pixReadMemJpeg(data, size, 0, 1, NULL, 0)) == NULL)
869 return (PIX *)ERROR_PTR( "jpeg: no pix returned", procName, NULL);
870 break;
871
872 case IFF_PNG:
873 if ((pix = pixReadMemPng(data, size)) == NULL)
874 return (PIX *)ERROR_PTR("png: no pix returned", procName, NULL);
875 break;
876
877 case IFF_TIFF:
878 case IFF_TIFF_PACKBITS:
879 case IFF_TIFF_RLE:
880 case IFF_TIFF_G3:
881 case IFF_TIFF_G4:
882 case IFF_TIFF_LZW:
883 case IFF_TIFF_ZIP:
884 /* Reading page 0 by default */
885 if ((pix = pixReadMemTiff(data, size, 0)) == NULL)
886 return (PIX *)ERROR_PTR("tiff: no pix returned", procName, NULL);
887 break;
888
889 case IFF_PNM:
890 if ((pix = pixReadMemPnm(data, size)) == NULL)
891 return (PIX *)ERROR_PTR("pnm: no pix returned", procName, NULL);
892 break;
893
894 case IFF_GIF:
895 if ((pix = pixReadMemGif(data, size)) == NULL)
896 return (PIX *)ERROR_PTR("gif: no pix returned", procName, NULL);
897 break;
898
899 case IFF_JP2:
900 if ((pix = pixReadMemJp2k(data, size, 1, NULL, 0, 0)) == NULL)
901 return (PIX *)ERROR_PTR("jp2k: no pix returned", procName, NULL);
902 break;
903
904 case IFF_WEBP:
905 if ((pix = pixReadMemWebP(data, size)) == NULL)
906 return (PIX *)ERROR_PTR("webp: no pix returned", procName, NULL);
907 break;
908
909 case IFF_PS:
910 L_ERROR("PostScript reading is not supported\n", procName);
911 return NULL;
912
913 case IFF_LPDF:
914 L_ERROR("Pdf reading is not supported\n", procName);
915 return NULL;
916
917 case IFF_SPIX:
918 if ((pix = pixReadMemSpix(data, size)) == NULL)
919 return (PIX *)ERROR_PTR("spix: no pix returned", procName, NULL);
920 break;
921
922 case IFF_UNKNOWN:
923 return (PIX *)ERROR_PTR("Unknown format: no pix returned",
924 procName, NULL);
925 break;
926 }
927
928 /* Set the input format. For tiff reading from memory we lose
929 * the actual input format; for 1 bpp, default to G4. Also
930 * verify that the colormap is valid. */
931 if (pix) {
932 if (format == IFF_TIFF && pixGetDepth(pix) == 1)
933 format = IFF_TIFF_G4;
934 pixSetInputFormat(pix, format);
935 if ((cmap = pixGetColormap(pix))) {
936 pixcmapIsValid(cmap, pix, &valid);
937 if (!valid) {
938 pixDestroy(&pix);
939 return (PIX *)ERROR_PTR("invalid colormap", procName, NULL);
940 }
941 }
942 pixSetPadBits(pix, 0);
943 }
944 return pix;
945}
946
947
973l_ok
974pixReadHeaderMem(const l_uint8 *data,
975 size_t size,
976 l_int32 *pformat,
977 l_int32 *pw,
978 l_int32 *ph,
979 l_int32 *pbps,
980 l_int32 *pspp,
981 l_int32 *piscmap)
982{
983l_int32 format, ret, w, h, d, bps, spp, iscmap;
984l_int32 type; /* not used */
985PIX *pix;
986
987 PROCNAME("pixReadHeaderMem");
988
989 if (pw) *pw = 0;
990 if (ph) *ph = 0;
991 if (pbps) *pbps = 0;
992 if (pspp) *pspp = 0;
993 if (piscmap) *piscmap = 0;
994 if (pformat) *pformat = 0;
995 iscmap = 0; /* init to false */
996 if (!data)
997 return ERROR_INT("data not defined", procName, 1);
998 if (size < 12)
999 return ERROR_INT("size < 12", procName, 1);
1000
1001 findFileFormatBuffer(data, &format);
1002
1003 switch (format)
1004 {
1005 case IFF_BMP: /* cheating: read the pix */
1006 if ((pix = pixReadMemBmp(data, size)) == NULL)
1007 return ERROR_INT( "bmp: pix not read", procName, 1);
1008 pixGetDimensions(pix, &w, &h, &d);
1009 pixDestroy(&pix);
1010 bps = (d == 32) ? 8 : d;
1011 spp = (d == 32) ? 3 : 1;
1012 break;
1013
1014 case IFF_JFIF_JPEG:
1015 ret = readHeaderMemJpeg(data, size, &w, &h, &spp, NULL, NULL);
1016 bps = 8;
1017 if (ret)
1018 return ERROR_INT( "jpeg: no header info returned", procName, 1);
1019 break;
1020
1021 case IFF_PNG:
1022 ret = readHeaderMemPng(data, size, &w, &h, &bps, &spp, &iscmap);
1023 if (ret)
1024 return ERROR_INT( "png: no header info returned", procName, 1);
1025 break;
1026
1027 case IFF_TIFF:
1028 case IFF_TIFF_PACKBITS:
1029 case IFF_TIFF_RLE:
1030 case IFF_TIFF_G3:
1031 case IFF_TIFF_G4:
1032 case IFF_TIFF_LZW:
1033 case IFF_TIFF_ZIP:
1034 case IFF_TIFF_JPEG:
1035 /* Reading page 0 by default; possibly redefine format */
1036 ret = readHeaderMemTiff(data, size, 0, &w, &h, &bps, &spp,
1037 NULL, &iscmap, &format);
1038 if (ret)
1039 return ERROR_INT( "tiff: no header info returned", procName, 1);
1040 break;
1041
1042 case IFF_PNM:
1043 ret = readHeaderMemPnm(data, size, &w, &h, &d, &type, &bps, &spp);
1044 if (ret)
1045 return ERROR_INT( "pnm: no header info returned", procName, 1);
1046 break;
1047
1048 case IFF_GIF: /* cheating: read the pix */
1049 if ((pix = pixReadMemGif(data, size)) == NULL)
1050 return ERROR_INT( "gif: pix not read", procName, 1);
1051 pixGetDimensions(pix, &w, &h, &d);
1052 pixDestroy(&pix);
1053 iscmap = 1; /* always colormapped; max 256 colors */
1054 spp = 1;
1055 bps = d;
1056 break;
1057
1058 case IFF_JP2:
1059 ret = readHeaderMemJp2k(data, size, &w, &h, &bps, &spp, NULL);
1060 break;
1061
1062 case IFF_WEBP:
1063 bps = 8;
1064 ret = readHeaderMemWebP(data, size, &w, &h, &spp);
1065 break;
1066
1067 case IFF_PS:
1068 if (pformat) *pformat = format;
1069 return ERROR_INT("PostScript reading is not supported\n", procName, 1);
1070
1071 case IFF_LPDF:
1072 if (pformat) *pformat = format;
1073 return ERROR_INT("Pdf reading is not supported\n", procName, 1);
1074
1075 case IFF_SPIX:
1076 ret = sreadHeaderSpix((l_uint32 *)data, size, &w, &h, &bps,
1077 &spp, &iscmap);
1078 if (ret)
1079 return ERROR_INT( "pnm: no header info returned", procName, 1);
1080 break;
1081
1082 case IFF_UNKNOWN:
1083 return ERROR_INT("unknown format; no data returned", procName, 1);
1084 break;
1085 }
1086
1087 if (pw) *pw = w;
1088 if (ph) *ph = h;
1089 if (pbps) *pbps = bps;
1090 if (pspp) *pspp = spp;
1091 if (piscmap) *piscmap = iscmap;
1092 if (pformat) *pformat = format;
1093 return 0;
1094}
1095
1096
1097/*---------------------------------------------------------------------*
1098 * Output image file information *
1099 *---------------------------------------------------------------------*/
1100extern const char *ImageFileFormatExtensions[];
1101
1120l_ok
1121writeImageFileInfo(const char *filename,
1122 FILE *fpout,
1123 l_int32 headeronly)
1124{
1125char *text;
1126l_int32 w, h, d, wpl, count, npages, color;
1127l_int32 format, bps, spp, iscmap, xres, yres, transparency;
1128FILE *fpin;
1129PIX *pix, *pixt;
1130PIXCMAP *cmap;
1131
1132 PROCNAME("writeImageFileInfo");
1133
1134 if (!filename)
1135 return ERROR_INT("filename not defined", procName, 1);
1136 if (!fpout)
1137 return ERROR_INT("stream not defined", procName, 1);
1138
1139 /* Read the header */
1140 if (pixReadHeader(filename, &format, &w, &h, &bps, &spp, &iscmap)) {
1141 L_ERROR("failure to read header of %s\n", procName, filename);
1142 return 1;
1143 }
1144 fprintf(fpout, "===============================================\n"
1145 "Reading the header:\n");
1146 fprintf(fpout, " input image format type: %s\n",
1147 ImageFileFormatExtensions[format]);
1148 fprintf(fpout, " w = %d, h = %d, bps = %d, spp = %d, iscmap = %d\n",
1149 w, h, bps, spp, iscmap);
1150
1151 findFileFormat(filename, &format);
1152 if (format == IFF_JP2) {
1153 fpin = lept_fopen(filename, "rb");
1154 fgetJp2kResolution(fpin, &xres, &yres);
1155 fclose(fpin);
1156 fprintf(fpout, " xres = %d, yres = %d\n", xres, yres);
1157 } else if (format == IFF_PNG) {
1158 fpin = lept_fopen(filename, "rb");
1159 fgetPngResolution(fpin, &xres, &yres);
1160 fclose(fpin);
1161 fprintf(fpout, " xres = %d, yres = %d\n", xres, yres);
1162 if (iscmap) {
1163 fpin = lept_fopen(filename, "rb");
1164 fgetPngColormapInfo(fpin, &cmap, &transparency);
1165 fclose(fpin);
1166 if (transparency)
1167 fprintf(fpout, " colormap has transparency\n");
1168 else
1169 fprintf(fpout, " colormap does not have transparency\n");
1170 pixcmapWriteStream(fpout, cmap);
1171 pixcmapDestroy(&cmap);
1172 }
1173 } else if (format == IFF_JFIF_JPEG) {
1174 fpin = lept_fopen(filename, "rb");
1175 fgetJpegResolution(fpin, &xres, &yres);
1176 fclose(fpin);
1177 fprintf(fpout, " xres = %d, yres = %d\n", xres, yres);
1178 }
1179
1180 if (headeronly)
1181 return 0;
1182
1183 /* Read the full image. Note that when we read an image that
1184 * has transparency in a colormap, we convert it to RGBA. */
1185 fprintf(fpout, "===============================================\n"
1186 "Reading the full image:\n");
1187
1188 /* Preserve 16 bpp if the format is png */
1189 if (format == IFF_PNG && bps == 16)
1191
1192 if ((pix = pixRead(filename)) == NULL) {
1193 L_ERROR("failure to read full image of %s\n", procName, filename);
1194 return 1;
1195 }
1196
1197 format = pixGetInputFormat(pix);
1198 pixGetDimensions(pix, &w, &h, &d);
1199 wpl = pixGetWpl(pix);
1200 spp = pixGetSpp(pix);
1201 fprintf(fpout, " input image format type: %s\n",
1202 ImageFileFormatExtensions[format]);
1203 fprintf(fpout, " w = %d, h = %d, d = %d, spp = %d, wpl = %d\n",
1204 w, h, d, spp, wpl);
1205 fprintf(fpout, " xres = %d, yres = %d\n",
1206 pixGetXRes(pix), pixGetYRes(pix));
1207
1208 text = pixGetText(pix);
1209 if (text) /* not null */
1210 fprintf(fpout, " text: %s\n", text);
1211
1212 cmap = pixGetColormap(pix);
1213 if (cmap) {
1214 pixcmapHasColor(cmap, &color);
1215 if (color)
1216 fprintf(fpout, " colormap exists and has color values:");
1217 else
1218 fprintf(fpout, " colormap exists and has only gray values:");
1219 pixcmapWriteStream(fpout, pixGetColormap(pix));
1220 }
1221 else
1222 fprintf(fpout, " colormap does not exist\n");
1223
1224 if (format == IFF_TIFF || format == IFF_TIFF_G4 ||
1225 format == IFF_TIFF_G3 || format == IFF_TIFF_PACKBITS) {
1226 fprintf(fpout, " Tiff header information:\n");
1227 fpin = lept_fopen(filename, "rb");
1228 tiffGetCount(fpin, &npages);
1229 lept_fclose(fpin);
1230 if (npages == 1)
1231 fprintf(fpout, " One page in file\n");
1232 else
1233 fprintf(fpout, " %d pages in file\n", npages);
1234 fprintTiffInfo(fpout, filename);
1235 }
1236
1237 if (d == 1) {
1238 pixCountPixels(pix, &count, NULL);
1239 pixGetDimensions(pix, &w, &h, NULL);
1240 fprintf(fpout, " 1 bpp: foreground pixel fraction ON/Total = %g\n",
1241 (l_float32)count / (l_float32)(w * h));
1242 }
1243 fprintf(fpout, "===============================================\n");
1244
1245 /* If there is an alpha component, visualize it. Note that when
1246 * alpha == 0, the rgb layer is transparent. We visualize the
1247 * result when a white background is visible through the
1248 * transparency layer. */
1249 if (pixGetSpp(pix) == 4) {
1250 pixt = pixDisplayLayersRGBA(pix, 0xffffff00, 600.0);
1251 pixDisplay(pixt, 100, 100);
1252 pixDestroy(&pixt);
1253 }
1254
1255 if (format == IFF_PNG && bps == 16)
1256 l_pngSetReadStrip16To8(1); /* return to default if format is png */
1257
1258 pixDestroy(&pix);
1259 return 0;
1260}
1261
1262
1263/*---------------------------------------------------------------------*
1264 * Test function for I/O with different formats *
1265 *---------------------------------------------------------------------*/
1288l_ok
1289ioFormatTest(const char *filename)
1290{
1291l_int32 w, h, d, depth, equal, problems;
1292l_float32 diff;
1293BOX *box;
1294PIX *pixs, *pixc, *pix1, *pix2;
1295PIXCMAP *cmap;
1296
1297 PROCNAME("ioFormatTest");
1298
1299 if (!filename)
1300 return ERROR_INT("filename not defined", procName, 1);
1301
1302 /* Read the input file and limit the size */
1303 if ((pix1 = pixRead(filename)) == NULL)
1304 return ERROR_INT("pix1 not made", procName, 1);
1305 pixGetDimensions(pix1, &w, &h, NULL);
1306 if (w > 250 && h > 250) { /* take the central 250 x 250 region */
1307 box = boxCreate(w / 2 - 125, h / 2 - 125, 250, 250);
1308 pixs = pixClipRectangle(pix1, box, NULL);
1309 boxDestroy(&box);
1310 } else {
1311 pixs = pixClone(pix1);
1312 }
1313 pixDestroy(&pix1);
1314
1315 lept_mkdir("lept/format");
1316
1317 /* Note that the reader automatically removes colormaps
1318 * from 1 bpp BMP images, but not from 8 bpp BMP images.
1319 * Therefore, if our 8 bpp image initially doesn't have a
1320 * colormap, we are going to need to remove it from any
1321 * pix read from a BMP file. */
1322 pixc = pixClone(pixs); /* laziness */
1323
1324 /* This does not test the alpha layer pixels, because most
1325 * formats don't support it. Remove any alpha. */
1326 if (pixGetSpp(pixc) == 4)
1327 pixSetSpp(pixc, 3);
1328 cmap = pixGetColormap(pixc); /* colormap; can be NULL */
1329 d = pixGetDepth(pixc);
1330
1331 problems = FALSE;
1332
1333 /* ----------------------- BMP -------------------------- */
1334
1335 /* BMP works for 1, 2, 4, 8 and 32 bpp images.
1336 * It always writes colormaps for 1 and 8 bpp, so we must
1337 * remove it after readback if the input image doesn't have
1338 * a colormap. Although we can write/read 2 bpp BMP, nobody
1339 * else can read them! */
1340 if (d == 1 || d == 8) {
1341 L_INFO("write/read bmp\n", procName);
1342 pixWrite(FILE_BMP, pixc, IFF_BMP);
1343 pix1 = pixRead(FILE_BMP);
1344 if (!cmap)
1346 else
1347 pix2 = pixClone(pix1);
1348 pixEqual(pixc, pix2, &equal);
1349 if (!equal) {
1350 L_INFO(" **** bad bmp image: d = %d ****\n", procName, d);
1351 problems = TRUE;
1352 }
1353 pixDestroy(&pix1);
1354 pixDestroy(&pix2);
1355 }
1356
1357 if (d == 2 || d == 4 || d == 32) {
1358 L_INFO("write/read bmp\n", procName);
1359 pixWrite(FILE_BMP, pixc, IFF_BMP);
1360 pix1 = pixRead(FILE_BMP);
1361 pixEqual(pixc, pix1, &equal);
1362 if (!equal) {
1363 L_INFO(" **** bad bmp image: d = %d ****\n", procName, d);
1364 problems = TRUE;
1365 }
1366 pixDestroy(&pix1);
1367 }
1368
1369 /* ----------------------- PNG -------------------------- */
1370#if HAVE_LIBPNG
1371 /* PNG works for all depths, but here, because we strip
1372 * 16 --> 8 bpp on reading, we don't test png for 16 bpp. */
1373 if (d != 16) {
1374 L_INFO("write/read png\n", procName);
1375 pixWrite(FILE_PNG, pixc, IFF_PNG);
1376 pix1 = pixRead(FILE_PNG);
1377 pixEqual(pixc, pix1, &equal);
1378 if (!equal) {
1379 L_INFO(" **** bad png image: d = %d ****\n", procName, d);
1380 problems = TRUE;
1381 }
1382 pixDestroy(&pix1);
1383 }
1384#endif /* HAVE_LIBPNG */
1385
1386 /* ----------------------- TIFF -------------------------- */
1387#if HAVE_LIBTIFF
1388 /* TIFF works for 1, 2, 4, 8, 16 and 32 bpp images.
1389 * Because 8 bpp tiff always writes 256 entry colormaps, the
1390 * colormap sizes may be different for 8 bpp images with
1391 * colormap; we are testing if the image content is the same.
1392 * Likewise, the 2 and 4 bpp tiff images with colormaps
1393 * have colormap sizes 4 and 16, rsp. This test should
1394 * work properly on the content, regardless of the number
1395 * of color entries in pixc. */
1396
1397 /* tiff uncompressed works for all pixel depths */
1398 L_INFO("write/read uncompressed tiff\n", procName);
1399 pixWrite(FILE_TIFF, pixc, IFF_TIFF);
1400 pix1 = pixRead(FILE_TIFF);
1401 pixEqual(pixc, pix1, &equal);
1402 if (!equal) {
1403 L_INFO(" **** bad tiff uncompressed image: d = %d ****\n",
1404 procName, d);
1405 problems = TRUE;
1406 }
1407 pixDestroy(&pix1);
1408
1409 /* tiff lzw works for all pixel depths */
1410 L_INFO("write/read lzw compressed tiff\n", procName);
1411 pixWrite(FILE_LZW, pixc, IFF_TIFF_LZW);
1412 pix1 = pixRead(FILE_LZW);
1413 pixEqual(pixc, pix1, &equal);
1414 if (!equal) {
1415 L_INFO(" **** bad tiff lzw compressed image: d = %d ****\n",
1416 procName, d);
1417 problems = TRUE;
1418 }
1419 pixDestroy(&pix1);
1420
1421 /* tiff adobe deflate (zip) works for all pixel depths */
1422 L_INFO("write/read zip compressed tiff\n", procName);
1423 pixWrite(FILE_ZIP, pixc, IFF_TIFF_ZIP);
1424 pix1 = pixRead(FILE_ZIP);
1425 pixEqual(pixc, pix1, &equal);
1426 if (!equal) {
1427 L_INFO(" **** bad tiff zip compressed image: d = %d ****\n",
1428 procName, d);
1429 problems = TRUE;
1430 }
1431 pixDestroy(&pix1);
1432
1433 /* tiff jpeg encoding works for grayscale and rgb */
1434 if (d == 8 || d == 32) {
1435 PIX *pixc1;
1436 L_INFO("write/read jpeg compressed tiff\n", procName);
1437 if (d == 8 && pixGetColormap(pixc)) {
1439 pixWrite(FILE_TIFF_JPEG, pixc1, IFF_TIFF_JPEG);
1440 if ((pix1 = pixRead(FILE_TIFF_JPEG)) == NULL) {
1441 L_INFO(" did not read FILE_TIFF_JPEG\n", procName);
1442 problems = TRUE;
1443 }
1444 pixDestroy(&pixc1);
1445 } else {
1446 pixWrite(FILE_TIFF_JPEG, pixc, IFF_TIFF_JPEG);
1447 pix1 = pixRead(FILE_TIFF_JPEG);
1448 if (d == 8) {
1449 pixCompareGray(pix1, pixc, L_COMPARE_ABS_DIFF, 0, NULL, &diff,
1450 NULL, NULL);
1451 } else {
1452 pixCompareRGB(pix1, pixc, L_COMPARE_ABS_DIFF, 0, NULL, &diff,
1453 NULL, NULL);
1454 }
1455 if (diff > 8.0) {
1456 L_INFO(" **** bad tiff jpeg compressed image: "
1457 "d = %d, diff = %5.2f ****\n", procName, d, diff);
1458 problems = TRUE;
1459 }
1460 }
1461 pixDestroy(&pix1);
1462 }
1463
1464 /* tiff g4, g3, rle and packbits work for 1 bpp */
1465 if (d == 1) {
1466 L_INFO("write/read g4 compressed tiff\n", procName);
1467 pixWrite(FILE_G4, pixc, IFF_TIFF_G4);
1468 pix1 = pixRead(FILE_G4);
1469 pixEqual(pixc, pix1, &equal);
1470 if (!equal) {
1471 L_INFO(" **** bad tiff g4 image ****\n", procName);
1472 problems = TRUE;
1473 }
1474 pixDestroy(&pix1);
1475
1476 L_INFO("write/read g3 compressed tiff\n", procName);
1477 pixWrite(FILE_G3, pixc, IFF_TIFF_G3);
1478 pix1 = pixRead(FILE_G3);
1479 pixEqual(pixc, pix1, &equal);
1480 if (!equal) {
1481 L_INFO(" **** bad tiff g3 image ****\n", procName);
1482 problems = TRUE;
1483 }
1484 pixDestroy(&pix1);
1485
1486 L_INFO("write/read rle compressed tiff\n", procName);
1487 pixWrite(FILE_RLE, pixc, IFF_TIFF_RLE);
1488 pix1 = pixRead(FILE_RLE);
1489 pixEqual(pixc, pix1, &equal);
1490 if (!equal) {
1491 L_INFO(" **** bad tiff rle image: d = %d ****\n", procName, d);
1492 problems = TRUE;
1493 }
1494 pixDestroy(&pix1);
1495
1496 L_INFO("write/read packbits compressed tiff\n", procName);
1497 pixWrite(FILE_PB, pixc, IFF_TIFF_PACKBITS);
1498 pix1 = pixRead(FILE_PB);
1499 pixEqual(pixc, pix1, &equal);
1500 if (!equal) {
1501 L_INFO(" **** bad tiff packbits image: d = %d ****\n",
1502 procName, d);
1503 problems = TRUE;
1504 }
1505 pixDestroy(&pix1);
1506 }
1507#endif /* HAVE_LIBTIFF */
1508
1509 /* ----------------------- PNM -------------------------- */
1510
1511 /* pnm works for 1, 2, 4, 8, 16 and 32 bpp.
1512 * pnm doesn't have colormaps, so when we write colormapped
1513 * pix out as pnm, the colormap is removed. Thus for the test,
1514 * we must remove the colormap from pixc before testing. */
1515 L_INFO("write/read pnm\n", procName);
1516 pixWrite(FILE_PNM, pixc, IFF_PNM);
1517 pix1 = pixRead(FILE_PNM);
1518 if (cmap)
1520 else
1521 pix2 = pixClone(pixc);
1522 pixEqual(pix1, pix2, &equal);
1523 if (!equal) {
1524 L_INFO(" **** bad pnm image: d = %d ****\n", procName, d);
1525 problems = TRUE;
1526 }
1527 pixDestroy(&pix1);
1528 pixDestroy(&pix2);
1529
1530 /* ----------------------- GIF -------------------------- */
1531#if HAVE_LIBGIF
1532 /* GIF works for only 1 and 8 bpp, colormapped */
1533 if (d != 8 || !cmap)
1534 pix1 = pixConvertTo8(pixc, 1);
1535 else
1536 pix1 = pixClone(pixc);
1537 L_INFO("write/read gif\n", procName);
1538 pixWrite(FILE_GIF, pix1, IFF_GIF);
1539 pix2 = pixRead(FILE_GIF);
1540 pixEqual(pix1, pix2, &equal);
1541 if (!equal) {
1542 L_INFO(" **** bad gif image: d = %d ****\n", procName, d);
1543 problems = TRUE;
1544 }
1545 pixDestroy(&pix1);
1546 pixDestroy(&pix2);
1547#endif /* HAVE_LIBGIF */
1548
1549 /* ----------------------- JPEG ------------------------- */
1550#if HAVE_LIBJPEG
1551 /* JPEG works for only 8 bpp gray and rgb */
1552 if (cmap || d > 8)
1553 pix1 = pixConvertTo32(pixc);
1554 else
1555 pix1 = pixConvertTo8(pixc, 0);
1556 depth = pixGetDepth(pix1);
1557 L_INFO("write/read jpeg\n", procName);
1558 pixWrite(FILE_JPG, pix1, IFF_JFIF_JPEG);
1559 pix2 = pixRead(FILE_JPG);
1560 if (depth == 8) {
1561 pixCompareGray(pix1, pix2, L_COMPARE_ABS_DIFF, 0, NULL, &diff,
1562 NULL, NULL);
1563 } else {
1564 pixCompareRGB(pix1, pix2, L_COMPARE_ABS_DIFF, 0, NULL, &diff,
1565 NULL, NULL);
1566 }
1567 if (diff > 8.0) {
1568 L_INFO(" **** bad jpeg image: d = %d, diff = %5.2f ****\n",
1569 procName, depth, diff);
1570 problems = TRUE;
1571 }
1572 pixDestroy(&pix1);
1573 pixDestroy(&pix2);
1574#endif /* HAVE_LIBJPEG */
1575
1576 /* ----------------------- WEBP ------------------------- */
1577#if HAVE_LIBWEBP
1578 /* WEBP works for rgb and rgba */
1579 if (cmap || d <= 16)
1580 pix1 = pixConvertTo32(pixc);
1581 else
1582 pix1 = pixClone(pixc);
1583 depth = pixGetDepth(pix1);
1584 L_INFO("write/read webp\n", procName);
1585 pixWrite(FILE_WEBP, pix1, IFF_WEBP);
1586 pix2 = pixRead(FILE_WEBP);
1587 pixCompareRGB(pix1, pix2, L_COMPARE_ABS_DIFF, 0, NULL, &diff, NULL, NULL);
1588 if (diff > 5.0) {
1589 L_INFO(" **** bad webp image: d = %d, diff = %5.2f ****\n",
1590 procName, depth, diff);
1591 problems = TRUE;
1592 }
1593 pixDestroy(&pix1);
1594 pixDestroy(&pix2);
1595#endif /* HAVE_LIBWEBP */
1596
1597 /* ----------------------- JP2K ------------------------- */
1598#if HAVE_LIBJP2K
1599 /* JP2K works for only 8 bpp gray, rgb and rgba */
1600 if (cmap || d > 8)
1601 pix1 = pixConvertTo32(pixc);
1602 else
1603 pix1 = pixConvertTo8(pixc, 0);
1604 depth = pixGetDepth(pix1);
1605 L_INFO("write/read jp2k\n", procName);
1606 pixWrite(FILE_JP2K, pix1, IFF_JP2);
1607 pix2 = pixRead(FILE_JP2K);
1608 if (depth == 8) {
1609 pixCompareGray(pix1, pix2, L_COMPARE_ABS_DIFF, 0, NULL, &diff,
1610 NULL, NULL);
1611 } else {
1612 pixCompareRGB(pix1, pix2, L_COMPARE_ABS_DIFF, 0, NULL, &diff,
1613 NULL, NULL);
1614 }
1615 lept_stderr("diff = %7.3f\n", diff);
1616 if (diff > 7.0) {
1617 L_INFO(" **** bad jp2k image: d = %d, diff = %5.2f ****\n",
1618 procName, depth, diff);
1619 problems = TRUE;
1620 }
1621 pixDestroy(&pix1);
1622 pixDestroy(&pix2);
1623#endif /* HAVE_LIBJP2K */
1624
1625 if (problems == FALSE)
1626 L_INFO("All formats read and written OK!\n", procName);
1627
1628 pixDestroy(&pixc);
1629 pixDestroy(&pixs);
1630 return problems;
1631}
PIX * pixReadStreamBmp(FILE *fp)
pixReadStreamBmp()
Definition: bmpio.c:87
PIX * pixReadMemBmp(const l_uint8 *cdata, size_t size)
pixReadMemBmp()
Definition: bmpio.c:129
void boxDestroy(BOX **pbox)
boxDestroy()
Definition: boxbasic.c:282
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:172
void pixcmapDestroy(PIXCMAP **pcmap)
pixcmapDestroy()
Definition: colormap.c:279
l_ok pixcmapHasColor(PIXCMAP *cmap, l_int32 *pcolor)
pixcmapHasColor()
Definition: colormap.c:1075
l_ok pixcmapIsValid(const PIXCMAP *cmap, PIX *pix, l_int32 *pvalid)
pixcmapIsValid()
Definition: colormap.c:317
l_ok pixcmapWriteStream(FILE *fp, const PIXCMAP *cmap)
pixcmapWriteStream()
Definition: colormap.c:1965
l_ok pixCompareRGB(PIX *pix1, PIX *pix2, l_int32 comptype, l_int32 plottype, l_int32 *psame, l_float32 *pdiff, l_float32 *prmsdiff, PIX **ppixdiff)
pixCompareRGB()
Definition: compare.c:991
l_ok pixEqual(PIX *pix1, PIX *pix2, l_int32 *psame)
pixEqual()
Definition: compare.c:156
l_ok pixCompareGray(PIX *pix1, PIX *pix2, l_int32 comptype, l_int32 plottype, l_int32 *psame, l_float32 *pdiff, l_float32 *prmsdiff, PIX **ppixdiff)
pixCompareGray()
Definition: compare.c:882
@ TIFF_LITTLEEND_ID
Definition: imageio.h:128
@ TIFF_BIGEND_ID
Definition: imageio.h:127
@ BMP_ID
Definition: imageio.h:126
l_ok readHeaderJp2k(const char *filename, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp, l_int32 *pcodec)
readHeaderJp2k()
Definition: jp2kheader.c:80
l_ok readHeaderMemJp2k(const l_uint8 *data, size_t size, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp, l_int32 *pcodec)
readHeaderMemJp2k()
Definition: jp2kheader.c:172
l_ok readHeaderMemJpeg(const l_uint8 *data, size_t size, l_int32 *pw, l_int32 *ph, l_int32 *pspp, l_int32 *pycck, l_int32 *pcmyk)
readHeaderMemJpeg()
Definition: jpegio.c:1048
PIX * pixReadStreamJpeg(FILE *fp, l_int32 cmapflag, l_int32 reduction, l_int32 *pnwarn, l_int32 hint)
pixReadStreamJpeg()
Definition: jpegio.c:264
l_ok readHeaderJpeg(const char *filename, l_int32 *pw, l_int32 *ph, l_int32 *pspp, l_int32 *pycck, l_int32 *pcmyk)
readHeaderJpeg()
Definition: jpegio.c:509
PIX * pixReadMemJpeg(const l_uint8 *data, size_t size, l_int32 cmflag, l_int32 reduction, l_int32 *pnwarn, l_int32 hint)
pixReadMemJpeg()
Definition: jpegio.c:1001
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:621
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1113
l_ok pixSetText(PIX *pix, const char *textstring)
pixSetText()
Definition: pix1.c:1536
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:593
char * pixGetText(PIX *pix)
pixGetText()
Definition: pix1.c:1512
PIX * pixDisplayLayersRGBA(PIX *pixs, l_uint32 val, l_int32 maxw)
pixDisplayLayersRGBA()
Definition: pix2.c:2351
l_ok pixSetPadBits(PIX *pix, l_int32 val)
pixSetPadBits()
Definition: pix2.c:1382
l_ok pixCountPixels(PIX *pixs, l_int32 *pcount, l_int32 *tab8)
pixCountPixels()
Definition: pix3.c:1937
PIX * pixClipRectangle(PIX *pixs, BOX *box, BOX **pboxc)
pixClipRectangle()
Definition: pix5.c:1026
@ REMOVE_CMAP_BASED_ON_SRC
Definition: pix.h:260
@ L_NOCOPY
Definition: pix.h:710
@ L_INSERT
Definition: pix.h:711
l_ok pixaAddPix(PIXA *pixa, PIX *pix, l_int32 copyflag)
pixaAddPix()
Definition: pixabasic.c:506
PIXA * pixaCreate(l_int32 n)
pixaCreate()
Definition: pixabasic.c:167
PIX * pixConvertTo8(PIX *pixs, l_int32 cmapflag)
pixConvertTo8()
Definition: pixconv.c:3133
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
Definition: pixconv.c:328
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3332
l_ok readHeaderPng(const char *filename, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp, l_int32 *piscmap)
readHeaderPng()
Definition: pngio.c:575
l_ok readHeaderMemPng(const l_uint8 *data, size_t size, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp, l_int32 *piscmap)
readHeaderMemPng()
Definition: pngio.c:676
PIX * pixReadStreamPng(FILE *fp)
pixReadStreamPng()
Definition: pngio.c:187
PIX * pixReadMemPng(const l_uint8 *filedata, size_t filesize)
pixReadMemPng()
Definition: pngio.c:1595
void l_pngSetReadStrip16To8(l_int32 flag)
l_pngSetReadStrip16To8()
Definition: pngio.c:1352
l_ok readHeaderPnm(const char *filename, l_int32 *pw, l_int32 *ph, l_int32 *pd, l_int32 *ptype, l_int32 *pbps, l_int32 *pspp)
readHeaderPnm()
Definition: pnmio.c:520
PIX * pixReadMemPnm(const l_uint8 *data, size_t size)
pixReadMemPnm()
Definition: pnmio.c:1159
PIX * pixReadStreamPnm(FILE *fp)
pixReadStreamPnm()
Definition: pnmio.c:150
l_ok readHeaderMemPnm(const l_uint8 *data, size_t size, l_int32 *pw, l_int32 *ph, l_int32 *pd, l_int32 *ptype, l_int32 *pbps, l_int32 *pspp)
readHeaderMemPnm()
Definition: pnmio.c:1192
PIX * pixReadIndexed(SARRAY *sa, l_int32 index)
pixReadIndexed()
Definition: readfile.c:281
PIX * pixRead(const char *filename)
pixRead()
Definition: readfile.c:193
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:446
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:584
PIXA * pixaReadFilesSA(SARRAY *sa)
pixaReadFilesSA()
Definition: readfile.c:154
l_ok writeImageFileInfo(const char *filename, FILE *fpout, l_int32 headeronly)
writeImageFileInfo()
Definition: readfile.c:1121
l_ok findFileFormatStream(FILE *fp, l_int32 *pformat)
findFileFormatStream()
Definition: readfile.c:619
PIX * pixReadStream(FILE *fp, l_int32 hint)
pixReadStream()
Definition: readfile.c:322
PIX * pixReadWithHint(const char *filename, l_int32 hint)
pixReadWithHint()
Definition: readfile.c:230
l_ok findFileFormatBuffer(const l_uint8 *buf, l_int32 *pformat)
findFileFormatBuffer()
Definition: readfile.c:671
PIX * pixReadMem(const l_uint8 *data, size_t size)
pixReadMem()
Definition: readfile.c:844
l_ok ioFormatTest(const char *filename)
ioFormatTest()
Definition: readfile.c:1289
l_int32 fileFormatIsTiff(FILE *fp)
fileFormatIsTiff()
Definition: readfile.c:800
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:974
SARRAY * getSortedPathnamesInDirectory(const char *dirname, const char *substr, l_int32 first, l_int32 nfiles)
getSortedPathnamesInDirectory()
Definition: sarray1.c:1848
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
sarrayGetString()
Definition: sarray1.c:703
l_int32 sarrayGetCount(SARRAY *sa)
sarrayGetCount()
Definition: sarray1.c:643
void sarrayDestroy(SARRAY **psa)
sarrayDestroy()
Definition: sarray1.c:362
l_ok readHeaderSpix(const char *filename, l_int32 *pwidth, l_int32 *pheight, l_int32 *pbps, l_int32 *pspp, l_int32 *piscmap)
readHeaderSpix()
Definition: spixio.c:130
PIX * pixReadStreamSpix(FILE *fp)
pixReadStreamSpix()
Definition: spixio.c:92
PIX * pixReadMemSpix(const l_uint8 *data, size_t size)
pixReadMemSpix()
Definition: spixio.c:305
l_ok sreadHeaderSpix(const l_uint32 *data, size_t size, l_int32 *pwidth, l_int32 *pheight, l_int32 *pbps, l_int32 *pspp, l_int32 *piscmap)
sreadHeaderSpix()
Definition: spixio.c:216
Definition: pix.h:481
Definition: pix.h:139
Definition: pix.h:456
Definition: array.h:127
l_ok fprintTiffInfo(FILE *fpout, const char *tiffile)
fprintTiffInfo()
Definition: tiffio.c:1604
l_ok readHeaderTiff(const char *filename, l_int32 n, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp, l_int32 *pres, l_int32 *pcmap, l_int32 *pformat)
readHeaderTiff()
Definition: tiffio.c:1787
l_ok readHeaderMemTiff(const l_uint8 *cdata, size_t size, l_int32 n, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp, l_int32 *pres, l_int32 *pcmap, l_int32 *pformat)
readHeaderMemTiff()
Definition: tiffio.c:1911
l_ok findTiffCompression(FILE *fp, l_int32 *pcomptype)
findTiffCompression()
Definition: tiffio.c:2044
PIX * pixReadStreamTiff(FILE *fp, l_int32 n)
pixReadStreamTiff()
Definition: tiffio.c:420
PIX * pixReadMemTiff(const l_uint8 *cdata, size_t size, l_int32 n)
pixReadMemTiff()
Definition: tiffio.c:2621
l_ok tiffGetCount(FILE *fp, l_int32 *pn)
tiffGetCount()
Definition: tiffio.c:1637
void lept_stderr(const char *fmt,...)
lept_stderr()
Definition: utils1.c:306
l_ok lept_fclose(FILE *fp)
lept_fclose()
Definition: utils2.c:2143
FILE * lept_fopen(const char *filename, const char *mode)
lept_fopen()
Definition: utils2.c:2113
size_t fnbytesInFile(FILE *fp)
fnbytesInFile()
Definition: utils2.c:1635
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1932
l_int32 lept_mkdir(const char *subdir)
lept_mkdir()
Definition: utils2.c:2218