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