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

# User Rev Content
1 greg 1.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 greg 2.3 #include <math.h>
17    
18 greg 1.1 #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 greg 1.2 #define GAMMA 2.5 /* gamma value used in correction */
64 greg 1.1
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 greg 1.10 int wrong_fmt = 0;
104 greg 1.1
105    
106     main(argc, argv)
107     int argc;
108     char *argv[];
109     {
110 greg 1.4 int onintr(), checkhead();
111 greg 1.1 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 greg 1.10 getheader(fin, checkhead, NULL);
146     if (wrong_fmt)
147     quitmsg("input must be a Radiance picture");
148 greg 1.1 /* get picture dimensions */
149 greg 1.11 if (fgetresolu(&xmax, &ymax, fin) < 0)
150 greg 1.1 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 greg 1.4 }
171    
172    
173     checkhead(line) /* deal with line from header */
174     char *line;
175     {
176 greg 1.10 char fmt[32];
177    
178 greg 1.6 if (isexpos(line))
179     exposure *= exposval(line);
180 greg 1.10 else if (isformat(line)) {
181     formatval(fmt, line);
182     wrong_fmt = strcmp(fmt, COLRFMT);
183     }
184 greg 1.1 }
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 greg 1.9 printf("%-3gL", luminance(cval)/exposure);
329 greg 1.1 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 greg 1.5 register int i;
410     /* read scanline */
411 greg 1.1 getscan(y);
412     /* convert scanline */
413 greg 1.7 normcolrs(scanline, xmax, 0);
414 greg 1.5 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 greg 1.1 }
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 greg 1.8 val = pow((i+0.5)/256.0, 1.0/GAMMA) * 256.0;
528 greg 1.1 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     }