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 {}