1 /* $Header: /cvsroot/osrs/libtiff/tools/tiffdump.c,v 1.3 2003/09/02 13:28:09 warmerda Exp $ */
2
3 /*
4 * Copyright (c) 1988-1997 Sam Leffler
5 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and
8 * its documentation for any purpose is hereby granted without fee, provided
9 * that (i) the above copyright notices and this permission notice appear in
10 * all copies of the software and related documentation, and (ii) the names of
11 * Sam Leffler and Silicon Graphics may not be used in any advertising or
12 * publicity relating to the software without the specific, prior written
13 * permission of Sam Leffler and Silicon Graphics.
14 *
15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
18 *
19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24 * OF THIS SOFTWARE.
25 */
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #if defined(VMS)
32 #include <unixio.h>
33 #include <file.h>
34 #elif defined(_WINDOWS)
35 #include <io.h>
36 #define off_t toff_t
37 #include "tiffio.h"
38 #include <fcntl.h>
39 #elif defined(applec)
40 #define open _open_ /* to avoid conflicts */
41 #include <fcntl.h>
42 #undef open
43 int open(const char*, int, int);
44 typedef unsigned int off_t;
45 #else /* !VMS && !_WINDOWS && !applec */
46 #ifdef unix
47 #include <sys/types.h>
48 #endif
49 #include <unistd.h>
50 #include <fcntl.h>
51 #endif
52
53 #if defined(MSDOS)
54 #include <malloc.h>
55 #endif
56
57 #ifndef O_BINARY
58 #define O_BINARY 0
59 #endif
60
61 #include "tiffio.h"
62
63 char* appname;
64 char* curfile;
65 int swabflag;
66 int bigendian;
67 int typeshift[13]; /* data type shift counts */
68 long typemask[13]; /* data type masks */
69 int maxitems = 24; /* maximum indirect data items to print */
70
71 char* bytefmt = "%s%#02x"; /* BYTE */
72 char* sbytefmt = "%s%d"; /* SBYTE */
73 char* shortfmt = "%s%u"; /* SHORT */
74 char* sshortfmt = "%s%d"; /* SSHORT */
75 char* longfmt = "%s%lu"; /* LONG */
76 char* slongfmt = "%s%ld"; /* SLONG */
77 char* rationalfmt = "%s%g"; /* RATIONAL */
78 char* srationalfmt = "%s%g"; /* SRATIONAL */
79 char* floatfmt = "%s%g"; /* FLOAT */
80 char* doublefmt = "%s%g"; /* DOUBLE */
81
82 static void dump(int, uint32);
83 extern int optind;
84 extern char* optarg;
85
86 void
usage()87 usage()
88 {
89 fprintf(stderr, "usage: %s [-h] [-o offset] [-m maxitems] file.tif ...\n", appname);
90 exit(-1);
91 }
92
93 int
main(int argc,char * argv[])94 main(int argc, char* argv[])
95 {
96 int one = 1, fd;
97 int multiplefiles = (argc > 1);
98 int c;
99 uint32 diroff = (uint32) 0;
100 bigendian = (*(char *)&one == 0);
101
102 appname = argv[0];
103 while ((c = getopt(argc, argv, "m:o:h")) != -1) {
104 switch (c) {
105 case 'h': /* print values in hex */
106 shortfmt = "%s%#x";
107 sshortfmt = "%s%#x";
108 longfmt = "%s%#lx";
109 slongfmt = "%s%#lx";
110 break;
111 case 'o':
112 diroff = (uint32) strtoul(optarg, NULL, 0);
113 break;
114 case 'm':
115 maxitems = strtoul(optarg, NULL, 0);
116 break;
117 default:
118 usage();
119 }
120 }
121 if (optind >= argc)
122 usage();
123 for (; optind < argc; optind++) {
124 fd = open(argv[optind], O_RDONLY|O_BINARY, 0);
125 if (fd < 0) {
126 perror(argv[0]);
127 return (-1);
128 }
129 if (multiplefiles)
130 printf("%s:\n", argv[optind]);
131 curfile = argv[optind];
132 swabflag = 0;
133 dump(fd, diroff);
134 close(fd);
135 }
136 return (0);
137 }
138
139 static TIFFHeader hdr;
140
141 #define ord(e) ((int)e)
142
143 /*
144 * Initialize shift & mask tables and byte
145 * swapping state according to the file
146 * byte order.
147 */
148 static void
InitByteOrder(int magic)149 InitByteOrder(int magic)
150 {
151 typemask[0] = 0;
152 typemask[ord(TIFF_BYTE)] = 0xff;
153 typemask[ord(TIFF_SBYTE)] = 0xff;
154 typemask[ord(TIFF_UNDEFINED)] = 0xff;
155 typemask[ord(TIFF_SHORT)] = 0xffff;
156 typemask[ord(TIFF_SSHORT)] = 0xffff;
157 typemask[ord(TIFF_LONG)] = 0xffffffff;
158 typemask[ord(TIFF_SLONG)] = 0xffffffff;
159 typemask[ord(TIFF_RATIONAL)] = 0xffffffff;
160 typemask[ord(TIFF_SRATIONAL)] = 0xffffffff;
161 typemask[ord(TIFF_FLOAT)] = 0xffffffff;
162 typemask[ord(TIFF_DOUBLE)] = 0xffffffff;
163 typeshift[0] = 0;
164 typeshift[ord(TIFF_LONG)] = 0;
165 typeshift[ord(TIFF_SLONG)] = 0;
166 typeshift[ord(TIFF_RATIONAL)] = 0;
167 typeshift[ord(TIFF_SRATIONAL)] = 0;
168 typeshift[ord(TIFF_FLOAT)] = 0;
169 typeshift[ord(TIFF_DOUBLE)] = 0;
170 if (magic == TIFF_BIGENDIAN) {
171 typeshift[ord(TIFF_BYTE)] = 24;
172 typeshift[ord(TIFF_SBYTE)] = 24;
173 typeshift[ord(TIFF_SHORT)] = 16;
174 typeshift[ord(TIFF_SSHORT)] = 16;
175 swabflag = !bigendian;
176 } else {
177 typeshift[ord(TIFF_BYTE)] = 0;
178 typeshift[ord(TIFF_SBYTE)] = 0;
179 typeshift[ord(TIFF_SHORT)] = 0;
180 typeshift[ord(TIFF_SSHORT)] = 0;
181 swabflag = bigendian;
182 }
183 }
184
185 static uint32 ReadDirectory(int, unsigned, uint32);
186 static void ReadError(char*);
187 static void Error(const char*, ...);
188 static void Fatal(const char*, ...);
189
190 static void
dump(int fd,uint32 diroff)191 dump(int fd, uint32 diroff)
192 {
193 unsigned i;
194
195 lseek(fd, (off_t) 0, 0);
196 if (read(fd, (char*) &hdr, sizeof (hdr)) != sizeof (hdr))
197 ReadError("TIFF header");
198 /*
199 * Setup the byte order handling.
200 */
201 if (hdr.tiff_magic != TIFF_BIGENDIAN && hdr.tiff_magic != TIFF_LITTLEENDIAN)
202 Fatal("Not a TIFF file, bad magic number %u (%#x)",
203 hdr.tiff_magic, hdr.tiff_magic);
204 InitByteOrder(hdr.tiff_magic);
205 /*
206 * Swap header if required.
207 */
208 if (swabflag) {
209 TIFFSwabShort(&hdr.tiff_version);
210 TIFFSwabLong(&hdr.tiff_diroff);
211 }
212 /*
213 * Now check version (if needed, it's been byte-swapped).
214 * Note that this isn't actually a version number, it's a
215 * magic number that doesn't change (stupid).
216 */
217 if (hdr.tiff_version != TIFF_VERSION)
218 Fatal("Not a TIFF file, bad version number %u (%#x)",
219 hdr.tiff_version, hdr.tiff_version);
220 printf("Magic: %#x <%s-endian> Version: %#x\n",
221 hdr.tiff_magic,
222 hdr.tiff_magic == TIFF_BIGENDIAN ? "big" : "little",
223 hdr.tiff_version);
224 if (diroff == 0)
225 diroff = hdr.tiff_diroff;
226 for (i = 0; diroff != 0; i++) {
227 if (i > 0)
228 putchar('\n');
229 diroff = ReadDirectory(fd, i, diroff);
230 }
231 }
232
233 static int datawidth[] = {
234 0, /* nothing */
235 1, /* TIFF_BYTE */
236 1, /* TIFF_ASCII */
237 2, /* TIFF_SHORT */
238 4, /* TIFF_LONG */
239 8, /* TIFF_RATIONAL */
240 1, /* TIFF_SBYTE */
241 1, /* TIFF_UNDEFINED */
242 2, /* TIFF_SSHORT */
243 4, /* TIFF_SLONG */
244 8, /* TIFF_SRATIONAL */
245 4, /* TIFF_FLOAT */
246 8, /* TIFF_DOUBLE */
247 };
248 #define NWIDTHS (sizeof (datawidth) / sizeof (datawidth[0]))
249 static int TIFFFetchData(int, TIFFDirEntry*, void*);
250 static void PrintTag(FILE*, uint16);
251 static void PrintType(FILE*, uint16);
252 static void PrintData(FILE*, uint16, uint32, unsigned char*);
253 static void PrintByte(FILE*, const char*, TIFFDirEntry*);
254 static void PrintShort(FILE*, const char*, TIFFDirEntry*);
255 static void PrintLong(FILE*, const char*, TIFFDirEntry*);
256
257 /*
258 * Read the next TIFF directory from a file
259 * and convert it to the internal format.
260 * We read directories sequentially.
261 */
262 static uint32
ReadDirectory(int fd,unsigned ix,uint32 off)263 ReadDirectory(int fd, unsigned ix, uint32 off)
264 {
265 register TIFFDirEntry *dp;
266 register int n;
267 TIFFDirEntry *dir = 0;
268 uint16 dircount;
269 int space;
270 uint32 nextdiroff = 0;
271
272 if (off == 0) /* no more directories */
273 goto done;
274 if (lseek(fd, (off_t) off, 0) != off) {
275 Fatal("Seek error accessing TIFF directory");
276 goto done;
277 }
278 if (read(fd, (char*) &dircount, sizeof (uint16)) != sizeof (uint16)) {
279 ReadError("directory count");
280 goto done;
281 }
282 if (swabflag)
283 TIFFSwabShort(&dircount);
284 dir = (TIFFDirEntry *)_TIFFmalloc(dircount * sizeof (TIFFDirEntry));
285 if (dir == NULL) {
286 Fatal("No space for TIFF directory");
287 goto done;
288 }
289 n = read(fd, (char*) dir, dircount*sizeof (*dp));
290 if (n != dircount*sizeof (*dp)) {
291 n /= sizeof (*dp);
292 Error(
293 "Could only read %u of %u entries in directory at offset %#lx",
294 n, dircount, (unsigned long) off);
295 dircount = n;
296 }
297 if (read(fd, (char*) &nextdiroff, sizeof (uint32)) != sizeof (uint32))
298 nextdiroff = 0;
299 if (swabflag)
300 TIFFSwabLong(&nextdiroff);
301 printf("Directory %u: offset %lu (%#lx) next %lu (%#lx)\n", ix,
302 (unsigned long) off, (unsigned long) off,
303 (unsigned long) nextdiroff, (unsigned long) nextdiroff);
304 for (dp = dir, n = dircount; n > 0; n--, dp++) {
305 if (swabflag) {
306 TIFFSwabArrayOfShort(&dp->tdir_tag, 2);
307 TIFFSwabArrayOfLong(&dp->tdir_count, 2);
308 }
309 PrintTag(stdout, dp->tdir_tag);
310 putchar(' ');
311 PrintType(stdout, dp->tdir_type);
312 putchar(' ');
313 printf("%lu<", (unsigned long) dp->tdir_count);
314 if (dp->tdir_type >= NWIDTHS) {
315 printf(">\n");
316 continue;
317 }
318 space = dp->tdir_count * datawidth[dp->tdir_type];
319 if (space <= 4) {
320 switch (dp->tdir_type) {
321 case TIFF_FLOAT:
322 case TIFF_UNDEFINED:
323 case TIFF_ASCII: {
324 unsigned char data[4];
325 _TIFFmemcpy(data, &dp->tdir_offset, 4);
326 if (swabflag)
327 TIFFSwabLong((uint32*) data);
328 PrintData(stdout,
329 dp->tdir_type, dp->tdir_count, data);
330 break;
331 }
332 case TIFF_BYTE:
333 PrintByte(stdout, bytefmt, dp);
334 break;
335 case TIFF_SBYTE:
336 PrintByte(stdout, sbytefmt, dp);
337 break;
338 case TIFF_SHORT:
339 PrintShort(stdout, shortfmt, dp);
340 break;
341 case TIFF_SSHORT:
342 PrintShort(stdout, sshortfmt, dp);
343 break;
344 case TIFF_LONG:
345 PrintLong(stdout, longfmt, dp);
346 break;
347 case TIFF_SLONG:
348 PrintLong(stdout, slongfmt, dp);
349 break;
350 }
351 } else {
352 unsigned char *data = (unsigned char *)_TIFFmalloc(space);
353 if (data) {
354 if (TIFFFetchData(fd, dp, data))
355 if (dp->tdir_count > maxitems) {
356 PrintData(stdout, dp->tdir_type,
357 maxitems, data);
358 printf(" ...");
359 } else
360 PrintData(stdout, dp->tdir_type,
361 dp->tdir_count, data);
362 _TIFFfree(data);
363 } else
364 Error("No space for data for tag %u",
365 dp->tdir_tag);
366 }
367 printf(">\n");
368 }
369 done:
370 if (dir)
371 _TIFFfree((char *)dir);
372 return (nextdiroff);
373 }
374
375 static struct tagname {
376 uint16 tag;
377 char* name;
378 } tagnames[] = {
379 { TIFFTAG_SUBFILETYPE, "SubFileType" },
380 { TIFFTAG_OSUBFILETYPE, "OldSubFileType" },
381 { TIFFTAG_IMAGEWIDTH, "ImageWidth" },
382 { TIFFTAG_IMAGELENGTH, "ImageLength" },
383 { TIFFTAG_BITSPERSAMPLE, "BitsPerSample" },
384 { TIFFTAG_COMPRESSION, "Compression" },
385 { TIFFTAG_PHOTOMETRIC, "Photometric" },
386 { TIFFTAG_THRESHHOLDING, "Threshholding" },
387 { TIFFTAG_CELLWIDTH, "CellWidth" },
388 { TIFFTAG_CELLLENGTH, "CellLength" },
389 { TIFFTAG_FILLORDER, "FillOrder" },
390 { TIFFTAG_DOCUMENTNAME, "DocumentName" },
391 { TIFFTAG_IMAGEDESCRIPTION, "ImageDescription" },
392 { TIFFTAG_MAKE, "Make" },
393 { TIFFTAG_MODEL, "Model" },
394 { TIFFTAG_STRIPOFFSETS, "StripOffsets" },
395 { TIFFTAG_ORIENTATION, "Orientation" },
396 { TIFFTAG_SAMPLESPERPIXEL, "SamplesPerPixel" },
397 { TIFFTAG_ROWSPERSTRIP, "RowsPerStrip" },
398 { TIFFTAG_STRIPBYTECOUNTS, "StripByteCounts" },
399 { TIFFTAG_MINSAMPLEVALUE, "MinSampleValue" },
400 { TIFFTAG_MAXSAMPLEVALUE, "MaxSampleValue" },
401 { TIFFTAG_XRESOLUTION, "XResolution" },
402 { TIFFTAG_YRESOLUTION, "YResolution" },
403 { TIFFTAG_PLANARCONFIG, "PlanarConfig" },
404 { TIFFTAG_PAGENAME, "PageName" },
405 { TIFFTAG_XPOSITION, "XPosition" },
406 { TIFFTAG_YPOSITION, "YPosition" },
407 { TIFFTAG_FREEOFFSETS, "FreeOffsets" },
408 { TIFFTAG_FREEBYTECOUNTS, "FreeByteCounts" },
409 { TIFFTAG_GRAYRESPONSEUNIT, "GrayResponseUnit" },
410 { TIFFTAG_GRAYRESPONSECURVE,"GrayResponseCurve" },
411 { TIFFTAG_GROUP3OPTIONS, "Group3Options" },
412 { TIFFTAG_GROUP4OPTIONS, "Group4Options" },
413 { TIFFTAG_RESOLUTIONUNIT, "ResolutionUnit" },
414 { TIFFTAG_PAGENUMBER, "PageNumber" },
415 { TIFFTAG_COLORRESPONSEUNIT,"ColorResponseUnit" },
416 { TIFFTAG_TRANSFERFUNCTION, "TransferFunction" },
417 { TIFFTAG_SOFTWARE, "Software" },
418 { TIFFTAG_DATETIME, "DateTime" },
419 { TIFFTAG_ARTIST, "Artist" },
420 { TIFFTAG_HOSTCOMPUTER, "HostComputer" },
421 { TIFFTAG_PREDICTOR, "Predictor" },
422 { TIFFTAG_WHITEPOINT, "Whitepoint" },
423 { TIFFTAG_PRIMARYCHROMATICITIES,"PrimaryChromaticities" },
424 { TIFFTAG_COLORMAP, "Colormap" },
425 { TIFFTAG_HALFTONEHINTS, "HalftoneHints" },
426 { TIFFTAG_TILEWIDTH, "TileWidth" },
427 { TIFFTAG_TILELENGTH, "TileLength" },
428 { TIFFTAG_TILEOFFSETS, "TileOffsets" },
429 { TIFFTAG_TILEBYTECOUNTS, "TileByteCounts" },
430 { TIFFTAG_BADFAXLINES, "BadFaxLines" },
431 { TIFFTAG_CLEANFAXDATA, "CleanFaxData" },
432 { TIFFTAG_CONSECUTIVEBADFAXLINES, "ConsecutiveBadFaxLines" },
433 { TIFFTAG_SUBIFD, "SubIFD" },
434 { TIFFTAG_INKSET, "InkSet" },
435 { TIFFTAG_INKNAMES, "InkNames" },
436 { TIFFTAG_NUMBEROFINKS, "NumberOfInks" },
437 { TIFFTAG_DOTRANGE, "DotRange" },
438 { TIFFTAG_TARGETPRINTER, "TargetPrinter" },
439 { TIFFTAG_EXTRASAMPLES, "ExtraSamples" },
440 { TIFFTAG_SAMPLEFORMAT, "SampleFormat" },
441 { TIFFTAG_SMINSAMPLEVALUE, "SMinSampleValue" },
442 { TIFFTAG_SMAXSAMPLEVALUE, "SMaxSampleValue" },
443 { TIFFTAG_JPEGPROC, "JPEGProcessingMode" },
444 { TIFFTAG_JPEGIFOFFSET, "JPEGInterchangeFormat" },
445 { TIFFTAG_JPEGIFBYTECOUNT, "JPEGInterchangeFormatLength" },
446 { TIFFTAG_JPEGRESTARTINTERVAL,"JPEGRestartInterval" },
447 { TIFFTAG_JPEGLOSSLESSPREDICTORS,"JPEGLosslessPredictors" },
448 { TIFFTAG_JPEGPOINTTRANSFORM,"JPEGPointTransform" },
449 { TIFFTAG_JPEGTABLES, "JPEGTables" },
450 { TIFFTAG_JPEGQTABLES, "JPEGQTables" },
451 { TIFFTAG_JPEGDCTABLES, "JPEGDCTables" },
452 { TIFFTAG_JPEGACTABLES, "JPEGACTables" },
453 { TIFFTAG_YCBCRCOEFFICIENTS,"YCbCrCoefficients" },
454 { TIFFTAG_YCBCRSUBSAMPLING, "YCbCrSubsampling" },
455 { TIFFTAG_YCBCRPOSITIONING, "YCbCrPositioning" },
456 { TIFFTAG_REFERENCEBLACKWHITE, "ReferenceBlackWhite" },
457 { TIFFTAG_REFPTS, "IgReferencePoints (Island Graphics)" },
458 { TIFFTAG_REGIONTACKPOINT, "IgRegionTackPoint (Island Graphics)" },
459 { TIFFTAG_REGIONWARPCORNERS,"IgRegionWarpCorners (Island Graphics)" },
460 { TIFFTAG_REGIONAFFINE, "IgRegionAffine (Island Graphics)" },
461 { TIFFTAG_MATTEING, "OBSOLETE Matteing (Silicon Graphics)" },
462 { TIFFTAG_DATATYPE, "OBSOLETE DataType (Silicon Graphics)" },
463 { TIFFTAG_IMAGEDEPTH, "ImageDepth (Silicon Graphics)" },
464 { TIFFTAG_TILEDEPTH, "TileDepth (Silicon Graphics)" },
465 { 32768, "OLD BOGUS Matteing tag" },
466 { TIFFTAG_COPYRIGHT, "Copyright" },
467 { TIFFTAG_ICCPROFILE, "ICC Profile" },
468 { TIFFTAG_JBIGOPTIONS, "JBIG Options" },
469 { TIFFTAG_STONITS, "StoNits" },
470 };
471 #define NTAGS (sizeof (tagnames) / sizeof (tagnames[0]))
472
473 static void
PrintTag(FILE * fd,uint16 tag)474 PrintTag(FILE* fd, uint16 tag)
475 {
476 register struct tagname *tp;
477
478 for (tp = tagnames; tp < &tagnames[NTAGS]; tp++)
479 if (tp->tag == tag) {
480 fprintf(fd, "%s (%u)", tp->name, tag);
481 return;
482 }
483 fprintf(fd, "%u (%#x)", tag, tag);
484 }
485
486 static void
PrintType(FILE * fd,uint16 type)487 PrintType(FILE* fd, uint16 type)
488 {
489 static char *typenames[] = {
490 "0",
491 "BYTE",
492 "ASCII",
493 "SHORT",
494 "LONG",
495 "RATIONAL",
496 "SBYTE",
497 "UNDEFINED",
498 "SSHORT",
499 "SLONG",
500 "SRATIONAL",
501 "FLOAT",
502 "DOUBLE"
503 };
504 #define NTYPES (sizeof (typenames) / sizeof (typenames[0]))
505
506 if (type < NTYPES)
507 fprintf(fd, "%s (%u)", typenames[type], type);
508 else
509 fprintf(fd, "%u (%#x)", type, type);
510 }
511 #undef NTYPES
512
513 static void
PrintByte(FILE * fd,const char * fmt,TIFFDirEntry * dp)514 PrintByte(FILE* fd, const char* fmt, TIFFDirEntry* dp)
515 {
516 char* sep = "";
517
518 if (hdr.tiff_magic != TIFF_LITTLEENDIAN) {
519 switch ((int)dp->tdir_count) {
520 case 4: fprintf(fd, fmt, sep, dp->tdir_offset&0xff);
521 sep = " ";
522 case 3: fprintf(fd, fmt, sep, (dp->tdir_offset>>8)&0xff);
523 sep = " ";
524 case 2: fprintf(fd, fmt, sep, (dp->tdir_offset>>16)&0xff);
525 sep = " ";
526 case 1: fprintf(fd, fmt, sep, dp->tdir_offset>>24);
527 }
528 } else {
529 switch ((int)dp->tdir_count) {
530 case 4: fprintf(fd, fmt, sep, dp->tdir_offset>>24);
531 sep = " ";
532 case 3: fprintf(fd, fmt, sep, (dp->tdir_offset>>16)&0xff);
533 sep = " ";
534 case 2: fprintf(fd, fmt, sep, (dp->tdir_offset>>8)&0xff);
535 sep = " ";
536 case 1: fprintf(fd, fmt, sep, dp->tdir_offset&0xff);
537 }
538 }
539 }
540
541 static void
PrintShort(FILE * fd,const char * fmt,TIFFDirEntry * dp)542 PrintShort(FILE* fd, const char* fmt, TIFFDirEntry* dp)
543 {
544 char *sep = "";
545
546 if (hdr.tiff_magic != TIFF_LITTLEENDIAN) {
547 switch (dp->tdir_count) {
548 case 2: fprintf(fd, fmt, sep, dp->tdir_offset&0xffff);
549 sep = " ";
550 case 1: fprintf(fd, fmt, sep, dp->tdir_offset>>16);
551 }
552 } else {
553 switch (dp->tdir_count) {
554 case 2: fprintf(fd, fmt, sep, dp->tdir_offset>>16);
555 sep = " ";
556 case 1: fprintf(fd, fmt, sep, dp->tdir_offset&0xffff);
557 }
558 }
559 }
560
561 static void
PrintLong(FILE * fd,const char * fmt,TIFFDirEntry * dp)562 PrintLong(FILE* fd, const char* fmt, TIFFDirEntry* dp)
563 {
564 fprintf(fd, fmt, "", (long) dp->tdir_offset);
565 }
566
567 #include <ctype.h>
568
569 static void
PrintASCII(FILE * fd,uint32 cc,const unsigned char * cp)570 PrintASCII(FILE* fd, uint32 cc, const unsigned char* cp)
571 {
572 for (; cc > 0; cc--, cp++) {
573 const char* tp;
574
575 if (isprint(*cp)) {
576 fputc(*cp, fd);
577 continue;
578 }
579 for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++)
580 if (*tp++ == *cp)
581 break;
582 if (*tp)
583 fprintf(fd, "\\%c", *tp);
584 else if (*cp)
585 fprintf(fd, "\\%03o", *cp);
586 else
587 fprintf(fd, "\\0");
588 }
589 }
590
591 static void
PrintData(FILE * fd,uint16 type,uint32 count,unsigned char * data)592 PrintData(FILE* fd, uint16 type, uint32 count, unsigned char* data)
593 {
594 char* sep = "";
595
596 switch (type) {
597 case TIFF_BYTE:
598 while (count-- > 0)
599 fprintf(fd, bytefmt, sep, *data++), sep = " ";
600 break;
601 case TIFF_SBYTE:
602 while (count-- > 0)
603 fprintf(fd, sbytefmt, sep, *(char *)data++), sep = " ";
604 break;
605 case TIFF_UNDEFINED:
606 while (count-- > 0)
607 fprintf(fd, bytefmt, sep, *data++), sep = " ";
608 break;
609 case TIFF_ASCII:
610 PrintASCII(fd, count, data);
611 break;
612 case TIFF_SHORT: {
613 register uint16 *wp = (uint16*)data;
614 while (count-- > 0)
615 fprintf(fd, shortfmt, sep, *wp++), sep = " ";
616 break;
617 }
618 case TIFF_SSHORT: {
619 register int16 *wp = (int16*)data;
620 while (count-- > 0)
621 fprintf(fd, sshortfmt, sep, *wp++), sep = " ";
622 break;
623 }
624 case TIFF_LONG: {
625 register uint32 *lp = (uint32*)data;
626 while (count-- > 0) {
627 fprintf(fd, longfmt, sep, (unsigned long) *lp++);
628 sep = " ";
629 }
630 break;
631 }
632 case TIFF_SLONG: {
633 register int32 *lp = (int32*)data;
634 while (count-- > 0)
635 fprintf(fd, slongfmt, sep, (long) *lp++), sep = " ";
636 break;
637 }
638 case TIFF_RATIONAL: {
639 register uint32 *lp = (uint32*)data;
640 while (count-- > 0) {
641 if (lp[1] == 0)
642 fprintf(fd, "%sNan (%lu/%lu)", sep,
643 (unsigned long) lp[0],
644 (unsigned long) lp[1]);
645 else
646 fprintf(fd, rationalfmt, sep,
647 (double)lp[0] / (double)lp[1]);
648 sep = " ";
649 lp += 2;
650 }
651 break;
652 }
653 case TIFF_SRATIONAL: {
654 register int32 *lp = (int32*)data;
655 while (count-- > 0) {
656 if (lp[1] == 0)
657 fprintf(fd, "%sNan (%ld/%ld)", sep,
658 (long) lp[0], (long) lp[1]);
659 else
660 fprintf(fd, srationalfmt, sep,
661 (double)lp[0] / (double)lp[1]);
662 sep = " ";
663 lp += 2;
664 }
665 break;
666 }
667 case TIFF_FLOAT: {
668 register float *fp = (float *)data;
669 while (count-- > 0)
670 fprintf(fd, floatfmt, sep, *fp++), sep = " ";
671 break;
672 }
673 case TIFF_DOUBLE: {
674 register double *dp = (double *)data;
675 while (count-- > 0)
676 fprintf(fd, doublefmt, sep, *dp++), sep = " ";
677 break;
678 }
679 }
680 }
681
682 /*
683 * Fetch a contiguous directory item.
684 */
685 static int
TIFFFetchData(int fd,TIFFDirEntry * dir,void * cp)686 TIFFFetchData(int fd, TIFFDirEntry* dir, void* cp)
687 {
688 int cc, w;
689
690 w = (dir->tdir_type < NWIDTHS ? datawidth[dir->tdir_type] : 0);
691 cc = dir->tdir_count * w;
692 if (lseek(fd, (off_t) dir->tdir_offset, 0) == dir->tdir_offset &&
693 read(fd, cp, cc) == cc) {
694 if (swabflag) {
695 switch (dir->tdir_type) {
696 case TIFF_SHORT:
697 case TIFF_SSHORT:
698 TIFFSwabArrayOfShort((uint16*) cp,
699 dir->tdir_count);
700 break;
701 case TIFF_LONG:
702 case TIFF_SLONG:
703 case TIFF_FLOAT:
704 TIFFSwabArrayOfLong((uint32*) cp,
705 dir->tdir_count);
706 break;
707 case TIFF_RATIONAL:
708 TIFFSwabArrayOfLong((uint32*) cp,
709 2*dir->tdir_count);
710 break;
711 case TIFF_DOUBLE:
712 TIFFSwabArrayOfDouble((double*) cp,
713 dir->tdir_count);
714 break;
715 }
716 }
717 return (cc);
718 }
719 Error("Error while reading data for tag %u", dir->tdir_tag);
720 return (0);
721 }
722
723 static void
ReadError(char * what)724 ReadError(char* what)
725 {
726 Fatal("Error while reading %s", what);
727 }
728
729 #include <stdarg.h>
730
731 static void
vError(FILE * fd,const char * fmt,va_list ap)732 vError(FILE* fd, const char* fmt, va_list ap)
733 {
734 fprintf(fd, "%s: ", curfile);
735 vfprintf(fd, fmt, ap);
736 fprintf(fd, ".\n");
737 }
738
739 static void
Error(const char * fmt,...)740 Error(const char* fmt, ...)
741 {
742 va_list ap;
743 va_start(ap, fmt);
744 vError(stderr, fmt, ap);
745 va_end(ap);
746 }
747
748 static void
Fatal(const char * fmt,...)749 Fatal(const char* fmt, ...)
750 {
751 va_list ap;
752 va_start(ap, fmt);
753 vError(stderr, fmt, ap);
754 va_end(ap);
755 exit(-1);
756 }
757