1 /* $Id: tif_print.c,v 1.62 2015-08-19 02:31:04 bfriesen 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 *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 *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
_TIFFPrintField(FILE * fd,const TIFFField * fip,uint32 value_count,void * raw_data)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
_TIFFPrettyPrintField(TIFF * tif,const TIFFField * fip,FILE * fd,uint32 tag,uint32 value_count,void * raw_data)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
TIFFPrintDirectory(TIFF * tif,FILE * fd,long flags)236 TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
237 {
238 	TIFFDirectory *td = &tif->tif_dir;
239 	char *sep;
240 	uint16 i;
241 	long l, n;
242 
243 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
244 	fprintf(fd, "TIFF Directory at offset 0x%I64x (%I64u)\n",
245 		(unsigned __int64) tif->tif_diroff,
246 		(unsigned __int64) tif->tif_diroff);
247 #else
248 	fprintf(fd, "TIFF Directory at offset 0x%llx (%llu)\n",
249 		(unsigned long long) tif->tif_diroff,
250 		(unsigned long long) tif->tif_diroff);
251 #endif
252 	if (TIFFFieldSet(tif,FIELD_SUBFILETYPE)) {
253 		fprintf(fd, "  Subfile Type:");
254 		sep = " ";
255 		if (td->td_subfiletype & FILETYPE_REDUCEDIMAGE) {
256 			fprintf(fd, "%sreduced-resolution image", sep);
257 			sep = "/";
258 		}
259 		if (td->td_subfiletype & FILETYPE_PAGE) {
260 			fprintf(fd, "%smulti-page document", sep);
261 			sep = "/";
262 		}
263 		if (td->td_subfiletype & FILETYPE_MASK)
264 			fprintf(fd, "%stransparency mask", sep);
265 		fprintf(fd, " (%lu = 0x%lx)\n",
266 		    (long) td->td_subfiletype, (long) td->td_subfiletype);
267 	}
268 	if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) {
269 		fprintf(fd, "  Image Width: %lu Image Length: %lu",
270 		    (unsigned long) td->td_imagewidth, (unsigned long) td->td_imagelength);
271 		if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH))
272 			fprintf(fd, " Image Depth: %lu",
273 			    (unsigned long) td->td_imagedepth);
274 		fprintf(fd, "\n");
275 	}
276 	if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS)) {
277 		fprintf(fd, "  Tile Width: %lu Tile Length: %lu",
278 		    (unsigned long) td->td_tilewidth, (unsigned long) td->td_tilelength);
279 		if (TIFFFieldSet(tif,FIELD_TILEDEPTH))
280 			fprintf(fd, " Tile Depth: %lu",
281 			    (unsigned long) td->td_tiledepth);
282 		fprintf(fd, "\n");
283 	}
284 	if (TIFFFieldSet(tif,FIELD_RESOLUTION)) {
285 		fprintf(fd, "  Resolution: %g, %g",
286 		    td->td_xresolution, td->td_yresolution);
287 		if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT)) {
288 			switch (td->td_resolutionunit) {
289 			case RESUNIT_NONE:
290 				fprintf(fd, " (unitless)");
291 				break;
292 			case RESUNIT_INCH:
293 				fprintf(fd, " pixels/inch");
294 				break;
295 			case RESUNIT_CENTIMETER:
296 				fprintf(fd, " pixels/cm");
297 				break;
298 			default:
299 				fprintf(fd, " (unit %u = 0x%x)",
300 				    td->td_resolutionunit,
301 				    td->td_resolutionunit);
302 				break;
303 			}
304 		}
305 		fprintf(fd, "\n");
306 	}
307 	if (TIFFFieldSet(tif,FIELD_POSITION))
308 		fprintf(fd, "  Position: %g, %g\n",
309 		    td->td_xposition, td->td_yposition);
310 	if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
311 		fprintf(fd, "  Bits/Sample: %u\n", td->td_bitspersample);
312 	if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT)) {
313 		fprintf(fd, "  Sample Format: ");
314 		switch (td->td_sampleformat) {
315 		case SAMPLEFORMAT_VOID:
316 			fprintf(fd, "void\n");
317 			break;
318 		case SAMPLEFORMAT_INT:
319 			fprintf(fd, "signed integer\n");
320 			break;
321 		case SAMPLEFORMAT_UINT:
322 			fprintf(fd, "unsigned integer\n");
323 			break;
324 		case SAMPLEFORMAT_IEEEFP:
325 			fprintf(fd, "IEEE floating point\n");
326 			break;
327 		case SAMPLEFORMAT_COMPLEXINT:
328 			fprintf(fd, "complex signed integer\n");
329 			break;
330 		case SAMPLEFORMAT_COMPLEXIEEEFP:
331 			fprintf(fd, "complex IEEE floating point\n");
332 			break;
333 		default:
334 			fprintf(fd, "%u (0x%x)\n",
335 			    td->td_sampleformat, td->td_sampleformat);
336 			break;
337 		}
338 	}
339 	if (TIFFFieldSet(tif,FIELD_COMPRESSION)) {
340 		const TIFFCodec* c = TIFFFindCODEC(td->td_compression);
341 		fprintf(fd, "  Compression Scheme: ");
342 		if (c)
343 			fprintf(fd, "%s\n", c->name);
344 		else
345 			fprintf(fd, "%u (0x%x)\n",
346 			    td->td_compression, td->td_compression);
347 	}
348 	if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) {
349 		fprintf(fd, "  Photometric Interpretation: ");
350 		if (td->td_photometric < NPHOTONAMES)
351 			fprintf(fd, "%s\n", photoNames[td->td_photometric]);
352 		else {
353 			switch (td->td_photometric) {
354 			case PHOTOMETRIC_LOGL:
355 				fprintf(fd, "CIE Log2(L)\n");
356 				break;
357 			case PHOTOMETRIC_LOGLUV:
358 				fprintf(fd, "CIE Log2(L) (u',v')\n");
359 				break;
360 			default:
361 				fprintf(fd, "%u (0x%x)\n",
362 				    td->td_photometric, td->td_photometric);
363 				break;
364 			}
365 		}
366 	}
367 	if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES) && td->td_extrasamples) {
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 		fprintf(fd, "  Ink Names: ");
393 		i = td->td_samplesperpixel;
394 		sep = "";
395 		for (cp = td->td_inknames;
396 		     i > 0 && cp < td->td_inknames + td->td_inknameslen;
397 		     cp = strchr(cp,'\0')+1, i--) {
398 			size_t max_chars =
399 				td->td_inknameslen - (cp - td->td_inknames);
400 			fputs(sep, fd);
401 			_TIFFprintAsciiBounded(fd, cp, max_chars);
402 			sep = ", ";
403 		}
404                 fputs("\n", fd);
405 	}
406 	if (TIFFFieldSet(tif,FIELD_THRESHHOLDING)) {
407 		fprintf(fd, "  Thresholding: ");
408 		switch (td->td_threshholding) {
409 		case THRESHHOLD_BILEVEL:
410 			fprintf(fd, "bilevel art scan\n");
411 			break;
412 		case THRESHHOLD_HALFTONE:
413 			fprintf(fd, "halftone or dithered scan\n");
414 			break;
415 		case THRESHHOLD_ERRORDIFFUSE:
416 			fprintf(fd, "error diffused\n");
417 			break;
418 		default:
419 			fprintf(fd, "%u (0x%x)\n",
420 			    td->td_threshholding, td->td_threshholding);
421 			break;
422 		}
423 	}
424 	if (TIFFFieldSet(tif,FIELD_FILLORDER)) {
425 		fprintf(fd, "  FillOrder: ");
426 		switch (td->td_fillorder) {
427 		case FILLORDER_MSB2LSB:
428 			fprintf(fd, "msb-to-lsb\n");
429 			break;
430 		case FILLORDER_LSB2MSB:
431 			fprintf(fd, "lsb-to-msb\n");
432 			break;
433 		default:
434 			fprintf(fd, "%u (0x%x)\n",
435 			    td->td_fillorder, td->td_fillorder);
436 			break;
437 		}
438 	}
439 	if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING))
440         {
441 		fprintf(fd, "  YCbCr Subsampling: %u, %u\n",
442 			td->td_ycbcrsubsampling[0], td->td_ycbcrsubsampling[1] );
443 	}
444 	if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING)) {
445 		fprintf(fd, "  YCbCr Positioning: ");
446 		switch (td->td_ycbcrpositioning) {
447 		case YCBCRPOSITION_CENTERED:
448 			fprintf(fd, "centered\n");
449 			break;
450 		case YCBCRPOSITION_COSITED:
451 			fprintf(fd, "cosited\n");
452 			break;
453 		default:
454 			fprintf(fd, "%u (0x%x)\n",
455 			    td->td_ycbcrpositioning, td->td_ycbcrpositioning);
456 			break;
457 		}
458 	}
459 	if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS))
460 		fprintf(fd, "  Halftone Hints: light %u dark %u\n",
461 		    td->td_halftonehints[0], td->td_halftonehints[1]);
462 	if (TIFFFieldSet(tif,FIELD_ORIENTATION)) {
463 		fprintf(fd, "  Orientation: ");
464 		if (td->td_orientation < NORIENTNAMES)
465 			fprintf(fd, "%s\n", orientNames[td->td_orientation]);
466 		else
467 			fprintf(fd, "%u (0x%x)\n",
468 			    td->td_orientation, td->td_orientation);
469 	}
470 	if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
471 		fprintf(fd, "  Samples/Pixel: %u\n", td->td_samplesperpixel);
472 	if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP)) {
473 		fprintf(fd, "  Rows/Strip: ");
474 		if (td->td_rowsperstrip == (uint32) -1)
475 			fprintf(fd, "(infinite)\n");
476 		else
477 			fprintf(fd, "%lu\n", (unsigned long) td->td_rowsperstrip);
478 	}
479 	if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE))
480 		fprintf(fd, "  Min Sample Value: %u\n", td->td_minsamplevalue);
481 	if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE))
482 		fprintf(fd, "  Max Sample Value: %u\n", td->td_maxsamplevalue);
483 	if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE)) {
484 		int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
485 		fprintf(fd, "  SMin Sample Value:");
486 		for (i = 0; i < count; ++i)
487 			fprintf(fd, " %g", td->td_sminsamplevalue[i]);
488 		fprintf(fd, "\n");
489 	}
490 	if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE)) {
491 		int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
492 		fprintf(fd, "  SMax Sample Value:");
493 		for (i = 0; i < count; ++i)
494 			fprintf(fd, " %g", td->td_smaxsamplevalue[i]);
495 		fprintf(fd, "\n");
496 	}
497 	if (TIFFFieldSet(tif,FIELD_PLANARCONFIG)) {
498 		fprintf(fd, "  Planar Configuration: ");
499 		switch (td->td_planarconfig) {
500 		case PLANARCONFIG_CONTIG:
501 			fprintf(fd, "single image plane\n");
502 			break;
503 		case PLANARCONFIG_SEPARATE:
504 			fprintf(fd, "separate image planes\n");
505 			break;
506 		default:
507 			fprintf(fd, "%u (0x%x)\n",
508 			    td->td_planarconfig, td->td_planarconfig);
509 			break;
510 		}
511 	}
512 	if (TIFFFieldSet(tif,FIELD_PAGENUMBER))
513 		fprintf(fd, "  Page Number: %u-%u\n",
514 		    td->td_pagenumber[0], td->td_pagenumber[1]);
515 	if (TIFFFieldSet(tif,FIELD_COLORMAP)) {
516 		fprintf(fd, "  Color Map: ");
517 		if (flags & TIFFPRINT_COLORMAP) {
518 			fprintf(fd, "\n");
519 			n = 1L<<td->td_bitspersample;
520 			for (l = 0; l < n; l++)
521 				fprintf(fd, "   %5lu: %5u %5u %5u\n",
522 				    l,
523 				    td->td_colormap[0][l],
524 				    td->td_colormap[1][l],
525 				    td->td_colormap[2][l]);
526 		} else
527 			fprintf(fd, "(present)\n");
528 	}
529 	if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE)) {
530 		fprintf(fd, "  Reference Black/White:\n");
531 		for (i = 0; i < 3; i++)
532 		fprintf(fd, "    %2d: %5g %5g\n", i,
533 			td->td_refblackwhite[2*i+0],
534 			td->td_refblackwhite[2*i+1]);
535 	}
536 	if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION)) {
537 		fprintf(fd, "  Transfer Function: ");
538 		if (flags & TIFFPRINT_CURVES) {
539 			fprintf(fd, "\n");
540 			n = 1L<<td->td_bitspersample;
541 			for (l = 0; l < n; l++) {
542 				fprintf(fd, "    %2lu: %5u",
543 				    l, td->td_transferfunction[0][l]);
544 				for (i = 1; i < td->td_samplesperpixel; i++)
545 					fprintf(fd, " %5u",
546 					    td->td_transferfunction[i][l]);
547 				fputc('\n', fd);
548 			}
549 		} else
550 			fprintf(fd, "(present)\n");
551 	}
552 	if (TIFFFieldSet(tif, FIELD_SUBIFD) && (td->td_subifd)) {
553 		fprintf(fd, "  SubIFD Offsets:");
554 		for (i = 0; i < td->td_nsubifd; i++)
555 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
556 			fprintf(fd, " %5I64u",
557 				(unsigned __int64) td->td_subifd[i]);
558 #else
559 			fprintf(fd, " %5llu",
560 				(unsigned long long) td->td_subifd[i]);
561 #endif
562 		fputc('\n', fd);
563 	}
564 
565 	/*
566 	** Custom tag support.
567 	*/
568 	{
569 		int  i;
570 		short count;
571 
572 		count = (short) TIFFGetTagListCount(tif);
573 		for(i = 0; i < count; i++) {
574 			uint32 tag = TIFFGetTagListEntry(tif, i);
575 			const TIFFField *fip;
576 			uint32 value_count;
577 			int mem_alloc = 0;
578 			void *raw_data;
579 
580 			fip = TIFFFieldWithTag(tif, tag);
581 			if(fip == NULL)
582 				continue;
583 
584 			if(fip->field_passcount) {
585 				if (fip->field_readcount == TIFF_VARIABLE2 ) {
586 					if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1)
587 						continue;
588 				} else if (fip->field_readcount == TIFF_VARIABLE ) {
589 					uint16 small_value_count;
590 					if(TIFFGetField(tif, tag, &small_value_count, &raw_data) != 1)
591 						continue;
592 					value_count = small_value_count;
593 				} else {
594 					assert (fip->field_readcount == TIFF_VARIABLE
595 						|| fip->field_readcount == TIFF_VARIABLE2);
596 					continue;
597 				}
598 			} else {
599 				if (fip->field_readcount == TIFF_VARIABLE
600 				    || fip->field_readcount == TIFF_VARIABLE2)
601 					value_count = 1;
602 				else if (fip->field_readcount == TIFF_SPP)
603 					value_count = td->td_samplesperpixel;
604 				else
605 					value_count = fip->field_readcount;
606 				if (fip->field_tag == TIFFTAG_DOTRANGE
607 				    && strcmp(fip->field_name,"DotRange") == 0) {
608 					/* TODO: This is an evil exception and should not have been
609 					   handled this way ... likely best if we move it into
610 					   the directory structure with an explicit field in
611 					   libtiff 4.1 and assign it a FIELD_ value */
612 					static uint16 dotrange[2];
613 					raw_data = dotrange;
614 					TIFFGetField(tif, tag, dotrange+0, dotrange+1);
615 				} else if (fip->field_type == TIFF_ASCII
616 					   || fip->field_readcount == TIFF_VARIABLE
617 					   || fip->field_readcount == TIFF_VARIABLE2
618 					   || fip->field_readcount == TIFF_SPP
619 					   || value_count > 1) {
620 					if(TIFFGetField(tif, tag, &raw_data) != 1)
621 						continue;
622 				} else {
623 					raw_data = _TIFFmalloc(
624 					    _TIFFDataSize(fip->field_type)
625 					    * value_count);
626 					mem_alloc = 1;
627 					if(TIFFGetField(tif, tag, raw_data) != 1) {
628 						_TIFFfree(raw_data);
629 						continue;
630 					}
631 				}
632 			}
633 
634 			/*
635 			 * Catch the tags which needs to be specially handled
636 			 * and pretty print them. If tag not handled in
637 			 * _TIFFPrettyPrintField() fall down and print it as
638 			 * any other tag.
639 			 */
640 			if (!_TIFFPrettyPrintField(tif, fip, fd, tag, value_count, raw_data))
641 				_TIFFPrintField(fd, fip, value_count, raw_data);
642 
643 			if(mem_alloc)
644 				_TIFFfree(raw_data);
645 		}
646 	}
647 
648 	if (tif->tif_tagmethods.printdir)
649 		(*tif->tif_tagmethods.printdir)(tif, fd, flags);
650 
651         _TIFFFillStriles( tif );
652 
653 	if ((flags & TIFFPRINT_STRIPS) &&
654 	    TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) {
655 		uint32 s;
656 
657 		fprintf(fd, "  %lu %s:\n",
658 		    (long) td->td_nstrips,
659 		    isTiled(tif) ? "Tiles" : "Strips");
660 		for (s = 0; s < td->td_nstrips; s++)
661 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
662 			fprintf(fd, "    %3lu: [%8I64u, %8I64u]\n",
663 			    (unsigned long) s,
664 			    (unsigned __int64) td->td_stripoffset[s],
665 			    (unsigned __int64) td->td_stripbytecount[s]);
666 #else
667 			fprintf(fd, "    %3lu: [%8llu, %8llu]\n",
668 			    (unsigned long) s,
669 			    (unsigned long long) td->td_stripoffset[s],
670 			    (unsigned long long) td->td_stripbytecount[s]);
671 #endif
672 	}
673 }
674 
675 void
_TIFFprintAscii(FILE * fd,const char * cp)676 _TIFFprintAscii(FILE* fd, const char* cp)
677 {
678 	_TIFFprintAsciiBounded( fd, cp, strlen(cp));
679 }
680 
681 static void
_TIFFprintAsciiBounded(FILE * fd,const char * cp,size_t max_chars)682 _TIFFprintAsciiBounded(FILE* fd, const char* cp, size_t max_chars)
683 {
684 	for (; max_chars > 0 && *cp != '\0'; cp++, max_chars--) {
685 		const char* tp;
686 
687 		if (isprint((int)*cp)) {
688 			fputc(*cp, fd);
689 			continue;
690 		}
691 		for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++)
692 			if (*tp++ == *cp)
693 				break;
694 		if (*tp)
695 			fprintf(fd, "\\%c", *tp);
696 		else
697 			fprintf(fd, "\\%03o", *cp & 0xff);
698 	}
699 }
700 
701 void
_TIFFprintAsciiTag(FILE * fd,const char * name,const char * value)702 _TIFFprintAsciiTag(FILE* fd, const char* name, const char* value)
703 {
704 	fprintf(fd, "  %s: \"", name);
705 	_TIFFprintAscii(fd, value);
706 	fprintf(fd, "\"\n");
707 }
708 
709 /* vim: set ts=8 sts=8 sw=8 noet: */
710 /*
711  * Local Variables:
712  * mode: c
713  * c-basic-offset: 8
714  * fill-column: 78
715  * End:
716  */
717