blob: 6740e074e68e32432097d814cfc972eed29de08c [file] [log] [blame]
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +11001#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
tterribe7e3293f2008-01-23 23:04:43 +00005#include <stdlib.h>
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +11006#include <stdio.h>
tterribe06390d02008-01-11 03:13:50 +00007#include <math.h>
tterribe06390d02008-01-11 03:13:50 +00008#include "bitrenc.h"
Jean-Marc Valin6238bc02008-01-28 22:28:54 +11009#include "entcode.h"
10#include "entenc.h"
11#include "entdec.h"
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110012
Jean-Marc Valin2f5ccf62008-02-27 07:48:48 +110013#ifndef M_LOG2E
14# define M_LOG2E 1.4426950408889634074
15#endif
16
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110017int main(int _argc,char **_argv){
18 ec_byte_buffer buf;
19 ec_enc enc;
20 ec_dec dec;
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +110021 ec_uint64 sym64;
tterribe06390d02008-01-11 03:13:50 +000022 long nbits;
tterribe3eff11d2008-01-11 05:51:49 +000023 long nbits2;
tterribe06390d02008-01-11 03:13:50 +000024 double entropy;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110025 int ft;
26 int ftb;
27 int sym;
28 int sz;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110029 int i;
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110030 int ret;
31 ret=0;
tterribe06390d02008-01-11 03:13:50 +000032 entropy=0;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110033 /*Testing encoding of raw bit values.*/
34 ec_byte_writeinit(&buf);
35 ec_enc_init(&enc,&buf);
36 for(ft=0;ft<1024;ft++){
37 for(i=0;i<ft;i++){
tterribe06390d02008-01-11 03:13:50 +000038 entropy+=log(ft)*M_LOG2E;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110039 ec_enc_uint(&enc,i,ft);
tterribe06390d02008-01-11 03:13:50 +000040 entropy+=log(ft)*M_LOG2E+30;
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +110041 ec_enc_uint64(&enc,(ec_uint64)i<<30|i,(ec_uint64)ft<<30);
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110042 }
43 }
44 /*Testing encoding of raw bit values.*/
45 for(ftb=0;ftb<16;ftb++){
46 for(i=0;i<(1<<ftb);i++){
tterribe06390d02008-01-11 03:13:50 +000047 entropy+=ftb;
tterribe3eff11d2008-01-11 05:51:49 +000048 nbits=ec_enc_tell(&enc,0);
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110049 ec_enc_bits(&enc,i,ftb);
tterribe3eff11d2008-01-11 05:51:49 +000050 nbits2=ec_enc_tell(&enc,0);
tterribe06390d02008-01-11 03:13:50 +000051 if(nbits2-nbits!=ftb){
52 fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
53 nbits2-nbits,ftb);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110054 ret=-1;
tterribe06390d02008-01-11 03:13:50 +000055 }
56 entropy+=ftb+30;
57 nbits=nbits2;
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +110058 ec_enc_bits64(&enc,(ec_uint64)i<<30|i,ftb+30);
tterribe3eff11d2008-01-11 05:51:49 +000059 nbits2=ec_enc_tell(&enc,0);
tterribe06390d02008-01-11 03:13:50 +000060 if(nbits2-nbits!=ftb+30){
61 fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
62 nbits2-nbits,ftb+30);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110063 ret=-1;
tterribe06390d02008-01-11 03:13:50 +000064 }
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110065 }
66 }
tterribe3eff11d2008-01-11 05:51:49 +000067 nbits=ec_enc_tell(&enc,4);
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110068 ec_enc_done(&enc);
tterribe06390d02008-01-11 03:13:50 +000069 fprintf(stderr,
tterribefad779c2008-01-11 05:12:17 +000070 "Encoded %0.2lf bits of entropy to %0.2lf bits (%0.3lf%% wasted).\n",
71 entropy,ldexp(nbits,-4),100*(nbits-ldexp(entropy,4))/nbits);
tterribe06390d02008-01-11 03:13:50 +000072 fprintf(stderr,"Packed to %li bytes.\n",(long)(buf.ptr-buf.buf));
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110073 ec_byte_readinit(&buf,ec_byte_get_buffer(&buf),ec_byte_bytes(&buf));
74 ec_dec_init(&dec,&buf);
75 for(ft=0;ft<1024;ft++){
76 for(i=0;i<ft;i++){
77 sym=ec_dec_uint(&dec,ft);
78 if(sym!=i){
79 fprintf(stderr,"Decoded %i instead of %i with ft of %i.\n",sym,i,ft);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110080 ret=-1;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110081 }
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +110082 sym64=ec_dec_uint64(&dec,(ec_uint64)ft<<30);
83 if(sym64!=((ec_uint64)i<<30|i)){
84 fprintf(stderr,"Decoded %lli instead of %lli with ft of %lli.\n",sym64,
85 (ec_uint64)i<<30|i,(ec_uint64)ft<<30);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110086 ret=-1;
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +110087 }
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110088 }
89 }
90 for(ftb=0;ftb<16;ftb++){
91 for(i=0;i<(1<<ftb);i++){
92 sym=ec_dec_bits(&dec,ftb);
93 if(sym!=i){
94 fprintf(stderr,"Decoded %i instead of %i with ftb of %i.\n",sym,i,ftb);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110095 ret=-1;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110096 }
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +110097 sym64=ec_dec_bits64(&dec,ftb+30);
98 if(sym64!=((ec_uint64)i<<30|i)){
99 fprintf(stderr,"Decoded %lli instead of %lli with ftb of %i.\n",
100 sym64,(ec_uint64)i<<30|i,ftb+30);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +1100101 ret=-1;
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +1100102 }
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +1100103 }
104 }
tterribe3eff11d2008-01-11 05:51:49 +0000105 nbits2=ec_dec_tell(&dec,4);
106 if(nbits!=nbits2){
107 fprintf(stderr,
108 "Reported number of bits used was %0.2lf, should be %0.2lf.\n",
109 ldexp(nbits2,-4),ldexp(nbits,-4));
Jean-Marc Valin3df6e272008-02-20 15:08:08 +1100110 ret=-1;
tterribe3eff11d2008-01-11 05:51:49 +0000111 }
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +1100112 ec_byte_writeclear(&buf);
tterribe7e3293f2008-01-23 23:04:43 +0000113 fprintf(stderr,"Testing random streams...\n");
114 srand(0);
Jean-Marc Valin2991af52008-02-19 21:02:43 +1100115 for(i=0;i<409600;i++){
tterribe7e3293f2008-01-23 23:04:43 +0000116 unsigned *data;
117 int j;
Jean-Marc Valincb0956d2008-02-07 20:21:57 +1100118 int tell_bits;
119 int zeros;
Jean-Marc Valin2991af52008-02-19 21:02:43 +1100120 ft=rand()/((RAND_MAX>>(rand()%11))+1)+10;
121 sz=rand()/((RAND_MAX>>(rand()%9))+1);
tterribe7e3293f2008-01-23 23:04:43 +0000122 data=(unsigned *)malloc(sz*sizeof(*data));
123 ec_byte_writeinit(&buf);
124 ec_enc_init(&enc,&buf);
Jean-Marc Valincb0956d2008-02-07 20:21:57 +1100125 zeros = rand()%13==0;
tterribe7e3293f2008-01-23 23:04:43 +0000126 for(j=0;j<sz;j++){
Jean-Marc Valincb0956d2008-02-07 20:21:57 +1100127 if (zeros)
128 data[j]=0;
129 else
130 data[j]=rand()%ft;
tterribe7e3293f2008-01-23 23:04:43 +0000131 ec_enc_uint(&enc,data[j],ft);
132 }
Jean-Marc Valin2991af52008-02-19 21:02:43 +1100133 if (rand()%2==0)
134 while(ec_enc_tell(&enc, 0)%8 != 0)
135 ec_enc_uint(&enc, rand()%2, 2);
Jean-Marc Valincb0956d2008-02-07 20:21:57 +1100136 tell_bits = ec_enc_tell(&enc, 0);
tterribe7e3293f2008-01-23 23:04:43 +0000137 ec_enc_done(&enc);
Jean-Marc Valinb3756702008-02-08 11:50:17 +1100138 if ((tell_bits+7)/8 < ec_byte_bytes(&buf))
139 {
140 fprintf (stderr, "tell() lied, there's %d bytes instead of %d\n",
141 ec_byte_bytes(&buf), (tell_bits+7)/8);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +1100142 ret=-1;
Jean-Marc Valinb3756702008-02-08 11:50:17 +1100143 }
Jean-Marc Valincb0956d2008-02-07 20:21:57 +1100144 tell_bits -= 8*ec_byte_bytes(&buf);
tterribe7e3293f2008-01-23 23:04:43 +0000145 ec_byte_readinit(&buf,ec_byte_get_buffer(&buf),ec_byte_bytes(&buf));
146 ec_dec_init(&dec,&buf);
147 for(j=0;j<sz;j++){
148 sym=ec_dec_uint(&dec,ft);
149 if(sym!=data[j]){
150 fprintf(stderr,
151 "Decoded %i instead of %i with ft of %i at position %i of %i.\n",
152 sym,data[j],ft,j,sz);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +1100153 ret=-1;
tterribe7e3293f2008-01-23 23:04:43 +0000154 }
155 }
156 ec_byte_writeclear(&buf);
tterribebab4fb12008-01-23 23:10:28 +0000157 free(data);
tterribe7e3293f2008-01-23 23:04:43 +0000158 }
Jean-Marc Valin3df6e272008-02-20 15:08:08 +1100159 return ret;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +1100160}