【转】分析PNG图像文件结构(2)

来源:互联网 发布:2007office软件下载 编辑:程序博客网 时间:2024/04/27 14:32

在未得到原作者的同意下转载,特地在此贴出源地址以作声明:http://wmnmtm.blog.163.com/blog/static/3824571420106235582697/

--------------------------------华丽的分割线----------------------------

表5-15归纳了pic1.png图像文件中文件头数据块(IHDR)中各字段的含义。由于PNG文件使用Big-Endian顺序存储数据,所以不需要反转字节数据理解。

表5-15 pic1.png图像文件中文件头数据块(IHDR)的各字段含义


十六进制值

描 述

00 00 00 0D

文件头的数据长度,00 00 00 0D =13

49 48 44 52

数据块类型标志,49 48 44 52的ASCII值等于IHDR

00 00 00 C8

图像的宽度,00 00 00 C8 = 200

00 00 00 96

图像的高度,00 00 00 96 = 150

08

色深,表示2的8次幂等于256色

03

03表示索引图像

00

00表示使用Deflate压缩编码压缩图像数据

00

00表示为将来使用更好的压缩方法预留

00

00表示非隔行扫描

AC 02 37 2B

AC 02 37 2B表示CRC


从表5-14看到pic1.png文件的文件头数据块(IHDR)结构中的CRC字段的值为AC 02 37 2B,这个CRC值是按照从数据块类型标志字段到CRC字段前一字节的数据计算而来的,即使用数据49 48 44 52 00 00 00 C8 00 00 00 96 08 03 00 00 00计算,CRC的计算代码如下:

   /*8位消息的CRC表格*/unsigned long crc_table[256];/*Flag:CRC表格计算完了吗?初始化 False*/int crc_table_computed = 0;/*写一个CRC表格*/void make_crc_table(void){unsigned long c;int n, k;for (n = 0; n < 256; n++) {c = (unsigned long) n;for (k = 0; k < 8; k++) {if (c & 1)c = 0xedb88320L ^ (c >> 1);elsec = c >> 1;}crc_table[n] = c;}crc_table_computed = 1;}/*使用bu[0..len-1]更新CRC表格*/unsigned long update_crc(unsigned long crc, unsigned char *buf,int len){unsigned long c = crc;int n;if (!crc_table_computed)make_crc_table();for (n = 0; n < len; n++) {c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);}return c;}/* 返回 CRC表格buf[0..len-1]. */unsigned long crc(unsigned char *buf, int len){return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL;}main(){/*计算CRC需要的初始化数据,不同的数据块有不同的初始化数据*/unsigned char buf[17] = {0x49,0x48,0x44,0x52,0x00,0x00,0x00,0xC8,0x00,0x00,0x00,0x96,0x08,0x03,0x00,0x00, 0x00 };unsigned long value=0;value= crc(buf,17);}

继续分析下面的数据块,PNG图像文件的数据块类型由数据块类型标志决定,按照PNG图像文件中数据块的数据结构分析,接下来的数据块是物理像素尺寸数据块(pHYs),物理像素尺寸数据块(pHYs)指定像素大小或图像的宽和高的比例。

表5-16所示为物理像素尺寸数据块(pHYs)中各字段的含义。

表5-16 物理像素尺寸数据块(pHYs) 中各字段的含义

字 段 名

大小(单

位:字节)

描 述

physPixelPerUnitX

4

每单位多少像素,x轴

physPixelPerUnitY

4

每单位多少像素,y轴

UnkownUnit ,Meter

1

枚举类型,UnkownUnit=0,表示只定义了像素显示的比例,未定义实际像素大小。

枚举类型,Meter=1,表示定义单位为米

物理像素尺寸数据块(pHYs)的结构可以用以下代码定义:

PNG_CHUNK_HEADER chunkHdr ;uint physPixelPerUnitX;uint physPixelPerUnitY;enum {UnkownUnit = 0,Meter = 1} pHYs;DWORD pHYsCrc;
图5-20所示为pic1.png中的物理像素尺寸数据块(pHYs)的结构。
查看大图 (点击查看大图)图5-20 pic1.png中的物理像素尺寸数据块(pHYs)的结构
原创粉丝点击