about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDevon Sawatsky <novedevo@gmail.com>2023-10-22 17:33:50 -0700
committerDevon Sawatsky <novedevo@gmail.com>2023-10-22 17:33:50 -0700
commit47f045d305b43fd3dd0938d5eda9fd61be7f6c5f (patch)
tree974053d04b68878894cfb224047316c6b54c777c
parent22a1bdf44a1f18d91d3dd286eb349e75d762c0f6 (diff)
downloadgifed-47f045d305b43fd3dd0938d5eda9fd61be7f6c5f.tar.gz
gifed-47f045d305b43fd3dd0938d5eda9fd61be7f6c5f.zip
switch bitstream to bitvec based
-rw-r--r--gifed/Cargo.toml1
-rw-r--r--gifed/src/lzw.rs48
2 files changed, 11 insertions, 38 deletions
diff --git a/gifed/Cargo.toml b/gifed/Cargo.toml
index 48b4bf5..a27ff7b 100644
--- a/gifed/Cargo.toml
+++ b/gifed/Cargo.toml
@@ -8,6 +8,7 @@ description = "Gif encoding and decoding with fine control"
 repository = "https://github.com/genuinebyte/gifed"
 
 [dependencies]
+bitvec = "1.0.1"
 weezl = "0.1.5"
 
 [dev-dependencies]
diff --git a/gifed/src/lzw.rs b/gifed/src/lzw.rs
index 53451da..bcf1988 100644
--- a/gifed/src/lzw.rs
+++ b/gifed/src/lzw.rs
@@ -1,5 +1,7 @@
 use std::collections::HashMap;
 
+use bitvec::prelude::*;
+
 pub struct LZW {}
 impl LZW {
 	pub fn encode(minimum_size: u8, indices: &[u8]) -> Vec<u8> {
@@ -60,7 +62,7 @@ impl LZW {
 				}
 			}
 		}
-		out.push_bits(code_size, eoi);
+		out.push_bits(code_size, end_of_information_code);
 
 		out.vec()
 	}
@@ -126,55 +128,25 @@ mod lzw_test {
 }
 
 struct BitStream {
-	formed: Vec<u8>,
-	current: u8,
-	index: u8,
+	formed: BitVec<u8, Lsb0>,
 }
 
 impl BitStream {
 	fn new() -> Self {
 		Self {
-			formed: vec![],
-			current: 0,
-			index: 0,
+			formed: BitVec::EMPTY,
 		}
 	}
 
 	fn push_bits(&mut self, count: u8, data: u16) {
-		// number of bits that are in self.current after we put in the new data
-		let mut new_index = self.index + count;
-		// combine self.current an the data we were given. shifts data over by
-		// the number of bits that are in self.current so we don't collide
-		let mut current32 = (self.current as u32) | ((data as u32) << self.index);
-
-		// Take bytes from current32 until we can store the partial in self.current
-		loop {
-			// Will we have over a byte of data in self.current?
-			if new_index >= 8 {
-				// Yes. Push the last 8-bits to the output vec
-				self.formed.push(current32 as u8);
-				// and make sure we remove them from current
-				current32 >>= 8;
-				// and that we adjust the index to reflect that
-				new_index -= 8;
-			} else {
-				// No, all data fits in the u8 of self.current. assign and break, we're done.
-				self.current = current32 as u8;
-				self.index = new_index;
-
-				break;
-			}
+		for i in 0..count {
+			self.formed.push((data & (1 << i)) > 0)
 		}
 	}
 
-	fn vec(self) -> Vec<u8> {
-		let mut out = self.formed;
-
-		if self.index != 0 {
-			out.push(self.current);
-		}
-
-		out
+	fn vec(mut self) -> Vec<u8> {
+		self.formed.set_uninitialized(false);
+		self.formed.into_vec()
 	}
 }