GRASS GIS 8 Programmer's Manual  8.2.2dev(2023)-3d2c704037
color_xform.c
Go to the documentation of this file.
1 /*!
2  * \file lib/raster/color_xform.c
3  *
4  * \brief Raster Library - Colors management
5  *
6  * (C) 2001-2021 by the GRASS Development Team
7  *
8  * This program is free software under the GNU General Public License
9  * (>=v2). Read the file COPYING that comes with GRASS for details.
10  *
11  * \author Original author CERL
12  */
13 
14 #include <math.h>
15 
16 #include <grass/gis.h>
17 #include <grass/raster.h>
18 
19 /*!
20  * \brief Make histogram-stretched version of existing color table
21  *
22  * Generates a histogram contrast-stretched color table that goes from
23  * the histogram information in the Cell_stats structure <i>statf</i>.
24  * (See \ref Raster_Histograms).
25  *
26  * \param[out] dst struct to hold new colors
27  * \param src struct containing original colors
28  * \param statf cell stats info
29  */
31  struct Colors *src, struct Cell_stats *statf)
32 {
33  DCELL min, max;
34  int red, grn, blu;
35  int red2, grn2, blu2;
36  long count, total, sum;
37  CELL cat, prev;
38  int first;
39 
40  Rast_init_colors(dst);
41 
42  Rast_get_d_color_range(&min, &max, src);
43 
44  Rast_get_default_color(&red, &grn, &blu, src);
45  Rast_set_default_color(red, grn, blu, dst);
46 
47  Rast_get_null_value_color(&red, &grn, &blu, src);
48  Rast_set_null_value_color(red, grn, blu, dst);
49 
50  total = 0;
51 
53  while (Rast_next_cell_stat(&cat, &count, statf))
54  if (count > 0)
55  total += count;
56 
57  if (total <= 0)
58  return;
59 
60  sum = 0;
61  prev = 0;
62  first = 1;
63 
65  while (Rast_next_cell_stat(&cat, &count, statf)) {
66  DCELL x;
67 
68  if (count <= 0)
69  continue;
70 
71  x = min + (max - min) * (sum + count / 2.0) / total;
72  Rast_get_d_color(&x, &red2, &grn2, &blu2, src);
73 
74  sum += count;
75 
76  if (!first && red2 == red && blu2 == blu && grn2 == grn)
77  continue;
78 
79  if (!first)
80  Rast_add_c_color_rule(&prev, red, grn, blu,
81  &cat, red2, grn2, blu2,
82  dst);
83 
84  first = 0;
85 
86  prev = cat;
87  red = red2;
88  grn = grn2;
89  blu = blu2;
90  }
91 
92  if (!first && cat > prev)
93  Rast_add_c_color_rule(&prev, red, grn, blu,
94  &cat, red2, grn2, blu2,
95  dst);
96 }
97 
98 /*!
99  * \brief Make histogram-stretched version of existing color table (FP version)
100  *
101  * Generates a histogram contrast-stretched color table that goes from
102  * the histogram information in the FP_stats structure <b>statf.</b>
103  * (See \ref Raster_Histograms).
104  *
105  * \param[out] dst struct to hold new colors
106  * \param src struct containing original colors
107  * \param statf cell stats info
108  */
110  struct Colors *src, struct FP_stats *statf)
111 {
112  DCELL min, max;
113  int red, grn, blu;
114  int red2, grn2, blu2;
115  unsigned long sum;
116  DCELL val, val2;
117  int first;
118  int i;
119 
120  Rast_init_colors(dst);
121 
122  Rast_get_d_color_range(&min, &max, src);
123 
124  Rast_get_default_color(&red, &grn, &blu, src);
125  Rast_set_default_color(red, grn, blu, dst);
126 
127  Rast_get_null_value_color(&red, &grn, &blu, src);
128  Rast_set_null_value_color(red, grn, blu, dst);
129 
130  if (!statf->total)
131  return;
132 
133  sum = 0;
134  first = 1;
135 
136  for (i = 0; i <= statf->count; i++) {
137  DCELL x;
138 
139  val2 = statf->min + (statf->max - statf->min) * i / statf->count;
140  if (statf->geometric)
141  val2 = exp(val2);
142  if (statf->geom_abs)
143  val2 = exp(val2) - 1;
144  if (statf->flip)
145  val2 = -val2;
146  x = min + (max - min) * sum / statf->total;
147  Rast_get_d_color(&x, &red2, &grn2, &blu2, src);
148 
149  if (i < statf->count)
150  sum += statf->stats[i];
151 
152  if (!first && red2 == red && blu2 == blu && grn2 == grn)
153  continue;
154 
155  if (!first)
156  Rast_add_d_color_rule(&val, red, grn, blu,
157  &val2, red2, grn2, blu2,
158  dst);
159 
160  first = 0;
161 
162  if (i == statf->count)
163  break;
164 
165  val = val2;
166  red = red2;
167  grn = grn2;
168  blu = blu2;
169  }
170 
171  if (!first && val2 > val)
172  Rast_add_d_color_rule(&val, red, grn, blu,
173  &val2, red2, grn2, blu2,
174  dst);
175 }
176 
177 /*!
178  * \brief Make logarithmically-scaled version of an existing color table
179  *
180  * \param[out] dst struct to hold new colors
181  * \param src struct containing original colors
182  * \param samples number of samples
183  */
184 
185 void Rast_log_colors(struct Colors *dst, struct Colors *src, int samples)
186 {
187  DCELL min, max;
188  double delta, lmin, lmax;
189  int red, grn, blu;
190  DCELL prev;
191  int i;
192 
193  Rast_init_colors(dst);
194 
195  Rast_get_d_color_range(&min, &max, src);
196 
197  if (min <= 0.0) {
198  /* shift cell values by 1 - min so that they are in [1, max - min + 1]
199  */
200  delta = 1 - min;
201  lmin = log(min + delta);
202  lmax = log(max + delta);
203  } else {
204  delta = 0;
205  lmin = log(min);
206  lmax = log(max);
207  }
208 
209  Rast_get_default_color(&red, &grn, &blu, src);
210  Rast_set_default_color(red, grn, blu, dst);
211 
212  Rast_get_null_value_color(&red, &grn, &blu, src);
213  Rast_set_null_value_color(red, grn, blu, dst);
214 
215  for (i = 0; i <= samples; i++) {
216  int red2, grn2, blu2;
217  double lx;
218  DCELL x, y;
219 
220  y = min + (max - min) * i / samples;
221  Rast_get_d_color(&y, &red2, &grn2, &blu2, src);
222 
223  if (i == 0)
224  x = min;
225  else if (i == samples)
226  x = max;
227  else {
228  lx = lmin + (lmax - lmin) * i / samples;
229  /* restore cell values approximately */
230  x = exp(lx) - delta;
231  }
232 
233  if (i > 0)
234  Rast_add_d_color_rule(&prev, red, grn, blu,
235  &x, red2, grn2, blu2, dst);
236 
237  prev = x;
238 
239  red = red2;
240  grn = grn2;
241  blu = blu2;
242  }
243 }
244 
245 /*!
246  * \brief Make logarithmically-scaled version of an existing color
247  * table, allowing for signed values
248  *
249  * \param[out] dst struct to hold new colors
250  * \param src struct containing original colors
251  * \param samples number of samples
252  */
253 void Rast_abs_log_colors(struct Colors *dst, struct Colors *src, int samples)
254 {
255  DCELL min, max;
256  double absmin, absmax, amin, amax, delta, lamin, lamax;
257  int red, grn, blu;
258  DCELL prev;
259  int i;
260 
261  Rast_init_colors(dst);
262 
263  Rast_get_d_color_range(&min, &max, src);
264 
265  absmin = fabs(min);
266  absmax = fabs(max);
267  amin = MIN(absmin, absmax);
268  amax = MAX(absmin, absmax);
269 
270  if (min * max <= 0.0) {
271  /* 0 <= abs(cell) <= amax */
272  amin = 0;
273  /* use the same shifting for Rast_log_colors */
274  delta = 1 - amin;
275  lamin = log(amin + delta);
276  lamax = log(amax + delta);
277  } else {
278  /* 0 < amin <= abs(cell) <= amax */
279  delta = 0;
280  lamin = log(amin);
281  lamax = log(amax);
282  }
283 
284  Rast_get_default_color(&red, &grn, &blu, src);
285  Rast_set_default_color(red, grn, blu, dst);
286 
287  Rast_get_null_value_color(&red, &grn, &blu, src);
288  Rast_set_null_value_color(red, grn, blu, dst);
289 
290  for (i = 0; i <= samples; i++) {
291  int red2, grn2, blu2;
292  double lx;
293  DCELL x, y;
294 
295  y = min + (max - min) * i / samples;
296  Rast_get_d_color(&y, &red2, &grn2, &blu2, src);
297 
298  if (i == 0)
299  x = amin;
300  else if (i == samples)
301  x = amax;
302  else {
303  lx = lamin + (lamax - lamin) * i / samples;
304  /* restore cell values approximately */
305  x = exp(lx) - delta;
306  }
307 
308  if (i > 0) {
309  DCELL x0 = prev, x1 = x;
310 
311  Rast_add_d_color_rule(&x0, red, grn, blu,
312  &x1, red2, grn2, blu2, dst);
313  x0 = -x0;
314  x1 = -x1;
315  Rast_add_d_color_rule(&x0, red, grn, blu,
316  &x1, red2, grn2, blu2, dst);
317  }
318 
319  prev = x;
320 
321  red = red2;
322  grn = grn2;
323  blu = blu2;
324  }
325 }
int count
Definition: raster.h:245
if(!(yy_init))
Definition: sqlp.yy.c:775
int Rast_next_cell_stat(CELL *, long *, struct Cell_stats *)
Retrieve sorted cell stats.
Definition: cell_stats.c:314
int Rast_rewind_cell_stats(struct Cell_stats *)
Reset/rewind cell stats.
Definition: cell_stats.c:250
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
DCELL max
Definition: raster.h:246
#define min(x, y)
Definition: draw2.c:31
double DCELL
Definition: gis.h:614
void Rast_get_d_color_range(DCELL *, DCELL *, const struct Colors *)
Get color range values (DCELL)
Definition: color_range.c:87
int geometric
Definition: raster.h:242
int count
char * dst
Definition: lz4.h:599
void Rast_histogram_eq_fp_colors(struct Colors *dst, struct Colors *src, struct FP_stats *statf)
Make histogram-stretched version of existing color table (FP version)
Definition: color_xform.c:109
#define x
#define max(x, y)
Definition: draw2.c:32
void Rast_get_default_color(int *, int *, int *, const struct Colors *)
Gets default color.
Definition: color_get.c:155
void Rast_histogram_eq_colors(struct Colors *dst, struct Colors *src, struct Cell_stats *statf)
Make histogram-stretched version of existing color table.
Definition: color_xform.c:30
int geom_abs
Definition: raster.h:243
void Rast_get_null_value_color(int *, int *, int *, const struct Colors *)
Gets color for null value.
Definition: color_get.c:127
#define MIN(a, b)
Definition: gis.h:140
int flip
Definition: raster.h:244
#define MAX(a, b)
Definition: gis.h:135
void Rast_set_default_color(int, int, int, struct Colors *)
Set default color value.
Definition: color_set.c:100
unsigned long * stats
Definition: raster.h:247
void Rast_set_null_value_color(int, int, int, struct Colors *)
Set color for NULL-value.
Definition: color_set.c:79
void Rast_abs_log_colors(struct Colors *dst, struct Colors *src, int samples)
Make logarithmically-scaled version of an existing color table, allowing for signed values...
Definition: color_xform.c:253
unsigned long total
Definition: raster.h:248
Definition: gis.h:676
int Rast_get_d_color(const DCELL *, int *, int *, int *, struct Colors *)
Gets color from raster map (DCELL)
Definition: color_get.c:110
int CELL
Definition: gis.h:613
DCELL min
Definition: raster.h:246
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_log_colors(struct Colors *dst, struct Colors *src, int samples)
Make logarithmically-scaled version of an existing color table.
Definition: color_xform.c:185
void Rast_init_colors(struct Colors *)
Initialize color structure.
Definition: color_init.c:25
struct _Color_Rule_ * prev
Definition: gis.h:646