ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/d48c.c
Revision: 1.5
Committed: Sun Mar 28 20:33:13 2004 UTC (20 years, 1 month ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R6P1, rad3R6
Changes since 1.4: +59 -29 lines
Log Message:
Continued ANSIfication, and other fixes and clarifications.

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 1.5 static const char RCSid[] = "$Id: d48c.c,v 1.4 2003/10/27 10:24:51 schorsch Exp $";
3 greg 1.1 #endif
4 greg 1.2 /*
5 greg 1.1 * d48c.c - driver for dicomed D48 film recorder w/ color optics.
6     *
7     * 3/26/87
8     */
9    
10     #include <stdio.h>
11 schorsch 1.5 #include <string.h>
12 greg 1.1 #include <signal.h>
13    
14 schorsch 1.5 #include "paths.h"
15 schorsch 1.4 #include "rterror.h"
16 greg 1.1 #include "color.h"
17    
18    
19     #define HSIZE 4096 /* device width */
20     #define VSIZE 4096 /* device height */
21    
22     #define MAXMULT 15 /* maximum element size */
23    
24     /* dicomed commands */
25     #define O_ECS 0 /* encoded command select */
26     #define O_CONF 03400 /* configuration code */
27     #define O_FES 020000 /* function element select */
28     #define O_VPA 040000 /* vector or position absolute */
29     #define O_ICS 0100000 /* initial condition select */
30     #define O_PES 0120000 /* point element select */
31    
32     /* ECS commands */
33     #define ECS_FA 07 /* film advance */
34     #define ECS_RED 011 /* select red filter */
35     #define ECS_GRN 012 /* select green filter */
36     #define ECS_BLU 014 /* select blue filter */
37     #define ECS_NEU 017 /* select neutral filter */
38     #define ECS_RAS 020 /* select raster mode */
39     #define ECS_COL 022 /* select color mode */
40     #define ECS_BW 023 /* select black and white mode */
41     #define ECS_BT 024 /* bypass translation tables */
42    
43     /* FES functions */
44     #define FES_RE 030000 /* raster element */
45     #define FES_RL 0170000 /* run length */
46    
47     /* ICS fields */
48     #define ICS_HVINT 040 /* interchange h and v axes */
49     #define ICS_VREV 0100 /* reverse v axis direction */
50     #define ICS_HREV 0200 /* reverse h axis direction */
51    
52     int nrows; /* number of rows for output */
53     int ncols; /* number of columns for output */
54    
55     int mult; /* number of h/v points per elem. */
56    
57     int hhome; /* offset for h */
58     int vhome; /* offset for v */
59    
60     /* dicomed configurations */
61     #define C_POLAROID 0 /* polaroid print */
62     #define C_35FRES 1 /* 35mm full resolution */
63     #define C_35FFRA 2 /* 35mm full frame */
64     #define C_SHEET 3 /* 4X5 sheet film */
65    
66     #define NCONF 4 /* number of configurations */
67    
68     struct config {
69     char *name; /* configuration name */
70     int ccode; /* configuration code */
71     int icsfield; /* initial condition select */
72     int hbeg, vbeg; /* coord. origin */
73     int hsiz, vsiz; /* dimensions */
74     } ctab[NCONF] = {
75     { "polaroid", 11, ICS_HVINT|ICS_VREV, 0, 0, 4096, 4096 },
76     { "35r", 5, 0, 0, 0, 4096, 4096 },
77     { "35f", 7, 0, 39, 692, 4018, 2712 },
78     { "sheet", 10, ICS_HVINT|ICS_VREV, 0, 0, 4096, 4096 },
79     };
80    
81     #define NEU 3 /* neutral color */
82    
83     struct filter {
84     float cv[3]; /* filter color vector */
85     char *fn; /* file name for this color */
86     FILE *fp; /* stream for this color */
87     } ftab[4] = {
88     { {1.0, 0.0, 0.0}, NULL, NULL }, /* red */
89     { {0.0, 1.0, 0.0}, NULL, NULL }, /* green */
90     { {0.0, 0.0, 1.0}, NULL, NULL }, /* blue */
91     { {0.3, 0.59, 0.11}, NULL, NULL }, /* neutral */
92     };
93    
94     #define f_val(col,f) ( colval(col,0)*ftab[f].cv[0] + \
95     colval(col,1)*ftab[f].cv[1] + \
96     colval(col,2)*ftab[f].cv[2] )
97    
98     float neumap[] = { /* neutral map, log w/ E6 */
99     .0, .0,
100     .0004, .059,
101     .0008, .122,
102     .0018, .184,
103     .0033, .247,
104     .0061, .310,
105     .0119, .373,
106     .0202, .435,
107     .0373, .498,
108     .065, .561,
109     .113, .624,
110     .199, .686,
111     .300, .749,
112     .432, .812,
113     .596, .875,
114     .767, .937,
115     1.000, 1.000,
116     };
117    
118    
119     int docolor = 1; /* color? */
120    
121     int cftype = C_35FFRA; /* configuration type */
122    
123     char *progname; /* program name */
124    
125 schorsch 1.5 static void settype(char *cname);
126     static void dofile(char *fname);
127     static void d_init(void);
128     static void scanout(COLOR *scan, int y);
129     static void d_done(void);
130     static void runlength(COLOR *scan, int f);
131     static double mapfilter(COLOR col, int f);
132     static void transfer(FILE *fin, FILE *fout);
133    
134 greg 1.1
135 schorsch 1.5 int
136     main(
137     int argc,
138     char *argv[]
139     )
140 greg 1.1 {
141     int i;
142    
143     if (signal(SIGINT, quit) == SIG_IGN)
144     signal(SIGINT, SIG_IGN);
145 schorsch 1.4 #ifdef SIGHUP
146 greg 1.1 if (signal(SIGHUP, quit) == SIG_IGN)
147     signal(SIGINT, SIG_IGN);
148 schorsch 1.4 #endif
149 greg 1.1 signal(SIGTERM, quit);
150 schorsch 1.4 #ifdef SIGPIPE
151 greg 1.1 signal(SIGPIPE, quit);
152 schorsch 1.4 #endif
153     #ifdef SIGXCPU
154 greg 1.1 signal(SIGXCPU, quit);
155 schorsch 1.4 #endif
156     #ifdef SIGXFSZ
157 greg 1.1 signal(SIGXFSZ, quit);
158 schorsch 1.4 #endif
159 greg 1.1
160     progname = argv[0];
161    
162     for (i = 1; i < argc && argv[i][0] == '-'; i++)
163     switch (argv[i][1]) {
164     case 'c': /* color */
165     docolor = 1;
166     break;
167     case 'b': /* black and white */
168     docolor = 0;
169     break;
170     case 't': /* type */
171     settype(argv[++i]);
172     break;
173     default:
174     fprintf(stderr, "%s: Unknown option: %s\n",
175     progname, argv[i]);
176     quit(1);
177     break;
178     }
179    
180     if (i < argc)
181     for ( ; i < argc; i++)
182     dofile(argv[i]);
183     else
184     dofile(NULL);
185    
186     quit(0);
187 schorsch 1.5 return 0; /* pro forma return */
188 greg 1.1 }
189    
190    
191 schorsch 1.5 static void
192     settype( /* set configuration type */
193     char *cname
194     )
195 greg 1.1 {
196     for (cftype = 0; cftype < NCONF; cftype++)
197     if (!strcmp(cname, ctab[cftype].name))
198     return;
199    
200     fprintf(stderr, "%s: Unknown type: %s\n", progname, cname);
201     quit(1);
202     }
203    
204    
205 greg 1.3 void
206 schorsch 1.4 quit(int code) /* quit program */
207 greg 1.1 {
208     int i;
209    
210     for (i = 0; i < 4; i++)
211     if (ftab[i].fn != NULL)
212     unlink(ftab[i].fn);
213     exit(code);
214     }
215    
216    
217 schorsch 1.5 static void
218     dofile( /* convert file to dicomed format */
219     char *fname
220     )
221 greg 1.1 {
222     FILE *fin;
223     char sbuf[128];
224     COLOR scanline[HSIZE];
225     int i;
226    
227     if (fname == NULL) {
228     fin = stdin;
229     fname = "<stdin>";
230     } else if ((fin = fopen(fname, "r")) == NULL) {
231     fprintf(stderr, "%s: Cannot open: %s\n", progname, fname);
232     quit(1);
233     }
234     /* discard header */
235     while (fgets(sbuf, sizeof(sbuf), fin) != NULL && sbuf[0] != '\n')
236     ;
237     /* get picture size */
238     if (fgets(sbuf, sizeof(sbuf), fin) == NULL ||
239     sscanf(sbuf, "-Y %d +X %d\n", &nrows, &ncols) != 2) {
240     fprintf(stderr, "%s: Bad picture size: %s\n", progname, fname);
241     quit(1);
242     }
243    
244     mult = ctab[cftype].hsiz / ncols;
245     if (ctab[cftype].vsiz / nrows < mult)
246     mult = ctab[cftype].vsiz / nrows;
247    
248     if (mult < 1) {
249     fprintf(stderr, "%s: Resolution mismatch: %s\n",
250     progname, fname);
251     quit(1);
252     }
253     if (mult > MAXMULT)
254     mult = MAXMULT; /* maximum element size */
255    
256     hhome = ctab[cftype].hbeg + (ctab[cftype].hsiz - ncols*mult)/2;
257     vhome = ctab[cftype].vbeg + (ctab[cftype].vsiz - nrows*mult)/2;
258    
259     d_init();
260    
261     for (i = nrows-1; i >= 0; i--) {
262     if (freadscan(scanline, ncols, fin) < 0) {
263     fprintf(stderr, "%s: Read error in row %d: %s\n",
264     progname, i, fname);
265     quit(1);
266     }
267     scanout(scanline, i);
268     }
269    
270     d_done();
271    
272     fclose(fin);
273     }
274    
275    
276 schorsch 1.5 static void
277     d_init(void) /* set up dicomed, files */
278 greg 1.1 {
279 schorsch 1.5 //char *mktemp();
280 greg 1.1 /* initial condition select */
281     putw(O_ICS|ctab[cftype].icsfield, stdout);
282     /* configuration code */
283     putw(O_CONF|ctab[cftype].ccode, stdout);
284     /* select raster mode */
285     putw(O_ECS|ECS_RAS, stdout);
286     /* color or black and white */
287     putw(O_ECS|(docolor?ECS_COL:ECS_BW), stdout);
288     /* bypass translation tables */
289     putw(O_ECS|ECS_BT, stdout);
290     /* point element select */
291     putw(O_PES|mult<<9|010, stdout);
292     putw(mult<<9|010, stdout);
293     putw(mult<<4|mult, stdout);
294    
295     if (docolor) { /* color output */
296     /* set up red file */
297     if (ftab[RED].fn == NULL)
298     ftab[RED].fn = mktemp(TEMPLATE);
299     if ((ftab[RED].fp = fopen(ftab[RED].fn, "w+")) == NULL) {
300     fprintf(stderr, "%s: Cannot open: %s\n",
301     progname, ftab[RED].fn);
302     quit(1);
303     }
304     putw(O_ECS|ECS_RED, ftab[RED].fp); /* red filter */
305     putw(O_VPA, ftab[RED].fp); /* home */
306     putw(hhome<<3, ftab[RED].fp);
307     putw(vhome<<3, ftab[RED].fp);
308     /* set up green file */
309     ftab[GRN].fp = stdout;
310     putw(O_ECS|ECS_GRN, ftab[GRN].fp); /* green filter */
311     putw(O_VPA, ftab[GRN].fp); /* home */
312     putw(hhome<<3, ftab[GRN].fp);
313     putw(vhome<<3, ftab[GRN].fp);
314     /* set up blue file */
315     if (ftab[BLU].fn == NULL)
316     ftab[BLU].fn = mktemp(TEMPLATE);
317     if ((ftab[BLU].fp = fopen(ftab[BLU].fn, "w+")) == NULL) {
318     fprintf(stderr, "%s: Cannot open: %s\n",
319     progname, ftab[BLU].fn);
320     quit(1);
321     }
322     putw(O_ECS|ECS_BLU, ftab[BLU].fp); /* blue filter */
323     putw(O_VPA, ftab[BLU].fp); /* home */
324     putw(hhome<<3, ftab[BLU].fp);
325     putw(vhome<<3, ftab[BLU].fp);
326    
327     } else { /* black and white */
328     ftab[NEU].fp = stdout;
329     putw(O_ECS|ECS_NEU, ftab[NEU].fp); /* neutral filter */
330     putw(O_VPA, ftab[NEU].fp); /* home */
331     putw(hhome<<3, ftab[NEU].fp);
332     putw(vhome<<3, ftab[NEU].fp);
333     }
334     }
335    
336    
337 schorsch 1.5 static void
338     scanout( /* output scan line */
339     COLOR *scan,
340     int y
341     )
342 greg 1.1 {
343     int i;
344     /* uses horiz. flyback */
345     if (docolor)
346     for (i = 0; i < 3; i++)
347     runlength(scan, i);
348     else
349     runlength(scan, NEU);
350     }
351    
352    
353 schorsch 1.5 static void
354     d_done(void) /* flush files, finish frame */
355 greg 1.1 {
356     if (docolor) {
357     transfer(ftab[RED].fp, stdout);
358     transfer(ftab[BLU].fp, stdout);
359     }
360     putw(O_ECS|ECS_FA, stdout); /* film advance */
361     fflush(stdout);
362     if (ferror(stdout)) {
363     fprintf(stderr, "%s: Write error: <stdout>\n", progname);
364     quit(1);
365     }
366     }
367    
368    
369 schorsch 1.5 static void
370     runlength( /* do scanline for filter f */
371     COLOR *scan,
372     int f
373     )
374 greg 1.1 {
375 schorsch 1.5 //double mapfilter();
376 greg 1.1 BYTE ebuf[2*HSIZE];
377     register int j;
378     register BYTE *ep;
379    
380     ep = ebuf;
381     ep[0] = mapfilter(scan[0], f) * 255.9999;
382     ep[1] = 1;
383     ep += 2;
384     for (j = 1; j < ncols; j++) {
385     ep[0] = mapfilter(scan[j], f) * 255.9999;
386     if (ep[0] == ep[-2] && ep[-1] < 255)
387     ep[-1]++;
388     else {
389     ep[1] = 1;
390     ep += 2;
391     }
392     }
393     j = ep - ebuf;
394     putw(O_FES, ftab[f].fp);
395     putw(FES_RL|j>>1, ftab[f].fp);
396     for (ep = ebuf; j-- > 0; ep++)
397     putc(*ep, ftab[f].fp);
398    
399     if (ferror(ftab[f].fp)) {
400     fprintf(stderr, "%s: Write error: %s\n", progname,
401     ftab[f].fn==NULL ? "<stdout>" : ftab[f].fn);
402     quit(1);
403     }
404     }
405    
406    
407 schorsch 1.5 static double
408     mapfilter( /* map filter value */
409     COLOR col,
410     register int f
411     )
412 greg 1.1 {
413     static float *mp[4] = {neumap, neumap, neumap, neumap};
414     double x, y;
415    
416     y = f_val(col,f);
417    
418     if (y >= 1.0)
419     return(1.0);
420    
421     while (y >= mp[f][2])
422     mp[f] += 2;
423     while (y < mp[f][0])
424     mp[f] -= 2;
425    
426     x = (y - mp[f][0]) / (mp[f][2] - mp[f][0]);
427    
428     return((1.0-x)*mp[f][1] + x*mp[f][3]);
429     }
430    
431    
432 schorsch 1.5 /* XXX replaces putw() from stdio.h. Do we really need this? */
433     int
434     putw( /* output a (short) word */
435     int w,
436     register FILE *fp
437     )
438 greg 1.1 {
439     putc(w&0377, fp); /* in proper order! */
440     putc(w>>8, fp);
441 schorsch 1.5 return 0;
442 greg 1.1 }
443    
444    
445 schorsch 1.5 static void
446     transfer( /* transfer fin contents to fout, close fin */
447     register FILE *fin,
448     register FILE *fout
449     )
450 greg 1.1 {
451     register int c;
452    
453     fseek(fin, 0L, 0); /* rewind input */
454    
455     while ((c = getc(fin)) != EOF) /* transfer file */
456     putc(c, fout);
457    
458     fclose(fin); /* close input */
459     }