armCOMM_Bitstream.c revision 0c1bc742181ded4930842b46e9507372f0b1b963
1/**
2 *
3 * File Name:  armCOMM_Bitstream.c
4 * OpenMAX DL: v1.0.2
5 * Revision:   9641
6 * Date:       Thursday, February 7, 2008
7 *
8 * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
9 *
10 *
11 *
12 * Defines bitstream encode and decode functions common to all codecs
13 */
14
15#include "omxtypes.h"
16#include "armCOMM.h"
17#include "armCOMM_Bitstream.h"
18
19/***************************************
20 * Fixed bit length Decode
21 ***************************************/
22
23/**
24 * Function: armLookAheadBits()
25 *
26 * Description:
27 * Get the next N bits from the bitstream without advancing the bitstream pointer
28 *
29 * Parameters:
30 * [in]     **ppBitStream
31 * [in]     *pOffset
32 * [in]     N=1...32
33 *
34 * Returns  Value
35 */
36
37OMX_U32 armLookAheadBits(const OMX_U8 **ppBitStream, OMX_INT *pOffset, OMX_INT N)
38{
39    const OMX_U8 *pBitStream = *ppBitStream;
40    OMX_INT Offset = *pOffset;
41    OMX_U32 Value;
42
43    armAssert(Offset>=0 && Offset<=7);
44    armAssert(N>=1 && N<=32);
45
46    /* Read next 32 bits from stream */
47    Value = (pBitStream[0] << 24 ) | ( pBitStream[1] << 16)  | (pBitStream[2] << 8 ) | (pBitStream[3]) ;
48    Value = (Value << Offset ) | (pBitStream[4] >> (8-Offset));
49
50    /* Return N bits */
51    return Value >> (32-N);
52}
53
54
55/**
56 * Function: armGetBits()
57 *
58 * Description:
59 * Read N bits from the bitstream
60 *
61 * Parameters:
62 * [in]     *ppBitStream
63 * [in]     *pOffset
64 * [in]     N=1..32
65 *
66 * [out]    *ppBitStream
67 * [out]    *pOffset
68 * Returns  Value
69 */
70
71
72OMX_U32 armGetBits(const OMX_U8 **ppBitStream, OMX_INT *pOffset, OMX_INT N)
73{
74    const OMX_U8 *pBitStream = *ppBitStream;
75    OMX_INT Offset = *pOffset;
76    OMX_U32 Value;
77
78    if(N == 0)
79    {
80      return 0;
81    }
82
83    armAssert(Offset>=0 && Offset<=7);
84    armAssert(N>=1 && N<=32);
85
86    /* Read next 32 bits from stream */
87    Value = (pBitStream[0] << 24 ) | ( pBitStream[1] << 16)  | (pBitStream[2] << 8 ) | (pBitStream[3]) ;
88    Value = (Value << Offset ) | (pBitStream[4] >> (8-Offset));
89
90    /* Advance bitstream pointer by N bits */
91    Offset += N;
92    *ppBitStream = pBitStream + (Offset>>3);
93    *pOffset = Offset & 7;
94
95    /* Return N bits */
96    return Value >> (32-N);
97}
98
99/**
100 * Function: armByteAlign()
101 *
102 * Description:
103 * Align the pointer *ppBitStream to the next byte boundary
104 *
105 * Parameters:
106 * [in]     *ppBitStream
107 * [in]     *pOffset
108 *
109 * [out]    *ppBitStream
110 * [out]    *pOffset
111 *
112 **/
113
114OMXVoid armByteAlign(const OMX_U8 **ppBitStream,OMX_INT *pOffset)
115{
116    if(*pOffset > 0)
117    {
118        *ppBitStream += 1;
119        *pOffset = 0;
120    }
121}
122
123/**
124 * Function: armSkipBits()
125 *
126 * Description:
127 * Skip N bits from the value at *ppBitStream
128 *
129 * Parameters:
130 * [in]     *ppBitStream
131 * [in]     *pOffset
132 * [in]     N
133 *
134 * [out]    *ppBitStream
135 * [out]    *pOffset
136 *
137 **/
138
139
140OMXVoid armSkipBits(const OMX_U8 **ppBitStream,OMX_INT *pOffset,OMX_INT N)
141{
142    OMX_INT Offset = *pOffset;
143    const OMX_U8 *pBitStream = *ppBitStream;
144
145    /* Advance bitstream pointer by N bits */
146    Offset += N;
147    *ppBitStream = pBitStream + (Offset>>3);
148    *pOffset = Offset & 7;
149}
150
151/***************************************
152 * Variable bit length Decode
153 ***************************************/
154
155/**
156 * Function: armUnPackVLC32()
157 *
158 * Description:
159 * Variable length decode of variable length symbol (max size 32 bits) read from
160 * the bit stream pointed by *ppBitStream at *pOffset by using the table
161 * pointed by pCodeBook
162 *
163 * Parameters:
164 * [in]     *pBitStream
165 * [in]     *pOffset
166 * [in]     pCodeBook
167 *
168 * [out]    *pBitStream
169 * [out]    *pOffset
170 *
171 * Returns : Code Book Index if successfull.
172 *         : ARM_NO_CODEBOOK_INDEX = -1 if search fails.
173 **/
174#ifndef C_OPTIMIZED_IMPLEMENTATION
175
176OMX_U16 armUnPackVLC32(
177    const OMX_U8 **ppBitStream,
178    OMX_INT *pOffset,
179    const ARM_VLC32 *pCodeBook
180)
181{
182    const OMX_U8 *pBitStream = *ppBitStream;
183    OMX_INT Offset = *pOffset;
184    OMX_U32 Value;
185    OMX_INT Index;
186
187    armAssert(Offset>=0 && Offset<=7);
188
189    /* Read next 32 bits from stream */
190    Value = (pBitStream[0] << 24 ) | ( pBitStream[1] << 16)  | (pBitStream[2] << 8 ) | (pBitStream[3]) ;
191    Value = (Value << Offset ) | (pBitStream[4] >> (8-Offset));
192
193    /* Search through the codebook */
194    for (Index=0; pCodeBook->codeLen != 0; Index++)
195    {
196        if (pCodeBook->codeWord == (Value >> (32 - pCodeBook->codeLen)))
197        {
198            Offset       = Offset + pCodeBook->codeLen;
199            *ppBitStream = pBitStream + (Offset >> 3) ;
200            *pOffset     = Offset & 7;
201
202            return Index;
203        }
204        pCodeBook++;
205    }
206
207    /* No code match found */
208    return ARM_NO_CODEBOOK_INDEX;
209}
210
211#endif
212
213/***************************************
214 * Fixed bit length Encode
215 ***************************************/
216
217/**
218 * Function: armPackBits
219 *
220 * Description:
221 * Pack a VLC code word into the bitstream
222 *
223 * Remarks:
224 *
225 * Parameters:
226 * [in] ppBitStream     pointer to the pointer to the current byte
227 *                      in the bit stream.
228 * [in] pOffset         pointer to the bit position in the byte
229 *                      pointed by *ppBitStream. Valid within 0
230 *                      to 7.
231 * [in] codeWord        Code word that need to be inserted in to the
232 *                          bitstream
233 * [in] codeLength      Length of the code word valid range 1...32
234 *
235 * [out] ppBitStream    *ppBitStream is updated after the block is encoded,
236 *                          so that it points to the current byte in the bit
237 *                          stream buffer.
238 * [out] pBitOffset     *pBitOffset is updated so that it points to the
239 *                          current bit position in the byte pointed by
240 *                          *ppBitStream.
241 *
242 * Return Value:
243 * Standard OMX_RESULT result. See enumeration for possible result codes.
244 *
245 */
246
247OMXResult armPackBits (
248    OMX_U8  **ppBitStream,
249    OMX_INT *pOffset,
250    OMX_U32 codeWord,
251    OMX_INT codeLength
252)
253{
254    OMX_U8  *pBitStream = *ppBitStream;
255    OMX_INT Offset = *pOffset;
256    OMX_U32 Value;
257
258    /* checking argument validity */
259    armRetArgErrIf(Offset < 0, OMX_Sts_BadArgErr);
260    armRetArgErrIf(Offset > 7, OMX_Sts_BadArgErr);
261    armRetArgErrIf(codeLength < 1, OMX_Sts_BadArgErr);
262    armRetArgErrIf(codeLength > 32, OMX_Sts_BadArgErr);
263
264    /* Prepare the first byte */
265    codeWord = codeWord << (32-codeLength);
266    Value = (pBitStream[0] >> (8-Offset)) << (8-Offset);
267    Value = Value | (codeWord >> (24+Offset));
268
269    /* Write out whole bytes */
270    while (8-Offset <= codeLength)
271    {
272        *pBitStream++ = (OMX_U8)Value;
273        codeWord   = codeWord  << (8-Offset);
274        codeLength = codeLength - (8-Offset);
275        Offset = 0;
276        Value = codeWord >> 24;
277    }
278
279    /* Write out final partial byte */
280    *pBitStream  = (OMX_U8)Value;
281    *ppBitStream = pBitStream;
282    *pOffset = Offset + codeLength;
283
284    return  OMX_Sts_NoErr;
285}
286
287/***************************************
288 * Variable bit length Encode
289 ***************************************/
290
291/**
292 * Function: armPackVLC32
293 *
294 * Description:
295 * Pack a VLC code word into the bitstream
296 *
297 * Remarks:
298 *
299 * Parameters:
300 * [in]	ppBitStream		pointer to the pointer to the current byte
301 *                      in the bit stream.
302 * [in]	pBitOffset	    pointer to the bit position in the byte
303 *                      pointed by *ppBitStream. Valid within 0
304 *                      to 7.
305 * [in]	 code     		VLC code word that need to be inserted in to the
306 *                      bitstream
307 *
308 * [out] ppBitStream	*ppBitStream is updated after the block is encoded,
309 *	                    so that it points to the current byte in the bit
310 *						stream buffer.
311 * [out] pBitOffset		*pBitOffset is updated so that it points to the
312 *						current bit position in the byte pointed by
313 *						*ppBitStream.
314 *
315 * Return Value:
316 * Standard OMX_RESULT result. See enumeration for possible result codes.
317 *
318 */
319
320OMXResult armPackVLC32 (
321    OMX_U8 **ppBitStream,
322    OMX_INT *pBitOffset,
323    ARM_VLC32 code
324)
325{
326    return (armPackBits(ppBitStream, pBitOffset, code.codeWord, code.codeLen));
327}
328
329/*End of File*/
330