1b815c7f3Sopenharmony_ci/*
2b815c7f3Sopenharmony_ci * Copyright (c) 2011 Apple Inc. All rights reserved.
3b815c7f3Sopenharmony_ci * Copyright (C) 2013-2014 Erik de Castro Lopo <erikd@mega-nerd.com>
4b815c7f3Sopenharmony_ci *
5b815c7f3Sopenharmony_ci * @APPLE_APACHE_LICENSE_HEADER_START@
6b815c7f3Sopenharmony_ci *
7b815c7f3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License") ;
8b815c7f3Sopenharmony_ci * you may not use this file except in compliance with the License.
9b815c7f3Sopenharmony_ci * You may obtain a copy of the License at
10b815c7f3Sopenharmony_ci *
11b815c7f3Sopenharmony_ci *	 http://www.apache.org/licenses/LICENSE-2.0
12b815c7f3Sopenharmony_ci *
13b815c7f3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14b815c7f3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15b815c7f3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16b815c7f3Sopenharmony_ci * See the License for the specific language governing permissions and
17b815c7f3Sopenharmony_ci * limitations under the License.
18b815c7f3Sopenharmony_ci *
19b815c7f3Sopenharmony_ci * @APPLE_APACHE_LICENSE_HEADER_END@
20b815c7f3Sopenharmony_ci */
21b815c7f3Sopenharmony_ci
22b815c7f3Sopenharmony_ci/*
23b815c7f3Sopenharmony_ci	File:		ag_enc.c
24b815c7f3Sopenharmony_ci
25b815c7f3Sopenharmony_ci	Contains:   Adaptive Golomb encode routines.
26b815c7f3Sopenharmony_ci
27b815c7f3Sopenharmony_ci	Copyright:	(c) 2001-2011 Apple, Inc.
28b815c7f3Sopenharmony_ci*/
29b815c7f3Sopenharmony_ci
30b815c7f3Sopenharmony_ci#include "aglib.h"
31b815c7f3Sopenharmony_ci#include "ALACBitUtilities.h"
32b815c7f3Sopenharmony_ci#include "EndianPortable.h"
33b815c7f3Sopenharmony_ci#include "ALACAudioTypes.h"
34b815c7f3Sopenharmony_ci
35b815c7f3Sopenharmony_ci#include <math.h>
36b815c7f3Sopenharmony_ci#include <stdio.h>
37b815c7f3Sopenharmony_ci#include <stdlib.h>
38b815c7f3Sopenharmony_ci#include <string.h>
39b815c7f3Sopenharmony_ci
40b815c7f3Sopenharmony_ci#define CODE_TO_LONG_MAXBITS	32
41b815c7f3Sopenharmony_ci#define N_MAX_MEAN_CLAMP		0xffff
42b815c7f3Sopenharmony_ci#define N_MEAN_CLAMP_VAL		0xffff
43b815c7f3Sopenharmony_ci#define REPORT_VAL				40
44b815c7f3Sopenharmony_ci
45b815c7f3Sopenharmony_ci#if __GNUC__
46b815c7f3Sopenharmony_ci#define ALWAYS_INLINE		__attribute__ ((always_inline))
47b815c7f3Sopenharmony_ci#elif defined _MSC_VER
48b815c7f3Sopenharmony_ci#define ALWAYS_INLINE		__forceinline
49b815c7f3Sopenharmony_ci#else
50b815c7f3Sopenharmony_ci#define ALWAYS_INLINE
51b815c7f3Sopenharmony_ci#endif
52b815c7f3Sopenharmony_ci
53b815c7f3Sopenharmony_ci
54b815c7f3Sopenharmony_ci/*	And on the subject of the CodeWarrior x86 compiler and inlining, I reworked a lot of this
55b815c7f3Sopenharmony_ci	to help the compiler out.   In many cases this required manual inlining or a macro.  Sorry
56b815c7f3Sopenharmony_ci	if it is ugly but the performance gains are well worth it.
57b815c7f3Sopenharmony_ci	- WSK 5/19/04
58b815c7f3Sopenharmony_ci*/
59b815c7f3Sopenharmony_ci
60b815c7f3Sopenharmony_ci// note: implementing this with some kind of "count leading zeros" assembly is a big performance win
61b815c7f3Sopenharmony_cistatic inline int32_t lead (int32_t m)
62b815c7f3Sopenharmony_ci{
63b815c7f3Sopenharmony_ci	long j ;
64b815c7f3Sopenharmony_ci	unsigned long c = (1ul << 31) ;
65b815c7f3Sopenharmony_ci
66b815c7f3Sopenharmony_ci	for (j = 0 ; j < 32 ; j++)
67b815c7f3Sopenharmony_ci	{
68b815c7f3Sopenharmony_ci		if ((c & m) != 0)
69b815c7f3Sopenharmony_ci			break ;
70b815c7f3Sopenharmony_ci		c >>= 1 ;
71b815c7f3Sopenharmony_ci	}
72b815c7f3Sopenharmony_ci	return j ;
73b815c7f3Sopenharmony_ci}
74b815c7f3Sopenharmony_ci
75b815c7f3Sopenharmony_ci#define arithmin (a, b) ((a) < (b) ? (a) : (b))
76b815c7f3Sopenharmony_ci
77b815c7f3Sopenharmony_cistatic inline int32_t ALWAYS_INLINE lg3a (int32_t x)
78b815c7f3Sopenharmony_ci{
79b815c7f3Sopenharmony_ci	int32_t result ;
80b815c7f3Sopenharmony_ci
81b815c7f3Sopenharmony_ci	x += 3 ;
82b815c7f3Sopenharmony_ci	result = lead (x) ;
83b815c7f3Sopenharmony_ci
84b815c7f3Sopenharmony_ci	return 31 - result ;
85b815c7f3Sopenharmony_ci}
86b815c7f3Sopenharmony_ci
87b815c7f3Sopenharmony_cistatic inline int32_t ALWAYS_INLINE abs_func (int32_t a)
88b815c7f3Sopenharmony_ci{
89b815c7f3Sopenharmony_ci	// note: the CW PPC intrinsic __abs () turns into these instructions so no need to try and use it
90b815c7f3Sopenharmony_ci	int32_t isneg = a >> 31 ;
91b815c7f3Sopenharmony_ci	int32_t xorval = a ^ isneg ;
92b815c7f3Sopenharmony_ci	int32_t result = xorval-isneg ;
93b815c7f3Sopenharmony_ci
94b815c7f3Sopenharmony_ci	return result ;
95b815c7f3Sopenharmony_ci}
96b815c7f3Sopenharmony_ci
97b815c7f3Sopenharmony_ci#if PRAGMA_MARK
98b815c7f3Sopenharmony_ci#pragma mark -
99b815c7f3Sopenharmony_ci#endif
100b815c7f3Sopenharmony_ci
101b815c7f3Sopenharmony_cistatic inline int32_t dyn_code (int32_t m, int32_t k, int32_t n, uint32_t *outNumBits)
102b815c7f3Sopenharmony_ci{
103b815c7f3Sopenharmony_ci	uint32_t 	divx, mod, de ;
104b815c7f3Sopenharmony_ci	uint32_t	numBits ;
105b815c7f3Sopenharmony_ci	uint32_t	value ;
106b815c7f3Sopenharmony_ci
107b815c7f3Sopenharmony_ci	// Assert (n >= 0) ;
108b815c7f3Sopenharmony_ci
109b815c7f3Sopenharmony_ci	divx = n / m ;
110b815c7f3Sopenharmony_ci
111b815c7f3Sopenharmony_ci	if (divx >= MAX_PREFIX_16)
112b815c7f3Sopenharmony_ci	{
113b815c7f3Sopenharmony_ci		numBits = MAX_PREFIX_16 + MAX_DATATYPE_BITS_16 ;
114b815c7f3Sopenharmony_ci		value = (((1 << MAX_PREFIX_16) - 1) << MAX_DATATYPE_BITS_16) + n ;
115b815c7f3Sopenharmony_ci	}
116b815c7f3Sopenharmony_ci	else
117b815c7f3Sopenharmony_ci	{
118b815c7f3Sopenharmony_ci		mod = n%m ;
119b815c7f3Sopenharmony_ci		de = (mod == 0) ;
120b815c7f3Sopenharmony_ci		numBits = divx + k + 1 - de ;
121b815c7f3Sopenharmony_ci		value = (((1 << divx) - 1) << (numBits - divx)) + mod + 1 - de ;
122b815c7f3Sopenharmony_ci
123b815c7f3Sopenharmony_ci		// if coding this way is bigger than doing escape, then do escape
124b815c7f3Sopenharmony_ci		if (numBits > MAX_PREFIX_16 + MAX_DATATYPE_BITS_16)
125b815c7f3Sopenharmony_ci		{
126b815c7f3Sopenharmony_ci			numBits = MAX_PREFIX_16 + MAX_DATATYPE_BITS_16 ;
127b815c7f3Sopenharmony_ci			value = (((1 << MAX_PREFIX_16) - 1) << MAX_DATATYPE_BITS_16) + n ;
128b815c7f3Sopenharmony_ci		}
129b815c7f3Sopenharmony_ci	}
130b815c7f3Sopenharmony_ci
131b815c7f3Sopenharmony_ci	*outNumBits = numBits ;
132b815c7f3Sopenharmony_ci
133b815c7f3Sopenharmony_ci	return (int32_t) value ;
134b815c7f3Sopenharmony_ci}
135b815c7f3Sopenharmony_ci
136b815c7f3Sopenharmony_ci
137b815c7f3Sopenharmony_cistatic inline int32_t dyn_code_32bit (int32_t maxbits, uint32_t m, uint32_t k, uint32_t n, uint32_t *outNumBits, uint32_t *outValue, uint32_t *overflow, uint32_t *overflowbits)
138b815c7f3Sopenharmony_ci{
139b815c7f3Sopenharmony_ci	uint32_t 	divx, mod, de ;
140b815c7f3Sopenharmony_ci	uint32_t	numBits ;
141b815c7f3Sopenharmony_ci	uint32_t	value ;
142b815c7f3Sopenharmony_ci	int32_t			didOverflow = 0 ;
143b815c7f3Sopenharmony_ci
144b815c7f3Sopenharmony_ci	divx = n / m ;
145b815c7f3Sopenharmony_ci
146b815c7f3Sopenharmony_ci	if (divx < MAX_PREFIX_32)
147b815c7f3Sopenharmony_ci	{
148b815c7f3Sopenharmony_ci		mod = n - (m * divx) ;
149b815c7f3Sopenharmony_ci
150b815c7f3Sopenharmony_ci		de = (mod == 0) ;
151b815c7f3Sopenharmony_ci		numBits = divx + k + 1 - de ;
152b815c7f3Sopenharmony_ci		value = (((1 << divx) - 1) << (numBits - divx)) + mod + 1 - de ;
153b815c7f3Sopenharmony_ci		if (numBits > 25)
154b815c7f3Sopenharmony_ci			goto codeasescape ;
155b815c7f3Sopenharmony_ci	}
156b815c7f3Sopenharmony_ci	else
157b815c7f3Sopenharmony_ci	{
158b815c7f3Sopenharmony_cicodeasescape:
159b815c7f3Sopenharmony_ci		numBits = MAX_PREFIX_32 ;
160b815c7f3Sopenharmony_ci		value = (((1 << MAX_PREFIX_32) - 1)) ;
161b815c7f3Sopenharmony_ci		*overflow = n ;
162b815c7f3Sopenharmony_ci		*overflowbits = maxbits ;
163b815c7f3Sopenharmony_ci		didOverflow = 1 ;
164b815c7f3Sopenharmony_ci	}
165b815c7f3Sopenharmony_ci
166b815c7f3Sopenharmony_ci	*outNumBits = numBits ;
167b815c7f3Sopenharmony_ci	*outValue = value ;
168b815c7f3Sopenharmony_ci
169b815c7f3Sopenharmony_ci	return didOverflow ;
170b815c7f3Sopenharmony_ci}
171b815c7f3Sopenharmony_ci
172b815c7f3Sopenharmony_ci
173b815c7f3Sopenharmony_cistatic inline void ALWAYS_INLINE dyn_jam_noDeref (unsigned char *out, uint32_t bitPos, uint32_t numBits, uint32_t value)
174b815c7f3Sopenharmony_ci{
175b815c7f3Sopenharmony_ci	uint32_t	mask ;
176b815c7f3Sopenharmony_ci	uint32_t	curr ;
177b815c7f3Sopenharmony_ci	uint32_t	shift ;
178b815c7f3Sopenharmony_ci
179b815c7f3Sopenharmony_ci	//Assert (numBits <= 32) ;
180b815c7f3Sopenharmony_ci
181b815c7f3Sopenharmony_ci	curr = psf_get_be32 (out, bitPos >> 3) ;
182b815c7f3Sopenharmony_ci
183b815c7f3Sopenharmony_ci	shift = 32 - (bitPos & 7) - numBits ;
184b815c7f3Sopenharmony_ci
185b815c7f3Sopenharmony_ci	mask = ~0u >> (32 - numBits) ;		// mask must be created in two steps to avoid compiler sequencing ambiguity
186b815c7f3Sopenharmony_ci	mask <<= shift ;
187b815c7f3Sopenharmony_ci
188b815c7f3Sopenharmony_ci	value = (value << shift) & mask ;
189b815c7f3Sopenharmony_ci	value |= curr & ~mask ;
190b815c7f3Sopenharmony_ci
191b815c7f3Sopenharmony_ci	psf_put_be32 (out, bitPos >> 3, value) ;
192b815c7f3Sopenharmony_ci}
193b815c7f3Sopenharmony_ci
194b815c7f3Sopenharmony_ci
195b815c7f3Sopenharmony_cistatic inline void ALWAYS_INLINE dyn_jam_noDeref_large (unsigned char *out, uint32_t bitPos, uint32_t numBits, uint32_t value)
196b815c7f3Sopenharmony_ci{
197b815c7f3Sopenharmony_ci	uint32_t	w ;
198b815c7f3Sopenharmony_ci	uint32_t	curr ;
199b815c7f3Sopenharmony_ci	uint32_t	mask ;
200b815c7f3Sopenharmony_ci	int32_t		shiftvalue = (32 - (bitPos & 7) - numBits) ;
201b815c7f3Sopenharmony_ci
202b815c7f3Sopenharmony_ci	//Assert (numBits <= 32) ;
203b815c7f3Sopenharmony_ci
204b815c7f3Sopenharmony_ci	curr = psf_get_be32 (out, bitPos >> 3) ;
205b815c7f3Sopenharmony_ci
206b815c7f3Sopenharmony_ci	if (shiftvalue < 0)
207b815c7f3Sopenharmony_ci	{
208b815c7f3Sopenharmony_ci		uint8_t 	tailbyte ;
209b815c7f3Sopenharmony_ci		uint8_t 	*tailptr ;
210b815c7f3Sopenharmony_ci
211b815c7f3Sopenharmony_ci		w = value >> -shiftvalue ;
212b815c7f3Sopenharmony_ci		mask = ~0u >> -shiftvalue ;
213b815c7f3Sopenharmony_ci		w |= (curr & ~mask) ;
214b815c7f3Sopenharmony_ci
215b815c7f3Sopenharmony_ci		tailptr = out + (bitPos >> 3) + 4 ;
216b815c7f3Sopenharmony_ci		tailbyte = (value << ((8+shiftvalue))) & 0xff ;
217b815c7f3Sopenharmony_ci		*tailptr = (uint8_t) tailbyte ;
218b815c7f3Sopenharmony_ci	}
219b815c7f3Sopenharmony_ci	else
220b815c7f3Sopenharmony_ci	{
221b815c7f3Sopenharmony_ci		mask = ~0u >> (32 - numBits) ;
222b815c7f3Sopenharmony_ci		mask <<= shiftvalue ;			// mask must be created in two steps to avoid compiler sequencing ambiguity
223b815c7f3Sopenharmony_ci
224b815c7f3Sopenharmony_ci		w = (value << shiftvalue) & mask ;
225b815c7f3Sopenharmony_ci		w |= curr & ~mask ;
226b815c7f3Sopenharmony_ci	}
227b815c7f3Sopenharmony_ci
228b815c7f3Sopenharmony_ci	psf_put_be32 (out, bitPos >> 3, w) ;
229b815c7f3Sopenharmony_ci}
230b815c7f3Sopenharmony_ci
231b815c7f3Sopenharmony_ci
232b815c7f3Sopenharmony_ciint32_t dyn_comp (AGParamRecPtr params, int32_t * pc, BitBuffer * bitstream, int32_t numSamples, int32_t bitSize, uint32_t * outNumBits)
233b815c7f3Sopenharmony_ci{
234b815c7f3Sopenharmony_ci	unsigned char *		out ;
235b815c7f3Sopenharmony_ci	uint32_t		bitPos, startPos ;
236b815c7f3Sopenharmony_ci	uint32_t			m, k, n, c, mz, nz ;
237b815c7f3Sopenharmony_ci	uint32_t		numBits ;
238b815c7f3Sopenharmony_ci	uint32_t			value ;
239b815c7f3Sopenharmony_ci	int32_t				del, zmode ;
240b815c7f3Sopenharmony_ci	uint32_t		overflow, overflowbits ;
241b815c7f3Sopenharmony_ci	int32_t					status ;
242b815c7f3Sopenharmony_ci
243b815c7f3Sopenharmony_ci	// shadow the variables in params so there's not the dereferencing overhead
244b815c7f3Sopenharmony_ci	uint32_t		mb, pb, kb, wb ;
245b815c7f3Sopenharmony_ci	int32_t					rowPos = 0 ;
246b815c7f3Sopenharmony_ci	int32_t					rowSize = params->sw ;
247b815c7f3Sopenharmony_ci	int32_t					rowJump = (params->fw) - rowSize ;
248b815c7f3Sopenharmony_ci	int32_t *			inPtr = pc ;
249b815c7f3Sopenharmony_ci
250b815c7f3Sopenharmony_ci	*outNumBits = 0 ;
251b815c7f3Sopenharmony_ci	RequireAction ((bitSize >= 1) && (bitSize <= 32), return kALAC_ParamError ;) ;
252b815c7f3Sopenharmony_ci
253b815c7f3Sopenharmony_ci	out = bitstream->cur ;
254b815c7f3Sopenharmony_ci	startPos = bitstream->bitIndex ;
255b815c7f3Sopenharmony_ci	bitPos = startPos ;
256b815c7f3Sopenharmony_ci
257b815c7f3Sopenharmony_ci	mb = params->mb = params->mb0 ;
258b815c7f3Sopenharmony_ci	pb = params->pb ;
259b815c7f3Sopenharmony_ci	kb = params->kb ;
260b815c7f3Sopenharmony_ci	wb = params->wb ;
261b815c7f3Sopenharmony_ci	zmode = 0 ;
262b815c7f3Sopenharmony_ci
263b815c7f3Sopenharmony_ci	c = 0 ;
264b815c7f3Sopenharmony_ci	status = ALAC_noErr ;
265b815c7f3Sopenharmony_ci
266b815c7f3Sopenharmony_ci	while (c < (uint32_t) numSamples)
267b815c7f3Sopenharmony_ci	{
268b815c7f3Sopenharmony_ci		m = mb >> QBSHIFT ;
269b815c7f3Sopenharmony_ci		k = lg3a (m) ;
270b815c7f3Sopenharmony_ci		if (k > kb)
271b815c7f3Sopenharmony_ci		{
272b815c7f3Sopenharmony_ci			k = kb ;
273b815c7f3Sopenharmony_ci		}
274b815c7f3Sopenharmony_ci		m = (1 << k) - 1 ;
275b815c7f3Sopenharmony_ci
276b815c7f3Sopenharmony_ci		del = *inPtr++ ;
277b815c7f3Sopenharmony_ci		rowPos++ ;
278b815c7f3Sopenharmony_ci
279b815c7f3Sopenharmony_ci		n = (abs_func (del) << 1) - ((del >> 31) & 1) - zmode ;
280b815c7f3Sopenharmony_ci		//Assert (32-lead (n) <= bitSize) ;
281b815c7f3Sopenharmony_ci
282b815c7f3Sopenharmony_ci		if (dyn_code_32bit (bitSize, m, k, n, &numBits, &value, &overflow, &overflowbits))
283b815c7f3Sopenharmony_ci		{
284b815c7f3Sopenharmony_ci			dyn_jam_noDeref (out, bitPos, numBits, value) ;
285b815c7f3Sopenharmony_ci			bitPos += numBits ;
286b815c7f3Sopenharmony_ci			dyn_jam_noDeref_large (out, bitPos, overflowbits, overflow) ;
287b815c7f3Sopenharmony_ci			bitPos += overflowbits ;
288b815c7f3Sopenharmony_ci		}
289b815c7f3Sopenharmony_ci		else
290b815c7f3Sopenharmony_ci		{
291b815c7f3Sopenharmony_ci			dyn_jam_noDeref (out, bitPos, numBits, value) ;
292b815c7f3Sopenharmony_ci			bitPos += numBits ;
293b815c7f3Sopenharmony_ci		}
294b815c7f3Sopenharmony_ci
295b815c7f3Sopenharmony_ci		c++ ;
296b815c7f3Sopenharmony_ci		if (rowPos >= rowSize)
297b815c7f3Sopenharmony_ci		{
298b815c7f3Sopenharmony_ci			rowPos = 0 ;
299b815c7f3Sopenharmony_ci			inPtr += rowJump ;
300b815c7f3Sopenharmony_ci		}
301b815c7f3Sopenharmony_ci
302b815c7f3Sopenharmony_ci		mb = pb * (n + zmode) + mb - ((pb * mb) >> QBSHIFT) ;
303b815c7f3Sopenharmony_ci
304b815c7f3Sopenharmony_ci		// update mean tracking if it's overflowed
305b815c7f3Sopenharmony_ci		if (n > N_MAX_MEAN_CLAMP)
306b815c7f3Sopenharmony_ci			mb = N_MEAN_CLAMP_VAL ;
307b815c7f3Sopenharmony_ci
308b815c7f3Sopenharmony_ci		zmode = 0 ;
309b815c7f3Sopenharmony_ci
310b815c7f3Sopenharmony_ci		RequireAction (c <= (uint32_t) numSamples, status = kALAC_ParamError ; goto Exit ;) ;
311b815c7f3Sopenharmony_ci
312b815c7f3Sopenharmony_ci		if (((mb << MMULSHIFT) < QB) && (c < (uint32_t) numSamples))
313b815c7f3Sopenharmony_ci		{
314b815c7f3Sopenharmony_ci			zmode = 1 ;
315b815c7f3Sopenharmony_ci			nz = 0 ;
316b815c7f3Sopenharmony_ci
317b815c7f3Sopenharmony_ci			while (c < (uint32_t) numSamples && *inPtr == 0)
318b815c7f3Sopenharmony_ci			{
319b815c7f3Sopenharmony_ci				/* Take care of wrap-around globals. */
320b815c7f3Sopenharmony_ci				++inPtr ;
321b815c7f3Sopenharmony_ci				++nz ;
322b815c7f3Sopenharmony_ci				++c ;
323b815c7f3Sopenharmony_ci				if (++rowPos >= rowSize)
324b815c7f3Sopenharmony_ci				{
325b815c7f3Sopenharmony_ci					rowPos = 0 ;
326b815c7f3Sopenharmony_ci					inPtr += rowJump ;
327b815c7f3Sopenharmony_ci				}
328b815c7f3Sopenharmony_ci
329b815c7f3Sopenharmony_ci				if (nz >= 65535)
330b815c7f3Sopenharmony_ci				{
331b815c7f3Sopenharmony_ci					zmode = 0 ;
332b815c7f3Sopenharmony_ci					break ;
333b815c7f3Sopenharmony_ci				}
334b815c7f3Sopenharmony_ci			}
335b815c7f3Sopenharmony_ci
336b815c7f3Sopenharmony_ci			k = lead (mb) - BITOFF + ((mb + MOFF) >> MDENSHIFT) ;
337b815c7f3Sopenharmony_ci			mz = ((1 << k) - 1) & wb ;
338b815c7f3Sopenharmony_ci
339b815c7f3Sopenharmony_ci			value = dyn_code (mz, k, nz, &numBits) ;
340b815c7f3Sopenharmony_ci			dyn_jam_noDeref (out, bitPos, numBits, value) ;
341b815c7f3Sopenharmony_ci			bitPos += numBits ;
342b815c7f3Sopenharmony_ci
343b815c7f3Sopenharmony_ci			mb = 0 ;
344b815c7f3Sopenharmony_ci		}
345b815c7f3Sopenharmony_ci	}
346b815c7f3Sopenharmony_ci
347b815c7f3Sopenharmony_ci	*outNumBits = (bitPos - startPos) ;
348b815c7f3Sopenharmony_ci	BitBufferAdvance (bitstream, *outNumBits) ;
349b815c7f3Sopenharmony_ci
350b815c7f3Sopenharmony_ciExit:
351b815c7f3Sopenharmony_ci	return status ;
352b815c7f3Sopenharmony_ci}
353