%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/waritko/yacy/libbuild/J7Zip-modified/src/SevenZip/Compression/LZMA/
Upload File :
Create Path :
Current File : //home/waritko/yacy/libbuild/J7Zip-modified/src/SevenZip/Compression/LZMA/Decoder.java

package SevenZip.Compression.LZMA;

import SevenZip.ICompressCoder;
import SevenZip.ICompressGetInStreamProcessedSize;
import SevenZip.ICompressProgressInfo;
import SevenZip.ICompressSetInStream;
import SevenZip.ICompressSetOutStreamSize;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import SevenZip.Compression.LZ.OutWindow;
import SevenZip.Compression.RangeCoder.BitTreeDecoder;

public class Decoder extends InputStream implements ICompressCoder, ICompressGetInStreamProcessedSize,
		ICompressSetInStream, ICompressSetOutStreamSize {
	
	private static final int kLenIdFinished 		= -1;
	private static final int kLenIdNeedInit 		= -2;
	
	private final SevenZip.Compression.RangeCoder.Decoder m_RangeDecoder = new SevenZip.Compression.RangeCoder.Decoder();
	private final OutWindow m_OutWindow 			= new OutWindow();
	
	private final short[] m_IsMatchDecoders 		= new short[Base.kNumStates << Base.kNumPosStatesBitsMax];
	private final short[] m_IsRepDecoders 			= new short[Base.kNumStates];
	private final short[] m_IsRepG0Decoders 		= new short[Base.kNumStates];
	private final short[] m_IsRepG1Decoders 		= new short[Base.kNumStates];
	private final short[] m_IsRepG2Decoders 		= new short[Base.kNumStates];
	private final short[] m_IsRep0LongDecoders 		= new short[Base.kNumStates << Base.kNumPosStatesBitsMax];
	private final short[] m_PosDecoders 			= new short[Base.kNumFullDistances - Base.kEndPosModelIndex];
	
	private final BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates];
	private final BitTreeDecoder m_PosAlignDecoder 	= new BitTreeDecoder(Base.kNumAlignBits);
	
	private final LenDecoder m_LenDecoder;
	private final LenDecoder m_RepLenDecoder;
	
	private final LiteralDecoder m_LiteralDecoder;
	
	private final int m_DictionarySize;
	private final int m_DictionarySizeCheck;
	
	private int m_posStateMask;
	
	private long _outSize = 0;
	private boolean _outSizeDefined 			= false;
	private int _remainLen; // -1 means end of stream. // -2 means need Init
	private int _rep0;
	private int _rep1;
	private int _rep2;
	private int _rep3;
	private int _state;
	
	public Decoder(byte[] properties) {
		for (int i = 0; i < Base.kNumLenToPosStates; i++)
			this.m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits);
		
		if (properties.length < 5)
			throw new IllegalArgumentException("properties.length < 5");
		int val = properties[0] & 0xFF;
		int lc = val % 9;
		int remainder = val / 9;
		int lp = remainder % 5;
		int pb = remainder / 5;
		int dictionarySize = 0;
		for (int i = 0; i < 4; i++)
			dictionarySize += ((int)(properties[1 + i]) & 0xFF) << (i * 8);
		
		// Set lc, lp, pb
		if (lc > Base.kNumLitContextBitsMax || lp > 4 || pb > Base.kNumPosStatesBitsMax)
			throw new IllegalArgumentException("lc > Base.kNumLitContextBitsMax || lp > 4 || pb > Base.kNumPosStatesBitsMax");
		// if (this.m_LiteralDecoder != null) throw new NullPointerException("LiteralDecoder != null, WTF?!"); // hint: skip use of not initialized static variable
		this.m_LiteralDecoder = new LiteralDecoder(lp, lc);
		int numPosStates = 1 << pb;
		this.m_LenDecoder = new LenDecoder(numPosStates);
		this.m_RepLenDecoder = new LenDecoder(numPosStates);
		this.m_posStateMask = numPosStates - 1;
		
		// set dictionary size
		if (dictionarySize < 0)
			throw new IllegalArgumentException("dictionarySize must not be smaller than 0");
		this.m_DictionarySize = dictionarySize;
		this.m_DictionarySizeCheck = Math.max(this.m_DictionarySize, 1);
		this.m_OutWindow.Create(Math.max(this.m_DictionarySizeCheck, (1 << 12)));
		this.m_RangeDecoder.Create(1 << 20);
	}
	
	public long GetInStreamProcessedSize() {
		throw new UnknownError("GetInStreamProcessedSize");
		// return m_RangeDecoder.GetProcessedSize();
	}
	
	public void ReleaseInStream() throws IOException {
		this.m_RangeDecoder.ReleaseStream();
	}
	
	public void SetInStream(InputStream inStream) { // Common.ISequentialInStream
		this.m_RangeDecoder.SetStream(inStream);
	}
	
	public void SetOutStreamSize(long outSize /* const UInt64 *outSize*/ ) {
		this._outSizeDefined = (outSize != ICompressSetOutStreamSize.INVALID_OUTSIZE);
		if (this._outSizeDefined)
			this._outSize = outSize;
		this._remainLen = kLenIdNeedInit;
		this.m_OutWindow.Init();
	}
	
	// #ifdef _ST_MODE
	public int read() throws IOException {
		throw new IOException("LZMA Decoder - read() not implemented");
	}
	
	public int read(byte [] data, int off, int size) throws IOException  {
		if (off != 0) throw new IOException("LZMA Decoder - read(byte [] data, int off != 0, int size)) not implemented");
		
		long startPos = this.m_OutWindow.GetProcessedSize();
		this.m_OutWindow.SetMemStream(data);
		CodeSpec(size);
		Flush();
		int ret = (int)(this.m_OutWindow.GetProcessedSize() - startPos);
		if (ret == 0) ret = -1;
		return ret;
	}
	
	// #endif // _ST_MODE
	
	private void Init() throws IOException {
		this.m_OutWindow.Init(false);
		
		SevenZip.Compression.RangeCoder.Decoder.InitBitModels(this.m_IsMatchDecoders);
		SevenZip.Compression.RangeCoder.Decoder.InitBitModels(this.m_IsRep0LongDecoders);
		SevenZip.Compression.RangeCoder.Decoder.InitBitModels(this.m_IsRepDecoders);
		SevenZip.Compression.RangeCoder.Decoder.InitBitModels(this.m_IsRepG0Decoders);
		SevenZip.Compression.RangeCoder.Decoder.InitBitModels(this.m_IsRepG1Decoders);
		SevenZip.Compression.RangeCoder.Decoder.InitBitModels(this.m_IsRepG2Decoders);
		SevenZip.Compression.RangeCoder.Decoder.InitBitModels(this.m_PosDecoders);
		
		this._rep0 = this._rep1 = this._rep2 = this._rep3 = 0;
		this._state = Base.StateInit();
		
		// this.m_LiteralDecoder.Init();
		for (int i = 0; i < Base.kNumLenToPosStates; i++)
			this.m_PosSlotDecoder[i].Init();
		// this.m_LenDecoder.Init();
		// this.m_RepLenDecoder.Init();
		this.m_PosAlignDecoder.Init();
	}
	
	public void Flush() throws IOException {
		this.m_OutWindow.Flush();
	}
	
	private void ReleaseStreams() throws IOException  {
		this.m_OutWindow.ReleaseStream();
		ReleaseInStream();
	}
	
	public void CodeReal(
			InputStream inStream, // , ISequentialInStream
			OutputStream outStream, // ISequentialOutStream
			long outSize,
			ICompressProgressInfo progress // useless_progress
	) throws IOException {
		SetInStream(inStream);
		this.m_OutWindow.SetStream(outStream);
		SetOutStreamSize(outSize);
		
		do {
			int curSize = 1 << 18;
			CodeSpec(curSize);
			if (this._remainLen == kLenIdFinished)
				break;
			
			if (progress != null) {
				long inSize = this.m_RangeDecoder.GetProcessedSize();
				long nowPos64 = this.m_OutWindow.GetProcessedSize();
				progress.SetRatioInfo(inSize, nowPos64);
			}
		} while (!this._outSizeDefined || this.m_OutWindow.GetProcessedSize() < this._outSize);
		Flush();
	}
	
	public void Code(
			InputStream inStream, // , ISequentialInStream
			OutputStream outStream, // ISequentialOutStream
			long outSize,
			ICompressProgressInfo progress // useless_progress
	) throws IOException {
		try {
			CodeReal(inStream,outStream,outSize,progress);
		} finally {
			Flush();
			ReleaseStreams();
		}
	}
	
	private void CodeSpec(int curSize) throws IOException {
		if (this._outSizeDefined) {
			long rem = this._outSize - this.m_OutWindow.GetProcessedSize();
			if (curSize > rem)
				curSize = (int)rem;
		}
		
		if (this._remainLen == kLenIdFinished)
			return;
		if (this._remainLen == kLenIdNeedInit) {
			this.m_RangeDecoder.Init();
			Init();
			this._remainLen = 0;
		}
		if (curSize == 0)
			return;
		
		int rep0 = this._rep0;
		int rep1 = this._rep1;
		int rep2 = this._rep2;
		int rep3 = this._rep3;
		int state = this._state;
		byte prevByte;
		
		while(this._remainLen > 0 && curSize > 0) {
			prevByte = this.m_OutWindow.GetByte(rep0);
			this.m_OutWindow.PutByte(prevByte);
			this._remainLen--;
			curSize--;
		}
		long nowPos64 = this.m_OutWindow.GetProcessedSize();
		if (nowPos64 == 0) {
			prevByte = 0;
		} else {
			prevByte = this.m_OutWindow.GetByte(0);
		}
		
		while(curSize > 0) {
			if (this.m_RangeDecoder.bufferedStream.WasFinished())
				throw new IOException("m_RangeDecoder.bufferedStream was finised");
				// return HRESULT.S_FALSE;
			int posState = (int)nowPos64 & this.m_posStateMask;
			
			if (this.m_RangeDecoder.DecodeBit(this.m_IsMatchDecoders, (state << Base.kNumPosStatesBitsMax) + posState) == 0) {
				LiteralDecoder.Decoder2 decoder2 = this.m_LiteralDecoder.GetDecoder((int)nowPos64, prevByte);
				if (!Base.StateIsCharState(state)) {
					prevByte = decoder2.DecodeWithMatchByte(this.m_RangeDecoder, this.m_OutWindow.GetByte(rep0));
				} else {
					prevByte = decoder2.DecodeNormal(this.m_RangeDecoder);
				}
				this.m_OutWindow.PutByte(prevByte);
				state = Base.StateUpdateChar(state);
				curSize--;
				nowPos64++;
			} else {
				int len;
				if (this.m_RangeDecoder.DecodeBit(this.m_IsRepDecoders, state) == 1) {
					len = 0;
					if (this.m_RangeDecoder.DecodeBit(this.m_IsRepG0Decoders, state) == 0) {
						if (this.m_RangeDecoder.DecodeBit(this.m_IsRep0LongDecoders, (state << Base.kNumPosStatesBitsMax) + posState) == 0) {
							state = Base.StateUpdateShortRep(state);
							len = 1;
						}
					} else {
						int distance;
						if (this.m_RangeDecoder.DecodeBit(this.m_IsRepG1Decoders, state) == 0) {
							distance = rep1;
						} else {
							if (this.m_RangeDecoder.DecodeBit(this.m_IsRepG2Decoders, state) == 0) {
								distance = rep2;
							} else {
								distance = rep3;
								rep3 = rep2;
							}
							rep2 = rep1;
						}
						rep1 = rep0;
						rep0 = distance;
					}
					if (len == 0) {
						len = this.m_RepLenDecoder.Decode(this.m_RangeDecoder, posState) + Base.kMatchMinLen;
						state = Base.StateUpdateRep(state);
					}
				} else {
					rep3 = rep2;
					rep2 = rep1;
					rep1 = rep0;
					len = Base.kMatchMinLen + this.m_LenDecoder.Decode(this.m_RangeDecoder, posState);
					state = Base.StateUpdateMatch(state);
					int posSlot = this.m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(this.m_RangeDecoder);
					if (posSlot >= Base.kStartPosModelIndex) {
						int numDirectBits = (posSlot >> 1) - 1;
						rep0 = ((2 | (posSlot & 1)) << numDirectBits);
						if (posSlot < Base.kEndPosModelIndex) {
							rep0 += BitTreeDecoder.ReverseDecode(
									this.m_PosDecoders,
									rep0 - posSlot - 1,
									this.m_RangeDecoder,
									numDirectBits);
						} else {
							rep0 += (this.m_RangeDecoder.DecodeDirectBits(numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits);
							rep0 += this.m_PosAlignDecoder.ReverseDecode(this.m_RangeDecoder);
							if (rep0 < 0) {
								if (rep0 == -1)
									break;
								throw new IOException("rep0 == -1");
								// return HRESULT.S_FALSE;
							}
						}
					} else {
						rep0 = posSlot;
					}
				}
				
				if (rep0 >= nowPos64 || rep0 >= this.m_DictionarySizeCheck) {
					// m_OutWindow.Flush();
					this._remainLen = kLenIdFinished;
					throw new IOException("rep0 >= nowPos64 || rep0 >= m_DictionarySizeCheck");
					// return HRESULT.S_FALSE;
				}
				
				
				int locLen = len;
				if (len > curSize)
					locLen = curSize;
				// if (!m_OutWindow.CopyBlock(rep0, locLen))
					//    return HRESULT.S_FALSE;
				this.m_OutWindow.CopyBlock(rep0, locLen);
				prevByte = this.m_OutWindow.GetByte(0);
				curSize -= locLen;
				nowPos64 += locLen;
				len -= locLen;
				if (len != 0) {
					this._remainLen = len;
					break;
				}
			}
		}
		
		if (this.m_RangeDecoder.bufferedStream.WasFinished())
			throw new IOException("m_RangeDecoder.bufferedStream was finised");
		
		this._rep0 = rep0;
		this._rep1 = rep1;
		this._rep2 = rep2;
		this._rep3 = rep3;
		this._state = state;
	}
	
	private class LenDecoder {
		
		private final short[] m_Choice = new short[2];
		private final BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
		private final BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
		private final BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits);
		private int m_NumPosStates = 0;
		
		public LenDecoder(int numPosStates) {
			while (this.m_NumPosStates < numPosStates) {
				this.m_LowCoder[this.m_NumPosStates] = new BitTreeDecoder(Base.kNumLowLenBits);
				this.m_MidCoder[this.m_NumPosStates] = new BitTreeDecoder(Base.kNumMidLenBits);
				this.m_NumPosStates++;
			}
			SevenZip.Compression.RangeCoder.Decoder.InitBitModels(this.m_Choice);
			for (int posState = 0; posState < this.m_NumPosStates; posState++) {
				this.m_LowCoder[posState].Init();
				this.m_MidCoder[posState].Init();
			}
			this.m_HighCoder.Init();
		}
		
		public int Decode(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, int posState) throws IOException {
			if (rangeDecoder.DecodeBit(this.m_Choice, 0) == 0)
				return this.m_LowCoder[posState].Decode(rangeDecoder);
			int symbol = Base.kNumLowLenSymbols;
			if (rangeDecoder.DecodeBit(this.m_Choice, 1) == 0)
				symbol += this.m_MidCoder[posState].Decode(rangeDecoder);
			else
				symbol += Base.kNumMidLenSymbols + this.m_HighCoder.Decode(rangeDecoder);
			return symbol;
		}
	}
	
	private static class LiteralDecoder {
		
		private final Decoder2[] m_Coders;
		private final int m_NumPrevBits;
		private final int m_NumPosBits;
		private final int m_PosMask;
		
		public LiteralDecoder(int numPosBits, int numPrevBits) {
			this.m_NumPrevBits = numPrevBits;
			this.m_NumPosBits = numPosBits;
			this.m_PosMask = (1 << numPosBits) - 1;
			final int numStates = 1 << (this.m_NumPrevBits + this.m_NumPosBits);
			this.m_Coders = new Decoder2[numStates];
			for (int i = 0; i < numStates; i++)
				this.m_Coders[i] = new Decoder2();
		}
		
		private Decoder2 GetDecoder(int pos, byte prevByte) {
			final int indexHigh = (pos & this.m_PosMask) << this.m_NumPrevBits;
			final int indexLow = (prevByte & 0xFF) >>> (8 - this.m_NumPrevBits);
			return this.m_Coders[indexHigh + indexLow];
		}
		
		private static class Decoder2 {
			final short[] m_Decoders = new short[0x300];
			
			public Decoder2() {
				SevenZip.Compression.RangeCoder.Decoder.InitBitModels(this.m_Decoders);
			}
			
			public byte DecodeNormal(SevenZip.Compression.RangeCoder.Decoder rangeDecoder) throws IOException {
				int symbol = 1;
				do {
					symbol = (symbol << 1) | rangeDecoder.DecodeBit(this.m_Decoders, symbol);
				} while (symbol < 0x100);
				return (byte)symbol;
			}
			
			public byte DecodeWithMatchByte(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, byte matchByte) throws IOException {
				int symbol = 1, matchBit, bit;
				do {
					matchBit = (matchByte >> 7) & 1;
					matchByte <<= 1;
					bit = rangeDecoder.DecodeBit(this.m_Decoders, ((1 + matchBit) << 8) + symbol);
					symbol = (symbol << 1) | bit;
					if (matchBit != bit) {
						while (symbol < 0x100)
							symbol = (symbol << 1) | rangeDecoder.DecodeBit(this.m_Decoders, symbol);
						break;
					}
				} while (symbol < 0x100);
				return (byte)symbol;
			}
		}
	}
}

Zerion Mini Shell 1.0