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, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.1: +3 -1 lines
Log Message:
Fixed SCCSid

File Contents

# Content
1 /* Copyright 1988 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * 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 }