diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Cargo.toml | 24 | ||||
-rw-r--r-- | README.md | 10 | ||||
-rw-r--r-- | gifed/Cargo.toml | 19 | ||||
-rw-r--r-- | gifed/benches/lzw_encode.rs (renamed from benches/lzw_encode.rs) | 0 | ||||
-rw-r--r-- | gifed/examples/read.rs (renamed from examples/read.rs) | 0 | ||||
-rw-r--r-- | gifed/src/block/colortable.rs (renamed from src/block/colortable.rs) | 0 | ||||
-rw-r--r-- | gifed/src/block/extension/application.rs (renamed from src/block/extension/application.rs) | 0 | ||||
-rw-r--r-- | gifed/src/block/extension/graphiccontrol.rs (renamed from src/block/extension/graphiccontrol.rs) | 0 | ||||
-rw-r--r-- | gifed/src/block/extension/mod.rs (renamed from src/block/extension/mod.rs) | 0 | ||||
-rw-r--r-- | gifed/src/block/imagedescriptor.rs (renamed from src/block/imagedescriptor.rs) | 0 | ||||
-rw-r--r-- | gifed/src/block/indexedimage.rs (renamed from src/block/indexedimage.rs) | 0 | ||||
-rw-r--r-- | gifed/src/block/mod.rs (renamed from src/block/mod.rs) | 0 | ||||
-rw-r--r-- | gifed/src/block/screendescriptor.rs (renamed from src/block/screendescriptor.rs) | 0 | ||||
-rw-r--r-- | gifed/src/block/version.rs (renamed from src/block/version.rs) | 0 | ||||
-rw-r--r-- | gifed/src/color.rs (renamed from src/color.rs) | 0 | ||||
-rw-r--r-- | gifed/src/colorimage.rs (renamed from src/colorimage.rs) | 0 | ||||
-rw-r--r-- | gifed/src/gif.rs (renamed from src/gif.rs) | 16 | ||||
-rw-r--r-- | gifed/src/lib.rs (renamed from src/lib.rs) | 0 | ||||
-rw-r--r-- | gifed/src/lzw.rs (renamed from src/lzw.rs) | 0 | ||||
-rw-r--r-- | gifed/src/reader/mod.rs (renamed from src/reader/mod.rs) | 0 | ||||
-rw-r--r-- | gifed/src/writer/gifbuilder.rs (renamed from src/writer/gifbuilder.rs) | 0 | ||||
-rw-r--r-- | gifed/src/writer/imagebuilder.rs (renamed from src/writer/imagebuilder.rs) | 0 | ||||
-rw-r--r-- | gifed/src/writer/mod.rs (renamed from src/writer/mod.rs) | 0 | ||||
-rw-r--r-- | gifprobe/Cargo.toml | 14 | ||||
-rw-r--r-- | gifprobe/src/main.rs | 107 |
26 files changed, 170 insertions, 22 deletions
diff --git a/.gitignore b/.gitignore index e3b0c5d..4699ed7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ /.vscode -/target +**/target Cargo.lock *.gif *.txt diff --git a/Cargo.toml b/Cargo.toml index 295a943..2a5d22b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,19 +1,5 @@ -[package] -name = "gifed" -version = "0.1.0" -authors = ["Brad Alfirevic <brad@genbyte.dev>"] -edition = "2018" -license = "CC0-1.0" -description = "Gif encoding and decoding with fine control" -repository = "https://github.com/genuinebyte/gifed" - -[dev-dependencies] -criterion = "0.3" -png = "0.17.2" - -[dependencies] -weezl = "0.1.5" - -[[bench]] -name = "lzw_encode" -harness = false \ No newline at end of file +[workspace] +members = [ + "gifed", + "gifprobe" +] \ No newline at end of file diff --git a/README.md b/README.md index b65f891..ca9d927 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ This crate is still pretty rough. I hope to make it feature complete and intuitive to use while still allowing fine grained control over the file itself, which has been and always will be, one of the main goals of this crate. -### TODO +### Gifed TODO - [x] Writing GIF87a - [x] Writing GIF89a - [x] Automatically select the lowest version possible when writing @@ -18,4 +18,10 @@ always will be, one of the main goals of this crate. - [ ] Well written and easy to understand docs! `bitvec` quality, but who can match that? [weezl-crates]: https://crates.io/crates/weezl -[rgb-crates]: https://crates.io/crates/rgb \ No newline at end of file +[rgb-crates]: https://crates.io/crates/rgb + +## gifprobe +Similar to FFMPEG's ffprobe, gifprobe will print details of a gif to stdout. + +# License +gided and gifprobe are licensed under Creative Commons Zero 1.0; they're in the public domain. Attribution is appreciated, but not required. \ No newline at end of file diff --git a/gifed/Cargo.toml b/gifed/Cargo.toml new file mode 100644 index 0000000..08974f5 --- /dev/null +++ b/gifed/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "gifed" +version = "0.1.0" +authors = ["Genevive Alfirevic <gen@nyble.dev>"] +edition = "2018" +license = "CC0-1.0" +description = "Gif encoding and decoding with fine control" +repository = "https://github.com/genuinebyte/gifed" + +[dev-dependencies] +criterion = "0.3" +png = "0.17.2" + +[dependencies] +weezl = "0.1.5" + +[[bench]] +name = "lzw_encode" +harness = false \ No newline at end of file diff --git a/benches/lzw_encode.rs b/gifed/benches/lzw_encode.rs index 69ed275..69ed275 100644 --- a/benches/lzw_encode.rs +++ b/gifed/benches/lzw_encode.rs diff --git a/examples/read.rs b/gifed/examples/read.rs index 3c40bfe..3c40bfe 100644 --- a/examples/read.rs +++ b/gifed/examples/read.rs diff --git a/src/block/colortable.rs b/gifed/src/block/colortable.rs index 01fe00b..01fe00b 100644 --- a/src/block/colortable.rs +++ b/gifed/src/block/colortable.rs diff --git a/src/block/extension/application.rs b/gifed/src/block/extension/application.rs index 9ec1814..9ec1814 100644 --- a/src/block/extension/application.rs +++ b/gifed/src/block/extension/application.rs diff --git a/src/block/extension/graphiccontrol.rs b/gifed/src/block/extension/graphiccontrol.rs index b595554..b595554 100644 --- a/src/block/extension/graphiccontrol.rs +++ b/gifed/src/block/extension/graphiccontrol.rs diff --git a/src/block/extension/mod.rs b/gifed/src/block/extension/mod.rs index fb5eb20..fb5eb20 100644 --- a/src/block/extension/mod.rs +++ b/gifed/src/block/extension/mod.rs diff --git a/src/block/imagedescriptor.rs b/gifed/src/block/imagedescriptor.rs index 25567b2..25567b2 100644 --- a/src/block/imagedescriptor.rs +++ b/gifed/src/block/imagedescriptor.rs diff --git a/src/block/indexedimage.rs b/gifed/src/block/indexedimage.rs index 8ed0319..8ed0319 100644 --- a/src/block/indexedimage.rs +++ b/gifed/src/block/indexedimage.rs diff --git a/src/block/mod.rs b/gifed/src/block/mod.rs index e35224b..e35224b 100644 --- a/src/block/mod.rs +++ b/gifed/src/block/mod.rs diff --git a/src/block/screendescriptor.rs b/gifed/src/block/screendescriptor.rs index dc0257d..dc0257d 100644 --- a/src/block/screendescriptor.rs +++ b/gifed/src/block/screendescriptor.rs diff --git a/src/block/version.rs b/gifed/src/block/version.rs index 0171ad4..0171ad4 100644 --- a/src/block/version.rs +++ b/gifed/src/block/version.rs diff --git a/src/color.rs b/gifed/src/color.rs index e18ce58..e18ce58 100644 --- a/src/color.rs +++ b/gifed/src/color.rs diff --git a/src/colorimage.rs b/gifed/src/colorimage.rs index 69dac1e..69dac1e 100644 --- a/src/colorimage.rs +++ b/gifed/src/colorimage.rs diff --git a/src/gif.rs b/gifed/src/gif.rs index de84764..89aaa64 100644 --- a/src/gif.rs +++ b/gifed/src/gif.rs @@ -121,6 +121,12 @@ impl<'a> Iterator for ImageIterator<'a> { } } +pub struct FrameIterator<'a> { + gif: &'a Gif, + veciter: std::slice::Iter<'a, Block>, + buffer: Vec<u8>, +} + pub struct Image<'a> { pub(crate) width: u16, pub(crate) height: u16, @@ -157,6 +163,16 @@ impl<'a> Image<'a> { } } +pub struct Frame { + width: u16, + height: u16, + palette: ColorTable, + transparent_index: Option<u8>, + indicies: Vec<u8>, + delay_after_draw: u16, + user_input_flag: bool, +} + #[cfg(test)] pub mod gif { use std::convert::TryInto; diff --git a/src/lib.rs b/gifed/src/lib.rs index 0a11fdc..0a11fdc 100644 --- a/src/lib.rs +++ b/gifed/src/lib.rs diff --git a/src/lzw.rs b/gifed/src/lzw.rs index dce6a5d..dce6a5d 100644 --- a/src/lzw.rs +++ b/gifed/src/lzw.rs diff --git a/src/reader/mod.rs b/gifed/src/reader/mod.rs index 41494df..41494df 100644 --- a/src/reader/mod.rs +++ b/gifed/src/reader/mod.rs diff --git a/src/writer/gifbuilder.rs b/gifed/src/writer/gifbuilder.rs index 57a62e3..57a62e3 100644 --- a/src/writer/gifbuilder.rs +++ b/gifed/src/writer/gifbuilder.rs diff --git a/src/writer/imagebuilder.rs b/gifed/src/writer/imagebuilder.rs index f5c9e2b..f5c9e2b 100644 --- a/src/writer/imagebuilder.rs +++ b/gifed/src/writer/imagebuilder.rs diff --git a/src/writer/mod.rs b/gifed/src/writer/mod.rs index 88311fc..88311fc 100644 --- a/src/writer/mod.rs +++ b/gifed/src/writer/mod.rs diff --git a/gifprobe/Cargo.toml b/gifprobe/Cargo.toml new file mode 100644 index 0000000..75047b8 --- /dev/null +++ b/gifprobe/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "gifprobe" +version = "0.1.0" +authors = ["Genevive Alfirevic <gen@nyble.dev"] +edition = "2018" +license = "CC0-1.0" +description = "Print the details of a gif to stdout; ffprobe for gif" +repository = "https://github.com/genuinebyte/gifed" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +owo-colors = "2.0.0" +gifed = { path = "../gifed" } \ No newline at end of file diff --git a/gifprobe/src/main.rs b/gifprobe/src/main.rs new file mode 100644 index 0000000..3af9a50 --- /dev/null +++ b/gifprobe/src/main.rs @@ -0,0 +1,107 @@ +use std::{convert::TryInto, fs::File, io::Write, path::Path}; + +use gifed::{ + block::{ + extension::{Extension, GraphicControl}, + ColorTable, IndexedImage, Version, + }, + reader::GifReader, + writer::{GifBuilder, ImageBuilder}, + Color, +}; +use owo_colors::OwoColorize; + +fn main() { + let file = if let Some(file) = std::env::args().skip(1).next() { + file + } else { + println!("usage: gifprobe file.gif"); + return; + }; + + let gif = GifReader::file(&file).unwrap(); + + println!("Version {}", gif.header.yellow()); + println!( + "Logical Screen Descriptor\n\tDimensions {}x{}", + gif.screen_descriptor.width.yellow(), + gif.screen_descriptor.height.yellow() + ); + + if gif.screen_descriptor.color_table_present() { + println!( + "\tGlobal Color Table Present {}\n\tGlobal Color Table Size {}", + "Yes".green(), + gif.screen_descriptor.color_table_len().green() + ); + } else { + println!( + "\tGlobal Color Table Present {}\n\tGlobal Color Table Size {}", + "No".red(), + gif.screen_descriptor.color_table_len().red() + ); + } + + let mut img_count = 0; + let mut hundreths: usize = 0; + + for block in gif.blocks { + match block { + gifed::block::Block::IndexedImage(img) => { + describe_image(&img); + img_count += 1; + } + gifed::block::Block::Extension(ext) => match ext { + gifed::block::extension::Extension::GraphicControl(gce) => { + hundreths += gce.delay_time() as usize; + + println!( + "Graphic Control Extension\n\tDelay Time {}\n\tDispose {}", + format!("{}s", gce.delay_time() as f32 / 100.0).yellow(), + gce.disposal_method().unwrap().yellow() + ) + } + gifed::block::extension::Extension::Looping(_) => todo!(), + gifed::block::extension::Extension::Comment(cmt) => { + println!("Comment Extension\n\tLength {}", cmt.len()) + } + gifed::block::extension::Extension::Application(app) => { + let auth = app.authentication_code(); + println!("Application Extension\n\tIdentifier {}\n\tAuthentication {:02X} {:02X} {:02X}",app.identifier().yellow(), auth[0].yellow(), auth[1].yellow(), auth[2].yellow()); + } + }, + } + } + + println!( + "{} is {}.{}s long and has {} frames", + file, + hundreths / 100, + hundreths % 100, + img_count + ); +} + +fn describe_image(bli: &IndexedImage) { + println!( + "Image\n\tOffset {}x{}\n\tDimensions {}x{}", + bli.image_descriptor.left.yellow(), + bli.image_descriptor.top.yellow(), + bli.image_descriptor.width.yellow(), + bli.image_descriptor.height.yellow(), + ); + + if bli.image_descriptor.color_table_present() { + println!( + "\tLocal Color Table Present {}\n\tLocal Color Table Size {}", + "Yes".green(), + bli.image_descriptor.color_table_size().green() + ); + } else { + println!( + "\tLocal Color Table Present {}\n\tLocal Color Table Size {}", + "No".red(), + bli.image_descriptor.color_table_size().red() + ); + } +} |