hayro_syntax/filter/
mod.rs1mod ascii_85;
4mod ascii_hex;
5mod ccitt;
6mod dct;
7mod jbig2;
8mod jpx;
9mod lzw_flate;
10mod run_length;
11
12use crate::object::dict::Dict;
13use crate::object::dict::keys::*;
14use crate::object::name::Name;
15use crate::util::OptionLog;
16use log::warn;
17
18#[derive(Debug, Copy, Clone)]
20pub enum Filter {
21 AsciiHexDecode,
23 Ascii85Decode,
25 LzwDecode,
27 FlateDecode,
29 RunLengthDecode,
31 CcittFaxDecode,
33 Jbig2Decode,
35 DctDecode,
37 JpxDecode,
39 Crypt,
41}
42
43pub enum ImageColorSpace {
45 Gray,
47 Rgb,
49 Cmyk,
51}
52
53pub struct FilterResult {
55 pub data: Vec<u8>,
57 pub color_space: Option<ImageColorSpace>,
59 pub bits_per_component: Option<u8>,
61}
62
63impl FilterResult {
64 fn from_data(data: Vec<u8>) -> Self {
65 Self {
66 data,
67 color_space: None,
68 bits_per_component: None,
69 }
70 }
71}
72
73impl Filter {
74 fn debug_name(&self) -> &'static str {
75 match self {
76 Filter::AsciiHexDecode => "ascii_hex",
77 Filter::Ascii85Decode => "ascii_85",
78 Filter::LzwDecode => "lzw",
79 Filter::FlateDecode => "flate",
80 Filter::RunLengthDecode => "run-length",
81 Filter::CcittFaxDecode => "ccit_fax",
82 Filter::Jbig2Decode => "jbig2",
83 Filter::DctDecode => "dct",
84 Filter::JpxDecode => "jpx",
85 Filter::Crypt => "crypt",
86 }
87 }
88
89 pub(crate) fn from_name(name: &Name) -> Option<Self> {
90 match *name {
91 ASCII_HEX_DECODE | ASCII_HEX_DECODE_ABBREVIATION => Some(Filter::AsciiHexDecode),
92 ASCII85_DECODE | ASCII85_DECODE_ABBREVIATION => Some(Filter::Ascii85Decode),
93 LZW_DECODE | LZW_DECODE_ABBREVIATION => Some(Filter::LzwDecode),
94 FLATE_DECODE | FLATE_DECODE_ABBREVIATION => Some(Filter::FlateDecode),
95 RUN_LENGTH_DECODE | RUN_LENGTH_DECODE_ABBREVIATION => Some(Filter::RunLengthDecode),
96 CCITTFAX_DECODE | CCITTFAX_DECODE_ABBREVIATION => Some(Filter::CcittFaxDecode),
97 JBIG2_DECODE => Some(Filter::Jbig2Decode),
98 DCT_DECODE | DCT_DECODE_ABBREVIATION => Some(Filter::DctDecode),
99 JPX_DECODE => Some(Filter::JpxDecode),
100 CRYPT => Some(Filter::Crypt),
101 _ => {
102 warn!("unknown filter: {}", name.as_str());
103
104 None
105 }
106 }
107 }
108
109 pub fn apply(&self, data: &[u8], params: Dict) -> Option<FilterResult> {
111 match self {
112 Filter::AsciiHexDecode => ascii_hex::decode(data).map(FilterResult::from_data),
113 Filter::Ascii85Decode => ascii_85::decode(data).map(FilterResult::from_data),
114 Filter::RunLengthDecode => run_length::decode(data).map(FilterResult::from_data),
115 Filter::LzwDecode => lzw_flate::lzw::decode(data, params).map(FilterResult::from_data),
116 Filter::DctDecode => dct::decode(data, params).map(FilterResult::from_data),
117 Filter::FlateDecode => {
118 lzw_flate::flate::decode(data, params).map(FilterResult::from_data)
119 }
120 Filter::CcittFaxDecode => ccitt::decode(data, params).map(FilterResult::from_data),
121 Filter::Jbig2Decode => Some(FilterResult::from_data(jbig2::decode(data, params)?)),
122 Filter::JpxDecode => jpx::decode(data),
123 _ => None,
124 }
125 .error_none(&format!("failed to apply filter {}", self.debug_name()))
126 }
127}