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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: d48c.c,v 1.3 2003/02/22 02:07:27 greg Exp $";
3 #endif
4 /*
5 * 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 #include "rterror.h"
14 #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 #ifdef SIGHUP
135 if (signal(SIGHUP, quit) == SIG_IGN)
136 signal(SIGINT, SIG_IGN);
137 #endif
138 signal(SIGTERM, quit);
139 #ifdef SIGPIPE
140 signal(SIGPIPE, quit);
141 #endif
142 #ifdef SIGXCPU
143 signal(SIGXCPU, quit);
144 #endif
145 #ifdef SIGXFSZ
146 signal(SIGXFSZ, quit);
147 #endif
148
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 void
192 quit(int code) /* quit program */
193 {
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 }