diff --git a/src/encoder/compression/uncompressed.rs b/src/encoder/compression/uncompressed.rs index f414403..2385d9e 100644 --- a/src/encoder/compression/uncompressed.rs +++ b/src/encoder/compression/uncompressed.rs @@ -14,7 +14,7 @@ impl Compression for Uncompressed { impl CompressionAlgorithm for Uncompressed { fn write_to(&mut self, writer: &mut W, bytes: &[u8]) -> Result { - writer.write(bytes).map(|byte_count| byte_count as u64) + writer.write_all(bytes).map(|()| bytes.len() as u64) } } diff --git a/src/encoder/writer.rs b/src/encoder/writer.rs index f45038b..e3585cc 100644 --- a/src/encoder/writer.rs +++ b/src/encoder/writer.rs @@ -190,3 +190,58 @@ impl TiffWriter { Ok(()) } } + +#[test] +fn encoder_on_short_writes() { + struct ShortWriter { + inner: T, + } + + impl std::io::Write for ShortWriter { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + let lower_bound = buf.len().min(1); + let lower = buf.len().saturating_sub(1).max(lower_bound); + + self.inner.write(&buf[..lower]) + } + + fn flush(&mut self) -> std::io::Result<()> { + self.inner.flush() + } + } + + impl std::io::Seek for ShortWriter { + fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result { + self.inner.seek(pos) + } + } + + let mut write = ShortWriter { + inner: std::io::Cursor::new(vec![0u8; 0]), + }; + + let imgdata = vec![42u8; 100 * 100]; + for comp in [ + super::Compression::Uncompressed, + super::Compression::Packbits, + ] { + write.inner.set_position(0); + write.inner.get_mut().clear(); + + { + let mut tiff_writer = super::TiffEncoder::new(&mut write) + .unwrap() + .with_compression(comp); + + tiff_writer + .write_image::(100, 100, &imgdata) + .unwrap(); + } + + write.inner.set_position(0); + let mut tiff_reader = crate::decoder::Decoder::new(&mut write.inner).unwrap(); + let data = tiff_reader.read_image().unwrap(); + + assert!(matches!(data, crate::decoder::DecodingResult::U8(v) if v == imgdata)); + } +}