/*
 * Copyright (C) 2007-2008 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
/* ----------------------------------------------------------------
 *
 * 
 * File Name:  armVCM4P10_DecodeCoeffsToPair.c
 * OpenMAX DL: v1.0.2
 * Revision:   9641
 * Date:       Thursday, February 7, 2008
 * 
 * 
 * 
 * 
 * H.264 decode coefficients module
 * 
 */
 
#ifdef DEBUG_ARMVCM4P10_DECODECOEFFSTOPAIR
#undef DEBUG_ON
#define DEBUG_ON
#endif
 
#include "omxtypes.h"
#include "armOMX.h"
#include "omxVC.h"

#include "armCOMM.h"
#include "armCOMM_Bitstream.h"
#include "armVCM4P10_CAVLCTables.h"

/* 4x4 DeZigZag table */

static const OMX_U8 armVCM4P10_ZigZag[16] =
{
    0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
};

/*
 * Description:
 * This function perform the work required by the OpenMAX
 * DecodeCoeffsToPair function and DecodeChromaDCCoeffsToPair.
 * Since most of the code is common we share it here.
 *
 * Parameters:
 * [in]	ppBitStream		Double pointer to current byte in bit stream buffer
 * [in]	pOffset			Pointer to current bit position in the byte pointed
 *								to by *ppBitStream
 * [in]	sMaxNumCoeff	Maximum number of non-zero coefficients in current
 *								block (4,15 or 16)
 * [in]	nTable          Table number (0 to 4) according to the five columns
 *                      of Table 9-5 in the H.264 spec
 * [out]	ppBitStream		*ppBitStream is updated after each block is decoded
 * [out]	pOffset			*pOffset is updated after each block is decoded
 * [out]	pNumCoeff		Pointer to the number of nonzero coefficients in
 *								this block
 * [out]	ppPosCoefbuf	Double pointer to destination residual
 *								coefficient-position pair buffer
 * Return Value:
 * Standard omxError result. See enumeration for possible result codes.

 */

