1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the copyright notices for more information.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ======================================================================-====*/
18 #include "vvImageMapToWLColors.h"
19 #include "clitkCommon.h"
20 #include "vtkDataArray.h"
21 #include "vtkImageData.h"
22 #include "vtkInformation.h"
23 #include "vtkInformationVector.h"
24 #include "vtkObjectFactory.h"
25 #include "vtkScalarsToColors.h"
26 #include "vtkPointData.h"
27 #include <vtkObjectFactory.h>
29 vtkStandardNewMacro(vvImageMapToWLColors);
31 vvImageMapToWLColors::vvImageMapToWLColors() :
36 void vtkImageMapToWindowLevelClamps ( vtkImageData *data, double w,
37 double l, T& lower, T& upper,
38 unsigned char &lower_val,
39 unsigned char &upper_val)
41 double f_lower, f_upper, f_lower_val, f_upper_val;
42 double adjustedLower, adjustedUpper;
45 data->GetPointData()->GetScalars()->GetDataTypeRange( range );
47 f_lower = l - fabs(w) / 2.0;
48 f_upper = f_lower + fabs(w);
50 // Set the correct lower value
51 if ( f_lower <= range[1]) {
52 if (f_lower >= range[0]) {
53 lower = static_cast<T>(f_lower);
54 adjustedLower = f_lower;
56 lower = static_cast<T>(range[0]);
57 adjustedLower = range[0];
60 lower = static_cast<T>(range[1]);
61 adjustedLower = range[1];
64 // Set the correct upper value
65 if ( f_upper >= range[0]) {
66 if (f_upper <= range[1]) {
67 upper = static_cast<T>(f_upper);
68 adjustedUpper = f_upper;
70 upper = static_cast<T>(range[1]);
71 adjustedUpper = range[1];
74 upper = static_cast<T>(range[0]);
75 adjustedUpper = range [0];
78 // now compute the lower and upper values
80 f_lower_val = 255.0*(adjustedLower - f_lower)/w;
81 f_upper_val = 255.0*(adjustedUpper - f_lower)/w;
83 f_lower_val = 255.0 + 255.0*(adjustedLower - f_lower)/w;
84 f_upper_val = 255.0 + 255.0*(adjustedUpper - f_lower)/w;
87 if (f_upper_val > 255) {
89 } else if (f_upper_val < 0) {
92 upper_val = static_cast<unsigned char>(f_upper_val);
95 if (f_lower_val > 255) {
97 } else if (f_lower_val < 0) {
100 lower_val = static_cast<unsigned char>(f_lower_val);
105 void vvImageMapToWindowLevelColorsExecute(
106 vtkImageMapToWindowLevelColors *self,
107 vtkImageData *inData, T *inPtr,
108 vtkImageData *outData,
109 unsigned char *outPtr,
110 int outExt[6], int id, bool wl_mode)
112 int idxX, idxY, idxZ;
113 int extX, extY, extZ;
114 vtkIdType inIncX, inIncY, inIncZ;
115 vtkIdType outIncX, outIncY, outIncZ;
116 unsigned long count = 0;
117 unsigned long target;
118 int dataType = inData->GetScalarType();
119 int numberOfComponents,numberOfOutputComponents,outputFormat;
121 vtkScalarsToColors *lookupTable = self->GetLookupTable();
122 unsigned char *outPtr1;
126 double shift = self->GetWindow() / 2.0 - self->GetLevel();
127 double scale = 255.0 / self->GetWindow();
130 unsigned char lower_val, upper_val, result_val;
131 vtkImageMapToWindowLevelClamps( inData, self->GetWindow(),
133 lower, upper, lower_val, upper_val );
135 // find the region to loop over
136 extX = outExt[1] - outExt[0] + 1;
137 extY = outExt[3] - outExt[2] + 1;
138 extZ = outExt[5] - outExt[4] + 1;
140 target = static_cast<unsigned long>(extZ*extY/50.0);
143 // Get increments to march through data
144 inData->GetContinuousIncrements(outExt, inIncX, inIncY, inIncZ);
146 outData->GetContinuousIncrements(outExt, outIncX, outIncY, outIncZ);
147 numberOfComponents = inData->GetNumberOfScalarComponents();
148 numberOfOutputComponents = outData->GetNumberOfScalarComponents();
149 outputFormat = self->GetOutputFormat();
151 rowLength = extX*numberOfComponents;
153 // Loop through output pixels
156 for (idxZ = 0; idxZ < extZ; idxZ++) {
157 for (idxY = 0; !self->AbortExecute && idxY < extY; idxY++) {
159 if (!(count%target)) {
160 self->UpdateProgress(count/(50.0*target));
169 lookupTable->MapScalarsThroughTable2(
171 static_cast<unsigned char *>(outPtr1),
172 dataType,extX,numberOfComponents,
175 unsigned short ushort_val;
176 for (idxX = 0; idxX < extX; idxX++) {
177 if (*iptr <= lower) {
178 ushort_val = lower_val;
179 } else if (*iptr >= upper) {
180 ushort_val = upper_val;
182 ushort_val = static_cast<unsigned char>((*iptr + shift)*scale);
184 *optr = static_cast<unsigned char>((*optr * ushort_val) >> 8);
185 switch (outputFormat) {
187 *(optr+1) = static_cast<unsigned char>(
188 (*(optr+1) * ushort_val) >> 8);
189 *(optr+2) = static_cast<unsigned char>(
190 (*(optr+2) * ushort_val) >> 8);
194 *(optr+1) = static_cast<unsigned char>(
195 (*(optr+1) * ushort_val) >> 8);
196 *(optr+2) = static_cast<unsigned char>(
197 (*(optr+2) * ushort_val) >> 8);
199 case VTK_LUMINANCE_ALPHA:
203 iptr += numberOfComponents;
204 optr += numberOfOutputComponents;
208 for (idxX = 0; idxX < extX; idxX++) {
209 if (*iptr <= lower) {
210 result_val = lower_val;
211 } else if (*iptr >= upper) {
212 result_val = upper_val;
214 result_val = static_cast<unsigned char>((*iptr + shift)*scale);
217 switch (outputFormat) {
219 *(optr+1) = result_val;
220 *(optr+2) = result_val;
224 *(optr+1) = result_val;
225 *(optr+2) = result_val;
227 case VTK_LUMINANCE_ALPHA:
231 iptr += numberOfComponents;
232 optr += numberOfOutputComponents;
235 outPtr1 += outIncY + extX*numberOfOutputComponents;
236 inPtr1 += inIncY + rowLength;
244 void vvImageMapToWLColors::ThreadedRequestData(
245 vtkInformation *vtkNotUsed(request),
246 vtkInformationVector **vtkNotUsed(inputVector),
247 vtkInformationVector *vtkNotUsed(outputVector),
248 vtkImageData ***inData,
249 vtkImageData **outData,
250 int outExt[6], int id)
252 void *inPtr = inData[0][0]->GetScalarPointerForExtent(outExt);
253 void *outPtr = outData[0]->GetScalarPointerForExtent(outExt);
255 switch (inData[0][0]->GetScalarType()) {
257 vvImageMapToWindowLevelColorsExecute(this,
259 static_cast<VTK_TT *>(inPtr),
261 static_cast<unsigned char *>(outPtr),
265 vtkErrorMacro(<< "Execute: Unknown ScalarType");