Skip to main content

djvu_bzz/
lib.rs

1//! BZZ compressor and decompressor for DjVu documents.
2//!
3//! BZZ combines ZP adaptive arithmetic coding, move-to-front coding, and the
4//! Burrows-Wheeler transform. DjVu uses it for compressed metadata chunks such
5//! as DIRM, NAVM, ANTz, TXTz, and FGbz.
6
7#![cfg_attr(not(feature = "std"), no_std)]
8#![deny(unsafe_code)]
9
10#[cfg(not(feature = "std"))]
11extern crate alloc;
12
13mod decode;
14#[cfg(feature = "std")]
15mod encode;
16
17#[cfg(feature = "parallel")]
18pub use decode::bzz_decode_parallel;
19pub use decode::{bzz_decode, decode};
20#[cfg(feature = "std")]
21pub use encode::bzz_encode;
22
23/// BZZ compression decoding errors.
24#[derive(Debug, thiserror::Error, PartialEq, Eq)]
25#[non_exhaustive]
26pub enum BzzError {
27    /// Input is too short to be a valid BZZ stream (fewer than 2 bytes).
28    #[error("BZZ input is too short")]
29    TooShort,
30
31    /// The block size field in the BZZ stream is invalid or out of range.
32    #[error("BZZ stream contains an invalid block size")]
33    InvalidBlockSize,
34
35    /// The BWT sort index embedded in the stream is out of range.
36    #[error("BZZ stream contains an invalid BWT index")]
37    InvalidBwtIndex,
38
39    /// The ZP arithmetic coder encountered an error.
40    #[error("ZP coder error in BZZ stream")]
41    ZpError,
42
43    /// The BWT block did not contain an end-of-block marker.
44    #[error("BZZ block is missing the end-of-block marker")]
45    MissingMarker,
46
47    /// A single block's decoded size exceeds the safety limit (4 MB).
48    #[error("BZZ block size exceeds maximum allowed ({0} > 4 MB)")]
49    BlockSizeTooLarge(usize),
50
51    /// The total decompressed output exceeds the safety limit (256 MB).
52    #[error("BZZ total output size exceeds maximum allowed (256 MB)")]
53    OutputTooLarge,
54
55    /// The ZP coder ran past the real input and is decoding synthetic
56    /// padding as if it were data (a truncated or hostile stream).
57    #[error("BZZ stream is truncated (decoder is spinning on synthetic padding)")]
58    Truncated,
59}
60
61/// Map ZP-coder init errors into [`BzzError`] so callers using `?` keep working.
62impl From<djvu_zp::ZpError> for BzzError {
63    fn from(_: djvu_zp::ZpError) -> Self {
64        BzzError::TooShort
65    }
66}