blob: 93441dfe5353fc0cd219fe001439ea3705788574 [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>
Jean-Marc Valin6238bc02008-01-28 22:28:54 +11008#include "entcode.h"
9#include "entenc.h"
10#include "entdec.h"
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110011
Jean-Marc Valin2f5ccf62008-02-27 07:48:48 +110012#ifndef M_LOG2E
13# define M_LOG2E 1.4426950408889634074
14#endif
15
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110016int main(int _argc,char **_argv){
17 ec_byte_buffer buf;
18 ec_enc enc;
19 ec_dec dec;
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +110020 ec_uint64 sym64;
tterribe06390d02008-01-11 03:13:50 +000021 long nbits;
tterribe3eff11d2008-01-11 05:51:49 +000022 long nbits2;
tterribe06390d02008-01-11 03:13:50 +000023 double entropy;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110024 int ft;
25 int ftb;
26 int sym;
27 int sz;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110028 int i;
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110029 int ret;
30 ret=0;
tterribe06390d02008-01-11 03:13:50 +000031 entropy=0;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110032 /*Testing encoding of raw bit values.*/
33 ec_byte_writeinit(&buf);
34 ec_enc_init(&enc,&buf);
35 for(ft=0;ft<1024;ft++){
36 for(i=0;i<ft;i++){
tterribe06390d02008-01-11 03:13:50 +000037 entropy+=log(ft)*M_LOG2E;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110038 ec_enc_uint(&enc,i,ft);
tterribe06390d02008-01-11 03:13:50 +000039 entropy+=log(ft)*M_LOG2E+30;
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +110040 ec_enc_uint64(&enc,(ec_uint64)i<<30|i,(ec_uint64)ft<<30);
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110041 }
42 }
43 /*Testing encoding of raw bit values.*/
44 for(ftb=0;ftb<16;ftb++){
45 for(i=0;i<(1<<ftb);i++){
tterribe06390d02008-01-11 03:13:50 +000046 entropy+=ftb;
tterribe3eff11d2008-01-11 05:51:49 +000047 nbits=ec_enc_tell(&enc,0);
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110048 ec_enc_bits(&enc,i,ftb);
tterribe3eff11d2008-01-11 05:51:49 +000049 nbits2=ec_enc_tell(&enc,0);
tterribe06390d02008-01-11 03:13:50 +000050 if(nbits2-nbits!=ftb){
51 fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
52 nbits2-nbits,ftb);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110053 ret=-1;
tterribe06390d02008-01-11 03:13:50 +000054 }
55 entropy+=ftb+30;
56 nbits=nbits2;
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +110057 ec_enc_bits64(&enc,(ec_uint64)i<<30|i,ftb+30);
tterribe3eff11d2008-01-11 05:51:49 +000058 nbits2=ec_enc_tell(&enc,0);
tterribe06390d02008-01-11 03:13:50 +000059 if(nbits2-nbits!=ftb+30){
60 fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
61 nbits2-nbits,ftb+30);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110062 ret=-1;
tterribe06390d02008-01-11 03:13:50 +000063 }
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110064 }
65 }
tterribe3eff11d2008-01-11 05:51:49 +000066 nbits=ec_enc_tell(&enc,4);
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110067 ec_enc_done(&enc);
tterribe06390d02008-01-11 03:13:50 +000068 fprintf(stderr,
tterribefad779c2008-01-11 05:12:17 +000069 "Encoded %0.2lf bits of entropy to %0.2lf bits (%0.3lf%% wasted).\n",
70 entropy,ldexp(nbits,-4),100*(nbits-ldexp(entropy,4))/nbits);
tterribe06390d02008-01-11 03:13:50 +000071 fprintf(stderr,"Packed to %li bytes.\n",(long)(buf.ptr-buf.buf));
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110072 ec_byte_readinit(&buf,ec_byte_get_buffer(&buf),ec_byte_bytes(&buf));
73 ec_dec_init(&dec,&buf);
74 for(ft=0;ft<1024;ft++){
75 for(i=0;i<ft;i++){
76 sym=ec_dec_uint(&dec,ft);
77 if(sym!=i){
78 fprintf(stderr,"Decoded %i instead of %i with ft of %i.\n",sym,i,ft);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110079 ret=-1;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110080 }
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +110081 sym64=ec_dec_uint64(&dec,(ec_uint64)ft<<30);
82 if(sym64!=((ec_uint64)i<<30|i)){
Jean-Marc Valina82dfdd2008-03-13 23:01:55 +110083 fprintf(stderr,"Decoded %lu instead of %lu with ft of %lu.\n",sym64,
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +110084 (ec_uint64)i<<30|i,(ec_uint64)ft<<30);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110085 ret=-1;
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +110086 }
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110087 }
88 }
89 for(ftb=0;ftb<16;ftb++){
90 for(i=0;i<(1<<ftb);i++){
91 sym=ec_dec_bits(&dec,ftb);
92 if(sym!=i){
93 fprintf(stderr,"Decoded %i instead of %i with ftb of %i.\n",sym,i,ftb);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110094 ret=-1;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110095 }
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +110096 sym64=ec_dec_bits64(&dec,ftb+30);
97 if(sym64!=((ec_uint64)i<<30|i)){
Jean-Marc Valina82dfdd2008-03-13 23:01:55 +110098 fprintf(stderr,"Decoded %lu instead of %lu with ftb of %i.\n",
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +110099 sym64,(ec_uint64)i<<30|i,ftb+30);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +1100100 ret=-1;
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +1100101 }
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +1100102 }
103 }
tterribe3eff11d2008-01-11 05:51:49 +0000104 nbits2=ec_dec_tell(&dec,4);
105 if(nbits!=nbits2){
106 fprintf(stderr,
107 "Reported number of bits used was %0.2lf, should be %0.2lf.\n",
108 ldexp(nbits2,-4),ldexp(nbits,-4));
Jean-Marc Valin3df6e272008-02-20 15:08:08 +1100109 ret=-1;
tterribe3eff11d2008-01-11 05:51:49 +0000110 }
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +1100111 ec_byte_writeclear(&buf);
tterribe7e3293f2008-01-23 23:04:43 +0000112 fprintf(stderr,"Testing random streams...\n");
113 srand(0);
Jean-Marc Valin2991af52008-02-19 21:02:43 +1100114 for(i=0;i<409600;i++){
tterribe7e3293f2008-01-23 23:04:43 +0000115 unsigned *data;
116 int j;
Jean-Marc Valincb0956d2008-02-07 20:21:57 +1100117 int tell_bits;
118 int zeros;
Jean-Marc Valin2991af52008-02-19 21:02:43 +1100119 ft=rand()/((RAND_MAX>>(rand()%11))+1)+10;
120 sz=rand()/((RAND_MAX>>(rand()%9))+1);
tterribe7e3293f2008-01-23 23:04:43 +0000121 data=(unsigned *)malloc(sz*sizeof(*data));
122 ec_byte_writeinit(&buf);
123 ec_enc_init(&enc,&buf);
Jean-Marc Valincb0956d2008-02-07 20:21:57 +1100124 zeros = rand()%13==0;
tterribe7e3293f2008-01-23 23:04:43 +0000125 for(j=0;j<sz;j++){
Jean-Marc Valincb0956d2008-02-07 20:21:57 +1100126 if (zeros)
127 data[j]=0;
128 else
129 data[j]=rand()%ft;
tterribe7e3293f2008-01-23 23:04:43 +0000130 ec_enc_uint(&enc,data[j],ft);
131 }
Jean-Marc Valin2991af52008-02-19 21:02:43 +1100132 if (rand()%2==0)
133 while(ec_enc_tell(&enc, 0)%8 != 0)
134 ec_enc_uint(&enc, rand()%2, 2);
Jean-Marc Valincb0956d2008-02-07 20:21:57 +1100135 tell_bits = ec_enc_tell(&enc, 0);
tterribe7e3293f2008-01-23 23:04:43 +0000136 ec_enc_done(&enc);
Jean-Marc Valinb3756702008-02-08 11:50:17 +1100137 if ((tell_bits+7)/8 < ec_byte_bytes(&buf))
138 {
Jean-Marc Valina82dfdd2008-03-13 23:01:55 +1100139 fprintf (stderr, "tell() lied, there's %li bytes instead of %d\n",
Jean-Marc Valinb3756702008-02-08 11:50:17 +1100140 ec_byte_bytes(&buf), (tell_bits+7)/8);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +1100141 ret=-1;
Jean-Marc Valinb3756702008-02-08 11:50:17 +1100142 }
Jean-Marc Valincb0956d2008-02-07 20:21:57 +1100143 tell_bits -= 8*ec_byte_bytes(&buf);
tterribe7e3293f2008-01-23 23:04:43 +0000144 ec_byte_readinit(&buf,ec_byte_get_buffer(&buf),ec_byte_bytes(&buf));
145 ec_dec_init(&dec,&buf);
146 for(j=0;j<sz;j++){
147 sym=ec_dec_uint(&dec,ft);
148 if(sym!=data[j]){
149 fprintf(stderr,
150 "Decoded %i instead of %i with ft of %i at position %i of %i.\n",
151 sym,data[j],ft,j,sz);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +1100152 ret=-1;
tterribe7e3293f2008-01-23 23:04:43 +0000153 }
154 }
155 ec_byte_writeclear(&buf);
tterribebab4fb12008-01-23 23:10:28 +0000156 free(data);
tterribe7e3293f2008-01-23 23:04:43 +0000157 }
Jean-Marc Valin3df6e272008-02-20 15:08:08 +1100158 return ret;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +1100159}