ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/aedimage.c
Revision: 2.3
Committed: Fri Oct 2 16:21:47 1992 UTC (31 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.2: +2 -1 lines
Log Message:
Removed problematic math function declarations

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