ref: de31e7e09ab8958558147e7367532d0409d86744
parent: 4e955ed3794f37c91a699e25b97de71cb08077ad
author: Timothy B. Terriberry <[email protected]>
date: Tue Dec 21 12:30:45 EST 2010
Add test coverage for entropy coder compatibility. This ensures that the various alternative routines in the entropy encoder and decoder (e.g., ec_{enc|dec}_bit_logp()) really are just specialized optimizations of the same general ec_encode() and ec_decode() routines. This is done by randomly picking one to encode with for each symbol, and randomly picking a different one to decode with.
--- a/tests/ectest.c
+++ b/tests/ectest.c
@@ -167,7 +167,102 @@
j+1,ec_dec_tell(&dec,3),tell[j+1],seed);
}
}
+ free(tell);
free(data);
+ }
+ /*Test compatibility between multiple different encode/decode routines.*/
+ for(i=0;i<409600;i++){
+ unsigned *logp1;
+ unsigned *data;
+ unsigned *tell;
+ unsigned *enc_method;
+ int j;
+ sz=rand()/((RAND_MAX>>(rand()%9))+1);
+ logp1=(unsigned *)malloc(sz*sizeof(*logp1));
+ data=(unsigned *)malloc(sz*sizeof(*data));
+ tell=(unsigned *)malloc((sz+1)*sizeof(*tell));
+ enc_method=(unsigned *)malloc(sz*sizeof(*enc_method));
+ ec_byte_writeinit_buffer(&buf, ptr, DATA_SIZE2);
+ ec_enc_init(&enc,&buf);
+ tell[0]=ec_enc_tell(&enc,3);
+ for(j=0;j<sz;j++){
+ data[j]=rand()/((RAND_MAX>>1)+1);
+ logp1[j]=(rand()%15)+1;
+ enc_method[j]=rand()%3;
+ switch(enc_method[j]){
+ case 0:{
+ ec_encode(&enc,data[j]?(1<<logp1[j])-1:0,
+ (1<<logp1[j])-(data[j]?0:1),1<<logp1[j]);
+ }break;
+ case 1:{
+ ec_encode_bin(&enc,data[j]?(1<<logp1[j])-1:0,
+ (1<<logp1[j])-(data[j]?0:1),logp1[j]);
+ }break;
+ case 2:{
+ ec_enc_bit_logp(&enc,data[j],logp1[j]);
+ }break;
+ }
+ tell[j+1]=ec_enc_tell(&enc,3);
+ }
+ ec_enc_done(&enc);
+ if((ec_enc_tell(&enc,0)+7)/8<ec_byte_bytes(&buf)){
+ fprintf(stderr,"tell() lied, there's %i bytes instead of %d (Random seed: %u)\n",
+ ec_byte_bytes(&buf),(ec_enc_tell(&enc,0)+7)/8,seed);
+ ret=-1;
+ }
+ ec_byte_readinit(&buf,ptr,DATA_SIZE2);
+ ec_dec_init(&dec,&buf);
+ if(ec_dec_tell(&dec,3)!=tell[0]){
+ fprintf(stderr,
+ "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
+ 0,ec_dec_tell(&dec,3),tell[0],seed);
+ }
+ for(j=0;j<sz;j++){
+ int fs;
+ int dec_method;
+ dec_method=rand()/((RAND_MAX>>2)+1);
+ switch(dec_method){
+ case 0:{
+ fs=ec_decode(&dec,1<<logp1[j]);
+ sym=fs>=(1<<logp1[j])-1;
+ ec_dec_update(&dec,sym?(1<<logp1[j])-1:0,
+ (1<<logp1[j])-(sym?0:1),1<<logp1[j]);
+ }break;
+ case 1:{
+ fs=ec_decode_bin(&dec,logp1[j]);
+ sym=fs>=(1<<logp1[j])-1;
+ ec_dec_update(&dec,sym?(1<<logp1[j])-1:0,
+ (1<<logp1[j])-(sym?0:1),1<<logp1[j]);
+ }break;
+ case 2:{
+ sym=ec_dec_bit_logp(&dec,logp1[j]);
+ }break;
+ case 3:{
+ int cdf[3];
+ cdf[0]=0;
+ cdf[1]=(1<<logp1[j])-1;
+ cdf[2]=1<<logp1[j];
+ sym=ec_dec_cdf(&dec,cdf,logp1[j]);
+ }break;
+ }
+ if(sym!=data[j]){
+ fprintf(stderr,
+ "Decoded %i instead of %i with logp1 of %i at position %i of %i (Random seed: %u).\n",
+ sym,data[j],logp1[j],j,sz,seed);
+ fprintf(stderr,"Encoding method: %i, decoding method: %i\n",
+ enc_method[j],dec_method);
+ ret=-1;
+ }
+ if(ec_dec_tell(&dec,3)!=tell[j+1]){
+ fprintf(stderr,
+ "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
+ j+1,ec_dec_tell(&dec,3),tell[j+1],seed);
+ }
+ }
+ free(enc_method);
+ free(tell);
+ free(data);
+ free(logp1);
}
free(ptr);
return ret;