ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/aedimage.c
Revision: 2.5
Committed: Sat Feb 22 02:07:27 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 2.4: +3 -4 lines
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

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