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