Coverage Report

Created: 2026-09-01 07:47

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
959M
static int ec_write_byte(ec_enc *_this,unsigned _value){
61
959M
  if(_this->offs+_this->end_offs>=_this->storage)return -1;
62
951M
  _this->buf[_this->offs++]=(unsigned char)_value;
63
951M
  return 0;
64
959M
}
65
66
91.5M
static int ec_write_byte_at_end(ec_enc *_this,unsigned _value){
67
91.5M
  if(_this->offs+_this->end_offs>=_this->storage)return -1;
68
91.5M
  _this->buf[_this->storage-++(_this->end_offs)]=(unsigned char)_value;
69
91.5M
  return 0;
70
91.5M
}
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.13G
static void ec_enc_carry_out(ec_enc *_this,int _c){
83
1.13G
  if(_c!=EC_SYM_MAX){
84
    /*No further carry propagation possible, flush buffer.*/
85
1.00G
    int carry;
86
1.00G
    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.00G
    if(_this->rem>=0)_this->error|=ec_write_byte(_this,_this->rem+carry);
90
1.00G
    if(_this->ext>0){
91
121M
      unsigned sym;
92
121M
      sym=(EC_SYM_MAX+carry)&EC_SYM_MAX;
93
121M
      do _this->error|=ec_write_byte(_this,sym);
94
121M
      while(--(_this->ext)>0);
95
121M
    }
96
1.00G
    _this->rem=_c&EC_SYM_MAX;
97
1.00G
  }
98
121M
  else _this->ext++;
99
1.13G
}
100
101
3.90G
static OPUS_INLINE void ec_enc_normalize(ec_enc *_this){
102
  /*If the range is too small, output some bits and rescale it.*/
103
4.69G
  while(_this->rng<=EC_CODE_BOT){
104
789M
    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
789M
    _this->val=(_this->val<<EC_SYM_BITS)&(EC_CODE_TOP-1);
107
789M
    _this->rng<<=EC_SYM_BITS;
108
789M
    _this->nbits_total+=EC_SYM_BITS;
109
789M
  }
110
3.90G
}
111
112
243M
void ec_enc_init(ec_enc *_this,unsigned char *_buf,opus_uint32 _size){
113
243M
  _this->buf=_buf;
114
243M
  _this->end_offs=0;
115
243M
  _this->end_window=0;
116
243M
  _this->nend_bits=0;
117
  /*This is the offset from which ec_tell() will subtract partial bits.*/
118
243M
  _this->nbits_total=EC_CODE_BITS+1;
119
243M
  _this->offs=0;
120
243M
  _this->rng=EC_CODE_TOP;
121
243M
  _this->rem=-1;
122
243M
  _this->val=0;
123
243M
  _this->ext=0;
124
243M
  _this->storage=_size;
125
243M
  _this->error=0;
126
243M
}
127
128
121M
void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft){
129
121M
  opus_uint32 r;
130
121M
  r=celt_udiv(_this->rng,_ft);
131
121M
  if(_fl>0){
132
91.9M
    _this->val+=_this->rng-IMUL32(r,(_ft-_fl));
133
91.9M
    _this->rng=IMUL32(r,(_fh-_fl));
134
91.9M
  }
135
29.0M
  else _this->rng-=IMUL32(r,(_ft-_fh));
136
121M
  ec_enc_normalize(_this);
137
121M
}
138
139
98.4M
void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits){
140
98.4M
  opus_uint32 r;
141
98.4M
  r=_this->rng>>_bits;
142
98.4M
  if(_fl>0){
143
65.3M
    _this->val+=_this->rng-IMUL32(r,((1U<<_bits)-_fl));
144
65.3M
    _this->rng=IMUL32(r,(_fh-_fl));
145
65.3M
  }
146
33.1M
  else _this->rng-=IMUL32(r,((1U<<_bits)-_fh));
147
98.4M
  ec_enc_normalize(_this);
148
98.4M
}
149
150
/*The probability of having a "one" is 1/(1<<_logp).*/
151
280M
void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp){
152
280M
  opus_uint32 r;
153
280M
  opus_uint32 s;
154
280M
  opus_uint32 l;
155
280M
  r=_this->rng;
156
280M
  l=_this->val;
157
280M
  s=r>>_logp;
158
280M
  r-=s;
159
280M
  if(_val)_this->val=l+r;
160
280M
  _this->rng=_val?s:r;
161
280M
  ec_enc_normalize(_this);
162
280M
}
163
164
3.40G
void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb){
165
3.40G
  opus_uint32 r;
166
3.40G
  r=_this->rng>>_ftb;
167
3.40G
  if(_s>0){
168
1.94G
    _this->val+=_this->rng-IMUL32(r,_icdf[_s-1]);
169
1.94G
    _this->rng=IMUL32(r,_icdf[_s-1]-_icdf[_s]);
170
1.94G
  }
171
1.45G
  else _this->rng-=IMUL32(r,_icdf[_s]);
172
3.40G
  ec_enc_normalize(_this);
173
3.40G
}
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
82.6M
void ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft){
187
82.6M
  unsigned  ft;
188
82.6M
  unsigned  fl;
189
82.6M
  int       ftb;
190
  /*In order to optimize EC_ILOG(), it is undefined for the value 0.*/
191
82.6M
  celt_assert(_ft>1);
192
82.6M
  _ft--;
193
82.6M
  ftb=EC_ILOG(_ft);
194
82.6M
  if(ftb>EC_UINT_BITS){
195
55.3M
    ftb-=EC_UINT_BITS;
196
55.3M
    ft=(_ft>>ftb)+1;
197
55.3M
    fl=(unsigned)(_fl>>ftb);
198
55.3M
    ec_encode(_this,fl,fl+1,ft);
199
55.3M
    ec_enc_bits(_this,_fl&(((opus_uint32)1<<ftb)-1U),ftb);
200
55.3M
  }
201
27.3M
  else ec_encode(_this,_fl,_fl+1,_ft+1);
202
82.6M
}
203
204
141M
void ec_enc_bits(ec_enc *_this,opus_uint32 _fl,unsigned _bits){
205
141M
  ec_window window;
206
141M
  int       used;
207
141M
  window=_this->end_window;
208
141M
  used=_this->nend_bits;
209
141M
  celt_assert(_bits>0);
210
141M
  if(used+_bits>EC_WINDOW_SIZE){
211
78.2M
    do{
212
78.2M
      _this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX);
213
78.2M
      window>>=EC_SYM_BITS;
214
78.2M
      used-=EC_SYM_BITS;
215
78.2M
    }
216
78.2M
    while(used>=EC_SYM_BITS);
217
27.6M
  }
218
141M
  window|=(ec_window)_fl<<used;
219
141M
  used+=_bits;
220
141M
  _this->end_window=window;
221
141M
  _this->nend_bits=used;
222
141M
  _this->nbits_total+=_bits;
223
141M
}
224
225
47.9M
void ec_enc_patch_initial_bits(ec_enc *_this,unsigned _val,unsigned _nbits){
226
47.9M
  int      shift;
227
47.9M
  unsigned mask;
228
47.9M
  celt_assert(_nbits<=EC_SYM_BITS);
229
47.9M
  shift=EC_SYM_BITS-_nbits;
230
47.9M
  mask=((1<<_nbits)-1)<<shift;
231
47.9M
  if(_this->offs>0){
232
    /*The first byte has been finalized.*/
233
47.9M
    _this->buf[0]=(unsigned char)((_this->buf[0]&~mask)|_val<<shift);
234
47.9M
  }
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
47.9M
}
247
248
286M
void ec_enc_shrink(ec_enc *_this,opus_uint32 _size){
249
286M
  celt_assert(_this->offs+_this->end_offs<=_size);
250
286M
  OPUS_MOVE(_this->buf+_size-_this->end_offs,
251
286M
   _this->buf+_this->storage-_this->end_offs,_this->end_offs);
252
286M
  _this->storage=_size;
253
286M
}
254
255
243M
void ec_enc_done(ec_enc *_this){
256
243M
  ec_window   window;
257
243M
  int         used;
258
243M
  opus_uint32 msk;
259
243M
  opus_uint32 end;
260
243M
  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
243M
  l=EC_CODE_BITS-EC_ILOG(_this->rng);
264
243M
  msk=(EC_CODE_TOP-1)>>l;
265
243M
  end=(_this->val+msk)&~msk;
266
243M
  if((end|msk)>=_this->val+_this->rng){
267
22.7M
    l++;
268
22.7M
    msk>>=1;
269
22.7M
    end=(_this->val+msk)&~msk;
270
22.7M
  }
271
416M
  while(l>0){
272
173M
    ec_enc_carry_out(_this,(int)(end>>EC_CODE_SHIFT));
273
173M
    end=(end<<EC_SYM_BITS)&(EC_CODE_TOP-1);
274
173M
    l-=EC_SYM_BITS;
275
173M
  }
276
  /*If we have a buffered byte flush it into the output buffer.*/
277
243M
  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
243M
  window=_this->end_window;
280
243M
  used=_this->nend_bits;
281
257M
  while(used>=EC_SYM_BITS){
282
13.3M
    _this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX);
283
13.3M
    window>>=EC_SYM_BITS;
284
13.3M
    used-=EC_SYM_BITS;
285
13.3M
  }
286
  /*Clear any excess space and add any remaining extra bits to the last byte.*/
287
243M
  if(!_this->error){
288
243M
    if (_this->buf) OPUS_CLEAR(_this->buf+_this->offs,
289
243M
     _this->storage-_this->offs-_this->end_offs);
290
243M
    if(used>0){
291
      /*If there's no range coder data at all, give up.*/
292
5.61M
      if(_this->end_offs>=_this->storage)_this->error=-1;
293
5.61M
      else{
294
5.61M
        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
5.61M
        if(_this->offs+_this->end_offs>=_this->storage&&l<used){
298
0
          window&=(1<<l)-1;
299
0
          _this->error=-1;
300
0
        }
301
5.61M
        _this->buf[_this->storage-_this->end_offs-1]|=(unsigned char)window;
302
5.61M
      }
303
5.61M
    }
304
243M
  }
305
243M
}