fastpack_core/imaging/
alias.rs1use rustc_hash::FxHashMap;
2
3use crate::types::sprite::Sprite;
4
5pub fn detect_aliases(sprites: Vec<Sprite>) -> (Vec<Sprite>, Vec<Sprite>) {
15 let mut buckets: FxHashMap<(u32, u32, u64), Vec<usize>> = FxHashMap::default();
17 let mut unique: Vec<Sprite> = Vec::new();
18 let mut aliases: Vec<Sprite> = Vec::new();
19
20 for mut sprite in sprites {
21 let w = sprite.image.width();
22 let h = sprite.image.height();
23 let key = (w, h, sprite.content_hash);
24
25 let canon_id = buckets.get(&key).and_then(|indices| {
26 indices.iter().find_map(|&i| {
27 if pixels_equal(&sprite.image, &unique[i].image) {
28 Some(unique[i].id.clone())
29 } else {
30 None
31 }
32 })
33 });
34
35 if let Some(id) = canon_id {
36 sprite.alias_of = Some(id);
37 aliases.push(sprite);
38 } else {
39 let idx = unique.len();
40 buckets.entry(key).or_default().push(idx);
41 unique.push(sprite);
42 }
43 }
44
45 (unique, aliases)
46}
47
48fn pixels_equal(a: &image::DynamicImage, b: &image::DynamicImage) -> bool {
49 match (a.as_rgba8(), b.as_rgba8()) {
50 (Some(ra), Some(rb)) => ra.as_raw() == rb.as_raw(),
51 _ => false,
52 }
53}