use crate::*;
#[cfg(feature = "parallel")]
use rayon::prelude::*;
use std::marker::PhantomData;
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Meta<T: Type, C: Color> {
pub size: Size,
_type: PhantomData<T>,
_color: PhantomData<C>,
}
impl<T: Type, C: Color> Meta<T, C> {
pub fn new(size: impl Into<Size>) -> Meta<T, C> {
Meta {
size: size.into(),
_type: PhantomData,
_color: PhantomData,
}
}
#[inline]
pub fn width_step(&self) -> usize {
self.size.width * C::CHANNELS
}
#[inline]
pub fn num_pixels(&self) -> usize {
self.size.width * self.size.height
}
#[inline]
pub fn num_values(&self) -> usize {
self.size.width * self.size.height * C::CHANNELS
}
#[inline]
pub fn num_bytes(&self) -> usize {
self.size.width * self.size.height * C::CHANNELS * std::mem::size_of::<T>()
}
#[inline]
pub fn has_alpha(&self) -> bool {
C::ALPHA.is_some()
}
#[inline]
pub fn is_alpha_channel(&self, c: Channel) -> bool {
C::ALPHA == Some(c)
}
#[inline]
pub fn color_name(&self) -> &str {
C::NAME
}
#[inline]
pub fn type_name(&self) -> &str {
T::type_name()
}
#[inline]
pub fn size(&self) -> Size {
self.size
}
#[inline]
pub fn width(&self) -> usize {
self.size.width
}
#[inline]
pub fn height(&self) -> usize {
self.size.height
}
#[inline]
pub fn type_max(&self) -> f64 {
T::MAX
}
#[inline]
pub fn type_min(&self) -> f64 {
T::MIN
}
#[inline]
pub fn index(&self, pt: impl Into<Point>) -> usize {
let pt = pt.into();
self.width_step() * pt.y + pt.x * C::CHANNELS
}
#[inline]
pub fn new_pixel(&self) -> Pixel<C> {
Pixel::new()
}
pub fn convert_index_to_point(&self, n: usize) -> Point {
let width = self.size.width;
let y = n / width / C::CHANNELS;
let x = (n - (y * width * C::CHANNELS)) / C::CHANNELS;
Point::new(x, y)
}
#[cfg(not(feature = "parallel"))]
pub fn iter(&self) -> impl '_ + std::iter::Iterator<Item = Point> {
(0..self.num_pixels())
.into_iter()
.map(move |n| self.convert_index_to_point(n))
}
#[cfg(feature = "parallel")]
pub fn iter(&self) -> impl '_ + rayon::iter::ParallelIterator<Item = Point> {
(0..self.num_pixels())
.into_par_iter()
.map(move |n| self.convert_index_to_point(n))
}
}