1
/* $Id: ras2tiff.c 47655 2007-07-22 15:36:51Z VZ $ */
4
* Copyright (c) 1988-1997 Sam Leffler
5
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
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.
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.
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
27
#include "tif_config.h"
38
#include "rasterfile.h"
42
#define howmany(x, y) (((x)+((y)-1))/(y))
44
#define streq(a,b) (strcmp(a,b) == 0)
45
#define strneq(a,b,n) (strncmp(a,b,n) == 0)
51
static uint16 compression = (uint16) -1;
52
static int jpegcolormode = JPEGCOLORMODE_RGB;
53
static int quality = 75; /* JPEG quality */
54
static uint16 predictor = 0;
56
static void usage(void);
57
static int processCompressOptions(char*);
60
main(int argc, char* argv[])
64
tsize_t linebytes, scanline;
69
uint16 config = PLANARCONFIG_CONTIG;
70
uint32 rowsperstrip = (uint32) -1;
75
while ((c = getopt(argc, argv, "c:r:h")) != -1)
77
case 'c': /* compression scheme */
78
if (!processCompressOptions(optarg))
81
case 'r': /* rows/strip */
82
rowsperstrip = atoi(optarg);
88
if (argc - optind != 2)
90
in = fopen(argv[optind], "r" BINMODE);
92
fprintf(stderr, "%s: Can not open.\n", argv[optind]);
95
if (fread(&h, sizeof (h), 1, in) != 1) {
96
fprintf(stderr, "%s: Can not read header.\n", argv[optind]);
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);
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);
120
fprintf(stderr, "%s: Not a rasterfile.\n", argv[optind]);
123
out = TIFFOpen(argv[optind+1], "w");
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) {
134
register uint16* map;
138
buf = (unsigned char *)_TIFFmalloc(h.ras_maplength);
140
fprintf(stderr, "No space to read in colormap.\n");
143
if (fread(buf, h.ras_maplength, 1, in) != 1) {
144
fprintf(stderr, "%s: Read error on colormap.\n",
148
mapsize = 1<<h.ras_depth;
149
if (h.ras_maplength > mapsize*3) {
151
"%s: Huh, %ld colormap entries, should be %d?\n",
152
argv[optind], h.ras_maplength, mapsize*3);
155
red = (uint16*)_TIFFmalloc(mapsize * 3 * sizeof (uint16));
157
fprintf(stderr, "No space for colormap.\n");
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) {
167
_TIFFmemset(map, 0, i*sizeof (uint16));
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);
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);
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);
192
case COMPRESSION_LZW:
193
case COMPRESSION_DEFLATE:
195
TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
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);
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",
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; }
223
if (TIFFWriteScanline(out, buf, row, 0) < 0)
226
(void) TIFFClose(out);
231
processCompressOptions(char* opt)
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, ':');
240
compression = COMPRESSION_JPEG;
243
if (isdigit((int)cp[1]))
244
quality = atoi(cp+1);
245
else if (cp[1] == 'r' )
246
jpegcolormode = JPEGCOLORMODE_RAW;
250
cp = strchr(cp+1,':');
252
} else if (strneq(opt, "lzw", 3)) {
253
char* cp = strchr(opt, ':');
255
predictor = atoi(cp+1);
256
compression = COMPRESSION_LZW;
257
} else if (strneq(opt, "zip", 3)) {
258
char* cp = strchr(opt, ':');
260
predictor = atoi(cp+1);
261
compression = COMPRESSION_DEFLATE;
268
"usage: ras2tiff [options] input.ras output.tif",
269
"where options are:",
270
" -r # make each strip have no more than # rows",
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",
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",
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",
297
fprintf(stderr, "%s\n\n", TIFFGetVersion());
298
for (i = 0; stuff[i] != NULL; i++)
299
fprintf(stderr, "%s\n", stuff[i]);
303
/* vim: set ts=8 sts=8 sw=8 noet: */