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