use crate::{Palette, PaletteBuf};
use alloc::{borrow::ToOwned as _, vec::Vec};
mod nearest_neighbor;
mod palette_substitution;
pub use nearest_neighbor::*;
pub use palette_substitution::*;
pub trait IndexedColorMap<Input> {
type Output: Clone + Send + Sync;
fn into_palette(self) -> PaletteBuf<Self::Output>;
fn palette(&self) -> &Palette<Self::Output>;
fn base_palette(&self) -> &Palette<Input>;
fn palette_index(&self, color: &Input) -> u8;
#[inline]
fn palette_color(&self, color: &Input) -> Self::Output {
self.palette()[self.palette_index(color)].clone()
}
#[inline]
fn map_to_indices(&self, input: &[Input]) -> Vec<u8> {
input
.iter()
.map(|color| self.palette_index(color))
.collect()
}
#[inline]
fn map_to_colors_of_palette<T: Clone + Send + Sync>(
&self,
palette: &Palette<T>,
input: &[Input],
) -> Vec<T> {
input
.iter()
.map(|color| palette[self.palette_index(color)].clone())
.collect()
}
#[inline]
fn map_to_colors(&self, input: &[Input]) -> Vec<Self::Output> {
self.map_to_colors_of_palette(self.palette(), input)
}
}
impl<Input, R> IndexedColorMap<Input> for &R
where
R: IndexedColorMap<Input>,
{
type Output = R::Output;
#[inline]
fn into_palette(self) -> PaletteBuf<Self::Output> {
self.palette().to_owned()
}
#[inline]
fn palette(&self) -> &Palette<Self::Output> {
(*self).palette()
}
#[inline]
fn base_palette(&self) -> &Palette<Input> {
(*self).base_palette()
}
#[inline]
fn palette_color(&self, color: &Input) -> Self::Output {
(*self).palette_color(color)
}
#[inline]
fn palette_index(&self, color: &Input) -> u8 {
(*self).palette_index(color)
}
#[inline]
fn map_to_indices(&self, input: &[Input]) -> Vec<u8> {
(*self).map_to_indices(input)
}
fn map_to_colors_of_palette<T: Clone + Send + Sync>(
&self,
palette: &Palette<T>,
input: &[Input],
) -> Vec<T> {
(*self).map_to_colors_of_palette(palette, input)
}
#[inline]
fn map_to_colors(&self, input: &[Input]) -> Vec<Self::Output> {
(*self).map_to_colors(input)
}
}