ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t8.c
Revision: 2.6
Committed: Sun Feb 27 10:17:23 1994 UTC (30 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.5: +1 -0 lines
Log Message:
Added new ID to first line of header and changed use of formatval

File Contents

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