about summary refs log tree commit diff
path: root/gifed/src/block
diff options
context:
space:
mode:
Diffstat (limited to 'gifed/src/block')
-rw-r--r--gifed/src/block/extension/graphiccontrol.rs8
-rw-r--r--gifed/src/block/extension/mod.rs46
-rw-r--r--gifed/src/block/mod.rs58
3 files changed, 64 insertions, 48 deletions
diff --git a/gifed/src/block/extension/graphiccontrol.rs b/gifed/src/block/extension/graphiccontrol.rs
index b595554..8b62160 100644
--- a/gifed/src/block/extension/graphiccontrol.rs
+++ b/gifed/src/block/extension/graphiccontrol.rs
@@ -22,7 +22,7 @@ impl GraphicControl {
 		};
 
 		ret.set_disposal_method(disposal_method);
-		ret.user_input(user_input_flag);
+		ret.set_user_input(user_input_flag);
 		ret.transparency(transparency_flag);
 
 		ret
@@ -51,7 +51,11 @@ impl GraphicControl {
 		self.transparency_index
 	}
 
-	pub fn user_input(&mut self, flag: bool) {
+	pub fn user_input(&self) -> bool {
+		self.packed & 0b000_000_1_0 > 0
+	}
+
+	pub fn set_user_input(&mut self, flag: bool) {
 		if flag {
 			self.packed |= 0b000_000_1_0;
 		} else {
diff --git a/gifed/src/block/extension/mod.rs b/gifed/src/block/extension/mod.rs
index fb5eb20..99ac88b 100644
--- a/gifed/src/block/extension/mod.rs
+++ b/gifed/src/block/extension/mod.rs
@@ -1,49 +1,5 @@
 mod application;
 mod graphiccontrol;
 
-pub use graphiccontrol::{DisposalMethod, GraphicControl};
-
 pub use self::application::Application;
-
-pub enum Extension {
-	GraphicControl(GraphicControl),
-	Looping(u16),
-	Comment(Vec<u8>), // Plain Text
-	Application(Application),
-}
-
-impl From<&Extension> for Box<[u8]> {
-	fn from(ext: &Extension) -> Self {
-		let mut vec = vec![];
-		vec.push(0x21); // Push the extension introducer
-
-		match ext {
-			Extension::GraphicControl(gc) => {
-				vec.push(0xF9); // Graphic control label
-				vec.push(0x04); // Block size for this extension is always 4
-				vec.push(gc.packed);
-				vec.extend_from_slice(&gc.delay_time.to_le_bytes());
-				vec.push(gc.transparency_index);
-			}
-			Extension::Looping(count) => {
-				vec.push(0xFF); // Application extension label
-				vec.push(0x0B); // 11 bytes in this block
-				vec.extend_from_slice(b"NETSCAPE2.0"); // App. ident. and "auth code"
-				vec.push(0x03); // Sub-block length
-				vec.push(0x01); // Identifies netscape looping extension
-				vec.extend_from_slice(&count.to_le_bytes());
-			}
-			Extension::Comment(_) => todo!(),
-			Extension::Application(_) => todo!(),
-		}
-
-		vec.push(0x00); // Zero-length data block indicates end of extension
-		vec.into_boxed_slice()
-	}
-}
-
-impl From<GraphicControl> for Extension {
-	fn from(gce: GraphicControl) -> Self {
-		Extension::GraphicControl(gce)
-	}
-}
+pub use graphiccontrol::{DisposalMethod, GraphicControl};
diff --git a/gifed/src/block/mod.rs b/gifed/src/block/mod.rs
index e35224b..a101600 100644
--- a/gifed/src/block/mod.rs
+++ b/gifed/src/block/mod.rs
@@ -14,12 +14,68 @@ pub use version::Version;
 
 use crate::writer::ImageBuilder;
 
+use self::extension::Application;
+use self::extension::GraphicControl;
+
 pub enum Block {
 	IndexedImage(IndexedImage),
-	Extension(extension::Extension),
+	//TODO: Extension(Extension),
+	GraphicControlExtension(GraphicControl),
+	CommentExtension(Vec<u8>),
+	//TODO: PlainTextExtension(PlainTextExtension),
+	ApplicationExtension(Application),
+	LoopingExtension(LoopCount),
 }
 
 enum WriteBlock {
 	ImageBuilder(ImageBuilder),
 	Block(Block),
 }
+
+pub enum LoopCount {
+	Forever,
+	Number(u16),
+}
+
+pub(crate) fn encode_block(mcs: u8, block: &Block) -> Box<[u8]> {
+	match block {
+		Block::IndexedImage(img) => img.as_boxed_slice(mcs),
+		Block::GraphicControlExtension(_) => encode_extension(block),
+		Block::CommentExtension(_) => encode_extension(block),
+		Block::ApplicationExtension(_) => encode_extension(block),
+		Block::LoopingExtension(_) => encode_extension(block),
+	}
+}
+
+fn encode_extension(block: &Block) -> Box<[u8]> {
+	let mut vec = vec![];
+	vec.push(0x21); // Extension Introducer
+
+	match block {
+		Block::IndexedImage(_) => unreachable!(),
+		Block::GraphicControlExtension(gce) => {
+			vec.push(0xF9); // Graphic control label
+			vec.push(0x04); // Block size for this extension is always 4
+			vec.push(gce.packed);
+			vec.extend_from_slice(&gce.delay_time.to_le_bytes());
+			vec.push(gce.transparency_index);
+		}
+		Block::CommentExtension(comment) => todo!(),
+		Block::ApplicationExtension(app) => todo!(),
+		Block::LoopingExtension(lc) => {
+			vec.push(0xFF); // Application extension label
+			vec.push(0x0B); // 11 bytes in this block
+			vec.extend_from_slice(b"NETSCAPE2.0"); // App. ident. and "auth code"
+			vec.push(0x03); // Sub-block length
+			vec.push(0x01); // Identifies netscape looping extension
+
+			match lc {
+				LoopCount::Forever => vec.extend_from_slice(&[0x00, 0x00]),
+				LoopCount::Number(count) => vec.extend_from_slice(&count.to_le_bytes()),
+			}
+		}
+	}
+
+	vec.push(0x00); // Zero length sub-block indicates end of extension
+	vec.into_boxed_slice()
+}