Coverage Report

Created: 2026-01-10 07:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opus/celt/entenc.c
Line
Count
Source
1
/* Copyright (c) 2001-2011 Timothy B. Terriberry
2
   Copyright (c) 2008-2009 Xiph.Org Foundation */
3
/*
4
   Redistribution and use in source and binary forms, with or without
5
   modification, are permitted provided that the following conditions
6
   are met:
7
8
   - Redistributions of source code must retain the above copyright
9
   notice, this list of conditions and the following disclaimer.
10
11
   - Redistributions in binary form must reproduce the above copyright
12
   notice, this list of conditions and the following disclaimer in the
13
   documentation and/or other materials provided with the distribution.
14
15
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18
   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19
   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
*/
27
28
#if defined(HAVE_CONFIG_H)
29
# include "config.h"
30
#endif
31
#include "os_support.h"
32
#include "arch.h"
33
#include "entenc.h"
34
#include "mfrngcod.h"
35
36
/*A range encoder.
37
  See entdec.c and the references for implementation details \cite{Mar79,MNW98}.
38
39
  @INPROCEEDINGS{Mar79,
40
   author="Martin, G.N.N.",
41
   title="Range encoding: an algorithm for removing redundancy from a digitised
42
    message",
43
   booktitle="Video \& Data Recording Conference",
44
   year=1979,
45
   address="Southampton",
46
   month=Jul
47
  }
48
  @ARTICLE{MNW98,
49
   author="Alistair Moffat and Radford Neal and Ian H. Witten",
50
   title="Arithmetic Coding Revisited",
51
   journal="{ACM} Transactions on Information Systems",
52
   year=1998,
53
   volume=16,
54
   number=3,
55
   pages="256--294",
56
   month=Jul,
57
   URL="http://www.stanford.edu/class/ee398/handouts/papers/Moffat98ArithmCoding.pdf"
58
  }*/
59
60
1.12G
static int ec_write_byte(ec_enc *_this,unsigned _value){
61
1.12G
  if(_this->offs+_this->end_offs>=_this->storage)return -1;
62
1.12G
  _this->buf[_this->offs++]=(unsigned char)_value;
63
1.12G
  return 0;
64
1.12G
}
65
66
327M
static int ec_write_byte_at_end(ec_enc *_this,unsigned _value){
67
327M
  if(_this->offs+_this->end_offs>=_this->storage)return -1;
68
327M
  _this->buf[_this->storage-++(_this->end_offs)]=(unsigned char)_value;
69
327M
  return 0;
70
327M
}
71
72
/*Outputs a symbol, with a carry bit.
73
  If there is a potential to propagate a carry over several symbols, they are
74
   buffered until it can be determined whether or not an actual carry will
75
   occur.
76
  If the counter for the buffered symbols overflows, then the stream becomes
77
   undecodable.
78
  This gives a theoretical limit of a few billion symbols in a single packet on
79
   32-bit systems.
80
  The alternative is to truncate the range in order to force a carry, but
81
   requires similar carry tracking in the decoder, needlessly slowing it down.*/
82
1.20G
static void ec_enc_carry_out(ec_enc *_this,int _c){
83
1.20G
  if(_c!=EC_SYM_MAX){
84
    /*No further carry propagation possible, flush buffer.*/
85
1.18G
    int carry;
86
1.18G
    carry=_c>>EC_SYM_BITS;
87
    /*Don't output a byte on the first write.
88
      This compare should be taken care of by branch-prediction thereafter.*/
89
1.18G
    if(_this->rem>=0)_this->error|=ec_write_byte(_this,_this->rem+carry);
90
1.18G
    if(_this->ext>0){
91
19.1M
      unsigned sym;
92
19.1M
      sym=(EC_SYM_MAX+carry)&EC_SYM_MAX;
93
19.1M
      do _this->error|=ec_write_byte(_this,sym);
94
19.1M
      while(--(_this->ext)>0);
95
19.1M
    }
96
1.18G
    _this->rem=_c&EC_SYM_MAX;
97
1.18G
  }
98
19.1M
  else _this->ext++;
99
1.20G
}
100
101
4.07G
static OPUS_INLINE void ec_enc_normalize(ec_enc *_this){
102
  /*If the range is too small, output some bits and rescale it.*/
103
5.14G
  while(_this->rng<=EC_CODE_BOT){
104
1.07G
    ec_enc_carry_out(_this,(int)(_this->val>>EC_CODE_SHIFT));
105
    /*Move the next-to-high-order symbol into the high-order position.*/
106
1.07G
    _this->val=(_this->val<<EC_SYM_BITS)&(EC_CODE_TOP-1);
107
1.07G
    _this->rng<<=EC_SYM_BITS;
108
1.07G
    _this->nbits_total+=EC_SYM_BITS;
109
1.07G
  }
110
4.07G
}
111
112
70.0M
void ec_enc_init(ec_enc *_this,unsigned char *_buf,opus_uint32 _size){
113
70.0M
  _this->buf=_buf;
114
70.0M
  _this->end_offs=0;
115
70.0M
  _this->end_window=0;
116
70.0M
  _this->nend_bits=0;
117
  /*This is the offset from which ec_tell() will subtract partial bits.*/
118
70.0M
  _this->nbits_total=EC_CODE_BITS+1;
119
70.0M
  _this->offs=0;
120
70.0M
  _this->rng=EC_CODE_TOP;
121
70.0M
  _this->rem=-1;
122
70.0M
  _this->val=0;
123
70.0M
  _this->ext=0;
124
70.0M
  _this->storage=_size;
125
70.0M
  _this->error=0;
126
70.0M
}
127
128
555M
void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft){
129
555M
  opus_uint32 r;
130
555M
  r=celt_udiv(_this->rng,_ft);
131
555M
  if(_fl>0){
132
154M
    _this->val+=_this->rng-IMUL32(r,(_ft-_fl));
133
154M
    _this->rng=IMUL32(r,(_fh-_fl));
134
154M
  }
135
401M
  else _this->rng-=IMUL32(r,(_ft-_fh));
136
555M
  ec_enc_normalize(_this);
137
555M
}
138
139
890M
void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits){
140
890M
  opus_uint32 r;
141
890M
  r=_this->rng>>_bits;
142
890M
  if(_fl>0){
143
576M
    _this->val+=_this->rng-IMUL32(r,((1U<<_bits)-_fl));
144
576M
    _this->rng=IMUL32(r,(_fh-_fl));
145
576M
  }
146
314M
  else _this->rng-=IMUL32(r,((1U<<_bits)-_fh));
147
890M
  ec_enc_normalize(_this);
148
890M
}
149
150
/*The probability of having a "one" is 1/(1<<_logp).*/
151
1.27G
void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp){
152
1.27G
  opus_uint32 r;
153
1.27G
  opus_uint32 s;
154
1.27G
  opus_uint32 l;
155
1.27G
  r=_this->rng;
156
1.27G
  l=_this->val;
157
1.27G
  s=r>>_logp;
158
1.27G
  r-=s;
159
1.27G
  if(_val)_this->val=l+r;
160
1.27G
  _this->rng=_val?s:r;
161
1.27G
  ec_enc_normalize(_this);
162
1.27G
}
163
164
1.34G
void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb){
165
1.34G
  opus_uint32 r;
166
1.34G
  r=_this->rng>>_ftb;
167
1.34G
  if(_s>0){
168
778M
    _this->val+=_this->rng-IMUL32(r,_icdf[_s-1]);
169
778M
    _this->rng=IMUL32(r,_icdf[_s-1]-_icdf[_s]);
170
778M
  }
171
570M
  else _this->rng-=IMUL32(r,_icdf[_s]);
172
1.34G
  ec_enc_normalize(_this);
173
1.34G
}
174
175
0
void ec_enc_icdf16(ec_enc *_this,int _s,const opus_uint16 *_icdf,unsigned _ftb){
176
0
  opus_uint32 r;
177
0
  r=_this->rng>>_ftb;
178
0
  if(_s>0){
179
0
    _this->val+=_this->rng-IMUL32(r,_icdf[_s-1]);
180
0
    _this->rng=IMUL32(r,_icdf[_s-1]-_icdf[_s]);
181
0
  }
182
0
  else _this->rng-=IMUL32(r,_icdf[_s]);
183
0
  ec_enc_normalize(_this);
184
0
}
185
186
396M
void ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft){
187
396M
  unsigned  ft;
188
396M
  unsigned  fl;
189
396M
  int       ftb;
190
  /*In order to optimize EC_ILOG(), it is undefined for the value 0.*/
191
396M
  celt_assert(_ft>1);
192
396M
  _ft--;
193
396M
  ftb=EC_ILOG(_ft);
194
396M
  if(ftb>EC_UINT_BITS){
195
199M
    ftb-=EC_UINT_BITS;
196
199M
    ft=(_ft>>ftb)+1;
197
199M
    fl=(unsigned)(_fl>>ftb);
198
199M
    ec_encode(_this,fl,fl+1,ft);
199
199M
    ec_enc_bits(_this,_fl&(((opus_uint32)1<<ftb)-1U),ftb);
200
199M
  }
201
197M
  else ec_encode(_this,_fl,_fl+1,_ft+1);
202
396M
}
203
204
871M
void ec_enc_bits(ec_enc *_this,opus_uint32 _fl,unsigned _bits){
205
871M
  ec_window window;
206
871M
  int       used;
207
871M
  window=_this->end_window;
208
871M
  used=_this->nend_bits;
209
871M
  celt_assert(_bits>0);
210
871M
  if(used+_bits>EC_WINDOW_SIZE){
211
279M
    do{
212
279M
      _this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX);
213
279M
      window>>=EC_SYM_BITS;
214
279M
      used-=EC_SYM_BITS;
215
279M
    }
216
279M
    while(used>=EC_SYM_BITS);
217
93.3M
  }
218
871M
  window|=(ec_window)_fl<<used;
219
871M
  used+=_bits;
220
871M
  _this->end_window=window;
221
871M
  _this->nend_bits=used;
222
871M
  _this->nbits_total+=_bits;
223
871M
}
224
225
19.5M
void ec_enc_patch_initial_bits(ec_enc *_this,unsigned _val,unsigned _nbits){
226
19.5M
  int      shift;
227
19.5M
  unsigned mask;
228
19.5M
  celt_assert(_nbits<=EC_SYM_BITS);
229
19.5M
  shift=EC_SYM_BITS-_nbits;
230
19.5M
  mask=((1<<_nbits)-1)<<shift;
231
19.5M
  if(_this->offs>0){
232
    /*The first byte has been finalized.*/
233
19.5M
    _this->buf[0]=(unsigned char)((_this->buf[0]&~mask)|_val<<shift);
234
19.5M
  }
235
0
  else if(_this->rem>=0){
236
    /*The first byte is still awaiting carry propagation.*/
237
0
    _this->rem=(_this->rem&~mask)|_val<<shift;
238
0
  }
239
0
  else if(_this->rng<=(EC_CODE_TOP>>_nbits)){
240
    /*The renormalization loop has never been run.*/
241
0
    _this->val=(_this->val&~((opus_uint32)mask<<EC_CODE_SHIFT))|
242
0
     (opus_uint32)_val<<(EC_CODE_SHIFT+shift);
243
0
  }
244
  /*The encoder hasn't even encoded _nbits of data yet.*/
245
0
  else _this->error=-1;
246
19.5M
}
247
248
94.1M
void ec_enc_shrink(ec_enc *_this,opus_uint32 _size){
249
94.1M
  celt_assert(_this->offs+_this->end_offs<=_size);
250
94.1M
  OPUS_MOVE(_this->buf+_size-_this->end_offs,
251
94.1M
   _this->buf+_this->storage-_this->end_offs,_this->end_offs);
252
94.1M
  _this->storage=_size;
253
94.1M
}
254
255
62.4M
void ec_enc_done(ec_enc *_this){
256
62.4M
  ec_window   window;
257
62.4M
  int         used;
258
62.4M
  opus_uint32 msk;
259
62.4M
  opus_uint32 end;
260
62.4M
  int         l;
261
  /*We output the minimum number of bits that ensures that the symbols encoded
262
     thus far will be decoded correctly regardless of the bits that follow.*/
263
62.4M
  l=EC_CODE_BITS-EC_ILOG(_this->rng);
264
62.4M
  msk=(EC_CODE_TOP-1)>>l;
265
62.4M
  end=(_this->val+msk)&~msk;
266
62.4M
  if((end|msk)>=_this->val+_this->rng){
267
11.8M
    l++;
268
11.8M
    msk>>=1;
269
11.8M
    end=(_this->val+msk)&~msk;
270
11.8M
  }
271
126M
  while(l>0){
272
64.2M
    ec_enc_carry_out(_this,(int)(end>>EC_CODE_SHIFT));
273
64.2M
    end=(end<<EC_SYM_BITS)&(EC_CODE_TOP-1);
274
64.2M
    l-=EC_SYM_BITS;
275
64.2M
  }
276
  /*If we have a buffered byte flush it into the output buffer.*/
277
62.4M
  if(_this->rem>=0||_this->ext>0)ec_enc_carry_out(_this,0);
278
  /*If we have buffered extra bits, flush them as well.*/
279
62.4M
  window=_this->end_window;
280
62.4M
  used=_this->nend_bits;
281
110M
  while(used>=EC_SYM_BITS){
282
48.4M
    _this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX);
283
48.4M
    window>>=EC_SYM_BITS;
284
48.4M
    used-=EC_SYM_BITS;
285
48.4M
  }
286
  /*Clear any excess space and add any remaining extra bits to the last byte.*/
287
62.4M
  if(!_this->error){
288
62.4M
    if (_this->buf) OPUS_CLEAR(_this->buf+_this->offs,
289
62.4M
     _this->storage-_this->offs-_this->end_offs);
290
62.4M
    if(used>0){
291
      /*If there's no range coder data at all, give up.*/
292
30.8M
      if(_this->end_offs>=_this->storage)_this->error=-1;
293
30.8M
      else{
294
30.8M
        l=-l;
295
        /*If we've busted, don't add too many extra bits to the last byte; it
296
           would corrupt the range coder data, and that's more important.*/
297
30.8M
        if(_this->offs+_this->end_offs>=_this->storage&&l<used){
298
0
          window&=(1<<l)-1;
299
0
          _this->error=-1;
300
0
        }
301
30.8M
        _this->buf[_this->storage-_this->end_offs-1]|=(unsigned char)window;
302
30.8M
      }
303
30.8M
    }
304
62.4M
  }
305
62.4M
}