~ubuntu-branches/ubuntu/wily/ginkgocadx/wily-proposed

« back to all changes in this revision

Viewing changes to src/cadxcore/wx/VTK/vtkImageMapToWindowLevelColors2.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Tille
  • Date: 2011-05-02 08:09:26 UTC
  • Revision ID: james.westby@ubuntu.com-20110502080926-bql5wep49c7hg91t
Tags: upstream-2.4.1.1
ImportĀ upstreamĀ versionĀ 2.4.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*=========================================================================
 
2
 
 
3
 Program:   Visualization Toolkit
 
4
 Module:    $RCSfile: vtkImageMapToWindowLevelColors2.cxx,v $
 
5
 
 
6
 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
 
7
 All rights reserved.
 
8
 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
 
9
 
 
10
 This software is distributed WITHOUT ANY WARRANTY; without even
 
11
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 
12
 PURPOSE.  See the above copyright notice for more information.
 
13
 
 
14
 =========================================================================*/
 
15
#include "vtkImageMapToWindowLevelColors2.h"
 
16
 
 
17
#include <vtkDataArray.h>
 
18
#include <vtkImageData.h>
 
19
#include <vtkInformation.h>
 
20
#include <vtkInformationVector.h>
 
21
#include <vtkObjectFactory.h>
 
22
#include <vtkScalarsToColors.h>
 
23
#include <vtkPointData.h>
 
24
 
 
25
vtkCxxRevisionMacro(vtkImageMapToWindowLevelColors2, "$Revision: 1.3 $")
 
26
vtkStandardNewMacro(vtkImageMapToWindowLevelColors2)
 
27
 
 
28
// Constructor sets default values
 
29
vtkImageMapToWindowLevelColors2::vtkImageMapToWindowLevelColors2()
 
30
{
 
31
        this->Window = 255;
 
32
        this->Level  = 127.5;
 
33
}
 
34
 
 
35
vtkImageMapToWindowLevelColors2::~vtkImageMapToWindowLevelColors2()
 
36
{
 
37
}
 
38
 
 
39
//----------------------------------------------------------------------------
 
40
// This method checks to see if we can simply reference the input data
 
41
int vtkImageMapToWindowLevelColors2::RequestData(
 
42
                                                                                                 vtkInformation *request,
 
43
                                                                                                 vtkInformationVector **inputVector,
 
44
                                                                                                 vtkInformationVector *outputVector)
 
45
{
 
46
        vtkInformation *outInfo = outputVector->GetInformationObject(0);
 
47
        vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
 
48
        
 
49
        vtkImageData *outData = vtkImageData::SafeDownCast(
 
50
                                                                                                           outInfo->Get(vtkDataObject::DATA_OBJECT()));
 
51
        vtkImageData *inData = vtkImageData::SafeDownCast(
 
52
                                                                                                          inInfo->Get(vtkDataObject::DATA_OBJECT()));
 
53
        
 
54
        // If LookupTable is null and window / level produces no change,
 
55
        // then just pass the data
 
56
        if (this->LookupTable == NULL &&
 
57
                (inData->GetScalarType() == VTK_UNSIGNED_CHAR &&
 
58
                 this->Window == 255 && this->Level == 127.5))
 
59
    {
 
60
                vtkDebugMacro("ExecuteData: LookupTable not set, "\
 
61
                                          "Window / Level at default, "\
 
62
                                          "passing input to output.");
 
63
                
 
64
                outData->SetExtent(inData->GetExtent());
 
65
                outData->GetPointData()->PassData(inData->GetPointData());
 
66
                this->DataWasPassed = 1;
 
67
    }
 
68
        else
 
69
                // normal behaviour - skip up a level since we don't want to
 
70
                // call the superclasses ExecuteData - it would pass the data if there
 
71
                // is no lookup table even if there is a window / level - wrong
 
72
                // behavior.
 
73
    {
 
74
                if (this->DataWasPassed)
 
75
                {
 
76
                        outData->GetPointData()->SetScalars(NULL);
 
77
                        this->DataWasPassed = 0;
 
78
                }
 
79
                
 
80
                return this->vtkThreadedImageAlgorithm::RequestData(request, inputVector,
 
81
                                                                                                                        outputVector);
 
82
    }
 
83
        
 
84
        return 1;
 
85
}
 
86
 
 
87
//----------------------------------------------------------------------------
 
