【问题标题】:"zlib: inflate error = -3 (data error)" with custom png implementation“zlib: inflate error = -3 (data error)” 自定义 png 实现
【发布时间】:2020-04-26 09:43:47
【问题描述】:

出于学习目的,我正在 VHDL 中实现 PNG 编码器。它适用于从 1x1 到 4x4 的图像尺寸。在 5x5 的图像尺寸下,有一种我无法理解的行为:

当编码值为 0...24 的原始数据时,编码有效。但是,当使用值为 255...231 的原始数据时,会生成损坏的图像。

输入值 0...24:

> hexdump -C png_encoder/gen/test_img_no_compression_5x5.png
00000000  89 50 4e 47 0d 0a 1a 0a  00 00 00 0d 49 48 44 52  |.PNG........IHDR|
00000010  00 00 00 05 00 00 00 05  08 00 00 00 00 a8 04 79  |...............y|
00000020  39 00 00 00 4c 49 44 41  54 78 01 00 04 00 fb ff  |9...LIDATx......|
00000030  00 00 01 02 00 04 00 fb  ff 03 04 00 05 00 04 00  |................|
00000040  fb ff 06 07 08 09 00 04  00 fb ff 00 0a 0b 0c 00  |................|
00000050  04 00 fb ff 0d 0e 00 0f  00 04 00 fb ff 10 11 12  |................|
00000060  13 00 04 00 fb ff 00 14  15 16 01 02 00 fd ff 17  |................|
00000070  18 0b a4 01 2d d5 1f a2  6d 00 00 00 00 49 45 4e  |....-...m....IEN|
00000080  44 ae 42 60 82                                    |D.B`.|
00000085

> pngcheck -vv png_encoder/gen/test_img_no_compression_5x5.png 
File: png_encoder/gen/test_img_no_compression_5x5.png (133 bytes)
  chunk IHDR at offset 0x0000c, length 13
    5 x 5 image, 8-bit grayscale, non-interlaced
  chunk IDAT at offset 0x00025, length 76
    zlib: deflated, 32K window, superfast compression
    row filters (0 none, 1 sub, 2 up, 3 avg, 4 paeth):
      0 0 0 0 0 (5 out of 5)
  chunk IEND at offset 0x0007d, length 0
No errors detected in png_encoder/gen/test_img_no_compression_5x5.png (3 chunks, -432.0% compression).

输入值 255...231:

> hexdump -C png_encoder/gen/test_img_no_compression_5x5.png
00000000  89 50 4e 47 0d 0a 1a 0a  00 00 00 0d 49 48 44 52  |.PNG........IHDR|
00000010  00 00 00 05 00 00 00 05  08 00 00 00 00 a8 04 79  |...............y|
00000020  39 00 00 00 4c 49 44 41  54 78 01 00 04 00 fb ff  |9...LIDATx......|
00000030  00 ff fe fd 00 04 00 fb  ff fc fb 00 fa 00 04 00  |................|
00000040  fb ff f9 f8 f7 f6 00 04  00 fb ff 00 f5 f4 f3 00  |................|
00000050  04 00 fb ff f2 f1 00 f0  00 04 00 fb ff ef ee ed  |................|
00000060  ec 00 04 00 fb ff 00 eb  ea e9 01 02 00 fd ff e8  |................|
00000070  e7 6a 21 17 bc 9a 17 87  e7 00 00 00 00 49 45 4e  |.j!..........IEN|
00000080  44 ae 42 60 82                                    |D.B`.|
00000085

> pngcheck -vv png_encoder/gen/test_img_no_compression_5x5.png 
File: png_encoder/gen/test_img_no_compression_5x5.png (133 bytes)
  chunk IHDR at offset 0x0000c, length 13
    5 x 5 image, 8-bit grayscale, non-interlaced
  chunk IDAT at offset 0x00025, length 76
    zlib: deflated, 32K window, superfast compression
    row filters (0 none, 1 sub, 2 up, 3 avg, 4 paeth):

    zlib: inflate error = -3 (data error)
 (0 out of 5)
ERRORS DETECTED in png_encoder/gen/test_img_no_compression_5x5.png

如何解读错误信息zlib: inflate error = -3 (data error)

我阅读了https://www.zlib.net/zlib_how.html,但没有找到更具体的信息。我的第一个猜测是行过滤器不正确,但由于两个文件的结构相同,这不太可能。第二种情况下 ADLER32 计算是否有问题(可能有些溢出)?

【问题讨论】:

    标签: algorithm png zlib


    【解决方案1】:

    这是 ADLER32 校验和计算中的溢出。具体来说,在使用 65521 进行模运算之前,添加并截断了两个 16 位数字。不幸的是,我的 ADLER32 单元测试还没有捕捉到它。

    但是,在实施过程中多次显示错误消息,我始终不确定原因。如果有人可以详细说明错误消息或解释如何获得更好的错误消息,我会很高兴听到。

    【讨论】:

    • 您的具体意思是消息“inflate error = -3 (data error)”? zlib 主动使用 Adler-32 校验和来验证数据是否正确解包。如果解压过程中发生错误(并且无法进一步解压),那么你会得到这个错误,但是如果数据解压没有任何错误并且这个校验和不匹配,它只能断定有数据中某处出现意外错误。
    • 是的,我的意思是这个特定的错误消息。仅知道解压过程中出现问题时,要找到确切的错误原因有点困难。但我想当实现变得更稳定时它会变得更好。
    猜你喜欢
    • 2022-06-16
    • 1970-01-01
    • 2015-11-03
    • 2013-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多