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