OMXResult armVCM4P10_DecodeCoeffsToPair(
     const OMX_U8** ppBitStream,
     OMX_S32* pOffset,
     OMX_U8* pNumCoeff,
     OMX_U8  **ppPosCoefbuf,
     OMX_INT nTable,
     OMX_INT sMaxNumCoeff        
 )
{
    int CoeffToken, TotalCoeff, TrailingOnes;
    int Level, LevelCode, LevelPrefix, LevelSuffix, LevelSuffixSize;
    int SuffixLength, Run, ZerosLeft,CoeffNum;
    int i, Flags;
    OMX_U8 *pPosCoefbuf = *ppPosCoefbuf;
    OMX_S16 pLevel[16];
    OMX_U8  pRun[16];

    CoeffToken = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCCoeffTokenTables[nTable]);
    armRetDataErrIf(CoeffToken == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err);

    TrailingOnes = armVCM4P10_CAVLCTrailingOnes[CoeffToken];
    TotalCoeff   = armVCM4P10_CAVLCTotalCoeff[CoeffToken];
    *pNumCoeff   = (OMX_U8)TotalCoeff;

    DEBUG_PRINTF_2("TotalCoeff = %d, TrailingOnes = %d\n", TotalCoeff, TrailingOnes);

    if (TotalCoeff == 0)
    {
        /* Nothing to do */
        return OMX_Sts_NoErr;
    }

    /* Decode trailing ones */
    for (i=TotalCoeff-1; i>=TotalCoeff-TrailingOnes; i--)
    {
        if (armGetBits(ppBitStream, pOffset, 1))
        {
            Level = -1;
        }
        else
        {
            Level = +1;
        }
        pLevel[i] = (OMX_S16)Level;

        DEBUG_PRINTF_2("Level[%d] = %d\n", i, pLevel[i]);
    }

    /* Decode (non zero) level values */
    SuffixLength = 0;
    if (TotalCoeff>10 && TrailingOnes<3)
    {
        SuffixLength=1;
    }
    for ( ; i>=0; i--)
    {
        LevelPrefix = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCLevelPrefix);
        armRetDataErrIf(LevelPrefix == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err);

        LevelSuffixSize = SuffixLength;
        if (LevelPrefix==14 && SuffixLength==0)
        {
            LevelSuffixSize = 4;
        }
        if (LevelPrefix==15)
        {
            LevelSuffixSize = 12;
        }
        
        LevelSuffix = 0;
        if (LevelSuffixSize > 0)
        {
            LevelSuffix = armGetBits(ppBitStream, pOffset, LevelSuffixSize);
        }

        LevelCode = (LevelPrefix << SuffixLength) + LevelSuffix;


        if (LevelPrefix==15 && SuffixLength==0)
        {
            LevelCode += 15;
        }

        /* LevelCode = 2*(magnitude-1) + sign */

        if (i==TotalCoeff-1-TrailingOnes && TrailingOnes<3)
        {
            /* Level magnitude can't be 1 */
            LevelCode += 2;
        }
        if (LevelCode & 1)
        {
            /* 2a+1 maps to -a-1 */
            Level = (-LevelCode-1)>>1;
        }
        else
        {
            /* 2a+0 maps to +a+1 */
            Level = (LevelCode+2)>>1;
        }
        pLevel[i] = (OMX_S16)Level;

        DEBUG_PRINTF_2("Level[%d] = %d\n", i, pLevel[i]);

        if (SuffixLength==0)
        {
            SuffixLength=1;
        }
        if ( ((LevelCode>>1)+1)>(3<<(SuffixLength-1)) && SuffixLength<6 )
        {
            SuffixLength++;
        }
    }

    /* Decode run values */
    ZerosLeft = 0;
    if (TotalCoeff < sMaxNumCoeff)
    {
        /* Decode TotalZeros VLC */
        if (sMaxNumCoeff==4)
        {
            ZerosLeft = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCTotalZeros2x2Tables[TotalCoeff-1]);
            armRetDataErrIf(ZerosLeft ==ARM_NO_CODEBOOK_INDEX , OMX_Sts_Err);
        }
        else
        {
            ZerosLeft = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCTotalZeroTables[TotalCoeff-1]);
             armRetDataErrIf(ZerosLeft ==ARM_NO_CODEBOOK_INDEX , OMX_Sts_Err);
	    }
    }

    DEBUG_PRINTF_1("TotalZeros = %d\n", ZerosLeft);

	CoeffNum=ZerosLeft+TotalCoeff-1;

    for (i=TotalCoeff-1; i>0; i--)
    {
        Run = 0;
        if (ZerosLeft > 0)
        {
            int Table = ZerosLeft;
            if (Table > 6)
            {
                Table = 7;
            }
            Run = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCRunBeforeTables[Table-1]);
            armRetDataErrIf(Run == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err);
        }
        pRun[i] = (OMX_U8)Run;

        DEBUG_PRINTF_2("Run[%d] = %d\n", i, pRun[i]);

        ZerosLeft -= Run;
    }
    pRun[0] = (OMX_U8)ZerosLeft;

    DEBUG_PRINTF_1("Run[0] = %d\n", pRun[i]);


    /* Fill in coefficients */
	    
    if (sMaxNumCoeff==15)
    {
        CoeffNum++; /* Skip the DC position */
    }
	
	/*for (i=0;i<TotalCoeff;i++)
		CoeffNum += pRun[i]+1;*/
    
	for (i=(TotalCoeff-1); i>=0; i--)
    {
        /*CoeffNum += pRun[i]+1;*/
        Level     = pLevel[i];

        DEBUG_PRINTF_2("Coef[%d] = %d\n", CoeffNum, Level);

        Flags = CoeffNum;
		CoeffNum -= (pRun[i]+1);
        if (sMaxNumCoeff>4)
        {
            /* Perform 4x4 DeZigZag */
            Flags = armVCM4P10_ZigZag[Flags];
        }
        if (i==0)
        {   
            /* End of block flag */
            Flags += 0x20;
        }
        if (Level<-128 || Level>127)
        {
            /* Overflow flag */
            Flags += 0x10;
        }
        
        *pPosCoefbuf++ = (OMX_U8)(Flags);
        *pPosCoefbuf++ = (OMX_U8)(Level & 0xFF);
        if (Flags & 0x10)
        {
            *pPosCoefbuf++ = (OMX_U8)(Level>>8);
        }
    }

    *ppPosCoefbuf = pPosCoefbuf;

    return OMX_Sts_NoErr;
}
