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 itkStreamingImageFilter_h
19 #define itkStreamingImageFilter_h
20 
21 #include "itkImageToImageFilter.h"
22 #include "itkImageRegionSplitterBase.h"
23 
24 namespace itk
25 {
26 /** \class StreamingImageFilter
27  * \brief Pipeline object to control data streaming for large data processing.
28  *
29  * StreamingImageFilter is a pipeline object that allows the user to control
30  * how data is pulled through the pipeline.  To generate its
31  * OutputRequestedRegion, this filter will divide the output into several
32  * pieces (controlled by SetNumberOfStreamDivisions), and call the upstream
33  * pipeline for each piece, tiling the individual outputs into one large
34  * output. This reduces the memory footprint for the application since
35  * each filter does not have to process the entire dataset at once.
36  * This filter will produce the entire output as one image, but the upstream
37  * filters will do their processing in pieces.
38  *
39  * \ingroup ITKSystemObjects
40  * \ingroup DataProcessing
41  * \ingroup ITKCommon
42  */
43 template< typename TInputImage, typename TOutputImage >
44 class ITK_TEMPLATE_EXPORT StreamingImageFilter:public ImageToImageFilter< TInputImage, TOutputImage >
45 {
46 public:
47   ITK_DISALLOW_COPY_AND_ASSIGN(StreamingImageFilter);
48 
49   /** Standard class type aliases. */
50   using Self = StreamingImageFilter;
51   using Superclass = ImageToImageFilter< TInputImage, TOutputImage >;
52   using Pointer = SmartPointer< Self >;
53   using ConstPointer = SmartPointer< const Self >;
54 
55   /** Method for creation through the object factory. */
56   itkNewMacro(Self);
57 
58   /** Run-time type information (and related methods). */
59   itkTypeMacro(StreamingImageFilter, ImageToImageFilter);
60 
61   /** Some type alias for the input and output. */
62   using InputImageType = TInputImage;
63   using InputImagePointer = typename InputImageType::Pointer;
64   using InputImageRegionType = typename InputImageType::RegionType;
65   using InputImagePixelType = typename InputImageType::PixelType;
66 
67   using OutputImageType = TOutputImage;
68   using OutputImagePointer = typename OutputImageType::Pointer;
69   using OutputImageRegionType = typename OutputImageType::RegionType;
70   using OutputImagePixelType = typename OutputImageType::PixelType;
71   using DataObjectPointer = typename Superclass::DataObjectPointer;
72 
73   /** Dimension of input image. */
74   static constexpr unsigned int InputImageDimension = InputImageType::ImageDimension;
75   static constexpr unsigned int OutputImageDimension = OutputImageType::ImageDimension;
76 
77   /** SmartPointer to a region splitting object */
78   using SplitterType = ImageRegionSplitterBase;
79   using RegionSplitterPointer = typename SplitterType::Pointer;
80 
81   /** Set the number of pieces to divide the input.  The upstream pipeline
82    * will be executed this many times. */
83   itkSetMacro(NumberOfStreamDivisions, unsigned int);
84 
85   /** Get the number of pieces to divide the input. The upstream pipeline
86    * will be executed this many times. */
87   itkGetConstReferenceMacro(NumberOfStreamDivisions, unsigned int);
88 
89   /** Get/Set the helper class for dividing the input into chunks. */
90   itkSetObjectMacro(RegionSplitter, SplitterType);
91   itkGetModifiableObjectMacro(RegionSplitter, SplitterType);
92 
93   /** Override UpdateOutputData() from ProcessObject to divide upstream
94    * updates into pieces. This filter does not have a GenerateData()
95    * or ThreadedGenerateData() method.  Instead, all the work is done
96    * in UpdateOutputData() since it must update a little, execute a little,
97    * update some more, execute some more, etc. */
98   void UpdateOutputData(DataObject *output) override;
99 
100   /** Override PropagateRequestedRegion from ProcessObject
101    *  Since inside UpdateOutputData we iterate over streaming pieces
102    *  we don't need to proapage up the pipeline
103    */
104   void PropagateRequestedRegion(DataObject *output) override;
105 
106 #ifdef ITK_USE_CONCEPT_CHECKING
107   // Begin concept checking
108   itkConceptMacro( SameDimensionCheck,
109                    ( Concept::SameDimension< InputImageDimension, OutputImageDimension > ) );
110   itkConceptMacro( InputConvertibleToOutputCheck,
111                    ( Concept::Convertible< InputImagePixelType, OutputImagePixelType > ) );
112   // End concept checking
113 #endif
114 
115 protected:
116   StreamingImageFilter();
117   ~StreamingImageFilter() override = default;
118   void PrintSelf(std::ostream & os, Indent indent) const override;
119 
120 private:
121   unsigned int          m_NumberOfStreamDivisions;
122   RegionSplitterPointer m_RegionSplitter;
123 };
124 } // end namespace itk
125 
126 #ifndef ITK_MANUAL_INSTANTIATION
127 #include "itkStreamingImageFilter.hxx"
128 #endif
129 
130 #endif
131