/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkNaryFunctorImageFilter.txx,v $ Language: C++ Date: $Date: 2006/10/24 13:54:36 $ Version: $Revision: 1.20 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkNaryFunctorImageFilter_txx #define __itkNaryFunctorImageFilter_txx #include "itkNaryFunctorImageFilter.h" #include "itkImageRegionIterator.h" #include "itkProgressReporter.h" namespace itk { /** * Constructor */ template NaryFunctorImageFilter ::NaryFunctorImageFilter() { // This number will be incremented each time an image // is added over the two minimum required this->SetNumberOfRequiredInputs( 2 ); this->InPlaceOff(); } /** * ThreadedGenerateData Performs the pixel-wise addition */ template void NaryFunctorImageFilter ::ThreadedGenerateData( const OutputImageRegionType &outputRegionForThread, int threadId) { const unsigned int numberOfInputImages = static_cast< unsigned int >( this->GetNumberOfInputs() ); OutputImagePointer outputPtr = this->GetOutput(0); ImageRegionIterator outputIt(outputPtr, outputRegionForThread); // Clear the content of the output outputIt.GoToBegin(); while( !outputIt.IsAtEnd() ) { outputIt.Set( itk::NumericTraits< OutputImagePixelType >::Zero ); ++outputIt; } typedef ImageRegionConstIterator ImageRegionConstIteratorType; std::vector< ImageRegionConstIteratorType * > inputItrVector; inputItrVector.resize(numberOfInputImages); //Array< ImageRegionConstIteratorType > inputItrVector(numberOfInputImages); // support progress methods/callbacks. // count the number of inputs that are non-null unsigned int lastValidImage = 0; for (unsigned int i=0; i < numberOfInputImages; ++i) { InputImagePointer inputPtr = dynamic_cast( ProcessObject::GetInput( i ) ); if (inputPtr) { ImageRegionConstIteratorType *inputIt = new ImageRegionConstIteratorType(inputPtr,outputRegionForThread); lastValidImage = i; inputItrVector[i] = reinterpret_cast< ImageRegionConstIteratorType * >( inputIt ); inputItrVector[i]->GoToBegin(); } else { inputItrVector[i] = reinterpret_cast< ImageRegionConstIteratorType * >(NULL); } } ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); if( !inputItrVector[lastValidImage] ) { //No valid regions in the thread return; } NaryArrayType naryInputArray; naryInputArray.resize( numberOfInputImages ); outputIt.GoToBegin(); while( !inputItrVector[lastValidImage]->IsAtEnd()) { for (unsigned int inputNumber=0; inputNumber < numberOfInputImages; inputNumber++) { naryInputArray[ inputNumber ] = inputItrVector[inputNumber]->Get(); ++(*inputItrVector[inputNumber]); } outputIt.Set( m_Functor( naryInputArray ) ); ++outputIt; progress.CompletedPixel(); } for (unsigned int i=0; i < numberOfInputImages; ++i) { if (inputItrVector[i]) { delete inputItrVector[i]; } } } } // end namespace itk #endif