tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

LzmaDecoder.cs (12075B)


      1 // LzmaDecoder.cs
      2 
      3 using System;
      4 
      5 namespace SevenZip.Compression.LZMA
      6 {
      7 using RangeCoder;
      8 
      9 public class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream
     10 {
     11 	class LenDecoder
     12 	{
     13 		BitDecoder m_Choice = new BitDecoder();
     14 		BitDecoder m_Choice2 = new BitDecoder();
     15 		BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
     16 		BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
     17 		BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits);
     18 		uint m_NumPosStates = 0;
     19 
     20 		public void Create(uint numPosStates)
     21 		{
     22 			for (uint posState = m_NumPosStates; posState < numPosStates; posState++)
     23 			{
     24 				m_LowCoder[posState] = new BitTreeDecoder(Base.kNumLowLenBits);
     25 				m_MidCoder[posState] = new BitTreeDecoder(Base.kNumMidLenBits);
     26 			}
     27 			m_NumPosStates = numPosStates;
     28 		}
     29 
     30 		public void Init()
     31 		{
     32 			m_Choice.Init();
     33 			for (uint posState = 0; posState < m_NumPosStates; posState++)
     34 			{
     35 				m_LowCoder[posState].Init();
     36 				m_MidCoder[posState].Init();
     37 			}
     38 			m_Choice2.Init();
     39 			m_HighCoder.Init();
     40 		}
     41 
     42 		public uint Decode(RangeCoder.Decoder rangeDecoder, uint posState)
     43 		{
     44 			if (m_Choice.Decode(rangeDecoder) == 0)
     45 				return m_LowCoder[posState].Decode(rangeDecoder);
     46 			else
     47 			{
     48 				uint symbol = Base.kNumLowLenSymbols;
     49 				if (m_Choice2.Decode(rangeDecoder) == 0)
     50 					symbol += m_MidCoder[posState].Decode(rangeDecoder);
     51 				else
     52 				{
     53 					symbol += Base.kNumMidLenSymbols;
     54 					symbol += m_HighCoder.Decode(rangeDecoder);
     55 				}
     56 				return symbol;
     57 			}
     58 		}
     59 	}
     60 
     61 	class LiteralDecoder
     62 	{
     63 		struct Decoder2
     64 		{
     65 			BitDecoder[] m_Decoders;
     66 			public void Create() { m_Decoders = new BitDecoder[0x300]; }
     67 			public void Init() { for (int i = 0; i < 0x300; i++) m_Decoders[i].Init(); }
     68 
     69 			public byte DecodeNormal(RangeCoder.Decoder rangeDecoder)
     70 			{
     71 				uint symbol = 1;
     72 				do
     73 					symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder);
     74 				while (symbol < 0x100);
     75 				return (byte)symbol;
     76 			}
     77 
     78 			public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, byte matchByte)
     79 			{
     80 				uint symbol = 1;
     81 				do
     82 				{
     83 					uint matchBit = (uint)(matchByte >> 7) & 1;
     84 					matchByte <<= 1;
     85 					uint bit = m_Decoders[((1 + matchBit) << 8) + symbol].Decode(rangeDecoder);
     86 					symbol = (symbol << 1) | bit;
     87 					if (matchBit != bit)
     88 					{
     89 						while (symbol < 0x100)
     90 							symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder);
     91 						break;
     92 					}
     93 				}
     94 				while (symbol < 0x100);
     95 				return (byte)symbol;
     96 			}
     97 		}
     98 
     99 		Decoder2[] m_Coders;
    100 		int m_NumPrevBits;
    101 		int m_NumPosBits;
    102 		uint m_PosMask;
    103 
    104 		public void Create(int numPosBits, int numPrevBits)
    105 		{
    106 			if (m_Coders != null && m_NumPrevBits == numPrevBits &&
    107 				m_NumPosBits == numPosBits)
    108 				return;
    109 			m_NumPosBits = numPosBits;
    110 			m_PosMask = ((uint)1 << numPosBits) - 1;
    111 			m_NumPrevBits = numPrevBits;
    112 			uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
    113 			m_Coders = new Decoder2[numStates];
    114 			for (uint i = 0; i < numStates; i++)
    115 				m_Coders[i].Create();
    116 		}
    117 
    118 		public void Init()
    119 		{
    120 			uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
    121 			for (uint i = 0; i < numStates; i++)
    122 				m_Coders[i].Init();
    123 		}
    124 
    125 		uint GetState(uint pos, byte prevByte)
    126 		{ return ((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits)); }
    127 
    128 		public byte DecodeNormal(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte)
    129 		{ return m_Coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
    130 
    131 		public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte, byte matchByte)
    132 		{ return m_Coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
    133 	};
    134 
    135 	LZ.OutWindow m_OutWindow = new LZ.OutWindow();
    136 	RangeCoder.Decoder m_RangeDecoder = new RangeCoder.Decoder();
    137 
    138 	BitDecoder[] m_IsMatchDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
    139 	BitDecoder[] m_IsRepDecoders = new BitDecoder[Base.kNumStates];
    140 	BitDecoder[] m_IsRepG0Decoders = new BitDecoder[Base.kNumStates];
    141 	BitDecoder[] m_IsRepG1Decoders = new BitDecoder[Base.kNumStates];
    142 	BitDecoder[] m_IsRepG2Decoders = new BitDecoder[Base.kNumStates];
    143 	BitDecoder[] m_IsRep0LongDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
    144 
    145 	BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates];
    146 	BitDecoder[] m_PosDecoders = new BitDecoder[Base.kNumFullDistances - Base.kEndPosModelIndex];
    147 
    148 	BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits);
    149 
    150 	LenDecoder m_LenDecoder = new LenDecoder();
    151 	LenDecoder m_RepLenDecoder = new LenDecoder();
    152 
    153 	LiteralDecoder m_LiteralDecoder = new LiteralDecoder();
    154 
    155 	uint m_DictionarySize;
    156 	uint m_DictionarySizeCheck;
    157 
    158 	uint m_PosStateMask;
    159 
    160 	public Decoder()
    161 	{
    162 		m_DictionarySize = 0xFFFFFFFF;
    163 		for (int i = 0; i < Base.kNumLenToPosStates; i++)
    164 			m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits);
    165 	}
    166 
    167 	void SetDictionarySize(uint dictionarySize)
    168 	{
    169 		if (m_DictionarySize != dictionarySize)
    170 		{
    171 			m_DictionarySize = dictionarySize;
    172 			m_DictionarySizeCheck = Math.Max(m_DictionarySize, 1);
    173 			uint blockSize = Math.Max(m_DictionarySizeCheck, (1 << 12));
    174 			m_OutWindow.Create(blockSize);
    175 		}
    176 	}
    177 
    178 	void SetLiteralProperties(int lp, int lc)
    179 	{
    180 		if (lp > 8)
    181 			throw new InvalidParamException();
    182 		if (lc > 8)
    183 			throw new InvalidParamException();
    184 		m_LiteralDecoder.Create(lp, lc);
    185 	}
    186 
    187 	void SetPosBitsProperties(int pb)
    188 	{
    189 		if (pb > Base.kNumPosStatesBitsMax)
    190 			throw new InvalidParamException();
    191 		uint numPosStates = (uint)1 << pb;
    192 		m_LenDecoder.Create(numPosStates);
    193 		m_RepLenDecoder.Create(numPosStates);
    194 		m_PosStateMask = numPosStates - 1;
    195 	}
    196 
    197 	bool _solid = false;
    198 	void Init(System.IO.Stream inStream, System.IO.Stream outStream)
    199 	{
    200 		m_RangeDecoder.Init(inStream);
    201 		m_OutWindow.Init(outStream, _solid);
    202 
    203 		uint i;
    204 		for (i = 0; i < Base.kNumStates; i++)
    205 		{
    206 			for (uint j = 0; j <= m_PosStateMask; j++)
    207 			{
    208 				uint index = (i << Base.kNumPosStatesBitsMax) + j;
    209 				m_IsMatchDecoders[index].Init();
    210 				m_IsRep0LongDecoders[index].Init();
    211 			}
    212 			m_IsRepDecoders[i].Init();
    213 			m_IsRepG0Decoders[i].Init();
    214 			m_IsRepG1Decoders[i].Init();
    215 			m_IsRepG2Decoders[i].Init();
    216 		}
    217 
    218 		m_LiteralDecoder.Init();
    219 		for (i = 0; i < Base.kNumLenToPosStates; i++)
    220 			m_PosSlotDecoder[i].Init();
    221 		// m_PosSpecDecoder.Init();
    222 		for (i = 0; i < Base.kNumFullDistances - Base.kEndPosModelIndex; i++)
    223 			m_PosDecoders[i].Init();
    224 
    225 		m_LenDecoder.Init();
    226 		m_RepLenDecoder.Init();
    227 		m_PosAlignDecoder.Init();
    228 	}
    229 
    230 	public void Code(System.IO.Stream inStream, System.IO.Stream outStream,
    231 		Int64 inSize, Int64 outSize, ICodeProgress progress)
    232 	{
    233 		Init(inStream, outStream);
    234 
    235 		Base.State state = new Base.State();
    236 		state.Init();
    237 		uint rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
    238 
    239 		UInt64 nowPos64 = 0;
    240 		UInt64 outSize64 = (UInt64)outSize;
    241 		if (nowPos64 < outSize64)
    242 		{
    243 			if (m_IsMatchDecoders[state.Index << Base.kNumPosStatesBitsMax].Decode(m_RangeDecoder) != 0)
    244 				throw new DataErrorException();
    245 			state.UpdateChar();
    246 			byte b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, 0, 0);
    247 			m_OutWindow.PutByte(b);
    248 			nowPos64++;
    249 		}
    250 		while (nowPos64 < outSize64)
    251 		{
    252 			// UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64);
    253 				// while(nowPos64 < next)
    254 			{
    255 				uint posState = (uint)nowPos64 & m_PosStateMask;
    256 				if (m_IsMatchDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0)
    257 				{
    258 					byte b;
    259 					byte prevByte = m_OutWindow.GetByte(0);
    260 					if (!state.IsCharState())
    261 						b = m_LiteralDecoder.DecodeWithMatchByte(m_RangeDecoder,
    262 							(uint)nowPos64, prevByte, m_OutWindow.GetByte(rep0));
    263 					else
    264 						b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, (uint)nowPos64, prevByte);
    265 					m_OutWindow.PutByte(b);
    266 					state.UpdateChar();
    267 					nowPos64++;
    268 				}
    269 				else
    270 				{
    271 					uint len;
    272 					if (m_IsRepDecoders[state.Index].Decode(m_RangeDecoder) == 1)
    273 					{
    274 						if (m_IsRepG0Decoders[state.Index].Decode(m_RangeDecoder) == 0)
    275 						{
    276 							if (m_IsRep0LongDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0)
    277 							{
    278 								state.UpdateShortRep();
    279 								m_OutWindow.PutByte(m_OutWindow.GetByte(rep0));
    280 								nowPos64++;
    281 								continue;
    282 							}
    283 						}
    284 						else
    285 						{
    286 							UInt32 distance;
    287 							if (m_IsRepG1Decoders[state.Index].Decode(m_RangeDecoder) == 0)
    288 							{
    289 								distance = rep1;
    290 							}
    291 							else
    292 							{
    293 								if (m_IsRepG2Decoders[state.Index].Decode(m_RangeDecoder) == 0)
    294 									distance = rep2;
    295 								else
    296 								{
    297 									distance = rep3;
    298 									rep3 = rep2;
    299 								}
    300 								rep2 = rep1;
    301 							}
    302 							rep1 = rep0;
    303 							rep0 = distance;
    304 						}
    305 						len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen;
    306 						state.UpdateRep();
    307 					}
    308 					else
    309 					{
    310 						rep3 = rep2;
    311 						rep2 = rep1;
    312 						rep1 = rep0;
    313 						len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState);
    314 						state.UpdateMatch();
    315 						uint posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder);
    316 						if (posSlot >= Base.kStartPosModelIndex)
    317 						{
    318 							int numDirectBits = (int)((posSlot >> 1) - 1);
    319 							rep0 = ((2 | (posSlot & 1)) << numDirectBits);
    320 							if (posSlot < Base.kEndPosModelIndex)
    321 								rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders,
    322 										rep0 - posSlot - 1, m_RangeDecoder, numDirectBits);
    323 							else
    324 							{
    325 								rep0 += (m_RangeDecoder.DecodeDirectBits(
    326 									numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits);
    327 								rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder);
    328 							}
    329 						}
    330 						else
    331 							rep0 = posSlot;
    332 					}
    333 					if (rep0 >= m_OutWindow.TrainSize + nowPos64 || rep0 >= m_DictionarySizeCheck)
    334 					{
    335 						if (rep0 == 0xFFFFFFFF)
    336 							break;
    337 						throw new DataErrorException();
    338 					}
    339 					m_OutWindow.CopyBlock(rep0, len);
    340 					nowPos64 += len;
    341 				}
    342 			}
    343 		}
    344 		m_OutWindow.Flush();
    345 		m_OutWindow.ReleaseStream();
    346 		m_RangeDecoder.ReleaseStream();
    347 	}
    348 
    349 	public void SetDecoderProperties(byte[] properties)
    350 	{
    351 		if (properties.Length < 5)
    352 			throw new InvalidParamException();
    353 		int lc = properties[0] % 9;
    354 		int remainder = properties[0] / 9;
    355 		int lp = remainder % 5;
    356 		int pb = remainder / 5;
    357 		if (pb > Base.kNumPosStatesBitsMax)
    358 			throw new InvalidParamException();
    359 		UInt32 dictionarySize = 0;
    360 		for (int i = 0; i < 4; i++)
    361 			dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8);
    362 		SetDictionarySize(dictionarySize);
    363 		SetLiteralProperties(lp, lc);
    364 		SetPosBitsProperties(pb);
    365 	}
    366 
    367 	public bool Train(System.IO.Stream stream)
    368 	{
    369 		_solid = true;
    370 		return m_OutWindow.Train(stream);
    371 	}
    372 
    373 	/*
    374 	public override bool CanRead { get { return true; }}
    375 	public override bool CanWrite { get { return true; }}
    376 	public override bool CanSeek { get { return true; }}
    377 	public override long Length { get { return 0; }}
    378 	public override long Position
    379 	{
    380 		get { return 0;	}
    381 		set { }
    382 	}
    383 	public override void Flush() { }
    384 	public override int Read(byte[] buffer, int offset, int count) 
    385 	{
    386 		return 0;
    387 	}
    388 	public override void Write(byte[] buffer, int offset, int count)
    389 	{
    390 	}
    391 	public override long Seek(long offset, System.IO.SeekOrigin origin)
    392 	{
    393 		return 0;
    394 	}
    395 	public override void SetLength(long value) {}
    396 	*/
    397 }
    398 }