~ubuntu-branches/ubuntu/precise/tiff/precise-security

« back to all changes in this revision

Viewing changes to .pc/CVE-2014-81xx-9.patch/tools/tiffdump.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2015-03-30 08:11:18 UTC
  • Revision ID: package-import@ubuntu.com-20150330081118-bvaoaii1act27voq
Tags: 3.9.5-2ubuntu1.7
* SECURITY UPDATE: Fix multiple security issues
  - debian/patches/CVE-2014-81xx-1.patch to CVE-2014-81xx-11.patch
  - debian/patches/CVE-2014-8128-5.patch
  - debian/patches/CVE-2014-9655-1.patch to CVE-2014-9655-3.patch
  - debian/patches/read_overrun.patch
  - debian/patches/CVE-2014-8130.patch
  - CVE-2014-8127 (partially)
  - CVE-2014-8128
  - CVE-2014-8129
  - CVE-2014-8130
  - CVE-2014-9330
  - CVE-2014-9655

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: tiffdump.c,v 1.13.2.4 2010-07-07 14:02:56 dron 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
#include "tif_config.h"
 
28
 
 
29
#include <stdio.h>
 
30
#include <stdlib.h>
 
31
#include <string.h>
 
32
 
 
33
#ifdef HAVE_UNISTD_H
 
34
# include <unistd.h>
 
35
#endif
 
36
 
 
37
#ifdef HAVE_FCNTL_H
 
38
# include <fcntl.h>
 
39
#endif
 
40
 
 
41
#ifdef HAVE_SYS_TYPES_H
 
42
# include <sys/types.h>
 
43
#endif
 
44
 
 
45
#ifdef HAVE_IO_H
 
46
# include <io.h>
 
47
#endif
 
48
 
 
49
#include "tiffio.h"
 
50
 
 
51
#ifndef O_BINARY
 
52
# define O_BINARY       0
 
53
#endif
 
54
 
 
55
/* Safe multiply which returns zero if there is an integer overflow */
 
56
#ifndef TIFFSafeMultiply
 
57
# define TIFFSafeMultiply(t,v,m) ((((t)m != (t)0) && (((t)((v*m)/m)) == (t)v)) ? (t)(v*m) : (t)0)
 
58
#endif
 
59
 
 
60
char*   appname;
 
61
char*   curfile;
 
62
int     swabflag;
 
63
int     bigendian;
 
64
int     typeshift[14];          /* data type shift counts */
 
65
long    typemask[14];           /* data type masks */
 
66
uint32  maxitems = 24;          /* maximum indirect data items to print */
 
67
 
 
68
char*   bytefmt = "%s%#02x";            /* BYTE */
 
69
char*   sbytefmt = "%s%d";              /* SBYTE */
 
70
char*   shortfmt = "%s%u";              /* SHORT */
 
71
char*   sshortfmt = "%s%d";             /* SSHORT */
 
72
char*   longfmt = "%s%lu";              /* LONG */
 
73
char*   slongfmt = "%s%ld";             /* SLONG */
 
74
char*   rationalfmt = "%s%g";           /* RATIONAL */
 
75
char*   srationalfmt = "%s%g";          /* SRATIONAL */
 
76
char*   floatfmt = "%s%g";              /* FLOAT */
 
77
char*   doublefmt = "%s%g";             /* DOUBLE */
 
78
char*   ifdfmt = "%s%#04x";             /* IFD offset */
 
79
 
 
80
static  void dump(int, off_t);
 
81
extern  int optind;
 
82
extern  char* optarg;
 
83
 
 
84
void
 
85
usage()
 
86
{
 
87
        fprintf(stderr, "usage: %s [-h] [-o offset] [-m maxitems] file.tif ...\n", appname);
 
88
        exit(-1);
 
89
}
 
90
 
 
91
int
 
92
main(int argc, char* argv[])
 
