about summary refs log tree commit diff
path: root/gifed/src/block/extension
diff options
context:
space:
mode:
authorGenevieve Alfirevic <gen@nyble.dev>2022-02-02 23:03:01 -0600
committerGenevieve Alfirevic <gen@nyble.dev>2022-02-02 23:03:01 -0600
commit64dc74a04eedd550f1c72af1caa88d2b81ab70e8 (patch)
tree5f58b1bae93640279995d9ce0a038f6a8381d5f3 /gifed/src/block/extension
parente7248533e5db69893b7a35ac83e90f0680420d27 (diff)
downloadgifed-64dc74a04eedd550f1c72af1caa88d2b81ab70e8.tar.gz
gifed-64dc74a04eedd550f1c72af1caa88d2b81ab70e8.zip
Why are these files changed
Diffstat (limited to 'gifed/src/block/extension')
-rw-r--r--gifed/src/block/extension/application.rs4
-rw-r--r--gifed/src/block/extension/graphiccontrol.rs84
2 files changed, 66 insertions, 22 deletions
diff --git a/gifed/src/block/extension/application.rs b/gifed/src/block/extension/application.rs
index 9ec1814..3d46277 100644
--- a/gifed/src/block/extension/application.rs
+++ b/gifed/src/block/extension/application.rs
@@ -1,11 +1,11 @@
 pub struct Application {
-	pub(crate) identifier: String, // max len 8
+	pub(crate) identifier: [u8; 8],
 	pub(crate) authentication_code: [u8; 3],
 	pub(crate) data: Vec<u8>,
 }
 
 impl Application {
-	pub fn identifier(&self) -> &str {
+	pub fn identifier(&self) -> &[u8] {
 		&self.identifier
 	}
 
diff --git a/gifed/src/block/extension/graphiccontrol.rs b/gifed/src/block/extension/graphiccontrol.rs
index 8b62160..a6abbdc 100644
--- a/gifed/src/block/extension/graphiccontrol.rs
+++ b/gifed/src/block/extension/graphiccontrol.rs
@@ -1,9 +1,9 @@
-use std::{convert::TryInto, fmt};
+use std::{convert::TryInto, fmt, time::Duration};
 
 #[derive(Clone, Debug)]
 pub struct GraphicControl {
 	pub(crate) packed: u8,
-	pub(crate) delay_time: u16,
+	pub(crate) delay: u16,
 	pub(crate) transparency_index: u8,
 }
 
@@ -12,22 +12,27 @@ impl GraphicControl {
 		disposal_method: DisposalMethod,
 		user_input_flag: bool,
 		transparency_flag: bool,
-		delay_time: u16,
+		delay: u16,
 		transparency_index: u8,
 	) -> Self {
 		let mut ret = Self {
 			packed: 0,
-			delay_time,
+			delay,
 			transparency_index,
 		};
 
 		ret.set_disposal_method(disposal_method);
 		ret.set_user_input(user_input_flag);
-		ret.transparency(transparency_flag);
+		ret.set_transparent(transparency_flag);
 
 		ret
 	}
 
+	/// Get the disposal method that should be used for the associated image.
+	///
+	/// # Returns
+	/// This method will return `Some([DisposalMethod])` if the disposal method
+	/// is recognized, or None if it was set to a reserved value.
 	pub fn disposal_method(&self) -> Option<DisposalMethod> {
 		match self.packed & 0b000_111_00 {
 			0b000_000_00 => Some(DisposalMethod::NoAction),
@@ -38,6 +43,7 @@ impl GraphicControl {
 		}
 	}
 
+	/// Set the disposal method that shoudl be used for the associated image.
 	pub fn set_disposal_method(&mut self, method: DisposalMethod) {
 		match method {
 			DisposalMethod::NoAction => self.packed &= 0b111_000_1_1,
@@ -47,10 +53,48 @@ impl GraphicControl {
 		};
 	}
 
-	pub fn transparency_index(&self) -> u8 {
+	/// Returns the index that should be replaced by a fully transparent pixel
+	/// if the transparency flag is set, or None if it's not set.
+	pub fn transparent_index(&self) -> Option<u8> {
+		if self.transparent() {
+			Some(self.transparency_index)
+		} else {
+			None
+		}
+	}
+
+	/// Returns the transparency index regardless if the transparency flag is set.
+	/// You probably want [GraphicControl::transparency_index] instead.s
+	pub fn transparent_index_unchecked(&self) -> u8 {
 		self.transparency_index
 	}
 
+	/// Sets the transparent index flag to the value provided. This will change
+	/// the index value in any way and should be used with caution. You probably
+	/// want [GraphicControl::set_transparent_index] instead.
+	pub fn set_transparent(&mut self, flag: bool) {
+		if flag {
+			self.packed |= 0b000_000_0_1;
+		} else {
+			self.packed &= 0b111_111_1_0;
+		}
+	}
+
+	/// Sets the transparent index and flips the flag to indicate a transparent
+	/// index is present.
+	pub fn set_transparent_index(&mut self, index: Option<u8>) {
+		self.set_transparent(index.is_some());
+
+		if let Some(index) = index {
+			self.transparency_index = index;
+		}
+	}
+
+	/// Get the value of the transparency flag
+	pub fn transparent(&self) -> bool {
+		self.packed & 0b000_000_0_1 > 0
+	}
+
 	pub fn user_input(&self) -> bool {
 		self.packed & 0b000_000_1_0 > 0
 	}
@@ -63,36 +107,36 @@ impl GraphicControl {
 		}
 	}
 
-	pub fn transparency(&mut self, flag: bool) {
-		if flag {
-			self.packed |= 0b000_000_0_1;
-		} else {
-			self.packed &= 0b111_111_1_0;
-		}
+	pub fn delay(&self) -> u16 {
+		self.delay
 	}
 
-	pub fn delay_time(&self) -> u16 {
-		self.delay_time
+	pub fn delay_duration(&self) -> Duration {
+		Duration::from_millis(self.delay as u64 * 10)
 	}
 
-	pub fn delay_time_mut(&mut self) -> &mut u16 {
-		&mut self.delay_time
+	pub fn delay_mut(&mut self) -> &mut u16 {
+		&mut self.delay
 	}
 
-	pub fn is_transparent(&self) -> bool {
-		self.packed & 0b000_000_0_1 > 0
+	pub fn packed(&self) -> u8 {
+		self.packed
+	}
+
+	pub fn packed_mut(&mut self) -> &mut u8 {
+		&mut self.packed
 	}
 }
 
 impl From<[u8; 4]> for GraphicControl {
 	fn from(arr: [u8; 4]) -> Self {
 		let packed = arr[0];
-		let delay_time = u16::from_le_bytes(arr[1..3].try_into().unwrap());
+		let delay = u16::from_le_bytes(arr[1..3].try_into().unwrap());
 		let transparency_index = arr[3];
 
 		Self {
 			packed,
-			delay_time,
+			delay,
 			transparency_index,
 		}
 	}