Switch from SmartReader to EndianReader (#233)
This commit is contained in:
1 parent
ee0dbf373b
commit
f44da4a00d
5 files changed
+78
-118
No files matched your search
+12
-12
@@ -5,7 +5,7 @@ use std::io::{self, Read, Seek};
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
use super::stream::{ByteOrder, EndianReader, SmartReader};
|
use super::stream::{ByteOrder, EndianReader};
|
||||||
use crate::tags::{Tag, Type};
|
use crate::tags::{Tag, Type};
|
||||||
use crate::{TiffError, TiffFormatError, TiffResult};
|
use crate::{TiffError, TiffFormatError, TiffResult};
|
||||||
|
|
||||||
@@ -364,22 +364,22 @@ impl Entry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a mem_reader for the offset/value field
|
/// Returns a mem_reader for the offset/value field
|
||||||
fn r(&self, byte_order: ByteOrder) -> SmartReader<io::Cursor<Vec<u8>>> {
|
fn r(&self, byte_order: ByteOrder) -> EndianReader<io::Cursor<Vec<u8>>> {
|
||||||
SmartReader::wrap(io::Cursor::new(self.offset.to_vec()), byte_order)
|
EndianReader::new(io::Cursor::new(self.offset.to_vec()), byte_order)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn val<R: Read + Seek>(
|
pub(crate) fn val<R: Read + Seek>(
|
||||||
&self,
|
&self,
|
||||||
limits: &super::Limits,
|
limits: &super::Limits,
|
||||||
bigtiff: bool,
|
bigtiff: bool,
|
||||||
reader: &mut SmartReader<R>,
|
reader: &mut EndianReader<R>,
|
||||||
) -> TiffResult<Value> {
|
) -> TiffResult<Value> {
|
||||||
// Case 1: there are no values so we can return immediately.
|
// Case 1: there are no values so we can return immediately.
|
||||||
if self.count == 0 {
|
if self.count == 0 {
|
||||||
return Ok(List(Vec::new()));
|
return Ok(List(Vec::new()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let bo = reader.byte_order();
|
let bo = reader.byte_order;
|
||||||
|
|
||||||
let tag_size = match self.type_ {
|
let tag_size = match self.type_ {
|
||||||
Type::BYTE | Type::SBYTE | Type::ASCII | Type::UNDEFINED => 1,
|
Type::BYTE | Type::SBYTE | Type::ASCII | Type::UNDEFINED => 1,
|
||||||
@@ -482,7 +482,7 @@ impl Entry {
|
|||||||
Type::SBYTE => return offset_to_sbytes(self.count as usize, self),
|
Type::SBYTE => return offset_to_sbytes(self.count as usize, self),
|
||||||
Type::ASCII => {
|
Type::ASCII => {
|
||||||
let mut buf = vec![0; self.count as usize];
|
let mut buf = vec![0; self.count as usize];
|
||||||
self.r(bo).read_exact(&mut buf)?;
|
buf.copy_from_slice(&self.offset[..self.count as usize]);
|
||||||
if buf.is_ascii() && buf.ends_with(&[0]) {
|
if buf.is_ascii() && buf.ends_with(&[0]) {
|
||||||
let v = str::from_utf8(&buf)?;
|
let v = str::from_utf8(&buf)?;
|
||||||
let v = v.trim_matches(char::from(0));
|
let v = v.trim_matches(char::from(0));
|
||||||
@@ -564,7 +564,7 @@ impl Entry {
|
|||||||
// at a different endianess of file/computer.
|
// at a different endianess of file/computer.
|
||||||
Type::BYTE => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| {
|
Type::BYTE => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| {
|
||||||
let mut buf = [0; 1];
|
let mut buf = [0; 1];
|
||||||
reader.read_exact(&mut buf)?;
|
reader.inner().read_exact(&mut buf)?;
|
||||||
Ok(UnsignedBig(u64::from(buf[0])))
|
Ok(UnsignedBig(u64::from(buf[0])))
|
||||||
}),
|
}),
|
||||||
Type::SBYTE => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| {
|
Type::SBYTE => self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| {
|
||||||
@@ -613,7 +613,7 @@ impl Entry {
|
|||||||
Type::UNDEFINED => {
|
Type::UNDEFINED => {
|
||||||
self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| {
|
self.decode_offset(self.count, bo, bigtiff, limits, reader, |reader| {
|
||||||
let mut buf = [0; 1];
|
let mut buf = [0; 1];
|
||||||
reader.read_exact(&mut buf)?;
|
reader.inner().read_exact(&mut buf)?;
|
||||||
Ok(Byte(buf[0]))
|
Ok(Byte(buf[0]))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -630,7 +630,7 @@ impl Entry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut out = vec![0; n];
|
let mut out = vec![0; n];
|
||||||
reader.read_exact(&mut out)?;
|
reader.inner().read_exact(&mut out)?;
|
||||||
// Strings may be null-terminated, so we trim anything downstream of the null byte
|
// Strings may be null-terminated, so we trim anything downstream of the null byte
|
||||||
if let Some(first) = out.iter().position(|&b| b == 0) {
|
if let Some(first) = out.iter().position(|&b| b == 0) {
|
||||||
out.truncate(first);
|
out.truncate(first);
|
||||||
@@ -647,12 +647,12 @@ impl Entry {
|
|||||||
bo: ByteOrder,
|
bo: ByteOrder,
|
||||||
bigtiff: bool,
|
bigtiff: bool,
|
||||||
limits: &super::Limits,
|
limits: &super::Limits,
|
||||||
reader: &mut SmartReader<R>,
|
reader: &mut EndianReader<R>,
|
||||||
decode_fn: F,
|
decode_fn: F,
|
||||||
) -> TiffResult<Value>
|
) -> TiffResult<Value>
|
||||||
where
|
where
|
||||||
R: Read + Seek,
|
R: Read + Seek,
|
||||||
F: Fn(&mut SmartReader<R>) -> TiffResult<Value>,
|
F: Fn(&mut EndianReader<R>) -> TiffResult<Value>,
|
||||||
{
|
{
|
||||||
let value_count = usize::try_from(value_count)?;
|
let value_count = usize::try_from(value_count)?;
|
||||||
if value_count > limits.decoding_buffer_size / mem::size_of::<Value>() {
|
if value_count > limits.decoding_buffer_size / mem::size_of::<Value>() {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use super::ifd::{Directory, Value};
|
|||||||
use super::stream::{ByteOrder, DeflateReader, LZWReader, PackBitsReader};
|
use super::stream::{ByteOrder, DeflateReader, LZWReader, PackBitsReader};
|
||||||
use super::tag_reader::TagReader;
|
use super::tag_reader::TagReader;
|
||||||
use super::{predict_f16, predict_f32, predict_f64, Limits};
|
use super::{predict_f16, predict_f32, predict_f64, Limits};
|
||||||
use super::{stream::SmartReader, ChunkType};
|
use super::{stream::EndianReader, ChunkType};
|
||||||
use crate::tags::{
|
use crate::tags::{
|
||||||
CompressionMethod, PhotometricInterpretation, PlanarConfiguration, Predictor, SampleFormat, Tag,
|
CompressionMethod, PhotometricInterpretation, PlanarConfiguration, Predictor, SampleFormat, Tag,
|
||||||
};
|
};
|
||||||
@@ -80,7 +80,7 @@ pub(crate) struct Image {
|
|||||||
|
|
||||||
impl Image {
|
impl Image {
|
||||||
pub fn from_reader<R: Read + Seek>(
|
pub fn from_reader<R: Read + Seek>(
|
||||||
reader: &mut SmartReader<R>,
|
reader: &mut EndianReader<R>,
|
||||||
ifd: Directory,
|
ifd: Directory,
|
||||||
limits: &Limits,
|
limits: &Limits,
|
||||||
bigtiff: bool,
|
bigtiff: bool,
|
||||||
|
|||||||
+16
-16
@@ -12,7 +12,7 @@ use half::f16;
|
|||||||
|
|
||||||
use self::ifd::Directory;
|
use self::ifd::Directory;
|
||||||
use self::image::Image;
|
use self::image::Image;
|
||||||
use self::stream::{ByteOrder, EndianReader, SmartReader};
|
use self::stream::{ByteOrder, EndianReader};
|
||||||
|
|
||||||
pub mod ifd;
|
pub mod ifd;
|
||||||
mod image;
|
mod image;
|
||||||
@@ -260,7 +260,7 @@ pub struct Decoder<R>
|
|||||||
where
|
where
|
||||||
R: Read + Seek,
|
R: Read + Seek,
|
||||||
{
|
{
|
||||||
reader: SmartReader<R>,
|
reader: EndianReader<R>,
|
||||||
bigtiff: bool,
|
bigtiff: bool,
|
||||||
limits: Limits,
|
limits: Limits,
|
||||||
next_ifd: Option<u64>,
|
next_ifd: Option<u64>,
|
||||||
@@ -462,7 +462,7 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let mut reader = SmartReader::wrap(r, byte_order);
|
let mut reader = EndianReader::new(r, byte_order);
|
||||||
|
|
||||||
let bigtiff = match reader.read_u16()? {
|
let bigtiff = match reader.read_u16()? {
|
||||||
42 => false,
|
42 => false,
|
||||||
@@ -640,7 +640,7 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn read_byte(&mut self) -> Result<u8, io::Error> {
|
pub fn read_byte(&mut self) -> Result<u8, io::Error> {
|
||||||
let mut buf = [0; 1];
|
let mut buf = [0; 1];
|
||||||
self.reader.read_exact(&mut buf)?;
|
self.reader.inner().read_exact(&mut buf)?;
|
||||||
Ok(buf[0])
|
Ok(buf[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -694,7 +694,7 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn read_string(&mut self, length: usize) -> TiffResult<String> {
|
pub fn read_string(&mut self, length: usize) -> TiffResult<String> {
|
||||||
let mut out = vec![0; length];
|
let mut out = vec![0; length];
|
||||||
self.reader.read_exact(&mut out)?;
|
self.reader.inner().read_exact(&mut out)?;
|
||||||
// Strings may be null-terminated, so we trim anything downstream of the null byte
|
// Strings may be null-terminated, so we trim anything downstream of the null byte
|
||||||
if let Some(first) = out.iter().position(|&b| b == 0) {
|
if let Some(first) = out.iter().position(|&b| b == 0) {
|
||||||
out.truncate(first);
|
out.truncate(first);
|
||||||
@@ -711,7 +711,7 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
let mut val = [0; 4];
|
let mut val = [0; 4];
|
||||||
self.reader.read_exact(&mut val)?;
|
self.reader.inner().read_exact(&mut val)?;
|
||||||
Ok(val)
|
Ok(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -719,7 +719,7 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn read_offset_u64(&mut self) -> Result<[u8; 8], io::Error> {
|
pub fn read_offset_u64(&mut self) -> Result<[u8; 8], io::Error> {
|
||||||
let mut val = [0; 8];
|
let mut val = [0; 8];
|
||||||
self.reader.read_exact(&mut val)?;
|
self.reader.inner().read_exact(&mut val)?;
|
||||||
Ok(val)
|
Ok(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -731,7 +731,7 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn goto_offset_u64(&mut self, offset: u64) -> io::Result<()> {
|
pub fn goto_offset_u64(&mut self, offset: u64) -> io::Result<()> {
|
||||||
self.reader.seek(io::SeekFrom::Start(offset)).map(|_| ())
|
self.reader.goto_offset(offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reads a IFD entry.
|
/// Reads a IFD entry.
|
||||||
@@ -742,7 +742,7 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
// Count 4 bytes
|
// Count 4 bytes
|
||||||
// Value 4 bytes either a pointer the value itself
|
// Value 4 bytes either a pointer the value itself
|
||||||
fn read_entry(
|
fn read_entry(
|
||||||
reader: &mut SmartReader<R>,
|
reader: &mut EndianReader<R>,
|
||||||
bigtiff: bool,
|
bigtiff: bool,
|
||||||
) -> TiffResult<Option<(Tag, ifd::Entry)>> {
|
) -> TiffResult<Option<(Tag, ifd::Entry)>> {
|
||||||
let tag = Tag::from_u16_exhaustive(reader.read_u16()?);
|
let tag = Tag::from_u16_exhaustive(reader.read_u16()?);
|
||||||
@@ -759,13 +759,13 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
let mut offset = [0; 8];
|
let mut offset = [0; 8];
|
||||||
|
|
||||||
let count = reader.read_u64()?;
|
let count = reader.read_u64()?;
|
||||||
reader.read_exact(&mut offset)?;
|
reader.inner().read_exact(&mut offset)?;
|
||||||
ifd::Entry::new_u64(type_, count, offset)
|
ifd::Entry::new_u64(type_, count, offset)
|
||||||
} else {
|
} else {
|
||||||
let mut offset = [0; 4];
|
let mut offset = [0; 4];
|
||||||
|
|
||||||
let count = reader.read_u32()?;
|
let count = reader.read_u32()?;
|
||||||
reader.read_exact(&mut offset)?;
|
reader.inner().read_exact(&mut offset)?;
|
||||||
ifd::Entry::new(type_, count, offset)
|
ifd::Entry::new(type_, count, offset)
|
||||||
};
|
};
|
||||||
Ok(Some((tag, entry)))
|
Ok(Some((tag, entry)))
|
||||||
@@ -773,7 +773,7 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
|
|
||||||
/// Reads the IFD starting at the indicated location.
|
/// Reads the IFD starting at the indicated location.
|
||||||
fn read_ifd(
|
fn read_ifd(
|
||||||
reader: &mut SmartReader<R>,
|
reader: &mut EndianReader<R>,
|
||||||
bigtiff: bool,
|
bigtiff: bool,
|
||||||
ifd_location: u64,
|
ifd_location: u64,
|
||||||
) -> TiffResult<(Directory, Option<u64>)> {
|
) -> TiffResult<(Directory, Option<u64>)> {
|
||||||
@@ -984,7 +984,7 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
output_width: usize,
|
output_width: usize,
|
||||||
) -> TiffResult<()> {
|
) -> TiffResult<()> {
|
||||||
let offset = self.image.chunk_file_range(chunk_index)?.0;
|
let offset = self.image.chunk_file_range(chunk_index)?.0;
|
||||||
self.goto_offset_u64(offset)?;
|
self.reader.goto_offset(offset)?;
|
||||||
|
|
||||||
let byte_order = self.reader.byte_order;
|
let byte_order = self.reader.byte_order;
|
||||||
|
|
||||||
@@ -994,7 +994,7 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
/ 8;
|
/ 8;
|
||||||
|
|
||||||
self.image.expand_chunk(
|
self.image.expand_chunk(
|
||||||
&mut self.reader,
|
self.reader.inner(),
|
||||||
buffer.as_bytes_mut(),
|
buffer.as_bytes_mut(),
|
||||||
output_row_stride.try_into()?,
|
output_row_stride.try_into()?,
|
||||||
byte_order,
|
byte_order,
|
||||||
@@ -1129,7 +1129,7 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
// * pass requested band as parameter
|
// * pass requested band as parameter
|
||||||
// * collect bands to a RGB encoding result in case of RGB bands
|
// * collect bands to a RGB encoding result in case of RGB bands
|
||||||
for chunk in 0..image_chunks {
|
for chunk in 0..image_chunks {
|
||||||
self.goto_offset_u64(self.image().chunk_offsets[chunk])?;
|
self.reader.goto_offset(self.image().chunk_offsets[chunk])?;
|
||||||
|
|
||||||
let x = chunk % chunks_across;
|
let x = chunk % chunks_across;
|
||||||
let y = chunk / chunks_across;
|
let y = chunk / chunks_across;
|
||||||
@@ -1137,7 +1137,7 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
y * output_row_stride * chunk_dimensions.1 as usize + x * chunk_row_bytes;
|
y * output_row_stride * chunk_dimensions.1 as usize + x * chunk_row_bytes;
|
||||||
let byte_order = self.reader.byte_order;
|
let byte_order = self.reader.byte_order;
|
||||||
self.image.expand_chunk(
|
self.image.expand_chunk(
|
||||||
&mut self.reader,
|
self.reader.inner(),
|
||||||
&mut result.as_buffer(0).as_bytes_mut()[buffer_offset..],
|
&mut result.as_buffer(0).as_bytes_mut()[buffer_offset..],
|
||||||
output_row_stride,
|
output_row_stride,
|
||||||
byte_order,
|
byte_order,
|
||||||
|
|||||||
+46
-86
@@ -12,16 +12,32 @@ pub enum ByteOrder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Reader that is aware of the byte order.
|
/// Reader that is aware of the byte order.
|
||||||
pub trait EndianReader: Read {
|
#[derive(Debug)]
|
||||||
/// Byte order that should be adhered to
|
pub struct EndianReader<R> {
|
||||||
fn byte_order(&self) -> ByteOrder;
|
reader: R,
|
||||||
|
pub(crate) byte_order: ByteOrder,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: Read + Seek> EndianReader<R> {
|
||||||
|
pub fn new(reader: R, byte_order: ByteOrder) -> Self {
|
||||||
|
Self { reader, byte_order }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn inner(&mut self) -> &mut R {
|
||||||
|
&mut self.reader
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn goto_offset(&mut self, offset: u64) -> io::Result<()> {
|
||||||
|
self.reader.seek(io::SeekFrom::Start(offset))?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Reads an u16
|
/// Reads an u16
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn read_u16(&mut self) -> Result<u16, io::Error> {
|
pub fn read_u16(&mut self) -> Result<u16, io::Error> {
|
||||||
let mut n = [0u8; 2];
|
let mut n = [0u8; 2];
|
||||||
self.read_exact(&mut n)?;
|
self.reader.read_exact(&mut n)?;
|
||||||
Ok(match self.byte_order() {
|
Ok(match self.byte_order {
|
||||||
ByteOrder::LittleEndian => u16::from_le_bytes(n),
|
ByteOrder::LittleEndian => u16::from_le_bytes(n),
|
||||||
ByteOrder::BigEndian => u16::from_be_bytes(n),
|
ByteOrder::BigEndian => u16::from_be_bytes(n),
|
||||||
})
|
})
|
||||||
@@ -29,10 +45,10 @@ pub trait EndianReader: Read {
|
|||||||
|
|
||||||
/// Reads an i8
|
/// Reads an i8
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn read_i8(&mut self) -> Result<i8, io::Error> {
|
pub fn read_i8(&mut self) -> Result<i8, io::Error> {
|
||||||
let mut n = [0u8; 1];
|
let mut n = [0u8; 1];
|
||||||
self.read_exact(&mut n)?;
|
self.reader.read_exact(&mut n)?;
|
||||||
Ok(match self.byte_order() {
|
Ok(match self.byte_order {
|
||||||
ByteOrder::LittleEndian => i8::from_le_bytes(n),
|
ByteOrder::LittleEndian => i8::from_le_bytes(n),
|
||||||
ByteOrder::BigEndian => i8::from_be_bytes(n),
|
ByteOrder::BigEndian => i8::from_be_bytes(n),
|
||||||
})
|
})
|
||||||
@@ -40,10 +56,10 @@ pub trait EndianReader: Read {
|
|||||||
|
|
||||||
/// Reads an i16
|
/// Reads an i16
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn read_i16(&mut self) -> Result<i16, io::Error> {
|
pub fn read_i16(&mut self) -> Result<i16, io::Error> {
|
||||||
let mut n = [0u8; 2];
|
let mut n = [0u8; 2];
|
||||||
self.read_exact(&mut n)?;
|
self.reader.read_exact(&mut n)?;
|
||||||
Ok(match self.byte_order() {
|
Ok(match self.byte_order {
|
||||||
ByteOrder::LittleEndian => i16::from_le_bytes(n),
|
ByteOrder::LittleEndian => i16::from_le_bytes(n),
|
||||||
ByteOrder::BigEndian => i16::from_be_bytes(n),
|
ByteOrder::BigEndian => i16::from_be_bytes(n),
|
||||||
})
|
})
|
||||||
@@ -51,10 +67,10 @@ pub trait EndianReader: Read {
|
|||||||
|
|
||||||
/// Reads an u32
|
/// Reads an u32
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn read_u32(&mut self) -> Result<u32, io::Error> {
|
pub fn read_u32(&mut self) -> Result<u32, io::Error> {
|
||||||
let mut n = [0u8; 4];
|
let mut n = [0u8; 4];
|
||||||
self.read_exact(&mut n)?;
|
self.reader.read_exact(&mut n)?;
|
||||||
Ok(match self.byte_order() {
|
Ok(match self.byte_order {
|
||||||
ByteOrder::LittleEndian => u32::from_le_bytes(n),
|
ByteOrder::LittleEndian => u32::from_le_bytes(n),
|
||||||
ByteOrder::BigEndian => u32::from_be_bytes(n),
|
ByteOrder::BigEndian => u32::from_be_bytes(n),
|
||||||
})
|
})
|
||||||
@@ -62,10 +78,10 @@ pub trait EndianReader: Read {
|
|||||||
|
|
||||||
/// Reads an i32
|
/// Reads an i32
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn read_i32(&mut self) -> Result<i32, io::Error> {
|
pub fn read_i32(&mut self) -> Result<i32, io::Error> {
|
||||||
let mut n = [0u8; 4];
|
let mut n = [0u8; 4];
|
||||||
self.read_exact(&mut n)?;
|
self.reader.read_exact(&mut n)?;
|
||||||
Ok(match self.byte_order() {
|
Ok(match self.byte_order {
|
||||||
ByteOrder::LittleEndian => i32::from_le_bytes(n),
|
ByteOrder::LittleEndian => i32::from_le_bytes(n),
|
||||||
ByteOrder::BigEndian => i32::from_be_bytes(n),
|
ByteOrder::BigEndian => i32::from_be_bytes(n),
|
||||||
})
|
})
|
||||||
@@ -73,10 +89,10 @@ pub trait EndianReader: Read {
|
|||||||
|
|
||||||
/// Reads an u64
|
/// Reads an u64
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn read_u64(&mut self) -> Result<u64, io::Error> {
|
pub fn read_u64(&mut self) -> Result<u64, io::Error> {
|
||||||
let mut n = [0u8; 8];
|
let mut n = [0u8; 8];
|
||||||
self.read_exact(&mut n)?;
|
self.reader.read_exact(&mut n)?;
|
||||||
Ok(match self.byte_order() {
|
Ok(match self.byte_order {
|
||||||
ByteOrder::LittleEndian => u64::from_le_bytes(n),
|
ByteOrder::LittleEndian => u64::from_le_bytes(n),
|
||||||
ByteOrder::BigEndian => u64::from_be_bytes(n),
|
ByteOrder::BigEndian => u64::from_be_bytes(n),
|
||||||
})
|
})
|
||||||
@@ -84,10 +100,10 @@ pub trait EndianReader: Read {
|
|||||||
|
|
||||||
/// Reads an i64
|
/// Reads an i64
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn read_i64(&mut self) -> Result<i64, io::Error> {
|
pub fn read_i64(&mut self) -> Result<i64, io::Error> {
|
||||||
let mut n = [0u8; 8];
|
let mut n = [0u8; 8];
|
||||||
self.read_exact(&mut n)?;
|
self.reader.read_exact(&mut n)?;
|
||||||
Ok(match self.byte_order() {
|
Ok(match self.byte_order {
|
||||||
ByteOrder::LittleEndian => i64::from_le_bytes(n),
|
ByteOrder::LittleEndian => i64::from_le_bytes(n),
|
||||||
ByteOrder::BigEndian => i64::from_be_bytes(n),
|
ByteOrder::BigEndian => i64::from_be_bytes(n),
|
||||||
})
|
})
|
||||||
@@ -95,10 +111,10 @@ pub trait EndianReader: Read {
|
|||||||
|
|
||||||
/// Reads an f32
|
/// Reads an f32
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn read_f32(&mut self) -> Result<f32, io::Error> {
|
pub fn read_f32(&mut self) -> Result<f32, io::Error> {
|
||||||
let mut n = [0u8; 4];
|
let mut n = [0u8; 4];
|
||||||
self.read_exact(&mut n)?;
|
self.reader.read_exact(&mut n)?;
|
||||||
Ok(f32::from_bits(match self.byte_order() {
|
Ok(f32::from_bits(match self.byte_order {
|
||||||
ByteOrder::LittleEndian => u32::from_le_bytes(n),
|
ByteOrder::LittleEndian => u32::from_le_bytes(n),
|
||||||
ByteOrder::BigEndian => u32::from_be_bytes(n),
|
ByteOrder::BigEndian => u32::from_be_bytes(n),
|
||||||
}))
|
}))
|
||||||
@@ -106,10 +122,10 @@ pub trait EndianReader: Read {
|
|||||||
|
|
||||||
/// Reads an f64
|
/// Reads an f64
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn read_f64(&mut self) -> Result<f64, io::Error> {
|
pub fn read_f64(&mut self) -> Result<f64, io::Error> {
|
||||||
let mut n = [0u8; 8];
|
let mut n = [0u8; 8];
|
||||||
self.read_exact(&mut n)?;
|
self.reader.read_exact(&mut n)?;
|
||||||
Ok(f64::from_bits(match self.byte_order() {
|
Ok(f64::from_bits(match self.byte_order {
|
||||||
ByteOrder::LittleEndian => u64::from_le_bytes(n),
|
ByteOrder::LittleEndian => u64::from_le_bytes(n),
|
||||||
ByteOrder::BigEndian => u64::from_be_bytes(n),
|
ByteOrder::BigEndian => u64::from_be_bytes(n),
|
||||||
}))
|
}))
|
||||||
@@ -252,62 +268,6 @@ impl<R: Read> Read for PackBitsReader<R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
/// ## SmartReader Reader
|
|
||||||
///
|
|
||||||
|
|
||||||
/// Reader that is aware of the byte order.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct SmartReader<R>
|
|
||||||
where
|
|
||||||
R: Read,
|
|
||||||
{
|
|
||||||
reader: R,
|
|
||||||
pub byte_order: ByteOrder,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R> SmartReader<R>
|
|
||||||
where
|
|
||||||
R: Read,
|
|
||||||
{
|
|
||||||
/// Wraps a reader
|
|
||||||
pub fn wrap(reader: R, byte_order: ByteOrder) -> SmartReader<R> {
|
|
||||||
SmartReader { reader, byte_order }
|
|
||||||
}
|
|
||||||
pub fn into_inner(self) -> R {
|
|
||||||
self.reader
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<R: Read + Seek> SmartReader<R> {
|
|
||||||
pub fn goto_offset(&mut self, offset: u64) -> io::Result<()> {
|
|
||||||
self.seek(io::SeekFrom::Start(offset)).map(|_| ())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R> EndianReader for SmartReader<R>
|
|
||||||
where
|
|
||||||
R: Read,
|
|
||||||
{
|
|
||||||
#[inline(always)]
|
|
||||||
fn byte_order(&self) -> ByteOrder {
|
|
||||||
self.byte_order
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R: Read> Read for SmartReader<R> {
|
|
||||||
#[inline]
|
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
|
||||||
self.reader.read(buf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R: Read + Seek> Seek for SmartReader<R> {
|
|
||||||
#[inline]
|
|
||||||
fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
|
|
||||||
self.reader.seek(pos)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ use crate::tags::Tag;
|
|||||||
use crate::{TiffError, TiffFormatError, TiffResult};
|
use crate::{TiffError, TiffFormatError, TiffResult};
|
||||||
|
|
||||||
use super::ifd::{Directory, Value};
|
use super::ifd::{Directory, Value};
|
||||||
use super::stream::SmartReader;
|
use super::stream::EndianReader;
|
||||||
use super::Limits;
|
use super::Limits;
|
||||||
|
|
||||||
pub(crate) struct TagReader<'a, R: Read + Seek> {
|
pub(crate) struct TagReader<'a, R: Read + Seek> {
|
||||||
pub reader: &'a mut SmartReader<R>,
|
pub reader: &'a mut EndianReader<R>,
|
||||||
pub ifd: &'a Directory,
|
pub ifd: &'a Directory,
|
||||||
pub limits: &'a Limits,
|
pub limits: &'a Limits,
|
||||||
pub bigtiff: bool,
|
pub bigtiff: bool,
|
||||||
|
|||||||
Reference in new issue
Block a user