93
{
 
94
        int one = 1, fd;
 
95
        int multiplefiles = (argc > 1);
 
96
        int c;
 
97
        uint32 diroff = (uint32) 0;
 
98
        bigendian = (*(char *)&one == 0);
 
99
 
 
100
        appname = argv[0];
 
101
        while ((c = getopt(argc, argv, "m:o:h")) != -1) {
 
102
                switch (c) {
 
103
                case 'h':                       /* print values in hex */
 
104
                        shortfmt = "%s%#x";
 
105
                        sshortfmt = "%s%#x";
 
106
                        longfmt = "%s%#lx";
 
107
                        slongfmt = "%s%#lx";
 
108
                        break;
 
109
                case 'o':
 
110
                        diroff = (uint32) strtoul(optarg, NULL, 0);
 
111
                        break;
 
112
                case 'm':
 
113
                        maxitems = strtoul(optarg, NULL, 0);
 
114
                        break;
 
115
                default:
 
116
                        usage();
 
117
                }
 
118
        }
 
119
        if (optind >= argc)
 
120
                usage();
 
121
        for (; optind < argc; optind++) {
 
122
                fd = open(argv[optind], O_RDONLY|O_BINARY, 0);
 
123
                if (fd < 0) {
 
124
                        perror(argv[0]);
 
125
                        return (-1);
 
126
                }
 
127
                if (multiplefiles)
 
128
                        printf("%s:\n", argv[optind]);
 
129
                curfile = argv[optind];
 
130
                swabflag = 0;
 
131
                dump(fd, diroff);
 
132
                close(fd);
 
133
        }
 
134
        return (0);
 
135
}
 
136
 
 
137
static  TIFFHeader hdr;
 
138
 
 
139
#define ord(e)  ((int)e)
 
140
 
 
141
/*
 
142
 * Initialize shift & mask tables and byte
 
143
 * swapping state according to the file
 
144
 * byte order.
 
145
 */
 
146
static void
 
147
InitByteOrder(int magic)
 
148
{
 
149
        typemask[0] = 0;
 
150
        typemask[ord(TIFF_BYTE)] = 0xff;
 
151
        typemask[ord(TIFF_SBYTE)] = 0xff;
 
152
        typemask[ord(TIFF_UNDEFINED)] = 0xff;
 
153
        typemask[ord(TIFF_SHORT)] = 0xffff;
 
154
        typemask[ord(TIFF_SSHORT)] = 0xffff;
 
155
        typemask[ord(TIFF_LONG)] = 0xffffffff;
 
156
        typemask[ord(TIFF_SLONG)] = 0xffffffff;
 
157
        typemask[ord(TIFF_IFD)] = 0xffffffff;
 
158
        typemask[ord(TIFF_RATIONAL)] = 0xffffffff;
 
159
        typemask[ord(TIFF_SRATIONAL)] = 0xffffffff;
 
160
        typemask[ord(TIFF_FLOAT)] = 0xffffffff;
 
161
        typemask[ord(TIFF_DOUBLE)] = 0xffffffff;
 
162
        typeshift[0] = 0;
 
163
        typeshift[ord(TIFF_LONG)] = 0;
 
164
        typeshift[ord(TIFF_SLONG)] = 0;
 
165
        typeshift[ord(TIFF_IFD)] = 0;
 
166
        typeshift[ord(TIFF_RATIONAL)] = 0;
 
167
        typeshift[ord(TIFF_SRATIONAL)] = 0;
 
168
        typeshift[ord(TIFF_FLOAT)] = 0;
 
169
        typeshift[ord(TIFF_DOUBLE)] = 0;
 
170
        if (magic == TIFF_BIGENDIAN || magic == MDI_BIGENDIAN) {
 
171
                typeshift[ord(TIFF_BYTE)] = 24;
 
172
                typeshift[ord(TIFF_SBYTE)] = 24;
 
173
                typeshift[ord(TIFF_SHORT)] = 16;
 
174
                typeshift[ord(TIFF_SSHORT)] = 16;
 
175
                swabflag = !bigendian;
 
176
        } else {
 
177
                typeshift[ord(TIFF_BYTE)] = 0;
 
178
                typeshift[ord(TIFF_SBYTE)] = 0;
 
179
                typeshift[ord(TIFF_SHORT)] = 0;
 
180
                typeshift[ord(TIFF_SSHORT)] = 0;
 
181
                swabflag = bigendian;
 
182
        }
 
183
}
 
184
 
 
185
static  off_t ReadDirectory(int, unsigned, off_t);
 
186
static  void ReadError(char*);
 
187
static  void Error(const char*, ...);
 
188
static  void Fatal(const char*, ...);
 
189
 
 
190
static void
 
191
dump(int fd, off_t diroff)
 
