4
#include <grass/raster.h>
6
#define LOOKUP_COLORS 2048
8
static void organize_lookup(struct Colors *, int);
9
static int organize_fp_lookup(struct Colors *, int);
10
static int double_comp(const void *, const void *);
12
void Rast__organize_colors(struct Colors *colors)
14
/* don't do anything if called recursively */
15
if (!colors->organizing) {
16
colors->organizing = 1;
18
organize_lookup(colors, 0);
19
organize_lookup(colors, 1);
21
organize_fp_lookup(colors, 0);
22
organize_fp_lookup(colors, 1);
24
colors->organizing = 0;
28
static int organize_fp_lookup(struct Colors *colors, int mod)
32
struct _Color_Info_ *cp;
33
struct _Color_Rule_ *rule;
36
cp = &colors->modular;
40
/* if one of the lookup tables exist, don't do anything */
41
if (cp->lookup.active || cp->fp_lookup.active)
46
cp->fp_lookup.vals = (DCELL *)
47
G_calloc(cp->n_rules * 2, sizeof(DCELL));
48
/* 2 endpoints for each rule */
49
cp->fp_lookup.rules = (struct _Color_Rule_ **)
50
G_calloc(cp->n_rules * 2, sizeof(struct _Color_Rule_ *));
52
/* get the list of DCELL values from set of all lows and highs
54
/* NOTE: if low==high in a rule, the value appears twice in a list
55
but if low==high of the previous, rule the value appears only once */
58
/* go through the list of rules from end to beginning,
59
because rules are sored in reverse order of reading,
60
and we want to read the in correct order, to ignore
61
the same values in the end of rule and beginning of next rule */
63
/* first go to the last rules */
64
for (rule = cp->rules; rule->next; rule = rule->next) ;
65
/* now traverse from the last to the first rule */
66
for (; rule; rule = rule->prev) {
67
/* check if the min is the same as previous maximum */
68
if (i == 0 || rule->low.value != cp->fp_lookup.vals[i - 1])
69
cp->fp_lookup.vals[i++] = rule->low.value;
70
cp->fp_lookup.vals[i++] = rule->high.value;
72
cp->fp_lookup.nalloc = i;
74
/* now sort the values */
75
qsort((char *)cp->fp_lookup.vals, cp->fp_lookup.nalloc,
76
sizeof(DCELL), &double_comp);
78
/* now find the rule to apply inbetween each 2 values in a list */
79
for (i = 0; i < cp->fp_lookup.nalloc - 1; i++) {
80
val = (cp->fp_lookup.vals[i] + cp->fp_lookup.vals[i + 1]) / 2.;
81
/* fprintf (stderr, "%lf %lf ", cp->fp_lookup.vals[i], cp->fp_lookup.vals[i+1]); */
83
for (rule = cp->rules; rule; rule = rule->next)
84
if (rule->low.value <= val && val <= rule->high.value)
86
/* if(rule) fprintf (stderr, "%d %lf %lf %d\n", i, rule->low.value, rule->high.value, rule);
87
else fprintf (stderr, "null\n");
89
cp->fp_lookup.rules[i] = rule;
91
cp->fp_lookup.active = 1;
96
static void organize_lookup(struct Colors *colors, int mod)
100
CELL cat[LOOKUP_COLORS];
101
struct _Color_Info_ *cp;
103
/* don't do anything if the color structure is float */
104
if (colors->is_float)
108
cp = &colors->modular;
112
if (cp->lookup.active)
115
n = (CELL) cp->max - (CELL) cp->min + 1;
116
if (n >= LOOKUP_COLORS || n <= 0)
120
for (i = 0; i < n; i++)
123
cp->lookup.nalloc = n;
124
cp->lookup.red = (unsigned char *)G_malloc(n);
125
cp->lookup.grn = (unsigned char *)G_malloc(n);
126
cp->lookup.blu = (unsigned char *)G_malloc(n);
127
cp->lookup.set = (unsigned char *)G_malloc(n);
129
G_zero(cp->lookup.set, n * sizeof(unsigned char));
130
Rast__lookup_colors((void *)cat,
131
cp->lookup.red, cp->lookup.grn, cp->lookup.blu,
132
cp->lookup.set, n, colors, mod, 1, CELL_TYPE);
134
cp->lookup.active = 1;
137
static int double_comp(const void *xx, const void *yy)
139
const DCELL *x = xx, *y = yy;