Coverage Report

Created: 2026-10-17 08:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
162k
    pub fn new(reader: R, byte_order: ByteOrder) -> Self {
17
162k
        Self { reader, byte_order }
18
162k
    }
<tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<&[u8]>>>::new
Line
Count
Source
16
19.7k
    pub fn new(reader: R, byte_order: ByteOrder) -> Self {
17
19.7k
        Self { reader, byte_order }
18
19.7k
    }
<tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::new
Line
Count
Source
16
142k
    pub fn new(reader: R, byte_order: ByteOrder) -> Self {
17
142k
        Self { reader, byte_order }
18
142k
    }
19
20
536k
    pub fn inner(&mut self) -> &mut R {
21
536k
        &mut self.reader
22
536k
    }
<tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<&[u8]>>>::inner
Line
Count
Source
20
536k
    pub fn inner(&mut self) -> &mut R {
21
536k
        &mut self.reader
22
536k
    }
Unexecuted instantiation: <tiff::decoder::stream::EndianReader<_>>::inner
23
24
91.9k
    pub fn goto_offset(&mut self, offset: u64) -> io::Result<()>
25
91.9k
    where
26
91.9k
        R: Seek,
27
    {
28
91.9k
        self.reader.seek(io::SeekFrom::Start(offset))?;
29
91.9k
        Ok(())
30
91.9k
    }
<tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<&[u8]>>>::goto_offset
Line
Count
Source
24
91.9k
    pub fn goto_offset(&mut self, offset: u64) -> io::Result<()>
25
91.9k
    where
26
91.9k
        R: Seek,
27
    {
28
91.9k
        self.reader.seek(io::SeekFrom::Start(offset))?;
29
91.9k
        Ok(())
30
91.9k
    }
Unexecuted instantiation: <tiff::decoder::stream::EndianReader<_>>::goto_offset
31
32
    /// Reads an u16
33
    #[inline(always)]
34
3.10M
    pub fn read_u16(&mut self) -> Result<u16, io::Error> {
35
3.10M
        let mut n = [0u8; 2];
36
3.10M
        self.reader.read_exact(&mut n)?;
37
3.09M
        Ok(match self.byte_order {
38
2.92M
            ByteOrder::LittleEndian => u16::from_le_bytes(n),
39
173k
            ByteOrder::BigEndian => u16::from_be_bytes(n),
40
        })
41
3.10M
    }
<tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::read_u16
Line
Count
Source
34
99.8k
    pub fn read_u16(&mut self) -> Result<u16, io::Error> {
35
99.8k
        let mut n = [0u8; 2];
36
99.8k
        self.reader.read_exact(&mut n)?;
37
99.8k
        Ok(match self.byte_order {
38
96.7k
            ByteOrder::LittleEndian => u16::from_le_bytes(n),
39
3.03k
            ByteOrder::BigEndian => u16::from_be_bytes(n),
40
        })
41
99.8k
    }
<tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<&[u8]>>>::read_u16
Line
Count
Source
34
3.00M
    pub fn read_u16(&mut self) -> Result<u16, io::Error> {
35
3.00M
        let mut n = [0u8; 2];
36
3.00M
        self.reader.read_exact(&mut n)?;
37
3.00M
        Ok(match self.byte_order {
38
2.82M
            ByteOrder::LittleEndian => u16::from_le_bytes(n),
39
170k
            ByteOrder::BigEndian => u16::from_be_bytes(n),
40
        })
41
3.00M
    }
Unexecuted instantiation: <tiff::decoder::stream::EndianReader<_>>::read_u16
42
43
    /// Reads an i16
44
    #[inline(always)]
45
11
    pub fn read_i16(&mut self) -> Result<i16, io::Error> {
46
11
        let mut n = [0u8; 2];
47
11
        self.reader.read_exact(&mut n)?;
48
11
        Ok(match self.byte_order {
49
11
            ByteOrder::LittleEndian => i16::from_le_bytes(n),
50
0
            ByteOrder::BigEndian => i16::from_be_bytes(n),
51
        })
52
11
    }
<tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::read_i16
Line
Count
Source
45
11
    pub fn read_i16(&mut self) -> Result<i16, io::Error> {
46
11
        let mut n = [0u8; 2];
47
11
        self.reader.read_exact(&mut n)?;
48
11
        Ok(match self.byte_order {
49
11
            ByteOrder::LittleEndian => i16::from_le_bytes(n),
50
0
            ByteOrder::BigEndian => i16::from_be_bytes(n),
51
        })
52
11
    }
Unexecuted instantiation: <tiff::decoder::stream::EndianReader<_>>::read_i16
53
54
    /// Reads an u32
55
    #[inline(always)]
56
2.60M
    pub fn read_u32(&mut self) -> Result<u32, io::Error> {
57
2.60M
        let mut n = [0u8; 4];
58
2.60M
        self.reader.read_exact(&mut n)?;
59
2.60M
        Ok(match self.byte_order {
60
2.44M
            ByteOrder::LittleEndian => u32::from_le_bytes(n),
61
156k
            ByteOrder::BigEndian => u32::from_be_bytes(n),
62
        })
63
2.60M
    }
<tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::read_u32
Line
Count
Source
56
43.3k
    pub fn read_u32(&mut self) -> Result<u32, io::Error> {
57
43.3k
        let mut n = [0u8; 4];
58
43.3k
        self.reader.read_exact(&mut n)?;
59
43.3k
        Ok(match self.byte_order {
60
41.5k
            ByteOrder::LittleEndian => u32::from_le_bytes(n),
61
1.76k
            ByteOrder::BigEndian => u32::from_be_bytes(n),
62
        })
63
43.3k
    }
<tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<&[u8]>>>::read_u32
Line
Count
Source
56
2.55M
    pub fn read_u32(&mut self) -> Result<u32, io::Error> {
57
2.55M
        let mut n = [0u8; 4];
58
2.55M
        self.reader.read_exact(&mut n)?;
59
2.55M
        Ok(match self.byte_order {
60
2.40M
            ByteOrder::LittleEndian => u32::from_le_bytes(n),
61
154k
            ByteOrder::BigEndian => u32::from_be_bytes(n),
62
        })
63
2.55M
    }
Unexecuted instantiation: <tiff::decoder::stream::EndianReader<_>>::read_u32
64
65
    /// Reads an i32
66
    #[inline(always)]
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
29
        Ok(match self.byte_order {
71
29
            ByteOrder::LittleEndian => i32::from_le_bytes(n),
72
0
            ByteOrder::BigEndian => i32::from_be_bytes(n),
73
        })
74
34
    }
<tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::read_i32
Line
Count
Source
67
6
    pub fn read_i32(&mut self) -> Result<i32, io::Error> {
68
6
        let mut n = [0u8; 4];
69
6
        self.reader.read_exact(&mut n)?;
70
6
        Ok(match self.byte_order {
71
6
            ByteOrder::LittleEndian => i32::from_le_bytes(n),
72
0
            ByteOrder::BigEndian => i32::from_be_bytes(n),
73
        })
74
6
    }
<tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<&[u8]>>>::read_i32
Line
Count
Source
67
28
    pub fn read_i32(&mut self) -> Result<i32, io::Error> {
68
28
        let mut n = [0u8; 4];
69
28
        self.reader.read_exact(&mut n)?;
70
23
        Ok(match self.byte_order {
71
23
            ByteOrder::LittleEndian => i32::from_le_bytes(n),
72
0
            ByteOrder::BigEndian => i32::from_be_bytes(n),
73
        })
74
28
    }
Unexecuted instantiation: <tiff::decoder::stream::EndianReader<_>>::read_i32
75
76
    /// Reads an u64
77
    #[inline(always)]
78
4.56k
    pub fn read_u64(&mut self) -> Result<u64, io::Error> {
79
4.56k
        let mut n = [0u8; 8];
80
4.56k
        self.reader.read_exact(&mut n)?;
81
4.53k
        Ok(match self.byte_order {
82
3.14k
            ByteOrder::LittleEndian => u64::from_le_bytes(n),
83
1.39k
            ByteOrder::BigEndian => u64::from_be_bytes(n),
84
        })
85
4.56k
    }
<tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::read_u64
Line
Count
Source
78
226
    pub fn read_u64(&mut self) -> Result<u64, io::Error> {
79
226
        let mut n = [0u8; 8];
80
226
        self.reader.read_exact(&mut n)?;
81
226
        Ok(match self.byte_order {
82
177
            ByteOrder::LittleEndian => u64::from_le_bytes(n),
83
49
            ByteOrder::BigEndian => u64::from_be_bytes(n),
84
        })
85
226
    }
<tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<&[u8]>>>::read_u64
Line
Count
Source
78
4.34k
    pub fn read_u64(&mut self) -> Result<u64, io::Error> {
79
4.34k
        let mut n = [0u8; 8];
80
4.34k
        self.reader.read_exact(&mut n)?;
81
4.30k
        Ok(match self.byte_order {
82
2.96k
            ByteOrder::LittleEndian => u64::from_le_bytes(n),
83
1.34k
            ByteOrder::BigEndian => u64::from_be_bytes(n),
84
        })
85
4.34k
    }
Unexecuted instantiation: <tiff::decoder::stream::EndianReader<_>>::read_u64
86
87
    /// Reads an i64
88
    #[inline(always)]
89
6
    pub fn read_i64(&mut self) -> Result<i64, io::Error> {
90
6
        let mut n = [0u8; 8];
91
6
        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
6
    }
<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
5
    pub fn read_i64(&mut self) -> Result<i64, io::Error> {
90
5
        let mut n = [0u8; 8];
91
5
        self.reader.read_exact(&mut n)?;
92
3
        Ok(match self.byte_order {
93
3
            ByteOrder::LittleEndian => i64::from_le_bytes(n),
94
0
            ByteOrder::BigEndian => i64::from_be_bytes(n),
95
        })
96
5
    }
Unexecuted instantiation: <tiff::decoder::stream::EndianReader<_>>::read_i64
97
98
    /// Reads an f32
99
    #[inline(always)]
100
4
    pub fn read_f32(&mut self) -> Result<f32, io::Error> {
101
4
        let mut n = [0u8; 4];
102
4
        self.reader.read_exact(&mut n)?;
103
4
        Ok(f32::from_bits(match self.byte_order {
104
2
            ByteOrder::LittleEndian => u32::from_le_bytes(n),
105
2
            ByteOrder::BigEndian => u32::from_be_bytes(n),
106
        }))
107
4
    }
<tiff::decoder::stream::EndianReader<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::read_f32
Line
Count
Source
100
4
    pub fn read_f32(&mut self) -> Result<f32, io::Error> {
101
4
        let mut n = [0u8; 4];
102
4
        self.reader.read_exact(&mut n)?;
103
4
        Ok(f32::from_bits(match self.byte_order {
104
2
            ByteOrder::LittleEndian => u32::from_le_bytes(n),
105
2
            ByteOrder::BigEndian => u32::from_be_bytes(n),
106
        }))
107
4
    }
Unexecuted instantiation: <tiff::decoder::stream::EndianReader<_>>::read_f32
108
109
    /// Reads an f64
110
    #[inline(always)]
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
6
        Ok(f64::from_bits(match self.byte_order {
115
5
            ByteOrder::LittleEndian => u64::from_le_bytes(n),
116
1
            ByteOrder::BigEndian => u64::from_be_bytes(n),
117
        }))
118
8
    }
<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
7
    pub fn read_f64(&mut self) -> Result<f64, io::Error> {
112
7
        let mut n = [0u8; 8];
113
7
        self.reader.read_exact(&mut n)?;
114
5
        Ok(f64::from_bits(match self.byte_order {
115
4
            ByteOrder::LittleEndian => u64::from_le_bytes(n),
116
1
            ByteOrder::BigEndian => u64::from_be_bytes(n),
117
        }))
118
7
    }
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.19k
    pub fn new(reader: R, compressed_length: usize) -> LZWReader<R> {
144
2.19k
        let configuration =
145
2.19k
            weezl::decode::Configuration::with_tiff_size_switch(weezl::BitOrder::Msb, 8)
146
2.19k
                .with_yield_on_full_buffer(true);
147
2.19k
        Self {
148
2.19k
            reader: BufReader::with_capacity(
149
2.19k
                (32 * 1024).min(compressed_length),
150
2.19k
                reader.take(u64::try_from(compressed_length).unwrap()),
151
2.19k
            ),
152
2.19k
            decoder: configuration.build(),
153
2.19k
        }
154
2.19k
    }
