about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--gifed/examples/read.rs26
-rw-r--r--gifed/src/block/colortable.rs9
-rw-r--r--gifed/src/gif.rs68
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()
 	}