GRASS GIS 8 Programmer's Manual  8.2.2dev(2023)-3d2c704037
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 /*---------------------------------------------------------------------------*/
void Rast__write_colors(FILE *, struct Colors *)
Write map layer color table.
struct _Color_Info_ fixed
Definition: gis.h:690
void Rast_add_c_color_rule(const CELL *, int, int, int, const CELL *, int, int, int, struct Colors *)
Adds the integer color rule (CELL version)
Definition: color_rule.c:75
#define Rast_is_d_null_value(dcellVal)
Definition: defs/raster.h:414
#define min(x, y)
Definition: draw2.c:31
int version
Definition: gis.h:678
void Rast_invert_colors(struct Colors *)
Definition: color_invrt.c:17
double DCELL
Definition: gis.h:614
DCELL cmax
Definition: gis.h:693
void Rast_shift_d_colors(DCELL, struct Colors *)
Definition: color_shift.c:22
void G_strip(char *)
Removes all leading and trailing white space from string.
Definition: strings.c:300
void Rast_set_d_color_range(DCELL, DCELL, struct Colors *)
Set color range (DCELL version)
Definition: color_range.c:42
#define NULL
Definition: ccmath.h:32
int G_remove_misc(const char *, const char *, const char *)
Remove a database misc file.
Definition: remove.c:65
int Rast3d_read_range(const char *, const char *, struct FPRange *)
Definition: d/range.c:59
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)
Definition: symbol/read.c:220
void Rast_get_fp_range_min_max(const struct FPRange *, DCELL *, DCELL *)
Get minimum and maximum value from fp range.
Definition: range.c:764
DCELL cmin
Definition: gis.h:692
int Rast__insert_color_into_lookup(CELL, int, int, int, struct _Color_Info_ *)
Definition: color_insrt.c:14
void Rast_mark_colors_as_fp(struct Colors *)
Mark colors as floating-point.
int Rast_add_modular_c_color_rule(const CELL *, int, int, int, const CELL *, int, int, int, struct Colors *)
Add modular integer color rule (CELL version)
Definition: color_rule.c:184
FILE * G_fopen_old_misc(const char *, const char *, const char *, const char *)
open a database misc file for reading
Definition: open_misc.c:210
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.
void G_fseek(FILE *, off_t, int)
Change the file position of the stream.
Definition: gis/seek.c:50
void Rast_set_default_color(int, int, int, struct Colors *)
Set default color value.
Definition: color_set.c:100
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.
void Rast_set_null_value_color(int, int, int, struct Colors *)
Set color for NULL-value.
Definition: color_set.c:79
int Rast3d_remove_color(const char *name)
Removes the primary and/or secondary color file.
Definition: gis.h:676
#define RASTER3D_DIRECTORY
Definition: raster3d.h:31
FILE * G_fopen_new_misc(const char *, const char *, const char *)
open a new database misc file
Definition: open_misc.c:182
#define DEFAULT_COLOR_TABLE
Definition: gis.h:383
const char * G_mapset(void)
Get current mapset name.
Definition: gis/mapset.c:33
void G_warning(const char *,...) __attribute__((format(printf
int CELL
Definition: gis.h:613
int Rast_add_modular_d_color_rule(const DCELL *, int, int, int, const DCELL *, int, int, int, struct Colors *)
Add modular floating-point color rule (DCELL version)
Definition: color_rule.c:124
#define _(str)
Definition: glocale.h:10
void Rast_add_d_color_rule(const DCELL *, int, int, int, const DCELL *, int, int, int, struct Colors *)
Adds the floating-point color rule (DCELL version)
Definition: color_rule.c:35
void Rast_make_fp_colors(struct Colors *, const char *, DCELL, DCELL)
Load color rules from predefined floating-point color table.
const char * name
Definition: named_colr.c:7
void Rast_init_colors(struct Colors *)
Initialize color structure.
Definition: color_init.c:25
#define RASTER3D_COLOR_ELEMENT
Definition: raster3d.h:37