home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / software / unix / libtiff / lbtif3_3.tar / tools / tiffdump.c < prev    next >
C/C++ Source or Header  |  1993-08-26  |  19KB  |  725 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Header: /usr/people/sam/tiff/tools/RCS/tiffdump.c,v 1.29 93/08/26 17:12:13 sam Exp $";
  3. #endif
  4.  
  5. /*
  6.  * Copyright (c) 1988, 1989, 1990, 1991, 1992 Sam Leffler
  7.  * Copyright (c) 1991, 1992 Silicon Graphics, Inc.
  8.  *
  9.  * Permission to use, copy, modify, distribute, and sell this software and 
  10.  * its documentation for any purpose is hereby granted without fee, provided
  11.  * that (i) the above copyright notices and this permission notice appear in
  12.  * all copies of the software and related documentation, and (ii) the names of
  13.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  14.  * publicity relating to the software without the specific, prior written
  15.  * permission of Sam Leffler and Silicon Graphics.
  16.  * 
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  18.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  19.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  20.  * 
  21.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  22.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  23.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  24.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  25.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  26.  * OF THIS SOFTWARE.
  27.  */
  28.  
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <unistd.h>
  32. #include <string.h>
  33.  
  34. #if defined(VMS)
  35. #include <unixio.h>
  36. #include <file.h>
  37. #else
  38. #include <fcntl.h>
  39. #endif
  40. #if defined(MSDOS)
  41. #include <malloc.h>
  42. #else
  43. #define    O_BINARY    0
  44. #endif
  45.  
  46. #include "tiff.h"
  47.  
  48. char    *curfile;
  49. int    swabflag;
  50. int    bigendian;
  51. int    typeshift[13];    /* data type shift counts */
  52. long    typemask[13];    /* data type masks */
  53.  
  54. char*    bytefmt = "%s0x%02x";        /* BYTE */
  55. char*    sbytefmt = "%s%d";        /* SBYTE */
  56. char*    shortfmt = "%s%u";        /* SHORT */
  57. char*    sshortfmt = "%s%d";        /* SSHORT */
  58. char*    longfmt = "%s%lu";        /* LONG */
  59. char*    slongfmt = "%s%ld";        /* SLONG */
  60. char*    rationalfmt = "%s%g";        /* RATIONAL */
  61. char*    srationalfmt = "%s%g";        /* SRATIONAL */
  62. char*    floatfmt = "%s%g";        /* FLOAT */
  63. char*    doublefmt = "%s%g";        /* DOUBLE */
  64.  
  65. static    void dump(int);
  66.  
  67. void
  68. main(int argc, char* argv[])
  69. {
  70.     int one = 1, fd;
  71.     int multiplefiles = (argc > 1);
  72.  
  73.     bigendian = (*(char *)&one == 0);
  74.     argc--, argv++;
  75.     if (argc > 1 && strcmp(argv[0], "-h") == 0) {
  76.         shortfmt = "%s0x%x";
  77.         sshortfmt = "%s0x%x";
  78.         longfmt = "%s0x%lx";
  79.         slongfmt = "%s0x%lx";
  80.         argc--, argv++;
  81.     }
  82.     for (; argc > 0; argc--, argv++) {
  83.         fd = open(argv[0], O_RDONLY|O_BINARY);
  84.         if (fd < 0) {
  85.             perror(argv[0]);
  86.             exit(-1);
  87.         }
  88.         if (multiplefiles)
  89.             printf("%s:\n", argv[0]);
  90.         curfile = *argv;
  91.         swabflag = 0;
  92.         dump(fd);
  93.         close(fd);
  94.     }
  95.     exit(0);
  96. }
  97.  
  98. static    TIFFHeader h;
  99.  
  100. #define    ord(e)    ((int)e)
  101.  
  102. /*
  103.  * Initialize shift & mask tables and byte
  104.  * swapping state according to the file
  105.  * byte order.
  106.  */
  107. static void
  108. InitByteOrder(int magic)
  109. {
  110.     typemask[0] = 0;
  111.     typemask[ord(TIFF_BYTE)] = 0xff;
  112.     typemask[ord(TIFF_SBYTE)] = 0xff;
  113.     typemask[ord(TIFF_UNDEFINED)] = 0xff;
  114.     typemask[ord(TIFF_SHORT)] = 0xffff;
  115.     typemask[ord(TIFF_SSHORT)] = 0xffff;
  116.     typemask[ord(TIFF_LONG)] = 0xffffffff;
  117.     typemask[ord(TIFF_SLONG)] = 0xffffffff;
  118.     typemask[ord(TIFF_RATIONAL)] = 0xffffffff;
  119.     typemask[ord(TIFF_SRATIONAL)] = 0xffffffff;
  120.     typemask[ord(TIFF_FLOAT)] = 0xffffffff;
  121.     typemask[ord(TIFF_DOUBLE)] = 0xffffffff;
  122.     typeshift[0] = 0;
  123.     typeshift[ord(TIFF_LONG)] = 0;
  124.     typeshift[ord(TIFF_SLONG)] = 0;
  125.     typeshift[ord(TIFF_RATIONAL)] = 0;
  126.     typeshift[ord(TIFF_SRATIONAL)] = 0;
  127.     typeshift[ord(TIFF_FLOAT)] = 0;
  128.     typeshift[ord(TIFF_DOUBLE)] = 0;
  129.     if (magic == TIFF_BIGENDIAN) {
  130.         typeshift[ord(TIFF_BYTE)] = 24;
  131.         typeshift[ord(TIFF_SBYTE)] = 24;
  132.         typeshift[ord(TIFF_SHORT)] = 16;
  133.         typeshift[ord(TIFF_SSHORT)] = 16;
  134.         swabflag = !bigendian;
  135.     } else {
  136.         typeshift[ord(TIFF_BYTE)] = 0;
  137.         typeshift[ord(TIFF_SBYTE)] = 0;
  138.         typeshift[ord(TIFF_SHORT)] = 0;
  139.         typeshift[ord(TIFF_SSHORT)] = 0;
  140.         swabflag = bigendian;
  141.     }
  142. }
  143.  
  144. static    uint32 ReadDirectory(int, uint32);
  145. static    void TIFFSwabShort(uint16 *);
  146. static    void TIFFSwabLong(uint32 *);
  147. static    void TIFFSwabArrayOfShort(uint16 *, unsigned long);
  148. static    void TIFFSwabArrayOfLong(uint32 *, unsigned long);
  149. static    void ReadError(char*);
  150. static    void Error(const char*, ...);
  151. static    void Fatal(const char*, ...);
  152.  
  153. static void
  154. dump(int fd)
  155. {
  156.     uint32 off;
  157.     int i;
  158.  
  159.     lseek(fd, 0L, 0);
  160.     if (read(fd, (char*) &h, sizeof (h)) != sizeof (h))
  161.         ReadError("TIFF header");
  162.     /*
  163.      * Setup the byte order handling.
  164.      */
  165.     if (h.tiff_magic != TIFF_BIGENDIAN && h.tiff_magic != TIFF_LITTLEENDIAN)
  166.         Fatal("Not a TIFF file, bad magic number %u (0x%x)",
  167.             h.tiff_magic, h.tiff_magic);
  168.     InitByteOrder(h.tiff_magic);
  169.     /*
  170.      * Swap header if required.
  171.      */
  172.     if (swabflag) {
  173.         TIFFSwabShort(&h.tiff_version);
  174.         TIFFSwabLong(&h.tiff_diroff);
  175.     }
  176.     /*
  177.      * Now check version (if needed, it's been byte-swapped).
  178.      * Note that this isn't actually a version number, it's a
  179.      * magic number that doesn't change (stupid).
  180.      */
  181.     if (h.tiff_version != TIFF_VERSION)
  182.         Fatal("Not a TIFF file, bad version number %u (0x%x)",
  183.             h.tiff_version, h.tiff_version); 
  184.     printf("Magic: 0x%x <%s-endian> Version: 0x%x\n",
  185.         h.tiff_magic,
  186.         h.tiff_magic == TIFF_BIGENDIAN ? "big" : "little",
  187.         h.tiff_version);
  188.     i = 0;
  189.     off = h.tiff_diroff;
  190.     while (off) {
  191.         if (i > 0)
  192.             putchar('\n');
  193.         printf("Directory %d: offset %lu (0x%lx)\n", i++, off, off);
  194.         off = ReadDirectory(fd, off);
  195.     }
  196. }
  197.  
  198. static int datawidth[] = {
  199.     0,    /* nothing */
  200.     1,    /* TIFF_BYTE */
  201.     1,    /* TIFF_ASCII */
  202.     2,    /* TIFF_SHORT */
  203.     4,    /* TIFF_LONG */
  204.     8,    /* TIFF_RATIONAL */
  205.     1,    /* TIFF_SBYTE */
  206.     1,    /* TIFF_UNDEFINED */
  207.     2,    /* TIFF_SSHORT */
  208.     4,    /* TIFF_SLONG */
  209.     8,    /* TIFF_SRATIONAL */
  210.     4,    /* TIFF_FLOAT */
  211.     8,    /* TIFF_DOUBLE */
  212. };
  213. #define    NWIDTHS    (sizeof (datawidth) / sizeof (datawidth[0]))
  214. static    int TIFFFetchData(int, TIFFDirEntry*, void*);
  215. static    void PrintTag(FILE*, uint16);
  216. static    void PrintType(FILE*, uint16);
  217. static    void PrintData(FILE*, uint16, uint32, unsigned char*);
  218. static    void PrintByte(FILE*, const char*, TIFFDirEntry*);
  219. static    void PrintShort(FILE*, const char*, TIFFDirEntry*);
  220. static    void PrintLong(FILE*, const char*, TIFFDirEntry*);
  221.  
  222. /*
  223.  * Read the next TIFF directory from a file
  224.  * and convert it to the internal format.
  225.  * We read directories sequentially.
  226.  */
  227. static uint32
  228. ReadDirectory(int fd, uint32 off)
  229. {
  230.     register TIFFDirEntry *dp;
  231.     register int n;
  232.     TIFFDirEntry *dir = 0;
  233.     uint16 dircount;
  234.     char *cp;
  235.     int space;
  236.     uint32 nextdiroff = 0;
  237.  
  238.     if (off == 0)            /* no more directories */
  239.         goto done;
  240.     if (lseek(fd, off, 0) != off) {
  241.         Fatal("Seek error accessing TIFF directory");
  242.         goto done;
  243.     }
  244.     if (read(fd, (char*) &dircount, sizeof (uint16)) != sizeof (uint16)) {
  245.         ReadError("directory count");
  246.         goto done;
  247.     }
  248.     if (swabflag)
  249.         TIFFSwabShort(&dircount);
  250.     dir = (TIFFDirEntry *)malloc(dircount * sizeof (TIFFDirEntry));
  251.     if (dir == NULL) {
  252.         Fatal("No space for TIFF directory");
  253.         goto done;
  254.     }
  255.     n = read(fd, (char*) dir, dircount*sizeof (*dp));
  256.     if (n != dircount*sizeof (*dp)) {
  257.         n /= sizeof (*dp);
  258.         Error(
  259.         "Could only read %u of %u entries in directory at offset 0x%lx",
  260.             n, dircount, (unsigned long) off);
  261.         dircount = n;
  262.     }
  263.     if (read(fd, (char*) &nextdiroff, sizeof (uint32)) != sizeof (uint32))
  264.         nextdiroff = 0;
  265.     if (swabflag)
  266.         TIFFSwabLong(&nextdiroff);
  267.     for (dp = dir, n = dircount; n > 0; n--, dp++) {
  268.         if (swabflag) {
  269.             TIFFSwabArrayOfShort(&dp->tdir_tag, 2);
  270.             TIFFSwabArrayOfLong(&dp->tdir_count, 2);
  271.         }
  272.         PrintTag(stdout, dp->tdir_tag);
  273.         putchar(' ');
  274.         PrintType(stdout, dp->tdir_type);
  275.         putchar(' ');
  276.         printf("%u<", dp->tdir_count);
  277.         if (dp->tdir_type >= NWIDTHS) {
  278.             printf(">\n");
  279.             continue;
  280.         }
  281.         space = dp->tdir_count * datawidth[dp->tdir_type];
  282.         if (space <= 4) {
  283.             switch (dp->tdir_type) {
  284.             case TIFF_ASCII: {
  285.                 unsigned char data[4];
  286.                 memcpy(data, &dp->tdir_offset, 4);
  287.                 if (swabflag)
  288.                     TIFFSwabLong((uint32*) data);
  289.                 PrintData(stdout,
  290.                     dp->tdir_type, dp->tdir_count, data);
  291.                 break;
  292.             }
  293.             case TIFF_BYTE:
  294.                 PrintByte(stdout, bytefmt, dp);
  295.                 break;
  296.             case TIFF_SBYTE:
  297.                 PrintByte(stdout, sbytefmt, dp);
  298.                 break;
  299.             case TIFF_SHORT:
  300.                 PrintShort(stdout, shortfmt, dp);
  301.                 break;
  302.             case TIFF_SSHORT:
  303.                 PrintShort(stdout, sshortfmt, dp);
  304.                 break;
  305.             case TIFF_LONG:
  306.                 PrintLong(stdout, longfmt, dp);
  307.                 break;
  308.             case TIFF_SLONG:
  309.                 PrintLong(stdout, slongfmt, dp);
  310.                 break;
  311.             }
  312.         } else {
  313.             unsigned char *data = (unsigned char *)malloc(space);
  314.             if (data) {
  315.                 if (TIFFFetchData(fd, dp, data))
  316.                     PrintData(stdout, dp->tdir_type,
  317.                         dp->tdir_count, data);
  318.                 free(data);
  319.             } else
  320.                 Error("No space for data for tag %u",
  321.                     dp->tdir_tag);
  322.         }
  323.         printf(">\n");
  324.     }
  325. done:
  326.     if (dir)
  327.         free((char *)dir);
  328.     return (nextdiroff);
  329. }
  330.  
  331. static    struct tagname {
  332.     uint16    tag;
  333.     char*    name;
  334. } tagnames[] = {
  335.     { TIFFTAG_SUBFILETYPE,    "SubFileType" },
  336.     { TIFFTAG_OSUBFILETYPE,    "OldSubFileType" },
  337.     { TIFFTAG_IMAGEWIDTH,    "ImageWidth" },
  338.     { TIFFTAG_IMAGELENGTH,    "ImageLength" },
  339.     { TIFFTAG_BITSPERSAMPLE,    "BitsPerSample" },
  340.     { TIFFTAG_COMPRESSION,    "Compression" },
  341.     { TIFFTAG_PHOTOMETRIC,    "Photometric" },
  342.     { TIFFTAG_THRESHHOLDING,    "Threshholding" },
  343.     { TIFFTAG_CELLWIDTH,    "CellWidth" },
  344.     { TIFFTAG_CELLLENGTH,    "CellLength" },
  345.     { TIFFTAG_FILLORDER,    "FillOrder" },
  346.     { TIFFTAG_DOCUMENTNAME,    "DocumentName" },
  347.     { TIFFTAG_IMAGEDESCRIPTION,    "ImageDescription" },
  348.     { TIFFTAG_MAKE,        "Make" },
  349.     { TIFFTAG_MODEL,        "Model" },
  350.     { TIFFTAG_STRIPOFFSETS,    "StripOffsets" },
  351.     { TIFFTAG_ORIENTATION,    "Orientation" },
  352.     { TIFFTAG_SAMPLESPERPIXEL,    "SamplesPerPixel" },
  353.     { TIFFTAG_ROWSPERSTRIP,    "RowsPerStrip" },
  354.     { TIFFTAG_STRIPBYTECOUNTS,    "StripByteCounts" },
  355.     { TIFFTAG_MINSAMPLEVALUE,    "MinSampleValue" },
  356.     { TIFFTAG_MAXSAMPLEVALUE,    "MaxSampleValue" },
  357.     { TIFFTAG_XRESOLUTION,    "XResolution" },
  358.     { TIFFTAG_YRESOLUTION,    "YResolution" },
  359.     { TIFFTAG_PLANARCONFIG,    "PlanarConfig" },
  360.     { TIFFTAG_PAGENAME,        "PageName" },
  361.     { TIFFTAG_XPOSITION,    "XPosition" },
  362.     { TIFFTAG_YPOSITION,    "YPosition" },
  363.     { TIFFTAG_FREEOFFSETS,    "FreeOffsets" },
  364.     { TIFFTAG_FREEBYTECOUNTS,    "FreeByteCounts" },
  365.     { TIFFTAG_GRAYRESPONSEUNIT,    "GrayResponseUnit" },
  366.     { TIFFTAG_GRAYRESPONSECURVE,"GrayResponseCurve" },
  367.     { TIFFTAG_GROUP3OPTIONS,    "Group3Options" },
  368.     { TIFFTAG_GROUP4OPTIONS,    "Group4Options" },
  369.     { TIFFTAG_RESOLUTIONUNIT,    "ResolutionUnit" },
  370.     { TIFFTAG_PAGENUMBER,    "PageNumber" },
  371.     { TIFFTAG_COLORRESPONSEUNIT,"ColorResponseUnit" },
  372.     { TIFFTAG_TRANSFERFUNCTION,    "TransferFunction" },
  373.     { TIFFTAG_SOFTWARE,        "Software" },
  374.     { TIFFTAG_DATETIME,        "DateTime" },
  375.     { TIFFTAG_ARTIST,        "Artist" },
  376.     { TIFFTAG_HOSTCOMPUTER,    "HostComputer" },
  377.     { TIFFTAG_PREDICTOR,    "Predictor" },
  378.     { TIFFTAG_WHITEPOINT,    "Whitepoint" },
  379.     { TIFFTAG_PRIMARYCHROMATICITIES,"PrimaryChromaticities" },
  380.     { TIFFTAG_COLORMAP,        "Colormap" },
  381.     { TIFFTAG_HALFTONEHINTS,    "HalftoneHints" },
  382.     { TIFFTAG_TILEWIDTH,    "TileWidth" },
  383.     { TIFFTAG_TILELENGTH,    "TileLength" },
  384.     { TIFFTAG_TILEOFFSETS,    "TileOffsets" },
  385.     { TIFFTAG_TILEBYTECOUNTS,    "TileByteCounts" },
  386.     { TIFFTAG_BADFAXLINES,    "BadFaxLines" },
  387.     { TIFFTAG_CLEANFAXDATA,    "CleanFaxData" },
  388.     { TIFFTAG_CONSECUTIVEBADFAXLINES, "ConsecutiveBadFaxLines" },
  389.     { TIFFTAG_INKSET,        "InkSet" },
  390.     { TIFFTAG_INKNAMES,        "InkNames" },
  391.     { TIFFTAG_DOTRANGE,        "DotRange" },
  392.     { TIFFTAG_TARGETPRINTER,    "TargetPrinter" },
  393.     { TIFFTAG_EXTRASAMPLES,    "ExtraSamples" },
  394.     { TIFFTAG_SAMPLEFORMAT,    "SampleFormat" },
  395.     { TIFFTAG_SMINSAMPLEVALUE,    "SMinSampleValue" },
  396.     { TIFFTAG_SMAXSAMPLEVALUE,    "SMaxSampleValue" },
  397.     { TIFFTAG_JPEGPROC,        "JPEGProcessingMode" },
  398.     { TIFFTAG_JPEGIFOFFSET,    "JPEGInterchangeFormat" },
  399.     { TIFFTAG_JPEGIFBYTECOUNT,    "JPEGInterchangeFormatLength" },
  400.     { TIFFTAG_JPEGRESTARTINTERVAL,"JPEGRestartInterval" },
  401.     { TIFFTAG_JPEGLOSSLESSPREDICTORS,"JPEGLosslessPredictors" },
  402.     { TIFFTAG_JPEGPOINTTRANSFORM,"JPEGPointTransform" },
  403.     { TIFFTAG_JPEGQTABLES,    "JPEGQTables" },
  404.     { TIFFTAG_JPEGDCTABLES,    "JPEGDCTables" },
  405.     { TIFFTAG_JPEGACTABLES,    "JPEGACTables" },
  406.     { TIFFTAG_YCBCRCOEFFICIENTS,"YCbCrCoefficients" },
  407.     { TIFFTAG_YCBCRSUBSAMPLING,    "YCbCrSubsampling" },
  408.     { TIFFTAG_YCBCRPOSITIONING,    "YCbCrPositioning" },
  409.     { TIFFTAG_REFERENCEBLACKWHITE, "ReferenceBlackWhite" },
  410.     { TIFFTAG_REFPTS,        "IgReferencePoints (Island Graphics)" },
  411.     { TIFFTAG_REGIONTACKPOINT,    "IgRegionTackPoint (Island Graphics)" },
  412.     { TIFFTAG_REGIONWARPCORNERS,"IgRegionWarpCorners (Island Graphics)" },
  413.     { TIFFTAG_REGIONAFFINE,    "IgRegionAffine (Island Graphics)" },
  414.     { TIFFTAG_MATTEING,        "OBSOLETE Matteing (Silicon Graphics)" },
  415.     { TIFFTAG_DATATYPE,        "OBSOLETE DataType (Silicon Graphics)" },
  416.     { TIFFTAG_IMAGEDEPTH,    "ImageDepth (Silicon Graphics)" },
  417.     { TIFFTAG_TILEDEPTH,    "TileDepth (Silicon Graphics)" },
  418.     { 32768,            "OLD BOGUS Matteing tag" },
  419. };
  420. #define    NTAGS    (sizeof (tagnames) / sizeof (tagnames[0]))
  421.  
  422. static void
  423. PrintTag(FILE* fd, uint16 tag)
  424. {
  425.     register struct tagname *tp;
  426.  
  427.     for (tp = tagnames; tp < &tagnames[NTAGS]; tp++)
  428.         if (tp->tag == tag) {
  429.             fprintf(fd, "%s (%u)", tp->name, tag);
  430.             return;
  431.         }
  432.     fprintf(fd, "%u (0x%x)", tag, tag);
  433. }
  434.  
  435. static void
  436. PrintType(FILE* fd, uint16 type)
  437. {
  438.     static char *typenames[] = {
  439.         "0",
  440.         "BYTE",
  441.         "ASCII",
  442.         "SHORT",
  443.         "LONG",
  444.         "RATIONAL",
  445.         "SBYTE",
  446.         "UNDEFINED",
  447.         "SSHORT",
  448.         "SLONG",
  449.         "SRATIONAL",
  450.         "FLOAT",
  451.         "DOUBLE"
  452.     };
  453. #define    NTYPES    (sizeof (typenames) / sizeof (typenames[0]))
  454.  
  455.     if (type < NTYPES)
  456.         fprintf(fd, "%s (%u)", typenames[type], type);
  457.     else
  458.         fprintf(fd, "%u (0x%x)", type, type);
  459. }
  460. #undef    NTYPES
  461.  
  462. static void
  463. PrintByte(FILE* fd, const char* fmt, TIFFDirEntry* dp)
  464. {
  465.     char* sep = "";
  466.  
  467.     if (h.tiff_magic != TIFF_LITTLEENDIAN) {
  468.         switch ((int)dp->tdir_count) {
  469.         case 4: fprintf(fd, fmt, sep, dp->tdir_offset&0xff);
  470.             sep = " ";
  471.         case 3: fprintf(fd, fmt, sep, (dp->tdir_offset>>8)&0xff);
  472.             sep = " ";
  473.         case 2: fprintf(fd, fmt, sep, (dp->tdir_offset>>16)&0xff);
  474.             sep = " ";
  475.         case 1: fprintf(fd, fmt, sep, dp->tdir_offset>>24);
  476.         }
  477.     } else {
  478.         switch ((int)dp->tdir_count) {
  479.         case 4: fprintf(fd, fmt, sep, dp->tdir_offset>>24);
  480.             sep = " ";
  481.         case 3: fprintf(fd, fmt, sep, (dp->tdir_offset>>16)&0xff);
  482.             sep = " ";
  483.         case 2: fprintf(fd, fmt, sep, (dp->tdir_offset>>8)&0xff);
  484.             sep = " ";
  485.         case 1: fprintf(fd, fmt, sep, dp->tdir_offset&0xff);
  486.         }
  487.     }
  488. }
  489.  
  490. static void
  491. PrintShort(FILE* fd, const char* fmt, TIFFDirEntry* dp)
  492. {
  493.     char *sep = "";
  494.  
  495.     if (h.tiff_magic != TIFF_LITTLEENDIAN) {
  496.         switch (dp->tdir_count) {
  497.         case 2: fprintf(fd, fmt, sep, dp->tdir_offset&0xffff);
  498.             sep = " ";
  499.         case 1: fprintf(fd, fmt, sep, dp->tdir_offset>>16);
  500.         }
  501.     } else {
  502.         switch (dp->tdir_count) {
  503.         case 2: fprintf(fd, fmt, sep, dp->tdir_offset>>16);
  504.             sep = " ";
  505.         case 1: fprintf(fd, fmt, sep, dp->tdir_offset&0xffff);
  506.         }
  507.     }
  508. }
  509.  
  510. static void
  511. PrintLong(FILE* fd, const char* fmt, TIFFDirEntry* dp)
  512. {
  513.     fprintf(fd, fmt, "", (long) dp->tdir_offset);
  514. }
  515.  
  516. static void
  517. PrintData(FILE* fd, uint16 type, uint32 count, unsigned char* data)
  518. {
  519.     char* sep = "";
  520.  
  521.     switch (type) {
  522.     case TIFF_BYTE:
  523.         while (count-- > 0)
  524.             fprintf(fd, bytefmt, sep, data++), sep = " ";
  525.         break;
  526.     case TIFF_SBYTE:
  527.         while (count-- > 0)
  528.             fprintf(fd, sbytefmt, sep, *(char *)data++), sep = " ";
  529.         break;
  530.     case TIFF_UNDEFINED:
  531.         while (count-- > 0)
  532.             fprintf(fd, bytefmt, sep, *data++), sep = " ";
  533.         break;
  534.     case TIFF_ASCII:
  535.         fprintf(fd, "%.*s", count, data);
  536.         break;
  537.     case TIFF_SHORT: {
  538.         register uint16 *wp = (uint16*)data;
  539.         while (count-- > 0)
  540.             fprintf(fd, shortfmt, sep, *wp++), sep = " ";
  541.         break;
  542.     }
  543.     case TIFF_SSHORT: {
  544.         register int16 *wp = (int16*)data;
  545.         while (count-- > 0)
  546.             fprintf(fd, sshortfmt, sep, *wp++), sep = " ";
  547.         break;
  548.     }
  549.     case TIFF_LONG: {
  550.         register uint32 *lp = (uint32*)data;
  551.         while (count-- > 0) {
  552.             fprintf(fd, longfmt, sep, (unsigned long) *lp++);
  553.             sep = " ";
  554.         }
  555.         break;
  556.     }
  557.     case TIFF_SLONG: {
  558.         register int32 *lp = (int32*)data;
  559.         while (count-- > 0)
  560.             fprintf(fd, slongfmt, sep, (long) *lp++), sep = " ";
  561.         break;
  562.     }
  563.     case TIFF_RATIONAL: {
  564.         register uint32 *lp = (uint32*)data;
  565.         while (count-- > 0) {
  566.             if (lp[1] == 0)
  567.                 fprintf(fd, "%sNan (%lu/%lu)", sep,
  568.                     lp[0], lp[1]);
  569.             else
  570.                 fprintf(fd, rationalfmt, sep,
  571.                     (double)lp[0] / (double)lp[1]);
  572.             sep = " ";
  573.             lp += 2;
  574.         }
  575.         break;
  576.     }
  577.     case TIFF_SRATIONAL: {
  578.         register int32 *lp = (int32*)data;
  579.         while (count-- > 0) {
  580.             if (lp[1] == 0)
  581.                 fprintf(fd, "%sNan (%ld/%ld)", sep,
  582.                     lp[0], lp[1]);
  583.             else
  584.                 fprintf(fd, srationalfmt, sep,
  585.                     (double)lp[0] / (double)lp[1]);
  586.             sep = " ";
  587.             lp += 2;
  588.         }
  589.         break;
  590.     }
  591.     case TIFF_FLOAT: {
  592.         register float *fp = (float *)data;
  593.         while (count-- > 0)
  594.             fprintf(fd, floatfmt, sep, *fp++), sep = " ";
  595.         break;
  596.     }
  597.     case TIFF_DOUBLE: {
  598.         register double *dp = (double *)data;
  599.         while (count-- > 0)
  600.             fprintf(fd, doublefmt, sep, *dp++), sep = " ";
  601.         break;
  602.     }
  603.     }
  604. }
  605.  
  606. static void
  607. TIFFSwabShort(uint16* wp)
  608. {
  609.     register unsigned char *cp = (unsigned char *)wp;
  610.     int t;
  611.  
  612.     t = cp[1]; cp[1] = cp[0]; cp[0] = t;
  613. }
  614.  
  615. static void
  616. TIFFSwabLong(uint32* lp)
  617. {
  618.     register unsigned char *cp = (unsigned char *)lp;
  619.     int t;
  620.  
  621.     t = cp[3]; cp[3] = cp[0]; cp[0] = t;
  622.     t = cp[2]; cp[2] = cp[1]; cp[1] = t;
  623. }
  624.  
  625. static void
  626. TIFFSwabArrayOfShort(uint16* wp, unsigned long n)
  627. {
  628.     register unsigned char *cp;
  629.     register int t;
  630.  
  631.     /* XXX unroll loop some */
  632.     while (n-- > 0) {
  633.         cp = (unsigned char *)wp;
  634.         t = cp[1]; cp[1] = cp[0]; cp[0] = t;
  635.         wp++;
  636.     }
  637. }
  638.  
  639. static void
  640. TIFFSwabArrayOfLong(uint32* lp, unsigned long n)
  641. {
  642.     register unsigned char *cp;
  643.     register int t;
  644.  
  645.     /* XXX unroll loop some */
  646.     while (n-- > 0) {
  647.         cp = (unsigned char *)lp;
  648.         t = cp[3]; cp[3] = cp[0]; cp[0] = t;
  649.         t = cp[2]; cp[2] = cp[1]; cp[1] = t;
  650.         lp++;
  651.     }
  652. }
  653.  
  654. /*
  655.  * Fetch a contiguous directory item.
  656.  */
  657. static int
  658. TIFFFetchData(int fd, TIFFDirEntry* dir, void* cp)
  659. {
  660.     int cc, w;
  661.  
  662.     w = (dir->tdir_type < NWIDTHS ? datawidth[dir->tdir_type] : 0);
  663.     cc = dir->tdir_count * w;
  664.     if (lseek(fd, (off_t) dir->tdir_offset, 0) == dir->tdir_offset &&
  665.         read(fd, cp, cc) == cc) {
  666.         if (swabflag) {
  667.             switch (dir->tdir_type) {
  668.             case TIFF_SHORT:
  669.             case TIFF_SSHORT:
  670.                 TIFFSwabArrayOfShort((uint16*) cp,
  671.                     dir->tdir_count);
  672.                 break;
  673.             case TIFF_LONG:
  674.             case TIFF_SLONG:
  675.                 TIFFSwabArrayOfLong((uint32*) cp,
  676.                     dir->tdir_count);
  677.                 break;
  678.             case TIFF_RATIONAL:
  679.             case TIFF_DOUBLE:
  680.                 TIFFSwabArrayOfLong((uint32*) cp,
  681.                     2*dir->tdir_count);
  682.                 break;
  683.             }
  684.         }
  685.         return (cc);
  686.     }
  687.     Error("Error while reading data for tag %u", dir->tdir_tag);
  688.     return (0);
  689. }
  690.  
  691. static void
  692. ReadError(char* what)
  693. {
  694.     Fatal("Error while reading %s", what);
  695. }
  696.  
  697. #include <stdarg.h>
  698.  
  699. static void
  700. vError(FILE* fd, const char* fmt, va_list ap)
  701. {
  702.     fprintf(fd, "%s: ", curfile);
  703.     vfprintf(fd, fmt, ap);
  704.     fprintf(fd, ".\n");
  705. }
  706.  
  707. static void
  708. Error(const char* fmt, ...)
  709. {
  710.     va_list ap;
  711.     va_start(ap, fmt);
  712.     vError(stderr, fmt, ap);
  713.     va_end(ap);
  714. }
  715.  
  716. static void
  717. Fatal(const char* fmt, ...)
  718. {
  719.     va_list ap;
  720.     va_start(ap, fmt);
  721.     vError(stderr, fmt, ap);
  722.     va_end(ap);
  723.     exit(-1);
  724. }
  725.