Good page. If I can I would also add a filtered image (or a set of them, if interlaced) to illustrate how PNG filters work.
> The main reason to have multiple IDATs is if the encoder software wants to keep memory usage low and not need to buffer the entire IDAT, which is required just to know the final length of the chunk before starting to write the chunk.
It should be noted that this is only true for streaming applications where they have no chance to fix the length field already written.
> For example, outputting every DEFLATE symbol, every pixel value, or even every palette value, would be very verbose and probably not helpful.
I have some idea for the visualization, but one possibility is to show a list of DEFLATE blocks. zlib tries to break blocks when applicable as a sort of adaptive compression so it might be interesting to see overall changes in the image triggering new blocks. I've written a function to list blocks and their overheads (to encode Huffman trees), which is now a part of the Roadroller packer [1].
I’m always a fan of anything that helps people understand the contents of the binary files that are slung about the Internet.
I realize you mentioned you decided not to parse any metadata found in the file. However, metadata can be such a window into the file, I’d really encourage you to extend the site to accommodate it.
Thanks, I agree with having accessible tools to dissect binary file formats. I'm not sure what you mean by "decided not to parse any metadata", care to elaborate? I implemented the parsing of almost all native PNG metadata chunks because they're concisely described in the official specification. I currently don't parse iCCP or eXIf because they will require reading more long external specifications. I don't parse IDAT (but might soon) because decompressing all the image data could use enough CPU time to have a perceptible lag.
This is one of those awkward parts of the standard, the samples always take up 16 bits and decoders are expected to mask off the extra high bits, any 16-bit value was supposed to be considered valid. In the real world trash values are often written for transparency (tRNS) chunks that inadvertently match samples in the image when the extra bits are masked off, which leads to random holes in the image. In practice those chunks have to be ignored when the values are out-of-range for the given bit depth.
It makes sense to treat it as an error but the ISO standard is too vague on this and the libpng developers never "fixed" this[1], it issues a warning but otherwise just masks off the high bits. Firefox has a workaround[2][3], Chrome doesn't.
FWIW I do the same in my library[4], handling it as an error is problematic because it would mean the chunk gets discarded and then you can't even retrieve the values.
Mine is web-based, written in a memory-safe language, no need to download and run a local executable, supports OSes other than Windows, thousands less lines of code, but read-only. Thanks for mentioning TweakPNG though; I think I'll link to it as another resource.
I looked at your code and it's written in typescript, but I have a thing written in jQuery whitch floats the table headers that your website really needs. You can probably use position:fixed too.
For anyone who wants to implement this, please _don't_ implement it like the GIF. <https://github.com/mkoryak/floatThead/blob/master/README.md> Instead, do what mobile web browsers do, where the header is automatically revealed and overlaid onto the content when scrolling up. On desktop, you can make it so the headers are also revealed when mousing around over the relevant data. But indiscriminately reducing the size of the viewport by going sticky is incredibly annoying.
It is a problem[1][2]. Desktop is the only use case I even had in mind. I only threw in the mobile/desktop mention in order to reference what mobile browsers do with the address bar and a last minute thought about how the availability of a mouse pointer presents the opportunity to add a little polish. Sticky headers, whether on mobile or desktop, are worse than animated banners.
> The main reason to have multiple IDATs is if the encoder software wants to keep memory usage low and not need to buffer the entire IDAT, which is required just to know the final length of the chunk before starting to write the chunk.
It should be noted that this is only true for streaming applications where they have no chance to fix the length field already written.
> For example, outputting every DEFLATE symbol, every pixel value, or even every palette value, would be very verbose and probably not helpful.
I have some idea for the visualization, but one possibility is to show a list of DEFLATE blocks. zlib tries to break blocks when applicable as a sort of adaptive compression so it might be interesting to see overall changes in the image triggering new blocks. I've written a function to list blocks and their overheads (to encode Huffman trees), which is now a part of the Roadroller packer [1].
[1] https://github.com/lifthrasiir/roadroller/blob/main/deflate....