mirror of
https://github.com/bend-n/fimg.git
synced 2024-12-22 10:28:21 -06:00
packing trait
This commit is contained in:
parent
3b69335dcd
commit
669a541bb7
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "fimg"
|
name = "fimg"
|
||||||
version = "0.4.25"
|
version = "0.4.26"
|
||||||
authors = ["bend-n <bend.n@outlook.com>"]
|
authors = ["bend-n <bend.n@outlook.com>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use stackblur_iter::imgref::ImgRefMut;
|
use stackblur_iter::imgref::ImgRefMut;
|
||||||
|
|
||||||
use crate::{pixels::convert::PFrom, Image};
|
use crate::Image;
|
||||||
|
|
||||||
impl<T: AsMut<[u32]> + AsRef<[u32]>> Image<T, 1> {
|
impl<T: AsMut<[u32]> + AsRef<[u32]>> Image<T, 1> {
|
||||||
/// Blur a image of packed 32 bit integers, `[0xAARRGGBB]`.
|
/// Blur a image of packed 32 bit integers, `[0xAARRGGBB]`.
|
||||||
|
@ -13,8 +13,7 @@ impl<T: AsMut<[u32]> + AsRef<[u32]>> Image<T, 1> {
|
||||||
|
|
||||||
impl<const N: usize> Image<Box<[u8]>, N>
|
impl<const N: usize> Image<Box<[u8]>, N>
|
||||||
where
|
where
|
||||||
[u8; 4]: PFrom<N>,
|
[u8; N]: crate::Pack,
|
||||||
[u8; N]: PFrom<4>,
|
|
||||||
{
|
{
|
||||||
/// Blur a image.
|
/// Blur a image.
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -38,8 +37,7 @@ where
|
||||||
|
|
||||||
impl<const N: usize> Image<&[u8], N>
|
impl<const N: usize> Image<&[u8], N>
|
||||||
where
|
where
|
||||||
[u8; 4]: PFrom<N>,
|
[u8; N]: crate::Pack,
|
||||||
[u8; N]: PFrom<4>,
|
|
||||||
{
|
{
|
||||||
/// Blur a image.
|
/// Blur a image.
|
||||||
pub fn blur(self, radius: usize) -> Image<Box<[u8]>, N> {
|
pub fn blur(self, radius: usize) -> Image<Box<[u8]>, N> {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! define From's for images.
|
//! define From's for images.
|
||||||
//! these conversions are defined by [`PFrom`].
|
//! these conversions are defined by [`PFrom`].
|
||||||
use crate::{pixels::convert::PFrom, Image};
|
use crate::{pixels::convert::PFrom, Image, Pack};
|
||||||
|
|
||||||
fn map<const A: usize, const B: usize>(image: Image<&[u8], A>) -> Image<Box<[u8]>, B>
|
fn map<const A: usize, const B: usize>(image: Image<&[u8], A>) -> Image<Box<[u8]>, B>
|
||||||
where
|
where
|
||||||
|
@ -64,33 +64,13 @@ boxconv!(4 => 1);
|
||||||
boxconv!(4 => 2);
|
boxconv!(4 => 2);
|
||||||
boxconv!(4 => 3);
|
boxconv!(4 => 3);
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub const fn pack([r, g, b, a]: [u8; 4]) -> u32 {
|
|
||||||
((a as u32) << 24) | ((r as u32) << 16) | ((g as u32) << 8) | (b as u32)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub const fn unpack(n: u32) -> [u8; 4] {
|
|
||||||
[
|
|
||||||
((n >> 16) & 0xFF) as u8,
|
|
||||||
((n >> 8) & 0xFF) as u8,
|
|
||||||
(n & 0xFF) as u8,
|
|
||||||
((n >> 24) & 0xFF) as u8,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<const N: usize> From<Image<&[u8], N>> for Image<Box<[u32]>, 1>
|
impl<const N: usize> From<Image<&[u8], N>> for Image<Box<[u32]>, 1>
|
||||||
where
|
where
|
||||||
[u8; 4]: PFrom<N>,
|
[u8; N]: Pack,
|
||||||
{
|
{
|
||||||
/// Pack into ARGB.
|
/// Pack into ARGB.
|
||||||
fn from(value: Image<&[u8], N>) -> Self {
|
fn from(value: Image<&[u8], N>) -> Self {
|
||||||
let buf = value
|
let buf = value.chunked().map(Pack::pack).collect();
|
||||||
.chunked()
|
|
||||||
.copied()
|
|
||||||
.map(PFrom::pfrom)
|
|
||||||
.map(pack)
|
|
||||||
.collect();
|
|
||||||
// SAFETY: ctor
|
// SAFETY: ctor
|
||||||
unsafe { Self::new(value.width, value.height, buf) }
|
unsafe { Self::new(value.width, value.height, buf) }
|
||||||
}
|
}
|
||||||
|
@ -98,18 +78,14 @@ where
|
||||||
|
|
||||||
pub fn unpack_all<const N: usize>(buffer: &[u32]) -> impl Iterator<Item = u8> + '_
|
pub fn unpack_all<const N: usize>(buffer: &[u32]) -> impl Iterator<Item = u8> + '_
|
||||||
where
|
where
|
||||||
[u8; N]: PFrom<4>,
|
[u8; N]: Pack,
|
||||||
{
|
{
|
||||||
buffer
|
buffer.iter().copied().flat_map(<[u8; N]>::unpack)
|
||||||
.iter()
|
|
||||||
.copied()
|
|
||||||
.map(unpack)
|
|
||||||
.flat_map(<[u8; N] as PFrom<4>>::pfrom)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const N: usize> From<Image<&[u32], 1>> for Image<Box<[u8]>, N>
|
impl<const N: usize> From<Image<&[u32], 1>> for Image<Box<[u8]>, N>
|
||||||
where
|
where
|
||||||
[u8; N]: PFrom<4>,
|
[u8; N]: Pack,
|
||||||
{
|
{
|
||||||
fn from(value: Image<&[u32], 1>) -> Self {
|
fn from(value: Image<&[u32], 1>) -> Self {
|
||||||
let buf = unpack_all(value.buffer).collect();
|
let buf = unpack_all(value.buffer).collect();
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
//! text raster
|
//! text raster
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
convert::{pack, unpack},
|
|
||||||
pixels::{float, Wam},
|
pixels::{float, Wam},
|
||||||
Image,
|
Image, Pack,
|
||||||
};
|
};
|
||||||
use fontdue::{layout::TextStyle, Font};
|
use fontdue::{layout::TextStyle, Font};
|
||||||
use umath::{generic_float::Constructors, FF32};
|
use umath::{generic_float::Constructors, FF32};
|
||||||
|
@ -37,11 +36,12 @@ impl Image<&mut [u32], 1> {
|
||||||
// SAFETY: the rasterizer kinda promises that metrics width and height are in bounds
|
// SAFETY: the rasterizer kinda promises that metrics width and height are in bounds
|
||||||
let fill = unsafe { float(*bitmap.get_unchecked(j * metrics.width + i)) };
|
let fill = unsafe { float(*bitmap.get_unchecked(j * metrics.width + i)) };
|
||||||
// SAFETY: we clampin
|
// SAFETY: we clampin
|
||||||
let bg = unsafe { unpack(*self.buffer.get_unchecked(self.at(x, y))) };
|
let bg: [u8; 4] =
|
||||||
|
unsafe { Pack::unpack(*self.buffer.get_unchecked(self.at(x, y))) };
|
||||||
// SAFETY: see above
|
// SAFETY: see above
|
||||||
*unsafe { self.buffer.get_unchecked_mut(self.at(x, y)) } =
|
*unsafe { self.buffer.get_unchecked_mut(self.at(x, y)) } =
|
||||||
// SAFETY: fill is 0..=1
|
// SAFETY: fill is 0..=1
|
||||||
pack(unsafe { bg.wam(color, FF32::one() - fill, fill) });
|
Pack::pack(unsafe { &bg.wam(color, FF32::one() - fill, fill) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,8 @@ mod drawing;
|
||||||
mod r#dyn;
|
mod r#dyn;
|
||||||
pub(crate) mod math;
|
pub(crate) mod math;
|
||||||
mod overlay;
|
mod overlay;
|
||||||
|
mod pack;
|
||||||
|
pub use pack::Pack;
|
||||||
pub mod pixels;
|
pub mod pixels;
|
||||||
#[cfg(feature = "scale")]
|
#[cfg(feature = "scale")]
|
||||||
pub mod scale;
|
pub mod scale;
|
||||||
|
|
55
src/pack.rs
Normal file
55
src/pack.rs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
//! trait for packing pixels
|
||||||
|
|
||||||
|
use crate::pixels::convert::{PFrom, RGB, RGBA, Y, YA};
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub const fn pack([r, g, b, a]: [u8; 4]) -> u32 {
|
||||||
|
((a as u32) << 24) | ((r as u32) << 16) | ((g as u32) << 8) | (b as u32)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub const fn unpack(n: u32) -> [u8; 4] {
|
||||||
|
[
|
||||||
|
((n >> 16) & 0xFF) as u8,
|
||||||
|
((n >> 8) & 0xFF) as u8,
|
||||||
|
(n & 0xFF) as u8,
|
||||||
|
((n >> 24) & 0xFF) as u8,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// packs and unpacks this pixel
|
||||||
|
/// note that `unpack(pack(p))` may not equal `p`
|
||||||
|
pub trait Pack<P = u32> {
|
||||||
|
/// pack this pixel
|
||||||
|
fn pack(&self) -> P;
|
||||||
|
/// unpacks this pixel
|
||||||
|
fn unpack(from: P) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! simple {
|
||||||
|
($p:ident) => {
|
||||||
|
impl Pack for $p {
|
||||||
|
fn pack(&self) -> u32 {
|
||||||
|
pack(PFrom::pfrom(*self))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unpack(from: u32) -> $p {
|
||||||
|
PFrom::pfrom(unpack(from))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
simple!(RGBA);
|
||||||
|
simple!(RGB);
|
||||||
|
simple!(YA);
|
||||||
|
simple!(Y);
|
||||||
|
|
||||||
|
impl Pack<u8> for Y {
|
||||||
|
fn pack(&self) -> u8 {
|
||||||
|
self[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unpack(from: u8) -> Self {
|
||||||
|
[from]
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,12 +2,12 @@ use crate::Image;
|
||||||
|
|
||||||
#[cfg(feature = "real-show")]
|
#[cfg(feature = "real-show")]
|
||||||
mod real {
|
mod real {
|
||||||
use crate::{pixels::convert::PFrom, Image};
|
use crate::Image;
|
||||||
use minifb::{Key, Window};
|
use minifb::{Key, Window};
|
||||||
|
|
||||||
pub fn show<const CHANNELS: usize>(i: Image<&[u8], CHANNELS>)
|
pub fn show<const CHANNELS: usize>(i: Image<&[u8], CHANNELS>)
|
||||||
where
|
where
|
||||||
[u8; 4]: PFrom<CHANNELS>,
|
[u8; CHANNELS]: crate::Pack,
|
||||||
{
|
{
|
||||||
let mut win = Window::new(
|
let mut win = Window::new(
|
||||||
"show",
|
"show",
|
||||||
|
|
Loading…
Reference in a new issue