Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Purpose: Block directory API. 4 : * 5 : ****************************************************************************** 6 : * Copyright (c) 2011 7 : * PCI Geomatics, 90 Allstate Parkway, Markham, Ontario, Canada. 8 : * 9 : * SPDX-License-Identifier: MIT 10 : ****************************************************************************/ 11 : 12 : #include "blockdir/binarytilelayer.h" 13 : #include "blockdir/blockfile.h" 14 : #include "core/pcidsk_utils.h" 15 : #include "pcidsk_exception.h" 16 : #include <algorithm> 17 : #include <limits> 18 : 19 : using namespace PCIDSK; 20 : 21 : /************************************************************************/ 22 : /* BinaryTileLayer() */ 23 : /************************************************************************/ 24 : 25 : /** 26 : * Constructor. 27 : * 28 : * @param poBlockDir The associated block directory. 29 : * @param nLayer The index of the block layer. 30 : * @param psBlockLayer The block layer info. 31 : * @param psTileLayer The tile layer info. 32 : */ 33 27 : BinaryTileLayer::BinaryTileLayer(BlockDir * poBlockDir, uint32 nLayer, 34 : BlockLayerInfo * psBlockLayer, 35 27 : TileLayerInfo * psTileLayer) 36 27 : : BlockTileLayer(poBlockDir, nLayer, psBlockLayer, psTileLayer) 37 : { 38 27 : } 39 : 40 : /************************************************************************/ 41 : /* WriteTileList() */ 42 : /************************************************************************/ 43 : 44 : /** 45 : * Writes the tile list to disk. 46 : */ 47 12 : void BinaryTileLayer::WriteTileList(void) 48 : { 49 24 : BlockTileInfoList oTileList = moTileList; 50 : 51 12 : SwapBlockTile(&oTileList.front(), oTileList.size()); 52 : 53 12 : WriteToLayer(&oTileList.front(), 0, 54 12 : oTileList.size() * sizeof(BlockTileInfo)); 55 12 : } 56 : 57 : /************************************************************************/ 58 : /* ReadTileList() */ 59 : /************************************************************************/ 60 : 61 : /** 62 : * Reads the tile list from disk. 63 : */ 64 7 : void BinaryTileLayer::ReadTileList(void) 65 : { 66 7 : uint32 nTileCount = GetTileCount(); 67 : 68 7 : uint64 nSize = static_cast<uint64>(nTileCount) * sizeof(BlockTileInfo); 69 : 70 7 : if (nSize > GetLayerSize() || !GetFile()->IsValidFileOffset(nSize)) 71 0 : return ThrowPCIDSKException("The tile layer is corrupted."); 72 : 73 : #if SIZEOF_VOIDP < 8 74 : if (nSize > std::numeric_limits<size_t>::max()) 75 : return ThrowPCIDSKException("Unable to read extremely large tile layer on 32-bit system."); 76 : #endif 77 : 78 : try 79 : { 80 7 : moTileList.resize(nTileCount); 81 : } 82 0 : catch (const std::exception & ex) 83 : { 84 0 : return ThrowPCIDSKException("Out of memory in BinaryTileDir::ReadTileList(): %s", ex.what()); 85 : } 86 : 87 7 : ReadFromLayer(&moTileList.front(), 0, 88 7 : moTileList.size() * sizeof(BlockTileInfo)); 89 : 90 7 : SwapBlockTile(&moTileList.front(), moTileList.size()); 91 : } 92 : 93 : /************************************************************************/ 94 : /* SwapBlockTile() */ 95 : /************************************************************************/ 96 : 97 : /** 98 : * Swaps the specified block tile info array. 99 : * 100 : * @param psTile The block tile info array to swap. 101 : * @param nCount The number of block tile info. 102 : */ 103 19 : void BinaryTileLayer::SwapBlockTile(BlockTileInfo * psTile, size_t nCount) 104 : { 105 19 : if (!mpoBlockDir->NeedsSwap()) 106 19 : return; 107 : 108 0 : for (BlockTileInfo * psEnd = psTile + nCount; 109 0 : psTile < psEnd; psTile++) 110 : { 111 0 : SwapData(&psTile->nOffset, 8, 1); 112 0 : SwapData(&psTile->nSize, 4, 1); 113 : } 114 : }