ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/aedimage.c
Revision: 2.4
Committed: Tue Oct 27 09:08:25 1998 UTC (25 years, 6 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Changes since 2.3: +2 -0 lines
Log Message:
changed getheader() to listen to return value of passed function

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 greg 2.3 #include <math.h>
17    
18 greg 1.1 #include <signal.h>
19    
20     #include <sys/ioctl.h>
21    
22     #include "pic.h"
23    
24     #include "color.h"
25    
26    
27     /* AED command characters */
28    
29     #define AEDFMT "1888N" /* Format string to send to AED */
30     #define CSTAT 0100 /* Console status: lower case */
31     #define SCS 96 /* Set Console Status */
32     #define SCT 75 /* Set color lookup table */
33     #define SEC 67 /* Set color for vector drawing */
34     #define MOV 81 /* Set CAP (current access pointer) to x, y */
35     #define MVR 105 /* Set CAP relative */
36     #define DVA 65 /* Draw vector to new CAP x, y */
37     #define DVR 108 /* Draw vector relative */
38     #define WHS 88 /* Write horizontal scan */
39     #define WHR 92 /* Write horizontal runs */
40     #define OPT 40 /* Miscellaneous terminal control */
41     #define SEN 71 /* Set encoding types */
42     #define RST 48 /* Reset terminal */
43     #define FFD 12 /* Clear screen */
44     #define SCS 96 /* Set status */
45     #define DAI 114 /* Define area of interest */
46     #define EJC 85 /* Enable Joystick cursor positioning */
47     #define DJC 100 /* Disable Joystick cursor positioning */
48     #define SCC 99 /* Set Cursor Colors */
49     #define SCP 93 /* Set Cursor Parameters */
50     #define RCP 106 /* Read Cursor Position */
51     #define MAXRLEN 255 /* Maximum runlength for a span */
52     #define NUL 0 /* Null terminates run sequences */
53     #define ESC 27 /* Escape starts a command sequence */
54     #define END 1 /* Ctrl-A used to terminate command mode */
55    
56     #define BLK 0 /* color table entry for black */
57     #define WHT 7 /* color table entry for white */
58    
59     #define command(c) (putc(ESC, stdout), putc(c, stdout))
60     #define byte(b) putc(b, stdout)
61     #define flush() fflush(stdout)
62    
63 greg 1.2 #define GAMMA 2.5 /* gamma value used in correction */
64 greg 1.1
65     #define MINCOLOR 8 /* start of device color table */
66    
67     #define NCOLORS 248 /* available color table size */
68    
69     #define NROWS 512 /* maximum # rows for output */
70     #define NCOLS 512 /* maximum # columns for output */
71    
72     int dither = 0; /* dither colors? */
73    
74     int greyscale = 0; /* grey only? */
75    
76     int initialized = 0;
77     struct sgttyb oldflags;
78     int oldlmode;
79    
80     int intrcnt = 0; /* interrupt well */
81    
82     #define disintr() (intrcnt--) /* disable interrupts */
83     #define enaintr() onintr() /* enable interrupts */
84    
85     char *progname;
86    
87     char errmsg[128];
88    
89     COLR scanline[NCOLS];
90    
91     colormap colrtbl;
92    
93     int cury;
94    
95     int xmax, ymax;
96    
97     FILE *fin;
98    
99     extern long ftell();
100     long scanpos[NROWS];
101    
102     double exposure = 1.0;
103 greg 1.10 int wrong_fmt = 0;
104 greg 1.1
105    
106     main(argc, argv)
107     int argc;
108     char *argv[];
109     {
110 greg 1.4 int onintr(), checkhead();
111 greg 1.1 char sbuf[256];
112     register int i;
113    
114     progname = argv[0];
115    
116     #ifdef SIGTSTP
117     signal(SIGTSTP, SIG_IGN);
118     #endif
119     if (signal(SIGINT, onintr) == SIG_IGN)
120     signal(SIGINT, SIG_IGN);
121    
122     for (i = 1; i < argc; i++)
123     if (argv[i][0] == '-')
124     switch (argv[i][1]) {
125     case 'd':
126     dither = !dither;
127     break;
128     case 'b':
129     greyscale = !greyscale;
130     break;
131     default:
132     goto userr;
133     }
134     else
135     break;
136    
137     if (i+1 != argc)
138     goto userr;
139    
140     if ((fin = fopen(argv[i], "r")) == NULL) {
141     sprintf(errmsg, "can't open file \"%s\"", argv[i]);
142     quitmsg(errmsg);
143     }
144     /* get header */
145 greg 1.10 getheader(fin, checkhead, NULL);
146     if (wrong_fmt)
147     quitmsg("input must be a Radiance picture");
148 greg 1.1 /* get picture dimensions */
149 greg 1.11 if (fgetresolu(&xmax, &ymax, fin) < 0)
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 greg 1.4 }
171    
172    
173 gwlarson 2.4 int
174 greg 1.4 checkhead(line) /* deal with line from header */
175     char *line;
176     {
177 greg 1.10 char fmt[32];
178    
179 greg 1.6 if (isexpos(line))
180     exposure *= exposval(line);
181 greg 1.10 else if (isformat(line)) {
182     formatval(fmt, line);
183     wrong_fmt = strcmp(fmt, COLRFMT);
184     }
185 gwlarson 2.4 return(0);
186 greg 1.1 }
187    
188    
189     init() /* initialize terminal */
190     {
191     struct sgttyb flags;
192     int lmode;
193    
194     if (isatty(1)) {
195     /* Set literal mode so AED gets bit 8 */
196     ioctl(1, TIOCLGET, &oldlmode);
197     lmode = oldlmode | LLITOUT | LNOFLSH;
198     ioctl(1, TIOCLSET, &lmode);
199     ioctl(1, TIOCLGET, &lmode); /* 4.2 bug */
200     /* Turn terminal echoing off */
201     ioctl(1, TIOCGETP, &oldflags);
202     ioctl(1, TIOCGETP, &flags);
203     flags.sg_flags &= ~ECHO;
204     ioctl(1, TIOCSETP, &flags);
205     initialized = 1;
206     } else
207     quitmsg("output must be to a terminal");
208    
209     /* Reset AED and tell it the data format */
210     command(RST);
211     longwait(2);
212     command(OPT);
213     byte(6); byte(1); /* AED command set */
214     command(SEN); fputs(AEDFMT, stdout);
215     command(SCS); byte(CSTAT); /* console status */
216     command(FFD); /* clear screen */
217     flush();
218     }
219    
220    
221     onintr() /* die gracefully */
222     {
223     if (++intrcnt > 0)
224     quitmsg("interrupt");
225     }
226    
227    
228     quitmsg(err) /* uninitialize terminal and exit */
229     char *err;
230     {
231     if (initialized) { /* close AED */
232     command(DJC); /* disable cursor */
233     command(SEC);
234     byte(WHT); /* Set color to white */
235     aedsetcap(0, 0); /* Put cursor in a good place */
236     byte(END);
237     flush();
238     ioctl(1, TIOCSETP, &oldflags);
239     ioctl(1, TIOCLSET, &oldlmode);
240     putchar('\n');
241     }
242     if (err != NULL) {
243     fprintf(stderr, "%s: %s\n", progname, err);
244     exit(1);
245     }
246     exit(0);
247     }
248    
249    
250     eputs(s)
251     char *s;
252     {
253     fputs(s, stderr);
254     }
255    
256    
257     quit(status)
258     int status;
259     {
260     quitmsg(status ? "aborted" : NULL);
261     }
262    
263    
264     loopcom() /* print pixel values interactively */
265     {
266     int coffset[3]; /* color table offset */
267     struct sgttyb flags;
268     COLOR cval, ctmp;
269     int rept, x, y, j;
270     register int com, i;
271     /* Set raw mode on input */
272     ioctl(0, TIOCGETP, &flags);
273     flags.sg_flags |= RAW;
274     flags.sg_flags &= ~ECHO;
275     ioctl(0, TIOCSETP, &flags);
276    
277     coffset[0] = coffset[1] = coffset[2] = 0;
278     /* set cursor type */
279     command(SCC);
280     byte(BLK); byte(WHT); byte(15);
281     command(SCP);
282     byte('+'); byte(0); byte(1);
283     /* loop on command */
284     for ( ; ; ) {
285     command(EJC); /* enable cursor */
286     flush();
287     rept = 0; /* get command */
288     while ((com = getc(stdin)) >= '0' && com <= '9')
289     rept = rept*10 + com - '0';
290     if (rept == 0) rept = 1;
291     command(DJC); /* disable cursor */
292     switch (com) {
293     case '\r':
294     case '\n':
295     case 'l':
296     case 'L':
297     case 'c':
298     case 'C':
299     case 'p':
300     case 'P':
301     case '=':
302     aedgetcap(&x, &y); /* get cursor position */
303     y = ymax-1-y;
304     if (y < 0 || scanpos[y] == -1) /* off picture? */
305     break;
306     /* get value */
307     setcolor(cval, 0.0, 0.0, 0.0);
308     for (j = rept-1; j >= 0; j--) {
309     if (y+j >= NROWS || scanpos[y+j] == -1)
310     continue;
311     getscan(y+j);
312     for (i = 0; i < rept; i++)
313     if (x+i < xmax) {
314     colr_color(ctmp, scanline[x+i]);
315     addcolor(cval, ctmp);
316     }
317     }
318     scalecolor(cval, 1.0/(rept*rept));
319     /* print value */
320     command(SEC);
321     byte(scanline[(x+20)%xmax][EXP] >= COLXS ? BLK : WHT);
322     byte(END);
323     switch (com) {
324     case '\r':
325     case '\n':
326     printf("%-3g", intens(cval)/exposure);
327     break;
328     case 'l':
329     case 'L':
330 greg 1.9 printf("%-3gL", luminance(cval)/exposure);
331 greg 1.1 break;
332     case 'c':
333     case 'C':
334     printf("(%.2f,%.2f,%.2f)",
335     colval(cval,RED),
336     colval(cval,GRN),
337     colval(cval,BLU));
338     break;
339     case 'p':
340     case 'P':
341     printf("(%d,%d)", x, y);
342     break;
343     case '=':
344     printf("(%d,%d,%d)", coffset[0],
345     coffset[1], coffset[2]);
346     break;
347     }
348     break;
349     case 'w':
350     rept = -rept;
351     case 'W':
352     coffset[0] += rept;
353     coffset[1] += rept;
354     coffset[2] += rept;
355     movecolor(coffset);
356     break;
357     case 'r':
358     rept = -rept;
359     case 'R':
360     coffset[0] += rept;
361     movecolor(coffset);
362     break;
363     case 'g':
364     rept = -rept;
365     case 'G':
366     coffset[1] += rept;
367     movecolor(coffset);
368     break;
369     case 'b':
370     rept = -rept;
371     case 'B':
372     coffset[2] += rept;
373     movecolor(coffset);
374     break;
375     case '!':
376     coffset[0] = coffset[1] = coffset[2] = 0;
377     movecolor(coffset);
378     break;
379     case 'C'-'@':
380     case 'q':
381     case 'Q':
382     return;
383     }
384     }
385     }
386    
387    
388     getscan(y)
389     int y;
390     {
391     if (y != cury) {
392     if (scanpos[y] == -1)
393     quitmsg("cannot seek in getscan");
394     if (fseek(fin, scanpos[y], 0) == -1)
395     quitmsg("fseek error");
396     cury = y;
397     } else
398     scanpos[y] = ftell(fin);
399    
400     if (freadcolrs(scanline, xmax, fin) < 0)
401     quitmsg("read error");
402    
403     cury++;
404     }
405    
406    
407     picreadline3(y, l3) /* read in 3-byte scanline */
408     int y;
409     register rgbpixel *l3;
410     {
411 greg 1.5 register int i;
412     /* read scanline */
413 greg 1.1 getscan(y);
414     /* convert scanline */
415 greg 1.7 normcolrs(scanline, xmax, 0);
416 greg 1.5 for (i = 0; i < xmax; i++) {
417     l3[i].r = scanline[i][RED];
418     l3[i].g = scanline[i][GRN];
419     l3[i].b = scanline[i][BLU];
420 greg 1.1 }
421     }
422    
423    
424     picwriteline(y, l) /* output scan line of pixel values */
425     int y;
426     register pixel *l;
427     {
428     int curpix;
429     register int n, ncols;
430    
431     disintr(); /* disable interrupts */
432     aedsetcap(0, ymax-1-y);
433     command(DAI);
434     aedcoord(xmax-1, ymax-1-y);
435     ncols = xmax;
436     if (dither) { /* pixel run lengths short */
437     command(WHS);
438     while (ncols-- > 0)
439     byte(MINCOLOR + *l++);
440     } else { /* pixel run lengths long */
441     command(WHR);
442     while (ncols-- > 0) {
443     curpix = *l++;
444     for (n = 1; n < MAXRLEN; n++) {
445     if (ncols <= 0 || *l != curpix)
446     break;
447     l++; ncols--;
448     }
449     byte(n);
450     byte(MINCOLOR + curpix);
451     }
452     byte(NUL);
453     }
454     flush();
455     enaintr(); /* enable interrupts */
456     }
457    
458    
459     /*
460     * aedsetcap - sets AED's current access pointer to (x, y). Used
461     * before writing a span to put it in the right place.
462     */
463    
464     aedsetcap(x, y)
465     register int x, y;
466     {
467     command(MOV);
468     aedcoord(x, y);
469     }
470    
471     /*
472     * aedcoord - puts out an (x, y) coordinate in AED 8 bit format.
473     */
474    
475     aedcoord(x, y)
476     register int x, y;
477     {
478     putc(((x >> 4) & 0x30) | ((y >> 8) & 0x3), stdout);
479     putc(x & 0xff, stdout);
480     putc(y & 0xff, stdout);
481     }
482    
483    
484     aedgetcap(xp, yp) /* get cursor postion */
485     int *xp, *yp;
486     {
487     register int c;
488     /* get cursor postition */
489     command(RCP);
490     flush();
491     c = getc(stdin);
492     *xp = (c & 0x30) << 4;
493     *yp = (c & 0x3) << 8;
494     *xp |= getc(stdin);
495     *yp |= getc(stdin);
496     }
497    
498    
499     movecolor(offset) /* move our color table up or down */
500     int offset[3];
501     {
502     register int i, j, c;
503    
504     disintr();
505     command(SCT);
506     byte(MINCOLOR);
507     byte(NCOLORS);
508     for (i = 0; i < NCOLORS; i++)
509     for (j = 0; j < 3; j++) {
510     c = colrtbl[j][i] + offset[j];
511     if (c < 0)
512     byte(0);
513     else if (c > 255)
514     byte(255);
515     else
516     byte(c);
517     }
518     shortwait(20);
519     enaintr();
520     }
521    
522    
523     picreadcm(map) /* do gamma correction */
524     colormap map;
525     {
526     register int i, val;
527    
528     for (i = 0; i < 256; i++) {
529 greg 1.8 val = pow((i+0.5)/256.0, 1.0/GAMMA) * 256.0;
530 greg 1.1 map[0][i] = map[1][i] = map[2][i] = val;
531     }
532     }
533    
534    
535     picwritecm(map) /* write out color map */
536     colormap map;
537     {
538     register int i, j;
539    
540     disintr();
541     command(SCT);
542     byte(MINCOLOR);
543     byte(NCOLORS);
544     for (i = 0; i < NCOLORS; i++)
545     for (j = 0; j < 3; j++)
546     byte(map[j][i]);
547     shortwait(20);
548     enaintr();
549     }
550    
551    
552     longwait(t) /* longer wait */
553     int t;
554     {
555     flush();
556     sleep(t);
557     }
558    
559    
560     shortwait(t) /* shorter wait */
561     int t;
562     {
563     register long l = t*1000;
564    
565     flush();
566     while (l--)
567     ;
568     }