1 /*=========================================================================
5 Author : Joel Schaerer (joel.schaerer@insa-lyon.fr)
8 Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
9 CREATIS-LRMN http://www.creatis.insa-lyon.fr
11 This program is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, version 3 of the License.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 =========================================================================*/
25 #include "vvImageMapToWLColors.h"
26 #include "clitkCommon.h"
27 #include "vtkDataArray.h"
28 #include "vtkImageData.h"
29 #include "vtkInformation.h"
30 #include "vtkInformationVector.h"
31 #include "vtkObjectFactory.h"
32 #include "vtkScalarsToColors.h"
33 #include "vtkPointData.h"
34 #include <vtkObjectFactory.h>
36 vtkStandardNewMacro(vvImageMapToWLColors);
38 vvImageMapToWLColors::vvImageMapToWLColors() :
43 void vtkImageMapToWindowLevelClamps ( vtkImageData *data, double w,
44 double l, T& lower, T& upper,
45 unsigned char &lower_val,
46 unsigned char &upper_val)
48 double f_lower, f_upper, f_lower_val, f_upper_val;
49 double adjustedLower, adjustedUpper;
52 data->GetPointData()->GetScalars()->GetDataTypeRange( range );
54 f_lower = l - fabs(w) / 2.0;
55 f_upper = f_lower + fabs(w);
57 // Set the correct lower value
58 if ( f_lower <= range[1])
60 if (f_lower >= range[0])
62 lower = static_cast<T>(f_lower);
63 adjustedLower = f_lower;
67 lower = static_cast<T>(range[0]);
68 adjustedLower = range[0];
73 lower = static_cast<T>(range[1]);
74 adjustedLower = range[1];
77 // Set the correct upper value
78 if ( f_upper >= range[0])
80 if (f_upper <= range[1])
82 upper = static_cast<T>(f_upper);
83 adjustedUpper = f_upper;
87 upper = static_cast<T>(range[1]);
88 adjustedUpper = range[1];
93 upper = static_cast<T>(range[0]);
94 adjustedUpper = range [0];
97 // now compute the lower and upper values
100 f_lower_val = 255.0*(adjustedLower - f_lower)/w;
101 f_upper_val = 255.0*(adjustedUpper - f_lower)/w;
105 f_lower_val = 255.0 + 255.0*(adjustedLower - f_lower)/w;
106 f_upper_val = 255.0 + 255.0*(adjustedUpper - f_lower)/w;
109 if (f_upper_val > 255)
113 else if (f_upper_val < 0)
119 upper_val = static_cast<unsigned char>(f_upper_val);
122 if (f_lower_val > 255)
126 else if (f_lower_val < 0)
132 lower_val = static_cast<unsigned char>(f_lower_val);
137 void vvImageMapToWindowLevelColorsExecute(
138 vtkImageMapToWindowLevelColors *self,
139 vtkImageData *inData, T *inPtr,
140 vtkImageData *outData,
141 unsigned char *outPtr,
142 int outExt[6], int id, bool wl_mode)
144 int idxX, idxY, idxZ;
145 int extX, extY, extZ;
146 vtkIdType inIncX, inIncY, inIncZ;
147 vtkIdType outIncX, outIncY, outIncZ;
148 unsigned long count = 0;
149 unsigned long target;
150 int dataType = inData->GetScalarType();
151 int numberOfComponents,numberOfOutputComponents,outputFormat;
153 vtkScalarsToColors *lookupTable = self->GetLookupTable();
154 unsigned char *outPtr1;
158 double shift = self->GetWindow() / 2.0 - self->GetLevel();
159 double scale = 255.0 / self->GetWindow();
162 unsigned char lower_val, upper_val, result_val;
163 vtkImageMapToWindowLevelClamps( inData, self->GetWindow(),
165 lower, upper, lower_val, upper_val );
167 // find the region to loop over
168 extX = outExt[1] - outExt[0] + 1;
169 extY = outExt[3] - outExt[2] + 1;
170 extZ = outExt[5] - outExt[4] + 1;
172 target = static_cast<unsigned long>(extZ*extY/50.0);
175 // Get increments to march through data
176 inData->GetContinuousIncrements(outExt, inIncX, inIncY, inIncZ);
178 outData->GetContinuousIncrements(outExt, outIncX, outIncY, outIncZ);
179 numberOfComponents = inData->GetNumberOfScalarComponents();
180 numberOfOutputComponents = outData->GetNumberOfScalarComponents();
181 outputFormat = self->GetOutputFormat();
183 rowLength = extX*numberOfComponents;
185 // Loop through output pixels
188 for (idxZ = 0; idxZ < extZ; idxZ++)
190 for (idxY = 0; !self->AbortExecute && idxY < extY; idxY++)
196 self->UpdateProgress(count/(50.0*target));
206 lookupTable->MapScalarsThroughTable2(
208 static_cast<unsigned char *>(outPtr1),
209 dataType,extX,numberOfComponents,
213 unsigned short ushort_val;
214 for (idxX = 0; idxX < extX; idxX++)
218 ushort_val = lower_val;
220 else if (*iptr >= upper)
222 ushort_val = upper_val;
226 ushort_val = static_cast<unsigned char>((*iptr + shift)*scale);
228 *optr = static_cast<unsigned char>((*optr * ushort_val) >> 8);
229 switch (outputFormat)
232 *(optr+1) = static_cast<unsigned char>(
233 (*(optr+1) * ushort_val) >> 8);
234 *(optr+2) = static_cast<unsigned char>(
235 (*(optr+2) * ushort_val) >> 8);
239 *(optr+1) = static_cast<unsigned char>(
240 (*(optr+1) * ushort_val) >> 8);
241 *(optr+2) = static_cast<unsigned char>(
242 (*(optr+2) * ushort_val) >> 8);
244 case VTK_LUMINANCE_ALPHA:
248 iptr += numberOfComponents;
249 optr += numberOfOutputComponents;
255 for (idxX = 0; idxX < extX; idxX++)
259 result_val = lower_val;
261 else if (*iptr >= upper)
263 result_val = upper_val;
267 result_val = static_cast<unsigned char>((*iptr + shift)*scale);
270 switch (outputFormat)
273 *(optr+1) = result_val;
274 *(optr+2) = result_val;
278 *(optr+1) = result_val;
279 *(optr+2) = result_val;
281 case VTK_LUMINANCE_ALPHA:
285 iptr += numberOfComponents;
286 optr += numberOfOutputComponents;
289 outPtr1 += outIncY + extX*numberOfOutputComponents;
290 inPtr1 += inIncY + rowLength;
298 void vvImageMapToWLColors::ThreadedRequestData(
299 vtkInformation *vtkNotUsed(request),
300 vtkInformationVector **vtkNotUsed(inputVector),
301 vtkInformationVector *vtkNotUsed(outputVector),
302 vtkImageData ***inData,
303 vtkImageData **outData,
304 int outExt[6], int id)
306 void *inPtr = inData[0][0]->GetScalarPointerForExtent(outExt);
307 void *outPtr = outData[0]->GetScalarPointerForExtent(outExt);
309 switch (inData[0][0]->GetScalarType())
312 vvImageMapToWindowLevelColorsExecute(this,
314 static_cast<VTK_TT *>(inPtr),
316 static_cast<unsigned char *>(outPtr),
320 vtkErrorMacro(<< "Execute: Unknown ScalarType");