GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
color_read.c
Go to the documentation of this file.
1 
2 /**********************************************************************
3  *
4  * G_read_colors (name, mapset, colors)
5  * char *name name of map
6  * char *mapset mapset that map belongs to
7  * struct Colors *colors structure to hold color info
8  *
9  * Reads the color information associated with map layer "map"
10  * in mapset "mapset" into the structure "colors".
11  *
12  * returns: 1 if successful
13  * 0 if missing, but default colors generated
14  * -1 on fail
15  *
16  * note: If a secondary color file for map name "name" exists
17  * in the current project, that color file is read. This
18  * allows the user to define their own color lookup tables
19  * for cell maps found in other mapsets.
20  *
21  * Warning message is printed if the color file is
22  * missing or invalid.
23  *********************************************************************/
24 
25 #include <grass/gis.h>
26 #include <grass/glocale.h>
27 #include <string.h>
28 
29 static int read_colors(const char *, const char *, const char *,
30  struct Colors *);
31 static int read_new_colors(FILE *, struct Colors *);
32 static int read_old_colors(FILE *, struct Colors *);
33 
34 
62 int G_read_colors(const char *name, const char *mapset, struct Colors *colors)
63 {
64  int fp;
65  char buf[GNAME_MAX];
66  char *err;
67  char xname[GNAME_MAX];
68  struct Range range;
69  struct FPRange drange;
70  CELL min, max;
71  DCELL dmin, dmax;
72 
73  fp = G_raster_map_is_fp(name, mapset);
74  G_init_colors(colors);
75 
76  strcpy(xname, name);
77  mapset = G_find_cell(xname, mapset);
78  name = xname;
79 
80  if (fp)
81  G_mark_colors_as_fp(colors);
82 
83  /* first look for secondary color table in current mapset */
84  sprintf(buf, "colr2/%s", mapset);
85  if (read_colors(buf, name, G_mapset(), colors) >= 0)
86  return 1;
87 
88  /* now look for the regular color table */
89  switch (read_colors("colr", name, mapset, colors)) {
90  case -2:
91  if (!fp) {
92  if (G_read_range(name, mapset, &range) >= 0) {
93  G_get_range_min_max(&range, &min, &max);
94  if (!G_is_c_null_value(&min) && !G_is_c_null_value(&max))
95  G_make_rainbow_colors(colors, min, max);
96  return 0;
97  }
98  }
99  else {
100  if (G_read_fp_range(name, mapset, &drange) >= 0) {
101  G_get_fp_range_min_max(&drange, &dmin, &dmax);
102  if (!G_is_d_null_value(&dmin) && !G_is_d_null_value(&dmax))
103  G_make_rainbow_fp_colors(colors, dmin, dmax);
104  return 0;
105  }
106  }
107  err = "missing";
108  break;
109  case -1:
110  err = "invalid";
111  break;
112  default:
113  return 1;
114  }
115 
116  G_warning(_("color support for [%s] in mapset [%s] %s"), name, mapset,
117  err);
118  return -1;
119 }
120 
121 static int read_colors(const char *element, const char *name,
122  const char *mapset, struct Colors *colors)
123 {
124  FILE *fd;
125  int stat;
126  char buf[1024];
127 
128  if (!(fd = G_fopen_old(element, name, mapset)))
129  return -2;
130 
131  /*
132  * first line in 4.0 color files is %
133  * otherwise it is pre 4.0
134  */
135  if (fgets(buf, sizeof buf, fd) == NULL) {
136  fclose(fd);
137  return -1;
138  }
139  fseek(fd, 0L, 0);
140 
141  G_strip(buf);
142  if (*buf == '%') { /* 4.0 format */
143  stat = read_new_colors(fd, colors);
144  colors->version = 0; /* 4.0 format */
145  }
146  else {
147  stat = read_old_colors(fd, colors);
148  colors->version = -1; /* pre 4.0 format */
149  }
150  fclose(fd);
151  return stat;
152 }
153 
154 /* parse input lines with the following formats
155  * val1:r:g:b val2:r:g:b
156  * val:r:g:b (implies cat1==cat2)
157  *
158  * r:g:b can be just a single grey level
159  * cat1:x cat2:y
160  * cat:x
161  *
162  * optional lines are
163  * invert invert color table
164  * shift:n where n is the amount to shift the color table
165  * nv:r:g:b color to use for NULL values
166  * *:r:g:b color to use for undefined (beyond color rules)
167  */
168 static int read_new_colors(FILE * fd, struct Colors *colors)
169 {
170  double val1, val2;
171  long cat1, cat2;
172  int r1, g1, b1;
173  int r2, g2, b2;
174  char buf[1024];
175  char word1[256], word2[256];
176  int n, fp_rule;
177  int null, undef;
178  int modular;
179  DCELL shift;
180 
181  if (fgets(buf, sizeof buf, fd) == NULL)
182  return -1;
183  G_strip(buf);
184 
185  if (sscanf(buf + 1, "%lf %lf", &val1, &val2) == 2)
186  G_set_d_color_range((DCELL) val1, (DCELL) val2, colors);
187 
188  modular = 0;
189  while (fgets(buf, sizeof buf, fd)) {
190  null = undef = fp_rule = 0;
191  *word1 = *word2 = 0;
192  n = sscanf(buf, "%s %s", word1, word2);
193  if (n < 1)
194  continue;
195 
196  if (sscanf(word1, "shift:%lf", &shift) == 1
197  || (strcmp(word1, "shift:") == 0 &&
198  sscanf(word2, "%lf", &shift) == 1)) {
199  G_shift_d_colors(shift, colors);
200  continue;
201  }
202  if (strcmp(word1, "invert") == 0) {
203  G_invert_colors(colors);
204  continue;
205  }
206  if (strcmp(word1, "%%") == 0) {
207  modular = !modular;
208  continue;
209  }
210 
211  switch (sscanf(word1, "nv:%d:%d:%d", &r1, &g1, &b1)) {
212  case 1:
213  null = 1;
214  b1 = g1 = r1;
215  break;
216  case 3:
217  null = 1;
218  break;
219  }
220  if (!null)
221  switch (sscanf(word1, "*:%d:%d:%d", &r1, &g1, &b1)) {
222  case 1:
223  undef = 1;
224  b1 = g1 = r1;
225  break;
226  case 3:
227  undef = 1;
228  break;
229  }
230  if (!null && !undef)
231  switch (sscanf(word1, "%ld:%d:%d:%d", &cat1, &r1, &g1, &b1)) {
232  case 2:
233  b1 = g1 = r1;
234  break;
235  case 4:
236  break;
237  default:
238  if (sscanf(word1, "%lf:%d:%d:%d", &val1, &r1, &g1, &b1) == 4)
239  fp_rule = 1;
240  else if (sscanf(word1, "%lf:%d", &val1, &r1) == 2) {
241  fp_rule = 1;
242  b1 = g1 = r1;
243  }
244  else
245  continue; /* other lines are ignored */
246  }
247  if (n == 2) {
248  switch (sscanf(word2, "%ld:%d:%d:%d", &cat2, &r2, &g2, &b2)) {
249  case 2:
250  b2 = g2 = r2;
251  if (fp_rule)
252  val2 = (DCELL) cat2;
253  break;
254  case 4:
255  if (fp_rule)
256  val2 = (DCELL) cat2;
257  break;
258  default:
259  if (sscanf(word2, "%lf:%d:%d:%d", &val2, &r2, &g2, &b2) == 4) {
260  if (!fp_rule)
261  val1 = (DCELL) cat1;
262  fp_rule = 1;
263  }
264  else if (sscanf(word2, "%lf:%d", &val2, &r2) == 2) {
265  if (!fp_rule)
266  val1 = (DCELL) cat1;
267  fp_rule = 1;
268  b2 = g2 = r2;
269  }
270  else
271  continue; /* other lines are ignored */
272  }
273  }
274  else {
275  if (!fp_rule)
276  cat2 = cat1;
277  else
278  val2 = val1;
279  r2 = r1;
280  g2 = g1;
281  b2 = b1;
282  }
283  if (null)
284  G_set_null_value_color(r1, g1, b1, colors);
285  else if (undef)
286  G_set_default_color(r1, g1, b1, colors);
287 
288  else if (modular) {
289  if (fp_rule)
290  G_add_modular_d_raster_color_rule((DCELL *) & val1, r1, g1,
291  b1, (DCELL *) & val2, r2,
292  g2, b2, colors);
293  else
294  G_add_modular_color_rule((CELL) cat1, r1, g1, b1,
295  (CELL) cat2, r2, g2, b2, colors);
296  }
297  else {
298  if (fp_rule)
299  G_add_d_raster_color_rule((DCELL *) & val1, r1, g1, b1,
300  (DCELL *) & val2, r2, g2, b2,
301  colors);
302  else
303  G_add_color_rule((CELL) cat1, r1, g1, b1,
304  (CELL) cat2, r2, g2, b2, colors);
305  }
306  /*
307  fprintf (stderr, "adding rule %d=%.2lf %d %d %d %d=%.2lf %d %d %d\n", cat1,val1, r1, g1, b1, cat2, val2, r2, g2, b2);
308  */
309  }
310  return 1;
311 }
312 
313 static int read_old_colors(FILE * fd, struct Colors *colors)
314 {
315  char buf[256];
316  long n;
317  long min;
318  float red_f, grn_f, blu_f;
319  int red, grn, blu;
320  int old;
321  int zero;
322 
323  G_init_colors(colors);
324  /*
325  * first line in pre 3.0 color files is number of colors - ignore
326  * otherwise it is #min first color, and the next line is for color 0
327  */
328  if (fgets(buf, sizeof buf, fd) == NULL)
329  return -1;
330 
331  G_strip(buf);
332  if (*buf == '#') { /* 3.0 format */
333  old = 0;
334  if (sscanf(buf + 1, "%ld", &min) != 1) /* first color */
335  return -1;
336  zero = 1;
337  }
338  else {
339  old = 1;
340  min = 0;
341  zero = 0;
342  }
343 
344  colors->cmin = min;
345  n = min;
346  while (fgets(buf, sizeof buf, fd)) {
347  if (old) {
348  if (sscanf(buf, "%f %f %f", &red_f, &grn_f, &blu_f) != 3)
349  return -1;
350 
351  red = 256 * red_f;
352  grn = 256 * grn_f;
353  blu = 256 * blu_f;
354  }
355  else {
356  switch (sscanf(buf, "%d %d %d", &red, &grn, &blu)) {
357  case 1:
358  blu = grn = red;
359  break;
360  case 2:
361  blu = grn;
362  break;
363  case 3:
364  break;
365  default:
366  return -1;
367  }
368  }
369  if (zero) {
370  G__insert_color_into_lookup((CELL) 0, red, grn, blu,
371  &colors->fixed);
372  zero = 0;
373  }
374  else
375  G__insert_color_into_lookup((CELL) n++, red, grn, blu,
376  &colors->fixed);
377  }
378  colors->cmax = n - 1;
379 
380  return 0;
381 }
382 
383 
396 int G_mark_colors_as_fp(struct Colors *colors)
397 {
398  colors->is_float = 1;
399 
400  return 0;
401 }
char * G_mapset(void)
current mapset name
Definition: mapset.c:31
int G_is_c_null_value(const CELL *cellVal)
Returns 1 if cell is NULL, 0 otherwise. This will test if the value cell is the largest int...
Definition: null_val.c:244
sprintf(buf2,"%s", G3D_CATS_ELEMENT)
int G_set_default_color(int red, int grn, int blu, struct Colors *colors)
Sets the default color (in colors) to r,g,b. This is the color for values which do not have an explic...
Definition: color_set.c:82
int G_set_null_value_color(int red, int grn, int blu, struct Colors *colors)
Sets the color (in colors) for the NULL-value to r,g,b.
Definition: color_set.c:59
int G_add_modular_color_rule(CELL cat1, int r1, int g1, int b1, CELL cat2, int r2, int g2, int b2, struct Colors *colors)
Add modular color rule.
Definition: color_rule.c:310
DCELL val1
Definition: g3dcats.c:91
int G_add_d_raster_color_rule(const DCELL *val1, int r1, int g1, int b1, const DCELL *val2, int r2, int g2, int b2, struct Colors *colors)
Adds the floating-point rule (DCELL version)
Definition: color_rule.c:41
FILE * fd
Definition: g3dcolor.c:368
string name
Definition: render.py:1314
#define min(x, y)
Definition: draw2.c:68
const char * err
Definition: g3dcolor.c:50
int G_read_colors(const char *name, const char *mapset, struct Colors *colors)
read map layer color table
Definition: color_read.c:62
DCELL dmin
Definition: g3dcolor.c:53
#define max(x, y)
Definition: draw2.c:69
int G_read_range(const char *name, const char *mapset, struct Range *range)
read raster range
Definition: range.c:226
int G_raster_map_is_fp(const char *name, const char *mapset)
Check if raster map is floating-point.
Definition: opencell.c:969
int G_invert_colors(struct Colors *colors)
Definition: color_invrt.c:3
DCELL val2
Definition: g3dcats.c:91
int G_get_range_min_max(const struct Range *range, CELL *min, CELL *max)
get range min and max
Definition: range.c:608
int G_make_rainbow_colors(struct Colors *colors, CELL min, CELL max)
make rainbow colors
Definition: color_compat.c:97
int stat
Definition: g3dcolor.c:369
G_mark_colors_as_fp(colors)
char * G_find_cell(char *name, const char *mapset)
find a raster map
Definition: find_cell.c:63
int G_is_d_null_value(const DCELL *dcellVal)
Returns 1 if dcell is NULL, 0 otherwise. This will test if the value dcell is a NaN. Same test as in G_is_f_null_value().
Definition: null_val.c:306
int G_strip(char *buf)
Removes all leading and trailing white space from string.
Definition: strings.c:389
int G_set_d_color_range(DCELL min, DCELL max, struct Colors *colors)
Definition: color_range.c:18
int G_make_rainbow_fp_colors(struct Colors *colors, DCELL min, DCELL max)
Definition: color_compat.c:102
int G__insert_color_into_lookup(CELL cat, int red, int grn, int blu, struct _Color_Info_ *cp)
Definition: color_insrt.c:12
char buf[GNAME_MAX+sizeof(G3D_DIRECTORY)+2]
Definition: g3drange.c:62
return NULL
Definition: dbfopen.c:1394
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
int G_get_fp_range_min_max(const struct FPRange *range, DCELL *min, DCELL *max)
Extract the min/max from the range structure r. If the range structure has no defined min/max (first!...
Definition: range.c:667
fclose(fd)
int G_add_color_rule(CELL cat1, int r1, int g1, int b1, CELL cat2, int r2, int g2, int b2, struct Colors *colors)
Set colors rules.
Definition: color_rule.c:165
int G_read_fp_range(const char *name, const char *mapset, struct FPRange *drange)
Read the floating point range file f_range. This file is written in binary using XDR format...
Definition: range.c:139
int old
Definition: g3dcats.c:92
int G_shift_d_colors(DCELL shift, struct Colors *colors)
Definition: color_shift.c:9
FILE * G_fopen_old(const char *element, const char *name, const char *mapset)
Open a database file for reading.
Definition: gis/open.c:226
DCELL dmax
Definition: g3dcolor.c:53
int G_add_modular_d_raster_color_rule(const DCELL *val1, int r1, int g1, int b1, const DCELL *val2, int r2, int g2, int b2, struct Colors *colors)
Add modular color rule (DCELL version)
Definition: color_rule.c:187
G_init_colors(colors)
char xname[512]
Definition: g3dcats.c:89
int n
Definition: dataquad.c:291