use std::ops::{Add, AddAssign};
use std::ops::{Sub, SubAssign};
use std::ops::{Mul, MulAssign};
use std::ops::{Div, DivAssign};
use {ScalarVal, Pixel, PixelArithmetic};
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct PixelVal<T>(pub T) where T: Pixel;
impl<PixelP> PixelVal<PixelP>
where PixelP: Pixel
{
pub fn calc_minimum_pitch(width: u32, height: u32) -> usize {
PixelP::calc_minimum_pitch(width, height)
}
pub fn calc_size_in_bytes(width: u32, height: u32, pitch: u32) -> Option<usize> {
PixelP::calc_size_in_bytes(width, height, pitch)
}
pub fn load_from_raw_buffer(x: u32, y: u32, pitch: u32, buffer: &[u8]) -> Self {
PixelVal(PixelP::load_from_raw_buffer(x, y, pitch, buffer))
}
pub fn write_into_raw_buffer(&self, x: u32, y: u32, pitch: u32, buffer: &mut [u8]) {
self.0.write_into_raw_buffer(x, y, pitch, buffer)
}
}
macro_rules! derive_std_op_for_px_px {
($op_type:ident, $op_std_func:ident, $op_px_func:ident) => (
impl<T> $op_type<PixelVal<T>> for PixelVal<T>
where T: PixelArithmetic
{
type Output = PixelVal<T>;
fn $op_std_func(self, rhs: Self) -> Self {
PixelVal((self.0).$op_px_func(rhs.0))
}
}
)
}
derive_std_op_for_px_px!(Add, add, add_px_px);
derive_std_op_for_px_px!(Sub, sub, sub_px_px);
derive_std_op_for_px_px!(Mul, mul, mul_px_px);
derive_std_op_for_px_px!(Div, div, div_px_px);
macro_rules! derive_std_op_for_px_sc_and_sc_px {
($op_type:ident, $op_std_func:ident, $op_px_sc_func:ident, $op_sc_px_func:ident) => (
impl<T> $op_type<ScalarVal<T::ScalarT>> for PixelVal<T>
where T: PixelArithmetic
{
type Output = PixelVal<T>;
fn $op_std_func(self, rhs: ScalarVal<T::ScalarT>) -> Self::Output {
PixelVal((self.0).$op_px_sc_func(rhs.0))
}
}
impl<T> $op_type<PixelVal<T>> for ScalarVal<T::ScalarT>
where T: PixelArithmetic
{
type Output = PixelVal<T>;
fn $op_std_func(self, rhs: PixelVal<T>) -> Self::Output {
PixelVal((rhs.0).$op_sc_px_func(self.0))
}
}
)
}
derive_std_op_for_px_sc_and_sc_px!(Add, add, add_px_sc, add_sc_px);
derive_std_op_for_px_sc_and_sc_px!(Sub, sub, sub_px_sc, sub_sc_px);
derive_std_op_for_px_sc_and_sc_px!(Mul, mul, mul_px_sc, mul_sc_px);
derive_std_op_for_px_sc_and_sc_px!(Div, div, div_px_sc, div_sc_px);
macro_rules! derive_std_assign_op_for_px_px_and_px_sc {
($op_type:ident, $op_std_assign_func:ident, $op_std_func:ident) => (
impl<T> $op_type<PixelVal<T>> for PixelVal<T>
where T: PixelArithmetic
{
fn $op_std_assign_func(&mut self, rhs: PixelVal<T>) {
*self = (*self).$op_std_func(rhs)
}
}
impl<T> $op_type<ScalarVal<T::ScalarT>> for PixelVal<T>
where T: PixelArithmetic
{
fn $op_std_assign_func(&mut self, rhs: ScalarVal<T::ScalarT>) {
*self = (*self).$op_std_func(rhs)
}
}
)
}
derive_std_assign_op_for_px_px_and_px_sc!(AddAssign, add_assign, add);
derive_std_assign_op_for_px_px_and_px_sc!(SubAssign, sub_assign, sub);
derive_std_assign_op_for_px_px_and_px_sc!(MulAssign, mul_assign, mul);
derive_std_assign_op_for_px_px_and_px_sc!(DivAssign, div_assign, div);