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
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
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
00050 cp->fp_lookup.rules = (struct _Color_Rule_ **)
00051 G_calloc(cp->n_rules * 2 , sizeof(struct _Color_Rule_ *));
00052
00053
00054
00055
00056
00057
00058 i=0;
00059
00060
00061
00062
00063
00064
00065 for (rule = cp->rules; rule->next; rule = rule->next);
00066
00067 for (; rule; rule = rule->prev)
00068 {
00069
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
00077 qsort((char *) cp->fp_lookup.vals, cp->fp_lookup.nalloc,
00078 sizeof(DCELL), &double_comp);
00079
00080
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
00085
00086 for (rule = cp->rules; rule; rule = rule->next)
00087 if (rule->low.value <= val && val <= rule->high.value)
00088 break;
00089
00090
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
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