diff options
author | Genny <gen@nyble.dev> | 2021-10-12 00:48:58 -0500 |
---|---|---|
committer | Genny <gen@nyble.dev> | 2021-10-12 00:48:58 -0500 |
commit | 41c60e38620ac68e32bcb977723e232ba12ecf4a (patch) | |
tree | 8f8bb40d535d7388a947f4b89b1d2ece6cbaba05 | |
parent | 757eab88d67a425728b87286c763387f52367196 (diff) | |
download | gifed-41c60e38620ac68e32bcb977723e232ba12ecf4a.tar.gz gifed-41c60e38620ac68e32bcb977723e232ba12ecf4a.zip |
Actually implement image iterator
I forgot to implement next, oops!
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | examples/read.rs | 22 | ||||
-rw-r--r-- | src/block/extension/graphiccontrol.rs | 4 | ||||
-rw-r--r-- | src/gif.rs | 69 |
4 files changed, 90 insertions, 6 deletions
diff --git a/.gitignore b/.gitignore index 02f12fc..e3b0c5d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/.vscode /target Cargo.lock *.gif diff --git a/examples/read.rs b/examples/read.rs new file mode 100644 index 0000000..3c40bfe --- /dev/null +++ b/examples/read.rs @@ -0,0 +1,22 @@ +use gifed::{ + reader::{self, GifReader}, + writer::ImageBuilder, + Gif, +}; + +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(); +} diff --git a/src/block/extension/graphiccontrol.rs b/src/block/extension/graphiccontrol.rs index 6bbe4ea..b595554 100644 --- a/src/block/extension/graphiccontrol.rs +++ b/src/block/extension/graphiccontrol.rs @@ -75,7 +75,9 @@ impl GraphicControl { &mut self.delay_time } - //TODO: Transparency index setter + pub fn is_transparent(&self) -> bool { + self.packed & 0b000_000_0_1 > 0 + } } impl From<[u8; 4]> for GraphicControl { diff --git a/src/gif.rs b/src/gif.rs index da7a1d9..de84764 100644 --- a/src/gif.rs +++ b/src/gif.rs @@ -62,19 +62,62 @@ impl Gif { } pub fn images<'a>(&'a self) -> ImageIterator<'a> { - ImageIterator { inner: self } + ImageIterator { + gif: self, + veciter: self.blocks.iter(), + } } } pub struct ImageIterator<'a> { - inner: &'a Gif, + gif: &'a Gif, + veciter: std::slice::Iter<'a, Block>, } impl<'a> Iterator for ImageIterator<'a> { type Item = Image<'a>; fn next(&mut self) -> Option<Self::Item> { - todo!() + let mut transparent = None; + + let img = loop { + match self.veciter.next() { + Some(block) => match block { + Block::IndexedImage(img) => break img, + Block::Extension(Extension::GraphicControl(gce)) => { + if gce.is_transparent() { + transparent = Some(gce.transparency_index()); + } else { + transparent = None; + } + } + _ => (), + }, + None => return None, + } + }; + + 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(), + transparent_index: transparent, + indicies: &img.indicies, + }) + } 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(), + transparent_index: transparent, + indicies: &img.indicies, + }) + } } } @@ -89,13 +132,29 @@ pub struct Image<'a> { } impl<'a> Image<'a> { - pub fn dimesnions(&self) -> (u16, u16) { - (self.width, self.height) + pub fn width(&self) -> u16 { + self.width + } + + pub fn height(&self) -> u16 { + self.height } pub fn position(&self) -> (u16, u16) { (self.left_offset, self.top_offset) } + + pub fn palette(&self) -> &ColorTable { + self.palette + } + + pub fn transparent_index(&self) -> Option<u8> { + self.transparent_index + } + + pub fn indicies(&self) -> &[u8] { + self.indicies + } } #[cfg(test)] |