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

