blob: 397a29ed04eed4cba8b2c6db995a16c57a917f96 [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>
Gregory Maxwell7aa0ed42009-02-19 21:28:33 -05008#include <sys/types.h>
9#include <unistd.h>
10#include <time.h>
Jean-Marc Valin6238bc02008-01-28 22:28:54 +110011#include "entcode.h"
12#include "entenc.h"
13#include "entdec.h"
Jean-Marc Valinc08be442009-06-17 23:23:46 -040014#include <string.h>
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110015
Jean-Marc Valin4d108fc2008-12-23 09:31:39 -050016#include "../libcelt/rangeenc.c"
17#include "../libcelt/rangedec.c"
18#include "../libcelt/entenc.c"
19#include "../libcelt/entdec.c"
20#include "../libcelt/entcode.c"
21
Jean-Marc Valin2f5ccf62008-02-27 07:48:48 +110022#ifndef M_LOG2E
23# define M_LOG2E 1.4426950408889634074
24#endif
Jean-Marc Valinc08be442009-06-17 23:23:46 -040025#define DATA_SIZE 10000000
26#define DATA_SIZE2 10000
Jean-Marc Valin2f5ccf62008-02-27 07:48:48 +110027
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110028int main(int _argc,char **_argv){
29 ec_byte_buffer buf;
30 ec_enc enc;
31 ec_dec dec;
tterribe06390d02008-01-11 03:13:50 +000032 long nbits;
tterribe3eff11d2008-01-11 05:51:49 +000033 long nbits2;
tterribe06390d02008-01-11 03:13:50 +000034 double entropy;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110035 int ft;
36 int ftb;
37 int sym;
38 int sz;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110039 int i;
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110040 int ret;
Gregory Maxwell7aa0ed42009-02-19 21:28:33 -050041 unsigned int seed;
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110042 ret=0;
tterribe06390d02008-01-11 03:13:50 +000043 entropy=0;
Jean-Marc Valinc08be442009-06-17 23:23:46 -040044 unsigned char *ptr;
Gregory Maxwell7aa0ed42009-02-19 21:28:33 -050045 if (_argc > 2) {
46 fprintf(stderr, "Usage: %s [<seed>]\n", _argv[0]);
47 return 1;
48 }
49 if (_argc > 1)
50 seed = atoi(_argv[1]);
51 else
52 seed = (time(NULL) ^ (getpid()%(1<<16) << 16));
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110053 /*Testing encoding of raw bit values.*/
Jean-Marc Valinc08be442009-06-17 23:23:46 -040054 ptr = malloc(DATA_SIZE);
55 ec_byte_writeinit_buffer(&buf, ptr, DATA_SIZE);
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110056 ec_enc_init(&enc,&buf);
Timothy B. Terriberry0268a992008-12-20 22:12:18 -050057 for(ft=2;ft<1024;ft++){
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110058 for(i=0;i<ft;i++){
tterribe06390d02008-01-11 03:13:50 +000059 entropy+=log(ft)*M_LOG2E;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110060 ec_enc_uint(&enc,i,ft);
61 }
62 }
63 /*Testing encoding of raw bit values.*/
64 for(ftb=0;ftb<16;ftb++){
65 for(i=0;i<(1<<ftb);i++){
tterribe06390d02008-01-11 03:13:50 +000066 entropy+=ftb;
tterribe3eff11d2008-01-11 05:51:49 +000067 nbits=ec_enc_tell(&enc,0);
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110068 ec_enc_bits(&enc,i,ftb);
tterribe3eff11d2008-01-11 05:51:49 +000069 nbits2=ec_enc_tell(&enc,0);
tterribe06390d02008-01-11 03:13:50 +000070 if(nbits2-nbits!=ftb){
71 fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
72 nbits2-nbits,ftb);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110073 ret=-1;
tterribe06390d02008-01-11 03:13:50 +000074 }
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110075 }
76 }
tterribe3eff11d2008-01-11 05:51:49 +000077 nbits=ec_enc_tell(&enc,4);
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110078 ec_enc_done(&enc);
tterribe06390d02008-01-11 03:13:50 +000079 fprintf(stderr,
tterribefad779c2008-01-11 05:12:17 +000080 "Encoded %0.2lf bits of entropy to %0.2lf bits (%0.3lf%% wasted).\n",
81 entropy,ldexp(nbits,-4),100*(nbits-ldexp(entropy,4))/nbits);
tterribe06390d02008-01-11 03:13:50 +000082 fprintf(stderr,"Packed to %li bytes.\n",(long)(buf.ptr-buf.buf));
Jean-Marc Valinc08be442009-06-17 23:23:46 -040083 ec_byte_readinit(&buf,ptr,DATA_SIZE);
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110084 ec_dec_init(&dec,&buf);
Timothy B. Terriberry0268a992008-12-20 22:12:18 -050085 for(ft=2;ft<1024;ft++){
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110086 for(i=0;i<ft;i++){
87 sym=ec_dec_uint(&dec,ft);
88 if(sym!=i){
89 fprintf(stderr,"Decoded %i instead of %i with ft of %i.\n",sym,i,ft);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110090 ret=-1;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +110091 }
92 }
93 }
94 for(ftb=0;ftb<16;ftb++){
95 for(i=0;i<(1<<ftb);i++){
96 sym=ec_dec_bits(&dec,ftb);
97 if(sym!=i){
98 fprintf(stderr,"Decoded %i instead of %i with ftb of %i.\n",sym,i,ftb);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +110099 ret=-1;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +1100100 }
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +1100101 }
102 }
tterribe3eff11d2008-01-11 05:51:49 +0000103 nbits2=ec_dec_tell(&dec,4);
104 if(nbits!=nbits2){
105 fprintf(stderr,
106 "Reported number of bits used was %0.2lf, should be %0.2lf.\n",
107 ldexp(nbits2,-4),ldexp(nbits,-4));
Jean-Marc Valin3df6e272008-02-20 15:08:08 +1100108 ret=-1;
tterribe3eff11d2008-01-11 05:51:49 +0000109 }
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +1100110 ec_byte_writeclear(&buf);
Gregory Maxwell7aa0ed42009-02-19 21:28:33 -0500111 srand(seed);
112 fprintf(stderr,"Testing random streams... Random seed: %u (%.4X)\n", seed, rand() % 65536);
Jean-Marc Valin2991af52008-02-19 21:02:43 +1100113 for(i=0;i<409600;i++){
tterribe7e3293f2008-01-23 23:04:43 +0000114 unsigned *data;
115 int j;
Jean-Marc Valincb0956d2008-02-07 20:21:57 +1100116 int tell_bits;
117 int zeros;
Jean-Marc Valin2991af52008-02-19 21:02:43 +1100118 ft=rand()/((RAND_MAX>>(rand()%11))+1)+10;
119 sz=rand()/((RAND_MAX>>(rand()%9))+1);
tterribe7e3293f2008-01-23 23:04:43 +0000120 data=(unsigned *)malloc(sz*sizeof(*data));
Jean-Marc Valinc08be442009-06-17 23:23:46 -0400121 ec_byte_writeinit_buffer(&buf, ptr, DATA_SIZE2);
tterribe7e3293f2008-01-23 23:04:43 +0000122 ec_enc_init(&enc,&buf);
Jean-Marc Valincb0956d2008-02-07 20:21:57 +1100123 zeros = rand()%13==0;
tterribe7e3293f2008-01-23 23:04:43 +0000124 for(j=0;j<sz;j++){
Jean-Marc Valincb0956d2008-02-07 20:21:57 +1100125 if (zeros)
126 data[j]=0;
127 else
128 data[j]=rand()%ft;
tterribe7e3293f2008-01-23 23:04:43 +0000129 ec_enc_uint(&enc,data[j],ft);
130 }
Jean-Marc Valin2991af52008-02-19 21:02:43 +1100131 if (rand()%2==0)
132 while(ec_enc_tell(&enc, 0)%8 != 0)
133 ec_enc_uint(&enc, rand()%2, 2);
Jean-Marc Valincb0956d2008-02-07 20:21:57 +1100134 tell_bits = ec_enc_tell(&enc, 0);
tterribe7e3293f2008-01-23 23:04:43 +0000135 ec_enc_done(&enc);
Jean-Marc Valinb3756702008-02-08 11:50:17 +1100136 if ((tell_bits+7)/8 < ec_byte_bytes(&buf))
137 {
Gregory Maxwell7aa0ed42009-02-19 21:28:33 -0500138 fprintf (stderr, "tell() lied, there's %li bytes instead of %d (Random seed: %u)\n",
139 ec_byte_bytes(&buf), (tell_bits+7)/8,seed);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +1100140 ret=-1;
Jean-Marc Valinb3756702008-02-08 11:50:17 +1100141 }
Jean-Marc Valincb0956d2008-02-07 20:21:57 +1100142 tell_bits -= 8*ec_byte_bytes(&buf);
Jean-Marc Valinc08be442009-06-17 23:23:46 -0400143 ec_byte_readinit(&buf,ptr,DATA_SIZE2);
tterribe7e3293f2008-01-23 23:04:43 +0000144 ec_dec_init(&dec,&buf);
145 for(j=0;j<sz;j++){
146 sym=ec_dec_uint(&dec,ft);
147 if(sym!=data[j]){
148 fprintf(stderr,
Gregory Maxwell7aa0ed42009-02-19 21:28:33 -0500149 "Decoded %i instead of %i with ft of %i at position %i of %i (Random seed: %u).\n",
150 sym,data[j],ft,j,sz,seed);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +1100151 ret=-1;
tterribe7e3293f2008-01-23 23:04:43 +0000152 }
153 }
154 ec_byte_writeclear(&buf);
tterribebab4fb12008-01-23 23:10:28 +0000155 free(data);
tterribe7e3293f2008-01-23 23:04:43 +0000156 }
Jean-Marc Valinc08be442009-06-17 23:23:46 -0400157 free(ptr);
Jean-Marc Valin3df6e272008-02-20 15:08:08 +1100158 return ret;
Timothy B. Terriberry2ec8d9e2007-12-06 15:09:53 +1100159}