~brian-sidebotham/wxwidgets-cmake/wxpython-2.9.4

« back to all changes in this revision

Viewing changes to src/tiff/tools/ras2tiff.c

  • Committer: Brian Sidebotham
  • Date: 2013-08-03 14:30:08 UTC
  • Revision ID: brian.sidebotham@gmail.com-20130803143008-c7806tkych1tp6fc
Initial import into Bazaar

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: ras2tiff.c 47655 2007-07-22 15:36:51Z VZ $ */
 
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
#include <ctype.h>
 
33
 
 
34
#ifdef HAVE_UNISTD_H
 
35
# include <unistd.h>
 
36
#endif
 
37
 
 
38
#include "rasterfile.h"
 
39
#include "tiffio.h"
 
40
 
 
41
#ifndef howmany
 
42
#define howmany(x, y)   (((x)+((y)-1))/(y))
 
43
#endif
 
44
#define streq(a,b)      (strcmp(a,b) == 0)
 
45
#define strneq(a,b,n)   (strncmp(a,b,n) == 0)
 
46
 
 
47
#ifndef BINMODE
 
48
#define BINMODE
 
49
#endif
 
50
 
 
51
static  uint16 compression = (uint16) -1;
 
52
static  int jpegcolormode = JPEGCOLORMODE_RGB;
 
53
static  int quality = 75;               /* JPEG quality */
 
54
static  uint16 predictor = 0;
 
55
 
 
56
static void usage(void);
 
57
static  int processCompressOptions(char*);
 
58
 
 
59
int
 
60
main(int argc, char* argv[])
 
61
{
 
62
        unsigned char* buf;
 
63
        long row;
 
64
        tsize_t linebytes, scanline;
 
65
        TIFF *out;
 
66
        FILE *in;
 
67
        struct rasterfile h;
 
68
        uint16 photometric;
 
69
        uint16 config = PLANARCONFIG_CONTIG;
 
70
        uint32 rowsperstrip = (uint32) -1;
 
71
        int c;
 
72
        extern int optind;
 
73
        extern char* optarg;
 
74
 
 
75
        while ((c = getopt(argc, argv, "c:r:h")) != -1)
 
76
                switch (c) {
 
77
                case 'c':               /* compression scheme */
 
78
                        if (!processCompressOptions(optarg))
 
79
                                usage();
 
80
                        break;
 
81
                case 'r':               /* rows/strip */
 
82
                        rowsperstrip = atoi(optarg);
 
83
                        break;
 
84
                case 'h':
 
85
                        usage();
 
86
                        /*NOTREACHED*/
 
87
                }
 
88
        if (argc - optind != 2)
 
89
                usage();
 
90
        in = fopen(argv[optind], "r" BINMODE);
 
91
        if (in == NULL) {
 
92
                fprintf(stderr, "%s: Can not open.\n", argv[optind]);
 
93
                return (-1);
 
94
        }
 
95
        if (fread(&h, sizeof (h), 1, in) != 1) {
 
96
                fprintf(stderr, "%s: Can not read header.\n", argv[optind]);
 
97
                return (-2);
 
98
        }
 
99
        if (strcmp(h.ras_magic, RAS_MAGIC) == 0) {
 
100
#ifndef WORDS_BIGENDIAN
 
101
                        TIFFSwabLong((uint32 *)&h.ras_width);
 
102
                        TIFFSwabLong((uint32 *)&h.ras_height);
 
103
                        TIFFSwabLong((uint32 *)&h.ras_depth);
 
104
                        TIFFSwabLong((uint32 *)&h.ras_length);
 
105
                        TIFFSwabLong((uint32 *)&h.ras_type);
 
106
                        TIFFSwabLong((uint32 *)&h.ras_maptype);
 
107
                        TIFFSwabLong((uint32 *)&h.ras_maplength);
 
108
#endif
 
109
        } else if (strcmp(h.ras_magic, RAS_MAGIC_INV) == 0) {
 
110
#ifdef WORDS_BIGENDIAN
 
111
                        TIFFSwabLong((uint32 *)&h.ras_width);
 
112
                        TIFFSwabLong((uint32 *)&h.ras_height);
 
113
                        TIFFSwabLong((uint32 *)&h.ras_depth);
 
114
                        TIFFSwabLong((uint32 *)&h.ras_length);
 
115
                        TIFFSwabLong((uint32 *)&h.ras_type);
 
116
                        TIFFSwabLong((uint32 *)&h.ras_maptype);
 
117
                        TIFFSwabLong((uint32 *)&h.ras_maplength);
 
118
#endif
 
119
        } else {
 
120
                fprintf(stderr, "%s: Not a rasterfile.\n", argv[optind]);
 
121
                return (-3);
 
122
        }
 
123
        out = TIFFOpen(argv[optind+1], "w");
 
124
        if (out == NULL)
 
125
                return (-4);
 
126
        TIFFSetField(out, TIFFTAG_IMAGEWIDTH, (uint32) h.ras_width);
 
127
        TIFFSetField(out, TIFFTAG_IMAGELENGTH, (uint32) h.ras_height);
 
128
        TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
 
129
        TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, h.ras_depth > 8 ? 3 : 1);
 
