~ubuntu-branches/ubuntu/wily/grass/wily

« back to all changes in this revision

Viewing changes to lib/gis/color_rule.c

Tags: 7.0.0~rc1+ds1-1~exp1
* New upstream release candidate.
* Repack upstream tarball, remove precompiled Python objects.
* Add upstream metadata.
* Update gbp.conf and Vcs-Git URL to use the experimental branch.
* Update watch file for GRASS 7.0.
* Drop build dependencies for Tcl/Tk, add build dependencies:
  python-numpy, libnetcdf-dev, netcdf-bin, libblas-dev, liblapack-dev
* Update Vcs-Browser URL to use cgit instead of gitweb.
* Update paths to use grass70.
* Add configure options: --with-netcdf, --with-blas, --with-lapack,
  remove --with-tcltk-includes.
* Update patches for GRASS 7.
* Update copyright file, changes:
  - Update copyright years
  - Group files by license
  - Remove unused license sections
* Add patches for various typos.
* Fix desktop file with patch instead of d/rules.
* Use minimal dh rules.
* Bump Standards-Version to 3.9.6, no changes.
* Use dpkg-maintscript-helper to replace directories with symlinks.
  (closes: #776349)
* Update my email to use @debian.org address.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
/**
3
 
 * \file color_rule.c
4
 
 *
5
 
 * \brief GIS Library - Color rules.
6
 
 *
7
 
 * (C) 2001-2008 by the GRASS Development Team
8
 
 *
9
 
 * This program is free software under the GNU General Public License 
10
 
 * (>=v2). Read the file COPYING that comes with GRASS for details.
11
 
 *
12
 
 * \author GRASS GIS Development Team
13
 
 *
14
 
 * \date 1999-2008
15
 
 */
16
 
 
17
 
#include <grass/gis.h>
18
 
 
19
 
#define LIMIT(x) if (x < 0) x = 0; else if (x > 255) x = 255;
20
 
 
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);
25
 
 
26
 
 
27
 
/*!
28
 
 * \brief Adds the floating-point rule (DCELL version)
29
 
 *
30
 
 * See G_add_raster_color_rule() for details.
31
 
 *
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
37
 
 *  \return 1
38
 
 */
39
 
 
40
 
int
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)
44
 
{
45
 
    add_color_rule(val1, r1, g1, b1, val2, r2, g2, b2, &colors->fixed,
46
 
                   colors->version, &colors->cmin, &colors->cmax, DCELL_TYPE);
47
 
    return 1;
48
 
}
49
 
 
50
 
 
51
 
/*!
52
 
 * \brief Adds the floating-point rule (FCELL version)
53
 
 *
54
 
 * See G_add_raster_color_rule() for details.
55
 
 *
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
61
 
 *  \return 1
62
 
 */
63
 
 
64
 
int
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)
68
 
{
69
 
    add_color_rule(cat1, r1, g1, b1, cat2, r2, g2, b2, &colors->fixed,
70
 
                   colors->version, &colors->cmin, &colors->cmax, FCELL_TYPE);
71
 
    return 1;
72
 
}
73
 
 
74
 
 
75
 
/*!
76
 
 * \brief Adds the floating-point rule (CCELL version)
77
 
 *
78
 
 * See G_add_raster_color_rule() for details.
79
 
 *
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
85
 
 *  \return 1
86
 
 */
87
 
 
88
 
int
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)
92
 
{
93
 
    add_color_rule(cat1, r1, g1, b1, cat2, r2, g2, b2, &colors->fixed,
94
 
                   colors->version, &colors->cmin, &colors->cmax, CELL_TYPE);
95
 
    return 1;
96
 
}
97
 
 
98
 
 
99
 
/*!
100
 
 * \brief Adds the floating-point rule
101
 
 *
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>
107
 
 *
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()
111
 
 *
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)
118
 
 *  \return 1
119
 
 */
120
 
 
121
 
int
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)
125
 
