implement subrange for DecodingBuffer
This commit is contained in:
1 parent
46c7efd836
commit
d0e4f37a28
1 file changed
+41
-42
+41
-42
@@ -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()? {
|
||||
|
||||
Reference in new issue
Block a user