misc/libphysfs/lzma/Java/SevenZip/Compression/RangeCoder/Encoder.java
changeset 13881 99b265e0d1d0
parent 13880 5f819b90d479
child 13882 b172a5d40eee
equal deleted inserted replaced
13880:5f819b90d479 13881:99b265e0d1d0
     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 }