ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/aedimage.c
Revision: 2.6
Committed: Fri Jan 2 12:47:01 2004 UTC (20 years, 4 months ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R6P1, rad3R6
Changes since 2.5: +10 -9 lines
Log Message:
Fixed typing/prototype of getheader() and its callback.

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 2.6 static const char RCSid[] = "$Id: aedimage.c,v 2.5 2003/02/22 02:07:27 greg Exp $";
3 greg 1.1 #endif
4     /*
5     * aedimage.c - RADIANCE driver for AED 512 terminal.
6     *
7     * 3/20/86
8     * 3/3/88 Added calls to Paul Heckbert's ciq routines
9     */
10    
11     #include <stdio.h>
12 greg 2.3 #include <math.h>
13 greg 1.1 #include <signal.h>
14     #include <sys/ioctl.h>
15    
16     #include "pic.h"
17 schorsch 2.6 #include "resolu.h"
18 greg 1.1 #include "color.h"
19    
20    
21     /* AED command characters */
22    
23     #define AEDFMT "1888N" /* Format string to send to AED */
24     #define CSTAT 0100 /* Console status: lower case */
25     #define SCS 96 /* Set Console Status */
26     #define SCT 75 /* Set color lookup table */
27     #define SEC 67 /* Set color for vector drawing */
28     #define MOV 81 /* Set CAP (current access pointer) to x, y */
29     #define MVR 105 /* Set CAP relative */
30     #define DVA 65 /* Draw vector to new CAP x, y */
31     #define DVR 108 /* Draw vector relative */
32     #define WHS 88 /* Write horizontal scan */
33     #define WHR 92 /* Write horizontal runs */
34     #define OPT 40 /* Miscellaneous terminal control */
35     #define SEN 71 /* Set encoding types */
36     #define RST 48 /* Reset terminal */
37     #define FFD 12 /* Clear screen */
38     #define SCS 96 /* Set status */
39     #define DAI 114 /* Define area of interest */
40     #define EJC 85 /* Enable Joystick cursor positioning */
41     #define DJC 100 /* Disable Joystick cursor positioning */
42     #define SCC 99 /* Set Cursor Colors */
43     #define SCP 93 /* Set Cursor Parameters */
44     #define RCP 106 /* Read Cursor Position */
45     #define MAXRLEN 255 /* Maximum runlength for a span */
46     #define NUL 0 /* Null terminates run sequences */
47     #define ESC 27 /* Escape starts a command sequence */
48     #define END 1 /* Ctrl-A used to terminate command mode */
49    
50     #define BLK 0 /* color table entry for black */
51     #define WHT 7 /* color table entry for white */
52    
53     #define command(c) (putc(ESC, stdout), putc(c, stdout))
54     #define byte(b) putc(b, stdout)
55     #define flush() fflush(stdout)
56    
57 greg 1.2 #define GAMMA 2.5 /* gamma value used in correction */
58 greg 1.1
59     #define MINCOLOR 8 /* start of device color table */
60    
61     #define NCOLORS 248 /* available color table size */
62    
63     #define NROWS 512 /* maximum # rows for output */
64     #define NCOLS 512 /* maximum # columns for output */
65    
66     int dither = 0; /* dither colors? */
67    
68     int greyscale = 0; /* grey only? */
69    
70     int initialized = 0;
71     struct sgttyb oldflags;
72     int oldlmode;
73    
74     int intrcnt = 0; /* interrupt well */
75    
76     #define disintr() (intrcnt--) /* disable interrupts */
77     #define enaintr() onintr() /* enable interrupts */
78    
79     char *progname;
80    
81     char errmsg[128];
82    
83     COLR scanline[NCOLS];
84    
85     colormap colrtbl;
86    
87     int cury;
88    
89     int xmax, ymax;
90    
91     FILE *fin;
92    
93     extern long ftell();
94     long scanpos[NROWS];
95    
96     double exposure = 1.0;
97 greg 1.10 int wrong_fmt = 0;
98 greg 1.1
99 schorsch 2.6 static gethfunc checkhead;
100    
101 greg 1.1
102     main(argc, argv)
103     int argc;
104     char *argv[];
105     {
106 schorsch 2.6 int onintr();
107 greg 1.1 char sbuf[256];
108     register int i;
109    
110     progname = argv[0];
111    
112     #ifdef SIGTSTP
113     signal(SIGTSTP, SIG_IGN);
114     #endif
115     if (signal(SIGINT, onintr) == SIG_IGN)
116     signal(SIGINT, SIG_IGN);
117    
118     for (i = 1; i < argc; i++)
119     if (argv[i][0] == '-')
120     switch (argv[i][1]) {
121     case 'd':
122     dither = !dither;
123     break;
124     case 'b':
125     greyscale = !greyscale;
126     break;
127     default:
128     goto userr;
129     }
130     else
131     break;
132    
133     if (i+1 != argc)
134     goto userr;
135    
136     if ((fin = fopen(argv[i], "r")) == NULL) {
137     sprintf(errmsg, "can't open file \"%s\"", argv[i]);
138     quitmsg(errmsg);
139     }
140     /* get header */
141 greg 1.10 getheader(fin, checkhead, NULL);
142     if (wrong_fmt)
143     quitmsg("input must be a Radiance picture");
144 greg 1.1 /* get picture dimensions */
145 greg 1.11 if (fgetresolu(&xmax, &ymax, fin) < 0)
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 schorsch 2.6 static int
170     checkhead( /* deal with line from header */
171     char *line,
172     void *p
173     )
174 greg 1.4 {
175 greg 1.10 char fmt[32];
176    
177 greg 1.6 if (isexpos(line))
178     exposure *= exposval(line);
179 greg 1.10 else if (isformat(line)) {
180     formatval(fmt, line);
181     wrong_fmt = strcmp(fmt, COLRFMT);
182     }
183 gwlarson 2.4 return(0);
184 greg 1.1 }
185    
186    
187     init() /* initialize terminal */
188     {
189     struct sgttyb flags;
190     int lmode;
191    
192     if (isatty(1)) {
193     /* Set literal mode so AED gets bit 8 */
194     ioctl(1, TIOCLGET, &oldlmode);
195     lmode = oldlmode | LLITOUT | LNOFLSH;
196     ioctl(1, TIOCLSET, &lmode);
197     ioctl(1, TIOCLGET, &lmode); /* 4.2 bug */
198     /* Turn terminal echoing off */
199     ioctl(1, TIOCGETP, &oldflags);
200     ioctl(1, TIOCGETP, &flags);
201     flags.sg_flags &= ~ECHO;
202     ioctl(1, TIOCSETP, &flags);
203     initialized = 1;
204     } else
205     quitmsg("output must be to a terminal");
206    
207     /* Reset AED and tell it the data format */
208     command(RST);
209     longwait(2);
210     command(OPT);
211     byte(6); byte(1); /* AED command set */
212     command(SEN); fputs(AEDFMT, stdout);
213     command(SCS); byte(CSTAT); /* console status */
214     command(FFD); /* clear screen */
215     flush();
216     }
217    
218    
219     onintr() /* die gracefully */
220     {
221     if (++intrcnt > 0)
222     quitmsg("interrupt");
223     }
224    
225    
226     quitmsg(err) /* uninitialize terminal and exit */
227     char *err;
228     {
229     if (initialized) { /* close AED */
230     command(DJC); /* disable cursor */
231     command(SEC);
232     byte(WHT); /* Set color to white */
233     aedsetcap(0, 0); /* Put cursor in a good place */
234     byte(END);
235     flush();
236     ioctl(1, TIOCSETP, &oldflags);
237     ioctl(1, TIOCLSET, &oldlmode);
238     putchar('\n');
239     }
240     if (err != NULL) {
241     fprintf(stderr, "%s: %s\n", progname, err);
242     exit(1);
243     }
244     exit(0);
245     }
246    
247    
248 greg 2.5 void
249 greg 1.1 eputs(s)
250     char *s;
251     {
252     fputs(s, stderr);
253     }
254    
255    
256 greg 2.5 void
257 greg 1.1 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     }