ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t8.c
Revision: 1.10
Committed: Wed Aug 7 08:36:37 1991 UTC (32 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.9: +14 -6 lines
Log Message:
added -e +/-stops option

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