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