GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-602118adcc
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  return 0;
41  }
42  }
43  else
44  /* ATTENTION: RLE encoded reading is only supported for backward
45  * compatibility */
46  if (indexLength <
47  map->indexLongNbytes * map->nTiles) { /* RLE encoded? */
48 
49  if (indexLength > (int)sizeof(long) * map->nTiles) {
50 
51  /*->index large enough? */
52  tmp2 = Rast3d_malloc(indexLength);
53  if (tmp2 == NULL) {
54  Rast3d_error("Rast3d_readIndex: error in Rast3d_malloc");
55  return 0;
56  }
57  }
58  else /* YES */
59  tmp2 = (unsigned char *)map->index;
60 
61  if (read(map->data_fd, tmp2, indexLength) != indexLength) {
62  Rast3d_error("Rast3d_readIndex: can't read file");
63  return 0;
64  }
65 
66  Rast3d_rle_decode((char *)tmp2, (char *)tmp,
67  map->indexLongNbytes * map->nTiles, 1, &dummy1,
68  &dummy2);
69 
70  if (indexLength > (int)sizeof(long) * map->nTiles)
71  Rast3d_free(tmp2);
72  } /* END RLE */
73 
74  Rast3d_long_decode(tmp, map->index, map->nTiles, map->indexLongNbytes);
75 
76  for (tileIndex = 0; tileIndex < map->nTiles; tileIndex++)
77  if (map->index[tileIndex] == 0)
78  map->index[tileIndex] = -1;
79 
80  Rast3d_free(tmp);
81 
82  return 1;
83 }
84 
85 /*---------------------------------------------------------------------------*/
86 
88 {
89  int indexLength, tileIndex;
90  unsigned char *tmp;
91  long ldummy;
92 
93  if (!map->hasIndex)
94  return 1;
95 
96  map->indexOffset = lseek(map->data_fd, (long)0, SEEK_END);
97  if (map->indexOffset == -1) {
98  Rast3d_error("Rast3d_flush_index: can't rewind file");
99  return 0;
100  }
101 
102  map->indexNbytesUsed =
103  Rast3d_long_encode(&(map->indexOffset), (unsigned char *)&ldummy, 1);
104 
105  tmp = Rast3d_malloc(sizeof(long) * map->nTiles);
106  if (tmp == NULL) {
107  Rast3d_error("Rast3d_flush_index: error in Rast3d_malloc");
108  return 0;
109  }
110 
111  for (tileIndex = 0; tileIndex < map->nTiles; tileIndex++)
112  if (map->index[tileIndex] == -1)
113  map->index[tileIndex] = 0;
114 
115  (void)Rast3d_long_encode(map->index, tmp, map->nTiles);
116 
117  indexLength = map->nTiles * sizeof(long);
118  if (write(map->data_fd, tmp, indexLength) != indexLength) {
119  Rast3d_error("Rast3d_flush_index: can't write file");
120  return 0;
121  }
122 
123  Rast3d_free(tmp);
124  if (!Rast3d_readIndex(map)) {
125  Rast3d_error("Rast3d_flush_index: error in Rast3d_readIndex");
126  return 0;
127  }
128 
129  return 1;
130 }
131 
132 /*---------------------------------------------------------------------------*/
133 
134 static long *cmpIndex;
135 
136 static int indexSortCompare(const void *a, const void *b)
137 {
138  long offset1, offset2;
139 
140  offset1 = cmpIndex[*((const long *)a)];
141  offset2 = cmpIndex[*((const long *)b)];
142 
143  if (offset1 > offset2)
144  return 1;
145  if (offset1 < offset2)
146  return -1;
147  return 0;
148 }
149 
150 /*---------------------------------------------------------------------------*/
151 
152 int Rast3d_init_index(RASTER3D_Map *map, int hasIndex)
153 {
154  int tile;
155  int i0, i1, i2, i3, i4, i5, nofElts;
156  long offset;
157  long *offsetP;
158 
159  map->hasIndex = hasIndex;
160  map->index = Rast3d_malloc(sizeof(long) * map->nTiles);
161  map->tileLength = Rast3d_malloc(sizeof(int) * map->nTiles);
162 
163  if ((map->index == NULL) || (map->tileLength == NULL)) {
164  Rast3d_error("Rast3d_init_index: error in Rast3d_malloc");
165  return 0;
166  }
167 
168  if (map->operation == RASTER3D_WRITE_DATA) {
169  for (tile = 0; tile < map->nTiles; tile++)
170  map->index[tile] = -1;
171  return 1;
172  }
173 
174  if (!map->hasIndex) {
175  offset = 0;
176  for (tile = 0; tile < map->nTiles; tile++) {
177  map->index[tile] = offset * map->numLengthExtern + map->offset;
179  map, tile, &i0, &i1, &i2, &i3, &i4, &i5);
180  map->tileLength[tile] = nofElts * map->numLengthExtern;
181  offset += nofElts;
182  }
183  return 1;
184  }
185 
186  if (!Rast3d_readIndex(map)) {
187  Rast3d_error("Rast3d_init_index: error in Rast3d_readIndex");
188  return 0;
189  }
190 
191  offsetP = Rast3d_malloc(sizeof(long) * map->nTiles);
192  if (offsetP == NULL) {
193  Rast3d_error("Rast3d_init_index: error in Rast3d_malloc");
194  return 0;
195  }
196 
197  for (tile = 0; tile < map->nTiles; tile++)
198  offsetP[tile] = tile;
199  cmpIndex = map->index;
200  qsort(offsetP, map->nTiles, sizeof(long), indexSortCompare);
201 
202  for (tile = 0; tile < map->nTiles - 1; tile++) {
203  if (map->index[offsetP[tile]] == -1) {
204  map->tileLength[offsetP[tile]] = 0;
205  continue;
206  }
207 
208  map->tileLength[offsetP[tile]] =
209  map->index[offsetP[tile + 1]] - map->index[offsetP[tile]];
210  }
211 
212  if (map->index[offsetP[map->nTiles - 1]] == -1)
213  map->tileLength[offsetP[map->nTiles - 1]] = 0;
214  else
215  map->tileLength[offsetP[map->nTiles - 1]] =
216  map->indexOffset - map->index[offsetP[map->nTiles - 1]];
217 
218  Rast3d_free(offsetP);
219 
220  return 1;
221 }
#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