ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t8.c
Revision: 2.1
Committed: Tue Nov 12 16:05:11 1991 UTC (32 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.12: +0 -0 lines
Log Message:
updated revision number for release 2.0

File Contents

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