mirror of
https://github.com/bend-n/fimg.git
synced 2024-12-22 10:28:21 -06:00
remove needless traits
This commit is contained in:
parent
5168d0f6d9
commit
82c597213b
|
@ -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"
|
||||||
|
|
|
@ -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) };
|
||||||
|
|
57
src/lib.rs
57
src/lib.rs
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue