]>
Commit | Line | Data |
---|---|---|
8414a40c VZ |
1 | /* $Id$ */ |
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 | ||
80ed523f VZ |
49 | #ifdef NEED_LIBPORT |
50 | # include "libport.h" | |
51 | #endif | |
52 | ||
53 | #ifndef HAVE_GETOPT | |
54 | extern int getopt(int, char**, char*); | |
55 | #endif | |
56 | ||
8414a40c VZ |
57 | #include "tiffio.h" |
58 | ||
59 | #ifndef O_BINARY | |
60 | # define O_BINARY 0 | |
61 | #endif | |
62 | ||
80ed523f VZ |
63 | static union |
64 | { | |
65 | TIFFHeaderClassic classic; | |
66 | TIFFHeaderBig big; | |
67 | TIFFHeaderCommon common; | |
68 | } hdr; | |
69 | char* appname; | |
70 | char* curfile; | |
71 | int swabflag; | |
72 | int bigendian; | |
73 | int bigtiff; | |
74 | uint32 maxitems = 24; /* maximum indirect data items to print */ | |
75 | ||
76 | const char* bytefmt = "%s%#02x"; /* BYTE */ | |
77 | const char* sbytefmt = "%s%d"; /* SBYTE */ | |
78 | const char* shortfmt = "%s%u"; /* SHORT */ | |
79 | const char* sshortfmt = "%s%d"; /* SSHORT */ | |
80 | const char* longfmt = "%s%lu"; /* LONG */ | |
81 | const char* slongfmt = "%s%ld"; /* SLONG */ | |
82 | const char* ifdfmt = "%s%#04lx"; /* IFD offset */ | |
83 | #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) | |
84 | const char* long8fmt = "%s%I64u"; /* LONG8 */ | |
85 | const char* slong8fmt = "%s%I64d"; /* SLONG8 */ | |
86 | const char* ifd8fmt = "%s%#08I64x"; /* IFD offset8*/ | |
87 | #else | |
88 | const char* long8fmt = "%s%llu"; /* LONG8 */ | |
89 | const char* slong8fmt = "%s%lld"; /* SLONG8 */ | |
90 | const char* ifd8fmt = "%s%#08llx"; /* IFD offset8*/ | |
91 | #endif | |
92 | const char* rationalfmt = "%s%g"; /* RATIONAL */ | |
93 | const char* srationalfmt = "%s%g"; /* SRATIONAL */ | |
94 | const char* floatfmt = "%s%g"; /* FLOAT */ | |
95 | const char* doublefmt = "%s%g"; /* DOUBLE */ | |
96 | ||
97 | static void dump(int, uint64); | |
98 | extern int optind; | |
99 | extern char* optarg; | |
8414a40c VZ |
100 | |
101 | void | |
102 | usage() | |
103 | { | |
104 | fprintf(stderr, "usage: %s [-h] [-o offset] [-m maxitems] file.tif ...\n", appname); | |
105 | exit(-1); | |
106 | } | |
107 | ||
108 | int | |
109 | main(int argc, char* argv[]) | |
110 | { | |
111 | int one = 1, fd; | |
112 | int multiplefiles = (argc > 1); | |
113 | int c; | |
80ed523f | 114 | uint64 diroff = 0; |
8414a40c VZ |
115 | bigendian = (*(char *)&one == 0); |
116 | ||
117 | appname = argv[0]; | |
118 | while ((c = getopt(argc, argv, "m:o:h")) != -1) { | |
119 | switch (c) { | |
120 | case 'h': /* print values in hex */ | |
121 | shortfmt = "%s%#x"; | |
122 | sshortfmt = "%s%#x"; | |
123 | longfmt = "%s%#lx"; | |
124 | slongfmt = "%s%#lx"; | |
125 | break; | |
126 | case 'o': | |
80ed523f | 127 | diroff = (uint64) strtoul(optarg, NULL, 0); |
8414a40c VZ |
128 | break; |
129 | case 'm': | |
130 | maxitems = strtoul(optarg, NULL, 0); | |
131 | break; | |
132 | default: | |
133 | usage(); | |
134 | } | |
135 | } | |
136 | if (optind >= argc) | |
137 | usage(); | |
138 | for (; optind < argc; optind++) { | |
139 | fd = open(argv[optind], O_RDONLY|O_BINARY, 0); | |
140 | if (fd < 0) { | |
141 | perror(argv[0]); | |
142 | return (-1); | |
143 | } | |
144 | if (multiplefiles) | |
145 | printf("%s:\n", argv[optind]); | |
146 | curfile = argv[optind]; | |
147 | swabflag = 0; | |
80ed523f | 148 | bigtiff = 0; |
8414a40c VZ |
149 | dump(fd, diroff); |
150 | close(fd); | |
151 | } | |
152 | return (0); | |
153 | } | |
154 | ||
80ed523f | 155 | #define ord(e) ((int)e) |
8414a40c | 156 | |
80ed523f VZ |
157 | static uint64 ReadDirectory(int, unsigned, uint64); |
158 | static void ReadError(char*); | |
159 | static void Error(const char*, ...); | |
160 | static void Fatal(const char*, ...); | |
8414a40c VZ |
161 | |
162 | static void | |
80ed523f | 163 | dump(int fd, uint64 diroff) |
8414a40c VZ |
164 | { |
165 | unsigned i; | |
166 | ||
167 | lseek(fd, (off_t) 0, 0); | |
80ed523f | 168 | if (read(fd, (char*) &hdr, sizeof (TIFFHeaderCommon)) != sizeof (TIFFHeaderCommon)) |
8414a40c | 169 | ReadError("TIFF header"); |
80ed523f VZ |
170 | if (hdr.common.tiff_magic != TIFF_BIGENDIAN |
171 | && hdr.common.tiff_magic != TIFF_LITTLEENDIAN && | |
8414a40c | 172 | #if HOST_BIGENDIAN |
80ed523f VZ |
173 | /* MDI is sensitive to the host byte order, unlike TIFF */ |
174 | MDI_BIGENDIAN != hdr.common.tiff_magic | |
8414a40c | 175 | #else |
80ed523f | 176 | MDI_LITTLEENDIAN != hdr.common.tiff_magic |
8414a40c | 177 | #endif |
80ed523f | 178 | ) { |
8414a40c | 179 | Fatal("Not a TIFF or MDI file, bad magic number %u (%#x)", |
80ed523f VZ |
180 | hdr.common.tiff_magic, hdr.common.tiff_magic); |
181 | } | |
182 | if (hdr.common.tiff_magic == TIFF_BIGENDIAN | |
183 | || hdr.common.tiff_magic == MDI_BIGENDIAN) | |
184 | swabflag = !bigendian; | |
185 | else | |
186 | swabflag = bigendian; | |
187 | if (swabflag) | |
188 | TIFFSwabShort(&hdr.common.tiff_version); | |
189 | if (hdr.common.tiff_version==42) | |
190 | { | |
191 | if (read(fd, (char*) &hdr.classic.tiff_diroff, 4) != 4) | |
192 | ReadError("TIFF header"); | |
193 | if (swabflag) | |
194 | TIFFSwabLong(&hdr.classic.tiff_diroff); | |
195 | printf("Magic: %#x <%s-endian> Version: %#x <%s>\n", | |
196 | hdr.classic.tiff_magic, | |
197 | hdr.classic.tiff_magic == TIFF_BIGENDIAN ? "big" : "little", | |
198 | 42,"ClassicTIFF"); | |
199 | if (diroff == 0) | |
200 | diroff = hdr.classic.tiff_diroff; | |
201 | } | |
202 | else if (hdr.common.tiff_version==43) | |
203 | { | |
204 | if (read(fd, (char*) &hdr.big.tiff_offsetsize, 12) != 12) | |
205 | ReadError("TIFF header"); | |
206 | if (swabflag) | |
207 | { | |
208 | TIFFSwabShort(&hdr.big.tiff_offsetsize); | |
209 | TIFFSwabShort(&hdr.big.tiff_unused); | |
210 | TIFFSwabLong8(&hdr.big.tiff_diroff); | |
211 | } | |
212 | printf("Magic: %#x <%s-endian> Version: %#x <%s>\n", | |
213 | hdr.big.tiff_magic, | |
214 | hdr.big.tiff_magic == TIFF_BIGENDIAN ? "big" : "little", | |
215 | 43,"BigTIFF"); | |
216 | printf("OffsetSize: %#x Unused: %#x\n", | |
217 | hdr.big.tiff_offsetsize,hdr.big.tiff_unused); | |
218 | if (diroff == 0) | |
219 | diroff = hdr.big.tiff_diroff; | |
220 | bigtiff = 1; | |
8414a40c | 221 | } |
80ed523f | 222 | else |
8414a40c | 223 | Fatal("Not a TIFF file, bad version number %u (%#x)", |
80ed523f | 224 | hdr.common.tiff_version, hdr.common.tiff_version); |
8414a40c VZ |
225 | for (i = 0; diroff != 0; i++) { |
226 | if (i > 0) | |
227 | putchar('\n'); | |
228 | diroff = ReadDirectory(fd, i, diroff); | |
229 | } | |
230 | } | |
231 | ||
80ed523f VZ |
232 | static const int datawidth[] = { |
233 | 0, /* 00 = undefined */ | |
234 | 1, /* 01 = TIFF_BYTE */ | |
235 | 1, /* 02 = TIFF_ASCII */ | |
236 | 2, /* 03 = TIFF_SHORT */ | |
237 | 4, /* 04 = TIFF_LONG */ | |
238 | 8, /* 05 = TIFF_RATIONAL */ | |
239 | 1, /* 06 = TIFF_SBYTE */ | |
240 | 1, /* 07 = TIFF_UNDEFINED */ | |
241 | 2, /* 08 = TIFF_SSHORT */ | |
242 | 4, /* 09 = TIFF_SLONG */ | |
243 | 8, /* 10 = TIFF_SRATIONAL */ | |
244 | 4, /* 11 = TIFF_FLOAT */ | |
245 | 8, /* 12 = TIFF_DOUBLE */ | |
246 | 4, /* 13 = TIFF_IFD */ | |
247 | 0, /* 14 = undefined */ | |
248 | 0, /* 15 = undefined */ | |
249 | 8, /* 16 = TIFF_LONG8 */ | |
250 | 8, /* 17 = TIFF_SLONG8 */ | |
251 | 8, /* 18 = TIFF_IFD8 */ | |
8414a40c | 252 | }; |
80ed523f VZ |
253 | #define NWIDTHS (sizeof (datawidth) / sizeof (datawidth[0])) |
254 | static void PrintTag(FILE*, uint16); | |
255 | static void PrintType(FILE*, uint16); | |
256 | static void PrintData(FILE*, uint16, uint32, unsigned char*); | |
8414a40c VZ |
257 | |
258 | /* | |
259 | * Read the next TIFF directory from a file | |
260 | * and convert it to the internal format. | |
261 | * We read directories sequentially. | |
262 | */ | |
80ed523f VZ |
263 | static uint64 |
264 | ReadDirectory(int fd, unsigned int ix, uint64 off) | |
8414a40c | 265 | { |
8414a40c | 266 | uint16 dircount; |
80ed523f VZ |
267 | uint32 direntrysize; |
268 | void* dirmem = NULL; | |
269 | uint64 nextdiroff = 0; | |
270 | uint32 n; | |
271 | uint8* dp; | |
8414a40c VZ |
272 | |
273 | if (off == 0) /* no more directories */ | |
274 | goto done; | |
80ed523f VZ |
275 | #if defined(__WIN32__) && defined(_MSC_VER) |
276 | if (_lseeki64(fd, (__int64)off, SEEK_SET) != (__int64)off) { | |
277 | #else | |
278 | if (lseek(fd, (off_t)off, SEEK_SET) != (off_t)off) { | |
279 | #endif | |
8414a40c VZ |
280 | Fatal("Seek error accessing TIFF directory"); |
281 | goto done; | |
282 | } | |
80ed523f VZ |
283 | if (!bigtiff) { |
284 | if (read(fd, (char*) &dircount, sizeof (uint16)) != sizeof (uint16)) { | |
285 | ReadError("directory count"); | |
286 | goto done; | |
287 | } | |
288 | if (swabflag) | |
289 | TIFFSwabShort(&dircount); | |
290 | direntrysize = 12; | |
291 | } else { | |
292 | uint64 dircount64 = 0; | |
293 | if (read(fd, (char*) &dircount64, sizeof (uint64)) != sizeof (uint64)) { | |
294 | ReadError("directory count"); | |
295 | goto done; | |
296 | } | |
297 | if (swabflag) | |
298 | TIFFSwabLong8(&dircount64); | |
299 | if (dircount64>0xFFFF) { | |
300 | Error("Sanity check on directory count failed"); | |
301 | goto done; | |
302 | } | |
303 | dircount = (uint16)dircount64; | |
304 | direntrysize = 20; | |
8414a40c | 305 | } |
80ed523f VZ |
306 | dirmem = _TIFFmalloc(dircount * direntrysize); |
307 | if (dirmem == NULL) { | |
8414a40c VZ |
308 | Fatal("No space for TIFF directory"); |
309 | goto done; | |
310 | } | |
80ed523f VZ |
311 | n = read(fd, (char*) dirmem, dircount*direntrysize); |
312 | if (n != dircount*direntrysize) { | |
313 | n /= direntrysize; | |
8414a40c | 314 | Error( |
80ed523f VZ |
315 | #if defined(__WIN32__) && defined(_MSC_VER) |
316 | "Could only read %lu of %u entries in directory at offset %#I64x", | |
317 | (unsigned long)n, dircount, (unsigned __int64) off); | |
318 | #else | |
319 | "Could only read %lu of %u entries in directory at offset %#llx", | |
320 | (unsigned long)n, dircount, (unsigned long long) off); | |
321 | #endif | |
8414a40c | 322 | dircount = n; |
8414a40c | 323 | nextdiroff = 0; |
80ed523f VZ |
324 | } else { |
325 | if (!bigtiff) { | |
326 | uint32 nextdiroff32; | |
327 | if (read(fd, (char*) &nextdiroff32, sizeof (uint32)) != sizeof (uint32)) | |
328 | nextdiroff32 = 0; | |
329 | if (swabflag) | |
330 | TIFFSwabLong(&nextdiroff32); | |
331 | nextdiroff = nextdiroff32; | |
332 | } else { | |
333 | if (read(fd, (char*) &nextdiroff, sizeof (uint64)) != sizeof (uint64)) | |
334 | nextdiroff = 0; | |
335 | if (swabflag) | |
336 | TIFFSwabLong8(&nextdiroff); | |
8414a40c | 337 | } |
80ed523f VZ |
338 | } |
339 | #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) | |
340 | printf("Directory %u: offset %I64u (%#I64x) next %I64u (%#I64x)\n", ix, | |
341 | (unsigned __int64)off, (unsigned __int64)off, | |
342 | (unsigned __int64)nextdiroff, (unsigned __int64)nextdiroff); | |
343 | #else | |
344 | printf("Directory %u: offset %llu (%#llx) next %llu (%#llx)\n", ix, | |
345 | (unsigned long long)off, (unsigned long long)off, | |
346 | (unsigned long long)nextdiroff, (unsigned long long)nextdiroff); | |
347 | #endif | |
348 | for (dp = (uint8*)dirmem, n = dircount; n > 0; n--) { | |
349 | uint16 tag; | |
350 | uint16 type; | |
351 | uint16 typewidth; | |
352 | uint64 count; | |
353 | uint64 datasize; | |
354 | int datafits; | |
355 | void* datamem; | |
356 | uint64 dataoffset; | |
357 | int datatruncated; | |
358 | tag = *(uint16*)dp; | |
359 | if (swabflag) | |
360 | TIFFSwabShort(&tag); | |
361 | dp += sizeof(uint16); | |
362 | type = *(uint16*)dp; | |
363 | dp += sizeof(uint16); | |
364 | if (swabflag) | |
365 | TIFFSwabShort(&type); | |
366 | PrintTag(stdout, tag); | |
8414a40c | 367 | putchar(' '); |
80ed523f | 368 | PrintType(stdout, type); |
8414a40c | 369 | putchar(' '); |
80ed523f VZ |
370 | if (!bigtiff) |
371 | { | |
372 | uint32 count32; | |
373 | count32 = *(uint32*)dp; | |
374 | if (swabflag) | |
375 | TIFFSwabLong(&count32); | |
376 | dp += sizeof(uint32); | |
377 | count = count32; | |
8414a40c | 378 | } |
80ed523f VZ |
379 | else |
380 | { | |
381 | count = *(uint64*)dp; | |
382 | if (swabflag) | |
383 | TIFFSwabLong8(&count); | |
384 | dp += sizeof(uint64); | |
385 | } | |
386 | #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) | |
387 | printf("%I64u<", (unsigned __int64)count); | |
388 | #else | |
389 | printf("%llu<", (unsigned long long)count); | |
390 | #endif | |
391 | if (type >= NWIDTHS) | |
392 | typewidth = 0; | |
393 | else | |
394 | typewidth = datawidth[type]; | |
395 | datasize = count*typewidth; | |
396 | datafits = 1; | |
397 | datamem = dp; | |
398 | dataoffset = 0; | |
399 | datatruncated = 0; | |
400 | if (!bigtiff) | |
401 | { | |
402 | if (datasize>4) | |
403 | { | |
404 | uint32 dataoffset32; | |
405 | datafits = 0; | |
406 | datamem = NULL; | |
407 | dataoffset32 = *(uint32*)dp; | |
8414a40c | 408 | if (swabflag) |
80ed523f VZ |
409 | TIFFSwabLong(&dataoffset32); |
410 | dataoffset = dataoffset32; | |
8414a40c | 411 | } |
80ed523f VZ |
412 | dp += sizeof(uint32); |
413 | } | |
414 | else | |
415 | { | |
416 | if (datasize>8) | |
417 | { | |
418 | datafits = 0; | |
419 | datamem = NULL; | |
420 | dataoffset = *(uint64*)dp; | |
421 | if (swabflag) | |
422 | TIFFSwabLong8(&dataoffset); | |
8414a40c | 423 | } |
80ed523f VZ |
424 | dp += sizeof(uint64); |
425 | } | |
426 | if (datasize>0x10000) | |
427 | { | |
428 | datatruncated = 1; | |
429 | count = 0x10000/typewidth; | |
430 | datasize = count*typewidth; | |
431 | } | |
432 | if (count>maxitems) | |
433 | { | |
434 | datatruncated = 1; | |
435 | count = maxitems; | |
436 | datasize = count*typewidth; | |
437 | } | |
438 | if (!datafits) | |
439 | { | |
440 | datamem = _TIFFmalloc((uint32)datasize); | |
441 | if (datamem) { | |
442 | #if defined(__WIN32__) && defined(_MSC_VER) | |
443 | if (_lseeki64(fd, (__int64)dataoffset, SEEK_SET) | |
444 | != (__int64)dataoffset) | |
445 | #else | |
446 | if (lseek(fd, (off_t)dataoffset, 0) != | |
447 | (off_t)dataoffset) | |
448 | #endif | |
449 | { | |
450 | Error( | |
451 | "Seek error accessing tag %u value", tag); | |
452 | _TIFFfree(datamem); | |
453 | datamem = NULL; | |
454 | } | |
455 | if (read(fd, datamem, (size_t)datasize) != (TIFF_SSIZE_T)datasize) | |
456 | { | |
457 | Error( | |
458 | "Read error accessing tag %u value", tag); | |
459 | _TIFFfree(datamem); | |
460 | datamem = NULL; | |
461 | } | |
8414a40c | 462 | } else |
80ed523f VZ |
463 | Error("No space for data for tag %u",tag); |
464 | } | |
465 | if (datamem) | |
466 | { | |
467 | if (swabflag) | |
468 | { | |
469 | switch (type) | |
470 | { | |
471 | case TIFF_BYTE: | |
472 | case TIFF_ASCII: | |
473 | case TIFF_SBYTE: | |
474 | case TIFF_UNDEFINED: | |
475 | break; | |
476 | case TIFF_SHORT: | |
477 | case TIFF_SSHORT: | |
478 | TIFFSwabArrayOfShort((uint16*)datamem,(tmsize_t)count); | |
479 | break; | |
480 | case TIFF_LONG: | |
481 | case TIFF_SLONG: | |
482 | case TIFF_FLOAT: | |
483 | case TIFF_IFD: | |
484 | TIFFSwabArrayOfLong((uint32*)datamem,(tmsize_t)count); | |
485 | break; | |
486 | case TIFF_RATIONAL: | |
487 | case TIFF_SRATIONAL: | |
488 | TIFFSwabArrayOfLong((uint32*)datamem,(tmsize_t)count*2); | |
489 | break; | |
490 | case TIFF_DOUBLE: | |
491 | case TIFF_LONG8: | |
492 | case TIFF_SLONG8: | |
493 | case TIFF_IFD8: | |
494 | TIFFSwabArrayOfLong8((uint64*)datamem,(tmsize_t)count); | |
495 | break; | |
496 | } | |
497 | } | |
498 | PrintData(stdout,type,(uint32)count,datamem); | |
499 | if (datatruncated) | |
500 | printf(" ..."); | |
501 | if (!datafits) | |
502 | _TIFFfree(datamem); | |
8414a40c VZ |
503 | } |
504 | printf(">\n"); | |
505 | } | |
506 | done: | |
80ed523f VZ |
507 | if (dirmem) |
508 | _TIFFfree((char *)dirmem); | |
8414a40c VZ |
509 | return (nextdiroff); |
510 | } | |
511 | ||
80ed523f VZ |
512 | static const struct tagname { |
513 | uint16 tag; | |
514 | const char* name; | |
8414a40c VZ |
515 | } tagnames[] = { |
516 | { TIFFTAG_SUBFILETYPE, "SubFileType" }, | |
517 | { TIFFTAG_OSUBFILETYPE, "OldSubFileType" }, | |
518 | { TIFFTAG_IMAGEWIDTH, "ImageWidth" }, | |
519 | { TIFFTAG_IMAGELENGTH, "ImageLength" }, | |
520 | { TIFFTAG_BITSPERSAMPLE, "BitsPerSample" }, | |
521 | { TIFFTAG_COMPRESSION, "Compression" }, | |
522 | { TIFFTAG_PHOTOMETRIC, "Photometric" }, | |
523 | { TIFFTAG_THRESHHOLDING, "Threshholding" }, | |
524 | { TIFFTAG_CELLWIDTH, "CellWidth" }, | |
525 | { TIFFTAG_CELLLENGTH, "CellLength" }, | |
526 | { TIFFTAG_FILLORDER, "FillOrder" }, | |
527 | { TIFFTAG_DOCUMENTNAME, "DocumentName" }, | |
528 | { TIFFTAG_IMAGEDESCRIPTION, "ImageDescription" }, | |
529 | { TIFFTAG_MAKE, "Make" }, | |
530 | { TIFFTAG_MODEL, "Model" }, | |
531 | { TIFFTAG_STRIPOFFSETS, "StripOffsets" }, | |
532 | { TIFFTAG_ORIENTATION, "Orientation" }, | |
533 | { TIFFTAG_SAMPLESPERPIXEL, "SamplesPerPixel" }, | |
534 | { TIFFTAG_ROWSPERSTRIP, "RowsPerStrip" }, | |
535 | { TIFFTAG_STRIPBYTECOUNTS, "StripByteCounts" }, | |
536 | { TIFFTAG_MINSAMPLEVALUE, "MinSampleValue" }, | |
537 | { TIFFTAG_MAXSAMPLEVALUE, "MaxSampleValue" }, | |
538 | { TIFFTAG_XRESOLUTION, "XResolution" }, | |
539 | { TIFFTAG_YRESOLUTION, "YResolution" }, | |
540 | { TIFFTAG_PLANARCONFIG, "PlanarConfig" }, | |
541 | { TIFFTAG_PAGENAME, "PageName" }, | |
542 | { TIFFTAG_XPOSITION, "XPosition" }, | |
543 | { TIFFTAG_YPOSITION, "YPosition" }, | |
544 | { TIFFTAG_FREEOFFSETS, "FreeOffsets" }, | |
545 | { TIFFTAG_FREEBYTECOUNTS, "FreeByteCounts" }, | |
546 | { TIFFTAG_GRAYRESPONSEUNIT, "GrayResponseUnit" }, | |
547 | { TIFFTAG_GRAYRESPONSECURVE,"GrayResponseCurve" }, | |
548 | { TIFFTAG_GROUP3OPTIONS, "Group3Options" }, | |
549 | { TIFFTAG_GROUP4OPTIONS, "Group4Options" }, | |
550 | { TIFFTAG_RESOLUTIONUNIT, "ResolutionUnit" }, | |
551 | { TIFFTAG_PAGENUMBER, "PageNumber" }, | |
552 | { TIFFTAG_COLORRESPONSEUNIT,"ColorResponseUnit" }, | |
553 | { TIFFTAG_TRANSFERFUNCTION, "TransferFunction" }, | |
554 | { TIFFTAG_SOFTWARE, "Software" }, | |
555 | { TIFFTAG_DATETIME, "DateTime" }, | |
556 | { TIFFTAG_ARTIST, "Artist" }, | |
557 | { TIFFTAG_HOSTCOMPUTER, "HostComputer" }, | |
558 | { TIFFTAG_PREDICTOR, "Predictor" }, | |
559 | { TIFFTAG_WHITEPOINT, "Whitepoint" }, | |
560 | { TIFFTAG_PRIMARYCHROMATICITIES,"PrimaryChromaticities" }, | |
561 | { TIFFTAG_COLORMAP, "Colormap" }, | |
562 | { TIFFTAG_HALFTONEHINTS, "HalftoneHints" }, | |
563 | { TIFFTAG_TILEWIDTH, "TileWidth" }, | |
564 | { TIFFTAG_TILELENGTH, "TileLength" }, | |
565 | { TIFFTAG_TILEOFFSETS, "TileOffsets" }, | |
566 | { TIFFTAG_TILEBYTECOUNTS, "TileByteCounts" }, | |
567 | { TIFFTAG_BADFAXLINES, "BadFaxLines" }, | |
568 | { TIFFTAG_CLEANFAXDATA, "CleanFaxData" }, | |
569 | { TIFFTAG_CONSECUTIVEBADFAXLINES, "ConsecutiveBadFaxLines" }, | |
570 | { TIFFTAG_SUBIFD, "SubIFD" }, | |
571 | { TIFFTAG_INKSET, "InkSet" }, | |
572 | { TIFFTAG_INKNAMES, "InkNames" }, | |
573 | { TIFFTAG_NUMBEROFINKS, "NumberOfInks" }, | |
574 | { TIFFTAG_DOTRANGE, "DotRange" }, | |
575 | { TIFFTAG_TARGETPRINTER, "TargetPrinter" }, | |
576 | { TIFFTAG_EXTRASAMPLES, "ExtraSamples" }, | |
577 | { TIFFTAG_SAMPLEFORMAT, "SampleFormat" }, | |
578 | { TIFFTAG_SMINSAMPLEVALUE, "SMinSampleValue" }, | |
579 | { TIFFTAG_SMAXSAMPLEVALUE, "SMaxSampleValue" }, | |
580 | { TIFFTAG_JPEGPROC, "JPEGProcessingMode" }, | |
581 | { TIFFTAG_JPEGIFOFFSET, "JPEGInterchangeFormat" }, | |
582 | { TIFFTAG_JPEGIFBYTECOUNT, "JPEGInterchangeFormatLength" }, | |
583 | { TIFFTAG_JPEGRESTARTINTERVAL,"JPEGRestartInterval" }, | |
584 | { TIFFTAG_JPEGLOSSLESSPREDICTORS,"JPEGLosslessPredictors" }, | |
585 | { TIFFTAG_JPEGPOINTTRANSFORM,"JPEGPointTransform" }, | |
586 | { TIFFTAG_JPEGTABLES, "JPEGTables" }, | |
587 | { TIFFTAG_JPEGQTABLES, "JPEGQTables" }, | |
588 | { TIFFTAG_JPEGDCTABLES, "JPEGDCTables" }, | |
589 | { TIFFTAG_JPEGACTABLES, "JPEGACTables" }, | |
590 | { TIFFTAG_YCBCRCOEFFICIENTS,"YCbCrCoefficients" }, | |
591 | { TIFFTAG_YCBCRSUBSAMPLING, "YCbCrSubsampling" }, | |
592 | { TIFFTAG_YCBCRPOSITIONING, "YCbCrPositioning" }, | |
593 | { TIFFTAG_REFERENCEBLACKWHITE, "ReferenceBlackWhite" }, | |
594 | { TIFFTAG_REFPTS, "IgReferencePoints (Island Graphics)" }, | |
595 | { TIFFTAG_REGIONTACKPOINT, "IgRegionTackPoint (Island Graphics)" }, | |
596 | { TIFFTAG_REGIONWARPCORNERS,"IgRegionWarpCorners (Island Graphics)" }, | |
597 | { TIFFTAG_REGIONAFFINE, "IgRegionAffine (Island Graphics)" }, | |
598 | { TIFFTAG_MATTEING, "OBSOLETE Matteing (Silicon Graphics)" }, | |
599 | { TIFFTAG_DATATYPE, "OBSOLETE DataType (Silicon Graphics)" }, | |
600 | { TIFFTAG_IMAGEDEPTH, "ImageDepth (Silicon Graphics)" }, | |
601 | { TIFFTAG_TILEDEPTH, "TileDepth (Silicon Graphics)" }, | |
602 | { 32768, "OLD BOGUS Matteing tag" }, | |
603 | { TIFFTAG_COPYRIGHT, "Copyright" }, | |
604 | { TIFFTAG_ICCPROFILE, "ICC Profile" }, | |
605 | { TIFFTAG_JBIGOPTIONS, "JBIG Options" }, | |
606 | { TIFFTAG_STONITS, "StoNits" }, | |
607 | }; | |
608 | #define NTAGS (sizeof (tagnames) / sizeof (tagnames[0])) | |
609 | ||
610 | static void | |
611 | PrintTag(FILE* fd, uint16 tag) | |
612 | { | |
80ed523f | 613 | const struct tagname *tp; |
8414a40c VZ |
614 | |
615 | for (tp = tagnames; tp < &tagnames[NTAGS]; tp++) | |
616 | if (tp->tag == tag) { | |
617 | fprintf(fd, "%s (%u)", tp->name, tag); | |
618 | return; | |
619 | } | |
620 | fprintf(fd, "%u (%#x)", tag, tag); | |
621 | } | |
622 | ||
623 | static void | |
624 | PrintType(FILE* fd, uint16 type) | |
625 | { | |
80ed523f | 626 | static const char *typenames[] = { |
8414a40c VZ |
627 | "0", |
628 | "BYTE", | |
629 | "ASCII", | |
630 | "SHORT", | |
631 | "LONG", | |
632 | "RATIONAL", | |
633 | "SBYTE", | |
634 | "UNDEFINED", | |
635 | "SSHORT", | |
636 | "SLONG", | |
637 | "SRATIONAL", | |
638 | "FLOAT", | |
80ed523f VZ |
639 | "DOUBLE", |
640 | "IFD", | |
641 | "14", | |
642 | "15", | |
643 | "LONG8", | |
644 | "SLONG8", | |
645 | "IFD8" | |
8414a40c VZ |
646 | }; |
647 | #define NTYPES (sizeof (typenames) / sizeof (typenames[0])) | |
648 | ||
649 | if (type < NTYPES) | |
650 | fprintf(fd, "%s (%u)", typenames[type], type); | |
651 | else | |
652 | fprintf(fd, "%u (%#x)", type, type); | |
653 | } | |
654 | #undef NTYPES | |
655 | ||
8414a40c VZ |
656 | #include <ctype.h> |
657 | ||
658 | static void | |
659 | PrintASCII(FILE* fd, uint32 cc, const unsigned char* cp) | |
660 | { | |
661 | for (; cc > 0; cc--, cp++) { | |
662 | const char* tp; | |
663 | ||
664 | if (isprint(*cp)) { | |
665 | fputc(*cp, fd); | |
666 | continue; | |
667 | } | |
668 | for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++) | |
669 | if (*tp++ == *cp) | |
670 | break; | |
671 | if (*tp) | |
672 | fprintf(fd, "\\%c", *tp); | |
673 | else if (*cp) | |
674 | fprintf(fd, "\\%03o", *cp); | |
675 | else | |
676 | fprintf(fd, "\\0"); | |
677 | } | |
678 | } | |
679 | ||
680 | static void | |
681 | PrintData(FILE* fd, uint16 type, uint32 count, unsigned char* data) | |
682 | { | |
683 | char* sep = ""; | |
684 | ||
685 | switch (type) { | |
686 | case TIFF_BYTE: | |
687 | while (count-- > 0) | |
688 | fprintf(fd, bytefmt, sep, *data++), sep = " "; | |
689 | break; | |
690 | case TIFF_SBYTE: | |
691 | while (count-- > 0) | |
692 | fprintf(fd, sbytefmt, sep, *(char *)data++), sep = " "; | |
693 | break; | |
694 | case TIFF_UNDEFINED: | |
695 | while (count-- > 0) | |
696 | fprintf(fd, bytefmt, sep, *data++), sep = " "; | |
697 | break; | |
698 | case TIFF_ASCII: | |
699 | PrintASCII(fd, count, data); | |
700 | break; | |
701 | case TIFF_SHORT: { | |
702 | uint16 *wp = (uint16*)data; | |
703 | while (count-- > 0) | |
704 | fprintf(fd, shortfmt, sep, *wp++), sep = " "; | |
705 | break; | |
706 | } | |
707 | case TIFF_SSHORT: { | |
708 | int16 *wp = (int16*)data; | |
709 | while (count-- > 0) | |
710 | fprintf(fd, sshortfmt, sep, *wp++), sep = " "; | |
711 | break; | |
712 | } | |
713 | case TIFF_LONG: { | |
714 | uint32 *lp = (uint32*)data; | |
715 | while (count-- > 0) { | |
716 | fprintf(fd, longfmt, sep, (unsigned long) *lp++); | |
717 | sep = " "; | |
718 | } | |
719 | break; | |
720 | } | |
721 | case TIFF_SLONG: { | |
722 | int32 *lp = (int32*)data; | |
723 | while (count-- > 0) | |
724 | fprintf(fd, slongfmt, sep, (long) *lp++), sep = " "; | |
725 | break; | |
726 | } | |
80ed523f VZ |
727 | case TIFF_LONG8: { |
728 | uint64 *llp = (uint64*)data; | |
729 | while (count-- > 0) { | |
730 | #if defined(__WIN32__) && defined(_MSC_VER) | |
731 | fprintf(fd, long8fmt, sep, (unsigned __int64) *llp++); | |
732 | #else | |
733 | fprintf(fd, long8fmt, sep, (unsigned long long) *llp++); | |
734 | #endif | |
735 | sep = " "; | |
736 | } | |
737 | break; | |
738 | } | |
739 | case TIFF_SLONG8: { | |
740 | int64 *llp = (int64*)data; | |
741 | while (count-- > 0) | |
742 | #if defined(__WIN32__) && defined(_MSC_VER) | |
743 | fprintf(fd, slong8fmt, sep, (__int64) *llp++), sep = " "; | |
744 | #else | |
745 | fprintf(fd, slong8fmt, sep, (long long) *llp++), sep = " "; | |
746 | #endif | |
747 | break; | |
748 | } | |
8414a40c VZ |
749 | case TIFF_RATIONAL: { |
750 | uint32 *lp = (uint32*)data; | |
751 | while (count-- > 0) { | |
752 | if (lp[1] == 0) | |
753 | fprintf(fd, "%sNan (%lu/%lu)", sep, | |
754 | (unsigned long) lp[0], | |
755 | (unsigned long) lp[1]); | |
756 | else | |
757 | fprintf(fd, rationalfmt, sep, | |
758 | (double)lp[0] / (double)lp[1]); | |
759 | sep = " "; | |
760 | lp += 2; | |
761 | } | |
762 | break; | |
763 | } | |
764 | case TIFF_SRATIONAL: { | |
765 | int32 *lp = (int32*)data; | |
766 | while (count-- > 0) { | |
767 | if (lp[1] == 0) | |
768 | fprintf(fd, "%sNan (%ld/%ld)", sep, | |
769 | (long) lp[0], (long) lp[1]); | |
770 | else | |
771 | fprintf(fd, srationalfmt, sep, | |
772 | (double)lp[0] / (double)lp[1]); | |
773 | sep = " "; | |
774 | lp += 2; | |
775 | } | |
776 | break; | |
777 | } | |
778 | case TIFF_FLOAT: { | |
779 | float *fp = (float *)data; | |
780 | while (count-- > 0) | |
781 | fprintf(fd, floatfmt, sep, *fp++), sep = " "; | |
782 | break; | |
783 | } | |
784 | case TIFF_DOUBLE: { | |
785 | double *dp = (double *)data; | |
786 | while (count-- > 0) | |
787 | fprintf(fd, doublefmt, sep, *dp++), sep = " "; | |
788 | break; | |
789 | } | |
790 | case TIFF_IFD: { | |
791 | uint32 *lp = (uint32*)data; | |
792 | while (count-- > 0) { | |
793 | fprintf(fd, ifdfmt, sep, (unsigned long) *lp++); | |
794 | sep = " "; | |
795 | } | |
796 | break; | |
797 | } | |
80ed523f VZ |
798 | case TIFF_IFD8: { |
799 | uint64 *llp = (uint64*)data; | |
800 | while (count-- > 0) { | |
801 | #if defined(__WIN32__) && defined(_MSC_VER) | |
802 | fprintf(fd, ifd8fmt, sep, (unsigned __int64) *llp++); | |
803 | #else | |
804 | fprintf(fd, ifd8fmt, sep, (unsigned long long) *llp++); | |
805 | #endif | |
806 | sep = " "; | |
8414a40c | 807 | } |
80ed523f VZ |
808 | break; |
809 | } | |
8414a40c | 810 | } |
8414a40c VZ |
811 | } |
812 | ||
813 | static void | |
814 | ReadError(char* what) | |
815 | { | |
816 | Fatal("Error while reading %s", what); | |
817 | } | |
818 | ||
819 | #include <stdarg.h> | |
820 | ||
821 | static void | |
822 | vError(FILE* fd, const char* fmt, va_list ap) | |
823 | { | |
824 | fprintf(fd, "%s: ", curfile); | |
825 | vfprintf(fd, fmt, ap); | |
826 | fprintf(fd, ".\n"); | |
827 | } | |
828 | ||
829 | static void | |
830 | Error(const char* fmt, ...) | |
831 | { | |
832 | va_list ap; | |
833 | va_start(ap, fmt); | |
834 | vError(stderr, fmt, ap); | |
835 | va_end(ap); | |
836 | } | |
837 | ||
838 | static void | |
839 | Fatal(const char* fmt, ...) | |
840 | { | |
841 | va_list ap; | |
842 | va_start(ap, fmt); | |
843 | vError(stderr, fmt, ap); | |
844 | va_end(ap); | |
845 | exit(-1); | |
846 | } | |
847 | ||
848 | /* vim: set ts=8 sts=8 sw=8 noet: */ | |
80ed523f VZ |
849 | /* |
850 | * Local Variables: | |
851 | * mode: c | |
852 | * c-basic-offset: 8 | |
853 | * fill-column: 78 | |
854 | * End: | |
855 | */ |