192
{
 
193
        unsigned i;
 
194
 
 
195
        lseek(fd, (off_t) 0, 0);
 
196
        if (read(fd, (char*) &hdr, sizeof (hdr)) != sizeof (hdr))
 
197
                ReadError("TIFF header");
 
198
        /*
 
199
         * Setup the byte order handling.
 
200
         */
 
201
        if (hdr.tiff_magic != TIFF_BIGENDIAN && hdr.tiff_magic != TIFF_LITTLEENDIAN &&
 
202
#if HOST_BIGENDIAN
 
203
            /* MDI is sensitive to the host byte order, unlike TIFF */
 
204
            MDI_BIGENDIAN != hdr.tiff_magic )
 
205
#else
 
206
            MDI_LITTLEENDIAN != hdr.tiff_magic )
 
207
#endif
 
208
                Fatal("Not a TIFF or MDI file, bad magic number %u (%#x)",
 
209
                    hdr.tiff_magic, hdr.tiff_magic);
 
210
        InitByteOrder(hdr.tiff_magic);
 
211
        /*
 
212
         * Swap header if required.
 
213
         */
 
214
        if (swabflag) {
 
215
                TIFFSwabShort(&hdr.tiff_version);
 
216
                TIFFSwabLong(&hdr.tiff_diroff);
 
217
        }
 
218
        /*
 
219
         * Now check version (if needed, it's been byte-swapped).
 
220
         * Note that this isn't actually a version number, it's a
 
221
         * magic number that doesn't change (stupid).
 
222
         */
 
223
        if (hdr.tiff_version != TIFF_VERSION)
 
224
                Fatal("Not a TIFF file, bad version number %u (%#x)",
 
225
                    hdr.tiff_version, hdr.tiff_version); 
 
226
        printf("Magic: %#x <%s-endian> Version: %#x\n",
 
227
            hdr.tiff_magic,
 
228
            hdr.tiff_magic == TIFF_BIGENDIAN ? "big" : "little",
 
229
            hdr.tiff_version);
 
230
        if (diroff == 0)
 
231
            diroff = hdr.tiff_diroff;
 
232
        for (i = 0; diroff != 0; i++) {
 
233
                if (i > 0)
 
234
                        putchar('\n');
 
235
                diroff = ReadDirectory(fd, i, diroff);
 
236
        }
 
237
}
 
238
 
 
239
static int datawidth[] = {
 
240
    0,  /* nothing */
 
241
    1,  /* TIFF_BYTE */
 
242
    1,  /* TIFF_ASCII */
 
243
    2,  /* TIFF_SHORT */
 
244
    4,  /* TIFF_LONG */
 
245
    8,  /* TIFF_RATIONAL */
 
246
    1,  /* TIFF_SBYTE */
 
247
    1,  /* TIFF_UNDEFINED */
 
248
    2,  /* TIFF_SSHORT */
 
249
    4,  /* TIFF_SLONG */
 
250
    8,  /* TIFF_SRATIONAL */
 
251
    4,  /* TIFF_FLOAT */
 
252
    8,  /* TIFF_DOUBLE */
 
253
    4   /* TIFF_IFD */
 
254
};
 
255
#define NWIDTHS (sizeof (datawidth) / sizeof (datawidth[0]))
 
256
static  int TIFFFetchData(int, TIFFDirEntry*, void*);
 
257
static  void PrintTag(FILE*, uint16);
 
258
static  void PrintType(FILE*, uint16);
 
259
static  void PrintData(FILE*, uint16, uint32, unsigned char*);
 
260
 
 
261
/*
 
262
 * Read the next TIFF directory from a file
 
263
 * and convert it to the internal format.
 
264
 * We read directories sequentially.
 
265
 */
 
266
static off_t
 
267
ReadDirectory(int fd, unsigned ix, off_t off)
 
