Huffman存储格式
()中数字的单位为位
Huffmancode_count(8)-存储对应了多少Huffman编码,最大255
FileEnd_Offset(3)-按8位存后,不足8位用n填补,最大7
Huffman_Max(3)-存储对应的每个HuffmanCode需要的位数的位数(如最大需要255位,则需要存储8,需要3的位数)
Table-
{
ASCII Code(8), Huffman Bits(Huffman_Max), HuffmanCode(Huffman Bits)
}-存的是哈弗曼表, ASCII码8位, 存储哈弗曼编码的长度Huffman_Max位,哈弗曼编码Huffman Bits位
HuffmanCodeStream 哈弗曼码的流
ZeroFillUp(FileEnd_Offset)-填充位,可以为0可以为1,这里选择为0,需要FileEnd_Offset个位数
后来想到了Adaptive Huffman编码, 原因是比较有意思
经过一段时间实践,发现除了能节省表的空间,并不会节省很多其他的东西,也浪费了时间,时间复杂度为O(n^2),在我用源代码文件,中文,英文,日文,还有简单测试样本进行测试当中,发现仅有简单测试文本能够进行压缩,其他文件不够理想,而且速度很慢
转而想到还是用普通的吧,什么叫做普通的Huffman,就是预读信息或者预测信息统计频率,利用Huffman方式进行编码,随后将编码表存入压缩文件中,方便解码时预读调用,开始有些疑虑的是,若是出现了9位以上的编码怎么办,其实这个担心是没有必要的,Huffman编码降低的期望值,所以总体上还是降低了速度,速度为2n,时间复杂度为O(n),同时也方便实现
简要说下实现要点吧,
AH需要在前面添加关键字,以便补充后面不够8位的数据
正常版则在于预读时的哈弗曼树的建立,以及表的存储,建议是数据哈弗曼编码特殊隔位的格式,因为数据每次读8位...
再者,若要提高速度,最好不要使用C++中的动态库,STL和MFC,这点很重要
总结:
Adaptive Huffman, 不如想象中好,节省表空间,但不一定能起到压缩作用,O(n^2)
Huffman,不像想象那样坏,添加表,节省期望值,O(n)
RunLength的结构
Buffer_Size(8)-标志位,其实完全可以用2位的,但是写读时不是很方便,表示存储RunLength中数据大小,比如10个0,30个1,再20个0,我们存10,30,20当然此时的Buffer为1,自然也是可以优化的,这里不予以考虑;但试想若超过255怎么办,如10个0,1024个1,这时用2作为Buffersize显然是最好的,那若是10个0,10个1,10个0,10个1.....1024个1这时若是用Buffersize为2就得不偿失了,这时我们采用以下的方法:
buffer size还是为1,前面还是10,10,10,10....到1024时我们改成这样,
00000001000000000000000
用3个buffer长度进行存储,如果你默认第一个为0的个数的话,第二个就为1的,则除了头信息和第一个流文件可能为0外,其他不可能为0,这时若存一个比正常大的数,我们就采用上述方法分隔起来,前面存前8位,中间各位符0,后面存后八位,此时1024就为1,0,0或者为00000001000000000000000
但是这样不一定是最优的,因为要是仅仅一个需要1SIZE的,为其他都为2SIZE则会产生不必要的损耗,所以使用之前一定要先计算最优BufferSize