编辑:这是指IDAT中的实际数据流块(以及唯一的IDAT块)。我成功地浏览了从IHDR到IEND的相关关键块 - 问题在于实际块之间的导航。
所以,我出于好奇,正在编写一个小宠物项目,编写一个PNG加载器并首先尝试使用未压缩的文件来实际获得它的要点。对于压缩类型00(无压缩),如果最终块有问题,则应该是2^16 - 1
,65535或更小的大小。
所以,我正确加载第一个块并尝试添加最后一个块长度的偏移量(如果是最后一个,则为变量,65535或更小)。因此,我希望到65535th的偏移应该落在下一个块的第一个字节上,因为最后一个从0读取到非包含65535或65534th字节是第一个块的最后一个字节。但由于一些奇怪的原因,我的未压缩PNG文件(用Photoshop输出)读取了应该是第二个块传递的虚假数据(它将其标记为压缩和最终的动态霍夫曼代码,因此LZ77压缩算法的变体) ,在不同的图像上,它输出77用于压缩类型等,在1MB文件的100k字节标记处。)
所以,我可能必须登陆错误的字节?它应该是微不足道的,但我看不出我失败的地方,这是相关的一点:
unsigned int accumulatedOffset = 0;
CBlock cblock; // initializes length to 0
do {
accumulatedOffset += cblock.length; // Adds 65535 on second pass
// Extract block header
unsigned char bheader = IDATChunk[Description::BlockHeaderOffset + accumulatedOffset];
// The second pass reads from the wrong byte, it seems.
} while(...)
我错过了第二次传球之间的东西吗?
答案 0 :(得分:1)
啊,谢谢你的编辑。所以你在谈论放气块。
如果您有所有存储的deflate块,格式为:
00 rs pq ~rs ~pq [ pqrs bytes ] ... same thing repeated ... 01 rs pq ~rs ~pq [ pqrs bytes ]
其中~
表示反向或一个补码。
请注意,这将遵循zlib标头,后跟zlib预告片。请参阅RFC 1950。