You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义Python Deflate实现(固定霍夫曼)PNG显示异常排查

Troubleshooting zlib Header & Inflate Errors in Custom Deflate-PNG Implementation

Let's break down the issues causing your pngcheck errors and address your questions step by step:

1. Zlib Header Checksum Failure

Your zlib header [78, 1] (CMF=78, FLG=1) violates the RFC 1950 requirement that (CMF * 256 + FLG) must be divisible by 31. This is the direct cause of the header checksum failure.

  • Calculate the correct FLG value:
    • CMF=78 → 78 * 256 = 19968
    • 19968 % 31 = 4 (since 31 × 644 = 19964)
    • FLG needs to be 31 - 4 = 27 (0x1B in hex) to make the total sum a multiple of 31: 19968 + 27 = 19995 = 31 × 645
  • Update your header to bytearray([78, 27]) to fix this checksum error.

2. Incorrect Adler32 Calculation

Zlib's Adler32 checksum is computed over the entire uncompressed data stream, not just a single scanline. Your current code only calculates the checksum for one scanline, which guarantees a mismatch with the decompressor's expected value.

  • Fix this by accumulating the checksum across all scanlines:
    # Initialize Adler32 with the required starting value of 1
    adler32Value = 1
    for scanline in all_scanlines:
        # Process the scanline (LZ77 + Huffman encoding)
        # ...
        # Update Adler32 with the current uncompressed scanline
        adler32Value = zlib.adler32(bytearray(scanline), adler32Value)
    # After processing all scanlines, write the final big-endian checksum
    adler32Array = bytearray((adler32Value & 0xFFFFFFFF).to_bytes(4, 'big'))
    outputPNG.write(adler32Array)
    
  • Note: Your byte order for storing Adler32 is correct (big-endian), but the accumulated value itself was wrong.

3. Bit Packing Endianness Mistake

RFC 1951 (Deflate) specifies that bits are packed into bytes least significant bit (LSB) first. Your use of endian='big' in the bitarray reverses this order, corrupting the compressed bitstream and leading to inflate_error = -3.

  • Switch to endian='little' when creating your bitarray to match Deflate's rules:
    outputBitStream = ba.bitarray(endian='little')
    
  • This ensures the first bit in your bitarray is stored as the LSB of the first byte, which is how Deflate expects bits to be ordered.

4. Quick Block Header Sanity Check

Your block header logic (001 for non-final blocks, 101 for final blocks) is correct for fixed Huffman encoding (BTYPE=01):

  • First bit = BFINAL (0 = not final, 1 = final)
  • Next two bits = BTYPE (01 = fixed Huffman)
    Just confirm this bit sequence is packed correctly with the LSB-first endianness fix above.

Final Notes

After fixing these issues, re-run pngcheck to verify the zlib header and inflate errors are resolved. If problems persist, double-check that your fixed Huffman encoding correctly emits the end-of-block code (256) and that your LZ77 output is properly formatted for Huffman encoding.

内容的提问来源于stack exchange,提问作者Diligent Hero

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:34:51