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