~ubuntu-branches/ubuntu/vivid/grass/vivid-proposed

« back to all changes in this revision

Viewing changes to lib/raster/color_rule.c

  • Committer: Package Import Robot
  • Author(s): Bas Couwenberg
  • Date: 2015-02-20 23:12:08 UTC
  • mfrom: (8.2.6 experimental)
  • Revision ID: package-import@ubuntu.com-20150220231208-1u6qvqm84v430b10
Tags: 7.0.0-1~exp1
* New upstream release.
* Update python-ctypes-ternary.patch to use if/else instead of and/or.
* Drop check4dev patch, rely on upstream check.
* Add build dependency on libpq-dev to grass-dev for libpq-fe.h.
* Drop patches applied upstream, refresh remaining patches.
* Update symlinks for images switched from jpg to png.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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) if (x < 0) x = 0; else if (x > 255) x = 255;
 
18
 
 
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);
 
23
 
 
24
/*!
 
25
  \brief Adds the floating-point color rule (DCELL version)
 
26
  
 
27
  See Rast_add_color_rule() for details.
 
28
  
 
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
 
34
*/
 
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)
 
38
{
 
39
    add_color_rule(val1, r1, g1, b1, val2, r2, g2, b2, &colors->fixed,
 
40
                   colors->version, &colors->cmin, &colors->cmax, DCELL_TYPE);
 
41
}
 
42
 
 
43
 
 
44
/*!
 
45
  \brief Adds the floating-point color rule (FCELL version)
 
46
  
 
47
  See Rast_add_color_rule() for details.
 
48
  
 
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
 
54
*/
 
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)
 
58
{
 
59
    add_color_rule(cat1, r1, g1, b1, cat2, r2, g2, b2, &colors->fixed,
 
60
                   colors->version, &colors->cmin, &colors->cmax, FCELL_TYPE);
 
61
}
 
62
 
 
63
 
 
64
/*!
 
65
  \brief Adds the integer color rule (CELL version)
 
66
  
 
67
  See Rast_add_color_rule() for details.
 
68
  
 
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
 
74
*/
 
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)
 
78
{
 
79
    add_color_rule(cat1, r1, g1, b1, cat2, r2, g2, b2, &colors->fixed,
 
80
                   colors->version, &colors->cmin, &colors->cmax, CELL_TYPE);
 
81
}
 
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 converted ino
 
91
  <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 */
 
362
        Rast__color_free_lookup(cp);
 
363
        Rast__color_free_fp_lookup(cp);
 
364
    }
 
365
}