⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lzmaencoder.cpp

📁 sleuthit-2.09 一个磁盘的工具集
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    _isRepG1[i].Init();    _isRepG2[i].Init();  }  _literalEncoder.Init();  {    for(UInt32 i = 0; i < kNumLenToPosStates; i++)      _posSlotEncoder[i].Init();  }  {    for(UInt32 i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)      _posEncoders[i].Init();  }  _lenEncoder.Init(1 << _posStateBits);  _repMatchLenEncoder.Init(1 << _posStateBits);  _posAlignEncoder.Init();  _longestMatchWasFound = false;  _optimumEndIndex = 0;  _optimumCurrentIndex = 0;  _additionalOffset = 0;  return S_OK;}HRESULT CEncoder::MovePos(UInt32 num){  if (num == 0)    return S_OK;  _additionalOffset += num;  return _matchFinder->Skip(num);}UInt32 CEncoder::Backward(UInt32 &backRes, UInt32 cur){  _optimumEndIndex = cur;  UInt32 posMem = _optimum[cur].PosPrev;  UInt32 backMem = _optimum[cur].BackPrev;  do  {    if (_optimum[cur].Prev1IsChar)    {      _optimum[posMem].MakeAsChar();      _optimum[posMem].PosPrev = posMem - 1;      if (_optimum[cur].Prev2)      {        _optimum[posMem - 1].Prev1IsChar = false;        _optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2;        _optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2;      }    }    UInt32 posPrev = posMem;    UInt32 backCur = backMem;    backMem = _optimum[posPrev].BackPrev;    posMem = _optimum[posPrev].PosPrev;    _optimum[posPrev].BackPrev = backCur;    _optimum[posPrev].PosPrev = cur;    cur = posPrev;  }  while(cur != 0);  backRes = _optimum[0].BackPrev;  _optimumCurrentIndex  = _optimum[0].PosPrev;  return _optimumCurrentIndex; }/*Out:  (lenRes == 1) && (backRes == 0xFFFFFFFF) means Literal*/HRESULT CEncoder::GetOptimum(UInt32 position, UInt32 &backRes, UInt32 &lenRes){  if(_optimumEndIndex != _optimumCurrentIndex)  {    const COptimal &optimum = _optimum[_optimumCurrentIndex];    lenRes = optimum.PosPrev - _optimumCurrentIndex;    backRes = optimum.BackPrev;    _optimumCurrentIndex = optimum.PosPrev;    return S_OK;  }  _optimumCurrentIndex = _optimumEndIndex = 0;    UInt32 lenMain, numDistancePairs;  if (!_longestMatchWasFound)  {    RINOK(ReadMatchDistances(lenMain, numDistancePairs));  }  else  {    lenMain = _longestMatchLength;    numDistancePairs = _numDistancePairs;    _longestMatchWasFound = false;  }  const Byte *data = _matchFinder->GetPointerToCurrentPos() - 1;  UInt32 numAvailableBytes = _matchFinder->GetNumAvailableBytes() + 1;  if (numAvailableBytes < 2)  {    backRes = (UInt32)(-1);    lenRes = 1;    return S_OK;  }  if (numAvailableBytes > kMatchMaxLen)    numAvailableBytes = kMatchMaxLen;  UInt32 reps[kNumRepDistances];  UInt32 repLens[kNumRepDistances];  UInt32 repMaxIndex = 0;  UInt32 i;  for(i = 0; i < kNumRepDistances; i++)  {    reps[i] = _repDistances[i];    UInt32 backOffset = reps[i] + 1;    if (data[0] != data[(size_t)0 - backOffset] || data[1] != data[(size_t)1 - backOffset])    {      repLens[i] = 0;      continue;    }    UInt32 lenTest;    for (lenTest = 2; lenTest < numAvailableBytes &&         data[lenTest] == data[(size_t)lenTest - backOffset]; lenTest++);    repLens[i] = lenTest;    if (lenTest > repLens[repMaxIndex])      repMaxIndex = i;  }  if(repLens[repMaxIndex] >= _numFastBytes)  {    backRes = repMaxIndex;    lenRes = repLens[repMaxIndex];    return MovePos(lenRes - 1);  }  UInt32 *matchDistances = _matchDistances + 1;  if(lenMain >= _numFastBytes)  {    backRes = matchDistances[numDistancePairs - 1] + kNumRepDistances;     lenRes = lenMain;    return MovePos(lenMain - 1);  }  Byte currentByte = *data;  Byte matchByte = data[(size_t)0 - reps[0] - 1];  if(lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2)  {    backRes = (UInt32)-1;    lenRes = 1;    return S_OK;  }  _optimum[0].State = _state;  UInt32 posState = (position & _posStateMask);  _optimum[1].Price = _isMatch[_state.Index][posState].GetPrice0() +       _literalEncoder.GetSubCoder(position, _previousByte)->GetPrice(!_state.IsCharState(), matchByte, currentByte);  _optimum[1].MakeAsChar();  UInt32 matchPrice = _isMatch[_state.Index][posState].GetPrice1();  UInt32 repMatchPrice = matchPrice + _isRep[_state.Index].GetPrice1();  if(matchByte == currentByte)  {    UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState);    if(shortRepPrice < _optimum[1].Price)    {      _optimum[1].Price = shortRepPrice;      _optimum[1].MakeAsShortRep();    }  }  UInt32 lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]);  if(lenEnd < 2)  {    backRes = _optimum[1].BackPrev;    lenRes = 1;    return S_OK;  }  _optimum[1].PosPrev = 0;  for (i = 0; i < kNumRepDistances; i++)    _optimum[0].Backs[i] = reps[i];  UInt32 len = lenEnd;  do    _optimum[len--].Price = kIfinityPrice;  while (len >= 2);  for(i = 0; i < kNumRepDistances; i++)  {    UInt32 repLen = repLens[i];    if (repLen < 2)      continue;    UInt32 price = repMatchPrice + GetPureRepPrice(i, _state, posState);    do    {      UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(repLen - 2, posState);      COptimal &optimum = _optimum[repLen];      if (curAndLenPrice < optimum.Price)       {        optimum.Price = curAndLenPrice;        optimum.PosPrev = 0;        optimum.BackPrev = i;        optimum.Prev1IsChar = false;      }    }    while(--repLen >= 2);  }  UInt32 normalMatchPrice = matchPrice + _isRep[_state.Index].GetPrice0();  len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);  if (len <= lenMain)  {    UInt32 offs = 0;    while (len > matchDistances[offs])      offs += 2;    for(; ; len++)    {      UInt32 distance = matchDistances[offs + 1];      UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState);      COptimal &optimum = _optimum[len];      if (curAndLenPrice < optimum.Price)       {        optimum.Price = curAndLenPrice;        optimum.PosPrev = 0;        optimum.BackPrev = distance + kNumRepDistances;        optimum.Prev1IsChar = false;      }      if (len == matchDistances[offs])      {        offs += 2;        if (offs == numDistancePairs)          break;      }    }  }  UInt32 cur = 0;  while(true)  {    cur++;    if(cur == lenEnd)    {      lenRes = Backward(backRes, cur);      return S_OK;    }    UInt32 newLen, numDistancePairs;    RINOK(ReadMatchDistances(newLen, numDistancePairs));    if(newLen >= _numFastBytes)    {      _numDistancePairs = numDistancePairs;      _longestMatchLength = newLen;      _longestMatchWasFound = true;      lenRes = Backward(backRes, cur);      return S_OK;    }    position++;    COptimal &curOptimum = _optimum[cur];    UInt32 posPrev = curOptimum.PosPrev;    CState state;    if (curOptimum.Prev1IsChar)    {      posPrev--;      if (curOptimum.Prev2)      {        state = _optimum[curOptimum.PosPrev2].State;        if (curOptimum.BackPrev2 < kNumRepDistances)          state.UpdateRep();        else          state.UpdateMatch();      }      else        state = _optimum[posPrev].State;      state.UpdateChar();    }    else      state = _optimum[posPrev].State;    if (posPrev == cur - 1)    {      if (curOptimum.IsShortRep())        state.UpdateShortRep();      else        state.UpdateChar();    }    else    {      UInt32 pos;      if (curOptimum.Prev1IsChar && curOptimum.Prev2)      {        posPrev = curOptimum.PosPrev2;        pos = curOptimum.BackPrev2;        state.UpdateRep();      }      else      {        pos = curOptimum.BackPrev;        if (pos < kNumRepDistances)          state.UpdateRep();        else          state.UpdateMatch();      }      const COptimal &prevOptimum = _optimum[posPrev];      if (pos < kNumRepDistances)      {        reps[0] = prevOptimum.Backs[pos];    		UInt32 i;        for(i = 1; i <= pos; i++)          reps[i] = prevOptimum.Backs[i - 1];        for(; i < kNumRepDistances; i++)          reps[i] = prevOptimum.Backs[i];      }      else      {        reps[0] = (pos - kNumRepDistances);        for(UInt32 i = 1; i < kNumRepDistances; i++)          reps[i] = prevOptimum.Backs[i - 1];      }    }    curOptimum.State = state;    for(UInt32 i = 0; i < kNumRepDistances; i++)      curOptimum.Backs[i] = reps[i];    UInt32 curPrice = curOptimum.Price;     const Byte *data = _matchFinder->GetPointerToCurrentPos() - 1;    const Byte currentByte = *data;    const Byte matchByte = data[(size_t)0 - reps[0] - 1];    UInt32 posState = (position & _posStateMask);    UInt32 curAnd1Price = curPrice +        _isMatch[state.Index][posState].GetPrice0() +        _literalEncoder.GetSubCoder(position, data[(size_t)0 - 1])->GetPrice(!state.IsCharState(), matchByte, currentByte);    COptimal &nextOptimum = _optimum[cur + 1];    bool nextIsChar = false;    if (curAnd1Price < nextOptimum.Price)     {      nextOptimum.Price = curAnd1Price;      nextOptimum.PosPrev = cur;      nextOptimum.MakeAsChar();      nextIsChar = true;    }    UInt32 matchPrice = curPrice + _isMatch[state.Index][posState].GetPrice1();    UInt32 repMatchPrice = matchPrice + _isRep[state.Index].GetPrice1();        if(matchByte == currentByte &&        !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0))    {      UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState);      if(shortRepPrice <= nextOptimum.Price)      {        nextOptimum.Price = shortRepPrice;        nextOptimum.PosPrev = cur;        nextOptimum.MakeAsShortRep();        nextIsChar = true;      }    }    /*    if(newLen == 2 && matchDistances[2] >= kDistLimit2) // test it maybe set 2000 ?      continue;    */    UInt32 numAvailableBytesFull = _matchFinder->GetNumAvailableBytes() + 1;    numAvailableBytesFull = MyMin(kNumOpts - 1 - cur, numAvailableBytesFull);    UInt32 numAvailableBytes = numAvailableBytesFull;    if (numAvailableBytes < 2)      continue;    if (numAvailableBytes > _numFastBytes)      numAvailableBytes = _numFastBytes;    if (!nextIsChar && matchByte != currentByte) // speed optimization    {      // try Literal + rep0      UInt32 backOffset = reps[0] + 1;      UInt32 limit = MyMin(numAvailableBytesFull, _numFastBytes + 1);      UInt32 temp;      for (temp = 1; temp < limit &&           data[temp] == data[(size_t)temp - backOffset]; temp++);      UInt32 lenTest2 = temp - 1;      if (lenTest2 >= 2)      {        CState state2 = state;        state2.UpdateChar();        UInt32 posStateNext = (position + 1) & _posStateMask;        UInt32 nextRepMatchPrice = curAnd1Price +             _isMatch[state2.Index][posStateNext].GetPrice1() +            _isRep[state2.Index].GetPrice1();        // for (; lenTest2 >= 2; lenTest2--)        {          UInt32 offset = cur + 1 + lenTest2;          while(lenEnd < offset)            _optimum[++lenEnd].Price = kIfinityPrice;          UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(              0, lenTest2, state2, posStateNext);          COptimal &optimum = _optimum[offset];          if (curAndLenPrice < optimum.Price)           {            optimum.Price = curAndLenPrice;            optimum.PosPrev = cur + 1;            optimum.BackPrev = 0;            optimum.Prev1IsChar = true;            optimum.Prev2 = false;          }        }      }    }        UInt32 startLen = 2; // speed optimization     for(UInt32 repIndex = 0; repIndex < kNumRepDistances; repIndex++)    {      // UInt32 repLen = _matchFinder->GetMatchLen(0 - 1, reps[repIndex], newLen); // test it;      UInt32 backOffset = reps[repIndex] + 1;      if (data[0] != data[(size_t)0 - backOffset] ||          data[1] != data[(size_t)1 - backOffset])        continue;      UInt32 lenTest;      for (lenTest = 2; lenTest < numAvailableBytes &&           data[lenTest] == data[(size_t)lenTest - backOffset]; lenTest++);      while(lenEnd < cur + lenTest)        _optimum[++lenEnd].Price = kIfinityPrice;      UInt32 lenTestTemp = lenTest;      UInt32 price = repMatchPrice + GetPureRepPrice(repIndex, state, posState);      do      {        UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(lenTest - 2, posState);        COptimal &optimum = _optimum[cur + lenTest];        if (curAndLenPrice < optimum.Price)         {          optimum.Price = curAndLenPrice;          optimum.PosPrev = cur;          optimum.BackPrev = repIndex;          optimum.Prev1IsChar = false;        }      }      while(--lenTest >= 2);      lenTest = lenTestTemp;            if (repIndex == 0)        startLen = lenTest + 1;              // if (_maxMode)        {          UInt32 lenTest2 = lenTest + 1;          UInt32 limit = MyMin(numAvailableBytesFull, lenTest2 + _numFastBytes);          for (; lenTest2 < limit &&               data[lenTest2] == data[(size_t)lenTest2 - backOffset]; lenTest2++);          lenTest2 -= lenTest + 1;          if (lenTest2 >= 2)          {            CState state2 = state;            state2.UpdateRep();            UInt32 posStateNext = (position + lenTest) & _posStateMask;            UInt32 curAndLenCharPrice =                 price + _repMatchLenEncoder.GetPrice(lenTest - 2, posState) +                 _isMatch[state2.Index][posStateNext].GetPrice0() +                _literalEncoder.GetSubCoder(position + lenTest, data[(size_t)lenTest - 1])->GetPrice(                true, data[(size_t)lenTest - backOffset], data[lenTest]);            state2.UpdateChar();            posStateNext = (position + lenTest + 1) & _posStateMask;            UInt32 nextRepMatchPrice = curAndLenCharPrice +                 _isMatch[state2.Index][posStateNext].GetPrice1() +                _isRep[state2.Index].GetPrice1();                        // for(; lenTest2 >= 2; lenTest2--)            {              UInt32 offset = cur + lenTest + 1 + lenTest2;              while(lenEnd < offset)                _optimum[++lenEnd].Price = kIfinityPrice;              UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(                  0, lenTest2, state2, posStateNext);              COptimal &optimum = _optimum[offset];              if (curAndLenPrice < optimum.Price)               {                optimum.Price = curAndLenPrice;                optimum.PosPrev = cur + lenTest + 1;                optimum.BackPrev = 0;                optimum.Prev1IsChar = true;                optimum.Prev2 = true;                optimum.PosPrev2 = cur;                optimum.BackPrev2 = repIndex;              }            }          }        }      }        //    for(UInt32 lenTest = 2; lenTest <= newLen; lenTest++)    if (newLen > numAvailableBytes)    {      newLen = numAvailableBytes;      for (numDistancePairs = 0; newLen > matchDistances[numDistancePairs]; numDistancePairs += 2);      matchDistances[numDistancePairs] = newLen;      numDistancePairs += 2;    }    if (newLen >= startLen)    {      UInt32 normalMatchPrice = matchPrice + _isRep[state.Index].GetPrice0();      while(lenEnd < cur + newLen)        _optimum[++lenEnd].Price = kIfinityPrice;      UInt32 offs = 0;      while(startLen > matchDistances[offs])        offs += 2;      UInt32 curBack = matchDistances[offs + 1];      UInt32 posSlot = GetPosSlot2(curBack);      for(UInt32 lenTest = /*2*/ startLen; ; lenTest++)      {        UInt32 curAndLenPrice = normalMatchPrice;        UInt32 lenToPosState = GetLenToPosState(lenTest);        if (curBack < kNumFullDistances)          curAndLenPrice += _distancesPrices[lenToPosState][curBack];        else          curAndLenPrice += _posSlotPrices[lenToPosState][posSlot] + _alignPrices[curBack & kAlignMask];          curAndLenPrice += _lenEncoder.GetPrice(lenTest - kMatchMinLen, posState);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -