ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pvalue.c
Revision: 2.42
Committed: Thu Mar 10 03:25:54 2022 UTC (2 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, HEAD
Changes since 2.41: +6 -1 lines
Log Message:
fix(pvalue): Remove NCOMP=, NROWS=, NCOLS= lines from header (either direction)

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.42 static const char RCSid[] = "$Id: pvalue.c,v 2.41 2022/02/04 20:11:49 greg Exp $";
3 greg 1.1 #endif
4     /*
5     * pvalue.c - program to print pixel values.
6     *
7     * 4/23/86
8     */
9    
10 greg 2.24 #include "platform.h"
11 greg 1.8 #include "standard.h"
12 greg 1.1 #include "color.h"
13 greg 1.8 #include "resolu.h"
14 schorsch 2.26 #include "view.h"
15 greg 2.15
16 greg 2.5 #define min(a,b) ((a)<(b)?(a):(b))
17 greg 1.1
18 greg 2.10 /* what to put out (also RED, GRN, BLU) */
19     #define ALL 3
20     #define BRIGHT 4
21    
22 greg 2.5 RESOLU picres; /* resolution of picture */
23 greg 1.6 int uniq = 0; /* print only unique values? */
24 greg 2.7 int doexposure = 0; /* exposure change? (>100 to print) */
25 greg 1.1 int dataonly = 0; /* data only format? */
26 greg 2.10 int putprim = ALL; /* what to put out */
27 greg 1.1 int reverse = 0; /* reverse conversion? */
28     int format = 'a'; /* input/output format */
29 greg 1.6 char *fmtid = "ascii"; /* format identifier for header */
30 greg 2.3 int header = 1; /* do header? */
31 greg 2.10 long skipbytes = 0; /* skip bytes in input? */
32 greg 2.23 int swapbytes = 0; /* swap bytes? */
33 greg 2.12 int interleave = 1; /* file is interleaved? */
34 greg 2.3 int resolution = 1; /* put/get resolution string? */
35 greg 2.7 int original = 0; /* convert to original values? */
36 greg 1.6 int wrongformat = 0; /* wrong input format? */
37 greg 2.5 double gamcor = 1.0; /* gamma correction */
38 greg 1.7
39 greg 2.30 RGBPRIMP outprims = stdprims; /* output primaries for reverse conversion */
40     RGBPRIMS myprims;
41    
42 greg 2.4 int ord[3] = {RED, GRN, BLU}; /* RGB ordering */
43     int rord[4]; /* reverse ordering */
44    
45 greg 1.5 COLOR exposure = WHTCOLOR;
46 greg 1.1
47     char *progname;
48    
49     FILE *fin;
50 greg 2.10 FILE *fin2 = NULL, *fin3 = NULL; /* for other color channels */
51 greg 1.1
52 schorsch 2.26
53     typedef int getfunc_t(COLOR col);
54     typedef int putfunc_t(COLOR col);
55     typedef double brightfunc_t(COLOR col);
56    
57     getfunc_t *getval;
58     putfunc_t *putval;
59     brightfunc_t *mybright;
60 greg 1.1
61 schorsch 2.25 static gethfunc checkhead;
62 schorsch 2.26 static brightfunc_t rgb_bright, xyz_bright;
63     static getfunc_t getbascii, getbint, getbdouble, getbfloat, getbbyte, getbword;
64     static getfunc_t getcascii, getcint, getcdouble, getcfloat, getcbyte, getcword;
65     static putfunc_t putbascii, putbint, putbdouble, putbfloat, putbbyte, putbword;
66     static putfunc_t putcascii, putcint, putcdouble, putcfloat, putcbyte, putcword;
67     static putfunc_t putpascii, putpint, putpdouble, putpfloat, putpbyte, putpword;
68    
69     static void set_io(void);
70     static void pixtoval(void);
71     static void valtopix(void);
72    
73    
74     static double
75     rgb_bright(
76     COLOR clr
77     )
78 greg 2.14 {
79     return(bright(clr));
80     }
81    
82 schorsch 2.26 static double
83     xyz_bright(
84     COLOR clr
85     )
86 greg 2.14 {
87     return(clr[CIEY]);
88     }
89    
90 schorsch 2.26 int
91     main(
92     int argc,
93     char **argv
94     )
95 greg 1.1 {
96 greg 2.36 const char *inpmode = "r";
97     double d, expval = 1.0;
98     int i;
99 greg 1.1
100     progname = argv[0];
101 schorsch 2.26 mybright = &rgb_bright; /* default */
102 greg 1.1
103     for (i = 1; i < argc; i++)
104 greg 1.8 if (argv[i][0] == '-' || argv[i][0] == '+')
105 greg 1.1 switch (argv[i][1]) {
106 greg 1.8 case 'h': /* header */
107     header = argv[i][0] == '+';
108 greg 1.1 break;
109 greg 2.3 case 'H': /* resolution string */
110     resolution = argv[i][0] == '+';
111     break;
112 greg 2.10 case 's': /* skip bytes in header */
113     skipbytes = atol(argv[++i]);
114     break;
115 greg 1.1 case 'u': /* unique values */
116 greg 1.8 uniq = argv[i][0] == '-';
117 greg 1.1 break;
118     case 'o': /* original values */
119 greg 1.8 original = argv[i][0] == '-';
120 greg 1.1 break;
121 greg 2.41 case 'O': /* original watts/sr/m^2 */
122     original = -(argv[i][0] == '-');
123     break;
124 greg 1.7 case 'g': /* gamma correction */
125 greg 2.7 gamcor = atof(argv[i+1]);
126 greg 1.8 if (argv[i][0] == '+')
127     gamcor = 1.0/gamcor;
128 greg 2.7 i++;
129 greg 1.7 break;
130 greg 2.7 case 'e': /* exposure correction */
131     d = atof(argv[i+1]);
132     if (argv[i+1][0] == '-' || argv[i+1][0] == '+')
133     d = pow(2.0, d);
134     if (argv[i][0] == '-')
135 greg 2.9 expval *= d;
136 greg 2.7 scalecolor(exposure, d);
137     doexposure++;
138     i++;
139     break;
140 greg 2.4 case 'R': /* reverse byte sequence */
141     if (argv[i][0] == '-') {
142     ord[0]=BLU; ord[1]=GRN; ord[2]=RED;
143     } else {
144     ord[0]=RED; ord[1]=GRN; ord[2]=BLU;
145     }
146     break;
147 greg 1.1 case 'r': /* reverse conversion */
148 greg 1.8 reverse = argv[i][0] == '-';
149 greg 1.1 break;
150 greg 2.12 case 'n': /* non-interleaved RGB */
151     interleave = argv[i][0] == '+';
152     break;
153 greg 1.1 case 'b': /* brightness values */
154 greg 2.10 putprim = argv[i][0] == '-' ? BRIGHT : ALL;
155 greg 1.1 break;
156 greg 2.30 case 'p': /* primary controls */
157 greg 2.10 switch (argv[i][2]) {
158 greg 2.30 /* these two options affect -r conversion */
159     case '\0':
160     myprims[RED][CIEX] = atof(argv[++i]);
161     myprims[RED][CIEY] = atof(argv[++i]);
162     myprims[GRN][CIEX] = atof(argv[++i]);
163     myprims[GRN][CIEY] = atof(argv[++i]);
164     myprims[BLU][CIEX] = atof(argv[++i]);
165     myprims[BLU][CIEY] = atof(argv[++i]);
166     myprims[WHT][CIEX] = atof(argv[++i]);
167     myprims[WHT][CIEY] = atof(argv[++i]);
168     outprims = myprims;
169     break;
170     case 'x': case 'X': outprims = NULL; break;
171     /* the following options affect +r only */
172 greg 2.10 case 'r': case 'R': putprim = RED; break;
173     case 'g': case 'G': putprim = GRN; break;
174     case 'b': case 'B': putprim = BLU; break;
175     default: goto unkopt;
176     }
177     break;
178 greg 1.1 case 'd': /* data only (no indices) */
179 greg 2.39 dataonly = (argv[i][0] == '-');
180 greg 1.1 switch (argv[i][2]) {
181     case '\0':
182     case 'a': /* ascii */
183     format = 'a';
184 greg 1.6 fmtid = "ascii";
185 greg 1.1 break;
186     case 'i': /* integer */
187 greg 1.6 format = 'i';
188     fmtid = "ascii";
189     break;
190 greg 1.1 case 'b': /* byte */
191 greg 1.8 dataonly = 1;
192 greg 1.6 format = 'b';
193     fmtid = "byte";
194     break;
195 greg 2.16 case 'W': /* 16-bit swapped */
196     swapbytes = 1;
197 greg 2.15 case 'w': /* 16-bit */
198     dataonly = 1;
199     format = 'w';
200     fmtid = "16-bit";
201     break;
202 greg 2.23 case 'F': /* swapped floats */
203     swapbytes = 1;
204 greg 1.1 case 'f': /* float */
205 greg 1.8 dataonly = 1;
206 greg 1.6 format = 'f';
207     fmtid = "float";
208     break;
209 greg 2.23 case 'D': /* swapped doubles */
210     swapbytes = 1;
211 greg 1.1 case 'd': /* double */
212 greg 1.8 dataonly = 1;
213 greg 1.6 format = 'd';
214     fmtid = "double";
215 greg 1.1 break;
216     default:
217     goto unkopt;
218     }
219     break;
220     case 'x': /* x resolution */
221 greg 2.6 case 'X': /* x resolution */
222 greg 2.3 resolution = 0;
223 greg 1.8 if (argv[i][0] == '-')
224 greg 2.14 picres.rt |= XDECR;
225 greg 1.8 picres.xr = atoi(argv[++i]);
226 greg 1.1 break;
227     case 'y': /* y resolution */
228 greg 2.6 case 'Y': /* y resolution */
229 greg 2.3 resolution = 0;
230 greg 1.8 if (argv[i][0] == '-')
231 greg 2.14 picres.rt |= YDECR;
232 greg 1.8 if (picres.xr == 0)
233 greg 2.14 picres.rt |= YMAJOR;
234 greg 1.8 picres.yr = atoi(argv[++i]);
235 greg 1.1 break;
236     default:
237     unkopt:
238     fprintf(stderr, "%s: unknown option: %s\n",
239     progname, argv[i]);
240     quit(1);
241     break;
242     }
243     else
244     break;
245 greg 1.6 /* recognize special formats */
246 schorsch 2.22 if (dataonly && format == 'b') {
247 greg 2.17 if (putprim == ALL)
248     fmtid = "24-bit_rgb";
249     else
250 greg 1.6 fmtid = "8-bit_grey";
251 schorsch 2.22 }
252     if (dataonly && format == 'w') {
253 greg 2.17 if (putprim == ALL)
254     fmtid = "48-bit_rgb";
255 greg 1.6 else
256 greg 2.15 fmtid = "16-bit_grey";
257 schorsch 2.22 }
258 greg 2.36 if (!reverse || (format != 'a') & (format != 'i'))
259     inpmode = "rb";
260 greg 2.4 /* assign reverse ordering */
261     rord[ord[0]] = 0;
262     rord[ord[1]] = 1;
263     rord[ord[2]] = 2;
264     /* get input */
265 greg 1.1 if (i == argc) {
266 greg 2.36 long n = skipbytes;
267     if (inpmode[1] == 'b')
268     SET_FILE_BINARY(stdin);
269     while (n-- > 0)
270     if (getchar() == EOF) {
271     fprintf(stderr,
272     "%s: cannot skip %ld bytes on standard input\n",
273     progname, skipbytes);
274     quit(1);
275     }
276 greg 1.1 fin = stdin;
277 greg 2.10 } else if (i < argc) {
278 greg 2.36 if ((fin = fopen(argv[i], inpmode)) == NULL) {
279 greg 1.1 fprintf(stderr, "%s: can't open file \"%s\"\n",
280     progname, argv[i]);
281     quit(1);
282     }
283 greg 2.17 if (reverse && putprim != BRIGHT && i == argc-3) {
284 greg 2.36 if ((fin2 = fopen(argv[i+1], inpmode)) == NULL) {
285 greg 2.10 fprintf(stderr, "%s: can't open file \"%s\"\n",
286     progname, argv[i+1]);
287     quit(1);
288     }
289 greg 2.36 if ((fin3 = fopen(argv[i+2], inpmode)) == NULL) {
290 greg 2.10 fprintf(stderr, "%s: can't open file \"%s\"\n",
291     progname, argv[i+2]);
292     quit(1);
293     }
294 greg 2.12 interleave = -1;
295 greg 2.10 } else if (i != argc-1)
296     fin = NULL;
297 greg 2.17 if (reverse && putprim != BRIGHT && !interleave) {
298 greg 2.36 fin2 = fopen(argv[i], inpmode);
299     fin3 = fopen(argv[i], inpmode);
300 greg 2.12 }
301 greg 2.36 if (skipbytes && (fseek(fin, skipbytes, SEEK_SET) || (fin2 != NULL &&
302     fseek(fin2, skipbytes, SEEK_SET) |
303     fseek(fin3, skipbytes, SEEK_SET)))) {
304 greg 2.12 fprintf(stderr, "%s: cannot skip %ld bytes on input\n",
305     progname, skipbytes);
306     quit(1);
307     }
308 greg 2.10 }
309     if (fin == NULL) {
310 greg 1.1 fprintf(stderr, "%s: bad # file arguments\n", progname);
311     quit(1);
312     }
313    
314     if (reverse) {
315 schorsch 2.18 SET_FILE_BINARY(stdout);
316 greg 1.6 /* get header */
317 greg 2.8 if (header) {
318 greg 2.38 getheader(fin, checkhead, stdout);
319     if (wrongformat) {
320     fprintf(stderr, "%s: wrong input format (expected %s)\n",
321     progname, fmtid);
322 greg 2.8 quit(1);
323     }
324 greg 2.10 if (fin2 != NULL) {
325     getheader(fin2, NULL, NULL);
326     getheader(fin3, NULL, NULL);
327     }
328 greg 2.8 } else
329     newheader("RADIANCE", stdout);
330 greg 2.3 /* get resolution */
331     if ((resolution && !fgetsresolu(&picres, fin)) ||
332     picres.xr <= 0 || picres.yr <= 0) {
333     fprintf(stderr, "%s: missing resolution\n", progname);
334     quit(1);
335     }
336 greg 2.10 if (resolution && fin2 != NULL) {
337     RESOLU pres2;
338     if (!fgetsresolu(&pres2, fin2) ||
339 greg 2.14 pres2.rt != picres.rt ||
340 greg 2.10 pres2.xr != picres.xr ||
341     pres2.yr != picres.yr ||
342     !fgetsresolu(&pres2, fin3) ||
343 greg 2.14 pres2.rt != picres.rt ||
344 greg 2.10 pres2.xr != picres.xr ||
345     pres2.yr != picres.yr) {
346     fprintf(stderr, "%s: resolution mismatch\n",
347     progname);
348     quit(1);
349     }
350     }
351 greg 1.6 /* add to header */
352     printargs(i, argv, stdout);
353 greg 2.9 if (expval < .99 || expval > 1.01)
354 greg 2.7 fputexpos(expval, stdout);
355 greg 2.30 if (outprims != NULL) {
356     if (outprims != stdprims)
357     fputprims(outprims, stdout);
358     fputformat(COLRFMT, stdout);
359 greg 2.41 } else { /* XYZ data */
360     if (original < 0) {
361     scalecolor(exposure, WHTEFFICACY);
362     doexposure++;
363     }
364 greg 2.30 fputformat(CIEFMT, stdout);
365 greg 2.41 }
366 greg 1.8 putchar('\n');
367 greg 2.3 fputsresolu(&picres, stdout); /* always put resolution */
368 greg 1.1 valtopix();
369     } else {
370 greg 2.36 if ((format != 'a') & (format != 'i'))
371 schorsch 2.18 SET_FILE_BINARY(stdout);
372 greg 1.1 /* get header */
373 greg 2.38 getheader(fin, checkhead, header ? stdout : (FILE *)NULL);
374 greg 1.6 if (wrongformat) {
375 greg 2.14 fprintf(stderr,
376     "%s: input not a Radiance RGBE picture\n",
377 greg 1.6 progname);
378     quit(1);
379     }
380 greg 2.3 if (!fgetsresolu(&picres, fin)) {
381     fprintf(stderr, "%s: missing resolution\n", progname);
382     quit(1);
383     }
384 greg 2.41 if (original < 0 && mybright == &xyz_bright) {
385     scalecolor(exposure, 1./WHTEFFICACY);
386     doexposure++;
387     }
388 greg 1.1 if (header) {
389     printargs(i, argv, stdout);
390 greg 2.39 printf("NCOMP=%d\n", putprim==ALL ? 3 : 1);
391     if (!resolution && dataonly && !uniq)
392     printf("NCOLS=%d\nNROWS=%d\n", scanlen(&picres),
393     numscans(&picres));
394 greg 2.9 if (expval < .99 || expval > 1.01)
395 greg 2.7 fputexpos(expval, stdout);
396 greg 2.37 if (swapbytes) {
397     if (nativebigendian())
398     puts("BigEndian=0");
399     else
400     puts("BigEndian=1");
401 greg 2.40 } else if ((format != 'a') & (format != 'i') &
402     (format != 'b'))
403 greg 2.37 fputendian(stdout);
404 greg 1.6 fputformat(fmtid, stdout);
405 greg 1.8 putchar('\n');
406 greg 1.1 }
407 greg 2.3 if (resolution) /* put resolution */
408     fputsresolu(&picres, stdout);
409 greg 1.1 pixtoval();
410     }
411    
412     quit(0);
413 schorsch 2.26 return 0; /* pro forma return */
414 greg 1.1 }
415    
416    
417 schorsch 2.25 static int
418     checkhead( /* deal with line from header */
419     char *line,
420     void *p
421     )
422 greg 1.1 {
423 greg 2.38 FILE *fout = (FILE *)p;
424 greg 2.34 char fmt[MAXFMTLEN];
425 greg 1.5 double d;
426     COLOR ctmp;
427 greg 2.37 int rv;
428 greg 1.5
429 greg 2.14 if (formatval(fmt, line)) {
430 greg 2.38 if (reverse)
431     wrongformat = strcmp(fmt, fmtid);
432     else if (!strcmp(fmt, CIEFMT))
433 greg 2.14 mybright = &xyz_bright;
434 greg 2.27 else if (!strcmp(fmt, COLRFMT))
435 greg 2.14 mybright = &rgb_bright;
436     else
437     wrongformat++;
438 greg 2.39 return(1);
439     }
440 greg 2.42 if (!strncmp(line,"NROWS=",6) ||
441     !strncmp(line,"NCOLS=",6) ||
442     !strncmp(line,"NCOMP=",6))
443     return(1);
444    
445 greg 2.39 if (original && isexpos(line)) {
446 greg 1.5 d = 1.0/exposval(line);
447     scalecolor(exposure, d);
448 greg 2.7 doexposure++;
449 greg 2.39 return(1);
450     }
451     if (original && iscolcor(line)) {
452 greg 1.5 colcorval(ctmp, line);
453 greg 1.7 setcolor(exposure, colval(exposure,RED)/colval(ctmp,RED),
454     colval(exposure,GRN)/colval(ctmp,GRN),
455     colval(exposure,BLU)/colval(ctmp,BLU));
456 greg 2.7 doexposure++;
457 greg 2.39 return(1);
458     }
459     if ((rv = isbigendian(line)) >= 0) {
460 greg 2.38 if (reverse)
461     swapbytes = (nativebigendian() != rv);
462 greg 2.39 return(1);
463     }
464     if (fout != NULL)
465 greg 2.38 fputs(line, fout);
466 gwlarson 2.13 return(0);
467 greg 1.1 }
468    
469    
470 schorsch 2.26 static void
471     pixtoval(void) /* convert picture to values */
472 greg 1.1 {
473 greg 2.35 COLOR *scanln;
474 greg 1.7 int dogamma;
475 greg 1.1 COLOR lastc;
476 schorsch 2.21 RREAL hv[2];
477 greg 2.12 int startprim, endprim;
478     long startpos;
479 greg 2.35 int x, y;
480 greg 1.1
481 greg 1.8 scanln = (COLOR *)malloc(scanlen(&picres)*sizeof(COLOR));
482 greg 1.1 if (scanln == NULL) {
483     fprintf(stderr, "%s: out of memory\n", progname);
484     quit(1);
485     }
486 greg 1.8 dogamma = gamcor < .95 || gamcor > 1.05;
487 greg 2.36 if ((putprim == ALL) & !interleave) {
488 greg 2.12 startprim = RED; endprim = BLU;
489     startpos = ftell(fin);
490     } else {
491     startprim = putprim; endprim = putprim;
492     }
493     for (putprim = startprim; putprim <= endprim; putprim++) {
494 greg 2.36 if (putprim != startprim && fseek(fin, startpos, SEEK_SET)) {
495 greg 2.12 fprintf(stderr, "%s: seek error on input file\n",
496     progname);
497 greg 1.1 quit(1);
498     }
499 greg 2.12 set_io();
500     setcolor(lastc, 0.0, 0.0, 0.0);
501     for (y = 0; y < numscans(&picres); y++) {
502     if (freadscan(scanln, scanlen(&picres), fin) < 0) {
503     fprintf(stderr, "%s: read error\n", progname);
504 greg 1.1 quit(1);
505     }
506 greg 2.12 for (x = 0; x < scanlen(&picres); x++) {
507 schorsch 2.22 if (uniq) {
508 greg 2.12 if ( colval(scanln[x],RED) ==
509     colval(lastc,RED) &&
510     colval(scanln[x],GRN) ==
511     colval(lastc,GRN) &&
512     colval(scanln[x],BLU) ==
513     colval(lastc,BLU) )
514     continue;
515     else
516     copycolor(lastc, scanln[x]);
517 schorsch 2.22 }
518 greg 2.12 if (doexposure)
519     multcolor(scanln[x], exposure);
520     if (dogamma)
521     setcolor(scanln[x],
522     pow(colval(scanln[x],RED), 1.0/gamcor),
523     pow(colval(scanln[x],GRN), 1.0/gamcor),
524     pow(colval(scanln[x],BLU), 1.0/gamcor));
525     if (!dataonly) {
526     pix2loc(hv, &picres, x, y);
527     printf("%7d %7d ",
528     (int)(hv[0]*picres.xr),
529     (int)(hv[1]*picres.yr));
530     }
531     if ((*putval)(scanln[x]) < 0) {
532     fprintf(stderr, "%s: write error\n",
533     progname);
534     quit(1);
535     }
536     }
537 greg 1.1 }
538     }
539 greg 2.14 free((void *)scanln);
540 greg 1.1 }
541    
542    
543 schorsch 2.26 static void
544     valtopix(void) /* convert values to a pixel file */
545 greg 1.1 {
546 greg 2.35 int dogamma;
547     COLOR *scanln;
548     COLR rgbe;
549     int x, y;
550 greg 1.1
551 greg 1.8 scanln = (COLOR *)malloc(scanlen(&picres)*sizeof(COLOR));
552 greg 1.1 if (scanln == NULL) {
553     fprintf(stderr, "%s: out of memory\n", progname);
554     quit(1);
555     }
556 greg 1.8 dogamma = gamcor < .95 || gamcor > 1.05;
557 greg 2.12 set_io();
558 greg 1.8 for (y = 0; y < numscans(&picres); y++) {
559     for (x = 0; x < scanlen(&picres); x++) {
560 greg 2.10 if (!dataonly) {
561 greg 1.1 fscanf(fin, "%*d %*d");
562 greg 2.10 if (fin2 != NULL) {
563     fscanf(fin2, "%*d %*d");
564     fscanf(fin3, "%*d %*d");
565     }
566     }
567 greg 2.11 if ((*getval)(scanln[x]) < 0) {
568 greg 1.1 fprintf(stderr, "%s: read error\n", progname);
569     quit(1);
570     }
571 greg 1.7 if (dogamma)
572     setcolor(scanln[x],
573 greg 1.8 pow(colval(scanln[x],RED), gamcor),
574     pow(colval(scanln[x],GRN), gamcor),
575     pow(colval(scanln[x],BLU), gamcor));
576 greg 2.7 if (doexposure)
577     multcolor(scanln[x], exposure);
578 greg 2.35 if (uniq) { /* uncompressed? */
579     setcolr(rgbe, scanln[x][RED],
580     scanln[x][GRN],
581     scanln[x][BLU]);
582     if (putbinary(rgbe, sizeof(COLR), 1, stdout) != 1)
583     goto writerr;
584     }
585 greg 1.1 }
586 greg 2.35 /* write scan if compressed */
587     if (!uniq && fwritescan(scanln, scanlen(&picres), stdout) < 0)
588     goto writerr;
589 greg 1.1 }
590 greg 2.14 free((void *)scanln);
591 greg 2.35 return;
592     writerr:
593     fprintf(stderr, "%s: write error\n", progname);
594     quit(1);
595 greg 1.1 }
596    
597    
598 greg 2.14 void
599 greg 1.1 quit(code)
600     int code;
601     {
602     exit(code);
603     }
604    
605    
606 schorsch 2.26 static int
607     getcascii( /* get an ascii color value from stream(s) */
608     COLOR col
609     )
610 greg 1.1 {
611 greg 2.5 double vd[3];
612 greg 1.1
613 greg 2.11 if (fin2 == NULL) {
614     if (fscanf(fin, "%lf %lf %lf", &vd[0], &vd[1], &vd[2]) != 3)
615 greg 2.10 return(-1);
616     } else {
617 greg 2.11 if (fscanf(fin, "%lf", &vd[0]) != 1 ||
618     fscanf(fin2, "%lf", &vd[1]) != 1 ||
619     fscanf(fin3, "%lf", &vd[2]) != 1)
620 greg 2.10 return(-1);
621     }
622 greg 2.4 setcolor(col, vd[rord[RED]], vd[rord[GRN]], vd[rord[BLU]]);
623 greg 1.1 return(0);
624     }
625    
626    
627 schorsch 2.26 static int
628     getcdouble( /* get a double color value from stream(s) */
629     COLOR col
630     )
631 greg 1.1 {
632 greg 2.5 double vd[3];
633 greg 1.1
634 greg 2.11 if (fin2 == NULL) {
635 greg 2.33 if (getbinary(vd, sizeof(double), 3, fin) != 3)
636 greg 2.10 return(-1);
637     } else {
638 greg 2.33 if (getbinary(vd, sizeof(double), 1, fin) != 1 ||
639     getbinary(vd+1, sizeof(double), 1, fin2) != 1 ||
640     getbinary(vd+2, sizeof(double), 1, fin3) != 1)
641 greg 2.10 return(-1);
642     }
643 greg 2.23 if (swapbytes)
644     swap64((char *)vd, 3);
645 greg 2.4 setcolor(col, vd[rord[RED]], vd[rord[GRN]], vd[rord[BLU]]);
646 greg 1.1 return(0);
647     }
648    
649    
650 schorsch 2.26 static int
651     getcfloat( /* get a float color value from stream(s) */
652     COLOR col
653     )
654 greg 1.1 {
655     float vf[3];
656    
657 greg 2.11 if (fin2 == NULL) {
658 greg 2.33 if (getbinary(vf, sizeof(float), 3, fin) != 3)
659 greg 2.10 return(-1);
660     } else {
661 greg 2.33 if (getbinary(vf, sizeof(float), 1, fin) != 1 ||
662     getbinary(vf+1, sizeof(float), 1, fin2) != 1 ||
663     getbinary(vf+2, sizeof(float), 1, fin3) != 1)
664 greg 2.10 return(-1);
665     }
666 greg 2.23 if (swapbytes)
667 greg 2.29 swap32((char *)vf, 3);
668 greg 2.4 setcolor(col, vf[rord[RED]], vf[rord[GRN]], vf[rord[BLU]]);
669 greg 1.1 return(0);
670     }
671    
672    
673 schorsch 2.26 static int
674     getcint( /* get an int color value from stream(s) */
675     COLOR col
676     )
677 greg 1.1 {
678     int vi[3];
679    
680 greg 2.11 if (fin2 == NULL) {
681     if (fscanf(fin, "%d %d %d", &vi[0], &vi[1], &vi[2]) != 3)
682 greg 2.10 return(-1);
683     } else {
684 greg 2.11 if (fscanf(fin, "%d", &vi[0]) != 1 ||
685     fscanf(fin2, "%d", &vi[1]) != 1 ||
686     fscanf(fin3, "%d", &vi[2]) != 1)
687 greg 2.10 return(-1);
688     }
689 greg 2.4 setcolor(col, (vi[rord[RED]]+.5)/256.,
690     (vi[rord[GRN]]+.5)/256., (vi[rord[BLU]]+.5)/256.);
691 greg 1.1 return(0);
692     }
693    
694    
695 schorsch 2.26 static int
696     getcbyte( /* get a byte color value from stream(s) */
697     COLOR col
698     )
699 greg 1.1 {
700 greg 2.31 uby8 vb[3];
701 greg 1.1
702 greg 2.11 if (fin2 == NULL) {
703 greg 2.33 if (getbinary(vb, sizeof(uby8), 3, fin) != 3)
704 greg 2.10 return(-1);
705     } else {
706 greg 2.33 if (getbinary(vb, sizeof(uby8), 1, fin) != 1 ||
707     getbinary(vb+1, sizeof(uby8), 1, fin2) != 1 ||
708     getbinary(vb+2, sizeof(uby8), 1, fin3) != 1)
709 greg 2.10 return(-1);
710     }
711 greg 2.4 setcolor(col, (vb[rord[RED]]+.5)/256.,
712     (vb[rord[GRN]]+.5)/256., (vb[rord[BLU]]+.5)/256.);
713 greg 1.1 return(0);
714     }
715    
716    
717 schorsch 2.26 static int
718     getcword( /* get a 16-bit color value from stream(s) */
719     COLOR col
720     )
721 greg 2.15 {
722     uint16 vw[3];
723    
724     if (fin2 == NULL) {
725 greg 2.33 if (getbinary(vw, sizeof(uint16), 3, fin) != 3)
726 greg 2.15 return(-1);
727     } else {
728 greg 2.33 if (getbinary(vw, sizeof(uint16), 1, fin) != 1 ||
729     getbinary(vw+1, sizeof(uint16), 1, fin2) != 1 ||
730     getbinary(vw+2, sizeof(uint16), 1, fin3) != 1)
731 greg 2.15 return(-1);
732     }
733 greg 2.16 if (swapbytes)
734 greg 2.29 swap16((char *)vw, 3);
735 greg 2.15 setcolor(col, (vw[rord[RED]]+.5)/65536.,
736     (vw[rord[GRN]]+.5)/65536., (vw[rord[BLU]]+.5)/65536.);
737     return(0);
738     }
739    
740    
741 schorsch 2.26 static int
742     getbascii( /* get an ascii brightness value from fin */
743     COLOR col
744     )
745 greg 1.1 {
746 greg 2.5 double vd;
747 greg 1.1
748 greg 2.11 if (fscanf(fin, "%lf", &vd) != 1)
749 greg 1.1 return(-1);
750     setcolor(col, vd, vd, vd);
751     return(0);
752     }
753    
754    
755 schorsch 2.26 static int
756     getbdouble( /* get a double brightness value from fin */
757     COLOR col
758     )
759 greg 1.1 {
760 greg 2.5 double vd;
761 greg 1.1
762 greg 2.33 if (getbinary(&vd, sizeof(double), 1, fin) != 1)
763 greg 1.1 return(-1);
764 greg 2.23 if (swapbytes)
765     swap64((char *)&vd, 1);
766 greg 1.1 setcolor(col, vd, vd, vd);
767     return(0);
768     }
769    
770    
771 schorsch 2.26 static int
772     getbfloat( /* get a float brightness value from fin */
773     COLOR col
774     )
775 greg 1.1 {
776     float vf;
777    
778 greg 2.33 if (getbinary(&vf, sizeof(float), 1, fin) != 1)
779 greg 1.1 return(-1);
780 greg 2.23 if (swapbytes)
781 greg 2.29 swap32((char *)&vf, 1);
782 greg 1.1 setcolor(col, vf, vf, vf);
783     return(0);
784     }
785    
786    
787 schorsch 2.26 static int
788     getbint( /* get an int brightness value from fin */
789     COLOR col
790     )
791 greg 1.1 {
792     int vi;
793 greg 2.5 double d;
794 greg 1.1
795 greg 2.11 if (fscanf(fin, "%d", &vi) != 1)
796 greg 1.1 return(-1);
797     d = (vi+.5)/256.;
798     setcolor(col, d, d, d);
799     return(0);
800     }
801    
802    
803 schorsch 2.26 static int
804     getbbyte( /* get a byte brightness value from fin */
805     COLOR col
806     )
807 greg 1.1 {
808 greg 2.31 uby8 vb;
809 greg 2.5 double d;
810 greg 1.1
811 greg 2.33 if (getbinary(&vb, sizeof(uby8), 1, fin) != 1)
812 greg 1.1 return(-1);
813     d = (vb+.5)/256.;
814     setcolor(col, d, d, d);
815     return(0);
816     }
817    
818    
819 schorsch 2.26 static int
820     getbword( /* get a 16-bit brightness value from fin */
821     COLOR col
822     )
823 greg 2.15 {
824     uint16 vw;
825     double d;
826    
827 greg 2.33 if (getbinary(&vw, sizeof(uint16), 1, fin) != 1)
828 greg 2.15 return(-1);
829 greg 2.16 if (swapbytes)
830 greg 2.29 swap16((char *)&vw, 1);
831 greg 2.15 d = (vw+.5)/65536.;
832     setcolor(col, d, d, d);
833     return(0);
834     }
835    
836    
837 schorsch 2.26 static int
838     putcascii( /* put an ascii color to stdout */
839     COLOR col
840     )
841 greg 1.1 {
842 greg 2.11 fprintf(stdout, "%15.3e %15.3e %15.3e\n",
843 greg 2.4 colval(col,ord[0]),
844     colval(col,ord[1]),
845     colval(col,ord[2]));
846 greg 1.1
847 greg 2.11 return(ferror(stdout) ? -1 : 0);
848 greg 1.1 }
849    
850    
851 schorsch 2.26 static int
852     putcfloat( /* put a float color to stdout */
853     COLOR col
854     )
855 greg 1.1 {
856     float vf[3];
857    
858 greg 2.4 vf[0] = colval(col,ord[0]);
859     vf[1] = colval(col,ord[1]);
860     vf[2] = colval(col,ord[2]);
861 greg 2.23 if (swapbytes)
862 greg 2.29 swap32((char *)vf, 3);
863 greg 2.33 putbinary(vf, sizeof(float), 3, stdout);
864 greg 1.1
865 greg 2.11 return(ferror(stdout) ? -1 : 0);
866 greg 1.1 }
867    
868    
869 schorsch 2.26 static int
870     putcdouble( /* put a double color to stdout */
871     COLOR col
872     )
873 greg 1.1 {
874 greg 2.5 double vd[3];
875 greg 1.1
876 greg 2.4 vd[0] = colval(col,ord[0]);
877     vd[1] = colval(col,ord[1]);
878     vd[2] = colval(col,ord[2]);
879 greg 2.23 if (swapbytes)
880     swap64((char *)vd, 3);
881 greg 2.33 putbinary(vd, sizeof(double), 3, stdout);
882 greg 1.1
883 greg 2.11 return(ferror(stdout) ? -1 : 0);
884 greg 1.1 }
885    
886    
887 schorsch 2.26 static int
888     putcint( /* put an int color to stdout */
889     COLOR col
890     )
891 greg 1.1 {
892 greg 2.11 fprintf(stdout, "%d %d %d\n",
893 greg 2.4 (int)(colval(col,ord[0])*256.),
894     (int)(colval(col,ord[1])*256.),
895     (int)(colval(col,ord[2])*256.));
896 greg 1.1
897 greg 2.11 return(ferror(stdout) ? -1 : 0);
898 greg 1.1 }
899    
900    
901 schorsch 2.26 static int
902     putcbyte( /* put a byte color to stdout */
903     COLOR col
904     )
905 greg 1.1 {
906 greg 2.15 long i;
907 greg 2.31 uby8 vb[3];
908 greg 1.1
909 greg 2.4 i = colval(col,ord[0])*256.;
910 greg 1.1 vb[0] = min(i,255);
911 greg 2.4 i = colval(col,ord[1])*256.;
912 greg 1.1 vb[1] = min(i,255);
913 greg 2.4 i = colval(col,ord[2])*256.;
914 greg 1.1 vb[2] = min(i,255);
915 greg 2.33 putbinary(vb, sizeof(uby8), 3, stdout);
916 greg 1.1
917 greg 2.11 return(ferror(stdout) ? -1 : 0);
918 greg 1.1 }
919    
920    
921 schorsch 2.26 static int
922     putcword( /* put a 16-bit color to stdout */
923     COLOR col
924     )
925 greg 2.15 {
926     long i;
927     uint16 vw[3];
928    
929     i = colval(col,ord[0])*65536.;
930     vw[0] = min(i,65535);
931     i = colval(col,ord[1])*65536.;
932     vw[1] = min(i,65535);
933     i = colval(col,ord[2])*65536.;
934     vw[2] = min(i,65535);
935 greg 2.16 if (swapbytes)
936 greg 2.29 swap16((char *)vw, 3);
937 greg 2.33 putbinary(vw, sizeof(uint16), 3, stdout);
938 greg 2.15
939     return(ferror(stdout) ? -1 : 0);
940     }
941    
942    
943 schorsch 2.26 static int
944     putbascii( /* put an ascii brightness to stdout */
945     COLOR col
946     )
947 greg 1.1 {
948 greg 2.14 fprintf(stdout, "%15.3e\n", (*mybright)(col));
949 greg 1.1
950 greg 2.11 return(ferror(stdout) ? -1 : 0);
951 greg 1.1 }
952    
953    
954 schorsch 2.26 static int
955     putbfloat( /* put a float brightness to stdout */
956     COLOR col
957     )
958 greg 1.1 {
959     float vf;
960    
961 greg 2.14 vf = (*mybright)(col);
962 greg 2.23 if (swapbytes)
963 greg 2.29 swap32((char *)&vf, 1);
964 greg 2.33 putbinary(&vf, sizeof(float), 1, stdout);
965 greg 1.1
966 greg 2.11 return(ferror(stdout) ? -1 : 0);
967 greg 1.1 }
968    
969    
970 schorsch 2.26 static int
971     putbdouble( /* put a double brightness to stdout */
972     COLOR col
973     )
974 greg 1.1 {
975 greg 2.5 double vd;
976 greg 1.1
977 greg 2.14 vd = (*mybright)(col);
978 greg 2.23 if (swapbytes)
979     swap64((char *)&vd, 1);
980 greg 2.33 putbinary(&vd, sizeof(double), 1, stdout);
981 greg 1.1
982 greg 2.11 return(ferror(stdout) ? -1 : 0);
983 greg 1.1 }
984    
985    
986 schorsch 2.26 static int
987     putbint( /* put an int brightness to stdout */
988     COLOR col
989     )
990 greg 1.1 {
991 greg 2.14 fprintf(stdout, "%d\n", (int)((*mybright)(col)*256.));
992 greg 1.1
993 greg 2.11 return(ferror(stdout) ? -1 : 0);
994 greg 1.1 }
995    
996    
997 schorsch 2.26 static int
998     putbbyte( /* put a byte brightness to stdout */
999     COLOR col
1000     )
1001 greg 1.1 {
1002 greg 2.35 int i;
1003 greg 2.31 uby8 vb;
1004 greg 1.1
1005 greg 2.14 i = (*mybright)(col)*256.;
1006 greg 1.1 vb = min(i,255);
1007 greg 2.33 putbinary(&vb, sizeof(uby8), 1, stdout);
1008 greg 1.1
1009 greg 2.11 return(ferror(stdout) ? -1 : 0);
1010 greg 1.1 }
1011    
1012    
1013 schorsch 2.26 static int
1014     putbword( /* put a 16-bit brightness to stdout */
1015     COLOR col
1016     )
1017 greg 2.15 {
1018     long i;
1019     uint16 vw;
1020    
1021     i = (*mybright)(col)*65536.;
1022     vw = min(i,65535);
1023 greg 2.16 if (swapbytes)
1024 greg 2.29 swap16((char *)&vw, 1);
1025 greg 2.33 putbinary(&vw, sizeof(uint16), 1, stdout);
1026 greg 2.15
1027     return(ferror(stdout) ? -1 : 0);
1028     }
1029    
1030    
1031 schorsch 2.26 static int
1032     putpascii( /* put an ascii primary to stdout */
1033     COLOR col
1034     )
1035 greg 2.10 {
1036 greg 2.11 fprintf(stdout, "%15.3e\n", colval(col,putprim));
1037 greg 2.10
1038 greg 2.11 return(ferror(stdout) ? -1 : 0);
1039 greg 2.10 }
1040    
1041    
1042 schorsch 2.26 static int
1043     putpfloat( /* put a float primary to stdout */
1044     COLOR col
1045     )
1046 greg 2.10 {
1047     float vf;
1048    
1049     vf = colval(col,putprim);
1050 greg 2.23 if (swapbytes)
1051 greg 2.29 swap32((char *)&vf, 1);
1052 greg 2.33 putbinary(&vf, sizeof(float), 1, stdout);
1053 greg 2.10
1054 greg 2.11 return(ferror(stdout) ? -1 : 0);
1055 greg 2.10 }
1056    
1057    
1058 schorsch 2.26 static int
1059     putpdouble( /* put a double primary to stdout */
1060     COLOR col
1061     )
1062 greg 2.10 {
1063     double vd;
1064    
1065     vd = colval(col,putprim);
1066 greg 2.23 if (swapbytes)
1067     swap64((char *)&vd, 1);
1068 greg 2.33 putbinary(&vd, sizeof(double), 1, stdout);
1069 greg 2.10
1070 greg 2.11 return(ferror(stdout) ? -1 : 0);
1071 greg 2.10 }
1072    
1073    
1074 schorsch 2.26 static int
1075     putpint( /* put an int primary to stdout */
1076     COLOR col
1077     )
1078 greg 2.10 {
1079 greg 2.11 fprintf(stdout, "%d\n", (int)(colval(col,putprim)*256.));
1080 greg 2.10
1081 greg 2.11 return(ferror(stdout) ? -1 : 0);
1082 greg 2.10 }
1083    
1084    
1085 schorsch 2.26 static int
1086     putpbyte( /* put a byte primary to stdout */
1087     COLOR col
1088     )
1089 greg 2.10 {
1090 greg 2.15 long i;
1091 greg 2.31 uby8 vb;
1092 greg 2.10
1093     i = colval(col,putprim)*256.;
1094     vb = min(i,255);
1095 greg 2.33 putbinary(&vb, sizeof(uby8), 1, stdout);
1096 greg 2.10
1097 greg 2.11 return(ferror(stdout) ? -1 : 0);
1098 greg 2.10 }
1099    
1100    
1101 schorsch 2.26 static int
1102     putpword( /* put a 16-bit primary to stdout */
1103     COLOR col
1104     )
1105 greg 2.15 {
1106     long i;
1107     uint16 vw;
1108    
1109     i = colval(col,putprim)*65536.;
1110     vw = min(i,65535);
1111 greg 2.16 if (swapbytes)
1112 greg 2.29 swap16((char *)&vw, 1);
1113 greg 2.33 putbinary(&vw, sizeof(uint16), 1, stdout);
1114 greg 2.15
1115     return(ferror(stdout) ? -1 : 0);
1116     }
1117    
1118    
1119 schorsch 2.26 static void
1120     set_io(void) /* set put and get functions */
1121 greg 1.1 {
1122     switch (format) {
1123     case 'a': /* ascii */
1124 greg 2.10 if (putprim == BRIGHT) {
1125 greg 1.1 getval = getbascii;
1126     putval = putbascii;
1127 greg 2.10 } else if (putprim != ALL) {
1128     getval = getbascii;
1129     putval = putpascii;
1130 greg 1.1 } else {
1131     getval = getcascii;
1132     putval = putcascii;
1133 greg 2.12 if (reverse && !interleave) {
1134     fprintf(stderr,
1135     "%s: ASCII input files must be interleaved\n",
1136     progname);
1137     quit(1);
1138     }
1139 greg 1.1 }
1140     return;
1141     case 'f': /* binary float */
1142 greg 2.10 if (putprim == BRIGHT) {
1143 greg 1.1 getval = getbfloat;
1144     putval = putbfloat;
1145 greg 2.10 } else if (putprim != ALL) {
1146     getval = getbfloat;
1147     putval = putpfloat;
1148 greg 1.1 } else {
1149     getval = getcfloat;
1150     putval = putcfloat;
1151 greg 2.12 if (reverse && !interleave) {
1152     if (fin2 == NULL)
1153     goto namerr;
1154     if (fseek(fin2,
1155 greg 2.36 (long)sizeof(float)*picres.xr*picres.yr, SEEK_CUR))
1156 greg 2.12 goto seekerr;
1157     if (fseek(fin3,
1158 greg 2.36 (long)sizeof(float)*2*picres.xr*picres.yr, SEEK_CUR))
1159 greg 2.12 goto seekerr;
1160     }
1161 greg 1.1 }
1162     return;
1163     case 'd': /* binary double */
1164 greg 2.10 if (putprim == BRIGHT) {
1165 greg 1.1 getval = getbdouble;
1166     putval = putbdouble;
1167 greg 2.10 } else if (putprim != ALL) {
1168     getval = getbdouble;
1169     putval = putpdouble;
1170 greg 1.1 } else {
1171     getval = getcdouble;
1172     putval = putcdouble;
1173 greg 2.12 if (reverse && !interleave) {
1174     if (fin2 == NULL)
1175     goto namerr;
1176     if (fseek(fin2,
1177 greg 2.36 (long)sizeof(double)*picres.xr*picres.yr, SEEK_CUR))
1178 greg 2.12 goto seekerr;
1179     if (fseek(fin3,
1180 greg 2.36 (long)sizeof(double)*2*picres.xr*picres.yr, SEEK_CUR))
1181 greg 2.12 goto seekerr;
1182     }
1183 greg 1.1 }
1184     return;
1185     case 'i': /* integer */
1186 greg 2.10 if (putprim == BRIGHT) {
1187 greg 1.1 getval = getbint;
1188     putval = putbint;
1189 greg 2.10 } else if (putprim != ALL) {
1190     getval = getbint;
1191     putval = putpint;
1192 greg 1.1 } else {
1193     getval = getcint;
1194     putval = putcint;
1195 greg 2.12 if (reverse && !interleave) {
1196     fprintf(stderr,
1197     "%s: integer input files must be interleaved\n",
1198     progname);
1199     quit(1);
1200     }
1201 greg 1.1 }
1202     return;
1203     case 'b': /* byte */
1204 greg 2.10 if (putprim == BRIGHT) {
1205 greg 1.1 getval = getbbyte;
1206     putval = putbbyte;
1207 greg 2.10 } else if (putprim != ALL) {
1208     getval = getbbyte;
1209     putval = putpbyte;
1210 greg 1.1 } else {
1211     getval = getcbyte;
1212     putval = putcbyte;
1213 greg 2.12 if (reverse && !interleave) {
1214     if (fin2 == NULL)
1215     goto namerr;
1216     if (fseek(fin2,
1217 greg 2.36 (long)sizeof(uby8)*picres.xr*picres.yr, SEEK_CUR))
1218 greg 2.12 goto seekerr;
1219     if (fseek(fin3,
1220 greg 2.36 (long)sizeof(uby8)*2*picres.xr*picres.yr, SEEK_CUR))
1221 greg 2.15 goto seekerr;
1222     }
1223     }
1224     return;
1225     case 'w': /* 16-bit */
1226     if (putprim == BRIGHT) {
1227     getval = getbword;
1228     putval = putbword;
1229     } else if (putprim != ALL) {
1230     getval = getbword;
1231     putval = putpword;
1232     } else {
1233     getval = getcword;
1234     putval = putcword;
1235     if (reverse && !interleave) {
1236     if (fin2 == NULL)
1237     goto namerr;
1238     if (fseek(fin2,
1239 greg 2.36 (long)sizeof(uint16)*picres.xr*picres.yr, SEEK_CUR))
1240 greg 2.15 goto seekerr;
1241     if (fseek(fin3,
1242 greg 2.36 (long)sizeof(uint16)*2*picres.xr*picres.yr, SEEK_CUR))
1243 greg 2.12 goto seekerr;
1244     }
1245 greg 1.1 }
1246     return;
1247     }
1248 schorsch 2.26 /* badopt: */ /* label not used */
1249 greg 2.12 fprintf(stderr, "%s: botched file type\n", progname);
1250     quit(1);
1251     namerr:
1252     fprintf(stderr, "%s: non-interleaved file(s) must be named\n",
1253     progname);
1254     quit(1);
1255     seekerr:
1256     fprintf(stderr, "%s: cannot seek on interleaved input file\n",
1257     progname);
1258     quit(1);
1259 greg 1.1 }