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