ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/aedimage.c
Revision: 1.3
Committed: Tue Sep 12 13:04:16 1989 UTC (34 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.2: +1 -2 lines
Log Message:
added calls to get/put picture resolution (bug fix)

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