Skip to main content

figif_core/traits/
encoder.rs

1//! GIF encoder trait for writing GIF files.
2
3use crate::error::Result;
4use crate::types::{EncodableFrame, EncodeConfig};
5use std::io::Write;
6use std::path::Path;
7
8/// Trait for encoding frames into GIF format.
9///
10/// Implementations can provide different encoding strategies:
11/// - Standard lossless GIF encoding
12/// - Lossy encoding for smaller file sizes
13/// - High-quality encoding with dithering
14///
15/// # Example
16///
17/// ```ignore
18/// use figif_core::traits::GifEncoder;
19/// use figif_core::encoders::StandardEncoder;
20///
21/// let encoder = StandardEncoder::new();
22/// let bytes = encoder.encode(&frames, &EncodeConfig::default())?;
23/// ```
24pub trait GifEncoder: Send + Sync {
25    /// Encode frames to a byte vector.
26    fn encode(&self, frames: &[EncodableFrame], config: &EncodeConfig) -> Result<Vec<u8>>;
27
28    /// Encode frames to a file.
29    fn encode_to_file(
30        &self,
31        frames: &[EncodableFrame],
32        path: impl AsRef<Path>,
33        config: &EncodeConfig,
34    ) -> Result<()>;
35
36    /// Encode frames to any writer.
37    fn encode_to_writer<W: Write>(
38        &self,
39        frames: &[EncodableFrame],
40        writer: W,
41        config: &EncodeConfig,
42    ) -> Result<()>;
43
44    /// Whether this encoder supports lossy compression.
45    fn supports_lossy(&self) -> bool;
46
47    /// Get the name of this encoder for logging/debugging.
48    fn name(&self) -> &'static str;
49}
50
51/// Extension trait for encoder utilities.
52pub trait GifEncoderExt: GifEncoder {
53    /// Encode with default configuration.
54    fn encode_default(&self, frames: &[EncodableFrame]) -> Result<Vec<u8>> {
55        self.encode(frames, &EncodeConfig::default())
56    }
57
58    /// Check if this encoder can handle the given configuration.
59    fn can_encode(&self, config: &EncodeConfig) -> bool {
60        // If lossy quality is requested, encoder must support it
61        if config.lossy_quality.is_some() && !self.supports_lossy() {
62            return false;
63        }
64        true
65    }
66}
67
68// Blanket implementation
69impl<T: GifEncoder> GifEncoderExt for T {}