GRASS GIS 7 Programmer's Manual  7.5.svn(2018)-r72990
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
raster3d/color.c
Go to the documentation of this file.
1 
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <sys/types.h>
6 #include <unistd.h>
7 
8 #include <grass/gis.h>
9 #include <grass/raster.h>
10 #include <grass/glocale.h>
11 
12 #include "raster3d_intern.h"
13 
14 static int read_colors(const char *, const char *, struct Colors *);
15 static int read_new_colors(FILE *, struct Colors *);
16 static int read_old_colors(FILE *, struct Colors *);
17 
18 /*---------------------------------------------------------------------------*/
19 
20 /*!
21  \brief Removes the primary and/or secondary color file.
22 
23  \todo Is <em>primary and/or secondary color file</em> still valid for 7?
24 
25  \see G_remove_colr
26 */
27 int Rast3d_remove_color(const char *name)
28  /* adapted from G_remove_colr */
29 {
31 }
32 
33 /*---------------------------------------------------------------------------*/
34 
35 /*!
36  \brief Reads color file for map \p name in \p mapset into the Colors structure.
37 
38  \param name 3D raster map name
39  \param mapset mapset name
40  \param colors colors to be associated with a map
41 
42  \see Rast3d_write_colors, Rast_read_colors
43 */
44 int Rast3d_read_colors(const char *name, const char *mapset, struct Colors *colors)
45  /* adapted from Rast_read_colors */
46 {
47  const char *err;
48  struct FPRange drange;
49  DCELL dmin, dmax;
50 
51  Rast_init_colors(colors);
52 
53  Rast_mark_colors_as_fp(colors);
54 
55  switch (read_colors(name, mapset, colors)) {
56  case -2:
57  if (Rast3d_read_range(name, mapset, &drange) >= 0) {
58  Rast_get_fp_range_min_max(&drange, &dmin, &dmax);
59  if (!Rast_is_d_null_value(&dmin) && !Rast_is_d_null_value(&dmax))
60  Rast_make_fp_colors(colors, DEFAULT_COLOR_TABLE, dmin, dmax);
61  return 0;
62  }
63  err = "missing";
64  break;
65  case -1:
66  err = "invalid";
67  break;
68  default:
69  return 1;
70  }
71 
72  G_warning("color support for [%s] in mapset [%s] %s", name, mapset, err);
73  return -1;
74 }
75 
76 static int read_colors(const char *name, const char *mapset,
77  struct Colors *colors)
78 {
79  FILE *fd;
80  int stat;
81  char buf[1024];
82 
84  if (!fd)
85  return -2;
86 
87  /*
88  * first line in 4.0 color files is %
89  * otherwise it is pre 4.0
90  */
91  if (fgets(buf, sizeof buf, fd) == NULL) {
92  fclose(fd);
93  return -1;
94  }
95  G_fseek(fd, 0L, 0);
96 
97  G_strip(buf);
98  if (*buf == '%') { /* 4.0 format */
99  stat = read_new_colors(fd, colors);
100  colors->version = 0; /* 4.0 format */
101  }
102  else {
103  stat = read_old_colors(fd, colors);
104  colors->version = -1; /* pre 4.0 format */
105  }
106  fclose(fd);
107  return stat;
108 }
109 
110 /* parse input lines with the following formats
111  * val1:r:g:b val2:r:g:b
112  * val:r:g:b (implies cat1==cat2)
113  *
114  * r:g:b can be just a single grey level
115  * cat1:x cat2:y
116  * cat:x
117  *
118  * optional lines are
119  * invert invert color table
120  * shift:n where n is the amount to shift the color table
121  */
122 static int read_new_colors(FILE * fd, struct Colors *colors)
123 {
124  double val1, val2;
125  long cat1, cat2;
126  int r1, g1, b1;
127  int r2, g2, b2;
128  char buf[1024];
129  char word1[256], word2[256];
130  int n, fp_rule;
131  int null, undef;
132  int modular;
133  DCELL shift;
134 
135  if (fgets(buf, sizeof buf, fd) == NULL)
136  return -1;
137  G_strip(buf);
138 
139  if (sscanf(buf + 1, "%lf %lf", &val1, &val2) == 2)
140  Rast_set_d_color_range((DCELL) val1, (DCELL) val2, colors);
141 
142  modular = 0;
143  while (fgets(buf, sizeof buf, fd)) {
144  null = undef = fp_rule = 0;
145  *word1 = *word2 = 0;
146  n = sscanf(buf, "%s %s", word1, word2);
147  if (n < 1)
148  continue;
149 
150  if (sscanf(word1, "shift:%lf", &shift) == 1
151  || (strcmp(word1, "shift:") == 0 &&
152  sscanf(word2, "%lf", &shift) == 1)) {
153  Rast_shift_d_colors(shift, colors);
154  continue;
155  }
156  if (strcmp(word1, "invert") == 0) {
157  Rast_invert_colors(colors);
158  continue;
159  }
160  if (strcmp(word1, "%%") == 0) {
161  modular = !modular;
162  continue;
163  }
164 
165  switch (sscanf(word1, "nv:%d:%d:%d", &r1, &g1, &b1)) {
166  case 1:
167  null = 1;
168  b1 = g1 = r1;
169  break;
170  case 3:
171  null = 1;
172  break;
173  }
174  if (!null)
175  switch (sscanf(word1, "*:%d:%d:%d", &r1, &g1, &b1)) {
176  case 1:
177  undef = 1;
178  b1 = g1 = r1;
179  break;
180  case 3:
181  undef = 1;
182  break;
183  }
184  if (!null && !undef)
185  switch (sscanf(word1, "%ld:%d:%d:%d", &cat1, &r1, &g1, &b1)) {
186  case 2:
187  b1 = g1 = r1;
188  break;
189  case 4:
190  break;
191  default:
192  if (sscanf(word1, "%lf:%d:%d:%d", &val1, &r1, &g1, &b1) == 4)
193  fp_rule = 1;
194  else if (sscanf(word1, "%lf:%d", &val1, &r1) == 2) {
195  fp_rule = 1;
196  b1 = g1 = r1;
197  }
198  else
199  continue; /* other lines are ignored */
200  }
201  if (n == 2) {
202  switch (sscanf(word2, "%ld:%d:%d:%d", &cat2, &r2, &g2, &b2)) {
203  case 2:
204  b2 = g2 = r2;
205  if (fp_rule)
206  val2 = (DCELL) cat2;
207  break;
208  case 4:
209  if (fp_rule)
210  val2 = (DCELL) cat2;
211  break;
212  default:
213  if (sscanf(word2, "%lf:%d:%d:%d", &val2, &r2, &g2, &b2) == 4) {
214  if (!fp_rule)
215  val1 = (DCELL) cat1;
216  fp_rule = 1;
217  }
218  else if (sscanf(word2, "%lf:%d", &val2, &r2) == 2) {
219  if (!fp_rule)
220  val1 = (DCELL) cat1;
221  fp_rule = 1;
222  b2 = g2 = r2;
223  }
224  else
225  continue; /* other lines are ignored */
226  }
227  }
228  else {
229  if (!fp_rule)
230  cat2 = cat1;
231  else
232  val2 = val1;
233  r2 = r1;
234  g2 = g1;
235  b2 = b1;
236  }
237  if (null)
238  Rast_set_null_value_color(r1, g1, b1, colors);
239  else if (undef)
240  Rast_set_default_color(r1, g1, b1, colors);
241 
242  else if (modular) {
243  if (fp_rule)
244  Rast_add_modular_d_color_rule((DCELL *) & val1, r1, g1,
245  b1, (DCELL *) & val2, r2,
246  g2, b2, colors);
247  else
248  Rast_add_modular_c_color_rule((CELL *) &cat1, r1, g1, b1,
249  (CELL *) &cat2, r2, g2, b2, colors);
250  }
251  else {
252  if (fp_rule)
253  Rast_add_d_color_rule((DCELL *) & val1, r1, g1, b1,
254  (DCELL *) & val2, r2, g2, b2,
255  colors);
256  else
257  Rast_add_c_color_rule((CELL *) &cat1, r1, g1, b1,
258  (CELL *) &cat2, r2, g2, b2, colors);
259  }
260  /*
261  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);
262  */
263  }
264  return 1;
265 }
266 
267 static int read_old_colors(FILE * fd, struct Colors *colors)
268 {
269  char buf[256];
270  long n;
271  long min;
272  float red_f, grn_f, blu_f;
273  int red, grn, blu;
274  int old;
275  int zero;
276 
277  Rast_init_colors(colors);
278  /*
279  * first line in pre 3.0 color files is number of colors - ignore
280  * otherwise it is #min first color, and the next line is for color 0
281  */
282  if (fgets(buf, sizeof buf, fd) == NULL)
283  return -1;
284 
285  G_strip(buf);
286  if (*buf == '#') { /* 3.0 format */
287  old = 0;
288  if (sscanf(buf + 1, "%ld", &min) != 1) /* first color */
289  return -1;
290  zero = 1;
291  }
292  else {
293  old = 1;
294  min = 0;
295  zero = 0;
296  }
297 
298  colors->cmin = min;
299  n = min;
300  while (fgets(buf, sizeof buf, fd)) {
301  if (old) {
302  if (sscanf(buf, "%f %f %f", &red_f, &grn_f, &blu_f) != 3)
303  return -1;
304 
305  red = 256 * red_f;
306  grn = 256 * grn_f;
307  blu = 256 * blu_f;
308  }
309  else {
310  switch (sscanf(buf, "%d %d %d", &red, &grn, &blu)) {
311  case 1:
312  blu = grn = red;
313  break;
314  case 2:
315  blu = grn;
316  break;
317  case 3:
318  break;
319  default:
320  return -1;
321  }
322  }
323  if (zero) {
324  Rast__insert_color_into_lookup((CELL) 0, red, grn, blu,
325  &colors->fixed);
326  zero = 0;
327  }
328  else
329  Rast__insert_color_into_lookup((CELL) n++, red, grn, blu,
330  &colors->fixed);
331  }
332  colors->cmax = n - 1;
333 
334  return 0;
335 }
336 
337 /*---------------------------------------------------------------------------*/
338 
339 /*!
340  \brief Writes the \p colors for map \p name in \p mapset into a color file.
341 
342  \param name 3D raster map name
343  \param mapset mapset name
344  \param colors colors to be associated with a map
345 
346  \see Rast3d_read_colors, Rast3d_remove_color, Rast_write_colors
347 */
348 int Rast3d_write_colors(const char *name, const char *mapset, struct Colors *colors)
349  /* adapted from Rast_write_colors */
350 {
351  FILE *fd;
352 
353  if (strcmp(mapset, G_mapset()) != 0) {
354  G_warning(_("mapset <%s> is not the current mapset"), mapset);
355  return -1;
356  }
357 
359  if (!fd)
360  return -1;
361 
362  Rast__write_colors(fd, colors);
363  fclose(fd);
364 
365  return 1;
366 }
367 
368 /*---------------------------------------------------------------------------*/
369 
370 /*---------------------------------------------------------------------------*/
371 
372 /*---------------------------------------------------------------------------*/
int Rast__insert_color_into_lookup(CELL cat, int red, int grn, int blu, struct _Color_Info_ *cp)
Definition: color_insrt.c:14
struct _Color_Info_ fixed
Definition: gis.h:657
int Rast_add_modular_c_color_rule(const CELL *val1, int r1, int g1, int b1, const CELL *val2, int r2, int g2, int b2, struct Colors *colors)
Add modular integer color rule (CELL version)
Definition: color_rule.c:184
void G_strip(char *buf)
Removes all leading and trailing white space from string.
Definition: strings.c:258
void Rast_add_c_color_rule(const CELL *cat1, int r1, int g1, int b1, const CELL *cat2, int r2, int g2, int b2, struct Colors *colors)
Adds the integer color rule (CELL version)
Definition: color_rule.c:75
#define min(x, y)
Definition: draw2.c:31
int version
Definition: gis.h:645
void Rast_set_null_value_color(int red, int grn, int blu, struct Colors *colors)
Set color for NULL-value.
Definition: color_set.c:79
void Rast_shift_d_colors(DCELL shift, struct Colors *colors)
Definition: color_shift.c:22
double DCELL
Definition: gis.h:581
void Rast_mark_colors_as_fp(struct Colors *colors)
Mark colors as floating-point.
DCELL cmax
Definition: gis.h:660
int old
Definition: raster3d/cats.c:84
void Rast_make_fp_colors(struct Colors *colors, const char *name, DCELL min, DCELL max)
Load color rules from predefined floating-point color table.
FILE * G_fopen_old_misc(const char *dir, const char *element, const char *name, const char *mapset)
open a database file for reading
Definition: open_misc.c:210
#define NULL
Definition: ccmath.h:32
void Rast_init_colors(struct Colors *colors)
Initialize color structure.
Definition: color_init.c:25
void Rast_set_default_color(int red, int grn, int blu, struct Colors *colors)
Set default color value.
Definition: color_set.c:100
fd
Definition: d/range.c:69
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)
Definition: symbol/read.c:220
DCELL cmin
Definition: gis.h:659
DCELL val1
Definition: raster3d/cats.c:83
int Rast3d_write_colors(const char *name, const char *mapset, struct Colors *colors)
Writes the colors for map name in mapset into a color file.
fclose(fd)
void Rast_invert_colors(struct Colors *colors)
Definition: color_invrt.c:17
void Rast_add_d_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 color rule (DCELL version)
Definition: color_rule.c:35
int Rast3d_read_colors(const char *name, const char *mapset, struct Colors *colors)
Reads color file for map name in mapset into the Colors structure.
int Rast3d_remove_color(const char *name)
Removes the primary and/or secondary color file.
Definition: gis.h:643
int Rast_add_modular_d_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 floating-point color rule (DCELL version)
Definition: color_rule.c:124
DCELL val2
Definition: raster3d/cats.c:83
void G_fseek(FILE *fp, off_t offset, int whence)
Change the file position of the stream.
Definition: gis/seek.c:48
#define RASTER3D_DIRECTORY
Definition: raster3d.h:31
void Rast_set_d_color_range(DCELL min, DCELL max, struct Colors *colors)
Set color range (DCELL version)
Definition: color_range.c:42
#define DEFAULT_COLOR_TABLE
Definition: gis.h:350
int CELL
Definition: gis.h:580
FILE * G_fopen_new_misc(const char *dir, const char *element, const char *name)
open a new database file
Definition: open_misc.c:182
#define _(str)
Definition: glocale.h:13
void Rast__write_colors(FILE *fd, struct Colors *colors)
Write map layer color table.
const char * G_mapset(void)
Get current mapset name.
Definition: gis/mapset.c:33
int G_remove_misc(const char *dir, const char *element, const char *name)
Remove a database misc file.
Definition: remove.c:65
void Rast_get_fp_range_min_max(const struct FPRange *range, DCELL *min, DCELL *max)
Get minimum and maximum value from fp range.
Definition: range.c:752
const char * name
Definition: named_colr.c:7
#define RASTER3D_COLOR_ELEMENT
Definition: raster3d.h:37
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition: gis/error.c:204
int Rast_is_d_null_value(const DCELL *dcellVal)
To check if a DCELL raster value is set to NULL.
Definition: null_val.c:261