diff options
author | gennyble <gen@nyble.dev> | 2024-12-07 03:00:54 -0600 |
---|---|---|
committer | gennyble <gen@nyble.dev> | 2024-12-07 03:00:54 -0600 |
commit | 38cce8b8d0609d4bbe0e07b7b79b5ecdc5bd6831 (patch) | |
tree | 912c244296fe9352a8aab181a9b5347eb578cefa | |
parent | 7a3a4b5f86b17015e174737fde6c4867682b17f8 (diff) | |
download | gifed-38cce8b8d0609d4bbe0e07b7b79b5ecdc5bd6831.tar.gz gifed-38cce8b8d0609d4bbe0e07b7b79b5ecdc5bd6831.zip |
It forms a single-image gif
-rw-r--r-- | gifed/src/gif.rs | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/gifed/src/gif.rs b/gifed/src/gif.rs index 06cf0b8..06e03a8 100644 --- a/gifed/src/gif.rs +++ b/gifed/src/gif.rs @@ -6,7 +6,8 @@ use crate::{ extension::{DisposalMethod, GraphicControl}, Block, CompressedImage, IndexedImage, Palette, ScreenDescriptor, Version, }, - writer::EncodeBlock, + writer::{EncodeBlock, ImageBuilder}, + Color, EncodeError, }; #[derive(Clone, Debug)] @@ -30,6 +31,42 @@ impl Gif { } } + /// Create a new GIF with a single frame. + /// + /// `data` should be a buffer of RGB data with a length of width * height * 3. + /// + /// ## Errors + /// [EncodeError::TooManyColors] if the number of unique colors in the RGB + /// image are greater than 256. + pub fn from_rgb(width: u16, height: u16, mut data: Vec<u8>) -> Result<Self, EncodeError> { + let mut pal = Palette::new(); + for idx in 0..data.len() / 3 { + let raw = &data[idx * 3..idx * 3 + 3]; + let clr = Color::new(raw[0], raw[1], raw[2]); + + match pal.from_color(clr) { + Some(clr_idx) => data[idx] = clr_idx, + None => { + if pal.len() == 256 { + // Error if we're already at max size + return Err(EncodeError::TooManyColors); + } else { + // Set as the next index, then fill that index in the palette + data[idx] = pal.len() as u8; + pal.push(clr); + } + } + } + } + data.resize(width as usize * height as usize, 0); + + let mut gif = Gif::new(width, height); + let img = ImageBuilder::new(width, height).palette(pal).build(data)?; + gif.push(img); + + Ok(gif) + } + pub fn set_width(&mut self, width: u16) { self.descriptor.width = width; } @@ -246,7 +283,7 @@ impl<'a> Image<'a> { } /// Clones the CompressedImage and decompresses it. - pub fn decompess(&self) -> IndexedImage { + pub fn decompress(&self) -> IndexedImage { //FIXME: remove unwrap self.compressed.clone().decompress().unwrap() } |