Coverage Report

Created: 2025-12-14 07:08

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