Encoder.java 40 KB

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