ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/aedimage.c
Revision: 1.4
Committed: Fri Sep 15 09:10:24 1989 UTC (34 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.3: +10 -6 lines
Log Message:
added call to getheader in aedimage

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