mirror of
https://github.com/bend-n/fimg.git
synced 2024-12-22 10:28:21 -06:00
full documentation
This commit is contained in:
parent
e2128bb9f2
commit
f8ea570db0
|
@ -1,3 +1,4 @@
|
||||||
|
//! Manages the affine image transformations.
|
||||||
use crate::Image;
|
use crate::Image;
|
||||||
|
|
||||||
impl<const CHANNELS: usize> Image<Vec<u8>, CHANNELS> {
|
impl<const CHANNELS: usize> Image<Vec<u8>, CHANNELS> {
|
||||||
|
|
17
src/lib.rs
17
src/lib.rs
|
@ -1,3 +1,6 @@
|
||||||
|
//! # fimg
|
||||||
|
//!
|
||||||
|
//! Provides fast image operations, such as rotation, flipping, and overlaying.
|
||||||
#![feature(
|
#![feature(
|
||||||
slice_swap_unchecked,
|
slice_swap_unchecked,
|
||||||
slice_as_chunks,
|
slice_as_chunks,
|
||||||
|
@ -7,12 +10,13 @@
|
||||||
test
|
test
|
||||||
)]
|
)]
|
||||||
#![warn(
|
#![warn(
|
||||||
|
clippy::missing_docs_in_private_items,
|
||||||
clippy::multiple_unsafe_ops_per_block,
|
clippy::multiple_unsafe_ops_per_block,
|
||||||
clippy::missing_const_for_fn,
|
clippy::missing_const_for_fn,
|
||||||
clippy::missing_safety_doc,
|
clippy::missing_safety_doc,
|
||||||
unsafe_op_in_unsafe_fn,
|
unsafe_op_in_unsafe_fn,
|
||||||
clippy::dbg_macro,
|
clippy::dbg_macro,
|
||||||
clippy::perf
|
missing_docs
|
||||||
)]
|
)]
|
||||||
#![allow(clippy::zero_prefixed_literal)]
|
#![allow(clippy::zero_prefixed_literal)]
|
||||||
|
|
||||||
|
@ -22,6 +26,10 @@ mod affine;
|
||||||
mod overlay;
|
mod overlay;
|
||||||
pub use overlay::{Overlay, OverlayAt};
|
pub use overlay::{Overlay, OverlayAt};
|
||||||
|
|
||||||
|
/// like assert!(), but causes undefined behaviour at runtime when the condition is not met.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
/// UB if condition is false.
|
||||||
macro_rules! assert_unchecked {
|
macro_rules! assert_unchecked {
|
||||||
($cond:expr) => {{
|
($cond:expr) => {{
|
||||||
if !$cond {
|
if !$cond {
|
||||||
|
@ -54,6 +62,7 @@ impl Image<&[u8], 3> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// calculates a column major index, with unchecked math
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn really_unsafe_index(x: u32, y: u32, w: u32) -> usize {
|
unsafe fn really_unsafe_index(x: u32, y: u32, w: u32) -> usize {
|
||||||
// y * w + x
|
// y * w + x
|
||||||
|
@ -98,7 +107,7 @@ impl<T, const CHANNELS: usize> Image<T, CHANNELS> {
|
||||||
#[inline]
|
#[inline]
|
||||||
/// create a new image
|
/// 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 {
|
Self {
|
||||||
buffer,
|
buffer,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
|
@ -229,13 +238,15 @@ impl<const CHANNELS: usize> Image<Vec<u8>, CHANNELS> {
|
||||||
/// if width || height == 0
|
/// if width || height == 0
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn alloc(width: u32, height: u32) -> Self {
|
pub fn alloc(width: u32, height: u32) -> Self {
|
||||||
Image {
|
Self {
|
||||||
width: width.try_into().unwrap(),
|
width: width.try_into().unwrap(),
|
||||||
height: height.try_into().unwrap(),
|
height: height.try_into().unwrap(),
|
||||||
buffer: vec![0; CHANNELS * width as usize * height as usize],
|
buffer: vec![0; CHANNELS * width as usize * height as usize],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// helper macro for defining the save() method.
|
||||||
macro_rules! save {
|
macro_rules! save {
|
||||||
($channels:literal == $clr:ident ($clrhuman:literal)) => {
|
($channels:literal == $clr:ident ($clrhuman:literal)) => {
|
||||||
impl Image<Vec<u8>, $channels> {
|
impl Image<Vec<u8>, $channels> {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
//! Handles image overlay
|
||||||
use super::{assert_unchecked, really_unsafe_index, Image};
|
use super::{assert_unchecked, really_unsafe_index, Image};
|
||||||
use std::simd::SimdInt;
|
use std::simd::SimdInt;
|
||||||
use std::simd::SimdPartialOrd;
|
use std::simd::SimdPartialOrd;
|
||||||
|
@ -22,11 +23,10 @@ pub trait Overlay<W> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
/// SIMD accelerated rgba => rgb overlay.
|
||||||
|
///
|
||||||
|
/// See [blit](https://en.wikipedia.org/wiki/Bit_blit)
|
||||||
unsafe fn blit(rgb: &mut [u8], rgba: &[u8]) {
|
unsafe fn blit(rgb: &mut [u8], rgba: &[u8]) {
|
||||||
const LAST4: Simd<u8, 16> = Simd::from_array([
|
|
||||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0,
|
|
||||||
]);
|
|
||||||
|
|
||||||
let mut srci = 0;
|
let mut srci = 0;
|
||||||
let mut dsti = 0;
|
let mut dsti = 0;
|
||||||
while dsti + 16 <= rgb.len() {
|
while dsti + 16 <= rgb.len() {
|
||||||
|
@ -38,7 +38,9 @@ unsafe fn blit(rgb: &mut [u8], rgba: &[u8]) {
|
||||||
threshold,
|
threshold,
|
||||||
[3, 3, 3, 7, 7, 7, 11, 11, 11, 15, 15, 15, 0, 0, 0, 0]
|
[3, 3, 3, 7, 7, 7, 11, 11, 11, 15, 15, 15, 0, 0, 0, 0]
|
||||||
);
|
);
|
||||||
mask &= LAST4;
|
mask &= Simd::from_array([
|
||||||
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0,
|
||||||
|
]);
|
||||||
|
|
||||||
let new_rgb = simd_swizzle!(new, [0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 0, 0, 0, 0]);
|
let new_rgb = simd_swizzle!(new, [0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 0, 0, 0, 0]);
|
||||||
let blended = (new_rgb & mask) | (old & !mask);
|
let blended = (new_rgb & mask) | (old & !mask);
|
||||||
|
@ -106,8 +108,16 @@ impl OverlayAt<Image<&[u8], 4>> for Image<&mut [u8], 3> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OverlayAt<Image<&[u8], 3>> for Image<&mut [u8], 3> {
|
impl OverlayAt<Image<&[u8], 3>> for Image<&mut [u8], 3> {
|
||||||
|
/// Overlay a RGB image(with) => self at coordinates x, y.
|
||||||
|
/// As this is a `RGBxRGB` operation, blending is unnecessary,
|
||||||
|
/// and this is simply a copy.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// UB if x, y is out of bounds
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn overlay_at(&mut self, with: &Image<&[u8], 3>, x: u32, y: u32) -> &mut Self {
|
unsafe fn overlay_at(&mut self, with: &Image<&[u8], 3>, x: u32, y: u32) -> &mut Self {
|
||||||
|
/// helper macro for defining rgb=>rgb overlays. allows unrolling
|
||||||
macro_rules! o3x3 {
|
macro_rules! o3x3 {
|
||||||
($n:expr) => {{
|
($n:expr) => {{
|
||||||
for j in 0..($n as usize) {
|
for j in 0..($n as usize) {
|
||||||
|
|
Loading…
Reference in a new issue