GRASS 8 Programmer's Manual 8.6.0dev(2026)-55de52a352
Loading...
Searching...
No Matches
quant_io.c
Go to the documentation of this file.
1/*!
2 * \file lib/raster/quant_io.c
3 *
4 * \brief Raster Library - Quantization rules (input / output)
5 *
6 * SPDX-FileCopyrightText: 1999-2010 GRASS Development Team
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 *
9 * \author USACERL and many others
10 */
11
12/**********************************************************************
13 *
14 **********************************************************************/
15
16#include <string.h>
17
18#include <grass/gis.h>
19#include <grass/raster.h>
20#include <grass/glocale.h>
21
22#define QUANT_FILE_NAME "f_quant"
23
24static int quant_parse_file(FILE *, struct Quant *);
25
26#if 0
27/* redundant: integer range doesn't exist now: it is defined by
28 the quant rules */
29static int quant_load_range(struct Quant *quant, const char *name,
30 const char *mapset)
31{
32 struct FPRange fprange;
33 struct Range range;
34 char buf[300];
35 DCELL dMin, dMax;
36 CELL min, max;
37
38 if (Rast_read_fp_range(name, mapset, &fprange) <= 0)
39 return 0;
40 Rast_get_fp_range_min_max(&fprange, &dMin, &dMax);
41 if (Rast_is_d_null_value(&dMin) || Rast_is_d_null_value(&dMax)) {
42 G_warning(_("Floating data range for raster map <%s> is empty"),
44 return -3;
45 }
46
47 if (Rast_read_range(name, mapset, &range) < 0)
48 return 0;
49 Rast_get_range_min_max(&range, &min, &max);
51 G_warning(_("Integer data range for raster map <%s> is empty"),
53 return -3;
54 }
55
56 Rast_quant_add_rule(quant, dMin, dMax, min, max);
57
58 return 1;
59}
60#endif
61
62/*!
63 \brief Reads quantization rules (internal use only)
64
65 Reads quantization rules for raster map <i>name</i> in <i>mapset</i>
66 and stores them in the quantization structure "quant". If the map is
67 in another mapset, first checks for quant2 table for this map in
68 current mapset.
69
70 Note: in the case of negative return value, the result of using the
71 quantization structure is not defined.
72 in case of return value 0, calls to Rast_quant_perform_d()
73 and Rast_quant_perform_f() return NO_DATA (see description of
74 Rast_quant_perform_d() for more details). in case of
75 return values 2 and 3, the explicit rule for quant is set:
76 floating range is mapped to integer range.
77
78 Note: use Rast_quant_init() to allocate and initialize the quantization
79 staructure quant before the first usage of G_quant_import().
80
81 Note: this function uses Rast_quant_free () to clear all previously
82 stored rules in quant.
83
84 \param name map name
85 \param mapset mapset name
86 \param[out] quant pointer to Quant structure
87
88 \return -2 if raster map is of type integer.
89 \return -1 if map name is fully qualified and mapset is not the current one
90 \return 0 if quantization file does not exist, or the file is empty,
91 \return 1 if non-empty quantization file exists.
92 */
93int Rast__quant_import(const char *name, const char *mapset,
94 struct Quant *quant)
95{
96 char buf[1024];
98 int parsStat;
99 FILE *fd;
100
101 Rast_quant_free(quant);
102
103 if (Rast_map_type(name, mapset) == CELL_TYPE) {
104 char *mname = G_fully_qualified_name(name, mapset);
105 G_warning(_("Attempt to open quantization"
106 " table for CELL raster map <%s>"),
107 mname);
108 G_free(mname);
109 return -2;
110 }
111
113 if (strlen(mapset) == 0)
114 mapset = xmapset;
115 else if (strcmp(xmapset, mapset) != 0)
116 return -1;
117 name = xname;
118 }
119
120 /* first check if quant2/mapset/name exists in the current mapset */
121 snprintf(element, sizeof(element), "quant2/%s", mapset);
122 if ((fd = G_fopen_old(element, name, G_mapset()))) {
123 parsStat = quant_parse_file(fd, quant);
124 fclose(fd);
125 if (parsStat)
126 return 1;
127 snprintf(buf, sizeof(buf),
128 "quantization file in quant2 for raster map <%s> is empty",
130 }
131
132 /* now try reading regular : cell_misc/name/quant file */
133 if (!(fd = G_fopen_old_misc("cell_misc", QUANT_FILE_NAME, name, mapset))) {
134
135 /* int range doesn't exist anymore if (quant_load_range (quant, name,
136 * mapset)>0) return 3; */
137 char *mname = G_fully_qualified_name(name, mapset);
138 G_warning(_("Quantization file for raster map <%s> is missing"), mname);
139 G_free(mname);
140 }
141 else {
142 parsStat = quant_parse_file(fd, quant);
143 fclose(fd);
144
145 if (parsStat)
146 return 1;
147 /* int range doesn't exist anymore if (quant_load_range (quant, name,
148 * mapset)>0) return 2; */
149 G_warning(_("Quantization file for raster map <%s> is empty"),
151 }
152
153 return 0;
154}
155
156/*!
157 \brief Parse input lines with the following formats
158
159 \code
160 d_high:d_low:c_high:c_low
161 d_high:d_low:c_val (i.e. c_high == c_low)
162 *:d_val:c_val (interval [inf, d_val]) (**)
163 d_val:*:c_val (interval [d_val, inf]) (**)
164 \endcode
165
166 All other lines are ignored
167
168 (**) only the first appearances in the file are considered.
169 */
170static int quant_parse_file(FILE *fd, struct Quant *quant)
171{
172 CELL cLow, cHigh;
173 DCELL dLow, dHigh;
174 char buf[1024];
175 int foundNegInf = 0, foundPosInf = 0;
176
177 while (fgets(buf, sizeof(buf), fd)) {
178 if (strncmp(buf, "truncate", 8) == 0) {
179 quant->truncate_only = 1;
180 return 1;
181 }
182 if (strncmp(buf, "round", 5) == 0) {
183 quant->round_only = 1;
184 return 1;
185 }
186 switch (sscanf(buf, "%lf:%lf:%d:%d", &dLow, &dHigh, &cLow, &cHigh)) {
187 case 3:
188 Rast_quant_add_rule(quant, dLow, dHigh, cLow, cLow);
189 break;
190 case 4:
191 Rast_quant_add_rule(quant, dLow, dHigh, cLow, cHigh);
192 break;
193 default:
194 switch (sscanf(buf, "*:%lf:%d", &dLow, &cLow)) {
195 case 2:
196 if (!foundNegInf) {
197 Rast_quant_set_neg_infinite_rule(quant, dLow, cLow);
198 foundNegInf = 1;
199 }
200 break;
201 default:
202 switch (sscanf(buf, "%lf:*:%d", &dLow, &cLow)) {
203 case 2:
204 if (!foundPosInf) {
205 Rast_quant_set_pos_infinite_rule(quant, dLow, cLow);
206 foundPosInf = 1;
207 }
208 break;
209 default:
210 continue; /* other lines are ignored */
211 }
212 }
213 }
214 }
215
216 if (Rast_quant_nof_rules(quant) > 0)
218
219 return ((Rast_quant_nof_rules(quant) > 0) ||
220 (Rast_quant_get_neg_infinite_rule(quant, &dLow, &cLow) > 0) ||
221 (Rast_quant_get_pos_infinite_rule(quant, &dLow, &cLow) > 0));
222}
223
224static void quant_write(FILE *fd, const struct Quant *quant)
225{
226 DCELL dLow, dHigh;
227 CELL cLow, cHigh;
228 int i;
229
230 if (quant->truncate_only) {
231 fprintf(fd, "truncate");
232 return;
233 }
234 if (quant->round_only) {
235 fprintf(fd, "round");
236 return;
237 }
238 if (Rast_quant_get_neg_infinite_rule(quant, &dLow, &cLow) > 0)
239 fprintf(fd, "*:%.20g:%d\n", dLow, cLow);
240
241 if (Rast_quant_get_pos_infinite_rule(quant, &dLow, &cLow) > 0)
242 fprintf(fd, "%.20g:*:%d\n", dLow, cLow);
243
244 for (i = Rast_quant_nof_rules(quant) - 1; i >= 0; i--) {
245 Rast_quant_get_ith_rule(quant, i, &dLow, &dHigh, &cLow, &cHigh);
246 fprintf(fd, "%.20g:%.20g:%d", dLow, dHigh, cLow);
247 if (cLow != cHigh)
248 fprintf(fd, ":%d", cHigh);
249 fprintf(fd, "\n");
250 }
251}
252
253/*!
254 \brief Writes the quantization rules (internal use only)
255
256 Writes the quantization rules stored in <i>quant</i> for <i>name</i>
257 . If the mapset is the same as the current mapset, the quant file is
258 created in 'cell_misc/name' directory, otherwise it is created in
259 'quant2/mapset' directory, much like writing colors for map in
260 another mapset. The rules are written in decreasing order of
261 priority (i.e. rules added earlier are written later).
262
263 Note: if no rules are defined an empty file is created.
264
265 \param name map name
266 \param mapset mapset name
267 \param quant pointer to Quant structure
268
269 \return -1 if map name is not fully qualified or file could not be opened.
270 \return 1 otherwise.
271 */
272int Rast__quant_export(const char *name, const char *mapset,
273 const struct Quant *quant)
274{
275 char element[GNAME_MAX + 7];
277 FILE *fd;
278
280 if (strcmp(xmapset, mapset) != 0)
281 return -1;
282 name = xname;
283 }
284
285 if (strcmp(G_mapset(), mapset) == 0) {
286 G_remove_misc("cell_misc", QUANT_FILE_NAME, name);
287 G__make_mapset_element_misc("cell_misc", name);
288 if (!(fd = G_fopen_new_misc("cell_misc", QUANT_FILE_NAME, name)))
289 return -1;
290 }
291 else {
292 snprintf(element, sizeof(element), "quant2/%s", mapset);
295 if (!(fd = G_fopen_new(element, name)))
296 return -1;
297 }
298
299 quant_write(fd, quant);
300 fclose(fd);
301
302 return 1;
303}
int G_name_is_fully_qualified(const char *, char *, char *)
Check if map name is fully qualified (map @ mapset)
Definition nme_in_mps.c:34
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:145
int G__make_mapset_element_misc(const char *, const char *)
Create misc element in the current mapset.
Definition mapset_msc.c:259
void G_warning(const char *,...) __attribute__((format(printf
FILE * G_fopen_new(const char *, const char *)
Open a new database file.
Definition gis/open.c:218
int G_make_mapset_object_group(const char *)
Create directory for group of elements of a given type.
Definition mapset_msc.c:73
FILE * G_fopen_old(const char *, const char *, const char *)
Open a database file for reading.
Definition gis/open.c:250
char * G_fully_qualified_name(const char *, const char *)
Get fully qualified element name.
Definition nme_in_mps.c:99
int G_remove(const char *, const char *)
Remove a database file.
Definition remove.c:41
int G_remove_misc(const char *, const char *, const char *)
Remove a database misc file.
Definition remove.c:62
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
FILE * G_fopen_new_misc(const char *, const char *, const char *)
open a new database misc file
Definition open_misc.c:183
const char * G_mapset(void)
Get current mapset name.
Definition gis/mapset.c:31
int Rast_quant_get_neg_infinite_rule(const struct Quant *, DCELL *, CELL *)
Returns in "dLeft" and "c" the rule values.
Definition quant.c:388
int Rast_read_fp_range(const char *, const char *, struct FPRange *)
Read floating-point range.
void Rast_quant_set_pos_infinite_rule(struct Quant *, DCELL, CELL)
Defines a rule for values "dRight" and larger.
Definition quant.c:410
void Rast_quant_free(struct Quant *)
Resets and frees allocated memory.
Definition quant.c:53
void Rast_quant_set_neg_infinite_rule(struct Quant *, DCELL, CELL)
Defines a rule for values "dLeft" and smaller.
Definition quant.c:362
void Rast_get_fp_range_min_max(const struct FPRange *, DCELL *, DCELL *)
Get minimum and maximum value from fp range.
void Rast_quant_reverse_rule_order(struct Quant *)
Rreverses the order in which the qunatization rules are stored.
Definition quant.c:511
RASTER_MAP_TYPE Rast_map_type(const char *, const char *)
Determine raster data type.
void Rast_quant_add_rule(struct Quant *, DCELL, DCELL, CELL, CELL)
Adds a new rule to the set of quantization rules.
Definition quant.c:467
void Rast_get_range_min_max(const struct Range *, CELL *, CELL *)
Get range min and max.
int Rast_read_range(const char *, const char *, struct Range *)
Read raster range (CELL)
void Rast_quant_get_ith_rule(const struct Quant *, int, DCELL *, DCELL *, CELL *, CELL *)
Returns the i'th quantization rule.
Definition quant.c:325
int Rast_quant_get_pos_infinite_rule(const struct Quant *, DCELL *, CELL *)
Returns in "dRight" and "c" the rule values.
Definition quant.c:436
#define Rast_is_d_null_value(dcellVal)
#define Rast_is_c_null_value(cellVal)
int Rast_quant_nof_rules(const struct Quant *)
Returns the number of quantization rules defined.
Definition quant.c:307
#define min(x, y)
Definition draw2.c:29
#define max(x, y)
Definition draw2.c:30
#define GMAPSET_MAX
Definition gis.h:194
#define GNAME_MAX
Definition gis.h:193
double DCELL
Definition gis.h:632
int CELL
Definition gis.h:631
#define _(str)
Definition glocale.h:10
const char * name
Definition named_colr.c:6
#define QUANT_FILE_NAME
Definition quant_io.c:22
int Rast__quant_export(const char *name, const char *mapset, const struct Quant *quant)
Writes the quantization rules (internal use only)
Definition quant_io.c:272
int Rast__quant_import(const char *name, const char *mapset, struct Quant *quant)
Reads quantization rules (internal use only)
Definition quant_io.c:93
#define CELL_TYPE
Definition raster.h:11
Definition raster.h:80
int truncate_only
Definition raster.h:81
int round_only
Definition raster.h:82