rebranding, image databending
This commit is contained in:
parent
f7eb44179d
commit
ff6e44072e
7 changed files with 104 additions and 40 deletions
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "bingus"
|
name = "bingus"
|
||||||
version = "0.1.2"
|
version = "0.2.0"
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
description.workspace = true
|
description.workspace = true
|
||||||
|
@ -10,4 +10,5 @@ keywords.workspace = true
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
[dependencies]
|
[dependencies]
|
||||||
derive-new = { workspace = true }
|
image = { version = "0.25", features = ["rayon"] }
|
||||||
|
num = "0"
|
||||||
|
|
1
bingus/src/img.rs
Normal file
1
bingus/src/img.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod image;
|
66
bingus/src/img/image.rs
Normal file
66
bingus/src/img/image.rs
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
use std::ops::{BitOr, Deref, Shl};
|
||||||
|
|
||||||
|
use image::{ImageBuffer, Pixel};
|
||||||
|
use num::{traits::ToBytes, Zero};
|
||||||
|
|
||||||
|
use crate::{Bendable, IntoDataBytes, TryFromDataBytes};
|
||||||
|
|
||||||
|
impl<P: Pixel> IntoDataBytes for ImageBuffer<P, Vec<P::Subpixel>>
|
||||||
|
where
|
||||||
|
Vec<P>: Deref<Target = [P::Subpixel]>,
|
||||||
|
P::Subpixel: ToBytes,
|
||||||
|
{
|
||||||
|
fn into_bytes(self) -> crate::Bytes {
|
||||||
|
self.into_iter()
|
||||||
|
.flat_map(|subpixel| subpixel.to_be_bytes().as_ref().to_vec())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Dimensions {
|
||||||
|
pub width: u32,
|
||||||
|
pub height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P: Pixel> TryFromDataBytes for ImageBuffer<P, Vec<P::Subpixel>>
|
||||||
|
where
|
||||||
|
Vec<P>: Deref<Target = [P::Subpixel]>,
|
||||||
|
P::Subpixel:
|
||||||
|
ToBytes + Zero + Shl<u8, Output = P::Subpixel> + BitOr<P::Subpixel, Output = P::Subpixel>,
|
||||||
|
{
|
||||||
|
type Error = ();
|
||||||
|
type Format = Dimensions;
|
||||||
|
fn try_from_bytes(bytes: crate::Bytes, format: Self::Format) -> Result<Self, Self::Error>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
ImageBuffer::from_raw(
|
||||||
|
format.width,
|
||||||
|
format.height,
|
||||||
|
bytes
|
||||||
|
.chunks_exact(P::Subpixel::zero().to_be_bytes().as_ref().len())
|
||||||
|
.map(|p| {
|
||||||
|
p.iter()
|
||||||
|
.copied()
|
||||||
|
.flat_map(num::traits::cast::<u8, P::Subpixel>)
|
||||||
|
.reduce(|acc, b| (acc << 8u8) | b)
|
||||||
|
.unwrap()
|
||||||
|
})
|
||||||
|
.collect::<Vec<P::Subpixel>>(),
|
||||||
|
)
|
||||||
|
.ok_or(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P: Pixel> Bendable for ImageBuffer<P, Vec<P::Subpixel>>
|
||||||
|
where
|
||||||
|
Vec<P>: Deref<Target = [P::Subpixel]>,
|
||||||
|
P::Subpixel:
|
||||||
|
ToBytes + Zero + Shl<u8, Output = P::Subpixel> + BitOr<P::Subpixel, Output = P::Subpixel>,
|
||||||
|
{
|
||||||
|
type Unit = P;
|
||||||
|
fn apply<F: Fn(&Self::Unit) -> Self::Unit>(mut self, f: F) -> Self {
|
||||||
|
self.pixels_mut().for_each(|p| *p = f(p));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,2 +1,34 @@
|
||||||
#![forbid(unused_crate_dependencies)]
|
pub mod img;
|
||||||
pub mod rawdata;
|
pub mod snd;
|
||||||
|
pub mod txt;
|
||||||
|
|
||||||
|
pub type Bytes = Vec<u8>;
|
||||||
|
|
||||||
|
pub trait Bendable: TryFromDataBytes + IntoDataBytes {
|
||||||
|
type Unit;
|
||||||
|
fn bend_into<T: Bendable>(
|
||||||
|
self,
|
||||||
|
format: <T as TryFromDataBytes>::Format,
|
||||||
|
) -> Result<T, <T as TryFromDataBytes>::Error> {
|
||||||
|
T::bend_from(self, format)
|
||||||
|
}
|
||||||
|
fn bend_from<T: Bendable>(
|
||||||
|
b: T,
|
||||||
|
format: <Self as TryFromDataBytes>::Format,
|
||||||
|
) -> Result<Self, <Self as TryFromDataBytes>::Error> {
|
||||||
|
Self::try_from_bytes(b.into_bytes(), format)
|
||||||
|
}
|
||||||
|
fn apply<F: Fn(&Self::Unit) -> Self::Unit>(self, f: F) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait IntoDataBytes: Sized {
|
||||||
|
fn into_bytes(self) -> Bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait TryFromDataBytes {
|
||||||
|
type Error;
|
||||||
|
type Format;
|
||||||
|
fn try_from_bytes(bytes: Bytes, format: Self::Format) -> Result<Self, Self::Error>
|
||||||
|
where
|
||||||
|
Self: Sized;
|
||||||
|
}
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
use std::ops::Deref;
|
|
||||||
|
|
||||||
use derive_new::new;
|
|
||||||
|
|
||||||
pub type Bytes = [u8];
|
|
||||||
|
|
||||||
#[derive(new)]
|
|
||||||
pub struct RawData<D: Deref<Target = Bytes>>(D);
|
|
||||||
|
|
||||||
impl<D> From<RawData<D>> for Vec<u8>
|
|
||||||
where
|
|
||||||
D: Deref<Target = Bytes>,
|
|
||||||
{
|
|
||||||
fn from(value: RawData<D>) -> Self {
|
|
||||||
value.to_owned()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D> Clone for RawData<D>
|
|
||||||
where
|
|
||||||
D: Clone + Deref<Target = Bytes>,
|
|
||||||
{
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self(self.deref().clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D> Deref for RawData<D>
|
|
||||||
where
|
|
||||||
D: Deref<Target = Bytes>,
|
|
||||||
{
|
|
||||||
type Target = D;
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
0
bingus/src/snd.rs
Normal file
0
bingus/src/snd.rs
Normal file
0
bingus/src/txt.rs
Normal file
0
bingus/src/txt.rs
Normal file
Loading…
Add table
Add a link
Reference in a new issue