1 /*
2 * Copyright (c) 2011 Apple Inc. All rights reserved.
3 *
4 * @APPLE_APACHE_LICENSE_HEADER_START@
5 *
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
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
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.
17 *
18 * @APPLE_APACHE_LICENSE_HEADER_END@
19 */
20
21 /*=============================================================================
22 File: ALACBitUtilities.c
23
24 $NoKeywords: $
25 =============================================================================*/
26
27 #include <stdio.h>
28 #include "ALACBitUtilities.h"
29
30 #define PRAGMA_MARK 0
31
32 // BitBufferInit
33 //
BitBufferInit(BitBuffer * bits,uint8_t * buffer,uint32_t byteSize)34 void BitBufferInit (BitBuffer * bits, uint8_t * buffer, uint32_t byteSize)
35 {
36 bits->cur = buffer ;
37 bits->end = bits->cur + byteSize ;
38 bits->bitIndex = 0 ;
39 bits->byteSize = byteSize ;
40 }
41
42 // BitBufferRead
43 //
BitBufferRead(BitBuffer * bits,uint8_t numBits)44 uint32_t BitBufferRead (BitBuffer * bits, uint8_t numBits)
45 {
46 uint32_t returnBits ;
47
48 //Assert (numBits <= 16) ;
49
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 ;
53
54 bits->bitIndex += numBits ;
55
56 returnBits = returnBits >> (24 - numBits) ;
57
58 bits->cur += (bits->bitIndex >> 3) ;
59 bits->bitIndex &= 7 ;
60
61 //Assert (bits->cur <= bits->end) ;
62
63 return returnBits ;
64 }
65
66 // BitBufferReadSmall
67 //
68 // Reads up to 8 bits
BitBufferReadSmall(BitBuffer * bits,uint8_t numBits)69 uint8_t BitBufferReadSmall (BitBuffer * bits, uint8_t numBits)
70 {
71 uint16_t returnBits ;
72
73 //Assert (numBits <= 8) ;
74
75 returnBits = (bits->cur [0] << 8) | bits->cur [1] ;
76 returnBits = returnBits << bits->bitIndex ;
77
78 bits->bitIndex += numBits ;
79
80 returnBits = returnBits >> (16 - numBits) ;
81
82 bits->cur += (bits->bitIndex >> 3) ;
83 bits->bitIndex &= 7 ;
84
85 //Assert (bits->cur <= bits->end) ;
86
87 return (uint8_t) returnBits ;
88 }
89
90 // BitBufferReadOne
91 //
92 // Reads one byte
BitBufferReadOne(BitBuffer * bits)93 uint8_t BitBufferReadOne (BitBuffer * bits)
94 {
95 uint8_t returnBits ;
96
97 returnBits = (bits->cur [0] >> (7 - bits->bitIndex)) & 1 ;
98
99 bits->bitIndex++ ;
100
101 bits->cur += (bits->bitIndex >> 3) ;
102 bits->bitIndex &= 7 ;
103
104 //Assert (bits->cur <= bits->end) ;
105
106 return returnBits ;
107 }
108
109 // BitBufferPeek
110 //
BitBufferPeek(BitBuffer * bits,uint8_t numBits)111 uint32_t BitBufferPeek (BitBuffer * bits, uint8_t numBits)
112 {
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)) ;
115 }
116
117 // BitBufferPeekOne
118 //
BitBufferPeekOne(BitBuffer * bits)119 uint32_t BitBufferPeekOne (BitBuffer * bits)
120 {
121 return ((bits->cur [0] >> (7 - bits->bitIndex)) & 1) ;
122 }
123
124 // BitBufferUnpackBERSize
125 //
BitBufferUnpackBERSize(BitBuffer * bits)126 uint32_t BitBufferUnpackBERSize (BitBuffer * bits)
127 {
128 uint32_t size ;
129 uint8_t tmp ;
130
131 for (size = 0, tmp = 0x80u ; tmp &= 0x80u ; size = (size << 7u) | (tmp & 0x7fu))
132 tmp = (uint8_t) BitBufferReadSmall (bits, 8) ;
133
134 return size ;
135 }
136
137 // BitBufferGetPosition
138 //
BitBufferGetPosition(BitBuffer * bits)139 uint32_t BitBufferGetPosition (BitBuffer * bits)
140 {
141 uint8_t * begin ;
142
143 begin = bits->end - bits->byteSize ;
144
145 return ((uint32_t) (bits->cur - begin) * 8) + bits->bitIndex ;
146 }
147
148 // BitBufferByteAlign
149 //
BitBufferByteAlign(BitBuffer * bits,int32_t addZeros)150 void BitBufferByteAlign (BitBuffer * bits, int32_t addZeros)
151 {
152 // align bit buffer to next byte boundary, writing zeros if requested
153 if (bits->bitIndex == 0)
154 return ;
155
156 if (addZeros)
157 BitBufferWrite (bits, 0, 8 - bits->bitIndex) ;
158 else
159 BitBufferAdvance (bits, 8 - bits->bitIndex) ;
160 }
161
162 // BitBufferAdvance
163 //
BitBufferAdvance(BitBuffer * bits,uint32_t numBits)164 void BitBufferAdvance (BitBuffer * bits, uint32_t numBits)
165 {
166 if (numBits)
167 {
168 bits->bitIndex += numBits ;
169 bits->cur += (bits->bitIndex >> 3) ;
170 bits->bitIndex &= 7 ;
171 }
172 }
173
174 // BitBufferRewind
175 //
BitBufferRewind(BitBuffer * bits,uint32_t numBits)176 void BitBufferRewind (BitBuffer * bits, uint32_t numBits)
177 {
178 uint32_t numBytes ;
179
180 if (numBits == 0)
181 return ;
182
183 if (bits->bitIndex >= numBits)
184 {
185 bits->bitIndex -= numBits ;
186 return ;
187 }
188
189 numBits -= bits->bitIndex ;
190 bits->bitIndex = 0 ;
191
192 numBytes = numBits / 8 ;
193 numBits = numBits % 8 ;
194
195 bits->cur -= numBytes ;
196
197 if (numBits > 0)
198 {
199 bits->bitIndex = 8 - numBits ;
200 bits->cur-- ;
201 }
202
203 if (bits->cur < (bits->end - bits->byteSize))
204 {
205 //DebugCMsg ("BitBufferRewind: Rewound too far.") ;
206
207 bits->cur = (bits->end - bits->byteSize) ;
208 bits->bitIndex = 0 ;
209 }
210 }
211
212 // BitBufferWrite
213 //
BitBufferWrite(BitBuffer * bits,uint32_t bitValues,uint32_t numBits)214 void BitBufferWrite (BitBuffer * bits, uint32_t bitValues, uint32_t numBits)
215 {
216 uint32_t invBitIndex ;
217
218 RequireAction (bits != NULL, return ;) ;
219 RequireActionSilent (numBits > 0, return ;) ;
220
221 invBitIndex = 8 - bits->bitIndex ;
222
223 while (numBits > 0)
224 {
225 uint32_t tmp ;
226 uint8_t shift ;
227 uint8_t mask ;
228 uint32_t curNum ;
229
230 curNum = MIN (invBitIndex, numBits) ;
231
232 tmp = bitValues >> (numBits - curNum) ;
233
234 shift = (uint8_t) (invBitIndex - curNum) ;
235 mask = 0xffu >> (8 - curNum) ; // must be done in two steps to avoid compiler sequencing ambiguity
236 mask <<= shift ;
237
238 bits->cur [0] = (bits->cur [0] & ~mask) | (((uint8_t) tmp << shift) & mask) ;
239 numBits -= curNum ;
240
241 // increment to next byte if need be
242 invBitIndex -= curNum ;
243 if (invBitIndex == 0)
244 {
245 invBitIndex = 8 ;
246 bits->cur++ ;
247 }
248 }
249
250 bits->bitIndex = 8 - invBitIndex ;
251 }
252
BitBufferReset(BitBuffer * bits)253 void BitBufferReset (BitBuffer * bits)
254 //void BitBufferInit (BitBuffer * bits, uint8_t * buffer, uint32_t byteSize)
255 {
256 bits->cur = bits->end - bits->byteSize ;
257 bits->bitIndex = 0 ;
258 }
259
260 #if PRAGMA_MARK
261 #pragma mark -
262 #endif
263