roentgen b75cab
/* $Id: tif_print.c,v 1.60 2012-08-19 16:56:35 bfriesen 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
/*
roentgen b75cab
 * TIFF Library.
roentgen b75cab
 *
roentgen b75cab
 * Directory Printing Support
roentgen b75cab
 */
roentgen b75cab
#include "tiffiop.h"
roentgen b75cab
#include <stdio.h></stdio.h>
roentgen b75cab
roentgen b75cab
#include <ctype.h></ctype.h>
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
_TIFFprintAsciiBounded(FILE* fd, const char* cp, int max_chars);
roentgen b75cab
roentgen b75cab
static const char *photoNames[] = {
roentgen b75cab
    "min-is-white",				/* PHOTOMETRIC_MINISWHITE */
roentgen b75cab
    "min-is-black",				/* PHOTOMETRIC_MINISBLACK */
roentgen b75cab
    "RGB color",				/* PHOTOMETRIC_RGB */
roentgen b75cab
    "palette color (RGB from colormap)",	/* PHOTOMETRIC_PALETTE */
roentgen b75cab
    "transparency mask",			/* PHOTOMETRIC_MASK */
roentgen b75cab
    "separated",				/* PHOTOMETRIC_SEPARATED */
roentgen b75cab
    "YCbCr",					/* PHOTOMETRIC_YCBCR */
roentgen b75cab
    "7 (0x7)",
roentgen b75cab
    "CIE L*a*b*",				/* PHOTOMETRIC_CIELAB */
roentgen b75cab
    "ICC L*a*b*",				/* PHOTOMETRIC_ICCLAB */
roentgen b75cab
    "ITU L*a*b*" 				/* PHOTOMETRIC_ITULAB */
roentgen b75cab
};
roentgen b75cab
#define	NPHOTONAMES	(sizeof (photoNames) / sizeof (photoNames[0]))
roentgen b75cab
roentgen b75cab
static const char *orientNames[] = {
roentgen b75cab
    "0 (0x0)",
roentgen b75cab
    "row 0 top, col 0 lhs",			/* ORIENTATION_TOPLEFT */
roentgen b75cab
    "row 0 top, col 0 rhs",			/* ORIENTATION_TOPRIGHT */
roentgen b75cab
    "row 0 bottom, col 0 rhs",			/* ORIENTATION_BOTRIGHT */
roentgen b75cab
    "row 0 bottom, col 0 lhs",			/* ORIENTATION_BOTLEFT */
roentgen b75cab
    "row 0 lhs, col 0 top",			/* ORIENTATION_LEFTTOP */
roentgen b75cab
    "row 0 rhs, col 0 top",			/* ORIENTATION_RIGHTTOP */
roentgen b75cab
    "row 0 rhs, col 0 bottom",			/* ORIENTATION_RIGHTBOT */
roentgen b75cab
    "row 0 lhs, col 0 bottom",			/* ORIENTATION_LEFTBOT */
roentgen b75cab
};
roentgen b75cab
#define	NORIENTNAMES	(sizeof (orientNames) / sizeof (orientNames[0]))
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
_TIFFPrintField(FILE* fd, const TIFFField *fip,
roentgen b75cab
		uint32 value_count, void *raw_data)
