/*
 ** 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:		dyn_bits.c

	Content:	Noiseless coder module functions

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

#include "aac_rom.h"
#include "dyn_bits.h"
#include "bit_cnt.h"
#include "psy_const.h"

/*****************************************************************************
*
* function name: buildBitLookUp
* description:  count bits using all possible tables
*
*****************************************************************************/
static void
buildBitLookUp(const Word16 *quantSpectrum,
               const Word16 maxSfb,
               const Word16 *sfbOffset,
               const UWord16 *sfbMax,
               Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
               SECTION_INFO * sectionInfo)
{
  Word32 i;

  for (i=0; i<maxSfb; i++) {
    Word16 sfbWidth, maxVal;

    sectionInfo[i].sfbCnt = 1;
    sectionInfo[i].sfbStart = i;
    sectionInfo[i].sectionBits = INVALID_BITCOUNT;
    sectionInfo[i].codeBook = -1;
    sfbWidth = sfbOffset[i + 1] - sfbOffset[i];
    maxVal = sfbMax[i];
    bitCount(quantSpectrum + sfbOffset[i], sfbWidth, maxVal, bitLookUp[i]);
  }
}


/*****************************************************************************
*
* function name: findBestBook
* description:  essential helper functions
*
*****************************************************************************/
static Word16
findBestBook(const Word16 *bc, Word16 *book)
{
  Word32 minBits, j;
  minBits = INVALID_BITCOUNT;

  for (j=0; j<=CODE_BOOK_ESC_NDX; j++) {

    if (bc[j] < minBits) {
      minBits = bc[j];
      *book = j;
    }
  }
  return extract_l(minBits);
}

static Word16
findMinMergeBits(const Word16 *bc1, const Word16 *bc2)
{
  Word32 minBits, j, sum;
  minBits = INVALID_BITCOUNT;

  for (j=0; j<=CODE_BOOK_ESC_NDX; j++) {
    sum = bc1[j] + bc2[j];
    if (sum < minBits) {
      minBits = sum;
    }
  }
  return extract_l(minBits);
}

static void
mergeBitLookUp(Word16 *bc1, const Word16 *bc2)
{
  Word32 j;

  for (j=0; j<=CODE_BOOK_ESC_NDX; j++) {
    bc1[j] = min(bc1[j] + bc2[j], INVALID_BITCOUNT);
  }
}

static Word16
findMaxMerge(const Word16 mergeGainLookUp[MAX_SFB_LONG],
             const SECTION_INFO *sectionInfo,
             const Word16 maxSfb, Word16 *maxNdx)
{
  Word32 i, maxMergeGain;
  maxMergeGain = 0;

  for (i=0; i+sectionInfo[i].sfbCnt < maxSfb; i += sectionInfo[i].sfbCnt) {

    if (mergeGainLookUp[i] > maxMergeGain) {
      maxMergeGain = mergeGainLookUp[i];
      *maxNdx = i;
    }
  }
  return extract_l(maxMergeGain);
}



static Word16
CalcMergeGain(const SECTION_INFO *sectionInfo,
              Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
              const Word16 *sideInfoTab,
              const Word16 ndx1,
              const Word16 ndx2)
{
  Word32 SplitBits;
  Word32 MergeBits;
  Word32 MergeGain;

  /*
    Bit amount for splitted sections
  */
  SplitBits = sectionInfo[ndx1].sectionBits + sectionInfo[ndx2].sectionBits;

  MergeBits = sideInfoTab[sectionInfo[ndx1].sfbCnt + sectionInfo[ndx2].sfbCnt] +
                  findMinMergeBits(bitLookUp[ndx1], bitLookUp[ndx2]);
  MergeGain = (SplitBits - MergeBits);

  return extract_l(MergeGain);
}

/*
  sectioning Stage 0:find minimum codbooks
*/

static void
gmStage0(SECTION_INFO * sectionInfo,
         Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
         const Word16 maxSfb)
{
  Word32 i;

  for (i=0; i<maxSfb; i++) {
    /* Side-Info bits will be calculated in Stage 1!  */

    if (sectionInfo[i].sectionBits == INVALID_BITCOUNT) {
      sectionInfo[i].sectionBits = findBestBook(bitLookUp[i], &(sectionInfo[i].codeBook));
    }
  }
}

/*
  sectioning Stage 1:merge all connected regions with the same code book and
  calculate side info
*/

static void
gmStage1(SECTION_INFO * sectionInfo,
         Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
         const Word16 maxSfb,
         const Word16 *sideInfoTab)
{
  SECTION_INFO * sectionInfo_s;
  SECTION_INFO * sectionInfo_e;
  Word32 mergeStart, mergeEnd;
  mergeStart = 0;

  do {

    sectionInfo_s = sectionInfo + mergeStart;
	for (mergeEnd=mergeStart+1; mergeEnd<maxSfb; mergeEnd++) {
      sectionInfo_e = sectionInfo + mergeEnd;
      if (sectionInfo_s->codeBook != sectionInfo_e->codeBook)
        break;
      sectionInfo_s->sfbCnt += 1;
      sectionInfo_s->sectionBits += sectionInfo_e->sectionBits;

      mergeBitLookUp(bitLookUp[mergeStart], bitLookUp[mergeEnd]);
    }

    sectionInfo_s->sectionBits += sideInfoTab[sectionInfo_s->sfbCnt];
    sectionInfo[mergeEnd - 1].sfbStart = sectionInfo_s->sfbStart;      /* speed up prev search */

    mergeStart = mergeEnd;


  } while (mergeStart - maxSfb < 0);
}

/*
  sectioning Stage 2:greedy merge algorithm, merge connected sections with
  maximum bit gain until no more gain is possible
*/
static void
gmStage2(SECTION_INFO *sectionInfo,
         Word16 mergeGainLookUp[MAX_SFB_LONG],
         Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
         const Word16 maxSfb,
         const Word16 *sideInfoTab)
{
  Word16 i;

  for (i=0; i+sectionInfo[i].sfbCnt<maxSfb; i+=sectionInfo[i].sfbCnt) {
    mergeGainLookUp[i] = CalcMergeGain(sectionInfo,
                                       bitLookUp,
                                       sideInfoTab,
                                       i,
                                       (i + sectionInfo[i].sfbCnt));
  }

  while (TRUE) {
    Word16 maxMergeGain, maxNdx = 0, maxNdxNext, maxNdxLast;

    maxMergeGain = findMaxMerge(mergeGainLookUp, sectionInfo, maxSfb, &maxNdx);


    if (maxMergeGain <= 0)
      break;


    maxNdxNext = maxNdx + sectionInfo[maxNdx].sfbCnt;

    sectionInfo[maxNdx].sfbCnt = sectionInfo[maxNdx].sfbCnt + sectionInfo[maxNdxNext].sfbCnt;
    sectionInfo[maxNdx].sectionBits = sectionInfo[maxNdx].sectionBits +
                                          (sectionInfo[maxNdxNext].sectionBits - maxMergeGain);


    mergeBitLookUp(bitLookUp[maxNdx], bitLookUp[maxNdxNext]);


    if (maxNdx != 0) {
      maxNdxLast = sectionInfo[maxNdx - 1].sfbStart;
      mergeGainLookUp[maxNdxLast] = CalcMergeGain(sectionInfo,
                                                  bitLookUp,
                                                  sideInfoTab,
                                                  maxNdxLast,
                                                  maxNdx);
    }
    maxNdxNext = maxNdx + sectionInfo[maxNdx].sfbCnt;

    sectionInfo[maxNdxNext - 1].sfbStart = sectionInfo[maxNdx].sfbStart;


    if (maxNdxNext - maxSfb < 0) {
      mergeGainLookUp[maxNdx] = CalcMergeGain(sectionInfo,
                                              bitLookUp,
                                              sideInfoTab,
                                              maxNdx,
                                              maxNdxNext);
    }
  }
}

