00001
00008 #ifndef HUFFMANCODER_H_
00009 #define HUFFMANCODER_H_
00010
00011 #include <itpp/base/vec.h>
00012 #include <itpp/base/array.h>
00013
00014 namespace itpp {
00015
00021 class HuffmanCoder {
00022 public:
00023
00027 HuffmanCoder() : initialized(false),trained(false) {}
00028
00033 HuffmanCoder(unsigned int H0) { setRawRate(H0); }
00034
00039 HuffmanCoder(unsigned int H0,const itpp::Vec<unsigned int> &trainingdata) { setRawRate(H0); train(trainingdata); }
00040
00044 virtual ~HuffmanCoder() {}
00045
00052 inline void setRawRate(unsigned int H0);
00059 inline itpp::bvec code(unsigned int symbol);
00060
00066 inline itpp::bvec code(itpp::Vec<unsigned int> symbols);
00067
00068
00074 itpp::Vec<unsigned int> decode(itpp::bvec coded);
00075
00081 double train(const Vec<unsigned int> &trainingdata);
00082
00087 bool isTrained() const { return trained; }
00088
00093 bool isInitialized() const { return initialized; }
00094
00099 unsigned int getN() const { return N; }
00100
00105 unsigned int getH0() const { return H0; }
00106
00112 const itpp::Array<itpp::bvec> &getCodeTable() const { return codetable; }
00113
00119 const itpp::Vec<unsigned int> &getDecodeTable() const { return decodetable; }
00120
00121 protected:
00122 bool initialized;
00123 bool trained;
00124 unsigned int N;
00125 unsigned int H0;
00126 itpp::Array<itpp::bvec> codetable;
00127 itpp::Vec<unsigned int> decodetable;
00129 private:
00133 class sort_elem{
00134 public:
00138 sort_elem() { rel_h = 0; }
00139
00143 ~sort_elem() {}
00144
00149 void setSymbol(unsigned int symbol) { this->symbol=symbol; }
00150
00155 unsigned int getSymbol() const { return symbol; }
00156
00161 unsigned int getFrequency() const { return rel_h; }
00162
00166 void operator++() { rel_h++; }
00167
00171 friend bool operator<(const HuffmanCoder::sort_elem &a,const HuffmanCoder::sort_elem &b) { return (a.rel_h < b.rel_h); }
00172
00176 friend bool operator<=(const HuffmanCoder::sort_elem &a,const HuffmanCoder::sort_elem &b) { return (a.rel_h <= b.rel_h); }
00177
00181 friend bool operator>(const HuffmanCoder::sort_elem &a,const HuffmanCoder::sort_elem &b) { return (a.rel_h > b.rel_h); }
00182
00186 friend bool operator>=(const HuffmanCoder::sort_elem &a,const HuffmanCoder::sort_elem &b) { return (a.rel_h >= b.rel_h); }
00187
00191 friend bool operator==(const HuffmanCoder::sort_elem &a,const HuffmanCoder::sort_elem &b) { return (a.rel_h == b.rel_h); }
00192
00196 friend bool operator!=(const HuffmanCoder::sort_elem &a,const HuffmanCoder::sort_elem &b) { return (a.rel_h != b.rel_h); }
00197
00198 protected:
00199 unsigned int symbol;
00200 unsigned int rel_h;
00201 };
00202 };
00203
00204 itpp::bvec HuffmanCoder::code(unsigned int symbol)
00205 {
00206 #ifdef DEBUG
00207 if(!initialized) cerr << "HuffmanCoder::code() called on an uninitialized object!" << endl;
00208 if(!initialized) cerr << "HuffmanCoder::code() called on an untrained object!" << endl;
00209 if(symbol >= N) cerr << "HuffmanCoder::code(symbol): symbol value " << symbol << "out of range [0.." << N-1 << "]!" << endl;
00210 #endif
00211 return codetable(symbol);
00212 }
00213
00214 itpp::bvec HuffmanCoder::code(itpp::Vec<unsigned int> symbols)
00215 {
00216 itpp::bvec output;
00217 for(int k=0;k<symbols.length();k++) output=concat(output,code(symbols(k)));
00218 return output;
00219 }
00220 }
00221
00222 void itpp::HuffmanCoder::setRawRate(unsigned int H0)
00223 {
00224 this->H0=H0;
00225 N=1<<H0;
00226 codetable.set_size(N,false);
00227 decodetable.set_size(N,false);
00228 trained=false;
00229 initialized=true;
00230 }
00231
00232 #endif
00233