blob: 0f0fae811dd369d0b1c3ed02143fd4f37430ad3e [file] [log] [blame]
tterribe7e3293f2008-01-23 23:04:43 +00001#include <stdlib.h>
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +11002#include <stdio.h>
tterribe06390d02008-01-11 03:13:50 +00003#include <math.h>
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +11004#include "probenc.h"
5#include "probdec.h"
tterribe06390d02008-01-11 03:13:50 +00006#include "bitrenc.h"
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +11007
8int main(int _argc,char **_argv){
9 ec_byte_buffer buf;
10 ec_enc enc;
11 ec_dec dec;
12 ec_probmod mod;
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +110013 ec_uint64 sym64;
tterribe06390d02008-01-11 03:13:50 +000014 long nbits;
tterribe3eff11d2008-01-11 05:51:49 +000015 long nbits2;
tterribe06390d02008-01-11 03:13:50 +000016 double entropy;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110017 int ft;
18 int ftb;
19 int sym;
20 int sz;
21 int s;
22 int i;
tterribe06390d02008-01-11 03:13:50 +000023 entropy=0;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110024 /*Testing encoding of raw bit values.*/
25 ec_byte_writeinit(&buf);
26 ec_enc_init(&enc,&buf);
27 for(ft=0;ft<1024;ft++){
28 for(i=0;i<ft;i++){
tterribe06390d02008-01-11 03:13:50 +000029 entropy+=log(ft)*M_LOG2E;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110030 ec_enc_uint(&enc,i,ft);
tterribe06390d02008-01-11 03:13:50 +000031 entropy+=log(ft)*M_LOG2E+30;
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +110032 ec_enc_uint64(&enc,(ec_uint64)i<<30|i,(ec_uint64)ft<<30);
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110033 }
34 }
35 /*Testing encoding of raw bit values.*/
36 for(ftb=0;ftb<16;ftb++){
37 for(i=0;i<(1<<ftb);i++){
tterribe06390d02008-01-11 03:13:50 +000038 entropy+=ftb;
tterribe3eff11d2008-01-11 05:51:49 +000039 nbits=ec_enc_tell(&enc,0);
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110040 ec_enc_bits(&enc,i,ftb);
tterribe3eff11d2008-01-11 05:51:49 +000041 nbits2=ec_enc_tell(&enc,0);
tterribe06390d02008-01-11 03:13:50 +000042 if(nbits2-nbits!=ftb){
43 fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
44 nbits2-nbits,ftb);
45 }
46 entropy+=ftb+30;
47 nbits=nbits2;
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +110048 ec_enc_bits64(&enc,(ec_uint64)i<<30|i,ftb+30);
tterribe3eff11d2008-01-11 05:51:49 +000049 nbits2=ec_enc_tell(&enc,0);
tterribe06390d02008-01-11 03:13:50 +000050 if(nbits2-nbits!=ftb+30){
51 fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
52 nbits2-nbits,ftb+30);
53 }
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110054 }
55 }
56 for(sz=1;sz<256;sz++){
57 ec_probmod_init_full(&mod,sz,1,sz+(sz>>1),NULL);
58 for(i=0;i<sz;i++){
59 s=((unsigned)(i*45678901+7))%sz;
tterribe06390d02008-01-11 03:13:50 +000060 entropy+=(log(mod.ft)-log(ec_bitree_get_freq(mod.bitree,s)))*M_LOG2E;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110061 ec_probmod_write(&mod,&enc,s);
62 }
63 ec_probmod_clear(&mod);
64 }
65 for(sz=11;sz<256;sz++){
66 ec_probmod_init_full(&mod,sz,1,sz+(sz>>1),NULL);
67 for(i=0;i<sz;i++){
68 s=((unsigned)(i*45678901+7))%sz;
tterribe06390d02008-01-11 03:13:50 +000069 entropy+=(log(ec_bitree_get_cumul(mod.bitree,EC_MINI(s+6,sz))-
70 ec_bitree_get_cumul(mod.bitree,EC_MAXI(s-5,0)))-
71 log(ec_bitree_get_freq(mod.bitree,s)))*M_LOG2E;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110072 ec_probmod_write_range(&mod,&enc,s,EC_MAXI(s-5,0),EC_MINI(s+6,sz));
73 }
74 ec_probmod_clear(&mod);
75 }
tterribe3eff11d2008-01-11 05:51:49 +000076 nbits=ec_enc_tell(&enc,4);
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110077 ec_enc_done(&enc);
tterribe06390d02008-01-11 03:13:50 +000078 fprintf(stderr,
tterribefad779c2008-01-11 05:12:17 +000079 "Encoded %0.2lf bits of entropy to %0.2lf bits (%0.3lf%% wasted).\n",
80 entropy,ldexp(nbits,-4),100*(nbits-ldexp(entropy,4))/nbits);
tterribe06390d02008-01-11 03:13:50 +000081 fprintf(stderr,"Packed to %li bytes.\n",(long)(buf.ptr-buf.buf));
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110082 ec_byte_readinit(&buf,ec_byte_get_buffer(&buf),ec_byte_bytes(&buf));
83 ec_dec_init(&dec,&buf);
84 for(ft=0;ft<1024;ft++){
85 for(i=0;i<ft;i++){
86 sym=ec_dec_uint(&dec,ft);
87 if(sym!=i){
88 fprintf(stderr,"Decoded %i instead of %i with ft of %i.\n",sym,i,ft);
89 return -1;
90 }
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +110091 sym64=ec_dec_uint64(&dec,(ec_uint64)ft<<30);
92 if(sym64!=((ec_uint64)i<<30|i)){
93 fprintf(stderr,"Decoded %lli instead of %lli with ft of %lli.\n",sym64,
94 (ec_uint64)i<<30|i,(ec_uint64)ft<<30);
95 }
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110096 }
97 }
98 for(ftb=0;ftb<16;ftb++){
99 for(i=0;i<(1<<ftb);i++){
100 sym=ec_dec_bits(&dec,ftb);
101 if(sym!=i){
102 fprintf(stderr,"Decoded %i instead of %i with ftb of %i.\n",sym,i,ftb);
103 return -1;
104 }
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +1100105 sym64=ec_dec_bits64(&dec,ftb+30);
106 if(sym64!=((ec_uint64)i<<30|i)){
107 fprintf(stderr,"Decoded %lli instead of %lli with ftb of %i.\n",
108 sym64,(ec_uint64)i<<30|i,ftb+30);
109 }
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +1100110 }
111 }
112 for(sz=1;sz<256;sz++){
113 ec_probmod_init_full(&mod,sz,1,sz+(sz>>1),NULL);
114 for(i=0;i<sz;i++){
115 s=((unsigned)(i*45678901+7))%sz;
116 sym=ec_probmod_read(&mod,&dec);
117 if(sym!=s){
118 fprintf(stderr,"Decoded %i instead of %i with sz of %i.\n",sym,s,sz);
119 return -1;
120 }
121 }
122 ec_probmod_clear(&mod);
123 }
124 for(sz=11;sz<256;sz++){
125 ec_probmod_init_full(&mod,sz,1,sz+(sz>>1),NULL);
126 for(i=0;i<sz;i++){
127 s=((unsigned)(i*45678901+7))%sz;
128 sym=ec_probmod_read_range(&mod,&dec,EC_MAXI(s-5,0),EC_MINI(s+6,sz));
129 if(sym!=s){
130 fprintf(stderr,"Decoded %i instead of %i with sz of %i.\n",sym,s,sz);
131 return -1;
132 }
133 }
134 ec_probmod_clear(&mod);
135 }
tterribe3eff11d2008-01-11 05:51:49 +0000136 nbits2=ec_dec_tell(&dec,4);
137 if(nbits!=nbits2){
138 fprintf(stderr,
139 "Reported number of bits used was %0.2lf, should be %0.2lf.\n",
140 ldexp(nbits2,-4),ldexp(nbits,-4));
141 }
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +1100142 ec_byte_writeclear(&buf);
tterribe7e3293f2008-01-23 23:04:43 +0000143 fprintf(stderr,"Testing random streams...\n");
144 srand(0);
145 for(i=0;i<1024;i++){
146 unsigned *data;
147 int j;
148 ft=rand()/((RAND_MAX>>9)+1)+512;
149 sz=rand()/((RAND_MAX>>9)+1);
150 data=(unsigned *)malloc(sz*sizeof(*data));
151 ec_byte_writeinit(&buf);
152 ec_enc_init(&enc,&buf);
153 for(j=0;j<sz;j++){
154 data[j]=rand()%ft;
155 ec_enc_uint(&enc,data[j],ft);
156 }
157 ec_enc_done(&enc);
158 ec_byte_readinit(&buf,ec_byte_get_buffer(&buf),ec_byte_bytes(&buf));
159 ec_dec_init(&dec,&buf);
160 for(j=0;j<sz;j++){
161 sym=ec_dec_uint(&dec,ft);
162 if(sym!=data[j]){
163 fprintf(stderr,
164 "Decoded %i instead of %i with ft of %i at position %i of %i.\n",
165 sym,data[j],ft,j,sz);
166 }
167 }
168 ec_byte_writeclear(&buf);
tterribebab4fb12008-01-23 23:10:28 +0000169 free(data);
tterribe7e3293f2008-01-23 23:04:43 +0000170 }
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +1100171 return 0;
172}