Coverage Report

Created: 2025-08-26 07:03

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