/src/assimp/contrib/Open3DGC/o3dgcArithmeticCodec.cpp
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 | | // - - Inclusion - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
72 | | |
73 | | #include <stdlib.h> |
74 | | #include "o3dgcArithmeticCodec.h" |
75 | | |
76 | | namespace o3dgc |
77 | | { |
78 | | // - - Constants - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
79 | | |
80 | | const unsigned AC__MinLength = 0x01000000U; // threshold for renormalization |
81 | | const unsigned AC__MaxLength = 0xFFFFFFFFU; // maximum AC interval length |
82 | | |
83 | | // Maximum values for binary models |
84 | | const unsigned BM__LengthShift = 13; // length bits discarded before mult. |
85 | | const unsigned BM__MaxCount = 1 << BM__LengthShift; // for adaptive models |
86 | | |
87 | | // Maximum values for general models |
88 | | const unsigned DM__LengthShift = 15; // length bits discarded before mult. |
89 | | const unsigned DM__MaxCount = 1 << DM__LengthShift; // for adaptive models |
90 | | |
91 | | |
92 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
93 | | // - - Static functions - - - - - - - - - - - - - - - - - - - - - - - - - - - |
94 | | |
95 | | AI_WONT_RETURN static void AC_Error(const char * msg) AI_WONT_RETURN_SUFFIX; |
96 | | static void AC_Error(const char * msg) |
97 | 0 | { |
98 | 0 | fprintf(stderr, "\n\n -> Arithmetic coding error: "); |
99 | 0 | fputs(msg, stderr); |
100 | 0 | fputs("\n Execution terminated!\n", stderr); |
101 | 0 | getchar(); |
102 | 0 | exit(1); |
103 | 0 | } |
104 | | |
105 | | |
106 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
107 | | // - - Coding implementations - - - - - - - - - - - - - - - - - - - - - - - - |
108 | | |
109 | | inline void Arithmetic_Codec::propagate_carry(void) |
110 | 0 | { |
111 | 0 | unsigned char * p; // carry propagation on compressed data buffer |
112 | 0 | for (p = ac_pointer - 1; *p == 0xFFU; p--) *p = 0; |
113 | 0 | ++*p; |
114 | 0 | } |
115 | | |
116 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
117 | | |
118 | | inline void Arithmetic_Codec::renorm_enc_interval(void) |
119 | 0 | { |
120 | 0 | do { // output and discard top byte |
121 | 0 | *ac_pointer++ = (unsigned char)(base >> 24); |
122 | 0 | base <<= 8; |
123 | 0 | } while ((length <<= 8) < AC__MinLength); // length multiplied by 256 |
124 | 0 | } |
125 | | |
126 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
127 | | |
128 | | inline void Arithmetic_Codec::renorm_dec_interval(void) |
129 | 0 | { |
130 | 0 | do { // read least-significant byte |
131 | 0 | value = (value << 8) | unsigned(*++ac_pointer); |
132 | 0 | } while ((length <<= 8) < AC__MinLength); // length multiplied by 256 |
133 | 0 | } |
134 | | |
135 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
136 | | |
137 | | void Arithmetic_Codec::put_bit(unsigned bit) |
138 | 0 | { |
139 | | #ifdef _DEBUG |
140 | | if (mode != 1) AC_Error("encoder not initialized"); |
141 | | #endif |
142 | |
|
143 | 0 | length >>= 1; // halve interval |
144 | 0 | if (bit) { |
145 | 0 | unsigned init_base = base; |
146 | 0 | base += length; // move base |
147 | 0 | if (init_base > base) propagate_carry(); // overflow = carry |
148 | 0 | } |
149 | |
|
150 | 0 | if (length < AC__MinLength) renorm_enc_interval(); // renormalization |
151 | 0 | } |
152 | | |
153 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
154 | | |
155 | | unsigned Arithmetic_Codec::get_bit(void) |
156 | 0 | { |
157 | | #ifdef _DEBUG |
158 | | if (mode != 2) AC_Error("decoder not initialized"); |
159 | | #endif |
160 | |
|
161 | 0 | length >>= 1; // halve interval |
162 | 0 | unsigned bit = (value >= length); // decode bit |
163 | 0 | if (bit) value -= length; // move base |
164 | |
|
165 | 0 | if (length < AC__MinLength) renorm_dec_interval(); // renormalization |
166 | |
|
167 | 0 | return bit; // return data bit value |
168 | 0 | } |
169 | | |
170 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
171 | | |
172 | | void Arithmetic_Codec::put_bits(unsigned data, unsigned bits) |
173 | 0 | { |
174 | | #ifdef _DEBUG |
175 | | if (mode != 1) AC_Error("encoder not initialized"); |
176 | | if ((bits < 1) || (bits > 20)) AC_Error("invalid number of bits"); |
177 | | if (data >= (1U << bits)) AC_Error("invalid data"); |
178 | | #endif |
179 | |
|
180 | 0 | unsigned init_base = base; |
181 | 0 | base += data * (length >>= bits); // new interval base and length |
182 | |
|
183 | 0 | if (init_base > base) propagate_carry(); // overflow = carry |
184 | 0 | if (length < AC__MinLength) renorm_enc_interval(); // renormalization |
185 | 0 | } |
186 | | |
187 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
188 | | |
189 | | unsigned Arithmetic_Codec::get_bits(unsigned bits) |
190 | 0 | { |
191 | | #ifdef _DEBUG |
192 | | if (mode != 2) AC_Error("decoder not initialized"); |
193 | | if ((bits < 1) || (bits > 20)) AC_Error("invalid number of bits"); |
194 | | #endif |
195 | |
|
196 | 0 | unsigned s = value / (length >>= bits); // decode symbol, change length |
197 | |
|
198 | 0 | value -= length * s; // update interval |
199 | 0 | if (length < AC__MinLength) renorm_dec_interval(); // renormalization |
200 | |
|
201 | 0 | return s; |
202 | 0 | } |
203 | | |
204 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
205 | | |
206 | | void Arithmetic_Codec::encode(unsigned bit, |
207 | | Static_Bit_Model & M) |
208 | 0 | { |
209 | | #ifdef _DEBUG |
210 | | if (mode != 1) AC_Error("encoder not initialized"); |
211 | | #endif |
212 | |
|
213 | 0 | unsigned x = M.bit_0_prob * (length >> BM__LengthShift); // product l x p0 |
214 | | // update interval |
215 | 0 | if (bit == 0) |
216 | 0 | length = x; |
217 | 0 | else { |
218 | 0 | unsigned init_base = base; |
219 | 0 | base += x; |
220 | 0 | length -= x; |
221 | 0 | if (init_base > base) propagate_carry(); // overflow = carry |
222 | 0 | } |
223 | |
|
224 | 0 | if (length < AC__MinLength) renorm_enc_interval(); // renormalization |
225 | 0 | } |
226 | | |
227 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
228 | | |
229 | | unsigned Arithmetic_Codec::decode(Static_Bit_Model & M) |
230 | 0 | { |
231 | | #ifdef _DEBUG |
232 | | if (mode != 2) AC_Error("decoder not initialized"); |
233 | | #endif |
234 | |
|
235 | 0 | unsigned x = M.bit_0_prob * (length >> BM__LengthShift); // product l x p0 |
236 | 0 | unsigned bit = (value >= x); // decision |
237 | | // update & shift interval |
238 | 0 | if (bit == 0) |
239 | 0 | length = x; |
240 | 0 | else { |
241 | 0 | value -= x; // shifted interval base = 0 |
242 | 0 | length -= x; |
243 | 0 | } |
244 | |
|
245 | 0 | if (length < AC__MinLength) renorm_dec_interval(); // renormalization |
246 | |
|
247 | 0 | return bit; // return data bit value |
248 | 0 | } |
249 | | |
250 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
251 | | |
252 | | void Arithmetic_Codec::encode(unsigned bit, |
253 | | Adaptive_Bit_Model & M) |
254 | 0 | { |
255 | | #ifdef _DEBUG |
256 | | if (mode != 1) AC_Error("encoder not initialized"); |
257 | | #endif |
258 | |
|
259 | 0 | unsigned x = M.bit_0_prob * (length >> BM__LengthShift); // product l x p0 |
260 | | // update interval |
261 | 0 | if (bit == 0) { |
262 | 0 | length = x; |
263 | 0 | ++M.bit_0_count; |
264 | 0 | } |
265 | 0 | else { |
266 | 0 | unsigned init_base = base; |
267 | 0 | base += x; |
268 | 0 | length -= x; |
269 | 0 | if (init_base > base) propagate_carry(); // overflow = carry |
270 | 0 | } |
271 | |
|
272 | 0 | if (length < AC__MinLength) renorm_enc_interval(); // renormalization |
273 | |
|
274 | 0 | if (--M.bits_until_update == 0) M.update(); // periodic model update |
275 | 0 | } |
276 | | |
277 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
278 | | |
279 | | unsigned Arithmetic_Codec::decode(Adaptive_Bit_Model & M) |
280 | 0 | { |
281 | | #ifdef _DEBUG |
282 | | if (mode != 2) AC_Error("decoder not initialized"); |
283 | | #endif |
284 | |
|
285 | 0 | unsigned x = M.bit_0_prob * (length >> BM__LengthShift); // product l x p0 |
286 | 0 | unsigned bit = (value >= x); // decision |
287 | | // update interval |
288 | 0 | if (bit == 0) { |
289 | 0 | length = x; |
290 | 0 | ++M.bit_0_count; |
291 | 0 | } |
292 | 0 | else { |
293 | 0 | value -= x; |
294 | 0 | length -= x; |
295 | 0 | } |
296 | |
|
297 | 0 | if (length < AC__MinLength) renorm_dec_interval(); // renormalization |
298 | |
|
299 | 0 | if (--M.bits_until_update == 0) M.update(); // periodic model update |
300 | |
|
301 | 0 | return bit; // return data bit value |
302 | 0 | } |
303 | | |
304 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
305 | | |
306 | | void Arithmetic_Codec::encode(unsigned data, |
307 | | Static_Data_Model & M) |
308 | 0 | { |
309 | | #ifdef _DEBUG |
310 | | if (mode != 1) AC_Error("encoder not initialized"); |
311 | | if (data >= M.data_symbols) AC_Error("invalid data symbol"); |
312 | | #endif |
313 | |
|
314 | 0 | unsigned x, init_base = base; |
315 | | // compute products |
316 | 0 | if (data == M.last_symbol) { |
317 | 0 | x = M.distribution[data] * (length >> DM__LengthShift); |
318 | 0 | base += x; // update interval |
319 | 0 | length -= x; // no product needed |
320 | 0 | } |
321 | 0 | else { |
322 | 0 | x = M.distribution[data] * (length >>= DM__LengthShift); |
323 | 0 | base += x; // update interval |
324 | 0 | length = M.distribution[data+1] * length - x; |
325 | 0 | } |
326 | | |
327 | 0 | if (init_base > base) propagate_carry(); // overflow = carry |
328 | |
|
329 | 0 | if (length < AC__MinLength) renorm_enc_interval(); // renormalization |
330 | 0 | } |
331 | | |
332 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
333 | | |
334 | | unsigned Arithmetic_Codec::decode(Static_Data_Model & M) |
335 | 0 | { |
336 | | #ifdef _DEBUG |
337 | | if (mode != 2) AC_Error("decoder not initialized"); |
338 | | #endif |
339 | |
|
340 | 0 | unsigned n, s, x, y = length; |
341 | |
|
342 | 0 | if (M.decoder_table) { // use table look-up for faster decoding |
343 | |
|
344 | 0 | unsigned dv = value / (length >>= DM__LengthShift); |
345 | 0 | unsigned t = dv >> M.table_shift; |
346 | |
|
347 | 0 | s = M.decoder_table[t]; // initial decision based on table look-up |
348 | 0 | n = M.decoder_table[t+1] + 1; |
349 | |
|
350 | 0 | while (n > s + 1) { // finish with bisection search |
351 | 0 | unsigned m = (s + n) >> 1; |
352 | 0 | if (M.distribution[m] > dv) n = m; else s = m; |
353 | 0 | } |
354 | | // compute products |
355 | 0 | x = M.distribution[s] * length; |
356 | 0 | if (s != M.last_symbol) y = M.distribution[s+1] * length; |
357 | 0 | } |
358 | | |
359 | 0 | else { // decode using only multiplications |
360 | |
|
361 | 0 | x = s = 0; |
362 | 0 | length >>= DM__LengthShift; |
363 | 0 | unsigned m = (n = M.data_symbols) >> 1; |
364 | | // decode via bisection search |
365 | 0 | do { |
366 | 0 | unsigned z = length * M.distribution[m]; |
367 | 0 | if (z > value) { |
368 | 0 | n = m; |
369 | 0 | y = z; // value is smaller |
370 | 0 | } |
371 | 0 | else { |
372 | 0 | s = m; |
373 | 0 | x = z; // value is larger or equal |
374 | 0 | } |
375 | 0 | } while ((m = (s + n) >> 1) != s); |
376 | 0 | } |
377 | |
|
378 | 0 | value -= x; // update interval |
379 | 0 | length = y - x; |
380 | |
|
381 | 0 | if (length < AC__MinLength) renorm_dec_interval(); // renormalization |
382 | |
|
383 | 0 | return s; |
384 | 0 | } |
385 | | |
386 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
387 | | |
388 | | void Arithmetic_Codec::encode(unsigned data, |
389 | | Adaptive_Data_Model & M) |
390 | 0 | { |
391 | | #ifdef _DEBUG |
392 | | if (mode != 1) AC_Error("encoder not initialized"); |
393 | | if (data >= M.data_symbols) |
394 | | { |
395 | | AC_Error("invalid data symbol"); |
396 | | } |
397 | | #endif |
398 | |
|
399 | 0 | unsigned x, init_base = base; |
400 | | // compute products |
401 | 0 | if (data == M.last_symbol) { |
402 | 0 | x = M.distribution[data] * (length >> DM__LengthShift); |
403 | 0 | base += x; // update interval |
404 | 0 | length -= x; // no product needed |
405 | 0 | } |
406 | 0 | else { |
407 | 0 | x = M.distribution[data] * (length >>= DM__LengthShift); |
408 | 0 | base += x; // update interval |
409 | 0 | length = M.distribution[data+1] * length - x; |
410 | 0 | } |
411 | |
|
412 | 0 | if (init_base > base) propagate_carry(); // overflow = carry |
413 | |
|
414 | 0 | if (length < AC__MinLength) renorm_enc_interval(); // renormalization |
415 | |
|
416 | 0 | ++M.symbol_count[data]; |
417 | 0 | if (--M.symbols_until_update == 0) M.update(true); // periodic model update |
418 | 0 | } |
419 | | |
420 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
421 | | |
422 | | unsigned Arithmetic_Codec::decode(Adaptive_Data_Model & M) |
423 | 0 | { |
424 | | #ifdef _DEBUG |
425 | | if (mode != 2) AC_Error("decoder not initialized"); |
426 | | #endif |
427 | |
|
428 | 0 | unsigned n, s, x, y = length; |
429 | |
|
430 | 0 | if (M.decoder_table) { // use table look-up for faster decoding |
431 | |
|
432 | 0 | unsigned dv = value / (length >>= DM__LengthShift); |
433 | 0 | unsigned t = dv >> M.table_shift; |
434 | |
|
435 | 0 | s = M.decoder_table[t]; // initial decision based on table look-up |
436 | 0 | n = M.decoder_table[t+1] + 1; |
437 | |
|
438 | 0 | while (n > s + 1) { // finish with bisection search |
439 | 0 | unsigned m = (s + n) >> 1; |
440 | 0 | if (M.distribution[m] > dv) n = m; else s = m; |
441 | 0 | } |
442 | | // compute products |
443 | 0 | x = M.distribution[s] * length; |
444 | 0 | if (s != M.last_symbol) { |
445 | 0 | y = M.distribution[s+1] * length; |
446 | 0 | } |
447 | 0 | } |
448 | | |
449 | 0 | else { // decode using only multiplications |
450 | |
|
451 | 0 | x = s = 0; |
452 | 0 | length >>= DM__LengthShift; |
453 | 0 | unsigned m = (n = M.data_symbols) >> 1; |
454 | | // decode via bisection search |
455 | 0 | do { |
456 | 0 | unsigned z = length * M.distribution[m]; |
457 | 0 | if (z > value) { |
458 | 0 | n = m; |
459 | 0 | y = z; // value is smaller |
460 | 0 | } |
461 | 0 | else { |
462 | 0 | s = m; |
463 | 0 | x = z; // value is larger or equal |
464 | 0 | } |
465 | 0 | } while ((m = (s + n) >> 1) != s); |
466 | 0 | } |
467 | |
|
468 | 0 | value -= x; // update interval |
469 | 0 | length = y - x; |
470 | |
|
471 | 0 | if (length < AC__MinLength) renorm_dec_interval(); // renormalization |
472 | |
|
473 | 0 | ++M.symbol_count[s]; |
474 | 0 | if (--M.symbols_until_update == 0) M.update(false); // periodic model update |
475 | |
|
476 | 0 | return s; |
477 | 0 | } |
478 | | |
479 | | |
480 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
481 | | // - - Other Arithmetic_Codec implementations - - - - - - - - - - - - - - - - |
482 | | |
483 | | Arithmetic_Codec::Arithmetic_Codec(void) |
484 | 0 | { |
485 | 0 | mode = buffer_size = 0; |
486 | 0 | new_buffer = code_buffer = 0; |
487 | 0 | } |
488 | | |
489 | | Arithmetic_Codec::Arithmetic_Codec(unsigned max_code_bytes, |
490 | | unsigned char * user_buffer) |
491 | 0 | { |
492 | 0 | mode = buffer_size = 0; |
493 | 0 | new_buffer = code_buffer = 0; |
494 | 0 | set_buffer(max_code_bytes, user_buffer); |
495 | 0 | } |
496 | | |
497 | | Arithmetic_Codec::~Arithmetic_Codec(void) |
498 | 0 | { |
499 | 0 | delete [] new_buffer; |
500 | 0 | } |
501 | | |
502 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
503 | | |
504 | | void Arithmetic_Codec::set_buffer(unsigned max_code_bytes, |
505 | | unsigned char * user_buffer) |
506 | 0 | { |
507 | | // test for reasonable sizes |
508 | 0 | if (!max_code_bytes)// || (max_code_bytes > 0x10000000U)) // updated by K. Mammou |
509 | 0 | { |
510 | 0 | AC_Error("invalid codec buffer size"); |
511 | 0 | } |
512 | 0 | if (mode != 0) AC_Error("cannot set buffer while encoding or decoding"); |
513 | | |
514 | 0 | if (user_buffer != 0) { // user provides memory buffer |
515 | 0 | buffer_size = max_code_bytes; |
516 | 0 | code_buffer = user_buffer; // set buffer for compressed data |
517 | 0 | delete [] new_buffer; // free anything previously assigned |
518 | 0 | new_buffer = 0; |
519 | 0 | return; |
520 | 0 | } |
521 | | |
522 | 0 | if (max_code_bytes <= buffer_size) return; // enough available |
523 | | |
524 | 0 | buffer_size = max_code_bytes; // assign new memory |
525 | 0 | delete [] new_buffer; // free anything previously assigned |
526 | 0 | new_buffer = new unsigned char[buffer_size+16]; // 16 extra bytes |
527 | 0 | code_buffer = new_buffer; // set buffer for compressed data |
528 | 0 | } |
529 | | |
530 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
531 | | |
532 | | void Arithmetic_Codec::start_encoder(void) |
533 | 0 | { |
534 | 0 | if (mode != 0) AC_Error("cannot start encoder"); |
535 | 0 | if (buffer_size == 0) AC_Error("no code buffer set"); |
536 | | |
537 | 0 | mode = 1; |
538 | 0 | base = 0; // initialize encoder variables: interval and pointer |
539 | 0 | length = AC__MaxLength; |
540 | 0 | ac_pointer = code_buffer; // pointer to next data byte |
541 | 0 | } |
542 | | |
543 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
544 | | |
545 | | void Arithmetic_Codec::start_decoder(void) |
546 | 0 | { |
547 | 0 | if (mode != 0) AC_Error("cannot start decoder"); |
548 | 0 | if (buffer_size == 0) AC_Error("no code buffer set"); |
549 | | |
550 | | // initialize decoder: interval, pointer, initial code value |
551 | 0 | mode = 2; |
552 | 0 | length = AC__MaxLength; |
553 | 0 | ac_pointer = code_buffer + 3; |
554 | 0 | value = (unsigned(code_buffer[0]) << 24)|(unsigned(code_buffer[1]) << 16) | |
555 | 0 | (unsigned(code_buffer[2]) << 8)| unsigned(code_buffer[3]); |
556 | 0 | } |
557 | | |
558 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
559 | | |
560 | | void Arithmetic_Codec::read_from_file(FILE * code_file) |
561 | 0 | { |
562 | 0 | unsigned shift = 0, code_bytes = 0; |
563 | 0 | int file_byte; |
564 | | // read variable-length header with number of code bytes |
565 | 0 | do { |
566 | 0 | if ((file_byte = getc(code_file)) == EOF) |
567 | 0 | AC_Error("cannot read code from file"); |
568 | 0 | code_bytes |= unsigned(file_byte & 0x7F) << shift; |
569 | 0 | shift += 7; |
570 | 0 | } while (file_byte & 0x80); |
571 | | // read compressed data |
572 | 0 | if (code_bytes > buffer_size) AC_Error("code buffer overflow"); |
573 | 0 | if (fread(code_buffer, 1, code_bytes, code_file) != code_bytes) |
574 | 0 | AC_Error("cannot read code from file"); |
575 | | |
576 | 0 | start_decoder(); // initialize decoder |
577 | 0 | } |
578 | | |
579 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
580 | | |
581 | | unsigned Arithmetic_Codec::stop_encoder(void) |
582 | 0 | { |
583 | 0 | if (mode != 1) AC_Error("invalid to stop encoder"); |
584 | 0 | mode = 0; |
585 | |
|
586 | 0 | unsigned init_base = base; // done encoding: set final data bytes |
587 | |
|
588 | 0 | if (length > 2 * AC__MinLength) { |
589 | 0 | base += AC__MinLength; // base offset |
590 | 0 | length = AC__MinLength >> 1; // set new length for 1 more byte |
591 | 0 | } |
592 | 0 | else { |
593 | 0 | base += AC__MinLength >> 1; // base offset |
594 | 0 | length = AC__MinLength >> 9; // set new length for 2 more bytes |
595 | 0 | } |
596 | |
|
597 | 0 | if (init_base > base) propagate_carry(); // overflow = carry |
598 | |
|
599 | 0 | renorm_enc_interval(); // renormalization = output last bytes |
600 | |
|
601 | 0 | unsigned code_bytes = unsigned(ac_pointer - code_buffer); |
602 | 0 | if (code_bytes > buffer_size) AC_Error("code buffer overflow"); |
603 | | |
604 | 0 | return code_bytes; // number of bytes used |
605 | 0 | } |
606 | | |
607 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
608 | | |
609 | | unsigned Arithmetic_Codec::write_to_file(FILE * code_file) |
610 | 0 | { |
611 | 0 | unsigned header_bytes = 0, code_bytes = stop_encoder(), nb = code_bytes; |
612 | | |
613 | | // write variable-length header with number of code bytes |
614 | 0 | do { |
615 | 0 | int file_byte = int(nb & 0x7FU); |
616 | 0 | if ((nb >>= 7) > 0) file_byte |= 0x80; |
617 | 0 | if (putc(file_byte, code_file) == EOF) |
618 | 0 | AC_Error("cannot write compressed data to file"); |
619 | 0 | header_bytes++; |
620 | 0 | } while (nb); |
621 | | // write compressed data |
622 | 0 | if (fwrite(code_buffer, 1, code_bytes, code_file) != code_bytes) |
623 | 0 | AC_Error("cannot write compressed data to file"); |
624 | | |
625 | 0 | return code_bytes + header_bytes; // bytes used |
626 | 0 | } |
627 | | |
628 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
629 | | |
630 | | void Arithmetic_Codec::stop_decoder(void) |
631 | 0 | { |
632 | 0 | if (mode != 2) AC_Error("invalid to stop decoder"); |
633 | 0 | mode = 0; |
634 | 0 | } |
635 | | |
636 | | |
637 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
638 | | // - Static bit model implementation - - - - - - - - - - - - - - - - - - - - - |
639 | | |
640 | | Static_Bit_Model::Static_Bit_Model(void) |
641 | 0 | { |
642 | 0 | bit_0_prob = 1U << (BM__LengthShift - 1); // p0 = 0.5 |
643 | 0 | } |
644 | | |
645 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
646 | | |
647 | | void Static_Bit_Model::set_probability_0(double p0) |
648 | 0 | { |
649 | 0 | if ((p0 < 0.0001)||(p0 > 0.9999)) AC_Error("invalid bit probability"); |
650 | 0 | bit_0_prob = unsigned(p0 * (1 << BM__LengthShift)); |
651 | 0 | } |
652 | | |
653 | | |
654 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
655 | | // - Adaptive bit model implementation - - - - - - - - - - - - - - - - - - - - |
656 | | |
657 | | Adaptive_Bit_Model::Adaptive_Bit_Model(void) |
658 | 0 | { |
659 | 0 | reset(); |
660 | 0 | } |
661 | | |
662 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
663 | | |
664 | | void Adaptive_Bit_Model::reset(void) |
665 | 0 | { |
666 | | // initialization to equiprobable model |
667 | 0 | bit_0_count = 1; |
668 | 0 | bit_count = 2; |
669 | 0 | bit_0_prob = 1U << (BM__LengthShift - 1); |
670 | 0 | update_cycle = bits_until_update = 4; // start with frequent updates |
671 | 0 | } |
672 | | |
673 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
674 | | |
675 | | void Adaptive_Bit_Model::update(void) |
676 | 0 | { |
677 | | // halve counts when a threshold is reached |
678 | |
|
679 | 0 | if ((bit_count += update_cycle) > BM__MaxCount) { |
680 | 0 | bit_count = (bit_count + 1) >> 1; |
681 | 0 | bit_0_count = (bit_0_count + 1) >> 1; |
682 | 0 | if (bit_0_count == bit_count) ++bit_count; |
683 | 0 | } |
684 | | // compute scaled bit 0 probability |
685 | 0 | unsigned scale = 0x80000000U / bit_count; |
686 | 0 | bit_0_prob = (bit_0_count * scale) >> (31 - BM__LengthShift); |
687 | | |
688 | | // set frequency of model updates |
689 | 0 | update_cycle = (5 * update_cycle) >> 2; |
690 | 0 | if (update_cycle > 64) update_cycle = 64; |
691 | 0 | bits_until_update = update_cycle; |
692 | 0 | } |
693 | | |
694 | | |
695 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
696 | | // - - Static data model implementation - - - - - - - - - - - - - - - - - - - |
697 | | |
698 | | Static_Data_Model::Static_Data_Model(void) |
699 | 0 | { |
700 | 0 | data_symbols = 0; |
701 | 0 | distribution = 0; |
702 | 0 | } |
703 | | |
704 | | Static_Data_Model::~Static_Data_Model(void) |
705 | 0 | { |
706 | 0 | delete [] distribution; |
707 | 0 | } |
708 | | |
709 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
710 | | |
711 | | void Static_Data_Model::set_distribution(unsigned number_of_symbols, |
712 | | const double probability[]) |
713 | 0 | { |
714 | 0 | if ((number_of_symbols < 2) || (number_of_symbols > (1 << 11))) |
715 | 0 | AC_Error("invalid number of data symbols"); |
716 | | |
717 | 0 | if (data_symbols != number_of_symbols) { // assign memory for data model |
718 | 0 | data_symbols = number_of_symbols; |
719 | 0 | last_symbol = data_symbols - 1; |
720 | 0 | delete [] distribution; |
721 | | // define size of table for fast decoding |
722 | 0 | if (data_symbols > 16) { |
723 | 0 | unsigned table_bits = 3; |
724 | 0 | while (data_symbols > (1U << (table_bits + 2))) ++table_bits; |
725 | 0 | table_size = 1 << table_bits; |
726 | 0 | table_shift = DM__LengthShift - table_bits; |
727 | 0 | distribution = new unsigned[data_symbols+table_size+2]; |
728 | 0 | decoder_table = distribution + data_symbols; |
729 | 0 | } |
730 | 0 | else { // small alphabet: no table needed |
731 | 0 | decoder_table = 0; |
732 | 0 | table_size = table_shift = 0; |
733 | 0 | distribution = new unsigned[data_symbols]; |
734 | 0 | } |
735 | 0 | } |
736 | | // compute cumulative distribution, decoder table |
737 | 0 | unsigned s = 0; |
738 | 0 | double sum = 0.0, p = 1.0 / double(data_symbols); |
739 | |
|
740 | 0 | for (unsigned k = 0; k < data_symbols; k++) { |
741 | 0 | if (probability) p = probability[k]; |
742 | 0 | if ((p < 0.0001) || (p > 0.9999)) AC_Error("invalid symbol probability"); |
743 | 0 | distribution[k] = unsigned(sum * (1 << DM__LengthShift)); |
744 | 0 | sum += p; |
745 | 0 | if (table_size == 0) continue; |
746 | 0 | unsigned w = distribution[k] >> table_shift; |
747 | 0 | while (s < w) decoder_table[++s] = k - 1; |
748 | 0 | } |
749 | | |
750 | 0 | if (table_size != 0) { |
751 | 0 | decoder_table[0] = 0; |
752 | 0 | while (s <= table_size) decoder_table[++s] = data_symbols - 1; |
753 | 0 | } |
754 | |
|
755 | 0 | if ((sum < 0.9999) || (sum > 1.0001)) AC_Error("invalid probabilities"); |
756 | 0 | } |
757 | | |
758 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
759 | | // - - Adaptive data model implementation - - - - - - - - - - - - - - - - - - |
760 | | |
761 | | Adaptive_Data_Model::Adaptive_Data_Model(void) |
762 | 0 | { |
763 | 0 | data_symbols = 0; |
764 | 0 | distribution = 0; |
765 | 0 | } |
766 | | |
767 | | Adaptive_Data_Model::Adaptive_Data_Model(unsigned number_of_symbols) |
768 | 0 | { |
769 | 0 | data_symbols = 0; |
770 | 0 | distribution = 0; |
771 | 0 | set_alphabet(number_of_symbols); |
772 | 0 | } |
773 | | |
774 | | Adaptive_Data_Model::~Adaptive_Data_Model(void) |
775 | 0 | { |
776 | 0 | delete [] distribution; |
777 | 0 | } |
778 | | |
779 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
780 | | |
781 | | void Adaptive_Data_Model::set_alphabet(unsigned number_of_symbols) |
782 | 0 | { |
783 | 0 | if ((number_of_symbols < 2) || (number_of_symbols > (1 << 11))) |
784 | 0 | AC_Error("invalid number of data symbols"); |
785 | | |
786 | 0 | if (data_symbols != number_of_symbols) { // assign memory for data model |
787 | 0 | data_symbols = number_of_symbols; |
788 | 0 | last_symbol = data_symbols - 1; |
789 | 0 | delete [] distribution; |
790 | | // define size of table for fast decoding |
791 | 0 | if (data_symbols > 16) { |
792 | 0 | unsigned table_bits = 3; |
793 | 0 | while (data_symbols > (1U << (table_bits + 2))) ++table_bits; |
794 | 0 | table_size = 1 << table_bits; |
795 | 0 | table_shift = DM__LengthShift - table_bits; |
796 | 0 | distribution = new unsigned[2*data_symbols+table_size+2]; |
797 | 0 | decoder_table = distribution + 2 * data_symbols; |
798 | 0 | } |
799 | 0 | else { // small alphabet: no table needed |
800 | 0 | decoder_table = 0; |
801 | 0 | table_size = table_shift = 0; |
802 | 0 | distribution = new unsigned[2*data_symbols]; |
803 | 0 | } |
804 | 0 | symbol_count = distribution + data_symbols; |
805 | 0 | } |
806 | |
|
807 | 0 | reset(); // initialize model |
808 | 0 | } |
809 | | |
810 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
811 | | |
812 | | void Adaptive_Data_Model::update(bool from_encoder) |
813 | 0 | { |
814 | | // halve counts when a threshold is reached |
815 | |
|
816 | 0 | if ((total_count += update_cycle) > DM__MaxCount) { |
817 | 0 | total_count = 0; |
818 | 0 | for (unsigned n = 0; n < data_symbols; n++) |
819 | 0 | total_count += (symbol_count[n] = (symbol_count[n] + 1) >> 1); |
820 | 0 | } |
821 | 0 | assert(total_count > 0); |
822 | | // compute cumulative distribution, decoder table |
823 | 0 | unsigned k, sum = 0, s = 0; |
824 | 0 | unsigned scale = 0x80000000U / total_count; |
825 | |
|
826 | 0 | if (from_encoder || (table_size == 0)) |
827 | 0 | for (k = 0; k < data_symbols; k++) { |
828 | 0 | distribution[k] = (scale * sum) >> (31 - DM__LengthShift); |
829 | 0 | sum += symbol_count[k]; |
830 | 0 | } |
831 | 0 | else { |
832 | 0 | assert(decoder_table); |
833 | 0 | for (k = 0; k < data_symbols; k++) { |
834 | 0 | distribution[k] = (scale * sum) >> (31 - DM__LengthShift); |
835 | 0 | sum += symbol_count[k]; |
836 | 0 | unsigned w = distribution[k] >> table_shift; |
837 | 0 | while (s < w) decoder_table[++s] = k - 1; |
838 | 0 | } |
839 | 0 | decoder_table[0] = 0; |
840 | 0 | while (s <= table_size) decoder_table[++s] = data_symbols - 1; |
841 | 0 | } |
842 | | // set frequency of model updates |
843 | 0 | update_cycle = (5 * update_cycle) >> 2; |
844 | 0 | unsigned max_cycle = (data_symbols + 6) << 3; |
845 | 0 | if (update_cycle > max_cycle) update_cycle = max_cycle; |
846 | 0 | symbols_until_update = update_cycle; |
847 | 0 | } |
848 | | |
849 | | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
850 | | |
851 | | void Adaptive_Data_Model::reset(void) |
852 | 0 | { |
853 | 0 | if (data_symbols == 0) return; |
854 | | |
855 | | // restore probability estimates to uniform distribution |
856 | 0 | total_count = 0; |
857 | 0 | update_cycle = data_symbols; |
858 | 0 | for (unsigned k = 0; k < data_symbols; k++) symbol_count[k] = 1; |
859 | 0 | update(false); |
860 | 0 | symbols_until_update = update_cycle = (data_symbols + 6) >> 1; |
861 | 0 | } |
862 | | } |
863 | | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |