Skip to main content

otf_pixels_codec_png/
lib.rs

1//! PNG codec for `otf-pixels`, implemented from scratch.
2//!
3//! Includes its own DEFLATE implementation per ADR-0010: PNG *is* mostly
4//! DEFLATE, so depending on a compression crate would reduce "PNG from
5//! scratch" to "PNG container parsing from scratch".
6//!
7//! Every parser here reads attacker-controlled bytes and returns errors rather
8//! than panicking. `unsafe_code = "forbid"` means the classic decompressor
9//! failure — an out-of-bounds write through a back-reference — is
10//! unrepresentable rather than merely avoided.
11
12mod decoder;
13mod encoder;
14mod format;
15
16pub use decoder::{PngCodec, PngDecoder, probe};
17pub use encoder::PngEncoder;
18pub use format::{ColorType, Filter, Header, SIGNATURE};
19
20// Re-exported rather than defined here: ADR-0012 moved the compression
21// primitives to `otf-pixels-compress` once TIFF and GIF became consumers of
22// them. They stay in this crate's public surface so nothing downstream breaks.
23pub use otf_pixels_compress::{
24    Adler32, Crc32, Inflater, Level, ZlibStream, deflate, inflate_to, zlib_compress,
25    zlib_decompress,
26};
27
28/// Translate a compression failure into this crate's error type.
29///
30/// `otf-pixels-compress` deliberately does not depend on `otf-pixels-core`
31/// (ADR-0012), so the mapping to a stable [`ErrorCode`] lives here, where the
32/// format context is known.
33///
34/// [`ErrorCode`]: otf_pixels_core::ErrorCode
35pub(crate) fn compress_error(error: otf_pixels_compress::Error) -> otf_pixels_core::PixelsError {
36    otf_pixels_core::PixelsError::malformed(error.format(), error.detail().to_owned())
37}