<tiff::decoder::stream::LZWReader<&mut std::io::cursor::Cursor<&[u8]>>>::new
Line
Count
Source
143
2.19k
    pub fn new(reader: R, compressed_length: usize) -> LZWReader<R> {
144
2.19k
        let configuration =
145
2.19k
            weezl::decode::Configuration::with_tiff_size_switch(weezl::BitOrder::Msb, 8)
146
2.19k
                .with_yield_on_full_buffer(true);
147
2.19k
        Self {
148
2.19k
            reader: BufReader::with_capacity(
149
2.19k
                (32 * 1024).min(compressed_length),
150
2.19k
                reader.take(u64::try_from(compressed_length).unwrap()),
151
2.19k
            ),
152
2.19k
            decoder: configuration.build(),
153
2.19k
        }
154
2.19k
    }
Unexecuted instantiation: <tiff::decoder::stream::LZWReader<_>>::new
155
}
156
157
#[cfg(feature = "lzw")]
158
impl<R: Read> Read for LZWReader<R> {
159
157k
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
160
        loop {
161
160k
            let result = self.decoder.decode_bytes(self.reader.fill_buf()?, buf);
162
160k
            self.reader.consume(result.consumed_in);
163
164
160k
            match result.status {
165
                Ok(weezl::LzwStatus::Ok) => {
166
159k
                    if result.consumed_out == 0 {
167
2.50k
                        continue;
168
                    } else {
169
157k
                        return Ok(result.consumed_out);
170
                    }
171
                }
172
                Ok(weezl::LzwStatus::NoProgress) => {
173
350
                    return Err(io::Error::new(
174
350
                        io::ErrorKind::UnexpectedEof,
175
350
                        "no lzw end code found",
176
350
                    ));
177
                }
178
                Ok(weezl::LzwStatus::Done) => {
179
131
                    return Ok(result.consumed_out);
180
                }
181
468
                Err(err) => return Err(io::Error::new(io::ErrorKind::InvalidData, err)),
182
            }
183
        }
184
157k
    }
<tiff::decoder::stream::LZWReader<&mut std::io::cursor::Cursor<&[u8]>> as std::io::Read>::read
Line
Count
Source
159
157k
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
160
        loop {
161
160k
            let result = self.decoder.decode_bytes(self.reader.fill_buf()?, buf);
162
160k
            self.reader.consume(result.consumed_in);
163
164
160k
            match result.status {
165
                Ok(weezl::LzwStatus::Ok) => {
166
159k
                    if result.consumed_out == 0 {
167
2.50k
                        continue;
168
                    } else {
169
157k
                        return Ok(result.consumed_out);
170
                    }
171
                }
172
                Ok(weezl::LzwStatus::NoProgress) => {
173
350
                    return Err(io::Error::new(
174
350
                        io::ErrorKind::UnexpectedEof,
175
350
                        "no lzw end code found",
176
350
                    ));
177
                }
178
                Ok(weezl::LzwStatus::Done) => {
179
131
                    return Ok(result.consumed_out);
180
                }
181
468
                Err(err) => return Err(io::Error::new(io::ErrorKind::InvalidData, err)),
182
            }
183
        }
184
157k
    }
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
480
    pub fn new(reader: R, length: u64) -> Self {
208
480
        Self {
209
480
            reader: reader.take(length),
210
480
            state: PackBitsReaderState::Header,
211
480
            count: 0,
212
480
        }
213
480
    }
<tiff::decoder::stream::PackBitsReader<&mut std::io::cursor::Cursor<&[u8]>>>::new
Line
Count
Source
207
480
    pub fn new(reader: R, length: u64) -> Self {
208
480
        Self {
209
480
            reader: reader.take(length),
210
480
            state: PackBitsReaderState::Header,
211
480
            count: 0,
212
480
        }
213
480
    }
