Recognizes if input is ogg or not.
[xiph.git] / ghost / libentcode / rangeenc.c
blobea0b761706a0fdc5e54e05863f3f625da27ec2e9
1 #include <stddef.h>
2 #include "entenc.h"
3 #include "mfrngcod.h"
7 /*A range encoder.
8 See rangedec.c and the references for implementation details
9 \cite{Mar79,MNW98}.
11 @INPROCEEDINGS{Mar79,
12 author="Martin, G.N.N.",
13 title="Range encoding: an algorithm for removing redundancy from a digitised
14 message",
15 booktitle="Video \& Data Recording Conference",
16 year=1979,
17 address="Southampton",
18 month=Jul
20 @ARTICLE{MNW98,
21 author="Alistair Moffat and Radford Neal and Ian H. Witten",
22 title="Arithmetic Coding Revisited",
23 journal="{ACM} Transactions on Information Systems",
24 year=1998,
25 volume=16,
26 number=3,
27 pages="256--294",
28 month=Jul,
29 URL="http://www.stanford.edu/class/ee398/handouts/papers/Moffat98ArithmCoding.pdf"
30 }*/
34 /*Outputs a symbol, with a carry bit.
35 If there is a potential to propagate a carry over several symbols, they are
36 buffered until it can be determined whether or not an actual carry will
37 occur.
38 If the counter for the buffered symbols overflows, then the stream becomes
39 undecodable.
40 This gives a theoretical limit of a few billion symbols in a single packet on
41 32-bit systems.
42 The alternative is to truncate the range in order to force a carry, but
43 requires similar carry tracking in the decoder, needlessly slowing it down.*/
44 static void ec_enc_carry_out(ec_enc *_this,int _c){
45 if(_c!=EC_SYM_MAX){
46 /*No further carry propagation possible, flush buffer.*/
47 int carry;
48 carry=_c>>EC_SYM_BITS;
49 /*Don't output a byte on the first write.
50 This compare should be taken care of by branch-prediction thereafter.*/
51 if(_this->rem>=0)ec_byte_write1(_this->buf,_this->rem+carry);
52 if(_this->ext>0){
53 unsigned sym;
54 sym=EC_SYM_MAX+carry&EC_SYM_MAX;
55 do ec_byte_write1(_this->buf,sym);
56 while(--(_this->ext)>0);
58 _this->rem=_c&EC_SYM_MAX;
60 else _this->ext++;
63 static void ec_enc_normalize(ec_enc *_this){
64 /*If the range is too small, output some bits and rescale it.*/
65 while(_this->rng<=EC_CODE_BOT){
66 ec_enc_carry_out(_this,(int)(_this->low>>EC_CODE_SHIFT));
67 /*Move the next-to-high-order symbol into the high-order position.*/
68 _this->low=_this->low<<EC_SYM_BITS&EC_CODE_TOP-1;
69 _this->rng<<=EC_SYM_BITS;
73 void ec_enc_init(ec_enc *_this,ec_byte_buffer *_buf){
74 _this->buf=_buf;
75 _this->rem=-1;
76 _this->ext=0;
77 _this->low=0;
78 _this->rng=EC_CODE_TOP;
81 void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft){
82 ec_uint32 r;
83 r=_this->rng/_ft;
84 if(_fl>0){
85 _this->low+=_this->rng-r*(_ft-_fl);
86 _this->rng=r*(_fh-_fl);
88 else _this->rng-=r*(_ft-_fh);
89 ec_enc_normalize(_this);
92 long ec_enc_tell(ec_enc *_this,int _b){
93 ec_uint32 r;
94 int l;
95 long nbits;
96 nbits=ec_byte_bytes(_this->buf)+(_this->rem>=0)+_this->ext<<3;
97 /*To handle the non-integral number of bits still left in the encoder state,
98 we compute the number of bits of low that must be encoded to ensure that
99 the value is inside the range for any possible subsequent bits.
100 Note that this is subtly different than the actual value we would end the
101 stream with, which tries to make as many of the trailing bits zeros as
102 possible.*/
103 nbits+=EC_CODE_BITS;
104 nbits<<=_b;
105 l=EC_ILOG(_this->rng);
106 r=_this->rng>>l-16;
107 while(_b-->0){
108 int b;
109 r=r*r>>15;
110 b=(int)(r>>16);
111 l=l<<1|b;
112 r>>=b;
114 return nbits-l;
117 void ec_enc_done(ec_enc *_this){
118 /*We compute the integer in the current interval that has the largest number
119 of trailing zeros, and write that to the stream.
120 This is guaranteed to yield the smallest possible encoding.*/
121 if(_this->low){
122 unsigned end;
123 end=EC_CODE_TOP;
124 /*Ensure that the end value is in the range.*/
125 if(end-_this->low>=_this->rng){
126 unsigned msk;
127 msk=EC_CODE_TOP-1;
129 msk>>=1;
130 end=_this->low+msk&~msk|msk+1;
132 while(end-_this->low>=_this->rng);
134 /*The remaining output is the next free end.*/
135 while(end){
136 ec_enc_carry_out(_this,end>>EC_CODE_SHIFT);
137 end=end<<EC_SYM_BITS&EC_CODE_TOP-1;
140 /*If we have a buffered byte...*/
141 if(_this->rem>=0||_this->ext>0){
142 unsigned char *buf;
143 long i;
144 /*Flush it into the output buffer.*/
145 ec_enc_carry_out(_this,0);
146 _this->rem=-1;
147 /*We may be able to drop some redundant bytes from the end.*/
148 buf=ec_byte_get_buffer(_this->buf);
149 i=ec_byte_bytes(_this->buf);
150 /*Strip trailing zeros.*/
151 do i--;
152 while(i>0&&!buf[i]);
153 /*Strip one trailing EC_FOF_RSV1 byte if the buffer ends in a string of
154 consecutive EC_FOF_RSV1 bytes preceded by one (or more) zeros.*/
155 if(i>0&&buf[i]==EC_FOF_RSV1){
156 long j;
157 j=i;
158 do j--;
159 while(j>0&&buf[j]==EC_FOF_RSV1);
160 if(!buf[j])i--;
162 ec_byte_writetrunc(_this->buf,i+1);