268
{
 
269
        register TIFFDirEntry *dp;
 
270
        register unsigned int n;
 
271
        TIFFDirEntry *dir = 0;
 
272
        uint16 dircount;
 
273
        int space;
 
274
        uint32 nextdiroff = 0;
 
275
 
 
276
        if (off == 0)                   /* no more directories */
 
277
                goto done;
 
278
        if (lseek(fd, (off_t) off, 0) != off) {
 
279
                Fatal("Seek error accessing TIFF directory");
 
280
                goto done;
 
281
        }
 
282
        if (read(fd, (char*) &dircount, sizeof (uint16)) != sizeof (uint16)) {
 
283
                ReadError("directory count");
 
284
                goto done;
 
285
        }
 
286
        if (swabflag)
 
287
                TIFFSwabShort(&dircount);
 
288
        dir = (TIFFDirEntry *)_TIFFmalloc(dircount * sizeof (TIFFDirEntry));
 
289
        if (dir == NULL) {
 
290
                Fatal("No space for TIFF directory");
 
291
                goto done;
 
292
        }
 
293
        n = read(fd, (char*) dir, dircount*sizeof (*dp));
 
294
        if (n != dircount*sizeof (*dp)) {
 
295
                n /= sizeof (*dp);
 
296
                Error(
 
297
            "Could only read %u of %u entries in directory at offset %#lx",
 
298
                    n, dircount, (unsigned long) off);
 
299
                dircount = n;
 
300
        }
 
301
        if (read(fd, (char*) &nextdiroff, sizeof (uint32)) != sizeof (uint32))
 
302
                nextdiroff = 0;
 
303
        if (swabflag)
 
304
                TIFFSwabLong(&nextdiroff);
 
305
        printf("Directory %u: offset %lu (%#lx) next %lu (%#lx)\n", ix,
 
306
            (unsigned long)off, (unsigned long)off,
 
307
            (unsigned long)nextdiroff, (unsigned long)nextdiroff);
 
308
        for (dp = dir, n = dircount; n > 0; n--, dp++) {
 
309
                if (swabflag) {
 
310
                        TIFFSwabArrayOfShort(&dp->tdir_tag, 2);
 
311
                        TIFFSwabArrayOfLong(&dp->tdir_count, 2);
 
312
                }
 
313
                PrintTag(stdout, dp->tdir_tag);
 
314
                putchar(' ');
 
315
                PrintType(stdout, dp->tdir_type);
 
316
                putchar(' ');
 
317
                printf("%lu<", (unsigned long) dp->tdir_count);
 
318
                if (dp->tdir_type >= NWIDTHS) {
 
319
                        printf(">\n");
 
320
                        continue;
 
321
                }
 
322
                space = TIFFSafeMultiply(int, dp->tdir_count, datawidth[dp->tdir_type]);
 
323
                if (space <= 0) {
 
324
                        printf(">\n");
 
325
                        Error("Invalid count for tag %u", dp->tdir_tag);
 
326
                        continue;
 
327
                }
 
328
                if (space <= 4) {
 
329
                        switch (dp->tdir_type) {
 
330
                        case TIFF_FLOAT:
 
331
                        case TIFF_UNDEFINED:
 
332
                        case TIFF_ASCII:
 
333
                        case TIFF_BYTE:
 
334
                        case TIFF_SBYTE:
 
335
                        case TIFF_SHORT:
 
336
                        case TIFF_SSHORT:
 
337
                        case TIFF_LONG:
 
338
                        case TIFF_SLONG:
 
339
                        case TIFF_IFD: {
 
340
                                unsigned char data[4];
 
341
                                _TIFFmemcpy(data, &dp->tdir_offset, 4);
 
342
                                if (swabflag)
 
343
                                        TIFFSwabLong((uint32*) data);
 
344
                                PrintData(stdout,
 
345
                                    dp->tdir_type, dp->tdir_count, data);
 
346
                                break;
 
347
                                       }
 
348
                        }
 
349
                } else {
 
350
                        unsigned char *data = (unsigned char *)_TIFFmalloc(space);
 
351
                        if (data) {
 
352
                                if (TIFFFetchData(fd, dp, data)) {
 
353
                                        if (dp->tdir_count > maxitems) {
 
354
                                                PrintData(stdout, dp->tdir_type,
 
355
                                                    maxitems, data);
 
356
                                                printf(" ...");
 
357
                                        } else
 
358
                                                PrintData(stdout, dp->tdir_type,
 
359
                                                    dp->tdir_count, data);
 
360
                                }
 
361
                                _TIFFfree(data);
 
362
                        } else
 
363
                                Error("No space for data for tag %u",
 
364
                                    dp->tdir_tag);
 
365
                }
 
366
                printf(">\n");
 
367
        }
 
368
done:
 
369
        if (dir)
 
370
                _TIFFfree((char *)dir);
 
371
        return (nextdiroff);
 
372
}
 
