diff --git a/src/decoder/ifd.rs b/src/decoder/ifd.rs index 21008335..c033c84a 100644 --- a/src/decoder/ifd.rs +++ b/src/decoder/ifd.rs @@ -10,14 +10,15 @@ use crate::tags::{Tag, Type}; use crate::{TiffError, TiffFormatError, TiffResult, TiffUnsupportedError}; use self::Value::{ - Ascii, Byte, Double, Float, List, Rational, RationalBig, SRational, SRationalBig, Signed, - SignedBig, Unsigned, UnsignedBig, + Ascii, Byte, Double, Float, List, Rational, RationalBig, SRational, SRationalBig, Short, + Signed, SignedBig, Unsigned, UnsignedBig, }; #[allow(unused_qualifications)] #[derive(Debug, Clone, PartialEq)] pub enum Value { Byte(u8), + Short(u16), Signed(i32), SignedBig(i64), Unsigned(u32), @@ -42,8 +43,20 @@ impl Value { } } + pub fn into_u16(self) -> TiffResult { + match self { + Short(val) => Ok(val), + Unsigned(val) => Ok(u16::try_from(val)?), + UnsignedBig(val) => Ok(u16::try_from(val)?), + val => Err(TiffError::FormatError( + TiffFormatError::UnsignedIntegerExpected(val), + )), + } + } + pub fn into_u32(self) -> TiffResult { match self { + Short(val) => Ok(val.into()), Unsigned(val) => Ok(val), UnsignedBig(val) => Ok(u32::try_from(val)?), val => Err(TiffError::FormatError( @@ -64,6 +77,7 @@ impl Value { pub fn into_u64(self) -> TiffResult { match self { + Short(val) => Ok(val.into()), Unsigned(val) => Ok(val.into()), UnsignedBig(val) => Ok(val), val => Err(TiffError::FormatError( @@ -100,6 +114,15 @@ impl Value { } } + pub fn into_string(self) -> TiffResult { + match self { + Ascii(val) => Ok(val), + val => Err(TiffError::FormatError( + TiffFormatError::SignedIntegerExpected(val), + )), + } + } + pub fn into_u32_vec(self) -> TiffResult> { match self { List(vec) => { @@ -139,6 +162,22 @@ impl Value { } } + pub fn into_u16_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_u16()?) + } + Ok(new_vec) + } + Short(val) => Ok(vec![val]), + val => Err(TiffError::FormatError( + TiffFormatError::UnsignedIntegerExpected(val), + )), + } + } + pub fn into_i32_vec(self) -> TiffResult> { match self { List(vec) => { diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 4105b89a..af05a784 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -472,6 +472,7 @@ impl Decoder { } _ => return Err(TiffUnsupportedError::UnsupportedSampleDepth(self.samples).into()), } + Ok(()) } @@ -728,6 +729,10 @@ impl Decoder { pub fn get_tag_u32_vec(&mut self, tag: Tag) -> TiffResult> { self.get_tag(tag)?.into_u32_vec() } + + pub fn get_tag_u16_vec(&mut self, tag: Tag) -> TiffResult> { + self.get_tag(tag)?.into_u16_vec() + } pub fn get_tag_u64_vec(&mut self, tag: Tag) -> TiffResult> { self.get_tag(tag)?.into_u64_vec() } @@ -747,6 +752,11 @@ impl Decoder { self.get_tag(tag)?.into_u8_vec() } + /// Tries to retrieve a tag and convert it to a ascii vector. + pub fn get_tag_ascii_string(&mut self, tag: Tag) -> TiffResult { + self.get_tag(tag)?.into_string() + } + /// Decompresses the strip into the supplied buffer. /// Returns the number of bytes read. fn expand_strip<'a>( diff --git a/src/tags.rs b/src/tags.rs index 2741725a..5da23f48 100644 --- a/src/tags.rs +++ b/src/tags.rs @@ -120,6 +120,14 @@ pub enum Tag(u16) unknown("A private or extension tag") { TileOffsets = 324, TileByteCounts = 325, SampleFormat = 339, + // GeoTIFF + ModelPixelScaleTag = 33550, // (SoftDesk) + ModelTransformationTag = 34264, // (JPL Carto Group) + ModelTiepointTag = 33922, // (Intergraph) + GeoKeyDirectoryTag = 34735, // (SPOT) + GeoDoubleParamsTag = 34736, // (SPOT) + GeoAsciiParamsTag = 34737, // (SPOT) + GdalNodata = 42113, // Contains areas with missing data } }