1/* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18/*
19
20 Pathname: getbits.h
21
22------------------------------------------------------------------------------
23 REVISION HISTORY
24
25 Description: Update comments for the structure
26
27 Description: Move structur to another file
28
29 Who:                                            Date: MM/DD/YYYY
30 Description:
31
32
33------------------------------------------------------------------------------
34 INCLUDE DESCRIPTION
35
36 Header file for the function getbits().
37
38------------------------------------------------------------------------------
39*/
40
41/*----------------------------------------------------------------------------
42; CONTINUE ONLY IF NOT ALREADY DEFINED
43----------------------------------------------------------------------------*/
44#ifndef GETBITS_H
45#define GETBITS_H
46
47#ifdef __cplusplus
48extern "C"
49{
50#endif
51
52    /*----------------------------------------------------------------------------
53    ; INCLUDES
54    ----------------------------------------------------------------------------*/
55#include "pv_audio_type_defs.h"
56#include "ibstream.h"
57
58    /*----------------------------------------------------------------------------
59    ; MACROS
60    ; Define module specific macros here
61    ----------------------------------------------------------------------------*/
62
63    /*----------------------------------------------------------------------------
64    ; DEFINES
65    ; Include all pre-processor statements here.
66    ----------------------------------------------------------------------------*/
67
68    /*----------------------------------------------------------------------------
69    ; EXTERNAL VARIABLES REFERENCES
70    ; Declare variables used in this module but defined elsewhere
71    ----------------------------------------------------------------------------*/
72
73    /*----------------------------------------------------------------------------
74    ; SIMPLE TYPEDEF'S
75    ----------------------------------------------------------------------------*/
76
77    /*----------------------------------------------------------------------------
78    ; ENUMERATED TYPEDEF'S
79    ----------------------------------------------------------------------------*/
80
81    /*----------------------------------------------------------------------------
82    ; STRUCTURES TYPEDEF'S
83    ----------------------------------------------------------------------------*/
84
85    /*----------------------------------------------------------------------------
86    ; GLOBAL FUNCTION DEFINITIONS
87    ; Function Prototype declaration
88    ----------------------------------------------------------------------------*/
89
90#define INBUF_ARRAY_INDEX_SHIFT  (3)
91#define INBUF_BIT_WIDTH         (1<<(INBUF_ARRAY_INDEX_SHIFT))
92#define INBUF_BIT_MODULO_MASK   ((INBUF_BIT_WIDTH)-1)
93
94#define MAX_GETBITS             (25)
95
96#define  CHECK_INPUT_BUFFER_LIMITS  1
97
98    __inline UInt32 getbits(
99        const UInt  neededBits,
100        BITS       *pInputStream)
101    {
102        UInt32   returnValue = 0;
103        UInt     offset;
104        UInt     bitIndex;
105        UChar    *pElem;        /* Needs to be same type as pInput->pBuffer */
106
107        offset = (pInputStream->usedBits) >> INBUF_ARRAY_INDEX_SHIFT;
108
109        pElem = pInputStream->pBuffer + offset;
110
111#if CHECK_INPUT_BUFFER_LIMITS
112
113        offset =  pInputStream->inputBufferCurrentLength - offset;
114        /*  check if access to input buffer does not go beyond boundaries */
115        if (offset > 3)
116        {
117            returnValue = (((UInt32) * (pElem)) << 24) |
118                          (((UInt32) * (pElem + 1)) << 16) |
119                          (((UInt32) * (pElem + 2)) << 8) |
120                          ((UInt32) * (pElem + 3));
121        }
122        else  /*  then access only available bytes  */
123        {
124            /*  Access to the bitstream beyond frame boundaries are not allowed,
125             *  Here, only what was available before the end of the frame will
126             *  be processed. Non-accessible bytes will be filled in with zeros.
127             *  Zero values guarantees that the data structures are filled in with values
128             *  that eventually will signal an error (like invalid parameters) or that allow
129             *  completion of the parsing routine.
130             *  Overrun is detected on file pvmp4audiodecodeframe.cpp.
131             */
132            switch (offset)
133            {
134                case 3:
135                    returnValue  = (((UInt32) * (pElem + 2)) << 8);
136                case 2:
137                    returnValue |= (((UInt32) * (pElem + 1)) << 16);
138                case 1:
139                    returnValue |= (((UInt32) * (pElem)) << 24);
140                default:
141                    break;
142            }
143        }
144
145
146#else
147
148        returnValue = (((UInt32) * (pElem)) << 24) |
149                      (((UInt32) * (pElem + 1)) << 16) |
150                      (((UInt32) * (pElem + 2)) << 8) |
151                      ((UInt32) * (pElem + 3));
152#endif
153
154        /* Remove extra high bits by shifting up */
155        bitIndex = (UInt)((pInputStream->usedBits) & INBUF_BIT_MODULO_MASK);
156
157        /* This line is faster way to mask off the high bits. */
158        returnValue = returnValue << (bitIndex);
159
160        /* Move the field down. */
161        returnValue = returnValue >> (32 - neededBits);
162
163        pInputStream->usedBits += neededBits;
164
165        return (returnValue);
166
167    }
168
169
170
171    __inline UInt get1bits(
172        BITS       *pInputStream)
173    {
174        UInt     returnValue;
175        UInt     offset;
176        UInt     bitIndex;
177        UChar    *pElem;        /* Needs to be same type as pInput->pBuffer */
178
179        offset = (pInputStream->usedBits) >> INBUF_ARRAY_INDEX_SHIFT;
180
181        pElem = pInputStream->pBuffer + offset;
182
183#if CHECK_INPUT_BUFFER_LIMITS
184        returnValue = (offset < pInputStream->inputBufferCurrentLength) ? ((UInt) * (pElem)) : 0;
185#else
186        returnValue = ((UInt32) * (pElem));
187#endif
188
189
190        /* Remove extra high bits by shifting up */
191        bitIndex = (UInt)((pInputStream->usedBits++) & INBUF_BIT_MODULO_MASK);
192
193        /* This line is faster way to mask off the high bits. */
194        returnValue = 0xFF & (returnValue << (bitIndex));
195
196        /* Move the field down. */
197
198        return ((UInt)(returnValue >> 7));
199
200    }
201
202
203
204    __inline UInt get9_n_lessbits(
205        const UInt  neededBits,
206        BITS       *pInputStream)
207
208    {
209        UInt     returnValue;
210        UInt     offset;
211        UInt     bitIndex;
212        UChar    *pElem;        /* Needs to be same type as pInput->pBuffer */
213
214        offset = (pInputStream->usedBits) >> INBUF_ARRAY_INDEX_SHIFT;
215
216        pElem = pInputStream->pBuffer + offset;
217
218#if CHECK_INPUT_BUFFER_LIMITS
219
220
221        offset =  pInputStream->inputBufferCurrentLength - offset;
222        /*  check if access to input buffer does not go beyond boundaries */
223        if (offset > 1)
224        {
225            returnValue = (((UInt32) * (pElem)) << 8) |
226                          ((UInt32) * (pElem + 1));
227        }
228        else  /*  then access only available bytes  */
229        {
230            /*  Access to the bitstream beyond frame boundaries are not allowed,
231             *  Here, only what was available before the end of the frame will
232             *  be processed. Non-accessible bytes will be filled in with zeros.
233             *  Zero values guarantees that the data structures are filled in with values
234             *  that eventually will signal an error (like invalid parameters) or that allow
235             *  completion of the parsing routine.
236             *  Overrun is detected on file pvmp4audiodecodeframe.cpp
237             */
238            switch (offset)
239            {
240                case 1:
241                    returnValue  = (((UInt32) * (pElem)) << 8);
242                    break;
243                default:
244                    returnValue = 0;
245                    break;
246            }
247        }
248
249
250#else
251        returnValue = (((UInt32) * (pElem)) << 8) |
252                      ((UInt32) * (pElem + 1)) ;
253#endif
254
255        /* Remove extra high bits by shifting up */
256        bitIndex = (UInt)((pInputStream->usedBits) & INBUF_BIT_MODULO_MASK);
257
258        pInputStream->usedBits += neededBits;
259
260        /* This line is faster way to mask off the high bits. */
261        returnValue = 0xFFFF & (returnValue << (bitIndex));
262
263        /* Move the field down. */
264
265        return (UInt)(returnValue >> (16 - neededBits));
266
267    }
268
269    __inline UInt32 get17_n_lessbits(
270        const UInt  neededBits,
271        BITS       *pInputStream)
272    {
273        UInt32   returnValue;
274        UInt     offset;
275        UInt     bitIndex;
276        UChar    *pElem;        /* Needs to be same type as pInput->pBuffer */
277
278        offset = (pInputStream->usedBits) >> INBUF_ARRAY_INDEX_SHIFT;
279
280        pElem = pInputStream->pBuffer + offset;
281
282#if CHECK_INPUT_BUFFER_LIMITS
283
284        offset =  pInputStream->inputBufferCurrentLength - offset;
285        /*  check if access to input buffer does not go beyond boundaries */
286
287        if (offset > 2)
288        {
289            returnValue = (((UInt32) * (pElem)) << 16) |
290                          (((UInt32) * (pElem + 1)) << 8) |
291                          ((UInt32)  * (pElem + 2));
292        }
293        else   /*  then access only available bytes  */
294        {
295            /*  Access to the bitstream beyond frame boundaries are not allowed,
296             *  Here, only what was available before the end of the frame will
297             *  be processed. Non-accessible bytes will be filled in with zeros.
298             *  Zero values guarantees that the data structures are filled in with values
299             *  that eventually will signal an error (like invalid parameters) or that allow
300             *  completion of the parsing routine.
301             *  Overrun is detected on file pvmp4audiodecodeframe.cpp
302             */
303            returnValue = 0;
304            switch (offset)
305            {
306                case 2:
307                    returnValue  = (((UInt32) * (pElem + 1)) << 8);
308                case 1:
309                    returnValue |= (((UInt32) * (pElem)) << 16);
310                default:
311                    break;
312            }
313        }
314
315#else
316
317        returnValue = (((UInt32) * (pElem)) << 16) |
318                      (((UInt32) * (pElem + 1)) << 8) |
319                      ((UInt32)  * (pElem + 2));
320#endif
321
322        /* Remove extra high bits by shifting up */
323        bitIndex = (UInt)((pInputStream->usedBits) & INBUF_BIT_MODULO_MASK);
324
325        /* This line is faster way to mask off the high bits. */
326        returnValue = 0xFFFFFF & (returnValue << (bitIndex));
327
328        /* Move the field down. */
329        returnValue = returnValue >> (24 - neededBits);
330
331        pInputStream->usedBits += neededBits;
332
333        return (returnValue);
334
335    }
336
337#ifdef __cplusplus
338}
339#endif
340
341/*----------------------------------------------------------------------------
342; END
343----------------------------------------------------------------------------*/
344#endif /* GETBITS_H*/
345
346
347