From 299747ee24851f2f20a8a466a3a5b58f1b116768 Mon Sep 17 00:00:00 2001
From: "Timothy B. Terriberry" <tterribe@xiph.org>
Date: Sat, 29 May 2010 22:47:37 -0400
Subject: [PATCH] Provide direct implementations ec_{enc|dec}_bit_prob() that
 do not require a division instead of using the normal entropy coder path.
 This should be exactly equivalent to the existing code.

---
 libcelt/entdec.c   | 18 ------------------
 libcelt/entdec.h   |  3 +--
 libcelt/entenc.c   | 12 ------------
 libcelt/rangedec.c | 16 ++++++++++++++++
 libcelt/rangeenc.c | 14 ++++++++++++++
 5 files changed, 31 insertions(+), 32 deletions(-)

diff --git a/libcelt/entdec.c b/libcelt/entdec.c
index 191d3ee82..5b8846bc2 100644
--- a/libcelt/entdec.c
+++ b/libcelt/entdec.c
@@ -111,21 +111,3 @@ ec_uint32 ec_dec_uint(ec_dec *_this,ec_uint32 _ft){
     return t;
   }
 }
-
-/* The probability of having a "one" is given in 1/256 */
-int ec_dec_bit_prob(ec_dec *_this,int _prob)
-{
-   int val;
-   int fl=0, fh=256-_prob;
-   val = ec_decode_bin(_this, 8);
-   if (val >= fh)
-   {
-      val = 1;
-      fl=fh;
-      fh=256;
-   } else {
-      val = 0;
-   }
-   ec_dec_update(_this,fl,fh,256);
-   return val;
-}
diff --git a/libcelt/entdec.h b/libcelt/entdec.h
index 008b6c8d7..b2b4b5673 100644
--- a/libcelt/entdec.h
+++ b/libcelt/entdec.h
@@ -47,8 +47,7 @@ struct ec_dec{
    int             rem;
    /*The number of values in the current range.*/
    ec_uint32       rng;
-   /*The difference between the input value and the lowest value in the current
-      range.*/
+   /*The difference between the top of the current range and the input value.*/
    ec_uint32       dif;
    /*Normalization factor.*/
    ec_uint32       nrm;
diff --git a/libcelt/entenc.c b/libcelt/entenc.c
index 44353f5b1..4594daa36 100644
--- a/libcelt/entenc.c
+++ b/libcelt/entenc.c
@@ -100,15 +100,3 @@ void ec_enc_uint(ec_enc *_this,ec_uint32 _fl,ec_uint32 _ft){
     ec_encode(_this,_fl,_fl+1,_ft+1);
   }
 }
-
-/* The probability of having a "one" is given in 1/256 */
-void ec_enc_bit_prob(ec_enc *_this,int val,int _prob)
-{
-   int fl=0, fh=256-_prob;
-   if (val)
-   {
-      fl=fh;
-      fh=256;
-   }
-   ec_encode_bin(_this,fl,fh,8);
-}
diff --git a/libcelt/rangedec.c b/libcelt/rangedec.c
index a8d322b4d..2526d4111 100644
--- a/libcelt/rangedec.c
+++ b/libcelt/rangedec.c
@@ -186,6 +186,22 @@ void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft){
   ec_dec_normalize(_this);
 }
 
+/*The probability of having a "one" is given in 1/256.*/
+int ec_dec_bit_prob(ec_dec *_this,int _prob){
+  ec_uint32 r;
+  ec_uint32 s;
+  ec_uint32 d;
+  int       val;
+  r=_this->rng;
+  d=_this->dif;
+  s=IMUL32(r>>8,_prob);
+  val=d<=s;
+  if(!val)_this->dif=d-s;
+  _this->rng=val?s:r-s;
+  ec_dec_normalize(_this);
+  return val;
+}
+
 long ec_dec_tell(ec_dec *_this,int _b){
   ec_uint32 r;
   int       l;
diff --git a/libcelt/rangeenc.c b/libcelt/rangeenc.c
index 0ba34974d..f7f171ba1 100644
--- a/libcelt/rangeenc.c
+++ b/libcelt/rangeenc.c
@@ -138,6 +138,20 @@ void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits){
    ec_enc_normalize(_this);
 }
 
+/*The probability of having a "one" is given in 1/256.*/
+void ec_enc_bit_prob(ec_enc *_this,int _val,int _prob){
+   ec_uint32 r;
+   ec_uint32 s;
+   ec_uint32 l;
+   r=_this->rng;
+   l=_this->low;
+   s=IMUL32(r>>8,_prob);
+   r-=s;
+   if(_val)_this->low=l+r;
+   _this->rng=_val?s:r;
+   ec_enc_normalize(_this);
+}
+
 void ec_encode_raw(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned bits){
   _this->nb_end_bits += bits;
   while (bits >= _this->end_bits_left)
-- 
GitLab