w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

readfile.c
Go to the documentation of this file.
1 /*====================================================================*
2  - Copyright (C) 2001 Leptonica. All rights reserved.
3  - This software is distributed in the hope that it will be
4  - useful, but with NO WARRANTY OF ANY KIND.
5  - No author or distributor accepts responsibility to anyone for the
6  - consequences of using this software, or for whether it serves any
7  - particular purpose or works at all, unless he or she says so in
8  - writing. Everyone is granted permission to copy, modify and
9  - redistribute this source code, for commercial or non-commercial
10  - purposes, with the following restrictions: (1) the origin of this
11  - source code must not be misrepresented; (2) modified versions must
12  - be plainly marked as such; and (3) this notice may not be removed
13  - or altered from any source or modified source distribution.
14  *====================================================================*/
15 
16 
17 /*
18  * readfile.c: reads image on file into memory
19  *
20  * High level read functions
21  * PIX *pixRead()
22  * PIX *pixReadWithHint()
23  * PIX *pixReadStream()
24  *
25  * Format helper
26  * l_int32 findFileFormat()
27  * l_int32 findFileFormatBuffer()
28  *
29  * Test function for I/O with different formats
30  * l_int32 ioFormatTest()
31  */
32 
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include "allheaders.h"
37 
38 
39  /* choose type of PIX to be generated */
40 enum {
41  READ_24_BIT_COLOR = 0, /* read in as 24 (really 32) bit pix */
42  CONVERT_TO_PALETTE = 1, /* convert to 8 bit colormapped pix */
43  READ_GRAY = 2 /* read gray only */
44 };
45 
46  /* Output files for ioFormatTest().
47  * Note that the test for jpeg is not yet implemented */
48 static const char *FILE_BMP = "/usr/tmp/junkout.bmp";
49 static const char *FILE_PNG = "/usr/tmp/junkout.png";
50 static const char *FILE_PNM = "/usr/tmp/junkout.pnm";
51 static const char *FILE_G4 = "/usr/tmp/junkout_g4.tif";
52 static const char *FILE_TIFF = "/usr/tmp/junkout.tif";
53 static const char *FILE_JPG = "/usr/tmp/junkout.jpg";
54 
55 
56 
57 /*!
58  * pixRead()
59  *
60  * Input: filename (with full pathname or in local directory)
61  * Return: pix if OK; null on error
62  */
63 PIX *
64 pixRead(const char *filename)
65 {
66 FILE *fp;
67 PIX *pix;
68 
69  PROCNAME("pixRead");
70 
71  if (!filename)
72  return (PIX *)ERROR_PTR("filename not defined", procName, NULL);
73 
74  if ((fp = fopenReadStream(filename)) == NULL)
75  return (PIX *)ERROR_PTR("image file not found", procName, NULL);
76  pix = pixReadStream(fp, 0);
77  fclose(fp);
78 
79  if (!pix)
80  return (PIX *)ERROR_PTR("image not returned", procName, NULL);
81  return pix;
82 }
83 
84 /*!
85  * pixReadWithHint()
86  *
87  * Input: filename (with full pathname or in local directory)
88  * hint: a bitwise OR of L_HINT_* values. These are not
89  * binding, but may be used to optimize the
90  * decoding of images.
91  * Return: pix if OK; null on error
92  */
93 PIX *
95  l_int32 hint)
96 {
97 FILE *fp;
98 PIX *pix;
99 
100  PROCNAME("pixReadWithHint");
101 
102  if (!filename)
103  return (PIX *)ERROR_PTR("filename not defined", procName, NULL);
104 
105  if ((fp = fopenReadStream(filename)) == NULL)
106  return (PIX *)ERROR_PTR("image file not found", procName, NULL);
107  pix = pixReadStream(fp, hint);
108  fclose(fp);
109 
110  if (!pix)
111  return (PIX *)ERROR_PTR("image not returned", procName, NULL);
112  return pix;
113 }
114 
115 
116 /*!
117  * pixReadStream()
118  *
119  * Input: file stream
120  * hint: a bitwise OR of L_HINT_* values
121  * Return: pix if OK; null on error
122  */
123 PIX *
125  l_int32 hint)
126 {
128 PIX *pix;
129 
130  PROCNAME("pixReadStream");
131 
132  if (!fp)
133  return (PIX *)ERROR_PTR("stream not defined", procName, NULL);
134 
136 
137  switch (format)
138  {
139  case IFF_BMP:
140  if ((pix = pixReadStreamBmp(fp)) == NULL )
141  return (PIX *)ERROR_PTR( "bmp: no pix returned", procName, NULL);
142  break;
143 
144  case IFF_JFIF_JPEG:
146  == NULL)
147  return (PIX *)ERROR_PTR( "jpeg: no pix returned", procName, NULL);
148  break;
149 
150  case IFF_PNG:
151  if ((pix = pixReadStreamPng(fp)) == NULL)
152  return (PIX *)ERROR_PTR("png: no pix returned", procName, NULL);
153  break;
154 
155  case IFF_TIFF:
156  if ((pix = pixReadStreamTiff(fp, 0)) == NULL) /* page 0 by default */
157  return (PIX *)ERROR_PTR("tiff: no pix returned", procName, NULL);
158  break;
159 
160  case IFF_PNM:
161  if ((pix = pixReadStreamPnm(fp)) == NULL)
162  return (PIX *)ERROR_PTR("pnm: no pix returned", procName, NULL);
163  break;
164 
165  case IFF_UNKNOWN:
166  return (PIX *)ERROR_PTR( "Unknown format: no pix returned",
167  procName, NULL);
168  break;
169  }
170 
172  return pix;
173 }
174 
175 
176 
177 /*!
178  * findFileFormat()
179  *
180  * Input: fp
181  * Return: format integer; 0 on error or if format not recognized
182  *
183  * N.B.: this resets fp to BOF
184  */
185 l_int32
187 {
188 l_uint8 firstbytes[12];
189 
190  PROCNAME("findFileFormat");
191 
192  if (!fp)
193  return ERROR_INT("stream not defined", procName, 0);
194 
195  rewind(fp);
196  if (nbytesInFile(fp) < 12)
197  return ERROR_INT("truncated file", procName, 0);
198 
199  fread((char *)&firstbytes, 1, 12, fp);
200  rewind(fp);
201 
202  return findFileFormatBuffer(firstbytes);
203 }
204 
205 
206 /*!
207  * findFileFormatBuffer()
208  *
209  * Input: byte buffer (at least 12 bytes in size; we can't check)
210  * Return: format integer; 0 on error or if format not recognized
211  *
212  * Note: this allows you to determine the file format from the first
213  * 12 bytes in the compressed data stream, which are stored
214  * in memory.
215  */
216 l_int32
218 {
219 l_uint16 twobytepw;
220 
221  PROCNAME("findFileFormatBuffer");
222 
223  if (!buf)
224  return ERROR_INT("byte buffer not defined", procName, 0);
225 
226  /* check the bmp and tiff 2-byte header ids */
227  ((char *)(&twobytepw))[0] = buf[0];
228  ((char *)(&twobytepw))[1] = buf[1];
229 
230  if (convertOnBigEnd16(twobytepw) == BMP_ID)
231  return IFF_BMP;
232 
233  if (twobytepw == TIFF_BIGEND_ID || twobytepw == TIFF_LITTLEEND_ID)
234  return IFF_TIFF;
235 
236  /* check for the p*m 2-byte header ids */
237  if ((buf[0] == 'P' && buf[1] == '4') || /* newer packed */
238  (buf[0] == 'P' && buf[1] == '1')) /* old format */
239  return IFF_PNM;
240 
241  if ((buf[0] == 'P' && buf[1] == '5') || /* newer */
242  (buf[0] == 'P' && buf[1] == '2')) /* old */
243  return IFF_PNM;
244 
245  if ((buf[0] == 'P' && buf[1] == '6') || /* newer */
246  (buf[0] == 'P' && buf[1] == '3')) /* old */
247  return IFF_PNM;
248 
249  /* Consider the first 11 bytes of the standard JFIF JPEG header:
250  * - The first two bytes are the most important: 0xffd8.
251  * - The next two bytes are the jfif marker: 0xffe0.
252  * Not all jpeg files have this marker.
253  * - The next two bytes are the header length.
254  * - The next 5 bytes are a null-terminated string.
255  * For JFIF, the string is "JFIF", naturally. For others it
256  * can be "Exif" or just about anything else.
257  * - Because of all this variability, we only check the first
258  * two byte marker. All jpeg files are identified as
259  * IFF_JFIF_JPEG. */
260  if (buf[0] == 0xff && buf[1] == 0xd8)
261  return IFF_JFIF_JPEG;
262 
263  /* check for the 8 byte PNG signature (png_signature in png.c):
264  * {137, 80, 78, 71, 13, 10, 26, 10} */
265  if (buf[0] == 137 && buf[1] == 80 && buf[2] == 78 && buf[3] == 71 &&
266  buf[4] == 13 && buf[5] == 10 && buf[6] == 26 && buf[7] == 10)
267  return IFF_PNG;
268 
269  /* format header not found */
270  return IFF_UNKNOWN;
271 }
272 
273 
274 /*
275  * ioFormatTest()
276  *
277  * Input: filename (input file)
278  * Return: 0 if OK; 1 on error
279  *
280  * Note: This writes and reads a set of output files in different formats
281  * to /usr/tmp/, and tests that the result before and after
282  * is unchanged. It should work properly on input images of
283  * any depth, with and without colormaps.
284  */
285 l_int32
286 ioFormatTest(const char *filename)
287 {
288 l_int32 d, equal, problems;
289 PIX *pixs, *pixc, *pixt, *pixt2;
290 PIXCMAP *cmap;
291 
292  PROCNAME("ioFormatTest");
293 
294  if (!filename)
295  return ERROR_INT("filename not defined", procName, 1);
296 
297  if ((pixs = pixRead(filename)) == NULL)
298  return ERROR_INT("pix not made", procName, 1);
299 
300  /* Note that the reader automatically removes colormaps
301  * from 1 bpp BMP images, but not from 8 bpp BMP images.
302  * Therefore, if our 8 bpp image initially doesn't have a
303  * colormap, we are going to need to remove it from any
304  * pix read from a BMP file! */
305  pixc = pixClone(pixs); /* laziness */
306  cmap = pixGetColormap(pixc); /* colormap; can be NULL */
307  d = pixGetDepth(pixc);
308 
309  problems = FALSE;
310  switch (d)
311  {
312  case 1:
313  case 8:
314  case 32:
315  /* BMP always writes colormaps for 1 and 8 bpp, so we
316  * remove it if the input image doesn't have a colormap */
317  pixWrite(FILE_BMP, pixc, IFF_BMP);
318  pixt = pixRead(FILE_BMP);
319  if (!cmap)
321  else
322  pixt2 = pixClone(pixt);
323  pixEqual(pixc, pixt2, &equal);
324  if (!equal) {
325  fprintf(stderr, "bad bmp image\n");
326  problems = TRUE;
327  }
328  pixDestroy(&pixt);
329  pixDestroy(&pixt2);
330 
331  pixWrite(FILE_PNG, pixc, IFF_PNG);
332  pixt = pixRead(FILE_PNG);
333  pixEqual(pixc, pixt, &equal);
334  if (!equal) {
335  fprintf(stderr, "bad png image\n");
336  problems = TRUE;
337  }
338  pixDestroy(&pixt);
339 
340  /* Because 8 bpp tiff always writes 256 entry colormaps, the
341  * colormap sizes may be different for 8 bpp images with
342  * colormap; we are testing if the image content is the same */
343  pixWrite(FILE_TIFF, pixc, IFF_TIFF);
344  pixt = pixRead(FILE_TIFF);
345  pixEqual(pixc, pixt, &equal);
346  if (!equal) {
347  fprintf(stderr, "bad tiff uncompressed image\n");
348  problems = TRUE;
349  }
350  pixDestroy(&pixt);
351 
352  if (d == 1) {
353  pixWrite(FILE_G4, pixc, IFF_TIFF_G4);
354  pixt = pixRead(FILE_G4);
355  pixEqual(pixc, pixt, &equal);
356  if (!equal) {
357  fprintf(stderr, "bad tiff g4 image\n");
358  problems = TRUE;
359  }
360  pixDestroy(&pixt);
361  }
362 
363  /* pnm doesn't have colormaps, so when we write colormapped
364  * pix out as pnm, the colormap is removed. Thus for the test,
365  * we must remove the colormap from pixc before testing. */
366  pixWrite(FILE_PNM, pixc, IFF_PNM);
367  pixt = pixRead(FILE_PNM);
368  if (cmap)
370  else
371  pixt2 = pixClone(pixc);
372  pixEqual(pixt, pixt2, &equal);
373  if (!equal) {
374  fprintf(stderr, "bad pnm image\n");
375  problems = TRUE;
376  }
377  pixDestroy(&pixt);
378  pixDestroy(&pixt2);
379  break;
380  case 2:
381  case 4:
382  pixWrite(FILE_PNG, pixc, IFF_PNG);
383  pixt = pixRead(FILE_PNG);
384  pixEqual(pixc, pixt, &equal);
385  if (!equal) {
386  fprintf(stderr, "bad png 2 or 4 bpp image\n");
387  problems = TRUE;
388  }
389  pixDestroy(&pixt);
390 
391  /* I believe the 2 and 4 bpp tiff images with colormaps
392  * have colormap sizes 4 and 16, rsp. This test should
393  * work properly on the content, regardless of the number
394  * of color entries in pixc. */
395  pixWrite(FILE_TIFF, pixc, IFF_TIFF);
396  pixt = pixRead(FILE_TIFF);
397  pixEqual(pixc, pixt, &equal);
398  if (!equal) {
399  fprintf(stderr, "bad tiff uncompressed image\n");
400  problems = TRUE;
401  }
402  pixDestroy(&pixt);
403 
404  /* Note: this works in this test, but nobody else can
405  * read 2 bpp colormapped bmp files that are generated here! */
406  pixWrite(FILE_BMP, pixc, IFF_BMP);
407  pixt = pixRead(FILE_BMP);
408  pixEqual(pixc, pixt, &equal);
409  if (!equal) {
410  fprintf(stderr, "bad bmp 2 or 4 bpp image\n");
411  problems = TRUE;
412  }
413  pixDestroy(&pixt);
414  break;
415  case 16:
416  pixWrite(FILE_PNG, pixc, IFF_PNG);
417  pixt = pixRead(FILE_PNG);
418  pixEqual(pixc, pixt, &equal);
419  if (!equal) {
420  fprintf(stderr, "bad png 16 bpp image\n");
421  problems = TRUE;
422  }
423  pixDestroy(&pixt);
424  default:
425  return ERROR_INT("d not in {1,2,4,8,16,32}", procName, 1);
426  }
427 
428  if (problems == FALSE)
429  L_INFO("all formats read and written OK", procName);
430 
431  pixDestroy(&pixc);
432  pixDestroy(&pixs);
433  return 0;
434 }
435 
PIX * pixReadStreamBmp(FILE *fp)
Definition: bmpio.c:46
@ FALSE
Definition: dd.h:101
@ TRUE
Definition: dd.h:102
#define fread
Definition: xxstdio.h:25
#define PROCNAME(name)
Definition: environ.h:131
#define ERROR_PTR(a, b, c)
Definition: environ.h:132
unsigned short l_uint16
Definition: environ.h:31
#define L_INFO(a, b)
Definition: environ.h:138
unsigned char l_uint8
Definition: environ.h:29
#define ERROR_INT(a, b, c)
Definition: environ.h:133
int l_int32
Definition: environ.h:32
#define d(n)
Definition: gpos-common.c:151
struct fractpoint hint
Definition: hints.c:78
@ IFF_PNG
Definition: imageio.h:31
@ IFF_UNKNOWN
Definition: imageio.h:28
@ IFF_TIFF_G4
Definition: imageio.h:35
@ IFF_TIFF
Definition: imageio.h:32
@ IFF_BMP
Definition: imageio.h:29
@ IFF_PNM
Definition: imageio.h:36
@ IFF_JFIF_JPEG
Definition: imageio.h:30
@ TIFF_LITTLEEND_ID
Definition: imageio.h:46
@ TIFF_BIGEND_ID
Definition: imageio.h:45
@ BMP_ID
Definition: imageio.h:44
pix
Definition: in_pcx.cpp:383
l_int32 findFileFormat(FILE *fp)
Definition: readfile.c:186
l_int32 ioFormatTest(const char *filename)
Definition: readfile.c:286
static const char * FILE_PNG
Definition: readfile.c:49
PIX * pixReadWithHint(const char *filename, l_int32 hint)
Definition: readfile.c:94
static const char * FILE_BMP
Definition: readfile.c:48
static const char * FILE_TIFF
Definition: readfile.c:52
l_int32 findFileFormatBuffer(const l_uint8 *buf)
Definition: readfile.c:217
static const char * FILE_G4
Definition: readfile.c:51
PIX * pixRead(const char *filename)
Definition: readfile.c:64
@ READ_GRAY
Definition: readfile.c:43
@ READ_24_BIT_COLOR
Definition: readfile.c:41
@ CONVERT_TO_PALETTE
Definition: readfile.c:42
static const char * FILE_JPG
Definition: readfile.c:53
PIX * pixReadStream(FILE *fp, l_int32 hint)
Definition: readfile.c:124
static const char * FILE_PNM
Definition: readfile.c:50
PIX * pixReadStreamJpeg(FILE *fp, l_int32 cmflag, l_int32 reduction, l_int32 *pnwarn, l_int32 hint)
Definition: jpegio.c:135
#define NULL
Definition: ftobjs.h:61
#define buf
#define fclose
Definition: debug.h:100
#define fprintf
Definition: mendex.h:64
l_int32 pixSetInputFormat(PIX *pix, l_int32 informat)
Definition: pix1.c:628
void pixDestroy(PIX **ppix)
Definition: pix1.c:225
l_int32 pixEqual(PIX *pix1, PIX *pix2, l_int32 *psame)
Definition: pix2.c:2525
l_int32 nbytesInFile(FILE *fp)
Definition: utils.c:841
PIX * pixReadStreamPnm(FILE *fp)
Definition: pnmio.c:88
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
Definition: pixconv.c:198
l_int32 pixGetDepth(PIX *pix)
Definition: pix1.c:449
PIXCMAP * pixGetColormap(PIX *pix)
Definition: pix1.c:766
l_uint16 convertOnBigEnd16(l_uint16 shortin)
Definition: utils.c:937
PIX * pixReadStreamTiff(FILE *fp, l_int32 n)
Definition: tiffio.c:111
l_int32 pixWrite(const char *filename, PIX *pix, l_int32 format)
Definition: writefile.c:113
FILE * fopenReadStream(const char *filename)
Definition: utils.c:992
PIX * pixReadStreamPng(FILE *fp)
Definition: pngio.c:62
PIX * pixClone(PIX *pixs)
Definition: pix1.c:197
static int format
Definition: pbmclean.c:15
char * filename[256]
Definition: pbmtopk.c:46
@ REMOVE_CMAP_BASED_ON_SRC
Definition: pix.h:113
#define fp
int equal(char *s, char *t)
Definition: pix.h:51
#define FILE
Definition: t1stdio.h:34
TT_CharMap cmap
Definition: ttf2pfb.c:163