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

📄 lzmaencoder.cpp

📁 proximap bootloader for study
💻 CPP
📖 第 1 页 / 共 3 页
字号:
STDMETHODIMP CEncoder::SetOutStream(ISequentialOutStream *outStream){  _rangeEncoder.SetStream(outStream);  return S_OK;}HRESULT CEncoder::Init(){  CBaseState::Init();  // RINOK(_matchFinder->Init(inStream));  _rangeEncoder.Init();  for(int i = 0; i < kNumStates; i++)  {    for (UInt32 j = 0; j <= _posStateMask; j++)    {      _isMatch[i][j].Init();      _isRep0Long[i][j].Init();    }    _isRep[i].Init();    _isRepG0[i].Init();    _isRepG1[i].Init();    _isRepG2[i].Init();  }  _literalEncoder.Init();  // _repMatchLenEncoder.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){  for (;num > 0; num--)  {    _matchFinder->DummyLongestMatch();    RINOK(_matchFinder->MovePos());    _additionalOffset++;  }  return S_OK;}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; }/*inline UInt32 GetMatchLen(const Byte *data, UInt32 back, UInt32 limit){    back++;  for(UInt32 i = 0; i < limit && data[i] == data[i - back]; i++);  return i;}*/HRESULT CEncoder::GetOptimum(UInt32 position, UInt32 &backRes, UInt32 &lenRes){  if(_optimumEndIndex != _optimumCurrentIndex)  {    lenRes = _optimum[_optimumCurrentIndex].PosPrev - _optimumCurrentIndex;    backRes = _optimum[_optimumCurrentIndex].BackPrev;    _optimumCurrentIndex = _optimum[_optimumCurrentIndex].PosPrev;    return S_OK;  }  _optimumCurrentIndex = 0;  _optimumEndIndex = 0; // test it;    UInt32 lenMain;  if (!_longestMatchWasFound)  {    RINOK(ReadMatchDistances(lenMain));  }  else  {    lenMain = _longestMatchLength;    _longestMatchWasFound = false;  }  UInt32 reps[kNumRepDistances];  UInt32 repLens[kNumRepDistances];  UInt32 repMaxIndex = 0;  UInt32 i;  for(i = 0; i < kNumRepDistances; i++)  {    reps[i] = _repDistances[i];    repLens[i] = _matchFinder->GetMatchLen(0 - 1, reps[i], kMatchMaxLen);    if (i == 0 || repLens[i] > repLens[repMaxIndex])      repMaxIndex = i;  }  if(repLens[repMaxIndex] > _numFastBytes)  {    backRes = repMaxIndex;    lenRes = repLens[repMaxIndex];    MovePos(lenRes - 1);    return S_OK;  }  if(lenMain > _numFastBytes)  {    UInt32 backMain = (lenMain < _numFastBytes) ? _matchDistances[lenMain] :        _matchDistances[_numFastBytes];    backRes = backMain + kNumRepDistances;     MovePos(lenMain - 1);    lenRes = lenMain;    return S_OK;  }  Byte currentByte = _matchFinder->GetIndexByte(0 - 1);  _optimum[0].State = _state;  Byte matchByte;    matchByte = _matchFinder->GetIndexByte(0 - _repDistances[0] - 1 - 1);  UInt32 posState = (position & _posStateMask);  _optimum[1].Price = _isMatch[_state.Index][posState].GetPrice(0) +       _literalEncoder.GetPrice(position, _previousByte, _peviousIsMatch, matchByte, currentByte);  _optimum[1].MakeAsChar();  _optimum[1].PosPrev = 0;  for (i = 0; i < kNumRepDistances; i++)    _optimum[0].Backs[i] = reps[i];  UInt32 matchPrice = _isMatch[_state.Index][posState].GetPrice(1);  UInt32 repMatchPrice = matchPrice + _isRep[_state.Index].GetPrice(1);  if(matchByte == currentByte)  {    UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState);    if(shortRepPrice < _optimum[1].Price)    {      _optimum[1].Price = shortRepPrice;      _optimum[1].MakeAsShortRep();    }  }  if(lenMain < 2)  {    backRes = _optimum[1].BackPrev;    lenRes = 1;    return S_OK;  }    UInt32 normalMatchPrice = matchPrice +       _isRep[_state.Index].GetPrice(0);  if (lenMain <= repLens[repMaxIndex])    lenMain = 0;  UInt32 len;  for(len = 2; len <= lenMain; len++)  {    _optimum[len].PosPrev = 0;    _optimum[len].BackPrev = _matchDistances[len] + kNumRepDistances;    _optimum[len].Price = normalMatchPrice +         GetPosLenPrice(_matchDistances[len], len, posState);    _optimum[len].Prev1IsChar = false;  }  if (lenMain < repLens[repMaxIndex])    lenMain = repLens[repMaxIndex];  for (; len <= lenMain; len++)    _optimum[len].Price = kIfinityPrice;  for(i = 0; i < kNumRepDistances; i++)  {    UInt32 repLen = repLens[i];    for(UInt32 lenTest = 2; lenTest <= repLen; lenTest++)    {      UInt32 curAndLenPrice = repMatchPrice + GetRepPrice(i, lenTest, _state, posState);      COptimal &optimum = _optimum[lenTest];      if (curAndLenPrice < optimum.Price)       {        optimum.Price = curAndLenPrice;        optimum.PosPrev = 0;        optimum.BackPrev = i;        optimum.Prev1IsChar = false;      }    }  }  UInt32 cur = 0;  UInt32 lenEnd = lenMain;  while(true)  {    cur++;    if(cur == lenEnd)    {      lenRes = Backward(backRes, cur);      return S_OK;    }    position++;    UInt32 posPrev = _optimum[cur].PosPrev;    CState state;    if (_optimum[cur].Prev1IsChar)    {      posPrev--;      if (_optimum[cur].Prev2)      {        state = _optimum[_optimum[cur].PosPrev2].State;        if (_optimum[cur].BackPrev2 < kNumRepDistances)          state.UpdateRep();        else          state.UpdateMatch();      }      else        state = _optimum[posPrev].State;      state.UpdateChar();    }    else      state = _optimum[posPrev].State;    bool prevWasMatch;    if (posPrev == cur - 1)    {      if (_optimum[cur].IsShortRep())      {        prevWasMatch = true;        state.UpdateShortRep();      }      else      {        prevWasMatch = false;        state.UpdateChar();      }      /*      if (_optimum[cur].Prev1IsChar)        for(int i = 0; i < kNumRepDistances; i++)          reps[i] = _optimum[posPrev].Backs[i];      */    }    else    {      prevWasMatch = true;      UInt32 pos;      if (_optimum[cur].Prev1IsChar && _optimum[cur].Prev2)      {        posPrev = _optimum[cur].PosPrev2;        pos = _optimum[cur].BackPrev2;        state.UpdateRep();      }      else      {        pos = _optimum[cur].BackPrev;        if (pos < kNumRepDistances)          state.UpdateRep();        else          state.UpdateMatch();      }      if (pos < kNumRepDistances)      {        reps[0] = _optimum[posPrev].Backs[pos];    		UInt32 i;        for(i = 1; i <= pos; i++)          reps[i] = _optimum[posPrev].Backs[i - 1];        for(; i < kNumRepDistances; i++)          reps[i] = _optimum[posPrev].Backs[i];      }      else      {        reps[0] = (pos - kNumRepDistances);        for(UInt32 i = 1; i < kNumRepDistances; i++)          reps[i] = _optimum[posPrev].Backs[i - 1];      }    }    _optimum[cur].State = state;    for(UInt32 i = 0; i < kNumRepDistances; i++)      _optimum[cur].Backs[i] = reps[i];    UInt32 newLen;    RINOK(ReadMatchDistances(newLen));    if(newLen > _numFastBytes)    {      _longestMatchLength = newLen;      _longestMatchWasFound = true;      lenRes = Backward(backRes, cur);      return S_OK;    }    UInt32 curPrice = _optimum[cur].Price;     // Byte currentByte  = _matchFinder->GetIndexByte(0 - 1);    // Byte matchByte = _matchFinder->GetIndexByte(0 - reps[0] - 1 - 1);    const Byte *data = _matchFinder->GetPointerToCurrentPos() - 1;    Byte currentByte = *data;    Byte matchByte = data[(size_t)0 - reps[0] - 1];    UInt32 posState = (position & _posStateMask);    UInt32 curAnd1Price = curPrice +        _isMatch[state.Index][posState].GetPrice(0) +        _literalEncoder.GetPrice(position, data[(size_t)0 - 1], prevWasMatch, 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].GetPrice(1);    UInt32 repMatchPrice = matchPrice + _isRep[state.Index].GetPrice(1);        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 = false;      }    }    /*    if(newLen == 2 && _matchDistances[2] >= kDistLimit2) // test it maybe set 2000 ?      continue;    */    UInt32 numAvailableBytes = _matchFinder->GetNumAvailableBytes() + 1;    numAvailableBytes = MyMin(kNumOpts - 1 - cur, numAvailableBytes);    if (numAvailableBytes < 2)      continue;    if (numAvailableBytes > _numFastBytes)      numAvailableBytes = _numFastBytes;    if (numAvailableBytes >= 3 && !nextIsChar)    {      UInt32 backOffset = reps[0] + 1;      UInt32 temp;      for (temp = 1; temp < numAvailableBytes; temp++)        if (data[temp] != data[(size_t)temp - backOffset])          break;      UInt32 lenTest2 = temp - 1;      if (lenTest2 >= 2)      {        CState state2 = state;        state2.UpdateChar();        UInt32 posStateNext = (position + 1) & _posStateMask;        UInt32 nextRepMatchPrice = curAnd1Price +             _isMatch[state2.Index][posStateNext].GetPrice(1) +            _isRep[state2.Index].GetPrice(1);        // for (; lenTest2 >= 2; lenTest2--)        {          while(lenEnd < cur + 1 + lenTest2)            _optimum[++lenEnd].Price = kIfinityPrice;          UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(              0, lenTest2, state2, posStateNext);          COptimal &optimum = _optimum[cur + 1 + lenTest2];          if (curAndLenPrice < optimum.Price)           {            optimum.Price = curAndLenPrice;            optimum.PosPrev = cur + 1;            optimum.BackPrev = 0;            optimum.Prev1IsChar = true;            optimum.Prev2 = false;          }        }      }    }    for(UInt32 repIndex = 0; repIndex < kNumRepDistances; repIndex++)    {      // UInt32 repLen = _matchFinder->GetMatchLen(0 - 1, reps[repIndex], newLen); // test it;      UInt32 backOffset = reps[repIndex] + 1;      UInt32 lenTest;      for (lenTest = 0; lenTest < numAvailableBytes; lenTest++)        if (data[lenTest] != data[(size_t)lenTest - backOffset])          break;      for(; lenTest >= 2; lenTest--)      {        while(lenEnd < cur + lenTest)          _optimum[++lenEnd].Price = kIfinityPrice;        UInt32 curAndLenPrice = repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState);        COptimal &optimum = _optimum[cur + lenTest];        if (curAndLenPrice < optimum.Price)         {          optimum.Price = curAndLenPrice;          optimum.PosPrev = cur;          optimum.BackPrev = repIndex;          optimum.Prev1IsChar = false;        }        /*        if (_maxMode)        {          UInt32 temp;          for (temp = lenTest + 1; temp < numAvailableBytes; temp++)            if (data[temp] != data[(size_t)temp - backOffset])              break;          UInt32 lenTest2 = temp - (lenTest + 1);          if (lenTest2 >= 2)          {            CState state2 = state;            state2.UpdateRep();            UInt32 posStateNext = (position + lenTest) & _posStateMask;            UInt32 curAndLenCharPrice = curAndLenPrice +                 _isMatch[state2.Index][posStateNext].GetPrice(0) +                _literalEncoder.GetPrice(position + lenTest, data[(size_t)lenTest - 1],                 true, data[(size_t)lenTest - backOffset], data[lenTest]);            state2.UpdateChar();            posStateNext = (position + lenTest + 1) & _posStateMask;            UInt32 nextMatchPrice = curAndLenCharPrice + _isMatch[state2.Index][posStateNext].GetPrice(1);            UInt32 nextRepMatchPrice = nextMatchPrice + _isRep[state2.Index].GetPrice(1);                        // for(; lenTest2 >= 2; lenTest2--)            {              UInt32 offset = lenTest + 1 + lenTest2;              while(lenEnd < cur + offset)                _optimum[++lenEnd].Price = kIfinityPrice;              UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(                  0, lenTest2, state2, posStateNext);              COptimal &optimum = _optimum[cur + 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;    if (newLen >= 2)    {      if (newLen == 2 && _matchDistances[2] >= 0x80)        continue;      UInt32 normalMatchPrice = matchPrice +         _isRep[state.Index].GetPrice(0);      while(lenEnd < cur + newLen)        _optimum[++lenEnd].Price = kIfinityPrice;

⌨️ 快捷键说明

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