home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1986 Regents of the University of California */
-
- #ifndef lint
- static char SCCSid[] = "@(#)aedimage.c 2.3 10/2/92 LBL";
- #endif
-
- /*
- * aedimage.c - RADIANCE driver for AED 512 terminal.
- *
- * 3/20/86
- * 3/3/88 Added calls to Paul Heckbert's ciq routines
- */
-
- #include <stdio.h>
-
- #include <math.h>
-
- #include <signal.h>
-
- #include <sys/ioctl.h>
-
- #include "pic.h"
-
- #include "color.h"
-
-
- /* AED command characters */
-
- #define AEDFMT "1888N" /* Format string to send to AED */
- #define CSTAT 0100 /* Console status: lower case */
- #define SCS 96 /* Set Console Status */
- #define SCT 75 /* Set color lookup table */
- #define SEC 67 /* Set color for vector drawing */
- #define MOV 81 /* Set CAP (current access pointer) to x, y */
- #define MVR 105 /* Set CAP relative */
- #define DVA 65 /* Draw vector to new CAP x, y */
- #define DVR 108 /* Draw vector relative */
- #define WHS 88 /* Write horizontal scan */
- #define WHR 92 /* Write horizontal runs */
- #define OPT 40 /* Miscellaneous terminal control */
- #define SEN 71 /* Set encoding types */
- #define RST 48 /* Reset terminal */
- #define FFD 12 /* Clear screen */
- #define SCS 96 /* Set status */
- #define DAI 114 /* Define area of interest */
- #define EJC 85 /* Enable Joystick cursor positioning */
- #define DJC 100 /* Disable Joystick cursor positioning */
- #define SCC 99 /* Set Cursor Colors */
- #define SCP 93 /* Set Cursor Parameters */
- #define RCP 106 /* Read Cursor Position */
- #define MAXRLEN 255 /* Maximum runlength for a span */
- #define NUL 0 /* Null terminates run sequences */
- #define ESC 27 /* Escape starts a command sequence */
- #define END 1 /* Ctrl-A used to terminate command mode */
-
- #define BLK 0 /* color table entry for black */
- #define WHT 7 /* color table entry for white */
-
- #define command(c) (putc(ESC, stdout), putc(c, stdout))
- #define byte(b) putc(b, stdout)
- #define flush() fflush(stdout)
-
- #define GAMMA 2.5 /* gamma value used in correction */
-
- #define MINCOLOR 8 /* start of device color table */
-
- #define NCOLORS 248 /* available color table size */
-
- #define NROWS 512 /* maximum # rows for output */
- #define NCOLS 512 /* maximum # columns for output */
-
- int dither = 0; /* dither colors? */
-
- int greyscale = 0; /* grey only? */
-
- int initialized = 0;
- struct sgttyb oldflags;
- int oldlmode;
-
- int intrcnt = 0; /* interrupt well */
-
- #define disintr() (intrcnt--) /* disable interrupts */
- #define enaintr() onintr() /* enable interrupts */
-
- char *progname;
-
- char errmsg[128];
-
- COLR scanline[NCOLS];
-
- colormap colrtbl;
-
- int cury;
-
- int xmax, ymax;
-
- FILE *fin;
-
- extern long ftell();
- long scanpos[NROWS];
-
- double exposure = 1.0;
- int wrong_fmt = 0;
-
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int onintr(), checkhead();
- char sbuf[256];
- register int i;
-
- progname = argv[0];
-
- #ifdef SIGTSTP
- signal(SIGTSTP, SIG_IGN);
- #endif
- if (signal(SIGINT, onintr) == SIG_IGN)
- signal(SIGINT, SIG_IGN);
-
- for (i = 1; i < argc; i++)
- if (argv[i][0] == '-')
- switch (argv[i][1]) {
- case 'd':
- dither = !dither;
- break;
- case 'b':
- greyscale = !greyscale;
- break;
- default:
- goto userr;
- }
- else
- break;
-
- if (i+1 != argc)
- goto userr;
-
- if ((fin = fopen(argv[i], "r")) == NULL) {
- sprintf(errmsg, "can't open file \"%s\"", argv[i]);
- quitmsg(errmsg);
- }
- /* get header */
- getheader(fin, checkhead, NULL);
- if (wrong_fmt)
- quitmsg("input must be a Radiance picture");
- /* get picture dimensions */
- if (fgetresolu(&xmax, &ymax, fin) < 0)
- quitmsg("bad picture size");
- if (xmax > NCOLS || ymax > NROWS)
- quitmsg("resolution mismatch");
-
- init(); /* initialize terminal for output */
-
- for (i = 0; i < NROWS; i++)
- scanpos[i] = -1;
-
- if (greyscale) /* map colors and display */
- biq(dither,NCOLORS,1,colrtbl);
- else
- ciq(dither,NCOLORS,1,colrtbl);
-
- loopcom();
-
- quitmsg(NULL);
- userr:
- fprintf(stderr, "Usage: %s [-d][-b] input\n", progname);
- quit(1);
- }
-
-
- checkhead(line) /* deal with line from header */
- char *line;
- {
- char fmt[32];
-
- if (isexpos(line))
- exposure *= exposval(line);
- else if (isformat(line)) {
- formatval(fmt, line);
- wrong_fmt = strcmp(fmt, COLRFMT);
- }
- }
-
-
- init() /* initialize terminal */
- {
- struct sgttyb flags;
- int lmode;
-
- if (isatty(1)) {
- /* Set literal mode so AED gets bit 8 */
- ioctl(1, TIOCLGET, &oldlmode);
- lmode = oldlmode | LLITOUT | LNOFLSH;
- ioctl(1, TIOCLSET, &lmode);
- ioctl(1, TIOCLGET, &lmode); /* 4.2 bug */
- /* Turn terminal echoing off */
- ioctl(1, TIOCGETP, &oldflags);
- ioctl(1, TIOCGETP, &flags);
- flags.sg_flags &= ~ECHO;
- ioctl(1, TIOCSETP, &flags);
- initialized = 1;
- } else
- quitmsg("output must be to a terminal");
-
- /* Reset AED and tell it the data format */
- command(RST);
- longwait(2);
- command(OPT);
- byte(6); byte(1); /* AED command set */
- command(SEN); fputs(AEDFMT, stdout);
- command(SCS); byte(CSTAT); /* console status */
- command(FFD); /* clear screen */
- flush();
- }
-
-
- onintr() /* die gracefully */
- {
- if (++intrcnt > 0)
- quitmsg("interrupt");
- }
-
-
- quitmsg(err) /* uninitialize terminal and exit */
- char *err;
- {
- if (initialized) { /* close AED */
- command(DJC); /* disable cursor */
- command(SEC);
- byte(WHT); /* Set color to white */
- aedsetcap(0, 0); /* Put cursor in a good place */
- byte(END);
- flush();
- ioctl(1, TIOCSETP, &oldflags);
- ioctl(1, TIOCLSET, &oldlmode);
- putchar('\n');
- }
- if (err != NULL) {
- fprintf(stderr, "%s: %s\n", progname, err);
- exit(1);
- }
- exit(0);
- }
-
-
- eputs(s)
- char *s;
- {
- fputs(s, stderr);
- }
-
-
- quit(status)
- int status;
- {
- quitmsg(status ? "aborted" : NULL);
- }
-
-
- loopcom() /* print pixel values interactively */
- {
- int coffset[3]; /* color table offset */
- struct sgttyb flags;
- COLOR cval, ctmp;
- int rept, x, y, j;
- register int com, i;
- /* Set raw mode on input */
- ioctl(0, TIOCGETP, &flags);
- flags.sg_flags |= RAW;
- flags.sg_flags &= ~ECHO;
- ioctl(0, TIOCSETP, &flags);
-
- coffset[0] = coffset[1] = coffset[2] = 0;
- /* set cursor type */
- command(SCC);
- byte(BLK); byte(WHT); byte(15);
- command(SCP);
- byte('+'); byte(0); byte(1);
- /* loop on command */
- for ( ; ; ) {
- command(EJC); /* enable cursor */
- flush();
- rept = 0; /* get command */
- while ((com = getc(stdin)) >= '0' && com <= '9')
- rept = rept*10 + com - '0';
- if (rept == 0) rept = 1;
- command(DJC); /* disable cursor */
- switch (com) {
- case '\r':
- case '\n':
- case 'l':
- case 'L':
- case 'c':
- case 'C':
- case 'p':
- case 'P':
- case '=':
- aedgetcap(&x, &y); /* get cursor position */
- y = ymax-1-y;
- if (y < 0 || scanpos[y] == -1) /* off picture? */
- break;
- /* get value */
- setcolor(cval, 0.0, 0.0, 0.0);
- for (j = rept-1; j >= 0; j--) {
- if (y+j >= NROWS || scanpos[y+j] == -1)
- continue;
- getscan(y+j);
- for (i = 0; i < rept; i++)
- if (x+i < xmax) {
- colr_color(ctmp, scanline[x+i]);
- addcolor(cval, ctmp);
- }
- }
- scalecolor(cval, 1.0/(rept*rept));
- /* print value */
- command(SEC);
- byte(scanline[(x+20)%xmax][EXP] >= COLXS ? BLK : WHT);
- byte(END);
- switch (com) {
- case '\r':
- case '\n':
- printf("%-3g", intens(cval)/exposure);
- break;
- case 'l':
- case 'L':
- printf("%-3gL", luminance(cval)/exposure);
- break;
- case 'c':
- case 'C':
- printf("(%.2f,%.2f,%.2f)",
- colval(cval,RED),
- colval(cval,GRN),
- colval(cval,BLU));
- break;
- case 'p':
- case 'P':
- printf("(%d,%d)", x, y);
- break;
- case '=':
- printf("(%d,%d,%d)", coffset[0],
- coffset[1], coffset[2]);
- break;
- }
- break;
- case 'w':
- rept = -rept;
- case 'W':
- coffset[0] += rept;
- coffset[1] += rept;
- coffset[2] += rept;
- movecolor(coffset);
- break;
- case 'r':
- rept = -rept;
- case 'R':
- coffset[0] += rept;
- movecolor(coffset);
- break;
- case 'g':
- rept = -rept;
- case 'G':
- coffset[1] += rept;
- movecolor(coffset);
- break;
- case 'b':
- rept = -rept;
- case 'B':
- coffset[2] += rept;
- movecolor(coffset);
- break;
- case '!':
- coffset[0] = coffset[1] = coffset[2] = 0;
- movecolor(coffset);
- break;
- case 'C'-'@':
- case 'q':
- case 'Q':
- return;
- }
- }
- }
-
-
- getscan(y)
- int y;
- {
- if (y != cury) {
- if (scanpos[y] == -1)
- quitmsg("cannot seek in getscan");
- if (fseek(fin, scanpos[y], 0) == -1)
- quitmsg("fseek error");
- cury = y;
- } else
- scanpos[y] = ftell(fin);
-
- if (freadcolrs(scanline, xmax, fin) < 0)
- quitmsg("read error");
-
- cury++;
- }
-
-
- picreadline3(y, l3) /* read in 3-byte scanline */
- int y;
- register rgbpixel *l3;
- {
- register int i;
- /* read scanline */
- getscan(y);
- /* convert scanline */
- normcolrs(scanline, xmax, 0);
- for (i = 0; i < xmax; i++) {
- l3[i].r = scanline[i][RED];
- l3[i].g = scanline[i][GRN];
- l3[i].b = scanline[i][BLU];
- }
- }
-
-
- picwriteline(y, l) /* output scan line of pixel values */
- int y;
- register pixel *l;
- {
- int curpix;
- register int n, ncols;
-
- disintr(); /* disable interrupts */
- aedsetcap(0, ymax-1-y);
- command(DAI);
- aedcoord(xmax-1, ymax-1-y);
- ncols = xmax;
- if (dither) { /* pixel run lengths short */
- command(WHS);
- while (ncols-- > 0)
- byte(MINCOLOR + *l++);
- } else { /* pixel run lengths long */
- command(WHR);
- while (ncols-- > 0) {
- curpix = *l++;
- for (n = 1; n < MAXRLEN; n++) {
- if (ncols <= 0 || *l != curpix)
- break;
- l++; ncols--;
- }
- byte(n);
- byte(MINCOLOR + curpix);
- }
- byte(NUL);
- }
- flush();
- enaintr(); /* enable interrupts */
- }
-
-
- /*
- * aedsetcap - sets AED's current access pointer to (x, y). Used
- * before writing a span to put it in the right place.
- */
-
- aedsetcap(x, y)
- register int x, y;
- {
- command(MOV);
- aedcoord(x, y);
- }
-
- /*
- * aedcoord - puts out an (x, y) coordinate in AED 8 bit format.
- */
-
- aedcoord(x, y)
- register int x, y;
- {
- putc(((x >> 4) & 0x30) | ((y >> 8) & 0x3), stdout);
- putc(x & 0xff, stdout);
- putc(y & 0xff, stdout);
- }
-
-
- aedgetcap(xp, yp) /* get cursor postion */
- int *xp, *yp;
- {
- register int c;
- /* get cursor postition */
- command(RCP);
- flush();
- c = getc(stdin);
- *xp = (c & 0x30) << 4;
- *yp = (c & 0x3) << 8;
- *xp |= getc(stdin);
- *yp |= getc(stdin);
- }
-
-
- movecolor(offset) /* move our color table up or down */
- int offset[3];
- {
- register int i, j, c;
-
- disintr();
- command(SCT);
- byte(MINCOLOR);
- byte(NCOLORS);
- for (i = 0; i < NCOLORS; i++)
- for (j = 0; j < 3; j++) {
- c = colrtbl[j][i] + offset[j];
- if (c < 0)
- byte(0);
- else if (c > 255)
- byte(255);
- else
- byte(c);
- }
- shortwait(20);
- enaintr();
- }
-
-
- picreadcm(map) /* do gamma correction */
- colormap map;
- {
- register int i, val;
-
- for (i = 0; i < 256; i++) {
- val = pow((i+0.5)/256.0, 1.0/GAMMA) * 256.0;
- map[0][i] = map[1][i] = map[2][i] = val;
- }
- }
-
-
- picwritecm(map) /* write out color map */
- colormap map;
- {
- register int i, j;
-
- disintr();
- command(SCT);
- byte(MINCOLOR);
- byte(NCOLORS);
- for (i = 0; i < NCOLORS; i++)
- for (j = 0; j < 3; j++)
- byte(map[j][i]);
- shortwait(20);
- enaintr();
- }
-
-
- longwait(t) /* longer wait */
- int t;
- {
- flush();
- sleep(t);
- }
-
-
- shortwait(t) /* shorter wait */
- int t;
- {
- register long l = t*1000;
-
- flush();
- while (l--)
- ;
- }
-