GRASS Programmer's Manual
6.4.2(2012)
|
00001 00002 00003 #include <stdio.h> 00004 #include <stdlib.h> 00005 #include <string.h> 00006 #include <sys/types.h> 00007 #include <unistd.h> 00008 #include <rpc/types.h> 00009 #include <rpc/xdr.h> 00010 #include <grass/gis.h> 00011 #include "G3d_intern.h" 00012 00013 static int read_colors(const char *, const char *, const char *, 00014 struct Colors *); 00015 static int read_new_colors(FILE *, struct Colors *); 00016 static int read_old_colors(FILE *, struct Colors *); 00017 00018 /*---------------------------------------------------------------------------*/ 00019 00020 int G3d_removeColor(const char *name) 00021 /* adapted from G_remove_colr */ 00022 { 00023 char buf[200], secondary[500], buf2[200], xname[512], xmapset[512]; 00024 00025 if (G__name_is_fully_qualified(name, xname, xmapset)) { 00026 sprintf(buf, "%s/%s", G3D_DIRECTORY, xname); 00027 sprintf(buf2, "%s@%s", G3D_COLOR_ELEMENT, xmapset); /* == color@mapset */ 00028 } 00029 else { 00030 sprintf(buf, "%s/%s", G3D_DIRECTORY, name); 00031 sprintf(buf2, "%s", G3D_COLOR_ELEMENT); 00032 } 00033 00034 G_remove(buf, buf2); 00035 00036 sprintf(secondary, "%s/%s/%s", 00037 G3D_DIRECTORY, G3D_COLOR2_DIRECTORY, G_mapset()); 00038 G_remove(secondary, name); 00039 00040 return 0; 00041 } 00042 00043 /*---------------------------------------------------------------------------*/ 00044 00045 int 00046 G3d_readColors(const char *name, const char *mapset, struct Colors *colors) 00047 /* adapted from G_read_colors */ 00048 { 00049 char buf[512], buf2[200]; 00050 const char *err; 00051 char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; 00052 struct FPRange drange; 00053 DCELL dmin, dmax; 00054 00055 G_init_colors(colors); 00056 00057 if (G__name_is_fully_qualified(name, xname, xmapset)) { 00058 if (strcmp(xmapset, mapset) != 0) 00059 return -1; 00060 name = xname; 00061 } 00062 00063 sprintf(buf, "%s/%s/%s", G3D_DIRECTORY, G3D_COLOR2_DIRECTORY, mapset); 00064 if (read_colors(buf, name, G_mapset(), colors) >= 0) 00065 return 1; 00066 00067 G_mark_colors_as_fp(colors); 00068 00069 /* now look for the regular color table */ 00070 /*if (G__name_is_fully_qualified (name, xname, xmapset)) { 00071 sprintf (buf, "%s/%s", G3D_DIRECTORY, xname); 00072 sprintf (buf2, "%s@%s", G3D_COLOR_ELEMENT, xmapset); // == color@mapset 00073 //} else { */ 00074 sprintf(buf, "%s/%s", G3D_DIRECTORY, name); 00075 sprintf(buf2, "%s", G3D_COLOR_ELEMENT); 00076 /*//} 00077 */ 00078 00079 switch (read_colors(buf, buf2, mapset, colors)) { 00080 case -2: 00081 if (G3d_readRange(name, mapset, &drange) >= 0) { 00082 G_get_fp_range_min_max(&drange, &dmin, &dmax); 00083 if (!G_is_d_null_value(&dmin) && !G_is_d_null_value(&dmax)) 00084 G_make_rainbow_fp_colors(colors, dmin, dmax); 00085 return 0; 00086 } 00087 err = "missing"; 00088 break; 00089 case -1: 00090 err = "invalid"; 00091 break; 00092 default: 00093 return 1; 00094 } 00095 00096 G_warning("color support for [%s] in mapset [%s] %s", name, mapset, err); 00097 return -1; 00098 } 00099 00100 static int read_colors(const char *element, const char *name, 00101 const char *mapset, struct Colors *colors) 00102 { 00103 FILE *fd; 00104 int stat; 00105 char buf[1024]; 00106 00107 if (!(fd = G_fopen_old(element, name, mapset))) 00108 return -2; 00109 00110 /* 00111 * first line in 4.0 color files is % 00112 * otherwise it is pre 4.0 00113 */ 00114 if (fgets(buf, sizeof buf, fd) == NULL) { 00115 fclose(fd); 00116 return -1; 00117 } 00118 fseek(fd, 0L, 0); 00119 00120 G_strip(buf); 00121 if (*buf == '%') { /* 4.0 format */ 00122 stat = read_new_colors(fd, colors); 00123 colors->version = 0; /* 4.0 format */ 00124 } 00125 else { 00126 stat = read_old_colors(fd, colors); 00127 colors->version = -1; /* pre 4.0 format */ 00128 } 00129 fclose(fd); 00130 return stat; 00131 } 00132 00133 /* parse input lines with the following formats 00134 * val1:r:g:b val2:r:g:b 00135 * val:r:g:b (implies cat1==cat2) 00136 * 00137 * r:g:b can be just a single grey level 00138 * cat1:x cat2:y 00139 * cat:x 00140 * 00141 * optional lines are 00142 * invert invert color table 00143 * shift:n where n is the amount to shift the color table 00144 */ 00145 static int read_new_colors(FILE * fd, struct Colors *colors) 00146 { 00147 double val1, val2; 00148 long cat1, cat2; 00149 int r1, g1, b1; 00150 int r2, g2, b2; 00151 char buf[1024]; 00152 char word1[256], word2[256]; 00153 int n, fp_rule; 00154 int null, undef; 00155 int modular; 00156 DCELL shift; 00157 00158 if (fgets(buf, sizeof buf, fd) == NULL) 00159 return -1; 00160 G_strip(buf); 00161 00162 if (sscanf(buf + 1, "%lf %lf", &val1, &val2) == 2) 00163 G_set_d_color_range((DCELL) val1, (DCELL) val2, colors); 00164 00165 modular = 0; 00166 while (fgets(buf, sizeof buf, fd)) { 00167 null = undef = fp_rule = 0; 00168 *word1 = *word2 = 0; 00169 n = sscanf(buf, "%s %s", word1, word2); 00170 if (n < 1) 00171 continue; 00172 00173 if (sscanf(word1, "shift:%lf", &shift) == 1 00174 || (strcmp(word1, "shift:") == 0 && 00175 sscanf(word2, "%lf", &shift) == 1)) { 00176 G_shift_d_colors(shift, colors); 00177 continue; 00178 } 00179 if (strcmp(word1, "invert") == 0) { 00180 G_invert_colors(colors); 00181 continue; 00182 } 00183 if (strcmp(word1, "%%") == 0) { 00184 modular = !modular; 00185 continue; 00186 } 00187 00188 switch (sscanf(word1, "nv:%d:%d:%d", &r1, &g1, &b1)) { 00189 case 1: 00190 null = 1; 00191 b1 = g1 = r1; 00192 break; 00193 case 3: 00194 null = 1; 00195 break; 00196 } 00197 if (!null) 00198 switch (sscanf(word1, "*:%d:%d:%d", &r1, &g1, &b1)) { 00199 case 1: 00200 undef = 1; 00201 b1 = g1 = r1; 00202 break; 00203 case 3: 00204 undef = 1; 00205 break; 00206 } 00207 if (!null && !undef) 00208 switch (sscanf(word1, "%ld:%d:%d:%d", &cat1, &r1, &g1, &b1)) { 00209 case 2: 00210 b1 = g1 = r1; 00211 break; 00212 case 4: 00213 break; 00214 default: 00215 if (sscanf(word1, "%lf:%d:%d:%d", &val1, &r1, &g1, &b1) == 4) 00216 fp_rule = 1; 00217 else if (sscanf(word1, "%lf:%d", &val1, &r1) == 2) { 00218 fp_rule = 1; 00219 b1 = g1 = r1; 00220 } 00221 else 00222 continue; /* other lines are ignored */ 00223 } 00224 if (n == 2) { 00225 switch (sscanf(word2, "%ld:%d:%d:%d", &cat2, &r2, &g2, &b2)) { 00226 case 2: 00227 b2 = g2 = r2; 00228 if (fp_rule) 00229 val2 = (DCELL) cat2; 00230 break; 00231 case 4: 00232 if (fp_rule) 00233 val2 = (DCELL) cat2; 00234 break; 00235 default: 00236 if (sscanf(word2, "%lf:%d:%d:%d", &val2, &r2, &g2, &b2) == 4) { 00237 if (!fp_rule) 00238 val1 = (DCELL) cat1; 00239 fp_rule = 1; 00240 } 00241 else if (sscanf(word2, "%lf:%d", &val2, &r2) == 2) { 00242 if (!fp_rule) 00243 val1 = (DCELL) cat1; 00244 fp_rule = 1; 00245 b2 = g2 = r2; 00246 } 00247 else 00248 continue; /* other lines are ignored */ 00249 } 00250 } 00251 else { 00252 if (!fp_rule) 00253 cat2 = cat1; 00254 else 00255 val2 = val1; 00256 r2 = r1; 00257 g2 = g1; 00258 b2 = b1; 00259 } 00260 if (null) 00261 G_set_null_value_color(r1, g1, b1, colors); 00262 else if (undef) 00263 G_set_default_color(r1, g1, b1, colors); 00264 00265 else if (modular) { 00266 if (fp_rule) 00267 G_add_modular_d_raster_color_rule((DCELL *) & val1, r1, g1, 00268 b1, (DCELL *) & val2, r2, 00269 g2, b2, colors); 00270 else 00271 G_add_modular_color_rule((CELL) cat1, r1, g1, b1, 00272 (CELL) cat2, r2, g2, b2, colors); 00273 } 00274 else { 00275 if (fp_rule) 00276 G_add_d_raster_color_rule((DCELL *) & val1, r1, g1, b1, 00277 (DCELL *) & val2, r2, g2, b2, 00278 colors); 00279 else 00280 G_add_color_rule((CELL) cat1, r1, g1, b1, 00281 (CELL) cat2, r2, g2, b2, colors); 00282 } 00283 /* 00284 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); 00285 */ 00286 } 00287 return 1; 00288 } 00289 00290 static int read_old_colors(FILE * fd, struct Colors *colors) 00291 { 00292 char buf[256]; 00293 long n; 00294 long min; 00295 float red_f, grn_f, blu_f; 00296 int red, grn, blu; 00297 int old; 00298 int zero; 00299 00300 G_init_colors(colors); 00301 /* 00302 * first line in pre 3.0 color files is number of colors - ignore 00303 * otherwise it is #min first color, and the next line is for color 0 00304 */ 00305 if (fgets(buf, sizeof buf, fd) == NULL) 00306 return -1; 00307 00308 G_strip(buf); 00309 if (*buf == '#') { /* 3.0 format */ 00310 old = 0; 00311 if (sscanf(buf + 1, "%ld", &min) != 1) /* first color */ 00312 return -1; 00313 zero = 1; 00314 } 00315 else { 00316 old = 1; 00317 min = 0; 00318 zero = 0; 00319 } 00320 00321 colors->cmin = min; 00322 n = min; 00323 while (fgets(buf, sizeof buf, fd)) { 00324 if (old) { 00325 if (sscanf(buf, "%f %f %f", &red_f, &grn_f, &blu_f) != 3) 00326 return -1; 00327 00328 red = 256 * red_f; 00329 grn = 256 * grn_f; 00330 blu = 256 * blu_f; 00331 } 00332 else { 00333 switch (sscanf(buf, "%d %d %d", &red, &grn, &blu)) { 00334 case 1: 00335 blu = grn = red; 00336 break; 00337 case 2: 00338 blu = grn; 00339 break; 00340 case 3: 00341 break; 00342 default: 00343 return -1; 00344 } 00345 } 00346 if (zero) { 00347 G__insert_color_into_lookup((CELL) 0, red, grn, blu, 00348 &colors->fixed); 00349 zero = 0; 00350 } 00351 else 00352 G__insert_color_into_lookup((CELL) n++, red, grn, blu, 00353 &colors->fixed); 00354 } 00355 colors->cmax = n - 1; 00356 00357 return 0; 00358 } 00359 00360 /*---------------------------------------------------------------------------*/ 00361 00362 int 00363 G3d_writeColors(const char *name, const char *mapset, struct Colors *colors) 00364 /* adapted from G_write_colors */ 00365 { 00366 char element[512], buf[512], buf2[200]; 00367 char xname[512], xmapset[512]; 00368 FILE *fd; 00369 int stat; 00370 00371 if (G__name_is_fully_qualified(name, xname, xmapset)) { 00372 if (strcmp(xmapset, mapset) != 0) 00373 return -1; 00374 name = xname; 00375 } 00376 00377 /* 00378 * if mapset is current mapset, remove colr2 file (created by pre 3.0 grass) 00379 * and then write original color table 00380 * else write secondary color table 00381 */ 00382 00383 sprintf(element, "%s/%s/%s", G3D_DIRECTORY, G3D_COLOR2_DIRECTORY, mapset); 00384 if (strcmp(mapset, G_mapset()) == 0) { 00385 G_remove(element, name); /* get rid of existing colr2, if any */ 00386 00387 if (G__name_is_fully_qualified(name, xname, xmapset)) { 00388 sprintf(buf, "%s/%s", G3D_DIRECTORY, xname); 00389 sprintf(buf2, "%s@%s", G3D_COLOR_ELEMENT, xmapset); /* == color@mapset */ 00390 } 00391 else { 00392 sprintf(buf, "%s/%s", G3D_DIRECTORY, name); 00393 sprintf(buf2, "%s", G3D_COLOR_ELEMENT); 00394 } 00395 00396 if (!(fd = G_fopen_new(buf, buf2))) 00397 return -1; 00398 } 00399 else { 00400 if (!(fd = G_fopen_new(element, name))) 00401 return -1; 00402 } 00403 00404 stat = G__write_colors(fd, colors); 00405 fclose(fd); 00406 return stat; 00407 } 00408 00409 /*---------------------------------------------------------------------------*/ 00410 00411 /*---------------------------------------------------------------------------*/ 00412 00413 /*---------------------------------------------------------------------------*/