[xiph-commits] r14394 - trunk/ghost/libentcode
tterribe at svn.xiph.org
tterribe at svn.xiph.org
Thu Jan 10 21:51:52 PST 2008
Author: tterribe
Date: 2008-01-10 21:51:49 -0800 (Thu, 10 Jan 2008)
New Revision: 14394
Modified:
trunk/ghost/libentcode/ectest.c
trunk/ghost/libentcode/entdec.h
trunk/ghost/libentcode/entenc.h
trunk/ghost/libentcode/mfrngdec.c
trunk/ghost/libentcode/mfrngenc.c
trunk/ghost/libentcode/rangedec.c
trunk/ghost/libentcode/rangeenc.c
Log:
Add ec_dec_tell() to report the same information as ec_enc_tell() decode side.
Remove ec_enc_tell() and replace it with ec_enc_tellf(): just request 0
fractional bits if you want an integer value.
Modified: trunk/ghost/libentcode/ectest.c
===================================================================
--- trunk/ghost/libentcode/ectest.c 2008-01-11 05:12:17 UTC (rev 14393)
+++ trunk/ghost/libentcode/ectest.c 2008-01-11 05:51:49 UTC (rev 14394)
@@ -11,6 +11,7 @@
ec_probmod mod;
ec_uint64 sym64;
long nbits;
+ long nbits2;
double entropy;
int ft;
int ftb;
@@ -33,12 +34,10 @@
/*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 @@
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 @@
}
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 @@
}
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;
Modified: trunk/ghost/libentcode/entdec.h
===================================================================
--- trunk/ghost/libentcode/entdec.h 2008-01-11 05:12:17 UTC (rev 14393)
+++ trunk/ghost/libentcode/entdec.h 2008-01-11 05:51:49 UTC (rev 14394)
@@ -86,4 +86,17 @@
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
Modified: trunk/ghost/libentcode/entenc.h
===================================================================
--- trunk/ghost/libentcode/entenc.h 2008-01-11 05:12:17 UTC (rev 14393)
+++ trunk/ghost/libentcode/entenc.h 2008-01-11 05:51:49 UTC (rev 14394)
@@ -65,18 +65,16 @@
/*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.
Modified: trunk/ghost/libentcode/mfrngdec.c
===================================================================
--- trunk/ghost/libentcode/mfrngdec.c 2008-01-11 05:12:17 UTC (rev 14393)
+++ trunk/ghost/libentcode/mfrngdec.c 2008-01-11 05:51:49 UTC (rev 14394)
@@ -137,26 +137,24 @@
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 @@
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;
Modified: trunk/ghost/libentcode/mfrngenc.c
===================================================================
--- trunk/ghost/libentcode/mfrngenc.c 2008-01-11 05:12:17 UTC (rev 14393)
+++ trunk/ghost/libentcode/mfrngenc.c 2008-01-11 05:51:49 UTC (rev 14394)
@@ -119,20 +119,7 @@
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;
Modified: trunk/ghost/libentcode/rangedec.c
===================================================================
--- trunk/ghost/libentcode/rangedec.c 2008-01-11 05:12:17 UTC (rev 14393)
+++ trunk/ghost/libentcode/rangedec.c 2008-01-11 05:51:49 UTC (rev 14394)
@@ -120,26 +120,24 @@
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 @@
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;
Modified: trunk/ghost/libentcode/rangeenc.c
===================================================================
--- trunk/ghost/libentcode/rangeenc.c 2008-01-11 05:12:17 UTC (rev 14393)
+++ trunk/ghost/libentcode/rangeenc.c 2008-01-11 05:51:49 UTC (rev 14394)
@@ -91,20 +91,7 @@
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;
More information about the commits
mailing list