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]
name = "fimg"
version = "0.1.0"
version = "0.2.0"
authors = ["bend-n <bend.n@outlook.com>"]
license = "MIT"
edition = "2021"

View file

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

View file

@ -20,18 +20,8 @@ use std::{num::NonZeroU32, slice::SliceIndex};
mod affine;
mod overlay;
pub use affine::{Flips, Rotations};
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 {
($cond:expr) => {{
if !$cond {
@ -46,9 +36,12 @@ macro_rules! assert_unchecked {
}
use assert_unchecked;
impl RepeatNew for Image<&[u8], 3> {
type Output = Image<Vec<u8>, 3>;
unsafe fn repeated(&self, x: u32, y: u32) -> Self::Output {
impl Image<&[u8], 3> {
/// 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
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
for x in 0..(x / self.width()) {
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) }
}
/// A image with a variable number of channels, and a nonzero size.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Image<T, const CHANNELS: usize> {
/// column order 2d slice/vec
pub buffer: T,
/// image horizontal size
pub width: NonZeroU32,
/// image vertical size
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> {
#[inline]
/// get the height as a [`u32`]
pub fn height(&self) -> u32 {
self.height.into()
}
#[inline]
/// get the width as a [`u32`]
pub fn width(&self) -> u32 {
self.width.into()
}
#[inline]
/// create a new image
pub const fn new(width: NonZeroU32, height: NonZeroU32, buffer: T) -> Self {
Image {
buffer,
@ -109,6 +109,7 @@ impl<T, const CHANNELS: usize> Image<T, CHANNELS> {
impl<const CHANNELS: usize> Image<&[u8], CHANNELS> {
#[inline]
#[must_use]
/// Copy this ref image
pub const fn copy(&self) -> Self {
Self {
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> {
/// Reference the buffer
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> {
impl<const CHANNELS: usize> Image<&mut [u8], CHANNELS> {
/// Downcast the mutable reference
pub fn as_ref(&self) -> Image<&[u8], CHANNELS> {
Image::new(self.width, self.height, self.buffer)
}
}
impl<const CHANNELS: usize> FromRefMut<CHANNELS> for Image<&mut [u8], CHANNELS> {
fn as_mut(&mut self) -> Image<&mut [u8], CHANNELS> {
impl<const CHANNELS: usize> 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)
}
}
impl<const CHANNELS: usize> FromRef<CHANNELS> for Image<Vec<u8>, CHANNELS> {
fn as_ref(&self) -> Image<&[u8], CHANNELS> {
impl<const CHANNELS: usize> Image<Vec<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)
}
}
impl<const CHANNELS: usize> FromRefMut<CHANNELS> for Image<Vec<u8>, CHANNELS> {
fn as_mut(&mut self) -> Image<&mut [u8], CHANNELS> {
impl<const CHANNELS: usize> Image<Vec<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)
}
}

View file

@ -3,6 +3,7 @@ use std::simd::SimdInt;
use std::simd::SimdPartialOrd;
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> {
/// Overlay with => self at coordinates x, y, without blending
/// # Safety
@ -10,7 +11,8 @@ pub trait OverlayAt<W> {
/// UB if x, y is out of bounds
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> {
/// Overlay with => self (does not blend)
/// # Safety