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