summaryrefslogtreecommitdiff
path: root/tiff/tools/tiffdump.c
diff options
context:
space:
mode:
Diffstat (limited to 'tiff/tools/tiffdump.c')
-rwxr-xr-xtiff/tools/tiffdump.c895
1 files changed, 895 insertions, 0 deletions
diff --git a/tiff/tools/tiffdump.c b/tiff/tools/tiffdump.c
new file mode 100755
index 0000000..f490d85
--- /dev/null
+++ b/tiff/tools/tiffdump.c
@@ -0,0 +1,895 @@
+/* $Id: tiffdump.c,v 1.30 2014-12-22 02:52:38 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include "tif_config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include "tiffiop.h"
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#ifdef HAVE_IO_H
+# include <io.h>
+#endif
+
+#ifdef NEED_LIBPORT
+# include "libport.h"
+#endif
+
+#ifndef HAVE_GETOPT
+extern int getopt(int, char**, char*);
+#endif
+
+#include "tiffio.h"
+
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
+
+static union
+{
+ TIFFHeaderClassic classic;
+ TIFFHeaderBig big;
+ TIFFHeaderCommon common;
+} hdr;
+char* appname;
+char* curfile;
+int swabflag;
+int bigendian;
+int bigtiff;
+uint32 maxitems = 24; /* maximum indirect data items to print */
+
+const char* bytefmt = "%s%#02x"; /* BYTE */
+const char* sbytefmt = "%s%d"; /* SBYTE */
+const char* shortfmt = "%s%u"; /* SHORT */
+const char* sshortfmt = "%s%d"; /* SSHORT */
+const char* longfmt = "%s%lu"; /* LONG */
+const char* slongfmt = "%s%ld"; /* SLONG */
+const char* ifdfmt = "%s%#04lx"; /* IFD offset */
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+const char* long8fmt = "%s%I64u"; /* LONG8 */
+const char* slong8fmt = "%s%I64d"; /* SLONG8 */
+const char* ifd8fmt = "%s%#08I64x"; /* IFD offset8*/
+#else
+const char* long8fmt = "%s%llu"; /* LONG8 */
+const char* slong8fmt = "%s%lld"; /* SLONG8 */
+const char* ifd8fmt = "%s%#08llx"; /* IFD offset8*/
+#endif
+const char* rationalfmt = "%s%g"; /* RATIONAL */
+const char* srationalfmt = "%s%g"; /* SRATIONAL */
+const char* floatfmt = "%s%g"; /* FLOAT */
+const char* doublefmt = "%s%g"; /* DOUBLE */
+
+static void dump(int, uint64);
+extern int optind;
+extern char* optarg;
+
+void
+usage()
+{
+ fprintf(stderr, "usage: %s [-h] [-o offset] [-m maxitems] file.tif ...\n", appname);
+ exit(-1);
+}
+
+int
+main(int argc, char* argv[])
+{
+ int one = 1, fd;
+ int multiplefiles = (argc > 1);
+ int c;
+ uint64 diroff = 0;
+ bigendian = (*(char *)&one == 0);
+
+ appname = argv[0];
+ while ((c = getopt(argc, argv, "m:o:h")) != -1) {
+ switch (c) {
+ case 'h': /* print values in hex */
+ shortfmt = "%s%#x";
+ sshortfmt = "%s%#x";
+ longfmt = "%s%#lx";
+ slongfmt = "%s%#lx";
+ break;
+ case 'o':
+ diroff = (uint64) strtoul(optarg, NULL, 0);
+ break;
+ case 'm':
+ maxitems = strtoul(optarg, NULL, 0);
+ break;
+ default:
+ usage();
+ }
+ }
+ if (optind >= argc)
+ usage();
+ for (; optind < argc; optind++) {
+ fd = open(argv[optind], O_RDONLY|O_BINARY, 0);
+ if (fd < 0) {
+ perror(argv[0]);
+ return (-1);
+ }
+ if (multiplefiles)
+ printf("%s:\n", argv[optind]);
+ curfile = argv[optind];
+ swabflag = 0;
+ bigtiff = 0;
+ dump(fd, diroff);
+ close(fd);
+ }
+ return (0);
+}
+
+#define ord(e) ((int)e)
+
+static uint64 ReadDirectory(int, unsigned, uint64);
+static void ReadError(char*);
+static void Error(const char*, ...);
+static void Fatal(const char*, ...);
+
+static void
+dump(int fd, uint64 diroff)
+{
+ unsigned i, j;
+ uint64* visited_diroff = NULL;
+ unsigned int count_visited_dir = 0;
+
+ lseek(fd, (off_t) 0, 0);
+ if (read(fd, (char*) &hdr, sizeof (TIFFHeaderCommon)) != sizeof (TIFFHeaderCommon))
+ ReadError("TIFF header");
+ if (hdr.common.tiff_magic != TIFF_BIGENDIAN
+ && hdr.common.tiff_magic != TIFF_LITTLEENDIAN &&
+#if HOST_BIGENDIAN
+ /* MDI is sensitive to the host byte order, unlike TIFF */
+ MDI_BIGENDIAN != hdr.common.tiff_magic
+#else
+ MDI_LITTLEENDIAN != hdr.common.tiff_magic
+#endif
+ ) {
+ Fatal("Not a TIFF or MDI file, bad magic number %u (%#x)",
+ hdr.common.tiff_magic, hdr.common.tiff_magic);
+ }
+ if (hdr.common.tiff_magic == TIFF_BIGENDIAN
+ || hdr.common.tiff_magic == MDI_BIGENDIAN)
+ swabflag = !bigendian;
+ else
+ swabflag = bigendian;
+ if (swabflag)
+ TIFFSwabShort(&hdr.common.tiff_version);
+ if (hdr.common.tiff_version==42)
+ {
+ if (read(fd, (char*) &hdr.classic.tiff_diroff, 4) != 4)
+ ReadError("TIFF header");
+ if (swabflag)
+ TIFFSwabLong(&hdr.classic.tiff_diroff);
+ printf("Magic: %#x <%s-endian> Version: %#x <%s>\n",
+ hdr.classic.tiff_magic,
+ hdr.classic.tiff_magic == TIFF_BIGENDIAN ? "big" : "little",
+ 42,"ClassicTIFF");
+ if (diroff == 0)
+ diroff = hdr.classic.tiff_diroff;
+ }
+ else if (hdr.common.tiff_version==43)
+ {
+ if (read(fd, (char*) &hdr.big.tiff_offsetsize, 12) != 12)
+ ReadError("TIFF header");
+ if (swabflag)
+ {
+ TIFFSwabShort(&hdr.big.tiff_offsetsize);
+ TIFFSwabShort(&hdr.big.tiff_unused);
+ TIFFSwabLong8(&hdr.big.tiff_diroff);
+ }
+ printf("Magic: %#x <%s-endian> Version: %#x <%s>\n",
+ hdr.big.tiff_magic,
+ hdr.big.tiff_magic == TIFF_BIGENDIAN ? "big" : "little",
+ 43,"BigTIFF");
+ printf("OffsetSize: %#x Unused: %#x\n",
+ hdr.big.tiff_offsetsize,hdr.big.tiff_unused);
+ if (diroff == 0)
+ diroff = hdr.big.tiff_diroff;
+ bigtiff = 1;
+ }
+ else
+ Fatal("Not a TIFF file, bad version number %u (%#x)",
+ hdr.common.tiff_version, hdr.common.tiff_version);
+ for (i = 0; diroff != 0; i++) {
+ for(j=0; j<count_visited_dir; j++)
+ {
+ if( visited_diroff[j] == diroff )
+ {
+ free(visited_diroff);
+ Fatal("Cycle detected in chaining of TIFF directories!");
+ }
+ }
+ {
+ size_t alloc_size;
+ alloc_size=TIFFSafeMultiply(tmsize_t,(count_visited_dir + 1),
+ sizeof(uint64));
+ if (alloc_size == 0)
+ {
+ if (visited_diroff)
+ free(visited_diroff);
+ visited_diroff = 0;
+ }
+ else
+ {
+ visited_diroff = (uint64*) realloc(visited_diroff,alloc_size);
+ }
+ }
+ if( !visited_diroff )
+ Fatal("Out of memory");
+ visited_diroff[count_visited_dir] = diroff;
+ count_visited_dir ++;
+
+ if (i > 0)
+ putchar('\n');
+ diroff = ReadDirectory(fd, i, diroff);
+ }
+ if( visited_diroff )
+ free(visited_diroff);
+}
+
+static const int datawidth[] = {
+ 0, /* 00 = undefined */
+ 1, /* 01 = TIFF_BYTE */
+ 1, /* 02 = TIFF_ASCII */
+ 2, /* 03 = TIFF_SHORT */
+ 4, /* 04 = TIFF_LONG */
+ 8, /* 05 = TIFF_RATIONAL */
+ 1, /* 06 = TIFF_SBYTE */
+ 1, /* 07 = TIFF_UNDEFINED */
+ 2, /* 08 = TIFF_SSHORT */
+ 4, /* 09 = TIFF_SLONG */
+ 8, /* 10 = TIFF_SRATIONAL */
+ 4, /* 11 = TIFF_FLOAT */
+ 8, /* 12 = TIFF_DOUBLE */
+ 4, /* 13 = TIFF_IFD */
+ 0, /* 14 = undefined */
+ 0, /* 15 = undefined */
+ 8, /* 16 = TIFF_LONG8 */
+ 8, /* 17 = TIFF_SLONG8 */
+ 8, /* 18 = TIFF_IFD8 */
+};
+#define NWIDTHS (sizeof (datawidth) / sizeof (datawidth[0]))
+static void PrintTag(FILE*, uint16);
+static void PrintType(FILE*, uint16);
+static void PrintData(FILE*, uint16, uint32, unsigned char*);
+
+/*
+ * Read the next TIFF directory from a file
+ * and convert it to the internal format.
+ * We read directories sequentially.
+ */
+static uint64
+ReadDirectory(int fd, unsigned int ix, uint64 off)
+{
+ uint16 dircount;
+ uint32 direntrysize;
+ void* dirmem = NULL;
+ uint64 nextdiroff = 0;
+ uint32 n;
+ uint8* dp;
+
+ if (off == 0) /* no more directories */
+ goto done;
+#if defined(__WIN32__) && defined(_MSC_VER)
+ if (_lseeki64(fd, (__int64)off, SEEK_SET) != (__int64)off) {
+#else
+ if (lseek(fd, (off_t)off, SEEK_SET) != (off_t)off) {
+#endif
+ Fatal("Seek error accessing TIFF directory");
+ goto done;
+ }
+ if (!bigtiff) {
+ if (read(fd, (char*) &dircount, sizeof (uint16)) != sizeof (uint16)) {
+ ReadError("directory count");
+ goto done;
+ }
+ if (swabflag)
+ TIFFSwabShort(&dircount);
+ direntrysize = 12;
+ } else {
+ uint64 dircount64 = 0;
+ if (read(fd, (char*) &dircount64, sizeof (uint64)) != sizeof (uint64)) {
+ ReadError("directory count");
+ goto done;
+ }
+ if (swabflag)
+ TIFFSwabLong8(&dircount64);
+ if (dircount64>0xFFFF) {
+ Error("Sanity check on directory count failed");
+ goto done;
+ }
+ dircount = (uint16)dircount64;
+ direntrysize = 20;
+ }
+ dirmem = _TIFFmalloc(TIFFSafeMultiply(tmsize_t,dircount,direntrysize));
+ if (dirmem == NULL) {
+ Fatal("No space for TIFF directory");
+ goto done;
+ }
+ n = read(fd, (char*) dirmem, dircount*direntrysize);
+ if (n != dircount*direntrysize) {
+ n /= direntrysize;
+ Error(
+#if defined(__WIN32__) && defined(_MSC_VER)
+ "Could only read %lu of %u entries in directory at offset %#I64x",
+ (unsigned long)n, dircount, (unsigned __int64) off);
+#else
+ "Could only read %lu of %u entries in directory at offset %#llx",
+ (unsigned long)n, dircount, (unsigned long long) off);
+#endif
+ dircount = n;
+ nextdiroff = 0;
+ } else {
+ if (!bigtiff) {
+ uint32 nextdiroff32;
+ if (read(fd, (char*) &nextdiroff32, sizeof (uint32)) != sizeof (uint32))
+ nextdiroff32 = 0;
+ if (swabflag)
+ TIFFSwabLong(&nextdiroff32);
+ nextdiroff = nextdiroff32;
+ } else {
+ if (read(fd, (char*) &nextdiroff, sizeof (uint64)) != sizeof (uint64))
+ nextdiroff = 0;
+ if (swabflag)
+ TIFFSwabLong8(&nextdiroff);
+ }
+ }
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ printf("Directory %u: offset %I64u (%#I64x) next %I64u (%#I64x)\n", ix,
+ (unsigned __int64)off, (unsigned __int64)off,
+ (unsigned __int64)nextdiroff, (unsigned __int64)nextdiroff);
+#else
+ printf("Directory %u: offset %llu (%#llx) next %llu (%#llx)\n", ix,
+ (unsigned long long)off, (unsigned long long)off,
+ (unsigned long long)nextdiroff, (unsigned long long)nextdiroff);
+#endif
+ for (dp = (uint8*)dirmem, n = dircount; n > 0; n--) {
+ uint16 tag;
+ uint16 type;
+ uint16 typewidth;
+ uint64 count;
+ uint64 datasize;
+ int datafits;
+ void* datamem;
+ uint64 dataoffset;
+ int datatruncated;
+ int datasizeoverflow;
+
+ tag = *(uint16*)dp;
+ if (swabflag)
+ TIFFSwabShort(&tag);
+ dp += sizeof(uint16);
+ type = *(uint16*)dp;
+ dp += sizeof(uint16);
+ if (swabflag)
+ TIFFSwabShort(&type);
+ PrintTag(stdout, tag);
+ putchar(' ');
+ PrintType(stdout, type);
+ putchar(' ');
+ if (!bigtiff)
+ {
+ uint32 count32;
+ count32 = *(uint32*)dp;
+ if (swabflag)
+ TIFFSwabLong(&count32);
+ dp += sizeof(uint32);
+ count = count32;
+ }
+ else
+ {
+ count = *(uint64*)dp;
+ if (swabflag)
+ TIFFSwabLong8(&count);
+ dp += sizeof(uint64);
+ }
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ printf("%I64u<", (unsigned __int64)count);
+#else
+ printf("%llu<", (unsigned long long)count);
+#endif
+ if (type >= NWIDTHS)
+ typewidth = 0;
+ else
+ typewidth = datawidth[type];
+ datasize = count*typewidth;
+ datasizeoverflow = (typewidth > 0 && datasize / typewidth != count);
+ datafits = 1;
+ datamem = dp;
+ dataoffset = 0;
+ datatruncated = 0;
+ if (!bigtiff)
+ {
+ if (datasizeoverflow || datasize>4)
+ {
+ uint32 dataoffset32;
+ datafits = 0;
+ datamem = NULL;
+ dataoffset32 = *(uint32*)dp;
+ if (swabflag)
+ TIFFSwabLong(&dataoffset32);
+ dataoffset = dataoffset32;
+ }
+ dp += sizeof(uint32);
+ }
+ else
+ {
+ if (datasizeoverflow || datasize>8)
+ {
+ datafits = 0;
+ datamem = NULL;
+ dataoffset = *(uint64*)dp;
+ if (swabflag)
+ TIFFSwabLong8(&dataoffset);
+ }
+ dp += sizeof(uint64);
+ }
+ if (datasizeoverflow || datasize>0x10000)
+ {
+ datatruncated = 1;
+ count = 0x10000/typewidth;
+ datasize = count*typewidth;
+ }
+ if (count>maxitems)
+ {
+ datatruncated = 1;
+ count = maxitems;
+ datasize = count*typewidth;
+ }
+ if (!datafits)
+ {
+ datamem = _TIFFmalloc((uint32)datasize);
+ if (datamem) {
+#if defined(__WIN32__) && defined(_MSC_VER)
+ if (_lseeki64(fd, (__int64)dataoffset, SEEK_SET)
+ != (__int64)dataoffset)
+#else
+ if (lseek(fd, (off_t)dataoffset, 0) !=
+ (off_t)dataoffset)
+#endif
+ {
+ Error(
+ "Seek error accessing tag %u value", tag);
+ _TIFFfree(datamem);
+ datamem = NULL;
+ }
+ else if (read(fd, datamem, (size_t)datasize) != (TIFF_SSIZE_T)datasize)
+ {
+ Error(
+ "Read error accessing tag %u value", tag);
+ _TIFFfree(datamem);
+ datamem = NULL;
+ }
+ } else
+ Error("No space for data for tag %u",tag);
+ }
+ if (datamem)
+ {
+ if (swabflag)
+ {
+ switch (type)
+ {
+ case TIFF_BYTE:
+ case TIFF_ASCII:
+ case TIFF_SBYTE:
+ case TIFF_UNDEFINED:
+ break;
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ TIFFSwabArrayOfShort((uint16*)datamem,(tmsize_t)count);
+ break;
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_FLOAT:
+ case TIFF_IFD:
+ TIFFSwabArrayOfLong((uint32*)datamem,(tmsize_t)count);
+ break;
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ TIFFSwabArrayOfLong((uint32*)datamem,(tmsize_t)count*2);
+ break;
+ case TIFF_DOUBLE:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ case TIFF_IFD8:
+ TIFFSwabArrayOfLong8((uint64*)datamem,(tmsize_t)count);
+ break;
+ }
+ }
+ PrintData(stdout,type,(uint32)count,datamem);
+ if (datatruncated)
+ printf(" ...");
+ if (!datafits)
+ {
+ _TIFFfree(datamem);
+ datamem = NULL;
+ }
+ }
+ printf(">\n");
+ }
+done:
+ if (dirmem)
+ _TIFFfree((char *)dirmem);
+ return (nextdiroff);
+}
+
+static const struct tagname {
+ uint16 tag;
+ const char* name;
+} tagnames[] = {
+ { TIFFTAG_SUBFILETYPE, "SubFileType" },
+ { TIFFTAG_OSUBFILETYPE, "OldSubFileType" },
+ { TIFFTAG_IMAGEWIDTH, "ImageWidth" },
+ { TIFFTAG_IMAGELENGTH, "ImageLength" },
+ { TIFFTAG_BITSPERSAMPLE, "BitsPerSample" },
+ { TIFFTAG_COMPRESSION, "Compression" },
+ { TIFFTAG_PHOTOMETRIC, "Photometric" },
+ { TIFFTAG_THRESHHOLDING, "Threshholding" },
+ { TIFFTAG_CELLWIDTH, "CellWidth" },
+ { TIFFTAG_CELLLENGTH, "CellLength" },
+ { TIFFTAG_FILLORDER, "FillOrder" },
+ { TIFFTAG_DOCUMENTNAME, "DocumentName" },
+ { TIFFTAG_IMAGEDESCRIPTION, "ImageDescription" },
+ { TIFFTAG_MAKE, "Make" },
+ { TIFFTAG_MODEL, "Model" },
+ { TIFFTAG_STRIPOFFSETS, "StripOffsets" },
+ { TIFFTAG_ORIENTATION, "Orientation" },
+ { TIFFTAG_SAMPLESPERPIXEL, "SamplesPerPixel" },
+ { TIFFTAG_ROWSPERSTRIP, "RowsPerStrip" },
+ { TIFFTAG_STRIPBYTECOUNTS, "StripByteCounts" },
+ { TIFFTAG_MINSAMPLEVALUE, "MinSampleValue" },
+ { TIFFTAG_MAXSAMPLEVALUE, "MaxSampleValue" },
+ { TIFFTAG_XRESOLUTION, "XResolution" },
+ { TIFFTAG_YRESOLUTION, "YResolution" },
+ { TIFFTAG_PLANARCONFIG, "PlanarConfig" },
+ { TIFFTAG_PAGENAME, "PageName" },
+ { TIFFTAG_XPOSITION, "XPosition" },
+ { TIFFTAG_YPOSITION, "YPosition" },
+ { TIFFTAG_FREEOFFSETS, "FreeOffsets" },
+ { TIFFTAG_FREEBYTECOUNTS, "FreeByteCounts" },
+ { TIFFTAG_GRAYRESPONSEUNIT, "GrayResponseUnit" },
+ { TIFFTAG_GRAYRESPONSECURVE,"GrayResponseCurve" },
+ { TIFFTAG_GROUP3OPTIONS, "Group3Options" },
+ { TIFFTAG_GROUP4OPTIONS, "Group4Options" },
+ { TIFFTAG_RESOLUTIONUNIT, "ResolutionUnit" },
+ { TIFFTAG_PAGENUMBER, "PageNumber" },
+ { TIFFTAG_COLORRESPONSEUNIT,"ColorResponseUnit" },
+ { TIFFTAG_TRANSFERFUNCTION, "TransferFunction" },
+ { TIFFTAG_SOFTWARE, "Software" },
+ { TIFFTAG_DATETIME, "DateTime" },
+ { TIFFTAG_ARTIST, "Artist" },
+ { TIFFTAG_HOSTCOMPUTER, "HostComputer" },
+ { TIFFTAG_PREDICTOR, "Predictor" },
+ { TIFFTAG_WHITEPOINT, "Whitepoint" },
+ { TIFFTAG_PRIMARYCHROMATICITIES,"PrimaryChromaticities" },
+ { TIFFTAG_COLORMAP, "Colormap" },
+ { TIFFTAG_HALFTONEHINTS, "HalftoneHints" },
+ { TIFFTAG_TILEWIDTH, "TileWidth" },
+ { TIFFTAG_TILELENGTH, "TileLength" },
+ { TIFFTAG_TILEOFFSETS, "TileOffsets" },
+ { TIFFTAG_TILEBYTECOUNTS, "TileByteCounts" },
+ { TIFFTAG_BADFAXLINES, "BadFaxLines" },
+ { TIFFTAG_CLEANFAXDATA, "CleanFaxData" },
+ { TIFFTAG_CONSECUTIVEBADFAXLINES, "ConsecutiveBadFaxLines" },
+ { TIFFTAG_SUBIFD, "SubIFD" },
+ { TIFFTAG_INKSET, "InkSet" },
+ { TIFFTAG_INKNAMES, "InkNames" },
+ { TIFFTAG_NUMBEROFINKS, "NumberOfInks" },
+ { TIFFTAG_DOTRANGE, "DotRange" },
+ { TIFFTAG_TARGETPRINTER, "TargetPrinter" },
+ { TIFFTAG_EXTRASAMPLES, "ExtraSamples" },
+ { TIFFTAG_SAMPLEFORMAT, "SampleFormat" },
+ { TIFFTAG_SMINSAMPLEVALUE, "SMinSampleValue" },
+ { TIFFTAG_SMAXSAMPLEVALUE, "SMaxSampleValue" },
+ { TIFFTAG_JPEGPROC, "JPEGProcessingMode" },
+ { TIFFTAG_JPEGIFOFFSET, "JPEGInterchangeFormat" },
+ { TIFFTAG_JPEGIFBYTECOUNT, "JPEGInterchangeFormatLength" },
+ { TIFFTAG_JPEGRESTARTINTERVAL,"JPEGRestartInterval" },
+ { TIFFTAG_JPEGLOSSLESSPREDICTORS,"JPEGLosslessPredictors" },
+ { TIFFTAG_JPEGPOINTTRANSFORM,"JPEGPointTransform" },
+ { TIFFTAG_JPEGTABLES, "JPEGTables" },
+ { TIFFTAG_JPEGQTABLES, "JPEGQTables" },
+ { TIFFTAG_JPEGDCTABLES, "JPEGDCTables" },
+ { TIFFTAG_JPEGACTABLES, "JPEGACTables" },
+ { TIFFTAG_YCBCRCOEFFICIENTS,"YCbCrCoefficients" },
+ { TIFFTAG_YCBCRSUBSAMPLING, "YCbCrSubsampling" },
+ { TIFFTAG_YCBCRPOSITIONING, "YCbCrPositioning" },
+ { TIFFTAG_REFERENCEBLACKWHITE, "ReferenceBlackWhite" },
+ { TIFFTAG_REFPTS, "IgReferencePoints (Island Graphics)" },
+ { TIFFTAG_REGIONTACKPOINT, "IgRegionTackPoint (Island Graphics)" },
+ { TIFFTAG_REGIONWARPCORNERS,"IgRegionWarpCorners (Island Graphics)" },
+ { TIFFTAG_REGIONAFFINE, "IgRegionAffine (Island Graphics)" },
+ { TIFFTAG_MATTEING, "OBSOLETE Matteing (Silicon Graphics)" },
+ { TIFFTAG_DATATYPE, "OBSOLETE DataType (Silicon Graphics)" },
+ { TIFFTAG_IMAGEDEPTH, "ImageDepth (Silicon Graphics)" },
+ { TIFFTAG_TILEDEPTH, "TileDepth (Silicon Graphics)" },
+ { 32768, "OLD BOGUS Matteing tag" },
+ { TIFFTAG_COPYRIGHT, "Copyright" },
+ { TIFFTAG_ICCPROFILE, "ICC Profile" },
+ { TIFFTAG_JBIGOPTIONS, "JBIG Options" },
+ { TIFFTAG_STONITS, "StoNits" },
+};
+#define NTAGS (sizeof (tagnames) / sizeof (tagnames[0]))
+
+static void
+PrintTag(FILE* fd, uint16 tag)
+{
+ const struct tagname *tp;
+
+ for (tp = tagnames; tp < &tagnames[NTAGS]; tp++)
+ if (tp->tag == tag) {
+ fprintf(fd, "%s (%u)", tp->name, tag);
+ return;
+ }
+ fprintf(fd, "%u (%#x)", tag, tag);
+}
+
+static void
+PrintType(FILE* fd, uint16 type)
+{
+ static const char *typenames[] = {
+ "0",
+ "BYTE",
+ "ASCII",
+ "SHORT",
+ "LONG",
+ "RATIONAL",
+ "SBYTE",
+ "UNDEFINED",
+ "SSHORT",
+ "SLONG",
+ "SRATIONAL",
+ "FLOAT",
+ "DOUBLE",
+ "IFD",
+ "14",
+ "15",
+ "LONG8",
+ "SLONG8",
+ "IFD8"
+ };
+#define NTYPES (sizeof (typenames) / sizeof (typenames[0]))
+
+ if (type < NTYPES)
+ fprintf(fd, "%s (%u)", typenames[type], type);
+ else
+ fprintf(fd, "%u (%#x)", type, type);
+}
+#undef NTYPES
+
+#include <ctype.h>
+
+static void
+PrintASCII(FILE* fd, uint32 cc, const unsigned char* cp)
+{
+ for (; cc > 0; cc--, cp++) {
+ const char* tp;
+
+ if (isprint(*cp)) {
+ fputc(*cp, fd);
+ continue;
+ }
+ for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++)
+ if (*tp++ == *cp)
+ break;
+ if (*tp)
+ fprintf(fd, "\\%c", *tp);
+ else if (*cp)
+ fprintf(fd, "\\%03o", *cp);
+ else
+ fprintf(fd, "\\0");
+ }
+}
+
+static void
+PrintData(FILE* fd, uint16 type, uint32 count, unsigned char* data)
+{
+ char* sep = "";
+
+ switch (type) {
+ case TIFF_BYTE:
+ while (count-- > 0)
+ fprintf(fd, bytefmt, sep, *data++), sep = " ";
+ break;
+ case TIFF_SBYTE:
+ while (count-- > 0)
+ fprintf(fd, sbytefmt, sep, *(char *)data++), sep = " ";
+ break;
+ case TIFF_UNDEFINED:
+ while (count-- > 0)
+ fprintf(fd, bytefmt, sep, *data++), sep = " ";
+ break;
+ case TIFF_ASCII:
+ PrintASCII(fd, count, data);
+ break;
+ case TIFF_SHORT: {
+ uint16 *wp = (uint16*)data;
+ while (count-- > 0)
+ fprintf(fd, shortfmt, sep, *wp++), sep = " ";
+ break;
+ }
+ case TIFF_SSHORT: {
+ int16 *wp = (int16*)data;
+ while (count-- > 0)
+ fprintf(fd, sshortfmt, sep, *wp++), sep = " ";
+ break;
+ }
+ case TIFF_LONG: {
+ uint32 *lp = (uint32*)data;
+ while (count-- > 0) {
+ fprintf(fd, longfmt, sep, (unsigned long) *lp++);
+ sep = " ";
+ }
+ break;
+ }
+ case TIFF_SLONG: {
+ int32 *lp = (int32*)data;
+ while (count-- > 0)
+ fprintf(fd, slongfmt, sep, (long) *lp++), sep = " ";
+ break;
+ }
+ case TIFF_LONG8: {
+ uint64 *llp = (uint64*)data;
+ while (count-- > 0) {
+#if defined(__WIN32__) && defined(_MSC_VER)
+ fprintf(fd, long8fmt, sep, (unsigned __int64) *llp++);
+#else
+ fprintf(fd, long8fmt, sep, (unsigned long long) *llp++);
+#endif
+ sep = " ";
+ }
+ break;
+ }
+ case TIFF_SLONG8: {
+ int64 *llp = (int64*)data;
+ while (count-- > 0)
+#if defined(__WIN32__) && defined(_MSC_VER)
+ fprintf(fd, slong8fmt, sep, (__int64) *llp++), sep = " ";
+#else
+ fprintf(fd, slong8fmt, sep, (long long) *llp++), sep = " ";
+#endif
+ break;
+ }
+ case TIFF_RATIONAL: {
+ uint32 *lp = (uint32*)data;
+ while (count-- > 0) {
+ if (lp[1] == 0)
+ fprintf(fd, "%sNan (%lu/%lu)", sep,
+ (unsigned long) lp[0],
+ (unsigned long) lp[1]);
+ else
+ fprintf(fd, rationalfmt, sep,
+ (double)lp[0] / (double)lp[1]);
+ sep = " ";
+ lp += 2;
+ }
+ break;
+ }
+ case TIFF_SRATIONAL: {
+ int32 *lp = (int32*)data;
+ while (count-- > 0) {
+ if (lp[1] == 0)
+ fprintf(fd, "%sNan (%ld/%ld)", sep,
+ (long) lp[0], (long) lp[1]);
+ else
+ fprintf(fd, srationalfmt, sep,
+ (double)lp[0] / (double)lp[1]);
+ sep = " ";
+ lp += 2;
+ }
+ break;
+ }
+ case TIFF_FLOAT: {
+ float *fp = (float *)data;
+ while (count-- > 0)
+ fprintf(fd, floatfmt, sep, *fp++), sep = " ";
+ break;
+ }
+ case TIFF_DOUBLE: {
+ double *dp = (double *)data;
+ while (count-- > 0)
+ fprintf(fd, doublefmt, sep, *dp++), sep = " ";
+ break;
+ }
+ case TIFF_IFD: {
+ uint32 *lp = (uint32*)data;
+ while (count-- > 0) {
+ fprintf(fd, ifdfmt, sep, (unsigned long) *lp++);
+ sep = " ";
+ }
+ break;
+ }
+ case TIFF_IFD8: {
+ uint64 *llp = (uint64*)data;
+ while (count-- > 0) {
+#if defined(__WIN32__) && defined(_MSC_VER)
+ fprintf(fd, ifd8fmt, sep, (unsigned __int64) *llp++);
+#else
+ fprintf(fd, ifd8fmt, sep, (unsigned long long) *llp++);
+#endif
+ sep = " ";
+ }
+ break;
+ }
+ }
+}
+
+static void
+ReadError(char* what)
+{
+ Fatal("Error while reading %s", what);
+}
+
+#include <stdarg.h>
+
+static void
+vError(FILE* fd, const char* fmt, va_list ap)
+{
+ fprintf(fd, "%s: ", curfile);
+ vfprintf(fd, fmt, ap);
+ fprintf(fd, ".\n");
+}
+
+static void
+Error(const char* fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vError(stderr, fmt, ap);
+ va_end(ap);
+}
+
+static void
+Fatal(const char* fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vError(stderr, fmt, ap);
+ va_end(ap);
+ exit(-1);
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */