⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 biaridecod.c

📁 h.264/avc 视频编码程序,实现分数像素匹配功能,非原创.
💻 C
字号:
/*
***********************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2001, International Telecommunications Union, Geneva
*
* DISCLAIMER OF WARRANTY
*
* These software programs are available to the user without any
* license fee or royalty on an "as is" basis. The ITU disclaims
* any and all warranties, whether express, implied, or
* statutory, including any implied warranties of merchantability
* or of fitness for a particular purpose.  In no event shall the
* contributor or the ITU be liable for any incidental, punitive, or
* consequential damages of any kind whatsoever arising from the
* use of these programs.
*
* This disclaimer of warranty extends to the user of these programs
* and user's customers, employees, agents, transferees, successors,
* and assigns.
*
* The ITU does not represent or warrant that the programs furnished
* hereunder are free of infringement of any third-party patents.
* Commercial implementations of ITU-T Recommendations, including
* shareware, may be subject to royalty fees to patent holders.
* Information regarding the ITU-T patent policy is available from
* the ITU Web site at http://www.itu.int.
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY.
************************************************************************
*/

/*!
 *************************************************************************************
 * \file biaridecod.c
 *
 * \brief
 *    binary arithmetic decoder routines
 * \date
 *    21. Oct 2000
 * \author
 *    Main contributors (see contributors.h for copyright, address and affiliation details)
 *    - Detlev Marpe                    <marpe@hhi.de>
 *    - Gabi Blaettermann               <blaetter@hhi.de>
 *************************************************************************************
 */

#include <stdlib.h>
#include <math.h>
#include "global.h"
#include "biaridecod.h"
#include "memalloc.h"

extern int symbolCount;

/************************************************************************
 * M a c r o s
 ************************************************************************
 */

#define get_byte(){                                                     \
            Dbuffer = Dcodestrm[(*Dcodestrm_len)++];        \
                        Dbits_to_go = 7;                                \
          }


/************************************************************************
 ************************************************************************
                      init / exit decoder
 ************************************************************************
 ************************************************************************/


/*!
 ************************************************************************
 * \brief
 *    Allocates memory for the DecodingEnvironment struct
 * \return DecodingContextPtr
 *    allocated memory
 ************************************************************************
 */
DecodingEnvironmentPtr arideco_create_decoding_environment()
{
  DecodingEnvironmentPtr dep;

  if ((dep = calloc(1,sizeof(DecodingEnvironment))) == NULL)
    no_mem_exit("arideco_create_decoding_environment: dep");
  return dep;
}


/*!
 ***********************************************************************
 * \brief
 *    Frees memory of the DecodingEnvironment struct
 ***********************************************************************
 */
void arideco_delete_decoding_environment(DecodingEnvironmentPtr dep)
{
  if (dep == NULL)
  {
    snprintf(errortext, ET_SIZE, "Error freeing dep (NULL pointer)");
    error (errortext, 200);
  }
  else
    free(dep);
}


/*!
 ************************************************************************
 * \brief
 *    Initializes the DecodingEnvironment for the arithmetic coder
 ************************************************************************
 */
void arideco_start_decoding(DecodingEnvironmentPtr dep, unsigned char *cpixcode,
                            int firstbyte, int *cpixcode_len )
{
  int i;
  int bits;
  bits = B_BITS;

  Dcodestrm = cpixcode;
  Dcodestrm_len = cpixcode_len;
  *Dcodestrm_len = firstbyte;

  Dbits_to_go = 0;
  dep->Dvalue = 0;

  for (i = 0; i < bits; i++)
  {
    if (--Dbits_to_go < 0)
      get_byte();
    dep->Dvalue += dep->Dvalue  + (Dbuffer & 1);
    Dbuffer >>= 1;
  }
  dep->Dlow = 0;

  /* Only necessary for new AC */
  dep->Drange = CACM99_HALF;
}


/*!
 ************************************************************************
 * \brief
 *    arideco_bits_read
 ************************************************************************
 */
int arideco_bits_read(DecodingEnvironmentPtr dep)
{
  return 8 * ((*Dcodestrm_len)-1) + (8 - Dbits_to_go) - CODE_VALUE_BITS;
}


/*!
 ************************************************************************
 * \brief
 *    arideco_done_decoding():
 ************************************************************************
 */
void arideco_done_decoding(DecodingEnvironmentPtr dep)
{
  (*Dcodestrm_len)++;
}



/*!
 ************************************************************************
 * \brief
 *    biari_decode_symbol():
 * \return
 *    the decoded symbol
 ************************************************************************
 */