373
 
 
374
static  struct tagname {
 
375
        uint16  tag;
 
376
        char*   name;
 
377
} tagnames[] = {
 
378
    { TIFFTAG_SUBFILETYPE,      "SubFileType" },
 
379
    { TIFFTAG_OSUBFILETYPE,     "OldSubFileType" },
 
380
    { TIFFTAG_IMAGEWIDTH,       "ImageWidth" },
 
381
    { TIFFTAG_IMAGELENGTH,      "ImageLength" },
 
382
    { TIFFTAG_BITSPERSAMPLE,    "BitsPerSample" },
 
383
    { TIFFTAG_COMPRESSION,      "Compression" },
 
384
    { TIFFTAG_PHOTOMETRIC,      "Photometric" },
 
385
    { TIFFTAG_THRESHHOLDING,    "Threshholding" },
 
386
    { TIFFTAG_CELLWIDTH,        "CellWidth" },
 
387
    { TIFFTAG_CELLLENGTH,       "CellLength" },
 
388
    { TIFFTAG_FILLORDER,        "FillOrder" },
 
389
    { TIFFTAG_DOCUMENTNAME,     "DocumentName" },
 
390
    { TIFFTAG_IMAGEDESCRIPTION, "ImageDescription" },
 
391
    { TIFFTAG_MAKE,             "Make" },
 
392
    { TIFFTAG_MODEL,            "Model" },
 
393
    { TIFFTAG_STRIPOFFSETS,     "StripOffsets" },
 
394
    { TIFFTAG_ORIENTATION,      "Orientation" },
 
395
    { TIFFTAG_SAMPLESPERPIXEL,  "SamplesPerPixel" },
 
396
    { TIFFTAG_ROWSPERSTRIP,     "RowsPerStrip" },
 
397
    { TIFFTAG_STRIPBYTECOUNTS,  "StripByteCounts" },
 
398
    { TIFFTAG_MINSAMPLEVALUE,   "MinSampleValue" },
 
399
    { TIFFTAG_MAXSAMPLEVALUE,   "MaxSampleValue" },
 
400
    { TIFFTAG_XRESOLUTION,      "XResolution" },
 
401
    { TIFFTAG_YRESOLUTION,      "YResolution" },
 
402
    { TIFFTAG_PLANARCONFIG,     "PlanarConfig" },
 
403
    { TIFFTAG_PAGENAME,         "PageName" },
 
404
    { TIFFTAG_XPOSITION,        "XPosition" },
 
405
    { TIFFTAG_YPOSITION,        "YPosition" },
 
406
    { TIFFTAG_FREEOFFSETS,      "FreeOffsets" },
 
407
    { TIFFTAG_FREEBYTECOUNTS,   "FreeByteCounts" },
 
408
    { TIFFTAG_GRAYRESPONSEUNIT, "GrayResponseUnit" },
 
409
    { TIFFTAG_GRAYRESPONSECURVE,"GrayResponseCurve" },
 
410
    { TIFFTAG_GROUP3OPTIONS,    "Group3Options" },
 
411
    { TIFFTAG_GROUP4OPTIONS,    "Group4Options" },
 
412
    { TIFFTAG_RESOLUTIONUNIT,   "ResolutionUnit" },
 
413
    { TIFFTAG_PAGENUMBER,       "PageNumber" },
 
414
    { TIFFTAG_COLORRESPONSEUNIT,"ColorResponseUnit" },
 
415
    { TIFFTAG_TRANSFERFUNCTION, "TransferFunction" },
 
416
    { TIFFTAG_SOFTWARE,         "Software" },
 
417
    { TIFFTAG_DATETIME,         "DateTime" },
 
418
    { TIFFTAG_ARTIST,           "Artist" },
 
419
    { TIFFTAG_HOSTCOMPUTER,     "HostComputer" },
 
420
    { TIFFTAG_PREDICTOR,        "Predictor" },
 
421
    { TIFFTAG_WHITEPOINT,       "Whitepoint" },
 
422
    { TIFFTAG_PRIMARYCHROMATICITIES,"PrimaryChromaticities" },
 
423
    { TIFFTAG_COLORMAP,         "Colormap" },
 
424
    { TIFFTAG_HALFTONEHINTS,    "HalftoneHints" },
 
425
    { TIFFTAG_TILEWIDTH,        "TileWidth" },
 
426
    { TIFFTAG_TILELENGTH,       "TileLength" },
 
427
    { TIFFTAG_TILEOFFSETS,      "TileOffsets" },
 
428
    { TIFFTAG_TILEBYTECOUNTS,   "TileByteCounts" },
 
429
    { TIFFTAG_BADFAXLINES,      "BadFaxLines" },
 
430
    { TIFFTAG_CLEANFAXDATA,     "CleanFaxData" },
 
431
    { TIFFTAG_CONSECUTIVEBADFAXLINES, "ConsecutiveBadFaxLines" },
 
432
    { TIFFTAG_SUBIFD,           "SubIFD" },
 
433
    { TIFFTAG_INKSET,           "InkSet" },
 
434
    { TIFFTAG_INKNAMES,         "InkNames" },
 
435
    { TIFFTAG_NUMBEROFINKS,     "NumberOfInks" },
 
436
    { TIFFTAG_DOTRANGE,         "DotRange" },
 
437
    { TIFFTAG_TARGETPRINTER,    "TargetPrinter" },
 
438
    { TIFFTAG_EXTRASAMPLES,     "ExtraSamples" },
 
439
    { TIFFTAG_SAMPLEFORMAT,     "SampleFormat" },
 
440
    { TIFFTAG_SMINSAMPLEVALUE,  "SMinSampleValue" },
 
441
    { TIFFTAG_SMAXSAMPLEVALUE,  "SMaxSampleValue" },
 
442
    { TIFFTAG_JPEGPROC,         "JPEGProcessingMode" },
 
443
    { TIFFTAG_JPEGIFOFFSET,     "JPEGInterchangeFormat" },
 
444
    { TIFFTAG_JPEGIFBYTECOUNT,  "JPEGInterchangeFormatLength" },
 
445
    { TIFFTAG_JPEGRESTARTINTERVAL,"JPEGRestartInterval" },
 
446
    { TIFFTAG_JPEGLOSSLESSPREDICTORS,"JPEGLosslessPredictors" },
 
447
    { TIFFTAG_JPEGPOINTTRANSFORM,"JPEGPointTransform" },
 
448
    { TIFFTAG_JPEGTABLES,       "JPEGTables" },
 
449
    { TIFFTAG_JPEGQTABLES,      "JPEGQTables" },
 
450
    { TIFFTAG_JPEGDCTABLES,     "JPEGDCTables" },
 
451
    { TIFFTAG_JPEGACTABLES,     "JPEGACTables" },
 
452
    { TIFFTAG_YCBCRCOEFFICIENTS,"YCbCrCoefficients" },
 
453
    { TIFFTAG_YCBCRSUBSAMPLING, "YCbCrSubsampling" },
 
454
    { TIFFTAG_YCBCRPOSITIONING, "YCbCrPositioning" },
 
455
    { TIFFTAG_REFERENCEBLACKWHITE, "ReferenceBlackWhite" },
 
456
    { TIFFTAG_REFPTS,           "IgReferencePoints (Island Graphics)" },
 
457
    { TIFFTAG_REGIONTACKPOINT,  "IgRegionTackPoint (Island Graphics)" },
 
458
    { TIFFTAG_REGIONWARPCORNERS,"IgRegionWarpCorners (Island Graphics)" },
 
459
    { TIFFTAG_REGIONAFFINE,     "IgRegionAffine (Island Graphics)" },
 
460
    { TIFFTAG_MATTEING,         "OBSOLETE Matteing (Silicon Graphics)" },
 
461
    { TIFFTAG_DATATYPE,         "OBSOLETE DataType (Silicon Graphics)" },
 
462
    { TIFFTAG_IMAGEDEPTH,       "ImageDepth (Silicon Graphics)" },
 
463
    { TIFFTAG_TILEDEPTH,        "TileDepth (Silicon Graphics)" },
 
464
    { 32768,                    "OLD BOGUS Matteing tag" },
 
465
    { TIFFTAG_COPYRIGHT,        "Copyright" },
 
466
    { TIFFTAG_ICCPROFILE,       "ICC Profile" },
 
467
    { TIFFTAG_JBIGOPTIONS,      "JBIG Options" },
 
468
    { TIFFTAG_STONITS,          "StoNits" },
 
469
};
 
470
#define NTAGS   (sizeof (tagnames) / sizeof (tagnames[0]))
 
471
 
 
472
static void
 
473
PrintTag(FILE* fd, uint16 tag)
 
474
{
 
475
        register struct tagname *tp;
 
476
 
 
477
        for (tp = tagnames; tp < &tagnames[NTAGS]; tp++)
 
478
                if (tp->tag == tag) {
 
479
                        fprintf(fd, "%s (%u)", tp->name, tag);
 
480
                        return;
 
481
                }
 
482
        fprintf(fd, "%u (%#x)", tag, tag);
 
483
}
 
484
 
 
485
static void
 
486
PrintType(FILE* fd, uint16 type)
 
487
{
 
488
        static char *typenames[] = {
 
489
            "0",
 
490
            "BYTE",
 
491
            "ASCII",
 
492
            "SHORT",
 
493
            "LONG",
 
494
            "RATIONAL",
 
495
            "SBYTE",
 
496
            "UNDEFINED",
 
497
            "SSHORT",
 
498
            "SLONG",
 
499
            "SRATIONAL",
 
500
            "FLOAT",
 
501
            "DOUBLE"
 
502
        };
 
503
#define NTYPES  (sizeof (typenames) / sizeof (typenames[0]))
 
504
 
 
505
        if (type < NTYPES)
 
506
                fprintf(fd, "%s (%u)", typenames[type], type);
 
507
        else
 
508
                fprintf(fd, "%u (%#x)", type, type);
 
509
}
 
