nuke funny zone, we're getting serious
This commit is contained in:
parent
42bd1a49f4
commit
1ef8d8c4cb
3 changed files with 1 additions and 156 deletions
|
@ -1,6 +1,6 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
members = ["bent", "bent-funny-zone", "bingus", "bong"]
|
members = ["bent", "bingus", "bong"]
|
||||||
package.edition = "2021"
|
package.edition = "2021"
|
||||||
package.license = "Unlicense"
|
package.license = "Unlicense"
|
||||||
package.description = "databending made easy"
|
package.description = "databending made easy"
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "bent-funny-zone"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition.workspace = true
|
|
||||||
license.workspace = true
|
|
||||||
description.workspace = true
|
|
||||||
authors.workspace = true
|
|
||||||
repository.workspace = true
|
|
||||||
keywords.workspace = true
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
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 = { workspace = true }
|
|
||||||
infer = { workspace = true }
|
|
||||||
indicatif = { workspace = true }
|
|
|
@ -1,131 +0,0 @@
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
|
||||||
use bingus::rawdata::RawData;
|
|
||||||
use dasp_sample::{Sample, U24};
|
|
||||||
use derive_new::new;
|
|
||||||
use dirs::{download_dir, home_dir, picture_dir};
|
|
||||||
use fundsp::math::uparc;
|
|
||||||
use image::{ImageFormat, ImageReader, RgbImage};
|
|
||||||
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<Self> {
|
|
||||||
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<PathBuf> {
|
|
||||||
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<Self> {
|
|
||||||
Files::try_new(
|
|
||||||
FileDialog::new()
|
|
||||||
.set_title("Input image")
|
|
||||||
.set_directory(working_dir())
|
|
||||||
.add_filter(
|
|
||||||
"images",
|
|
||||||
&ImageFormat::all()
|
|
||||||
.map(ImageFormat::extensions_str)
|
|
||||||
.flatten()
|
|
||||||
.collect::<Vec<&'static &'static str>>(),
|
|
||||||
)
|
|
||||||
.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 dp = DataPath::new(Files::prompt()?);
|
|
||||||
let img = RawData::<RgbImage>::new(
|
|
||||||
ImageReader::open(dp.files.input)?
|
|
||||||
.decode()
|
|
||||||
.context("can't use this picture")?
|
|
||||||
.into_rgb8(),
|
|
||||||
);
|
|
||||||
let processed = RawData::<RgbImage>::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(),
|
|
||||||
);
|
|
||||||
processed.save(dp.files.output)?;
|
|
||||||
|
|
||||||
// let bytes: Vec<u8> = (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::<Vec<u8>>()
|
|
||||||
// );
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn working_dir() -> PathBuf {
|
|
||||||
picture_dir()
|
|
||||||
.or(download_dir())
|
|
||||||
.or(home_dir())
|
|
||||||
.unwrap_or("/".into())
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue