Switch to quick_error and cleaner error messages (#269)

This commit is contained in:
Jonathan Behrens authored and GitHub committed 2025-06-09 19:10:12 -07:00
1 parent f44da4a00d
commit b5d8ee5f86
3 files changed
+170 -371

No files matched your search

+1
View File
@@ -22,6 +22,7 @@ weezl = "0.1.0"
jpeg = { package = "jpeg-decoder", version = "0.3.0", default-features = false }
flate2 = "1.0.20"
zstd = { version = "0.13", optional = true }
quick-error = "2.0.1"
[dev-dependencies]
criterion = "0.3.1"
+19 -49
View File
@@ -42,15 +42,13 @@ impl Value {
pub fn into_u8(self) -> TiffResult<u8> {
match self {
Byte(val) => Ok(val),
val => Err(TiffError::FormatError(TiffFormatError::ByteExpected(val))),
_ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)),
}
}
pub fn into_i8(self) -> TiffResult<i8> {
match self {
SignedByte(val) => Ok(val),
val => Err(TiffError::FormatError(TiffFormatError::SignedByteExpected(
val,
))),
_ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)),
}
}
@@ -60,7 +58,7 @@ impl Value {
Short(val) => Ok(val),
Unsigned(val) => Ok(u16::try_from(val)?),
UnsignedBig(val) => Ok(u16::try_from(val)?),
val => Err(TiffError::FormatError(TiffFormatError::ShortExpected(val))),
_ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)),
}
}
@@ -70,9 +68,7 @@ impl Value {
SignedShort(val) => Ok(val),
Signed(val) => Ok(i16::try_from(val)?),
SignedBig(val) => Ok(i16::try_from(val)?),
val => Err(TiffError::FormatError(
TiffFormatError::SignedShortExpected(val),
)),
_ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)),
}
}
@@ -84,9 +80,7 @@ impl Value {
UnsignedBig(val) => Ok(u32::try_from(val)?),
Ifd(val) => Ok(val),
IfdBig(val) => Ok(u32::try_from(val)?),
val => Err(TiffError::FormatError(
TiffFormatError::UnsignedIntegerExpected(val),
)),
_ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)),
}
}
@@ -96,9 +90,7 @@ impl Value {
SignedShort(val) => Ok(val.into()),
Signed(val) => Ok(val),
SignedBig(val) => Ok(i32::try_from(val)?),
val => Err(TiffError::FormatError(
TiffFormatError::SignedIntegerExpected(val),
)),
_ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)),
}
}
@@ -110,9 +102,7 @@ impl Value {
UnsignedBig(val) => Ok(val),
Ifd(val) => Ok(val.into()),
IfdBig(val) => Ok(val),
val => Err(TiffError::FormatError(
TiffFormatError::UnsignedIntegerExpected(val),
)),
_ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)),
}
}
@@ -122,36 +112,28 @@ impl Value {
SignedShort(val) => Ok(val.into()),
Signed(val) => Ok(val.into()),
SignedBig(val) => Ok(val),
val => Err(TiffError::FormatError(
TiffFormatError::SignedIntegerExpected(val),
)),
_ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)),
}
}
pub fn into_f32(self) -> TiffResult<f32> {
match self {
Float(val) => Ok(val),
val => Err(TiffError::FormatError(
TiffFormatError::SignedIntegerExpected(val),
)),
_ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)),
}
}
pub fn into_f64(self) -> TiffResult<f64> {
match self {
Double(val) => Ok(val),
val => Err(TiffError::FormatError(
TiffFormatError::SignedIntegerExpected(val),
)),
_ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)),
}
}
pub fn into_string(self) -> TiffResult<String> {
match self {
Ascii(val) => Ok(val),
val => Err(TiffError::FormatError(
TiffFormatError::SignedIntegerExpected(val),
)),
_ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)),
}
}
@@ -175,9 +157,7 @@ impl Value {
Ifd(val) => Ok(vec![val]),
IfdBig(val) => Ok(vec![u32::try_from(val)?]),
Ascii(val) => Ok(val.chars().map(u32::from).collect()),
val => Err(TiffError::FormatError(
TiffFormatError::UnsignedIntegerExpected(val),
)),
_ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)),
}
}
@@ -192,7 +172,7 @@ impl Value {
}
Byte(val) => Ok(vec![val]),
val => Err(TiffError::FormatError(TiffFormatError::ByteExpected(val))),
_ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)),
}
}
@@ -207,7 +187,7 @@ impl Value {
}
Byte(val) => Ok(vec![val.into()]),
Short(val) => Ok(vec![val]),
val => Err(TiffError::FormatError(TiffFormatError::ShortExpected(val))),
_ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)),
}
}
@@ -238,9 +218,7 @@ impl Value {
SRationalBig(numerator, denominator) => {
Ok(vec![i32::try_from(numerator)?, i32::try_from(denominator)?])
}
val => Err(TiffError::FormatError(
TiffFormatError::SignedIntegerExpected(val),
)),
_ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)),
}
}
@@ -254,9 +232,7 @@ impl Value {
Ok(new_vec)
}
Float(val) => Ok(vec![val]),
val => Err(TiffError::FormatError(
TiffFormatError::UnsignedIntegerExpected(val),
)),
_ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)),
}
}
@@ -270,9 +246,7 @@ impl Value {
Ok(new_vec)
}
Double(val) => Ok(vec![val]),
val => Err(TiffError::FormatError(
TiffFormatError::UnsignedIntegerExpected(val),
)),
_ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)),
}
}
@@ -294,9 +268,7 @@ impl Value {
Ifd(val) => Ok(vec![val.into()]),
IfdBig(val) => Ok(vec![val]),
Ascii(val) => Ok(val.chars().map(u32::from).map(u64::from).collect()),
val => Err(TiffError::FormatError(
TiffFormatError::UnsignedIntegerExpected(val),
)),
_ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)),
}
}
@@ -325,9 +297,7 @@ impl Value {
SignedBig(val) => Ok(vec![val]),
SRational(numerator, denominator) => Ok(vec![numerator.into(), denominator.into()]),
SRationalBig(numerator, denominator) => Ok(vec![numerator, denominator]),
val => Err(TiffError::FormatError(
TiffFormatError::SignedIntegerExpected(val),
)),
_ => Err(TiffError::FormatError(TiffFormatError::InvalidTypeForTag)),
}
}
}
+150 -322
View File
@@ -1,14 +1,11 @@
use std::error::Error;
use std::fmt;
use std::fmt::Display;
use std::io;
use std::str;
use std::string;
use std::sync::Arc;
use jpeg::UnsupportedFeature;
use quick_error::quick_error;
use crate::decoder::{ifd::Value, ChunkType};
use crate::decoder::ChunkType;
use crate::tags::{
CompressionMethod, PhotometricInterpretation, PlanarConfiguration, SampleFormat, Tag,
};
@@ -16,302 +13,186 @@ use crate::ColorType;
use crate::weezl::LzwError;
/// Tiff error kinds.
#[derive(Debug)]
pub enum TiffError {
quick_error! {
/// Tiff error kinds.
#[derive(Debug)]
pub enum TiffError {
/// The Image is not formatted properly.
FormatError(TiffFormatError),
FormatError(err: TiffFormatError) {
display("format error: {err}")
from()
source(err)
}
/// The Decoder does not support features required by the image.
UnsupportedError(TiffUnsupportedError),
UnsupportedError(err: TiffUnsupportedError) {
display("unsupported error: {err}")
from()
source(err)
}
/// An I/O Error occurred while decoding the image.
IoError(io::Error),
IoError(err: io::Error) {
display("{err}")
from()
source(err)
}
/// The Limits of the Decoder is exceeded.
LimitsExceeded,
/// An integer conversion to or from a platform size failed, either due to
/// limits of the platform size or limits of the format.
IntSizeError,
LimitsExceeded {
display("decoder limits exceeded")
}
/// An integer conversion to or from a platform size failed.
IntSizeError {
display("platform or format size limits exceeded")
}
/// The image does not support the requested operation
UsageError(UsageError),
}
/// The image is not formatted properly.
///
/// This indicates that the encoder producing the image might behave incorrectly or that the input
/// file has been corrupted.
///
/// 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)]
#[non_exhaustive]
pub enum TiffFormatError {
TiffSignatureNotFound,
TiffSignatureInvalid,
ImageFileDirectoryNotFound,
InconsistentSizesEncountered,
UnexpectedCompressedData {
actual_bytes: usize,
required_bytes: usize,
},
InconsistentStripSamples {
actual_samples: usize,
required_samples: usize,
},
InvalidDimensions(u32, u32),
InvalidTag,
InvalidTagValueType(Tag),
RequiredTagNotFound(Tag),
UnknownPredictor(u16),
UnknownPlanarConfiguration(u16),
ByteExpected(Value),
SignedByteExpected(Value),
ShortExpected(Value),
SignedShortExpected(Value),
UnsignedIntegerExpected(Value),
SignedIntegerExpected(Value),
Format(String),
RequiredTagEmpty(Tag),
StripTileTagConflict,
CycleInOffsets,
JpegDecoder(JpegDecoderError),
SamplesPerPixelIsZero,
}
impl fmt::Display for TiffFormatError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
use self::TiffFormatError::*;
match *self {
TiffSignatureNotFound => write!(fmt, "TIFF signature not found."),
TiffSignatureInvalid => write!(fmt, "TIFF signature invalid."),
ImageFileDirectoryNotFound => write!(fmt, "Image file directory not found."),
InconsistentSizesEncountered => write!(fmt, "Inconsistent sizes encountered."),
UnexpectedCompressedData {
actual_bytes,
required_bytes,
} => {
write!(
fmt,
"Decompression returned different amount of bytes than expected: got {}, expected {}.",
actual_bytes, required_bytes
)
}
InconsistentStripSamples {
actual_samples,
required_samples,
} => {
write!(
fmt,
"Inconsistent elements in strip: got {}, expected {}.",
actual_samples, required_samples
)
}
InvalidDimensions(width, height) => write!(fmt, "Invalid dimensions: {}x{}.", width, height),
InvalidTag => write!(fmt, "Image contains invalid tag."),
InvalidTagValueType(ref tag) => {
write!(fmt, "Tag `{:?}` did not have the expected value type.", tag)
}
RequiredTagNotFound(ref tag) => write!(fmt, "Required tag `{:?}` not found.", tag),
UnknownPredictor(ref predictor) => {
write!(fmt, "Unknown predictor “{}” encountered", predictor)
}
UnknownPlanarConfiguration(ref planar_config) => {
write!(fmt, "Unknown planar configuration “{}” encountered", planar_config)
}
ByteExpected(ref val) => write!(fmt, "Expected byte, {:?} found.", val),
SignedByteExpected(ref val) => write!(fmt, "Expected signed byte, {:?} found.", val),
ShortExpected(ref val) => write!(fmt, "Expected short, {:?} found.", val),
SignedShortExpected(ref val) => write!(fmt, "Expected signed short, {:?} found.", val),
UnsignedIntegerExpected(ref val) => {
write!(fmt, "Expected unsigned integer, {:?} found.", val)
}
SignedIntegerExpected(ref val) => {
write!(fmt, "Expected signed integer, {:?} found.", val)
}
Format(ref val) => write!(fmt, "Invalid format: {:?}.", val),
RequiredTagEmpty(ref val) => write!(fmt, "Required tag {:?} was empty.", val),
StripTileTagConflict => write!(fmt, "File should contain either (StripByteCounts and StripOffsets) or (TileByteCounts and TileOffsets), other combination was found."),
CycleInOffsets => write!(fmt, "File contained a cycle in the list of IFDs"),
JpegDecoder(ref error) => write!(fmt, "{}", error),
SamplesPerPixelIsZero => write!(fmt, "Samples per pixel is zero"),
UsageError(err: UsageError) {
display("usage error: {err}")
from()
source(err)
}
}
}
/// The Decoder does not support features required by the image.
///
/// This only captures known failures for which the standard either does not require support or an
/// implementation has been planned but not yet completed. Some variants may become unused over
/// time and will then get deprecated before being removed.
///
/// The list of variants may grow. Matching against this exhaustively is not covered by interface
/// stability guarantees.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum TiffUnsupportedError {
FloatingPointPredictor(ColorType),
HorizontalPredictor(ColorType),
InconsistentBitsPerSample(Vec<u8>),
InterpretationWithBits(PhotometricInterpretation, Vec<u8>),
UnknownInterpretation,
UnknownCompressionMethod,
UnsupportedCompressionMethod(CompressionMethod),
UnsupportedSampleDepth(u8),
UnsupportedSampleFormat(Vec<SampleFormat>),
UnsupportedColorType(ColorType),
UnsupportedBitsPerChannel(u8),
UnsupportedPlanarConfig(Option<PlanarConfiguration>),
UnsupportedDataType,
UnsupportedInterpretation(PhotometricInterpretation),
UnsupportedJpegFeature(UnsupportedFeature),
MisalignedTileBoundaries,
}
impl fmt::Display for TiffUnsupportedError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
use self::TiffUnsupportedError::*;
match *self {
FloatingPointPredictor(color_type) => write!(
fmt,
"Floating point predictor for {:?} is unsupported.",
color_type
),
HorizontalPredictor(color_type) => write!(
fmt,
"Horizontal predictor for {:?} is unsupported.",
color_type
),
InconsistentBitsPerSample(ref bits_per_sample) => {
write!(fmt, "Inconsistent bits per sample: {:?}.", bits_per_sample)
quick_error! {
/// The image is not formatted properly.
///
/// This indicates that the encoder producing the image might behave incorrectly or that the
/// input file has been corrupted.
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub enum TiffFormatError {
TiffSignatureNotFound {
display("TIFF signature not found")
}
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)
TiffSignatureInvalid {
display("TIFF signature invalid")
}
UnsupportedSampleDepth(samples) => {
write!(fmt, "{} samples per pixel is unsupported.", samples)
ImageFileDirectoryNotFound {
display("image file directory not found")
}
UnsupportedSampleFormat(ref formats) => {
write!(fmt, "Sample format {:?} is unsupported.", formats)
InconsistentSizesEncountered {
display("inconsistent sizes encountered")
}
UnsupportedColorType(color_type) => {
write!(fmt, "Color type {:?} is unsupported", color_type)
InvalidDimensions(width: u32, height: u32) {
display("invalid dimensions: {width}x{height}")
}
UnsupportedBitsPerChannel(bits) => {
write!(fmt, "{} bits per channel not supported", bits)
InvalidTag {
display("image contains invalid tag")
}
UnsupportedPlanarConfig(config) => {
write!(fmt, "Unsupported planar configuration “{:?}”.", config)
InvalidTagValueType(tag: Tag) {
display("tag `{tag:?}` did not have the expected value type")
}
UnsupportedDataType => write!(fmt, "Unsupported data type."),
UnsupportedInterpretation(interpretation) => {
write!(
fmt,
"Unsupported photometric interpretation \"{:?}\".",
interpretation
)
RequiredTagNotFound(tag: Tag) {
display("required tag `{tag:?}` not found")
}
UnsupportedJpegFeature(ref unsupported_feature) => {
write!(fmt, "Unsupported JPEG feature {:?}", unsupported_feature)
UnknownPredictor(pred: u16) {
display("unknown predictor “{pred}” encountered")
}
MisalignedTileBoundaries => write!(fmt, "Tile rows are not aligned to byte boundaries"),
UnknownPlanarConfiguration(cfg: u16) {
display("unknown planar configuration “{cfg}”")
}
InvalidTypeForTag {
display("tag has invalid type")
}
StripTileTagConflict {
display("file should contain either (StripByteCounts and StripOffsets) or (TileByteCounts and TileOffsets), other combination was found")
}
CycleInOffsets {
display("file contained a cycle in the list of IFDs")
}
SamplesPerPixelIsZero {
display("samples per pixel is zero")
}
CompressedDataCorrupt(message: String) {
display("compressed data is corrupt: {message}")
}
}
}
/// User attempted to use the Decoder in a way that is incompatible with a specific image.
///
/// For example: attempting to read a tile from a stripped image.
#[derive(Debug)]
pub enum UsageError {
InvalidChunkType(ChunkType, ChunkType),
InvalidChunkIndex(u32),
PredictorCompressionMismatch,
PredictorIncompatible,
PredictorUnavailable,
}
impl fmt::Display for UsageError {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
use self::UsageError::*;
match *self {
InvalidChunkType(expected, actual) => {
write!(
fmt,
"Requested operation is only valid for images with chunk encoding of type: {:?}, got {:?}.",
expected, actual
)
quick_error! {
/// The Decoder does not support features required by the image.
///
/// This only captures known failures for which the standard either does not require support or an
/// implementation has been planned but not yet completed. Some variants may become unused over
/// time and will then get deprecated before being removed.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum TiffUnsupportedError {
FloatingPointPredictor(color_type: ColorType) {
display("floating point predictor for {color_type:?} is unsupported")
}
InvalidChunkIndex(index) => write!(fmt, "Image chunk index ({}) requested.", index),
PredictorCompressionMismatch => write!(
fmt,
"The requested predictor is not compatible with the requested compression"
),
PredictorIncompatible => write!(
fmt,
"The requested predictor is not compatible with the image's format"
),
PredictorUnavailable => write!(fmt, "The requested predictor is not available"),
HorizontalPredictor(color_type: ColorType) {
display("horizontal predictor for {color_type:?} is unsupported")
}
InconsistentBitsPerSample(bits_per_sample: Vec<u8>) {
display("inconsistent bits per sample: {bits_per_sample:?}")
}
InterpretationWithBits(interpretation: PhotometricInterpretation, bits_per_sample: Vec<u8>) {
display("Photometric interpretation {interpretation:?} with bits per sample {bits_per_sample:?} is unsupported")
}
UnknownInterpretation {
display("unknown photometric interpretation")
}
UnknownCompressionMethod {
display("unknown compression method")
}
UnsupportedCompressionMethod(method: CompressionMethod) {
display("compression method {method:?} is unsupported")
}
UnsupportedSampleDepth(depth: u8) {
display("{depth} samples per pixel is unsupported")
}
UnsupportedSampleFormat(sample_format: Vec<SampleFormat>) {
display("sample format {sample_format:?} is unsupported")
}
UnsupportedColorType(color_type: ColorType) {
display("color type {color_type:?} is unsupported")
}
UnsupportedBitsPerChannel(bits_per_channel: u8) {
display("{bits_per_channel} bits per channel not supported")
}
UnsupportedPlanarConfig(planar: Option<PlanarConfiguration>) {
display("unsupported planar configuration “{planar:?}”")
}
UnsupportedDataType {
display("unsupported data type.")
}
UnsupportedInterpretation(interpretation: PhotometricInterpretation) {
display("unsupported photometric interpretation \"{interpretation:?}\"")
}
UnsupportedJpegFeature(feature: UnsupportedFeature) {
display("unsupported JPEG feature {feature:?}")
}
MisalignedTileBoundaries {
display("tile rows are not aligned to byte boundaries")
}
}
}
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),
TiffError::LimitsExceeded => write!(fmt, "The Decoder limits are exceeded"),
TiffError::IntSizeError => write!(fmt, "Platform or format size limits exceeded"),
TiffError::UsageError(ref e) => write!(fmt, "Usage error: {}", e),
quick_error! {
/// User attempted to use the Decoder in a way that is incompatible with a specific image.
///
/// For example: attempting to read a tile from a stripped image.
#[derive(Debug)]
#[non_exhaustive]
pub enum UsageError {
InvalidChunkType(expected: ChunkType, actual: ChunkType) {
display("requested operation is only valid for images with chunk encoding of type {expected:?} but got {actual:?}")
}
InvalidChunkIndex(index: u32) {
display("invalid chunk index ({index}) requested")
}
}
impl Error for TiffError {
fn description(&self) -> &str {
match *self {
TiffError::FormatError(..) => "Format error",
TiffError::UnsupportedError(..) => "Unsupported error",
TiffError::IoError(..) => "IO error",
TiffError::LimitsExceeded => "Decoder limits exceeded",
TiffError::IntSizeError => "Platform or format size limits exceeded",
TiffError::UsageError(..) => "Invalid usage",
PredictorCompressionMismatch {
display("requested predictor is not compatible with the requested compression")
}
PredictorIncompatible {
display("the requested predictor is not compatible with the image's format")
}
fn cause(&self) -> Option<&dyn Error> {
match *self {
TiffError::IoError(ref e) => Some(e),
_ => None,
PredictorUnavailable {
display("the requested predictor is not available")
}
}
}
impl From<io::Error> for TiffError {
fn from(err: io::Error) -> TiffError {
TiffError::IoError(err)
}
}
impl From<str::Utf8Error> for TiffError {
fn from(_err: str::Utf8Error) -> TiffError {
TiffError::FormatError(TiffFormatError::InvalidTag)
@@ -324,24 +205,6 @@ impl From<string::FromUtf8Error> for TiffError {
}
}
impl From<TiffFormatError> for TiffError {
fn from(err: TiffFormatError) -> TiffError {
TiffError::FormatError(err)
}
}
impl From<TiffUnsupportedError> for TiffError {
fn from(err: TiffUnsupportedError) -> TiffError {
TiffError::UnsupportedError(err)
}
}
impl From<UsageError> for TiffError {
fn from(err: UsageError) -> TiffError {
TiffError::UsageError(err)
}
}
impl From<std::num::TryFromIntError> for TiffError {
fn from(_err: std::num::TryFromIntError) -> TiffError {
TiffError::IntSizeError
@@ -350,48 +213,13 @@ impl From<std::num::TryFromIntError> for TiffError {
impl From<LzwError> for TiffError {
fn from(err: LzwError) -> TiffError {
match err {
LzwError::InvalidCode => TiffError::FormatError(TiffFormatError::Format(String::from(
"LZW compressed data corrupted",
))),
}
}
}
#[derive(Debug, Clone)]
pub struct JpegDecoderError {
inner: Arc<jpeg::Error>,
}
impl JpegDecoderError {
fn new(error: jpeg::Error) -> Self {
Self {
inner: Arc::new(error),
}
}
}
impl PartialEq for JpegDecoderError {
fn eq(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.inner, &other.inner)
}
}
impl Display for JpegDecoderError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.inner.fmt(f)
}
}
impl From<JpegDecoderError> for TiffError {
fn from(error: JpegDecoderError) -> Self {
TiffError::FormatError(TiffFormatError::JpegDecoder(error))
TiffError::FormatError(TiffFormatError::CompressedDataCorrupt(err.to_string()))
}
}
impl From<jpeg::Error> for TiffError {
fn from(error: jpeg::Error) -> Self {
JpegDecoderError::new(error).into()
fn from(err: jpeg::Error) -> Self {
TiffError::FormatError(TiffFormatError::CompressedDataCorrupt(err.to_string()))
}
}