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

  1. /* Copyright (c) 1992 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)vgaimage.c 2.2 10/14/92 LBL";
  5. #endif
  6.  
  7. /*
  8.  *  vgaimage.c - driver for VGA board under DOS
  9.  */
  10.  
  11. #include  "standard.h"
  12. #include  <graph.h>
  13. #include  "color.h"
  14. #include  "random.h"
  15. #include  "resolu.h"
  16. #include <dos.h>
  17. #include <i86.h>
  18.  
  19. #define  M_RDOWN        0x8
  20. #define  M_RUP          0x10
  21. #define  M_LDOWN        0x2
  22. #define  M_LUP          0x4
  23. #define  M_MOTION       0x1
  24.  
  25. int crad;
  26. int mouse_event = 0;
  27. int mouse_xpos = -1;
  28. int mouse_ypos = -1;
  29.  
  30. #define  hide_cursor()  move_cursor(-1,-1)
  31. #define  show_cursor()  move_cursor(mouse_xpos,mouse_ypos)
  32.  
  33. #define  CTRL(c)        ((c)-'@')
  34.  
  35. #define  MAXWIDTH       1024
  36. #define  MAXHEIGHT      768
  37.  
  38. short  ourblack = 0; ourwhite = 1;
  39.  
  40. double  gamcor = 2.2;                   /* gamma correction */
  41.  
  42. int  dither = 1;                        /* dither colors? */
  43.  
  44. int  maxcolors = 0;                     /* maximum colors */
  45. int  minpix = 0;                        /* minimum pixel value */
  46. int  greyscale = 0;                     /* in grey */
  47.  
  48. int  scale = 0;                         /* scalefactor; power of two */
  49.  
  50. COLR  scanline[MAXWIDTH];               /* scan line buffer */
  51.  
  52. int  xmax, ymax;                        /* picture dimensions */
  53. FILE  *fin = stdin;                     /* input file */
  54. long  scanpos[MAXHEIGHT];               /* scan line positions in file */
  55. int  cury = 0;                          /* current scan location */
  56.  
  57. double  exposure = 1.0;                 /* exposure compensation used */
  58.  
  59. int  wrongformat = 0;                   /* input in another format? */
  60.  
  61. struct {
  62.     int  xmin, ymin, xsiz, ysiz;
  63. }  box = {0, 0, 0, 0};                  /* current box */
  64.  
  65. int  initialized = 0;
  66. int  cheight, cwidth;
  67.  
  68. #define postext(x,y)    _settextposition(1+(y)/cheight,1+(x)/cwidth)
  69.  
  70. char  *progname;
  71.  
  72. char  errmsg[128];
  73.  
  74. extern BYTE  clrtab[256][3];            /* global color map */
  75.  
  76. extern long  ftell();
  77.  
  78.  
  79. main(argc, argv)
  80. int  argc;
  81. char  *argv[];
  82. {
  83.     extern char  *getenv(), *fixargv0();
  84.     char  *gv;
  85.     int  headline();
  86.     int  i;
  87.     
  88.     progname = argv[0] = fixargv0(argv[0]);
  89.     if ((gv = getenv("GAMMA")) != NULL)
  90.         gamcor = atof(gv);
  91.  
  92.     for (i = 1; i < argc; i++)
  93.         if (argv[i][0] == '-')
  94.             switch (argv[i][1]) {
  95.             case 'c':
  96.                 maxcolors = atoi(argv[++i]);
  97.                 break;
  98.             case 'b':
  99.                 greyscale = !greyscale;
  100.                 break;
  101.             case 'm':
  102.                 maxcolors = 2;
  103.                 break;
  104.             case 'd':
  105.                 dither = !dither;
  106.                 break;
  107.             case 'e':
  108.                 if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
  109.                     goto userr;
  110.                 scale = atoi(argv[++i]);
  111.                 break;
  112.             case 'g':
  113.                 gamcor = atof(argv[++i]);
  114.                 break;
  115.             default:
  116.                 goto userr;
  117.             }
  118.         else
  119.             break;
  120.  
  121.     if (i == argc-1) {              /* open picture */
  122.         fin = fopen(argv[i], "r");
  123.         if (fin == NULL) {
  124.             sprintf(errmsg, "cannot open file \"%s\"", argv[i]);
  125.             quiterr(errmsg);
  126.         }
  127.     } else if (i != argc)
  128.         goto userr;
  129.     setmode(fileno(fin), O_BINARY);
  130.                 /* get header */
  131.     getheader(fin, headline, NULL);
  132.                 /* get picture dimensions */
  133.     if (wrongformat || fgetresolu(&xmax, &ymax, fin) < 0)
  134.         quiterr("bad picture format");
  135.     if (xmax > MAXWIDTH | ymax > MAXHEIGHT)
  136.         quiterr("input picture too large for VGA");
  137.  
  138.     init();                 /* initialize and display */
  139.  
  140.     while (docommand())     /* loop on command */
  141.         ;
  142.     quiterr(NULL);
  143. userr:
  144.     fprintf(stderr,
  145.     "Usage: %s [-b][-m][-d][-c ncolors][-e +/-stops] file\n", progname);
  146.     exit(1);
  147. }
  148.  
  149.  
  150. headline(s)             /* get relevant info from header */
  151. char  *s;
  152. {
  153.     char  fmt[32];
  154.  
  155.     if (isexpos(s))
  156.         exposure *= exposval(s);
  157.     else if (isformat(s)) {
  158.         formatval(fmt, s);
  159.         wrongformat = strcmp(fmt, COLRFMT);
  160.     }
  161. }
  162.  
  163.  
  164. init()                  /* initialize and load display */
  165. {
  166.     static struct {
  167.         short   mode;
  168.         short   xsiz, ysiz;
  169.     } video[] = {    
  170.         {_MRES256COLOR, 320, 200},
  171.         {_VRES256COLOR, 640, 400},
  172.         {_SVRES256COLOR, 800, 600},
  173.         {_XRES256COLOR, 1024, 768},
  174.         -1
  175.     };
  176.     struct videoconfig      config;
  177.     register int    i;
  178.                 /* pick a card... */
  179.     for (i = 0; video[i].mode != -1; i++)
  180.         if (video[i].xsiz >= xmax && video[i].ysiz >= ymax)
  181.             break;
  182.     if (video[i].mode == -1)
  183.         quiterr("input picture too large");
  184.     if (_setvideomode(video[i].mode) == 0)
  185.         quiterr("inadequate display card for picture");
  186.     ms_init();
  187.     initialized = 1;
  188.     _getvideoconfig(&config);
  189.     if (maxcolors == 0)
  190.         maxcolors = config.numcolors;
  191.     if (maxcolors > 4) {
  192.         maxcolors -= minpix = 2;
  193.         _settextcolor(ourwhite);
  194.     }
  195.     cheight = config.numypixels/config.numtextrows;
  196.     cwidth = config.numxpixels/config.numtextcols;
  197.                 /* clear scan position array */
  198.     for (i = 0; i < ymax; i++)
  199.         scanpos[i] = -1;
  200.                 /* display image */
  201.     if (greyscale)
  202.         greyimage();
  203.     else
  204.         mappedimage();
  205. }
  206.  
  207.  
  208. quiterr(err)            /* print message and exit */
  209. char  *err;
  210. {
  211.     if (initialized) {
  212.         ms_done();
  213.         _setvideomode(_DEFAULTMODE);
  214.     }
  215.     if (err != NULL) {
  216.         fprintf(stderr, "%s: %s\n", progname, err);
  217.         exit(1);
  218.     }
  219.     exit(0);
  220. }
  221.  
  222.  
  223. int
  224. docommand()                     /* execute command */
  225. {
  226.     char  buf[64];
  227.     COLOR  cval;
  228.     int  com;
  229.     double  comp;
  230.  
  231.     while (!kbhit())
  232.         watch_mouse();
  233.     com = getch();
  234.     switch (com) {                  /* interpret command */
  235.     case 'q':
  236.     case CTRL('Z'):                         /* quit */
  237.         return(0);
  238.     case '\n':
  239.     case '\r':
  240.     case 'l':
  241.     case 'c':                               /* value */
  242.         if (avgbox(cval) == -1)
  243.             return(-1);
  244.         switch (com) {
  245.         case '\n':
  246.         case '\r':                              /* radiance */
  247.             sprintf(buf, "%.3f", intens(cval)/exposure);
  248.             break;
  249.         case 'l':                               /* luminance */
  250.             sprintf(buf, "%.0fL", luminance(cval)/exposure);
  251.             break;
  252.         case 'c':                               /* color */
  253.             comp = pow(2.0, (double)scale);
  254.             sprintf(buf, "(%.2f,%.2f,%.2f)",
  255.                     colval(cval,RED)*comp,
  256.                     colval(cval,GRN)*comp,
  257.                     colval(cval,BLU)*comp);
  258.             break;
  259.         }
  260.         postext(box.xmin+box.xsiz/2, box.ymin+box.ysiz/2);
  261.         hide_cursor();
  262.         _outtext(buf);
  263.         show_cursor();
  264.         return(1);
  265.     default:
  266.         return(-1);
  267.     }
  268. }
  269.  
  270.  
  271. watch_mouse()                   /* look after mousie */
  272. {
  273.     int     a_x, a_y, l_x, l_y;
  274.  
  275.     if (mouse_event & M_MOTION)
  276.         move_cursor(mouse_xpos, mouse_ypos);
  277.     if (!(mouse_event & M_LDOWN))
  278.         return;
  279.     l_x = a_x = mouse_xpos; l_y = a_y = mouse_ypos;
  280.     hide_cursor();
  281.     revbox(a_x, a_y, l_x, l_y);             /* show box */
  282.     do {
  283.         mouse_event = 0;
  284.         while (!mouse_event)
  285.             ;
  286.         if (mouse_event & M_MOTION) {
  287.             revbox(a_x, a_y, l_x, l_y);
  288.             revbox(a_x, a_y, l_x=mouse_xpos, l_y=mouse_ypos);
  289.         }
  290.     } while (!(mouse_event & M_LUP));
  291.     revbox(a_x, a_y, l_x, l_y);             /* hide box */
  292.     show_cursor();
  293.     box.xmin = mouse_xpos;
  294.     box.ymin = mouse_ypos;
  295.     if (box.xmin > a_x) {
  296.         box.xsiz = box.xmin - a_x + 1;
  297.         box.xmin = a_x;
  298.     } else {
  299.         box.xsiz = a_x - box.xmin + 1;
  300.     }
  301.     if (box.ymin > a_y) {
  302.         box.ysiz = box.ymin - a_y + 1;
  303.         box.ymin = a_y;
  304.     } else {
  305.         box.ysiz = a_y - box.ymin + 1;
  306.     }
  307.     mouse_event = 0;
  308. }
  309.  
  310.  
  311. revbox(x0, y0, x1, y1)                  /* draw box with reversed lines */
  312. int  x0, y0, x1, y1;
  313. {
  314.     _setplotaction(_GXOR);
  315.     _setcolor(255);
  316.     _moveto(x0, y0);
  317.     _lineto(x1, y0);
  318.     _lineto(x1, y1);
  319.     _lineto(x0, y1);
  320.     _lineto(x0, y0);
  321. }
  322.  
  323.  
  324. int
  325. avgbox(clr)                             /* average color over current box */
  326. COLOR  clr;
  327. {
  328.     static COLOR  lc;
  329.     static int  ll, lr, lt, lb;
  330.     int  left, right, top, bottom;
  331.     int  y;
  332.     double  d;
  333.     COLOR  ctmp;
  334.     register int  x;
  335.  
  336.     setcolor(clr, 0.0, 0.0, 0.0);
  337.     left = box.xmin;
  338.     right = left + box.xsiz;
  339.     if (left < 0)
  340.         left = 0;
  341.     if (right > xmax)
  342.         right = xmax;
  343.     if (left >= right)
  344.         return(-1);
  345.     top = box.ymin;
  346.     bottom = top + box.ysiz;
  347.     if (top < 0)
  348.         top = 0;
  349.     if (bottom > ymax)
  350.         bottom = ymax;
  351.     if (top >= bottom)
  352.         return(-1);
  353.     if (left == ll && right == lr && top == lt && bottom == lb) {
  354.         copycolor(clr, lc);
  355.         return(0);
  356.     }
  357.     for (y = top; y < bottom; y++) {
  358.         if (getscan(y) == -1)
  359.             return(-1);
  360.         for (x = left; x < right; x++) {
  361.             colr_color(ctmp, scanline[x]);
  362.             addcolor(clr, ctmp);
  363.         }
  364.     }
  365.     d = 1.0/((right-left)*(bottom-top));
  366.     scalecolor(clr, d);
  367.     ll = left; lr = right; lt = top; lb = bottom;
  368.     copycolor(lc, clr);
  369.     return(0);
  370. }
  371.  
  372.  
  373. setpalette()                    /* set our palette using clrtab */
  374. {
  375.     long    cvals[256];
  376.     register int    i;
  377.  
  378.     if (minpix >= 2) {
  379.         cvals[ourblack] = _BLACK; cvals[ourwhite] = _BRIGHTWHITE;
  380.     }
  381.     for (i = 0; i < maxcolors; i++)
  382.         cvals[i+minpix] = clrtab[i][BLU]<<14 & 0x3f0000L |
  383.                   clrtab[i][GRN]<<6 & 0x3f00 |
  384.                   clrtab[i][RED]>>2;
  385.     _remapallpalette(cvals);
  386. }
  387.  
  388.  
  389. greyimage()                     /* display greyscale image */
  390. {
  391.     short   thiscolor, lastcolor = -1;
  392.     int     y;
  393.     register int    x;
  394.                     /* set gamma correction */
  395.     setcolrgam(gamcor);
  396.                     /* set up color map */
  397.     for (x = 0; x < maxcolors; x++)
  398.         clrtab[x][RED] = clrtab[x][GRN] =
  399.             clrtab[x][BLU] = ((long)x*256+maxcolors/2)/maxcolors;
  400.     setpalette();
  401.     _setplotaction(_GPSET);
  402.                     /* read and display file */
  403.     for (y = 0; y < ymax; y++) {
  404.         getscan(y);
  405.         if (scale)
  406.             shiftcolrs(scanline, xmax, scale);
  407.         colrs_gambs(scanline, xmax);
  408.         if (maxcolors < 256)
  409.             for (x = 0; x < xmax; x++) { 
  410.                 thiscolor = ((long)normbright(scanline[x]) *
  411.                     maxcolors + 128) >> 8;
  412.                 if (thiscolor != lastcolor)
  413.                     _setcolor((lastcolor=thiscolor)+minpix);
  414.                 _setpixel(x, y);
  415.             }
  416.         else
  417.             for (x = 0; x < xmax; x++) {
  418.                 thiscolor = normbright(scanline[x]);
  419.                 if (thiscolor != lastcolor)
  420.                     _setcolor((lastcolor=thiscolor)+minpix);
  421.                 _setpixel(x, y);
  422.             }
  423.     }
  424. }
  425.  
  426.  
  427. mappedimage()                   /* display color-mapped image */
  428. {
  429.     BYTE    bscan[MAXWIDTH];
  430.     int     y;
  431.     register int    x;
  432.                     /* set gamma correction */
  433.     setcolrgam(gamcor);
  434.                     /* make histogram */
  435.     _outtext("Quantizing image -- Please wait...");
  436.     new_histo();
  437.     for (y = 0; y < ymax; y++) {
  438.         if (getscan(y) < 0)
  439.             quiterr("seek error in getmapped");
  440.         if (scale)
  441.             shiftcolrs(scanline, xmax, scale);
  442.         colrs_gambs(scanline, xmax);
  443.         cnt_colrs(scanline, xmax);
  444.     }
  445.                     /* map pixels */
  446.     if (!new_clrtab(maxcolors))
  447.         quiterr("cannot create color map");
  448.     setpalette();
  449.     _setplotaction(_GPSET);
  450.                     /* display image */
  451.     for (y = 0; y < ymax; y++) {
  452.         if (getscan(y) < 0)
  453.             quiterr("seek error in getmapped");
  454.         if (scale)
  455.             shiftcolrs(scanline, xmax, scale);
  456.         colrs_gambs(scanline, xmax);
  457.         if (dither)
  458.             dith_colrs(bscan, scanline, xmax);
  459.         else
  460.             map_colrs(bscan, scanline, xmax);
  461.         for (x = 0; x < xmax; x++) {
  462.             if (x==0 || bscan[x] != bscan[x-1])
  463.                 _setcolor(bscan[x]+minpix);
  464.             _setpixel(x, y);
  465.         }
  466.     }
  467. }
  468.  
  469.  
  470. getscan(y)
  471. int  y;
  472. {
  473.     if (y != cury) {
  474.         if (scanpos[y] == -1)
  475.             return(-1);
  476.         if (fseek(fin, scanpos[y], 0) == -1)
  477.             quiterr("fseek error");
  478.         cury = y;
  479.     } else if (scanpos != NULL && scanpos[y] == -1)
  480.         scanpos[y] = ftell(fin);
  481.  
  482.     if (freadcolrs(scanline, xmax, fin) < 0)
  483.         quiterr("picture read error");
  484.  
  485.     cury++;
  486.     return(0);
  487. }
  488.  
  489.  
  490. /*
  491.  * Microsoft Mouse handling routines
  492.  */
  493.  
  494.  
  495. #pragma off (check_stack)
  496. void _loadds far mouse_handler (int max, int mcx, int mdx)
  497. {
  498. #pragma aux mouse_handler parm [EAX] [ECX] [EDX]
  499.     mouse_event = max;
  500.     mouse_xpos = mcx;
  501.     mouse_ypos = mdx;
  502. }
  503. #pragma on (check_stack)
  504.  
  505.  
  506. void
  507. move_cursor(newx, newy)         /* move cursor to new position */
  508. int  newx, newy;
  509. {
  510.     static char  *imp = NULL;
  511.     static int  curx = -1, cury = -1;
  512. #define xcmin           (curx-crad<0 ? 0 : curx-crad)
  513. #define ycmin           (cury-crad<0 ? 0 : cury-crad)
  514. #define xcmax           (curx+crad>=xmax ? xmax-1 : curx+crad)
  515. #define ycmax           (cury+crad>=ymax ? ymax-1 : cury+crad)
  516.  
  517.     if (newx == curx & newy == cury)
  518.         return;
  519.     if (imp == NULL && 
  520.         (imp = bmalloc(_imagesize(0,0,2*crad+1,2*crad+1))) == NULL) {
  521.         quiterr("out of memory in move_cursor");
  522.     }
  523.     if (curx >= 0 & cury >= 0)      /* clear old cursor */
  524.         _putimage(xcmin, ycmin, imp, _GPSET);
  525.                     /* record new position */
  526.     curx = newx; cury = newy;
  527.     if (curx < 0 | cury < 0)
  528.         return;         /* no cursor */
  529.                     /* save under new cursor */
  530.     _getimage(xcmin, ycmin, xcmax, ycmax, imp);
  531.                     /* draw new cursor */
  532.     _setplotaction(_GPSET);
  533.     _setcolor(ourwhite);
  534.     _rectangle(_GFILLINTERIOR, xcmin, cury-1, xcmax, cury+1);
  535.     _rectangle(_GFILLINTERIOR, curx-1, ycmin, curx+1, ycmax);
  536.     _setcolor(ourblack);
  537.     _moveto(xcmin+1, cury);
  538.     _lineto(xcmax-1, cury);
  539.     _moveto(curx, ycmin+1);
  540.     _lineto(curx, ycmax-1);
  541. #undef xcmin
  542. #undef ycmin
  543. #undef xcmax
  544. #undef ycmax
  545. }
  546.  
  547.  
  548. int
  549. ms_init()
  550. {
  551.     struct SREGS sregs;
  552.     union REGS inregs, outregs;
  553.     int far *ptr;
  554.     int (far *function_ptr)();
  555.  
  556.     segread(&sregs);
  557.  
  558.     /* check for mouse driver */
  559.  
  560.     inregs.w.ax = 0;
  561.     int386 (0x33, &inregs, &outregs);
  562.     if( outregs.w.ax != -1 ) {
  563.     return(0);
  564.     }
  565.  
  566.     crad = ymax/40;
  567.     
  568.     /* set screen limits */
  569.  
  570.     inregs.w.ax = 0x7;          /* horizontal resolution */
  571.     inregs.w.cx = 0;
  572.     inregs.w.dx = xmax-1;
  573.     int386x( 0x33, &inregs, &outregs, &sregs );
  574.     inregs.w.ax = 0x8;          /* vertical resolution */
  575.     inregs.w.cx = 0;
  576.     inregs.w.dx = ymax-1;
  577.     int386x( 0x33, &inregs, &outregs, &sregs );
  578.  
  579.     /* install watcher */
  580.  
  581.     inregs.w.ax = 0xC;
  582.     inregs.w.cx = M_LDOWN | M_LUP | M_MOTION;
  583.     function_ptr = mouse_handler;
  584.     inregs.x.edx = FP_OFF( function_ptr );
  585.     sregs.es     = FP_SEG( function_ptr );
  586.     int386x( 0x33, &inregs, &outregs, &sregs );
  587.     
  588.     return(1);
  589. }
  590.  
  591. ms_done()
  592. {
  593.     union REGS inregs, outregs;
  594.  
  595.     /* uninstall watcher */
  596.  
  597.     inregs.w.ax = 0;
  598.     int386 (0x33, &inregs, &outregs);
  599. }
  600.  
  601.