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