Implement a pure Rust PNG decoder in the image crate per RFC 2083 (PNG specification).
Requirements#
- Validate PNG signature (8-byte magic)
- Parse critical chunks: IHDR, IDAT, IEND, PLTE
- Parse ancillary chunks: tRNS (transparency)
- Support color types:
- 0: Grayscale
- 2: RGB
- 3: Indexed-color (palette)
- 4: Grayscale + Alpha
- 6: RGBA
- Bit depths: 1, 2, 4, 8, 16 (downconvert 16-bit to 8-bit)
- Scanline filtering: None, Sub, Up, Average, Paeth (reconstruct filtered rows)
- Interlacing: Adam7 (reorder passes into final image)
- Decompress IDAT chunks via zlib
- CRC-32 validation on chunks
- Output as RGBA8
Image - API:
fn decode_png(data: &[u8]) -> Result<Image, ImageError>
Acceptance Criteria#
- Decodes standard PNG test images (various color types, bit depths, interlacing)
- Handles tRNS transparency for palette and grayscale images
- Rejects corrupt PNGs (bad signature, CRC mismatch, invalid IHDR)
- Unit tests for each color type, filter type, and interlacing
- Integration tests with real PNG files
- No external dependencies, no
unsafe
Dependencies#
- Requires DEFLATE decompressor
- Requires zlib wrapper
- Requires pixel format types
Phase 7 — Image Decoders