GRASS Programmer's Manual
6.4.2(2012)
|
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 }