fast image operations
Diffstat (limited to 'src/convert.rs')
| -rw-r--r-- | src/convert.rs | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/convert.rs b/src/convert.rs new file mode 100644 index 0000000..5704f26 --- /dev/null +++ b/src/convert.rs @@ -0,0 +1,64 @@ +//! define From's for images. +//! these conversions are defined by [`PFrom`]. +use crate::{pixels::convert::PFrom, Image}; + +fn map<const A: usize, const B: usize>(image: Image<&[u8], A>) -> Image<Box<[u8]>, B> +where + [u8; B]: PFrom<A>, +{ + let buffer = image + .chunked() + .copied() + .flat_map(<[u8; B] as PFrom<A>>::pfrom) + .collect::<Vec<_>>() + .into(); + // SAFETY: ctor + unsafe { Image::new(image.width, image.height, buffer) } +} + +macro_rules! convert { + ($a:literal => $b:literal) => { + impl From<Image<&[u8], $b>> for Image<Box<[u8]>, $a> { + fn from(value: Image<&[u8], $b>) -> Self { + map(value) + } + } + }; +} + +macro_rules! cv { + [$($n:literal),+] => { + $(convert!($n => 1); + convert!($n => 2); + convert!($n => 3); + convert!($n => 4);)+ + }; +} + +cv![1, 2, 3, 4]; + +macro_rules! boxconv { + ($a:literal => $b: literal) => { + impl From<Image<Box<[u8]>, $b>> for Image<Box<[u8]>, $a> { + fn from(value: Image<Box<[u8]>, $b>) -> Self { + value.as_ref().into() + } + } + }; +} + +boxconv!(1 => 2); +boxconv!(1 => 3); +boxconv!(1 => 4); + +boxconv!(2 => 1); +boxconv!(2 => 3); +boxconv!(2 => 4); + +boxconv!(3 => 1); +boxconv!(3 => 2); +boxconv!(3 => 4); + +boxconv!(4 => 1); +boxconv!(4 => 2); +boxconv!(4 => 3); |