Octane v1.01.20 - The Open Compression Toolkit for C++ http://octane.sourceforge.net/
Homepage | Main | Modules | Class Hierarchy | Compound List | File List | Compound Members | Related Pages

coders/coder_huffman/huffmannodes.hpp

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 //---------------------------------------------------------------------------
00015 
00016 //---------------------------------------------------------------------------
00017 // recursive header protection
00018 #ifndef Coder_HuffmanNodesH
00019 #define Coder_HuffmanNodesH
00020 //---------------------------------------------------------------------------
00021 
00022 
00023 //---------------------------------------------------------------------------
00024 // application includes
00025 #include "../../bitio/bitio.hpp"
00026 // system includes
00027 #include <string>
00028 #include <iostream>
00029 #include <iomanip>
00030 #include <vector>
00031 #include <queue>
00032 #include <set>
00033 #include <bitset>
00034 using namespace std;
00035 //---------------------------------------------------------------------------
00036 
00037 
00038 //---------------------------------------------------------------------------
00039 // forward declarations
00040 class HuffNode;
00041 class HuffNode_Middle;
00042 class HuffNode_Leaf;
00043 //---------------------------------------------------------------------------
00044 
00045 
00046 //---------------------------------------------------------------------------
00047 // jibz modified huffman pq weight comparisn,
00048 #define OCTANE_USEJIBZHUFFMANPQGREATER
00049 // <mouser> so if left is a leaf and right is not a leaf, then you treat right as if it has lower weight
00050 // <mouser> (on ties)
00051 // <Jibz> yes .. that was what I was going for .. making internal nodes seem slightly smaller than leafs with the same weight
00052 // <mouser> now why is this good?
00053 // <Jibz> I don't know .. it may even be bad ;)
00054 // <mouser> hehehehe
00055 // <Jibz> but it seems like it might be better to make a choice, than to pick at random (or whatever the pq gives you)
00056 // COMPARISON SHOWS -> no perceivable difference.
00057 //--------------------------------------------------------------------------- 
00058 
00059 
00060 
00061 //---------------------------------------------------------------------------
00062 // TypeDefs and Defines
00063 //
00064 // what kind of precision should we use for the weights?
00065 //  note that because of the way trees are built, this values needs to store
00066 //  the SUM of all weights in the tree, not just the maximum frequency of
00067 //  any leaf(!).
00068 
00069 // We could use a typedef here but it can cause warnings on type conversions
00070 // //typedef unsigned long THuffmanNodeWeight;
00071 // #define THuffmanNodeWeight unsigned long
00072 // #define THuffmanNodeWeight_MAX       ULONGMAX
00073 // typedef unsigned long THuffmanNodeWeight;
00074 
00076 #define THuffmanNodeWeight float
00077 
00078 #define THuffmanNodeWeight_MAX  FLOATMAX
00079 
00091 #define DEF_HUFFMANPQ_MAXIMUM_CODEBITDEPTH      160
00092 
00096 #define DEF_HUFFMANPQ_MAXFUNCBITS 200
00097 //---------------------------------------------------------------------------
00098 
00099 
00100 
00101 
00102 
00103 
00104 //---------------------------------------------------------------------------
00110 class HuffNode {
00111 protected:
00113         THuffmanNodeWeight weight;
00114 public:
00116         HuffNode() { ; }
00118         virtual ~HuffNode() { ; }
00119 public:
00121         bool operator>( const HuffNode* &a ) const {return weight > (a->get_weight());}
00122 public:
00124         virtual void traverse_buildbitcodes(std::bitset<DEF_HUFFMANPQ_MAXFUNCBITS> &current_bitset, int bitsetlength);
00125 public:
00127         virtual void recursive_freechildren() { ; }
00128 public:
00130         THuffmanNodeWeight get_weight() const {return weight;}
00132         void increment_weight(int increment) {weight+=increment;}
00134         void set_weight(THuffmanNodeWeight val) {weight=val;}
00136         virtual unsigned int get_memoryused() const {return sizeof(this);}
00138         virtual HuffNode *get_child0() {return 0;}
00140         virtual HuffNode *get_child1() {return 0;}
00141 public:
00143         virtual bool isleaf() {return false;}
00144 };
00145 //---------------------------------------------------------------------------
00146 
00147 
00148 //---------------------------------------------------------------------------
00151 class HuffNode_Middle : public HuffNode {
00152 protected:
00154         HuffNode *child0;
00156         HuffNode *child1;
00157 public:
00159         HuffNode_Middle(HuffNode* c0, HuffNode *c1 ) {weight=c0->get_weight()+c1->get_weight(); child0=c0; child1=c1;}
00162         virtual ~HuffNode_Middle() { ; }
00163 public:
00164         void recursive_freechildren() {child0->recursive_freechildren(); delete child0; child1->recursive_freechildren(); delete child1;}
00165 public:
00166         virtual void traverse_buildbitcodes(std::bitset<DEF_HUFFMANPQ_MAXFUNCBITS> &current_bitset, int bitsetlength);
00167 public:
00168         virtual unsigned int get_memoryused() const {return sizeof(this)+(child0->get_memoryused())+(child1->get_memoryused());}
00169         virtual HuffNode *get_child0() {return child0;}
00170         virtual HuffNode *get_child1() {return child1;}
00171 public:
00172         bool isleaf() {return false;}
00173 };
00174 //---------------------------------------------------------------------------
00175 
00176 
00177 //---------------------------------------------------------------------------
00183 class HuffNode_Leaf : public HuffNode {
00184 protected:
00185         // length of the bitcode for this symbol
00186         unsigned char code_bitsetlength;
00188         std::bitset<DEF_HUFFMANPQ_MAXIMUM_CODEBITDEPTH> code_bitset;
00190         int symbolid;
00191 public:
00193         HuffNode_Leaf(int insymbolid, THuffmanNodeWeight inweight) {symbolid=insymbolid; weight=inweight;}
00195         virtual ~HuffNode_Leaf() { ; }
00196 public:
00197         void recursive_freechildren() { ; }
00198 public:
00199         virtual void traverse_buildbitcodes(std::bitset<DEF_HUFFMANPQ_MAXFUNCBITS> &current_bitset, int bitsetlength);
00200 public:
00202         int get_symbolid() {return symbolid;}
00204         void set_symbolid(int val) {symbolid=val;}
00206         unsigned char get_bitcode_length() {return code_bitsetlength;};
00208         std::string get_bitcode_string();
00209 public:
00212         virtual unsigned int get_memoryused() const {return (unsigned int)(sizeof(this)+sizeof(code_bitset));}
00213 public:
00214         virtual bool isleaf() {return true;}
00215 public:
00217         virtual bool AddBitsToBitWriter(bitwriter &bw);
00218 };
00219 //---------------------------------------------------------------------------
00220 
00221 
00222 //---------------------------------------------------------------------------
00226 
00227 template< class T >
00228 class PQWeightGreater
00229 {
00230     public:
00231         bool operator() (const T& pLeft, const T& pRight) const
00232         {
00233         #ifdef OCTANE_USEJIBZHUFFMANPQGREATER
00234                 if (pLeft->get_weight()==pRight->get_weight()) return (pLeft->isleaf() && !pRight->isleaf());
00235                 //if (pLeft->get_weight()==pRight->get_weight()) return (!pLeft->isleaf() && pRight->isleaf());
00236         #endif
00237         return pLeft->get_weight()>pRight->get_weight();
00238         }
00239 };
00240 //---------------------------------------------------------------------------
00241 
00242 
00243 //---------------------------------------------------------------------------
00244 // typedef for priority queue of HuffNodes, which we use in huffman coding and in DictionarySet
00245 typedef std::priority_queue< HuffNode*, std::vector< HuffNode* >, PQWeightGreater<HuffNode*> > THuffmanNodePriorityQueue;
00246 //---------------------------------------------------------------------------
00247 
00248 
00249 
00250 
00251 
00252 
00253 //---------------------------------------------------------------------------
00254 #endif
00255 //---------------------------------------------------------------------------
00256 
00257 
 
Generated on 20 May 2004 by doxygen 1.3.3