use std::ops::{Add, AddAssign};
use std::ops::{Sub, SubAssign};
use std::ops::{Mul, MulAssign};
use std::ops::{Div, DivAssign};
use ScalarVal;
use {PixelArithmetic, PixelVal};
use {Image, ImageBufferVal};
#[derive(Clone)]
pub struct ImageVal<ImageP>(pub ImageP) where ImageP: Image;
impl<ImageP> ImageVal<ImageP>
where ImageP: Image
{
pub fn get_size_in_bytes(&self) -> usize {
self.0.get_size_in_bytes()
}
pub fn load_from_raw_buffer(&mut self, buffer: &[u8]) {
self.0.load_from_raw_buffer(buffer)
}
pub fn write_into_raw_buffer(&self, buffer: &mut [u8]) {
self.0.write_into_raw_buffer(buffer)
}
pub fn width(&self) -> u32 {
self.0.width()
}
pub fn height(&self) -> u32 {
self.0.height()
}
pub fn pitch(&self) -> u32 {
self.0.pitch()
}
pub fn get_pixel(&self, x: u32, y: u32) -> Option<PixelVal<ImageP::PixelT>> {
self.0.get_pixel(x, y).map(|v| PixelVal(v))
}
pub fn set_pixel(&mut self, x: u32, y: u32, value: PixelVal<ImageP::PixelT>) {
self.0.set_pixel(x, y, value.0)
}
}
macro_rules! derive_std_op_for_img_img {
($op_type:ident, $op_std_func:ident) => (
impl<'a, PixelX, ImageA, ImageB> $op_type<&'a ImageVal<ImageB>> for &'a ImageVal<ImageA>
where PixelX: PixelArithmetic,
ImageA: Image<PixelT = PixelX>,
ImageB: Image<PixelT = PixelX>
{
type Output = ImageBufferVal<ImageA::PixelT>;
fn $op_std_func(self, rhs: &'a ImageVal<ImageB>) -> Self::Output {
assert_eq!(self.width(), rhs.width());
assert_eq!(self.height(), rhs.height());
let mut result = Self::Output::new_with_size(self.width(), self.height());
for y in 0..self.height() {
for x in 0..self.width() {
let new_pixel = (self.get_pixel(x, y).unwrap()).$op_std_func(rhs.get_pixel(x, y).unwrap());
result.set_pixel(x, y, new_pixel);
}
}
result
}
}
)
}
derive_std_op_for_img_img!(Add, add);
derive_std_op_for_img_img!(Sub, sub);
derive_std_op_for_img_img!(Mul, mul);
derive_std_op_for_img_img!(Div, div);
macro_rules! derive_std_op_for_img_val_and_val_img {
($op_type:ident, $op_std_func:ident) => (
impl<'a, ImageT> $op_type<PixelVal<ImageT::PixelT>> for &'a ImageVal<ImageT>
where ImageT: Image,
ImageT::PixelT: PixelArithmetic
{
type Output = ImageBufferVal<ImageT::PixelT>;
fn $op_std_func(self, rhs: PixelVal<ImageT::PixelT>) -> Self::Output {
let mut result = Self::Output::new_with_size(self.width(), self.height());
for y in 0..self.height() {
for x in 0..self.width() {
let new_pixel = (self.get_pixel(x, y).unwrap()).$op_std_func(rhs);
result.set_pixel(x, y, new_pixel);
}
}
result
}
}
impl<'a, ImageT> $op_type<&'a ImageVal<ImageT>> for PixelVal<ImageT::PixelT>
where ImageT: Image,
ImageT::PixelT: PixelArithmetic
{
type Output = ImageBufferVal<ImageT::PixelT>;
fn $op_std_func(self, rhs: &'a ImageVal<ImageT>) -> Self::Output {
let mut result = Self::Output::new_with_size(rhs.width(), rhs.height());
for y in 0..rhs.height() {
for x in 0..rhs.width() {
let new_pixel = (self).$op_std_func(rhs.get_pixel(x, y).unwrap());
result.set_pixel(x, y, new_pixel);
}
}
result
}
}
impl<'a, ImageT> $op_type<ScalarVal<<ImageT::PixelT as PixelArithmetic>::ScalarT>> for &'a ImageVal<ImageT>
where ImageT: Image,
ImageT::PixelT: PixelArithmetic
{
type Output = ImageBufferVal<ImageT::PixelT>;
fn $op_std_func(self, rhs: ScalarVal<<ImageT::PixelT as PixelArithmetic>::ScalarT>) -> Self::Output {
let mut result = Self::Output::new_with_size(self.width(), self.height());
for y in 0..self.height() {
for x in 0..self.width() {
let new_pixel = (self.get_pixel(x, y).unwrap()).$op_std_func(rhs);
result.set_pixel(x, y, new_pixel);
}
}
result
}
}
impl<'a, ImageT> $op_type<&'a ImageVal<ImageT>> for ScalarVal<<ImageT::PixelT as PixelArithmetic>::ScalarT>
where ImageT: Image,
ImageT::PixelT: PixelArithmetic
{
type Output = ImageBufferVal<ImageT::PixelT>;
fn $op_std_func(self, rhs: &'a ImageVal<ImageT>) -> Self::Output {
let mut result = Self::Output::new_with_size(rhs.width(), rhs.height());
for y in 0..rhs.height() {
for x in 0..rhs.width() {
let new_pixel = (self).$op_std_func(rhs.get_pixel(x, y).unwrap());
result.set_pixel(x, y, new_pixel);
}
}
result
}
}
)
}
derive_std_op_for_img_val_and_val_img!(Add, add);
derive_std_op_for_img_val_and_val_img!(Sub, sub);
derive_std_op_for_img_val_and_val_img!(Mul, mul);
derive_std_op_for_img_val_and_val_img!(Div, div);
macro_rules! derive_std_assign_op_for_img_img_and_img_val {
($op_type:ident, $op_std_assign_func:ident) => (
impl<'a, PixelX, ImageA, ImageB> $op_type<&'a ImageVal<ImageB>> for ImageVal<ImageA>
where PixelX: PixelArithmetic,
ImageA: Image<PixelT = PixelX>,
ImageB: Image<PixelT = PixelX>
{
fn $op_std_assign_func(&mut self, rhs: &'a ImageVal<ImageB>) {
assert_eq!(self.width(), rhs.width());
assert_eq!(self.height(), rhs.height());
for y in 0..self.height() {
for x in 0..self.width() {
let mut pixel_lhs = self.get_pixel(x, y).unwrap();
let pixel_rhs = rhs.get_pixel(x, y).unwrap();
(pixel_lhs).$op_std_assign_func(pixel_rhs);
self.set_pixel(x, y, pixel_lhs);
}
}
}
}
impl<ImageA> $op_type<PixelVal<ImageA::PixelT>> for ImageVal<ImageA>
where ImageA: Image,
ImageA::PixelT: PixelArithmetic
{
fn $op_std_assign_func(&mut self, rhs: PixelVal<ImageA::PixelT>) {
for y in 0..self.height() {
for x in 0..self.width() {
let mut pixel = self.get_pixel(x, y).unwrap();
(pixel).$op_std_assign_func(rhs);
self.set_pixel(x, y, pixel);
}
}
}
}
impl<ImageA> $op_type<ScalarVal<<ImageA::PixelT as PixelArithmetic>::ScalarT>> for ImageVal<ImageA>
where ImageA: Image,
ImageA::PixelT: PixelArithmetic
{
fn $op_std_assign_func(&mut self, rhs: ScalarVal<<ImageA::PixelT as PixelArithmetic>::ScalarT>) {
for y in 0..self.height() {
for x in 0..self.width() {
let mut pixel = self.get_pixel(x, y).unwrap();
(pixel).$op_std_assign_func(rhs);
self.set_pixel(x, y, pixel);
}
}
}
}
)
}
derive_std_assign_op_for_img_img_and_img_val!(AddAssign, add_assign);
derive_std_assign_op_for_img_img_and_img_val!(SubAssign, sub_assign);
derive_std_assign_op_for_img_img_and_img_val!(MulAssign, mul_assign);
derive_std_assign_op_for_img_img_and_img_val!(DivAssign, div_assign);