GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
g3d/index.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/G3d.h>
6 #include "G3d_intern.h"
7 
8 /*---------------------------------------------------------------------------*/
9 
10 static int G3d_readIndex(G3D_Map * map)
11 {
12  unsigned char *tmp, *tmp2;
13  int dummy1, dummy2, indexLength, tileIndex;
14  long indexLast;
15 
16  indexLast = lseek(map->data_fd, (long)0, SEEK_END);
17  if (indexLast == -1) {
18  G3d_error("G3d_readIndex: can't position file");
19  return 0;
20  }
21 
22  indexLength = indexLast - map->indexOffset;
23 
24  if (lseek(map->data_fd, map->indexOffset, SEEK_SET) == -1) {
25  G3d_error("G3d_readIndex: can't position file");
26  return 0;
27  }
28 
29  tmp = G3d_malloc(map->indexLongNbytes * map->nTiles);
30 
31  if (tmp == NULL) {
32  G3d_error("G3d_readIndex: error in G3d_malloc");
33  return 0;
34  }
35 
36  if (indexLength < map->indexLongNbytes * map->nTiles) { /* RLE encoded? */
37 
38  if (indexLength > sizeof(long) * map->nTiles) {
39 
40  /*->index large enough? */
41  tmp2 = G3d_malloc(indexLength);
42  if (tmp2 == NULL) {
43  G3d_error("G3d_readIndex: error in G3d_malloc");
44  return 0;
45  }
46  }
47  else /* YES */
48  tmp2 = (unsigned char *)map->index;
49 
50  if (read(map->data_fd, tmp2, indexLength) != indexLength) {
51  G3d_error("G3d_readIndex: can't read file");
52  return 0;
53  }
54 
55  G_rle_decode(tmp2, tmp, map->indexLongNbytes * map->nTiles, 1,
56  &dummy1, &dummy2);
57 
58  if (indexLength > sizeof(long) * map->nTiles)
59  G3d_free(tmp2);
60  }
61  else /* NO RLE */ if (read(map->data_fd, tmp, indexLength) != indexLength) {
62  G3d_error("G3d_readIndex: can't read file");
63  return 0;
64  }
65 
66  G3d_longDecode(tmp, map->index, map->nTiles, map->indexLongNbytes);
67 
68  for (tileIndex = 0; tileIndex < map->nTiles; tileIndex++)
69  if (map->index[tileIndex] == 0)
70  map->index[tileIndex] = -1;
71 
72  G3d_free(tmp);
73 
74  return 1;
75 }
76 
77 /*---------------------------------------------------------------------------*/
78 
79 int G3d_flushIndex(G3D_Map * map)
80 {
81  int sizeCompressed, indexLength, tileIndex;
82  unsigned char *tmp;
83  long ldummy;
84 
85  if (!map->hasIndex)
86  return 1;
87 
88  map->indexOffset = lseek(map->data_fd, (long)0, SEEK_END);
89  if (map->indexOffset == -1) {
90  G3d_error("G3d_flushIndex: can't rewind file");
91  return 0;
92  }
93 
94  map->indexNbytesUsed = G3d_longEncode(&(map->indexOffset),
95  (unsigned char *)&ldummy, 1);
96 
97  tmp = G3d_malloc(sizeof(long) * map->nTiles);
98  if (tmp == NULL) {
99  G3d_error("G3d_flushIndex: error in G3d_malloc");
100  return 0;
101  }
102 
103  for (tileIndex = 0; tileIndex < map->nTiles; tileIndex++)
104  if (map->index[tileIndex] == -1)
105  map->index[tileIndex] = 0;
106 
107  (void)G3d_longEncode(map->index, tmp, map->nTiles);
108 
109  sizeCompressed = G_rle_count_only(tmp, sizeof(long) * map->nTiles, 1);
110 
111  if (sizeCompressed >= map->nTiles * sizeof(long)) {
112  indexLength = map->nTiles * sizeof(long);
113  if (write(map->data_fd, tmp, indexLength) != indexLength) {
114  G3d_error("G3d_flushIndex: can't write file");
115  return 0;
116  }
117  }
118  else {
119  indexLength = sizeCompressed;
120  G_rle_encode(tmp, (char *)map->index, sizeof(long) * map->nTiles, 1);
121  if (write(map->data_fd, map->index, sizeCompressed) != sizeCompressed) {
122  G3d_error("G3d_flushIndex: can't write file");
123  return 0;
124  }
125  }
126 
127  G3d_free(tmp);
128  if (!G3d_readIndex(map)) {
129  G3d_error("G3d_flushIndex: error in G3d_readIndex");
130  return 0;
131  }
132 
133  return 1;
134 }
135 
136 /*---------------------------------------------------------------------------*/
137 
138 static long *cmpIndex;
139 
140 static int indexSortCompare(const void *a, const void *b)
141 {
142  long offset1, offset2;
143 
144  offset1 = cmpIndex[*((const int *)a)];
145  offset2 = cmpIndex[*((const int *)b)];
146 
147  if (offset1 > offset2)
148  return 1;
149  if (offset1 < offset2)
150  return -1;
151  return 0;
152 }
153 
154 /*---------------------------------------------------------------------------*/
155 
156 int G3d_initIndex(G3D_Map * map, int hasIndex)
157 {
158  int tile;
159  int i0, i1, i2, i3, i4, i5, offset, nofElts;
160  int *offsetP;
161 
162  map->hasIndex = hasIndex;
163  map->index = G3d_malloc(sizeof(long) * map->nTiles);
164  map->tileLength = G3d_malloc(sizeof(int) * map->nTiles);
165 
166  if ((map->index == NULL) || (map->tileLength == NULL)) {
167  G3d_error("G3d_initIndex: error in G3d_malloc");
168  return 0;
169  }
170 
171  if (map->operation == G3D_WRITE_DATA) {
172  for (tile = 0; tile < map->nTiles; tile++)
173  map->index[tile] = -1;
174  return 1;
175  }
176 
177  if (!map->hasIndex) {
178  offset = 0;
179  for (tile = 0; tile < map->nTiles; tile++) {
180  map->index[tile] = offset * map->numLengthExtern + map->offset;
182  (map, tile, &i0, &i1, &i2, &i3, &i4, &i5);
183  map->tileLength[tile] = nofElts * map->numLengthExtern;
184  offset += nofElts;
185  }
186  return 1;
187  }
188 
189  if (!G3d_readIndex(map)) {
190  G3d_error("G3d_initIndex: error in G3d_readIndex");
191  return 0;
192  }
193 
194  offsetP = G3d_malloc(sizeof(int) * map->nTiles);
195  if (offsetP == NULL) {
196  G3d_error("G3d_initIndex: error in G3d_malloc");
197  return 0;
198  }
199 
200  for (tile = 0; tile < map->nTiles; tile++)
201  offsetP[tile] = tile;
202  cmpIndex = map->index;
203  qsort(offsetP, map->nTiles, sizeof(int), indexSortCompare);
204 
205  for (tile = 0; tile < map->nTiles - 1; tile++) {
206  if (map->index[offsetP[tile]] == -1) {
207  map->tileLength[offsetP[tile]] = 0;
208  continue;
209  }
210 
211  map->tileLength[offsetP[tile]] = map->index[offsetP[tile + 1]] -
212  map->index[offsetP[tile]];
213  }
214 
215  if (map->index[offsetP[map->nTiles - 1]] == -1)
216  map->tileLength[offsetP[map->nTiles - 1]] = 0;
217  else
218  map->tileLength[offsetP[map->nTiles - 1]] =
219  map->indexOffset - map->index[offsetP[map->nTiles - 1]];
220 
221  G3d_free(offsetP);
222 
223  return 1;
224 }
float b
Definition: named_colr.c:8
void G3d_free(void *buf)
Same as free (ptr).
Definition: g3dalloc.c:71
void G3d_error(const char *msg,...)
Definition: g3derror.c:75
int G_rle_count_only(char *src, int nofElts, int eltLength)
Definition: rle.c:123
#define G3D_WRITE_DATA
Definition: G3d_intern.h:19
int G3d_initIndex(G3D_Map *map, int hasIndex)
Definition: g3d/index.c:156
void G_rle_encode(char *src, char *dst, int nofElts, int eltLength)
Definition: rle.c:166
if(!YY_CURRENT_BUFFER)
Definition: lex.yy.c:799
int G3d_longEncode(long *source, unsigned char *dst, int nofNums)
Definition: g3dlong.c:5
int G3d_computeClippedTileDimensions(G3D_Map *map, int tileIndex, int *rows, int *cols, int *depths, int *xRedundant, int *yRedundant, int *zRedundant)
Computes the dimensions of the tile when clipped to fit the region of map. The clipped dimensions are...
Definition: tilemath.c:267
int G3d_flushIndex(G3D_Map *map)
Definition: g3d/index.c:79
return NULL
Definition: dbfopen.c:1394
void * G3d_malloc(int nBytes)
Same as malloc (nBytes), except that in case of error G3d_error() is invoked.
Definition: g3dalloc.c:24
void G_rle_decode(char *src, char *dst, int nofElts, int eltLength, int *lengthEncode, int *lengthDecode)
Definition: rle.c:223
void G3d_longDecode(unsigned char *source, long *dst, int nofNums, int longNbytes)
Definition: g3dlong.c:36