0
votes

I'm trying to write my own deflate implementation in python with Fixed Huffman. When I pack the image back into the .png file nothing is being displayed in a regular image viewer. Each chunk header is formed according to the specification from the RFC-1950. I have used pngcheck to find out why the image wasn't displaying anything and got these 2 messages back:

zlib: compression header fails checksum

zlib: inflate_error = -3

For the Adler32 value I calculated it like zlib.adler32(bytearray(scanline)). One more thing that confuses me is the endianness of the compressed stream and I'm not entirely sure on how to pack the fixed Huffman code bits inside the bytes, I know that it is specified in 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)

The CRC isn't causing errors for the iDAT chunk so my best guess is the Adler32 checksum.

1
"scanline" is the uncompressed data which i got by applying the filter + appending the filter value to the filtered pixelsDiligent Hero
You are right, I missed that! But I do hope you constructed this scanline correct. Mind you, even if you did not, it's not "the" answer, as zlib doesn't care and ought to work.Jongware

1 Answers

2
votes

You should carefully read error messages. "compression header fails checksum" indicates that it is the zlib header that is incorrect, not the trailer which is the Adler-32. That two-byte header includes a five-bit check value that is not properly set in your stream. (Or maybe you forgot the header completely.)