Make it an extension trait of Read

This commit is contained in:
A. Molzer committed 2026-08-10 21:09:32 +02:00
1 parent 5942111bb5
commit 988a5a0c07
2 files changed
+9 -12

No files matched your search

+5 -5
View File
@@ -1204,7 +1204,7 @@ impl Image {
let mut packed = vec![0u8; chunk_row_bytes]; let mut packed = vec![0u8; chunk_row_bytes];
for row in buf.chunks_mut(layout.row_stride).take(data_dims.1 as usize) { for row in buf.chunks_mut(layout.row_stride).take(data_dims.1 as usize) {
reader.read_samples(&mut packed)?; reader.read_exact(&mut packed)?;
let out_row = &mut row[..data_row_bytes]; let out_row = &mut row[..data_row_bytes];
unpack_bits(&packed, out_row, tiff_bps, samples_per_data_row, out_bps); unpack_bits(&packed, out_row, tiff_bps, samples_per_data_row, out_bps);
@@ -1238,7 +1238,7 @@ impl Image {
} else if is_output_chunk_rows && is_all_bits { } else if is_output_chunk_rows && is_all_bits {
// Here we can read directly into the output buffer itself. // Here we can read directly into the output buffer itself.
let tile = &mut buf[..chunk_row_bytes * data_dims.1 as usize]; let tile = &mut buf[..chunk_row_bytes * data_dims.1 as usize];
reader.read_samples(tile)?; reader.read_exact(tile)?;
for row in tile.chunks_mut(chunk_row_bytes) { for row in tile.chunks_mut(chunk_row_bytes) {
super::fix_endianness_and_predict( super::fix_endianness_and_predict(
@@ -1272,7 +1272,7 @@ impl Image {
// this case is handled specially when needed. // this case is handled specially when needed.
let mut encoded = vec![0u8; chunk_row_bytes]; let mut encoded = vec![0u8; chunk_row_bytes];
for row in buf.chunks_mut(layout.row_stride).take(data_dims.1 as usize) { for row in buf.chunks_mut(layout.row_stride).take(data_dims.1 as usize) {
reader.read_samples(&mut encoded)?; reader.read_exact(&mut encoded)?;
let row = &mut row[..data_row_bytes]; let row = &mut row[..data_row_bytes];
match color_type.bit_depth() { match color_type.bit_depth() {
@@ -1313,7 +1313,7 @@ impl Image {
let skip = u64::try_from(chunk_row_bytes - data_row_bytes)?; let skip = u64::try_from(chunk_row_bytes - data_row_bytes)?;
reader.read_padded_samples(&mut row[..used], skip)?; reader.read_padded_samples(&mut row[..used], skip)?;
} else { } else {
reader.read_samples(&mut row[..used])?; reader.read_exact(&mut row[..used])?;
} }
super::fix_endianness_and_predict( super::fix_endianness_and_predict(
@@ -1371,7 +1371,7 @@ impl Image {
// width, and writing their horizontal padding would spill into the following // width, and writing their horizontal padding would spill into the following
// output row (and predict/invert would run past the chunk's own columns). // output row (and predict/invert would run past the chunk's own columns).
let row = &mut row[..data_row_bytes]; let row = &mut row[..data_row_bytes];
reader.read_samples(&mut encoded)?; reader.read_exact(&mut encoded)?;
Self::compact_photometric_bytes(&mut encoded, row, &photo_range); Self::compact_photometric_bytes(&mut encoded, row, &photo_range);
+4 -7
View File
@@ -124,6 +124,9 @@ impl<R: Read> EndianReader<R> {
/// A variant of `io::Read` that takes one block to the end. /// A variant of `io::Read` that takes one block to the end.
/// ///
/// This is derived from `Read` so that any special optimization done by `std` (or any nightly crate
/// for that matter) surely remains usable.
///
/// We want our decompression engines to be much more specialized than the standard library trait. /// We want our decompression engines to be much more specialized than the standard library trait.
/// Firstly there is more information available to communicate (the tiff Type, known decompressed /// Firstly there is more information available to communicate (the tiff Type, known decompressed
/// size, …) and secondly they can potentially *reset*. This could be solved with an extension trait /// size, …) and secondly they can potentially *reset*. This could be solved with an extension trait
@@ -134,9 +137,7 @@ impl<R: Read> EndianReader<R> {
/// discarding data *after* it is put into the output buffer. Yet, for some decompression that write /// discarding data *after* it is put into the output buffer. Yet, for some decompression that write
/// alone is considerable work where it could simply skip bits more efficiently. So the reader would /// alone is considerable work where it could simply skip bits more efficiently. So the reader would
/// likely want to know about a sample mask. /// likely want to know about a sample mask.
pub trait ReadSamples { pub trait ReadSamples: Read {
fn read_samples(&mut self, buf: &mut [u8]) -> io::Result<()>;
/// Read a row of samples and throw away some additional padding samples at the end. /// Read a row of samples and throw away some additional padding samples at the end.
/// ///
/// This is automatically implemented for `Self: Read` as a copy into `io::Sink`. /// This is automatically implemented for `Self: Read` as a copy into `io::Sink`.
@@ -144,10 +145,6 @@ pub trait ReadSamples {
} }
impl<R: Read> ReadSamples for R { impl<R: Read> ReadSamples for R {
fn read_samples(&mut self, buf: &mut [u8]) -> io::Result<()> {
self.read_exact(buf)
}
fn read_padded_samples(&mut self, buf: &mut [u8], discard: u64) -> io::Result<()> { fn read_padded_samples(&mut self, buf: &mut [u8], discard: u64) -> io::Result<()> {
self.read_exact(buf)?; self.read_exact(buf)?;
std::io::copy(&mut self.by_ref().take(discard), &mut std::io::sink())?; std::io::copy(&mut self.by_ref().take(discard), &mut std::io::sink())?;