Working to make compression handing more robust.
This commit is contained in:
parent
3d66db50e0
commit
a5b768e5f9
@ -34,7 +34,14 @@ namespace PolyVox
|
|||||||
Compressor() {};
|
Compressor() {};
|
||||||
virtual ~Compressor() {};
|
virtual ~Compressor() {};
|
||||||
|
|
||||||
|
// Computes a worst-case scenario for how big the output can be for a given input size. If
|
||||||
|
// necessary you can use this as a destination buffer size, though it may be somewhat wasteful.
|
||||||
|
virtual uint32_t getMaxCompressedSize(uint32_t uUncompressedInputSize) = 0;
|
||||||
|
|
||||||
|
// Compresses the data.
|
||||||
virtual uint32_t compress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength) = 0;
|
virtual uint32_t compress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength) = 0;
|
||||||
|
|
||||||
|
// Decompresses the data.
|
||||||
virtual uint32_t decompress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength) = 0;
|
virtual uint32_t decompress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -150,19 +150,52 @@ namespace PolyVox
|
|||||||
if(m_bIsUncompressedDataModified)
|
if(m_bIsUncompressedDataModified)
|
||||||
{
|
{
|
||||||
void* pSrcData = reinterpret_cast<void*>(m_tUncompressedData);
|
void* pSrcData = reinterpret_cast<void*>(m_tUncompressedData);
|
||||||
void* pDstData = reinterpret_cast<void*>( new uint8_t[1000000] );
|
|
||||||
uint32_t uSrcLength = m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType);
|
uint32_t uSrcLength = m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType);
|
||||||
|
|
||||||
|
void* pDstData = 0;
|
||||||
|
uint32_t uCompressedLength = 0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
uint8_t buffer[1000000];
|
||||||
|
|
||||||
|
pDstData = reinterpret_cast<void*>( buffer );
|
||||||
uint32_t uDstLength = 1000000;
|
uint32_t uDstLength = 1000000;
|
||||||
|
|
||||||
//MinizCompressor compressor;
|
uCompressedLength = pCompressor->compress(pSrcData, uSrcLength, pDstData, uDstLength);
|
||||||
//RLECompressor<VoxelType, uint16_t> compressor;
|
}
|
||||||
uint32_t uCompressedLength = pCompressor->compress(pSrcData, uSrcLength, pDstData, uDstLength);
|
catch(std::exception& e)
|
||||||
|
{
|
||||||
|
// It is possible for the compression to fail. A common cause for this would be if the destination
|
||||||
|
// buffer is not big enough. So now we try again using a buffer that is definitely big enough.
|
||||||
|
uint32_t uMaxCompressedSize = pCompressor->getMaxCompressedSize(uSrcLength);
|
||||||
|
uint8_t* buffer = new uint8_t[ uMaxCompressedSize ];
|
||||||
|
|
||||||
|
pDstData = reinterpret_cast<void*>( buffer );
|
||||||
|
uint32_t uDstLength = uMaxCompressedSize;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
uCompressedLength = pCompressor->compress(pSrcData, uSrcLength, pDstData, uDstLength);
|
||||||
|
}
|
||||||
|
catch(std::exception& e)
|
||||||
|
{
|
||||||
|
// At this point it didn't work even with a bigger buffer.
|
||||||
|
// Not much more we can do so just rethrow the exception.
|
||||||
|
delete buffer;
|
||||||
|
POLYVOX_THROW(std::runtime_error, "Failed to compress block data");
|
||||||
|
}
|
||||||
|
|
||||||
|
delete buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the old compressed data and assign a new one
|
||||||
|
delete m_pCompressedData;
|
||||||
m_pCompressedData = reinterpret_cast<void*>( new uint8_t[uCompressedLength] );
|
m_pCompressedData = reinterpret_cast<void*>( new uint8_t[uCompressedLength] );
|
||||||
|
|
||||||
|
//Copy the data across
|
||||||
memcpy(m_pCompressedData, pDstData, uCompressedLength);
|
memcpy(m_pCompressedData, pDstData, uCompressedLength);
|
||||||
m_uCompressedDataLength = uCompressedLength;
|
m_uCompressedDataLength = uCompressedLength;
|
||||||
|
|
||||||
delete pDstData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Flag the uncompressed data as no longer being used.
|
//Flag the uncompressed data as no longer being used.
|
||||||
|
@ -619,7 +619,9 @@ namespace PolyVox
|
|||||||
// create the new block
|
// create the new block
|
||||||
LoadedBlock newBlock(m_uBlockSideLength);
|
LoadedBlock newBlock(m_uBlockSideLength);
|
||||||
|
|
||||||
//Blocks start out compressed - should we change this?
|
// Blocks start out compressed - should we change this?
|
||||||
|
// Or maybe we should just 'seed' them with compressed data,
|
||||||
|
// rather than creating an empty block and then compressing?
|
||||||
newBlock.block.compress(m_pCompressor);
|
newBlock.block.compress(m_pCompressor);
|
||||||
|
|
||||||
itBlock = m_pBlocks.insert(std::make_pair(v3dBlockPos, newBlock)).first;
|
itBlock = m_pBlocks.insert(std::make_pair(v3dBlockPos, newBlock)).first;
|
||||||
|
@ -11,6 +11,7 @@ namespace PolyVox
|
|||||||
MinizCompressor();
|
MinizCompressor();
|
||||||
~MinizCompressor();
|
~MinizCompressor();
|
||||||
|
|
||||||
|
uint32_t getMaxCompressedSize(uint32_t uUncompressedInputSize);
|
||||||
uint32_t compress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength);
|
uint32_t compress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength);
|
||||||
uint32_t decompress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength);
|
uint32_t decompress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength);
|
||||||
};
|
};
|
||||||
|
@ -17,6 +17,7 @@ namespace PolyVox
|
|||||||
RLECompressor();
|
RLECompressor();
|
||||||
~RLECompressor();
|
~RLECompressor();
|
||||||
|
|
||||||
|
uint32_t getMaxCompressedSize(uint32_t uUncompressedInputSize);
|
||||||
uint32_t compress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength);
|
uint32_t compress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength);
|
||||||
uint32_t decompress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength);
|
uint32_t decompress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength);
|
||||||
};
|
};
|
||||||
|
@ -14,6 +14,13 @@ namespace PolyVox
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename ValueType, typename LengthType>
|
||||||
|
uint32_t RLECompressor<ValueType, LengthType>::getMaxCompressedSize(uint32_t uUncompressedInputSize)
|
||||||
|
{
|
||||||
|
// In the worst case we will have a seperate Run (of length one) for each element of the input data.
|
||||||
|
return uUncompressedInputSize * sizeof(Run);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ValueType, typename LengthType>
|
template<typename ValueType, typename LengthType>
|
||||||
uint32_t RLECompressor<ValueType, LengthType>::compress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength)
|
uint32_t RLECompressor<ValueType, LengthType>::compress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength)
|
||||||
{
|
{
|
||||||
|
@ -29,6 +29,11 @@ namespace PolyVox
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t MinizCompressor::getMaxCompressedSize(uint32_t uUncompressedInputSize)
|
||||||
|
{
|
||||||
|
return static_cast<uint32_t>(mz_compressBound(static_cast<mz_ulong>(uUncompressedInputSize)));
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t MinizCompressor::compress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength)
|
uint32_t MinizCompressor::compress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength)
|
||||||
{
|
{
|
||||||
mz_ulong ulDstLength = uDstLength;
|
mz_ulong ulDstLength = uDstLength;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user