Skip to main content

otf_pixels_codec_tiff/
lib.rs

1//! TIFF codec for `otf-pixels`, implemented from scratch.
2//!
3//! Baseline TIFF 6.0: both byte orders, strip and tile layouts, none/LZW/
4//! Deflate/PackBits compression, greyscale/RGB/palette photometrics at 1, 8
5//! and 16 bits. Exotic tags are skipped rather than treated as errors, which
6//! SPEC §Formats requires and TIFF's extensibility makes essential.
7//!
8//! # Why TIFF is the streaming showcase
9//!
10//! A *tiled* TIFF stores its pixels as an array of independently compressed
11//! rectangles, each with its own offset. That makes it the one v1 format
12//! capable of genuine random access: producing an arbitrary region means
13//! decompressing the tiles it touches and nothing else.
14//!
15//! So [`TiffDecoder`] reports [`DecodeCapability::Regions`] for a tiled file,
16//! and the scheduler pulls regions rather than rows. Turning a 2 GB tiled
17//! scan into a thumbnail then costs the tiles the thumbnail actually needs —
18//! which is what ADR-0001's demand-driven design was for, and what the rest of
19//! v1 has been building toward.
20//!
21//! [`DecodeCapability::Regions`]: otf_pixels_core::DecodeCapability::Regions
22
23mod decoder;
24mod encoder;
25mod ifd;
26mod image;
27
28pub use decoder::{TiffCodec, TiffDecoder, probe};
29pub use encoder::{TiffEncoder, TiffLayout};
30pub use ifd::{ByteOrder, Directory, tag};
31pub use image::{Compression, Layout, Photometric, TiffImage};
32
33/// Translate a compression failure into this crate's error type.
34///
35/// `otf-pixels-compress` deliberately does not depend on `otf-pixels-core`
36/// (ADR-0012), so the mapping lives here, where the format context is known.
37pub(crate) fn compress_error(error: otf_pixels_compress::Error) -> otf_pixels_core::PixelsError {
38    otf_pixels_core::PixelsError::malformed("tiff", error.detail().to_owned())
39}