Coverage Report

Created: 2025-07-12 07:11

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