misc/libphysfs/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderBit.h
changeset 13881 99b265e0d1d0
parent 13880 5f819b90d479
child 13882 b172a5d40eee
equal deleted inserted replaced
13880:5f819b90d479 13881:99b265e0d1d0
     1 // Compress/RangeCoder/RangeCoderBit.h
       
     2 
       
     3 #ifndef __COMPRESS_RANGECODER_BIT_H
       
     4 #define __COMPRESS_RANGECODER_BIT_H
       
     5 
       
     6 #include "RangeCoder.h"
       
     7 
       
     8 namespace NCompress {
       
     9 namespace NRangeCoder {
       
    10 
       
    11 const int kNumBitModelTotalBits  = 11;
       
    12 const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits);
       
    13 
       
    14 const int kNumMoveReducingBits = 2;
       
    15 
       
    16 const int kNumBitPriceShiftBits = 6;
       
    17 const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits;
       
    18 
       
    19 class CPriceTables
       
    20 {
       
    21 public:
       
    22   static UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
       
    23   static void Init();
       
    24   CPriceTables();
       
    25 };
       
    26 
       
    27 template <int numMoveBits>
       
    28 class CBitModel
       
    29 {
       
    30 public:
       
    31   UInt32 Prob;
       
    32   void UpdateModel(UInt32 symbol)
       
    33   {
       
    34     /*
       
    35     Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;
       
    36     Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);
       
    37     */
       
    38     if (symbol == 0)
       
    39       Prob += (kBitModelTotal - Prob) >> numMoveBits;
       
    40     else
       
    41       Prob -= (Prob) >> numMoveBits;
       
    42   }
       
    43 public:
       
    44   void Init() { Prob = kBitModelTotal / 2; }
       
    45 };
       
    46 
       
    47 template <int numMoveBits>
       
    48 class CBitEncoder: public CBitModel<numMoveBits>
       
    49 {
       
    50 public:
       
    51   void Encode(CEncoder *encoder, UInt32 symbol)
       
    52   {
       
    53     /*
       
    54     encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol);
       
    55     this->UpdateModel(symbol);
       
    56     */
       
    57     UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob;
       
    58     if (symbol == 0)
       
    59     {
       
    60       encoder->Range = newBound;
       
    61       this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
       
    62     }
       
    63     else
       
    64     {
       
    65       encoder->Low += newBound;
       
    66       encoder->Range -= newBound;
       
    67       this->Prob -= (this->Prob) >> numMoveBits;
       
    68     }
       
    69     if (encoder->Range < kTopValue)
       
    70     {
       
    71       encoder->Range <<= 8;
       
    72       encoder->ShiftLow();
       
    73     }
       
    74   }
       
    75   UInt32 GetPrice(UInt32 symbol) const
       
    76   {
       
    77     return CPriceTables::ProbPrices[
       
    78       (((this->Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
       
    79   }
       
    80   UInt32 GetPrice0() const { return CPriceTables::ProbPrices[this->Prob >> kNumMoveReducingBits]; }
       
    81   UInt32 GetPrice1() const { return CPriceTables::ProbPrices[(kBitModelTotal - this->Prob) >> kNumMoveReducingBits]; }
       
    82 };
       
    83 
       
    84 
       
    85 template <int numMoveBits>
       
    86 class CBitDecoder: public CBitModel<numMoveBits>
       
    87 {
       
    88 public:
       
    89   UInt32 Decode(CDecoder *decoder)
       
    90   {
       
    91     UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob;
       
    92     if (decoder->Code < newBound)
       
    93     {
       
    94       decoder->Range = newBound;
       
    95       this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
       
    96       if (decoder->Range < kTopValue)
       
    97       {
       
    98         decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
       
    99         decoder->Range <<= 8;
       
   100       }
       
   101       return 0;
       
   102     }
       
   103     else
       
   104     {
       
   105       decoder->Range -= newBound;
       
   106       decoder->Code -= newBound;
       
   107       this->Prob -= (this->Prob) >> numMoveBits;
       
   108       if (decoder->Range < kTopValue)
       
   109       {
       
   110         decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
       
   111         decoder->Range <<= 8;
       
   112       }
       
   113       return 1;
       
   114     }
       
   115   }
       
   116 };
       
   117 
       
   118 }}
       
   119 
       
   120 #endif