// DeflateEncoder.h #ifndef __DEFLATE_ENCODER_H #define __DEFLATE_ENCODER_H #include "../../../C/LzFind.h" #include "Common/MyCom.h" #include "../ICoder.h" #include "BitlEncoder.h" #include "DeflateConst.h" namespace NCompress { namespace NDeflate { namespace NEncoder { struct CCodeValue { UInt16 Len; UInt16 Pos; void SetAsLiteral() { Len = (1 << 15); } bool IsLiteral() const { return (Len >= (1 << 15)); } }; struct COptimal { UInt32 Price; UInt16 PosPrev; UInt16 BackPrev; }; const UInt32 kNumOptsBase = 1 << 12; const UInt32 kNumOpts = kNumOptsBase + kMatchMaxLen; class CCoder; struct CTables: public CLevels { bool UseSubBlocks; bool StoreMode; bool StaticMode; UInt32 BlockSizeRes; UInt32 m_Pos; void InitStructures(); }; typedef struct _CSeqInStream { ISeqInStream SeqInStream; CMyComPtr RealStream; } CSeqInStream; class CCoder { CMatchFinder _lzInWindow; CBitlEncoder m_OutStream; CSeqInStream _seqInStream; public: CCodeValue *m_Values; UInt16 *m_MatchDistances; UInt32 m_NumFastBytes; bool _fastMode; bool _btMode; UInt16 *m_OnePosMatchesMemory; UInt16 *m_DistanceMemory; UInt32 m_Pos; int m_NumPasses; int m_NumDivPasses; bool m_CheckStatic; bool m_IsMultiPass; UInt32 m_ValueBlockSize; UInt32 m_NumLenCombinations; UInt32 m_MatchMaxLen; const Byte *m_LenStart; const Byte *m_LenDirectBits; bool m_Created; bool m_Deflate64Mode; Byte m_LevelLevels[kLevelTableSize]; int m_NumLitLenLevels; int m_NumDistLevels; UInt32 m_NumLevelCodes; UInt32 m_ValueIndex; bool m_SecondPass; UInt32 m_AdditionalOffset; UInt32 m_OptimumEndIndex; UInt32 m_OptimumCurrentIndex; Byte m_LiteralPrices[256]; Byte m_LenPrices[kNumLenSymbolsMax]; Byte m_PosPrices[kDistTableSize64]; CLevels m_NewLevels; UInt32 mainFreqs[kFixedMainTableSize]; UInt32 distFreqs[kDistTableSize64]; UInt32 mainCodes[kFixedMainTableSize]; UInt32 distCodes[kDistTableSize64]; UInt32 levelCodes[kLevelTableSize]; Byte levelLens[kLevelTableSize]; UInt32 BlockSizeRes; CTables *m_Tables; COptimal m_Optimum[kNumOpts]; UInt32 m_MatchFinderCycles; // IMatchFinderSetNumPasses *m_SetMfPasses; void GetMatches(); void MovePos(UInt32 num); UInt32 Backward(UInt32 &backRes, UInt32 cur); UInt32 GetOptimal(UInt32 &backRes); UInt32 GetOptimalFast(UInt32 &backRes); void LevelTableDummy(const Byte *levels, int numLevels, UInt32 *freqs); void WriteBits(UInt32 value, int numBits); void LevelTableCode(const Byte *levels, int numLevels, const Byte *lens, const UInt32 *codes); void MakeTables(unsigned maxHuffLen); UInt32 GetLzBlockPrice() const; void TryBlock(); UInt32 TryDynBlock(int tableIndex, UInt32 numPasses); UInt32 TryFixedBlock(int tableIndex); void SetPrices(const CLevels &levels); void WriteBlock(); HRESULT Create(); void Free(); void WriteStoreBlock(UInt32 blockSize, UInt32 additionalOffset, bool finalBlock); void WriteTables(bool writeMode, bool finalBlock); void WriteBlockData(bool writeMode, bool finalBlock); void ReleaseStreams() { _seqInStream.RealStream.Release(); m_OutStream.ReleaseStream(); } class CCoderReleaser { CCoder *m_Coder; public: CCoderReleaser(CCoder *coder): m_Coder(coder) {} ~CCoderReleaser() { m_Coder->ReleaseStreams(); } }; friend class CCoderReleaser; UInt32 GetBlockPrice(int tableIndex, int numDivPasses); void CodeBlock(int tableIndex, bool finalBlock); public: CCoder(bool deflate64Mode = false); ~CCoder(); HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); HRESULT BaseCode(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); HRESULT BaseSetEncoderProperties2(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); }; class CCOMCoder : public ICompressCoder, public ICompressSetCoderProperties, public CMyUnknownImp, public CCoder { public: MY_UNKNOWN_IMP1(ICompressSetCoderProperties) CCOMCoder(): CCoder(false) {}; STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); }; class CCOMCoder64 : public ICompressCoder, public ICompressSetCoderProperties, public CMyUnknownImp, public CCoder { public: MY_UNKNOWN_IMP1(ICompressSetCoderProperties) CCOMCoder64(): CCoder(true) {}; STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); }; }}} #endif