Home | History | Annotate | Download | only in libtiff
      1 /* $Id: tif_print.c,v 1.65 2016-11-20 22:31:22 erouault Exp $ */
      2 
      3 /*
      4  * Copyright (c) 1988-1997 Sam Leffler
      5  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
      6  *
      7  * Permission to use, copy, modify, distribute, and sell this software and
      8  * its documentation for any purpose is hereby granted without fee, provided
      9  * that (i) the above copyright notices and this permission notice appear in
     10  * all copies of the software and related documentation, and (ii) the names of
     11  * Sam Leffler and Silicon Graphics may not be used in any advertising or
     12  * publicity relating to the software without the specific, prior written
     13  * permission of Sam Leffler and Silicon Graphics.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
     16  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
     17  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
     18  *
     19  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
     20  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
     21  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
     22  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
     23  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
     24  * OF THIS SOFTWARE.
     25  */
     26 
     27 /*
     28  * TIFF Library.
     29  *
     30  * Directory Printing Support
     31  */
     32 #include "tiffiop.h"
     33 #include <stdio.h>
     34 
     35 #include <ctype.h>
     36 
     37 static void
     38 _TIFFprintAsciiBounded(FILE* fd, const char* cp, size_t max_chars);
     39 
     40 static const char * const photoNames[] = {
     41     "min-is-white",				/* PHOTOMETRIC_MINISWHITE */
     42     "min-is-black",				/* PHOTOMETRIC_MINISBLACK */
     43     "RGB color",				/* PHOTOMETRIC_RGB */
     44     "palette color (RGB from colormap)",	/* PHOTOMETRIC_PALETTE */
     45     "transparency mask",			/* PHOTOMETRIC_MASK */
     46     "separated",				/* PHOTOMETRIC_SEPARATED */
     47     "YCbCr",					/* PHOTOMETRIC_YCBCR */
     48     "7 (0x7)",
     49     "CIE L*a*b*",				/* PHOTOMETRIC_CIELAB */
     50     "ICC L*a*b*",				/* PHOTOMETRIC_ICCLAB */
     51     "ITU L*a*b*" 				/* PHOTOMETRIC_ITULAB */
     52 };
     53 #define	NPHOTONAMES	(sizeof (photoNames) / sizeof (photoNames[0]))
     54 
     55 static const char * const orientNames[] = {
     56     "0 (0x0)",
     57     "row 0 top, col 0 lhs",			/* ORIENTATION_TOPLEFT */
     58     "row 0 top, col 0 rhs",			/* ORIENTATION_TOPRIGHT */
     59     "row 0 bottom, col 0 rhs",			/* ORIENTATION_BOTRIGHT */
     60     "row 0 bottom, col 0 lhs",			/* ORIENTATION_BOTLEFT */
     61     "row 0 lhs, col 0 top",			/* ORIENTATION_LEFTTOP */
     62     "row 0 rhs, col 0 top",			/* ORIENTATION_RIGHTTOP */
     63     "row 0 rhs, col 0 bottom",			/* ORIENTATION_RIGHTBOT */
     64     "row 0 lhs, col 0 bottom",			/* ORIENTATION_LEFTBOT */
     65 };
     66 #define	NORIENTNAMES	(sizeof (orientNames) / sizeof (orientNames[0]))
     67 
     68 static void
     69 _TIFFPrintField(FILE* fd, const TIFFField *fip,
     70 		uint32 value_count, void *raw_data)
     71 {
     72 	uint32 j;
     73 
     74 	fprintf(fd, "  %s: ", fip->field_name);
     75 
     76 	for(j = 0; j < value_count; j++) {
     77 		if(fip->field_type == TIFF_BYTE)
     78 			fprintf(fd, "%u", ((uint8 *) raw_data)[j]);
     79 		else if(fip->field_type == TIFF_UNDEFINED)
     80 			fprintf(fd, "0x%x",
     81 			    (unsigned int) ((unsigned char *) raw_data)[j]);
     82 		else if(fip->field_type == TIFF_SBYTE)
     83 			fprintf(fd, "%d", ((int8 *) raw_data)[j]);
     84 		else if(fip->field_type == TIFF_SHORT)
     85 			fprintf(fd, "%u", ((uint16 *) raw_data)[j]);
     86 		else if(fip->field_type == TIFF_SSHORT)
     87 			fprintf(fd, "%d", ((int16 *) raw_data)[j]);
     88 		else if(fip->field_type == TIFF_LONG)
     89 			fprintf(fd, "%lu",
     90 			    (unsigned long)((uint32 *) raw_data)[j]);
     91 		else if(fip->field_type == TIFF_SLONG)
     92 			fprintf(fd, "%ld", (long)((int32 *) raw_data)[j]);
     93 		else if(fip->field_type == TIFF_IFD)
     94 			fprintf(fd, "0x%lx",
     95 				(unsigned long)((uint32 *) raw_data)[j]);
     96 		else if(fip->field_type == TIFF_RATIONAL
     97 			|| fip->field_type == TIFF_SRATIONAL
     98 			|| fip->field_type == TIFF_FLOAT)
     99 			fprintf(fd, "%f", ((float *) raw_data)[j]);
    100 		else if(fip->field_type == TIFF_LONG8)
    101 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
    102 			fprintf(fd, "%I64u",
    103 			    (unsigned __int64)((uint64 *) raw_data)[j]);
    104 #else
    105 			fprintf(fd, "%llu",
    106 			    (unsigned long long)((uint64 *) raw_data)[j]);
    107 #endif
    108 		else if(fip->field_type == TIFF_SLONG8)
    109 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
    110 			fprintf(fd, "%I64d", (__int64)((int64 *) raw_data)[j]);
    111 #else
    112 			fprintf(fd, "%lld", (long long)((int64 *) raw_data)[j]);
    113 #endif
    114 		else if(fip->field_type == TIFF_IFD8)
    115 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
    116 			fprintf(fd, "0x%I64x",
    117 				(unsigned __int64)((uint64 *) raw_data)[j]);
    118 #else
    119 			fprintf(fd, "0x%llx",
    120 				(unsigned long long)((uint64 *) raw_data)[j]);
    121 #endif
    122 		else if(fip->field_type == TIFF_FLOAT)
    123 			fprintf(fd, "%f", ((float *)raw_data)[j]);
    124 		else if(fip->field_type == TIFF_DOUBLE)
    125 			fprintf(fd, "%f", ((double *) raw_data)[j]);
    126 		else if(fip->field_type == TIFF_ASCII) {
    127 			fprintf(fd, "%s", (char *) raw_data);
    128 			break;
    129 		}
    130 		else {
    131 			fprintf(fd, "<unsupported data type in TIFFPrint>");
    132 			break;
    133 		}
    134 
    135 		if(j < value_count - 1)
    136 			fprintf(fd, ",");
    137 	}
    138 
    139 	fprintf(fd, "\n");
    140 }
    141 
    142 static int
    143 _TIFFPrettyPrintField(TIFF* tif, const TIFFField *fip, FILE* fd, uint32 tag,
    144 		      uint32 value_count, void *raw_data)
    145 {
    146         (void) tif;
    147 
    148 	/* do not try to pretty print auto-defined fields */
    149 	if (strncmp(fip->field_name,"Tag ", 4) == 0) {
    150 		return 0;
    151 	}
    152 
    153 	switch (tag)
    154 	{
    155 		case TIFFTAG_INKSET:
    156 			if (value_count == 2 && fip->field_type == TIFF_SHORT) {
    157 				fprintf(fd, "  Ink Set: ");
    158 				switch (*((uint16*)raw_data)) {
    159 				case INKSET_CMYK:
    160 					fprintf(fd, "CMYK\n");
    161 					break;
    162 				default:
    163 					fprintf(fd, "%u (0x%x)\n",
    164 						*((uint16*)raw_data),
    165 						*((uint16*)raw_data));
    166 					break;
    167 				}
    168 				return 1;
    169 			}
    170 			return 0;
    171 
    172 		case TIFFTAG_DOTRANGE:
    173 			if (value_count == 2 && fip->field_type == TIFF_SHORT) {
    174 				fprintf(fd, "  Dot Range: %u-%u\n",
    175 					((uint16*)raw_data)[0], ((uint16*)raw_data)[1]);
    176 				return 1;
    177 			}
    178 			return 0;
    179 
    180 		case TIFFTAG_WHITEPOINT:
    181 			if (value_count == 2 && fip->field_type == TIFF_RATIONAL) {
    182 				fprintf(fd, "  White Point: %g-%g\n",
    183 					((float *)raw_data)[0], ((float *)raw_data)[1]);
    184 				return 1;
    185 			}
    186 			return 0;
    187 
    188 		case TIFFTAG_XMLPACKET:
    189 		{
    190 			uint32 i;
    191 
    192 			fprintf(fd, "  XMLPacket (XMP Metadata):\n" );
    193 			for(i = 0; i < value_count; i++)
    194 				fputc(((char *)raw_data)[i], fd);
    195 			fprintf( fd, "\n" );
    196 			return 1;
    197 		}
    198 		case TIFFTAG_RICHTIFFIPTC:
    199 			/*
    200 			 * XXX: for some weird reason RichTIFFIPTC tag
    201 			 * defined as array of LONG values.
    202 			 */
    203 			fprintf(fd,
    204 			    "  RichTIFFIPTC Data: <present>, %lu bytes\n",
    205 			    (unsigned long) value_count * 4);
    206 			return 1;
    207 
    208 		case TIFFTAG_PHOTOSHOP:
    209 			fprintf(fd, "  Photoshop Data: <present>, %lu bytes\n",
    210 			    (unsigned long) value_count);
    211 			return 1;
    212 
    213 		case TIFFTAG_ICCPROFILE:
    214 			fprintf(fd, "  ICC Profile: <present>, %lu bytes\n",
    215 			    (unsigned long) value_count);
    216 			return 1;
    217 
    218 		case TIFFTAG_STONITS:
    219 			if (value_count == 1 && fip->field_type == TIFF_DOUBLE) {
    220 				fprintf(fd,
    221 					"  Sample to Nits conversion factor: %.4e\n",
    222 					*((double*)raw_data));
    223 				return 1;
    224 			}
    225 			return 0;
    226 	}
    227 
    228 	return 0;
    229 }
    230 
    231 /*
    232  * Print the contents of the current directory
    233  * to the specified stdio file stream.
    234  */
    235 void
    236 TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
    237 {
    238 	TIFFDirectory *td = &tif->tif_dir;
    239 	char *sep;
    240 	long l, n;
    241 
    242 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
    243 	fprintf(fd, "TIFF Directory at offset 0x%I64x (%I64u)\n",
    244 		(unsigned __int64) tif->tif_diroff,
    245 		(unsigned __int64) tif->tif_diroff);
    246 #else
    247 	fprintf(fd, "TIFF Directory at offset 0x%llx (%llu)\n",
    248 		(unsigned long long) tif->tif_diroff,
    249 		(unsigned long long) tif->tif_diroff);
    250 #endif
    251 	if (TIFFFieldSet(tif,FIELD_SUBFILETYPE)) {
    252 		fprintf(fd, "  Subfile Type:");
    253 		sep = " ";
    254 		if (td->td_subfiletype & FILETYPE_REDUCEDIMAGE) {
    255 			fprintf(fd, "%sreduced-resolution image", sep);
    256 			sep = "/";
    257 		}
    258 		if (td->td_subfiletype & FILETYPE_PAGE) {
    259 			fprintf(fd, "%smulti-page document", sep);
    260 			sep = "/";
    261 		}
    262 		if (td->td_subfiletype & FILETYPE_MASK)
    263 			fprintf(fd, "%stransparency mask", sep);
    264 		fprintf(fd, " (%lu = 0x%lx)\n",
    265 		    (unsigned long) td->td_subfiletype, (long) td->td_subfiletype);
    266 	}
    267 	if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) {
    268 		fprintf(fd, "  Image Width: %lu Image Length: %lu",
    269 		    (unsigned long) td->td_imagewidth, (unsigned long) td->td_imagelength);
    270 		if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH))
    271 			fprintf(fd, " Image Depth: %lu",
    272 			    (unsigned long) td->td_imagedepth);
    273 		fprintf(fd, "\n");
    274 	}
    275 	if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS)) {
    276 		fprintf(fd, "  Tile Width: %lu Tile Length: %lu",
    277 		    (unsigned long) td->td_tilewidth, (unsigned long) td->td_tilelength);
    278 		if (TIFFFieldSet(tif,FIELD_TILEDEPTH))
    279 			fprintf(fd, " Tile Depth: %lu",
    280 			    (unsigned long) td->td_tiledepth);
    281 		fprintf(fd, "\n");
    282 	}
    283 	if (TIFFFieldSet(tif,FIELD_RESOLUTION)) {
    284 		fprintf(fd, "  Resolution: %g, %g",
    285 		    td->td_xresolution, td->td_yresolution);
    286 		if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT)) {
    287 			switch (td->td_resolutionunit) {
    288 			case RESUNIT_NONE:
    289 				fprintf(fd, " (unitless)");
    290 				break;
    291 			case RESUNIT_INCH:
    292 				fprintf(fd, " pixels/inch");
    293 				break;
    294 			case RESUNIT_CENTIMETER:
    295 				fprintf(fd, " pixels/cm");
    296 				break;
    297 			default:
    298 				fprintf(fd, " (unit %u = 0x%x)",
    299 				    td->td_resolutionunit,
    300 				    td->td_resolutionunit);
    301 				break;
    302 			}
    303 		}
    304 		fprintf(fd, "\n");
    305 	}
    306 	if (TIFFFieldSet(tif,FIELD_POSITION))
    307 		fprintf(fd, "  Position: %g, %g\n",
    308 		    td->td_xposition, td->td_yposition);
    309 	if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
    310 		fprintf(fd, "  Bits/Sample: %u\n", td->td_bitspersample);
    311 	if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT)) {
    312 		fprintf(fd, "  Sample Format: ");
    313 		switch (td->td_sampleformat) {
    314 		case SAMPLEFORMAT_VOID:
    315 			fprintf(fd, "void\n");
    316 			break;
    317 		case SAMPLEFORMAT_INT:
    318 			fprintf(fd, "signed integer\n");
    319 			break;
    320 		case SAMPLEFORMAT_UINT:
    321 			fprintf(fd, "unsigned integer\n");
    322 			break;
    323 		case SAMPLEFORMAT_IEEEFP:
    324 			fprintf(fd, "IEEE floating point\n");
    325 			break;
    326 		case SAMPLEFORMAT_COMPLEXINT:
    327 			fprintf(fd, "complex signed integer\n");
    328 			break;
    329 		case SAMPLEFORMAT_COMPLEXIEEEFP:
    330 			fprintf(fd, "complex IEEE floating point\n");
    331 			break;
    332 		default:
    333 			fprintf(fd, "%u (0x%x)\n",
    334 			    td->td_sampleformat, td->td_sampleformat);
    335 			break;
    336 		}
    337 	}
    338 	if (TIFFFieldSet(tif,FIELD_COMPRESSION)) {
    339 		const TIFFCodec* c = TIFFFindCODEC(td->td_compression);
    340 		fprintf(fd, "  Compression Scheme: ");
    341 		if (c)
    342 			fprintf(fd, "%s\n", c->name);
    343 		else
    344 			fprintf(fd, "%u (0x%x)\n",
    345 			    td->td_compression, td->td_compression);
    346 	}
    347 	if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) {
    348 		fprintf(fd, "  Photometric Interpretation: ");
    349 		if (td->td_photometric < NPHOTONAMES)
    350 			fprintf(fd, "%s\n", photoNames[td->td_photometric]);
    351 		else {
    352 			switch (td->td_photometric) {
    353 			case PHOTOMETRIC_LOGL:
    354 				fprintf(fd, "CIE Log2(L)\n");
    355 				break;
    356 			case PHOTOMETRIC_LOGLUV:
    357 				fprintf(fd, "CIE Log2(L) (u',v')\n");
    358 				break;
    359 			default:
    360 				fprintf(fd, "%u (0x%x)\n",
    361 				    td->td_photometric, td->td_photometric);
    362 				break;
    363 			}
    364 		}
    365 	}
    366 	if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES) && td->td_extrasamples) {
    367 		uint16 i;
    368 		fprintf(fd, "  Extra Samples: %u<", td->td_extrasamples);
    369 		sep = "";
    370 		for (i = 0; i < td->td_extrasamples; i++) {
    371 			switch (td->td_sampleinfo[i]) {
    372 			case EXTRASAMPLE_UNSPECIFIED:
    373 				fprintf(fd, "%sunspecified", sep);
    374 				break;
    375 			case EXTRASAMPLE_ASSOCALPHA:
    376 				fprintf(fd, "%sassoc-alpha", sep);
    377 				break;
    378 			case EXTRASAMPLE_UNASSALPHA:
    379 				fprintf(fd, "%sunassoc-alpha", sep);
    380 				break;
    381 			default:
    382 				fprintf(fd, "%s%u (0x%x)", sep,
    383 				    td->td_sampleinfo[i], td->td_sampleinfo[i]);
    384 				break;
    385 			}
    386 			sep = ", ";
    387 		}
    388 		fprintf(fd, ">\n");
    389 	}
    390 	if (TIFFFieldSet(tif,FIELD_INKNAMES)) {
    391 		char* cp;
    392 		uint16 i;
    393 		fprintf(fd, "  Ink Names: ");
    394 		i = td->td_samplesperpixel;
    395 		sep = "";
    396 		for (cp = td->td_inknames;
    397 		     i > 0 && cp < td->td_inknames + td->td_inknameslen;
    398 		     cp = strchr(cp,'\0')+1, i--) {
    399 			size_t max_chars =
    400 				td->td_inknameslen - (cp - td->td_inknames);
    401 			fputs(sep, fd);
    402 			_TIFFprintAsciiBounded(fd, cp, max_chars);
    403 			sep = ", ";
    404 		}
    405                 fputs("\n", fd);
    406 	}
    407 	if (TIFFFieldSet(tif,FIELD_THRESHHOLDING)) {
    408 		fprintf(fd, "  Thresholding: ");
    409 		switch (td->td_threshholding) {
    410 		case THRESHHOLD_BILEVEL:
    411 			fprintf(fd, "bilevel art scan\n");
    412 			break;
    413 		case THRESHHOLD_HALFTONE:
    414 			fprintf(fd, "halftone or dithered scan\n");
    415 			break;
    416 		case THRESHHOLD_ERRORDIFFUSE:
    417 			fprintf(fd, "error diffused\n");
    418 			break;
    419 		default:
    420 			fprintf(fd, "%u (0x%x)\n",
    421 			    td->td_threshholding, td->td_threshholding);
    422 			break;
    423 		}
    424 	}
    425 	if (TIFFFieldSet(tif,FIELD_FILLORDER)) {
    426 		fprintf(fd, "  FillOrder: ");
    427 		switch (td->td_fillorder) {
    428 		case FILLORDER_MSB2LSB:
    429 			fprintf(fd, "msb-to-lsb\n");
    430 			break;
    431 		case FILLORDER_LSB2MSB:
    432 			fprintf(fd, "lsb-to-msb\n");
    433 			break;
    434 		default:
    435 			fprintf(fd, "%u (0x%x)\n",
    436 			    td->td_fillorder, td->td_fillorder);
    437 			break;
    438 		}
    439 	}
    440 	if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING))
    441         {
    442 		fprintf(fd, "  YCbCr Subsampling: %u, %u\n",
    443 			td->td_ycbcrsubsampling[0], td->td_ycbcrsubsampling[1] );
    444 	}
    445 	if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING)) {
    446 		fprintf(fd, "  YCbCr Positioning: ");
    447 		switch (td->td_ycbcrpositioning) {
    448 		case YCBCRPOSITION_CENTERED:
    449 			fprintf(fd, "centered\n");
    450 			break;
    451 		case YCBCRPOSITION_COSITED:
    452 			fprintf(fd, "cosited\n");
    453 			break;
    454 		default:
    455 			fprintf(fd, "%u (0x%x)\n",
    456 			    td->td_ycbcrpositioning, td->td_ycbcrpositioning);
    457 			break;
    458 		}
    459 	}
    460 	if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS))
    461 		fprintf(fd, "  Halftone Hints: light %u dark %u\n",
    462 		    td->td_halftonehints[0], td->td_halftonehints[1]);
    463 	if (TIFFFieldSet(tif,FIELD_ORIENTATION)) {
    464 		fprintf(fd, "  Orientation: ");
    465 		if (td->td_orientation < NORIENTNAMES)
    466 			fprintf(fd, "%s\n", orientNames[td->td_orientation]);
    467 		else
    468 			fprintf(fd, "%u (0x%x)\n",
    469 			    td->td_orientation, td->td_orientation);
    470 	}
    471 	if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
    472 		fprintf(fd, "  Samples/Pixel: %u\n", td->td_samplesperpixel);
    473 	if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP)) {
    474 		fprintf(fd, "  Rows/Strip: ");
    475 		if (td->td_rowsperstrip == (uint32) -1)
    476 			fprintf(fd, "(infinite)\n");
    477 		else
    478 			fprintf(fd, "%lu\n", (unsigned long) td->td_rowsperstrip);
    479 	}
    480 	if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE))
    481 		fprintf(fd, "  Min Sample Value: %u\n", td->td_minsamplevalue);
    482 	if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE))
    483 		fprintf(fd, "  Max Sample Value: %u\n", td->td_maxsamplevalue);
    484 	if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE)) {
    485 		int i;
    486 		int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
    487 		fprintf(fd, "  SMin Sample Value:");
    488 		for (i = 0; i < count; ++i)
    489 			fprintf(fd, " %g", td->td_sminsamplevalue[i]);
    490 		fprintf(fd, "\n");
    491 	}
    492 	if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE)) {
    493 		int i;
    494 		int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
    495 		fprintf(fd, "  SMax Sample Value:");
    496 		for (i = 0; i < count; ++i)
    497 			fprintf(fd, " %g", td->td_smaxsamplevalue[i]);
    498 		fprintf(fd, "\n");
    499 	}
    500 	if (TIFFFieldSet(tif,FIELD_PLANARCONFIG)) {
    501 		fprintf(fd, "  Planar Configuration: ");
    502 		switch (td->td_planarconfig) {
    503 		case PLANARCONFIG_CONTIG:
    504 			fprintf(fd, "single image plane\n");
    505 			break;
    506 		case PLANARCONFIG_SEPARATE:
    507 			fprintf(fd, "separate image planes\n");
    508 			break;
    509 		default:
    510 			fprintf(fd, "%u (0x%x)\n",
    511 			    td->td_planarconfig, td->td_planarconfig);
    512 			break;
    513 		}
    514 	}
    515 	if (TIFFFieldSet(tif,FIELD_PAGENUMBER))
    516 		fprintf(fd, "  Page Number: %u-%u\n",
    517 		    td->td_pagenumber[0], td->td_pagenumber[1]);
    518 	if (TIFFFieldSet(tif,FIELD_COLORMAP)) {
    519 		fprintf(fd, "  Color Map: ");
    520 		if (flags & TIFFPRINT_COLORMAP) {
    521 			fprintf(fd, "\n");
    522 			n = 1L<<td->td_bitspersample;
    523 			for (l = 0; l < n; l++)
    524 				fprintf(fd, "   %5ld: %5u %5u %5u\n",
    525 				    l,
    526 				    td->td_colormap[0][l],
    527 				    td->td_colormap[1][l],
    528 				    td->td_colormap[2][l]);
    529 		} else
    530 			fprintf(fd, "(present)\n");
    531 	}
    532 	if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE)) {
    533 		int i;
    534 		fprintf(fd, "  Reference Black/White:\n");
    535 		for (i = 0; i < 3; i++)
    536 		fprintf(fd, "    %2d: %5g %5g\n", i,
    537 			td->td_refblackwhite[2*i+0],
    538 			td->td_refblackwhite[2*i+1]);
    539 	}
    540 	if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION)) {
    541 		fprintf(fd, "  Transfer Function: ");
    542 		if (flags & TIFFPRINT_CURVES) {
    543 			fprintf(fd, "\n");
    544 			n = 1L<<td->td_bitspersample;
    545 			for (l = 0; l < n; l++) {
    546 				uint16 i;
    547 				fprintf(fd, "    %2ld: %5u",
    548 				    l, td->td_transferfunction[0][l]);
    549 				for (i = 1; i < td->td_samplesperpixel; i++)
    550 					fprintf(fd, " %5u",
    551 					    td->td_transferfunction[i][l]);
    552 				fputc('\n', fd);
    553 			}
    554 		} else
    555 			fprintf(fd, "(present)\n");
    556 	}
    557 	if (TIFFFieldSet(tif, FIELD_SUBIFD) && (td->td_subifd)) {
    558 		uint16 i;
    559 		fprintf(fd, "  SubIFD Offsets:");
    560 		for (i = 0; i < td->td_nsubifd; i++)
    561 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
    562 			fprintf(fd, " %5I64u",
    563 				(unsigned __int64) td->td_subifd[i]);
    564 #else
    565 			fprintf(fd, " %5llu",
    566 				(unsigned long long) td->td_subifd[i]);
    567 #endif
    568 		fputc('\n', fd);
    569 	}
    570 
    571 	/*
    572 	** Custom tag support.
    573 	*/
    574 	{
    575 		int  i;
    576 		short count;
    577 
    578 		count = (short) TIFFGetTagListCount(tif);
    579 		for(i = 0; i < count; i++) {
    580 			uint32 tag = TIFFGetTagListEntry(tif, i);
    581 			const TIFFField *fip;
    582 			uint32 value_count;
    583 			int mem_alloc = 0;
    584 			void *raw_data;
    585 
    586 			fip = TIFFFieldWithTag(tif, tag);
    587 			if(fip == NULL)
    588 				continue;
    589 
    590 			if(fip->field_passcount) {
    591 				if (fip->field_readcount == TIFF_VARIABLE2 ) {
    592 					if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1)
    593 						continue;
    594 				} else if (fip->field_readcount == TIFF_VARIABLE ) {
    595 					uint16 small_value_count;
    596 					if(TIFFGetField(tif, tag, &small_value_count, &raw_data) != 1)
    597 						continue;
    598 					value_count = small_value_count;
    599 				} else {
    600 					assert (fip->field_readcount == TIFF_VARIABLE
    601 						|| fip->field_readcount == TIFF_VARIABLE2);
    602 					continue;
    603 				}
    604 			} else {
    605 				if (fip->field_readcount == TIFF_VARIABLE
    606 				    || fip->field_readcount == TIFF_VARIABLE2)
    607 					value_count = 1;
    608 				else if (fip->field_readcount == TIFF_SPP)
    609 					value_count = td->td_samplesperpixel;
    610 				else
    611 					value_count = fip->field_readcount;
    612 				if (fip->field_tag == TIFFTAG_DOTRANGE
    613 				    && strcmp(fip->field_name,"DotRange") == 0) {
    614 					/* TODO: This is an evil exception and should not have been
    615 					   handled this way ... likely best if we move it into
    616 					   the directory structure with an explicit field in
    617 					   libtiff 4.1 and assign it a FIELD_ value */
    618 					static uint16 dotrange[2];
    619 					raw_data = dotrange;
    620 					TIFFGetField(tif, tag, dotrange+0, dotrange+1);
    621 				} else if (fip->field_type == TIFF_ASCII
    622 					   || fip->field_readcount == TIFF_VARIABLE
    623 					   || fip->field_readcount == TIFF_VARIABLE2
    624 					   || fip->field_readcount == TIFF_SPP
    625 					   || value_count > 1) {
    626 					if(TIFFGetField(tif, tag, &raw_data) != 1)
    627 						continue;
    628 				} else {
    629 					raw_data = _TIFFmalloc(
    630 					    _TIFFDataSize(fip->field_type)
    631 					    * value_count);
    632 					mem_alloc = 1;
    633 					if(TIFFGetField(tif, tag, raw_data) != 1) {
    634 						_TIFFfree(raw_data);
    635 						continue;
    636 					}
    637 				}
    638 			}
    639 
    640 			/*
    641 			 * Catch the tags which needs to be specially handled
    642 			 * and pretty print them. If tag not handled in
    643 			 * _TIFFPrettyPrintField() fall down and print it as
    644 			 * any other tag.
    645 			 */
    646 			if (!_TIFFPrettyPrintField(tif, fip, fd, tag, value_count, raw_data))
    647 				_TIFFPrintField(fd, fip, value_count, raw_data);
    648 
    649 			if(mem_alloc)
    650 				_TIFFfree(raw_data);
    651 		}
    652 	}
    653 
    654 	if (tif->tif_tagmethods.printdir)
    655 		(*tif->tif_tagmethods.printdir)(tif, fd, flags);
    656 
    657         _TIFFFillStriles( tif );
    658 
    659 	if ((flags & TIFFPRINT_STRIPS) &&
    660 	    TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) {
    661 		uint32 s;
    662 
    663 		fprintf(fd, "  %lu %s:\n",
    664 		    (unsigned long) td->td_nstrips,
    665 		    isTiled(tif) ? "Tiles" : "Strips");
    666 		for (s = 0; s < td->td_nstrips; s++)
    667 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
    668 			fprintf(fd, "    %3lu: [%8I64u, %8I64u]\n",
    669 			    (unsigned long) s,
    670 			    (unsigned __int64) td->td_stripoffset[s],
    671 			    (unsigned __int64) td->td_stripbytecount[s]);
    672 #else
    673 			fprintf(fd, "    %3lu: [%8llu, %8llu]\n",
    674 			    (unsigned long) s,
    675 			    (unsigned long long) td->td_stripoffset[s],
    676 			    (unsigned long long) td->td_stripbytecount[s]);
    677 #endif
    678 	}
    679 }
    680 
    681 void
    682 _TIFFprintAscii(FILE* fd, const char* cp)
    683 {
    684 	_TIFFprintAsciiBounded( fd, cp, strlen(cp));
    685 }
    686 
    687 static void
    688 _TIFFprintAsciiBounded(FILE* fd, const char* cp, size_t max_chars)
    689 {
    690 	for (; max_chars > 0 && *cp != '\0'; cp++, max_chars--) {
    691 		const char* tp;
    692 
    693 		if (isprint((int)*cp)) {
    694 			fputc(*cp, fd);
    695 			continue;
    696 		}
    697 		for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++)
    698 			if (*tp++ == *cp)
    699 				break;
    700 		if (*tp)
    701 			fprintf(fd, "\\%c", *tp);
    702 		else
    703 			fprintf(fd, "\\%03o", *cp & 0xff);
    704 	}
    705 }
    706 
    707 void
    708 _TIFFprintAsciiTag(FILE* fd, const char* name, const char* value)
    709 {
    710 	fprintf(fd, "  %s: \"", name);
    711 	_TIFFprintAscii(fd, value);
    712 	fprintf(fd, "\"\n");
    713 }
    714 
    715 /* vim: set ts=8 sts=8 sw=8 noet: */
    716 /*
    717  * Local Variables:
    718  * mode: c
    719  * c-basic-offset: 8
    720  * fill-column: 78
    721  * End:
    722  */
    723