webp_animation/
lib.rs

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
135
136
137
//! # Overview
//!
//! This crate provides a high-level Rust wrapper for decoding and encoding
//! [WebP](https://en.wikipedia.org/wiki/WebP) animations.
//! Underlying WebP format processing is handled by C-based
//! [libwebp](https://developers.google.com/speed/webp/docs/container-api) library by Google,
//! which is interfaced through Rust [libwebp-sys2](https://crates.io/crates/libwebp-sys2)
//! crate
//!
//! # Usage
//! Have a look at [`Decoder`] and [`Encoder`] for use-case specific examples.

use std::fmt::{self, Display};

mod decoder;
mod encoder;
mod encoder_config;
mod frame;
mod webp_data;

pub use decoder::*;
pub use encoder::*;
pub use encoder_config::*;
pub use frame::*;
pub use webp_data::*;

pub mod prelude {
    // general
    pub use crate::ColorMode;

    // decoder
    pub use crate::{Decoder, DecoderOptions};

    // encoder
    pub use crate::{Encoder, EncoderOptions, EncodingConfig, EncodingType, LossyEncodingConfig};
}

/// Color Mode that configures the output type of [`Decoder`] [`Frame`]'s
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum ColorMode {
    /// Rgb (red, green, blue) -no alpha
    Rgb,
    /// Rgba (red, green, blue, alpha)
    Rgba,
    /// Bgra (blue, green, red, alpha)
    Bgra,
    // Bgr (blue, green, red) - no alpha
    Bgr,
}

impl ColorMode {
    /// Return the pixel bytesize for the color mode
    pub fn size(&self) -> usize {
        match self {
            Self::Rgb | Self::Bgr => 3,
            Self::Rgba | Self::Bgra => 4,
        }
    }
}

/// Error type produced by `webp_animation` code
#[derive(Debug, PartialEq)]
pub enum Error {
    /// Initializing webp options failed, internal (memory allocation?) failure
    OptionsInitFailed,

    /// Decoder init failed, input contains wrong bytes
    DecodeFailed,

    /// Decoder could not get metadata of webp stream. Corrupt data?
    DecoderGetInfoFailed,

    /// Webp stream contains too large canvas. For now, size is limited to 3840 * 2160 pixels
    /// See `MAX_CANVAS_SIZE` variable from code
    TooLargeCanvas(u32, u32, usize),

    /// Encoder create failed. Wrong options combination?
    EncoderCreateFailed,

    /// Data input buffer size did not match encoder metadata (width * height * 4)
    BufferSizeFailed(usize, usize),

    /// Raw data could not be converted into webp frame by underlying libwebp library
    PictureImportFailed,

    /// Frame could not be added to webp stream by underlying libwebp library
    EncoderAddFailed,

    /// Underlying data is in different color mode
    WrongColorMode(ColorMode, ColorMode),

    /// Timestamp must be higher value than previous frame timestamp
    TimestampMustBeHigherThanPrevious(i32, i32),

    /// Timestamp must be higher or equal to the previous frame timestamp
    TimestampMustBeEqualOrHigherThanPrevious(i32, i32),

    /// Encoder webp assembly failed
    EncoderAssmebleFailed,

    /// Supplied dimensions must be positive
    DimensionsMustbePositive,

    /// No frames have been supplied to encoder
    NoFramesAdded,

    /// Supplied zero-sized buffer where bytes where expected
    ZeroSizeBuffer,

    /// Encoder config validation failed
    InvalidEncodingConfig,
}

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Error::OptionsInitFailed => write!(f, "OptionsInitFailed: Initializing webp options failed, internal (memory allocation?) failure"),
            Error::DecodeFailed => write!(f, "DecodeFailed: Could not decode input bytes, possibly malformed data"),
            Error::DecoderGetInfoFailed => write!(f, "DecoderGetInfoFailed: Decoder could not get metadata of webp stream. Corrupt data?"),
            Error::TooLargeCanvas(width, height, max_size) => write!(f, "TooLargeCanvas: Decodable canvas is too large ({} x {} = {} pixels). For now, size is limited to 3840 * 2160 = {} pixels", width, height, width * height, max_size),
            Error::EncoderCreateFailed => write!(f, "EncoderCreateFailed: Encoder create failed. Wrong options combination?"),
            Error::BufferSizeFailed(expected, received) => write!(f, "BufferSizeFailed: Expected (width * height * 4 = {}) bytes as input buffer, got {} bytes", expected, received),
            Error::PictureImportFailed => write!(f, "PictureImportFailed: Raw data could not be converted into webp frame by underlying libwebp library"),
            Error::EncoderAddFailed => write!(f, "EncoderAddFailed: Frame could not be added to webp stream by underlying libwebp library"),
            Error::WrongColorMode(requested, expected) => write!(f, "WrongColorMode: Requested image in {:?} format but underlying is stored as {:?}", expected, requested),
            Error::TimestampMustBeHigherThanPrevious(requested, previous) => write!(f, "TimestampMustBeHigherThanPrevious: Supplied timestamp (got {}) must be higher than {}", requested, previous),
            Error::TimestampMustBeEqualOrHigherThanPrevious(requested, previous) => write!(f, "TimestampMustBeEqualOrHigherThanPrevious: Supplied timestamp (got {}) must be higher or equal to {}", requested, previous),
            Error::EncoderAssmebleFailed => write!(f, "EncoderAssmebleFailed: Encoder webp assembly failed"),
            Error::DimensionsMustbePositive => write!(f, "DimensionsMustbePositive: Supplied dimensions must be positive"),
            Error::NoFramesAdded => write!(f, "NoFramesAdded: No frames have been added yet"),
            Error::ZeroSizeBuffer => write!(f, "ZeroSizeBuffer: Buffer contains no data"),
            Error::InvalidEncodingConfig => write!(f, "InvalidEncodingConfig: encoding configuration validation failed")
        }
    }
}

impl std::error::Error for Error {}