]> git.saurik.com Git - wxWidgets.git/blame - src/tiff/tools/sgisv.c
xti changes
[wxWidgets.git] / src / tiff / tools / sgisv.c
CommitLineData
8414a40c
VZ
1/* $Id$ */
2
3/*
4 * Copyright (c) 1990-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 <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30
31#include <gl.h>
32#include <ctype.h>
33
34#include "tiffio.h"
35
36typedef unsigned char u_char;
37typedef unsigned long u_long;
38
39#define streq(a,b) (strcmp(a,b) == 0)
40#define strneq(a,b,n) (strncmp(a,b,n) == 0)
41
42uint32 rowsperstrip = (uint32) -1;
43uint16 compression = COMPRESSION_PACKBITS;
44uint16 config = PLANARCONFIG_CONTIG;
45uint16 predictor = 0;
46int xmaxscreen;
47int ymaxscreen;
48uint16 photometric = PHOTOMETRIC_RGB;
49int jpegcolormode = JPEGCOLORMODE_RGB;
50int quality = 75; /* JPEG quality */
51
52static void usage(void);
53static void tiffsv(char*, int, int, int, int);
54
55int
56main(int argc, char* argv[])
57{
58 int c;
59 extern int optind;
60 extern char* optarg;
61
62 while ((c = getopt(argc, argv, "c:p:r:")) != -1)
63 switch (c) {
64 case 'b': /* save as b&w */
65 photometric = PHOTOMETRIC_MINISBLACK;
66 break;
67 case 'c': /* compression scheme */
68 if (streq(optarg, "none"))
69 compression = COMPRESSION_NONE;
70 else if (streq(optarg, "packbits"))
71 compression = COMPRESSION_PACKBITS;
72 else if (strneq(optarg, "jpeg", 4)) {
73 char* cp = strchr(optarg, ':');
74 if (cp && isdigit(cp[1]))
75 quality = atoi(cp+1);
76 if (cp && strchr(cp, 'r'))
77 jpegcolormode = JPEGCOLORMODE_RAW;
78 compression = COMPRESSION_JPEG;
79 } else if (strneq(optarg, "lzw", 3)) {
80 char* cp = strchr(optarg, ':');
81 if (cp)
82 predictor = atoi(cp+1);
83 compression = COMPRESSION_LZW;
84 } else
85 usage();
86 break;
87 case 'p': /* planar configuration */
88 if (streq(optarg, "separate"))
89 config = PLANARCONFIG_SEPARATE;
90 else if (streq(optarg, "contig"))
91 config = PLANARCONFIG_CONTIG;
92 else
93 usage();
94 break;
95 case 'r': /* rows/strip */
96 rowsperstrip = atoi(optarg);
97 break;
98 case '?':
99 usage();
100 /*NOTREACHED*/
101 }
102 if (argc - optind != 1 && argc - optind != 5)
103 usage();
104 xmaxscreen = getgdesc(GD_XPMAX)-1;
105 ymaxscreen = getgdesc(GD_YPMAX)-1;
106 foreground();
107 noport();
108 winopen("tiffsv");
109 if (argc - optind == 5)
110 tiffsv(argv[optind],
111 atoi(argv[optind+1]), atoi(argv[optind+2]),
112 atoi(argv[optind+3]), atoi(argv[optind+4]));
113 else
114 tiffsv(argv[optind], 0, xmaxscreen, 0, ymaxscreen);
115 return (0);
116}
117
118char* stuff[] = {
119"usage: tiffsv [options] outimage.tif [x1 x2 y1 y2] [-b]",
120"where options are:",
121" -p contig pack samples contiguously (e.g. RGBRGB...)",
122" -p separate store samples separately (e.g. RRR...GGG...BBB...)",
123"",
124" -r # make each strip have no more than # rows",
125"",
126" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
127" -c jpeg[:opts]compress output with JPEG encoding",
128" -c packbits compress output with packbits encoding",
129" -c none use no compression algorithm on output",
130"",
131"JPEG options:",
132" # set compression quality level (0-100, default 75)",
133" r output color image as RGB rather than YCbCr",
134"",
135"LZW options:",
136" # set predictor value for Lempel-Ziv & Welch encoding",
137"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
138NULL
139};
140
141static void
142usage(void)
143{
144 char buf[BUFSIZ];
145 int i;
146
147 setbuf(stderr, buf);
148 for (i = 0; stuff[i] != NULL; i++)
149 fprintf(stderr, "%s\n", stuff[i]);
150 exit(-1);
151}
152
153static void
154svRGBSeparate(TIFF* tif, u_long* ss, int xsize, int ysize)
155{
156 tsize_t stripsize = TIFFStripSize(tif);
157 u_char *rbuf = (u_char *)_TIFFmalloc(3*stripsize);
158 u_char *gbuf = rbuf + stripsize;
159 u_char *bbuf = gbuf + stripsize;
160 register int y;
161
162 for (y = 0; y <= ysize; y += rowsperstrip) {
163 u_char *rp, *gp, *bp;
164 register int x;
165 register uint32 n;
166
167 n = rowsperstrip;
168 if (n > ysize-y+1)
169 n = ysize-y+1;
170 rp = rbuf; gp = gbuf; bp = bbuf;
171 do {
172 for (x = 0; x <= xsize; x++) {
173 u_long v = ss[x];
174 rp[x] = v;
175 gp[x] = v >> 8;
176 bp[x] = v >> 16;
177 }
178 rp += xsize+1, gp += xsize+1, bp += xsize+1;
179 ss += xsize+1;
180 } while (--n);
181 if (TIFFWriteEncodedStrip(tif, TIFFComputeStrip(tif,y,0),
182 rbuf, stripsize) < 0)
183 break;
184 if (TIFFWriteEncodedStrip(tif, TIFFComputeStrip(tif,y,1),
185 gbuf, stripsize) < 0)
186 break;
187 if (TIFFWriteEncodedStrip(tif, TIFFComputeStrip(tif,y,2),
188 bbuf, stripsize) < 0)
189 break;
190 }
191 _TIFFfree(rbuf);
192}
193
194static void
195svRGBContig(TIFF* tif, u_long* ss, int xsize, int ysize)
196{
197 register int x, y;
198 tsize_t stripsize = TIFFStripSize(tif);
199 u_char *strip = (u_char *)_TIFFmalloc(stripsize);
200
201 for (y = 0; y <= ysize; y += rowsperstrip) {
202 register u_char *pp = strip;
203 register uint32 n;
204
205 n = rowsperstrip;
206 if (n > ysize-y+1)
207 n = ysize-y+1;
208 do {
209 for (x = 0; x <= xsize; x++) {
210 u_long v = ss[x];
211 pp[0] = v;
212 pp[1] = v >> 8;
213 pp[2] = v >> 16;
214 pp += 3;
215 }
216 ss += xsize+1;
217 } while (--n);
218 if (TIFFWriteEncodedStrip(tif, TIFFComputeStrip(tif,y,0),
219 strip, stripsize) < 0)
220 break;
221 }
222 _TIFFfree(strip);
223}
224
225#undef RED
226#undef GREEN
227#undef BLUE
228#define CVT(x) (((x)*255)/100)
229#define RED CVT(28) /* 28% */
230#define GREEN CVT(59) /* 59% */
231#define BLUE CVT(11) /* 11% */
232
233static void
234svGrey(TIFF* tif, u_long* ss, int xsize, int ysize)
235{
236 register int x, y;
237 u_char *buf = (u_char *)_TIFFmalloc(TIFFScanlineSize(tif));
238
239 for (y = 0; y <= ysize; y++) {
240 for (x = 0; x <= xsize; x++) {
241 u_char *cp = (u_char *)&ss[x];
242 buf[x] = (RED*cp[3] + GREEN*cp[2] + BLUE*cp[1]) >> 8;
243 }
244 if (TIFFWriteScanline(tif, buf, (uint32) y, 0) < 0)
245 break;
246 ss += xsize+1;
247 }
248 _TIFFfree(buf);
249}
250
251#define MIN(a,b) ((a)<(b)?(a):(b))
252#define ABS(x) ((x)<0?-(x):(x))
253
254static void
255tiffsv(char* name, int x1, int x2, int y1, int y2)
256{
257 TIFF *tif;
258 int xsize, ysize;
259 int xorg, yorg;
260 u_long *scrbuf;
261
262 xorg = MIN(x1,x2);
263 yorg = MIN(y1,y2);
264 if (xorg<0)
265 xorg = 0;
266 if (yorg<0)
267 yorg = 0;
268 xsize = ABS(x2-x1);
269 ysize = ABS(y2-y1);
270 if (xorg+xsize > xmaxscreen)
271 xsize = xmaxscreen-xorg;
272 if (yorg+ysize > ymaxscreen)
273 ysize = ymaxscreen-yorg;
274 tif = TIFFOpen(name, "w");
275 TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, (uint32) (xsize+1));
276 TIFFSetField(tif, TIFFTAG_IMAGELENGTH, (uint32) (ysize+1));
277 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
278 TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL,
279 photometric == PHOTOMETRIC_RGB ? 3 : 1);
280 TIFFSetField(tif, TIFFTAG_PLANARCONFIG, config);
281 TIFFSetField(tif, TIFFTAG_COMPRESSION, compression);
282 switch (compression) {
283 case COMPRESSION_JPEG:
284 if (photometric == PHOTOMETRIC_RGB && jpegcolormode == JPEGCOLORMODE_RGB)
285 photometric = PHOTOMETRIC_YCBCR;
286 TIFFSetField(tif, TIFFTAG_JPEGQUALITY, quality);
287 TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
288 break;
289 case COMPRESSION_LZW:
290 if (predictor != 0)
291 TIFFSetField(tif, TIFFTAG_PREDICTOR, predictor);
292 break;
293 }
294 TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric);
295 TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT);
296 rowsperstrip = TIFFDefaultStripSize(tif, rowsperstrip);
297 TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
298 scrbuf = (u_long *)_TIFFmalloc((xsize+1)*(ysize+1)*sizeof (u_long));
299 readdisplay(xorg, yorg, xorg+xsize, yorg+ysize, scrbuf, RD_FREEZE);
300 if (photometric == PHOTOMETRIC_RGB) {
301 if (config == PLANARCONFIG_SEPARATE)
302 svRGBSeparate(tif, scrbuf, xsize, ysize);
303 else
304 svRGBContig(tif, scrbuf, xsize, ysize);
305 } else
306 svGrey(tif, scrbuf, xsize, ysize);
307 (void) TIFFClose(tif);
308 _TIFFfree((char *)scrbuf);
309}