hackedteam/vector-edk

View on GitHub
vector-uefi/insyde/7zip/Java/SevenZip/Compression/RangeCoder/Encoder.java

Summary

Maintainability
A
30 mins
Test Coverage
package SevenZip.Compression.RangeCoder;
import java.io.IOException;

public class Encoder
{
    static final int kTopMask = ~((1 << 24) - 1);
    
    static final int kNumBitModelTotalBits = 11;
    static final int kBitModelTotal = (1 << kNumBitModelTotalBits);
    static final int kNumMoveBits = 5;
    
    java.io.OutputStream Stream;

    long Low;
    int Range;
    int _cacheSize;
    int _cache;
    
    long _position;
    
    public void SetStream(java.io.OutputStream stream)
    {
        Stream = stream;
    }
    
    public void ReleaseStream()
    {
        Stream = null;
    }
    
    public void Init()
    {
        _position = 0;
        Low = 0;
        Range = -1;
        _cacheSize = 1;
        _cache = 0;
    }
    
    public void FlushData() throws IOException
    {
        for (int i = 0; i < 5; i++)
            ShiftLow();
    }
    
    public void FlushStream() throws IOException
    {
        Stream.flush();
    }
    
    public void ShiftLow() throws IOException
    {
        int LowHi = (int)(Low >>> 32);
        if (LowHi != 0 || Low < 0xFF000000L)
        {
            _position += _cacheSize;
            int temp = _cache;
            do
            {
                Stream.write(temp + LowHi);
                temp = 0xFF;
            }
            while(--_cacheSize != 0);
            _cache = (((int)Low) >>> 24);
        }
        _cacheSize++;
        Low = (Low & 0xFFFFFF) << 8;
    }
    
    public void EncodeDirectBits(int v, int numTotalBits) throws IOException
    {
        for (int i = numTotalBits - 1; i >= 0; i--)
        {
            Range >>>= 1;
            if (((v >>> i) & 1) == 1)
                Low += Range;
            if ((Range & Encoder.kTopMask) == 0)
            {
                Range <<= 8;
                ShiftLow();
            }
        }
    }
    
    
    public long GetProcessedSizeAdd()
    {
        return _cacheSize + _position + 4;
    }
    
    
    
    static final int kNumMoveReducingBits = 2;
    public static final int kNumBitPriceShiftBits = 6;
    
    public static void InitBitModels(short []probs)
    {
        for (int i = 0; i < probs.length; i++)
            probs[i] = (kBitModelTotal >>> 1);
    }
    
    public void Encode(short []probs, int index, int symbol) throws IOException
    {
        int prob = probs[index];
        int newBound = (Range >>> kNumBitModelTotalBits) * prob;
        if (symbol == 0)
        {
            Range = newBound;
            probs[index] = (short)(prob + ((kBitModelTotal - prob) >>> kNumMoveBits));
        }
        else
        {
            Low += (newBound & 0xFFFFFFFFL);
            Range -= newBound;
            probs[index] = (short)(prob - ((prob) >>> kNumMoveBits));
        }
        if ((Range & kTopMask) == 0)
        {
            Range <<= 8;
            ShiftLow();
        }
    }
    
    private static int[] ProbPrices = new int[kBitModelTotal >>> kNumMoveReducingBits];
    
    static
    {
        int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
        for (int i = kNumBits - 1; i >= 0; i--)
        {
            int start = 1 << (kNumBits - i - 1);
            int end = 1 << (kNumBits - i);
            for (int j = start; j < end; j++)
                ProbPrices[j] = (i << kNumBitPriceShiftBits) +
                        (((end - j) << kNumBitPriceShiftBits) >>> (kNumBits - i - 1));
        }
    }
    
    static public int GetPrice(int Prob, int symbol)
    {
        return ProbPrices[(((Prob - symbol) ^ ((-symbol))) & (kBitModelTotal - 1)) >>> kNumMoveReducingBits];
    }
    static public int GetPrice0(int Prob)
    { 
        return ProbPrices[Prob >>> kNumMoveReducingBits]; 
    }
    static public int GetPrice1(int Prob)
    { 
        return ProbPrices[(kBitModelTotal - Prob) >>> kNumMoveReducingBits]; 
    }
}