1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#![allow(incomplete_features, internal_features, mixed_script_confusables)]
#![feature(
    custom_inner_attributes,
    proc_macro_hygiene,
    type_alias_impl_trait,
    adt_const_params,
    stmt_expr_attributes,
    iter_array_chunks,
    generic_const_exprs,
    core_intrinsics,
    iter_intersperse,
    maybe_uninit_array_assume_init,
    iter_map_windows
)]
#![allow(non_camel_case_types)]
#[derive(Copy, Clone)]
pub struct pal<'palette, const N: usize> {
    inner: &'palette [[f32; N]],
}
impl<'a, const N: usize> pal<'a, N> {
    /// Create a ne palette. The length can not be 0 and must be < u32::MAX.
    pub fn new(value: &'a [[f32; N]]) -> Self {
        let value = value.as_ref();
        assert!(value.len() != 0);
        assert!(value.len() < u32::MAX as usize);
        pal { inner: value }
    }
}

impl<'a, const N: usize> AsRef<[[f32; N]]> for pal<'a, N> {
    fn as_ref(&self) -> &[[f32; N]] {
        &*self
    }
}
impl<'a, const N: usize> Deref for pal<'a, N> {
    type Target = [[f32; N]];

    fn deref(&self) -> &Self::Target {
        &self.inner
    }
}
type out<'palette, P> = IndexedImage<Box<[u32]>, P>;

pub mod diffusion;
pub mod ordered;

pub mod dumb;
use std::ops::Deref;

use atools::prelude::*;
use dumb::Closest;
use fimg::{Image, indexed::IndexedImage};

fn dither<'a, const C: usize>(
    image: Image<impl AsRef<[f32]>, C>,
    f: impl FnMut(((usize, usize), &[f32; C])) -> u32,
    pal: pal<'a, C>,
) -> out<'a, pal<'a, C>> {
    unsafe {
        IndexedImage::build(image.width(), image.height())
            .pal(pal)
            .buf_unchecked(
                image
                    .chunked()
                    .zip(image.ordered())
                    .map(|(p, xy)| (xy.array().map(|x| x as usize).tuple(), p))
                    .map(f)
                    .collect(),
            )
    }
}