ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t8.c
Revision: 1.9
Committed: Thu Apr 18 14:35:45 1991 UTC (33 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.8: +5 -4 lines
Log Message:
added format information to headers

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