Loading...
Searching...
No Matches
color_rules.c
Go to the documentation of this file.
/*!
\file lib/gis/color_rules.c
\brief GIS Library - Color tables management subroutines
Taken from r.colors module.
(C) 2001-2011 by the GRASS Development Team
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <grass/gis.h>
#include <grass/glocale.h>
struct colorinfo {
char *name;
char *desc;
char *type;
};
static struct colorinfo *get_colorinfo(int *);
static void free_colorinfo(struct colorinfo *, int);
static int cmp_clrname(const void *a, const void *b)
{
struct colorinfo *ca = (struct colorinfo *)a;
struct colorinfo *cb = (struct colorinfo *)b;
return (strcmp(ca->name, cb->name));
}
/*!
\brief Get list of color rules for Option->options
\return allocated string buffer with options
*/
char *G_color_rules_options(void)
{
char *list;
const char *name;
int size, len, nrules;
int i, n;
struct colorinfo *colorinfo;
list = NULL;
size = len = 0;
colorinfo = get_colorinfo(&nrules);
for (i = 0; i < nrules; i++) {
name = colorinfo[i].name;
n = strlen(name);
if (size < len + n + 2) {
size = len + n + 200;
list = G_realloc(list, size);
}
if (len > 0)
list[len++] = ',';
memcpy(&list[len], name, n + 1);
len += n;
}
free_colorinfo(colorinfo, nrules);
return list;
}
/*!
\brief Get color rules description for Option->descriptions
\return allocated buffer with descriptions
*/
char *G_color_rules_descriptions(void)
{
int result_len, result_max;
char *result;
const char *name, *desc;
int i, len, nrules;
struct colorinfo *colorinfo;
result_len = 0;
result_max = 2000;
result = G_malloc(result_max);
colorinfo = get_colorinfo(&nrules);
for (i = 0; i < nrules; i++) {
name = colorinfo[i].name;
desc = colorinfo[i].desc;
if (!desc)
desc = _("no description");
/* desc = _(desc); */
len = strlen(name) + strlen(desc) + 2;
if (result_len + len >= result_max) {
result_max = result_len + len + 1000;
result = G_realloc(result, result_max);
}
sprintf(result + result_len, "%s;%s;", name, desc);
result_len += len;
}
free_colorinfo(colorinfo, nrules);
return result;
}
/*!
\brief Get color rules description for Option->descriptions
The type of color rule including range is appended to the description
\return allocated buffer with name, description, and type
*/
char *G_color_rules_description_type(void)
{
int i, len, nrules;
struct colorinfo *colorinfo;
const char *name, *desc, *type;
int result_len, result_max;
char *result;
colorinfo = get_colorinfo(&nrules);
result_len = 0;
result_max = 2000;
result = G_malloc(result_max);
for (i = 0; i < nrules; i++) {
name = colorinfo[i].name;
desc = colorinfo[i].desc;
type = colorinfo[i].type;
if (desc) {
len = strlen(name) + strlen(desc) + strlen(type) + 5;
if (result_len + len >= result_max) {
result_max = result_len + len + 1000;
result = G_realloc(result, result_max);
}
sprintf(result + result_len, "%s;%s [%s];", name, desc, type);
result_len += len;
}
else {
len = strlen(name) + strlen(type) + 5;
if (result_len + len >= result_max) {
result_max = result_len + len + 1000;
result = G_realloc(result, result_max);
}
sprintf(result + result_len, "%s; [%s];", name, type);
result_len += len;
}
}
free_colorinfo(colorinfo, nrules);
return result;
}
/*!
\brief Print color rules
\param out file where to print
*/
void G_list_color_rules(FILE *out)
{
int i, nrules;
struct colorinfo *colorinfo;
colorinfo = get_colorinfo(&nrules);
for (i = 0; i < nrules; i++)
fprintf(out, "%s\n", colorinfo[i].name);
free_colorinfo(colorinfo, nrules);
}
/*!
\brief Print color rules with description and type
The type of color rule including range is appended to the description.
If a color rule name is given, color info is printed only for this
rule.
\param name optional color rule name, or NULL
\param out file where to print
*/
void G_list_color_rules_description_type(FILE *out, char *name)
{
int i, nrules;
struct colorinfo *colorinfo, csearch, *cfound;
colorinfo = get_colorinfo(&nrules);
cfound = NULL;
if (name) {
csearch.name = name;
cfound = bsearch(&csearch, colorinfo, nrules, sizeof(struct colorinfo),
cmp_clrname);
if (cfound) {
if (cfound->desc) {
fprintf(out, "%s: %s [%s]\n", cfound->name, cfound->desc,
cfound->type);
}
else {
fprintf(out, "%s: [%s]\n", cfound->name, cfound->type);
}
}
}
if (cfound == NULL) {
for (i = 0; i < nrules; i++) {
if (colorinfo[i].desc) {
fprintf(out, "%s: %s [%s]\n", colorinfo[i].name,
colorinfo[i].desc, colorinfo[i].type);
}
else {
fprintf(out, "%s: [%s]\n", colorinfo[i].name,
colorinfo[i].type);
}
}
}
free_colorinfo(colorinfo, nrules);
}
/*!
\brief Check if color rule is defined
\param name color rule name
\return 1 found
\return 0 not found
*/
int G_find_color_rule(const char *name)
{
int result, nrules;
struct colorinfo *colorinfo, csearch;
colorinfo = get_colorinfo(&nrules);
csearch.name = (char *)name;
result = (bsearch(&csearch, colorinfo, nrules, sizeof(struct colorinfo),
cmp_clrname) != NULL);
free_colorinfo(colorinfo, nrules);
return result;
}
struct colorinfo *get_colorinfo(int *nrules)
{
int i;
char path[GPATH_MAX];
FILE *fp;
struct colorinfo *colorinfo;
char **cnames;
/* load color rules */
snprintf(path, GPATH_MAX, "%s/etc/colors", G_gisbase());
*nrules = 0;
cnames = G_ls2(path, nrules);
(*nrules) += 3;
colorinfo = G_malloc(*nrules * sizeof(struct colorinfo));
for (i = 0; i < *nrules - 3; i++) {
char buf[1024];
double rmin, rmax;
int first;
int cisperc;
colorinfo[i].name = G_store(cnames[i]);
colorinfo[i].desc = NULL;
/* open color rule file */
snprintf(path, GPATH_MAX, "%s/etc/colors/%s", G_gisbase(),
colorinfo[i].name);
fp = fopen(path, "r");
if (!fp)
G_fatal_error(_("Unable to open color rule"));
/* scan all lines */
first = 1;
rmin = rmax = 0;
cisperc = 0;
while (G_getl2(buf, sizeof(buf), fp)) {
char value[80], color[80];
double x;
char c;
G_strip(buf);
if (*buf == '\0')
continue;
if (*buf == '#')
continue;
if (sscanf(buf, "%s %[^\n]", value, color) != 2)
continue;
if (G_strcasecmp(value, "default") == 0) {
continue;
}
if (G_strcasecmp(value, "nv") == 0) {
continue;
}
if (sscanf(value, "%lf%c", &x, &c) == 2 && c == '%') {
cisperc = 1;
break;
}
if (sscanf(value, "%lf", &x) == 1) {
if (first) {
first = 0;
rmin = rmax = x;
}
else {
if (rmin > x)
rmin = x;
if (rmax < x)
rmax = x;
}
}
}
fclose(fp);
if (cisperc)
colorinfo[i].type = G_store(_("range: map values"));
else {
snprintf(buf, sizeof(buf) - 1, _("range: %g to %g"), rmin, rmax);
colorinfo[i].type = G_store(buf);
}
}
G_free(cnames);
/* colors without rules but description */
colorinfo[*nrules - 3].name = G_store("random");
colorinfo[*nrules - 3].desc = NULL;
colorinfo[*nrules - 3].type = G_store(_("range: map values"));
colorinfo[*nrules - 2].name = G_store("grey.eq");
colorinfo[*nrules - 2].desc = NULL;
colorinfo[*nrules - 2].type = G_store(_("range: map values"));
colorinfo[*nrules - 1].name = G_store("grey.log");
colorinfo[*nrules - 1].desc = NULL;
colorinfo[*nrules - 1].type = G_store(_("range: map values"));
qsort(colorinfo, *nrules, sizeof(struct colorinfo), cmp_clrname);
/* load color descriptions */
snprintf(path, GPATH_MAX, "%s/etc/colors.desc", G_gisbase());
fp = fopen(path, "r");
if (!fp)
G_fatal_error(_("Unable to open color descriptions"));
for (;;) {
char buf[1024];
char tok_buf[1024];
char *cname, *cdesc;
int ntokens;
char **tokens;
struct colorinfo csearch, *cfound;
if (!G_getl2(buf, sizeof(buf), fp))
break;
strcpy(tok_buf, buf);
tokens = G_tokenize(tok_buf, ":");
ntokens = G_number_of_tokens(tokens);
if (ntokens != 2)
continue;
cname = G_chop(tokens[0]);
cdesc = G_chop(tokens[1]);
csearch.name = cname;
cfound = bsearch(&csearch, colorinfo, *nrules, sizeof(struct colorinfo),
cmp_clrname);
if (cfound) {
cfound->desc = G_store(cdesc);
}
G_free_tokens(tokens);
}
fclose(fp);
return colorinfo;
}
void free_colorinfo(struct colorinfo *colorinfo, int nrules)
{
int i;
for (i = 0; i < nrules; i++) {
if (colorinfo[i].name)
G_free(colorinfo[i].name);
if (colorinfo[i].desc)
G_free(colorinfo[i].desc);
if (colorinfo[i].type)
G_free(colorinfo[i].type);
}
if (nrules > 0)
G_free(colorinfo);
}
G_free
void G_free(void *buf)
Free allocated memory.
Definition alloc.c:147
ca
struct cairo_state ca
Definition cairodriver/graph.c:42
NULL
#define NULL
Definition ccmath.h:32
G_color_rules_description_type
char * G_color_rules_description_type(void)
Get color rules description for Option->descriptions.
Definition color_rules.c:124
G_color_rules_descriptions
char * G_color_rules_descriptions(void)
Get color rules description for Option->descriptions.
Definition color_rules.c:79
G_list_color_rules
void G_list_color_rules(FILE *out)
Print color rules.
Definition color_rules.c:175
G_list_color_rules_description_type
void G_list_color_rules_description_type(FILE *out, char *name)
Print color rules with description and type.
Definition color_rules.c:198
G_find_color_rule
int G_find_color_rule(const char *name)
Check if color rule is defined.
Definition color_rules.c:246
G_color_rules_options
char * G_color_rules_options(void)
Get list of color rules for Option->options.
Definition color_rules.c:40
b
double b
Definition driver/set_window.c:5
G_getl2
int G_getl2(char *buf, int n, FILE *fd)
Gets a line of text from a file of any pedigree.
Definition getl.c:60
G_fatal_error
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition gis/error.c:159
G_gisbase
const char * G_gisbase(void)
Get full path name of the top level module directory.
Definition gisbase.c:39
G_ls2
char ** G_ls2(const char *dir, int *num_files)
Stores a sorted directory listing in an array.
Definition ls.c:94
name
const char * name
Definition named_colr.c:6
strcpy
#define strcpy
Definition parson.c:66
list
struct list * list
Definition read_list.c:24
G_chop
char * G_chop(char *line)
Chop leading and trailing white spaces.
Definition strings.c:332
G_strcasecmp
int G_strcasecmp(const char *x, const char *y)
String compare ignoring case (upper or lower).
Definition strings.c:47
G_store
char * G_store(const char *s)
Copy string to allocated memory.
Definition strings.c:87
G_strip
void G_strip(char *buf)
Removes all leading and trailing white space from string.
Definition strings.c:300
path
Definition path.h:15
G_free_tokens
void G_free_tokens(char **tokens)
Free memory allocated to tokens.
Definition token.c:197
G_tokenize
char ** G_tokenize(const char *buf, const char *delim)
Tokenize string.
Definition token.c:47
G_number_of_tokens
int G_number_of_tokens(char **tokens)
Return number of tokens.
Definition token.c:178
x
#define x