From 804a766037ccd3c6b60dfb3553059c7b7bdcd8dc Mon Sep 17 00:00:00 2001 From: Daviw Williams Date: Wed, 30 Jan 2013 16:04:47 +0100 Subject: [PATCH] Added my two new compressor classes - one based on Miniz and the other based on RLE. --- library/PolyVoxCore/CMakeLists.txt | 4 + .../include/PolyVoxCore/AStarPathfinder.inl | 2 +- .../include/PolyVoxCore/MinizCompressor.h | 16 ++++ .../include/PolyVoxCore/RLECompressor.h | 24 ++++++ .../include/PolyVoxCore/RLECompressor.inl | 85 +++++++++++++++++++ .../polyvoxcore/source/MinizCompressor.cpp | 45 ++++++++++ 6 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 library/PolyVoxCore/include/PolyVoxCore/MinizCompressor.h create mode 100644 library/PolyVoxCore/include/PolyVoxCore/RLECompressor.h create mode 100644 library/PolyVoxCore/include/PolyVoxCore/RLECompressor.inl create mode 100644 library/polyvoxcore/source/MinizCompressor.cpp diff --git a/library/PolyVoxCore/CMakeLists.txt b/library/PolyVoxCore/CMakeLists.txt index 43f95a91..c62d34ff 100644 --- a/library/PolyVoxCore/CMakeLists.txt +++ b/library/PolyVoxCore/CMakeLists.txt @@ -31,6 +31,7 @@ endif() SET(CORE_SRC_FILES source/ArraySizes.cpp source/AStarPathfinder.cpp + source/MinizCompressor.cpp source/Log.cpp source/Region.cpp source/VertexTypes.cpp @@ -71,6 +72,7 @@ SET(CORE_INC_FILES include/PolyVoxCore/MarchingCubesSurfaceExtractor.inl include/PolyVoxCore/Material.h include/PolyVoxCore/MaterialDensityPair.h + include/PolyVoxCore/MinizCompressor.h include/PolyVoxCore/PolyVoxForwardDeclarations.h include/PolyVoxCore/RawVolume.h include/PolyVoxCore/RawVolume.inl @@ -78,6 +80,8 @@ SET(CORE_INC_FILES include/PolyVoxCore/Raycast.h include/PolyVoxCore/Raycast.inl include/PolyVoxCore/Region.h + include/PolyVoxCore/RLECompressor.h + include/PolyVoxCore/RLECompressor.inl include/PolyVoxCore/SimpleVolume.h include/PolyVoxCore/SimpleVolume.inl include/PolyVoxCore/SimpleVolumeBlock.inl diff --git a/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.inl b/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.inl index 4df72be0..cf490afe 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/AStarPathfinder.inl @@ -336,7 +336,7 @@ namespace PolyVox } // Robert Jenkins' 32 bit integer hash function - // http://www.concentric.net/~ttwang/tech/inthash.htm + // http://www.burtleburtle.net/bob/hash/integer.html template uint32_t AStarPathfinder::hash( uint32_t a) { diff --git a/library/PolyVoxCore/include/PolyVoxCore/MinizCompressor.h b/library/PolyVoxCore/include/PolyVoxCore/MinizCompressor.h new file mode 100644 index 00000000..51474097 --- /dev/null +++ b/library/PolyVoxCore/include/PolyVoxCore/MinizCompressor.h @@ -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__ diff --git a/library/PolyVoxCore/include/PolyVoxCore/RLECompressor.h b/library/PolyVoxCore/include/PolyVoxCore/RLECompressor.h new file mode 100644 index 00000000..c2611eb2 --- /dev/null +++ b/library/PolyVoxCore/include/PolyVoxCore/RLECompressor.h @@ -0,0 +1,24 @@ +#ifndef __PolyVox_RLECompressor_H__ +#define __PolyVox_RLECompressor_H__ + +#include + +template +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__ diff --git a/library/PolyVoxCore/include/PolyVoxCore/RLECompressor.inl b/library/PolyVoxCore/include/PolyVoxCore/RLECompressor.inl new file mode 100644 index 00000000..8b897f6c --- /dev/null +++ b/library/PolyVoxCore/include/PolyVoxCore/RLECompressor.inl @@ -0,0 +1,85 @@ +#include +#include + +template +RLECompressor::RLECompressor() +{ +} + +template +RLECompressor::~RLECompressor() +{ +} + +template +uint32_t RLECompressor::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(pSrcData); + Run* pDstDataAsRun = reinterpret_cast(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::max())) + { + pDstDataAsRun->length++; + } + else + { + pDstDataAsRun++; + assert(pDstDataAsRun < pDstDataEnd); + pDstDataAsRun->value = *pSrcDataAsInt; + pDstDataAsRun->length = 1; + uDstLengthInBytes += sizeof(Run); + } + + pSrcDataAsInt++; + } + + return uDstLengthInBytes; +} + +template +uint32_t RLECompressor::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(pSrcData); + ValueType* pDstDataAsInt = reinterpret_cast(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; +} + diff --git a/library/polyvoxcore/source/MinizCompressor.cpp b/library/polyvoxcore/source/MinizCompressor.cpp new file mode 100644 index 00000000..7e4cbc3e --- /dev/null +++ b/library/polyvoxcore/source/MinizCompressor.cpp @@ -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; +} \ No newline at end of file