510
#undef  NTYPES
 
511
 
 
512
#include <ctype.h>
 
513
 
 
514
static void
 
515
PrintASCII(FILE* fd, uint32 cc, const unsigned char* cp)
 
516
{
 
517
        for (; cc > 0; cc--, cp++) {
 
518
                const char* tp;
 
519
 
 
520
                if (isprint(*cp)) {
 
521
                        fputc(*cp, fd);
 
522
                        continue;
 
523
                }
 
524
                for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++)
 
525
                        if (*tp++ == *cp)
 
526
                                break;
 
527
                if (*tp)
 
528
                        fprintf(fd, "\\%c", *tp);
 
529
                else if (*cp)
 
530
                        fprintf(fd, "\\%03o", *cp);
 
531
                else
 
532
                        fprintf(fd, "\\0");
 
533
        }
 
534
}
 
535
 
 
536
static void
 
537
PrintData(FILE* fd, uint16 type, uint32 count, unsigned char* data)
 
538
{
 
539
        char* sep = "";
 
540
 
 
541
        switch (type) {
 
542
        case TIFF_BYTE:
 
543
                while (count-- > 0)
 
544
                        fprintf(fd, bytefmt, sep, *data++), sep = " ";
 
545
                break;
 
546
        case TIFF_SBYTE:
 
547
                while (count-- > 0)
 
548
                        fprintf(fd, sbytefmt, sep, *(char *)data++), sep = " ";
 
549
                break;
 
550
        case TIFF_UNDEFINED:
 
551
                while (count-- > 0)
 
552
                        fprintf(fd, bytefmt, sep, *data++), sep = " ";
 
553
                break;
 
554
        case TIFF_ASCII:
 
555
                PrintASCII(fd, count, data);
 
556
                break;
 
557
        case TIFF_SHORT: {
 
558
                uint16 *wp = (uint16*)data;
 
559
                while (count-- > 0)
 
560
                        fprintf(fd, shortfmt, sep, *wp++), sep = " ";
 
561
                break;
 
562
        }
 
563
        case TIFF_SSHORT: {
 
564
                int16 *wp = (int16*)data;
 
565
                while (count-- > 0)
 
566
                        fprintf(fd, sshortfmt, sep, *wp++), sep = " ";
 
567
                break;
 
568
        }
 
569
        case TIFF_LONG: {
 
570
                uint32 *lp = (uint32*)data;
 
571
                while (count-- > 0) {
 
572
                        fprintf(fd, longfmt, sep, (unsigned long) *lp++);
 
573
                        sep = " ";
 
574
                }
 
575
                break;
 
576
        }
 
577
        case TIFF_SLONG: {
 
578
                int32 *lp = (int32*)data;
 
579
                while (count-- > 0)
 
580
                        fprintf(fd, slongfmt, sep, (long) *lp++), sep = " ";
 
581
                break;
 
582
        }
 
583
        case TIFF_RATIONAL: {
 
584
                uint32 *lp = (uint32*)data;
 
585
                while (count-- > 0) {
 
586
                        if (lp[1] == 0)
 
587
                                fprintf(fd, "%sNan (%lu/%lu)", sep,
 
588
                                    (unsigned long) lp[0],
 
589
                                    (unsigned long) lp[1]);
 
590
                        else
 
591
                                fprintf(fd, rationalfmt, sep,
 
592
                                    (double)lp[0] / (double)lp[1]);
 
593
                        sep = " ";
 
594
                        lp += 2;
 
595
                }
 
596
                break;
 
597
        }
 
598
        case TIFF_SRATIONAL: {
 
599
                int32 *lp = (int32*)data;
 
600
                while (count-- > 0) {
 
601
                        if (lp[1] == 0)
 
602
                                fprintf(fd, "%sNan (%ld/%ld)", sep,
 
603
                                    (long) lp[0], (long) lp[1]);
 
604
                        else
 
605
                                fprintf(fd, srationalfmt, sep,
 
606
                                    (double)lp[0] / (double)lp[1]);
 
607
                        sep = " ";
 
608
                        lp += 2;
 
609
                }
 
610
                break;
 
611
        }
 
612
        case TIFF_FLOAT: {
 
613
                float *fp = (float *)data;
 
614
                while (count-- > 0)
 
615
                        fprintf(fd, floatfmt, sep, *fp++), sep = " ";
 
616
                break;
 
617
        }
 
618
        case TIFF_DOUBLE: {
 
619
                double *dp = (double *)data;
 
620
                while (count-- > 0)
 
621
                        fprintf(fd, doublefmt, sep, *dp++), sep = " ";
 
622
                break;
 
623
        }
 
624
        case TIFF_IFD: {
 
625
                uint32 *lp = (uint32*)data;
 
626
                while (count-- > 0) {
 
627
                        fprintf(fd, ifdfmt, sep, (unsigned long) *lp++);
 
628
                        sep = " ";
 
629
                }
 
630
                break;
 
631
        }
 
632
        }
 
633
}
 