130
        TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, h.ras_depth > 1 ? 8 : 1);
 
131
        TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
 
132
        if (h.ras_maptype != RMT_NONE) {
 
133
                uint16* red;
 
134
                register uint16* map;
 
135
                register int i, j;
 
136
                int mapsize;
 
137
 
 
138
                buf = (unsigned char *)_TIFFmalloc(h.ras_maplength);
 
139
                if (buf == NULL) {
 
140
                        fprintf(stderr, "No space to read in colormap.\n");
 
141
                        return (-5);
 
142
                }
 
143
                if (fread(buf, h.ras_maplength, 1, in) != 1) {
 
144
                        fprintf(stderr, "%s: Read error on colormap.\n",
 
145
                            argv[optind]);
 
146
                        return (-6);
 
147
                }
 
148
                mapsize = 1<<h.ras_depth; 
 
149
                if (h.ras_maplength > mapsize*3) {
 
150
                        fprintf(stderr,
 
151
                            "%s: Huh, %ld colormap entries, should be %d?\n",
 
152
                            argv[optind], h.ras_maplength, mapsize*3);
 
153
                        return (-7);
 
154
                }
 
155
                red = (uint16*)_TIFFmalloc(mapsize * 3 * sizeof (uint16));
 
156
                if (red == NULL) {
 
157
                        fprintf(stderr, "No space for colormap.\n");
 
158
                        return (-8);
 
159
                }
 
160
                map = red;
 
161
                for (j = 0; j < 3; j++) {
 
162
#define SCALE(x)        (((x)*((1L<<16)-1))/255)
 
163
                        for (i = h.ras_maplength/3; i-- > 0;)
 
164
                                *map++ = SCALE(*buf++);
 
165
                        if ((i = h.ras_maplength/3) < mapsize) {
 
166
                                i = mapsize - i;
 
167
                                _TIFFmemset(map, 0, i*sizeof (uint16));
 
168
                                map += i;
 
169
                        }
 
170
                }
 
171
                TIFFSetField(out, TIFFTAG_COLORMAP,
 
172
                     red, red + mapsize, red + 2*mapsize);
 
173
                photometric = PHOTOMETRIC_PALETTE;
 
174
                if (compression == (uint16) -1)
 
175
                        compression = COMPRESSION_PACKBITS;
 
176
                TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
 
177
        } else {
 
178
                /* XXX this is bogus... */
 
179
                photometric = h.ras_depth == 24 ?
 
180
                    PHOTOMETRIC_RGB : PHOTOMETRIC_MINISBLACK;
 
181
                if (compression == (uint16) -1)
 
182
                        compression = COMPRESSION_LZW;
 
183
                TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
 
184
        }
 
185
        switch (compression) {
 
186
        case COMPRESSION_JPEG:
 
187
                if (photometric == PHOTOMETRIC_RGB && jpegcolormode == JPEGCOLORMODE_RGB)
 
188
                        photometric = PHOTOMETRIC_YCBCR;
 
189
                TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
 
190
                TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
 
191
                break;
 
192
        case COMPRESSION_LZW:
 
193
        case COMPRESSION_DEFLATE:
 
194
                if (predictor != 0)
 
195
                        TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
 
196
                break;
 
197
        }
 
198
        TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
 
199
        linebytes = ((h.ras_depth*h.ras_width+15) >> 3) &~ 1;
 
200
        scanline = TIFFScanlineSize(out);
 
