GRASS Programmer's Manual 6.4.1(2011)
color_org.c
Go to the documentation of this file.
00001 #include <grass/gis.h>
00002 #include <stdlib.h>
00003 
00004 #define LOOKUP_COLORS 2048
00005 
00006 static int organizing = 0;
00007 static int organize_lookup(struct Colors *, int);
00008 static int organize_fp_lookup(struct Colors *, int);
00009 static int double_comp(const void *, const void *);
00010 
00011 int G__organize_colors(struct Colors *colors)
00012 {
00013     /* don't do anything if called recursively */
00014     if (!organizing) {
00015         organizing = 1;
00016 
00017         organize_lookup(colors, 0);
00018         organize_lookup(colors, 1);
00019 
00020         organize_fp_lookup(colors, 0);
00021         organize_fp_lookup(colors, 1);
00022 
00023         organizing = 0;
00024     }
00025 
00026     return 0;
00027 }
00028 
00029 static int organize_fp_lookup(struct Colors *colors, int mod)
00030 {
00031     int i;
00032     DCELL val;
00033     struct _Color_Info_ *cp;
00034     struct _Color_Rule_ *rule;
00035 
00036     if (mod)
00037         cp = &colors->modular;
00038     else
00039         cp = &colors->fixed;
00040 
00041     /* if one of the lookup tables exist, don't do anything */
00042     if (cp->lookup.active || cp->fp_lookup.active)
00043         return 1;
00044     if (cp->n_rules == 0)
00045         return 1;
00046 
00047     cp->fp_lookup.vals = (DCELL *)
00048         G_calloc(cp->n_rules * 2, sizeof(DCELL));
00049     /* 2 endpoints for each rule */
00050     cp->fp_lookup.rules = (struct _Color_Rule_ **)
00051         G_calloc(cp->n_rules * 2, sizeof(struct _Color_Rule_ *));
00052 
00053     /* get the list of DCELL values from set of all lows and highs
00054        of all rules */
00055     /* NOTE: if low==high in a rule, the value appears twice in a list
00056        but if low==high of the previous, rule the value appears only once */
00057 
00058     i = 0;
00059     /* go through the list of rules from end to beginning, 
00060        because rules are sored in reverse order of reading,
00061        and we want to read the in correct order, to ignore
00062        the same values in the end of rule and beginning of next rule */
00063 
00064     /* first go to the last rules */
00065     for (rule = cp->rules; rule->next; rule = rule->next) ;
00066     /* now traverse from the last to the first rule */
00067     for (; rule; rule = rule->prev) {
00068         /* check if the min is the same as previous maximum */
00069         if (i == 0 || rule->low.value != cp->fp_lookup.vals[i - 1])
00070             cp->fp_lookup.vals[i++] = rule->low.value;
00071         cp->fp_lookup.vals[i++] = rule->high.value;
00072     }
00073     cp->fp_lookup.nalloc = i;
00074 
00075     /* now sort the values */
00076     qsort((char *)cp->fp_lookup.vals, cp->fp_lookup.nalloc,
00077           sizeof(DCELL), &double_comp);
00078 
00079     /* now find the rule to apply inbetween each 2 values in a list */
00080     for (i = 0; i < cp->fp_lookup.nalloc - 1; i++) {
00081         val = (cp->fp_lookup.vals[i] + cp->fp_lookup.vals[i + 1]) / 2.;
00082         /* fprintf (stderr, "%lf %lf ", cp->fp_lookup.vals[i], cp->fp_lookup.vals[i+1]); */
00083 
00084         for (rule = cp->rules; rule; rule = rule->next)
00085             if (rule->low.value <= val && val <= rule->high.value)
00086                 break;
00087         /* if(rule) fprintf (stderr, "%d %lf %lf %d\n", i, rule->low.value, rule->high.value, rule);
00088            else fprintf (stderr, "null\n");
00089          */
00090         cp->fp_lookup.rules[i] = rule;
00091     }
00092     cp->fp_lookup.active = 1;
00093 
00094     return 0;
00095 }
00096 
00097 static int organize_lookup(struct Colors *colors, int mod)
00098 {
00099     int i, n;
00100     CELL x;
00101     CELL cat[LOOKUP_COLORS];
00102     struct _Color_Info_ *cp;
00103 
00104     /* don't do anything if the color structure is float */
00105     if (colors->is_float)
00106         return 0;
00107 
00108     if (mod)
00109         cp = &colors->modular;
00110     else
00111         cp = &colors->fixed;
00112 
00113     if (cp->lookup.active)
00114         return 0;
00115 
00116     n = (CELL) cp->max - (CELL) cp->min + 1;
00117     if (n >= LOOKUP_COLORS || n <= 0)
00118         return 0;
00119 
00120     x = (CELL) cp->min;
00121     for (i = 0; i < n; i++)
00122         cat[i] = x++;;
00123 
00124     cp->lookup.nalloc = n;
00125     cp->lookup.red = (unsigned char *)G_malloc(n);
00126     cp->lookup.grn = (unsigned char *)G_malloc(n);
00127     cp->lookup.blu = (unsigned char *)G_malloc(n);
00128     cp->lookup.set = (unsigned char *)G_malloc(n);
00129 
00130     G_zero(cp->lookup.set, n * sizeof(unsigned char));
00131     G__lookup_colors((void *)cat,
00132                      cp->lookup.red, cp->lookup.grn, cp->lookup.blu,
00133                      cp->lookup.set, n, colors, mod, 1, CELL_TYPE);
00134 
00135     cp->lookup.active = 1;
00136 
00137     return 0;
00138 }
00139 
00140 static int double_comp(const void *xx, const void *yy)
00141 {
00142     const DCELL *x = xx, *y = yy;
00143 
00144     if (*x < *y)
00145         return -1;
00146     else if (*x == *y)
00147         return 0;
00148     else
00149         return 1;
00150 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines