]> Creatis software - clitk.git/blob - vv/vvImageMapToWLColors.cxx
9cc9f82a80a9ea153ca5989f9e8c76bea20713cd
[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     if (f_lower >= range[0]) {
53       lower = static_cast<T>(f_lower);
54       adjustedLower = f_lower;
55     } else {
56       lower = static_cast<T>(range[0]);
57       adjustedLower = range[0];
58     }
59   } else {
60     lower = static_cast<T>(range[1]);
61     adjustedLower = range[1];
62   }
63
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;
69     } else {
70       upper = static_cast<T>(range[1]);
71       adjustedUpper = range[1];
72     }
73   } else {
74     upper = static_cast<T>(range[0]);
75     adjustedUpper = range [0];
76   }
77
78   // now compute the lower and upper values
79   if (w >= 0) {
80     f_lower_val = 255.0*(adjustedLower - f_lower)/w;
81     f_upper_val = 255.0*(adjustedUpper - f_lower)/w;
82   } else {
83     f_lower_val = 255.0 + 255.0*(adjustedLower - f_lower)/w;
84     f_upper_val = 255.0 + 255.0*(adjustedUpper - f_lower)/w;
85   }
86
87   if (f_upper_val > 255) {
88     upper_val = 255;
89   } else if (f_upper_val < 0) {
90     upper_val = 0;
91   } else {
92     upper_val = static_cast<unsigned char>(f_upper_val);
93   }
94
95   if (f_lower_val > 255) {
96     lower_val = 255;
97   } else if (f_lower_val < 0) {
98     lower_val = 0;
99   } else {
100     lower_val = static_cast<unsigned char>(f_lower_val);
101   }
102 }
103
104 template <class T>
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)
111 {
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;
120   int rowLength;
121   vtkScalarsToColors *lookupTable = self->GetLookupTable();
122   unsigned char *outPtr1;
123   T *inPtr1;
124   unsigned char *optr;
125   T    *iptr;
126   double shift =  self->GetWindow() / 2.0 - self->GetLevel();
127   double scale = 255.0 / self->GetWindow();
128
129   T   lower, upper;
130   unsigned char lower_val, upper_val, result_val;
131   vtkImageMapToWindowLevelClamps( inData, self->GetWindow(),
132                                   self->GetLevel(),
133                                   lower, upper, lower_val, upper_val );
134
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;
139
140   target = static_cast<unsigned long>(extZ*extY/50.0);
141   target++;
142
143   // Get increments to march through data
144   inData->GetContinuousIncrements(outExt, inIncX, inIncY, inIncZ);
145
146   outData->GetContinuousIncrements(outExt, outIncX, outIncY, outIncZ);
147   numberOfComponents = inData->GetNumberOfScalarComponents();
148   numberOfOutputComponents = outData->GetNumberOfScalarComponents();
149   outputFormat = self->GetOutputFormat();
150
151   rowLength = extX*numberOfComponents;
152
153   // Loop through output pixels
154   outPtr1 = outPtr;
155   inPtr1 = inPtr;
156   for (idxZ = 0; idxZ < extZ; idxZ++) {
157     for (idxY = 0; !self->AbortExecute && idxY < extY; idxY++) {
158       if (!id) {
159         if (!(count%target)) {
160           self->UpdateProgress(count/(50.0*target));
161         }
162         count++;
163       }
164
165       iptr = inPtr1;
166       optr = outPtr1;
167
168       if ( lookupTable ) {
169         lookupTable->MapScalarsThroughTable2(
170           inPtr1,
171           static_cast<unsigned char *>(outPtr1),
172           dataType,extX,numberOfComponents,
173           outputFormat);
174         if (wl_mode) {
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;
181             } else {
182               ushort_val = static_cast<unsigned char>((*iptr + shift)*scale);
183             }
184             *optr = static_cast<unsigned char>((*optr * ushort_val) >> 8);
185             switch (outputFormat) {
186             case VTK_RGBA:
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);
191               *(optr+3) = 255;
192               break;
193             case VTK_RGB:
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);
198               break;
199             case VTK_LUMINANCE_ALPHA:
200               *(optr+1) = 255;
201               break;
202             }
203             iptr += numberOfComponents;
204             optr += numberOfOutputComponents;
205           }
206         }
207       } else {
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;
213           } else {
214             result_val = static_cast<unsigned char>((*iptr + shift)*scale);
215           }
216           *optr = result_val;
217           switch (outputFormat) {
218           case VTK_RGBA:
219             *(optr+1) = result_val;
220             *(optr+2) = result_val;
221             *(optr+3) = 255;
222             break;
223           case VTK_RGB:
224             *(optr+1) = result_val;
225             *(optr+2) = result_val;
226             break;
227           case VTK_LUMINANCE_ALPHA:
228             *(optr+1) = 255;
229             break;
230           }
231           iptr += numberOfComponents;
232           optr += numberOfOutputComponents;
233         }
234       }
235       outPtr1 += outIncY + extX*numberOfOutputComponents;
236       inPtr1 += inIncY + rowLength;
237     }
238     outPtr1 += outIncZ;
239     inPtr1 += inIncZ;
240   }
241 }
242
243
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)
251 {
252   void *inPtr = inData[0][0]->GetScalarPointerForExtent(outExt);
253   void *outPtr = outData[0]->GetScalarPointerForExtent(outExt);
254
255   switch (inData[0][0]->GetScalarType()) {
256     vtkTemplateMacro(
257       vvImageMapToWindowLevelColorsExecute(this,
258                                            inData[0][0],
259                                            static_cast<VTK_TT *>(inPtr),
260                                            outData[0],
261                                            static_cast<unsigned char *>(outPtr),
262                                            outExt,
263                                            id,wl_mode));
264   default:
265     vtkErrorMacro(<< "Execute: Unknown ScalarType");
266     return;
267   }
268 }
269
270