我目前正在为了学习目的而自己编写一个小的PNG图像I/O库.我的问题如下:
我创建了一个尺寸仅为2 x 2的小PNG,并在十六进制编辑器中打开它以研究其内容.这是我使用GIMP创建的图像,并以压缩"9"存储.
(请注意,这是原始2 x 2像素图像的放大图像;))

所以我猜没有压缩,这在内存中看起来像这样:
00 00 00 FF 00 00 00 00 FF 00 FF 00
Run Code Online (Sandbox Code Playgroud)
存储时没有alpha通道.
(为了清楚起见,我在这里只说了这个.我知道压缩,并且不希望在文件中看到这个字节模式).
我提取了IDAT块并剥离了块ID("IDAT")和尾随CRC值并得到了这个字节序列:
08 D7 05 C1 01 01 00 00 00 80 10 FF 4F 17 10 48 06 0F FE 02 FE
Run Code Online (Sandbox Code Playgroud)
现在前两个字节08 D7包含有关编码块的信息.最后四个字节0F FE 02 FE必须是ADLER32校验和.
这最终让我得到以下字节:
05 C1 01 01 00 00 00 80 10 FF 4F 17 10 48 06
Run Code Online (Sandbox Code Playgroud)
以二进制表示形式写的这些字节是:
0000 0101 1100 0001 0000 0001 0000 0001
0000 0000 …Run Code Online (Sandbox Code Playgroud) 我对这个问题的希望(参见底部)希望对我的放气过程进行尽可能多的布置,并且我可以(可能非常)误解了我所在的领域。希望最后,这个问题可以成为一个方便的资源。
前两个字节等于zlib压缩的标头,格式为(credit)
---CMF--- ---FLG---
0111.1000 1101.0101
CINF -CM- +-||
| |+- FCHECK
| +-- FDICT
+---- FLEVEL
Run Code Online (Sandbox Code Playgroud)
从RFC 1950开始,从右到左:
FCHECK(1.0101)-验证CMF和FLG为16位无符号整数是31的倍数
FDICT(0)-如果设置,表示在FLG之后紧随其后的预设DICT
FLEVEL(11)-压缩“强度” [0-3]
CM(1000)-用于压缩方法,其中CM = 8 ==“放气”压缩方法
CINF(0111)-指示使用的滑动窗口的大小,其中CINF = 7 == 32K滑动窗口
NEW BYTE中的后三位等于霍夫曼编码块的标头:
---CMF--- ---FLG--- NEW BYTE
0111.1000 1101.0101 11101100
|-|
| +- BFINAL
+--- BTYPE
Run Code Online (Sandbox Code Playgroud)
从RFC 1951右到左:
BFINAL(0)-如果这是最后一个数据块,则设置为(1)
BTYPE(10)-霍夫曼编码:(00)无;(01)修正霍夫曼码;(10)动态代码;(11)无效
从这里开始,我将假设BTYPE =(10)
下列值会立即进行:
NEW BYTE NXT BYTE
(11101)100 -> 101)(11101) -> 0111111(1
|-|
| +- BFINAL
+--- BTYPE
Run Code Online (Sandbox Code Playgroud)
HLIT (11101)-5位长度/文字代码,增加了257个(257-286) …