ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t8.c
Revision: 1.10
Committed: Wed Aug 7 08:36:37 1991 UTC (32 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.9: +14 -6 lines
Log Message:
added -e +/-stops option

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