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 }
F64 f64
Definition: mydefs.hpp:61
int BOOL
Definition: mydefs.hpp:57
#define FALSE
Definition: mydefs.hpp:133
BOOL init(ByteStreamIn *instream)
float F32
Definition: mydefs.hpp:51
I32 init(U32 *table=0)
const U32 BM__LengthShift
unsigned int U32
Definition: mydefs.hpp:39
void destroySymbolModel(EntropyModel *model)
ByteStreamIn * instream
void initSymbolModel(EntropyModel *model, U32 *table=0)
EntropyModel * createSymbolModel(U32 n)
unsigned short U16
Definition: mydefs.hpp:40
void destroyBitModel(EntropyModel *model)
unsigned char U8
Definition: mydefs.hpp:41
EntropyModel * createBitModel()
void initBitModel(EntropyModel *model)
U32 u32
Definition: mydefs.hpp:60
U32 decodeSymbol(EntropyModel *model)
F32 f32
Definition: mydefs.hpp:60
const U32 AC__MaxLength
const U32 AC__MinLength
U32 decodeBit(EntropyModel *model)
const U32 DM__LengthShift
#define TRUE
Definition: mydefs.hpp:137
U64 u64
Definition: mydefs.hpp:61
unsigned long long U64
Definition: mydefs.hpp:47
virtual U32 getByte()=0
double F64
Definition: mydefs.hpp:52


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 Mon Feb 28 2022 22:46:06