From 522fbd1a69dfce74ef967bfbbcb7972bcb4dc169 Mon Sep 17 00:00:00 2001 From: Atul Bhosale Date: Thu, 18 Apr 2019 00:04:43 +0530 Subject: [PATCH] Format code using 'cargo fmt' --- src/decoder/ifd.rs | 74 ++++----- src/decoder/mod.rs | 335 +++++++++++++++++++++++++++-------------- src/decoder/stream.rs | 99 ++++++++---- src/encoder/mod.rs | 83 ++++++---- src/encoder/writer.rs | 11 +- src/error.rs | 63 +++++--- src/lib.rs | 5 +- tests/decode_images.rs | 45 +++--- tests/encode_images.rs | 63 ++++---- tests/fuzz_tests.rs | 2 +- 10 files changed, 488 insertions(+), 292 deletions(-) diff --git a/src/decoder/ifd.rs b/src/decoder/ifd.rs index 15db66b..057ce6e 100644 --- a/src/decoder/ifd.rs +++ b/src/decoder/ifd.rs @@ -1,12 +1,12 @@ //! Function for reading TIFF tags +use std::collections::HashMap; use std::io::{self, Read, Seek}; -use std::collections::{HashMap}; -use super::stream::{ByteOrder, SmartReader, EndianReader}; -use ::{TiffError, TiffFormatError, TiffUnsupportedError, TiffResult}; +use super::stream::{ByteOrder, EndianReader, SmartReader}; +use {TiffError, TiffFormatError, TiffResult, TiffUnsupportedError}; -use self::Value::{Unsigned, List, Rational, Ascii}; +use self::Value::{Ascii, List, Rational, Unsigned}; macro_rules! tags { {$( @@ -37,7 +37,7 @@ macro_rules! tags { } // Note: These tags appear in the order they are mentioned in the TIFF reference -tags!{ +tags! { // Baseline tags: Artist 315; // grayscale images PhotometricInterpretation 1 or 3 @@ -90,7 +90,6 @@ pub enum Type { RATIONAL = 5, } - #[allow(unused_qualifications)] #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Value { @@ -98,14 +97,16 @@ pub enum Value { Unsigned(u32), List(Vec), Rational(u32, u32), - Ascii(String) + Ascii(String), } impl Value { pub fn into_u32(self) -> TiffResult { match self { Unsigned(val) => Ok(val), - val => Err(TiffError::FormatError(TiffFormatError::UnsignedIntegerExpected(val))), + val => Err(TiffError::FormatError( + TiffFormatError::UnsignedIntegerExpected(val), + )), } } pub fn into_u32_vec(self) -> TiffResult> { @@ -116,10 +117,10 @@ impl Value { new_vec.push(v.into_u32()?) } Ok(new_vec) - }, + } Unsigned(val) => Ok(vec![val]), Rational(numerator, denominator) => Ok(vec![numerator, denominator]), - Ascii(val) => Ok(val.chars().map(|x| x as u32).collect()) + Ascii(val) => Ok(val.chars().map(|x| x as u32).collect()), } } } @@ -133,29 +134,32 @@ pub struct Entry { impl ::std::fmt::Debug for Entry { fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { - fmt.write_str(&format!("Entry {{ type_: {:?}, count: {:?}, offset: {:?} }}", - self.type_, - self.count, - &self.offset + fmt.write_str(&format!( + "Entry {{ type_: {:?}, count: {:?}, offset: {:?} }}", + self.type_, self.count, &self.offset )) } } impl Entry { pub fn new(type_: Type, count: u32, offset: [u8; 4]) -> Entry { - Entry { type_, count, offset } + Entry { + type_, + count, + offset, + } } /// Returns a mem_reader for the offset/value field fn r(&self, byte_order: ByteOrder) -> SmartReader>> { - SmartReader::wrap( - io::Cursor::new(self.offset.to_vec()), - byte_order - ) + SmartReader::wrap(io::Cursor::new(self.offset.to_vec()), byte_order) } - pub fn val(&self, limits: &super::Limits, decoder: &mut super::Decoder) - -> TiffResult { + pub fn val( + &self, + limits: &super::Limits, + decoder: &mut super::Decoder, + ) -> TiffResult { let bo = decoder.byte_order(); match (self.type_, self.count) { // TODO check if this could give wrong results @@ -166,28 +170,28 @@ impl Entry { let mut r = self.r(bo); Ok(List(vec![ Unsigned(u32::from(r.read_u16()?)), - Unsigned(u32::from(r.read_u16()?)) + Unsigned(u32::from(r.read_u16()?)), ])) - }, + } (Type::SHORT, n) => { if n as usize > limits.decoding_buffer_size / std::mem::size_of::() { - return Err(TiffError::LimitsExceeded) + return Err(TiffError::LimitsExceeded); } let mut v = Vec::with_capacity(n as usize); try!(decoder.goto_offset(try!(self.r(bo).read_u32()))); - for _ in 0 .. n { + for _ in 0..n { v.push(Unsigned(u32::from(decoder.read_short()?))) } Ok(List(v)) - }, + } (Type::LONG, 1) => Ok(Unsigned(try!(self.r(bo).read_u32()))), (Type::LONG, n) => { if n as usize > limits.decoding_buffer_size / std::mem::size_of::() { - return Err(TiffError::LimitsExceeded) + return Err(TiffError::LimitsExceeded); } let mut v = Vec::with_capacity(n as usize); try!(decoder.goto_offset(try!(self.r(bo).read_u32()))); - for _ in 0 .. n { + for _ in 0..n { v.push(Unsigned(try!(decoder.read_long()))) } Ok(List(v)) @@ -197,29 +201,31 @@ impl Entry { let numerator = try!(decoder.read_long()); let denominator = try!(decoder.read_long()); Ok(Rational(numerator, denominator)) - }, + } (Type::RATIONAL, n) => { if n as usize > limits.decoding_buffer_size / std::mem::size_of::() { - return Err(TiffError::LimitsExceeded) + return Err(TiffError::LimitsExceeded); } let mut v = Vec::with_capacity(n as usize); try!(decoder.goto_offset(try!(self.r(bo).read_u32()))); - for _ in 0 .. n { + for _ in 0..n { let numerator = try!(decoder.read_long()); let denominator = try!(decoder.read_long()); v.push(Rational(numerator, denominator)) } Ok(List(v)) - }, + } (Type::ASCII, n) => { if n as usize > limits.decoding_buffer_size { - return Err(TiffError::LimitsExceeded) + return Err(TiffError::LimitsExceeded); } try!(decoder.goto_offset(try!(self.r(bo).read_u32()))); let string = try!(decoder.read_string(n as usize)); Ok(Ascii(string)) } - _ => Err(TiffError::UnsupportedError(TiffUnsupportedError::UnsupportedDataType)) + _ => Err(TiffError::UnsupportedError( + TiffUnsupportedError::UnsupportedDataType, + )), } } } diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 5e070f1..fd7e0eb 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -1,18 +1,12 @@ -use std::io::{self, Read, Seek}; use num_traits::{FromPrimitive, Num}; use std::collections::HashMap; +use std::io::{self, Read, Seek}; -use ::{ColorType, TiffError, TiffFormatError, TiffUnsupportedError, TiffResult}; +use {ColorType, TiffError, TiffFormatError, TiffResult, TiffUnsupportedError}; use self::ifd::Directory; -use self::stream::{ - ByteOrder, - EndianReader, - SmartReader, - LZWReader, - PackBitsReader -}; +use self::stream::{ByteOrder, EndianReader, LZWReader, PackBitsReader, SmartReader}; pub mod ifd; mod stream; @@ -23,15 +17,14 @@ pub enum DecodingResult { /// A vector of unsigned bytes U8(Vec), /// A vector of unsigned words - U16(Vec) + U16(Vec), } impl DecodingResult { fn new_u8(size: usize, limits: &Limits) -> TiffResult { if size > limits.decoding_buffer_size { Err(TiffError::LimitsExceeded) - } - else { + } else { Ok(DecodingResult::U8(vec![0; size])) } } @@ -39,8 +32,7 @@ impl DecodingResult { fn new_u16(size: usize, limits: &Limits) -> TiffResult { if size > limits.decoding_buffer_size / 2 { Err(TiffError::LimitsExceeded) - } - else { + } else { Ok(DecodingResult::U16(vec![0; size])) } } @@ -58,7 +50,7 @@ pub enum DecodingBuffer<'a> { /// A slice of unsigned bytes U8(&'a mut [u8]), /// A slice of unsigned words - U16(&'a mut [u16]) + U16(&'a mut [u16]), } impl<'a> DecodingBuffer<'a> { @@ -76,7 +68,10 @@ impl<'a> DecodingBuffer<'a> { } } - fn copy<'b>(&'b mut self) -> DecodingBuffer<'b> where 'a: 'b { + fn copy<'b>(&'b mut self) -> DecodingBuffer<'b> + where + 'a: 'b, + { match self { DecodingBuffer::U8(ref mut buf) => DecodingBuffer::U8(buf), DecodingBuffer::U16(ref mut buf) => DecodingBuffer::U16(buf), @@ -104,19 +99,19 @@ pub enum CompressionMethod { Fax4 = 4, LZW = 5, JPEG = 6, - PackBits = 0x8005 + PackBits = 0x8005, } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, FromPrimitive)] pub enum PlanarConfiguration { Chunky = 1, - Planar = 2 + Planar = 2, } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, FromPrimitive)] enum Predictor { None = 1, - Horizontal = 2 + Horizontal = 2, } #[derive(Debug)] @@ -129,12 +124,12 @@ struct StripDecodeState { /// Decoding limits #[derive(Clone, Debug)] pub struct Limits { - /// The maximum size of any `DecodingResult` in bytes, the default is + /// The maximum size of any `DecodingResult` in bytes, the default is /// 256MiB. If the entire image is decoded at once, then this will /// be the maximum size of the image. If it is decoded one strip at a /// time, this will be the maximum size of a strip. decoding_buffer_size: usize, - /// The maximum size of any ifd value in bytes, the default is + /// The maximum size of any ifd value in bytes, the default is /// 1MiB. ifd_value_size: usize, } @@ -142,8 +137,8 @@ pub struct Limits { impl Default for Limits { fn default() -> Limits { Limits { - decoding_buffer_size: 256*1024*1024, - ifd_value_size: 1024*1024, + decoding_buffer_size: 256 * 1024 * 1024, + ifd_value_size: 1024 * 1024, } } } @@ -152,7 +147,10 @@ impl Default for Limits { /// /// Currently does not support decoding of interlaced images #[derive(Debug)] -pub struct Decoder where R: Read + Seek { +pub struct Decoder +where + R: Read + Seek, +{ reader: SmartReader, byte_order: ByteOrder, limits: Limits, @@ -183,10 +181,10 @@ impl Wrapping for u16 { } } -fn rev_hpredict_nsamp(image: &mut [T], - size: (u32, u32), - samples: usize) - where T: Num + Copy + Wrapping { +fn rev_hpredict_nsamp(image: &mut [T], size: (u32, u32), samples: usize) +where + T: Num + Copy + Wrapping, +{ let width = size.0 as usize; let height = size.1 as usize; for row in 0..height { @@ -203,12 +201,16 @@ fn rev_hpredict(image: DecodingBuffer, size: (u32, u32), color_type: ColorType) ColorType::Gray(8) | ColorType::Gray(16) => 1, ColorType::RGB(8) | ColorType::RGB(16) => 3, ColorType::RGBA(8) | ColorType::RGBA(16) | ColorType::CMYK(8) => 4, - _ => return Err(TiffError::UnsupportedError(TiffUnsupportedError::HorizontalPredictor(color_type))) + _ => { + return Err(TiffError::UnsupportedError( + TiffUnsupportedError::HorizontalPredictor(color_type), + )) + } }; match image { DecodingBuffer::U8(buf) => { rev_hpredict_nsamp(buf, size, samples); - }, + } DecodingBuffer::U16(buf) => { rev_hpredict_nsamp(buf, size, samples); } @@ -232,7 +234,8 @@ impl Decoder { photometric_interpretation: PhotometricInterpretation::BlackIsZero, compression_method: CompressionMethod::None, strip_decoder: None, - }.init() + } + .init() } pub fn with_limits(mut self, limits: Limits) -> Decoder { @@ -247,16 +250,34 @@ impl Decoder { pub fn colortype(&mut self) -> TiffResult { match self.photometric_interpretation { // TODO: catch also [ 8, 8, 8, _] this does not work due to a bug in rust atm - PhotometricInterpretation::RGB if self.bits_per_sample == [8, 8, 8, 8] => Ok(ColorType::RGBA(8)), - PhotometricInterpretation::RGB if self.bits_per_sample == [8, 8, 8] => Ok(ColorType::RGB(8)), - PhotometricInterpretation::RGB if self.bits_per_sample == [16, 16, 16, 16] => Ok(ColorType::RGBA(16)), - PhotometricInterpretation::RGB if self.bits_per_sample == [16, 16, 16] => Ok(ColorType::RGB(16)), - PhotometricInterpretation::CMYK if self.bits_per_sample == [8, 8, 8, 8] => Ok(ColorType::CMYK(8)), + PhotometricInterpretation::RGB if self.bits_per_sample == [8, 8, 8, 8] => { + Ok(ColorType::RGBA(8)) + } + PhotometricInterpretation::RGB if self.bits_per_sample == [8, 8, 8] => { + Ok(ColorType::RGB(8)) + } + PhotometricInterpretation::RGB if self.bits_per_sample == [16, 16, 16, 16] => { + Ok(ColorType::RGBA(16)) + } + PhotometricInterpretation::RGB if self.bits_per_sample == [16, 16, 16] => { + Ok(ColorType::RGB(16)) + } + PhotometricInterpretation::CMYK if self.bits_per_sample == [8, 8, 8, 8] => { + Ok(ColorType::CMYK(8)) + } PhotometricInterpretation::BlackIsZero | PhotometricInterpretation::WhiteIsZero - if self.bits_per_sample.len() == 1 => Ok(ColorType::Gray(self.bits_per_sample[0])), + if self.bits_per_sample.len() == 1 => + { + Ok(ColorType::Gray(self.bits_per_sample[0])) + } // TODO: this is bad we should not fail at this point - _ => Err(TiffError::UnsupportedError(TiffUnsupportedError::InterpretationWithBits(self.photometric_interpretation, self.bits_per_sample.clone()))) + _ => Err(TiffError::UnsupportedError( + TiffUnsupportedError::InterpretationWithBits( + self.photometric_interpretation, + self.bits_per_sample.clone(), + ), + )), } } @@ -266,18 +287,26 @@ impl Decoder { match &*endianess { b"II" => { self.byte_order = ByteOrder::LittleEndian; - self.reader.byte_order = ByteOrder::LittleEndian; }, + self.reader.byte_order = ByteOrder::LittleEndian; + } b"MM" => { self.byte_order = ByteOrder::BigEndian; - self.reader.byte_order = ByteOrder::BigEndian; }, - _ => return Err(TiffError::FormatError(TiffFormatError::TiffSignatureNotFound)) + self.reader.byte_order = ByteOrder::BigEndian; + } + _ => { + return Err(TiffError::FormatError( + TiffFormatError::TiffSignatureNotFound, + )) + } } if try!(self.read_short()) != 42 { - return Err(TiffError::FormatError(TiffFormatError::TiffSignatureInvalid)) + return Err(TiffError::FormatError( + TiffFormatError::TiffSignatureInvalid, + )); } self.next_ifd = match try!(self.read_long()) { 0 => None, - n => Some(n) + n => Some(n), }; Ok(()) } @@ -296,18 +325,24 @@ impl Decoder { self.width = try!(self.get_tag_u32(ifd::Tag::ImageWidth)); self.height = try!(self.get_tag_u32(ifd::Tag::ImageLength)); self.strip_decoder = None; - self.photometric_interpretation = match FromPrimitive::from_u32( - try!(self.get_tag_u32(ifd::Tag::PhotometricInterpretation)) - ) { + self.photometric_interpretation = match FromPrimitive::from_u32(try!( + self.get_tag_u32(ifd::Tag::PhotometricInterpretation) + )) { Some(val) => val, - None => return Err(TiffError::UnsupportedError(TiffUnsupportedError::UnknownInterpretation)) + None => { + return Err(TiffError::UnsupportedError( + TiffUnsupportedError::UnknownInterpretation, + )) + } }; if let Some(val) = try!(self.find_tag_u32(ifd::Tag::Compression)) { match FromPrimitive::from_u32(val) { - Some(method) => { - self.compression_method = method - }, - None => return Err(TiffError::UnsupportedError(TiffUnsupportedError::UnknownCompressionMethod)) + Some(method) => self.compression_method = method, + None => { + return Err(TiffError::UnsupportedError( + TiffUnsupportedError::UnknownCompressionMethod, + )) + } } } if let Some(val) = try!(self.find_tag_u32(ifd::Tag::SamplesPerPixel)) { @@ -323,9 +358,12 @@ impl Decoder { if let Some(val) = try!(self.find_tag_u32_vec(ifd::Tag::BitsPerSample)) { self.bits_per_sample = val.iter().map(|&v| v as u8).collect() } - } - _ => return Err(TiffError::UnsupportedError(TiffUnsupportedError::UnsupportedSampleDepth(self.samples))) + _ => { + return Err(TiffError::UnsupportedError( + TiffUnsupportedError::UnsupportedSampleDepth(self.samples), + )) + } } Ok(self) } @@ -373,7 +411,9 @@ impl Decoder { /// Moves the cursor to the specified offset #[inline] pub fn goto_offset(&mut self, offset: u32) -> io::Result<()> { - self.reader.seek(io::SeekFrom::Start(u64::from(offset))).map(|_| ()) + self.reader + .seek(io::SeekFrom::Start(u64::from(offset))) + .map(|_| ()) } /// Reads a IFD entry. @@ -391,34 +431,40 @@ impl Decoder { // Unknown type. Skip this entry according to spec. try!(self.read_long()); try!(self.read_long()); - return Ok(None) - + return Ok(None); } }; - Ok(Some((tag, ifd::Entry::new( - type_, - try!(self.read_long()), // count - try!(self.read_offset()) // offset - )))) + Ok(Some(( + tag, + ifd::Entry::new( + type_, + try!(self.read_long()), // count + try!(self.read_offset()), // offset + ), + ))) } /// Reads the next IFD fn read_ifd(&mut self) -> TiffResult { let mut dir: Directory = HashMap::new(); match self.next_ifd { - None => return Err(TiffError::FormatError(TiffFormatError::ImageFileDirectoryNotFound)), - Some(offset) => try!(self.goto_offset(offset)) + None => { + return Err(TiffError::FormatError( + TiffFormatError::ImageFileDirectoryNotFound, + )) + } + Some(offset) => try!(self.goto_offset(offset)), } for _ in 0..try!(self.read_short()) { let (tag, entry) = match try!(self.read_entry()) { Some(val) => val, - None => continue // Unknown data type in tag, skip + None => continue, // Unknown data type in tag, skip }; dir.insert(tag, entry); } self.next_ifd = match try!(self.read_long()) { 0 => None, - n => Some(n) + n => Some(n), }; Ok(dir) } @@ -440,7 +486,7 @@ impl Decoder { pub fn find_tag_u32(&mut self, tag: ifd::Tag) -> TiffResult> { match self.find_tag(tag)? { Some(val) => val.into_u32().map(Some), - None => Ok(None) + None => Ok(None), } } @@ -448,7 +494,7 @@ impl Decoder { pub fn find_tag_u32_vec(&mut self, tag: ifd::Tag) -> TiffResult>> { match self.find_tag(tag)? { Some(val) => val.into_u32_vec().map(Some), - None => Ok(None) + None => Ok(None), } } @@ -457,7 +503,9 @@ impl Decoder { pub fn get_tag(&mut self, tag: ifd::Tag) -> TiffResult { match try!(self.find_tag(tag)) { Some(val) => Ok(val), - None => Err(TiffError::FormatError(TiffFormatError::RequiredTagNotFound(tag))), + None => Err(TiffError::FormatError( + TiffFormatError::RequiredTagNotFound(tag), + )), } } @@ -473,50 +521,73 @@ impl Decoder { /// Decompresses the strip into the supplied buffer. /// Returns the number of bytes read. - fn expand_strip<'a>(&mut self, buffer: DecodingBuffer<'a>, offset: u32, length: u32, max_uncompressed_length: usize) -> TiffResult { + fn expand_strip<'a>( + &mut self, + buffer: DecodingBuffer<'a>, + offset: u32, + length: u32, + max_uncompressed_length: usize, + ) -> TiffResult { let color_type = try!(self.colortype()); try!(self.goto_offset(offset)); let (bytes, mut reader): (usize, Box) = match self.compression_method { CompressionMethod::None => { let order = self.reader.byte_order; - (length as usize, Box::new(SmartReader::wrap(&mut self.reader, order))) - }, + ( + length as usize, + Box::new(SmartReader::wrap(&mut self.reader, order)), + ) + } CompressionMethod::LZW => { - let (bytes, reader) = try!(LZWReader::new(&mut self.reader, length as usize, max_uncompressed_length)); + let (bytes, reader) = try!(LZWReader::new( + &mut self.reader, + length as usize, + max_uncompressed_length + )); (bytes, Box::new(reader)) - }, + } CompressionMethod::PackBits => { let order = self.reader.byte_order; - let (bytes, reader) = try!(PackBitsReader::new(&mut self.reader, order, length as usize)); + let (bytes, reader) = try!(PackBitsReader::new( + &mut self.reader, + order, + length as usize + )); (bytes, Box::new(reader)) - }, - method => return Err(TiffError::UnsupportedError(TiffUnsupportedError::UnsupportedCompressionMethod(method))) + } + method => { + return Err(TiffError::UnsupportedError( + TiffUnsupportedError::UnsupportedCompressionMethod(method), + )) + } }; - + if bytes / buffer.byte_len() > max_uncompressed_length { - return Err(TiffError::FormatError(TiffFormatError::InconsistentSizesEncountered)); + return Err(TiffError::FormatError( + TiffFormatError::InconsistentSizesEncountered, + )); } Ok(match (color_type, buffer) { - (ColorType:: RGB(8), DecodingBuffer::U8(ref mut buffer)) | - (ColorType::RGBA(8), DecodingBuffer::U8(ref mut buffer)) | - (ColorType::CMYK(8), DecodingBuffer::U8(ref mut buffer)) => { + (ColorType::RGB(8), DecodingBuffer::U8(ref mut buffer)) + | (ColorType::RGBA(8), DecodingBuffer::U8(ref mut buffer)) + | (ColorType::CMYK(8), DecodingBuffer::U8(ref mut buffer)) => { try!(reader.read_exact(&mut buffer[..bytes])); bytes } - (ColorType::RGBA(16), DecodingBuffer::U16(ref mut buffer)) | - (ColorType:: RGB(16), DecodingBuffer::U16(ref mut buffer)) => { - try!(reader.read_u16_into(&mut buffer[..bytes/2])); - bytes/2 + (ColorType::RGBA(16), DecodingBuffer::U16(ref mut buffer)) + | (ColorType::RGB(16), DecodingBuffer::U16(ref mut buffer)) => { + try!(reader.read_u16_into(&mut buffer[..bytes / 2])); + bytes / 2 } (ColorType::Gray(16), DecodingBuffer::U16(ref mut buffer)) => { - try!(reader.read_u16_into(&mut buffer[..bytes/2])); + try!(reader.read_u16_into(&mut buffer[..bytes / 2])); if self.photometric_interpretation == PhotometricInterpretation::WhiteIsZero { - for datum in buffer[..bytes/2].iter_mut() { + for datum in buffer[..bytes / 2].iter_mut() { *datum = 0xffff - *datum } } - bytes/2 + bytes / 2 } (ColorType::Gray(n), DecodingBuffer::U8(ref mut buffer)) if n <= 8 => { try!(reader.read_exact(&mut buffer[..bytes])); @@ -527,15 +598,20 @@ impl Decoder { } bytes } - (type_, _) => return Err(TiffError::UnsupportedError(TiffUnsupportedError::UnsupportedColorType(type_))), + (type_, _) => { + return Err(TiffError::UnsupportedError( + TiffUnsupportedError::UnsupportedColorType(type_), + )) + } }) } /// Number of strips in image pub fn strip_count(&mut self) -> TiffResult { - let rows_per_strip = self.get_tag_u32(ifd::Tag::RowsPerStrip) + let rows_per_strip = self + .get_tag_u32(ifd::Tag::RowsPerStrip) .unwrap_or(self.height); - + Ok((self.height + rows_per_strip - 1) / rows_per_strip) } @@ -557,20 +633,40 @@ impl Decoder { self.initialize_strip_decoder()?; let index = self.strip_decoder.as_ref().unwrap().strip_index; - let offset = *self.strip_decoder.as_ref().unwrap().strip_offsets.get(index) - .ok_or(TiffError::FormatError(TiffFormatError::InconsistentSizesEncountered))?; - let byte_count = *self.strip_decoder.as_ref().unwrap().strip_bytes.get(index) - .ok_or(TiffError::FormatError(TiffFormatError::InconsistentSizesEncountered))?; + let offset = *self + .strip_decoder + .as_ref() + .unwrap() + .strip_offsets + .get(index) + .ok_or(TiffError::FormatError( + TiffFormatError::InconsistentSizesEncountered, + ))?; + let byte_count = *self + .strip_decoder + .as_ref() + .unwrap() + .strip_bytes + .get(index) + .ok_or(TiffError::FormatError( + TiffFormatError::InconsistentSizesEncountered, + ))?; - let rows_per_strip = self.get_tag_u32(ifd::Tag::RowsPerStrip) + let rows_per_strip = self + .get_tag_u32(ifd::Tag::RowsPerStrip) .unwrap_or(self.height) as usize; - let strip_height = std::cmp::min(rows_per_strip, self.height as usize - index * rows_per_strip); + let strip_height = std::cmp::min( + rows_per_strip, + self.height as usize - index * rows_per_strip, + ); let buffer_size = self.width as usize * strip_height * self.bits_per_sample.len(); if buffer.len() < buffer_size || byte_count as usize / buffer.byte_len() > buffer_size { - return Err(TiffError::FormatError(TiffFormatError::InconsistentSizesEncountered)); + return Err(TiffError::FormatError( + TiffFormatError::InconsistentSizesEncountered, + )); } let units_read = self.expand_strip(buffer.copy(), offset, byte_count, buffer_size)?; @@ -582,7 +678,9 @@ impl Decoder { } if units_read < buffer_size { - return Err(TiffError::FormatError(TiffFormatError::InconsistentSizesEncountered)); + return Err(TiffError::FormatError( + TiffFormatError::InconsistentSizesEncountered, + )); } if let Ok(predictor) = self.get_tag_u32(ifd::Tag::Predictor) { match FromPrimitive::from_u32(predictor) { @@ -591,10 +689,14 @@ impl Decoder { rev_hpredict( buffer.copy(), (self.width, strip_height as u32), - self.colortype()? + self.colortype()?, )?; - }, - None => return Err(TiffError::FormatError(TiffFormatError::UnknownPredictor(predictor))), + } + None => { + return Err(TiffError::FormatError(TiffFormatError::UnknownPredictor( + predictor, + ))) + } } } Ok(()) @@ -605,17 +707,25 @@ impl Decoder { self.initialize_strip_decoder()?; let index = self.strip_decoder.as_ref().unwrap().strip_index; - let rows_per_strip = self.get_tag_u32(ifd::Tag::RowsPerStrip) + let rows_per_strip = self + .get_tag_u32(ifd::Tag::RowsPerStrip) .unwrap_or(self.height) as usize; - let strip_height = std::cmp::min(rows_per_strip, self.height as usize - index * rows_per_strip); + let strip_height = std::cmp::min( + rows_per_strip, + self.height as usize - index * rows_per_strip, + ); let buffer_size = self.width as usize * strip_height * self.bits_per_sample.iter().count(); let mut result = match self.bits_per_sample.iter().cloned().max().unwrap_or(8) { n if n <= 8 => DecodingResult::new_u8(buffer_size, &self.limits)?, n if n <= 16 => DecodingResult::new_u16(buffer_size, &self.limits)?, - n => return Err(TiffError::UnsupportedError(TiffUnsupportedError::UnsupportedBitsPerChannel(n))), + n => { + return Err(TiffError::UnsupportedError( + TiffUnsupportedError::UnsupportedBitsPerChannel(n), + )) + } }; self.read_strip_to_buffer(result.as_buffer(0))?; @@ -626,17 +736,24 @@ impl Decoder { /// Decodes the entire image and return it as a Vector pub fn read_image(&mut self) -> TiffResult { self.initialize_strip_decoder()?; - let rows_per_strip = self.get_tag_u32(ifd::Tag::RowsPerStrip) + let rows_per_strip = self + .get_tag_u32(ifd::Tag::RowsPerStrip) .unwrap_or(self.height) as usize; - let samples_per_strip = self.width as usize * rows_per_strip * self.bits_per_sample.iter().count(); + let samples_per_strip = + self.width as usize * rows_per_strip * self.bits_per_sample.iter().count(); - let buffer_size = self.width as usize * self.height as usize * self.bits_per_sample.iter().count(); + let buffer_size = + self.width as usize * self.height as usize * self.bits_per_sample.iter().count(); let mut result = match self.bits_per_sample.iter().cloned().max().unwrap_or(8) { n if n <= 8 => DecodingResult::new_u8(buffer_size, &self.limits)?, n if n <= 16 => DecodingResult::new_u16(buffer_size, &self.limits)?, - n => return Err(TiffError::UnsupportedError(TiffUnsupportedError::UnsupportedBitsPerChannel(n))), + n => { + return Err(TiffError::UnsupportedError( + TiffUnsupportedError::UnsupportedBitsPerChannel(n), + )) + } }; for i in 0..self.strip_count()? as usize { diff --git a/src/decoder/stream.rs b/src/decoder/stream.rs index 5e8f5e0..b9285db 100644 --- a/src/decoder/stream.rs +++ b/src/decoder/stream.rs @@ -1,8 +1,8 @@ //! All IO functionality needed for TIFF decoding -use std::io::{self, Read, Seek}; -use byteorder::{ReadBytesExt, BigEndian, LittleEndian}; +use byteorder::{BigEndian, LittleEndian, ReadBytesExt}; use lzw; +use std::io::{self, Read, Seek}; /// Byte order of the TIFF file. #[derive(Clone, Copy, Debug)] @@ -10,10 +10,9 @@ pub enum ByteOrder { /// little endian byte order LittleEndian, /// big endian byte order - BigEndian + BigEndian, } - /// Reader that is aware of the byte order. pub trait EndianReader: Read { /// Byte order that should be adhered to @@ -24,15 +23,19 @@ pub trait EndianReader: Read { fn read_u16(&mut self) -> Result { match self.byte_order() { ByteOrder::LittleEndian => ::read_u16::(self), - ByteOrder::BigEndian => ::read_u16::(self) + ByteOrder::BigEndian => ::read_u16::(self), } } #[inline(always)] fn read_u16_into(&mut self, buffer: &mut [u16]) -> Result<(), io::Error> { match self.byte_order() { - ByteOrder::LittleEndian => ::read_u16_into::(self, buffer), - ByteOrder::BigEndian => ::read_u16_into::(self, buffer) + ByteOrder::LittleEndian => { + ::read_u16_into::(self, buffer) + } + ByteOrder::BigEndian => { + ::read_u16_into::(self, buffer) + } } } @@ -41,7 +44,7 @@ pub trait EndianReader: Read { fn read_u32(&mut self) -> Result { match self.byte_order() { ByteOrder::LittleEndian => ::read_u32::(self), - ByteOrder::BigEndian => ::read_u32::(self) + ByteOrder::BigEndian => ::read_u32::(self), } } } @@ -49,12 +52,19 @@ pub trait EndianReader: Read { /// Reader that decompresses LZW streams pub struct LZWReader { buffer: io::Cursor>, - byte_order: ByteOrder + byte_order: ByteOrder, } impl LZWReader { /// Wraps a reader - pub fn new(reader: &mut SmartReader, compressed_length: usize, max_uncompressed_length: usize) -> io::Result<(usize, LZWReader)> where R: Read + Seek { + pub fn new( + reader: &mut SmartReader, + compressed_length: usize, + max_uncompressed_length: usize, + ) -> io::Result<(usize, LZWReader)> + where + R: Read + Seek, + { let order = reader.byte_order; let mut compressed = vec![0; compressed_length as usize]; try!(reader.read_exact(&mut compressed[..])); @@ -68,10 +78,13 @@ impl LZWReader { } let bytes = uncompressed.len(); - Ok((bytes, LZWReader { - buffer: io::Cursor::new(uncompressed), - byte_order: order - })) + Ok(( + bytes, + LZWReader { + buffer: io::Cursor::new(uncompressed), + byte_order: order, + }, + )) } } @@ -92,25 +105,32 @@ impl EndianReader for LZWReader { /// Reader that unpacks Apple's `PackBits` format pub struct PackBitsReader { buffer: io::Cursor>, - byte_order: ByteOrder + byte_order: ByteOrder, } impl PackBitsReader { /// Wraps a reader - pub fn new(mut reader: R, byte_order: ByteOrder, length: usize) -> io::Result<(usize, PackBitsReader)> { + pub fn new( + mut reader: R, + byte_order: ByteOrder, + length: usize, + ) -> io::Result<(usize, PackBitsReader)> { let mut buffer = Vec::new(); let mut read: usize = 0; while read < length { let lread = read_packbits_run(&mut reader, &mut buffer)?; if lread == 0 { - return Err(io::ErrorKind::UnexpectedEof.into()) + return Err(io::ErrorKind::UnexpectedEof.into()); } read += lread; } - Ok((buffer.len(), PackBitsReader { - buffer: io::Cursor::new(buffer), - byte_order - })) + Ok(( + buffer.len(), + PackBitsReader { + buffer: io::Cursor::new(buffer), + byte_order, + }, + )) } } @@ -128,7 +148,7 @@ fn read_packbits_run(reader: &mut R, buffer: &mut Vec) -> io try!(reader.read_exact(&mut header)); buffer.resize(new_len, header[0]); Ok(2) - }, + } h => { let num_vals = h as usize + 1; let start = buffer.len(); @@ -136,7 +156,7 @@ fn read_packbits_run(reader: &mut R, buffer: &mut Vec) -> io try!(reader.read_exact(&mut buffer[start..])); Ok(num_vals + 1) } - } + }, } } @@ -156,19 +176,28 @@ impl EndianReader for PackBitsReader { /// Reader that is aware of the byte order. #[derive(Debug)] -pub struct SmartReader where R: Read + Seek { +pub struct SmartReader +where + R: Read + Seek, +{ reader: R, - pub byte_order: ByteOrder + pub byte_order: ByteOrder, } -impl SmartReader where R: Read + Seek { +impl SmartReader +where + R: Read + Seek, +{ /// Wraps a reader pub fn wrap(reader: R, byte_order: ByteOrder) -> SmartReader { SmartReader { reader, byte_order } } } -impl EndianReader for SmartReader where R: Read + Seek { +impl EndianReader for SmartReader +where + R: Read + Seek, +{ #[inline(always)] fn byte_order(&self) -> ByteOrder { self.byte_order @@ -195,19 +224,23 @@ mod test { #[test] fn test_packbits() { - let encoded = vec![0xFE, 0xAA, 0x02, 0x80, 0x00, 0x2A, 0xFD, 0xAA, - 0x03, 0x80, 0x00, 0x2A, 0x22, 0xF7, 0xAA]; + let encoded = vec![ + 0xFE, 0xAA, 0x02, 0x80, 0x00, 0x2A, 0xFD, 0xAA, 0x03, 0x80, 0x00, 0x2A, 0x22, 0xF7, + 0xAA, + ]; let encoded_len = encoded.len(); let buff = io::Cursor::new(encoded); - let (_, mut decoder) = PackBitsReader::new(buff, ByteOrder::LittleEndian, encoded_len).unwrap(); + let (_, mut decoder) = + PackBitsReader::new(buff, ByteOrder::LittleEndian, encoded_len).unwrap(); let mut decoded = Vec::new(); decoder.read_to_end(&mut decoded).unwrap(); - let expected = vec![0xAA, 0xAA, 0xAA, 0x80, 0x00, 0x2A, 0xAA, 0xAA, - 0xAA, 0xAA, 0x80, 0x00, 0x2A, 0x22, 0xAA, 0xAA, - 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA]; + let expected = vec![ + 0xAA, 0xAA, 0xAA, 0x80, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0x80, 0x00, 0x2A, 0x22, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + ]; assert_eq!(decoded, expected); } } diff --git a/src/encoder/mod.rs b/src/encoder/mod.rs index eeb9e1e..8618898 100644 --- a/src/encoder/mod.rs +++ b/src/encoder/mod.rs @@ -1,15 +1,15 @@ -use std::io::{Write, Seek}; +use byteorder::NativeEndian; use std::collections::BTreeMap; -use byteorder::{NativeEndian}; +use std::io::{Seek, Write}; use crate::decoder::ifd::{self, Tag}; -use crate::error::{TiffResult, TiffFormatError, TiffError}; +use crate::error::{TiffError, TiffFormatError, TiffResult}; -mod writer; pub mod colortype; +mod writer; -use self::writer::*; use self::colortype::*; +use self::writer::*; /// Type to represent tiff values of type `RATIONAL` #[derive(Clone)] @@ -60,9 +60,8 @@ impl TiffValue for [u16] { fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { // We write using nativeedian so this sould be safe - let slice = unsafe { - std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len()*2) - }; + let slice = + unsafe { std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * 2) }; writer.write_bytes(slice)?; Ok(()) } @@ -78,9 +77,8 @@ impl TiffValue for [u32] { fn write(&self, writer: &mut TiffWriter) -> TiffResult<()> { // We write using nativeedian so this sould be safe - let slice = unsafe { - std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len()*4) - }; + let slice = + unsafe { std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * 4) }; writer.write_bytes(slice)?; Ok(()) } @@ -172,8 +170,7 @@ impl TiffValue for str { writer.write_bytes(self.as_bytes())?; writer.write_u8(0)?; Ok(()) - } - else { + } else { Err(TiffError::FormatError(TiffFormatError::InvalidTag)) } } @@ -219,7 +216,7 @@ impl TiffEncoder { let mut encoder = TiffEncoder { writer: TiffWriter::new(writer), }; - + NativeEndian::write_header(&mut encoder.writer)?; Ok(encoder) @@ -231,20 +228,32 @@ impl TiffEncoder { } /// Create an 'ImageEncoder' to encode an image one slice at a time. - pub fn new_image(&mut self, width: u32, height: u32) -> TiffResult> { + pub fn new_image( + &mut self, + width: u32, + height: u32, + ) -> TiffResult> { let encoder = DirectoryEncoder::new(&mut self.writer)?; ImageEncoder::new(encoder, width, height) } /// Convenience function to write an entire image from memory. - pub fn write_image(&mut self, width: u32, height: u32, data: &[C::Inner]) -> TiffResult<()> where [C::Inner]: TiffValue { + pub fn write_image( + &mut self, + width: u32, + height: u32, + data: &[C::Inner], + ) -> TiffResult<()> + where + [C::Inner]: TiffValue, + { let encoder = DirectoryEncoder::new(&mut self.writer)?; let mut image: ImageEncoder = ImageEncoder::new(encoder, width, height).unwrap(); let mut idx = 0; while image.next_strip_sample_count() > 0 { let sample_count = image.next_strip_sample_count() as usize; - image.write_strip(&data[idx..idx+sample_count]).unwrap(); + image.write_strip(&data[idx..idx + sample_count]).unwrap(); idx += sample_count; } image.finish() @@ -285,7 +294,8 @@ impl<'a, W: Write + Seek> DirectoryEncoder<'a, W> { value.write(&mut writer).unwrap(); } - self.ifd.insert(tag.to_u16(), (::FIELD_TYPE as u16, value.count(), bytes)); + self.ifd + .insert(tag.to_u16(), (::FIELD_TYPE as u16, value.count(), bytes)); } fn write_directory(&mut self) -> TiffResult { @@ -297,15 +307,14 @@ impl<'a, W: Write + Seek> DirectoryEncoder<'a, W> { *bytes = vec![0, 0, 0, 0]; let mut writer = TiffWriter::new(bytes as &mut [u8]); writer.write_u32(offset as u32)?; - } - else { + } else { while bytes.len() < 4 { bytes.push(0); } } } - let offset = self.writer.offset(); + let offset = self.writer.offset(); self.writer.write_u16(self.ifd.len() as u16)?; for (tag, (field_type, count, offset)) in self.ifd.iter() { @@ -355,7 +364,6 @@ impl<'a, W: Write + Seek> Drop for DirectoryEncoder<'a, W> { } } - /// Type to encode images strip by strip. /// /// You should call `finish` on this when you are finished with it. @@ -393,7 +401,11 @@ pub struct ImageEncoder<'a, W: Write + Seek, C: ColorType> { } impl<'a, W: Write + Seek, T: ColorType> ImageEncoder<'a, W, T> { - fn new(mut encoder: DirectoryEncoder<'a, W>, width: u32, height: u32) -> TiffResult> { + fn new( + mut encoder: DirectoryEncoder<'a, W>, + width: u32, + height: u32, + ) -> TiffResult> { let row_samples = u64::from(width) * ::BITS_PER_SAMPLE.len() as u64; let row_bytes = row_samples * u64::from(::BYTE_LEN); @@ -412,10 +424,10 @@ impl<'a, W: Write + Seek, T: ColorType> ImageEncoder<'a, W, T> { encoder.write_tag(Tag::RowsPerStrip, rows_per_strip as u32); encoder.write_tag(Tag::SamplesPerPixel, ::BITS_PER_SAMPLE.len() as u16); - encoder.write_tag(Tag::XResolution, Rational {n: 1, d: 1}); - encoder.write_tag(Tag::YResolution, Rational {n: 1, d: 1}); + encoder.write_tag(Tag::XResolution, Rational { n: 1, d: 1 }); + encoder.write_tag(Tag::YResolution, Rational { n: 1, d: 1 }); encoder.write_tag(Tag::ResolutionUnit, 1u16); - + Ok(ImageEncoder { encoder, strip_count, @@ -433,17 +445,23 @@ impl<'a, W: Write + Seek, T: ColorType> ImageEncoder<'a, W, T> { /// Number of samples the next strip should have. pub fn next_strip_sample_count(&self) -> u64 { if self.strip_idx >= self.strip_count { - return 0 + return 0; } let start_row = std::cmp::min(u64::from(self.height), self.strip_idx * self.rows_per_strip); - let end_row = std::cmp::min(u64::from(self.height), (self.strip_idx+1)*self.rows_per_strip); + let end_row = std::cmp::min( + u64::from(self.height), + (self.strip_idx + 1) * self.rows_per_strip, + ); (end_row - start_row) * self.row_samples } /// Write a single strip. - pub fn write_strip(&mut self, value: &[T::Inner]) -> TiffResult<()> where [T::Inner]: TiffValue { + pub fn write_strip(&mut self, value: &[T::Inner]) -> TiffResult<()> + where + [T::Inner]: TiffValue, + { // TODO: Compression let samples = self.next_strip_sample_count(); assert_eq!(value.len() as u64, samples); @@ -479,8 +497,10 @@ impl<'a, W: Write + Seek, T: ColorType> ImageEncoder<'a, W, T> { } fn finish_internal(&mut self) -> TiffResult<()> { - self.encoder.write_tag(Tag::StripOffsets, &*self.strip_offsets); - self.encoder.write_tag(Tag::StripByteCounts, &*self.strip_byte_count); + self.encoder + .write_tag(Tag::StripOffsets, &*self.strip_offsets); + self.encoder + .write_tag(Tag::StripByteCounts, &*self.strip_byte_count); self.dropped = true; self.encoder.finish_internal() @@ -504,4 +524,3 @@ impl<'a, W: Write + Seek, C: ColorType> Drop for ImageEncoder<'a, W, C> { } } } - diff --git a/src/encoder/writer.rs b/src/encoder/writer.rs index 1f0eef1..a689f0c 100644 --- a/src/encoder/writer.rs +++ b/src/encoder/writer.rs @@ -1,6 +1,6 @@ -use std::io::{self, Write, Seek, SeekFrom}; -use byteorder::{ByteOrder, WriteBytesExt, BigEndian, LittleEndian, NativeEndian}; use crate::error::TiffResult; +use byteorder::{BigEndian, ByteOrder, LittleEndian, NativeEndian, WriteBytesExt}; +use std::io::{self, Seek, SeekFrom, Write}; pub trait TiffByteOrder: ByteOrder { fn write_header(writer: &mut TiffWriter) -> TiffResult<()>; @@ -33,10 +33,7 @@ pub struct TiffWriter { impl TiffWriter { pub fn new(writer: W) -> Self { - Self { - writer, - offset: 0, - } + Self { writer, offset: 0 } } pub fn offset(&self) -> u64 { @@ -82,7 +79,7 @@ impl TiffWriter { let padd_len = 4 - (self.offset % 4); self.writer.write_all(&padding[..padd_len as usize])?; } - + Ok(()) } } diff --git a/src/error.rs b/src/error.rs index d26d91b..cc57e62 100644 --- a/src/error.rs +++ b/src/error.rs @@ -4,7 +4,7 @@ use std::io; use std::string; use decoder::ifd::{Tag, Value}; -use decoder::{PhotometricInterpretation, CompressionMethod, PlanarConfiguration}; +use decoder::{CompressionMethod, PhotometricInterpretation, PlanarConfiguration}; use ColorType; /// Tiff error kinds. @@ -45,8 +45,12 @@ impl fmt::Display for TiffFormatError { InconsistentSizesEncountered => write!(fmt, "Inconsistent sizes encountered."), InvalidTag => write!(fmt, "Image contains invalid tag."), RequiredTagNotFound(ref tag) => write!(fmt, "Required tag `{:?}` not found.", tag), - UnknownPredictor(ref predictor) => write!(fmt, "Unknown predictor “{}” encountered", predictor), - UnsignedIntegerExpected(ref val) => write!(fmt, "Expected unsigned integer, {:?} found.", val), + UnknownPredictor(ref predictor) => { + write!(fmt, "Unknown predictor “{}” encountered", predictor) + } + UnsignedIntegerExpected(ref val) => { + write!(fmt, "Expected unsigned integer, {:?} found.", val) + } } } } @@ -69,17 +73,36 @@ impl fmt::Display for TiffUnsupportedError { fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { use self::TiffUnsupportedError::*; match *self { - HorizontalPredictor(color_type) => write!(fmt, "Horizontal predictor for {:?} is unsupported.", color_type), - InterpretationWithBits(ref photometric_interpretation, ref bits_per_sample) => { - write!(fmt, "{:?} with {:?} bits per sample is unsupported", photometric_interpretation, bits_per_sample) - }, - UnknownInterpretation => write!(fmt, "The image is using an unknown photometric interpretation."), + HorizontalPredictor(color_type) => write!( + fmt, + "Horizontal predictor for {:?} is unsupported.", + color_type + ), + InterpretationWithBits(ref photometric_interpretation, ref bits_per_sample) => write!( + fmt, + "{:?} with {:?} bits per sample is unsupported", + photometric_interpretation, bits_per_sample + ), + UnknownInterpretation => write!( + fmt, + "The image is using an unknown photometric interpretation." + ), UnknownCompressionMethod => write!(fmt, "Unknown compression method."), - UnsupportedCompressionMethod(method) => write!(fmt, "Compression method {:?} is unsupported", method), - UnsupportedSampleDepth(samples) => write!(fmt, "{} samples per pixel is supported.", samples), - UnsupportedColorType(color_type) => write!(fmt, "Color type {:?} is unsupported", color_type), - UnsupportedBitsPerChannel(bits) => write!(fmt, "{} bits per channel not supported", bits), - UnsupportedPlanarConfig(config) => write!(fmt, "Unsupported planar configuration “{:?}”.", config), + UnsupportedCompressionMethod(method) => { + write!(fmt, "Compression method {:?} is unsupported", method) + } + UnsupportedSampleDepth(samples) => { + write!(fmt, "{} samples per pixel is supported.", samples) + } + UnsupportedColorType(color_type) => { + write!(fmt, "Color type {:?} is unsupported", color_type) + } + UnsupportedBitsPerChannel(bits) => { + write!(fmt, "{} bits per channel not supported", bits) + } + UnsupportedPlanarConfig(config) => { + write!(fmt, "Unsupported planar configuration “{:?}”.", config) + } UnsupportedDataType => write!(fmt, "Unsupported data type."), } } @@ -89,8 +112,12 @@ impl fmt::Display for TiffError { fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { match *self { TiffError::FormatError(ref e) => write!(fmt, "Format error: {}", e), - TiffError::UnsupportedError(ref f) => write!(fmt, "The Decoder does not support the \ - image format `{}`", f), + TiffError::UnsupportedError(ref f) => write!( + fmt, + "The Decoder does not support the \ + image format `{}`", + f + ), TiffError::IoError(ref e) => e.fmt(fmt), TiffError::LimitsExceeded => write!(fmt, "The Decoder limits are exceeded"), } @@ -98,7 +125,7 @@ impl fmt::Display for TiffError { } impl Error for TiffError { - fn description (&self) -> &str { + fn description(&self) -> &str { match *self { TiffError::FormatError(..) => "Format error", TiffError::UnsupportedError(..) => "Unsupported error", @@ -107,10 +134,10 @@ impl Error for TiffError { } } - fn cause (&self) -> Option<&Error> { + fn cause(&self) -> Option<&Error> { match *self { TiffError::IoError(ref e) => Some(e), - _ => None + _ => None, } } } diff --git a/src/lib.rs b/src/lib.rs index bf4a1bb..8ed1d25 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,14 +8,15 @@ extern crate byteorder; extern crate lzw; -#[macro_use] extern crate num_derive; +#[macro_use] +extern crate num_derive; extern crate num_traits; pub mod decoder; pub mod encoder; mod error; -pub use self::error::{TiffError, TiffFormatError, TiffUnsupportedError, TiffResult}; +pub use self::error::{TiffError, TiffFormatError, TiffResult, TiffUnsupportedError}; /// An enumeration over supported color types and their bit depths #[derive(Copy, PartialEq, Eq, Debug, Clone, Hash)] diff --git a/tests/decode_images.rs b/tests/decode_images.rs index f34bcf8..78ceb6c 100644 --- a/tests/decode_images.rs +++ b/tests/decode_images.rs @@ -1,14 +1,14 @@ extern crate tiff; +use tiff::decoder::{ifd::Tag, ifd::Value, Decoder, DecodingResult}; use tiff::ColorType; -use tiff::decoder::{Decoder, DecodingResult, ifd::Tag, ifd::Value}; use std::fs::File; #[test] -fn test_gray_u8() -{ - let img_file = File::open("./tests/images/minisblack-1c-8b.tiff").expect("Cannot find test image!"); +fn test_gray_u8() { + let img_file = + File::open("./tests/images/minisblack-1c-8b.tiff").expect("Cannot find test image!"); let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); assert_eq!(decoder.colortype().unwrap(), ColorType::Gray(8)); let img_res = decoder.read_image(); @@ -16,8 +16,7 @@ fn test_gray_u8() } #[test] -fn test_rgb_u8() -{ +fn test_rgb_u8() { let img_file = File::open("./tests/images/rgb-3c-8b.tiff").expect("Cannot find test image!"); let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); assert_eq!(decoder.colortype().unwrap(), ColorType::RGB(8)); @@ -26,9 +25,9 @@ fn test_rgb_u8() } #[test] -fn test_gray_u16() -{ - let img_file = File::open("./tests/images/minisblack-1c-16b.tiff").expect("Cannot find test image!"); +fn test_gray_u16() { + let img_file = + File::open("./tests/images/minisblack-1c-16b.tiff").expect("Cannot find test image!"); let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); assert_eq!(decoder.colortype().unwrap(), ColorType::Gray(16)); let img_res = decoder.read_image(); @@ -36,8 +35,7 @@ fn test_gray_u16() } #[test] -fn test_rgb_u16() -{ +fn test_rgb_u16() { let img_file = File::open("./tests/images/rgb-3c-16b.tiff").expect("Cannot find test image!"); let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); assert_eq!(decoder.colortype().unwrap(), ColorType::RGB(16)); @@ -46,8 +44,7 @@ fn test_rgb_u16() } #[test] -fn test_string_tags() -{ +fn test_string_tags() { // these files have null-terminated strings for their Software tag. One has extra bytes after // the null byte, so we check both to ensure that we're truncating properly let filenames = vec!["minisblack-1c-16b.tiff", "rgb-3c-16b.tiff"]; @@ -55,10 +52,13 @@ fn test_string_tags() let path = format!("./tests/images/{}", filename); let img_file = File::open(path).expect("can't open file"); let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); - let software= decoder.get_tag(Tag::Software).unwrap(); + let software = decoder.get_tag(Tag::Software).unwrap(); match software { - Value::Ascii(s) => assert_eq!(s, String::from("GraphicsMagick 1.2 unreleased Q16 http://www.GraphicsMagick.org/")), - _ => assert!(false) + Value::Ascii(s) => assert_eq!( + s, + String::from("GraphicsMagick 1.2 unreleased Q16 http://www.GraphicsMagick.org/") + ), + _ => assert!(false), }; } } @@ -80,8 +80,7 @@ fn test_decode_data() { assert_eq!(decoder.dimensions().unwrap(), (100, 100)); if let DecodingResult::U8(img_res) = decoder.read_image().unwrap() { assert_eq!(image_data, img_res); - } - else { + } else { panic!("Wrong data type"); } } @@ -90,9 +89,9 @@ fn test_decode_data() { //#[test] //fn test_gray_alpha_u8() //{ - //let img_file = File::open("./tests/images/minisblack-2c-8b-alpha.tiff").expect("Cannot find test image!"); - //let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); - //assert_eq!(decoder.colortype().unwrap(), ColorType::GrayA(8)); - //let img_res = decoder.read_image(); - //assert!(img_res.is_ok()); +//let img_file = File::open("./tests/images/minisblack-2c-8b-alpha.tiff").expect("Cannot find test image!"); +//let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); +//assert_eq!(decoder.colortype().unwrap(), ColorType::GrayA(8)); +//let img_res = decoder.read_image(); +//assert!(img_res.is_ok()); //} diff --git a/tests/encode_images.rs b/tests/encode_images.rs index 720df4b..d4a5f77 100644 --- a/tests/encode_images.rs +++ b/tests/encode_images.rs @@ -1,12 +1,12 @@ -extern crate tiff; extern crate tempfile; +extern crate tiff; -use tiff::ColorType; use tiff::decoder::{Decoder, DecodingResult}; use tiff::encoder::{colortype, TiffEncoder}; +use tiff::ColorType; -use std::io::{Seek, SeekFrom}; use std::fs::File; +use std::io::{Seek, SeekFrom}; #[test] fn encode_decode() { @@ -23,7 +23,8 @@ fn encode_decode() { { let mut tiff = TiffEncoder::new(&mut file).unwrap(); - tiff.write_image::(100, 100, &image_data).unwrap(); + tiff.write_image::(100, 100, &image_data) + .unwrap(); } { file.seek(SeekFrom::Start(0)).unwrap(); @@ -32,18 +33,16 @@ fn encode_decode() { assert_eq!(decoder.dimensions().unwrap(), (100, 100)); if let DecodingResult::U8(img_res) = decoder.read_image().unwrap() { assert_eq!(image_data, img_res); - } - else { + } else { panic!("Wrong data type"); } } } - #[test] -fn test_gray_u8_roundtrip() -{ - let img_file = File::open("./tests/images/minisblack-1c-8b.tiff").expect("Cannot find test image!"); +fn test_gray_u8_roundtrip() { + let img_file = + File::open("./tests/images/minisblack-1c-8b.tiff").expect("Cannot find test image!"); let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); assert_eq!(decoder.colortype().unwrap(), ColorType::Gray(8)); @@ -55,25 +54,24 @@ fn test_gray_u8_roundtrip() let mut file = tempfile::tempfile().unwrap(); { let mut tiff = TiffEncoder::new(&mut file).unwrap(); - + let (width, height) = decoder.dimensions().unwrap(); - tiff.write_image::(width, height, &image_data).unwrap(); + tiff.write_image::(width, height, &image_data) + .unwrap(); } file.seek(SeekFrom::Start(0)).unwrap(); { let mut decoder = Decoder::new(&mut file).unwrap(); if let DecodingResult::U8(img_res) = decoder.read_image().unwrap() { assert_eq!(image_data, img_res); - } - else { + } else { panic!("Wrong data type"); } } } #[test] -fn test_rgb_u8_roundtrip() -{ +fn test_rgb_u8_roundtrip() { let img_file = File::open("./tests/images/rgb-3c-8b.tiff").expect("Cannot find test image!"); let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); assert_eq!(decoder.colortype().unwrap(), ColorType::RGB(8)); @@ -86,26 +84,26 @@ fn test_rgb_u8_roundtrip() let mut file = tempfile::tempfile().unwrap(); { let mut tiff = TiffEncoder::new(&mut file).unwrap(); - + let (width, height) = decoder.dimensions().unwrap(); - tiff.write_image::(width, height, &image_data).unwrap(); + tiff.write_image::(width, height, &image_data) + .unwrap(); } file.seek(SeekFrom::Start(0)).unwrap(); { let mut decoder = Decoder::new(&mut file).unwrap(); if let DecodingResult::U8(img_res) = decoder.read_image().unwrap() { assert_eq!(image_data, img_res); - } - else { + } else { panic!("Wrong data type"); } } } #[test] -fn test_gray_u16_roundtrip() -{ - let img_file = File::open("./tests/images/minisblack-1c-16b.tiff").expect("Cannot find test image!"); +fn test_gray_u16_roundtrip() { + let img_file = + File::open("./tests/images/minisblack-1c-16b.tiff").expect("Cannot find test image!"); let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); assert_eq!(decoder.colortype().unwrap(), ColorType::Gray(16)); @@ -117,25 +115,24 @@ fn test_gray_u16_roundtrip() let mut file = tempfile::tempfile().unwrap(); { let mut tiff = TiffEncoder::new(&mut file).unwrap(); - + let (width, height) = decoder.dimensions().unwrap(); - tiff.write_image::(width, height, &image_data).unwrap(); + tiff.write_image::(width, height, &image_data) + .unwrap(); } file.seek(SeekFrom::Start(0)).unwrap(); { let mut decoder = Decoder::new(&mut file).unwrap(); if let DecodingResult::U16(img_res) = decoder.read_image().unwrap() { assert_eq!(image_data, img_res); - } - else { + } else { panic!("Wrong data type"); } } } #[test] -fn test_rgb_u16_roundtrip() -{ +fn test_rgb_u16_roundtrip() { let img_file = File::open("./tests/images/rgb-3c-16b.tiff").expect("Cannot find test image!"); let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); assert_eq!(decoder.colortype().unwrap(), ColorType::RGB(16)); @@ -148,17 +145,17 @@ fn test_rgb_u16_roundtrip() let mut file = tempfile::tempfile().unwrap(); { let mut tiff = TiffEncoder::new(&mut file).unwrap(); - + let (width, height) = decoder.dimensions().unwrap(); - tiff.write_image::(width, height, &image_data).unwrap(); + tiff.write_image::(width, height, &image_data) + .unwrap(); } file.seek(SeekFrom::Start(0)).unwrap(); { let mut decoder = Decoder::new(&mut file).unwrap(); if let DecodingResult::U16(img_res) = decoder.read_image().unwrap() { assert_eq!(image_data, img_res); - } - else { + } else { panic!("Wrong data type"); } } diff --git a/tests/fuzz_tests.rs b/tests/fuzz_tests.rs index 88cb64d..db126a6 100644 --- a/tests/fuzz_tests.rs +++ b/tests/fuzz_tests.rs @@ -1,7 +1,7 @@ extern crate tiff; -use tiff::TiffResult; use tiff::decoder::Decoder; +use tiff::TiffResult; use std::fs::File;