diff options
-rw-r--r-- | gifed/examples/read.rs | 26 | ||||
-rw-r--r-- | gifed/src/block/colortable.rs | 9 | ||||
-rw-r--r-- | gifed/src/gif.rs | 68 |
3 files changed, 60 insertions, 43 deletions
diff --git a/gifed/examples/read.rs b/gifed/examples/read.rs index 3a96509..26c342a 100644 --- a/gifed/examples/read.rs +++ b/gifed/examples/read.rs @@ -1,3 +1,5 @@ +use std::fs::File; + use gifed::{ reader::{self, GifReader}, writer::ImageBuilder, @@ -6,17 +8,17 @@ use gifed::{ fn main() { let reader = GifReader::file("examples/simulation.gif").unwrap(); - let first = reader.images().next().unwrap(); - Gif::builder(first.width, first.height) - .palette(first.palette.clone()) - .image( - ImageBuilder::new(first.width, first.height) - .transparent_index(first.transparent_index) - .indicies(first.indicies), - ) - .build() - .unwrap() - .save("first.gif") - .unwrap(); + // Create the directory we're we'll dump all the PNGs + std::fs::create_dir_all("examples/read/").unwrap(); + + for (frame_number, image) in reader.images().enumerate() { + let filename = format!("examples/read/simulation_{}.png", frame_number); + let file = File::create(filename).unwrap(); + + let mut encoder = png::Encoder::new(file, image.width as u32, image.height as u32); + encoder.set_color(png::ColorType::Rgba); + let mut writer = encoder.write_header().unwrap(); + writer.write_image_data(&image.rgba().unwrap()).unwrap(); + } } diff --git a/gifed/src/block/colortable.rs b/gifed/src/block/colortable.rs index 01fe00b..b467d64 100644 --- a/gifed/src/block/colortable.rs +++ b/gifed/src/block/colortable.rs @@ -44,6 +44,15 @@ impl ColorTable { } None } + + pub fn as_bytes(&self) -> Vec<u8> { + let mut bytes = Vec::with_capacity(self.table.len() * 3); + for color in &self.table { + bytes.extend_from_slice(&[color.r, color.g, color.b]); + } + + bytes + } } impl Deref for ColorTable { diff --git a/gifed/src/gif.rs b/gifed/src/gif.rs index e8d6150..97da21e 100644 --- a/gifed/src/gif.rs +++ b/gifed/src/gif.rs @@ -57,56 +57,53 @@ impl Gif { pub fn images<'a>(&'a self) -> ImageIterator<'a> { ImageIterator { gif: self, - veciter: self.blocks.iter(), + block_index: 0, } } } pub struct ImageIterator<'a> { gif: &'a Gif, - veciter: std::slice::Iter<'a, Block>, + block_index: usize, } impl<'a> Iterator for ImageIterator<'a> { type Item = Image<'a>; fn next(&mut self) -> Option<Self::Item> { - let mut graphic_control = None; + let starting_block = self.block_index; let img = loop { - match self.veciter.next() { + match self.gif.blocks.get(self.block_index) { Some(block) => match block { - Block::IndexedImage(img) => break img, - Block::GraphicControlExtension(gce) => { - graphic_control = Some(gce.clone()); + Block::IndexedImage(img) => { + // Step over this image so we don't hit it next time + self.block_index += 1; + + break img; } _ => (), }, None => return None, } + + self.block_index += 1; }; - if img.image_descriptor.color_table_present() { - Some(Image { - width: img.image_descriptor.width, - height: img.image_descriptor.height, - left_offset: img.image_descriptor.left, - top_offset: img.image_descriptor.top, - palette: &img.local_color_table.as_ref().unwrap(), - indicies: &img.indicies, - graphic_control, - }) - } else { - Some(Image { - width: img.image_descriptor.width, - height: img.image_descriptor.height, - left_offset: img.image_descriptor.left, - top_offset: img.image_descriptor.top, - palette: self.gif.global_color_table.as_ref().unwrap(), - indicies: &img.indicies, - graphic_control, - }) - } + let palette = img + .local_color_table + .as_ref() + .unwrap_or(self.gif.global_color_table.as_ref().unwrap()); + + Some(Image { + width: img.image_descriptor.width, + height: img.image_descriptor.height, + left_offset: img.image_descriptor.left, + top_offset: img.image_descriptor.top, + palette, + indicies: &img.indicies, + blocks: &self.gif.blocks[starting_block..self.block_index], + }) } } @@ -117,7 +114,7 @@ pub struct Image<'a> { pub top_offset: u16, pub palette: &'a ColorTable, pub indicies: &'a [u8], - pub graphic_control: Option<GraphicControl>, + pub blocks: &'a [Block], } impl<'a> Image<'a> { @@ -173,9 +170,18 @@ impl<'a> Image<'a> { Some(rgb) } + pub fn graphic_control(&self) -> Option<&GraphicControl> { + for block in self.blocks { + if let Block::GraphicControlExtension(gce) = block { + return Some(gce); + } + } + + None + } + pub fn trans_index(&self) -> Option<u8> { - self.graphic_control - .as_ref() + self.graphic_control() .map(|gce| gce.transparent_index()) .flatten() } |