Coverage Report

Created: 2025-08-26 06:41

/src/assimp/contrib/Open3DGC/o3dgcArithmeticCodec.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
Copyright (c) 2004 Amir Said (said@ieee.org) & William A. Pearlman (pearlw@ecse.rpi.edu)
3
All rights reserved.
4
5
Redistribution and use in source and binary forms, with or without modification, 
6
are permitted provided that the following conditions are met:
7
8
-   Redistributions of source code must retain the above copyright notice, this list 
9
    of conditions and the following disclaimer. 
10
11
-   Redistributions in binary form must reproduce the above copyright notice, this list of 
12
    conditions and the following disclaimer in the documentation and/or other materials 
13
    provided with the distribution.
14
15
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
16
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
17
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
18
THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
19
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
20
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
21
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 
22
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
23
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
24
OF SUCH DAMAGE.
25
*/
26
27
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
28
//                                                                           -
29
//                       ****************************                        -
30
//                        ARITHMETIC CODING EXAMPLES                         -
31
//                       ****************************                        -
32
//                                                                           -
33
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
34
//                                                                           -
35
// Fast arithmetic coding implementation                                     -
36
// -> 32-bit variables, 32-bit product, periodic updates, table decoding     -
37
//                                                                           -
38
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
39
//                                                                           -
40
// Version 1.00  -  April 25, 2004                                           -
41
//                                                                           -
42
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
43
//                                                                           -
44
//                                  WARNING                                  -
45
//                                 =========                                 -
46
//                                                                           -
47
// The only purpose of this program is to demonstrate the basic principles   -
48
// of arithmetic coding. It is provided as is, without any express or        -
49
// implied warranty, without even the warranty of fitness for any particular -
50
// purpose, or that the implementations are correct.                         -
51
//                                                                           -
52
// Permission to copy and redistribute this code is hereby granted, provided -
53
// that this warning and copyright notices are not removed or altered.       -
54
//                                                                           -
55
// Copyright (c) 2004 by Amir Said (said@ieee.org) &                         -
56
//                       William A. Pearlman (pearlw@ecse.rpi.edu)           -
57
//                                                                           -
58
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
59
//                                                                           -
60
// A description of the arithmetic coding method used here is available in   -
61
//                                                                           -
62
// Lossless Compression Handbook, ed. K. Sayood                              -
63
// Chapter 5: Arithmetic Coding (A. Said), pp. 101-152, Academic Press, 2003 -
64
//                                                                           -
65
// A. Said, Introduction to Arithetic Coding Theory and Practice             -
66
// HP Labs report HPL-2004-76  -  http://www.hpl.hp.com/techreports/         -
67
//                                                                           -
68
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
69
70
71
// - - Definitions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
72
73
#ifndef O3DGC_ARITHMETIC_CODEC
74
#define O3DGC_ARITHMETIC_CODEC
75
76
#include <stdio.h>
77
#include "o3dgcCommon.h"
78
#include <assimp/defs.h>
79
80
namespace o3dgc
81
{
82
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
83
    // - - Class definitions - - - - - - - - - - - - - - - - - - - - - - - - - - -
84
85
    class Static_Bit_Model                         // static model for binary data
86
    {
87
    public:
88
89
      Static_Bit_Model(void);
90
91
      void set_probability_0(double);             // set probability of symbol '0'
92
93
    private:  //  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
94
      unsigned bit_0_prob;
95
      friend class Arithmetic_Codec;
96
    };
97
98
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
99
100
    class Static_Data_Model                       // static model for general data
101
    {
102
    public:
103
104
      Static_Data_Model(void);
105
     ~Static_Data_Model(void);
106
107
0
      unsigned model_symbols(void) { return data_symbols; }
108
109
      void set_distribution(unsigned number_of_symbols,
110
                            const double probability[] = 0);    // 0 means uniform
111
112
    private:  //  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
113
      unsigned * distribution, * decoder_table;
114
      unsigned data_symbols, last_symbol, table_size, table_shift;
115
      friend class Arithmetic_Codec;
116
    };
117
118
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
119
120
    class Adaptive_Bit_Model                     // adaptive model for binary data
121
    {
122
    public:
123
124
      Adaptive_Bit_Model(void);         
125
126
      void reset(void);                             // reset to equiprobable model
127
128
    private:  //  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
129
      void     update(void);
130
      unsigned update_cycle, bits_until_update;
131
      unsigned bit_0_prob, bit_0_count, bit_count;
132
      friend class Arithmetic_Codec;
133
    };
134
135
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
136
137
    class Adaptive_Data_Model                    // adaptive model for binary data
138
    {
139
    public:
140
141
      Adaptive_Data_Model(void);
142
      Adaptive_Data_Model(unsigned number_of_symbols);
143
     ~Adaptive_Data_Model(void);
144
145
0
      unsigned model_symbols(void) { return data_symbols; }
146
147
      void reset(void);                             // reset to equiprobable model
148
      void set_alphabet(unsigned number_of_symbols);
149
150
    private:  //  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
151
      void     update(bool);
152
      unsigned * distribution, * symbol_count, * decoder_table;
153
      unsigned total_count, update_cycle, symbols_until_update;
154
      unsigned data_symbols, last_symbol, table_size, table_shift;
155
      friend class Arithmetic_Codec;
156
    };
157
158
159
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
160
    // - - Encoder and decoder class - - - - - - - - - - - - - - - - - - - - - - -
161
162
    // Class with both the arithmetic encoder and decoder.  All compressed data is
163
    // saved to a memory buffer
164
165
    class Arithmetic_Codec
166
    {
167
    public:
168
169
      Arithmetic_Codec(void);
170
     ~Arithmetic_Codec(void);
171
      Arithmetic_Codec(unsigned max_code_bytes,
172
                       unsigned char * user_buffer = 0);         // 0 = assign new
173
174
0
      unsigned char * buffer(void) { return code_buffer; }
175
176
      void set_buffer(unsigned max_code_bytes,
177
                      unsigned char * user_buffer = 0);          // 0 = assign new
178
179
      void     start_encoder(void);
180
      void     start_decoder(void);
181
      void     read_from_file(FILE * code_file);  // read code data, start decoder
182
183
      unsigned stop_encoder(void);                 // returns number of bytes used
184
      unsigned write_to_file(FILE * code_file);   // stop encoder, write code data
185
      void     stop_decoder(void);
186
187
      void     put_bit(unsigned bit);
188
      unsigned get_bit(void);
189
190
      void     put_bits(unsigned data, unsigned number_of_bits);
191
      unsigned get_bits(unsigned number_of_bits);
192
193
      void     encode(unsigned bit,
194
                      Static_Bit_Model &);
195
      unsigned decode(Static_Bit_Model &);
196
197
      void     encode(unsigned data,
198
                      Static_Data_Model &);
199
      unsigned decode(Static_Data_Model &);
200
201
      void     encode(unsigned bit,
202
                      Adaptive_Bit_Model &);
203
      unsigned decode(Adaptive_Bit_Model &);
204
205
      void     encode(unsigned data,
206
                      Adaptive_Data_Model &);
207
      unsigned decode(Adaptive_Data_Model &);
208
209
//   This section was added by K. Mammou
210
      void     ExpGolombEncode(unsigned int symbol, 
211
                               int k,
212
                               Static_Bit_Model & bModel0,
213
                               Adaptive_Bit_Model & bModel1)
214
0
               {
215
0
                   while(1)
216
0
                   {
217
0
                       if (symbol >= (unsigned int)(1<<k))
218
0
                       {
219
0
                           encode(1, bModel1);
220
0
                           symbol = symbol - (1<<k);
221
0
                           k++;
222
0
                       }
223
0
                       else
224
0
                       {
225
0
                           encode(0, bModel1); // now terminated zero of unary part
226
0
                           while (k--) // next binary part
227
0
                           {
228
0
                               encode((signed short)((symbol>>k)&1), bModel0);
229
0
                           }
230
0
                           break;
231
0
                       }
232
0
                   }
233
0
               }
234
235
236
    unsigned   ExpGolombDecode(int k,
237
                               Static_Bit_Model & bModel0,
238
                               Adaptive_Bit_Model & bModel1)
239
0
               {
240
0
                   unsigned int l;
241
0
                   int symbol = 0;
242
0
                   int binary_symbol = 0;
243
0
                   do
244
0
                   {
245
0
                       l=decode(bModel1);
246
0
                       if (l==1)
247
0
                       {
248
0
                           symbol += (1<<k);
249
0
                           k++;
250
0
                        }
251
0
                   }
252
0
                   while (l!=0);
253
0
                   while (k--)                             //next binary part
254
0
                   if (decode(bModel0)==1)
255
0
                   {
256
0
                       binary_symbol |= (1<<k);
257
0
                   }
258
0
                   return (unsigned int) (symbol+binary_symbol);
259
0
                }
260
//----------------------------------------------------------
261
262
    private:  //  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
263
      void propagate_carry(void);
264
      void renorm_enc_interval(void);
265
      void renorm_dec_interval(void);
266
      unsigned char * code_buffer, * new_buffer, * ac_pointer;
267
      unsigned base, value, length;                     // arithmetic coding state
268
      unsigned buffer_size, mode;     // mode: 0 = undef, 1 = encoder, 2 = decoder
269
    };
270
    inline long DecodeIntACEGC(Arithmetic_Codec & acd,
271
                               Adaptive_Data_Model & mModelValues,
272
                               Static_Bit_Model & bModel0,
273
                               Adaptive_Bit_Model & bModel1,
274
                               const unsigned long exp_k,
275
                               const unsigned long M)
276
0
    {
277
0
        unsigned long uiValue = acd.decode(mModelValues);
278
0
        if (uiValue == M) 
279
0
        {
280
0
            uiValue += acd.ExpGolombDecode(exp_k, bModel0, bModel1);
281
0
        }
282
0
        return UIntToInt(uiValue);
283
0
    }
284
    inline unsigned long DecodeUIntACEGC(Arithmetic_Codec & acd,
285
                                         Adaptive_Data_Model & mModelValues,
286
                                         Static_Bit_Model & bModel0,
287
                                         Adaptive_Bit_Model & bModel1,
288
                                         const unsigned long exp_k,
289
                                         const unsigned long M)
290
0
    {
291
0
        unsigned long uiValue = acd.decode(mModelValues);
292
0
        if (uiValue == M) 
293
0
        {
294
0
            uiValue += acd.ExpGolombDecode(exp_k, bModel0, bModel1);
295
0
        }
296
0
        return uiValue;
297
0
    }
298
299
    inline void EncodeIntACEGC(long predResidual, 
300
                               Arithmetic_Codec & ace,
301
                               Adaptive_Data_Model & mModelValues,
302
                               Static_Bit_Model & bModel0,
303
                               Adaptive_Bit_Model & bModel1,
304
                               const unsigned long M)
305
0
    {
306
0
        unsigned long uiValue = IntToUInt(predResidual);
307
0
        if (uiValue < M) 
308
0
        {
309
0
            ace.encode(uiValue, mModelValues);
310
0
        }
311
0
        else 
312
0
        {
313
0
            ace.encode(M, mModelValues);
314
0
            ace.ExpGolombEncode(uiValue-M, 0, bModel0, bModel1);
315
0
        }
316
0
    }
317
    inline void EncodeUIntACEGC(long predResidual, 
318
                                Arithmetic_Codec & ace,
319
                                Adaptive_Data_Model & mModelValues,
320
                                Static_Bit_Model & bModel0,
321
                                Adaptive_Bit_Model & bModel1,
322
                                const unsigned long M)
323
0
    {
324
0
        unsigned long uiValue = (unsigned long) predResidual;
325
0
        if (uiValue < M) 
326
0
        {
327
0
            ace.encode(uiValue, mModelValues);
328
0
        }
329
0
        else 
330
0
        {
331
0
            ace.encode(M, mModelValues);
332
0
            ace.ExpGolombEncode(uiValue-M, 0, bModel0, bModel1);
333
0
        }
334
0
    }
335
336
}
337
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
338
339
#endif
340