1370b324cSopenharmony_cipackage SevenZip.Compression.LZMA;
2370b324cSopenharmony_ci
3370b324cSopenharmony_ciimport SevenZip.Compression.RangeCoder.BitTreeEncoder;
4370b324cSopenharmony_ciimport SevenZip.Compression.LZMA.Base;
5370b324cSopenharmony_ciimport SevenZip.Compression.LZ.BinTree;
6370b324cSopenharmony_ciimport SevenZip.ICodeProgress;
7370b324cSopenharmony_ciimport java.io.IOException;
8370b324cSopenharmony_ci
9370b324cSopenharmony_cipublic class Encoder
10370b324cSopenharmony_ci{
11370b324cSopenharmony_ci	public static final int EMatchFinderTypeBT2 = 0;
12370b324cSopenharmony_ci	public static final int EMatchFinderTypeBT4 = 1;
13370b324cSopenharmony_ci
14370b324cSopenharmony_ci
15370b324cSopenharmony_ci
16370b324cSopenharmony_ci
17370b324cSopenharmony_ci	static final int kIfinityPrice = 0xFFFFFFF;
18370b324cSopenharmony_ci
19370b324cSopenharmony_ci	static byte[] g_FastPos = new byte[1 << 11];
20370b324cSopenharmony_ci
21370b324cSopenharmony_ci	static
22370b324cSopenharmony_ci	{
23370b324cSopenharmony_ci		int kFastSlots = 22;
24370b324cSopenharmony_ci		int c = 2;
25370b324cSopenharmony_ci		g_FastPos[0] = 0;
26370b324cSopenharmony_ci		g_FastPos[1] = 1;
27370b324cSopenharmony_ci		for (int slotFast = 2; slotFast < kFastSlots; slotFast++)
28370b324cSopenharmony_ci		{
29370b324cSopenharmony_ci			int k = (1 << ((slotFast >> 1) - 1));
30370b324cSopenharmony_ci			for (int j = 0; j < k; j++, c++)
31370b324cSopenharmony_ci				g_FastPos[c] = (byte)slotFast;
32370b324cSopenharmony_ci		}
33370b324cSopenharmony_ci	}
34370b324cSopenharmony_ci
35370b324cSopenharmony_ci	static int GetPosSlot(int pos)
36370b324cSopenharmony_ci	{
37370b324cSopenharmony_ci		if (pos < (1 << 11))
38370b324cSopenharmony_ci			return g_FastPos[pos];
39370b324cSopenharmony_ci		if (pos < (1 << 21))
40370b324cSopenharmony_ci			return (g_FastPos[pos >> 10] + 20);
41370b324cSopenharmony_ci		return (g_FastPos[pos >> 20] + 40);
42370b324cSopenharmony_ci	}
43370b324cSopenharmony_ci
44370b324cSopenharmony_ci	static int GetPosSlot2(int pos)
45370b324cSopenharmony_ci	{
46370b324cSopenharmony_ci		if (pos < (1 << 17))
47370b324cSopenharmony_ci			return (g_FastPos[pos >> 6] + 12);
48370b324cSopenharmony_ci		if (pos < (1 << 27))
49370b324cSopenharmony_ci			return (g_FastPos[pos >> 16] + 32);
50370b324cSopenharmony_ci		return (g_FastPos[pos >> 26] + 52);
51370b324cSopenharmony_ci	}
52370b324cSopenharmony_ci
53370b324cSopenharmony_ci	int _state = Base.StateInit();
54370b324cSopenharmony_ci	byte _previousByte;
55370b324cSopenharmony_ci	int[] _repDistances = new int[Base.kNumRepDistances];
56370b324cSopenharmony_ci
57370b324cSopenharmony_ci	void BaseInit()
58370b324cSopenharmony_ci	{
59370b324cSopenharmony_ci		_state = Base.StateInit();
60370b324cSopenharmony_ci		_previousByte = 0;
61370b324cSopenharmony_ci		for (int i = 0; i < Base.kNumRepDistances; i++)
62370b324cSopenharmony_ci			_repDistances[i] = 0;
63370b324cSopenharmony_ci	}
64370b324cSopenharmony_ci
65370b324cSopenharmony_ci	static final int kDefaultDictionaryLogSize = 22;
66370b324cSopenharmony_ci	static final int kNumFastBytesDefault = 0x20;
67370b324cSopenharmony_ci
68370b324cSopenharmony_ci	class LiteralEncoder
69370b324cSopenharmony_ci	{
70370b324cSopenharmony_ci		class Encoder2
71370b324cSopenharmony_ci		{
72370b324cSopenharmony_ci			short[] m_Encoders = new short[0x300];
73370b324cSopenharmony_ci
74370b324cSopenharmony_ci			public void Init() { SevenZip.Compression.RangeCoder.Encoder.InitBitModels(m_Encoders); }
75370b324cSopenharmony_ci
76370b324cSopenharmony_ci
77370b324cSopenharmony_ci
78370b324cSopenharmony_ci			public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, byte symbol) throws IOException
79370b324cSopenharmony_ci			{
80370b324cSopenharmony_ci				int context = 1;
81370b324cSopenharmony_ci				for (int i = 7; i >= 0; i--)
82370b324cSopenharmony_ci				{
83370b324cSopenharmony_ci					int bit = ((symbol >> i) & 1);
84370b324cSopenharmony_ci					rangeEncoder.Encode(m_Encoders, context, bit);
85370b324cSopenharmony_ci					context = (context << 1) | bit;
86370b324cSopenharmony_ci				}
87370b324cSopenharmony_ci			}
88370b324cSopenharmony_ci
89370b324cSopenharmony_ci			public void EncodeMatched(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, byte matchByte, byte symbol) throws IOException
90370b324cSopenharmony_ci			{
91370b324cSopenharmony_ci				int context = 1;
92370b324cSopenharmony_ci				boolean same = true;
93370b324cSopenharmony_ci				for (int i = 7; i >= 0; i--)
94370b324cSopenharmony_ci				{
95370b324cSopenharmony_ci					int bit = ((symbol >> i) & 1);
96370b324cSopenharmony_ci					int state = context;
97370b324cSopenharmony_ci					if (same)
98370b324cSopenharmony_ci					{
99370b324cSopenharmony_ci						int matchBit = ((matchByte >> i) & 1);
100370b324cSopenharmony_ci						state += ((1 + matchBit) << 8);
101370b324cSopenharmony_ci						same = (matchBit == bit);
102370b324cSopenharmony_ci					}
103370b324cSopenharmony_ci					rangeEncoder.Encode(m_Encoders, state, bit);
104370b324cSopenharmony_ci					context = (context << 1) | bit;
105370b324cSopenharmony_ci				}
106370b324cSopenharmony_ci			}
107370b324cSopenharmony_ci
108370b324cSopenharmony_ci			public int GetPrice(boolean matchMode, byte matchByte, byte symbol)
109370b324cSopenharmony_ci			{
110370b324cSopenharmony_ci				int price = 0;
111370b324cSopenharmony_ci				int context = 1;
112370b324cSopenharmony_ci				int i = 7;
113370b324cSopenharmony_ci				if (matchMode)
114370b324cSopenharmony_ci				{
115370b324cSopenharmony_ci					for (; i >= 0; i--)
116370b324cSopenharmony_ci					{
117370b324cSopenharmony_ci						int matchBit = (matchByte >> i) & 1;
118370b324cSopenharmony_ci						int bit = (symbol >> i) & 1;
119370b324cSopenharmony_ci						price += SevenZip.Compression.RangeCoder.Encoder.GetPrice(m_Encoders[((1 + matchBit) << 8) + context], bit);
120370b324cSopenharmony_ci						context = (context << 1) | bit;
121370b324cSopenharmony_ci						if (matchBit != bit)
122370b324cSopenharmony_ci						{
123370b324cSopenharmony_ci							i--;
124370b324cSopenharmony_ci							break;
125370b324cSopenharmony_ci						}
126370b324cSopenharmony_ci					}
127370b324cSopenharmony_ci				}
128370b324cSopenharmony_ci				for (; i >= 0; i--)
129370b324cSopenharmony_ci				{
130370b324cSopenharmony_ci					int bit = (symbol >> i) & 1;
131370b324cSopenharmony_ci					price += SevenZip.Compression.RangeCoder.Encoder.GetPrice(m_Encoders[context], bit);
132370b324cSopenharmony_ci					context = (context << 1) | bit;
133370b324cSopenharmony_ci				}
134370b324cSopenharmony_ci				return price;
135370b324cSopenharmony_ci			}
136370b324cSopenharmony_ci		}
137370b324cSopenharmony_ci
138370b324cSopenharmony_ci		Encoder2[] m_Coders;
139370b324cSopenharmony_ci		int m_NumPrevBits;
140370b324cSopenharmony_ci		int m_NumPosBits;
141370b324cSopenharmony_ci		int m_PosMask;
142370b324cSopenharmony_ci
143370b324cSopenharmony_ci		public void Create(int numPosBits, int numPrevBits)
144370b324cSopenharmony_ci		{
145370b324cSopenharmony_ci			if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits)
146370b324cSopenharmony_ci				return;
147370b324cSopenharmony_ci			m_NumPosBits = numPosBits;
148370b324cSopenharmony_ci			m_PosMask = (1 << numPosBits) - 1;
149370b324cSopenharmony_ci			m_NumPrevBits = numPrevBits;
150370b324cSopenharmony_ci			int numStates = 1 << (m_NumPrevBits + m_NumPosBits);
151370b324cSopenharmony_ci			m_Coders = new Encoder2[numStates];
152370b324cSopenharmony_ci			for (int i = 0; i < numStates; i++)
153370b324cSopenharmony_ci				m_Coders[i] = new Encoder2();
154370b324cSopenharmony_ci		}
155370b324cSopenharmony_ci
156370b324cSopenharmony_ci		public void Init()
157370b324cSopenharmony_ci		{
158370b324cSopenharmony_ci			int numStates = 1 << (m_NumPrevBits + m_NumPosBits);
159370b324cSopenharmony_ci			for (int i = 0; i < numStates; i++)
160370b324cSopenharmony_ci				m_Coders[i].Init();
161370b324cSopenharmony_ci		}
162370b324cSopenharmony_ci
163370b324cSopenharmony_ci		public Encoder2 GetSubCoder(int pos, byte prevByte)
164370b324cSopenharmony_ci		{ return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + ((prevByte & 0xFF) >>> (8 - m_NumPrevBits))]; }
165370b324cSopenharmony_ci	}
166370b324cSopenharmony_ci
167370b324cSopenharmony_ci	class LenEncoder
168370b324cSopenharmony_ci	{
169370b324cSopenharmony_ci		short[] _choice = new short[2];
170370b324cSopenharmony_ci		BitTreeEncoder[] _lowCoder = new BitTreeEncoder[Base.kNumPosStatesEncodingMax];
171370b324cSopenharmony_ci		BitTreeEncoder[] _midCoder = new BitTreeEncoder[Base.kNumPosStatesEncodingMax];
172370b324cSopenharmony_ci		BitTreeEncoder _highCoder = new BitTreeEncoder(Base.kNumHighLenBits);
173370b324cSopenharmony_ci
174370b324cSopenharmony_ci
175370b324cSopenharmony_ci		public LenEncoder()
176370b324cSopenharmony_ci		{
177370b324cSopenharmony_ci			for (int posState = 0; posState < Base.kNumPosStatesEncodingMax; posState++)
178370b324cSopenharmony_ci			{
179370b324cSopenharmony_ci				_lowCoder[posState] = new BitTreeEncoder(Base.kNumLowLenBits);
180370b324cSopenharmony_ci				_midCoder[posState] = new BitTreeEncoder(Base.kNumMidLenBits);
181370b324cSopenharmony_ci			}
182370b324cSopenharmony_ci		}
183370b324cSopenharmony_ci
184370b324cSopenharmony_ci		public void Init(int numPosStates)
185370b324cSopenharmony_ci		{
186370b324cSopenharmony_ci			SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_choice);
187370b324cSopenharmony_ci
188370b324cSopenharmony_ci			for (int posState = 0; posState < numPosStates; posState++)
189370b324cSopenharmony_ci			{
190370b324cSopenharmony_ci				_lowCoder[posState].Init();
191370b324cSopenharmony_ci				_midCoder[posState].Init();
192370b324cSopenharmony_ci			}
193370b324cSopenharmony_ci			_highCoder.Init();
194370b324cSopenharmony_ci		}
195370b324cSopenharmony_ci
196370b324cSopenharmony_ci		public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, int symbol, int posState) throws IOException
197370b324cSopenharmony_ci		{
198370b324cSopenharmony_ci			if (symbol < Base.kNumLowLenSymbols)
199370b324cSopenharmony_ci			{
200370b324cSopenharmony_ci				rangeEncoder.Encode(_choice, 0, 0);
201370b324cSopenharmony_ci				_lowCoder[posState].Encode(rangeEncoder, symbol);
202370b324cSopenharmony_ci			}
203370b324cSopenharmony_ci			else
204370b324cSopenharmony_ci			{
205370b324cSopenharmony_ci				symbol -= Base.kNumLowLenSymbols;
206370b324cSopenharmony_ci				rangeEncoder.Encode(_choice, 0, 1);
207370b324cSopenharmony_ci				if (symbol < Base.kNumMidLenSymbols)
208370b324cSopenharmony_ci				{
209370b324cSopenharmony_ci					rangeEncoder.Encode(_choice, 1, 0);
210370b324cSopenharmony_ci					_midCoder[posState].Encode(rangeEncoder, symbol);
211370b324cSopenharmony_ci				}
212370b324cSopenharmony_ci				else
213370b324cSopenharmony_ci				{
214370b324cSopenharmony_ci					rangeEncoder.Encode(_choice, 1, 1);
215370b324cSopenharmony_ci					_highCoder.Encode(rangeEncoder, symbol - Base.kNumMidLenSymbols);
216370b324cSopenharmony_ci				}
217370b324cSopenharmony_ci			}
218370b324cSopenharmony_ci		}
219370b324cSopenharmony_ci
220370b324cSopenharmony_ci		public void SetPrices(int posState, int numSymbols, int[] prices, int st)
221370b324cSopenharmony_ci		{
222370b324cSopenharmony_ci			int a0 = SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_choice[0]);
223370b324cSopenharmony_ci			int a1 = SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_choice[0]);
224370b324cSopenharmony_ci			int b0 = a1 + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_choice[1]);
225370b324cSopenharmony_ci			int b1 = a1 + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_choice[1]);
226370b324cSopenharmony_ci			int i = 0;
227370b324cSopenharmony_ci			for (i = 0; i < Base.kNumLowLenSymbols; i++)
228370b324cSopenharmony_ci			{
229370b324cSopenharmony_ci				if (i >= numSymbols)
230370b324cSopenharmony_ci					return;
231370b324cSopenharmony_ci				prices[st + i] = a0 + _lowCoder[posState].GetPrice(i);
232370b324cSopenharmony_ci			}
233370b324cSopenharmony_ci			for (; i < Base.kNumLowLenSymbols + Base.kNumMidLenSymbols; i++)
234370b324cSopenharmony_ci			{
235370b324cSopenharmony_ci				if (i >= numSymbols)
236370b324cSopenharmony_ci					return;
237370b324cSopenharmony_ci				prices[st + i] = b0 + _midCoder[posState].GetPrice(i - Base.kNumLowLenSymbols);
238370b324cSopenharmony_ci			}
239370b324cSopenharmony_ci			for (; i < numSymbols; i++)
240370b324cSopenharmony_ci				prices[st + i] = b1 + _highCoder.GetPrice(i - Base.kNumLowLenSymbols - Base.kNumMidLenSymbols);
241370b324cSopenharmony_ci		}
242370b324cSopenharmony_ci	};
243370b324cSopenharmony_ci
244370b324cSopenharmony_ci	public static final int kNumLenSpecSymbols = Base.kNumLowLenSymbols + Base.kNumMidLenSymbols;
245370b324cSopenharmony_ci
246370b324cSopenharmony_ci	class LenPriceTableEncoder extends LenEncoder
247370b324cSopenharmony_ci	{
248370b324cSopenharmony_ci		int[] _prices = new int[Base.kNumLenSymbols<<Base.kNumPosStatesBitsEncodingMax];
249370b324cSopenharmony_ci		int _tableSize;
250370b324cSopenharmony_ci		int[] _counters = new int[Base.kNumPosStatesEncodingMax];
251370b324cSopenharmony_ci
252370b324cSopenharmony_ci		public void SetTableSize(int tableSize) { _tableSize = tableSize; }
253370b324cSopenharmony_ci
254370b324cSopenharmony_ci		public int GetPrice(int symbol, int posState)
255370b324cSopenharmony_ci		{
256370b324cSopenharmony_ci			return _prices[posState * Base.kNumLenSymbols + symbol];
257370b324cSopenharmony_ci		}
258370b324cSopenharmony_ci
259370b324cSopenharmony_ci		void UpdateTable(int posState)
260370b324cSopenharmony_ci		{
261370b324cSopenharmony_ci			SetPrices(posState, _tableSize, _prices, posState * Base.kNumLenSymbols);
262370b324cSopenharmony_ci			_counters[posState] = _tableSize;
263370b324cSopenharmony_ci		}
264370b324cSopenharmony_ci
265370b324cSopenharmony_ci		public void UpdateTables(int numPosStates)
266370b324cSopenharmony_ci		{
267370b324cSopenharmony_ci			for (int posState = 0; posState < numPosStates; posState++)
268370b324cSopenharmony_ci				UpdateTable(posState);
269370b324cSopenharmony_ci		}
270370b324cSopenharmony_ci
271370b324cSopenharmony_ci		public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, int symbol, int posState) throws IOException
272370b324cSopenharmony_ci		{
273370b324cSopenharmony_ci			super.Encode(rangeEncoder, symbol, posState);
274370b324cSopenharmony_ci			if (--_counters[posState] == 0)
275370b324cSopenharmony_ci				UpdateTable(posState);
276370b324cSopenharmony_ci		}
277370b324cSopenharmony_ci	}
278370b324cSopenharmony_ci
279370b324cSopenharmony_ci	static final int kNumOpts = 1 << 12;
280370b324cSopenharmony_ci	class Optimal
281370b324cSopenharmony_ci	{
282370b324cSopenharmony_ci		public int State;
283370b324cSopenharmony_ci
284370b324cSopenharmony_ci		public boolean Prev1IsChar;
285370b324cSopenharmony_ci		public boolean Prev2;
286370b324cSopenharmony_ci
287370b324cSopenharmony_ci		public int PosPrev2;
288370b324cSopenharmony_ci		public int BackPrev2;
289370b324cSopenharmony_ci
290370b324cSopenharmony_ci		public int Price;
291370b324cSopenharmony_ci		public int PosPrev;
292370b324cSopenharmony_ci		public int BackPrev;
293370b324cSopenharmony_ci
294370b324cSopenharmony_ci		public int Backs0;
295370b324cSopenharmony_ci		public int Backs1;
296370b324cSopenharmony_ci		public int Backs2;
297370b324cSopenharmony_ci		public int Backs3;
298370b324cSopenharmony_ci
299370b324cSopenharmony_ci		public void MakeAsChar() { BackPrev = -1; Prev1IsChar = false; }
300370b324cSopenharmony_ci		public void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; }
301370b324cSopenharmony_ci		public boolean IsShortRep() { return (BackPrev == 0); }
302370b324cSopenharmony_ci	};
303370b324cSopenharmony_ci	Optimal[] _optimum = new Optimal[kNumOpts];
304370b324cSopenharmony_ci	SevenZip.Compression.LZ.BinTree _matchFinder = null;
305370b324cSopenharmony_ci	SevenZip.Compression.RangeCoder.Encoder _rangeEncoder = new SevenZip.Compression.RangeCoder.Encoder();
306370b324cSopenharmony_ci
307370b324cSopenharmony_ci	short[] _isMatch = new short[Base.kNumStates<<Base.kNumPosStatesBitsMax];
308370b324cSopenharmony_ci	short[] _isRep = new short[Base.kNumStates];
309370b324cSopenharmony_ci	short[] _isRepG0 = new short[Base.kNumStates];
310370b324cSopenharmony_ci	short[] _isRepG1 = new short[Base.kNumStates];
311370b324cSopenharmony_ci	short[] _isRepG2 = new short[Base.kNumStates];
312370b324cSopenharmony_ci	short[] _isRep0Long = new short[Base.kNumStates<<Base.kNumPosStatesBitsMax];
313370b324cSopenharmony_ci
314370b324cSopenharmony_ci	BitTreeEncoder[] _posSlotEncoder = new BitTreeEncoder[Base.kNumLenToPosStates]; // kNumPosSlotBits
315370b324cSopenharmony_ci
316370b324cSopenharmony_ci	short[] _posEncoders = new short[Base.kNumFullDistances-Base.kEndPosModelIndex];
317370b324cSopenharmony_ci	BitTreeEncoder _posAlignEncoder = new BitTreeEncoder(Base.kNumAlignBits);
318370b324cSopenharmony_ci
319370b324cSopenharmony_ci	LenPriceTableEncoder _lenEncoder = new LenPriceTableEncoder();
320370b324cSopenharmony_ci	LenPriceTableEncoder _repMatchLenEncoder = new LenPriceTableEncoder();
321370b324cSopenharmony_ci
322370b324cSopenharmony_ci	LiteralEncoder _literalEncoder = new LiteralEncoder();
323370b324cSopenharmony_ci
324370b324cSopenharmony_ci	int[] _matchDistances = new int[Base.kMatchMaxLen*2+2];
325370b324cSopenharmony_ci
326370b324cSopenharmony_ci	int _numFastBytes = kNumFastBytesDefault;
327370b324cSopenharmony_ci	int _longestMatchLength;
328370b324cSopenharmony_ci	int _numDistancePairs;
329370b324cSopenharmony_ci
330370b324cSopenharmony_ci	int _additionalOffset;
331370b324cSopenharmony_ci
332370b324cSopenharmony_ci	int _optimumEndIndex;
333370b324cSopenharmony_ci	int _optimumCurrentIndex;
334370b324cSopenharmony_ci
335370b324cSopenharmony_ci	boolean _longestMatchWasFound;
336370b324cSopenharmony_ci
337370b324cSopenharmony_ci	int[] _posSlotPrices = new int[1<<(Base.kNumPosSlotBits+Base.kNumLenToPosStatesBits)];
338370b324cSopenharmony_ci	int[] _distancesPrices = new int[Base.kNumFullDistances<<Base.kNumLenToPosStatesBits];
339370b324cSopenharmony_ci	int[] _alignPrices = new int[Base.kAlignTableSize];
340370b324cSopenharmony_ci	int _alignPriceCount;
341370b324cSopenharmony_ci
342370b324cSopenharmony_ci	int _distTableSize = (kDefaultDictionaryLogSize * 2);
343370b324cSopenharmony_ci
344370b324cSopenharmony_ci	int _posStateBits = 2;
345370b324cSopenharmony_ci	int _posStateMask = (4 - 1);
346370b324cSopenharmony_ci	int _numLiteralPosStateBits = 0;
347370b324cSopenharmony_ci	int _numLiteralContextBits = 3;
348370b324cSopenharmony_ci
349370b324cSopenharmony_ci	int _dictionarySize = (1 << kDefaultDictionaryLogSize);
350370b324cSopenharmony_ci	int _dictionarySizePrev = -1;
351370b324cSopenharmony_ci	int _numFastBytesPrev = -1;
352370b324cSopenharmony_ci
353370b324cSopenharmony_ci	long nowPos64;
354370b324cSopenharmony_ci	boolean _finished;
355370b324cSopenharmony_ci	java.io.InputStream _inStream;
356370b324cSopenharmony_ci
357370b324cSopenharmony_ci	int _matchFinderType = EMatchFinderTypeBT4;
358370b324cSopenharmony_ci	boolean _writeEndMark = false;
359370b324cSopenharmony_ci
360370b324cSopenharmony_ci	boolean _needReleaseMFStream = false;
361370b324cSopenharmony_ci
362370b324cSopenharmony_ci	void Create()
363370b324cSopenharmony_ci	{
364370b324cSopenharmony_ci		if (_matchFinder == null)
365370b324cSopenharmony_ci		{
366370b324cSopenharmony_ci			SevenZip.Compression.LZ.BinTree bt = new SevenZip.Compression.LZ.BinTree();
367370b324cSopenharmony_ci			int numHashBytes = 4;
368370b324cSopenharmony_ci			if (_matchFinderType == EMatchFinderTypeBT2)
369370b324cSopenharmony_ci				numHashBytes = 2;
370370b324cSopenharmony_ci			bt.SetType(numHashBytes);
371370b324cSopenharmony_ci			_matchFinder = bt;
372370b324cSopenharmony_ci		}
373370b324cSopenharmony_ci		_literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits);
374370b324cSopenharmony_ci
375370b324cSopenharmony_ci		if (_dictionarySize == _dictionarySizePrev && _numFastBytesPrev == _numFastBytes)
376370b324cSopenharmony_ci			return;
377370b324cSopenharmony_ci		_matchFinder.Create(_dictionarySize, kNumOpts, _numFastBytes, Base.kMatchMaxLen + 1);
378370b324cSopenharmony_ci		_dictionarySizePrev = _dictionarySize;
379370b324cSopenharmony_ci		_numFastBytesPrev = _numFastBytes;
380370b324cSopenharmony_ci	}
381370b324cSopenharmony_ci
382370b324cSopenharmony_ci	public Encoder()
383370b324cSopenharmony_ci	{
384370b324cSopenharmony_ci		for (int i = 0; i < kNumOpts; i++)
385370b324cSopenharmony_ci			_optimum[i] = new Optimal();
386370b324cSopenharmony_ci		for (int i = 0; i < Base.kNumLenToPosStates; i++)
387370b324cSopenharmony_ci			_posSlotEncoder[i] = new BitTreeEncoder(Base.kNumPosSlotBits);
388370b324cSopenharmony_ci	}
389370b324cSopenharmony_ci
390370b324cSopenharmony_ci	void SetWriteEndMarkerMode(boolean writeEndMarker)
391370b324cSopenharmony_ci	{
392370b324cSopenharmony_ci		_writeEndMark = writeEndMarker;
393370b324cSopenharmony_ci	}
394370b324cSopenharmony_ci
395370b324cSopenharmony_ci	void Init()
396370b324cSopenharmony_ci	{
397370b324cSopenharmony_ci		BaseInit();
398370b324cSopenharmony_ci		_rangeEncoder.Init();
399370b324cSopenharmony_ci
400370b324cSopenharmony_ci		SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isMatch);
401370b324cSopenharmony_ci		SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRep0Long);
402370b324cSopenharmony_ci		SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRep);
403370b324cSopenharmony_ci		SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRepG0);
404370b324cSopenharmony_ci		SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRepG1);
405370b324cSopenharmony_ci		SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRepG2);
406370b324cSopenharmony_ci		SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_posEncoders);
407370b324cSopenharmony_ci
408370b324cSopenharmony_ci
409370b324cSopenharmony_ci
410370b324cSopenharmony_ci
411370b324cSopenharmony_ci
412370b324cSopenharmony_ci
413370b324cSopenharmony_ci
414370b324cSopenharmony_ci		_literalEncoder.Init();
415370b324cSopenharmony_ci		for (int i = 0; i < Base.kNumLenToPosStates; i++)
416370b324cSopenharmony_ci			_posSlotEncoder[i].Init();
417370b324cSopenharmony_ci
418370b324cSopenharmony_ci
419370b324cSopenharmony_ci
420370b324cSopenharmony_ci		_lenEncoder.Init(1 << _posStateBits);
421370b324cSopenharmony_ci		_repMatchLenEncoder.Init(1 << _posStateBits);
422370b324cSopenharmony_ci
423370b324cSopenharmony_ci		_posAlignEncoder.Init();
424370b324cSopenharmony_ci
425370b324cSopenharmony_ci		_longestMatchWasFound = false;
426370b324cSopenharmony_ci		_optimumEndIndex = 0;
427370b324cSopenharmony_ci		_optimumCurrentIndex = 0;
428370b324cSopenharmony_ci		_additionalOffset = 0;
429370b324cSopenharmony_ci	}
430370b324cSopenharmony_ci
431370b324cSopenharmony_ci	int ReadMatchDistances() throws java.io.IOException
432370b324cSopenharmony_ci	{
433370b324cSopenharmony_ci		int lenRes = 0;
434370b324cSopenharmony_ci		_numDistancePairs = _matchFinder.GetMatches(_matchDistances);
435370b324cSopenharmony_ci		if (_numDistancePairs > 0)
436370b324cSopenharmony_ci		{
437370b324cSopenharmony_ci			lenRes = _matchDistances[_numDistancePairs - 2];
438370b324cSopenharmony_ci			if (lenRes == _numFastBytes)
439370b324cSopenharmony_ci				lenRes += _matchFinder.GetMatchLen((int)lenRes - 1, _matchDistances[_numDistancePairs - 1],
440370b324cSopenharmony_ci					Base.kMatchMaxLen - lenRes);
441370b324cSopenharmony_ci		}
442370b324cSopenharmony_ci		_additionalOffset++;
443370b324cSopenharmony_ci		return lenRes;
444370b324cSopenharmony_ci	}
445370b324cSopenharmony_ci
446370b324cSopenharmony_ci	void MovePos(int num) throws java.io.IOException
447370b324cSopenharmony_ci	{
448370b324cSopenharmony_ci		if (num > 0)
449370b324cSopenharmony_ci		{
450370b324cSopenharmony_ci			_matchFinder.Skip(num);
451370b324cSopenharmony_ci			_additionalOffset += num;
452370b324cSopenharmony_ci		}
453370b324cSopenharmony_ci	}
454370b324cSopenharmony_ci
455370b324cSopenharmony_ci	int GetRepLen1Price(int state, int posState)
456370b324cSopenharmony_ci	{
457370b324cSopenharmony_ci		return SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRepG0[state]) +
458370b324cSopenharmony_ci				SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRep0Long[(state << Base.kNumPosStatesBitsMax) + posState]);
459370b324cSopenharmony_ci	}
460370b324cSopenharmony_ci
461370b324cSopenharmony_ci	int GetPureRepPrice(int repIndex, int state, int posState)
462370b324cSopenharmony_ci	{
463370b324cSopenharmony_ci		int price;
464370b324cSopenharmony_ci		if (repIndex == 0)
465370b324cSopenharmony_ci		{
466370b324cSopenharmony_ci			price = SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRepG0[state]);
467370b324cSopenharmony_ci			price += SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep0Long[(state << Base.kNumPosStatesBitsMax) + posState]);
468370b324cSopenharmony_ci		}
469370b324cSopenharmony_ci		else
470370b324cSopenharmony_ci		{
471370b324cSopenharmony_ci			price = SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRepG0[state]);
472370b324cSopenharmony_ci			if (repIndex == 1)
473370b324cSopenharmony_ci				price += SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRepG1[state]);
474370b324cSopenharmony_ci			else
475370b324cSopenharmony_ci			{
476370b324cSopenharmony_ci				price += SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRepG1[state]);
477370b324cSopenharmony_ci				price += SevenZip.Compression.RangeCoder.Encoder.GetPrice(_isRepG2[state], repIndex - 2);
478370b324cSopenharmony_ci			}
479370b324cSopenharmony_ci		}
480370b324cSopenharmony_ci		return price;
481370b324cSopenharmony_ci	}
482370b324cSopenharmony_ci
483370b324cSopenharmony_ci	int GetRepPrice(int repIndex, int len, int state, int posState)
484370b324cSopenharmony_ci	{
485370b324cSopenharmony_ci		int price = _repMatchLenEncoder.GetPrice(len - Base.kMatchMinLen, posState);
486370b324cSopenharmony_ci		return price + GetPureRepPrice(repIndex, state, posState);
487370b324cSopenharmony_ci	}
488370b324cSopenharmony_ci
489370b324cSopenharmony_ci	int GetPosLenPrice(int pos, int len, int posState)
490370b324cSopenharmony_ci	{
491370b324cSopenharmony_ci		int price;
492370b324cSopenharmony_ci		int lenToPosState = Base.GetLenToPosState(len);
493370b324cSopenharmony_ci		if (pos < Base.kNumFullDistances)
494370b324cSopenharmony_ci			price = _distancesPrices[(lenToPosState * Base.kNumFullDistances) + pos];
495370b324cSopenharmony_ci		else
496370b324cSopenharmony_ci			price = _posSlotPrices[(lenToPosState << Base.kNumPosSlotBits) + GetPosSlot2(pos)] +
497370b324cSopenharmony_ci				_alignPrices[pos & Base.kAlignMask];
498370b324cSopenharmony_ci		return price + _lenEncoder.GetPrice(len - Base.kMatchMinLen, posState);
499370b324cSopenharmony_ci	}
500370b324cSopenharmony_ci
501370b324cSopenharmony_ci	int Backward(int cur)
502370b324cSopenharmony_ci	{
503370b324cSopenharmony_ci		_optimumEndIndex = cur;
504370b324cSopenharmony_ci		int posMem = _optimum[cur].PosPrev;
505370b324cSopenharmony_ci		int backMem = _optimum[cur].BackPrev;
506370b324cSopenharmony_ci		do
507370b324cSopenharmony_ci		{
508370b324cSopenharmony_ci			if (_optimum[cur].Prev1IsChar)
509370b324cSopenharmony_ci			{
510370b324cSopenharmony_ci				_optimum[posMem].MakeAsChar();
511370b324cSopenharmony_ci				_optimum[posMem].PosPrev = posMem - 1;
512370b324cSopenharmony_ci				if (_optimum[cur].Prev2)
513370b324cSopenharmony_ci				{
514370b324cSopenharmony_ci					_optimum[posMem - 1].Prev1IsChar = false;
515370b324cSopenharmony_ci					_optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2;
516370b324cSopenharmony_ci					_optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2;
517370b324cSopenharmony_ci				}
518370b324cSopenharmony_ci			}
519370b324cSopenharmony_ci			int posPrev = posMem;
520370b324cSopenharmony_ci			int backCur = backMem;
521370b324cSopenharmony_ci
522370b324cSopenharmony_ci			backMem = _optimum[posPrev].BackPrev;
523370b324cSopenharmony_ci			posMem = _optimum[posPrev].PosPrev;
524370b324cSopenharmony_ci
525370b324cSopenharmony_ci			_optimum[posPrev].BackPrev = backCur;
526370b324cSopenharmony_ci			_optimum[posPrev].PosPrev = cur;
527370b324cSopenharmony_ci			cur = posPrev;
528370b324cSopenharmony_ci		}
529370b324cSopenharmony_ci		while (cur > 0);
530370b324cSopenharmony_ci		backRes = _optimum[0].BackPrev;
531370b324cSopenharmony_ci		_optimumCurrentIndex = _optimum[0].PosPrev;
532370b324cSopenharmony_ci		return _optimumCurrentIndex;
533370b324cSopenharmony_ci	}
534370b324cSopenharmony_ci
535370b324cSopenharmony_ci	int[] reps = new int[Base.kNumRepDistances];
536370b324cSopenharmony_ci	int[] repLens = new int[Base.kNumRepDistances];
537370b324cSopenharmony_ci	int backRes;
538370b324cSopenharmony_ci
539370b324cSopenharmony_ci	int GetOptimum(int position) throws IOException
540370b324cSopenharmony_ci	{
541370b324cSopenharmony_ci		if (_optimumEndIndex != _optimumCurrentIndex)
542370b324cSopenharmony_ci		{
543370b324cSopenharmony_ci			int lenRes = _optimum[_optimumCurrentIndex].PosPrev - _optimumCurrentIndex;
544370b324cSopenharmony_ci			backRes = _optimum[_optimumCurrentIndex].BackPrev;
545370b324cSopenharmony_ci			_optimumCurrentIndex = _optimum[_optimumCurrentIndex].PosPrev;
546370b324cSopenharmony_ci			return lenRes;
547370b324cSopenharmony_ci		}
548370b324cSopenharmony_ci		_optimumCurrentIndex = _optimumEndIndex = 0;
549370b324cSopenharmony_ci
550370b324cSopenharmony_ci		int lenMain, numDistancePairs;
551370b324cSopenharmony_ci		if (!_longestMatchWasFound)
552370b324cSopenharmony_ci		{
553370b324cSopenharmony_ci			lenMain = ReadMatchDistances();
554370b324cSopenharmony_ci		}
555370b324cSopenharmony_ci		else
556370b324cSopenharmony_ci		{
557370b324cSopenharmony_ci			lenMain = _longestMatchLength;
558370b324cSopenharmony_ci			_longestMatchWasFound = false;
559370b324cSopenharmony_ci		}
560370b324cSopenharmony_ci		numDistancePairs = _numDistancePairs;
561370b324cSopenharmony_ci
562370b324cSopenharmony_ci		int numAvailableBytes = _matchFinder.GetNumAvailableBytes() + 1;
563370b324cSopenharmony_ci		if (numAvailableBytes < 2)
564370b324cSopenharmony_ci		{
565370b324cSopenharmony_ci			backRes = -1;
566370b324cSopenharmony_ci			return 1;
567370b324cSopenharmony_ci		}
568370b324cSopenharmony_ci		if (numAvailableBytes > Base.kMatchMaxLen)
569370b324cSopenharmony_ci			numAvailableBytes = Base.kMatchMaxLen;
570370b324cSopenharmony_ci
571370b324cSopenharmony_ci		int repMaxIndex = 0;
572370b324cSopenharmony_ci		int i;
573370b324cSopenharmony_ci		for (i = 0; i < Base.kNumRepDistances; i++)
574370b324cSopenharmony_ci		{
575370b324cSopenharmony_ci			reps[i] = _repDistances[i];
576370b324cSopenharmony_ci			repLens[i] = _matchFinder.GetMatchLen(0 - 1, reps[i], Base.kMatchMaxLen);
577370b324cSopenharmony_ci			if (repLens[i] > repLens[repMaxIndex])
578370b324cSopenharmony_ci				repMaxIndex = i;
579370b324cSopenharmony_ci		}
580370b324cSopenharmony_ci		if (repLens[repMaxIndex] >= _numFastBytes)
581370b324cSopenharmony_ci		{
582370b324cSopenharmony_ci			backRes = repMaxIndex;
583370b324cSopenharmony_ci			int lenRes = repLens[repMaxIndex];
584370b324cSopenharmony_ci			MovePos(lenRes - 1);
585370b324cSopenharmony_ci			return lenRes;
586370b324cSopenharmony_ci		}
587370b324cSopenharmony_ci
588370b324cSopenharmony_ci		if (lenMain >= _numFastBytes)
589370b324cSopenharmony_ci		{
590370b324cSopenharmony_ci			backRes = _matchDistances[numDistancePairs - 1] + Base.kNumRepDistances;
591370b324cSopenharmony_ci			MovePos(lenMain - 1);
592370b324cSopenharmony_ci			return lenMain;
593370b324cSopenharmony_ci		}
594370b324cSopenharmony_ci
595370b324cSopenharmony_ci		byte currentByte = _matchFinder.GetIndexByte(0 - 1);
596370b324cSopenharmony_ci		byte matchByte = _matchFinder.GetIndexByte(0 - _repDistances[0] - 1 - 1);
597370b324cSopenharmony_ci
598370b324cSopenharmony_ci		if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2)
599370b324cSopenharmony_ci		{
600370b324cSopenharmony_ci			backRes = -1;
601370b324cSopenharmony_ci			return 1;
602370b324cSopenharmony_ci		}
603370b324cSopenharmony_ci
604370b324cSopenharmony_ci		_optimum[0].State = _state;
605370b324cSopenharmony_ci
606370b324cSopenharmony_ci		int posState = (position & _posStateMask);
607370b324cSopenharmony_ci
608370b324cSopenharmony_ci		_optimum[1].Price = SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(_state << Base.kNumPosStatesBitsMax) + posState]) +
609370b324cSopenharmony_ci				_literalEncoder.GetSubCoder(position, _previousByte).GetPrice(!Base.StateIsCharState(_state), matchByte, currentByte);
610370b324cSopenharmony_ci		_optimum[1].MakeAsChar();
611370b324cSopenharmony_ci
612370b324cSopenharmony_ci		int matchPrice = SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(_state << Base.kNumPosStatesBitsMax) + posState]);
613370b324cSopenharmony_ci		int repMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[_state]);
614370b324cSopenharmony_ci
615370b324cSopenharmony_ci		if (matchByte == currentByte)
616370b324cSopenharmony_ci		{
617370b324cSopenharmony_ci			int shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState);
618370b324cSopenharmony_ci			if (shortRepPrice < _optimum[1].Price)
619370b324cSopenharmony_ci			{
620370b324cSopenharmony_ci				_optimum[1].Price = shortRepPrice;
621370b324cSopenharmony_ci				_optimum[1].MakeAsShortRep();
622370b324cSopenharmony_ci			}
623370b324cSopenharmony_ci		}
624370b324cSopenharmony_ci
625370b324cSopenharmony_ci		int lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]);
626370b324cSopenharmony_ci
627370b324cSopenharmony_ci		if (lenEnd < 2)
628370b324cSopenharmony_ci		{
629370b324cSopenharmony_ci			backRes = _optimum[1].BackPrev;
630370b324cSopenharmony_ci			return 1;
631370b324cSopenharmony_ci		}
632370b324cSopenharmony_ci
633370b324cSopenharmony_ci		_optimum[1].PosPrev = 0;
634370b324cSopenharmony_ci
635370b324cSopenharmony_ci		_optimum[0].Backs0 = reps[0];
636370b324cSopenharmony_ci		_optimum[0].Backs1 = reps[1];
637370b324cSopenharmony_ci		_optimum[0].Backs2 = reps[2];
638370b324cSopenharmony_ci		_optimum[0].Backs3 = reps[3];
639370b324cSopenharmony_ci
640370b324cSopenharmony_ci		int len = lenEnd;
641370b324cSopenharmony_ci		do
642370b324cSopenharmony_ci			_optimum[len--].Price = kIfinityPrice;
643370b324cSopenharmony_ci		while (len >= 2);
644370b324cSopenharmony_ci
645370b324cSopenharmony_ci		for (i = 0; i < Base.kNumRepDistances; i++)
646370b324cSopenharmony_ci		{
647370b324cSopenharmony_ci			int repLen = repLens[i];
648370b324cSopenharmony_ci			if (repLen < 2)
649370b324cSopenharmony_ci				continue;
650370b324cSopenharmony_ci			int price = repMatchPrice + GetPureRepPrice(i, _state, posState);
651370b324cSopenharmony_ci			do
652370b324cSopenharmony_ci			{
653370b324cSopenharmony_ci				int curAndLenPrice = price + _repMatchLenEncoder.GetPrice(repLen - 2, posState);
654370b324cSopenharmony_ci				Optimal optimum = _optimum[repLen];
655370b324cSopenharmony_ci				if (curAndLenPrice < optimum.Price)
656370b324cSopenharmony_ci				{
657370b324cSopenharmony_ci					optimum.Price = curAndLenPrice;
658370b324cSopenharmony_ci					optimum.PosPrev = 0;
659370b324cSopenharmony_ci					optimum.BackPrev = i;
660370b324cSopenharmony_ci					optimum.Prev1IsChar = false;
661370b324cSopenharmony_ci				}
662370b324cSopenharmony_ci			}
663370b324cSopenharmony_ci			while (--repLen >= 2);
664370b324cSopenharmony_ci		}
665370b324cSopenharmony_ci
666370b324cSopenharmony_ci		int normalMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRep[_state]);
667370b324cSopenharmony_ci
668370b324cSopenharmony_ci		len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
669370b324cSopenharmony_ci		if (len <= lenMain)
670370b324cSopenharmony_ci		{
671370b324cSopenharmony_ci			int offs = 0;
672370b324cSopenharmony_ci			while (len > _matchDistances[offs])
673370b324cSopenharmony_ci				offs += 2;
674370b324cSopenharmony_ci			for (; ; len++)
675370b324cSopenharmony_ci			{
676370b324cSopenharmony_ci				int distance = _matchDistances[offs + 1];
677370b324cSopenharmony_ci				int curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState);
678370b324cSopenharmony_ci				Optimal optimum = _optimum[len];
679370b324cSopenharmony_ci				if (curAndLenPrice < optimum.Price)
680370b324cSopenharmony_ci				{
681370b324cSopenharmony_ci					optimum.Price = curAndLenPrice;
682370b324cSopenharmony_ci					optimum.PosPrev = 0;
683370b324cSopenharmony_ci					optimum.BackPrev = distance + Base.kNumRepDistances;
684370b324cSopenharmony_ci					optimum.Prev1IsChar = false;
685370b324cSopenharmony_ci				}
686370b324cSopenharmony_ci				if (len == _matchDistances[offs])
687370b324cSopenharmony_ci				{
688370b324cSopenharmony_ci					offs += 2;
689370b324cSopenharmony_ci					if (offs == numDistancePairs)
690370b324cSopenharmony_ci						break;
691370b324cSopenharmony_ci				}
692370b324cSopenharmony_ci			}
693370b324cSopenharmony_ci		}
694370b324cSopenharmony_ci
695370b324cSopenharmony_ci		int cur = 0;
696370b324cSopenharmony_ci
697370b324cSopenharmony_ci		while (true)
698370b324cSopenharmony_ci		{
699370b324cSopenharmony_ci			cur++;
700370b324cSopenharmony_ci			if (cur == lenEnd)
701370b324cSopenharmony_ci				return Backward(cur);
702370b324cSopenharmony_ci			int newLen = ReadMatchDistances();
703370b324cSopenharmony_ci			numDistancePairs = _numDistancePairs;
704370b324cSopenharmony_ci			if (newLen >= _numFastBytes)
705370b324cSopenharmony_ci			{
706370b324cSopenharmony_ci
707370b324cSopenharmony_ci				_longestMatchLength = newLen;
708370b324cSopenharmony_ci				_longestMatchWasFound = true;
709370b324cSopenharmony_ci				return Backward(cur);
710370b324cSopenharmony_ci			}
711370b324cSopenharmony_ci			position++;
712370b324cSopenharmony_ci			int posPrev = _optimum[cur].PosPrev;
713370b324cSopenharmony_ci			int state;
714370b324cSopenharmony_ci			if (_optimum[cur].Prev1IsChar)
715370b324cSopenharmony_ci			{
716370b324cSopenharmony_ci				posPrev--;
717370b324cSopenharmony_ci				if (_optimum[cur].Prev2)
718370b324cSopenharmony_ci				{
719370b324cSopenharmony_ci					state = _optimum[_optimum[cur].PosPrev2].State;
720370b324cSopenharmony_ci					if (_optimum[cur].BackPrev2 < Base.kNumRepDistances)
721370b324cSopenharmony_ci						state = Base.StateUpdateRep(state);
722370b324cSopenharmony_ci					else
723370b324cSopenharmony_ci						state = Base.StateUpdateMatch(state);
724370b324cSopenharmony_ci				}
725370b324cSopenharmony_ci				else
726370b324cSopenharmony_ci					state = _optimum[posPrev].State;
727370b324cSopenharmony_ci				state = Base.StateUpdateChar(state);
728370b324cSopenharmony_ci			}
729370b324cSopenharmony_ci			else
730370b324cSopenharmony_ci				state = _optimum[posPrev].State;
731370b324cSopenharmony_ci			if (posPrev == cur - 1)
732370b324cSopenharmony_ci			{
733370b324cSopenharmony_ci				if (_optimum[cur].IsShortRep())
734370b324cSopenharmony_ci					state = Base.StateUpdateShortRep(state);
735370b324cSopenharmony_ci				else
736370b324cSopenharmony_ci					state = Base.StateUpdateChar(state);
737370b324cSopenharmony_ci			}
738370b324cSopenharmony_ci			else
739370b324cSopenharmony_ci			{
740370b324cSopenharmony_ci				int pos;
741370b324cSopenharmony_ci				if (_optimum[cur].Prev1IsChar && _optimum[cur].Prev2)
742370b324cSopenharmony_ci				{
743370b324cSopenharmony_ci					posPrev = _optimum[cur].PosPrev2;
744370b324cSopenharmony_ci					pos = _optimum[cur].BackPrev2;
745370b324cSopenharmony_ci					state = Base.StateUpdateRep(state);
746370b324cSopenharmony_ci				}
747370b324cSopenharmony_ci				else
748370b324cSopenharmony_ci				{
749370b324cSopenharmony_ci					pos = _optimum[cur].BackPrev;
750370b324cSopenharmony_ci					if (pos < Base.kNumRepDistances)
751370b324cSopenharmony_ci						state = Base.StateUpdateRep(state);
752370b324cSopenharmony_ci					else
753370b324cSopenharmony_ci						state = Base.StateUpdateMatch(state);
754370b324cSopenharmony_ci				}
755370b324cSopenharmony_ci				Optimal opt = _optimum[posPrev];
756370b324cSopenharmony_ci				if (pos < Base.kNumRepDistances)
757370b324cSopenharmony_ci				{
758370b324cSopenharmony_ci					if (pos == 0)
759370b324cSopenharmony_ci					{
760370b324cSopenharmony_ci						reps[0] = opt.Backs0;
761370b324cSopenharmony_ci						reps[1] = opt.Backs1;
762370b324cSopenharmony_ci						reps[2] = opt.Backs2;
763370b324cSopenharmony_ci						reps[3] = opt.Backs3;
764370b324cSopenharmony_ci					}
765370b324cSopenharmony_ci					else if (pos == 1)
766370b324cSopenharmony_ci					{
767370b324cSopenharmony_ci						reps[0] = opt.Backs1;
768370b324cSopenharmony_ci						reps[1] = opt.Backs0;
769370b324cSopenharmony_ci						reps[2] = opt.Backs2;
770370b324cSopenharmony_ci						reps[3] = opt.Backs3;
771370b324cSopenharmony_ci					}
772370b324cSopenharmony_ci					else if (pos == 2)
773370b324cSopenharmony_ci					{
774370b324cSopenharmony_ci						reps[0] = opt.Backs2;
775370b324cSopenharmony_ci						reps[1] = opt.Backs0;
776370b324cSopenharmony_ci						reps[2] = opt.Backs1;
777370b324cSopenharmony_ci						reps[3] = opt.Backs3;
778370b324cSopenharmony_ci					}
779370b324cSopenharmony_ci					else
780370b324cSopenharmony_ci					{
781370b324cSopenharmony_ci						reps[0] = opt.Backs3;
782370b324cSopenharmony_ci						reps[1] = opt.Backs0;
783370b324cSopenharmony_ci						reps[2] = opt.Backs1;
784370b324cSopenharmony_ci						reps[3] = opt.Backs2;
785370b324cSopenharmony_ci					}
786370b324cSopenharmony_ci				}
787370b324cSopenharmony_ci				else
788370b324cSopenharmony_ci				{
789370b324cSopenharmony_ci					reps[0] = (pos - Base.kNumRepDistances);
790370b324cSopenharmony_ci					reps[1] = opt.Backs0;
791370b324cSopenharmony_ci					reps[2] = opt.Backs1;
792370b324cSopenharmony_ci					reps[3] = opt.Backs2;
793370b324cSopenharmony_ci				}
794370b324cSopenharmony_ci			}
795370b324cSopenharmony_ci			_optimum[cur].State = state;
796370b324cSopenharmony_ci			_optimum[cur].Backs0 = reps[0];
797370b324cSopenharmony_ci			_optimum[cur].Backs1 = reps[1];
798370b324cSopenharmony_ci			_optimum[cur].Backs2 = reps[2];
799370b324cSopenharmony_ci			_optimum[cur].Backs3 = reps[3];
800370b324cSopenharmony_ci			int curPrice = _optimum[cur].Price;
801370b324cSopenharmony_ci
802370b324cSopenharmony_ci			currentByte = _matchFinder.GetIndexByte(0 - 1);
803370b324cSopenharmony_ci			matchByte = _matchFinder.GetIndexByte(0 - reps[0] - 1 - 1);
804370b324cSopenharmony_ci
805370b324cSopenharmony_ci			posState = (position & _posStateMask);
806370b324cSopenharmony_ci
807370b324cSopenharmony_ci			int curAnd1Price = curPrice +
808370b324cSopenharmony_ci				SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(state << Base.kNumPosStatesBitsMax) + posState]) +
809370b324cSopenharmony_ci				_literalEncoder.GetSubCoder(position, _matchFinder.GetIndexByte(0 - 2)).
810370b324cSopenharmony_ci				GetPrice(!Base.StateIsCharState(state), matchByte, currentByte);
811370b324cSopenharmony_ci
812370b324cSopenharmony_ci			Optimal nextOptimum = _optimum[cur + 1];
813370b324cSopenharmony_ci
814370b324cSopenharmony_ci			boolean nextIsChar = false;
815370b324cSopenharmony_ci			if (curAnd1Price < nextOptimum.Price)
816370b324cSopenharmony_ci			{
817370b324cSopenharmony_ci				nextOptimum.Price = curAnd1Price;
818370b324cSopenharmony_ci				nextOptimum.PosPrev = cur;
819370b324cSopenharmony_ci				nextOptimum.MakeAsChar();
820370b324cSopenharmony_ci				nextIsChar = true;
821370b324cSopenharmony_ci			}
822370b324cSopenharmony_ci
823370b324cSopenharmony_ci			matchPrice = curPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state << Base.kNumPosStatesBitsMax) + posState]);
824370b324cSopenharmony_ci			repMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state]);
825370b324cSopenharmony_ci
826370b324cSopenharmony_ci			if (matchByte == currentByte &&
827370b324cSopenharmony_ci				!(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0))
828370b324cSopenharmony_ci			{
829370b324cSopenharmony_ci				int shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState);
830370b324cSopenharmony_ci				if (shortRepPrice <= nextOptimum.Price)
831370b324cSopenharmony_ci				{
832370b324cSopenharmony_ci					nextOptimum.Price = shortRepPrice;
833370b324cSopenharmony_ci					nextOptimum.PosPrev = cur;
834370b324cSopenharmony_ci					nextOptimum.MakeAsShortRep();
835370b324cSopenharmony_ci					nextIsChar = true;
836370b324cSopenharmony_ci				}
837370b324cSopenharmony_ci			}
838370b324cSopenharmony_ci
839370b324cSopenharmony_ci			int numAvailableBytesFull = _matchFinder.GetNumAvailableBytes() + 1;
840370b324cSopenharmony_ci			numAvailableBytesFull = Math.min(kNumOpts - 1 - cur, numAvailableBytesFull);
841370b324cSopenharmony_ci			numAvailableBytes = numAvailableBytesFull;
842370b324cSopenharmony_ci
843370b324cSopenharmony_ci			if (numAvailableBytes < 2)
844370b324cSopenharmony_ci				continue;
845370b324cSopenharmony_ci			if (numAvailableBytes > _numFastBytes)
846370b324cSopenharmony_ci				numAvailableBytes = _numFastBytes;
847370b324cSopenharmony_ci			if (!nextIsChar && matchByte != currentByte)
848370b324cSopenharmony_ci			{
849370b324cSopenharmony_ci				// try Literal + rep0
850370b324cSopenharmony_ci				int t = Math.min(numAvailableBytesFull - 1, _numFastBytes);
851370b324cSopenharmony_ci				int lenTest2 = _matchFinder.GetMatchLen(0, reps[0], t);
852370b324cSopenharmony_ci				if (lenTest2 >= 2)
853370b324cSopenharmony_ci				{
854370b324cSopenharmony_ci					int state2 = Base.StateUpdateChar(state);
855370b324cSopenharmony_ci
856370b324cSopenharmony_ci					int posStateNext = (position + 1) & _posStateMask;
857370b324cSopenharmony_ci					int nextRepMatchPrice = curAnd1Price +
858370b324cSopenharmony_ci						SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]) +
859370b324cSopenharmony_ci						SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state2]);
860370b324cSopenharmony_ci					{
861370b324cSopenharmony_ci						int offset = cur + 1 + lenTest2;
862370b324cSopenharmony_ci						while (lenEnd < offset)
863370b324cSopenharmony_ci							_optimum[++lenEnd].Price = kIfinityPrice;
864370b324cSopenharmony_ci						int curAndLenPrice = nextRepMatchPrice + GetRepPrice(
865370b324cSopenharmony_ci								0, lenTest2, state2, posStateNext);
866370b324cSopenharmony_ci						Optimal optimum = _optimum[offset];
867370b324cSopenharmony_ci						if (curAndLenPrice < optimum.Price)
868370b324cSopenharmony_ci						{
869370b324cSopenharmony_ci							optimum.Price = curAndLenPrice;
870370b324cSopenharmony_ci							optimum.PosPrev = cur + 1;
871370b324cSopenharmony_ci							optimum.BackPrev = 0;
872370b324cSopenharmony_ci							optimum.Prev1IsChar = true;
873370b324cSopenharmony_ci							optimum.Prev2 = false;
874370b324cSopenharmony_ci						}
875370b324cSopenharmony_ci					}
876370b324cSopenharmony_ci				}
877370b324cSopenharmony_ci			}
878370b324cSopenharmony_ci
879370b324cSopenharmony_ci			int startLen = 2; // speed optimization
880370b324cSopenharmony_ci
881370b324cSopenharmony_ci			for (int repIndex = 0; repIndex < Base.kNumRepDistances; repIndex++)
882370b324cSopenharmony_ci			{
883370b324cSopenharmony_ci				int lenTest = _matchFinder.GetMatchLen(0 - 1, reps[repIndex], numAvailableBytes);
884370b324cSopenharmony_ci				if (lenTest < 2)
885370b324cSopenharmony_ci					continue;
886370b324cSopenharmony_ci				int lenTestTemp = lenTest;
887370b324cSopenharmony_ci				do
888370b324cSopenharmony_ci				{
889370b324cSopenharmony_ci					while (lenEnd < cur + lenTest)
890370b324cSopenharmony_ci						_optimum[++lenEnd].Price = kIfinityPrice;
891370b324cSopenharmony_ci					int curAndLenPrice = repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState);
892370b324cSopenharmony_ci					Optimal optimum = _optimum[cur + lenTest];
893370b324cSopenharmony_ci					if (curAndLenPrice < optimum.Price)
894370b324cSopenharmony_ci					{
895370b324cSopenharmony_ci						optimum.Price = curAndLenPrice;
896370b324cSopenharmony_ci						optimum.PosPrev = cur;
897370b324cSopenharmony_ci						optimum.BackPrev = repIndex;
898370b324cSopenharmony_ci						optimum.Prev1IsChar = false;
899370b324cSopenharmony_ci					}
900370b324cSopenharmony_ci				}
901370b324cSopenharmony_ci				while (--lenTest >= 2);
902370b324cSopenharmony_ci				lenTest = lenTestTemp;
903370b324cSopenharmony_ci
904370b324cSopenharmony_ci				if (repIndex == 0)
905370b324cSopenharmony_ci					startLen = lenTest + 1;
906370b324cSopenharmony_ci
907370b324cSopenharmony_ci				// if (_maxMode)
908370b324cSopenharmony_ci				if (lenTest < numAvailableBytesFull)
909370b324cSopenharmony_ci				{
910370b324cSopenharmony_ci					int t = Math.min(numAvailableBytesFull - 1 - lenTest, _numFastBytes);
911370b324cSopenharmony_ci					int lenTest2 = _matchFinder.GetMatchLen(lenTest, reps[repIndex], t);
912370b324cSopenharmony_ci					if (lenTest2 >= 2)
913370b324cSopenharmony_ci					{
914370b324cSopenharmony_ci						int state2 = Base.StateUpdateRep(state);
915370b324cSopenharmony_ci
916370b324cSopenharmony_ci						int posStateNext = (position + lenTest) & _posStateMask;
917370b324cSopenharmony_ci						int curAndLenCharPrice =
918370b324cSopenharmony_ci								repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState) +
919370b324cSopenharmony_ci								SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]) +
920370b324cSopenharmony_ci								_literalEncoder.GetSubCoder(position + lenTest,
921370b324cSopenharmony_ci								_matchFinder.GetIndexByte(lenTest - 1 - 1)).GetPrice(true,
922370b324cSopenharmony_ci								_matchFinder.GetIndexByte(lenTest - 1 - (reps[repIndex] + 1)),
923370b324cSopenharmony_ci								_matchFinder.GetIndexByte(lenTest - 1));
924370b324cSopenharmony_ci						state2 = Base.StateUpdateChar(state2);
925370b324cSopenharmony_ci						posStateNext = (position + lenTest + 1) & _posStateMask;
926370b324cSopenharmony_ci						int nextMatchPrice = curAndLenCharPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]);
927370b324cSopenharmony_ci						int nextRepMatchPrice = nextMatchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state2]);
928370b324cSopenharmony_ci
929370b324cSopenharmony_ci						// for(; lenTest2 >= 2; lenTest2--)
930370b324cSopenharmony_ci						{
931370b324cSopenharmony_ci							int offset = lenTest + 1 + lenTest2;
932370b324cSopenharmony_ci							while (lenEnd < cur + offset)
933370b324cSopenharmony_ci								_optimum[++lenEnd].Price = kIfinityPrice;
934370b324cSopenharmony_ci							int curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);
935370b324cSopenharmony_ci							Optimal optimum = _optimum[cur + offset];
936370b324cSopenharmony_ci							if (curAndLenPrice < optimum.Price)
937370b324cSopenharmony_ci							{
938370b324cSopenharmony_ci								optimum.Price = curAndLenPrice;
939370b324cSopenharmony_ci								optimum.PosPrev = cur + lenTest + 1;
940370b324cSopenharmony_ci								optimum.BackPrev = 0;
941370b324cSopenharmony_ci								optimum.Prev1IsChar = true;
942370b324cSopenharmony_ci								optimum.Prev2 = true;
943370b324cSopenharmony_ci								optimum.PosPrev2 = cur;
944370b324cSopenharmony_ci								optimum.BackPrev2 = repIndex;
945370b324cSopenharmony_ci							}
946370b324cSopenharmony_ci						}
947370b324cSopenharmony_ci					}
948370b324cSopenharmony_ci				}
949370b324cSopenharmony_ci			}
950370b324cSopenharmony_ci
951370b324cSopenharmony_ci			if (newLen > numAvailableBytes)
952370b324cSopenharmony_ci			{
953370b324cSopenharmony_ci				newLen = numAvailableBytes;
954370b324cSopenharmony_ci				for (numDistancePairs = 0; newLen > _matchDistances[numDistancePairs]; numDistancePairs += 2) ;
955370b324cSopenharmony_ci				_matchDistances[numDistancePairs] = newLen;
956370b324cSopenharmony_ci				numDistancePairs += 2;
957370b324cSopenharmony_ci			}
958370b324cSopenharmony_ci			if (newLen >= startLen)
959370b324cSopenharmony_ci			{
960370b324cSopenharmony_ci				normalMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRep[state]);
961370b324cSopenharmony_ci				while (lenEnd < cur + newLen)
962370b324cSopenharmony_ci					_optimum[++lenEnd].Price = kIfinityPrice;
963370b324cSopenharmony_ci
964370b324cSopenharmony_ci				int offs = 0;
965370b324cSopenharmony_ci				while (startLen > _matchDistances[offs])
966370b324cSopenharmony_ci					offs += 2;
967370b324cSopenharmony_ci
968370b324cSopenharmony_ci				for (int lenTest = startLen; ; lenTest++)
969370b324cSopenharmony_ci				{
970370b324cSopenharmony_ci					int curBack = _matchDistances[offs + 1];
971370b324cSopenharmony_ci					int curAndLenPrice = normalMatchPrice + GetPosLenPrice(curBack, lenTest, posState);
972370b324cSopenharmony_ci					Optimal optimum = _optimum[cur + lenTest];
973370b324cSopenharmony_ci					if (curAndLenPrice < optimum.Price)
974370b324cSopenharmony_ci					{
975370b324cSopenharmony_ci						optimum.Price = curAndLenPrice;
976370b324cSopenharmony_ci						optimum.PosPrev = cur;
977370b324cSopenharmony_ci						optimum.BackPrev = curBack + Base.kNumRepDistances;
978370b324cSopenharmony_ci						optimum.Prev1IsChar = false;
979370b324cSopenharmony_ci					}
980370b324cSopenharmony_ci
981370b324cSopenharmony_ci					if (lenTest == _matchDistances[offs])
982370b324cSopenharmony_ci					{
983370b324cSopenharmony_ci						if (lenTest < numAvailableBytesFull)
984370b324cSopenharmony_ci						{
985370b324cSopenharmony_ci							int t = Math.min(numAvailableBytesFull - 1 - lenTest, _numFastBytes);
986370b324cSopenharmony_ci							int lenTest2 = _matchFinder.GetMatchLen(lenTest, curBack, t);
987370b324cSopenharmony_ci							if (lenTest2 >= 2)
988370b324cSopenharmony_ci							{
989370b324cSopenharmony_ci								int state2 = Base.StateUpdateMatch(state);
990370b324cSopenharmony_ci
991370b324cSopenharmony_ci								int posStateNext = (position + lenTest) & _posStateMask;
992370b324cSopenharmony_ci								int curAndLenCharPrice = curAndLenPrice +
993370b324cSopenharmony_ci									SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]) +
994370b324cSopenharmony_ci									_literalEncoder.GetSubCoder(position + lenTest,
995370b324cSopenharmony_ci									_matchFinder.GetIndexByte(lenTest - 1 - 1)).
996370b324cSopenharmony_ci									GetPrice(true,
997370b324cSopenharmony_ci									_matchFinder.GetIndexByte(lenTest - (curBack + 1) - 1),
998370b324cSopenharmony_ci									_matchFinder.GetIndexByte(lenTest - 1));
999370b324cSopenharmony_ci								state2 = Base.StateUpdateChar(state2);
1000370b324cSopenharmony_ci								posStateNext = (position + lenTest + 1) & _posStateMask;
1001370b324cSopenharmony_ci								int nextMatchPrice = curAndLenCharPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]);
1002370b324cSopenharmony_ci								int nextRepMatchPrice = nextMatchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state2]);
1003370b324cSopenharmony_ci
1004370b324cSopenharmony_ci								int offset = lenTest + 1 + lenTest2;
1005370b324cSopenharmony_ci								while (lenEnd < cur + offset)
1006370b324cSopenharmony_ci									_optimum[++lenEnd].Price = kIfinityPrice;
1007370b324cSopenharmony_ci								curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);
1008370b324cSopenharmony_ci								optimum = _optimum[cur + offset];
1009370b324cSopenharmony_ci								if (curAndLenPrice < optimum.Price)
1010370b324cSopenharmony_ci								{
1011370b324cSopenharmony_ci									optimum.Price = curAndLenPrice;
1012370b324cSopenharmony_ci									optimum.PosPrev = cur + lenTest + 1;
1013370b324cSopenharmony_ci									optimum.BackPrev = 0;
1014370b324cSopenharmony_ci									optimum.Prev1IsChar = true;
1015370b324cSopenharmony_ci									optimum.Prev2 = true;
1016370b324cSopenharmony_ci									optimum.PosPrev2 = cur;
1017370b324cSopenharmony_ci									optimum.BackPrev2 = curBack + Base.kNumRepDistances;
1018370b324cSopenharmony_ci								}
1019370b324cSopenharmony_ci							}
1020370b324cSopenharmony_ci						}
1021370b324cSopenharmony_ci						offs += 2;
1022370b324cSopenharmony_ci						if (offs == numDistancePairs)
1023370b324cSopenharmony_ci							break;
1024370b324cSopenharmony_ci					}
1025370b324cSopenharmony_ci				}
1026370b324cSopenharmony_ci			}
1027370b324cSopenharmony_ci		}
1028370b324cSopenharmony_ci	}
1029370b324cSopenharmony_ci
1030370b324cSopenharmony_ci	boolean ChangePair(int smallDist, int bigDist)
1031370b324cSopenharmony_ci	{
1032370b324cSopenharmony_ci		int kDif = 7;
1033370b324cSopenharmony_ci		return (smallDist < (1 << (32 - kDif)) && bigDist >= (smallDist << kDif));
1034370b324cSopenharmony_ci	}
1035370b324cSopenharmony_ci
1036370b324cSopenharmony_ci	void WriteEndMarker(int posState) throws IOException
1037370b324cSopenharmony_ci	{
1038370b324cSopenharmony_ci		if (!_writeEndMark)
1039370b324cSopenharmony_ci			return;
1040370b324cSopenharmony_ci
1041370b324cSopenharmony_ci		_rangeEncoder.Encode(_isMatch, (_state << Base.kNumPosStatesBitsMax) + posState, 1);
1042370b324cSopenharmony_ci		_rangeEncoder.Encode(_isRep, _state, 0);
1043370b324cSopenharmony_ci		_state = Base.StateUpdateMatch(_state);
1044370b324cSopenharmony_ci		int len = Base.kMatchMinLen;
1045370b324cSopenharmony_ci		_lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);
1046370b324cSopenharmony_ci		int posSlot = (1 << Base.kNumPosSlotBits) - 1;
1047370b324cSopenharmony_ci		int lenToPosState = Base.GetLenToPosState(len);
1048370b324cSopenharmony_ci		_posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot);
1049370b324cSopenharmony_ci		int footerBits = 30;
1050370b324cSopenharmony_ci		int posReduced = (1 << footerBits) - 1;
1051370b324cSopenharmony_ci		_rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits);
1052370b324cSopenharmony_ci		_posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask);
1053370b324cSopenharmony_ci	}
1054370b324cSopenharmony_ci
1055370b324cSopenharmony_ci	void Flush(int nowPos) throws IOException
1056370b324cSopenharmony_ci	{
1057370b324cSopenharmony_ci		ReleaseMFStream();
1058370b324cSopenharmony_ci		WriteEndMarker(nowPos & _posStateMask);
1059370b324cSopenharmony_ci		_rangeEncoder.FlushData();
1060370b324cSopenharmony_ci		_rangeEncoder.FlushStream();
1061370b324cSopenharmony_ci	}
1062370b324cSopenharmony_ci
1063370b324cSopenharmony_ci	public void CodeOneBlock(long[] inSize, long[] outSize, boolean[] finished) throws IOException
1064370b324cSopenharmony_ci	{
1065370b324cSopenharmony_ci		inSize[0] = 0;
1066370b324cSopenharmony_ci		outSize[0] = 0;
1067370b324cSopenharmony_ci		finished[0] = true;
1068370b324cSopenharmony_ci
1069370b324cSopenharmony_ci		if (_inStream != null)
1070370b324cSopenharmony_ci		{
1071370b324cSopenharmony_ci			_matchFinder.SetStream(_inStream);
1072370b324cSopenharmony_ci			_matchFinder.Init();
1073370b324cSopenharmony_ci			_needReleaseMFStream = true;
1074370b324cSopenharmony_ci			_inStream = null;
1075370b324cSopenharmony_ci		}
1076370b324cSopenharmony_ci
1077370b324cSopenharmony_ci		if (_finished)
1078370b324cSopenharmony_ci			return;
1079370b324cSopenharmony_ci		_finished = true;
1080370b324cSopenharmony_ci
1081370b324cSopenharmony_ci
1082370b324cSopenharmony_ci		long progressPosValuePrev = nowPos64;
1083370b324cSopenharmony_ci		if (nowPos64 == 0)
1084370b324cSopenharmony_ci		{
1085370b324cSopenharmony_ci			if (_matchFinder.GetNumAvailableBytes() == 0)
1086370b324cSopenharmony_ci			{
1087370b324cSopenharmony_ci				Flush((int)nowPos64);
1088370b324cSopenharmony_ci				return;
1089370b324cSopenharmony_ci			}
1090370b324cSopenharmony_ci
1091370b324cSopenharmony_ci			ReadMatchDistances();
1092370b324cSopenharmony_ci			int posState = (int)(nowPos64) & _posStateMask;
1093370b324cSopenharmony_ci			_rangeEncoder.Encode(_isMatch, (_state << Base.kNumPosStatesBitsMax) + posState, 0);
1094370b324cSopenharmony_ci			_state = Base.StateUpdateChar(_state);
1095370b324cSopenharmony_ci			byte curByte = _matchFinder.GetIndexByte(0 - _additionalOffset);
1096370b324cSopenharmony_ci			_literalEncoder.GetSubCoder((int)(nowPos64), _previousByte).Encode(_rangeEncoder, curByte);
1097370b324cSopenharmony_ci			_previousByte = curByte;
1098370b324cSopenharmony_ci			_additionalOffset--;
1099370b324cSopenharmony_ci			nowPos64++;
1100370b324cSopenharmony_ci		}
1101370b324cSopenharmony_ci		if (_matchFinder.GetNumAvailableBytes() == 0)
1102370b324cSopenharmony_ci		{
1103370b324cSopenharmony_ci			Flush((int)nowPos64);
1104370b324cSopenharmony_ci			return;
1105370b324cSopenharmony_ci		}
1106370b324cSopenharmony_ci		while (true)
1107370b324cSopenharmony_ci		{
1108370b324cSopenharmony_ci
1109370b324cSopenharmony_ci			int len = GetOptimum((int)nowPos64);
1110370b324cSopenharmony_ci			int pos = backRes;
1111370b324cSopenharmony_ci			int posState = ((int)nowPos64) & _posStateMask;
1112370b324cSopenharmony_ci			int complexState = (_state << Base.kNumPosStatesBitsMax) + posState;
1113370b324cSopenharmony_ci			if (len == 1 && pos == -1)
1114370b324cSopenharmony_ci			{
1115370b324cSopenharmony_ci				_rangeEncoder.Encode(_isMatch, complexState, 0);
1116370b324cSopenharmony_ci				byte curByte = _matchFinder.GetIndexByte((int)(0 - _additionalOffset));
1117370b324cSopenharmony_ci				LiteralEncoder.Encoder2 subCoder = _literalEncoder.GetSubCoder((int)nowPos64, _previousByte);
1118370b324cSopenharmony_ci				if (!Base.StateIsCharState(_state))
1119370b324cSopenharmony_ci				{
1120370b324cSopenharmony_ci					byte matchByte = _matchFinder.GetIndexByte((int)(0 - _repDistances[0] - 1 - _additionalOffset));
1121370b324cSopenharmony_ci					subCoder.EncodeMatched(_rangeEncoder, matchByte, curByte);
1122370b324cSopenharmony_ci				}
1123370b324cSopenharmony_ci				else
1124370b324cSopenharmony_ci					subCoder.Encode(_rangeEncoder, curByte);
1125370b324cSopenharmony_ci				_previousByte = curByte;
1126370b324cSopenharmony_ci				_state = Base.StateUpdateChar(_state);
1127370b324cSopenharmony_ci			}
1128370b324cSopenharmony_ci			else
1129370b324cSopenharmony_ci			{
1130370b324cSopenharmony_ci				_rangeEncoder.Encode(_isMatch, complexState, 1);
1131370b324cSopenharmony_ci				if (pos < Base.kNumRepDistances)
1132370b324cSopenharmony_ci				{
1133370b324cSopenharmony_ci					_rangeEncoder.Encode(_isRep, _state, 1);
1134370b324cSopenharmony_ci					if (pos == 0)
1135370b324cSopenharmony_ci					{
1136370b324cSopenharmony_ci						_rangeEncoder.Encode(_isRepG0, _state, 0);
1137370b324cSopenharmony_ci						if (len == 1)
1138370b324cSopenharmony_ci							_rangeEncoder.Encode(_isRep0Long, complexState, 0);
1139370b324cSopenharmony_ci						else
1140370b324cSopenharmony_ci							_rangeEncoder.Encode(_isRep0Long, complexState, 1);
1141370b324cSopenharmony_ci					}
1142370b324cSopenharmony_ci					else
1143370b324cSopenharmony_ci					{
1144370b324cSopenharmony_ci						_rangeEncoder.Encode(_isRepG0, _state, 1);
1145370b324cSopenharmony_ci						if (pos == 1)
1146370b324cSopenharmony_ci							_rangeEncoder.Encode(_isRepG1, _state, 0);
1147370b324cSopenharmony_ci						else
1148370b324cSopenharmony_ci						{
1149370b324cSopenharmony_ci							_rangeEncoder.Encode(_isRepG1, _state, 1);
1150370b324cSopenharmony_ci							_rangeEncoder.Encode(_isRepG2, _state, pos - 2);
1151370b324cSopenharmony_ci						}
1152370b324cSopenharmony_ci					}
1153370b324cSopenharmony_ci					if (len == 1)
1154370b324cSopenharmony_ci						_state = Base.StateUpdateShortRep(_state);
1155370b324cSopenharmony_ci					else
1156370b324cSopenharmony_ci					{
1157370b324cSopenharmony_ci						_repMatchLenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);
1158370b324cSopenharmony_ci						_state = Base.StateUpdateRep(_state);
1159370b324cSopenharmony_ci					}
1160370b324cSopenharmony_ci					int distance = _repDistances[pos];
1161370b324cSopenharmony_ci					if (pos != 0)
1162370b324cSopenharmony_ci					{
1163370b324cSopenharmony_ci						for (int i = pos; i >= 1; i--)
1164370b324cSopenharmony_ci							_repDistances[i] = _repDistances[i - 1];
1165370b324cSopenharmony_ci						_repDistances[0] = distance;
1166370b324cSopenharmony_ci					}
1167370b324cSopenharmony_ci				}
1168370b324cSopenharmony_ci				else
1169370b324cSopenharmony_ci				{
1170370b324cSopenharmony_ci					_rangeEncoder.Encode(_isRep, _state, 0);
1171370b324cSopenharmony_ci					_state = Base.StateUpdateMatch(_state);
1172370b324cSopenharmony_ci					_lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);
1173370b324cSopenharmony_ci					pos -= Base.kNumRepDistances;
1174370b324cSopenharmony_ci					int posSlot = GetPosSlot(pos);
1175370b324cSopenharmony_ci					int lenToPosState = Base.GetLenToPosState(len);
1176370b324cSopenharmony_ci					_posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot);
1177370b324cSopenharmony_ci
1178370b324cSopenharmony_ci					if (posSlot >= Base.kStartPosModelIndex)
1179370b324cSopenharmony_ci					{
1180370b324cSopenharmony_ci						int footerBits = (int)((posSlot >> 1) - 1);
1181370b324cSopenharmony_ci						int baseVal = ((2 | (posSlot & 1)) << footerBits);
1182370b324cSopenharmony_ci						int posReduced = pos - baseVal;
1183370b324cSopenharmony_ci
1184370b324cSopenharmony_ci						if (posSlot < Base.kEndPosModelIndex)
1185370b324cSopenharmony_ci							BitTreeEncoder.ReverseEncode(_posEncoders,
1186370b324cSopenharmony_ci									baseVal - posSlot - 1, _rangeEncoder, footerBits, posReduced);
1187370b324cSopenharmony_ci						else
1188370b324cSopenharmony_ci						{
1189370b324cSopenharmony_ci							_rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits);
1190370b324cSopenharmony_ci							_posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask);
1191370b324cSopenharmony_ci							_alignPriceCount++;
1192370b324cSopenharmony_ci						}
1193370b324cSopenharmony_ci					}
1194370b324cSopenharmony_ci					int distance = pos;
1195370b324cSopenharmony_ci					for (int i = Base.kNumRepDistances - 1; i >= 1; i--)
1196370b324cSopenharmony_ci						_repDistances[i] = _repDistances[i - 1];
1197370b324cSopenharmony_ci					_repDistances[0] = distance;
1198370b324cSopenharmony_ci					_matchPriceCount++;
1199370b324cSopenharmony_ci				}
1200370b324cSopenharmony_ci				_previousByte = _matchFinder.GetIndexByte(len - 1 - _additionalOffset);
1201370b324cSopenharmony_ci			}
1202370b324cSopenharmony_ci			_additionalOffset -= len;
1203370b324cSopenharmony_ci			nowPos64 += len;
1204370b324cSopenharmony_ci			if (_additionalOffset == 0)
1205370b324cSopenharmony_ci			{
1206370b324cSopenharmony_ci				// if (!_fastMode)
1207370b324cSopenharmony_ci				if (_matchPriceCount >= (1 << 7))
1208370b324cSopenharmony_ci					FillDistancesPrices();
1209370b324cSopenharmony_ci				if (_alignPriceCount >= Base.kAlignTableSize)
1210370b324cSopenharmony_ci					FillAlignPrices();
1211370b324cSopenharmony_ci				inSize[0] = nowPos64;
1212370b324cSopenharmony_ci				outSize[0] = _rangeEncoder.GetProcessedSizeAdd();
1213370b324cSopenharmony_ci				if (_matchFinder.GetNumAvailableBytes() == 0)
1214370b324cSopenharmony_ci				{
1215370b324cSopenharmony_ci					Flush((int)nowPos64);
1216370b324cSopenharmony_ci					return;
1217370b324cSopenharmony_ci				}
1218370b324cSopenharmony_ci
1219370b324cSopenharmony_ci				if (nowPos64 - progressPosValuePrev >= (1 << 12))
1220370b324cSopenharmony_ci				{
1221370b324cSopenharmony_ci					_finished = false;
1222370b324cSopenharmony_ci					finished[0] = false;
1223370b324cSopenharmony_ci					return;
1224370b324cSopenharmony_ci				}
1225370b324cSopenharmony_ci			}
1226370b324cSopenharmony_ci		}
1227370b324cSopenharmony_ci	}
1228370b324cSopenharmony_ci
1229370b324cSopenharmony_ci	void ReleaseMFStream()
1230370b324cSopenharmony_ci	{
1231370b324cSopenharmony_ci		if (_matchFinder != null && _needReleaseMFStream)
1232370b324cSopenharmony_ci		{
1233370b324cSopenharmony_ci			_matchFinder.ReleaseStream();
1234370b324cSopenharmony_ci			_needReleaseMFStream = false;
1235370b324cSopenharmony_ci		}
1236370b324cSopenharmony_ci	}
1237370b324cSopenharmony_ci
1238370b324cSopenharmony_ci	void SetOutStream(java.io.OutputStream outStream)
1239370b324cSopenharmony_ci	{ _rangeEncoder.SetStream(outStream); }
1240370b324cSopenharmony_ci	void ReleaseOutStream()
1241370b324cSopenharmony_ci	{ _rangeEncoder.ReleaseStream(); }
1242370b324cSopenharmony_ci
1243370b324cSopenharmony_ci	void ReleaseStreams()
1244370b324cSopenharmony_ci	{
1245370b324cSopenharmony_ci		ReleaseMFStream();
1246370b324cSopenharmony_ci		ReleaseOutStream();
1247370b324cSopenharmony_ci	}
1248370b324cSopenharmony_ci
1249370b324cSopenharmony_ci	void SetStreams(java.io.InputStream inStream, java.io.OutputStream outStream,
1250370b324cSopenharmony_ci			long inSize, long outSize)
1251370b324cSopenharmony_ci	{
1252370b324cSopenharmony_ci		_inStream = inStream;
1253370b324cSopenharmony_ci		_finished = false;
1254370b324cSopenharmony_ci		Create();
1255370b324cSopenharmony_ci		SetOutStream(outStream);
1256370b324cSopenharmony_ci		Init();
1257370b324cSopenharmony_ci
1258370b324cSopenharmony_ci		// if (!_fastMode)
1259370b324cSopenharmony_ci		{
1260370b324cSopenharmony_ci			FillDistancesPrices();
1261370b324cSopenharmony_ci			FillAlignPrices();
1262370b324cSopenharmony_ci		}
1263370b324cSopenharmony_ci
1264370b324cSopenharmony_ci		_lenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen);
1265370b324cSopenharmony_ci		_lenEncoder.UpdateTables(1 << _posStateBits);
1266370b324cSopenharmony_ci		_repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen);
1267370b324cSopenharmony_ci		_repMatchLenEncoder.UpdateTables(1 << _posStateBits);
1268370b324cSopenharmony_ci
1269370b324cSopenharmony_ci		nowPos64 = 0;
1270370b324cSopenharmony_ci	}
1271370b324cSopenharmony_ci
1272370b324cSopenharmony_ci	long[] processedInSize = new long[1]; long[] processedOutSize = new long[1]; boolean[] finished = new boolean[1];
1273370b324cSopenharmony_ci	public void Code(java.io.InputStream inStream, java.io.OutputStream outStream,
1274370b324cSopenharmony_ci			long inSize, long outSize, ICodeProgress progress) throws IOException
1275370b324cSopenharmony_ci	{
1276370b324cSopenharmony_ci		_needReleaseMFStream = false;
1277370b324cSopenharmony_ci		try
1278370b324cSopenharmony_ci		{
1279370b324cSopenharmony_ci			SetStreams(inStream, outStream, inSize, outSize);
1280370b324cSopenharmony_ci			while (true)
1281370b324cSopenharmony_ci			{
1282370b324cSopenharmony_ci
1283370b324cSopenharmony_ci
1284370b324cSopenharmony_ci
1285370b324cSopenharmony_ci				CodeOneBlock(processedInSize, processedOutSize, finished);
1286370b324cSopenharmony_ci				if (finished[0])
1287370b324cSopenharmony_ci					return;
1288370b324cSopenharmony_ci				if (progress != null)
1289370b324cSopenharmony_ci				{
1290370b324cSopenharmony_ci					progress.SetProgress(processedInSize[0], processedOutSize[0]);
1291370b324cSopenharmony_ci				}
1292370b324cSopenharmony_ci			}
1293370b324cSopenharmony_ci		}
1294370b324cSopenharmony_ci		finally
1295370b324cSopenharmony_ci		{
1296370b324cSopenharmony_ci			ReleaseStreams();
1297370b324cSopenharmony_ci		}
1298370b324cSopenharmony_ci	}
1299370b324cSopenharmony_ci
1300370b324cSopenharmony_ci	public static final int kPropSize = 5;
1301370b324cSopenharmony_ci	byte[] properties = new byte[kPropSize];
1302370b324cSopenharmony_ci
1303370b324cSopenharmony_ci	public void WriteCoderProperties(java.io.OutputStream outStream) throws IOException
1304370b324cSopenharmony_ci	{
1305370b324cSopenharmony_ci		properties[0] = (byte)((_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits);
1306370b324cSopenharmony_ci		for (int i = 0; i < 4; i++)
1307370b324cSopenharmony_ci			properties[1 + i] = (byte)(_dictionarySize >> (8 * i));
1308370b324cSopenharmony_ci		outStream.write(properties, 0, kPropSize);
1309370b324cSopenharmony_ci	}
1310370b324cSopenharmony_ci
1311370b324cSopenharmony_ci	int[] tempPrices = new int[Base.kNumFullDistances];
1312370b324cSopenharmony_ci	int _matchPriceCount;
1313370b324cSopenharmony_ci
1314370b324cSopenharmony_ci	void FillDistancesPrices()
1315370b324cSopenharmony_ci	{
1316370b324cSopenharmony_ci		for (int i = Base.kStartPosModelIndex; i < Base.kNumFullDistances; i++)
1317370b324cSopenharmony_ci		{
1318370b324cSopenharmony_ci			int posSlot = GetPosSlot(i);
1319370b324cSopenharmony_ci			int footerBits = (int)((posSlot >> 1) - 1);
1320370b324cSopenharmony_ci			int baseVal = ((2 | (posSlot & 1)) << footerBits);
1321370b324cSopenharmony_ci			tempPrices[i] = BitTreeEncoder.ReverseGetPrice(_posEncoders,
1322370b324cSopenharmony_ci				baseVal - posSlot - 1, footerBits, i - baseVal);
1323370b324cSopenharmony_ci		}
1324370b324cSopenharmony_ci
1325370b324cSopenharmony_ci		for (int lenToPosState = 0; lenToPosState < Base.kNumLenToPosStates; lenToPosState++)
1326370b324cSopenharmony_ci		{
1327370b324cSopenharmony_ci			int posSlot;
1328370b324cSopenharmony_ci			BitTreeEncoder encoder = _posSlotEncoder[lenToPosState];
1329370b324cSopenharmony_ci
1330370b324cSopenharmony_ci			int st = (lenToPosState << Base.kNumPosSlotBits);
1331370b324cSopenharmony_ci			for (posSlot = 0; posSlot < _distTableSize; posSlot++)
1332370b324cSopenharmony_ci				_posSlotPrices[st + posSlot] = encoder.GetPrice(posSlot);
1333370b324cSopenharmony_ci			for (posSlot = Base.kEndPosModelIndex; posSlot < _distTableSize; posSlot++)
1334370b324cSopenharmony_ci				_posSlotPrices[st + posSlot] += ((((posSlot >> 1) - 1) - Base.kNumAlignBits) << SevenZip.Compression.RangeCoder.Encoder.kNumBitPriceShiftBits);
1335370b324cSopenharmony_ci
1336370b324cSopenharmony_ci			int st2 = lenToPosState * Base.kNumFullDistances;
1337370b324cSopenharmony_ci			int i;
1338370b324cSopenharmony_ci			for (i = 0; i < Base.kStartPosModelIndex; i++)
1339370b324cSopenharmony_ci				_distancesPrices[st2 + i] = _posSlotPrices[st + i];
1340370b324cSopenharmony_ci			for (; i < Base.kNumFullDistances; i++)
1341370b324cSopenharmony_ci				_distancesPrices[st2 + i] = _posSlotPrices[st + GetPosSlot(i)] + tempPrices[i];
1342370b324cSopenharmony_ci		}
1343370b324cSopenharmony_ci		_matchPriceCount = 0;
1344370b324cSopenharmony_ci	}
1345370b324cSopenharmony_ci
1346370b324cSopenharmony_ci	void FillAlignPrices()
1347370b324cSopenharmony_ci	{
1348370b324cSopenharmony_ci		for (int i = 0; i < Base.kAlignTableSize; i++)
1349370b324cSopenharmony_ci			_alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i);
1350370b324cSopenharmony_ci		_alignPriceCount = 0;
1351370b324cSopenharmony_ci	}
1352370b324cSopenharmony_ci
1353370b324cSopenharmony_ci
1354370b324cSopenharmony_ci	public boolean SetAlgorithm(int algorithm)
1355370b324cSopenharmony_ci	{
1356370b324cSopenharmony_ci		/*
1357370b324cSopenharmony_ci		_fastMode = (algorithm == 0);
1358370b324cSopenharmony_ci		_maxMode = (algorithm >= 2);
1359370b324cSopenharmony_ci		*/
1360370b324cSopenharmony_ci		return true;
1361370b324cSopenharmony_ci	}
1362370b324cSopenharmony_ci
1363370b324cSopenharmony_ci	public boolean SetDictionarySize(int dictionarySize)
1364370b324cSopenharmony_ci	{
1365370b324cSopenharmony_ci		int kDicLogSizeMaxCompress = 29;
1366370b324cSopenharmony_ci		if (dictionarySize < (1 << Base.kDicLogSizeMin) || dictionarySize > (1 << kDicLogSizeMaxCompress))
1367370b324cSopenharmony_ci			return false;
1368370b324cSopenharmony_ci		_dictionarySize = dictionarySize;
1369370b324cSopenharmony_ci		int dicLogSize;
1370370b324cSopenharmony_ci		for (dicLogSize = 0; dictionarySize > (1 << dicLogSize); dicLogSize++) ;
1371370b324cSopenharmony_ci		_distTableSize = dicLogSize * 2;
1372370b324cSopenharmony_ci		return true;
1373370b324cSopenharmony_ci	}
1374370b324cSopenharmony_ci
1375370b324cSopenharmony_ci	public boolean SetNumFastBytes(int numFastBytes)
1376370b324cSopenharmony_ci	{
1377370b324cSopenharmony_ci		if (numFastBytes < 5 || numFastBytes > Base.kMatchMaxLen)
1378370b324cSopenharmony_ci			return false;
1379370b324cSopenharmony_ci		_numFastBytes = numFastBytes;
1380370b324cSopenharmony_ci		return true;
1381370b324cSopenharmony_ci	}
1382370b324cSopenharmony_ci
1383370b324cSopenharmony_ci	public boolean SetMatchFinder(int matchFinderIndex)
1384370b324cSopenharmony_ci	{
1385370b324cSopenharmony_ci		if (matchFinderIndex < 0 || matchFinderIndex > 2)
1386370b324cSopenharmony_ci			return false;
1387370b324cSopenharmony_ci		int matchFinderIndexPrev = _matchFinderType;
1388370b324cSopenharmony_ci		_matchFinderType = matchFinderIndex;
1389370b324cSopenharmony_ci		if (_matchFinder != null && matchFinderIndexPrev != _matchFinderType)
1390370b324cSopenharmony_ci		{
1391370b324cSopenharmony_ci			_dictionarySizePrev = -1;
1392370b324cSopenharmony_ci			_matchFinder = null;
1393370b324cSopenharmony_ci		}
1394370b324cSopenharmony_ci		return true;
1395370b324cSopenharmony_ci	}
1396370b324cSopenharmony_ci
1397370b324cSopenharmony_ci	public boolean SetLcLpPb(int lc, int lp, int pb)
1398370b324cSopenharmony_ci	{
1399370b324cSopenharmony_ci		if (
1400370b324cSopenharmony_ci				lp < 0 || lp > Base.kNumLitPosStatesBitsEncodingMax ||
1401370b324cSopenharmony_ci				lc < 0 || lc > Base.kNumLitContextBitsMax ||
1402370b324cSopenharmony_ci				pb < 0 || pb > Base.kNumPosStatesBitsEncodingMax)
1403370b324cSopenharmony_ci			return false;
1404370b324cSopenharmony_ci		_numLiteralPosStateBits = lp;
1405370b324cSopenharmony_ci		_numLiteralContextBits = lc;
1406370b324cSopenharmony_ci		_posStateBits = pb;
1407370b324cSopenharmony_ci		_posStateMask = ((1) << _posStateBits) - 1;
1408370b324cSopenharmony_ci		return true;
1409370b324cSopenharmony_ci	}
1410370b324cSopenharmony_ci
1411370b324cSopenharmony_ci	public void SetEndMarkerMode(boolean endMarkerMode)
1412370b324cSopenharmony_ci	{
1413370b324cSopenharmony_ci		_writeEndMark = endMarkerMode;
1414370b324cSopenharmony_ci	}
1415370b324cSopenharmony_ci}
1416370b324cSopenharmony_ci
1417