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

# Content
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 }