LCOV - code coverage report
Current view: top level - media/libopus/celt - entenc.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 147 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 14 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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           0 : static int ec_write_byte(ec_enc *_this,unsigned _value){
      61           0 :   if(_this->offs+_this->end_offs>=_this->storage)return -1;
      62           0 :   _this->buf[_this->offs++]=(unsigned char)_value;
      63           0 :   return 0;
      64             : }
      65             : 
      66           0 : static int ec_write_byte_at_end(ec_enc *_this,unsigned _value){
      67           0 :   if(_this->offs+_this->end_offs>=_this->storage)return -1;
      68           0 :   _this->buf[_this->storage-++(_this->end_offs)]=(unsigned char)_value;
      69           0 :   return 0;
      70             : }
      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           0 : static void ec_enc_carry_out(ec_enc *_this,int _c){
      83           0 :   if(_c!=EC_SYM_MAX){
      84             :     /*No further carry propagation possible, flush buffer.*/
      85             :     int carry;
      86           0 :     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           0 :     if(_this->rem>=0)_this->error|=ec_write_byte(_this,_this->rem+carry);
      90           0 :     if(_this->ext>0){
      91             :       unsigned sym;
      92           0 :       sym=(EC_SYM_MAX+carry)&EC_SYM_MAX;
      93           0 :       do _this->error|=ec_write_byte(_this,sym);
      94           0 :       while(--(_this->ext)>0);
      95             :     }
      96           0 :     _this->rem=_c&EC_SYM_MAX;
      97             :   }
      98           0 :   else _this->ext++;
      99           0 : }
     100             : 
     101           0 : static OPUS_INLINE void ec_enc_normalize(ec_enc *_this){
     102             :   /*If the range is too small, output some bits and rescale it.*/
     103           0 :   while(_this->rng<=EC_CODE_BOT){
     104           0 :     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           0 :     _this->val=(_this->val<<EC_SYM_BITS)&(EC_CODE_TOP-1);
     107           0 :     _this->rng<<=EC_SYM_BITS;
     108           0 :     _this->nbits_total+=EC_SYM_BITS;
     109             :   }
     110           0 : }
     111             : 
     112           0 : void ec_enc_init(ec_enc *_this,unsigned char *_buf,opus_uint32 _size){
     113           0 :   _this->buf=_buf;
     114           0 :   _this->end_offs=0;
     115           0 :   _this->end_window=0;
     116           0 :   _this->nend_bits=0;
     117             :   /*This is the offset from which ec_tell() will subtract partial bits.*/
     118           0 :   _this->nbits_total=EC_CODE_BITS+1;
     119           0 :   _this->offs=0;
     120           0 :   _this->rng=EC_CODE_TOP;
     121           0 :   _this->rem=-1;
     122           0 :   _this->val=0;
     123           0 :   _this->ext=0;
     124           0 :   _this->storage=_size;
     125           0 :   _this->error=0;
     126           0 : }
     127             : 
     128           0 : void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft){
     129             :   opus_uint32 r;
     130           0 :   r=celt_udiv(_this->rng,_ft);
     131           0 :   if(_fl>0){
     132           0 :     _this->val+=_this->rng-IMUL32(r,(_ft-_fl));
     133           0 :     _this->rng=IMUL32(r,(_fh-_fl));
     134             :   }
     135           0 :   else _this->rng-=IMUL32(r,(_ft-_fh));
     136           0 :   ec_enc_normalize(_this);
     137           0 : }
     138             : 
     139           0 : void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits){
     140             :   opus_uint32 r;
     141           0 :   r=_this->rng>>_bits;
     142           0 :   if(_fl>0){
     143           0 :     _this->val+=_this->rng-IMUL32(r,((1U<<_bits)-_fl));
     144           0 :     _this->rng=IMUL32(r,(_fh-_fl));
     145             :   }
     146           0 :   else _this->rng-=IMUL32(r,((1U<<_bits)-_fh));
     147           0 :   ec_enc_normalize(_this);
     148           0 : }
     149             : 
     150             : /*The probability of having a "one" is 1/(1<<_logp).*/
     151           0 : void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp){
     152             :   opus_uint32 r;
     153             :   opus_uint32 s;
     154             :   opus_uint32 l;
     155           0 :   r=_this->rng;
     156           0 :   l=_this->val;
     157           0 :   s=r>>_logp;
     158           0 :   r-=s;
     159           0 :   if(_val)_this->val=l+r;
     160           0 :   _this->rng=_val?s:r;
     161           0 :   ec_enc_normalize(_this);
     162           0 : }
     163             : 
     164           0 : void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb){
     165             :   opus_uint32 r;
     166           0 :   r=_this->rng>>_ftb;
     167           0 :   if(_s>0){
     168           0 :     _this->val+=_this->rng-IMUL32(r,_icdf[_s-1]);
     169           0 :     _this->rng=IMUL32(r,_icdf[_s-1]-_icdf[_s]);
     170             :   }
     171           0 :   else _this->rng-=IMUL32(r,_icdf[_s]);
     172           0 :   ec_enc_normalize(_this);
     173           0 : }
     174             : 
     175           0 : void ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft){
     176             :   unsigned  ft;
     177             :   unsigned  fl;
     178             :   int       ftb;
     179             :   /*In order to optimize EC_ILOG(), it is undefined for the value 0.*/
     180           0 :   celt_assert(_ft>1);
     181           0 :   _ft--;
     182           0 :   ftb=EC_ILOG(_ft);
     183           0 :   if(ftb>EC_UINT_BITS){
     184           0 :     ftb-=EC_UINT_BITS;
     185           0 :     ft=(_ft>>ftb)+1;
     186           0 :     fl=(unsigned)(_fl>>ftb);
     187           0 :     ec_encode(_this,fl,fl+1,ft);
     188           0 :     ec_enc_bits(_this,_fl&(((opus_uint32)1<<ftb)-1U),ftb);
     189             :   }
     190           0 :   else ec_encode(_this,_fl,_fl+1,_ft+1);
     191           0 : }
     192             : 
     193           0 : void ec_enc_bits(ec_enc *_this,opus_uint32 _fl,unsigned _bits){
     194             :   ec_window window;
     195             :   int       used;
     196           0 :   window=_this->end_window;
     197           0 :   used=_this->nend_bits;
     198           0 :   celt_assert(_bits>0);
     199           0 :   if(used+_bits>EC_WINDOW_SIZE){
     200             :     do{
     201           0 :       _this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX);
     202           0 :       window>>=EC_SYM_BITS;
     203           0 :       used-=EC_SYM_BITS;
     204             :     }
     205           0 :     while(used>=EC_SYM_BITS);
     206             :   }
     207           0 :   window|=(ec_window)_fl<<used;
     208           0 :   used+=_bits;
     209           0 :   _this->end_window=window;
     210           0 :   _this->nend_bits=used;
     211           0 :   _this->nbits_total+=_bits;
     212           0 : }
     213             : 
     214           0 : void ec_enc_patch_initial_bits(ec_enc *_this,unsigned _val,unsigned _nbits){
     215             :   int      shift;
     216             :   unsigned mask;
     217           0 :   celt_assert(_nbits<=EC_SYM_BITS);
     218           0 :   shift=EC_SYM_BITS-_nbits;
     219           0 :   mask=((1<<_nbits)-1)<<shift;
     220           0 :   if(_this->offs>0){
     221             :     /*The first byte has been finalized.*/
     222           0 :     _this->buf[0]=(unsigned char)((_this->buf[0]&~mask)|_val<<shift);
     223             :   }
     224           0 :   else if(_this->rem>=0){
     225             :     /*The first byte is still awaiting carry propagation.*/
     226           0 :     _this->rem=(_this->rem&~mask)|_val<<shift;
     227             :   }
     228           0 :   else if(_this->rng<=(EC_CODE_TOP>>_nbits)){
     229             :     /*The renormalization loop has never been run.*/
     230           0 :     _this->val=(_this->val&~((opus_uint32)mask<<EC_CODE_SHIFT))|
     231           0 :      (opus_uint32)_val<<(EC_CODE_SHIFT+shift);
     232             :   }
     233             :   /*The encoder hasn't even encoded _nbits of data yet.*/
     234           0 :   else _this->error=-1;
     235           0 : }
     236             : 
     237           0 : void ec_enc_shrink(ec_enc *_this,opus_uint32 _size){
     238           0 :   celt_assert(_this->offs+_this->end_offs<=_size);
     239           0 :   OPUS_MOVE(_this->buf+_size-_this->end_offs,
     240             :    _this->buf+_this->storage-_this->end_offs,_this->end_offs);
     241           0 :   _this->storage=_size;
     242           0 : }
     243             : 
     244           0 : void ec_enc_done(ec_enc *_this){
     245             :   ec_window   window;
     246             :   int         used;
     247             :   opus_uint32 msk;
     248             :   opus_uint32 end;
     249             :   int         l;
     250             :   /*We output the minimum number of bits that ensures that the symbols encoded
     251             :      thus far will be decoded correctly regardless of the bits that follow.*/
     252           0 :   l=EC_CODE_BITS-EC_ILOG(_this->rng);
     253           0 :   msk=(EC_CODE_TOP-1)>>l;
     254           0 :   end=(_this->val+msk)&~msk;
     255           0 :   if((end|msk)>=_this->val+_this->rng){
     256           0 :     l++;
     257           0 :     msk>>=1;
     258           0 :     end=(_this->val+msk)&~msk;
     259             :   }
     260           0 :   while(l>0){
     261           0 :     ec_enc_carry_out(_this,(int)(end>>EC_CODE_SHIFT));
     262           0 :     end=(end<<EC_SYM_BITS)&(EC_CODE_TOP-1);
     263           0 :     l-=EC_SYM_BITS;
     264             :   }
     265             :   /*If we have a buffered byte flush it into the output buffer.*/
     266           0 :   if(_this->rem>=0||_this->ext>0)ec_enc_carry_out(_this,0);
     267             :   /*If we have buffered extra bits, flush them as well.*/
     268           0 :   window=_this->end_window;
     269           0 :   used=_this->nend_bits;
     270           0 :   while(used>=EC_SYM_BITS){
     271           0 :     _this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX);
     272           0 :     window>>=EC_SYM_BITS;
     273           0 :     used-=EC_SYM_BITS;
     274             :   }
     275             :   /*Clear any excess space and add any remaining extra bits to the last byte.*/
     276           0 :   if(!_this->error){
     277           0 :     OPUS_CLEAR(_this->buf+_this->offs,
     278             :      _this->storage-_this->offs-_this->end_offs);
     279           0 :     if(used>0){
     280             :       /*If there's no range coder data at all, give up.*/
     281           0 :       if(_this->end_offs>=_this->storage)_this->error=-1;
     282             :       else{
     283           0 :         l=-l;
     284             :         /*If we've busted, don't add too many extra bits to the last byte; it
     285             :            would corrupt the range coder data, and that's more important.*/
     286           0 :         if(_this->offs+_this->end_offs>=_this->storage&&l<used){
     287           0 :           window&=(1<<l)-1;
     288           0 :           _this->error=-1;
     289             :         }
     290           0 :         _this->buf[_this->storage-_this->end_offs-1]|=(unsigned char)window;
     291             :       }
     292             :     }
     293             :   }
     294           0 : }

Generated by: LCOV version 1.13