ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/aedimage.c
Revision: 1.4
Committed: Fri Sep 15 09:10:24 1989 UTC (34 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.3: +10 -6 lines
Log Message:
added call to getheader in aedimage

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