Huffman编码压缩~
实在没动力写下去了,先存个档。 读档时间未定~ 一两天, 一两个月 , 或者一辈子。
Huffman.cpp
1 #include "stdafx.h" 2 #include "Huffman.h" 3 #include <iostream> 4 #include <math.h> 5 #include <queue> 6 #include <stack> 7 using namespace std; 8 9 10 HuffmanTree::HuffmanTree():m_root(NULL), m_nNode(0), m_nTotalNode(0) 11 { 12 memset(m_code, 0, sizeof(HuffmanCode) * 256); 13 } 14 15 HuffmanTree::~HuffmanTree() 16 { 17 if(m_root != NULL) 18 delete m_root; 19 DestoryTree(m_root); 20 } 21 22 Huffman_node* HuffmanTree::CreateNode(unsigned char value, int weight) 23 { 24 Huffman_node* p = new Huffman_node; 25 p->weight = weight; 26 p->value = value; 27 p->leftchild = NULL; 28 p->rightchild = NULL; 29 p->parent = NULL; 30 31 return p; 32 } 33 34 int HuffmanTree::DestoryTree(Huffman_node* root) 35 { 36 queue<Huffman_node*> qNode; 37 Huffman_node* temp; 38 39 qNode.push(root); 40 while(!qNode.empty()) 41 { 42 temp = qNode.front(); 43 qNode.pop(); 44 if(temp->leftchild != NULL) 45 qNode.push(temp->leftchild); 46 if(temp->rightchild != NULL) 47 qNode.push(temp->rightchild); 48 delete temp; 49 } 50 51 return true; 52 } 53 54 Huffman_node* HuffmanTree::MergeNode(Huffman_node* first, Huffman_node* sencond) 55 { 56 Huffman_node* root = CreateNode(0, first->weight + sencond->weight); 57 root->leftchild = first; 58 root->rightchild = sencond; 59 first->parent = root; 60 sencond->parent = root; 61 62 return root; 63 } 64 65 Huffman_node* HuffmanTree::BuildHuffmanTree(void* buf, int len) 66 { 67 long Table[256] = {0}; 68 int count; 69 Huffman_node* minimal[2]; 70 Huffman_node* temp; 71 priority_queue<Huffman_node*> nodelist; 72 73 for(int i = 0; i < len; i++) 74 { 75 Table[((unsigned char*)buf)[i]] += 1; 76 } 77 78 for(int i = 0; i < 256; i++) 79 { 80 if(Table[i] != 0) 81 { 82 temp = CreateNode(i, Table[i]); 83 nodelist.push(temp); 84 m_leaves.push_back(temp); 85 } 86 } 87 88 m_nNode = nodelist.size(); 89 m_nTotalNode = m_nNode * 2 - 1; 90 91 Huffman_node* root; 92 while(1) 93 { 94 //找到2个权值最小的节点 95 minimal[0] = nodelist.top(); 96 nodelist.pop(); 97 98 minimal[1] = nodelist.top(); 99 nodelist.pop(); 100 101 root = MergeNode(minimal[0], minimal[1]); 102 if(nodelist.empty()) 103 break; 104 nodelist.push(root); 105 } 106 107 return root; 108 } 109 110 void PrintTree(Huffman_node* root) 111 { 112 //if(root->leftchild == NULL) 113 } 114 115 int HuffmanTree::IsLeftChild(Huffman_node* node) 116 { 117 if(node->parent == NULL) 118 return -1; 119 if(node->parent->leftchild == node) 120 return 1; 121 else 122 return 0; 123 } 124 125 int HuffmanTree::CovertBits(vector<char> vecBits, void* code_buf) 126 { 127 int len = 0; 128 for(int i = 0; i < vecBits.size(); i += 8) 129 { 130 int num = 0; 131 for(int j = 0; j < 8; j++) 132 { 133 num += (vecBits[i+j] * (int)pow(2.0,7-j)); 134 } 135 ((unsigned char*)code_buf)[len++] = num; 136 } 137 138 return len; 139 } 140 141 142 void HuffmanTree::GenerateCode(Huffman_node* root) 143 { 144 vector<Huffman_node *>::iterator iter; 145 146 for(iter = m_leaves.begin(); iter != m_leaves.end(); iter++) 147 { 148 Huffman_node* temp = *iter; 149 char c = temp->value; 150 151 while(temp != m_root) 152 { 153 if(IsLeftChild(temp)) 154 m_code[c].bit.push_back(0); 155 else 156 m_code[c].bit.push_back(1); 157 temp = temp->parent; 158 } 159 } 160 } 161 162 163 int HuffmanTree::_Code(void* buf, int len, void* code_buf) 164 { 165 vector<char> bits; 166 167 code_buf = new unsigned char[len + 1]; 168 m_root = BuildHuffmanTree(buf, len); 169 170 //生成Huffman编码,编码是反向的,使用的时候逆向输出. 171 GenerateCode(m_root); 172 173 for(int i = 0; i< len; i++) 174 { 175 unsigned char c = ((unsigned char *)buf)[i]; 176 bits.insert(bits.end(), m_code[c].bit.rbegin(), m_code[c].bit.rend()); 177 } 178 179 int rest = bits.size() % 8; 180 if(rest) 181 { 182 for(int i = 0; i < (8-rest); i++) 183 bits.push_back(0); 184 } 185 186 int code_len = CovertBits(bits, code_buf); 187 188 return code_len; 189 } 190 191 192 int HuffmanTree::_Decode(void* buf, int len, void* decode_buf) 193 { 194 return 0; 195 }
Huffman.h
#include<vector> using namespace std; struct Huffman_node { unsigned char value; int weight; Huffman_node* parent; Huffman_node* leftchild; Huffman_node* rightchild; public: Huffman_node operator=(Huffman_node &x) { value = x.value; weight = x.weight; parent = x.parent; leftchild = x.leftchild; rightchild = x.rightchild; return *this; } friend bool operator<(Huffman_node& first, Huffman_node& second) { return first.weight < second.value; } }; struct HuffmanCode { unsigned char value; vector<char> bit; }; struct HuffmanCode_header { unsigned int sign; // 特征 long compressSize; // 压缩后大小 long uncompressSize; // 未压缩前大小 unsigned int reserved; // 保留 unsigned int version; // 版本 }; class HuffmanTree { private: Huffman_node* CreateNode(unsigned char value, int weight); int DestoryTree(Huffman_node* root); Huffman_node* MergeNode(Huffman_node* first, Huffman_node* sencond); Huffman_node* BuildHuffmanTree(void* buf, int len); void GenerateCode(Huffman_node* root); int IsLeftChild(Huffman_node* node); int CovertBits(vector<char> vecBits, void* code_buf); int _Code(void* buf, int len, void* code_buf); int _Decode(void* buf, int len, void* decode_buf); int LoadTreeFromFile(); int SaveTreeToFile(); public: HuffmanTree(); ~HuffmanTree(); public: int m_nNode; int m_nTotalNode; Huffman_node* m_root; HuffmanCode m_code[256]; vector<Huffman_node*> m_leaves; };