diff --git a/src/decoder/ifd.rs b/src/decoder/ifd.rs index ea363b1..f6f0f0d 100644 --- a/src/decoder/ifd.rs +++ b/src/decoder/ifd.rs @@ -9,6 +9,30 @@ use {TiffError, TiffFormatError, TiffResult, TiffUnsupportedError}; use self::Value::{Ascii, List, Rational, Unsigned, Signed, SRational}; +pub(crate) mod seals { + pub trait TagConversion: Sized { + fn __from_inner_type(T) -> Result; + + fn __to_inner_type(&self) -> T; + } +} + +pub trait U16Tag: Sized { + fn from_u16(val: u16) -> Option; + + fn to_u16(&self) -> u16; +} + +impl> U16Tag for T { + fn from_u16(val: u16) -> Option { + Self::__from_inner_type(val).ok() + } + + fn to_u16(&self) -> u16 { + Self::__to_inner_type(self) + } +} + macro_rules! tags { { // Permit arbitrary meta items, which include documentation. @@ -31,7 +55,7 @@ macro_rules! tags { )* } - impl $name { + impl ::decoder::ifd::seals::TagConversion<$ty> for $name { #[inline(always)] fn __from_inner_type(n: $ty) -> Result { match n { @@ -101,12 +125,8 @@ pub enum Tag(u16) unknown("A private or extension tag") { } impl Tag { - pub fn from_u16(val: u16) -> Self { - Self::__from_inner_type(val).unwrap_or_else(Tag::Unknown) - } - - pub fn to_u16(&self) -> u16 { - Self::__to_inner_type(self) + pub fn from_u16_exhaustive(val: u16) -> Self { + Self::from_u16(val).unwrap_or_else(|| Tag::Unknown(val)) } } @@ -127,16 +147,6 @@ pub enum Type(u16) { } } -impl Type { - pub fn from_u16(val: u16) -> Option { - Self::__from_inner_type(val).ok() - } - - pub fn to_u16(&self) -> u16 { - Self::__to_inner_type(self) - } -} - #[allow(unused_qualifications)] #[derive(Debug, Clone, PartialEq, Eq, Hash)] diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 78862ee..f4e757d 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -5,7 +5,7 @@ use std::cmp; use {ColorType, TiffError, TiffFormatError, TiffResult, TiffUnsupportedError}; -use self::ifd::Directory; +use self::ifd::{Directory, U16Tag}; use self::stream::{ByteOrder, EndianReader, LZWReader, DeflateReader, PackBitsReader, SmartReader}; @@ -154,46 +154,6 @@ enum Predictor(u16) { } } -impl PhotometricInterpretation { - pub fn from_u16(val: u16) -> Option { - Self::__from_inner_type(val).ok() - } - - pub fn to_u16(&self) -> u16 { - Self::__to_inner_type(self) - } -} - -impl CompressionMethod { - pub fn from_u16(val: u16) -> Option { - Self::__from_inner_type(val).ok() - } - - pub fn to_u16(&self) -> u16 { - Self::__to_inner_type(self) - } -} - -impl PlanarConfiguration { - pub fn from_u16(val: u16) -> Option { - Self::__from_inner_type(val).ok() - } - - pub fn to_u16(&self) -> u16 { - Self::__to_inner_type(self) - } -} - -impl Predictor { - pub fn from_u16(val: u16) -> Option { - Self::__from_inner_type(val).ok() - } - - pub fn to_u16(&self) -> u16 { - Self::__to_inner_type(self) - } -} - #[derive(Debug)] struct StripDecodeState { strip_index: usize, @@ -526,7 +486,7 @@ impl Decoder { // Count 4 bytes // Value 4 bytes either a pointer the value itself fn read_entry(&mut self) -> TiffResult> { - let tag = ifd::Tag::from_u16(self.read_short()?); + let tag = ifd::Tag::from_u16_exhaustive(self.read_short()?); let type_ = match ifd::Type::from_u16(self.read_short()?) { Some(t) => t, None => { diff --git a/src/encoder/mod.rs b/src/encoder/mod.rs index 96e8bfb..3055c13 100644 --- a/src/encoder/mod.rs +++ b/src/encoder/mod.rs @@ -3,7 +3,7 @@ use std::collections::BTreeMap; use std::io::{Seek, Write}; use std::mem; -use decoder::ifd::{self, Tag}; +use decoder::ifd::{self, Tag, U16Tag}; use error::{TiffError, TiffFormatError, TiffResult}; pub mod colortype;