~ubuntu-branches/ubuntu/quantal/tiff/quantal

« back to all changes in this revision

Viewing changes to tools/tiffsplit.c

  • Committer: Bazaar Package Importer
  • Author(s): Jay Berkenbilt
  • Date: 2009-08-28 15:44:23 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090828154423-7oisj77n302jrroa
Tags: 3.9.1-1
New upstream release

Show diffs side-by-side

added added

removed removed

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