GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-d6dec75dd4
color_rule.c
Go to the documentation of this file.
1 /*!
2  \file lib/raster/color_rule.c
3 
4  \brief Raster Library - Color rules.
5 
6  (C) 2001-2009 by the GRASS Development Team
7 
8  This program is free software under the GNU General Public License
9  (>=v2). Read the file COPYING that comes with GRASS for details.
10 
11  \author Original author CERL
12  */
13 
14 #include <grass/gis.h>
15 #include <grass/raster.h>
16 
17 #define LIMIT(x) \
18  if (x < 0) \
19  x = 0; \
20  else if (x > 255) \
21  x = 255;
22 
23 static void add_color_rule(const void *, int, int, int, const void *, int, int,
24  int, struct _Color_Info_ *, int, DCELL *, DCELL *,
26 
27 /*!
28  \brief Adds the floating-point color rule (DCELL version)
29 
30  See Rast_add_color_rule() for details.
31 
32  \param val1 cell value
33  \param r1,g1,b1 color value
34  \param val2 cell value
35  \param r2,g2,b2 color value
36  \param[in,out] colors pointer to color table structure
37  */
38 void Rast_add_d_color_rule(const DCELL *val1, int r1, int g1, int b1,
39  const DCELL *val2, int r2, int g2, int b2,
40  struct Colors *colors)
41 {
42  add_color_rule(val1, r1, g1, b1, val2, r2, g2, b2, &colors->fixed,
43  colors->version, &colors->cmin, &colors->cmax, DCELL_TYPE);
44 }
45 
46 /*!
47  \brief Adds the floating-point color rule (FCELL version)
48 
49  See Rast_add_color_rule() for details.
50 
51  \param cat1 cell value
52  \param r1,g1,b1 color value
53  \param cat2 cell value
54  \param r2,g2,b2 color value
55  \param[in,out] colors pointer to color table structure
56  */
57 void Rast_add_f_color_rule(const FCELL *cat1, int r1, int g1, int b1,
58  const FCELL *cat2, int r2, int g2, int b2,
59  struct Colors *colors)
60 {
61  add_color_rule(cat1, r1, g1, b1, cat2, r2, g2, b2, &colors->fixed,
62  colors->version, &colors->cmin, &colors->cmax, FCELL_TYPE);
63 }
64 
65 /*!
66  \brief Adds the integer color rule (CELL version)
67 
68  See Rast_add_color_rule() for details.
69 
70  \param cat1 cell value
71  \param r1,g1,b1 color value
72  \param cat2 cell value
73  \param r2,g2,b2 color value
74  \param[in,out] colors pointer to color table structure
75  */
76 void Rast_add_c_color_rule(const CELL *cat1, int r1, int g1, int b1,
77  const CELL *cat2, int r2, int g2, int b2,
78  struct Colors *colors)
79 {
80  add_color_rule(cat1, r1, g1, b1, cat2, r2, g2, b2, &colors->fixed,
81  colors->version, &colors->cmin, &colors->cmax, CELL_TYPE);
82 }
83 
84 /*!
85  \brief Adds the color rule
86 
87  Adds the floating-point rule that the range [<em>v1,v2</em>] gets a
88  linear ramp of colors from [<em>r1,g1,b1</em>] to
89  [<em>r2,g2,b2</em>].
90  If either <em>v1</em> or <em>v2</em> is the NULL-value, this call is
91  converted ino <tt>Rast_set_null_value_color (r1, g1, b1, colors)</tt>
92 
93  - If <em>map_type</em> is CELL_TYPE, calls Rast_add_c_color_rule()
94  - If <em>map_type</em> is FCELL_TYPE, calls Rast_add_f_color_rule()
95  - If <em>map_type</em> is DCELL_TYPE, calls Rast_add_d_color_rule()
96 
97  \param val1 cell value
98  \param r1,g1,b1 color value
99  \param val2 cell value
100  \param r2,g2,b2 color value
101  \param[in,out] colors pointer to color table structure
102  \param data_type raster data type (CELL, FCELL, DCELL)
103  */
104 void Rast_add_color_rule(const void *val1, int r1, int g1, int b1,
105  const void *val2, int r2, int g2, int b2,
106  struct Colors *colors, RASTER_MAP_TYPE data_type)
107 {
108  add_color_rule(val1, r1, g1, b1, val2, r2, g2, b2, &colors->fixed,
109  colors->version, &colors->cmin, &colors->cmax, data_type);
110 }
111 
112 /*!
113  \brief Add modular floating-point color rule (DCELL version)
114 
115  \param val1 cell value
116  \param r1,g1,b1 color value
117  \param val2 cell value
118  \param r2,g2,b2 color value
119  \param[in,out] colors pointer to color table structure
120 
121  \return -1 on failure
122  \return 1 on success
123  */
124 int Rast_add_modular_d_color_rule(const DCELL *val1, int r1, int g1, int b1,
125  const DCELL *val2, int r2, int g2, int b2,
126  struct Colors *colors)
127 {
128  DCELL min, max;
129 
130  if (colors->version < 0)
131  return -1; /* can't use this on 3.0 colors */
132  min = colors->cmin;
133  max = colors->cmax;
134  add_color_rule(val1, r1, g1, b1, val2, r2, g2, b2, &colors->modular, 0,
135  &colors->cmin, &colors->cmax, DCELL_TYPE);
136  colors->cmin = min; /* don't reset these */
137  colors->cmax = max;
138 
139  return 1;
140 }
141 
142 /*!
143  \brief Add modular floating-point color rule (FCELL version)
144 
145  \param val1 cell value
146  \param r1,g1,b1 color value
147  \param val2 cell value
148  \param r2,g2,b2 color value
149  \param[in,out] colors pointer to color table structure
150 
151  \return -1 on failure
152  \return 1 on success
153  */
154 int Rast_add_modular_f_color_rule(const FCELL *val1, int r1, int g1, int b1,
155  const FCELL *val2, int r2, int g2, int b2,
156  struct Colors *colors)
157 {
158  DCELL min, max;
159 
160  if (colors->version < 0)
161  return -1; /* can;t use this on 3.0 colors */
162  min = colors->cmin;
163  max = colors->cmax;
164  add_color_rule(val1, r1, g1, b1, val2, r2, g2, b2, &colors->modular, 0,
165  &colors->cmin, &colors->cmax, FCELL_TYPE);
166  colors->cmin = min; /* don't reset these */
167  colors->cmax = max;
168 
169  return 1;
170 }
171 
172 /*!
173  \brief Add modular integer color rule (CELL version)
174 
175  \param val1 cell value
176  \param r1,g1,b1 color value
177  \param val2 cell value
178  \param r2,g2,b2 color value
179  \param[in,out] colors pointer to color table structure
180 
181  \return -1 on failure
182  \return 1 on success
183  */
184 int Rast_add_modular_c_color_rule(const CELL *val1, int r1, int g1, int b1,
185  const CELL *val2, int r2, int g2, int b2,
186  struct Colors *colors)
187 {
188  CELL min, max;
189 
190  if (colors->version < 0)
191  return -1; /* can;t use this on 3.0 colors */
192  min = colors->cmin;
193  max = colors->cmax;
194  add_color_rule(val1, r1, g1, b1, val2, r2, g2, b2, &colors->modular, 0,
195  &colors->cmin, &colors->cmax, CELL_TYPE);
196  colors->cmin = min; /* don't reset these */
197  colors->cmax = max;
198 
199  return 1;
200 }
201 
202 /*!
203  \brief Add modular color rule
204 
205  \todo Question: shouldn't this function call
206  G_add_modular_<data_type>_raster_color_rule() instead?
207 
208  \param val1 cell value
209  \param r1,g1,b1 color value
210  \param val2 cell value
211  \param r2,g2,b2 color value
212  \param[in,out] colors pointer to color table structure
213  \param data_type raster data type
214 
215  \return -1 on failure
216  \return 1 on success
217  */
218 int Rast_add_modular_color_rule(const void *val1, int r1, int g1, int b1,
219  const void *val2, int r2, int g2, int b2,
220  struct Colors *colors,
221  RASTER_MAP_TYPE data_type)
222 {
223  CELL min, max;
224 
225  if (colors->version < 0)
226  return -1; /* can't use this on 3.0 colors */
227  min = colors->cmin;
228  max = colors->cmax;
229  add_color_rule(val1, r1, g1, b1, val2, r2, g2, b2, &colors->modular, 0,
230  &colors->cmin, &colors->cmax, data_type);
231  colors->cmin = min; /* don't reset these */
232  colors->cmax = max;
233 
234  return 1;
235 }
236 
237 static void add_color_rule(const void *pt1, int r1, int g1, int b1,
238  const void *pt2, int r2, int g2, int b2,
239  struct _Color_Info_ *cp, int version, DCELL *cmin,
240  DCELL *cmax, RASTER_MAP_TYPE data_type)
241 {
242  struct _Color_Rule_ *rule, *next;
243  unsigned char red, grn, blu;
244  DCELL min, max, val1, val2;
245  CELL cat;
246 
247  val1 = Rast_get_d_value(pt1, data_type);
248  val2 = Rast_get_d_value(pt2, data_type);
249  /* allocate a low:high rule */
250  rule = (struct _Color_Rule_ *)G_malloc(sizeof(*rule));
251  rule->next = rule->prev = NULL;
252 
253  /* make sure colors are in the range [0,255] */
254  LIMIT(r1);
255  LIMIT(g1);
256  LIMIT(b1);
257  LIMIT(r2);
258  LIMIT(g2);
259  LIMIT(b2);
260 
261  /* val1==val2, use average color */
262  /* otherwise make sure low < high */
263  if (val1 == val2) {
264  rule->low.value = rule->high.value = val1;
265  rule->low.red = rule->high.red = (r1 + r2) / 2;
266  rule->low.grn = rule->high.grn = (g1 + g2) / 2;
267  rule->low.blu = rule->high.blu = (b1 + b2) / 2;
268  }
269  else if (val1 < val2) {
270  rule->low.value = val1;
271  rule->low.red = r1;
272  rule->low.grn = g1;
273  rule->low.blu = b1;
274 
275  rule->high.value = val2;
276  rule->high.red = r2;
277  rule->high.grn = g2;
278  rule->high.blu = b2;
279  }
280  else {
281  rule->low.value = val2;
282  rule->low.red = r2;
283  rule->low.grn = g2;
284  rule->low.blu = b2;
285 
286  rule->high.value = val1;
287  rule->high.red = r1;
288  rule->high.grn = g1;
289  rule->high.blu = b1;
290  }
291 
292  /* keep track of the overall min and max, excluding null */
293  if (Rast_is_d_null_value(&(rule->low.value)))
294  return;
295  if (Rast_is_d_null_value(&(rule->high.value)))
296  return;
297  min = rule->low.value;
298  max = rule->high.value;
299  if (min <= max) {
300  if (cp->min > cp->max) {
301  cp->min = min;
302  cp->max = max;
303  }
304  else {
305  if (cp->min > min)
306  cp->min = min;
307  if (cp->max < max)
308  cp->max = max;
309  }
310  }
311  if (*cmin > *cmax) {
312  *cmin = cp->min;
313  *cmax = cp->max;
314  }
315  else {
316  if (*cmin > cp->min)
317  *cmin = cp->min;
318  if (*cmax < cp->max)
319  *cmax = cp->max;
320  }
321 
322  /* If version is old style (i.e., pre 4.0),
323  * interpolate this rule from min to max
324  * and insert each cat into the lookup table.
325  * Then free the rule.
326  * Otherwise, free the lookup table, if active.
327  * G_organize_colors() will regenerate it
328  * Link this rule into the list of rules
329  */
330 
331  if (version < 0) {
332  for (cat = (CELL)min; cat <= (CELL)max; cat++) {
333  Rast__interpolate_color_rule((DCELL)cat, &red, &grn, &blu, rule);
334  Rast__insert_color_into_lookup(cat, (int)red, (int)grn, (int)blu,
335  cp);
336  }
337  G_free(rule);
338  }
339  else {
340  if (cp->rules)
341  cp->rules->prev = rule;
342  rule->next = cp->rules;
343  cp->rules = rule;
344 
345  /* prune the rules:
346  * remove all rules that are contained by this rule
347  */
348  min = rule->low.value; /* mod 4.1 */
349  max = rule->high.value; /* mod 4.1 */
350  cp->n_rules++;
351  for (rule = rule->next; rule; rule = next) {
352  next = rule->next; /* has to be done here, not in for stmt */
353  if (min <= rule->low.value && max >= rule->high.value) {
354  if ((rule->prev->next = next)) /* remove from the list */
355  next->prev = rule->prev;
356  G_free(rule);
357  cp->n_rules--;
358  }
359  }
360 
361  /* free lookup array, if allocated */
364  }
365 }
#define NULL
Definition: ccmath.h:32
int Rast_add_modular_c_color_rule(const CELL *val1, int r1, int g1, int b1, const CELL *val2, int r2, int g2, int b2, struct Colors *colors)
Add modular integer color rule (CELL version)
Definition: color_rule.c:184
void Rast_add_d_color_rule(const DCELL *val1, int r1, int g1, int b1, const DCELL *val2, int r2, int g2, int b2, struct Colors *colors)
Adds the floating-point color rule (DCELL version)
Definition: color_rule.c:38
void Rast_add_c_color_rule(const CELL *cat1, int r1, int g1, int b1, const CELL *cat2, int r2, int g2, int b2, struct Colors *colors)
Adds the integer color rule (CELL version)
Definition: color_rule.c:76
int Rast_add_modular_color_rule(const void *val1, int r1, int g1, int b1, const void *val2, int r2, int g2, int b2, struct Colors *colors, RASTER_MAP_TYPE data_type)
Add modular color rule.
Definition: color_rule.c:218
void Rast_add_f_color_rule(const FCELL *cat1, int r1, int g1, int b1, const FCELL *cat2, int r2, int g2, int b2, struct Colors *colors)
Adds the floating-point color rule (FCELL version)
Definition: color_rule.c:57
#define LIMIT(x)
Definition: color_rule.c:17
int Rast_add_modular_d_color_rule(const DCELL *val1, int r1, int g1, int b1, const DCELL *val2, int r2, int g2, int b2, struct Colors *colors)
Add modular floating-point color rule (DCELL version)
Definition: color_rule.c:124
void Rast_add_color_rule(const void *val1, int r1, int g1, int b1, const void *val2, int r2, int g2, int b2, struct Colors *colors, RASTER_MAP_TYPE data_type)
Adds the color rule.
Definition: color_rule.c:104
int Rast_add_modular_f_color_rule(const FCELL *val1, int r1, int g1, int b1, const FCELL *val2, int r2, int g2, int b2, struct Colors *colors)
Add modular floating-point color rule (FCELL version)
Definition: color_rule.c:154
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:150
#define G_malloc(n)
Definition: defs/gis.h:94
int Rast__insert_color_into_lookup(CELL, int, int, int, struct _Color_Info_ *)
Definition: color_insrt.c:18
void Rast__color_free_fp_lookup(struct _Color_Info_ *)
Free color rules structure.
Definition: color_free.c:79
#define Rast_is_d_null_value(dcellVal)
Definition: defs/raster.h:408
void Rast__color_free_lookup(struct _Color_Info_ *)
Free color rules structure.
Definition: color_free.c:61
void Rast__interpolate_color_rule(DCELL, unsigned char *, unsigned char *, unsigned char *, const struct _Color_Rule_ *)
Interpolate color rules.
Definition: color_look.c:422
DCELL Rast_get_d_value(const void *, RASTER_MAP_TYPE)
Retrieves the value of given type from pointer p (DCELL)
#define min(x, y)
Definition: draw2.c:29
#define max(x, y)
Definition: draw2.c:30
float FCELL
Definition: gis.h:630
double DCELL
Definition: gis.h:629
int CELL
Definition: gis.h:628
#define FCELL_TYPE
Definition: raster.h:12
#define DCELL_TYPE
Definition: raster.h:13
#define CELL_TYPE
Definition: raster.h:11
int RASTER_MAP_TYPE
Definition: raster.h:25
Definition: gis.h:686
DCELL cmax
Definition: gis.h:702
struct _Color_Info_ fixed
Definition: gis.h:699
struct _Color_Info_ modular
Definition: gis.h:700
int version
Definition: gis.h:687
DCELL cmin
Definition: gis.h:701
DCELL max
Definition: gis.h:683
struct _Color_Rule_ * rules
Definition: gis.h:663
DCELL min
Definition: gis.h:683
int n_rules
Definition: gis.h:664
struct _Color_Rule_ * prev
Definition: gis.h:659
struct _Color_Rule_ * next
Definition: gis.h:658
struct _Color_Value_ low high
Definition: gis.h:657
unsigned char blu
Definition: gis.h:653
unsigned char red
Definition: gis.h:651
DCELL value
Definition: gis.h:650
unsigned char grn
Definition: gis.h:652