p7zip/CPP/7zip/Compress/DeflateEncoder.h
2017-10-11 12:35:36 +02:00

217 lines
4.9 KiB
C++

// 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;
ISequentialInStream *RealStream;
} CSeqInStream;
struct CEncProps
{
int Level;
int algo;
int fb;
int btMode;
UInt32 mc;
UInt32 numPasses;
CEncProps()
{
Level = -1;
mc = 0;
algo = fb = btMode = -1;
numPasses = (UInt32)(Int32)-1;
}
void Normalize();
};
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;
unsigned m_NumPasses;
unsigned 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];
unsigned m_NumLitLenLevels;
unsigned 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;
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, unsigned numLevels, UInt32 *freqs);
void WriteBits(UInt32 value, unsigned numBits);
void LevelTableCode(const Byte *levels, unsigned numLevels, const Byte *lens, const UInt32 *codes);
void MakeTables(unsigned maxHuffLen);
UInt32 GetLzBlockPrice() const;
void TryBlock();
UInt32 TryDynBlock(unsigned tableIndex, UInt32 numPasses);
UInt32 TryFixedBlock(unsigned 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);
UInt32 GetBlockPrice(unsigned tableIndex, unsigned numDivPasses);
void CodeBlock(unsigned tableIndex, bool finalBlock);
void SetProps(const CEncProps *props2);
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_IMP2(ICompressCoder, 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_IMP2(ICompressCoder, 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