figif_core/traits/decoder.rs
1//! GIF decoder trait for loading GIF files.
2
3use crate::error::Result;
4use crate::types::{DecodedFrame, GifMetadata};
5use std::io::Read;
6use std::path::Path;
7
8/// Trait for decoding GIF files into frames.
9///
10/// Implementations can choose different strategies:
11/// - Buffered: Load all frames into memory at once
12/// - Streaming: Decode frames lazily on-demand
13///
14/// # Example
15///
16/// ```ignore
17/// use figif_core::traits::GifDecoder;
18/// use figif_core::decoders::BufferedDecoder;
19///
20/// let decoder = BufferedDecoder::new();
21/// let frames = decoder.decode_file("animation.gif")?;
22/// ```
23pub trait GifDecoder: Send + Sync {
24 /// The type of iterator returned by decode operations.
25 type FrameIter: Iterator<Item = Result<DecodedFrame>>;
26
27 /// Decode a GIF from a file path.
28 ///
29 /// Returns an iterator over decoded frames.
30 fn decode_file(&self, path: impl AsRef<Path>) -> Result<Self::FrameIter>;
31
32 /// Decode a GIF from a byte slice.
33 ///
34 /// Returns an iterator over decoded frames.
35 fn decode_bytes(&self, data: &[u8]) -> Result<Self::FrameIter>;
36
37 /// Decode a GIF from any reader.
38 ///
39 /// Returns an iterator over decoded frames.
40 fn decode_reader<R: Read + Send>(&self, reader: R) -> Result<Self::FrameIter>;
41
42 /// Extract metadata without fully decoding all frames.
43 ///
44 /// This is useful for getting dimensions, frame count, and duration
45 /// without the overhead of decoding all pixel data.
46 fn metadata_from_bytes(&self, data: &[u8]) -> Result<GifMetadata>;
47
48 /// Extract metadata from a file.
49 fn metadata_from_file(&self, path: impl AsRef<Path>) -> Result<GifMetadata>;
50
51 /// Get the name of this decoder for logging/debugging.
52 fn name(&self) -> &'static str;
53}
54
55/// A decoder that collects all frames into a vector.
56///
57/// This is useful when you need random access to frames
58/// or when the streaming approach is not suitable.
59pub trait BufferedGifDecoder: GifDecoder {
60 /// Decode all frames into a vector.
61 fn decode_all(&self, data: &[u8]) -> Result<Vec<DecodedFrame>> {
62 self.decode_bytes(data)?.collect()
63 }
64
65 /// Decode all frames from a file into a vector.
66 fn decode_all_from_file(&self, path: impl AsRef<Path>) -> Result<Vec<DecodedFrame>> {
67 self.decode_file(path)?.collect()
68 }
69}