GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-bb27c0570b
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  */
30 void Rast_histogram_eq_colors(struct Colors *dst, struct Colors *src,
31  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 
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, &cat, red2, grn2, blu2,
81  dst);
82 
83  first = 0;
84 
85  prev = cat;
86  red = red2;
87  grn = grn2;
88  blu = blu2;
89  }
90 
91  if (!first && cat > prev)
92  Rast_add_c_color_rule(&prev, red, grn, blu, &cat, red2, grn2, blu2,
93  dst);
94 }
95 
96 /*!
97  * \brief Make histogram-stretched version of existing color table (FP version)
98  *
99  * Generates a histogram contrast-stretched color table that goes from
100  * the histogram information in the FP_stats structure <b>statf.</b>
101  * (See \ref Raster_Histograms).
102  *
103  * \param[out] dst struct to hold new colors
104  * \param src struct containing original colors
105  * \param statf cell stats info
106  */
107 void Rast_histogram_eq_fp_colors(struct Colors *dst, struct Colors *src,
108  struct FP_stats *statf)
109 {
110  DCELL min, max;
111  int red, grn, blu;
112  int red2, grn2, blu2;
113  unsigned long sum;
114  DCELL val, val2;
115  int first;
116  int i;
117 
118  Rast_init_colors(dst);
119 
120  Rast_get_d_color_range(&min, &max, src);
121 
122  Rast_get_default_color(&red, &grn, &blu, src);
123  Rast_set_default_color(red, grn, blu, dst);
124 
125  Rast_get_null_value_color(&red, &grn, &blu, src);
126  Rast_set_null_value_color(red, grn, blu, dst);
127 
128  if (!statf->total)
129  return;
130 
131  sum = 0;
132  first = 1;
133 
134  for (i = 0; i <= statf->count; i++) {
135  DCELL x;
136 
137  val2 = statf->min + (statf->max - statf->min) * i / statf->count;
138  if (statf->geometric)
139  val2 = exp(val2);
140  if (statf->geom_abs)
141  val2 = exp(val2) - 1;
142  if (statf->flip)
143  val2 = -val2;
144  x = min + (max - min) * sum / statf->total;
145  Rast_get_d_color(&x, &red2, &grn2, &blu2, src);
146 
147  if (i < statf->count)
148  sum += statf->stats[i];
149 
150  if (!first && red2 == red && blu2 == blu && grn2 == grn)
151  continue;
152 
153  if (!first)
154  Rast_add_d_color_rule(&val, red, grn, blu, &val2, red2, grn2, blu2,
155  dst);
156 
157  first = 0;
158 
159  if (i == statf->count)
160  break;
161 
162  val = val2;
163  red = red2;
164  grn = grn2;
165  blu = blu2;
166  }
167 
168  if (!first && val2 > val)
169  Rast_add_d_color_rule(&val, red, grn, blu, &val2, red2, grn2, blu2,
170  dst);
171 }
172 
173 /*!
174  * \brief Make logarithmically-scaled version of an existing color table
175  *
176  * \param[out] dst struct to hold new colors
177  * \param src struct containing original colors
178  * \param samples number of samples
179  */
180 
181 void Rast_log_colors(struct Colors *dst, struct Colors *src, int samples)
182 {
183  DCELL min, max;
184  double delta, lmin, lmax;
185  int red, grn, blu;
186  DCELL prev;
187  int i;
188 
189  Rast_init_colors(dst);
190 
191  Rast_get_d_color_range(&min, &max, src);
192 
193  if (min <= 0.0) {
194  /* shift cell values by 1 - min so that they are in [1, max - min + 1]
195  */
196  delta = 1 - min;
197  lmin = log(min + delta);
198  lmax = log(max + delta);
199  }
200  else {
201  delta = 0;
202  lmin = log(min);
203  lmax = log(max);
204  }
205 
206  Rast_get_default_color(&red, &grn, &blu, src);
207  Rast_set_default_color(red, grn, blu, dst);
208 
209  Rast_get_null_value_color(&red, &grn, &blu, src);
210  Rast_set_null_value_color(red, grn, blu, dst);
211 
212  for (i = 0; i <= samples; i++) {
213  int red2, grn2, blu2;
214  double lx;
215  DCELL x, y;
216 
217  y = min + (max - min) * i / samples;
218  Rast_get_d_color(&y, &red2, &grn2, &blu2, src);
219 
220  if (i == 0)
221  x = min;
222  else if (i == samples)
223  x = max;
224  else {
225  lx = lmin + (lmax - lmin) * i / samples;
226  /* restore cell values approximately */
227  x = exp(lx) - delta;
228  }
229 
230  if (i > 0)
231  Rast_add_d_color_rule(&prev, red, grn, blu, &x, red2, grn2, blu2,
232  dst);
233 
234  prev = x;
235 
236  red = red2;
237  grn = grn2;
238  blu = blu2;
239  }
240 }
241 
242 /*!
243  * \brief Make logarithmically-scaled version of an existing color
244  * table, allowing for signed values
245  *
246  * \param[out] dst struct to hold new colors
247  * \param src struct containing original colors
248  * \param samples number of samples
249  */
250 void Rast_abs_log_colors(struct Colors *dst, struct Colors *src, int samples)
251 {
252  DCELL min, max;
253  double absmin, absmax, amin, amax, delta, lamin, lamax;
254  int red, grn, blu;
255  DCELL prev;
256  int i;
257 
258  Rast_init_colors(dst);
259 
260  Rast_get_d_color_range(&min, &max, src);
261 
262  absmin = fabs(min);
263  absmax = fabs(max);
264  amin = MIN(absmin, absmax);
265  amax = MAX(absmin, absmax);
266 
267  if (min * max <= 0.0) {
268  /* 0 <= abs(cell) <= amax */
269  amin = 0;
270  /* use the same shifting for Rast_log_colors */
271  delta = 1 - amin;
272  lamin = log(amin + delta);
273  lamax = log(amax + delta);
274  }
275  else {
276  /* 0 < amin <= abs(cell) <= amax */
277  delta = 0;
278  lamin = log(amin);
279  lamax = log(amax);
280  }
281 
282  Rast_get_default_color(&red, &grn, &blu, src);
283  Rast_set_default_color(red, grn, blu, dst);
284 
285  Rast_get_null_value_color(&red, &grn, &blu, src);
286  Rast_set_null_value_color(red, grn, blu, dst);
287 
288  for (i = 0; i <= samples; i++) {
289  int red2, grn2, blu2;
290  double lx;
291  DCELL x, y;
292 
293  y = min + (max - min) * i / samples;
294  Rast_get_d_color(&y, &red2, &grn2, &blu2, src);
295 
296  if (i == 0)
297  x = amin;
298  else if (i == samples)
299  x = amax;
300  else {
301  lx = lamin + (lamax - lamin) * i / samples;
302  /* restore cell values approximately */
303  x = exp(lx) - delta;
304  }
305 
306  if (i > 0) {
307  DCELL x0 = prev, x1 = x;
308 
309  Rast_add_d_color_rule(&x0, red, grn, blu, &x1, red2, grn2, blu2,
310  dst);
311  x0 = -x0;
312  x1 = -x1;
313  Rast_add_d_color_rule(&x0, red, grn, blu, &x1, red2, grn2, blu2,
314  dst);
315  }
316 
317  prev = x;
318 
319  red = red2;
320  grn = grn2;
321  blu = blu2;
322  }
323 }
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:250
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
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:181
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:107
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:38
void Rast_set_null_value_color(int, int, int, struct Colors *)
Set color for NULL-value.
Definition: color_set.c:79
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:76
int Rast_rewind_cell_stats(struct Cell_stats *)
Reset/rewind cell stats.
Definition: cell_stats.c:248
void Rast_init_colors(struct Colors *)
Initialize color structure.
Definition: color_init.c:25
int Rast_next_cell_stat(CELL *, long *, struct Cell_stats *)
Retrieve sorted cell stats.
Definition: cell_stats.c:312
void Rast_get_d_color_range(DCELL *, DCELL *, const struct Colors *)
Get color range values (DCELL)
Definition: color_range.c:86
void Rast_get_null_value_color(int *, int *, int *, const struct Colors *)
Gets color for null value.
Definition: color_get.c:126
int Rast_get_d_color(const DCELL *, int *, int *, int *, struct Colors *)
Gets color from raster map (DCELL)
Definition: color_get.c:109
void Rast_set_default_color(int, int, int, struct Colors *)
Set default color value.
Definition: color_set.c:99
void Rast_get_default_color(int *, int *, int *, const struct Colors *)
Gets default color.
Definition: color_get.c:154
#define min(x, y)
Definition: draw2.c:29
#define max(x, y)
Definition: draw2.c:30
#define MIN(a, b)
Definition: gis.h:154
double DCELL
Definition: gis.h:626
int CELL
Definition: gis.h:625
#define MAX(a, b)
Definition: gis.h:149
int count
if(!(yy_init))
Definition: sqlp.yy.c:775
Definition: gis.h:683
int geometric
Definition: raster.h:226
int flip
Definition: raster.h:228
DCELL max
Definition: raster.h:230
unsigned long * stats
Definition: raster.h:231
unsigned long total
Definition: raster.h:232
int geom_abs
Definition: raster.h:227
DCELL min
Definition: raster.h:230
int count
Definition: raster.h:229
#define x