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

📄 lzmaencoder.h

📁 MONA是为数不多的C++语言编写的一个很小的操作系统
💻 H
字号:
// LZMA/Encoder.h#ifndef __LZMA_ENCODER_H#define __LZMA_ENCODER_H#include "../../../Common/MyCom.h"#include "../../../Common/Alloc.h"#include "../../ICoder.h"#include "../LZ/IMatchFinder.h"#include "../RangeCoder/RangeCoderBitTree.h"#include "LZMA.h"namespace NCompress {namespace NLZMA {typedef NRangeCoder::CBitEncoder<kNumMoveBits> CMyBitEncoder;class CBaseState{protected:  CState _state;  Byte _previousByte;  bool _peviousIsMatch;  UInt32 _repDistances[kNumRepDistances];  void Init()  {    _state.Init();    _previousByte = 0;    _peviousIsMatch = false;    for(UInt32 i = 0 ; i < kNumRepDistances; i++)      _repDistances[i] = 0;  }};struct COptimal{  CState State;  bool Prev1IsChar;  bool Prev2;  UInt32 PosPrev2;  UInt32 BackPrev2;       UInt32 Price;      UInt32 PosPrev;         // posNext;  UInt32 BackPrev;       UInt32 Backs[kNumRepDistances];  void MakeAsChar() { BackPrev = UInt32(-1); Prev1IsChar = false; }  void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; }  bool IsShortRep() { return (BackPrev == 0); }};extern Byte g_FastPos[1024];inline UInt32 GetPosSlot(UInt32 pos){  if (pos < (1 << 10))    return g_FastPos[pos];  if (pos < (1 << 19))    return g_FastPos[pos >> 9] + 18;  return g_FastPos[pos >> 18] + 36;}inline UInt32 GetPosSlot2(UInt32 pos){  if (pos < (1 << 16))    return g_FastPos[pos >> 6] + 12;  if (pos < (1 << 25))    return g_FastPos[pos >> 15] + 30;  return g_FastPos[pos >> 24] + 48;}const UInt32 kIfinityPrice = 0xFFFFFFF;const UInt32 kNumOpts = 1 << 12;class CLiteralEncoder2{  CMyBitEncoder _encoders[0x300];public:  void Init()  {    for (int i = 0; i < 0x300; i++)      _encoders[i].Init();  }  void Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol);  void EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, Byte matchByte, Byte symbol);  UInt32 GetPrice(bool matchMode, Byte matchByte, Byte symbol) const;};class CLiteralEncoder{  CLiteralEncoder2 *_coders;  int _numPrevBits;  int _numPosBits;  UInt32 _posMask;public:  CLiteralEncoder(): _coders(0) {}  ~CLiteralEncoder()  { Free(); }  void Free()  {     MyFree(_coders);    _coders = 0;  }  bool Create(int numPosBits, int numPrevBits)  {    if (_coders == 0 || (numPosBits + numPrevBits) !=         (_numPrevBits + _numPosBits) )    {      Free();      UInt32 numStates = 1 << (numPosBits + numPrevBits);      _coders = (CLiteralEncoder2 *)MyAlloc(numStates * sizeof(CLiteralEncoder2));    }    _numPosBits = numPosBits;    _posMask = (1 << numPosBits) - 1;    _numPrevBits = numPrevBits;    return (_coders != 0);  }  void Init()  {    UInt32 numStates = 1 << (_numPrevBits + _numPosBits);    for (UInt32 i = 0; i < numStates; i++)      _coders[i].Init();  }  UInt32 GetState(UInt32 pos, Byte prevByte) const    { return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); }  CLiteralEncoder2 *GetSubCoder(UInt32 pos, Byte prevByte)    { return &_coders[GetState(pos, prevByte)]; }  /*  void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 pos, Byte prevByte,       Byte symbol)    { _coders[GetState(pos, prevByte)].Encode(rangeEncoder, symbol); }  void EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, UInt32 pos, Byte prevByte,       Byte matchByte, Byte symbol)    { _coders[GetState(pos, prevByte)].Encode(rangeEncoder,      matchByte, symbol); }  */  UInt32 GetPrice(UInt32 pos, Byte prevByte, bool matchMode, Byte matchByte, Byte symbol) const    { return _coders[GetState(pos, prevByte)].GetPrice(matchMode, matchByte, symbol); }};namespace NLength {class CEncoder{  CMyBitEncoder _choice;  NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumLowBits>  _lowCoder[kNumPosStatesEncodingMax];  CMyBitEncoder  _choice2;  NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumMidBits>  _midCoder[kNumPosStatesEncodingMax];  NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumHighBits>  _highCoder;public:  void Init(UInt32 numPosStates);  void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState);  UInt32 GetPrice(UInt32 symbol, UInt32 posState) const;};const UInt32 kNumSpecSymbols = kNumLowSymbols + kNumMidSymbols;class CPriceTableEncoder: public CEncoder{  UInt32 _prices[kNumSymbolsTotal][kNumPosStatesEncodingMax];  UInt32 _tableSize;  UInt32 _counters[kNumPosStatesEncodingMax];public:  void SetTableSize(UInt32 tableSize) { _tableSize = tableSize;  }  UInt32 GetPrice(UInt32 symbol, UInt32 posState) const    { return _prices[symbol][posState]; }  void UpdateTable(UInt32 posState)  {    for (UInt32 len = 0; len < _tableSize; len++)      _prices[len][posState] = CEncoder::GetPrice(len, posState);    _counters[posState] = _tableSize;  }  void UpdateTables(UInt32 numPosStates)  {    for (UInt32 posState = 0; posState < numPosStates; posState++)      UpdateTable(posState);  }  void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState)  {    CEncoder::Encode(rangeEncoder, symbol, posState);    if (--_counters[posState] == 0)      UpdateTable(posState);  }};}class CEncoder :   public ICompressCoder,  public ICompressSetOutStream,  public ICompressSetCoderProperties,  public ICompressWriteCoderProperties,  public CBaseState,  public CMyUnknownImp{  COptimal _optimum[kNumOpts];  CMyComPtr<IMatchFinder> _matchFinder; // test it  NRangeCoder::CEncoder _rangeEncoder;  CMyBitEncoder _isMatch[kNumStates][NLength::kNumPosStatesEncodingMax];  CMyBitEncoder _isRep[kNumStates];  CMyBitEncoder _isRepG0[kNumStates];  CMyBitEncoder _isRepG1[kNumStates];  CMyBitEncoder _isRepG2[kNumStates];  CMyBitEncoder _isRep0Long[kNumStates][NLength::kNumPosStatesEncodingMax];  /* !!! */  CMyBitEncoder _K_isRepExt[kNumStates];  NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumRepExtBits> _K_RepExt;  NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumPosSlotBits> _posSlotEncoder[kNumLenToPosStates];  CMyBitEncoder _posEncoders[kNumFullDistances - kEndPosModelIndex];  NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumAlignBits> _posAlignEncoder;    NLength::CPriceTableEncoder _lenEncoder;  NLength::CPriceTableEncoder _repMatchLenEncoder;  CLiteralEncoder _literalEncoder;  UInt32 _matchDistances[kMatchMaxLen + 1];  bool _fastMode;  bool _maxMode;  UInt32 _numFastBytes;  UInt32 _longestMatchLength;      UInt32 _additionalOffset;  UInt32 _optimumEndIndex;  UInt32 _optimumCurrentIndex;  bool _longestMatchWasFound;  UInt32 _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];    UInt32 _distancesPrices[kNumLenToPosStates][kNumFullDistances];  UInt32 _alignPrices[kAlignTableSize];  UInt32 _alignPriceCount;  UInt32 _distTableSize;  UInt32 _posStateBits;  UInt32 _posStateMask;  UInt32 _numLiteralPosStateBits;  UInt32 _numLiteralContextBits;  UInt32 _dictionarySize;  UInt32 _dictionarySizePrev;  UInt32 _numFastBytesPrev;  UInt64 lastPosSlotFillingPos;  UInt64 nowPos64;  bool _finished;  ISequentialInStream *_inStream;  int _matchFinderIndex;  #ifdef COMPRESS_MF_MT  bool _multiThread;  #endif  bool _writeEndMark;  bool _needReleaseMFStream;    HRESULT ReadMatchDistances(UInt32 &len);  HRESULT MovePos(UInt32 num);  UInt32 GetRepLen1Price(CState state, UInt32 posState) const  {    return _isRepG0[state.Index].GetPrice(0) +        _isRep0Long[state.Index][posState].GetPrice(0);  }  UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, CState state, UInt32 posState) const  {    UInt32 price = _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState);    if(repIndex == 0)    {      price += _isRepG0[state.Index].GetPrice(0);      price += _isRep0Long[state.Index][posState].GetPrice(1);    }    else    {      price += _isRepG0[state.Index].GetPrice(1);      if (repIndex == 1)        price += _isRepG1[state.Index].GetPrice(0);      else      {        price += _isRepG1[state.Index].GetPrice(1);        price += _isRepG2[state.Index].GetPrice(repIndex - 2);      }    }    return price;  }  /*  UInt32 GetPosLen2Price(UInt32 pos, UInt32 posState) const  {    if (pos >= kNumFullDistances)      return kIfinityPrice;    return _distancesPrices[0][pos] + _lenEncoder.GetPrice(0, posState);  }  UInt32 GetPosLen3Price(UInt32 pos, UInt32 len, UInt32 posState) const  {    UInt32 price;    UInt32 lenToPosState = GetLenToPosState(len);    if (pos < kNumFullDistances)      price = _distancesPrices[lenToPosState][pos];    else      price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] +           _alignPrices[pos & kAlignMask];    return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);  }  */  UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState) const  {    if (len == 2 && pos >= 0x80)      return kIfinityPrice;    UInt32 price;    UInt32 lenToPosState = GetLenToPosState(len);    if (pos < kNumFullDistances)      price = _distancesPrices[lenToPosState][pos];    else      price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] +           _alignPrices[pos & kAlignMask];    return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);  }  UInt32 Backward(UInt32 &backRes, UInt32 cur);  HRESULT GetOptimum(UInt32 position, UInt32 &backRes, UInt32 &lenRes);  HRESULT GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRes);  void FillPosSlotPrices();  void FillDistancesPrices();  void FillAlignPrices();      void ReleaseMFStream()  {    if (_matchFinder && _needReleaseMFStream)    {      _matchFinder->ReleaseStream();      _needReleaseMFStream = false;    }  }  void ReleaseStreams()  {    ReleaseMFStream();    _rangeEncoder.ReleaseStream();  }  HRESULT Flush(UInt32 nowPos);  class CCoderReleaser  {    CEncoder *_coder;  public:    CCoderReleaser(CEncoder *coder): _coder(coder) {}    ~CCoderReleaser()    {      _coder->ReleaseStreams();    }  };  friend class CCoderReleaser;  void WriteEndMarker(UInt32 posState);public:  CEncoder();  void SetWriteEndMarkerMode(bool writeEndMarker)    { _writeEndMark= writeEndMarker; }  HRESULT Create();  MY_UNKNOWN_IMP3(      ICompressSetOutStream,      ICompressSetCoderProperties,      ICompressWriteCoderProperties      )      HRESULT Init();    // ICompressCoder interface  HRESULT SetStreams(ISequentialInStream *inStream,      ISequentialOutStream *outStream,      const UInt64 *inSize, const UInt64 *outSize);  HRESULT CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished);  HRESULT CodeReal(ISequentialInStream *inStream,      ISequentialOutStream *outStream,       const UInt64 *inSize, const UInt64 *outSize,      ICompressProgressInfo *progress);  // ICompressCoder interface  STDMETHOD(Code)(ISequentialInStream *inStream,      ISequentialOutStream *outStream,       const UInt64 *inSize, const UInt64 *outSize,      ICompressProgressInfo *progress);  // IInitMatchFinder interface  STDMETHOD(InitMatchFinder)(IMatchFinder *matchFinder);  // ICompressSetCoderProperties2  STDMETHOD(SetCoderProperties)(const PROPID *propIDs,       const PROPVARIANT *properties, UInt32 numProperties);    // ICompressWriteCoderProperties  STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);  STDMETHOD(SetOutStream)(ISequentialOutStream *outStream);  virtual ~CEncoder() {}};}}#endif

⌨️ 快捷键说明

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