/*
 ** 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"


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;

  /*   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);
}
