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