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