home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / software / unix / saoimage / sao1_07.tar / clrvary.c < prev    next >
C/C++ Source or Header  |  1990-04-20  |  6KB  |  176 lines

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    clrvary.c (Color Vary)
  6.  * Purpose:    Interactive color manipulation keyed to mouse position
  7.  * Subroutine:    vary_colors()                returns: void
  8.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  9.  *        You may do anything you like with this file except remove
  10.  *        this copyright.  The Smithsonian Astrophysical Observatory
  11.  *        makes no representations about the suitability of this
  12.  *        software for any purpose.  It is provided "as is" without
  13.  *        express or implied warranty.
  14.  * Modified:    {0} Michael VanHilst    initial version         15 June 1989
  15.  *        {n} <who> -- <does what> -- <when>
  16.  */
  17.  
  18. #include <X11/Xlib.h>        /* X window stuff */
  19. #include <X11/Xutil.h>        /* X window manager stuff */
  20. #include "hfiles/constant.h"    /* define mode codes */
  21. #include "hfiles/struct.h"    /* declare structure types */
  22. #include "hfiles/extern.h"    /* extern main parameter structures */
  23. #include "hfiles/cgraph.h"    /* color graph structs */
  24. #include "hfiles/define.h"    /* define SQR */
  25.  
  26. extern struct cgraphRec cgraph;
  27.  
  28. /*
  29.  * Subroutine:    vary_colors
  30.  * Purpose:    Modify colors as per mode and the mouse position
  31.  */
  32. void vary_colors ( event, mode, track, x, y, width, height )
  33.      XEvent *event;    /* i: details of event to check button states */
  34.      int mode;        /* i: code for type of varying */
  35.      int track;        /* i: update graphbox displays */
  36.      int x, y;        /* i: mouse coords (could be adjusted) */
  37.      int width, height;    /* i: dimensions bby which to judge control */
  38. {
  39.   double threshold, saturation;
  40.   double contrast, bias;
  41.   double gamma;
  42.   int button1, button2, button3;
  43.   void make_cellmap_from_table(), make_cellstore_from_cellmaps();
  44.   void vary_contrast_and_bias(), draw_cgraph(), label_gamma();
  45.  
  46.   if( event->xbutton.state & ControlMask ) {
  47.     button1 = (event->xbutton.state & Button1Mask);
  48.     button2 = (event->xbutton.state & Button2Mask);
  49.     button3 = (event->xbutton.state & Button3Mask);
  50.     if( event->type == ButtonPress ) {
  51.       button1 |= (event->xbutton.button == Button1);
  52.       button2 |= (event->xbutton.button == Button2);
  53.       button3 |= (event->xbutton.button == Button3);
  54.     }
  55.   } else {
  56.     button1 = 1;
  57.     button2 = 1;
  58.     button3 = 1;
  59.   }
  60.   /* gamma is horizontal */
  61.   if( mode == VOP_gamma ) {
  62.     /* ranges from 0.0 to 4.0, with 1.0 in the middle */
  63.     gamma = SQR((double)(2 * x) / (double)width);
  64.     if( button1 ) {
  65.       color.ctable.red.do_gamma = 1;
  66.       color.ctable.red.gamma = gamma;
  67.       make_cellmap_from_table(&color.ctable.red);
  68.       cgraph.red.unset = 1;
  69.     }
  70.     if( button2 ) {
  71.       color.ctable.green.do_gamma = 1;
  72.       color.ctable.green.gamma = gamma;
  73.       make_cellmap_from_table(&color.ctable.green);
  74.       cgraph.green.unset = 1;
  75.     }
  76.     if( button3 ) {
  77.       color.ctable.blue.do_gamma = 1;
  78.       color.ctable.blue.gamma = gamma;
  79.       make_cellmap_from_table(&color.ctable.blue);
  80.       cgraph.blue.unset = 1;
  81.     }
  82.     if( graphbox.active )
  83.       label_gamma(button1, button2, button3 );
  84.   } else {
  85.     /* make y increase from the bottom */
  86.     y = height - y;
  87.     if( mode == VOP_ThreshSat ) {
  88.       /* threshold is parallel to the color bar, saturation is perpendicular */
  89.       /* threshold varies from -1 to 1, saturation varies from 0 to 2 */
  90.       threshold = ((double)(x * 2) / (double)width) - 1.0;
  91.       saturation = (double)(y * 2) / (double)height;
  92.       contrast = saturation - threshold;
  93.       bias = (threshold + saturation) / 2;
  94.     } else if( mode == VOP_ContBias ) {
  95.       /* make x parallel to color bar */
  96.       /* bias is parallel to the color bar, contrast is perpendicular */
  97.       /* contrast varies from 0 to 2 */
  98.       contrast = (double)(2 * y) / (double)height;
  99.       /* bias ranges from (0.0 - contrast/2) to (1.0 + contrast/2) */
  100.       bias = (double)x / (double)width;
  101.       /* adjust bias to control full range for any contrast */
  102.       bias += ((bias - 0.5) * contrast);
  103.     } else
  104.       return;
  105.     if( button1 ) {
  106.       vary_contrast_and_bias(&color.ctable.red, contrast, bias);
  107.       make_cellmap_from_table(&color.ctable.red);
  108.       cgraph.red.unset = 1;
  109.     }
  110.     if( button2 ) {
  111.       vary_contrast_and_bias(&color.ctable.green, contrast, bias);
  112.       make_cellmap_from_table(&color.ctable.green);
  113.       cgraph.green.unset = 1;
  114.     }
  115.     if( button3 ) {
  116.       vary_contrast_and_bias(&color.ctable.blue, contrast, bias);
  117.       make_cellmap_from_table(&color.ctable.blue);
  118.       cgraph.blue.unset = 1;
  119.     }
  120.   }
  121.   /* update the server colormap */
  122.   make_cellstore_from_cellmaps(&color);
  123.   XStoreColors(color.display, color.colormap, color.cellstore, color.ncolors);
  124.   if( track && graphbox.active )
  125.     /* update the color graph */
  126.     draw_cgraph(0, 0);
  127. }
  128.  
  129. /*
  130.  * Subroutine:    vary_contrast_and_bias
  131.  * Purpose:    change color table cell_levels as per new contrast and bias
  132.  */
  133. void vary_contrast_and_bias ( table, contrast, bias )
  134.      struct subtableRec *table;
  135.      double contrast;        /* i: normal = 1.0 */
  136.      double bias;        /* i: normal = 0.5 */
  137. {
  138.   double *base_level, *cell_level;
  139.   int vertex_cnt;
  140.   static void invert_table();
  141.  
  142.   base_level = table->base_level;
  143.   cell_level = table->cell_level;
  144.   vertex_cnt = table->vertex_cnt;
  145.   if( contrast < 0.0 ) {
  146.     int i, j;
  147.     if( table->invert_order == 0 )
  148.       invert_table(table);
  149.     for( i=0, j=vertex_cnt - 1; i<vertex_cnt; i++, j-- )
  150.       cell_level[i] = (base_level[j] * contrast) + bias;
  151.   } else {
  152.     int i;
  153.     if( table->invert_order )
  154.       invert_table(table);
  155.     for( i=0; i<vertex_cnt; i++ )
  156.       cell_level[i] = (base_level[i] * contrast) + bias;
  157.   }
  158.   table->bias = bias;
  159.   table->contrast = contrast;
  160. }
  161.  
  162. static void invert_table ( table )
  163.      struct subtableRec *table;
  164. {
  165.   int i, j;
  166.   double *intensity;
  167.   intensity = table->intensity;
  168.   for( i = 0, j = table->vertex_cnt - 1; i < j; i++, j-- ) {
  169.     double temp;
  170.     temp = intensity[i];
  171.     intensity[i] = intensity[j];
  172.     intensity[j] = temp;
  173.   }
  174.   table->invert_order ^= 1;
  175. }
  176.