GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
g3dcolor.c
Go to the documentation of this file.
1 
2 
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <sys/types.h>
7 #include <unistd.h>
8 #include <rpc/types.h>
9 #include <rpc/xdr.h>
10 #include <grass/gis.h>
11 #include "G3d_intern.h"
12 
13 static int read_colors(const char *, const char *, const char *,
14  struct Colors *);
15 static int read_new_colors(FILE *, struct Colors *);
16 static int read_old_colors(FILE *, struct Colors *);
17 
18 /*---------------------------------------------------------------------------*/
19 
20 int G3d_removeColor(const char *name)
21  /* adapted from G_remove_colr */
22 {
23  char buf[200], secondary[500], buf2[200], xname[512], xmapset[512];
24 
25  if (G__name_is_fully_qualified(name, xname, xmapset)) {
26  sprintf(buf, "%s/%s", G3D_DIRECTORY, xname);
27  sprintf(buf2, "%s@%s", G3D_COLOR_ELEMENT, xmapset); /* == color@mapset */
28  }
29  else {
30  sprintf(buf, "%s/%s", G3D_DIRECTORY, name);
31  sprintf(buf2, "%s", G3D_COLOR_ELEMENT);
32  }
33 
34  G_remove(buf, buf2);
35 
36  sprintf(secondary, "%s/%s/%s",
37  G3D_DIRECTORY, G3D_COLOR2_DIRECTORY, G_mapset());
38  G_remove(secondary, name);
39 
40  return 0;
41 }
42 
43 /*---------------------------------------------------------------------------*/
44 
45 int
46 G3d_readColors(const char *name, const char *mapset, struct Colors *colors)
47  /* adapted from G_read_colors */
48 {
49  char buf[512], buf2[200];
50  const char *err;
51  char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
52  struct FPRange drange;
53  DCELL dmin, dmax;
54 
55  G_init_colors(colors);
56 
57  if (G__name_is_fully_qualified(name, xname, xmapset)) {
58  if (strcmp(xmapset, mapset) != 0)
59  return -1;
60  name = xname;
61  }
62 
63  sprintf(buf, "%s/%s/%s", G3D_DIRECTORY, G3D_COLOR2_DIRECTORY, mapset);
64  if (read_colors(buf, name, G_mapset(), colors) >= 0)
65  return 1;
66 
67  G_mark_colors_as_fp(colors);
68 
69  /* now look for the regular color table */
70  /*if (G__name_is_fully_qualified (name, xname, xmapset)) {
71  sprintf (buf, "%s/%s", G3D_DIRECTORY, xname);
72  sprintf (buf2, "%s@%s", G3D_COLOR_ELEMENT, xmapset); // == color@mapset
73  //} else { */
74  sprintf(buf, "%s/%s", G3D_DIRECTORY, name);
75  sprintf(buf2, "%s", G3D_COLOR_ELEMENT);
76  /*//}
77  */
78 
79  switch (read_colors(buf, buf2, mapset, colors)) {
80  case -2:
81  if (G3d_readRange(name, mapset, &drange) >= 0) {
82  G_get_fp_range_min_max(&drange, &dmin, &dmax);
83  if (!G_is_d_null_value(&dmin) && !G_is_d_null_value(&dmax))
84  G_make_rainbow_fp_colors(colors, dmin, dmax);
85  return 0;
86  }
87  err = "missing";
88  break;
89  case -1:
90  err = "invalid";
91  break;
92  default:
93  return 1;
94  }
95 
96  G_warning("color support for [%s] in mapset [%s] %s", name, mapset, err);
97  return -1;
98 }
99 
100 static int read_colors(const char *element, const char *name,
101  const char *mapset, struct Colors *colors)
102 {
103  FILE *fd;
104  int stat;
105  char buf[1024];
106 
107  if (!(fd = G_fopen_old(element, name, mapset)))
108  return -2;
109 
110  /*
111  * first line in 4.0 color files is %
112  * otherwise it is pre 4.0
113  */
114  if (fgets(buf, sizeof buf, fd) == NULL) {
115  fclose(fd);
116  return -1;
117  }
118  fseek(fd, 0L, 0);
119 
120  G_strip(buf);
121  if (*buf == '%') { /* 4.0 format */
122  stat = read_new_colors(fd, colors);
123  colors->version = 0; /* 4.0 format */
124  }
125  else {
126  stat = read_old_colors(fd, colors);
127  colors->version = -1; /* pre 4.0 format */
128  }
129  fclose(fd);
130  return stat;
131 }
132 
133 /* parse input lines with the following formats
134  * val1:r:g:b val2:r:g:b
135  * val:r:g:b (implies cat1==cat2)
136  *
137  * r:g:b can be just a single grey level
138  * cat1:x cat2:y
139  * cat:x
140  *
141  * optional lines are
142  * invert invert color table
143  * shift:n where n is the amount to shift the color table
144  */
145 static int read_new_colors(FILE * fd, struct Colors *colors)
146 {
147  double val1, val2;
148  long cat1, cat2;
149  int r1, g1, b1;
150  int r2, g2, b2;
151  char buf[1024];
152  char word1[256], word2[256];
153  int n, fp_rule;
154  int null, undef;
155  int modular;
156  DCELL shift;
157 
158  if (fgets(buf, sizeof buf, fd) == NULL)
159  return -1;
160  G_strip(buf);
161 
162  if (sscanf(buf + 1, "%lf %lf", &val1, &val2) == 2)
163  G_set_d_color_range((DCELL) val1, (DCELL) val2, colors);
164 
165  modular = 0;
166  while (fgets(buf, sizeof buf, fd)) {
167  null = undef = fp_rule = 0;
168  *word1 = *word2 = 0;
169  n = sscanf(buf, "%s %s", word1, word2);
170  if (n < 1)
171  continue;
172 
173  if (sscanf(word1, "shift:%lf", &shift) == 1
174  || (strcmp(word1, "shift:") == 0 &&
175  sscanf(word2, "%lf", &shift) == 1)) {
176  G_shift_d_colors(shift, colors);
177  continue;
178  }
179  if (strcmp(word1, "invert") == 0) {
180  G_invert_colors(colors);
181  continue;
182  }
183  if (strcmp(word1, "%%") == 0) {
184  modular = !modular;
185  continue;
186  }
187 
188  switch (sscanf(word1, "nv:%d:%d:%d", &r1, &g1, &b1)) {
189  case 1:
190  null = 1;
191  b1 = g1 = r1;
192  break;
193  case 3:
194  null = 1;
195  break;
196  }
197  if (!null)
198  switch (sscanf(word1, "*:%d:%d:%d", &r1, &g1, &b1)) {
199  case 1:
200  undef = 1;
201  b1 = g1 = r1;
202  break;
203  case 3:
204  undef = 1;
205  break;
206  }
207  if (!null && !undef)
208  switch (sscanf(word1, "%ld:%d:%d:%d", &cat1, &r1, &g1, &b1)) {
209  case 2:
210  b1 = g1 = r1;
211  break;
212  case 4:
213  break;
214  default:
215  if (sscanf(word1, "%lf:%d:%d:%d", &val1, &r1, &g1, &b1) == 4)
216  fp_rule = 1;
217  else if (sscanf(word1, "%lf:%d", &val1, &r1) == 2) {
218  fp_rule = 1;
219  b1 = g1 = r1;
220  }
221  else
222  continue; /* other lines are ignored */
223  }
224  if (n == 2) {
225  switch (sscanf(word2, "%ld:%d:%d:%d", &cat2, &r2, &g2, &b2)) {
226  case 2:
227  b2 = g2 = r2;
228  if (fp_rule)
229  val2 = (DCELL) cat2;
230  break;
231  case 4:
232  if (fp_rule)
233  val2 = (DCELL) cat2;
234  break;
235  default:
236  if (sscanf(word2, "%lf:%d:%d:%d", &val2, &r2, &g2, &b2) == 4) {
237  if (!fp_rule)
238  val1 = (DCELL) cat1;
239  fp_rule = 1;
240  }
241  else if (sscanf(word2, "%lf:%d", &val2, &r2) == 2) {
242  if (!fp_rule)
243  val1 = (DCELL) cat1;
244  fp_rule = 1;
245  b2 = g2 = r2;
246  }
247  else
248  continue; /* other lines are ignored */
249  }
250  }
251  else {
252  if (!fp_rule)
253  cat2 = cat1;
254  else
255  val2 = val1;
256  r2 = r1;
257  g2 = g1;
258  b2 = b1;
259  }
260  if (null)
261  G_set_null_value_color(r1, g1, b1, colors);
262  else if (undef)
263  G_set_default_color(r1, g1, b1, colors);
264 
265  else if (modular) {
266  if (fp_rule)
267  G_add_modular_d_raster_color_rule((DCELL *) & val1, r1, g1,
268  b1, (DCELL *) & val2, r2,
269  g2, b2, colors);
270  else
271  G_add_modular_color_rule((CELL) cat1, r1, g1, b1,
272  (CELL) cat2, r2, g2, b2, colors);
273  }
274  else {
275  if (fp_rule)
276  G_add_d_raster_color_rule((DCELL *) & val1, r1, g1, b1,
277  (DCELL *) & val2, r2, g2, b2,
278  colors);
279  else
280  G_add_color_rule((CELL) cat1, r1, g1, b1,
281  (CELL) cat2, r2, g2, b2, colors);
282  }
283  /*
284  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);
285  */
286  }
287  return 1;
288 }
289 
290 static int read_old_colors(FILE * fd, struct Colors *colors)
291 {
292  char buf[256];
293  long n;
294  long min;
295  float red_f, grn_f, blu_f;
296  int red, grn, blu;
297  int old;
298  int zero;
299 
300  G_init_colors(colors);
301  /*
302  * first line in pre 3.0 color files is number of colors - ignore
303  * otherwise it is #min first color, and the next line is for color 0
304  */
305  if (fgets(buf, sizeof buf, fd) == NULL)
306  return -1;
307 
308  G_strip(buf);
309  if (*buf == '#') { /* 3.0 format */
310  old = 0;
311  if (sscanf(buf + 1, "%ld", &min) != 1) /* first color */
312  return -1;
313  zero = 1;
314  }
315  else {
316  old = 1;
317  min = 0;
318  zero = 0;
319  }
320 
321  colors->cmin = min;
322  n = min;
323  while (fgets(buf, sizeof buf, fd)) {
324  if (old) {
325  if (sscanf(buf, "%f %f %f", &red_f, &grn_f, &blu_f) != 3)
326  return -1;
327 
328  red = 256 * red_f;
329  grn = 256 * grn_f;
330  blu = 256 * blu_f;
331  }
332  else {
333  switch (sscanf(buf, "%d %d %d", &red, &grn, &blu)) {
334  case 1:
335  blu = grn = red;
336  break;
337  case 2:
338  blu = grn;
339  break;
340  case 3:
341  break;
342  default:
343  return -1;
344  }
345  }
346  if (zero) {
347  G__insert_color_into_lookup((CELL) 0, red, grn, blu,
348  &colors->fixed);
349  zero = 0;
350  }
351  else
352  G__insert_color_into_lookup((CELL) n++, red, grn, blu,
353  &colors->fixed);
354  }
355  colors->cmax = n - 1;
356 
357  return 0;
358 }
359 
360 /*---------------------------------------------------------------------------*/
361 
362 int
363 G3d_writeColors(const char *name, const char *mapset, struct Colors *colors)
364  /* adapted from G_write_colors */
365 {
366  char element[512], buf[512], buf2[200];
367  char xname[512], xmapset[512];
368  FILE *fd;
369  int stat;
370 
371  if (G__name_is_fully_qualified(name, xname, xmapset)) {
372  if (strcmp(xmapset, mapset) != 0)
373  return -1;
374  name = xname;
375  }
376 
377  /*
378  * if mapset is current mapset, remove colr2 file (created by pre 3.0 grass)
379  * and then write original color table
380  * else write secondary color table
381  */
382 
383  sprintf(element, "%s/%s/%s", G3D_DIRECTORY, G3D_COLOR2_DIRECTORY, mapset);
384  if (strcmp(mapset, G_mapset()) == 0) {
385  G_remove(element, name); /* get rid of existing colr2, if any */
386 
387  if (G__name_is_fully_qualified(name, xname, xmapset)) {
388  sprintf(buf, "%s/%s", G3D_DIRECTORY, xname);
389  sprintf(buf2, "%s@%s", G3D_COLOR_ELEMENT, xmapset); /* == color@mapset */
390  }
391  else {
392  sprintf(buf, "%s/%s", G3D_DIRECTORY, name);
393  sprintf(buf2, "%s", G3D_COLOR_ELEMENT);
394  }
395 
396  if (!(fd = G_fopen_new(buf, buf2)))
397  return -1;
398  }
399  else {
400  if (!(fd = G_fopen_new(element, name)))
401  return -1;
402  }
403 
404  stat = G__write_colors(fd, colors);
405  fclose(fd);
406  return stat;
407 }
408 
409 /*---------------------------------------------------------------------------*/
410 
411 /*---------------------------------------------------------------------------*/
412 
413 /*---------------------------------------------------------------------------*/
char * G_mapset(void)
current mapset name
Definition: mapset.c:31
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
char xmapset[512]
Definition: g3dcats.c:89
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
DCELL dmin
Definition: g3dcolor.c:53
int G_invert_colors(struct Colors *colors)
Definition: color_invrt.c:3
DCELL val2
Definition: g3dcats.c:91
int stat
Definition: g3dcolor.c:369
G_mark_colors_as_fp(colors)
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 G3d_removeColor(const char *name)
Definition: g3dcolor.c:20
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
int G_remove(const char *element, const char *name)
Remove a database file.
Definition: remove.c:47
char buf[GNAME_MAX+sizeof(G3D_DIRECTORY)+2]
Definition: g3drange.c:62
FILE * G_fopen_new(const char *element, const char *name)
Open a new database file.
Definition: gis/open.c:197
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)
char buf2[200]
Definition: g3dcats.c:89
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 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
struct FPRange drange
Definition: g3dcolor.c:52
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
int G__write_colors(FILE *fd, struct Colors *colors)
Definition: color_write.c:105
int G__name_is_fully_qualified(const char *fullname, char *name, char *mapset)
Check if map name is fully qualified (map @ mapset)
Definition: nme_in_mps.c:57