Skip to main content

hayro_syntax/filter/
mod.rs

1//! Results from decoding filtered data streams.
2
3mod ascii_85;
4pub(crate) mod ascii_hex;
5#[cfg(feature = "images")]
6mod ccitt;
7#[cfg(feature = "images")]
8mod dct;
9#[cfg(feature = "images")]
10mod jbig2;
11#[cfg(feature = "images")]
12mod jpx;
13mod lzw_flate;
14mod png;
15mod run_length;
16
17use crate::object::Dict;
18use crate::object::Name;
19use crate::object::dict::keys::*;
20use crate::object::stream::{DecodeFailure, FilterResult, ImageDecodeParams};
21use core::ops::Deref;
22
23/// A data filter.
24#[derive(Debug, Copy, Clone, PartialEq, Eq)]
25pub enum Filter {
26    /// ASCII hexadecimal encoding.
27    AsciiHexDecode,
28    /// ASCII base-85 encoding.
29    Ascii85Decode,
30    /// Lempel-Ziv-Welch (LZW) compression.
31    LzwDecode,
32    /// DEFLATE compression (zlib/gzip).
33    FlateDecode,
34    /// Run-length encoding compression.
35    RunLengthDecode,
36    /// CCITT Group 3 or Group 4 fax compression.
37    CcittFaxDecode,
38    /// JBIG2 compression for bi-level images.
39    Jbig2Decode,
40    /// JPEG (DCT) compression.
41    DctDecode,
42    /// JPEG 2000 compression.
43    JpxDecode,
44    /// Encryption filter.
45    Crypt,
46}
47
48impl Filter {
49    pub(crate) fn from_name(name: Name<'_>) -> Option<Self> {
50        match name.deref() {
51            ASCII_HEX_DECODE | ASCII_HEX_DECODE_ABBREVIATION => Some(Self::AsciiHexDecode),
52            ASCII85_DECODE | ASCII85_DECODE_ABBREVIATION => Some(Self::Ascii85Decode),
53            LZW_DECODE | LZW_DECODE_ABBREVIATION => Some(Self::LzwDecode),
54            FLATE_DECODE | FLATE_DECODE_ABBREVIATION => Some(Self::FlateDecode),
55            RUN_LENGTH_DECODE | RUN_LENGTH_DECODE_ABBREVIATION => Some(Self::RunLengthDecode),
56            CCITTFAX_DECODE | CCITTFAX_DECODE_ABBREVIATION => Some(Self::CcittFaxDecode),
57            JBIG2_DECODE => Some(Self::Jbig2Decode),
58            DCT_DECODE | DCT_DECODE_ABBREVIATION => Some(Self::DctDecode),
59            JPX_DECODE => Some(Self::JpxDecode),
60            CRYPT => Some(Self::Crypt),
61            _ => None,
62        }
63    }
64
65    pub(crate) fn apply(
66        &self,
67        data: &[u8],
68        params: &Dict<'_>,
69        #[cfg_attr(not(feature = "images"), allow(unused))] image_params: &ImageDecodeParams,
70    ) -> Result<FilterResult<'static>, DecodeFailure> {
71        match self {
72            Self::AsciiHexDecode => ascii_hex::decode(data)
73                .map(FilterResult::from_data)
74                .ok_or(DecodeFailure::StreamDecode),
75            Self::Ascii85Decode => ascii_85::decode(data)
76                .map(FilterResult::from_data)
77                .ok_or(DecodeFailure::StreamDecode),
78            Self::RunLengthDecode => run_length::decode(data)
79                .map(FilterResult::from_data)
80                .ok_or(DecodeFailure::StreamDecode),
81            Self::LzwDecode => lzw_flate::lzw::decode(data, params)
82                .map(FilterResult::from_data)
83                .ok_or(DecodeFailure::StreamDecode),
84            Self::FlateDecode => lzw_flate::flate::decode(data, params)
85                .map(FilterResult::from_data)
86                .ok_or(DecodeFailure::StreamDecode),
87            #[cfg(feature = "images")]
88            Self::DctDecode => {
89                dct::decode(data, params, image_params).ok_or(DecodeFailure::ImageDecode)
90            }
91            #[cfg(feature = "images")]
92            Self::CcittFaxDecode => {
93                ccitt::decode(data, params, image_params).ok_or(DecodeFailure::ImageDecode)
94            }
95            #[cfg(feature = "images")]
96            Self::Jbig2Decode => {
97                jbig2::decode(data, params, image_params).ok_or(DecodeFailure::ImageDecode)
98            }
99            #[cfg(feature = "images")]
100            Self::JpxDecode => jpx::decode(data, image_params).ok_or(DecodeFailure::ImageDecode),
101            #[cfg(not(feature = "images"))]
102            Self::DctDecode | Self::CcittFaxDecode | Self::Jbig2Decode | Self::JpxDecode => {
103                Err(DecodeFailure::ImageDecode)
104            }
105            _ => Err(DecodeFailure::StreamDecode),
106        }
107    }
108}