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;
};

浙公网安备 33010602011771号