GRASS 8 Programmer's Manual 8.6.0dev(2026)-ddeab64dbf
Loading...
Searching...
No Matches
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
10static int Rast3d_readIndex(RASTER3D_Map *map)
11{
12 unsigned char *tmp, *tmp2;
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
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? */
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);
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)
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{
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
139static long *cmpIndex;
140
141static 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
157int 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
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
void * Rast3d_malloc(int)
Same as malloc (nBytes), except that in case of error Rast3d_error() is invoked.
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:243
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
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
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 operation
Definition raster3d.h:79
int * tileLength
Definition raster3d.h:145
long indexOffset
Definition raster3d.h:123
#define read
Definition unistd.h:5
#define write
Definition unistd.h:6