Coverage Report

Created: 2026-09-14 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/avm/avm_dsp/entdec.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2021, Alliance for Open Media. All rights reserved
3
 *
4
 * This source code is subject to the terms of the BSD 3-Clause Clear License
5
 * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
6
 * License was not distributed with this source code in the LICENSE file, you
7
 * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/.  If the
8
 * Alliance for Open Media Patent License 1.0 was not distributed with this
9
 * source code in the PATENTS file, you can obtain it at
10
 * aomedia.org/license/patent-license/.
11
 */
12
13
#include <assert.h>
14
#include "avm_dsp/entdec.h"
15
#include "avm_dsp/prob.h"
16
17
/*A range decoder.
18
  This is an entropy decoder based upon \cite{Mar79}, which is itself a
19
   rediscovery of the FIFO arithmetic code introduced by \cite{Pas76}.
20
  It is very similar to arithmetic encoding, except that encoding is done with
21
   digits in any base, instead of with bits, and so it is faster when using
22
   larger bases (i.e.: a byte).
23
  The author claims an average waste of $\frac{1}{2}\log_b(2b)$ bits, where $b$
24
   is the base, longer than the theoretical optimum, but to my knowledge there
25
   is no published justification for this claim.
26
  This only seems true when using near-infinite precision arithmetic so that
27
   the process is carried out with no rounding errors.
28
29
  An excellent description of implementation details is available at
30
   http://www.arturocampos.com/ac_range.html
31
  A recent work \cite{MNW98} which proposes several changes to arithmetic
32
   encoding for efficiency actually re-discovers many of the principles
33
   behind range encoding, and presents a good theoretical analysis of them.
34
35
  End of stream is handled by writing out the smallest number of bits that
36
   ensures that the stream will be correctly decoded regardless of the value of
37
   any subsequent bits.
38
  avm_od_ec_dec_tell() can be used to determine how many bits were needed to
39
  decode all the symbols thus far; other data can be packed in the remaining
40
  bits of the input buffer.
41
  @PHDTHESIS{Pas76,
42
    author="Richard Clark Pasco",
43
    title="Source coding algorithms for fast data compression",
44
    school="Dept. of Electrical Engineering, Stanford University",
45
    address="Stanford, CA",
46
    month=May,
47
    year=1976,
48
    URL="http://www.richpasco.org/scaffdc.pdf"
49
  }
50
  @INPROCEEDINGS{Mar79,
51
   author="Martin, G.N.N.",
52
   title="Range encoding: an algorithm for removing redundancy from a digitised
53
    message",
54
   booktitle="Video & Data Recording Conference",
55
   year=1979,
56
   address="Southampton",
57
   month=Jul,
58
   URL="http://www.compressconsult.com/rangecoder/rngcod.pdf.gz"
59
  }
60
  @ARTICLE{MNW98,
61
   author="Alistair Moffat and Radford Neal and Ian H. Witten",
62
   title="Arithmetic Coding Revisited",
63
   journal="{ACM} Transactions on Information Systems",
64
   year=1998,
65
   volume=16,
66
   number=3,
67
   pages="256--294",
68
   month=Jul,
69
   URL="http://researchcommons.waikato.ac.nz/bitstream/handle/10289/78/content.pdf"
70
  }*/
71
72
/*Initializes the decoder.
73
  buf: The input buffer to use.
74
  storage: The size in bytes of the input buffer.*/
75
void avm_od_ec_dec_init(od_ec_dec *dec, const unsigned char *buf,
76
17.4k
                        uint32_t storage) {
77
17.4k
  dec->buf = buf;
78
17.4k
  dec->end = buf + storage;
79
17.4k
  dec->bptr = buf;
80
17.4k
  dec->dif = ((od_ec_window)1 << (OD_EC_WINDOW_SIZE - 1)) - 1;
81
17.4k
  dec->rng = 0x8000;
82
17.4k
  dec->cnt = -15;
83
17.4k
  dec->tell_offs = dec->cnt + 1;
84
17.4k
  od_ec_dec_refill(dec);
85
17.4k
}
86
87
/*Decode a single binary value.
88
  f: The probability that the bit is one, scaled by 32768.
89
  Return: The value decoded (0 or 1).*/
