1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkWindowLevelLookupTable.cxx
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 "vtkWindowLevelLookupTable.h"
16 #include "vtkObjectFactory.h"
17 
18 #include <math.h>
19 
20 vtkStandardNewMacro(vtkWindowLevelLookupTable);
21 
22 //----------------------------------------------------------------------------
vtkWindowLevelLookupTable(int sze,int ext)23 vtkWindowLevelLookupTable::vtkWindowLevelLookupTable(int sze, int ext)
24   : vtkLookupTable(sze, ext)
25 {
26   this->Level = (this->TableRange[0] + this->TableRange[1])/2;
27   this->Window = (this->TableRange[1] - this->TableRange[0]);
28 
29   this->InverseVideo = 0;
30 
31   this->MinimumTableValue[0] = 0.0;
32   this->MinimumTableValue[1] = 0.0;
33   this->MinimumTableValue[2] = 0.0;
34   this->MinimumTableValue[3] = 1.0;
35 
36   this->MaximumTableValue[0] = 1.0;
37   this->MaximumTableValue[1] = 1.0;
38   this->MaximumTableValue[2] = 1.0;
39   this->MaximumTableValue[3] = 1.0;
40 }
41 
42 //----------------------------------------------------------------------------
43 // Table is built as a linear ramp between MinimumTableValue and
44 // MaximumTableValue.
Build()45 void vtkWindowLevelLookupTable::Build()
46 {
47   if (this->Table->GetNumberOfTuples() < 1 ||
48       (this->GetMTime() > this->BuildTime &&
49        this->InsertTime < this->BuildTime))
50     {
51     int i, j;
52     unsigned char *rgba;
53     double start[4], incr[4];
54 
55     for (j = 0; j < 4; j++)
56       {
57       start[j] = this->MinimumTableValue[j]*255;
58       incr[j] = ((this->MaximumTableValue[j]-this->MinimumTableValue[j]) /
59                  (this->NumberOfColors - 1) * 255);
60       }
61 
62     if (this->InverseVideo)
63       {
64       for (i = 0; i < this->NumberOfColors; i++)
65         {
66         rgba = this->Table->WritePointer(4*i,4);
67         for (j = 0; j < 4; j++)
68           {
69           rgba[j] = static_cast<unsigned char> \
70             (start[j] + (this->NumberOfColors - i - 1)*incr[j] + 0.5);
71           }
72         }
73       }
74     else
75       {
76       for (i = 0; i < this->NumberOfColors; i++)
77         {
78         rgba = this->Table->WritePointer(4*i,4);
79         for (j = 0; j < 4; j++)
80           {
81           rgba[j] = static_cast<unsigned char>(start[j] + i*incr[j] + 0.5);
82           }
83         }
84       }
85     }
86   this->BuildTime.Modified();
87 }
88 
89 //----------------------------------------------------------------------------
90 // Reverse the color table (don't rebuild in case someone has
91 // been adjusting the table values by hand)
92 // This is a little ugly ... it might be best to remove
93 // SetInverseVideo altogether and just use a negative Window.
SetInverseVideo(int iv)94 void vtkWindowLevelLookupTable::SetInverseVideo(int iv)
95 {
96   if (this->InverseVideo == iv)
97     {
98     return;
99     }
100 
101   this->InverseVideo = iv;
102 
103   if (this->Table->GetNumberOfTuples() < 1)
104     {
105     return;
106     }
107 
108   unsigned char *rgba, *rgba2;
109   unsigned char tmp[4];
110   int i;
111   int n = this->NumberOfColors-1;
112 
113   for (i = 0; i < this->NumberOfColors/2; i++)
114     {
115     rgba = this->Table->WritePointer(4*i,4);
116     rgba2 = this->Table->WritePointer(4*(n-i),4);
117     tmp[0]=rgba[0]; tmp[1]=rgba[1]; tmp[2]=rgba[2]; tmp[3]=rgba[3];
118     rgba[0]=rgba2[0]; rgba[1]=rgba2[1]; rgba[2]=rgba2[2]; rgba[3]=rgba2[3];
119     rgba2[0]=tmp[0]; rgba2[1]=tmp[1]; rgba2[2]=tmp[2]; rgba2[3]=tmp[3];
120     }
121   this->Modified();
122 }
123 
124 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)125 void vtkWindowLevelLookupTable::PrintSelf(ostream& os, vtkIndent indent)
126 {
127   this->Superclass::PrintSelf(os,indent);
128 
129   os << indent << "Window: " << this->Window << "\n";
130   os << indent << "Level: " << this->Level << "\n";
131   os << indent << "InverseVideo: "
132      << (this->InverseVideo ? "On\n" : "Off\n");
133   os << indent << "MinimumTableValue : ("
134      << this->MinimumTableValue[0] << ", "
135      << this->MinimumTableValue[1] << ", "
136      << this->MinimumTableValue[2] << ", "
137      << this->MinimumTableValue[3] << ")\n";
138   os << indent << "MaximumTableValue : ("
139      << this->MaximumTableValue[0] << ", "
140      << this->MaximumTableValue[1] << ", "
141      << this->MaximumTableValue[2] << ", "
142      << this->MaximumTableValue[3] << ")\n";
143 }
144