Add oc_enc_tell to report an estimate of the number of bits used so far.

Remove the special case for 0 in EC_ILOG, as we never pass it 0 and this
 generates slightly better code.

Update ec_enc_bits64 to split the encoded values along word boundaries...
 this should generate slightly better code, as well as fix a subtle bug (the
 proper bits were not being masked out of the low part).
However, this will render previous streams that used this function undecodable
 (to my knowledge, no one is actually using it yet).

git-svn-id: http://svn.xiph.org/trunk/ghost@14391 0101bb08-14d6-0310-b084-bc0e0c8e3800
This commit is contained in:
tterribe 2008-01-11 03:13:50 +00:00 committed by Jean-Marc Valin
parent 45018cbfa2
commit 06390d082d
7 changed files with 81 additions and 16 deletions

View file

@ -1,6 +1,8 @@
#include <stdio.h>
#include <math.h>
#include "probenc.h"
#include "probdec.h"
#include "bitrenc.h"
int main(int _argc,char **_argv){
ec_byte_buffer buf;
@ -8,32 +10,54 @@ int main(int _argc,char **_argv){
ec_dec dec;
ec_probmod mod;
ec_uint64 sym64;
long nbits;
double entropy;
int ft;
int ftb;
int sym;
int sz;
int s;
int i;
entropy=0;
/*Testing encoding of raw bit values.*/
ec_byte_writeinit(&buf);
ec_enc_init(&enc,&buf);
for(ft=0;ft<1024;ft++){
for(i=0;i<ft;i++){
entropy+=log(ft)*M_LOG2E;
ec_enc_uint(&enc,i,ft);
entropy+=log(ft)*M_LOG2E+30;
ec_enc_uint64(&enc,(ec_uint64)i<<30|i,(ec_uint64)ft<<30);
}
}
/*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);
ec_enc_bits(&enc,i,ftb);
nbits2=ec_enc_tell(&enc);
if(nbits2-nbits!=ftb){
fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
nbits2-nbits,ftb);
}
entropy+=ftb+30;
nbits=nbits2;
ec_enc_bits64(&enc,(ec_uint64)i<<30|i,ftb+30);
nbits2=ec_enc_tell(&enc);
if(nbits2-nbits!=ftb+30){
fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
nbits2-nbits,ftb+30);
}
}
}
for(sz=1;sz<256;sz++){
ec_probmod_init_full(&mod,sz,1,sz+(sz>>1),NULL);
for(i=0;i<sz;i++){
s=((unsigned)(i*45678901+7))%sz;
entropy+=(log(mod.ft)-log(ec_bitree_get_freq(mod.bitree,s)))*M_LOG2E;
ec_probmod_write(&mod,&enc,s);
}
ec_probmod_clear(&mod);
@ -42,12 +66,19 @@ int main(int _argc,char **_argv){
ec_probmod_init_full(&mod,sz,1,sz+(sz>>1),NULL);
for(i=0;i<sz;i++){
s=((unsigned)(i*45678901+7))%sz;
entropy+=(log(ec_bitree_get_cumul(mod.bitree,EC_MINI(s+6,sz))-
ec_bitree_get_cumul(mod.bitree,EC_MAXI(s-5,0)))-
log(ec_bitree_get_freq(mod.bitree,s)))*M_LOG2E;
ec_probmod_write_range(&mod,&enc,s,EC_MAXI(s-5,0),EC_MINI(s+6,sz));
}
ec_probmod_clear(&mod);
}
nbits=ec_enc_tell(&enc);
ec_enc_done(&enc);
fprintf(stderr,"Encoded to %li bytes.\n",(long)(buf.ptr-buf.buf));
fprintf(stderr,
"Encoded %0.2lf bits of entropy to %li bits (%0.3lf%% wasted).\n",
entropy,nbits,100*(nbits-entropy)/nbits);
fprintf(stderr,"Packed to %li bytes.\n",(long)(buf.ptr-buf.buf));
ec_byte_readinit(&buf,ec_byte_get_buffer(&buf),ec_byte_bytes(&buf));
ec_dec_init(&dec,&buf);
for(ft=0;ft<1024;ft++){