ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/aedimage.c
Revision: 1.3
Committed: Tue Sep 12 13:04:16 1989 UTC (34 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.2: +1 -2 lines
Log Message:
added calls to get/put picture resolution (bug fix)

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