ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t8.c
Revision: 2.5
Committed: Wed Nov 11 17:34:12 1992 UTC (31 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +6 -3 lines
Log Message:
fixed bug in greyscale conversion

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 printargs(i, argv, stdout);
129 fputformat(COLRFMT, stdout);
130 putchar('\n');
131 fprtresolu(xmax, ymax, stdout);
132 /* convert file */
133 tg2ra(&head);
134 } else {
135 if (getrhead(&head, stdin) < 0)
136 quiterr("bad Radiance input");
137 /* write header */
138 putthead(&head, NULL, stdout);
139 /* convert file */
140 if (greyscale)
141 getgrey(ncolors);
142 else
143 getmapped(ncolors, dither);
144 /* write data */
145 writetarga(&head, tarData, stdout);
146 }
147 quiterr(NULL);
148 userr:
149 fprintf(stderr,
150 "Usage: %s [-d][-c ncolors][-b][-g gamv][-e +/-stops] input [output]\n",
151 progname);
152 fprintf(stderr, " Or: %s -r [-g gamv][-e +/-stops] [input [output]]\n",
153 progname);
154 exit(1);
155 }
156
157
158 int
159 getint2(fp) /* get a 2-byte positive integer */
160 register FILE *fp;
161 {
162 register int b1, b2;
163
164 if ((b1 = getc(fp)) == EOF || (b2 = getc(fp)) == EOF)
165 quiterr("read error");
166
167 return(b1 | b2<<8);
168 }
169
170
171 putint2(i, fp) /* put a 2-byte positive integer */
172 register int i;
173 register FILE *fp;
174 {
175 putc(i&0xff, fp);
176 putc(i>>8&0xff, fp);
177 }
178
179
180 quiterr(err) /* print message and exit */
181 char *err;
182 {
183 if (err != NULL) {
184 fprintf(stderr, "%s: %s\n", progname, err);
185 exit(1);
186 }
187 exit(0);
188 }
189
190
191 eputs(s)
192 char *s;
193 {
194 fputs(s, stderr);
195 }
196
197
198 quit(code)
199 int code;
200 {
201 exit(code);
202 }
203
204
205 getthead(hp, ip, fp) /* read header from input */
206 struct hdStruct *hp;
207 char *ip;
208 register FILE *fp;
209 {
210 int nidbytes;
211
212 if ((nidbytes = getc(fp)) == EOF)
213 return(-1);
214 hp->mapType = getc(fp);
215 hp->dataType = getc(fp);
216 hp->mapOrig = getint2(fp);
217 hp->mapLength = getint2(fp);
218 hp->CMapBits = getc(fp);
219 hp->XOffset = getint2(fp);
220 hp->YOffset = getint2(fp);
221 hp->x = getint2(fp);
222 hp->y = getint2(fp);
223 hp->dataBits = getc(fp);
224 hp->imType = getc(fp);
225
226 if (ip != NULL)
227 if (nidbytes)
228 fread((char *)ip, nidbytes, 1, fp);
229 else
230 *ip = '\0';
231 else if (nidbytes)
232 fseek(fp, (long)nidbytes, 1);
233
234 return(feof(fp) || ferror(fp) ? -1 : 0);
235 }
236
237
238 putthead(hp, ip, fp) /* write header to output */
239 struct hdStruct *hp;
240 char *ip;
241 register FILE *fp;
242 {
243 if (ip != NULL)
244 putc(strlen(ip), fp);
245 else
246 putc(0, fp);
247 putc(hp->mapType, fp);
248 putc(hp->dataType, fp);
249 putint2(hp->mapOrig, fp);
250 putint2(hp->mapLength, fp);
251 putc(hp->CMapBits, fp);
252 putint2(hp->XOffset, fp);
253 putint2(hp->YOffset, fp);
254 putint2(hp->x, fp);
255 putint2(hp->y, fp);
256 putc(hp->dataBits, fp);
257 putc(hp->imType, fp);
258
259 if (ip != NULL)
260 fputs(ip, fp);
261
262 return(ferror(fp) ? -1 : 0);
263 }
264
265
266 getrhead(h, fp) /* load RADIANCE input file header */
267 register struct hdStruct *h;
268 FILE *fp;
269 {
270 /* get header info. */
271 if (checkheader(fp, COLRFMT, NULL) < 0 ||
272 fgetresolu(&xmax, &ymax, fp) < 0)
273 return(-1);
274 /* assign header */
275 h->textSize = 0;
276 h->mapType = CM_HASMAP;
277 h->dataType = IM_CMAP;
278 h->mapOrig = 0;
279 h->mapLength = 256;
280 h->CMapBits = 24;
281 h->XOffset = 0;
282 h->YOffset = 0;
283 h->x = xmax;
284 h->y = ymax;
285 h->dataBits = 8;
286 h->imType = 0;
287 /* allocate scanline */
288 inl = (COLR *)emalloc(xmax*sizeof(COLR));
289 /* allocate targa data */
290 tarData = taralloc(h);
291
292 return(0);
293 }
294
295
296 tg2ra(hp) /* targa file to RADIANCE file */
297 struct hdStruct *hp;
298 {
299 union {
300 BYTE c3[256][3];
301 BYTE c4[256][4];
302 } map;
303 COLR ctab[256];
304 COLR *scanline;
305 register int i, j;
306
307 /* get color table */
308 if ((hp->CMapBits==24 ? fread((char *)(map.c3+hp->mapOrig),
309 3*hp->mapLength,1,stdin) :
310 fread((char *)(map.c4+hp->mapOrig),
311 4*hp->mapLength,1,stdin)) != 1)
312 quiterr("error reading color table");
313 /* convert table */
314 for (i = hp->mapOrig; i < hp->mapOrig+hp->mapLength; i++)
315 if (hp->CMapBits == 24)
316 setcolr(ctab[i],
317 pow((map.c3[i][2]+.5)/256.,gamv),
318 pow((map.c3[i][1]+.5)/256.,gamv),
319 pow((map.c3[i][0]+.5)/256.,gamv));
320 else
321 setcolr(ctab[i],
322 pow((map.c4[i][3]+.5)/256.,gamv),
323 pow((map.c4[i][2]+.5)/256.,gamv),
324 pow((map.c4[i][1]+.5)/256.,gamv));
325 if (bradj)
326 shiftcolrs(ctab, 256, bradj);
327 /* allocate targa data */
328 tarData = taralloc(hp);
329 /* get data */
330 readtarga(hp, tarData, stdin);
331 /* allocate input scanline */
332 scanline = (COLR *)emalloc(xmax*sizeof(COLR));
333 /* convert file */
334 for (i = ymax-1; i >= 0; i--) {
335 for (j = 0; j < xmax; j++)
336 copycolr(scanline[j], ctab[tarData[i*xmax+j]]);
337 if (fwritecolrs(scanline, xmax, stdout) < 0)
338 quiterr("error writing RADIANCE file");
339 }
340 free((char *)scanline);
341 free((char *)tarData);
342 }
343
344
345 getmapped(nc, dith) /* read in and quantize image */
346 int nc; /* number of colors to use */
347 int dith; /* use dithering? */
348 {
349 long fpos;
350 register int y;
351
352 setcolrgam(gamv);
353 fpos = ftell(stdin);
354 new_histo(); /* build histogram */
355 for (y = ymax-1; y >= 0; y--) {
356 if (freadcolrs(inl, xmax, stdin) < 0)
357 quiterr("error reading Radiance input");
358 if (bradj)
359 shiftcolrs(inl, xmax, bradj);
360 colrs_gambs(inl, xmax);
361 cnt_colrs(inl, xmax);
362 }
363 if (fseek(stdin, fpos, 0) == EOF)
364 quiterr("Radiance input must be from a file");
365 new_clrtab(nc); /* map colors */
366 for (y = ymax-1; y >= 0; y--) {
367 if (freadcolrs(inl, xmax, stdin) < 0)
368 quiterr("error reading Radiance input");
369 if (bradj)
370 shiftcolrs(inl, xmax, bradj);
371 colrs_gambs(inl, xmax);
372 if (dith)
373 dith_colrs(tarData+y*xmax, inl, xmax);
374 else
375 map_colrs(tarData+y*xmax, inl, xmax);
376 }
377 }
378
379
380 getgrey(nc) /* read in and convert to greyscale image */
381 int nc; /* number of colors to use */
382 {
383 int y;
384 register BYTE *dp;
385 register int x;
386
387 setcolrgam(gamv);
388 dp = tarData+xmax*ymax;;
389 for (y = ymax-1; y >= 0; y--) {
390 if (freadcolrs(inl, xmax, stdin) < 0)
391 quiterr("error reading Radiance input");
392 if (bradj)
393 shiftcolrs(inl, xmax, bradj);
394 x = xmax;
395 while (x--)
396 inl[x][GRN] = normbright(inl[x]);
397 colrs_gambs(inl, xmax);
398 x = xmax;
399 if (nc < 256)
400 while (x--)
401 *--dp = ((long)inl[x][GRN]*nc+nc/2)>>8;
402 else
403 while (x--)
404 *--dp = inl[x][GRN];
405 }
406 for (x = 0; x < nc; x++)
407 clrtab[x][RED] = clrtab[x][GRN] =
408 clrtab[x][BLU] = ((long)x*256+128)/nc;
409 }
410
411
412 writetarga(h, d, fp) /* write out targa data */
413 struct hdStruct *h;
414 BYTE *d;
415 FILE *fp;
416 {
417 register int i, j;
418
419 for (i = 0; i < h->mapLength; i++) /* write color map */
420 for (j = 2; j >= 0; j--)
421 putc(clrtab[i][j], fp);
422 if (h->dataType == IM_CMAP) { /* uncompressed */
423 if (fwrite((char *)d,h->x*sizeof(BYTE),h->y,fp) != h->y)
424 quiterr("error writing targa file");
425 return;
426 }
427 quiterr("unsupported output type");
428 }
429
430
431 readtarga(h, data, fp) /* read in targa data */
432 struct hdStruct *h;
433 BYTE *data;
434 FILE *fp;
435 {
436 register int cnt, c;
437 register BYTE *dp;
438
439 if (h->dataType == IM_CMAP) { /* uncompressed */
440 if (fread((char *)data,h->x*sizeof(BYTE),h->y,fp) != h->y)
441 goto readerr;
442 return;
443 }
444 for (dp = data; dp < data+h->x*h->y; ) {
445 if ((c = getc(fp)) == EOF)
446 goto readerr;
447 cnt = (c & 0x7f) + 1;
448 if (c & 0x80) { /* repeated pixel */
449 if ((c = getc(fp)) == EOF)
450 goto readerr;
451 while (cnt--)
452 *dp++ = c;
453 } else /* non-repeating pixels */
454 while (cnt--) {
455 if ((c = getc(fp)) == EOF)
456 goto readerr;
457 *dp++ = c;
458 }
459 }
460 return;
461 readerr:
462 quiterr("error reading targa file");
463 }