ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/aedimage.c
Revision: 1.1
Committed: Thu Feb 2 10:49:04 1989 UTC (35 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

File Contents

# Content
1 /* Copyright (c) 1986 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * aedimage.c - RADIANCE driver for AED 512 terminal.
9 *
10 * 3/20/86
11 * 3/3/88 Added calls to Paul Heckbert's ciq routines
12 */
13
14 #include <stdio.h>
15
16 #include <signal.h>
17
18 #include <sys/ioctl.h>
19
20 #include "pic.h"
21
22 #include "color.h"
23
24
25 /* AED command characters */
26
27 #define AEDFMT "1888N" /* Format string to send to AED */
28 #define CSTAT 0100 /* Console status: lower case */
29 #define SCS 96 /* Set Console Status */
30 #define SCT 75 /* Set color lookup table */
31 #define SEC 67 /* Set color for vector drawing */
32 #define MOV 81 /* Set CAP (current access pointer) to x, y */
33 #define MVR 105 /* Set CAP relative */
34 #define DVA 65 /* Draw vector to new CAP x, y */
35 #define DVR 108 /* Draw vector relative */
36 #define WHS 88 /* Write horizontal scan */
37 #define WHR 92 /* Write horizontal runs */
38 #define OPT 40 /* Miscellaneous terminal control */
39 #define SEN 71 /* Set encoding types */
40 #define RST 48 /* Reset terminal */
41 #define FFD 12 /* Clear screen */
42 #define SCS 96 /* Set status */
43 #define DAI 114 /* Define area of interest */
44 #define EJC 85 /* Enable Joystick cursor positioning */
45 #define DJC 100 /* Disable Joystick cursor positioning */
46 #define SCC 99 /* Set Cursor Colors */
47 #define SCP 93 /* Set Cursor Parameters */
48 #define RCP 106 /* Read Cursor Position */
49 #define MAXRLEN 255 /* Maximum runlength for a span */
50 #define NUL 0 /* Null terminates run sequences */
51 #define ESC 27 /* Escape starts a command sequence */
52 #define END 1 /* Ctrl-A used to terminate command mode */
53
54 #define BLK 0 /* color table entry for black */
55 #define WHT 7 /* color table entry for white */
56
57 #define command(c) (putc(ESC, stdout), putc(c, stdout))
58 #define byte(b) putc(b, stdout)
59 #define flush() fflush(stdout)
60
61 #define GAMMA 2.0 /* gamma value used in correction */
62
63 #define MINCOLOR 8 /* start of device color table */
64
65 #define NCOLORS 248 /* available color table size */
66
67 #define NROWS 512 /* maximum # rows for output */
68 #define NCOLS 512 /* maximum # columns for output */
69
70 int dither = 0; /* dither colors? */
71
72 int greyscale = 0; /* grey only? */
73
74 int initialized = 0;
75 struct sgttyb oldflags;
76 int oldlmode;
77
78 int intrcnt = 0; /* interrupt well */
79
80 #define disintr() (intrcnt--) /* disable interrupts */
81 #define enaintr() onintr() /* enable interrupts */
82
83 char *progname;
84
85 char errmsg[128];
86
87 COLR scanline[NCOLS];
88
89 colormap colrtbl;
90
91 int cury;
92
93 int xmax, ymax;
94
95 FILE *fin;
96
97 extern long ftell();
98 long scanpos[NROWS];
99
100 extern double atof();
101 double exposure = 1.0;
102
103
104 main(argc, argv)
105 int argc;
106 char *argv[];
107 {
108 int onintr();
109 double atof();
110 char sbuf[256];
111 register int i;
112
113 progname = argv[0];
114
115 #ifdef SIGTSTP
116 signal(SIGTSTP, SIG_IGN);
117 #endif
118 if (signal(SIGINT, onintr) == SIG_IGN)
119 signal(SIGINT, SIG_IGN);
120
121 for (i = 1; i < argc; i++)
122 if (argv[i][0] == '-')
123 switch (argv[i][1]) {
124 case 'd':
125 dither = !dither;
126 break;
127 case 'b':
128 greyscale = !greyscale;
129 break;
130 default:
131 goto userr;
132 }
133 else
134 break;
135
136 if (i+1 != argc)
137 goto userr;
138
139 if ((fin = fopen(argv[i], "r")) == NULL) {
140 sprintf(errmsg, "can't open file \"%s\"", argv[i]);
141 quitmsg(errmsg);
142 }
143 /* get header */
144 while (fgets(sbuf, sizeof(sbuf), fin) != NULL && sbuf[0] != '\n')
145 if (!strncmp(sbuf, "EXPOSURE=", 9))
146 exposure *= atof(sbuf+9);
147
148 /* get picture dimensions */
149 if (fgets(sbuf, sizeof(sbuf), fin) == NULL ||
150 sscanf(sbuf, "-Y %d +X %d\n", &ymax, &xmax) != 2)
151 quitmsg("bad picture size");
152 if (xmax > NCOLS || ymax > NROWS)
153 quitmsg("resolution mismatch");
154
155 init(); /* initialize terminal for output */
156
157 for (i = 0; i < NROWS; i++)
158 scanpos[i] = -1;
159
160 if (greyscale) /* map colors and display */
161 biq(dither,NCOLORS,1,colrtbl);
162 else
163 ciq(dither,NCOLORS,1,colrtbl);
164
165 loopcom();
166
167 quitmsg(NULL);
168 userr:
169 fprintf(stderr, "Usage: %s [-d][-b] input\n", progname);
170 quit(1);
171 }
172
173
174 init() /* initialize terminal */
175 {
176 struct sgttyb flags;
177 int lmode;
178
179 if (isatty(1)) {
180 /* Set literal mode so AED gets bit 8 */
181 ioctl(1, TIOCLGET, &oldlmode);
182 lmode = oldlmode | LLITOUT | LNOFLSH;
183 ioctl(1, TIOCLSET, &lmode);
184 ioctl(1, TIOCLGET, &lmode); /* 4.2 bug */
185 /* Turn terminal echoing off */
186 ioctl(1, TIOCGETP, &oldflags);
187 ioctl(1, TIOCGETP, &flags);
188 flags.sg_flags &= ~ECHO;
189 ioctl(1, TIOCSETP, &flags);
190 initialized = 1;
191 } else
192 quitmsg("output must be to a terminal");
193
194 /* Reset AED and tell it the data format */
195 command(RST);
196 longwait(2);
197 command(OPT);
198 byte(6); byte(1); /* AED command set */
199 command(SEN); fputs(AEDFMT, stdout);
200 command(SCS); byte(CSTAT); /* console status */
201 command(FFD); /* clear screen */
202 flush();
203 }
204
205
206 onintr() /* die gracefully */
207 {
208 if (++intrcnt > 0)
209 quitmsg("interrupt");
210 }
211
212
213 quitmsg(err) /* uninitialize terminal and exit */
214 char *err;
215 {
216 if (initialized) { /* close AED */
217 command(DJC); /* disable cursor */
218 command(SEC);
219 byte(WHT); /* Set color to white */
220 aedsetcap(0, 0); /* Put cursor in a good place */
221 byte(END);
222 flush();
223 ioctl(1, TIOCSETP, &oldflags);
224 ioctl(1, TIOCLSET, &oldlmode);
225 putchar('\n');
226 }
227 if (err != NULL) {
228 fprintf(stderr, "%s: %s\n", progname, err);
229 exit(1);
230 }
231 exit(0);
232 }
233
234
235 eputs(s)
236 char *s;
237 {
238 fputs(s, stderr);
239 }
240
241
242 quit(status)
243 int status;
244 {
245 quitmsg(status ? "aborted" : NULL);
246 }
247
248
249 loopcom() /* print pixel values interactively */
250 {
251 int coffset[3]; /* color table offset */
252 struct sgttyb flags;
253 COLOR cval, ctmp;
254 int rept, x, y, j;
255 register int com, i;
256 /* Set raw mode on input */
257 ioctl(0, TIOCGETP, &flags);
258 flags.sg_flags |= RAW;
259 flags.sg_flags &= ~ECHO;
260 ioctl(0, TIOCSETP, &flags);
261
262 coffset[0] = coffset[1] = coffset[2] = 0;
263 /* set cursor type */
264 command(SCC);
265 byte(BLK); byte(WHT); byte(15);
266 command(SCP);
267 byte('+'); byte(0); byte(1);
268 /* loop on command */
269 for ( ; ; ) {
270 command(EJC); /* enable cursor */
271 flush();
272 rept = 0; /* get command */
273 while ((com = getc(stdin)) >= '0' && com <= '9')
274 rept = rept*10 + com - '0';
275 if (rept == 0) rept = 1;
276 command(DJC); /* disable cursor */
277 switch (com) {
278 case '\r':
279 case '\n':
280 case 'l':
281 case 'L':
282 case 'c':
283 case 'C':
284 case 'p':
285 case 'P':
286 case '=':
287 aedgetcap(&x, &y); /* get cursor position */
288 y = ymax-1-y;
289 if (y < 0 || scanpos[y] == -1) /* off picture? */
290 break;
291 /* get value */
292 setcolor(cval, 0.0, 0.0, 0.0);
293 for (j = rept-1; j >= 0; j--) {
294 if (y+j >= NROWS || scanpos[y+j] == -1)
295 continue;
296 getscan(y+j);
297 for (i = 0; i < rept; i++)
298 if (x+i < xmax) {
299 colr_color(ctmp, scanline[x+i]);
300 addcolor(cval, ctmp);
301 }
302 }
303 scalecolor(cval, 1.0/(rept*rept));
304 /* print value */
305 command(SEC);
306 byte(scanline[(x+20)%xmax][EXP] >= COLXS ? BLK : WHT);
307 byte(END);
308 switch (com) {
309 case '\r':
310 case '\n':
311 printf("%-3g", intens(cval)/exposure);
312 break;
313 case 'l':
314 case 'L':
315 printf("%-3gL", bright(cval)*683.0/exposure);
316 break;
317 case 'c':
318 case 'C':
319 printf("(%.2f,%.2f,%.2f)",
320 colval(cval,RED),
321 colval(cval,GRN),
322 colval(cval,BLU));
323 break;
324 case 'p':
325 case 'P':
326 printf("(%d,%d)", x, y);
327 break;
328 case '=':
329 printf("(%d,%d,%d)", coffset[0],
330 coffset[1], coffset[2]);
331 break;
332 }
333 break;
334 case 'w':
335 rept = -rept;
336 case 'W':
337 coffset[0] += rept;
338 coffset[1] += rept;
339 coffset[2] += rept;
340 movecolor(coffset);
341 break;
342 case 'r':
343 rept = -rept;
344 case 'R':
345 coffset[0] += rept;
346 movecolor(coffset);
347 break;
348 case 'g':
349 rept = -rept;
350 case 'G':
351 coffset[1] += rept;
352 movecolor(coffset);
353 break;
354 case 'b':
355 rept = -rept;
356 case 'B':
357 coffset[2] += rept;
358 movecolor(coffset);
359 break;
360 case '!':
361 coffset[0] = coffset[1] = coffset[2] = 0;
362 movecolor(coffset);
363 break;
364 case 'C'-'@':
365 case 'q':
366 case 'Q':
367 return;
368 }
369 }
370 }
371
372
373 getscan(y)
374 int y;
375 {
376 if (y != cury) {
377 if (scanpos[y] == -1)
378 quitmsg("cannot seek in getscan");
379 if (fseek(fin, scanpos[y], 0) == -1)
380 quitmsg("fseek error");
381 cury = y;
382 } else
383 scanpos[y] = ftell(fin);
384
385 if (freadcolrs(scanline, xmax, fin) < 0)
386 quitmsg("read error");
387
388 cury++;
389 }
390
391
392 picreadline3(y, l3) /* read in 3-byte scanline */
393 int y;
394 register rgbpixel *l3;
395 {
396 register BYTE *l4;
397 register int shift, c;
398 int i;
399
400 getscan(y);
401 /* convert scanline */
402 for (l4=scanline[0], i=xmax; i--; l4+=4, l3++) {
403 shift = l4[EXP] - COLXS;
404 if (shift >= 8) {
405 l3->r = l3->g = l3->b = 255;
406 } else if (shift <= -8) {
407 l3->r = l3->g = l3->b = 0;
408 } else if (shift > 0) {
409 c = l4[RED] << shift;
410 l3->r = c > 255 ? 255 : c;
411 c = l4[GRN] << shift;
412 l3->g = c > 255 ? 255 : c;
413 c = l4[BLU] << shift;
414 l3->b = c > 255 ? 255 : c;
415 } else if (shift < 0) {
416 l3->r = l4[RED] >> -shift;
417 l3->g = l4[GRN] >> -shift;
418 l3->b = l4[BLU] >> -shift;
419 } else {
420 l3->r = l4[RED];
421 l3->g = l4[GRN];
422 l3->b = l4[BLU];
423 }
424 }
425 }
426
427
428 picwriteline(y, l) /* output scan line of pixel values */
429 int y;
430 register pixel *l;
431 {
432 int curpix;
433 register int n, ncols;
434
435 disintr(); /* disable interrupts */
436 aedsetcap(0, ymax-1-y);
437 command(DAI);
438 aedcoord(xmax-1, ymax-1-y);
439 ncols = xmax;
440 if (dither) { /* pixel run lengths short */
441 command(WHS);
442 while (ncols-- > 0)
443 byte(MINCOLOR + *l++);
444 } else { /* pixel run lengths long */
445 command(WHR);
446 while (ncols-- > 0) {
447 curpix = *l++;
448 for (n = 1; n < MAXRLEN; n++) {
449 if (ncols <= 0 || *l != curpix)
450 break;
451 l++; ncols--;
452 }
453 byte(n);
454 byte(MINCOLOR + curpix);
455 }
456 byte(NUL);
457 }
458 flush();
459 enaintr(); /* enable interrupts */
460 }
461
462
463 /*
464 * aedsetcap - sets AED's current access pointer to (x, y). Used
465 * before writing a span to put it in the right place.
466 */
467
468 aedsetcap(x, y)
469 register int x, y;
470 {
471 command(MOV);
472 aedcoord(x, y);
473 }
474
475 /*
476 * aedcoord - puts out an (x, y) coordinate in AED 8 bit format.
477 */
478
479 aedcoord(x, y)
480 register int x, y;
481 {
482 putc(((x >> 4) & 0x30) | ((y >> 8) & 0x3), stdout);
483 putc(x & 0xff, stdout);
484 putc(y & 0xff, stdout);
485 }
486
487
488 aedgetcap(xp, yp) /* get cursor postion */
489 int *xp, *yp;
490 {
491 register int c;
492 /* get cursor postition */
493 command(RCP);
494 flush();
495 c = getc(stdin);
496 *xp = (c & 0x30) << 4;
497 *yp = (c & 0x3) << 8;
498 *xp |= getc(stdin);
499 *yp |= getc(stdin);
500 }
501
502
503 movecolor(offset) /* move our color table up or down */
504 int offset[3];
505 {
506 register int i, j, c;
507
508 disintr();
509 command(SCT);
510 byte(MINCOLOR);
511 byte(NCOLORS);
512 for (i = 0; i < NCOLORS; i++)
513 for (j = 0; j < 3; j++) {
514 c = colrtbl[j][i] + offset[j];
515 if (c < 0)
516 byte(0);
517 else if (c > 255)
518 byte(255);
519 else
520 byte(c);
521 }
522 shortwait(20);
523 enaintr();
524 }
525
526
527 picreadcm(map) /* do gamma correction */
528 colormap map;
529 {
530 extern double pow();
531 register int i, val;
532
533 for (i = 0; i < 256; i++) {
534 val = pow(i/256.0, 1.0/GAMMA) * 256.0;
535 map[0][i] = map[1][i] = map[2][i] = val;
536 }
537 }
538
539
540 picwritecm(map) /* write out color map */
541 colormap map;
542 {
543 register int i, j;
544
545 disintr();
546 command(SCT);
547 byte(MINCOLOR);
548 byte(NCOLORS);
549 for (i = 0; i < NCOLORS; i++)
550 for (j = 0; j < 3; j++)
551 byte(map[j][i]);
552 shortwait(20);
553 enaintr();
554 }
555
556
557 longwait(t) /* longer wait */
558 int t;
559 {
560 flush();
561 sleep(t);
562 }
563
564
565 shortwait(t) /* shorter wait */
566 int t;
567 {
568 register long l = t*1000;
569
570 flush();
571 while (l--)
572 ;
573 }