"zlib: inflate error = -3 (error data)" с пользовательской реализацией png - PullRequest
1 голос
/ 26 апреля 2020

Я использую кодировщик PNG в VHDL для целей обучения. Работает с размерами изображения от 1х1 до 4х4. При размере изображения 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, но не нашел более подробной c информации. Мое первое предположение было, что фильтры строк некорректны, но поскольку оба файла имеют одинаковую структуру, это маловероятно. Что-то не так с вычислением ADLER32 во втором случае (возможно, с некоторым переполнением)?

1 Ответ

1 голос
/ 26 апреля 2020

Это был переполнение в вычислении контрольной суммы ADLER32. В частности, были добавлены и усечены два 16-битных числа перед применением модуля по 65521. К сожалению, мой юнит-тест ADLER32 пока не уловил его.

Однако, сообщение об ошибке несколько раз отображалось во время реализации, и я всегда был не уверен в причине. Если кто-нибудь может разработать сообщение об ошибке или объяснить, как получить лучшее сообщение об ошибке, я был бы рад услышать его.

...