ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t16.c
Revision: 2.12
Committed: Sat Jun 7 05:09:46 2025 UTC (2 weeks, 4 days ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 2.11: +1 -2 lines
Log Message:
refactor: Put some declarations into "paths.h" and included in "platform.h"

File Contents

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