上一篇文章我们介绍了对待编码图片进行变换和量化,量化后数据通过zig-zag序列化后得到一维数组。最后步骤就是对一维数组进行熵编码。这里采用的熵编码为哈弗曼编码(Huffman coding),哈弗曼几乎是所有压缩算法的基础,它的基本原理是根据数据中元素的使用频率,调整元素的编码长度,以得到更高的压缩比。我们下面来看下具体的编码过程。
假设量化后zig-zag得到的一维数据为:
量化后数据
1、数据中的0出现的概率非常高,所以首先要做的事情,是对其中的0进行处理,把数据中的非零的数据,以及数据前面0的个数作为一个处理单元。如果其中某个单元的0的个数超过16,则需要分成每16个一组,如果最后一个单元全都是0,则使用特殊字符“EOB”表示,EOB意思就是“后面的数据全都是0”,
对0进行组合
每个组合第1个数字表示0的数量
2、处理括号里右边的数字,这个数字的取值范围在-2047~2047之间,JPEG提供了一张标准的码表用于对这些数字编码:
标准码表
对右边数字根据码表编码
根据协议可以确定的是括号中前两个数字分都在0~15之间,所以这两个数可以合并成一个byte,高四位是前面0的个数,后四位是后面数字的位数。
合并为1个字节
3、处理括号里左边的数字,使用哈弗曼编码。下面这张表,就是一张针对数据中的第一个单元,也就是直流(DC)部分的哈弗曼表,由于直流数据是序列第一个数据,没有前置的0,所以byte只用了4个byte,值的范围在0~11之间。
直流分量哈夫曼表
交流分量会出现0,所以值的范围任务高四位可能为0x0~0xf(0的个数最大为15),低四位范围为0~0xb(对应码表中的size),下面这张哈夫曼表对应的就是交流部分的。
交流数据哈夫曼表
这样分别对直流数据和交流数据编码并且序列后得到了最终的编码数据。
熵编码总体流程
最终我们使用了10个字节的空间保存了原本长度为64的数组,至此JPEG的主要压缩算法结束,这些数据就是保存在jpg文件中的最终编码数据。
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved