Exemplo n.º 1
0
 int getPosLenPrice(int pos, int len, int posState) {
   int price;
   int lenToPosState = Base.getLenToPosState(len);
   if (pos < Base.kNumFullDistances) {
     price = _distancesPrices[(lenToPosState * Base.kNumFullDistances) + pos];
   } else {
     price =
         _posSlotPrices[(lenToPosState << Base.kNumPosSlotBits) + getPosSlot2(pos)]
             + _alignPrices[pos & Base.kAlignMask];
   }
   return price + _lenEncoder.getPrice(len - Base.kMatchMinLen, posState);
 }
Exemplo n.º 2
0
  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);
  }
Exemplo n.º 3
0
  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;
        }
      }
    }
  }