2 * Copyright (c) 2011 Apple Inc. All rights reserved.
4 * @APPLE_APACHE_LICENSE_HEADER_START@
6 * Licensed under the Apache License, Version 2.0 (the "License") ;
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * @APPLE_APACHE_LICENSE_HEADER_END@
21 /*=============================================================================
22 File: ALACBitUtilities.c
25 =============================================================================*/
28 #include "ALACBitUtilities.h"
34 void BitBufferInit (BitBuffer * bits, uint8_t * buffer, uint32_t byteSize)
37 bits->end = bits->cur + byteSize ;
39 bits->byteSize = byteSize ;
44 uint32_t BitBufferRead (BitBuffer * bits, uint8_t numBits)
48 //Assert (numBits <= 16) ;
50 returnBits = ((uint32_t) bits->cur [0] << 16) | ((uint32_t) bits->cur [1] << 8) | ((uint32_t) bits->cur [2]) ;
51 returnBits = returnBits << bits->bitIndex ;
52 returnBits &= 0x00FFFFFF ;
54 bits->bitIndex += numBits ;
56 returnBits = returnBits >> (24 - numBits) ;
58 bits->cur += (bits->bitIndex >> 3) ;
61 //Assert (bits->cur <= bits->end) ;
69 uint8_t BitBufferReadSmall (BitBuffer * bits, uint8_t numBits)
73 //Assert (numBits <= 8) ;
75 returnBits = (bits->cur [0] << 8) | bits->cur [1] ;
76 returnBits = returnBits << bits->bitIndex ;
78 bits->bitIndex += numBits ;
80 returnBits = returnBits >> (16 - numBits) ;
82 bits->cur += (bits->bitIndex >> 3) ;
85 //Assert (bits->cur <= bits->end) ;
87 return (uint8_t) returnBits ;
93 uint8_t BitBufferReadOne (BitBuffer * bits)
97 returnBits = (bits->cur [0] >> (7 - bits->bitIndex)) & 1 ;
101 bits->cur += (bits->bitIndex >> 3) ;
102 bits->bitIndex &= 7 ;
104 //Assert (bits->cur <= bits->end) ;
111 uint32_t BitBufferPeek (BitBuffer * bits, uint8_t numBits)
113 return ((((((uint32_t) bits->cur [0] << 16) | ((uint32_t) bits->cur [1] << 8) |
114 ((uint32_t) bits->cur [2])) << bits->bitIndex) & 0x00FFFFFF) >> (24 - numBits)) ;
119 uint32_t BitBufferPeekOne (BitBuffer * bits)
121 return ((bits->cur [0] >> (7 - bits->bitIndex)) & 1) ;
124 // BitBufferUnpackBERSize
126 uint32_t BitBufferUnpackBERSize (BitBuffer * bits)
131 for (size = 0, tmp = 0x80u ; tmp &= 0x80u ; size = (size << 7u) | (tmp & 0x7fu))
132 tmp = (uint8_t) BitBufferReadSmall (bits, 8) ;
137 // BitBufferGetPosition
139 uint32_t BitBufferGetPosition (BitBuffer * bits)
143 begin = bits->end - bits->byteSize ;
145 return ((uint32_t) (bits->cur - begin) * 8) + bits->bitIndex ;
148 // BitBufferByteAlign
150 void BitBufferByteAlign (BitBuffer * bits, int32_t addZeros)
152 // align bit buffer to next byte boundary, writing zeros if requested
153 if (bits->bitIndex == 0)
157 BitBufferWrite (bits, 0, 8 - bits->bitIndex) ;
159 BitBufferAdvance (bits, 8 - bits->bitIndex) ;
164 void BitBufferAdvance (BitBuffer * bits, uint32_t numBits)
168 bits->bitIndex += numBits ;
169 bits->cur += (bits->bitIndex >> 3) ;
170 bits->bitIndex &= 7 ;
176 void BitBufferRewind (BitBuffer * bits, uint32_t numBits)
183 if (bits->bitIndex >= numBits)
185 bits->bitIndex -= numBits ;
189 numBits -= bits->bitIndex ;
192 numBytes = numBits / 8 ;
193 numBits = numBits % 8 ;
195 bits->cur -= numBytes ;
199 bits->bitIndex = 8 - numBits ;
203 if (bits->cur < (bits->end - bits->byteSize))
205 //DebugCMsg ("BitBufferRewind: Rewound too far.") ;
207 bits->cur = (bits->end - bits->byteSize) ;
214 void BitBufferWrite (BitBuffer * bits, uint32_t bitValues, uint32_t numBits)
216 uint32_t invBitIndex ;
218 RequireAction (bits != NULL, return ;) ;
219 RequireActionSilent (numBits > 0, return ;) ;
221 invBitIndex = 8 - bits->bitIndex ;
230 curNum = MIN (invBitIndex, numBits) ;
232 tmp = bitValues >> (numBits - curNum) ;
234 shift = (uint8_t) (invBitIndex - curNum) ;
235 mask = 0xffu >> (8 - curNum) ; // must be done in two steps to avoid compiler sequencing ambiguity
238 bits->cur [0] = (bits->cur [0] & ~mask) | (((uint8_t) tmp << shift) & mask) ;
241 // increment to next byte if need be
242 invBitIndex -= curNum ;
243 if (invBitIndex == 0)
250 bits->bitIndex = 8 - invBitIndex ;
253 void BitBufferReset (BitBuffer * bits)
254 //void BitBufferInit (BitBuffer * bits, uint8_t * buffer, uint32_t byteSize)
256 bits->cur = bits->end - bits->byteSize ;