ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/d48c.c
Revision: 1.2
Committed: Thu Feb 2 14:10:37 1989 UTC (35 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.1: +3 -1 lines
Log Message:
Fixed SCCSid

File Contents

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