GRASS 8 Programmer's Manual 8.6.0dev(2026)-ddeab64dbf
Loading...
Searching...
No Matches
raster3d/header.c
Go to the documentation of this file.
1#include <stdio.h>
2#include <stdlib.h>
3#include <sys/types.h>
4#include <unistd.h>
5#include <grass/raster3d.h>
6#include <grass/glocale.h>
7#include "raster3d_intern.h"
8
9/*---------------------------------------------------------------------------*/
10
13void *xdr;
15
16/*---------------------------------------------------------------------------*/
17
18#define RASTER3D_HEADER_TILEX "TileDimensionX"
19#define RASTER3D_HEADER_TILEY "TileDimensionY"
20#define RASTER3D_HEADER_TILEZ "TileDimensionZ"
21#define RASTER3D_HEADER_TYPE "CellType"
22#define RASTER3D_HEADER_COMPRESSION "useCompression"
23#define RASTER3D_HEADER_USERLE "useRle"
24#define RASTER3D_HEADER_USELZW "useLzw"
25#define RASTER3D_HEADER_PRECISION "Precision"
26#define RASTER3D_HEADER_DATA_OFFSET "nofHeaderBytes"
27#define RASTER3D_HEADER_USEXDR "useXdr"
28#define RASTER3D_HEADER_HASINDEX "hasIndex"
29#define RASTER3D_HEADER_UNIT "Units"
30#define RASTER3D_HEADER_VERTICAL_UNIT "VerticalUnits"
31#define RASTER3D_HEADER_VERSION "Version"
32
33/*---------------------------------------------------------------------------*/
34
35static int Rast3d__readHeader(
36 struct Key_Value *headerKeys, int *proj, int *zone, double *north,
37 double *south, double *east, double *west, double *top, double *bottom,
38 int *rows, int *cols, int *depths, double *ew_res, double *ns_res,
39 double *tb_res, int *tileX, int *tileY, int *tileZ, int *type,
40 int *compression, int *useRle, int *useLzw, int *precision, int *dataOffset,
41 int *useXdr, int *hasIndex, char **unit, int *vertical_unit, int *version)
42{
43 int returnVal;
44 int (*headerInt)(struct Key_Value *, const char *, int *),
45 (*headerDouble)(struct Key_Value *, const char *, double *),
46 (*headerValue)(struct Key_Value *, const char *, char *, char *, int,
47 int, int *);
48 int (*headerString)(struct Key_Value *, const char *, char **);
49
54
55 returnVal = 1;
58
65
69
73
77
79 "float", DCELL_TYPE, FCELL_TYPE, type);
81 0, 1, compression);
82 returnVal &=
83 headerValue(headerKeys, RASTER3D_HEADER_USERLE, "0", "1", 0, 1, useRle);
84 returnVal &=
85 headerValue(headerKeys, RASTER3D_HEADER_USELZW, "0", "1", 0, 1, useLzw);
86
89
90 returnVal &=
91 headerValue(headerKeys, RASTER3D_HEADER_USEXDR, "0", "1", 0, 1, useXdr);
93 1, hasIndex);
95 /* New format and API changes */
97 G_warning("You are using an old raster3d data format, the vertical "
98 "unit is undefined. "
99 "Please use r3.support to define the vertical unit to avoid "
100 "this warning.");
101 /* New format and API changes */
103 G_warning("You are using an old raster3d data format, the version is "
104 "undefined.");
105 *version = 1;
106 }
107
108 if (returnVal)
109 return 1;
110
111 Rast3d_error("Rast3d_readWriteHeader: error reading/writing header");
112 return 0;
113}
114
115static int Rast3d__writeHeader(
116 struct Key_Value *headerKeys, int *proj, int *zone, double *north,
117 double *south, double *east, double *west, double *top, double *bottom,
118 int *rows, int *cols, int *depths, double *ew_res, double *ns_res,
119 double *tb_res, int *tileX, int *tileY, int *tileZ, int *type,
120 int *compression, int *useRle, int *useLzw, int *precision, int *dataOffset,
121 int *useXdr, int *hasIndex, char **unit, int *vertical_unit, int *version)
122{
123 int returnVal;
124 int (*headerInt)(struct Key_Value *, const char *, const int *),
125 (*headerDouble)(struct Key_Value *, const char *, const double *),
126 (*headerValue)(struct Key_Value *, const char *, const char *,
127 const char *, int, int, const int *);
128 int (*headerString)(struct Key_Value *, const char *, char *const *);
129
134
135 returnVal = 1;
138
145
149
153
157
159 "float", DCELL_TYPE, FCELL_TYPE, type);
161 0, 1, compression);
162 returnVal &=
163 headerValue(headerKeys, RASTER3D_HEADER_USERLE, "0", "1", 0, 1, useRle);
164 returnVal &=
165 headerValue(headerKeys, RASTER3D_HEADER_USELZW, "0", "1", 0, 1, useLzw);
166
169
170 returnVal &=
171 headerValue(headerKeys, RASTER3D_HEADER_USEXDR, "0", "1", 0, 1, useXdr);
173 1, hasIndex);
175 /* New format and API changes */
177 G_warning("You are using an old raster3d data format, the vertical "
178 "unit is undefined. "
179 "Please use r3.support to define the vertical unit to avoid "
180 "this warning.");
181 /* New format and API changes */
183 G_warning("You are using an old raster3d data format, the version is "
184 "undefined.");
185 *version = 1;
186 }
187
188 if (returnVal)
189 return 1;
190
191 Rast3d_error("Rast3d_readWriteHeader: error reading/writing header");
192 return 0;
193}
194
195/*---------------------------------------------------------------------------*/
196
197int Rast3d_read_header(RASTER3D_Map *map, int *proj, int *zone, double *north,
198 double *south, double *east, double *west, double *top,
199 double *bottom, int *rows, int *cols, int *depths,
200 double *ew_res, double *ns_res, double *tb_res,
201 int *tileX, int *tileY, int *tileZ, int *type,
202 int *compression, int *useRle, int *useLzw,
203 int *precision, int *dataOffset, int *useXdr,
204 int *hasIndex, char **unit, int *vertical_unit,
205 int *version)
206{
207 struct Key_Value *headerKeys;
208 char path[GPATH_MAX];
209
211 if (access(path, R_OK) != 0) {
212 Rast3d_error("Rast3d_read_header: unable to find [%s]", path);
213 return 0;
214 }
215
217
218 if (!Rast3d__readHeader(headerKeys, proj, zone, north, south, east, west,
219 top, bottom, rows, cols, depths, ew_res, ns_res,
220 tb_res, tileX, tileY, tileZ, type, compression,
221 useRle, useLzw, precision, dataOffset, useXdr,
222 hasIndex, unit, vertical_unit, version)) {
224 "Rast3d_read_header: error extracting header key(s) of file %s",
225 path);
226 return 0;
227 }
228
230 return 1;
231}
232
233/*---------------------------------------------------------------------------*/
234
235int Rast3d_write_header(RASTER3D_Map *map, int proj, int zone, double north,
236 double south, double east, double west, double top,
237 double bottom, int rows, int cols, int depths,
238 double ew_res, double ns_res, double tb_res, int tileX,
239 int tileY, int tileZ, int type, int compression,
240 int useRle, int useLzw, int precision, int dataOffset,
241 int useXdr, int hasIndex, char *unit, int vertical_unit,
242 int version)
243{
244 struct Key_Value *headerKeys;
245 char path[GPATH_MAX];
246
248
249 if (!Rast3d__writeHeader(
250 headerKeys, &proj, &zone, &north, &south, &east, &west, &top,
251 &bottom, &rows, &cols, &depths, &ew_res, &ns_res, &tb_res, &tileX,
252 &tileY, &tileZ, &type, &compression, &useRle, &useLzw, &precision,
253 &dataOffset, &useXdr, &hasIndex, &unit, &vertical_unit, &version)) {
255 "Rast3d_write_header: error adding header key(s) for file %s",
256 path);
257 return 0;
258 }
259
263
265
266 return 1;
267}
268
269/*---------------------------------------------------------------------------*/
270
272{
274 map, map->region.proj, map->region.zone, map->region.north,
275 map->region.south, map->region.east, map->region.west,
276 map->region.top, map->region.bottom, map->region.rows,
277 map->region.cols, map->region.depths, map->region.ew_res,
278 map->region.ns_res, map->region.tb_res, map->tileX, map->tileY,
279 map->tileZ, map->type, map->compression, map->useRle, map->useLzw,
280 map->precision, map->offset, map->useXdr, map->hasIndex, map->unit,
281 map->vertical_unit, map->version)) {
282 G_warning(_("Unable to write header for 3D raster map <%s>"),
283 map->fileName);
284 return 0;
285 }
286 return 1;
287}
288
289/*---------------------------------------------------------------------------*/
290
291/*!
292 * \brief
293 *
294 * Returns a number
295 * which encodes multiplicity <em>n</em> of <em>cacheCode</em>. This value can
296 * be used to specify the size of the cache. If <em>cacheCode</em> is the size
297 * (in tiles) of the cache the function returns <em>cacheCode * n</em>. If
298 * <em>cacheCode</em> is RASTER3D_USE_CACHE_DEFAULT the function returns
299 * RASTER3D_USE_CACHE_DEFAULT.
300 * If <em>cacheCode</em> is RASTER3D_USE_CACHE_??? the function returns a value
301 * encoding RASTER3D_USE_CACHE_??? and <em>n</em>. Here RASTER3D_USE_CACHE_???
302 * is one of RASTER3D_USE_CACHE_X, RASTER3D_USE_CACHE_Y, RASTER3D_USE_CACHE_Z,
303 * RASTER3D_USE_CACHE_XY, RASTER3D_USE_CACHE_XZ, RASTER3D_USE_CACHE_YZ, or
304 * RASTER3D_USE_CACHE_XYZ, where e.g. RASTER3D_USE_CACHE_X specifies that the
305 * cache should store as many tiles as there exist in one row along the x-axis
306 * of the tile cube, and RASTER3D_USE_CACHE_XY specifies that the cache should
307 * store as many tiles as there exist in one slice of the tile cube with
308 * constant Z coordinate.
309 *
310 * \param cacheCode
311 * \param n
312 * \return int
313 */
315{
317 return cacheCode * n;
319 return cacheCode;
320
322 Rast3d_fatal_error("Rast3d_cache_size_encode: invalid cache code");
323
324 return n * (-10) + cacheCode;
325}
326
327/*---------------------------------------------------------------------------*/
328
330{
331 int n, size;
332
334 return cacheCode;
337
338 n = -(cacheCode / 10);
339 n = RASTER3D_MAX(1, n);
340 cacheCode = -((-cacheCode) % 10);
341
343 size = map->nx * n;
345 size = map->ny * n;
347 size = map->nz * n;
349 size = map->nxy * n;
351 size = map->nx * map->nz * n;
353 size = map->ny * map->nz * n;
355 size = map->nTiles;
356 else
357 Rast3d_fatal_error("Rast3d__compute_cache_size: invalid cache code");
358
359 return RASTER3D_MIN(size, map->nTiles);
360}
361
362/*---------------------------------------------------------------------------*/
363
364/* this function does actually more than filling the header fields of the */
365/* RASTER3D-Map structure. It also allocates memory for compression and xdr, */
366/* and initializes the index and cache. This function should be taken apart. */
367
368int Rast3d_fill_header(RASTER3D_Map *map, int operation, int compression,
369 int useRle, int useLzw, int type, int precision,
370 int cache, int hasIndex, int useXdr, int typeIntern,
371 int nofHeaderBytes, int tileX, int tileY, int tileZ,
372 int proj, int zone, double north, double south,
373 double east, double west, double top, double bottom,
374 int rows, int cols, int depths, double ew_res,
375 double ns_res, double tb_res, char *unit,
376 int vertical_unit, int version)
377{
378 if (!RASTER3D_VALID_OPERATION(operation))
379 Rast3d_fatal_error("Rast3d_fill_header: operation not valid\n");
380
381 map->version = version;
382
383 map->operation = operation;
384
385 map->unit = G_store(unit);
386 map->vertical_unit = vertical_unit;
387
388 map->region.proj = proj;
389 map->region.zone = zone;
390
391 map->region.north = north;
392 map->region.south = south;
393 map->region.east = east;
394 map->region.west = west;
395 map->region.top = top;
396 map->region.bottom = bottom;
397
398 map->region.rows = rows;
399 map->region.cols = cols;
400 map->region.depths = depths;
401
402 map->region.ew_res = ew_res;
403 map->region.ns_res = ns_res;
404 map->region.tb_res = tb_res;
405
407
408 map->tileX = tileX;
409 map->tileY = tileY;
410 map->tileZ = tileZ;
411 map->tileXY = map->tileX * map->tileY;
412 map->tileSize = map->tileXY * map->tileZ;
413
414 map->nx = (map->region.cols - 1) / tileX + 1;
415 map->ny = (map->region.rows - 1) / tileY + 1;
416 map->nz = (map->region.depths - 1) / tileZ + 1;
417 map->nxy = map->nx * map->ny;
418 map->nTiles = map->nxy * map->nz;
419
420 if ((map->region.cols) % map->tileX != 0)
421 map->clipX = map->nx - 1;
422 else
423 map->clipX = -1;
424 if ((map->region.rows) % map->tileY != 0)
425 map->clipY = map->ny - 1;
426 else
427 map->clipY = -1;
428 if ((map->region.depths) % map->tileZ != 0)
429 map->clipZ = map->nz - 1;
430 else
431 map->clipZ = -1;
432
433 if ((type != FCELL_TYPE) && (type != DCELL_TYPE))
434 Rast3d_fatal_error("Rast3d_fill_header: invalid type");
435 map->type = type;
436
437 if ((typeIntern != FCELL_TYPE) && (typeIntern != DCELL_TYPE))
438 Rast3d_fatal_error("Rast3d_fill_header: invalid type");
439 map->typeIntern = typeIntern;
440
441 if (!RASTER3D_VALID_XDR_OPTION(useXdr))
442 Rast3d_fatal_error("Rast3d_fill_header: invalid xdr option");
443 map->useXdr = useXdr; /* Only kept for backward compatibility */
444
445 map->offset = nofHeaderBytes;
446
447 if ((map->fileEndPtr = lseek(map->data_fd, (long)0, SEEK_END)) == -1) {
448 Rast3d_error("Rast3d_fill_header: can't position file");
449 return 0;
450 }
451
452 map->useCache = (cache != RASTER3D_NO_CACHE);
453
456
458 map->useRle = useRle; /* Only kept for backward compatibility */
459 map->useLzw = useLzw; /* Only kept for backward compatibility */
460 map->precision = precision;
461
462#define RLE_STATUS_BYTES 2
463
465 if (tmpCompress == NULL) {
467 map->tileSize *
471 if (tmpCompress == NULL) {
472 Rast3d_error("Rast3d_fill_header: error in Rast3d_malloc");
473 return 0;
474 }
475 }
476 else if (map->tileSize * RASTER3D_MAX(map->numLengthIntern,
477 map->numLengthExtern) +
481 map->tileSize *
485 if (tmpCompress == NULL) {
486 Rast3d_error("Rast3d_fill_header: error in Rast3d_realloc");
487 return 0;
488 }
489 }
490 }
491
492#define XDR_MISUSE_BYTES 10
493
495 Rast3d_error("Rast3d_fill_header: error in Rast3d_init_fp_xdr");
496 return 0;
497 }
498
499 if ((!map->useCache) ||
500 ((cache == RASTER3D_USE_CACHE_DEFAULT) && (g3d_cache_default == 0))) {
501 map->useCache = 0;
502 map->cache = NULL;
503 /* allocate one tile buffer */
504 map->data = Rast3d_malloc(map->tileSize * map->numLengthIntern);
505 if (map->data == NULL) {
506 Rast3d_error("Rast3d_fill_header: error in Rast3d_malloc");
507 return 0;
508 }
509 map->currentIndex = -1;
510 }
511 else {
513 map, RASTER3D_MAX(
515 g3d_cache_max / map->tileSize /
516 map->numLengthIntern)))) {
517 Rast3d_error("Rast3d_fill_header: error in Rast3d_init_cache");
518 return 0;
519 }
520 }
521
522 if (!Rast3d_init_index(map, hasIndex)) {
523 Rast3d_error("Rast3d_fill_header: error in Rast3d_init_index");
524 return 0;
525 }
526
527 return 1;
528}
#define NULL
Definition ccmath.h:32
int g3d_cache_max
Definition defaults.c:68
int g3d_cache_default
Definition defaults.c:67
void G_warning(const char *,...) __attribute__((format(printf
void G_free_key_value(struct Key_Value *)
Free allocated Key_Value structure.
Definition key_value1.c:104
struct Key_Value * G_read_key_value_file(const char *)
Read key/values pairs from file.
Definition key_value3.c:55
struct Key_Value * G_create_key_value(void)
Allocate and initialize Key_Value structure.
Definition key_value1.c:23
void G_write_key_value_file(const char *, const struct Key_Value *)
Write key/value pairs to file.
Definition key_value3.c:28
char * G_store(const char *)
Copy string to allocated memory.
Definition strings.c:87
void Rast3d_filename(char *, const char *, const char *, const char *)
Definition filename.c:9
void * Rast3d_realloc(void *, int)
Same as realloc (ptr, nBytes), except that in case of error Rast3d_error() is invoked.
void Rast3d_make_mapset_map_directory(const char *)
int Rast3d_key_set_int(struct Key_Value *, const char *, const int *)
Definition keys.c:93
int Rast3d_key_get_string(struct Key_Value *, const char *, char **)
Definition keys.c:48
int Rast3d_init_index(RASTER3D_Map *, int)
int Rast3d_key_set_string(struct Key_Value *, const char *, char *const *)
Definition keys.c:116
void Rast3d_adjust_region(RASTER3D_Region *)
Computes an adjusts the resolutions in the region structure from the region boundaries and number of ...
Definition region.c:144
int Rast3d_init_fp_xdr(RASTER3D_Map *, int)
Definition fpxdr.c:65
int Rast3d_key_get_int(struct Key_Value *, const char *, int *)
Definition keys.c:7
int Rast3d_key_set_value(struct Key_Value *, const char *, const char *, const char *, int, int, const int *)
Definition keys.c:125
int Rast3d_length(int)
int Rast3d_extern_length(int)
void * Rast3d_malloc(int)
Same as malloc (nBytes), except that in case of error Rast3d_error() is invoked.
int Rast3d_key_get_double(struct Key_Value *, const char *, double *)
Definition keys.c:27
void Rast3d_error(const char *,...) __attribute__((format(printf
int Rast3d_key_set_double(struct Key_Value *, const char *, const double *)
Definition keys.c:104
int Rast3d_key_get_value(struct Key_Value *, const char *, char *, char *, int, int, int *)
Definition keys.c:66
void Rast3d_fatal_error(const char *,...) __attribute__((format(printf
int Rast3d_init_cache(RASTER3D_Map *, int)
Definition cache.c:221
#define GPATH_MAX
Definition gis.h:199
#define _(str)
Definition glocale.h:10
unsigned short compression
Definition gsd_img_tif.c:42
#define RASTER3D_HEADER_PRECISION
int Rast3d_rewrite_header(RASTER3D_Map *map)
#define RASTER3D_HEADER_VERTICAL_UNIT
int Rast3d__compute_cache_size(RASTER3D_Map *map, int cacheCode)
#define RASTER3D_HEADER_USEXDR
#define RASTER3D_HEADER_VERSION
#define RASTER3D_HEADER_HASINDEX
#define RASTER3D_HEADER_TILEX
#define RASTER3D_HEADER_USELZW
#define RASTER3D_HEADER_UNIT
#define RASTER3D_HEADER_TYPE
void * xdr
int Rast3d_read_header(RASTER3D_Map *map, int *proj, int *zone, double *north, double *south, double *east, double *west, double *top, double *bottom, int *rows, int *cols, int *depths, double *ew_res, double *ns_res, double *tb_res, int *tileX, int *tileY, int *tileZ, int *type, int *compression, int *useRle, int *useLzw, int *precision, int *dataOffset, int *useXdr, int *hasIndex, char **unit, int *vertical_unit, int *version)
#define RASTER3D_HEADER_USERLE
int Rast3d_cache_size_encode(int cacheCode, int n)
Returns a number which encodes multiplicity n of cacheCode. This value can be used to specify the siz...
int xdrLength
#define RASTER3D_HEADER_COMPRESSION
#define RASTER3D_HEADER_DATA_OFFSET
void * tmpCompress
int Rast3d_fill_header(RASTER3D_Map *map, int operation, int compression, int useRle, int useLzw, int type, int precision, int cache, int hasIndex, int useXdr, int typeIntern, int nofHeaderBytes, int tileX, int tileY, int tileZ, int proj, int zone, double north, double south, double east, double west, double top, double bottom, int rows, int cols, int depths, double ew_res, double ns_res, double tb_res, char *unit, int vertical_unit, int version)
int Rast3d_write_header(RASTER3D_Map *map, int proj, int zone, double north, double south, double east, double west, double top, double bottom, int rows, int cols, int depths, double ew_res, double ns_res, double tb_res, int tileX, int tileY, int tileZ, int type, int compression, int useRle, int useLzw, int precision, int dataOffset, int useXdr, int hasIndex, char *unit, int vertical_unit, int version)
#define RASTER3D_HEADER_TILEY
int tmpCompressLength
#define XDR_MISUSE_BYTES
#define RLE_STATUS_BYTES
#define RASTER3D_HEADER_TILEZ
#define RASTER3D_HEADER_ELEMENT
Definition raster3d.h:35
#define RASTER3D_USE_CACHE_X
Definition raster3d.h:20
#define RASTER3D_USE_CACHE_XZ
Definition raster3d.h:24
#define RASTER3D_USE_CACHE_YZ
Definition raster3d.h:25
#define RASTER3D_NO_COMPRESSION
Definition raster3d.h:13
#define RASTER3D_USE_CACHE_DEFAULT
Definition raster3d.h:19
#define RASTER3D_NO_CACHE
Definition raster3d.h:18
#define RASTER3D_USE_CACHE_XY
Definition raster3d.h:23
#define RASTER3D_USE_CACHE_Z
Definition raster3d.h:22
#define RASTER3D_USE_CACHE_Y
Definition raster3d.h:21
#define RASTER3D_USE_CACHE_XYZ
Definition raster3d.h:26
#define RASTER3D_REGION_COLS
#define RASTER3D_REGION_EAST
#define RASTER3D_REGION_PROJ
#define RASTER3D_REGION_NORTH
#define RASTER3D_VALID_XDR_OPTION(o)
#define RASTER3D_REGION_DEPTHS
#define RASTER3D_REGION_WEST
#define RASTER3D_REGION_NSRES
#define RASTER3D_VALID_OPERATION(o)
#define RASTER3D_REGION_ZONE
#define RASTER3D_MIN(a, b)
#define RASTER3D_REGION_ROWS
#define RASTER3D_REGION_BOTTOM
#define RASTER3D_REGION_TBRES
#define RASTER3D_REGION_SOUTH
#define RASTER3D_MAX(a, b)
#define RASTER3D_REGION_EWRES
#define RASTER3D_REGION_TOP
#define FCELL_TYPE
Definition raster.h:12
#define DCELL_TYPE
Definition raster.h:13
int numLengthExtern
Definition raster3d.h:173
int compression
Definition raster3d.h:111
char * fileName
Definition raster3d.h:74
RASTER3D_Region region
Definition raster3d.h:82
int currentIndex
Definition raster3d.h:156
char * data
Definition raster3d.h:153
void * cache
Definition raster3d.h:161
char * mapset
Definition raster3d.h:76
char * unit
Definition raster3d.h:91
int operation
Definition raster3d.h:79
int vertical_unit
Definition raster3d.h:92
int numLengthIntern
Definition raster3d.h:176
double tb_res
Definition raster3d.h:56
double ns_res
Definition raster3d.h:56
double ew_res
Definition raster3d.h:56
double bottom
Definition raster3d.h:51
Definition path.h:15
#define access
Definition unistd.h:7
#define R_OK
Definition unistd.h:25