From 0194f60ca3d2f8c329e35f1eed4db39202ed550c Mon Sep 17 00:00:00 2001 From: p6nj Date: Sun, 7 Jul 2024 08:19:23 +0200 Subject: [PATCH 01/15] finally a perfect ToSample trait! --- Cargo.toml | 4 ++ bent-funny-zone/Cargo.toml | 9 +++-- bent-funny-zone/src/main.rs | 72 +--------------------------------- bingus/Cargo.toml | 1 + bingus/src/lib.rs | 78 +++++++++++++------------------------ bingus/src/media.rs | 1 - 6 files changed, 38 insertions(+), 127 deletions(-) delete mode 100644 bingus/src/media.rs diff --git a/Cargo.toml b/Cargo.toml index 2fb99f0..bcf529e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,4 +9,8 @@ package.repository = "https://codeberg.org/p6nj/bent" package.keywords = ["databending", "data-bending", "bending", "bend", "art"] [workspace.dependencies] +fundsp = "0.18.2" +image = "0.24.9" +anyhow = "1.0.86" dasp_sample = "0.11.0" +bingus = { version = "0.1.0", path = "bingus" } diff --git a/bent-funny-zone/Cargo.toml b/bent-funny-zone/Cargo.toml index aec3e0f..20f92ae 100644 --- a/bent-funny-zone/Cargo.toml +++ b/bent-funny-zone/Cargo.toml @@ -11,7 +11,8 @@ keywords.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -anyhow = "1.0.86" -bmp = "0.5.0" -dasp_sample = "0.11.0" -fundsp = { version = "0.18.1", default-features = false, features = ["std"] } +image = { workspace = true } +fundsp = { workspace = true } +anyhow = { workspace = true } +dasp_sample = { workspace = true } +bingus = { workspace = true } diff --git a/bent-funny-zone/src/main.rs b/bent-funny-zone/src/main.rs index a4f4ea6..dfd2102 100644 --- a/bent-funny-zone/src/main.rs +++ b/bent-funny-zone/src/main.rs @@ -1,75 +1,7 @@ -use std::fs::File; - use anyhow::Result; -use bmp::{open, Pixel}; -use dasp_sample::{FromSample, Sample, ToSample, U24}; +use bingus::BytesToSample; fn main() -> Result<()> { - let mut bmp = open("bmp/bigsample.bmp")?; - for y in 0..bmp.get_height() { - for x in 0..bmp.get_width() { - if x > 100 && x < 300 { - bmp.set_pixel( - x, - y, - sample_to_rgb(rgb_to_sample::(bmp.get_pixel(x, y))), - ); - } - } - } - bmp.to_writer(&mut File::create("bmp/out.bmp")?)?; + dbg!([1u8, 2, 3].to_sample::()); Ok(()) } - -fn rgb_to_sample>(pix: Pixel) -> T { - (((U24::from(pix.r)) << 16.into()) | (U24::from(pix.g) << 8.into()) | U24::from(pix.b)) - .to_sample() -} - -fn sample_to_rgb>(sample: T) -> Pixel { - let rgb: U24 = sample.to_sample(); - let rgo = ((rgb) >> 8.into()) << 8.into(); - let roo = ((rgo) >> 16.into()) << 16.into(); - Pixel::new( - ((roo) >> 16.into()).inner() as u8, - ((rgo - roo) >> 8.into()).inner() as u8, - (rgb - rgo).inner() as u8, - ) -} - -#[cfg(test)] -mod tests { - use bmp::Pixel; - use dasp_sample::{Sample, I24, I48, U24, U48}; - - use super::{rgb_to_sample, sample_to_rgb}; - - #[test] - fn sample_convert_consistency() { - let original = U24::from(42); - assert_eq!(original.clone(), original.to_sample::().to_sample()) - } - - #[test] - fn rgb2s2rgb_type_consistency() { - let pix = Pixel::new(45, 18, 143); - assert_eq!( - sample_to_rgb(rgb_to_sample::(pix)), - sample_to_rgb(rgb_to_sample::(pix)) - ); - assert_eq!( - sample_to_rgb(rgb_to_sample::(pix)), - sample_to_rgb(rgb_to_sample::(pix)) - ); - assert_eq!( - sample_to_rgb(rgb_to_sample::(pix)), - sample_to_rgb(rgb_to_sample::(pix)) - ); - } - - #[test] - fn rgb2s2rgb() { - let pix = Pixel::new(45, 18, 143); - assert_eq!(pix, (sample_to_rgb(rgb_to_sample::(pix)))); - } -} diff --git a/bingus/Cargo.toml b/bingus/Cargo.toml index 8027b64..1548bfb 100644 --- a/bingus/Cargo.toml +++ b/bingus/Cargo.toml @@ -10,4 +10,5 @@ keywords.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +fundsp = { workspace = true } dasp_sample = { workspace = true } diff --git a/bingus/src/lib.rs b/bingus/src/lib.rs index a717ba8..8c9509a 100644 --- a/bingus/src/lib.rs +++ b/bingus/src/lib.rs @@ -1,61 +1,35 @@ +use std::{ + array, mem, + ops::{BitOr, Shl}, +}; + use dasp_sample::{FromSample, Sample, U24}; -mod media; +use fundsp::Real; -pub trait AsMedia { - fn as_media(self) -> T; -} +pub type Byte = u8; -pub trait AsSample +pub trait BytesToSample where - S: Sample, + Self: IntoIterator + Sized, + Ii: Iterator, + Ir: FromSample + + Sample + + Default + + From + + Shl + + BitOr, + It: Sample, { - fn as_sample(self) -> S; -} - -impl AsSample for u8 -where - S: Sample + FromSample, -{ - fn as_sample(self) -> S { - self.to_sample() - } -} - -impl AsSample for (u8, u8) -where - S: Sample + FromSample, -{ - fn as_sample(self) -> S { - (((self.0 as u16) << 8) | self.1 as u16).to_sample() - } -} - -impl AsSample for (u8, u8, u8) -where - S: Sample + FromSample, -{ - fn as_sample(self) -> S { - (((U24::from(self.0)) << 16.into()) | (U24::from(self.1) << 8.into()) | U24::from(self.2)) + fn to_sample(self) -> S + where + S: Real + Sample + FromSample, + { + self.into_iter() + .map(|it| Ir::from_sample(it)) + .reduce(|acc, ir| (acc << Ir::from(mem::size_of::() as u8 * 8u8)) | ir) + .unwrap() .to_sample() } } -impl AsSample for (u8, u8, u8, u8) -where - S: Sample + FromSample, -{ - fn as_sample(self) -> S { - (((self.0 as u32) << 24) | ((self.1 as u32) << 16) | ((self.2 as u32) << 8) | self.3 as u32) - .to_sample() - } -} - -impl AsMedia for T -where - T: AsSample, - S: Sample, -{ - fn as_media(self) -> S { - self.as_sample() - } -} +impl BytesToSample> for [Byte; 3] {} diff --git a/bingus/src/media.rs b/bingus/src/media.rs deleted file mode 100644 index 43abd1f..0000000 --- a/bingus/src/media.rs +++ /dev/null @@ -1 +0,0 @@ -pub struct Sample; From 1dec7aad5676a903ccf4af16fccb4b9d0127e028 Mon Sep 17 00:00:00 2001 From: p6nj Date: Sun, 7 Jul 2024 08:53:56 +0200 Subject: [PATCH 02/15] yay! macro! --- bingus/src/lib.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/bingus/src/lib.rs b/bingus/src/lib.rs index 8c9509a..adb5159 100644 --- a/bingus/src/lib.rs +++ b/bingus/src/lib.rs @@ -3,7 +3,7 @@ use std::{ ops::{BitOr, Shl}, }; -use dasp_sample::{FromSample, Sample, U24}; +use dasp_sample::{FromSample, Sample, U24, U48}; use fundsp::Real; pub type Byte = u8; @@ -32,4 +32,20 @@ where } } -impl BytesToSample> for [Byte; 3] {} +macro_rules! impl_bts_for_array_of { + ($($N:expr, $Ir:ty);*) => + { + $( + impl BytesToSample<$Ir, Byte, array::IntoIter> for [Byte; $N] {} + )* + } +} + +impl_bts_for_array_of! { + 1, u8; + 2, u16; + 3, U24; + 4, u32; + 6, U48; + 8, u64 +} From 14c98f484b7f0deffd2fb41e13cdd8a5481d98ca Mon Sep 17 00:00:00 2001 From: p6nj Date: Sun, 7 Jul 2024 12:12:58 +0200 Subject: [PATCH 03/15] reorganize bingus --- bent-funny-zone/src/main.rs | 2 +- bingus/src/convert.rs | 3 ++ bingus/src/convert/samples.rs | 6 ++++ bingus/src/convert/samples/from.rs | 1 + bingus/src/convert/samples/into.rs | 51 +++++++++++++++++++++++++++++ bingus/src/lib.rs | 52 +----------------------------- 6 files changed, 63 insertions(+), 52 deletions(-) create mode 100644 bingus/src/convert.rs create mode 100644 bingus/src/convert/samples.rs create mode 100644 bingus/src/convert/samples/from.rs create mode 100644 bingus/src/convert/samples/into.rs diff --git a/bent-funny-zone/src/main.rs b/bent-funny-zone/src/main.rs index dfd2102..c7e6a80 100644 --- a/bent-funny-zone/src/main.rs +++ b/bent-funny-zone/src/main.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use bingus::BytesToSample; +use bingus::convert::samples::BytesToSample; fn main() -> Result<()> { dbg!([1u8, 2, 3].to_sample::()); diff --git a/bingus/src/convert.rs b/bingus/src/convert.rs new file mode 100644 index 0000000..6d13bdb --- /dev/null +++ b/bingus/src/convert.rs @@ -0,0 +1,3 @@ +pub mod samples; + +pub type Byte = u8; diff --git a/bingus/src/convert/samples.rs b/bingus/src/convert/samples.rs new file mode 100644 index 0000000..bbbf6e7 --- /dev/null +++ b/bingus/src/convert/samples.rs @@ -0,0 +1,6 @@ +use super::Byte; + +mod from; +mod into; + +pub use into::BytesToSample; diff --git a/bingus/src/convert/samples/from.rs b/bingus/src/convert/samples/from.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/bingus/src/convert/samples/from.rs @@ -0,0 +1 @@ + diff --git a/bingus/src/convert/samples/into.rs b/bingus/src/convert/samples/into.rs new file mode 100644 index 0000000..0e626d6 --- /dev/null +++ b/bingus/src/convert/samples/into.rs @@ -0,0 +1,51 @@ +use std::{ + array, mem, + ops::{BitOr, Shl}, +}; + +use dasp_sample::{FromSample, Sample, U24, U48}; +use fundsp::Real; + +use super::Byte; + +pub trait BytesToSample +where + Self: IntoIterator + Sized, + Ii: Iterator, + Ir: FromSample + + Sample + + Default + + From + + Shl + + BitOr, + It: Sample, +{ + fn to_sample(self) -> S + where + S: Real + Sample + FromSample, + { + self.into_iter() + .map(|it| Ir::from_sample(it)) + .reduce(|acc, ir| (acc << Ir::from(mem::size_of::() as u8 * 8u8)) | ir) + .unwrap() + .to_sample() + } +} + +macro_rules! impl_bts_for_array_of { + ($($N:expr, $Ir:ty);*) => + { + $( + impl BytesToSample<$Ir, Byte, array::IntoIter> for [Byte; $N] {} + )* + } +} + +impl_bts_for_array_of! { + 1, u8; + 2, u16; + 3, U24; + 4, u32; + 6, U48; + 8, u64 +} diff --git a/bingus/src/lib.rs b/bingus/src/lib.rs index adb5159..b5b6721 100644 --- a/bingus/src/lib.rs +++ b/bingus/src/lib.rs @@ -1,51 +1 @@ -use std::{ - array, mem, - ops::{BitOr, Shl}, -}; - -use dasp_sample::{FromSample, Sample, U24, U48}; -use fundsp::Real; - -pub type Byte = u8; - -pub trait BytesToSample -where - Self: IntoIterator + Sized, - Ii: Iterator, - Ir: FromSample - + Sample - + Default - + From - + Shl - + BitOr, - It: Sample, -{ - fn to_sample(self) -> S - where - S: Real + Sample + FromSample, - { - self.into_iter() - .map(|it| Ir::from_sample(it)) - .reduce(|acc, ir| (acc << Ir::from(mem::size_of::() as u8 * 8u8)) | ir) - .unwrap() - .to_sample() - } -} - -macro_rules! impl_bts_for_array_of { - ($($N:expr, $Ir:ty);*) => - { - $( - impl BytesToSample<$Ir, Byte, array::IntoIter> for [Byte; $N] {} - )* - } -} - -impl_bts_for_array_of! { - 1, u8; - 2, u16; - 3, U24; - 4, u32; - 6, U48; - 8, u64 -} +pub mod convert; From 5c2607b574adaa8fb3e5e0038fd48954ee2dac73 Mon Sep 17 00:00:00 2001 From: p6nj Date: Wed, 10 Jul 2024 18:58:11 +0200 Subject: [PATCH 04/15] it works!! --- Cargo.toml | 2 +- bent-funny-zone/Cargo.toml | 1 - bent-funny-zone/src/main.rs | 36 +++++++++++++++++++-- bingus/Cargo.toml | 2 +- bingus/src/convert.rs | 3 -- bingus/src/convert/samples.rs | 6 ---- bingus/src/convert/samples/from.rs | 1 - bingus/src/convert/samples/into.rs | 51 ------------------------------ bingus/src/lib.rs | 2 +- 9 files changed, 37 insertions(+), 67 deletions(-) delete mode 100644 bingus/src/convert.rs delete mode 100644 bingus/src/convert/samples.rs delete mode 100644 bingus/src/convert/samples/from.rs delete mode 100644 bingus/src/convert/samples/into.rs diff --git a/Cargo.toml b/Cargo.toml index bcf529e..42856bd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,5 +12,5 @@ package.keywords = ["databending", "data-bending", "bending", "bend", "art"] fundsp = "0.18.2" image = "0.24.9" anyhow = "1.0.86" -dasp_sample = "0.11.0" bingus = { version = "0.1.0", path = "bingus" } +num-traits = "0.2.19" diff --git a/bent-funny-zone/Cargo.toml b/bent-funny-zone/Cargo.toml index 20f92ae..ccc2cda 100644 --- a/bent-funny-zone/Cargo.toml +++ b/bent-funny-zone/Cargo.toml @@ -14,5 +14,4 @@ keywords.workspace = true image = { workspace = true } fundsp = { workspace = true } anyhow = { workspace = true } -dasp_sample = { workspace = true } bingus = { workspace = true } diff --git a/bent-funny-zone/src/main.rs b/bent-funny-zone/src/main.rs index c7e6a80..16427a5 100644 --- a/bent-funny-zone/src/main.rs +++ b/bent-funny-zone/src/main.rs @@ -1,7 +1,39 @@ +use std::array; + use anyhow::Result; -use bingus::convert::samples::BytesToSample; +use fundsp::{ + hacker::{bell_hz, pipei, U12}, + math::db_amp, +}; +use image::io::Reader as ImageReader; fn main() -> Result<()> { - dbg!([1u8, 2, 3].to_sample::()); + let mut img = ImageReader::open("bmp/bigsample.bmp")?.decode()?.to_rgb8(); + let mut equalizer = + pipei::(|i| bell_hz(1000.0 + 1000.0 * i as f32, 1.0, db_amp(0.0))); + img.to_vec() + .chunks_exact(3) + .map(|px: &[u8]| f32::from_ne_bytes(array::from_fn(|i| px[i % px.len()]))) + .map(|x| equalizer.filter_mono(x)) + .flat_map(|px| -> [u8; 3] { + let px = px.to_ne_bytes(); + array::from_fn(move |i| px[i]) + }) + .zip(img.as_mut()) + .for_each(|(filtered, original)| *original = filtered); + img.save("bmp/out.bmp")?; + + // let bytes: Vec = (1u8..7).into_iter().collect(); + // assert_eq!( + // bytes, + // bytes + // .chunks_exact(3) + // .map(|px: &[u8]| f64::from_ne_bytes(array::from_fn(|i| px[i % px.len()]))) + // .flat_map(|px: f64| -> [u8; 3] { + // let px = px.to_ne_bytes(); + // array::from_fn(move |i| px[i]) + // }) + // .collect::>() + // ); Ok(()) } diff --git a/bingus/Cargo.toml b/bingus/Cargo.toml index 1548bfb..8ee8c05 100644 --- a/bingus/Cargo.toml +++ b/bingus/Cargo.toml @@ -11,4 +11,4 @@ keywords.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] fundsp = { workspace = true } -dasp_sample = { workspace = true } +num-traits = { workspace = true } diff --git a/bingus/src/convert.rs b/bingus/src/convert.rs deleted file mode 100644 index 6d13bdb..0000000 --- a/bingus/src/convert.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod samples; - -pub type Byte = u8; diff --git a/bingus/src/convert/samples.rs b/bingus/src/convert/samples.rs deleted file mode 100644 index bbbf6e7..0000000 --- a/bingus/src/convert/samples.rs +++ /dev/null @@ -1,6 +0,0 @@ -use super::Byte; - -mod from; -mod into; - -pub use into::BytesToSample; diff --git a/bingus/src/convert/samples/from.rs b/bingus/src/convert/samples/from.rs deleted file mode 100644 index 8b13789..0000000 --- a/bingus/src/convert/samples/from.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/bingus/src/convert/samples/into.rs b/bingus/src/convert/samples/into.rs deleted file mode 100644 index 0e626d6..0000000 --- a/bingus/src/convert/samples/into.rs +++ /dev/null @@ -1,51 +0,0 @@ -use std::{ - array, mem, - ops::{BitOr, Shl}, -}; - -use dasp_sample::{FromSample, Sample, U24, U48}; -use fundsp::Real; - -use super::Byte; - -pub trait BytesToSample -where - Self: IntoIterator + Sized, - Ii: Iterator, - Ir: FromSample - + Sample - + Default - + From - + Shl - + BitOr, - It: Sample, -{ - fn to_sample(self) -> S - where - S: Real + Sample + FromSample, - { - self.into_iter() - .map(|it| Ir::from_sample(it)) - .reduce(|acc, ir| (acc << Ir::from(mem::size_of::() as u8 * 8u8)) | ir) - .unwrap() - .to_sample() - } -} - -macro_rules! impl_bts_for_array_of { - ($($N:expr, $Ir:ty);*) => - { - $( - impl BytesToSample<$Ir, Byte, array::IntoIter> for [Byte; $N] {} - )* - } -} - -impl_bts_for_array_of! { - 1, u8; - 2, u16; - 3, U24; - 4, u32; - 6, U48; - 8, u64 -} diff --git a/bingus/src/lib.rs b/bingus/src/lib.rs index b5b6721..8b13789 100644 --- a/bingus/src/lib.rs +++ b/bingus/src/lib.rs @@ -1 +1 @@ -pub mod convert; + From 5d39e227b66651118bff6652cd4bdf03652162ca Mon Sep 17 00:00:00 2001 From: p6nj Date: Thu, 11 Jul 2024 17:45:55 +0200 Subject: [PATCH 05/15] file picker, progress bar, perf enhancements --- .gitignore | 2 +- Cargo.toml | 4 ++ bent-funny-zone/Cargo.toml | 6 ++ bent-funny-zone/src/main.rs | 124 ++++++++++++++++++++++++++++++------ 4 files changed, 114 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index 55d94da..249bc38 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ /target *.lock -bmp/out.bmp +bmp/out.* diff --git a/Cargo.toml b/Cargo.toml index 42856bd..704f945 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,3 +14,7 @@ image = "0.24.9" anyhow = "1.0.86" bingus = { version = "0.1.0", path = "bingus" } num-traits = "0.2.19" +dasp_sample = "0.11.0" +rayon = "1.10.0" +dirs = "5.0.1" +rfd = "0.14.1" diff --git a/bent-funny-zone/Cargo.toml b/bent-funny-zone/Cargo.toml index ccc2cda..6306660 100644 --- a/bent-funny-zone/Cargo.toml +++ b/bent-funny-zone/Cargo.toml @@ -15,3 +15,9 @@ image = { workspace = true } fundsp = { workspace = true } anyhow = { workspace = true } bingus = { workspace = true } +dasp_sample = { workspace = true } +rayon = { workspace = true } +dirs = { workspace = true } +rfd = { workspace = true } +derive-new = "0.6.0" +indicatif = { version = "0.17.8", features = ["rayon"] } diff --git a/bent-funny-zone/src/main.rs b/bent-funny-zone/src/main.rs index 16427a5..e04dc8b 100644 --- a/bent-funny-zone/src/main.rs +++ b/bent-funny-zone/src/main.rs @@ -1,27 +1,102 @@ -use std::array; +use std::path::PathBuf; -use anyhow::Result; -use fundsp::{ - hacker::{bell_hz, pipei, U12}, - math::db_amp, -}; -use image::io::Reader as ImageReader; +use anyhow::{Context, Result}; +use dasp_sample::{Sample, U24}; +use derive_new::new; +use dirs::{download_dir, home_dir, picture_dir}; +use fundsp::math::uparc; +use image::{io::Reader as ImageReader, ImageBuffer, ImageFormat, Rgb}; +use indicatif::{ParallelProgressIterator, ProgressStyle}; +use rayon::{iter::ParallelIterator, slice::ParallelSlice}; +use rfd::FileDialog; + +struct Files { + input: PathBuf, + output: PathBuf, +} + +#[derive(new)] +struct DataPath { + files: Files, +} + +impl Files { + fn try_new(input: PathBuf, output: PathBuf) -> Result { + Ok(Files { + input: Self::verify_image_file(input, "input")?, + output: Self::verify_image_file(output, "output")?, + }) + } + fn verify_image_file(path: PathBuf, label: &'static str) -> Result { + ImageFormat::from_path(&path).with_context(|| { + format!("your {label} image must have a supported extension from this list:") + + &ImageFormat::all() + .map(|format| { + format!( + "\n\t{:?} ({})", + format, + format + .extensions_str() + .iter() + .fold(String::new(), |acc, x| acc + &format!(".{x}, ")) + .strip_suffix(", ") + .unwrap() + ) + }) + .reduce(|acc, x| acc + &x) + .unwrap() + })?; + Ok(path) + } + fn prompt() -> Result { + Files::try_new( + FileDialog::new() + .set_title("Input image") + .set_directory(working_dir()) + .pick_file() + .context("no input image selected")?, + FileDialog::new() + .set_title("Output image") + .set_directory(working_dir()) + .save_file() + .context("no output filename provided")?, + ) + } +} fn main() -> Result<()> { - let mut img = ImageReader::open("bmp/bigsample.bmp")?.decode()?.to_rgb8(); - let mut equalizer = - pipei::(|i| bell_hz(1000.0 + 1000.0 * i as f32, 1.0, db_amp(0.0))); - img.to_vec() - .chunks_exact(3) - .map(|px: &[u8]| f32::from_ne_bytes(array::from_fn(|i| px[i % px.len()]))) - .map(|x| equalizer.filter_mono(x)) - .flat_map(|px| -> [u8; 3] { - let px = px.to_ne_bytes(); - array::from_fn(move |i| px[i]) - }) - .zip(img.as_mut()) - .for_each(|(filtered, original)| *original = filtered); - img.save("bmp/out.bmp")?; + let dp = DataPath::new(Files::prompt()?); + let img = ImageReader::open(dp.files.input)? + .decode() + .context("can't use this picture")? + .to_rgb8(); + let (width, height) = (img.width(), img.height()); + let processed: ImageBuffer, Vec> = ImageBuffer::from_raw( + width, + height, + img.into_raw() + .par_chunks_exact(3) + .progress_count((width * height).into()) + .with_style(ProgressStyle::with_template( + "[{eta}] {bar:40.green/red} {pos}/{len} pixels", + )?) + .map(|px: &[u8]| (px[2] as i32) | ((px[1] as i32) << 8) | ((px[0] as i32) << 16)) + .map(|px| U24::new_unchecked(px)) + .map(|x| uparc(x.to_sample())) + .flat_map(|sample: f32| { + let rgb: U24 = sample.to_sample(); + let rgo = ((rgb) >> 8.into()) << 8.into(); + let roo = ((rgo) >> 16.into()) << 16.into(); + [ + ((roo) >> 16.into()).inner() as u8, + ((rgo - roo) >> 8.into()).inner() as u8, + (rgb - rgo).inner() as u8, + ] + }) + .collect(), + ) + .unwrap(); + processed.save(dp.files.output)?; // let bytes: Vec = (1u8..7).into_iter().collect(); // assert_eq!( @@ -37,3 +112,10 @@ fn main() -> Result<()> { // ); Ok(()) } + +fn working_dir() -> PathBuf { + picture_dir() + .or(download_dir()) + .or(home_dir()) + .unwrap_or("/".into()) +} From e34287df9ed570816c6c4a1f034719c7f6de6654 Mon Sep 17 00:00:00 2001 From: p6nj Date: Sat, 13 Jul 2024 09:07:50 +0200 Subject: [PATCH 06/15] RawData, clippy --- Cargo.toml | 3 +++ bent-funny-zone/Cargo.toml | 5 ++-- bent-funny-zone/src/main.rs | 2 +- bingus/src/lib.rs | 49 +++++++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 704f945..56117cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,3 +18,6 @@ dasp_sample = "0.11.0" rayon = "1.10.0" dirs = "5.0.1" rfd = "0.14.1" +derive-new = "0.6.0" +infer = "0.16.0" +indicatif = { version = "0.17.8", features = ["rayon"] } diff --git a/bent-funny-zone/Cargo.toml b/bent-funny-zone/Cargo.toml index 6306660..1d7e5a2 100644 --- a/bent-funny-zone/Cargo.toml +++ b/bent-funny-zone/Cargo.toml @@ -19,5 +19,6 @@ dasp_sample = { workspace = true } rayon = { workspace = true } dirs = { workspace = true } rfd = { workspace = true } -derive-new = "0.6.0" -indicatif = { version = "0.17.8", features = ["rayon"] } +derive-new = { workspace = true } +infer = { workspace = true } +indicatif = { workspace = true } diff --git a/bent-funny-zone/src/main.rs b/bent-funny-zone/src/main.rs index e04dc8b..733408a 100644 --- a/bent-funny-zone/src/main.rs +++ b/bent-funny-zone/src/main.rs @@ -81,7 +81,7 @@ fn main() -> Result<()> { "[{eta}] {bar:40.green/red} {pos}/{len} pixels", )?) .map(|px: &[u8]| (px[2] as i32) | ((px[1] as i32) << 8) | ((px[0] as i32) << 16)) - .map(|px| U24::new_unchecked(px)) + .map(U24::new_unchecked) .map(|x| uparc(x.to_sample())) .flat_map(|sample: f32| { let rgb: U24 = sample.to_sample(); diff --git a/bingus/src/lib.rs b/bingus/src/lib.rs index 8b13789..ce40a72 100644 --- a/bingus/src/lib.rs +++ b/bingus/src/lib.rs @@ -1 +1,50 @@ +use std::{borrow::Cow, ops::Deref}; +type Bytes<'a> = Cow<'a, [u8]>; + +pub trait Metadata {} + +pub struct RawData<'a, M: Metadata> { + pub(crate) data: Bytes<'a>, + pub(crate) metadata: M, +} + +impl<'a, M> RawData<'a, M> +where + M: Metadata, +{ + fn metadata(&self) -> &M { + &self.metadata + } +} + +impl<'a, M> Deref for RawData<'a, M> +where + M: Metadata, +{ + type Target = Bytes<'a>; + fn deref(&self) -> &Self::Target { + &self.data + } +} + +impl<'a, M> From> for Vec +where + M: Metadata, +{ + fn from(value: RawData<'a, M>) -> Self { + value.data.into_owned() + } +} + +impl<'a, M> Clone for RawData<'a, M> +where + M: Metadata + Clone, +{ + fn clone(&self) -> Self { + Self { + data: self.data.clone(), + metadata: self.metadata().clone(), + } + } +} From 825bcfa5a1b61bea306e687dc6b34eb08448c085 Mon Sep 17 00:00:00 2001 From: p6nj Date: Sat, 13 Jul 2024 10:05:27 +0200 Subject: [PATCH 07/15] RawImage --- bingus/Cargo.toml | 4 ++-- bingus/src/lib.rs | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/bingus/Cargo.toml b/bingus/Cargo.toml index 8ee8c05..00acf16 100644 --- a/bingus/Cargo.toml +++ b/bingus/Cargo.toml @@ -10,5 +10,5 @@ keywords.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -fundsp = { workspace = true } -num-traits = { workspace = true } +image = { workspace = true } +derive-new = { workspace = true } diff --git a/bingus/src/lib.rs b/bingus/src/lib.rs index ce40a72..2a54c04 100644 --- a/bingus/src/lib.rs +++ b/bingus/src/lib.rs @@ -1,5 +1,8 @@ use std::{borrow::Cow, ops::Deref}; +use derive_new::new; +use image::{DynamicImage, RgbImage}; + type Bytes<'a> = Cow<'a, [u8]>; pub trait Metadata {} @@ -48,3 +51,38 @@ where } } } + +#[derive(new)] +pub struct ImageMetadata { + width: u32, + height: u32, +} +impl Metadata for ImageMetadata {} +pub type RawImage<'a> = RawData<'a, ImageMetadata>; + +impl From for RawImage<'_> { + fn from(value: DynamicImage) -> Self { + value.to_rgb8().into() + } +} + +impl From for RawImage<'_> { + fn from(value: RgbImage) -> Self { + let metadata = ImageMetadata::new(value.width(), value.height()); + Self { + data: Cow::Owned(value.into_raw()), + metadata, + } + } +} + +impl<'a> From> for RgbImage { + fn from(value: RawImage<'a>) -> Self { + RgbImage::from_raw( + value.metadata.width, + value.metadata.height, + value.data.to_vec(), + ) + .unwrap() + } +} From a0d82499c0ff83e4d8b2267f52cf561421205f5d Mon Sep 17 00:00:00 2001 From: p6nj Date: Sun, 14 Jul 2024 07:57:40 +0200 Subject: [PATCH 08/15] reorganize lib, use it in the funny zone --- Cargo.toml | 1 + bent-funny-zone/src/main.rs | 28 +++++------ bingus/Cargo.toml | 1 + bingus/src/lib.rs | 89 +--------------------------------- bingus/src/rawdata.rs | 48 ++++++++++++++++++ bingus/src/rawdata/rgbimage.rs | 42 ++++++++++++++++ 6 files changed, 106 insertions(+), 103 deletions(-) create mode 100644 bingus/src/rawdata.rs create mode 100644 bingus/src/rawdata/rgbimage.rs diff --git a/Cargo.toml b/Cargo.toml index 56117cb..f0a268c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,3 +21,4 @@ rfd = "0.14.1" derive-new = "0.6.0" infer = "0.16.0" indicatif = { version = "0.17.8", features = ["rayon"] } +getset = "0.1.2" diff --git a/bent-funny-zone/src/main.rs b/bent-funny-zone/src/main.rs index 733408a..8681dac 100644 --- a/bent-funny-zone/src/main.rs +++ b/bent-funny-zone/src/main.rs @@ -1,11 +1,12 @@ use std::path::PathBuf; use anyhow::{Context, Result}; +use bingus::rawdata::rgbimage::RawImage; use dasp_sample::{Sample, U24}; use derive_new::new; use dirs::{download_dir, home_dir, picture_dir}; use fundsp::math::uparc; -use image::{io::Reader as ImageReader, ImageBuffer, ImageFormat, Rgb}; +use image::{io::Reader as ImageReader, ImageFormat, RgbImage}; use indicatif::{ParallelProgressIterator, ProgressStyle}; use rayon::{iter::ParallelIterator, slice::ParallelSlice}; use rfd::FileDialog; @@ -66,17 +67,15 @@ impl Files { fn main() -> Result<()> { let dp = DataPath::new(Files::prompt()?); - let img = ImageReader::open(dp.files.input)? - .decode() - .context("can't use this picture")? - .to_rgb8(); - let (width, height) = (img.width(), img.height()); - let processed: ImageBuffer, Vec> = ImageBuffer::from_raw( - width, - height, - img.into_raw() - .par_chunks_exact(3) - .progress_count((width * height).into()) + let img = RawImage::from( + ImageReader::open(dp.files.input)? + .decode() + .context("can't use this picture")?, + ); + let processed = RawImage::new( + *img.metadata(), + img.par_chunks_exact(3) + .progress_count((img.metadata().width() * img.metadata().height()).into()) .with_style(ProgressStyle::with_template( "[{eta}] {bar:40.green/red} {pos}/{len} pixels", )?) @@ -94,9 +93,8 @@ fn main() -> Result<()> { ] }) .collect(), - ) - .unwrap(); - processed.save(dp.files.output)?; + ); + RgbImage::from(processed).save(dp.files.output)?; // let bytes: Vec = (1u8..7).into_iter().collect(); // assert_eq!( diff --git a/bingus/Cargo.toml b/bingus/Cargo.toml index 00acf16..f51bb2c 100644 --- a/bingus/Cargo.toml +++ b/bingus/Cargo.toml @@ -12,3 +12,4 @@ keywords.workspace = true [dependencies] image = { workspace = true } derive-new = { workspace = true } +getset = { workspace = true } diff --git a/bingus/src/lib.rs b/bingus/src/lib.rs index 2a54c04..83808c4 100644 --- a/bingus/src/lib.rs +++ b/bingus/src/lib.rs @@ -1,88 +1 @@ -use std::{borrow::Cow, ops::Deref}; - -use derive_new::new; -use image::{DynamicImage, RgbImage}; - -type Bytes<'a> = Cow<'a, [u8]>; - -pub trait Metadata {} - -pub struct RawData<'a, M: Metadata> { - pub(crate) data: Bytes<'a>, - pub(crate) metadata: M, -} - -impl<'a, M> RawData<'a, M> -where - M: Metadata, -{ - fn metadata(&self) -> &M { - &self.metadata - } -} - -impl<'a, M> Deref for RawData<'a, M> -where - M: Metadata, -{ - type Target = Bytes<'a>; - fn deref(&self) -> &Self::Target { - &self.data - } -} - -impl<'a, M> From> for Vec -where - M: Metadata, -{ - fn from(value: RawData<'a, M>) -> Self { - value.data.into_owned() - } -} - -impl<'a, M> Clone for RawData<'a, M> -where - M: Metadata + Clone, -{ - fn clone(&self) -> Self { - Self { - data: self.data.clone(), - metadata: self.metadata().clone(), - } - } -} - -#[derive(new)] -pub struct ImageMetadata { - width: u32, - height: u32, -} -impl Metadata for ImageMetadata {} -pub type RawImage<'a> = RawData<'a, ImageMetadata>; - -impl From for RawImage<'_> { - fn from(value: DynamicImage) -> Self { - value.to_rgb8().into() - } -} - -impl From for RawImage<'_> { - fn from(value: RgbImage) -> Self { - let metadata = ImageMetadata::new(value.width(), value.height()); - Self { - data: Cow::Owned(value.into_raw()), - metadata, - } - } -} - -impl<'a> From> for RgbImage { - fn from(value: RawImage<'a>) -> Self { - RgbImage::from_raw( - value.metadata.width, - value.metadata.height, - value.data.to_vec(), - ) - .unwrap() - } -} +pub mod rawdata; diff --git a/bingus/src/rawdata.rs b/bingus/src/rawdata.rs new file mode 100644 index 0000000..98498d5 --- /dev/null +++ b/bingus/src/rawdata.rs @@ -0,0 +1,48 @@ +use std::{borrow::Cow, ops::Deref}; + +use derive_new::new; +use getset::Getters; + +pub mod rgbimage; + +type Bytes<'a> = Cow<'a, [u8]>; + +pub trait Metadata {} + +#[derive(new, Getters)] +pub struct RawData<'a, M: Metadata> { + #[getset(get = "pub")] + pub(crate) metadata: M, + pub(crate) data: Bytes<'a>, +} + +impl<'a, M> From> for Vec +where + M: Metadata, +{ + fn from(value: RawData<'a, M>) -> Self { + value.data.into_owned() + } +} + +impl<'a, M> Clone for RawData<'a, M> +where + M: Metadata + Clone, +{ + fn clone(&self) -> Self { + Self { + data: self.data.clone(), + metadata: self.metadata().clone(), + } + } +} + +impl<'a, M> Deref for RawData<'a, M> +where + M: Metadata, +{ + type Target = Bytes<'a>; + fn deref(&self) -> &Self::Target { + &self.data + } +} diff --git a/bingus/src/rawdata/rgbimage.rs b/bingus/src/rawdata/rgbimage.rs new file mode 100644 index 0000000..f5daf9c --- /dev/null +++ b/bingus/src/rawdata/rgbimage.rs @@ -0,0 +1,42 @@ +use derive_new::new; +use getset::Getters; +use image::{DynamicImage, RgbImage}; + +use super::*; + +#[derive(new, Getters, Clone, Copy)] +pub struct ImageMetadata { + #[getset(get = "pub")] + width: u32, + #[getset(get = "pub")] + height: u32, +} +impl Metadata for ImageMetadata {} +pub type RawImage<'a> = RawData<'a, ImageMetadata>; + +impl From for RawImage<'_> { + fn from(value: DynamicImage) -> Self { + value.to_rgb8().into() + } +} + +impl From for RawImage<'_> { + fn from(value: RgbImage) -> Self { + let metadata = ImageMetadata::new(value.width(), value.height()); + Self { + data: Cow::Owned(value.into_raw()), + metadata, + } + } +} + +impl<'a> From> for RgbImage { + fn from(value: RawImage<'a>) -> Self { + RgbImage::from_raw( + value.metadata.width, + value.metadata.height, + value.data.to_vec(), + ) + .unwrap() + } +} From c56b0b6227578485975ba384d2dd716e418f2348 Mon Sep 17 00:00:00 2001 From: p6nj Date: Sun, 14 Jul 2024 17:35:44 +0200 Subject: [PATCH 09/15] simplify lib towards simple wrapper --- bent-funny-zone/src/main.rs | 55 ++++++++++++++++++---------------- bingus/src/rawdata.rs | 42 ++++++++++---------------- bingus/src/rawdata/rgbimage.rs | 42 -------------------------- 3 files changed, 45 insertions(+), 94 deletions(-) delete mode 100644 bingus/src/rawdata/rgbimage.rs diff --git a/bent-funny-zone/src/main.rs b/bent-funny-zone/src/main.rs index 8681dac..563303f 100644 --- a/bent-funny-zone/src/main.rs +++ b/bent-funny-zone/src/main.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; use anyhow::{Context, Result}; -use bingus::rawdata::rgbimage::RawImage; +use bingus::rawdata::RawData; use dasp_sample::{Sample, U24}; use derive_new::new; use dirs::{download_dir, home_dir, picture_dir}; @@ -67,34 +67,39 @@ impl Files { fn main() -> Result<()> { let dp = DataPath::new(Files::prompt()?); - let img = RawImage::from( + let img = RawData::::new( ImageReader::open(dp.files.input)? .decode() - .context("can't use this picture")?, + .context("can't use this picture")? + .into_rgb8(), ); - let processed = RawImage::new( - *img.metadata(), - img.par_chunks_exact(3) - .progress_count((img.metadata().width() * img.metadata().height()).into()) - .with_style(ProgressStyle::with_template( - "[{eta}] {bar:40.green/red} {pos}/{len} pixels", - )?) - .map(|px: &[u8]| (px[2] as i32) | ((px[1] as i32) << 8) | ((px[0] as i32) << 16)) - .map(U24::new_unchecked) - .map(|x| uparc(x.to_sample())) - .flat_map(|sample: f32| { - let rgb: U24 = sample.to_sample(); - let rgo = ((rgb) >> 8.into()) << 8.into(); - let roo = ((rgo) >> 16.into()) << 16.into(); - [ - ((roo) >> 16.into()).inner() as u8, - ((rgo - roo) >> 8.into()).inner() as u8, - (rgb - rgo).inner() as u8, - ] - }) - .collect(), + let processed = RawData::::new( + RgbImage::from_raw( + img.width(), + img.height(), + img.par_chunks_exact(3) + .progress_count((img.width() * img.height()).into()) + .with_style(ProgressStyle::with_template( + "[{eta}] {bar:40.green/red} {pos}/{len} pixels", + )?) + .map(|px: &[u8]| (px[2] as i32) | ((px[1] as i32) << 8) | ((px[0] as i32) << 16)) + .map(U24::new_unchecked) + .map(|x| uparc(x.to_sample())) + .flat_map(|sample: f32| { + let rgb: U24 = sample.to_sample(); + let rgo = ((rgb) >> 8.into()) << 8.into(); + let roo = ((rgo) >> 16.into()) << 16.into(); + [ + ((roo) >> 16.into()).inner() as u8, + ((rgo - roo) >> 8.into()).inner() as u8, + (rgb - rgo).inner() as u8, + ] + }) + .collect(), + ) + .unwrap(), ); - RgbImage::from(processed).save(dp.files.output)?; + processed.save(dp.files.output)?; // let bytes: Vec = (1u8..7).into_iter().collect(); // assert_eq!( diff --git a/bingus/src/rawdata.rs b/bingus/src/rawdata.rs index 98498d5..d0ac87b 100644 --- a/bingus/src/rawdata.rs +++ b/bingus/src/rawdata.rs @@ -1,48 +1,36 @@ -use std::{borrow::Cow, ops::Deref}; +use std::ops::Deref; use derive_new::new; -use getset::Getters; -pub mod rgbimage; +pub type Bytes = [u8]; -type Bytes<'a> = Cow<'a, [u8]>; +#[derive(new)] +pub struct RawData>(D); -pub trait Metadata {} - -#[derive(new, Getters)] -pub struct RawData<'a, M: Metadata> { - #[getset(get = "pub")] - pub(crate) metadata: M, - pub(crate) data: Bytes<'a>, -} - -impl<'a, M> From> for Vec +impl From> for Vec where - M: Metadata, + D: Deref, { - fn from(value: RawData<'a, M>) -> Self { - value.data.into_owned() + fn from(value: RawData) -> Self { + value.to_owned() } } -impl<'a, M> Clone for RawData<'a, M> +impl Clone for RawData where - M: Metadata + Clone, + D: Clone + Deref, { fn clone(&self) -> Self { - Self { - data: self.data.clone(), - metadata: self.metadata().clone(), - } + Self(self.deref().clone()) } } -impl<'a, M> Deref for RawData<'a, M> +impl Deref for RawData where - M: Metadata, + D: Deref, { - type Target = Bytes<'a>; + type Target = D; fn deref(&self) -> &Self::Target { - &self.data + &self.0 } } diff --git a/bingus/src/rawdata/rgbimage.rs b/bingus/src/rawdata/rgbimage.rs deleted file mode 100644 index f5daf9c..0000000 --- a/bingus/src/rawdata/rgbimage.rs +++ /dev/null @@ -1,42 +0,0 @@ -use derive_new::new; -use getset::Getters; -use image::{DynamicImage, RgbImage}; - -use super::*; - -#[derive(new, Getters, Clone, Copy)] -pub struct ImageMetadata { - #[getset(get = "pub")] - width: u32, - #[getset(get = "pub")] - height: u32, -} -impl Metadata for ImageMetadata {} -pub type RawImage<'a> = RawData<'a, ImageMetadata>; - -impl From for RawImage<'_> { - fn from(value: DynamicImage) -> Self { - value.to_rgb8().into() - } -} - -impl From for RawImage<'_> { - fn from(value: RgbImage) -> Self { - let metadata = ImageMetadata::new(value.width(), value.height()); - Self { - data: Cow::Owned(value.into_raw()), - metadata, - } - } -} - -impl<'a> From> for RgbImage { - fn from(value: RawImage<'a>) -> Self { - RgbImage::from_raw( - value.metadata.width, - value.metadata.height, - value.data.to_vec(), - ) - .unwrap() - } -} From 3315342aa514f1d9dc7a495e7ba76217d98da987 Mon Sep 17 00:00:00 2001 From: p6nj Date: Sat, 20 Jul 2024 21:13:30 +0200 Subject: [PATCH 10/15] image fix came out --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f0a268c..5f867f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ package.keywords = ["databending", "data-bending", "bending", "bend", "art"] [workspace.dependencies] fundsp = "0.18.2" -image = "0.24.9" +image = "0.25.1" anyhow = "1.0.86" bingus = { version = "0.1.0", path = "bingus" } num-traits = "0.2.19" From ba055093be9ed663bbab5f881d63606f4457d674 Mon Sep 17 00:00:00 2001 From: p6nj Date: Tue, 23 Jul 2024 17:47:18 +0200 Subject: [PATCH 11/15] image filter --- bent-funny-zone/src/main.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/bent-funny-zone/src/main.rs b/bent-funny-zone/src/main.rs index 563303f..22e1e15 100644 --- a/bent-funny-zone/src/main.rs +++ b/bent-funny-zone/src/main.rs @@ -54,6 +54,13 @@ impl Files { FileDialog::new() .set_title("Input image") .set_directory(working_dir()) + .add_filter( + "images", + &ImageFormat::all() + .map(ImageFormat::extensions_str) + .flatten() + .collect::>(), + ) .pick_file() .context("no input image selected")?, FileDialog::new() From f8ed6d2ce11216fcee46f448b24a7adf6392da7d Mon Sep 17 00:00:00 2001 From: p6nj Date: Tue, 23 Jul 2024 17:50:26 +0200 Subject: [PATCH 12/15] prepare for cargo publish --- bingus/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bingus/Cargo.toml b/bingus/Cargo.toml index f51bb2c..3170a44 100644 --- a/bingus/Cargo.toml +++ b/bingus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bingus" -version = "0.1.0" +version = "0.1.1" edition.workspace = true license.workspace = true description.workspace = true From ff3a6ee5fc335f4b857450edd96f3b1d22a16377 Mon Sep 17 00:00:00 2001 From: p6nj Date: Tue, 23 Jul 2024 17:53:07 +0200 Subject: [PATCH 13/15] clean bingus deps --- bingus/Cargo.toml | 4 +--- bingus/src/lib.rs | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/bingus/Cargo.toml b/bingus/Cargo.toml index 3170a44..5f28930 100644 --- a/bingus/Cargo.toml +++ b/bingus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bingus" -version = "0.1.1" +version = "0.1.2" edition.workspace = true license.workspace = true description.workspace = true @@ -10,6 +10,4 @@ keywords.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -image = { workspace = true } derive-new = { workspace = true } -getset = { workspace = true } diff --git a/bingus/src/lib.rs b/bingus/src/lib.rs index 83808c4..e295326 100644 --- a/bingus/src/lib.rs +++ b/bingus/src/lib.rs @@ -1 +1,2 @@ +#![forbid(unused_crate_dependencies)] pub mod rawdata; From d994f316a7d706118613a26ad5b00ae1c0dcc118 Mon Sep 17 00:00:00 2001 From: p6nj Date: Sat, 27 Jul 2024 07:26:19 +0200 Subject: [PATCH 14/15] add licenses --- LICENSE | 24 ++++++++++++++++++++++++ bent/LICENSE | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 LICENSE create mode 100644 bent/LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..68a49da --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/bent/LICENSE b/bent/LICENSE new file mode 100644 index 0000000..68a49da --- /dev/null +++ b/bent/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to From 95aaed66e789b2001413fd85f8fd2b67b43dce02 Mon Sep 17 00:00:00 2001 From: p6nj Date: Sat, 27 Jul 2024 08:35:40 +0200 Subject: [PATCH 15/15] vanilla wasm_bindgen bent --- bent/Cargo.toml | 7 +++++++ bent/assets/bent.svg | 12 ++++++++++++ bent/assets/path-generator.py | 15 +++++++++++++++ bent/index.html | 36 +++++++++++++++++++++++++++++++++++ bent/src/js.rs | 7 +++++++ bent/src/lib.rs | 10 ++++++++++ bent/src/macros.rs | 27 ++++++++++++++++++++++++++ bent/src/main.rs | 3 --- 8 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 bent/assets/bent.svg create mode 100644 bent/assets/path-generator.py create mode 100644 bent/index.html create mode 100644 bent/src/js.rs create mode 100644 bent/src/lib.rs create mode 100644 bent/src/macros.rs delete mode 100644 bent/src/main.rs diff --git a/bent/Cargo.toml b/bent/Cargo.toml index 7c3fd50..e00aed4 100644 --- a/bent/Cargo.toml +++ b/bent/Cargo.toml @@ -10,4 +10,11 @@ keywords.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +crate-type = ["cdylib"] + [dependencies] +wasm-bindgen = "0.2" + +[profile.release] +lto = true diff --git a/bent/assets/bent.svg b/bent/assets/bent.svg new file mode 100644 index 0000000..60b8b98 --- /dev/null +++ b/bent/assets/bent.svg @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/bent/assets/path-generator.py b/bent/assets/path-generator.py new file mode 100644 index 0000000..1af8d68 --- /dev/null +++ b/bent/assets/path-generator.py @@ -0,0 +1,15 @@ +p = lambda x: print(x, end=" ") + + +def line(coords: tuple[tuple[int]]): + p(f"M {coords[0][0]} {coords[0][1]} L {coords[1][0]} {coords[1][1]}") + + +n = 100 +line(((0, 0), (n, n))) +line(((n, 0), (0, n))) +for i in range(1, n): + line(((i, 0), (n - i, n))) + line(((0, i), (n, n - i))) + +print() diff --git a/bent/index.html b/bent/index.html new file mode 100644 index 0000000..6a253de --- /dev/null +++ b/bent/index.html @@ -0,0 +1,36 @@ + + + + + + BENT + + + + + + + +
+

