From 3b0da4d1ae3cb58ea47357319a6c9e3915216311 Mon Sep 17 00:00:00 2001 From: Etienne Prothon Date: Wed, 5 Aug 2020 14:25:02 +0200 Subject: [PATCH] feat: Add decoding value and get tags as f32 or f64 --- src/decoder/ifd.rs | 62 ++++++++++++++++++++++++++++++++++++++++++++-- src/decoder/mod.rs | 22 ++++++++++++++++ src/error.rs | 2 +- 3 files changed, 83 insertions(+), 3 deletions(-) diff --git a/src/decoder/ifd.rs b/src/decoder/ifd.rs index 444597e..7276069 100644 --- a/src/decoder/ifd.rs +++ b/src/decoder/ifd.rs @@ -9,14 +9,16 @@ use super::stream::{ByteOrder, EndianReader, SmartReader}; use tags::{Tag, Type}; use {TiffError, TiffFormatError, TiffResult, TiffUnsupportedError}; -use self::Value::{Ascii, List, Rational, Unsigned, Signed, SRational}; +use self::Value::{Ascii, List, Rational, Unsigned, Signed, SRational, Float, Double}; #[allow(unused_qualifications)] -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub enum Value { Signed(i32), Unsigned(u32), + Float(f32), + Double(f64), List(Vec), Rational(u32, u32), SRational(i32, i32), @@ -44,6 +46,24 @@ impl Value { } } + pub fn into_f32(self) -> TiffResult { + match self { + Float(val) => Ok(val), + val => Err(TiffError::FormatError( + TiffFormatError::SignedIntegerExpected(val), + )), + } + } + + pub fn into_f64(self) -> TiffResult { + match self { + Double(val) => Ok(val), + val => Err(TiffError::FormatError( + TiffFormatError::SignedIntegerExpected(val), + )), + } + } + pub fn into_u32_vec(self) -> TiffResult> { match self { List(vec) => { @@ -84,6 +104,38 @@ impl Value { )), } } + + pub fn into_f32_vec(self) -> TiffResult> { + match self { + List(vec) => { + let mut new_vec = Vec::with_capacity(vec.len()); + for v in vec { + new_vec.push(v.into_f32()?) + } + Ok(new_vec) + } + Float(val) => Ok(vec![val]), + val => Err(TiffError::FormatError( + TiffFormatError::UnsignedIntegerExpected(val), + )), + } + } + + pub fn into_f64_vec(self) -> TiffResult> { + match self { + List(vec) => { + let mut new_vec = Vec::with_capacity(vec.len()); + for v in vec { + new_vec.push(v.into_f64()?) + } + Ok(new_vec) + } + Double(val) => Ok(vec![val]), + val => Err(TiffError::FormatError( + TiffFormatError::UnsignedIntegerExpected(val), + )), + } + } } #[derive(Clone)] @@ -169,6 +221,12 @@ impl Entry { (Type::SLONG, n) => self.decode_offset(n, bo, limits, decoder, |decoder| { Ok(Signed(decoder.read_slong()?)) }), + (Type::FLOAT, n) => self.decode_offset(n, bo, limits, decoder, |decoder| { + Ok(Float(decoder.read_float()?)) + }), + (Type::DOUBLE, n) => self.decode_offset(n, bo, limits, decoder, |decoder| { + Ok(Double(decoder.read_double()?)) + }), (Type::RATIONAL, 1) => { decoder.goto_offset(self.r(bo).read_u32()?)?; let numerator = decoder.read_long()?; diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 318af19..c4b8fed 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -483,6 +483,18 @@ impl Decoder { self.reader.read_i32() } + /// Reads a TIFF float value + #[inline] + pub fn read_float(&mut self) -> Result { + self.reader.read_f32() + } + + /// Reads a TIFF double value + #[inline] + pub fn read_double(&mut self) -> Result { + self.reader.read_f64() + } + /// Reads a string #[inline] pub fn read_string(&mut self, length: usize) -> TiffResult { @@ -625,6 +637,16 @@ impl Decoder { self.get_tag(tag)?.into_u32_vec() } + /// Tries to retrieve a tag and convert it to the desired type. + pub fn get_tag_f32_vec(&mut self, tag: Tag) -> TiffResult> { + self.get_tag(tag)?.into_f32_vec() + } + + /// Tries to retrieve a tag and convert it to the desired type. + pub fn get_tag_f64_vec(&mut self, tag: Tag) -> TiffResult> { + self.get_tag(tag)?.into_f64_vec() + } + /// Decompresses the strip into the supplied buffer. /// Returns the number of bytes read. fn expand_strip<'a>( diff --git a/src/error.rs b/src/error.rs index a86f404..32f50bf 100644 --- a/src/error.rs +++ b/src/error.rs @@ -35,7 +35,7 @@ pub enum TiffError { /// /// The list of variants may grow to incorporate errors of future features. Matching against this /// exhaustively is not covered by interface stability guarantees. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq)] pub enum TiffFormatError { TiffSignatureNotFound, TiffSignatureInvalid,