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

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    histscan.c (Histogram Scan)
  6.  * Subroutine:    scan_histogram_for_peaks()    returns: void
  7.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  8.  *        You may do anything you like with this file except remove
  9.  *        this copyright.  The Smithsonian Astrophysical Observatory
  10.  *        makes no representations about the suitability of this
  11.  *        software for any purpose.  It is provided "as is" without
  12.  *        express or implied warranty.
  13.  * Modified:    {0} Michael VanHilst    initial version          30 May 1989
  14.  *        {n} <who> -- <does what> -- <when>
  15.  */
  16.  
  17. #include "hfiles/histeq.h"
  18.  
  19. /*
  20.  * Subroutine:    scan_histogram_for_peaks
  21.  * Purpose:    Scan the image histogram picking out large cell count values
  22.  *        make sub-groups of the histogram between the large count levels
  23.  */
  24. void scan_histogram_for_peaks ( subrange, histogram,
  25.                     pixel_area, map_levels, average )
  26.      SubrangeLink *subrange;    /* i/o: link (initially covers range) */
  27.      int *histogram;        /* i: histogram (for signed index) */
  28.      int *pixel_area;        /* i/o: number of pixels to account for */
  29.      int *map_levels;        /* i/o: number of levels left to map */
  30.      int *average;        /* i/o: average pixels per color map level */
  31. {
  32.   int i;
  33.   int scan_end;            /* l: end of subrange in histogram */
  34.   int scan_start;        /* l: histogram entry after last peak */
  35.   int pixel_count;        /* l: number of pixels at histogram entry */
  36.   int sr_nzentries;        /* l: number of non-zero entries in subrange */
  37.   int sr_pixel_area;        /* l: number of pixels in current subrange */
  38.   int sr_max_peak;        /* l: highest peak within current  subrange */
  39.   static SubrangeLink *get_new_subrange_record();
  40.   static void fill_subrange_record();
  41.  
  42.   /* set initial pixel_count values */
  43.   sr_pixel_area = 0;
  44.   sr_nzentries = 0;
  45.   sr_max_peak = 0;
  46.   scan_start = subrange->low;
  47.   scan_end = subrange->high;
  48.   /* run through values in histogram mapping excessive entries */
  49.   for( i = scan_start; i <= scan_end; i++ ) {
  50.     pixel_count = histogram[i];
  51.     /* if this pixel value alone is enough for one level, mark it */
  52.     if( pixel_count >= *average ) {
  53.       /* take this count out of equalization distribution */
  54.       *pixel_area -= pixel_count;
  55.       *map_levels -= 1;
  56.       /* compute new average, (peaks in prior range will be rechecked later */
  57.       if( *map_levels > 0 )
  58.     *average = (*pixel_area / *map_levels) + 1;
  59.       /* make a subrange between peaks if there was a valley & get new link */
  60.       if( i > scan_start ) {
  61.     fill_subrange_record(subrange, scan_start, i - 1, i - scan_start,
  62.                  sr_nzentries, sr_pixel_area, sr_max_peak);
  63.     subrange = get_new_subrange_record(subrange);
  64.       }
  65.       /* make a subrange of one for this peak */
  66.       fill_subrange_record(subrange, i, i, -1, 1, pixel_count, pixel_count);
  67.       subrange->color_levels = 1;
  68.       /* if entries remain, put them in a subrange */
  69.       if (i < scan_end) {
  70.     subrange = get_new_subrange_record(subrange);
  71.     fill_subrange_record(subrange, i + 1, scan_end, scan_end - i, 0, 0, 0);
  72.       }
  73.       /* reset scan values */
  74.       sr_pixel_area = 0;
  75.       sr_nzentries = 0;
  76.       sr_max_peak = 0;
  77.       scan_start = i + 1;
  78.     } else {
  79.       /* update scan values */
  80.       if( pixel_count > 0 ) {
  81.     sr_pixel_area += pixel_count;
  82.     ++sr_nzentries;
  83.     if( pixel_count > sr_max_peak )
  84.       sr_max_peak = pixel_count;
  85.       }
  86.     }
  87.   }
  88.   /* mark the final group */
  89.   if( scan_start < scan_end ) {
  90.     fill_subrange_record(subrange, scan_start, scan_end,
  91.              (scan_end - scan_start) + 1,
  92.              sr_nzentries, sr_pixel_area, sr_max_peak);
  93.   }
  94. }
  95.  
  96. /*
  97.  * Subroutine:    get_new_subrange_record
  98.  * Purpose:    Create a new link in histogram link list, after one given
  99.  * Returns:    Pointer to new subrange link
  100.  */
  101. static SubrangeLink *get_new_subrange_record ( old_link )
  102.      SubrangeLink *old_link;
  103. {
  104.   SubrangeLink *new_link;
  105.   char *calloc_errchk();
  106.  
  107.   /* create new record for histogram link list */
  108.   new_link = (SubrangeLink *)
  109.     calloc_errchk(1, sizeof(SubrangeLink), "histeq link");
  110.   new_link->next = old_link->next;
  111.   old_link->next = new_link;
  112.   new_link->color_levels = 0;
  113.   new_link->excess_pixels = 0;
  114.   return( new_link );
  115. }
  116.  
  117. /*
  118.  * Subroutine:    fill_subrange_record
  119.  * Purpose:    Set parameters in subrange link list record
  120.  */
  121. static void fill_subrange_record ( link, low, high, range, nz_entries,
  122.                    pixel_area, max_entry )
  123.      SubrangeLink *link;
  124.      int low, high;        /* i: first and last index in histogram */
  125.      int range;            /* i: span of histogram entries */
  126.      int nz_entries;        /* i: non-zero entries in range */
  127.      int pixel_area;        /* i: sum of histogram entry values (pixels) */
  128.      int max_entry;        /* i: highest histogram entry value */
  129. {
  130.   link->low = low;
  131.   link->high = high;
  132.   link->range = range;
  133.   link->nz_entries = nz_entries;
  134.   link->pixel_area = pixel_area;
  135.   link->max_entry = max_entry;
  136. }
  137.