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 : * Permission is hereby granted, free of charge, to any person obtaining a 10 : * copy of this software and associated documentation files (the "Software"), 11 : * to deal in the Software without restriction, including without limitation 12 : * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 : * and/or sell copies of the Software, and to permit persons to whom the 14 : * Software is furnished to do so, subject to the following conditions: 15 : * 16 : * The above copyright notice and this permission notice shall be included 17 : * in all copies or substantial portions of the Software. 18 : * 19 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 : * DEALINGS IN THE SOFTWARE. 26 : ****************************************************************************/ 27 : 28 : #include "blockdir/binarytilelayer.h" 29 : #include "blockdir/blockfile.h" 30 : #include "core/pcidsk_utils.h" 31 : #include "pcidsk_exception.h" 32 : #include <algorithm> 33 : #include <limits> 34 : 35 : using namespace PCIDSK; 36 : 37 : /************************************************************************/ 38 : /* BinaryTileLayer() */ 39 : /************************************************************************/ 40 : 41 : /** 42 : * Constructor. 43 : * 44 : * @param poBlockDir The associated block directory. 45 : * @param nLayer The index of the block layer. 46 : * @param psBlockLayer The block layer info. 47 : * @param psTileLayer The tile layer info. 48 : */ 49 27 : BinaryTileLayer::BinaryTileLayer(BlockDir * poBlockDir, uint32 nLayer, 50 : BlockLayerInfo * psBlockLayer, 51 27 : TileLayerInfo * psTileLayer) 52 27 : : BlockTileLayer(poBlockDir, nLayer, psBlockLayer, psTileLayer) 53 : { 54 27 : } 55 : 56 : /************************************************************************/ 57 : /* WriteTileList() */ 58 : /************************************************************************/ 59 : 60 : /** 61 : * Writes the tile list to disk. 62 : */ 63 12 : void BinaryTileLayer::WriteTileList(void) 64 : { 65 24 : BlockTileInfoList oTileList = moTileList; 66 : 67 12 : SwapBlockTile(&oTileList.front(), oTileList.size()); 68 : 69 12 : WriteToLayer(&oTileList.front(), 0, 70 12 : oTileList.size() * sizeof(BlockTileInfo)); 71 12 : } 72 : 73 : /************************************************************************/ 74 : /* ReadTileList() */ 75 : /************************************************************************/ 76 : 77 : /** 78 : * Reads the tile list from disk. 79 : */ 80 7 : void BinaryTileLayer::ReadTileList(void) 81 : { 82 7 : uint32 nTileCount = GetTileCount(); 83 : 84 7 : uint64 nSize = static_cast<uint64>(nTileCount) * sizeof(BlockTileInfo); 85 : 86 7 : if (nSize > GetLayerSize() || !GetFile()->IsValidFileOffset(nSize)) 87 0 : return ThrowPCIDSKException("The tile layer is corrupted."); 88 : 89 : #if SIZEOF_VOIDP < 8 90 : if (nSize > std::numeric_limits<size_t>::max()) 91 : return ThrowPCIDSKException("Unable to read extremely large tile layer on 32-bit system."); 92 : #endif 93 : 94 : try 95 : { 96 7 : moTileList.resize(nTileCount); 97 : } 98 0 : catch (const std::exception & ex) 99 : { 100 0 : return ThrowPCIDSKException("Out of memory in BinaryTileDir::ReadTileList(): %s", ex.what()); 101 : } 102 : 103 7 : ReadFromLayer(&moTileList.front(), 0, 104 7 : moTileList.size() * sizeof(BlockTileInfo)); 105 : 106 7 : SwapBlockTile(&moTileList.front(), moTileList.size()); 107 : } 108 : 109 : /************************************************************************/ 110 : /* SwapBlockTile() */ 111 : /************************************************************************/ 112 : 113 : /** 114 : * Swaps the specified block tile info array. 115 : * 116 : * @param psTile The block tile info array to swap. 117 : * @param nCount The number of block tile info. 118 : */ 119 19 : void BinaryTileLayer::SwapBlockTile(BlockTileInfo * psTile, size_t nCount) 120 : { 121 19 : if (!mpoBlockDir->NeedsSwap()) 122 19 : return; 123 : 124 0 : for (BlockTileInfo * psEnd = psTile + nCount; 125 0 : psTile < psEnd; psTile++) 126 : { 127 0 : SwapData(&psTile->nOffset, 8, 1); 128 0 : SwapData(&psTile->nSize, 4, 1); 129 : } 130 : }