Coverage Report

Created: 2025-08-26 06:41

/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