Coverage Report

Created: 2026-02-26 07:34

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
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
}