Working to make compression handing more robust.
This commit is contained in:
parent
3d66db50e0
commit
a5b768e5f9
@ -34,7 +34,14 @@ namespace PolyVox
|
||||
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;
|
||||
|
||||
// Decompresses the data.
|
||||
virtual uint32_t decompress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength) = 0;
|
||||
};
|
||||
}
|
||||
|
@ -150,19 +150,52 @@ namespace PolyVox
|
||||
if(m_bIsUncompressedDataModified)
|
||||
{
|
||||
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 uDstLength = 1000000;
|
||||
|
||||
//MinizCompressor compressor;
|
||||
//RLECompressor<VoxelType, uint16_t> compressor;
|
||||
uint32_t uCompressedLength = pCompressor->compress(pSrcData, uSrcLength, pDstData, uDstLength);
|
||||
void* pDstData = 0;
|
||||
uint32_t uCompressedLength = 0;
|
||||
|
||||
try
|
||||
{
|
||||
uint8_t buffer[1000000];
|
||||
|
||||
pDstData = reinterpret_cast<void*>( buffer );
|
||||
uint32_t uDstLength = 1000000;
|
||||
|
||||
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] );
|
||||
|
||||
//Copy the data across
|
||||
memcpy(m_pCompressedData, pDstData, uCompressedLength);
|
||||
m_uCompressedDataLength = uCompressedLength;
|
||||
|
||||
delete pDstData;
|
||||
}
|
||||
|
||||
//Flag the uncompressed data as no longer being used.
|
||||
|
@ -619,7 +619,9 @@ namespace PolyVox
|
||||
// create the new block
|
||||
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);
|
||||
|
||||
itBlock = m_pBlocks.insert(std::make_pair(v3dBlockPos, newBlock)).first;
|
||||
|
@ -11,6 +11,7 @@ namespace PolyVox
|
||||
MinizCompressor();
|
||||
~MinizCompressor();
|
||||
|
||||
uint32_t getMaxCompressedSize(uint32_t uUncompressedInputSize);
|
||||
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);
|
||||
};
|
||||
|
@ -17,6 +17,7 @@ namespace PolyVox
|
||||
RLECompressor();
|
||||
~RLECompressor();
|
||||
|
||||
uint32_t getMaxCompressedSize(uint32_t uUncompressedInputSize);
|
||||
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);
|
||||
};
|
||||
|
@ -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>
|
||||
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)
|
||||
{
|
||||
mz_ulong ulDstLength = uDstLength;
|
||||
|
Loading…
x
Reference in New Issue
Block a user