• Main Page
  • Related Pages
  • Data Structures
  • Files
  • File List
  • Globals

color_rules.c

Go to the documentation of this file.
00001 
00002 /****************************************************************************
00003  *
00004  * MODULE:       gis library
00005  * AUTHOR(S):    Glynn Clements <glynn@gclements.plus.com>
00006  * COPYRIGHT:    (C) 2007 Glynn Clements and the GRASS Development Team
00007  *
00008  * NOTE:         Based upon r.colors/rules.c
00009  *               The colors are stored in ./colors/
00010  *
00011  *  This program is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU General Public License as published by
00013  *  the Free Software Foundation; either version 2 of the License, or
00014  *  (at your option) any later version.
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU General Public License for more details.
00020  *
00021  *****************************************************************************/
00022 
00023 #include <stdio.h>
00024 #include <grass/gis.h>
00025 #include <grass/glocale.h>
00026 
00027 struct rule
00028 {
00029     int set;
00030     int r, g, b;
00031     DCELL val;
00032 };
00033 
00034 enum rule_error
00035 {
00036     CR_OK = 0,
00037     CR_ERROR_SYNTAX,
00038     CR_ERROR_RGB,
00039     CR_ERROR_COLOR,
00040     CR_ERROR_PERCENT,
00041     CR_ERROR_VALUE,
00042 };
00043 
00044 int G_parse_color_rule(DCELL min, DCELL max, const char *buf,
00045                        DCELL * val, int *r, int *g, int *b,
00046                        int *norm, int *nval, int *dflt)
00047 {
00048     char value[80], color[80];
00049     double x;
00050     char c;
00051 
00052     *norm = *nval = *dflt = 0;
00053 
00054     if (sscanf(buf, "%s %[^\n]", value, color) != 2)
00055         return CR_ERROR_SYNTAX;
00056 
00057     G_chop(color);
00058 
00059     if (sscanf(color, "%d:%d:%d", r, g, b) == 3 ||
00060         sscanf(color, "%d %d %d", r, g, b) == 3) {
00061         if (*r < 0 || *r > 255 || *g < 0 || *g > 255 || *b < 0 || *b > 255)
00062             return CR_ERROR_RGB;
00063     }
00064     else {
00065         float fr, fg, fb;
00066 
00067         if (G_color_values(color, &fr, &fg, &fb) < 0)
00068             return CR_ERROR_COLOR;
00069 
00070         *r = (int)(fr * 255.99);
00071         *g = (int)(fg * 255.99);
00072         *b = (int)(fb * 255.99);
00073     }
00074 
00075     G_chop(value);
00076 
00077     if (G_strcasecmp(value, "default") == 0) {
00078         *dflt = 1;
00079         return CR_OK;
00080     }
00081 
00082     if (G_strcasecmp(value, "nv") == 0) {
00083         *nval = 1;
00084         return CR_OK;
00085     }
00086 
00087     if (sscanf(value, "%lf%c", &x, &c) == 2 && c == '%') {
00088         if (x < 0 || x > 100)
00089             return CR_ERROR_PERCENT;
00090 
00091         *val = min + (max - min) * (x / 100);
00092         *norm = 1;
00093         return CR_OK;
00094     }
00095 
00096     if (sscanf(value, "%lf", val) == 1) {
00097         *norm = 1;
00098         return CR_OK;
00099     }
00100 
00101     return CR_ERROR_VALUE;
00102 }
00103 
00104 const char *G_parse_color_rule_error(int code)
00105 {
00106     switch (code) {
00107     case CR_OK:
00108         return "";
00109     case CR_ERROR_SYNTAX:
00110         return _("syntax error");
00111     case CR_ERROR_RGB:
00112         return _("R/G/B not in range 0-255");
00113     case CR_ERROR_COLOR:
00114         return _("invalid color name");
00115     case CR_ERROR_PERCENT:
00116         return _("percentage not in range 0-100");
00117     case CR_ERROR_VALUE:
00118         return _("invalid value");
00119     default:
00120         return _("unknown error");
00121     }
00122 }
00123 
00124 int G_read_color_rule(void *closure, DCELL min, DCELL max,
00125                       DCELL * val, int *r, int *g, int *b,
00126                       int *norm, int *nval, int *dflt)
00127 {
00128     char buf[1024];
00129     FILE *fp = closure;
00130     int ret;
00131 
00132     *norm = *nval = *dflt = 0;
00133 
00134     for (;;) {
00135         if (!G_getl2(buf, sizeof(buf), fp))
00136             return 0;
00137 
00138         G_strip(buf);
00139         G_debug(5, "color buf = [%s]", buf);
00140 
00141         if (*buf == '\0')
00142             continue;
00143         if (*buf == '#')
00144             continue;
00145 
00146         ret =
00147             G_parse_color_rule(min, max, buf, val, r, g, b, norm, nval, dflt);
00148         if (ret == 0)
00149             return 1;
00150 
00151         G_fatal_error(_("bad rule (%s): [%s]"),
00152                       G_parse_color_rule_error(ret), buf);
00153     }
00154 
00155     return 0;
00156 }
00157 
00158 int G_read_color_rules(struct Colors *colors, DCELL min, DCELL max,
00159                        read_rule_fn * read_rule, void *closure)
00160 {
00161     struct rule *rule = NULL;
00162     int nrules = 0;
00163     struct rule dflt, null;
00164     int set, is_null, is_dflt, r, g, b;
00165     DCELL val;
00166     int n;
00167 
00168     if (!read_rule)
00169         read_rule = G_read_color_rule;
00170 
00171     G_init_colors(colors);
00172 
00173     /* initialization */
00174     dflt.r = dflt.g = dflt.b = dflt.set = 0;
00175     null.r = null.g = null.b = null.set = 0;
00176 
00177     while ((*read_rule)
00178            (closure, min, max, &val, &r, &g, &b, &set, &is_null, &is_dflt)) {
00179         struct rule *p;
00180 
00181         if (set) {
00182             n = nrules++;
00183             rule = G_realloc(rule, nrules * sizeof(struct rule));
00184             p = &rule[n];
00185         }
00186         else if (is_dflt)
00187             p = &dflt;
00188         else if (is_null)
00189             p = &null;
00190 
00191         p->r = r;
00192         p->g = g;
00193         p->b = b;
00194         p->set = 1;
00195         p->val = val;
00196     }
00197 
00198     if (nrules == 0)
00199         return 0;
00200 
00201     if (nrules == 1) {
00202         const struct rule *p = &rule[0];
00203 
00204         G_set_d_color(p->val, p->r, p->g, p->b, colors);
00205     }
00206 
00207     for (n = 1; n < nrules; n++) {
00208         struct rule *lo = &rule[n - 1];
00209         struct rule *hi = &rule[n];
00210 
00211         G_add_d_raster_color_rule(&lo->val, lo->r, lo->g, lo->b,
00212                                   &hi->val, hi->r, hi->g, hi->b, colors);
00213     }
00214 
00215     /* null value and default color set up, if rules are set up by user */
00216     if (null.set)
00217         G_set_null_value_color(null.r, null.g, null.b, colors);
00218 
00219     if (dflt.set)
00220         G_set_default_color(dflt.r, dflt.g, dflt.b, colors);
00221 
00222     return 1;
00223 }
00224 
00225 static int load_rules_file(struct Colors *colors, const char *path, DCELL min,
00226                            DCELL max)
00227 {
00228     FILE *fp;
00229     int ret;
00230 
00231     fp = fopen(path, "r");
00232 
00233     if (!fp)
00234         return 0;
00235 
00236     ret = G_read_color_rules(colors, min, max, G_read_color_rule, (void *)fp);
00237 
00238     fclose(fp);
00239 
00240     return ret;
00241 }
00242 
00243 int G_load_colors(struct Colors *colors, const char *path, CELL min, CELL max)
00244 {
00245     return load_rules_file(colors, path, (DCELL) min, (DCELL) max);
00246 }
00247 
00248 int G_load_fp_colors(struct Colors *colors, const char *path, DCELL min,
00249                      DCELL max)
00250 {
00251     return load_rules_file(colors, path, min, max);
00252 }
00253 
00254 static int load_rules_name(struct Colors *colors, const char *name, DCELL min,
00255                            DCELL max)
00256 {
00257     int ret;
00258     char path[GPATH_MAX];
00259 
00260     sprintf(path, "%s/etc/colors/%s", G_gisbase(), name);
00261 
00262     ret = load_rules_file(colors, path, min, max);
00263 
00264     if (!ret)
00265         G_fatal_error(_("Unable to load color rules <%s>"), name);
00266 
00267     return ret;
00268 }
00269 
00270 int G_make_colors(struct Colors *colors, const char *name, CELL min, CELL max)
00271 {
00272     return load_rules_name(colors, name, (DCELL) min, (DCELL) max);
00273 }
00274 
00275 int G_make_fp_colors(struct Colors *colors, const char *name, DCELL min,
00276                      DCELL max)
00277 {
00278     return load_rules_name(colors, name, min, max);
00279 }

Generated on Thu Dec 9 2010 20:46:05 for GRASS Programmer's Manual by  doxygen 1.7.2