/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tiff-0.11.3/src/decoder/stream.rs
Line | Count | Source |
1 | | //! All IO functionality needed for TIFF decoding |
2 | | #[cfg(feature = "webp")] |
3 | | use std::io::Cursor; |
4 | | use std::io::{self, BufRead, BufReader, Read, Seek, Take}; |
5 | | |
6 | | pub use crate::tags::ByteOrder; |
7 | | |
8 | | /// Reader that is aware of the byte order. |
9 | | #[derive(Debug)] |
10 | | pub struct EndianReader<R> { |
11 | | reader: R, |
12 | | pub(crate) byte_order: ByteOrder, |
13 | | } |
14 | | |
15 | | impl<R: Read> EndianReader<R> { |
16 | 154k | pub fn new(reader: R, byte_order: ByteOrder) -> Self { |
17 | 154k | Self { reader, byte_order } |
18 | 154k | } <tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<&[u8]>>>::new Line | Count | Source | 16 | 19.8k | pub fn new(reader: R, byte_order: ByteOrder) -> Self { | 17 | 19.8k | Self { reader, byte_order } | 18 | 19.8k | } |
<tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::new Line | Count | Source | 16 | 134k | pub fn new(reader: R, byte_order: ByteOrder) -> Self { | 17 | 134k | Self { reader, byte_order } | 18 | 134k | } |
|
19 | | |
20 | 544k | pub fn inner(&mut self) -> &mut R { |
21 | 544k | &mut self.reader |
22 | 544k | } <tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<&[u8]>>>::inner Line | Count | Source | 20 | 544k | pub fn inner(&mut self) -> &mut R { | 21 | 544k | &mut self.reader | 22 | 544k | } |
Unexecuted instantiation: <tiff::decoder::stream::EndianReader<_>>::inner |
23 | | |
24 | 79.4k | pub fn goto_offset(&mut self, offset: u64) -> io::Result<()> |
25 | 79.4k | where |
26 | 79.4k | R: Seek, |
27 | | { |
28 | 79.4k | self.reader.seek(io::SeekFrom::Start(offset))?; |
29 | 79.4k | Ok(()) |
30 | 79.4k | } <tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<&[u8]>>>::goto_offset Line | Count | Source | 24 | 79.4k | pub fn goto_offset(&mut self, offset: u64) -> io::Result<()> | 25 | 79.4k | where | 26 | 79.4k | R: Seek, | 27 | | { | 28 | 79.4k | self.reader.seek(io::SeekFrom::Start(offset))?; | 29 | 79.4k | Ok(()) | 30 | 79.4k | } |
Unexecuted instantiation: <tiff::decoder::stream::EndianReader<_>>::goto_offset |
31 | | |
32 | | /// Reads an u16 |
33 | | #[inline(always)] |
34 | 3.73M | pub fn read_u16(&mut self) -> Result<u16, io::Error> { |
35 | 3.73M | let mut n = [0u8; 2]; |
36 | 3.73M | self.reader.read_exact(&mut n)?; |
37 | 3.73M | Ok(match self.byte_order { |
38 | 3.47M | ByteOrder::LittleEndian => u16::from_le_bytes(n), |
39 | 253k | ByteOrder::BigEndian => u16::from_be_bytes(n), |
40 | | }) |
41 | 3.73M | } <tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<&[u8]>>>::read_u16 Line | Count | Source | 34 | 3.63M | pub fn read_u16(&mut self) -> Result<u16, io::Error> { | 35 | 3.63M | let mut n = [0u8; 2]; | 36 | 3.63M | self.reader.read_exact(&mut n)?; | 37 | 3.63M | Ok(match self.byte_order { | 38 | 3.38M | ByteOrder::LittleEndian => u16::from_le_bytes(n), | 39 | 251k | ByteOrder::BigEndian => u16::from_be_bytes(n), | 40 | | }) | 41 | 3.63M | } |
<tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::read_u16 Line | Count | Source | 34 | 94.7k | pub fn read_u16(&mut self) -> Result<u16, io::Error> { | 35 | 94.7k | let mut n = [0u8; 2]; | 36 | 94.7k | self.reader.read_exact(&mut n)?; | 37 | 94.7k | Ok(match self.byte_order { | 38 | 93.1k | ByteOrder::LittleEndian => u16::from_le_bytes(n), | 39 | 1.66k | ByteOrder::BigEndian => u16::from_be_bytes(n), | 40 | | }) | 41 | 94.7k | } |
Unexecuted instantiation: <tiff::decoder::stream::EndianReader<_>>::read_u16 |
42 | | |
43 | | /// Reads an i16 |
44 | | #[inline(always)] |
45 | 14 | pub fn read_i16(&mut self) -> Result<i16, io::Error> { |
46 | 14 | let mut n = [0u8; 2]; |
47 | 14 | self.reader.read_exact(&mut n)?; |
48 | 14 | Ok(match self.byte_order { |
49 | 12 | ByteOrder::LittleEndian => i16::from_le_bytes(n), |
50 | 2 | ByteOrder::BigEndian => i16::from_be_bytes(n), |
51 | | }) |
52 | 14 | } <tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::read_i16 Line | Count | Source | 45 | 14 | pub fn read_i16(&mut self) -> Result<i16, io::Error> { | 46 | 14 | let mut n = [0u8; 2]; | 47 | 14 | self.reader.read_exact(&mut n)?; | 48 | 14 | Ok(match self.byte_order { | 49 | 12 | ByteOrder::LittleEndian => i16::from_le_bytes(n), | 50 | 2 | ByteOrder::BigEndian => i16::from_be_bytes(n), | 51 | | }) | 52 | 14 | } |
Unexecuted instantiation: <tiff::decoder::stream::EndianReader<_>>::read_i16 |
53 | | |
54 | | /// Reads an u32 |
55 | | #[inline(always)] |
56 | 3.21M | pub fn read_u32(&mut self) -> Result<u32, io::Error> { |
57 | 3.21M | let mut n = [0u8; 4]; |
58 | 3.21M | self.reader.read_exact(&mut n)?; |
59 | 3.20M | Ok(match self.byte_order { |
60 | 2.98M | ByteOrder::LittleEndian => u32::from_le_bytes(n), |
61 | 228k | ByteOrder::BigEndian => u32::from_be_bytes(n), |
62 | | }) |
63 | 3.21M | } <tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<&[u8]>>>::read_u32 Line | Count | Source | 56 | 3.17M | pub fn read_u32(&mut self) -> Result<u32, io::Error> { | 57 | 3.17M | let mut n = [0u8; 4]; | 58 | 3.17M | self.reader.read_exact(&mut n)?; | 59 | 3.17M | Ok(match self.byte_order { | 60 | 2.94M | ByteOrder::LittleEndian => u32::from_le_bytes(n), | 61 | 227k | ByteOrder::BigEndian => u32::from_be_bytes(n), | 62 | | }) | 63 | 3.17M | } |
<tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::read_u32 Line | Count | Source | 56 | 39.3k | pub fn read_u32(&mut self) -> Result<u32, io::Error> { | 57 | 39.3k | let mut n = [0u8; 4]; | 58 | 39.3k | self.reader.read_exact(&mut n)?; | 59 | 39.3k | Ok(match self.byte_order { | 60 | 38.2k | ByteOrder::LittleEndian => u32::from_le_bytes(n), | 61 | 1.09k | ByteOrder::BigEndian => u32::from_be_bytes(n), | 62 | | }) | 63 | 39.3k | } |
Unexecuted instantiation: <tiff::decoder::stream::EndianReader<_>>::read_u32 |
64 | | |
65 | | /// Reads an i32 |
66 | | #[inline(always)] |
67 | 43 | pub fn read_i32(&mut self) -> Result<i32, io::Error> { |
68 | 43 | let mut n = [0u8; 4]; |
69 | 43 | self.reader.read_exact(&mut n)?; |
70 | 35 | Ok(match self.byte_order { |
71 | 30 | ByteOrder::LittleEndian => i32::from_le_bytes(n), |
72 | 5 | ByteOrder::BigEndian => i32::from_be_bytes(n), |
73 | | }) |
74 | 43 | } <tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::read_i32 Line | Count | Source | 67 | 9 | pub fn read_i32(&mut self) -> Result<i32, io::Error> { | 68 | 9 | let mut n = [0u8; 4]; | 69 | 9 | self.reader.read_exact(&mut n)?; | 70 | 9 | Ok(match self.byte_order { | 71 | 9 | ByteOrder::LittleEndian => i32::from_le_bytes(n), | 72 | 0 | ByteOrder::BigEndian => i32::from_be_bytes(n), | 73 | | }) | 74 | 9 | } |
<tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<&[u8]>>>::read_i32 Line | Count | Source | 67 | 34 | pub fn read_i32(&mut self) -> Result<i32, io::Error> { | 68 | 34 | let mut n = [0u8; 4]; | 69 | 34 | self.reader.read_exact(&mut n)?; | 70 | 26 | Ok(match self.byte_order { | 71 | 21 | ByteOrder::LittleEndian => i32::from_le_bytes(n), | 72 | 5 | ByteOrder::BigEndian => i32::from_be_bytes(n), | 73 | | }) | 74 | 34 | } |
Unexecuted instantiation: <tiff::decoder::stream::EndianReader<_>>::read_i32 |
75 | | |
76 | | /// Reads an u64 |
77 | | #[inline(always)] |
78 | 12.8k | pub fn read_u64(&mut self) -> Result<u64, io::Error> { |
79 | 12.8k | let mut n = [0u8; 8]; |
80 | 12.8k | self.reader.read_exact(&mut n)?; |
81 | 12.8k | Ok(match self.byte_order { |
82 | 5.31k | ByteOrder::LittleEndian => u64::from_le_bytes(n), |
83 | 7.55k | ByteOrder::BigEndian => u64::from_be_bytes(n), |
84 | | }) |
85 | 12.8k | } <tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<&[u8]>>>::read_u64 Line | Count | Source | 78 | 12.6k | pub fn read_u64(&mut self) -> Result<u64, io::Error> { | 79 | 12.6k | let mut n = [0u8; 8]; | 80 | 12.6k | self.reader.read_exact(&mut n)?; | 81 | 12.6k | Ok(match self.byte_order { | 82 | 5.12k | ByteOrder::LittleEndian => u64::from_le_bytes(n), | 83 | 7.51k | ByteOrder::BigEndian => u64::from_be_bytes(n), | 84 | | }) | 85 | 12.6k | } |
<tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::read_u64 Line | Count | Source | 78 | 227 | pub fn read_u64(&mut self) -> Result<u64, io::Error> { | 79 | 227 | let mut n = [0u8; 8]; | 80 | 227 | self.reader.read_exact(&mut n)?; | 81 | 227 | Ok(match self.byte_order { | 82 | 191 | ByteOrder::LittleEndian => u64::from_le_bytes(n), | 83 | 36 | ByteOrder::BigEndian => u64::from_be_bytes(n), | 84 | | }) | 85 | 227 | } |
Unexecuted instantiation: <tiff::decoder::stream::EndianReader<_>>::read_u64 |
86 | | |
87 | | /// Reads an i64 |
88 | | #[inline(always)] |
89 | 8 | pub fn read_i64(&mut self) -> Result<i64, io::Error> { |
90 | 8 | let mut n = [0u8; 8]; |
91 | 8 | self.reader.read_exact(&mut n)?; |
92 | 5 | Ok(match self.byte_order { |
93 | 5 | ByteOrder::LittleEndian => i64::from_le_bytes(n), |
94 | 0 | ByteOrder::BigEndian => i64::from_be_bytes(n), |
95 | | }) |
96 | 8 | } <tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::read_i64 Line | Count | Source | 89 | 1 | pub fn read_i64(&mut self) -> Result<i64, io::Error> { | 90 | 1 | let mut n = [0u8; 8]; | 91 | 1 | self.reader.read_exact(&mut n)?; | 92 | 1 | Ok(match self.byte_order { | 93 | 1 | ByteOrder::LittleEndian => i64::from_le_bytes(n), | 94 | 0 | ByteOrder::BigEndian => i64::from_be_bytes(n), | 95 | | }) | 96 | 1 | } |
<tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<&[u8]>>>::read_i64 Line | Count | Source | 89 | 7 | pub fn read_i64(&mut self) -> Result<i64, io::Error> { | 90 | 7 | let mut n = [0u8; 8]; | 91 | 7 | self.reader.read_exact(&mut n)?; | 92 | 4 | Ok(match self.byte_order { | 93 | 4 | ByteOrder::LittleEndian => i64::from_le_bytes(n), | 94 | 0 | ByteOrder::BigEndian => i64::from_be_bytes(n), | 95 | | }) | 96 | 7 | } |
Unexecuted instantiation: <tiff::decoder::stream::EndianReader<_>>::read_i64 |
97 | | |
98 | | /// Reads an f32 |
99 | | #[inline(always)] |
100 | 7 | pub fn read_f32(&mut self) -> Result<f32, io::Error> { |
101 | 7 | let mut n = [0u8; 4]; |
102 | 7 | self.reader.read_exact(&mut n)?; |
103 | 7 | Ok(f32::from_bits(match self.byte_order { |
104 | 6 | ByteOrder::LittleEndian => u32::from_le_bytes(n), |
105 | 1 | ByteOrder::BigEndian => u32::from_be_bytes(n), |
106 | | })) |
107 | 7 | } <tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::read_f32 Line | Count | Source | 100 | 7 | pub fn read_f32(&mut self) -> Result<f32, io::Error> { | 101 | 7 | let mut n = [0u8; 4]; | 102 | 7 | self.reader.read_exact(&mut n)?; | 103 | 7 | Ok(f32::from_bits(match self.byte_order { | 104 | 6 | ByteOrder::LittleEndian => u32::from_le_bytes(n), | 105 | 1 | ByteOrder::BigEndian => u32::from_be_bytes(n), | 106 | | })) | 107 | 7 | } |
Unexecuted instantiation: <tiff::decoder::stream::EndianReader<_>>::read_f32 |
108 | | |
109 | | /// Reads an f64 |
110 | | #[inline(always)] |
111 | 9 | pub fn read_f64(&mut self) -> Result<f64, io::Error> { |
112 | 9 | let mut n = [0u8; 8]; |
113 | 9 | self.reader.read_exact(&mut n)?; |
114 | 6 | Ok(f64::from_bits(match self.byte_order { |
115 | 6 | ByteOrder::LittleEndian => u64::from_le_bytes(n), |
116 | 0 | ByteOrder::BigEndian => u64::from_be_bytes(n), |
117 | | })) |
118 | 9 | } <tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::read_f64 Line | Count | Source | 111 | 1 | pub fn read_f64(&mut self) -> Result<f64, io::Error> { | 112 | 1 | let mut n = [0u8; 8]; | 113 | 1 | self.reader.read_exact(&mut n)?; | 114 | 1 | Ok(f64::from_bits(match self.byte_order { | 115 | 1 | ByteOrder::LittleEndian => u64::from_le_bytes(n), | 116 | 0 | ByteOrder::BigEndian => u64::from_be_bytes(n), | 117 | | })) | 118 | 1 | } |
<tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<&[u8]>>>::read_f64 Line | Count | Source | 111 | 8 | pub fn read_f64(&mut self) -> Result<f64, io::Error> { | 112 | 8 | let mut n = [0u8; 8]; | 113 | 8 | self.reader.read_exact(&mut n)?; | 114 | 5 | Ok(f64::from_bits(match self.byte_order { | 115 | 5 | ByteOrder::LittleEndian => u64::from_le_bytes(n), | 116 | 0 | ByteOrder::BigEndian => u64::from_be_bytes(n), | 117 | | })) | 118 | 8 | } |
Unexecuted instantiation: <tiff::decoder::stream::EndianReader<_>>::read_f64 |
119 | | } |
120 | | |
121 | | // |
122 | | // # READERS |
123 | | // |
124 | | |
125 | | /// Type alias for the deflate Reader |
126 | | #[cfg(feature = "deflate")] |
127 | | pub type DeflateReader<R> = flate2::read::ZlibDecoder<R>; |
128 | | |
129 | | // |
130 | | // ## LZW Reader |
131 | | // |
132 | | |
133 | | /// Reader that decompresses LZW streams |
134 | | #[cfg(feature = "lzw")] |
135 | | pub struct LZWReader<R: Read> { |
136 | | reader: BufReader<Take<R>>, |
137 | | decoder: weezl::decode::Decoder, |
138 | | } |
139 | | |
140 | | #[cfg(feature = "lzw")] |
141 | | impl<R: Read> LZWReader<R> { |
142 | | /// Wraps a reader |
143 | 2.30k | pub fn new(reader: R, compressed_length: usize) -> LZWReader<R> { |
144 | 2.30k | let configuration = |
145 | 2.30k | weezl::decode::Configuration::with_tiff_size_switch(weezl::BitOrder::Msb, 8) |
146 | 2.30k | .with_yield_on_full_buffer(true); |
147 | 2.30k | Self { |
148 | 2.30k | reader: BufReader::with_capacity( |
149 | 2.30k | (32 * 1024).min(compressed_length), |
150 | 2.30k | reader.take(u64::try_from(compressed_length).unwrap()), |
151 | 2.30k | ), |
152 | 2.30k | decoder: configuration.build(), |
153 | 2.30k | } |
154 | 2.30k | } <tiff::decoder::stream::LZWReader<&mut std::io::cursor::Cursor<&[u8]>>>::new Line | Count | Source | 143 | 2.30k | pub fn new(reader: R, compressed_length: usize) -> LZWReader<R> { | 144 | 2.30k | let configuration = | 145 | 2.30k | weezl::decode::Configuration::with_tiff_size_switch(weezl::BitOrder::Msb, 8) | 146 | 2.30k | .with_yield_on_full_buffer(true); | 147 | 2.30k | Self { | 148 | 2.30k | reader: BufReader::with_capacity( | 149 | 2.30k | (32 * 1024).min(compressed_length), | 150 | 2.30k | reader.take(u64::try_from(compressed_length).unwrap()), | 151 | 2.30k | ), | 152 | 2.30k | decoder: configuration.build(), | 153 | 2.30k | } | 154 | 2.30k | } |
Unexecuted instantiation: <tiff::decoder::stream::LZWReader<_>>::new |
155 | | } |
156 | | |
157 | | #[cfg(feature = "lzw")] |
158 | | impl<R: Read> Read for LZWReader<R> { |
159 | 164k | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
160 | | loop { |
161 | 166k | let result = self.decoder.decode_bytes(self.reader.fill_buf()?, buf); |
162 | 166k | self.reader.consume(result.consumed_in); |
163 | | |
164 | 166k | match result.status { |
165 | | Ok(weezl::LzwStatus::Ok) => { |
166 | 165k | if result.consumed_out == 0 { |
167 | 2.75k | continue; |
168 | | } else { |
169 | 162k | return Ok(result.consumed_out); |
170 | | } |
171 | | } |
172 | | Ok(weezl::LzwStatus::NoProgress) => { |
173 | 461 | return Err(io::Error::new( |
174 | 461 | io::ErrorKind::UnexpectedEof, |
175 | 461 | "no lzw end code found", |
176 | 461 | )); |
177 | | } |
178 | | Ok(weezl::LzwStatus::Done) => { |
179 | 165 | return Ok(result.consumed_out); |
180 | | } |
181 | 613 | Err(err) => return Err(io::Error::new(io::ErrorKind::InvalidData, err)), |
182 | | } |
183 | | } |
184 | 164k | } <tiff::decoder::stream::LZWReader<&mut std::io::cursor::Cursor<&[u8]>> as std::io::Read>::read Line | Count | Source | 159 | 164k | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { | 160 | | loop { | 161 | 166k | let result = self.decoder.decode_bytes(self.reader.fill_buf()?, buf); | 162 | 166k | self.reader.consume(result.consumed_in); | 163 | | | 164 | 166k | match result.status { | 165 | | Ok(weezl::LzwStatus::Ok) => { | 166 | 165k | if result.consumed_out == 0 { | 167 | 2.75k | continue; | 168 | | } else { | 169 | 162k | return Ok(result.consumed_out); | 170 | | } | 171 | | } | 172 | | Ok(weezl::LzwStatus::NoProgress) => { | 173 | 461 | return Err(io::Error::new( | 174 | 461 | io::ErrorKind::UnexpectedEof, | 175 | 461 | "no lzw end code found", | 176 | 461 | )); | 177 | | } | 178 | | Ok(weezl::LzwStatus::Done) => { | 179 | 165 | return Ok(result.consumed_out); | 180 | | } | 181 | 613 | Err(err) => return Err(io::Error::new(io::ErrorKind::InvalidData, err)), | 182 | | } | 183 | | } | 184 | 164k | } |
Unexecuted instantiation: <tiff::decoder::stream::LZWReader<_> as std::io::Read>::read |
185 | | } |
186 | | |
187 | | // |
188 | | // ## PackBits Reader |
189 | | // |
190 | | |
191 | | /// Internal state machine for the PackBitsReader. |
192 | | enum PackBitsReaderState { |
193 | | Header, |
194 | | Literal, |
195 | | Repeat { value: u8 }, |
196 | | } |
197 | | |
198 | | /// Reader that unpacks Apple's `PackBits` format |
199 | | pub struct PackBitsReader<R: Read> { |
200 | | reader: Take<R>, |
201 | | state: PackBitsReaderState, |
202 | | count: usize, |
203 | | } |
204 | | |
205 | | impl<R: Read> PackBitsReader<R> { |
206 | | /// Wraps a reader |
207 | 531 | pub fn new(reader: R, length: u64) -> Self { |
208 | 531 | Self { |
209 | 531 | reader: reader.take(length), |
210 | 531 | state: PackBitsReaderState::Header, |
211 | 531 | count: 0, |
212 | 531 | } |
213 | 531 | } <tiff::decoder::stream::PackBitsReader<&mut std::io::cursor::Cursor<&[u8]>>>::new Line | Count | Source | 207 | 531 | pub fn new(reader: R, length: u64) -> Self { | 208 | 531 | Self { | 209 | 531 | reader: reader.take(length), | 210 | 531 | state: PackBitsReaderState::Header, | 211 | 531 | count: 0, | 212 | 531 | } | 213 | 531 | } |
Unexecuted instantiation: <tiff::decoder::stream::PackBitsReader<_>>::new |
214 | | } |
215 | | |
216 | | impl<R: Read> Read for PackBitsReader<R> { |
217 | 142k | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
218 | 274k | while let PackBitsReaderState::Header = self.state { |
219 | 132k | if self.reader.limit() == 0 { |
220 | 17 | return Ok(0); |
221 | 132k | } |
222 | 132k | let mut header: [u8; 1] = [0]; |
223 | 132k | self.reader.read_exact(&mut header)?; |
224 | 131k | let h = header[0] as i8; |
225 | 131k | if (-127..=-1).contains(&h) { |
226 | 47.9k | let mut data: [u8; 1] = [0]; |
227 | 47.9k | self.reader.read_exact(&mut data)?; |
228 | 47.9k | self.state = PackBitsReaderState::Repeat { value: data[0] }; |
229 | 47.9k | self.count = (1 - h as isize) as usize; |
230 | 83.9k | } else if h >= 0 { |
231 | 83.0k | self.state = PackBitsReaderState::Literal; |
232 | 83.0k | self.count = h as usize + 1; |
233 | 83.0k | } else { |
234 | 893 | // h = -128 is a no-op. |
235 | 893 | } |
236 | | } |
237 | | |
238 | 142k | let length = buf.len().min(self.count); |
239 | 142k | let actual = match self.state { |
240 | 85.8k | PackBitsReaderState::Literal => self.reader.read(&mut buf[..length])?, |
241 | 56.5k | PackBitsReaderState::Repeat { value } => { |
242 | 1.59M | for b in &mut buf[..length] { |
243 | 1.59M | *b = value; |
244 | 1.59M | } |
245 | | |
246 | 56.5k | length |
247 | | } |
248 | 0 | PackBitsReaderState::Header => unreachable!(), |
249 | | }; |
250 | | |
251 | 142k | self.count -= actual; |
252 | 142k | if self.count == 0 { |
253 | 130k | self.state = PackBitsReaderState::Header; |
254 | 130k | } |
255 | 142k | Ok(actual) |
256 | 142k | } <tiff::decoder::stream::PackBitsReader<&mut std::io::cursor::Cursor<&[u8]>> as std::io::Read>::read Line | Count | Source | 217 | 142k | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { | 218 | 274k | while let PackBitsReaderState::Header = self.state { | 219 | 132k | if self.reader.limit() == 0 { | 220 | 17 | return Ok(0); | 221 | 132k | } | 222 | 132k | let mut header: [u8; 1] = [0]; | 223 | 132k | self.reader.read_exact(&mut header)?; | 224 | 131k | let h = header[0] as i8; | 225 | 131k | if (-127..=-1).contains(&h) { | 226 | 47.9k | let mut data: [u8; 1] = [0]; | 227 | 47.9k | self.reader.read_exact(&mut data)?; | 228 | 47.9k | self.state = PackBitsReaderState::Repeat { value: data[0] }; | 229 | 47.9k | self.count = (1 - h as isize) as usize; | 230 | 83.9k | } else if h >= 0 { | 231 | 83.0k | self.state = PackBitsReaderState::Literal; | 232 | 83.0k | self.count = h as usize + 1; | 233 | 83.0k | } else { | 234 | 893 | // h = -128 is a no-op. | 235 | 893 | } | 236 | | } | 237 | | | 238 | 142k | let length = buf.len().min(self.count); | 239 | 142k | let actual = match self.state { | 240 | 85.8k | PackBitsReaderState::Literal => self.reader.read(&mut buf[..length])?, | 241 | 56.5k | PackBitsReaderState::Repeat { value } => { | 242 | 1.59M | for b in &mut buf[..length] { | 243 | 1.59M | *b = value; | 244 | 1.59M | } | 245 | | | 246 | 56.5k | length | 247 | | } | 248 | 0 | PackBitsReaderState::Header => unreachable!(), | 249 | | }; | 250 | | | 251 | 142k | self.count -= actual; | 252 | 142k | if self.count == 0 { | 253 | 130k | self.state = PackBitsReaderState::Header; | 254 | 130k | } | 255 | 142k | Ok(actual) | 256 | 142k | } |
Unexecuted instantiation: <tiff::decoder::stream::PackBitsReader<_> as std::io::Read>::read |
257 | | } |
258 | | |
259 | | #[cfg(feature = "fax")] |
260 | | pub struct Group4Reader<R: Read> { |
261 | | decoder: fax34::decoder::Group4Decoder<io::Bytes<io::BufReader<io::Take<R>>>>, |
262 | | line_buf: io::Cursor<Vec<u8>>, |
263 | | height: u16, |
264 | | width: u16, |
265 | | y: u16, |
266 | | } |
267 | | |
268 | | #[cfg(feature = "fax")] |
269 | | impl<R: Read> Group4Reader<R> { |
270 | 688 | pub fn new( |
271 | 688 | dimensions: (u32, u32), |
272 | 688 | reader: R, |
273 | 688 | compressed_length: u64, |
274 | 688 | ) -> crate::TiffResult<Self> { |
275 | 688 | let width = u16::try_from(dimensions.0)?; |
276 | 686 | let height = u16::try_from(dimensions.1)?; |
277 | | |
278 | | Ok(Self { |
279 | 683 | decoder: fax34::decoder::Group4Decoder::new( |
280 | 683 | io::BufReader::new(reader.take(compressed_length)).bytes(), |
281 | 683 | width, |
282 | 0 | )?, |
283 | 683 | line_buf: io::Cursor::new(Vec::with_capacity(width.into())), |
284 | 683 | width, |
285 | 683 | height, |
286 | | y: 0, |
287 | | }) |
288 | 688 | } <tiff::decoder::stream::Group4Reader<&mut std::io::cursor::Cursor<&[u8]>>>::new Line | Count | Source | 270 | 688 | pub fn new( | 271 | 688 | dimensions: (u32, u32), | 272 | 688 | reader: R, | 273 | 688 | compressed_length: u64, | 274 | 688 | ) -> crate::TiffResult<Self> { | 275 | 688 | let width = u16::try_from(dimensions.0)?; | 276 | 686 | let height = u16::try_from(dimensions.1)?; | 277 | | | 278 | | Ok(Self { | 279 | 683 | decoder: fax34::decoder::Group4Decoder::new( | 280 | 683 | io::BufReader::new(reader.take(compressed_length)).bytes(), | 281 | 683 | width, | 282 | 0 | )?, | 283 | 683 | line_buf: io::Cursor::new(Vec::with_capacity(width.into())), | 284 | 683 | width, | 285 | 683 | height, | 286 | | y: 0, | 287 | | }) | 288 | 688 | } |
Unexecuted instantiation: <tiff::decoder::stream::Group4Reader<_>>::new |
289 | | } |
290 | | |
291 | | #[cfg(feature = "fax")] |
292 | | impl<R: Read> Read for Group4Reader<R> { |
293 | 725k | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
294 | | // Either we have not read any line or we are at the end of a line. |
295 | 725k | if self.line_buf.position() as usize == self.line_buf.get_ref().len() |
296 | 710k | && self.y < self.height |
297 | | { |
298 | 710k | let next = self.decoder.advance().map_err(std::io::Error::other)?; |
299 | | |
300 | 709k | match next { |
301 | 11.7k | fax34::decoder::DecodeStatus::End => (), |
302 | | fax34::decoder::DecodeStatus::Incomplete => { |
303 | 698k | self.y += 1; |
304 | | |
305 | | // We known `transitions` yields exactly `self.width` items (per doc). |
306 | | // FIXME: performance. We do not need an individual pixel iterator, filling |
307 | | // memory especially for long runs can be much quicker. The `transitions` are |
308 | | // the positions at which each run-length ends, i.e. the prefix sum of run |
309 | | // lengths. Runs in fax4 start with white. |
310 | 698k | let transitions = fax34::decoder::pels(self.decoder.transition(), self.width); |
311 | | |
312 | 698k | let buffer = self.line_buf.get_mut(); |
313 | 698k | buffer.resize(usize::from(self.width).div_ceil(8), 0u8); |
314 | | |
315 | 698k | let target = &mut buffer[..]; |
316 | | |
317 | | // Note: it may seem strange to treat black as 0b1 and white as 0b0 despite all |
318 | | // our streams by default decoding as-if PhotometricInterpretation::BlackIsMin. |
319 | | // This is however consistent with libtiff. It seems that fax4's "White" |
320 | | // differs from what libtiff thinks of as "White". For content, a line of data |
321 | | // is in runlength encoding of white-black-white-black always starting with |
322 | | // white. In libtiff, the loop always does both colors in one go and the |
323 | | // structure is: |
324 | | // |
325 | | // ``` |
326 | | // for (; runs < erun; runs += 2) |
327 | | // // white run |
328 | | // do { *lp++ = 0L; } while (…) |
329 | | // // black run |
330 | | // do { *lp++ = -1L; } while (…) |
331 | | // ``` |
332 | | // |
333 | | // So indeed the Fax4::White run is implemented by filling with zeros. |
334 | 2.92G | let mut bits = transitions.map(|c| match c { |
335 | 1.06G | fax34::Color::Black => true, |
336 | 1.86G | fax34::Color::White => false, |
337 | 2.92G | }); <tiff::decoder::stream::Group4Reader<&mut std::io::cursor::Cursor<&[u8]>> as std::io::Read>::read::{closure#0}Line | Count | Source | 334 | 2.92G | let mut bits = transitions.map(|c| match c { | 335 | 1.06G | fax34::Color::Black => true, | 336 | 1.86G | fax34::Color::White => false, | 337 | 2.92G | }); |
Unexecuted instantiation: <tiff::decoder::stream::Group4Reader<_> as std::io::Read>::read::{closure#0} |
338 | | |
339 | | // Assemble bits in MSB as per our library representation for buffer. |
340 | 367M | for byte in target { |
341 | 366M | let mut val = 0; |
342 | | |
343 | 2.92G | for (idx, bit) in bits.by_ref().take(8).enumerate() { |
344 | 2.92G | val |= u8::from(bit) << (7 - idx % 8); |
345 | 2.92G | } |
346 | | |
347 | 366M | *byte = val; |
348 | | } |
349 | | |
350 | 698k | self.line_buf.set_position(0); |
351 | | } |
352 | | } |
353 | 15.5k | } |
354 | | |
355 | 725k | self.line_buf.read(buf) |
356 | 725k | } <tiff::decoder::stream::Group4Reader<&mut std::io::cursor::Cursor<&[u8]>> as std::io::Read>::read Line | Count | Source | 293 | 725k | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { | 294 | | // Either we have not read any line or we are at the end of a line. | 295 | 725k | if self.line_buf.position() as usize == self.line_buf.get_ref().len() | 296 | 710k | && self.y < self.height | 297 | | { | 298 | 710k | let next = self.decoder.advance().map_err(std::io::Error::other)?; | 299 | | | 300 | 709k | match next { | 301 | 11.7k | fax34::decoder::DecodeStatus::End => (), | 302 | | fax34::decoder::DecodeStatus::Incomplete => { | 303 | 698k | self.y += 1; | 304 | | | 305 | | // We known `transitions` yields exactly `self.width` items (per doc). | 306 | | // FIXME: performance. We do not need an individual pixel iterator, filling | 307 | | // memory especially for long runs can be much quicker. The `transitions` are | 308 | | // the positions at which each run-length ends, i.e. the prefix sum of run | 309 | | // lengths. Runs in fax4 start with white. | 310 | 698k | let transitions = fax34::decoder::pels(self.decoder.transition(), self.width); | 311 | | | 312 | 698k | let buffer = self.line_buf.get_mut(); | 313 | 698k | buffer.resize(usize::from(self.width).div_ceil(8), 0u8); | 314 | | | 315 | 698k | let target = &mut buffer[..]; | 316 | | | 317 | | // Note: it may seem strange to treat black as 0b1 and white as 0b0 despite all | 318 | | // our streams by default decoding as-if PhotometricInterpretation::BlackIsMin. | 319 | | // This is however consistent with libtiff. It seems that fax4's "White" | 320 | | // differs from what libtiff thinks of as "White". For content, a line of data | 321 | | // is in runlength encoding of white-black-white-black always starting with | 322 | | // white. In libtiff, the loop always does both colors in one go and the | 323 | | // structure is: | 324 | | // | 325 | | // ``` | 326 | | // for (; runs < erun; runs += 2) | 327 | | // // white run | 328 | | // do { *lp++ = 0L; } while (…) | 329 | | // // black run | 330 | | // do { *lp++ = -1L; } while (…) | 331 | | // ``` | 332 | | // | 333 | | // So indeed the Fax4::White run is implemented by filling with zeros. | 334 | 698k | let mut bits = transitions.map(|c| match c { | 335 | | fax34::Color::Black => true, | 336 | | fax34::Color::White => false, | 337 | | }); | 338 | | | 339 | | // Assemble bits in MSB as per our library representation for buffer. | 340 | 367M | for byte in target { | 341 | 366M | let mut val = 0; | 342 | | | 343 | 2.92G | for (idx, bit) in bits.by_ref().take(8).enumerate() { | 344 | 2.92G | val |= u8::from(bit) << (7 - idx % 8); | 345 | 2.92G | } | 346 | | | 347 | 366M | *byte = val; | 348 | | } | 349 | | | 350 | 698k | self.line_buf.set_position(0); | 351 | | } | 352 | | } | 353 | 15.5k | } | 354 | | | 355 | 725k | self.line_buf.read(buf) | 356 | 725k | } |
Unexecuted instantiation: <tiff::decoder::stream::Group4Reader<_> as std::io::Read>::read |
357 | | } |
358 | | |
359 | | #[cfg(feature = "webp")] |
360 | | pub struct WebPReader { |
361 | | inner: Cursor<Vec<u8>>, |
362 | | } |
363 | | |
364 | | #[cfg(feature = "webp")] |
365 | | impl WebPReader { |
366 | | pub fn new<R: Read + Seek>( |
367 | | reader: R, |
368 | | compressed_length: u64, |
369 | | samples: u16, |
370 | | ) -> crate::TiffResult<Self> { |
371 | | let mut decoder = |
372 | | image_webp::WebPDecoder::new(io::BufReader::new(reader.take(compressed_length))) |
373 | | .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; |
374 | | |
375 | | if !(samples == 4 || (samples == 3 && !decoder.has_alpha())) { |
376 | | return Err(io::Error::new( |
377 | | io::ErrorKind::InvalidData, |
378 | | "bad sample count for WebP compressed data", |
379 | | ) |
380 | | .into()); |
381 | | } |
382 | | |
383 | | let total_bytes = |
384 | | samples as usize * decoder.dimensions().0 as usize * decoder.dimensions().1 as usize; |
385 | | let mut data = vec![0; total_bytes]; |
386 | | |
387 | | decoder |
388 | | .read_image(&mut data) |
389 | | .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; |
390 | | |
391 | | // Add a fully opaque alpha channel if needed |
392 | | if samples == 4 && !decoder.has_alpha() { |
393 | | for i in (0..(total_bytes / 4)).rev() { |
394 | | data[i * 4 + 3] = 255; |
395 | | data[i * 4 + 2] = data[i * 3 + 2]; |
396 | | data[i * 4 + 1] = data[i * 3 + 1]; |
397 | | data[i * 4] = data[i * 3]; |
398 | | } |
399 | | } |
400 | | |
401 | | Ok(Self { |
402 | | inner: Cursor::new(data), |
403 | | }) |
404 | | } |
405 | | } |
406 | | |
407 | | #[cfg(feature = "webp")] |
408 | | impl Read for WebPReader { |
409 | | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
410 | | self.inner.read(buf) |
411 | | } |
412 | | } |
413 | | |
414 | | #[cfg(test)] |
415 | | mod test { |
416 | | use super::*; |
417 | | |
418 | | #[test] |
419 | | fn test_packbits() { |
420 | | let encoded = vec![ |
421 | | 0xFE, 0xAA, 0x02, 0x80, 0x00, 0x2A, 0xFD, 0xAA, 0x03, 0x80, 0x00, 0x2A, 0x22, 0xF7, |
422 | | 0xAA, |
423 | | ]; |
424 | | let encoded_len = encoded.len(); |
425 | | |
426 | | let buff = io::Cursor::new(encoded); |
427 | | let mut decoder = PackBitsReader::new(buff, encoded_len as u64); |
428 | | |
429 | | let mut decoded = Vec::new(); |
430 | | decoder.read_to_end(&mut decoded).unwrap(); |
431 | | |
432 | | let expected = vec![ |
433 | | 0xAA, 0xAA, 0xAA, 0x80, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0x80, 0x00, 0x2A, 0x22, |
434 | | 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, |
435 | | ]; |
436 | | assert_eq!(decoded, expected); |
437 | | } |
438 | | } |