Deflater.h
资源名称:DXGuide.zip [点击查看]
上传用户:wymy58
上传日期:2007-01-07
资源大小:2086k
文件大小:15k
源码类别:
DirextX编程
开发平台:
Visual C++
- // Form zlib 1.1.3, Copyright (C) 1995-1998 Jean-loup Gailly
- // Copyright (C) 1999 DXGuide. All Rights Reserved.
- // File: Deflater.h
- #ifndef _DEFLATER__H
- #define _DEFLATER__H
- #if _MSC_VER >= 1000
- #pragma once
- #endif // _MSC_VER >= 1000
- //#define FASTEST
- //#define GEN_TREES_H
- //#define ASMV
- //#define UNALIGNED_OK
- //#define DUMP_BL_TREE
- //#define !!FORCE_STORED!!
- //#define FORCE_STATIC
- //#define TRUNCATE_BLOCK
- //#define USE_DICT_HEAD
- #include "Zlib113.h"
- #include "Checksum.h"
- // compression levels
- enum CompressLevel
- {
- COMPRESSLEVEL_0,
- COMPRESSLEVEL_1,
- COMPRESSLEVEL_2,
- COMPRESSLEVEL_3,
- COMPRESSLEVEL_4,
- COMPRESSLEVEL_5,
- COMPRESSLEVEL_6,
- COMPRESSLEVEL_7,
- COMPRESSLEVEL_8,
- COMPRESSLEVEL_9,
- COMPRESSLEVEL_NUM,
- COMPRESSLEVEL_NO_COMPRESSION = COMPRESSLEVEL_0,
- // Compression level for fastest compression.
- COMPRESSLEVEL_BEST_SPEED = COMPRESSLEVEL_1,
- // Compression level for best compression.
- COMPRESSLEVEL_BEST_COMPRESSION = COMPRESSLEVEL_NUM - 1,
- // Default compression level.
- COMPRESSLEVEL_DEFAULT_COMPRESSION = COMPRESSLEVEL_6,
- };
- // compression strategy; see Init() below for details
- enum CompressStrategy
- {
- STRATEGY_DEFAULT = 0,
- STRATEGY_FILTERED = 1,
- STRATEGY_HUFFMAN_ONLY = 2,
- };
- // Maximum value for memLevel in Init()
- #ifndef MAX_MEM_LEVEL
- #define MAX_MEM_LEVEL 9
- #endif
- // default memLevel
- #if MAX_MEM_LEVEL >= 8
- #define DEF_MEM_LEVEL 8
- #else
- #define DEF_MEM_LEVEL MAX_MEM_LEVEL
- #endif
- // A Pos is an index in the character window. We use
- // short instead of int to save space in the various tables.
- // IPos is used only for parameter passing.
- typedef WORD Pos;
- typedef UINT IPos;
- // number of length codes, not counting the special END_BLOCK code
- #define LENGTH_CODES 29
- // number of literal bytes 0..255
- #define LITERALS 256
- // number of Literal or Length codes, including the END_BLOCK code
- #define L_CODES (LITERALS + 1 + LENGTH_CODES)
- // number of distance codes
- #define D_CODES 30
- // number of codes used to transfer the bit lengths
- #define BL_CODES 19
- // maximum heap size
- #define LCODES_HEAP_SIZE (2 * L_CODES + 1)
- // All codes must not exceed MAX_BITS bits
- #define MAX_BITS 15
- // The minimum and maximum match lengths
- #define MIN_MATCH 3
- #define MAX_MATCH 258 // 255 + MIN_MATCH ?
- // Minimum amount of m_uLookAhead, except at the end of the
- // input file.
- // See Deflate.cpp for comments about the MIN_MATCH + 1.
- #define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
- // Data structure describing a single value and its code string.
- struct ct_data
- {
- union
- {
- WORD m_wFreq; // frequency count
- WORD m_wCode; // bit string
- };
- union
- {
- WORD m_wDad; // father node in Huffman tree
- WORD m_wLen; // length of bit string
- };
- };
- class CDeflater
- {
- protected:
- // The three kinds of block type
- enum BlockType
- {
- STORED_BLOCK = 0,
- STATIC_TREES = 1,
- DYN_TREES = 2
- };
- // Function prototypes.
- enum BlockState
- {
- BLOCKSTATE_NEEDMORE, // block not completed, need more input or more output
- BLOCKSTATE_BLOCKDONE, // block flush performed
- BLOCKSTATE_FINISHSTARTED, // finish started, need only more output at next deflate
- BLOCKSTATE_FINISHDONE // finish done, accept no more input or output
- };
- // Stream status
- enum StreamStatus
- {
- STREAMSTATE_INIT = 42,
- STREAMSTATE_BUSY = 113,
- STREAMSTATE_FINISH = 666,
- };
- #ifdef _DEBUG
- // Possible values of the m_DataType field
- enum DataType
- {
- Z_BINARY = 0,
- Z_ASCII = 1,
- Z_UNKNOWN = 2
- };
- #endif // _DEBUG
- public:
- struct static_tree_desc
- {
- const ct_data* m_pStaticTree; // static tree or NULL
- const int* m_pExtraBits; // extra bits for each code or NULL
- int m_nExtraBaseIndex; // base index for m_pExtraBits
- int m_nElements; // max number of elements in the tree
- int m_nMaxBitLength; // max bit length for the codes
- };
- struct tree_desc
- {
- int m_nMaxCode; // largest code with non zero frequency
- ct_data* m_pDynamicTree; // the dynamic tree
- static_tree_desc* m_pStaticTreeDesc; // the corresponding static tree
- };
- // Compression function. Returns the block state after the call.
- typedef CDeflater::BlockState (CDeflater::*compress_func)(FlushValues flush);
- // Values for m_uMaxLazyMatch, m_uGoodMatchLength and m_uMaxChainLength,
- // depending on the desired pack level (0..9). The values
- // given below have been tuned to exclude worst case
- // performance for pathological files. Better values may be
- // found for specific files.
- struct config
- {
- WORD m_uGoodMatchLength; // reduce lazy search above this match length
- WORD m_uMaxLazyMatch; // do not perform lazy search above this match length
- WORD m_uNiceMatchLength; // quit search above this match length
- WORD m_uMaxChainLength;
- compress_func func;
- };
- public:
- CDeflater(void);
- ~CDeflater();
- public:
- ZRetVal Deflate(FlushValues flush);
- // Advanced functions
- public:
- ZRetVal Init(
- CompressLevel compressLevel = COMPRESSLEVEL_DEFAULT_COMPRESSION,
- CompressStrategy strategy = STRATEGY_DEFAULT,
- int nWindowBits = MAX_WBITS,
- int nMemLevel = DEF_MEM_LEVEL,
- CompressMethod compressMethod = Z_DEFLATED);
- ZRetVal DeflateSetDictionary(
- const BYTE* pDictionary, UINT uDictLength);
- ZRetVal DeflateCopy(CDeflater* source);
- ZRetVal DeflateEnd(void);
- ZRetVal DeflateReset(void);
- ZRetVal DeflateParams(CompressLevel compressLevel, CompressStrategy strategy);
- protected:
- BlockState DeflateStored(FlushValues flush);
- BlockState DeflateFast(FlushValues flush);
- BlockState DeflateSlow(FlushValues flush);
- void InitLongestMatchRoutines(void);
- void FlushPending(void);
- UINT ReadBuffer(BYTE* pBuf, UINT uSize);
- void FillWindow(void);
- protected:
- static UINT LongestMatch(CDeflater* s, IPos uCurMatchPos);
- #ifdef _DEBUG
- void CheckMatch(IPos uStartPos, IPos uMatchPos, int nLength);
- #endif // _DEBUG
- protected:
- void TreeInitTree(void);
- void TreeAlign(void);
- bool TreeTally(UINT uDist, UINT lc);
- void TreeFlushBlock(const BYTE* pBuf, DWORD dwStoredLen, bool bEof);
- void TreeStoredBlock(const BYTE* pBuf, DWORD dwStoredLen, bool bEof);
- void TreeInitBlock(void);
- void pqdownheap(ct_data* tree, int k);
- void pqremove(ct_data* pTree, int& top);
- void TreeGenBitLen(const tree_desc* desc);
- void TreeBuildTree(tree_desc* desc);
- void TreeSendBits(int nValue, // value to send
- int nLength); // number of bits
- void TreeSendCode(int c, const ct_data* pTree);
- void TreeScanTree(ct_data* tree, int nMaxCode);
- void TreeSendTree(ct_data* pTree, int nMaxCode);
- void TreeSendAllTrees(int nLCodes, int nDCodes, int nBLCodes);
- int TreeBuildBLTree(void);
- void TreeCompressBlock(const ct_data* pLitTree, const ct_data* pDistTree);
- void BitBufWindup(void);
- void bi_flush(void);
- void CopyBlock(const BYTE* pBuf, UINT uLen, bool bHeader);
- protected:
- UINT MAX_DIST(void);
- void UpdateHash(BYTE c);
- Pos InsertString(UINT uStrStart);
- void PutShortMSB(WORD w);
- void PutShortLSB(WORD w);
- BYTE GetDistCode(UINT uDist);
- void FlushBlock(bool bEof);
- bool TreeTallyLit(BYTE c);
- bool TreeTallyDist(WORD wDist, BYTE byteLen);
- protected:
- static const config configuration_table[COMPRESSLEVEL_NUM];
- public:
- const BYTE* m_pSourceBuf; // next input byte
- UINT m_uSourceBufLen; // number of bytes available at m_pSourceBuf
- BYTE* m_pDestBuf; // next output byte should be put there
- UINT m_uDestBufLen; // remaining free space at m_pDestBuf
- public:
- DWORD m_dwTotalInputBytes; // total nb of input bytes read so far
- DWORD m_dwTotalOutputBytes; // total nb of bytes output so far
- protected:
- LPCTSTR m_lpszMsg; // last error message, NULL if no error
- CChecksum m_checksum; // adler32 value of the uncompressed data
- protected:
- static BYTE _dist_code[];
- static BYTE _length_code[];
- #ifdef GEN_TREES_H
- static void TreeStaticInit(void);
- static void GenTreesHeader(void);
- #endif // GEN_TREES_H
- #ifdef _DEBUG
- protected:
- DataType m_DataType; // best guess about the data type: ascii or binary
- void SetDataType(void);
- #endif // _DEBUG
- public:
- DWORD GetTotalIn(void) const;
- DWORD GetTotalOut(void) const;
- DWORD GetAdler32(void) const;
- void SetInput(const void* pBuf, UINT uLen);
- bool NeedsInput(void) const;
- protected:
- StreamStatus m_streamStatus; // as the name implies
- BYTE* m_pPendingBuf; // output still pending
- DWORD m_dwPendingBufSize; // size of m_pPendingBuf
- BYTE* m_pPendingOutPos; // next pending byte to output to the stream
- UINT m_uPendingBytes; // nb of bytes in the pending buffer
- int m_noheader; // suppress zlib header and adler32
- BYTE m_byteMethod; // STORED (for zip only) or DEFLATED
- FlushValues m_lastFlush; // value of flush param for previous deflate call
- UINT m_uLZ77WindowSize; // LZ77 window size (32K by default)
- UINT m_uLZ77WindowBits; // log2(m_uLZ77WindowSize) (8..16)
- UINT m_uLZ77WindowMask; // m_uLZ77WindowSize - 1
- // Sliding window. Input bytes are read into the second
- // half of the window, and move to the first half later
- // to keep a dictionary of at least wSize bytes. With
- // this organization, matches are limited to a distance
- // of wSize-MAX_MATCH bytes, but this ensures that IO is
- // always performed with a length multiple of the block
- // size. Also, it limits the window size to 64K, which is
- // quite useful on MSDOS.
- // To do: use the user input buffer as sliding window.
- BYTE* m_pSlidingWindow;
- // Actual size of window: 2 * wSize, except when the user
- // input buffer is directly used as sliding window.
- DWORD m_dwWindowSize;
- #ifndef FASTEST
- // Link to older string with same hash index. To limit
- // the size of this array to 64K, this link is maintained
- // only for the last 32K strings. An index in this array
- // is thus a window index modulo 32K.
- Pos* m_pPrevStringPos;
- #endif // !FASTEST
- Pos* m_pHashChainsHeadPos; // Heads of the hash chains or NULL.
- UINT m_uInsHashIndex; // hash index of string to be inserted
- UINT m_uHashSize; // number of elements in hash table
- UINT m_uHashBits; // log2(m_uHashSize)
- // Number of bits by which m_uInsHashIndex must be
- // shifted at each input step. It must be such that after
- // MIN_MATCH steps, the oldest byte no longer takes part
- // in the hash key, that is:
- // m_uHashShift * MIN_MATCH >= m_uHashBits
- UINT m_uHashShift;
- // Window position at the beginning of the current output
- // block. Gets negative when the window is moved backwards.
- long m_lBlockStartPos;
- UINT m_uBestMatchLength; // length of best match
- IPos m_uPrevMatchPos; // previous match
- bool m_bMatchAvailable; // set if previous match exists
- UINT m_uStrStart; // start of string to insert
- UINT m_uMatchStart; // start of matching string
- UINT m_uLookAhead; // number of valid bytes ahead in window
- // Length of the best match at previous step. Matches
- // not greater than this are discarded. This is used in
- // the lazy match evaluation.
- UINT m_uPrevLength;
- // To speed up deflation, hash chains are never searched
- // beyond this length. A higher limit improves
- // compression ratio but degrades the speed.
- UINT m_uMaxChainLength;
- // Attempt to find a better match only when the current
- // match is strictly smaller than this value. This
- // mechanism is used only for compression levels >= 4.
- // Insert new strings in the hash table only if the match
- // length is not greater than this length. This saves
- // time but degrades compression. max_insert_length is
- // used only for compression levels <= 3.
- UINT m_uMaxLazyMatch; // max_insert_length
- CompressLevel m_compressLevel; // compression level (1..9)
- CompressStrategy m_strategy; // favor or force Huffman coding
- // Use a faster search when the previous match is longer than this
- UINT m_uGoodMatchLength;
- // Stop searching when current match exceeds this
- UINT m_uNiceMatchLength;
- ct_data m_aDynLiterTree[LCODES_HEAP_SIZE]; // literal and length tree
- ct_data m_aDynDistTree[2 * D_CODES + 1]; // distance tree
- ct_data m_aBLTree[2 * BL_CODES + 1]; // Huffman tree for bit lengths
- tree_desc m_literalTreeDesc; // desc. for literal tree
- tree_desc m_distanceTreeDesc; // desc. for distance tree
- tree_desc m_bitLenTreeDesc; // desc. for bit length tree
- // number of codes at each bit length for an optimal tree
- WORD m_awBLCount[MAX_BITS + 1];
- int m_aHuffmanHeap[LCODES_HEAP_SIZE]; // heap used to build the Huffman trees
- int m_nHeapLen; // number of elements in the heap
- int m_nHeapMaxFreq; // element of largest frequency
- // The sons of heap[n] are heap[2 * n] and heap[2 * n + 1].
- // heap[0] is not used. The same heap array is used to build all trees.
- // Depth of each subtree used as tie breaker for trees of
- // equal frequency
- BYTE m_abyteDepth[LCODES_HEAP_SIZE];
- // buffer for literals or lengths
- BYTE* m_pLitLenBuf;
- UINT m_uLitLenBufSize;
- /* Size of match buffer for literals/lengths. There are 4 reasons for
- * limiting m_uLitLenBufSize to 64K:
- * - frequencies can be kept in 16 bit counters
- * - if compression is not successful for the first block, all input
- * data is still in the window so we can still emit a stored block even
- * when input comes from standard input. (This can also be done for
- * all blocks if m_uLitLenBufSize is not greater than 32K.)
- * - if compression is not successful for a file smaller than 64K, we can
- * even emit a stored file instead of a stored block (saving 5 bytes).
- * This is applicable only for zip (not gzip or zlib).
- * - creating new Huffman trees less frequently may not provide fast
- * adaptation to changes in the input data statistics. (Take for
- * example a binary file with poorly compressible code followed by
- * a highly compressible string table.) Smaller buffer sizes give
- * fast adaptation but have of course the overhead of transmitting
- * trees more frequently.
- * - I can't count above 4
- */
- UINT m_uLastLitLenBufIndex; // running index in m_pLitLenBuf
- // Buffer for distances. To simplify the code,
- // m_pwDistBuf and m_pLitLenBuf have the same number of
- // elements. To use different lengths, an extra flag
- // array would be necessary.
- WORD* m_pwDistBuf;
- DWORD m_dwOptiTreesBitLen; // bit length of current block with optimal trees
- DWORD m_dwStaticTreesBitLen; // bit length of current block with static trees
- UINT m_uStringMatches; // number of string matches in current block
- int m_nLastEOBLen; // bit length of EOB code for last block
- #ifdef _DEBUG
- DWORD m_dwCompressedLen; // total bit length of compressed file mod 2^32
- DWORD m_dwCompressedBitsSent; // bit length of compressed data sent mod 2^32
- #endif // _DEBUG
- // Output buffer. bits are inserted starting at the
- // bottom (least significant bits).
- WORD m_wOutputBitBuf;
- // Number of valid bits in m_wOutputBitBuf. All bits
- // above the valid bit are always zero.
- int m_nValidBits;
- };
- #include "Deflater.inl"
- #endif // _DEFLATER__H