Added my two new compressor classes - one based on Miniz and the other based on RLE.

This commit is contained in:
Daviw Williams 2013-01-30 16:04:47 +01:00
parent 7b64c0c3c0
commit 804a766037
6 changed files with 175 additions and 1 deletions

View File

@ -31,6 +31,7 @@ endif()
SET(CORE_SRC_FILES SET(CORE_SRC_FILES
source/ArraySizes.cpp source/ArraySizes.cpp
source/AStarPathfinder.cpp source/AStarPathfinder.cpp
source/MinizCompressor.cpp
source/Log.cpp source/Log.cpp
source/Region.cpp source/Region.cpp
source/VertexTypes.cpp source/VertexTypes.cpp
@ -71,6 +72,7 @@ SET(CORE_INC_FILES
include/PolyVoxCore/MarchingCubesSurfaceExtractor.inl include/PolyVoxCore/MarchingCubesSurfaceExtractor.inl
include/PolyVoxCore/Material.h include/PolyVoxCore/Material.h
include/PolyVoxCore/MaterialDensityPair.h include/PolyVoxCore/MaterialDensityPair.h
include/PolyVoxCore/MinizCompressor.h
include/PolyVoxCore/PolyVoxForwardDeclarations.h include/PolyVoxCore/PolyVoxForwardDeclarations.h
include/PolyVoxCore/RawVolume.h include/PolyVoxCore/RawVolume.h
include/PolyVoxCore/RawVolume.inl include/PolyVoxCore/RawVolume.inl
@ -78,6 +80,8 @@ SET(CORE_INC_FILES
include/PolyVoxCore/Raycast.h include/PolyVoxCore/Raycast.h
include/PolyVoxCore/Raycast.inl include/PolyVoxCore/Raycast.inl
include/PolyVoxCore/Region.h include/PolyVoxCore/Region.h
include/PolyVoxCore/RLECompressor.h
include/PolyVoxCore/RLECompressor.inl
include/PolyVoxCore/SimpleVolume.h include/PolyVoxCore/SimpleVolume.h
include/PolyVoxCore/SimpleVolume.inl include/PolyVoxCore/SimpleVolume.inl
include/PolyVoxCore/SimpleVolumeBlock.inl include/PolyVoxCore/SimpleVolumeBlock.inl

View File

@ -336,7 +336,7 @@ namespace PolyVox
} }
// Robert Jenkins' 32 bit integer hash function // Robert Jenkins' 32 bit integer hash function
// http://www.concentric.net/~ttwang/tech/inthash.htm // http://www.burtleburtle.net/bob/hash/integer.html
template<typename VolumeType> template<typename VolumeType>
uint32_t AStarPathfinder<VolumeType>::hash( uint32_t a) uint32_t AStarPathfinder<VolumeType>::hash( uint32_t a)
{ {

View File

@ -0,0 +1,16 @@
#ifndef __PolyVox_MinizCompressor_H__
#define __PolyVox_MinizCompressor_H__
#include "PolyVoxCore/Impl/TypeDef.h"
class MinizCompressor
{
public:
MinizCompressor();
~MinizCompressor();
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);
};
#endif //__PolyVox_MinizCompressor_H__

View File

@ -0,0 +1,24 @@
#ifndef __PolyVox_RLECompressor_H__
#define __PolyVox_RLECompressor_H__
#include <cstdint>
template<typename ValueType, typename LengthType>
class RLECompressor
{
struct Run
{
ValueType value;
LengthType length;
};
public:
RLECompressor();
~RLECompressor();
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);
};
#include "RLECompressor.inl"
#endif //__PolyVox_RLECompressor_H__

View File

@ -0,0 +1,85 @@
#include <algorithm>
#include <cassert>
template<typename ValueType, typename LengthType>
RLECompressor<ValueType, LengthType>::RLECompressor()
{
}
template<typename ValueType, typename LengthType>
RLECompressor<ValueType, LengthType>::~RLECompressor()
{
}
template<typename ValueType, typename LengthType>
uint32_t RLECompressor<ValueType, LengthType>::compress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength)
{
assert(uSrcLength % sizeof(ValueType) == 0);
uSrcLength /= sizeof(ValueType);
uDstLength /= sizeof(Run);
ValueType* pSrcDataAsInt = reinterpret_cast<ValueType*>(pSrcData);
Run* pDstDataAsRun = reinterpret_cast<Run*>(pDstData);
ValueType* pSrcDataEnd = pSrcDataAsInt + uSrcLength;
Run* pDstDataEnd = pDstDataAsRun + uDstLength;
uint32_t uDstLengthInBytes = 0;
pDstDataAsRun->value = *pSrcDataAsInt;
pSrcDataAsInt++;
pDstDataAsRun->length = 1;
uDstLengthInBytes += sizeof(Run);
while(pSrcDataAsInt < pSrcDataEnd)
{
if((*pSrcDataAsInt == pDstDataAsRun->value) && (pDstDataAsRun->length < std::numeric_limits<LengthType>::max()))
{
pDstDataAsRun->length++;
}
else
{
pDstDataAsRun++;
assert(pDstDataAsRun < pDstDataEnd);
pDstDataAsRun->value = *pSrcDataAsInt;
pDstDataAsRun->length = 1;
uDstLengthInBytes += sizeof(Run);
}
pSrcDataAsInt++;
}
return uDstLengthInBytes;
}
template<typename ValueType, typename LengthType>
uint32_t RLECompressor<ValueType, LengthType>::decompress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength)
{
assert(uSrcLength % sizeof(Run) == 0);
uSrcLength /= sizeof(Run);
uDstLength /= sizeof(ValueType);
Run* pSrcDataAsRun = reinterpret_cast<Run*>(pSrcData);
ValueType* pDstDataAsInt = reinterpret_cast<ValueType*>(pDstData);
Run* pSrcDataEnd = pSrcDataAsRun + uSrcLength;
ValueType* pDstDataEnd = pDstDataAsInt + uDstLength;
uint32_t uDstLengthInBytes = 0;
while(pSrcDataAsRun < pSrcDataEnd)
{
std::fill(pDstDataAsInt, pDstDataAsInt + pSrcDataAsRun->length, pSrcDataAsRun->value);
pDstDataAsInt += pSrcDataAsRun->length;
uDstLengthInBytes += pSrcDataAsRun->length * sizeof(ValueType);
pSrcDataAsRun++;
}
return uDstLengthInBytes;
}

