1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
use ifd::{ Entry, DataType, }; use tag::AnyTag; use image::{ PhotometricInterpretation, BitsPerSample, BitsPerSampleError, ImageHeaderError, }; use std::io; use std::fmt::{ self, Display, }; use failure::{ Context, Fail, Backtrace, }; pub type DecodeResult<T> = ::std::result::Result<T, DecodeError>; #[derive(Debug, Fail)] pub enum DecodeErrorKind { #[fail(display = "IO Error: {:?}", error)] IO { error: io::Error }, #[fail(display = "Incorrect header: No Byte Order")] NoByteOrder, #[fail(display = "Incorrect header: No Version")] NoVersion, #[fail(display = "Incorrect header: No IFD address")] NoIFDAddress, #[fail(display = "No Image address")] NoImage, #[fail(display = "Can't find the tag ({:?})", tag)] CannotFindTheTag { tag: AnyTag }, #[fail(display = "Unsupported IFD Entry ({})\n reason: {}", entry, reason)] UnsupportedIFDEntry{ entry: Entry, reason: String }, #[fail(display = "Tag ({:?}) does not support data: ({:?})", tag, data)] UnsupportedMultipleData { tag: AnyTag, data: Vec<u32> }, #[fail(display = "Tag ({:?}) does not support data: ({:?})", tag, data)] UnsupportedData { tag: AnyTag, data: u32 }, #[fail(display = "Calculated from width and height: {}, sum: {}", calc, sum)] IncorrectBufferSize { calc: usize, sum: usize }, #[fail(display = "Incompatible Data ({:?}/{:?}", photometric_interpretation, bits_per_sample)] IncompatibleData { photometric_interpretation: PhotometricInterpretation, bits_per_sample: BitsPerSample }, #[fail(display = "Tag ({:?}) requires data, but you dont got any data", tag)] NoData { tag: AnyTag }, #[fail(display = "Tag ({:?}) requires only one value, but you got extra data: {:?}.", tag, data)] ExtraData { tag: AnyTag, data: Vec<u32> }, #[fail(display = "Tag ({:?}) doesn't support this datatype/count : {:?}/{}", tag, datatype, count)] NoSupportDataType { tag: AnyTag, datatype: DataType, count: usize }, } #[derive(Debug)] pub struct DecodeError { inner: Context<DecodeErrorKind>, } impl Fail for DecodeError { fn cause(&self) -> Option<&Fail> { self.inner.cause() } fn backtrace(&self) -> Option<&Backtrace> { self.inner.backtrace() } } impl Display for DecodeError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Display::fmt(&self.inner, f) } } impl DecodeError { fn new(kind: DecodeErrorKind) -> DecodeError { DecodeError { inner: Context::new(kind) } } pub fn kind(&self) -> &DecodeErrorKind { self.inner.get_context() } } impl From<io::Error> for DecodeError { fn from(err: io::Error) -> DecodeError { DecodeError::new(DecodeErrorKind::IO { error: err }) } } impl From<BitsPerSampleError> for DecodeError { fn from(err: BitsPerSampleError) -> DecodeError { let kind = DecodeErrorKind::UnsupportedMultipleData { tag: AnyTag::BitsPerSample, data: err.values().iter().map(|x| *x as u32).collect::<_>() }; DecodeError::new(kind) } } impl From<ImageHeaderError> for DecodeError { fn from(err: ImageHeaderError) -> DecodeError { let (photometric_interpretation, bits_per_sample) = match err { ImageHeaderError::IncompatibleData { photometric_interpretation, bits_per_sample } => (photometric_interpretation, bits_per_sample) }; DecodeError::new(DecodeErrorKind::IncompatibleData { photometric_interpretation, bits_per_sample }) } } impl From<DecodeErrorKind> for DecodeError { fn from(kind: DecodeErrorKind) -> DecodeError { DecodeError { inner: Context::new(kind) } } }