image-rs / image-png

PNG decoding and encoding library in pure Rust
https://docs.rs/png
Apache License 2.0
357 stars 140 forks source link

Fix chunk type output #319

Closed MichaelMcDonnell closed 2 years ago

MichaelMcDonnell commented 2 years ago

If you try to use the pngcheck example to list the chunk types in a PNG file then you get an output that is very noisy and difficult to read. For example, if you run the following command:

$ cargo run --example pngcheck -- -v tests/pngsuite/basi0g01.png

Then you get the following noisy output:

File: tests/pngsuite/basi0g01.png (10240) bytes
  chunk ChunkType { type: EscapeDebug(EscapeDefault { state: Char('I') })EscapeDebug(EscapeDefault { state: Char('H') })EscapeDebug(EscapeDefault { state: Char('D') })EscapeDebug(EscapeDefault { state: Char('R') }), critical: true, private: false, reserved: false, safecopy: false } at offset 0x0000c, length 13
    32 x 32 image, 1-bit grayscale, interlaced
  chunk ChunkType { type: EscapeDebug(EscapeDefault { state: Char('g') })EscapeDebug(EscapeDefault { state: Char('A') })EscapeDebug(EscapeDefault { state: Char('M') })EscapeDebug(EscapeDefault { state: Char('A') }), critical: false, private: false, reserved: false, safecopy: false } at offset 0x00025, length 4
  chunk ChunkType { type: EscapeDebug(EscapeDefault { state: Char('I') })EscapeDebug(EscapeDefault { state: Char('D') })EscapeDebug(EscapeDefault { state: Char('A') })EscapeDebug(EscapeDefault { state: Char('T') }), critical: true, private: false, reserved: false, safecopy: false } at offset 0x00035, length 144
  chunk ChunkType { type: EscapeDebug(EscapeDefault { state: Char('I') })EscapeDebug(EscapeDefault { state: Char('E') })EscapeDebug(EscapeDefault { state: Char('N') })EscapeDebug(EscapeDefault { state: Char('D') }), critical: true, private: false, reserved: false, safecopy: false } at offset 0x000d1, length 0
No errors detected in tests/pngsuite/basi0g01.png (4 chunks, 7.7% compression)

Notice how the type field contains a lot of information that is not useful in this context. I think this is a regression that was introduced inadvertently with pull request #248. The code is using the Debug implementation to print the escaped characters instead of the Display implementation. I think the intention was to print the escaped characters themselves and not a debug representation.

If the Display implementation is used instead to print the escaped characters then the chunk type becomes clear when running pngcheck:

File: tests/pngsuite/basi0g01.png (10240) bytes
  chunk ChunkType { type: IHDR, critical: true, private: false, reserved: false, safecopy: false } at offset 0x0000c, length 13
    32 x 32 image, 1-bit grayscale, interlaced
  chunk ChunkType { type: gAMA, critical: false, private: false, reserved: false, safecopy: false } at offset 0x00025, length 4
  chunk ChunkType { type: IDAT, critical: true, private: false, reserved: false, safecopy: false } at offset 0x00035, length 144
  chunk ChunkType { type: IEND, critical: true, private: false, reserved: false, safecopy: false } at offset 0x000d1, length 0
No errors detected in tests/pngsuite/basi0g01.png (4 chunks, 7.7% compression)

Now the chunk types show as IHDR, gAMA, IDAT, and IEND.

MichaelMcDonnell commented 2 years ago

Thanks!