New comit of SDL2
[supertux.git] / src / SDL2 / external / tiff-4.0.3 / tools / sgi2tiff.c
1 /* $Id: sgi2tiff.c,v 1.6 2010-03-10 18:56:49 bfriesen Exp $ */
2
3 /*
4  * Copyright (c) 1991-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 #include <gl/image.h>
31 #include <ctype.h>
32
33 #include "tiffio.h"
34
35 #define streq(a,b)      (strcmp(a,b) == 0)
36 #define strneq(a,b,n)   (strncmp(a,b,n) == 0)
37
38 static  short config = PLANARCONFIG_CONTIG;
39 static  uint16 compression = COMPRESSION_PACKBITS;
40 static  uint16 predictor = 0;
41 static  uint16 fillorder = 0;
42 static  uint32 rowsperstrip = (uint32) -1;
43 static  int jpegcolormode = JPEGCOLORMODE_RGB;
44 static  int quality = 75;               /* JPEG quality */
45 static  uint16 photometric;
46
47 static  void usage(void);
48 static  int cpContig(IMAGE*, TIFF*);
49 static  int cpSeparate(IMAGE*, TIFF*);
50 static  int processCompressOptions(char*);
51
52 /* XXX image library has no prototypes */
53 extern  IMAGE* iopen(const char*, const char*);
54 extern  void iclose(IMAGE*);
55 extern  void getrow(IMAGE*, short*, int, int);
56
57 int
58 main(int argc, char* argv[])
59 {
60         IMAGE *in;
61         TIFF *out;
62         int c;
63         extern int optind;
64         extern char* optarg;
65
66         while ((c = getopt(argc, argv, "c:p:r:")) != -1)
67                 switch (c) {
68                 case 'c':               /* compression scheme */
69                         if (!processCompressOptions(optarg))
70                                 usage();
71                         break;
72                 case 'f':               /* fill order */
73                         if (streq(optarg, "lsb2msb"))
74                                 fillorder = FILLORDER_LSB2MSB;
75                         else if (streq(optarg, "msb2lsb"))
76                                 fillorder = FILLORDER_MSB2LSB;
77                         else
78                                 usage();
79                         break;
80                 case 'p':               /* planar configuration */
81                         if (streq(optarg, "separate"))
82                                 config = PLANARCONFIG_SEPARATE;
83                         else if (streq(optarg, "contig"))
84                                 config = PLANARCONFIG_CONTIG;
85                         else
86                                 usage();
87                         break;
88                 case 'r':               /* rows/strip */
89                         rowsperstrip = atoi(optarg);
90                         break;
91                 case '?':
92                         usage();
93                         /*NOTREACHED*/
94                 }
95         if (argc - optind != 2)
96                 usage();
97         in = iopen(argv[optind], "r");
98         if (in == NULL)
99                 return (-1);
100         out = TIFFOpen(argv[optind+1], "w");
101         if (out == NULL)
102                 return (-2);
103         TIFFSetField(out, TIFFTAG_IMAGEWIDTH, (uint32) in->xsize);
104         TIFFSetField(out, TIFFTAG_IMAGELENGTH, (uint32) in->ysize);
105         TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8);
106         TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
107         if (in->zsize == 1)
108                 photometric = PHOTOMETRIC_MINISBLACK;
109         else
110                 photometric = PHOTOMETRIC_RGB;
111         switch (compression) {
112         case COMPRESSION_JPEG:
113                 if (photometric == PHOTOMETRIC_RGB && jpegcolormode == JPEGCOLORMODE_RGB)
114                         photometric = PHOTOMETRIC_YCBCR;
115                 TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
116                 TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
117                 break;
118         case COMPRESSION_LZW:
119         case COMPRESSION_DEFLATE:
120                 if (predictor != 0)
121                         TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
122                 break;
123         }
124         TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
125         if (fillorder != 0)
126                 TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
127         TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
128         TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, in->zsize);
129         if (in->zsize > 3) {
130             uint16 v[1];
131             v[0] = EXTRASAMPLE_UNASSALPHA;
132             TIFFSetField(out, TIFFTAG_EXTRASAMPLES, 1, v);
133         }
134         TIFFSetField(out, TIFFTAG_MINSAMPLEVALUE, (uint16) in->min);
135         TIFFSetField(out, TIFFTAG_MAXSAMPLEVALUE, (uint16) in->max);
136         TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
137         if (config != PLANARCONFIG_SEPARATE)
138                 TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
139                     TIFFDefaultStripSize(out, rowsperstrip));
140         else                    /* force 1 row/strip for library limitation */
141                 TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, 1L);
142         if (in->name[0] != '\0')
143                 TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, in->name);
144         if (config == PLANARCONFIG_CONTIG)
145                 cpContig(in, out);
146         else
147                 cpSeparate(in, out);
148         (void) iclose(in);
149         (void) TIFFClose(out);
150         return (0);
151 }
152
153 static int
154 processCompressOptions(char* opt)
155 {
156         if (streq(opt, "none"))
157                 compression = COMPRESSION_NONE;
158         else if (streq(opt, "packbits"))
159                 compression = COMPRESSION_PACKBITS;
160         else if (strneq(opt, "jpeg", 4)) {
161                 char* cp = strchr(opt, ':');
162
163                 defcompression = COMPRESSION_JPEG;
164                 while( cp )
165                 {
166                     if (isdigit((int)cp[1]))
167                         quality = atoi(cp+1);
168                     else if (cp[1] == 'r' )
169                         jpegcolormode = JPEGCOLORMODE_RAW;
170                     else
171                         usage();
172
173                     cp = strchr(cp+1,':');
174                 }
175         } else if (strneq(opt, "lzw", 3)) {
176                 char* cp = strchr(opt, ':');
177                 if (cp)
178                         predictor = atoi(cp+1);
179                 compression = COMPRESSION_LZW;
180         } else if (strneq(opt, "zip", 3)) {
181                 char* cp = strchr(opt, ':');
182                 if (cp)
183                         predictor = atoi(cp+1);
184                 compression = COMPRESSION_DEFLATE;
185         } else
186                 return (0);
187         return (1);
188 }
189
190 static int
191 cpContig(IMAGE* in, TIFF* out)
192 {
193         tdata_t buf = _TIFFmalloc(TIFFScanlineSize(out));
194         short *r = NULL;
195         int x, y;
196
197         if (in->zsize == 3) {
198                 short *g, *b;
199
200                 r = (short *)_TIFFmalloc(3 * in->xsize * sizeof (short));
201                 g = r + in->xsize;
202                 b = g + in->xsize;
203                 for (y = in->ysize-1; y >= 0; y--) {
204                         uint8* pp = (uint8*) buf;
205
206                         getrow(in, r, y, 0);
207                         getrow(in, g, y, 1);
208                         getrow(in, b, y, 2);
209                         for (x = 0; x < in->xsize; x++) {
210                                 pp[0] = r[x];
211                                 pp[1] = g[x];
212                                 pp[2] = b[x];
213                                 pp += 3;
214                         }
215                         if (TIFFWriteScanline(out, buf, in->ysize-y-1, 0) < 0)
216                                 goto bad;
217                 }
218         } else if (in->zsize == 4) {
219                 short *g, *b, *a;
220
221                 r = (short *)_TIFFmalloc(4 * in->xsize * sizeof (short));
222                 g = r + in->xsize;
223                 b = g + in->xsize;
224                 a = b + in->xsize;
225                 for (y = in->ysize-1; y >= 0; y--) {
226                         uint8* pp = (uint8*) buf;
227
228                         getrow(in, r, y, 0);
229                         getrow(in, g, y, 1);
230                         getrow(in, b, y, 2);
231                         getrow(in, a, y, 3);
232                         for (x = 0; x < in->xsize; x++) {
233                                 pp[0] = r[x];
234                                 pp[1] = g[x];
235                                 pp[2] = b[x];
236                                 pp[3] = a[x];
237                                 pp += 4;
238                         }
239                         if (TIFFWriteScanline(out, buf, in->ysize-y-1, 0) < 0)
240                                 goto bad;
241                 }
242         } else {
243                 uint8* pp = (uint8*) buf;
244
245                 r = (short *)_TIFFmalloc(in->xsize * sizeof (short));
246                 for (y = in->ysize-1; y >= 0; y--) {
247                         getrow(in, r, y, 0);
248                         for (x = in->xsize-1; x >= 0; x--)
249                                 pp[x] = r[x];
250                         if (TIFFWriteScanline(out, buf, in->ysize-y-1, 0) < 0)
251                                 goto bad;
252                 }
253         }
254         if (r)
255                 _TIFFfree(r);
256         _TIFFfree(buf);
257         return (1);
258 bad:
259         if (r)
260                 _TIFFfree(r);
261         _TIFFfree(buf);
262         return (0);
263 }
264
265 static int
266 cpSeparate(IMAGE* in, TIFF* out)
267 {
268         tdata_t buf = _TIFFmalloc(TIFFScanlineSize(out));
269         short *r = (short *)_TIFFmalloc(in->xsize * sizeof (short));
270         uint8* pp = (uint8*) buf;
271         int x, y, z;
272
273         for (z = 0; z < in->zsize; z++) {
274                 for (y = in->ysize-1; y >= 0; y--) {
275                         getrow(in, r, y, z);
276                         for (x = 0; x < in->xsize; x++)
277                                 pp[x] = r[x];
278                         if (TIFFWriteScanline(out, buf, in->ysize-y-1, z) < 0)
279                                 goto bad;
280                 }
281         }
282         _TIFFfree(r);
283         _TIFFfree(buf);
284         return (1);
285 bad:
286         _TIFFfree(r);
287         _TIFFfree(buf);
288         return (0);
289 }
290
291 char* stuff[] = {
292 "usage: sgi2tiff [options] input.rgb output.tif",
293 "where options are:",
294 " -r #          make each strip have no more than # rows",
295 "",
296 " -p contig     pack samples contiguously (e.g. RGBRGB...)",
297 " -p separate   store samples separately (e.g. RRR...GGG...BBB...)",
298 "",
299 " -f lsb2msb    force lsb-to-msb FillOrder for output",
300 " -f msb2lsb    force msb-to-lsb FillOrder for output",
301 "",
302 " -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
303 " -c zip[:opts] compress output with deflate encoding",
304 " -c jpeg[:opts]compress output with JPEG encoding",
305 " -c packbits   compress output with packbits encoding",
306 " -c none       use no compression algorithm on output",
307 "",
308 "JPEG options:",
309 " #             set compression quality level (0-100, default 75)",
310 " r             output color image as RGB rather than YCbCr",
311 "",
312 "LZW and deflate options:",
313 " #             set predictor value",
314 "For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
315 NULL
316 };
317
318 static void
319 usage(void)
320 {
321         char buf[BUFSIZ];
322         int i;
323
324         setbuf(stderr, buf);
325         for (i = 0; stuff[i] != NULL; i++)
326                 fprintf(stderr, "%s\n", stuff[i]);
327         exit(-1);
328 }
329 /*
330  * Local Variables:
331  * mode: c
332  * c-basic-offset: 8
333  * fill-column: 78
334  * End:
335  */