From ac3d9ffd2a913da2f578cc0dd908962ce23246bc Mon Sep 17 00:00:00 2001 From: Devon Sawatsky Date: Sun, 31 Dec 2023 16:13:34 -0800 Subject: rewrite the gif builder API to actually work --- gifed/src/gif_builder.rs | 82 ++++++++++++++++++------------------------------ 1 file changed, 31 insertions(+), 51 deletions(-) diff --git a/gifed/src/gif_builder.rs b/gifed/src/gif_builder.rs index b376bf7..323e63c 100644 --- a/gifed/src/gif_builder.rs +++ b/gifed/src/gif_builder.rs @@ -1,14 +1,14 @@ -use std::convert::TryFrom; - -#[cfg(feature = "colorsquash")] -use colorsquash::Squasher; - use crate::{ block::{Palette, ScreenDescriptor, Version}, writer::ImageBuilder, - Color, EncodeError, Gif, + EncodeError, Gif, }; +use colorsquash::Squasher; +use rgb::{ComponentBytes, RGB8}; + +use std::convert::TryFrom; + pub struct GifBuilder { width: u16, height: u16, @@ -51,7 +51,7 @@ impl GifBuilder { let images = frames.into_iter().map(|frame| { let Frame { interval, - image, + image_indices, palette, } = frame; @@ -59,23 +59,12 @@ impl GifBuilder { .map(|interval| interval * 10) .or(framerate.map(|fr| 100 / fr)) .unwrap_or(10); - let image_indicies = image - .into_iter() - .flat_map(|row| { - row.into_iter().map(|c| { - //if there is a palette for this frame, use that to encode the - palette - .or(global_palette) - .map(|p| p.from_color(c)) //TODO: this is wrong. don't do this - .flatten() - }) - }) - .collect::>(); - let mut ib = ImageBuilder::new(width, height).delay(delay); - if let Some(p) = palette { - ib = ib.palette(p); - } - ib.build(image_indicies)?.image.compress(None) + ImageBuilder::new(width, height) + .delay(delay) + .palette(palette) + .build(image_indices)? + .image + .compress(None) }); for compressed_image in images { @@ -96,48 +85,39 @@ impl Default for GifBuilder { height: 256, framerate: Some(15), frames: vec![], + global_palette: None, } } } pub struct Frame { - image: Vec>, //row-major - interval: Option, + ///indices into the palette + image_indices: Vec, ///in hundredths of a second - palette: Option, + interval: Option, + palette: Palette, } -impl From>> for Frame { - fn from(image: Vec>) -> Self { +impl From>> for Frame { + /// image: row-major ordering + fn from(image: Vec>) -> Self { + let flat = image.concat(); + + let squasher = Squasher::new(255u8, flat.as_slice()); + + let mut image_indices = vec![0; flat.len()]; + squasher.map_unsafe(flat.as_bytes(), &mut image_indices); + let palette = Palette::try_from(squasher.palette_bytes().as_slice()).unwrap(); Self { - image, + image_indices, interval: None, - palette: None, + palette, } } } impl Frame { - #[cfg(feature = "colorsquash")] - pub fn optimize_palette(&mut self) { - #[cfg(feature = "rgb")] - let image_bytes = self.image.clone().into_iter().flatten().collect::>(); - #[cfg(not(feature = "rgb"))] - let image_bytes = self - .image - .iter() - .flat_map(|row| row.iter().flat_map(|color| [color.r, color.g, color.b])) - .collect::>(); - #[cfg(feature = "rgb")] - let squasher = Squasher::new(255u8, image_bytes.as_slice()); - #[cfg(not(feature = "rgb"))] - let squasher = Squasher::new_raw(255u8, image_bytes.as_slice()); - let pal = Palette::try_from(squasher.palette_bytes().as_slice()).unwrap(); - self.set_palette(pal) - } - pub fn set_palette(&mut self, palette: Palette) { - self.palette = Some(palette) - } + /// pub fn set_interval(&mut self, interval_hundredths: u16) { self.interval = Some(interval_hundredths); } -- cgit 1.4.1-3-g733a5