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

« back to all changes in this revision

Viewing changes to lib/raster/color_rules.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_read.c
 
3
  
 
4
  \brief Raster Library - Read and parse color rules file
 
5
  
 
6
  (C) 2007 by the GRASS Development Team
 
7
  
 
8
  This program is free software under the GNU General Public
 
9
  License (>=v2). Read the file COPYING that comes with GRASS
 
10
  for details.
 
11
  
 
12
  \author Glynn Clements
 
13
*/
 
14
 
 
15
#include <stdio.h>
 
16
 
 
17
#include <grass/gis.h>
 
18
#include <grass/raster.h>
 
19
#include <grass/glocale.h>
 
20
 
 
21
struct rule
 
22
{
 
23
    int set;
 
24
    int r, g, b;
 
25
    DCELL val;
 
26
};
 
27
 
 
28
enum rule_error
 
29
{
 
30
    CR_OK = 0,
 
31
    CR_ERROR_SYNTAX,
 
32
    CR_ERROR_RGB,
 
33
    CR_ERROR_COLOR,
 
34
    CR_ERROR_PERCENT,
 
35
    CR_ERROR_VALUE,
 
36
};
 
37
 
 
38
/*!
 
39
  \brief Read color rule
 
40
 
 
41
  \param min, max min & max values (used only when color rules are in percentage)
 
42
  \param buf
 
43
  \param val value
 
44
  \param[out] r,g,b color values
 
45
  \param norm
 
46
  \param nval
 
47
  \param dflt
 
48
 
 
49
  \return 0 on failure
 
50
  \return 1 on success
 
51
*/
 
52
int Rast_parse_color_rule(DCELL min, DCELL max, const char *buf,
 
53
                          DCELL * val, int *r, int *g, int *b,
 
54
                          int *norm, int *nval, int *dflt)
 
55
{
 
56
    char value[80], color[80];
 
57
    double x;
 
58
    char c;
 
59
 
 
60
    *norm = *nval = *dflt = 0;
 
61
 
 
62
    if (sscanf(buf, "%s %[^\n]", value, color) != 2)
 
63
        return CR_ERROR_SYNTAX;
 
64
 
 
65
    G_chop(color);
 
66
 
 
67
    if (sscanf(color, "%d:%d:%d", r, g, b) == 3 ||
 
68
        sscanf(color, "%d %d %d", r, g, b) == 3) {
 
69
        if (*r < 0 || *r > 255 || *g < 0 || *g > 255 || *b < 0 || *b > 255)
 
70
            return CR_ERROR_RGB;
 
71
    }
 
72
    else {
 
73
        float fr, fg, fb;
 
74
 
 
75
        if (G_color_values(color, &fr, &fg, &fb) < 0)
 
76
            return CR_ERROR_COLOR;
 
77
 
 
78
        *r = (int)(fr * 255.99);
 
79
        *g = (int)(fg * 255.99);
 
80
        *b = (int)(fb * 255.99);
 
81
    }
 
82
 
 
83
    G_chop(value);
 
84
 
 
85
    if (G_strcasecmp(value, "default") == 0) {
 
86
        *dflt = 1;
 
87
        return CR_OK;
 
88
    }
 
89
 
 
90
    if (G_strcasecmp(value, "nv") == 0) {
 
91
        *nval = 1;
 
92
        return CR_OK;
 
93
    }
 
94
 
 
95
    if (sscanf(value, "%lf%c", &x, &c) == 2 && c == '%') {
 
96
        if (x < 0 || x > 100)
 
97
            return CR_ERROR_PERCENT;
 
98
 
 
99
        *val = min + (max - min) * (x / 100);
 
100
        *norm = 1;
 
101
        return CR_OK;
 
102
    }
 
103
 
 
104
    if (sscanf(value, "%lf", val) == 1) {
 
105
        *norm = 1;
 
106
        return CR_OK;
 
107
    }
 
108
 
 
109
    return CR_ERROR_VALUE;
 
110
}
 
111
 
 
112
/*!
 
113
  \brief Parse color rule
 
114
 
 
115
  \param code
 
116
  
 
117
  \return pointer to buffer with error message
 
118
*/
 
119
const char *Rast_parse_color_rule_error(int code)
 
