ruby-lzma 0.4.1

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