ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t8.c
Revision: 1.2
Committed: Tue Sep 12 13:04:38 1989 UTC (34 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.1: +2 -2 lines
Log Message:
added calls to get/put picture resolution (bug fix)

File Contents

# Content
1 /* Copyright (c) 1986 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * ra_t8.c - program to convert between RADIANCE and
9 * Targa 8-bit color-mapped images.
10 *
11 * 8/22/88 Adapted from ra_pr.c
12 */
13
14 #include <stdio.h>
15
16 #include "color.h"
17
18 #include "pic.h"
19
20 #include "targa.h"
21
22 /* descriptor for a picture file or frame buffer */
23 typedef struct {
24 char *name; /* file name */
25 FILE *fp; /* file pointer */
26 int nexty; /* file positioning */
27 int bytes_line; /* 0 == variable length lines */
28 union {
29 long b; /* initial scanline */
30 long *y; /* individual scanline */
31 } pos; /* position(s) */
32 } pic;
33
34 #define goodpic(h) (my_imType(h) && my_mapType(h))
35 #define my_imType(h) (((h)->dataType==IM_CMAP || (h)->dataType==IM_CCMAP) \
36 && (h)->dataBits==8 && (h)->imType==0)
37 #define my_mapType(h) ((h)->mapType==CM_HASMAP && \
38 ((h)->CMapBits==24 || (h)->CMapBits==32))
39
40 #define taralloc(h) (pixel *)emalloc((h)->x*(h)->y*sizeof(pixel))
41
42 extern pic *openinput();
43
44 extern char *ecalloc(), *emalloc();
45
46 extern long ftell();
47
48 extern double atof(), pow();
49
50 double gamma = 2.0; /* gamma correction */
51
52 pic *inpic;
53
54 char *progname;
55
56 char errmsg[128];
57
58 COLR *inline;
59
60 pixel *tarData;
61
62 int xmax, ymax;
63
64
65 main(argc, argv)
66 int argc;
67 char *argv[];
68 {
69 colormap rasmap;
70 struct hdStruct head;
71 int dither = 1;
72 int reverse = 0;
73 int ncolors = 256;
74 int greyscale = 0;
75 int i;
76
77 progname = argv[0];
78
79 for (i = 1; i < argc; i++)
80 if (argv[i][0] == '-')
81 switch (argv[i][1]) {
82 case 'd':
83 dither = !dither;
84 break;
85 case 'g':
86 gamma = atof(argv[++i]);
87 break;
88 case 'r':
89 reverse = !reverse;
90 break;
91 case 'b':
92 greyscale = 1;
93 break;
94 case 'c':
95 ncolors = atoi(argv[++i]);
96 break;
97 default:
98 goto userr;
99 }
100 else
101 break;
102
103 if (reverse) {
104 if (i < argc-2)
105 goto userr;
106 if (i <= argc-1 && freopen(argv[i], "r", stdin) == NULL) {
107 sprintf(errmsg, "can't open input \"%s\"", argv[i]);
108 quiterr(errmsg);
109 }
110 /* get header */
111 if (getthead(&head, NULL, stdin) < 0)
112 quiterr("bad targa file");
113 if (!goodpic(&head))
114 quiterr("incompatible format");
115 xmax = head.x;
116 ymax = head.y;
117 /* open output file */
118 if (i == argc-2 && freopen(argv[i+1], "w", stdout) == NULL) {
119 sprintf(errmsg, "can't open output \"%s\"", argv[i+1]);
120 quiterr(errmsg);
121 }
122 /* put header */
123 printargs(argc, argv, stdout);
124 putchar('\n');
125 fputresolu(YMAJOR|YDECR, xmax, ymax, stdout);
126 /* convert file */
127 tg2ra(&head);
128 } else {
129 if (i > argc-1 || i < argc-2)
130 goto userr;
131 if ((inpic = openinput(argv[i], &head)) == NULL) {
132 sprintf(errmsg, "can't open input \"%s\"", argv[i]);
133 quiterr(errmsg);
134 }
135 if (i == argc-2 && freopen(argv[i+1], "w", stdout) == NULL) {
136 sprintf(errmsg, "can't open output \"%s\"", argv[i+1]);
137 quiterr(errmsg);
138 }
139 /* write header */
140 putthead(&head, NULL, stdout);
141 /* convert file */
142 if (greyscale)
143 biq(dither,ncolors,1,rasmap);
144 else
145 ciq(dither,ncolors,1,rasmap);
146 /* write data */
147 writetarga(&head, tarData, stdout);
148 }
149 quiterr(NULL);
150 userr:
151 fprintf(stderr,
152 "Usage: %s [-d][-c ncolors][-b][-g gamma] input [output]\n",
153 progname);
154 fprintf(stderr, " Or: %s -r [-g gamma] [input [output]]\n",
155 progname);
156 exit(1);
157 }
158
159
160 int
161 getint2(fp) /* get a 2-byte positive integer */
162 register FILE *fp;
163 {
164 register int b1, b2;
165
166 if ((b1 = getc(fp)) == EOF || (b2 = getc(fp)) == EOF)
167 quiterr("read error");
168
169 return(b1 | b2<<8);
170 }
171
172
173 putint2(i, fp) /* put a 2-byte positive integer */
174 register int i;
175 register FILE *fp;
176 {
177 putc(i&0xff, fp);
178 putc(i>>8&0xff, fp);
179 }
180
181
182 quiterr(err) /* print message and exit */
183 char *err;
184 {
185 if (err != NULL) {
186 fprintf(stderr, "%s: %s\n", progname, err);
187 exit(1);
188 }
189 exit(0);
190 }
191
192
193 eputs(s)
194 char *s;
195 {
196 fputs(s, stderr);
197 }
198
199
200 quit(code)
201 int code;
202 {
203 exit(code);
204 }
205
206
207 getthead(hp, ip, fp) /* read header from input */
208 struct hdStruct *hp;
209 char *ip;
210 register FILE *fp;
211 {
212 int nidbytes;
213
214 if ((nidbytes = getc(fp)) == EOF)
215 return(-1);
216 hp->mapType = getc(fp);
217 hp->dataType = getc(fp);
218 hp->mapOrig = getint2(fp);
219 hp->mapLength = getint2(fp);
220 hp->CMapBits = getc(fp);
221 hp->XOffset = getint2(fp);
222 hp->YOffset = getint2(fp);
223 hp->x = getint2(fp);
224 hp->y = getint2(fp);
225 hp->dataBits = getc(fp);
226 hp->imType = getc(fp);
227
228 if (ip != NULL)
229 if (nidbytes)
230 fread(ip, nidbytes, 1, fp);
231 else
232 *ip = '\0';
233 else if (nidbytes)
234 fseek(fp, (long)nidbytes, 1);
235
236 return(feof(fp) || ferror(fp) ? -1 : 0);
237 }
238
239
240 putthead(hp, ip, fp) /* write header to output */
241 struct hdStruct *hp;
242 char *ip;
243 register FILE *fp;
244 {
245 if (ip != NULL)
246 putc(strlen(ip), fp);
247 else
248 putc(0, fp);
249 putc(hp->mapType, fp);
250 putc(hp->dataType, fp);
251 putint2(hp->mapOrig, fp);
252 putint2(hp->mapLength, fp);
253 putc(hp->CMapBits, fp);
254 putint2(hp->XOffset, fp);
255 putint2(hp->YOffset, fp);
256 putint2(hp->x, fp);
257 putint2(hp->y, fp);
258 putc(hp->dataBits, fp);
259 putc(hp->imType, fp);
260
261 if (ip != NULL)
262 fputs(ip, fp);
263
264 return(ferror(fp) ? -1 : 0);
265 }
266
267
268 pic *
269 openinput(fname, h) /* open RADIANCE input file */
270 char *fname;
271 register struct hdStruct *h;
272 {
273 register pic *p;
274
275 p = (pic *)emalloc(sizeof(pic));
276 p->name = fname;
277 if (fname == NULL)
278 p->fp = stdin;
279 else if ((p->fp = fopen(fname, "r")) == NULL)
280 return(NULL);
281 /* discard header */
282 getheader(p->fp, NULL);
283 if (fgetresolu(&xmax, &ymax, p->fp) != (YMAJOR|YDECR))
284 quiterr("bad picture size");
285 p->nexty = 0;
286 p->bytes_line = 0; /* variable length lines */
287 p->pos.y = (long *)ecalloc(ymax, sizeof(long));
288 p->pos.y[0] = ftell(p->fp);
289 /* assign header */
290 h->textSize = 0;
291 h->mapType = CM_HASMAP;
292 h->dataType = IM_CMAP;
293 h->mapOrig = 0;
294 h->mapLength = 256;
295 h->CMapBits = 24;
296 h->XOffset = 0;
297 h->YOffset = 0;
298 h->x = xmax;
299 h->y = ymax;
300 h->dataBits = 8;
301 h->imType = 0;
302 /* allocate scanline */
303 inline = (COLR *)emalloc(xmax*sizeof(COLR));
304 /* allocate targa data */
305 tarData = taralloc(h);
306
307 return(p);
308 }
309
310
311 tg2ra(hp) /* targa file to RADIANCE file */
312 struct hdStruct *hp;
313 {
314 union {
315 BYTE c3[256][3];
316 BYTE c4[256][4];
317 } map;
318 COLR ctab[256];
319 COLR *scanline;
320 register int i, j;
321
322 /* get color table */
323 if ((hp->CMapBits==24 ? fread(map.c3, sizeof(map.c3), 1, stdin) :
324 fread(map.c4, sizeof(map.c4), 1, stdin)) != 1)
325 quiterr("error reading color table");
326 /* convert table */
327 for (i = hp->mapOrig; i < hp->mapOrig+hp->mapLength; i++)
328 if (hp->CMapBits == 24)
329 setcolr(ctab[i],
330 pow((map.c3[i][2]+.5)/256.,gamma),
331 pow((map.c3[i][1]+.5)/256.,gamma),
332 pow((map.c3[i][0]+.5)/256.,gamma));
333 else
334 setcolr(ctab[i],
335 pow((map.c4[i][3]+.5)/256.,gamma),
336 pow((map.c4[i][2]+.5)/256.,gamma),
337 pow((map.c4[i][1]+.5)/256.,gamma));
338
339 /* allocate targa data */
340 tarData = taralloc(hp);
341 /* get data */
342 readtarga(hp, tarData, stdin);
343 /* allocate input scanline */
344 scanline = (COLR *)emalloc(xmax*sizeof(COLR));
345 /* convert file */
346 for (i = ymax-1; i >= 0; i--) {
347 for (j = 0; j < xmax; j++)
348 copycolr(scanline[j], ctab[tarData[i*xmax+j]]);
349 if (fwritecolrs(scanline, xmax, stdout) < 0)
350 quiterr("error writing RADIANCE file");
351 }
352 free((char *)scanline);
353 free((char *)tarData);
354 }
355
356
357 picreadline3(y, l3) /* read in 3-byte scanline */
358 int y;
359 register rgbpixel *l3;
360 {
361 register BYTE *l4;
362 register int shift, c;
363 int i;
364
365 if (inpic->nexty != y) { /* find scanline */
366 if (inpic->bytes_line == 0) {
367 if (inpic->pos.y[y] == 0) {
368 while (inpic->nexty < y) {
369 if (freadcolrs(inline, xmax, inpic->fp) < 0)
370 quiterr("read error in picreadline3");
371 inpic->pos.y[++inpic->nexty] = ftell(inpic->fp);
372 }
373 } else if (fseek(inpic->fp, inpic->pos.y[y], 0) == EOF)
374 quiterr("seek error in picreadline3");
375 } else if (fseek(inpic->fp, y*inpic->bytes_line+inpic->pos.b, 0) == EOF)
376 quiterr("seek error in picreadline3");
377 } else if (inpic->bytes_line == 0 && inpic->pos.y[inpic->nexty] == 0)
378 inpic->pos.y[inpic->nexty] = ftell(inpic->fp);
379 if (freadcolrs(inline, xmax, inpic->fp) < 0) /* read scanline */
380 quiterr("read error in picreadline3");
381 inpic->nexty = y+1;
382 /* convert scanline */
383 for (l4=inline[0], i=xmax; i--; l4+=4, l3++) {
384 shift = l4[EXP] - COLXS;
385 if (shift >= 8) {
386 l3->r = l3->g = l3->b = 255;
387 } else if (shift <= -8) {
388 l3->r = l3->g = l3->b = 0;
389 } else if (shift > 0) {
390 c = l4[RED] << shift;
391 l3->r = c > 255 ? 255 : c;
392 c = l4[GRN] << shift;
393 l3->g = c > 255 ? 255 : c;
394 c = l4[BLU] << shift;
395 l3->b = c > 255 ? 255 : c;
396 } else if (shift < 0) {
397 l3->r = l4[RED] >> -shift;
398 l3->g = l4[GRN] >> -shift;
399 l3->b = l4[BLU] >> -shift;
400 } else {
401 l3->r = l4[RED];
402 l3->g = l4[GRN];
403 l3->b = l4[BLU];
404 }
405 }
406 }
407
408
409 picwriteline(y, l) /* save output scanline */
410 int y;
411 pixel *l;
412 {
413 bcopy(l, &tarData[(ymax-1-y)*xmax], xmax*sizeof(pixel));
414 }
415
416
417 writetarga(h, d, fp) /* write out targa data */
418 struct hdStruct *h;
419 pixel *d;
420 FILE *fp;
421 {
422 if (h->dataType == IM_CMAP) { /* uncompressed */
423 if (fwrite(d, h->x*sizeof(pixel), h->y, fp) != h->y)
424 quiterr("error writing targa file");
425 return;
426 }
427 quiterr("unsupported output type");
428 }
429
430
431 readtarga(h, data, fp) /* read in targa data */
432 struct hdStruct *h;
433 pixel *data;
434 FILE *fp;
435 {
436 register int cnt, c;
437 register pixel *dp;
438
439 if (h->dataType == IM_CMAP) { /* uncompressed */
440 if (fread(data, h->x*sizeof(pixel), h->y, fp) != h->y)
441 goto readerr;
442 return;
443 }
444 for (dp = data; dp < data+h->x*h->y; ) {
445 if ((c = getc(fp)) == EOF)
446 goto readerr;
447 cnt = (c & 0x7f) + 1;
448 if (c & 0x80) { /* repeated pixel */
449 if ((c = getc(fp)) == EOF)
450 goto readerr;
451 while (cnt--)
452 *dp++ = c;
453 } else /* non-repeating pixels */
454 while (cnt--) {
455 if ((c = getc(fp)) == EOF)
456 goto readerr;
457 *dp++ = c;
458 }
459 }
460 return;
461 readerr:
462 quiterr("error reading targa file");
463 }
464
465
466 picwritecm(cm) /* write out color map */
467 colormap cm;
468 {
469 register int i, j;
470
471 for (j = 0; j < 256; j++)
472 for (i = 2; i >= 0; i--)
473 putc(cm[i][j], stdout);
474 }
475
476
477 picreadcm(map) /* do gamma correction if requested */
478 colormap map;
479 {
480 register int i, val;
481
482 for (i = 0; i < 256; i++) {
483 val = pow(i/256.0, 1.0/gamma) * 256.0;
484 map[0][i] = map[1][i] = map[2][i] = val;
485 }
486 }