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

# User Rev Content
1 greg 1.10 /* Copyright (c) 1991 Regents of the University of California */
2 greg 1.1
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 greg 1.12 #include "resolu.h"
19    
20 greg 1.1 #include "pic.h"
21    
22     #include "targa.h"
23    
24 greg 1.4 #ifndef BSD
25     #define bcopy(s,d,n) (void)memcpy(d,s,n)
26     extern char *memcpy();
27     #endif
28 greg 1.1 /* 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 greg 1.11 double gamma = 2.2; /* gamma correction */
57 greg 1.1
58 greg 1.10 int bradj = 0; /* brightness adjustment */
59    
60 greg 1.1 pic *inpic;
61    
62     char *progname;
63    
64     char errmsg[128];
65    
66 greg 1.7 COLR *inl;
67 greg 1.1
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 greg 1.10 case 'e':
103     if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
104     goto userr;
105     bradj = atoi(argv[++i]);
106     break;
107 greg 1.1 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 greg 1.6 printargs(i, argv, stdout);
137 greg 1.9 fputformat(COLRFMT, stdout);
138 greg 1.1 putchar('\n');
139 greg 1.12 fprtresolu(xmax, ymax, stdout);
140 greg 1.1 /* convert file */
141     tg2ra(&head);
142     } else {
143 greg 1.10 if (i < argc-2 || (!greyscale && i > argc-1))
144 greg 1.1 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 greg 1.10 "Usage: %s [-d][-c ncolors][-b][-g gamma][-e +/-stops] input [output]\n",
167 greg 1.1 progname);
168 greg 1.10 fprintf(stderr, " Or: %s -r [-g gamma][-e +/-stops] [input [output]]\n",
169 greg 1.1 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 greg 1.4 fread((char *)ip, nidbytes, 1, fp);
245 greg 1.1 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 greg 1.9 /* get header info. */
296     if (checkheader(p->fp, COLRFMT, NULL) < 0 ||
297 greg 1.12 fgetresolu(&xmax, &ymax, p->fp) < 0)
298 greg 1.9 quiterr("bad picture format");
299 greg 1.1 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 greg 1.7 inl = (COLR *)emalloc(xmax*sizeof(COLR));
318 greg 1.1 /* 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 greg 1.12 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 greg 1.1 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 greg 1.10 if (bradj)
355     shiftcolrs(ctab, 256, bradj);
356 greg 1.1 /* 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 greg 1.3 register int i;
379 greg 1.1
380 greg 1.3 if (inpic->nexty != y) { /* find scanline */
381 greg 1.1 if (inpic->bytes_line == 0) {
382     if (inpic->pos.y[y] == 0) {
383     while (inpic->nexty < y) {
384 greg 1.7 if (freadcolrs(inl, xmax, inpic->fp) < 0)
385 greg 1.1 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 greg 1.7 if (freadcolrs(inl, xmax, inpic->fp) < 0) /* read scanline */
395 greg 1.1 quiterr("read error in picreadline3");
396     inpic->nexty = y+1;
397     /* convert scanline */
398 greg 1.10 normcolrs(inl, xmax, bradj);
399 greg 1.3 for (i = 0; i < xmax; i++) {
400 greg 1.7 l3[i].r = inl[i][RED];
401     l3[i].g = inl[i][GRN];
402     l3[i].b = inl[i][BLU];
403 greg 1.1 }
404     }
405    
406    
407     picwriteline(y, l) /* save output scanline */
408     int y;
409     pixel *l;
410     {
411 greg 1.4 bcopy((char *)l, (char *)&tarData[(ymax-1-y)*xmax], xmax*sizeof(pixel));
412 greg 1.1 }
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 greg 1.4 if (fwrite((char *)d,h->x*sizeof(pixel),h->y,fp) != h->y)
422 greg 1.1 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 greg 1.4 if (fread((char *)data,h->x*sizeof(pixel),h->y,fp) != h->y)
439 greg 1.1 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 greg 1.8 val = pow((i+0.5)/256.0, 1.0/gamma) * 256.0;
482 greg 1.1 map[0][i] = map[1][i] = map[2][i] = val;
483     }
484     }