File: histzero.c

package info (click to toggle)
saoimage 1.29.3-1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 3,952 kB
  • ctags: 4,265
  • sloc: ansic: 50,317; makefile: 243; sh: 35
file content (115 lines) | stat: -rw-r--r-- 3,316 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#ifndef lint
static char SccsId[] = "%W%  %G%";
#endif

/* Module:	histzero.c (Histogram Zero)
 * Subroutine:	resolve_zeroes()			returns: void
 * Copyright:	1989 Smithsonian Astrophysical Observatory
 *		You may do anything you like with this file except remove
 *		this copyright.  The Smithsonian Astrophysical Observatory
 *		makes no representations about the suitability of this
 *		software for any purpose.  It is provided "as is" without
 *		express or implied warranty.
 * Modified:	{0} Michael VanHilst	initial version		  30 May 1989
 *		{n} <who> -- <does what> -- <when>
 */

#include <stdio.h>
#include "hfiles/histeq.h"		/* define SubrangeLink */

/*
 * Subroutine:	resolve_zeroes
 * Purpose:	Combine groups with zero alloted levels with adjoining groups
 * Note:	Adjoining groups are large count single level groups
 * Called by:	histrogram_equalize() above
 */
void resolve_zeroes ( PriorLink, zeroes )
     SubrangeLink *PriorLink;
     int zeroes;
{
  SubrangeLink *ThisLink, *NextLink;
  int a_count, b_count, z1count, z2count;
  static void merge_links();

  /* if very first entry is a zero allocated link */
  if( PriorLink->color_levels == 0 ) {
    /* merge this and next */
    merge_links(PriorLink);
    zeroes--;
  }
  /* scan for the zero allocated links */
  while( zeroes > 0 ) {
    ThisLink = PriorLink->next;
#ifdef DEBUG
    /* if reached the end of the list, we had an error */
    if( ThisLink == 0 ) {
      (void)fprintf(stderr,"Zero error\n");
      return;
    }
#endif
    /* if we are about to hit a zero */
    if( ThisLink->color_levels == 0 ) {
      /* if it is the last zero merge with prior */
      NextLink = ThisLink->next;
      if( NextLink == 0 ) {
	merge_links(PriorLink);
	return;
      }
      a_count = PriorLink->pixel_area;
      b_count = NextLink->pixel_area;
      /* if the preceding link is smaller than the trailing link */
      if( a_count > b_count ) {
	merge_links(PriorLink);
	zeroes--;
      } else {
	/* probe beyond */
	if( NextLink->next != 0 ) {
	  if( NextLink->next->color_levels != 0 ) {
	    /* if new competition, merge with next link */
	    merge_links(ThisLink);
	    zeroes--;
	  } else {
	    z1count = ThisLink->pixel_area;
	    z2count = NextLink->next->pixel_area;
	    /* where would the next one go? */
	    if( (NextLink->next->next == 0) ||
		(NextLink->next->next->pixel_area > (b_count + z2count)) ) {
	      if( (b_count + z2count) > (a_count + z1count) ) {
		merge_links(PriorLink);
	      } else {
		merge_links(ThisLink);
	      }
	    } else
	      merge_links(ThisLink);
	    zeroes--;
	  }
	} else {
	  merge_links(PriorLink);
	  zeroes--;
	}
      }
    }
    PriorLink = ThisLink;
  }
}

/*
 * Subroutine:	merge_links
 * Purpose:	Combine two links of histogram group list
 */
static void merge_links ( subrange )
     SubrangeLink *subrange;
{
  SubrangeLink *lostlink;

  lostlink = subrange->next;
  subrange->next = lostlink->next;
  subrange->max_entry = MAX(subrange->max_entry, lostlink->max_entry);
  subrange->pixel_area += lostlink->pixel_area;
  subrange->high = lostlink->high;
  subrange->range += lostlink->range;
  subrange->nz_entries += lostlink->nz_entries;
  subrange->excess_pixels += lostlink->excess_pixels;
  subrange->color_levels += lostlink->color_levels;
  free( (char *)lostlink );
}