1 /* $Header$ */
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 const char *photoNames[] = {
38     "min-is-white",				/* PHOTOMETRIC_MINISWHITE */
39     "min-is-black",				/* PHOTOMETRIC_MINISBLACK */
40     "RGB color",				/* PHOTOMETRIC_RGB */
41     "palette color (RGB from colormap)",	/* PHOTOMETRIC_PALETTE */
42     "transparency mask",			/* PHOTOMETRIC_MASK */
43     "separated",				/* PHOTOMETRIC_SEPARATED */
44     "YCbCr",					/* PHOTOMETRIC_YCBCR */
45     "7 (0x7)",
46     "CIE L*a*b*",				/* PHOTOMETRIC_CIELAB */
47 };
48 #define	NPHOTONAMES	(sizeof (photoNames) / sizeof (photoNames[0]))
49 
50 static const char *orientNames[] = {
51     "0 (0x0)",
52     "row 0 top, col 0 lhs",			/* ORIENTATION_TOPLEFT */
53     "row 0 top, col 0 rhs",			/* ORIENTATION_TOPRIGHT */
54     "row 0 bottom, col 0 rhs",			/* ORIENTATION_BOTRIGHT */
55     "row 0 bottom, col 0 lhs",			/* ORIENTATION_BOTLEFT */
56     "row 0 lhs, col 0 top",			/* ORIENTATION_LEFTTOP */
57     "row 0 rhs, col 0 top",			/* ORIENTATION_RIGHTTOP */
58     "row 0 rhs, col 0 bottom",			/* ORIENTATION_RIGHTBOT */
59     "row 0 lhs, col 0 bottom",			/* ORIENTATION_LEFTBOT */
60 };
61 #define	NORIENTNAMES	(sizeof (orientNames) / sizeof (orientNames[0]))
62 
63 /*
64  * Print the contents of the current directory
65  * to the specified stdio file stream.
66  */
67 void
TIFFPrintDirectory(TIFF * tif,FILE * fd,long flags)68 TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
69 {
70 	register TIFFDirectory *td;
71 	char *sep;
72 	uint16 i;
73 	long l, n;
74 
75 	fprintf(fd, "TIFF Directory at offset 0x%lx\n", tif->tif_diroff);
76 	td = &tif->tif_dir;
77 	if (TIFFFieldSet(tif,FIELD_SUBFILETYPE)) {
78 		fprintf(fd, "  Subfile Type:");
79 		sep = " ";
80 		if (td->td_subfiletype & FILETYPE_REDUCEDIMAGE) {
81 			fprintf(fd, "%sreduced-resolution image", sep);
82 			sep = "/";
83 		}
84 		if (td->td_subfiletype & FILETYPE_PAGE) {
85 			fprintf(fd, "%smulti-page document", sep);
86 			sep = "/";
87 		}
88 		if (td->td_subfiletype & FILETYPE_MASK)
89 			fprintf(fd, "%stransparency mask", sep);
90 		fprintf(fd, " (%lu = 0x%lx)\n",
91 		    (long) td->td_subfiletype, (long) td->td_subfiletype);
92 	}
93 	if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) {
94 		fprintf(fd, "  Image Width: %lu Image Length: %lu",
95 		    (u_long) td->td_imagewidth, (u_long) td->td_imagelength);
96 		if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH))
97 			fprintf(fd, " Image Depth: %lu",
98 			    (u_long) td->td_imagedepth);
99 		fprintf(fd, "\n");
100 	}
101 
102  	/* Begin Pixar */
103  	if (TIFFFieldSet(tif,FIELD_IMAGEFULLWIDTH) ||
104  	    TIFFFieldSet(tif,FIELD_IMAGEFULLLENGTH)) {
105 	  fprintf(fd, "  Pixar Full Image Width: %lu Full Image Length: %lu\n",
106 		  (u_long) td->td_imagefullwidth,
107 		  (u_long) td->td_imagefulllength);
108  	}
109  	if (TIFFFieldSet(tif,FIELD_TEXTUREFORMAT))
110 	  _TIFFprintAsciiTag(fd, "Texture Format", td->td_textureformat);
111  	if (TIFFFieldSet(tif,FIELD_WRAPMODES))
112 	  _TIFFprintAsciiTag(fd, "Texture Wrap Modes", td->td_wrapmodes);
113  	if (TIFFFieldSet(tif,FIELD_FOVCOT))
114 	  fprintf(fd, "  Field of View Cotangent: %g\n", td->td_fovcot);
115 	if (TIFFFieldSet(tif,FIELD_MATRIX_WORLDTOSCREEN)) {
116 	  typedef float	Matrix[4][4];
117 	  Matrix*		m = (Matrix*)td->td_matrixWorldToScreen;
118 
119 	  fprintf(fd, "  Matrix NP:\n\t%g %g %g %g\n\t%g %g %g %g\n\t%g %g %g %g\n\t%g %g %g %g\n",
120 		  (*m)[0][0], (*m)[0][1], (*m)[0][2], (*m)[0][3],
121 		  (*m)[1][0], (*m)[1][1], (*m)[1][2], (*m)[1][3],
122 		  (*m)[2][0], (*m)[2][1], (*m)[2][2], (*m)[2][3],
123 		  (*m)[3][0], (*m)[3][1], (*m)[3][2], (*m)[3][3]);
124  	}
125  	if (TIFFFieldSet(tif,FIELD_MATRIX_WORLDTOCAMERA)) {
126 	  typedef float	Matrix[4][4];
127 	  Matrix*		m = (Matrix*)td->td_matrixWorldToCamera;
128 
129 	  fprintf(fd, "  Matrix Nl:\n\t%g %g %g %g\n\t%g %g %g %g\n\t%g %g %g %g\n\t%g %g %g %g\n",
130 		  (*m)[0][0], (*m)[0][1], (*m)[0][2], (*m)[0][3],
131 		  (*m)[1][0], (*m)[1][1], (*m)[1][2], (*m)[1][3],
132 		  (*m)[2][0], (*m)[2][1], (*m)[2][2], (*m)[2][3],
133 		  (*m)[3][0], (*m)[3][1], (*m)[3][2], (*m)[3][3]);
134  	}
135  	/* End Pixar */
136 
137 	if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS)) {
138 		fprintf(fd, "  Tile Width: %lu Tile Length: %lu",
139 		    (u_long) td->td_tilewidth, (u_long) td->td_tilelength);
140 		if (TIFFFieldSet(tif,FIELD_TILEDEPTH))
141 			fprintf(fd, " Tile Depth: %lu",
142 			    (u_long) td->td_tiledepth);
143 		fprintf(fd, "\n");
144 	}
145 	if (TIFFFieldSet(tif,FIELD_RESOLUTION)) {
146 		fprintf(fd, "  Resolution: %g, %g",
147 		    td->td_xresolution, td->td_yresolution);
148 		if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT)) {
149 			switch (td->td_resolutionunit) {
150 			case RESUNIT_NONE:
151 				fprintf(fd, " (unitless)");
152 				break;
153 			case RESUNIT_INCH:
154 				fprintf(fd, " pixels/inch");
155 				break;
156 			case RESUNIT_CENTIMETER:
157 				fprintf(fd, " pixels/cm");
158 				break;
159 			default:
160 				fprintf(fd, " (unit %u = 0x%x)",
161 				    td->td_resolutionunit,
162 				    td->td_resolutionunit);
163 				break;
164 			}
165 		}
166 		fprintf(fd, "\n");
167 	}
168 	if (TIFFFieldSet(tif,FIELD_POSITION))
169 		fprintf(fd, "  Position: %g, %g\n",
170 		    td->td_xposition, td->td_yposition);
171 	if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
172 		fprintf(fd, "  Bits/Sample: %u\n", td->td_bitspersample);
173 	if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT)) {
174 		fprintf(fd, "  Sample Format: ");
175 		switch (td->td_sampleformat) {
176 		case SAMPLEFORMAT_VOID:
177 			fprintf(fd, "void\n");
178 			break;
179 		case SAMPLEFORMAT_INT:
180 			fprintf(fd, "signed integer\n");
181 			break;
182 		case SAMPLEFORMAT_UINT:
183 			fprintf(fd, "unsigned integer\n");
184 			break;
185 		case SAMPLEFORMAT_IEEEFP:
186 			fprintf(fd, "IEEE floating point\n");
187 			break;
188 		case SAMPLEFORMAT_COMPLEXINT:
189 			fprintf(fd, "complex signed integer\n");
190 			break;
191 		case SAMPLEFORMAT_COMPLEXIEEEFP:
192 			fprintf(fd, "complex IEEE floating point\n");
193 			break;
194 		default:
195 			fprintf(fd, "%u (0x%x)\n",
196 			    td->td_sampleformat, td->td_sampleformat);
197 			break;
198 		}
199 	}
200 	if (TIFFFieldSet(tif,FIELD_COMPRESSION)) {
201 		const TIFFCodec* c = TIFFFindCODEC(td->td_compression);
202 		fprintf(fd, "  Compression Scheme: ");
203 		if (c)
204 			fprintf(fd, "%s\n", c->name);
205 		else
206 			fprintf(fd, "%u (0x%x)\n",
207 			    td->td_compression, td->td_compression);
208 	}
209 	if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) {
210 		fprintf(fd, "  Photometric Interpretation: ");
211 		if (td->td_photometric < NPHOTONAMES)
212 			fprintf(fd, "%s\n", photoNames[td->td_photometric]);
213 		else {
214 			switch (td->td_photometric) {
215 			case PHOTOMETRIC_LOGL:
216 				fprintf(fd, "CIE Log2(L)\n");
217 				break;
218 			case PHOTOMETRIC_LOGLUV:
219 				fprintf(fd, "CIE Log2(L) (u',v')\n");
220 				break;
221 			default:
222 				fprintf(fd, "%u (0x%x)\n",
223 				    td->td_photometric, td->td_photometric);
224 				break;
225 			}
226 		}
227 	}
228 	if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES) && td->td_extrasamples) {
229 		fprintf(fd, "  Extra Samples: %u<", td->td_extrasamples);
230 		sep = "";
231 		for (i = 0; i < td->td_extrasamples; i++) {
232 			switch (td->td_sampleinfo[i]) {
233 			case EXTRASAMPLE_UNSPECIFIED:
234 				fprintf(fd, "%sunspecified", sep);
235 				break;
236 			case EXTRASAMPLE_ASSOCALPHA:
237 				fprintf(fd, "%sassoc-alpha", sep);
238 				break;
239 			case EXTRASAMPLE_UNASSALPHA:
240 				fprintf(fd, "%sunassoc-alpha", sep);
241 				break;
242 			default:
243 				fprintf(fd, "%s%u (0x%x)", sep,
244 				    td->td_sampleinfo[i], td->td_sampleinfo[i]);
245 				break;
246 			}
247 			sep = ", ";
248 		}
249 		fprintf(fd, ">\n");
250 	}
251 	if (TIFFFieldSet(tif,FIELD_STONITS)) {
252 		fprintf(fd, "  Sample to Nits conversion factor: %.4e\n",
253 				td->td_stonits);
254 	}
255 #ifdef CMYK_SUPPORT
256 	if (TIFFFieldSet(tif,FIELD_INKSET)) {
257 		fprintf(fd, "  Ink Set: ");
258 		switch (td->td_inkset) {
259 		case INKSET_CMYK:
260 			fprintf(fd, "CMYK\n");
261 			break;
262 		default:
263 			fprintf(fd, "%u (0x%x)\n",
264 			    td->td_inkset, td->td_inkset);
265 			break;
266 		}
267 	}
268 	if (TIFFFieldSet(tif,FIELD_INKNAMES)) {
269 		char* cp;
270 		fprintf(fd, "  Ink Names: ");
271 		i = td->td_samplesperpixel;
272 		sep = "";
273 		for (cp = td->td_inknames; i > 0; cp = strchr(cp,'\0')+1, i--) {
274 			fprintf(fd, "%s", sep);
275 			_TIFFprintAscii(fd, cp);
276 			sep = ", ";
277 		}
278 	}
279 	if (TIFFFieldSet(tif,FIELD_NUMBEROFINKS))
280 		fprintf(fd, " Number of Inks: %u\n", td->td_ninks);
281 	if (TIFFFieldSet(tif,FIELD_DOTRANGE))
282 		fprintf(fd, "  Dot Range: %u-%u\n",
283 		    td->td_dotrange[0], td->td_dotrange[1]);
284 	if (TIFFFieldSet(tif,FIELD_TARGETPRINTER))
285 		_TIFFprintAsciiTag(fd, "Target Printer", td->td_targetprinter);
286 #endif
287 	if (TIFFFieldSet(tif,FIELD_THRESHHOLDING)) {
288 		fprintf(fd, "  Thresholding: ");
289 		switch (td->td_threshholding) {
290 		case THRESHHOLD_BILEVEL:
291 			fprintf(fd, "bilevel art scan\n");
292 			break;
293 		case THRESHHOLD_HALFTONE:
294 			fprintf(fd, "halftone or dithered scan\n");
295 			break;
296 		case THRESHHOLD_ERRORDIFFUSE:
297 			fprintf(fd, "error diffused\n");
298 			break;
299 		default:
300 			fprintf(fd, "%u (0x%x)\n",
301 			    td->td_threshholding, td->td_threshholding);
302 			break;
303 		}
304 	}
305 	if (TIFFFieldSet(tif,FIELD_FILLORDER)) {
306 		fprintf(fd, "  FillOrder: ");
307 		switch (td->td_fillorder) {
308 		case FILLORDER_MSB2LSB:
309 			fprintf(fd, "msb-to-lsb\n");
310 			break;
311 		case FILLORDER_LSB2MSB:
312 			fprintf(fd, "lsb-to-msb\n");
313 			break;
314 		default:
315 			fprintf(fd, "%u (0x%x)\n",
316 			    td->td_fillorder, td->td_fillorder);
317 			break;
318 		}
319 	}
320 #ifdef YCBCR_SUPPORT
321 	if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING))
322         {
323             /*
324              * For hacky reasons (see tif_jpeg.c - JPEGFixupTestSubsampling),
325              * we need to fetch this rather than trust what is in our
326              * structures.
327              */
328             uint16 subsampling[2];
329 
330             TIFFGetField( tif, TIFFTAG_YCBCRSUBSAMPLING,
331                           subsampling + 0, subsampling + 1 );
332 		fprintf(fd, "  YCbCr Subsampling: %u, %u\n",
333                         subsampling[0], subsampling[1] );
334         }
335 	if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING)) {
336 		fprintf(fd, "  YCbCr Positioning: ");
337 		switch (td->td_ycbcrpositioning) {
338 		case YCBCRPOSITION_CENTERED:
339 			fprintf(fd, "centered\n");
340 			break;
341 		case YCBCRPOSITION_COSITED:
342 			fprintf(fd, "cosited\n");
343 			break;
344 		default:
345 			fprintf(fd, "%u (0x%x)\n",
346 			    td->td_ycbcrpositioning, td->td_ycbcrpositioning);
347 			break;
348 		}
349 	}
350 	if (TIFFFieldSet(tif,FIELD_YCBCRCOEFFICIENTS))
351 		fprintf(fd, "  YCbCr Coefficients: %g, %g, %g\n",
352 		    td->td_ycbcrcoeffs[0],
353 		    td->td_ycbcrcoeffs[1],
354 		    td->td_ycbcrcoeffs[2]);
355 #endif
356 	if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS))
357 		fprintf(fd, "  Halftone Hints: light %u dark %u\n",
358 		    td->td_halftonehints[0], td->td_halftonehints[1]);
359 	if (TIFFFieldSet(tif,FIELD_ARTIST))
360 		_TIFFprintAsciiTag(fd, "Artist", td->td_artist);
361 	if (TIFFFieldSet(tif,FIELD_DATETIME))
362 		_TIFFprintAsciiTag(fd, "Date & Time", td->td_datetime);
363 	if (TIFFFieldSet(tif,FIELD_HOSTCOMPUTER))
364 		_TIFFprintAsciiTag(fd, "Host Computer", td->td_hostcomputer);
365 	if (TIFFFieldSet(tif,FIELD_COPYRIGHT))
366 		_TIFFprintAsciiTag(fd, "Copyright", td->td_copyright);
367 	if (TIFFFieldSet(tif,FIELD_DOCUMENTNAME))
368 		_TIFFprintAsciiTag(fd, "Document Name", td->td_documentname);
369 	if (TIFFFieldSet(tif,FIELD_IMAGEDESCRIPTION))
370 		_TIFFprintAsciiTag(fd, "Image Description", td->td_imagedescription);
371 	if (TIFFFieldSet(tif,FIELD_MAKE))
372 		_TIFFprintAsciiTag(fd, "Make", td->td_make);
373 	if (TIFFFieldSet(tif,FIELD_MODEL))
374 		_TIFFprintAsciiTag(fd, "Model", td->td_model);
375 	if (TIFFFieldSet(tif,FIELD_ORIENTATION)) {
376 		fprintf(fd, "  Orientation: ");
377 		if (td->td_orientation < NORIENTNAMES)
378 			fprintf(fd, "%s\n", orientNames[td->td_orientation]);
379 		else
380 			fprintf(fd, "%u (0x%x)\n",
381 			    td->td_orientation, td->td_orientation);
382 	}
383 	if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
384 		fprintf(fd, "  Samples/Pixel: %u\n", td->td_samplesperpixel);
385 	if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP)) {
386 		fprintf(fd, "  Rows/Strip: ");
387 		if (td->td_rowsperstrip == (uint32) -1)
388 			fprintf(fd, "(infinite)\n");
389 		else
390 			fprintf(fd, "%lu\n", (u_long) td->td_rowsperstrip);
391 	}
392 	if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE))
393 		fprintf(fd, "  Min Sample Value: %u\n", td->td_minsamplevalue);
394 	if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE))
395 		fprintf(fd, "  Max Sample Value: %u\n", td->td_maxsamplevalue);
396 	if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE))
397 		fprintf(fd, "  SMin Sample Value: %g\n",
398 		    td->td_sminsamplevalue);
399 	if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE))
400 		fprintf(fd, "  SMax Sample Value: %g\n",
401 		    td->td_smaxsamplevalue);
402 	if (TIFFFieldSet(tif,FIELD_PLANARCONFIG)) {
403 		fprintf(fd, "  Planar Configuration: ");
404 		switch (td->td_planarconfig) {
405 		case PLANARCONFIG_CONTIG:
406 			fprintf(fd, "single image plane\n");
407 			break;
408 		case PLANARCONFIG_SEPARATE:
409 			fprintf(fd, "separate image planes\n");
410 			break;
411 		default:
412 			fprintf(fd, "%u (0x%x)\n",
413 			    td->td_planarconfig, td->td_planarconfig);
414 			break;
415 		}
416 	}
417 	if (TIFFFieldSet(tif,FIELD_PAGENAME))
418 		_TIFFprintAsciiTag(fd, "Page Name", td->td_pagename);
419 	if (TIFFFieldSet(tif,FIELD_PAGENUMBER))
420 		fprintf(fd, "  Page Number: %u-%u\n",
421 		    td->td_pagenumber[0], td->td_pagenumber[1]);
422 	if (TIFFFieldSet(tif,FIELD_COLORMAP)) {
423 		fprintf(fd, "  Color Map: ");
424 		if (flags & TIFFPRINT_COLORMAP) {
425 			fprintf(fd, "\n");
426 			n = 1L<<td->td_bitspersample;
427 			for (l = 0; l < n; l++)
428 				fprintf(fd, "   %5lu: %5u %5u %5u\n",
429 				    l,
430 				    td->td_colormap[0][l],
431 				    td->td_colormap[1][l],
432 				    td->td_colormap[2][l]);
433 		} else
434 			fprintf(fd, "(present)\n");
435 	}
436 #ifdef COLORIMETRY_SUPPORT
437 	if (TIFFFieldSet(tif,FIELD_WHITEPOINT))
438 		fprintf(fd, "  White Point: %g-%g\n",
439 		    td->td_whitepoint[0], td->td_whitepoint[1]);
440 	if (TIFFFieldSet(tif,FIELD_PRIMARYCHROMAS))
441 		fprintf(fd, "  Primary Chromaticities: %g,%g %g,%g %g,%g\n",
442 		    td->td_primarychromas[0], td->td_primarychromas[1],
443 		    td->td_primarychromas[2], td->td_primarychromas[3],
444 		    td->td_primarychromas[4], td->td_primarychromas[5]);
445 	if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE)) {
446 		fprintf(fd, "  Reference Black/White:\n");
447 		for (i = 0; i < td->td_samplesperpixel; i++)
448 			fprintf(fd, "    %2d: %5g %5g\n",
449 			    i,
450 			    td->td_refblackwhite[2*i+0],
451 			    td->td_refblackwhite[2*i+1]);
452 	}
453 	if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION)) {
454 		fprintf(fd, "  Transfer Function: ");
455 		if (flags & TIFFPRINT_CURVES) {
456 			fprintf(fd, "\n");
457 			n = 1L<<td->td_bitspersample;
458 			for (l = 0; l < n; l++) {
459 				fprintf(fd, "    %2lu: %5u",
460 				    l, td->td_transferfunction[0][l]);
461 				for (i = 1; i < td->td_samplesperpixel; i++)
462 					fprintf(fd, " %5u",
463 					    td->td_transferfunction[i][l]);
464 				fputc('\n', fd);
465 			}
466 		} else
467 			fprintf(fd, "(present)\n");
468 	}
469 #endif
470 #ifdef ICC_SUPPORT
471 	if (TIFFFieldSet(tif,FIELD_ICCPROFILE))
472 		fprintf(fd, "  ICC Profile: <present>, %lu bytes\n",
473 		    (u_long) td->td_profileLength);
474 #endif
475 #ifdef PHOTOSHOP_SUPPORT
476  	if (TIFFFieldSet(tif,FIELD_PHOTOSHOP))
477  		fprintf(fd, "  Photoshop Data: <present>, %lu bytes\n",
478  		    (u_long) td->td_photoshopLength);
479 #endif
480 #ifdef IPTC_SUPPORT
481  	if (TIFFFieldSet(tif,FIELD_RICHTIFFIPTC))
482  		fprintf(fd, "  RichTIFFIPTC Data: <present>, %lu bytes\n",
483  		    (u_long) td->td_richtiffiptcLength);
484 #endif
485 #if SUBIFD_SUPPORT
486 	if (TIFFFieldSet(tif, FIELD_SUBIFD)) {
487 		fprintf(fd, "  SubIFD Offsets:");
488 		for (i = 0; i < td->td_nsubifd; i++)
489 			fprintf(fd, " %5lu", (long) td->td_subifd[i]);
490 		fputc('\n', fd);
491 	}
492 #endif
493         /*
494         ** Custom tag support.
495         */
496         {
497             int  i;
498             short count;
499 
500             count = (short) TIFFGetTagListCount( tif );
501             for( i = 0; i < count; i++ )
502             {
503                 ttag_t  tag = TIFFGetTagListEntry( tif, i );
504                 const TIFFFieldInfo *fld;
505 
506                 fld = TIFFFieldWithTag( tif, tag );
507                 if( fld == NULL )
508                     continue;
509 
510                 if( fld->field_passcount )
511                 {
512                     short value_count;
513                     int j;
514                     void *raw_data;
515 
516                     if( TIFFGetField( tif, tag, &value_count, &raw_data ) != 1 )
517                         continue;
518 
519                     fprintf(fd, "  %s: ", fld->field_name );
520 
521                     for( j = 0; j < value_count; j++ )
522                     {
523 			if( fld->field_type == TIFF_BYTE )
524                             fprintf( fd, "%d",
525                                      (int) ((char *) raw_data)[j] );
526 			else if( fld->field_type == TIFF_SHORT )
527                             fprintf( fd, "%d",
528                                      (int) ((short *) raw_data)[j] );
529                         else if( fld->field_type == TIFF_LONG )
530                             fprintf( fd, "%d",
531                                      (int) ((long *) raw_data)[j] );
532 			else if( fld->field_type == TIFF_RATIONAL )
533 			    fprintf( fd, "%f",
534 				     ((float *) raw_data)[j] );
535                         else if( fld->field_type == TIFF_ASCII )
536                         {
537                             fprintf( fd, "%s",
538                                      (char *) raw_data );
539                             break;
540                         }
541                         else if( fld->field_type == TIFF_DOUBLE )
542                             fprintf( fd, "%f",
543                                      ((double *) raw_data)[j] );
544                         else if( fld->field_type == TIFF_FLOAT )
545                             fprintf( fd, "%f",
546                                      ((float *) raw_data)[j] );
547                         else
548                         {
549                             fprintf( fd,
550                                      "<unsupported data type in TIFFPrint>" );
551                             break;
552                         }
553 
554                         if( j < value_count-1 )
555                             fprintf( fd, "," );
556                     }
557                     fprintf( fd, "\n" );
558                 }
559                 else if( !fld->field_passcount
560                          && fld->field_type == TIFF_ASCII )
561                 {
562                     char *data;
563 
564                     if( TIFFGetField( tif, tag, &data ) )
565                         fprintf(fd, "  %s: %s\n", fld->field_name, data );
566                 }
567             }
568         }
569 
570 	if (tif->tif_tagmethods.printdir)
571 		(*tif->tif_tagmethods.printdir)(tif, fd, flags);
572 	if ((flags & TIFFPRINT_STRIPS) &&
573 	    TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) {
574 		tstrip_t s;
575 
576 		fprintf(fd, "  %lu %s:\n",
577 		    (long) td->td_nstrips,
578 		    isTiled(tif) ? "Tiles" : "Strips");
579 		for (s = 0; s < td->td_nstrips; s++)
580 			fprintf(fd, "    %3lu: [%8lu, %8lu]\n",
581 			    (u_long) s,
582 			    (u_long) td->td_stripoffset[s],
583 			    (u_long) td->td_stripbytecount[s]);
584 	}
585 }
586 
587 void
_TIFFprintAscii(FILE * fd,const char * cp)588 _TIFFprintAscii(FILE* fd, const char* cp)
589 {
590 	for (; *cp != '\0'; cp++) {
591 		const char* tp;
592 
593 		if (isprint(*cp)) {
594 			fputc(*cp, fd);
595 			continue;
596 		}
597 		for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++)
598 			if (*tp++ == *cp)
599 				break;
600 		if (*tp)
601 			fprintf(fd, "\\%c", *tp);
602 		else
603 			fprintf(fd, "\\%03o", *cp & 0xff);
604 	}
605 }
606 
607 void
_TIFFprintAsciiTag(FILE * fd,const char * name,const char * value)608 _TIFFprintAsciiTag(FILE* fd, const char* name, const char* value)
609 {
610 	fprintf(fd, "  %s: \"", name);
611 	_TIFFprintAscii(fd, value);
612 	fprintf(fd, "\"\n");
613 }
614