123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <grass/raster3d.h>
- #include "raster3d_intern.h"
- /*---------------------------------------------------------------------------*/
- static int Rast3d_readIndex(RASTER3D_Map * map)
- {
- unsigned char *tmp, *tmp2;
- int dummy1, dummy2, indexLength, tileIndex;
- long indexLast;
- indexLast = lseek(map->data_fd, (long)0, SEEK_END);
- if (indexLast == -1) {
- Rast3d_error("Rast3d_readIndex: can't position file");
- return 0;
- }
- indexLength = indexLast - map->indexOffset;
- if (lseek(map->data_fd, map->indexOffset, SEEK_SET) == -1) {
- Rast3d_error("Rast3d_readIndex: can't position file");
- return 0;
- }
- tmp = Rast3d_malloc(map->indexLongNbytes * map->nTiles);
- if (tmp == NULL) {
- Rast3d_error("Rast3d_readIndex: error in Rast3d_malloc");
- return 0;
- }
- /* The size of the tile index array in the map file */
- if(indexLength == map->indexLongNbytes * map->nTiles) {
- if (read(map->data_fd, tmp, indexLength) != indexLength) {
- Rast3d_error("Rast3d_readIndex: can't read file");
- return 0;
- }
- } else
- /* ATTENTION: RLE encoded reading is only supported for backward compatibility */
- if (indexLength < map->indexLongNbytes * map->nTiles) { /* RLE encoded? */
- if (indexLength > sizeof(long) * map->nTiles) {
- /*->index large enough? */
- tmp2 = Rast3d_malloc(indexLength);
- if (tmp2 == NULL) {
- Rast3d_error("Rast3d_readIndex: error in Rast3d_malloc");
- return 0;
- }
- }
- else /* YES */
- tmp2 = (unsigned char *)map->index;
- if (read(map->data_fd, tmp2, indexLength) != indexLength) {
- Rast3d_error("Rast3d_readIndex: can't read file");
- return 0;
- }
- Rast3d_rle_decode((char *)tmp2, (char *)tmp, map->indexLongNbytes * map->nTiles, 1,
- &dummy1, &dummy2);
- if (indexLength > sizeof(long) * map->nTiles)
- Rast3d_free(tmp2);
- } /* END RLE */
- Rast3d_long_decode(tmp, map->index, map->nTiles, map->indexLongNbytes);
- for (tileIndex = 0; tileIndex < map->nTiles; tileIndex++)
- if (map->index[tileIndex] == 0)
- map->index[tileIndex] = -1;
- Rast3d_free(tmp);
- return 1;
- }
- /*---------------------------------------------------------------------------*/
- int Rast3d_flush_index(RASTER3D_Map * map)
- {
- int indexLength, tileIndex;
- unsigned char *tmp;
- long ldummy;
- if (!map->hasIndex)
- return 1;
- map->indexOffset = lseek(map->data_fd, (long)0, SEEK_END);
- if (map->indexOffset == -1) {
- Rast3d_error("Rast3d_flush_index: can't rewind file");
- return 0;
- }
- map->indexNbytesUsed = Rast3d_long_encode(&(map->indexOffset),
- (unsigned char *)&ldummy, 1);
- tmp = Rast3d_malloc(sizeof(long) * map->nTiles);
- if (tmp == NULL) {
- Rast3d_error("Rast3d_flush_index: error in Rast3d_malloc");
- return 0;
- }
- for (tileIndex = 0; tileIndex < map->nTiles; tileIndex++)
- if (map->index[tileIndex] == -1)
- map->index[tileIndex] = 0;
- (void)Rast3d_long_encode(map->index, tmp, map->nTiles);
- indexLength = map->nTiles * sizeof(long);
- if (write(map->data_fd, tmp, indexLength) != indexLength) {
- Rast3d_error("Rast3d_flush_index: can't write file");
- return 0;
- }
- Rast3d_free(tmp);
- if (!Rast3d_readIndex(map)) {
- Rast3d_error("Rast3d_flush_index: error in Rast3d_readIndex");
- return 0;
- }
- return 1;
- }
- /*---------------------------------------------------------------------------*/
- static long *cmpIndex;
- static int indexSortCompare(const void *a, const void *b)
- {
- long offset1, offset2;
- offset1 = cmpIndex[*((const long *)a)];
- offset2 = cmpIndex[*((const long *)b)];
- if (offset1 > offset2)
- return 1;
- if (offset1 < offset2)
- return -1;
- return 0;
- }
- /*---------------------------------------------------------------------------*/
- int Rast3d_init_index(RASTER3D_Map * map, int hasIndex)
- {
- int tile;
- int i0, i1, i2, i3, i4, i5, nofElts;
- long offset;
- long *offsetP;
- map->hasIndex = hasIndex;
- map->index = Rast3d_malloc(sizeof(long) * map->nTiles);
- map->tileLength = Rast3d_malloc(sizeof(int) * map->nTiles);
- if ((map->index == NULL) || (map->tileLength == NULL)) {
- Rast3d_error("Rast3d_init_index: error in Rast3d_malloc");
- return 0;
- }
- if (map->operation == RASTER3D_WRITE_DATA) {
- for (tile = 0; tile < map->nTiles; tile++)
- map->index[tile] = -1;
- return 1;
- }
- if (!map->hasIndex) {
- offset = 0;
- for (tile = 0; tile < map->nTiles; tile++) {
- map->index[tile] = offset * map->numLengthExtern + map->offset;
- nofElts = Rast3d_compute_clipped_tile_dimensions
- (map, tile, &i0, &i1, &i2, &i3, &i4, &i5);
- map->tileLength[tile] = nofElts * map->numLengthExtern;
- offset += nofElts;
- }
- return 1;
- }
- if (!Rast3d_readIndex(map)) {
- Rast3d_error("Rast3d_init_index: error in Rast3d_readIndex");
- return 0;
- }
- offsetP = Rast3d_malloc(sizeof(long) * map->nTiles);
- if (offsetP == NULL) {
- Rast3d_error("Rast3d_init_index: error in Rast3d_malloc");
- return 0;
- }
- for (tile = 0; tile < map->nTiles; tile++)
- offsetP[tile] = tile;
- cmpIndex = map->index;
- qsort(offsetP, map->nTiles, sizeof(long), indexSortCompare);
- for (tile = 0; tile < map->nTiles - 1; tile++) {
- if (map->index[offsetP[tile]] == -1) {
- map->tileLength[offsetP[tile]] = 0;
- continue;
- }
- map->tileLength[offsetP[tile]] = map->index[offsetP[tile + 1]] -
- map->index[offsetP[tile]];
- }
- if (map->index[offsetP[map->nTiles - 1]] == -1)
- map->tileLength[offsetP[map->nTiles - 1]] = 0;
- else
- map->tileLength[offsetP[map->nTiles - 1]] =
- map->indexOffset - map->index[offsetP[map->nTiles - 1]];
- Rast3d_free(offsetP);
- return 1;
- }
|