90
0
int avm_od_ec_decode_bool_q15(od_ec_dec *dec, unsigned f) {
91
0
  od_ec_window dif;
92
0
  od_ec_window vw;
93
0
  unsigned r;
94
0
  unsigned r_new;
95
0
  unsigned v;
96
0
  int ret;
97
0
  assert(0 < f);
98
0
  assert(f < 32768U);
99
0
  dif = dec->dif;
100
0
  r = dec->rng;
101
0
  assert(dif >> (OD_EC_WINDOW_SIZE - 16) < r);
102
0
  assert(32768U <= r);
103
0
  v = od_ec_prob_scale(f, r, 0, 2);
104
0
  vw = (od_ec_window)v << (OD_EC_WINDOW_SIZE - 16);
105
0
  ret = 1;
106
0
  r_new = v;
107
0
  if (dif >= vw) {
108
0
    r_new = r - v;
109
0
    dif -= vw;
110
0
    ret = 0;
111
0
  }
112
0
  return od_ec_dec_normalize(dec, dif, r_new, ret);
113
0
}
114
115
/*Decode a single binary value, with 50/50 probability.
116
  Return: The value decoded (0 or 1).*/
117
0
int od_ec_decode_bool_bypass(od_ec_dec *dec) {
118
0
  return od_ec_decode_literal_bypass(dec, 1);
119
0
}
120
121
/*Decode a literal of n_bits
122
  n_bits: Number of bits to decode 1..8
123
  Return: The value decoded (0..2^n_bits-1).*/
124
4.47M
int od_ec_decode_literal_bypass(od_ec_dec *dec, int n_bits) {
125
4.47M
  od_ec_window dif;
126
4.47M
  od_ec_window vw;
127
4.47M
  unsigned r;
128
4.47M
  int ret;
129
4.47M
  dif = dec->dif;
130
4.47M
  r = dec->rng;
131
4.47M
  assert((r & 1) == 0);
132
4.47M
  assert(dif >> (OD_EC_WINDOW_SIZE - 16) < r);
133
4.47M
  assert(32768U <= r);
134
4.47M
  assert(0 < n_bits && n_bits <= 32);
135
4.47M
  vw = (od_ec_window)r << (OD_EC_WINDOW_SIZE - 16);
136
4.47M
  ret = 0;
137
9.69M
  for (int bit = 0; bit < n_bits; bit++) {
138
5.21M
    vw >>= 1;
139
5.21M
    ret <<= 1;
140
5.21M
    if (dif >= vw) {
141
2.68M
      dif -= vw;
142
2.68M
    } else {
143
2.53M
      ret |= 1;
144
2.53M
    }
145
5.21M
  }
146
4.47M
  return od_ec_dec_bypass_normalize(dec, dif, n_bits, ret);
147
4.47M
}
148
149
/*Decode unary-coded symbol.
150
  max_bits: Max number of decoded bits.
151
  Return: The value decoded (0..2^n_bits-1).*/
152
OD_WARN_UNUSED_RESULT int od_ec_decode_unary_bypass(od_ec_dec *dec,
153
                                                    int max_bits)
154
    OD_ARG_NONNULL(1);
