blob: 3ae6eed04fae45ff7e1561957114de56cd72b262
1 | /* ***** BEGIN LICENSE BLOCK ***** |
2 | * Source last modified: $Id: bitstream.c,v 1.1.2.1.6.1 2005/10/19 00:18:49 gwright Exp $ |
3 | * |
4 | * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. |
5 | * |
6 | * The contents of this file, and the files included with this file, |
7 | * are subject to the current version of the RealNetworks Public |
8 | * Source License (the "RPSL") available at |
9 | * http://www.helixcommunity.org/content/rpsl unless you have licensed |
10 | * the file under the current version of the RealNetworks Community |
11 | * Source License (the "RCSL") available at |
12 | * http://www.helixcommunity.org/content/rcsl, in which case the RCSL |
13 | * will apply. You may also obtain the license terms directly from |
14 | * RealNetworks. You may not use this file except in compliance with |
15 | * the RPSL or, if you have a valid RCSL with RealNetworks applicable |
16 | * to this file, the RCSL. Please see the applicable RPSL or RCSL for |
17 | * the rights, obligations and limitations governing use of the |
18 | * contents of the file. |
19 | * |
20 | * This file is part of the Helix DNA Technology. RealNetworks is the |
21 | * developer of the Original Code and owns the copyrights in the |
22 | * portions it created. |
23 | * |
24 | * This file, and the files included with this file, is distributed |
25 | * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY |
26 | * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS |
27 | * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES |
28 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET |
29 | * ENJOYMENT OR NON-INFRINGEMENT. |
30 | * |
31 | * Technology Compatibility Kit Test Suite(s) Location: |
32 | * http://www.helixcommunity.org/content/tck |
33 | * |
34 | * Contributor(s): |
35 | * |
36 | * ***** END LICENSE BLOCK ***** */ |
37 | |
38 | /************************************************************************************** |
39 | * Fixed-point HE-AAC decoder |
40 | * Jon Recker (jrecker@real.com) |
41 | * February 2005 |
42 | * |
43 | * bitstream.c - bitstream parsing functions |
44 | **************************************************************************************/ |
45 | |
46 | #include "bitstream.h" |
47 | |
48 | /************************************************************************************** |
49 | * Function: SetBitstreamPointer |
50 | * |
51 | * Description: initialize bitstream reader |
52 | * |
53 | * Inputs: pointer to BitStreamInfo struct |
54 | * number of bytes in bitstream |
55 | * pointer to byte-aligned buffer of data to read from |
56 | * |
57 | * Outputs: initialized bitstream info struct |
58 | * |
59 | * Return: none |
60 | **************************************************************************************/ |
61 | void SetBitstreamPointer(BitStreamInfo *bsi, int nBytes, unsigned char *buf) |
62 | { |
63 | /* init bitstream */ |
64 | bsi->bytePtr = buf; |
65 | bsi->iCache = 0; /* 4-byte unsigned int */ |
66 | bsi->cachedBits = 0; /* i.e. zero bits in cache */ |
67 | bsi->nBytes = nBytes; |
68 | } |
69 | |
70 | /************************************************************************************** |
71 | * Function: RefillBitstreamCache |
72 | * |
73 | * Description: read new data from bitstream buffer into 32-bit cache |
74 | * |
75 | * Inputs: pointer to initialized BitStreamInfo struct |
76 | * |
77 | * Outputs: updated bitstream info struct |
78 | * |
79 | * Return: none |
80 | * |
81 | * Notes: only call when iCache is completely drained (resets bitOffset to 0) |
82 | * always loads 4 new bytes except when bsi->nBytes < 4 (end of buffer) |
83 | * stores data as big-endian in cache, regardless of machine endian-ness |
84 | **************************************************************************************/ |
85 | static __inline void RefillBitstreamCache(BitStreamInfo *bsi) |
86 | { |
87 | int nBytes = bsi->nBytes; |
88 | |
89 | /* optimize for common case, independent of machine endian-ness */ |
90 | if (nBytes >= 4) { |
91 | bsi->iCache = (*bsi->bytePtr++) << 24; |
92 | bsi->iCache |= (*bsi->bytePtr++) << 16; |
93 | bsi->iCache |= (*bsi->bytePtr++) << 8; |
94 | bsi->iCache |= (*bsi->bytePtr++); |
95 | bsi->cachedBits = 32; |
96 | bsi->nBytes -= 4; |
97 | } else { |
98 | bsi->iCache = 0; |
99 | while (nBytes--) { |
100 | bsi->iCache |= (*bsi->bytePtr++); |
101 | bsi->iCache <<= 8; |
102 | } |
103 | bsi->iCache <<= ((3 - bsi->nBytes) * 8); |
104 | bsi->cachedBits = 8 * bsi->nBytes; |
105 | bsi->nBytes = 0; |
106 | } |
107 | } |
108 | |
109 | /************************************************************************************** |
110 | * Function: GetBits |
111 | * |
112 | * Description: get bits from bitstream, advance bitstream pointer |
113 | * |
114 | * Inputs: pointer to initialized BitStreamInfo struct |
115 | * number of bits to get from bitstream |
116 | * |
117 | * Outputs: updated bitstream info struct |
118 | * |
119 | * Return: the next nBits bits of data from bitstream buffer |
120 | * |
121 | * Notes: nBits must be in range [0, 31], nBits outside this range masked by 0x1f |
122 | * for speed, does not indicate error if you overrun bit buffer |
123 | * if nBits == 0, returns 0 |
124 | **************************************************************************************/ |
125 | unsigned int GetBits(BitStreamInfo *bsi, int nBits) |
126 | { |
127 | unsigned int data, lowBits; |
128 | |
129 | nBits &= 0x1f; /* nBits mod 32 to avoid unpredictable results like >> by negative amount */ |
130 | data = bsi->iCache >> (31 - nBits); /* unsigned >> so zero-extend */ |
131 | data >>= 1; /* do as >> 31, >> 1 so that nBits = 0 works okay (returns 0) */ |
132 | bsi->iCache <<= nBits; /* left-justify cache */ |
133 | bsi->cachedBits -= nBits; /* how many bits have we drawn from the cache so far */ |
134 | |
135 | /* if we cross an int boundary, refill the cache */ |
136 | if (bsi->cachedBits < 0) { |
137 | lowBits = -bsi->cachedBits; |
138 | RefillBitstreamCache(bsi); |
139 | data |= bsi->iCache >> (32 - lowBits); /* get the low-order bits */ |
140 | |
141 | bsi->cachedBits -= lowBits; /* how many bits have we drawn from the cache so far */ |
142 | bsi->iCache <<= lowBits; /* left-justify cache */ |
143 | } |
144 | |
145 | return data; |
146 | } |
147 | |
148 | /************************************************************************************** |
149 | * Function: GetBitsNoAdvance |
150 | * |
151 | * Description: get bits from bitstream, do not advance bitstream pointer |
152 | * |
153 | * Inputs: pointer to initialized BitStreamInfo struct |
154 | * number of bits to get from bitstream |
155 | * |
156 | * Outputs: none (state of BitStreamInfo struct left unchanged) |
157 | * |
158 | * Return: the next nBits bits of data from bitstream buffer |
159 | * |
160 | * Notes: nBits must be in range [0, 31], nBits outside this range masked by 0x1f |
161 | * for speed, does not indicate error if you overrun bit buffer |
162 | * if nBits == 0, returns 0 |
163 | **************************************************************************************/ |
164 | unsigned int GetBitsNoAdvance(BitStreamInfo *bsi, int nBits) |
165 | { |
166 | unsigned char *buf; |
167 | unsigned int data, iCache; |
168 | signed int lowBits; |
169 | |
170 | nBits &= 0x1f; /* nBits mod 32 to avoid unpredictable results like >> by negative amount */ |
171 | data = bsi->iCache >> (31 - nBits); /* unsigned >> so zero-extend */ |
172 | data >>= 1; /* do as >> 31, >> 1 so that nBits = 0 works okay (returns 0) */ |
173 | lowBits = nBits - bsi->cachedBits; /* how many bits do we have left to read */ |
174 | |
175 | /* if we cross an int boundary, read next bytes in buffer */ |
176 | if (lowBits > 0) { |
177 | iCache = 0; |
178 | buf = bsi->bytePtr; |
179 | while (lowBits > 0) { |
180 | iCache <<= 8; |
181 | if (buf < bsi->bytePtr + bsi->nBytes) { |
182 | iCache |= (unsigned int) * buf++; |
183 | } |
184 | lowBits -= 8; |
185 | } |
186 | lowBits = -lowBits; |
187 | data |= iCache >> lowBits; |
188 | } |
189 | |
190 | return data; |
191 | } |
192 | |
193 | /************************************************************************************** |
194 | * Function: AdvanceBitstream |
195 | * |
196 | * Description: move bitstream pointer ahead |
197 | * |
198 | * Inputs: pointer to initialized BitStreamInfo struct |
199 | * number of bits to advance bitstream |
200 | * |
201 | * Outputs: updated bitstream info struct |
202 | * |
203 | * Return: none |
204 | * |
205 | * Notes: generally used following GetBitsNoAdvance(bsi, maxBits) |
206 | **************************************************************************************/ |
207 | void AdvanceBitstream(BitStreamInfo *bsi, int nBits) |
208 | { |
209 | nBits &= 0x1f; |
210 | if (nBits > bsi->cachedBits) { |
211 | nBits -= bsi->cachedBits; |
212 | RefillBitstreamCache(bsi); |
213 | } |
214 | bsi->iCache <<= nBits; |
215 | bsi->cachedBits -= nBits; |
216 | } |
217 | |
218 | /************************************************************************************** |
219 | * Function: CalcBitsUsed |
220 | * |
221 | * Description: calculate how many bits have been read from bitstream |
222 | * |
223 | * Inputs: pointer to initialized BitStreamInfo struct |
224 | * pointer to start of bitstream buffer |
225 | * bit offset into first byte of startBuf (0-7) |
226 | * |
227 | * Outputs: none |
228 | * |
229 | * Return: number of bits read from bitstream, as offset from startBuf:startOffset |
230 | **************************************************************************************/ |
231 | int CalcBitsUsed(BitStreamInfo *bsi, unsigned char *startBuf, int startOffset) |
232 | { |
233 | int bitsUsed; |
234 | |
235 | bitsUsed = (bsi->bytePtr - startBuf) * 8; |
236 | bitsUsed -= bsi->cachedBits; |
237 | bitsUsed -= startOffset; |
238 | |
239 | return bitsUsed; |
240 | } |
241 | |
242 | /************************************************************************************** |
243 | * Function: ByteAlignBitstream |
244 | * |
245 | * Description: bump bitstream pointer to start of next byte |
246 | * |
247 | * Inputs: pointer to initialized BitStreamInfo struct |
248 | * |
249 | * Outputs: byte-aligned bitstream BitStreamInfo struct |
250 | * |
251 | * Return: none |
252 | * |
253 | * Notes: if bitstream is already byte-aligned, do nothing |
254 | **************************************************************************************/ |
255 | void ByteAlignBitstream(BitStreamInfo *bsi) |
256 | { |
257 | int offset; |
258 | |
259 | offset = bsi->cachedBits & 0x07; |
260 | AdvanceBitstream(bsi, offset); |
261 | } |
262 |