ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/aedimage.c
Revision: 2.1
Committed: Tue Nov 12 16:05:36 1991 UTC (32 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.11: +0 -0 lines
Log Message:
updated revision number for release 2.0

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.5 /* 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 int wrong_fmt = 0;
103
104
105 main(argc, argv)
106 int argc;
107 char *argv[];
108 {
109 int onintr(), checkhead();
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 getheader(fin, checkhead, NULL);
145 if (wrong_fmt)
146 quitmsg("input must be a Radiance picture");
147 /* get picture dimensions */
148 if (fgetresolu(&xmax, &ymax, fin) < 0)
149 quitmsg("bad picture size");
150 if (xmax > NCOLS || ymax > NROWS)
151 quitmsg("resolution mismatch");
152
153 init(); /* initialize terminal for output */
154
155 for (i = 0; i < NROWS; i++)
156 scanpos[i] = -1;
157
158 if (greyscale) /* map colors and display */
159 biq(dither,NCOLORS,1,colrtbl);
160 else
161 ciq(dither,NCOLORS,1,colrtbl);
162
163 loopcom();
164
165 quitmsg(NULL);
166 userr:
167 fprintf(stderr, "Usage: %s [-d][-b] input\n", progname);
168 quit(1);
169 }
170
171
172 checkhead(line) /* deal with line from header */
173 char *line;
174 {
175 char fmt[32];
176
177 if (isexpos(line))
178 exposure *= exposval(line);
179 else if (isformat(line)) {
180 formatval(fmt, line);
181 wrong_fmt = strcmp(fmt, COLRFMT);
182 }
183 }
184
185
186 init() /* initialize terminal */
187 {
188 struct sgttyb flags;
189 int lmode;
190
191 if (isatty(1)) {
192 /* Set literal mode so AED gets bit 8 */
193 ioctl(1, TIOCLGET, &oldlmode);
194 lmode = oldlmode | LLITOUT | LNOFLSH;
195 ioctl(1, TIOCLSET, &lmode);
196 ioctl(1, TIOCLGET, &lmode); /* 4.2 bug */
197 /* Turn terminal echoing off */
198 ioctl(1, TIOCGETP, &oldflags);
199 ioctl(1, TIOCGETP, &flags);
200 flags.sg_flags &= ~ECHO;
201 ioctl(1, TIOCSETP, &flags);
202 initialized = 1;
203 } else
204 quitmsg("output must be to a terminal");
205
206 /* Reset AED and tell it the data format */
207 command(RST);
208 longwait(2);
209 command(OPT);
210 byte(6); byte(1); /* AED command set */
211 command(SEN); fputs(AEDFMT, stdout);
212 command(SCS); byte(CSTAT); /* console status */
213 command(FFD); /* clear screen */
214 flush();
215 }
216
217
218 onintr() /* die gracefully */
219 {
220 if (++intrcnt > 0)
221 quitmsg("interrupt");
222 }
223
224
225 quitmsg(err) /* uninitialize terminal and exit */
226 char *err;
227 {
228 if (initialized) { /* close AED */
229 command(DJC); /* disable cursor */
230 command(SEC);
231 byte(WHT); /* Set color to white */
232 aedsetcap(0, 0); /* Put cursor in a good place */
233 byte(END);
234 flush();
235 ioctl(1, TIOCSETP, &oldflags);
236 ioctl(1, TIOCLSET, &oldlmode);
237 putchar('\n');
238 }
239 if (err != NULL) {
240 fprintf(stderr, "%s: %s\n", progname, err);
241 exit(1);
242 }
243 exit(0);
244 }
245
246
247 eputs(s)
248 char *s;
249 {
250 fputs(s, stderr);
251 }
252
253
254 quit(status)
255 int status;
256 {
257 quitmsg(status ? "aborted" : NULL);
258 }
259
260
261 loopcom() /* print pixel values interactively */
262 {
263 int coffset[3]; /* color table offset */
264 struct sgttyb flags;
265 COLOR cval, ctmp;
266 int rept, x, y, j;
267 register int com, i;
268 /* Set raw mode on input */
269 ioctl(0, TIOCGETP, &flags);
270 flags.sg_flags |= RAW;
271 flags.sg_flags &= ~ECHO;
272 ioctl(0, TIOCSETP, &flags);
273
274 coffset[0] = coffset[1] = coffset[2] = 0;
275 /* set cursor type */
276 command(SCC);
277 byte(BLK); byte(WHT); byte(15);
278 command(SCP);
279 byte('+'); byte(0); byte(1);
280 /* loop on command */
281 for ( ; ; ) {
282 command(EJC); /* enable cursor */
283 flush();
284 rept = 0; /* get command */
285 while ((com = getc(stdin)) >= '0' && com <= '9')
286 rept = rept*10 + com - '0';
287 if (rept == 0) rept = 1;
288 command(DJC); /* disable cursor */
289 switch (com) {
290 case '\r':
291 case '\n':
292 case 'l':
293 case 'L':
294 case 'c':
295 case 'C':
296 case 'p':
297 case 'P':
298 case '=':
299 aedgetcap(&x, &y); /* get cursor position */
300 y = ymax-1-y;
301 if (y < 0 || scanpos[y] == -1) /* off picture? */
302 break;
303 /* get value */
304 setcolor(cval, 0.0, 0.0, 0.0);
305 for (j = rept-1; j >= 0; j--) {
306 if (y+j >= NROWS || scanpos[y+j] == -1)
307 continue;
308 getscan(y+j);
309 for (i = 0; i < rept; i++)
310 if (x+i < xmax) {
311 colr_color(ctmp, scanline[x+i]);
312 addcolor(cval, ctmp);
313 }
314 }
315 scalecolor(cval, 1.0/(rept*rept));
316 /* print value */
317 command(SEC);
318 byte(scanline[(x+20)%xmax][EXP] >= COLXS ? BLK : WHT);
319 byte(END);
320 switch (com) {
321 case '\r':
322 case '\n':
323 printf("%-3g", intens(cval)/exposure);
324 break;
325 case 'l':
326 case 'L':
327 printf("%-3gL", luminance(cval)/exposure);
328 break;
329 case 'c':
330 case 'C':
331 printf("(%.2f,%.2f,%.2f)",
332 colval(cval,RED),
333 colval(cval,GRN),
334 colval(cval,BLU));
335 break;
336 case 'p':
337 case 'P':
338 printf("(%d,%d)", x, y);
339 break;
340 case '=':
341 printf("(%d,%d,%d)", coffset[0],
342 coffset[1], coffset[2]);
343 break;
344 }
345 break;
346 case 'w':
347 rept = -rept;
348 case 'W':
349 coffset[0] += rept;
350 coffset[1] += rept;
351 coffset[2] += rept;
352 movecolor(coffset);
353 break;
354 case 'r':
355 rept = -rept;
356 case 'R':
357 coffset[0] += rept;
358 movecolor(coffset);
359 break;
360 case 'g':
361 rept = -rept;
362 case 'G':
363 coffset[1] += rept;
364 movecolor(coffset);
365 break;
366 case 'b':
367 rept = -rept;
368 case 'B':
369 coffset[2] += rept;
370 movecolor(coffset);
371 break;
372 case '!':
373 coffset[0] = coffset[1] = coffset[2] = 0;
374 movecolor(coffset);
375 break;
376 case 'C'-'@':
377 case 'q':
378 case 'Q':
379 return;
380 }
381 }
382 }
383
384
385 getscan(y)
386 int y;
387 {
388 if (y != cury) {
389 if (scanpos[y] == -1)
390 quitmsg("cannot seek in getscan");
391 if (fseek(fin, scanpos[y], 0) == -1)
392 quitmsg("fseek error");
393 cury = y;
394 } else
395 scanpos[y] = ftell(fin);
396
397 if (freadcolrs(scanline, xmax, fin) < 0)
398 quitmsg("read error");
399
400 cury++;
401 }
402
403
404 picreadline3(y, l3) /* read in 3-byte scanline */
405 int y;
406 register rgbpixel *l3;
407 {
408 register int i;
409 /* read scanline */
410 getscan(y);
411 /* convert scanline */
412 normcolrs(scanline, xmax, 0);
413 for (i = 0; i < xmax; i++) {
414 l3[i].r = scanline[i][RED];
415 l3[i].g = scanline[i][GRN];
416 l3[i].b = scanline[i][BLU];
417 }
418 }
419
420
421 picwriteline(y, l) /* output scan line of pixel values */
422 int y;
423 register pixel *l;
424 {
425 int curpix;
426 register int n, ncols;
427
428 disintr(); /* disable interrupts */
429 aedsetcap(0, ymax-1-y);
430 command(DAI);
431 aedcoord(xmax-1, ymax-1-y);
432 ncols = xmax;
433 if (dither) { /* pixel run lengths short */
434 command(WHS);
435 while (ncols-- > 0)
436 byte(MINCOLOR + *l++);
437 } else { /* pixel run lengths long */
438 command(WHR);
439 while (ncols-- > 0) {
440 curpix = *l++;
441 for (n = 1; n < MAXRLEN; n++) {
442 if (ncols <= 0 || *l != curpix)
443 break;
444 l++; ncols--;
445 }
446 byte(n);
447 byte(MINCOLOR + curpix);
448 }
449 byte(NUL);
450 }
451 flush();
452 enaintr(); /* enable interrupts */
453 }
454
455
456 /*
457 * aedsetcap - sets AED's current access pointer to (x, y). Used
458 * before writing a span to put it in the right place.
459 */
460
461 aedsetcap(x, y)
462 register int x, y;
463 {
464 command(MOV);
465 aedcoord(x, y);
466 }
467
468 /*
469 * aedcoord - puts out an (x, y) coordinate in AED 8 bit format.
470 */
471
472 aedcoord(x, y)
473 register int x, y;
474 {
475 putc(((x >> 4) & 0x30) | ((y >> 8) & 0x3), stdout);
476 putc(x & 0xff, stdout);
477 putc(y & 0xff, stdout);
478 }
479
480
481 aedgetcap(xp, yp) /* get cursor postion */
482 int *xp, *yp;
483 {
484 register int c;
485 /* get cursor postition */
486 command(RCP);
487 flush();
488 c = getc(stdin);
489 *xp = (c & 0x30) << 4;
490 *yp = (c & 0x3) << 8;
491 *xp |= getc(stdin);
492 *yp |= getc(stdin);
493 }
494
495
496 movecolor(offset) /* move our color table up or down */
497 int offset[3];
498 {
499 register int i, j, c;
500
501 disintr();
502 command(SCT);
503 byte(MINCOLOR);
504 byte(NCOLORS);
505 for (i = 0; i < NCOLORS; i++)
506 for (j = 0; j < 3; j++) {
507 c = colrtbl[j][i] + offset[j];
508 if (c < 0)
509 byte(0);
510 else if (c > 255)
511 byte(255);
512 else
513 byte(c);
514 }
515 shortwait(20);
516 enaintr();
517 }
518
519
520 picreadcm(map) /* do gamma correction */
521 colormap map;
522 {
523 extern double pow();
524 register int i, val;
525
526 for (i = 0; i < 256; i++) {
527 val = pow((i+0.5)/256.0, 1.0/GAMMA) * 256.0;
528 map[0][i] = map[1][i] = map[2][i] = val;
529 }
530 }
531
532
533 picwritecm(map) /* write out color map */
534 colormap map;
535 {
536 register int i, j;
537
538 disintr();
539 command(SCT);
540 byte(MINCOLOR);
541 byte(NCOLORS);
542 for (i = 0; i < NCOLORS; i++)
543 for (j = 0; j < 3; j++)
544 byte(map[j][i]);
545 shortwait(20);
546 enaintr();
547 }
548
549
550 longwait(t) /* longer wait */
551 int t;
552 {
553 flush();
554 sleep(t);
555 }
556
557
558 shortwait(t) /* shorter wait */
559 int t;
560 {
561 register long l = t*1000;
562
563 flush();
564 while (l--)
565 ;
566 }