/* ImLib3D
 * Copyright (c) 2001, ULP-IPB Strasbourg.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
/*!
  \file   Arithmetic.hpp
  \brief  Linear Image Processing Classes

  <long description> This file contains all class declarations for arithmetic image processing
  tasks. The definitions are in the .hxx file.  

  This functions here are supposed only to be the real code and algorithms for image processing,
  the operators and functions that call these functions will be declared in the Image3D-classes for 
  utilisation. 

*/


#ifndef _Arithmetic_hpp
#define _Arithmetic_hpp

#include<ImLib3D/ImageProcessor.hpp>

namespace IP3D
{
/*! #&Addition&#     Adds 2 images
        Ignores masks.
     <UL>Args:
      <LI>Source image 1  type:ImageType
      <LI>Source image 2  type:ImageType
      <LI>Result image    type:ImageType
     </UL>
~*/
	template <class ImageType>
	void Addition(const ImageType& im1, const ImageType& im2, ImageType& imDest);
	template <class ImageType>
	static void Apply(const ImageType& im1, const typename ImageType::value_type& scalarValue, ImageType& imDest);
};

namespace IP3D
{
/*! #&AdditionWithConstant&#     Adds 2 images
        Ignores masks.
     <UL>Args:
      <LI>Source image 1  type:ImageType
      <LI>Source image 2  type:ImageType
      <LI>Result image    type:ImageType
     </UL>
~*/
	template <class ImageType>
	void AdditionWithConstant(const ImageType& im1, const typename ImageType::value_type& scalarValue, ImageType& imDest);
};


namespace IP3D
{
/*! #&Difference&#     Substracts two images.
        Ignores masks.
     <UL>Args:
      <LI>Source image 1  type:ImageType
      <LI>Source image 2  type:ImageType
      <LI>Result image    type:ImageType
     </UL>
~*/
	template <class ImageType>
	void Difference(const ImageType& im1, const ImageType& im2, ImageType& imDest);
};
namespace IP3D
{
/*! #&DifferenceWithConstant&#     Substracts two images.
        Ignores masks.
     <UL>Args:
      <LI>Source image 1  type:ImageType
      <LI>Source image 2  type:ImageType
      <LI>Result image    type:ImageType
     </UL>
~*/
	template <class ImageType>
	void DifferenceWithConstant(const ImageType& im1, const typename ImageType::value_type& scalarValue, ImageType& imDest);
};


namespace IP3D
{
/*! #&Multiplication&#     Multiplies two images.
        Ignores masks.
     <UL>Args:
      <LI>Source image 1  type:ImageType
      <LI>Source image 2  type:ImageType
      <LI>Result image    type:ImageType
     </UL>
~*/
	template <class ImageType>
	void Multiplication(const ImageType& im1, const ImageType& im2, ImageType& imDest);
};

namespace IP3D
{
/*! #&MultiplicationWithConstant&#     Multiplies an image by a constant floating point value.
        The constant is double-precision. Ignores masks.
     <UL>Args:
      <LI>Source image  type:ImageType
      <LI>Constant      type:double
      <LI>Result image  type:ImageType
     </UL>
~*/
	template <class ImageType>
	void MultiplicationWithConstant(const ImageType& im1, double scalarValue, ImageType& imDest);
};


namespace IP3D
{
/*! #&Division&#     Divides two images.
        Ignores masks.
     <UL>Args:
      <LI>Source image 1  type:ImageType
      <LI>Source image 2  type:ImageType
      <LI>Result image    type:ImageType
     </UL>
~*/
	template <class ImageType>
	void Division(const ImageType& im1, const ImageType& im2, ImageType& imDest);
};

namespace IP3D
{
/*! #&MaxImage&#     Maximum of two images.
        Ignores masks.
     <UL>Args:
      <LI>Source image 1  type:ImageType
      <LI>Source image 2  type:ImageType
      <LI>Result image    type:ImageType
     </UL>
~*/
	template <class ImageType>
	void MaxImage(const ImageType& im1, const ImageType& im2, ImageType& imDest);
};

namespace IP3D
{
/*! #&Abs&#     Absolute value of an image.
        Ignores masks.
     <UL>Args:
      <LI>Source image 1  type:ImageType
      <LI>Result image    type:ImageType
     </UL>
~*/
	template <class ImageType>
	void Abs(const ImageType& im1, ImageType& imDest);
};
template <class Im3DValue> inline Im3DValue AbsoluteValue(const Im3DValue &v)
{ThrowError("AbsoluteValue unimplemented for type:%s",TypeName<Im3DValue>());return v;}
template <> inline double    AbsoluteValue<double   >(const double    &v){return fabs(v);}
template <> inline float     AbsoluteValue<float    >(const float     &v){return fabs(v);}
template <> inline int       AbsoluteValue<int      >(const int       &v){return  abs(v);}
template <> inline long  int AbsoluteValue<long  int>(const long  int &v){return labs(v);}
template <> inline short int AbsoluteValue<short int>(const short int &v){return labs(v);}
template <> inline byte      AbsoluteValue<byte     >(const byte      &v){return      v ;}

#include<ImLib3D/Arithmetic.hxx>

#endif  //_Arithmetic_hpp
