Skip to main content

otf_pixels_codec_jpeg/
lib.rs

1//! JPEG codec for `otf-pixels`, implemented from scratch.
2//!
3//! Baseline JPEG — 8-bit samples, sequential DCT, Huffman coding — is decoded
4//! and encoded. Progressive JPEG is decoded too (ADR-0018): its scans fill a
5//! coefficient buffer that is then turned into pixels by the same path.
6//! Arithmetic coding, lossless, 12-bit and CMYK report
7//! [`PixelsError::Unsupported`].
8//!
9//! [`PixelsError::Unsupported`]: otf_pixels_core::PixelsError::Unsupported
10//!
11//! # Memory
12//!
13//! Decode is streaming, at one MCU row. A JPEG's entropy stream is a single
14//! run of bits with no per-row structure, but it is *ordered*: every block of
15//! MCU row `n` precedes every block of row `n + 1`. So the decoder keeps one
16//! band of component planes — 8 or 16 pixel rows — converts it to interleaved
17//! output, serves those rows, and reuses the band. Nothing scales with image
18//! height, which is what makes a thumbnail of a 24 MP photograph affordable.
19//!
20//! # Safety
21//!
22//! Every parser here reads attacker-controlled bytes. Malformed input is a
23//! value, never a panic: `unsafe_code = "forbid"` and the workspace's ban on
24//! `unwrap`/`expect`/`panic!` mean the classic decoder failures — a Huffman
25//! table indexing past its symbols, an MCU count overflowing, a block written
26//! outside its plane — are unrepresentable rather than merely avoided.
27
28mod decoder;
29mod encoder;
30mod entropy;
31mod fdct;
32mod format;
33mod huffman;
34mod idct;
35mod progressive;
36mod progressive_encode;
37mod tables;
38
39pub use decoder::{JpegCodec, JpegDecoder, probe};
40pub use encoder::{JpegEncoder, Subsampling};
41pub use format::{Component, Frame, SIGNATURE, Scan, ScanComponent};
42pub use idct::Scale;