png output
This commit is contained in:
parent
c47132c389
commit
5d977ae028
3 changed files with 123 additions and 27 deletions
98
Cargo.lock
generated
98
Cargo.lock
generated
|
@ -2,6 +2,12 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 4
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "adler2"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anstream"
|
name = "anstream"
|
||||||
version = "0.6.18"
|
version = "0.6.18"
|
||||||
|
@ -58,6 +64,12 @@ version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.9.0"
|
version = "2.9.0"
|
||||||
|
@ -74,6 +86,18 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytemuck"
|
||||||
|
version = "1.22.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder-lite"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.16"
|
version = "1.2.16"
|
||||||
|
@ -135,6 +159,15 @@ version = "1.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc32fast"
|
||||||
|
version = "1.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.15.0"
|
version = "1.15.0"
|
||||||
|
@ -157,11 +190,31 @@ dependencies = [
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fdeflate"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c"
|
||||||
|
dependencies = [
|
||||||
|
"simd-adler32",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flate2"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc"
|
||||||
|
dependencies = [
|
||||||
|
"crc32fast",
|
||||||
|
"miniz_oxide",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "grapher"
|
name = "grapher"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
|
"image",
|
||||||
"mlua",
|
"mlua",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -171,6 +224,18 @@ version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "image"
|
||||||
|
version = "0.25.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck",
|
||||||
|
"byteorder-lite",
|
||||||
|
"num-traits",
|
||||||
|
"png",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "is_terminal_polyfill"
|
name = "is_terminal_polyfill"
|
||||||
version = "1.70.1"
|
version = "1.70.1"
|
||||||
|
@ -224,6 +289,16 @@ version = "2.7.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miniz_oxide"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5"
|
||||||
|
dependencies = [
|
||||||
|
"adler2",
|
||||||
|
"simd-adler32",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mlua"
|
name = "mlua"
|
||||||
version = "0.10.3"
|
version = "0.10.3"
|
||||||
|
@ -295,6 +370,19 @@ version = "0.3.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "png"
|
||||||
|
version = "0.17.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"crc32fast",
|
||||||
|
"fdeflate",
|
||||||
|
"flate2",
|
||||||
|
"miniz_oxide",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.94"
|
version = "1.0.94"
|
||||||
|
@ -319,7 +407,7 @@ version = "0.5.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1"
|
checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 2.9.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -334,7 +422,7 @@ version = "0.38.44"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
|
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 2.9.0",
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys",
|
||||||
|
@ -373,6 +461,12 @@ version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "simd-adler32"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.14.0"
|
version = "1.14.0"
|
||||||
|
|
|
@ -5,4 +5,5 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "4.5.32", features = ["derive"] }
|
clap = { version = "4.5.32", features = ["derive"] }
|
||||||
|
image = { version = "0.25.5", features = ["png"], default-features = false }
|
||||||
mlua = { version = "0.10.3", features = ["lua54", "vendored"] }
|
mlua = { version = "0.10.3", features = ["lua54", "vendored"] }
|
||||||
|
|
51
src/main.rs
51
src/main.rs
|
@ -1,7 +1,9 @@
|
||||||
use std::{num::NonZero, process};
|
use std::{path::PathBuf, process};
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
use image::{ImageBuffer, Pixel};
|
||||||
use mlua::Lua;
|
use mlua::Lua;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let Args {
|
let Args {
|
||||||
width,
|
width,
|
||||||
|
@ -11,9 +13,13 @@ fn main() {
|
||||||
ymin,
|
ymin,
|
||||||
xmax,
|
xmax,
|
||||||
ymax,
|
ymax,
|
||||||
|
output_file,
|
||||||
} = Args::parse();
|
} = Args::parse();
|
||||||
|
if output_file.extension().is_none_or(|s| s != "png") {
|
||||||
|
eprintln!("i'm only doing pngs");
|
||||||
|
process::exit(2)
|
||||||
|
}
|
||||||
let lua = Lua::new();
|
let lua = Lua::new();
|
||||||
|
|
||||||
// so we can write unqualified sin, cos, etc
|
// so we can write unqualified sin, cos, etc
|
||||||
lua.load("setmetatable(_G, {__index = math})")
|
lua.load("setmetatable(_G, {__index = math})")
|
||||||
.exec()
|
.exec()
|
||||||
|
@ -41,7 +47,6 @@ fn main() {
|
||||||
|
|
||||||
let pos_to_sample = |ix: u16, iy: u16| -> (f32, f32) {
|
let pos_to_sample = |ix: u16, iy: u16| -> (f32, f32) {
|
||||||
// TODO: bad
|
// TODO: bad
|
||||||
let (width, height): (u16, u16) = (width.into(), height.into());
|
|
||||||
let (width, height): (f32, f32) = (width.into(), height.into());
|
let (width, height): (f32, f32) = (width.into(), height.into());
|
||||||
let (x, y) = (f32::from(ix), f32::from(iy));
|
let (x, y) = (f32::from(ix), f32::from(iy));
|
||||||
let (xt, yt) = (x / width, y / height);
|
let (xt, yt) = (x / width, y / height);
|
||||||
|
@ -51,8 +56,8 @@ fn main() {
|
||||||
let (mut min, mut max) = (-1.0f32, 1.0f32);
|
let (mut min, mut max) = (-1.0f32, 1.0f32);
|
||||||
// first, find the min and max of the function
|
// first, find the min and max of the function
|
||||||
// (literally doubles our runtime :D)
|
// (literally doubles our runtime :D)
|
||||||
for iy in 0..(height.into()) {
|
for iy in 0..height {
|
||||||
for ix in 0..(width.into()) {
|
for ix in 0..width {
|
||||||
let (x, y) = pos_to_sample(ix, iy);
|
let (x, y) = pos_to_sample(ix, iy);
|
||||||
let i = f(x, y);
|
let i = f(x, y);
|
||||||
min = min.min(i);
|
min = min.min(i);
|
||||||
|
@ -61,35 +66,31 @@ fn main() {
|
||||||
}
|
}
|
||||||
let (min, max) = (min, max);
|
let (min, max) = (min, max);
|
||||||
|
|
||||||
for iy in (0..(height.into())).rev() {
|
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
|
||||||
for ix in 0..(width.into()) {
|
let img = ImageBuffer::from_fn(width.into(), height.into(), |x, y| {
|
||||||
let (x, y) = pos_to_sample(ix, iy);
|
let (x, y) = pos_to_sample(x as u16, y as u16);
|
||||||
let i = f(x, y);
|
let i = f(x, y);
|
||||||
let scaled = i / (max - min);
|
let scaled = i / (max - min);
|
||||||
#[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
|
// cube rooting makes things sharper
|
||||||
// cube rooting makes things sharper
|
let channel = (scaled.cbrt() * 256.) as u8;
|
||||||
let channel = (scaled.cbrt() * 256.) as u8;
|
image::Luma([channel]).to_rgb()
|
||||||
put_pixel(channel, channel, channel);
|
});
|
||||||
put_pixel(channel, channel, channel);
|
if let Err(e) = img.save(output_file) {
|
||||||
}
|
eprintln!("error saving image: {e}");
|
||||||
println!();
|
process::exit(4);
|
||||||
}
|
}
|
||||||
// reset style
|
|
||||||
print!("\x1b[0m");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn put_pixel(r: u8, g: u8, b: u8) {
|
|
||||||
print!("\x1b[48;2;{r};{g};{b}m ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
struct Args {
|
struct Args {
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
width: NonZero<u16>,
|
width: u16,
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
height: NonZero<u16>,
|
height: u16,
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
expr: String,
|
expr: String,
|
||||||
|
#[arg(short, long)]
|
||||||
|
output_file: PathBuf,
|
||||||
#[arg(default_value_t = -1.0)]
|
#[arg(default_value_t = -1.0)]
|
||||||
xmin: f32,
|
xmin: f32,
|
||||||
#[arg(default_value_t = -1.0)]
|
#[arg(default_value_t = -1.0)]
|
||||||
|
|
Loading…
Reference in a new issue