16b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org/* Copyright (c) 2007-2011 Xiph.Org Foundation, Mozilla Corporation,
26b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org                           Gregory Maxwell
36b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   Written by Jean-Marc Valin, Gregory Maxwell, and Timothy B. Terriberry */
46b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org/*
56b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   Redistribution and use in source and binary forms, with or without
66b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   modification, are permitted provided that the following conditions
76b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   are met:
86b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org
96b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   - Redistributions of source code must retain the above copyright
106b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   notice, this list of conditions and the following disclaimer.
116b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org
126b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   - Redistributions in binary form must reproduce the above copyright
136b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   notice, this list of conditions and the following disclaimer in the
146b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   documentation and/or other materials provided with the distribution.
156b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org
166b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
206b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
216b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
226b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
236b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
246b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
256b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
266b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org*/
286b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org
29885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef HAVE_CONFIG_H
30885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "config.h"
31885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
32885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
33885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include <stdlib.h>
34885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include <stdio.h>
35885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include <math.h>
36885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include <time.h>
37885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "entcode.h"
38885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "entenc.h"
39885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "entdec.h"
40885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include <string.h>
41885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
42885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "entenc.c"
43885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "entdec.c"
44885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "entcode.c"
45885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
46885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifndef M_LOG2E
47885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org# define M_LOG2E    1.4426950408889634074
48885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
49885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define DATA_SIZE 10000000
50885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define DATA_SIZE2 10000
51885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
52885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgint main(int _argc,char **_argv){
53885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc         enc;
54885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_dec         dec;
55885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  long           nbits;
56885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  long           nbits2;
57885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  double         entropy;
58885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  int            ft;
59885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  int            ftb;
60885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  int            sz;
61885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  int            i;
62885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  int            ret;
63885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  unsigned int   sym;
64885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  unsigned int   seed;
65885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  unsigned char *ptr;
66885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  const char    *env_seed;
67885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ret=0;
68885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  entropy=0;
69885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if (_argc > 2) {
70885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org	fprintf(stderr, "Usage: %s [<seed>]\n", _argv[0]);
71885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org	return 1;
72885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
73885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  env_seed = getenv("SEED");
74885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  if (_argc > 1)
75885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    seed = atoi(_argv[1]);
76885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  else if (env_seed)
77885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    seed = atoi(env_seed);
78885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  else
79885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    seed = time(NULL);
80885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  /*Testing encoding of raw bit values.*/
81885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ptr = (unsigned char *)malloc(DATA_SIZE);
82885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_init(&enc,ptr, DATA_SIZE);
83885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  for(ft=2;ft<1024;ft++){
84885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    for(i=0;i<ft;i++){
85885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      entropy+=log(ft)*M_LOG2E;
86885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      ec_enc_uint(&enc,i,ft);
87885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
88885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  }
89885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  /*Testing encoding of raw bit values.*/
90885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  for(ftb=1;ftb<16;ftb++){
91885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    for(i=0;i<(1<<ftb);i++){
92885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      entropy+=ftb;
93885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      nbits=ec_tell(&enc);
94885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      ec_enc_bits(&enc,i,ftb);
95885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      nbits2=ec_tell(&enc);
96885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if(nbits2-nbits!=ftb){
97885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
98885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         nbits2-nbits,ftb);
99885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        ret=-1;
100885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
101885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
102885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  }
103885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  nbits=ec_tell_frac(&enc);
104885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_done(&enc);
105885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  fprintf(stderr,
106885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   "Encoded %0.2lf bits of entropy to %0.2lf bits (%0.3lf%% wasted).\n",
107885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   entropy,ldexp(nbits,-3),100*(nbits-ldexp(entropy,3))/nbits);
108885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  fprintf(stderr,"Packed to %li bytes.\n",(long)ec_range_bytes(&enc));
109885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_dec_init(&dec,ptr,DATA_SIZE);
110885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  for(ft=2;ft<1024;ft++){
111885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    for(i=0;i<ft;i++){
112885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      sym=ec_dec_uint(&dec,ft);
113885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if(sym!=(unsigned)i){
114885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        fprintf(stderr,"Decoded %i instead of %i with ft of %i.\n",sym,i,ft);
115885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        ret=-1;
116885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
117885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
118885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  }
119885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  for(ftb=1;ftb<16;ftb++){
120885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    for(i=0;i<(1<<ftb);i++){
121885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      sym=ec_dec_bits(&dec,ftb);
122885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if(sym!=(unsigned)i){
123885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        fprintf(stderr,"Decoded %i instead of %i with ftb of %i.\n",sym,i,ftb);
124885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        ret=-1;
125885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
126885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
127885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  }
128885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  nbits2=ec_tell_frac(&dec);
129885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  if(nbits!=nbits2){
130885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr,
131885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org     "Reported number of bits used was %0.2lf, should be %0.2lf.\n",
132885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org     ldexp(nbits2,-3),ldexp(nbits,-3));
133885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ret=-1;
134885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  }
135885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  /*Testing an encoder bust prefers range coder data over raw bits.
136885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    This isn't a general guarantee, will only work for data that is buffered in
137885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org     the encoder state and not yet stored in the user buffer, and should never
138885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org     get used in practice.
139885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    It's mostly here for code coverage completeness.*/
140885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  /*Start with a 16-bit buffer.*/
141885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_init(&enc,ptr,2);
142885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  /*Write 7 raw bits.*/
143885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_bits(&enc,0x55,7);
144885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  /*Write 12.3 bits of range coder data.*/
145885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_uint(&enc,1,2);
146885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_uint(&enc,1,3);
147885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_uint(&enc,1,4);
148885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_uint(&enc,1,5);
149885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_uint(&enc,2,6);
150885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_uint(&enc,6,7);
151885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_done(&enc);
152885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_dec_init(&dec,ptr,2);
153885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  if(!enc.error
154885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /*The raw bits should have been overwritten by the range coder data.*/
155885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   ||ec_dec_bits(&dec,7)!=0x05
156885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /*And all the range coder data should have been encoded correctly.*/
157885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   ||ec_dec_uint(&dec,2)!=1
158885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   ||ec_dec_uint(&dec,3)!=1
159885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   ||ec_dec_uint(&dec,4)!=1
160885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   ||ec_dec_uint(&dec,5)!=1
161885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   ||ec_dec_uint(&dec,6)!=2
162885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   ||ec_dec_uint(&dec,7)!=6){
163885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr,"Encoder bust overwrote range coder data with raw bits.\n");
164885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ret=-1;
165885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  }
166885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  srand(seed);
167885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  fprintf(stderr,"Testing random streams... Random seed: %u (%.4X)\n", seed, rand() % 65536);
168885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  for(i=0;i<409600;i++){
169885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    unsigned *data;
170885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    unsigned *tell;
171885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    unsigned tell_bits;
172885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int       j;
173885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int zeros;
174885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ft=rand()/((RAND_MAX>>(rand()%11U))+1U)+10;
175885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    sz=rand()/((RAND_MAX>>(rand()%9U))+1U);
176885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    data=(unsigned *)malloc(sz*sizeof(*data));
177885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    tell=(unsigned *)malloc((sz+1)*sizeof(*tell));
178885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ec_enc_init(&enc,ptr,DATA_SIZE2);
179885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    zeros = rand()%13==0;
180885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    tell[0]=ec_tell_frac(&enc);
181885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    for(j=0;j<sz;j++){
182885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (zeros)
183885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        data[j]=0;
184885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      else
185885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        data[j]=rand()%ft;
186885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      ec_enc_uint(&enc,data[j],ft);
187885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      tell[j+1]=ec_tell_frac(&enc);
188885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
189885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if (rand()%2==0)
190885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      while(ec_tell(&enc)%8 != 0)
191885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        ec_enc_uint(&enc, rand()%2, 2);
192885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    tell_bits = ec_tell(&enc);
193885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ec_enc_done(&enc);
194885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if(tell_bits!=(unsigned)ec_tell(&enc)){
195885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      fprintf(stderr,"ec_tell() changed after ec_enc_done(): %i instead of %i (Random seed: %u)\n",
196885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       ec_tell(&enc),tell_bits,seed);
197885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      ret=-1;
198885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
199885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if ((tell_bits+7)/8 < ec_range_bytes(&enc))
200885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    {
201885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      fprintf (stderr, "ec_tell() lied, there's %i bytes instead of %d (Random seed: %u)\n",
202885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               ec_range_bytes(&enc), (tell_bits+7)/8,seed);
203885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      ret=-1;
204885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
205885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ec_dec_init(&dec,ptr,DATA_SIZE2);
206885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if(ec_tell_frac(&dec)!=tell[0]){
207885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      fprintf(stderr,
208885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
209885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       0,ec_tell_frac(&dec),tell[0],seed);
210885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
211885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    for(j=0;j<sz;j++){
212885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      sym=ec_dec_uint(&dec,ft);
213885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if(sym!=data[j]){
214885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        fprintf(stderr,
215885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         "Decoded %i instead of %i with ft of %i at position %i of %i (Random seed: %u).\n",
216885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         sym,data[j],ft,j,sz,seed);
217885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        ret=-1;
218885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
219885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if(ec_tell_frac(&dec)!=tell[j+1]){
220885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        fprintf(stderr,
221885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
222885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         j+1,ec_tell_frac(&dec),tell[j+1],seed);
223885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
224885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
225885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    free(tell);
226885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    free(data);
227885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  }
228885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  /*Test compatibility between multiple different encode/decode routines.*/
229885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  for(i=0;i<409600;i++){
230885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    unsigned *logp1;
231885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    unsigned *data;
232885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    unsigned *tell;
233885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    unsigned *enc_method;
234885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int       j;
235885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    sz=rand()/((RAND_MAX>>(rand()%9U))+1U);
236885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    logp1=(unsigned *)malloc(sz*sizeof(*logp1));
237885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    data=(unsigned *)malloc(sz*sizeof(*data));
238885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    tell=(unsigned *)malloc((sz+1)*sizeof(*tell));
239885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    enc_method=(unsigned *)malloc(sz*sizeof(*enc_method));
240885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ec_enc_init(&enc,ptr,DATA_SIZE2);
241885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    tell[0]=ec_tell_frac(&enc);
242885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    for(j=0;j<sz;j++){
243885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      data[j]=rand()/((RAND_MAX>>1)+1);
244885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      logp1[j]=(rand()%15)+1;
245885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      enc_method[j]=rand()/((RAND_MAX>>2)+1);
246885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      switch(enc_method[j]){
247885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        case 0:{
248885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          ec_encode(&enc,data[j]?(1<<logp1[j])-1:0,
249885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org           (1<<logp1[j])-(data[j]?0:1),1<<logp1[j]);
250885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }break;
251885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        case 1:{
252885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          ec_encode_bin(&enc,data[j]?(1<<logp1[j])-1:0,
253885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org           (1<<logp1[j])-(data[j]?0:1),logp1[j]);
254885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }break;
255885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        case 2:{
256885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          ec_enc_bit_logp(&enc,data[j],logp1[j]);
257885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }break;
258885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        case 3:{
259885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          unsigned char icdf[2];
260885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          icdf[0]=1;
261885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          icdf[1]=0;
262885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          ec_enc_icdf(&enc,data[j],icdf,logp1[j]);
263885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }break;
264885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
265885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      tell[j+1]=ec_tell_frac(&enc);
266885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
267885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ec_enc_done(&enc);
268885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if((ec_tell(&enc)+7U)/8U<ec_range_bytes(&enc)){
269885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      fprintf(stderr,"tell() lied, there's %i bytes instead of %d (Random seed: %u)\n",
270885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       ec_range_bytes(&enc),(ec_tell(&enc)+7)/8,seed);
271885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      ret=-1;
272885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
273885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ec_dec_init(&dec,ptr,DATA_SIZE2);
274885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if(ec_tell_frac(&dec)!=tell[0]){
275885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      fprintf(stderr,
276885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
277885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       0,ec_tell_frac(&dec),tell[0],seed);
278885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
279885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    for(j=0;j<sz;j++){
280885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int fs;
281885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int dec_method;
282885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      dec_method=rand()/((RAND_MAX>>2)+1);
283885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      switch(dec_method){
284885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        case 0:{
285885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          fs=ec_decode(&dec,1<<logp1[j]);
286885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          sym=fs>=(1<<logp1[j])-1;
287885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          ec_dec_update(&dec,sym?(1<<logp1[j])-1:0,
288885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org           (1<<logp1[j])-(sym?0:1),1<<logp1[j]);
289885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }break;
290885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        case 1:{
291885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          fs=ec_decode_bin(&dec,logp1[j]);
292885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          sym=fs>=(1<<logp1[j])-1;
293885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          ec_dec_update(&dec,sym?(1<<logp1[j])-1:0,
294885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org           (1<<logp1[j])-(sym?0:1),1<<logp1[j]);
295885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }break;
296885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        case 2:{
297885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          sym=ec_dec_bit_logp(&dec,logp1[j]);
298885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }break;
299885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        case 3:{
300885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          unsigned char icdf[2];
301885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          icdf[0]=1;
302885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          icdf[1]=0;
303885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          sym=ec_dec_icdf(&dec,icdf,logp1[j]);
304885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }break;
305885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
306885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if(sym!=data[j]){
307885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        fprintf(stderr,
308885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         "Decoded %i instead of %i with logp1 of %i at position %i of %i (Random seed: %u).\n",
309885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         sym,data[j],logp1[j],j,sz,seed);
310885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        fprintf(stderr,"Encoding method: %i, decoding method: %i\n",
311885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         enc_method[j],dec_method);
312885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        ret=-1;
313885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
314885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if(ec_tell_frac(&dec)!=tell[j+1]){
315885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        fprintf(stderr,
316885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
317885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         j+1,ec_tell_frac(&dec),tell[j+1],seed);
318885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
319885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
320885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    free(enc_method);
321885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    free(tell);
322885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    free(data);
323885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    free(logp1);
324885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  }
325885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_init(&enc,ptr,DATA_SIZE2);
326885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_bit_logp(&enc,0,1);
327885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_bit_logp(&enc,0,1);
328885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_bit_logp(&enc,0,1);
329885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_bit_logp(&enc,0,1);
330885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_bit_logp(&enc,0,2);
331885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_patch_initial_bits(&enc,3,2);
332885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  if(enc.error){
333885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr,"patch_initial_bits failed");
334885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ret=-1;
335885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  }
336885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_patch_initial_bits(&enc,0,5);
337885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  if(!enc.error){
338885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr,"patch_initial_bits didn't fail when it should have");
339885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ret=-1;
340885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  }
341885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_done(&enc);
342885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  if(ec_range_bytes(&enc)!=1||ptr[0]!=192){
343885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr,"Got %d when expecting 192 for patch_initial_bits",ptr[0]);
344885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ret=-1;
345885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  }
346885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_init(&enc,ptr,DATA_SIZE2);
347885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_bit_logp(&enc,0,1);
348885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_bit_logp(&enc,0,1);
349885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_bit_logp(&enc,1,6);
350885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_bit_logp(&enc,0,2);
351885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_patch_initial_bits(&enc,0,2);
352885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  if(enc.error){
353885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr,"patch_initial_bits failed");
354885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ret=-1;
355885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  }
356885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_done(&enc);
357885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  if(ec_range_bytes(&enc)!=2||ptr[0]!=63){
358885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr,"Got %d when expecting 63 for patch_initial_bits",ptr[0]);
359885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ret=-1;
360885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  }
361885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_init(&enc,ptr,2);
362885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_bit_logp(&enc,0,2);
363885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  for(i=0;i<48;i++){
364885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ec_enc_bits(&enc,0,1);
365885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  }
366885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_done(&enc);
367885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  if(!enc.error){
368885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr,"Raw bits overfill didn't fail when it should have");
369885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ret=-1;
370885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  }
371885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_init(&enc,ptr,2);
372885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  for(i=0;i<17;i++){
373885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ec_enc_bits(&enc,0,1);
374885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  }
375885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ec_enc_done(&enc);
376885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  if(!enc.error){
377885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fprintf(stderr,"17 raw bits encoded in two bytes");
378885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    ret=-1;
379885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  }
380885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  free(ptr);
381885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  return ret;
382885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
383