634
 
 
635
/*
 
636
 * Fetch a contiguous directory item.
 
637
 */
 
638
static int
 
639
TIFFFetchData(int fd, TIFFDirEntry* dir, void* cp)
 
640
{
 
641
        int cc, w;
 
642
 
 
643
        w = (dir->tdir_type < NWIDTHS ? datawidth[dir->tdir_type] : 0);
 
644
        cc = dir->tdir_count * w;
 
645
        if (lseek(fd, (off_t)dir->tdir_offset, 0) != (off_t)-1
 
646
            && read(fd, cp, cc) == cc) {
 
647
                if (swabflag) {
 
648
                        switch (dir->tdir_type) {
 
649
                        case TIFF_SHORT:
 
650
                        case TIFF_SSHORT:
 
651
                                TIFFSwabArrayOfShort((uint16*) cp,
 
652
                                    dir->tdir_count);
 
653
                                break;
 
654
                        case TIFF_LONG:
 
655
                        case TIFF_SLONG:
 
656
                        case TIFF_FLOAT:
 
657
                        case TIFF_IFD:
 
658
                                TIFFSwabArrayOfLong((uint32*) cp,
 
659
                                    dir->tdir_count);
 
660
                                break;
 
661
                        case TIFF_RATIONAL:
 
662
                                TIFFSwabArrayOfLong((uint32*) cp,
 
663
                                    2*dir->tdir_count);
 
664
                                break;
 
665
                        case TIFF_DOUBLE:
 
666
                                TIFFSwabArrayOfDouble((double*) cp,
 
667
                                    dir->tdir_count);
 
668
                                break;
 
669
                        }
 
670
                }
 
671
                return (cc);
 
672
        }
 
673
        Error("Error while reading data for tag %u", dir->tdir_tag);
 
674
        return (0);
 
675
}
 
676
 
 
677
static void
 
678
ReadError(char* what)
 
679
{
 
680
        Fatal("Error while reading %s", what);
 
681
}
 
682
 
 
683
#include <stdarg.h>
 
684
 
 
685
static void
 
686
vError(FILE* fd, const char* fmt, va_list ap)
 
687
{
 
688
        fprintf(fd, "%s: ", curfile);
 
689
        vfprintf(fd, fmt, ap);
 
690
        fprintf(fd, ".\n");
 
691
}
 
692
 
 
693
static void
 
694
Error(const char* fmt, ...)
 
695
{
 
696
        va_list ap;
 
697
        va_start(ap, fmt);
 
698
        vError(stderr, fmt, ap);
 
699
        va_end(ap);
 
700
}
 
701
 
 
702
static void
 
703
Fatal(const char* fmt, ...)
 
704
{
 
705
        va_list ap;
 
706
        va_start(ap, fmt);
 
707
        vError(stderr, fmt, ap);
 
708
        va_end(ap);
 
709
        exit(-1);
 
710
}
 
711
 
 
712
/* vim: set ts=8 sts=8 sw=8 noet: */
 
713
/*
 
714
 * Local Variables:
 
715
 * mode: c
 
716
 * c-basic-offset: 8
 
717
 * fill-column: 78
 
718
 * End:
 
719
 */