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

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    grphbtmp.c (Color Graph Bitmap)
  6.  * Purpose:    Create the halftone colorbar
  7.  * Subroutine:    make_halftone_colorbar()    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         7 July 1989
  15.  *        {n} <who> -- <does what> -- <when>
  16.  */
  17.  
  18. #include <stdio.h>        /* stderr, NULL, etc. */
  19. #include <X11/Xlib.h>        /* X window stuff */
  20. #include <X11/Xutil.h>        /* X window manager stuff */
  21. #include "hfiles/color.h"
  22. #include "hfiles/constant.h"    /* define codes */
  23.  
  24. extern struct colorRec color;
  25.  
  26. /*
  27.  * Subroutine:    make_halftone_panimage
  28.  * Purpose:    Make halftone bitmap for pan window (panbox)
  29.  */
  30. void make_halftone_colorbar ( bytedata, bitdata,
  31.                   width, height, bytes_per_line )
  32.      unsigned char *bytedata;
  33.      unsigned char *bitdata;
  34.      int width, height;
  35.      int bytes_per_line;
  36. {
  37.   static void byte_dither_sample(), byte_diffuse_sample();
  38.  
  39.   bzero((char *)bitdata, bytes_per_line * height);
  40.   if( color.halftone.mode == BOP_Dither ) {
  41.     byte_dither_sample(bytedata, width, 1, bitdata, bytes_per_line, 0, 0,
  42.                width, height, color.pixvalmap, color.halftone.matrix);
  43.   } else if( color.halftone.mode == BOP_Diffuse ) {
  44.     byte_diffuse_sample(bytedata, width, 1, bitdata, bytes_per_line, 0, 0,
  45.             width, height, color.pixvalmap,
  46.             color.halftone.errbuf);
  47.   }
  48. }
  49.  
  50. /*
  51.  * Subroutine:    byte_dither_sample
  52.  * Purpose:    Perform subsampling and dithering to produce a bitmap image
  53.  *        from 16 bit signed data through a scaling lookup table.
  54.  *        Used when bitmap is same size or smaller than data image.
  55.  * Method:    Sample every zoom'th data element in each direction
  56.  * Note:    This is a copy of the disp dither code but for byte data
  57.  */
  58. static void byte_dither_sample ( byte_data, data_width, zoom,
  59.                  bitmap, bytes_per_line,
  60.                  x, y, width, height, lookup, dither_matrix )
  61.      unsigned char *byte_data;
  62.      int data_width;
  63.      int zoom;
  64.      unsigned char *bitmap;
  65.      int bytes_per_line;
  66.      int x, y, width, height;
  67.      register unsigned long *lookup;
  68.      short *dither_matrix;
  69. {
  70.   register unsigned char *data;        /* ptr to current data input */
  71.   register short *matrix;        /* ptr to current dither value */
  72.   register unsigned char *bitmap_byte;    /* ptr to current output byte */
  73.   register int bitmap_bit;    /* current bit in current output byte */
  74.   unsigned char *data_row;
  75.   short *matrix_row;
  76.   short *matrix_row_end;
  77.   short *matrix_end;
  78.   unsigned char *data_row_end;
  79.   unsigned char *bitmap_row;
  80.   short x_step;
  81.   short y_step;
  82.   short bitmap_first_bit;
  83.   short i;
  84.  
  85.   /* point register pointer to data buffer */
  86.   data_row = byte_data;
  87.   bitmap_row = bitmap + (y * bytes_per_line) + (x / 8);
  88.   bitmap_first_bit = x & 7;    /* same as %8 */
  89.   matrix_row = dither_matrix;
  90.   matrix_row_end = matrix_row + 16;
  91.   matrix_end = matrix_row + 256;
  92.   x_step = zoom;
  93.   y_step = data_width * x_step;
  94.   /* process one row at a time */
  95.   if( color.halftone.inverse ) {
  96.     for( i = 0; i < height; i++ ) {
  97.       matrix = matrix_row;
  98.       data = data_row;
  99.       data_row_end = data + width;
  100.       bitmap_byte = bitmap_row;
  101.       bitmap_bit = bitmap_first_bit;
  102.       /* process through the row */
  103.       while( data < data_row_end ) {
  104.     if( lookup[*data] <= *matrix )
  105.       *bitmap_byte |= 1 << bitmap_bit;
  106.     data += x_step;
  107.     ++matrix;
  108.     /* check for next byte */
  109.     if( ++bitmap_bit == 8 ) {
  110.       bitmap_bit = 0;
  111.       ++bitmap_byte;
  112.       if( matrix >= matrix_row_end )
  113.         matrix = matrix_row;
  114.     }
  115.       }
  116.       bitmap_row += bytes_per_line;
  117.       data_row += y_step;
  118.       matrix_row = matrix_row_end;
  119.       matrix_row_end += 16;
  120.       if( matrix_row >= matrix_end ) {
  121.     matrix_row = matrix;
  122.     matrix_row_end = matrix_row + 16;
  123.       }
  124.     }
  125.   } else {
  126.     for( i = 0; i < height; i++ ) {
  127.       matrix = matrix_row;
  128.       data = data_row;
  129.       data_row_end = data + width;
  130.       bitmap_byte = bitmap_row;
  131.       bitmap_bit = bitmap_first_bit;
  132.       /* process through the row */
  133.       while( data < data_row_end ) {
  134.     if( lookup[*data] > *matrix )
  135.       *bitmap_byte |= 1 << bitmap_bit;
  136.     data += x_step;
  137.     ++matrix;
  138.     /* check for next byte */
  139.     if( ++bitmap_bit == 8 ) {
  140.       bitmap_bit = 0;
  141.       ++bitmap_byte;
  142.       if( matrix >= matrix_row_end )
  143.         matrix = matrix_row;
  144.     }
  145.       }
  146.       bitmap_row += bytes_per_line;
  147.       data_row += y_step;
  148.       matrix_row = matrix_row_end;
  149.       matrix_row_end += 16;
  150.       if( matrix_row >= matrix_end ) {
  151.     matrix_row = matrix;
  152.     matrix_row_end = matrix_row + 16;
  153.       }
  154.     }
  155.   }
  156. }
  157.  
  158. /*
  159.  * Subroutine:    byte_diffuse_sample
  160.  * Purpose:    Perform subsampling and error diffusion to produce a bitmap
  161.  *        image from 16 bit signed data through a scaling lookup table.
  162.  *        Used when bitmap is same size or smaller than data image.
  163.  * Method:    Sample every zoom'th data element in each direction
  164.  * Note:    This is a copy of the DispDiffuse code but for byte data
  165.  */
  166. static void byte_diffuse_sample ( byte_data, data_width, zoom,
  167.                   bitmap, bytes_per_line,
  168.                   x, y, width, height, lookup, errbuf )
  169.      unsigned char *byte_data;
  170.      int data_width;
  171.      int zoom;
  172.      unsigned char *bitmap;
  173.      int bytes_per_line;
  174.      int x, y, width, height;
  175.      register unsigned long *lookup;
  176.      short *errbuf;
  177. {
  178.   register int val;
  179.   register short *error;
  180.   register unsigned char *data;
  181.   register unsigned char *bitmap_byte;
  182.   register int maxval;
  183.   unsigned char *bitmap_row;
  184.   unsigned char *data_row;
  185.   unsigned char *data_row_end;
  186.   short error0;
  187.   short bitmap_bit;
  188.   short bitmap_first_bit;
  189.   short x_step, y_step;
  190.   short i;
  191.  
  192.   data_row = byte_data;
  193.   bitmap_row = bitmap + (y * bytes_per_line) + (x / 8);
  194.   bitmap_first_bit = x & 7;    /* same as %8 */
  195.   /* halftone standard of 256 levels */
  196.   maxval = 256;
  197.   error0 = 0;
  198.   /* subsample line skipping */
  199.   x_step = zoom;
  200.   y_step = data_width * zoom;
  201.   if( color.halftone.inverse ) {
  202.     /* go through each row of the bitmap */
  203.     for( i = 0; i < height; i++ ) {
  204.       error = errbuf;
  205.       data = data_row;
  206.       data_row_end = data + width;
  207.       bitmap_byte = bitmap_row;
  208.       bitmap_bit = bitmap_first_bit;
  209.       while( data < data_row_end ) {
  210.     /* val is data value plus average of error remnants */
  211.     val = lookup[*data] + ((*error + error0 + error[1] + error[2]) >> 2);
  212.     /* save earlier error */
  213.     error0 = *(++error);
  214.     /* replace old error with this error */
  215.     if( val < maxval ) {
  216.       *bitmap_byte |= 1 << bitmap_bit;
  217.       *error = val;
  218.     } else
  219.       *error = val - maxval;
  220.     data += x_step;
  221.     /* update word and bit pointers */
  222.     if( ++bitmap_bit > 7 ) {
  223.       bitmap_byte++;
  224.       bitmap_bit = 0;
  225.     }
  226.       }
  227.       data_row += y_step;
  228.       /* advance to next line in bitmap_byte */
  229.       bitmap_row += bytes_per_line;
  230.     }
  231.   } else {
  232.     /* go through each row of the bitmap */
  233.     for( i = 0; i < height; i++ ) {
  234.       error = errbuf;
  235.       data = data_row;
  236.       data_row_end = data + width;
  237.       bitmap_byte = bitmap_row;
  238.       bitmap_bit = bitmap_first_bit;
  239.       while( data < data_row_end ) {
  240.     /* val is data value plus average of error remnants */
  241.     val = lookup[*data] + ((*error + error0 + error[1] + error[2]) >> 2);
  242.     /* save earlier error */
  243.     error0 = *(++error);
  244.     /* replace old error with this error */
  245.     if( val >= maxval ) {
  246.       *bitmap_byte |= 1 << bitmap_bit;
  247.       *error = val - maxval;
  248.     } else
  249.       *error = val;
  250.     data += x_step;
  251.     /* update word and bit pointers */
  252.     if( ++bitmap_bit > 7 ) {
  253.       bitmap_byte++;
  254.       bitmap_bit = 0;
  255.     }
  256.       }
  257.       data_row += y_step;
  258.       /* advance to next line in bitmap_byte */
  259.       bitmap_row += bytes_per_line;
  260.     }
  261.   }
  262. }
  263.