More work making the compression more robust.

This commit is contained in:
Daviw Williams 2013-02-01 16:10:10 +01:00
parent a5b768e5f9
commit 09c6e2bf26
2 changed files with 28 additions and 23 deletions

View File

@ -141,7 +141,7 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
void Block<VoxelType>::compress(Compressor* pCompressor) void Block<VoxelType>::compress(Compressor* pCompressor)
{ {
//POLYVOX_ASSERT(pCompressor, "Compressor is not valid"); POLYVOX_ASSERT(pCompressor, "Compressor is not valid");
POLYVOX_ASSERT(m_bIsCompressed == false, "Attempted to compress block which is already flagged as compressed."); POLYVOX_ASSERT(m_bIsCompressed == false, "Attempted to compress block which is already flagged as compressed.");
POLYVOX_ASSERT(m_tUncompressedData != 0, "No uncompressed data is present."); POLYVOX_ASSERT(m_tUncompressedData != 0, "No uncompressed data is present.");
@ -149,53 +149,58 @@ namespace PolyVox
//modified then we don't need to redo the compression. //modified then we don't need to redo the compression.
if(m_bIsUncompressedDataModified) if(m_bIsUncompressedDataModified)
{ {
// Delete the old compressed data as we'll create a new one
delete[] m_pCompressedData;
m_pCompressedData = 0;
void* pSrcData = reinterpret_cast<void*>(m_tUncompressedData); void* pSrcData = reinterpret_cast<void*>(m_tUncompressedData);
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; uint8_t tempBuffer[10000];
void* pDstData = reinterpret_cast<void*>( tempBuffer );
uint32_t uDstLength = 10000;
uint32_t uCompressedLength = 0; uint32_t uCompressedLength = 0;
try try
{ {
uint8_t buffer[1000000];
pDstData = reinterpret_cast<void*>( buffer );
uint32_t uDstLength = 1000000;
uCompressedLength = pCompressor->compress(pSrcData, uSrcLength, pDstData, uDstLength); uCompressedLength = pCompressor->compress(pSrcData, uSrcLength, pDstData, uDstLength);
// Create new compressed data and copy across
m_pCompressedData = reinterpret_cast<void*>( new uint8_t[uCompressedLength] );
memcpy(m_pCompressedData, pDstData, uCompressedLength);
m_uCompressedDataLength = uCompressedLength;
} }
catch(std::exception& e) catch(std::exception&)
{ {
// It is possible for the compression to fail. A common cause for this would be if the destination // 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. // buffer is not big enough. So now we try again using a buffer that is definitely big enough.
// Note that ideally we will choose our earlier buffer size so that this almost never happens.
uint32_t uMaxCompressedSize = pCompressor->getMaxCompressedSize(uSrcLength); uint32_t uMaxCompressedSize = pCompressor->getMaxCompressedSize(uSrcLength);
uint8_t* buffer = new uint8_t[ uMaxCompressedSize ]; uint8_t* buffer = new uint8_t[ uMaxCompressedSize ];
pDstData = reinterpret_cast<void*>( buffer ); pDstData = reinterpret_cast<void*>( buffer );
uint32_t uDstLength = uMaxCompressedSize; uDstLength = uMaxCompressedSize;
try try
{ {
uCompressedLength = pCompressor->compress(pSrcData, uSrcLength, pDstData, uDstLength); uCompressedLength = pCompressor->compress(pSrcData, uSrcLength, pDstData, uDstLength);
// Create new compressed data and copy across
m_pCompressedData = reinterpret_cast<void*>( new uint8_t[uCompressedLength] );
memcpy(m_pCompressedData, pDstData, uCompressedLength);
m_uCompressedDataLength = uCompressedLength;
} }
catch(std::exception& e) catch(std::exception&)
{ {
// At this point it didn't work even with a bigger buffer. // At this point it didn't work even with a bigger buffer.
// Not much more we can do so just rethrow the exception. // Not much more we can do so just rethrow the exception.
delete buffer; delete[] buffer;
POLYVOX_THROW(std::runtime_error, "Failed to compress block data"); POLYVOX_THROW(std::runtime_error, "Failed to compress block data");
} }
delete buffer; 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;
} }
//Flag the uncompressed data as no longer being used. //Flag the uncompressed data as no longer being used.

View File

@ -271,8 +271,8 @@ TestVolume::TestVolume()
{ {
Region region(-57, -31, 12, 64, 96, 131); // Deliberatly awkward size Region region(-57, -31, 12, 64, 96, 131); // Deliberatly awkward size
m_pCompressor = new RLECompressor<int32_t, uint16_t>; //m_pCompressor = new RLECompressor<int32_t, uint16_t>;
//m_pCompressor = new MinizCompressor; m_pCompressor = new MinizCompressor;
//Create the volumes //Create the volumes
m_pRawVolume = new RawVolume<int32_t>(region); m_pRawVolume = new RawVolume<int32_t>(region);