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