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