int ec_dec_done(ec_dec *_this){ unsigned low; int ret; /*Check to make sure we've used all the input bytes. This ensures that no more ones would ever be inserted into the decoder.*/ if(_this->buf->ptr-ec_byte_get_buffer(_this->buf)<= ec_byte_bytes(_this->buf)){ return 0; } /*We compute the smallest finitely odd fraction that fits inside the current range, and write that to the stream. This is guaranteed to yield the smallest possible encoding.*/ /*TODO: Fix this line, as it is wrong. It doesn't seem worth being able to make this check to do an extra subtraction for every symbol decoded.*/ low=/*What we want: _this->top-_this->rng; What we have:*/_this->dif if(low){ unsigned end; end=EC_CODE_TOP; /*Ensure that the next free end is in the range.*/ if(end-low>=_this->rng){ unsigned msk; msk=EC_CODE_TOP-1; do{ msk>>=1; end=(low+msk)&~msk|msk+1; } while(end-low>=_this->rng); } /*The remaining input should have been the next free end.*/ return end-low!=_this->dif; }
int main(void) { int i; int ret = 0; ec_enc enc; ec_dec dec; ec_byte_buffer buf; unsigned char *ptr; int val[10000], decay[10000]; ALLOC_STACK; ptr = malloc(DATA_SIZE); ec_byte_writeinit_buffer(&buf, ptr, DATA_SIZE); //ec_byte_writeinit(&buf); ec_enc_init(&enc,&buf); val[0] = 3; decay[0] = 6000; val[1] = 0; decay[1] = 5800; val[2] = -1; decay[2] = 5600; for (i=3;i<10000;i++) { val[i] = rand()%15-7; decay[i] = rand()%11000+5000; } for (i=0;i<10000;i++) ec_laplace_encode(&enc, &val[i], decay[i]); ec_enc_done(&enc); ec_byte_readinit(&buf,ec_byte_get_buffer(&buf),ec_byte_bytes(&buf)); ec_dec_init(&dec,&buf); for (i=0;i<10000;i++) { int d = ec_laplace_decode(&dec, decay[i]); if (d != val[i]) { fprintf (stderr, "Got %d instead of %d\n", d, val[i]); ret = 1; } } return ret; }
int main(int _argc,char **_argv){ ec_byte_buffer buf; ec_enc enc; ec_dec dec; long nbits; long nbits2; double entropy; int ft; int ftb; int sym; int sz; int i; int ret; ret=0; entropy=0; /*Testing encoding of raw bit values.*/ ec_byte_writeinit(&buf); ec_enc_init(&enc,&buf); for(ft=0;ft<1024;ft++){ for(i=0;i<ft;i++){ entropy+=log(ft)*M_LOG2E; ec_enc_uint(&enc,i,ft); } } /*Testing encoding of raw bit values.*/ for(ftb=0;ftb<16;ftb++){ for(i=0;i<(1<<ftb);i++){ entropy+=ftb; nbits=ec_enc_tell(&enc,0); ec_enc_bits(&enc,i,ftb); nbits2=ec_enc_tell(&enc,0); if(nbits2-nbits!=ftb){ fprintf(stderr,"Used %li bits to encode %i bits directly.\n", nbits2-nbits,ftb); ret=-1; } } } nbits=ec_enc_tell(&enc,4); ec_enc_done(&enc); fprintf(stderr, "Encoded %0.2lf bits of entropy to %0.2lf bits (%0.3lf%% wasted).\n", entropy,ldexp(nbits,-4),100*(nbits-ldexp(entropy,4))/nbits); fprintf(stderr,"Packed to %li bytes.\n",(long)(buf.ptr-buf.buf)); ec_byte_readinit(&buf,ec_byte_get_buffer(&buf),ec_byte_bytes(&buf)); ec_dec_init(&dec,&buf); for(ft=0;ft<1024;ft++){ for(i=0;i<ft;i++){ sym=ec_dec_uint(&dec,ft); if(sym!=i){ fprintf(stderr,"Decoded %i instead of %i with ft of %i.\n",sym,i,ft); ret=-1; } } } for(ftb=0;ftb<16;ftb++){ for(i=0;i<(1<<ftb);i++){ sym=ec_dec_bits(&dec,ftb); if(sym!=i){ fprintf(stderr,"Decoded %i instead of %i with ftb of %i.\n",sym,i,ftb); ret=-1; } } } nbits2=ec_dec_tell(&dec,4); if(nbits!=nbits2){ fprintf(stderr, "Reported number of bits used was %0.2lf, should be %0.2lf.\n", ldexp(nbits2,-4),ldexp(nbits,-4)); ret=-1; } ec_byte_writeclear(&buf); fprintf(stderr,"Testing random streams...\n"); srand(0); for(i=0;i<409600;i++){ unsigned *data; int j; int tell_bits; int zeros; ft=rand()/((RAND_MAX>>(rand()%11))+1)+10; sz=rand()/((RAND_MAX>>(rand()%9))+1); data=(unsigned *)malloc(sz*sizeof(*data)); ec_byte_writeinit(&buf); ec_enc_init(&enc,&buf); zeros = rand()%13==0; for(j=0;j<sz;j++){ if (zeros) data[j]=0; else data[j]=rand()%ft; ec_enc_uint(&enc,data[j],ft); } if (rand()%2==0) while(ec_enc_tell(&enc, 0)%8 != 0) ec_enc_uint(&enc, rand()%2, 2); tell_bits = ec_enc_tell(&enc, 0); ec_enc_done(&enc); if ((tell_bits+7)/8 < ec_byte_bytes(&buf)) { fprintf (stderr, "tell() lied, there's %li bytes instead of %d\n", ec_byte_bytes(&buf), (tell_bits+7)/8); ret=-1; } tell_bits -= 8*ec_byte_bytes(&buf); ec_byte_readinit(&buf,ec_byte_get_buffer(&buf),ec_byte_bytes(&buf)); ec_dec_init(&dec,&buf); for(j=0;j<sz;j++){ sym=ec_dec_uint(&dec,ft); if(sym!=data[j]){ fprintf(stderr, "Decoded %i instead of %i with ft of %i at position %i of %i.\n", sym,data[j],ft,j,sz); ret=-1; } } ec_byte_writeclear(&buf); free(data); } return ret; }