arith_codec.h
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:22k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2. *
  3. * $Id: arith_codec.h,v 1.2 2005/01/30 05:11:39 gabest Exp $ $Name:  $
  4. *
  5. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  6. *
  7. * The contents of this file are subject to the Mozilla Public License
  8. * Version 1.1 (the "License"); you may not use this file except in compliance
  9. * with the License. You may obtain a copy of the License at
  10. * http://www.mozilla.org/MPL/
  11. *
  12. * Software distributed under the License is distributed on an "AS IS" basis,
  13. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
  14. * the specific language governing rights and limitations under the License.
  15. *
  16. * The Original Code is BBC Research and Development m_code.
  17. *
  18. * The Initial Developer of the Original Code is the British Broadcasting
  19. * Corporation.
  20. * Portions created by the Initial Developer are Copyright (C) 2004.
  21. * All Rights Reserved.
  22. *
  23. * Contributor(s):    Richard Felton (Original Author),
  24.                     Thomas Davies,
  25.                     Scott R Ladd
  26. *
  27. * Alternatively, the contents of this file may be used under the terms of
  28. * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
  29. * Public License Version 2.1 (the "LGPL"), in which case the provisions of
  30. * the GPL or the LGPL are applicable instead of those above. If you wish to
  31. * allow use of your version of this file only under the terms of the either
  32. * the GPL or LGPL and not to allow others to use your version of this file
  33. * under the MPL, indicate your decision by deleting the provisions above
  34. * and replace them with the notice and other provisions required by the GPL
  35. * or LGPL. If you do not delete the provisions above, a recipient may use
  36. * your version of this file under the terms of any one of the MPL, the GPL
  37. * or the LGPL.
  38. * ***** END LICENSE BLOCK ***** */
  39. #ifndef _ARITH_CODEC_H_
  40. #define _ARITH_CODEC_H_
  41. /////////////////////////////////////////////////////////////////////////
  42. /////////////////////////////////////////////////////////////////////////
  43. ////                                                                 ////
  44. ////-----------Abstract binary arithmetic coding class---------------////
  45. ////subclass this for coding motion vectors, subband residues etc ...////
  46. ////                                                                 ////
  47. /////////////////////////////////////////////////////////////////////////
  48. /////////////////////////////////////////////////////////////////////////
  49. #include <libdirac_common/common.h>
  50. #include <libdirac_common/bit_manager.h>
  51. #include <vector>
  52. #ifdef _MSC_VER // define types for MSVC compiler on Windows
  53.     typedef unsigned short    uint16_t;
  54.     typedef unsigned _int32    uint32_t;
  55. #else // include header file for types for Linux
  56.     #include <inttypes.h>
  57. #endif
  58. namespace dirac
  59. {
  60.     //! Abstract binary arithmetic coding class
  61.     /*!
  62.         This is an abtract binary arithmetic encoding class, used as the base
  63.         for concrete classes that encode motion vectors and subband residues.
  64.         param        T        a container (most probably, or array) type
  65.      */
  66.     template<class T> //T is container/array type
  67.     class ArithCodec
  68.     {
  69.     public:
  70.         //! Constructor for encoding
  71.         /*!
  72.         Creates an ArithCodec object to decode input based on a set of 
  73.         parameters.
  74.             param        bits_out     output for encoded bits
  75.             param    number_of_contexts    the number of contexts used
  76.         */    
  77.         ArithCodec(BasicOutputManager * bits_out, size_t number_of_contexts);
  78.     
  79.         //! Constructor for decoding
  80.         /*!
  81.             Creates an ArithCodec object to decode input based on a set of 
  82.             parameters.
  83.             param    bits_in               source of bits to be decoded
  84.             param    number_of_contexts    the number of contexts used
  85.          */
  86.         ArithCodec(BitInputManager * bits_in, size_t number_of_contexts);
  87.     
  88.         //! Destructor
  89.         /*!
  90.             Destructor is virtual as this class is abstract.
  91.          */ 
  92.         virtual ~ArithCodec();
  93.     
  94.         //! Compresses the input and returns the number of bits written. 
  95.         /*!
  96.             Compress takes a type T object (a container or array) and 
  97.             compresses it using the abstract
  98.             function DoWorkCode() which is overridden in subclasses. 
  99.             It returns the number of bits written. 
  100.             param    in_data    the input to be compressed. Non-const, 
  101.                                  since the compression may be lossy.
  102.          */
  103.         int Compress(T & in_data);
  104.     
  105.         //! Decompresses the bitstream and writes into the output.
  106.         /*!
  107.             Decompresses the  bitstream, up to the number of bits specified 
  108.             and writes into the output
  109.     
  110.             subclasses.
  111.             param    out_data    the output into which the decompressed data 
  112.                                   is written.
  113.             param    num_bits    the number of bits to be read from the
  114.                                   bitstream. [May be eliminated in
  115.                                   future revisions. TJD 13 April 2004.]
  116.          */ 
  117.         void Decompress(T & out_data, int num_bits);
  118.     
  119.     protected:
  120.     
  121.         // use explicity type sizes for portability
  122.         typedef uint16_t code_t;
  123.         typedef uint32_t calc_t;
  124.     
  125.         // NOTE: These macros imply an unsigned 16-bit operand
  126.         static const code_t CODE_MAX     = 0xffff;
  127.         static const code_t CODE_MSB     = ((0xffff + 1) >> 1);
  128.         static const code_t CODE_2ND_MSB = ((0xffff + 1) >> 2);
  129.     
  130.         //! A class for encapsulating interval fractions for use in arithmetic coding.
  131.         /*!
  132.              A class for encapsulating a subinterval of the unit interval 
  133.              [0,1) (0<=x<1) as a start value, a stop value (numerators) 
  134.              and a weight value (the denominator). The interval is the to be
  135.              interpreted as [m_start/m_weight,m_stop/m_weight).
  136.          */
  137.         class Triple
  138.         {
  139.         public:
  140.             //! Constructor.
  141.             Triple()
  142.               : m_start(0),
  143.                 m_stop(0),
  144.                 m_weight(0) {}
  145.     
  146.             // value constructor
  147.             Triple(code_t start, code_t stop, code_t weight)
  148.             {
  149.                 m_start  = start;
  150.                 m_stop   = stop;
  151.                 m_weight = weight;
  152.             }
  153.     
  154.             //! copy constructor
  155.             Triple(const Triple& rhs)
  156.               : m_start(rhs.m_start),
  157.                 m_stop(rhs.m_stop),
  158.                 m_weight(rhs.m_weight) { }
  159.     
  160.             //! assignment 
  161.             Triple & operator = (const Triple& rhs)
  162.             {
  163.                 m_start  = rhs.m_start;
  164.                 m_stop   = rhs.m_stop;
  165.                 m_weight = rhs.m_weight;
  166.                 return *this;
  167.             }
  168.     
  169.             // get the start value    
  170.             code_t Start() const { return m_start; }
  171.     
  172.             // get the stop value    
  173.             code_t Stop() const  { return m_stop; }
  174.     
  175.             // get the weight value    
  176.             code_t Weight() const { return m_weight; }
  177.     
  178.         private:
  179.             //! The m_start value. 
  180.             code_t m_start;    
  181.     
  182.             //! The m_stop value.Should be >=m_start. 
  183.             code_t m_stop;
  184.     
  185.             //! The denominator for interpreting m_start, m_stop. Should be >= m_start,m_stop. 
  186.             code_t m_weight;    
  187.         };
  188.     
  189.         //! A class for binary contexts.
  190.         /*!
  191.             A class for binary contexts. Stores probabilities for 0 and 1 in 
  192.             terms of counts of numbers of occurrences, and also as Triples 
  193.             partitioning the interval [0,1) into two parts [0,p) and [p,1). 
  194.          */
  195.         class Context
  196.         {
  197.         public:
  198.             //! Default Constructor.
  199.             /*!
  200.                 Default constructor initialises counts to 1 each of 0 and 1.
  201.              */    
  202.             Context()
  203.             {
  204.                 SetCounts(1,1);
  205.             }
  206.     
  207.             //! Constructor.
  208.             /*!
  209.                 Constructor initialises the counts to those set.
  210.              */    
  211.             Context(int cnt0,int cnt1)
  212.             {
  213.                 SetCounts(cnt0,cnt1);
  214.             }
  215.     
  216.             //! Copy constructor
  217.             Context(const Context & cpy)
  218.               : count0(cpy.count0),
  219.                 count1(cpy.count1),
  220.                 trip0(cpy.trip0),
  221.                 trip1(cpy.trip1)
  222.             {}
  223.     
  224.             //! Assignment=
  225.             Context & operator=(const Context& rhs)
  226.             {
  227.                 count0 = rhs.count0;
  228.                 count1 = rhs.count1;
  229.                 trip0  = rhs.trip0;
  230.                 trip1  = rhs.trip1;
  231.                 return *this;
  232.             }
  233.     
  234.             //! Destructor
  235.             ~Context() {}
  236.     
  237.             //! Sets the counts according to the input.
  238.             /*!
  239.                 Sets the counts, and then the triples to reflect the counts.
  240.              */    
  241.             void SetCounts(int cnt0, int cnt1)
  242.             {
  243.                 count0 = cnt0;
  244.                 count1 = cnt1;
  245.                 SetTriples();
  246.             }
  247.     
  248.             //! Returns the count of zeroes.
  249.             code_t GetCount0() const { return count0; }    
  250.     
  251.             //! Returns the count of ones.
  252.             code_t GetCount1() const { return count1; }    
  253.     
  254.             //! Increment the count.
  255.             /*!
  256.                 Increment the count of Symbol by amnt.
  257.                 param    symbol  the symbol whose count is to be 
  258.                                    incremented (false=0, true=1)
  259.                 param    amnt    the amount to increment by
  260.              */    
  261.             void IncrCount(bool symbol, int amnt)
  262.             {
  263.                 if ( symbol ) 
  264.                     count1 += amnt; 
  265.                 else 
  266.                     count0 += amnt;
  267.     
  268.                 SetTriples();
  269.             }
  270.     
  271.              //! Divide the counts by 2, making sure neither ends up 0.
  272.             void HalveCounts()
  273.             {
  274.                 count0 >>= 1;
  275.                 count0++;
  276.                 count1 >>= 1;
  277.                 count1++;
  278.     
  279.                 SetTriples();
  280.             }
  281.     
  282.             //! Return the m_m_weight, equal to the count of 0 plus the count of 1.    
  283.             code_t Weight() const { return trip0.Weight(); }
  284.     
  285.                //! Return the triple associated with Symbol.    
  286.             const Triple & GetTriple( const bool symbol ) const { return (symbol ? trip1 : trip0); }
  287.     
  288.             //! Given a number, return the corresponding symbol and triple.
  289.             /*!
  290.                 Given a number, which should be in the range [0,m_weight) 
  291.                 return the corresponding symbol.  The range [0,m_weight) is 
  292.                 partitioned into portions [0,count0), [count0,m_weight) 
  293.                 corresponding to 0 and 1.
  294.              */    
  295.             bool GetSymbol(const code_t num, Triple & trip_val) const
  296.             {
  297.                 if (num < trip0.Stop())
  298.                 {
  299.                     trip_val = trip0;
  300.                     return false; //ie zero
  301.                 }
  302.                 else
  303.                 {
  304.                     trip_val = trip1;
  305.                     return true; //ie 1
  306.                 }
  307.             } 
  308.     
  309.         private:
  310.             code_t count0;
  311.             code_t count1;
  312.     
  313.             Triple trip0;
  314.             Triple trip1;
  315.     
  316.             void SetTriples()
  317.             {
  318.                 //updates triples given counts
  319.                 trip0 = Triple(0, trip0.Start() + count0, count0 + count1);    
  320.                 trip1 = Triple(trip0.Stop(), trip1.Start() + count1, trip0.Weight());    
  321.             }
  322.         };
  323.     
  324.     protected:
  325.     
  326.         //! Return the context counts, perhaps so as to improve initialisation the next time around
  327.         //std::vector<Context> & ContextList() { return m_context_list; }
  328.     
  329.         //virtual codec functions (to be overridden)
  330.         ////////////////////////////////////////////
  331.     
  332.         //! The method by which the contexts are initialised
  333.         virtual void InitContexts()=0;                                        
  334.     
  335.         //! The method by which the counts are updated.
  336.         virtual void Update( const bool symbol , const int context_num )=0;    
  337.     
  338.         //! The method by which the counts are resized
  339.         virtual void Resize(const int context_num)=0;                        
  340.     
  341.         //! The method by which _all_ the counts are resized.
  342.         virtual void ResetAll()=0;                                            
  343.     
  344.         //! Choose the context based on previous data.
  345.         virtual int ChooseContext(const T &data, const int bin_number) const =0;
  346.     
  347.         //! Choose the context based on previous data.
  348.         virtual int ChooseContext(const T &data) const=0;                         
  349.     
  350.         //virtual encode-only functions
  351.         /////////////////////////////// 
  352.     
  353.         //! Does the work of actually coding the data 
  354.         virtual void DoWorkCode(T & in_data) = 0;    
  355.     
  356.         //core encode-only functions
  357.         ////////////////////////////
  358.     
  359.         //! Initialises the Encoder
  360.         void InitEncoder();
  361.     
  362.         //! encodes a triple and writes to output
  363.         void EncodeTriple(const Triple & c);
  364.     
  365.         //! encodes a symbol and writes to output
  366.         void EncodeSymbol(const bool symbol, const int context_num);    
  367.     
  368.         //! flushes the output of the encoder.
  369.         void FlushEncoder(); 
  370.     
  371.         //! flushes the input of the encoder by reading all the remaining bits
  372.         void FlushDecoder(); 
  373.     
  374.         //! virtual decode-only functions    
  375.         virtual void DoWorkDecode(T & out_data, int num_bits)=0;    
  376.     
  377.         // core decode-only functions
  378.         ////////////////////////////
  379.     
  380.         //! Initialise the Decoder
  381.         void InitDecoder();                    
  382.     
  383.         //! Remove the symbol from the coded input stream
  384.         void RemFromStream(const Triple & c);
  385.     
  386.         //! Rescales the interval midpoint according to the context 
  387.         void SetCurrentCount(const int context_num); 
  388.     
  389.         //! Decodes a symbol given a context number
  390.         void DecodeSymbol(bool& symbol, int context_num); 
  391.     
  392.     private:
  393.         //! count of the total number of bits input or output
  394.         int m_bit_count;                        
  395.     
  396.         //! max number of bits to be input
  397.         int m_max_count;                        
  398.     
  399.         //! Number of underflow bits
  400.         int m_underflow;                        
  401.     
  402.         //! The present input code
  403.         code_t m_code;                    
  404.     
  405.         //! Scaled midpoint of the decoding interval
  406.         code_t m_count;                        
  407.     
  408.         //! Start of the current code range
  409.         code_t m_low_code;                        
  410.     
  411.         //! End of the current code range
  412.         code_t m_high_code;                    
  413.     
  414.         // Parameters for controlling coding/decoding
  415.         // codec_params_type cparams;        
  416.     
  417.         //! Manages interface with file/stream
  418.         BitInputManager* m_bit_input;                
  419.     
  420.         //! Manages interface with file/stream. Can be header or data
  421.         BasicOutputManager* m_bit_output;
  422.     
  423.         //private, bodyless copy constructor: class should not be copied
  424.         ArithCodec(const ArithCodec & cpy);
  425.     
  426.         //private, bodyless copy operator=: class should not be assigned
  427.         ArithCodec & operator = (const ArithCodec & rhs);
  428.     
  429.     
  430.     protected:
  431.     
  432.         //! List of contexts
  433.         std::vector<Context> m_context_list;    
  434.     };
  435.     
  436.     //Implementation - core functions
  437.     /////////////////////////////////
  438.     
  439.     template<class T>
  440.     ArithCodec<T>::ArithCodec(BitInputManager* bits_in, size_t number_of_contexts)
  441.       : m_bit_count(0),
  442.         m_bit_input(bits_in),
  443.         m_context_list(number_of_contexts)
  444.     {
  445.         // nothing needed here
  446.     }    
  447.     
  448.     //! Constructor for encoding
  449.     template<class T>
  450.     ArithCodec<T>::ArithCodec(BasicOutputManager* bits_out, size_t number_of_contexts)
  451.       : m_bit_count(0),
  452.         m_bit_output(bits_out),
  453.         m_context_list(number_of_contexts)
  454.     {
  455.         // nothing needed here
  456.     }    
  457.     
  458.     template<class T>
  459.     ArithCodec<T>::~ArithCodec()
  460.     {
  461.         // nothing needed here
  462.     }
  463.     
  464.     template<class T>
  465.     int ArithCodec<T>::Compress(T &in_data)
  466.     {
  467.         InitEncoder();                
  468.         DoWorkCode(in_data);
  469.         FlushEncoder();
  470.         return m_bit_count;
  471.     }
  472.     
  473.     template<class T>
  474.     void ArithCodec<T>::Decompress(T &out_data, int num_bits)
  475.     {
  476.         m_max_count=num_bits;
  477.         InitDecoder();
  478.         DoWorkDecode(out_data,num_bits);
  479.         FlushDecoder();        
  480.         m_bit_input->FlushInput();
  481.     }
  482.     
  483.     template<class T>
  484.     void ArithCodec<T>::InitEncoder()
  485.     {
  486.         // Set the m_code word stuff
  487.         m_low_code  = 0;
  488.         m_high_code = CODE_MAX;
  489.         m_underflow = 0;
  490.     }
  491.     
  492.     template<class T>
  493.     void ArithCodec<T>::EncodeTriple(const Triple &c)
  494.     {
  495.         // Rescale m_high_code and m_low_code for the new symbol
  496.         calc_t range( static_cast<calc_t>(m_high_code - m_low_code) + 1 );
  497.     
  498.         //formulae given we know we're binary coding    
  499.         if (!c.Start()) // c.Start()=0, so symbol is 0, so m_low_code unchanged 
  500.             m_high_code = m_low_code + static_cast<code_t>(( range * c.Stop() ) / c.Weight() - 1 );
  501.         else //symbol is 1, so m_high_code unchanged
  502.             m_low_code += static_cast<code_t>(( range * c.Start() ) / c.Weight() );                
  503.     
  504.         do
  505.         {
  506.             if (( m_high_code & CODE_MSB ) == ( m_low_code & CODE_MSB ))
  507.             {
  508.                 m_bit_output->OutputBit( m_high_code & CODE_MSB, m_bit_count);
  509.                 while ( m_underflow > 0 )
  510.                 {
  511.                     m_bit_output->OutputBit(~m_high_code & CODE_MSB, m_bit_count);
  512.                     m_underflow--;
  513.                 }
  514.             }
  515.     
  516.             else if ( ( m_low_code & CODE_2ND_MSB ) && !( m_high_code & CODE_2ND_MSB ))
  517.             {
  518.                 m_underflow += 1;
  519.                 m_low_code  &= (CODE_2ND_MSB) - 1;
  520.                 m_high_code |= CODE_2ND_MSB;
  521.             }
  522.             else return ;
  523.     
  524.             m_low_code  <<= 1;
  525.             m_high_code <<= 1;
  526.             m_high_code  |= 1;
  527.         }
  528.         while(true);
  529.     }
  530.     
  531.     template<class T>
  532.     inline void ArithCodec<T>::EncodeSymbol(const bool symbol, const int context_num)
  533.     {
  534.         EncodeTriple(m_context_list[context_num].GetTriple(symbol));
  535.         Update( symbol , context_num );
  536.     }
  537.     
  538.     template<class T>
  539.     void ArithCodec<T>::FlushEncoder()
  540.     {
  541.         // Flushes the output
  542.         m_bit_output->OutputBit(m_low_code & CODE_2ND_MSB,m_bit_count);
  543.         m_underflow++;
  544.     
  545.         while ( m_underflow-- > 0 )
  546.             m_bit_output->OutputBit(~m_low_code & CODE_2ND_MSB, m_bit_count);
  547.     }
  548.     
  549.     template<class T>
  550.     void ArithCodec<T>::InitDecoder()
  551.     {
  552.         //Read in a full word of data
  553.            code_t i;
  554.         m_code = 0;
  555.     
  556.         for ( i = 0; i < (8 * sizeof(code_t)); i++ )
  557.         {
  558.             m_code <<= 1;
  559.     
  560.             if (m_bit_input->InputBit(m_bit_count,m_max_count))
  561.                 m_code++;
  562.         }
  563.     
  564.         m_low_code  = 0;
  565.         m_high_code = CODE_MAX;
  566.         m_underflow = 0;
  567.     }
  568.     
  569.     template<class T>
  570.     void ArithCodec<T>::RemFromStream( const Triple &c )
  571.     {
  572.        
  573.         calc_t range( static_cast<calc_t>( m_high_code - m_low_code ) + 1 );
  574.     
  575.         if(!c.Start())//c.Start()=0, so symbol is 0, so m_low_code unchanged 
  576.             m_high_code = m_low_code + static_cast<code_t>(( range * c.Stop() ) / c.Weight() - 1 );
  577.     
  578.         else//symbol is 1, so m_high_code unchanged
  579.             m_low_code += static_cast<code_t>(( range * c.Start() ) / c.Weight() );        
  580.     
  581.         do
  582.         {        
  583.             if ( ( m_high_code & CODE_MSB ) == ( m_low_code & CODE_MSB ) )
  584.             {
  585.                 // Do nothing
  586.             }        
  587.             else if ((m_low_code & CODE_2ND_MSB) == CODE_2ND_MSB  && (m_high_code & CODE_2ND_MSB) == 0 )
  588.             {
  589.                 m_code      ^= CODE_2ND_MSB;
  590.                 m_low_code  &= (CODE_2ND_MSB) - 1;
  591.                 m_high_code |= CODE_2ND_MSB;
  592.             }        
  593.             else return;
  594.     
  595.             m_low_code  <<= 1;
  596.             m_high_code <<= 1;
  597.             m_high_code  |= 1;
  598.             m_code      <<= 1;
  599.     
  600.             if ( m_bit_input->InputBit( m_bit_count , m_max_count ) )
  601.                 m_code++; 
  602.     
  603.         } while (1);
  604.     
  605.     }
  606.     
  607.     template<class T>
  608.     void ArithCodec<T>::SetCurrentCount(const int context_num)
  609.     {
  610.         calc_t range;
  611.         range = static_cast<calc_t>( m_high_code - m_low_code ) + 1;
  612.         m_count = static_cast<code_t>( 
  613.                                       ( ( static_cast<calc_t>( m_code - m_low_code ) + 1 ) * m_context_list[context_num].Weight() - 1 ) 
  614.                                       / range );
  615.     }
  616.     
  617.     template<class T>
  618.     void ArithCodec<T>::DecodeSymbol(bool& symbol, const int context_num)
  619.     {
  620.         Triple limits;    
  621.         SetCurrentCount( context_num );
  622.         symbol = m_context_list[context_num].GetSymbol( m_count , limits );        
  623.         RemFromStream( limits );
  624.         Update(  symbol , context_num );
  625.     }
  626.     
  627.     template<class T>
  628.     void ArithCodec<T>::FlushDecoder()
  629.     {
  630.         // Flushes the input
  631.         while(m_bit_count < m_max_count)
  632.             m_bit_input->InputBit( m_bit_count , m_max_count );
  633.     }
  634.     
  635. } //namespace dirac
  636. #endif