GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
gis/color_rules.c
Go to the documentation of this file.
1/*!
2 \file lib/gis/color_rules.c
3
4 \brief GIS Library - Color tables management subroutines
5
6 Taken from r.colors module.
7
8 (C) 2001-2011 by the GRASS Development Team
9 */
10
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14
15#include <grass/gis.h>
16#include <grass/glocale.h>
17
18struct colorinfo {
19 char *name;
20 char *desc;
21 char *type;
22};
23
24static struct colorinfo *get_colorinfo(int *);
25static void free_colorinfo(struct colorinfo *, int);
26
27static int cmp_clrname(const void *a, const void *b)
28{
29 struct colorinfo *ca = (struct colorinfo *)a;
30 struct colorinfo *cb = (struct colorinfo *)b;
31
32 return (strcmp(ca->name, cb->name));
33}
34
35/*!
36 \brief Get list of color rules for Option->options
37
38 \return allocated string buffer with options
39 */
41{
42 char *list;
43 const char *name;
44 int size, len, nrules;
45 int i, n;
46 struct colorinfo *colorinfo;
47
48 list = NULL;
49 size = len = 0;
50
51 colorinfo = get_colorinfo(&nrules);
52
53 for (i = 0; i < nrules; i++) {
54 name = colorinfo[i].name;
55 n = strlen(name);
56
57 if (size < len + n + 2) {
58 size = len + n + 200;
59 list = G_realloc(list, size);
60 }
61
62 if (len > 0)
63 list[len++] = ',';
64
65 memcpy(&list[len], name, n + 1);
66 len += n;
67 }
68
69 free_colorinfo(colorinfo, nrules);
70
71 return list;
72}
73
74/*!
75 \brief Get color rules description for Option->descriptions
76
77 \return allocated buffer with descriptions
78 */
80{
82 char *result;
83 const char *name, *desc;
84 int i, len, nrules;
85 struct colorinfo *colorinfo;
86
87 result_len = 0;
88 result_max = 2000;
89 result = G_malloc(result_max);
90
91 colorinfo = get_colorinfo(&nrules);
92
93 for (i = 0; i < nrules; i++) {
94 name = colorinfo[i].name;
95 desc = colorinfo[i].desc;
96
97 if (!desc)
98 desc = _("no description");
99
100 /* desc = _(desc); */
101
102 len = strlen(name) + strlen(desc) + 2;
103 if (result_len + len >= result_max) {
104 result_max = result_len + len + 1000;
105 result = G_realloc(result, result_max);
106 }
107
108 sprintf(result + result_len, "%s;%s;", name, desc);
109 result_len += len;
110 }
111
112 free_colorinfo(colorinfo, nrules);
113
114 return result;
115}
116
117/*!
118 \brief Get color rules description for Option->descriptions
119
120 The type of color rule including range is appended to the description
121
122 \return allocated buffer with name, description, and type
123 */
125{
126 int i, len, nrules;
127 struct colorinfo *colorinfo;
128 const char *name, *desc, *type;
130 char *result;
131
132 colorinfo = get_colorinfo(&nrules);
133
134 result_len = 0;
135 result_max = 2000;
136 result = G_malloc(result_max);
137
138 for (i = 0; i < nrules; i++) {
139 name = colorinfo[i].name;
140 desc = colorinfo[i].desc;
141 type = colorinfo[i].type;
142
143 if (desc) {
144 len = strlen(name) + strlen(desc) + strlen(type) + 5;
145 if (result_len + len >= result_max) {
146 result_max = result_len + len + 1000;
147 result = G_realloc(result, result_max);
148 }
149
150 sprintf(result + result_len, "%s;%s [%s];", name, desc, type);
151 result_len += len;
152 }
153 else {
154 len = strlen(name) + strlen(type) + 5;
155 if (result_len + len >= result_max) {
156 result_max = result_len + len + 1000;
157 result = G_realloc(result, result_max);
158 }
159
160 sprintf(result + result_len, "%s; [%s];", name, type);
161 result_len += len;
162 }
163 }
164
165 free_colorinfo(colorinfo, nrules);
166
167 return result;
168}
169
170/*!
171 \brief Print color rules
172
173 \param out file where to print
174 */
176{
177 int i, nrules;
178 struct colorinfo *colorinfo;
179
180 colorinfo = get_colorinfo(&nrules);
181
182 for (i = 0; i < nrules; i++)
183 fprintf(out, "%s\n", colorinfo[i].name);
184
185 free_colorinfo(colorinfo, nrules);
186}
187
188/*!
189 \brief Print color rules with description and type
190
191 The type of color rule including range is appended to the description.
192 If a color rule name is given, color info is printed only for this
193 rule.
194
195 \param name optional color rule name, or NULL
196 \param out file where to print
197 */
199{
200 int i, nrules;
201 struct colorinfo *colorinfo, csearch, *cfound;
202
203 colorinfo = get_colorinfo(&nrules);
204
205 cfound = NULL;
206 if (name) {
207 csearch.name = name;
208 cfound = bsearch(&csearch, colorinfo, nrules, sizeof(struct colorinfo),
209 cmp_clrname);
210
211 if (cfound) {
212 if (cfound->desc) {
213 fprintf(out, "%s: %s [%s]\n", cfound->name, cfound->desc,
214 cfound->type);
215 }
216 else {
217 fprintf(out, "%s: [%s]\n", cfound->name, cfound->type);
218 }
219 }
220 }
221
222 if (cfound == NULL) {
223 for (i = 0; i < nrules; i++) {
224 if (colorinfo[i].desc) {
225 fprintf(out, "%s: %s [%s]\n", colorinfo[i].name,
226 colorinfo[i].desc, colorinfo[i].type);
227 }
228 else {
229 fprintf(out, "%s: [%s]\n", colorinfo[i].name,
230 colorinfo[i].type);
231 }
232 }
233 }
234
235 free_colorinfo(colorinfo, nrules);
236}
237
238/*!
239 \brief Check if color rule is defined
240
241 \param name color rule name
242
243 \return 1 found
244 \return 0 not found
245 */
246int G_find_color_rule(const char *name)
247{
248 int result, nrules;
249 struct colorinfo *colorinfo, csearch;
250
251 colorinfo = get_colorinfo(&nrules);
252
253 csearch.name = (char *)name;
254 result = (bsearch(&csearch, colorinfo, nrules, sizeof(struct colorinfo),
255 cmp_clrname) != NULL);
256
257 free_colorinfo(colorinfo, nrules);
258
259 return result;
260}
261
262struct colorinfo *get_colorinfo(int *nrules)
263{
264 int i;
265 char path[GPATH_MAX];
266 FILE *fp;
267 struct colorinfo *colorinfo;
268 char **cnames;
269
270 /* load color rules */
271 snprintf(path, GPATH_MAX, "%s/etc/colors", G_gisbase());
272
273 *nrules = 0;
275 (*nrules) += 3;
276 colorinfo = G_malloc(*nrules * sizeof(struct colorinfo));
277 for (i = 0; i < *nrules - 3; i++) {
278 char buf[1024];
279 double rmin, rmax;
280 int first;
281 int cisperc;
282
283 colorinfo[i].name = G_store(cnames[i]);
284 colorinfo[i].desc = NULL;
285
286 /* open color rule file */
287 snprintf(path, GPATH_MAX, "%s/etc/colors/%s", G_gisbase(),
288 colorinfo[i].name);
289 fp = fopen(path, "r");
290 if (!fp)
291 G_fatal_error(_("Unable to open color rule"));
292
293 /* scan all lines */
294 first = 1;
295 rmin = rmax = 0;
296 cisperc = 0;
297 while (G_getl2(buf, sizeof(buf), fp)) {
298 char value[80], color[80];
299 double x;
300 char c;
301
302 G_strip(buf);
303
304 if (*buf == '\0')
305 continue;
306 if (*buf == '#')
307 continue;
308
309 if (sscanf(buf, "%s %[^\n]", value, color) != 2)
310 continue;
311
312 if (G_strcasecmp(value, "default") == 0) {
313 continue;
314 }
315
316 if (G_strcasecmp(value, "nv") == 0) {
317 continue;
318 }
319
320 if (sscanf(value, "%lf%c", &x, &c) == 2 && c == '%') {
321 cisperc = 1;
322 break;
323 }
324 if (sscanf(value, "%lf", &x) == 1) {
325 if (first) {
326 first = 0;
327 rmin = rmax = x;
328 }
329 else {
330 if (rmin > x)
331 rmin = x;
332 if (rmax < x)
333 rmax = x;
334 }
335 }
336 }
337 fclose(fp);
338
339 if (cisperc)
340 colorinfo[i].type = G_store(_("range: map values"));
341 else {
342 snprintf(buf, sizeof(buf) - 1, _("range: %g to %g"), rmin, rmax);
343 colorinfo[i].type = G_store(buf);
344 }
345 }
346 G_free(cnames);
347
348 /* colors without rules but description */
349 colorinfo[*nrules - 3].name = G_store("random");
350 colorinfo[*nrules - 3].desc = NULL;
351 colorinfo[*nrules - 3].type = G_store(_("range: map values"));
352
353 colorinfo[*nrules - 2].name = G_store("grey.eq");
354 colorinfo[*nrules - 2].desc = NULL;
355 colorinfo[*nrules - 2].type = G_store(_("range: map values"));
356
357 colorinfo[*nrules - 1].name = G_store("grey.log");
358 colorinfo[*nrules - 1].desc = NULL;
359 colorinfo[*nrules - 1].type = G_store(_("range: map values"));
360
361 qsort(colorinfo, *nrules, sizeof(struct colorinfo), cmp_clrname);
362
363 /* load color descriptions */
364 snprintf(path, GPATH_MAX, "%s/etc/colors.desc", G_gisbase());
365 fp = fopen(path, "r");
366 if (!fp)
367 G_fatal_error(_("Unable to open color descriptions"));
368
369 for (;;) {
370 char buf[1024];
371 char tok_buf[1024];
372 char *cname, *cdesc;
373 int ntokens;
374 char **tokens;
375 struct colorinfo csearch, *cfound;
376
377 if (!G_getl2(buf, sizeof(buf), fp))
378 break;
379 strcpy(tok_buf, buf);
380 tokens = G_tokenize(tok_buf, ":");
382 if (ntokens != 2)
383 continue;
384
385 cname = G_chop(tokens[0]);
386 cdesc = G_chop(tokens[1]);
387
389 cfound = bsearch(&csearch, colorinfo, *nrules, sizeof(struct colorinfo),
390 cmp_clrname);
391
392 if (cfound) {
393 cfound->desc = G_store(cdesc);
394 }
396 }
397 fclose(fp);
398
399 return colorinfo;
400}
401
402void free_colorinfo(struct colorinfo *colorinfo, int nrules)
403{
404 int i;
405
406 for (i = 0; i < nrules; i++) {
407 if (colorinfo[i].name)
408 G_free(colorinfo[i].name);
409 if (colorinfo[i].desc)
410 G_free(colorinfo[i].desc);
411 if (colorinfo[i].type)
412 G_free(colorinfo[i].type);
413 }
414 if (nrules > 0)
415 G_free(colorinfo);
416}
struct cairo_state ca
#define NULL
Definition ccmath.h:32
AMI_err name(char **stream_name)
Definition ami_stream.h:426
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
#define G_malloc(n)
Definition defs/gis.h:139
char ** G_tokenize(const char *, const char *)
Tokenize string.
Definition gis/token.c:47
void G_free_tokens(char **)
Free memory allocated to tokens.
Definition gis/token.c:197
void G_strip(char *)
Removes all leading and trailing white space from string.
Definition strings.c:300
int G_number_of_tokens(char **)
Return number of tokens.
Definition gis/token.c:178
char ** G_ls2(const char *, int *)
Stores a sorted directory listing in an array.
Definition ls.c:94
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
char * G_store(const char *)
Copy string to allocated memory.
Definition strings.c:87
char * G_color_rules_description_type(void)
Get color rules description for Option->descriptions.
char * G_color_rules_descriptions(void)
Get color rules description for Option->descriptions.
void G_list_color_rules(FILE *out)
Print color rules.
void G_list_color_rules_description_type(FILE *out, char *name)
Print color rules with description and type.
int G_find_color_rule(const char *name)
Check if color rule is defined.
char * G_color_rules_options(void)
Get list of color rules for Option->options.
#define GPATH_MAX
Definition gis.h:199
#define _(str)
Definition glocale.h:10
const char * name
Definition named_colr.c:6
#define strcpy
Definition parson.c:66
double b
Definition r_raster.c:39
Definition manage.h:4
Definition path.h:15
#define x