GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
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 */
30void 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
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 */
107void 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
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
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 */
180void Rast_log_colors(struct Colors *dst, struct Colors *src, int samples)
181{
182 DCELL min, max;
183 double delta, lmin, lmax;
184 int red, grn, blu;
185 DCELL prev;
186 int i;
187
188 Rast_init_colors(dst);
189
191
192 if (min <= 0.0) {
193 /* shift cell values by 1 - min so that they are in [1, max - min + 1]
194 */
195 delta = 1 - min;
196 lmin = log(min + delta);
197 lmax = log(max + delta);
198 }
199 else {
200 delta = 0;
201 lmin = log(min);
202 lmax = log(max);
203 }
204
205 Rast_get_default_color(&red, &grn, &blu, src);
206 Rast_set_default_color(red, grn, blu, dst);
207
208 Rast_get_null_value_color(&red, &grn, &blu, src);
209 Rast_set_null_value_color(red, grn, blu, dst);
210
211 for (i = 0; i <= samples; i++) {
212 int red2, grn2, blu2;
213 double lx;
214 DCELL x, y;
215
216 y = min + (max - min) * i / samples;
217 Rast_get_d_color(&y, &red2, &grn2, &blu2, src);
218
219 if (i == 0)
220 x = min;
221 else if (i == samples)
222 x = max;
223 else {
224 lx = lmin + (lmax - lmin) * i / samples;
225 /* restore cell values approximately */
226 x = exp(lx) - delta;
227 }
228
229 if (i > 0)
230 Rast_add_d_color_rule(&prev, red, grn, blu, &x, red2, grn2, blu2,
231 dst);
232
233 prev = x;
234
235 red = red2;
236 grn = grn2;
237 blu = blu2;
238 }
239}
240
241/*!
242 * \brief Make logarithmically-scaled version of an existing color
243 * table, allowing for signed values
244 *
245 * \param[out] dst struct to hold new colors
246 * \param src struct containing original colors
247 * \param samples number of samples
248 */
249void Rast_abs_log_colors(struct Colors *dst, struct Colors *src, int samples)
250{
251 DCELL min, max;
252 double absmin, absmax, amin, amax, delta, lamin, lamax;
253 int red, grn, blu;
254 DCELL prev;
255 int i;
256
257 Rast_init_colors(dst);
258
260
261 absmin = fabs(min);
262 absmax = fabs(max);
263 amin = MIN(absmin, absmax);
264 amax = MAX(absmin, absmax);
265
266 if (min * max <= 0.0) {
267 /* 0 <= abs(cell) <= amax */
268 amin = 0;
269 /* use the same shifting for Rast_log_colors */
270 delta = 1 - amin;
271 lamin = log(amin + delta);
272 lamax = log(amax + delta);
273 }
274 else {
275 /* 0 < amin <= abs(cell) <= amax */
276 delta = 0;
277 lamin = log(amin);
278 lamax = log(amax);
279 }
280
281 Rast_get_default_color(&red, &grn, &blu, src);
282 Rast_set_default_color(red, grn, blu, dst);
283
284 Rast_get_null_value_color(&red, &grn, &blu, src);
285 Rast_set_null_value_color(red, grn, blu, dst);
286
287 for (i = 0; i <= samples; i++) {
288 int red2, grn2, blu2;
289 double lx;
290 DCELL x, y;
291
292 y = min + (max - min) * i / samples;
293 Rast_get_d_color(&y, &red2, &grn2, &blu2, src);
294
295 if (i == 0)
296 x = amin;
297 else if (i == samples)
298 x = amax;
299 else {
300 lx = lamin + (lamax - lamin) * i / samples;
301 /* restore cell values approximately */
302 x = exp(lx) - delta;
303 }
304
305 if (i > 0) {
306 DCELL x0 = prev, x1 = x;
307
308 Rast_add_d_color_rule(&x0, red, grn, blu, &x1, red2, grn2, blu2,
309 dst);
310 x0 = -x0;
311 x1 = -x1;
312 Rast_add_d_color_rule(&x0, red, grn, blu, &x1, red2, grn2, blu2,
313 dst);
314 }
315
316 prev = x;
317
318 red = red2;
319 grn = grn2;
320 blu = blu2;
321 }
322}
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.
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.
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)
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:153
double DCELL
Definition gis.h:635
int CELL
Definition gis.h:634
#define MAX(a, b)
Definition gis.h:148
int count
Definition gis.h:692
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