Leptonica  1.83.1
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(). */
82 static const char *FILE_BMP = "/tmp/lept/format/file.bmp";
83 static const char *FILE_PNG = "/tmp/lept/format/file.png";
84 static const char *FILE_PNM = "/tmp/lept/format/file.pnm";
85 static const char *FILE_G3 = "/tmp/lept/format/file_g3.tif";
86 static const char *FILE_G4 = "/tmp/lept/format/file_g4.tif";
87 static const char *FILE_RLE = "/tmp/lept/format/file_rle.tif";
88 static const char *FILE_PB = "/tmp/lept/format/file_packbits.tif";
89 static const char *FILE_LZW = "/tmp/lept/format/file_lzw.tif";
90 static const char *FILE_ZIP = "/tmp/lept/format/file_zip.tif";
91 static const char *FILE_TIFF_JPEG = "/tmp/lept/format/file_jpeg.tif";
92 static const char *FILE_TIFF = "/tmp/lept/format/file.tif";
93 static const char *FILE_JPG = "/tmp/lept/format/file.jpg";
94 static const char *FILE_GIF = "/tmp/lept/format/file.gif";
95 static const char *FILE_WEBP = "/tmp/lept/format/file.webp";
96 static 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 */
101 static const unsigned char JP2K_CODESTREAM[4] = { 0xff, 0x4f, 0xff, 0x51 };
102 static 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  *---------------------------------------------------------------------*/
126 PIXA *
127 pixaReadFiles(const char *dirname,
128  const char *substr)
129 {
130 PIXA *pixa;
131 SARRAY *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 
151 PIXA *
153 {
154 char *str;
155 l_int32 i, n;
156 PIX *pix;
157 PIXA *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 
188 PIX *
189 pixRead(const char *filename)
190 {
191 FILE *fp;
192 PIX *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 
223 PIX *
224 pixReadWithHint(const char *filename,
225  l_int32 hint)
226 {
227 FILE *fp;
228 PIX *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 
272 PIX *
274  l_int32 index)
275 {
276 char *fname;
277 l_int32 n;
278 PIX *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 
311 PIX *
312 pixReadStream(FILE *fp,
313  l_int32 hint)
314 {
315 l_int32 format, ret, valid;
316 l_uint8 *comment;
317 PIX *pix;
318 PIXCMAP *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  *---------------------------------------------------------------------*/
433 l_ok
434 pixReadHeader(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 {
442 l_int32 format, ret, w, h, d, bps, spp, iscmap;
443 l_int32 type; /* ignored */
444 FILE *fp;
445 PIX *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  *---------------------------------------------------------------------*/
569 l_ok
570 findFileFormat(const char *filename,
571  l_int32 *pformat)
572 {
573 l_int32 ret;
574 FILE *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 
602 l_ok
604  l_int32 *pformat)
605 {
606 l_uint8 firstbytes[13];
607 l_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 
652 l_ok
653 findFileFormatBuffer(const l_uint8 *buf,
654  l_int32 *pformat)
655 {
656 l_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 
779 l_int32
781 {
782 l_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  *---------------------------------------------------------------------*/
821 PIX *
822 pixReadMem(const l_uint8 *data,
823  size_t size)
824 {
825 l_int32 format, valid;
826 PIX *pix;
827 PIXCMAP *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 
949 l_ok
950 pixReadHeaderMem(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 {
959 l_int32 format, ret, w, h, d, bps, spp, iscmap;
960 l_int32 type; /* not used */
961 PIX *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  *---------------------------------------------------------------------*/
1074 extern const char *ImageFileFormatExtensions[];
1075 
1094 l_ok
1095 writeImageFileInfo(const char *filename,
1096  FILE *fpout,
1097  l_int32 headeronly)
1098 {
1099 char *text;
1100 l_int32 w, h, d, wpl, count, npages, color;
1101 l_int32 format, bps, spp, iscmap, xres, yres, transparency;
1102 FILE *fpin;
1103 PIX *pix, *pixt;
1104 PIXCMAP *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)
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  *---------------------------------------------------------------------*/
1260 l_ok
1261 ioFormatTest(const char *filename)
1262 {
1263 l_int32 w, h, d, depth, equal, problems;
1264 l_float32 diff;
1265 BOX *box;
1266 PIX *pixs, *pixc, *pix1, *pix2;
1267 PIXCMAP *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)
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)) {
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)
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 }
PIX * pixReadMemBmp(const l_uint8 *cdata, size_t size)
pixReadMemBmp()
Definition: bmpio.c:132
PIX * pixReadStreamBmp(FILE *fp)
pixReadStreamBmp()
Definition: bmpio.c:88
void boxDestroy(BOX **pbox)
boxDestroy()
Definition: boxbasic.c:273
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:171
void pixcmapDestroy(PIXCMAP **pcmap)
pixcmapDestroy()
Definition: colormap.c:272
l_ok pixcmapHasColor(PIXCMAP *cmap, l_int32 *pcolor)
pixcmapHasColor()
Definition: colormap.c:1026
l_ok pixcmapIsValid(const PIXCMAP *cmap, PIX *pix, l_int32 *pvalid)
pixcmapIsValid()
Definition: colormap.c:308
l_ok pixcmapWriteStream(FILE *fp, const PIXCMAP *cmap)
pixcmapWriteStream()
Definition: colormap.c:1882
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:973
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:866
@ 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:168
PIX * pixReadStreamJpeg(FILE *fp, l_int32 cmapflag, l_int32 reduction, l_int32 *pnwarn, l_int32 hint)
pixReadStreamJpeg()
Definition: jpegio.c:263
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:986
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:1031
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:506
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:608
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1074
char * pixGetText(PIX *pix)
pixGetText()
Definition: pix1.c:1408
l_ok pixSetText(PIX *pix, const char *textstring)
pixSetText()
Definition: pix1.c:1430
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:582
PIX * pixDisplayLayersRGBA(PIX *pixs, l_uint32 val, l_int32 maxw)
pixDisplayLayersRGBA()
Definition: pix2.c:2340
l_ok pixSetPadBits(PIX *pix, l_int32 val)
pixSetPadBits()
Definition: pix2.c:1346
l_ok pixCountPixels(PIX *pixs, l_int32 *pcount, l_int32 *tab8)
pixCountPixels()
Definition: pix3.c:1893
PIX * pixClipRectangle(PIX *pixs, BOX *box, BOX **pboxc)
pixClipRectangle()
Definition: pix5.c:994
@ REMOVE_CMAP_BASED_ON_SRC
Definition: pix.h:384
@ L_NOCOPY
Definition: pix.h:503
@ L_INSERT
Definition: pix.h:504
l_ok pixaAddPix(PIXA *pixa, PIX *pix, l_int32 copyflag)
pixaAddPix()
Definition: pixabasic.c:493
PIXA * pixaCreate(l_int32 n)
pixaCreate()
Definition: pixabasic.c:167
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
Definition: pixconv.c:324
PIX * pixConvertTo8(PIX *pixs, l_int32 cmapflag)
pixConvertTo8()
Definition: pixconv.c:3055
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3246
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:574
PIX * pixReadMemPng(const l_uint8 *filedata, size_t filesize)
pixReadMemPng()
Definition: pngio.c:1576
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:671
void l_pngSetReadStrip16To8(l_int32 flag)
l_pngSetReadStrip16To8()
Definition: pngio.c:1333
PIX * pixReadStreamPng(FILE *fp)
pixReadStreamPng()
Definition: pngio.c:188
PIX * pixReadMemPnm(const l_uint8 *data, size_t size)
pixReadMemPnm()
Definition: pnmio.c:1147
PIX * pixReadStreamPnm(FILE *fp)
pixReadStreamPnm()
Definition: pnmio.c:150
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:518
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:1178
PIXA * pixaReadFilesSA(SARRAY *sa)
pixaReadFilesSA()
Definition: readfile.c:152
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
l_ok findFileFormat(const char *filename, l_int32 *pformat)
findFileFormat()
Definition: readfile.c:570
PIX * pixReadWithHint(const char *filename, l_int32 hint)
pixReadWithHint()
Definition: readfile.c:224
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
PIXA * pixaReadFiles(const char *dirname, const char *substr)
pixaReadFiles()
Definition: readfile.c:127
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
PIX * pixRead(const char *filename)
pixRead()
Definition: readfile.c:189
PIX * pixReadIndexed(SARRAY *sa, l_int32 index)
pixReadIndexed()
Definition: readfile.c:273
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
PIX * pixReadStream(FILE *fp, l_int32 hint)
pixReadStream()
Definition: readfile.c:312
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
sarrayGetString()
Definition: sarray1.c:673
l_int32 sarrayGetCount(SARRAY *sa)
sarrayGetCount()
Definition: sarray1.c:617
void sarrayDestroy(SARRAY **psa)
sarrayDestroy()
Definition: sarray1.c:353
SARRAY * getSortedPathnamesInDirectory(const char *dirname, const char *substr, l_int32 first, l_int32 nfiles)
getSortedPathnamesInDirectory()
Definition: sarray1.c:1739
PIX * pixReadStreamSpix(FILE *fp)
pixReadStreamSpix()
Definition: spixio.c:92
PIX * pixReadMemSpix(const l_uint8 *data, size_t size)
pixReadMemSpix()
Definition: spixio.c:295
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:128
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:210
l_ok fprintTiffInfo(FILE *fpout, const char *tiffile)
fprintTiffInfo()
Definition: tiffio.c:1602
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:1777
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:1898
l_ok findTiffCompression(FILE *fp, l_int32 *pcomptype)
findTiffCompression()
Definition: tiffio.c:2025
PIX * pixReadMemTiff(const l_uint8 *cdata, size_t size, l_int32 n)
pixReadMemTiff()
Definition: tiffio.c:2599
PIX * pixReadStreamTiff(FILE *fp, l_int32 n)
pixReadStreamTiff()
Definition: tiffio.c:429
l_ok tiffGetCount(FILE *fp, l_int32 *pn)
tiffGetCount()
Definition: tiffio.c:1633
void lept_stderr(const char *fmt,...)
lept_stderr()
Definition: utils1.c:306
l_ok lept_fclose(FILE *fp)
lept_fclose()
Definition: utils2.c:2065
size_t fnbytesInFile(FILE *fp)
fnbytesInFile()
Definition: utils2.c:1581
FILE * lept_fopen(const char *filename, const char *mode)
lept_fopen()
Definition: utils2.c:2037
l_int32 lept_mkdir(const char *subdir)
lept_mkdir()
Definition: utils2.c:2138
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1864