/*
 ** Copyright 2003-2010, VisualOn, Inc.
 **
 ** 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:		bitenc.c

	Content:	Bitstream encoder functions

*******************************************************************************/

#include "bitenc.h"
#include "bit_cnt.h"
#include "dyn_bits.h"
#include "qc_data.h"
#include "interface.h"

#define UNUSED(x) (void)(x)

static const  Word16 globalGainOffset = 100;
static const  Word16 icsReservedBit   = 0;


/*****************************************************************************
*
* function name: encodeSpectralData
* description:  encode spectral data
* returns:      spectral bits used
*
*****************************************************************************/
static Word32 encodeSpectralData(Word16             *sfbOffset,
                                 SECTION_DATA       *sectionData,
                                 Word16             *quantSpectrum,
                                 HANDLE_BIT_BUF      hBitStream)
{
  Word16 i,sfb;
  Word16 dbgVal;
  SECTION_INFO* psectioninfo;
  dbgVal = GetBitsAvail(hBitStream);

  for(i=0; i<sectionData->noOfSections; i++) {
    psectioninfo = &(sectionData->sectionInfo[i]);
	/*
       huffencode spectral data for this section
    */
    for(sfb=psectioninfo->sfbStart;
        sfb<psectioninfo->sfbStart+psectioninfo->sfbCnt;
        sfb++) {
      codeValues(quantSpectrum+sfbOffset[sfb],
                 sfbOffset[sfb+1] - sfbOffset[sfb],
                 psectioninfo->codeBook,
                 hBitStream);
    }
  }

  return(GetBitsAvail(hBitStream)-dbgVal);
}

/*****************************************************************************
*
* function name:encodeGlobalGain
* description: encodes Global Gain (common scale factor)
* returns:     none
*
*****************************************************************************/
static void encodeGlobalGain(Word16 globalGain,
                             Word16 logNorm,
                             Word16 scalefac,
                             HANDLE_BIT_BUF hBitStream)
{
  WriteBits(hBitStream, ((globalGain - scalefac) + globalGainOffset-(logNorm << 2)), 8);
}


/*****************************************************************************
*
* function name:encodeIcsInfo
* description: encodes Ics Info
* returns:     none
*
*****************************************************************************/

static void encodeIcsInfo(Word16 blockType,
                          Word16 windowShape,
                          Word16 groupingMask,
                          SECTION_DATA *sectionData,
                          HANDLE_BIT_BUF  hBitStream)
{
  WriteBits(hBitStream,icsReservedBit,1);
  WriteBits(hBitStream,blockType,2);
  WriteBits(hBitStream,windowShape,1);


  switch(blockType){
    case LONG_WINDOW:
    case START_WINDOW:
    case STOP_WINDOW:
      WriteBits(hBitStream,sectionData->maxSfbPerGroup,6);

      /* No predictor data present */
      WriteBits(hBitStream, 0, 1);
      break;

    case SHORT_WINDOW:
      WriteBits(hBitStream,sectionData->maxSfbPerGroup,4);

      /*
      Write grouping bits
      */
      WriteBits(hBitStream,groupingMask,TRANS_FAC-1);
      break;
  }
}

/*****************************************************************************
*
* function name: encodeSectionData
* description:  encode section data (common Huffman codebooks for adjacent
*               SFB's)
* returns:      none
*
*****************************************************************************/
static Word32 encodeSectionData(SECTION_DATA *sectionData,
                                HANDLE_BIT_BUF hBitStream)
{
  Word16 sectEscapeVal=0,sectLenBits=0;
  Word16 sectLen;
  Word16 i;
  Word16 dbgVal=GetBitsAvail(hBitStream);



  switch(sectionData->blockType)
  {
    case LONG_WINDOW:
    case START_WINDOW:
    case STOP_WINDOW:
      sectEscapeVal = SECT_ESC_VAL_LONG;
      sectLenBits   = SECT_BITS_LONG;
      break;

    case SHORT_WINDOW:
      sectEscapeVal = SECT_ESC_VAL_SHORT;
      sectLenBits   = SECT_BITS_SHORT;
      break;
  }

  for(i=0;i<sectionData->noOfSections;i++) {
    WriteBits(hBitStream,sectionData->sectionInfo[i].codeBook,4);
    sectLen = sectionData->sectionInfo[i].sfbCnt;

    while(sectLen >= sectEscapeVal) {

      WriteBits(hBitStream,sectEscapeVal,sectLenBits);
      sectLen = sectLen - sectEscapeVal;
    }
    WriteBits(hBitStream,sectLen,sectLenBits);
  }
  return(GetBitsAvail(hBitStream)-dbgVal);
}

