Skip to content

Commit

Permalink
Switch to quick-error (#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
fintelia authored Apr 21, 2024
1 parent 7a80ea6 commit 19e478f
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 127 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ include = ["/src", "LICENSE-APACHE", "LICENSE-MIT", "README.md"]

[dependencies]
byteorder-lite = "0.1.0"
thiserror = "1.0.47"
quick-error = "2.0.1"

[dev-dependencies]
paste = "1.0.14"
Expand Down
259 changes: 145 additions & 114 deletions src/decoder.rs
Original file line number Diff line number Diff line change
@@ -1,132 +1,163 @@
use byteorder_lite::{LittleEndian, ReadBytesExt};
use std::collections::HashMap;
use quick_error::quick_error;

use std::collections::HashMap;
use std::io::{self, BufReader, Cursor, Read, Seek};

use std::num::NonZeroU16;
use std::ops::Range;
use thiserror::Error;

use crate::extended::{self, get_alpha_predictor, read_alpha_chunk, WebPExtendedInfo};

use super::lossless::LosslessDecoder;
use super::vp8::Vp8Decoder;

/// Errors that can occur when attempting to decode a WebP image
#[derive(Error, Debug)]
#[non_exhaustive]
pub enum DecodingError {
/// An IO error occurred while reading the file
#[error("IO Error: {0}")]
IoError(#[from] io::Error),
quick_error! {
/// Errors that can occur when attempting to decode a WebP image
#[derive(Debug)]
#[non_exhaustive]
pub enum DecodingError {
/// An IO error occurred while reading the file
IoError(err: io::Error) {
from()
display("IO Error: {}", err)
source(err)
}

/// RIFF's "RIFF" signature not found or invalid
RiffSignatureInvalid(err: [u8; 4]) {
display("Invalid RIFF signature: {err:x?}")
}

/// WebP's "WEBP" signature not found or invalid
WebpSignatureInvalid(err: [u8; 4]) {
display("Invalid WebP signature: {err:x?}")
}

/// An expected chunk was missing
ChunkMissing {
display("An expected chunk was missing")
}

/// Chunk Header was incorrect or invalid in its usage
ChunkHeaderInvalid(err: [u8; 4]) {
display("Invalid Chunk header: {err:x?}")
}

/// Some bits were invalid
ReservedBitSet {
display("Reserved bits set")
}

/// Invalid compression method
InvalidCompressionMethod {
display("Invalid compression method")
}

/// Alpha chunk doesn't match the frame's size
AlphaChunkSizeMismatch {
display("Alpha chunk size mismatch")
}

/// Image is too large, either for the platform's pointer size or generally
ImageTooLarge {
display("Image too large")
}

/// Frame would go out of the canvas
FrameOutsideImage {
display("Frame outside image")
}

/// RIFF's "RIFF" signature not found or invalid
#[error("Invalid RIFF signature: {0:x?}")]
RiffSignatureInvalid([u8; 4]),
/// Signature of 0x2f not found
LosslessSignatureInvalid(err: u8) {
display("Invalid lossless signature: {err:x?}")
}

/// WebP's "WEBP" signature not found or invalid
#[error("Invalid WebP signature: {0:x?}")]
WebpSignatureInvalid([u8; 4]),

/// An expected chunk was missing
#[error("An expected chunk was missing")]
ChunkMissing,

/// Chunk Header was incorrect or invalid in its usage
#[error("Invalid Chunk header: {0:?}")]
ChunkHeaderInvalid([u8; 4]),

/// Some bits were invalid
#[error("Reserved bits set")]
ReservedBitSet,

/// Invalid compression method
#[error("Invalid compression method")]
InvalidCompressionMethod,

/// Alpha chunk doesn't match the frame's size
#[error("Alpha chunk size mismatch")]
AlphaChunkSizeMismatch,

/// Image is too large, either for the platform's pointer size or generally
#[error("Image too large")]
ImageTooLarge,

/// Frame would go out of the canvas
#[error("Frame outside image")]
FrameOutsideImage,

/// Signature of 0x2f not found
#[error("Invalid lossless signature: {0:x?}")]
LosslessSignatureInvalid(u8),

/// Version Number was not zero
#[error("Invalid lossless version number: {0}")]
VersionNumberInvalid(u8),

/// Invalid color cache bits
#[error("Invalid color cache bits: {0}")]
InvalidColorCacheBits(u8),

/// An invalid Huffman code was encountered
#[error("Invalid Huffman code")]
HuffmanError,

/// The bitstream was somehow corrupt
#[error("Corrupt bitstream")]
BitStreamError,

/// The transforms specified were invalid
#[error("Invalid transform")]
TransformError,

/// VP8's `[0x9D, 0x01, 0x2A]` magic not found or invalid
#[error("Invalid VP8 magic: {0:x?}")]
Vp8MagicInvalid([u8; 3]),

/// VP8 Decoder initialisation wasn't provided with enough data
#[error("Not enough VP8 init data")]
NotEnoughInitData,

/// At time of writing, only the YUV colour-space encoded as `0` is specified
#[error("Invalid VP8 color space: {0}")]
ColorSpaceInvalid(u8),

/// LUMA prediction mode was not recognised
#[error("Invalid VP8 luma prediction mode: {0}")]
LumaPredictionModeInvalid(i8),

/// Intra-prediction mode was not recognised
#[error("Invalid VP8 intra prediction mode: {0}")]
IntraPredictionModeInvalid(i8),

/// Chroma prediction mode was not recognised
#[error("Invalid VP8 chroma prediction mode: {0}")]
ChromaPredictionModeInvalid(i8),

/// Inconsistent image sizes
#[error("Inconsistent image sizes")]
InconsistentImageSizes,

/// The file may be valid, but this crate doesn't support decoding it.
#[error("Unsupported feature: {0}")]
UnsupportedFeature(String),

/// Invalid function call or parameter
#[error("Invalid parameter: {0}")]
InvalidParameter(String),

/// Memory limit exceeded
#[error("Memory limit exceeded")]
MemoryLimitExceeded,
/// Version Number was not zero
VersionNumberInvalid(err: u8) {
display("Invalid lossless version number: {err}")
}

/// Invalid chunk size
#[error("Invalid chunk size")]
InvalidChunkSize,
/// Invalid color cache bits
InvalidColorCacheBits(err: u8) {
display("Invalid color cache bits: {err}")
}

/// No more frames in image
#[error("No more frames")]
NoMoreFrames,
/// An invalid Huffman code was encountered
HuffmanError {
display("Invalid Huffman code")
}

/// The bitstream was somehow corrupt
BitStreamError {
display("Corrupt bitstream")
}

/// The transforms specified were invalid
TransformError {
display("Invalid transform")
}

/// VP8's `[0x9D, 0x01, 0x2A]` magic not found or invalid
Vp8MagicInvalid(err: [u8; 3]) {
display("Invalid VP8 magic: {err:x?}")
}

/// VP8 Decoder initialisation wasn't provided with enough data
NotEnoughInitData {
display("Not enough VP8 init data")
}

/// At time of writing, only the YUV colour-space encoded as `0` is specified
ColorSpaceInvalid(err: u8) {
display("Invalid VP8 color space: {err}")
}

/// LUMA prediction mode was not recognised
LumaPredictionModeInvalid(err: i8) {
display("Invalid VP8 luma prediction mode: {err}")
}

/// Intra-prediction mode was not recognised
IntraPredictionModeInvalid(err: i8) {
display("Invalid VP8 intra prediction mode: {err}")
}

/// Chroma prediction mode was not recognised
ChromaPredictionModeInvalid(err: i8) {
display("Invalid VP8 chroma prediction mode: {err}")
}

/// Inconsistent image sizes
InconsistentImageSizes {
display("Inconsistent image sizes")
}

/// The file may be valid, but this crate doesn't support decoding it.
UnsupportedFeature(err: String) {
display("Unsupported feature: {err}")
}

/// Invalid function call or parameter
InvalidParameter(err: String) {
display("Invalid parameter: {err}")
}

/// Memory limit exceeded
MemoryLimitExceeded {
display("Memory limit exceeded")
}

/// Invalid chunk size
InvalidChunkSize {
display("Invalid chunk size")
}

/// No more frames in image
NoMoreFrames {
display("No more frames")
}
}
}

/// All possible RIFF chunks in a WebP image file
Expand Down
30 changes: 18 additions & 12 deletions src/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::collections::BinaryHeap;
use std::io::{self, Write};
use std::slice::ChunksExact;

use thiserror::Error;
use quick_error::quick_error;

/// Color type of the image.
///
Expand All @@ -22,17 +22,23 @@ pub enum ColorType {
Rgba8,
}

/// Error that can occur during encoding.
#[derive(Error, Debug)]
#[non_exhaustive]
pub enum EncodingError {
/// An IO error occurred.
#[error("IO error: {0}")]
IoError(#[from] io::Error),

/// The image dimensions are not allowed by the WebP format.
#[error("Invalid dimensions")]
InvalidDimensions,
quick_error! {
/// Error that can occur during encoding.
#[derive(Debug)]
#[non_exhaustive]
pub enum EncodingError {
/// An IO error occurred.
IoError(err: io::Error) {
from()
display("IO error: {}", err)
source(err)
}

/// The image dimensions are not allowed by the WebP format.
InvalidDimensions {
display("Invalid dimensions")
}
}
}

struct BitWriter<W> {
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#![forbid(unsafe_code)]
#![deny(missing_docs)]
// Increase recursion limit for the `quick_error!` macro.
#![recursion_limit = "256"]

pub use self::decoder::{DecodingError, LoopCount, WebPDecoder};
pub use self::encoder::{ColorType, EncodingError, WebPEncoder};
Expand Down

0 comments on commit 19e478f

Please sign in to comment.