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

# User Rev Content
1 greg 2.3 /* Copyright (c) 1992 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 2.3 #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 greg 1.4 extern char *memcpy();
33     #endif
34 greg 1.1 /* 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 greg 2.3 #define goodpic(h) (my_imType(h) && my_mapType(h))
47     #define my_imType(h) (((h)->dataType==IM_CMAP || (h)->dataType==IM_CCMAP) \
48 greg 1.1 && (h)->dataBits==8 && (h)->imType==0)
49 greg 2.3 #define my_mapType(h) ((h)->mapType==CM_HASMAP && \
50 greg 1.1 ((h)->CMapBits==24 || (h)->CMapBits==32))
51    
52 greg 2.3 #define taralloc(h) (pixel *)emalloc((h)->x*(h)->y*sizeof(pixel))
53 greg 1.1
54     extern pic *openinput();
55    
56     extern char *ecalloc(), *emalloc();
57    
58     extern long ftell();
59    
60 greg 1.11 double gamma = 2.2; /* gamma correction */
61 greg 1.1
62 greg 1.10 int bradj = 0; /* brightness adjustment */
63    
64 greg 1.1 pic *inpic;
65    
66     char *progname;
67    
68     char errmsg[128];
69    
70 greg 1.7 COLR *inl;
71 greg 1.1
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 greg 2.3 struct hdStruct head;
83 greg 1.1 int dither = 1;
84     int reverse = 0;
85     int ncolors = 256;
86     int greyscale = 0;
87     int i;
88 greg 2.3 #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 greg 1.1 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 greg 1.10 case 'e':
112     if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
113     goto userr;
114     bradj = atoi(argv[++i]);
115     break;
116 greg 1.1 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 greg 1.6 printargs(i, argv, stdout);
146 greg 1.9 fputformat(COLRFMT, stdout);
147 greg 1.1 putchar('\n');
148 greg 1.12 fprtresolu(xmax, ymax, stdout);
149 greg 1.1 /* convert file */
150     tg2ra(&head);
151     } else {
152 greg 1.10 if (i < argc-2 || (!greyscale && i > argc-1))
153 greg 1.1 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 greg 1.10 "Usage: %s [-d][-c ncolors][-b][-g gamma][-e +/-stops] input [output]\n",
176 greg 1.1 progname);
177 greg 1.10 fprintf(stderr, " Or: %s -r [-g gamma][-e +/-stops] [input [output]]\n",
178 greg 1.1 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 greg 2.3 struct hdStruct *hp;
232 greg 1.1 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 greg 1.4 fread((char *)ip, nidbytes, 1, fp);
254 greg 1.1 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 greg 2.3 struct hdStruct *hp;
265 greg 1.1 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 greg 1.9 /* get header info. */
305     if (checkheader(p->fp, COLRFMT, NULL) < 0 ||
306 greg 1.12 fgetresolu(&xmax, &ymax, p->fp) < 0)
307 greg 1.9 quiterr("bad picture format");
308 greg 1.1 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 greg 1.7 inl = (COLR *)emalloc(xmax*sizeof(COLR));
327 greg 1.1 /* allocate targa data */
328     tarData = taralloc(h);
329    
330     return(p);
331     }
332    
333    
334     tg2ra(hp) /* targa file to RADIANCE file */
335 greg 2.3 struct hdStruct *hp;
336 greg 1.1 {
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 greg 1.12 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 greg 1.1 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 greg 1.10 if (bradj)
364     shiftcolrs(ctab, 256, bradj);
365 greg 1.1 /* 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 greg 1.3 register int i;
388 greg 1.1
389 greg 1.3 if (inpic->nexty != y) { /* find scanline */
390 greg 1.1 if (inpic->bytes_line == 0) {
391     if (inpic->pos.y[y] == 0) {
392     while (inpic->nexty < y) {
393 greg 1.7 if (freadcolrs(inl, xmax, inpic->fp) < 0)
394 greg 1.1 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 greg 1.7 if (freadcolrs(inl, xmax, inpic->fp) < 0) /* read scanline */
404 greg 1.1 quiterr("read error in picreadline3");
405     inpic->nexty = y+1;
406     /* convert scanline */
407 greg 1.10 normcolrs(inl, xmax, bradj);
408 greg 1.3 for (i = 0; i < xmax; i++) {
409 greg 1.7 l3[i].r = inl[i][RED];
410     l3[i].g = inl[i][GRN];
411     l3[i].b = inl[i][BLU];
412 greg 1.1 }
413     }
414    
415    
416     picwriteline(y, l) /* save output scanline */
417     int y;
418     pixel *l;
419     {
420 greg 1.4 bcopy((char *)l, (char *)&tarData[(ymax-1-y)*xmax], xmax*sizeof(pixel));
421 greg 1.1 }
422    
423    
424     writetarga(h, d, fp) /* write out targa data */
425 greg 2.3 struct hdStruct *h;
426 greg 1.1 pixel *d;
427     FILE *fp;
428     {
429     if (h->dataType == IM_CMAP) { /* uncompressed */
430 greg 1.4 if (fwrite((char *)d,h->x*sizeof(pixel),h->y,fp) != h->y)
431 greg 1.1 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 greg 2.3 struct hdStruct *h;
440 greg 1.1 pixel *data;
441     FILE *fp;
442     {
443     register int cnt, c;
444     register pixel *dp;
445    
446     if (h->dataType == IM_CMAP) { /* uncompressed */
447 greg 1.4 if (fread((char *)data,h->x*sizeof(pixel),h->y,fp) != h->y)
448 greg 1.1 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 greg 1.8 val = pow((i+0.5)/256.0, 1.0/gamma) * 256.0;
491 greg 1.1 map[0][i] = map[1][i] = map[2][i] = val;
492     }
493     }