#include #include #include #include #include #include #include "G3d_intern.h" static int G3d_xdrTile2tile (G3D_Map *map, char *tile, int rows, int cols, int depths, int xRedundant, int yRedundant, int zRedundant, int nofNum, int type) { int y, z, xLength, yLength, length; if (! G3d_initCopyFromXdr (map, type)) { G3d_error ("G3d_xdrTile2tile: error in G3d_initCopyFromXdr"); return 0; } if (nofNum == map->tileSize) { if (! G3d_copyFromXdr (map->tileSize, tile)) { G3d_error ("G3d_xdrTile2tile: error in G3d_copyFromXdr"); return 0; } return 1; } length = G3d_length (type); xLength = xRedundant * length; yLength = map->tileX * yRedundant * length; if (xRedundant) { for (z = 0; z < depths; z++) { for (y = 0; y < rows; y++) { if (! G3d_copyFromXdr (cols, tile)) { G3d_error ("G3d_xdrTile2tile: error in G3d_copyFromXdr"); return 0; } tile += cols * length; G3d_setNullValue (tile, xRedundant, type); tile += xLength; } if (yRedundant) { G3d_setNullValue (tile, map->tileX * yRedundant, type); tile += yLength; } } if (! zRedundant) return 1; G3d_setNullValue (tile, map->tileXY * zRedundant, type); return 1; } if (yRedundant) { for (z = 0; z < depths; z++) { if (! G3d_copyFromXdr (map->tileX * rows, tile)) { G3d_error ("G3d_xdrTile2tile: error in G3d_copyFromXdr"); return 0; } tile += map->tileX * rows * length; G3d_setNullValue (tile, map->tileX * yRedundant, type); tile += yLength; } if (! zRedundant) return 1; G3d_setNullValue (tile, map->tileXY * zRedundant, type); return 1; } if (! G3d_copyFromXdr (map->tileXY * depths, tile)) { G3d_error ("G3d_xdrTile2tile: error in G3d_copyFromXdr"); return 0; } if (! zRedundant) return 1; tile += map->tileXY * depths * length; G3d_setNullValue (tile, map->tileXY * zRedundant, type); return 1; } /*---------------------------------------------------------------------------*/ static int G3d_readTileUncompressed (G3D_Map *map, int tileIndex, int nofNum) { int nofBytes; nofBytes = nofNum * map->numLengthExtern; nofBytes = G3D_MIN (nofBytes, map->fileEndPtr - map->index[tileIndex]); if (read (map->data_fd, xdr, nofBytes) != nofBytes) { G3d_error ("G3d_readTileUncompressed: can't read file"); return 0; } return 1; } /*---------------------------------------------------------------------------*/ static int G3d_readTileCompressed (G3D_Map *map, int tileIndex, int nofNum) { if (! G_fpcompress_readXdrNums (map->data_fd, xdr, nofNum, map->tileLength[tileIndex], map->precision, tmpCompress, map->type == G3D_FLOAT)) { G3d_error ("G3d_readTileCompressed: error in G_fpcompress_readXdrNums"); return 0; } return 1; } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* EXPORTED FUNCTIONS */ /*---------------------------------------------------------------------------*/ /*! * \brief * * * Reads tile with index tileIndex into the tile buffer. The cells * are stored with type type which must be one of G3D_FLOAT and * G3D_DOUBLE. If the tile with tileIndex is not stored on the file * corresponding to map, and tileIndex is a valid index tile * is filled with NULL-values. * * \param map * \param tileIndex * \param tile * \param type * \return 1 ... if successful, * 0 ... otherwise. */ int G3d_readTile (G3D_Map *map, int tileIndex, char *tile, int type) { int nofNum, rows, cols, depths, xRedundant, yRedundant, zRedundant; if ((tileIndex >= map->nTiles) || (tileIndex < 0)) G3d_fatalError ("G3d_readTile: tile index out of range"); if (map->index[tileIndex] == -1) { G3d_setNullTileType (map, tile, type); return 1; } nofNum = G3d_computeClippedTileDimensions (map, tileIndex, &rows, &cols, &depths, &xRedundant, &yRedundant, &zRedundant); if (lseek (map->data_fd, map->index[tileIndex], SEEK_SET) == -1) { G3d_error ("G3d_readTile: can't position file"); return 0; } if (map->compression == G3D_NO_COMPRESSION) { if (! G3d_readTileUncompressed (map, tileIndex, nofNum)) { G3d_error ("G3d_readTile: error in G3d_readTileUncompressed"); return 0; } } else if (! G3d_readTileCompressed (map, tileIndex, nofNum)) { G3d_error ("G3d_readTile: error in G3d_readTileCompressed"); return 0; } if (! G3d_xdrTile2tile (map, tile, rows, cols, depths, xRedundant, yRedundant, zRedundant, nofNum, type)) { G3d_error ("G3d_readTile: error in G3d_xdrTile2tile"); return 0; } if (G3d_maskIsOff (map)) return 1; G3d_maskTile (map, tileIndex, tile, type); return 1; } /*---------------------------------------------------------------------------*/ /*! * \brief * * Is equivalent to G3d_readTile (map, tileIndex, tile, G3D_FLOAT). * * \param map * \param tileIndex * \param tile * \return int */ int G3d_readTileFloat (G3D_Map *map, int tileIndex, char *tile) { if (! G3d_readTile (map, tileIndex, tile, G3D_FLOAT)) { G3d_error ("G3d_readTileFloat: error in G3d_readTile"); return 0; } return 1; } /*---------------------------------------------------------------------------*/ /*! * \brief * * Is equivalent to G3d_readTile (map, tileIndex, tile, G3D_DOUBLE). * * \param map * \param tileIndex * \param tile * \return int */ int G3d_readTileDouble (G3D_Map *map, int tileIndex, char *tile) { if (! G3d_readTile (map, tileIndex, tile, G3D_DOUBLE)) { G3d_error ("G3d_readTileDouble: error in G3d_readTile"); return 0; } return 1; } /*---------------------------------------------------------------------------*/ /* CACHE-MODE-ONLY FUNCTIONS */ /*---------------------------------------------------------------------------*/ /*! * \brief * * Locks tile with tileIndex in cache. If after locking fewer than the minimum number of * unlocked tiles are unlocked, the lock request is ignored. * * \param map * \param tileIndex * \return 1 ... if successful, * -1 ... if request is ignored, * 0 ... otherwise. */ int G3d_lockTile (G3D_Map *map, int tileIndex) { if (! map->useCache) G3d_fatalError ("G3d_lockTile: function invalid in non-cache mode"); if (! G3d_cache_lock (map->cache, tileIndex)) { G3d_error ("G3d_lockTile: error in G3d_cache_lock"); return 0; } return 1; } /*---------------------------------------------------------------------------*/ /*! * \brief * * Unlocks tile with tileIndex. * * \param map * \param tileIndex * \return 1 ... if successful, * 0 ... otherwise. */ int G3d_unlockTile (G3D_Map *map, int tileIndex) { if (! map->useCache) G3d_fatalError ("G3d_unlockTile: function invalid in non-cache mode"); if (! G3d_cache_unlock (map->cache, tileIndex)) { G3d_error ("G3d_unlockTile: error in G3d_cache_unlock"); return 0; } return 1; } /*---------------------------------------------------------------------------*/ /*! * \brief * * Unlocks every tile in cache of map. * * \param map * \return 1 ... if successful, * 0 ... otherwise. */ int G3d_unlockAll (G3D_Map *map) { if (! map->useCache) G3d_fatalError ("G3d_unlockAll: function invalid in non-cache mode"); if (! G3d_cache_unlock_all (map->cache)) { G3d_error ("G3d_unlockAll: error in G3d_cache_unlock_all"); return 0; } return 1; } /*---------------------------------------------------------------------------*/ /*! * \brief * * Turns autolock mode on. * * \param map * \return void */ void G3d_autolockOn (G3D_Map *map) { if (! map->useCache) G3d_fatalError ("G3d_autoLockOn: function invalid in non-cache mode"); G3d_cache_autolock_on (map->cache); } /*---------------------------------------------------------------------------*/ /*! * \brief * * Turns autolock mode Off. * * \param map * \return void */ void G3d_autolockOff (G3D_Map *map) { if (! map->useCache) G3d_fatalError ("G3d_autoLockOff: function invalid in non-cache mode"); G3d_cache_autolock_off (map->cache); } /*---------------------------------------------------------------------------*/ /*! * \brief * * Sets the minimum * number of unlocked tiles to minUnlocked. This function should be used * in combination with G3d_unlockAll () in order to avoid situations where the * new minimum is larger than the actual number of unlocked tiles. * minUnlocked must be one of G3D_USE_CACHE_X, G3D_USE_CACHE_Y, * G3D_USE_CACHE_Z, G3D_USE_CACHE_XY, G3D_USE_CACHE_XZ, * G3D_USE_CACHE_YZ, G3D_USE_CACHE_XYZ, the result of G3d_cacheSizeEncode() * (cf.{g3d:G3d.cacheSizeEncode}), or any positive integer * which explicitly specifies the number of tiles. * * \param map * \param minUnlocked * \return void */ void G3d_minUnlocked (G3D_Map *map, int minUnlocked) { if (! map->useCache) G3d_fatalError ("G3d_autoLockOff: function invalid in non-cache mode"); G3d_cache_set_minUnlock (map->cache, G3d__computeCacheSize (map, minUnlocked)); } /*---------------------------------------------------------------------------*/ /*! * \brief * * Starts a new cycle. * * \param map * \return 1 ... if successful, * 0 ... otherwise. */ int G3d_beginCycle (G3D_Map *map) { if (! G3d_unlockAll (map)) { G3d_fatalError ("G3d_beginCycle: error in G3d_unlockAll"); return 0; } G3d_autolockOn (map); return 1; } /*---------------------------------------------------------------------------*/ /*! * \brief * * Ends a cycle. * * \param map * \return 1 ... if successful, * 0 ... otherwise. */ int G3d_endCycle (G3D_Map *map) { G3d_autolockOff (map); return 1; }