From cb10dd3629757b1ae547853fa06be9ae58f6bb9f Mon Sep 17 00:00:00 2001 From: Ivan Smirnov Date: Mon, 3 Jan 2022 21:12:06 +0300 Subject: [PATCH] Error types cleanup + clippy fixes --- src/decode.rs | 2 +- src/encode.rs | 2 +- src/error.rs | 63 ++++++++++++++++++++------------------------------- src/header.rs | 9 ++++---- src/types.rs | 1 + 5 files changed, 32 insertions(+), 45 deletions(-) diff --git a/src/decode.rs b/src/decode.rs index ee8bfb0..862e068 100644 --- a/src/decode.rs +++ b/src/decode.rs @@ -73,7 +73,7 @@ where _ => { cold(); if unlikely(data.len() < QOI_PADDING_SIZE) { - return Err(Error::UnexpectedBufferEnd); // TODO: remove InputDataSize err + return Err(Error::UnexpectedBufferEnd); } } } diff --git a/src/encode.rs b/src/encode.rs index f1201ec..4fbac4b 100644 --- a/src/encode.rs +++ b/src/encode.rs @@ -11,7 +11,7 @@ use crate::pixel::{Pixel, SupportedChannels}; use crate::types::{Channels, ColorSpace}; #[cfg(feature = "std")] use crate::utils::GenericWriter; -use crate::utils::{cold, unlikely, BytesMut, Writer}; +use crate::utils::{unlikely, BytesMut, Writer}; #[allow(clippy::cast_possible_truncation, unused_assignments)] fn qoi_encode_impl(mut buf: W, data: &[u8]) -> Result diff --git a/src/error.rs b/src/error.rs index b8ad4f6..50649b0 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,18 +1,21 @@ use core::convert::Infallible; use core::fmt::{self, Display}; -use crate::consts::{QOI_MAGIC, QOI_PIXELS_MAX}; +use crate::consts::QOI_MAGIC; +/// Errors that can occur during encoding or decoding. #[derive(Debug)] pub enum Error { + InvalidMagic { + magic: u32, + }, InvalidChannels { channels: u8, }, - EmptyImage { - width: u32, - height: u32, + InvalidColorSpace { + colorspace: u8, }, - ImageTooLarge { + InvalidImageDimensions { width: u32, height: u32, }, @@ -21,61 +24,45 @@ pub enum Error { width: u32, height: u32, }, - InputBufferTooSmall { - size: usize, - required: usize, - }, OutputBufferTooSmall { size: usize, required: usize, }, - InvalidMagic { - magic: u32, - }, UnexpectedBufferEnd, - InvalidColorSpace { - colorspace: u8, - }, InvalidPadding, #[cfg(feature = "std")] IoError(std::io::Error), } +/// Alias for `Result` with the error type `qoi_fast::Error`. pub type Result = core::result::Result; impl Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { + Self::InvalidMagic { magic } => { + write!(f, "invalid magic: expected {:?}, got {:?}", QOI_MAGIC, magic.to_be_bytes()) + } Self::InvalidChannels { channels } => { write!(f, "invalid number of channels: {}", channels) } - Self::EmptyImage { width, height } => { - write!(f, "image contains no pixels: {}x{}", width, height) - } - Self::ImageTooLarge { width, height } => { - let mp = QOI_PIXELS_MAX / 1_000_000; - write!(f, "image is too large: {}x{} (max={}Mp)", width, height, mp) - } - Self::InvalidImageLength { size, width, height } => { - write!(f, "invalid image length: {} for {}x{}", size, width, height) - } - Self::InputBufferTooSmall { size, required } => { - write!(f, "input buffer size too small: {} (minimum required: {})", size, required) - } - Self::OutputBufferTooSmall { size, required } => { - write!(f, "output buffer size too small: {} (minimum required: {})", size, required) - } - Self::InvalidMagic { magic } => { - write!(f, "invalid magic: expected {:?}, got {:?}", QOI_MAGIC, magic) - } - Self::UnexpectedBufferEnd => { - write!(f, "unexpected input buffer end while decoding") - } Self::InvalidColorSpace { colorspace } => { write!(f, "invalid color space: {} (expected 0 or 1)", colorspace) } + Self::InvalidImageDimensions { width, height } => { + write!(f, "invalid image dimensions: {}x{}", width, height) + } + Self::InvalidImageLength { size, width, height } => { + write!(f, "invalid image length: {} bytes for {}x{}", size, width, height) + } + Self::OutputBufferTooSmall { size, required } => { + write!(f, "output buffer size too small: {} (required: {})", size, required) + } + Self::UnexpectedBufferEnd => { + write!(f, "unexpected input buffer end while decoding") + } Self::InvalidPadding => { - write!(f, "invalid padding (stream end marker)") + write!(f, "invalid padding (stream end marker mismatch)") } #[cfg(feature = "std")] Self::IoError(ref err) => { diff --git a/src/header.rs b/src/header.rs index 091b38c..2a6539d 100644 --- a/src/header.rs +++ b/src/header.rs @@ -44,10 +44,9 @@ impl Header { pub const fn try_new( width: u32, height: u32, channels: Channels, colorspace: ColorSpace, ) -> Result { - if unlikely(height == 0 || width == 0) { - return Err(Error::EmptyImage { width, height }); - } else if unlikely((width as usize).saturating_mul(height as usize) > QOI_PIXELS_MAX) { - return Err(Error::ImageTooLarge { width, height }); + let n_pixels = (width as usize).saturating_mul(height as usize); + if unlikely(n_pixels == 0 || n_pixels > QOI_PIXELS_MAX) { + return Err(Error::InvalidImageDimensions { width, height }); } Ok(Self { width, height, channels, colorspace }) } @@ -83,7 +82,7 @@ impl Header { pub(crate) fn decode(data: impl AsRef<[u8]>) -> Result { let data = data.as_ref(); if unlikely(data.len() < QOI_HEADER_SIZE) { - return Err(Error::InputBufferTooSmall { size: data.len(), required: QOI_HEADER_SIZE }); + return Err(Error::UnexpectedBufferEnd); } let v = cast_slice::<_, [u8; 4]>(&data[..12]); let magic = u32::from_be_bytes(v[0]); diff --git a/src/types.rs b/src/types.rs index 81229d4..8213cf4 100644 --- a/src/types.rs +++ b/src/types.rs @@ -16,6 +16,7 @@ pub enum ColorSpace { Linear = 1, } +#[allow(clippy::doc_markdown)] impl ColorSpace { /// Returns true if the color space is sRGB with linear alpha. pub const fn is_srgb(self) -> bool {