]> git.saurik.com Git - wxWidgets.git/blob - src/tiff/tools/tiffsplit.c
Fix crash in wxDC::GetMultiLineTextExtent() after last commit.
[wxWidgets.git] / src / tiff / tools / tiffsplit.c
1 /* $Id$ */
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 "tif_config.h"
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include "tiffio.h"
34
35 #ifndef HAVE_GETOPT
36 extern int getopt(int, char**, char*);
37 #endif
38
39 #define CopyField(tag, v) \
40 if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
41 #define CopyField2(tag, v1, v2) \
42 if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2)
43 #define CopyField3(tag, v1, v2, v3) \
44 if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
45
46 static char fname[1024+1];
47
48 static int tiffcp(TIFF*, TIFF*);
49 static void newfilename(void);
50 static int cpStrips(TIFF*, TIFF*);
51 static int cpTiles(TIFF*, TIFF*);
52
53 int
54 main(int argc, char* argv[])
55 {
56 TIFF *in, *out;
57
58 if (argc < 2) {
59 fprintf(stderr, "%s\n\n", TIFFGetVersion());
60 fprintf(stderr, "usage: tiffsplit input.tif [prefix]\n");
61 return (-3);
62 }
63 if (argc > 2)
64 strcpy(fname, argv[2]);
65 in = TIFFOpen(argv[1], "r");
66 if (in != NULL) {
67 do {
68 char path[1024+1];
69 newfilename();
70 strcpy(path, fname);
71 strcat(path, ".tif");
72 out = TIFFOpen(path, TIFFIsBigEndian(in)?"wb":"wl");
73 if (out == NULL)
74 return (-2);
75 if (!tiffcp(in, out))
76 return (-1);
77 TIFFClose(out);
78 } while (TIFFReadDirectory(in));
79 (void) TIFFClose(in);
80 }
81 return (0);
82 }
83
84 static void
85 newfilename(void)
86 {
87 static int first = 1;
88 static long lastTurn;
89 static long fnum;
90 static short defname;
91 static char *fpnt;
92
93 if (first) {
94 if (fname[0]) {
95 fpnt = fname + strlen(fname);
96 defname = 0;
97 } else {
98 fname[0] = 'x';
99 fpnt = fname + 1;
100 defname = 1;
101 }
102 first = 0;
103 }
104 #define MAXFILES 17576
105 if (fnum == MAXFILES) {
106 if (!defname || fname[0] == 'z') {
107 fprintf(stderr, "tiffsplit: too many files.\n");
108 exit(1);
109 }
110 fname[0]++;
111 fnum = 0;
112 }
113 if (fnum % 676 == 0) {
114 if (fnum != 0) {
115 /*
116 * advance to next letter every 676 pages
117 * condition for 'z'++ will be covered above
118 */
119 fpnt[0]++;
120 } else {
121 /*
122 * set to 'a' if we are on the very first file
123 */
124 fpnt[0] = 'a';
125 }
126 /*
127 * set the value of the last turning point
128 */
129 lastTurn = fnum;
130 }
131 /*
132 * start from 0 every 676 times (provided by lastTurn)
133 * this keeps us within a-z boundaries
134 */
135 fpnt[1] = (char)((fnum - lastTurn) / 26) + 'a';
136 /*
137 * cycle last letter every file, from a-z, then repeat
138 */
139 fpnt[2] = (char)(fnum % 26) + 'a';
140 fnum++;
141 }
142
143 static int
144 tiffcp(TIFF* in, TIFF* out)
145 {
146 uint16 bitspersample, samplesperpixel, compression, shortv, *shortav;
147 uint32 w, l;
148 float floatv;
149 char *stringv;
150 uint32 longv;
151
152 CopyField(TIFFTAG_SUBFILETYPE, longv);
153 CopyField(TIFFTAG_TILEWIDTH, w);
154 CopyField(TIFFTAG_TILELENGTH, l);
155 CopyField(TIFFTAG_IMAGEWIDTH, w);
156 CopyField(TIFFTAG_IMAGELENGTH, l);
157 CopyField(TIFFTAG_BITSPERSAMPLE, bitspersample);
158 CopyField(TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
159 CopyField(TIFFTAG_COMPRESSION, compression);
160 if (compression == COMPRESSION_JPEG) {
161 uint16 count = 0;
162 void *table = NULL;
163 if (TIFFGetField(in, TIFFTAG_JPEGTABLES, &count, &table)
164 && count > 0 && table) {
165 TIFFSetField(out, TIFFTAG_JPEGTABLES, count, table);
166 }
167 }
168 CopyField(TIFFTAG_PHOTOMETRIC, shortv);
169 CopyField(TIFFTAG_PREDICTOR, shortv);
170 CopyField(TIFFTAG_THRESHHOLDING, shortv);
171 CopyField(TIFFTAG_FILLORDER, shortv);
172 CopyField(TIFFTAG_ORIENTATION, shortv);
173 CopyField(TIFFTAG_MINSAMPLEVALUE, shortv);
174 CopyField(TIFFTAG_MAXSAMPLEVALUE, shortv);
175 CopyField(TIFFTAG_XRESOLUTION, floatv);
176 CopyField(TIFFTAG_YRESOLUTION, floatv);
177 CopyField(TIFFTAG_GROUP3OPTIONS, longv);
178 CopyField(TIFFTAG_GROUP4OPTIONS, longv);
179 CopyField(TIFFTAG_RESOLUTIONUNIT, shortv);
180 CopyField(TIFFTAG_PLANARCONFIG, shortv);
181 CopyField(TIFFTAG_ROWSPERSTRIP, longv);
182 CopyField(TIFFTAG_XPOSITION, floatv);
183 CopyField(TIFFTAG_YPOSITION, floatv);
184 CopyField(TIFFTAG_IMAGEDEPTH, longv);
185 CopyField(TIFFTAG_TILEDEPTH, longv);
186 CopyField(TIFFTAG_SAMPLEFORMAT, longv);
187 CopyField2(TIFFTAG_EXTRASAMPLES, shortv, shortav);
188 { uint16 *red, *green, *blue;
189 CopyField3(TIFFTAG_COLORMAP, red, green, blue);
190 }
191 { uint16 shortv2;
192 CopyField2(TIFFTAG_PAGENUMBER, shortv, shortv2);
193 }
194 CopyField(TIFFTAG_ARTIST, stringv);
195 CopyField(TIFFTAG_IMAGEDESCRIPTION, stringv);
196 CopyField(TIFFTAG_MAKE, stringv);
197 CopyField(TIFFTAG_MODEL, stringv);
198 CopyField(TIFFTAG_SOFTWARE, stringv);
199 CopyField(TIFFTAG_DATETIME, stringv);
200 CopyField(TIFFTAG_HOSTCOMPUTER, stringv);
201 CopyField(TIFFTAG_PAGENAME, stringv);
202 CopyField(TIFFTAG_DOCUMENTNAME, stringv);
203 CopyField(TIFFTAG_BADFAXLINES, longv);
204 CopyField(TIFFTAG_CLEANFAXDATA, longv);
205 CopyField(TIFFTAG_CONSECUTIVEBADFAXLINES, longv);
206 CopyField(TIFFTAG_FAXRECVPARAMS, longv);
207 CopyField(TIFFTAG_FAXRECVTIME, longv);
208 CopyField(TIFFTAG_FAXSUBADDRESS, stringv);
209 CopyField(TIFFTAG_FAXDCS, stringv);
210 if (TIFFIsTiled(in))
211 return (cpTiles(in, out));
212 else
213 return (cpStrips(in, out));
214 }
215
216 static int
217 cpStrips(TIFF* in, TIFF* out)
218 {
219 tsize_t bufsize = TIFFStripSize(in);
220 unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize);
221
222 if (buf) {
223 tstrip_t s, ns = TIFFNumberOfStrips(in);
224 uint32 *bytecounts;
225
226 TIFFGetField(in, TIFFTAG_STRIPBYTECOUNTS, &bytecounts);
227 for (s = 0; s < ns; s++) {
228 if (bytecounts[s] > (uint32)bufsize) {
229 buf = (unsigned char *)_TIFFrealloc(buf, bytecounts[s]);
230 if (!buf)
231 return (0);
232 bufsize = bytecounts[s];
233 }
234 if (TIFFReadRawStrip(in, s, buf, bytecounts[s]) < 0 ||
235 TIFFWriteRawStrip(out, s, buf, bytecounts[s]) < 0) {
236 _TIFFfree(buf);
237 return (0);
238 }
239 }
240 _TIFFfree(buf);
241 return (1);
242 }
243 return (0);
244 }
245
246 static int
247 cpTiles(TIFF* in, TIFF* out)
248 {
249 tsize_t bufsize = TIFFTileSize(in);
250 unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize);
251
252 if (buf) {
253 ttile_t t, nt = TIFFNumberOfTiles(in);
254 uint32 *bytecounts;
255
256 TIFFGetField(in, TIFFTAG_TILEBYTECOUNTS, &bytecounts);
257 for (t = 0; t < nt; t++) {
258 if (bytecounts[t] > (uint32) bufsize) {
259 buf = (unsigned char *)_TIFFrealloc(buf, bytecounts[t]);
260 if (!buf)
261 return (0);
262 bufsize = bytecounts[t];
263 }
264 if (TIFFReadRawTile(in, t, buf, bytecounts[t]) < 0 ||
265 TIFFWriteRawTile(out, t, buf, bytecounts[t]) < 0) {
266 _TIFFfree(buf);
267 return (0);
268 }
269 }
270 _TIFFfree(buf);
271 return (1);
272 }
273 return (0);
274 }
275
276 /* vim: set ts=8 sts=8 sw=8 noet: */