ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t16.c
Revision: 2.6
Committed: Sat Feb 22 02:07:28 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 2.5: +9 -8 lines
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.6 static const char RCSid[] = "$Id$";
3 greg 1.1 #endif
4     /*
5     * ra_t16.c - program to convert between RADIANCE and
6     * Targa 16, 24 and 32-bit images.
7     *
8     * 11/2/88 Adapted from ra_t8.c
9     */
10    
11     #include <stdio.h>
12    
13 greg 2.3 #ifdef MSDOS
14     #include <fcntl.h>
15     #endif
16    
17 greg 2.6 #include <time.h>
18    
19 greg 2.3 #include <math.h>
20    
21 greg 1.1 #include "color.h"
22    
23 greg 1.15 #include "resolu.h"
24    
25 greg 1.5 #include "random.h"
26    
27 greg 1.1 #include "targa.h"
28    
29     #define goodpic(h) (((h)->dataType==IM_RGB || (h)->dataType==IM_CRGB) \
30     && ((h)->dataBits==16 || (h)->dataBits==24))
31    
32     #define taralloc(h) (unsigned char *)emalloc((h)->x*(h)->y*(h)->dataBits/8)
33    
34     #define readtarga(h,d,f) ((h)->dataBits==16 ? readt16(h,d,f) : \
35     readt24(h,d,f))
36    
37     #define writetarga(h,d,f) ((h)->dataBits==16 ? writet16(h,d,f) : \
38     writet24(h,d,f))
39    
40     extern char *ecalloc(), *emalloc();
41    
42 greg 2.4 double gamcor = 2.2; /* gamma correction */
43 greg 1.1
44 greg 1.13 int bradj = 0; /* brightness adjustment */
45    
46 greg 1.1 char *progname;
47    
48     char msg[128];
49    
50    
51     main(argc, argv)
52     int argc;
53     char *argv[];
54     {
55     struct hdStruct head;
56     int reverse = 0;
57     int i;
58 greg 2.3 #ifdef MSDOS
59     extern int _fmode;
60     _fmode = O_BINARY;
61     setmode(fileno(stdin), O_BINARY);
62     setmode(fileno(stdout), O_BINARY);
63     #endif
64 greg 1.1 progname = argv[0];
65    
66     head.dataBits = 16;
67     for (i = 1; i < argc; i++)
68     if (argv[i][0] == '-')
69     switch (argv[i][1]) {
70     case 'g':
71 greg 2.4 gamcor = atof(argv[++i]);
72 greg 1.1 break;
73     case 'r':
74     reverse = !reverse;
75     break;
76     case '2':
77     head.dataBits = 16;
78     break;
79     case '3':
80     head.dataBits = 24;
81     break;
82 greg 1.13 case 'e':
83     if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
84     goto userr;
85     bradj = atoi(argv[++i]);
86     break;
87 greg 1.1 default:
88     goto userr;
89     }
90     else
91     break;
92    
93     if (i < argc-2)
94     goto userr;
95     /* open input file */
96     if (i <= argc-1 && freopen(argv[i], "r", stdin) == NULL) {
97     sprintf(msg, "can't open input \"%s\"", argv[i]);
98     quiterr(msg);
99     }
100     /* open output file */
101     if (i == argc-2 && freopen(argv[i+1], "w", stdout) == NULL) {
102     sprintf(msg, "can't open output \"%s\"", argv[i+1]);
103     quiterr(msg);
104     }
105 greg 1.9 /* set gamma */
106 greg 2.4 setcolrgam(gamcor);
107 greg 1.1 /* convert */
108     if (reverse) {
109     /* get header */
110     if (getthead(&head, NULL, stdin) < 0)
111     quiterr("bad targa file");
112     if (!goodpic(&head))
113     quiterr("incompatible format");
114     /* put header */
115 greg 2.5 newheader("RADIANCE", stdout);
116 greg 1.7 printargs(i, argv, stdout);
117 greg 1.11 fputformat(COLRFMT, stdout);
118 greg 1.1 putchar('\n');
119 greg 1.15 fprtresolu(head.x, head.y, stdout);
120 greg 1.1 /* convert file */
121     tg2ra(&head);
122     } else {
123 greg 1.11 if (checkheader(stdin, COLRFMT, NULL) < 0 ||
124 greg 1.15 fgetresolu(&head.x, &head.y, stdin) < 0)
125 greg 1.1 quiterr("bad picture file");
126     /* assign header */
127     head.textSize = 0;
128     head.mapType = CM_NOMAP;
129     head.dataType = IM_RGB;
130     head.XOffset = 0;
131     head.YOffset = 0;
132     head.imType = 0;
133     /* write header */
134     putthead(&head, NULL, stdout);
135     /* convert file */
136     ra2tg(&head);
137     }
138     exit(0);
139     userr:
140 greg 1.13 fprintf(stderr, "Usage: %s [-2|-3|-r][-g gamma][-e +/-stops] [input [output]]\n",
141 greg 1.1 progname);
142     exit(1);
143     }
144    
145    
146     int
147     getint2(fp) /* get a 2-byte positive integer */
148     register FILE *fp;
149     {
150     register int b1, b2;
151    
152     if ((b1 = getc(fp)) == EOF || (b2 = getc(fp)) == EOF)
153     quiterr("read error");
154    
155     return(b1 | b2<<8);
156     }
157    
158    
159     putint2(i, fp) /* put a 2-byte positive integer */
160     register int i;
161     register FILE *fp;
162     {
163     putc(i&0xff, fp);
164     putc(i>>8&0xff, fp);
165     }
166    
167    
168     quiterr(err) /* print message and exit */
169     char *err;
170     {
171     fprintf(stderr, "%s: %s\n", progname, err);
172     exit(1);
173     }
174    
175    
176 greg 2.6 void
177 greg 1.1 eputs(s)
178     char *s;
179     {
180     fputs(s, stderr);
181     }
182    
183    
184 greg 2.6 void
185 greg 1.1 quit(code)
186     int code;
187     {
188     exit(code);
189     }
190    
191    
192     getthead(hp, ip, fp) /* read header from input */
193     struct hdStruct *hp;
194     char *ip;
195     register FILE *fp;
196     {
197     int nidbytes;
198    
199     if ((nidbytes = getc(fp)) == EOF)
200     return(-1);
201     hp->mapType = getc(fp);
202     hp->dataType = getc(fp);
203     hp->mapOrig = getint2(fp);
204     hp->mapLength = getint2(fp);
205     hp->CMapBits = getc(fp);
206     hp->XOffset = getint2(fp);
207     hp->YOffset = getint2(fp);
208     hp->x = getint2(fp);
209     hp->y = getint2(fp);
210     hp->dataBits = getc(fp);
211     hp->imType = getc(fp);
212    
213     if (ip != NULL)
214     if (nidbytes)
215 greg 1.6 fread((char *)ip, nidbytes, 1, fp);
216 greg 1.1 else
217     *ip = '\0';
218     else if (nidbytes)
219     fseek(fp, (long)nidbytes, 1);
220    
221     return(feof(fp) || ferror(fp) ? -1 : 0);
222     }
223    
224    
225     putthead(hp, ip, fp) /* write header to output */
226     struct hdStruct *hp;
227     char *ip;
228     register FILE *fp;
229     {
230     if (ip != NULL)
231     putc(strlen(ip), fp);
232     else
233     putc(0, fp);
234     putc(hp->mapType, fp);
235     putc(hp->dataType, fp);
236     putint2(hp->mapOrig, fp);
237     putint2(hp->mapLength, fp);
238     putc(hp->CMapBits, fp);
239     putint2(hp->XOffset, fp);
240     putint2(hp->YOffset, fp);
241     putint2(hp->x, fp);
242     putint2(hp->y, fp);
243     putc(hp->dataBits, fp);
244     putc(hp->imType, fp);
245    
246     if (ip != NULL)
247     fputs(ip, fp);
248    
249     return(ferror(fp) ? -1 : 0);
250     }
251    
252    
253     tg2ra(hp) /* targa file to RADIANCE file */
254     struct hdStruct *hp;
255     {
256 greg 1.9 COLR *scanline;
257 greg 1.1 unsigned char *tarData;
258     register int i, j;
259     /* skip color table */
260     if (hp->mapType == CM_HASMAP)
261     fseek(stdin, (long)hp->mapLength*hp->CMapBits/8, 1);
262     /* allocate targa data */
263     tarData = taralloc(hp);
264     /* get data */
265     readtarga(hp, tarData, stdin);
266     /* allocate input scanline */
267 greg 1.9 scanline = (COLR *)emalloc(hp->x*sizeof(COLR));
268 greg 1.1 /* convert file */
269     for (i = hp->y-1; i >= 0; i--) {
270     if (hp->dataBits == 16) {
271     register unsigned short *dp;
272     dp = (unsigned short *)tarData + i*hp->x;
273     for (j = 0; j < hp->x; j++) {
274 greg 1.9 scanline[j][RED] = *dp>>7 & 0xf8;
275     scanline[j][GRN] = *dp>>2 & 0xf8;
276     scanline[j][BLU] = *dp<<3 & 0xf8;
277 greg 1.1 dp++;
278     }
279     } else { /* hp->dataBits == 24 */
280     register unsigned char *dp;
281     dp = (unsigned char *)tarData + i*3*hp->x;
282     for (j = 0; j < hp->x; j++) {
283 greg 1.9 scanline[j][RED] = dp[2];
284     scanline[j][GRN] = dp[1];
285     scanline[j][BLU] = dp[0];
286 greg 1.1 dp += 3;
287     }
288     }
289 greg 1.9 gambs_colrs(scanline, hp->x);
290 greg 1.13 if (bradj)
291     shiftcolrs(scanline, hp->x, bradj);
292 greg 1.9 if (fwritecolrs(scanline, hp->x, stdout) < 0)
293 greg 1.1 quiterr("error writing RADIANCE file");
294     }
295 greg 2.6 free((void *)scanline);
296     free((void *)tarData);
297 greg 1.1 }
298    
299    
300     ra2tg(hp) /* convert radiance to targa file */
301     struct hdStruct *hp;
302     {
303 greg 1.3 register int i, j;
304 greg 1.1 unsigned char *tarData;
305 greg 1.9 COLR *inl;
306 greg 1.1 /* allocate space for data */
307 greg 1.9 inl = (COLR *)emalloc(hp->x*sizeof(COLR));
308 greg 1.1 tarData = taralloc(hp);
309     /* convert file */
310     for (j = hp->y-1; j >= 0; j--) {
311 greg 1.9 if (freadcolrs(inl, hp->x, stdin) < 0)
312 greg 1.1 quiterr("error reading RADIANCE file");
313 greg 1.13 if (bradj)
314     shiftcolrs(inl, hp->x, bradj);
315 greg 1.9 colrs_gambs(inl, hp->x);
316 greg 1.1 if (hp->dataBits == 16) {
317     register unsigned short *dp;
318 greg 1.12 register int v;
319 greg 1.1 dp = (unsigned short *)tarData + j*hp->x;
320     for (i = 0; i < hp->x; i++) {
321 greg 1.12 v = inl[i][RED] + (random()&7);
322     if (v > 255) v = 255;
323     *dp = (v&0xf8)<<7;
324     v = inl[i][GRN] + (random()&7);
325     if (v > 255) v = 255;
326     *dp |= (v&0xf8)<<2;
327     v = inl[i][BLU] + (random()&7);
328     if (v > 255) v = 255;
329     *dp++ |= v>>3;
330 greg 1.1 }
331     } else { /* hp->dataBits == 24 */
332     register unsigned char *dp;
333     dp = (unsigned char *)tarData + j*3*hp->x;
334     for (i = 0; i < hp->x; i++) {
335 greg 1.10 *dp++ = inl[i][BLU];
336     *dp++ = inl[i][GRN];
337 greg 1.9 *dp++ = inl[i][RED];
338 greg 1.1 }
339     }
340     }
341     /* write out targa data */
342     writetarga(hp, tarData, stdout);
343    
344 greg 2.6 free((void *)inl);
345     free((void *)tarData);
346 greg 1.1 }
347    
348    
349     writet24(h, d, fp) /* write out 24-bit targa data */
350     struct hdStruct *h;
351     unsigned char *d;
352     FILE *fp;
353     {
354     if (h->dataType == IM_RGB) { /* uncompressed */
355 greg 1.6 if (fwrite((char *)d, 3*h->x, h->y, fp) != h->y)
356 greg 1.1 quiterr("error writing targa file");
357     return;
358     }
359     quiterr("unsupported output type");
360     }
361    
362    
363     writet16(h, d, fp) /* write out 16-bit targa data */
364     struct hdStruct *h;
365     register unsigned short *d;
366     FILE *fp;
367     {
368     register int cnt;
369    
370     if (h->dataType == IM_RGB) { /* uncompressed */
371     for (cnt = h->x*h->y; cnt-- > 0; )
372     putint2(*d++, fp);
373     if (ferror(fp))
374     quiterr("error writing targa file");
375     return;
376     }
377     quiterr("unsupported output type");
378     }
379    
380    
381     readt24(h, data, fp) /* read in 24-bit targa data */
382     register struct hdStruct *h;
383     unsigned char *data;
384     FILE *fp;
385     {
386     register int cnt, c;
387     register unsigned char *dp;
388     int r, g, b;
389    
390     if (h->dataType == IM_RGB) { /* uncompressed */
391 greg 1.6 if (fread((char *)data, 3*h->x, h->y, fp) != h->y)
392 greg 1.1 goto readerr;
393     return;
394     }
395     for (dp = data; dp < data+3*h->x*h->y; ) {
396     if ((c = getc(fp)) == EOF)
397     goto readerr;
398     cnt = (c & 0x7f) + 1;
399     if (c & 0x80) { /* repeated pixel */
400 greg 1.2 b = getc(fp); g = getc(fp);
401     if ((r = getc(fp)) == EOF)
402 greg 1.1 goto readerr;
403     while (cnt--) {
404 greg 1.2 *dp++ = b;
405     *dp++ = g;
406 greg 1.1 *dp++ = r;
407     }
408     } else /* non-repeating pixels */
409     while (cnt--) {
410     *dp++ = getc(fp); *dp++ = getc(fp);
411 greg 1.2 if ((r = getc(fp)) == EOF)
412 greg 1.1 goto readerr;
413 greg 1.2 *dp++ = r;
414 greg 1.1 }
415     }
416     return;
417     readerr:
418     quiterr("error reading targa file");
419     }
420    
421    
422     readt16(h, data, fp) /* read in 16-bit targa data */
423     register struct hdStruct *h;
424     unsigned short *data;
425     FILE *fp;
426     {
427     register int cnt, c;
428     register unsigned short *dp;
429    
430     if (h->dataType == IM_RGB) { /* uncompressed */
431     dp = data;
432     for (cnt = h->x*h->y; cnt-- > 0; )
433     *dp++ = getint2(fp);
434     return;
435     }
436     for (dp = data; dp < data+h->x*h->y; ) {
437     if ((c = getc(fp)) == EOF)
438     goto readerr;
439     cnt = (c & 0x7f) + 1;
440     if (c & 0x80) { /* repeated pixel */
441     c = getint2(fp);
442     while (cnt--)
443     *dp++ = c;
444     } else /* non-repeating pixels */
445     while (cnt--)
446     *dp++ = getint2(fp);
447     }
448     return;
449     readerr:
450     quiterr("error reading targa file");
451     }