Home | History | Annotate | Download | only in RangeCoder
      1 package SevenZip.Compression.RangeCoder;
      2 import java.io.IOException;
      3 
      4 public class Encoder
      5 {
      6 	static final int kTopMask = ~((1 << 24) - 1);
      7 
      8 	static final int kNumBitModelTotalBits = 11;
      9 	static final int kBitModelTotal = (1 << kNumBitModelTotalBits);
     10 	static final int kNumMoveBits = 5;
     11 
     12 	java.io.OutputStream Stream;
     13 
     14 	long Low;
     15 	int Range;
     16 	int _cacheSize;
     17 	int _cache;
     18 
     19 	long _position;
     20 
     21 	public void SetStream(java.io.OutputStream stream)
     22 	{
     23 		Stream = stream;
     24 	}
     25 
     26 	public void ReleaseStream()
     27 	{
     28 		Stream = null;
     29 	}
     30 
     31 	public void Init()
     32 	{
     33 		_position = 0;
     34 		Low = 0;
     35 		Range = -1;
     36 		_cacheSize = 1;
     37 		_cache = 0;
     38 	}
     39 
     40 	public void FlushData() throws IOException
     41 	{
     42 		for (int i = 0; i < 5; i++)
     43 			ShiftLow();
     44 	}
     45 
     46 	public void FlushStream() throws IOException
     47 	{
     48 		Stream.flush();
     49 	}
     50 
     51 	public void ShiftLow() throws IOException
     52 	{
     53 		int LowHi = (int)(Low >>> 32);
     54 		if (LowHi != 0 || Low < 0xFF000000L)
     55 		{
     56 			_position += _cacheSize;
     57 			int temp = _cache;
     58 			do
     59 			{
     60 				Stream.write(temp + LowHi);
     61 				temp = 0xFF;
     62 			}
     63 			while(--_cacheSize != 0);
     64 			_cache = (((int)Low) >>> 24);
     65 		}
     66 		_cacheSize++;
     67 		Low = (Low & 0xFFFFFF) << 8;
     68 	}
     69 
     70 	public void EncodeDirectBits(int v, int numTotalBits) throws IOException
     71 	{
     72 		for (int i = numTotalBits - 1; i >= 0; i--)
     73 		{
     74 			Range >>>= 1;
     75 			if (((v >>> i) & 1) == 1)
     76 				Low += Range;
     77 			if ((Range & Encoder.kTopMask) == 0)
     78 			{
     79 				Range <<= 8;
     80 				ShiftLow();
     81 			}
     82 		}
     83 	}
     84 
     85 
     86 	public long GetProcessedSizeAdd()
     87 	{
     88 		return _cacheSize + _position + 4;
     89 	}
     90 
     91 
     92 
     93 	static final int kNumMoveReducingBits = 2;
     94 	public static final int kNumBitPriceShiftBits = 6;
     95 
     96 	public static void InitBitModels(short []probs)
     97 	{
     98 		for (int i = 0; i < probs.length; i++)
     99 			probs[i] = (kBitModelTotal >>> 1);
    100 	}
    101 
    102 	public void Encode(short []probs, int index, int symbol) throws IOException
    103 	{
    104 		int prob = probs[index];
    105 		int newBound = (Range >>> kNumBitModelTotalBits) * prob;
    106 		if (symbol == 0)
    107 		{
    108 			Range = newBound;
    109 			probs[index] = (short)(prob + ((kBitModelTotal - prob) >>> kNumMoveBits));
    110 		}
    111 		else
    112 		{
    113 			Low += (newBound & 0xFFFFFFFFL);
    114 			Range -= newBound;
    115 			probs[index] = (short)(prob - ((prob) >>> kNumMoveBits));
    116 		}
    117 		if ((Range & kTopMask) == 0)
    118 		{
    119 			Range <<= 8;
    120 			ShiftLow();
    121 		}
    122 	}
    123 
    124 	private static int[] ProbPrices = new int[kBitModelTotal >>> kNumMoveReducingBits];
    125 
    126 	static
    127 	{
    128 		int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
    129 		for (int i = kNumBits - 1; i >= 0; i--)
    130 		{
    131 			int start = 1 << (kNumBits - i - 1);
    132 			int end = 1 << (kNumBits - i);
    133 			for (int j = start; j < end; j++)
    134 				ProbPrices[j] = (i << kNumBitPriceShiftBits) +
    135 						(((end - j) << kNumBitPriceShiftBits) >>> (kNumBits - i - 1));
    136 		}
    137 	}
    138 
    139 	static public int GetPrice(int Prob, int symbol)
    140 	{
    141 		return ProbPrices[(((Prob - symbol) ^ ((-symbol))) & (kBitModelTotal - 1)) >>> kNumMoveReducingBits];
    142 	}
    143 	static public int GetPrice0(int Prob)
    144 	{
    145 		return ProbPrices[Prob >>> kNumMoveReducingBits];
    146 	}
    147 	static public int GetPrice1(int Prob)
    148 	{
    149 		return ProbPrices[(kBitModelTotal - Prob) >>> kNumMoveReducingBits];
    150 	}
    151 }
    152