GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
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
23static 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 */
38void 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 */
57void 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 */
76void 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 */
104void 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 */
124int 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 */
154int 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 */
184int 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 */
218int 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
237static 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 G_free(rule);
295 return;
296 }
297 if (Rast_is_d_null_value(&(rule->high.value))) {
298 G_free(rule);
299 return;
300 }
301 min = rule->low.value;
302 max = rule->high.value;
303 if (min <= max) {
304 if (cp->min > cp->max) {
305 cp->min = min;
306 cp->max = max;
307 }
308 else {
309 if (cp->min > min)
310 cp->min = min;
311 if (cp->max < max)
312 cp->max = max;
313 }
314 }
315 if (*cmin > *cmax) {
316 *cmin = cp->min;
317 *cmax = cp->max;
318 }
319 else {
320 if (*cmin > cp->min)
321 *cmin = cp->min;
322 if (*cmax < cp->max)
323 *cmax = cp->max;
324 }
325
326 /* If version is old style (i.e., pre 4.0),
327 * interpolate this rule from min to max
328 * and insert each cat into the lookup table.
329 * Then free the rule.
330 * Otherwise, free the lookup table, if active.
331 * G_organize_colors() will regenerate it
332 * Link this rule into the list of rules
333 */
334
335 if (version < 0) {
336 for (cat = (CELL)min; cat <= (CELL)max; cat++) {
337 Rast__interpolate_color_rule((DCELL)cat, &red, &grn, &blu, rule);
338 Rast__insert_color_into_lookup(cat, (int)red, (int)grn, (int)blu,
339 cp);
340 }
341 G_free(rule);
342 }
343 else {
344 if (cp->rules)
345 cp->rules->prev = rule;
346 rule->next = cp->rules;
347 cp->rules = rule;
348
349 /* prune the rules:
350 * remove all rules that are contained by this rule
351 */
352 min = rule->low.value; /* mod 4.1 */
353 max = rule->high.value; /* mod 4.1 */
354 cp->n_rules++;
355 for (rule = rule->next; rule; rule = next) {
356 next = rule->next; /* has to be done here, not in for stmt */
357 if (min <= rule->low.value && max >= rule->high.value) {
358 if ((rule->prev->next = next)) /* remove from the list */
359 next->prev = rule->prev;
360 G_free(rule);
361 cp->n_rules--;
362 }
363 }
364
365 /* free lookup array, if allocated */
368 }
369}
#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:147
#define G_malloc(n)
Definition defs/gis.h:139
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)
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:636
double DCELL
Definition gis.h:635
int CELL
Definition gis.h:634
#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:692
DCELL cmax
Definition gis.h:708
struct _Color_Info_ fixed
Definition gis.h:705
struct _Color_Info_ modular
Definition gis.h:706
int version
Definition gis.h:693
DCELL cmin
Definition gis.h:707
struct _Color_Rule_ * prev
Definition gis.h:665
struct _Color_Rule_ * next
Definition gis.h:664
struct _Color_Value_ low high
Definition gis.h:663