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