From ce1ee6776fa67d7b2bec9e0559f4116e83b8f9eb Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 24 Mar 2021 10:47:23 +0100 Subject: [PATCH] Move `TiffValue` trait to separate module --- src/encoder/mod.rs | 386 +------------------------------------- src/encoder/tiff_value.rs | 385 +++++++++++++++++++++++++++++++++++++ 2 files changed, 389 insertions(+), 382 deletions(-) create mode 100644 src/encoder/tiff_value.rs diff --git a/src/encoder/mod.rs b/src/encoder/mod.rs index c1f7680..ebe66f5 100644 --- a/src/encoder/mod.rs +++ b/src/encoder/mod.rs @@ -1,3 +1,5 @@ +pub use tiff_value::*; + use std::{ cmp, collections::BTreeMap, @@ -8,395 +10,15 @@ use std::{ num::TryFromIntError, }; -use crate::bytecast; -use crate::error::{TiffError, TiffFormatError, TiffResult}; -use crate::tags::{self, ResolutionUnit, Tag, Type}; +use crate::{error::TiffResult, tags::{self, ResolutionUnit, Tag}}; pub mod colortype; mod writer; +mod tiff_value; use self::colortype::*; use self::writer::*; -/// Type to represent tiff values of type `RATIONAL` -#[derive(Clone)] -pub struct Rational { - pub n: u32, - pub d: u32, -} - -/// Type to represent tiff values of type `SRATIONAL` -pub struct SRational { - pub n: i32, - pub d: i32, -} - -/// Trait for types that can be encoded in a tiff file -pub trait TiffValue { - const BYTE_LEN: u8; - const FIELD_TYPE: Type; - fn count(&self) -> usize; - fn bytes(&self) -> usize { - self.count() * usize::from(Self::BYTE_LEN) - } - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()>; -} - -impl TiffValue for [u8] { - const BYTE_LEN: u8 = 1; - const FIELD_TYPE: Type = Type::BYTE; - - fn count(&self) -> usize { - self.len() - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - writer.write_bytes(self)?; - Ok(()) - } -} - -impl TiffValue for [i8] { - const BYTE_LEN: u8 = 1; - const FIELD_TYPE: Type = Type::SBYTE; - - fn count(&self) -> usize { - self.len() - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - let slice = bytecast::i8_as_ne_bytes(self); - writer.write_bytes(slice)?; - Ok(()) - } -} - -impl TiffValue for [u16] { - const BYTE_LEN: u8 = 2; - const FIELD_TYPE: Type = Type::SHORT; - - fn count(&self) -> usize { - self.len() - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - let slice = bytecast::u16_as_ne_bytes(self); - writer.write_bytes(slice)?; - Ok(()) - } -} - -impl TiffValue for [i16] { - const BYTE_LEN: u8 = 2; - const FIELD_TYPE: Type = Type::SSHORT; - - fn count(&self) -> usize { - self.len() - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - let slice = bytecast::i16_as_ne_bytes(self); - writer.write_bytes(slice)?; - Ok(()) - } -} - -impl TiffValue for [u32] { - const BYTE_LEN: u8 = 4; - const FIELD_TYPE: Type = Type::LONG; - - fn count(&self) -> usize { - self.len() - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - let slice = bytecast::u32_as_ne_bytes(self); - writer.write_bytes(slice)?; - Ok(()) - } -} - -impl TiffValue for [i32] { - const BYTE_LEN: u8 = 4; - const FIELD_TYPE: Type = Type::SLONG; - - fn count(&self) -> usize { - self.len() - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - let slice = bytecast::i32_as_ne_bytes(self); - writer.write_bytes(slice)?; - Ok(()) - } -} - -impl TiffValue for [u64] { - const BYTE_LEN: u8 = 8; - const FIELD_TYPE: Type = Type::LONG8; - - fn count(&self) -> usize { - self.len() - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - let slice = bytecast::u64_as_ne_bytes(self); - writer.write_bytes(slice)?; - Ok(()) - } -} - -impl TiffValue for [f32] { - const BYTE_LEN: u8 = 4; - const FIELD_TYPE: Type = Type::FLOAT; - - fn count(&self) -> usize { - self.len() - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - // We write using nativeedian so this sould be safe - let slice = bytecast::f32_as_ne_bytes(self); - writer.write_bytes(slice)?; - Ok(()) - } -} - -impl TiffValue for [f64] { - const BYTE_LEN: u8 = 8; - const FIELD_TYPE: Type = Type::DOUBLE; - - fn count(&self) -> usize { - self.len() - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - // We write using nativeedian so this sould be safe - let slice = bytecast::f64_as_ne_bytes(self); - writer.write_bytes(slice)?; - Ok(()) - } -} - -impl TiffValue for [Rational] { - const BYTE_LEN: u8 = 8; - const FIELD_TYPE: Type = Type::RATIONAL; - - fn count(&self) -> usize { - self.len() - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - for x in self { - x.write(writer)?; - } - Ok(()) - } -} - -impl TiffValue for [SRational] { - const BYTE_LEN: u8 = 8; - const FIELD_TYPE: Type = Type::SRATIONAL; - - fn count(&self) -> usize { - self.len() - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - for x in self { - x.write(writer)?; - } - Ok(()) - } -} - -impl TiffValue for u8 { - const BYTE_LEN: u8 = 1; - const FIELD_TYPE: Type = Type::BYTE; - - fn count(&self) -> usize { - 1 - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - writer.write_u8(*self)?; - Ok(()) - } -} - -impl TiffValue for i8 { - const BYTE_LEN: u8 = 1; - const FIELD_TYPE: Type = Type::SBYTE; - - fn count(&self) -> usize { - 1 - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - writer.write_i8(*self)?; - Ok(()) - } -} - -impl TiffValue for u16 { - const BYTE_LEN: u8 = 2; - const FIELD_TYPE: Type = Type::SHORT; - - fn count(&self) -> usize { - 1 - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - writer.write_u16(*self)?; - Ok(()) - } -} - -impl TiffValue for i16 { - const BYTE_LEN: u8 = 2; - const FIELD_TYPE: Type = Type::SSHORT; - - fn count(&self) -> usize { - 1 - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - writer.write_i16(*self)?; - Ok(()) - } -} - -impl TiffValue for u32 { - const BYTE_LEN: u8 = 4; - const FIELD_TYPE: Type = Type::LONG; - - fn count(&self) -> usize { - 1 - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - writer.write_u32(*self)?; - Ok(()) - } -} - -impl TiffValue for i32 { - const BYTE_LEN: u8 = 4; - const FIELD_TYPE: Type = Type::SLONG; - - fn count(&self) -> usize { - 1 - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - writer.write_i32(*self)?; - Ok(()) - } -} - -impl TiffValue for u64 { - const BYTE_LEN: u8 = 8; - const FIELD_TYPE: Type = Type::LONG8; - - fn count(&self) -> usize { - 1 - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - writer.write_u64(*self)?; - Ok(()) - } -} - -impl TiffValue for f32 { - const BYTE_LEN: u8 = 4; - const FIELD_TYPE: Type = Type::FLOAT; - - fn count(&self) -> usize { - 1 - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - writer.write_f32(*self)?; - Ok(()) - } -} - -impl TiffValue for f64 { - const BYTE_LEN: u8 = 8; - const FIELD_TYPE: Type = Type::DOUBLE; - - fn count(&self) -> usize { - 1 - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - writer.write_f64(*self)?; - Ok(()) - } -} - -impl TiffValue for Rational { - const BYTE_LEN: u8 = 8; - const FIELD_TYPE: Type = Type::RATIONAL; - - fn count(&self) -> usize { - 1 - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - writer.write_u32(self.n)?; - writer.write_u32(self.d)?; - Ok(()) - } -} - -impl TiffValue for SRational { - const BYTE_LEN: u8 = 8; - const FIELD_TYPE: Type = Type::SRATIONAL; - - fn count(&self) -> usize { - 1 - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - writer.write_i32(self.n)?; - writer.write_i32(self.d)?; - Ok(()) - } -} - -impl TiffValue for str { - const BYTE_LEN: u8 = 1; - const FIELD_TYPE: Type = Type::ASCII; - - fn count(&self) -> usize { - self.len() + 1 - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - if self.is_ascii() && !self.bytes().any(|b| b == 0) { - writer.write_bytes(self.as_bytes())?; - writer.write_u8(0)?; - Ok(()) - } else { - Err(TiffError::FormatError(TiffFormatError::InvalidTag)) - } - } -} - -impl<'a, T: TiffValue + ?Sized> TiffValue for &'a T { - const BYTE_LEN: u8 = T::BYTE_LEN; - const FIELD_TYPE: Type = T::FIELD_TYPE; - - fn count(&self) -> usize { - (*self).count() - } - - fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { - (*self).write(writer) - } -} /// Tiff encoder. /// diff --git a/src/encoder/tiff_value.rs b/src/encoder/tiff_value.rs new file mode 100644 index 0000000..4f40036 --- /dev/null +++ b/src/encoder/tiff_value.rs @@ -0,0 +1,385 @@ +use std::io::Write; + +use crate::{TiffError, TiffFormatError, TiffResult, bytecast, tags::Type}; + +use super::writer::TiffWriter; + +/// Trait for types that can be encoded in a tiff file +pub trait TiffValue { + const BYTE_LEN: u8; + const FIELD_TYPE: Type; + fn count(&self) -> usize; + fn bytes(&self) -> usize { + self.count() * usize::from(Self::BYTE_LEN) + } + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()>; +} + +impl TiffValue for [u8] { + const BYTE_LEN: u8 = 1; + const FIELD_TYPE: Type = Type::BYTE; + + fn count(&self) -> usize { + self.len() + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + writer.write_bytes(self)?; + Ok(()) + } +} + +impl TiffValue for [i8] { + const BYTE_LEN: u8 = 1; + const FIELD_TYPE: Type = Type::SBYTE; + + fn count(&self) -> usize { + self.len() + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + let slice = bytecast::i8_as_ne_bytes(self); + writer.write_bytes(slice)?; + Ok(()) + } +} + +impl TiffValue for [u16] { + const BYTE_LEN: u8 = 2; + const FIELD_TYPE: Type = Type::SHORT; + + fn count(&self) -> usize { + self.len() + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + let slice = bytecast::u16_as_ne_bytes(self); + writer.write_bytes(slice)?; + Ok(()) + } +} + +impl TiffValue for [i16] { + const BYTE_LEN: u8 = 2; + const FIELD_TYPE: Type = Type::SSHORT; + + fn count(&self) -> usize { + self.len() + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + let slice = bytecast::i16_as_ne_bytes(self); + writer.write_bytes(slice)?; + Ok(()) + } +} + +impl TiffValue for [u32] { + const BYTE_LEN: u8 = 4; + const FIELD_TYPE: Type = Type::LONG; + + fn count(&self) -> usize { + self.len() + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + let slice = bytecast::u32_as_ne_bytes(self); + writer.write_bytes(slice)?; + Ok(()) + } +} + +impl TiffValue for [i32] { + const BYTE_LEN: u8 = 4; + const FIELD_TYPE: Type = Type::SLONG; + + fn count(&self) -> usize { + self.len() + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + let slice = bytecast::i32_as_ne_bytes(self); + writer.write_bytes(slice)?; + Ok(()) + } +} + +impl TiffValue for [u64] { + const BYTE_LEN: u8 = 8; + const FIELD_TYPE: Type = Type::LONG8; + + fn count(&self) -> usize { + self.len() + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + let slice = bytecast::u64_as_ne_bytes(self); + writer.write_bytes(slice)?; + Ok(()) + } +} + +impl TiffValue for [f32] { + const BYTE_LEN: u8 = 4; + const FIELD_TYPE: Type = Type::FLOAT; + + fn count(&self) -> usize { + self.len() + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + // We write using nativeedian so this sould be safe + let slice = bytecast::f32_as_ne_bytes(self); + writer.write_bytes(slice)?; + Ok(()) + } +} + +impl TiffValue for [f64] { + const BYTE_LEN: u8 = 8; + const FIELD_TYPE: Type = Type::DOUBLE; + + fn count(&self) -> usize { + self.len() + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + // We write using nativeedian so this sould be safe + let slice = bytecast::f64_as_ne_bytes(self); + writer.write_bytes(slice)?; + Ok(()) + } +} + +impl TiffValue for [Rational] { + const BYTE_LEN: u8 = 8; + const FIELD_TYPE: Type = Type::RATIONAL; + + fn count(&self) -> usize { + self.len() + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + for x in self { + x.write(writer)?; + } + Ok(()) + } +} + +impl TiffValue for [SRational] { + const BYTE_LEN: u8 = 8; + const FIELD_TYPE: Type = Type::SRATIONAL; + + fn count(&self) -> usize { + self.len() + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + for x in self { + x.write(writer)?; + } + Ok(()) + } +} + +impl TiffValue for u8 { + const BYTE_LEN: u8 = 1; + const FIELD_TYPE: Type = Type::BYTE; + + fn count(&self) -> usize { + 1 + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + writer.write_u8(*self)?; + Ok(()) + } +} + +impl TiffValue for i8 { + const BYTE_LEN: u8 = 1; + const FIELD_TYPE: Type = Type::SBYTE; + + fn count(&self) -> usize { + 1 + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + writer.write_i8(*self)?; + Ok(()) + } +} + +impl TiffValue for u16 { + const BYTE_LEN: u8 = 2; + const FIELD_TYPE: Type = Type::SHORT; + + fn count(&self) -> usize { + 1 + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + writer.write_u16(*self)?; + Ok(()) + } +} + +impl TiffValue for i16 { + const BYTE_LEN: u8 = 2; + const FIELD_TYPE: Type = Type::SSHORT; + + fn count(&self) -> usize { + 1 + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + writer.write_i16(*self)?; + Ok(()) + } +} + +impl TiffValue for u32 { + const BYTE_LEN: u8 = 4; + const FIELD_TYPE: Type = Type::LONG; + + fn count(&self) -> usize { + 1 + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + writer.write_u32(*self)?; + Ok(()) + } +} + +impl TiffValue for i32 { + const BYTE_LEN: u8 = 4; + const FIELD_TYPE: Type = Type::SLONG; + + fn count(&self) -> usize { + 1 + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + writer.write_i32(*self)?; + Ok(()) + } +} + +impl TiffValue for u64 { + const BYTE_LEN: u8 = 8; + const FIELD_TYPE: Type = Type::LONG8; + + fn count(&self) -> usize { + 1 + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + writer.write_u64(*self)?; + Ok(()) + } +} + +impl TiffValue for f32 { + const BYTE_LEN: u8 = 4; + const FIELD_TYPE: Type = Type::FLOAT; + + fn count(&self) -> usize { + 1 + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + writer.write_f32(*self)?; + Ok(()) + } +} + +impl TiffValue for f64 { + const BYTE_LEN: u8 = 8; + const FIELD_TYPE: Type = Type::DOUBLE; + + fn count(&self) -> usize { + 1 + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + writer.write_f64(*self)?; + Ok(()) + } +} + +impl TiffValue for Rational { + const BYTE_LEN: u8 = 8; + const FIELD_TYPE: Type = Type::RATIONAL; + + fn count(&self) -> usize { + 1 + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + writer.write_u32(self.n)?; + writer.write_u32(self.d)?; + Ok(()) + } +} + +impl TiffValue for SRational { + const BYTE_LEN: u8 = 8; + const FIELD_TYPE: Type = Type::SRATIONAL; + + fn count(&self) -> usize { + 1 + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + writer.write_i32(self.n)?; + writer.write_i32(self.d)?; + Ok(()) + } +} + +impl TiffValue for str { + const BYTE_LEN: u8 = 1; + const FIELD_TYPE: Type = Type::ASCII; + + fn count(&self) -> usize { + self.len() + 1 + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + if self.is_ascii() && !self.bytes().any(|b| b == 0) { + writer.write_bytes(self.as_bytes())?; + writer.write_u8(0)?; + Ok(()) + } else { + Err(TiffError::FormatError(TiffFormatError::InvalidTag)) + } + } +} + +impl<'a, T: TiffValue + ?Sized> TiffValue for &'a T { + const BYTE_LEN: u8 = T::BYTE_LEN; + const FIELD_TYPE: Type = T::FIELD_TYPE; + + fn count(&self) -> usize { + (*self).count() + } + + fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { + (*self).write(writer) + } +} + +/// Type to represent tiff values of type `RATIONAL` +#[derive(Clone)] +pub struct Rational { + pub n: u32, + pub d: u32, +} + +/// Type to represent tiff values of type `SRATIONAL` +pub struct SRational { + pub n: i32, + pub d: i32, +}