ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t8.c
Revision: 2.15
Committed: Tue Mar 20 18:45:04 2018 UTC (6 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R2
Changes since 2.14: +2 -1 lines
Log Message:
Added missing rtio.h include to redefine getc, putc, etc.

File Contents

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