Fixes and comments for RLE compression.
This commit is contained in:
parent
46e38c4714
commit
3d66db50e0
@ -22,39 +22,54 @@ namespace PolyVox
|
|||||||
POLYVOX_THROW(std::length_error, "Source length must be a integer multiple of the ValueType size");
|
POLYVOX_THROW(std::length_error, "Source length must be a integer multiple of the ValueType size");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lengths provided are in bytes, so convert them to be in terms of our types.
|
||||||
uSrcLength /= sizeof(ValueType);
|
uSrcLength /= sizeof(ValueType);
|
||||||
uDstLength /= sizeof(Run);
|
uDstLength /= sizeof(Run);
|
||||||
|
|
||||||
ValueType* pSrcDataAsInt = reinterpret_cast<ValueType*>(pSrcData);
|
// Get data pointers in the appropriate type
|
||||||
|
ValueType* pSrcDataAsType = reinterpret_cast<ValueType*>(pSrcData);
|
||||||
Run* pDstDataAsRun = reinterpret_cast<Run*>(pDstData);
|
Run* pDstDataAsRun = reinterpret_cast<Run*>(pDstData);
|
||||||
|
|
||||||
ValueType* pSrcDataEnd = pSrcDataAsInt + uSrcLength;
|
// Pointers to just past the end of the data
|
||||||
|
ValueType* pSrcDataEnd = pSrcDataAsType + uSrcLength;
|
||||||
Run* pDstDataEnd = pDstDataAsRun + uDstLength;
|
Run* pDstDataEnd = pDstDataAsRun + uDstLength;
|
||||||
|
|
||||||
|
//Counter for the output length
|
||||||
uint32_t uDstLengthInBytes = 0;
|
uint32_t uDstLengthInBytes = 0;
|
||||||
|
|
||||||
|
// Read the first element of the source and set up the first run based on it.
|
||||||
pDstDataAsRun->value = *pSrcDataAsInt;
|
pDstDataAsRun->value = *pSrcDataAsType;
|
||||||
pSrcDataAsInt++;
|
pSrcDataAsType++;
|
||||||
pDstDataAsRun->length = 1;
|
pDstDataAsRun->length = 1;
|
||||||
uDstLengthInBytes += sizeof(Run);
|
uDstLengthInBytes += sizeof(Run);
|
||||||
|
|
||||||
while(pSrcDataAsInt < pSrcDataEnd)
|
//Now process all remaining elements of the source.
|
||||||
|
while(pSrcDataAsType < pSrcDataEnd)
|
||||||
{
|
{
|
||||||
if((*pSrcDataAsInt == pDstDataAsRun->value) && (pDstDataAsRun->length < (std::numeric_limits<LengthType>::max)()))
|
// If the value is the same as the current run (and we have not
|
||||||
|
// reached the maximum run length) then extend the current run.
|
||||||
|
if((*pSrcDataAsType == pDstDataAsRun->value) && (pDstDataAsRun->length < (std::numeric_limits<LengthType>::max)()))
|
||||||
{
|
{
|
||||||
pDstDataAsRun->length++;
|
pDstDataAsRun->length++;
|
||||||
}
|
}
|
||||||
|
// Otherwise we need to start a new Run.
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pDstDataAsRun++;
|
pDstDataAsRun++;
|
||||||
assert(pDstDataAsRun < pDstDataEnd);
|
|
||||||
pDstDataAsRun->value = *pSrcDataAsInt;
|
// Check if we have enough space in the destination buffer.
|
||||||
|
if(pDstDataAsRun >= pDstDataEnd)
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::runtime_error, "Insufficient space in destination buffer.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the new run.
|
||||||
|
pDstDataAsRun->value = *pSrcDataAsType;
|
||||||
pDstDataAsRun->length = 1;
|
pDstDataAsRun->length = 1;
|
||||||
uDstLengthInBytes += sizeof(Run);
|
uDstLengthInBytes += sizeof(Run);
|
||||||
}
|
}
|
||||||
|
|
||||||
pSrcDataAsInt++;
|
pSrcDataAsType++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return uDstLengthInBytes;
|
return uDstLengthInBytes;
|
||||||
@ -68,24 +83,34 @@ namespace PolyVox
|
|||||||
POLYVOX_THROW(std::length_error, "Source length must be a integer multiple of the Run size");
|
POLYVOX_THROW(std::length_error, "Source length must be a integer multiple of the Run size");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lengths provided are in bytes, so convert them to be in terms of our types.
|
||||||
uSrcLength /= sizeof(Run);
|
uSrcLength /= sizeof(Run);
|
||||||
uDstLength /= sizeof(ValueType);
|
uDstLength /= sizeof(ValueType);
|
||||||
|
|
||||||
|
// Get data pointers in the appropriate type
|
||||||
Run* pSrcDataAsRun = reinterpret_cast<Run*>(pSrcData);
|
Run* pSrcDataAsRun = reinterpret_cast<Run*>(pSrcData);
|
||||||
ValueType* pDstDataAsInt = reinterpret_cast<ValueType*>(pDstData);
|
ValueType* pDstDataAsType = reinterpret_cast<ValueType*>(pDstData);
|
||||||
|
|
||||||
|
// Pointers to just past the end of the data
|
||||||
Run* pSrcDataEnd = pSrcDataAsRun + uSrcLength;
|
Run* pSrcDataEnd = pSrcDataAsRun + uSrcLength;
|
||||||
ValueType* pDstDataEnd = pDstDataAsInt + uDstLength;
|
ValueType* pDstDataEnd = pDstDataAsType + uDstLength;
|
||||||
|
|
||||||
|
//Counter for the output length
|
||||||
uint32_t uDstLengthInBytes = 0;
|
uint32_t uDstLengthInBytes = 0;
|
||||||
|
|
||||||
while(pSrcDataAsRun < pSrcDataEnd)
|
while(pSrcDataAsRun < pSrcDataEnd)
|
||||||
{
|
{
|
||||||
std::fill(pDstDataAsInt, pDstDataAsInt + pSrcDataAsRun->length, pSrcDataAsRun->value);
|
// Check if we have enough space in the destination buffer.
|
||||||
pDstDataAsInt += pSrcDataAsRun->length;
|
if(pDstDataAsType + pSrcDataAsRun->length > pDstDataEnd)
|
||||||
|
{
|
||||||
|
POLYVOX_THROW(std::runtime_error, "Insufficient space in destination buffer.");
|
||||||
|
}
|
||||||
|
|
||||||
uDstLengthInBytes += pSrcDataAsRun->length * sizeof(ValueType);
|
// Write the run into the destination
|
||||||
|
std::fill(pDstDataAsType, pDstDataAsType + pSrcDataAsRun->length, pSrcDataAsRun->value);
|
||||||
|
pDstDataAsType += pSrcDataAsRun->length;
|
||||||
|
|
||||||
|
uDstLengthInBytes += pSrcDataAsRun->length * sizeof(ValueType);
|
||||||
pSrcDataAsRun++;
|
pSrcDataAsRun++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user