roentgen b75cab
{
roentgen b75cab
	uint32 j;
roentgen b75cab
		
roentgen b75cab
	fprintf(fd, "  %s: ", fip->field_name);
roentgen b75cab
roentgen b75cab
	for(j = 0; j < value_count; j++) {
roentgen b75cab
		if(fip->field_type == TIFF_BYTE)
roentgen b75cab
			fprintf(fd, "%u", ((uint8 *) raw_data)[j]);
roentgen b75cab
		else if(fip->field_type == TIFF_UNDEFINED)
roentgen b75cab
			fprintf(fd, "0x%x",
roentgen b75cab
			    (unsigned int) ((unsigned char *) raw_data)[j]);
roentgen b75cab
		else if(fip->field_type == TIFF_SBYTE)
roentgen b75cab
			fprintf(fd, "%d", ((int8 *) raw_data)[j]);
roentgen b75cab
		else if(fip->field_type == TIFF_SHORT)
roentgen b75cab
			fprintf(fd, "%u", ((uint16 *) raw_data)[j]);
roentgen b75cab
		else if(fip->field_type == TIFF_SSHORT)
roentgen b75cab
			fprintf(fd, "%d", ((int16 *) raw_data)[j]);
roentgen b75cab
		else if(fip->field_type == TIFF_LONG)
roentgen b75cab
			fprintf(fd, "%lu",
roentgen b75cab
			    (unsigned long)((uint32 *) raw_data)[j]);
roentgen b75cab
		else if(fip->field_type == TIFF_SLONG)
roentgen b75cab
			fprintf(fd, "%ld", (long)((int32 *) raw_data)[j]);
roentgen b75cab
		else if(fip->field_type == TIFF_IFD)
roentgen b75cab
			fprintf(fd, "0x%lx",
roentgen b75cab
				(unsigned long)((uint32 *) raw_data)[j]);
roentgen b75cab
		else if(fip->field_type == TIFF_RATIONAL
roentgen b75cab
			|| fip->field_type == TIFF_SRATIONAL
roentgen b75cab
			|| fip->field_type == TIFF_FLOAT)
roentgen b75cab
			fprintf(fd, "%f", ((float *) raw_data)[j]);
roentgen b75cab
		else if(fip->field_type == TIFF_LONG8)
roentgen b75cab
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
roentgen b75cab
			fprintf(fd, "%I64u",
roentgen b75cab
			    (unsigned __int64)((uint64 *) raw_data)[j]);
roentgen b75cab
#else
roentgen b75cab
			fprintf(fd, "%llu",
roentgen b75cab
			    (unsigned long long)((uint64 *) raw_data)[j]);
roentgen b75cab
#endif
roentgen b75cab
		else if(fip->field_type == TIFF_SLONG8)
roentgen b75cab
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
roentgen b75cab
			fprintf(fd, "%I64d", (__int64)((int64 *) raw_data)[j]);
roentgen b75cab
#else
roentgen b75cab
			fprintf(fd, "%lld", (long long)((int64 *) raw_data)[j]);
roentgen b75cab
#endif
roentgen b75cab
		else if(fip->field_type == TIFF_IFD8)
roentgen b75cab
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
roentgen b75cab
			fprintf(fd, "0x%I64x",
roentgen b75cab
				(unsigned __int64)((uint64 *) raw_data)[j]);
roentgen b75cab
#else
roentgen b75cab
			fprintf(fd, "0x%llx",
roentgen b75cab
				(unsigned long long)((uint64 *) raw_data)[j]);
roentgen b75cab
#endif
roentgen b75cab
		else if(fip->field_type == TIFF_FLOAT)
roentgen b75cab
			fprintf(fd, "%f", ((float *)raw_data)[j]);
roentgen b75cab
		else if(fip->field_type == TIFF_DOUBLE)
roentgen b75cab
			fprintf(fd, "%f", ((double *) raw_data)[j]);
roentgen b75cab
		else if(fip->field_type == TIFF_ASCII) {
roentgen b75cab
			fprintf(fd, "%s", (char *) raw_data);
roentgen b75cab
			break;
roentgen b75cab
		}
roentgen b75cab
		else {
roentgen b75cab
			fprintf(fd, "<unsupported data="" in="" tiffprint="" type="">");</unsupported>
roentgen b75cab
			break;
roentgen b75cab
		}
roentgen b75cab
roentgen b75cab
		if(j < value_count - 1)
roentgen b75cab
			fprintf(fd, ",");
roentgen b75cab
	}
roentgen b75cab
roentgen b75cab
	fprintf(fd, "\n");
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
_TIFFPrettyPrintField(TIFF* tif, const TIFFField *fip, FILE* fd, uint32 tag,
roentgen b75cab
		      uint32 value_count, void *raw_data)
roentgen b75cab
{
roentgen b75cab
        (void) tif;
roentgen b75cab
roentgen b75cab
	/* do not try to pretty print auto-defined fields */
roentgen b75cab
	if (strncmp(fip->field_name,"Tag ", 4) == 0) {
roentgen b75cab
		return 0;
roentgen b75cab
	}
roentgen b75cab
        
roentgen b75cab
	switch (tag)
roentgen b75cab
	{
roentgen b75cab
		case TIFFTAG_INKSET:
roentgen b75cab
			if (value_count == 2 && fip->field_type == TIFF_SHORT) {
roentgen b75cab
				fprintf(fd, "  Ink Set: ");
roentgen b75cab
				switch (*((uint16*)raw_data)) {
roentgen b75cab
				case INKSET_CMYK:
roentgen b75cab
					fprintf(fd, "CMYK\n");
roentgen b75cab
					break;
roentgen b75cab
				default:
roentgen b75cab
					fprintf(fd, "%u (0x%x)\n",
roentgen b75cab
						*((uint16*)raw_data),
roentgen b75cab
						*((uint16*)raw_data));
roentgen b75cab
					break;
roentgen b75cab
				}
roentgen b75cab
				return 1;
roentgen b75cab
			}
roentgen b75cab
			return 0;
roentgen b75cab
roentgen b75cab
		case TIFFTAG_DOTRANGE:
roentgen b75cab
			if (value_count == 2 && fip->field_type == TIFF_SHORT) {
roentgen b75cab
				fprintf(fd, "  Dot Range: %u-%u\n",
roentgen b75cab
					((uint16*)raw_data)[0], ((uint16*)raw_data)[1]);
roentgen b75cab
				return 1;
roentgen b75cab
			}
roentgen b75cab
			return 0;
roentgen b75cab
roentgen b75cab
		case TIFFTAG_WHITEPOINT:
roentgen b75cab
			if (value_count == 2 && fip->field_type == TIFF_RATIONAL) {
roentgen b75cab
				fprintf(fd, "  White Point: %g-%g\n",
roentgen b75cab
					((float *)raw_data)[0], ((float *)raw_data)[1]);
roentgen b75cab
				return 1;
roentgen b75cab
			} 
roentgen b75cab
			return 0;
roentgen b75cab
roentgen b75cab
		case TIFFTAG_XMLPACKET:
roentgen b75cab
		{
roentgen b75cab
			uint32 i;
roentgen b75cab
roentgen b75cab
			fprintf(fd, "  XMLPacket (XMP Metadata):\n" );
roentgen b75cab
			for(i = 0; i < value_count; i++)
roentgen b75cab
				fputc(((char *)raw_data)[i], fd);
roentgen b75cab
			fprintf( fd, "\n" );
roentgen b75cab
			return 1;
roentgen b75cab
		}
roentgen b75cab
		case TIFFTAG_RICHTIFFIPTC:
roentgen b75cab
			/*
roentgen b75cab
			 * XXX: for some weird reason RichTIFFIPTC tag
roentgen b75cab
			 * defined as array of LONG values.
roentgen b75cab
			 */
roentgen b75cab
			fprintf(fd,
roentgen b75cab
			    "  RichTIFFIPTC Data: <present>, %lu bytes\n",</present>
roentgen b75cab
			    (unsigned long) value_count * 4);
roentgen b75cab
			return 1;
roentgen b75cab
roentgen b75cab
		case TIFFTAG_PHOTOSHOP:
roentgen b75cab
			fprintf(fd, "  Photoshop Data: <present>, %lu bytes\n",</present>
roentgen b75cab
			    (unsigned long) value_count);
roentgen b75cab
			return 1;
roentgen b75cab
roentgen b75cab
		case TIFFTAG_ICCPROFILE:
roentgen b75cab
			fprintf(fd, "  ICC Profile: <present>, %lu bytes\n",</present>
roentgen b75cab
			    (unsigned long) value_count);
roentgen b75cab
			return 1;
roentgen b75cab
roentgen b75cab
		case TIFFTAG_STONITS:
roentgen b75cab
			if (value_count == 1 && fip->field_type == TIFF_DOUBLE) { 
roentgen b75cab
				fprintf(fd,
roentgen b75cab
					"  Sample to Nits conversion factor: %.4e\n",
roentgen b75cab
					*((double*)raw_data));
roentgen b75cab
				return 1;
roentgen b75cab
			}
roentgen b75cab
			return 0;
roentgen b75cab
	}
roentgen b75cab
roentgen b75cab
	return 0;
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
/*
roentgen b75cab
 * Print the contents of the current directory
roentgen b75cab
 * to the specified stdio file stream.
roentgen b75cab
 */
roentgen b75cab
void
roentgen b75cab
TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
roentgen b75cab
{
roentgen b75cab
	TIFFDirectory *td = &tif->tif_dir;
roentgen b75cab
	char *sep;
roentgen b75cab
	uint16 i;
roentgen b75cab
	long l, n;
roentgen b75cab
roentgen b75cab
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
roentgen b75cab
	fprintf(fd, "TIFF Directory at offset 0x%I64x (%I64u)\n",
roentgen b75cab
		(unsigned __int64) tif->tif_diroff,
roentgen b75cab
		(unsigned __int64) tif->tif_diroff);
roentgen b75cab
#else
roentgen b75cab
	fprintf(fd, "TIFF Directory at offset 0x%llx (%llu)\n",
roentgen b75cab
		(unsigned long long) tif->tif_diroff,
roentgen b75cab
		(unsigned long long) tif->tif_diroff);
roentgen b75cab
#endif
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_SUBFILETYPE)) {
roentgen b75cab
		fprintf(fd, "  Subfile Type:");
roentgen b75cab
		sep = " ";
roentgen b75cab
		if (td->td_subfiletype & FILETYPE_REDUCEDIMAGE) {
roentgen b75cab
			fprintf(fd, "%sreduced-resolution image", sep);
roentgen b75cab
			sep = "/";
roentgen b75cab
		}
roentgen b75cab
		if (td->td_subfiletype & FILETYPE_PAGE) {
roentgen b75cab
			fprintf(fd, "%smulti-page document", sep);
roentgen b75cab
			sep = "/";
roentgen b75cab
		}
roentgen b75cab
		if (td->td_subfiletype & FILETYPE_MASK)
roentgen b75cab
			fprintf(fd, "%stransparency mask", sep);
roentgen b75cab
		fprintf(fd, " (%lu = 0x%lx)\n",
roentgen b75cab
		    (long) td->td_subfiletype, (long) td->td_subfiletype);
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) {
roentgen b75cab
		fprintf(fd, "  Image Width: %lu Image Length: %lu",
roentgen b75cab
		    (unsigned long) td->td_imagewidth, (unsigned long) td->td_imagelength);
roentgen b75cab
		if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH))