Unexecuted instantiation: <tiff::decoder::stream::PackBitsReader<_>>::new
214
}
215
216
impl<R: Read> Read for PackBitsReader<R> {
217
176k
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
218
335k
        while let PackBitsReaderState::Header = self.state {
219
159k
            if self.reader.limit() == 0 {
220
10
                return Ok(0);
221
159k
            }
222
159k
            let mut header: [u8; 1] = [0];
223
159k
            self.reader.read_exact(&mut header)?;
224
159k
            let h = header[0] as i8;
225
159k
            if (-127..=-1).contains(&h) {
226
65.3k
                let mut data: [u8; 1] = [0];
227
65.3k
                self.reader.read_exact(&mut data)?;
228
65.3k
                self.state = PackBitsReaderState::Repeat { value: data[0] };
229
65.3k
                self.count = (1 - h as isize) as usize;
230
94.2k
            } else if h >= 0 {
231
93.7k
                self.state = PackBitsReaderState::Literal;
232
93.7k
                self.count = h as usize + 1;
233
93.7k
            } else {
234
534
                // h = -128 is a no-op.
235
534
            }
236
        }
237
238
176k
        let length = buf.len().min(self.count);
239
176k
        let actual = match self.state {
240
96.3k
            PackBitsReaderState::Literal => self.reader.read(&mut buf[..length])?,
241
79.8k
            PackBitsReaderState::Repeat { value } => {
242
2.70M
                for b in &mut buf[..length] {
243
2.70M
                    *b = value;
244
2.70M
                }
245
246
79.8k
                length
247
            }
248
0
            PackBitsReaderState::Header => unreachable!(),
249
        };
250
251
176k
        self.count -= actual;
252
176k
        if self.count == 0 {
253
158k
            self.state = PackBitsReaderState::Header;
254
158k
        }
255
176k
        Ok(actual)
256
176k
    }
<tiff::decoder::stream::PackBitsReader<&mut std::io::cursor::Cursor<&[u8]>> as std::io::Read>::read
Line
Count
Source
217
176k
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
218
335k
        while let PackBitsReaderState::Header = self.state {
219
159k
            if self.reader.limit() == 0 {
220
10
                return Ok(0);
221
159k
            }
222
159k
            let mut header: [u8; 1] = [0];
223
159k
            self.reader.read_exact(&mut header)?;
224
159k
            let h = header[0] as i8;
225
159k
            if (-127..=-1).contains(&h) {
226
65.3k
                let mut data: [u8; 1] = [0];
227
65.3k
                self.reader.read_exact(&mut data)?;
228
65.3k
                self.state = PackBitsReaderState::Repeat { value: data[0] };
229
65.3k
                self.count = (1 - h as isize) as usize;
230
94.2k
            } else if h >= 0 {
231
93.7k
                self.state = PackBitsReaderState::Literal;
232
93.7k
                self.count = h as usize + 1;
233
93.7k
            } else {
234
534
                // h = -128 is a no-op.
235
534
            }
236
        }
237
238
176k
        let length = buf.len().min(self.count);
239
176k
        let actual = match self.state {
240
96.3k
            PackBitsReaderState::Literal => self.reader.read(&mut buf[..length])?,
241
79.8k
            PackBitsReaderState::Repeat { value } => {
242
2.70M
                for b in &mut buf[..length] {
243
2.70M
                    *b = value;
244
2.70M
                }
245
246
79.8k
                length
247
            }
248
0
            PackBitsReaderState::Header => unreachable!(),
249
        };
250
251
176k
        self.count -= actual;
252
176k
        if self.count == 0 {
253
158k
            self.state = PackBitsReaderState::Header;
254
158k
        }
255
176k
        Ok(actual)
256
176k
    }
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
584
    pub fn new(
271
584
        dimensions: (u32, u32),
272
584
        reader: R,
273
584
        compressed_length: u64,
274
584
    ) -> crate::TiffResult<Self> {
275
584
        let width = u16::try_from(dimensions.0)?;
276
572
        let height = u16::try_from(dimensions.1)?;
277
278
        Ok(Self {
279
562
            decoder: fax34::decoder::Group4Decoder::new(
280
562
                io::BufReader::new(reader.take(compressed_length)).bytes(),
281
562
                width,
282
0
            )?,
283
562
            line_buf: io::Cursor::new(Vec::with_capacity(width.into())),
284
562
            width,
285
562
            height,
286
            y: 0,
287
        })
288
584
    }