/*****************************************************************************
*
* function name: encodeScaleFactorData
* description:  encode DPCM coded scale factors
* returns:      none
*
*****************************************************************************/
static Word32 encodeScaleFactorData(UWord16        *maxValueInSfb,
                                    SECTION_DATA   *sectionData,
                                    Word16         *scalefac,
                                    HANDLE_BIT_BUF  hBitStream)
{
  Word16 i,j,lastValScf,deltaScf;
  Word16 dbgVal = GetBitsAvail(hBitStream);
  SECTION_INFO* psectioninfo;

  lastValScf=scalefac[sectionData->firstScf];

  for(i=0;i<sectionData->noOfSections;i++){
    psectioninfo = &(sectionData->sectionInfo[i]);
    if (psectioninfo->codeBook != CODE_BOOK_ZERO_NO){
      for (j=psectioninfo->sfbStart;
           j<psectioninfo->sfbStart+psectioninfo->sfbCnt; j++){

        if(maxValueInSfb[j] == 0) {
          deltaScf = 0;
        }
        else {
          deltaScf = lastValScf - scalefac[j];
          lastValScf = scalefac[j];
        }

        if(codeScalefactorDelta(deltaScf,hBitStream)){
          return(1);
        }
      }
    }

  }
  return(GetBitsAvail(hBitStream)-dbgVal);
}

/*****************************************************************************
*
* function name:encodeMsInfo
* description: encodes MS-Stereo Info
* returns:     none
*
*****************************************************************************/
static void encodeMSInfo(Word16          sfbCnt,
                         Word16          grpSfb,
                         Word16          maxSfb,
                         Word16          msDigest,
                         Word16         *jsFlags,
                         HANDLE_BIT_BUF  hBitStream)
{
  Word16 sfb, sfbOff;


  switch(msDigest)
  {
    case MS_NONE:
      WriteBits(hBitStream,SI_MS_MASK_NONE,2);
      break;

    case MS_ALL:
      WriteBits(hBitStream,SI_MS_MASK_ALL,2);
      break;

    case MS_SOME:
      WriteBits(hBitStream,SI_MS_MASK_SOME,2);
      for(sfbOff = 0; sfbOff < sfbCnt; sfbOff+=grpSfb) {
        for(sfb=0; sfb<maxSfb; sfb++) {

          if(jsFlags[sfbOff+sfb] & MS_ON) {
            WriteBits(hBitStream,1,1);
          }
          else{
            WriteBits(hBitStream,0,1);
          }
        }
      }
      break;
  }

}

/*****************************************************************************
*
* function name: encodeTnsData
* description:  encode TNS data (filter order, coeffs, ..)
* returns:      none
*
*****************************************************************************/
static void encodeTnsData(TNS_INFO tnsInfo,
                          Word16 blockType,
                          HANDLE_BIT_BUF hBitStream) {
  Word16 i,k;
  Flag tnsPresent;
  Word16 numOfWindows;
  Word16 coefBits;
  Flag isShort;


  if (blockType==2) {
    isShort = 1;
    numOfWindows = TRANS_FAC;
  }
  else {
    isShort = 0;
    numOfWindows = 1;
  }

  tnsPresent=0;
  for (i=0; i<numOfWindows; i++) {

    if (tnsInfo.tnsActive[i]) {
      tnsPresent=1;
    }
  }

  if (tnsPresent==0) {
    WriteBits(hBitStream,0,1);
  }
  else{ /* there is data to be written*/
    WriteBits(hBitStream,1,1); /*data_present */
    for (i=0; i<numOfWindows; i++) {

      WriteBits(hBitStream,tnsInfo.tnsActive[i],(isShort?1:2));

      if (tnsInfo.tnsActive[i]) {

        WriteBits(hBitStream,((tnsInfo.coefRes[i] - 4)==0?1:0),1);

        WriteBits(hBitStream,tnsInfo.length[i],(isShort?4:6));

        WriteBits(hBitStream,tnsInfo.order[i],(isShort?3:5));

        if (tnsInfo.order[i]){
          WriteBits(hBitStream, FILTER_DIRECTION, 1);

          if(tnsInfo.coefRes[i] == 4) {
            coefBits = 3;
            for(k=0; k<tnsInfo.order[i]; k++) {

              if (tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] > 3 ||
                  tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] < -4) {
                coefBits = 4;
                break;
              }
            }
          }
          else {
            coefBits = 2;
            for(k=0; k<tnsInfo.order[i]; k++) {

              if (tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] > 1 ||
                  tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] < -2) {
                coefBits = 3;
                break;
              }
            }
          }
          WriteBits(hBitStream, tnsInfo.coefRes[i] - coefBits, 1); /*coef_compres*/
          for (k=0; k<tnsInfo.order[i]; k++ ) {
            static const Word16 rmask[] = {0,1,3,7,15};

            WriteBits(hBitStream,tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] & rmask[coefBits],coefBits);
          }
        }
      }
    }
  }

}

