GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-bea8435a9e
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 
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 *);
11 
12 void 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 
28 static 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 
97 static 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 
139 static 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:95
#define G_malloc(n)
Definition: defs/gis.h:94
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:629
int CELL
Definition: gis.h:628
#define CELL_TYPE
Definition: raster.h:11
Definition: gis.h:686
int is_float
Definition: gis.h:690
struct _Color_Info_ fixed
Definition: gis.h:699
struct _Color_Info_ modular
Definition: gis.h:700
int organizing
Definition: gis.h:703
struct _Color_Info_::@3 lookup
unsigned char * red
Definition: gis.h:667
DCELL * vals
Definition: gis.h:676
struct _Color_Info_::@4 fp_lookup
DCELL max
Definition: gis.h:683
int active
Definition: gis.h:672
unsigned char * set
Definition: gis.h:670
unsigned char * blu
Definition: gis.h:669
struct _Color_Rule_ * rules
Definition: gis.h:663
unsigned char * grn
Definition: gis.h:668
DCELL min
Definition: gis.h:683
int n_rules
Definition: gis.h:664
int nalloc
Definition: gis.h:671
struct _Color_Rule_ * prev
Definition: gis.h:659
struct _Color_Rule_ * next
Definition: gis.h:658
struct _Color_Value_ low high
Definition: gis.h:657
DCELL value
Definition: gis.h:650
#define x