88
int vtkImageMapToWindowLevelColors2::RequestInformation (
 
89
                                                                                                                 vtkInformation *vtkNotUsed(request),
 
90
                                                                                                                 vtkInformationVector **inputVector,
 
91
                                                                                                                 vtkInformationVector *outputVector)
 
92
{
 
93
        vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
 
94
        vtkInformation *outInfo = outputVector->GetInformationObject(0);
 
95
        
 
96
        vtkInformation *inScalarInfo = 
 
97
    vtkDataObject::GetActiveFieldInformation(inInfo, 
 
98
                                                                                         vtkDataObject::FIELD_ASSOCIATION_POINTS, vtkDataSetAttributes::SCALARS);
 
99
        if (!inScalarInfo)
 
100
    {
 
101
                vtkErrorMacro("Missing scalar field on input information!");
 
102
                return 0;
 
103
    }
 
104
        
 
105
        // If LookupTable is null and window / level produces no change,
 
106
        // then the data will be passed
 
107
        if ( this->LookupTable == NULL &&
 
108
                (inScalarInfo->Get(vtkDataObject::FIELD_ARRAY_TYPE()) == 
 
109
                 VTK_UNSIGNED_CHAR &&
 
110
                 this->Window == 255 && this->Level == 127.5) )
 
111
    {
 
112
                if (inScalarInfo->Get(vtkDataObject::FIELD_ARRAY_TYPE()) != 
 
113
                        VTK_UNSIGNED_CHAR)
 
114
                {
 
115
                        vtkErrorMacro("ExecuteInformation: No LookupTable was set and input data is not VTK_UNSIGNED_CHAR!");
 
116
                }
 
117
                else
 
118
                {
 
119
                        // no lookup table, pass the input if it was UNSIGNED_CHAR 
 
120
                        vtkDataObject::SetPointDataActiveScalarInfo
 
121
                        (outInfo, VTK_UNSIGNED_CHAR, 
 
122
                         inScalarInfo->Get(vtkDataObject::FIELD_NUMBER_OF_COMPONENTS()));
 
123
                }
 
124
    }
 
125
        else  // the lookup table was set or window / level produces a change
 
126
    {
 
127
                int numComponents = 4;
 
128
                switch (this->OutputFormat)
 
129
                {
 
130
                        case VTK_RGBA:
 
131
                                numComponents = 4;
 
132
                                break;
 
133
                        case VTK_RGB:
 
134
                                numComponents = 3;
 
135
                                break;
 
136
                        case VTK_LUMINANCE_ALPHA:
 
137
                                numComponents = 2;
 
138
                                break;
 
139
                        case VTK_LUMINANCE:
 
140
                                numComponents = 1;
 
141
                                break;
 
142
                        default:
 
143
                                vtkErrorMacro("ExecuteInformation: Unrecognized color format.");
 
144
                                break;
 
145
                }
 
146
                vtkDataObject::SetPointDataActiveScalarInfo(outInfo, VTK_UNSIGNED_CHAR, numComponents);
 
147
    }
 
148
        
 
149
        return 1;
 
150
}
 
151
 
 
152
/* 
 
153
 * This templated routine calculates effective lower and upper limits 
 
154
 * for a window of values of type T, lower and upper. 
 
155
 */
 
156
template <class T>
 
157
void vtkImageMapToWindowLevelClamps ( vtkImageData *data, double w, 
 
158
                                                                         double l, T& lower, T& upper, 
 
159
                                                                         unsigned char &lower_val, 
 
160
                                                                         unsigned char &upper_val)
 
161
{
 
162
        double f_lower, f_upper, f_lower_val, f_upper_val;
 
163
        double adjustedLower, adjustedUpper;
 
164
        double range[2];
 
165
        
 
166
        data->GetPointData()->GetScalars()->GetDataTypeRange( range );
 
167
        
 
168
        f_lower = l - fabs(w) / 2.0;
 
169
        f_upper = f_lower + fabs(w);
 
170
        
 
171
        // Set the correct lower value
 
172
        if ( f_lower <= range[1])
 
173
    {
 
174
                if (f_lower >= range[0])
 
175
                {
 
176
                        lower = (T) f_lower;
 
177
                        adjustedLower = f_lower;
 
178
                }
 
179
                else
 
180
                {
 
181
                        lower = (T) range[0];
 
182
                        adjustedLower = range[0];
 
183
                }
 
184
    }
 
185
        else
 
186
    {
 
187
                lower = (T) range[1];
 
188
                adjustedLower = range[1];
 
189
    }
 
190
        
 
191
        // Set the correct upper value
 
192
        if ( f_upper >= range[0])
 
193
    {
 
194
                if (f_upper <= range[1])
 
195
                {
 
196
                        upper = (T) f_upper;
 
197
                        adjustedUpper = f_upper;
 
198
                }
 
199
                else
 
200
                {
 
201
                        upper = (T) range[1];
 
202
                        adjustedUpper = range[1];
 
203
                }
 
204
    }
 
205
        else
 
206
    {
 
207
                upper = (T) range [0];
 
208
                adjustedUpper = range [0];
 
209
    }
 
210
        
 
211
        // now compute the lower and upper values
 
212
        if (w >= 0)
 
213
    {
 
214
                f_lower_val = 255.0*(adjustedLower - f_lower)/w;
 
215
                f_upper_val = 255.0*(adjustedUpper - f_lower)/w;
 
216
    }
 
217
        else
 
218
    {
 
219
                f_lower_val = 255.0 + 255.0*(adjustedLower - f_lower)/w;
 
220
                f_upper_val = 255.0 + 255.0*(adjustedUpper - f_lower)/w;
 
221
    }
 
222
        
 
223
        if (f_upper_val > 255) 
 
224
    {
 
225
                upper_val = 255;
 
226
    }
 
227
        else if (f_upper_val < 0)
 
228
    {
 
229
                upper_val = 0;
 
230
    }
 
231
        else
 
232
    {
 
233
                upper_val = (unsigned char)(f_upper_val);
 
234
    }
 
235
        
 
236
        if (f_lower_val > 255) 
 
237
    {
 
238
                lower_val = 255;
 
239
    }
 
240
        else if (f_lower_val < 0)
 
241
    {
 
242
                lower_val = 0;
 
243
    }
 
244
        else
 
245
    {
 
246
                lower_val = (unsigned char)(f_lower_val);
 
247
    }  
 
248
}
 
249
 
 
250
//----------------------------------------------------------------------------
 
251
// Small helper to do the clamp:
 
252
template <typename T>
 
253
void vtkClampHelper1(T* iptr, unsigned char *optr,
 
254
                                         T lower, T upper,
 
255
                                         unsigned char lower_val, unsigned char upper_val, 
 
256
                                         double shift, double scale)
 
257
{
 
258
        unsigned short ushort_val;
 
259
        if (*iptr <= lower) 
 
260
    {
 
261
                ushort_val = lower_val;
 
262
    }
 
263
        else if (*iptr >= upper)
 
264
    {
 
265
                ushort_val = upper_val;
 
266
    }
 
267
        else
 
268
    {
 
269
                ushort_val = (unsigned char) ((*iptr + shift)*scale);
 
270
    }
 
271
        *optr = (unsigned char)((*optr * ushort_val) >> 8);
 
272
}
 
273
 
 
274
//----------------------------------------------------------------------------
 
275
template <typename T>
 
276
void vtkClampHelper2(T* iptr, unsigned char *optr,
 
277
                                         T lower, T upper,
 
278
                                         unsigned char lower_val, unsigned char upper_val, 
 
279
                                         double shift, double scale)
 
280
{
 
281
        unsigned char result_val;
 
282
        if (*iptr <= lower) 
 
283
    {
 
284
                result_val = lower_val;
 
285
    }
 
286
        else if (*iptr >= upper)
 
287
    {
 
288
                result_val = upper_val;
 
289
    }
 
290
        else
 
291
    {
 
292
                result_val = (unsigned char) ((*iptr + shift)*scale);
 
293
    }
 
294
        *optr = result_val;
 
295
}
 
296
 
 
297
//----------------------------------------------------------------------------
 
298
// This non-templated function executes the filter for any type of data.
 
299
template <class T>
 
300
void vtkImageMapToWindowLevelColors2Execute(
 
301
                                                                                        vtkImageMapToWindowLevelColors2 *self, 
 
302
                                                                                        vtkImageData *inData, T *inPtr,
 
303
                                                                                        vtkImageData *outData, 
 
304
                                                                                        unsigned char *outPtr,
 
305
                                                                                        int outExt[6], int id)
 
