implement subrange for DecodingBuffer

This commit is contained in:
Tomáš Král committed 2021-05-15 21:14:00 +02:00
1 parent 46c7efd836
commit d0e4f37a28
1 file changed
+41 -42
+41 -42
View File
@@ -1,7 +1,7 @@
use std::cmp;
use std::collections::HashMap;
use std::convert::TryFrom;
use std::io::{self, Read, Seek};
use std::{cmp, ops::Range};
use crate::{
bytecast, ColorType, TiffError, TiffFormatError, TiffResult, TiffUnsupportedError, UsageError,
@@ -214,21 +214,21 @@ impl<'a> DecodingBuffer<'a> {
}
}
fn prefix<'b>(&'b mut self, new_length: usize) -> DecodingBuffer<'b>
fn subrange<'b>(&'b mut self, range: Range<usize>) -> DecodingBuffer<'b>
where
'a: 'b,
{
match *self {
DecodingBuffer::U8(ref mut buf) => DecodingBuffer::U8(&mut buf[..new_length]),
DecodingBuffer::U16(ref mut buf) => DecodingBuffer::U16(&mut buf[..new_length]),
DecodingBuffer::U32(ref mut buf) => DecodingBuffer::U32(&mut buf[..new_length]),
DecodingBuffer::U64(ref mut buf) => DecodingBuffer::U64(&mut buf[..new_length]),
DecodingBuffer::F32(ref mut buf) => DecodingBuffer::F32(&mut buf[..new_length]),
DecodingBuffer::F64(ref mut buf) => DecodingBuffer::F64(&mut buf[..new_length]),
DecodingBuffer::I8(ref mut buf) => DecodingBuffer::I8(&mut buf[..new_length]),
DecodingBuffer::I16(ref mut buf) => DecodingBuffer::I16(&mut buf[..new_length]),
DecodingBuffer::I32(ref mut buf) => DecodingBuffer::I32(&mut buf[..new_length]),
DecodingBuffer::I64(ref mut buf) => DecodingBuffer::I64(&mut buf[..new_length]),
DecodingBuffer::U8(ref mut buf) => DecodingBuffer::U8(&mut buf[range]),
DecodingBuffer::U16(ref mut buf) => DecodingBuffer::U16(&mut buf[range]),
DecodingBuffer::U32(ref mut buf) => DecodingBuffer::U32(&mut buf[range]),
DecodingBuffer::U64(ref mut buf) => DecodingBuffer::U64(&mut buf[range]),
DecodingBuffer::F32(ref mut buf) => DecodingBuffer::F32(&mut buf[range]),
DecodingBuffer::F64(ref mut buf) => DecodingBuffer::F64(&mut buf[range]),
DecodingBuffer::I8(ref mut buf) => DecodingBuffer::I8(&mut buf[range]),
DecodingBuffer::I16(ref mut buf) => DecodingBuffer::I16(&mut buf[range]),
DecodingBuffer::I32(ref mut buf) => DecodingBuffer::I32(&mut buf[range]),
DecodingBuffer::I64(ref mut buf) => DecodingBuffer::I64(&mut buf[range]),
}
}
}
@@ -1026,61 +1026,60 @@ impl<R: Read + Seek> Decoder<R> {
}
}
fn invert_colors(buf: &mut DecodingBuffer, color_type: ColorType, start: usize, end: usize) {
fn invert_colors(buf: &mut DecodingBuffer, color_type: ColorType) {
match (color_type, buf) {
(ColorType::Gray(64), DecodingBuffer::U64(ref mut buffer)) => {
Self::invert_colors_unsigned(&mut buffer[start..end], u64::MAX);
Self::invert_colors_unsigned(buffer, u64::MAX);
}
(ColorType::Gray(32), DecodingBuffer::U32(ref mut buffer)) => {
Self::invert_colors_unsigned(&mut buffer[start..end], u32::MAX);
Self::invert_colors_unsigned(buffer, u32::MAX);
}
(ColorType::Gray(16), DecodingBuffer::U16(ref mut buffer)) => {
Self::invert_colors_unsigned(&mut buffer[start..end], u16::MAX);
Self::invert_colors_unsigned(buffer, u16::MAX);
}
(ColorType::Gray(n), DecodingBuffer::U8(ref mut buffer)) if n <= 8 => {
Self::invert_colors_unsigned(&mut buffer[start..end], u8::MAX);
Self::invert_colors_unsigned(buffer, u8::MAX);
}
(ColorType::Gray(32), DecodingBuffer::F32(ref mut buffer)) => {
Self::invert_colors_fp(&mut buffer[start..end], 1.0);
Self::invert_colors_fp(buffer, 1.0);
}
(ColorType::Gray(64), DecodingBuffer::F64(ref mut buffer)) => {
Self::invert_colors_fp(&mut buffer[start..end], 1.0);
Self::invert_colors_fp(buffer, 1.0);
}
_ => {}
}
}
/// Fix endianness. If `byte_order` matches the host, then conversion is a no-op.
fn fix_endianness(buf: &mut DecodingBuffer, byte_order: ByteOrder, s: usize, e: usize) {
// "s" = start, "e" = end, used for better formatting
fn fix_endianness(buf: &mut DecodingBuffer, byte_order: ByteOrder) {
match byte_order {
ByteOrder::LittleEndian => match buf {
DecodingBuffer::U8(_) | DecodingBuffer::I8(_) => {}
DecodingBuffer::U16(b) => b[s..e].iter_mut().for_each(|v| *v = u16::from_le(*v)),
DecodingBuffer::I16(b) => b[s..e].iter_mut().for_each(|v| *v = i16::from_le(*v)),
DecodingBuffer::U32(b) => b[s..e].iter_mut().for_each(|v| *v = u32::from_le(*v)),
DecodingBuffer::I32(b) => b[s..e].iter_mut().for_each(|v| *v = i32::from_le(*v)),
DecodingBuffer::U64(b) => b[s..e].iter_mut().for_each(|v| *v = u64::from_le(*v)),
DecodingBuffer::I64(b) => b[s..e].iter_mut().for_each(|v| *v = i64::from_le(*v)),
DecodingBuffer::F32(b) => b[s..e]
DecodingBuffer::U16(b) => b.iter_mut().for_each(|v| *v = u16::from_le(*v)),
DecodingBuffer::I16(b) => b.iter_mut().for_each(|v| *v = i16::from_le(*v)),
DecodingBuffer::U32(b) => b.iter_mut().for_each(|v| *v = u32::from_le(*v)),
DecodingBuffer::I32(b) => b.iter_mut().for_each(|v| *v = i32::from_le(*v)),
DecodingBuffer::U64(b) => b.iter_mut().for_each(|v| *v = u64::from_le(*v)),
DecodingBuffer::I64(b) => b.iter_mut().for_each(|v| *v = i64::from_le(*v)),
DecodingBuffer::F32(b) => b
.iter_mut()
.for_each(|v| *v = f32::from_bits(u32::from_le(v.to_bits()))),
DecodingBuffer::F64(b) => b[s..e]
DecodingBuffer::F64(b) => b
.iter_mut()
.for_each(|v| *v = f64::from_bits(u64::from_le(v.to_bits()))),
},
ByteOrder::BigEndian => match buf {
DecodingBuffer::U8(_) | DecodingBuffer::I8(_) => {}
DecodingBuffer::U16(b) => b[s..e].iter_mut().for_each(|v| *v = u16::from_be(*v)),
DecodingBuffer::I16(b) => b[s..e].iter_mut().for_each(|v| *v = i16::from_be(*v)),
DecodingBuffer::U32(b) => b[s..e].iter_mut().for_each(|v| *v = u32::from_be(*v)),
DecodingBuffer::I32(b) => b[s..e].iter_mut().for_each(|v| *v = i32::from_be(*v)),
DecodingBuffer::U64(b) => b[s..e].iter_mut().for_each(|v| *v = u64::from_be(*v)),
DecodingBuffer::I64(b) => b[s..e].iter_mut().for_each(|v| *v = i64::from_be(*v)),
DecodingBuffer::F32(b) => b[s..e]
DecodingBuffer::U16(b) => b.iter_mut().for_each(|v| *v = u16::from_be(*v)),
DecodingBuffer::I16(b) => b.iter_mut().for_each(|v| *v = i16::from_be(*v)),
DecodingBuffer::U32(b) => b.iter_mut().for_each(|v| *v = u32::from_be(*v)),
DecodingBuffer::I32(b) => b.iter_mut().for_each(|v| *v = i32::from_be(*v)),
DecodingBuffer::U64(b) => b.iter_mut().for_each(|v| *v = u64::from_be(*v)),
DecodingBuffer::I64(b) => b.iter_mut().for_each(|v| *v = i64::from_be(*v)),
DecodingBuffer::F32(b) => b
.iter_mut()
.for_each(|v| *v = f32::from_bits(u32::from_be(v.to_bits()))),
DecodingBuffer::F64(b) => b[s..e]
DecodingBuffer::F64(b) => b
.iter_mut()
.for_each(|v| *v = f64::from_bits(u64::from_be(v.to_bits()))),
},
@@ -1145,11 +1144,11 @@ impl<R: Read + Seek> Decoder<R> {
}
let len = buffer.len();
Self::fix_endianness(&mut buffer, byte_order, 0, len);
Self::fix_endianness(&mut buffer.subrange(0..len), byte_order);
// Invert colors if necessary.
if self.photometric_interpretation == PhotometricInterpretation::WhiteIsZero {
Self::invert_colors(&mut buffer, color_type, 0, len);
Self::invert_colors(&mut buffer.subrange(0..len), color_type);
}
Ok(())
@@ -1213,11 +1212,11 @@ impl<R: Read + Seek> Decoder<R> {
reader.read_exact(padding_buffer)?
}
Self::fix_endianness(&mut buffer, self.byte_order, row_start, row_end);
Self::fix_endianness(&mut buffer.subrange(row_start..row_end), self.byte_order);
// Invert colors if necessary.
if self.photometric_interpretation == PhotometricInterpretation::WhiteIsZero {
Self::invert_colors(&mut buffer, color_type, row_start, row_end);
Self::invert_colors(&mut buffer.subrange(row_start..row_end), color_type);
}
}
@@ -1456,7 +1455,7 @@ impl<R: Read + Seek> Decoder<R> {
));
}
self.expand_strip(buffer.prefix(buffer_size), offset, byte_count)?;
self.expand_strip(buffer.subrange(0..buffer_size), offset, byte_count)?;
self.strip_decoder.as_mut().unwrap().strip_index += 1;
if u32::try_from(index)? == self.strip_count()? {