home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / software / unix / saoimage / sao1_07.tar / dispdthr.c < prev    next >
C/C++ Source or Header  |  1991-06-21  |  12KB  |  317 lines

  1. #ifndef lint
  2. static char SccsId[] = "@(#)dispdither.c    1.2  8/12/89";
  3. #endif
  4.  
  5. /* Module:    dispdthr.c (Display Dither)
  6.  * Purpose:    Map 16 bit data to a single plane bitmap using dithering
  7.  * Subroutine:    dither_sample()            returns: void
  8.  * Subroutine:    dither_replicate()        returns: void
  9.  * Xlib calls:    none
  10.  * Method:    Image dithering based on 16x16 square of values from 0 to 255.
  11.  * Note:    Matrix is short to allow compare with 256 (not a uchar val)
  12.  * Note:    Lookup is used to rescale input data to 0-255 range
  13.  * Note:    Most loops check by pointer val, saving indexing overhead
  14.  * Note:    Seperate code used for forward and reverse video rather than
  15.  *        switching foreground and background val, because non-image
  16.  *        area of display must not change
  17.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  18.  *        You may do anything you like with this file except remove
  19.  *        this copyright.  The Smithsonian Astrophysical Observatory
  20.  *        makes no representations about the suitability of this
  21.  *        software for any purpose.  It is provided "as is" without
  22.  *        express or implied warranty.
  23.  * Modified:    {0} Michael VanHilst    initial version         7 July 1989
  24.  *        {1} MVH added ULedge partial replicate         3  Feb 1990
  25.  *        {2} MVH replaced zoom rep code            21 June 1991
  26.  *        {n} <who> -- <does what> -- <when>
  27.  */
  28.  
  29. static unsigned char bit_mask[8] = {
  30.   0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
  31.  
  32. /*
  33.  * Subroutine:    zoom_dither_sample
  34.  * Purpose:    Perform subsampling and dithering to produce a bitmap image
  35.  *        from 16 bit signed data through a scaling lookup table.
  36.  *        Used when bitmap is same size or smaller than data image.
  37.  * Method:    Sample every zoom'th data element in each direction
  38.  * Note:    x, y, width, and height define a subsection within output.
  39.  *        Bits outside of subsection are unchanged.
  40.  */
  41. void dither_sample ( short_data, data_width, zoom, bitmap, bytes_per_line,
  42.              x, y, width, height, lookup, dither_matrix, inverse )
  43.      short *short_data;            /* i: image of signed short data */
  44.      int data_width;            /* i: row width of short image */
  45.      int zoom;                /* i: zoom factor for subsampling */
  46.      unsigned char *bitmap;        /* o: output bitmap buffer */
  47.      int bytes_per_line;        /* i: bytes per line of bitmap */
  48.      int x, y, width, height;        /* i: dimensions to fill */
  49.      register unsigned char *lookup;    /* i: short to uchar lookup table */
  50.      short *dither_matrix;        /* i: 16x16 matrix for dithering */
  51.      int inverse;            /* i: make 0 on 1, else 1 on 0 */
  52. {
  53.   register short *data;            /* l: ptr to current data input */
  54.   register short *matrix;        /* l: ptr to current dither value */
  55.   register unsigned char *bitmap_byte;    /* l: ptr to current output byte */
  56.   register unsigned char *bitmap_bit;    /* l: current bit in output byte */
  57.   short *data_row;            /* l: beginning of current input row */
  58.   short *matrix_row;            /* l: 1st entry in matrix row */
  59.   short *matrix_row_end;        /* l: last short in matrix row */
  60.   short *matrix_end;            /* l: last short in matrix */
  61.   short *data_row_end;            /* l: last short in input data row */
  62.   unsigned char *bitmap_row;        /* l: first byte of output row */
  63.   unsigned char *bitmap_first_bit;    /* l: first byte to actually write */
  64.   unsigned char *bitmap_last_bit;    /* l: last byte to be affected */
  65.   short x_step;                /* l: sampling step along row */
  66.   short y_step;                /* l: pointer offset to advance rows */
  67.   short i;
  68.  
  69.   /* point register pointer to data buffer */
  70.   data_row = short_data;
  71.   bitmap_row = bitmap + (y * bytes_per_line) + (x / 8);
  72.   bitmap_first_bit = bit_mask + (x & 7);    /* same as %8 */
  73.   bitmap_last_bit = &(bit_mask[7]);
  74.   /* initialize matrix pointers for use and loop tests */
  75.   matrix_row = dither_matrix;
  76.   matrix_row_end = matrix_row + 16;
  77.   matrix_end = matrix_row + 256;
  78.   /* initial sampling step size for both directions */
  79.   x_step = zoom;
  80.   y_step = data_width * x_step;
  81.   /* width becomes count of data traversed each row */
  82.   width *= zoom;
  83.   /* if high vals are to be white */
  84.   if( inverse ) {
  85.     /* process one row at a time */
  86.     for( i = 0; i < height; i++ ) {
  87.       matrix = matrix_row;
  88.       data = data_row;
  89.       data_row_end = data + width;
  90.       bitmap_byte = bitmap_row;
  91.       bitmap_bit = bitmap_first_bit;
  92.       /* process through the row */
  93.       while( data < data_row_end ) {
  94.     /* set bit by comparing val to matrix entry */
  95.     if( lookup[*data] <= *matrix )
  96.       *bitmap_byte |= *bitmap_bit;
  97.     data += x_step;
  98.     ++matrix;
  99.     /* check for next byte */
  100.     if( ++bitmap_bit > bitmap_last_bit ) {
  101.       bitmap_bit = bit_mask;
  102.       ++bitmap_byte;
  103.       /* matrix row wrap-around happens every other byte edge */
  104.       if( matrix >= matrix_row_end )
  105.         matrix = matrix_row;
  106.     }
  107.       }
  108.       /* advance to next row of everything */
  109.       bitmap_row += bytes_per_line;
  110.       data_row += y_step;
  111.       matrix_row = matrix_row_end;
  112.       matrix_row_end += 16;
  113.       /* check for matrix column wrap-around */
  114.       if( matrix_row >= matrix_end ) {
  115.     matrix_row = dither_matrix;
  116.     matrix_row_end = matrix_row + 16;
  117.       }
  118.     }
  119.     /* else foreground is to be black */
  120.   } else {
  121.     /* process one row at a time */
  122.     for( i = 0; i < height; i++ ) {
  123.       matrix = matrix_row;
  124.       data = data_row;
  125.       data_row_end = data + width;
  126.       bitmap_byte = bitmap_row;
  127.       bitmap_bit = bitmap_first_bit;
  128.       /* process through the row */
  129.       while( data < data_row_end ) {
  130.     /* set bit by comparing val to matrix entry */
  131.     if( lookup[*data] > *matrix )
  132.       *bitmap_byte |= *bitmap_bit;
  133.     data += x_step;
  134.     ++matrix;
  135.     /* check for next byte */
  136.     if( ++bitmap_bit > bitmap_last_bit ) {
  137.       bitmap_bit = bit_mask;
  138.       ++bitmap_byte;
  139.       /* matrix row wrap-around happens every other byte edge */
  140.       if( matrix >= matrix_row_end )
  141.         matrix = matrix_row;
  142.     }
  143.       }
  144.       /* advance to next row of everything */
  145.       bitmap_row += bytes_per_line;
  146.       data_row += y_step;
  147.       matrix_row = matrix_row_end;
  148.       matrix_row_end += 16;
  149.       /* check for matrix column wrap-around */
  150.       if( matrix_row >= matrix_end ) {
  151.     matrix_row = dither_matrix;
  152.     matrix_row_end = matrix_row + 16;
  153.       }
  154.     }
  155.   }
  156. }
  157.  
  158. /*
  159.  * Subroutine:    zoom_dither_replicate
  160.  * Purpose:    Perform replication and dithering to produce a bitmap image
  161.  *        from 16 bit signed data through a scaling lookup table.
  162.  *        Used when bitmap is larger than data image.
  163.  * Method:    Repeat data element zoom times in each direction
  164.  */
  165. void dither_replicate ( short_data, data_width, zoom, bitmap, bytes_per_line,
  166.                 first_x_rep, first_y_rep, x, y, width, height,
  167.                 lookup, dither_matrix, inverse )
  168.      short *short_data;            /* i: image of signed short data */
  169.      int data_width;            /* i: row width of short image */
  170.      int zoom;                /* i: zoom factor for replicating */
  171.      unsigned char *bitmap;        /* o: output bitmap buffer */
  172.      int bytes_per_line;        /* i: bytes per line of bitmap */
  173.      int first_x_rep;            /* i: number of reps in 1st column */
  174.      int first_y_rep;            /* i: num of reps in 1st row */
  175.      int x, y, width, height;        /* i: area of output to fill */
  176.      register unsigned char *lookup;    /* i: short to uchar lookup table */
  177.      short *dither_matrix;        /* i: 16x16 matrix for dithering */
  178.      int inverse;            /* i: make 0 on 1, else 1 on 0 */
  179. {
  180.   register short *data;            /* l: ptr to current data input */
  181.   register short *matrix;        /* l: ptr to current dither value */
  182.   register unsigned char *bitmap_byte;    /* l: ptr to current output byte */
  183.   register int bitmap_bit;        /* l: current bit in output byte */
  184.   short *data_row;            /* l: beginning of current input row */
  185.   short *matrix_row;            /* l: 1st entry in matrix row */
  186.   short *matrix_row_end;        /* l: last short in matrix row */
  187.   short *matrix_end;            /* l: last short in matrix */
  188.   short *data_row_end;            /* l: last short in input data row */
  189.   unsigned char *bitmap_row;        /* l: first byte of output row */
  190.   unsigned char *bitmap_row_end;    /* l: first byte in bitmap */
  191.   int bitmap_first_bit;            /* l: 1st bit of first byte affected */
  192.   int bitmap_last_bit;            /* l: last bit of last byte affected */
  193.   int bitmap_bytes_per_row;        /* l: length of output line in bytes */
  194.   int x_step;                /* l: repetition step along row */
  195.   int y_step;                /* l: pointer offset to repeat rows */
  196.   int i;
  197.  
  198.   /* point register pointer to data buffer */
  199.   data_row = short_data;
  200.   bitmap_row = bitmap + (y * bytes_per_line) + (x / 8);
  201.   /* which bit does this x fall on? ((x & 7) is same as (x % 8)) */
  202.   bitmap_first_bit = x & 7;
  203.   /* which bit will last x fall on */
  204. /*
  205.   bitmap_last_bit = (width + bitmap_first_bit) & 7;
  206.   bitmap_bytes_per_row = (width + bitmap_first_bit + 7) / 8;
  207. */
  208.   bitmap_last_bit = (width + bitmap_first_bit - 1) & 7;
  209.   bitmap_bytes_per_row = (x + width + 7) / 8;
  210.   if( bitmap_bytes_per_row >= bytes_per_line )
  211.     bitmap_bytes_per_row = bytes_per_line - ((x / 8) + 1);
  212.   else
  213.     bitmap_bytes_per_row -= ((x / 8) + 1);
  214.  
  215.   /* get matrix pointer and loop references ready */
  216.   matrix_row = dither_matrix;
  217.   matrix_row_end = matrix_row + 16;
  218.   matrix_end = matrix_row + 256;
  219.   /* convert first rep to first step toward zoom reps */
  220.   y_step = 1 + zoom - first_y_rep;
  221.   first_x_rep = 1 + zoom - first_x_rep;
  222.   if( inverse ) {
  223.     /* do one row at a time */
  224.     for( i = 0; i < height; i++ ) {
  225.       /* beginning of row initialization */
  226.       data = data_row;
  227.       bitmap_byte = bitmap_row;
  228.       bitmap_row_end = bitmap_byte + bitmap_bytes_per_row;
  229.       bitmap_bit = bitmap_first_bit;
  230.       /* align matrix with output bytes */
  231.       matrix = matrix_row + bitmap_bit;
  232.       x_step = first_x_rep;
  233.       /* go through the row */
  234.       while( (bitmap_byte < bitmap_row_end) ||
  235.          ((bitmap_byte == bitmap_row_end) &&
  236.           (bitmap_bit <= bitmap_last_bit)) ) {
  237.     /* set bit by comparing val to matrix entry */
  238.     if( lookup[*data] <= *matrix )
  239.       *bitmap_byte |= 1 << bitmap_bit;
  240.     ++matrix;
  241.     /* check for next bitmap byte and end of matrix row */
  242.     if( ++bitmap_bit == 8 ) {
  243.       bitmap_bit = 0;
  244.       ++bitmap_byte;
  245.       /* wrap matrix row around on output byte edges */
  246.       if( matrix >= matrix_row_end )
  247.         matrix = matrix_row;
  248.     }
  249.     /* move to next val when done with replication */
  250.     if( ++x_step > zoom ) {
  251.       ++data;
  252.       x_step = 1;
  253.     }
  254.       }
  255.       bitmap_row += bytes_per_line;
  256.       matrix_row = matrix_row_end;
  257.       matrix_row_end += 16;
  258.       /* check for matrix column wrap-around */
  259.       if( matrix_row >= matrix_end ) {
  260.     matrix_row = dither_matrix;
  261.     matrix_row_end = matrix_row + 16;
  262.       }
  263.       /* advance data row only after zoom repetitions */
  264.       if( ++y_step > zoom ) {
  265.     data_row += data_width;
  266.     y_step = 1;
  267.       }
  268.     }
  269.   } else {
  270.     /* do one row at a time */
  271.     for( i = 0; i < height; i++ ) {
  272.       data = data_row;
  273.       bitmap_byte = bitmap_row;
  274.       bitmap_row_end = bitmap_byte + bitmap_bytes_per_row;
  275.       bitmap_bit = bitmap_first_bit;
  276.       /* align matrix with output bytes */
  277.       matrix = matrix_row + bitmap_bit;
  278.       x_step = first_x_rep;
  279.       /* go through the row */
  280.       while( (bitmap_byte < bitmap_row_end) ||
  281.          ((bitmap_byte == bitmap_row_end) &&
  282.           (bitmap_bit <= bitmap_last_bit)) ) {
  283.     /* set bit by comparing val to matrix entry */
  284.     if( lookup[*data] > *matrix )
  285.       *bitmap_byte |= 1 << bitmap_bit;
  286.     ++matrix;
  287.     /* check for next bitmap byte and end of matrix row */
  288.     if( ++bitmap_bit == 8 ) {
  289.       bitmap_bit = 0;
  290.       ++bitmap_byte;
  291.       /* wrap matrix row around on output byte edges */
  292.       if( matrix >= matrix_row_end )
  293.         matrix = matrix_row;
  294.     }
  295.     /* move to next val when done with replication */
  296.     if( ++x_step > zoom ) {
  297.       ++data;
  298.       x_step = 1;
  299.     }
  300.       }
  301.       bitmap_row += bytes_per_line;
  302.       matrix_row = matrix_row_end;
  303.       matrix_row_end += 16;
  304.       /* check for matrix column wrap-around */
  305.       if( matrix_row >= matrix_end ) {
  306.     matrix_row = dither_matrix;
  307.     matrix_row_end = matrix_row + 16;
  308.       }
  309.       /* advance data row only after zoom repetitions */
  310.       if( ++y_step > zoom ) {
  311.     data_row += data_width;
  312.     y_step = 1;
  313.       }
  314.     }
  315.   }
  316. }
  317.