/*========================================================================= Program: GDCM (Grassroots DICOM). A DICOM library Copyright (c) 2006-2011 Mathieu Malaterre All rights reserved. See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /*========================================================================= Portions of this file are subject to the VTK Toolkit Version 3 copyright. Program: Visualization Toolkit Module: $RCSfile: vtkLookupTable16.cxx,v $ Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkLookupTable16.h" #include "vtkObjectFactory.h" #include //vtkCxxRevisionMacro(vtkLookupTable16, "$Revision: 1.107 $") vtkStandardNewMacro(vtkLookupTable16) vtkLookupTable16::vtkLookupTable16(int sze, int ext) : vtkLookupTable(sze, ext) { this->Table16 = vtkUnsignedShortArray::New(); this->Table16->Register(this); this->Table16->Delete(); this->Table16->SetNumberOfComponents(4); this->Table16->Allocate(4*sze,4*ext); } //---------------------------------------------------------------------------- vtkLookupTable16::~vtkLookupTable16() { this->Table16->UnRegister(this); this->Table16 = NULL; } void vtkLookupTable16::Build() { } void vtkLookupTable16::SetNumberOfTableValues(vtkIdType number) { if (this->NumberOfColors == number) { return; } this->Modified(); this->NumberOfColors = number; this->Table16->SetNumberOfTuples(number); } //---------------------------------------------------------------------------- // Apply shift/scale to the scalar value v and do table lookup. inline unsigned short *vtkLinearLookup16(double v, unsigned short *table, double maxIndex, double shift, double scale) { double findx = (v + shift)*scale; if (findx < 0) { findx = 0; } if (findx > maxIndex) { findx = maxIndex; } return &table[4*static_cast(findx)]; /* round return &table[4*(int)(findx + 0.5f)]; */ } void vtkLookupTableLogRange16(double [2], double [2]) { assert(0); } inline double vtkApplyLogScale16(double , double [2], double [2]) { assert(0); return 0; } template void vtkLookupTable16MapData(vtkLookupTable16 *self, T *input, unsigned short *output, int length, int inIncr, int outFormat) { int i = length; double *range = self->GetTableRange(); double maxIndex = (double)self->GetNumberOfColors() - 1; double shift, scale; unsigned short *table = self->GetPointer(0); unsigned short *cptr; double alpha; if ( (alpha=self->GetAlpha()) >= 1.0 ) //no blending required { if (self->GetScale() == VTK_SCALE_LOG10) { double val; double logRange[2]; vtkLookupTableLogRange16(range, logRange); shift = -logRange[0]; if (logRange[1] <= logRange[0]) { scale = VTK_DOUBLE_MAX; } else { /* while this looks like the wrong scale, it is the correct scale * taking into account the truncation to int that happens below. */ scale = (maxIndex + 1)/(logRange[1] - logRange[0]); } if (outFormat == VTK_RGBA) { while (--i >= 0) { val = vtkApplyLogScale16((double)*input, range, logRange); cptr = vtkLinearLookup16(val, table, maxIndex, shift, scale); *output++ = *cptr++; *output++ = *cptr++; *output++ = *cptr++; *output++ = *cptr++; input += inIncr; } } else if (outFormat == VTK_RGB) { while (--i >= 0) { val = vtkApplyLogScale16((double)*input, range, logRange); cptr = vtkLinearLookup16(val, table, maxIndex, shift, scale); *output++ = *cptr++; *output++ = *cptr++; *output++ = *cptr++; input += inIncr; } } else if (outFormat == VTK_LUMINANCE_ALPHA) { while (--i >= 0) { val = vtkApplyLogScale16((double)*input, range, logRange); cptr = vtkLinearLookup16(val, table, maxIndex, shift, scale); *output++ = static_cast(cptr[0]*0.30 + cptr[1]*0.59 + cptr[2]*0.11 + 0.5); *output++ = cptr[3]; input += inIncr; } } else // outFormat == VTK_LUMINANCE { while (--i >= 0) { val = vtkApplyLogScale16((double)*input, range, logRange); cptr = vtkLinearLookup16(val, table, maxIndex, shift, scale); *output++ = static_cast(cptr[0]*0.30 + cptr[1]*0.59 + cptr[2]*0.11 + 0.5); input += inIncr; } } }//if log scale else //not log scale { shift = -range[0]; if (range[1] <= range[0]) { scale = VTK_DOUBLE_MAX; } else { /* while this looks like the wrong scale, it is the correct scale * taking into account the truncation to int that happens below. */ scale = (maxIndex + 1)/(range[1] - range[0]); } if (outFormat == VTK_RGBA) { while (--i >= 0) { cptr = vtkLinearLookup16((double)*input, table, maxIndex, shift, scale); *output++ = *cptr++; *output++ = *cptr++; *output++ = *cptr++; *output++ = *cptr++; input += inIncr; } } else if (outFormat == VTK_RGB) { while (--i >= 0) { cptr = vtkLinearLookup16((double)*input, table, maxIndex, shift, scale); *output++ = *cptr++; *output++ = *cptr++; *output++ = *cptr++; input += inIncr; } } else if (outFormat == VTK_LUMINANCE_ALPHA) { while (--i >= 0) { cptr = vtkLinearLookup16((double)*input, table, maxIndex, shift, scale); *output++ = static_cast(cptr[0]*0.30 + cptr[1]*0.59 + cptr[2]*0.11 + 0.5); *output++ = cptr[3]; input += inIncr; } } else // outFormat == VTK_LUMINANCE { while (--i >= 0) { cptr = vtkLinearLookup16((double)*input, table, maxIndex, shift, scale); *output++ = static_cast(cptr[0]*0.30 + cptr[1]*0.59 + cptr[2]*0.11 + 0.5); input += inIncr; } } }//if not log lookup }//if blending not needed else //blend with the specified alpha { if (self->GetScale() == VTK_SCALE_LOG10) { double val; double logRange[2]; vtkLookupTableLogRange16(range, logRange); shift = -logRange[0]; if (logRange[1] <= logRange[0]) { scale = VTK_DOUBLE_MAX; } else { /* while this looks like the wrong scale, it is the correct scale * taking into account the truncation to int that happens below. */ scale = (maxIndex + 1)/(logRange[1] - logRange[0]); } if (outFormat == VTK_RGBA) { while (--i >= 0) { val = vtkApplyLogScale16((double)*input, range, logRange); cptr = vtkLinearLookup16(val, table, maxIndex, shift, scale); *output++ = *cptr++; *output++ = *cptr++; *output++ = *cptr++; *output++ = static_cast((*cptr)*alpha); cptr++; input += inIncr; } } else if (outFormat == VTK_RGB) { while (--i >= 0) { val = vtkApplyLogScale16((double)*input, range, logRange); cptr = vtkLinearLookup16(val, table, maxIndex, shift, scale); *output++ = *cptr++; *output++ = *cptr++; *output++ = *cptr++; input += inIncr; } } else if (outFormat == VTK_LUMINANCE_ALPHA) { while (--i >= 0) { val = vtkApplyLogScale16((double)*input, range, logRange); cptr = vtkLinearLookup16(val, table, maxIndex, shift, scale); *output++ = static_cast(cptr[0]*0.30 + cptr[1]*0.59 + cptr[2]*0.11 + 0.5); *output++ = static_cast(alpha*cptr[3]); input += inIncr; } } else // outFormat == VTK_LUMINANCE { while (--i >= 0) { val = vtkApplyLogScale16((double)*input, range, logRange); cptr = vtkLinearLookup16(val, table, maxIndex, shift, scale); *output++ = static_cast(cptr[0]*0.30 + cptr[1]*0.59 + cptr[2]*0.11 + 0.5); input += inIncr; } } }//log scale with blending else //no log scale with blending { shift = -range[0]; if (range[1] <= range[0]) { scale = VTK_DOUBLE_MAX; } else { /* while this looks like the wrong scale, it is the correct scale * taking into account the truncation to int that happens below. */ scale = (maxIndex + 1)/(range[1] - range[0]); } if (outFormat == VTK_RGBA) { while (--i >= 0) { cptr = vtkLinearLookup16((double)*input, table, maxIndex, shift, scale); *output++ = *cptr++; *output++ = *cptr++; *output++ = *cptr++; *output++ = static_cast((*cptr)*alpha); cptr++; input += inIncr; } } else if (outFormat == VTK_RGB) { while (--i >= 0) { cptr = vtkLinearLookup16((double)*input, table, maxIndex, shift, scale); *output++ = *cptr++; *output++ = *cptr++; *output++ = *cptr++; input += inIncr; } } else if (outFormat == VTK_LUMINANCE_ALPHA) { while (--i >= 0) { cptr = vtkLinearLookup16((double)*input, table, maxIndex, shift, scale); *output++ = static_cast(cptr[0]*0.30 + cptr[1]*0.59 + cptr[2]*0.11 + 0.5); *output++ = static_cast(cptr[3]*alpha); input += inIncr; } } else // outFormat == VTK_LUMINANCE { while (--i >= 0) { cptr = vtkLinearLookup16((double)*input, table, maxIndex, shift, scale); *output++ = static_cast(cptr[0]*0.30 + cptr[1]*0.59 + cptr[2]*0.11 + 0.5); input += inIncr; } } }//no log scale }//alpha blending } //---------------------------------------------------------------------------- void vtkLookupTable16::MapScalarsThroughTable2(void *input, unsigned char *output, int inputDataType, int numberOfValues, int inputIncrement, int outputFormat) { if (this->UseMagnitude && inputIncrement > 1) { assert(0); // switch (inputDataType) // { // vtkTemplateMacro( // vtkLookupTableMapMag(this,static_cast(input),(unsigned short*)output, // numberOfValues,inputIncrement,outputFormat); // return // ); // case VTK_BIT: // vtkErrorMacro("Cannot comput magnitude of bit array."); // break; // default: // vtkErrorMacro(<< "MapImageThroughTable: Unknown input ScalarType"); // } } switch (inputDataType) { case VTK_BIT: { assert(0); //vtkIdType i, id; //vtkBitArray *bitArray = vtkBitArray::New(); //bitArray->SetVoidArray(input,numberOfValues,1); //vtkUnsignedCharArray *newInput = vtkUnsignedCharArray::New(); //newInput->SetNumberOfValues(numberOfValues); //for (id=i=0; iSetValue(i, bitArray->GetValue(id)); // } //vtkLookupTableMapData(this, // static_cast(newInput->GetPointer(0)), // output,numberOfValues, // inputIncrement,outputFormat); //newInput->Delete(); //bitArray->Delete(); } break; vtkTemplateMacro( vtkLookupTable16MapData(this,static_cast(input),(unsigned short*)output, numberOfValues,inputIncrement,outputFormat) ); default: vtkErrorMacro(<< "MapImageThroughTable: Unknown input ScalarType"); return; } } void vtkLookupTable16::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os,indent); }