1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkImageNormalize.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 "vtkImageNormalize.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 #include <cmath>
25
26 vtkStandardNewMacro(vtkImageNormalize);
27
28 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)29 void vtkImageNormalize::PrintSelf(ostream& os, vtkIndent indent)
30 {
31 this->Superclass::PrintSelf(os, indent);
32 }
33
34 //------------------------------------------------------------------------------
vtkImageNormalize()35 vtkImageNormalize::vtkImageNormalize()
36 {
37 this->SetNumberOfInputPorts(1);
38 this->SetNumberOfOutputPorts(1);
39 }
40
41 //------------------------------------------------------------------------------
RequestInformation(vtkInformation * vtkNotUsed (request),vtkInformationVector ** vtkNotUsed (inputVector),vtkInformationVector * outputVector)42 int vtkImageNormalize::RequestInformation(vtkInformation* vtkNotUsed(request),
43 vtkInformationVector** vtkNotUsed(inputVector), vtkInformationVector* outputVector)
44 {
45 // get the info objects
46 vtkInformation* outInfo = outputVector->GetInformationObject(0);
47 vtkDataObject::SetPointDataActiveScalarInfo(outInfo, VTK_FLOAT, -1);
48 return 1;
49 }
50
51 //------------------------------------------------------------------------------
52 // This execute method handles boundaries.
53 // it handles boundaries. Pixels are just replicated to get values
54 // out of extent.
55 template <class T>
vtkImageNormalizeExecute(vtkImageNormalize * self,vtkImageData * inData,vtkImageData * outData,int outExt[6],int id,T *)56 void vtkImageNormalizeExecute(
57 vtkImageNormalize* self, vtkImageData* inData, vtkImageData* outData, int outExt[6], int id, T*)
58 {
59 vtkImageIterator<T> inIt(inData, outExt);
60 vtkImageProgressIterator<float> outIt(outData, outExt, self, id);
61 int idxC, maxC;
62 float sum;
63 T* inVect;
64
65 // find the region to loop over
66 maxC = inData->GetNumberOfScalarComponents();
67
68 // Loop through output pixels
69 while (!outIt.IsAtEnd())
70 {
71 T* inSI = inIt.BeginSpan();
72 float* outSI = outIt.BeginSpan();
73 float* outSIEnd = outIt.EndSpan();
74 while (outSI != outSIEnd)
75 {
76 // save the start of the vector
77 inVect = inSI;
78
79 // compute the magnitude.
80 sum = 0.0;
81 for (idxC = 0; idxC < maxC; idxC++)
82 {
83 sum += static_cast<float>(*inSI) * static_cast<float>(*inSI);
84 inSI++;
85 }
86 if (sum > 0.0)
87 {
88 sum = 1.0 / sqrt(sum);
89 }
90
91 // now divide to normalize.
92 for (idxC = 0; idxC < maxC; idxC++)
93 {
94 *outSI = static_cast<float>(*inVect) * sum;
95 inVect++;
96 outSI++;
97 }
98 }
99 inIt.NextSpan();
100 outIt.NextSpan();
101 }
102 }
103
104 //------------------------------------------------------------------------------
105 // This method contains a switch statement that calls the correct
106 // templated function for the input data type. The output data
107 // must match input type. This method does handle boundary conditions.
ThreadedExecute(vtkImageData * inData,vtkImageData * outData,int outExt[6],int id)108 void vtkImageNormalize::ThreadedExecute(
109 vtkImageData* inData, vtkImageData* outData, int outExt[6], int id)
110 {
111 vtkDebugMacro(<< "Execute: inData = " << inData << ", outData = " << outData);
112
113 // this filter expects that input is the same type as output.
114 if (outData->GetScalarType() != VTK_FLOAT)
115 {
116 vtkErrorMacro(<< "Execute: output ScalarType, " << outData->GetScalarType()
117 << ", must be float");
118 return;
119 }
120
121 switch (inData->GetScalarType())
122 {
123 vtkTemplateMacro(
124 vtkImageNormalizeExecute(this, inData, outData, outExt, id, static_cast<VTK_TT*>(nullptr)));
125 default:
126 vtkErrorMacro(<< "Execute: Unknown ScalarType");
127 return;
128 }
129 }
130