Line | Count | Source |
1 | | /* Copyright (c) 2001-2011 Timothy B. Terriberry |
2 | | Copyright (c) 2008-2009 Xiph.Org Foundation */ |
3 | | /* |
4 | | Redistribution and use in source and binary forms, with or without |
5 | | modification, are permitted provided that the following conditions |
6 | | are met: |
7 | | |
8 | | - Redistributions of source code must retain the above copyright |
9 | | notice, this list of conditions and the following disclaimer. |
10 | | |
11 | | - Redistributions in binary form must reproduce the above copyright |
12 | | notice, this list of conditions and the following disclaimer in the |
13 | | documentation and/or other materials provided with the distribution. |
14 | | |
15 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
16 | | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
17 | | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
18 | | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER |
19 | | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
20 | | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
21 | | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
22 | | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
23 | | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
24 | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | | */ |
27 | | |
28 | | #if defined(HAVE_CONFIG_H) |
29 | | # include "config.h" |
30 | | #endif |
31 | | #include "os_support.h" |
32 | | #include "arch.h" |
33 | | #include "entenc.h" |
34 | | #include "mfrngcod.h" |
35 | | |
36 | | /*A range encoder. |
37 | | See entdec.c and the references for implementation details \cite{Mar79,MNW98}. |
38 | | |
39 | | @INPROCEEDINGS{Mar79, |
40 | | author="Martin, G.N.N.", |
41 | | title="Range encoding: an algorithm for removing redundancy from a digitised |
42 | | message", |
43 | | booktitle="Video \& Data Recording Conference", |
44 | | year=1979, |
45 | | address="Southampton", |
46 | | month=Jul |
47 | | } |
48 | | @ARTICLE{MNW98, |
49 | | author="Alistair Moffat and Radford Neal and Ian H. Witten", |
50 | | title="Arithmetic Coding Revisited", |
51 | | journal="{ACM} Transactions on Information Systems", |
52 | | year=1998, |
53 | | volume=16, |
54 | | number=3, |
55 | | pages="256--294", |
56 | | month=Jul, |
57 | | URL="http://www.stanford.edu/class/ee398/handouts/papers/Moffat98ArithmCoding.pdf" |
58 | | }*/ |
59 | | |
60 | 1.34G | static int ec_write_byte(ec_enc *_this,unsigned _value){ |
61 | 1.34G | if(_this->offs+_this->end_offs>=_this->storage)return -1; |
62 | 1.33G | _this->buf[_this->offs++]=(unsigned char)_value; |
63 | 1.33G | return 0; |
64 | 1.34G | } |
65 | | |
66 | 271M | static int ec_write_byte_at_end(ec_enc *_this,unsigned _value){ |
67 | 271M | if(_this->offs+_this->end_offs>=_this->storage)return -1; |
68 | 271M | _this->buf[_this->storage-++(_this->end_offs)]=(unsigned char)_value; |
69 | 271M | return 0; |
70 | 271M | } |
71 | | |
72 | | /*Outputs a symbol, with a carry bit. |
73 | | If there is a potential to propagate a carry over several symbols, they are |
74 | | buffered until it can be determined whether or not an actual carry will |
75 | | occur. |
76 | | If the counter for the buffered symbols overflows, then the stream becomes |
77 | | undecodable. |
78 | | This gives a theoretical limit of a few billion symbols in a single packet on |
79 | | 32-bit systems. |
80 | | The alternative is to truncate the range in order to force a carry, but |
81 | | requires similar carry tracking in the decoder, needlessly slowing it down.*/ |
82 | 1.53G | static void ec_enc_carry_out(ec_enc *_this,int _c){ |
83 | 1.53G | if(_c!=EC_SYM_MAX){ |
84 | | /*No further carry propagation possible, flush buffer.*/ |
85 | 1.42G | int carry; |
86 | 1.42G | carry=_c>>EC_SYM_BITS; |
87 | | /*Don't output a byte on the first write. |
88 | | This compare should be taken care of by branch-prediction thereafter.*/ |
89 | 1.42G | if(_this->rem>=0)_this->error|=ec_write_byte(_this,_this->rem+carry); |
90 | 1.42G | if(_this->ext>0){ |
91 | 102M | unsigned sym; |
92 | 102M | sym=(EC_SYM_MAX+carry)&EC_SYM_MAX; |
93 | 102M | do _this->error|=ec_write_byte(_this,sym); |
94 | 102M | while(--(_this->ext)>0); |
95 | 102M | } |
96 | 1.42G | _this->rem=_c&EC_SYM_MAX; |
97 | 1.42G | } |
98 | 102M | else _this->ext++; |
99 | 1.53G | } |
100 | | |
101 | 5.22G | static OPUS_INLINE void ec_enc_normalize(ec_enc *_this){ |
102 | | /*If the range is too small, output some bits and rescale it.*/ |
103 | 6.39G | while(_this->rng<=EC_CODE_BOT){ |
104 | 1.17G | ec_enc_carry_out(_this,(int)(_this->val>>EC_CODE_SHIFT)); |
105 | | /*Move the next-to-high-order symbol into the high-order position.*/ |
106 | 1.17G | _this->val=(_this->val<<EC_SYM_BITS)&(EC_CODE_TOP-1); |
107 | 1.17G | _this->rng<<=EC_SYM_BITS; |
108 | 1.17G | _this->nbits_total+=EC_SYM_BITS; |
109 | 1.17G | } |
110 | 5.22G | } |
111 | | |
112 | 232M | void ec_enc_init(ec_enc *_this,unsigned char *_buf,opus_uint32 _size){ |
113 | 232M | _this->buf=_buf; |
114 | 232M | _this->end_offs=0; |
115 | 232M | _this->end_window=0; |
116 | 232M | _this->nend_bits=0; |
117 | | /*This is the offset from which ec_tell() will subtract partial bits.*/ |
118 | 232M | _this->nbits_total=EC_CODE_BITS+1; |
119 | 232M | _this->offs=0; |
120 | 232M | _this->rng=EC_CODE_TOP; |
121 | 232M | _this->rem=-1; |
122 | 232M | _this->val=0; |
123 | 232M | _this->ext=0; |
124 | 232M | _this->storage=_size; |
125 | 232M | _this->error=0; |
126 | 232M | } |
127 | | |
128 | 408M | void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft){ |
129 | 408M | opus_uint32 r; |
130 | 408M | r=celt_udiv(_this->rng,_ft); |
131 | 408M | if(_fl>0){ |
132 | 142M | _this->val+=_this->rng-IMUL32(r,(_ft-_fl)); |
133 | 142M | _this->rng=IMUL32(r,(_fh-_fl)); |
134 | 142M | } |
135 | 265M | else _this->rng-=IMUL32(r,(_ft-_fh)); |
136 | 408M | ec_enc_normalize(_this); |
137 | 408M | } |
138 | | |
139 | 543M | void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits){ |
140 | 543M | opus_uint32 r; |
141 | 543M | r=_this->rng>>_bits; |
142 | 543M | if(_fl>0){ |
143 | 344M | _this->val+=_this->rng-IMUL32(r,((1U<<_bits)-_fl)); |
144 | 344M | _this->rng=IMUL32(r,(_fh-_fl)); |
145 | 344M | } |
146 | 198M | else _this->rng-=IMUL32(r,((1U<<_bits)-_fh)); |
147 | 543M | ec_enc_normalize(_this); |
148 | 543M | } |
149 | | |
150 | | /*The probability of having a "one" is 1/(1<<_logp).*/ |
151 | 1.03G | void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp){ |
152 | 1.03G | opus_uint32 r; |
153 | 1.03G | opus_uint32 s; |
154 | 1.03G | opus_uint32 l; |
155 | 1.03G | r=_this->rng; |
156 | 1.03G | l=_this->val; |
157 | 1.03G | s=r>>_logp; |
158 | 1.03G | r-=s; |
159 | 1.03G | if(_val)_this->val=l+r; |
160 | 1.03G | _this->rng=_val?s:r; |
161 | 1.03G | ec_enc_normalize(_this); |
162 | 1.03G | } |
163 | | |
164 | 3.24G | void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb){ |
165 | 3.24G | opus_uint32 r; |
166 | 3.24G | r=_this->rng>>_ftb; |
167 | 3.24G | if(_s>0){ |
168 | 1.86G | _this->val+=_this->rng-IMUL32(r,_icdf[_s-1]); |
169 | 1.86G | _this->rng=IMUL32(r,_icdf[_s-1]-_icdf[_s]); |
170 | 1.86G | } |
171 | 1.37G | else _this->rng-=IMUL32(r,_icdf[_s]); |
172 | 3.24G | ec_enc_normalize(_this); |
173 | 3.24G | } |
174 | | |
175 | 0 | void ec_enc_icdf16(ec_enc *_this,int _s,const opus_uint16 *_icdf,unsigned _ftb){ |
176 | 0 | opus_uint32 r; |
177 | 0 | r=_this->rng>>_ftb; |
178 | 0 | if(_s>0){ |
179 | 0 | _this->val+=_this->rng-IMUL32(r,_icdf[_s-1]); |
180 | 0 | _this->rng=IMUL32(r,_icdf[_s-1]-_icdf[_s]); |
181 | 0 | } |
182 | 0 | else _this->rng-=IMUL32(r,_icdf[_s]); |
183 | 0 | ec_enc_normalize(_this); |
184 | 0 | } |
185 | | |
186 | 297M | void ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft){ |
187 | 297M | unsigned ft; |
188 | 297M | unsigned fl; |
189 | 297M | int ftb; |
190 | | /*In order to optimize EC_ILOG(), it is undefined for the value 0.*/ |
191 | 297M | celt_assert(_ft>1); |
192 | 297M | _ft--; |
193 | 297M | ftb=EC_ILOG(_ft); |
194 | 297M | if(ftb>EC_UINT_BITS){ |
195 | 171M | ftb-=EC_UINT_BITS; |
196 | 171M | ft=(_ft>>ftb)+1; |
197 | 171M | fl=(unsigned)(_fl>>ftb); |
198 | 171M | ec_encode(_this,fl,fl+1,ft); |
199 | 171M | ec_enc_bits(_this,_fl&(((opus_uint32)1<<ftb)-1U),ftb); |
200 | 171M | } |
201 | 126M | else ec_encode(_this,_fl,_fl+1,_ft+1); |
202 | 297M | } |
203 | | |
204 | 602M | void ec_enc_bits(ec_enc *_this,opus_uint32 _fl,unsigned _bits){ |
205 | 602M | ec_window window; |
206 | 602M | int used; |
207 | 602M | window=_this->end_window; |
208 | 602M | used=_this->nend_bits; |
209 | 602M | celt_assert(_bits>0); |
210 | 602M | if(used+_bits>EC_WINDOW_SIZE){ |
211 | 234M | do{ |
212 | 234M | _this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX); |
213 | 234M | window>>=EC_SYM_BITS; |
214 | 234M | used-=EC_SYM_BITS; |
215 | 234M | } |
216 | 234M | while(used>=EC_SYM_BITS); |
217 | 80.7M | } |
218 | 602M | window|=(ec_window)_fl<<used; |
219 | 602M | used+=_bits; |
220 | 602M | _this->end_window=window; |
221 | 602M | _this->nend_bits=used; |
222 | 602M | _this->nbits_total+=_bits; |
223 | 602M | } |
224 | | |
225 | 53.4M | void ec_enc_patch_initial_bits(ec_enc *_this,unsigned _val,unsigned _nbits){ |
226 | 53.4M | int shift; |
227 | 53.4M | unsigned mask; |
228 | 53.4M | celt_assert(_nbits<=EC_SYM_BITS); |
229 | 53.4M | shift=EC_SYM_BITS-_nbits; |
230 | 53.4M | mask=((1<<_nbits)-1)<<shift; |
231 | 53.4M | if(_this->offs>0){ |
232 | | /*The first byte has been finalized.*/ |
233 | 53.4M | _this->buf[0]=(unsigned char)((_this->buf[0]&~mask)|_val<<shift); |
234 | 53.4M | } |
235 | 0 | else if(_this->rem>=0){ |
236 | | /*The first byte is still awaiting carry propagation.*/ |
237 | 0 | _this->rem=(_this->rem&~mask)|_val<<shift; |
238 | 0 | } |
239 | 0 | else if(_this->rng<=(EC_CODE_TOP>>_nbits)){ |
240 | | /*The renormalization loop has never been run.*/ |
241 | 0 | _this->val=(_this->val&~((opus_uint32)mask<<EC_CODE_SHIFT))| |
242 | 0 | (opus_uint32)_val<<(EC_CODE_SHIFT+shift); |
243 | 0 | } |
244 | | /*The encoder hasn't even encoded _nbits of data yet.*/ |
245 | 0 | else _this->error=-1; |
246 | 53.4M | } |
247 | | |
248 | 267M | void ec_enc_shrink(ec_enc *_this,opus_uint32 _size){ |
249 | 267M | celt_assert(_this->offs+_this->end_offs<=_size); |
250 | 267M | OPUS_MOVE(_this->buf+_size-_this->end_offs, |
251 | 267M | _this->buf+_this->storage-_this->end_offs,_this->end_offs); |
252 | 267M | _this->storage=_size; |
253 | 267M | } |
254 | | |
255 | 232M | void ec_enc_done(ec_enc *_this){ |
256 | 232M | ec_window window; |
257 | 232M | int used; |
258 | 232M | opus_uint32 msk; |
259 | 232M | opus_uint32 end; |
260 | 232M | int l; |
261 | | /*We output the minimum number of bits that ensures that the symbols encoded |
262 | | thus far will be decoded correctly regardless of the bits that follow.*/ |
263 | 232M | l=EC_CODE_BITS-EC_ILOG(_this->rng); |
264 | 232M | msk=(EC_CODE_TOP-1)>>l; |
265 | 232M | end=(_this->val+msk)&~msk; |
266 | 232M | if((end|msk)>=_this->val+_this->rng){ |
267 | 28.1M | l++; |
268 | 28.1M | msk>>=1; |
269 | 28.1M | end=(_this->val+msk)&~msk; |
270 | 28.1M | } |
271 | 414M | while(l>0){ |
272 | 182M | ec_enc_carry_out(_this,(int)(end>>EC_CODE_SHIFT)); |
273 | 182M | end=(end<<EC_SYM_BITS)&(EC_CODE_TOP-1); |
274 | 182M | l-=EC_SYM_BITS; |
275 | 182M | } |
276 | | /*If we have a buffered byte flush it into the output buffer.*/ |
277 | 232M | if(_this->rem>=0||_this->ext>0)ec_enc_carry_out(_this,0); |
278 | | /*If we have buffered extra bits, flush them as well.*/ |
279 | 232M | window=_this->end_window; |
280 | 232M | used=_this->nend_bits; |
281 | 269M | while(used>=EC_SYM_BITS){ |
282 | 36.6M | _this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX); |
283 | 36.6M | window>>=EC_SYM_BITS; |
284 | 36.6M | used-=EC_SYM_BITS; |
285 | 36.6M | } |
286 | | /*Clear any excess space and add any remaining extra bits to the last byte.*/ |
287 | 232M | if(!_this->error){ |
288 | 232M | if (_this->buf) OPUS_CLEAR(_this->buf+_this->offs, |
289 | 232M | _this->storage-_this->offs-_this->end_offs); |
290 | 232M | if(used>0){ |
291 | | /*If there's no range coder data at all, give up.*/ |
292 | 25.6M | if(_this->end_offs>=_this->storage)_this->error=-1; |
293 | 25.6M | else{ |
294 | 25.6M | l=-l; |
295 | | /*If we've busted, don't add too many extra bits to the last byte; it |
296 | | would corrupt the range coder data, and that's more important.*/ |
297 | 25.6M | if(_this->offs+_this->end_offs>=_this->storage&&l<used){ |
298 | 0 | window&=(1<<l)-1; |
299 | 0 | _this->error=-1; |
300 | 0 | } |
301 | 25.6M | _this->buf[_this->storage-_this->end_offs-1]|=(unsigned char)window; |
302 | 25.6M | } |
303 | 25.6M | } |
304 | 232M | } |
305 | 232M | } |