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