ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t8.c
Revision: 2.13
Committed: Sun Mar 28 20:33:14 2004 UTC (20 years ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R7P2, rad3R7P1, rad4R0, rad3R6, rad3R6P1, rad3R8, rad3R9
Changes since 2.12: +76 -50 lines
Log Message:
Continued ANSIfication, and other fixes and clarifications.

File Contents

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