View File

@ -0,0 +1,45 @@
#include "PolyVoxCore/MinizCompressor.h"
// Diable things we don't need, and in particular the zlib compatible names which
// would cause conflicts if a user application is using both PolyVox and zlib.
#define MINIZ_NO_STDIO
#define MINIZ_NO_ARCHIVE_APIS
#define MINIZ_NO_TIME
//#define MINIZ_NO_ZLIB_APIS
#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES
//#define MINIZ_NO_MALLOC
// For some unknown reason the miniz library is supplied only as a
// single .c file without a header. Apparently the only way to use
// it is then to #include it directly which is what the examples do.
#include "PolyVoxCore/Impl/miniz.c"
MinizCompressor::MinizCompressor()
{
}
MinizCompressor::~MinizCompressor()
{
}
uint32_t MinizCompressor::compress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength)
{
mz_ulong ulDstLength = uDstLength;
// Do the compression
int result = mz_compress((unsigned char*)pDstData, &ulDstLength, (const unsigned char*) pSrcData, uSrcLength);
assert(result == MZ_OK);
// Return the number of bytes written to the output.
return ulDstLength;
}
uint32_t MinizCompressor::decompress(void* pSrcData, uint32_t uSrcLength, void* pDstData, uint32_t uDstLength)
{
mz_ulong ulDstLength = uDstLength;
int result = mz_uncompress((unsigned char*) pDstData, &ulDstLength, (const unsigned char*) pSrcData, uSrcLength);
assert(result == MZ_OK);
return ulDstLength;
}