/* ///////////////////////////////////////////////////////////////////////
//
//               INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in accordance with the terms of that agreement.
//        Copyright (c) 2008 Intel Corporation. All Rights Reserved.
//
//  Description: Parses VC-1 picture layer for progressive P picture in simple
//  or main profile bitstream.
//
*/

#include "vc1parse.h"

/*------------------------------------------------------------------------------
 * Parse picture layer.  This function parses progressive P picture for simple
 * or main profile bitstream.  This parser starts after PTYPE was parsed but
 * stops before parsing of macroblock layer.
 * Table 19 of SMPTE 421M after processing up to PTYPE for P picture.
 *------------------------------------------------------------------------------
 */

vc1_Status vc1_ParsePictureHeader_ProgressivePpicture(void* ctxt, vc1_Info *pInfo)
{
    uint8_t bit_count;
    const uint8_t *table;
    uint32_t tempValue;
    vc1_Status status = VC1_STATUS_OK;
    vc1_metadata_t *md = &pInfo->metadata;
    vc1_PictureLayerHeader *picLayerHeader = &pInfo->picLayerHeader;

    /* rounding control is implied for simple and main profile, SMPTE 421M 8.3.7.
       It toggles back and forth between 0 and 1 for P frames */
    if (md->PROFILE != VC1_PROFILE_ADVANCED)
    {
        picLayerHeader->RNDCTRL = md->RNDCTRL ^ 1 ;
        md->RNDCTRL = picLayerHeader->RNDCTRL;
    }

    VC1_GET_BITS9(5, picLayerHeader->PQINDEX);
    if ((status = vc1_CalculatePQuant(pInfo)) != VC1_STATUS_OK)
        return status;

    if (picLayerHeader->PQINDEX <= 8)
    {
        VC1_GET_BITS9(1, picLayerHeader->HALFQP);
    }
    else picLayerHeader->HALFQP=0;

    if (md->QUANTIZER == 1)
    {
        VC1_GET_BITS9(1, picLayerHeader->PQUANTIZER);
        picLayerHeader->UniformQuant = picLayerHeader->PQUANTIZER;
    }

    /* MVRANGE. */
    if ((status = vc1_MVRangeDecode(ctxt, pInfo)) != VC1_STATUS_OK)
        return status;

    if (md->MULTIRES == 1)
        VC1_GET_BITS9(2, tempValue); /* RESPIC. */

    if (picLayerHeader->PQUANT > 12)
        table = VC1_MVMODE_LOW_TBL;
    else
        table = VC1_MVMODE_HIGH_TBL;

    bit_count = 0;
    VC1_GET_BITS9(1, picLayerHeader->MVMODE);
    while ((picLayerHeader->MVMODE == 0) && (bit_count < 3))
    {
        VC1_GET_BITS9(1, picLayerHeader->MVMODE);
        bit_count++;
    }
    if (bit_count == 3)
        bit_count += picLayerHeader->MVMODE;
    picLayerHeader->MVMODE = table[bit_count];

    if (picLayerHeader->MVMODE == VC1_MVMODE_INTENSCOMP)
    {
        bit_count = 0;
        VC1_GET_BITS9(1, picLayerHeader->MVMODE2);
        while ((picLayerHeader->MVMODE2 == 0) && (bit_count < 2))
        {
            VC1_GET_BITS9(1, picLayerHeader->MVMODE2);
            bit_count++;
        }
        if (bit_count == 2 && picLayerHeader->MVMODE2 == 0)
            bit_count++;
        picLayerHeader->MVMODE2 = table[bit_count];
        VC1_GET_BITS9(6, picLayerHeader->LUMSCALE);
        VC1_GET_BITS9(6, picLayerHeader->LUMSHIFT);
    }
    else
        picLayerHeader->MVMODE2 = 0;

    if ((picLayerHeader->MVMODE == VC1_MVMODE_MIXED_MV) ||
            ((picLayerHeader->MVMODE == VC1_MVMODE_INTENSCOMP) &&
             (picLayerHeader->MVMODE2 == VC1_MVMODE_MIXED_MV)))
    {
        if ((status = vc1_DecodeBitplane(ctxt, pInfo,
                                         md->widthMB, md->heightMB, BPP_MVTYPEMB))
                != VC1_STATUS_OK)
        {
            return status;
        }
    }

    if ((status = vc1_DecodeBitplane(ctxt, pInfo,
                                     md->widthMB, md->heightMB, BPP_SKIPMB)) != VC1_STATUS_OK)
    {
        return status;
    }

    VC1_GET_BITS9(2, picLayerHeader->MVTAB);
    VC1_GET_BITS9(2, picLayerHeader->CBPTAB);

    if ((status = vc1_VOPDQuant(ctxt, pInfo)) != VC1_STATUS_OK)
        return status;

    if (md->VSTRANSFORM == 1)
    {
        VC1_GET_BITS9(1, picLayerHeader->TTMBF);
        if (picLayerHeader->TTMBF == 1)
        {
            VC1_GET_BITS9(2, picLayerHeader->TTFRM);
        }
    }

    VC1_GET_BITS9(1, picLayerHeader->TRANSACFRM);
    if (picLayerHeader->TRANSACFRM == 1)
    {
        VC1_GET_BITS9(1, picLayerHeader->TRANSACFRM);
        picLayerHeader->TRANSACFRM += 2;
    }

    VC1_GET_BITS9(1, picLayerHeader->TRANSDCTAB);

    /* Skip parsing of macroblock layer. */

    return status;
}

