diff options
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | benches/lzw_encode.rs | 20 | ||||
-rw-r--r-- | src/colorimage.rs | 63 | ||||
-rw-r--r-- | src/gif.rs | 36 | ||||
-rw-r--r-- | src/lib.rs | 2 | ||||
-rw-r--r-- | src/reader/mod.rs | 7 |
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" + ) + } } } } |