ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t8.c
Revision: 2.3
Committed: Fri Oct 9 15:24:21 1992 UTC (31 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.2: +25 -16 lines
Log Message:
Changes for 32-bit PC port

File Contents

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