1/**
2 *
3 * File Name:  omxVCM4P2_EncodeVLCZigzag_IntraDCVLC.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 * Description:
13 * Contains modules for zigzag scanning and VLC encoding
14 * for intra block.
15 *
16 */
17
18#include "omxtypes.h"
19#include "armOMX.h"
20#include "omxVC.h"
21
22#include "armVC.h"
23#include "armCOMM_Bitstream.h"
24#include "armCOMM.h"
25#include "armVCM4P2_Huff_Tables_VLC.h"
26#include "armVCM4P2_ZigZag_Tables.h"
27
28
29
30/**
31 * Function:  omxVCM4P2_EncodeVLCZigzag_IntraDCVLC   (6.2.4.5.2)
32 *
33 * Description:
34 * Performs zigzag scan and VLC encoding of AC and DC coefficients for one
35 * intra block.  Two versions of the function (DCVLC and ACVLC) are provided
36 * in order to support the two different methods of processing DC
37 * coefficients, as described in [ISO14496-2], subclause 7.4.1.4, "Intra DC
38 * Coefficient Decoding for the Case of Switched VLC Encoding".
39 *
40 * Input Arguments:
41 *
42 *   ppBitStream - double pointer to the current byte in the bitstream
43 *   pBitOffset - pointer to the bit position in the byte pointed by
44 *            *ppBitStream. Valid within 0 to 7.
45 *   pQDctBlkCoef - pointer to the quantized DCT coefficient
46 *   predDir - AC prediction direction, which is used to decide the zigzag
47 *            scan pattern; takes one of the following values:
48 *            -  OMX_VC_NONE - AC prediction not used.
49 *                             Performs classical zigzag scan.
50 *            -  OMX_VC_HORIZONTAL - Horizontal prediction.
51 *                             Performs alternate-vertical zigzag scan.
52 *            -  OMX_VC_VERTICAL - Vertical prediction.
53 *                             Performs alternate-horizontal zigzag scan.
54 *   pattern - block pattern which is used to decide whether this block is
55 *            encoded
56 *   shortVideoHeader - binary flag indicating presence of
57 *            short_video_header; escape modes 0-3 are used if
58 *            shortVideoHeader==0, and escape mode 4 is used when
59 *            shortVideoHeader==1.
60 *   videoComp - video component type (luminance, chrominance) of the current
61 *            block
62 *
63 * Output Arguments:
64 *
65 *   ppBitStream - *ppBitStream is updated after the block is encoded, so
66 *            that it points to the current byte in the bit stream buffer.
67 *   pBitOffset - *pBitOffset is updated so that it points to the current bit
68 *            position in the byte pointed by *ppBitStream.
69 *
70 * Return Value:
71 *
72 *    OMX_Sts_NoErr - no error
73 *    OMX_Sts_BadArgErr - Bad arguments:
74 *    -    At least one of the following pointers is NULL: ppBitStream,
75 *              *ppBitStream, pBitOffset, pQDctBlkCoef.
76 *    -   *pBitOffset < 0, or *pBitOffset >7.
77 *    -    PredDir is not one of: OMX_VC_NONE, OMX_VC_HORIZONTAL, or
78 *         OMX_VC_VERTICAL.
79 *    -    VideoComp is not one component of enum OMXVCM4P2VideoComponent.
80 *
81 */
82
83OMXResult omxVCM4P2_EncodeVLCZigzag_IntraDCVLC(
84     OMX_U8 **ppBitStream,
85     OMX_INT *pBitOffset,
86     const OMX_S16 *pQDctBlkCoef,
87     OMX_U8 predDir,
88     OMX_U8 pattern,
89     OMX_INT shortVideoHeader,
90     OMXVCM4P2VideoComponent videoComp
91)
92{
93    OMX_S16 dcValue, powOfSize;
94    OMX_U8  DCValueSize, start = 1;
95    OMX_U16 absDCValue;
96
97    /* Argument error checks */
98    armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr);
99    armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr);
100    armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr);
101    armRetArgErrIf(pQDctBlkCoef == NULL, OMX_Sts_BadArgErr);
102    armRetArgErrIf((*pBitOffset < 0) || (*pBitOffset >7), OMX_Sts_BadArgErr);
103	armRetArgErrIf((videoComp != OMX_VC_LUMINANCE) && (videoComp != OMX_VC_CHROMINANCE), OMX_Sts_BadArgErr);
104	armRetArgErrIf((predDir != OMX_VC_NONE) && (predDir != OMX_VC_HORIZONTAL) && (predDir != OMX_VC_VERTICAL) , OMX_Sts_BadArgErr);
105
106    if (pattern)
107    {
108        dcValue = pQDctBlkCoef[0];
109        absDCValue = armAbs(dcValue);
110
111        /* Find the size */
112        DCValueSize = armLogSize (absDCValue);
113        absDCValue = armAbs(dcValue);
114
115        /* Insert the code into the bitstream */
116        if (videoComp == OMX_VC_LUMINANCE)
117        {
118
119            armPackVLC32 (ppBitStream, pBitOffset,
120                          armVCM4P2_aIntraDCLumaIndex[DCValueSize]);
121        }
122        else if (videoComp == OMX_VC_CHROMINANCE)
123        {
124
125            armPackVLC32 (ppBitStream, pBitOffset,
126                          armVCM4P2_aIntraDCChromaIndex[DCValueSize]);
127        }
128
129        /* Additional code generation in case of negative
130           dc value the additional */
131        if (DCValueSize > 0)
132        {
133            if (dcValue < 0)
134            {
135                /* calulate 2 pow */
136                powOfSize = (1 << DCValueSize);
137
138                absDCValue =  absDCValue ^ (powOfSize - 1);
139            }
140            armPackBits(ppBitStream, pBitOffset, (OMX_U32)absDCValue, \
141                        DCValueSize);
142
143            if (DCValueSize > 8)
144            {
145                armPackBits(ppBitStream, pBitOffset, 1, 1);
146            }
147        }
148    }
149
150    return armVCM4P2_EncodeVLCZigzag_Intra(
151                ppBitStream,
152                pBitOffset,
153                pQDctBlkCoef,
154                predDir,
155                pattern,
156                shortVideoHeader,
157                start);
158}
159
160/* End of file */
161