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 */
44typedef 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
139void impeg2d_bit_stream_init(stream_t *stream,
140                             UWORD8 *byteBuf,
141                             UWORD32 u4_max_offset);
142INLINE UWORD8 impeg2d_bit_stream_get_bit(stream_t *stream);
143INLINE void impeg2d_bit_stream_flush(void* ctxt, UWORD32 NoOfBits);
144INLINE void impeg2d_bit_stream_flush_to_byte_boundary(void* ctxt);
145INLINE UWORD32 impeg2d_bit_stream_nxt(stream_t *stream, WORD32 NoOfBits);
146
147INLINE UWORD32 impeg2d_bit_stream_get(void* ctxt, UWORD32 numBits);
148INLINE UWORD32 impeg2d_bit_stream_num_bits_read(void* ctxt);
149
150
151
152
153
154
155
156#endif /* __IMPEG2D_BITSTREAM_H__ */
157