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 /*========================================================================= 19 * 20 * Portions of this file are subject to the VTK Toolkit Version 3 copyright. 21 * 22 * Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 23 * 24 * For complete copyright, license and disclaimer of warranty information 25 * please refer to the NOTICE file at the top of the ITK source tree. 26 * 27 *=========================================================================*/ 28 #ifndef itkInPlaceImageFilter_h 29 #define itkInPlaceImageFilter_h 30 31 #include "itkImageToImageFilter.h" 32 #include "itkIsSame.h" 33 34 namespace itk 35 { 36 /** \class InPlaceImageFilter 37 * \brief Base class for filters that take an image as input and overwrite that image as the output 38 * 39 * InPlaceImageFilter is the base class for all process objects whose 40 * output image data is constructed by overwriting the input image 41 * data. In other words, the output bulk data is the same block of 42 * memory as the input bulk data. This filter provides the mechanisms 43 * for in place image processing while maintaining general pipeline 44 * mechanics. InPlaceImageFilters use less memory than standard 45 * ImageToImageFilters because the input buffer is reused as the 46 * output buffer. However, this benefit does not come without a cost. 47 * Since the filter overwrites its input, the ownership of the bulk 48 * data is transitioned from the input data object to the output data 49 * object. When a data object has multiple consumers with one 50 * of the consumers being an in place filter, the in place filter 51 * effectively destroys the bulk data for the data object. Upstream 52 * filters will then have to re-execute to regenerate the data object's 53 * bulk data for the remaining consumers. 54 * 55 * Since an InPlaceImageFilter reuses the input bulk data memory for the 56 * output bulk data memory, the input image type must match the output 57 * image type. If the input and output image types are not identical, 58 * the filter reverts to a traditional ImageToImageFilter behaviour 59 * where an output image is allocated. Additionally, the requested 60 * region of the output must match that of the input. In place 61 * operation can also be controlled (when the input and output image 62 * type match) via the methods InPlaceOn() and InPlaceOff(). 63 * 64 * Subclasses of InPlaceImageFilter must take extra care in how they 65 * manage memory using (and perhaps overriding) the implementations of 66 * ReleaseInputs() and AllocateOutputs() provided here. 67 * 68 * \ingroup ImageFilters 69 * \ingroup ITKCommon 70 */ 71 template< typename TInputImage, typename TOutputImage = TInputImage > 72 class ITK_TEMPLATE_EXPORT InPlaceImageFilter:public ImageToImageFilter< TInputImage, TOutputImage > 73 { 74 public: 75 ITK_DISALLOW_COPY_AND_ASSIGN(InPlaceImageFilter); 76 77 /** Standard class type aliases. */ 78 using Self = InPlaceImageFilter; 79 using Superclass = ImageToImageFilter< TInputImage, TOutputImage >; 80 using Pointer = SmartPointer< Self >; 81 using ConstPointer = SmartPointer< const Self >; 82 83 /** Run-time type information (and related methods). */ 84 itkTypeMacro(InPlaceImageFilter, ImageToImageFilter); 85 86 /** Superclass type alias. */ 87 using OutputImageType = typename Superclass::OutputImageType; 88 using OutputImagePointer = typename Superclass::OutputImagePointer; 89 using OutputImageRegionType = typename Superclass::OutputImageRegionType; 90 using OutputImagePixelType = typename Superclass::OutputImagePixelType; 91 92 /** Some convenient type alias. */ 93 using InputImageType = TInputImage; 94 using InputImagePointer = typename InputImageType::Pointer; 95 using InputImageConstPointer = typename InputImageType::ConstPointer; 96 using InputImageRegionType = typename InputImageType::RegionType; 97 using InputImagePixelType = typename InputImageType::PixelType; 98 99 /** ImageDimension constants */ 100 static constexpr unsigned int InputImageDimension = TInputImage::ImageDimension; 101 static constexpr unsigned int OutputImageDimension = TOutputImage::ImageDimension; 102 103 /** In place operation can be turned on and off. Asking for 104 * in-place operation, i.e. calling SetInplace(true) or InplaceOn(), 105 * will be effective only if CanRunInPlace also returns true. 106 * By default CanRunInPlace checks whether the input and output 107 * image type match. */ 108 itkSetMacro(InPlace, bool); 109 itkGetConstMacro(InPlace, bool); 110 itkBooleanMacro(InPlace); 111 112 /** Can the filter run in place? To do so, the filter's first input 113 * and output must have the same dimension and pixel type. This 114 * method can be used in conjunction with the InPlace ivar to 115 * determine whether a particular use of the filter is really 116 * running in place. Some filters may be able to optimize their 117 * operation if the InPlace is true and CanRunInPlace is true. 118 * CanRunInPlace may also be overridded by InPlaceImageFilter 119 * subclasses to fine tune its behavior. */ 120 virtual bool CanRunInPlace() const; 121 122 protected: 123 InPlaceImageFilter() = default; 124 ~InPlaceImageFilter() override = default; 125 126 void PrintSelf(std::ostream & os, Indent indent) const override; 127 128 /** The GenerateData method normally allocates the buffers for all 129 * of the outputs of a filter. Since InPlaceImageFilter's can use an 130 * overwritten version of the input for its output, the output 131 * buffer should not be allocated. When possible, we graft the input 132 * to the filter to the output. If an InPlaceFilter has multiple 133 * outputs, then it would need to override this method to graft one 134 * of its outputs and allocate the remaining. If a filter is 135 * threaded (i.e. it provides an implementation of 136 * ThreadedGenerateData()), this method is called automatically. If 137 * an InPlaceFilter is not threaded (i.e. it provides an 138 * implementation of GenerateData()), then this method (or 139 * equivalent) must be called in GenerateData(). */ AllocateOutputs()140 void AllocateOutputs() override 141 { 142 this->InternalAllocateOutputs(IsSame<TInputImage, TOutputImage>()); 143 } 144 145 /** InPlaceImageFilter may transfer ownership of the input bulk data 146 * to the output object. Once the output object owns the bulk data 147 * (done in AllocateOutputs()), the input object must release its 148 * hold on the bulk data. ProcessObject::ReleaseInputs() only 149 * releases the input bulk data when the user has set the 150 * ReleaseDataFlag. InPlaceImageFilter::ReleaseInputs() also 151 * releases the input that it has overwritten. 152 * 153 * \sa ProcessObject::ReleaseInputs() */ 154 void ReleaseInputs() override; 155 156 /** This methods should only be called during the GenerateData phase 157 * of the pipeline. This method return true if the input image's 158 * bulk data is the same as the output image's data. 159 */ 160 itkGetConstMacro(RunningInPlace,bool); 161 162 private: 163 // the type are different we can't run in place InternalAllocateOutputs(const FalseType &)164 void InternalAllocateOutputs( const FalseType& ) 165 { 166 this->m_RunningInPlace = false; 167 this->Superclass::AllocateOutputs(); 168 } 169 170 void InternalAllocateOutputs( const TrueType& ); 171 172 bool m_InPlace{true}; // enable the possibility of in-place 173 bool m_RunningInPlace{false}; 174 175 }; 176 } // end namespace itk 177 178 #ifndef ITK_MANUAL_INSTANTIATION 179 #include "itkInPlaceImageFilter.hxx" 180 #endif 181 182 #endif 183