ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/d48c.c
Revision: 1.1
Committed: Thu Feb 2 10:49:15 1989 UTC (35 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

File Contents

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