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

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    clrmap.c (Color Map)
  6.  * Purpose:    Set up the cell storemap XColor array
  7.  * Subroutine:    make_cellstore_from_tables()    returns: void
  8.  * Subroutine:    make_cellstore_from_cellmaps()    returns: void
  9.  * Subroutine:    make_cellmap_from_table()    returns: void
  10.  * Xlib calls:    none
  11.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  12.  *        You may do anything you like with this file except remove
  13.  *        this copyright.  The Smithsonian Astrophysical Observatory
  14.  *        makes no representations about the suitability of this
  15.  *        software for any purpose.  It is provided "as is" without
  16.  *        express or implied warranty.
  17.  * Modified:    {0} Michael VanHilst    initial version           16 May 1989
  18.  *        {n} <who> -- <does what> -- <when>
  19.  */
  20.  
  21. #include <stdio.h>            /* stderr, NULL, etc. */
  22. #include <math.h>            /* define pow */
  23. #include <X11/Xlib.h>            /* X window stuff */
  24. #include <X11/Xutil.h>            /* X window manager stuff */
  25. #include "hfiles/color.h"        /* color structs */
  26. #include "hfiles/define.h"        /* INTERP, INCSZ, and more */
  27.  
  28. /*
  29.  * Subroutine:    make_cellstore_from_table
  30.  * Purpose:    Fill the color map according to the color vertex tables
  31.  */
  32. void make_cellstore_from_tables ( color )
  33.      struct colorRec *color;
  34. {
  35.   void make_cellmap_from_table(), make_cellstore_from_cellmaps();
  36.  
  37.   make_cellmap_from_table(&color->ctable.red);
  38.   make_cellmap_from_table(&color->ctable.green);
  39.   make_cellmap_from_table(&color->ctable.blue);
  40.   make_cellstore_from_cellmaps(color);
  41. }
  42.  
  43. /*
  44.  * Subroutine:    make_cellstore_from_cellmaps
  45.  * Purpose:    Fill XColor storemap from individual cellmaps
  46.  */
  47. void make_cellstore_from_cellmaps ( color )
  48.      struct colorRec *color;
  49. {
  50.   double gamma;
  51.   double *cellmap;
  52.   double *gammamap;
  53.   register int i;
  54.   int ncolors;
  55.   XColor *cellstore;
  56.  
  57.   cellstore = color->cellstore;
  58.   ncolors = color->ncolors;
  59.  
  60.   cellmap = color->ctable.red.cellmap;
  61.   if( color->ctable.red.do_gamma ) {
  62.     gammamap = color->ctable.red.gammamap;
  63.     gamma = 1.0 / color->ctable.red.gamma;
  64.     for( i=0; i<ncolors; i++ )
  65.       cellstore[i].red = (unsigned short)
  66.     (65535.0 * (gammamap[i] = pow(cellmap[i], gamma)));
  67.   } else {
  68.     for( i=0; i<ncolors; i++ )
  69.       cellstore[i].red = (unsigned short)(cellmap[i] * 65535.0);
  70.   }
  71.   cellmap = color->ctable.green.cellmap;
  72.   if( color->ctable.green.do_gamma ) {
  73.     gammamap = color->ctable.green.gammamap;
  74.     gamma = 1.0 / color->ctable.green.gamma;
  75.     for( i=0; i<ncolors; i++ )
  76.       cellstore[i].green = (unsigned short)
  77.     (65535.0 * (gammamap[i] = pow(cellmap[i], gamma)));
  78.   } else {
  79.     for( i=0; i<ncolors; i++ )
  80.       cellstore[i].green = (unsigned short)(cellmap[i] * 65535.0);
  81.   }
  82.   cellmap = color->ctable.blue.cellmap;
  83.   if( color->ctable.blue.do_gamma ) {
  84.     gammamap = color->ctable.blue.gammamap;
  85.     gamma = 1.0 / color->ctable.blue.gamma;
  86.     for( i=0; i<ncolors; i++ )
  87.       cellstore[i].blue = (unsigned short)
  88.     (65535.0 * (gammamap[i] = pow(cellmap[i], gamma)));
  89.   } else {
  90.     for( i=0; i<ncolors; i++ )
  91.       cellstore[i].blue = (unsigned short)(cellmap[i] * 65535.0);
  92.   }
  93. }
  94.  
  95. /*
  96.  * Subroutine:    make_cellmap_from_table
  97.  * Purpose:    Fill cellstore values based on table values
  98.  * Method:    Set map values using interpolated ramps between map entries
  99.  */
  100. void make_cellmap_from_table ( table )
  101.      struct subtableRec *table;
  102. {
  103.   double cell_factor;
  104.   double level_last;
  105.   double level_next;
  106.   double start_intensity;    /* l: intensity at start cell */
  107.   double intensity_inc;        /* l: change in intensity between cells */
  108.   double intensity_last;
  109.   double intensity_next;
  110.   double *cellmap;        /* l: intensity by cell array */
  111.   int start_cell, stop_cell;    /* l: cells at ends of ramp function */
  112.   int table_cnt;
  113.   int map_sz;
  114.   int table_i, map_i;
  115.  
  116.   /* initialization phase */
  117.   table_cnt = table->vertex_cnt;
  118.   cellmap = table->cellmap;
  119.   map_sz = table->map_sz;
  120.   cell_factor = (double)(map_sz - 1);
  121.   table_i = 0;
  122.   while( (table->cell_level[table_i] < 0.0) && (++table_i < table_cnt) );
  123.   if( table_i >= table_cnt ) {
  124.     /* entire table is below 0.0: set entire map with last intensity */
  125.     start_intensity = table->intensity[table_cnt - 1];
  126.     for( map_i=0; map_i<map_sz; map_i++ )
  127.       cellmap[map_i] = start_intensity;
  128.     return;
  129.   } else if( table_i > 0 ) {
  130.     /* table extends partially below 0.0 */
  131.     level_last = table->cell_level[table_i - 1];
  132.     intensity_last = table->intensity[table_i - 1];
  133.   } else {
  134.     /* table starts at or above 0.0 */
  135.     level_last = 0.0;
  136.     intensity_last = table->intensity[table_i];
  137.   }
  138.  
  139.   /* middle phase: run through map or table */
  140.   start_cell = 0;
  141.   do {
  142.     level_next = table->cell_level[table_i];
  143.     intensity_next = table->intensity[table_i];
  144.     stop_cell = (int)(level_next * cell_factor);
  145.     if( stop_cell >= map_sz )
  146.       /* stop at end of map if there */
  147.       stop_cell = map_sz - 1;
  148.     if( stop_cell >= start_cell ) {
  149.       /* if levels traverse any map cells, set them */
  150.       start_intensity =
  151.     INTERP(level_last, ((double)start_cell)/cell_factor, level_next,
  152.            intensity_last, intensity_next);
  153.       if( stop_cell == start_cell ) {
  154.     /* if only one cell is traversed, set it */
  155.     cellmap[start_cell] = start_intensity;
  156.       } else {
  157.     intensity_inc = INCSZ(level_last, level_next,
  158.                   intensity_last, intensity_next, cell_factor);
  159.     for( map_i=start_cell; map_i<=stop_cell; map_i++ ) {
  160.       cellmap[map_i] = start_intensity;
  161.       start_intensity += intensity_inc;
  162.     }
  163.     /* check for slight over-step at end */
  164.     if( cellmap[stop_cell] < 0.0 )
  165.       cellmap[stop_cell] = 0.0;
  166.     else if( cellmap[stop_cell] > 1.0 )
  167.       cellmap[stop_cell] = 1.0;
  168.       }
  169.       start_cell = stop_cell + 1;
  170.     }
  171.     level_last = level_next;
  172.     intensity_last = intensity_next;
  173.   } while( (level_last < 1.0) && (++table_i < table_cnt) );
  174.     
  175.   /* completion phase */
  176.   if( start_cell < map_sz ) {
  177.     /* table ended before 1.0 */
  178.     for( map_i=start_cell; map_i<map_sz; map_i++ )
  179.       cellmap[map_i] = intensity_last;
  180.   }
  181. }
  182.