blob: 35bc193ce06459e74ecfee8e58c20e0cbfa7a5d1 [file] [log] [blame]
Jean-Marc Valin8b2ff0d2009-10-17 21:40:10 -04001/* Copyright (c) 2001-2008 Timothy B. Terriberry
2 Copyright (c) 2008-2009 Xiph.Org Foundation */
Gregory Maxwellf40bbf72009-02-03 20:36:57 -05003/*
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 - Neither the name of the Xiph.org Foundation nor the names of its
16 contributors may be used to endorse or promote products derived from
17 this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*/
31
Jean-Marc Valin02fa9132008-02-20 12:09:29 +110032#ifdef HAVE_CONFIG_H
33#include "config.h"
34#endif
35
Jean-Marc Valin821945d2008-04-10 13:24:48 +100036#include "arch.h"
Jean-Marc Valin9c3e22c2007-12-07 22:25:31 +110037#include "entdec.h"
38#include "mfrngcod.h"
39
40
41
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +110042/*A range decoder.
Jean-Marc Valin9c3e22c2007-12-07 22:25:31 +110043 This is an entropy decoder based upon \cite{Mar79}, which is itself a
44 rediscovery of the FIFO arithmetic code introduced by \cite{Pas76}.
45 It is very similar to arithmetic encoding, except that encoding is done with
46 digits in any base, instead of with bits, and so it is faster when using
47 larger bases (i.e.: a byte).
48 The author claims an average waste of $\frac{1}{2}\log_b(2b)$ bits, where $b$
49 is the base, longer than the theoretical optimum, but to my knowledge there
50 is no published justification for this claim.
51 This only seems true when using near-infinite precision arithmetic so that
52 the process is carried out with no rounding errors.
53
54 IBM (the author's employer) never sought to patent the idea, and to my
55 knowledge the algorithm is unencumbered by any patents, though its
56 performance is very competitive with proprietary arithmetic coding.
57 The two are based on very similar ideas, however.
58 An excellent description of implementation details is available at
59 http://www.arturocampos.com/ac_range.html
60 A recent work \cite{MNW98} which proposes several changes to arithmetic
61 encoding for efficiency actually re-discovers many of the principles
62 behind range encoding, and presents a good theoretical analysis of them.
63
Timothy B. Terriberry8d940a62008-10-19 14:41:38 -040064 End of stream is handled by writing out the smallest number of bits that
65 ensures that the stream will be correctly decoded regardless of the value of
66 any subsequent bits.
67 ec_dec_tell() can be used to determine how many bits were needed to decode
68 all the symbols thus far; other data can be packed in the remaining bits of
69 the input buffer.
Jean-Marc Valin9c3e22c2007-12-07 22:25:31 +110070 @PHDTHESIS{Pas76,
71 author="Richard Clark Pasco",
Timothy B. Terriberryd7101772007-12-11 13:25:00 +110072 title="Source coding algorithms for fast data compression",
Jean-Marc Valin9c3e22c2007-12-07 22:25:31 +110073 school="Dept. of Electrical Engineering, Stanford University",
74 address="Stanford, CA",
75 month=May,
76 year=1976
77 }
78 @INPROCEEDINGS{Mar79,
79 author="Martin, G.N.N.",
80 title="Range encoding: an algorithm for removing redundancy from a digitised
81 message",
82 booktitle="Video & Data Recording Conference",
83 year=1979,
84 address="Southampton",
85 month=Jul
86 }
87 @ARTICLE{MNW98,
88 author="Alistair Moffat and Radford Neal and Ian H. Witten",
89 title="Arithmetic Coding Revisited",
90 journal="{ACM} Transactions on Information Systems",
91 year=1998,
92 volume=16,
93 number=3,
94 pages="256--294",
95 month=Jul,
Timothy B. Terriberryf13fea72007-12-11 13:25:57 +110096 URL="http://www.stanford.edu/class/ee398/handouts/papers/Moffat98ArithmCoding.pdf"
Jean-Marc Valin9c3e22c2007-12-07 22:25:31 +110097 }*/
98
99
Jean-Marc Valin9c3e22c2007-12-07 22:25:31 +1100100/*Gets the next byte of input.
101 After all the bytes in the current packet have been consumed, and the extra
102 end code returned if needed, this function will continue to return zero each
103 time it is called.
104 Return: The next byte of input.*/
105static int ec_dec_in(ec_dec *_this){
106 int ret;
107 ret=ec_byte_read1(_this->buf);
108 if(ret<0){
Timothy B. Terriberrya2fd1162008-01-24 22:28:58 -0500109 ret=0;
Timothy B.B Terriberryd77f61a2008-10-19 14:24:53 -0400110 /*Needed to keep oc_dec_tell() operating correctly.*/
tterribe7e3293f2008-01-23 23:04:43 +0000111 ec_byte_adv1(_this->buf);
Jean-Marc Valin9c3e22c2007-12-07 22:25:31 +1100112 }
tterribe7e3293f2008-01-23 23:04:43 +0000113 return ret;
Jean-Marc Valin9c3e22c2007-12-07 22:25:31 +1100114}
115
Timothy B. Terriberryd7101772007-12-11 13:25:00 +1100116/*Normalizes the contents of dif and rng so that rng lies entirely in the
117 high-order symbol.*/
Jean-Marc Valinfd8fda92008-03-27 09:00:14 +1100118static inline void ec_dec_normalize(ec_dec *_this){
Jean-Marc Valin9c3e22c2007-12-07 22:25:31 +1100119 /*If the range is too small, rescale it and input some bits.*/
120 while(_this->rng<=EC_CODE_BOT){
121 int sym;
122 _this->rng<<=EC_SYM_BITS;
123 /*Use up the remaining bits from our last symbol.*/
124 sym=_this->rem<<EC_CODE_EXTRA&EC_SYM_MAX;
125 /*Read the next value from the input.*/
126 _this->rem=ec_dec_in(_this);
127 /*Take the rest of the bits we need from this new symbol.*/
128 sym|=_this->rem>>EC_SYM_BITS-EC_CODE_EXTRA;
129 _this->dif=(_this->dif<<EC_SYM_BITS)-sym&EC_CODE_MASK;
130 /*dif can never be larger than EC_CODE_TOP.
131 This is equivalent to the slightly more readable:
132 if(_this->dif>EC_CODE_TOP)_this->dif-=EC_CODE_TOP;*/
Timothy B. Terriberryd7101772007-12-11 13:25:00 +1100133 _this->dif^=_this->dif&_this->dif-1&EC_CODE_TOP;
Jean-Marc Valin9c3e22c2007-12-07 22:25:31 +1100134 }
135}
136
137void ec_dec_init(ec_dec *_this,ec_byte_buffer *_buf){
138 _this->buf=_buf;
139 _this->rem=ec_dec_in(_this);
140 _this->rng=1U<<EC_CODE_EXTRA;
141 _this->dif=_this->rng-(_this->rem>>EC_SYM_BITS-EC_CODE_EXTRA);
142 /*Normalize the interval.*/
143 ec_dec_normalize(_this);
Jean-Marc Valincef1d6a2010-09-02 10:16:56 -0400144 _this->end_byte=0; /* Required for platforms that have chars > 8 bits */
Jean-Marc Valinc08be442009-06-17 23:23:46 -0400145 _this->end_bits_left=0;
146 _this->nb_end_bits=0;
Jean-Marc Valinb1e017f2010-07-18 21:20:35 -0400147 _this->error=0;
Jean-Marc Valin9c3e22c2007-12-07 22:25:31 +1100148}
149
150
151unsigned ec_decode(ec_dec *_this,unsigned _ft){
152 unsigned s;
153 _this->nrm=_this->rng/_ft;
154 s=(unsigned)((_this->dif-1)/_this->nrm);
155 return _ft-EC_MINI(s+1,_ft);
156}
157
Jean-Marc Valin949a29b2009-07-25 20:16:01 -0400158unsigned ec_decode_bin(ec_dec *_this,unsigned _bits){
Jean-Marc Valinc2decd32008-03-22 22:58:45 +1100159 unsigned s;
Jean-Marc Valin949a29b2009-07-25 20:16:01 -0400160 _this->nrm=_this->rng>>_bits;
Jean-Marc Valinc2decd32008-03-22 22:58:45 +1100161 s=(unsigned)((_this->dif-1)/_this->nrm);
Jean-Marc Valin949a29b2009-07-25 20:16:01 -0400162 return (1<<_bits)-EC_MINI(s+1,1<<_bits);
163}
164
Jean-Marc Valinaaedf172010-09-10 20:20:04 -0400165unsigned ec_dec_bits(ec_dec *_this,unsigned bits){
Jean-Marc Valinc08be442009-06-17 23:23:46 -0400166 unsigned value=0;
167 int count=0;
168 _this->nb_end_bits += bits;
169 while (bits>=_this->end_bits_left)
170 {
171 value |= _this->end_byte>>(8-_this->end_bits_left)<<count;
172 count += _this->end_bits_left;
173 bits -= _this->end_bits_left;
174 _this->end_byte=ec_byte_look_at_end(_this->buf);
175 _this->end_bits_left = 8;
176 }
177 value |= ((_this->end_byte>>(8-_this->end_bits_left))&((1<<bits)-1))<<count;
178 _this->end_bits_left -= bits;
179 return value;
Jean-Marc Valinc2decd32008-03-22 22:58:45 +1100180}
181
Jean-Marc Valin9c3e22c2007-12-07 22:25:31 +1100182void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft){
183 ec_uint32 s;
Jean-Marc Valin821945d2008-04-10 13:24:48 +1000184 s=IMUL32(_this->nrm,(_ft-_fh));
Jean-Marc Valin9c3e22c2007-12-07 22:25:31 +1100185 _this->dif-=s;
Jean-Marc Valin821945d2008-04-10 13:24:48 +1000186 _this->rng=_fl>0?IMUL32(_this->nrm,(_fh-_fl)):_this->rng-s;
Jean-Marc Valin9c3e22c2007-12-07 22:25:31 +1100187 ec_dec_normalize(_this);
188}
189
Timothy B. Terriberry43e94062010-05-29 23:02:33 -0400190/*The probability of having a "one" is given in 1/65536.*/
191int ec_dec_bit_prob(ec_dec *_this,unsigned _prob){
Timothy B. Terriberry299747e2010-05-29 22:47:37 -0400192 ec_uint32 r;
193 ec_uint32 s;
194 ec_uint32 d;
195 int val;
196 r=_this->rng;
197 d=_this->dif;
Timothy B. Terriberry43e94062010-05-29 23:02:33 -0400198 s=(r>>16)*_prob;
Timothy B. Terriberry299747e2010-05-29 22:47:37 -0400199 val=d<=s;
200 if(!val)_this->dif=d-s;
201 _this->rng=val?s:r-s;
202 ec_dec_normalize(_this);
203 return val;
204}
205
Jean-Marc Valin531f2ae2010-08-02 09:01:28 -0400206ec_uint32 ec_dec_tell(ec_dec *_this,int _b){
tterribe3eff11d2008-01-11 05:51:49 +0000207 ec_uint32 r;
208 int l;
Jean-Marc Valin531f2ae2010-08-02 09:01:28 -0400209 ec_uint32 nbits;
Timothy B.B Terriberryd77f61a2008-10-19 14:24:53 -0400210 nbits=(ec_byte_bytes(_this->buf)-(EC_CODE_BITS+EC_SYM_BITS-1)/EC_SYM_BITS)*
211 EC_SYM_BITS;
Timothy B. Terriberry8d940a62008-10-19 14:41:38 -0400212 /*To handle the non-integral number of bits still left in the decoder state,
tterribe3eff11d2008-01-11 05:51:49 +0000213 we compute the number of bits of low that must be encoded to ensure that
Timothy B. Terriberry8d940a62008-10-19 14:41:38 -0400214 the value is inside the range for any possible subsequent bits.*/
Jean-Marc Valinc08be442009-06-17 23:23:46 -0400215 nbits+=EC_CODE_BITS+1+_this->nb_end_bits;
tterribe3eff11d2008-01-11 05:51:49 +0000216 nbits<<=_b;
217 l=EC_ILOG(_this->rng);
218 r=_this->rng>>l-16;
219 while(_b-->0){
220 int b;
221 r=r*r>>15;
222 b=(int)(r>>16);
223 l=l<<1|b;
224 r>>=b;
225 }
226 return nbits-l;
227}