home *** CD-ROM | disk | FTP | other *** search
- /* tiffdump - dump a tiff file, to avoid painful hex dumps
- */
- #include "aldtypes.h"
- #include "imtypes.h"
- #include "tiff.h"
- #include "imag.h"
- #include "imtiff.h"
- #include "vio.h"
- #include "stdio.h"
- #include "dloc.h"
-
- /* prototypes:
- */
- #ifdef MACINTOSH
- FILE * fopen (char *, char *);
- int fseek (FILE *, long, int);
- int fread (char *, int, int, FILE *);
- int fclose (FILE *);
- #endif
-
-
- static struct {
- WORD tag;
- char *str;
- } tagstr[] = {
- TGNEWSUBFILETYPE, "NewSubfileType",
- TGOLDSUBFILETYPE, "OldSubfileType",
- TGIMAGEWIDTH, "ImageWidth",
- TGIMAGELENGTH, "ImageLength",
- TGCOMPRESSION, "Compression",
- TGPHOTOMETRICINTERPRETATION,"PhotometricInterp",
- TGTHRESHHOLDING, "Threshholding",
- TGCELLWIDTH, "CellWidth",
- TGCELLLENGTH, "CellLength",
- TGFILLORDER, "FillOrder",
- TGSTRIPOFFSETS, "StripOffsets",
- TGORIENTATION, "Orientation",
- TGSAMPLESPERPIXEL, "SamplesPerPixel",
- TGBITSPERSAMPLE, "BitsPerSample",
- TGROWSPERSTRIP, "RowsPerStrip",
- TGSTRIPBYTECOUNTS, "StripByteCounts",
- TGMINSAMPLEVALUE, "MinSampleValue",
- TGMAXSAMPLEVALUE, "MaxSampleValue",
- TGXRESOLUTION, "XResolution",
- TGYRESOLUTION, "YResolution",
- TGPLANARCONFIGURATION, "PlanarConfiguration",
- TGDOCUMENTNAME, "DocumentName",
- TGPAGENAME, "PageName",
- TGXPOSITION, "XPosition",
- TGYPOSITION, "YPosition",
- TGIMAGEDESCRIPTION, "ImageDescription",
- TGMAKE, "Make",
- TGMODEL, "Model",
- TGFREEOFFSETS, "FreeOffsets",
- TGFREEBYTECOUNTS, "FreeByteCounts",
- TGGRAYUNIT, "GrayUnit",
- TGGRAYCURVE, "GrayCurve",
- TGRESOLUTIONUNIT, "ResolutionUnit",
- TGPAGENUMBER, "PageNumber",
- TGCOLORRESPONSECURVES, "ColorResponseCurves",
- TGSOFTWARE, "Software",
- TGDATETIME, "DateTime",
- TGARTIST, "Artist",
- TGHOSTCOMPUTER, "HostComputer",
- TGPREDICTOR, "Predictor",
- TGWHITEPOINT, "WhitePoint",
- TGPRIMARYCHROMATICITIES, "PrimaryChromaticities",
- TGCOLORMAP, "ColorMap",
-
- };
-
- /* a particularly greasy static:
- */
- DWORD TiffStart = 0L;
-
- /***************************** subroutines ***************************/
-
-
- /* get tag string
- */
- static char defstr[] = "(no string avail)";
- void GtTagString (WORD, char **);
- LOCAL void GtTagString (tag, ps)
- WORD tag;
- char **ps;
- {
- int tablen;
- int ii;
-
- tablen = sizeof (tagstr) / sizeof (tagstr[0]);
- for (ii = 0; ii < tablen; ii++) {
- if (tag == tagstr[ii].tag) {
- *ps = tagstr[ii].str;
- return;
- }
- }
- *ps = defstr;
- }
-
- /* dump an entry
- */
- #define MAXVAL 100
-
- RC dumpentry (PDLOC, WORD, DWORD, DIRENTRY *);
-
- LOCAL RC dumpentry (pDloc, ByteOrder, pos, pde)
- PDLOC pDloc;
- WORD ByteOrder; /* INTELTIFF vs MOTOROLATIFF */
- DWORD pos;
- DIRENTRY *pde;
- {
- RC err;
- WORD tsize;
- WORD BytesToRead;
- char *bufptr;
- union {
- char bytes[MAXVAL];
- DWORD dword;
- } buf;
- WORD maxitems;
- WORD item;
- char *s;
- DWORD valpos;
- DWORD ValBuf;
- int red;
-
- /* get the non byte reversed value
- */
- if (err = VRead (pDloc, pos + 8L, sizeof(ValBuf), (LPSTR)&ValBuf)) {
- DBMSG(("dumpentry: VRead error\n"));
- return err;
- }
-
- /* dump the basic entry
- */
- GtTagString (pde->deTag, &s);
- DBMSG(("%6lu tag=%5u [%-20.20s] type=%u length=%lu val=0x%.8lx\n",
- pos, pde->deTag, s, pde->deType, pde->deLength, ValBuf));
-
- /* print out the value intelligently
- */
- if (err = GtTiffSizeof (pde->deType, &tsize)) {
- DBMSG(("dumpentry: GtTiffSizeof error\n"));
- return err;
- }
- BytesToRead = tsize * pde->deLength;
- maxitems = MAXVAL / tsize;
- maxitems = (pde->deLength < (DWORD) maxitems) ?
- (WORD)(pde->deLength) : maxitems;
- /* careful here: we can't just use deVal to grab data out of, since
- * may already have been byte-reversed!
- */
- if (BytesToRead <= 4)
- valpos = pos + 8L; /* deVal starts on byte 8, wit de */
- else
- valpos = pde->deVal;
- if (err = GtData (pDloc, ByteOrder, valpos, maxitems, pde->deType, buf.bytes)) {
- DBMSG(( "dumpentry: GtData error\n"));
- return err;
- }
-
- bufptr = buf.bytes;
-
- switch (pde->deType) {
- case TIFFBYTE:
- for (item = 0; item < maxitems; item++)
- DBMSG(("%x", (unsigned)(*bufptr++)));
- DBMSG(("\n"));
- break;
- case TIFFASCII:
- if (maxitems == 0)
- break;
- DBMSG(("%.*s\n", maxitems, bufptr));
- break;
- case TIFFSHORT:
- for (item = 0; item < maxitems; item++, bufptr += 2)
- DBMSG(("%u ", *((WORD *)bufptr)));
- DBMSG(("\n"));
- break;
- case TIFFLONG:
- for (item = 0; item < maxitems; item++, bufptr += 4)
- DBMSG(("%lu ", *((DWORD *)bufptr)));
- DBMSG(("\n"));
- break;
- case TIFFRATIONAL:
- for (item = 0; item < maxitems; item++) {
- DBMSG(("% lu ", *((DWORD *)bufptr)));
- bufptr += 4;
- DBMSG(("%lu ", *((DWORD *)bufptr)));
- bufptr += 4;
- }
- DBMSG(("\n"));
- break;
- default:
- DBMSG(( "dumpentry: can't get here\n"));
- break;
- }
- return SUCCESS;
- }
-
-
-
- /***************************** main routine **************************/
- #ifdef WINDOWS
- int main (int,char **);
- int main (ac, av)
- #endif
-
- #ifdef MACINTOSH
- int _main (int, char **);
- int _main (ac, av)
- #endif
-
- int ac;
- char **av;
- {
- RC err;
- TIFFHDR th;
- DIRENTRY de;
- WORD entries;
- WORD entry;
- DWORD location;
- DLOC dloc;
- DWORD dwtemp;
- WORD wtemp;
- WORD ByteOrder;
- WORD red;
-
-
- /* check # of args
- */
- if (ac != 2) {
- DBMSG(("usage: tiffdump filename\n"));
- goto cu0;
- }
-
- /* open the file
- */
- if ((dloc.dlFp = fopen (av[1], "rb")) == (FILE *) NULL) {
- DBMSG(("can't open %s\n", av[1]));
- goto cu0;
- }
- DBMSG(("FILE: %s\n", av[1]));
- dloc.dlWhere = INFILE;
-
- /* since I use this program to dump TIFF "files" that are embedded in
- * other files (a nonstandard thing to do), I will look for a
- * plausible start of the TIFF section. TODO: make this more
- * general (cycle through TIFF "files") and more robust (check for
- * version #, at least).
- */
- while ((red = fread ((char *)&ByteOrder, sizeof(WORD), 1, dloc.dlFp)) == 1) {
- if (ByteOrder == INTELTIFF || ByteOrder == MOTOROLATIFF)
- break;
- else
- TiffStart += 2L;
- }
- DBMSG(("TiffStart=%lu\n",TiffStart));
- DBMSG(("ByteOrder=%x\n",ByteOrder));
- if (red == 0) {
- DBMSG(("can't find ByteOrder\n"));
- goto quit;
- }
- #if 0
- dloc.dlOrder = ByteOrder;
- #endif /* 0 */
-
- /* read the 8-byte header, and dump it
- */
- if (err = GtTiffHdr ((PDLOC)&dloc, &th)) {
- DBMSG(("can't read header\n"));
- goto quit;
- }
- if (th.thByteOrder == INTELTIFF)
- DBMSG(("%6lu ByteOrder = INTELTIFF\n", 0L));
- else if (th.thByteOrder == MOTOROLATIFF)
- DBMSG(("%6lu ByteOrder = MOTOROLATIFF\n", 0L));
- else {
- DBMSG(("bad byte order.\n"));
- goto quit;
- }
- DBMSG(("%6lu Version = %d\n", 2L, th.thVersion));
- DBMSG(("%6lu IfdOffset = %lu\n", 4L, th.thIfdOffset));
-
- location = th.thIfdOffset;
- #if 0
- dloc.dlOrder = th.thByteOrder;
- #endif /* 0 */
-
- /* loop through the IFD's
- */
- do {
- /* if ifd location is 0, quit
- */
- if (location == 0L) {
- DBMSG(("ifd at 0. quit.\n"));
- break;
- }
-
- /* read the number of entries, and dump it
- */
- if (err = GtData ((PDLOC)&dloc, th.thByteOrder, (DWORD)location, 1, TIFFSHORT,
- (LPSTR)&entries)) {
- DBMSG(("can't read # of entries\n"));
- break;
- }
- DBMSG(("\n%6lu Entries = %d\n", th.thIfdOffset, entries));
- if (entries == 0) {
- DBMSG(("number of entries is 0. quit.\n"));
- break;
- }
- location += 2;
-
- /* loop through the entries
- */
- for (entry = 0; entry < entries; entry++) {
-
- /* read the entry
- */
- if (err = GtTiffEntry ((PDLOC)&dloc, th.thByteOrder, location, &de)) {
- DBMSG(("can't read entry\n"));
- goto quit;
- }
-
- /* print the entry in human-readable form
- */
- if (err = dumpentry ((PDLOC)&dloc, th.thByteOrder, location, &de)) {
- DBMSG(("dumpentry error\n"));
- goto quit;
- }
-
- /* store the value, for future diagnostic use
- */
-
- /* adjust the current location
- */
- location += sizeof (DIRENTRY);
-
- } /* end of entry loop */
-
- /* read the location of the next ifd
- */
- if (err = GtData((PDLOC)&dloc, th.thByteOrder, (DWORD)location, 1, TIFFLONG,
- (LPSTR)&dwtemp)) {
- DBMSG(("%6lu can't read location of the next ifd\n",
- location));
- goto quit;
- }
- DBMSG(("%6lu next ifd at %lu\n", location, dwtemp));
- location = dwtemp;
-
- } while (1); /* end of ifd loop */
-
- /* now check for errors. We go through a lot of the same work again, since
- * this error-checking was an afterthought.
- */
- {
- IMAG imag;
- IMAG *p = &imag;
-
- DBMSG(("\n\n"));
-
- if (err = GtTiffInfo ((PDLOC)&dloc, p)) {
- /* DBMSG(("tiffdump: GtTiffInfo\n")); */
- goto b0;
- }
-
- b1: CloseImag(p);
- b0: ;
- }
-
- quit: ;
- fclose (dloc.dlFp);
- cu0: return;
- }