201
        if (scanline > linebytes) {
 
202
                buf = (unsigned char *)_TIFFmalloc(scanline);
 
203
                _TIFFmemset(buf+linebytes, 0, scanline-linebytes);
 
204
        } else
 
205
                buf = (unsigned char *)_TIFFmalloc(linebytes);
 
206
        TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
 
207
            TIFFDefaultStripSize(out, rowsperstrip));
 
208
        for (row = 0; row < h.ras_height; row++) {
 
209
                if (fread(buf, linebytes, 1, in) != 1) {
 
210
                        fprintf(stderr, "%s: scanline %ld: Read error.\n",
 
211
                            argv[optind], row);
 
212
                        break;
 
213
                }
 
214
                if (h.ras_type == RT_STANDARD && h.ras_depth == 24) {
 
215
                        tsize_t cc = h.ras_width;
 
216
                        unsigned char* cp = buf;
 
217
#define SWAP(a,b)       { unsigned char t = (a); (a) = (b); (b) = t; }
 
218
                        do {
 
219
                                SWAP(cp[0], cp[2]);
 
220
                                cp += 3;
 
221
                        } while (--cc);
 
222
                }
 
223
                if (TIFFWriteScanline(out, buf, row, 0) < 0)
 
224
                        break;
 
225
        }
 
226
        (void) TIFFClose(out);
 
227
        return (0);
 
228
}
 
229
 
 
230
static int
 
231
processCompressOptions(char* opt)
 
232
{
 
233
        if (streq(opt, "none"))
 
234
                compression = COMPRESSION_NONE;
 
235
        else if (streq(opt, "packbits"))
 
236
                compression = COMPRESSION_PACKBITS;
 
237
        else if (strneq(opt, "jpeg", 4)) {
 
238
                char* cp = strchr(opt, ':');
 
239
 
 
240
                compression = COMPRESSION_JPEG;
 
241
                while( cp )
 
242
                {
 
243
                    if (isdigit((int)cp[1]))
 
244
                        quality = atoi(cp+1);
 
245
                    else if (cp[1] == 'r' )
 
246
                        jpegcolormode = JPEGCOLORMODE_RAW;
 
247
                    else
 
248
                        usage();
 
249
 
 
250
                    cp = strchr(cp+1,':');
 
251
                }
 
252
        } else if (strneq(opt, "lzw", 3)) {
 
253
                char* cp = strchr(opt, ':');
 
254
                if (cp)
 
255
                        predictor = atoi(cp+1);
 
256
                compression = COMPRESSION_LZW;
 
257
        } else if (strneq(opt, "zip", 3)) {
 
258
                char* cp = strchr(opt, ':');
 
259
                if (cp)
 
260
                        predictor = atoi(cp+1);
 
261
                compression = COMPRESSION_DEFLATE;
 
262
        } else
 
263
                return (0);
 
264
        return (1);
 
265
}
 
266
 
 
267
char* stuff[] = {
 
268
"usage: ras2tiff [options] input.ras output.tif",
 
269
"where options are:",
 
270
" -r #          make each strip have no more than # rows",
 
271
"",
 
272
" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
 
273
" -c zip[:opts] compress output with deflate encoding",
 
274
" -c jpeg[:opts]        compress output with JPEG encoding",
 
275
" -c packbits   compress output with packbits encoding",
 
276
" -c none       use no compression algorithm on output",
 
277
"",
 
278
"JPEG options:",
 
279
" #             set compression quality level (0-100, default 75)",
 
280
" r             output color image as RGB rather than YCbCr",
 
281
"For example, -c jpeg:r:50 to get JPEG-encoded RGB data with 50% comp. quality",
 
282
"",
 
283
"LZW and deflate options:",
 
284
" #             set predictor value",
 
285
"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
 
286
" -h            this help message",
 
287
NULL
 
288
};
 
289
 
 
290
static void
 
291
usage(void)
 
292
{
 
293
        char buf[BUFSIZ];
 
294
        int i;
 
295
 
 
296
        setbuf(stderr, buf);
 
297
        fprintf(stderr, "%s\n\n", TIFFGetVersion());
 
298
        for (i = 0; stuff[i] != NULL; i++)
 
299
                fprintf(stderr, "%s\n", stuff[i]);
 
300
        exit(-1);
 
301
}
 
302
 
 
303
/* vim: set ts=8 sts=8 sw=8 noet: */