com.wallstop-studios.unity-helpers 2.0.0-rc79 → 2.0.0-rc79.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/Runtime/Protobuf-Net/System.Collections.Immutable.dll +0 -0
  2. package/Runtime/Protobuf-Net/System.Runtime.CompilerServices.Unsafe.dll +0 -0
  3. package/Runtime/Protobuf-Net/protobuf-net.Core.dll +0 -0
  4. package/Runtime/Protobuf-Net/protobuf-net.dll +0 -0
  5. package/Runtime/Utils/LZMA.cs +53 -0
  6. package/Runtime/Utils/LZMA.cs.meta +3 -0
  7. package/Runtime/Utils/SevenZip/Common/CRC.cs +61 -0
  8. package/Runtime/Utils/SevenZip/Common/CRC.cs.meta +11 -0
  9. package/Runtime/Utils/SevenZip/Common/InBuffer.cs +71 -0
  10. package/Runtime/Utils/SevenZip/Common/InBuffer.cs.meta +11 -0
  11. package/Runtime/Utils/SevenZip/Common/OutBuffer.cs +65 -0
  12. package/Runtime/Utils/SevenZip/Common/OutBuffer.cs.meta +11 -0
  13. package/Runtime/Utils/SevenZip/Common.meta +3 -0
  14. package/Runtime/Utils/SevenZip/Compress/LZ/IMatchFinder.cs +28 -0
  15. package/Runtime/Utils/SevenZip/Compress/LZ/IMatchFinder.cs.meta +11 -0
  16. package/Runtime/Utils/SevenZip/Compress/LZ/LzBinTree.cs +404 -0
  17. package/Runtime/Utils/SevenZip/Compress/LZ/LzBinTree.cs.meta +11 -0
  18. package/Runtime/Utils/SevenZip/Compress/LZ/LzInWindow.cs +153 -0
  19. package/Runtime/Utils/SevenZip/Compress/LZ/LzInWindow.cs.meta +11 -0
  20. package/Runtime/Utils/SevenZip/Compress/LZ/LzOutWindow.cs +110 -0
  21. package/Runtime/Utils/SevenZip/Compress/LZ/LzOutWindow.cs.meta +11 -0
  22. package/Runtime/{Protobuf-Net/System.Collections.Immutable.xml.meta → Utils/SevenZip/Compress/LZ.meta} +3 -2
  23. package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaBase.cs +101 -0
  24. package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaBase.cs.meta +11 -0
  25. package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaDecoder.cs +464 -0
  26. package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaDecoder.cs.meta +11 -0
  27. package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaEncoder.cs +1669 -0
  28. package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaEncoder.cs.meta +11 -0
  29. package/Runtime/Utils/SevenZip/Compress/LZMA.meta +8 -0
  30. package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoder.cs +233 -0
  31. package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoder.cs.meta +11 -0
  32. package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoderBit.cs +137 -0
  33. package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoderBit.cs.meta +11 -0
  34. package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoderBitTree.cs +170 -0
  35. package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoderBitTree.cs.meta +11 -0
  36. package/Runtime/Utils/SevenZip/Compress/RangeCoder.meta +8 -0
  37. package/Runtime/{Protobuf-Net/System.Runtime.CompilerServices.Unsafe.xml.meta → Utils/SevenZip/Compress.meta} +3 -2
  38. package/Runtime/Utils/SevenZip/ICoder.cs +177 -0
  39. package/Runtime/Utils/SevenZip/ICoder.cs.meta +11 -0
  40. package/Runtime/Utils/SevenZip.meta +3 -0
  41. package/package.json +2 -1
  42. package/Runtime/Protobuf-Net/System.Buffers.dll +0 -0
  43. package/Runtime/Protobuf-Net/System.Buffers.dll.meta +0 -33
  44. package/Runtime/Protobuf-Net/System.Collections.Immutable.xml +0 -6812
  45. package/Runtime/Protobuf-Net/System.Numerics.Vectors.dll +0 -0
  46. package/Runtime/Protobuf-Net/System.Numerics.Vectors.dll.meta +0 -33
  47. package/Runtime/Protobuf-Net/System.Runtime.CompilerServices.Unsafe.xml +0 -342
