xref: /aosp_15_r20/external/pdfium/third_party/libtiff/tif_print.c (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
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