1370b324cSopenharmony_ci// LzmaDecoder.cs
2370b324cSopenharmony_ci
3370b324cSopenharmony_ciusing System;
4370b324cSopenharmony_ci
5370b324cSopenharmony_cinamespace SevenZip.Compression.LZMA
6370b324cSopenharmony_ci{
7370b324cSopenharmony_ci	using RangeCoder;
8370b324cSopenharmony_ci
9370b324cSopenharmony_ci	public class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream
10370b324cSopenharmony_ci	{
11370b324cSopenharmony_ci		class LenDecoder
12370b324cSopenharmony_ci		{
13370b324cSopenharmony_ci			BitDecoder m_Choice = new BitDecoder();
14370b324cSopenharmony_ci			BitDecoder m_Choice2 = new BitDecoder();
15370b324cSopenharmony_ci			BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
16370b324cSopenharmony_ci			BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
17370b324cSopenharmony_ci			BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits);
18370b324cSopenharmony_ci			uint m_NumPosStates = 0;
19370b324cSopenharmony_ci
20370b324cSopenharmony_ci			public void Create(uint numPosStates)
21370b324cSopenharmony_ci			{
22370b324cSopenharmony_ci				for (uint posState = m_NumPosStates; posState < numPosStates; posState++)
23370b324cSopenharmony_ci				{
24370b324cSopenharmony_ci					m_LowCoder[posState] = new BitTreeDecoder(Base.kNumLowLenBits);
25370b324cSopenharmony_ci					m_MidCoder[posState] = new BitTreeDecoder(Base.kNumMidLenBits);
26370b324cSopenharmony_ci				}
27370b324cSopenharmony_ci				m_NumPosStates = numPosStates;
28370b324cSopenharmony_ci			}
29370b324cSopenharmony_ci
30370b324cSopenharmony_ci			public void Init()
31370b324cSopenharmony_ci			{
32370b324cSopenharmony_ci				m_Choice.Init();
33370b324cSopenharmony_ci				for (uint posState = 0; posState < m_NumPosStates; posState++)
34370b324cSopenharmony_ci				{
35370b324cSopenharmony_ci					m_LowCoder[posState].Init();
36370b324cSopenharmony_ci					m_MidCoder[posState].Init();
37370b324cSopenharmony_ci				}
38370b324cSopenharmony_ci				m_Choice2.Init();
39370b324cSopenharmony_ci				m_HighCoder.Init();
40370b324cSopenharmony_ci			}
41370b324cSopenharmony_ci
42370b324cSopenharmony_ci			public uint Decode(RangeCoder.Decoder rangeDecoder, uint posState)
43370b324cSopenharmony_ci			{
44370b324cSopenharmony_ci				if (m_Choice.Decode(rangeDecoder) == 0)
45370b324cSopenharmony_ci					return m_LowCoder[posState].Decode(rangeDecoder);
46370b324cSopenharmony_ci				else
47370b324cSopenharmony_ci				{
48370b324cSopenharmony_ci					uint symbol = Base.kNumLowLenSymbols;
49370b324cSopenharmony_ci					if (m_Choice2.Decode(rangeDecoder) == 0)
50370b324cSopenharmony_ci						symbol += m_MidCoder[posState].Decode(rangeDecoder);
51370b324cSopenharmony_ci					else
52370b324cSopenharmony_ci					{
53370b324cSopenharmony_ci						symbol += Base.kNumMidLenSymbols;
54370b324cSopenharmony_ci						symbol += m_HighCoder.Decode(rangeDecoder);
55370b324cSopenharmony_ci					}
56370b324cSopenharmony_ci					return symbol;
57370b324cSopenharmony_ci				}
58370b324cSopenharmony_ci			}
59370b324cSopenharmony_ci		}
60370b324cSopenharmony_ci
61370b324cSopenharmony_ci		class LiteralDecoder
62370b324cSopenharmony_ci		{
63370b324cSopenharmony_ci			struct Decoder2
64370b324cSopenharmony_ci			{
65370b324cSopenharmony_ci				BitDecoder[] m_Decoders;
66370b324cSopenharmony_ci				public void Create() { m_Decoders = new BitDecoder[0x300]; }
67370b324cSopenharmony_ci				public void Init() { for (int i = 0; i < 0x300; i++) m_Decoders[i].Init(); }
68370b324cSopenharmony_ci
69370b324cSopenharmony_ci				public byte DecodeNormal(RangeCoder.Decoder rangeDecoder)
70370b324cSopenharmony_ci				{
71370b324cSopenharmony_ci					uint symbol = 1;
72370b324cSopenharmony_ci					do
73370b324cSopenharmony_ci						symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder);
74370b324cSopenharmony_ci					while (symbol < 0x100);
75370b324cSopenharmony_ci					return (byte)symbol;
76370b324cSopenharmony_ci				}
77370b324cSopenharmony_ci
78370b324cSopenharmony_ci				public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, byte matchByte)
79370b324cSopenharmony_ci				{
80370b324cSopenharmony_ci					uint symbol = 1;
81370b324cSopenharmony_ci					do
82370b324cSopenharmony_ci					{
83370b324cSopenharmony_ci						uint matchBit = (uint)(matchByte >> 7) & 1;
84370b324cSopenharmony_ci						matchByte <<= 1;
85370b324cSopenharmony_ci						uint bit = m_Decoders[((1 + matchBit) << 8) + symbol].Decode(rangeDecoder);
86370b324cSopenharmony_ci						symbol = (symbol << 1) | bit;
87370b324cSopenharmony_ci						if (matchBit != bit)
88370b324cSopenharmony_ci						{
89370b324cSopenharmony_ci							while (symbol < 0x100)
90370b324cSopenharmony_ci								symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder);
91370b324cSopenharmony_ci							break;
92370b324cSopenharmony_ci						}
93370b324cSopenharmony_ci					}
94370b324cSopenharmony_ci					while (symbol < 0x100);
95370b324cSopenharmony_ci					return (byte)symbol;
96370b324cSopenharmony_ci				}
97370b324cSopenharmony_ci			}
98370b324cSopenharmony_ci
99370b324cSopenharmony_ci			Decoder2[] m_Coders;
100370b324cSopenharmony_ci			int m_NumPrevBits;
101370b324cSopenharmony_ci			int m_NumPosBits;
102370b324cSopenharmony_ci			uint m_PosMask;
103370b324cSopenharmony_ci
104370b324cSopenharmony_ci			public void Create(int numPosBits, int numPrevBits)
105370b324cSopenharmony_ci			{
106370b324cSopenharmony_ci				if (m_Coders != null && m_NumPrevBits == numPrevBits &&
107370b324cSopenharmony_ci					m_NumPosBits == numPosBits)
108370b324cSopenharmony_ci					return;
109370b324cSopenharmony_ci				m_NumPosBits = numPosBits;
110370b324cSopenharmony_ci				m_PosMask = ((uint)1 << numPosBits) - 1;
111370b324cSopenharmony_ci				m_NumPrevBits = numPrevBits;
112370b324cSopenharmony_ci				uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
113370b324cSopenharmony_ci				m_Coders = new Decoder2[numStates];
114370b324cSopenharmony_ci				for (uint i = 0; i < numStates; i++)
115370b324cSopenharmony_ci					m_Coders[i].Create();
116370b324cSopenharmony_ci			}
117370b324cSopenharmony_ci
118370b324cSopenharmony_ci			public void Init()
119370b324cSopenharmony_ci			{
120370b324cSopenharmony_ci				uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
121370b324cSopenharmony_ci				for (uint i = 0; i < numStates; i++)
122370b324cSopenharmony_ci					m_Coders[i].Init();
123370b324cSopenharmony_ci			}
124370b324cSopenharmony_ci
125370b324cSopenharmony_ci			uint GetState(uint pos, byte prevByte)
126370b324cSopenharmony_ci			{ return ((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits)); }
127370b324cSopenharmony_ci
128370b324cSopenharmony_ci			public byte DecodeNormal(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte)
129370b324cSopenharmony_ci			{ return m_Coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
130370b324cSopenharmony_ci
131370b324cSopenharmony_ci			public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte, byte matchByte)
132370b324cSopenharmony_ci			{ return m_Coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
133370b324cSopenharmony_ci		};
134370b324cSopenharmony_ci
135370b324cSopenharmony_ci		LZ.OutWindow m_OutWindow = new LZ.OutWindow();
136370b324cSopenharmony_ci		RangeCoder.Decoder m_RangeDecoder = new RangeCoder.Decoder();
137370b324cSopenharmony_ci
138370b324cSopenharmony_ci		BitDecoder[] m_IsMatchDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
139370b324cSopenharmony_ci		BitDecoder[] m_IsRepDecoders = new BitDecoder[Base.kNumStates];
140370b324cSopenharmony_ci		BitDecoder[] m_IsRepG0Decoders = new BitDecoder[Base.kNumStates];
141370b324cSopenharmony_ci		BitDecoder[] m_IsRepG1Decoders = new BitDecoder[Base.kNumStates];
142370b324cSopenharmony_ci		BitDecoder[] m_IsRepG2Decoders = new BitDecoder[Base.kNumStates];
143370b324cSopenharmony_ci		BitDecoder[] m_IsRep0LongDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
144370b324cSopenharmony_ci
145370b324cSopenharmony_ci		BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates];
146370b324cSopenharmony_ci		BitDecoder[] m_PosDecoders = new BitDecoder[Base.kNumFullDistances - Base.kEndPosModelIndex];
147370b324cSopenharmony_ci
148370b324cSopenharmony_ci		BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits);
149370b324cSopenharmony_ci
150370b324cSopenharmony_ci		LenDecoder m_LenDecoder = new LenDecoder();
151370b324cSopenharmony_ci		LenDecoder m_RepLenDecoder = new LenDecoder();
152370b324cSopenharmony_ci
153370b324cSopenharmony_ci		LiteralDecoder m_LiteralDecoder = new LiteralDecoder();
154370b324cSopenharmony_ci
155370b324cSopenharmony_ci		uint m_DictionarySize;
156370b324cSopenharmony_ci		uint m_DictionarySizeCheck;
157370b324cSopenharmony_ci
158370b324cSopenharmony_ci		uint m_PosStateMask;
159370b324cSopenharmony_ci
160370b324cSopenharmony_ci		public Decoder()
161370b324cSopenharmony_ci		{
162370b324cSopenharmony_ci			m_DictionarySize = 0xFFFFFFFF;
163370b324cSopenharmony_ci			for (int i = 0; i < Base.kNumLenToPosStates; i++)
164370b324cSopenharmony_ci				m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits);
165370b324cSopenharmony_ci		}
166370b324cSopenharmony_ci
167370b324cSopenharmony_ci		void SetDictionarySize(uint dictionarySize)
168370b324cSopenharmony_ci		{
169370b324cSopenharmony_ci			if (m_DictionarySize != dictionarySize)
170370b324cSopenharmony_ci			{
171370b324cSopenharmony_ci				m_DictionarySize = dictionarySize;
172370b324cSopenharmony_ci				m_DictionarySizeCheck = Math.Max(m_DictionarySize, 1);
173370b324cSopenharmony_ci				uint blockSize = Math.Max(m_DictionarySizeCheck, (1 << 12));
174370b324cSopenharmony_ci				m_OutWindow.Create(blockSize);
175370b324cSopenharmony_ci			}
176370b324cSopenharmony_ci		}
177370b324cSopenharmony_ci
178370b324cSopenharmony_ci		void SetLiteralProperties(int lp, int lc)
179370b324cSopenharmony_ci		{
180370b324cSopenharmony_ci			if (lp > 8)
181370b324cSopenharmony_ci				throw new InvalidParamException();
182370b324cSopenharmony_ci			if (lc > 8)
183370b324cSopenharmony_ci				throw new InvalidParamException();
184370b324cSopenharmony_ci			m_LiteralDecoder.Create(lp, lc);
185370b324cSopenharmony_ci		}
186370b324cSopenharmony_ci
187370b324cSopenharmony_ci		void SetPosBitsProperties(int pb)
188370b324cSopenharmony_ci		{
189370b324cSopenharmony_ci			if (pb > Base.kNumPosStatesBitsMax)
190370b324cSopenharmony_ci				throw new InvalidParamException();
191370b324cSopenharmony_ci			uint numPosStates = (uint)1 << pb;
192370b324cSopenharmony_ci			m_LenDecoder.Create(numPosStates);
193370b324cSopenharmony_ci			m_RepLenDecoder.Create(numPosStates);
194370b324cSopenharmony_ci			m_PosStateMask = numPosStates - 1;
195370b324cSopenharmony_ci		}
196370b324cSopenharmony_ci
197370b324cSopenharmony_ci		bool _solid = false;
198370b324cSopenharmony_ci		void Init(System.IO.Stream inStream, System.IO.Stream outStream)
199370b324cSopenharmony_ci		{
200370b324cSopenharmony_ci			m_RangeDecoder.Init(inStream);
201370b324cSopenharmony_ci			m_OutWindow.Init(outStream, _solid);
202370b324cSopenharmony_ci
203370b324cSopenharmony_ci			uint i;
204370b324cSopenharmony_ci			for (i = 0; i < Base.kNumStates; i++)
205370b324cSopenharmony_ci			{
206370b324cSopenharmony_ci				for (uint j = 0; j <= m_PosStateMask; j++)
207370b324cSopenharmony_ci				{
208370b324cSopenharmony_ci					uint index = (i << Base.kNumPosStatesBitsMax) + j;
209370b324cSopenharmony_ci					m_IsMatchDecoders[index].Init();
210370b324cSopenharmony_ci					m_IsRep0LongDecoders[index].Init();
211370b324cSopenharmony_ci				}
212370b324cSopenharmony_ci				m_IsRepDecoders[i].Init();
213370b324cSopenharmony_ci				m_IsRepG0Decoders[i].Init();
214370b324cSopenharmony_ci				m_IsRepG1Decoders[i].Init();
215370b324cSopenharmony_ci				m_IsRepG2Decoders[i].Init();
216370b324cSopenharmony_ci			}
217370b324cSopenharmony_ci
218370b324cSopenharmony_ci			m_LiteralDecoder.Init();
219370b324cSopenharmony_ci			for (i = 0; i < Base.kNumLenToPosStates; i++)
220370b324cSopenharmony_ci				m_PosSlotDecoder[i].Init();
221370b324cSopenharmony_ci			// m_PosSpecDecoder.Init();
222370b324cSopenharmony_ci			for (i = 0; i < Base.kNumFullDistances - Base.kEndPosModelIndex; i++)
223370b324cSopenharmony_ci				m_PosDecoders[i].Init();
224370b324cSopenharmony_ci
225370b324cSopenharmony_ci			m_LenDecoder.Init();
226370b324cSopenharmony_ci			m_RepLenDecoder.Init();
227370b324cSopenharmony_ci			m_PosAlignDecoder.Init();
228370b324cSopenharmony_ci		}
229370b324cSopenharmony_ci
230370b324cSopenharmony_ci		public void Code(System.IO.Stream inStream, System.IO.Stream outStream,
231370b324cSopenharmony_ci			Int64 inSize, Int64 outSize, ICodeProgress progress)
232370b324cSopenharmony_ci		{
233370b324cSopenharmony_ci			Init(inStream, outStream);
234370b324cSopenharmony_ci
235370b324cSopenharmony_ci			Base.State state = new Base.State();
236370b324cSopenharmony_ci			state.Init();
237370b324cSopenharmony_ci			uint rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
238370b324cSopenharmony_ci
239370b324cSopenharmony_ci			UInt64 nowPos64 = 0;
240370b324cSopenharmony_ci			UInt64 outSize64 = (UInt64)outSize;
241370b324cSopenharmony_ci			if (nowPos64 < outSize64)
242370b324cSopenharmony_ci			{
243370b324cSopenharmony_ci				if (m_IsMatchDecoders[state.Index << Base.kNumPosStatesBitsMax].Decode(m_RangeDecoder) != 0)
244370b324cSopenharmony_ci					throw new DataErrorException();
245370b324cSopenharmony_ci				state.UpdateChar();
246370b324cSopenharmony_ci				byte b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, 0, 0);
247370b324cSopenharmony_ci				m_OutWindow.PutByte(b);
248370b324cSopenharmony_ci				nowPos64++;
249370b324cSopenharmony_ci			}
250370b324cSopenharmony_ci			while (nowPos64 < outSize64)
251370b324cSopenharmony_ci			{
252370b324cSopenharmony_ci				// UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64);
253370b324cSopenharmony_ci					// while(nowPos64 < next)
254370b324cSopenharmony_ci				{
255370b324cSopenharmony_ci					uint posState = (uint)nowPos64 & m_PosStateMask;
256370b324cSopenharmony_ci					if (m_IsMatchDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0)
257370b324cSopenharmony_ci					{
258370b324cSopenharmony_ci						byte b;
259370b324cSopenharmony_ci						byte prevByte = m_OutWindow.GetByte(0);
260370b324cSopenharmony_ci						if (!state.IsCharState())
261370b324cSopenharmony_ci							b = m_LiteralDecoder.DecodeWithMatchByte(m_RangeDecoder,
262370b324cSopenharmony_ci								(uint)nowPos64, prevByte, m_OutWindow.GetByte(rep0));
263370b324cSopenharmony_ci						else
264370b324cSopenharmony_ci							b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, (uint)nowPos64, prevByte);
265370b324cSopenharmony_ci						m_OutWindow.PutByte(b);
266370b324cSopenharmony_ci						state.UpdateChar();
267370b324cSopenharmony_ci						nowPos64++;
268370b324cSopenharmony_ci					}
269370b324cSopenharmony_ci					else
270370b324cSopenharmony_ci					{
271370b324cSopenharmony_ci						uint len;
272370b324cSopenharmony_ci						if (m_IsRepDecoders[state.Index].Decode(m_RangeDecoder) == 1)
273370b324cSopenharmony_ci						{
274370b324cSopenharmony_ci							if (m_IsRepG0Decoders[state.Index].Decode(m_RangeDecoder) == 0)
275370b324cSopenharmony_ci							{
276370b324cSopenharmony_ci								if (m_IsRep0LongDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0)
277370b324cSopenharmony_ci								{
278370b324cSopenharmony_ci									state.UpdateShortRep();
279370b324cSopenharmony_ci									m_OutWindow.PutByte(m_OutWindow.GetByte(rep0));
280370b324cSopenharmony_ci									nowPos64++;
281370b324cSopenharmony_ci									continue;
282370b324cSopenharmony_ci								}
283370b324cSopenharmony_ci							}
284370b324cSopenharmony_ci							else
285370b324cSopenharmony_ci							{
286370b324cSopenharmony_ci								UInt32 distance;
287370b324cSopenharmony_ci								if (m_IsRepG1Decoders[state.Index].Decode(m_RangeDecoder) == 0)
288370b324cSopenharmony_ci								{
289370b324cSopenharmony_ci									distance = rep1;
290370b324cSopenharmony_ci								}
291370b324cSopenharmony_ci								else
292370b324cSopenharmony_ci								{
293370b324cSopenharmony_ci									if (m_IsRepG2Decoders[state.Index].Decode(m_RangeDecoder) == 0)
294370b324cSopenharmony_ci										distance = rep2;
295370b324cSopenharmony_ci									else
296370b324cSopenharmony_ci									{
297370b324cSopenharmony_ci										distance = rep3;
298370b324cSopenharmony_ci										rep3 = rep2;
299370b324cSopenharmony_ci									}
300370b324cSopenharmony_ci									rep2 = rep1;
301370b324cSopenharmony_ci								}
302370b324cSopenharmony_ci								rep1 = rep0;
303370b324cSopenharmony_ci								rep0 = distance;
304370b324cSopenharmony_ci							}
305370b324cSopenharmony_ci							len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen;
306370b324cSopenharmony_ci							state.UpdateRep();
307370b324cSopenharmony_ci						}
308370b324cSopenharmony_ci						else
309370b324cSopenharmony_ci						{
310370b324cSopenharmony_ci							rep3 = rep2;
311370b324cSopenharmony_ci							rep2 = rep1;
312370b324cSopenharmony_ci							rep1 = rep0;
313370b324cSopenharmony_ci							len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState);
314370b324cSopenharmony_ci							state.UpdateMatch();
315370b324cSopenharmony_ci							uint posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder);
316370b324cSopenharmony_ci							if (posSlot >= Base.kStartPosModelIndex)
317370b324cSopenharmony_ci							{
318370b324cSopenharmony_ci								int numDirectBits = (int)((posSlot >> 1) - 1);
319370b324cSopenharmony_ci								rep0 = ((2 | (posSlot & 1)) << numDirectBits);
320370b324cSopenharmony_ci								if (posSlot < Base.kEndPosModelIndex)
321370b324cSopenharmony_ci									rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders,
322370b324cSopenharmony_ci											rep0 - posSlot - 1, m_RangeDecoder, numDirectBits);
323370b324cSopenharmony_ci								else
324370b324cSopenharmony_ci								{
325370b324cSopenharmony_ci									rep0 += (m_RangeDecoder.DecodeDirectBits(
326370b324cSopenharmony_ci										numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits);
327370b324cSopenharmony_ci									rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder);
328370b324cSopenharmony_ci								}
329370b324cSopenharmony_ci							}
330370b324cSopenharmony_ci							else
331370b324cSopenharmony_ci								rep0 = posSlot;
332370b324cSopenharmony_ci						}
333370b324cSopenharmony_ci						if (rep0 >= m_OutWindow.TrainSize + nowPos64 || rep0 >= m_DictionarySizeCheck)
334370b324cSopenharmony_ci						{
335370b324cSopenharmony_ci							if (rep0 == 0xFFFFFFFF)
336370b324cSopenharmony_ci								break;
337370b324cSopenharmony_ci							throw new DataErrorException();
338370b324cSopenharmony_ci						}
339370b324cSopenharmony_ci						m_OutWindow.CopyBlock(rep0, len);
340370b324cSopenharmony_ci						nowPos64 += len;
341370b324cSopenharmony_ci					}
342370b324cSopenharmony_ci				}
343370b324cSopenharmony_ci			}
344370b324cSopenharmony_ci			m_OutWindow.Flush();
345370b324cSopenharmony_ci			m_OutWindow.ReleaseStream();
346370b324cSopenharmony_ci			m_RangeDecoder.ReleaseStream();
347370b324cSopenharmony_ci		}
348370b324cSopenharmony_ci
349370b324cSopenharmony_ci		public void SetDecoderProperties(byte[] properties)
350370b324cSopenharmony_ci		{
351370b324cSopenharmony_ci			if (properties.Length < 5)
352370b324cSopenharmony_ci				throw new InvalidParamException();
353370b324cSopenharmony_ci			int lc = properties[0] % 9;
354370b324cSopenharmony_ci			int remainder = properties[0] / 9;
355370b324cSopenharmony_ci			int lp = remainder % 5;
356370b324cSopenharmony_ci			int pb = remainder / 5;
357370b324cSopenharmony_ci			if (pb > Base.kNumPosStatesBitsMax)
358370b324cSopenharmony_ci				throw new InvalidParamException();
359370b324cSopenharmony_ci			UInt32 dictionarySize = 0;
360370b324cSopenharmony_ci			for (int i = 0; i < 4; i++)
361370b324cSopenharmony_ci				dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8);
362370b324cSopenharmony_ci			SetDictionarySize(dictionarySize);
363370b324cSopenharmony_ci			SetLiteralProperties(lp, lc);
364370b324cSopenharmony_ci			SetPosBitsProperties(pb);
365370b324cSopenharmony_ci		}
366370b324cSopenharmony_ci
367370b324cSopenharmony_ci		public bool Train(System.IO.Stream stream)
368370b324cSopenharmony_ci		{
369370b324cSopenharmony_ci			_solid = true;
370370b324cSopenharmony_ci			return m_OutWindow.Train(stream);
371370b324cSopenharmony_ci		}
372370b324cSopenharmony_ci
373370b324cSopenharmony_ci		/*
374370b324cSopenharmony_ci		public override bool CanRead { get { return true; }}
375370b324cSopenharmony_ci		public override bool CanWrite { get { return true; }}
376370b324cSopenharmony_ci		public override bool CanSeek { get { return true; }}
377370b324cSopenharmony_ci		public override long Length { get { return 0; }}
378370b324cSopenharmony_ci		public override long Position
379370b324cSopenharmony_ci		{
380370b324cSopenharmony_ci			get { return 0;	}
381370b324cSopenharmony_ci			set { }
382370b324cSopenharmony_ci		}
383370b324cSopenharmony_ci		public override void Flush() { }
384370b324cSopenharmony_ci		public override int Read(byte[] buffer, int offset, int count)
385370b324cSopenharmony_ci		{
386370b324cSopenharmony_ci			return 0;
387370b324cSopenharmony_ci		}
388370b324cSopenharmony_ci		public override void Write(byte[] buffer, int offset, int count)
389370b324cSopenharmony_ci		{
390370b324cSopenharmony_ci		}
391370b324cSopenharmony_ci		public override long Seek(long offset, System.IO.SeekOrigin origin)
392370b324cSopenharmony_ci		{
393370b324cSopenharmony_ci			return 0;
394370b324cSopenharmony_ci		}
395370b324cSopenharmony_ci		public override void SetLength(long value) {}
396370b324cSopenharmony_ci		*/
397370b324cSopenharmony_ci	}
398370b324cSopenharmony_ci}
399