KWStyle - itkImageSource.txx
 
Matrix View
Description

1 /*=========================================================================
2
3   Program:   Insight Segmentation & Registration Toolkit
4   Module:    $RCSfile: itkImageSource.txx.html,v $
5   Language:  C++
6   Date:      $Date: 2006/01/17 19:15:40 $
7   Version:   $Revision: 1.4 $
8
9   Copyright (c) Insight Software Consortium. All rights reserved.
10   See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11
12   Portions of this code are covered under the VTK copyright.
13   See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details.
14
15      This software is distributed WITHOUT ANY WARRANTY; without even 
16      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
17 IND *****PURPOSE.  See the above copyright notices for more information.
18
19 =========================================================================*/
20 DEF #ifndef _itkImageSource_txx
21 DEF #define _itkImageSource_txx
22 #include "itkImageSource.h"
23
24 #include "vnl/vnl_math.h"
25
26 namespace itk
27 {
28
29 /**
30  *
31  */
32 template<class TOutputImage>
33 ImageSource<TOutputImage>
34 ::ImageSource()
35 {
36   // Create the output. We use static_cast<> here because we know the default
37   // output must be of type TOutputImage
38   typename TOutputImage::Pointer output
39 IND ****= static_cast<TOutputImage*>(this->MakeOutput(0).GetPointer()); 
40   this->ProcessObject::SetNumberOfRequiredOutputs(1);
41   this->ProcessObject::SetNthOutput(0, output.GetPointer());
42
43   // Set the default behavior of an image source to NOT release its
44   // output bulk data prior to GenerateData() in case that bulk data
45   // can be reused (an thus avoid a costly deallocate/allocate cycle).
46   this->ReleaseDataBeforeUpdateFlagOff();
47 }
48
49 /**
50  *
51  */
52 template<class TOutputImage>
53 typename ImageSource<TOutputImage>::DataObjectPointer
54 ImageSource<TOutputImage>
55 ::MakeOutput(unsigned int)
56 {
57   return static_cast<DataObject*>(TOutputImage::New().GetPointer());
58 }
59   
60 /**
61  *
62  */
63 template<class TOutputImage>
64 typename ImageSource<TOutputImage>::OutputImageType * 
65 ImageSource<TOutputImage>
66 ::GetOutput()
67 {
68   if (this->GetNumberOfOutputs() < 1)
69     {
70     return 0;
71     }
72   
73   return static_cast<TOutputImage*>
74 IND ****(this->ProcessObject::GetOutput(0));
75 }
76
77   
78 /**
79  *
80  */
81 template<class TOutputImage>
82 typename ImageSource<TOutputImage>::OutputImageType *
83 ImageSource<TOutputImage>
84 ::GetOutput(unsigned int idx)
85 {
86   return static_cast<TOutputImage*>
87 IND ****(this->ProcessObject::GetOutput(idx));
88 }
89
90
91 EML
92 EML
93 /**
94  * 
95  */
96 template<class TOutputImage>
97 void
98 ImageSource<TOutputImage>
99 ::GraftOutput(DataObject *graft)
100 {
101   this->GraftNthOutput(0, graft);
102 }
103
104
105 /**
106  * 
107  */
108 template<class TOutputImage>
109 void
110 ImageSource<TOutputImage>
111 ::GraftNthOutput(unsigned int idx, DataObject *graft)
112 {
113   if ( idx >= this->GetNumberOfOutputs() )
114     {
115     itkExceptionMacro(<<"Requested to graft output " << idx << 
116 LEN         " but this filter only has " << this->GetNumberOfOutputs() << " Outputs.");
117     }  
118
119   if ( !graft )
120     {
121     itkExceptionMacro(<<"Requested to graft output that is a NULL pointer" );
122     }
123
124   DataObject * output = this->GetOutput(idx);
125
126   // Call GraftImage to copy meta-information, regions, and the pixel container
127   output->Graft( graft );
128 }
129
130 //----------------------------------------------------------------------------
131 template <class TOutputImage>
132 int 
133 ImageSource<TOutputImage>
134 ::SplitRequestedRegion(int i, int num, OutputImageRegionType& splitRegion)
135 {
136   // Get the output pointer
137   OutputImageType * outputPtr = this->GetOutput();
138   const typename TOutputImage::SizeType& requestedRegionSize 
139 IND ****= outputPtr->GetRequestedRegion().GetSize();
140
141   int splitAxis;
142   typename TOutputImage::IndexType splitIndex;
143   typename TOutputImage::SizeType splitSize;
144
145   // Initialize the splitRegion to the output requested region
146   splitRegion = outputPtr->GetRequestedRegion();
147   splitIndex = splitRegion.GetIndex();
148   splitSize = splitRegion.GetSize();
149
150   // split on the outermost dimension available
151   splitAxis = outputPtr->GetImageDimension() - 1;
152   while (requestedRegionSize[splitAxis] == 1)
153     {
154     --splitAxis;
155     if (splitAxis < 0)
156       { // cannot split
157       itkDebugMacro("  Cannot Split");
158       return 1;
159       }
160     }
161
162   // determine the actual number of pieces that will be generated
163 LEN   typename TOutputImage::SizeType::SizeValueType range = requestedRegionSize[splitAxis];
164   int valuesPerThread = (int)::ceil(range/(double)num);
165   int maxThreadIdUsed = (int)::ceil(range/(double)valuesPerThread) - 1;
166
167   // Split the region
168   if (i < maxThreadIdUsed)
169     {
170     splitIndex[splitAxis] += i*valuesPerThread;
171     splitSize[splitAxis] = valuesPerThread;
172     }
173   if (i == maxThreadIdUsed)
174     {
175     splitIndex[splitAxis] += i*valuesPerThread;
176     // last thread needs to process the "rest" dimension being split
177     splitSize[splitAxis] = splitSize[splitAxis] - i*valuesPerThread;
178     }
179   
180   // set the split region ivars
181   splitRegion.SetIndex( splitIndex );
182   splitRegion.SetSize( splitSize );
183
184   itkDebugMacro("  Split Piece: " << splitRegion );
185
186   return maxThreadIdUsed + 1;
187 }
188
189 //----------------------------------------------------------------------------
190 template <class TOutputImage>
191 void 
192 ImageSource<TOutputImage>
193 ::AllocateOutputs()
194 {
195   OutputImagePointer outputPtr;
196
197   // Allocate the output memory
198   for (unsigned int i=0; i < this->GetNumberOfOutputs(); i++)
199     {
200     outputPtr = this->GetOutput(i);
201     outputPtr->SetBufferedRegion(outputPtr->GetRequestedRegion());
202     outputPtr->Allocate();
203     }
204 }
205
206 //----------------------------------------------------------------------------
207 template <class TOutputImage>
208 void 
209 ImageSource<TOutputImage>
210 ::GenerateData()
211 {
212   // Call a method that can be overriden by a subclass to allocate
213   // memory for the filter's outputs
214   this->AllocateOutputs();
215   
216   // Call a method that can be overridden by a subclass to perform
217   // some calculations prior to splitting the main computations into
218   // separate threads
219   this->BeforeThreadedGenerateData();
220   
221   // Set up the multithreaded processing
222   ThreadStruct str;
223   str.Filter = this;
224   
225   this->GetMultiThreader()->SetNumberOfThreads(this->GetNumberOfThreads());
226   this->GetMultiThreader()->SetSingleMethod(this->ThreaderCallback, &str);
227   
228   // multithread the execution
229   this->GetMultiThreader()->SingleMethodExecute();
230
231   // Call a method that can be overridden by a subclass to perform
232   // some calculations after all the threads have completed
233   this->AfterThreadedGenerateData();
234
235 }
236
237
238 //----------------------------------------------------------------------------
239 // The execute method created by the subclass.
240 template <class TOutputImage>
241 void 
242 ImageSource<TOutputImage>
243 ::ThreadedGenerateData(const OutputImageRegionType&,
244                        int)
245 {
246   itkExceptionMacro("subclass should override this method!!!");
247 }
248
249 // Callback routine used by the threading library. This routine just calls
250 // the ThreadedGenerateData method after setting the correct region for this
251 // thread. 
252 template <class TOutputImage>
253 ITK_THREAD_RETURN_TYPE 
254 ImageSource<TOutputImage>
255 ::ThreaderCallback( void *arg )
256 {
257   ThreadStruct *str;
258   int total, threadId, threadCount;
259
260   threadId = ((MultiThreader::ThreadInfoStruct *)(arg))->ThreadID;
261   threadCount = ((MultiThreader::ThreadInfoStruct *)(arg))->NumberOfThreads;
262
263   str = (ThreadStruct *)(((MultiThreader::ThreadInfoStruct *)(arg))->UserData);
264
265   // execute the actual method with appropriate output region
266   // first find out how many pieces extent can be split into.
267   typename TOutputImage::RegionType splitRegion;
268   total = str->Filter->SplitRequestedRegion(threadId, threadCount,
269                                             splitRegion);
270
271   if (threadId < total)
272     {
273     str->Filter->ThreadedGenerateData(splitRegion, threadId);
274     }
275   // else
276   //   {
277 IND **//   otherwise don't use this thread. Sometimes the threads dont
278 IND **//   break up very well and it is just as efficient to leave a 
279 IND **//   few threads idle.
280 IND **//   }
281   
282   return ITK_THREAD_RETURN_VALUE;
283 }
284
285
286 // end namespace itk
287
288 #endif
289

Generated by KWStyle 1.0b on Tuesday January,17 at 02:14:17PM
© Kitware Inc.