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