1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkImageCast.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #include "vtkImageCast.h"
16 
17 #include "vtkImageData.h"
18 #include "vtkImageProgressIterator.h"
19 #include "vtkInformation.h"
20 #include "vtkInformationVector.h"
21 #include "vtkObjectFactory.h"
22 #include "vtkStreamingDemandDrivenPipeline.h"
23 
24 vtkStandardNewMacro(vtkImageCast);
25 
26 //----------------------------------------------------------------------------
vtkImageCast()27 vtkImageCast::vtkImageCast()
28 {
29   this->SetNumberOfInputPorts(1);
30   this->SetNumberOfOutputPorts(1);
31   this->OutputScalarType = VTK_FLOAT;
32   this->ClampOverflow = 0;
33 }
34 
35 
36 //----------------------------------------------------------------------------
37 // Just change the Image type.
RequestInformation(vtkInformation * vtkNotUsed (request),vtkInformationVector ** vtkNotUsed (inputVector),vtkInformationVector * outputVector)38 int vtkImageCast::RequestInformation (
39   vtkInformation       * vtkNotUsed( request ),
40   vtkInformationVector** vtkNotUsed( inputVector ),
41   vtkInformationVector * outputVector)
42 {
43   // get the info objects
44   vtkInformation* outInfo = outputVector->GetInformationObject(0);
45   vtkDataObject::SetPointDataActiveScalarInfo(outInfo, this->OutputScalarType, -1);
46   return 1;
47 }
48 
49 //----------------------------------------------------------------------------
50 // This templated function executes the filter for any type of data.
51 template <class IT, class OT>
vtkImageCastExecute(vtkImageCast * self,vtkImageData * inData,vtkImageData * outData,int outExt[6],int id,IT *,OT *)52 void vtkImageCastExecute(vtkImageCast *self,
53                          vtkImageData *inData,
54                          vtkImageData *outData,
55                          int outExt[6], int id, IT *, OT *)
56 {
57   vtkImageIterator<IT> inIt(inData, outExt);
58   vtkImageProgressIterator<OT> outIt(outData, outExt, self, id);
59 
60   double typeMin, typeMax, val;
61   int clamp;
62 
63   // for preventing overflow
64   typeMin = outData->GetScalarTypeMin();
65   typeMax = outData->GetScalarTypeMax();
66   clamp = self->GetClampOverflow();
67 
68   // Loop through output pixels
69   while (!outIt.IsAtEnd())
70   {
71     IT* inSI = inIt.BeginSpan();
72     OT* outSI = outIt.BeginSpan();
73     OT* outSIEnd = outIt.EndSpan();
74     if (clamp)
75     {
76       while (outSI != outSIEnd)
77       {
78         // Pixel operation
79         val = static_cast<double>(*inSI);
80         if (val > typeMax)
81         {
82           val = typeMax;
83         }
84         if (val < typeMin)
85         {
86           val = typeMin;
87         }
88         *outSI = static_cast<OT>(val);
89         ++outSI;
90         ++inSI;
91       }
92     }
93     else
94     {
95       while (outSI != outSIEnd)
96       {
97         // now process the components
98         // NB: without clamping, this cast may result in undefined behavior!
99         *outSI = static_cast<OT>(*inSI);
100         ++outSI;
101         ++inSI;
102       }
103     }
104     inIt.NextSpan();
105     outIt.NextSpan();
106   }
107 }
108 
109 
110 
111 //----------------------------------------------------------------------------
112 template <class T>
vtkImageCastExecute(vtkImageCast * self,vtkImageData * inData,vtkImageData * outData,int outExt[6],int id,T *)113 void vtkImageCastExecute(vtkImageCast *self,
114                          vtkImageData *inData,
115                          vtkImageData *outData, int outExt[6], int id,
116                          T *)
117 {
118   switch (outData->GetScalarType())
119   {
120     vtkTemplateMacro(vtkImageCastExecute(self,
121                                          inData, outData, outExt, id,
122                                          static_cast<T *>(nullptr),
123                                          static_cast<VTK_TT *>(nullptr)));
124     default:
125       vtkGenericWarningMacro("Execute: Unknown output ScalarType");
126       return;
127   }
128 }
129 
130 
131 
132 
133 //----------------------------------------------------------------------------
134 // This method is passed a input and output region, and executes the filter
135 // algorithm to fill the output from the input.
136 // It just executes a switch statement to call the correct function for
137 // the regions data types.
ThreadedExecute(vtkImageData * inData,vtkImageData * outData,int outExt[6],int id)138 void vtkImageCast::ThreadedExecute (vtkImageData *inData,
139                                    vtkImageData *outData,
140                                    int outExt[6], int id)
141 {
142   switch (inData->GetScalarType())
143   {
144     vtkTemplateMacro(
145       vtkImageCastExecute(this, inData,
146                           outData, outExt, id,
147                           static_cast<VTK_TT *>(nullptr)));
148     default:
149       vtkErrorMacro(<< "Execute: Unknown input ScalarType");
150       return;
151   }
152 }
153 
154 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)155 void vtkImageCast::PrintSelf(ostream& os, vtkIndent indent)
156 {
157   this->Superclass::PrintSelf(os,indent);
158 
159   os << indent << "OutputScalarType: " << this->OutputScalarType << "\n";
160   os << indent << "ClampOverflow: ";
161   if (this->ClampOverflow)
162   {
163     os << "On\n";
164   }
165   else
166   {
167     os << "Off\n";
168   }
169 }
170 
171