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