Skip to main content

oxideav_tiff/
lib.rs

1//! Pure-Rust TIFF 6.0 image decoder + encoder + container.
2//!
3//! Implements the *Aldus TIFF Revision 6.0 (June 1992)* baseline plus
4//! the universally-deployed Part 2 extensions (LZW with optional
5//! horizontal-differencing predictor; Adobe Deflate; YCbCr / CMYK
6//! photometrics; tiles), the multi-IFD chain (multi-page), the
7//! Adobe Pagemaker 6.0 *BigTIFF* design (8-byte offsets, magic 43),
8//! and the de-facto registry extension Compression = 50000
9//! (Zstandard).
10//! Spec-only clean-room: no external library source was consulted at
11//! any point.
12//!
13//! Decode-side coverage:
14//!
15//! * Byte order: `II` (little-endian) and `MM` (big-endian)
16//! * Variants: classic TIFF (32-bit offsets) + BigTIFF (64-bit offsets)
17//! * Photometric: WhiteIsZero / BlackIsZero / RGB / Palette / CMYK /
18//!   YCbCr / TransparencyMask / CIELab (3-sample L*a*b* and 1-sample
19//!   L*-only, TIFF 6.0 §23, decoded to display Rgb24 / Gray8 via
20//!   Lab → XYZ@D65 → linear NTSC RGB → sRGB)
21//! * Bit depths: 1, 4, 8, 16 (per-strip and per-tile)
22//! * Compression: 1 None / 2 CCITT Modified Huffman / 3 CCITT T.4
23//!   (1-D and 2-D) / 4 CCITT T.6 / 32773 PackBits / 5 LZW /
24//!   8 Deflate (zlib) / 50000 Zstandard (de-facto registry
25//!   extension; one RFC 8478 frame per strip or tile) /
26//!   7 JPEG-in-TIFF (TIFF Tech Note 2; routes each strip/tile through
27//!   `oxideav-mjpeg`)
28//! * Predictor: 1 (none) and 2 (horizontal differencing,
29//!   per-component for SamplesPerPixel > 1)
30//! * Strip OR tile layout
31//! * Multi-page (full next-IFD chain walk via [`decode_tiff_all`])
32//!
33//! Encode-side coverage (classic II / single or multi page):
34//!
35//! * Photometric: WhiteIsZero (1-bit bilevel) / BlackIsZero (8/16-bit
36//!   greyscale) / RGB (8-bit) / Palette (8-bit indexed) /
37//!   TransparencyMask (1-bit, sets PhotometricInterpretation = 4 and
38//!   NewSubfileType bit 2 per TIFF 6.0 §"PhotometricInterpretation"
39//!   value 4 + §"NewSubfileType" bit 2) / CIELab (8-bit chunky
40//!   `(L*, a*, b*)` and 1-sample L*-only, PhotometricInterpretation = 8
41//!   per TIFF 6.0 §23 "CIE L*a*b* Images") / CMYK (8-bit chunky
42//!   `(C, M, Y, K)`, PhotometricInterpretation = 5 per TIFF 6.0 §16
43//!   "CMYK Images") / YCbCr (8-bit chunky `(Y, Cb, Cr)` at
44//!   `YCbCrSubSampling = [1, 1]` chunky 4:4:4,
45//!   PhotometricInterpretation = 6 per TIFF 6.0 §21 "YCbCr Images")
46//! * Compression: None / PackBits / LZW / Deflate / Zstandard
47//!   (Compression=50000) / CCITT Modified Huffman (Compression=2) /
48//!   CCITT T.4 1-D and 2-D (Compression=3, with optional T4Options
49//!   bit 2 byte-aligned EOLs) / CCITT T.6 (Compression=4)
50//! * Layout: single strip, `PlanarConfiguration = 2` (separate planes,
51//!   chunky-source), or tiled (TIFF 6.0 §15, chunky) — see
52//!   [`EncodePage::planar`] / [`EncodePage::tiling`]
53//! * Predictor: 2 (horizontal differencing) via [`EncodePage::predictor`]
54//! * Multi-page chain via [`encode_tiff_multi`]
55//!
56//! Out of scope for this round (next-round backlog): the deprecated
57//! TIFF 6.0 §22 old-style JPEG (Compression=6) and encode-side
58//! JPEG-in-TIFF (Compression=7). YCbCr encode is currently
59//! `YCbCrSubSampling = [1, 1]` chunky 4:4:4 only; the
60//! chroma-subsampled writes (`[2, 1]` / `[2, 2]` / `[4, 1]` /
61//! `[4, 2]` / `[1, 2]`) and the YCbCr planar / tiled / predictor
62//! compositions are deferred — the §21 "Ordering of Component
63//! Samples" data-unit shape changes under non-1:1 subsampling and
64//! needs the dedicated packer. Decode-side Compression=7 (new-style
65//! JPEG-in-TIFF, per TIFF Tech Note 2) is implemented as of round 92.
66//!
67//! ## Standalone vs registry-integrated
68//!
69//! The crate's default `registry` Cargo feature pulls in `oxideav-core`
70//! and exposes the `Decoder` trait surface, the TIFF container
71//! demuxer/probe, and the [`registry::register`] entry point. Disable
72//! the feature (`default-features = false`) for an oxideav-core-free
73//! build that still exposes the standalone [`decode_tiff`] API plus
74//! [`TiffImage`] / [`TiffPixelFormat`] / [`TiffPlane`] / [`TiffError`]
75//! types — none of which depend on `oxideav-core`.
76
77pub mod ccitt;
78pub mod compress;
79pub mod decoder;
80pub mod encoder;
81pub mod error;
82pub mod ifd;
83pub mod image;
84pub mod types;
85
86#[cfg(feature = "registry")]
87pub mod container;
88
89#[cfg(feature = "registry")]
90pub mod jpeg;
91
92#[cfg(feature = "registry")]
93pub mod registry;
94
95/// Codec id for TIFF image frames.
96pub const CODEC_ID_STR: &str = "tiff";
97
98// Standalone, framework-free API. Available regardless of the
99// `registry` feature.
100pub use decoder::{decode_tiff, decode_tiff_all, DecodedTiff};
101pub use encoder::{
102    encode_tiff, encode_tiff_multi, EncodePage, EncodePixelFormat, RgbColor, TiffCompression,
103};
104pub use error::{Result, TiffError};
105pub use image::{TiffImage, TiffPixelFormat, TiffPlane};
106
107// Framework-integrated API (`oxideav-core`-dependent). Gated behind
108// `registry` so image-library callers can build the crate without
109// dragging in `oxideav-core`.
110#[cfg(feature = "registry")]
111pub use registry::{make_decoder, register, register_codecs, register_containers};