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 | |
51 | struct 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 | |
60 | enum { |
61 | CACHEBITS = 8 * sizeof(unsigned long) |
62 | } ; |
63 | |
64 | static 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 | */ |
81 | unsigned 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 | */ |
105 | int 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. */ |
113 | void 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 | */ |
130 | int 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 | */ |
151 | void 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 | |
168 | int 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 | |
181 | int 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 | |
193 | int 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 |