ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/d48c.c
Revision: 1.4
Committed: Mon Oct 27 10:24:51 2003 UTC (20 years, 6 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 1.3: +11 -5 lines
Log Message:
Various compatibility fixes.

File Contents

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