155
196k
int od_ec_decode_unary_bypass(od_ec_dec *dec, int max_bits) {
156
196k
  if (dec->cnt < max_bits - 1) od_ec_dec_refill(dec);
157
196k
  od_ec_window dif;
158
196k
  od_ec_window vw;
159
196k
  unsigned r;
160
196k
  int ret;
161
196k
  dif = dec->dif;
162
196k
  r = dec->rng;
163
196k
  assert((r & 1) == 0);
164
196k
  assert(dif >> (OD_EC_WINDOW_SIZE - 16) < r);
165
196k
  assert(32768U <= r);
166
196k
  assert((0 < max_bits) && (max_bits <= 32));
167
196k
  vw = (od_ec_window)r << (OD_EC_WINDOW_SIZE - 16);
168
196k
  ret = 0;
169
196k
  int bit;
170
394k
  for (bit = 0; bit < max_bits; bit++) {
171
388k
    vw >>= 1;
172
388k
    if (dif >= vw) {
173
198k
      dif -= vw;
174
198k
      ret++;
175
198k
    } else {
176
189k
      bit++;
177
189k
      break;
178
189k
    }
179
388k
  }
180
196k
  return od_ec_dec_bypass_normalize(dec, dif, bit, ret);
181
196k
}
182
183
/*Decodes a symbol given an inverse cumulative distribution function (CDF)
184
   table in Q15.
185
  icdf: CDF_PROB_TOP minus the CDF, such that symbol s falls in the range
186
         [s > 0 ? (CDF_PROB_TOP - icdf[s - 1]) : 0, CDF_PROB_TOP - icdf[s]).
187
        The values must be monotonically non-increasing, and icdf[nsyms - 1]
188
         must be 0.
189
  nsyms: The number of symbols in the alphabet.
190
         This should be at most 16.
191
  Return: The decoded symbol s.*/
192
int avm_od_ec_decode_cdf_q15_c(od_ec_dec *dec, const uint16_t *icdf,
193
0
                               int nsyms) {
194
0
  od_ec_window dif;
195
0
  unsigned r;
196
0
  unsigned c;
197
0
  unsigned u;
198
0
  unsigned v;
199
0
  int ret;
200
0
  (void)nsyms;
201
0
  dif = dec->dif;
202
0
  r = dec->rng;
203
204
0
  assert(dif >> (OD_EC_WINDOW_SIZE - 16) < r);
205
0
  assert(icdf[nsyms - 1] == OD_ICDF(CDF_PROB_TOP));
206
0
  assert(32768U <= r);
207
0
  assert(7 - EC_PROB_SHIFT - CDF_SHIFT >= 0);
208
0
  c = (unsigned)(dif >> (OD_EC_WINDOW_SIZE - 16));
209
0
  v = r;
210
0
  ret = -1;
211
0
  do {
212
0
    u = v;
213
0
    ret++;
214
0
    v = od_ec_prob_scale(icdf[ret], r, ret, nsyms);
215
0
  } while (c < v);
216
0
  assert(v < u);
217
0
  assert(u <= r);
218
0
  r = u - v;
219
0
  dif -= (od_ec_window)v << (OD_EC_WINDOW_SIZE - 16);
220
0
  return od_ec_dec_normalize(dec, dif, r, ret);
221
0
}
222
223
/*Returns the number of bits "used" by the decoded symbols so far.
224
  This same number can be computed in either the encoder or the decoder, and is
225
   suitable for making coding decisions.
226
  Return: The number of bits.
227
          This will always be slightly larger than the exact value (e.g., all
228
           rounding error is in the positive direction).*/
229
86.1k
int avm_od_ec_dec_tell(const od_ec_dec *dec) {
230
  /*There is a window of bits stored in dec->dif. The difference
231
     (dec->bptr - dec->buf) tells us how many bytes have been read into this
232
     window. The difference (dec->cnt - dec->tell_offs) tells us how many of
233
     the bits in that window remain unconsumed.*/
234
86.1k
  return (int)((dec->bptr - dec->buf) * 8 - dec->cnt + dec->tell_offs);
235
86.1k
}
236
237
/*Returns the number of bits "used" by the decoded symbols so far.
238
  This same number can be computed in either the encoder or the decoder, and is
239
   suitable for making coding decisions.
240
  Return: The number of bits scaled by 2**OD_BITRES.
241
          This will always be slightly larger than the exact value (e.g., all
242
           rounding error is in the positive direction).*/
243
0
uint64_t avm_od_ec_dec_tell_frac(const od_ec_dec *dec) {
244
0
  return avm_od_ec_tell_frac(avm_od_ec_dec_tell(dec), dec->rng);
245
0
}