{
126
 
    add_color_rule(val1, r1, g1, b1, val2, r2, g2, b2, &colors->fixed,
127
 
                   colors->version, &colors->cmin, &colors->cmax, data_type);
128
 
    return 1;
129
 
}
130
 
 
131
 
 
132
 
/*!
133
 
 * \brief Set colors rules
134
 
 *
135
 
 * This is the heart
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
143
 
 * 0 -- 255.
144
 
 * For example, to create a linear grey scale for the range 200 -- 1000:
145
 
 \code
146
 
 struct Colors colr;
147
 
 G_init_colors (&colr);
148
 
 G_add_color_rule ((CELL)200, 0,0,0, (CELL)1000, 255,255,255);
149
 
 \endcode
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. 
155
 
 *
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
161
 
 *  \return 1
162
 
 */
163
 
 
164
 
int
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)
167
 
{
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);
171
 
    return 1;
172
 
}
173
 
 
174
 
/**
175
 
 * \brief Add modular color rule (DCELL version)
176
 
 *
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
182
 
 *
183
 
 * \return -1 on failure
184
 
 * \return 1 on success
185
 
 */
186
 
int
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)
190
 
{
191
 
    DCELL min, max;
192
 
 
193
 
    if (colors->version < 0)
194
 
        return -1;              /* can't use this on 3.0 colors */
195
 
    min = colors->cmin;
196
 
    max = colors->cmax;
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 */
200
 
    colors->cmax = max;
201
 
 
202
 
    return 1;
203
 
}
204
 
 
205
 
/**
206
 
 * \brief Add modular color rule (FCELL version)
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
 
 *
214
 
 * \return -1 on failure
215
 
 * \return 1 on success
216
 
 */
217
 
int
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)
221
 
{
222
 
    DCELL min, max;
223
 
 
224
 
    if (colors->version < 0)
225
 
        return -1;              /* can;t use this on 3.0 colors */
226
 
    min = colors->cmin;
227
 
    max = colors->cmax;
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 */
231
 
    colors->cmax = max;
232
 
 
233
 
    return 1;
234
 
}
235
 
 
236
 
/**
237
 
 * \brief Add modular color rule (CCELL version)
238
 
 *
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
244
 
 *
245
 
 * \return -1 on failure
246
 
 * \return 1 on success
247
 
 */
248
 
int
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)
252
 
{
253
 
    return G_add_modular_color_rule(*val1, r1, g1, b1, *val2, r2, g2, b2,
254
 
                                    colors);
255
 
}
256
 
 
257
 
/**
258
 
 * \brief Add modular color rule
259
 
 *
260
 
 * Question: shouldn't this function call
261
 
 * G_add_modular_<data_type>_raster_color_rule() instead???
262
 
 *
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
269
 
 *
270
 
 * \return -1 on failure
271
 
 * \return 1 on success
272
 
 */
273
 
int
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)
278
 
{
279
 
    CELL min, max;
280
 
 
281
 
    if (colors->version < 0)
282
 
        return -1;              /* can't use this on 3.0 colors */
283
 
    min = colors->cmin;
284
 
    max = colors->cmax;
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 */
288
 
    colors->cmax = max;
289
 
 
290
 
    return 1;
291
 
}
292
 
 
293
 
/**
294
 
 * \brief Add modular color rule
295
 
 *
296
 
 * This function seems to be same as
297
 
 * G_add_modular_raster_color_rule(). Can be removed?
298
 
 *
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
305
 
 *
306
 
 * \return -1 on failure
307
 
 * \return 1 on success
308
 
 */
309
 
int
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)
312
 
