From f88c9f00c3f901d91b9caa16192f544881d412c2 Mon Sep 17 00:00:00 2001 From: Andreas Molzer Date: Sun, 10 Nov 2019 17:40:53 +0100 Subject: [PATCH] Move everything to the tags macro --- src/decoder/ifd.rs | 6 ++-- src/decoder/mod.rs | 70 ++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 61 insertions(+), 15 deletions(-) diff --git a/src/decoder/ifd.rs b/src/decoder/ifd.rs index 1b4bbe9..f162f8b 100644 --- a/src/decoder/ifd.rs +++ b/src/decoder/ifd.rs @@ -13,7 +13,7 @@ macro_rules! tags { { // Permit arbitrary meta items, which include documentation. $( #[$enum_attr:meta] )* - pub enum $name:ident($ty:ty) $(unknown($unknown_doc:literal))* { + $vis:vis enum $name:ident($ty:ty) $(unknown($unknown_doc:literal))* { // Each of the `Name = Val,` permitting documentation. $($(#[$ident_attr:meta])* $tag:ident = $val:expr,)* } @@ -33,14 +33,14 @@ macro_rules! tags { impl $name { #[inline(always)] - fn __from_inner_type(n: u16) -> Result { + fn __from_inner_type(n: $ty) -> Result { $(if n == $val { Ok($name::$tag) } else)* { Err(n) } } #[inline(always)] - fn __to_inner_type(&self) -> u16 { + fn __to_inner_type(&self) -> $ty { match *self { $( $name::$tag => $val, )* $( $name::Unknown(n) => { $unknown_doc; n }, )* diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index cb69db0..a409b97 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -1,4 +1,4 @@ -use num_traits::{FromPrimitive, Num}; +use num_traits::{Num}; use std::collections::HashMap; use std::io::{self, Read, Seek}; use std::cmp; @@ -9,6 +9,7 @@ use self::ifd::Directory; use self::stream::{ByteOrder, EndianReader, LZWReader, DeflateReader, PackBitsReader, SmartReader}; +#[macro_use] pub mod ifd; mod stream; @@ -80,8 +81,8 @@ impl<'a> DecodingBuffer<'a> { } } -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, FromPrimitive)] -pub enum PhotometricInterpretation { +tags! { +pub enum PhotometricInterpretation(u32) { WhiteIsZero = 0, BlackIsZero = 1, RGB = 2, @@ -91,9 +92,10 @@ pub enum PhotometricInterpretation { YCbCr = 6, CIELab = 8, } +} -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, FromPrimitive)] -pub enum CompressionMethod { +tags! { +pub enum CompressionMethod(u32) { None = 1, Huffman = 2, Fax3 = 3, @@ -104,18 +106,61 @@ pub enum CompressionMethod { OldDeflate = 0x80B2, PackBits = 0x8005, } +} -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, FromPrimitive)] -pub enum PlanarConfiguration { +tags! { +pub enum PlanarConfiguration(u32) { Chunky = 1, Planar = 2, } +} -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, FromPrimitive)] -enum Predictor { +tags! { +enum Predictor(u32) { None = 1, Horizontal = 2, } +} + +impl PhotometricInterpretation { + pub fn from_u32(val: u32) -> Option { + Self::__from_inner_type(val).ok() + } + + pub fn to_u32(&self) -> u32 { + Self::__to_inner_type(self) + } +} + +impl CompressionMethod { + pub fn from_u32(val: u32) -> Option { + Self::__from_inner_type(val).ok() + } + + pub fn to_u32(&self) -> u32 { + Self::__to_inner_type(self) + } +} + +impl PlanarConfiguration { + pub fn from_u32(val: u32) -> Option { + Self::__from_inner_type(val).ok() + } + + pub fn to_u32(&self) -> u32 { + Self::__to_inner_type(self) + } +} + +impl Predictor { + pub fn from_u32(val: u32) -> Option { + Self::__from_inner_type(val).ok() + } + + pub fn to_u32(&self) -> u32 { + Self::__to_inner_type(self) + } +} #[derive(Debug)] struct StripDecodeState { @@ -334,7 +379,7 @@ impl Decoder { self.width = self.get_tag_u32(ifd::Tag::ImageWidth)?; self.height = self.get_tag_u32(ifd::Tag::ImageLength)?; self.strip_decoder = None; - self.photometric_interpretation = match FromPrimitive::from_u32( + self.photometric_interpretation = match PhotometricInterpretation::from_u32( self.get_tag_u32(ifd::Tag::PhotometricInterpretation)? ) { Some(val) => val, @@ -345,7 +390,7 @@ impl Decoder { } }; if let Some(val) = self.find_tag_u32(ifd::Tag::Compression)? { - match FromPrimitive::from_u32(val) { + match CompressionMethod::from_u32(val) { Some(method) => self.compression_method = method, None => { return Err(TiffError::UnsupportedError( @@ -720,7 +765,7 @@ impl Decoder { )); } if let Ok(predictor) = self.get_tag_u32(ifd::Tag::Predictor) { - match FromPrimitive::from_u32(predictor) { + match Predictor::from_u32(predictor) { Some(Predictor::None) => (), Some(Predictor::Horizontal) => { rev_hpredict( @@ -734,6 +779,7 @@ impl Decoder { predictor, ))) } + Some(Predictor::__NonExhaustive) => unreachable!(), } } Ok(())