roentgen b75cab
			fprintf(fd, " Image Depth: %lu",
roentgen b75cab
			    (unsigned long) td->td_imagedepth);
roentgen b75cab
		fprintf(fd, "\n");
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS)) {
roentgen b75cab
		fprintf(fd, "  Tile Width: %lu Tile Length: %lu",
roentgen b75cab
		    (unsigned long) td->td_tilewidth, (unsigned long) td->td_tilelength);
roentgen b75cab
		if (TIFFFieldSet(tif,FIELD_TILEDEPTH))
roentgen b75cab
			fprintf(fd, " Tile Depth: %lu",
roentgen b75cab
			    (unsigned long) td->td_tiledepth);
roentgen b75cab
		fprintf(fd, "\n");
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_RESOLUTION)) {
roentgen b75cab
		fprintf(fd, "  Resolution: %g, %g",
roentgen b75cab
		    td->td_xresolution, td->td_yresolution);
roentgen b75cab
		if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT)) {
roentgen b75cab
			switch (td->td_resolutionunit) {
roentgen b75cab
			case RESUNIT_NONE:
roentgen b75cab
				fprintf(fd, " (unitless)");
roentgen b75cab
				break;
roentgen b75cab
			case RESUNIT_INCH:
roentgen b75cab
				fprintf(fd, " pixels/inch");
roentgen b75cab
				break;
roentgen b75cab
			case RESUNIT_CENTIMETER:
roentgen b75cab
				fprintf(fd, " pixels/cm");
roentgen b75cab
				break;
roentgen b75cab
			default:
roentgen b75cab
				fprintf(fd, " (unit %u = 0x%x)",
roentgen b75cab
				    td->td_resolutionunit,
roentgen b75cab
				    td->td_resolutionunit);
roentgen b75cab
				break;
roentgen b75cab
			}
roentgen b75cab
		}
