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