Coverage Report

Created: 2026-07-16 07:16

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