/* 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 Image3Dlinear.hxx */
//! _Image3Dlinear_hxx
#ifndef _Image3Dlinear_hxx
#define _Image3Dlinear_hxx

#include<ImLib3D/Interpolator3D.hpp>

// *******************************************************
// ********************** Image3Dlinear ********************
// *******************************************************
template<class Im3DValue>
Image3Dlinear<Im3DValue>::~Image3Dlinear()
{
	if(destroyInterpolator && interpolator){delete interpolator;}
	_Base::DeAllocate();	
}

// *************************** Accessors ******* ***********
template<class Im3DValue>
Im3DValue Image3Dlinear<Im3DValue>::SafeValue(int pos) const 
{
	if ((pos < 0) || (pos >= Container3D<Im3DValue>::GetNVoxels()))
		return zero;
	else return (*this)(pos);
}

template<class Im3DValue>
void
Image3Dlinear<Im3DValue>::ComplexImag(Image3Df &imag) const
{
	imag.Resize(Container3D<Im3DValue>::Size());

	const_iteratorFast p;
	Image3Df::iteratorFast pImag;
	for (p = Container3D<Im3DValue>::begin(),pImag=imag.begin(); p != Container3D<Im3DValue>::end(); p++,pImag++)
	{
		*pImag=(*p).imag();
	}
}
template<class Im3DValue>
void
Image3Dlinear<Im3DValue>::ComplexReal(Image3Df &imag) const
{
	imag.Resize(Container3D<Im3DValue>::Size());

	const_iteratorFast p;
	Image3Df::iteratorFast pImag;
	for (p = Container3D<Im3DValue>::begin(),pImag=imag.begin(); p != Container3D<Im3DValue>::end(); p++,pImag++)
	{
		*pImag=(*p).real();
	}
}
template<class Im3DValue>
void
Image3Dlinear<Im3DValue>::ComplexNorm2(Image3Df &imag) const
{
	imag.Resize(Container3D<Im3DValue>::Size());

	const_iteratorFast p;
	Image3Df::iteratorFast pImag;
	for (p = Container3D<Im3DValue>::begin(),pImag=imag.begin(); p != Container3D<Im3DValue>::end(); p++,pImag++)
	{
		*pImag=norm(*p);
	}
}
template<class Im3DValue>
void
Image3Dlinear<Im3DValue>::ComplexModule(Image3Df &imag) const
{
	imag.Resize(Container3D<Im3DValue>::Size());

	const_iteratorFast p;
	Image3Df::iteratorFast pImag;
	for (p = Container3D<Im3DValue>::begin(),pImag=imag.begin(); p != Container3D<Im3DValue>::end(); p++,pImag++)
	{
		*pImag=sqrt(norm(*p));
	}
}

//! L2-Norm of the image (Sum of all (voxelvalue*voxelvalue)s)
template<class Im3DValue>
double
Image3Dreal<Im3DValue>::L2Norm() const
{
	double energie = 0;
	typename Image3Dreal<Im3DValue>::const_iteratorFastMasked p;
	for (p=Container3D<Im3DValue>::begin(); p!=Container3D<Im3DValue>::end(); p++)
	{
		energie += (*p)*(*p);
	}
	return sqrt(energie);
}

template<class Im3DValue>
void
Image3Dlinear<Im3DValue>::GetComponent(int c,Image3Df &res) const 
{
	res.Resize(_Base::Size());
	const_iteratorFast p;
	Image3Df::iteratorFast rp;
	for(p=_Base::begin(),rp=res.begin();p!=_Base::end(); p++,rp++)
	{
		*rp=(*p)(c);
	}		
}
template<class Im3DValue>
void
Image3Dlinear<Im3DValue>::SetComponent(int c,const Image3Df &src)
{
	src.Resize(_Base::Size());
	iteratorFast p;
	Image3Df::const_iteratorFast rp;
	for(p=_Base::begin(),rp=src.begin();p!=_Base::end(); p++,rp++)
	{
		(*p)(c)=*rp;
	}		
}

#endif // _Image3Dlinear_hxx
