home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Raytrace & Morphing / SOS-RAYTRACE.ISO / programm / source / radsrc22 / src / px / aedimage.c next >
Encoding:
C/C++ Source or Header  |  1992-10-02  |  11.4 KB  |  567 lines

  1. /* Copyright (c) 1986 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)aedimage.c 2.3 10/2/92 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  <math.h>
  17.  
  18. #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. #define  GAMMA        2.5        /* gamma value used in correction */
  64.  
  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. int  wrong_fmt = 0;
  104.  
  105.  
  106. main(argc, argv)
  107. int  argc;
  108. char  *argv[];
  109. {
  110.     int  onintr(), checkhead();
  111.     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.     getheader(fin, checkhead, NULL);
  146.     if (wrong_fmt)
  147.         quitmsg("input must be a Radiance picture");
  148.                 /* get picture dimensions */
  149.     if (fgetresolu(&xmax, &ymax, fin) < 0)
  150.         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. }
  171.  
  172.  
  173. checkhead(line)                /* deal with line from header */
  174. char  *line;
  175. {
  176.     char    fmt[32];
  177.  
  178.     if (isexpos(line))
  179.         exposure *= exposval(line);
  180.     else if (isformat(line)) {
  181.         formatval(fmt, line);
  182.         wrong_fmt = strcmp(fmt, COLRFMT);
  183.     }
  184. }
  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. eputs(s)
  249. char  *s;
  250. {
  251.     fputs(s, stderr);
  252. }
  253.  
  254.  
  255. quit(status)
  256. int  status;
  257. {
  258.     quitmsg(status ? "aborted" : NULL);
  259. }
  260.  
  261.  
  262. loopcom()                /* print pixel values interactively */
  263. {
  264.     int  coffset[3];        /* color table offset */
  265.     struct sgttyb  flags;
  266.     COLOR  cval, ctmp;
  267.     int  rept, x, y, j;
  268.     register int  com, i;
  269.                         /* Set raw mode on input */
  270.     ioctl(0, TIOCGETP, &flags);
  271.     flags.sg_flags |= RAW;
  272.     flags.sg_flags &= ~ECHO;
  273.     ioctl(0, TIOCSETP, &flags);
  274.  
  275.     coffset[0] = coffset[1] = coffset[2] = 0;
  276.                         /* set cursor type */
  277.     command(SCC);
  278.     byte(BLK); byte(WHT); byte(15);
  279.     command(SCP);
  280.     byte('+'); byte(0); byte(1);
  281.                         /* loop on command */
  282.     for ( ; ; ) {
  283.         command(EJC);            /* enable cursor */
  284.         flush();
  285.         rept = 0;            /* get command */
  286.         while ((com = getc(stdin)) >= '0' && com <= '9')
  287.             rept = rept*10 + com - '0';
  288.         if (rept == 0) rept = 1;
  289.         command(DJC);            /* disable cursor */
  290.         switch (com) {
  291.         case '\r':
  292.         case '\n':
  293.         case 'l':
  294.         case 'L':
  295.         case 'c':
  296.         case 'C':
  297.         case 'p':
  298.         case 'P':
  299.         case '=':
  300.             aedgetcap(&x, &y);    /* get cursor position */
  301.             y = ymax-1-y;
  302.             if (y < 0 || scanpos[y] == -1)    /* off picture? */
  303.                 break;
  304.                         /* get value */
  305.             setcolor(cval, 0.0, 0.0, 0.0);
  306.             for (j = rept-1; j >= 0; j--) {
  307.                 if (y+j >= NROWS || scanpos[y+j] == -1)
  308.                     continue;
  309.                 getscan(y+j);
  310.                 for (i = 0; i < rept; i++)
  311.                     if (x+i < xmax) {
  312.                         colr_color(ctmp, scanline[x+i]);
  313.                         addcolor(cval, ctmp);
  314.                     }
  315.             }
  316.             scalecolor(cval, 1.0/(rept*rept));
  317.                         /* print value */
  318.             command(SEC);
  319.             byte(scanline[(x+20)%xmax][EXP] >= COLXS ? BLK : WHT);
  320.             byte(END);
  321.             switch (com) {
  322.             case '\r':
  323.             case '\n':
  324.                 printf("%-3g", intens(cval)/exposure);
  325.                 break;
  326.             case 'l':
  327.             case 'L':
  328.                 printf("%-3gL", luminance(cval)/exposure);
  329.                 break;
  330.             case 'c':
  331.             case 'C':
  332.                 printf("(%.2f,%.2f,%.2f)",
  333.                         colval(cval,RED),
  334.                         colval(cval,GRN),
  335.                         colval(cval,BLU));
  336.                 break;
  337.             case 'p':
  338.             case 'P':
  339.                 printf("(%d,%d)", x, y);
  340.                 break;
  341.             case '=':
  342.                 printf("(%d,%d,%d)", coffset[0],
  343.                         coffset[1], coffset[2]);
  344.                 break;
  345.             }
  346.             break;
  347.         case 'w':
  348.             rept = -rept;
  349.         case 'W':
  350.             coffset[0] += rept;
  351.             coffset[1] += rept;
  352.             coffset[2] += rept;
  353.             movecolor(coffset);
  354.             break;
  355.         case 'r':
  356.             rept = -rept;
  357.         case 'R':
  358.             coffset[0] += rept;
  359.             movecolor(coffset);
  360.             break;
  361.         case 'g':
  362.             rept = -rept;
  363.         case 'G':
  364.             coffset[1] += rept;
  365.             movecolor(coffset);
  366.             break;
  367.         case 'b':
  368.             rept = -rept;
  369.         case 'B':
  370.             coffset[2] += rept;
  371.             movecolor(coffset);
  372.             break;
  373.         case '!':
  374.             coffset[0] = coffset[1] = coffset[2] = 0;
  375.             movecolor(coffset);
  376.             break;
  377.         case 'C'-'@':
  378.         case 'q':
  379.         case 'Q':
  380.             return;
  381.         }
  382.     }
  383. }
  384.  
  385.  
  386. getscan(y)
  387. int  y;
  388. {
  389.     if (y != cury) {
  390.         if (scanpos[y] == -1)
  391.             quitmsg("cannot seek in getscan");
  392.         if (fseek(fin, scanpos[y], 0) == -1)
  393.             quitmsg("fseek error");
  394.         cury = y;
  395.     } else
  396.         scanpos[y] = ftell(fin);
  397.  
  398.     if (freadcolrs(scanline, xmax, fin) < 0)
  399.         quitmsg("read error");
  400.  
  401.     cury++;
  402. }
  403.  
  404.  
  405. picreadline3(y, l3)            /* read in 3-byte scanline */
  406. int  y;
  407. register rgbpixel  *l3;
  408. {
  409.     register int    i;
  410.                             /* read scanline */
  411.     getscan(y);
  412.                             /* convert scanline */
  413.     normcolrs(scanline, xmax, 0);
  414.     for (i = 0; i < xmax; i++) {
  415.         l3[i].r = scanline[i][RED];
  416.         l3[i].g = scanline[i][GRN];
  417.         l3[i].b = scanline[i][BLU];
  418.     }
  419. }
  420.  
  421.  
  422. picwriteline(y, l)        /* output scan line of pixel values */
  423. int  y;
  424. register pixel  *l;
  425. {
  426.     int  curpix;
  427.     register int  n, ncols;
  428.     
  429.     disintr();            /* disable interrupts */
  430.     aedsetcap(0, ymax-1-y);
  431.     command(DAI);
  432.     aedcoord(xmax-1, ymax-1-y);
  433.     ncols = xmax;
  434.     if (dither) {        /* pixel run lengths short */
  435.         command(WHS);
  436.         while (ncols-- > 0)
  437.             byte(MINCOLOR + *l++);
  438.     } else {            /* pixel run lengths long */
  439.         command(WHR);
  440.         while (ncols-- > 0) {
  441.             curpix = *l++;
  442.             for (n = 1; n < MAXRLEN; n++) {
  443.                 if (ncols <= 0 || *l != curpix)
  444.                     break;
  445.                 l++; ncols--;
  446.             }
  447.             byte(n);
  448.             byte(MINCOLOR + curpix);
  449.         }
  450.         byte(NUL);
  451.     }
  452.     flush();
  453.     enaintr();            /* enable interrupts */
  454. }
  455.  
  456.  
  457. /*
  458.  * aedsetcap - sets AED's current access pointer to (x, y). Used
  459.  * before writing a span to put it in the right place.
  460.  */
  461.  
  462. aedsetcap(x, y)
  463. register int  x, y;
  464. {
  465.     command(MOV);
  466.     aedcoord(x, y);
  467. }
  468.  
  469. /*
  470.  * aedcoord - puts out an (x, y) coordinate in AED 8 bit format.
  471.  */
  472.  
  473. aedcoord(x, y)
  474. register int  x, y;
  475. {
  476.     putc(((x >> 4) & 0x30) | ((y >> 8) & 0x3), stdout);
  477.     putc(x & 0xff, stdout);
  478.     putc(y & 0xff, stdout);
  479. }
  480.  
  481.  
  482. aedgetcap(xp, yp)        /* get cursor postion */
  483. int  *xp, *yp;
  484. {
  485.     register int  c;
  486.                 /* get cursor postition */
  487.     command(RCP);
  488.     flush();
  489.     c = getc(stdin);
  490.     *xp = (c & 0x30) << 4;
  491.     *yp = (c & 0x3) << 8;
  492.     *xp |= getc(stdin);
  493.     *yp |= getc(stdin);
  494. }
  495.  
  496.  
  497. movecolor(offset)        /* move our color table up or down */
  498. int  offset[3];
  499. {
  500.     register int  i, j, c;
  501.  
  502.     disintr();
  503.     command(SCT);
  504.     byte(MINCOLOR);
  505.     byte(NCOLORS);
  506.     for (i = 0; i < NCOLORS; i++)
  507.         for (j = 0; j < 3; j++) {
  508.             c = colrtbl[j][i] + offset[j];
  509.             if (c < 0)
  510.                 byte(0);
  511.             else if (c > 255)
  512.                 byte(255);
  513.             else
  514.                 byte(c);
  515.         }
  516.     shortwait(20);
  517.     enaintr();
  518. }
  519.  
  520.  
  521. picreadcm(map)            /* do gamma correction */
  522. colormap  map;
  523. {
  524.     register int  i, val;
  525.  
  526.     for (i = 0; i < 256; i++) {
  527.         val = pow((i+0.5)/256.0, 1.0/GAMMA) * 256.0;
  528.         map[0][i] = map[1][i] = map[2][i] = val;
  529.     }
  530. }
  531.  
  532.  
  533. picwritecm(map)            /* write out color map */
  534. colormap  map;
  535. {
  536.     register int  i, j;
  537.  
  538.     disintr();
  539.     command(SCT);
  540.     byte(MINCOLOR);
  541.     byte(NCOLORS);
  542.     for (i = 0; i < NCOLORS; i++)
  543.         for (j = 0; j < 3; j++)
  544.             byte(map[j][i]);
  545.     shortwait(20);
  546.     enaintr();
  547. }
  548.  
  549.  
  550. longwait(t)        /* longer wait */
  551. int  t;
  552. {
  553.     flush();
  554.     sleep(t);
  555. }
  556.  
  557.  
  558. shortwait(t)        /* shorter wait */
  559. int  t;
  560. {
  561.     register long  l = t*1000;
  562.  
  563.     flush();
  564.     while (l--)
  565.         ;
  566. }
  567.