ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/aedimage.c
Revision: 2.2
Committed: Thu Dec 19 14:51:44 1991 UTC (32 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +0 -1 lines
Log Message:
eliminated atof declarations for NeXT

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