about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--README.md3
-rw-r--r--giftool/Cargo.toml10
-rw-r--r--giftool/src/main.rs169
3 files changed, 0 insertions, 182 deletions
diff --git a/README.md b/README.md
index 339407b..444faeb 100644
--- a/README.md
+++ b/README.md
@@ -41,8 +41,5 @@ These are part of the 89a spec, but are kept separate as they're not "core" to t
 ## gifprobe
 Similar to FFMPEG's ffprobe, gifprobe will print details of a gif to stdout.
 
-## giftool
-A CLI tool for modifying gif files.
-
 # License
 gifed, gifprobe, and giftool 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/giftool/Cargo.toml b/giftool/Cargo.toml
deleted file mode 100644
index 8e5763a..0000000
--- a/giftool/Cargo.toml
+++ /dev/null
@@ -1,10 +0,0 @@
-[package]
-name = "giftool"
-version = "0.1.0"
-edition = "2021"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-gifed = { path = "../gifed" }
-png = "0.17.2"
\ No newline at end of file
diff --git a/giftool/src/main.rs b/giftool/src/main.rs
deleted file mode 100644
index 1482185..0000000
--- a/giftool/src/main.rs
+++ /dev/null
@@ -1,169 +0,0 @@
-use std::{fs::File, ops::Deref, path::PathBuf};
-
-fn main() {
-	let subcommand = std::env::args().nth(1);
-
-	match subcommand.as_ref().map(|s| s.as_str()) {
-		Some("extract-frames") => extract_frames(),
-		Some("analyze") => analyze(),
-		_ => print_usage_and_exit(),
-	}
-}
-
-fn print_usage_and_exit() -> ! {
-	println!("usage: giftool <subcommand> <options>\n");
-	println!("extract_frames <input_gif> <output_directory>");
-	println!("\tExtract each frame of the gif to a png in the output directory.");
-	println!("analyze <input_gif>");
-	println!("\tAnalyze the gif, looking for places to make the image smaller.");
-
-	std::process::exit(0)
-}
-
-fn check_input_gif(igif: Option<PathBuf>) -> PathBuf {
-	if let Some(igif) = igif {
-		if !igif.exists() {
-			println!("The path provided to the gif does not exist");
-			std::process::exit(1);
-		} else if !igif.is_file() {
-			println!("The path provided to the gif is not a file");
-			std::process::exit(1);
-		}
-
-		igif
-	} else {
-		println!("No gif file provided");
-		std::process::exit(1);
-	}
-}
-
-fn extract_frames() {
-	let input_gif = std::env::args().nth(2).map(PathBuf::from);
-	let out_dir = std::env::args().nth(3).map(PathBuf::from);
-
-	let input_gif = check_input_gif(input_gif);
-
-	let out_dir = if let Some(odir) = out_dir {
-		if !odir.exists() {
-			println!("The output path does not exist");
-			std::process::exit(1);
-		} else if !odir.is_dir() {
-			println!("The output path is not a directory");
-			std::process::exit(1);
-		}
-
-		odir
-	} else {
-		println!("No output directory provided");
-		std::process::exit(1);
-	};
-
-	let gread = match GifReader::file(&input_gif) {
-		Ok(gread) => gread,
-		Err(e) => {
-			println!(
-				"Failed to read {} as a gif:\n{}",
-				input_gif.to_string_lossy(),
-				e
-			);
-			std::process::exit(1);
-		}
-	};
-
-	for (frame_number, image) in gread.images().enumerate() {
-		let mut fname = out_dir.clone();
-		fname.push(format!("{}.png", frame_number));
-
-		let file = File::create(fname).unwrap();
-
-		let mut encoder = png::Encoder::new(file, image.width as u32, image.height as u32);
-		encoder.set_color(png::ColorType::Indexed);
-		encoder.set_palette(image.palette.as_bytes());
-
-		if let Some(trns) = image.png_trns() {
-			encoder.set_trns(trns);
-		}
-
-		let mut writer = encoder.write_header().unwrap();
-		writer.write_image_data(&image.indicies).unwrap();
-	}
-}
-
-fn analyze() {
-	let input_gif = check_input_gif(std::env::args().nth(2).map(PathBuf::from));
-
-	//TODO:
-	// Look at color tables:
-	// - Can any of them be combined into a global colour table? Can they all be?
-	// - Can the colour tables be shrank? Is it bigger than it needs to be. (Are all the inidicies used)
-
-	let gread = match GifReader::file(&input_gif) {
-		Ok(gread) => gread,
-		Err(e) => {
-			println!(
-				"Failed to read {} as a gif:\n{}",
-				input_gif.to_string_lossy(),
-				e
-			);
-			std::process::exit(1);
-		}
-	};
-
-	if gread.global_color_table.is_some() {
-		if analyze_can_be_a_gct(&gread) {
-			println!("All local colors are in the global, this gif doesn't need locals");
-		}
-	}
-}
-
-/// A gif can be reindexed to not need any local color tables if:
-/// - The global color table contains all colors used in the gif
-/// OR
-/// - The global color table does not contain all colors used in the gif,
-///   but it can fit the colors it does not have.
-/// OR
-/// - There is no global color table, but there are only 256 colors used in
-///   the gif, so it can be created.
-///
-/// # Returns
-/// This function returns `true` if the gif can be reindexed to not need any
-/// local tables anymore.
-fn analyze_can_be_a_gct(gread: &Gif) -> bool {
-	let mut gct = if let Some(gct) = gread.global_color_table.as_ref() {
-		let mut gct = gct.clone().to_vec();
-		gct.dedup();
-		gct
-	} else {
-		vec![]
-	};
-
-	let mut gct_contains_all_colors = true;
-	let mut largest_gct_seen = 0;
-	let mut gif_has_local_tables = false;
-
-	for image in gread.images() {
-		if image.packed.color_table() {
-			gif_has_local_tables = true;
-			let lct = image.palette;
-
-			for color in lct.deref() {
-				if !gct.contains(color) {
-					gct_contains_all_colors = false;
-					gct.push(color.clone());
-				}
-			}
-		} else {
-			for index in image.indicies {
-				largest_gct_seen = largest_gct_seen.max(*index);
-			}
-		}
-	}
-
-	if gct_contains_all_colors || !gif_has_local_tables {
-		true
-	} else if !gct_contains_all_colors && gct.len() <= 256 {
-		true
-	} else {
-		false
-	}
-}