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:		ag_dec.c
23b815c7f3Sopenharmony_ci
24b815c7f3Sopenharmony_ci	Contains:   Adaptive Golomb decode routines.
25b815c7f3Sopenharmony_ci
26b815c7f3Sopenharmony_ci	Copyright:	(c) 2001-2011 Apple, Inc.
27b815c7f3Sopenharmony_ci*/
28b815c7f3Sopenharmony_ci
29b815c7f3Sopenharmony_ci#include <math.h>
30b815c7f3Sopenharmony_ci#include <stdio.h>
31b815c7f3Sopenharmony_ci#include <stdlib.h>
32b815c7f3Sopenharmony_ci#include <string.h>
33b815c7f3Sopenharmony_ci
34b815c7f3Sopenharmony_ci#include "aglib.h"
35b815c7f3Sopenharmony_ci#include "ALACBitUtilities.h"
36b815c7f3Sopenharmony_ci#include "ALACAudioTypes.h"
37b815c7f3Sopenharmony_ci
38b815c7f3Sopenharmony_ci#define CODE_TO_LONG_MAXBITS	32
39b815c7f3Sopenharmony_ci#define N_MAX_MEAN_CLAMP		0xffff
40b815c7f3Sopenharmony_ci#define N_MEAN_CLAMP_VAL		0xffff
41b815c7f3Sopenharmony_ci#define REPORT_VAL				40
42b815c7f3Sopenharmony_ci
43b815c7f3Sopenharmony_ci#if __GNUC__
44b815c7f3Sopenharmony_ci#define ALWAYS_INLINE		__attribute__ ((always_inline))
45b815c7f3Sopenharmony_ci#elif defined _MSC_VER
46b815c7f3Sopenharmony_ci#define ALWAYS_INLINE		__forceinline
47b815c7f3Sopenharmony_ci#else
48b815c7f3Sopenharmony_ci#define ALWAYS_INLINE
49b815c7f3Sopenharmony_ci#endif
50b815c7f3Sopenharmony_ci
51b815c7f3Sopenharmony_ci/*	And on the subject of the CodeWarrior x86 compiler and inlining, I reworked a lot of this
52b815c7f3Sopenharmony_ci	to help the compiler out.   In many cases this required manual inlining or a macro.  Sorry
53b815c7f3Sopenharmony_ci	if it is ugly but the performance gains are well worth it.
54b815c7f3Sopenharmony_ci	- WSK 5/19/04
55b815c7f3Sopenharmony_ci*/
56b815c7f3Sopenharmony_ci
57b815c7f3Sopenharmony_civoid set_standard_ag_params (AGParamRecPtr params, uint32_t fullwidth, uint32_t sectorwidth)
58b815c7f3Sopenharmony_ci{
59b815c7f3Sopenharmony_ci	/* Use
60b815c7f3Sopenharmony_ci		fullwidth = sectorwidth = numOfSamples, for analog 1-dimensional type-short data,
61b815c7f3Sopenharmony_ci		but use
62b815c7f3Sopenharmony_ci		fullwidth = full image width, sectorwidth = sector (patch) width
63b815c7f3Sopenharmony_ci		for such as image (2-dim.) data.
64b815c7f3Sopenharmony_ci	*/
65b815c7f3Sopenharmony_ci	set_ag_params (params, MB0, PB0, KB0, fullwidth, sectorwidth, MAX_RUN_DEFAULT) ;
66b815c7f3Sopenharmony_ci}
67b815c7f3Sopenharmony_ci
68b815c7f3Sopenharmony_civoid set_ag_params (AGParamRecPtr params, uint32_t m, uint32_t p, uint32_t k, uint32_t f, uint32_t s, uint32_t maxrun)
69b815c7f3Sopenharmony_ci{
70b815c7f3Sopenharmony_ci	params->mb = params->mb0 = m ;
71b815c7f3Sopenharmony_ci	params->pb = p ;
72b815c7f3Sopenharmony_ci	params->kb = k ;
73b815c7f3Sopenharmony_ci	params->wb = (1u << params->kb) - 1 ;
74b815c7f3Sopenharmony_ci	params->qb = QB-params->pb ;
75b815c7f3Sopenharmony_ci	params->fw = f ;
76b815c7f3Sopenharmony_ci	params->sw = s ;
77b815c7f3Sopenharmony_ci	params->maxrun = maxrun ;
78b815c7f3Sopenharmony_ci}
79b815c7f3Sopenharmony_ci
80b815c7f3Sopenharmony_ci#if PRAGMA_MARK
81b815c7f3Sopenharmony_ci#pragma mark -
82b815c7f3Sopenharmony_ci#endif
83b815c7f3Sopenharmony_ci
84b815c7f3Sopenharmony_ci
85b815c7f3Sopenharmony_ci// note: implementing this with some kind of "count leading zeros" assembly is a big performance win
86b815c7f3Sopenharmony_cistatic inline int32_t lead (int32_t m)
87b815c7f3Sopenharmony_ci{
88b815c7f3Sopenharmony_ci	long j ;
89b815c7f3Sopenharmony_ci	unsigned long c = (1ul << 31) ;
90b815c7f3Sopenharmony_ci
91b815c7f3Sopenharmony_ci	for (j = 0 ; j < 32 ; j++)
92b815c7f3Sopenharmony_ci	{
93b815c7f3Sopenharmony_ci		if ((c & m) != 0)
94b815c7f3Sopenharmony_ci			break ;
95b815c7f3Sopenharmony_ci		c >>= 1 ;
96b815c7f3Sopenharmony_ci	}
97b815c7f3Sopenharmony_ci	return j ;
98b815c7f3Sopenharmony_ci}
99b815c7f3Sopenharmony_ci
100b815c7f3Sopenharmony_ci#define arithmin(a, b) ((a) < (b) ? (a) : (b))
101b815c7f3Sopenharmony_ci
102b815c7f3Sopenharmony_cistatic inline int32_t ALWAYS_INLINE lg3a (int32_t x)
103b815c7f3Sopenharmony_ci{
104b815c7f3Sopenharmony_ci	int32_t result ;
105b815c7f3Sopenharmony_ci
106b815c7f3Sopenharmony_ci	x += 3 ;
107b815c7f3Sopenharmony_ci	result = lead (x) ;
108b815c7f3Sopenharmony_ci
109b815c7f3Sopenharmony_ci	return 31 - result ;
110b815c7f3Sopenharmony_ci}
111b815c7f3Sopenharmony_ci
112b815c7f3Sopenharmony_cistatic inline uint32_t ALWAYS_INLINE read32bit (uint8_t * buffer)
113b815c7f3Sopenharmony_ci{
114b815c7f3Sopenharmony_ci	// embedded CPUs typically can't read unaligned 32-bit words so just read the bytes
115b815c7f3Sopenharmony_ci	uint32_t		value ;
116b815c7f3Sopenharmony_ci
117b815c7f3Sopenharmony_ci	value = ((uint32_t) buffer [0] << 24) | ((uint32_t) buffer [1] << 16) |
118b815c7f3Sopenharmony_ci				((uint32_t) buffer [2] << 8) | (uint32_t) buffer [3] ;
119b815c7f3Sopenharmony_ci	return value ;
120b815c7f3Sopenharmony_ci
121b815c7f3Sopenharmony_ci}
122b815c7f3Sopenharmony_ci
123b815c7f3Sopenharmony_ci#if PRAGMA_MARK
124b815c7f3Sopenharmony_ci#pragma mark -
125b815c7f3Sopenharmony_ci#endif
126b815c7f3Sopenharmony_ci
127b815c7f3Sopenharmony_ci#define get_next_fromlong(inlong, suff)		((inlong) >> (32 - (suff)))
128b815c7f3Sopenharmony_ci
129b815c7f3Sopenharmony_ci
130b815c7f3Sopenharmony_cistatic inline uint32_t ALWAYS_INLINE
131b815c7f3Sopenharmony_cigetstreambits (uint8_t *in, int32_t bitoffset, int32_t numbits)
132b815c7f3Sopenharmony_ci{
133b815c7f3Sopenharmony_ci	uint32_t	load1, load2 ;
134b815c7f3Sopenharmony_ci	uint32_t	byteoffset = bitoffset / 8 ;
135b815c7f3Sopenharmony_ci	uint32_t	result ;
136b815c7f3Sopenharmony_ci
137b815c7f3Sopenharmony_ci	//Assert (numbits <= 32) ;
138b815c7f3Sopenharmony_ci
139b815c7f3Sopenharmony_ci	load1 = read32bit (in + byteoffset) ;
140b815c7f3Sopenharmony_ci
141b815c7f3Sopenharmony_ci	if ((numbits + (bitoffset & 0x7)) > 32)
142b815c7f3Sopenharmony_ci	{
143b815c7f3Sopenharmony_ci		int32_t load2shift ;
144b815c7f3Sopenharmony_ci
145b815c7f3Sopenharmony_ci		result = load1 << (bitoffset & 0x7) ;
146b815c7f3Sopenharmony_ci		load2 = (uint32_t) in [byteoffset + 4] ;
147b815c7f3Sopenharmony_ci		load2shift = (8 - (numbits + (bitoffset & 0x7) - 32)) ;
148b815c7f3Sopenharmony_ci		load2 >>= load2shift ;
149b815c7f3Sopenharmony_ci		result >>= (32 - numbits) ;
150b815c7f3Sopenharmony_ci		result |= load2 ;
151b815c7f3Sopenharmony_ci	}
152b815c7f3Sopenharmony_ci	else
153b815c7f3Sopenharmony_ci	{
154b815c7f3Sopenharmony_ci		result = load1 >> (32 - numbits - (bitoffset & 7)) ;
155b815c7f3Sopenharmony_ci	}
156b815c7f3Sopenharmony_ci
157b815c7f3Sopenharmony_ci	// a shift of >= "the number of bits in the type of the value being shifted" results in undefined
158b815c7f3Sopenharmony_ci	// behavior so don't try to shift by 32
159b815c7f3Sopenharmony_ci	if (numbits != (sizeof (result) * 8))
160b815c7f3Sopenharmony_ci		result &= ~ (0xfffffffful << numbits) ;
161b815c7f3Sopenharmony_ci
162b815c7f3Sopenharmony_ci	return result ;
163b815c7f3Sopenharmony_ci}
164b815c7f3Sopenharmony_ci
165b815c7f3Sopenharmony_ci
166b815c7f3Sopenharmony_cistatic inline int32_t dyn_get (unsigned char *in, uint32_t *bitPos, uint32_t m, uint32_t k)
167b815c7f3Sopenharmony_ci{
168b815c7f3Sopenharmony_ci	uint32_t	tempbits = *bitPos ;
169b815c7f3Sopenharmony_ci	uint32_t		result ;
170b815c7f3Sopenharmony_ci	uint32_t		pre = 0, v ;
171b815c7f3Sopenharmony_ci	uint32_t		streamlong ;
172b815c7f3Sopenharmony_ci
173b815c7f3Sopenharmony_ci	streamlong = read32bit (in + (tempbits >> 3)) ;
174b815c7f3Sopenharmony_ci	streamlong <<= (tempbits & 7) ;
175b815c7f3Sopenharmony_ci
176b815c7f3Sopenharmony_ci	/* find the number of bits in the prefix */
177b815c7f3Sopenharmony_ci	{
178b815c7f3Sopenharmony_ci		uint32_t	notI = ~streamlong ;
179b815c7f3Sopenharmony_ci		pre = lead (notI) ;
180b815c7f3Sopenharmony_ci	}
181b815c7f3Sopenharmony_ci
182b815c7f3Sopenharmony_ci	if (pre >= MAX_PREFIX_16)
183b815c7f3Sopenharmony_ci	{
184b815c7f3Sopenharmony_ci		pre = MAX_PREFIX_16 ;
185b815c7f3Sopenharmony_ci		tempbits += pre ;
186b815c7f3Sopenharmony_ci		streamlong <<= pre ;
187b815c7f3Sopenharmony_ci		result = get_next_fromlong (streamlong, MAX_DATATYPE_BITS_16) ;
188b815c7f3Sopenharmony_ci		tempbits += MAX_DATATYPE_BITS_16 ;
189b815c7f3Sopenharmony_ci
190b815c7f3Sopenharmony_ci	}
191b815c7f3Sopenharmony_ci	else
192b815c7f3Sopenharmony_ci	{
193b815c7f3Sopenharmony_ci		// all of the bits must fit within the long we have loaded
194b815c7f3Sopenharmony_ci		//Assert (pre+1+k <= 32) ;
195b815c7f3Sopenharmony_ci
196b815c7f3Sopenharmony_ci		tempbits += pre ;
197b815c7f3Sopenharmony_ci		tempbits += 1 ;
198b815c7f3Sopenharmony_ci		streamlong <<= pre + 1 ;
199b815c7f3Sopenharmony_ci		v = get_next_fromlong (streamlong, k) ;
200b815c7f3Sopenharmony_ci		tempbits += k ;
201b815c7f3Sopenharmony_ci
202b815c7f3Sopenharmony_ci		result = pre*m + v-1 ;
203b815c7f3Sopenharmony_ci
204b815c7f3Sopenharmony_ci		if (v < 2)
205b815c7f3Sopenharmony_ci		{
206b815c7f3Sopenharmony_ci			result -= (v-1) ;
207b815c7f3Sopenharmony_ci			tempbits -= 1 ;
208b815c7f3Sopenharmony_ci		}
209b815c7f3Sopenharmony_ci	}
210b815c7f3Sopenharmony_ci
211b815c7f3Sopenharmony_ci	*bitPos = tempbits ;
212b815c7f3Sopenharmony_ci	return result ;
213b815c7f3Sopenharmony_ci}
214b815c7f3Sopenharmony_ci
215b815c7f3Sopenharmony_ci
216b815c7f3Sopenharmony_cistatic inline int32_t dyn_get_32bit (uint8_t * in, uint32_t * bitPos, int32_t m, int32_t k, int32_t maxbits)
217b815c7f3Sopenharmony_ci{
218b815c7f3Sopenharmony_ci	uint32_t	tempbits = *bitPos ;
219b815c7f3Sopenharmony_ci	uint32_t		v ;
220b815c7f3Sopenharmony_ci	uint32_t		streamlong ;
221b815c7f3Sopenharmony_ci	uint32_t		result ;
222b815c7f3Sopenharmony_ci
223b815c7f3Sopenharmony_ci	streamlong = read32bit (in + (tempbits >> 3)) ;
224b815c7f3Sopenharmony_ci	streamlong <<= (tempbits & 7) ;
225b815c7f3Sopenharmony_ci
226b815c7f3Sopenharmony_ci	/* find the number of bits in the prefix */
227b815c7f3Sopenharmony_ci	{
228b815c7f3Sopenharmony_ci		uint32_t notI = ~streamlong ;
229b815c7f3Sopenharmony_ci		result = lead (notI) ;
230b815c7f3Sopenharmony_ci	}
231b815c7f3Sopenharmony_ci
232b815c7f3Sopenharmony_ci	if (result >= MAX_PREFIX_32)
233b815c7f3Sopenharmony_ci	{
234b815c7f3Sopenharmony_ci		result = getstreambits (in, tempbits+MAX_PREFIX_32, maxbits) ;
235b815c7f3Sopenharmony_ci		tempbits += MAX_PREFIX_32 + maxbits ;
236b815c7f3Sopenharmony_ci	}
237b815c7f3Sopenharmony_ci	else
238b815c7f3Sopenharmony_ci	{
239b815c7f3Sopenharmony_ci		/* all of the bits must fit within the long we have loaded*/
240b815c7f3Sopenharmony_ci		//Assert (k<=14) ;
241b815c7f3Sopenharmony_ci		//Assert (result<MAX_PREFIX_32) ;
242b815c7f3Sopenharmony_ci		//Assert (result+1+k <= 32) ;
243b815c7f3Sopenharmony_ci
244b815c7f3Sopenharmony_ci		tempbits += result ;
245b815c7f3Sopenharmony_ci		tempbits += 1 ;
246b815c7f3Sopenharmony_ci
247b815c7f3Sopenharmony_ci		if (k != 1)
248b815c7f3Sopenharmony_ci		{
249b815c7f3Sopenharmony_ci			streamlong <<= result + 1 ;
250b815c7f3Sopenharmony_ci			v = get_next_fromlong (streamlong, k) ;
251b815c7f3Sopenharmony_ci			tempbits += k ;
252b815c7f3Sopenharmony_ci			tempbits -= 1 ;
253b815c7f3Sopenharmony_ci			result = result*m ;
254b815c7f3Sopenharmony_ci
255b815c7f3Sopenharmony_ci			if (v >= 2)
256b815c7f3Sopenharmony_ci			{
257b815c7f3Sopenharmony_ci				result += (v-1) ;
258b815c7f3Sopenharmony_ci				tempbits += 1 ;
259b815c7f3Sopenharmony_ci			}
260b815c7f3Sopenharmony_ci		}
261b815c7f3Sopenharmony_ci	}
262b815c7f3Sopenharmony_ci
263b815c7f3Sopenharmony_ci	*bitPos = tempbits ;
264b815c7f3Sopenharmony_ci
265b815c7f3Sopenharmony_ci	return result ;
266b815c7f3Sopenharmony_ci}
267b815c7f3Sopenharmony_ci
268b815c7f3Sopenharmony_ciint32_t dyn_decomp (AGParamRecPtr params, BitBuffer * bitstream, int32_t * pc, int32_t numSamples, int32_t maxSize, uint32_t * outNumBits)
269b815c7f3Sopenharmony_ci{
270b815c7f3Sopenharmony_ci	uint8_t 		*in ;
271b815c7f3Sopenharmony_ci	int32_t			*outPtr = pc ;
272b815c7f3Sopenharmony_ci	uint32_t 	bitPos, startPos, maxPos ;
273b815c7f3Sopenharmony_ci	uint32_t		j, m, k, n, c, mz ;
274b815c7f3Sopenharmony_ci	int32_t			del, zmode ;
275b815c7f3Sopenharmony_ci	uint32_t 	mb ;
276b815c7f3Sopenharmony_ci	uint32_t	pb_local = params->pb ;
277b815c7f3Sopenharmony_ci	uint32_t	kb_local = params->kb ;
278b815c7f3Sopenharmony_ci	uint32_t	wb_local = params->wb ;
279b815c7f3Sopenharmony_ci	int32_t				status ;
280b815c7f3Sopenharmony_ci
281b815c7f3Sopenharmony_ci	RequireAction ((bitstream != NULL) && (pc != NULL) && (outNumBits != NULL), return kALAC_ParamError ;) ;
282b815c7f3Sopenharmony_ci	*outNumBits = 0 ;
283b815c7f3Sopenharmony_ci
284b815c7f3Sopenharmony_ci	in = bitstream->cur ;
285b815c7f3Sopenharmony_ci	startPos = bitstream->bitIndex ;
286b815c7f3Sopenharmony_ci	maxPos = bitstream->byteSize * 8 ;
287b815c7f3Sopenharmony_ci	bitPos = startPos ;
288b815c7f3Sopenharmony_ci
289b815c7f3Sopenharmony_ci	mb = params->mb0 ;
290b815c7f3Sopenharmony_ci	zmode = 0 ;
291b815c7f3Sopenharmony_ci
292b815c7f3Sopenharmony_ci	c = 0 ;
293b815c7f3Sopenharmony_ci	status = ALAC_noErr ;
294b815c7f3Sopenharmony_ci
295b815c7f3Sopenharmony_ci	while (c < (uint32_t) numSamples)
296b815c7f3Sopenharmony_ci	{
297b815c7f3Sopenharmony_ci		// bail if we've run off the end of the buffer
298b815c7f3Sopenharmony_ci		RequireAction (bitPos < maxPos, status = kALAC_ParamError ; goto Exit ;) ;
299b815c7f3Sopenharmony_ci
300b815c7f3Sopenharmony_ci		m = (mb) >> QBSHIFT ;
301b815c7f3Sopenharmony_ci		k = lg3a (m) ;
302b815c7f3Sopenharmony_ci
303b815c7f3Sopenharmony_ci		k = arithmin (k, kb_local) ;
304b815c7f3Sopenharmony_ci		m = (1 << k) - 1 ;
305b815c7f3Sopenharmony_ci
306b815c7f3Sopenharmony_ci		n = dyn_get_32bit (in, &bitPos, m, k, maxSize) ;
307b815c7f3Sopenharmony_ci
308b815c7f3Sopenharmony_ci		// least significant bit is sign bit
309b815c7f3Sopenharmony_ci		{
310b815c7f3Sopenharmony_ci			uint32_t	ndecode = n + zmode ;
311b815c7f3Sopenharmony_ci			int32_t		multiplier = - (int) (ndecode & 1) ;
312b815c7f3Sopenharmony_ci
313b815c7f3Sopenharmony_ci			multiplier |= 1 ;
314b815c7f3Sopenharmony_ci			del = ((ndecode+1) >> 1) * (multiplier) ;
315b815c7f3Sopenharmony_ci		}
316b815c7f3Sopenharmony_ci
317b815c7f3Sopenharmony_ci		*outPtr++ = del ;
318b815c7f3Sopenharmony_ci
319b815c7f3Sopenharmony_ci		c++ ;
320b815c7f3Sopenharmony_ci
321b815c7f3Sopenharmony_ci		mb = pb_local * (n + zmode) + mb - ((pb_local * mb) >> QBSHIFT) ;
322b815c7f3Sopenharmony_ci
323b815c7f3Sopenharmony_ci		// update mean tracking
324b815c7f3Sopenharmony_ci		if (n > N_MAX_MEAN_CLAMP)
325b815c7f3Sopenharmony_ci			mb = N_MEAN_CLAMP_VAL ;
326b815c7f3Sopenharmony_ci
327b815c7f3Sopenharmony_ci		zmode = 0 ;
328b815c7f3Sopenharmony_ci
329b815c7f3Sopenharmony_ci		if (((mb << MMULSHIFT) < QB) && (c < (uint32_t) numSamples))
330b815c7f3Sopenharmony_ci		{
331b815c7f3Sopenharmony_ci			zmode = 1 ;
332b815c7f3Sopenharmony_ci			k = lead (mb) - BITOFF + ((mb + MOFF) >> MDENSHIFT) ;
333b815c7f3Sopenharmony_ci			mz = ((1 << k) - 1) & wb_local ;
334b815c7f3Sopenharmony_ci
335b815c7f3Sopenharmony_ci			n = dyn_get (in, &bitPos, mz, k) ;
336b815c7f3Sopenharmony_ci
337b815c7f3Sopenharmony_ci			RequireAction (c+n <= (uint32_t) numSamples, status = kALAC_ParamError ; goto Exit ;) ;
338b815c7f3Sopenharmony_ci
339b815c7f3Sopenharmony_ci			for (j = 0 ; j < n ; j++)
340b815c7f3Sopenharmony_ci			{
341b815c7f3Sopenharmony_ci				*outPtr++ = 0 ;
342b815c7f3Sopenharmony_ci				++c ;
343b815c7f3Sopenharmony_ci			}
344b815c7f3Sopenharmony_ci
345b815c7f3Sopenharmony_ci			if (n >= 65535)
346b815c7f3Sopenharmony_ci				zmode = 0 ;
347b815c7f3Sopenharmony_ci
348b815c7f3Sopenharmony_ci			mb = 0 ;
349b815c7f3Sopenharmony_ci		}
350b815c7f3Sopenharmony_ci	}
351b815c7f3Sopenharmony_ci
352b815c7f3Sopenharmony_ciExit:
353b815c7f3Sopenharmony_ci	*outNumBits = (bitPos - startPos) ;
354b815c7f3Sopenharmony_ci	BitBufferAdvance (bitstream, *outNumBits) ;
355b815c7f3Sopenharmony_ci	RequireAction (bitstream->cur <= bitstream->end, status = kALAC_ParamError ;) ;
356b815c7f3Sopenharmony_ci
357b815c7f3Sopenharmony_ci	return status ;
358b815c7f3Sopenharmony_ci}
359