blob: 49d39a16938e3db1b647ee246a3e8ada40503eb4 [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;
tterribe06390d02008-01-11 03:13:50 +000020 long nbits;
tterribe3eff11d2008-01-11 05:51:49 +000021 long nbits2;
tterribe06390d02008-01-11 03:13:50 +000022 double entropy;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110023 int ft;
24 int ftb;
25 int sym;
26 int sz;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110027 int i;
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110028 int ret;
29 ret=0;
tterribe06390d02008-01-11 03:13:50 +000030 entropy=0;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110031 /*Testing encoding of raw bit values.*/
32 ec_byte_writeinit(&buf);
33 ec_enc_init(&enc,&buf);
Timothy B. Terriberry0268a992008-12-20 22:12:18 -050034 for(ft=2;ft<1024;ft++){
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110035 for(i=0;i<ft;i++){
tterribe06390d02008-01-11 03:13:50 +000036 entropy+=log(ft)*M_LOG2E;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110037 ec_enc_uint(&enc,i,ft);
38 }
39 }
40 /*Testing encoding of raw bit values.*/
41 for(ftb=0;ftb<16;ftb++){
42 for(i=0;i<(1<<ftb);i++){
tterribe06390d02008-01-11 03:13:50 +000043 entropy+=ftb;
tterribe3eff11d2008-01-11 05:51:49 +000044 nbits=ec_enc_tell(&enc,0);
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110045 ec_enc_bits(&enc,i,ftb);
tterribe3eff11d2008-01-11 05:51:49 +000046 nbits2=ec_enc_tell(&enc,0);
tterribe06390d02008-01-11 03:13:50 +000047 if(nbits2-nbits!=ftb){
48 fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
49 nbits2-nbits,ftb);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110050 ret=-1;
tterribe06390d02008-01-11 03:13:50 +000051 }
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110052 }
53 }
tterribe3eff11d2008-01-11 05:51:49 +000054 nbits=ec_enc_tell(&enc,4);
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110055 ec_enc_done(&enc);
tterribe06390d02008-01-11 03:13:50 +000056 fprintf(stderr,
tterribefad779c2008-01-11 05:12:17 +000057 "Encoded %0.2lf bits of entropy to %0.2lf bits (%0.3lf%% wasted).\n",
58 entropy,ldexp(nbits,-4),100*(nbits-ldexp(entropy,4))/nbits);
tterribe06390d02008-01-11 03:13:50 +000059 fprintf(stderr,"Packed to %li bytes.\n",(long)(buf.ptr-buf.buf));
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110060 ec_byte_readinit(&buf,ec_byte_get_buffer(&buf),ec_byte_bytes(&buf));
61 ec_dec_init(&dec,&buf);
Timothy B. Terriberry0268a992008-12-20 22:12:18 -050062 for(ft=2;ft<1024;ft++){
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110063 for(i=0;i<ft;i++){
64 sym=ec_dec_uint(&dec,ft);
65 if(sym!=i){
66 fprintf(stderr,"Decoded %i instead of %i with ft of %i.\n",sym,i,ft);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110067 ret=-1;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110068 }
69 }
70 }
71 for(ftb=0;ftb<16;ftb++){
72 for(i=0;i<(1<<ftb);i++){
73 sym=ec_dec_bits(&dec,ftb);
74 if(sym!=i){
75 fprintf(stderr,"Decoded %i instead of %i with ftb of %i.\n",sym,i,ftb);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110076 ret=-1;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110077 }
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110078 }
79 }
tterribe3eff11d2008-01-11 05:51:49 +000080 nbits2=ec_dec_tell(&dec,4);
81 if(nbits!=nbits2){
82 fprintf(stderr,
83 "Reported number of bits used was %0.2lf, should be %0.2lf.\n",
84 ldexp(nbits2,-4),ldexp(nbits,-4));
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110085 ret=-1;
tterribe3eff11d2008-01-11 05:51:49 +000086 }
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110087 ec_byte_writeclear(&buf);
tterribe7e3293f2008-01-23 23:04:43 +000088 fprintf(stderr,"Testing random streams...\n");
89 srand(0);
Jean-Marc Valin2991af52008-02-19 21:02:43 +110090 for(i=0;i<409600;i++){
tterribe7e3293f2008-01-23 23:04:43 +000091 unsigned *data;
92 int j;
Jean-Marc Valincb0956d2008-02-07 20:21:57 +110093 int tell_bits;
94 int zeros;
Jean-Marc Valin2991af52008-02-19 21:02:43 +110095 ft=rand()/((RAND_MAX>>(rand()%11))+1)+10;
96 sz=rand()/((RAND_MAX>>(rand()%9))+1);
tterribe7e3293f2008-01-23 23:04:43 +000097 data=(unsigned *)malloc(sz*sizeof(*data));
98 ec_byte_writeinit(&buf);
99 ec_enc_init(&enc,&buf);
Jean-Marc Valincb0956d2008-02-07 20:21:57 +1100100 zeros = rand()%13==0;
tterribe7e3293f2008-01-23 23:04:43 +0000101 for(j=0;j<sz;j++){
Jean-Marc Valincb0956d2008-02-07 20:21:57 +1100102 if (zeros)
103 data[j]=0;
104 else
105 data[j]=rand()%ft;
tterribe7e3293f2008-01-23 23:04:43 +0000106 ec_enc_uint(&enc,data[j],ft);
107 }
Jean-Marc Valin2991af52008-02-19 21:02:43 +1100108 if (rand()%2==0)
109 while(ec_enc_tell(&enc, 0)%8 != 0)
110 ec_enc_uint(&enc, rand()%2, 2);
Jean-Marc Valincb0956d2008-02-07 20:21:57 +1100111 tell_bits = ec_enc_tell(&enc, 0);
tterribe7e3293f2008-01-23 23:04:43 +0000112 ec_enc_done(&enc);
Jean-Marc Valinb3756702008-02-08 11:50:17 +1100113 if ((tell_bits+7)/8 < ec_byte_bytes(&buf))
114 {
Jean-Marc Valina82dfdd2008-03-13 23:01:55 +1100115 fprintf (stderr, "tell() lied, there's %li bytes instead of %d\n",
Jean-Marc Valinb3756702008-02-08 11:50:17 +1100116 ec_byte_bytes(&buf), (tell_bits+7)/8);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +1100117 ret=-1;
Jean-Marc Valinb3756702008-02-08 11:50:17 +1100118 }
Jean-Marc Valincb0956d2008-02-07 20:21:57 +1100119 tell_bits -= 8*ec_byte_bytes(&buf);
tterribe7e3293f2008-01-23 23:04:43 +0000120 ec_byte_readinit(&buf,ec_byte_get_buffer(&buf),ec_byte_bytes(&buf));
121 ec_dec_init(&dec,&buf);
122 for(j=0;j<sz;j++){
123 sym=ec_dec_uint(&dec,ft);
124 if(sym!=data[j]){
125 fprintf(stderr,
126 "Decoded %i instead of %i with ft of %i at position %i of %i.\n",
127 sym,data[j],ft,j,sz);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +1100128 ret=-1;
tterribe7e3293f2008-01-23 23:04:43 +0000129 }
130 }
131 ec_byte_writeclear(&buf);
tterribebab4fb12008-01-23 23:10:28 +0000132 free(data);
tterribe7e3293f2008-01-23 23:04:43 +0000133 }
Jean-Marc Valin3df6e272008-02-20 15:08:08 +1100134 return ret;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +1100135}