9.3.4. PNG模块功能说明
9.3.4.1. 原理框图
PNG解码模块主要包括:Bits读取模块、Huffman解码、LZ77 Dec模块,PNG DeFilter模块。
zlib/gzip 解压缩复用 PNG 解码模块
9.3.4.2. PNG 解码
PNG 文件结构
PNG数据块,由标准数据块和辅助数据块组成,如下给出基本的PNG数据块说明:
数据块符号 |
数据块名称 |
多数据块 |
是否可选 |
---|---|---|---|
IHDR |
文件头数据块 |
否 |
否 |
PLTE |
调色板数据块 |
否 |
否 |
tRNS |
图像透明数据块 |
否 |
否 |
IDAT |
图像数据块 |
多数据块 |
是 |
IEND |
图像结束数据块 |
否 |
否 |
在IHDR中可以获取到PNG图片的宽,高,位深,颜色类型,Interlace Method等参数。本模块对PNG标准的支持情况如下:
域名 |
标准定义 |
本模块是否支持 |
---|---|---|
位深 |
索引彩色图像:1,2,4,8 |
是 |
灰度图像:1,2,4,8或16 |
否 |
|
真彩色图像:8或者16 |
支持8bits,不支持16bits |
|
颜色格式 |
0:灰度图像,1,2,4,8或16 |
否 |
2:真彩色图像 |
是 |
|
3:索引彩色图像,1,2,4或8 |
是 |
|
4:带α通道数据的灰度图像,8或16 |
否 |
|
6:带α通道数据的真彩色图像,8或16 |
支持8bits,不支持16bits |
|
扫描方式 |
0:非隔行扫描 |
是 |
1:Adam7 |
否 |
PNG图片的码流数据都在数据块IDAT中,IDAT中是以zlib格式的压缩码流,在zlib压缩之前,可以采用Filter算法对原始数据进行处理,有助于提升压缩率。
PNG图像如下如所示,X表示当前要进行Filter的像素,A为当前像素左边像素,B为当前像素上边像素,C为当前像素左上边像素,则对Fiter的说明如下所示:
Filter类型 |
函数 |
Filter方式 |
---|---|---|
0 |
无 |
保留原始数据 |
1 |
减 |
减去A |
2 |
上 |
减去B |
3 |
平均 |
根据A和B取平均,并向下取整 |
4 |
Paeth |
使用最接近与A+B-C的A、B或者C |
PNG 图像的解码流程
PNG解码流程中的虚线框部分是由硬件实现,虚线框外部的PNG parser和Read zlib Header需要软件解析。蓝色部分是PNG解码和zlib不一样的地方,zlib解码后,每一行都需要进行Defilter处理,恢复原始的像素。
小技巧
PNG图片的deflate数据可能存放在多个IDAT数据块中,硬件不支持解析IDAT,所以需与软件配合才能完成解码。
软件解析所有IDAT数据,并把IDAT中的deflate数据拷贝到一块物理连续buffer中;
硬件读取该buffer中的deflate数据并完成解码
9.3.4.3. zlib解码
zlib封装结构如下:
zlib格式是对Deflate格式的一种封装。CMF是压缩方式的描述, FLG中的FDICT标记了是否使用预先设置的字典,目前不支持FDICT为1的情况。ADLER32为类似于CRC32的校验码。zlib封装详细说明请参考RFC1950。
zlib封装部分由软件解析,Deflate码流部分,由硬件Inflate模块解析,硬件解码完成后生成对应的ADLER32校验码,然后由软件比较硬件生成的校验码和zlib格式封装中ADLER32是否一致。如果一致则说明zlib解码正确。
9.3.4.4. gzip解码
gzip封装结构如下:
gzip也是对Deflate压缩格式的一种封装。对Deflate格式加入了头信息和尾部信息。gzip对原始码流用CRC32校验,和zlib中的校验方式不同。并且尾部加入了4 bytes 的原始码流的size信息。硬件解码时候,可以根据size的大小,来申请输出Buffer。gzip封装的详细说明请参考RFC1952。
gzip封装部分由软件解析,Deflate码流部分,由硬件Inflate模块解析,硬件解码完成后生成对应的CRC32校验码,然后由软件比较硬件生成的校验码和gzip格式封装中CRC32是否一致。如果一致则说明gzip解码正确。