00001 #ifndef CRYPTOPP_ZDEFLATE_H
00002 #define CRYPTOPP_ZDEFLATE_H
00003
00004 #include "cryptlib.h"
00005 #include "filters.h"
00006 #include "misc.h"
00007
00008 NAMESPACE_BEGIN(CryptoPP)
00009
00010
00011 class LowFirstBitWriter : public Filter
00012 {
00013 public:
00014 LowFirstBitWriter(BufferedTransformation *attachment);
00015 void PutBits(unsigned long value, unsigned int length);
00016 void FlushBitBuffer();
00017 void ClearBitBuffer();
00018
00019 void StartCounting();
00020 unsigned long FinishCounting();
00021
00022 protected:
00023 bool m_counting;
00024 unsigned long m_bitCount;
00025 unsigned long m_buffer;
00026 unsigned int m_bitsBuffered, m_bytesBuffered;
00027 FixedSizeSecBlock<byte, 256> m_outputBuffer;
00028 };
00029
00030
00031 class HuffmanEncoder
00032 {
00033 public:
00034 typedef unsigned int code_t;
00035 typedef unsigned int value_t;
00036
00037
00038 HuffmanEncoder() {}
00039
00040
00041
00042
00043 HuffmanEncoder(const unsigned int *codeBits, unsigned int nCodes);
00044
00045
00046
00047
00048 void Initialize(const unsigned int *codeBits, unsigned int nCodes);
00049
00050 static void GenerateCodeLengths(unsigned int *codeBits, unsigned int maxCodeBits, const unsigned int *codeCounts, size_t nCodes);
00051
00052 void Encode(LowFirstBitWriter &writer, value_t value) const;
00053
00054 struct Code
00055 {
00056 unsigned int code;
00057 unsigned int len;
00058 };
00059
00060 SecBlock<Code> m_valueToCode;
00061 };
00062
00063
00064
00065 class Deflator : public LowFirstBitWriter
00066 {
00067 public:
00068 enum {MIN_DEFLATE_LEVEL = 0, DEFAULT_DEFLATE_LEVEL = 6, MAX_DEFLATE_LEVEL = 9};
00069 enum {MIN_LOG2_WINDOW_SIZE = 9, DEFAULT_LOG2_WINDOW_SIZE = 15, MAX_LOG2_WINDOW_SIZE = 15};
00070
00071
00072
00073 Deflator(BufferedTransformation *attachment=NULL, int deflateLevel=DEFAULT_DEFLATE_LEVEL, int log2WindowSize=DEFAULT_LOG2_WINDOW_SIZE, bool detectUncompressible=true);
00074
00075 Deflator(const NameValuePairs ¶meters, BufferedTransformation *attachment=NULL);
00076
00077
00078 void SetDeflateLevel(int deflateLevel);
00079 int GetDeflateLevel() const {return m_deflateLevel;}
00080 int GetLog2WindowSize() const {return m_log2WindowSize;}
00081
00082 void IsolatedInitialize(const NameValuePairs ¶meters);
00083 size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
00084 bool IsolatedFlush(bool hardFlush, bool blocking);
00085
00086 protected:
00087 virtual void WritePrestreamHeader() {}
00088 virtual void ProcessUncompressedData(const byte *string, size_t length)
00089 {CRYPTOPP_UNUSED(string), CRYPTOPP_UNUSED(length);}
00090 virtual void WritePoststreamTail() {}
00091
00092 enum {STORED = 0, STATIC = 1, DYNAMIC = 2};
00093 enum {MIN_MATCH = 3, MAX_MATCH = 258};
00094
00095 void InitializeStaticEncoders();
00096 void Reset(bool forceReset = false);
00097 unsigned int FillWindow(const byte *str, size_t length);
00098 unsigned int ComputeHash(const byte *str) const;
00099 unsigned int LongestMatch(unsigned int &bestMatch) const;
00100 void InsertString(unsigned int start);
00101 void ProcessBuffer();
00102
00103 void LiteralByte(byte b);
00104 void MatchFound(unsigned int distance, unsigned int length);
00105 void EncodeBlock(bool eof, unsigned int blockType);
00106 void EndBlock(bool eof);
00107
00108 struct EncodedMatch
00109 {
00110 unsigned literalCode : 9;
00111 unsigned literalExtra : 5;
00112 unsigned distanceCode : 5;
00113 unsigned distanceExtra : 13;
00114 };
00115
00116 int m_deflateLevel, m_log2WindowSize, m_compressibleDeflateLevel;
00117 unsigned int m_detectSkip, m_detectCount;
00118 unsigned int DSIZE, DMASK, HSIZE, HMASK, GOOD_MATCH, MAX_LAZYLENGTH, MAX_CHAIN_LENGTH;
00119 bool m_headerWritten, m_matchAvailable;
00120 unsigned int m_dictionaryEnd, m_stringStart, m_lookahead, m_minLookahead, m_previousMatch, m_previousLength;
00121 HuffmanEncoder m_staticLiteralEncoder, m_staticDistanceEncoder, m_dynamicLiteralEncoder, m_dynamicDistanceEncoder;
00122 SecByteBlock m_byteBuffer;
00123 SecBlock<word16> m_head, m_prev;
00124 FixedSizeSecBlock<unsigned int, 286> m_literalCounts;
00125 FixedSizeSecBlock<unsigned int, 30> m_distanceCounts;
00126 SecBlock<EncodedMatch> m_matchBuffer;
00127 unsigned int m_matchBufferEnd, m_blockStart, m_blockLength;
00128 };
00129
00130 NAMESPACE_END
00131
00132 #endif