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