7 #include "fwRenderVTK/vtk/fwVtkWindowLevelLookupTable.hpp" 9 #include <vtkBitArray.h> 11 #include <vtkObjectFactory.h> 19 fwVtkWindowLevelLookupTable::fwVtkWindowLevelLookupTable(
int sze,
int ext) :
20 vtkLookupTable(sze, ext)
22 this->Level = (this->TableRange[0] + this->TableRange[1])/2;
23 this->Window = (this->TableRange[1] - this->TableRange[0]);
25 this->InverseVideo = 0;
29 this->LeftClampValue[0] = 0.0;
30 this->LeftClampValue[1] = 0.0;
31 this->LeftClampValue[2] = 0.0;
32 this->LeftClampValue[3] = 0.0;
34 this->RightClampValue[0] = 0.0;
35 this->RightClampValue[1] = 0.0;
36 this->RightClampValue[2] = 0.0;
37 this->RightClampValue[3] = 0.0;
39 this->InvertTable = vtkUnsignedCharArray::New();
40 this->InvertTable->Register(
this);
41 this->InvertTable->Delete();
42 this->InvertTable->SetNumberOfComponents(4);
43 this->InvertTable->Allocate(4*sze, 4*ext);
46 fwVtkWindowLevelLookupTable::~fwVtkWindowLevelLookupTable()
48 this->InvertTable->UnRegister(
this);
49 this->InvertTable = NULL;
54 void fwVtkWindowLevelLookupTable::BuildInvert()
56 if (this->GetMTime() < this->InvertTime)
60 if (this->Table->GetNumberOfTuples() < 1)
65 this->InvertTable->SetNumberOfTuples(this->NumberOfColors);
67 unsigned char* tableRgba, * invertTableRgba2;
69 int n =
static_cast<int>(this->NumberOfColors-1);
70 for (
int i = 0; i < this->NumberOfColors; i++)
72 tableRgba = this->Table->GetPointer(4*i);
73 invertTableRgba2 = this->InvertTable->WritePointer(4*(n-i), 4);
75 invertTableRgba2[0] = tableRgba[0];
76 invertTableRgba2[1] = tableRgba[1];
77 invertTableRgba2[2] = tableRgba[2];
78 invertTableRgba2[3] = tableRgba[3];
81 this->InvertTime.Modified();
87 unsigned char* fwVtkWindowLevelLookupTable::GetCurrentPointer(
const vtkIdType
id)
89 if(this->InverseVideo)
92 return this->InvertTable->GetPointer(4*
id);
96 return this->Table->GetPointer(4*
id);
101 void fwVtkWindowLevelLookupTable::PrintSelf(ostream& os, vtkIndent indent)
103 this->Superclass::PrintSelf(os, indent);
105 os << indent <<
"Window: " << this->Window <<
"\n";
106 os << indent <<
"Level: " << this->Level <<
"\n";
107 os << indent <<
"InverseVideo: " 108 << (this->InverseVideo ?
"On\n" :
"Off\n");
109 os << indent <<
"LeftClampValue : (" 110 << this->LeftClampValue[0] <<
", " 111 << this->LeftClampValue[1] <<
", " 112 << this->LeftClampValue[2] <<
", " 113 << this->LeftClampValue[3] <<
")\n";
114 os << indent <<
"RightClampValue : (" 115 << this->RightClampValue[0] <<
", " 116 << this->RightClampValue[1] <<
", " 117 << this->RightClampValue[2] <<
", " 118 << this->RightClampValue[3] <<
")\n";
123 inline double vtkApplyLogScale(
double v,
const double range[2],
124 const double logRange[2])
131 v = log10(-static_cast<double>(v));
133 else if (range[0] > range[1])
146 v = log10(static_cast<double>(v));
148 else if (range[0] < range[1])
162 inline unsigned char* vtkLinearLookup(
double v,
163 unsigned char* table,
165 double shift,
double scale,
166 unsigned char* nanColor,
167 unsigned char* leftColor,
168 unsigned char* rightColor
172 if (vtkMath::IsNan(v))
177 double findx = (v + shift)*scale;
182 else if (findx > maxIndex)
186 return &table[4*
static_cast<unsigned int>(findx)];
196 void fwVtkWindowLevelLookupTableLogRange(
const double range[2],
double logRange[2])
198 double rmin = range[0];
199 double rmax = range[1];
203 rmin = 1.0e-6*(rmax - rmin);
211 rmax = 1.0e-6*(rmin - rmax);
217 if (rmin < 0 && rmax < 0)
219 logRange[0] = log10(-static_cast<double>(rmin));
220 logRange[1] = log10(-static_cast<double>(rmax));
222 else if (rmin > 0 && rmax > 0)
224 logRange[0] = log10(static_cast<double>(rmin));
225 logRange[1] = log10(static_cast<double>(rmax));
234 unsigned char* output,
int length,
235 int inIncr,
int outFormat)
238 double* range =
self->GetTableRange();
239 double maxIndex =
self->GetNumberOfColors() - 1;
241 unsigned char* table =
self->GetCurrentPointer(0);
245 unsigned char nanColor[4];
246 unsigned char selfLeftColor[4];
247 unsigned char selfRightColor[4];
249 for (
int c = 0; c < 4; c++)
251 nanColor[c] =
static_cast<unsigned char>(
self->GetNanColor()[c]*255.0);
252 selfLeftColor[c] =
static_cast<unsigned char>(
self->GetLeftClampValue()[c]*255.0);
253 selfRightColor[c] =
static_cast<unsigned char>(
self->GetRightClampValue()[c]*255.0);
256 unsigned char* leftColor = selfLeftColor;
257 unsigned char* rightColor = selfRightColor;
259 if(self->GetClamping())
261 leftColor = &table[0];
262 rightColor = &table[(
self->GetNumberOfColors()-1) * 4];
265 if ( (alpha = self->GetAlpha()) >= 1.0 )
267 if (self->GetScale() == VTK_SCALE_LOG10)
271 fwVtkWindowLevelLookupTableLogRange(range, logRange);
272 shift = -logRange[0];
273 if (logRange[1] <= logRange[0])
275 scale = VTK_DOUBLE_MAX;
283 scale = (maxIndex)/(logRange[1] - logRange[0]);
285 if (outFormat == VTK_RGBA)
289 val = vtkApplyLogScale(*input, range, logRange);
290 cptr = vtkLinearLookup(val, table, maxIndex, shift, scale, nanColor, leftColor, rightColor);
298 else if (outFormat == VTK_RGB)
302 val = vtkApplyLogScale(*input, range, logRange);
303 cptr = vtkLinearLookup(val, table, maxIndex, shift, scale, nanColor, leftColor, rightColor);
310 else if (outFormat == VTK_LUMINANCE_ALPHA)
314 val = vtkApplyLogScale(*input, range, logRange);
315 cptr = vtkLinearLookup(val, table, maxIndex, shift, scale, nanColor, leftColor, rightColor);
316 *output++ =
static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
326 val = vtkApplyLogScale(*input, range, logRange);
327 cptr = vtkLinearLookup(val, table, maxIndex, shift, scale, nanColor, leftColor, rightColor);
328 *output++ =
static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
338 if (range[1] <= range[0])
340 scale = VTK_DOUBLE_MAX;
348 scale = (maxIndex)/(range[1] - range[0]);
351 if (outFormat == VTK_RGBA)
355 cptr = vtkLinearLookup(*input, table, maxIndex, shift, scale,
356 nanColor, leftColor, rightColor);
364 else if (outFormat == VTK_RGB)
368 cptr = vtkLinearLookup(*input, table, maxIndex, shift, scale,
369 nanColor, leftColor, rightColor);
376 else if (outFormat == VTK_LUMINANCE_ALPHA)
380 cptr = vtkLinearLookup(*input, table, maxIndex, shift, scale,
381 nanColor, leftColor, rightColor);
382 *output++ =
static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
392 cptr = vtkLinearLookup(*input, table, maxIndex, shift, scale,
393 nanColor, leftColor, rightColor);
394 *output++ =
static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
404 if (self->GetScale() == VTK_SCALE_LOG10)
408 fwVtkWindowLevelLookupTableLogRange(range, logRange);
409 shift = -logRange[0];
410 if (logRange[1] <= logRange[0])
412 scale = VTK_DOUBLE_MAX;
420 scale = (maxIndex)/(logRange[1] - logRange[0]);
422 if (outFormat == VTK_RGBA)
426 val = vtkApplyLogScale(*input, range, logRange);
427 cptr = vtkLinearLookup(val, table, maxIndex, shift, scale, nanColor, leftColor, rightColor);
431 *output++ =
static_cast<unsigned char>((*cptr)*alpha); cptr++;
435 else if (outFormat == VTK_RGB)
439 val = vtkApplyLogScale(*input, range, logRange);
440 cptr = vtkLinearLookup(val, table, maxIndex, shift, scale, nanColor, leftColor, rightColor);
447 else if (outFormat == VTK_LUMINANCE_ALPHA)
451 val = vtkApplyLogScale(*input, range, logRange);
452 cptr = vtkLinearLookup(val, table, maxIndex, shift, scale, nanColor, leftColor, rightColor);
453 *output++ =
static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
455 *output++ =
static_cast<unsigned char>(alpha*cptr[3]);
463 val = vtkApplyLogScale(*input, range, logRange);
464 cptr = vtkLinearLookup(val, table, maxIndex, shift, scale, nanColor, leftColor, rightColor);
465 *output++ =
static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
475 if (range[1] <= range[0])
477 scale = VTK_DOUBLE_MAX;
485 scale = (maxIndex)/(range[1] - range[0]);
488 if (outFormat == VTK_RGBA)
492 cptr = vtkLinearLookup(*input, table, maxIndex, shift, scale,
493 nanColor, leftColor, rightColor);
497 *output++ =
static_cast<unsigned char>((*cptr)*alpha); cptr++;
501 else if (outFormat == VTK_RGB)
505 cptr = vtkLinearLookup(*input, table, maxIndex, shift, scale,
506 nanColor, leftColor, rightColor);
513 else if (outFormat == VTK_LUMINANCE_ALPHA)
517 cptr = vtkLinearLookup(*input, table, maxIndex, shift, scale,
518 nanColor, leftColor, rightColor);
519 *output++ =
static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
521 *output++ =
static_cast<unsigned char>(cptr[3]*alpha);
529 cptr = vtkLinearLookup(*input, table, maxIndex, shift, scale,
530 nanColor, leftColor, rightColor);
531 *output++ =
static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
547 unsigned char* output,
int length,
548 int inIncr,
int outFormat)
554 mag =
new double[length];
555 for (i = 0; i < length; ++i)
558 for (j = 0; j < inIncr; ++j)
560 tmp =
static_cast<double>(*input);
567 fwVtkWindowLevelLookupTableMapData(
self, mag, output, length, 1, outFormat);
573 void fwVtkWindowLevelLookupTable::MapScalarsThroughTable2(
void* input,
574 unsigned char* output,
580 if (this->UseMagnitude && inputIncrement > 1)
582 switch (inputDataType)
585 fwVtkWindowLevelLookupTableMapMag(
this, static_cast<VTK_TT*>(input), output,
586 numberOfValues, inputIncrement, outputFormat);
590 vtkErrorMacro(
"Cannot comput magnitude of bit array.");
593 vtkErrorMacro(<<
"MapImageThroughTable: Unknown input ScalarType");
597 switch (inputDataType)
602 vtkBitArray* bitArray = vtkBitArray::New();
603 bitArray->SetVoidArray(input, numberOfValues, 1);
604 vtkUnsignedCharArray* newInput = vtkUnsignedCharArray::New();
605 newInput->SetNumberOfValues(numberOfValues);
606 for (
id = i = 0; i < numberOfValues; i++,
id += inputIncrement)
608 newInput->SetValue(i, static_cast<vtkUnsignedCharArray::ValueType>(bitArray->GetValue(
id)));
610 fwVtkWindowLevelLookupTableMapData(
this,
611 static_cast<unsigned char*>(newInput->GetPointer(0)),
612 output, numberOfValues,
613 inputIncrement, outputFormat);
620 fwVtkWindowLevelLookupTableMapData(
this, static_cast<VTK_TT*>(input), output,
621 numberOfValues, inputIncrement, outputFormat)
624 vtkErrorMacro(<<
"MapImageThroughTable: Unknown input ScalarType");
Reinplementation of vtkWindowLevelLookupTable : add specific out-of-bounds colors.