]> git.saurik.com Git - wxWidgets.git/blob - src/tiff/contrib/ras/tif2ras.c
don't test for both stream.fail() and stream.bad() as the latter implies the former...
[wxWidgets.git] / src / tiff / contrib / ras / tif2ras.c
1 #ifndef lint
2 static char id[] = "$Id$";
3 #endif
4 /*-
5 * tif2ras.c - Converts from a Tagged Image File Format image to a Sun Raster.
6 *
7 * Copyright (c) 1990 by Sun Microsystems, Inc.
8 *
9 * Author: Patrick J. Naughton
10 * naughton@wind.sun.com
11 *
12 * Permission to use, copy, modify, and distribute this software and its
13 * documentation for any purpose and without fee is hereby granted,
14 * provided that the above copyright notice appear in all copies and that
15 * both that copyright notice and this permission notice appear in
16 * supporting documentation.
17 *
18 * This file is provided AS IS with no warranties of any kind. The author
19 * shall have no liability with respect to the infringement of copyrights,
20 * trade secrets or any patents by this file or any part thereof. In no
21 * event will the author be liable for any lost revenue or profits or
22 * other special, indirect and consequential damages.
23 *
24 * Comments and additions should be sent to the author:
25 *
26 * Patrick J. Naughton
27 * Sun Microsystems
28 * 2550 Garcia Ave, MS 14-40
29 * Mountain View, CA 94043
30 * (415) 336-1080
31 *
32 * Revision History:
33 * 10-Jan-89: Created.
34 * 06-Mar-90: Change to byte encoded rasterfiles.
35 * fix bug in call to ReadScanline().
36 * fix bug in CVT() macro.
37 * fix assignment of td, (missing &).
38 *
39 * Description:
40 * This program takes a MicroSoft/Aldus "Tagged Image File Format" image or
41 * "TIFF" file as input and writes a Sun Rasterfile [see rasterfile(5)]. The
42 * output file may be standard output, but the input TIFF file must be a real
43 * file since seek(2) is used.
44 */
45
46 #include <stdio.h>
47 #include <pixrect/pixrect_hs.h>
48 #include "tiffio.h"
49
50 typedef int boolean;
51 #define True (1)
52 #define False (0)
53 #define CVT(x) (((x) * 255) / ((1L<<16)-1))
54
55 boolean Verbose = False;
56 char *pname; /* program name (used for error messages) */
57
58 void
59 error(s1, s2)
60 char *s1,
61 *s2;
62 {
63 fprintf(stderr, s1, pname, s2);
64 exit(1);
65 }
66
67 void
68 usage()
69 {
70 error("usage: %s -[vq] TIFFfile [rasterfile]\n", NULL);
71 }
72
73
74 main(argc, argv)
75 int argc;
76 char *argv[];
77 {
78 char *inf = NULL;
79 char *outf = NULL;
80 FILE *fp;
81 long width,
82 height;
83 int depth,
84 numcolors;
85 register TIFF *tif;
86 TIFFDirectory *td;
87 register u_char *inp,
88 *outp;
89 register int col,
90 i;
91 register long row;
92 u_char *Map = NULL;
93 u_char *buf;
94 short bitspersample;
95 short samplesperpixel;
96 short photometric;
97 u_short *redcolormap,
98 *bluecolormap,
99 *greencolormap;
100
101 Pixrect *pix; /* The Sun Pixrect */
102 colormap_t Colormap; /* The Pixrect Colormap */
103 u_char red[256],
104 green[256],
105 blue[256];
106
107 setbuf(stderr, NULL);
108 pname = argv[0];
109
110 while (--argc) {
111 if ((++argv)[0][0] == '-')
112 switch (argv[0][1]) {
113 case 'v':
114 Verbose = True;
115 break;
116 case 'q':
117 usage();
118 break;
119 default:
120 fprintf(stderr, "%s: illegal option -%c.\n", pname,
121 argv[0][1]);
122 exit(1);
123 }
124 else if (inf == NULL)
125 inf = argv[0];
126 else if (outf == NULL)
127 outf = argv[0];
128 else
129 usage();
130
131 }
132
133 if (inf == NULL)
134 error("%s: can't read input file from a stream.\n", NULL);
135
136 if (Verbose)
137 fprintf(stderr, "Reading %s...", inf);
138
139 tif = TIFFOpen(inf, "r");
140
141 if (tif == NULL)
142 error("%s: error opening TIFF file %s", inf);
143
144 if (Verbose)
145 TIFFPrintDirectory(tif, stderr, True, False, False);
146 TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
147 if (bitspersample > 8)
148 error("%s: can't handle more than 8-bits per sample\n", NULL);
149
150 TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
151 switch (samplesperpixel) {
152 case 1:
153 if (bitspersample == 1)
154 depth = 1;
155 else
156 depth = 8;
157 break;
158 case 3:
159 case 4:
160 depth = 24;
161 break;
162 default:
163 error("%s: only handle 1-channel gray scale or 3-channel color\n");
164 }
165
166 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
167 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
168
169 if (Verbose)
170 fprintf(stderr, "%dx%dx%d image, ", width, height, depth);
171 if (Verbose)
172 fprintf(stderr, "%d bits/sample, %d samples/pixel, ",
173 bitspersample, samplesperpixel);
174
175 pix = mem_create(width, height, depth);
176 if (pix == (Pixrect *) NULL)
177 error("%s: can't allocate memory for output pixrect...\n", NULL);
178
179 numcolors = (1 << bitspersample);
180
181 TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
182 if (numcolors == 2) {
183 if (Verbose)
184 fprintf(stderr, "monochrome ");
185 Colormap.type = RMT_NONE;
186 Colormap.length = 0;
187 Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = NULL;
188 } else {
189 switch (photometric) {
190 case PHOTOMETRIC_MINISBLACK:
191 if (Verbose)
192 fprintf(stderr, "%d graylevels (min=black), ", numcolors);
193 Map = (u_char *) malloc(numcolors * sizeof(u_char));
194 for (i = 0; i < numcolors; i++)
195 Map[i] = (255 * i) / numcolors;
196 Colormap.type = RMT_EQUAL_RGB;
197 Colormap.length = numcolors;
198 Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = Map;
199 break;
200 case PHOTOMETRIC_MINISWHITE:
201 if (Verbose)
202 fprintf(stderr, "%d graylevels (min=white), ", numcolors);
203 Map = (u_char *) malloc(numcolors * sizeof(u_char));
204 for (i = 0; i < numcolors; i++)
205 Map[i] = 255 - ((255 * i) / numcolors);
206 Colormap.type = RMT_EQUAL_RGB;
207 Colormap.length = numcolors;
208 Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = Map;
209 break;
210 case PHOTOMETRIC_RGB:
211 if (Verbose)
212 fprintf(stderr, "truecolor ");
213 Colormap.type = RMT_NONE;
214 Colormap.length = 0;
215 Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = NULL;
216 break;
217 case PHOTOMETRIC_PALETTE:
218 if (Verbose)
219 fprintf(stderr, "colormapped ");
220 Colormap.type = RMT_EQUAL_RGB;
221 Colormap.length = numcolors;
222 memset(red, 0, sizeof(red));
223 memset(green, 0, sizeof(green));
224 memset(blue, 0, sizeof(blue));
225 TIFFGetField(tif, TIFFTAG_COLORMAP,
226 &redcolormap, &greencolormap, &bluecolormap);
227 for (i = 0; i < numcolors; i++) {
228 red[i] = (u_char) CVT(redcolormap[i]);
229 green[i] = (u_char) CVT(greencolormap[i]);
230 blue[i] = (u_char) CVT(bluecolormap[i]);
231 }
232 Colormap.map[0] = red;
233 Colormap.map[1] = green;
234 Colormap.map[2] = blue;
235 break;
236 case PHOTOMETRIC_MASK:
237 error("%s: Don't know how to handle PHOTOMETRIC_MASK\n");
238 break;
239 case PHOTOMETRIC_DEPTH:
240 error("%s: Don't know how to handle PHOTOMETRIC_DEPTH\n");
241 break;
242 default:
243 error("%s: unknown photometric (cmap): %d\n", photometric);
244 }
245 }
246
247 buf = (u_char *) malloc(TIFFScanlineSize(tif));
248 if (buf == NULL)
249 error("%s: can't allocate memory for scanline buffer...\n", NULL);
250
251 for (row = 0; row < height; row++) {
252 if (TIFFReadScanline(tif, buf, row, 0) < 0)
253 error("%s: bad data read on line: %d\n", row);
254 inp = buf;
255 outp = (u_char *) mprd_addr(mpr_d(pix), 0, row);
256 switch (photometric) {
257 case PHOTOMETRIC_RGB:
258 if (samplesperpixel == 4)
259 for (col = 0; col < width; col++) {
260 *outp++ = *inp++; /* Blue */
261 *outp++ = *inp++; /* Green */
262 *outp++ = *inp++; /* Red */
263 inp++; /* skip alpha channel */
264 }
265 else
266 for (col = 0; col < width; col++) {
267 *outp++ = *inp++; /* Blue */
268 *outp++ = *inp++; /* Green */
269 *outp++ = *inp++; /* Red */
270 }
271 break;
272 case PHOTOMETRIC_MINISWHITE:
273 case PHOTOMETRIC_MINISBLACK:
274 switch (bitspersample) {
275 case 1:
276 for (col = 0; col < ((width + 7) / 8); col++)
277 *outp++ = *inp++;
278 break;
279 case 2:
280 for (col = 0; col < ((width + 3) / 4); col++) {
281 *outp++ = (*inp >> 6) & 3;
282 *outp++ = (*inp >> 4) & 3;
283 *outp++ = (*inp >> 2) & 3;
284 *outp++ = *inp++ & 3;
285 }
286 break;
287 case 4:
288 for (col = 0; col < width / 2; col++) {
289 *outp++ = *inp >> 4;
290 *outp++ = *inp++ & 0xf;
291 }
292 break;
293 case 8:
294 for (col = 0; col < width; col++)
295 *outp++ = *inp++;
296 break;
297 default:
298 error("%s: bad bits/sample: %d\n", bitspersample);
299 }
300 break;
301 case PHOTOMETRIC_PALETTE:
302 memcpy(outp, inp, width);
303 break;
304 default:
305 error("%s: unknown photometric (write): %d\n", photometric);
306 }
307 }
308
309 free((char *) buf);
310
311 if (Verbose)
312 fprintf(stderr, "done.\n");
313
314 if (outf == NULL || strcmp(outf, "Standard Output") == 0) {
315 outf = "Standard Output";
316 fp = stdout;
317 } else {
318 if (!(fp = fopen(outf, "w")))
319 error("%s: %s couldn't be opened for writing.\n", outf);
320 }
321
322 if (Verbose)
323 fprintf(stderr, "Writing rasterfile in %s...", outf);
324
325 if (pr_dump(pix, fp, &Colormap, RT_BYTE_ENCODED, 0) == PIX_ERR)
326 error("%s: error writing Sun Rasterfile: %s\n", outf);
327
328 if (Verbose)
329 fprintf(stderr, "done.\n");
330
331 pr_destroy(pix);
332
333 if (fp != stdout)
334 fclose(fp);
335
336 exit(0);
337 }