remove needless traits

This commit is contained in:
bendn 2023-09-05 09:59:33 +07:00
parent 5168d0f6d9
commit 82c597213b
No known key found for this signature in database
GPG key ID: 0D9D3A2A3B2A93D6
4 changed files with 66 additions and 70 deletions

View file

@ -1,6 +1,6 @@
[package] [package]
name = "fimg" name = "fimg"
version = "0.1.0" version = "0.2.0"
authors = ["bend-n <bend.n@outlook.com>"] authors = ["bend-n <bend.n@outlook.com>"]
license = "MIT" license = "MIT"
edition = "2021" edition = "2021"

View file

@ -1,39 +1,19 @@
use crate::{FromRefMut, Image}; use crate::Image;
pub trait Rotations {
/// Rotate a image 180 degrees clockwise.
fn rot_180(&mut self);
/// Rotate a image 90 degrees clockwise.
/// # Safety
///
/// UB if the image is not square
unsafe fn rot_90(&mut self);
/// Rotate a image 270 degrees clockwise, or 90 degrees anti clockwise.
/// # Safety
///
/// UB if the image is not square
unsafe fn rot_270(&mut self);
}
pub trait Flips {
/// Flip a image vertically.
fn flip_v(&mut self);
impl<const CHANNELS: usize> Image<Vec<u8>, CHANNELS> {
/// Flip a image horizontally. /// Flip a image horizontally.
fn flip_h(&mut self); pub fn flip_h(&mut self) {
}
impl<const CHANNELS: usize> Flips for Image<Vec<u8>, CHANNELS> {
fn flip_h(&mut self) {
self.as_mut().flip_h(); self.as_mut().flip_h();
} }
fn flip_v(&mut self) { /// Flip a image vertically.
pub fn flip_v(&mut self) {
self.as_mut().flip_v(); self.as_mut().flip_v();
} }
} }
impl<const CHANNELS: usize> Flips for Image<&mut [u8], CHANNELS> { impl<const CHANNELS: usize> Image<&mut [u8], CHANNELS> {
fn flip_v(&mut self) { /// Flip a image vertically.
pub fn flip_v(&mut self) {
for y in 0..self.height() / 2 { for y in 0..self.height() / 2 {
for x in 0..self.width() { for x in 0..self.width() {
let y2 = self.height() - y - 1; let y2 = self.height() - y - 1;
@ -46,6 +26,7 @@ impl<const CHANNELS: usize> Flips for Image<&mut [u8], CHANNELS> {
} }
} }
/// Flip a image horizontally.
fn flip_h(&mut self) { fn flip_h(&mut self) {
for y in 0..self.height() { for y in 0..self.height() {
for x in 0..self.width() / 2 { for x in 0..self.width() / 2 {
@ -59,22 +40,32 @@ impl<const CHANNELS: usize> Flips for Image<&mut [u8], CHANNELS> {
} }
} }
impl<const CHANNELS: usize> Rotations for Image<Vec<u8>, CHANNELS> { impl<const CHANNELS: usize> Image<Vec<u8>, CHANNELS> {
fn rot_180(&mut self) { /// Rotate a image 180 degrees clockwise.
pub fn rot_180(&mut self) {
self.as_mut().rot_180(); self.as_mut().rot_180();
} }
unsafe fn rot_90(&mut self) { /// Rotate a image 90 degrees clockwise.
/// # Safety
///
/// UB if the image is not square
pub unsafe fn rot_90(&mut self) {
unsafe { self.as_mut().rot_90() } unsafe { self.as_mut().rot_90() }
} }
unsafe fn rot_270(&mut self) { /// Rotate a image 270 degrees clockwise, or 90 degrees anti clockwise.
/// # Safety
///
/// UB if the image is not square
pub unsafe fn rot_270(&mut self) {
unsafe { self.as_mut().rot_270() } unsafe { self.as_mut().rot_270() }
} }
} }
impl<const CHANNELS: usize> Rotations for Image<&mut [u8], CHANNELS> { impl<const CHANNELS: usize> Image<&mut [u8], CHANNELS> {
fn rot_180(&mut self) { /// Rotate a image 180 degrees clockwise.
pub fn rot_180(&mut self) {
for y in 0..self.height() / 2 { for y in 0..self.height() / 2 {
for x in 0..self.width() { for x in 0..self.width() {
let p = unsafe { self.pixel(x, y) }; let p = unsafe { self.pixel(x, y) };
@ -99,17 +90,25 @@ impl<const CHANNELS: usize> Rotations for Image<&mut [u8], CHANNELS> {
} }
} }
/// Rotate a image 90 degrees clockwise.
/// # Safety
///
/// UB if the image is not square
#[inline] #[inline]
unsafe fn rot_90(&mut self) { pub unsafe fn rot_90(&mut self) {
// This is done by first flipping // This is done by first flipping
self.flip_v(); self.flip_v();
// Then transposing the image, to save allocations. // Then transposing the image, as to not allocate.
// SAFETY: caller ensures square // SAFETY: caller ensures square
unsafe { transpose(self) }; unsafe { transpose(self) };
} }
/// Rotate a image 270 degrees clockwise, or 90 degrees anti clockwise.
/// # Safety
///
/// UB if the image is not square
#[inline] #[inline]
unsafe fn rot_270(&mut self) { pub unsafe fn rot_270(&mut self) {
self.flip_h(); self.flip_h();
// SAFETY: caller ensures squareness // SAFETY: caller ensures squareness
unsafe { transpose(self) }; unsafe { transpose(self) };

View file

@ -20,18 +20,8 @@ use std::{num::NonZeroU32, slice::SliceIndex};
mod affine; mod affine;
mod overlay; mod overlay;
pub use affine::{Flips, Rotations};
pub use overlay::{Overlay, OverlayAt}; pub use overlay::{Overlay, OverlayAt};
pub trait RepeatNew {
type Output;
/// Repeat self till it fills a new image of size x, y
/// # Safety
///
/// UB if self's width is not a multiple of x, or self's height is not a multiple of y
unsafe fn repeated(&self, x: u32, y: u32) -> Self::Output;
}
macro_rules! assert_unchecked { macro_rules! assert_unchecked {
($cond:expr) => {{ ($cond:expr) => {{
if !$cond { if !$cond {
@ -46,9 +36,12 @@ macro_rules! assert_unchecked {
} }
use assert_unchecked; use assert_unchecked;
impl RepeatNew for Image<&[u8], 3> { impl Image<&[u8], 3> {
type Output = Image<Vec<u8>, 3>; /// Repeat self till it fills a new image of size x, y
unsafe fn repeated(&self, x: u32, y: u32) -> Self::Output { /// # Safety
///
/// UB if self's width is not a multiple of x, or self's height is not a multiple of y
pub unsafe fn repeated(&self, x: u32, y: u32) -> Image<Vec<u8>, 3> {
let mut img = Image::alloc(x, y); // could probably optimize this a ton but eh let mut img = Image::alloc(x, y); // could probably optimize this a ton but eh
for x in 0..(x / self.width()) { for x in 0..(x / self.width()) {
for y in 0..(y / self.height()) { for y in 0..(y / self.height()) {
@ -68,10 +61,14 @@ unsafe fn really_unsafe_index(x: u32, y: u32, w: u32) -> usize {
unsafe { tmp.unchecked_add(x as usize) } unsafe { tmp.unchecked_add(x as usize) }
} }
/// A image with a variable number of channels, and a nonzero size.
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub struct Image<T, const CHANNELS: usize> { pub struct Image<T, const CHANNELS: usize> {
/// column order 2d slice/vec
pub buffer: T, pub buffer: T,
/// image horizontal size
pub width: NonZeroU32, pub width: NonZeroU32,
/// image vertical size
pub height: NonZeroU32, pub height: NonZeroU32,
} }
@ -87,16 +84,19 @@ impl<const CHANNELS: usize> Default for Image<&'static [u8], CHANNELS> {
impl<T, const CHANNELS: usize> Image<T, CHANNELS> { impl<T, const CHANNELS: usize> Image<T, CHANNELS> {
#[inline] #[inline]
/// get the height as a [`u32`]
pub fn height(&self) -> u32 { pub fn height(&self) -> u32 {
self.height.into() self.height.into()
} }
#[inline] #[inline]
/// get the width as a [`u32`]
pub fn width(&self) -> u32 { pub fn width(&self) -> u32 {
self.width.into() self.width.into()
} }
#[inline] #[inline]
/// create a new image
pub const fn new(width: NonZeroU32, height: NonZeroU32, buffer: T) -> Self { pub const fn new(width: NonZeroU32, height: NonZeroU32, buffer: T) -> Self {
Image { Image {
buffer, buffer,
@ -109,6 +109,7 @@ impl<T, const CHANNELS: usize> Image<T, CHANNELS> {
impl<const CHANNELS: usize> Image<&[u8], CHANNELS> { impl<const CHANNELS: usize> Image<&[u8], CHANNELS> {
#[inline] #[inline]
#[must_use] #[must_use]
/// Copy this ref image
pub const fn copy(&self) -> Self { pub const fn copy(&self) -> Self {
Self { Self {
width: self.width, width: self.width,
@ -192,36 +193,30 @@ impl<T: std::ops::DerefMut<Target = [u8]>, const CHANNELS: usize> Image<T, CHANN
} }
} }
pub trait FromRef<const CHANNELS: usize> { impl<const CHANNELS: usize> Image<&mut [u8], CHANNELS> {
/// Reference the buffer /// Downcast the mutable reference
fn as_ref(&self) -> Image<&[u8], CHANNELS>; pub fn as_ref(&self) -> Image<&[u8], CHANNELS> {
}
pub trait FromRefMut<const CHANNELS: usize> {
/// Reference the buffer, mutably
fn as_mut(&mut self) -> Image<&mut [u8], CHANNELS>;
}
impl<const CHANNELS: usize> FromRef<CHANNELS> for Image<&mut [u8], CHANNELS> {
fn as_ref(&self) -> Image<&[u8], CHANNELS> {
Image::new(self.width, self.height, self.buffer) Image::new(self.width, self.height, self.buffer)
} }
} }
impl<const CHANNELS: usize> FromRefMut<CHANNELS> for Image<&mut [u8], CHANNELS> { impl<const CHANNELS: usize> Image<&mut [u8], CHANNELS> {
fn as_mut(&mut self) -> Image<&mut [u8], CHANNELS> { /// Copy this ref image
pub fn copy(&mut self) -> Image<&mut [u8], CHANNELS> {
Image::new(self.width, self.height, self.buffer) Image::new(self.width, self.height, self.buffer)
} }
} }
impl<const CHANNELS: usize> FromRef<CHANNELS> for Image<Vec<u8>, CHANNELS> { impl<const CHANNELS: usize> Image<Vec<u8>, CHANNELS> {
fn as_ref(&self) -> Image<&[u8], CHANNELS> { /// Create a reference to this owned image
pub fn as_ref(&self) -> Image<&[u8], CHANNELS> {
Image::new(self.width, self.height, &self.buffer) Image::new(self.width, self.height, &self.buffer)
} }
} }
impl<const CHANNELS: usize> FromRefMut<CHANNELS> for Image<Vec<u8>, CHANNELS> { impl<const CHANNELS: usize> Image<Vec<u8>, CHANNELS> {
fn as_mut(&mut self) -> Image<&mut [u8], CHANNELS> { /// Create a mutable reference to this owned image
pub fn as_mut(&mut self) -> Image<&mut [u8], CHANNELS> {
Image::new(self.width, self.height, &mut self.buffer) Image::new(self.width, self.height, &mut self.buffer)
} }
} }

View file

@ -3,6 +3,7 @@ use std::simd::SimdInt;
use std::simd::SimdPartialOrd; use std::simd::SimdPartialOrd;
use std::simd::{simd_swizzle, Simd}; use std::simd::{simd_swizzle, Simd};
/// Trait for layering a image ontop of another, with a offset to the second image.
pub trait OverlayAt<W> { pub trait OverlayAt<W> {
/// Overlay with => self at coordinates x, y, without blending /// Overlay with => self at coordinates x, y, without blending
/// # Safety /// # Safety
@ -10,7 +11,8 @@ pub trait OverlayAt<W> {
/// UB if x, y is out of bounds /// UB if x, y is out of bounds
unsafe fn overlay_at(&mut self, with: &W, x: u32, y: u32) -> &mut Self; unsafe fn overlay_at(&mut self, with: &W, x: u32, y: u32) -> &mut Self;
} }
/// Trait for layering images ontop of each other.
/// Think `magick a b -layers flatten a`
pub trait Overlay<W> { pub trait Overlay<W> {
/// Overlay with => self (does not blend) /// Overlay with => self (does not blend)
/// # Safety /// # Safety