GRASS Programmer's Manual  6.4.1(2011)
color_write.c
Go to the documentation of this file.
00001 
00002 /**********************************************************************
00003  *  G_write_colors (name, mapset, colors)
00004  *      char *name                   name of map
00005  *      char *mapset                 mapset that map belongs to
00006  *      struct Colors *colors        structure holding color info
00007  *
00008  *  Writes the color information associated with map layer "map"
00009  *  in mapset "mapset" from the structure "colors".
00010  *
00011  *  returns:    1  if successful
00012  *             -1  on fail
00013  *
00014  * If the environment variable FORCE_GRASS3_COLORS is set (to anything at all)
00015  * then the output format is 3.0, even if the structure contains 4.0 rules.
00016  * This allows users to create 3.0 color files for export to sites which
00017  * don't yet have 4.0
00018  ***********************************************************************/
00019 #include <string.h>
00020 #include <stdlib.h>
00021 #include <stdio.h>
00022 #include <grass/gis.h>
00023 #define PRECISION 30
00024 #define THRESHOLD .0000000000000000000000000000005
00025 /* .5 * 10 ^(-30) */
00026 
00027 static int write_new_colors(FILE *, struct Colors *);
00028 static int write_rules(FILE *, struct _Color_Rule_ *, DCELL, DCELL);
00029 static int write_old_colors(FILE *, struct Colors *);
00030 static int forced_write_old_colors(FILE *, struct Colors *);
00031 static int format_min(char *, double);
00032 static int format_max(char *, double);
00033 
00034 
00077 int G_write_colors(const char *name, const char *mapset,
00078                    struct Colors *colors)
00079 {
00080     char element[512];
00081     char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
00082     FILE *fd;
00083     int stat;
00084 
00085     if (G__name_is_fully_qualified(name, xname, xmapset)) {
00086         if (strcmp(xmapset, mapset) != 0)
00087             return -1;
00088         name = xname;
00089     }
00090     /*
00091      * if mapset is current mapset, remove colr2 file (created by pre 3.0 grass)
00092      *    and then write original color table
00093      * else write secondary color table
00094      */
00095     sprintf(element, "colr2/%s", mapset);
00096     if (strcmp(mapset, G_mapset()) == 0) {
00097         G_remove(element, name);        /* get rid of existing colr2, if any */
00098         strcpy(element, "colr");
00099     }
00100     if (!(fd = G_fopen_new(element, name)))
00101         return -1;
00102 
00103     stat = G__write_colors(fd, colors);
00104     fclose(fd);
00105     return stat;
00106 }
00107 
00108 int G__write_colors(FILE * fd, struct Colors *colors)
00109 {
00110     if (getenv("FORCE_GRASS3_COLORS"))
00111         return forced_write_old_colors(fd, colors);
00112     else if (colors->version < 0)
00113         return write_old_colors(fd, colors);
00114     else
00115         return write_new_colors(fd, colors);
00116 }
00117 
00118 static int write_new_colors(FILE * fd, struct Colors *colors)
00119 {
00120     char str1[100], str2[100];
00121 
00122     format_min(str1, (double)colors->cmin);
00123     format_max(str2, (double)colors->cmax);
00124     fprintf(fd, "%% %s %s\n", str1, str2);
00125 
00126     if (colors->shift) {
00127         sprintf(str2, "%.10f", (double)colors->shift);
00128         G_trim_decimal(str2);
00129         fprintf(fd, "shift:%s\n", str2);
00130     }
00131     if (colors->invert)
00132         fprintf(fd, "invert\n");
00133 
00134     if (colors->null_set) {
00135         fprintf(fd, "nv:%d", colors->null_red);
00136         if (colors->null_red != colors->null_grn || colors->null_red
00137             != colors->null_blu)
00138             fprintf(fd, ":%d:%d", colors->null_grn, colors->null_blu);
00139         fprintf(fd, "\n");
00140     }
00141     if (colors->undef_set) {
00142         fprintf(fd, "*:%d", colors->undef_red);
00143         if (colors->undef_red != colors->undef_grn || colors->undef_red
00144             != colors->undef_blu)
00145             fprintf(fd, ":%d:%d", colors->undef_grn, colors->undef_blu);
00146         fprintf(fd, "\n");
00147     }
00148     if (colors->modular.rules) {
00149         fprintf(fd, "%s\n", "%%");
00150         write_rules(fd, colors->modular.rules, colors->cmin, colors->cmax);
00151         fprintf(fd, "%s\n", "%%");
00152     }
00153     if (colors->fixed.rules)
00154         write_rules(fd, colors->fixed.rules, colors->cmin, colors->cmax);
00155 
00156     return 1;
00157 }
00158 
00159 static int write_rules(FILE * fd, struct _Color_Rule_ *crules, DCELL dmin, DCELL dmax   /* overall min and max data values in color table */
00160     )
00161 {
00162     struct _Color_Rule_ *rule;
00163     char str[100];
00164 
00165     /* find the end of the rules list */
00166     rule = crules;
00167     while (rule->next)
00168         rule = rule->next;
00169 
00170     /* write out the rules in reverse order */
00171     for (; rule; rule = rule->prev) {
00172         if (rule->low.value == dmin)
00173             format_min(str, (double)rule->low.value);
00174         else {
00175             sprintf(str, "%.10f", (double)rule->low.value);
00176             G_trim_decimal(str);
00177         }
00178         fprintf(fd, "%s:%d", str, (int)rule->low.red);
00179         if (rule->low.red != rule->low.grn || rule->low.red != rule->low.blu)
00180             fprintf(fd, ":%d:%d", rule->low.grn, rule->low.blu);
00181         /* even if low==high, write second end when the high is dmax */
00182         if (rule->high.value == dmax || rule->low.value != rule->high.value) {
00183             if (rule->high.value == dmax)
00184                 format_max(str, (double)rule->high.value);
00185             else {
00186                 sprintf(str, "%.10f", (double)rule->high.value);
00187                 G_trim_decimal(str);
00188             }
00189             fprintf(fd, " %s:%d", str, (int)rule->high.red);
00190             if (rule->high.red != rule->high.grn ||
00191                 rule->high.red != rule->high.blu)
00192                 fprintf(fd, ":%d:%d", rule->high.grn, rule->high.blu);
00193         }
00194         fprintf(fd, "\n");
00195     }
00196 
00197     return 0;
00198 }
00199 
00200 static int write_old_colors(FILE * fd, struct Colors *colors)
00201 {
00202     int i, n;
00203 
00204     fprintf(fd, "#%ld first color\n", (long)colors->fixed.min);
00205     if (colors->null_set) {
00206         fprintf(fd, "%d %d %d\n",
00207                 (int)colors->null_red,
00208                 (int)colors->null_grn, (int)colors->null_blu);
00209     }
00210     else
00211         fprintf(fd, "255 255 255\n");   /* white */
00212 
00213     n = colors->fixed.max - colors->fixed.min + 1;
00214 
00215     for (i = 0; i < n; i++) {
00216         fprintf(fd, "%d", (int)colors->fixed.lookup.red[i]);
00217         if (colors->fixed.lookup.red[i] != colors->fixed.lookup.grn[i]
00218             || colors->fixed.lookup.red[i] != colors->fixed.lookup.blu[i])
00219             fprintf(fd, " %d %d",
00220                     (int)colors->fixed.lookup.grn[i],
00221                     (int)colors->fixed.lookup.blu[i]);
00222         fprintf(fd, "\n");
00223     }
00224 
00225     return 1;
00226 }
00227 
00228 static int forced_write_old_colors(FILE * fd, struct Colors *colors)
00229 {
00230     int red, grn, blu;
00231     CELL cat;
00232 
00233     fprintf(fd, "#%ld first color\n", (long)colors->cmin);
00234     G_get_color((CELL) 0, &red, &grn, &blu, colors);
00235     fprintf(fd, "%d %d %d\n", red, grn, blu);
00236 
00237     for (cat = colors->cmin; cat <= colors->cmax; cat++) {
00238         G_get_color(cat, &red, &grn, &blu, colors);
00239         fprintf(fd, "%d", red);
00240         if (red != grn || red != blu)
00241             fprintf(fd, " %d %d", grn, blu);
00242         fprintf(fd, "\n");
00243     }
00244 
00245     return 1;
00246 }
00247 
00248 static int format_min(char *str, double dval)
00249 {
00250     double dtmp;
00251 
00252     sprintf(str, "%.*f", PRECISION, dval);
00253     G_trim_decimal(str);
00254     sscanf(str, "%lf", &dtmp);
00255     if (dtmp != dval) {         /* if  no zeros after decimal point were trimmed */
00256         sprintf(str, "%.*f", PRECISION, dval - THRESHOLD);
00257         /* because precision is probably higher than PRECISION */
00258     }
00259 
00260     return 0;
00261 }
00262 
00263 static int format_max(char *str, double dval)
00264 {
00265     double dtmp;
00266 
00267     sprintf(str, "%.*f", PRECISION, dval);
00268     G_trim_decimal(str);
00269     sscanf(str, "%lf", &dtmp);
00270     if (dtmp != dval) {         /* if  no zeros after decimal point were trimmed */
00271         sprintf(str, "%.*f", PRECISION, dval + THRESHOLD);
00272         /* because precision is probably higher than PRECISION */
00273     }
00274 
00275     return 0;
00276 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines