GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
color_look.c
Go to the documentation of this file.
1 #include <math.h>
2 #include <grass/gis.h>
3 
4 /* old 4.1 routine */
5 
38 int G_lookup_colors(const CELL * cell,
39  unsigned char *red, unsigned char *grn,
40  unsigned char *blu, unsigned char *set, int n,
41  struct Colors *colors)
42 {
43  G_lookup_c_raster_colors(cell, red, grn, blu, set, n, colors);
44 
45  return 0;
46 }
47 
48 /* I don't think it should exist, because it requires openning
49  of raster map every time Olga
50  int G_lookup_rgb_colors(map, mapset, r, g, b)
51  char *name, *mapset;
52  unsigned char *r, *g, *b;
53  {
54  RASTER_MAP_TYPE map_type;
55  void *rast;
56  ....
57  }
58  */
59 
60 
76 int G_lookup_c_raster_colors(const CELL * cell,
77  unsigned char *red, unsigned char *grn,
78  unsigned char *blu, unsigned char *set, int n,
79  struct Colors *colors)
80 {
81  G__organize_colors(colors); /* make sure the lookup tables are in place */
82 
83  G_zero((char *)set, n * sizeof(unsigned char));
84 
85  /* first lookup the fixed colors */
86  G__lookup_colors((void *)cell, red, grn, blu, set, n, colors, 0, 0,
87  CELL_TYPE);
88 
89  /* now lookup unset colors using the modular rules */
90  G__lookup_colors((void *)cell, red, grn, blu, set, n, colors, 1, 0,
91  CELL_TYPE);
92 
93  return 0;
94 }
95 
96 
118 int G_lookup_raster_colors(const void *raster,
119  unsigned char *red, unsigned char *grn,
120  unsigned char *blu, unsigned char *set, int n,
121  struct Colors *colors, RASTER_MAP_TYPE map_type)
122 {
123  G__organize_colors(colors); /* make sure the lookup tables are in place */
124  /* in case of float color rules, fp_lookup table is created */
125 
126  G_zero((char *)set, n * sizeof(unsigned char));
127 
128  /* first lookup the fixed colors */
129  G__lookup_colors(raster, red, grn, blu, set, n, colors, 0, 0, map_type);
130 
131  /* now lookup unset colors using the modular rules */
132  G__lookup_colors(raster, red, grn, blu, set, n, colors, 1, 0, map_type);
133 
134  return 0;
135 }
136 
137 
155 int G_lookup_f_raster_colors(const FCELL * fcell, unsigned char *red,
156  unsigned char *grn, unsigned char *blu,
157  unsigned char *set, int n, struct Colors *colors)
158 {
159  G__organize_colors(colors); /* make sure the lookup tables are in place */
160  /* in case of float color rules, fp_lookup table is created */
161 
162  G_zero((char *)set, n * sizeof(unsigned char));
163 
164  /* first lookup the fixed colors */
165  G__lookup_colors((void *)fcell, red, grn, blu, set, n, colors, 0, 0,
166  FCELL_TYPE);
167 
168  /* now lookup unset colors using the modular rules */
169  G__lookup_colors((void *)fcell, red, grn, blu, set, n, colors, 1, 0,
170  FCELL_TYPE);
171 
172  return 0;
173 }
174 
175 
193 int G_lookup_d_raster_colors(const DCELL * dcell, unsigned char *red,
194  unsigned char *grn, unsigned char *blu,
195  unsigned char *set, int n, struct Colors *colors)
196 {
197  G__organize_colors(colors); /* make sure the lookup tables are in place */
198  /* in case of float color rules, fp_lookup table is created */
199 
200  G_zero((char *)set, n * sizeof(unsigned char));
201 
202  /* first lookup the fixed colors */
203  G__lookup_colors((void *)dcell, red, grn, blu, set, n, colors, 0, 0,
204  DCELL_TYPE);
205 
206  /* now lookup unset colors using the modular rules */
207  G__lookup_colors((void *)dcell, red, grn, blu, set, n, colors, 1, 0,
208  DCELL_TYPE);
209 
210  return 0;
211 }
212 
213 
214 static int less_or_equal(double x, double y)
215 {
216  if (x <= y)
217  return 1;
218  else
219  return 0;
220 }
221 
222 static int less(double x, double y)
223 {
224  if (x < y)
225  return 1;
226  else
227  return 0;
228 }
229 
230 
231 int G__lookup_colors(const void *raster, unsigned char *red,
232  unsigned char *grn, unsigned char *blu,
233  unsigned char *set, int n, struct Colors *colors,
234  int mod, int rules_only, RASTER_MAP_TYPE data_type)
235 {
236  struct _Color_Info_ *cp;
237  struct _Color_Rule_ *rule;
238  DCELL dmin, dmax, val, dmod = 0L, shift;
239  CELL cat, min, max;
240  register const void *ptr, *last_ptr = NULL;
241  int invert;
242  int found, r, g, b;
243  int cell_type;
244  int lookup, max_ind, min_ind, try;
245  int (*lower) ();
246 
247  if (mod)
248  cp = &colors->modular;
249  else
250  cp = &colors->fixed;
251 
252  /* rules_only will be true only when called by G__organize_colors()
253  * when building the integer lookup talbes from the rules,
254  * so do not shift, invert, use lookup table or modulate cats.
255  * these operations will happen when lookup is called by user code
256  */
257  /* we want min, max for cp, not min, max overall */
258  dmin = cp->min;
259  dmax = cp->max;
260  min = (CELL) dmin;
261  max = (CELL) dmax + 1;
262 
263  cell_type = (data_type == CELL_TYPE);
264 
265  if (rules_only) {
266  shift = invert = lookup = mod = 0;
267  }
268  else {
269  if (mod) {
270  dmod = dmax - dmin;
271  /* for integers color table we make a gap of 1 in order
272  to make the same colors as before */
273  if (cell_type)
274  dmod += 1;
275  }
276 
277  shift = colors->shift;
278  invert = colors->invert;
279  lookup = cp->lookup.active;
280  }
281 
282  ptr = raster;
283 
284  for (; n-- > 0;
285  ptr =
286  G_incr_void_ptr(ptr, G_raster_size(data_type)), red++, grn++, blu++,
287  *set++ = found) {
288  /* if the cell is the same as last one, use the prev color values */
289  if (ptr != raster && G_raster_cmp(ptr, last_ptr, data_type) == 0) {
290  *red = *(red - 1);
291  *blu = *(blu - 1);
292  *grn = *(grn - 1);
293  found = *(set - 1);
294  last_ptr = ptr;
295  continue;
296  }
297  val = G_get_raster_value_d(ptr, data_type);
298  /* DEBUG fprintf (stderr, "val: %.4lf\n", val); */
299  last_ptr = ptr;
300 
301  if (*set) {
302  found = 1;
303  continue;
304  }
305 
306  if (G_is_null_value(ptr, data_type)) {
307  /* returns integers, not unsigned chars */
308  G_get_null_value_color(&r, &g, &b, colors);
309  *red = r;
310  *grn = g;
311  *blu = b;
312  found = 1;
313  continue;
314  }
315 
316  if (shift && val >= dmin && val <= dmax) {
317  val += shift;
318  while (val < dmin)
319  val += dmax - dmin + 1;
320  while (val > dmax)
321  val -= dmax - dmin + 1;
322  }
323 
324  /* invert non-null data around midpoint of range [min:max] */
325  if (invert)
326  val = dmin + dmax - val;
327 
328  if (mod) {
329  if (dmod > 0) {
330  val -= dmin;
331  while (val < 0)
332  val += dmod;
333  val = val - dmod * floor(val / dmod);
334  val += dmin;
335  }
336  else
337  val = dmin;
338  }
339 
340  cat = (CELL) val;
341 
342  found = 0;
343 
344  /* for non-null integers try to look them up in lookup table */
345  /* note: lookup table exists only for integer maps, and we also must
346  check if val is really integer */
347 
348  if (lookup && ((double)cat - val == 0.)) {
349  if (cat >= min && cat <= max) {
350  cat -= min;
351  if (cp->lookup.set[cat]) {
352  *red = cp->lookup.red[cat];
353  *grn = cp->lookup.grn[cat];
354  *blu = cp->lookup.blu[cat];
355  found = 1;
356  /*DEBUG
357  fprintf (stderr, "lookup %d %.2lf %d %d %d\n\n", cat, val, *red, *grn, *blu);
358  */
359  }
360  }
361  }
362 
363  if (found)
364  continue;
365 
366  /* if floating point lookup table is active, look up in there */
367  if (cp->fp_lookup.active) {
368  try = (cp->fp_lookup.nalloc - 1) / 2;
369  min_ind = 0;
370  max_ind = cp->fp_lookup.nalloc - 2;
371  while (1) {
372  /* when the rule for the interval is NULL, we exclude the end points.
373  when it exists, we include the end-points */
374  if (cp->fp_lookup.rules[try])
375  lower = less;
376  else
377  lower = less_or_equal;
378  /* DEBUG
379  fprintf (stderr, "%d %d %d %lf %lf %lf\n", min_ind, try, max_ind,
380  cp->fp_lookup.vals[try-1],
381  val,
382  cp->fp_lookup.vals[try]);
383  */
384 
385  if (lower(cp->fp_lookup.vals[try + 1], val)) { /* recurse to the second half */
386  min_ind = try + 1;
387  /* must be still < nalloc-1, since number is within the range */
388  try = (max_ind + min_ind) / 2;
389  if (min_ind > max_ind) {
390  rule = NULL;
391  break;
392  }
393  continue;
394  }
395  if (lower(val, cp->fp_lookup.vals[try])) { /* recurse to the second half */
396  max_ind = try - 1;
397  /* must be still >= 0, since number is within the range */
398  try = (max_ind + min_ind) / 2;
399  if (max_ind < min_ind) {
400  rule = NULL;
401  break;
402  }
403  continue;
404  }
405  rule = cp->fp_lookup.rules[try];
406  break;
407  }
408  }
409  else {
410  /* find the [low:high] rule that applies */
411  for (rule = cp->rules; rule; rule = rule->next) {
412  /* DEBUG
413  fprintf (stderr, "%.2lf %.2lf %.2lf\n",
414  val, rule->low.value, rule->high.value);
415  */
416  if (rule->low.value <= val && val <= rule->high.value)
417  break;
418  }
419  }
420 
421  /* if found, perform linear interpolation from low to high.
422  * else set colors to colors->undef or white if undef not set
423  */
424 
425  if (rule) {
426  G__interpolate_color_rule(val, red, grn, blu, rule);
427  found = 1;
428  }
429  if (!found) {
430  /* otherwise use default color */
431  G_get_default_color(&r, &g, &b, colors);
432  *red = r;
433  *grn = g;
434  *blu = b;
435  }
436  /* DEBUG
437  if (rule)
438  fprintf (stderr, "%.2lf %d %d %d %.2lf %d %d %d \n", rule->low.value , (int)rule->low.red, (int)rule->low.grn, (int)rule->low.blu, rule->high.value, (int)rule->high.red, (int)rule->high.grn, (int)rule->high.blu);
439  fprintf (stderr, "rule found %d %.2lf %d %d %d\n\n", cat, val, *red, *grn, *blu);
440  */
441  }
442 
443  return 0;
444 }
445 
446 int G__interpolate_color_rule(DCELL val, unsigned char *red,
447  unsigned char *grn, unsigned char *blu,
448  const struct _Color_Rule_ *rule)
449 {
450  DCELL delta;
451 
452  if ((delta = rule->high.value - rule->low.value)) {
453  val -= rule->low.value;
454 
455  *red =
456  (int)(val * (double)((int)rule->high.red - (int)rule->low.red) /
457  delta)
458  + (int)rule->low.red;
459  *grn =
460  (int)(val * (double)((int)rule->high.grn - (int)rule->low.grn) /
461  delta)
462  + (int)rule->low.grn;
463  *blu =
464  (int)(val * (double)((int)rule->high.blu - (int)rule->low.blu) /
465  delta)
466  + (int)rule->low.blu;
467  }
468  else {
469  *red = rule->low.red;
470  *grn = rule->low.grn;
471  *blu = rule->low.blu;
472  }
473 
474  return 0;
475 }
int G_lookup_raster_colors(const void *raster, unsigned char *red, unsigned char *grn, unsigned char *blu, unsigned char *set, int n, struct Colors *colors, RASTER_MAP_TYPE map_type)
If the cell_type is CELL_TYPE, calls G_lookup_colors((CELL *)cell, r, g, b, set, n, colors); If the cell_type is FCELL_TYPE, calls G_lookup_f_raster_colors(FCELL *)cell, r, g, b, set, n, colors); If the cell_type is DCELL_TYPE, calls G_lookup_d_raster_colors(DCELL *)cell, r, g, b, set, n, colors);.
Definition: color_look.c:118
float b
Definition: named_colr.c:8
int G_get_null_value_color(int *red, int *grn, int *blu, const struct Colors *colors)
Gets color for null value.
Definition: color_get.c:159
int G_lookup_colors(const CELL *cell, unsigned char *red, unsigned char *grn, unsigned char *blu, unsigned char *set, int n, struct Colors *colors)
lookup an array of colors
Definition: color_look.c:38
int G_lookup_f_raster_colors(const FCELL *fcell, unsigned char *red, unsigned char *grn, unsigned char *blu, unsigned char *set, int n, struct Colors *colors)
Converts the n floating-point values in the fcell array to their r,g,b color components. Embedded NULL-values are handled properly as well.
Definition: color_look.c:155
#define min(x, y)
Definition: draw2.c:68
float r
Definition: named_colr.c:8
int y
Definition: plot.c:34
#define max(x, y)
Definition: draw2.c:69
DCELL dmin
Definition: g3dcolor.c:53
void * G_incr_void_ptr(const void *ptr, const size_t size)
Advance void pointer.
Definition: gis/raster.c:33
int G_zero(void *buf, int i)
Zero out a buffer, buf, of length i.
Definition: gis/zero.c:29
int G_get_default_color(int *red, int *grn, int *blu, const struct Colors *colors)
Gets default color.
Definition: color_get.c:192
size_t G_raster_size(RASTER_MAP_TYPE data_type)
Returns size of a raster CELL in bytes.
Definition: alloc_cell.c:38
float g
Definition: named_colr.c:8
int G__organize_colors(struct Colors *colors)
Definition: color_org.c:11
int
Definition: g3dcolor.c:48
int G__interpolate_color_rule(DCELL val, unsigned char *red, unsigned char *grn, unsigned char *blu, const struct _Color_Rule_ *rule)
Definition: color_look.c:446
return NULL
Definition: dbfopen.c:1394
int G_raster_cmp(const void *v1, const void *v2, RASTER_MAP_TYPE data_type)
Compares raster values p and q.
Definition: gis/raster.c:54
CELL cat
Definition: g3dcats.c:90
int G_lookup_d_raster_colors(const DCELL *dcell, unsigned char *red, unsigned char *grn, unsigned char *blu, unsigned char *set, int n, struct Colors *colors)
Converts the n floating-point values in the dcell array to their r,g,b color components. Embedded NULL-values are handled properly as well.
Definition: color_look.c:193
int G__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)
Definition: color_look.c:231
DCELL dmax
Definition: g3dcolor.c:53
DCELL G_get_raster_value_d(const void *rast, RASTER_MAP_TYPE data_type)
Retrieves the value of type data_type from pointer p,.
Definition: gis/raster.c:313
int n
Definition: dataquad.c:291
string set
int G_is_null_value(const void *rast, RASTER_MAP_TYPE data_type)
If the data_type is CELL_TYPE, calls G_is_c_null_value ((CELL *) rast); If the data_type is FCELL_TYP...
Definition: null_val.c:207
int G_lookup_c_raster_colors(const CELL *cell, unsigned char *red, unsigned char *grn, unsigned char *blu, unsigned char *set, int n, struct Colors *colors)
The same as G_lookup_colors(cell, r, g, b, set, n, colors).
Definition: color_look.c:76