unsigned int biari_decode_symbol(DecodingEnvironmentPtr dep, BiContextTypePtr bi_ct )
{
  int bit;
  register unsigned int range, value;

  range = dep->Drange;
  value = dep->Dvalue;

  /* scope LPS, cLPS, rLPS, rMPS, and in_r */
  {
    int LPS;
    unsigned int cLPS, rLPS, rMPS;
    unsigned int in_r;

    /* scope c0 and c1 */
    {
      register unsigned short c0, c1, one_over_c0;

      one_over_c0 = ARITH_CUM_FREQ_TABLE[bi_ct->cum_freq[0]]>>10;
      c0 = bi_ct->cum_freq[0]-bi_ct->cum_freq[1];
      c1 = bi_ct->cum_freq[1];

      /* Unit interval size */
#if  AAC_FRAC_TABLE
      in_r = ((range*one_over_c0)>>16);   
#else
      in_r = range / (c0+c1);
#endif

      /* Determine LPS and cLPS. This should compile to conditional moves. */
      LPS = (c0 <  c1) ? 0 : 1;
      cLPS = (c0 < c1) ? c0 : c1;

    }

    /* Size of interval for LPS */
    rLPS = in_r * cLPS;
    rMPS = range - rLPS;
    /* Always set LPS interval at upper end of range. This always allocates the 
     * excess probabilty caused by the truncation during division to the MPS. 
     * Check if value lies in this upper end, if so, then bit is LPS otherwise 
     * bit is MPS */
    if (value >= rMPS) 
    {
      bit = LPS;
      value -= rMPS;
      range = rLPS;
    } 
    else 
    {
      bit = !(LPS);
      range -= rLPS;
    }
  }
  
  /* Increase model frequency counts appropriately */
  bi_ct->cum_freq[1] += bit;

  if (++bi_ct->cum_freq[0] >= bi_ct->max_cum_freq) 
    rescale_cum_freq(bi_ct);


  /* Renormalise when range <= 1/4 of max frequency count to maintain precise 
   * division of code space, minimizing loss of compression effectiveness. 
   * The idea is to prevent underflow, i.e. when the scaling operation 
   * maps different symbols of the model onto the same integer. The (low, high) 
   * pair can lie between:
   * - [0, 1/2) 
   * - [1/2, top) 
   * - [1/4, 3/4) 
   * The (low, high) pair can only become close together when they straddle 1/2 
   * (3rd case). We know unambiguously what to output if the (low,high) pair 
   * are, at the smallest:
   * - [1/4,1/2+epsilon)
   * - [1/2-epsilon,3/4)
   * This range is <= 1/4 of the max frequency count, hence we can (should) rescale 
   * at this time, i.e. when range <= 1/4
   */
  while (range <= CACM99_QUARTER)
  {
    /* Double range and value */
    range <<= 1;
    if (--Dbits_to_go < 0) 
    {
      get_byte();
    }
    /* Shift in next bit and add to value */
    value <<= 1;
    value += (Dbuffer & 1);
    Dbuffer >>= 1;   
  }
  
  dep->Drange = range;
  dep->Dvalue = value;

  return(bit);
}



/*!
 ************************************************************************
 * \brief
 *    Initializes a given context with some pre-defined probabilities
 *    and a maximum symbol count for triggering the rescaling
 ************************************************************************
 */
void biari_init_context( BiContextTypePtr ctx, int ini_count_0, int ini_count_1, int max_cum_freq )
{

  ctx->in_use       = TRUE;
  ctx->max_cum_freq = max_cum_freq;


  ctx->cum_freq[1]  = ini_count_1;
  ctx->cum_freq[0]  = ini_count_0 + ini_count_1;

}


/*!
 ************************************************************************
 * \brief
 *    biari_copy_context():
 ************************************************************************
 */
void biari_copy_context( BiContextTypePtr ctx_orig, BiContextTypePtr ctx_dest )
{
  ctx_dest->in_use     =  ctx_orig->in_use;
  ctx_dest->max_cum_freq = ctx_orig->max_cum_freq;

  ctx_dest->cum_freq[1] = ctx_orig->cum_freq[1];
  ctx_dest->cum_freq[0] = ctx_orig->cum_freq[0];

  return;
}

/*!
 ***********************************************************************
 * \brief
 *    biari_print_context():
 ***********************************************************************
 */
void biari_print_context( BiContextTypePtr ctx )
{
  printf("0: %4d\t",ctx->cum_freq[0] - ctx->cum_freq[1]);
  printf("1: %4d",ctx->cum_freq[1]);

  return;
}


/*!
 ***********************************************************************
 * \brief
 *    Rescales a given context model by halvening the symbol counts
 *
 ***********************************************************************
 */
void rescale_cum_freq( BiContextTypePtr   bi_ct)
{
  int old_cum_freq_of_one = bi_ct->cum_freq[1];

  bi_ct->cum_freq[1] = (bi_ct->cum_freq[1] + 1) >> 1;
  bi_ct->cum_freq[0] = bi_ct->cum_freq[1] +
    ( ( bi_ct->cum_freq[0] - old_cum_freq_of_one + 1 ) >> 1);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -