1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkCyclicShiftImageFilter_hxx
19 #define itkCyclicShiftImageFilter_hxx
20 
21 #include "itkCyclicShiftImageFilter.h"
22 #include "itkNumericTraits.h"
23 #include "itkProgressReporter.h"
24 #include "itkImageRegionIteratorWithIndex.h"
25 
26 namespace itk
27 {
28 
29 template< typename TInputImage, typename TOutputImage >
30 CyclicShiftImageFilter< TInputImage, TOutputImage >
CyclicShiftImageFilter()31 ::CyclicShiftImageFilter()
32 {
33   m_Shift.Fill( NumericTraits< OffsetValueType >::ZeroValue() );
34   this->DynamicMultiThreadingOn();
35 }
36 
37 template< typename TInputImage, typename TOutputImage >
38 void
39 CyclicShiftImageFilter< TInputImage, TOutputImage >
GenerateInputRequestedRegion()40 ::GenerateInputRequestedRegion()
41 {
42   // Call the superclass' implementation of this method.
43   Superclass::GenerateInputRequestedRegion();
44 
45   // We need all the input.
46   InputImagePointer input = const_cast< InputImageType * >( this->GetInput() );
47   if ( !input )
48     {
49     return;
50     }
51   input->SetRequestedRegionToLargestPossibleRegion();
52 }
53 
54 template< typename TInputImage, typename TOutputImage >
55 void
56 CyclicShiftImageFilter< TInputImage, TOutputImage >
DynamicThreadedGenerateData(const OutputImageRegionType & outputRegionForThread)57 ::DynamicThreadedGenerateData(const OutputImageRegionType & outputRegionForThread)
58 {
59   const InputImageType * inputImage = this->GetInput();
60 
61   // The index and size of the image needed to compute the shift
62   const IndexType outIdx = this->GetOutput()->GetLargestPossibleRegion().GetIndex();
63   const SizeType  outSize = this->GetOutput()->GetLargestPossibleRegion().GetSize();
64 
65   // Now iterate over the pixels of the output region for this thread.
66   ImageRegionIteratorWithIndex< OutputImageType > outIt(this->GetOutput(), outputRegionForThread);
67   for ( outIt.GoToBegin(); !outIt.IsAtEnd(); ++outIt )
68     {
69     IndexType index = outIt.GetIndex();
70 
71     for ( unsigned int i = 0; i < ImageDimension; ++i )
72       {
73       IndexValueType shiftedIdx = ( index[i] - outIdx[i] - m_Shift[i] )
74         % static_cast< OffsetValueType >(outSize[i]);
75       if ( shiftedIdx < 0 )
76         {
77         shiftedIdx += outSize[i];
78         }
79       index[i] = shiftedIdx + outIdx[i];
80       }
81 
82     outIt.Set( static_cast< OutputImagePixelType >( inputImage->GetPixel( index ) ) );
83     }
84 }
85 
86 template< typename TInputImage, typename TOutputImage >
87 void
88 CyclicShiftImageFilter< TInputImage, TOutputImage >
PrintSelf(std::ostream & os,Indent indent) const89 ::PrintSelf(std::ostream & os, Indent indent) const
90 {
91   Superclass::PrintSelf(os, indent);
92 
93   os << indent << "Shift: " << m_Shift << std::endl;
94 }
95 
96 } // end namespace itk
97 #endif
98