2
\file lib/raster/color_rule.c
4
\brief Raster Library - Color rules.
6
(C) 2001-2009 by the GRASS Development Team
8
This program is free software under the GNU General Public License
9
(>=v2). Read the file COPYING that comes with GRASS for details.
11
\author Original author CERL
14
#include <grass/gis.h>
15
#include <grass/raster.h>
17
#define LIMIT(x) if (x < 0) x = 0; else if (x > 255) x = 255;
19
static void add_color_rule(const void *, int, int, int,
20
const void *, int, int, int,
21
struct _Color_Info_ *, int,
22
DCELL *, DCELL *, RASTER_MAP_TYPE);
25
\brief Adds the floating-point color rule (DCELL version)
27
See Rast_add_color_rule() for details.
29
\param val1 cell value
30
\param r1,g1,b1 color value
31
\param val2 cell value
32
\param r2,g2,b2 color value
33
\param[in,out] colors pointer to color table structure
35
void Rast_add_d_color_rule(const DCELL * val1, int r1, int g1, int b1,
36
const DCELL * val2, int r2, int g2, int b2,
37
struct Colors *colors)
39
add_color_rule(val1, r1, g1, b1, val2, r2, g2, b2, &colors->fixed,
40
colors->version, &colors->cmin, &colors->cmax, DCELL_TYPE);
45
\brief Adds the floating-point color rule (FCELL version)
47
See Rast_add_color_rule() for details.
49
\param cat1 cell value
50
\param r1,g1,b1 color value
51
\param cat2 cell value
52
\param r2,g2,b2 color value
53
\param[in,out] colors pointer to color table structure
55
void Rast_add_f_color_rule(const FCELL * cat1, int r1, int g1, int b1,
56
const FCELL * cat2, int r2, int g2, int b2,
57
struct Colors *colors)
59
add_color_rule(cat1, r1, g1, b1, cat2, r2, g2, b2, &colors->fixed,
60
colors->version, &colors->cmin, &colors->cmax, FCELL_TYPE);
65
\brief Adds the integer color rule (CELL version)
67
See Rast_add_color_rule() for details.
69
\param cat1 cell value
70
\param r1,g1,b1 color value
71
\param cat2 cell value
72
\param r2,g2,b2 color value
73
\param[in,out] colors pointer to color table structure
75
void Rast_add_c_color_rule(const CELL * cat1, int r1, int g1, int b1,
76
const CELL * cat2, int r2, int g2, int b2,
77
struct Colors *colors)
79
add_color_rule(cat1, r1, g1, b1, cat2, r2, g2, b2, &colors->fixed,
80
colors->version, &colors->cmin, &colors->cmax, CELL_TYPE);
85
\brief Adds the color rule
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
90
If either <em>v1</em> or <em>v2</em> is the NULL-value, this call is converted ino
91
<tt>Rast_set_null_value_color (r1, g1, b1, colors)</tt>
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()
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)
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)
108
add_color_rule(val1, r1, g1, b1, val2, r2, g2, b2, &colors->fixed,
109
colors->version, &colors->cmin, &colors->cmax, data_type);
113
\brief Add modular floating-point color rule (DCELL version)
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
121
\return -1 on failure
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)
130
if (colors->version < 0)
131
return -1; /* can't use this on 3.0 colors */
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 */
143
\brief Add modular floating-point color rule (FCELL version)
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
151
\return -1 on failure
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)
160
if (colors->version < 0)
161
return -1; /* can;t use this on 3.0 colors */
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 */
173
\brief Add modular integer color rule (CELL version)
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
181
\return -1 on failure
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)
190
if (colors->version < 0)
191
return -1; /* can;t use this on 3.0 colors */
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 */
203
\brief Add modular color rule
205
\todo Question: shouldn't this function call
206
G_add_modular_<data_type>_raster_color_rule() instead?
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
215
\return -1 on failure
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)
225
if (colors->version < 0)
226
return -1; /* can't use this on 3.0 colors */
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 */
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)
242
struct _Color_Rule_ *rule, *next;
243
unsigned char red, grn, blu;
244
DCELL min, max, val1, val2;
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;
253
/* make sure colors are in the range [0,255] */
261
/* val1==val2, use average color */
262
/* otherwise make sure low < high */
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;
269
else if (val1 < val2) {
270
rule->low.value = val1;
275
rule->high.value = val2;
281
rule->low.value = val2;
286
rule->high.value = val1;
292
/* keep track of the overall min and max, excluding null */
293
if (Rast_is_d_null_value(&(rule->low.value)))
295
if (Rast_is_d_null_value(&(rule->high.value)))
297
min = rule->low.value;
298
max = rule->high.value;
300
if (cp->min > cp->max) {
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
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,
341
cp->rules->prev = rule;
342
rule->next = cp->rules;
346
* remove all rules that are contained by this rule
348
min = rule->low.value; /* mod 4.1 */
349
max = rule->high.value; /* mod 4.1 */
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;
361
/* free lookup array, if allocated */
362
Rast__color_free_lookup(cp);
363
Rast__color_free_fp_lookup(cp);