summaryrefslogtreecommitdiff
path: root/src/mesh/assimp-master/contrib/Open3DGC/o3dgcDynamicVectorEncoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesh/assimp-master/contrib/Open3DGC/o3dgcDynamicVectorEncoder.cpp')
-rw-r--r--src/mesh/assimp-master/contrib/Open3DGC/o3dgcDynamicVectorEncoder.cpp295
1 files changed, 295 insertions, 0 deletions
diff --git a/src/mesh/assimp-master/contrib/Open3DGC/o3dgcDynamicVectorEncoder.cpp b/src/mesh/assimp-master/contrib/Open3DGC/o3dgcDynamicVectorEncoder.cpp
new file mode 100644
index 0000000..00ae75e
--- /dev/null
+++ b/src/mesh/assimp-master/contrib/Open3DGC/o3dgcDynamicVectorEncoder.cpp
@@ -0,0 +1,295 @@
+/*
+Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+#include "o3dgcDVEncodeParams.h"
+#include "o3dgcDynamicVectorEncoder.h"
+#include "o3dgcArithmeticCodec.h"
+#include "o3dgcBinaryStream.h"
+
+//#define DEBUG_VERBOSE
+
+namespace o3dgc
+{
+#ifdef DEBUG_VERBOSE
+ FILE * g_fileDebugDVEnc = NULL;
+#endif //DEBUG_VERBOSE
+
+ inline O3DGCErrorCode Update(long * const data, const long size)
+ {
+ assert(size > 1);
+ const long size1 = size - 1;
+ long p = 2;
+ data[0] += data[1] >> 1;
+ while(p < size1)
+ {
+ data[p] += (data[p-1] + data[p+1] + 2) >> 2;
+ p += 2;
+ }
+ if ( p == size1)
+ {
+ data[p] += data[p-1]>>1;
+ }
+ return O3DGC_OK;
+ }
+ inline O3DGCErrorCode Predict(long * const data, const long size)
+ {
+ assert(size > 1);
+ const long size1 = size - 1;
+ long p = 1;
+ while(p < size1)
+ {
+ data[p] -= (data[p-1] + data[p+1] + 1) >> 1;
+ p += 2;
+ }
+ if ( p == size1)
+ {
+ data[p] -= data[p-1];
+ }
+ return O3DGC_OK;
+ }
+ inline O3DGCErrorCode Split(long * const data, const long size)
+ {
+ assert(size > 1);
+ long a = 1;
+ long b = size-1;
+ while (a < b)
+ {
+ for (long i = a; i < b; i += 2)
+ {
+ swap(data[i], data[i+1]);
+ }
+ ++a;
+ --b;
+ }
+ return O3DGC_OK;
+ }
+ inline O3DGCErrorCode Transform(long * const data, const unsigned long size)
+ {
+ unsigned long n = size;
+ while(n > 1)
+ {
+ Predict(data, n);
+ Update (data, n);
+ Split(data, n);
+ n = (n >> 1) + (n & 1);
+ }
+ return O3DGC_OK;
+ }
+ DynamicVectorEncoder::DynamicVectorEncoder(void)
+ {
+ m_maxNumVectors = 0;
+ m_numVectors = 0;
+ m_dimVectors = 0;
+ m_quantVectors = 0;
+ m_sizeBufferAC = 0;
+ m_bufferAC = 0;
+ m_posSize = 0;
+ m_streamType = O3DGC_STREAM_TYPE_UNKOWN;
+ }
+ DynamicVectorEncoder::~DynamicVectorEncoder()
+ {
+ delete [] m_quantVectors;
+ delete [] m_bufferAC;
+ }
+ O3DGCErrorCode DynamicVectorEncoder::Encode(const DVEncodeParams & params,
+ const DynamicVector & dynamicVector,
+ BinaryStream & bstream)
+ {
+ assert(params.GetQuantBits() > 0);
+ assert(dynamicVector.GetNVector() > 0);
+ assert(dynamicVector.GetDimVector() > 0);
+ assert(dynamicVector.GetStride() >= dynamicVector.GetDimVector());
+ assert(dynamicVector.GetVectors() && dynamicVector.GetMin() && dynamicVector.GetMax());
+ assert(m_streamType != O3DGC_STREAM_TYPE_UNKOWN);
+ // Encode header
+ unsigned long start = bstream.GetSize();
+ EncodeHeader(params, dynamicVector, bstream);
+ // Encode payload
+ EncodePayload(params, dynamicVector, bstream);
+ bstream.WriteUInt32(m_posSize, bstream.GetSize() - start, m_streamType);
+ return O3DGC_OK;
+
+ }
+ O3DGCErrorCode DynamicVectorEncoder::EncodeHeader(const DVEncodeParams & params,
+ const DynamicVector & dynamicVector,
+ BinaryStream & bstream)
+ {
+ m_streamType = params.GetStreamType();
+ bstream.WriteUInt32(O3DGC_DV_START_CODE, m_streamType);
+ m_posSize = bstream.GetSize();
+ bstream.WriteUInt32(0, m_streamType); // to be filled later
+ bstream.WriteUChar((unsigned char) params.GetEncodeMode(), m_streamType);
+ bstream.WriteUInt32(dynamicVector.GetNVector() , m_streamType);
+ if (dynamicVector.GetNVector() > 0)
+ {
+ bstream.WriteUInt32(dynamicVector.GetDimVector(), m_streamType);
+ bstream.WriteUChar ((unsigned char) params.GetQuantBits(), m_streamType);
+ }
+ return O3DGC_OK;
+ }
+ O3DGCErrorCode DynamicVectorEncoder::EncodeAC(unsigned long num,
+ unsigned long dim,
+ unsigned long M,
+ unsigned long & encodedBytes)
+ {
+ Arithmetic_Codec ace;
+ Static_Bit_Model bModel0;
+ Adaptive_Bit_Model bModel1;
+ Adaptive_Data_Model mModelValues(M+2);
+ const unsigned int NMAX = num * dim * 8 + 100;
+ if ( m_sizeBufferAC < NMAX )
+ {
+ delete [] m_bufferAC;
+ m_sizeBufferAC = NMAX;
+ m_bufferAC = new unsigned char [m_sizeBufferAC];
+ }
+ ace.set_buffer(NMAX, m_bufferAC);
+ ace.start_encoder();
+ ace.ExpGolombEncode(0, 0, bModel0, bModel1);
+ ace.ExpGolombEncode(M, 0, bModel0, bModel1);
+ for(unsigned long v = 0; v < num; ++v)
+ {
+ for(unsigned long d = 0; d < dim; ++d)
+ {
+ EncodeIntACEGC(m_quantVectors[d * num + v], ace, mModelValues, bModel0, bModel1, M);
+ }
+ }
+ encodedBytes = ace.stop_encoder();
+ return O3DGC_OK;
+ }
+
+ O3DGCErrorCode DynamicVectorEncoder::EncodePayload(const DVEncodeParams & params,
+ const DynamicVector & dynamicVector,
+ BinaryStream & bstream)
+ {
+#ifdef DEBUG_VERBOSE
+ g_fileDebugDVEnc = fopen("dv_enc.txt", "w");
+#endif //DEBUG_VERBOSE
+ unsigned long start = bstream.GetSize();
+ const unsigned long dim = dynamicVector.GetDimVector();
+ const unsigned long num = dynamicVector.GetNVector();
+
+ bstream.WriteUInt32(0, m_streamType);
+
+ for(unsigned long j=0 ; j<dynamicVector.GetDimVector() ; ++j)
+ {
+ bstream.WriteFloat32((float) dynamicVector.GetMin(j), m_streamType);
+ bstream.WriteFloat32((float) dynamicVector.GetMax(j), m_streamType);
+ }
+ Quantize(dynamicVector.GetVectors(),
+ num,
+ dim,
+ dynamicVector.GetStride(),
+ dynamicVector.GetMin(),
+ dynamicVector.GetMax(),
+ params.GetQuantBits());
+ for(unsigned long d = 0; d < dim; ++d)
+ {
+ Transform(m_quantVectors + d * num, num);
+ }
+ #ifdef DEBUG_VERBOSE
+ printf("IntArray (%i, %i)\n", num, dim);
+ fprintf(g_fileDebugDVEnc, "IntArray (%i, %i)\n", num, dim);
+ for(unsigned long v = 0; v < num; ++v)
+ {
+ for(unsigned long d = 0; d < dim; ++d)
+ {
+ printf("%i\t %i \t %i\n", d * num + v, m_quantVectors[d * num + v], IntToUInt(m_quantVectors[d * num + v]));
+ fprintf(g_fileDebugDVEnc, "%i\t %i \t %i\n", d * num + v, m_quantVectors[d * num + v], IntToUInt(m_quantVectors[d * num + v]));
+ }
+ }
+ #endif //DEBUG_VERBOSE
+
+ if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
+ {
+ for(unsigned long v = 0; v < num; ++v)
+ {
+ for(unsigned long d = 0; d < dim; ++d)
+ {
+ bstream.WriteIntASCII(m_quantVectors[d * num + v]);
+ }
+ }
+ }
+ else
+ {
+ unsigned long encodedBytes = 0;
+ unsigned long bestEncodedBytes = O3DGC_MAX_ULONG;
+ unsigned long M = 1;
+ unsigned long bestM = 1;
+ while (M < 1024)
+ {
+ EncodeAC(num, dim, M, encodedBytes);
+ if (encodedBytes > bestEncodedBytes)
+ {
+ break;
+ }
+ bestM = M;
+ bestEncodedBytes = encodedBytes;
+ M *= 2;
+ }
+ EncodeAC(num, dim, bestM, encodedBytes);
+ for(unsigned long i = 0; i < encodedBytes; ++i)
+ {
+ bstream.WriteUChar8Bin(m_bufferAC[i]);
+ }
+ }
+ bstream.WriteUInt32(start, bstream.GetSize() - start, m_streamType);
+#ifdef DEBUG_VERBOSE
+ fclose(g_fileDebugDVEnc);
+#endif //DEBUG_VERBOSE
+ return O3DGC_OK;
+ }
+ O3DGCErrorCode DynamicVectorEncoder::Quantize(const Real * const floatArray,
+ unsigned long numFloatArray,
+ unsigned long dimFloatArray,
+ unsigned long stride,
+ const Real * const minFloatArray,
+ const Real * const maxFloatArray,
+ unsigned long nQBits)
+ {
+ const unsigned long size = numFloatArray * dimFloatArray;
+ Real r;
+ if (m_maxNumVectors < size)
+ {
+ delete [] m_quantVectors;
+ m_maxNumVectors = size;
+ m_quantVectors = new long [m_maxNumVectors];
+ }
+ Real delta;
+ for(unsigned long d = 0; d < dimFloatArray; ++d)
+ {
+ r = maxFloatArray[d] - minFloatArray[d];
+ if (r > 0.0f)
+ {
+ delta = (float)((1 << nQBits) - 1) / r;
+ }
+ else
+ {
+ delta = 1.0f;
+ }
+ for(unsigned long v = 0; v < numFloatArray; ++v)
+ {
+ m_quantVectors[v + d * numFloatArray] = (long)((floatArray[v * stride + d]-minFloatArray[d]) * delta + 0.5f);
+ }
+ }
+ return O3DGC_OK;
+ }
+}