comparison mupdf-source/thirdparty/leptonica/src/readfile.c @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
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
27 /*!
28 * \file readfile.c: reads image on file into memory
29 * <pre>
30 *
31 * Top-level functions for reading images from file
32 * PIXA *pixaReadFiles()
33 * PIXA *pixaReadFilesSA()
34 * PIX *pixRead()
35 * PIX *pixReadWithHint()
36 * PIX *pixReadIndexed()
37 * PIX *pixReadStream()
38 *
39 * Read header information from file
40 * l_int32 pixReadHeader()
41 *
42 * Format finders
43 * l_int32 findFileFormat()
44 * l_int32 findFileFormatStream()
45 * l_int32 findFileFormatBuffer()
46 * l_int32 fileFormatIsTiff()
47 *
48 * Read from memory
49 * PIX *pixReadMem()
50 * l_int32 pixReadHeaderMem()
51 *
52 * Output image file information
53 * void writeImageFileInfo()
54 *
55 * Test function for I/O with different formats
56 * l_int32 ioFormatTest()
57 *
58 * Supported file formats:
59 * (1) Reading is supported without any external libraries:
60 * bmp
61 * pnm (including pbm, pgm, etc)
62 * spix (raw serialized)
63 * (2) Reading is supported with installation of external libraries:
64 * png
65 * jpg (standard jfif version)
66 * tiff (including most varieties of compression)
67 * gif
68 * webp
69 * jp2 (jpeg 2000)
70 * (3) Other file types will get an "unknown format" error.
71 * </pre>
72 */
73
74 #ifdef HAVE_CONFIG_H
75 #include <config_auto.h>
76 #endif /* HAVE_CONFIG_H */
77
78 #include <string.h>
79 #include "allheaders.h"
80
81 /* Output files for ioFormatTest(). */
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 *---------------------------------------------------------------------*/
110 /*!
111 * \brief pixaReadFiles()
112 *
113 * \param[in] dirname
114 * \param[in] substr [optional] substring filter on filenames; can be null
115 * \return pixa, or NULL on error
116 *
117 * <pre>
118 * Notes:
119 * (1) %dirname is the full path for the directory.
120 * (2) %substr is the part of the file name (excluding
121 * the directory) that is to be matched. All matching
122 * filenames are read into the Pixa. If substr is NULL,
123 * all filenames are read into the Pixa.
124 * </pre>
125 */
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
145 /*!
146 * \brief pixaReadFilesSA()
147 *
148 * \param[in] sa full pathnames for all files
149 * \return pixa, or NULL on error
150 */
151 PIXA *
152 pixaReadFilesSA(SARRAY *sa)
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
177 /*!
178 * \brief pixRead()
179 *
180 * \param[in] filename with full pathname or in local directory
181 * \return pix if OK; NULL on error
182 *
183 * <pre>
184 * Notes:
185 * (1) See at top of file for supported formats.
186 * </pre>
187 */
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 return (PIX*)ERROR_PTR_1("image file not found",
199 filename, __func__, NULL);
200 pix = pixReadStream(fp, 0);
201 fclose(fp);
202 if (!pix)
203 return (PIX *)ERROR_PTR_1("pix not read", filename, __func__, NULL);
204 return pix;
205 }
206
207
208 /*!
209 * \brief pixReadWithHint()
210 *
211 * \param[in] filename with full pathname or in local directory
212 * \param[in] hint bitwise OR of L_HINT_* values for jpeg;
213 * use 0 for no hint
214 * \return pix if OK; NULL on error
215 *
216 * <pre>
217 * Notes:
218 * (1) The hint is not binding, but may be used to optimize jpeg decoding.
219 * Use 0 for no hinting.
220 * </pre>
221 */
222 PIX *
223 pixReadWithHint(const char *filename,
224 l_int32 hint)
225 {
226 FILE *fp;
227 PIX *pix;
228
229 if (!filename)
230 return (PIX *)ERROR_PTR("filename not defined", __func__, NULL);
231
232 if ((fp = fopenReadStream(filename)) == NULL)
233 return (PIX *)ERROR_PTR_1("image file not found",
234 filename, __func__, NULL);
235 pix = pixReadStream(fp, hint);
236 fclose(fp);
237
238 if (!pix)
239 return (PIX *)ERROR_PTR_1("image not returned",
240 filename, __func__, NULL);
241 return pix;
242 }
243
244
245 /*!
246 * \brief pixReadIndexed()
247 *
248 * \param[in] sa string array of full pathnames
249 * \param[in] index into pathname array
250 * \return pix if OK; null if not found
251 *
252 * <pre>
253 * Notes:
254 * (1) This function is useful for selecting image files from a
255 * directory, where the integer %index is embedded into
256 * the file name.
257 * (2) This is typically done by generating the sarray using
258 * getNumberedPathnamesInDirectory(), so that the %index
259 * pathname would have the number %index in it. The size
260 * of the sarray should be the largest number (plus 1) appearing
261 * in the file names, respecting the constraints in the
262 * call to getNumberedPathnamesInDirectory().
263 * (3) Consequently, for some indices into the sarray, there may
264 * be no pathnames in the directory containing that number.
265 * By convention, we place empty C strings ("") in those
266 * locations in the sarray, and it is not an error if such
267 * a string is encountered and no pix is returned.
268 * Therefore, the caller must verify that a pix is returned.
269 * (4) See convertSegmentedPagesToPS() in src/psio1.c for an
270 * example of usage.
271 * </pre>
272 */
273 PIX *
274 pixReadIndexed(SARRAY *sa,
275 l_int32 index)
276 {
277 char *fname;
278 l_int32 n;
279 PIX *pix;
280
281 if (!sa)
282 return (PIX *)ERROR_PTR("sa not defined", __func__, NULL);
283 n = sarrayGetCount(sa);
284 if (index < 0 || index >= n)
285 return (PIX *)ERROR_PTR("index out of bounds", __func__, NULL);
286
287 fname = sarrayGetString(sa, index, L_NOCOPY);
288 if (fname[0] == '\0')
289 return NULL;
290
291 if ((pix = pixRead(fname)) == NULL) {
292 L_ERROR("pix not read from file %s\n", __func__, fname);
293 return NULL;
294 }
295
296 return pix;
297 }
298
299
300 /*!
301 * \brief pixReadStream()
302 *
303 * \param[in] fp file stream
304 * \param[in] hint bitwise OR of L_HINT_* values for jpeg; 0 for no hint
305 * \return pix if OK; NULL on error
306 *
307 * <pre>
308 * Notes:
309 * (1) The hint only applies to jpeg.
310 * </pre>
311 */
312 PIX *
313 pixReadStream(FILE *fp,
314 l_int32 hint)
315 {
316 l_int32 format, ret, valid;
317 l_uint8 *comment;
318 PIX *pix;
319 PIXCMAP *cmap;
320
321 if (!fp)
322 return (PIX *)ERROR_PTR("stream not defined", __func__, NULL);
323 pix = NULL;
324
325 findFileFormatStream(fp, &format);
326 switch (format)
327 {
328 case IFF_BMP:
329 if ((pix = pixReadStreamBmp(fp)) == NULL )
330 return (PIX *)ERROR_PTR( "bmp: no pix returned", __func__, NULL);
331 break;
332
333 case IFF_JFIF_JPEG:
334 if ((pix = pixReadStreamJpeg(fp, 0, 1, NULL, hint)) == NULL)
335 return (PIX *)ERROR_PTR( "jpeg: no pix returned", __func__, NULL);
336 ret = fgetJpegComment(fp, &comment);
337 if (!ret && comment)
338 pixSetText(pix, (char *)comment);
339 LEPT_FREE(comment);
340 break;
341
342 case IFF_PNG:
343 if ((pix = pixReadStreamPng(fp)) == NULL)
344 return (PIX *)ERROR_PTR("png: no pix returned", __func__, NULL);
345 break;
346
347 case IFF_TIFF:
348 case IFF_TIFF_PACKBITS:
349 case IFF_TIFF_RLE:
350 case IFF_TIFF_G3:
351 case IFF_TIFF_G4:
352 case IFF_TIFF_LZW:
353 case IFF_TIFF_ZIP:
354 case IFF_TIFF_JPEG:
355 if ((pix = pixReadStreamTiff(fp, 0)) == NULL) /* page 0 by default */
356 return (PIX *)ERROR_PTR("tiff: no pix returned", __func__, NULL);
357 break;
358
359 case IFF_PNM:
360 if ((pix = pixReadStreamPnm(fp)) == NULL)
361 return (PIX *)ERROR_PTR("pnm: no pix returned", __func__, NULL);
362 break;
363
364 case IFF_GIF:
365 if ((pix = pixReadStreamGif(fp)) == NULL)
366 return (PIX *)ERROR_PTR("gif: no pix returned", __func__, NULL);
367 break;
368
369 case IFF_JP2:
370 if ((pix = pixReadStreamJp2k(fp, 1, NULL, 0, 0)) == NULL)
371 return (PIX *)ERROR_PTR("jp2: no pix returned", __func__, NULL);
372 break;
373
374 case IFF_WEBP:
375 if ((pix = pixReadStreamWebP(fp)) == NULL)
376 return (PIX *)ERROR_PTR("webp: no pix returned", __func__, NULL);
377 break;
378
379 case IFF_PS:
380 L_ERROR("PostScript reading is not supported\n", __func__);
381 return NULL;
382
383 case IFF_LPDF:
384 L_ERROR("Pdf reading is not supported\n", __func__);
385 return NULL;
386
387 case IFF_SPIX:
388 if ((pix = pixReadStreamSpix(fp)) == NULL)
389 return (PIX *)ERROR_PTR("spix: no pix returned", __func__, NULL);
390 break;
391
392 case IFF_UNKNOWN:
393 return (PIX *)ERROR_PTR( "Unknown format: no pix returned",
394 __func__, NULL);
395 break;
396 }
397
398 if (pix) {
399 pixSetInputFormat(pix, format);
400 if ((cmap = pixGetColormap(pix))) {
401 pixcmapIsValid(cmap, pix, &valid);
402 if (!valid) {
403 pixDestroy(&pix);
404 return (PIX *)ERROR_PTR("invalid colormap", __func__, NULL);
405 }
406 }
407 }
408 return pix;
409 }
410
411
412
413 /*---------------------------------------------------------------------*
414 * Read header information from file *
415 *---------------------------------------------------------------------*/
416 /*!
417 * \brief pixReadHeader()
418 *
419 * \param[in] filename with full pathname or in local directory
420 * \param[out] pformat [optional] file format
421 * \param[out] pw, ph [optional] width and height
422 * \param[out] pbps [optional] bits/sample
423 * \param[out] pspp [optional] samples/pixel 1, 3 or 4
424 * \param[out] piscmap [optional] 1 if cmap exists; 0 otherwise
425 * \return 0 if OK, 1 on error
426 *
427 * <pre>
428 * Notes:
429 * (1) This reads the actual headers for jpeg, png, tiff and pnm.
430 * For bmp and gif, we cheat and read the entire file into a pix,
431 * from which we extract the "header" information.
432 * </pre>
433 */
434 l_ok
435 pixReadHeader(const char *filename,
436 l_int32 *pformat,
437 l_int32 *pw,
438 l_int32 *ph,
439 l_int32 *pbps,
440 l_int32 *pspp,
441 l_int32 *piscmap)
442 {
443 l_int32 format, ret, w, h, d, bps, spp, iscmap;
444 l_int32 type; /* ignored */
445 FILE *fp;
446 PIX *pix;
447
448 if (pw) *pw = 0;
449 if (ph) *ph = 0;
450 if (pbps) *pbps = 0;
451 if (pspp) *pspp = 0;
452 if (piscmap) *piscmap = 0;
453 if (pformat) *pformat = 0;
454 iscmap = 0; /* init to false */
455 if (!filename)
456 return ERROR_INT("filename not defined", __func__, 1);
457
458 if ((fp = fopenReadStream(filename)) == NULL)
459 return ERROR_INT_1("image file not found", filename, __func__, 1);
460 findFileFormatStream(fp, &format);
461 fclose(fp);
462
463 switch (format)
464 {
465 case IFF_BMP: /* cheating: reading the entire file */
466 if ((pix = pixRead(filename)) == NULL)
467 return ERROR_INT_1( "bmp: pix not read", filename, __func__, 1);
468 pixGetDimensions(pix, &w, &h, &d);
469 bps = (d == 32) ? 8 : d;
470 spp = pixGetSpp(pix);
471 iscmap = (pixGetColormap(pix)) ? 1 : 0;
472 pixDestroy(&pix);
473 break;
474
475 case IFF_JFIF_JPEG:
476 ret = readHeaderJpeg(filename, &w, &h, &spp, NULL, NULL);
477 bps = 8;
478 if (ret)
479 return ERROR_INT_1("jpeg: no header info returned",
480 filename, __func__, 1);
481 break;
482
483 case IFF_PNG:
484 ret = readHeaderPng(filename, &w, &h, &bps, &spp, &iscmap);
485 if (ret)
486 return ERROR_INT_1("png: no header info returned",
487 filename, __func__, 1);
488 break;
489
490 case IFF_TIFF:
491 case IFF_TIFF_PACKBITS:
492 case IFF_TIFF_RLE:
493 case IFF_TIFF_G3:
494 case IFF_TIFF_G4:
495 case IFF_TIFF_LZW:
496 case IFF_TIFF_ZIP:
497 case IFF_TIFF_JPEG:
498 /* Reading page 0 by default; possibly redefine format */
499 ret = readHeaderTiff(filename, 0, &w, &h, &bps, &spp, NULL, &iscmap,
500 &format);
501 if (ret)
502 return ERROR_INT_1("tiff: no header info returned",
503 filename, __func__, 1);
504 break;
505
506 case IFF_PNM:
507 ret = readHeaderPnm(filename, &w, &h, &d, &type, &bps, &spp);
508 if (ret)
509 return ERROR_INT_1("pnm: no header info returned",
510 filename, __func__, 1);
511 break;
512
513 case IFF_GIF: /* cheating: reading the entire file */
514 if ((pix = pixRead(filename)) == NULL)
515 return ERROR_INT_1( "gif: pix not read", filename, __func__, 1);
516 pixGetDimensions(pix, &w, &h, &d);
517 pixDestroy(&pix);
518 iscmap = 1; /* always colormapped; max 256 colors */
519 spp = 1;
520 bps = d;
521 break;
522
523 case IFF_JP2:
524 ret = readHeaderJp2k(filename, &w, &h, &bps, &spp, NULL);
525 break;
526
527 case IFF_WEBP:
528 if (readHeaderWebP(filename, &w, &h, &spp))
529 return ERROR_INT_1("webp: no header info returned",
530 filename, __func__, 1);
531 bps = 8;
532 break;
533
534 case IFF_PS:
535 if (pformat) *pformat = format;
536 return ERROR_INT("PostScript reading is not supported\n", __func__, 1);
537
538 case IFF_LPDF:
539 if (pformat) *pformat = format;
540 return ERROR_INT("Pdf reading is not supported\n", __func__, 1);
541
542 case IFF_SPIX:
543 ret = readHeaderSpix(filename, &w, &h, &bps, &spp, &iscmap);
544 if (ret)
545 return ERROR_INT_1("spix: no header info returned",
546 filename, __func__, 1);
547 break;
548
549 case IFF_UNKNOWN:
550 return ERROR_INT_1("unknown format in file", filename, __func__, 1);
551 }
552
553 if (pw) *pw = w;
554 if (ph) *ph = h;
555 if (pbps) *pbps = bps;
556 if (pspp) *pspp = spp;
557 if (piscmap) *piscmap = iscmap;
558 if (pformat) *pformat = format;
559 return 0;
560 }
561
562
563 /*---------------------------------------------------------------------*
564 * Format finders *
565 *---------------------------------------------------------------------*/
566 /*!
567 * \brief findFileFormat()
568 *
569 * \param[in] filename
570 * \param[out] pformat found format
571 * \return 0 if OK, 1 on error or if format is not recognized
572 */
573 l_ok
574 findFileFormat(const char *filename,
575 l_int32 *pformat)
576 {
577 l_int32 ret;
578 FILE *fp;
579
580 if (!pformat)
581 return ERROR_INT("&format not defined", __func__, 1);
582 *pformat = IFF_UNKNOWN;
583 if (!filename)
584 return ERROR_INT("filename not defined", __func__, 1);
585
586 if ((fp = fopenReadStream(filename)) == NULL)
587 return ERROR_INT_1("image file not found", filename, __func__, 1);
588 ret = findFileFormatStream(fp, pformat);
589 fclose(fp);
590 return ret;
591 }
592
593
594 /*!
595 * \brief findFileFormatStream()
596 *
597 * \param[in] fp file stream
598 * \param[out] pformat found format
599 * \return 0 if OK, 1 on error or if format is not recognized
600 *
601 * <pre>
602 * Notes:
603 * (1) Important: Side effect -- this resets fp to BOF.
604 * </pre>
605 */
606 l_ok
607 findFileFormatStream(FILE *fp,
608 l_int32 *pformat)
609 {
610 l_uint8 firstbytes[13];
611 l_int32 format;
612
613 if (!pformat)
614 return ERROR_INT("&format not defined", __func__, 1);
615 *pformat = IFF_UNKNOWN;
616 if (!fp)
617 return ERROR_INT("stream not defined", __func__, 1);
618
619 rewind(fp);
620 if (fnbytesInFile(fp) < 12)
621 return ERROR_INT("truncated file", __func__, 1);
622
623 if (fread(&firstbytes, 1, 12, fp) != 12)
624 return ERROR_INT("failed to read first 12 bytes of file", __func__, 1);
625 firstbytes[12] = 0;
626 rewind(fp);
627
628 findFileFormatBuffer(firstbytes, &format);
629 if (format == IFF_TIFF) {
630 findTiffCompression(fp, &format);
631 rewind(fp);
632 }
633 *pformat = format;
634 if (format == IFF_UNKNOWN)
635 return 1;
636 else
637 return 0;
638 }
639
640
641 /*!
642 * \brief findFileFormatBuffer()
643 *
644 * \param[in] buf byte buffer at least 12 bytes in size; we can't check
645 * \param[out] pformat found format
646 * \return 0 if OK, 1 on error or if format is not recognized
647 *
648 * <pre>
649 * Notes:
650 * (1) This determines the file format from the first 12 bytes in
651 * the compressed data stream, which are stored in memory.
652 * (2) For tiff files, this returns IFF_TIFF. The specific tiff
653 * compression is then determined using findTiffCompression().
654 * </pre>
655 */
656 l_ok
657 findFileFormatBuffer(const l_uint8 *buf,
658 l_int32 *pformat)
659 {
660 l_uint16 twobytepw;
661
662 if (!pformat)
663 return ERROR_INT("&format not defined", __func__, 1);
664 *pformat = IFF_UNKNOWN;
665 if (!buf)
666 return ERROR_INT("byte buffer not defined", __func__, 0);
667
668 /* Check the bmp and tiff 2-byte header ids */
669 ((char *)(&twobytepw))[0] = buf[0];
670 ((char *)(&twobytepw))[1] = buf[1];
671
672 if (convertOnBigEnd16(twobytepw) == BMP_ID) {
673 *pformat = IFF_BMP;
674 return 0;
675 }
676
677 if (twobytepw == TIFF_BIGEND_ID || twobytepw == TIFF_LITTLEEND_ID) {
678 *pformat = IFF_TIFF;
679 return 0;
680 }
681
682 /* Check for the p*m 2-byte header ids */
683 if ((buf[0] == 'P' && buf[1] == '4') || /* newer packed */
684 (buf[0] == 'P' && buf[1] == '1')) { /* old ASCII format */
685 *pformat = IFF_PNM;
686 return 0;
687 }
688
689 if ((buf[0] == 'P' && buf[1] == '5') || /* newer */
690 (buf[0] == 'P' && buf[1] == '2')) { /* old */
691 *pformat = IFF_PNM;
692 return 0;
693 }
694
695 if ((buf[0] == 'P' && buf[1] == '6') || /* newer */
696 (buf[0] == 'P' && buf[1] == '3')) { /* old */
697 *pformat = IFF_PNM;
698 return 0;
699 }
700
701 if (buf[0] == 'P' && buf[1] == '7') { /* new arbitrary (PAM) */
702 *pformat = IFF_PNM;
703 return 0;
704 }
705
706 /* Consider the first 11 bytes of the standard JFIF JPEG header:
707 * - The first two bytes are the most important: 0xffd8.
708 * - The next two bytes are the jfif marker: 0xffe0.
709 * Not all jpeg files have this marker.
710 * - The next two bytes are the header length.
711 * - The next 5 bytes are a null-terminated string.
712 * For JFIF, the string is "JFIF", naturally. For others it
713 * can be "Exif" or just about anything else.
714 * - Because of all this variability, we only check the first
715 * two byte marker. All jpeg files are identified as
716 * IFF_JFIF_JPEG. */
717 if (buf[0] == 0xff && buf[1] == 0xd8) {
718 *pformat = IFF_JFIF_JPEG;
719 return 0;
720 }
721
722 /* Check for the 8 byte PNG signature (png_signature in png.c):
723 * {137, 80, 78, 71, 13, 10, 26, 10} */
724 if (buf[0] == 137 && buf[1] == 80 && buf[2] == 78 && buf[3] == 71 &&
725 buf[4] == 13 && buf[5] == 10 && buf[6] == 26 && buf[7] == 10) {
726 *pformat = IFF_PNG;
727 return 0;
728 }
729
730 /* Look for "GIF87a" or "GIF89a" */
731 if (buf[0] == 'G' && buf[1] == 'I' && buf[2] == 'F' && buf[3] == '8' &&
732 (buf[4] == '7' || buf[4] == '9') && buf[5] == 'a') {
733 *pformat = IFF_GIF;
734 return 0;
735 }
736
737 /* Check for both types of jp2k file */
738 if (memcmp(buf, JP2K_CODESTREAM, 4) == 0 ||
739 memcmp(buf, JP2K_IMAGE_DATA, 12) == 0) {
740 *pformat = IFF_JP2;
741 return 0;
742 }
743
744 /* Check for webp */
745 if (buf[0] == 'R' && buf[1] == 'I' && buf[2] == 'F' && buf[3] == 'F' &&
746 buf[8] == 'W' && buf[9] == 'E' && buf[10] == 'B' && buf[11] == 'P') {
747 *pformat = IFF_WEBP;
748 return 0;
749 }
750
751 /* Check for ps */
752 if (buf[0] == '%' && buf[1] == '!' && buf[2] == 'P' && buf[3] == 'S' &&
753 buf[4] == '-' && buf[5] == 'A' && buf[6] == 'd' && buf[7] == 'o' &&
754 buf[8] == 'b' && buf[9] == 'e') {
755 *pformat = IFF_PS;
756 return 0;
757 }
758
759 /* Check for pdf */
760 if (buf[0] == '%' && buf[1] == 'P' && buf[2] == 'D' && buf[3] == 'F' &&
761 buf[4] == '-' && buf[5] == '1') {
762 *pformat = IFF_LPDF;
763 return 0;
764 }
765
766 /* Check for "spix" serialized pix */
767 if (buf[0] == 's' && buf[1] == 'p' && buf[2] == 'i' && buf[3] == 'x') {
768 *pformat = IFF_SPIX;
769 return 0;
770 }
771
772 /* File format identifier not found; unknown */
773 return 1;
774 }
775
776
777 /*!
778 * \brief fileFormatIsTiff()
779 *
780 * \param[in] fp file stream
781 * \return 1 if file is tiff; 0 otherwise or on error
782 */
783 l_int32
784 fileFormatIsTiff(FILE *fp)
785 {
786 l_int32 format;
787
788 if (!fp)
789 return ERROR_INT("stream not defined", __func__, 0);
790
791 findFileFormatStream(fp, &format);
792 if (format == IFF_TIFF || format == IFF_TIFF_PACKBITS ||
793 format == IFF_TIFF_RLE || format == IFF_TIFF_G3 ||
794 format == IFF_TIFF_G4 || format == IFF_TIFF_LZW ||
795 format == IFF_TIFF_ZIP || format == IFF_TIFF_JPEG)
796 return 1;
797 else
798 return 0;
799 }
800
801
802 /*---------------------------------------------------------------------*
803 * Read from memory *
804 *---------------------------------------------------------------------*/
805 /*!
806 * \brief pixReadMem()
807 *
808 * \param[in] data const; encoded
809 * \param[in] size size of data
810 * \return pix, or NULL on error
811 *
812 * <pre>
813 * Notes:
814 * (1) This is a variation of pixReadStream(), where the data is read
815 * from a memory buffer rather than a file.
816 * (2) On Windows, this only reads tiff formatted files directly from
817 * memory. For other formats, it writes to a temp file and
818 * decompresses from file.
819 * (3) findFileFormatBuffer() requires up to 12 bytes to decide on
820 * the format. That determines the constraint here. But in
821 * fact the data must contain the entire compressed string for
822 * the image.
823 * </pre>
824 */
825 PIX *
826 pixReadMem(const l_uint8 *data,
827 size_t size)
828 {
829 l_int32 format, valid;
830 PIX *pix;
831 PIXCMAP *cmap;
832
833 if (!data)
834 return (PIX *)ERROR_PTR("data not defined", __func__, NULL);
835 if (size < 12)
836 return (PIX *)ERROR_PTR("size < 12", __func__, NULL);
837 pix = NULL;
838
839 findFileFormatBuffer(data, &format);
840 switch (format)
841 {
842 case IFF_BMP:
843 if ((pix = pixReadMemBmp(data, size)) == NULL )
844 return (PIX *)ERROR_PTR( "bmp: no pix returned", __func__, NULL);
845 break;
846
847 case IFF_JFIF_JPEG:
848 if ((pix = pixReadMemJpeg(data, size, 0, 1, NULL, 0)) == NULL)
849 return (PIX *)ERROR_PTR( "jpeg: no pix returned", __func__, NULL);
850 break;
851
852 case IFF_PNG:
853 if ((pix = pixReadMemPng(data, size)) == NULL)
854 return (PIX *)ERROR_PTR("png: no pix returned", __func__, NULL);
855 break;
856
857 case IFF_TIFF:
858 case IFF_TIFF_PACKBITS:
859 case IFF_TIFF_RLE:
860 case IFF_TIFF_G3:
861 case IFF_TIFF_G4:
862 case IFF_TIFF_LZW:
863 case IFF_TIFF_ZIP:
864 /* Reading page 0 by default */
865 if ((pix = pixReadMemTiff(data, size, 0)) == NULL)
866 return (PIX *)ERROR_PTR("tiff: no pix returned", __func__, NULL);
867 break;
868
869 case IFF_PNM:
870 if ((pix = pixReadMemPnm(data, size)) == NULL)
871 return (PIX *)ERROR_PTR("pnm: no pix returned", __func__, NULL);
872 break;
873
874 case IFF_GIF:
875 if ((pix = pixReadMemGif(data, size)) == NULL)
876 return (PIX *)ERROR_PTR("gif: no pix returned", __func__, NULL);
877 break;
878
879 case IFF_JP2:
880 if ((pix = pixReadMemJp2k(data, size, 1, NULL, 0, 0)) == NULL)
881 return (PIX *)ERROR_PTR("jp2k: no pix returned", __func__, NULL);
882 break;
883
884 case IFF_WEBP:
885 if ((pix = pixReadMemWebP(data, size)) == NULL)
886 return (PIX *)ERROR_PTR("webp: no pix returned", __func__, NULL);
887 break;
888
889 case IFF_PS:
890 L_ERROR("PostScript reading is not supported\n", __func__);
891 return NULL;
892
893 case IFF_LPDF:
894 L_ERROR("Pdf reading is not supported\n", __func__);
895 return NULL;
896
897 case IFF_SPIX:
898 if ((pix = pixReadMemSpix(data, size)) == NULL)
899 return (PIX *)ERROR_PTR("spix: no pix returned", __func__, NULL);
900 break;
901
902 case IFF_UNKNOWN:
903 return (PIX *)ERROR_PTR("Unknown format: no pix returned",
904 __func__, NULL);
905 break;
906 }
907
908 /* Set the input format. For tiff reading from memory we lose
909 * the actual input format; for 1 bpp, default to G4. Also
910 * verify that the colormap is valid. */
911 if (pix) {
912 if (format == IFF_TIFF && pixGetDepth(pix) == 1)
913 format = IFF_TIFF_G4;
914 pixSetInputFormat(pix, format);
915 if ((cmap = pixGetColormap(pix))) {
916 pixcmapIsValid(cmap, pix, &valid);
917 if (!valid) {
918 pixDestroy(&pix);
919 return (PIX *)ERROR_PTR("invalid colormap", __func__, NULL);
920 }
921 }
922 pixSetPadBits(pix, 0);
923 }
924 return pix;
925 }
926
927
928 /*!
929 * \brief pixReadHeaderMem()
930 *
931 * \param[in] data const; encoded
932 * \param[in] size size of data
933 * \param[out] pformat [optional] image format
934 * \param[out] pw, ph [optional] width and height
935 * \param[out] pbps [optional] bits/sample
936 * \param[out] pspp [optional] samples/pixel 1, 3 or 4
937 * \param[out] piscmap [optional] 1 if cmap exists; 0 otherwise
938 * \return 0 if OK, 1 on error
939 *
940 * <pre>
941 * Notes:
942 * (1) This reads the actual headers for jpeg, png, tiff, jp2k and pnm.
943 * For bmp and gif, we cheat and read all the data into a pix,
944 * from which we extract the "header" information.
945 * (2) The amount of data required depends on the format. For
946 * png, it requires less than 30 bytes, but for jpeg it can
947 * require most of the compressed file. In practice, the data
948 * is typically the entire compressed file in memory.
949 * (3) findFileFormatBuffer() requires up to 12 bytes to decide on
950 * the format, which we require.
951 * </pre>
952 */
953 l_ok
954 pixReadHeaderMem(const l_uint8 *data,
955 size_t size,
956 l_int32 *pformat,
957 l_int32 *pw,
958 l_int32 *ph,
959 l_int32 *pbps,
960 l_int32 *pspp,
961 l_int32 *piscmap)
962 {
963 l_int32 format, ret, w, h, d, bps, spp, iscmap;
964 l_int32 type; /* not used */
965 PIX *pix;
966
967 if (pw) *pw = 0;
968 if (ph) *ph = 0;
969 if (pbps) *pbps = 0;
970 if (pspp) *pspp = 0;
971 if (piscmap) *piscmap = 0;
972 if (pformat) *pformat = 0;
973 iscmap = 0; /* init to false */
974 if (!data)
975 return ERROR_INT("data not defined", __func__, 1);
976 if (size < 12)
977 return ERROR_INT("size < 12", __func__, 1);
978
979 findFileFormatBuffer(data, &format);
980
981 switch (format)
982 {
983 case IFF_BMP: /* cheating: read the pix */
984 if ((pix = pixReadMemBmp(data, size)) == NULL)
985 return ERROR_INT( "bmp: pix not read", __func__, 1);
986 pixGetDimensions(pix, &w, &h, &d);
987 pixDestroy(&pix);
988 bps = (d == 32) ? 8 : d;
989 spp = (d == 32) ? 3 : 1;
990 break;
991
992 case IFF_JFIF_JPEG:
993 ret = readHeaderMemJpeg(data, size, &w, &h, &spp, NULL, NULL);
994 bps = 8;
995 if (ret)
996 return ERROR_INT( "jpeg: no header info returned", __func__, 1);
997 break;
998
999 case IFF_PNG:
1000 ret = readHeaderMemPng(data, size, &w, &h, &bps, &spp, &iscmap);
1001 if (ret)
1002 return ERROR_INT( "png: no header info returned", __func__, 1);
1003 break;
1004
1005 case IFF_TIFF:
1006 case IFF_TIFF_PACKBITS:
1007 case IFF_TIFF_RLE:
1008 case IFF_TIFF_G3:
1009 case IFF_TIFF_G4:
1010 case IFF_TIFF_LZW:
1011 case IFF_TIFF_ZIP:
1012 case IFF_TIFF_JPEG:
1013 /* Reading page 0 by default; possibly redefine format */
1014 ret = readHeaderMemTiff(data, size, 0, &w, &h, &bps, &spp,
1015 NULL, &iscmap, &format);
1016 if (ret)
1017 return ERROR_INT( "tiff: no header info returned", __func__, 1);
1018 break;
1019
1020 case IFF_PNM:
1021 ret = readHeaderMemPnm(data, size, &w, &h, &d, &type, &bps, &spp);
1022 if (ret)
1023 return ERROR_INT( "pnm: no header info returned", __func__, 1);
1024 break;
1025
1026 case IFF_GIF: /* cheating: read the pix */
1027 if ((pix = pixReadMemGif(data, size)) == NULL)
1028 return ERROR_INT( "gif: pix not read", __func__, 1);
1029 pixGetDimensions(pix, &w, &h, &d);
1030 pixDestroy(&pix);
1031 iscmap = 1; /* always colormapped; max 256 colors */
1032 spp = 1;
1033 bps = d;
1034 break;
1035
1036 case IFF_JP2:
1037 ret = readHeaderMemJp2k(data, size, &w, &h, &bps, &spp, NULL);
1038 break;
1039
1040 case IFF_WEBP:
1041 bps = 8;
1042 ret = readHeaderMemWebP(data, size, &w, &h, &spp);
1043 break;
1044
1045 case IFF_PS:
1046 if (pformat) *pformat = format;
1047 return ERROR_INT("PostScript reading is not supported\n", __func__, 1);
1048
1049 case IFF_LPDF:
1050 if (pformat) *pformat = format;
1051 return ERROR_INT("Pdf reading is not supported\n", __func__, 1);
1052
1053 case IFF_SPIX:
1054 ret = sreadHeaderSpix((l_uint32 *)data, size, &w, &h, &bps,
1055 &spp, &iscmap);
1056 if (ret)
1057 return ERROR_INT( "pnm: no header info returned", __func__, 1);
1058 break;
1059
1060 case IFF_UNKNOWN:
1061 return ERROR_INT("unknown format; no data returned", __func__, 1);
1062 break;
1063 }
1064
1065 if (pw) *pw = w;
1066 if (ph) *ph = h;
1067 if (pbps) *pbps = bps;
1068 if (pspp) *pspp = spp;
1069 if (piscmap) *piscmap = iscmap;
1070 if (pformat) *pformat = format;
1071 return 0;
1072 }
1073
1074
1075 /*---------------------------------------------------------------------*
1076 * Output image file information *
1077 *---------------------------------------------------------------------*/
1078 extern const char *ImageFileFormatExtensions[];
1079
1080 /*!
1081 * \brief writeImageFileInfo()
1082 *
1083 * \param[in] filename input file
1084 * \param[in] fpout output file stream
1085 * \param[in] headeronly 1 to read only the header; 0 to read both
1086 * the header and the input file
1087 * \return 0 if OK; 1 on error
1088 *
1089 * <pre>
1090 * Notes:
1091 * (1) If headeronly == 0 and the image has spp == 4,this will
1092 * also call pixDisplayLayersRGBA() to display the image
1093 * in three views.
1094 * (2) This is a debug function that changes the value of
1095 * var_PNG_STRIP_16_TO_8 to 1 (the default).
1096 * </pre>
1097 */
1098 l_ok
1099 writeImageFileInfo(const char *filename,
1100 FILE *fpout,
1101 l_int32 headeronly)
1102 {
1103 char *text;
1104 l_int32 w, h, d, wpl, count, npages, color;
1105 l_int32 format, bps, spp, iscmap, xres, yres, transparency;
1106 FILE *fpin;
1107 PIX *pix, *pixt;
1108 PIXCMAP *cmap;
1109
1110 if (!filename)
1111 return ERROR_INT("filename not defined", __func__, 1);
1112 if (!fpout)
1113 return ERROR_INT("stream not defined", __func__, 1);
1114
1115 /* Read the header */
1116 if (pixReadHeader(filename, &format, &w, &h, &bps, &spp, &iscmap)) {
1117 L_ERROR("failure to read header of %s\n", __func__, filename);
1118 return 1;
1119 }
1120 fprintf(fpout, "===============================================\n"
1121 "Reading the header:\n");
1122 fprintf(fpout, " input image format type: %s\n",
1123 ImageFileFormatExtensions[format]);
1124 fprintf(fpout, " w = %d, h = %d, bps = %d, spp = %d, iscmap = %d\n",
1125 w, h, bps, spp, iscmap);
1126
1127 findFileFormat(filename, &format);
1128 if (format == IFF_JP2) {
1129 fpin = fopenReadStream(filename);
1130 fgetJp2kResolution(fpin, &xres, &yres);
1131 if (fpin) fclose(fpin);
1132 fprintf(fpout, " xres = %d, yres = %d\n", xres, yres);
1133 } else if (format == IFF_PNG) {
1134 fpin = fopenReadStream(filename);
1135 fgetPngResolution(fpin, &xres, &yres);
1136 if (fpin) fclose(fpin);
1137 fprintf(fpout, " xres = %d, yres = %d\n", xres, yres);
1138 if (iscmap) {
1139 fpin = fopenReadStream(filename);
1140 fgetPngColormapInfo(fpin, &cmap, &transparency);
1141 if (fpin) fclose(fpin);
1142 if (transparency)
1143 fprintf(fpout, " colormap has transparency\n");
1144 else
1145 fprintf(fpout, " colormap does not have transparency\n");
1146 pixcmapWriteStream(fpout, cmap);
1147 pixcmapDestroy(&cmap);
1148 }
1149 } else if (format == IFF_JFIF_JPEG) {
1150 fpin = fopenReadStream(filename);
1151 fgetJpegResolution(fpin, &xres, &yres);
1152 if (fpin) fclose(fpin);
1153 fprintf(fpout, " xres = %d, yres = %d\n", xres, yres);
1154 }
1155
1156 if (headeronly)
1157 return 0;
1158
1159 /* Read the full image. Note that when we read an image that
1160 * has transparency in a colormap, we convert it to RGBA. */
1161 fprintf(fpout, "===============================================\n"
1162 "Reading the full image:\n");
1163
1164 /* Preserve 16 bpp if the format is png */
1165 if (format == IFF_PNG && bps == 16)
1166 l_pngSetReadStrip16To8(0);
1167
1168 if ((pix = pixRead(filename)) == NULL) {
1169 L_ERROR("failure to read full image of %s\n", __func__, filename);
1170 return 1;
1171 }
1172
1173 format = pixGetInputFormat(pix);
1174 pixGetDimensions(pix, &w, &h, &d);
1175 wpl = pixGetWpl(pix);
1176 spp = pixGetSpp(pix);
1177 fprintf(fpout, " input image format type: %s\n",
1178 ImageFileFormatExtensions[format]);
1179 fprintf(fpout, " w = %d, h = %d, d = %d, spp = %d, wpl = %d\n",
1180 w, h, d, spp, wpl);
1181 fprintf(fpout, " xres = %d, yres = %d\n",
1182 pixGetXRes(pix), pixGetYRes(pix));
1183
1184 text = pixGetText(pix);
1185 if (text) /* not null */
1186 fprintf(fpout, " text: %s\n", text);
1187
1188 cmap = pixGetColormap(pix);
1189 if (cmap) {
1190 pixcmapHasColor(cmap, &color);
1191 if (color)
1192 fprintf(fpout, " colormap exists and has color values:");
1193 else
1194 fprintf(fpout, " colormap exists and has only gray values:");
1195 pixcmapWriteStream(fpout, pixGetColormap(pix));
1196 }
1197 else
1198 fprintf(fpout, " colormap does not exist\n");
1199
1200 if (format == IFF_TIFF || format == IFF_TIFF_G4 ||
1201 format == IFF_TIFF_G3 || format == IFF_TIFF_PACKBITS) {
1202 fprintf(fpout, " Tiff header information:\n");
1203 fpin = fopenReadStream(filename);
1204 tiffGetCount(fpin, &npages);
1205 if (fpin) fclose(fpin);
1206 if (npages == 1)
1207 fprintf(fpout, " One page in file\n");
1208 else
1209 fprintf(fpout, " %d pages in file\n", npages);
1210 fprintTiffInfo(fpout, filename);
1211 }
1212
1213 if (d == 1) {
1214 pixCountPixels(pix, &count, NULL);
1215 pixGetDimensions(pix, &w, &h, NULL);
1216 fprintf(fpout, " 1 bpp: foreground pixel fraction ON/Total = %g\n",
1217 (l_float32)count / (l_float32)(w * h));
1218 }
1219 fprintf(fpout, "===============================================\n");
1220
1221 /* If there is an alpha component, visualize it. Note that when
1222 * alpha == 0, the rgb layer is transparent. We visualize the
1223 * result when a white background is visible through the
1224 * transparency layer. */
1225 if (pixGetSpp(pix) == 4) {
1226 pixt = pixDisplayLayersRGBA(pix, 0xffffff00, 600);
1227 pixDisplay(pixt, 100, 100);
1228 pixDestroy(&pixt);
1229 }
1230
1231 if (format == IFF_PNG && bps == 16)
1232 l_pngSetReadStrip16To8(1); /* return to default if format is png */
1233
1234 pixDestroy(&pix);
1235 return 0;
1236 }
1237
1238
1239 /*---------------------------------------------------------------------*
1240 * Test function for I/O with different formats *
1241 *---------------------------------------------------------------------*/
1242 /*!
1243 * \brief ioFormatTest()
1244 *
1245 * \param[in] filename input image file
1246 * \return 0 if OK; 1 on error or if the test fails
1247 *
1248 * <pre>
1249 * Notes:
1250 * (1) This writes and reads a set of output files losslessly
1251 * in different formats to /tmp/format/, and tests that the
1252 * result before and after is unchanged.
1253 * (2) This should work properly on input images of any depth,
1254 * with and without colormaps.
1255 * (3) All supported formats are tested for bmp, png, tiff and
1256 * non-ascii pnm. Ascii pnm also works (but who'd ever want
1257 * to use it?) We allow 2 bpp bmp, although it's not
1258 * supported elsewhere. And we don't support reading
1259 * 16 bpp png, although this can be turned on in pngio.c.
1260 * (4) This silently skips png or tiff testing if HAVE_LIBPNG
1261 * or HAVE_LIBTIFF are 0, respectively.
1262 * </pre>
1263 */
1264 l_ok
1265 ioFormatTest(const char *filename)
1266 {
1267 l_int32 w, h, d, equal, problems;
1268 #if HAVE_LIBJPEG || HAVE_LIBWEBP || HAVE_LIBJP2K
1269 l_int32 depth;
1270 #endif
1271 #if HAVE_LIBJPEG || HAVE_LIBTIFF || HAVE_LIBWEBP || HAVE_LIBJP2K
1272 l_float32 diff;
1273 #endif
1274 BOX *box;
1275 PIX *pixs, *pixc, *pix1, *pix2;
1276 PIXCMAP *cmap;
1277
1278 if (!filename)
1279 return ERROR_INT("filename not defined", __func__, 1);
1280
1281 /* Read the input file and limit the size */
1282 if ((pix1 = pixRead(filename)) == NULL)
1283 return ERROR_INT("pix1 not made", __func__, 1);
1284 pixGetDimensions(pix1, &w, &h, NULL);
1285 if (w > 250 && h > 250) { /* take the central 250 x 250 region */
1286 box = boxCreate(w / 2 - 125, h / 2 - 125, 250, 250);
1287 pixs = pixClipRectangle(pix1, box, NULL);
1288 boxDestroy(&box);
1289 } else {
1290 pixs = pixClone(pix1);
1291 }
1292 pixDestroy(&pix1);
1293
1294 lept_mkdir("lept/format");
1295
1296 /* Note that the reader automatically removes colormaps
1297 * from 1 bpp BMP images, but not from 8 bpp BMP images.
1298 * Therefore, if our 8 bpp image initially doesn't have a
1299 * colormap, we are going to need to remove it from any
1300 * pix read from a BMP file. */
1301 pixc = pixClone(pixs); /* laziness */
1302
1303 /* This does not test the alpha layer pixels, because most
1304 * formats don't support it. Remove any alpha. */
1305 if (pixGetSpp(pixc) == 4)
1306 pixSetSpp(pixc, 3);
1307 cmap = pixGetColormap(pixc); /* colormap; can be NULL */
1308 d = pixGetDepth(pixc);
1309
1310 problems = FALSE;
1311
1312 /* ----------------------- BMP -------------------------- */
1313
1314 /* BMP works for 1, 2, 4, 8 and 32 bpp images.
1315 * It always writes colormaps for 1 and 8 bpp, so we must
1316 * remove it after readback if the input image doesn't have
1317 * a colormap. Although we can write/read 2 bpp BMP, nobody
1318 * else can read them! */
1319 if (d == 1 || d == 8) {
1320 L_INFO("write/read bmp\n", __func__);
1321 pixWrite(FILE_BMP, pixc, IFF_BMP);
1322 pix1 = pixRead(FILE_BMP);
1323 if (!cmap)
1324 pix2 = pixRemoveColormap(pix1, REMOVE_CMAP_BASED_ON_SRC);
1325 else
1326 pix2 = pixClone(pix1);
1327 pixEqual(pixc, pix2, &equal);
1328 if (!equal) {
1329 L_INFO(" **** bad bmp image: d = %d ****\n", __func__, d);
1330 problems = TRUE;
1331 }
1332 pixDestroy(&pix1);
1333 pixDestroy(&pix2);
1334 }
1335
1336 if (d == 2 || d == 4 || d == 32) {
1337 L_INFO("write/read bmp\n", __func__);
1338 pixWrite(FILE_BMP, pixc, IFF_BMP);
1339 pix1 = pixRead(FILE_BMP);
1340 pixEqual(pixc, pix1, &equal);
1341 if (!equal) {
1342 L_INFO(" **** bad bmp image: d = %d ****\n", __func__, d);
1343 problems = TRUE;
1344 }
1345 pixDestroy(&pix1);
1346 }
1347
1348 /* ----------------------- PNG -------------------------- */
1349 #if HAVE_LIBPNG
1350 /* PNG works for all depths, but here, because we strip
1351 * 16 --> 8 bpp on reading, we don't test png for 16 bpp. */
1352 if (d != 16) {
1353 L_INFO("write/read png\n", __func__);
1354 pixWrite(FILE_PNG, pixc, IFF_PNG);
1355 pix1 = pixRead(FILE_PNG);
1356 pixEqual(pixc, pix1, &equal);
1357 if (!equal) {
1358 L_INFO(" **** bad png image: d = %d ****\n", __func__, d);
1359 problems = TRUE;
1360 }
1361 pixDestroy(&pix1);
1362 }
1363 #endif /* HAVE_LIBPNG */
1364
1365 /* ----------------------- TIFF -------------------------- */
1366 #if HAVE_LIBTIFF && HAVE_LIBJPEG
1367 /* TIFF works for 1, 2, 4, 8, 16 and 32 bpp images.
1368 * Because 8 bpp tiff always writes 256 entry colormaps, the
1369 * colormap sizes may be different for 8 bpp images with
1370 * colormap; we are testing if the image content is the same.
1371 * Likewise, the 2 and 4 bpp tiff images with colormaps
1372 * have colormap sizes 4 and 16, rsp. This test should
1373 * work properly on the content, regardless of the number
1374 * of color entries in pixc. */
1375
1376 /* tiff uncompressed works for all pixel depths */
1377 L_INFO("write/read uncompressed tiff\n", __func__);
1378 pixWrite(FILE_TIFF, pixc, IFF_TIFF);
1379 pix1 = pixRead(FILE_TIFF);
1380 pixEqual(pixc, pix1, &equal);
1381 if (!equal) {
1382 L_INFO(" **** bad tiff uncompressed image: d = %d ****\n",
1383 __func__, d);
1384 problems = TRUE;
1385 }
1386 pixDestroy(&pix1);
1387
1388 /* tiff lzw works for all pixel depths */
1389 L_INFO("write/read lzw compressed tiff\n", __func__);
1390 pixWrite(FILE_LZW, pixc, IFF_TIFF_LZW);
1391 pix1 = pixRead(FILE_LZW);
1392 pixEqual(pixc, pix1, &equal);
1393 if (!equal) {
1394 L_INFO(" **** bad tiff lzw compressed image: d = %d ****\n",
1395 __func__, d);
1396 problems = TRUE;
1397 }
1398 pixDestroy(&pix1);
1399
1400 /* tiff adobe deflate (zip) works for all pixel depths */
1401 L_INFO("write/read zip compressed tiff\n", __func__);
1402 pixWrite(FILE_ZIP, pixc, IFF_TIFF_ZIP);
1403 pix1 = pixRead(FILE_ZIP);
1404 pixEqual(pixc, pix1, &equal);
1405 if (!equal) {
1406 L_INFO(" **** bad tiff zip compressed image: d = %d ****\n",
1407 __func__, d);
1408 problems = TRUE;
1409 }
1410 pixDestroy(&pix1);
1411
1412 /* tiff jpeg encoding works for grayscale and rgb */
1413 if (d == 8 || d == 32) {
1414 PIX *pixc1;
1415 L_INFO("write/read jpeg compressed tiff\n", __func__);
1416 if (d == 8 && pixGetColormap(pixc)) {
1417 pixc1 = pixRemoveColormap(pixc, REMOVE_CMAP_BASED_ON_SRC);
1418 pixWrite(FILE_TIFF_JPEG, pixc1, IFF_TIFF_JPEG);
1419 if ((pix1 = pixRead(FILE_TIFF_JPEG)) == NULL) {
1420 L_INFO(" did not read FILE_TIFF_JPEG\n", __func__);
1421 problems = TRUE;
1422 }
1423 pixDestroy(&pixc1);
1424 } else {
1425 pixWrite(FILE_TIFF_JPEG, pixc, IFF_TIFF_JPEG);
1426 pix1 = pixRead(FILE_TIFF_JPEG);
1427 if (d == 8) {
1428 pixCompareGray(pix1, pixc, L_COMPARE_ABS_DIFF, 0, NULL, &diff,
1429 NULL, NULL);
1430 } else {
1431 pixCompareRGB(pix1, pixc, L_COMPARE_ABS_DIFF, 0, NULL, &diff,
1432 NULL, NULL);
1433 }
1434 if (diff > 8.0) {
1435 L_INFO(" **** bad tiff jpeg compressed image: "
1436 "d = %d, diff = %5.2f ****\n", __func__, d, diff);
1437 problems = TRUE;
1438 }
1439 }
1440 pixDestroy(&pix1);
1441 }
1442
1443 /* tiff g4, g3, rle and packbits work for 1 bpp */
1444 if (d == 1) {
1445 L_INFO("write/read g4 compressed tiff\n", __func__);
1446 pixWrite(FILE_G4, pixc, IFF_TIFF_G4);
1447 pix1 = pixRead(FILE_G4);
1448 pixEqual(pixc, pix1, &equal);
1449 if (!equal) {
1450 L_INFO(" **** bad tiff g4 image ****\n", __func__);
1451 problems = TRUE;
1452 }
1453 pixDestroy(&pix1);
1454
1455 L_INFO("write/read g3 compressed tiff\n", __func__);
1456 pixWrite(FILE_G3, pixc, IFF_TIFF_G3);
1457 pix1 = pixRead(FILE_G3);
1458 pixEqual(pixc, pix1, &equal);
1459 if (!equal) {
1460 L_INFO(" **** bad tiff g3 image ****\n", __func__);
1461 problems = TRUE;
1462 }
1463 pixDestroy(&pix1);
1464
1465 L_INFO("write/read rle compressed tiff\n", __func__);
1466 pixWrite(FILE_RLE, pixc, IFF_TIFF_RLE);
1467 pix1 = pixRead(FILE_RLE);
1468 pixEqual(pixc, pix1, &equal);
1469 if (!equal) {
1470 L_INFO(" **** bad tiff rle image: d = %d ****\n", __func__, d);
1471 problems = TRUE;
1472 }
1473 pixDestroy(&pix1);
1474
1475 L_INFO("write/read packbits compressed tiff\n", __func__);
1476 pixWrite(FILE_PB, pixc, IFF_TIFF_PACKBITS);
1477 pix1 = pixRead(FILE_PB);
1478 pixEqual(pixc, pix1, &equal);
1479 if (!equal) {
1480 L_INFO(" **** bad tiff packbits image: d = %d ****\n",
1481 __func__, d);
1482 problems = TRUE;
1483 }
1484 pixDestroy(&pix1);
1485 }
1486 #endif /* HAVE_LIBTIFF && HAVE_LIBJPEG */
1487
1488 /* ----------------------- PNM -------------------------- */
1489
1490 /* pnm works for 1, 2, 4, 8, 16 and 32 bpp.
1491 * pnm doesn't have colormaps, so when we write colormapped
1492 * pix out as pnm, the colormap is removed. Thus for the test,
1493 * we must remove the colormap from pixc before testing. */
1494 L_INFO("write/read pnm\n", __func__);
1495 pixWrite(FILE_PNM, pixc, IFF_PNM);
1496 pix1 = pixRead(FILE_PNM);
1497 if (cmap)
1498 pix2 = pixRemoveColormap(pixc, REMOVE_CMAP_BASED_ON_SRC);
1499 else
1500 pix2 = pixClone(pixc);
1501 pixEqual(pix1, pix2, &equal);
1502 if (!equal) {
1503 L_INFO(" **** bad pnm image: d = %d ****\n", __func__, d);
1504 problems = TRUE;
1505 }
1506 pixDestroy(&pix1);
1507 pixDestroy(&pix2);
1508
1509 /* ----------------------- GIF -------------------------- */
1510 #if HAVE_LIBGIF
1511 /* GIF works for only 1 and 8 bpp, colormapped */
1512 if (d != 8 || !cmap)
1513 pix1 = pixConvertTo8(pixc, 1);
1514 else
1515 pix1 = pixClone(pixc);
1516 L_INFO("write/read gif\n", __func__);
1517 pixWrite(FILE_GIF, pix1, IFF_GIF);
1518 pix2 = pixRead(FILE_GIF);
1519 pixEqual(pix1, pix2, &equal);
1520 if (!equal) {
1521 L_INFO(" **** bad gif image: d = %d ****\n", __func__, d);
1522 problems = TRUE;
1523 }
1524 pixDestroy(&pix1);
1525 pixDestroy(&pix2);
1526 #endif /* HAVE_LIBGIF */
1527
1528 /* ----------------------- JPEG ------------------------- */
1529 #if HAVE_LIBJPEG
1530 /* JPEG works for only 8 bpp gray and rgb */
1531 if (cmap || d > 8)
1532 pix1 = pixConvertTo32(pixc);
1533 else
1534 pix1 = pixConvertTo8(pixc, 0);
1535 depth = pixGetDepth(pix1);
1536 L_INFO("write/read jpeg\n", __func__);
1537 pixWrite(FILE_JPG, pix1, IFF_JFIF_JPEG);
1538 pix2 = pixRead(FILE_JPG);
1539 if (depth == 8) {
1540 pixCompareGray(pix1, pix2, L_COMPARE_ABS_DIFF, 0, NULL, &diff,
1541 NULL, NULL);
1542 } else {
1543 pixCompareRGB(pix1, pix2, L_COMPARE_ABS_DIFF, 0, NULL, &diff,
1544 NULL, NULL);
1545 }
1546 if (diff > 8.0) {
1547 L_INFO(" **** bad jpeg image: d = %d, diff = %5.2f ****\n",
1548 __func__, depth, diff);
1549 problems = TRUE;
1550 }
1551 pixDestroy(&pix1);
1552 pixDestroy(&pix2);
1553 #endif /* HAVE_LIBJPEG */
1554
1555 /* ----------------------- WEBP ------------------------- */
1556 #if HAVE_LIBWEBP
1557 /* WEBP works for rgb and rgba */
1558 if (cmap || d <= 16)
1559 pix1 = pixConvertTo32(pixc);
1560 else
1561 pix1 = pixClone(pixc);
1562 depth = pixGetDepth(pix1);
1563 L_INFO("write/read webp\n", __func__);
1564 pixWrite(FILE_WEBP, pix1, IFF_WEBP);
1565 pix2 = pixRead(FILE_WEBP);
1566 pixCompareRGB(pix1, pix2, L_COMPARE_ABS_DIFF, 0, NULL, &diff, NULL, NULL);
1567 if (diff > 5.0) {
1568 L_INFO(" **** bad webp image: d = %d, diff = %5.2f ****\n",
1569 __func__, depth, diff);
1570 problems = TRUE;
1571 }
1572 pixDestroy(&pix1);
1573 pixDestroy(&pix2);
1574 #endif /* HAVE_LIBWEBP */
1575
1576 /* ----------------------- JP2K ------------------------- */
1577 #if HAVE_LIBJP2K
1578 /* JP2K works for only 8 bpp gray, rgb and rgba */
1579 if (cmap || d > 8)
1580 pix1 = pixConvertTo32(pixc);
1581 else
1582 pix1 = pixConvertTo8(pixc, 0);
1583 depth = pixGetDepth(pix1);
1584 L_INFO("write/read jp2k\n", __func__);
1585 pixWrite(FILE_JP2K, pix1, IFF_JP2);
1586 pix2 = pixRead(FILE_JP2K);
1587 if (depth == 8) {
1588 pixCompareGray(pix1, pix2, L_COMPARE_ABS_DIFF, 0, NULL, &diff,
1589 NULL, NULL);
1590 } else {
1591 pixCompareRGB(pix1, pix2, L_COMPARE_ABS_DIFF, 0, NULL, &diff,
1592 NULL, NULL);
1593 }
1594 lept_stderr("diff = %7.3f\n", diff);
1595 if (diff > 7.0) {
1596 L_INFO(" **** bad jp2k image: d = %d, diff = %5.2f ****\n",
1597 __func__, depth, diff);
1598 problems = TRUE;
1599 }
1600 pixDestroy(&pix1);
1601 pixDestroy(&pix2);
1602 #endif /* HAVE_LIBJP2K */
1603
1604 if (problems == FALSE)
1605 L_INFO("All formats read and written OK!\n", __func__);
1606
1607 pixDestroy(&pixc);
1608 pixDestroy(&pixs);
1609 return problems;
1610 }