GRASS GIS 7 Programmer's Manual  7.5.svn(2018)-r72274
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 *)
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_ *));
51 
52  /* get the list of DCELL values from set of all lows and highs
53  of all rules */
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 */
56 
57  i = 0;
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 */
62 
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;
71  }
72  cp->fp_lookup.nalloc = i;
73 
74  /* now sort the values */
75  qsort((char *)cp->fp_lookup.vals, cp->fp_lookup.nalloc,
76  sizeof(DCELL), &double_comp);
77 
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]); */
82 
83  for (rule = cp->rules; rule; rule = rule->next)
84  if (rule->low.value <= val && val <= rule->high.value)
85  break;
86  /* if(rule) fprintf (stderr, "%d %lf %lf %d\n", i, rule->low.value, rule->high.value, rule);
87  else fprintf (stderr, "null\n");
88  */
89  cp->fp_lookup.rules[i] = rule;
90  }
91  cp->fp_lookup.active = 1;
92 
93  return 0;
94 }
95 
96 static void organize_lookup(struct Colors *colors, int mod)
97 {
98  int i, n;
99  CELL x;
101  struct _Color_Info_ *cp;
102 
103  /* don't do anything if the color structure is float */
104  if (colors->is_float)
105  return;
106 
107  if (mod)
108  cp = &colors->modular;
109  else
110  cp = &colors->fixed;
111 
112  if (cp->lookup.active)
113  return;
114 
115  n = (CELL) cp->max - (CELL) cp->min + 1;
116  if (n >= LOOKUP_COLORS || n <= 0)
117  return;
118 
119  x = (CELL) cp->min;
120  for (i = 0; i < n; i++)
121  cat[i] = x++;;
122 
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);
128 
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);
133 
134  cp->lookup.active = 1;
135 }
136 
137 static int double_comp(const void *xx, const void *yy)
138 {
139  const DCELL *x = xx, *y = yy;
140 
141  if (*x < *y)
142  return -1;
143  else if (*x == *y)
144  return 0;
145  else
146  return 1;
147 }
#define CELL_TYPE
Definition: raster.h:11
struct _Color_Info_ fixed
Definition: gis.h:657
CELL cat
Definition: raster3d/cats.c:82
unsigned char * blu
Definition: gis.h:625
unsigned char * red
Definition: gis.h:623
double DCELL
Definition: gis.h:581
struct _Color_Value_ low high
Definition: gis.h:611
struct _Color_Rule_ * next
Definition: gis.h:612
unsigned char * grn
Definition: gis.h:624
int is_float
Definition: gis.h:648
int nalloc
Definition: gis.h:627
unsigned char * set
Definition: gis.h:626
#define x
DCELL * vals
Definition: gis.h:633
#define LOOKUP_COLORS
Definition: color_org.c:6
DCELL min
Definition: gis.h:640
int organizing
Definition: gis.h:661
for(cat=0;;cat++)
DCELL value
Definition: gis.h:603
void Rast__organize_colors(struct Colors *colors)
Definition: color_org.c:12
Definition: gis.h:643
int active
Definition: gis.h:628
int n_rules
Definition: gis.h:619
void Rast__lookup_colors(const void *raster, unsigned char *red, unsigned char *grn, unsigned char *blu, unsigned char *set, int n, struct Colors *colors, int mod, int rules_only, RASTER_MAP_TYPE data_type)
Lookup an array of colors.
Definition: color_look.c:195
int CELL
Definition: gis.h:580
struct _Color_Info_::@3 lookup
struct _Color_Info_ modular
Definition: gis.h:658
struct _Color_Info_::@4 fp_lookup
DCELL max
Definition: gis.h:640
void G_zero(void *buf, int i)
Zero out a buffer, buf, of length i.
Definition: gis/zero.c:23
struct _Color_Rule_ * prev
Definition: gis.h:613
struct _Color_Rule_ * rules
Definition: gis.h:618