Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: third_party/lzma/v4_65/files/CS/7zip/Compress/LZMA/LzmaEncoder.cs

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // LzmaEncoder.cs
2
3 using System;
4
5 namespace SevenZip.Compression.LZMA
6 {
7 using RangeCoder;
8
9 public class Encoder : ICoder, ISetCoderProperties, IWriteCoderPropertie s
10 {
11 enum EMatchFinderType
12 {
13 BT2,
14 BT4,
15 };
16
17 const UInt32 kIfinityPrice = 0xFFFFFFF;
18
19 static Byte[] g_FastPos = new Byte[1 << 11];
20
21 static Encoder()
22 {
23 const Byte kFastSlots = 22;
24 int c = 2;
25 g_FastPos[0] = 0;
26 g_FastPos[1] = 1;
27 for (Byte slotFast = 2; slotFast < kFastSlots; slotFast+ +)
28 {
29 UInt32 k = ((UInt32)1 << ((slotFast >> 1) - 1));
30 for (UInt32 j = 0; j < k; j++, c++)
31 g_FastPos[c] = slotFast;
32 }
33 }
34
35 static UInt32 GetPosSlot(UInt32 pos)
36 {
37 if (pos < (1 << 11))
38 return g_FastPos[pos];
39 if (pos < (1 << 21))
40 return (UInt32)(g_FastPos[pos >> 10] + 20);
41 return (UInt32)(g_FastPos[pos >> 20] + 40);
42 }
43
44 static UInt32 GetPosSlot2(UInt32 pos)
45 {
46 if (pos < (1 << 17))
47 return (UInt32)(g_FastPos[pos >> 6] + 12);
48 if (pos < (1 << 27))
49 return (UInt32)(g_FastPos[pos >> 16] + 32);
50 return (UInt32)(g_FastPos[pos >> 26] + 52);
51 }
52
53 Base.State _state = new Base.State();
54 Byte _previousByte;
55 UInt32[] _repDistances = new UInt32[Base.kNumRepDistances];
56
57 void BaseInit()
58 {
59 _state.Init();
60 _previousByte = 0;
61 for (UInt32 i = 0; i < Base.kNumRepDistances; i++)
62 _repDistances[i] = 0;
63 }
64
65 const int kDefaultDictionaryLogSize = 22;
66 const UInt32 kNumFastBytesDefault = 0x20;
67
68 class LiteralEncoder
69 {
70 public struct Encoder2
71 {
72 BitEncoder[] m_Encoders;
73
74 public void Create() { m_Encoders = new BitEncod er[0x300]; }
75
76 public void Init() { for (int i = 0; i < 0x300; i++) m_Encoders[i].Init(); }
77
78 public void Encode(RangeCoder.Encoder rangeEncod er, byte symbol)
79 {
80 uint context = 1;
81 for (int i = 7; i >= 0; i--)
82 {
83 uint bit = (uint)((symbol >> i) & 1);
84 m_Encoders[context].Encode(range Encoder, bit);
85 context = (context << 1) | bit;
86 }
87 }
88
89 public void EncodeMatched(RangeCoder.Encoder ran geEncoder, byte matchByte, byte symbol)
90 {
91 uint context = 1;
92 bool same = true;
93 for (int i = 7; i >= 0; i--)
94 {
95 uint bit = (uint)((symbol >> i) & 1);
96 uint state = context;
97 if (same)
98 {
99 uint matchBit = (uint)(( matchByte >> i) & 1);
100 state += ((1 + matchBit) << 8);
101 same = (matchBit == bit) ;
102 }
103 m_Encoders[state].Encode(rangeEn coder, bit);
104 context = (context << 1) | bit;
105 }
106 }
107
108 public uint GetPrice(bool matchMode, byte matchB yte, byte symbol)
109 {
110 uint price = 0;
111 uint context = 1;
112 int i = 7;
113 if (matchMode)
114 {
115 for (; i >= 0; i--)
116 {
117 uint matchBit = (uint)(m atchByte >> i) & 1;
118 uint bit = (uint)(symbol >> i) & 1;
119 price += m_Encoders[((1 + matchBit) << 8) + context].GetPrice(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 uint bit = (uint)(symbol >> i) & 1;
131 price += m_Encoders[context].Get Price(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 uint m_PosMask;
142
143 public void Create(int numPosBits, int numPrevBits)
144 {
145 if (m_Coders != null && m_NumPrevBits == numPrev Bits && m_NumPosBits == numPosBits)
146 return;
147 m_NumPosBits = numPosBits;
148 m_PosMask = ((uint)1 << numPosBits) - 1;
149 m_NumPrevBits = numPrevBits;
150 uint numStates = (uint)1 << (m_NumPrevBits + m_N umPosBits);
151 m_Coders = new Encoder2[numStates];
152 for (uint i = 0; i < numStates; i++)
153 m_Coders[i].Create();
154 }
155
156 public void Init()
157 {
158 uint numStates = (uint)1 << (m_NumPrevBits + m_N umPosBits);
159 for (uint i = 0; i < numStates; i++)
160 m_Coders[i].Init();
161 }
162
163 public Encoder2 GetSubCoder(UInt32 pos, Byte prevByte)
164 { return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits))]; }
165 }
166
167 class LenEncoder
168 {
169 RangeCoder.BitEncoder _choice = new RangeCoder.BitEncode r();
170 RangeCoder.BitEncoder _choice2 = new RangeCoder.BitEncod er();
171 RangeCoder.BitTreeEncoder[] _lowCoder = new RangeCoder.B itTreeEncoder[Base.kNumPosStatesEncodingMax];
172 RangeCoder.BitTreeEncoder[] _midCoder = new RangeCoder.B itTreeEncoder[Base.kNumPosStatesEncodingMax];
173 RangeCoder.BitTreeEncoder _highCoder = new RangeCoder.Bi tTreeEncoder(Base.kNumHighLenBits);
174
175 public LenEncoder()
176 {
177 for (UInt32 posState = 0; posState < Base.kNumPo sStatesEncodingMax; posState++)
178 {
179 _lowCoder[posState] = new RangeCoder.Bit TreeEncoder(Base.kNumLowLenBits);
180 _midCoder[posState] = new RangeCoder.Bit TreeEncoder(Base.kNumMidLenBits);
181 }
182 }
183
184 public void Init(UInt32 numPosStates)
185 {
186 _choice.Init();
187 _choice2.Init();
188 for (UInt32 posState = 0; posState < numPosState s; posState++)
189 {
190 _lowCoder[posState].Init();
191 _midCoder[posState].Init();
192 }
193 _highCoder.Init();
194 }
195
196 public void Encode(RangeCoder.Encoder rangeEncoder, UInt 32 symbol, UInt32 posState)
197 {
198 if (symbol < Base.kNumLowLenSymbols)
199 {
200 _choice.Encode(rangeEncoder, 0);
201 _lowCoder[posState].Encode(rangeEncoder, symbol);
202 }
203 else
204 {
205 symbol -= Base.kNumLowLenSymbols;
206 _choice.Encode(rangeEncoder, 1);
207 if (symbol < Base.kNumMidLenSymbols)
208 {
209 _choice2.Encode(rangeEncoder, 0) ;
210 _midCoder[posState].Encode(range Encoder, symbol);
211 }
212 else
213 {
214 _choice2.Encode(rangeEncoder, 1) ;
215 _highCoder.Encode(rangeEncoder, symbol - Base.kNumMidLenSymbols);
216 }
217 }
218 }
219
220 public void SetPrices(UInt32 posState, UInt32 numSymbols , UInt32[] prices, UInt32 st)
221 {
222 UInt32 a0 = _choice.GetPrice0();
223 UInt32 a1 = _choice.GetPrice1();
224 UInt32 b0 = a1 + _choice2.GetPrice0();
225 UInt32 b1 = a1 + _choice2.GetPrice1();
226 UInt32 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.kNumMid LenSymbols; 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.GetPric e(i - Base.kNumLowLenSymbols - Base.kNumMidLenSymbols);
241 }
242 };
243
244 const UInt32 kNumLenSpecSymbols = Base.kNumLowLenSymbols + Base. kNumMidLenSymbols;
245
246 class LenPriceTableEncoder : LenEncoder
247 {
248 UInt32[] _prices = new UInt32[Base.kNumLenSymbols << Bas e.kNumPosStatesBitsEncodingMax];
249 UInt32 _tableSize;
250 UInt32[] _counters = new UInt32[Base.kNumPosStatesEncodi ngMax];
251
252 public void SetTableSize(UInt32 tableSize) { _tableSize = tableSize; }
253
254 public UInt32 GetPrice(UInt32 symbol, UInt32 posState)
255 {
256 return _prices[posState * Base.kNumLenSymbols + symbol];
257 }
258
259 void UpdateTable(UInt32 posState)
260 {
261 SetPrices(posState, _tableSize, _prices, posStat e * Base.kNumLenSymbols);
262 _counters[posState] = _tableSize;
263 }
264
265 public void UpdateTables(UInt32 numPosStates)
266 {
267 for (UInt32 posState = 0; posState < numPosState s; posState++)
268 UpdateTable(posState);
269 }
270
271 public new void Encode(RangeCoder.Encoder rangeEncoder, UInt32 symbol, UInt32 posState)
272 {
273 base.Encode(rangeEncoder, symbol, posState);
274 if (--_counters[posState] == 0)
275 UpdateTable(posState);
276 }
277 }
278
279 const UInt32 kNumOpts = 1 << 12;
280 class Optimal
281 {
282 public Base.State State;
283
284 public bool Prev1IsChar;
285 public bool Prev2;
286
287 public UInt32 PosPrev2;
288 public UInt32 BackPrev2;
289
290 public UInt32 Price;
291 public UInt32 PosPrev;
292 public UInt32 BackPrev;
293
294 public UInt32 Backs0;
295 public UInt32 Backs1;
296 public UInt32 Backs2;
297 public UInt32 Backs3;
298
299 public void MakeAsChar() { BackPrev = 0xFFFFFFFF; Prev1I sChar = false; }
300 public void MakeAsShortRep() { BackPrev = 0; ; Prev1IsCh ar = false; }
301 public bool IsShortRep() { return (BackPrev == 0); }
302 };
303 Optimal[] _optimum = new Optimal[kNumOpts];
304 LZ.IMatchFinder _matchFinder = null;
305 RangeCoder.Encoder _rangeEncoder = new RangeCoder.Encoder();
306
307 RangeCoder.BitEncoder[] _isMatch = new RangeCoder.BitEncoder[Bas e.kNumStates << Base.kNumPosStatesBitsMax];
308 RangeCoder.BitEncoder[] _isRep = new RangeCoder.BitEncoder[Base. kNumStates];
309 RangeCoder.BitEncoder[] _isRepG0 = new RangeCoder.BitEncoder[Bas e.kNumStates];
310 RangeCoder.BitEncoder[] _isRepG1 = new RangeCoder.BitEncoder[Bas e.kNumStates];
311 RangeCoder.BitEncoder[] _isRepG2 = new RangeCoder.BitEncoder[Bas e.kNumStates];
312 RangeCoder.BitEncoder[] _isRep0Long = new RangeCoder.BitEncoder[ Base.kNumStates << Base.kNumPosStatesBitsMax];
313
314 RangeCoder.BitTreeEncoder[] _posSlotEncoder = new RangeCoder.Bit TreeEncoder[Base.kNumLenToPosStates];
315
316 RangeCoder.BitEncoder[] _posEncoders = new RangeCoder.BitEncoder [Base.kNumFullDistances - Base.kEndPosModelIndex];
317 RangeCoder.BitTreeEncoder _posAlignEncoder = new RangeCoder.BitT reeEncoder(Base.kNumAlignBits);
318
319 LenPriceTableEncoder _lenEncoder = new LenPriceTableEncoder();
320 LenPriceTableEncoder _repMatchLenEncoder = new LenPriceTableEnco der();
321
322 LiteralEncoder _literalEncoder = new LiteralEncoder();
323
324 UInt32[] _matchDistances = new UInt32[Base.kMatchMaxLen * 2 + 2] ;
325
326 UInt32 _numFastBytes = kNumFastBytesDefault;
327 UInt32 _longestMatchLength;
328 UInt32 _numDistancePairs;
329
330 UInt32 _additionalOffset;
331
332 UInt32 _optimumEndIndex;
333 UInt32 _optimumCurrentIndex;
334
335 bool _longestMatchWasFound;
336
337 UInt32[] _posSlotPrices = new UInt32[1 << (Base.kNumPosSlotBits + Base.kNumLenToPosStatesBits)];
338 UInt32[] _distancesPrices = new UInt32[Base.kNumFullDistances << Base.kNumLenToPosStatesBits];
339 UInt32[] _alignPrices = new UInt32[Base.kAlignTableSize];
340 UInt32 _alignPriceCount;
341
342 UInt32 _distTableSize = (kDefaultDictionaryLogSize * 2);
343
344 int _posStateBits = 2;
345 UInt32 _posStateMask = (4 - 1);
346 int _numLiteralPosStateBits = 0;
347 int _numLiteralContextBits = 3;
348
349 UInt32 _dictionarySize = (1 << kDefaultDictionaryLogSize);
350 UInt32 _dictionarySizePrev = 0xFFFFFFFF;
351 UInt32 _numFastBytesPrev = 0xFFFFFFFF;
352
353 Int64 nowPos64;
354 bool _finished;
355 System.IO.Stream _inStream;
356
357 EMatchFinderType _matchFinderType = EMatchFinderType.BT4;
358 bool _writeEndMark = false;
359
360 bool _needReleaseMFStream;
361
362 void Create()
363 {
364 if (_matchFinder == null)
365 {
366 LZ.BinTree bt = new LZ.BinTree();
367 int numHashBytes = 4;
368 if (_matchFinderType == EMatchFinderType.BT2)
369 numHashBytes = 2;
370 bt.SetType(numHashBytes);
371 _matchFinder = bt;
372 }
373 _literalEncoder.Create(_numLiteralPosStateBits, _numLite ralContextBits);
374
375 if (_dictionarySize == _dictionarySizePrev && _numFastBy tesPrev == _numFastBytes)
376 return;
377 _matchFinder.Create(_dictionarySize, kNumOpts, _numFastB ytes, 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 RangeCoder.BitTreeEncod er(Base.kNumPosSlotBits);
388 }
389
390 void SetWriteEndMarkerMode(bool writeEndMarker)
391 {
392 _writeEndMark = writeEndMarker;
393 }
394
395 void Init()
396 {
397 BaseInit();
398 _rangeEncoder.Init();
399
400 uint i;
401 for (i = 0; i < Base.kNumStates; i++)
402 {
403 for (uint j = 0; j <= _posStateMask; j++)
404 {
405 uint complexState = (i << Base.kNumPosSt atesBitsMax) + j;
406 _isMatch[complexState].Init();
407 _isRep0Long[complexState].Init();
408 }
409 _isRep[i].Init();
410 _isRepG0[i].Init();
411 _isRepG1[i].Init();
412 _isRepG2[i].Init();
413 }
414 _literalEncoder.Init();
415 for (i = 0; i < Base.kNumLenToPosStates; i++)
416 _posSlotEncoder[i].Init();
417 for (i = 0; i < Base.kNumFullDistances - Base.kEndPosMod elIndex; i++)
418 _posEncoders[i].Init();
419
420 _lenEncoder.Init((UInt32)1 << _posStateBits);
421 _repMatchLenEncoder.Init((UInt32)1 << _posStateBits);
422
423 _posAlignEncoder.Init();
424
425 _longestMatchWasFound = false;
426 _optimumEndIndex = 0;
427 _optimumCurrentIndex = 0;
428 _additionalOffset = 0;
429 }
430
431 void ReadMatchDistances(out UInt32 lenRes, out UInt32 numDistanc ePairs)
432 {
433 lenRes = 0;
434 numDistancePairs = _matchFinder.GetMatches(_matchDistanc es);
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 }
444
445
446 void MovePos(UInt32 num)
447 {
448 if (num > 0)
449 {
450 _matchFinder.Skip(num);
451 _additionalOffset += num;
452 }
453 }
454
455 UInt32 GetRepLen1Price(Base.State state, UInt32 posState)
456 {
457 return _isRepG0[state.Index].GetPrice0() +
458 _isRep0Long[(state.Index << Base.kNumPos StatesBitsMax) + posState].GetPrice0();
459 }
460
461 UInt32 GetPureRepPrice(UInt32 repIndex, Base.State state, UInt32 posState)
462 {
463 UInt32 price;
464 if (repIndex == 0)
465 {
466 price = _isRepG0[state.Index].GetPrice0();
467 price += _isRep0Long[(state.Index << Base.kNumPo sStatesBitsMax) + posState].GetPrice1();
468 }
469 else
470 {
471 price = _isRepG0[state.Index].GetPrice1();
472 if (repIndex == 1)
473 price += _isRepG1[state.Index].GetPrice0 ();
474 else
475 {
476 price += _isRepG1[state.Index].GetPrice1 ();
477 price += _isRepG2[state.Index].GetPrice( repIndex - 2);
478 }
479 }
480 return price;
481 }
482
483 UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, Base.State state , UInt32 posState)
484 {
485 UInt32 price = _repMatchLenEncoder.GetPrice(len - Base.k MatchMinLen, posState);
486 return price + GetPureRepPrice(repIndex, state, posState );
487 }
488
489 UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState)
490 {
491 UInt32 price;
492 UInt32 lenToPosState = Base.GetLenToPosState(len);
493 if (pos < Base.kNumFullDistances)
494 price = _distancesPrices[(lenToPosState * Base.k NumFullDistances) + pos];
495 else
496 price = _posSlotPrices[(lenToPosState << Base.kN umPosSlotBits) + GetPosSlot2(pos)] +
497 _alignPrices[pos & Base.kAlignMask];
498 return price + _lenEncoder.GetPrice(len - Base.kMatchMin Len, posState);
499 }
500
501 UInt32 Backward(out UInt32 backRes, UInt32 cur)
502 {
503 _optimumEndIndex = cur;
504 UInt32 posMem = _optimum[cur].PosPrev;
505 UInt32 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 UInt32 posPrev = posMem;
520 UInt32 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 UInt32[] reps = new UInt32[Base.kNumRepDistances];
536 UInt32[] repLens = new UInt32[Base.kNumRepDistances];
537
538
539 UInt32 GetOptimum(UInt32 position, out UInt32 backRes)
540 {
541 if (_optimumEndIndex != _optimumCurrentIndex)
542 {
543 UInt32 lenRes = _optimum[_optimumCurrentIndex].P osPrev - _optimumCurrentIndex;
544 backRes = _optimum[_optimumCurrentIndex].BackPre v;
545 _optimumCurrentIndex = _optimum[_optimumCurrentI ndex].PosPrev;
546 return lenRes;
547 }
548 _optimumCurrentIndex = _optimumEndIndex = 0;
549
550 UInt32 lenMain, numDistancePairs;
551 if (!_longestMatchWasFound)
552 {
553 ReadMatchDistances(out lenMain, out numDistanceP airs);
554 }
555 else
556 {
557 lenMain = _longestMatchLength;
558 numDistancePairs = _numDistancePairs;
559 _longestMatchWasFound = false;
560 }
561
562 UInt32 numAvailableBytes = _matchFinder.GetNumAvailableB ytes() + 1;
563 if (numAvailableBytes < 2)
564 {
565 backRes = 0xFFFFFFFF;
566 return 1;
567 }
568 if (numAvailableBytes > Base.kMatchMaxLen)
569 numAvailableBytes = Base.kMatchMaxLen;
570
571 UInt32 repMaxIndex = 0;
572 UInt32 i;
573 for (i = 0; i < Base.kNumRepDistances; i++)
574 {
575 reps[i] = _repDistances[i];
576 repLens[i] = _matchFinder.GetMatchLen(0 - 1, rep s[i], Base.kMatchMaxLen);
577 if (repLens[i] > repLens[repMaxIndex])
578 repMaxIndex = i;
579 }
580 if (repLens[repMaxIndex] >= _numFastBytes)
581 {
582 backRes = repMaxIndex;
583 UInt32 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((Int32)(0 - _ repDistances[0] - 1 - 1));
597
598 if (lenMain < 2 && currentByte != matchByte && repLens[r epMaxIndex] < 2)
599 {
600 backRes = (UInt32)0xFFFFFFFF;
601 return 1;
602 }
603
604 _optimum[0].State = _state;
605
606 UInt32 posState = (position & _posStateMask);
607
608 _optimum[1].Price = _isMatch[(_state.Index << Base.kNumP osStatesBitsMax) + posState].GetPrice0() +
609 _literalEncoder.GetSubCoder(position, _p reviousByte).GetPrice(!_state.IsCharState(), matchByte, currentByte);
610 _optimum[1].MakeAsChar();
611
612 UInt32 matchPrice = _isMatch[(_state.Index << Base.kNumP osStatesBitsMax) + posState].GetPrice1();
613 UInt32 repMatchPrice = matchPrice + _isRep[_state.Index] .GetPrice1();
614
615 if (matchByte == currentByte)
616 {
617 UInt32 shortRepPrice = repMatchPrice + GetRepLen 1Price(_state, posState);
618 if (shortRepPrice < _optimum[1].Price)
619 {
620 _optimum[1].Price = shortRepPrice;
621 _optimum[1].MakeAsShortRep();
622 }
623 }
624
625 UInt32 lenEnd = ((lenMain >= repLens[repMaxIndex]) ? len Main : 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 UInt32 len = lenEnd;
641 do
642 _optimum[len--].Price = kIfinityPrice;
643 while (len >= 2);
644
645 for (i = 0; i < Base.kNumRepDistances; i++)
646 {
647 UInt32 repLen = repLens[i];
648 if (repLen < 2)
649 continue;
650 UInt32 price = repMatchPrice + GetPureRepPrice(i , _state, posState);
651 do
652 {
653 UInt32 curAndLenPrice = price + _repMatc hLenEncoder.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 UInt32 normalMatchPrice = matchPrice + _isRep[_state.Ind ex].GetPrice0();
667
668 len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
669 if (len <= lenMain)
670 {
671 UInt32 offs = 0;
672 while (len > _matchDistances[offs])
673 offs += 2;
674 for (; ; len++)
675 {
676 UInt32 distance = _matchDistances[offs + 1];
677 UInt32 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 + Ba se.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 UInt32 cur = 0;
696
697 while (true)
698 {
699 cur++;
700 if (cur == lenEnd)
701 return Backward(out backRes, cur);
702 UInt32 newLen;
703 ReadMatchDistances(out newLen, out numDistancePa irs);
704 if (newLen >= _numFastBytes)
705 {
706 _numDistancePairs = numDistancePairs;
707 _longestMatchLength = newLen;
708 _longestMatchWasFound = true;
709 return Backward(out backRes, cur);
710 }
711 position++;
712 UInt32 posPrev = _optimum[cur].PosPrev;
713 Base.State state;
714 if (_optimum[cur].Prev1IsChar)
715 {
716 posPrev--;
717 if (_optimum[cur].Prev2)
718 {
719 state = _optimum[_optimum[cur].P osPrev2].State;
720 if (_optimum[cur].BackPrev2 < Ba se.kNumRepDistances)
721 state.UpdateRep();
722 else
723 state.UpdateMatch();
724 }
725 else
726 state = _optimum[posPrev].State;
727 state.UpdateChar();
728 }
729 else
730 state = _optimum[posPrev].State;
731 if (posPrev == cur - 1)
732 {
733 if (_optimum[cur].IsShortRep())
734 state.UpdateShortRep();
735 else
736 state.UpdateChar();
737 }
738 else
739 {
740 UInt32 pos;
741 if (_optimum[cur].Prev1IsChar && _optimu m[cur].Prev2)
742 {
743 posPrev = _optimum[cur].PosPrev2 ;
744 pos = _optimum[cur].BackPrev2;
745 state.UpdateRep();
746 }
747 else
748 {
749 pos = _optimum[cur].BackPrev;
750 if (pos < Base.kNumRepDistances)
751 state.UpdateRep();
752 else
753 state.UpdateMatch();
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.kNumRepDis tances);
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 UInt32 curPrice = _optimum[cur].Price;
801
802 currentByte = _matchFinder.GetIndexByte(0 - 1);
803 matchByte = _matchFinder.GetIndexByte((Int32)(0 - reps[0] - 1 - 1));
804
805 posState = (position & _posStateMask);
806
807 UInt32 curAnd1Price = curPrice +
808 _isMatch[(state.Index << Base.kNumPosSta tesBitsMax) + posState].GetPrice0() +
809 _literalEncoder.GetSubCoder(position, _m atchFinder.GetIndexByte(0 - 2)).
810 GetPrice(!state.IsCharState(), matchByte , currentByte);
811
812 Optimal nextOptimum = _optimum[cur + 1];
813
814 bool 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 + _isMatch[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice1();
824 repMatchPrice = matchPrice + _isRep[state.Index] .GetPrice1();
825
826 if (matchByte == currentByte &&
827 !(nextOptimum.PosPrev < cur && nextOptim um.BackPrev == 0))
828 {
829 UInt32 shortRepPrice = repMatchPrice + G etRepLen1Price(state, posState);
830 if (shortRepPrice <= nextOptimum.Price)
831 {
832 nextOptimum.Price = shortRepPric e;
833 nextOptimum.PosPrev = cur;
834 nextOptimum.MakeAsShortRep();
835 nextIsChar = true;
836 }
837 }
838
839 UInt32 numAvailableBytesFull = _matchFinder.GetN umAvailableBytes() + 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 UInt32 t = Math.Min(numAvailableBytesFul l - 1, _numFastBytes);
851 UInt32 lenTest2 = _matchFinder.GetMatchL en(0, reps[0], t);
852 if (lenTest2 >= 2)
853 {
854 Base.State state2 = state;
855 state2.UpdateChar();
856 UInt32 posStateNext = (position + 1) & _posStateMask;
857 UInt32 nextRepMatchPrice = curAn d1Price +
858 _isMatch[(state2.Index < < Base.kNumPosStatesBitsMax) + posStateNext].GetPrice1() +
859 _isRep[state2.Index].Get Price1();
860 {
861 UInt32 offset = cur + 1 + lenTest2;
862 while (lenEnd < offset)
863 _optimum[++lenEn d].Price = kIfinityPrice;
864 UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(
865 0, lenTest2, sta te2, posStateNext);
866 Optimal optimum = _optim um[offset];
867 if (curAndLenPrice < opt imum.Price)
868 {
869 optimum.Price = curAndLenPrice;
870 optimum.PosPrev = cur + 1;
871 optimum.BackPrev = 0;
872 optimum.Prev1IsC har = true;
873 optimum.Prev2 = false;
874 }
875 }
876 }
877 }
878
879 UInt32 startLen = 2; // speed optimization
880
881 for (UInt32 repIndex = 0; repIndex < Base.kNumRe pDistances; repIndex++)
882 {
883 UInt32 lenTest = _matchFinder.GetMatchLe n(0 - 1, reps[repIndex], numAvailableBytes);
884 if (lenTest < 2)
885 continue;
886 UInt32 lenTestTemp = lenTest;
887 do
888 {
889 while (lenEnd < cur + lenTest)
890 _optimum[++lenEnd].Price = kIfinityPrice;
891 UInt32 curAndLenPrice = repMatch Price + GetRepPrice(repIndex, lenTest, state, posState);
892 Optimal optimum = _optimum[cur + lenTest];
893 if (curAndLenPrice < optimum.Pri ce)
894 {
895 optimum.Price = curAndLe nPrice;
896 optimum.PosPrev = cur;
897 optimum.BackPrev = repIn dex;
898 optimum.Prev1IsChar = fa lse;
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 UInt32 t = Math.Min(numAvailable BytesFull - 1 - lenTest, _numFastBytes);
911 UInt32 lenTest2 = _matchFinder.G etMatchLen((Int32)lenTest, reps[repIndex], t);
912 if (lenTest2 >= 2)
913 {
914 Base.State state2 = stat e;
915 state2.UpdateRep();
916 UInt32 posStateNext = (p osition + lenTest) & _posStateMask;
917 UInt32 curAndLenCharPric e =
918 repMatch Price + GetRepPrice(repIndex, lenTest, state, posState) +
919 _isMatch [(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice0() +
920 _literal Encoder.GetSubCoder(position + lenTest,
921 _matchFi nder.GetIndexByte((Int32)lenTest - 1 - 1)).GetPrice(true,
922 _matchFi nder.GetIndexByte((Int32)((Int32)lenTest - 1 - (Int32)(reps[repIndex] + 1))),
923 _matchFi nder.GetIndexByte((Int32)lenTest - 1));
924 state2.UpdateChar();
925 posStateNext = (position + lenTest + 1) & _posStateMask;
926 UInt32 nextMatchPrice = curAndLenCharPrice + _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posS tateNext].GetPrice1();
927 UInt32 nextRepMatchPrice = nextMatchPrice + _isRep[state2.Index].GetPrice1();
928
929 // for(; lenTest2 >= 2; lenTest2--)
930 {
931 UInt32 offset = lenTest + 1 + lenTest2;
932 while(lenEnd < c ur + offset)
933 _optimum [++lenEnd].Price = kIfinityPrice;
934 UInt32 curAndLen Price = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);
935 Optimal optimum = _optimum[cur + offset];
936 if (curAndLenPri ce < 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 > _mat chDistances[numDistancePairs]; numDistancePairs += 2) ;
955 _matchDistances[numDistancePairs] = newL en;
956 numDistancePairs += 2;
957 }
958 if (newLen >= startLen)
959 {
960 normalMatchPrice = matchPrice + _isRep[s tate.Index].GetPrice0();
961 while (lenEnd < cur + newLen)
962 _optimum[++lenEnd].Price = kIfin ityPrice;
963
964 UInt32 offs = 0;
965 while (startLen > _matchDistances[offs])
966 offs += 2;
967
968 for (UInt32 lenTest = startLen; ; lenTes t++)
969 {
970 UInt32 curBack = _matchDistances [offs + 1];
971 UInt32 curAndLenPrice = normalMa tchPrice + GetPosLenPrice(curBack, lenTest, posState);
972 Optimal optimum = _optimum[cur + lenTest];
973 if (curAndLenPrice < optimum.Pri ce)
974 {
975 optimum.Price = curAndLe nPrice;
976 optimum.PosPrev = cur;
977 optimum.BackPrev = curBa ck + Base.kNumRepDistances;
978 optimum.Prev1IsChar = fa lse;
979 }
980
981 if (lenTest == _matchDistances[o ffs])
982 {
983 if (lenTest < numAvailab leBytesFull)
984 {
985 UInt32 t = Math. Min(numAvailableBytesFull - 1 - lenTest, _numFastBytes);
986 UInt32 lenTest2 = _matchFinder.GetMatchLen((Int32)lenTest, curBack, t);
987 if (lenTest2 >= 2)
988 {
989 Base.Sta te state2 = state;
990 state2.U pdateMatch();
991 UInt32 p osStateNext = (position + lenTest) & _posStateMask;
992 UInt32 c urAndLenCharPrice = curAndLenPrice +
993 _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice0() +
994 _literalEncoder.GetSubCoder(position + lenTest,
995 _matchFinder.GetIndexByte((Int32)lenTest - 1 - 1)).
996 GetPrice(true,
997 _matchFinder.GetIndexByte((Int32)lenTest - (Int32)(curBack + 1) - 1),
998 _matchFinder.GetIndexByte((Int32)lenTest - 1));
999 state2.U pdateChar();
1000 posState Next = (position + lenTest + 1) & _posStateMask;
1001 UInt32 n extMatchPrice = curAndLenCharPrice + _isMatch[(state2.Index << Base.kNumPosState sBitsMax) + posStateNext].GetPrice1();
1002 UInt32 n extRepMatchPrice = nextMatchPrice + _isRep[state2.Index].GetPrice1();
1003
1004 UInt32 o ffset = lenTest + 1 + lenTest2;
1005 while (l enEnd < cur + offset)
1006 _optimum[++lenEnd].Price = kIfinityPrice;
1007 curAndLe nPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);
1008 optimum = _optimum[cur + offset];
1009 if (curA ndLenPrice < 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 == numDistanceP airs)
1023 break;
1024 }
1025 }
1026 }
1027 }
1028 }
1029
1030 bool ChangePair(UInt32 smallDist, UInt32 bigDist)
1031 {
1032 const int kDif = 7;
1033 return (smallDist < ((UInt32)(1) << (32 - kDif)) && bigD ist >= (smallDist << kDif));
1034 }
1035
1036 void WriteEndMarker(UInt32 posState)
1037 {
1038 if (!_writeEndMark)
1039 return;
1040
1041 _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + p osState].Encode(_rangeEncoder, 1);
1042 _isRep[_state.Index].Encode(_rangeEncoder, 0);
1043 _state.UpdateMatch();
1044 UInt32 len = Base.kMatchMinLen;
1045 _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLe n, posState);
1046 UInt32 posSlot = (1 << Base.kNumPosSlotBits) - 1;
1047 UInt32 lenToPosState = Base.GetLenToPosState(len);
1048 _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, pos Slot);
1049 int footerBits = 30;
1050 UInt32 posReduced = (((UInt32)1) << footerBits) - 1;
1051 _rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAl ignBits, footerBits - Base.kNumAlignBits);
1052 _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask);
1053 }
1054
1055 void Flush(UInt32 nowPos)
1056 {
1057 ReleaseMFStream();
1058 WriteEndMarker(nowPos & _posStateMask);
1059 _rangeEncoder.FlushData();
1060 _rangeEncoder.FlushStream();
1061 }
1062
1063 public void CodeOneBlock(out Int64 inSize, out Int64 outSize, ou t bool finished)
1064 {
1065 inSize = 0;
1066 outSize = 0;
1067 finished = true;
1068
1069 if (_inStream != null)
1070 {
1071 _matchFinder.SetStream(_inStream);
1072 _matchFinder.Init();
1073 _needReleaseMFStream = true;
1074 _inStream = null;
1075 if (_trainSize > 0)
1076 _matchFinder.Skip(_trainSize);
1077 }
1078
1079 if (_finished)
1080 return;
1081 _finished = true;
1082
1083
1084 Int64 progressPosValuePrev = nowPos64;
1085 if (nowPos64 == 0)
1086 {
1087 if (_matchFinder.GetNumAvailableBytes() == 0)
1088 {
1089 Flush((UInt32)nowPos64);
1090 return;
1091 }
1092 UInt32 len, numDistancePairs; // it's not used
1093 ReadMatchDistances(out len, out numDistancePairs );
1094 UInt32 posState = (UInt32)(nowPos64) & _posState Mask;
1095 _isMatch[(_state.Index << Base.kNumPosStatesBits Max) + posState].Encode(_rangeEncoder, 0);
1096 _state.UpdateChar();
1097 Byte curByte = _matchFinder.GetIndexByte((Int32) (0 - _additionalOffset));
1098 _literalEncoder.GetSubCoder((UInt32)(nowPos64), _previousByte).Encode(_rangeEncoder, curByte);
1099 _previousByte = curByte;
1100 _additionalOffset--;
1101 nowPos64++;
1102 }
1103 if (_matchFinder.GetNumAvailableBytes() == 0)
1104 {
1105 Flush((UInt32)nowPos64);
1106 return;
1107 }
1108 while (true)
1109 {
1110 UInt32 pos;
1111 UInt32 len = GetOptimum((UInt32)nowPos64, out po s);
1112
1113 UInt32 posState = ((UInt32)nowPos64) & _posState Mask;
1114 UInt32 complexState = (_state.Index << Base.kNum PosStatesBitsMax) + posState;
1115 if (len == 1 && pos == 0xFFFFFFFF)
1116 {
1117 _isMatch[complexState].Encode(_rangeEnco der, 0);
1118 Byte curByte = _matchFinder.GetIndexByte ((Int32)(0 - _additionalOffset));
1119 LiteralEncoder.Encoder2 subCoder = _lite ralEncoder.GetSubCoder((UInt32)nowPos64, _previousByte);
1120 if (!_state.IsCharState())
1121 {
1122 Byte matchByte = _matchFinder.Ge tIndexByte((Int32)(0 - _repDistances[0] - 1 - _additionalOffset));
1123 subCoder.EncodeMatched(_rangeEnc oder, matchByte, curByte);
1124 }
1125 else
1126 subCoder.Encode(_rangeEncoder, c urByte);
1127 _previousByte = curByte;
1128 _state.UpdateChar();
1129 }
1130 else
1131 {
1132 _isMatch[complexState].Encode(_rangeEnco der, 1);
1133 if (pos < Base.kNumRepDistances)
1134 {
1135 _isRep[_state.Index].Encode(_ran geEncoder, 1);
1136 if (pos == 0)
1137 {
1138 _isRepG0[_state.Index].E ncode(_rangeEncoder, 0);
1139 if (len == 1)
1140 _isRep0Long[comp lexState].Encode(_rangeEncoder, 0);
1141 else
1142 _isRep0Long[comp lexState].Encode(_rangeEncoder, 1);
1143 }
1144 else
1145 {
1146 _isRepG0[_state.Index].E ncode(_rangeEncoder, 1);
1147 if (pos == 1)
1148 _isRepG1[_state. Index].Encode(_rangeEncoder, 0);
1149 else
1150 {
1151 _isRepG1[_state. Index].Encode(_rangeEncoder, 1);
1152 _isRepG2[_state. Index].Encode(_rangeEncoder, pos - 2);
1153 }
1154 }
1155 if (len == 1)
1156 _state.UpdateShortRep();
1157 else
1158 {
1159 _repMatchLenEncoder.Enco de(_rangeEncoder, len - Base.kMatchMinLen, posState);
1160 _state.UpdateRep();
1161 }
1162 UInt32 distance = _repDistances[ pos];
1163 if (pos != 0)
1164 {
1165 for (UInt32 i = pos; i > = 1; i--)
1166 _repDistances[i] = _repDistances[i - 1];
1167 _repDistances[0] = dista nce;
1168 }
1169 }
1170 else
1171 {
1172 _isRep[_state.Index].Encode(_ran geEncoder, 0);
1173 _state.UpdateMatch();
1174 _lenEncoder.Encode(_rangeEncoder , len - Base.kMatchMinLen, posState);
1175 pos -= Base.kNumRepDistances;
1176 UInt32 posSlot = GetPosSlot(pos) ;
1177 UInt32 lenToPosState = Base.GetL enToPosState(len);
1178 _posSlotEncoder[lenToPosState].E ncode(_rangeEncoder, posSlot);
1179
1180 if (posSlot >= Base.kStartPosMod elIndex)
1181 {
1182 int footerBits = (int)(( posSlot >> 1) - 1);
1183 UInt32 baseVal = ((2 | ( posSlot & 1)) << footerBits);
1184 UInt32 posReduced = pos - baseVal;
1185
1186 if (posSlot < Base.kEndP osModelIndex)
1187 RangeCoder.BitTr eeEncoder.ReverseEncode(_posEncoders,
1188 baseVal - posSlot - 1, _rangeEncoder, footerBits, posReduced);
1189 else
1190 {
1191 _rangeEncoder.En codeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits );
1192 _posAlignEncoder .ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask);
1193 _alignPriceCount ++;
1194 }
1195 }
1196 UInt32 distance = pos;
1197 for (UInt32 i = Base.kNumRepDist ances - 1; i >= 1; i--)
1198 _repDistances[i] = _repD istances[i - 1];
1199 _repDistances[0] = distance;
1200 _matchPriceCount++;
1201 }
1202 _previousByte = _matchFinder.GetIndexByt e((Int32)(len - 1 - _additionalOffset));
1203 }
1204 _additionalOffset -= len;
1205 nowPos64 += len;
1206 if (_additionalOffset == 0)
1207 {
1208 // if (!_fastMode)
1209 if (_matchPriceCount >= (1 << 7))
1210 FillDistancesPrices();
1211 if (_alignPriceCount >= Base.kAlignTable Size)
1212 FillAlignPrices();
1213 inSize = nowPos64;
1214 outSize = _rangeEncoder.GetProcessedSize Add();
1215 if (_matchFinder.GetNumAvailableBytes() == 0)
1216 {
1217 Flush((UInt32)nowPos64);
1218 return;
1219 }
1220
1221 if (nowPos64 - progressPosValuePrev >= ( 1 << 12))
1222 {
1223 _finished = false;
1224 finished = false;
1225 return;
1226 }
1227 }
1228 }
1229 }
1230
1231 void ReleaseMFStream()
1232 {
1233 if (_matchFinder != null && _needReleaseMFStream)
1234 {
1235 _matchFinder.ReleaseStream();
1236 _needReleaseMFStream = false;
1237 }
1238 }
1239
1240 void SetOutStream(System.IO.Stream outStream) { _rangeEncoder.Se tStream(outStream); }
1241 void ReleaseOutStream() { _rangeEncoder.ReleaseStream(); }
1242
1243 void ReleaseStreams()
1244 {
1245 ReleaseMFStream();
1246 ReleaseOutStream();
1247 }
1248
1249 void SetStreams(System.IO.Stream inStream, System.IO.Stream outS tream,
1250 Int64 inSize, Int64 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.kMatch MinLen);
1265 _lenEncoder.UpdateTables((UInt32)1 << _posStateBits);
1266 _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - Bas e.kMatchMinLen);
1267 _repMatchLenEncoder.UpdateTables((UInt32)1 << _posStateB its);
1268
1269 nowPos64 = 0;
1270 }
1271
1272
1273 public void Code(System.IO.Stream inStream, System.IO.Stream out Stream,
1274 Int64 inSize, Int64 outSize, ICodeProgress progress)
1275 {
1276 _needReleaseMFStream = false;
1277 try
1278 {
1279 SetStreams(inStream, outStream, inSize, outSize) ;
1280 while (true)
1281 {
1282 Int64 processedInSize;
1283 Int64 processedOutSize;
1284 bool finished;
1285 CodeOneBlock(out processedInSize, out pr ocessedOutSize, out finished);
1286 if (finished)
1287 return;
1288 if (progress != null)
1289 {
1290 progress.SetProgress(processedIn Size, processedOutSize);
1291 }
1292 }
1293 }
1294 finally
1295 {
1296 ReleaseStreams();
1297 }
1298 }
1299
1300 const int kPropSize = 5;
1301 Byte[] properties = new Byte[kPropSize];
1302
1303 public void WriteCoderProperties(System.IO.Stream outStream)
1304 {
1305 properties[0] = (Byte)((_posStateBits * 5 + _numLiteralP osStateBits) * 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 UInt32[] tempPrices = new UInt32[Base.kNumFullDistances];
1312 UInt32 _matchPriceCount;
1313
1314 void FillDistancesPrices()
1315 {
1316 for (UInt32 i = Base.kStartPosModelIndex; i < Base.kNumF ullDistances; i++)
1317 {
1318 UInt32 posSlot = GetPosSlot(i);
1319 int footerBits = (int)((posSlot >> 1) - 1);
1320 UInt32 baseVal = ((2 | (posSlot & 1)) << footerB its);
1321 tempPrices[i] = BitTreeEncoder.ReverseGetPrice(_ posEncoders,
1322 baseVal - posSlot - 1, footerBits, i - b aseVal);
1323 }
1324
1325 for (UInt32 lenToPosState = 0; lenToPosState < Base.kNum LenToPosStates; lenToPosState++)
1326 {
1327 UInt32 posSlot;
1328 RangeCoder.BitTreeEncoder encoder = _posSlotEnco der[lenToPosState];
1329
1330 UInt32 st = (lenToPosState << Base.kNumPosSlotBi ts);
1331 for (posSlot = 0; posSlot < _distTableSize; posS lot++)
1332 _posSlotPrices[st + posSlot] = encoder.G etPrice(posSlot);
1333 for (posSlot = Base.kEndPosModelIndex; posSlot < _distTableSize; posSlot++)
1334 _posSlotPrices[st + posSlot] += ((((posS lot >> 1) - 1) - Base.kNumAlignBits) << RangeCoder.BitEncoder.kNumBitPriceShiftB its);
1335
1336 UInt32 st2 = lenToPosState * Base.kNumFullDistan ces;
1337 UInt32 i;
1338 for (i = 0; i < Base.kStartPosModelIndex; i++)
1339 _distancesPrices[st2 + i] = _posSlotPric es[st + i];
1340 for (; i < Base.kNumFullDistances; i++)
1341 _distancesPrices[st2 + i] = _posSlotPric es[st + GetPosSlot(i)] + tempPrices[i];
1342 }
1343 _matchPriceCount = 0;
1344 }
1345
1346 void FillAlignPrices()
1347 {
1348 for (UInt32 i = 0; i < Base.kAlignTableSize; i++)
1349 _alignPrices[i] = _posAlignEncoder.ReverseGetPri ce(i);
1350 _alignPriceCount = 0;
1351 }
1352
1353
1354 static string[] kMatchFinderIDs =
1355 {
1356 "BT2",
1357 "BT4",
1358 };
1359
1360 static int FindMatchFinder(string s)
1361 {
1362 for (int m = 0; m < kMatchFinderIDs.Length; m++)
1363 if (s == kMatchFinderIDs[m])
1364 return m;
1365 return -1;
1366 }
1367
1368 public void SetCoderProperties(CoderPropID[] propIDs, object[] p roperties)
1369 {
1370 for (UInt32 i = 0; i < properties.Length; i++)
1371 {
1372 object prop = properties[i];
1373 switch (propIDs[i])
1374 {
1375 case CoderPropID.NumFastBytes:
1376 {
1377 if (!(prop is Int32))
1378 throw new InvalidParamEx ception();
1379 Int32 numFastBytes = (Int32)prop ;
1380 if (numFastBytes < 5 || numFastB ytes > Base.kMatchMaxLen)
1381 throw new InvalidParamEx ception();
1382 _numFastBytes = (UInt32)numFastB ytes;
1383 break;
1384 }
1385 case CoderPropID.Algorithm:
1386 {
1387 /*
1388 if (!(prop is Int32))
1389 throw new InvalidParamEx ception();
1390 Int32 maximize = (Int32)prop;
1391 _fastMode = (maximize == 0);
1392 _maxMode = (maximize >= 2);
1393 */
1394 break;
1395 }
1396 case CoderPropID.MatchFinder:
1397 {
1398 if (!(prop is String))
1399 throw new InvalidParamEx ception();
1400 EMatchFinderType matchFinderInde xPrev = _matchFinderType;
1401 int m = FindMatchFinder(((string )prop).ToUpper());
1402 if (m < 0)
1403 throw new InvalidParamEx ception();
1404 _matchFinderType = (EMatchFinder Type)m;
1405 if (_matchFinder != null && matc hFinderIndexPrev != _matchFinderType)
1406 {
1407 _dictionarySizePrev = 0x FFFFFFFF;
1408 _matchFinder = null;
1409 }
1410 break;
1411 }
1412 case CoderPropID.DictionarySize:
1413 {
1414 const int kDicLogSizeMaxCompress = 30;
1415 if (!(prop is Int32))
1416 throw new InvalidParamEx ception(); ;
1417 Int32 dictionarySize = (Int32)pr op;
1418 if (dictionarySize < (UInt32)(1 << Base.kDicLogSizeMin) ||
1419 dictionarySize > (UInt32 )(1 << kDicLogSizeMaxCompress))
1420 throw new InvalidParamEx ception();
1421 _dictionarySize = (UInt32)dictio narySize;
1422 int dicLogSize;
1423 for (dicLogSize = 0; dicLogSize < (UInt32)kDicLogSizeMaxCompress; dicLogSize++)
1424 if (dictionarySize <= (( UInt32)(1) << dicLogSize))
1425 break;
1426 _distTableSize = (UInt32)dicLogS ize * 2;
1427 break;
1428 }
1429 case CoderPropID.PosStateBits:
1430 {
1431 if (!(prop is Int32))
1432 throw new InvalidParamEx ception();
1433 Int32 v = (Int32)prop;
1434 if (v < 0 || v > (UInt32)Base.kN umPosStatesBitsEncodingMax)
1435 throw new InvalidParamEx ception();
1436 _posStateBits = (int)v;
1437 _posStateMask = (((UInt32)1) << (int)_posStateBits) - 1;
1438 break;
1439 }
1440 case CoderPropID.LitPosBits:
1441 {
1442 if (!(prop is Int32))
1443 throw new InvalidParamEx ception();
1444 Int32 v = (Int32)prop;
1445 if (v < 0 || v > (UInt32)Base.kN umLitPosStatesBitsEncodingMax)
1446 throw new InvalidParamEx ception();
1447 _numLiteralPosStateBits = (int)v ;
1448 break;
1449 }
1450 case CoderPropID.LitContextBits:
1451 {
1452 if (!(prop is Int32))
1453 throw new InvalidParamEx ception();
1454 Int32 v = (Int32)prop;
1455 if (v < 0 || v > (UInt32)Base.kN umLitContextBitsMax)
1456 throw new InvalidParamEx ception(); ;
1457 _numLiteralContextBits = (int)v;
1458 break;
1459 }
1460 case CoderPropID.EndMarker:
1461 {
1462 if (!(prop is Boolean))
1463 throw new InvalidParamEx ception();
1464 SetWriteEndMarkerMode((Boolean)p rop);
1465 break;
1466 }
1467 default:
1468 throw new InvalidParamException( );
1469 }
1470 }
1471 }
1472
1473 uint _trainSize = 0;
1474 public void SetTrainSize(uint trainSize)
1475 {
1476 _trainSize = trainSize;
1477 }
1478
1479 }
1480 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698