/*****************************************************************************
*
* function name: encodeGainControlData
* description:  unsupported
* returns:      none
*
*****************************************************************************/
static void encodeGainControlData(HANDLE_BIT_BUF hBitStream)
{
  WriteBits(hBitStream,0,1);
}

/*****************************************************************************
*
* function name: encodePulseData
* description:  not supported yet (dummy)
* returns:      none
*
*****************************************************************************/
static void encodePulseData(HANDLE_BIT_BUF hBitStream)
{
  WriteBits(hBitStream,0,1);
}


/*****************************************************************************
*
* function name: WriteIndividualChannelStream
* description:  management of write process of individual channel stream
* returns:      none
*
*****************************************************************************/
static void
writeIndividualChannelStream(Flag   commonWindow,
                             Word16 mdctScale,
                             Word16 windowShape,
                             Word16 groupingMask,
                             Word16 *sfbOffset,
                             Word16 scf[],
                             UWord16 *maxValueInSfb,
                             Word16 globalGain,
                             Word16 quantSpec[],
                             SECTION_DATA *sectionData,
                             HANDLE_BIT_BUF hBitStream,
                             TNS_INFO tnsInfo)
{
  Word16 logNorm;

  logNorm = LOG_NORM_PCM - (mdctScale + 1);

  encodeGlobalGain(globalGain, logNorm,scf[sectionData->firstScf], hBitStream);


  if(!commonWindow) {
    encodeIcsInfo(sectionData->blockType, windowShape, groupingMask, sectionData, hBitStream);
  }

  encodeSectionData(sectionData, hBitStream);

  encodeScaleFactorData(maxValueInSfb,
                        sectionData,
                        scf,
                        hBitStream);

  encodePulseData(hBitStream);

  encodeTnsData(tnsInfo, sectionData->blockType, hBitStream);

  encodeGainControlData(hBitStream);

  encodeSpectralData(sfbOffset,
                     sectionData,
                     quantSpec,
                     hBitStream);

}

/*****************************************************************************
*
* function name: writeSingleChannelElement
* description:  write single channel element to bitstream
* returns:      none
*
*****************************************************************************/
static Word16 writeSingleChannelElement(Word16 instanceTag,
                                        Word16 *sfbOffset,
                                        QC_OUT_CHANNEL* qcOutChannel,
                                        HANDLE_BIT_BUF hBitStream,
                                        TNS_INFO tnsInfo)
{
  WriteBits(hBitStream,ID_SCE,3);
  WriteBits(hBitStream,instanceTag,4);
  writeIndividualChannelStream(0,
                               qcOutChannel->mdctScale,
                               qcOutChannel->windowShape,
                               qcOutChannel->groupingMask,
                               sfbOffset,
                               qcOutChannel->scf,
                               qcOutChannel->maxValueInSfb,
                               qcOutChannel->globalGain,
                               qcOutChannel->quantSpec,
                               &(qcOutChannel->sectionData),
                               hBitStream,
                               tnsInfo
                               );
  return(0);
}



