about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Cargo.lock14
-rw-r--r--squash/Cargo.toml1
-rw-r--r--squash/src/main.rs55
4 files changed, 58 insertions, 14 deletions
diff --git a/.gitignore b/.gitignore
index 4c7d6ed..ba7f17b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,8 @@
 *.PNG
 *.jpg
 *.JPG
+*.gif
+*.GIF
 flamegraph.svg
 perf.data
 perf.data.old
diff --git a/Cargo.lock b/Cargo.lock
index 4256a12..fc918c1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -80,6 +80,13 @@ dependencies = [
 ]
 
 [[package]]
+name = "gifed"
+version = "0.2.0"
+dependencies = [
+ "weezl",
+]
+
+[[package]]
 name = "log"
 version = "0.4.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -129,11 +136,18 @@ dependencies = [
  "anyhow",
  "camino",
  "colorsquash",
+ "gifed",
  "png",
  "zune-jpeg",
 ]
 
 [[package]]
+name = "weezl"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb"
+
+[[package]]
 name = "zune-core"
 version = "0.2.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/squash/Cargo.toml b/squash/Cargo.toml
index 1b92d38..921f937 100644
--- a/squash/Cargo.toml
+++ b/squash/Cargo.toml
@@ -14,3 +14,4 @@ camino = "1.1.6"
 # been released yet, so we're using the git here. the commit we require is e4b4811
 png = { git = "https://github.com/image-rs/image-png.git", rev = "f10238a1e886b228e7da5301e5c0f5011316f2d6" }
 zune-jpeg = "0.3.17"
+gifed = { path = "../../gifed/gifed" }
diff --git a/squash/src/main.rs b/squash/src/main.rs
index da3cfbf..fe7f310 100644
--- a/squash/src/main.rs
+++ b/squash/src/main.rs
@@ -3,6 +3,7 @@ use std::{fs::File, io::BufWriter};
 use anyhow::{anyhow, bail};
 use camino::{Utf8Path, Utf8PathBuf};
 use colorsquash::Squasher;
+use gifed::writer::{GifBuilder, ImageBuilder};
 use png::{ColorType, Decoder, Encoder};
 use zune_jpeg::{zune_core::colorspace::ColorSpace, JpegDecoder};
 
@@ -60,17 +61,24 @@ fn main() -> Result<(), anyhow::Error> {
 		color_count
 	);
 
-	// PNG Output
-	let file = File::create(output_path)?;
-	let bufw = BufWriter::new(file);
-
-	let mut enc = Encoder::new(bufw, image.width as u32, image.height as u32);
-	enc.set_color(ColorType::Indexed);
-	enc.set_depth(png::BitDepth::Eight);
-	enc.set_palette(squasher.palette_bytes());
-	enc.write_header()?.write_image_data(&image.data)?;
+	match output_path.extension() {
+		None => {
+			eprintln!("can't determine output filetype! defaulting to png");
+			save_png(image, squasher, output_path)
+		}
+		Some("png") => save_png(image, squasher, output_path),
+		Some("gif") => save_gif(image, squasher, output_path),
+		Some(ext) => {
+			eprintln!("unknown filetype '{ext}'!\nSupport output types are: GIF, PNG");
+			std::process::exit(1);
+		}
+	}
+}
 
-	Ok(())
+struct Image {
+	width: usize,
+	height: usize,
+	data: Vec<u8>,
 }
 
 fn get_png<P: AsRef<Utf8Path>>(path: P) -> Result<Image, anyhow::Error> {
@@ -124,8 +132,27 @@ fn get_jpg<P: AsRef<Utf8Path>>(path: P) -> Result<Image, anyhow::Error> {
 	})
 }
 
-struct Image {
-	width: usize,
-	height: usize,
-	data: Vec<u8>,
+fn save_png(image: Image, squasher: Squasher<u8>, path: Utf8PathBuf) -> Result<(), anyhow::Error> {
+	let file = File::create(path)?;
+	let bufw = BufWriter::new(file);
+
+	let mut enc = Encoder::new(bufw, image.width as u32, image.height as u32);
+	enc.set_color(ColorType::Indexed);
+	enc.set_depth(png::BitDepth::Eight);
+	enc.set_palette(squasher.palette_bytes());
+	enc.write_header()?.write_image_data(&image.data)?;
+
+	Ok(())
+}
+
+fn save_gif(image: Image, squasher: Squasher<u8>, path: Utf8PathBuf) -> Result<(), anyhow::Error> {
+	// I don't think I like this API anymore. It's a builder API, that's fine.
+	// I should make it so you can mutate the Gif directly.
+	GifBuilder::new(image.width as u16, image.height as u16)
+		.palette(squasher.palette_bytes().as_slice().try_into().unwrap())
+		.image(ImageBuilder::new(image.width as u16, image.height as u16).build(image.data)?)
+		.build()?
+		.save(path)?;
+
+	Ok(())
 }