color_write.c

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

Generated on Sat Jul 22 22:06:14 2006 for GRASS by  doxygen 1.4.7