DSP

LIBPNG显示PNG图像

2019-07-13 19:49发布

这两天查了很多资料,终于搞定了PNG解码的问题。我是用LIBPNG实现的。先看看png图像的格式: PNG图像格式文件(或者称为数据流)由一个8字节的PNG文件署名(PNG file signature)域和按照特定结构组织的3个以上的数据块(chunk)组成。 PNG定义了两种类型的数据块,一种是称为关键数据块(critical chunk),这是标准的数据块,另一种叫做辅助数据块(ancillary chunks),这是可选的数据块。关键数据块定义了4个标准数据块,每个PNG文件都必须包含它们,PNG读写软件也都必须要支持这些数据块。虽然PNG文件规范没有要求PNG编译码器对可选数据块进行编码和译码,但规范提倡支持可选数据块。4个标准数据块:(1)文件头数据块IHDR(header chunk):它包含有PNG文件中存储的图像数据的基本信息,并要作为第一个数据块出现在PNG数据流中,而且一个PNG数据流中只能有一个文件头数据块。文件头数据块由13字节组成。
域的名称字节数说明Width4 bytes图像宽度,以像素为单位Height4 bytes图像高度,以像素为单位Bit depth1 byte图像深度:
索引彩 {MOD}图像:1,2,4或8
灰度图像:1,2,4,8或16
真彩 {MOD}图像:8或16
ColorType1 byte颜 {MOD}类型:
0:灰度图像, 1,2,4,8或16
2:真彩 {MOD}图像,8或16
3:索引彩 {MOD}图像,1,2,4或8
4:带α通道数据的灰度图像,8或16
6:带α通道数据的真彩 {MOD}图像,8或16
Compression method1 byte压缩方法(LZ77派生算法)Filter method1 byte滤波器方法Interlace method1 byte隔行扫描方法:0:非隔行扫描1: Adam7(由Adam M. Costello开发的7 
遍隔行扫描方法)
 (2) 调 {MOD}板数据块PLTE(palette chunk):它包含有与索引彩 {MOD}图像((indexed-color image))相关的彩 {MOD}变换数据,它仅与索引彩 {MOD}图像有关,而且要放在图像数据块(image data chunk)之前。真彩 {MOD}的PNG数据流也可以有调 {MOD}板数据块,目的是便于非真彩 {MOD}显示程序用它来量化图像数据,从而显示该图像。表6-09 调 {MOD}板数据块结构
域的名称字节数说明Red1 byte0 = 黑,255 = 红Green">0 = 黑,255 = 绿Blue1 byte0 = 黑,255 = 蓝
 调 {MOD}板实际是一个彩 {MOD}索引查找表,它的表项数目可以是1~256中的一个数,每个表项有3字节,因此调 {MOD}板数据块所包含的最大字节数为768。(3) 图像数据块IDAT(image data chunk):它存储实际的数据,在数据流中可包含多个连续顺序的图像数据块。(4) 图像结束数据IEND(image trailer chunk):它用来标记PNG文件或者数据流已经结束,并且必须要放在文件的尾部。除了表示数据块开始的IHDR必须放在最前面, 表示PNG文件结束的IEND数据块放在最后面之外,其他数据块的存放顺序没有限制。  PNG的IDAT使用从LZ77派生的无损数据压缩算法,大概意思就是将数据作为一个数组,进行字符串匹配 ,从0开始向后移动,在每个位置上都寻找它前面的区域中和当前位置开始的串至少三个相匹配的串,并从这些串中找到最长的匹配的串。然后将会被一个<匹配长度,到匹配串开头的距离>对替换。 所以解析IDAT就是关键了。 这里LIBPNG用的是zlib程序库作为压缩引擎。zlib可以从它的官方网站下载。 zlib 的使用在sourceproject可以下载个例子看看:) 那里有显示的例子