diff --git a/libentcode/ectest.c b/libentcode/ectest.c
index 18d42bf1d478127532f75c008f4b362aa53dbd13..85994dcfe9b6032fed1a4e855698e0a5eefe35cb 100644
--- a/libentcode/ectest.c
+++ b/libentcode/ectest.c
@@ -11,6 +11,7 @@ int main(int _argc,char **_argv){
   ec_probmod     mod;
   ec_uint64      sym64;
   long           nbits;
+  long           nbits2;
   double         entropy;
   int            ft;
   int            ftb;
@@ -33,12 +34,10 @@ int main(int _argc,char **_argv){
   /*Testing encoding of raw bit values.*/
   for(ftb=0;ftb<16;ftb++){
     for(i=0;i<(1<<ftb);i++){
-      long nbits;
-      long nbits2;
       entropy+=ftb;
-      nbits=ec_enc_tell(&enc);
+      nbits=ec_enc_tell(&enc,0);
       ec_enc_bits(&enc,i,ftb);
-      nbits2=ec_enc_tell(&enc);
+      nbits2=ec_enc_tell(&enc,0);
       if(nbits2-nbits!=ftb){
         fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
          nbits2-nbits,ftb);
@@ -46,7 +45,7 @@ int main(int _argc,char **_argv){
       entropy+=ftb+30;
       nbits=nbits2;
       ec_enc_bits64(&enc,(ec_uint64)i<<30|i,ftb+30);
-      nbits2=ec_enc_tell(&enc);
+      nbits2=ec_enc_tell(&enc,0);
       if(nbits2-nbits!=ftb+30){
         fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
          nbits2-nbits,ftb+30);
@@ -73,7 +72,7 @@ int main(int _argc,char **_argv){
     }
     ec_probmod_clear(&mod);
   }
-  nbits=ec_enc_tellf(&enc,4);
+  nbits=ec_enc_tell(&enc,4);
   ec_enc_done(&enc);
   fprintf(stderr,
    "Encoded %0.2lf bits of entropy to %0.2lf bits (%0.3lf%% wasted).\n",
@@ -133,6 +132,12 @@ int main(int _argc,char **_argv){
     }
     ec_probmod_clear(&mod);
   }
+  nbits2=ec_dec_tell(&dec,4);
+  if(nbits!=nbits2){
+    fprintf(stderr,
+     "Reported number of bits used was %0.2lf, should be %0.2lf.\n",
+     ldexp(nbits2,-4),ldexp(nbits,-4));
+  }
   ec_byte_writeclear(&buf);
   fprintf(stderr,"All tests passed.\n");
   return 0;
diff --git a/libentcode/entdec.h b/libentcode/entdec.h
index bedb55eaf644644847958570e8a42bfbebe2465a..423c574ef5cd53a9e1339190893176b3634365f6 100644
--- a/libentcode/entdec.h
+++ b/libentcode/entdec.h
@@ -86,4 +86,17 @@ ec_uint32 ec_dec_uint(ec_dec *_this,ec_uint32 _ft);
   Return: The decoded bits.*/
 ec_uint64 ec_dec_uint64(ec_dec *_this,ec_uint64 _ft);
 
+/*Returns the number of bits "used" by the decoded symbols so far.
+  The actual number of bits may be larger, due to rounding to whole bytes, or
+   smaller, due to trailing zeros that were be stripped, so this is not an
+   estimate of the true packet size.
+  This same number can be computed by the encoder, and is suitable for making
+   coding decisions.
+  _b: The number of extra bits of precision to include.
+      At most 16 will be accurate.
+  Return: The number of bits scaled by 2**_b.
+          This will always be slightly larger than the exact value (e.g., all
+           rounding error is in the positive direction).*/
+long ec_dec_tell(ec_dec *_this,int _b);
+
 #endif
diff --git a/libentcode/entenc.h b/libentcode/entenc.h
index 61f89879e88780134d79b9827cc64f1b949fa80d..ebaed88737d2c68d8bab6175445258fc58f6df6f 100644
--- a/libentcode/entenc.h
+++ b/libentcode/entenc.h
@@ -65,18 +65,16 @@ void ec_enc_uint64(ec_enc *_this,ec_uint64 _fl,ec_uint64 _ft);
 
 /*Returns the number of bits "used" by the encoded symbols so far.
   The actual number of bits may be larger, due to rounding to whole bytes, or
-   smaller, due to trailing zeros that can be stripped.
-  Return: The number of bits.*/
-long ec_enc_tell(ec_enc *_this);
-
-/*Returns the number of bits "used" by the encoded symbols so far.
-  The actual number of bits may be larger, due to rounding to whole bytes, or
-   smaller, due to trailing zeros that can be stripped.
+   smaller, due to trailing zeros that can be stripped, so this is not an
+   estimate of the true packet size.
+  This same number can be computed by the decoder, and is suitable for making
+   coding decisions.
   _b: The number of extra bits of precision to include.
       At most 16 will be accurate.
   Return: The number of bits scaled by 2**_b.
-          This will always be slightly larger than the exact value.*/
-long ec_enc_tellf(ec_enc *_this,int _b);
+          This will always be slightly larger than the exact value (e.g., all
+           rounding error is in the positive direction).*/
+long ec_enc_tell(ec_enc *_this,int _b);
 
 /*Indicates that there are no more symbols to encode.
   All reamining output bytes are flushed to the output buffer.
diff --git a/libentcode/mfrngdec.c b/libentcode/mfrngdec.c
index caf1410f0c2a1cb1e358f95259d63dc9ccad081e..77b98e6b63a89ff3d88dbbe1ee28393e91efa7ba 100644
--- a/libentcode/mfrngdec.c
+++ b/libentcode/mfrngdec.c
@@ -137,26 +137,24 @@ static int ec_dec_in(ec_dec *_this){
   int ret;
   ret=ec_byte_read1(_this->buf);
   if(ret<0){
-    unsigned char *buf;
-    long           bytes;
+    long bytes;
     bytes=ec_byte_bytes(_this->buf);
-    buf=ec_byte_get_buffer(_this->buf);
     /*Breaking abstraction: don't do this at home, kids.*/
-    if(_this->buf->storage==bytes){
-      ec_byte_adv1(_this->buf);
-      if(bytes>0){
-        unsigned char *p;
-        p=buf+bytes;
-        /*If we end in a string of 0 or more EC_FOF_RSV1 bytes preceded by a
-           zero, return an extra EC_FOF_RSV1 byte.*/
-        do p--;
-        while(p>buf&&p[0]==EC_FOF_RSV1);
-        if(!p[0])return EC_FOF_RSV1;
-      }
+    if(_this->buf->storage==bytes&&bytes>0){
+      unsigned char *buf;
+      buf=ec_byte_get_buffer(_this->buf);
+      /*If we end in a string of 0 or more EC_FOF_RSV1 bytes preceded by a
+         zero, return an extra EC_FOF_RSV1 byte.*/
+      do bytes--;
+      while(bytes>0&&buf[bytes]==EC_FOF_RSV1);
+      if(!buf[bytes])ret=EC_FOF_RSV1;
     }
-    return 0;
+    else ret=0;
+    /*Needed to make sure the above conditional only triggers once, and to keep
+       oc_dec_tell() operating correctly.*/
+    ec_byte_adv1(_this->buf);
   }
-  else return ret;
+  return ret;
 }
 
 /*Normalizes the contents of dif and rng so that rng lies entirely in the
@@ -222,6 +220,31 @@ void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft){
   ec_dec_normalize(_this);
 }
 
+long ec_dec_tell(ec_dec *_this,int _b){
+  ec_uint32 r;
+  int       l;
+  long      nbits;
+  nbits=ec_byte_bytes(_this->buf)-(EC_CODE_BITS+EC_SYM_BITS-1)/EC_SYM_BITS<<3;
+  /*To handle the non-integral number of bits still left in the encoder state,
+     we compute the number of bits of low that must be encoded to ensure that
+     the value is inside the range for any possible subsequent bits.
+    Note that this is subtly different than the actual value we would end the
+     stream with, which tries to make as many of the trailing bits zeros as
+     possible.*/
+  nbits+=EC_CODE_BITS;
+  nbits<<=_b;
+  l=EC_ILOG(_this->rng);
+  r=_this->rng>>l-16;
+  while(_b-->0){
+    int b;
+    r=r*r>>15;
+    b=(int)(r>>16);
+    l=l<<1|b;
+    r>>=b;
+  }
+  return nbits-l;
+}
+
 #if 0
 int ec_dec_done(ec_dec *_this){
   unsigned low;
diff --git a/libentcode/mfrngenc.c b/libentcode/mfrngenc.c
index 5debf8adae5d47f67532f6c78a6af7b08b75e496..2b2b15c6d7b48ed348631198d8caa72664e75634 100644
--- a/libentcode/mfrngenc.c
+++ b/libentcode/mfrngenc.c
@@ -119,20 +119,7 @@ void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft){
   ec_enc_normalize(_this);
 }
 
-long ec_enc_tell(ec_enc *_this){
-  long nbits;
-  nbits=ec_byte_bytes(_this->buf)+(_this->rem>=0)+_this->ext<<3;
-  /*To handle the non-integral number of bits still left in the encoder state,
-     we compute the number of bits of low that must be encoded to ensure that
-     the value is inside the range for any possible subsequent bits.
-    Note that this is subtly different than the actual value we would end the
-     stream with, which tries to make as many of the trailing bits zeros as
-     possible.*/
-  nbits+=EC_CODE_BITS-EC_ILOG(_this->rng);
-  return nbits;
-}
-
-long ec_enc_tellf(ec_enc *_this,int _b){
+long ec_enc_tell(ec_enc *_this,int _b){
   ec_uint32 r;
   int       l;
   long      nbits;
diff --git a/libentcode/rangedec.c b/libentcode/rangedec.c
index 76817472fb9d0434e35287ff416de961d29a2e7a..49d26fd7557eb8fc93a13d33e833858bc758b9e6 100644
--- a/libentcode/rangedec.c
+++ b/libentcode/rangedec.c
@@ -120,26 +120,24 @@ static int ec_dec_in(ec_dec *_this){
   int ret;
   ret=ec_byte_read1(_this->buf);
   if(ret<0){
-    unsigned char *buf;
-    long           bytes;
+    long bytes;
     bytes=ec_byte_bytes(_this->buf);
-    buf=ec_byte_get_buffer(_this->buf);
     /*Breaking abstraction: don't do this at home, kids.*/
-    if(_this->buf->storage==bytes){
-      ec_byte_adv1(_this->buf);
-      if(bytes>0){
-        unsigned char *p;
-        p=buf+bytes;
-        /*If we end in a string of 0 or more EC_FOF_RSV1 bytes preceded by a
-           zero, return an extra EC_FOF_RSV1 byte.*/
-        do p--;
-        while(p>buf&&p[0]==EC_FOF_RSV1);
-        if(!p[0])return EC_FOF_RSV1;
-      }
+    if(_this->buf->storage==bytes&&bytes>0){
+      unsigned char *buf;
+      buf=ec_byte_get_buffer(_this->buf);
+      /*If we end in a string of 0 or more EC_FOF_RSV1 bytes preceded by a
+         zero, return an extra EC_FOF_RSV1 byte.*/
+      do bytes--;
+      while(bytes>0&&buf[bytes]==EC_FOF_RSV1);
+      if(!buf[bytes])ret=EC_FOF_RSV1;
     }
-    return 0;
+    else ret=0;
+    /*Needed to make sure the above conditional only triggers once, and to keep
+       oc_dec_tell() operating correctly.*/
+    ec_byte_adv1(_this->buf);
   }
-  else return ret;
+  return ret;
 }
 
 /*Normalizes the contents of dif and rng so that rng lies entirely in the
@@ -188,6 +186,31 @@ void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft){
   ec_dec_normalize(_this);
 }
 
+long ec_dec_tell(ec_dec *_this,int _b){
+  ec_uint32 r;
+  int       l;
+  long      nbits;
+  nbits=ec_byte_bytes(_this->buf)-(EC_CODE_BITS+EC_SYM_BITS-1)/EC_SYM_BITS<<3;
+  /*To handle the non-integral number of bits still left in the encoder state,
+     we compute the number of bits of low that must be encoded to ensure that
+     the value is inside the range for any possible subsequent bits.
+    Note that this is subtly different than the actual value we would end the
+     stream with, which tries to make as many of the trailing bits zeros as
+     possible.*/
+  nbits+=EC_CODE_BITS;
+  nbits<<=_b;
+  l=EC_ILOG(_this->rng);
+  r=_this->rng>>l-16;
+  while(_b-->0){
+    int b;
+    r=r*r>>15;
+    b=(int)(r>>16);
+    l=l<<1|b;
+    r>>=b;
+  }
+  return nbits-l;
+}
+
 #if 0
 int ec_dec_done(ec_dec *_this){
   unsigned low;
diff --git a/libentcode/rangeenc.c b/libentcode/rangeenc.c
index 8d3eef3b3c51a074cfc281590bab537a5f54c198..246a4555929181d2f0fa22045f27a0a8a5f55ba2 100644
--- a/libentcode/rangeenc.c
+++ b/libentcode/rangeenc.c
@@ -91,20 +91,7 @@ void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft){
   ec_enc_normalize(_this);
 }
 
-long ec_enc_tell(ec_enc *_this){
-  long nbits;
-  nbits=ec_byte_bytes(_this->buf)+(_this->rem>=0)+_this->ext<<3;
-  /*To handle the non-integral number of bits still left in the encoder state,
-     we compute the number of bits of low that must be encoded to ensure that
-     the value is inside the range for any possible subsequent bits.
-    Note that this is subtly different than the actual value we would end the
-     stream with, which tries to make as many of the trailing bits zeros as
-     possible.*/
-  nbits+=EC_CODE_BITS-EC_ILOG(_this->rng);
-  return nbits;
-}
-
-long ec_enc_tellf(ec_enc *_this,int _b){
+long ec_enc_tell(ec_enc *_this,int _b){
   ec_uint32 r;
   int       l;
   long      nbits;