mod gray;
mod rgb;
mod rgba;
pub use gray::*;
pub use rgb::*;
pub use rgba::*;
#[cfg(feature = "png")]
mod png;
#[cfg(feature = "png")]
pub use self::png::PngColorType;
pub trait Pixel {
type Component;
fn components(&self) -> &[Self::Component];
fn components_mut(&mut self) -> &mut [Self::Component];
fn invert(&mut self);
}
#[repr(C)]
pub struct Bitmap<T> {
pixels: *mut T,
width: u32,
height: u32,
}
unsafe impl<T> Send for Bitmap<T> {}
impl<T> AsRef<Bitmap<T>> for Bitmap<T> {
fn as_ref(&self) -> &Bitmap<T> {
self
}
}
impl<T> AsMut<Bitmap<T>> for Bitmap<T> {
fn as_mut(&mut self) -> &mut Bitmap<T> {
self
}
}
impl<T> Clone for Bitmap<T> {
fn clone(&self) -> Self {
let mut new = Self::new(self.width, self.height);
new.raw_pixels_mut().copy_from_slice(self.raw_pixels());
new
}
}
impl<T> Bitmap<T> {
pub fn new(width: u32, height: u32) -> Self {
let size = (width * height) as usize;
let pixels = core::mem::ManuallyDrop::new(Vec::with_capacity(size)).as_mut_ptr();
Self {
pixels,
width,
height,
}
}
}
impl<T> Drop for Bitmap<T> {
fn drop(&mut self) {
let size = (self.width * self.height) as usize;
let _pixels = unsafe { Vec::from_raw_parts(self.pixels, size, size) };
}
}
impl<T> Bitmap<T> {
pub fn width(&self) -> u32 {
self.width
}
pub fn height(&self) -> u32 {
self.height
}
pub fn pixels(&self) -> &[T] {
unsafe { std::slice::from_raw_parts(self.pixels, (self.width * self.height) as usize) }
}
pub fn pixels_mut(&mut self) -> &mut [T] {
unsafe { std::slice::from_raw_parts_mut(self.pixels, (self.width * self.height) as usize) }
}
pub fn raw_pixels(&self) -> &[u8] {
let pixels = self.pixels();
unsafe {
core::slice::from_raw_parts(
pixels.as_ptr() as _,
pixels.len() * core::mem::size_of::<T>(),
)
}
}
pub fn raw_pixels_mut(&mut self) -> &mut [u8] {
let pixels = self.pixels_mut();
unsafe {
core::slice::from_raw_parts_mut(
pixels.as_mut_ptr() as _,
pixels.len() * core::mem::size_of::<T>(),
)
}
}
pub fn pixel(&self, x: u32, y: u32) -> &T {
let index = x + y * self.width();
&self.pixels()[index as usize]
}
pub fn pixel_mut(&mut self, x: u32, y: u32) -> &mut T {
let index = x + y * self.width();
&mut self.pixels_mut()[index as usize]
}
pub fn invert(&mut self)
where
T: Pixel,
{
self.pixels_mut().iter_mut().for_each(|pixel| {
pixel.invert();
})
}
pub fn flip_x(&mut self) {
let width = self.width();
let height = self.height();
let pixels = self.pixels_mut();
for y in 0..height {
for x in 0..width / 2 {
let nx = width - x - 1;
unsafe {
core::ptr::swap(
&mut pixels[(x + y * width) as usize],
&mut pixels[(nx + y * width) as usize],
);
}
}
}
}
pub fn flip_y(&mut self) {
let width = self.width();
let height = self.height();
let pixels = self.pixels_mut();
for y in 0..height / 2 {
for x in 0..width {
let ny = height - y - 1;
unsafe {
core::ptr::swap(
&mut pixels[(x + y * width) as usize],
&mut pixels[(x + ny * width) as usize],
);
}
}
}
}
pub fn convert<R>(&self) -> Bitmap<R>
where
T: Copy,
R: From<T>,
{
let mut bitmap = Bitmap::<R>::new(self.width(), self.height());
bitmap
.pixels_mut()
.iter_mut()
.zip(self.pixels().iter())
.for_each(|(out_pixel, in_pixel)| *out_pixel = From::from(*in_pixel));
bitmap
}
}
impl<T> Bitmap<T> {
pub(crate) fn as_raw(&self) -> *const u8 {
self as *const _ as *const u8
}
pub(crate) fn as_raw_mut(&mut self) -> *mut u8 {
self as *mut _ as *mut u8
}
}
impl<'a, A, T> From<&'a Bitmap<A>> for Bitmap<T>
where
A: Copy,
T: From<A>,
{
fn from(bitmap: &'a Bitmap<A>) -> Self {
bitmap.convert()
}
}