#include #include #include #include #include #include #include "G3d_intern.h" /*---------------------------------------------------------------------------*/ static int G3d_tile2xdrTile (G3D_Map *map, char *tile, int rows, int cols, int depths, int xRedundant, int yRedundant, int zRedundant, int nofNum, int type) { int y, z; if (! G3d_initCopyToXdr (map, type)) { G3d_error ("G3d_tile2xdrTile: error in G3d_initCopyToXdr"); return 0; } if (nofNum == map->tileSize) { if (! G3d_copyToXdr (tile, map->tileSize)) { G3d_error ("G3d_tile2xdrTile: error in G3d_copyToXdr"); return 0; } return 1; } if (xRedundant) { for (z = 0; z < depths; z++) { for (y = 0; y < rows; y++) { if (! G3d_copyToXdr (tile, cols)) { G3d_error ("G3d_tile2xdrTile: error in G3d_copyToXdr"); return 0; } tile += map->tileX * G3d_length (type); } if (yRedundant) tile += map->tileX * yRedundant * G3d_length (type); } return 1; } if (yRedundant) { for (z = 0; z < depths; z++) { if (! G3d_copyToXdr (tile, map->tileX * rows)) { G3d_error ("G3d_tile2xdrTile: error in G3d_copyToXdr"); return 0; } tile += map->tileXY * G3d_length (type); } return 1; } if (! G3d_copyToXdr (tile, map->tileXY * depths)) { G3d_error ("G3d_tile2xdrTile: error in G3d_copyToXdr"); return 0; } return 1; } /*---------------------------------------------------------------------------*/ static int G3d_writeTileUncompressed (G3D_Map *map, int nofNum) { if (write (map->data_fd, xdr, map->numLengthExtern * nofNum) != map->numLengthExtern * nofNum) { G3d_error ("G3d_writeTileUncompressed: can't write file."); return 0; } return 1; } /*---------------------------------------------------------------------------*/ static int G3d_writeTileCompressed (G3D_Map *map, int nofNum) { if (! G_fpcompress_writeXdrNums (map->data_fd, xdr, nofNum, map->precision, tmpCompress, map->type == G3D_FLOAT, map->useRle, map->useLzw)) { G3d_error ( "G3d_writeTileCompressed: error in G_fpcompress_writeXdrNums"); return 0; } return 1; } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* EXPORTED FUNCTIONS */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /*! * \brief * * * Writes tile with index tileIndex to the file corresponding to map. * It is assumed that the cells in tile are of type which * must be one of G3D_FLOAT and G3D_DOUBLE. The actual type used to write the * tile depends on the type specified at the time when map is initialized. * A tile can only be written once. Subsequent attempts to write the same tile * are ignored. * * \param map * \param tileIndex * \param tile * \param type * \return 1 ... if successful, * 2 ... if write request was ignored, * 0 ... otherwise. */ int G3d_writeTile (G3D_Map *map, int tileIndex, char *tile, int type) { int rows, cols, depths, xRedundant, yRedundant, zRedundant, nofNum; /* valid tileIndex ? */ if ((tileIndex >= map->nTiles) || (tileIndex < 0)) G3d_fatalError ("G3d_writeTile: tileIndex out of range"); /* already written ? */ if (map->index[tileIndex] != -1) return 2; /* save the file position */ map->index[tileIndex] = lseek (map->data_fd, (long) 0, SEEK_END); if (map->index[tileIndex] == -1) { G3d_error ("G3d_writeTile: can't position file"); return 0; } nofNum = G3d_computeClippedTileDimensions (map, tileIndex, &rows, &cols, &depths, &xRedundant, &yRedundant, &zRedundant); G3d_range_updateFromTile (map, tile, rows, cols, depths, xRedundant, yRedundant, zRedundant, nofNum, type); if (! G3d_tile2xdrTile (map, tile, rows, cols, depths, xRedundant, yRedundant, zRedundant, nofNum, type)) { G3d_error ("G3d_writeTileCompressed: error in G3d_tile2xdrTile"); return 0; } if (map->compression == G3D_NO_COMPRESSION) { if (! G3d_writeTileUncompressed (map, nofNum)) { G3d_error ("G3d_writeTile: error in G3d_writeTileUncompressed"); return 0; } } else if (! G3d_writeTileCompressed (map, nofNum)) { G3d_error ("G3d_writeTile: error in G3d_writeTileCompressed"); return 0; } /* compute the length */ map->tileLength[tileIndex] = lseek (map->data_fd, (long) 0, SEEK_END) - map->index[tileIndex]; return 1; } /*---------------------------------------------------------------------------*/ /*! * \brief * * Is equivalent to G3d_writeTile (map, tileIndex, tile, G3D_FLOAT). * * \param map * \param tileIndex * \param tile * \return int */ int G3d_writeTileFloat (G3D_Map *map, int tileIndex, char *tile) { int status; if ((status = G3d_writeTile (map, tileIndex, tile, G3D_FLOAT))) return status; G3d_error ("G3d_writeTileFloat: error in G3d_writeTile"); return 0; } /*---------------------------------------------------------------------------*/ /*! * \brief * * Is equivalent to G3d_writeTile (map, tileIndex, tile, G3D_DOUBLE). * * \param map * \param tileIndex * \param tile * \return int */ int G3d_writeTileDouble (G3D_Map *map, int tileIndex, char *tile) { int status; if ((status = G3d_writeTile (map, tileIndex, tile, G3D_DOUBLE))) return status; G3d_error ("G3d_writeTileDouble: error in G3d_writeTile"); return 0; } /*---------------------------------------------------------------------------*/ /* CACHE-MODE-ONLY FUNCTIONS */ /*---------------------------------------------------------------------------*/ /*! * \brief * * Writes the tile with * tileIndex to the file corresponding to map and removes the tile * from the cache (in non-cache mode the buffer provided by the map-structure is * written). * If this tile has already been written before the write request is ignored. * If the tile was never referred to before the invokation of G3d_flushTile, a * tile filled with NULL-values is written. * * \param map * \param tileIndex * \return 1 ... if successful, * 0 ... otherwise. */ int G3d_flushTile (G3D_Map *map, int tileIndex) { char *tile; tile = G3d_getTilePtr (map, tileIndex); if (tile == NULL) { G3d_error ("G3d_flushTile: error in G3d_getTilePtr"); return 0; } if (! G3d_writeTile (map, tileIndex, tile, map->typeIntern)) { G3d_error ("G3d_flushTile: error in G3d_writeTile"); return 0; } if (! G3d__removeTile (map, tileIndex)) { G3d_error ("G3d_flushTile: error in G3d__removeTile"); return 0; } return 1; } /*---------------------------------------------------------------------------*/ #ifndef MIN #define MIN(a,b) (a < b ? a : b) #define MAX(a,b) (a > b ? a : b) #endif /*! * \brief * * Writes the tiles with tile-coordinates * contained in the axis-parallel cube with vertices (xMin, yMin, zMin) * and (xMax, yMax, zMax). Tiles which are not stored in the cache are * written as NULL-tiles. Write attempts for tiles which have already been * written earlier are ignored. * * \param map * \param xMin * \param yMin * \param zMin * \param xMax * \param yMax * \param zMax * \return 1 ... if successful, * 0 ... otherwise. */ int G3d_flushTileCube (G3D_Map *map, int xMin, int yMin, int zMin, int xMax, int yMax, int zMax) { int x, y, z; if (! map->useCache) G3d_fatalError ("G3d_flushTileCube: function invalid in non-cache mode"); for (x = xMin; x <= xMax; x++) for (y = yMin; y <= yMax; y++) for (z = zMin; z <= zMax; z++) if (! G3d_flushTile (map, G3d_tile2tileIndex (map, x, y, z))) { G3d_error ("G3d_flushTileCube: error in G3d_flushTile"); return 0; } return 1; } /*---------------------------------------------------------------------------*/ /*! * \brief * * Writes those tiles for which * every cell has coordinate contained in the axis-parallel cube * defined by the vertices with cell-coordinates (xMin, yMin, zMin) * and (xMax, yMax, zMax). * Tiles which are not stored in the cache are written as NULL-tiles. * Write attempts for tiles which have already been written earlier are * ignored. * * \param map * \param xMin * \param yMin * \param zMin * \param xMax * \param yMax * \param zMax * \return 1 ... if successful, * 0 ... otherwise. */ int G3d_flushTilesInCube (G3D_Map *map, int xMin, int yMin, int zMin, int xMax, int yMax, int zMax) { int xTileMin, yTileMin, zTileMin, xTileMax, yTileMax, zTileMax; int xOffs, yOffs, zOffs; int regionMaxX, regionMaxY, regionMaxZ; if (! map->useCache) G3d_fatalError ("G3d_flushTilesInCube: function invalid in non-cache mode"); /*AV*/ /*BEGIN OF ORIGINAL CODE */ /* * G3d_getCoordsMap (map, ®ionMaxX, ®ionMaxY, ®ionMaxZ); */ /*AV*/ /* BEGIN OF MY CODE */ G3d_getCoordsMap (map, ®ionMaxY, ®ionMaxX, ®ionMaxZ); /* END OF MY CODE */ if ((xMin < 0) && (xMax < 0)) G3d_fatalError ("G3d_flushTilesInCube: coordinate out of Range"); if ((xMin >= regionMaxX) && (xMax >= regionMaxX)) G3d_fatalError ("G3d_flushTilesInCube: coordinate out of Range"); xMin = MIN (MAX (0, xMin), regionMaxX - 1); if ((yMin < 0) && (yMax < 0)) G3d_fatalError ("G3d_flushTilesInCube: coordinate out of Range"); if ((yMin >= regionMaxY) && (yMax >= regionMaxY)) G3d_fatalError ("G3d_flushTilesInCube: coordinate out of Range"); yMin = MIN (MAX (0, yMin), regionMaxY - 1); if ((zMin < 0) && (zMax < 0)) G3d_fatalError ("G3d_flushTilesInCube: coordinate out of Range"); if ((zMin >= regionMaxZ) && (zMax >= regionMaxZ)) G3d_fatalError ("G3d_flushTilesInCube: coordinate out of Range"); zMin = MIN (MAX (0, zMin), regionMaxZ - 1); G3d_coord2tileCoord (map, xMin, yMin, zMin, &xTileMin, &yTileMin, &zTileMin, &xOffs, &yOffs, &zOffs); if (xOffs != 0) xTileMin++; if (yOffs != 0) yTileMin++; if (zOffs != 0) zTileMin++; G3d_coord2tileCoord (map, xMax + 1, yMax + 1, zMax + 1, &xTileMax, &yTileMax, &zTileMax, &xOffs, &yOffs, &zOffs); xTileMax--; yTileMax--; zTileMax--; if (! G3d_flushTileCube (map, xTileMin, yTileMin, zTileMin, xTileMax, yTileMax, zTileMax)) { G3d_error ("G3d_flushTilesInCube: error in G3d_flushTileCube"); return 0; } return 1; } #undef MIN #undef MAX /*---------------------------------------------------------------------------*/ /*! * \brief * * Is equivalent to G3d_putValue (map, x, y, z, &value, G3D_DOUBLE). * * \param map * \param x * \param y * \param z * \param value * \return int */ int G3d_putDouble (); /*! * \brief * * Is equivalent to G3d_putValue (map, x, y, z, &value, G3D_FLOAT). * * \param map * \param x * \param y * \param z * \param value * \return int */ int G3d_putFloat (G3D_Map *map, int x, int y, int z, float value) { int tileIndex, offs; float *tile; if (map->typeIntern == G3D_DOUBLE) { if (! G3d_putDouble (map, x, y, z, (double) value)) { G3d_error ("G3d_putFloat: error in G3d_putDouble"); return 0; } return 1; } G3d_coord2tileIndex (map, x, y, z, &tileIndex, &offs); tile = (float *) G3d_getTilePtr (map, tileIndex); if (tile == NULL) { G3d_error ("G3d_putFloat: error in G3d_getTilePtr"); return 0; } tile[offs] = value; return 1; } /*---------------------------------------------------------------------------*/ /*! * \brief * * Is equivalent to G3d_putValue (map, x, y, z, &value, G3D_DOUBLE). * * \param map * \param x * \param y * \param z * \param value * \return int */ int G3d_putDouble (G3D_Map *map, int x, int y, int z, double value) { int tileIndex, offs; double *tile; if (map->typeIntern == G3D_FLOAT) { if (! G3d_putFloat (map, x, y, z, (float) value)) { G3d_error ("G3d_putDouble: error in G3d_putFloat"); return 0; } return 1; } G3d_coord2tileIndex (map, x, y, z, &tileIndex, &offs); tile = (double *) G3d_getTilePtr (map, tileIndex); if (tile == NULL) { G3d_error ("G3d_putDouble: error in G3d_getTilePtr"); return 0; } tile[offs] = value; return 1; } /*---------------------------------------------------------------------------*/ /*! * \brief * * After converting *value of type into the type specified * at the initialization time (i.e. typeIntern) this function writes the * value into the tile buffer corresponding to cell-coordinate (x, y, z). * * \param map * \param x * \param y * \param z * \param value * \param type * \return 1 ... if successful, * 0 ... otherwise. */ int G3d_putValue (G3D_Map *map, int x, int y, int z, char *value, int type) { if (type == G3D_FLOAT) { if (! G3d_putFloat (map, x, y, z, *((float *) value))) { G3d_error ("G3d_putValue: error in G3d_putFloat"); return 0; } return 1; } if (! G3d_putDouble (map, x, y, z, *((double *) value))) { G3d_error ("G3d_putValue: error in G3d_putDouble"); return 0; } return 1; }