GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
color_org.c
Go to the documentation of this file.
1 #include <grass/gis.h>
2 #include <stdlib.h>
3 
4 #define LOOKUP_COLORS 2048
5 
6 static int organizing = 0;
7 static int organize_lookup(struct Colors *, int);
8 static int organize_fp_lookup(struct Colors *, int);
9 static int double_comp(const void *, const void *);
10 
11 int G__organize_colors(struct Colors *colors)
12 {
13  /* don't do anything if called recursively */
14  if (!organizing) {
15  organizing = 1;
16 
17  organize_lookup(colors, 0);
18  organize_lookup(colors, 1);
19 
20  organize_fp_lookup(colors, 0);
21  organize_fp_lookup(colors, 1);
22 
23  organizing = 0;
24  }
25 
26  return 0;
27 }
28 
29 static int organize_fp_lookup(struct Colors *colors, int mod)
30 {
31  int i;
32  DCELL val;
33  struct _Color_Info_ *cp;
34  struct _Color_Rule_ *rule;
35 
36  if (mod)
37  cp = &colors->modular;
38  else
39  cp = &colors->fixed;
40 
41  /* if one of the lookup tables exist, don't do anything */
42  if (cp->lookup.active || cp->fp_lookup.active)
43  return 1;
44  if (cp->n_rules == 0)
45  return 1;
46 
47  cp->fp_lookup.vals = (DCELL *)
48  G_calloc(cp->n_rules * 2, sizeof(DCELL));
49  /* 2 endpoints for each rule */
50  cp->fp_lookup.rules = (struct _Color_Rule_ **)
51  G_calloc(cp->n_rules * 2, sizeof(struct _Color_Rule_ *));
52 
53  /* get the list of DCELL values from set of all lows and highs
54  of all rules */
55  /* NOTE: if low==high in a rule, the value appears twice in a list
56  but if low==high of the previous, rule the value appears only once */
57 
58  i = 0;
59  /* go through the list of rules from end to beginning,
60  because rules are sored in reverse order of reading,
61  and we want to read the in correct order, to ignore
62  the same values in the end of rule and beginning of next rule */
63 
64  /* first go to the last rules */
65  for (rule = cp->rules; rule->next; rule = rule->next) ;
66  /* now traverse from the last to the first rule */
67  for (; rule; rule = rule->prev) {
68  /* check if the min is the same as previous maximum */
69  if (i == 0 || rule->low.value != cp->fp_lookup.vals[i - 1])
70  cp->fp_lookup.vals[i++] = rule->low.value;
71  cp->fp_lookup.vals[i++] = rule->high.value;
72  }
73  cp->fp_lookup.nalloc = i;
74 
75  /* now sort the values */
76  qsort((char *)cp->fp_lookup.vals, cp->fp_lookup.nalloc,
77  sizeof(DCELL), &double_comp);
78 
79  /* now find the rule to apply inbetween each 2 values in a list */
80  for (i = 0; i < cp->fp_lookup.nalloc - 1; i++) {
81  val = (cp->fp_lookup.vals[i] + cp->fp_lookup.vals[i + 1]) / 2.;
82  /* fprintf (stderr, "%lf %lf ", cp->fp_lookup.vals[i], cp->fp_lookup.vals[i+1]); */
83 
84  for (rule = cp->rules; rule; rule = rule->next)
85  if (rule->low.value <= val && val <= rule->high.value)
86  break;
87  /* if(rule) fprintf (stderr, "%d %lf %lf %d\n", i, rule->low.value, rule->high.value, rule);
88  else fprintf (stderr, "null\n");
89  */
90  cp->fp_lookup.rules[i] = rule;
91  }
92  cp->fp_lookup.active = 1;
93 
94  return 0;
95 }
96 
97 static int organize_lookup(struct Colors *colors, int mod)
98 {
99  int i, n;
100  CELL x;
101  CELL cat[LOOKUP_COLORS];
102  struct _Color_Info_ *cp;
103 
104  /* don't do anything if the color structure is float */
105  if (colors->is_float)
106  return 0;
107 
108  if (mod)
109  cp = &colors->modular;
110  else
111  cp = &colors->fixed;
112 
113  if (cp->lookup.active)
114  return 0;
115 
116  n = (CELL) cp->max - (CELL) cp->min + 1;
117  if (n >= LOOKUP_COLORS || n <= 0)
118  return 0;
119 
120  x = (CELL) cp->min;
121  for (i = 0; i < n; i++)
122  cat[i] = x++;;
123 
124  cp->lookup.nalloc = n;
125  cp->lookup.red = (unsigned char *)G_malloc(n);
126  cp->lookup.grn = (unsigned char *)G_malloc(n);
127  cp->lookup.blu = (unsigned char *)G_malloc(n);
128  cp->lookup.set = (unsigned char *)G_malloc(n);
129 
130  G_zero(cp->lookup.set, n * sizeof(unsigned char));
131  G__lookup_colors((void *)cat,
132  cp->lookup.red, cp->lookup.grn, cp->lookup.blu,
133  cp->lookup.set, n, colors, mod, 1, CELL_TYPE);
134 
135  cp->lookup.active = 1;
136 
137  return 0;
138 }
139 
140 static int double_comp(const void *xx, const void *yy)
141 {
142  const DCELL *x = xx, *y = yy;
143 
144  if (*x < *y)
145  return -1;
146  else if (*x == *y)
147  return 0;
148  else
149  return 1;
150 }
int y
Definition: plot.c:34
int G_zero(void *buf, int i)
Zero out a buffer, buf, of length i.
Definition: gis/zero.c:29
#define LOOKUP_COLORS
Definition: color_org.c:4
int G__organize_colors(struct Colors *colors)
Definition: color_org.c:11
for(cat=0;;cat++)
Definition: g3dcats.c:140
CELL cat
Definition: g3dcats.c:90
int G__lookup_colors(const void *raster, unsigned char *red, unsigned char *grn, unsigned char *blu, unsigned char *set, int n, struct Colors *colors, int mod, int rules_only, RASTER_MAP_TYPE data_type)
Definition: color_look.c:231
int n
Definition: dataquad.c:291