ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/aedimage.c
Revision: 1.2
Committed: Fri Mar 10 10:20:07 1989 UTC (35 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.1: +1 -1 lines
Log Message:
New gamma

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