1/*
2 * Copyright (C) 2007-2008 ARM Limited
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17/**
18 *
19 * File Name:  omxVCM4P2_QuantIntra_I.c
20 * OpenMAX DL: v1.0.2
21 * Revision:   9641
22 * Date:       Thursday, February 7, 2008
23 *
24 *
25 *
26 *
27 * Description:
28 * Contains modules for intra Quantization
29 *
30 */
31
32#include "omxtypes.h"
33#include "armOMX.h"
34#include "omxVC.h"
35
36#include "armCOMM.h"
37/**
38 * Function:  omxVCM4P2_QuantIntra_I   (6.2.4.4.2)
39 *
40 * Description:
41 * Performs quantization on intra block coefficients. This function supports
42 * bits_per_pixel == 8.
43 *
44 * Input Arguments:
45 *
46 *   pSrcDst - pointer to the input intra block coefficients; must be aligned
47 *            on a 16-byte boundary.
48 *   QP - quantization parameter (quantizer_scale).
49 *   blockIndex - block index indicating the component type and position,
50 *            valid in the range 0 to 5, as defined in [ISO14496-2], subclause
51 *            6.1.3.8.
52 *   shortVideoHeader - binary flag indicating presence of
53 *            short_video_header; shortVideoHeader==1 selects linear intra DC
54 *            mode, and shortVideoHeader==0 selects non linear intra DC mode.
55 *
56 * Output Arguments:
57 *
58 *   pSrcDst - pointer to the output (quantized) interblock coefficients.
59 *            When shortVideoHeader==1, AC coefficients are saturated on the
60 *            interval [-127, 127], and DC coefficients are saturated on the
61 *            interval [1, 254].  When shortVideoHeader==0, AC coefficients
62 *            are saturated on the interval [-2047, 2047].
63 *
64 * Return Value:
65 *
66 *    OMX_Sts_NoErr - no error
67 *    OMX_Sts_BadArgErr - bad arguments:
68 *    -    pSrcDst is NULL.
69 *    -    blockIndex < 0 or blockIndex >= 10
70 *    -    QP <= 0 or QP >= 32.
71 *
72 */
73
74OMXResult omxVCM4P2_QuantIntra_I(
75     OMX_S16 * pSrcDst,
76     OMX_U8 QP,
77     OMX_INT blockIndex,
78	 OMX_INT shortVideoHeader
79 )
80{
81
82    /* Definitions and Initializations*/
83    /* Initialized to remove compilation error */
84    OMX_INT dcScaler = 0, coeffCount,fSign;
85    OMX_INT maxClpAC, minClpAC;
86
87    /* Argument error checks */
88    armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr);
89    armRetArgErrIf(((blockIndex < 0) || (blockIndex >= 10)), OMX_Sts_BadArgErr);
90    armRetArgErrIf(((QP <= 0) || (QP >= 32)), OMX_Sts_BadArgErr);
91   /* One argument check is delayed until we have ascertained that  */
92   /* pQMatrix is not NULL.                                         */
93
94
95    /* Set the Clip Range based on SVH on/off */
96    if(shortVideoHeader == 1)
97    {
98        maxClpAC = 127;
99        minClpAC = -127;
100        dcScaler = 8;
101        /* Dequant the DC value, this applies to both the methods */
102        pSrcDst[0] = armIntDivAwayFromZero (pSrcDst[0], dcScaler);
103
104        /* Clip between 1 and 254 */
105        pSrcDst[0] = (OMX_S16) armClip (1, 254, pSrcDst[0]);
106    }
107    else
108    {
109        maxClpAC = 2047;
110        minClpAC = -2047;
111        /* Calculate the DC scaler value */
112        if ((blockIndex  < 4) || (blockIndex  > 5))
113        {
114            if (QP >= 1 && QP <= 4)
115            {
116                dcScaler = 8;
117            }
118            else if (QP >= 5 && QP <= 8)
119            {
120                dcScaler = 2 * QP;
121            }
122            else if (QP >= 9 && QP <= 24)
123            {
124                dcScaler = QP + 8;
125            }
126            else
127            {
128                dcScaler = (2 * QP) - 16;
129            }
130        }
131        else if (blockIndex < 6)
132        {
133            if (QP >= 1 && QP <= 4)
134            {
135                dcScaler = 8;
136            }
137            else if (QP >= 5 && QP <= 24)
138            {
139                dcScaler = (QP + 13)/2;
140            }
141            else
142            {
143                dcScaler = QP - 6;
144            }
145        }
146
147        /* Dequant the DC value, this applies to both the methods */
148        pSrcDst[0] = armIntDivAwayFromZero (pSrcDst[0], dcScaler);
149    }
150
151    /* Second Inverse quantisation method */
152    for (coeffCount = 1; coeffCount < 64; coeffCount++)
153    {
154        fSign =  armSignCheck (pSrcDst[coeffCount]);
155        pSrcDst[coeffCount] = armAbs(pSrcDst[coeffCount])/(2 * QP);
156        pSrcDst[coeffCount] *= fSign;
157
158        /* Clip */
159        pSrcDst[coeffCount] =
160        (OMX_S16) armClip (minClpAC, maxClpAC, pSrcDst[coeffCount]);
161    }
162    return OMX_Sts_NoErr;
163
164}
165
166/* End of file */
167
168
169