xref: /libtiff-4.0.7/tools/tiffsplit.c (revision 0ef31e1f)
1 /* $Header: /cvs/maptools/cvsroot/libtiff/tools/tiffsplit.c,v 1.1 1999-07-27 21:50:28 mike Exp $ */
2 
3 /*
4  * Copyright (c) 1992-1997 Sam Leffler
5  * Copyright (c) 1992-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 <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 
31 #include "tiffio.h"
32 
33 #define	streq(a,b)	(strcmp(a,b) == 0)
34 #define	CopyField(tag, v) \
35     if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
36 #define	CopyField2(tag, v1, v2) \
37     if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2)
38 #define	CopyField3(tag, v1, v2, v3) \
39     if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
40 
41 static	char fname[1024+1];
42 
43 static	int tiffcp(TIFF*, TIFF*);
44 static	void newfilename(void);
45 static	int cpStrips(TIFF*, TIFF*);
46 static	int cpTiles(TIFF*, TIFF*);
47 
48 int
49 main(int argc, char* argv[])
50 {
51 	TIFF *in, *out;
52 
53 	if (argc < 2) {
54 		fprintf(stderr, "usage: tiffsplit input.tif [prefix]\n");
55 		return (-3);
56 	}
57 	if (argc > 2)
58 		strcpy(fname, argv[2]);
59 	in = TIFFOpen(argv[1], "r");
60 	if (in != NULL) {
61 		do {
62 			char path[1024+1];
63 			newfilename();
64 			strcpy(path, fname);
65 			strcat(path, ".tif");
66 			out = TIFFOpen(path, "w");
67 			if (out == NULL)
68 				return (-2);
69 			if (!tiffcp(in, out))
70 				return (-1);
71 			TIFFClose(out);
72 		} while (TIFFReadDirectory(in));
73 		(void) TIFFClose(in);
74 	}
75 	return (0);
76 }
77 
78 static void
79 newfilename(void)
80 {
81 	static int first = 1;
82 	static long fnum;
83 	static short defname;
84 	static char *fpnt;
85 
86 	if (first) {
87 		if (fname[0]) {
88 			fpnt = fname + strlen(fname);
89 			defname = 0;
90 		} else {
91 			fname[0] = 'x';
92 			fpnt = fname + 1;
93 			defname = 1;
94 		}
95 		first = 0;
96 	}
97 #define	MAXFILES	676
98 	if (fnum == MAXFILES) {
99 		if (!defname || fname[0] == 'z') {
100 			fprintf(stderr, "tiffsplit: too many files.\n");
101 			exit(1);
102 		}
103 		fname[0]++;
104 		fnum = 0;
105 	}
106 	fpnt[0] = fnum / 26 + 'a';
107 	fpnt[1] = fnum % 26 + 'a';
108 	fnum++;
109 }
110 
111 static int
112 tiffcp(TIFF* in, TIFF* out)
113 {
114 	short bitspersample, samplesperpixel, shortv, *shortav;
115 	uint32 w, l;
116 	float floatv;
117 	char *stringv;
118 	uint32 longv;
119 
120 	CopyField(TIFFTAG_SUBFILETYPE, longv);
121 	CopyField(TIFFTAG_TILEWIDTH, w);
122 	CopyField(TIFFTAG_TILELENGTH, l);
123 	CopyField(TIFFTAG_IMAGEWIDTH, w);
124 	CopyField(TIFFTAG_IMAGELENGTH, l);
125 	CopyField(TIFFTAG_BITSPERSAMPLE, bitspersample);
126 	CopyField(TIFFTAG_COMPRESSION, shortv);
127 	CopyField(TIFFTAG_PREDICTOR, shortv);
128 	CopyField(TIFFTAG_PHOTOMETRIC, shortv);
129 	CopyField(TIFFTAG_THRESHHOLDING, shortv);
130 	CopyField(TIFFTAG_FILLORDER, shortv);
131 	CopyField(TIFFTAG_ORIENTATION, shortv);
132 	CopyField(TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
133 	CopyField(TIFFTAG_MINSAMPLEVALUE, shortv);
134 	CopyField(TIFFTAG_MAXSAMPLEVALUE, shortv);
135 	CopyField(TIFFTAG_XRESOLUTION, floatv);
136 	CopyField(TIFFTAG_YRESOLUTION, floatv);
137 	CopyField(TIFFTAG_GROUP3OPTIONS, longv);
138 	CopyField(TIFFTAG_GROUP4OPTIONS, longv);
139 	CopyField(TIFFTAG_RESOLUTIONUNIT, shortv);
140 	CopyField(TIFFTAG_PLANARCONFIG, shortv);
141 	CopyField(TIFFTAG_ROWSPERSTRIP, longv);
142 	CopyField(TIFFTAG_XPOSITION, floatv);
143 	CopyField(TIFFTAG_YPOSITION, floatv);
144 	CopyField(TIFFTAG_IMAGEDEPTH, longv);
145 	CopyField(TIFFTAG_TILEDEPTH, longv);
146 	CopyField2(TIFFTAG_EXTRASAMPLES, shortv, shortav);
147 	{ uint16 *red, *green, *blue;
148 	  CopyField3(TIFFTAG_COLORMAP, red, green, blue);
149 	}
150 	{ uint16 shortv2;
151 	  CopyField2(TIFFTAG_PAGENUMBER, shortv, shortv2);
152 	}
153 	CopyField(TIFFTAG_ARTIST, stringv);
154 	CopyField(TIFFTAG_IMAGEDESCRIPTION, stringv);
155 	CopyField(TIFFTAG_MAKE, stringv);
156 	CopyField(TIFFTAG_MODEL, stringv);
157 	CopyField(TIFFTAG_SOFTWARE, stringv);
158 	CopyField(TIFFTAG_DATETIME, stringv);
159 	CopyField(TIFFTAG_HOSTCOMPUTER, stringv);
160 	CopyField(TIFFTAG_PAGENAME, stringv);
161 	CopyField(TIFFTAG_DOCUMENTNAME, stringv);
162 	if (TIFFIsTiled(in))
163 		return (cpTiles(in, out));
164 	else
165 		return (cpStrips(in, out));
166 }
167 
168 static int
169 cpStrips(TIFF* in, TIFF* out)
170 {
171 	tsize_t bufsize  = TIFFStripSize(in);
172 	unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize);
173 
174 	if (buf) {
175 		tstrip_t s, ns = TIFFNumberOfStrips(in);
176 		uint32 *bytecounts;
177 
178 		TIFFGetField(in, TIFFTAG_STRIPBYTECOUNTS, &bytecounts);
179 		for (s = 0; s < ns; s++) {
180 			if (bytecounts[s] > bufsize) {
181 				buf = (unsigned char *)_TIFFrealloc(buf, bytecounts[s]);
182 				if (!buf)
183 					return (0);
184 				bufsize = bytecounts[s];
185 			}
186 			if (TIFFReadRawStrip(in, s, buf, bytecounts[s]) < 0 ||
187 			    TIFFWriteRawStrip(out, s, buf, bytecounts[s]) < 0) {
188 				_TIFFfree(buf);
189 				return (0);
190 			}
191 		}
192 		_TIFFfree(buf);
193 		return (1);
194 	}
195 	return (0);
196 }
197 
198 static int
199 cpTiles(TIFF* in, TIFF* out)
200 {
201 	tsize_t bufsize = TIFFTileSize(in);
202 	unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize);
203 
204 	if (buf) {
205 		ttile_t t, nt = TIFFNumberOfTiles(in);
206 		uint32 *bytecounts;
207 
208 		TIFFGetField(in, TIFFTAG_TILEBYTECOUNTS, &bytecounts);
209 		for (t = 0; t < nt; t++) {
210 			if (bytecounts[t] > bufsize) {
211 				buf = (unsigned char *)_TIFFrealloc(buf, bytecounts[t]);
212 				if (!buf)
213 					return (0);
214 				bufsize = bytecounts[t];
215 			}
216 			if (TIFFReadRawTile(in, t, buf, bytecounts[t]) < 0 ||
217 			    TIFFWriteRawTile(out, t, buf, bytecounts[t]) < 0) {
218 				_TIFFfree(buf);
219 				return (0);
220 			}
221 		}
222 		_TIFFfree(buf);
223 		return (1);
224 	}
225 	return (0);
226 }
227