Skip to main content

fastpack_compress/backends/
webp.rs

1use fastpack_core::types::config::PackMode;
2
3use crate::{
4    compressor::{CompressInput, CompressOutput, Compressor},
5    error::CompressError,
6};
7
8/// WebP encoder.
9///
10/// Requires the `webp-encode` cargo feature. `PackMode::Best` produces lossless
11/// output; `Fast` and `Good` produce lossy output at the quality specified by
12/// `CompressInput::quality`.
13pub struct WebpCompressor;
14
15impl Compressor for WebpCompressor {
16    fn compress(&self, input: &CompressInput<'_>) -> Result<CompressOutput, CompressError> {
17        compress_webp(input)
18    }
19
20    fn format_id(&self) -> &'static str {
21        "webp"
22    }
23
24    fn file_extension(&self) -> &'static str {
25        "webp"
26    }
27}
28
29fn compress_webp(input: &CompressInput<'_>) -> Result<CompressOutput, CompressError> {
30    #[cfg(feature = "webp-encode")]
31    {
32        let rgba = input.image.to_rgba8();
33        let (width, height) = rgba.dimensions();
34        let encoder = webp::Encoder::from_rgba(rgba.as_raw(), width, height);
35        let output = match input.pack_mode {
36            PackMode::Best => encoder.encode_lossless(),
37            _ => encoder.encode(input.quality as f32),
38        };
39        Ok(CompressOutput {
40            data: output.to_vec(),
41        })
42    }
43    #[cfg(not(feature = "webp-encode"))]
44    {
45        let _ = input;
46        Err(CompressError::Other(
47            "webp-encode feature is not enabled; rebuild with --features webp-encode".to_string(),
48        ))
49    }
50}