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

# User Rev Content
1 greg 1.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 greg 1.4 #ifndef BSD
23     #define bcopy(s,d,n) (void)memcpy(d,s,n)
24     extern char *memcpy();
25     #endif
26 greg 1.1 /* 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 greg 1.7 COLR *inl;
63 greg 1.1
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 greg 1.6 printargs(i, argv, stdout);
128 greg 1.9 fputformat(COLRFMT, stdout);
129 greg 1.1 putchar('\n');
130 greg 1.2 fputresolu(YMAJOR|YDECR, xmax, ymax, stdout);
131 greg 1.1 /* 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 greg 1.4 fread((char *)ip, nidbytes, 1, fp);
236 greg 1.1 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 greg 1.9 /* 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 greg 1.1 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 greg 1.7 inl = (COLR *)emalloc(xmax*sizeof(COLR));
309 greg 1.1 /* 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 greg 1.4 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 greg 1.1 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 greg 1.3 register int i;
367 greg 1.1
368 greg 1.3 if (inpic->nexty != y) { /* find scanline */
369 greg 1.1 if (inpic->bytes_line == 0) {
370     if (inpic->pos.y[y] == 0) {
371     while (inpic->nexty < y) {
372 greg 1.7 if (freadcolrs(inl, xmax, inpic->fp) < 0)
373 greg 1.1 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 greg 1.7 if (freadcolrs(inl, xmax, inpic->fp) < 0) /* read scanline */
383 greg 1.1 quiterr("read error in picreadline3");
384     inpic->nexty = y+1;
385     /* convert scanline */
386 greg 1.7 normcolrs(inl, xmax, 0);
387 greg 1.3 for (i = 0; i < xmax; i++) {
388 greg 1.7 l3[i].r = inl[i][RED];
389     l3[i].g = inl[i][GRN];
390     l3[i].b = inl[i][BLU];
391 greg 1.1 }
392     }
393    
394    
395     picwriteline(y, l) /* save output scanline */
396     int y;
397     pixel *l;
398     {
399 greg 1.4 bcopy((char *)l, (char *)&tarData[(ymax-1-y)*xmax], xmax*sizeof(pixel));
400 greg 1.1 }
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 greg 1.4 if (fwrite((char *)d,h->x*sizeof(pixel),h->y,fp) != h->y)
410 greg 1.1 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 greg 1.4 if (fread((char *)data,h->x*sizeof(pixel),h->y,fp) != h->y)
427 greg 1.1 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 greg 1.8 val = pow((i+0.5)/256.0, 1.0/gamma) * 256.0;
470 greg 1.1 map[0][i] = map[1][i] = map[2][i] = val;
471     }
472     }