Very bad (but functional!) initial implementation of LargeVolume compression with miniz.

This commit is contained in:
Daviw Williams 2013-01-10 16:20:29 +01:00
parent a8383b47db
commit c7937b176d
8 changed files with 4908 additions and 12 deletions

View File

@ -94,6 +94,7 @@ SET(CORE_INC_FILES
) )
SET(IMPL_SRC_FILES SET(IMPL_SRC_FILES
source/Impl/Compression.cpp
source/Impl/ErrorHandling.cpp source/Impl/ErrorHandling.cpp
source/Impl/MarchingCubesTables.cpp source/Impl/MarchingCubesTables.cpp
source/Impl/RandomUnitVectors.cpp source/Impl/RandomUnitVectors.cpp
@ -108,6 +109,7 @@ SET(IMPL_INC_FILES
include/PolyVoxCore/Impl/Block.h include/PolyVoxCore/Impl/Block.h
include/PolyVoxCore/Impl/Block.inl include/PolyVoxCore/Impl/Block.inl
include/PolyVoxCore/Impl/CompilerCapabilities.h include/PolyVoxCore/Impl/CompilerCapabilities.h
include/PolyVoxCore/Impl/Compression.h
include/PolyVoxCore/Impl/Config.h include/PolyVoxCore/Impl/Config.h
include/PolyVoxCore/Impl/ErrorHandling.h include/PolyVoxCore/Impl/ErrorHandling.h
include/PolyVoxCore/Impl/MarchingCubesTables.h include/PolyVoxCore/Impl/MarchingCubesTables.h

View File

@ -65,6 +65,8 @@ namespace PolyVox
void uncompress(void); void uncompress(void);
std::vector< RunlengthEntry<uint16_t> > m_vecCompressedData; std::vector< RunlengthEntry<uint16_t> > m_vecCompressedData;
uint8_t* m_pCompressedData;
uint32_t m_uCompressedDataLength;
VoxelType* m_tUncompressedData; VoxelType* m_tUncompressedData;
uint16_t m_uSideLength; uint16_t m_uSideLength;
uint8_t m_uSideLengthPower; uint8_t m_uSideLengthPower;

View File

@ -21,6 +21,7 @@ freely, subject to the following restrictions:
distribution. distribution.
*******************************************************************************/ *******************************************************************************/
#include "PolyVoxCore/Impl/Compression.h"
#include "PolyVoxCore/Impl/ErrorHandling.h" #include "PolyVoxCore/Impl/ErrorHandling.h"
#include "PolyVoxCore/Impl/Utility.h" #include "PolyVoxCore/Impl/Utility.h"
@ -36,10 +37,12 @@ namespace PolyVox
{ {
template <typename VoxelType> template <typename VoxelType>
Block<VoxelType>::Block(uint16_t uSideLength) Block<VoxelType>::Block(uint16_t uSideLength)
:m_tUncompressedData(0) :m_pCompressedData(0)
,m_uCompressedDataLength(0)
,m_tUncompressedData(0)
,m_uSideLength(0) ,m_uSideLength(0)
,m_uSideLengthPower(0) ,m_uSideLengthPower(0)
,m_bIsCompressed(true) ,m_bIsCompressed(false)
,m_bIsUncompressedDataModified(true) ,m_bIsUncompressedDataModified(true)
{ {
if(uSideLength != 0) if(uSideLength != 0)
@ -116,6 +119,7 @@ namespace PolyVox
} }
else else
{ {
POLYVOX_ASSERT(false, "Not implemented");
RunlengthEntry<uint16_t> rle; RunlengthEntry<uint16_t> rle;
rle.length = m_uSideLength*m_uSideLength*m_uSideLength; rle.length = m_uSideLength*m_uSideLength*m_uSideLength;
rle.value = tValue; rle.value = tValue;
@ -140,7 +144,11 @@ namespace PolyVox
m_uSideLength = uSideLength; m_uSideLength = uSideLength;
m_uSideLengthPower = logBase2(uSideLength); m_uSideLengthPower = logBase2(uSideLength);
m_tUncompressedData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength];
Block<VoxelType>::fill(VoxelType()); Block<VoxelType>::fill(VoxelType());
compress();
} }
template <typename VoxelType> template <typename VoxelType>
@ -161,7 +169,16 @@ 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)
{ {
uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength; Data src;
src.ptr = reinterpret_cast<uint8_t*>(m_tUncompressedData);
src.length = m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType);
Data compressedResult = polyvox_compress(src);
m_pCompressedData = compressedResult.ptr;
m_uCompressedDataLength = compressedResult.length;
/*uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength;
m_vecCompressedData.clear(); m_vecCompressedData.clear();
RunlengthEntry<uint16_t> entry; RunlengthEntry<uint16_t> entry;
@ -188,7 +205,7 @@ namespace PolyVox
//Shrink the vectors to their contents (maybe slow?): //Shrink the vectors to their contents (maybe slow?):
//http://stackoverflow.com/questions/1111078/reduce-the-capacity-of-an-stl-vector //http://stackoverflow.com/questions/1111078/reduce-the-capacity-of-an-stl-vector
//C++0x may have a shrink_to_fit() function? //C++0x may have a shrink_to_fit() function?
std::vector< RunlengthEntry<uint16_t> >(m_vecCompressedData).swap(m_vecCompressedData); std::vector< RunlengthEntry<uint16_t> >(m_vecCompressedData).swap(m_vecCompressedData);*/
} }
//Flag the uncompressed data as no longer being used. //Flag the uncompressed data as no longer being used.
@ -202,14 +219,22 @@ namespace PolyVox
{ {
POLYVOX_ASSERT(m_bIsCompressed == true, "Attempted to uncompress block which is not flagged as compressed."); POLYVOX_ASSERT(m_bIsCompressed == true, "Attempted to uncompress block which is not flagged as compressed.");
POLYVOX_ASSERT(m_tUncompressedData == 0, "Uncompressed data already exists."); POLYVOX_ASSERT(m_tUncompressedData == 0, "Uncompressed data already exists.");
m_tUncompressedData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength]; /*m_tUncompressedData = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength];
VoxelType* pUncompressedData = m_tUncompressedData; VoxelType* pUncompressedData = m_tUncompressedData;
for(uint32_t ct = 0; ct < m_vecCompressedData.size(); ++ct) for(uint32_t ct = 0; ct < m_vecCompressedData.size(); ++ct)
{ {
std::fill(pUncompressedData, pUncompressedData + m_vecCompressedData[ct].length, m_vecCompressedData[ct].value); std::fill(pUncompressedData, pUncompressedData + m_vecCompressedData[ct].length, m_vecCompressedData[ct].value);
pUncompressedData += m_vecCompressedData[ct].length; pUncompressedData += m_vecCompressedData[ct].length;
} }*/
Data src;
src.ptr = m_pCompressedData;
src.length = m_uCompressedDataLength;
Data uncompressedResult = polyvox_decompress(src);
m_tUncompressedData = reinterpret_cast<VoxelType*>(uncompressedResult.ptr);
m_bIsCompressed = false; m_bIsCompressed = false;
m_bIsUncompressedDataModified = false; m_bIsUncompressedDataModified = false;

View File

@ -0,0 +1,38 @@
/*******************************************************************************
Copyright (c) 2005-2009 David Williams
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*******************************************************************************/
#ifndef __PolyVox_Compression_H__
#define __PolyVox_Compression_H__
#include "PolyVoxCore/Impl/TypeDef.h"
struct Data
{
uint8_t* ptr;
unsigned long length; // Think what type this should be.
};
Data polyvox_compress(Data src);
Data polyvox_decompress(Data src);
#endif //__PolyVox_Compression_H__

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,63 @@
#include "PolyVoxCore/Impl/Compression.h"
#include "PolyVoxCore/Impl/ErrorHandling.h"
// The miniz library is supplied only as a single .c file without a header.
// Apparently the only way to use it would then be to #include it directly
// which is what the examples do.
#include "PolyVoxCore/Impl/miniz.c"
Data polyvox_compress(Data src)
{
POLYVOX_ASSERT(src.ptr != 0, "Source data cannot be null");
unsigned char* buffer;
mz_ulong compressedDataLength = compressBound(src.length);
buffer = new unsigned char[compressedDataLength];
int iCompressionResult = compress(buffer, &compressedDataLength, static_cast<const unsigned char*>(src.ptr), src.length);
// Debug more checking
POLYVOX_ASSERT(iCompressionResult == Z_OK, "Data compression failed.");
// Release mode checking
if (iCompressionResult != Z_OK)
{
delete[] buffer;
POLYVOX_THROW(std::runtime_error, "Data compression failed.");
}
Data dst;
dst.length = compressedDataLength;
dst.ptr = new uint8_t[dst.length];
memcpy(dst.ptr, buffer, compressedDataLength);
delete[] buffer;
return dst;
}
Data polyvox_decompress(Data src)
{
unsigned char* buffer;
mz_ulong uncompressedDataLength = 1000000;
buffer = new unsigned char[uncompressedDataLength];
int iUncompressionResult = uncompress(buffer, &uncompressedDataLength, src.ptr, src.length);
if (iUncompressionResult != Z_OK)
{
delete[] buffer;
POLYVOX_THROW(std::runtime_error, "Data decompression failed.");
}
Data dst;
dst.length = uncompressedDataLength;
dst.ptr = new uint8_t[dst.length];
memcpy(dst.ptr, buffer, uncompressedDataLength);
delete[] buffer;
return dst;
}

View File

@ -305,7 +305,7 @@ TestVolume::~TestVolume()
* RawVolume Tests * RawVolume Tests
*/ */
void TestVolume::testRawVolumeDirectAccessAllInternalForwards() /*void TestVolume::testRawVolumeDirectAccessAllInternalForwards()
{ {
int32_t result = 0; int32_t result = 0;
@ -391,13 +391,13 @@ void TestVolume::testRawVolumeSamplersWithExternalBackwards()
result = testSamplersWithWrappingBackwards(m_pRawVolume, -1, -3, -2, 2, 5, 4); result = testSamplersWithWrappingBackwards(m_pRawVolume, -1, -3, -2, 2, 5, 4);
} }
QCOMPARE(result, static_cast<int32_t>(-769775893)); QCOMPARE(result, static_cast<int32_t>(-769775893));
} }*/
/* /*
* SimpleVolume Tests * SimpleVolume Tests
*/ */
void TestVolume::testSimpleVolumeDirectAccessAllInternalForwards() /*void TestVolume::testSimpleVolumeDirectAccessAllInternalForwards()
{ {
int32_t result = 0; int32_t result = 0;
QBENCHMARK QBENCHMARK
@ -475,7 +475,7 @@ void TestVolume::testSimpleVolumeSamplersWithExternalBackwards()
result = testSamplersWithWrappingBackwards(m_pSimpleVolume, -1, -3, -2, 2, 5, 4); result = testSamplersWithWrappingBackwards(m_pSimpleVolume, -1, -3, -2, 2, 5, 4);
} }
QCOMPARE(result, static_cast<int32_t>(-769775893)); QCOMPARE(result, static_cast<int32_t>(-769775893));
} }*/
/* /*
* LargeVolume Tests * LargeVolume Tests

View File

@ -37,7 +37,7 @@ public:
~TestVolume(); ~TestVolume();
private slots: private slots:
void testRawVolumeDirectAccessAllInternalForwards(); /*void testRawVolumeDirectAccessAllInternalForwards();
void testRawVolumeSamplersAllInternalForwards(); void testRawVolumeSamplersAllInternalForwards();
void testRawVolumeDirectAccessWithExternalForwards(); void testRawVolumeDirectAccessWithExternalForwards();
void testRawVolumeSamplersWithExternalForwards(); void testRawVolumeSamplersWithExternalForwards();
@ -53,7 +53,7 @@ private slots:
void testSimpleVolumeDirectAccessAllInternalBackwards(); void testSimpleVolumeDirectAccessAllInternalBackwards();
void testSimpleVolumeSamplersAllInternalBackwards(); void testSimpleVolumeSamplersAllInternalBackwards();
void testSimpleVolumeDirectAccessWithExternalBackwards(); void testSimpleVolumeDirectAccessWithExternalBackwards();
void testSimpleVolumeSamplersWithExternalBackwards(); void testSimpleVolumeSamplersWithExternalBackwards();*/
void testLargeVolumeDirectAccessAllInternalForwards(); void testLargeVolumeDirectAccessAllInternalForwards();
void testLargeVolumeSamplersAllInternalForwards(); void testLargeVolumeSamplersAllInternalForwards();