ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t8.c
Revision: 1.7
Committed: Mon Mar 12 15:14:46 1990 UTC (34 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.6: +8 -8 lines
Log Message:
changed "inline" to "inl" for compiler compatibility

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