我想知道在PNG图像中使用多个IDAT-Chunks的好处是什么。
PNG文件说
可能有多个IDAT块;如果是这样,它们将连续出现而没有其他干预块。然后压缩的数据流是所有IDAT块的数据字段内容的串联。
我无法想象这是因为块内数据块的最大大小(2 ^ 32字节)。
答案 0 :(得分:3)
回想一下,所有PNG块(包括IDAT块)都有一个带有块长度的前缀。将所有压缩流放在一个巨大的IDAT块中会导致这两个不便:
在编码器端:压缩器在完成压缩之前不知道总压缩数据大小。然后,在写入块前缀之前,需要在内存中缓冲完整的压缩数据。
在解码器方面:它取决于如何实现块解码;如果它缓冲内存中的每个块(分配由块长度前缀给出的空间),并在填充并检查CRC后,将内容传递给解压缩器,那么,再次,拥有一个巨大的IDAT块将是一个内存猪。
考虑到这一点,我认为应该建议使用相当小的IDAT块(例如,16KB或64KB)。开销(每个块12个字节,如果len = 64KB,则小于1/5000)可以忽略不计。
答案 1 :(得分:0)
当读取PNG文件时,libpng limits即使文件中的IDAT块大小较大,它也会缓冲到8192个字节的数据块。这为libpng读取和解压缩IDAT块所需的分配大小设置了上限。但是,在读取整个IDAT块之前仍然无法检测到校验和错误,而且对于大型IDAT块,这可能需要更长的时间。
假设您不关心CRC错误的早期检测(如果它们确实发生了,它们仍然会被检测到,但稍后会被检测到),那么小IDAT块不会给读者带来任何好处。实际上,小型IDAT块意味着在zlib中对zlib进行更多单独调用以及更多前导码/后同步码成本,因此通常在处理时间和磁盘空间方面效率较低。
对于编写者来说,编写有限长度的IDAT块很方便,因为您可以在写入之前确定块的长度。如果要编写单个IDAT块,则必须在开始编写任何内容之前完成压缩(需要大量临时存储),或者一旦知道IDAT块长度,就必须在输出中寻找更新IDAT块长度
如果您正在压缩图像并同时传输结果,则可能无法实现。如果你把图像写入磁盘,那么这可能不是什么大问题。
简而言之,小块用于即时压缩,流输出用例。在大多数其他情况下,只需一个块就可以获得更好的效果。
答案 2 :(得分:-4)
IDAT块包含实际图像数据。要创建此数据:
从图像扫描线开始,如图像布局中所述;该原始数据的布局和总大小由IHDR的字段确定。 根据IHDR块指定的过滤方法过滤图像数据。 (请注意,使用过滤器方法0,当前定义的唯一一个,这意味着在每个扫描行中添加一个过滤器类型的字节。) 使用IHDR块指定的压缩方法压缩过滤的数据。 IDAT块包含压缩算法的输出数据流。
要读取图像数据,请反转此过程。