306
{
 
307
        int idxX, idxY, idxZ;
 
308
        int extX, extY, extZ;
 
309
        vtkIdType inIncX, inIncY, inIncZ;
 
310
        vtkIdType outIncX, outIncY, outIncZ;
 
311
        unsigned long count = 0;
 
312
        unsigned long target;
 
313
        int dataType = inData->GetScalarType();
 
314
        int numberOfComponents,numberOfOutputComponents,outputFormat;
 
315
        int rowLength;
 
316
        vtkScalarsToColors *lookupTable = self->GetLookupTable();
 
317
        unsigned char *outPtr1;
 
318
        T *inPtr1;
 
319
        unsigned char *optr;
 
320
        T    *iptr;
 
321
        double shift =  self->GetWindow() / 2.0 - self->GetLevel();
 
322
        double scale = 255.0 / self->GetWindow();
 
323
        
 
324
        T   lower, upper;
 
325
        unsigned char lower_val, upper_val;
 
326
        vtkImageMapToWindowLevelClamps( inData, self->GetWindow(), 
 
327
                                                                   self->GetLevel(), 
 
328
                                                                   lower, upper, lower_val, upper_val );
 
329
        
 
330
        // find the region to loop over
 
331
        extX = outExt[1] - outExt[0] + 1;
 
332
        extY = outExt[3] - outExt[2] + 1; 
 
333
        extZ = outExt[5] - outExt[4] + 1;
 
334
        
 
335
        target = (unsigned long)(extZ*extY/50.0);
 
336
        target++;
 
337
        
 
338
        // Get increments to march through data 
 
339
        inData->GetContinuousIncrements(outExt, inIncX, inIncY, inIncZ);
 
340
        
 
341
        outData->GetContinuousIncrements(outExt, outIncX, outIncY, outIncZ);
 
342
        numberOfComponents = inData->GetNumberOfScalarComponents();
 
343
        numberOfOutputComponents = outData->GetNumberOfScalarComponents();
 
344
        outputFormat = self->GetOutputFormat();
 
345
        
 
346
        rowLength = extX*numberOfComponents;
 
347
        
 
348
        // Loop through output pixels
 
349
        outPtr1 = outPtr;
 
350
        inPtr1 = inPtr;
 
351
        for (idxZ = 0; idxZ < extZ; idxZ++)
 
352
    {
 
353
                for (idxY = 0; !self->AbortExecute && idxY < extY; idxY++)
 
354
                {
 
355
                        if (!id) 
 
356
                        {
 
357
                                if (!(count%target))
 
358
                                {
 
359
                                        self->UpdateProgress(count/(50.0*target));
 
360
                                }
 
361
                                count++;
 
362
                        }
 
363
                        
 
364
                        iptr = inPtr1;
 
365
                        optr = outPtr1;
 
366
                        
 
367
                        if ( lookupTable )
 
368
                        {
 
369
                                lookupTable->MapScalarsThroughTable2(inPtr1,(unsigned char *)outPtr1,
 
370
                                                                                                         dataType,extX,numberOfComponents,
 
371
                                                                                                         outputFormat);
 
372
                                
 
373
                                for (idxX = 0; idxX < extX; idxX++)
 
374
                                {
 
375
                                        vtkClampHelper1<T>(iptr,optr,lower,upper,lower_val,upper_val,shift,scale);
 
376
                                        switch (outputFormat)
 
377
                                        {
 
378
                                                case VTK_RGBA:
 
379
                                                        vtkClampHelper1<T>(iptr+(1%numberOfComponents),optr+1,lower,upper,lower_val,upper_val,shift,scale);
 
380
                                                        vtkClampHelper1<T>(iptr+(2%numberOfComponents),optr+2,lower,upper,lower_val,upper_val,shift,scale);
 
381
                                                        *(optr+3) = 255;
 
382
                                                        break;
 
383
                                                case VTK_RGB:
 
384
                                                        vtkClampHelper1<T>(iptr+(1%numberOfComponents),optr+1,lower,upper,lower_val,upper_val,shift,scale);
 
385
                                                        vtkClampHelper1<T>(iptr+(2%numberOfComponents),optr+2,lower,upper,lower_val,upper_val,shift,scale);
 
386
                                                        break;
 
387
                                                case VTK_LUMINANCE_ALPHA:
 
388
                                                        *(optr+1) = 255;
 
389
                                                        break;
 
390
                                        }
 
391
                                        iptr += numberOfComponents;
 
392
                                        optr += numberOfOutputComponents;
 
393
                                }
 
394
                        }
 
395
                        else
 
396
                        {
 
397
                                for (idxX = 0; idxX < extX; idxX++)
 
398
                                {
 
399
                                        // We want to shift to the right position depending on the numberOfComponents from input
 
400
                                        // if grayscale we should stay at the same position, otherwise need to shift to r,g,b
 
401
                                        // (0%numberOfComponents) == 0 ...
 
402
                                        // (1%numberOfComponents) == 0 or 1
 
403
                                        vtkClampHelper2<T>(iptr,optr,lower,upper,lower_val,upper_val,shift,scale);
 
404
                                        switch (outputFormat)
 
405
                                        {
 
406
                                                case VTK_RGBA:
 
407
                                                        vtkClampHelper2<T>(iptr+(1%numberOfComponents),optr+1,lower,upper,lower_val,upper_val,shift,scale);
 
408
                                                        vtkClampHelper2<T>(iptr+(2%numberOfComponents),optr+2,lower,upper,lower_val,upper_val,shift,scale);
 
409
                                                        *(optr+3) = 255;
 
410
                                                        break;
 
411
                                                case VTK_RGB:
 
412
                                                        vtkClampHelper2<T>(iptr+(1%numberOfComponents),optr+1,lower,upper,lower_val,upper_val,shift,scale);
 
413
                                                        vtkClampHelper2<T>(iptr+(2%numberOfComponents),optr+2,lower,upper,lower_val,upper_val,shift,scale);
 
414
                                                        break;
 
415
                                                case VTK_LUMINANCE_ALPHA:
 
416
                                                        *(optr+1) = 255;
 
417
                                                        break;
 
418
                                        }
 
419
                                        iptr += numberOfComponents;
 
420
                                        optr += numberOfOutputComponents;
 
421
                                }
 
422
                        }      
 
423
                        outPtr1 += outIncY + extX*numberOfOutputComponents;
 
424
                        inPtr1 += inIncY + rowLength;
 
425
                }
 
426
                outPtr1 += outIncZ;
 
427
                inPtr1 += inIncZ;
 
428
    }
 
429
}
 
