Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs145
1 files changed, 7 insertions, 138 deletions
diff --git a/src/lib.rs b/src/lib.rs
index e948531..acf4e8b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,6 +1,9 @@
+#![allow(incomplete_features, internal_features)]
#![feature(
+ inline_const_pat,
const_option,
adt_const_params,
+ stmt_expr_attributes,
iter_array_chunks,
let_chains,
effects,
@@ -13,6 +16,10 @@
array_windows,
iter_map_windows
)]
+
+pub mod diffusion;
+pub mod ordered;
+
mod dumb;
mod kd;
use atools::prelude::*;
@@ -73,141 +80,3 @@ fn dither_with<const N: usize>(
) -> Image<Box<[f32]>, 4> {
dither(image, |((x, y), p)| f(((x % N, y % N), p)))
}
-const BLUE: Image<[f32; 1024 * 1024 * 3], 3> = unsafe {
- Image::new(
- std::num::NonZero::new(1024).unwrap(),
- std::num::NonZero::new(1024).unwrap(),
- std::mem::transmute(*include_bytes!("../blue.f32")),
- )
-};
-// todo: figure this out? seems off.
-pub fn remap_blue(image: Image<&[f32], 4>, palette: &[[f32; 4]]) -> Image<Box<[f32]>, 4> {
- let kd = map(palette);
- // Image::<Box<[u8]>, 3>::from(BLUE.as_ref()).show();
- dither(image, |((x, y), p)| {
- let (p, al) = p.pop();
- let noise = unsafe { BLUE.pixel(x as u32 % 1024, y as u32 % 1024) }.sub(0.5);
- let c = p.zip(noise).map(|(x, noise)| x + noise).join(al);
- palette[kd.find_nearest(c) as usize]
- })
-}
-
-pub fn remap_triangular(image: Image<&[f32], 4>, palette: &[[f32; 4]]) -> Image<Box<[f32]>, 4> {
- let kd = map(palette);
- dither(image, |((x, y), p)| {
- let (p, al) = p.pop();
- let noise = unsafe { BLUE.pixel(x as u32 % 1024, y as u32 % 1024) };
- let c = p
- .zip(noise)
- .map(|(x, noise)| {
- let noise = if x < (0.5 / 255.) || x > (254.5 / 255.) {
- noise - 0.5
- } else {
- if noise < 0.5 {
- (2.0 * noise).sqrt() - 1.0
- } else {
- 1.0 - (2.0 - 2.0 * noise).sqrt()
- }
- };
- x + noise
- })
- .join(al);
- palette[kd.find_nearest(c) as usize]
- })
-}
-
-pub fn remap_floyd_steinberg<const FAC: u8>(
- image: Image<&[f32], 4>,
- palette: &[[f32; 4]],
-) -> Image<Box<[f32]>, 4> {
- let kd = map(palette);
- let mut image =
- Image::build(image.width(), image.height()).buf(image.buffer().to_vec().into_boxed_slice());
- let w = image.width();
- let h = image.height();
- let fac = FAC as f32 * (1.0 / 255.0);
- let 七 = 7. / 16. * fac;
- let 三 = 3. / 16. * fac;
- let 五 = 5. / 16. * fac;
- let 一 = 1. / 16. * fac;
- for (x, y) in (0..h).flat_map(move |y| (0..w).map(move |x| (x, y))) {
- unsafe {
- let p = image.pixel(x, y);
- let new = palette[kd.find_nearest(p) as usize];
- *image.pixel_mut(x, y) = new;
- let error = p.asub(new);
- let f = |f| move |x: [f32; 4]| x.aadd(error.amul([f; 4]));
- image.replace(x + 1, y, f(七));
- image.replace(x.wrapping_sub(1), y + 1, f(三));
- image.replace(x, y + 1, f(五));
- image.replace(x + 1, y + 1, f(一));
- }
- }
- image
-}
-
-pub fn remap_atkinson(image: Image<&[f32], 4>, palette: &[[f32; 4]]) -> Image<Box<[f32]>, 4> {
- let kd = map(palette);
- let mut image =
- Image::build(image.width(), image.height()).buf(image.buffer().to_vec().into_boxed_slice());
- let w = image.width();
- let h = image.height();
- let eighth = [1. / 8.; 4];
- for (x, y) in (0..h).flat_map(move |y| (0..w).map(move |x| (x, y))) {
- unsafe {
- let p = image.pixel(x, y);
- let new = palette[kd.find_nearest(p) as usize];
- *image.pixel_mut(x, y) = new;
- let error = p.asub(new);
- let f = |x: [f32; 4]| x.aadd(error.amul(eighth));
- image.replace(x + 1, y, f);
- image.replace(x + 2, y, f);
-
- image.replace(x.wrapping_sub(1), y + 1, f);
- image.replace(x, y + 1, f);
- image.replace(x + 1, y + 1, f);
-
- image.replace(x, y + 2, f);
- }
- }
- image
-}
-
-pub fn remap_bayer_2x2(image: Image<&[f32], 4>, palette: &[[f32; 4]]) -> Image<Box<[f32]>, 4> {
- let kd = map(palette);
- let r = kd.space(palette);
- dither_with::<2>(image, |((x, y), &p)| {
- let color = p.add(r * BAYER_2X2[x + y * 2]);
- palette[kd.find_nearest(color) as usize]
- })
-}
-
-pub fn remap_bayer_4x4(image: Image<&[f32], 4>, palette: &[[f32; 4]]) -> Image<Box<[f32]>, 4> {
- let kd = map(palette);
- let r = kd.space(palette);
- dither_with::<4>(image, |((x, y), &p)| {
- let color = p.add(r * BAYER_4X4[x + y * 4]);
- palette[kd.find_nearest(color) as usize]
- })
-}
-
-pub fn remap_bayer_8x8(image: Image<&[f32], 4>, palette: &[[f32; 4]]) -> Image<Box<[f32]>, 4> {
- let kd = map(palette);
- let r = kd.space(palette);
- dither_with::<8>(image, |((x, y), &p)| {
- let color = p.add(r * BAYER_8X8[x + y * 8]);
- palette[kd.find_nearest(color) as usize]
- })
-}
-
-pub fn remap(image: Image<&[f32], 4>, palette: &[[f32; 4]]) -> Image<Box<[f32]>, 4> {
- let kd = map(palette);
- // todo!();
- Image::build(image.width(), image.height()).buf(
- image
- .chunked()
- .flat_map(|x| palette[kd.find_nearest(*x) as usize])
- // .map(|&x| palette.closest(x).1)
- .collect(),
- )
-}