color_read.c

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

Generated on Wed Aug 23 17:49:22 2006 for GRASS by  doxygen 1.4.7