]> git.saurik.com Git - wxWidgets.git/blob - src/tiff/tools/sgisv.c
fix Get(Sub)ItemRect() after changes of r54437; added test for it (see #10175)
[wxWidgets.git] / src / tiff / tools / sgisv.c
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
36 typedef unsigned char u_char;
37 typedef 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
42 uint32 rowsperstrip = (uint32) -1;
43 uint16 compression = COMPRESSION_PACKBITS;
44 uint16 config = PLANARCONFIG_CONTIG;
45 uint16 predictor = 0;
46 int xmaxscreen;
47 int ymaxscreen;
48 uint16 photometric = PHOTOMETRIC_RGB;
49 int jpegcolormode = JPEGCOLORMODE_RGB;
50 int quality = 75; /* JPEG quality */
51
52 static void usage(void);
53 static void tiffsv(char*, int, int, int, int);
54
55 int
56 main(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
118 char* 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",
138 NULL
139 };
140
141 static void
142 usage(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
153 static void
154 svRGBSeparate(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
194 static void
195 svRGBContig(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
233 static void
234 svGrey(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
254 static void
255 tiffsv(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 }