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