source: other-projects/trunk/7z-ant/src/SevenZip/Compression/LZMA/Encoder.java@ 17387

Last change on this file since 17387 was 17387, checked in by oranfry, 16 years ago

Modified ant task which works with the updated 7zip API

File size: 41.3 KB
Line 
1package SevenZip.Compression.LZMA;
2
3import SevenZip.Compression.RangeCoder.BitTreeEncoder;
4import SevenZip.Compression.LZMA.Base;
5import SevenZip.Compression.LZ.BinTree;
6import SevenZip.ICodeProgress;
7import java.io.IOException;
8
9public class Encoder
10{
11 public static final int EMatchFinderTypeBT2 = 0;
12 public static final int EMatchFinderTypeBT4 = 1;
13
14
15
16
17 static final int kIfinityPrice = 0xFFFFFFF;
18
19 static byte[] g_FastPos = new byte[1 << 11];
20
21 static
22 {
23 int kFastSlots = 22;
24 int c = 2;
25 g_FastPos[0] = 0;
26 g_FastPos[1] = 1;
27 for (int slotFast = 2; slotFast < kFastSlots; slotFast++)
28 {
29 int k = (1 << ((slotFast >> 1) - 1));
30 for (int j = 0; j < k; j++, c++)
31 g_FastPos[c] = (byte)slotFast;
32 }
33 }
34
35 static int GetPosSlot(int pos)
36 {
37 if (pos < (1 << 11))
38 return g_FastPos[pos];
39 if (pos < (1 << 21))
40 return (g_FastPos[pos >> 10] + 20);
41 return (g_FastPos[pos >> 20] + 40);
42 }
43
44 static int GetPosSlot2(int pos)
45 {
46 if (pos < (1 << 17))
47 return (g_FastPos[pos >> 6] + 12);
48 if (pos < (1 << 27))
49 return (g_FastPos[pos >> 16] + 32);
50 return (g_FastPos[pos >> 26] + 52);
51 }
52
53 int _state = Base.StateInit();
54 byte _previousByte;
55 int[] _repDistances = new int[Base.kNumRepDistances];
56
57 void BaseInit()
58 {
59 _state = Base.StateInit();
60 _previousByte = 0;
61 for (int i = 0; i < Base.kNumRepDistances; i++)
62 _repDistances[i] = 0;
63 }
64
65 static final int kDefaultDictionaryLogSize = 22;
66 static final int kNumFastBytesDefault = 0x20;
67
68 class LiteralEncoder
69 {
70 class Encoder2
71 {
72 short[] m_Encoders = new short[0x300];
73
74 public void Init() { SevenZip.Compression.RangeCoder.Encoder.InitBitModels(m_Encoders); }
75
76
77
78 public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, byte symbol) throws IOException
79 {
80 int context = 1;
81 for (int i = 7; i >= 0; i--)
82 {
83 int bit = ((symbol >> i) & 1);
84 rangeEncoder.Encode(m_Encoders, context, bit);
85 context = (context << 1) | bit;
86 }
87 }
88
89 public void EncodeMatched(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, byte matchByte, byte symbol) throws IOException
90 {
91 int context = 1;
92 boolean same = true;
93 for (int i = 7; i >= 0; i--)
94 {
95 int bit = ((symbol >> i) & 1);
96 int state = context;
97 if (same)
98 {
99 int matchBit = ((matchByte >> i) & 1);
100 state += ((1 + matchBit) << 8);
101 same = (matchBit == bit);
102 }
103 rangeEncoder.Encode(m_Encoders, state, bit);
104 context = (context << 1) | bit;
105 }
106 }
107
108 public int GetPrice(boolean matchMode, byte matchByte, byte symbol)
109 {
110 int price = 0;
111 int context = 1;
112 int i = 7;
113 if (matchMode)
114 {
115 for (; i >= 0; i--)
116 {
117 int matchBit = (matchByte >> i) & 1;
118 int bit = (symbol >> i) & 1;
119 price += SevenZip.Compression.RangeCoder.Encoder.GetPrice(m_Encoders[((1 + matchBit) << 8) + context], bit);
120 context = (context << 1) | bit;
121 if (matchBit != bit)
122 {
123 i--;
124 break;
125 }
126 }
127 }
128 for (; i >= 0; i--)
129 {
130 int bit = (symbol >> i) & 1;
131 price += SevenZip.Compression.RangeCoder.Encoder.GetPrice(m_Encoders[context], bit);
132 context = (context << 1) | bit;
133 }
134 return price;
135 }
136 }
137
138 Encoder2[] m_Coders;
139 int m_NumPrevBits;
140 int m_NumPosBits;
141 int m_PosMask;
142
143 public void Create(int numPosBits, int numPrevBits)
144 {
145 if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits)
146 return;
147 m_NumPosBits = numPosBits;
148 m_PosMask = (1 << numPosBits) - 1;
149 m_NumPrevBits = numPrevBits;
150 int numStates = 1 << (m_NumPrevBits + m_NumPosBits);
151 m_Coders = new Encoder2[numStates];
152 for (int i = 0; i < numStates; i++)
153 m_Coders[i] = new Encoder2();
154 }
155
156 public void Init()
157 {
158 int numStates = 1 << (m_NumPrevBits + m_NumPosBits);
159 for (int i = 0; i < numStates; i++)
160 m_Coders[i].Init();
161 }
162
163 public Encoder2 GetSubCoder(int pos, byte prevByte)
164 { return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + ((prevByte & 0xFF) >>> (8 - m_NumPrevBits))]; }
165 }
166
167 class LenEncoder
168 {
169 short[] _choice = new short[2];
170 BitTreeEncoder[] _lowCoder = new BitTreeEncoder[Base.kNumPosStatesEncodingMax];
171 BitTreeEncoder[] _midCoder = new BitTreeEncoder[Base.kNumPosStatesEncodingMax];
172 BitTreeEncoder _highCoder = new BitTreeEncoder(Base.kNumHighLenBits);
173
174
175 public LenEncoder()
176 {
177 for (int posState = 0; posState < Base.kNumPosStatesEncodingMax; posState++)
178 {
179 _lowCoder[posState] = new BitTreeEncoder(Base.kNumLowLenBits);
180 _midCoder[posState] = new BitTreeEncoder(Base.kNumMidLenBits);
181 }
182 }
183
184 public void Init(int numPosStates)
185 {
186 SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_choice);
187
188 for (int posState = 0; posState < numPosStates; posState++)
189 {
190 _lowCoder[posState].Init();
191 _midCoder[posState].Init();
192 }
193 _highCoder.Init();
194 }
195
196 public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, int symbol, int posState) throws IOException
197 {
198 if (symbol < Base.kNumLowLenSymbols)
199 {
200 rangeEncoder.Encode(_choice, 0, 0);
201 _lowCoder[posState].Encode(rangeEncoder, symbol);
202 }
203 else
204 {
205 symbol -= Base.kNumLowLenSymbols;
206 rangeEncoder.Encode(_choice, 0, 1);
207 if (symbol < Base.kNumMidLenSymbols)
208 {
209 rangeEncoder.Encode(_choice, 1, 0);
210 _midCoder[posState].Encode(rangeEncoder, symbol);
211 }
212 else
213 {
214 rangeEncoder.Encode(_choice, 1, 1);
215 _highCoder.Encode(rangeEncoder, symbol - Base.kNumMidLenSymbols);
216 }
217 }
218 }
219
220 public void SetPrices(int posState, int numSymbols, int[] prices, int st)
221 {
222 int a0 = SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_choice[0]);
223 int a1 = SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_choice[0]);
224 int b0 = a1 + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_choice[1]);
225 int b1 = a1 + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_choice[1]);
226 int i = 0;
227 for (i = 0; i < Base.kNumLowLenSymbols; i++)
228 {
229 if (i >= numSymbols)
230 return;
231 prices[st + i] = a0 + _lowCoder[posState].GetPrice(i);
232 }
233 for (; i < Base.kNumLowLenSymbols + Base.kNumMidLenSymbols; i++)
234 {
235 if (i >= numSymbols)
236 return;
237 prices[st + i] = b0 + _midCoder[posState].GetPrice(i - Base.kNumLowLenSymbols);
238 }
239 for (; i < numSymbols; i++)
240 prices[st + i] = b1 + _highCoder.GetPrice(i - Base.kNumLowLenSymbols - Base.kNumMidLenSymbols);
241 }
242 };
243
244 public static final int kNumLenSpecSymbols = Base.kNumLowLenSymbols + Base.kNumMidLenSymbols;
245
246 class LenPriceTableEncoder extends LenEncoder
247 {
248 int[] _prices = new int[Base.kNumLenSymbols<<Base.kNumPosStatesBitsEncodingMax];
249 int _tableSize;
250 int[] _counters = new int[Base.kNumPosStatesEncodingMax];
251
252 public void SetTableSize(int tableSize) { _tableSize = tableSize; }
253
254 public int GetPrice(int symbol, int posState)
255 {
256 return _prices[posState * Base.kNumLenSymbols + symbol];
257 }
258
259 void UpdateTable(int posState)
260 {
261 SetPrices(posState, _tableSize, _prices, posState * Base.kNumLenSymbols);
262 _counters[posState] = _tableSize;
263 }
264
265 public void UpdateTables(int numPosStates)
266 {
267 for (int posState = 0; posState < numPosStates; posState++)
268 UpdateTable(posState);
269 }
270
271 public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, int symbol, int posState) throws IOException
272 {
273 super.Encode(rangeEncoder, symbol, posState);
274 if (--_counters[posState] == 0)
275 UpdateTable(posState);
276 }
277 }
278
279 static final int kNumOpts = 1 << 12;
280 class Optimal
281 {
282 public int State;
283
284 public boolean Prev1IsChar;
285 public boolean Prev2;
286
287 public int PosPrev2;
288 public int BackPrev2;
289
290 public int Price;
291 public int PosPrev;
292 public int BackPrev;
293
294 public int Backs0;
295 public int Backs1;
296 public int Backs2;
297 public int Backs3;
298
299 public void MakeAsChar() { BackPrev = -1; Prev1IsChar = false; }
300 public void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; }
301 public boolean IsShortRep() { return (BackPrev == 0); }
302 };
303 Optimal[] _optimum = new Optimal[kNumOpts];
304 SevenZip.Compression.LZ.BinTree _matchFinder = null;
305 SevenZip.Compression.RangeCoder.Encoder _rangeEncoder = new SevenZip.Compression.RangeCoder.Encoder();
306
307 short[] _isMatch = new short[Base.kNumStates<<Base.kNumPosStatesBitsMax];
308 short[] _isRep = new short[Base.kNumStates];
309 short[] _isRepG0 = new short[Base.kNumStates];
310 short[] _isRepG1 = new short[Base.kNumStates];
311 short[] _isRepG2 = new short[Base.kNumStates];
312 short[] _isRep0Long = new short[Base.kNumStates<<Base.kNumPosStatesBitsMax];
313
314 BitTreeEncoder[] _posSlotEncoder = new BitTreeEncoder[Base.kNumLenToPosStates]; // kNumPosSlotBits
315
316 short[] _posEncoders = new short[Base.kNumFullDistances-Base.kEndPosModelIndex];
317 BitTreeEncoder _posAlignEncoder = new BitTreeEncoder(Base.kNumAlignBits);
318
319 LenPriceTableEncoder _lenEncoder = new LenPriceTableEncoder();
320 LenPriceTableEncoder _repMatchLenEncoder = new LenPriceTableEncoder();
321
322 LiteralEncoder _literalEncoder = new LiteralEncoder();
323
324 int[] _matchDistances = new int[Base.kMatchMaxLen*2+2];
325
326 int _numFastBytes = kNumFastBytesDefault;
327 int _longestMatchLength;
328 int _numDistancePairs;
329
330 int _additionalOffset;
331
332 int _optimumEndIndex;
333 int _optimumCurrentIndex;
334
335 boolean _longestMatchWasFound;
336
337 int[] _posSlotPrices = new int[1<<(Base.kNumPosSlotBits+Base.kNumLenToPosStatesBits)];
338 int[] _distancesPrices = new int[Base.kNumFullDistances<<Base.kNumLenToPosStatesBits];
339 int[] _alignPrices = new int[Base.kAlignTableSize];
340 int _alignPriceCount;
341
342 int _distTableSize = (kDefaultDictionaryLogSize * 2);
343
344 int _posStateBits = 2;
345 int _posStateMask = (4 - 1);
346 int _numLiteralPosStateBits = 0;
347 int _numLiteralContextBits = 3;
348
349 int _dictionarySize = (1 << kDefaultDictionaryLogSize);
350 int _dictionarySizePrev = -1;
351 int _numFastBytesPrev = -1;
352
353 long nowPos64;
354 boolean _finished;
355 java.io.InputStream _inStream;
356
357 int _matchFinderType = EMatchFinderTypeBT4;
358 boolean _writeEndMark = false;
359
360 boolean _needReleaseMFStream = false;
361
362 void Create()
363 {
364 if (_matchFinder == null)
365 {
366 SevenZip.Compression.LZ.BinTree bt = new SevenZip.Compression.LZ.BinTree();
367 int numHashBytes = 4;
368 if (_matchFinderType == EMatchFinderTypeBT2)
369 numHashBytes = 2;
370 bt.SetType(numHashBytes);
371 _matchFinder = bt;
372 }
373 _literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits);
374
375 if (_dictionarySize == _dictionarySizePrev && _numFastBytesPrev == _numFastBytes)
376 return;
377 _matchFinder.Create(_dictionarySize, kNumOpts, _numFastBytes, Base.kMatchMaxLen + 1);
378 _dictionarySizePrev = _dictionarySize;
379 _numFastBytesPrev = _numFastBytes;
380 }
381
382 public Encoder()
383 {
384 for (int i = 0; i < kNumOpts; i++)
385 _optimum[i] = new Optimal();
386 for (int i = 0; i < Base.kNumLenToPosStates; i++)
387 _posSlotEncoder[i] = new BitTreeEncoder(Base.kNumPosSlotBits);
388 }
389
390 void SetWriteEndMarkerMode(boolean writeEndMarker)
391 {
392 _writeEndMark = writeEndMarker;
393 }
394
395 void Init()
396 {
397 BaseInit();
398 _rangeEncoder.Init();
399
400 SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isMatch);
401 SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRep0Long);
402 SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRep);
403 SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRepG0);
404 SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRepG1);
405 SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRepG2);
406 SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_posEncoders);
407
408
409
410
411
412
413
414 _literalEncoder.Init();
415 for (int i = 0; i < Base.kNumLenToPosStates; i++)
416 _posSlotEncoder[i].Init();
417
418
419
420 _lenEncoder.Init(1 << _posStateBits);
421 _repMatchLenEncoder.Init(1 << _posStateBits);
422
423 _posAlignEncoder.Init();
424
425 _longestMatchWasFound = false;
426 _optimumEndIndex = 0;
427 _optimumCurrentIndex = 0;
428 _additionalOffset = 0;
429 }
430
431 int ReadMatchDistances() throws java.io.IOException
432 {
433 int lenRes = 0;
434 _numDistancePairs = _matchFinder.GetMatches(_matchDistances);
435 if (_numDistancePairs > 0)
436 {
437 lenRes = _matchDistances[_numDistancePairs - 2];
438 if (lenRes == _numFastBytes)
439 lenRes += _matchFinder.GetMatchLen((int)lenRes - 1, _matchDistances[_numDistancePairs - 1],
440 Base.kMatchMaxLen - lenRes);
441 }
442 _additionalOffset++;
443 return lenRes;
444 }
445
446 void MovePos(int num) throws java.io.IOException
447 {
448 if (num > 0)
449 {
450 _matchFinder.Skip(num);
451 _additionalOffset += num;
452 }
453 }
454
455 int GetRepLen1Price(int state, int posState)
456 {
457 return SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRepG0[state]) +
458 SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRep0Long[(state << Base.kNumPosStatesBitsMax) + posState]);
459 }
460
461 int GetPureRepPrice(int repIndex, int state, int posState)
462 {
463 int price;
464 if (repIndex == 0)
465 {
466 price = SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRepG0[state]);
467 price += SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep0Long[(state << Base.kNumPosStatesBitsMax) + posState]);
468 }
469 else
470 {
471 price = SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRepG0[state]);
472 if (repIndex == 1)
473 price += SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRepG1[state]);
474 else
475 {
476 price += SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRepG1[state]);
477 price += SevenZip.Compression.RangeCoder.Encoder.GetPrice(_isRepG2[state], repIndex - 2);
478 }
479 }
480 return price;
481 }
482
483 int GetRepPrice(int repIndex, int len, int state, int posState)
484 {
485 int price = _repMatchLenEncoder.GetPrice(len - Base.kMatchMinLen, posState);
486 return price + GetPureRepPrice(repIndex, state, posState);
487 }
488
489 int GetPosLenPrice(int pos, int len, int posState)
490 {
491 int price;
492 int lenToPosState = Base.GetLenToPosState(len);
493 if (pos < Base.kNumFullDistances)
494 price = _distancesPrices[(lenToPosState * Base.kNumFullDistances) + pos];
495 else
496 price = _posSlotPrices[(lenToPosState << Base.kNumPosSlotBits) + GetPosSlot2(pos)] +
497 _alignPrices[pos & Base.kAlignMask];
498 return price + _lenEncoder.GetPrice(len - Base.kMatchMinLen, posState);
499 }
500
501 int Backward(int cur)
502 {
503 _optimumEndIndex = cur;
504 int posMem = _optimum[cur].PosPrev;
505 int backMem = _optimum[cur].BackPrev;
506 do
507 {
508 if (_optimum[cur].Prev1IsChar)
509 {
510 _optimum[posMem].MakeAsChar();
511 _optimum[posMem].PosPrev = posMem - 1;
512 if (_optimum[cur].Prev2)
513 {
514 _optimum[posMem - 1].Prev1IsChar = false;
515 _optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2;
516 _optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2;
517 }
518 }
519 int posPrev = posMem;
520 int backCur = backMem;
521
522 backMem = _optimum[posPrev].BackPrev;
523 posMem = _optimum[posPrev].PosPrev;
524
525 _optimum[posPrev].BackPrev = backCur;
526 _optimum[posPrev].PosPrev = cur;
527 cur = posPrev;
528 }
529 while (cur > 0);
530 backRes = _optimum[0].BackPrev;
531 _optimumCurrentIndex = _optimum[0].PosPrev;
532 return _optimumCurrentIndex;
533 }
534
535 int[] reps = new int[Base.kNumRepDistances];
536 int[] repLens = new int[Base.kNumRepDistances];
537 int backRes;
538
539 int GetOptimum(int position) throws IOException
540 {
541 if (_optimumEndIndex != _optimumCurrentIndex)
542 {
543 int lenRes = _optimum[_optimumCurrentIndex].PosPrev - _optimumCurrentIndex;
544 backRes = _optimum[_optimumCurrentIndex].BackPrev;
545 _optimumCurrentIndex = _optimum[_optimumCurrentIndex].PosPrev;
546 return lenRes;
547 }
548 _optimumCurrentIndex = _optimumEndIndex = 0;
549
550 int lenMain, numDistancePairs;
551 if (!_longestMatchWasFound)
552 {
553 lenMain = ReadMatchDistances();
554 }
555 else
556 {
557 lenMain = _longestMatchLength;
558 _longestMatchWasFound = false;
559 }
560 numDistancePairs = _numDistancePairs;
561
562 int numAvailableBytes = _matchFinder.GetNumAvailableBytes() + 1;
563 if (numAvailableBytes < 2)
564 {
565 backRes = -1;
566 return 1;
567 }
568 if (numAvailableBytes > Base.kMatchMaxLen)
569 numAvailableBytes = Base.kMatchMaxLen;
570
571 int repMaxIndex = 0;
572 int i;
573 for (i = 0; i < Base.kNumRepDistances; i++)
574 {
575 reps[i] = _repDistances[i];
576 repLens[i] = _matchFinder.GetMatchLen(0 - 1, reps[i], Base.kMatchMaxLen);
577 if (repLens[i] > repLens[repMaxIndex])
578 repMaxIndex = i;
579 }
580 if (repLens[repMaxIndex] >= _numFastBytes)
581 {
582 backRes = repMaxIndex;
583 int lenRes = repLens[repMaxIndex];
584 MovePos(lenRes - 1);
585 return lenRes;
586 }
587
588 if (lenMain >= _numFastBytes)
589 {
590 backRes = _matchDistances[numDistancePairs - 1] + Base.kNumRepDistances;
591 MovePos(lenMain - 1);
592 return lenMain;
593 }
594
595 byte currentByte = _matchFinder.GetIndexByte(0 - 1);
596 byte matchByte = _matchFinder.GetIndexByte(0 - _repDistances[0] - 1 - 1);
597
598 if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2)
599 {
600 backRes = -1;
601 return 1;
602 }
603
604 _optimum[0].State = _state;
605
606 int posState = (position & _posStateMask);
607
608 _optimum[1].Price = SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(_state << Base.kNumPosStatesBitsMax) + posState]) +
609 _literalEncoder.GetSubCoder(position, _previousByte).GetPrice(!Base.StateIsCharState(_state), matchByte, currentByte);
610 _optimum[1].MakeAsChar();
611
612 int matchPrice = SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(_state << Base.kNumPosStatesBitsMax) + posState]);
613 int repMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[_state]);
614
615 if (matchByte == currentByte)
616 {
617 int shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState);
618 if (shortRepPrice < _optimum[1].Price)
619 {
620 _optimum[1].Price = shortRepPrice;
621 _optimum[1].MakeAsShortRep();
622 }
623 }
624
625 int lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]);
626
627 if (lenEnd < 2)
628 {
629 backRes = _optimum[1].BackPrev;
630 return 1;
631 }
632
633 _optimum[1].PosPrev = 0;
634
635 _optimum[0].Backs0 = reps[0];
636 _optimum[0].Backs1 = reps[1];
637 _optimum[0].Backs2 = reps[2];
638 _optimum[0].Backs3 = reps[3];
639
640 int len = lenEnd;
641 do
642 _optimum[len--].Price = kIfinityPrice;
643 while (len >= 2);
644
645 for (i = 0; i < Base.kNumRepDistances; i++)
646 {
647 int repLen = repLens[i];
648 if (repLen < 2)
649 continue;
650 int price = repMatchPrice + GetPureRepPrice(i, _state, posState);
651 do
652 {
653 int curAndLenPrice = price + _repMatchLenEncoder.GetPrice(repLen - 2, posState);
654 Optimal optimum = _optimum[repLen];
655 if (curAndLenPrice < optimum.Price)
656 {
657 optimum.Price = curAndLenPrice;
658 optimum.PosPrev = 0;
659 optimum.BackPrev = i;
660 optimum.Prev1IsChar = false;
661 }
662 }
663 while (--repLen >= 2);
664 }
665
666 int normalMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRep[_state]);
667
668 len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
669 if (len <= lenMain)
670 {
671 int offs = 0;
672 while (len > _matchDistances[offs])
673 offs += 2;
674 for (; ; len++)
675 {
676 int distance = _matchDistances[offs + 1];
677 int curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState);
678 Optimal optimum = _optimum[len];
679 if (curAndLenPrice < optimum.Price)
680 {
681 optimum.Price = curAndLenPrice;
682 optimum.PosPrev = 0;
683 optimum.BackPrev = distance + Base.kNumRepDistances;
684 optimum.Prev1IsChar = false;
685 }
686 if (len == _matchDistances[offs])
687 {
688 offs += 2;
689 if (offs == numDistancePairs)
690 break;
691 }
692 }
693 }
694
695 int cur = 0;
696
697 while (true)
698 {
699 cur++;
700 if (cur == lenEnd)
701 return Backward(cur);
702 int newLen = ReadMatchDistances();
703 numDistancePairs = _numDistancePairs;
704 if (newLen >= _numFastBytes)
705 {
706
707 _longestMatchLength = newLen;
708 _longestMatchWasFound = true;
709 return Backward(cur);
710 }
711 position++;
712 int posPrev = _optimum[cur].PosPrev;
713 int state;
714 if (_optimum[cur].Prev1IsChar)
715 {
716 posPrev--;
717 if (_optimum[cur].Prev2)
718 {
719 state = _optimum[_optimum[cur].PosPrev2].State;
720 if (_optimum[cur].BackPrev2 < Base.kNumRepDistances)
721 state = Base.StateUpdateRep(state);
722 else
723 state = Base.StateUpdateMatch(state);
724 }
725 else
726 state = _optimum[posPrev].State;
727 state = Base.StateUpdateChar(state);
728 }
729 else
730 state = _optimum[posPrev].State;
731 if (posPrev == cur - 1)
732 {
733 if (_optimum[cur].IsShortRep())
734 state = Base.StateUpdateShortRep(state);
735 else
736 state = Base.StateUpdateChar(state);
737 }
738 else
739 {
740 int pos;
741 if (_optimum[cur].Prev1IsChar && _optimum[cur].Prev2)
742 {
743 posPrev = _optimum[cur].PosPrev2;
744 pos = _optimum[cur].BackPrev2;
745 state = Base.StateUpdateRep(state);
746 }
747 else
748 {
749 pos = _optimum[cur].BackPrev;
750 if (pos < Base.kNumRepDistances)
751 state = Base.StateUpdateRep(state);
752 else
753 state = Base.StateUpdateMatch(state);
754 }
755 Optimal opt = _optimum[posPrev];
756 if (pos < Base.kNumRepDistances)
757 {
758 if (pos == 0)
759 {
760 reps[0] = opt.Backs0;
761 reps[1] = opt.Backs1;
762 reps[2] = opt.Backs2;
763 reps[3] = opt.Backs3;
764 }
765 else if (pos == 1)
766 {
767 reps[0] = opt.Backs1;
768 reps[1] = opt.Backs0;
769 reps[2] = opt.Backs2;
770 reps[3] = opt.Backs3;
771 }
772 else if (pos == 2)
773 {
774 reps[0] = opt.Backs2;
775 reps[1] = opt.Backs0;
776 reps[2] = opt.Backs1;
777 reps[3] = opt.Backs3;
778 }
779 else
780 {
781 reps[0] = opt.Backs3;
782 reps[1] = opt.Backs0;
783 reps[2] = opt.Backs1;
784 reps[3] = opt.Backs2;
785 }
786 }
787 else
788 {
789 reps[0] = (pos - Base.kNumRepDistances);
790 reps[1] = opt.Backs0;
791 reps[2] = opt.Backs1;
792 reps[3] = opt.Backs2;
793 }
794 }
795 _optimum[cur].State = state;
796 _optimum[cur].Backs0 = reps[0];
797 _optimum[cur].Backs1 = reps[1];
798 _optimum[cur].Backs2 = reps[2];
799 _optimum[cur].Backs3 = reps[3];
800 int curPrice = _optimum[cur].Price;
801
802 currentByte = _matchFinder.GetIndexByte(0 - 1);
803 matchByte = _matchFinder.GetIndexByte(0 - reps[0] - 1 - 1);
804
805 posState = (position & _posStateMask);
806
807 int curAnd1Price = curPrice +
808 SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(state << Base.kNumPosStatesBitsMax) + posState]) +
809 _literalEncoder.GetSubCoder(position, _matchFinder.GetIndexByte(0 - 2)).
810 GetPrice(!Base.StateIsCharState(state), matchByte, currentByte);
811
812 Optimal nextOptimum = _optimum[cur + 1];
813
814 boolean nextIsChar = false;
815 if (curAnd1Price < nextOptimum.Price)
816 {
817 nextOptimum.Price = curAnd1Price;
818 nextOptimum.PosPrev = cur;
819 nextOptimum.MakeAsChar();
820 nextIsChar = true;
821 }
822
823 matchPrice = curPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state << Base.kNumPosStatesBitsMax) + posState]);
824 repMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state]);
825
826 if (matchByte == currentByte &&
827 !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0))
828 {
829 int shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState);
830 if (shortRepPrice <= nextOptimum.Price)
831 {
832 nextOptimum.Price = shortRepPrice;
833 nextOptimum.PosPrev = cur;
834 nextOptimum.MakeAsShortRep();
835 nextIsChar = true;
836 }
837 }
838
839 int numAvailableBytesFull = _matchFinder.GetNumAvailableBytes() + 1;
840 numAvailableBytesFull = Math.min(kNumOpts - 1 - cur, numAvailableBytesFull);
841 numAvailableBytes = numAvailableBytesFull;
842
843 if (numAvailableBytes < 2)
844 continue;
845 if (numAvailableBytes > _numFastBytes)
846 numAvailableBytes = _numFastBytes;
847 if (!nextIsChar && matchByte != currentByte)
848 {
849 // try Literal + rep0
850 int t = Math.min(numAvailableBytesFull - 1, _numFastBytes);
851 int lenTest2 = _matchFinder.GetMatchLen(0, reps[0], t);
852 if (lenTest2 >= 2)
853 {
854 int state2 = Base.StateUpdateChar(state);
855
856 int posStateNext = (position + 1) & _posStateMask;
857 int nextRepMatchPrice = curAnd1Price +
858 SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]) +
859 SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state2]);
860 {
861 int offset = cur + 1 + lenTest2;
862 while (lenEnd < offset)
863 _optimum[++lenEnd].Price = kIfinityPrice;
864 int curAndLenPrice = nextRepMatchPrice + GetRepPrice(
865 0, lenTest2, state2, posStateNext);
866 Optimal optimum = _optimum[offset];
867 if (curAndLenPrice < optimum.Price)
868 {
869 optimum.Price = curAndLenPrice;
870 optimum.PosPrev = cur + 1;
871 optimum.BackPrev = 0;
872 optimum.Prev1IsChar = true;
873 optimum.Prev2 = false;
874 }
875 }
876 }
877 }
878
879 int startLen = 2; // speed optimization
880
881 for (int repIndex = 0; repIndex < Base.kNumRepDistances; repIndex++)
882 {
883 int lenTest = _matchFinder.GetMatchLen(0 - 1, reps[repIndex], numAvailableBytes);
884 if (lenTest < 2)
885 continue;
886 int lenTestTemp = lenTest;
887 do
888 {
889 while (lenEnd < cur + lenTest)
890 _optimum[++lenEnd].Price = kIfinityPrice;
891 int curAndLenPrice = repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState);
892 Optimal optimum = _optimum[cur + lenTest];
893 if (curAndLenPrice < optimum.Price)
894 {
895 optimum.Price = curAndLenPrice;
896 optimum.PosPrev = cur;
897 optimum.BackPrev = repIndex;
898 optimum.Prev1IsChar = false;
899 }
900 }
901 while (--lenTest >= 2);
902 lenTest = lenTestTemp;
903
904 if (repIndex == 0)
905 startLen = lenTest + 1;
906
907 // if (_maxMode)
908 if (lenTest < numAvailableBytesFull)
909 {
910 int t = Math.min(numAvailableBytesFull - 1 - lenTest, _numFastBytes);
911 int lenTest2 = _matchFinder.GetMatchLen(lenTest, reps[repIndex], t);
912 if (lenTest2 >= 2)
913 {
914 int state2 = Base.StateUpdateRep(state);
915
916 int posStateNext = (position + lenTest) & _posStateMask;
917 int curAndLenCharPrice =
918 repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState) +
919 SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]) +
920 _literalEncoder.GetSubCoder(position + lenTest,
921 _matchFinder.GetIndexByte(lenTest - 1 - 1)).GetPrice(true,
922 _matchFinder.GetIndexByte(lenTest - 1 - (reps[repIndex] + 1)),
923 _matchFinder.GetIndexByte(lenTest - 1));
924 state2 = Base.StateUpdateChar(state2);
925 posStateNext = (position + lenTest + 1) & _posStateMask;
926 int nextMatchPrice = curAndLenCharPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]);
927 int nextRepMatchPrice = nextMatchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state2]);
928
929 // for(; lenTest2 >= 2; lenTest2--)
930 {
931 int offset = lenTest + 1 + lenTest2;
932 while (lenEnd < cur + offset)
933 _optimum[++lenEnd].Price = kIfinityPrice;
934 int curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);
935 Optimal optimum = _optimum[cur + offset];
936 if (curAndLenPrice < optimum.Price)
937 {
938 optimum.Price = curAndLenPrice;
939 optimum.PosPrev = cur + lenTest + 1;
940 optimum.BackPrev = 0;
941 optimum.Prev1IsChar = true;
942 optimum.Prev2 = true;
943 optimum.PosPrev2 = cur;
944 optimum.BackPrev2 = repIndex;
945 }
946 }
947 }
948 }
949 }
950
951 if (newLen > numAvailableBytes)
952 {
953 newLen = numAvailableBytes;
954 for (numDistancePairs = 0; newLen > _matchDistances[numDistancePairs]; numDistancePairs += 2) ;
955 _matchDistances[numDistancePairs] = newLen;
956 numDistancePairs += 2;
957 }
958 if (newLen >= startLen)
959 {
960 normalMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRep[state]);
961 while (lenEnd < cur + newLen)
962 _optimum[++lenEnd].Price = kIfinityPrice;
963
964 int offs = 0;
965 while (startLen > _matchDistances[offs])
966 offs += 2;
967
968 for (int lenTest = startLen; ; lenTest++)
969 {
970 int curBack = _matchDistances[offs + 1];
971 int curAndLenPrice = normalMatchPrice + GetPosLenPrice(curBack, lenTest, posState);
972 Optimal optimum = _optimum[cur + lenTest];
973 if (curAndLenPrice < optimum.Price)
974 {
975 optimum.Price = curAndLenPrice;
976 optimum.PosPrev = cur;
977 optimum.BackPrev = curBack + Base.kNumRepDistances;
978 optimum.Prev1IsChar = false;
979 }
980
981 if (lenTest == _matchDistances[offs])
982 {
983 if (lenTest < numAvailableBytesFull)
984 {
985 int t = Math.min(numAvailableBytesFull - 1 - lenTest, _numFastBytes);
986 int lenTest2 = _matchFinder.GetMatchLen(lenTest, curBack, t);
987 if (lenTest2 >= 2)
988 {
989 int state2 = Base.StateUpdateMatch(state);
990
991 int posStateNext = (position + lenTest) & _posStateMask;
992 int curAndLenCharPrice = curAndLenPrice +
993 SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]) +
994 _literalEncoder.GetSubCoder(position + lenTest,
995 _matchFinder.GetIndexByte(lenTest - 1 - 1)).
996 GetPrice(true,
997 _matchFinder.GetIndexByte(lenTest - (curBack + 1) - 1),
998 _matchFinder.GetIndexByte(lenTest - 1));
999 state2 = Base.StateUpdateChar(state2);
1000 posStateNext = (position + lenTest + 1) & _posStateMask;
1001 int nextMatchPrice = curAndLenCharPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]);
1002 int nextRepMatchPrice = nextMatchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state2]);
1003
1004 int offset = lenTest + 1 + lenTest2;
1005 while (lenEnd < cur + offset)
1006 _optimum[++lenEnd].Price = kIfinityPrice;
1007 curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);
1008 optimum = _optimum[cur + offset];
1009 if (curAndLenPrice < optimum.Price)
1010 {
1011 optimum.Price = curAndLenPrice;
1012 optimum.PosPrev = cur + lenTest + 1;
1013 optimum.BackPrev = 0;
1014 optimum.Prev1IsChar = true;
1015 optimum.Prev2 = true;
1016 optimum.PosPrev2 = cur;
1017 optimum.BackPrev2 = curBack + Base.kNumRepDistances;
1018 }
1019 }
1020 }
1021 offs += 2;
1022 if (offs == numDistancePairs)
1023 break;
1024 }
1025 }
1026 }
1027 }
1028 }
1029
1030 boolean ChangePair(int smallDist, int bigDist)
1031 {
1032 int kDif = 7;
1033 return (smallDist < (1 << (32 - kDif)) && bigDist >= (smallDist << kDif));
1034 }
1035
1036 void WriteEndMarker(int posState) throws IOException
1037 {
1038 if (!_writeEndMark)
1039 return;
1040
1041 _rangeEncoder.Encode(_isMatch, (_state << Base.kNumPosStatesBitsMax) + posState, 1);
1042 _rangeEncoder.Encode(_isRep, _state, 0);
1043 _state = Base.StateUpdateMatch(_state);
1044 int len = Base.kMatchMinLen;
1045 _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);
1046 int posSlot = (1 << Base.kNumPosSlotBits) - 1;
1047 int lenToPosState = Base.GetLenToPosState(len);
1048 _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot);
1049 int footerBits = 30;
1050 int posReduced = (1 << footerBits) - 1;
1051 _rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits);
1052 _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask);
1053 }
1054
1055 void Flush(int nowPos) throws IOException
1056 {
1057 ReleaseMFStream();
1058 WriteEndMarker(nowPos & _posStateMask);
1059 _rangeEncoder.FlushData();
1060 _rangeEncoder.FlushStream();
1061 }
1062
1063 public void CodeOneBlock(long[] inSize, long[] outSize, boolean[] finished) throws IOException
1064 {
1065 inSize[0] = 0;
1066 outSize[0] = 0;
1067 finished[0] = true;
1068
1069 if (_inStream != null)
1070 {
1071 _matchFinder.SetStream(_inStream);
1072 _matchFinder.Init();
1073 _needReleaseMFStream = true;
1074 _inStream = null;
1075 }
1076
1077 if (_finished)
1078 return;
1079 _finished = true;
1080
1081
1082 long progressPosValuePrev = nowPos64;
1083 if (nowPos64 == 0)
1084 {
1085 if (_matchFinder.GetNumAvailableBytes() == 0)
1086 {
1087 Flush((int)nowPos64);
1088 return;
1089 }
1090
1091 ReadMatchDistances();
1092 int posState = (int)(nowPos64) & _posStateMask;
1093 _rangeEncoder.Encode(_isMatch, (_state << Base.kNumPosStatesBitsMax) + posState, 0);
1094 _state = Base.StateUpdateChar(_state);
1095 byte curByte = _matchFinder.GetIndexByte(0 - _additionalOffset);
1096 _literalEncoder.GetSubCoder((int)(nowPos64), _previousByte).Encode(_rangeEncoder, curByte);
1097 _previousByte = curByte;
1098 _additionalOffset--;
1099 nowPos64++;
1100 }
1101 if (_matchFinder.GetNumAvailableBytes() == 0)
1102 {
1103 Flush((int)nowPos64);
1104 return;
1105 }
1106 while (true)
1107 {
1108
1109 int len = GetOptimum((int)nowPos64);
1110 int pos = backRes;
1111 int posState = ((int)nowPos64) & _posStateMask;
1112 int complexState = (_state << Base.kNumPosStatesBitsMax) + posState;
1113 if (len == 1 && pos == -1)
1114 {
1115 _rangeEncoder.Encode(_isMatch, complexState, 0);
1116 byte curByte = _matchFinder.GetIndexByte((int)(0 - _additionalOffset));
1117 LiteralEncoder.Encoder2 subCoder = _literalEncoder.GetSubCoder((int)nowPos64, _previousByte);
1118 if (!Base.StateIsCharState(_state))
1119 {
1120 byte matchByte = _matchFinder.GetIndexByte((int)(0 - _repDistances[0] - 1 - _additionalOffset));
1121 subCoder.EncodeMatched(_rangeEncoder, matchByte, curByte);
1122 }
1123 else
1124 subCoder.Encode(_rangeEncoder, curByte);
1125 _previousByte = curByte;
1126 _state = Base.StateUpdateChar(_state);
1127 }
1128 else
1129 {
1130 _rangeEncoder.Encode(_isMatch, complexState, 1);
1131 if (pos < Base.kNumRepDistances)
1132 {
1133 _rangeEncoder.Encode(_isRep, _state, 1);
1134 if (pos == 0)
1135 {
1136 _rangeEncoder.Encode(_isRepG0, _state, 0);
1137 if (len == 1)
1138 _rangeEncoder.Encode(_isRep0Long, complexState, 0);
1139 else
1140 _rangeEncoder.Encode(_isRep0Long, complexState, 1);
1141 }
1142 else
1143 {
1144 _rangeEncoder.Encode(_isRepG0, _state, 1);
1145 if (pos == 1)
1146 _rangeEncoder.Encode(_isRepG1, _state, 0);
1147 else
1148 {
1149 _rangeEncoder.Encode(_isRepG1, _state, 1);
1150 _rangeEncoder.Encode(_isRepG2, _state, pos - 2);
1151 }
1152 }
1153 if (len == 1)
1154 _state = Base.StateUpdateShortRep(_state);
1155 else
1156 {
1157 _repMatchLenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);
1158 _state = Base.StateUpdateRep(_state);
1159 }
1160 int distance = _repDistances[pos];
1161 if (pos != 0)
1162 {
1163 for (int i = pos; i >= 1; i--)
1164 _repDistances[i] = _repDistances[i - 1];
1165 _repDistances[0] = distance;
1166 }
1167 }
1168 else
1169 {
1170 _rangeEncoder.Encode(_isRep, _state, 0);
1171 _state = Base.StateUpdateMatch(_state);
1172 _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);
1173 pos -= Base.kNumRepDistances;
1174 int posSlot = GetPosSlot(pos);
1175 int lenToPosState = Base.GetLenToPosState(len);
1176 _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot);
1177
1178 if (posSlot >= Base.kStartPosModelIndex)
1179 {
1180 int footerBits = (int)((posSlot >> 1) - 1);
1181 int baseVal = ((2 | (posSlot & 1)) << footerBits);
1182 int posReduced = pos - baseVal;
1183
1184 if (posSlot < Base.kEndPosModelIndex)
1185 BitTreeEncoder.ReverseEncode(_posEncoders,
1186 baseVal - posSlot - 1, _rangeEncoder, footerBits, posReduced);
1187 else
1188 {
1189 _rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits);
1190 _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask);
1191 _alignPriceCount++;
1192 }
1193 }
1194 int distance = pos;
1195 for (int i = Base.kNumRepDistances - 1; i >= 1; i--)
1196 _repDistances[i] = _repDistances[i - 1];
1197 _repDistances[0] = distance;
1198 _matchPriceCount++;
1199 }
1200 _previousByte = _matchFinder.GetIndexByte(len - 1 - _additionalOffset);
1201 }
1202 _additionalOffset -= len;
1203 nowPos64 += len;
1204 if (_additionalOffset == 0)
1205 {
1206 // if (!_fastMode)
1207 if (_matchPriceCount >= (1 << 7))
1208 FillDistancesPrices();
1209 if (_alignPriceCount >= Base.kAlignTableSize)
1210 FillAlignPrices();
1211 inSize[0] = nowPos64;
1212 outSize[0] = _rangeEncoder.GetProcessedSizeAdd();
1213 if (_matchFinder.GetNumAvailableBytes() == 0)
1214 {
1215 Flush((int)nowPos64);
1216 return;
1217 }
1218
1219 if (nowPos64 - progressPosValuePrev >= (1 << 12))
1220 {
1221 _finished = false;
1222 finished[0] = false;
1223 return;
1224 }
1225 }
1226 }
1227 }
1228
1229 void ReleaseMFStream()
1230 {
1231 if (_matchFinder != null && _needReleaseMFStream)
1232 {
1233 _matchFinder.ReleaseStream();
1234 _needReleaseMFStream = false;
1235 }
1236 }
1237
1238 void SetOutStream(java.io.OutputStream outStream)
1239 { _rangeEncoder.SetStream(outStream); }
1240 void ReleaseOutStream()
1241 { _rangeEncoder.ReleaseStream(); }
1242
1243 void ReleaseStreams()
1244 {
1245 ReleaseMFStream();
1246 ReleaseOutStream();
1247 }
1248
1249 void SetStreams(java.io.InputStream inStream, java.io.OutputStream outStream,
1250 long inSize, long outSize)
1251 {
1252 _inStream = inStream;
1253 _finished = false;
1254 Create();
1255 SetOutStream(outStream);
1256 Init();
1257
1258 // if (!_fastMode)
1259 {
1260 FillDistancesPrices();
1261 FillAlignPrices();
1262 }
1263
1264 _lenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen);
1265 _lenEncoder.UpdateTables(1 << _posStateBits);
1266 _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen);
1267 _repMatchLenEncoder.UpdateTables(1 << _posStateBits);
1268
1269 nowPos64 = 0;
1270 }
1271
1272 long[] processedInSize = new long[1]; long[] processedOutSize = new long[1]; boolean[] finished = new boolean[1];
1273 public void Code(java.io.InputStream inStream, java.io.OutputStream outStream,
1274 long inSize, long outSize, ICodeProgress progress) throws IOException
1275 {
1276 _needReleaseMFStream = false;
1277 try
1278 {
1279 SetStreams(inStream, outStream, inSize, outSize);
1280 while (true)
1281 {
1282
1283
1284
1285 CodeOneBlock(processedInSize, processedOutSize, finished);
1286 if (finished[0])
1287 return;
1288 if (progress != null)
1289 {
1290 progress.SetProgress(processedInSize[0], processedOutSize[0]);
1291 }
1292 }
1293 }
1294 finally
1295 {
1296 ReleaseStreams();
1297 }
1298 }
1299
1300 public static final int kPropSize = 5;
1301 byte[] properties = new byte[kPropSize];
1302
1303 public void WriteCoderProperties(java.io.OutputStream outStream) throws IOException
1304 {
1305 properties[0] = (byte)((_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits);
1306 for (int i = 0; i < 4; i++)
1307 properties[1 + i] = (byte)(_dictionarySize >> (8 * i));
1308 outStream.write(properties, 0, kPropSize);
1309 }
1310
1311 int[] tempPrices = new int[Base.kNumFullDistances];
1312 int _matchPriceCount;
1313
1314 void FillDistancesPrices()
1315 {
1316 for (int i = Base.kStartPosModelIndex; i < Base.kNumFullDistances; i++)
1317 {
1318 int posSlot = GetPosSlot(i);
1319 int footerBits = (int)((posSlot >> 1) - 1);
1320 int baseVal = ((2 | (posSlot & 1)) << footerBits);
1321 tempPrices[i] = BitTreeEncoder.ReverseGetPrice(_posEncoders,
1322 baseVal - posSlot - 1, footerBits, i - baseVal);
1323 }
1324
1325 for (int lenToPosState = 0; lenToPosState < Base.kNumLenToPosStates; lenToPosState++)
1326 {
1327 int posSlot;
1328 BitTreeEncoder encoder = _posSlotEncoder[lenToPosState];
1329
1330 int st = (lenToPosState << Base.kNumPosSlotBits);
1331 for (posSlot = 0; posSlot < _distTableSize; posSlot++)
1332 _posSlotPrices[st + posSlot] = encoder.GetPrice(posSlot);
1333 for (posSlot = Base.kEndPosModelIndex; posSlot < _distTableSize; posSlot++)
1334 _posSlotPrices[st + posSlot] += ((((posSlot >> 1) - 1) - Base.kNumAlignBits) << SevenZip.Compression.RangeCoder.Encoder.kNumBitPriceShiftBits);
1335
1336 int st2 = lenToPosState * Base.kNumFullDistances;
1337 int i;
1338 for (i = 0; i < Base.kStartPosModelIndex; i++)
1339 _distancesPrices[st2 + i] = _posSlotPrices[st + i];
1340 for (; i < Base.kNumFullDistances; i++)
1341 _distancesPrices[st2 + i] = _posSlotPrices[st + GetPosSlot(i)] + tempPrices[i];
1342 }
1343 _matchPriceCount = 0;
1344 }
1345
1346 void FillAlignPrices()
1347 {
1348 for (int i = 0; i < Base.kAlignTableSize; i++)
1349 _alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i);
1350 _alignPriceCount = 0;
1351 }
1352
1353
1354 public boolean SetAlgorithm(int algorithm)
1355 {
1356 /*
1357 _fastMode = (algorithm == 0);
1358 _maxMode = (algorithm >= 2);
1359 */
1360 return true;
1361 }
1362
1363 public boolean SetDictionarySize(int dictionarySize)
1364 {
1365 int kDicLogSizeMaxCompress = 29;
1366 if (dictionarySize < (1 << Base.kDicLogSizeMin) || dictionarySize > (1 << kDicLogSizeMaxCompress))
1367 return false;
1368 _dictionarySize = dictionarySize;
1369 int dicLogSize;
1370 for (dicLogSize = 0; dictionarySize > (1 << dicLogSize); dicLogSize++) ;
1371 _distTableSize = dicLogSize * 2;
1372 return true;
1373 }
1374
1375 public boolean SeNumFastBytes(int numFastBytes)
1376 {
1377 if (numFastBytes < 5 || numFastBytes > Base.kMatchMaxLen)
1378 return false;
1379 _numFastBytes = numFastBytes;
1380 return true;
1381 }
1382
1383 public boolean SetMatchFinder(int matchFinderIndex)
1384 {
1385 if (matchFinderIndex < 0 || matchFinderIndex > 2)
1386 return false;
1387 int matchFinderIndexPrev = _matchFinderType;
1388 _matchFinderType = matchFinderIndex;
1389 if (_matchFinder != null && matchFinderIndexPrev != _matchFinderType)
1390 {
1391 _dictionarySizePrev = -1;
1392 _matchFinder = null;
1393 }
1394 return true;
1395 }
1396
1397 public boolean SetLcLpPb(int lc, int lp, int pb)
1398 {
1399 if (
1400 lp < 0 || lp > Base.kNumLitPosStatesBitsEncodingMax ||
1401 lc < 0 || lc > Base.kNumLitContextBitsMax ||
1402 pb < 0 || pb > Base.kNumPosStatesBitsEncodingMax)
1403 return false;
1404 _numLiteralPosStateBits = lp;
1405 _numLiteralContextBits = lc;
1406 _posStateBits = pb;
1407 _posStateMask = ((1) << _posStateBits) - 1;
1408 return true;
1409 }
1410
1411 public void SetEndMarkerMode(boolean endMarkerMode)
1412 {
1413 _writeEndMark = endMarkerMode;
1414 }
1415}
1416
Note: See TracBrowser for help on using the repository browser.