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::collections::HashMap;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::io::{self, Read, Seek}; use std::io::{self, Read, Seek};
use std::{cmp, ops::Range};
use crate::{ use crate::{
bytecast, ColorType, TiffError, TiffFormatError, TiffResult, TiffUnsupportedError, UsageError, 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 where
'a: 'b, 'a: 'b,
{ {
match *self { match *self {
DecodingBuffer::U8(ref mut buf) => DecodingBuffer::U8(&mut buf[..new_length]), DecodingBuffer::U8(ref mut buf) => DecodingBuffer::U8(&mut buf[range]),
DecodingBuffer::U16(ref mut buf) => DecodingBuffer::U16(&mut buf[..new_length]), DecodingBuffer::U16(ref mut buf) => DecodingBuffer::U16(&mut buf[range]),
DecodingBuffer::U32(ref mut buf) => DecodingBuffer::U32(&mut buf[..new_length]), DecodingBuffer::U32(ref mut buf) => DecodingBuffer::U32(&mut buf[range]),
DecodingBuffer::U64(ref mut buf) => DecodingBuffer::U64(&mut buf[..new_length]), DecodingBuffer::U64(ref mut buf) => DecodingBuffer::U64(&mut buf[range]),
DecodingBuffer::F32(ref mut buf) => DecodingBuffer::F32(&mut buf[..new_length]), DecodingBuffer::F32(ref mut buf) => DecodingBuffer::F32(&mut buf[range]),
DecodingBuffer::F64(ref mut buf) => DecodingBuffer::F64(&mut buf[..new_length]), DecodingBuffer::F64(ref mut buf) => DecodingBuffer::F64(&mut buf[range]),
DecodingBuffer::I8(ref mut buf) => DecodingBuffer::I8(&mut buf[..new_length]), DecodingBuffer::I8(ref mut buf) => DecodingBuffer::I8(&mut buf[range]),
DecodingBuffer::I16(ref mut buf) => DecodingBuffer::I16(&mut buf[..new_length]), DecodingBuffer::I16(ref mut buf) => DecodingBuffer::I16(&mut buf[range]),
DecodingBuffer::I32(ref mut buf) => DecodingBuffer::I32(&mut buf[..new_length]), DecodingBuffer::I32(ref mut buf) => DecodingBuffer::I32(&mut buf[range]),
DecodingBuffer::I64(ref mut buf) => DecodingBuffer::I64(&mut buf[..new_length]), 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) { match (color_type, buf) {
(ColorType::Gray(64), DecodingBuffer::U64(ref mut buffer)) => { (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)) => { (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)) => { (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 => { (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)) => { (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)) => { (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. /// 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) { fn fix_endianness(buf: &mut DecodingBuffer, byte_order: ByteOrder) {
// "s" = start, "e" = end, used for better formatting
match byte_order { match byte_order {
ByteOrder::LittleEndian => match buf { ByteOrder::LittleEndian => match buf {
DecodingBuffer::U8(_) | DecodingBuffer::I8(_) => {} DecodingBuffer::U8(_) | DecodingBuffer::I8(_) => {}
DecodingBuffer::U16(b) => b[s..e].iter_mut().for_each(|v| *v = u16::from_le(*v)), DecodingBuffer::U16(b) => b.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::I16(b) => b.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::U32(b) => b.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::I32(b) => b.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::U64(b) => b.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::I64(b) => b.iter_mut().for_each(|v| *v = i64::from_le(*v)),
DecodingBuffer::F32(b) => b[s..e] DecodingBuffer::F32(b) => b
.iter_mut() .iter_mut()
.for_each(|v| *v = f32::from_bits(u32::from_le(v.to_bits()))), .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() .iter_mut()
.for_each(|v| *v = f64::from_bits(u64::from_le(v.to_bits()))), .for_each(|v| *v = f64::from_bits(u64::from_le(v.to_bits()))),
}, },
ByteOrder::BigEndian => match buf { ByteOrder::BigEndian => match buf {
DecodingBuffer::U8(_) | DecodingBuffer::I8(_) => {} DecodingBuffer::U8(_) | DecodingBuffer::I8(_) => {}
DecodingBuffer::U16(b) => b[s..e].iter_mut().for_each(|v| *v = u16::from_be(*v)), DecodingBuffer::U16(b) => b.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::I16(b) => b.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::U32(b) => b.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::I32(b) => b.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::U64(b) => b.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::I64(b) => b.iter_mut().for_each(|v| *v = i64::from_be(*v)),
DecodingBuffer::F32(b) => b[s..e] DecodingBuffer::F32(b) => b
.iter_mut() .iter_mut()
.for_each(|v| *v = f32::from_bits(u32::from_be(v.to_bits()))), .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() .iter_mut()
.for_each(|v| *v = f64::from_bits(u64::from_be(v.to_bits()))), .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(); 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. // Invert colors if necessary.
if self.photometric_interpretation == PhotometricInterpretation::WhiteIsZero { 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(()) Ok(())
@@ -1213,11 +1212,11 @@ impl<R: Read + Seek> Decoder<R> {
reader.read_exact(padding_buffer)? 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. // Invert colors if necessary.
if self.photometric_interpretation == PhotometricInterpretation::WhiteIsZero { 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; self.strip_decoder.as_mut().unwrap().strip_index += 1;
if u32::try_from(index)? == self.strip_count()? { if u32::try_from(index)? == self.strip_count()? {