/src/assimp/contrib/Open3DGC/o3dgcSC3DMCDecoder.inl
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc. |
3 | | |
4 | | Permission is hereby granted, free of charge, to any person obtaining a copy |
5 | | of this software and associated documentation files (the "Software"), to deal |
6 | | in the Software without restriction, including without limitation the rights |
7 | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
8 | | copies of the Software, and to permit persons to whom the Software is |
9 | | furnished to do so, subject to the following conditions: |
10 | | |
11 | | The above copyright notice and this permission notice shall be included in |
12 | | all copies or substantial portions of the Software. |
13 | | |
14 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
15 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
16 | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
17 | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
18 | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
19 | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
20 | | THE SOFTWARE. |
21 | | */ |
22 | | |
23 | | #pragma once |
24 | | #ifndef O3DGC_SC3DMC_DECODER_INL |
25 | | #define O3DGC_SC3DMC_DECODER_INL |
26 | | |
27 | | #include "o3dgcArithmeticCodec.h" |
28 | | #include "o3dgcTimer.h" |
29 | | |
30 | | #ifdef _MSC_VER |
31 | | # pragma warning(push) |
32 | | # pragma warning( disable : 4456) |
33 | | #endif // _MSC_VER |
34 | | |
35 | | //#define DEBUG_VERBOSE |
36 | | |
37 | | namespace o3dgc |
38 | | { |
39 | | #ifdef DEBUG_VERBOSE |
40 | | FILE * g_fileDebugSC3DMCDec = NULL; |
41 | | #endif //DEBUG_VERBOSE |
42 | | |
43 | | template<class T> |
44 | | O3DGCErrorCode SC3DMCDecoder<T>::DecodeHeader(IndexedFaceSet<T> & ifs, |
45 | | const BinaryStream & bstream) |
46 | 0 | { |
47 | 0 | unsigned long iterator0 = m_iterator; |
48 | 0 | unsigned long start_code = bstream.ReadUInt32(m_iterator, O3DGC_STREAM_TYPE_BINARY); |
49 | 0 | if (start_code != O3DGC_SC3DMC_START_CODE) |
50 | 0 | { |
51 | 0 | m_iterator = iterator0; |
52 | 0 | start_code = bstream.ReadUInt32(m_iterator, O3DGC_STREAM_TYPE_ASCII); |
53 | 0 | if (start_code != O3DGC_SC3DMC_START_CODE) |
54 | 0 | { |
55 | 0 | return O3DGC_ERROR_CORRUPTED_STREAM; |
56 | 0 | } |
57 | 0 | else |
58 | 0 | { |
59 | 0 | m_streamType = O3DGC_STREAM_TYPE_ASCII; |
60 | 0 | } |
61 | 0 | } |
62 | 0 | else |
63 | 0 | { |
64 | 0 | m_streamType = O3DGC_STREAM_TYPE_BINARY; |
65 | 0 | } |
66 | | |
67 | 0 | m_streamSize = bstream.ReadUInt32(m_iterator, m_streamType); |
68 | 0 | m_params.SetEncodeMode( (O3DGCSC3DMCEncodingMode) bstream.ReadUChar(m_iterator, m_streamType)); |
69 | |
|
70 | 0 | ifs.SetCreaseAngle((Real) bstream.ReadFloat32(m_iterator, m_streamType)); |
71 | | |
72 | 0 | unsigned char mask = bstream.ReadUChar(m_iterator, m_streamType); |
73 | |
|
74 | 0 | ifs.SetCCW ((mask & 1) == 1); |
75 | | // (mask & 2) == 1 |
76 | 0 | ifs.SetSolid (false); |
77 | | // (mask & 4) == 1 |
78 | 0 | ifs.SetConvex (false); |
79 | | // (mask & 8) == 1 |
80 | 0 | ifs.SetIsTriangularMesh(false); |
81 | | //bool markerBit0 = (mask & 16 ) == 1; |
82 | | //bool markerBit1 = (mask & 32 ) == 1; |
83 | | //bool markerBit2 = (mask & 64 ) == 1; |
84 | | //bool markerBit3 = (mask & 128) == 1; |
85 | | |
86 | 0 | ifs.SetNCoord (bstream.ReadUInt32(m_iterator, m_streamType)); |
87 | 0 | ifs.SetNNormal (bstream.ReadUInt32(m_iterator, m_streamType)); |
88 | | |
89 | |
|
90 | 0 | ifs.SetNumFloatAttributes(bstream.ReadUInt32(m_iterator, m_streamType)); |
91 | 0 | ifs.SetNumIntAttributes (bstream.ReadUInt32(m_iterator, m_streamType)); |
92 | | |
93 | 0 | if (ifs.GetNCoord() > 0) |
94 | 0 | { |
95 | 0 | ifs.SetNCoordIndex(bstream.ReadUInt32(m_iterator, m_streamType)); |
96 | 0 | for(int j=0 ; j<3 ; ++j) |
97 | 0 | { |
98 | 0 | ifs.SetCoordMin(j, (Real) bstream.ReadFloat32(m_iterator, m_streamType)); |
99 | 0 | ifs.SetCoordMax(j, (Real) bstream.ReadFloat32(m_iterator, m_streamType)); |
100 | 0 | } |
101 | 0 | m_params.SetCoordQuantBits( bstream.ReadUChar(m_iterator, m_streamType) ); |
102 | 0 | } |
103 | 0 | if (ifs.GetNNormal() > 0) |
104 | 0 | { |
105 | 0 | ifs.SetNNormalIndex(bstream.ReadUInt32(m_iterator, m_streamType)); |
106 | 0 | for(int j=0 ; j<3 ; ++j) |
107 | 0 | { |
108 | 0 | ifs.SetNormalMin(j, (Real) bstream.ReadFloat32(m_iterator, m_streamType)); |
109 | 0 | ifs.SetNormalMax(j, (Real) bstream.ReadFloat32(m_iterator, m_streamType)); |
110 | 0 | } |
111 | 0 | ifs.SetNormalPerVertex(bstream.ReadUChar(m_iterator, m_streamType) == 1); |
112 | 0 | m_params.SetNormalQuantBits(bstream.ReadUChar(m_iterator, m_streamType)); |
113 | 0 | } |
114 | |
|
115 | 0 | for(unsigned long a = 0; a < ifs.GetNumFloatAttributes(); ++a) |
116 | 0 | { |
117 | 0 | ifs.SetNFloatAttribute(a, bstream.ReadUInt32(m_iterator, m_streamType)); |
118 | 0 | if (ifs.GetNFloatAttribute(a) > 0) |
119 | 0 | { |
120 | 0 | ifs.SetNFloatAttributeIndex(a, bstream.ReadUInt32(m_iterator, m_streamType)); |
121 | 0 | unsigned char d = bstream.ReadUChar(m_iterator, m_streamType); |
122 | 0 | ifs.SetFloatAttributeDim(a, d); |
123 | 0 | for(unsigned char j = 0 ; j < d ; ++j) |
124 | 0 | { |
125 | 0 | ifs.SetFloatAttributeMin(a, j, (Real) bstream.ReadFloat32(m_iterator, m_streamType)); |
126 | 0 | ifs.SetFloatAttributeMax(a, j, (Real) bstream.ReadFloat32(m_iterator, m_streamType)); |
127 | 0 | } |
128 | 0 | ifs.SetFloatAttributePerVertex(a, bstream.ReadUChar(m_iterator, m_streamType) == 1); |
129 | 0 | ifs.SetFloatAttributeType(a, (O3DGCIFSFloatAttributeType) bstream.ReadUChar(m_iterator, m_streamType)); |
130 | 0 | m_params.SetFloatAttributeQuantBits(a, bstream.ReadUChar(m_iterator, m_streamType)); |
131 | 0 | } |
132 | 0 | } |
133 | 0 | for(unsigned long a = 0; a < ifs.GetNumIntAttributes(); ++a) |
134 | 0 | { |
135 | 0 | ifs.SetNIntAttribute(a, bstream.ReadUInt32(m_iterator, m_streamType)); |
136 | 0 | if (ifs.GetNIntAttribute(a) > 0) |
137 | 0 | { |
138 | 0 | ifs.SetNIntAttributeIndex(a, bstream.ReadUInt32(m_iterator, m_streamType)); |
139 | 0 | ifs.SetIntAttributeDim(a, bstream.ReadUChar(m_iterator, m_streamType)); |
140 | 0 | ifs.SetIntAttributePerVertex(a, bstream.ReadUChar(m_iterator, m_streamType) == 1); |
141 | 0 | ifs.SetIntAttributeType(a, (O3DGCIFSIntAttributeType) bstream.ReadUChar(m_iterator, m_streamType)); |
142 | 0 | } |
143 | 0 | } |
144 | 0 | return O3DGC_OK; |
145 | 0 | } |
146 | | template<class T> |
147 | | O3DGCErrorCode SC3DMCDecoder<T>::DecodePayload(IndexedFaceSet<T> & ifs, |
148 | | const BinaryStream & bstream) |
149 | 0 | { |
150 | 0 | O3DGCErrorCode ret = O3DGC_OK; |
151 | | #ifdef DEBUG_VERBOSE |
152 | | g_fileDebugSC3DMCDec = fopen("tfans_dec_main.txt", "w"); |
153 | | #endif //DEBUG_VERBOSE |
154 | |
|
155 | 0 | m_triangleListDecoder.SetStreamType(m_streamType); |
156 | 0 | m_stats.m_streamSizeCoordIndex = m_iterator; |
157 | 0 | Timer timer; |
158 | 0 | timer.Tic(); |
159 | 0 | m_triangleListDecoder.Decode(ifs.GetCoordIndex(), ifs.GetNCoordIndex(), ifs.GetNCoord(), bstream, m_iterator); |
160 | 0 | timer.Toc(); |
161 | 0 | m_stats.m_timeCoordIndex = timer.GetElapsedTime(); |
162 | 0 | m_stats.m_streamSizeCoordIndex = m_iterator - m_stats.m_streamSizeCoordIndex; |
163 | | |
164 | | // decode coord |
165 | 0 | m_stats.m_streamSizeCoord = m_iterator; |
166 | 0 | timer.Tic(); |
167 | 0 | if (ifs.GetNCoord() > 0) |
168 | 0 | { |
169 | 0 | ret = DecodeFloatArray(ifs.GetCoord(), ifs.GetNCoord(), 3, 3, ifs.GetCoordMin(), ifs.GetCoordMax(), |
170 | 0 | m_params.GetCoordQuantBits(), ifs, m_params.GetCoordPredMode(), bstream); |
171 | 0 | } |
172 | 0 | if (ret != O3DGC_OK) |
173 | 0 | { |
174 | 0 | return ret; |
175 | 0 | } |
176 | 0 | timer.Toc(); |
177 | 0 | m_stats.m_timeCoord = timer.GetElapsedTime(); |
178 | 0 | m_stats.m_streamSizeCoord = m_iterator - m_stats.m_streamSizeCoord; |
179 | | |
180 | | // decode Normal |
181 | 0 | m_stats.m_streamSizeNormal = m_iterator; |
182 | 0 | timer.Tic(); |
183 | 0 | if (ifs.GetNNormal() > 0) |
184 | 0 | { |
185 | 0 | DecodeFloatArray(ifs.GetNormal(), ifs.GetNNormal(), 3, 3, ifs.GetNormalMin(), ifs.GetNormalMax(), |
186 | 0 | m_params.GetNormalQuantBits(), ifs, m_params.GetNormalPredMode(), bstream); |
187 | 0 | } |
188 | 0 | if (ret != O3DGC_OK) |
189 | 0 | { |
190 | 0 | return ret; |
191 | 0 | } |
192 | 0 | timer.Toc(); |
193 | 0 | m_stats.m_timeNormal = timer.GetElapsedTime(); |
194 | 0 | m_stats.m_streamSizeNormal = m_iterator - m_stats.m_streamSizeNormal; |
195 | | |
196 | | // decode FloatAttributes |
197 | 0 | for(unsigned long a = 0; a < ifs.GetNumFloatAttributes(); ++a) |
198 | 0 | { |
199 | 0 | m_stats.m_streamSizeFloatAttribute[a] = m_iterator; |
200 | 0 | timer.Tic(); |
201 | 0 | DecodeFloatArray(ifs.GetFloatAttribute(a), ifs.GetNFloatAttribute(a), ifs.GetFloatAttributeDim(a), ifs.GetFloatAttributeDim(a), |
202 | 0 | ifs.GetFloatAttributeMin(a), ifs.GetFloatAttributeMax(a), |
203 | 0 | m_params.GetFloatAttributeQuantBits(a), ifs, m_params.GetFloatAttributePredMode(a), bstream); |
204 | 0 | timer.Toc(); |
205 | 0 | m_stats.m_timeFloatAttribute[a] = timer.GetElapsedTime(); |
206 | 0 | m_stats.m_streamSizeFloatAttribute[a] = m_iterator - m_stats.m_streamSizeFloatAttribute[a]; |
207 | 0 | } |
208 | 0 | if (ret != O3DGC_OK) |
209 | 0 | { |
210 | 0 | return ret; |
211 | 0 | } |
212 | | |
213 | | // decode IntAttributes |
214 | 0 | for(unsigned long a = 0; a < ifs.GetNumIntAttributes(); ++a) |
215 | 0 | { |
216 | 0 | m_stats.m_streamSizeIntAttribute[a] = m_iterator; |
217 | 0 | timer.Tic(); |
218 | 0 | DecodeIntArray(ifs.GetIntAttribute(a), ifs.GetNIntAttribute(a), ifs.GetIntAttributeDim(a), ifs.GetIntAttributeDim(a), |
219 | 0 | ifs, m_params.GetIntAttributePredMode(a), bstream); |
220 | 0 | timer.Toc(); |
221 | 0 | m_stats.m_timeIntAttribute[a] = timer.GetElapsedTime(); |
222 | 0 | m_stats.m_streamSizeIntAttribute[a] = m_iterator - m_stats.m_streamSizeIntAttribute[a]; |
223 | 0 | } |
224 | 0 | if (ret != O3DGC_OK) |
225 | 0 | { |
226 | 0 | return ret; |
227 | 0 | } |
228 | | |
229 | 0 | timer.Tic(); |
230 | 0 | m_triangleListDecoder.Reorder(); |
231 | 0 | timer.Toc(); |
232 | 0 | m_stats.m_timeReorder = timer.GetElapsedTime(); |
233 | |
|
234 | | #ifdef DEBUG_VERBOSE |
235 | | fclose(g_fileDebugSC3DMCDec); |
236 | | #endif //DEBUG_VERBOSE |
237 | 0 | return ret; |
238 | 0 | } |
239 | | template<class T> |
240 | | O3DGCErrorCode SC3DMCDecoder<T>::DecodeIntArray(long * const intArray, |
241 | | unsigned long numIntArray, |
242 | | unsigned long dimIntArray, |
243 | | unsigned long stride, |
244 | | const IndexedFaceSet<T> & ifs, |
245 | | O3DGCSC3DMCPredictionMode & predMode, |
246 | | const BinaryStream & bstream) |
247 | 0 | { |
248 | 0 | assert(dimIntArray < O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES); |
249 | 0 | long predResidual; |
250 | 0 | SC3DMCPredictor m_neighbors [O3DGC_SC3DMC_MAX_PREDICTION_NEIGHBORS]; |
251 | 0 | Arithmetic_Codec acd; |
252 | 0 | Static_Bit_Model bModel0; |
253 | 0 | Adaptive_Bit_Model bModel1; |
254 | 0 | Adaptive_Data_Model mModelPreds(O3DGC_SC3DMC_MAX_PREDICTION_NEIGHBORS+1); |
255 | 0 | unsigned long nPred; |
256 | |
|
257 | 0 | const AdjacencyInfo & v2T = m_triangleListDecoder.GetVertexToTriangle(); |
258 | 0 | const T * const triangles = ifs.GetCoordIndex(); |
259 | 0 | const long nvert = (long) numIntArray; |
260 | 0 | unsigned char * buffer = 0; |
261 | 0 | unsigned long start = m_iterator; |
262 | 0 | unsigned long streamSize = bstream.ReadUInt32(m_iterator, m_streamType); // bitsream size |
263 | 0 | unsigned char mask = bstream.ReadUChar(m_iterator, m_streamType); |
264 | 0 | O3DGCSC3DMCBinarization binarization = (O3DGCSC3DMCBinarization)((mask >> 4) & 7); |
265 | 0 | predMode = (O3DGCSC3DMCPredictionMode)(mask & 7); |
266 | 0 | streamSize -= (m_iterator - start); |
267 | 0 | unsigned long iteratorPred = m_iterator + streamSize; |
268 | 0 | unsigned int exp_k = 0; |
269 | 0 | unsigned int M = 0; |
270 | 0 | if (m_streamType != O3DGC_STREAM_TYPE_ASCII) |
271 | 0 | { |
272 | 0 | if (binarization != O3DGC_SC3DMC_BINARIZATION_AC_EGC) |
273 | 0 | { |
274 | 0 | return O3DGC_ERROR_CORRUPTED_STREAM; |
275 | 0 | } |
276 | 0 | bstream.GetBuffer(m_iterator, buffer); |
277 | 0 | m_iterator += streamSize; |
278 | 0 | acd.set_buffer(streamSize, buffer); |
279 | 0 | acd.start_decoder(); |
280 | 0 | exp_k = acd.ExpGolombDecode(0, bModel0, bModel1); |
281 | 0 | M = acd.ExpGolombDecode(0, bModel0, bModel1); |
282 | 0 | } |
283 | 0 | else |
284 | 0 | { |
285 | 0 | if (binarization != O3DGC_SC3DMC_BINARIZATION_ASCII) |
286 | 0 | { |
287 | 0 | return O3DGC_ERROR_CORRUPTED_STREAM; |
288 | 0 | } |
289 | 0 | bstream.ReadUInt32(iteratorPred, m_streamType); // predictors bitsream size |
290 | 0 | } |
291 | 0 | Adaptive_Data_Model mModelValues(M+2); |
292 | |
|
293 | | #ifdef DEBUG_VERBOSE |
294 | | printf("IntArray (%i, %i)\n", numIntArray, dimIntArray); |
295 | | fprintf(g_fileDebugSC3DMCDec, "IntArray (%i, %i)\n", numIntArray, dimIntArray); |
296 | | #endif //DEBUG_VERBOSE |
297 | |
|
298 | 0 | for (long v=0; v < nvert; ++v) |
299 | 0 | { |
300 | 0 | nPred = 0; |
301 | 0 | if ( v2T.GetNumNeighbors(v) > 0 && |
302 | 0 | predMode != O3DGC_SC3DMC_NO_PREDICTION) |
303 | 0 | { |
304 | 0 | int u0 = v2T.Begin(v); |
305 | 0 | int u1 = v2T.End(v); |
306 | 0 | for (long u = u0; u < u1; u++) |
307 | 0 | { |
308 | 0 | long ta = v2T.GetNeighbor(u); |
309 | 0 | if (ta < 0) |
310 | 0 | { |
311 | 0 | break; |
312 | 0 | } |
313 | 0 | for(long k = 0; k < 3; ++k) |
314 | 0 | { |
315 | 0 | long w = triangles[ta*3 + k]; |
316 | 0 | if ( w < v ) |
317 | 0 | { |
318 | 0 | SC3DMCTriplet id = {-1, -1, w}; |
319 | 0 | unsigned long p = Insert(id, nPred, m_neighbors); |
320 | 0 | if (p != 0xFFFFFFFF) |
321 | 0 | { |
322 | 0 | for (unsigned long i = 0; i < dimIntArray; i++) |
323 | 0 | { |
324 | 0 | m_neighbors[p].m_pred[i] = intArray[w*stride+i]; |
325 | 0 | } |
326 | 0 | } |
327 | 0 | } |
328 | 0 | } |
329 | 0 | } |
330 | 0 | } |
331 | 0 | if (nPred > 1) |
332 | 0 | { |
333 | | #ifdef DEBUG_VERBOSE1 |
334 | | printf("\t\t vm %i\n", v); |
335 | | fprintf(g_fileDebugSC3DMCDec, "\t\t vm %i\n", v); |
336 | | for (unsigned long p = 0; p < nPred; ++p) |
337 | | { |
338 | | printf("\t\t pred a = %i b = %i c = %i \n", m_neighbors[p].m_id.m_a, m_neighbors[p].m_id.m_b, m_neighbors[p].m_id.m_c); |
339 | | fprintf(g_fileDebugSC3DMCDec, "\t\t pred a = %i b = %i c = %i \n", m_neighbors[p].m_id.m_a, m_neighbors[p].m_id.m_b, m_neighbors[p].m_id.m_c); |
340 | | for (unsigned long i = 0; i < dimIntArray; ++i) |
341 | | { |
342 | | printf("\t\t\t %i\n", m_neighbors[p].m_pred[i]); |
343 | | fprintf(g_fileDebugSC3DMCDec, "\t\t\t %i\n", m_neighbors[p].m_pred[i]); |
344 | | } |
345 | | } |
346 | | #endif //DEBUG_VERBOSE |
347 | 0 | unsigned long bestPred; |
348 | 0 | if (m_streamType == O3DGC_STREAM_TYPE_ASCII) |
349 | 0 | { |
350 | 0 | bestPred = bstream.ReadUCharASCII(iteratorPred); |
351 | 0 | } |
352 | 0 | else |
353 | 0 | { |
354 | 0 | bestPred = acd.decode(mModelPreds); |
355 | 0 | } |
356 | | #ifdef DEBUG_VERBOSE1 |
357 | | printf("best (%i, %i, %i) \t pos %i\n", m_neighbors[bestPred].m_id.m_a, m_neighbors[bestPred].m_id.m_b, m_neighbors[bestPred].m_id.m_c, bestPred); |
358 | | fprintf(g_fileDebugSC3DMCDec, "best (%i, %i, %i) \t pos %i\n", m_neighbors[bestPred].m_id.m_a, m_neighbors[bestPred].m_id.m_b, m_neighbors[bestPred].m_id.m_c, bestPred); |
359 | | #endif //DEBUG_VERBOSE |
360 | 0 | for (unsigned long i = 0; i < dimIntArray; i++) |
361 | 0 | { |
362 | 0 | if (m_streamType == O3DGC_STREAM_TYPE_ASCII) |
363 | 0 | { |
364 | 0 | predResidual = bstream.ReadIntASCII(m_iterator); |
365 | 0 | } |
366 | 0 | else |
367 | 0 | { |
368 | 0 | predResidual = DecodeIntACEGC(acd, mModelValues, bModel0, bModel1, exp_k, M); |
369 | 0 | } |
370 | 0 | intArray[v*stride+i] = predResidual + m_neighbors[bestPred].m_pred[i]; |
371 | | #ifdef DEBUG_VERBOSE |
372 | | printf("%i \t %i \t [%i]\n", v*dimIntArray+i, predResidual, m_neighbors[bestPred].m_pred[i]); |
373 | | fprintf(g_fileDebugSC3DMCDec, "%i \t %i \t [%i]\n", v*dimIntArray+i, predResidual, m_neighbors[bestPred].m_pred[i]); |
374 | | #endif //DEBUG_VERBOSE |
375 | 0 | } |
376 | 0 | } |
377 | 0 | else if (v > 0 && predMode != O3DGC_SC3DMC_NO_PREDICTION) |
378 | 0 | { |
379 | 0 | for (unsigned long i = 0; i < dimIntArray; i++) |
380 | 0 | { |
381 | 0 | if (m_streamType == O3DGC_STREAM_TYPE_ASCII) |
382 | 0 | { |
383 | 0 | predResidual = bstream.ReadIntASCII(m_iterator); |
384 | 0 | } |
385 | 0 | else |
386 | 0 | { |
387 | 0 | predResidual = DecodeIntACEGC(acd, mModelValues, bModel0, bModel1, exp_k, M); |
388 | 0 | } |
389 | 0 | intArray[v*stride+i] = predResidual + intArray[(v-1)*stride+i]; |
390 | | #ifdef DEBUG_VERBOSE |
391 | | printf("%i \t %i\n", v*dimIntArray+i, predResidual); |
392 | | fprintf(g_fileDebugSC3DMCDec, "%i \t %i\n", v*dimIntArray+i, predResidual); |
393 | | #endif //DEBUG_VERBOSE |
394 | 0 | } |
395 | 0 | } |
396 | 0 | else |
397 | 0 | { |
398 | 0 | for (unsigned long i = 0; i < dimIntArray; i++) |
399 | 0 | { |
400 | 0 | if (m_streamType == O3DGC_STREAM_TYPE_ASCII) |
401 | 0 | { |
402 | 0 | predResidual = bstream.ReadUIntASCII(m_iterator); |
403 | 0 | } |
404 | 0 | else |
405 | 0 | { |
406 | 0 | predResidual = DecodeUIntACEGC(acd, mModelValues, bModel0, bModel1, exp_k, M); |
407 | 0 | } |
408 | 0 | intArray[v*stride+i] = predResidual; |
409 | | #ifdef DEBUG_VERBOSE |
410 | | printf("%i \t %i\n", v*dimIntArray+i, predResidual); |
411 | | fprintf(g_fileDebugSC3DMCDec, "%i \t %i\n", v*dimIntArray+i, predResidual); |
412 | | #endif //DEBUG_VERBOSE |
413 | 0 | } |
414 | 0 | } |
415 | 0 | } |
416 | 0 | m_iterator = iteratorPred; |
417 | | #ifdef DEBUG_VERBOSE |
418 | | fflush(g_fileDebugSC3DMCDec); |
419 | | #endif //DEBUG_VERBOSE |
420 | 0 | return O3DGC_OK; |
421 | 0 | } |
422 | | template <class T> |
423 | | O3DGCErrorCode SC3DMCDecoder<T>::ProcessNormals(const IndexedFaceSet<T> & ifs) |
424 | 0 | { |
425 | 0 | const long nvert = (long) ifs.GetNNormal(); |
426 | 0 | const unsigned long normalSize = ifs.GetNNormal() * 2; |
427 | 0 | if (m_normalsSize < normalSize) |
428 | 0 | { |
429 | 0 | delete [] m_normals; |
430 | 0 | m_normalsSize = normalSize; |
431 | 0 | m_normals = new Real [normalSize]; |
432 | 0 | } |
433 | 0 | const AdjacencyInfo & v2T = m_triangleListDecoder.GetVertexToTriangle(); |
434 | 0 | const T * const triangles = ifs.GetCoordIndex(); |
435 | 0 | Vec3<long> p1, p2, p3, n0, nt; |
436 | 0 | long na0 = 0, nb0 = 0; |
437 | 0 | Real rna0, rnb0, norm0; |
438 | 0 | char ni0 = 0, ni1 = 0; |
439 | 0 | long a, b, c; |
440 | 0 | for (long v=0; v < nvert; ++v) |
441 | 0 | { |
442 | 0 | n0.X() = 0; |
443 | 0 | n0.Y() = 0; |
444 | 0 | n0.Z() = 0; |
445 | 0 | int u0 = v2T.Begin(v); |
446 | 0 | int u1 = v2T.End(v); |
447 | 0 | for (long u = u0; u < u1; u++) |
448 | 0 | { |
449 | 0 | long ta = v2T.GetNeighbor(u); |
450 | 0 | if (ta == -1) |
451 | 0 | { |
452 | 0 | break; |
453 | 0 | } |
454 | 0 | a = triangles[ta*3 + 0]; |
455 | 0 | b = triangles[ta*3 + 1]; |
456 | 0 | c = triangles[ta*3 + 2]; |
457 | 0 | p1.X() = m_quantFloatArray[3*a]; |
458 | 0 | p1.Y() = m_quantFloatArray[3*a+1]; |
459 | 0 | p1.Z() = m_quantFloatArray[3*a+2]; |
460 | 0 | p2.X() = m_quantFloatArray[3*b]; |
461 | 0 | p2.Y() = m_quantFloatArray[3*b+1]; |
462 | 0 | p2.Z() = m_quantFloatArray[3*b+2]; |
463 | 0 | p3.X() = m_quantFloatArray[3*c]; |
464 | 0 | p3.Y() = m_quantFloatArray[3*c+1]; |
465 | 0 | p3.Z() = m_quantFloatArray[3*c+2]; |
466 | 0 | nt = (p2-p1)^(p3-p1); |
467 | 0 | n0 += nt; |
468 | 0 | } |
469 | 0 | norm0 = (Real) n0.GetNorm(); |
470 | 0 | if (norm0 == 0.0) |
471 | 0 | { |
472 | 0 | norm0 = 1.0; |
473 | 0 | } |
474 | 0 | SphereToCube(n0.X(), n0.Y(), n0.Z(), na0, nb0, ni0); |
475 | | |
476 | |
|
477 | 0 | rna0 = na0 / norm0; |
478 | 0 | rnb0 = nb0 / norm0; |
479 | 0 | ni1 = ni0 + m_orientation[v]; |
480 | 0 | m_orientation[v] = ni1; |
481 | 0 | if ( (ni1 >> 1) != (ni0 >> 1) ) |
482 | 0 | { |
483 | 0 | rna0 = Real(0.0); |
484 | 0 | rnb0 = Real(0.0); |
485 | 0 | } |
486 | 0 | m_normals[2*v] = rna0; |
487 | 0 | m_normals[2*v+1] = rnb0; |
488 | |
|
489 | | #ifdef DEBUG_VERBOSE1 |
490 | | printf("n0 \t %i \t %i \t %i \t %i (%f, %f)\n", v, n0.X(), n0.Y(), n0.Z(), rna0, rnb0); |
491 | | fprintf(g_fileDebugSC3DMCDec, "n0 \t %i \t %i \t %i \t %i (%f, %f)\n", v, n0.X(), n0.Y(), n0.Z(), rna0, rnb0); |
492 | | #endif //DEBUG_VERBOSE |
493 | |
|
494 | 0 | } |
495 | 0 | return O3DGC_OK; |
496 | 0 | } |
497 | | template<class T> |
498 | | O3DGCErrorCode SC3DMCDecoder<T>::DecodeFloatArray(Real * const floatArray, |
499 | | unsigned long numFloatArray, |
500 | | unsigned long dimFloatArray, |
501 | | unsigned long stride, |
502 | | const Real * const minFloatArray, |
503 | | const Real * const maxFloatArray, |
504 | | unsigned long nQBits, |
505 | | const IndexedFaceSet<T> & ifs, |
506 | | O3DGCSC3DMCPredictionMode & predMode, |
507 | | const BinaryStream & bstream) |
508 | 0 | { |
509 | 0 | assert(dimFloatArray < O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES); |
510 | 0 | long predResidual; |
511 | 0 | SC3DMCPredictor m_neighbors [O3DGC_SC3DMC_MAX_PREDICTION_NEIGHBORS]; |
512 | 0 | Arithmetic_Codec acd; |
513 | 0 | Static_Bit_Model bModel0; |
514 | 0 | Adaptive_Bit_Model bModel1; |
515 | 0 | Adaptive_Data_Model mModelPreds(O3DGC_SC3DMC_MAX_PREDICTION_NEIGHBORS+1); |
516 | 0 | unsigned long nPred; |
517 | |
|
518 | 0 | const AdjacencyInfo & v2T = m_triangleListDecoder.GetVertexToTriangle(); |
519 | 0 | const T * const triangles = ifs.GetCoordIndex(); |
520 | 0 | const long nvert = (long) numFloatArray; |
521 | 0 | const unsigned long size = numFloatArray * dimFloatArray; |
522 | 0 | unsigned char * buffer = 0; |
523 | 0 | unsigned long start = m_iterator; |
524 | 0 | unsigned long streamSize = bstream.ReadUInt32(m_iterator, m_streamType); // bitsream size |
525 | 0 | unsigned char mask = bstream.ReadUChar(m_iterator, m_streamType); |
526 | 0 | O3DGCSC3DMCBinarization binarization = (O3DGCSC3DMCBinarization)((mask >> 4) & 7); |
527 | 0 | predMode = (O3DGCSC3DMCPredictionMode)(mask & 7); |
528 | 0 | streamSize -= (m_iterator - start); |
529 | 0 | unsigned long iteratorPred = m_iterator + streamSize; |
530 | 0 | unsigned int exp_k = 0; |
531 | 0 | unsigned int M = 0; |
532 | 0 | if (m_streamType != O3DGC_STREAM_TYPE_ASCII) |
533 | 0 | { |
534 | 0 | if (binarization != O3DGC_SC3DMC_BINARIZATION_AC_EGC) |
535 | 0 | { |
536 | 0 | return O3DGC_ERROR_CORRUPTED_STREAM; |
537 | 0 | } |
538 | 0 | bstream.GetBuffer(m_iterator, buffer); |
539 | 0 | m_iterator += streamSize; |
540 | 0 | acd.set_buffer(streamSize, buffer); |
541 | 0 | acd.start_decoder(); |
542 | 0 | exp_k = acd.ExpGolombDecode(0, bModel0, bModel1); |
543 | 0 | M = acd.ExpGolombDecode(0, bModel0, bModel1); |
544 | 0 | } |
545 | 0 | else |
546 | 0 | { |
547 | 0 | if (binarization != O3DGC_SC3DMC_BINARIZATION_ASCII) |
548 | 0 | { |
549 | 0 | return O3DGC_ERROR_CORRUPTED_STREAM; |
550 | 0 | } |
551 | 0 | bstream.ReadUInt32(iteratorPred, m_streamType); // predictors bitsream size |
552 | 0 | } |
553 | 0 | Adaptive_Data_Model mModelValues(M+2); |
554 | | |
555 | |
|
556 | 0 | if (predMode == O3DGC_SC3DMC_SURF_NORMALS_PREDICTION) |
557 | 0 | { |
558 | 0 | m_orientation.Allocate(size); |
559 | 0 | m_orientation.Clear(); |
560 | 0 | if (m_streamType == O3DGC_STREAM_TYPE_ASCII) |
561 | 0 | { |
562 | 0 | for(unsigned long i = 0; i < numFloatArray; ++i) |
563 | 0 | { |
564 | 0 | m_orientation.PushBack((unsigned char) bstream.ReadIntASCII(m_iterator)); |
565 | 0 | } |
566 | 0 | } |
567 | 0 | else |
568 | 0 | { |
569 | 0 | Adaptive_Data_Model dModel(12); |
570 | 0 | for(unsigned long i = 0; i < numFloatArray; ++i) |
571 | 0 | { |
572 | 0 | m_orientation.PushBack((unsigned char) UIntToInt(acd.decode(dModel))); |
573 | 0 | } |
574 | 0 | } |
575 | 0 | ProcessNormals(ifs); |
576 | 0 | dimFloatArray = 2; |
577 | 0 | } |
578 | | #ifdef DEBUG_VERBOSE |
579 | | printf("FloatArray (%i, %i)\n", numFloatArray, dimFloatArray); |
580 | | fprintf(g_fileDebugSC3DMCDec, "FloatArray (%i, %i)\n", numFloatArray, dimFloatArray); |
581 | | #endif //DEBUG_VERBOSE |
582 | |
|
583 | 0 | if (m_quantFloatArraySize < size) |
584 | 0 | { |
585 | 0 | delete [] m_quantFloatArray; |
586 | 0 | m_quantFloatArraySize = size; |
587 | 0 | m_quantFloatArray = new long [size]; |
588 | 0 | } |
589 | 0 | for (long v=0; v < nvert; ++v) |
590 | 0 | { |
591 | 0 | nPred = 0; |
592 | 0 | if ( v2T.GetNumNeighbors(v) > 0 && |
593 | 0 | predMode != O3DGC_SC3DMC_NO_PREDICTION) |
594 | 0 | { |
595 | 0 | int u0 = v2T.Begin(v); |
596 | 0 | int u1 = v2T.End(v); |
597 | 0 | for (long u = u0; u < u1; u++) |
598 | 0 | { |
599 | 0 | long ta = v2T.GetNeighbor(u); |
600 | 0 | if (ta < 0) |
601 | 0 | { |
602 | 0 | break; |
603 | 0 | } |
604 | 0 | if (predMode == O3DGC_SC3DMC_PARALLELOGRAM_PREDICTION) |
605 | 0 | { |
606 | 0 | long a,b; |
607 | 0 | if ((long) triangles[ta*3] == v) |
608 | 0 | { |
609 | 0 | a = triangles[ta*3 + 1]; |
610 | 0 | b = triangles[ta*3 + 2]; |
611 | 0 | } |
612 | 0 | else if ((long)triangles[ta*3 + 1] == v) |
613 | 0 | { |
614 | 0 | a = triangles[ta*3 + 0]; |
615 | 0 | b = triangles[ta*3 + 2]; |
616 | 0 | } |
617 | 0 | else |
618 | 0 | { |
619 | 0 | a = triangles[ta*3 + 0]; |
620 | 0 | b = triangles[ta*3 + 1]; |
621 | 0 | } |
622 | 0 | if ( a < v && b < v) |
623 | 0 | { |
624 | 0 | int u0 = v2T.Begin(a); |
625 | 0 | int u1 = v2T.End(a); |
626 | 0 | for (long u = u0; u < u1; u++) |
627 | 0 | { |
628 | 0 | long tb = v2T.GetNeighbor(u); |
629 | 0 | if (tb < 0) |
630 | 0 | { |
631 | 0 | break; |
632 | 0 | } |
633 | 0 | long c = -1; |
634 | 0 | bool foundB = false; |
635 | 0 | for(long k = 0; k < 3; ++k) |
636 | 0 | { |
637 | 0 | long x = triangles[tb*3 + k]; |
638 | 0 | if (x == b) |
639 | 0 | { |
640 | 0 | foundB = true; |
641 | 0 | } |
642 | 0 | if (x < v && x != a && x != b) |
643 | 0 | { |
644 | 0 | c = x; |
645 | 0 | } |
646 | 0 | } |
647 | 0 | if (c != -1 && foundB) |
648 | 0 | { |
649 | 0 | SC3DMCTriplet id = {min(a, b), max(a, b), -c-1}; |
650 | 0 | unsigned long p = Insert(id, nPred, m_neighbors); |
651 | 0 | if (p != 0xFFFFFFFF) |
652 | 0 | { |
653 | 0 | for (unsigned long i = 0; i < dimFloatArray; i++) |
654 | 0 | { |
655 | 0 | m_neighbors[p].m_pred[i] = m_quantFloatArray[a*stride+i] + |
656 | 0 | m_quantFloatArray[b*stride+i] - |
657 | 0 | m_quantFloatArray[c*stride+i]; |
658 | 0 | } |
659 | 0 | } |
660 | 0 | } |
661 | 0 | } |
662 | 0 | } |
663 | 0 | } |
664 | 0 | if ( predMode == O3DGC_SC3DMC_SURF_NORMALS_PREDICTION || |
665 | 0 | predMode == O3DGC_SC3DMC_PARALLELOGRAM_PREDICTION || |
666 | 0 | predMode == O3DGC_SC3DMC_DIFFERENTIAL_PREDICTION ) |
667 | 0 | { |
668 | 0 | for(long k = 0; k < 3; ++k) |
669 | 0 | { |
670 | 0 | long w = triangles[ta*3 + k]; |
671 | 0 | if ( w < v ) |
672 | 0 | { |
673 | 0 | SC3DMCTriplet id = {-1, -1, w}; |
674 | 0 | unsigned long p = Insert(id, nPred, m_neighbors); |
675 | 0 | if (p != 0xFFFFFFFF) |
676 | 0 | { |
677 | 0 | for (unsigned long i = 0; i < dimFloatArray; i++) |
678 | 0 | { |
679 | 0 | m_neighbors[p].m_pred[i] = m_quantFloatArray[w*stride+i]; |
680 | 0 | } |
681 | 0 | } |
682 | 0 | } |
683 | 0 | } |
684 | 0 | } |
685 | 0 | } |
686 | 0 | } |
687 | 0 | if (nPred > 1) |
688 | 0 | { |
689 | | #ifdef DEBUG_VERBOSE1 |
690 | | printf("\t\t vm %i\n", v); |
691 | | fprintf(g_fileDebugSC3DMCDec, "\t\t vm %i\n", v); |
692 | | for (unsigned long p = 0; p < nPred; ++p) |
693 | | { |
694 | | printf("\t\t pred a = %i b = %i c = %i \n", m_neighbors[p].m_id.m_a, m_neighbors[p].m_id.m_b, m_neighbors[p].m_id.m_c); |
695 | | fprintf(g_fileDebugSC3DMCDec, "\t\t pred a = %i b = %i c = %i \n", m_neighbors[p].m_id.m_a, m_neighbors[p].m_id.m_b, m_neighbors[p].m_id.m_c); |
696 | | for (unsigned long i = 0; i < dimFloatArray; ++i) |
697 | | { |
698 | | printf("\t\t\t %i\n", m_neighbors[p].m_pred[i]); |
699 | | fprintf(g_fileDebugSC3DMCDec, "\t\t\t %i\n", m_neighbors[p].m_pred[i]); |
700 | | } |
701 | | } |
702 | | #endif //DEBUG_VERBOSE |
703 | 0 | unsigned long bestPred; |
704 | 0 | if (m_streamType == O3DGC_STREAM_TYPE_ASCII) |
705 | 0 | { |
706 | 0 | bestPred = bstream.ReadUCharASCII(iteratorPred); |
707 | 0 | } |
708 | 0 | else |
709 | 0 | { |
710 | 0 | bestPred = acd.decode(mModelPreds); |
711 | 0 | } |
712 | | #ifdef DEBUG_VERBOSE1 |
713 | | printf("best (%i, %i, %i) \t pos %i\n", m_neighbors[bestPred].m_id.m_a, m_neighbors[bestPred].m_id.m_b, m_neighbors[bestPred].m_id.m_c, bestPred); |
714 | | fprintf(g_fileDebugSC3DMCDec, "best (%i, %i, %i) \t pos %i\n", m_neighbors[bestPred].m_id.m_a, m_neighbors[bestPred].m_id.m_b, m_neighbors[bestPred].m_id.m_c, bestPred); |
715 | | #endif //DEBUG_VERBOSE |
716 | 0 | for (unsigned long i = 0; i < dimFloatArray; i++) |
717 | 0 | { |
718 | 0 | if (m_streamType == O3DGC_STREAM_TYPE_ASCII) |
719 | 0 | { |
720 | 0 | predResidual = bstream.ReadIntASCII(m_iterator); |
721 | 0 | } |
722 | 0 | else |
723 | 0 | { |
724 | 0 | predResidual = DecodeIntACEGC(acd, mModelValues, bModel0, bModel1, exp_k, M); |
725 | 0 | } |
726 | 0 | m_quantFloatArray[v*stride+i] = predResidual + m_neighbors[bestPred].m_pred[i]; |
727 | | #ifdef DEBUG_VERBOSE |
728 | | printf("%i \t %i \t [%i]\n", v*dimFloatArray+i, predResidual, m_neighbors[bestPred].m_pred[i]); |
729 | | fprintf(g_fileDebugSC3DMCDec, "%i \t %i \t [%i]\n", v*dimFloatArray+i, predResidual, m_neighbors[bestPred].m_pred[i]); |
730 | | #endif //DEBUG_VERBOSE |
731 | 0 | } |
732 | 0 | } |
733 | 0 | else if (v > 0 && predMode != O3DGC_SC3DMC_NO_PREDICTION) |
734 | 0 | { |
735 | 0 | for (unsigned long i = 0; i < dimFloatArray; i++) |
736 | 0 | { |
737 | 0 | if (m_streamType == O3DGC_STREAM_TYPE_ASCII) |
738 | 0 | { |
739 | 0 | predResidual = bstream.ReadIntASCII(m_iterator); |
740 | 0 | } |
741 | 0 | else |
742 | 0 | { |
743 | 0 | predResidual = DecodeIntACEGC(acd, mModelValues, bModel0, bModel1, exp_k, M); |
744 | 0 | } |
745 | 0 | m_quantFloatArray[v*stride+i] = predResidual + m_quantFloatArray[(v-1)*stride+i]; |
746 | | #ifdef DEBUG_VERBOSE |
747 | | printf("%i \t %i\n", v*dimFloatArray+i, predResidual); |
748 | | fprintf(g_fileDebugSC3DMCDec, "%i \t %i\n", v*dimFloatArray+i, predResidual); |
749 | | #endif //DEBUG_VERBOSE |
750 | 0 | } |
751 | 0 | } |
752 | 0 | else |
753 | 0 | { |
754 | 0 | for (unsigned long i = 0; i < dimFloatArray; i++) |
755 | 0 | { |
756 | 0 | if (m_streamType == O3DGC_STREAM_TYPE_ASCII) |
757 | 0 | { |
758 | 0 | predResidual = bstream.ReadUIntASCII(m_iterator); |
759 | 0 | } |
760 | 0 | else |
761 | 0 | { |
762 | 0 | predResidual = DecodeUIntACEGC(acd, mModelValues, bModel0, bModel1, exp_k, M); |
763 | 0 | } |
764 | 0 | m_quantFloatArray[v*stride+i] = predResidual; |
765 | | #ifdef DEBUG_VERBOSE |
766 | | printf("%i \t %i\n", v*dimFloatArray+i, predResidual); |
767 | | fprintf(g_fileDebugSC3DMCDec, "%i \t %i\n", v*dimFloatArray+i, predResidual); |
768 | | #endif //DEBUG_VERBOSE |
769 | 0 | } |
770 | 0 | } |
771 | 0 | } |
772 | 0 | m_iterator = iteratorPred; |
773 | 0 | if (predMode == O3DGC_SC3DMC_SURF_NORMALS_PREDICTION) |
774 | 0 | { |
775 | 0 | const Real minNormal[2] = {(Real)(-2),(Real)(-2)}; |
776 | 0 | const Real maxNormal[2] = {(Real)(2),(Real)(2)}; |
777 | 0 | Real na1, nb1; |
778 | 0 | Real na0, nb0; |
779 | 0 | char ni1; |
780 | 0 | IQuantizeFloatArray(floatArray, numFloatArray, dimFloatArray, stride, minNormal, maxNormal, nQBits+1); |
781 | 0 | for (long v=0; v < nvert; ++v) |
782 | 0 | { |
783 | 0 | na0 = m_normals[2*v]; |
784 | 0 | nb0 = m_normals[2*v+1]; |
785 | 0 | na1 = floatArray[stride*v] + na0; |
786 | 0 | nb1 = floatArray[stride*v+1] + nb0; |
787 | 0 | ni1 = m_orientation[v]; |
788 | |
|
789 | 0 | CubeToSphere(na1, nb1, ni1, |
790 | 0 | floatArray[stride*v], |
791 | 0 | floatArray[stride*v+1], |
792 | 0 | floatArray[stride*v+2]); |
793 | |
|
794 | | #ifdef DEBUG_VERBOSE1 |
795 | | printf("normal \t %i \t %f \t %f \t %f \t (%i, %f, %f) \t (%f, %f)\n", |
796 | | v, |
797 | | floatArray[stride*v], |
798 | | floatArray[stride*v+1], |
799 | | floatArray[stride*v+2], |
800 | | ni1, na1, nb1, |
801 | | na0, nb0); |
802 | | fprintf(g_fileDebugSC3DMCDec, "normal \t %i \t %f \t %f \t %f \t (%i, %f, %f) \t (%f, %f)\n", |
803 | | v, |
804 | | floatArray[stride*v], |
805 | | floatArray[stride*v+1], |
806 | | floatArray[stride*v+2], |
807 | | ni1, na1, nb1, |
808 | | na0, nb0); |
809 | | #endif //DEBUG_VERBOSE |
810 | 0 | } |
811 | 0 | } |
812 | 0 | else |
813 | 0 | { |
814 | 0 | IQuantizeFloatArray(floatArray, numFloatArray, dimFloatArray, stride, minFloatArray, maxFloatArray, nQBits); |
815 | 0 | } |
816 | | #ifdef DEBUG_VERBOSE |
817 | | fflush(g_fileDebugSC3DMCDec); |
818 | | #endif //DEBUG_VERBOSE |
819 | 0 | return O3DGC_OK; |
820 | 0 | } |
821 | | template<class T> |
822 | | O3DGCErrorCode SC3DMCDecoder<T>::IQuantizeFloatArray(Real * const floatArray, |
823 | | unsigned long numFloatArray, |
824 | | unsigned long dimFloatArray, |
825 | | unsigned long stride, |
826 | | const Real * const minFloatArray, |
827 | | const Real * const maxFloatArray, |
828 | | unsigned long nQBits) |
829 | 0 | { |
830 | | |
831 | 0 | Real idelta[O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES]; |
832 | 0 | Real r; |
833 | 0 | for(unsigned long d = 0; d < dimFloatArray; d++) |
834 | 0 | { |
835 | 0 | r = maxFloatArray[d] - minFloatArray[d]; |
836 | 0 | if (r > 0.0f) |
837 | 0 | { |
838 | 0 | idelta[d] = r/(float)((1 << nQBits) - 1); |
839 | 0 | } |
840 | 0 | else |
841 | 0 | { |
842 | 0 | idelta[d] = 1.0f; |
843 | 0 | } |
844 | 0 | } |
845 | 0 | for(unsigned long v = 0; v < numFloatArray; ++v) |
846 | 0 | { |
847 | 0 | for(unsigned long d = 0; d < dimFloatArray; ++d) { |
848 | 0 | floatArray[v * stride + d] = m_quantFloatArray[v * stride + d] * idelta[d] + minFloatArray[d]; |
849 | 0 | } |
850 | 0 | } |
851 | 0 | return O3DGC_OK; |
852 | 0 | } |
853 | | } // namespace o3dgc |
854 | | |
855 | | #ifdef _MSC_VER |
856 | | # pragma warning( pop ) |
857 | | #endif // _MSC_VER |
858 | | |
859 | | #endif // O3DGC_SC3DMC_DECODER_INL |
860 | | |
861 | | |