430
 
 
431
//----------------------------------------------------------------------------
 
432
// This method is passed a input and output data, and executes the filter
 
433
// algorithm to fill the output from the input.
 
434
 
 
435
void vtkImageMapToWindowLevelColors2::ThreadedRequestData(
 
436
                                                                                                                  vtkInformation *vtkNotUsed(request),
 
437
                                                                                                                  vtkInformationVector **vtkNotUsed(inputVector),
 
438
                                                                                                                  vtkInformationVector *vtkNotUsed(outputVector),
 
439
                                                                                                                  vtkImageData ***inData,
 
440
                                                                                                                  vtkImageData **outData,
 
441
                                                                                                                  int outExt[6], int id)
 
442
{
 
443
        void *inPtr = inData[0][0]->GetScalarPointerForExtent(outExt);
 
444
        void *outPtr = outData[0]->GetScalarPointerForExtent(outExt);
 
445
        
 
446
        switch (inData[0][0]->GetScalarType())
 
447
    {
 
448
                        vtkTemplateMacro(
 
449
                                                         vtkImageMapToWindowLevelColors2Execute( this, 
 
450
                                                                                                                                        inData[0][0], 
 
451
                                                                                                                                        (VTK_TT *)(inPtr), 
 
452
                                                                                                                                        outData[0], 
 
453
                                                                                                                                        (unsigned char *)(outPtr), 
 
454
                                                                                                                                        outExt, 
 
455
                                                                                                                                        id));
 
456
                default:
 
457
                        vtkErrorMacro(<< "Execute: Unknown ScalarType");
 
458
                        return;
 
459
    }
 
460
}
 
461
 
 
462
//----------------------------------------------------------------------------
 
463
void vtkImageMapToWindowLevelColors2::PrintSelf(ostream& os, vtkIndent indent)
 
464
{
 
465
        this->Superclass::PrintSelf(os,indent);
 
466
        
 
467
        os << indent << "Window: " << this->Window << endl;
 
468
        os << indent << "Level: " << this->Level << endl;
 
469
}