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