"Initial commit to Gerrit"
[profile/ivi/libtiff.git] / tools / sgisv.c
1 /* $Id: sgisv.c,v 1.5.2.1 2010-06-08 18:50:44 bfriesen Exp $ */
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 unsigned char;
37 typedef unsigned long uint32;
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, uint32* ss, int xsize, int ysize)
155 {
156         tsize_t stripsize = TIFFStripSize(tif);
157         unsigned char *rbuf = (unsigned char *)_TIFFmalloc(3*stripsize);
158         unsigned char *gbuf = rbuf + stripsize;
159         unsigned char *bbuf = gbuf + stripsize;
160         register int y;
161
162         for (y = 0; y <= ysize; y += rowsperstrip) {
163                 unsigned 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                                 uint32 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, uint32* ss, int xsize, int ysize)
196 {
197         register int x, y;
198         tsize_t stripsize = TIFFStripSize(tif);
199         unsigned char *strip = (unsigned char *)_TIFFmalloc(stripsize);
200
201         for (y = 0; y <= ysize; y += rowsperstrip) {
202                 register unsigned 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                                 uint32 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, uint32* ss, int xsize, int ysize)
235 {
236         register int x, y;
237         unsigned char *buf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(tif));
238
239         for (y = 0; y <= ysize; y++) {
240                 for (x = 0; x <= xsize; x++) {
241                         unsigned char *cp = (unsigned 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         uint32 *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 = (uint32 *)_TIFFmalloc((xsize+1)*(ysize+1)*sizeof (uint32));
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 }
310 /*
311  * Local Variables:
312  * mode: c
313  * c-basic-offset: 8
314  * fill-column: 78
315  * End:
316  */