summaryrefslogtreecommitdiff
path: root/audio_codec/libraac/aac_bitstream.c (plain)
blob: 696447f096208d19734a09d495a139dfb64cde81
1/* ***** BEGIN LICENSE BLOCK *****
2 * Source last modified: $Id: aac_bitstream.c,v 1.1.1.1.2.1 2005/05/04 18:21:58 hubbe Exp $
3 *
4 * REALNETWORKS CONFIDENTIAL--NOT FOR DISTRIBUTION IN SOURCE CODE FORM
5 * Portions Copyright (c) 1995-2005 RealNetworks, Inc.
6 * All Rights Reserved.
7 *
8 * The contents of this file, and the files included with this file,
9 * are subject to the current version of the Real Format Source Code
10 * Porting and Optimization License, available at
11 * https://helixcommunity.org/2005/license/realformatsource (unless
12 * RealNetworks otherwise expressly agrees in writing that you are
13 * subject to a different license). You may also obtain the license
14 * terms directly from RealNetworks. You may not use this file except
15 * in compliance with the Real Format Source Code Porting and
16 * Optimization License. There are no redistribution rights for the
17 * source code of this file. Please see the Real Format Source Code
18 * Porting and Optimization License for the rights, obligations and
19 * limitations governing use of the contents of the file.
20 *
21 * RealNetworks is the developer of the Original Code and owns the
22 * copyrights in the portions it created.
23 *
24 * This file, and the files included with this file, is distributed and
25 * made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND,
26 * EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL
27 * SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT
29 * OR NON-INFRINGEMENT.
30 *
31 * Technology Compatibility Kit Test Suite(s) Location:
32 * https://rarvcode-tck.helixcommunity.org
33 *
34 * Contributor(s):
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38#include <stdlib.h>
39#include "aac_bitstream.h"
40
41/** The bitstream structure.
42 * The idea of the bitstream reader is to keep a cache word that has the machine's
43 * largest native size. This word keeps the next-to-read bits left-aligned so that
44 * on a read, one shift suffices.
45 * The cache word is only refilled if it does not contain enough bits to satisy a
46 * a read request. Because the refill only happens in multiple of 8 bits, the maximum
47 * read size that is guaranteed to be always fulfilled is the number of bits in a long
48 * minus 8 (or whatever the number of bits in a byte is).
49 */
50
51struct BITSTREAM {
52 const unsigned char *buffer ; /**< points to the buffer holding the bits */
53 const unsigned char *pkptr ; /**< read pointer */
54 unsigned long cache ; /**< cache, always holds next bits left-aligned. */
55 int cacheBitsLeft ; /**< number of bits left in cache */
56 int nBits ; /**< the number of bits in the buffer */
57 int inc ; /**< read direction (forward/backward) */
58} ;
59
60enum {
61 CACHEBITS = 8 * sizeof(unsigned long)
62} ;
63
64static void fillUp(struct BITSTREAM *pBitstream)
65{
66 unsigned long k = 0 ;
67
68 while (CACHEBITS - pBitstream->cacheBitsLeft >= 8) {
69 k = (k << 8) + *(pBitstream->pkptr) ;
70 (pBitstream->pkptr) += pBitstream->inc ;
71 pBitstream->cacheBitsLeft += 8 ;
72 }
73 pBitstream->cache |= (k << (CACHEBITS - pBitstream->cacheBitsLeft)) ;
74}
75
76/** read nBits bits from bitstream
77 * @param pBitstream the bitstream to read from
78 * @param nBits the number of bits to read. nBits must be <= 32, currently.
79 * @return the bits read, right-justified
80 */
81unsigned int readBits(struct BITSTREAM *pBitstream, int nBits)
82{
83 unsigned int data ;
84
85 if (pBitstream->cacheBitsLeft < nBits) {
86 fillUp(pBitstream) ;
87 }
88
89 data = pBitstream->cache >> (CACHEBITS - nBits) ;
90 pBitstream->cache <<= nBits ;
91 pBitstream->cacheBitsLeft -= nBits ;
92
93 return data ;
94}
95
96/** push bits back into the bitstream.
97 * This call is here to make look-ahead possible, where after reading the client
98 * may realize it has read too far ahead. It is guaranteed to succeed as long as
99 * you don't push more bits back than have been read in the last readBits() call.
100 * @param pBitstream the bitstream to push back into
101 * @param bits the bits to push back
102 * @param nBits the number of bits to push back.
103 * @return an error code, signalling success or failure.
104 */
105int unreadBits(struct BITSTREAM *pBitstream, int bits, int nBits)
106{
107 pBitstream->cache = (pBitstream->cache >> nBits) | (bits << (CACHEBITS - nBits)) ;
108 pBitstream->cacheBitsLeft += nBits ;
109 return pBitstream->cacheBitsLeft > (signed)CACHEBITS ? -1 : 0 ;
110}
111
112/** byte-align the bitstream read pointer. */
113void byteAlign(struct BITSTREAM *pBitstream)
114{
115 int adjust = (pBitstream->cacheBitsLeft & 7) ;
116 pBitstream->cache <<= adjust ;
117 pBitstream->cacheBitsLeft -= adjust ;
118}
119
120/** allocate memory for a new bitstream structure.
121 * @param ppBitstream a pointer to a bitstream handle, to be initialized on
122 * successfull return
123 * @param nBits the maximum number of bits this bitstream must be able to hold.
124 * nBits must be divisible by 32.
125 * @param pUserMem optional user-defined memory handle
126 * @param fpMalloc user-defined malloc() implementation
127 * @return an error code, signalling success or failure.
128 * @see reverseBitstream
129 */
130int newBitstream(struct BITSTREAM **ppBitstream, int nBits,
131 void* pUserMem, rm_malloc_func_ptr fpMalloc)
132{
133 struct BITSTREAM *pBitstream ;
134
135 pBitstream = (struct BITSTREAM *)fpMalloc(pUserMem, sizeof(struct BITSTREAM)) ;
136 if (!pBitstream || !ppBitstream) {
137 return -1 ;
138 }
139
140 pBitstream->cacheBitsLeft = 0 ;
141 *ppBitstream = pBitstream ;
142
143 return 0 ;
144}
145
146/** free memory associated with a bitstream structure.
147 * @param pBitstream a bitstream handle
148 * @param pUserMem optional user-defined memory handle
149 * @param fpFree user-defined free() implementation
150 */
151void deleteBitstream(struct BITSTREAM *pBitstream, void* pUserMem,
152 rm_free_func_ptr fpFree)
153{
154 if (pBitstream) {
155 fpFree(pUserMem, pBitstream) ;
156 }
157}
158
159/** feed nbits bits to the bitstream, byte-wise.
160 * @param pBitstream the bitstream into which to feed the bytes
161 * @param input the input from which to read the bytes
162 * @param nbits the number of bits in the input. nbits must be divisible by 32
163 * for reverseBitstream() to work.
164 * @return an error code, signalling success or failure.
165 * @see reverseBitstream
166 */
167
168int feedBitstream(struct BITSTREAM *pBitstream, const unsigned char *input, int nbits)
169{
170 pBitstream->buffer = input ;
171 pBitstream->nBits = nbits ;
172
173 return 0 ;
174}
175
176/** return the number of bits left until end-of-stream.
177 * @param pBitstream the bitstream
178 * @return the number of bits left
179 */
180
181int bitsLeftInBitstream(struct BITSTREAM *pBitstream)
182{
183 return pBitstream->nBits - (pBitstream->pkptr - pBitstream->buffer) * 8 + pBitstream->cacheBitsLeft ;
184}
185
186/** set bitstream position, relative to origin defined through feedBitstream().
187 * @param pBitstream the bitstream
188 * @param position the position in bits (must be multiple of 8, currently).
189 * Always measured from beginning, regardless of direction.
190 * @param direction the direction of reading (+1/-1)
191 */
192
193int setAtBitstream(struct BITSTREAM *pBitstream, int position, int direction)
194{
195 pBitstream->pkptr = pBitstream->buffer + (position >> 3) ;
196 pBitstream->cacheBitsLeft = 0 ;
197 pBitstream->cache = 0 ;
198 pBitstream->inc = direction ;
199 return 0 ;
200}
201