5
* \brief GIS Library - Color rules.
7
* (C) 2001-2008 by the GRASS Development Team
9
* This program is free software under the GNU General Public License
10
* (>=v2). Read the file COPYING that comes with GRASS for details.
12
* \author GRASS GIS Development Team
17
#include <grass/gis.h>
19
#define LIMIT(x) if (x < 0) x = 0; else if (x > 255) x = 255;
21
static int add_color_rule(const void *, int, int, int,
22
const void *, int, int, int,
23
struct _Color_Info_ *, int,
24
DCELL *, DCELL *, RASTER_MAP_TYPE);
28
* \brief Adds the floating-point rule (DCELL version)
30
* See G_add_raster_color_rule() for details.
32
* \param v1 cell value
33
* \param r1,g1,b1 color value
34
* \param v2 cell value
35
* \param r2,g2,b2 color value
36
* \param[in,out] colors pointer to color table structure
41
G_add_d_raster_color_rule(const DCELL * val1, int r1, int g1, int b1,
42
const DCELL * val2, int r2, int g2, int b2,
43
struct Colors *colors)
45
add_color_rule(val1, r1, g1, b1, val2, r2, g2, b2, &colors->fixed,
46
colors->version, &colors->cmin, &colors->cmax, DCELL_TYPE);
52
* \brief Adds the floating-point rule (FCELL version)
54
* See G_add_raster_color_rule() for details.
56
* \param v1 cell value
57
* \param r1,g1,b1 color value
58
* \param v2 cell value
59
* \param r2,g2,b2 color value
60
* \param[in,out] colors pointer to color table structure
65
G_add_f_raster_color_rule(const FCELL * cat1, int r1, int g1, int b1,
66
const FCELL * cat2, int r2, int g2, int b2,
67
struct Colors *colors)
69
add_color_rule(cat1, r1, g1, b1, cat2, r2, g2, b2, &colors->fixed,
70
colors->version, &colors->cmin, &colors->cmax, FCELL_TYPE);
76
* \brief Adds the floating-point rule (CCELL version)
78
* See G_add_raster_color_rule() for details.
80
* \param v1 cell value
81
* \param r1,g1,b1 color value
82
* \param v2 cell value
83
* \param r2,g2,b2 color value
84
* \param[in,out] colors pointer to color table structure
89
G_add_c_raster_color_rule(const CELL * cat1, int r1, int g1, int b1,
90
const CELL * cat2, int r2, int g2, int b2,
91
struct Colors *colors)
93
add_color_rule(cat1, r1, g1, b1, cat2, r2, g2, b2, &colors->fixed,
94
colors->version, &colors->cmin, &colors->cmax, CELL_TYPE);
100
* \brief Adds the floating-point rule
102
* Adds the floating-point rule that the range [<em>v1,v2</em>] gets a
103
* linear ramp of colors from [<em>r1,g1,b1</em>] to
104
* [<em>r2,g2,b2</em>].
105
* If either <em>v1</em> or <em>v2</em> is the NULL-value, this call is converted into
106
* <tt>G_set_null_value_color (r1, g1, b1, colors)</tt>
108
* - If <em>map_type</em> is CELL_TYPE, calls G_add_c_raster_color_rule()
109
* - If <em>map_type</em> is FCELL_TYPE, calls G_add_f_raster_color_rule()
110
* - If <em>map_type</em> is DCELL_TYPE, calls G_add_d_raster_color_rule()
112
* \param v1 cell value
113
* \param r1,g1,b1 color value
114
* \param v2 cell value
115
* \param r2,g2,b2 color value
116
* \param[in,out] colors pointer to color table structure
117
* \param data_type raster data type (CELL, FCELL, DCELL)
122
G_add_raster_color_rule(const void *val1, int r1, int g1, int b1,
123
const void *val2, int r2, int g2, int b2,
124
struct Colors *colors, RASTER_MAP_TYPE data_type)
126
add_color_rule(val1, r1, g1, b1, val2, r2, g2, b2, &colors->fixed,
127
colors->version, &colors->cmin, &colors->cmax, data_type);
133
* \brief Set colors rules
136
* and soul of the new color logic. It adds a color rule to the <b>colors</b>
137
* structure. The colors defined by the red, green, and blue values
138
* <b>r1,g1,b1</b> and <b>r2,g2,b2</b> are assigned to <b>cat1</b> and
139
* <b>cat2</b> respectively. Colors for data values between <b>cat1</b> and
140
* <b>cat2</b> are not stored in the structure but are interpolated when
141
* queried by <i>G_lookup_colors</i> and<i>G_get_color.</i> The color
142
* components <b>r1,g1,b1</b> and <b>r2,g2,b2</b> must be in the range
144
* For example, to create a linear grey scale for the range 200 -- 1000:
147
G_init_colors (&colr);
148
G_add_color_rule ((CELL)200, 0,0,0, (CELL)1000, 255,255,255);
150
* The programmer is encouraged to review Raster_Color_Table_Format how
151
* this routine fits into the 5.x raster color logic.
152
* <b>Note.</b> The <b>colors</b> structure must have been initialized by
153
* <i>G_init_colors.</i> See Predefined_Color_Tables for routines to
154
* build some predefined color tables.
156
* \param cat1 cell value
157
* \param r1,g1,b1 color value
158
* \param cat2 cell value
159
* \param r2,g2,b2 color value
160
* \param[in,out] colors pointer to color table structure
165
G_add_color_rule(CELL cat1, int r1, int g1, int b1, CELL cat2, int r2, int g2,
166
int b2, struct Colors *colors)
168
add_color_rule((void *)&cat1, r1, g1, b1, (void *)&cat2, r2, g2, b2,
169
&colors->fixed, colors->version, &colors->cmin,
170
&colors->cmax, CELL_TYPE);
175
* \brief Add modular color rule (DCELL version)
177
* \param val1 cell value
178
* \param r1,g1,b1 color value
179
* \param val2 cell value
180
* \param r2,g2,b2 color value
181
* \param[in,out] colors pointer to color table structure
183
* \return -1 on failure
184
* \return 1 on success
187
G_add_modular_d_raster_color_rule(const DCELL * val1, int r1, int g1, int b1,
188
const DCELL * val2, int r2, int g2, int b2,
189
struct Colors *colors)
193
if (colors->version < 0)
194
return -1; /* can't use this on 3.0 colors */
197
add_color_rule(val1, r1, g1, b1, val2, r2, g2, b2, &colors->modular, 0,
198
&colors->cmin, &colors->cmax, DCELL_TYPE);
199
colors->cmin = min; /* don't reset these */
206
* \brief Add modular color rule (FCELL version)
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
214
* \return -1 on failure
215
* \return 1 on success
218
G_add_modular_f_raster_color_rule(const FCELL * val1, int r1, int g1, int b1,
219
const FCELL * val2, int r2, int g2, int b2,
220
struct Colors *colors)
224
if (colors->version < 0)
225
return -1; /* can;t use this on 3.0 colors */
228
add_color_rule(val1, r1, g1, b1, val2, r2, g2, b2, &colors->modular, 0,
229
&colors->cmin, &colors->cmax, FCELL_TYPE);
230
colors->cmin = min; /* don't reset these */
237
* \brief Add modular color rule (CCELL version)
239
* \param val1 cell value
240
* \param r1,g1,b1 color value
241
* \param val2 cell value
242
* \param r2,g2,b2 color value
243
* \param[in,out] colors pointer to color table structure
245
* \return -1 on failure
246
* \return 1 on success
249
G_add_modular_c_raster_color_rule(const CELL * val1, int r1, int g1, int b1,
250
const CELL * val2, int r2, int g2, int b2,
251
struct Colors *colors)
253
return G_add_modular_color_rule(*val1, r1, g1, b1, *val2, r2, g2, b2,
258
* \brief Add modular color rule
260
* Question: shouldn't this function call
261
* G_add_modular_<data_type>_raster_color_rule() instead???
263
* \param val1 cell value
264
* \param r1,g1,b1 color value
265
* \param val2 cell value
266
* \param r2,g2,b2 color value
267
* \param[in,out] colors pointer to color table structure
268
* \param data_type raster data type
270
* \return -1 on failure
271
* \return 1 on success
274
G_add_modular_raster_color_rule(const void *val1, int r1, int g1, int b1,
275
const void *val2, int r2, int g2, int b2,
276
struct Colors *colors,
277
RASTER_MAP_TYPE data_type)
281
if (colors->version < 0)
282
return -1; /* can't use this on 3.0 colors */
285
add_color_rule(val1, r1, g1, b1, val2, r2, g2, b2, &colors->modular, 0,
286
&colors->cmin, &colors->cmax, data_type);
287
colors->cmin = min; /* don't reset these */
294
* \brief Add modular color rule
296
* This function seems to be same as
297
* G_add_modular_raster_color_rule(). Can be removed?
299
* \param val1 cell value
300
* \param r1,g1,b1 color value
301
* \param val2 cell value
302
* \param r2,g2,b2 color value
303
* \param[in,out] colors pointer to color table structure
304
* \param data_type raster data type
306
* \return -1 on failure
307
* \return 1 on success
310
G_add_modular_color_rule(CELL cat1, int r1, int g1, int b1, CELL cat2, int r2,
311
int g2, int b2, struct Colors *colors)
315
if (colors->version < 0)
316
return -1; /* can;t use this on 3.0 colors */
319
add_color_rule((void *)&cat1, r1, g1, b1, (void *)&cat2, r2, g2, b2,
320
&colors->modular, 0, &colors->cmin, &colors->cmax,
322
colors->cmin = min; /* don't reset these */
328
static int add_color_rule(const void *pt1, int r1, int g1, int b1,
329
const void *pt2, int r2, int g2, int b2,
330
struct _Color_Info_ *cp, int version, DCELL * cmin,
331
DCELL * cmax, RASTER_MAP_TYPE data_type)
333
struct _Color_Rule_ *rule, *next;
334
unsigned char red, grn, blu;
335
DCELL min, max, val1, val2;
338
val1 = G_get_raster_value_d(pt1, data_type);
339
val2 = G_get_raster_value_d(pt2, data_type);
340
/* allocate a low:high rule */
341
rule = (struct _Color_Rule_ *)G_malloc(sizeof(*rule));
342
rule->next = rule->prev = NULL;
344
/* make sure colors are in the range [0,255] */
352
/* val1==val2, use average color */
353
/* otherwise make sure low < high */
355
rule->low.value = rule->high.value = val1;
356
rule->low.red = rule->high.red = (r1 + r2) / 2;
357
rule->low.grn = rule->high.grn = (g1 + g2) / 2;
358
rule->low.blu = rule->high.blu = (b1 + b2) / 2;
360
else if (val1 < val2) {
361
rule->low.value = val1;
366
rule->high.value = val2;
372
rule->low.value = val2;
377
rule->high.value = val1;
383
/* keep track of the overall min and max, excluding null */
384
if (G_is_d_null_value(&(rule->low.value)))
386
if (G_is_d_null_value(&(rule->high.value)))
388
min = rule->low.value;
389
max = rule->high.value;
391
if (cp->min > cp->max) {
413
/* If version is old style (i.e., pre 4.0),
414
* interpolate this rule from min to max
415
* and insert each cat into the lookup table.
416
* Then free the rule.
417
* Otherwise, free the lookup table, if active.
418
* G_organize_colors() will regenerate it
419
* Link this rule into the list of rules
423
for (cat = (CELL) min; cat <= (CELL) max; cat++) {
424
G__interpolate_color_rule((DCELL) cat, &red, &grn, &blu, rule);
425
G__insert_color_into_lookup(cat, (int)red, (int)grn, (int)blu,
432
cp->rules->prev = rule;
433
rule->next = cp->rules;
437
* remove all rules that are contained by this rule
439
min = rule->low.value; /* mod 4.1 */
440
max = rule->high.value; /* mod 4.1 */
442
for (rule = rule->next; rule; rule = next) {
443
next = rule->next; /* has to be done here, not in for stmt */
444
if (min <= rule->low.value && max >= rule->high.value) {
445
if ((rule->prev->next = next)) /* remove from the list */
446
next->prev = rule->prev;
452
/* free lookup array, if allocated */
453
G__color_free_lookup(cp);
454
G__color_free_fp_lookup(cp);