GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
color_org.c
Go to the documentation of this file.
1#include <stdlib.h>
2
3#include <grass/gis.h>
4#include <grass/raster.h>
5
6#define LOOKUP_COLORS 2048
7
8static void organize_lookup(struct Colors *, int);
9static int organize_fp_lookup(struct Colors *, int);
10static int double_comp(const void *, const void *);
11
12void Rast__organize_colors(struct Colors *colors)
13{
14 /* don't do anything if called recursively */
15 if (!colors->organizing) {
16 colors->organizing = 1;
17
18 organize_lookup(colors, 0);
19 organize_lookup(colors, 1);
20
21 organize_fp_lookup(colors, 0);
22 organize_fp_lookup(colors, 1);
23
24 colors->organizing = 0;
25 }
26}
27
28static int organize_fp_lookup(struct Colors *colors, int mod)
29{
30 int i;
31 DCELL val;
32 struct _Color_Info_ *cp;
33 struct _Color_Rule_ *rule;
34
35 if (mod)
36 cp = &colors->modular;
37 else
38 cp = &colors->fixed;
39
40 /* if one of the lookup tables exist, don't do anything */
41 if (cp->lookup.active || cp->fp_lookup.active)
42 return 1;
43 if (cp->n_rules == 0)
44 return 1;
45
46 cp->fp_lookup.vals = (DCELL *)G_calloc(cp->n_rules * 2, sizeof(DCELL));
47 /* 2 endpoints for each rule */
48 cp->fp_lookup.rules = (struct _Color_Rule_ **)G_calloc(
49 cp->n_rules * 2, sizeof(struct _Color_Rule_ *));
50
51 /* get the list of DCELL values from set of all lows and highs
52 of all rules */
53 /* NOTE: if low==high in a rule, the value appears twice in a list
54 but if low==high of the previous, rule the value appears only once */
55
56 i = 0;
57 /* go through the list of rules from end to beginning,
58 because rules are sored in reverse order of reading,
59 and we want to read the in correct order, to ignore
60 the same values in the end of rule and beginning of next rule */
61
62 /* first go to the last rules */
63 for (rule = cp->rules; rule->next; rule = rule->next)
64 ;
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;
71 }
72 cp->fp_lookup.nalloc = i;
73
74 /* now sort the values */
75 qsort((char *)cp->fp_lookup.vals, cp->fp_lookup.nalloc, sizeof(DCELL),
76 &double_comp);
77
78 /* now find the rule to apply between 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],
82 * cp->fp_lookup.vals[i+1]); */
83
84 for (rule = cp->rules; rule; rule = rule->next)
85 if (rule->low.value <= val && val <= rule->high.value)
86 break;
87 /* if(rule) fprintf (stderr, "%d %lf %lf %d\n", i, rule->low.value,
88 rule->high.value, rule); else fprintf (stderr, "null\n");
89 */
90 cp->fp_lookup.rules[i] = rule;
91 }
92 cp->fp_lookup.active = 1;
93
94 return 0;
95}
96
97static void organize_lookup(struct Colors *colors, int mod)
98{
99 int i, n;
100 CELL x;
101 CELL cat[LOOKUP_COLORS];
102 struct _Color_Info_ *cp;
103
104 /* don't do anything if the color structure is float */
105 if (colors->is_float)
106 return;
107
108 if (mod)
109 cp = &colors->modular;
110 else
111 cp = &colors->fixed;
112
113 if (cp->lookup.active)
114 return;
115
116 n = (CELL)cp->max - (CELL)cp->min + 1;
117 if (n >= LOOKUP_COLORS || n <= 0)
118 return;
119
120 x = (CELL)cp->min;
121 for (i = 0; i < n; i++)
122 cat[i] = x++;
123 ;
124
125 cp->lookup.nalloc = n;
126 cp->lookup.red = (unsigned char *)G_malloc(n);
127 cp->lookup.grn = (unsigned char *)G_malloc(n);
128 cp->lookup.blu = (unsigned char *)G_malloc(n);
129 cp->lookup.set = (unsigned char *)G_malloc(n);
130
131 G_zero(cp->lookup.set, n * sizeof(unsigned char));
132 Rast__lookup_colors((void *)cat, cp->lookup.red, cp->lookup.grn,
133 cp->lookup.blu, cp->lookup.set, n, colors, mod, 1,
134 CELL_TYPE);
135
136 cp->lookup.active = 1;
137}
138
139static int double_comp(const void *xx, const void *yy)
140{
141 const DCELL *x = xx, *y = yy;
142
143 if (*x < *y)
144 return -1;
145 else if (*x == *y)
146 return 0;
147 else
148 return 1;
149}
void Rast__organize_colors(struct Colors *colors)
Definition color_org.c:12
#define LOOKUP_COLORS
Definition color_org.c:6
void G_zero(void *, int)
Zero out a buffer, buf, of length i.
Definition gis/zero.c:23
#define G_calloc(m, n)
Definition defs/gis.h:140
#define G_malloc(n)
Definition defs/gis.h:139
void Rast__lookup_colors(const void *, unsigned char *, unsigned char *, unsigned char *, unsigned char *, int, struct Colors *, int, int, RASTER_MAP_TYPE)
Lookup an array of colors.
Definition color_look.c:195
double DCELL
Definition gis.h:635
int CELL
Definition gis.h:634
#define CELL_TYPE
Definition raster.h:11
Definition gis.h:692
int is_float
Definition gis.h:696
struct _Color_Info_ fixed
Definition gis.h:705
struct _Color_Info_ modular
Definition gis.h:706
int organizing
Definition gis.h:709
struct _Color_Rule_ * prev
Definition gis.h:665
struct _Color_Rule_ * next
Definition gis.h:664
struct _Color_Value_ low high
Definition gis.h:663
#define x