GRASS Programmer's Manual  6.4.1(2011)
color_read.c
Go to the documentation of this file.
00001 
00002 /**********************************************************************
00003  *
00004  *  G_read_colors (name, mapset, colors)
00005  *      char *name                   name of map
00006  *      char *mapset                 mapset that map belongs to
00007  *      struct Colors *colors        structure to hold color info
00008  *
00009  *  Reads the color information associated with map layer "map"
00010  *  in mapset "mapset" into the structure "colors".
00011  *
00012  *  returns:    1  if successful
00013  *              0  if missing, but default colors generated
00014  *             -1  on fail
00015  *
00016  *  note:   If a secondary color file for map name "name" exists
00017  *          in the current project, that color file is read.  This
00018  *          allows the user to define their own color lookup tables
00019  *          for cell maps found in other mapsets.
00020  *
00021  *          Warning message is printed if the color file is
00022  *          missing or invalid.
00023  *********************************************************************/
00024 
00025 #include <grass/gis.h>
00026 #include <grass/glocale.h>
00027 #include <string.h>
00028 
00029 static int read_colors(const char *, const char *, const char *,
00030                        struct Colors *);
00031 static int read_new_colors(FILE *, struct Colors *);
00032 static int read_old_colors(FILE *, struct Colors *);
00033 
00034 
00062 int G_read_colors(const char *name, const char *mapset, struct Colors *colors)
00063 {
00064     int fp;
00065     char buf[GNAME_MAX];
00066     char *err;
00067     char xname[GNAME_MAX];
00068     struct Range range;
00069     struct FPRange drange;
00070     CELL min, max;
00071     DCELL dmin, dmax;
00072 
00073     fp = G_raster_map_is_fp(name, mapset);
00074     G_init_colors(colors);
00075 
00076     strcpy(xname, name);
00077     mapset = G_find_cell(xname, mapset);
00078     name = xname;
00079 
00080     if (fp)
00081         G_mark_colors_as_fp(colors);
00082 
00083     /* first look for secondary color table in current mapset */
00084     sprintf(buf, "colr2/%s", mapset);
00085     if (read_colors(buf, name, G_mapset(), colors) >= 0)
00086         return 1;
00087 
00088     /* now look for the regular color table */
00089     switch (read_colors("colr", name, mapset, colors)) {
00090     case -2:
00091         if (!fp) {
00092             if (G_read_range(name, mapset, &range) >= 0) {
00093                 G_get_range_min_max(&range, &min, &max);
00094                 if (!G_is_c_null_value(&min) && !G_is_c_null_value(&max))
00095                     G_make_rainbow_colors(colors, min, max);
00096                 return 0;
00097             }
00098         }
00099         else {
00100             if (G_read_fp_range(name, mapset, &drange) >= 0) {
00101                 G_get_fp_range_min_max(&drange, &dmin, &dmax);
00102                 if (!G_is_d_null_value(&dmin) && !G_is_d_null_value(&dmax))
00103                     G_make_rainbow_fp_colors(colors, dmin, dmax);
00104                 return 0;
00105             }
00106         }
00107         err = "missing";
00108         break;
00109     case -1:
00110         err = "invalid";
00111         break;
00112     default:
00113         return 1;
00114     }
00115 
00116     G_warning(_("color support for [%s] in mapset [%s] %s"), name, mapset,
00117               err);
00118     return -1;
00119 }
00120 
00121 static int read_colors(const char *element, const char *name,
00122                        const char *mapset, struct Colors *colors)
00123 {
00124     FILE *fd;
00125     int stat;
00126     char buf[1024];
00127 
00128     if (!(fd = G_fopen_old(element, name, mapset)))
00129         return -2;
00130 
00131     /*
00132      * first line in 4.0 color files is %
00133      * otherwise it is pre 4.0
00134      */
00135     if (fgets(buf, sizeof buf, fd) == NULL) {
00136         fclose(fd);
00137         return -1;
00138     }
00139     fseek(fd, 0L, 0);
00140 
00141     G_strip(buf);
00142     if (*buf == '%') {          /* 4.0 format */
00143         stat = read_new_colors(fd, colors);
00144         colors->version = 0;    /* 4.0 format */
00145     }
00146     else {
00147         stat = read_old_colors(fd, colors);
00148         colors->version = -1;   /* pre 4.0 format */
00149     }
00150     fclose(fd);
00151     return stat;
00152 }
00153 
00154 /* parse input lines with the following formats
00155  *   val1:r:g:b val2:r:g:b
00156  *   val:r:g:b          (implies cat1==cat2)
00157  *
00158  * r:g:b can be just a single grey level
00159  *   cat1:x cat2:y
00160  *   cat:x
00161  *
00162  * optional lines are
00163  *    invert            invert color table
00164  *    shift:n           where n is the amount to shift the color table
00165  *    nv:r:g:b          color to use for NULL values
00166  *    *:r:g:b           color to use for undefined (beyond color rules)
00167  */
00168 static int read_new_colors(FILE * fd, struct Colors *colors)
00169 {
00170     double val1, val2;
00171     long cat1, cat2;
00172     int r1, g1, b1;
00173     int r2, g2, b2;
00174     char buf[1024];
00175     char word1[256], word2[256];
00176     int n, fp_rule;
00177     int null, undef;
00178     int modular;
00179     DCELL shift;
00180 
00181     if (fgets(buf, sizeof buf, fd) == NULL)
00182         return -1;
00183     G_strip(buf);
00184 
00185     if (sscanf(buf + 1, "%lf %lf", &val1, &val2) == 2)
00186         G_set_d_color_range((DCELL) val1, (DCELL) val2, colors);
00187 
00188     modular = 0;
00189     while (fgets(buf, sizeof buf, fd)) {
00190         null = undef = fp_rule = 0;
00191         *word1 = *word2 = 0;
00192         n = sscanf(buf, "%s %s", word1, word2);
00193         if (n < 1)
00194             continue;
00195 
00196         if (sscanf(word1, "shift:%lf", &shift) == 1
00197             || (strcmp(word1, "shift:") == 0 &&
00198                 sscanf(word2, "%lf", &shift) == 1)) {
00199             G_shift_d_colors(shift, colors);
00200             continue;
00201         }
00202         if (strcmp(word1, "invert") == 0) {
00203             G_invert_colors(colors);
00204             continue;
00205         }
00206         if (strcmp(word1, "%%") == 0) {
00207             modular = !modular;
00208             continue;
00209         }
00210 
00211         switch (sscanf(word1, "nv:%d:%d:%d", &r1, &g1, &b1)) {
00212         case 1:
00213             null = 1;
00214             b1 = g1 = r1;
00215             break;
00216         case 3:
00217             null = 1;
00218             break;
00219         }
00220         if (!null)
00221             switch (sscanf(word1, "*:%d:%d:%d", &r1, &g1, &b1)) {
00222             case 1:
00223                 undef = 1;
00224                 b1 = g1 = r1;
00225                 break;
00226             case 3:
00227                 undef = 1;
00228                 break;
00229             }
00230         if (!null && !undef)
00231             switch (sscanf(word1, "%ld:%d:%d:%d", &cat1, &r1, &g1, &b1)) {
00232             case 2:
00233                 b1 = g1 = r1;
00234                 break;
00235             case 4:
00236                 break;
00237             default:
00238                 if (sscanf(word1, "%lf:%d:%d:%d", &val1, &r1, &g1, &b1) == 4)
00239                     fp_rule = 1;
00240                 else if (sscanf(word1, "%lf:%d", &val1, &r1) == 2) {
00241                     fp_rule = 1;
00242                     b1 = g1 = r1;
00243                 }
00244                 else
00245                     continue;   /* other lines are ignored */
00246             }
00247         if (n == 2) {
00248             switch (sscanf(word2, "%ld:%d:%d:%d", &cat2, &r2, &g2, &b2)) {
00249             case 2:
00250                 b2 = g2 = r2;
00251                 if (fp_rule)
00252                     val2 = (DCELL) cat2;
00253                 break;
00254             case 4:
00255                 if (fp_rule)
00256                     val2 = (DCELL) cat2;
00257                 break;
00258             default:
00259                 if (sscanf(word2, "%lf:%d:%d:%d", &val2, &r2, &g2, &b2) == 4) {
00260                     if (!fp_rule)
00261                         val1 = (DCELL) cat1;
00262                     fp_rule = 1;
00263                 }
00264                 else if (sscanf(word2, "%lf:%d", &val2, &r2) == 2) {
00265                     if (!fp_rule)
00266                         val1 = (DCELL) cat1;
00267                     fp_rule = 1;
00268                     b2 = g2 = r2;
00269                 }
00270                 else
00271                     continue;   /* other lines are ignored */
00272             }
00273         }
00274         else {
00275             if (!fp_rule)
00276                 cat2 = cat1;
00277             else
00278                 val2 = val1;
00279             r2 = r1;
00280             g2 = g1;
00281             b2 = b1;
00282         }
00283         if (null)
00284             G_set_null_value_color(r1, g1, b1, colors);
00285         else if (undef)
00286             G_set_default_color(r1, g1, b1, colors);
00287 
00288         else if (modular) {
00289             if (fp_rule)
00290                 G_add_modular_d_raster_color_rule((DCELL *) & val1, r1, g1,
00291                                                   b1, (DCELL *) & val2, r2,
00292                                                   g2, b2, colors);
00293             else
00294                 G_add_modular_color_rule((CELL) cat1, r1, g1, b1,
00295                                          (CELL) cat2, r2, g2, b2, colors);
00296         }
00297         else {
00298             if (fp_rule)
00299                 G_add_d_raster_color_rule((DCELL *) & val1, r1, g1, b1,
00300                                           (DCELL *) & val2, r2, g2, b2,
00301                                           colors);
00302             else
00303                 G_add_color_rule((CELL) cat1, r1, g1, b1,
00304                                  (CELL) cat2, r2, g2, b2, colors);
00305         }
00306         /*
00307            fprintf (stderr, "adding rule %d=%.2lf %d %d %d  %d=%.2lf %d %d %d\n", cat1,val1,  r1, g1, b1, cat2, val2, r2, g2, b2);
00308          */
00309     }
00310     return 1;
00311 }
00312 
00313 static int read_old_colors(FILE * fd, struct Colors *colors)
00314 {
00315     char buf[256];
00316     long n;
00317     long min;
00318     float red_f, grn_f, blu_f;
00319     int red, grn, blu;
00320     int old;
00321     int zero;
00322 
00323     G_init_colors(colors);
00324     /*
00325      * first line in pre 3.0 color files is number of colors - ignore
00326      * otherwise it is #min first color, and the next line is for color 0
00327      */
00328     if (fgets(buf, sizeof buf, fd) == NULL)
00329         return -1;
00330 
00331     G_strip(buf);
00332     if (*buf == '#') {          /* 3.0 format */
00333         old = 0;
00334         if (sscanf(buf + 1, "%ld", &min) != 1)  /* first color */
00335             return -1;
00336         zero = 1;
00337     }
00338     else {
00339         old = 1;
00340         min = 0;
00341         zero = 0;
00342     }
00343 
00344     colors->cmin = min;
00345     n = min;
00346     while (fgets(buf, sizeof buf, fd)) {
00347         if (old) {
00348             if (sscanf(buf, "%f %f %f", &red_f, &grn_f, &blu_f) != 3)
00349                 return -1;
00350 
00351             red = 256 * red_f;
00352             grn = 256 * grn_f;
00353             blu = 256 * blu_f;
00354         }
00355         else {
00356             switch (sscanf(buf, "%d %d %d", &red, &grn, &blu)) {
00357             case 1:
00358                 blu = grn = red;
00359                 break;
00360             case 2:
00361                 blu = grn;
00362                 break;
00363             case 3:
00364                 break;
00365             default:
00366                 return -1;
00367             }
00368         }
00369         if (zero) {
00370             G__insert_color_into_lookup((CELL) 0, red, grn, blu,
00371                                         &colors->fixed);
00372             zero = 0;
00373         }
00374         else
00375             G__insert_color_into_lookup((CELL) n++, red, grn, blu,
00376                                         &colors->fixed);
00377     }
00378     colors->cmax = n - 1;
00379 
00380     return 0;
00381 }
00382 
00383 
00396 int G_mark_colors_as_fp(struct Colors *colors)
00397 {
00398     colors->is_float = 1;
00399 
00400     return 0;
00401 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines