ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t8.c
Revision: 2.8
Committed: Mon Nov 21 15:55:55 1994 UTC (29 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.7: +1 -1 lines
Log Message:
fixed Usage message to mention -n option

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