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(). */
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  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 
153 PIXA *
155 {
156 char *str;
157 l_int32 i, n;
158 PIX *pix;
159 PIXA *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 
192 PIX *
193 pixRead(const char *filename)
194 {
195 FILE *fp;
196 PIX *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 
229 PIX *
230 pixReadWithHint(const char *filename,
231  l_int32 hint)
232 {
233 FILE *fp;
234 PIX *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 
280 PIX *
282  l_int32 index)
283 {
284 char *fname;
285 l_int32 n;
286 PIX *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 
321 PIX *
322 pixReadStream(FILE *fp,
323  l_int32 hint)
324 {
325 l_int32 format, ret, valid;
326 l_uint8 *comment;
327 PIX *pix;
328 PIXCMAP *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  *---------------------------------------------------------------------*/
445 l_ok
446 pixReadHeader(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 {
454 l_int32 format, ret, w, h, d, bps, spp, iscmap;
455 l_int32 type; /* ignored */
456 FILE *fp;
457 PIX *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  *---------------------------------------------------------------------*/
583 l_ok
584 findFileFormat(const char *filename,
585  l_int32 *pformat)
586 {
587 l_int32 ret;
588 FILE *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 
618 l_ok
620  l_int32 *pformat)
621 {
622 l_uint8 firstbytes[13];
623 l_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 
670 l_ok
671 findFileFormatBuffer(const l_uint8 *buf,
672  l_int32 *pformat)
673 {
674 l_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 
799 l_int32
801 {
802 l_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  *---------------------------------------------------------------------*/
843 PIX *
844 pixReadMem(const l_uint8 *data,
845  size_t size)
846 {
847 l_int32 format, valid;
848 PIX *pix;
849 PIXCMAP *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 
973 l_ok
974 pixReadHeaderMem(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 {
983 l_int32 format, ret, w, h, d, bps, spp, iscmap;
984 l_int32 type; /* not used */
985 PIX *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  *---------------------------------------------------------------------*/
1100 extern const char *ImageFileFormatExtensions[];
1101 
1120 l_ok
1121 writeImageFileInfo(const char *filename,
1122  FILE *fpout,
1123  l_int32 headeronly)
1124 {
1125 char *text;
1126 l_int32 w, h, d, wpl, count, npages, color;
1127 l_int32 format, bps, spp, iscmap, xres, yres, transparency;
1128 FILE *fpin;
1129 PIX *pix, *pixt;
1130 PIXCMAP *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  *---------------------------------------------------------------------*/
1288 l_ok
1289 ioFormatTest(const char *filename)
1290 {
1291 l_int32 w, h, d, depth, equal, problems;
1292 l_float32 diff;
1293 BOX *box;
1294 PIX *pixs, *pixc, *pix1, *pix2;
1295 PIXCMAP *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 * pixReadMemBmp(const l_uint8 *cdata, size_t size)
pixReadMemBmp()
Definition: bmpio.c:129
PIX * pixReadStreamBmp(FILE *fp)
pixReadStreamBmp()
Definition: bmpio.c:87
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
PIX * pixReadStreamJpeg(FILE *fp, l_int32 cmapflag, l_int32 reduction, l_int32 *pnwarn, l_int32 hint)
pixReadStreamJpeg()
Definition: jpegio.c:264
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
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
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
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
char * pixGetText(PIX *pix)
pixGetText()
Definition: pix1.c:1512
l_ok pixSetText(PIX *pix, const char *textstring)
pixSetText()
Definition: pix1.c:1536
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:593
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 * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
Definition: pixconv.c:328
PIX * pixConvertTo8(PIX *pixs, l_int32 cmapflag)
pixConvertTo8()
Definition: pixconv.c:3133
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
PIX * pixReadMemPng(const l_uint8 *filedata, size_t filesize)
pixReadMemPng()
Definition: pngio.c:1595
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
void l_pngSetReadStrip16To8(l_int32 flag)
l_pngSetReadStrip16To8()
Definition: pngio.c:1352
PIX * pixReadStreamPng(FILE *fp)
pixReadStreamPng()
Definition: pngio.c:187
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 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
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
PIXA * pixaReadFilesSA(SARRAY *sa)
pixaReadFilesSA()
Definition: readfile.c:154
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
l_ok findFileFormat(const char *filename, l_int32 *pformat)
findFileFormat()
Definition: readfile.c:584
PIX * pixReadWithHint(const char *filename, l_int32 hint)
pixReadWithHint()
Definition: readfile.c:230
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
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:671
PIX * pixReadMem(const l_uint8 *data, size_t size)
pixReadMem()
Definition: readfile.c:844
PIX * pixRead(const char *filename)
pixRead()
Definition: readfile.c:193
PIX * pixReadIndexed(SARRAY *sa, l_int32 index)
pixReadIndexed()
Definition: readfile.c:281
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
PIX * pixReadStream(FILE *fp, l_int32 hint)
pixReadStream()
Definition: readfile.c:322
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
SARRAY * getSortedPathnamesInDirectory(const char *dirname, const char *substr, l_int32 first, l_int32 nfiles)
getSortedPathnamesInDirectory()
Definition: sarray1.c:1848
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 readHeaderSpix(const char *filename, l_int32 *pwidth, l_int32 *pheight, l_int32 *pbps, l_int32 *pspp, l_int32 *piscmap)
readHeaderSpix()
Definition: spixio.c:130
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 * pixReadMemTiff(const l_uint8 *cdata, size_t size, l_int32 n)
pixReadMemTiff()
Definition: tiffio.c:2621
PIX * pixReadStreamTiff(FILE *fp, l_int32 n)
pixReadStreamTiff()
Definition: tiffio.c:420
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
size_t fnbytesInFile(FILE *fp)
fnbytesInFile()
Definition: utils2.c:1635
FILE * lept_fopen(const char *filename, const char *mode)
lept_fopen()
Definition: utils2.c:2113
l_int32 lept_mkdir(const char *subdir)
lept_mkdir()
Definition: utils2.c:2218
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1932