1 /******************************************************************************
2  *
3  * Copyright (C) 2015 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 /*****************************************************************************/
21 /*                                                                           */
22 /*  File Name         : impeg2d_bitstream.h                                       */
23 /*                                                                           */
24 /*  Description       : This file contains all the necessary examples to     */
25 /*                      establish a consistent use of Ittiam C coding        */
26 /*                      standards (based on Indian Hill C Standards)         */
27 /*                                                                           */
28 /*  List of Functions : <List the functions defined in this file>            */
29 /*                                                                           */
30 /*  Issues / Problems : None                                                 */
31 /*                                                                           */
32 /*  Revision History  :                                                      */
33 /*                                                                           */
34 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
35 /*         10 01 2005   Ittiam          Draft                                */
36 /*                                                                           */
37 /*****************************************************************************/
38 #ifndef __IMPEG2D_BITSTREAM_H__
39 #define __IMPEG2D_BITSTREAM_H__
40 
41 
42 
43 /* Structure for the stream */
44 typedef struct _stream_t
45 {
46     void    *pv_bs_buf;               /* Pointer to buffer containing the
47                                         bitstream                    */
48 
49     UWORD32  *pu4_buf_aligned;         /* Pointer to the buffer after alignment correction,
50                                          It points to the currently usable buffer */
51 
52     UWORD32  u4_offset;                  /* Offset in the buffer for the current bit */
53 
54     UWORD32  u4_buf;                  /* Buffer storing the current word */
55 
56     UWORD32  u4_buf_nxt;              /* Buffer storing the next Word */
57 
58     UWORD32  u4_max_offset;            /* Max Bit stream buffer offset in bytes for error checks */
59 } stream_t;
60 
61 #define GET_MARKER_BIT(dec,stream)                                             \
62 {                                                                              \
63     if (impeg2d_bit_stream_get(stream,1) != 0x1) {                             \
64     /* No need to return error if marker is not present. */                    \
65     }                                                                          \
66 }
67 
68 /* Define A macro for inlining of FlushBits */
69 #define     FLUSH_BITS(u4_offset,u4_buf,u4_buf_nxt,u4_no_bits,pu4_buf_aligned) \
70 {                                                                              \
71         UWORD32     u4_temp;                                                   \
72                                                                                \
73         if (((u4_offset & 0x1f) + u4_no_bits)>= 32)                            \
74         {                                                                      \
75             u4_buf              = u4_buf_nxt;                                  \
76                                                                                \
77             u4_temp             = *(pu4_buf_aligned)++;                        \
78                                                                                \
79             CONV_LE_TO_BE(u4_buf_nxt,u4_temp)                                  \
80         }                                                                      \
81         u4_offset               += u4_no_bits;                                 \
82 }
83 
84 /* Macro to initialize the variables from stream */
85 #define GET_TEMP_STREAM_DATA(u4_buf,u4_buf_nxt,u4_offset,pu4_buf_aligned,stream)    \
86 {                                                                                   \
87     u4_buf = stream->u4_buf;                                                        \
88     u4_buf_nxt = stream->u4_buf_nxt;                                                \
89     u4_offset = stream->u4_offset;                                                     \
90     pu4_buf_aligned = stream->pu4_buf_aligned;                                      \
91 }
92 
93 /* Macro to put the stream variable values back */
94 #define PUT_TEMP_STREAM_DATA(u4_buf,u4_buf_nxt,u4_offset,pu4_buf_aligned,stream)    \
95 {                                                                                   \
96     stream->u4_buf = u4_buf;                                                        \
97     stream->u4_buf_nxt = u4_buf_nxt;                                                \
98     stream->u4_offset = u4_offset;                                                     \
99     stream->pu4_buf_aligned = pu4_buf_aligned;                                      \
100 }
101 
102 /* Macro to implement the get bits inline (ibits_nxt_inline) */
103 #define IBITS_NXT(u4_buf, u4_buf_nxt, u4_offset, u4_bits, no_of_bits)              \
104 {                                                                                   \
105     UWORD8 u4_bit_ptr;                                                              \
106     UWORD32 u4_temp;                                                                \
107                                                                                     \
108     u4_bit_ptr  = u4_offset & 0x1F;                                                 \
109     u4_bits     = u4_buf << u4_bit_ptr;                                             \
110                                                                                     \
111     u4_bit_ptr  += no_of_bits;                                                      \
112                                                                                     \
113     if(32 < u4_bit_ptr)                                                             \
114     {                                                                               \
115         /*  Read bits from the next word if necessary */                            \
116         u4_temp     = u4_buf_nxt;                                           \
117         u4_bit_ptr  &= (BITS_IN_INT - 1);                                           \
118                                                                                     \
119         u4_temp     = (u4_temp >> (BITS_IN_INT - u4_bit_ptr));                      \
120                                                                                     \
121     /* u4_temp consists of bits,if any that had to be read from the next word*/     \
122     /* of the buffer.The bits read from both the words are concatenated and*/       \
123     /* moved to the least significant positions of 'u4_bits'*/                      \
124             u4_bits = (u4_bits >> (32 - no_of_bits)) | u4_temp;                     \
125         }                                                                           \
126         else                                                                        \
127         {                                                                           \
128             u4_bits = (u4_bits >> (32 - no_of_bits));                               \
129         }                                                                           \
130 }
131 
132 /* Macro to implement the get bits inline (ibits_get_inline) */
133 #define IBITS_GET(u4_buf,u4_buf_nxt,u4_offset,u4_bits,pu4_buf_aligned,no_of_bits)   \
134 {                                                                                   \
135     IBITS_NXT(u4_buf, u4_buf_nxt, u4_offset, u4_bits, no_of_bits)                   \
136     FLUSH_BITS(u4_offset,u4_buf,u4_buf_nxt,no_of_bits,pu4_buf_aligned)              \
137 }
138 
139 void impeg2d_bit_stream_init(stream_t *stream,
140                              UWORD8 *byteBuf,
141                              UWORD32 u4_max_offset);
142 INLINE UWORD8 impeg2d_bit_stream_get_bit(stream_t *stream);
143 INLINE void impeg2d_bit_stream_flush(void* ctxt, UWORD32 NoOfBits);
144 INLINE void impeg2d_bit_stream_flush_to_byte_boundary(void* ctxt);
145 INLINE UWORD32 impeg2d_bit_stream_nxt(stream_t *stream, WORD32 NoOfBits);
146 
147 INLINE UWORD32 impeg2d_bit_stream_get(void* ctxt, UWORD32 numBits);
148 INLINE UWORD32 impeg2d_bit_stream_num_bits_read(void* ctxt);
149 
150 
151 
152 
153 
154 
155 
156 #endif /* __IMPEG2D_BITSTREAM_H__ */
157