ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/aedimage.c
Revision: 2.1
Committed: Tue Nov 12 16:05:36 1991 UTC (32 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.11: +0 -0 lines
Log Message:
updated revision number for release 2.0

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