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 _TIFFprintAsciiBounded(FILE *fd, const char *cp, size_t max_chars);
36
37 static const char *const 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 "ICC L*a*b*", /* PHOTOMETRIC_ICCLAB */
48 "ITU L*a*b*" /* PHOTOMETRIC_ITULAB */
49 };
50 #define NPHOTONAMES (sizeof(photoNames) / sizeof(photoNames[0]))
51
52 static const char *const orientNames[] = {
53 "0 (0x0)",
54 "row 0 top, col 0 lhs", /* ORIENTATION_TOPLEFT */
55 "row 0 top, col 0 rhs", /* ORIENTATION_TOPRIGHT */
56 "row 0 bottom, col 0 rhs", /* ORIENTATION_BOTRIGHT */
57 "row 0 bottom, col 0 lhs", /* ORIENTATION_BOTLEFT */
58 "row 0 lhs, col 0 top", /* ORIENTATION_LEFTTOP */
59 "row 0 rhs, col 0 top", /* ORIENTATION_RIGHTTOP */
60 "row 0 rhs, col 0 bottom", /* ORIENTATION_RIGHTBOT */
61 "row 0 lhs, col 0 bottom", /* ORIENTATION_LEFTBOT */
62 };
63 #define NORIENTNAMES (sizeof(orientNames) / sizeof(orientNames[0]))
64
65 static const struct tagname
66 {
67 uint16_t tag;
68 const char *name;
69 } tagnames[] = {
70 {TIFFTAG_GDAL_METADATA, "GDAL Metadata"},
71 {TIFFTAG_GDAL_NODATA, "GDAL NoDataValue"},
72 };
73 #define NTAGS (sizeof(tagnames) / sizeof(tagnames[0]))
74
_TIFFPrintField(FILE * fd,const TIFFField * fip,uint32_t value_count,void * raw_data)75 static void _TIFFPrintField(FILE *fd, const TIFFField *fip,
76 uint32_t value_count, void *raw_data)
77 {
78 uint32_t j;
79
80 /* Print a user-friendly name for tags of relatively common use, but */
81 /* which aren't registered by libtiff itself. */
82 const char *field_name = fip->field_name;
83 if (TIFFFieldIsAnonymous(fip))
84 {
85 for (size_t i = 0; i < NTAGS; ++i)
86 {
87 if (fip->field_tag == tagnames[i].tag)
88 {
89 field_name = tagnames[i].name;
90 break;
91 }
92 }
93 }
94 fprintf(fd, " %s: ", field_name);
95
96 for (j = 0; j < value_count; j++)
97 {
98 if (fip->field_type == TIFF_BYTE)
99 fprintf(fd, "%" PRIu8, ((uint8_t *)raw_data)[j]);
100 else if (fip->field_type == TIFF_UNDEFINED)
101 fprintf(fd, "0x%" PRIx8, ((uint8_t *)raw_data)[j]);
102 else if (fip->field_type == TIFF_SBYTE)
103 fprintf(fd, "%" PRId8, ((int8_t *)raw_data)[j]);
104 else if (fip->field_type == TIFF_SHORT)
105 fprintf(fd, "%" PRIu16, ((uint16_t *)raw_data)[j]);
106 else if (fip->field_type == TIFF_SSHORT)
107 fprintf(fd, "%" PRId16, ((int16_t *)raw_data)[j]);
108 else if (fip->field_type == TIFF_LONG)
109 fprintf(fd, "%" PRIu32, ((uint32_t *)raw_data)[j]);
110 else if (fip->field_type == TIFF_SLONG)
111 fprintf(fd, "%" PRId32, ((int32_t *)raw_data)[j]);
112 else if (fip->field_type == TIFF_IFD)
113 fprintf(fd, "0x%" PRIx32, ((uint32_t *)raw_data)[j]);
114 else if (fip->field_type == TIFF_RATIONAL ||
115 fip->field_type == TIFF_SRATIONAL)
116 {
117 int tv_size = TIFFFieldSetGetSize(fip);
118 if (tv_size == 8)
119 fprintf(fd, "%lf", ((double *)raw_data)[j]);
120 else
121 fprintf(fd, "%f", ((float *)raw_data)[j]);
122 }
123 else if (fip->field_type == TIFF_FLOAT)
124 fprintf(fd, "%f", ((float *)raw_data)[j]);
125 else if (fip->field_type == TIFF_LONG8)
126 fprintf(fd, "%" PRIu64, ((uint64_t *)raw_data)[j]);
127 else if (fip->field_type == TIFF_SLONG8)
128 fprintf(fd, "%" PRId64, ((int64_t *)raw_data)[j]);
129 else if (fip->field_type == TIFF_IFD8)
130 fprintf(fd, "0x%" PRIx64, ((uint64_t *)raw_data)[j]);
131 else if (fip->field_type == TIFF_DOUBLE)
132 fprintf(fd, "%lf", ((double *)raw_data)[j]);
133 else if (fip->field_type == TIFF_ASCII)
134 {
135 fprintf(fd, "%s", (char *)raw_data);
136 break;
137 }
138 else
139 {
140 fprintf(fd, "<unsupported data type in TIFFPrint>");
141 break;
142 }
143
144 if (j < value_count - 1)
145 fprintf(fd, ",");
146 }
147
148 fprintf(fd, "\n");
149 }
150
_TIFFPrettyPrintField(TIFF * tif,const TIFFField * fip,FILE * fd,uint32_t tag,uint32_t value_count,void * raw_data)151 static int _TIFFPrettyPrintField(TIFF *tif, const TIFFField *fip, FILE *fd,
152 uint32_t tag, uint32_t value_count,
153 void *raw_data)
154 {
155 (void)tif;
156
157 /* do not try to pretty print auto-defined fields */
158 if (TIFFFieldIsAnonymous(fip))
159 {
160 return 0;
161 }
162
163 switch (tag)
164 {
165 case TIFFTAG_INKSET:
166 if (value_count == 2 && fip->field_type == TIFF_SHORT)
167 {
168 fprintf(fd, " Ink Set: ");
169 switch (*((uint16_t *)raw_data))
170 {
171 case INKSET_CMYK:
172 fprintf(fd, "CMYK\n");
173 break;
174 default:
175 fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n",
176 *((uint16_t *)raw_data),
177 *((uint16_t *)raw_data));
178 break;
179 }
180 return 1;
181 }
182 return 0;
183
184 case TIFFTAG_DOTRANGE:
185 if (value_count == 2 && fip->field_type == TIFF_SHORT)
186 {
187 fprintf(fd, " Dot Range: %" PRIu16 "-%" PRIu16 "\n",
188 ((uint16_t *)raw_data)[0], ((uint16_t *)raw_data)[1]);
189 return 1;
190 }
191 return 0;
192
193 case TIFFTAG_WHITEPOINT:
194 if (value_count == 2 && fip->field_type == TIFF_RATIONAL)
195 {
196 fprintf(fd, " White Point: %g-%g\n", ((float *)raw_data)[0],
197 ((float *)raw_data)[1]);
198 return 1;
199 }
200 return 0;
201
202 case TIFFTAG_XMLPACKET:
203 {
204 uint32_t i;
205
206 fprintf(fd, " XMLPacket (XMP Metadata):\n");
207 for (i = 0; i < value_count; i++)
208 fputc(((char *)raw_data)[i], fd);
209 fprintf(fd, "\n");
210 return 1;
211 }
212 case TIFFTAG_RICHTIFFIPTC:
213 fprintf(fd, " RichTIFFIPTC Data: <present>, %" PRIu32 " bytes\n",
214 value_count);
215 return 1;
216
217 case TIFFTAG_PHOTOSHOP:
218 fprintf(fd, " Photoshop Data: <present>, %" PRIu32 " bytes\n",
219 value_count);
220 return 1;
221
222 case TIFFTAG_ICCPROFILE:
223 fprintf(fd, " ICC Profile: <present>, %" PRIu32 " bytes\n",
224 value_count);
225 return 1;
226
227 case TIFFTAG_STONITS:
228 if (value_count == 1 && fip->field_type == TIFF_DOUBLE)
229 {
230 fprintf(fd, " Sample to Nits conversion factor: %.4e\n",
231 *((double *)raw_data));
232 return 1;
233 }
234 return 0;
235 }
236
237 return 0;
238 }
239
240 /*
241 * Print the contents of the current directory
242 * to the specified stdio file stream.
243 */
TIFFPrintDirectory(TIFF * tif,FILE * fd,long flags)244 void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
245 {
246 TIFFDirectory *td = &tif->tif_dir;
247 char *sep;
248 long l, n;
249
250 fprintf(fd, "TIFF Directory at offset 0x%" PRIx64 " (%" PRIu64 ")\n",
251 tif->tif_diroff, tif->tif_diroff);
252 if (TIFFFieldSet(tif, FIELD_SUBFILETYPE))
253 {
254 fprintf(fd, " Subfile Type:");
255 sep = " ";
256 if (td->td_subfiletype & FILETYPE_REDUCEDIMAGE)
257 {
258 fprintf(fd, "%sreduced-resolution image", sep);
259 sep = "/";
260 }
261 if (td->td_subfiletype & FILETYPE_PAGE)
262 {
263 fprintf(fd, "%smulti-page document", sep);
264 sep = "/";
265 }
266 if (td->td_subfiletype & FILETYPE_MASK)
267 fprintf(fd, "%stransparency mask", sep);
268 fprintf(fd, " (%" PRIu32 " = 0x%" PRIx32 ")\n", td->td_subfiletype,
269 td->td_subfiletype);
270 }
271 if (TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS))
272 {
273 fprintf(fd, " Image Width: %" PRIu32 " Image Length: %" PRIu32,
274 td->td_imagewidth, td->td_imagelength);
275 if (TIFFFieldSet(tif, FIELD_IMAGEDEPTH))
276 fprintf(fd, " Image Depth: %" PRIu32, td->td_imagedepth);
277 fprintf(fd, "\n");
278 }
279 if (TIFFFieldSet(tif, FIELD_TILEDIMENSIONS))
280 {
281 fprintf(fd, " Tile Width: %" PRIu32 " Tile Length: %" PRIu32,
282 td->td_tilewidth, td->td_tilelength);
283 if (TIFFFieldSet(tif, FIELD_TILEDEPTH))
284 fprintf(fd, " Tile Depth: %" PRIu32, td->td_tiledepth);
285 fprintf(fd, "\n");
286 }
287 if (TIFFFieldSet(tif, FIELD_RESOLUTION))
288 {
289 fprintf(fd, " Resolution: %g, %g", td->td_xresolution,
290 td->td_yresolution);
291 if (TIFFFieldSet(tif, FIELD_RESOLUTIONUNIT))
292 {
293 switch (td->td_resolutionunit)
294 {
295 case RESUNIT_NONE:
296 fprintf(fd, " (unitless)");
297 break;
298 case RESUNIT_INCH:
299 fprintf(fd, " pixels/inch");
300 break;
301 case RESUNIT_CENTIMETER:
302 fprintf(fd, " pixels/cm");
303 break;
304 default:
305 fprintf(fd, " (unit %" PRIu16 " = 0x%" PRIx16 ")",
306 td->td_resolutionunit, td->td_resolutionunit);
307 break;
308 }
309 }
310 fprintf(fd, "\n");
311 }
312 if (TIFFFieldSet(tif, FIELD_POSITION))
313 fprintf(fd, " Position: %g, %g\n", td->td_xposition, td->td_yposition);
314 if (TIFFFieldSet(tif, FIELD_BITSPERSAMPLE))
315 fprintf(fd, " Bits/Sample: %" PRIu16 "\n", td->td_bitspersample);
316 if (TIFFFieldSet(tif, FIELD_SAMPLEFORMAT))
317 {
318 fprintf(fd, " Sample Format: ");
319 switch (td->td_sampleformat)
320 {
321 case SAMPLEFORMAT_VOID:
322 fprintf(fd, "void\n");
323 break;
324 case SAMPLEFORMAT_INT:
325 fprintf(fd, "signed integer\n");
326 break;
327 case SAMPLEFORMAT_UINT:
328 fprintf(fd, "unsigned integer\n");
329 break;
330 case SAMPLEFORMAT_IEEEFP:
331 fprintf(fd, "IEEE floating point\n");
332 break;
333 case SAMPLEFORMAT_COMPLEXINT:
334 fprintf(fd, "complex signed integer\n");
335 break;
336 case SAMPLEFORMAT_COMPLEXIEEEFP:
337 fprintf(fd, "complex IEEE floating point\n");
338 break;
339 default:
340 fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n",
341 td->td_sampleformat, td->td_sampleformat);
342 break;
343 }
344 }
345 if (TIFFFieldSet(tif, FIELD_COMPRESSION))
346 {
347 const TIFFCodec *c = TIFFFindCODEC(td->td_compression);
348 fprintf(fd, " Compression Scheme: ");
349 if (c)
350 fprintf(fd, "%s\n", c->name);
351 else
352 fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", td->td_compression,
353 td->td_compression);
354 }
355 if (TIFFFieldSet(tif, FIELD_PHOTOMETRIC))
356 {
357 fprintf(fd, " Photometric Interpretation: ");
358 if (td->td_photometric < NPHOTONAMES)
359 fprintf(fd, "%s\n", photoNames[td->td_photometric]);
360 else
361 {
362 switch (td->td_photometric)
363 {
364 case PHOTOMETRIC_LOGL:
365 fprintf(fd, "CIE Log2(L)\n");
366 break;
367 case PHOTOMETRIC_LOGLUV:
368 fprintf(fd, "CIE Log2(L) (u',v')\n");
369 break;
370 default:
371 fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n",
372 td->td_photometric, td->td_photometric);
373 break;
374 }
375 }
376 }
377 if (TIFFFieldSet(tif, FIELD_EXTRASAMPLES) && td->td_extrasamples)
378 {
379 uint16_t i;
380 fprintf(fd, " Extra Samples: %" PRIu16 "<", td->td_extrasamples);
381 sep = "";
382 for (i = 0; i < td->td_extrasamples; i++)
383 {
384 switch (td->td_sampleinfo[i])
385 {
386 case EXTRASAMPLE_UNSPECIFIED:
387 fprintf(fd, "%sunspecified", sep);
388 break;
389 case EXTRASAMPLE_ASSOCALPHA:
390 fprintf(fd, "%sassoc-alpha", sep);
391 break;
392 case EXTRASAMPLE_UNASSALPHA:
393 fprintf(fd, "%sunassoc-alpha", sep);
394 break;
395 default:
396 fprintf(fd, "%s%" PRIu16 " (0x%" PRIx16 ")", sep,
397 td->td_sampleinfo[i], td->td_sampleinfo[i]);
398 break;
399 }
400 sep = ", ";
401 }
402 fprintf(fd, ">\n");
403 }
404 if (TIFFFieldSet(tif, FIELD_INKNAMES))
405 {
406 char *cp;
407 uint16_t i;
408 fprintf(fd, " Ink Names: ");
409 i = td->td_samplesperpixel;
410 sep = "";
411 for (cp = td->td_inknames;
412 i > 0 && cp < td->td_inknames + td->td_inknameslen;
413 cp = strchr(cp, '\0') + 1, i--)
414 {
415 size_t max_chars = td->td_inknameslen - (cp - td->td_inknames);
416 fputs(sep, fd);
417 _TIFFprintAsciiBounded(fd, cp, max_chars);
418 sep = ", ";
419 }
420 fputs("\n", fd);
421 }
422 if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
423 {
424 fprintf(fd, " NumberOfInks: %d\n", td->td_numberofinks);
425 }
426 if (TIFFFieldSet(tif, FIELD_THRESHHOLDING))
427 {
428 fprintf(fd, " Thresholding: ");
429 switch (td->td_threshholding)
430 {
431 case THRESHHOLD_BILEVEL:
432 fprintf(fd, "bilevel art scan\n");
433 break;
434 case THRESHHOLD_HALFTONE:
435 fprintf(fd, "halftone or dithered scan\n");
436 break;
437 case THRESHHOLD_ERRORDIFFUSE:
438 fprintf(fd, "error diffused\n");
439 break;
440 default:
441 fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n",
442 td->td_threshholding, td->td_threshholding);
443 break;
444 }
445 }
446 if (TIFFFieldSet(tif, FIELD_FILLORDER))
447 {
448 fprintf(fd, " FillOrder: ");
449 switch (td->td_fillorder)
450 {
451 case FILLORDER_MSB2LSB:
452 fprintf(fd, "msb-to-lsb\n");
453 break;
454 case FILLORDER_LSB2MSB:
455 fprintf(fd, "lsb-to-msb\n");
456 break;
457 default:
458 fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", td->td_fillorder,
459 td->td_fillorder);
460 break;
461 }
462 }
463 if (TIFFFieldSet(tif, FIELD_YCBCRSUBSAMPLING))
464 {
465 fprintf(fd, " YCbCr Subsampling: %" PRIu16 ", %" PRIu16 "\n",
466 td->td_ycbcrsubsampling[0], td->td_ycbcrsubsampling[1]);
467 }
468 if (TIFFFieldSet(tif, FIELD_YCBCRPOSITIONING))
469 {
470 fprintf(fd, " YCbCr Positioning: ");
471 switch (td->td_ycbcrpositioning)
472 {
473 case YCBCRPOSITION_CENTERED:
474 fprintf(fd, "centered\n");
475 break;
476 case YCBCRPOSITION_COSITED:
477 fprintf(fd, "cosited\n");
478 break;
479 default:
480 fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n",
481 td->td_ycbcrpositioning, td->td_ycbcrpositioning);
482 break;
483 }
484 }
485 if (TIFFFieldSet(tif, FIELD_HALFTONEHINTS))
486 fprintf(fd, " Halftone Hints: light %" PRIu16 " dark %" PRIu16 "\n",
487 td->td_halftonehints[0], td->td_halftonehints[1]);
488 if (TIFFFieldSet(tif, FIELD_ORIENTATION))
489 {
490 fprintf(fd, " Orientation: ");
491 if (td->td_orientation < NORIENTNAMES)
492 fprintf(fd, "%s\n", orientNames[td->td_orientation]);
493 else
494 fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", td->td_orientation,
495 td->td_orientation);
496 }
497 if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
498 fprintf(fd, " Samples/Pixel: %" PRIx16 "\n", td->td_samplesperpixel);
499 if (TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
500 {
501 fprintf(fd, " Rows/Strip: ");
502 if (td->td_rowsperstrip == (uint32_t)-1)
503 fprintf(fd, "(infinite)\n");
504 else
505 fprintf(fd, "%" PRIu32 "\n", td->td_rowsperstrip);
506 }
507 if (TIFFFieldSet(tif, FIELD_MINSAMPLEVALUE))
508 fprintf(fd, " Min Sample Value: %" PRIu16 "\n", td->td_minsamplevalue);
509 if (TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
510 fprintf(fd, " Max Sample Value: %" PRIu16 "\n", td->td_maxsamplevalue);
511 if (TIFFFieldSet(tif, FIELD_SMINSAMPLEVALUE))
512 {
513 int i;
514 int count =
515 (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
516 fprintf(fd, " SMin Sample Value:");
517 for (i = 0; i < count; ++i)
518 fprintf(fd, " %g", td->td_sminsamplevalue[i]);
519 fprintf(fd, "\n");
520 }
521 if (TIFFFieldSet(tif, FIELD_SMAXSAMPLEVALUE))
522 {
523 int i;
524 int count =
525 (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
526 fprintf(fd, " SMax Sample Value:");
527 for (i = 0; i < count; ++i)
528 fprintf(fd, " %g", td->td_smaxsamplevalue[i]);
529 fprintf(fd, "\n");
530 }
531 if (TIFFFieldSet(tif, FIELD_PLANARCONFIG))
532 {
533 fprintf(fd, " Planar Configuration: ");
534 switch (td->td_planarconfig)
535 {
536 case PLANARCONFIG_CONTIG:
537 fprintf(fd, "single image plane\n");
538 break;
539 case PLANARCONFIG_SEPARATE:
540 fprintf(fd, "separate image planes\n");
541 break;
542 default:
543 fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n",
544 td->td_planarconfig, td->td_planarconfig);
545 break;
546 }
547 }
548 if (TIFFFieldSet(tif, FIELD_PAGENUMBER))
549 fprintf(fd, " Page Number: %" PRIu16 "-%" PRIu16 "\n",
550 td->td_pagenumber[0], td->td_pagenumber[1]);
551 if (TIFFFieldSet(tif, FIELD_COLORMAP))
552 {
553 fprintf(fd, " Color Map: ");
554 if (flags & TIFFPRINT_COLORMAP)
555 {
556 fprintf(fd, "\n");
557 n = 1L << td->td_bitspersample;
558 for (l = 0; l < n; l++)
559 fprintf(fd, " %5ld: %5" PRIu16 " %5" PRIu16 " %5" PRIu16 "\n",
560 l, td->td_colormap[0][l], td->td_colormap[1][l],
561 td->td_colormap[2][l]);
562 }
563 else
564 fprintf(fd, "(present)\n");
565 }
566 if (TIFFFieldSet(tif, FIELD_REFBLACKWHITE))
567 {
568 int i;
569 fprintf(fd, " Reference Black/White:\n");
570 for (i = 0; i < 3; i++)
571 fprintf(fd, " %2d: %5g %5g\n", i,
572 td->td_refblackwhite[2 * i + 0],
573 td->td_refblackwhite[2 * i + 1]);
574 }
575 if (TIFFFieldSet(tif, FIELD_TRANSFERFUNCTION))
576 {
577 fprintf(fd, " Transfer Function: ");
578 if (flags & TIFFPRINT_CURVES)
579 {
580 fprintf(fd, "\n");
581 n = 1L << td->td_bitspersample;
582 for (l = 0; l < n; l++)
583 {
584 uint16_t i;
585 fprintf(fd, " %2ld: %5" PRIu16, l,
586 td->td_transferfunction[0][l]);
587 for (i = 1;
588 i < td->td_samplesperpixel - td->td_extrasamples && i < 3;
589 i++)
590 fprintf(fd, " %5" PRIu16, td->td_transferfunction[i][l]);
591 fputc('\n', fd);
592 }
593 }
594 else
595 fprintf(fd, "(present)\n");
596 }
597 if (TIFFFieldSet(tif, FIELD_SUBIFD) && (td->td_subifd))
598 {
599 uint16_t i;
600 fprintf(fd, " SubIFD Offsets:");
601 for (i = 0; i < td->td_nsubifd; i++)
602 fprintf(fd, " %5" PRIu64, td->td_subifd[i]);
603 fputc('\n', fd);
604 }
605
606 /*
607 ** Custom tag support.
608 */
609 {
610 int i;
611 short count;
612
613 count = (short)TIFFGetTagListCount(tif);
614 for (i = 0; i < count; i++)
615 {
616 uint32_t tag = TIFFGetTagListEntry(tif, i);
617 const TIFFField *fip;
618 uint32_t value_count;
619 int mem_alloc = 0;
620 void *raw_data = NULL;
621 uint16_t dotrange[2]; /* must be kept in that scope and not moved in
622 the below TIFFTAG_DOTRANGE specific case */
623
624 fip = TIFFFieldWithTag(tif, tag);
625 if (fip == NULL)
626 continue;
627
628 if (fip->field_passcount)
629 {
630 if (fip->field_readcount == TIFF_VARIABLE2)
631 {
632 if (TIFFGetField(tif, tag, &value_count, &raw_data) != 1)
633 continue;
634 }
635 else if (fip->field_readcount == TIFF_VARIABLE)
636 {
637 uint16_t small_value_count;
638 if (TIFFGetField(tif, tag, &small_value_count, &raw_data) !=
639 1)
640 continue;
641 value_count = small_value_count;
642 }
643 else
644 {
645 assert(fip->field_readcount == TIFF_VARIABLE ||
646 fip->field_readcount == TIFF_VARIABLE2);
647 continue;
648 }
649 }
650 else
651 {
652 if (fip->field_readcount == TIFF_VARIABLE ||
653 fip->field_readcount == TIFF_VARIABLE2)
654 value_count = 1;
655 else if (fip->field_readcount == TIFF_SPP)
656 value_count = td->td_samplesperpixel;
657 else
658 value_count = fip->field_readcount;
659 if (fip->field_tag == TIFFTAG_DOTRANGE &&
660 strcmp(fip->field_name, "DotRange") == 0)
661 {
662 /* TODO: This is an evil exception and should not have been
663 handled this way ... likely best if we move it into
664 the directory structure with an explicit field in
665 libtiff 4.1 and assign it a FIELD_ value */
666 raw_data = dotrange;
667 TIFFGetField(tif, tag, dotrange + 0, dotrange + 1);
668 }
669 else if (fip->field_type == TIFF_ASCII ||
670 fip->field_readcount == TIFF_VARIABLE ||
671 fip->field_readcount == TIFF_VARIABLE2 ||
672 fip->field_readcount == TIFF_SPP || value_count > 1)
673 {
674 if (TIFFGetField(tif, tag, &raw_data) != 1)
675 continue;
676 }
677 else
678 {
679 /*--: Rational2Double: For Rationals evaluate
680 * "set_field_type" to determine internal storage size. */
681 int tv_size = TIFFFieldSetGetSize(fip);
682 raw_data = _TIFFmallocExt(tif, tv_size * value_count);
683 mem_alloc = 1;
684 if (TIFFGetField(tif, tag, raw_data) != 1)
685 {
686 _TIFFfreeExt(tif, raw_data);
687 continue;
688 }
689 }
690 }
691
692 /*
693 * Catch the tags which needs to be specially handled
694 * and pretty print them. If tag not handled in
695 * _TIFFPrettyPrintField() fall down and print it as
696 * any other tag.
697 */
698 if (raw_data != NULL &&
699 !_TIFFPrettyPrintField(tif, fip, fd, tag, value_count,
700 raw_data))
701 _TIFFPrintField(fd, fip, value_count, raw_data);
702
703 if (mem_alloc)
704 _TIFFfreeExt(tif, raw_data);
705 }
706 }
707
708 if (tif->tif_tagmethods.printdir)
709 (*tif->tif_tagmethods.printdir)(tif, fd, flags);
710
711 if ((flags & TIFFPRINT_STRIPS) && TIFFFieldSet(tif, FIELD_STRIPOFFSETS))
712 {
713 uint32_t s;
714
715 fprintf(fd, " %" PRIu32 " %s:\n", td->td_nstrips,
716 isTiled(tif) ? "Tiles" : "Strips");
717 for (s = 0; s < td->td_nstrips; s++)
718 fprintf(fd, " %3" PRIu32 ": [%8" PRIu64 ", %8" PRIu64 "]\n", s,
719 TIFFGetStrileOffset(tif, s),
720 TIFFGetStrileByteCount(tif, s));
721 }
722 }
723
_TIFFprintAscii(FILE * fd,const char * cp)724 void _TIFFprintAscii(FILE *fd, const char *cp)
725 {
726 _TIFFprintAsciiBounded(fd, cp, strlen(cp));
727 }
728
_TIFFprintAsciiBounded(FILE * fd,const char * cp,size_t max_chars)729 static void _TIFFprintAsciiBounded(FILE *fd, const char *cp, size_t max_chars)
730 {
731 for (; max_chars > 0 && *cp != '\0'; cp++, max_chars--)
732 {
733 const char *tp;
734
735 if (isprint((int)*cp))
736 {
737 fputc(*cp, fd);
738 continue;
739 }
740 for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++)
741 if (*tp++ == *cp)
742 break;
743 if (*tp)
744 fprintf(fd, "\\%c", *tp);
745 else
746 fprintf(fd, "\\%03o", *cp & 0xff);
747 }
748 }
749
_TIFFprintAsciiTag(FILE * fd,const char * name,const char * value)750 void _TIFFprintAsciiTag(FILE *fd, const char *name, const char *value)
751 {
752 fprintf(fd, " %s: \"", name);
753 _TIFFprintAscii(fd, value);
754 fprintf(fd, "\"\n");
755 }
756