void writeEndMarker(int posState) throws IOException { if (!_writeEndMark) { return; } _rangeEncoder.encode(_isMatch, (_state << Base.kNumPosStatesBitsMax) + posState, 1); _rangeEncoder.encode(_isRep, _state, 0); _state = Base.stateUpdateMatch(_state); int len = Base.kMatchMinLen; _lenEncoder.encode(_rangeEncoder, len - Base.kMatchMinLen, posState); int posSlot = (1 << Base.kNumPosSlotBits) - 1; int lenToPosState = Base.getLenToPosState(len); _posSlotEncoder[lenToPosState].encode(_rangeEncoder, posSlot); int footerBits = 30; int posReduced = (1 << footerBits) - 1; _rangeEncoder.encodeDirectBits( posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits); _posAlignEncoder.reverseEncode(_rangeEncoder, posReduced & Base.kAlignMask); }
public void codeOneBlock(long[] inSize, long[] outSize, boolean[] finished) throws IOException { inSize[0] = 0; outSize[0] = 0; finished[0] = true; if (_inStream != null) { _matchFinder.setStream(_inStream); _matchFinder.init(); _needReleaseMFStream = true; _inStream = null; } if (_finished) { return; } _finished = true; long progressPosValuePrev = nowPos64; if (nowPos64 == 0) { if (_matchFinder.getNumAvailableBytes() == 0) { flush((int) nowPos64); return; } readMatchDistances(); int posState = (int) (nowPos64) & _posStateMask; _rangeEncoder.encode(_isMatch, (_state << Base.kNumPosStatesBitsMax) + posState, 0); _state = Base.stateUpdateChar(_state); byte curByte = _matchFinder.getIndexByte(0 - _additionalOffset); _literalEncoder.getSubCoder((int) (nowPos64), _previousByte).encode(_rangeEncoder, curByte); _previousByte = curByte; _additionalOffset--; nowPos64++; } if (_matchFinder.getNumAvailableBytes() == 0) { flush((int) nowPos64); return; } while (true) { int len = getOptimum((int) nowPos64); int pos = backRes; int posState = ((int) nowPos64) & _posStateMask; int complexState = (_state << Base.kNumPosStatesBitsMax) + posState; if (len == 1 && pos == -1) { _rangeEncoder.encode(_isMatch, complexState, 0); byte curByte = _matchFinder.getIndexByte(0 - _additionalOffset); LiteralEncoder.Encoder2 subCoder = _literalEncoder.getSubCoder((int) nowPos64, _previousByte); if (!Base.stateIsCharState(_state)) { byte matchByte = _matchFinder.getIndexByte(0 - _repDistances[0] - 1 - _additionalOffset); subCoder.encodeMatched(_rangeEncoder, matchByte, curByte); } else { subCoder.encode(_rangeEncoder, curByte); } _previousByte = curByte; _state = Base.stateUpdateChar(_state); } else { _rangeEncoder.encode(_isMatch, complexState, 1); if (pos < Base.kNumRepDistances) { _rangeEncoder.encode(_isRep, _state, 1); if (pos == 0) { _rangeEncoder.encode(_isRepG0, _state, 0); if (len == 1) { _rangeEncoder.encode(_isRep0Long, complexState, 0); } else { _rangeEncoder.encode(_isRep0Long, complexState, 1); } } else { _rangeEncoder.encode(_isRepG0, _state, 1); if (pos == 1) { _rangeEncoder.encode(_isRepG1, _state, 0); } else { _rangeEncoder.encode(_isRepG1, _state, 1); _rangeEncoder.encode(_isRepG2, _state, pos - 2); } } if (len == 1) { _state = Base.stateUpdateShortRep(_state); } else { _repMatchLenEncoder.encode(_rangeEncoder, len - Base.kMatchMinLen, posState); _state = Base.stateUpdateRep(_state); } int distance = _repDistances[pos]; if (pos != 0) { for (int i = pos; i >= 1; i--) { _repDistances[i] = _repDistances[i - 1]; } _repDistances[0] = distance; } } else { _rangeEncoder.encode(_isRep, _state, 0); _state = Base.stateUpdateMatch(_state); _lenEncoder.encode(_rangeEncoder, len - Base.kMatchMinLen, posState); pos -= Base.kNumRepDistances; int posSlot = getPosSlot(pos); int lenToPosState = Base.getLenToPosState(len); _posSlotEncoder[lenToPosState].encode(_rangeEncoder, posSlot); if (posSlot >= Base.kStartPosModelIndex) { int footerBits = (posSlot >> 1) - 1; int baseVal = ((2 | (posSlot & 1)) << footerBits); int posReduced = pos - baseVal; if (posSlot < Base.kEndPosModelIndex) { BitTreeEncoder.reverseEncode( _posEncoders, baseVal - posSlot - 1, _rangeEncoder, footerBits, posReduced); } else { _rangeEncoder.encodeDirectBits( posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits); _posAlignEncoder.reverseEncode(_rangeEncoder, posReduced & Base.kAlignMask); _alignPriceCount++; } } int distance = pos; for (int i = Base.kNumRepDistances - 1; i >= 1; i--) { _repDistances[i] = _repDistances[i - 1]; } _repDistances[0] = distance; _matchPriceCount++; } _previousByte = _matchFinder.getIndexByte(len - 1 - _additionalOffset); } _additionalOffset -= len; nowPos64 += len; if (_additionalOffset == 0) { // if (!_fastMode) if (_matchPriceCount >= (1 << 7)) { fillDistancesPrices(); } if (_alignPriceCount >= Base.kAlignTableSize) { fillAlignPrices(); } inSize[0] = nowPos64; outSize[0] = _rangeEncoder.getProcessedSizeAdd(); if (_matchFinder.getNumAvailableBytes() == 0) { flush((int) nowPos64); return; } if (nowPos64 - progressPosValuePrev >= (1 << 12)) { _finished = false; finished[0] = false; return; } } } }