导语
在UE4 中实现哈夫曼编码的本意是在网络数据传输的时候,进行数据包一定程度的数据压缩。但是实现完之后发现并无用武之地,一个是因为压缩的数据中还必须要包含编码表,对于高频、小数据包反而会增加数据的大小和增加编码解码的计算消耗。二是因为好多要传输的数据本身就是已经编码压缩过了,再次编码压缩已经没有效果了(比如UE4 的 RenderTarget 图像数据 和 VoiceData)。所以权当是一次代码练习吧。
关于哈夫曼编码
Huffman于1952年提出一种编码方法,该方法完全依据出现概率来构造异字头的平均长度最短的码字 。简单来说就是用最少的bit来表示出现频率最高的字符,生成一张编码对照表,解码的时候根据对照表依次还原就行。
比如 “aabccade”,其中总共有a、b、c、d、e 五个字符,a出现3次,c出现2次,b、d、e出现1次,
那么可以用0表示a,用1表示c,用10表示b,用11表示d,用100表示e。所以原字符就可以用1
0-0-10-1-1-0-11-100
来表示了。当然具体实现细节要更复杂一点,涉及到二叉树,前缀码等。
HuffmanEncode.h
1 |
|
HuffmanEncode.cpp
1 | // Fill out your copyright notice in the Description page of Project Settings. |
蓝图代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21TArray<uint8> UBPFLibrary::HFM_Encode(TArray<uint8> indata)
{
uint8* outdata = new uint8[indata.Num()* 3]{ 0 };
int outdatasize =0;
Huffman::Encode(indata.GetData),indata.Numo,outdata, outdatasize);
TArray<uint8> outdatal;
outdata1.Init(o,outdatasize);
FMemory::Memcpy(outdata1.GetData(),outdata,outdatasize);
return outdatal;
}
TArray<uint8>UBPFLibrary::HFM_Decode(TArray<uint8> indata)
{
uint8* outdata = new uint8[indata.Num)* 3]{ e };
int outdatasize = 0;
Huffman::Decode(indata.GetData(),indata.Num(),outdata, outdatasize);
TArray<uint8>outdatal;
outdata1.Init(e,outdatasize);
FMemory::Memcpy(outdata1.GetData(),outdata,outdatasize);
return outdatal;
}