{
313
 
    CELL min, max;
314
 
 
315
 
    if (colors->version < 0)
316
 
        return -1;              /* can;t use this on 3.0 colors */
317
 
    min = colors->cmin;
318
 
    max = colors->cmax;
319
 
    add_color_rule((void *)&cat1, r1, g1, b1, (void *)&cat2, r2, g2, b2,
320
 
                   &colors->modular, 0, &colors->cmin, &colors->cmax,
321
 
                   CELL_TYPE);
322
 
    colors->cmin = min;         /* don't reset these */
323
 
    colors->cmax = max;
324
 
 
325
 
    return 1;
326
 
}
327
 
 
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)
332
 
{
333
 
    struct _Color_Rule_ *rule, *next;
334
 
    unsigned char red, grn, blu;
335
 
    DCELL min, max, val1, val2;
336
 
    CELL cat;
337
 
 
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;
343
 
 
344
 
    /* make sure colors are in the range [0,255] */
345
 
    LIMIT(r1);
346
 
    LIMIT(g1);
347
 
    LIMIT(b1);
348
 
    LIMIT(r2);
349
 
    LIMIT(g2);
350
 
    LIMIT(b2);
351
 
 
352
 
    /* val1==val2, use average color */
353
 
    /* otherwise make sure low < high */
354
 
    if (val1 == val2) {
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;
359
 
    }
360
 
    else if (val1 < val2) {
361
 
        rule->low.value = val1;
362
 
        rule->low.red = r1;
363
 
        rule->low.grn = g1;
364
 
        rule->low.blu = b1;
365
 
 
366
 
        rule->high.value = val2;
367
 
        rule->high.red = r2;
368
 
        rule->high.grn = g2;
369
 
        rule->high.blu = b2;
370
 
    }
371
 
    else {
372
 
        rule->low.value = val2;
373
 
        rule->low.red = r2;
374
 
        rule->low.grn = g2;
375
 
        rule->low.blu = b2;
376
 
 
377
 
        rule->high.value = val1;
378
 
        rule->high.red = r1;
379
 
        rule->high.grn = g1;
380
 
        rule->high.blu = b1;
381
 
    }
382
 
 
383
 
    /* keep track of the overall min and max, excluding null */
384
 
    if (G_is_d_null_value(&(rule->low.value)))
385
 
        return 0;
386
 
    if (G_is_d_null_value(&(rule->high.value)))
387
 
        return 0;
388
 
    min = rule->low.value;
389
 
    max = rule->high.value;
390
 
    if (min <= max) {
391
 
        if (cp->min > cp->max) {
392
 
            cp->min = min;
393
 
            cp->max = max;
394
 
        }
395
 
        else {
396
 
            if (cp->min > min)
397
 
                cp->min = min;
398
 
            if (cp->max < max)
399
 
                cp->max = max;
400
 
        }
401
 
    }
402
 
    if (*cmin > *cmax) {
403
 
        *cmin = cp->min;
404
 
        *cmax = cp->max;
405
 
    }
406
 
    else {
407
 
        if (*cmin > cp->min)
408
 
            *cmin = cp->min;
409
 
        if (*cmax < cp->max)
410
 
            *cmax = cp->max;
411
 
    }
412
 
 
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
420
 
     */
421
 
 
422
 
    if (version < 0) {
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,
426
 
                                        cp);
427
 
        }
428
 
        G_free(rule);
429
 
    }
430
 
    else {
431
 
        if (cp->rules)
432
 
            cp->rules->prev = rule;
433
 
        rule->next = cp->rules;
434
 
        cp->rules = rule;
435
 
 
436
 
        /* prune the rules:
437
 
         * remove all rules that are contained by this rule 
438
 
         */
439
 
        min = rule->low.value;  /* mod 4.1 */
440
 
        max = rule->high.value; /* mod 4.1 */
441
 
        cp->n_rules++;
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;
447
 
                G_free(rule);
448
 
                cp->n_rules--;
449
 
            }
450
 
        }
451
 
 
452
 
        /* free lookup array, if allocated */
453
 
        G__color_free_lookup(cp);
454
 
        G__color_free_fp_lookup(cp);
455
 
    }
456
 
 
457
 
    return 0;
458
 
}