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