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