]> git.saurik.com Git - wxWidgets.git/blob - src/tiff/tools/tiffinfo.c
Fix crash in wxDC::GetMultiLineTextExtent() after last commit.
[wxWidgets.git] / src / tiff / tools / tiffinfo.c
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_STRINGS_H
34 # include <strings.h>
35 #endif
36
37 #ifdef HAVE_UNISTD_H
38 # include <unistd.h>
39 #endif
40
41 #include "tiffio.h"
42
43 #define streq(a,b) (strcasecmp(a,b) == 0)
44
45 int showdata = 0; /* show data */
46 int rawdata = 0; /* show raw/decoded data */
47 int showwords = 0; /* show data as bytes/words */
48 int readdata = 0; /* read data in file */
49 int stoponerr = 1; /* stop on first read error */
50
51 static void usage(void);
52 static void tiffinfo(TIFF*, uint16, long);
53
54 int
55 main(int argc, char* argv[])
56 {
57 int dirnum = -1, multiplefiles, c;
58 uint16 order = 0;
59 TIFF* tif;
60 extern int optind;
61 extern char* optarg;
62 long flags = 0;
63 uint32 diroff = 0;
64 int chopstrips = 0; /* disable strip chopping */
65
66 while ((c = getopt(argc, argv, "f:o:cdDSjilmrsvwz0123456789")) != -1)
67 switch (c) {
68 case '0': case '1': case '2': case '3':
69 case '4': case '5': case '6': case '7':
70 case '8': case '9':
71 dirnum = atoi(&argv[optind-1][1]);
72 break;
73 case 'd':
74 showdata++;
75 /* fall thru... */
76 case 'D':
77 readdata++;
78 break;
79 case 'c':
80 flags |= TIFFPRINT_COLORMAP | TIFFPRINT_CURVES;
81 break;
82 case 'f': /* fill order */
83 if (streq(optarg, "lsb2msb"))
84 order = FILLORDER_LSB2MSB;
85 else if (streq(optarg, "msb2lsb"))
86 order = FILLORDER_MSB2LSB;
87 else
88 usage();
89 break;
90 case 'i':
91 stoponerr = 0;
92 break;
93 case 'o':
94 diroff = strtoul(optarg, NULL, 0);
95 break;
96 case 'j':
97 flags |= TIFFPRINT_JPEGQTABLES |
98 TIFFPRINT_JPEGACTABLES |
99 TIFFPRINT_JPEGDCTABLES;
100 break;
101 case 'r':
102 rawdata = 1;
103 break;
104 case 's':
105 flags |= TIFFPRINT_STRIPS;
106 break;
107 case 'w':
108 showwords = 1;
109 break;
110 case 'z':
111 chopstrips = 1;
112 break;
113 case '?':
114 usage();
115 /*NOTREACHED*/
116 }
117 if (optind >= argc)
118 usage();
119 multiplefiles = (argc - optind > 1);
120 for (; optind < argc; optind++) {
121 if (multiplefiles)
122 printf("%s:\n", argv[optind]);
123 tif = TIFFOpen(argv[optind], chopstrips ? "rC" : "rc");
124 if (tif != NULL) {
125 if (dirnum != -1) {
126 if (TIFFSetDirectory(tif, (tdir_t) dirnum))
127 tiffinfo(tif, order, flags);
128 } else if (diroff != 0) {
129 if (TIFFSetSubDirectory(tif, diroff))
130 tiffinfo(tif, order, flags);
131 } else {
132 do {
133 uint32 offset;
134
135 tiffinfo(tif, order, flags);
136 if (TIFFGetField(tif, TIFFTAG_EXIFIFD,
137 &offset)) {
138 if (TIFFReadEXIFDirectory(tif, offset))
139 tiffinfo(tif, order, flags);
140 }
141 } while (TIFFReadDirectory(tif));
142 }
143 TIFFClose(tif);
144 }
145 }
146 return (0);
147 }
148
149 char* stuff[] = {
150 "usage: tiffinfo [options] input...",
151 "where options are:",
152 " -D read data",
153 " -i ignore read errors",
154 " -c display data for grey/color response curve or colormap",
155 " -d display raw/decoded image data",
156 " -f lsb2msb force lsb-to-msb FillOrder for input",
157 " -f msb2lsb force msb-to-lsb FillOrder for input",
158 " -j show JPEG tables",
159 " -o offset set initial directory offset",
160 " -r read/display raw image data instead of decoded data",
161 " -s display strip offsets and byte counts",
162 " -w display raw data in words rather than bytes",
163 " -z enable strip chopping",
164 " -# set initial directory (first directory is # 0)",
165 NULL
166 };
167
168 static void
169 usage(void)
170 {
171 char buf[BUFSIZ];
172 int i;
173
174 setbuf(stderr, buf);
175 fprintf(stderr, "%s\n\n", TIFFGetVersion());
176 for (i = 0; stuff[i] != NULL; i++)
177 fprintf(stderr, "%s\n", stuff[i]);
178 exit(-1);
179 }
180
181 static void
182 ShowStrip(tstrip_t strip, unsigned char* pp, uint32 nrow, tsize_t scanline)
183 {
184 register tsize_t cc;
185
186 printf("Strip %lu:\n", (unsigned long) strip);
187 while (nrow-- > 0) {
188 for (cc = 0; cc < scanline; cc++) {
189 printf(" %02x", *pp++);
190 if (((cc+1) % 24) == 0)
191 putchar('\n');
192 }
193 putchar('\n');
194 }
195 }
196
197 void
198 TIFFReadContigStripData(TIFF* tif)
199 {
200 unsigned char *buf;
201 tsize_t scanline = TIFFScanlineSize(tif);
202
203 buf = (unsigned char *)_TIFFmalloc(TIFFStripSize(tif));
204 if (buf) {
205 uint32 row, h;
206 uint32 rowsperstrip = (uint32)-1;
207
208 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
209 TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
210 for (row = 0; row < h; row += rowsperstrip) {
211 uint32 nrow = (row+rowsperstrip > h ?
212 h-row : rowsperstrip);
213 tstrip_t strip = TIFFComputeStrip(tif, row, 0);
214 if (TIFFReadEncodedStrip(tif, strip, buf, nrow*scanline) < 0) {
215 if (stoponerr)
216 break;
217 } else if (showdata)
218 ShowStrip(strip, buf, nrow, scanline);
219 }
220 _TIFFfree(buf);
221 }
222 }
223
224 void
225 TIFFReadSeparateStripData(TIFF* tif)
226 {
227 unsigned char *buf;
228 tsize_t scanline = TIFFScanlineSize(tif);
229
230 buf = (unsigned char *)_TIFFmalloc(TIFFStripSize(tif));
231 if (buf) {
232 uint32 row, h;
233 uint32 rowsperstrip = (uint32)-1;
234 tsample_t s, samplesperpixel;
235
236 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
237 TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
238 TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
239 for (row = 0; row < h; row += rowsperstrip) {
240 for (s = 0; s < samplesperpixel; s++) {
241 uint32 nrow = (row+rowsperstrip > h ?
242 h-row : rowsperstrip);
243 tstrip_t strip = TIFFComputeStrip(tif, row, s);
244 if (TIFFReadEncodedStrip(tif, strip, buf, nrow*scanline) < 0) {
245 if (stoponerr)
246 break;
247 } else if (showdata)
248 ShowStrip(strip, buf, nrow, scanline);
249 }
250 }
251 _TIFFfree(buf);
252 }
253 }
254
255 static void
256 ShowTile(uint32 row, uint32 col, tsample_t sample,
257 unsigned char* pp, uint32 nrow, uint32 rowsize)
258 {
259 uint32 cc;
260
261 printf("Tile (%lu,%lu", (unsigned long) row, (unsigned long) col);
262 if (sample != (tsample_t) -1)
263 printf(",%u", sample);
264 printf("):\n");
265 while (nrow-- > 0) {
266 for (cc = 0; cc < rowsize; cc++) {
267 printf(" %02x", *pp++);
268 if (((cc+1) % 24) == 0)
269 putchar('\n');
270 }
271 putchar('\n');
272 }
273 }
274
275 void
276 TIFFReadContigTileData(TIFF* tif)
277 {
278 unsigned char *buf;
279 tsize_t rowsize = TIFFTileRowSize(tif);
280
281 buf = (unsigned char *)_TIFFmalloc(TIFFTileSize(tif));
282 if (buf) {
283 uint32 tw, th, w, h;
284 uint32 row, col;
285
286 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
287 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
288 TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
289 TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
290 for (row = 0; row < h; row += th) {
291 for (col = 0; col < w; col += tw) {
292 if (TIFFReadTile(tif, buf, col, row, 0, 0) < 0) {
293 if (stoponerr)
294 break;
295 } else if (showdata)
296 ShowTile(row, col, (tsample_t) -1, buf, th, rowsize);
297 }
298 }
299 _TIFFfree(buf);
300 }
301 }
302
303 void
304 TIFFReadSeparateTileData(TIFF* tif)
305 {
306 unsigned char *buf;
307 tsize_t rowsize = TIFFTileRowSize(tif);
308
309 buf = (unsigned char *)_TIFFmalloc(TIFFTileSize(tif));
310 if (buf) {
311 uint32 tw, th, w, h;
312 uint32 row, col;
313 tsample_t s, samplesperpixel;
314
315 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
316 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
317 TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
318 TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
319 TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
320 for (row = 0; row < h; row += th) {
321 for (col = 0; col < w; col += tw) {
322 for (s = 0; s < samplesperpixel; s++) {
323 if (TIFFReadTile(tif, buf, col, row, 0, s) < 0) {
324 if (stoponerr)
325 break;
326 } else if (showdata)
327 ShowTile(row, col, s, buf, th, rowsize);
328 }
329 }
330 }
331 _TIFFfree(buf);
332 }
333 }
334
335 void
336 TIFFReadData(TIFF* tif)
337 {
338 uint16 config;
339
340 TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &config);
341 if (TIFFIsTiled(tif)) {
342 if (config == PLANARCONFIG_CONTIG)
343 TIFFReadContigTileData(tif);
344 else
345 TIFFReadSeparateTileData(tif);
346 } else {
347 if (config == PLANARCONFIG_CONTIG)
348 TIFFReadContigStripData(tif);
349 else
350 TIFFReadSeparateStripData(tif);
351 }
352 }
353
354 static void
355 ShowRawBytes(unsigned char* pp, uint32 n)
356 {
357 uint32 i;
358
359 for (i = 0; i < n; i++) {
360 printf(" %02x", *pp++);
361 if (((i+1) % 24) == 0)
362 printf("\n ");
363 }
364 putchar('\n');
365 }
366
367 static void
368 ShowRawWords(uint16* pp, uint32 n)
369 {
370 uint32 i;
371
372 for (i = 0; i < n; i++) {
373 printf(" %04x", *pp++);
374 if (((i+1) % 15) == 0)
375 printf("\n ");
376 }
377 putchar('\n');
378 }
379
380 void
381 TIFFReadRawData(TIFF* tif, int bitrev)
382 {
383 tstrip_t nstrips = TIFFNumberOfStrips(tif);
384 const char* what = TIFFIsTiled(tif) ? "Tile" : "Strip";
385 uint32* stripbc;
386
387 TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &stripbc);
388 if (nstrips > 0) {
389 uint32 bufsize = stripbc[0];
390 tdata_t buf = _TIFFmalloc(bufsize);
391 tstrip_t s;
392
393 for (s = 0; s < nstrips; s++) {
394 if (stripbc[s] > bufsize) {
395 buf = _TIFFrealloc(buf, stripbc[s]);
396 bufsize = stripbc[s];
397 }
398 if (buf == NULL) {
399 fprintf(stderr,
400 "Cannot allocate buffer to read strip %lu\n",
401 (unsigned long) s);
402 break;
403 }
404 if (TIFFReadRawStrip(tif, s, buf, stripbc[s]) < 0) {
405 fprintf(stderr, "Error reading strip %lu\n",
406 (unsigned long) s);
407 if (stoponerr)
408 break;
409 } else if (showdata) {
410 if (bitrev) {
411 TIFFReverseBits(buf, stripbc[s]);
412 printf("%s %lu: (bit reversed)\n ",
413 what, (unsigned long) s);
414 } else
415 printf("%s %lu:\n ", what,
416 (unsigned long) s);
417 if (showwords)
418 ShowRawWords((uint16*) buf, stripbc[s]>>1);
419 else
420 ShowRawBytes((unsigned char*) buf, stripbc[s]);
421 }
422 }
423 if (buf != NULL)
424 _TIFFfree(buf);
425 }
426 }
427
428 static void
429 tiffinfo(TIFF* tif, uint16 order, long flags)
430 {
431 TIFFPrintDirectory(tif, stdout, flags);
432 if (!readdata)
433 return;
434 if (rawdata) {
435 if (order) {
436 uint16 o;
437 TIFFGetFieldDefaulted(tif,
438 TIFFTAG_FILLORDER, &o);
439 TIFFReadRawData(tif, o != order);
440 } else
441 TIFFReadRawData(tif, 0);
442 } else {
443 if (order)
444 TIFFSetField(tif, TIFFTAG_FILLORDER, order);
445 TIFFReadData(tif);
446 }
447 }
448
449 /* vim: set ts=8 sts=8 sw=8 noet: */