120
{
 
121
    switch (code) {
 
122
    case CR_OK:
 
123
        return "";
 
124
    case CR_ERROR_SYNTAX:
 
125
        return _("syntax error");
 
126
    case CR_ERROR_RGB:
 
127
        return _("R/G/B not in range 0-255");
 
128
    case CR_ERROR_COLOR:
 
129
        return _("invalid color name");
 
130
    case CR_ERROR_PERCENT:
 
131
        return _("percentage not in range 0-100");
 
132
    case CR_ERROR_VALUE:
 
133
        return _("invalid value");
 
134
    default:
 
135
        return _("unknown error");
 
136
    }
 
137
}
 
138
 
 
139
/*!
 
140
  \brief Read color rule
 
141
 
 
142
  \param closure
 
143
  \param min, max min & max values (used only when color rules are in percentage)
 
144
  \param val value
 
145
  \param[out] r,g,b color values
 
146
  \param norm
 
147
  \param nval
 
148
  \param dflt
 
149
 
 
150
  \return 0 on failure
 
151
  \return 1 on success
 
152
*/
 
153
int Rast_read_color_rule(void *closure, DCELL min, DCELL max,
 
154
                         DCELL * val, int *r, int *g, int *b,
 
155
                         int *norm, int *nval, int *dflt)
 
156
{
 
157
    char buf[1024];
 
158
    FILE *fp = closure;
 
159
    int ret;
 
160
 
 
161
    *norm = *nval = *dflt = 0;
 
162
 
 
163
    for (;;) {
 
164
        if (!G_getl2(buf, sizeof(buf), fp))
 
165
            return 0;
 
166
 
 
167
        G_strip(buf);
 
168
        G_debug(5, "color buf = [%s]", buf);
 
169
 
 
170
        if (*buf == '\0')
 
171
            continue;
 
172
        if (*buf == '#')
 
173
            continue;
 
174
 
 
175
        ret =
 
176
            Rast_parse_color_rule(min, max, buf, val, r, g, b, norm, nval,
 
177
                                  dflt);
 
178
        if (ret == 0)
 
179
            return 1;
 
180
 
 
181
        G_fatal_error(_("bad rule (%s): [%s]"),
 
182
                      Rast_parse_color_rule_error(ret), buf);
 
183
    }
 
184
 
 
185
    return 0;
 
186
}
 
187
 
 
188
/*!
 
189
  \brief Read color rules from file
 
190
  
 
191
  \param[out] colors pointer to Colors structure
 
192
  \param min, max min & max values (used only when color rules are in percentage)
 
193
  \param read_rule pointer to read_rule_fn structure
 
194
  \param closure 
 
195
 
 
196
  \return 0 on failure
 
197
  \return 1 on success
 
198
*/
 
199
int Rast_read_color_rules(struct Colors *colors, DCELL min, DCELL max,
 
200
                          read_rule_fn * read_rule, void *closure)
 
201
{
 
202
    struct rule *rule = NULL;
 
203
    int nrules = 0;
 
204
    struct rule dflt, null;
 
205
    int set, is_null, is_dflt, r, g, b;
 
206
    DCELL val;
 
207
    int n;
 
208
 
 
209
    if (!read_rule)
 
210
        read_rule = Rast_read_color_rule;
 
211
 
 
212
    Rast_init_colors(colors);
 
213
 
 
214
    /* initialization */
 
215
    dflt.r = dflt.g = dflt.b = dflt.set = 0;
 
216
    null.r = null.g = null.b = null.set = 0;
 
217
 
 
218
    while ((*read_rule)
 
219
           (closure, min, max, &val, &r, &g, &b, &set, &is_null, &is_dflt)) {
 
220
        struct rule *p;
 
221
 
 
222
        if (set) {
 
223
            n = nrules++;
 
224
            rule = G_realloc(rule, nrules * sizeof(struct rule));
 
225
            p = &rule[n];
 
226
        }
 
227
        else if (is_dflt)
 
228
            p = &dflt;
 
229
        else if (is_null)
 
230
            p = &null;
 
231
 
 
232
        p->r = r;
 
233
        p->g = g;
 
234
        p->b = b;
 
235
        p->set = 1;
 
236
        p->val = val;
 
237
    }
 
238
 
 
239
    if (nrules == 0)
 
240
        return 0;
 
241
 
 
242
    if (nrules == 1) {
 
243
        const struct rule *p = &rule[0];
 
244
 
 
245
        Rast_set_d_color(p->val, p->r, p->g, p->b, colors);
 
246
    }
 
247
 
 
248
    for (n = 1; n < nrules; n++) {
 
249
        struct rule *lo = &rule[n - 1];
 
250
        struct rule *hi = &rule[n];
 
251
 
 
252
        Rast_add_d_color_rule(&lo->val, lo->r, lo->g, lo->b,
 
253
                              &hi->val, hi->r, hi->g, hi->b, colors);
 
254
    }
 
255
 
 
256
    G_free(rule);
 
257
 
 
258
    /* null value and default color set up, if rules are set up by user */
 
259
    if (null.set)
 
260
        Rast_set_null_value_color(null.r, null.g, null.b, colors);
 
261
 
 
262
    if (dflt.set)
 
263
        Rast_set_default_color(dflt.r, dflt.g, dflt.b, colors);
 
264
 
 
265
    return 1;
 
266
}
 
