GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
g3d/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 <rpc/types.h>
6 #include <rpc/xdr.h>
7 #include <grass/G3d.h>
8 #include "G3d_intern.h"
9 
10 /*---------------------------------------------------------------------------*/
11 
14 void *xdr;
16 
17 /*---------------------------------------------------------------------------*/
18 
19 #define G3D_HEADER_TILEX "TileDimensionX"
20 #define G3D_HEADER_TILEY "TileDimensionY"
21 #define G3D_HEADER_TILEZ "TileDimensionZ"
22 #define G3D_HEADER_TYPE "CellType"
23 #define G3D_HEADER_COMPRESSION "useCompression"
24 #define G3D_HEADER_USERLE "useRle"
25 #define G3D_HEADER_USELZW "useLzw"
26 #define G3D_HEADER_PRECISION "Precision"
27 #define G3D_HEADER_DATA_OFFSET "nofHeaderBytes"
28 #define G3D_HEADER_USEXDR "useXdr"
29 #define G3D_HEADER_HASINDEX "hasIndex"
30 #define G3D_HEADER_UNIT "Units"
31 
32 /*---------------------------------------------------------------------------*/
33 
34 static int
35 G3d_readWriteHeader(struct Key_Value *headerKeys, int doRead, int *proj,
36  int *zone, double *north, double *south, double *east,
37  double *west, double *top, double *bottom, int *rows,
38  int *cols, int *depths, double *ew_res, double *ns_res,
39  double *tb_res, int *tileX, int *tileY, int *tileZ,
40  int *type, int *compression, int *useRle, int *useLzw,
41  int *precision, int *dataOffset, int *useXdr,
42  int *hasIndex, char **unit)
43 {
44  int returnVal;
45  int (*headerInt) (), (*headerDouble) (), (*headerValue) ();
46  int (*headerString) ();
47 
48  if (doRead) {
49  headerDouble = G3d_keyGetDouble;
50  headerInt = G3d_keyGetInt;
51  headerString = G3d_keyGetString;
52  headerValue = G3d_keyGetValue;
53  }
54  else {
55  headerDouble = G3d_keySetDouble;
56  headerInt = G3d_keySetInt;
57  headerString = G3d_keySetString;
58  headerValue = G3d_keySetValue;
59  }
60 
61  returnVal = 1;
62  returnVal &= headerInt(headerKeys, G3D_REGION_PROJ, proj);
63  returnVal &= headerInt(headerKeys, G3D_REGION_ZONE, zone);
64 
65  returnVal &= headerDouble(headerKeys, G3D_REGION_NORTH, north);
66  returnVal &= headerDouble(headerKeys, G3D_REGION_SOUTH, south);
67  returnVal &= headerDouble(headerKeys, G3D_REGION_EAST, east);
68  returnVal &= headerDouble(headerKeys, G3D_REGION_WEST, west);
69  returnVal &= headerDouble(headerKeys, G3D_REGION_TOP, top);
70  returnVal &= headerDouble(headerKeys, G3D_REGION_BOTTOM, bottom);
71 
72  returnVal &= headerInt(headerKeys, G3D_REGION_ROWS, rows);
73  returnVal &= headerInt(headerKeys, G3D_REGION_COLS, cols);
74  returnVal &= headerInt(headerKeys, G3D_REGION_DEPTHS, depths);
75 
76  returnVal &= headerDouble(headerKeys, G3D_REGION_NSRES, ns_res);
77  returnVal &= headerDouble(headerKeys, G3D_REGION_EWRES, ew_res);
78  returnVal &= headerDouble(headerKeys, G3D_REGION_TBRES, tb_res);
79 
80  returnVal &= headerInt(headerKeys, G3D_HEADER_TILEX, tileX);
81  returnVal &= headerInt(headerKeys, G3D_HEADER_TILEY, tileY);
82  returnVal &= headerInt(headerKeys, G3D_HEADER_TILEZ, tileZ);
83 
84  returnVal &= headerValue(headerKeys, G3D_HEADER_TYPE,
85  "double", "float", DCELL_TYPE, FCELL_TYPE, type);
86  returnVal &= headerValue(headerKeys, G3D_HEADER_COMPRESSION,
87  "0", "1", 0, 1, compression);
88  returnVal &= headerValue(headerKeys, G3D_HEADER_USERLE,
89  "0", "1", 0, 1, useRle);
90  returnVal &= headerValue(headerKeys, G3D_HEADER_USELZW,
91  "0", "1", 0, 1, useLzw);
92 
93  returnVal &= headerInt(headerKeys, G3D_HEADER_PRECISION, precision);
94  returnVal &= headerInt(headerKeys, G3D_HEADER_DATA_OFFSET, dataOffset);
95 
96  returnVal &= headerValue(headerKeys, G3D_HEADER_USEXDR,
97  "0", "1", 0, 1, useXdr);
98  returnVal &= headerValue(headerKeys, G3D_HEADER_HASINDEX,
99  "0", "1", 0, 1, hasIndex);
100  returnVal &= headerString(headerKeys, G3D_HEADER_UNIT, unit);
101 
102  if (returnVal)
103  return 1;
104 
105  G3d_error("G3d_readWriteHeader: error writing header");
106  return 0;
107 }
108 
109 /*---------------------------------------------------------------------------*/
110 
111 int
112 G3d_readHeader(G3D_Map * map, int *proj, int *zone, double *north,
113  double *south, double *east, double *west, double *top,
114  double *bottom, int *rows, int *cols, int *depths,
115  double *ew_res, double *ns_res, double *tb_res, int *tileX,
116  int *tileY, int *tileZ, int *type, int *compression,
117  int *useRle, int *useLzw, int *precision, int *dataOffset,
118  int *useXdr, int *hasIndex, char **unit)
119 {
120  struct Key_Value *headerKeys;
121  char path[GPATH_MAX];
122  int status;
123 
124  G3d_filename(path, G3D_HEADER_ELEMENT, map->fileName, map->mapset);
125  if (access(path, R_OK) != 0) {
126  G3d_error("G3d_readHeader: unable to find [%s]", path);
127  return 0;
128  }
129 
130  headerKeys = G_read_key_value_file(path, &status);
131  if (status != 0) {
132  G3d_error("G3d_readHeader: Unable to open %s", path);
133  return 0;
134  }
135 
136  if (!G3d_readWriteHeader(headerKeys, 1,
137  proj, zone,
138  north, south, east, west, top, bottom,
139  rows, cols, depths,
140  ew_res, ns_res, tb_res,
141  tileX, tileY, tileZ,
142  type, compression, useRle, useLzw, precision,
143  dataOffset, useXdr, hasIndex, unit)) {
144  G3d_error("G3d_readHeader: error extracting header key(s) of file %s",
145  path);
146  return 0;
147  }
148 
149  G_free_key_value(headerKeys);
150  return 1;
151 }
152 
153 /*---------------------------------------------------------------------------*/
154 
155 int
156 G3d_writeHeader(G3D_Map * map, int proj, int zone, double north, double south,
157  double east, double west, double top, double bottom, int rows,
158  int cols, int depths, double ew_res, double ns_res,
159  double tb_res, int tileX, int tileY, int tileZ, int type,
160  int compression, int useRle, int useLzw, int precision,
161  int dataOffset, int useXdr, int hasIndex, char *unit)
162 {
163  struct Key_Value *headerKeys;
164  char path[GPATH_MAX];
165  int status;
166 
167  headerKeys = G_create_key_value();
168 
169  if (!G3d_readWriteHeader(headerKeys, 0,
170  &proj, &zone,
171  &north, &south, &east, &west, &top, &bottom,
172  &rows, &cols, &depths,
173  &ew_res, &ns_res, &tb_res,
174  &tileX, &tileY, &tileZ,
175  &type, &compression, &useRle, &useLzw,
176  &precision, &dataOffset, &useXdr, &hasIndex,
177  &unit)) {
178  G3d_error("G3d_writeHeader: error adding header key(s) for file %s",
179  path);
180  return 0;
181  }
182 
183  G3d_filename(path, G3D_HEADER_ELEMENT, map->fileName, map->mapset);
184  G3d_makeMapsetMapDirectory(map->fileName);
185  G_write_key_value_file(path, headerKeys, &status);
186 
187  G_free_key_value(headerKeys);
188 
189  if (status == 0)
190  return 1;
191 
192  G3d_error("G3d_writeHeader: error writing header file %s", path);
193  return 0;
194 }
195 
196 /*---------------------------------------------------------------------------*/
197 
198 
224 int G3d_cacheSizeEncode(int cacheCode, int n)
225 {
226  if (cacheCode >= G3D_NO_CACHE)
227  return cacheCode * n;
228  if (cacheCode == G3D_USE_CACHE_DEFAULT)
229  return cacheCode;
230 
231  if (cacheCode < G3D_USE_CACHE_XYZ)
232  G3d_fatalError("G3d_cacheSizeEncode: invalid cache code");
233 
234  return n * (-10) + cacheCode;
235 }
236 
237 /*---------------------------------------------------------------------------*/
238 
239 int G3d__computeCacheSize(G3D_Map * map, int cacheCode)
240 {
241  int n, size;
242 
243  if (cacheCode >= G3D_NO_CACHE)
244  return cacheCode;
245  if (cacheCode == G3D_USE_CACHE_DEFAULT)
246  return G3D_MIN(g3d_cache_default, map->nTiles);
247 
248  n = -(cacheCode / 10);
249  n = G3D_MAX(1, n);
250  cacheCode = -((-cacheCode) % 10);
251 
252  if (cacheCode == G3D_USE_CACHE_X)
253  size = map->nx * n;
254  else if (cacheCode == G3D_USE_CACHE_Y)
255  size = map->ny * n;
256  else if (cacheCode == G3D_USE_CACHE_Z)
257  size = map->nz * n;
258  else if (cacheCode == G3D_USE_CACHE_XY)
259  size = map->nxy * n;
260  else if (cacheCode == G3D_USE_CACHE_XZ)
261  size = map->nx * map->nz * n;
262  else if (cacheCode == G3D_USE_CACHE_YZ)
263  size = map->ny * map->nz * n;
264  else if (cacheCode == G3D_USE_CACHE_XYZ)
265  size = map->nTiles;
266  else
267  G3d_fatalError("G3d__computeCacheSize: invalid cache code");
268 
269  return G3D_MIN(size, map->nTiles);
270 }
271 
272 /*---------------------------------------------------------------------------*/
273 
274 /* this function does actually more than filling the header fields of the */
275 /* G3D-Map structure. It also allocates memory for compression and xdr, */
276 /* and initializes the index and cache. This function should be taken apart. */
277 
278 int
279 G3d_fillHeader(G3D_Map * map, int operation, int compression, int useRle,
280  int useLzw, int type, int precision, int cache, int hasIndex,
281  int useXdr, int typeIntern, int nofHeaderBytes, int tileX,
282  int tileY, int tileZ, int proj, int zone, double north,
283  double south, double east, double west, double top,
284  double bottom, int rows, int cols, int depths, double ew_res,
285  double ns_res, double tb_res, char *unit)
286 {
287  if (!G3D_VALID_OPERATION(operation))
288  G3d_fatalError("G3d_fillHeader: operation not valid\n");
289 
290  map->operation = operation;
291 
292  map->unit = G_store(unit);
293 
294  map->region.proj = proj;
295  map->region.zone = zone;
296 
297  map->region.north = north;
298  map->region.south = south;
299  map->region.east = east;
300  map->region.west = west;
301  map->region.top = top;
302  map->region.bottom = bottom;
303 
304  map->region.rows = rows;
305  map->region.cols = cols;
306  map->region.depths = depths;
307 
308  map->region.ew_res = ew_res;
309  map->region.ns_res = ns_res;
310  map->region.tb_res = tb_res;
311 
312  G3d_adjustRegion(&(map->region));
313 
314  map->tileX = tileX;
315  map->tileY = tileY;
316  map->tileZ = tileZ;
317  map->tileXY = map->tileX * map->tileY;
318  map->tileSize = map->tileXY * map->tileZ;
319 
320  map->nx = (map->region.cols - 1) / tileX + 1;
321  map->ny = (map->region.rows - 1) / tileY + 1;
322  map->nz = (map->region.depths - 1) / tileZ + 1;
323  map->nxy = map->nx * map->ny;
324  map->nTiles = map->nxy * map->nz;
325 
326  if ((map->region.cols) % map->tileX != 0)
327  map->clipX = map->nx - 1;
328  else
329  map->clipX = -1;
330  if ((map->region.rows) % map->tileY != 0)
331  map->clipY = map->ny - 1;
332  else
333  map->clipY = -1;
334  if ((map->region.depths) % map->tileZ != 0)
335  map->clipZ = map->nz - 1;
336  else
337  map->clipZ = -1;
338 
339  if ((type != FCELL_TYPE) && (type != DCELL_TYPE))
340  G3d_fatalError("G3d_fillHeader: invalid type");
341  map->type = type;
342 
343  if ((typeIntern != FCELL_TYPE) && (typeIntern != DCELL_TYPE))
344  G3d_fatalError("G3d_fillHeader: invalid type");
345  map->typeIntern = typeIntern;
346 
347  if (!G3D_VALID_XDR_OPTION(useXdr))
348  G3d_fatalError("G3d_fillHeader: invalid xdr option");
349  map->useXdr = useXdr;
350 
351  map->offset = nofHeaderBytes;
352 
353  if ((map->fileEndPtr = lseek(map->data_fd, (long)0, SEEK_END)) == -1) {
354  G3d_error("G3d_fillHeader: can't position file");
355  return 0;
356  }
357 
358  map->useCache = (cache != G3D_NO_CACHE);
359 
360  map->numLengthIntern = G3d_length(map->typeIntern);
361  map->numLengthExtern = G3d_externLength(map->type);
362 
363  map->compression = compression;
364  map->useRle = useRle;
365  map->useLzw = useLzw;
366  map->precision = precision;
367 
368 #define RLE_STATUS_BYTES 2
369 
370  if (map->compression != G3D_NO_COMPRESSION) {
371  if (tmpCompress == NULL) {
372  tmpCompressLength = map->tileSize *
373  G3D_MAX(map->numLengthIntern, map->numLengthExtern) +
376  if (tmpCompress == NULL) {
377  G3d_error("G3d_fillHeader: error in G3d_malloc");
378  return 0;
379  }
380  }
381  else if (map->tileSize *
382  G3D_MAX(map->numLengthIntern, map->numLengthExtern)
384  tmpCompressLength = map->tileSize *
385  G3D_MAX(map->numLengthIntern, map->numLengthExtern) +
388  if (tmpCompress == NULL) {
389  G3d_error("G3d_fillHeader: error in G3d_realloc");
390  return 0;
391  }
392  }
393  }
394 
395 #define XDR_MISUSE_BYTES 10
396 
397  if (!G3d_initFpXdr(map, XDR_MISUSE_BYTES)) {
398  G3d_error("G3d_fillHeader: error in G3d_initFpXdr");
399  return 0;
400  }
401 
402  if ((!map->useCache) ||
403  ((cache == G3D_USE_CACHE_DEFAULT) && (g3d_cache_default == 0))) {
404  map->useCache = 0;
405  map->cache = NULL;
406  /* allocate one tile buffer */
407  map->data = G3d_malloc(map->tileSize * map->numLengthIntern);
408  if (map->data == NULL) {
409  G3d_error("G3d_fillHeader: error in G3d_malloc");
410  return 0;
411  }
412  map->currentIndex = -1;
413  }
414  else {
415  if (!G3d_initCache(map,
416  G3D_MAX(1,
417  G3D_MIN(G3d__computeCacheSize(map, cache),
418  g3d_cache_max /
419  map->tileSize /
420  map->numLengthIntern)))) {
421  G3d_error("G3d_fillHeader: error in G3d_initCache");
422  return 0;
423  }
424  }
425 
426  if (!G3d_initIndex(map, hasIndex)) {
427  G3d_error("G3d_fillHeader: error in G3d_initIndex");
428  return 0;
429  }
430 
431  return 1;
432 }
#define G3D_HEADER_DATA_OFFSET
Definition: g3d/header.c:27
int G3d_keyGetValue(struct Key_Value *keys, const char *key, char *val1, char *val2, int result1, int result2, int *resultVar)
Definition: g3dkeys.c:65
unsigned short compression
Definition: gsd_img_tif.c:40
#define G3D_REGION_EAST
Definition: G3d_intern.h:73
#define G3D_HEADER_PRECISION
Definition: g3d/header.c:26
int G3d_initCache(G3D_Map *map, int nCached)
Definition: g3dcache.c:215
#define G3D_REGION_COLS
Definition: G3d_intern.h:78
char * G_store(const char *s)
Copy string to allocated memory.
Definition: store.c:32
#define G3D_REGION_NSRES
Definition: G3d_intern.h:83
#define G3D_REGION_SOUTH
Definition: G3d_intern.h:72
int G3d_cacheSizeEncode(int cacheCode, int n)
Returns a number which encodes multiplicity n of cacheCode. This value can be used to specify the siz...
Definition: g3d/header.c:224
void G3d_makeMapsetMapDirectory(const char *mapName)
Definition: g3dmapset.c:9
int G3d_externLength(int t)
Definition: g3dmisc.c:89
#define G3D_HEADER_UNIT
Definition: g3d/header.c:30
void G3d_error(const char *msg,...)
Definition: g3derror.c:75
int G3d_keyGetDouble(struct Key_Value *keys, const char *key, double *d)
Definition: g3dkeys.c:26
int G3d_keySetInt(struct Key_Value *keys, const char *key, const int *i)
Definition: g3dkeys.c:93
#define G3D_MIN(a, b)
Definition: G3d_intern.h:25
#define G3D_HEADER_TILEX
Definition: g3d/header.c:19
int g3d_cache_max
Definition: g3ddefaults.c:59
int G3d_keySetValue(struct Key_Value *keys, const char *key, const char *val1, const char *val2, int keyval1, int keyval2, const int *keyvalVar)
Definition: g3dkeys.c:123
int G_free_key_value(struct Key_Value *kv)
Free allocated Key_Value structure.
Definition: key_value1.c:145
void * G3d_realloc(void *ptr, int nBytes)
Same as realloc (ptr, nBytes), except that in case of error G3d_error() is invoked.
Definition: g3dalloc.c:50
#define G3D_VALID_OPERATION(o)
Definition: G3d_intern.h:22
#define G3D_MAX(a, b)
Definition: G3d_intern.h:26
void G3d_filename(char *path, const char *elementName, const char *mapName, const char *mapset)
Definition: filename.c:10
#define R_OK
Definition: dirent.c:6
int G3d_readHeader(G3D_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)
Definition: g3d/header.c:112
#define G3D_REGION_DEPTHS
Definition: G3d_intern.h:79
#define G3D_HEADER_USEXDR
Definition: g3d/header.c:28
void * tmpCompress
Definition: g3d/header.c:12
tuple size
value.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
Definition: tools.py:2334
#define G3D_REGION_BOTTOM
Definition: G3d_intern.h:76
#define G3D_HEADER_HASINDEX
Definition: g3d/header.c:29
int g3d_cache_default
Definition: g3ddefaults.c:58
#define G3D_REGION_EWRES
Definition: G3d_intern.h:82
struct Key_Value * G_read_key_value_file(const char *file, int *stat)
Read key/values pairs from file.
Definition: key_value3.c:54
int tmpCompressLength
Definition: g3d/header.c:13
#define G3D_HEADER_COMPRESSION
Definition: g3d/header.c:23
#define G3D_VALID_XDR_OPTION(o)
Definition: G3d_intern.h:34
int G3d_initIndex(G3D_Map *map, int hasIndex)
Definition: g3d/index.c:156
int
Definition: g3dcolor.c:48
#define G3D_HEADER_TILEY
Definition: g3d/header.c:20
#define G3D_REGION_TBRES
Definition: G3d_intern.h:84
#define G3D_HEADER_TYPE
Definition: g3d/header.c:22
tuple unit
#define XDR_MISUSE_BYTES
int G3d_keySetDouble(struct Key_Value *keys, const char *key, const double *d)
Definition: g3dkeys.c:103
#define G3D_REGION_PROJ
Definition: G3d_intern.h:80
if(!YY_CURRENT_BUFFER)
Definition: lex.yy.c:799
#define G3D_HEADER_TILEZ
Definition: g3d/header.c:21
#define G3D_REGION_TOP
Definition: G3d_intern.h:75
int G3d_keyGetString(struct Key_Value *keys, const char *key, char **returnStr)
Definition: g3dkeys.c:47
return NULL
Definition: dbfopen.c:1394
int G_write_key_value_file(const char *file, const struct Key_Value *kv, int *stat)
Write key/value pairs to file.
Definition: key_value3.c:29
void * G3d_malloc(int nBytes)
Same as malloc (nBytes), except that in case of error G3d_error() is invoked.
Definition: g3dalloc.c:24
#define RLE_STATUS_BYTES
tuple cols
int G3d_length(int t)
Definition: g3dmisc.c:77
#define G3D_HEADER_USELZW
Definition: g3d/header.c:25
int G3d_fillHeader(G3D_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)
Definition: g3d/header.c:279
#define G3D_REGION_ZONE
Definition: G3d_intern.h:81
#define G3D_HEADER_USERLE
Definition: g3d/header.c:24
int G3d__computeCacheSize(G3D_Map *map, int cacheCode)
Definition: g3d/header.c:239
#define G3D_REGION_WEST
Definition: G3d_intern.h:74
void G3d_adjustRegion(G3D_Region *region)
Computes an adjusts the resolutions in the region structure from the region boundaries and number of ...
Definition: g3dregion.c:149
void * xdr
Definition: g3d/header.c:14
int G3d_keySetString(struct Key_Value *keys, const char *key, char *const *keyValStr)
Definition: g3dkeys.c:114
int G3d_initFpXdr(G3D_Map *map, int misuseBytes)
Definition: g3dfpxdr.c:64
#define G3D_REGION_NORTH
Definition: G3d_intern.h:71
int G3d_keyGetInt(struct Key_Value *keys, const char *key, int *i)
Definition: g3dkeys.c:7
int n
Definition: dataquad.c:291
int xdrLength
Definition: g3d/header.c:15
void G3d_fatalError(const char *,...)
This function prints the error message msg, and terminates the program with an error status...
Definition: g3derror.c:58
#define G3D_REGION_ROWS
Definition: G3d_intern.h:77
struct Key_Value * G_create_key_value(void)
Allocate and initialize Key_Value structure.
Definition: key_value1.c:25
int G3d_writeHeader(G3D_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)
Definition: g3d/header.c:156