GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-d6dec75dd4
raster3d/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/raster3d.h>
6 #include "raster3d_intern.h"
7 
8 /*---------------------------------------------------------------------------*/
9 
10 static int Rast3d_readIndex(RASTER3D_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  Rast3d_error("Rast3d_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  Rast3d_error("Rast3d_readIndex: can't position file");
26  return 0;
27  }
28 
29  tmp = Rast3d_malloc(map->indexLongNbytes * map->nTiles);
30 
31  if (tmp == NULL) {
32  Rast3d_error("Rast3d_readIndex: error in Rast3d_malloc");
33  return 0;
34  }
35 
36  /* The size of the tile index array in the map file */
37  if (indexLength == map->indexLongNbytes * map->nTiles) {
38  if (read(map->data_fd, tmp, indexLength) != indexLength) {
39  Rast3d_error("Rast3d_readIndex: can't read file");
40  Rast3d_free(tmp);
41  return 0;
42  }
43  }
44  else
45  /* ATTENTION: RLE encoded reading is only supported for backward
46  * compatibility */
47  if (indexLength <
48  map->indexLongNbytes * map->nTiles) { /* RLE encoded? */
49 
50  if (indexLength > (int)sizeof(long) * map->nTiles) {
51 
52  /*->index large enough? */
53  tmp2 = Rast3d_malloc(indexLength);
54  if (tmp2 == NULL) {
55  Rast3d_error("Rast3d_readIndex: error in Rast3d_malloc");
56  Rast3d_free(tmp);
57  return 0;
58  }
59  }
60  else /* YES */
61  tmp2 = (unsigned char *)map->index;
62 
63  if (read(map->data_fd, tmp2, indexLength) != indexLength) {
64  Rast3d_error("Rast3d_readIndex: can't read file");
65  Rast3d_free(tmp);
66  Rast3d_free(tmp2);
67  return 0;
68  }
69 
70  Rast3d_rle_decode((char *)tmp2, (char *)tmp,
71  map->indexLongNbytes * map->nTiles, 1, &dummy1,
72  &dummy2);
73 
74  if (indexLength > (int)sizeof(long) * map->nTiles)
75  Rast3d_free(tmp2);
76  } /* END RLE */
77 
78  Rast3d_long_decode(tmp, map->index, map->nTiles, map->indexLongNbytes);
79 
80  for (tileIndex = 0; tileIndex < map->nTiles; tileIndex++)
81  if (map->index[tileIndex] == 0)
82  map->index[tileIndex] = -1;
83 
84  Rast3d_free(tmp);
85 
86  return 1;
87 }
88 
89 /*---------------------------------------------------------------------------*/
90 
92 {
93  int indexLength, tileIndex;
94  unsigned char *tmp;
95  long ldummy;
96 
97  if (!map->hasIndex)
98  return 1;
99 
100  map->indexOffset = lseek(map->data_fd, (long)0, SEEK_END);
101  if (map->indexOffset == -1) {
102  Rast3d_error("Rast3d_flush_index: can't rewind file");
103  return 0;
104  }
105 
106  map->indexNbytesUsed =
107  Rast3d_long_encode(&(map->indexOffset), (unsigned char *)&ldummy, 1);
108 
109  tmp = Rast3d_malloc(sizeof(long) * map->nTiles);
110  if (tmp == NULL) {
111  Rast3d_error("Rast3d_flush_index: error in Rast3d_malloc");
112  return 0;
113  }
114 
115  for (tileIndex = 0; tileIndex < map->nTiles; tileIndex++)
116  if (map->index[tileIndex] == -1)
117  map->index[tileIndex] = 0;
118 
119  (void)Rast3d_long_encode(map->index, tmp, map->nTiles);
120 
121  indexLength = map->nTiles * sizeof(long);
122  if (write(map->data_fd, tmp, indexLength) != indexLength) {
123  Rast3d_error("Rast3d_flush_index: can't write file");
124  Rast3d_free(tmp);
125  return 0;
126  }
127 
128  Rast3d_free(tmp);
129  if (!Rast3d_readIndex(map)) {
130  Rast3d_error("Rast3d_flush_index: error in Rast3d_readIndex");
131  return 0;
132  }
133 
134  return 1;
135 }
136 
137 /*---------------------------------------------------------------------------*/
138 
139 static long *cmpIndex;
140 
141 static int indexSortCompare(const void *a, const void *b)
142 {
143  long offset1, offset2;
144 
145  offset1 = cmpIndex[*((const long *)a)];
146  offset2 = cmpIndex[*((const long *)b)];
147 
148  if (offset1 > offset2)
149  return 1;
150  if (offset1 < offset2)
151  return -1;
152  return 0;
153 }
154 
155 /*---------------------------------------------------------------------------*/
156 
157 int Rast3d_init_index(RASTER3D_Map *map, int hasIndex)
158 {
159  int tile;
160  int i0, i1, i2, i3, i4, i5, nofElts;
161  long offset;
162  long *offsetP;
163 
164  map->hasIndex = hasIndex;
165  map->index = Rast3d_malloc(sizeof(long) * map->nTiles);
166  map->tileLength = Rast3d_malloc(sizeof(int) * map->nTiles);
167 
168  if ((map->index == NULL) || (map->tileLength == NULL)) {
169  Rast3d_error("Rast3d_init_index: error in Rast3d_malloc");
170  return 0;
171  }
172 
173  if (map->operation == RASTER3D_WRITE_DATA) {
174  for (tile = 0; tile < map->nTiles; tile++)
175  map->index[tile] = -1;
176  return 1;
177  }
178 
179  if (!map->hasIndex) {
180  offset = 0;
181  for (tile = 0; tile < map->nTiles; tile++) {
182  map->index[tile] = offset * map->numLengthExtern + map->offset;
184  map, tile, &i0, &i1, &i2, &i3, &i4, &i5);
185  map->tileLength[tile] = nofElts * map->numLengthExtern;
186  offset += nofElts;
187  }
188  return 1;
189  }
190 
191  if (!Rast3d_readIndex(map)) {
192  Rast3d_error("Rast3d_init_index: error in Rast3d_readIndex");
193  return 0;
194  }
195 
196  offsetP = Rast3d_malloc(sizeof(long) * map->nTiles);
197  if (offsetP == NULL) {
198  Rast3d_error("Rast3d_init_index: error in Rast3d_malloc");
199  return 0;
200  }
201 
202  for (tile = 0; tile < map->nTiles; tile++)
203  offsetP[tile] = tile;
204  cmpIndex = map->index;
205  qsort(offsetP, map->nTiles, sizeof(long), indexSortCompare);
206 
207  for (tile = 0; tile < map->nTiles - 1; tile++) {
208  if (map->index[offsetP[tile]] == -1) {
209  map->tileLength[offsetP[tile]] = 0;
210  continue;
211  }
212 
213  map->tileLength[offsetP[tile]] =
214  map->index[offsetP[tile + 1]] - map->index[offsetP[tile]];
215  }
216 
217  if (map->index[offsetP[map->nTiles - 1]] == -1)
218  map->tileLength[offsetP[map->nTiles - 1]] = 0;
219  else
220  map->tileLength[offsetP[map->nTiles - 1]] =
221  map->indexOffset - map->index[offsetP[map->nTiles - 1]];
222 
223  Rast3d_free(offsetP);
224 
225  return 1;
226 }
#define NULL
Definition: ccmath.h:32
void Rast3d_free(void *)
Same as free (ptr).
void Rast3d_long_decode(unsigned char *, long *, int, int)
Definition: long.c:35
int Rast3d_compute_clipped_tile_dimensions(RASTER3D_Map *, int, int *, int *, int *, int *, int *, int *)
Computes the dimensions of the tile when clipped to fit the region of map. The clipped dimensions are...
Definition: tilemath.c:253
void Rast3d_error(const char *,...) __attribute__((format(printf
int Rast3d_long_encode(long *, unsigned char *, int)
Definition: long.c:5
void Rast3d_rle_decode(char *, char *, int, int, int *, int *)
Definition: rle.c:236
void * Rast3d_malloc(int)
Same as malloc (nBytes), except that in case of error Rast3d_error() is invoked.
double b
Definition: r_raster.c:39
int Rast3d_flush_index(RASTER3D_Map *map)
int Rast3d_init_index(RASTER3D_Map *map, int hasIndex)
#define RASTER3D_WRITE_DATA
if(!(yy_init))
Definition: sqlp.yy.c:775
long * index
Definition: raster3d.h:142
int numLengthExtern
Definition: raster3d.h:173
int indexLongNbytes
Definition: raster3d.h:126
int indexNbytesUsed
Definition: raster3d.h:130
int hasIndex
Definition: raster3d.h:136
int operation
Definition: raster3d.h:79
int * tileLength
Definition: raster3d.h:145
long indexOffset
Definition: raster3d.h:123