267
 
 
268
static int load_rules_file(struct Colors *colors, const char *path, DCELL min,
 
269
                           DCELL max)
 
270
{
 
271
    FILE *fp;
 
272
    int ret;
 
273
 
 
274
    fp = fopen(path, "r");
 
275
 
 
276
    if (!fp)
 
277
        return 0;
 
278
 
 
279
    ret =
 
280
        Rast_read_color_rules(colors, min, max, Rast_read_color_rule,
 
281
                              (void *)fp);
 
282
 
 
283
    fclose(fp);
 
284
 
 
285
    return ret;
 
286
}
 
287
 
 
288
/*!
 
289
  \brief Load color rules from file
 
290
  
 
291
  \param[out] colors pointer to Colors structure
 
292
  \param path path to the color rules file
 
293
  \param min, max min & max values (used only when color rules are in percentage)
 
294
 
 
295
  \return 0 on failure
 
296
  \return 1 on success
 
297
*/
 
298
int Rast_load_colors(struct Colors *colors, const char *path, CELL min,
 
299
                     CELL max)
 
300
{
 
301
    return load_rules_file(colors, path, (DCELL) min, (DCELL) max);
 
302
}
 
303
 
 
304
/*!
 
305
  \brief Load color floating-point rules from file
 
306
  
 
307
  \param[out] colors pointer to Colors structure
 
308
  \param path path to the color rules file
 
309
  \param min, max min & max values (used only when color rules are in percentage)
 
310
 
 
311
  \return 0 on failure
 
312
  \return 1 on success
 
313
*/
 
314
int Rast_load_fp_colors(struct Colors *colors, const char *path, DCELL min,
 
315
                        DCELL max)
 
316
{
 
317
    return load_rules_file(colors, path, min, max);
 
318
}
 
319
 
 
320
static void load_rules_name(struct Colors *colors, const char *name,
 
321
                            DCELL min, DCELL max)
 
322
{
 
323
    char path[GPATH_MAX];
 
324
 
 
325
    sprintf(path, "%s/etc/colors/%s", G_gisbase(), name);
 
326
 
 
327
    if (!load_rules_file(colors, path, min, max))
 
328
        G_fatal_error(_("Unable to load color rules <%s>"), name);
 
329
}
 
330
 
 
331
/*!
 
332
  \brief Load color rules from predefined color table
 
333
 
 
334
  \param[out] colors pointer to Colors structure
 
335
  \param name name of color table to load
 
336
  \param min, max min & max values (used only when color rules are in percentage)
 
337
*/
 
338
void Rast_make_colors(struct Colors *colors, const char *name, CELL min,
 
339
                      CELL max)
 
340
{
 
341
    return load_rules_name(colors, name, (DCELL) min, (DCELL) max);
 
342
}
 
343
 
 
344
/*!
 
345
  \brief Load color rules from predefined floating-point color table
 
346
 
 
347
  \param[out] colors pointer to Colors structure
 
348
  \param name name of color table to load
 
349
  \param min, max min & max values (used only when color rules are in percentage)
 
350
*/
 
351
void Rast_make_fp_colors(struct Colors *colors, const char *name, DCELL min,
 
352
                         DCELL max)
 
353
{
 
354
    return load_rules_name(colors, name, min, max);
 
355
}