ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t16.c
Revision: 2.7
Committed: Thu Jun 5 19:29:34 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.6: +5 -16 lines
Log Message:
Macros for setting binary file mode. Replacing MSDOS by _WIN32.

File Contents

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