如何解码没有压缩的PNG文件的IDAT块

时间:2016-08-22 03:25:31

标签: algorithm graphics png file-format deflate

我在Photoshop中创建了一些4x4像素,16位灰度图像,并将它们保存为非压缩,无交错,PNG文件。我正在尝试编写一个程序来从这些文件中提取图像数据,但我对IDAT块有点困惑。这是出于自我教育的目的,所以我没有使用图书馆。

以下是其中一个图像的IDAT块的十六进制代码,其中每个像素都是白色。

hex code

我的颜色代码我认为我在这一点上理解。

红色 =忽略,因为它是IEND块的一部分,与IDAT无关。
黄色 =块信息。前4个黄色字节是数据长度。第二个4个黄色字节是块标识符。图像末尾的最后4个黄色字节是循环冗余校验。
蓝色 = zlib压缩格式信息。其中第一个蓝色字节是压缩方法和压缩信息。第二个蓝色字节是标志信息。图像底部附近的最后四个蓝色字节是ADLER-32校验和。我假设在这种情况下没有DICTID。
灰色 = Deflate压缩算法的信息。在第一个灰色字节中,第一位是最后一个块标记,第二位和第三位是编码方法。第一个灰色字节的其余部分将被忽略。由于该方法是非压缩方法,所以第二和第三灰色字节是块中数据字节的长度,第四和第五灰色字节是第二和第三灰色字节的一个补码。
No Box =使用LZ77算法压缩的图像数据(由于未压缩的方法,没有霍夫曼码),算法使用8位表示潜在的重复长度,15位表示搜索返回距离。

要么我不正确地理解某些东西,要么我不理解如何正确地使用LZ77算法解码图像中没有框的字节。如果有人能够纠正我或表明我不理解,我会非常感激。谢谢。

1 个答案:

答案 0 :(得分:7)

顶行:01 ff fd 00 00 00 00 00 00(" sub"过滤器,第一个像素为fffd,          后续像素每个都与其左边的像素相同(差值= 0)

剩余3行:02 00 00 00 00 00 00 00 00("向上"过滤器,与上面的行完全相同)

最后一个块:01 00 00 ff ff(最后一个字节标记01,len 0000,~len ffff)

因此图像是4x4,所有像素都是16位fffd,几乎是白色。

如果你对所有字节使用过滤器类型0,那么可能更清楚地理解;每行都是00 ff fd ff ff ff ff ff fd fd

顺便说一句,IEND块应该有4个字节(CRC);您的编码器出现问题,或者您已将其编辑为十六进制转储的图片。