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