about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgennyble <gen@nyble.dev>2023-10-09 03:40:01 -0500
committergennyble <gen@nyble.dev>2023-10-09 03:40:01 -0500
commit54be5b8cb0f494e28dbed06bc3a93aefd2a9caf1 (patch)
tree5bbc11b4a08bbae6884466cfcca0f97e5967a9f7
parent8bda303bd7ce4f63c2430e9de92adfc07fec63f2 (diff)
downloadcolorsquash-54be5b8cb0f494e28dbed06bc3a93aefd2a9caf1.tar.gz
colorsquash-54be5b8cb0f494e28dbed06bc3a93aefd2a9caf1.zip
real, actual difference algorithms
-rw-r--r--squash/src/main.rs3
-rw-r--r--src/lib.rs20
2 files changed, 21 insertions, 2 deletions
diff --git a/squash/src/main.rs b/squash/src/main.rs
index fe7f310..f7964f4 100644
--- a/squash/src/main.rs
+++ b/squash/src/main.rs
@@ -51,7 +51,8 @@ fn main() -> Result<(), anyhow::Error> {
 		}
 	};
 
-	let squasher = Squasher::new(color_count, &image.data);
+	let squasher =
+		Squasher::new_with_difference(color_count, &image.data, &colorsquash::redmean_difference);
 	let size = squasher.map_over(&mut image.data);
 	image.data.resize(size, 0);
 
diff --git a/src/lib.rs b/src/lib.rs
index 383aa83..c16bfb2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -129,8 +129,10 @@ impl<T: Count> Squasher<T> {
     }
 
     fn select_colors(sorted: &[(RGB8, usize)], max_colors: T, difference: &DiffFn) -> Vec<RGB8> {
+        // I made these numbers up
         #[allow(non_snake_case)]
-        let RGB_TOLERANCE: f32 = 0.01 * 768.0;
+        //let RGB_TOLERANCE: f32 = 0.01 * 768.0;
+        let RGB_TOLERANCE: f32 = 36.0;
         let mut selected_colors: Vec<(RGB8, usize)> = Vec::with_capacity(max_colors.as_usize());
 
         for (key, count) in sorted.iter() {
@@ -238,3 +240,19 @@ pub fn rgb_difference(a: &RGB8, b: &RGB8) -> f32 {
     let absdiff = |a: u8, b: u8| (a as f32 - b as f32).abs();
     absdiff(a.r, b.r) + absdiff(a.g, b.g) + absdiff(a.b, b.b)
 }
+
+// https://en.wikipedia.org/wiki/Color_difference#sRGB
+#[inline(always)]
+pub fn redmean_difference(a: &RGB8, b: &RGB8) -> f32 {
+    let delta_r = a.r as f32 - b.r as f32;
+    let delta_g = a.g as f32 - b.g as f32;
+    let delta_b = a.b as f32 - b.b as f32;
+    // reasonably sure calling it prime is wrong, but
+    let r_prime = 0.5 * (a.r as f32 + b.r as f32);
+
+    let red_part = (2.0 + (r_prime / 256.0)) * (delta_r * delta_r);
+    let green_part = 4.0 * (delta_g * delta_g);
+    let blue_part = (2.0 + (255.0 - r_prime) / 256.0) * (delta_b * delta_b);
+
+    (red_part + green_part + blue_part).sqrt()
+}