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)  

tiffio.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  * tiffio.c
18  *
19  * Reading tiff:
20  * PIX *pixReadTiff() [ special top level ]
21  * PIX *pixReadStreamTiff()
22  * static PIX *pixReadFromTiffStream()
23  *
24  * Writing tiff:
25  * l_int32 pixWriteTiffCustom() [ special top level ]
26  * l_int32 pixWriteTiff() [ special top level ]
27  * l_int32 pixWriteStreamTiff()
28  * static l_int32 pixWriteToTiffStream()
29  * static l_int32 writeCustomTiffTags()
30  *
31  * Information about tiff file
32  * l_int32 fprintTiffInfo()
33  * l_int32 tiffGetCount()
34  * l_int32 readHeaderTiff()
35  * l_int32 freadHeaderTiff()
36  *
37  * Open tiff stream from file stream
38  * static TIFF *fopenTiff()
39  */
40 
41 #include <stdio.h>
42 #include <string.h>
43 #include <stdlib.h>
44 #include <sys/types.h>
45 #include <unistd.h>
46 #include <fcntl.h>
47 #include "allheaders.h"
48 
49 static const l_int32 DEFAULT_RESOLUTION = 300; /* ppi */
50 static const l_int32 MAX_PAGES_IN_TIFF_FILE = 1000; /* should be enough */
51 
52 
53  /* all functions with TIFF interfaces are static */
54 static TIFF *fopenTiff(FILE *fp, const char *modestr);
55 static PIX *pixReadFromTiffStream(TIFF *tif);
57  NUMA *natags, SARRAY *savals,
58  SARRAY *satypes, NUMA *nasizes);
59 static l_int32 writeCustomTiffTags(TIFF *tif, NUMA *natags,
60  SARRAY *savals, SARRAY *satypes,
61  NUMA *nasizes);
62 
63 
64 /*--------------------------------------------------------------*
65  * Reading from file *
66  *--------------------------------------------------------------*/
67 /*!
68  * pixReadTiff()
69  *
70  * Input: filename
71  * page number (0 based)
72  * Return: pix, or null on error
73  *
74  * Note: this is a version of pixRead(), specialized for tiff
75  * files, that allows specification of the page to be returned
76  */
77 PIX *
78 pixReadTiff(const char *filename,
79  l_int32 n)
80 {
81 FILE *fp;
82 PIX *pix;
83 
84  PROCNAME("pixReadTiff");
85 
86  if (!filename)
87  return (PIX *)ERROR_PTR("filename not defined", procName, NULL);
88 
89  if ((fp = fopenReadStream(filename)) == NULL)
90  return (PIX *)ERROR_PTR("image file not found", procName, NULL);
92  fclose(fp);
93 
94  if (!pix)
95  return (PIX *)ERROR_PTR("image not returned", procName, NULL);
96  return pix;
97 }
98 
99 
100 /*--------------------------------------------------------------*
101  * Reading from stream *
102  *--------------------------------------------------------------*/
103 /*!
104  * pixReadStreamTiff()
105  *
106  * Input: stream
107  * page number (0 based: start with 0)
108  * Return: pix, or null on error (e.g., if the page number is invalid)
109  */
110 PIX *
112  l_int32 n)
113 {
114 l_int32 i, pagefound;
115 PIX *pix;
116 TIFF *tif;
117 
118  PROCNAME("pixReadStreamTiff");
119 
120  if (!fp)
121  return (PIX *)ERROR_PTR("stream not defined", procName, NULL);
122 
123  if ((tif = fopenTiff(fp, "rb")) == NULL)
124  return (PIX *)ERROR_PTR("tif not opened", procName, NULL);
125 
126  pagefound = FALSE;
127  pix = NULL;
128  for (i = 0; i < MAX_PAGES_IN_TIFF_FILE; i++) {
129  if (i == n) {
130  pagefound = TRUE;
131  pix = pixReadFromTiffStream(tif);
132  break;
133  }
134  if (TIFFReadDirectory(tif) == 0)
135  break;
136  }
137  if (pagefound == FALSE) {
138  L_WARNING_INT("tiff page %d not found", procName, n);
139  }
140 
141  TIFFClose(tif);
142  return pix;
143 }
144 
145 
146 /*!
147  * pixReadFromTiffStream()
148  *
149  * Input: stream
150  * Return: pix, or null on error
151  */
152 static PIX *
154 {
155 l_uint8 *linebuf, *data;
156 l_uint16 spp, bps, bpp, tiffbpl, photometry;
157 l_uint16 *redmap, *greenmap, *bluemap;
158 l_int32 d, wpl, bpl, i, j, k, ncolors;
159 l_uint32 w, h, res;
160 l_uint32 *line, *ppixel;
161 l_float32 fres;
162 PIX *pix;
163 PIXCMAP *cmap;
164 
165  PROCNAME("pixReadFromTiffStream");
166 
167  if (!tif)
168  return (PIX *)ERROR_PTR("tif not defined", procName, NULL);
169 
170  /* Use default fields for bps and spp */
172  if (bps > 8)
173  return (PIX *)ERROR_PTR("bps > 8", procName, NULL);
175  bpp = bps * spp;
176  if (spp == 1)
177  d = bps;
178  else if (spp == 3)
179  d = 32;
180  else
181  return (PIX *)ERROR_PTR("spp not in set {1,3}", procName, NULL);
182 
185  tiffbpl = TIFFScanlineSize(tif);
186 
187  if ((linebuf = (l_uint8 *)CALLOC(tiffbpl + 1, sizeof(l_uint8))) == NULL)
188  return (PIX *)ERROR_PTR("calloc fail for linebuf", procName, NULL);
189 
190  if ((pix = pixCreate(w, h, d)) == NULL)
191  return (PIX *)ERROR_PTR("pix not made", procName, NULL);
192  data = (l_uint8 *)pixGetData(pix);
193  wpl = pixGetWpl(pix);
194  bpl = 4 * wpl;
195 
196  /* Read the data */
197  if (spp == 1) {
198  for (i = 0 ; i < h ; i++) {
199  if (TIFFReadScanline(tif, linebuf, i, 0) < 0)
200  return (PIX *)ERROR_PTR("line read fail", procName, NULL);
201  memcpy((char *)data, (char *)linebuf, tiffbpl);
202  data += bpl;
203  }
205  }
206  else {
207  line = pixGetData(pix);
208  for (i = 0 ; i < h ; i++, line += wpl)
209  {
210  if (TIFFReadScanline(tif, linebuf, i, 0) < 0)
211  return (PIX *)ERROR_PTR("line read fail", procName, NULL);
212  for (j = 0, k = 0, ppixel = line; j < w; j++) {
213  SET_DATA_BYTE(ppixel, COLOR_RED, linebuf[k++]);
214  SET_DATA_BYTE(ppixel, COLOR_GREEN, linebuf[k++]);
215  SET_DATA_BYTE(ppixel, COLOR_BLUE, linebuf[k++]);
216  ppixel++;
217  }
218  }
219  }
220 
221  if (TIFFGetField(tif, TIFFTAG_XRESOLUTION, &fres)) {
222  res = (l_uint32)fres;
223  pixSetXRes(pix, res);
224  }
225  if (TIFFGetField(tif, TIFFTAG_YRESOLUTION, &fres)) {
226  res = (l_uint32)fres;
227  pixSetYRes(pix, res);
228  }
229 
230  if (TIFFGetField(tif, TIFFTAG_COLORMAP, &redmap, &greenmap, &bluemap)) {
231  /* Save the colormap as a pix cmap. Because the
232  * tiff colormap components are 16 bit unsigned,
233  * and go from black (0) to white (0xffff), the
234  * the pix cmap takes the most significant byte. */
235  if ((cmap = pixcmapCreate(bps)) == NULL)
236  return (PIX *)ERROR_PTR("cmap not made", procName, NULL);
237  ncolors = 1 << bps;
238  for (i = 0; i < ncolors; i++)
239  pixcmapAddColor(cmap, redmap[i] >> 8, greenmap[i] >> 8,
240  bluemap[i] >> 8);
242  }
243  else { /* No colormap: check photometry and invert if necessary */
244  TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometry);
245  if ((d == 1 && photometry == PHOTOMETRIC_MINISBLACK) ||
246  (d == 8 && photometry == PHOTOMETRIC_MINISWHITE))
247  pixInvert(pix, pix);
248  }
249 
250  FREE((char *)linebuf);
251  return pix;
252 }
253 
254 
255 /*--------------------------------------------------------------*
256  * Writing to file *
257  *--------------------------------------------------------------*/
258 /*!
259  * pixWriteTiffCustom()
260  *
261  * Input: filename (to write to)
262  * pix
263  * comptype (IFF_TIFF, IFF_TIFF_PACKBITS,
264  * IFF_TIFF_G3, IFF_TIFF_G4)
265  * modestring ("a" or "w")
266  * natags (<optional> NUMA of custom tiff tags)
267  * savals (<optional> SARRAY of values)
268  * satypes (<optional> SARRAY of types)
269  * nasizes (<optional> NUMA of sizes)
270  * Return: 0 if OK, 1 on error
271  *
272  * Usage:
273  * (1) This writes a page image to a tiff file, with optional
274  * extra tags defined in tiff.h
275  * (2) For multi-page tiff, write the first pix with mode "w" and
276  * all subsequent pix with mode "a".
277  * (3) For the custom tiff tags:
278  * (a) The three arrays {natags, savals, satypes} must all be
279  * either NULL or defined and of equal size.
280  * (b) If they are defined, the tags are an array of integers,
281  * the vals are an array of values in string format, and
282  * the types are an array of types in string format.
283  * (c) All valid tags are definined in tiff.h.
284  * (d) The types allowed are the set of strings:
285  * "char*"
286  * "l_uint8*"
287  * "l_uint16"
288  * "l_uint32"
289  * "l_int32"
290  * "l_float64"
291  * "l_uint16-l_uint16" (note the dash; use it between the
292  * two l_uint16 vals in the val string)
293  * Of these, "char*" and "l_uint16" are the most commonly used.
294  * (e) The last array, nasizes, is also optional. It is for
295  * tags that take an array of bytes for a value, a number of
296  * elements in the array, and a type that is either "char*"
297  * or "l_uint8*" (probably either will work).
298  * Use NULL if there are no such tags.
299  * (f) VERY IMPORTANT: if there are any tags that require the
300  * extra size value, stored in nasizes, they must be
301  * written first!
302  */
303 l_int32
305  PIX *pix,
306  l_int32 comptype,
307  const char *modestring,
308  NUMA *natags,
309  SARRAY *savals,
310  SARRAY *satypes,
311  NUMA *nasizes)
312 {
313 l_int32 ret;
314 TIFF *tif;
315 
316  PROCNAME("pixWriteTiffCustom");
317 
318  if (!filename)
319  return ERROR_INT("filename not defined", procName, 1);
320  if (!pix)
321  return ERROR_INT("pix not defined", procName, 1);
322 
323  if ((tif = TIFFOpen(filename, modestring)) == NULL)
324  return ERROR_INT("tif not opened", procName, 1);
325  ret = pixWriteToTiffStream(tif, pix, comptype, natags, savals,
326  satypes, nasizes);
327  TIFFClose(tif);
328 
329  return ret;
330 }
331 
332 
333 /*!
334  * pixWriteTiff()
335  *
336  * Input: filename (to write to)
337  * pix
338  * comptype (IFF_TIFF, IFF_TIFF_PACKBITS,
339  * IFF_TIFF_G3, IFF_TIFF_G4)
340  * modestring ("a" or "w")
341  * Return: 0 if OK, 1 on error
342  *
343  * Usage: write the first pix with "w" and all subsequent
344  * ones with "a".
345  */
346 l_int32
347 pixWriteTiff(const char *filename,
348  PIX *pix,
349  l_int32 comptype,
350  const char *modestring)
351 {
352 l_int32 ret;
353 TIFF *tif;
354 
355  PROCNAME("pixWriteTiff");
356 
357  if (!filename)
358  return ERROR_INT("filename not defined", procName, 1 );
359  if (!pix)
360  return ERROR_INT("pix not defined", procName, 1 );
361 
362  if ((tif = TIFFOpen(filename, modestring)) == NULL)
363  return ERROR_INT("tif not opened", procName, 1);
364  ret = pixWriteToTiffStream(tif, pix, comptype, NULL, NULL, NULL, NULL);
365  TIFFClose(tif);
366 
367  return ret;
368 }
369 
370 
371 
372 /*--------------------------------------------------------------*
373  * Writing to stream *
374  *--------------------------------------------------------------*/
375 /*!
376  * pixWriteStreamTiff()
377  *
378  * Input: stream (opened for append or write)
379  * pix
380  * comptype (IFF_TIFF, IFF_TIFF_PACKBITS,
381  * IFF_TIFF_G3, IFF_TIFF_G4)
382  * Return: 0 if OK, 1 on error
383  *
384  * Notes: For images with bpp > 1, this resets the comptype, if
385  * necessary, to write uncompressed data. G3 and G4
386  * are only defined for 1 bpp. We only allow PACKBITS
387  * for bpp = 1, because for bpp > 1 it typically expands
388  * images that are not synthetically generated.
389  * G4 compression is typically about twice as good as G3.
390  * G4 is excellent for binary compression of text/line-art,
391  * but terrible for halftones and dithered patterns. (In
392  * fact, G4 on halftones can give a file that is larger
393  * than uncompressed!) If a binary image has dithered
394  * regions, it is usually better to compress with png.
395  */
396 l_int32
398  PIX *pix,
399  l_int32 comptype)
400 {
401 TIFF *tif;
402 
403  PROCNAME("pixWriteStreamTiff");
404 
405  if (!fp)
406  return ERROR_INT("stream not defined", procName, 1 );
407  if (!pix)
408  return ERROR_INT("pix not defined", procName, 1 );
409 
410  if (pixGetDepth(pix) != 1 && comptype != IFF_TIFF) {
411  L_WARNING("no compression on images with bpp > 1", procName);
412  comptype = IFF_TIFF;
413  }
414 
415  if ((tif = fopenTiff(fp, "wb")) == NULL)
416  return ERROR_INT("tif not opened", procName, 1);
417 
418  if (pixWriteToTiffStream(tif, pix, comptype, NULL, NULL, NULL, NULL)) {
419  TIFFClose(tif);
420  return ERROR_INT("tif write error", procName, 1);
421  }
422 
423  TIFFClose(tif);
424  return 0;
425 }
426 
427 
428 /*!
429  * pixWriteToTiffStream()
430  *
431  * Input: tif (data structure, opened to a file)
432  * pix
433  * comptype (IFF_TIFF: for any image; no compression
434  * IFF_TIFF_PACKBITS: for any image except 32 bpp
435  * IFF_TIFF_G4 and IFF_TIFF_G3: for binary only)
436  * natags (<optional> NUMA of custom tiff tags)
437  * savals (<optional> SARRAY of values)
438  * satypes (<optional> SARRAY of types)
439  * nasizes (<optional> NUMA of sizes)
440  * Return: 0 if OK, 1 on error
441  *
442  * Notes:
443  * (1) This static function should be called through higher level
444  * functions, such as pixWriteTiffCustom(), pixWriteTiff(), or
445  * pixWriteStreamTiff().
446  * (2) There is no compression for 32 bpp pix.
447  * (3) See pixWriteTiffCustom() for details on how to use
448  * the last four parameters for customized tiff tags.
449  */
450 static l_int32
452  PIX *pix,
453  l_int32 comptype,
454  NUMA *natags,
455  SARRAY *savals,
456  SARRAY *satypes,
457  NUMA *nasizes)
458 {
459 l_uint8 *linebuf, *data;
460 l_uint16 redmap[256], greenmap[256], bluemap[256];
461 l_int32 w, h, d, i, j, k, wpl, bpl, tiffbpl, ncolors, cmapsize;
462 l_int32 *rmap, *gmap, *bmap;
464 l_uint32 *line, *ppixel;
465 PIX *pixt;
466 PIXCMAP *cmap;
467 char *text;
468 
469  PROCNAME("pixWriteToTiffStream");
470 
471  if (!tif)
472  return ERROR_INT("tif stream not defined", procName, 1);
473  if (!pix)
474  return ERROR_INT( "pix not defined", procName, 1 );
475 
476  w = pixGetWidth(pix);
477  h = pixGetHeight(pix);
478  d = pixGetDepth(pix);
479  xres = pixGetXRes(pix);
480  yres = pixGetYRes(pix);
481  if (xres == 0) xres = DEFAULT_RESOLUTION;
482  if (yres == 0) yres = DEFAULT_RESOLUTION;
483 
484  /* ------------------ Write out the header ------------- */
488 
492 
493  if ((text = pixGetText(pix)) != NULL)
495 
496  if (d == 1)
498  else if (d == 32) {
501  (l_uint16)8, (l_uint16)8, (l_uint16)8);
503  }
504  else if ((cmap = pixGetColormap(pix)) == NULL)
506  else { /* Save colormap in the tiff; not more than 256 colors */
507  pixcmapToArrays(cmap, &rmap, &gmap, &bmap);
508  ncolors = pixcmapGetCount(cmap);
509  ncolors = L_MIN(256, ncolors); /* max 256 */
510  cmapsize = 1 << d;
511  cmapsize = L_MIN(256, cmapsize); /* power of 2; max 256 */
512  if (ncolors > cmapsize) {
513  L_WARNING("too many colors in cmap for tiff; truncating", procName);
514  ncolors = cmapsize;
515  }
516  for (i = 0; i < ncolors; i++) {
517  redmap[i] = (rmap[i] << 8) | rmap[i];
518  greenmap[i] = (gmap[i] << 8) | gmap[i];
519  bluemap[i] = (bmap[i] << 8) | bmap[i];
520  }
521  for (i = ncolors; i < cmapsize; i++) /* init, even though not used */
522  redmap[i] = greenmap[i] = bluemap[i] = 0;
523  FREE((void *)rmap);
524  FREE((void *)gmap);
525  FREE((void *)bmap);
526 
530  TIFFSetField(tif, TIFFTAG_COLORMAP, redmap, greenmap, bluemap);
531  }
532 
533  if (d != 32) {
536  }
537 
539  if (comptype == IFF_TIFF) /* no compression */
541  else if (comptype == IFF_TIFF_G4)
543  else if (comptype == IFF_TIFF_G3)
545  else if (comptype == IFF_TIFF_PACKBITS)
547  else {
548  L_WARNING("unknown tiff compression; using none", procName);
550  }
551 
552  /* This is a no-op if arrays are NULL */
553  writeCustomTiffTags(tif, natags, savals, satypes, nasizes);
554 
555  /* ------------- write out the image data ------------- */
556  tiffbpl = TIFFScanlineSize(tif);
557  wpl = pixGetWpl(pix);
558  bpl = 4 * wpl;
559  if (tiffbpl > bpl)
560  fprintf(stderr, "Big trouble: tiffbpl = %d, bpl = %d\n", tiffbpl, bpl);
561  if ((linebuf = (l_uint8 *)CALLOC(1, bpl)) == NULL)
562  return ERROR_INT("calloc fail for linebuf", procName, 1);
563 
564  /* Use single strip for image */
566 
567  if (d != 32) {
568  if ((pixt = pixEndianByteSwapNew(pix)) == NULL) {
569  FREE((char *)linebuf);
570  return ERROR_INT("pixt not made", procName, 1);
571  }
572  data = (l_uint8 *)pixGetData(pixt);
573  for (i = 0 ; i < h; i++, data += bpl) {
574  memcpy((char *)linebuf, (char *)data, tiffbpl);
575  if (TIFFWriteScanline(tif, linebuf, i, 0) < 0)
576  break;
577  }
578  pixDestroy(&pixt);
579  }
580  else {
581  line = pixGetData(pix);
582  for (i = 0 ; i < h; i++, line += wpl) {
583  line = pixGetData(pix) + i * wpl;
584  for (j = 0, k = 0, ppixel = line; j < w; j++) {
585  linebuf[k++] = GET_DATA_BYTE(ppixel, COLOR_RED);
586  linebuf[k++] = GET_DATA_BYTE(ppixel, COLOR_GREEN);
587  linebuf[k++] = GET_DATA_BYTE(ppixel, COLOR_BLUE);
588  ppixel++;
589  }
590  if (TIFFWriteScanline(tif, linebuf, i, 0) < 0)
591  break;
592  }
593  }
594 
595 /* TIFFWriteDirectory(tif); */
596  FREE((char *)linebuf);
597 
598  return 0;
599 }
600 
601 
602 /*!
603  * writeCustomTiffTags()
604  *
605  * Input: tif
606  * natags (<optional> NUMA of custom tiff tags)
607  * savals (<optional> SARRAY of values)
608  * satypes (<optional> SARRAY of types)
609  * nasizes (<optional> NUMA of sizes)
610  * Return: 0 if OK, 1 on error
611  *
612  * Usage:
613  * (1) This static function should be called indirectly through
614  * higher level functions, such as pixWriteTiffCustom(),
615  * which call pixWriteToTiffStream(). See details in
616  * pixWriteTiffCustom() for using the 4 input arrays.
617  * (2) This is a no-op if the first 3 arrays are all NULL.
618  * (3) Otherwise, the first 3 arrays must be defined and all
619  * of equal size.
620  * (4) The fourth array is always optional.
621  * (5) The most commonly used types are "char*" and "u_int16".
622  * See tiff.h for a full listing of the tiff tags.
623  * Note that many of these tags, in particular the bit tags,
624  * are intended to be private, and cannot be set by this function.
625  * Examples are the STRIPOFFSETS and STRIPBYTECOUNTS tags,
626  * which are bit tags that are automatically set in the header,
627  * and can be extracted using tiffdump.
628  */
629 static l_int32
631  NUMA *natags,
632  SARRAY *savals,
633  SARRAY *satypes,
634  NUMA *nasizes)
635 {
636 char *sval, *type;
637 l_int32 i, n, ns, size, tagval, val;
638 l_float64 dval;
639 l_uint32 uval, uval2;
640 
641  PROCNAME("writeCustomTiffTags");
642 
643  if (!tif)
644  return ERROR_INT("tif stream not defined", procName, 1);
645  if (!natags && !savals && !satypes)
646  return 0;
647  if (!natags || !savals || !satypes)
648  return ERROR_INT("not all arrays defined", procName, 1);
649  n = numaGetCount(natags);
650  if ((sarrayGetCount(savals) != n) || (sarrayGetCount(satypes) != n))
651  return ERROR_INT("not all sa the same size", procName, 1);
652 
653  /* The sized arrays (4 args to TIFFSetField) are written first */
654  if (nasizes) {
655  ns = numaGetCount(nasizes);
656  if (ns > n)
657  return ERROR_INT("too many 4-arg tag calls", procName, 1);
658  for (i = 0; i < ns; i++) {
659  numaGetIValue(natags, i, &tagval);
660  sval = sarrayGetString(savals, i, 0);
661  type = sarrayGetString(satypes, i, 0);
662  numaGetIValue(nasizes, i, &size);
663  if (strcmp(type, "char*") && strcmp(type, "l_uint8*"))
664  L_WARNING("array type not char* or l_uint8*; ignore", procName);
665  TIFFSetField(tif, tagval, size, sval);
666  }
667  }
668  else
669  ns = 0;
670 
671  /* The typical tags (3 args to TIFFSetField) are now written */
672  for (i = ns; i < n; i++) {
673  numaGetIValue(natags, i, &tagval);
674  sval = sarrayGetString(savals, i, 0);
675  type = sarrayGetString(satypes, i, 0);
676  if (!strcmp(type, "char*")) {
677  TIFFSetField(tif, tagval, sval);
678  }
679  else if (!strcmp(type, "l_uint16")) {
680  if (sscanf(sval, "%u", &uval) == 1) {
681  TIFFSetField(tif, tagval, (l_uint16)uval);
682  }
683  else {
684  fprintf(stderr, "val %s not of type %s\n", sval, type);
685  return ERROR_INT("custom tag(s) not written", procName, 1);
686  }
687  }
688  else if (!strcmp(type, "l_uint32")) {
689  if (sscanf(sval, "%u", &uval) == 1) {
690  TIFFSetField(tif, tagval, uval);
691  }
692  else {
693  fprintf(stderr, "val %s not of type %s\n", sval, type);
694  return ERROR_INT("custom tag(s) not written", procName, 1);
695  }
696  }
697  else if (!strcmp(type, "l_int32")) {
698  if (sscanf(sval, "%d", &val) == 1) {
699  TIFFSetField(tif, tagval, val);
700  }
701  else {
702  fprintf(stderr, "val %s not of type %s\n", sval, type);
703  return ERROR_INT("custom tag(s) not written", procName, 1);
704  }
705  }
706  else if (!strcmp(type, "l_float64")) {
707  if (sscanf(sval, "%f", &dval) == 1) {
708  TIFFSetField(tif, tagval, dval);
709  }
710  else {
711  fprintf(stderr, "val %s not of type %s\n", sval, type);
712  return ERROR_INT("custom tag(s) not written", procName, 1);
713  }
714  }
715  else if (!strcmp(type, "l_uint16-l_uint16")) {
716  if (sscanf(sval, "%u-%u", &uval, &uval2) == 2) {
717  TIFFSetField(tif, tagval, (l_uint16)uval, (l_uint16)uval2);
718  }
719  else {
720  fprintf(stderr, "val %s not of type %s\n", sval, type);
721  return ERROR_INT("custom tag(s) not written", procName, 1);
722  }
723  }
724  else
725  return ERROR_INT("unknown type; tag(s) not written", procName, 1);
726  }
727  return 0;
728 }
729 
730 
731 /*--------------------------------------------------------------*
732  * Print info to stream *
733  *--------------------------------------------------------------*/
734 /*
735  * fprintTiffInfo()
736  *
737  * Input: stream (for output of tag data)
738  * tiffile (input)
739  * Return: 0 if OK; 1 on error
740  */
741 l_int32
743  const char *tiffile)
744 {
745 TIFF *tif;
746 
747  PROCNAME("fprintTiffInfo");
748 
749  if (!tiffile)
750  return ERROR_INT("tiffile not defined", procName, 1);
751  if (!fpout)
752  return ERROR_INT("stream out not defined", procName, 1);
753 
754  if ((tif = TIFFOpen(tiffile, "rb")) == NULL)
755  return ERROR_INT("tif not open for read", procName, 1);
756 
757  TIFFPrintDirectory(tif, fpout, 0);
758  TIFFClose(tif);
759 
760  return 0;
761 }
762 
763 
764 /*--------------------------------------------------------------*
765  * Get count from stream *
766  *--------------------------------------------------------------*/
767 /*
768  * tiffGetCount()
769  *
770  * Input: stream (opened for read)
771  * &n (<return> number of images)
772  * Return: 0 if OK; 1 on error
773  */
774 l_int32
776  l_int32 *pn)
777 {
778 l_int32 i;
779 TIFF *tif;
780 
781  PROCNAME("tiffGetCount");
782 
783  if (!fp)
784  return ERROR_INT("stream not defined", procName, 1);
785  if (!pn)
786  return ERROR_INT("&n not defined", procName, 1);
787  *pn = 0;
788 
789  if ((tif = fopenTiff(fp, "rb")) == NULL)
790  return ERROR_INT("tif not open for read", procName, 1);
791 
792  for (i = 1; i < MAX_PAGES_IN_TIFF_FILE; i++) {
793  if (TIFFReadDirectory(tif) == 0)
794  break;
795  }
796  *pn = i;
797  TIFFClose(tif);
798  return 0;
799 }
800 
801 
802 /*--------------------------------------------------------------*
803  * Get some tiff header information *
804  *--------------------------------------------------------------*/
805 /*!
806  * readHeaderTiff()
807  *
808  * Input: filename
809  * &width (<return>)
810  * &height (<return>)
811  * &bps (<return> bits per sample -- 1, 2, 4 or 8)
812  * &spp (<return>; samples per pixel -- 1 or 3)
813  * &res (<optional return>; resolution in x dir; NULL to ignore)
814  * &cmap (<optional return>; colormap exists; input NULL to ignore)
815  * Return: 0 if OK, 1 on error
816  *
817  * Note: if there is a colormap, cmap is returned as 1; else 0.
818  */
819 l_int32
821  l_int32 *pwidth,
822  l_int32 *pheight,
823  l_int32 *pbps,
824  l_int32 *pspp,
825  l_int32 *pres,
826  l_int32 *pcmap)
827 {
828 l_int32 ret;
829 FILE *fp;
830 
831  PROCNAME("readHeaderTiff");
832 
833  if (!filename)
834  return ERROR_INT("filename not defined", procName, 1);
835  if (!pwidth || !pheight || !pbps || !pspp)
836  return ERROR_INT("input ptr(s) not all defined", procName, 1);
837  *pwidth = *pheight = *pbps = *pspp = 0;
838  if (pres) *pres = 0;
839  if (pcmap) *pcmap = 0;
840  if ((fp = fopenReadStream(filename)) == NULL)
841  return ERROR_INT("image file not found", procName, 1);
842  if (findFileFormat(fp) != IFF_TIFF)
843  return ERROR_INT("file not tiff format", procName, 1);
844  ret = freadHeaderTiff(fp, pwidth, pheight, pbps, pspp, pres, pcmap);
845  fclose(fp);
846  return ret;
847 }
848 
849 
850 /*!
851  * freadHeaderTiff()
852  *
853  * Input: stream
854  * &width (<return>)
855  * &height (<return>)
856  * &bps (<return> bits per sample -- 1, 2, 4 or 8)
857  * &spp (<return>; samples per pixel -- 1 or 3)
858  * &res (<optional return>; resolution in x dir; NULL to ignore)
859  * &cmap (<optional return>; colormap exists; input NULL to ignore)
860  * Return: 0 if OK, 1 on error
861  */
862 l_int32
864  l_int32 *pwidth,
865  l_int32 *pheight,
866  l_int32 *pbps,
867  l_int32 *pspp,
868  l_int32 *pres,
869  l_int32 *pcmap)
870 {
871 l_uint16 bps, spp;
872 l_uint16 *rmap, *gmap, *bmap;
873 l_uint32 w, h;
874 l_float32 fres;
875 TIFF *tif;
876 
877  PROCNAME("freadHeaderTiff");
878 
879  if (!fp)
880  return ERROR_INT("stream not defined", procName, 1);
881  if (!pwidth || !pheight || !pbps || !pspp)
882  return ERROR_INT("input ptr(s) not all defined", procName, 1);
883 
884  if ((tif = fopenTiff(fp, "rb")) == NULL)
885  return ERROR_INT("tif not opened", procName, 1);
886 
888  *pwidth = w;
890  *pheight = h;
892  *pbps = bps;
894  *pspp = spp;
895 
896  if (pres) {
897  *pres = 300;
898  if (TIFFGetField(tif, TIFFTAG_XRESOLUTION, &fres))
899  *pres = (l_int32)fres;
900  }
901 
902  if (pcmap) {
903  *pcmap = 0;
904  if (TIFFGetField(tif, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap))
905  *pcmap = 1;
906  }
907 
908  TIFFClose(tif);
909  return 0;
910 }
911 
912 
913 /*--------------------------------------------------------------*
914  * Open tiff stream from file stream *
915  *--------------------------------------------------------------*/
916 /*!
917  * fopenTiff()
918  *
919  * Input: stream
920  * modestring ("r", "w", ...)
921  * Return: tiff (data structure, opened for a file descriptor)
922  *
923  * Notes:
924  * (1) Why is this here? Leffler did not provide a function that
925  * takes a stream and gives a TIFF. He only gave one that
926  * generates a TIFF starting with a file descriptor. So we
927  * need to make it here, because it is useful to have functions
928  * that take a stream as input.
929  * (2) Requires lseek to rewind to BOF; fseek won't hack it.
930  */
931 static TIFF *
933  const char *modestring)
934 {
935 l_int32 fd;
936 
937  PROCNAME("fopenTiff");
938 
939  if (!fp)
940  return (TIFF *)ERROR_PTR("stream not opened", procName, NULL);
941  if (!modestring)
942  return (TIFF *)ERROR_PTR("modestring not defined", procName, NULL);
943 
944  if ((fd = fileno(fp)) < 0)
945  return (TIFF *)ERROR_PTR("invalid file descriptor", procName, NULL);
946  lseek(fd, 0, SEEK_SET);
947 
948  return TIFFFdOpen(fd, "TIFFstream", modestring);
949 }
950 
#define type(a)
Definition: aptex-macros.h:171
#define text(a)
Definition: aptex-macros.h:925
#define GET_DATA_BYTE(pdata, n)
Definition: arrayaccess.h:98
#define SET_DATA_BYTE(pdata, n, val)
Definition: arrayaccess.h:106
static char gmap[128]
Definition: asciitopgm.c:19
#define n
Definition: t4ht.c:1290
l_int32 pixcmapGetCount(PIXCMAP *cmap)
Definition: colormap.c:279
PIXCMAP * pixcmapCreate(l_int32 depth)
Definition: colormap.c:68
l_int32 pixcmapAddColor(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval)
Definition: colormap.c:162
l_int32 pixcmapToArrays(PIXCMAP *cmap, l_int32 **prmap, l_int32 **pgmap, l_int32 **pbmap)
Definition: colormap.c:616
@ FALSE
Definition: dd.h:101
@ TRUE
Definition: dd.h:102
int w
Definition: dviconv.c:26
int h
Definition: dviconv.c:9
int strcmp()
Definition: coll.cpp:143
int sscanf()
struct rect data
Definition: dvipdfm.c:64
#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
unsigned int l_uint32
Definition: environ.h:33
unsigned char l_uint8
Definition: environ.h:29
#define L_WARNING(a, b)
Definition: environ.h:136
#define ERROR_INT(a, b, c)
Definition: environ.h:133
int l_int32
Definition: environ.h:32
double l_float64
Definition: environ.h:35
#define L_WARNING_INT(a, b, c)
Definition: environ.h:137
float l_float32
Definition: environ.h:34
#define d(n)
Definition: gpos-common.c:151
#define memcpy(d, s, n)
Definition: gsftopk.c:64
const unsigned char FREE
Definition: image.cpp:34
@ IFF_TIFF_G3
Definition: imageio.h:34
@ IFF_TIFF_PACKBITS
Definition: imageio.h:33
@ IFF_TIFF_G4
Definition: imageio.h:35
@ IFF_TIFF
Definition: imageio.h:32
pix
Definition: in_pcx.cpp:383
#define SEEK_SET
Definition: jmemansi.c:26
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p scientific i
Definition: afcover.h:80
int cmapsize
Definition: bmp.h:90
#define fclose
Definition: debug.h:100
#define lseek
Definition: win32lib.h:83
#define fileno
Definition: win32lib.h:72
static int ret
Definition: convert.c:72
#define fprintf
Definition: mendex.h:64
#define CALLOC(t, n)
Definition: hash.c:21
l_uint32 * pixGetData(PIX *pix)
Definition: pix1.c:793
l_int32 numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
Definition: numarray.c:484
void pixDestroy(PIX **ppix)
Definition: pix1.c:225
l_int32 pixEndianByteSwap(PIX *pix)
Definition: pix2.c:1969
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
Definition: sarray.c:485
l_int32 pixSetYRes(PIX *pix, l_uint32 res)
Definition: pix1.c:602
l_int32 findFileFormat(FILE *fp)
Definition: readfile.c:186
PIX * pixEndianByteSwapNew(PIX *pixs)
Definition: pix2.c:1910
l_int32 pixSetXRes(PIX *pix, l_uint32 res)
Definition: pix1.c:553
l_int32 pixGetWpl(PIX *pix)
Definition: pix1.c:477
PIX * pixInvert(PIX *pixd, PIX *pixs)
Definition: pix2.c:1188
l_int32 pixGetDepth(PIX *pix)
Definition: pix1.c:449
char * pixGetText(PIX *pix)
Definition: pix1.c:658
l_uint32 pixGetXRes(PIX *pix)
Definition: pix1.c:529
l_int32 numaGetCount(NUMA *na)
Definition: numarray.c:435
l_int32 pixSetColormap(PIX *pix, PIXCMAP *colormap)
Definition: pix1.c:778
l_int32 sarrayGetCount(SARRAY *sa)
Definition: sarray.c:436
PIXCMAP * pixGetColormap(PIX *pix)
Definition: pix1.c:766
l_uint32 pixGetYRes(PIX *pix)
Definition: pix1.c:541
FILE * fopenReadStream(const char *filename)
Definition: utils.c:992
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
Definition: pix1.c:90
l_int32 pixGetHeight(PIX *pix)
Definition: pix1.c:419
l_int32 pixGetWidth(PIX *pix)
Definition: pix1.c:389
TIFF * TIFFOpen(const char *name, const char *mode)
Definition: tif_acorn.c:438
TIFF * TIFFFdOpen(int fd, const char *name, const char *mode)
Definition: tif_acorn.c:418
int TIFFGetFieldDefaulted(TIFF *tif, ttag_t tag,...)
Definition: tif_aux.c:194
void TIFFClose(TIFF *tif)
Definition: tif_close.c:33
int TIFFSetField(TIFF *tif, ttag_t tag,...)
Definition: tif_dir.c:566
int TIFFGetField(TIFF *tif, ttag_t tag,...)
Definition: tif_dir.c:869
int TIFFReadDirectory(TIFF *tif)
Definition: tif_dirread.c:79
void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
Definition: tif_print.c:68
int TIFFReadScanline(TIFF *tif, tdata_t buf, uint32 row, tsample_t sample)
Definition: tif_read.c:95
tsize_t TIFFScanlineSize(TIFF *tif)
Definition: tif_strip.c:162
int TIFFWriteScanline(TIFF *tif, tdata_t buf, uint32 row, tsample_t sample)
Definition: tif_write.c:52
#define COMPRESSION_NONE
Definition: tiff.h:150
#define TIFFTAG_BITSPERSAMPLE
Definition: tiff.h:148
#define TIFFTAG_RESOLUTIONUNIT
Definition: tiff.h:238
#define COMPRESSION_CCITTFAX3
Definition: tiff.h:152
#define ORIENTATION_TOPLEFT
Definition: tiff.h:202
#define TIFFTAG_SAMPLESPERPIXEL
Definition: tiff.h:210
#define TIFFTAG_COLORMAP
Definition: tiff.h:257
#define TIFFTAG_PHOTOMETRIC
Definition: tiff.h:176
#define PHOTOMETRIC_PALETTE
Definition: tiff.h:180
#define TIFFTAG_IMAGEWIDTH
Definition: tiff.h:146
#define TIFFTAG_XRESOLUTION
Definition: tiff.h:215
#define TIFFTAG_ORIENTATION
Definition: tiff.h:201
#define COMPRESSION_PACKBITS
Definition: tiff.h:159
#define TIFFTAG_IMAGEDESCRIPTION
Definition: tiff.h:197
#define TIFFTAG_YRESOLUTION
Definition: tiff.h:216
#define PHOTOMETRIC_MINISWHITE
Definition: tiff.h:177
#define TIFFTAG_ROWSPERSTRIP
Definition: tiff.h:211
#define RESUNIT_INCH
Definition: tiff.h:240
#define TIFFTAG_IMAGELENGTH
Definition: tiff.h:147
#define TIFFTAG_COMPRESSION
Definition: tiff.h:149
#define PHOTOMETRIC_MINISBLACK
Definition: tiff.h:178
#define PHOTOMETRIC_RGB
Definition: tiff.h:179
#define TIFFTAG_PLANARCONFIG
Definition: tiff.h:217
#define COMPRESSION_CCITTFAX4
Definition: tiff.h:153
#define PLANARCONFIG_CONTIG
Definition: tiff.h:218
#define L_MIN
Definition: manifests.h:69
int k
Definition: otp-parser.c:70
static int xres
Definition: pbmto4425.c:21
static int yres
Definition: pbmto4425.c:22
char * filename[256]
Definition: pbmtopk.c:46
#define res(length)
Definition: picttoppm.c:287
@ COLOR_BLUE
Definition: pix.h:102
@ COLOR_RED
Definition: pix.h:100
@ COLOR_GREEN
Definition: pix.h:101
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF base if bpp PF set rept prefetch_distance PF set OFFSET endr endif endm macro preload_leading_step2 base if bpp ifc DST PF PF else if bpp lsl PF PF lsl PF PF lsl PF PF bpl
#define fp
static int size
Definition: ppmlabel.c:24
char line[1024]
Definition: process_score.c:29
char linebuf[12000]
Definition: spottopgm.c:21
Definition: array.h:38
Definition: pix.h:51
Definition: array.h:70
Definition: bdf.c:133
Definition: sh2.c:920
Definition: tiffiop.h:70
Definition: strexpr.c:21
#define FILE
Definition: t1stdio.h:34
int j
Definition: t4ht.c:1589
val
Definition: tex4ht.c:3227
l_int32 pixWriteStreamTiff(FILE *fp, PIX *pix, l_int32 comptype)
Definition: tiffio.c:397
static TIFF * fopenTiff(FILE *fp, const char *modestr)
Definition: tiffio.c:932
l_int32 readHeaderTiff(const char *filename, l_int32 *pwidth, l_int32 *pheight, l_int32 *pbps, l_int32 *pspp, l_int32 *pres, l_int32 *pcmap)
Definition: tiffio.c:820
l_int32 fprintTiffInfo(FILE *fpout, const char *tiffile)
Definition: tiffio.c:742
static l_int32 writeCustomTiffTags(TIFF *tif, NUMA *natags, SARRAY *savals, SARRAY *satypes, NUMA *nasizes)
Definition: tiffio.c:630
static l_int32 pixWriteToTiffStream(TIFF *tif, PIX *pix, l_int32 type, NUMA *natags, SARRAY *savals, SARRAY *satypes, NUMA *nasizes)
Definition: tiffio.c:451
l_int32 pixWriteTiffCustom(const char *filename, PIX *pix, l_int32 comptype, const char *modestring, NUMA *natags, SARRAY *savals, SARRAY *satypes, NUMA *nasizes)
Definition: tiffio.c:304
l_int32 freadHeaderTiff(FILE *fp, l_int32 *pwidth, l_int32 *pheight, l_int32 *pbps, l_int32 *pspp, l_int32 *pres, l_int32 *pcmap)
Definition: tiffio.c:863
static PIX * pixReadFromTiffStream(TIFF *tif)
Definition: tiffio.c:153
l_int32 tiffGetCount(FILE *fp, l_int32 *pn)
Definition: tiffio.c:775
PIX * pixReadStreamTiff(FILE *fp, l_int32 n)
Definition: tiffio.c:111
static const l_int32 DEFAULT_RESOLUTION
Definition: tiffio.c:49
PIX * pixReadTiff(const char *filename, l_int32 n)
Definition: tiffio.c:78
static const l_int32 MAX_PAGES_IN_TIFF_FILE
Definition: tiffio.c:50
l_int32 pixWriteTiff(const char *filename, PIX *pix, l_int32 comptype, const char *modestring)
Definition: tiffio.c:347
static unsigned short bps
Definition: tifftopnm.c:58
static unsigned short spp
Definition: tifftopnm.c:58
TT_CharMap cmap
Definition: ttf2pfb.c:163
#define ns
Definition: xmlparse.c:597