/*****************************************************************************
*
* function name: writeChannelPairElement
* description:
* returns:      none
*
*****************************************************************************/
static Word16 writeChannelPairElement(Word16 instanceTag,
                                      Word16 msDigest,
                                      Word16 msFlags[MAX_GROUPED_SFB],
                                      Word16 *sfbOffset[2],
                                      QC_OUT_CHANNEL qcOutChannel[2],
                                      HANDLE_BIT_BUF hBitStream,
                                      TNS_INFO tnsInfo[2])
{
  WriteBits(hBitStream,ID_CPE,3);
  WriteBits(hBitStream,instanceTag,4);
  WriteBits(hBitStream,1,1); /* common window */

  encodeIcsInfo(qcOutChannel[0].sectionData.blockType,
                qcOutChannel[0].windowShape,
                qcOutChannel[0].groupingMask,
                &(qcOutChannel[0].sectionData),
                hBitStream);

  encodeMSInfo(qcOutChannel[0].sectionData.sfbCnt,
               qcOutChannel[0].sectionData.sfbPerGroup,
               qcOutChannel[0].sectionData.maxSfbPerGroup,
               msDigest,
               msFlags,
               hBitStream);

  writeIndividualChannelStream(1,
                               qcOutChannel[0].mdctScale,
                               qcOutChannel[0].windowShape,
                               qcOutChannel[0].groupingMask,
                               sfbOffset[0],
                               qcOutChannel[0].scf,
                               qcOutChannel[0].maxValueInSfb,
                               qcOutChannel[0].globalGain,
                               qcOutChannel[0].quantSpec,
                               &(qcOutChannel[0].sectionData),
                               hBitStream,
                               tnsInfo[0]);

  writeIndividualChannelStream(1,
                               qcOutChannel[1].mdctScale,
                               qcOutChannel[1].windowShape,
                               qcOutChannel[1].groupingMask,
                               sfbOffset[1],
                               qcOutChannel[1].scf,
                               qcOutChannel[1].maxValueInSfb,
                               qcOutChannel[1].globalGain,
                               qcOutChannel[1].quantSpec,
                               &(qcOutChannel[1].sectionData),
                               hBitStream,
                               tnsInfo[1]);

  return(0);
}



/*****************************************************************************
*
* function name: writeFillElement
* description:  write fill elements to bitstream
* returns:      none
*
*****************************************************************************/
static void writeFillElement( const UWord8 *ancBytes,
                              Word16 totFillBits,
                              HANDLE_BIT_BUF hBitStream)
{
  Word16 i;
  Word16 cnt,esc_count;

  /*
    Write fill Element(s):
    amount of a fill element can be 7+X*8 Bits, X element of [0..270]
  */

  while(totFillBits >= (3+4)) {
    cnt = min(((totFillBits - (3+4)) >> 3), ((1<<4)-1));

    WriteBits(hBitStream,ID_FIL,3);
    WriteBits(hBitStream,cnt,4);

    totFillBits = totFillBits - (3+4);


    if ((cnt == (1<<4)-1)) {

      esc_count = min( ((totFillBits >> 3) - ((1<<4)-1)), (1<<8)-1);
      WriteBits(hBitStream,esc_count,8);
      totFillBits = (totFillBits - 8);
      cnt = cnt + (esc_count - 1);
    }

    for(i=0;i<cnt;i++) {

      if(ancBytes)
        WriteBits(hBitStream, *ancBytes++,8);
      else
        WriteBits(hBitStream,0,8);
      totFillBits = totFillBits - 8;
    }
  }
}

/*****************************************************************************
*
* function name: WriteBitStream
* description:  main function of write bitsteam process
* returns:      0 if success
*
*****************************************************************************/
Word16 WriteBitstream (HANDLE_BIT_BUF hBitStream,
                       ELEMENT_INFO elInfo,
                       QC_OUT *qcOut,
                       PSY_OUT *psyOut,
                       Word16 *globUsedBits,
                       const UWord8 *ancBytes,
					   Word16 sampindex
                       ) /* returns error code */
{
  Word16 bitMarkUp;
  Word16 elementUsedBits;
  Word16 frameBits=0;

  UNUSED(ancBytes);

  /*   struct bitbuffer bsWriteCopy; */
  bitMarkUp = GetBitsAvail(hBitStream);
  if(qcOut->qcElement.adtsUsed)  /*  write adts header*/
  {
	  WriteBits(hBitStream, 0xFFF, 12); /* 12 bit Syncword */
	  WriteBits(hBitStream, 1, 1); /* ID == 0 for MPEG4 AAC, 1 for MPEG2 AAC */
	  WriteBits(hBitStream, 0, 2); /* layer == 0 */
	  WriteBits(hBitStream, 1, 1); /* protection absent */
	  WriteBits(hBitStream, 1, 2); /* profile */
	  WriteBits(hBitStream, sampindex, 4); /* sampling rate */
	  WriteBits(hBitStream, 0, 1); /* private bit */
	  WriteBits(hBitStream, elInfo.nChannelsInEl, 3); /* ch. config (must be > 0) */
								   /* simply using numChannels only works for
									6 channels or less, else a channel
									configuration should be written */
	  WriteBits(hBitStream, 0, 1); /* original/copy */
	  WriteBits(hBitStream, 0, 1); /* home */

	  /* Variable ADTS header */
	  WriteBits(hBitStream, 0, 1); /* copyr. id. bit */
	  WriteBits(hBitStream, 0, 1); /* copyr. id. start */
	  WriteBits(hBitStream, *globUsedBits >> 3, 13);
	  WriteBits(hBitStream, 0x7FF, 11); /* buffer fullness (0x7FF for VBR) */
	  WriteBits(hBitStream, 0, 2); /* raw data blocks (0+1=1) */
  }

  *globUsedBits=0;

  {

    Word16 *sfbOffset[2];
    TNS_INFO tnsInfo[2];
    elementUsedBits = 0;

    switch (elInfo.elType) {

      case ID_SCE:      /* single channel */
        sfbOffset[0] = psyOut->psyOutChannel[elInfo.ChannelIndex[0]].sfbOffsets;
        tnsInfo[0] = psyOut->psyOutChannel[elInfo.ChannelIndex[0]].tnsInfo;

        writeSingleChannelElement(elInfo.instanceTag,
                                  sfbOffset[0],
                                  &qcOut->qcChannel[elInfo.ChannelIndex[0]],
                                  hBitStream,
                                  tnsInfo[0]);
        break;

      case ID_CPE:     /* channel pair */
        {
          Word16 msDigest;
          Word16 *msFlags = psyOut->psyOutElement.toolsInfo.msMask;
          msDigest = psyOut->psyOutElement.toolsInfo.msDigest;
          sfbOffset[0] =
            psyOut->psyOutChannel[elInfo.ChannelIndex[0]].sfbOffsets;
          sfbOffset[1] =
            psyOut->psyOutChannel[elInfo.ChannelIndex[1]].sfbOffsets;

          tnsInfo[0]=
            psyOut->psyOutChannel[elInfo.ChannelIndex[0]].tnsInfo;
          tnsInfo[1]=
            psyOut->psyOutChannel[elInfo.ChannelIndex[1]].tnsInfo;
          writeChannelPairElement(elInfo.instanceTag,
                                  msDigest,
                                  msFlags,
                                  sfbOffset,
                                  &qcOut->qcChannel[elInfo.ChannelIndex[0]],
                                  hBitStream,
                                  tnsInfo);
        }
        break;

      default:
        return(1);

      }   /* switch */

    elementUsedBits = elementUsedBits - bitMarkUp;
    bitMarkUp = GetBitsAvail(hBitStream);
    frameBits = frameBits + elementUsedBits + bitMarkUp;

  }

  writeFillElement(NULL,
                   qcOut->totFillBits,
                   hBitStream);

  WriteBits(hBitStream,ID_END,3);

  /* byte alignement */
  WriteBits(hBitStream,0, (8 - (hBitStream->cntBits & 7)) & 7);

  *globUsedBits = *globUsedBits- bitMarkUp;
  bitMarkUp = GetBitsAvail(hBitStream);
  *globUsedBits = *globUsedBits + bitMarkUp;
  frameBits = frameBits + *globUsedBits;


  if (frameBits !=  (qcOut->totStaticBitsUsed+qcOut->totDynBitsUsed + qcOut->totAncBitsUsed +
                     qcOut->totFillBits + qcOut->alignBits)) {
    return(-1);
  }
  return(0);
}
