]> Creatis software - clitk.git/blob - vv/vvImageMapToWLColors.cxx
67683526b77d1fe6c32529f7a95549644b1dbeda
[clitk.git] / vv / vvImageMapToWLColors.cxx
1 #include "vvImageMapToWLColors.h"
2 #include "clitkCommon.h"
3 #include "vtkDataArray.h"
4 #include "vtkImageData.h"
5 #include "vtkInformation.h"
6 #include "vtkInformationVector.h"
7 #include "vtkObjectFactory.h"
8 #include "vtkScalarsToColors.h"
9 #include "vtkPointData.h"
10 #include <vtkObjectFactory.h>
11
12 vtkStandardNewMacro(vvImageMapToWLColors);
13
14 vvImageMapToWLColors::vvImageMapToWLColors() :
15     wl_mode(false)
16 {}
17
18 template <class T>
19 void vtkImageMapToWindowLevelClamps ( vtkImageData *data, double w, 
20                                       double l, T& lower, T& upper, 
21                                       unsigned char &lower_val, 
22                                       unsigned char &upper_val)
23 {
24   double f_lower, f_upper, f_lower_val, f_upper_val;
25   double adjustedLower, adjustedUpper;
26   double range[2];
27
28   data->GetPointData()->GetScalars()->GetDataTypeRange( range );
29
30   f_lower = l - fabs(w) / 2.0;
31   f_upper = f_lower + fabs(w);
32
33   // Set the correct lower value
34   if ( f_lower <= range[1])
35     {
36     if (f_lower >= range[0])
37       {
38       lower = static_cast<T>(f_lower);
39       adjustedLower = f_lower;
40       }
41     else
42       {
43       lower = static_cast<T>(range[0]);
44       adjustedLower = range[0];
45       }
46     }
47   else
48     {
49     lower = static_cast<T>(range[1]);
50     adjustedLower = range[1];
51     }
52   
53   // Set the correct upper value
54   if ( f_upper >= range[0])
55     {
56     if (f_upper <= range[1])
57       {
58       upper = static_cast<T>(f_upper);
59       adjustedUpper = f_upper;
60       }
61     else
62       {
63       upper = static_cast<T>(range[1]);
64       adjustedUpper = range[1];
65       }
66     }
67   else
68     {
69     upper = static_cast<T>(range[0]);
70     adjustedUpper = range [0];
71     }
72   
73   // now compute the lower and upper values
74   if (w >= 0)
75     {
76     f_lower_val = 255.0*(adjustedLower - f_lower)/w;
77     f_upper_val = 255.0*(adjustedUpper - f_lower)/w;
78     }
79   else
80     {
81     f_lower_val = 255.0 + 255.0*(adjustedLower - f_lower)/w;
82     f_upper_val = 255.0 + 255.0*(adjustedUpper - f_lower)/w;
83     }
84   
85   if (f_upper_val > 255) 
86     {
87     upper_val = 255;
88     }
89   else if (f_upper_val < 0)
90     {
91     upper_val = 0;
92     }
93   else
94     {
95     upper_val = static_cast<unsigned char>(f_upper_val);
96     }
97   
98   if (f_lower_val > 255) 
99     {
100     lower_val = 255;
101     }
102   else if (f_lower_val < 0)
103     {
104     lower_val = 0;
105     }
106   else
107     {
108     lower_val = static_cast<unsigned char>(f_lower_val);
109     }  
110 }
111
112 template <class T>
113 void vvImageMapToWindowLevelColorsExecute(
114   vtkImageMapToWindowLevelColors *self, 
115   vtkImageData *inData, T *inPtr,
116   vtkImageData *outData, 
117   unsigned char *outPtr,
118   int outExt[6], int id, bool wl_mode)
119 {
120     int idxX, idxY, idxZ;
121     int extX, extY, extZ;
122     vtkIdType inIncX, inIncY, inIncZ;
123     vtkIdType outIncX, outIncY, outIncZ;
124     unsigned long count = 0;
125     unsigned long target;
126     int dataType = inData->GetScalarType();
127     int numberOfComponents,numberOfOutputComponents,outputFormat;
128     int rowLength;
129     vtkScalarsToColors *lookupTable = self->GetLookupTable();
130     unsigned char *outPtr1;
131     T *inPtr1;
132     unsigned char *optr;
133     T    *iptr;
134     double shift =  self->GetWindow() / 2.0 - self->GetLevel();
135     double scale = 255.0 / self->GetWindow();
136
137     T   lower, upper;
138     unsigned char lower_val, upper_val, result_val;
139     vtkImageMapToWindowLevelClamps( inData, self->GetWindow(), 
140             self->GetLevel(), 
141             lower, upper, lower_val, upper_val );
142
143     // find the region to loop over
144     extX = outExt[1] - outExt[0] + 1;
145     extY = outExt[3] - outExt[2] + 1; 
146     extZ = outExt[5] - outExt[4] + 1;
147
148     target = static_cast<unsigned long>(extZ*extY/50.0);
149     target++;
150
151     // Get increments to march through data 
152     inData->GetContinuousIncrements(outExt, inIncX, inIncY, inIncZ);
153
154     outData->GetContinuousIncrements(outExt, outIncX, outIncY, outIncZ);
155     numberOfComponents = inData->GetNumberOfScalarComponents();
156     numberOfOutputComponents = outData->GetNumberOfScalarComponents();
157     outputFormat = self->GetOutputFormat();
158
159     rowLength = extX*numberOfComponents;
160
161     // Loop through output pixels
162     outPtr1 = outPtr;
163     inPtr1 = inPtr;
164     for (idxZ = 0; idxZ < extZ; idxZ++)
165     {
166         for (idxY = 0; !self->AbortExecute && idxY < extY; idxY++)
167         {
168             if (!id) 
169             {
170                 if (!(count%target))
171                 {
172                     self->UpdateProgress(count/(50.0*target));
173                 }
174                 count++;
175             }
176
177             iptr = inPtr1;
178             optr = outPtr1;
179
180             if ( lookupTable )
181             {
182                 lookupTable->MapScalarsThroughTable2(
183                         inPtr1,
184                         static_cast<unsigned char *>(outPtr1),
185                         dataType,extX,numberOfComponents,
186                         outputFormat);
187                 if (wl_mode)
188                 {
189                     unsigned short ushort_val;
190                     for (idxX = 0; idxX < extX; idxX++)
191                     {
192                         if (*iptr <= lower) 
193                         {
194                             ushort_val = lower_val;
195                         }
196                         else if (*iptr >= upper)
197                         {
198                             ushort_val = upper_val;
199                         }
200                         else
201                         {
202                             ushort_val = static_cast<unsigned char>((*iptr + shift)*scale);
203                         }
204                         *optr = static_cast<unsigned char>((*optr * ushort_val) >> 8);
205                         switch (outputFormat)
206                         {
207                             case VTK_RGBA:
208                                 *(optr+1) = static_cast<unsigned char>(
209                                         (*(optr+1) * ushort_val) >> 8);
210                                 *(optr+2) = static_cast<unsigned char>(
211                                         (*(optr+2) * ushort_val) >> 8);
212                                 *(optr+3) = 255;
213                                 break;
214                             case VTK_RGB:
215                                 *(optr+1) = static_cast<unsigned char>(
216                                         (*(optr+1) * ushort_val) >> 8);
217                                 *(optr+2) = static_cast<unsigned char>(
218                                         (*(optr+2) * ushort_val) >> 8);
219                                 break;
220                             case VTK_LUMINANCE_ALPHA:
221                                 *(optr+1) = 255;
222                                 break;
223                         }
224                         iptr += numberOfComponents;
225                         optr += numberOfOutputComponents;
226                     }
227                 }
228             }
229             else
230             {
231                 for (idxX = 0; idxX < extX; idxX++)
232                 {
233                     if (*iptr <= lower) 
234                     {
235                         result_val = lower_val;
236                     }
237                     else if (*iptr >= upper)
238                     {
239                         result_val = upper_val;
240                     }
241                     else
242                     {
243                         result_val = static_cast<unsigned char>((*iptr + shift)*scale);
244                     }
245                     *optr = result_val;
246                     switch (outputFormat)
247                     {
248                         case VTK_RGBA:
249                             *(optr+1) = result_val;
250                             *(optr+2) = result_val;            
251                             *(optr+3) = 255;
252                             break;
253                         case VTK_RGB:
254                             *(optr+1) = result_val;
255                             *(optr+2) = result_val;            
256                             break;
257                         case VTK_LUMINANCE_ALPHA:
258                             *(optr+1) = 255;
259                             break;
260                     }
261                     iptr += numberOfComponents;
262                     optr += numberOfOutputComponents;
263                 }
264             }      
265             outPtr1 += outIncY + extX*numberOfOutputComponents;
266             inPtr1 += inIncY + rowLength;
267         }
268         outPtr1 += outIncZ;
269         inPtr1 += inIncZ;
270     }
271 }
272     
273     
274 void vvImageMapToWLColors::ThreadedRequestData(
275   vtkInformation *vtkNotUsed(request),
276   vtkInformationVector **vtkNotUsed(inputVector),
277   vtkInformationVector *vtkNotUsed(outputVector),
278   vtkImageData ***inData,
279   vtkImageData **outData,
280   int outExt[6], int id)
281 {
282     void *inPtr = inData[0][0]->GetScalarPointerForExtent(outExt);
283     void *outPtr = outData[0]->GetScalarPointerForExtent(outExt);
284
285     switch (inData[0][0]->GetScalarType())
286     {
287         vtkTemplateMacro(
288                 vvImageMapToWindowLevelColorsExecute(this, 
289                     inData[0][0], 
290                     static_cast<VTK_TT *>(inPtr), 
291                     outData[0], 
292                     static_cast<unsigned char *>(outPtr), 
293                     outExt, 
294                     id,wl_mode));
295         default:
296         vtkErrorMacro(<< "Execute: Unknown ScalarType");
297         return;
298     }
299 }
300
301