Skip to content

Latest commit

 

History

History
128 lines (80 loc) · 5.03 KB

Develop.md

File metadata and controls

128 lines (80 loc) · 5.03 KB

元数据总结

关于 Big Endian 和 Little Endian

写在前面

计算机中储存数值有 2 种方式,一种是大端存储(Big Endian),一种是小端存储(Little Endian)。

以 uint32 数值的储存为例来举例:

所谓大端储存就是指存储的数值是从高位到低位的顺序,,就是数值占用 4 个字节,比如:

0x00 0x00 0x00 0x01 转为十进制,结果是 1

小端储存就不同了,同样的数,如果是小端储存,高位存储在低地址,低位存储在高地址,比如:

0x00 0x00 0x00 0x01 转为十进制,结果是 256^3。等于大端储存的 0x01 0x00 0x00 0x00

JPEG

因为历史原因,也叫 JPG

储存方式有如下的规则,其中一般使用开头和结尾的各 2 个字节来判断是否为 JPEG 格式

开头: 0xFF 0xD8 结尾: 0xFF 0xD9

如下所示:

| start: 2 bytes | block | block | ... | end: 2 bytes |

然后,储存时是按数据块(block)来储存的,每个数据库块的开头都有一个 2 字节的标识符,为 0xFF,type,来标识块的类型。 其中 C0 类型为图片的宽高信息。

数据块分析:

数值 偏移量 长度 说明
FF +0 1 开始标识符
任意 +1 1 类型,查看 JPEG 规范
n +2 ~ +3 2 块长度,包含这两位,但不包含 FF 和类型长度
内容 +4 ~ +(n+2) n-2 内容

已知类型标识符

数值 说明 信息
C0 宽度高度 +5~+6:高度 +7~+8:宽度

PNG

开头固定为:

89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52

宽度在 0x00000010 偏移量处, 0~3 位是宽度 4~7 位是高度

按照 PNG 规范,其实表示宽度和高度的字符各占 4 个字节,但实际应用中 2 字节可以表示的无符号整数的最大数值为 256^2-1=65535,而当前实际应用中我没有发现有这么大的图片,所以代码中只解析了 2 字节来表示宽度和高度,如果后续有需要,我会改进。

Webp

little endian

开头: 12 字节标识 webp 格式

20190920150556.png

RIFF(4 字节) + 文件长度(4 字节) + WEBP(4 字节), 文件长度不包含 RIFF 标识头和长度信息, 但包含 WEBP

比如我的图片文件大小为 125,198 字节, 这个文件长度对应的十六进制为 06 E9 01 00 , 这里要注意, 和 png jpg 的长度表示方案不同, 这里是倒序的 0x0001e906 = 125190


VP8 chunk: 找到 VP8 的标识 根据内容不同, 表示也不尽相同 往后偏移 +14 ~ +15 为宽度(倒序), 16~17为高度(倒序))

Gif

开头: 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 结尾: 0x3B

从偏移量 +6~+7 两位标识宽度 +8~+9标识高度, 这里也是倒序, 示例中图片的宽度对应的十六进制为: [0xB0,0x02] (688), 高度为[0x2E,0x05](1326)

Bmp

储存数字的方式是 little endian

本部分参考 信息来源

bmp 是 windows 的位图格式,但这个格式其实有很多种,通过开头的 2 个字节进行标识,一般情况下,咱们就关注 BM 开头的即可

sCtP6U

数据段总体分 4 个部分,其中调色板部分如果在颜色信息为 24 位或者 32 位以上是没有的

qWJIy2

而本库中需要的宽高信息集中在第二段中

第二段是如下的表

字节序号 数据结构 描述
15,16,17,18 uint 当前结构体的大小,通常是 40 或 56
19,20,21,22 int 图像宽度(像素)
23,24,25,26 int 图像高度(像素)
27,28 word 这个字的值永远是 1
29,30 word 每像素占用的位数,即 bpp
31,32,33,34 uint 压缩方式
35,36,37,38 uint 图像的尺寸(字节数)
39,40,41,42 int 水平分辨率,pixels-per-meter
43,44,45,46 int 垂直分辨率,pixels-per-meter
47,48,49,50 uint 引用色彩数
51,52,53,54 uint 关键色彩数

所以,我们通常读取前 2 个字节来判断是否是 BM,19 开始的四个字节是宽度,23 开始的四个字节是高度