ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/aedimage.c
Revision: 2.2
Committed: Thu Dec 19 14:51:44 1991 UTC (32 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +0 -1 lines
Log Message:
eliminated atof declarations for NeXT

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