@@ -0,0 +1,1669 @@
1
+ // LzmaEncoder.cs
2
+
3
+ using System;
4
+
5
+ namespace SevenZip.Compression.LZMA
6
+ {
7
+ using RangeCoder;
8
+
9
+ public class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties
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()
75
+ {
76
+ m_Encoders = new BitEncoder[0x300];
77
+ }
78
+
79
+ public void Init()
80
+ {
81
+ for (int i = 0; i < 0x300; i++)
82
+ m_Encoders[i].Init();
83
+ }
84
+
85
+ public void Encode(RangeCoder.Encoder rangeEncoder, byte symbol)
86
+ {
87
+ uint context = 1;
88
+ for (int i = 7; i >= 0; i--)
89
+ {
90
+ uint bit = (uint)((symbol >> i) & 1);
91
+ m_Encoders[context].Encode(rangeEncoder, bit);
92
+ context = (context << 1) | bit;
93
+ }
94
+ }
95
+
96
+ public void EncodeMatched(
97
+ RangeCoder.Encoder rangeEncoder,
98
+ byte matchByte,
99
+ byte symbol
100
+ )
101
+ {
102
+ uint context = 1;
103
+ bool same = true;
104
+ for (int i = 7; i >= 0; i--)
105
+ {
106
+ uint bit = (uint)((symbol >> i) & 1);
107
+ uint state = context;
108
+ if (same)
109
+ {
110
+ uint matchBit = (uint)((matchByte >> i) & 1);
111
+ state += ((1 + matchBit) << 8);
112
+ same = (matchBit == bit);
113
+ }
114
+ m_Encoders[state].Encode(rangeEncoder, bit);
115
+ context = (context << 1) | bit;
116
+ }
117
+ }
118
+
119
+ public uint GetPrice(bool matchMode, byte matchByte, byte symbol)
120
+ {
121
+ uint price = 0;
122
+ uint context = 1;
123
+ int i = 7;
124
+ if (matchMode)
125
+ {
126
+ for (; i >= 0; i--)
127
+ {
128
+ uint matchBit = (uint)(matchByte >> i) & 1;
129
+ uint bit = (uint)(symbol >> i) & 1;
130
+ price += m_Encoders[((1 + matchBit) << 8) + context].GetPrice(bit);
131
+ context = (context << 1) | bit;
132
+ if (matchBit != bit)
133
+ {
134
+ i--;
135
+ break;
136
+ }
137
+ }
138
+ }
139
+ for (; i >= 0; i--)
140
+ {
141
+ uint bit = (uint)(symbol >> i) & 1;
142
+ price += m_Encoders[context].GetPrice(bit);
143
+ context = (context << 1) | bit;
144
+ }
145
+ return price;
146
+ }
147
+ }
148
+
149
+ Encoder2[] m_Coders;
150
+ int m_NumPrevBits;
151
+ int m_NumPosBits;
152
+ uint m_PosMask;
153
+
154
+ public void Create(int numPosBits, int numPrevBits)
155
+ {
156
+ if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits)
157
+ return;
158
+ m_NumPosBits = numPosBits;
159
+ m_PosMask = ((uint)1 << numPosBits) - 1;
160
+ m_NumPrevBits = numPrevBits;
161
+ uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
162
+ m_Coders = new Encoder2[numStates];
163
+ for (uint i = 0; i < numStates; i++)
164
+ m_Coders[i].Create();
165
+ }
166
+
167
+ public void Init()
168
+ {
169
+ uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
170
+ for (uint i = 0; i < numStates; i++)
171
+ m_Coders[i].Init();
172
+ }
173
+
174
+ public Encoder2 GetSubCoder(UInt32 pos, Byte prevByte)
175
+ {
176
+ return m_Coders[
177
+ ((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits))
178
+ ];
179
+ }
180
+ }
181
+
182
+ class LenEncoder
183
+ {
184
+ RangeCoder.BitEncoder _choice = new RangeCoder.BitEncoder();
185
+ RangeCoder.BitEncoder _choice2 = new RangeCoder.BitEncoder();
186
+ RangeCoder.BitTreeEncoder[] _lowCoder = new RangeCoder.BitTreeEncoder[
187
+ Base.kNumPosStatesEncodingMax
188
+ ];
189
+ RangeCoder.BitTreeEncoder[] _midCoder = new RangeCoder.BitTreeEncoder[
190
+ Base.kNumPosStatesEncodingMax
191
+ ];
192
+ RangeCoder.BitTreeEncoder _highCoder = new RangeCoder.BitTreeEncoder(
193
+ Base.kNumHighLenBits
194
+ );
195
+
196
+ public LenEncoder()
197
+ {
198
+ for (UInt32 posState = 0; posState < Base.kNumPosStatesEncodingMax; posState++)
199
+ {
200
+ _lowCoder[posState] = new RangeCoder.BitTreeEncoder(Base.kNumLowLenBits);
201
+ _midCoder[posState] = new RangeCoder.BitTreeEncoder(Base.kNumMidLenBits);
202
+ }
203
+ }
204
+
205
+ public void Init(UInt32 numPosStates)
206
+ {
207
+ _choice.Init();
208
+ _choice2.Init();
209
+ for (UInt32 posState = 0; posState < numPosStates; posState++)
210
+ {
211
+ _lowCoder[posState].Init();
212
+ _midCoder[posState].Init();
213
+ }
214
+ _highCoder.Init();
215
+ }
216
+
217
+ public void Encode(RangeCoder.Encoder rangeEncoder, UInt32 symbol, UInt32 posState)
218
+ {
219
+ if (symbol < Base.kNumLowLenSymbols)
220
+ {
221
+ _choice.Encode(rangeEncoder, 0);
222
+ _lowCoder[posState].Encode(rangeEncoder, symbol);
223
+ }
224
+ else
225
+ {
226
+ symbol -= Base.kNumLowLenSymbols;
227
+ _choice.Encode(rangeEncoder, 1);
228
+ if (symbol < Base.kNumMidLenSymbols)
229
+ {
230
+ _choice2.Encode(rangeEncoder, 0);
231
+ _midCoder[posState].Encode(rangeEncoder, symbol);
232
+ }
233
+ else
234
+ {
235
+ _choice2.Encode(rangeEncoder, 1);
236
+ _highCoder.Encode(rangeEncoder, symbol - Base.kNumMidLenSymbols);
237
+ }
238
+ }
239
+ }
240
+
241
+ public void SetPrices(UInt32 posState, UInt32 numSymbols, UInt32[] prices, UInt32 st)
242
+ {
243
+ UInt32 a0 = _choice.GetPrice0();
244
+ UInt32 a1 = _choice.GetPrice1();
245
+ UInt32 b0 = a1 + _choice2.GetPrice0();
246
+ UInt32 b1 = a1 + _choice2.GetPrice1();
247
+ UInt32 i = 0;
248
+ for (i = 0; i < Base.kNumLowLenSymbols; i++)
249
+ {
250
+ if (i >= numSymbols)
251
+ return;
252
+ prices[st + i] = a0 + _lowCoder[posState].GetPrice(i);
253
+ }
254
+ for (; i < Base.kNumLowLenSymbols + Base.kNumMidLenSymbols; i++)
255
+ {
256
+ if (i >= numSymbols)
257
+ return;
258
+ prices[st + i] = b0 + _midCoder[posState].GetPrice(i - Base.kNumLowLenSymbols);
259
+ }
260
+ for (; i < numSymbols; i++)
261
+ prices[st + i] =
262
+ b1
263
+ + _highCoder.GetPrice(i - Base.kNumLowLenSymbols - Base.kNumMidLenSymbols);
264
+ }
265
+ };
266
+
267
+ const UInt32 kNumLenSpecSymbols = Base.kNumLowLenSymbols + Base.kNumMidLenSymbols;
268
+
269
+ class LenPriceTableEncoder : LenEncoder
270
+ {
271
+ UInt32[] _prices = new UInt32[Base.kNumLenSymbols << Base.kNumPosStatesBitsEncodingMax];
272
+ UInt32 _tableSize;
273
+ UInt32[] _counters = new UInt32[Base.kNumPosStatesEncodingMax];
274
+
275
+ public void SetTableSize(UInt32 tableSize)
276
+ {
277
+ _tableSize = tableSize;
278
+ }
279
+
280
+ public UInt32 GetPrice(UInt32 symbol, UInt32 posState)
281
+ {
282
+ return _prices[posState * Base.kNumLenSymbols + symbol];
283
+ }
284
+
285
+ void UpdateTable(UInt32 posState)
286
+ {
287
+ SetPrices(posState, _tableSize, _prices, posState * Base.kNumLenSymbols);
288
+ _counters[posState] = _tableSize;
289
+ }
290
+
291
+ public void UpdateTables(UInt32 numPosStates)
292
+ {
293
+ for (UInt32 posState = 0; posState < numPosStates; posState++)
294
+ UpdateTable(posState);
295
+ }
296
+
297
+ public new void Encode(RangeCoder.Encoder rangeEncoder, UInt32 symbol, UInt32 posState)
298
+ {
299
+ base.Encode(rangeEncoder, symbol, posState);
300
+ if (--_counters[posState] == 0)
301
+ UpdateTable(posState);
302
+ }
303
+ }
304
+
305
+ const UInt32 kNumOpts = 1 << 12;
306
+
307
+ class Optimal
308
+ {
309
+ public Base.State State;
310
+
311
+ public bool Prev1IsChar;
312
+ public bool Prev2;
313
+
314
+ public UInt32 PosPrev2;
315
+ public UInt32 BackPrev2;
316
+
317
+ public UInt32 Price;
318
+ public UInt32 PosPrev;
319
+ public UInt32 BackPrev;
320
+
321
+ public UInt32 Backs0;
322
+ public UInt32 Backs1;
323
+ public UInt32 Backs2;
324
+ public UInt32 Backs3;
325
+
326
+ public void MakeAsChar()
327
+ {
328
+ BackPrev = 0xFFFFFFFF;
329
+ Prev1IsChar = false;
330
+ }
331
+
332
+ public void MakeAsShortRep()
333
+ {
334
+ BackPrev = 0;
335
+ ;
336
+ Prev1IsChar = false;
337
+ }
338
+
339
+ public bool IsShortRep()
340
+ {
341
+ return (BackPrev == 0);
342
+ }
343
+ };
344
+
345
+ Optimal[] _optimum = new Optimal[kNumOpts];
346
+ LZ.IMatchFinder _matchFinder = null;
347
+ RangeCoder.Encoder _rangeEncoder = new RangeCoder.Encoder();
348
+
349
+ RangeCoder.BitEncoder[] _isMatch = new RangeCoder.BitEncoder[
350
+ Base.kNumStates << Base.kNumPosStatesBitsMax
351
+ ];
352
+ RangeCoder.BitEncoder[] _isRep = new RangeCoder.BitEncoder[Base.kNumStates];
353
+ RangeCoder.BitEncoder[] _isRepG0 = new RangeCoder.BitEncoder[Base.kNumStates];
354
+ RangeCoder.BitEncoder[] _isRepG1 = new RangeCoder.BitEncoder[Base.kNumStates];
355
+ RangeCoder.BitEncoder[] _isRepG2 = new RangeCoder.BitEncoder[Base.kNumStates];
356
+ RangeCoder.BitEncoder[] _isRep0Long = new RangeCoder.BitEncoder[
357
+ Base.kNumStates << Base.kNumPosStatesBitsMax
358
+ ];
359
+
360
+ RangeCoder.BitTreeEncoder[] _posSlotEncoder = new RangeCoder.BitTreeEncoder[
361
+ Base.kNumLenToPosStates
362
+ ];
363
+
364
+ RangeCoder.BitEncoder[] _posEncoders = new RangeCoder.BitEncoder[
365
+ Base.kNumFullDistances - Base.kEndPosModelIndex
366
+ ];
367
+ RangeCoder.BitTreeEncoder _posAlignEncoder = new RangeCoder.BitTreeEncoder(
368
+ Base.kNumAlignBits
369
+ );
370
+
371
+ LenPriceTableEncoder _lenEncoder = new LenPriceTableEncoder();
372
+ LenPriceTableEncoder _repMatchLenEncoder = new LenPriceTableEncoder();
373
+
374
+ LiteralEncoder _literalEncoder = new LiteralEncoder();
375
+
376
+ UInt32[] _matchDistances = new UInt32[Base.kMatchMaxLen * 2 + 2];
377
+
378
+ UInt32 _numFastBytes = kNumFastBytesDefault;
379
+ UInt32 _longestMatchLength;
380
+ UInt32 _numDistancePairs;
381
+
382
+ UInt32 _additionalOffset;
383
+
384
+ UInt32 _optimumEndIndex;
385
+ UInt32 _optimumCurrentIndex;
386
+
387
+ bool _longestMatchWasFound;
388
+
389
+ UInt32[] _posSlotPrices = new UInt32[
390
+ 1 << (Base.kNumPosSlotBits + Base.kNumLenToPosStatesBits)
391
+ ];
392
+ UInt32[] _distancesPrices = new UInt32[
393
+ Base.kNumFullDistances << Base.kNumLenToPosStatesBits
394
+ ];
395
+ UInt32[] _alignPrices = new UInt32[Base.kAlignTableSize];
396
+ UInt32 _alignPriceCount;
397
+
398
+ UInt32 _distTableSize = (kDefaultDictionaryLogSize * 2);
399
+
400
+ int _posStateBits = 2;
401
+ UInt32 _posStateMask = (4 - 1);
402
+ int _numLiteralPosStateBits = 0;
403
+ int _numLiteralContextBits = 3;
404
+
405
+ UInt32 _dictionarySize = (1 << kDefaultDictionaryLogSize);
406
+ UInt32 _dictionarySizePrev = 0xFFFFFFFF;
407
+ UInt32 _numFastBytesPrev = 0xFFFFFFFF;
408
+
409
+ Int64 nowPos64;
410
+ bool _finished;
411
+ System.IO.Stream _inStream;
412
+
413
+ EMatchFinderType _matchFinderType = EMatchFinderType.BT4;
414
+ bool _writeEndMark = false;
415
+
416
+ bool _needReleaseMFStream;
417
+
418
+ void Create()
419
+ {
420
+ if (_matchFinder == null)
421
+ {
422
+ LZ.BinTree bt = new LZ.BinTree();
423
+ int numHashBytes = 4;
424
+ if (_matchFinderType == EMatchFinderType.BT2)
425
+ numHashBytes = 2;
426
+ bt.SetType(numHashBytes);
427
+ _matchFinder = bt;
428
+ }
429
+ _literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits);
430
+
431
+ if (_dictionarySize == _dictionarySizePrev && _numFastBytesPrev == _numFastBytes)
432
+ return;
433
+ _matchFinder.Create(_dictionarySize, kNumOpts, _numFastBytes, Base.kMatchMaxLen + 1);
434
+ _dictionarySizePrev = _dictionarySize;
435
+ _numFastBytesPrev = _numFastBytes;
436
+ }
437
+
438
+ public Encoder()
439
+ {
440
+ for (int i = 0; i < kNumOpts; i++)
441
+ _optimum[i] = new Optimal();
442
+ for (int i = 0; i < Base.kNumLenToPosStates; i++)
443
+ _posSlotEncoder[i] = new RangeCoder.BitTreeEncoder(Base.kNumPosSlotBits);
444
+ }
445
+
446
+ void SetWriteEndMarkerMode(bool writeEndMarker)
447
+ {
448
+ _writeEndMark = writeEndMarker;
449
+ }
450
+
451
+ void Init()
452
+ {
453
+ BaseInit();
454
+ _rangeEncoder.Init();
455
+
456
+ uint i;
457
+ for (i = 0; i < Base.kNumStates; i++)
458
+ {
459
+ for (uint j = 0; j <= _posStateMask; j++)
460
+ {
461
+ uint complexState = (i << Base.kNumPosStatesBitsMax) + j;
462
+ _isMatch[complexState].Init();
463
+ _isRep0Long[complexState].Init();
464
+ }
465
+ _isRep[i].Init();
466
+ _isRepG0[i].Init();
467
+ _isRepG1[i].Init();
468
+ _isRepG2[i].Init();
469
+ }
470
+ _literalEncoder.Init();
471
+ for (i = 0; i < Base.kNumLenToPosStates; i++)
472
+ _posSlotEncoder[i].Init();
473
+ for (i = 0; i < Base.kNumFullDistances - Base.kEndPosModelIndex; i++)
474
+ _posEncoders[i].Init();
475
+
476
+ _lenEncoder.Init((UInt32)1 << _posStateBits);
477
+ _repMatchLenEncoder.Init((UInt32)1 << _posStateBits);
478
+
479
+ _posAlignEncoder.Init();
480
+
481
+ _longestMatchWasFound = false;
482
+ _optimumEndIndex = 0;
483
+ _optimumCurrentIndex = 0;
484
+ _additionalOffset = 0;
485
+ }
486
+
487
+ void ReadMatchDistances(out UInt32 lenRes, out UInt32 numDistancePairs)
488
+ {
489
+ lenRes = 0;
490
+ numDistancePairs = _matchFinder.GetMatches(_matchDistances);
491
+ if (numDistancePairs > 0)
492
+ {
493
+ lenRes = _matchDistances[numDistancePairs - 2];
494
+ if (lenRes == _numFastBytes)
495
+ lenRes += _matchFinder.GetMatchLen(
496
+ (int)lenRes - 1,
497
+ _matchDistances[numDistancePairs - 1],
498
+ Base.kMatchMaxLen - lenRes
499
+ );
500
+ }
501
+ _additionalOffset++;
502
+ }
503
+
504
+ void MovePos(UInt32 num)
505
+ {
506
+ if (num > 0)
507
+ {
508
+ _matchFinder.Skip(num);
509
+ _additionalOffset += num;
510
+ }
511
+ }
512
+
513
+ UInt32 GetRepLen1Price(Base.State state, UInt32 posState)
514
+ {
515
+ return _isRepG0[state.Index].GetPrice0()
516
+ + _isRep0Long[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice0();
517
+ }
518
+
519
+ UInt32 GetPureRepPrice(UInt32 repIndex, Base.State state, UInt32 posState)
520
+ {
521
+ UInt32 price;
522
+ if (repIndex == 0)
523
+ {
524
+ price = _isRepG0[state.Index].GetPrice0();
525
+ price += _isRep0Long[(state.Index << Base.kNumPosStatesBitsMax) + posState]
526
+ .GetPrice1();
527
+ }
528
+ else
529
+ {
530
+ price = _isRepG0[state.Index].GetPrice1();
531
+ if (repIndex == 1)
532
+ price += _isRepG1[state.Index].GetPrice0();
533
+ else
534
+ {
535
+ price += _isRepG1[state.Index].GetPrice1();
536
+ price += _isRepG2[state.Index].GetPrice(repIndex - 2);
537
+ }
538
+ }
539
+ return price;
540
+ }
541
+
542
+ UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, Base.State state, UInt32 posState)
543
+ {
544
+ UInt32 price = _repMatchLenEncoder.GetPrice(len - Base.kMatchMinLen, posState);
545
+ return price + GetPureRepPrice(repIndex, state, posState);
546
+ }
547
+
548
+ UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState)
549
+ {
550
+ UInt32 price;
551
+ UInt32 lenToPosState = Base.GetLenToPosState(len);
552
+ if (pos < Base.kNumFullDistances)
553
+ price = _distancesPrices[(lenToPosState * Base.kNumFullDistances) + pos];
554
+ else
555
+ price =
556
+ _posSlotPrices[(lenToPosState << Base.kNumPosSlotBits) + GetPosSlot2(pos)]
557
+ + _alignPrices[pos & Base.kAlignMask];
558
+ return price + _lenEncoder.GetPrice(len - Base.kMatchMinLen, posState);
559
+ }
560
+
561
+ UInt32 Backward(out UInt32 backRes, UInt32 cur)
562
+ {
563
+ _optimumEndIndex = cur;
564
+ UInt32 posMem = _optimum[cur].PosPrev;
565
+ UInt32 backMem = _optimum[cur].BackPrev;
566
+ do
567
+ {
568
+ if (_optimum[cur].Prev1IsChar)
569
+ {
570
+ _optimum[posMem].MakeAsChar();
571
+ _optimum[posMem].PosPrev = posMem - 1;
572
+ if (_optimum[cur].Prev2)
573
+ {
574
+ _optimum[posMem - 1].Prev1IsChar = false;
575
+ _optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2;
576
+ _optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2;
577
+ }
578
+ }
579
+ UInt32 posPrev = posMem;
580
+ UInt32 backCur = backMem;
581
+
582
+ backMem = _optimum[posPrev].BackPrev;
583
+ posMem = _optimum[posPrev].PosPrev;
584
+
585
+ _optimum[posPrev].BackPrev = backCur;
586
+ _optimum[posPrev].PosPrev = cur;
587
+ cur = posPrev;
588
+ } while (cur > 0);
589
+ backRes = _optimum[0].BackPrev;
590
+ _optimumCurrentIndex = _optimum[0].PosPrev;
591
+ return _optimumCurrentIndex;
592
+ }
593
+
594
+ UInt32[] reps = new UInt32[Base.kNumRepDistances];
595
+ UInt32[] repLens = new UInt32[Base.kNumRepDistances];
596
+
597
+ UInt32 GetOptimum(UInt32 position, out UInt32 backRes)
598
+ {
599
+ if (_optimumEndIndex != _optimumCurrentIndex)
600
+ {
601
+ UInt32 lenRes = _optimum[_optimumCurrentIndex].PosPrev - _optimumCurrentIndex;
602
+ backRes = _optimum[_optimumCurrentIndex].BackPrev;
603
+ _optimumCurrentIndex = _optimum[_optimumCurrentIndex].PosPrev;
604
+ return lenRes;
605
+ }
606
+ _optimumCurrentIndex = _optimumEndIndex = 0;
607
+
608
+ UInt32 lenMain,
609
+ numDistancePairs;
610
+ if (!_longestMatchWasFound)
611
+ {
612
+ ReadMatchDistances(out lenMain, out numDistancePairs);
613
+ }
614
+ else
615
+ {
616
+ lenMain = _longestMatchLength;
617
+ numDistancePairs = _numDistancePairs;
618
+ _longestMatchWasFound = false;
619
+ }
620
+
621
+ UInt32 numAvailableBytes = _matchFinder.GetNumAvailableBytes() + 1;
622
+ if (numAvailableBytes < 2)
623
+ {
624
+ backRes = 0xFFFFFFFF;
625
+ return 1;
626
+ }
627
+ if (numAvailableBytes > Base.kMatchMaxLen)
628
+ numAvailableBytes = Base.kMatchMaxLen;
629
+
630
+ UInt32 repMaxIndex = 0;
631
+ UInt32 i;
632
+ for (i = 0; i < Base.kNumRepDistances; i++)
633
+ {
634
+ reps[i] = _repDistances[i];
635
+ repLens[i] = _matchFinder.GetMatchLen(0 - 1, reps[i], Base.kMatchMaxLen);
636
+ if (repLens[i] > repLens[repMaxIndex])
637
+ repMaxIndex = i;
638
+ }
639
+ if (repLens[repMaxIndex] >= _numFastBytes)
640
+ {
641
+ backRes = repMaxIndex;
642
+ UInt32 lenRes = repLens[repMaxIndex];
643
+ MovePos(lenRes - 1);
644
+ return lenRes;
645
+ }
646
+
647
+ if (lenMain >= _numFastBytes)
648
+ {
649
+ backRes = _matchDistances[numDistancePairs - 1] + Base.kNumRepDistances;
650
+ MovePos(lenMain - 1);
651
+ return lenMain;
652
+ }
653
+
654
+ Byte currentByte = _matchFinder.GetIndexByte(0 - 1);
655
+ Byte matchByte = _matchFinder.GetIndexByte((Int32)(0 - _repDistances[0] - 1 - 1));
656
+
657
+ if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2)
658
+ {
659
+ backRes = (UInt32)0xFFFFFFFF;
660
+ return 1;
661
+ }
662
+
663
+ _optimum[0].State = _state;
664
+
665
+ UInt32 posState = (position & _posStateMask);
666
+
667
+ _optimum[1].Price =
668
+ _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice0()
669
+ + _literalEncoder
670
+ .GetSubCoder(position, _previousByte)
671
+ .GetPrice(!_state.IsCharState(), matchByte, currentByte);
672
+ _optimum[1].MakeAsChar();
673
+
674
+ UInt32 matchPrice = _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState]
675
+ .GetPrice1();
676
+ UInt32 repMatchPrice = matchPrice + _isRep[_state.Index].GetPrice1();
677
+
678
+ if (matchByte == currentByte)
679
+ {
680
+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState);
681
+ if (shortRepPrice < _optimum[1].Price)
682
+ {
683
+ _optimum[1].Price = shortRepPrice;
684
+ _optimum[1].MakeAsShortRep();
685
+ }
686
+ }
687
+
688
+ UInt32 lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]);
689
+
690
+ if (lenEnd < 2)
691
+ {
692
+ backRes = _optimum[1].BackPrev;
693
+ return 1;
694
+ }
695
+
696
+ _optimum[1].PosPrev = 0;
697
+
698
+ _optimum[0].Backs0 = reps[0];
699
+ _optimum[0].Backs1 = reps[1];
700
+ _optimum[0].Backs2 = reps[2];
701
+ _optimum[0].Backs3 = reps[3];
702
+
703
+ UInt32 len = lenEnd;
704
+ do _optimum[len--].Price = kIfinityPrice;
705
+ while (len >= 2);
706
+
707
+ for (i = 0; i < Base.kNumRepDistances; i++)
708
+ {
709
+ UInt32 repLen = repLens[i];
710
+ if (repLen < 2)
711
+ continue;
712
+ UInt32 price = repMatchPrice + GetPureRepPrice(i, _state, posState);
713
+ do
714
+ {
715
+ UInt32 curAndLenPrice =
716
+ price + _repMatchLenEncoder.GetPrice(repLen - 2, posState);
717
+ Optimal optimum = _optimum[repLen];
718
+ if (curAndLenPrice < optimum.Price)
719
+ {
720
+ optimum.Price = curAndLenPrice;
721
+ optimum.PosPrev = 0;
722
+ optimum.BackPrev = i;
723
+ optimum.Prev1IsChar = false;
724
+ }
725
+ } while (--repLen >= 2);
726
+ }
727
+
728
+ UInt32 normalMatchPrice = matchPrice + _isRep[_state.Index].GetPrice0();
729
+
730
+ len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
731
+ if (len <= lenMain)
732
+ {
733
+ UInt32 offs = 0;
734
+ while (len > _matchDistances[offs])
735
+ offs += 2;
736
+ for (; ; len++)
737
+ {
738
+ UInt32 distance = _matchDistances[offs + 1];
739
+ UInt32 curAndLenPrice =
740
+ normalMatchPrice + GetPosLenPrice(distance, len, posState);
741
+ Optimal optimum = _optimum[len];
742
+ if (curAndLenPrice < optimum.Price)
743
+ {
744
+ optimum.Price = curAndLenPrice;
745
+ optimum.PosPrev = 0;
746
+ optimum.BackPrev = distance + Base.kNumRepDistances;
747
+ optimum.Prev1IsChar = false;
748
+ }
749
+ if (len == _matchDistances[offs])
750
+ {
751
+ offs += 2;
752
+ if (offs == numDistancePairs)
753
+ break;
754
+ }
755
+ }
756
+ }
757
+
758
+ UInt32 cur = 0;
759
+
760
+ while (true)
761
+ {
762
+ cur++;
763
+ if (cur == lenEnd)
764
+ return Backward(out backRes, cur);
765
+ UInt32 newLen;
766
+ ReadMatchDistances(out newLen, out numDistancePairs);
767
+ if (newLen >= _numFastBytes)
768
+ {
769
+ _numDistancePairs = numDistancePairs;
770
+ _longestMatchLength = newLen;
771
+ _longestMatchWasFound = true;
772
+ return Backward(out backRes, cur);
773
+ }
774
+ position++;
775
+ UInt32 posPrev = _optimum[cur].PosPrev;
776
+ Base.State state;
777
+ if (_optimum[cur].Prev1IsChar)
778
+ {
779
+ posPrev--;
780
+ if (_optimum[cur].Prev2)
781
+ {
782
+ state = _optimum[_optimum[cur].PosPrev2].State;
783
+ if (_optimum[cur].BackPrev2 < Base.kNumRepDistances)
784
+ state.UpdateRep();
785
+ else
786
+ state.UpdateMatch();
787
+ }
788
+ else
789
+ state = _optimum[posPrev].State;
790
+ state.UpdateChar();
791
+ }
792
+ else
793
+ state = _optimum[posPrev].State;
794
+ if (posPrev == cur - 1)
795
+ {
796
+ if (_optimum[cur].IsShortRep())
797
+ state.UpdateShortRep();
798
+ else
799
+ state.UpdateChar();
800
+ }
801
+ else
802
+ {
803
+ UInt32 pos;
804
+ if (_optimum[cur].Prev1IsChar && _optimum[cur].Prev2)
805
+ {
806
+ posPrev = _optimum[cur].PosPrev2;
807
+ pos = _optimum[cur].BackPrev2;
808
+ state.UpdateRep();
809
+ }
810
+ else
811
+ {
812
+ pos = _optimum[cur].BackPrev;
813
+ if (pos < Base.kNumRepDistances)
814
+ state.UpdateRep();
815
+ else
816
+ state.UpdateMatch();
817
+ }
818
+ Optimal opt = _optimum[posPrev];
819
+ if (pos < Base.kNumRepDistances)
820
+ {
821
+ if (pos == 0)
822
+ {
823
+ reps[0] = opt.Backs0;
824
+ reps[1] = opt.Backs1;
825
+ reps[2] = opt.Backs2;
826
+ reps[3] = opt.Backs3;
827
+ }
828
+ else if (pos == 1)
829
+ {
830
+ reps[0] = opt.Backs1;
831
+ reps[1] = opt.Backs0;
832
+ reps[2] = opt.Backs2;
833
+ reps[3] = opt.Backs3;
834
+ }
835
+ else if (pos == 2)
836
+ {
837
+ reps[0] = opt.Backs2;
838
+ reps[1] = opt.Backs0;
839
+ reps[2] = opt.Backs1;
840
+ reps[3] = opt.Backs3;
841
+ }
842
+ else
843
+ {
844
+ reps[0] = opt.Backs3;
845
+ reps[1] = opt.Backs0;
846
+ reps[2] = opt.Backs1;
847
+ reps[3] = opt.Backs2;
848
+ }
849
+ }
850
+ else
851
+ {
852
+ reps[0] = (pos - Base.kNumRepDistances);
853
+ reps[1] = opt.Backs0;
854
+ reps[2] = opt.Backs1;
855
+ reps[3] = opt.Backs2;
856
+ }
857
+ }
858
+ _optimum[cur].State = state;
859
+ _optimum[cur].Backs0 = reps[0];
860
+ _optimum[cur].Backs1 = reps[1];
861
+ _optimum[cur].Backs2 = reps[2];
862
+ _optimum[cur].Backs3 = reps[3];
863
+ UInt32 curPrice = _optimum[cur].Price;
864
+
865
+ currentByte = _matchFinder.GetIndexByte(0 - 1);
866
+ matchByte = _matchFinder.GetIndexByte((Int32)(0 - reps[0] - 1 - 1));
867
+
868
+ posState = (position & _posStateMask);
869
+
870
+ UInt32 curAnd1Price =
871
+ curPrice
872
+ + _isMatch[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice0()
873
+ + _literalEncoder
874
+ .GetSubCoder(position, _matchFinder.GetIndexByte(0 - 2))
875
+ .GetPrice(!state.IsCharState(), matchByte, currentByte);
876
+
877
+ Optimal nextOptimum = _optimum[cur + 1];
878
+
879
+ bool nextIsChar = false;
880
+ if (curAnd1Price < nextOptimum.Price)
881
+ {
882
+ nextOptimum.Price = curAnd1Price;
883
+ nextOptimum.PosPrev = cur;
884
+ nextOptimum.MakeAsChar();
885
+ nextIsChar = true;
886
+ }
887
+
888
+ matchPrice =
889
+ curPrice
890
+ + _isMatch[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice1();
891
+ repMatchPrice = matchPrice + _isRep[state.Index].GetPrice1();
892
+
893
+ if (
894
+ matchByte == currentByte
895
+ && !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0)
896
+ )
897
+ {
898
+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState);
899
+ if (shortRepPrice <= nextOptimum.Price)
900
+ {
901
+ nextOptimum.Price = shortRepPrice;
902
+ nextOptimum.PosPrev = cur;
903
+ nextOptimum.MakeAsShortRep();
904
+ nextIsChar = true;
905
+ }
906
+ }
907
+
908
+ UInt32 numAvailableBytesFull = _matchFinder.GetNumAvailableBytes() + 1;
909
+ numAvailableBytesFull = Math.Min(kNumOpts - 1 - cur, numAvailableBytesFull);
910
+ numAvailableBytes = numAvailableBytesFull;
911
+
912
+ if (numAvailableBytes < 2)
913
+ continue;
914
+ if (numAvailableBytes > _numFastBytes)
915
+ numAvailableBytes = _numFastBytes;
916
+ if (!nextIsChar && matchByte != currentByte)
917
+ {
918
+ // try Literal + rep0
919
+ UInt32 t = Math.Min(numAvailableBytesFull - 1, _numFastBytes);
920
+ UInt32 lenTest2 = _matchFinder.GetMatchLen(0, reps[0], t);
921
+ if (lenTest2 >= 2)
922
+ {
923
+ Base.State state2 = state;
924
+ state2.UpdateChar();
925
+ UInt32 posStateNext = (position + 1) & _posStateMask;
926
+ UInt32 nextRepMatchPrice =
927
+ curAnd1Price
928
+ + _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext]
929
+ .GetPrice1()
930
+ + _isRep[state2.Index].GetPrice1();
931
+ {
932
+ UInt32 offset = cur + 1 + lenTest2;
933
+ while (lenEnd < offset)
934
+ _optimum[++lenEnd].Price = kIfinityPrice;
935
+ UInt32 curAndLenPrice =
936
+ nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);
937
+ Optimal optimum = _optimum[offset];
938
+ if (curAndLenPrice < optimum.Price)
939
+ {
940
+ optimum.Price = curAndLenPrice;
941
+ optimum.PosPrev = cur + 1;
942
+ optimum.BackPrev = 0;
943
+ optimum.Prev1IsChar = true;
944
+ optimum.Prev2 = false;
945
+ }
946
+ }
947
+ }
948
+ }
949
+
950
+ UInt32 startLen = 2; // speed optimization
951
+
952
+ for (UInt32 repIndex = 0; repIndex < Base.kNumRepDistances; repIndex++)
953
+ {
954
+ UInt32 lenTest = _matchFinder.GetMatchLen(
955
+ 0 - 1,
956
+ reps[repIndex],
957
+ numAvailableBytes
958
+ );
959
+ if (lenTest < 2)
960
+ continue;
961
+ UInt32 lenTestTemp = lenTest;
962
+ do
963
+ {
964
+ while (lenEnd < cur + lenTest)
965
+ _optimum[++lenEnd].Price = kIfinityPrice;
966
+ UInt32 curAndLenPrice =
967
+ repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState);
968
+ Optimal optimum = _optimum[cur + lenTest];
969
+ if (curAndLenPrice < optimum.Price)
970
+ {
971
+ optimum.Price = curAndLenPrice;
972
+ optimum.PosPrev = cur;
973
+ optimum.BackPrev = repIndex;
974
+ optimum.Prev1IsChar = false;
975
+ }
976
+ } while (--lenTest >= 2);
977
+ lenTest = lenTestTemp;
978
+
979
+ if (repIndex == 0)
980
+ startLen = lenTest + 1;
981
+
982
+ // if (_maxMode)
983
+ if (lenTest < numAvailableBytesFull)
984
+ {
985
+ UInt32 t = Math.Min(numAvailableBytesFull - 1 - lenTest, _numFastBytes);
986
+ UInt32 lenTest2 = _matchFinder.GetMatchLen(
987
+ (Int32)lenTest,
988
+ reps[repIndex],
989
+ t
990
+ );
991
+ if (lenTest2 >= 2)
992
+ {
993
+ Base.State state2 = state;
994
+ state2.UpdateRep();
995
+ UInt32 posStateNext = (position + lenTest) & _posStateMask;
996
+ UInt32 curAndLenCharPrice =
997
+ repMatchPrice
998
+ + GetRepPrice(repIndex, lenTest, state, posState)
999
+ + _isMatch[
1000
+ (state2.Index << Base.kNumPosStatesBitsMax) + posStateNext
1001
+ ]
1002
+ .GetPrice0()
1003
+ + _literalEncoder
1004
+ .GetSubCoder(
1005
+ position + lenTest,
1006
+ _matchFinder.GetIndexByte((Int32)lenTest - 1 - 1)
1007
+ )
1008
+ .GetPrice(
1009
+ true,
1010
+ _matchFinder.GetIndexByte(
1011
+ (Int32)(
1012
+ (Int32)lenTest - 1 - (Int32)(reps[repIndex] + 1)
1013
+ )
1014
+ ),
1015
+ _matchFinder.GetIndexByte((Int32)lenTest - 1)
1016
+ );
1017
+ state2.UpdateChar();
1018
+ posStateNext = (position + lenTest + 1) & _posStateMask;
1019
+ UInt32 nextMatchPrice =
1020
+ curAndLenCharPrice
1021
+ + _isMatch[
1022
+ (state2.Index << Base.kNumPosStatesBitsMax) + posStateNext
1023
+ ]
1024
+ .GetPrice1();
1025
+ UInt32 nextRepMatchPrice =
1026
+ nextMatchPrice + _isRep[state2.Index].GetPrice1();
1027
+
1028
+ // for(; lenTest2 >= 2; lenTest2--)
1029
+ {
1030
+ UInt32 offset = lenTest + 1 + lenTest2;
1031
+ while (lenEnd < cur + offset)
1032
+ _optimum[++lenEnd].Price = kIfinityPrice;
1033
+ UInt32 curAndLenPrice =
1034
+ nextRepMatchPrice
1035
+ + GetRepPrice(0, lenTest2, state2, posStateNext);
1036
+ Optimal optimum = _optimum[cur + offset];
1037
+ if (curAndLenPrice < optimum.Price)
1038
+ {
1039
+ optimum.Price = curAndLenPrice;
1040
+ optimum.PosPrev = cur + lenTest + 1;
1041
+ optimum.BackPrev = 0;
1042
+ optimum.Prev1IsChar = true;
1043
+ optimum.Prev2 = true;
1044
+ optimum.PosPrev2 = cur;
1045
+ optimum.BackPrev2 = repIndex;
1046
+ }
1047
+ }
1048
+ }
1049
+ }
1050
+ }
1051
+
1052
+ if (newLen > numAvailableBytes)
1053
+ {
1054
+ newLen = numAvailableBytes;
1055
+ for (
1056
+ numDistancePairs = 0;
1057
+ newLen > _matchDistances[numDistancePairs];
1058
+ numDistancePairs += 2
1059
+ )
1060
+ ;
1061
+ _matchDistances[numDistancePairs] = newLen;
1062
+ numDistancePairs += 2;
1063
+ }
1064
+ if (newLen >= startLen)
1065
+ {
1066
+ normalMatchPrice = matchPrice + _isRep[state.Index].GetPrice0();
1067
+ while (lenEnd < cur + newLen)
1068
+ _optimum[++lenEnd].Price = kIfinityPrice;
1069
+
1070
+ UInt32 offs = 0;
1071
+ while (startLen > _matchDistances[offs])
1072
+ offs += 2;
1073
+
1074
+ for (UInt32 lenTest = startLen; ; lenTest++)
1075
+ {
1076
+ UInt32 curBack = _matchDistances[offs + 1];
1077
+ UInt32 curAndLenPrice =
1078
+ normalMatchPrice + GetPosLenPrice(curBack, lenTest, posState);
1079
+ Optimal optimum = _optimum[cur + lenTest];
1080
+ if (curAndLenPrice < optimum.Price)
1081
+ {
1082
+ optimum.Price = curAndLenPrice;
1083
+ optimum.PosPrev = cur;
1084
+ optimum.BackPrev = curBack + Base.kNumRepDistances;
1085
+ optimum.Prev1IsChar = false;
1086
+ }
1087
+
1088
+ if (lenTest == _matchDistances[offs])
1089
+ {
1090
+ if (lenTest < numAvailableBytesFull)
1091
+ {
1092
+ UInt32 t = Math.Min(
1093
+ numAvailableBytesFull - 1 - lenTest,
1094
+ _numFastBytes
1095
+ );
1096
+ UInt32 lenTest2 = _matchFinder.GetMatchLen(
1097
+ (Int32)lenTest,
1098
+ curBack,
1099
+ t
1100
+ );
1101
+ if (lenTest2 >= 2)
1102
+ {
1103
+ Base.State state2 = state;
1104
+ state2.UpdateMatch();
1105
+ UInt32 posStateNext = (position + lenTest) & _posStateMask;
1106
+ UInt32 curAndLenCharPrice =
1107
+ curAndLenPrice
1108
+ + _isMatch[
1109
+ (state2.Index << Base.kNumPosStatesBitsMax)
1110
+ + posStateNext
1111
+ ]
1112
+ .GetPrice0()
1113
+ + _literalEncoder
1114
+ .GetSubCoder(
1115
+ position + lenTest,
1116
+ _matchFinder.GetIndexByte((Int32)lenTest - 1 - 1)
1117
+ )
1118
+ .GetPrice(
1119
+ true,
1120
+ _matchFinder.GetIndexByte(
1121
+ (Int32)lenTest - (Int32)(curBack + 1) - 1
1122
+ ),
1123
+ _matchFinder.GetIndexByte((Int32)lenTest - 1)
1124
+ );
1125
+ state2.UpdateChar();
1126
+ posStateNext = (position + lenTest + 1) & _posStateMask;
1127
+ UInt32 nextMatchPrice =
1128
+ curAndLenCharPrice
1129
+ + _isMatch[
1130
+ (state2.Index << Base.kNumPosStatesBitsMax)
1131
+ + posStateNext
1132
+ ]
1133
+ .GetPrice1();
1134
+ UInt32 nextRepMatchPrice =
1135
+ nextMatchPrice + _isRep[state2.Index].GetPrice1();
1136
+
1137
+ UInt32 offset = lenTest + 1 + lenTest2;
1138
+ while (lenEnd < cur + offset)
1139
+ _optimum[++lenEnd].Price = kIfinityPrice;
1140
+ curAndLenPrice =
1141
+ nextRepMatchPrice
1142
+ + GetRepPrice(0, lenTest2, state2, posStateNext);
1143
+ optimum = _optimum[cur + offset];
1144
+ if (curAndLenPrice < optimum.Price)
1145
+ {
1146
+ optimum.Price = curAndLenPrice;
1147
+ optimum.PosPrev = cur + lenTest + 1;
1148
+ optimum.BackPrev = 0;
1149
+ optimum.Prev1IsChar = true;
1150
+ optimum.Prev2 = true;
1151
+ optimum.PosPrev2 = cur;
1152
+ optimum.BackPrev2 = curBack + Base.kNumRepDistances;
1153
+ }
1154
+ }
1155
+ }
1156
+ offs += 2;
1157
+ if (offs == numDistancePairs)
1158
+ break;
1159
+ }
1160
+ }
1161
+ }
1162
+ }
1163
+ }
1164
+
1165
+ bool ChangePair(UInt32 smallDist, UInt32 bigDist)
1166
+ {
1167
+ const int kDif = 7;
1168
+ return (smallDist < ((UInt32)(1) << (32 - kDif)) && bigDist >= (smallDist << kDif));
1169
+ }
1170
+
1171
+ void WriteEndMarker(UInt32 posState)
1172
+ {
1173
+ if (!_writeEndMark)
1174
+ return;
1175
+
1176
+ _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState]
1177
+ .Encode(_rangeEncoder, 1);
1178
+ _isRep[_state.Index].Encode(_rangeEncoder, 0);
1179
+ _state.UpdateMatch();
1180
+ UInt32 len = Base.kMatchMinLen;
1181
+ _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);
1182
+ UInt32 posSlot = (1 << Base.kNumPosSlotBits) - 1;
1183
+ UInt32 lenToPosState = Base.GetLenToPosState(len);
1184
+ _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot);
1185
+ int footerBits = 30;
1186
+ UInt32 posReduced = (((UInt32)1) << footerBits) - 1;
1187
+ _rangeEncoder.EncodeDirectBits(
1188
+ posReduced >> Base.kNumAlignBits,
1189
+ footerBits - Base.kNumAlignBits
1190
+ );
1191
+ _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask);
1192
+ }
1193
+
1194
+ void Flush(UInt32 nowPos)
1195
+ {
1196
+ ReleaseMFStream();
1197
+ WriteEndMarker(nowPos & _posStateMask);
1198
+ _rangeEncoder.FlushData();
1199
+ _rangeEncoder.FlushStream();
1200
+ }
1201
+
1202
+ public void CodeOneBlock(out Int64 inSize, out Int64 outSize, out bool finished)
1203
+ {
1204
+ inSize = 0;
1205
+ outSize = 0;
1206
+ finished = true;
1207
+
1208
+ if (_inStream != null)
1209
+ {
1210
+ _matchFinder.SetStream(_inStream);
1211
+ _matchFinder.Init();
1212
+ _needReleaseMFStream = true;
1213
+ _inStream = null;
1214
+ if (_trainSize > 0)
1215
+ _matchFinder.Skip(_trainSize);
1216
+ }
1217
+
1218
+ if (_finished)
1219
+ return;
1220
+ _finished = true;
1221
+
1222
+ Int64 progressPosValuePrev = nowPos64;
1223
+ if (nowPos64 == 0)
1224
+ {
1225
+ if (_matchFinder.GetNumAvailableBytes() == 0)
1226
+ {
1227
+ Flush((UInt32)nowPos64);
1228
+ return;
1229
+ }
1230
+ UInt32 len,
1231
+ numDistancePairs; // it's not used
1232
+ ReadMatchDistances(out len, out numDistancePairs);
1233
+ UInt32 posState = (UInt32)(nowPos64) & _posStateMask;
1234
+ _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState]
1235
+ .Encode(_rangeEncoder, 0);
1236
+ _state.UpdateChar();
1237
+ Byte curByte = _matchFinder.GetIndexByte((Int32)(0 - _additionalOffset));
1238
+ _literalEncoder
1239
+ .GetSubCoder((UInt32)(nowPos64), _previousByte)
1240
+ .Encode(_rangeEncoder, curByte);
1241
+ _previousByte = curByte;
1242
+ _additionalOffset--;
1243
+ nowPos64++;
1244
+ }
1245
+ if (_matchFinder.GetNumAvailableBytes() == 0)
1246
+ {
1247
+ Flush((UInt32)nowPos64);
1248
+ return;
1249
+ }
1250
+ while (true)
1251
+ {
1252
+ UInt32 pos;
1253
+ UInt32 len = GetOptimum((UInt32)nowPos64, out pos);
1254
+
1255
+ UInt32 posState = ((UInt32)nowPos64) & _posStateMask;
1256
+ UInt32 complexState = (_state.Index << Base.kNumPosStatesBitsMax) + posState;
1257
+ if (len == 1 && pos == 0xFFFFFFFF)
1258
+ {
1259
+ _isMatch[complexState].Encode(_rangeEncoder, 0);
1260
+ Byte curByte = _matchFinder.GetIndexByte((Int32)(0 - _additionalOffset));
1261
+ LiteralEncoder.Encoder2 subCoder = _literalEncoder.GetSubCoder(
1262
+ (UInt32)nowPos64,
1263
+ _previousByte
1264
+ );
1265
+ if (!_state.IsCharState())
1266
+ {
1267
+ Byte matchByte = _matchFinder.GetIndexByte(
1268
+ (Int32)(0 - _repDistances[0] - 1 - _additionalOffset)
1269
+ );
1270
+ subCoder.EncodeMatched(_rangeEncoder, matchByte, curByte);
1271
+ }
1272
+ else
1273
+ subCoder.Encode(_rangeEncoder, curByte);
1274
+ _previousByte = curByte;
1275
+ _state.UpdateChar();
1276
+ }
1277
+ else
1278
+ {
1279
+ _isMatch[complexState].Encode(_rangeEncoder, 1);
1280
+ if (pos < Base.kNumRepDistances)
1281
+ {
1282
+ _isRep[_state.Index].Encode(_rangeEncoder, 1);
1283
+ if (pos == 0)
1284
+ {
1285
+ _isRepG0[_state.Index].Encode(_rangeEncoder, 0);
1286
+ if (len == 1)
1287
+ _isRep0Long[complexState].Encode(_rangeEncoder, 0);
1288
+ else
1289
+ _isRep0Long[complexState].Encode(_rangeEncoder, 1);
1290
+ }
1291
+ else
1292
+ {
1293
+ _isRepG0[_state.Index].Encode(_rangeEncoder, 1);
1294
+ if (pos == 1)
1295
+ _isRepG1[_state.Index].Encode(_rangeEncoder, 0);
1296
+ else
1297
+ {
1298
+ _isRepG1[_state.Index].Encode(_rangeEncoder, 1);
1299
+ _isRepG2[_state.Index].Encode(_rangeEncoder, pos - 2);
1300
+ }
1301
+ }
1302
+ if (len == 1)
1303
+ _state.UpdateShortRep();
1304
+ else
1305
+ {
1306
+ _repMatchLenEncoder.Encode(
1307
+ _rangeEncoder,
1308
+ len - Base.kMatchMinLen,
1309
+ posState
1310
+ );
1311
+ _state.UpdateRep();
1312
+ }
1313
+ UInt32 distance = _repDistances[pos];
1314
+ if (pos != 0)
1315
+ {
1316
+ for (UInt32 i = pos; i >= 1; i--)
1317
+ _repDistances[i] = _repDistances[i - 1];
1318
+ _repDistances[0] = distance;
1319
+ }
1320
+ }
1321
+ else
1322
+ {
1323
+ _isRep[_state.Index].Encode(_rangeEncoder, 0);
1324
+ _state.UpdateMatch();
1325
+ _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);
1326
+ pos -= Base.kNumRepDistances;
1327
+ UInt32 posSlot = GetPosSlot(pos);
1328
+ UInt32 lenToPosState = Base.GetLenToPosState(len);
1329
+ _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot);
1330
+
1331
+ if (posSlot >= Base.kStartPosModelIndex)
1332
+ {
1333
+ int footerBits = (int)((posSlot >> 1) - 1);
1334
+ UInt32 baseVal = ((2 | (posSlot & 1)) << footerBits);
1335
+ UInt32 posReduced = pos - baseVal;
1336
+
1337
+ if (posSlot < Base.kEndPosModelIndex)
1338
+ RangeCoder.BitTreeEncoder.ReverseEncode(
1339
+ _posEncoders,
1340
+ baseVal - posSlot - 1,
1341
+ _rangeEncoder,
1342
+ footerBits,
1343
+ posReduced
1344
+ );
1345
+ else
1346
+ {
1347
+ _rangeEncoder.EncodeDirectBits(
1348
+ posReduced >> Base.kNumAlignBits,
1349
+ footerBits - Base.kNumAlignBits
1350
+ );
1351
+ _posAlignEncoder.ReverseEncode(
1352
+ _rangeEncoder,
1353
+ posReduced & Base.kAlignMask
1354
+ );
1355
+ _alignPriceCount++;
1356
+ }
1357
+ }
1358
+ UInt32 distance = pos;
1359
+ for (UInt32 i = Base.kNumRepDistances - 1; i >= 1; i--)
1360
+ _repDistances[i] = _repDistances[i - 1];
1361
+ _repDistances[0] = distance;
1362
+ _matchPriceCount++;
1363
+ }
1364
+ _previousByte = _matchFinder.GetIndexByte((Int32)(len - 1 - _additionalOffset));
1365
+ }
1366
+ _additionalOffset -= len;
1367
+ nowPos64 += len;
1368
+ if (_additionalOffset == 0)
1369
+ {
1370
+ // if (!_fastMode)
1371
+ if (_matchPriceCount >= (1 << 7))
1372
+ FillDistancesPrices();
1373
+ if (_alignPriceCount >= Base.kAlignTableSize)
1374
+ FillAlignPrices();
1375
+ inSize = nowPos64;
1376
+ outSize = _rangeEncoder.GetProcessedSizeAdd();
1377
+ if (_matchFinder.GetNumAvailableBytes() == 0)
1378
+ {
1379
+ Flush((UInt32)nowPos64);
1380
+ return;
1381
+ }
1382
+
1383
+ if (nowPos64 - progressPosValuePrev >= (1 << 12))
1384
+ {
1385
+ _finished = false;
1386
+ finished = false;
1387
+ return;
1388
+ }
1389
+ }
1390
+ }
1391
+ }
1392
+
1393
+ void ReleaseMFStream()
1394
+ {
1395
+ if (_matchFinder != null && _needReleaseMFStream)
1396
+ {
1397
+ _matchFinder.ReleaseStream();
1398
+ _needReleaseMFStream = false;
1399
+ }
1400
+ }
1401
+
1402
+ void SetOutStream(System.IO.Stream outStream)
1403
+ {
1404
+ _rangeEncoder.SetStream(outStream);
1405
+ }
1406
+
1407
+ void ReleaseOutStream()
1408
+ {
1409
+ _rangeEncoder.ReleaseStream();
1410
+ }
1411
+
1412
+ void ReleaseStreams()
1413
+ {
1414
+ ReleaseMFStream();
1415
+ ReleaseOutStream();
1416
+ }
1417
+
1418
+ void SetStreams(
1419
+ System.IO.Stream inStream,
1420
+ System.IO.Stream outStream,
1421
+ Int64 inSize,
1422
+ Int64 outSize
1423
+ )
1424
+ {
1425
+ _inStream = inStream;
1426
+ _finished = false;
1427
+ Create();
1428
+ SetOutStream(outStream);
1429
+ Init();
1430
+
1431
+ // if (!_fastMode)
1432
+ {
1433
+ FillDistancesPrices();
1434
+ FillAlignPrices();
1435
+ }
1436
+
1437
+ _lenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen);
1438
+ _lenEncoder.UpdateTables((UInt32)1 << _posStateBits);
1439
+ _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen);
1440
+ _repMatchLenEncoder.UpdateTables((UInt32)1 << _posStateBits);
1441
+
1442
+ nowPos64 = 0;
1443
+ }
1444
+
1445
+ public void Code(
1446
+ System.IO.Stream inStream,
1447
+ System.IO.Stream outStream,
1448
+ Int64 inSize,
1449
+ Int64 outSize,
1450
+ ICodeProgress progress
1451
+ )
1452
+ {
1453
+ _needReleaseMFStream = false;
1454
+ try
1455
+ {
1456
+ SetStreams(inStream, outStream, inSize, outSize);
1457
+ while (true)
1458
+ {
1459
+ Int64 processedInSize;
1460
+ Int64 processedOutSize;
1461
+ bool finished;
1462
+ CodeOneBlock(out processedInSize, out processedOutSize, out finished);
1463
+ if (finished)
1464
+ return;
1465
+ if (progress != null)
1466
+ {
1467
+ progress.SetProgress(processedInSize, processedOutSize);
1468
+ }
1469
+ }
1470
+ }
1471
+ finally
1472
+ {
1473
+ ReleaseStreams();
1474
+ }
1475
+ }
1476
+
1477
+ const int kPropSize = 5;
1478
+ Byte[] properties = new Byte[kPropSize];
1479
+
1480
+ public void WriteCoderProperties(System.IO.Stream outStream)
1481
+ {
1482
+ properties[0] = (Byte)(
1483
+ (_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits
1484
+ );
1485
+ for (int i = 0; i < 4; i++)
1486
+ properties[1 + i] = (Byte)((_dictionarySize >> (8 * i)) & 0xFF);
1487
+ outStream.Write(properties, 0, kPropSize);
1488
+ }
1489
+
1490
+ UInt32[] tempPrices = new UInt32[Base.kNumFullDistances];
1491
+ UInt32 _matchPriceCount;
1492
+
1493
+ void FillDistancesPrices()
1494
+ {
1495
+ for (UInt32 i = Base.kStartPosModelIndex; i < Base.kNumFullDistances; i++)
1496
+ {
1497
+ UInt32 posSlot = GetPosSlot(i);
1498
+ int footerBits = (int)((posSlot >> 1) - 1);
1499
+ UInt32 baseVal = ((2 | (posSlot & 1)) << footerBits);
1500
+ tempPrices[i] = BitTreeEncoder.ReverseGetPrice(
1501
+ _posEncoders,
1502
+ baseVal - posSlot - 1,
1503
+ footerBits,
1504
+ i - baseVal
1505
+ );
1506
+ }
1507
+
1508
+ for (UInt32 lenToPosState = 0; lenToPosState < Base.kNumLenToPosStates; lenToPosState++)
1509
+ {
1510
+ UInt32 posSlot;
1511
+ RangeCoder.BitTreeEncoder encoder = _posSlotEncoder[lenToPosState];
1512
+
1513
+ UInt32 st = (lenToPosState << Base.kNumPosSlotBits);
1514
+ for (posSlot = 0; posSlot < _distTableSize; posSlot++)
1515
+ _posSlotPrices[st + posSlot] = encoder.GetPrice(posSlot);
1516
+ for (posSlot = Base.kEndPosModelIndex; posSlot < _distTableSize; posSlot++)
1517
+ _posSlotPrices[st + posSlot] += (
1518
+ (((posSlot >> 1) - 1) - Base.kNumAlignBits)
1519
+ << RangeCoder.BitEncoder.kNumBitPriceShiftBits
1520
+ );
1521
+
1522
+ UInt32 st2 = lenToPosState * Base.kNumFullDistances;
1523
+ UInt32 i;
1524
+ for (i = 0; i < Base.kStartPosModelIndex; i++)
1525
+ _distancesPrices[st2 + i] = _posSlotPrices[st + i];
1526
+ for (; i < Base.kNumFullDistances; i++)
1527
+ _distancesPrices[st2 + i] = _posSlotPrices[st + GetPosSlot(i)] + tempPrices[i];
1528
+ }
1529
+ _matchPriceCount = 0;
1530
+ }
1531
+
1532
+ void FillAlignPrices()
1533
+ {
1534
+ for (UInt32 i = 0; i < Base.kAlignTableSize; i++)
1535
+ _alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i);
1536
+ _alignPriceCount = 0;
1537
+ }
1538
+
1539
+ static string[] kMatchFinderIDs = { "BT2", "BT4" };
1540
+
1541
+ static int FindMatchFinder(string s)
1542
+ {
1543
+ for (int m = 0; m < kMatchFinderIDs.Length; m++)
1544
+ if (s == kMatchFinderIDs[m])
1545
+ return m;
1546
+ return -1;
1547
+ }
1548
+
1549
+ public void SetCoderProperties(CoderPropID[] propIDs, object[] properties)
1550
+ {
1551
+ for (UInt32 i = 0; i < properties.Length; i++)
1552
+ {
1553
+ object prop = properties[i];
1554
+ switch (propIDs[i])
1555
+ {
1556
+ case CoderPropID.NumFastBytes:
1557
+ {
1558
+ if (!(prop is Int32))
1559
+ throw new InvalidParamException();
1560
+ Int32 numFastBytes = (Int32)prop;
1561
+ if (numFastBytes < 5 || numFastBytes > Base.kMatchMaxLen)
1562
+ throw new InvalidParamException();
1563
+ _numFastBytes = (UInt32)numFastBytes;
1564
+ break;
1565
+ }
1566
+ case CoderPropID.Algorithm:
1567
+ {
1568
+ /*
1569
+ if (!(prop is Int32))
1570
+ throw new InvalidParamException();
1571
+ Int32 maximize = (Int32)prop;
1572
+ _fastMode = (maximize == 0);
1573
+ _maxMode = (maximize >= 2);
1574
+ */
1575
+ break;
1576
+ }
1577
+ case CoderPropID.MatchFinder:
1578
+ {
1579
+ if (!(prop is String))
1580
+ throw new InvalidParamException();
1581
+ EMatchFinderType matchFinderIndexPrev = _matchFinderType;
1582
+ int m = FindMatchFinder(((string)prop).ToUpper());
1583
+ if (m < 0)
1584
+ throw new InvalidParamException();
1585
+ _matchFinderType = (EMatchFinderType)m;
1586
+ if (_matchFinder != null && matchFinderIndexPrev != _matchFinderType)
1587
+ {
1588
+ _dictionarySizePrev = 0xFFFFFFFF;
1589
+ _matchFinder = null;
1590
+ }
1591
+ break;
1592
+ }
1593
+ case CoderPropID.DictionarySize:
1594
+ {
1595
+ const int kDicLogSizeMaxCompress = 30;
1596
+ if (!(prop is Int32))
1597
+ throw new InvalidParamException();
1598
+ ;
1599
+ Int32 dictionarySize = (Int32)prop;
1600
+ if (
1601
+ dictionarySize < (UInt32)(1 << Base.kDicLogSizeMin)
1602
+ || dictionarySize > (UInt32)(1 << kDicLogSizeMaxCompress)
1603
+ )
1604
+ throw new InvalidParamException();
1605
+ _dictionarySize = (UInt32)dictionarySize;
1606
+ int dicLogSize;
1607
+ for (
1608
+ dicLogSize = 0;
1609
+ dicLogSize < (UInt32)kDicLogSizeMaxCompress;
1610
+ dicLogSize++
1611
+ )
1612
+ if (dictionarySize <= ((UInt32)(1) << dicLogSize))
1613
+ break;
1614
+ _distTableSize = (UInt32)dicLogSize * 2;
1615
+ break;
1616
+ }
1617
+ case CoderPropID.PosStateBits:
1618
+ {
1619
+ if (!(prop is Int32))
1620
+ throw new InvalidParamException();
1621
+ Int32 v = (Int32)prop;
1622
+ if (v < 0 || v > (UInt32)Base.kNumPosStatesBitsEncodingMax)
1623
+ throw new InvalidParamException();
1624
+ _posStateBits = (int)v;
1625
+ _posStateMask = (((UInt32)1) << (int)_posStateBits) - 1;
1626
+ break;
1627
+ }
1628
+ case CoderPropID.LitPosBits:
1629
+ {
1630
+ if (!(prop is Int32))
1631
+ throw new InvalidParamException();
1632
+ Int32 v = (Int32)prop;
1633
+ if (v < 0 || v > (UInt32)Base.kNumLitPosStatesBitsEncodingMax)
1634
+ throw new InvalidParamException();
1635
+ _numLiteralPosStateBits = (int)v;
1636
+ break;
1637
+ }
1638
+ case CoderPropID.LitContextBits:
1639
+ {
1640
+ if (!(prop is Int32))
1641
+ throw new InvalidParamException();
1642
+ Int32 v = (Int32)prop;
1643
+ if (v < 0 || v > (UInt32)Base.kNumLitContextBitsMax)
1644
+ throw new InvalidParamException();
1645
+ ;
1646
+ _numLiteralContextBits = (int)v;
1647
+ break;
1648
+ }
1649
+ case CoderPropID.EndMarker:
1650
+ {
1651
+ if (!(prop is Boolean))
1652
+ throw new InvalidParamException();
1653
+ SetWriteEndMarkerMode((Boolean)prop);
1654
+ break;
1655
+ }
1656
+ default:
1657
+ throw new InvalidParamException();
1658
+ }
1659
+ }
1660
+ }
1661
+
1662
+ uint _trainSize = 0;
1663
+
1664
+ public void SetTrainSize(uint trainSize)
1665
+ {
1666
+ _trainSize = trainSize;
1667
+ }
1668
+ }
1669
+ }