roentgen b75cab
		fprintf(fd, "\n");
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_POSITION))
roentgen b75cab
		fprintf(fd, "  Position: %g, %g\n",
roentgen b75cab
		    td->td_xposition, td->td_yposition);
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
roentgen b75cab
		fprintf(fd, "  Bits/Sample: %u\n", td->td_bitspersample);
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT)) {
roentgen b75cab
		fprintf(fd, "  Sample Format: ");
roentgen b75cab
		switch (td->td_sampleformat) {
roentgen b75cab
		case SAMPLEFORMAT_VOID:
roentgen b75cab
			fprintf(fd, "void\n");
roentgen b75cab
			break;
roentgen b75cab
		case SAMPLEFORMAT_INT:
roentgen b75cab
			fprintf(fd, "signed integer\n");
roentgen b75cab
			break;
roentgen b75cab
		case SAMPLEFORMAT_UINT:
roentgen b75cab
			fprintf(fd, "unsigned integer\n");
roentgen b75cab
			break;
roentgen b75cab
		case SAMPLEFORMAT_IEEEFP:
roentgen b75cab
			fprintf(fd, "IEEE floating point\n");
roentgen b75cab
			break;
roentgen b75cab
		case SAMPLEFORMAT_COMPLEXINT:
roentgen b75cab
			fprintf(fd, "complex signed integer\n");
roentgen b75cab
			break;
roentgen b75cab
		case SAMPLEFORMAT_COMPLEXIEEEFP:
roentgen b75cab
			fprintf(fd, "complex IEEE floating point\n");
roentgen b75cab
			break;
roentgen b75cab
		default:
roentgen b75cab
			fprintf(fd, "%u (0x%x)\n",
roentgen b75cab
			    td->td_sampleformat, td->td_sampleformat);
roentgen b75cab
			break;
roentgen b75cab
		}
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_COMPRESSION)) {
roentgen b75cab
		const TIFFCodec* c = TIFFFindCODEC(td->td_compression);
roentgen b75cab
		fprintf(fd, "  Compression Scheme: ");
roentgen b75cab
		if (c)
roentgen b75cab
			fprintf(fd, "%s\n", c->name);
roentgen b75cab
		else
roentgen b75cab
			fprintf(fd, "%u (0x%x)\n",
roentgen b75cab
			    td->td_compression, td->td_compression);
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) {
roentgen b75cab
		fprintf(fd, "  Photometric Interpretation: ");
roentgen b75cab
		if (td->td_photometric < NPHOTONAMES)
roentgen b75cab
			fprintf(fd, "%s\n", photoNames[td->td_photometric]);
roentgen b75cab
		else {
roentgen b75cab
			switch (td->td_photometric) {
roentgen b75cab
			case PHOTOMETRIC_LOGL:
roentgen b75cab
				fprintf(fd, "CIE Log2(L)\n");
roentgen b75cab
				break;
roentgen b75cab
			case PHOTOMETRIC_LOGLUV:
roentgen b75cab
				fprintf(fd, "CIE Log2(L) (u',v')\n");
roentgen b75cab
				break;
roentgen b75cab
			default:
roentgen b75cab
				fprintf(fd, "%u (0x%x)\n",
roentgen b75cab
				    td->td_photometric, td->td_photometric);
roentgen b75cab
				break;
roentgen b75cab
			}
roentgen b75cab
		}
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES) && td->td_extrasamples) {
roentgen b75cab
		fprintf(fd, "  Extra Samples: %u<", td->td_extrasamples);
roentgen b75cab
		sep = "";
roentgen b75cab
		for (i = 0; i < td->td_extrasamples; i++) {
roentgen b75cab
			switch (td->td_sampleinfo[i]) {
roentgen b75cab
			case EXTRASAMPLE_UNSPECIFIED:
roentgen b75cab
				fprintf(fd, "%sunspecified", sep);
roentgen b75cab
				break;
roentgen b75cab
			case EXTRASAMPLE_ASSOCALPHA:
roentgen b75cab
				fprintf(fd, "%sassoc-alpha", sep);
roentgen b75cab
				break;
roentgen b75cab
			case EXTRASAMPLE_UNASSALPHA:
roentgen b75cab
				fprintf(fd, "%sunassoc-alpha", sep);
roentgen b75cab
				break;
roentgen b75cab
			default:
roentgen b75cab
				fprintf(fd, "%s%u (0x%x)", sep,
roentgen b75cab
				    td->td_sampleinfo[i], td->td_sampleinfo[i]);
roentgen b75cab
				break;
roentgen b75cab
			}
roentgen b75cab
			sep = ", ";
roentgen b75cab
		}
roentgen b75cab
		fprintf(fd, ">\n");
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_INKNAMES)) {
roentgen b75cab
		char* cp;
roentgen b75cab
		fprintf(fd, "  Ink Names: ");
roentgen b75cab
		i = td->td_samplesperpixel;
roentgen b75cab
		sep = "";
roentgen b75cab
		for (cp = td->td_inknames; 
roentgen b75cab
		     i > 0 && cp < td->td_inknames + td->td_inknameslen; 
roentgen b75cab
		     cp = strchr(cp,'\0')+1, i--) {
roentgen b75cab
			int max_chars = 
roentgen b75cab
				td->td_inknameslen - (cp - td->td_inknames);
roentgen b75cab
			fputs(sep, fd);
roentgen b75cab
			_TIFFprintAsciiBounded(fd, cp, max_chars);
roentgen b75cab
			sep = ", ";
roentgen b75cab
		}
roentgen b75cab
                fputs("\n", fd);
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_THRESHHOLDING)) {
roentgen b75cab
		fprintf(fd, "  Thresholding: ");
roentgen b75cab
		switch (td->td_threshholding) {
roentgen b75cab
		case THRESHHOLD_BILEVEL:
roentgen b75cab
			fprintf(fd, "bilevel art scan\n");
roentgen b75cab
			break;
roentgen b75cab
		case THRESHHOLD_HALFTONE:
roentgen b75cab
			fprintf(fd, "halftone or dithered scan\n");
roentgen b75cab
			break;
roentgen b75cab
		case THRESHHOLD_ERRORDIFFUSE:
roentgen b75cab
			fprintf(fd, "error diffused\n");
roentgen b75cab
			break;
roentgen b75cab
		default:
roentgen b75cab
			fprintf(fd, "%u (0x%x)\n",
roentgen b75cab
			    td->td_threshholding, td->td_threshholding);
roentgen b75cab
			break;
roentgen b75cab
		}
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_FILLORDER)) {
roentgen b75cab
		fprintf(fd, "  FillOrder: ");
roentgen b75cab
		switch (td->td_fillorder) {
roentgen b75cab
		case FILLORDER_MSB2LSB:
roentgen b75cab
			fprintf(fd, "msb-to-lsb\n");
roentgen b75cab
			break;
roentgen b75cab
		case FILLORDER_LSB2MSB:
roentgen b75cab
			fprintf(fd, "lsb-to-msb\n");
roentgen b75cab
			break;
roentgen b75cab
		default:
roentgen b75cab
			fprintf(fd, "%u (0x%x)\n",
roentgen b75cab
			    td->td_fillorder, td->td_fillorder);
roentgen b75cab
			break;
roentgen b75cab
		}
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING))
roentgen b75cab
        {
roentgen b75cab
		fprintf(fd, "  YCbCr Subsampling: %u, %u\n",
roentgen b75cab
			td->td_ycbcrsubsampling[0], td->td_ycbcrsubsampling[1] );
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING)) {
roentgen b75cab
		fprintf(fd, "  YCbCr Positioning: ");
roentgen b75cab
		switch (td->td_ycbcrpositioning) {
roentgen b75cab
		case YCBCRPOSITION_CENTERED:
roentgen b75cab
			fprintf(fd, "centered\n");
roentgen b75cab
			break;
roentgen b75cab
		case YCBCRPOSITION_COSITED:
roentgen b75cab
			fprintf(fd, "cosited\n");
roentgen b75cab
			break;
roentgen b75cab
		default:
roentgen b75cab
			fprintf(fd, "%u (0x%x)\n",
roentgen b75cab
			    td->td_ycbcrpositioning, td->td_ycbcrpositioning);
roentgen b75cab
			break;
roentgen b75cab
		}
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS))
roentgen b75cab
		fprintf(fd, "  Halftone Hints: light %u dark %u\n",
roentgen b75cab
		    td->td_halftonehints[0], td->td_halftonehints[1]);
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_ORIENTATION)) {
roentgen b75cab
		fprintf(fd, "  Orientation: ");
roentgen b75cab
		if (td->td_orientation < NORIENTNAMES)
roentgen b75cab
			fprintf(fd, "%s\n", orientNames[td->td_orientation]);
roentgen b75cab
		else
roentgen b75cab
			fprintf(fd, "%u (0x%x)\n",
roentgen b75cab
			    td->td_orientation, td->td_orientation);
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
roentgen b75cab
		fprintf(fd, "  Samples/Pixel: %u\n", td->td_samplesperpixel);
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP)) {
roentgen b75cab
		fprintf(fd, "  Rows/Strip: ");
roentgen b75cab
		if (td->td_rowsperstrip == (uint32) -1)
roentgen b75cab
			fprintf(fd, "(infinite)\n");
roentgen b75cab
		else
roentgen b75cab
			fprintf(fd, "%lu\n", (unsigned long) td->td_rowsperstrip);
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE))
roentgen b75cab
		fprintf(fd, "  Min Sample Value: %u\n", td->td_minsamplevalue);
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE))
roentgen b75cab
		fprintf(fd, "  Max Sample Value: %u\n", td->td_maxsamplevalue);
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE)) {
roentgen b75cab
		int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
roentgen b75cab
		fprintf(fd, "  SMin Sample Value:");
roentgen b75cab
		for (i = 0; i < count; ++i)
roentgen b75cab
			fprintf(fd, " %g", td->td_sminsamplevalue[i]);
roentgen b75cab
		fprintf(fd, "\n");
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE)) {
roentgen b75cab
		int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
roentgen b75cab
		fprintf(fd, "  SMax Sample Value:");
roentgen b75cab
		for (i = 0; i < count; ++i)
roentgen b75cab
			fprintf(fd, " %g", td->td_smaxsamplevalue[i]);
roentgen b75cab
		fprintf(fd, "\n");
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_PLANARCONFIG)) {
roentgen b75cab
		fprintf(fd, "  Planar Configuration: ");
roentgen b75cab
		switch (td->td_planarconfig) {
roentgen b75cab
		case PLANARCONFIG_CONTIG:
roentgen b75cab
			fprintf(fd, "single image plane\n");
roentgen b75cab
			break;
roentgen b75cab
		case PLANARCONFIG_SEPARATE:
roentgen b75cab
			fprintf(fd, "separate image planes\n");
roentgen b75cab
			break;
roentgen b75cab
		default:
roentgen b75cab
			fprintf(fd, "%u (0x%x)\n",
roentgen b75cab
			    td->td_planarconfig, td->td_planarconfig);
roentgen b75cab
			break;
roentgen b75cab
		}
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_PAGENUMBER))
roentgen b75cab
		fprintf(fd, "  Page Number: %u-%u\n",
roentgen b75cab
		    td->td_pagenumber[0], td->td_pagenumber[1]);
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_COLORMAP)) {
roentgen b75cab
		fprintf(fd, "  Color Map: ");
roentgen b75cab
		if (flags & TIFFPRINT_COLORMAP) {
roentgen b75cab
			fprintf(fd, "\n");
roentgen b75cab
			n = 1L<<td->td_bitspersample;</td->
roentgen b75cab
			for (l = 0; l < n; l++)
roentgen b75cab
				fprintf(fd, "   %5lu: %5u %5u %5u\n",
roentgen b75cab
				    l,
roentgen b75cab
				    td->td_colormap[0][l],
roentgen b75cab
				    td->td_colormap[1][l],
roentgen b75cab
				    td->td_colormap[2][l]);
roentgen b75cab
		} else
roentgen b75cab
			fprintf(fd, "(present)\n");
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE)) {
roentgen b75cab
		fprintf(fd, "  Reference Black/White:\n");
roentgen b75cab
		for (i = 0; i < 3; i++)
roentgen b75cab
		fprintf(fd, "    %2d: %5g %5g\n", i,
roentgen b75cab
			td->td_refblackwhite[2*i+0],
roentgen b75cab
			td->td_refblackwhite[2*i+1]);
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION)) {
roentgen b75cab
		fprintf(fd, "  Transfer Function: ");
roentgen b75cab
		if (flags & TIFFPRINT_CURVES) {
roentgen b75cab
			fprintf(fd, "\n");
roentgen b75cab
			n = 1L<<td->td_bitspersample;</td->
roentgen b75cab
			for (l = 0; l < n; l++) {
roentgen b75cab
				fprintf(fd, "    %2lu: %5u",
roentgen b75cab
				    l, td->td_transferfunction[0][l]);
roentgen b75cab
				for (i = 1; i < td->td_samplesperpixel; i++)
roentgen b75cab
					fprintf(fd, " %5u",
roentgen b75cab
					    td->td_transferfunction[i][l]);
roentgen b75cab
				fputc('\n', fd);
roentgen b75cab
			}
roentgen b75cab
		} else
roentgen b75cab
			fprintf(fd, "(present)\n");
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif, FIELD_SUBIFD) && (td->td_subifd)) {
roentgen b75cab
		fprintf(fd, "  SubIFD Offsets:");
roentgen b75cab
		for (i = 0; i < td->td_nsubifd; i++)
roentgen b75cab
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
roentgen b75cab
			fprintf(fd, " %5I64u",
roentgen b75cab
				(unsigned __int64) td->td_subifd[i]);
roentgen b75cab
#else
roentgen b75cab
			fprintf(fd, " %5llu",
roentgen b75cab
				(unsigned long long) td->td_subifd[i]);
roentgen b75cab
#endif
roentgen b75cab
		fputc('\n', fd);
roentgen b75cab
	}
