1#ifndef CRYPTOPP_ZDEFLATE_H 2#define CRYPTOPP_ZDEFLATE_H 3 4#include "filters.h" 5#include "misc.h" 6 7NAMESPACE_BEGIN(CryptoPP) 8 9//! _ 10class LowFirstBitWriter : public Filter 11{ 12public: 13 LowFirstBitWriter(BufferedTransformation *attachment); 14 void PutBits(unsigned long value, unsigned int length); 15 void FlushBitBuffer(); 16 void ClearBitBuffer(); 17 18 void StartCounting(); 19 unsigned long FinishCounting(); 20 21protected: 22 bool m_counting; 23 unsigned long m_bitCount; 24 unsigned long m_buffer; 25 unsigned int m_bitsBuffered, m_bytesBuffered; 26 FixedSizeSecBlock<byte, 256> m_outputBuffer; 27}; 28 29//! Huffman Encoder 30class HuffmanEncoder 31{ 32public: 33 typedef unsigned int code_t; 34 typedef unsigned int value_t; 35 36 HuffmanEncoder() {} 37 HuffmanEncoder(const unsigned int *codeBits, unsigned int nCodes); 38 void Initialize(const unsigned int *codeBits, unsigned int nCodes); 39 40 static void GenerateCodeLengths(unsigned int *codeBits, unsigned int maxCodeBits, const unsigned int *codeCounts, size_t nCodes); 41 42 void Encode(LowFirstBitWriter &writer, value_t value) const; 43 44 struct Code 45 { 46 unsigned int code; 47 unsigned int len; 48 }; 49 50 SecBlock<Code> m_valueToCode; 51}; 52 53//! DEFLATE (RFC 1951) compressor 54 55class Deflator : public LowFirstBitWriter 56{ 57public: 58 enum {MIN_DEFLATE_LEVEL = 0, DEFAULT_DEFLATE_LEVEL = 6, MAX_DEFLATE_LEVEL = 9}; 59 enum {MIN_LOG2_WINDOW_SIZE = 9, DEFAULT_LOG2_WINDOW_SIZE = 15, MAX_LOG2_WINDOW_SIZE = 15}; 60 /*! \note detectUncompressible makes it faster to process uncompressible files, but 61 if a file has both compressible and uncompressible parts, it may fail to compress some of the 62 compressible parts. */ 63 Deflator(BufferedTransformation *attachment=NULL, int deflateLevel=DEFAULT_DEFLATE_LEVEL, int log2WindowSize=DEFAULT_LOG2_WINDOW_SIZE, bool detectUncompressible=true); 64 //! possible parameter names: Log2WindowSize, DeflateLevel, DetectUncompressible 65 Deflator(const NameValuePairs ¶meters, BufferedTransformation *attachment=NULL); 66 67 //! this function can be used to set the deflate level in the middle of compression 68 void SetDeflateLevel(int deflateLevel); 69 int GetDeflateLevel() const {return m_deflateLevel;} 70 int GetLog2WindowSize() const {return m_log2WindowSize;} 71 72 void IsolatedInitialize(const NameValuePairs ¶meters); 73 size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); 74 bool IsolatedFlush(bool hardFlush, bool blocking); 75 76protected: 77 virtual void WritePrestreamHeader() {} 78 virtual void ProcessUncompressedData(const byte *string, size_t length) {} 79 virtual void WritePoststreamTail() {} 80 81 enum {STORED = 0, STATIC = 1, DYNAMIC = 2}; 82 enum {MIN_MATCH = 3, MAX_MATCH = 258}; 83 84 void InitializeStaticEncoders(); 85 void Reset(bool forceReset = false); 86 unsigned int FillWindow(const byte *str, size_t length); 87 unsigned int ComputeHash(const byte *str) const; 88 unsigned int LongestMatch(unsigned int &bestMatch) const; 89 void InsertString(unsigned int start); 90 void ProcessBuffer(); 91 92 void LiteralByte(byte b); 93 void MatchFound(unsigned int distance, unsigned int length); 94 void EncodeBlock(bool eof, unsigned int blockType); 95 void EndBlock(bool eof); 96 97 struct EncodedMatch 98 { 99 unsigned literalCode : 9; 100 unsigned literalExtra : 5; 101 unsigned distanceCode : 5; 102 unsigned distanceExtra : 13; 103 }; 104 105 int m_deflateLevel, m_log2WindowSize, m_compressibleDeflateLevel; 106 unsigned int m_detectSkip, m_detectCount; 107 unsigned int DSIZE, DMASK, HSIZE, HMASK, GOOD_MATCH, MAX_LAZYLENGTH, MAX_CHAIN_LENGTH; 108 bool m_headerWritten, m_matchAvailable; 109 unsigned int m_dictionaryEnd, m_stringStart, m_lookahead, m_minLookahead, m_previousMatch, m_previousLength; 110 HuffmanEncoder m_staticLiteralEncoder, m_staticDistanceEncoder, m_dynamicLiteralEncoder, m_dynamicDistanceEncoder; 111 SecByteBlock m_byteBuffer; 112 SecBlock<word16> m_head, m_prev; 113 FixedSizeSecBlock<unsigned int, 286> m_literalCounts; 114 FixedSizeSecBlock<unsigned int, 30> m_distanceCounts; 115 SecBlock<EncodedMatch> m_matchBuffer; 116 unsigned int m_matchBufferEnd, m_blockStart, m_blockLength; 117}; 118 119NAMESPACE_END 120 121#endif 122