<tiff::decoder::stream::Group4Reader<&mut std::io::cursor::Cursor<&[u8]>>>::new
Line
Count
Source
270
584
    pub fn new(
271
584
        dimensions: (u32, u32),
272
584
        reader: R,
273
584
        compressed_length: u64,
274
584
    ) -> crate::TiffResult<Self> {
275
584
        let width = u16::try_from(dimensions.0)?;
276
572
        let height = u16::try_from(dimensions.1)?;
277
278
        Ok(Self {
279
562
            decoder: fax34::decoder::Group4Decoder::new(
280
562
                io::BufReader::new(reader.take(compressed_length)).bytes(),
281
562
                width,
282
0
            )?,
283
562
            line_buf: io::Cursor::new(Vec::with_capacity(width.into())),
284
562
            width,
285
562
            height,
286
            y: 0,
287
        })
288
584
    }
Unexecuted instantiation: <tiff::decoder::stream::Group4Reader<_>>::new
289
}
290
291
#[cfg(feature = "fax")]
292
impl<R: Read> Read for Group4Reader<R> {
293
639k
    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
639k
        if self.line_buf.position() as usize == self.line_buf.get_ref().len()
296
637k
            && self.y < self.height
297
        {
298
637k
            let next = self.decoder.advance().map_err(std::io::Error::other)?;
299
300
637k
            match next {
301
401
                fax34::decoder::DecodeStatus::End => (),
302
                fax34::decoder::DecodeStatus::Incomplete => {
303
637k
                    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
637k
                    let transitions = fax34::decoder::pels(self.decoder.transition(), self.width);
311
312
637k
                    let buffer = self.line_buf.get_mut();
313
637k
                    buffer.resize(usize::from(self.width).div_ceil(8), 0u8);
314
315
637k
                    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
843M
                    let mut bits = transitions.map(|c| match c {
335
310M
                        fax34::Color::Black => true,
336
532M
                        fax34::Color::White => false,
337
843M
                    });
<tiff::decoder::stream::Group4Reader<&mut std::io::cursor::Cursor<&[u8]>> as std::io::Read>::read::{closure#0}
Line
Count
Source
334
843M
                    let mut bits = transitions.map(|c| match c {
335
310M
                        fax34::Color::Black => true,
336
532M
                        fax34::Color::White => false,
337
843M
                    });
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
106M
                    for byte in target {
341
105M
                        let mut val = 0;
342
343
843M
                        for (idx, bit) in bits.by_ref().take(8).enumerate() {
344
843M
                            val |= u8::from(bit) << (7 - idx % 8);
345
843M
                        }
346
347
105M
                        *byte = val;
348
                    }
349
350
637k
                    self.line_buf.set_position(0);
351
                }
352
            }
353
1.62k
        }
354
355
639k
        self.line_buf.read(buf)
356
639k
    }
<tiff::decoder::stream::Group4Reader<&mut std::io::cursor::Cursor<&[u8]>> as std::io::Read>::read
Line
Count
Source
293
639k
    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
639k
        if self.line_buf.position() as usize == self.line_buf.get_ref().len()
296
637k
            && self.y < self.height
297
        {
298
637k
            let next = self.decoder.advance().map_err(std::io::Error::other)?;
299
300
637k
            match next {
301
401
                fax34::decoder::DecodeStatus::End => (),
302
                fax34::decoder::DecodeStatus::Incomplete => {
303
637k
                    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
637k
                    let transitions = fax34::decoder::pels(self.decoder.transition(), self.width);
311
312
637k
                    let buffer = self.line_buf.get_mut();
313
637k
                    buffer.resize(usize::from(self.width).div_ceil(8), 0u8);
314
315
637k
                    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
637k
                    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
106M
                    for byte in target {
341
105M
                        let mut val = 0;
342
343
843M
                        for (idx, bit) in bits.by_ref().take(8).enumerate() {
344
843M
                            val |= u8::from(bit) << (7 - idx % 8);
345
843M
                        }
346
347
105M
                        *byte = val;
348
                    }
349
350
637k
                    self.line_buf.set_position(0);
351
                }
352
            }
353
1.62k
        }
354
355
639k
        self.line_buf.read(buf)
356
639k
    }
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
}