【发布时间】:2018-07-09 09:32:40
【问题描述】:
我正在尝试使用 Fixed Huffman 在 python 中编写自己的 deflate 实现。当我将图像打包回 .png 文件时,常规图像查看器中不会显示任何内容。每个块头都是根据 RFC-1950 的规范形成的。
我使用 pngcheck 来找出图像没有显示任何内容的原因并返回了这两条消息:
zlib:压缩头校验和失败
zlib: inflate_error = -3
对于 Adler32 值,我将其计算为 zlib.adler32(bytearray(scanline))。让我感到困惑的另一件事是压缩流的字节顺序,我不完全确定如何将固定的 Huffman 代码位打包到字节中,我知道它是在 RFC-1951 中指定的。
#zLibHeaderArray = bytearray([CMF,FLG])
zLibHeaderArray = bytearray([78,1])
outputPNG.write(zLibHeaderArray)
#First three bits per block
outputBitStream = ba.bitarray(endian = 'big')
if(isLast != 1):
outputBitStream += ba.bitarray('001')
else:
outputBitStream += ba.bitarray('101')
#-- here i transform the input scanline with lz77 and huffman and load it into the big endian bitarray
outputBitStream += ba.bitarray(getHuffman(256,huffman))
outputBitStream.tofile(outputPNG)
#Adler32 Checksum
adler32Value = zlib.adler32(bytearray(scanline))
a1, a2, a3, a4 = (adler32Value & 0xFFFFFFFF).to_bytes(4, 'big')
adler32Array = bytearray([a1,a2,a3,a4])
outputPNG.write(adler32Array)
CRC 不会导致 iDAT 块出错,所以我最好的猜测是 Adler32 校验和。
【问题讨论】:
-
"scanline" 是我通过应用过滤器 + 将过滤器值附加到过滤后的像素得到的未压缩数据
-
你说得对,我错过了!但我确实希望你正确地构建了这个
scanline。请注意,即使您没有这样做,这也不是“最佳”答案,因为 zlib 不在乎并且应该可以工作。
标签: python compression png zlib deflate