9.3.4. PNG模块功能说明

9.3.4.1. 原理框图

../../../_images/png_framework.png

PNG解码模块主要包括:Bits读取模块、Huffman解码、LZ77 Dec模块,PNG DeFilter模块。

zlib/gzip 解压缩复用 PNG 解码模块

9.3.4.2. PNG 解码

  1. PNG 文件结构

../../../_images/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的说明如下所示:

../../../_images/png_filter.png

Filter类型

函数

Filter方式

0

保留原始数据

1

减去A

2

减去B

3

平均

根据A和B取平均,并向下取整

4

Paeth

使用最接近与A+B-C的A、B或者C

  1. PNG 图像的解码流程

../../../_images/png_dec_flow.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封装结构如下:

../../../_images/zlib.png

zlib格式是对Deflate格式的一种封装。CMF是压缩方式的描述, FLG中的FDICT标记了是否使用预先设置的字典,目前不支持FDICT为1的情况。ADLER32为类似于CRC32的校验码。zlib封装详细说明请参考RFC1950。

zlib封装部分由软件解析,Deflate码流部分,由硬件Inflate模块解析,硬件解码完成后生成对应的ADLER32校验码,然后由软件比较硬件生成的校验码和zlib格式封装中ADLER32是否一致。如果一致则说明zlib解码正确。

9.3.4.4. gzip解码

gzip封装结构如下:

../../../_images/gzip.png

gzip也是对Deflate压缩格式的一种封装。对Deflate格式加入了头信息和尾部信息。gzip对原始码流用CRC32校验,和zlib中的校验方式不同。并且尾部加入了4 bytes 的原始码流的size信息。硬件解码时候,可以根据size的大小,来申请输出Buffer。gzip封装的详细说明请参考RFC1952。

gzip封装部分由软件解析,Deflate码流部分,由硬件Inflate模块解析,硬件解码完成后生成对应的CRC32校验码,然后由软件比较硬件生成的校验码和gzip格式封装中CRC32是否一致。如果一致则说明gzip解码正确。