arithmeticdecoder.cpp
Go to the documentation of this file.
1 /*
2 ===============================================================================
3 
4  FILE: arithmeticdecoder.cpp
5 
6  CONTENTS:
7 
8  A modular C++ wrapper for an adapted version of Amir Said's FastAC Code.
9  see: http://www.cipr.rpi.edu/~said/FastAC.html
10 
11  PROGRAMMERS:
12 
13  martin.isenburg@gmail.com
14 
15  COPYRIGHT:
16 
17  (c) 2011, Martin Isenburg, LASSO - tools to catch reality
18 
19  This is free software; you can redistribute and/or modify it under the
20  terms of the GNU Lesser General Licence as published by the Free Software
21  Foundation. See the COPYING file for more information.
22 
23  This software is distributed WITHOUT ANY WARRANTY and without even the
24  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
25 
26  CHANGE HISTORY:
27 
28  see header file
29 
30 ===============================================================================
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 #include "arithmeticdecoder.hpp"
71 
72 #include <string.h>
73 #include <assert.h>
74 
75 #include "arithmeticmodel.hpp"
76 
78 {
79  instream = 0;
80 }
81 
83 {
84  if (instream == 0) return FALSE;
85  this->instream = instream;
87  value = (instream->getByte() << 24);
88  value |= (instream->getByte() << 16);
89  value |= (instream->getByte() << 8);
90  value |= (instream->getByte());
91  return TRUE;
92 }
93 
95 {
96  instream = 0;
97 }
98 
100 {
102  return (EntropyModel*)m;
103 }
104 
105 void ArithmeticDecoder::initBitModel(EntropyModel* model)
106 {
108  m->init();
109 }
110 
111 void ArithmeticDecoder::destroyBitModel(EntropyModel* model)
112 {
114  delete m;
115 }
116 
118 {
119  ArithmeticModel* m = new ArithmeticModel(n, false);
120  return (EntropyModel*)m;
121 }
122 
123 void ArithmeticDecoder::initSymbolModel(EntropyModel* model, U32 *table)
124 {
125  ArithmeticModel* m = (ArithmeticModel*)model;
126  m->init(table);
127 }
128 
129 void ArithmeticDecoder::destroySymbolModel(EntropyModel* model)
130 {
131  ArithmeticModel* m = (ArithmeticModel*)model;
132  delete m;
133 }
134 
135 U32 ArithmeticDecoder::decodeBit(EntropyModel* model)
136 {
138  U32 x = m->bit_0_prob * (length >> BM__LengthShift); // product l x p0
139  U32 sym = (value >= x); // decision
140  // update & shift interval
141  if (sym == 0) {
142  length = x;
143  ++m->bit_0_count;
144  }
145  else {
146  value -= x; // shifted interval base = 0
147  length -= x;
148  }
149 
150  if (length < AC__MinLength) renorm_dec_interval(); // renormalization
151  if (--m->bits_until_update == 0) m->update(); // periodic model update
152 
153  return sym; // return data bit value
154 }
155 
157 {
158  ArithmeticModel* m = (ArithmeticModel*)model;
159  U32 n, sym, x, y = length;
160 
161  if (m->decoder_table) { // use table look-up for faster decoding
162 
163  unsigned dv = value / (length >>= DM__LengthShift);
164  unsigned t = dv >> m->table_shift;
165 
166  sym = m->decoder_table[t]; // initial decision based on table look-up
167  n = m->decoder_table[t+1] + 1;
168 
169  while (n > sym + 1) { // finish with bisection search
170  U32 k = (sym + n) >> 1;
171  if (m->distribution[k] > dv) n = k; else sym = k;
172  }
173  // compute products
174  x = m->distribution[sym] * length;
175  if (sym != m->last_symbol) y = m->distribution[sym+1] * length;
176  }
177 
178  else { // decode using only multiplications
179 
180  x = sym = 0;
182  U32 k = (n = m->symbols) >> 1;
183  // decode via bisection search
184  do {
185  U32 z = length * m->distribution[k];
186  if (z > value) {
187  n = k;
188  y = z; // value is smaller
189  }
190  else {
191  sym = k;
192  x = z; // value is larger or equal
193  }
194  } while ((k = (sym + n) >> 1) != sym);
195  }
196 
197  value -= x; // update interval
198  length = y - x;
199 
200  if (length < AC__MinLength) renorm_dec_interval(); // renormalization
201 
202  ++m->symbol_count[sym];
203  if (--m->symbols_until_update == 0) m->update(); // periodic model update
204 
205  return sym;
206 }
207 
209 {
210  U32 sym = value / (length >>= 1); // decode symbol, change length
211  value -= length * sym; // update interval
212 
213  if (length < AC__MinLength) renorm_dec_interval(); // renormalization
214 
215  return sym;
216 }
217 
219 {
220  assert(bits && (bits <= 32));
221 
222  if (bits > 19)
223  {
224  U32 tmp = readShort();
225  bits = bits - 16;
226  U32 tmp1 = readBits(bits) << 16;
227  return (tmp1|tmp);
228  }
229 
230  U32 sym = value / (length >>= bits);// decode symbol, change length
231  value -= length * sym; // update interval
232 
233  if (length < AC__MinLength) renorm_dec_interval(); // renormalization
234 
235  return sym;
236 }
237 
239 {
240  U32 sym = value / (length >>= 8); // decode symbol, change length
241  value -= length * sym; // update interval
242 
243  if (length < AC__MinLength) renorm_dec_interval(); // renormalization
244 
245  assert(sym < (1<<8));
246 
247  return (U8)sym;
248 }
249 
251 {
252  U32 sym = value / (length >>= 16); // decode symbol, change length
253  value -= length * sym; // update interval
254 
255  if (length < AC__MinLength) renorm_dec_interval(); // renormalization
256 
257  assert(sym < (1<<16));
258 
259  return (U16)sym;
260 }
261 
263 {
264  U32 lowerInt = readShort();
265  U32 upperInt = readShort();
266  return (upperInt<<16)|lowerInt;
267 }
268 
269 inline F32 ArithmeticDecoder::readFloat() /* danger in float reinterpretation */
270 {
271  U32I32F32 u32i32f32;
272  u32i32f32.u32 = readInt();
273  return u32i32f32.f32;
274 }
275 
277 {
278  U64 lowerInt = readInt();
279  U64 upperInt = readInt();
280  return (upperInt<<32)|lowerInt;
281 }
282 
283 inline F64 ArithmeticDecoder::readDouble() /* danger in float reinterpretation */
284 {
285  U64I64F64 u64i64f64;
286  u64i64f64.u64 = readInt64();
287  return u64i64f64.f64;
288 }
289 
291 {
292 
293 }
294 
296 {
297  do { // read least-significant byte
298  value = (value << 8) | instream->getByte();
299  } while ((length <<= 8) < AC__MinLength); // length multiplied by 256
300 }
ArithmeticDecoder::readBits
U32 readBits(U32 bits)
Definition: arithmeticdecoder.cpp:218
ByteStreamIn::getByte
virtual U32 getByte()=0
ArithmeticDecoder::length
U32 length
Definition: arithmeticdecoder.hpp:96
ArithmeticBitModel
Definition: arithmeticmodel.hpp:75
ArithmeticDecoder::initSymbolModel
void initSymbolModel(EntropyModel *model, U32 *table=0)
Definition: arithmeticdecoder.cpp:123
ArithmeticModel
Definition: arithmeticmodel.hpp:57
ArithmeticDecoder::init
BOOL init(ByteStreamIn *instream)
Definition: arithmeticdecoder.cpp:82
ArithmeticDecoder::~ArithmeticDecoder
~ArithmeticDecoder()
Definition: arithmeticdecoder.cpp:290
F64
double F64
Definition: mydefs.hpp:52
ArithmeticModel::last_symbol
U32 last_symbol
Definition: arithmeticmodel.hpp:69
U64I64F64::u64
U64 u64
Definition: mydefs.hpp:61
TRUE
#define TRUE
Definition: mydefs.hpp:137
ArithmeticDecoder::readDouble
F64 readDouble()
Definition: arithmeticdecoder.cpp:283
ArithmeticModel::table_shift
U32 table_shift
Definition: arithmeticmodel.hpp:69
ArithmeticDecoder::done
void done()
Definition: arithmeticdecoder.cpp:94
ArithmeticModel::decoder_table
U32 * decoder_table
Definition: arithmeticmodel.hpp:67
ArithmeticModel::distribution
U32 * distribution
Definition: arithmeticmodel.hpp:67
ArithmeticDecoder::value
U32 value
Definition: arithmeticdecoder.hpp:96
ArithmeticBitModel::bit_0_count
U32 bit_0_count
Definition: arithmeticmodel.hpp:86
ArithmeticDecoder::readInt
U32 readInt()
Definition: arithmeticdecoder.cpp:262
ArithmeticDecoder::renorm_dec_interval
void renorm_dec_interval()
Definition: arithmeticdecoder.cpp:295
ArithmeticDecoder::readShort
U16 readShort()
Definition: arithmeticdecoder.cpp:250
ArithmeticDecoder::ArithmeticDecoder
ArithmeticDecoder()
Definition: arithmeticdecoder.cpp:77
ArithmeticBitModel::init
void init()
Definition: arithmeticmodel.cpp:184
BM__LengthShift
const U32 BM__LengthShift
Definition: arithmeticmodel.hpp:50
ArithmeticDecoder::destroySymbolModel
void destroySymbolModel(EntropyModel *model)
Definition: arithmeticdecoder.cpp:129
ArithmeticDecoder::instream
ByteStreamIn * instream
Definition: arithmeticdecoder.hpp:93
ArithmeticDecoder::initBitModel
void initBitModel(EntropyModel *model)
Definition: arithmeticdecoder.cpp:105
ArithmeticDecoder::createSymbolModel
EntropyModel * createSymbolModel(U32 n)
Definition: arithmeticdecoder.cpp:117
ArithmeticModel::update
void update()
Definition: arithmeticmodel.cpp:131
ArithmeticDecoder::readByte
U8 readByte()
Definition: arithmeticdecoder.cpp:238
ArithmeticBitModel::bits_until_update
U32 bits_until_update
Definition: arithmeticmodel.hpp:85
ArithmeticDecoder::createBitModel
EntropyModel * createBitModel()
Definition: arithmeticdecoder.cpp:99
ArithmeticDecoder::destroyBitModel
void destroyBitModel(EntropyModel *model)
Definition: arithmeticdecoder.cpp:111
ArithmeticDecoder::readInt64
U64 readInt64()
Definition: arithmeticdecoder.cpp:276
ArithmeticModel::symbols_until_update
U32 symbols_until_update
Definition: arithmeticmodel.hpp:68
ArithmeticBitModel::update
void update()
Definition: arithmeticmodel.cpp:194
ByteStreamIn
Definition: bytestreamin.hpp:36
U16
unsigned short U16
Definition: mydefs.hpp:40
U8
unsigned char U8
Definition: mydefs.hpp:41
BOOL
int BOOL
Definition: mydefs.hpp:57
U64
unsigned long long U64
Definition: mydefs.hpp:47
U64I64F64
Definition: mydefs.hpp:61
AC__MinLength
const U32 AC__MinLength
Definition: arithmeticmodel.hpp:46
FALSE
#define FALSE
Definition: mydefs.hpp:133
F32
float F32
Definition: mydefs.hpp:51
ArithmeticDecoder::readFloat
F32 readFloat()
Definition: arithmeticdecoder.cpp:269
ArithmeticDecoder::decodeSymbol
U32 decodeSymbol(EntropyModel *model)
Definition: arithmeticdecoder.cpp:156
arithmeticmodel.hpp
U64I64F64::f64
F64 f64
Definition: mydefs.hpp:61
AC__MaxLength
const U32 AC__MaxLength
Definition: arithmeticmodel.hpp:47
ArithmeticModel::symbols
U32 symbols
Definition: arithmeticmodel.hpp:69
ArithmeticBitModel::bit_0_prob
U32 bit_0_prob
Definition: arithmeticmodel.hpp:86
U32I32F32::u32
U32 u32
Definition: mydefs.hpp:60
U32
unsigned int U32
Definition: mydefs.hpp:39
ArithmeticDecoder::decodeBit
U32 decodeBit(EntropyModel *model)
Definition: arithmeticdecoder.cpp:135
ArithmeticModel::init
I32 init(U32 *table=0)
Definition: arithmeticmodel.cpp:87
ArithmeticDecoder::readBit
U32 readBit()
Definition: arithmeticdecoder.cpp:208
arithmeticdecoder.hpp
DM__LengthShift
const U32 DM__LengthShift
Definition: arithmeticmodel.hpp:54
U32I32F32
Definition: mydefs.hpp:60
ArithmeticModel::symbol_count
U32 * symbol_count
Definition: arithmeticmodel.hpp:67
U32I32F32::f32
F32 f32
Definition: mydefs.hpp:60


lvr2
Author(s): Thomas Wiemann , Sebastian Pütz , Alexander Mock , Lars Kiesow , Lukas Kalbertodt , Tristan Igelbrink , Johan M. von Behren , Dominik Feldschnieders , Alexander Löhr
autogenerated on Wed Mar 2 2022 00:37:22