biariencode.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:9k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2. ***********************************************************************
  3. * COPYRIGHT AND WARRANTY INFORMATION
  4. *
  5. * Copyright 2001, International Telecommunications Union, Geneva
  6. *
  7. * DISCLAIMER OF WARRANTY
  8. *
  9. * These software programs are available to the user without any
  10. * license fee or royalty on an "as is" basis. The ITU disclaims
  11. * any and all warranties, whether express, implied, or
  12. * statutory, including any implied warranties of merchantability
  13. * or of fitness for a particular purpose.  In no event shall the
  14. * contributor or the ITU be liable for any incidental, punitive, or
  15. * consequential damages of any kind whatsoever arising from the
  16. * use of these programs.
  17. *
  18. * This disclaimer of warranty extends to the user of these programs
  19. * and user's customers, employees, agents, transferees, successors,
  20. * and assigns.
  21. *
  22. * The ITU does not represent or warrant that the programs furnished
  23. * hereunder are free of infringement of any third-party patents.
  24. * Commercial implementations of ITU-T Recommendations, including
  25. * shareware, may be subject to royalty fees to patent holders.
  26. * Information regarding the ITU-T patent policy is available from
  27. * the ITU Web site at http://www.itu.int.
  28. *
  29. * THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY.
  30. ************************************************************************
  31. */
  32. /*!
  33.  *************************************************************************************
  34.  * file biariencode.c
  35.  *
  36.  * brief
  37.  *    Routines for binary arithmetic encoding
  38.  * author
  39.  *    Main contributors (see contributors.h for copyright, address and affiliation details)
  40.  *    - Detlev Marpe                    <marpe@hhi.de>
  41.  *    - Gabi Blaettermann               <blaetter@hhi.de>
  42.  *************************************************************************************
  43.  */
  44. #include <stdlib.h>
  45. #include <math.h>
  46. #include "global.h"
  47. #include "biariencode.h"
  48. /*!
  49.  ************************************************************************
  50.  * Macro for writing bytes of code
  51.  ***********************************************************************
  52.  */
  53. #define put_byte() { 
  54.                      Ecodestrm[(*Ecodestrm_len)++] = Ebuffer; 
  55.                      Ebits_to_go = 8; 
  56.                     }
  57. /*!
  58.  ************************************************************************
  59.  * brief
  60.  *    Allocates memory for the EncodingEnvironment struct
  61.  ************************************************************************
  62.  */
  63. EncodingEnvironmentPtr arienco_create_encoding_environment()
  64. {
  65.   EncodingEnvironmentPtr eep;
  66.   if ( (eep = (EncodingEnvironmentPtr) calloc(1,sizeof(EncodingEnvironment))) == NULL)
  67.     no_mem_exit("arienco_create_encoding_environment: eep");
  68.   return eep;
  69. }
  70. /*!
  71.  ************************************************************************
  72.  * brief
  73.  *    Frees memory of the EncodingEnvironment struct
  74.  ************************************************************************
  75.  */
  76. void arienco_delete_encoding_environment(EncodingEnvironmentPtr eep)
  77. {
  78.   if (eep == NULL)
  79.   {
  80.     snprintf(errortext, ET_SIZE, "Error freeing eep (NULL pointer)");
  81.     error (errortext, 200);
  82.   }
  83.   else
  84.     free(eep);
  85. }
  86. /*!
  87.  ************************************************************************
  88.  * brief
  89.  *    Initializes the EncodingEnvironment for the arithmetic coder
  90.  ************************************************************************
  91.  */
  92. void arienco_start_encoding(EncodingEnvironmentPtr eep,
  93.                             unsigned char *code_buffer,
  94.                             int *code_len )
  95. {
  96.   Elow = 0;
  97.   Ehigh = TOP_VALUE;
  98.   Ebits_to_follow = 0;
  99.   Ebuffer = 0;
  100.   Ebits_to_go = 8;
  101.   Ecodestrm = code_buffer;
  102.   Ecodestrm_len = code_len;
  103. }
  104. /*!
  105.  ************************************************************************
  106.  * brief
  107.  *    Returns the number of currently written bits
  108.  ************************************************************************
  109.  */
  110. int arienco_bits_written(EncodingEnvironmentPtr eep)
  111. {
  112.    return (8 * (*Ecodestrm_len) + Ebits_to_follow + 8 + 2 - Ebits_to_go);
  113. }
  114. /*!
  115.  ************************************************************************
  116.  * brief
  117.  *    Terminates the arithmetic coder and writes the trailing bits
  118.  ************************************************************************
  119.  */
  120. void arienco_done_encoding(EncodingEnvironmentPtr eep)
  121. {
  122.   Ebits_to_follow ++;
  123.   if (Elow < FIRST_QTR)                 // output_bit(0)
  124.   {
  125.     Ebuffer >>= 1;
  126.     if (--Ebits_to_go == 0)
  127.       put_byte();
  128.     while (Ebits_to_follow > 0)
  129.     {
  130.       Ebuffer >>= 1;
  131.       Ebuffer |= 0x80;
  132.       if (--Ebits_to_go == 0)
  133.         put_byte();
  134.       Ebits_to_follow--;
  135.     }
  136.   }
  137.   else                                 // output_bit(1)
  138.   {
  139.     Ebuffer >>= 1;
  140.     Ebuffer |= 0x80;
  141.     if (--Ebits_to_go == 0)
  142.       put_byte();
  143.     while (Ebits_to_follow > 0)
  144.     {
  145.       Ebuffer >>= 1;
  146.       if (--Ebits_to_go == 0)
  147.         put_byte();
  148.       Ebits_to_follow--;
  149.     }
  150.   }
  151.   if (Ebits_to_go != 8)
  152.     Ecodestrm[(*Ecodestrm_len)++] = (Ebuffer >> Ebits_to_go);
  153. }
  154. /*!
  155.  ************************************************************************
  156.  * brief
  157.  *    Actually arithmetic encoding of one binary symbol by using
  158.  *    the symbol counts of its associated context model
  159.  ************************************************************************
  160.  */
  161. void biari_encode_symbol(EncodingEnvironmentPtr eep, signed short symbol, BiContextTypePtr bi_ct )
  162. {
  163.   int Elow_m1 = Elow - 1;
  164.   if( symbol != 0)
  165.   {
  166. #if AAC_FRAC_TABLE
  167.     Ehigh = Elow_m1 + ( ( ( Ehigh - Elow_m1 ) *
  168.             ((bi_ct->cum_freq[1]*ARITH_CUM_FREQ_TABLE[bi_ct->cum_freq[0]])>>16))>>10);
  169. #else
  170.     Ehigh = Elow_m1 + ( ( Ehigh - Elow_m1 ) * bi_ct->cum_freq[1]) / bi_ct->cum_freq[0];
  171. #endif
  172.     bi_ct->cum_freq[1]++;
  173.   }
  174.   else
  175.   {
  176. #if AAC_FRAC_TABLE
  177.     Elow += ((( Ehigh - Elow_m1 )  * ((bi_ct->cum_freq[1]*ARITH_CUM_FREQ_TABLE[bi_ct->cum_freq[0]])>>16))>>10);
  178. #else
  179.     Elow += ( ( Ehigh - Elow_m1 ) * bi_ct->cum_freq[1]) / bi_ct->cum_freq[0];
  180. #endif
  181.   }
  182.   if (++bi_ct->cum_freq[0] >= bi_ct->max_cum_freq)
  183.     rescale_cum_freq(bi_ct);
  184.   do
  185.   {
  186.     if (Ehigh < HALF)  // output_bit(0)
  187.     {
  188.       Ebuffer >>= 1;
  189.       if (--Ebits_to_go == 0)
  190.         put_byte();
  191.       while (Ebits_to_follow > 0)
  192.       {
  193.         Ebits_to_follow--;
  194.         Ebuffer >>= 1;
  195.         Ebuffer |= 0x80;
  196.         if (--Ebits_to_go == 0)
  197.           put_byte();
  198.       }
  199.     }
  200.     else
  201.       if (Elow >= HALF)  // output_bit(1)
  202.       {
  203.         Ebuffer >>= 1;
  204.         Ebuffer |= 0x80;
  205.         if (--Ebits_to_go == 0)
  206.           put_byte();
  207.         while (Ebits_to_follow > 0)
  208.         {
  209.           Ebits_to_follow--;
  210.           Ebuffer >>= 1;
  211.           if (--Ebits_to_go == 0)
  212.             put_byte();
  213.         }
  214.         Ehigh -= HALF;
  215.         Elow -= HALF;
  216.       }
  217.       else
  218.         if (Elow >= FIRST_QTR && Ehigh < THIRD_QTR)
  219.         {
  220.           Ebits_to_follow++;
  221.           Ehigh -= FIRST_QTR;
  222.           Elow -= FIRST_QTR;
  223.         }
  224.         else
  225.           break;
  226.         Elow <<= 1;
  227.         Ehigh += Ehigh+1;
  228.   }
  229.   while (1);
  230. }
  231. /*!
  232.  ************************************************************************
  233.  * brief
  234.  *    Initializes a given context with some pre-defined probabilities
  235.  *    and a maximum symbol count for triggering the rescaling
  236.  ************************************************************************
  237.  */
  238. void biari_init_context( BiContextTypePtr ctx, int ini_count_0, int ini_count_1, int max_cum_freq )
  239. {
  240.   ctx->in_use       = TRUE;
  241.   ctx->max_cum_freq = max_cum_freq;
  242.   ctx->cum_freq[1]  = ini_count_1;
  243.   ctx->cum_freq[0]  = ini_count_0 + ini_count_1;
  244. }
  245. /*!
  246.  ************************************************************************
  247.  * brief
  248.  *    Copies the content (symbol counts) of a given context
  249.  ************************************************************************
  250.  */
  251. void biari_copy_context( BiContextTypePtr ctx_orig, BiContextTypePtr ctx_dest )
  252. {
  253.   ctx_dest->in_use     =  ctx_orig->in_use;
  254.   ctx_dest->max_cum_freq = ctx_orig->max_cum_freq;
  255.   ctx_dest->cum_freq[1] = ctx_orig->cum_freq[1];
  256.   ctx_dest->cum_freq[0] = ctx_orig->cum_freq[0];
  257. }
  258. /*!
  259.  ************************************************************************
  260.  * brief
  261.  *    Prints the content (symbol counts) of a given context model
  262.  ************************************************************************
  263.  */
  264. void biari_print_context( BiContextTypePtr ctx )
  265. {
  266.   printf("0: %4dt",ctx->cum_freq[0] - ctx->cum_freq[1]);
  267.   printf("1: %4d",ctx->cum_freq[1]);
  268. }
  269. /*!
  270.  ************************************************************************
  271.  * brief
  272.  *    Rescales a given context model by halvening the symbol counts
  273.  ************************************************************************
  274.  */
  275. void rescale_cum_freq( BiContextTypePtr   bi_ct)
  276. {
  277.   int old_cum_freq_of_one = bi_ct->cum_freq[1];
  278.   bi_ct->cum_freq[1] = (bi_ct->cum_freq[1] + 1) >> 1;
  279.   bi_ct->cum_freq[0] = bi_ct->cum_freq[1] +
  280.                          ( ( bi_ct->cum_freq[0] - old_cum_freq_of_one + 1 ) >> 1);
  281. }