So did Thorsten Lemke, author of GraphicConverter, also write his own DEFLATE compressor? ( No: see update below.) Anyway, putting the whole thing together: > import struct And indeed this is just what the zlib compression library outputs: > from binascii import hexlify The GraphicConverter encoding is clearly wasteful: the last two blocks contain no data and could be dropped if we made the first block the final block by changing the first byte to 63. \-first block-/\-second block-/ \-third block-/ġ0 1 = Huffman coding block with fixed codesĠ0000000 00000000 = number of data bytes in the block (that is, zero)ġ1111111 11111111 = one’s complement of number of data bytesġ0 * = Huffman coding block with fixed codes A DEFLATE stream is a little-endian bit stream. Now we can turn to the DEFLATE Compressed Data Format Specification (RFC 1951). PNG is big-endian, so the single pixel value of 0 appears in the high bit of the byte the remaining seven bits are unused (why they contain the value 4 is a bit of a mystery). What’s this pair of bytes? The section on scanline serialization in the PNG specification explains that the first byte, 00, is the filter type for the first scanline of the image (in this case 0 means “no filtering”) and the second byte, 04, contains the packed samples for pixels in the scanline. It’s easy to decompress the IDAT chunk in Python: > import zlib The informational byte 9c meaning “the default compression algorithm was used” (plus a checksum).The header byte 78 meaning “deflate compression with a 32 KiB window”.Specification (RFC 1950) we can decode this zlib stream as This is a zlib data stream of the scanlines from the image, compressed using the “DEFLATE” method. So any possibility for reduction must lie in the IDAT chunk. We can’t do anything about the size of the file signature or the IHDR and IEND chunks, or the chunk overhead, as these are fixed in size. You can see the location of the chunks clearly in the hex dump, because the ASCII chunk types stand out. A 0-byte IEND chunk marking the end of the file, plus 12 bytes chunk overhead.A 16-byte IDAT chunk containing the image data, plus 12 bytes chunk overhead.A 13-byte IHDR chunk containing the image header, plus 12 bytes chunk overhead.Referring to the PNG specification, those 73 bytes break down as follows: To see if this is the case, we have to look at GraphicConverter’s output in detail. The PNG standard has a fair bit of flexibility, so it might be the case that GraphicConverter is being wasteful in some way. Is that the answer? Unfortunately it’s not easy to be sure. Let’s get going by creating a 1×1 black-and-white image in GraphicConverter and save it as PNG. This discussion at drj11’s blog raises the question of how small is the smallest Portable Network Graphics (PNG) image? Starting out with general principles, it seems likely that we want the smallest possible image (PNG format doesn’t allow empty images, so it’s going to have to be 1×1), with the smallest number of colour channels (PNG supports greyscale images, with a single colour channel per pixel) and the smallest bit depth per channel (PNG supports 1-bit channels). ◀ Smart quotes in Emacs 22 ✴ ✴ Crash ▶Ī detailed look at the encoding of bitmap images in the PNG file format, leading up to the discovery of the smallest possible transparent PNG, only 67 bytes long.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |