Initial commit

This commit is contained in:
Tove 2026-02-09 13:17:27 +01:00
commit 7e974d42ae
Signed by: TudbuT
GPG key ID: B3CF345217F202D3
12 changed files with 232 additions and 0 deletions

1
.envrc Normal file
View file

@ -0,0 +1 @@
use nix

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/target
/.direnv

7
Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "imgsyn"
version = "0.1.0"

6
Cargo.toml Normal file
View file

@ -0,0 +1,6 @@
[package]
name = "imgsyn"
version = "0.1.0"
edition = "2024"
[dependencies]

3
main.rs Normal file
View file

@ -0,0 +1,3 @@
fn main() {
}

12
shell.nix Normal file
View file

@ -0,0 +1,12 @@
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
nativeBuildInputs = with pkgs; [
rustfmt
cargo
clippy
rustc
ffmpeg
imagemagick
rust-analyzer
];
}

56
src/canvas.rs Normal file
View file

@ -0,0 +1,56 @@
use crate::{ImgSyn, pixel::Pixel};
#[derive(Clone, Copy, PartialEq)]
pub struct Canvas {
pub width: u32,
pub height: u32,
pub default_px: Pixel,
}
#[derive(Clone, PartialEq)]
pub struct PaintedCanvas {
pub meta: Canvas,
pub array: Vec<Vec<Pixel>>,
}
impl Canvas {
pub fn new(width: u32, height: u32, default_px: Pixel) -> Self {
Self {
width,
height,
default_px,
}
}
}
impl ImgSyn for Canvas {
fn getpx(&self, _meta: Canvas, _x: f32, _y: f32) -> Pixel {
self.default_px
}
}
impl PaintedCanvas {
pub fn new(meta @ Canvas { width, height, .. }: Canvas, function: impl ImgSyn) -> Self {
Self {
meta,
array: (0..width)
.map(|x| x as f32 / width as f32)
.map(|x| {
(0..height)
.map(|y| y as f32 / height as f32)
.map(|y| function.getpx(meta, x, y))
.collect()
})
.collect(),
}
}
}
impl ImgSyn for PaintedCanvas {
fn getpx(&self, meta: Canvas, x: f32, y: f32) -> Pixel {
// float coords -> int coords
let x = (x * meta.width as f32).round() as usize;
let y = (y * meta.height as f32).round() as usize;
self.array[x][y]
}
}

36
src/lib.rs Normal file
View file

@ -0,0 +1,36 @@
mod canvas;
pub mod ops;
mod pixel;
mod pixfn;
pub use canvas::*;
pub use pixel::*;
pub use pixfn::*;
use crate::ops::ImgSynMap;
pub trait ImgSynPixFn: Clone {
fn run(&self, meta: Canvas, x: f32, y: f32, pixel: Pixel) -> Pixel;
}
pub trait ImgSyn: Clone {
fn getpx(&self, meta: Canvas, x: f32, y: f32) -> Pixel;
fn map<F: ImgSynPixFn>(self, f: F) -> ImgSynMap<Self, F> {
ImgSynMap(self, f)
}
fn paint(self, meta: Canvas) -> PaintedCanvas {
PaintedCanvas::new(meta, self)
}
}
#[cfg(test)]
mod test {
use crate::{Canvas, ImgSyn, PixFnFloat, Pixel};
#[test]
fn test() {
Canvas::new(100, 100, Pixel::new_black())
.map(PixFnFloat(|_, x, y, pix| pix.with_r(x).with_g(y)))
.map(PixFnFloat(|_, _, _, pix| pix.with_b(1.0)));
}
}

10
src/ops/map.rs Normal file
View file

@ -0,0 +1,10 @@
use crate::{ImgSyn, ImgSynPixFn};
#[derive(Clone, Copy)]
pub struct ImgSynMap<Prev: ImgSyn, F: ImgSynPixFn>(pub(crate) Prev, pub(crate) F);
impl<Prev: ImgSyn, F: ImgSynPixFn> ImgSyn for ImgSynMap<Prev, F> {
fn getpx(&self, meta: crate::Canvas, x: f32, y: f32) -> crate::Pixel {
self.1.run(meta, x, y, self.0.getpx(meta, x, y))
}
}

2
src/ops/mod.rs Normal file
View file

@ -0,0 +1,2 @@
mod map;
pub use map::*;

69
src/pixel.rs Normal file
View file

@ -0,0 +1,69 @@
#[derive(Clone, Copy, PartialEq)]
pub struct Pixel {
r: f32,
g: f32,
b: f32,
a: f32,
}
impl Pixel {
pub fn new_blank_black() -> Pixel {
Self::new_black().with_a(0.0)
}
pub fn new_blank_white() -> Pixel {
Self::new_white().with_a(0.0)
}
pub fn new_white() -> Pixel {
Self {
r: 1.0,
g: 1.0,
b: 1.0,
a: 1.0,
}
}
pub fn new_black() -> Pixel {
Self {
r: 0.0,
g: 0.0,
b: 0.0,
a: 1.0,
}
}
pub fn with_r(self, x: f32) -> Pixel {
Self { r: x, ..self }
}
pub fn with_g(self, x: f32) -> Pixel {
Self { g: x, ..self }
}
pub fn with_b(self, x: f32) -> Pixel {
Self { b: x, ..self }
}
pub fn with_a(self, x: f32) -> Pixel {
Self { a: x, ..self }
}
pub fn map(self, f: impl FnOnce(Self) -> Pixel) -> Pixel {
f(self)
}
pub fn map_r(mut self, f: impl FnOnce(f32) -> f32) -> Pixel {
self.r = f(self.r);
self
}
pub fn map_g(mut self, f: impl FnOnce(f32) -> f32) -> Pixel {
self.r = f(self.r);
self
}
pub fn map_b(mut self, f: impl FnOnce(f32) -> f32) -> Pixel {
self.r = f(self.r);
self
}
pub fn map_a(mut self, f: impl FnOnce(f32) -> f32) -> Pixel {
self.r = f(self.r);
self
}
}

28
src/pixfn.rs Normal file
View file

@ -0,0 +1,28 @@
use crate::{Canvas, ImgSynPixFn, Pixel};
#[derive(Clone, Copy)]
pub struct PixFnInt<T: (Fn(Canvas, u32, u32, Pixel) -> Pixel) + Copy>(pub T);
impl<T> ImgSynPixFn for PixFnInt<T>
where
T: (Fn(Canvas, u32, u32, Pixel) -> Pixel) + Copy,
{
fn run(&self, meta: Canvas, x: f32, y: f32, pixel: Pixel) -> Pixel {
self.0(
meta,
(x * meta.width as f32).round() as u32,
(y * meta.height as f32).round() as u32,
pixel,
)
}
}
#[derive(Clone, Copy)]
pub struct PixFnFloat<T: (Fn(Canvas, f32, f32, Pixel) -> Pixel) + Copy>(pub T);
impl<T> ImgSynPixFn for PixFnFloat<T>
where
T: (Fn(Canvas, f32, f32, Pixel) -> Pixel) + Copy,
{
fn run(&self, meta: Canvas, x: f32, y: f32, pixel: Pixel) -> Pixel {
self.0(meta, x, y, pixel)
}
}