/*
  count bits used by the noiseless coder
*/
static void
noiselessCounter(SECTION_DATA *sectionData,
                 Word16 mergeGainLookUp[MAX_SFB_LONG],
                 Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
                 const Word16 *quantSpectrum,
                 const UWord16 *maxValueInSfb,
                 const Word16 *sfbOffset,
                 const Word32 blockType)
{
  Word32 grpNdx, i;
  const Word16 *sideInfoTab = NULL;
  SECTION_INFO *sectionInfo;

  /*
    use appropriate side info table
  */
  switch (blockType)
  {
    case LONG_WINDOW:
    case START_WINDOW:
    case STOP_WINDOW:
      sideInfoTab = sideInfoTabLong;
      break;
    case SHORT_WINDOW:
      sideInfoTab = sideInfoTabShort;
      break;
  }


  sectionData->noOfSections = 0;
  sectionData->huffmanBits = 0;
  sectionData->sideInfoBits = 0;


  if (sectionData->maxSfbPerGroup == 0)
    return;

  /*
    loop trough groups
  */
  for (grpNdx=0; grpNdx<sectionData->sfbCnt; grpNdx+=sectionData->sfbPerGroup) {

    sectionInfo = sectionData->sectionInfo + sectionData->noOfSections;

    buildBitLookUp(quantSpectrum,
                   sectionData->maxSfbPerGroup,
                   sfbOffset + grpNdx,
                   maxValueInSfb + grpNdx,
                   bitLookUp,
                   sectionInfo);

    /*
       0.Stage
    */
    gmStage0(sectionInfo, bitLookUp, sectionData->maxSfbPerGroup);

    /*
       1.Stage
    */
    gmStage1(sectionInfo, bitLookUp, sectionData->maxSfbPerGroup, sideInfoTab);


    /*
       2.Stage
    */
    gmStage2(sectionInfo,
             mergeGainLookUp,
             bitLookUp,
             sectionData->maxSfbPerGroup,
             sideInfoTab);


    /*
       compress output, calculate total huff and side bits
    */
    for (i=0; i<sectionData->maxSfbPerGroup; i+=sectionInfo[i].sfbCnt) {
      findBestBook(bitLookUp[i], &(sectionInfo[i].codeBook));
      sectionInfo[i].sfbStart = sectionInfo[i].sfbStart + grpNdx;

      sectionData->huffmanBits = (sectionData->huffmanBits +
                                     (sectionInfo[i].sectionBits - sideInfoTab[sectionInfo[i].sfbCnt]));
      sectionData->sideInfoBits = (sectionData->sideInfoBits + sideInfoTab[sectionInfo[i].sfbCnt]);
      sectionData->sectionInfo[sectionData->noOfSections] = sectionInfo[i];
      sectionData->noOfSections = sectionData->noOfSections + 1;
    }
  }
}


/*******************************************************************************
*
* functionname: scfCount
* returns     : ---
* description : count bits used by scalefactors.
*
********************************************************************************/
static void scfCount(const Word16 *scalefacGain,
                     const UWord16 *maxValueInSfb,
                     SECTION_DATA * sectionData)

{
  SECTION_INFO *psectionInfo;
  SECTION_INFO *psectionInfom;

  /* counter */
  Word32 i = 0; /* section counter */
  Word32 j = 0; /* sfb counter */
  Word32 k = 0; /* current section auxiliary counter */
  Word32 m = 0; /* other section auxiliary counter */
  Word32 n = 0; /* other sfb auxiliary counter */

  /* further variables */
  Word32 lastValScf     = 0;
  Word32 deltaScf       = 0;
  Flag found            = 0;
  Word32 scfSkipCounter = 0;


  sectionData->scalefacBits = 0;


  if (scalefacGain == NULL) {
    return;
  }

  lastValScf = 0;
  sectionData->firstScf = 0;

  psectionInfo = sectionData->sectionInfo;
  for (i=0; i<sectionData->noOfSections; i++) {

    if (psectionInfo->codeBook != CODE_BOOK_ZERO_NO) {
      sectionData->firstScf = psectionInfo->sfbStart;
      lastValScf = scalefacGain[sectionData->firstScf];
      break;
    }
	psectionInfo += 1;
  }

  psectionInfo = sectionData->sectionInfo;
  for (i=0; i<sectionData->noOfSections; i++, psectionInfo += 1) {

    if (psectionInfo->codeBook != CODE_BOOK_ZERO_NO
        && psectionInfo->codeBook != CODE_BOOK_PNS_NO) {
      for (j = psectionInfo->sfbStart;
           j < (psectionInfo->sfbStart + psectionInfo->sfbCnt); j++) {
        /* check if we can repeat the last value to save bits */

        if (maxValueInSfb[j] == 0) {
          found = 0;

          if (scfSkipCounter == 0) {
            /* end of section */

            if (j - ((psectionInfo->sfbStart + psectionInfo->sfbCnt) - 1) == 0) {
              found = 0;
            }
            else {
              for (k = j + 1; k < psectionInfo->sfbStart + psectionInfo->sfbCnt; k++) {

                if (maxValueInSfb[k] != 0) {
                  int tmp = L_abs(scalefacGain[k] - lastValScf);
				  found = 1;

                  if ( tmp < CODE_BOOK_SCF_LAV) {
                    /* save bits */
                    deltaScf = 0;
                  }
                  else {
                    /* do not save bits */
                    deltaScf = lastValScf - scalefacGain[j];
                    lastValScf = scalefacGain[j];
                    scfSkipCounter = 0;
                  }
                  break;
                }
                /* count scalefactor skip */
                scfSkipCounter = scfSkipCounter + 1;
              }
            }

			psectionInfom = psectionInfo + 1;
            /* search for the next maxValueInSfb[] != 0 in all other sections */
            for (m = i + 1; (m < sectionData->noOfSections) && (found == 0); m++) {

              if ((psectionInfom->codeBook != CODE_BOOK_ZERO_NO) &&
                  (psectionInfom->codeBook != CODE_BOOK_PNS_NO)) {
                for (n = psectionInfom->sfbStart;
                     n < (psectionInfom->sfbStart + psectionInfom->sfbCnt); n++) {

                  if (maxValueInSfb[n] != 0) {
                    found = 1;

                    if ( (abs_s(scalefacGain[n] - lastValScf) < CODE_BOOK_SCF_LAV)) {
                      deltaScf = 0;
                    }
                    else {
                      deltaScf = (lastValScf - scalefacGain[j]);
                      lastValScf = scalefacGain[j];
                      scfSkipCounter = 0;
                    }
                    break;
                  }
                  /* count scalefactor skip */
                  scfSkipCounter = scfSkipCounter + 1;
                }
              }

			  psectionInfom += 1;
            }

            if (found == 0) {
              deltaScf = 0;
              scfSkipCounter = 0;
            }
          }
          else {
            deltaScf = 0;
            scfSkipCounter = scfSkipCounter - 1;
          }
        }
        else {
          deltaScf = lastValScf - scalefacGain[j];
          lastValScf = scalefacGain[j];
        }
        sectionData->scalefacBits += bitCountScalefactorDelta(deltaScf);
      }
    }
  }
}


typedef Word16 (*lookUpTable)[CODE_BOOK_ESC_NDX + 1];


Word16
dynBitCount(const Word16  *quantSpectrum,
            const UWord16 *maxValueInSfb,
            const Word16  *scalefac,
            const Word16   blockType,
            const Word16   sfbCnt,
            const Word16   maxSfbPerGroup,
            const Word16   sfbPerGroup,
            const Word16  *sfbOffset,
            SECTION_DATA  *sectionData)
{
  sectionData->blockType      = blockType;
  sectionData->sfbCnt         = sfbCnt;
  sectionData->sfbPerGroup    = sfbPerGroup;
  if(sfbPerGroup)
	sectionData->noOfGroups   = sfbCnt/sfbPerGroup;
  else
	sectionData->noOfGroups   = 0x7fff;
  sectionData->maxSfbPerGroup = maxSfbPerGroup;

  noiselessCounter(sectionData,
                   sectionData->mergeGainLookUp,
                   (lookUpTable)sectionData->bitLookUp,
                   quantSpectrum,
                   maxValueInSfb,
                   sfbOffset,
                   blockType);

  scfCount(scalefac,
           maxValueInSfb,
           sectionData);


  return (sectionData->huffmanBits + sectionData->sideInfoBits +
	      sectionData->scalefacBits);
}

