Refactor a bit
Rename the Image* types to Tiff* Extract the "common" types to the top level.
This commit is contained in:
1 parent
7c46be100d
commit
0c623bc3a3
5 files changed
+110
-129
No files matched your search
+6
-6
@@ -4,7 +4,7 @@ use std::io::{self, Read, Seek};
|
|||||||
use std::collections::{HashMap};
|
use std::collections::{HashMap};
|
||||||
|
|
||||||
use super::stream::{ByteOrder, SmartReader, EndianReader};
|
use super::stream::{ByteOrder, SmartReader, EndianReader};
|
||||||
use super::{ImageError, ImageResult};
|
use ::{TiffError, TiffResult};
|
||||||
|
|
||||||
use self::Value::{Unsigned, List};
|
use self::Value::{Unsigned, List};
|
||||||
|
|
||||||
@@ -96,15 +96,15 @@ pub enum Value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Value {
|
impl Value {
|
||||||
pub fn into_u32(self) -> ImageResult<u32> {
|
pub fn into_u32(self) -> TiffResult<u32> {
|
||||||
match self {
|
match self {
|
||||||
Unsigned(val) => Ok(val),
|
Unsigned(val) => Ok(val),
|
||||||
val => Err(ImageError::FormatError(format!(
|
val => Err(TiffError::FormatError(format!(
|
||||||
"Expected unsigned integer, {:?} found.", val
|
"Expected unsigned integer, {:?} found.", val
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn into_u32_vec(self) -> ImageResult<Vec<u32>> {
|
pub fn into_u32_vec(self) -> TiffResult<Vec<u32>> {
|
||||||
match self {
|
match self {
|
||||||
List(vec) => {
|
List(vec) => {
|
||||||
let mut new_vec = Vec::with_capacity(vec.len());
|
let mut new_vec = Vec::with_capacity(vec.len());
|
||||||
@@ -153,7 +153,7 @@ impl Entry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn val<R: Read + Seek>(&self, decoder: &mut super::TIFFDecoder<R>)
|
pub fn val<R: Read + Seek>(&self, decoder: &mut super::TIFFDecoder<R>)
|
||||||
-> ImageResult<Value> {
|
-> TiffResult<Value> {
|
||||||
let bo = decoder.byte_order();
|
let bo = decoder.byte_order();
|
||||||
match (self.type_, self.count) {
|
match (self.type_, self.count) {
|
||||||
// TODO check if this could give wrong results
|
// TODO check if this could give wrong results
|
||||||
@@ -184,7 +184,7 @@ impl Entry {
|
|||||||
}
|
}
|
||||||
Ok(List(v))
|
Ok(List(v))
|
||||||
}
|
}
|
||||||
_ => Err(ImageError::UnsupportedError("Unsupported data type.".to_string()))
|
_ => Err(TiffError::UnsupportedError("Unsupported data type.".to_string()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-121
@@ -1,10 +1,10 @@
|
|||||||
use std::error::Error;
|
|
||||||
use std::io::{self, Read, Seek};
|
use std::io::{self, Read, Seek};
|
||||||
use std::fmt;
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use num_traits::{FromPrimitive, Num};
|
use num_traits::{FromPrimitive, Num};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use ::{ColorType, TiffError, TiffResult};
|
||||||
|
|
||||||
use self::ifd::Directory;
|
use self::ifd::Directory;
|
||||||
|
|
||||||
use self::stream::{
|
use self::stream::{
|
||||||
@@ -18,99 +18,6 @@ use self::stream::{
|
|||||||
mod ifd;
|
mod ifd;
|
||||||
mod stream;
|
mod stream;
|
||||||
|
|
||||||
/// An enumeration over supported color types and their bit depths
|
|
||||||
#[derive(Copy, PartialEq, Eq, Debug, Clone, Hash)]
|
|
||||||
pub enum ColorType {
|
|
||||||
/// Pixel is grayscale
|
|
||||||
Gray(u8),
|
|
||||||
|
|
||||||
/// Pixel contains R, G and B channels
|
|
||||||
RGB(u8),
|
|
||||||
|
|
||||||
/// Pixel is an index into a color palette
|
|
||||||
Palette(u8),
|
|
||||||
|
|
||||||
/// Pixel is grayscale with an alpha channel
|
|
||||||
GrayA(u8),
|
|
||||||
|
|
||||||
/// Pixel is RGB with an alpha channel
|
|
||||||
RGBA(u8),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An enumeration of Image errors
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum ImageError {
|
|
||||||
/// The Image is not formatted properly
|
|
||||||
FormatError(String),
|
|
||||||
|
|
||||||
/// The Image's dimensions are either too small or too large
|
|
||||||
DimensionError,
|
|
||||||
|
|
||||||
/// The Decoder does not support this image format
|
|
||||||
UnsupportedError(String),
|
|
||||||
|
|
||||||
/// The Decoder does not support this color type
|
|
||||||
UnsupportedColor(ColorType),
|
|
||||||
|
|
||||||
/// Not enough data was provided to the Decoder
|
|
||||||
/// to decode the image
|
|
||||||
NotEnoughData,
|
|
||||||
|
|
||||||
/// An I/O Error occurred while decoding the image
|
|
||||||
IoError(io::Error),
|
|
||||||
|
|
||||||
/// The end of the image has been reached
|
|
||||||
ImageEnd
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for ImageError {
|
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
|
||||||
match *self {
|
|
||||||
ImageError::FormatError(ref e) => write!(fmt, "Format error: {}", e),
|
|
||||||
ImageError::DimensionError => write!(fmt, "The Image's dimensions are either too \
|
|
||||||
small or too large"),
|
|
||||||
ImageError::UnsupportedError(ref f) => write!(fmt, "The Decoder does not support the \
|
|
||||||
image format `{}`", f),
|
|
||||||
ImageError::UnsupportedColor(ref c) => write!(fmt, "The decoder does not support \
|
|
||||||
the color type `{:?}`", c),
|
|
||||||
ImageError::NotEnoughData => write!(fmt, "Not enough data was provided to the \
|
|
||||||
Decoder to decode the image"),
|
|
||||||
ImageError::IoError(ref e) => e.fmt(fmt),
|
|
||||||
ImageError::ImageEnd => write!(fmt, "The end of the image has been reached")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Error for ImageError {
|
|
||||||
fn description (&self) -> &str {
|
|
||||||
match *self {
|
|
||||||
ImageError::FormatError(..) => "Format error",
|
|
||||||
ImageError::DimensionError => "Dimension error",
|
|
||||||
ImageError::UnsupportedError(..) => "Unsupported error",
|
|
||||||
ImageError::UnsupportedColor(..) => "Unsupported color",
|
|
||||||
ImageError::NotEnoughData => "Not enough data",
|
|
||||||
ImageError::IoError(..) => "IO error",
|
|
||||||
ImageError::ImageEnd => "Image end"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cause (&self) -> Option<&Error> {
|
|
||||||
match *self {
|
|
||||||
ImageError::IoError(ref e) => Some(e),
|
|
||||||
_ => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<io::Error> for ImageError {
|
|
||||||
fn from(err: io::Error) -> ImageError {
|
|
||||||
ImageError::IoError(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Result of an image decoding/encoding process
|
|
||||||
pub type ImageResult<T> = Result<T, ImageError>;
|
|
||||||
|
|
||||||
/// Result of a decoding process
|
/// Result of a decoding process
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum DecodingResult {
|
pub enum DecodingResult {
|
||||||
@@ -221,12 +128,12 @@ fn rev_hpredict_nsamp<T>(mut image: Vec<T>,
|
|||||||
image
|
image
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rev_hpredict(image: DecodingResult, size: (u32, u32), color_type: ColorType) -> ImageResult<DecodingResult> {
|
fn rev_hpredict(image: DecodingResult, size: (u32, u32), color_type: ColorType) -> TiffResult<DecodingResult> {
|
||||||
let samples = match color_type {
|
let samples = match color_type {
|
||||||
ColorType::Gray(8) | ColorType::Gray(16) => 1,
|
ColorType::Gray(8) | ColorType::Gray(16) => 1,
|
||||||
ColorType::RGB(8) | ColorType::RGB(16) => 3,
|
ColorType::RGB(8) | ColorType::RGB(16) => 3,
|
||||||
ColorType::RGBA(8) | ColorType::RGBA(16) => 4,
|
ColorType::RGBA(8) | ColorType::RGBA(16) => 4,
|
||||||
_ => return Err(ImageError::UnsupportedError(format!(
|
_ => return Err(TiffError::UnsupportedError(format!(
|
||||||
"Horizontal predictor for {:?} is unsupported.", color_type
|
"Horizontal predictor for {:?} is unsupported.", color_type
|
||||||
)))
|
)))
|
||||||
};
|
};
|
||||||
@@ -242,7 +149,7 @@ fn rev_hpredict(image: DecodingResult, size: (u32, u32), color_type: ColorType)
|
|||||||
|
|
||||||
impl<R: Read + Seek> TIFFDecoder<R> {
|
impl<R: Read + Seek> TIFFDecoder<R> {
|
||||||
/// Create a new decoder that decodes from the stream ```r```
|
/// Create a new decoder that decodes from the stream ```r```
|
||||||
pub fn new(r: R) -> ImageResult<TIFFDecoder<R>> {
|
pub fn new(r: R) -> TiffResult<TIFFDecoder<R>> {
|
||||||
TIFFDecoder {
|
TIFFDecoder {
|
||||||
reader: SmartReader::wrap(r, ByteOrder::LittleEndian),
|
reader: SmartReader::wrap(r, ByteOrder::LittleEndian),
|
||||||
byte_order: ByteOrder::LittleEndian,
|
byte_order: ByteOrder::LittleEndian,
|
||||||
@@ -257,7 +164,7 @@ impl<R: Read + Seek> TIFFDecoder<R> {
|
|||||||
}.init()
|
}.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn colortype(&mut self) -> ImageResult<ColorType> {
|
fn colortype(&mut self) -> TiffResult<ColorType> {
|
||||||
match self.photometric_interpretation {
|
match self.photometric_interpretation {
|
||||||
// TODO: catch also [ 8, 8, 8, _] this does not work due to a bug in rust atm
|
// 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, 8] => Ok(ColorType::RGBA(8)),
|
||||||
@@ -267,13 +174,13 @@ impl<R: Read + Seek> TIFFDecoder<R> {
|
|||||||
PhotometricInterpretation::BlackIsZero | PhotometricInterpretation::WhiteIsZero
|
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])),
|
||||||
|
|
||||||
_ => Err(ImageError::UnsupportedError(format!(
|
_ => Err(TiffError::UnsupportedError(format!(
|
||||||
"{:?} with {:?} bits per sample is unsupported", self.bits_per_sample, self.photometric_interpretation
|
"{:?} with {:?} bits per sample is unsupported", self.bits_per_sample, self.photometric_interpretation
|
||||||
))) // TODO: this is bad we should not fail at this point}
|
))) // TODO: this is bad we should not fail at this point}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_header(&mut self) -> ImageResult<()> {
|
fn read_header(&mut self) -> TiffResult<()> {
|
||||||
let mut endianess = Vec::with_capacity(2);
|
let mut endianess = Vec::with_capacity(2);
|
||||||
try!(self.reader.by_ref().take(2).read_to_end(&mut endianess));
|
try!(self.reader.by_ref().take(2).read_to_end(&mut endianess));
|
||||||
match &*endianess {
|
match &*endianess {
|
||||||
@@ -283,12 +190,12 @@ impl<R: Read + Seek> TIFFDecoder<R> {
|
|||||||
b"MM" => {
|
b"MM" => {
|
||||||
self.byte_order = ByteOrder::BigEndian;
|
self.byte_order = ByteOrder::BigEndian;
|
||||||
self.reader.byte_order = ByteOrder::BigEndian; },
|
self.reader.byte_order = ByteOrder::BigEndian; },
|
||||||
_ => return Err(ImageError::FormatError(
|
_ => return Err(TiffError::FormatError(
|
||||||
"TIFF signature not found.".to_string()
|
"TIFF signature not found.".to_string()
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
if try!(self.read_short()) != 42 {
|
if try!(self.read_short()) != 42 {
|
||||||
return Err(ImageError::FormatError("TIFF signature invalid.".to_string()))
|
return Err(TiffError::FormatError("TIFF signature invalid.".to_string()))
|
||||||
}
|
}
|
||||||
self.next_ifd = match try!(self.read_long()) {
|
self.next_ifd = match try!(self.read_long()) {
|
||||||
0 => None,
|
0 => None,
|
||||||
@@ -298,7 +205,7 @@ impl<R: Read + Seek> TIFFDecoder<R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Initializes the decoder.
|
/// Initializes the decoder.
|
||||||
pub fn init(mut self) -> ImageResult<TIFFDecoder<R>> {
|
pub fn init(mut self) -> TiffResult<TIFFDecoder<R>> {
|
||||||
try!(self.read_header());
|
try!(self.read_header());
|
||||||
self.next_image()
|
self.next_image()
|
||||||
}
|
}
|
||||||
@@ -306,7 +213,7 @@ impl<R: Read + Seek> TIFFDecoder<R> {
|
|||||||
/// Reads in the next image.
|
/// Reads in the next image.
|
||||||
/// If there is no further image in the TIFF file a format error is returned.
|
/// If there is no further image in the TIFF file a format error is returned.
|
||||||
/// To determine whether there are more images call `TIFFDecoder::more_images` instead.
|
/// To determine whether there are more images call `TIFFDecoder::more_images` instead.
|
||||||
pub fn next_image(mut self) -> ImageResult<TIFFDecoder<R>> {
|
pub fn next_image(mut self) -> TiffResult<TIFFDecoder<R>> {
|
||||||
self.ifd = Some(try!(self.read_ifd()));
|
self.ifd = Some(try!(self.read_ifd()));
|
||||||
self.width = try!(self.get_tag_u32(ifd::Tag::ImageWidth));
|
self.width = try!(self.get_tag_u32(ifd::Tag::ImageWidth));
|
||||||
self.height = try!(self.get_tag_u32(ifd::Tag::ImageLength));
|
self.height = try!(self.get_tag_u32(ifd::Tag::ImageLength));
|
||||||
@@ -314,7 +221,7 @@ impl<R: Read + Seek> TIFFDecoder<R> {
|
|||||||
try!(self.get_tag_u32(ifd::Tag::PhotometricInterpretation))
|
try!(self.get_tag_u32(ifd::Tag::PhotometricInterpretation))
|
||||||
) {
|
) {
|
||||||
Some(val) => val,
|
Some(val) => val,
|
||||||
None => return Err(ImageError::UnsupportedError(
|
None => return Err(TiffError::UnsupportedError(
|
||||||
"The image is using an unknown photometric interpretation.".to_string()
|
"The image is using an unknown photometric interpretation.".to_string()
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
@@ -323,7 +230,7 @@ impl<R: Read + Seek> TIFFDecoder<R> {
|
|||||||
Some(method) => {
|
Some(method) => {
|
||||||
self.compression_method = method
|
self.compression_method = method
|
||||||
},
|
},
|
||||||
None => return Err(ImageError::UnsupportedError(
|
None => return Err(TiffError::UnsupportedError(
|
||||||
"Unknown compression method.".to_string()
|
"Unknown compression method.".to_string()
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -343,7 +250,7 @@ impl<R: Read + Seek> TIFFDecoder<R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
_ => return Err(ImageError::UnsupportedError(
|
_ => return Err(TiffError::UnsupportedError(
|
||||||
format!("{} samples per pixel is supported.", self.samples)
|
format!("{} samples per pixel is supported.", self.samples)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -396,7 +303,7 @@ impl<R: Read + Seek> TIFFDecoder<R> {
|
|||||||
// Type 2 bytes
|
// Type 2 bytes
|
||||||
// Count 4 bytes
|
// Count 4 bytes
|
||||||
// Value 4 bytes either a pointer the value itself
|
// Value 4 bytes either a pointer the value itself
|
||||||
fn read_entry(&mut self) -> ImageResult<Option<(ifd::Tag, ifd::Entry)>> {
|
fn read_entry(&mut self) -> TiffResult<Option<(ifd::Tag, ifd::Entry)>> {
|
||||||
let tag = ifd::Tag::from_u16(try!(self.read_short()));
|
let tag = ifd::Tag::from_u16(try!(self.read_short()));
|
||||||
let type_: ifd::Type = match FromPrimitive::from_u16(try!(self.read_short())) {
|
let type_: ifd::Type = match FromPrimitive::from_u16(try!(self.read_short())) {
|
||||||
Some(t) => t,
|
Some(t) => t,
|
||||||
@@ -416,10 +323,10 @@ impl<R: Read + Seek> TIFFDecoder<R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Reads the next IFD
|
/// Reads the next IFD
|
||||||
fn read_ifd(&mut self) -> ImageResult<Directory> {
|
fn read_ifd(&mut self) -> TiffResult<Directory> {
|
||||||
let mut dir: Directory = HashMap::new();
|
let mut dir: Directory = HashMap::new();
|
||||||
match self.next_ifd {
|
match self.next_ifd {
|
||||||
None => return Err(ImageError::FormatError(
|
None => return Err(TiffError::FormatError(
|
||||||
"Image file directory not found.".to_string())
|
"Image file directory not found.".to_string())
|
||||||
),
|
),
|
||||||
Some(offset) => try!(self.goto_offset(offset))
|
Some(offset) => try!(self.goto_offset(offset))
|
||||||
@@ -440,7 +347,7 @@ impl<R: Read + Seek> TIFFDecoder<R> {
|
|||||||
|
|
||||||
/// Tries to retrieve a tag.
|
/// Tries to retrieve a tag.
|
||||||
/// Return `Ok(None)` if the tag is not present.
|
/// Return `Ok(None)` if the tag is not present.
|
||||||
fn find_tag(&mut self, tag: ifd::Tag) -> ImageResult<Option<ifd::Value>> {
|
fn find_tag(&mut self, tag: ifd::Tag) -> TiffResult<Option<ifd::Value>> {
|
||||||
let ifd: &Directory = unsafe {
|
let ifd: &Directory = unsafe {
|
||||||
let ifd = self.ifd.as_ref().unwrap(); // Ok to fail
|
let ifd = self.ifd.as_ref().unwrap(); // Ok to fail
|
||||||
// Get a immutable borrow of self
|
// Get a immutable borrow of self
|
||||||
@@ -455,7 +362,7 @@ impl<R: Read + Seek> TIFFDecoder<R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Tries to retrieve a tag and convert it to the desired type.
|
/// Tries to retrieve a tag and convert it to the desired type.
|
||||||
fn find_tag_u32(&mut self, tag: ifd::Tag) -> ImageResult<Option<u32>> {
|
fn find_tag_u32(&mut self, tag: ifd::Tag) -> TiffResult<Option<u32>> {
|
||||||
match self.find_tag(tag)? {
|
match self.find_tag(tag)? {
|
||||||
Some(val) => val.into_u32().map(Some),
|
Some(val) => val.into_u32().map(Some),
|
||||||
None => Ok(None)
|
None => Ok(None)
|
||||||
@@ -463,7 +370,7 @@ impl<R: Read + Seek> TIFFDecoder<R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Tries to retrieve a tag and convert it to the desired type.
|
/// Tries to retrieve a tag and convert it to the desired type.
|
||||||
fn find_tag_u32_vec(&mut self, tag: ifd::Tag) -> ImageResult<Option<Vec<u32>>> {
|
fn find_tag_u32_vec(&mut self, tag: ifd::Tag) -> TiffResult<Option<Vec<u32>>> {
|
||||||
match self.find_tag(tag)? {
|
match self.find_tag(tag)? {
|
||||||
Some(val) => val.into_u32_vec().map(Some),
|
Some(val) => val.into_u32_vec().map(Some),
|
||||||
None => Ok(None)
|
None => Ok(None)
|
||||||
@@ -472,28 +379,28 @@ impl<R: Read + Seek> TIFFDecoder<R> {
|
|||||||
|
|
||||||
/// Tries to retrieve a tag.
|
/// Tries to retrieve a tag.
|
||||||
/// Returns an error if the tag is not present
|
/// Returns an error if the tag is not present
|
||||||
fn get_tag(&mut self, tag: ifd::Tag) -> ImageResult<ifd::Value> {
|
fn get_tag(&mut self, tag: ifd::Tag) -> TiffResult<ifd::Value> {
|
||||||
match try!(self.find_tag(tag)) {
|
match try!(self.find_tag(tag)) {
|
||||||
Some(val) => Ok(val),
|
Some(val) => Ok(val),
|
||||||
None => Err(ImageError::FormatError(format!(
|
None => Err(TiffError::FormatError(format!(
|
||||||
"Required tag `{:?}` not found.", tag
|
"Required tag `{:?}` not found.", tag
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tries to retrieve a tag and convert it to the desired type.
|
/// Tries to retrieve a tag and convert it to the desired type.
|
||||||
fn get_tag_u32(&mut self, tag: ifd::Tag) -> ImageResult<u32> {
|
fn get_tag_u32(&mut self, tag: ifd::Tag) -> TiffResult<u32> {
|
||||||
self.get_tag(tag)?.into_u32()
|
self.get_tag(tag)?.into_u32()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tries to retrieve a tag and convert it to the desired type.
|
/// Tries to retrieve a tag and convert it to the desired type.
|
||||||
fn get_tag_u32_vec(&mut self, tag: ifd::Tag) -> ImageResult<Vec<u32>> {
|
fn get_tag_u32_vec(&mut self, tag: ifd::Tag) -> TiffResult<Vec<u32>> {
|
||||||
self.get_tag(tag)?.into_u32_vec()
|
self.get_tag(tag)?.into_u32_vec()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decompresses the strip into the supplied buffer.
|
/// Decompresses the strip into the supplied buffer.
|
||||||
/// Returns the number of bytes read.
|
/// Returns the number of bytes read.
|
||||||
fn expand_strip<'a>(&mut self, buffer: DecodingBuffer<'a>, offset: u32, length: u32, max_uncompressed_length: usize) -> ImageResult<usize> {
|
fn expand_strip<'a>(&mut self, buffer: DecodingBuffer<'a>, offset: u32, length: u32, max_uncompressed_length: usize) -> TiffResult<usize> {
|
||||||
let color_type = try!(self.colortype());
|
let color_type = try!(self.colortype());
|
||||||
try!(self.goto_offset(offset));
|
try!(self.goto_offset(offset));
|
||||||
let (bytes, mut reader): (usize, Box<EndianReader>) = match self.compression_method {
|
let (bytes, mut reader): (usize, Box<EndianReader>) = match self.compression_method {
|
||||||
@@ -510,7 +417,7 @@ impl<R: Read + Seek> TIFFDecoder<R> {
|
|||||||
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))
|
(bytes, Box::new(reader))
|
||||||
},
|
},
|
||||||
method => return Err(ImageError::UnsupportedError(format!(
|
method => return Err(TiffError::UnsupportedError(format!(
|
||||||
"Compression method {:?} is unsupported", method
|
"Compression method {:?} is unsupported", method
|
||||||
)))
|
)))
|
||||||
};
|
};
|
||||||
@@ -544,7 +451,7 @@ impl<R: Read + Seek> TIFFDecoder<R> {
|
|||||||
}
|
}
|
||||||
bytes
|
bytes
|
||||||
}
|
}
|
||||||
(type_, _) => return Err(ImageError::UnsupportedError(format!(
|
(type_, _) => return Err(TiffError::UnsupportedError(format!(
|
||||||
"Color type {:?} is unsupported", type_
|
"Color type {:?} is unsupported", type_
|
||||||
)))
|
)))
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
//! All IO functionality needed for TIFF decoding
|
//! All IO functionality needed for TIFF decoding
|
||||||
|
|
||||||
use std::io;
|
use std::io::{self, Read, Seek};
|
||||||
use std::io::{Read, Seek};
|
|
||||||
use byteorder::{ReadBytesExt, BigEndian, LittleEndian};
|
use byteorder::{ReadBytesExt, BigEndian, LittleEndian};
|
||||||
use lzw;
|
use lzw;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
use std::error::Error;
|
||||||
|
use std::fmt;
|
||||||
|
use std::io;
|
||||||
|
|
||||||
|
/// An enumeration of Tiff errors
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum TiffError {
|
||||||
|
/// The Image is not formatted properly
|
||||||
|
FormatError(String),
|
||||||
|
|
||||||
|
/// The Decoder does not support this image format
|
||||||
|
UnsupportedError(String),
|
||||||
|
|
||||||
|
/// An I/O Error occurred while decoding the image
|
||||||
|
IoError(io::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
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::IoError(ref e) => e.fmt(fmt),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error for TiffError {
|
||||||
|
fn description (&self) -> &str {
|
||||||
|
match *self {
|
||||||
|
TiffError::FormatError(..) => "Format error",
|
||||||
|
TiffError::UnsupportedError(..) => "Unsupported error",
|
||||||
|
TiffError::IoError(..) => "IO error",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cause (&self) -> Option<&Error> {
|
||||||
|
match *self {
|
||||||
|
TiffError::IoError(ref e) => Some(e),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<io::Error> for TiffError {
|
||||||
|
fn from(err: io::Error) -> TiffError {
|
||||||
|
TiffError::IoError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Result of an image decoding/encoding process
|
||||||
|
pub type TiffResult<T> = Result<T, TiffError>;
|
||||||
+22
@@ -14,3 +14,25 @@ extern crate num_traits;
|
|||||||
pub use self::decoder::TIFFDecoder;
|
pub use self::decoder::TIFFDecoder;
|
||||||
|
|
||||||
mod decoder;
|
mod decoder;
|
||||||
|
mod error;
|
||||||
|
|
||||||
|
pub use self::error::{TiffError, TiffResult};
|
||||||
|
|
||||||
|
/// An enumeration over supported color types and their bit depths
|
||||||
|
#[derive(Copy, PartialEq, Eq, Debug, Clone, Hash)]
|
||||||
|
pub enum ColorType {
|
||||||
|
/// Pixel is grayscale
|
||||||
|
Gray(u8),
|
||||||
|
|
||||||
|
/// Pixel contains R, G and B channels
|
||||||
|
RGB(u8),
|
||||||
|
|
||||||
|
/// Pixel is an index into a color palette
|
||||||
|
Palette(u8),
|
||||||
|
|
||||||
|
/// Pixel is grayscale with an alpha channel
|
||||||
|
GrayA(u8),
|
||||||
|
|
||||||
|
/// Pixel is RGB with an alpha channel
|
||||||
|
RGBA(u8),
|
||||||
|
}
|
||||||
Reference in new issue
Block a user