1 /******************************************************************************
2  *
3  *  Copyright 2014 The Android Open Source Project
4  *  Copyright 2003 - 2004 Open Interface North America, Inc. All rights
5  *                        reserved.
6  *
7  *  Licensed under the Apache License, Version 2.0 (the "License");
8  *  you may not use this file except in compliance with the License.
9  *  You may obtain a copy of the License at:
10  *
11  *  http://www.apache.org/licenses/LICENSE-2.0
12  *
13  *  Unless required by applicable law or agreed to in writing, software
14  *  distributed under the License is distributed on an "AS IS" BASIS,
15  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *  See the License for the specific language governing permissions and
17  *  limitations under the License.
18  *
19  ******************************************************************************/
20 #ifndef _OI_BITSTREAM_H
21 #define _OI_BITSTREAM_H
22 
23 /*******************************************************************************
24   $Revision: #1 $
25  ******************************************************************************/
26 
27 /**
28 @file
29 Function prototypes and macro definitions for manipulating input and output
30 bitstreams.
31 
32 @ingroup codec_internal
33 */
34 
35 /**
36 @addtogroup codec_internal
37 @{
38 */
39 
40 #include "oi_codec_sbc_private.h"
41 #include "oi_stddefs.h"
42 
43 INLINE void OI_BITSTREAM_ReadInit(OI_BITSTREAM* bs, const OI_BYTE* buffer);
44 
45 INLINE void OI_BITSTREAM_WriteInit(OI_BITSTREAM* bs, OI_BYTE* buffer);
46 
47 INLINE uint32_t OI_BITSTREAM_ReadUINT(OI_BITSTREAM* bs, OI_UINT bits);
48 
49 INLINE uint8_t OI_BITSTREAM_ReadUINT4Aligned(OI_BITSTREAM* bs);
50 
51 INLINE uint8_t OI_BITSTREAM_ReadUINT8Aligned(OI_BITSTREAM* bs);
52 
53 INLINE void OI_BITSTREAM_WriteUINT(OI_BITSTREAM* bs, uint16_t value,
54                                    OI_UINT bits);
55 
56 /*
57  * Use knowledge that the bitstream is aligned to optimize the write of a byte
58  */
59 PRIVATE void OI_BITSTREAM_WriteUINT8Aligned(OI_BITSTREAM* bs, uint8_t datum);
60 
61 /*
62  * Use knowledge that the bitstream is aligned to optimize the writing of a
63  * pair of nibbles.
64  */
65 PRIVATE void OI_BITSTREAM_Write2xUINT4Aligned(OI_BITSTREAM* bs, uint8_t datum1,
66                                               uint8_t datum2);
67 
68 /** Internally the bitstream looks ahead in the stream. When
69  * OI_SBC_ReadScalefactors() goes to temporarily break the abstraction, it will
70  * need to know where the "logical" pointer is in the stream.
71  */
72 #define OI_BITSTREAM_GetWritePtr(bs) ((bs)->ptr.w - 3)
73 #define OI_BITSTREAM_GetReadPtr(bs) ((bs)->ptr.r - 3)
74 
75 /** This is declared here as a macro because decoder.c breaks the bitsream
76  * encapsulation for efficiency reasons.
77  */
78 #define OI_BITSTREAM_READUINT(result, bits, ptr, value, bitPtr) \
79   do {                                                          \
80     OI_ASSERT((bits) <= 16);                                    \
81     OI_ASSERT((bitPtr) < 32);                                   \
82     OI_ASSERT((bitPtr) >= 0);                                   \
83                                                                 \
84     while ((bitPtr + bits) > 32) {                              \
85       (value) = ((value) << 8) | *(ptr)++;                      \
86       (bitPtr) -= 8;                                            \
87     }                                                           \
88                                                                 \
89     (result) = (value) << (bitPtr);                             \
90     (result) >>= 32 - (bits);                                   \
91                                                                 \
92     (bitPtr) += (bits);                                         \
93     OI_ASSERT(((bits) == 0) || ((result) < (1u << (bits))));    \
94   } while (0)
95 
96 #define OI_BITSTREAM_WRITEUINT(ptr, value, bitPtr, datum, bits) \
97   do {                                                          \
98     (bitPtr) -= (bits);                                         \
99     (value) |= (datum) << (bitPtr);                             \
100                                                                 \
101     while ((bitPtr) <= 16) {                                    \
102       (bitPtr) += 8;                                            \
103       *(ptr)++ = (uint8_t)((value) >> 24);                      \
104       (value) <<= 8;                                            \
105     }                                                           \
106   } while (0)
107 
108 #define OI_BITSTREAM_WRITEFLUSH(ptr, value, bitPtr) \
109   do {                                              \
110     while ((bitPtr) < 32) {                         \
111       (bitPtr) += 8;                                \
112       *(ptr)++ = (uint8_t)((value) >> 24);          \
113       (value) <<= 8;                                \
114     }                                               \
115   } while (0)
116 
117 /**
118 @}
119 */
120 
121 #endif /* _OI_BITSTREAM_H */
122