about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml2
-rw-r--r--benches/lzw_encode.rs20
-rw-r--r--src/colorimage.rs63
-rw-r--r--src/gif.rs36
-rw-r--r--src/lib.rs2
-rw-r--r--src/reader/mod.rs7
6 files changed, 110 insertions, 20 deletions
diff --git a/Cargo.toml b/Cargo.toml
index ebcebd6..295a943 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,7 +9,7 @@ repository = "https://github.com/genuinebyte/gifed"
 
 [dev-dependencies]
 criterion = "0.3"
-rand = "0.7.3"
+png = "0.17.2"
 
 [dependencies]
 weezl = "0.1.5"
diff --git a/benches/lzw_encode.rs b/benches/lzw_encode.rs
index 33440b2..aacf4a3 100644
--- a/benches/lzw_encode.rs
+++ b/benches/lzw_encode.rs
@@ -1,13 +1,23 @@
 use criterion::{black_box, criterion_group, criterion_main, Criterion};
-use rand::{thread_rng, Rng};
 use gifed::LZW;
+use rand::{thread_rng, Rng};
+use weezl::{encode::Encoder, BitOrder};
 
 pub fn criterion_benchmark(c: &mut Criterion) {
-	let mut random = [0u8; 255];
-	thread_rng().fill(&mut random[..]);
+    let mut random = [0u8; 2048];
+    thread_rng().fill(&mut random[..]);
 
-    c.bench_function("lzw encode 255bytes", |b| b.iter(|| LZW::encode(8, black_box(&random))));
+    c.bench_function("lzw encode 255bytes", |b| {
+        b.iter(|| LZW::encode(8, black_box(&random)))
+    });
+    c.bench_function("weezl encode 255bytes", |b| {
+        b.iter(|| {
+            Encoder::new(BitOrder::Msb, 8)
+                .encode(black_box(&random))
+                .unwrap()
+        })
+    });
 }
 
 criterion_group!(benches, criterion_benchmark);
-criterion_main!(benches);
\ No newline at end of file
+criterion_main!(benches);
diff --git a/src/colorimage.rs b/src/colorimage.rs
index 71f2bee..1bdb273 100644
--- a/src/colorimage.rs
+++ b/src/colorimage.rs
@@ -1,16 +1,61 @@
+use std::convert::TryFrom;
+
+use crate::{block::ColorTable, gif::Image, reader::DecodingError, Color};
+
 pub struct ColorImage {
-	width: u16,
-	height: u16,
-	data: Vec<Pixel>
+    width: u16,
+    height: u16,
+    data: Vec<Pixel>,
 }
 
 impl ColorImage {
-	pub fn new() {
-		
-	}
+    pub(crate) fn from_indicies(
+        width: u16,
+        height: u16,
+        indicies: &[u8],
+        table: &ColorTable,
+        transindex: Option<u8>,
+    ) -> Result<Self, DecodingError> {
+        let mut data = vec![Pixel::Transparent; (width * height) as usize];
+
+        for (image_index, color_index) in indicies.into_iter().enumerate() {
+            if let Some(trans) = transindex {
+                if trans == *color_index {
+                    data[image_index] = Pixel::Transparent;
+                }
+            } else {
+                data[image_index] = Pixel::Color(
+                    table
+                        .get(*color_index)
+                        .ok_or(DecodingError::ColorIndexOutOfBounds)?,
+                );
+            }
+        }
+
+        Ok(ColorImage {
+            width,
+            height,
+            data,
+        })
+    }
 }
 
+impl<'a> TryFrom<Image<'a>> for ColorImage {
+    type Error = DecodingError;
+
+    fn try_from(img: Image<'a>) -> Result<Self, Self::Error> {
+        ColorImage::from_indicies(
+            img.width,
+            img.height,
+            img.indicies,
+            img.palette,
+            img.transparent_index,
+        )
+    }
+}
+
+#[derive(Copy, Clone, Debug, PartialEq)]
 pub enum Pixel {
-	Color(Color),
-	Transparent
-}
\ No newline at end of file
+    Color(Color),
+    Transparent,
+}
diff --git a/src/gif.rs b/src/gif.rs
index 5b58ed1..3a56850 100644
--- a/src/gif.rs
+++ b/src/gif.rs
@@ -2,7 +2,9 @@ use std::{fs::File, io::Write, path::Path};
 
 use crate::{
     block::{extension::Extension, Block, ColorTable, ScreenDescriptor, Version},
+    colorimage,
     writer::GifBuilder,
+    ColorImage,
 };
 pub struct Gif {
     pub header: Version,
@@ -58,19 +60,43 @@ impl Gif {
     pub fn save<P: AsRef<Path>>(&self, path: P) -> std::io::Result<()> {
         File::create(path.as_ref())?.write_all(&self.to_vec())
     }
-}
 
-/*struct FrameIterator {
+    pub fn images<'a>(&'a self) -> ImageIterator<'a> {
+        ImageIterator { inner: self }
+    }
+}
 
+pub struct ImageIterator<'a> {
+    inner: &'a Gif,
 }
 
-impl Iterator for FrameIterator {
-    type Item = ();
+impl<'a> Iterator for ImageIterator<'a> {
+    type Item = Image<'a>;
 
     fn next(&mut self) -> Option<Self::Item> {
         todo!()
     }
-}*/
+}
+
+pub struct Image<'a> {
+    pub(crate) width: u16,
+    pub(crate) height: u16,
+    left_offset: u16,
+    top_offset: u16,
+    pub(crate) palette: &'a ColorTable,
+    pub(crate) transparent_index: Option<u8>,
+    pub(crate) indicies: &'a [u8],
+}
+
+impl<'a> Image<'a> {
+    pub fn dimesnions(&self) -> (u16, u16) {
+        (self.width, self.height)
+    }
+
+    pub fn position(&self) -> (u16, u16) {
+        (self.left_offset, self.top_offset)
+    }
+}
 
 #[cfg(test)]
 pub mod gif {
diff --git a/src/lib.rs b/src/lib.rs
index 97bab10..c7d820d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,4 +1,5 @@
 mod color;
+mod colorimage;
 mod gif;
 mod lzw;
 
@@ -10,6 +11,7 @@ use core::fmt;
 use std::error::Error;
 
 pub use color::Color;
+pub use colorimage::ColorImage;
 pub use gif::Gif;
 pub use lzw::LZW;
 
diff --git a/src/reader/mod.rs b/src/reader/mod.rs
index 958eff2..1b52874 100644
--- a/src/reader/mod.rs
+++ b/src/reader/mod.rs
@@ -181,6 +181,7 @@ pub enum DecodingError {
     IoError(std::io::Error),
     UnknownVersionString,
     UnexpectedEof,
+    ColorIndexOutOfBounds,
 }
 
 impl Error for DecodingError {}
@@ -194,6 +195,12 @@ impl fmt::Display for DecodingError {
             DecodingError::UnexpectedEof => {
                 write!(f, "Found the end of the data at a weird spot")
             }
+            DecodingError::ColorIndexOutOfBounds => {
+                write!(
+                    f,
+                    "The image contained an index not found in the color table"
+                )
+            }
         }
     }
 }