blob: 71c39e4e52d309cc7b59d3841cf2a4928ddc2afc [file] [log] [blame]
// 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<ISequentialInStream> 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