BENT

+
+ +
+

+ + +

+ + +
+ + + \ No newline at end of file diff --git a/bent/src/js.rs b/bent/src/js.rs new file mode 100644 index 0000000..a78e4b1 --- /dev/null +++ b/bent/src/js.rs @@ -0,0 +1,7 @@ +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(js_namespace = console)] + pub fn log(a: &str); +} diff --git a/bent/src/lib.rs b/bent/src/lib.rs new file mode 100644 index 0000000..d26acc3 --- /dev/null +++ b/bent/src/lib.rs @@ -0,0 +1,10 @@ +use wasm_bindgen::prelude::*; +#[allow(unused_macros)] +#[macro_use] +pub mod macros; +pub mod js; + +#[wasm_bindgen] +pub fn greet(name: &str) { + println!("Hello, {name}!"); +} diff --git a/bent/src/macros.rs b/bent/src/macros.rs new file mode 100644 index 0000000..7d9c941 --- /dev/null +++ b/bent/src/macros.rs @@ -0,0 +1,27 @@ +macro_rules! println { + ($($t:tt)*) => (crate::js::log(&format_args!($($t)*).to_string())) +} + +macro_rules! dbg { + // NOTE: We cannot use `concat!` to make a static string as a format argument + // of `eprintln!` because `file!` could contain a `{` or + // `$val` expression could be a block (`{ .. }`), in which case the `eprintln!` + // will be malformed. + () => { + println!("[{}:{}:{}]", file!(), line!(), column!()) + }; + ($val:expr $(,)?) => { + // Use of `match` here is intentional because it affects the lifetimes + // of temporaries - https://stackoverflow.com/a/48732525/1063961 + match $val { + tmp => { + println!("[{}:{}:{}] {} = {:#?}", + file!(), line!(), column!(), stringify!($val), &tmp); + tmp + } + } + }; + ($($val:expr),+ $(,)?) => { + ($(dbg!($val)),+,) + }; +} diff --git a/bent/src/main.rs b/bent/src/main.rs deleted file mode 100644 index e7a11a9..0000000 --- a/bent/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -}