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     {
00016         organizing = 1;
00017 
00018         organize_lookup (colors, 0);
00019         organize_lookup (colors, 1);
00020 
00021         organize_fp_lookup (colors, 0);
00022         organize_fp_lookup (colors, 1);
00023 
00024         organizing = 0;
00025     }
00026 
00027     return 0;
00028 }
00029 
00030 static int organize_fp_lookup (struct Colors *colors, int mod)
00031 {
00032     int i;
00033     DCELL val;
00034     struct _Color_Info_ *cp;
00035     struct _Color_Rule_ *rule;
00036 
00037     if (mod)
00038         cp = &colors->modular;
00039     else
00040         cp = &colors->fixed;
00041 
00042     /* if one of the lookup tables exist, don't do anything */
00043     if(cp->lookup.active || cp->fp_lookup.active)
00044         return 1;
00045     if(cp->n_rules == 0) 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     {
00069       /* check if the min is the same as previous maximum */
00070       if(i==0 || rule->low.value != cp->fp_lookup.vals[i-1])
00071          cp->fp_lookup.vals[i++] = rule->low.value;
00072       cp->fp_lookup.vals[i++] = rule->high.value;
00073     }
00074     cp->fp_lookup.nalloc = i;
00075 
00076     /* now sort the values */
00077     qsort((char *) cp->fp_lookup.vals, cp->fp_lookup.nalloc, 
00078                     sizeof(DCELL), &double_comp);
00079 
00080     /* now find the rule to apply inbetween each 2 values in a list */
00081     for(i=0;i<cp->fp_lookup.nalloc-1;i++)
00082     {
00083        val = (cp->fp_lookup.vals[i] + cp->fp_lookup.vals[i+1])/2.;
00084        /* fprintf (stderr, "%lf %lf ", cp->fp_lookup.vals[i], cp->fp_lookup.vals[i+1]);*/
00085 
00086        for (rule = cp->rules; rule; rule = rule->next)
00087           if (rule->low.value <= val && val <= rule->high.value)
00088                 break;
00089        /* if(rule) fprintf (stderr, "%d %lf %lf %d\n", i, rule->low.value, rule->high.value, rule);
00090        else fprintf (stderr, "null\n");
00091        */
00092        cp->fp_lookup.rules[i] = rule;
00093     }
00094     cp->fp_lookup.active = 1;
00095 
00096     return 0;
00097 }
00098   
00099 static int organize_lookup (struct Colors *colors, int mod)
00100 {
00101     int i,n;
00102     CELL x;
00103     CELL cat[LOOKUP_COLORS];
00104     struct _Color_Info_ *cp;
00105 
00106     /* don't do anything if the color structure is float */
00107     if(colors->is_float) return 0;
00108 
00109     if (mod)
00110         cp = &colors->modular;
00111     else
00112         cp = &colors->fixed;
00113 
00114     if (cp->lookup.active)
00115         return 0;
00116 
00117     n = (CELL )cp->max - (CELL )cp->min + 1;
00118     if (n >= LOOKUP_COLORS || n <= 0)
00119         return 0;
00120 
00121     x = (CELL ) cp->min;
00122     for (i=0; i < n; i++)
00123         cat[i] = x++;;
00124     
00125     cp->lookup.nalloc = n;
00126     cp->lookup.red = (unsigned char *) G_malloc(n);
00127     cp->lookup.grn = (unsigned char *) G_malloc(n);
00128     cp->lookup.blu = (unsigned char *) G_malloc(n);
00129     cp->lookup.set = (unsigned char *) G_malloc(n);
00130 
00131     G_zero (cp->lookup.set, n*sizeof(unsigned char));
00132         G__lookup_colors ((void *) cat, 
00133             cp->lookup.red, cp->lookup.grn, cp->lookup.blu, cp->lookup.set,
00134             n, colors, mod, 1, CELL_TYPE);
00135 
00136     cp->lookup.active = 1;
00137 
00138     return 0;
00139 }
00140 
00141 static int double_comp (const void *xx, const void *yy)
00142 {
00143     const DCELL *x = xx, *y = yy;
00144     if(*x < *y) return -1;
00145     else if(*x==*y) return 0;
00146     else return 1;
00147 }
00148 

Generated on Wed Dec 19 14:59:05 2007 for GRASS by  doxygen 1.5.4