roentgen b75cab
roentgen b75cab
	/*
roentgen b75cab
	** Custom tag support.
roentgen b75cab
	*/
roentgen b75cab
	{
roentgen b75cab
		int  i;
roentgen b75cab
		short count;
roentgen b75cab
roentgen b75cab
		count = (short) TIFFGetTagListCount(tif);
roentgen b75cab
		for(i = 0; i < count; i++) {
roentgen b75cab
			uint32 tag = TIFFGetTagListEntry(tif, i);
roentgen b75cab
			const TIFFField *fip;
roentgen b75cab
			uint32 value_count;
roentgen b75cab
			int mem_alloc = 0;
roentgen b75cab
			void *raw_data;
roentgen b75cab
roentgen b75cab
			fip = TIFFFieldWithTag(tif, tag);
roentgen b75cab
			if(fip == NULL)
roentgen b75cab
				continue;
roentgen b75cab
roentgen b75cab
			if(fip->field_passcount) {
roentgen b75cab
				if (fip->field_readcount == TIFF_VARIABLE ) {
roentgen b75cab
					if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1)
roentgen b75cab
						continue;
roentgen b75cab
				} else if (fip->field_readcount == TIFF_VARIABLE2 ) {
roentgen b75cab
					uint16 small_value_count;
roentgen b75cab
					if(TIFFGetField(tif, tag, &small_value_count, &raw_data) != 1)
roentgen b75cab
						continue;
roentgen b75cab
					value_count = small_value_count;
roentgen b75cab
				} else {
roentgen b75cab
					assert (fip->field_readcount == TIFF_VARIABLE
roentgen b75cab
						|| fip->field_readcount == TIFF_VARIABLE2);
roentgen b75cab
					continue;
roentgen b75cab
				} 
roentgen b75cab
			} else {
roentgen b75cab
				if (fip->field_readcount == TIFF_VARIABLE
roentgen b75cab
				    || fip->field_readcount == TIFF_VARIABLE2)
roentgen b75cab
					value_count = 1;
roentgen b75cab
				else if (fip->field_readcount == TIFF_SPP)
roentgen b75cab
					value_count = td->td_samplesperpixel;
roentgen b75cab
				else
roentgen b75cab
					value_count = fip->field_readcount;
roentgen b75cab
				if (fip->field_tag == TIFFTAG_DOTRANGE
roentgen b75cab
				    && strcmp(fip->field_name,"DotRange") == 0) {
roentgen b75cab
					/* TODO: This is an evil exception and should not have been
roentgen b75cab
					   handled this way ... likely best if we move it into
roentgen b75cab
					   the directory structure with an explicit field in 
roentgen b75cab
					   libtiff 4.1 and assign it a FIELD_ value */
roentgen b75cab
					static uint16 dotrange[2];
roentgen b75cab
					raw_data = dotrange;
roentgen b75cab
					TIFFGetField(tif, tag, dotrange+0, dotrange+1);
roentgen b75cab
				} else if (fip->field_type == TIFF_ASCII
roentgen b75cab
					   || fip->field_readcount == TIFF_VARIABLE
roentgen b75cab
					   || fip->field_readcount == TIFF_VARIABLE2
roentgen b75cab
					   || fip->field_readcount == TIFF_SPP
roentgen b75cab
					   || value_count > 1) {
roentgen b75cab
					if(TIFFGetField(tif, tag, &raw_data) != 1)
roentgen b75cab
						continue;
roentgen b75cab
				} else {
roentgen b75cab
					raw_data = _TIFFmalloc(
roentgen b75cab
					    _TIFFDataSize(fip->field_type)
roentgen b75cab
					    * value_count);
roentgen b75cab
					mem_alloc = 1;
roentgen b75cab
					if(TIFFGetField(tif, tag, raw_data) != 1) {
roentgen b75cab
						_TIFFfree(raw_data);
roentgen b75cab
						continue;
roentgen b75cab
					}
roentgen b75cab
				}
roentgen b75cab
			}
roentgen b75cab
roentgen b75cab
			/*
roentgen b75cab
			 * Catch the tags which needs to be specially handled
roentgen b75cab
			 * and pretty print them. If tag not handled in
roentgen b75cab
			 * _TIFFPrettyPrintField() fall down and print it as
roentgen b75cab
			 * any other tag.
roentgen b75cab
			 */
roentgen b75cab
			if (!_TIFFPrettyPrintField(tif, fip, fd, tag, value_count, raw_data))
roentgen b75cab
				_TIFFPrintField(fd, fip, value_count, raw_data);
roentgen b75cab
roentgen b75cab
			if(mem_alloc)
roentgen b75cab
				_TIFFfree(raw_data);
roentgen b75cab
		}
roentgen b75cab
	}
roentgen b75cab
        
roentgen b75cab
	if (tif->tif_tagmethods.printdir)
roentgen b75cab
		(*tif->tif_tagmethods.printdir)(tif, fd, flags);
roentgen b75cab
roentgen b75cab
        _TIFFFillStriles( tif );
roentgen b75cab
        
roentgen b75cab
	if ((flags & TIFFPRINT_STRIPS) &&
roentgen b75cab
	    TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) {
roentgen b75cab
		uint32 s;
roentgen b75cab
roentgen b75cab
		fprintf(fd, "  %lu %s:\n",
roentgen b75cab
		    (long) td->td_nstrips,
roentgen b75cab
		    isTiled(tif) ? "Tiles" : "Strips");
roentgen b75cab
		for (s = 0; s < td->td_nstrips; s++)
roentgen b75cab
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
roentgen b75cab
			fprintf(fd, "    %3lu: [%8I64u, %8I64u]\n",
roentgen b75cab
			    (unsigned long) s,
roentgen b75cab
			    (unsigned __int64) td->td_stripoffset[s],
roentgen b75cab
			    (unsigned __int64) td->td_stripbytecount[s]);
roentgen b75cab
#else
roentgen b75cab
			fprintf(fd, "    %3lu: [%8llu, %8llu]\n",
roentgen b75cab
			    (unsigned long) s,
roentgen b75cab
			    (unsigned long long) td->td_stripoffset[s],
roentgen b75cab
			    (unsigned long long) td->td_stripbytecount[s]);
roentgen b75cab
#endif
roentgen b75cab
	}
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
void
roentgen b75cab
_TIFFprintAscii(FILE* fd, const char* cp)
roentgen b75cab
{
roentgen b75cab
	_TIFFprintAsciiBounded( fd, cp, strlen(cp));
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
_TIFFprintAsciiBounded(FILE* fd, const char* cp, int max_chars)
roentgen b75cab
{
roentgen b75cab
	for (; max_chars > 0 && *cp != '\0'; cp++, max_chars--) {
roentgen b75cab
		const char* tp;
roentgen b75cab
roentgen b75cab
		if (isprint((int)*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
roentgen b75cab
			fprintf(fd, "\\%03o", *cp & 0xff);
roentgen b75cab
	}
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
void
roentgen b75cab
_TIFFprintAsciiTag(FILE* fd, const char* name, const char* value)
roentgen b75cab
{
roentgen b75cab
	fprintf(fd, "  %s: \"", name);
roentgen b75cab
	_TIFFprintAscii(fd, value);
roentgen b75cab
	fprintf(fd, "\"\n");
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
 */