diff options
Diffstat (limited to 'src/huffman/huff.h')
-rw-r--r-- | src/huffman/huff.h | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/src/huffman/huff.h b/src/huffman/huff.h new file mode 100644 index 0000000..b0a54ee --- /dev/null +++ b/src/huffman/huff.h @@ -0,0 +1,143 @@ +/*****************************************************************************/ +/* huffman.h Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Description : */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* xx.xx.xx 1.00 Lad The first version of huffman.h */ +/* 03.05.03 2.00 Lad Added compression */ +/* 08.12.03 2.01 Dan High-memory handling (> 0x80000000) */ +/*****************************************************************************/ + +#ifndef __HUFFMAN_H__ +#define __HUFFMAN_H__ + +//----------------------------------------------------------------------------- +// Defines + +#define HUFF_ITEM_COUNT 0x203 // Number of items in the item pool +#define LINK_ITEM_COUNT 0x80 // Maximum number of quick-link items + +//----------------------------------------------------------------------------- +// Structures and classes + +// Input stream for Huffmann decompression +class TInputStream +{ + public: + + TInputStream(void * pvInBuffer, size_t cbInBuffer); + unsigned int Get1Bit(); + unsigned int Peek7Bits(); + unsigned int Get8Bits(); + void SkipBits(unsigned int BitCount); + + unsigned char * pbInBufferEnd; // End position in the the input buffer + unsigned char * pbInBuffer; // Current position in the the input buffer + unsigned int BitBuffer; // Input bit buffer + unsigned int BitCount; // Number of bits remaining in 'dwBitBuff' +}; + + +// Output stream for Huffmann compression +class TOutputStream +{ + public: + + TOutputStream(void * pvOutBuffer, size_t cbOutLength); + void PutBits(unsigned int dwValue, unsigned int nBitCount); + void Flush(); + + unsigned char * pbOutBufferEnd; // End position in the output buffer + unsigned char * pbOutBuffer; // Current position in the output buffer + unsigned int BitBuffer; // Bit buffer + unsigned int BitCount; // Number of bits in the bit buffer +}; + +// A virtual tree item that represents the head of the item list +#define LIST_HEAD() ((THTreeItem *)(&pFirst)) + +enum TInsertPoint +{ + InsertAfter = 1, + InsertBefore = 2 +}; + +// Huffmann tree item +struct THTreeItem +{ + THTreeItem() { pPrev = pNext = NULL;} +// ~THTreeItem() { RemoveItem(); } + + void RemoveItem(); +// void RemoveEntry(); + + THTreeItem * pNext; // Pointer to lower-weight tree item + THTreeItem * pPrev; // Pointer to higher-weight item + unsigned int DecompressedValue; // 08 - Decompressed byte value (also index in the array) + unsigned int Weight; // 0C - Weight + THTreeItem * pParent; // 10 - Pointer to parent item (NULL if none) + THTreeItem * pChildLo; // 14 - Pointer to the child with lower-weight child ("left child") +}; + + +// Structure used for quick navigating in the huffmann tree. +// Allows skipping up to 7 bits in the compressed stream, thus +// decompressing a bit faster. Sometimes it can even get the decompressed +// byte directly. +struct TQuickLink +{ + unsigned int ValidValue; // If greater than THuffmannTree::MinValidValue, the entry is valid + unsigned int ValidBits; // Number of bits that are valid for this item link + union + { + THTreeItem * pItem; // Pointer to the item within the Huffmann tree + unsigned int DecompressedValue; // Value for direct decompression + }; +}; + + +// Structure for Huffman tree (Size 0x3674 bytes). Because I'm not expert +// for the decompression, I do not know actually if the class is really a Hufmann +// tree. If someone knows the decompression details, please let me know +class THuffmannTree +{ + public: + + THuffmannTree(bool bCompression); + ~THuffmannTree(); + + void LinkTwoItems(THTreeItem * pItem1, THTreeItem * pItem2); + void InsertItem(THTreeItem * item, TInsertPoint InsertPoint, THTreeItem * item2); + + THTreeItem * FindHigherOrEqualItem(THTreeItem * pItem, unsigned int Weight); + THTreeItem * CreateNewItem(unsigned int DecompressedValue, unsigned int Weight, TInsertPoint InsertPoint); + + unsigned int FixupItemPosByWeight(THTreeItem * pItem, unsigned int MaxWeight); + void BuildTree(unsigned int CompressionType); + + void IncWeightsAndRebalance(THTreeItem * pItem); + void InsertNewBranchAndRebalance(unsigned int Value1, unsigned int Value2); + + void EncodeOneByte(TOutputStream * os, THTreeItem * pItem); + unsigned int DecodeOneByte(TInputStream * is); + + unsigned int Compress(TOutputStream * os, void * pvInBuffer, int cbInBuffer, int nCmpType); + unsigned int Decompress(void * pvOutBuffer, unsigned int cbOutLength, TInputStream * is); + + THTreeItem ItemBuffer[HUFF_ITEM_COUNT]; // Buffer for tree items. No memory allocation is needed + unsigned int ItemsUsed; // Number of tree items used from ItemBuffer + + // Head of the linear item list + THTreeItem * pFirst; // Pointer to the highest weight item + THTreeItem * pLast; // Pointer to the lowest weight item + + THTreeItem * ItemsByByte[0x102]; // Array of item pointers, one for each possible byte value + TQuickLink QuickLinks[LINK_ITEM_COUNT]; // Array of quick-link items + + unsigned int MinValidValue; // A minimum value of TQDecompress::ValidValue to be considered valid + unsigned int bIsCmp0; // 1 if compression type 0 +}; + +#endif // __HUFFMAN_H__ |