GRASS 8 Programmer's Manual 8.6.0dev(2026)-745b61fbf6
Loading...
Searching...
No Matches
raster/color_rules.c
Go to the documentation of this file.
1/*!
2 \file lib/raster/color_rules.c
3
4 \brief Raster Library - Read and parse color rules file
5
6 SPDX-FileCopyrightText: 2007-2016 GRASS Development Team
7 SPDX-License-Identifier: GPL-2.0-or-later
8
9 \author Glynn Clements
10 */
11
12#include <stdio.h>
13
14#include <grass/gis.h>
15#include <grass/colors.h>
16#include <grass/raster.h>
17#include <grass/glocale.h>
18
19struct rule {
20 int set;
21 int r, g, b;
22 DCELL val;
23};
24
32
33/*!
34 \brief Read color rule
35
36 The val output parameter is always an absolute value and is derived
37 from the rule and the min and max values in case the rule is in percents.
38
39 Always only one of the norm, nval, and dflt output parameters is set
40 to non-zero value, the others are set to zero.
41
42 The return code can be translated to an error message using
43 the Rast_parse_color_rule_error() function.
44
45 \param min, max min & max values (used only when color rules are in
46 percentage) \param buf string with the color rule \param[out] val value which
47 the color is assigned to \param[out] r,g,b color values \param[out] norm set
48 to non-zero value if the value and color are set \param[out] nval set to
49 non-zero value if rule is for null value \param[out] dflt set to non-zero
50 value if rule specifies the default color
51
52 \returns enum rule_error values (non-zero on failure)
53 */
54int Rast_parse_color_rule(DCELL min, DCELL max, const char *buf, DCELL *val,
55 int *r, int *g, int *b, int *norm, int *nval,
56 int *dflt)
57{
58 char value[80], color[80];
59 double x;
60 char c;
61
62 *norm = *nval = *dflt = 0;
63
64 if (sscanf(buf, "%s %[^\n]", value, color) != 2)
66
67 /* we don't allow 'none' color here (ret == 2) */
68 /* G_str_to_color chops and has only 1 error state */
69 if (G_str_to_color(color, r, g, b) != 1)
71
72 G_chop(value);
73
74 if (G_strcasecmp(value, "default") == 0) {
75 *dflt = 1;
76 return CR_OK;
77 }
78
79 if (G_strcasecmp(value, "nv") == 0) {
80 *nval = 1;
81 return CR_OK;
82 }
83
84 if (sscanf(value, "%lf%c", &x, &c) == 2 && c == '%') {
85 if (x < 0 || x > 100)
86 return CR_ERROR_PERCENT;
87
88 *val = min + (max - min) * (x / 100);
89 *norm = 1;
90 return CR_OK;
91 }
92
93 if (sscanf(value, "%lf", val) == 1) {
94 *norm = 1;
95 return CR_OK;
96 }
97
98 return CR_ERROR_VALUE;
99}
100
101/*!
102 \brief Parse color rule
103
104 \param code
105
106 \return pointer to buffer with error message
107 */
108const char *Rast_parse_color_rule_error(int code)
109{
110 switch (code) {
111 case CR_OK:
112 return "";
114 return _("syntax error in the color rule");
116 return _("syntax error in the color format");
117 /* we no longer distinguish between these two errors
118 case CR_ERROR_RGB:
119 return _("R/G/B not in range 0-255");
120 case CR_ERROR_COLOR:
121 return _("invalid color name");
122 */
123 case CR_ERROR_PERCENT:
124 return _("percentage not in range 0-100");
125 case CR_ERROR_VALUE:
126 return _("invalid value");
127 default:
128 return _("unknown error");
129 }
130}
131
132/*!
133 \brief Read color rule
134
135 \param closure
136 \param min, max min & max values (used only when color rules are in
137 percentage) \param val value \param[out] r,g,b color values \param norm
138 \param nval
139 \param dflt
140
141 \return 0 on failure
142 \return 1 on success
143 */
144int Rast_read_color_rule(void *closure, DCELL min, DCELL max, DCELL *val,
145 int *r, int *g, int *b, int *norm, int *nval,
146 int *dflt)
147{
148 char buf[1024];
149 FILE *fp = closure;
150 int ret;
151
152 *norm = *nval = *dflt = 0;
153
154 for (;;) {
155 if (!G_getl2(buf, sizeof(buf), fp))
156 return 0;
157
158 G_strip(buf);
159 G_debug(5, "color buf = [%s]", buf);
160
161 if (*buf == '\0')
162 continue;
163 if (*buf == '#')
164 continue;
165
166 ret = Rast_parse_color_rule(min, max, buf, val, r, g, b, norm, nval,
167 dflt);
168 if (ret == 0)
169 return 1;
170
171 G_fatal_error(_("bad rule (%s): [%s]"),
173 }
174
175 return 0;
176}
177
178/*!
179 \brief Read color rules from file
180
181 \param[out] colors pointer to Colors structure
182 \param min, max min & max values (used only when color rules are in
183 percentage) \param read_rule pointer to read_rule_fn structure \param closure
184
185 \return 0 on failure
186 \return 1 on success
187 */
189 read_rule_fn *read_rule, void *closure)
190{
191 struct rule *rule = NULL;
192 int nrules = 0;
193 struct rule dflt, null;
194 int set, is_null, is_dflt, r, g, b;
195 DCELL val;
196 int n;
197
198 if (!read_rule)
200
201 Rast_init_colors(colors);
202
203 /* initialization */
204 dflt.r = dflt.g = dflt.b = dflt.set = 0;
205 null.r = null.g = null.b = null.set = 0;
206
207 while ((*read_rule)(closure, min, max, &val, &r, &g, &b, &set, &is_null,
208 &is_dflt)) {
209 struct rule *p = NULL;
210
211 if (set) {
212 n = nrules++;
213 rule = G_realloc(rule, nrules * sizeof(struct rule));
214 p = &rule[n];
215 }
216 else if (is_dflt)
217 p = &dflt;
218 else if (is_null)
219 p = &null;
220
221 if (!p)
222 G_fatal_error(_("Unknown error reading color rule"));
223
224 p->r = r;
225 p->g = g;
226 p->b = b;
227 p->set = 1;
228 p->val = val;
229 }
230
231 if (nrules == 0)
232 return 0;
233
234 if (nrules == 1) {
235 const struct rule *p = &rule[0];
236
237 Rast_set_d_color(p->val, p->r, p->g, p->b, colors);
238 }
239
240 for (n = 1; n < nrules; n++) {
241 struct rule *lo = &rule[n - 1];
242 struct rule *hi = &rule[n];
243
244 Rast_add_d_color_rule(&lo->val, lo->r, lo->g, lo->b, &hi->val, hi->r,
245 hi->g, hi->b, colors);
246 }
247
248 G_free(rule);
249
250 /* null value and default color set up, if rules are set up by user */
251 if (null.set)
252 Rast_set_null_value_color(null.r, null.g, null.b, colors);
253
254 if (dflt.set)
255 Rast_set_default_color(dflt.r, dflt.g, dflt.b, colors);
256
257 return 1;
258}
259
260static int load_rules_file(struct Colors *colors, const char *path, DCELL min,
261 DCELL max)
262{
263 FILE *fp;
264 int ret;
265
266 fp = fopen(path, "r");
267
268 if (!fp)
269 return 0;
270
272 (void *)fp);
273
274 fclose(fp);
275
276 return ret;
277}
278
279/*!
280 \brief Load color rules from file
281
282 \param[out] colors pointer to Colors structure
283 \param path path to the color rules file
284 \param min, max min & max values (used only when color rules are in
285 percentage)
286
287 \return 0 on failure
288 \return 1 on success
289 */
290int Rast_load_colors(struct Colors *colors, const char *path, CELL min,
291 CELL max)
292{
293 return load_rules_file(colors, path, (DCELL)min, (DCELL)max);
294}
295
296/*!
297 \brief Load color floating-point rules from file
298
299 \param[out] colors pointer to Colors structure
300 \param path path to the color rules file
301 \param min, max min & max values (used only when color rules are in
302 percentage)
303
304 \return 0 on failure
305 \return 1 on success
306 */
307int Rast_load_fp_colors(struct Colors *colors, const char *path, DCELL min,
308 DCELL max)
309{
310 return load_rules_file(colors, path, min, max);
311}
312
313static void load_rules_name(struct Colors *colors, const char *name, DCELL min,
314 DCELL max)
315{
316 char path[GPATH_MAX];
317
318 snprintf(path, sizeof(path), "%s/etc/colors/%s", G_gisbase(), name);
319
320 if (!load_rules_file(colors, path, min, max))
321 G_fatal_error(_("Unable to load color rules <%s>"), name);
322}
323
324/*!
325 \brief Load color rules from predefined color table
326
327 \param[out] colors pointer to Colors structure
328 \param name name of color table to load
329 \param min, max min & max values (used only when color rules are in
330 percentage)
331 */
332void Rast_make_colors(struct Colors *colors, const char *name, CELL min,
333 CELL max)
334{
335 load_rules_name(colors, name, (DCELL)min, (DCELL)max);
336}
337
338/*!
339 \brief Load color rules from predefined floating-point color table
340
341 \param[out] colors pointer to Colors structure
342 \param name name of color table to load
343 \param min, max min & max values (used only when color rules are in
344 percentage)
345 */
346void Rast_make_fp_colors(struct Colors *colors, const char *name, DCELL min,
347 DCELL max)
348{
349 load_rules_name(colors, name, min, max);
350}
#define NULL
Definition ccmath.h:32
int G_str_to_color(const char *, int *, int *, int *)
Parse color string and set red,green,blue.
Definition color_str.c:99
int G_getl2(char *, int, FILE *)
Gets a line of text from a file of any pedigree.
Definition getl.c:58
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:145
#define G_realloc(p, n)
Definition defs/gis.h:138
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
const char * G_gisbase(void)
Get full path name of the top level module directory.
Definition gisbase.c:39
void G_strip(char *)
Removes all leading and trailing white space from string.
Definition strings.c:298
int int G_strcasecmp(const char *, const char *)
String compare ignoring case (upper or lower)
Definition strings.c:45
char * G_chop(char *)
Chop leading and trailing white spaces.
Definition strings.c:330
int G_debug(int, const char *,...) __attribute__((format(printf
void Rast_add_d_color_rule(const DCELL *, int, int, int, const DCELL *, int, int, int, struct Colors *)
Adds the floating-point color rule (DCELL version)
Definition color_rule.c:36
void Rast_set_null_value_color(int, int, int, struct Colors *)
Set color for NULL-value.
Definition color_set.c:77
int read_rule_fn(void *, DCELL, DCELL, DCELL *, int *, int *, int *, int *, int *, int *)
void Rast_set_d_color(DCELL, int, int, int, struct Colors *)
Set a category color (DCELL)
Definition color_set.c:58
void Rast_init_colors(struct Colors *)
Initialize color structure.
Definition color_init.c:23
void Rast_set_default_color(int, int, int, struct Colors *)
Set default color value.
Definition color_set.c:97
#define min(x, y)
Definition draw2.c:29
#define max(x, y)
Definition draw2.c:30
#define GPATH_MAX
Definition gis.h:196
double DCELL
Definition gis.h:632
int CELL
Definition gis.h:631
#define _(str)
Definition glocale.h:10
float g
Definition named_colr.c:7
const char * name
Definition named_colr.c:6
double b
Definition r_raster.c:37
double r
Definition r_raster.c:37
int Rast_load_colors(struct Colors *colors, const char *path, CELL min, CELL max)
Load color rules from file.
int Rast_read_color_rule(void *closure, DCELL min, DCELL max, DCELL *val, int *r, int *g, int *b, int *norm, int *nval, int *dflt)
Read color rule.
int Rast_read_color_rules(struct Colors *colors, DCELL min, DCELL max, read_rule_fn *read_rule, void *closure)
Read color rules from file.
void Rast_make_fp_colors(struct Colors *colors, const char *name, DCELL min, DCELL max)
Load color rules from predefined floating-point color table.
int Rast_parse_color_rule(DCELL min, DCELL max, const char *buf, DCELL *val, int *r, int *g, int *b, int *norm, int *nval, int *dflt)
Read color rule.
const char * Rast_parse_color_rule_error(int code)
Parse color rule.
@ CR_ERROR_COLOR_SYNTAX
@ CR_ERROR_VALUE
@ CR_ERROR_PERCENT
@ CR_ERROR_RULE_SYNTAX
void Rast_make_colors(struct Colors *colors, const char *name, CELL min, CELL max)
Load color rules from predefined color table.
int Rast_load_fp_colors(struct Colors *colors, const char *path, DCELL min, DCELL max)
Load color floating-point rules from file.
Definition gis.h:689
Definition path.h:15
#define x