#include "gdcmIconImageGenerator.h"
#include "gdcmIconImage.h"
#include "gdcmAttribute.h"
#include "gdcmPrivateTag.h"
#include "gdcmImage.h"
#include "gdcmJPEGCodec.h"
#include "gdcmRescaler.h"
#include <list>
#include <limits>
#include <queue>
#include <algorithm>
namespace gdcm
{
class IconImageGeneratorInternals
{
public:
IconImageGeneratorInternals()
{
dims[0] = dims[1] = 0;
Min = 0;
Max = 0;
UseMinMax = false;
AutoMinMax = false;
ConvertRGBToPaletteColor = true;
UseOutsideValuePixel = false;
OutsideValuePixel = 0;
}
unsigned int dims[2];
double Min;
double Max;
bool UseMinMax;
bool AutoMinMax;
bool ConvertRGBToPaletteColor;
bool UseOutsideValuePixel;
double OutsideValuePixel;
};
IconImageGenerator::IconImageGenerator():P(new Pixmap),I(new IconImage),Internals(new IconImageGeneratorInternals)
{
}
IconImageGenerator::~IconImageGenerator()
{
delete Internals;
}
void IconImageGenerator::ConvertRGBToPaletteColor(bool b)
{
Internals->ConvertRGBToPaletteColor = b;
}
void IconImageGenerator::SetOutputDimensions(const unsigned int dims[2])
{
Internals->dims[0] = dims[0];
Internals->dims[1] = dims[1];
}
namespace quantization
{
const int NUM_DIMENSIONS = 3;
struct Point
{
unsigned char x[NUM_DIMENSIONS];
};
class Block
{
Point minCorner, maxCorner;
Point* points;
int pointsLength;
public:
Block(Point* points, std::ptrdiff_t pointsLength);
Point * getPoints();
int numPoints() const;
int longestSideIndex() const;
int longestSideLength() const;
bool operator<(const Block& rhs) const;
void shrink();
};
template <int index>
class CoordinatePointComparator
{
public:
bool operator()(Point left, Point right)
{
return left.x[index] < right.x[index];
}
};
Block::Block(Point* pts, std::ptrdiff_t ptslen)
{
gdcm_assert( ptslen > 0 );
this->points = pts;
this->pointsLength = (int)ptslen;
for(int i=0; i < NUM_DIMENSIONS; i++)
{
minCorner.x[i] = std::numeric_limits<unsigned char>::min();
maxCorner.x[i] = std::numeric_limits<unsigned char>::max();
}
}
Point * Block::getPoints()
{
return points;
}
int Block::numPoints() const
{
return pointsLength;
}
int Block::longestSideIndex() const
{
int m = maxCorner.x[0] - minCorner.x[0];
int maxIndex = 0;
for(int i=1; i < NUM_DIMENSIONS; i++)
{
int diff = maxCorner.x[i] - minCorner.x[i];
if (diff > m)
{
m = diff;
maxIndex = i;
}
}
return maxIndex;
}
int Block::longestSideLength() const
{
int i = longestSideIndex();
return maxCorner.x[i] - minCorner.x[i];
}
bool Block::operator<(const Block& rhs) const
{
return this->longestSideLength() < rhs.longestSideLength();
}
void Block::shrink()
{
int i,j;
for(j=0; j<NUM_DIMENSIONS; j++)
{
minCorner.x[j] = maxCorner.x[j] = points[0].x[j];
}
for(i=1; i < pointsLength; i++)
{
for(j=0; j<NUM_DIMENSIONS; j++)
{
minCorner.x[j] = std::min(minCorner.x[j], points[i].x[j]);
maxCorner.x[j] = std::max(maxCorner.x[j], points[i].x[j]);
}
}
}
std::list<Point> medianCut(DataElement const &PixelData, int numPoints, unsigned int desiredSize,
std::vector<unsigned char> & outputimage )
{
gdcm_assert( numPoints > 0 );
Point* Points = new Point[numPoints];
gdcm_assert( Points );
const ByteValue *bv = PixelData.GetByteValue();
gdcm_assert( bv );
const unsigned char *inbuffer = (const unsigned char*)bv->GetPointer();
gdcm_assert( inbuffer );
size_t bvlen = bv->GetLength(); (void)bvlen;
gdcm_assert( bvlen == (size_t) numPoints * 3 ); for(int i = 0; i < numPoints; i++)
{
#if 0#else
Points[i].x[0] = inbuffer[ 3 * i + 0 ];
Points[i].x[1] = inbuffer[ 3 * i + 1 ];
Points[i].x[2] = inbuffer[ 3 * i + 2 ];
#endif
}
Point* image = Points;
std::priority_queue<Block> blockQueue;
Block initialBlock(image, numPoints);
initialBlock.shrink();
blockQueue.push(initialBlock);
while (blockQueue.size() < desiredSize )
{
Block longestBlock = blockQueue.top();
blockQueue.pop();
Point * begin = longestBlock.getPoints();
Point * median = longestBlock.getPoints() + (longestBlock.numPoints()+1)/2;
Point * end = longestBlock.getPoints() + longestBlock.numPoints();
switch(longestBlock.longestSideIndex())
{
case 0: std::nth_element(begin, median, end, CoordinatePointComparator<0>()); break;
case 1: std::nth_element(begin, median, end, CoordinatePointComparator<1>()); break;
case 2: std::nth_element(begin, median, end, CoordinatePointComparator<2>()); break;
}
Block block1(begin, median-begin), block2(median, end-median);
block1.shrink();
block2.shrink();
blockQueue.push(block1);
blockQueue.push(block2);
}
std::list<Point> result;
outputimage.resize( numPoints );
while(!blockQueue.empty())
{
Block block = blockQueue.top();
blockQueue.pop();
Point * points = block.getPoints();
int sum[NUM_DIMENSIONS] = {0,0,0};
for(int i=0; i < block.numPoints(); i++)
{
for(int j=0; j < NUM_DIMENSIONS; j++)
{
sum[j] += points[i].x[j];
}
}
Point averagePoint;
for(int j=0; j < NUM_DIMENSIONS; j++)
{
averagePoint.x[j] = sum[j] / block.numPoints();
}
result.push_back(averagePoint);
size_t index = result.size();
gdcm_assert( index <= 256 );
for(int i = 0; i < numPoints; i++)
{
const unsigned char *currentcolor = inbuffer + 3 * i;
for(size_t j = 0; j < (size_t)block.numPoints(); j++)
{
gdcm_assert( currentcolor < inbuffer + bvlen );
gdcm_assert( currentcolor + 3 <= inbuffer + bvlen );
if( std::equal( currentcolor, currentcolor + 3, points[j].x ) )
{
gdcm_assert( index > 0 );
outputimage[i] = (unsigned char)(index - 1);
}
}
}
}
delete[] Points;
return result;
}
}
void IconImageGenerator::BuildLUT( Bitmap & bitmap, unsigned int maxcolor )
{
gdcm_assert( Internals->ConvertRGBToPaletteColor );
using namespace quantization;
const unsigned int *dims = bitmap.GetDimensions();
unsigned int numPoints = dims[0]*dims[1];
std::vector<unsigned char> indeximage;
std::list<Point> palette =
medianCut(bitmap.GetDataElement(), numPoints, maxcolor, indeximage);
size_t ncolors = palette.size();
LookupTable & lut = bitmap.GetLUT();
lut.Clear();
lut.Allocate( 8 );
std::vector< unsigned char > buffer[3];
for( int i = 0; i < 3; ++i )
buffer[i].reserve( ncolors );
std::list<Point>::const_iterator it = palette.begin();
for( ; it != palette.end(); ++it )
{
Point const & p = *it;
for( int i = 0; i < 3; ++i )
buffer[i].push_back( p.x[i] );
}
for( int i = 0; i < 3; ++i )
{
lut.InitializeLUT( LookupTable::LookupTableType(i), (unsigned short)ncolors, 0, 8 );
lut.SetLUT( LookupTable::LookupTableType(i), buffer[i].data(), (unsigned short)ncolors );
}
bitmap.GetDataElement().SetByteValue( (char*)indeximage.data(), (uint32_t)indeximage.size() );
gdcm_assert( lut.Initialized() );
}
void IconImageGenerator::SetOutsideValuePixel(double v)
{
if( Internals->AutoMinMax )
{
Internals->UseOutsideValuePixel = true;
Internals->OutsideValuePixel = v;
}
}
void IconImageGenerator::AutoPixelMinMax(bool b)
{
if( b )
{
Internals->UseMinMax = false;
Internals->AutoMinMax = true;
}
}
void IconImageGenerator::SetPixelMinMax(double min, double max)
{
Internals->Min = min;
Internals->Max = max;
Internals->UseMinMax = true;
Internals->AutoMinMax = false;
}
template <typename TPixelType>
void ComputeMinMax( const TPixelType *p, size_t npixels , double & min, double &max, double discardvalue)
{
gdcm_assert( npixels );
const TPixelType discard = (TPixelType)discardvalue;
gdcm_assert( (double)discard == discardvalue );
TPixelType lmin = std::numeric_limits< TPixelType>::max();
TPixelType lmax = std::numeric_limits< TPixelType>::min();
for( size_t i = 0; i < npixels; ++i )
{
if( p[i] < lmin && p[i] != discard )
{
lmin = p[i];
}
else if( p[i] > lmax )
{
lmax = p[i];
}
}
if( lmin == lmax )
{
if( lmax == std::numeric_limits<TPixelType>::max() )
{
lmin--;
gdcm_assert( lmin + 1 > lmin );
}
else
{
lmax++;
}
}
min = lmin;
max = lmax;
}
template <typename TPixelType>
void ComputeMinMax( const TPixelType *p, size_t npixels , double & min, double &max)
{
gdcm_assert( npixels );
TPixelType lmin = std::numeric_limits< TPixelType>::max();
TPixelType lmax = std::numeric_limits< TPixelType>::min();
for( size_t i = 0; i < npixels; ++i )
{
if( p[i] < lmin )
{
lmin = p[i];
}
else if( p[i] > lmax )
{
lmax = p[i];
}
}
if( lmin == lmax )
{
if( lmax == std::numeric_limits<TPixelType>::max() )
{
lmin--;
gdcm_assert( lmin + 1 > lmin );
}
else
{
lmax++;
}
}
min = lmin;
max = lmax;
}
bool IconImageGenerator::Generate()
{
I->Clear();
I->SetNumberOfDimensions(2);
I->SetDimension(0, Internals->dims[0] );
I->SetDimension(1, Internals->dims[1] );
PixelFormat oripf = P->GetPixelFormat();
if( P->GetPhotometricInterpretation() != PhotometricInterpretation::MONOCHROME1
&& P->GetPhotometricInterpretation() != PhotometricInterpretation::MONOCHROME2
&& P->GetPhotometricInterpretation() != PhotometricInterpretation::PALETTE_COLOR
&& P->GetPhotometricInterpretation() != PhotometricInterpretation::RGB
&& P->GetPhotometricInterpretation() != PhotometricInterpretation::YBR_FULL
&& P->GetPhotometricInterpretation() != PhotometricInterpretation::YBR_FULL_422
&& P->GetPhotometricInterpretation() != PhotometricInterpretation::YBR_RCT
&& P->GetPhotometricInterpretation() != PhotometricInterpretation::YBR_ICT )
{
gdcmErrorMacro( "PhotometricInterpretation is not supported: "
<< P->GetPhotometricInterpretation() );
return false;
}
if( P->GetPhotometricInterpretation() == PhotometricInterpretation::RGB
|| P->GetPhotometricInterpretation() == PhotometricInterpretation::YBR_FULL
|| P->GetPhotometricInterpretation() == PhotometricInterpretation::YBR_FULL_422
|| P->GetPhotometricInterpretation() == PhotometricInterpretation::YBR_RCT
|| P->GetPhotometricInterpretation() == PhotometricInterpretation::YBR_ICT )
{
if( Internals->ConvertRGBToPaletteColor )
{
I->SetPhotometricInterpretation( PhotometricInterpretation::PALETTE_COLOR );
}
else
{
I->SetPhotometricInterpretation( PhotometricInterpretation::RGB );
}
}
else
{
I->SetPhotometricInterpretation( P->GetPhotometricInterpretation() );
gdcm_assert( I->GetPhotometricInterpretation() == PhotometricInterpretation::MONOCHROME1
|| I->GetPhotometricInterpretation() == PhotometricInterpretation::MONOCHROME2
|| I->GetPhotometricInterpretation() == PhotometricInterpretation::PALETTE_COLOR );
if( !Internals->ConvertRGBToPaletteColor
&& P->GetPhotometricInterpretation() == PhotometricInterpretation::PALETTE_COLOR )
{
I->SetPhotometricInterpretation( PhotometricInterpretation::RGB );
}
}
gdcm_assert( I->GetPlanarConfiguration() == 0 );
std::vector< char > vbuffer;
size_t framelen = P->GetBufferLength();
if( P->GetNumberOfDimensions() == 3 )
{
const unsigned int *dims = P->GetDimensions();
gdcm_assert( framelen % dims[2] == 0 );
framelen /= dims[2];
}
vbuffer.resize( P->GetBufferLength() );
char *buffer = vbuffer.data();
bool boolean = P->GetBuffer(buffer);
if( !boolean ) return false;
vbuffer.resize( framelen );
I->SetPixelFormat( P->GetPixelFormat() );
DataElement& pixeldata = I->GetDataElement();
std::vector< char > vbuffer2;
vbuffer2.resize( I->GetBufferLength() );
uint8_t ps = I->GetPixelFormat().GetPixelSize();
char *iconb = vbuffer2.data();
char *imgb = vbuffer.data();
const unsigned int *imgdims = P->GetDimensions();
const unsigned int stepi = imgdims[0] / Internals->dims[0];
const unsigned int stepj = imgdims[1] / Internals->dims[1];
for(unsigned int i = 0; i < Internals->dims[1]; ++i )
for(unsigned int j = 0; j < Internals->dims[0]; ++j )
{
gdcm_assert( (i * Internals->dims[0] + j) * ps < I->GetBufferLength() );
gdcm_assert( (i * imgdims[0] * stepj + j * stepi) * ps < framelen );
memcpy(iconb + (i * Internals->dims[0] + j) * ps,
imgb + (i * imgdims[0] * stepj + j * stepi) * ps, ps );
}
if( P->GetPhotometricInterpretation() == PhotometricInterpretation::PALETTE_COLOR )
{
std::string tempvbuf(vbuffer2.data(), vbuffer2.size());
std::istringstream is( tempvbuf );
std::stringstream ss;
P->GetLUT().Decode( is, ss );
if( I->GetPixelFormat().GetBitsAllocated() == 16 )
{
std::string s = ss.str();
Rescaler r;
r.SetPixelFormat( I->GetPixelFormat() );
const double min = 0; const double max = 65536 - 1; r.SetSlope( 255. / (max - min + 0) ); const double step = min * r.GetSlope();
r.SetIntercept( 0 - step );
gdcm_assert( r.GetIntercept() + r.GetSlope() * min == 0. );
gdcm_assert( r.GetIntercept() + r.GetSlope() * max == 255. );
r.SetTargetPixelType( PixelFormat::UINT8 );
r.SetUseTargetPixelType(true);
std::vector<char> v8;
v8.resize( Internals->dims[0] * Internals->dims[1] * 3 );
if( !r.Rescale(v8.data(),s.data(),s.size()) )
{
gdcm_assert( 0 ); gdcmErrorMacro( "Problem in the rescaler" );
return false;
}
if( Internals->ConvertRGBToPaletteColor )
{
LookupTable &lut = I->GetLUT();
lut.Allocate();
std::stringstream ss2;
ss2.str( std::string( v8.data(), v8.size() ) );
std::string s2 = ss2.str();
I->SetPixelFormat( PixelFormat::UINT8 );
pixeldata.SetByteValue( s2.data(), (uint32_t)s2.size() );
BuildLUT( *I, 256 );
}
else
{
I->SetPixelFormat( PixelFormat::UINT8 );
I->GetPixelFormat().SetSamplesPerPixel( 3 );
pixeldata.SetByteValue( v8.data(), (uint32_t)v8.size() );
}
}
else
{
gdcm_assert( I->GetPixelFormat() == PixelFormat::UINT8 );
std::string s = ss.str();
if( Internals->ConvertRGBToPaletteColor )
{
LookupTable &lut = I->GetLUT();
lut.Allocate();
I->SetPixelFormat( PixelFormat::UINT8 );
pixeldata.SetByteValue( s.data(), (uint32_t)s.size() );
BuildLUT(*I, 256 );
}
else
{
I->SetPixelFormat( PixelFormat::UINT8 );
I->GetPixelFormat().SetSamplesPerPixel( 3 );
pixeldata.SetByteValue( s.data(), (uint32_t)s.size() );
}
}
}
else if( P->GetPhotometricInterpretation() == PhotometricInterpretation::RGB
|| P->GetPhotometricInterpretation() == PhotometricInterpretation::YBR_FULL
|| P->GetPhotometricInterpretation() == PhotometricInterpretation::YBR_FULL_422
|| P->GetPhotometricInterpretation() == PhotometricInterpretation::YBR_ICT
|| P->GetPhotometricInterpretation() == PhotometricInterpretation::YBR_RCT )
{
std::string tempvbuf( vbuffer2.data(), vbuffer2.size() );
if( P->GetPhotometricInterpretation() == PhotometricInterpretation::YBR_FULL
|| P->GetPhotometricInterpretation() == PhotometricInterpretation::YBR_FULL_422 )
{
gdcm_assert( I->GetPixelFormat() == PixelFormat::UINT8 );
if( P->GetPlanarConfiguration() == 0 )
{
unsigned char *ybr = (unsigned char*)tempvbuf.data();
unsigned char *ybr_out = ybr;
unsigned char *ybr_end = ybr + vbuffer2.size();
int R, G, B;
for( ; ybr != ybr_end; )
{
unsigned char a = (unsigned char)(*ybr); ++ybr;
unsigned char b = (unsigned char)(*ybr); ++ybr;
unsigned char c = (unsigned char)(*ybr); ++ybr;
R = 38142 *(a-16) + 52298 *(c -128);
G = 38142 *(a-16) - 26640 *(c -128) - 12845 *(b -128);
B = 38142 *(a-16) + 66093 *(b -128);
R = (R+16384)>>15;
G = (G+16384)>>15;
B = (B+16384)>>15;
if (R < 0) R = 0;
if (G < 0) G = 0;
if (B < 0) B = 0;
if (R > 255) R = 255;
if (G > 255) G = 255;
if (B > 255) B = 255;
*ybr_out = (unsigned char)R; ++ybr_out;
*ybr_out = (unsigned char)G; ++ybr_out;
*ybr_out = (unsigned char)B; ++ybr_out;
}
#if 0#endif
gdcm_assert( ybr_out == ybr_end );
}
else {
std::string tempvbufybr = tempvbuf;
unsigned char *ybr = (unsigned char*)tempvbufybr.data();
unsigned char *ybr_end = ybr + vbuffer2.size();
gdcm_assert( vbuffer2.size() % 3 == 0 );
size_t ybrl = vbuffer2.size() / 3;
unsigned char *ybra = ybr + 0 * ybrl;
unsigned char *ybrb = ybr + 1 * ybrl;
unsigned char *ybrc = ybr + 2 * ybrl;
unsigned char *ybr_out = (unsigned char*)tempvbuf.data();
unsigned char *ybr_out_end = ybr_out + vbuffer2.size();
int R, G, B;
for( ; ybr_out != ybr_out_end; )
{
unsigned char a = (unsigned char)(*ybra); ++ybra;
unsigned char b = (unsigned char)(*ybrb); ++ybrb;
unsigned char c = (unsigned char)(*ybrc); ++ybrc;
R = 38142 *(a-16) + 52298 *(c -128);
G = 38142 *(a-16) - 26640 *(c -128) - 12845 *(b -128);
B = 38142 *(a-16) + 66093 *(b -128);
R = (R+16384)>>15;
G = (G+16384)>>15;
B = (B+16384)>>15;
if (R < 0) R = 0;
if (G < 0) G = 0;
if (B < 0) B = 0;
if (R > 255) R = 255;
if (G > 255) G = 255;
if (B > 255) B = 255;
*ybr_out = (unsigned char)R; ++ybr_out;
*ybr_out = (unsigned char)G; ++ybr_out;
*ybr_out = (unsigned char)B; ++ybr_out;
}
gdcm_assert( ybra + 2 * ybrl == ybr_end ); (void)ybr_end;
gdcm_assert( ybrb + 1 * ybrl == ybr_end );
gdcm_assert( ybrc + 0 * ybrl == ybr_end );
}
}
else
{
if( P->GetPlanarConfiguration() == 1 )
{
gdcm_assert( I->GetPixelFormat() == PixelFormat::UINT8 );
std::string tempvbufrgb = tempvbuf;
unsigned char *rgb = (unsigned char*)tempvbufrgb.data();
unsigned char *rgb_end = rgb + vbuffer2.size();
gdcm_assert( vbuffer2.size() % 3 == 0 );
size_t rgbl = vbuffer2.size() / 3;
unsigned char *rgba = rgb + 0 * rgbl;
unsigned char *rgbb = rgb + 1 * rgbl;
unsigned char *rgbc = rgb + 2 * rgbl;
unsigned char *rgb_out = (unsigned char*)tempvbuf.data();
unsigned char *rgb_out_end = rgb_out + vbuffer2.size();
for( ; rgb_out != rgb_out_end; )
{
unsigned char a = (unsigned char)(*rgba); ++rgba;
unsigned char b = (unsigned char)(*rgbb); ++rgbb;
unsigned char c = (unsigned char)(*rgbc); ++rgbc;
*rgb_out = a; ++rgb_out;
*rgb_out = b; ++rgb_out;
*rgb_out = c; ++rgb_out;
}
gdcm_assert( rgba + 2 * rgbl == rgb_end ); (void)rgb_end;
gdcm_assert( rgbb + 1 * rgbl == rgb_end );
gdcm_assert( rgbc + 0 * rgbl == rgb_end );
}
}
std::istringstream is( tempvbuf );
if( I->GetPixelFormat() == PixelFormat::UINT8 )
{
std::string s = is.str();
if( Internals->ConvertRGBToPaletteColor )
{
I->SetPixelFormat( PixelFormat::UINT8 );
pixeldata.SetByteValue( s.data(), (uint32_t)s.size() );
BuildLUT(*I, 256 );
}
else
{
I->SetPixelFormat( PixelFormat::UINT8 );
I->GetPixelFormat().SetSamplesPerPixel( 3 );
pixeldata.SetByteValue( s.data(), (uint32_t)s.size() );
}
}
else
{
gdcm_assert( I->GetPixelFormat() == PixelFormat::UINT16 );
gdcm_assert( I->GetPixelFormat().GetPixelRepresentation() == 0 );
std::string s = is.str();
Rescaler r;
r.SetPixelFormat( I->GetPixelFormat() );
const double min = 0; const double max = 65536 - 1; r.SetSlope( 255. / (max - min + 0) ); const double step = min * r.GetSlope();
r.SetIntercept( 0 - step );
gdcm_assert( r.GetIntercept() + r.GetSlope() * min == 0. );
gdcm_assert( r.GetIntercept() + r.GetSlope() * max == 255. );
r.SetTargetPixelType( PixelFormat::UINT8 );
r.SetUseTargetPixelType(true);
std::vector<char> v8;
v8.resize( Internals->dims[0] * Internals->dims[1] * 3 );
if( !r.Rescale(v8.data(),s.data(),s.size()) )
{
gdcm_assert( 0 ); gdcmErrorMacro( "Problem in the rescaler" );
return false;
}
if( Internals->ConvertRGBToPaletteColor )
{
LookupTable &lut = I->GetLUT();
lut.Allocate();
I->SetPixelFormat( PixelFormat::UINT8 );
pixeldata.SetByteValue( v8.data(), (uint32_t)v8.size() );
BuildLUT(*I, 256 );
}
else
{
I->SetPixelFormat( PixelFormat::UINT8 );
I->GetPixelFormat().SetSamplesPerPixel( 3 );
pixeldata.SetByteValue( v8.data(), (uint32_t)v8.size() );
}
}
}
else
{
char *buffer2 = vbuffer2.data();
pixeldata.SetByteValue( buffer2, (uint32_t)vbuffer2.size() );
Rescaler r;
r.SetPixelFormat( I->GetPixelFormat() );
double min = (double)oripf.GetMin();
double max = (double)oripf.GetMax();
if( Internals->UseMinMax )
{
min = Internals->Min;
max = Internals->Max;
}
if( Internals->AutoMinMax )
{
void *p = vbuffer2.data();
size_t len = vbuffer2.size();
const PixelFormat &pf = I->GetPixelFormat();
gdcm_assert( pf.GetSamplesPerPixel() == 1 );
if( Internals->UseOutsideValuePixel )
{
const double d = Internals->OutsideValuePixel;
switch ( pf.GetScalarType() )
{
case PixelFormat::UINT8:
ComputeMinMax<uint8_t>( (const uint8_t*)p, len / sizeof( uint8_t ), min, max, d);
break;
case PixelFormat::INT8:
ComputeMinMax<int8_t>( (const int8_t*)p, len / sizeof( int8_t ), min, max, d);
break;
case PixelFormat::UINT16:
ComputeMinMax<uint16_t>( (const uint16_t*)p, len / sizeof( uint16_t ), min, max, d);
break;
case PixelFormat::INT16:
ComputeMinMax<int16_t>( (const int16_t*)p, len / sizeof( int16_t ), min, max, d);
break;
default:
gdcm_assert( 0 ); break;
}
switch ( pf.GetScalarType() )
{
case PixelFormat::UINT8:
std::replace( (uint8_t*)p, (uint8_t*)p + len / sizeof( uint8_t ), (uint8_t)d, (uint8_t)min);
break;
case PixelFormat::INT8:
std::replace( (int8_t*)p, (int8_t*)p + len / sizeof( int8_t ), (int8_t)d, (int8_t)min);
break;
case PixelFormat::UINT16:
std::replace( (uint16_t*)p, (uint16_t*)p + len / sizeof( uint16_t ), (uint16_t)d, (uint16_t)min);
break;
case PixelFormat::INT16:
std::replace( (int16_t*)p, (int16_t*)p + len / sizeof( int16_t ), (int16_t)d, (int16_t)min);
break;
default:
gdcm_assert( 0 ); break;
}
}
switch ( pf.GetScalarType() )
{
case PixelFormat::UINT8:
ComputeMinMax<uint8_t>( (const uint8_t*)p, len / sizeof( uint8_t ), min, max);
break;
case PixelFormat::INT8:
ComputeMinMax<int8_t>( (const int8_t*)p, len / sizeof( int8_t ), min, max);
break;
case PixelFormat::UINT16:
ComputeMinMax<uint16_t>( (const uint16_t*)p, len / sizeof( uint16_t ), min, max);
break;
case PixelFormat::INT16:
ComputeMinMax<int16_t>( (const int16_t*)p, len / sizeof( int16_t ), min, max);
break;
default:
gdcm_assert( 0 ); break;
}
}
r.SetSlope( 255. / (max - min + 0) ); const double step = min * r.GetSlope();
r.SetIntercept( 0 - step );
gdcm_assert( (int)(0.5 + r.GetIntercept() + r.GetSlope() * min) == 0 );
gdcm_assert( (int)(0.5 + r.GetIntercept() + r.GetSlope() * max) == 255 );
r.SetTargetPixelType( PixelFormat::UINT8 );
r.SetUseTargetPixelType(true);
std::vector<char> v8;
v8.resize( Internals->dims[0] * Internals->dims[1] );
if( !r.Rescale(v8.data(),vbuffer2.data(),vbuffer2.size()) )
{
gdcm_assert( 0 ); gdcmErrorMacro( "Problem in the rescaler" );
return false;
}
I->SetPixelFormat( PixelFormat::UINT8 );
pixeldata.SetByteValue( v8.data(), (uint32_t)v8.size() );
}
if( !Internals->ConvertRGBToPaletteColor
&& I->GetPhotometricInterpretation() == PhotometricInterpretation::RGB )
{
gdcm_assert( I->GetPixelFormat().GetSamplesPerPixel() == 3 );
}
else
{
gdcm_assert( I->GetPixelFormat().GetSamplesPerPixel() == 1 );
}
gdcm_assert( I->GetPixelFormat().GetBitsAllocated() == 8 );
gdcm_assert( I->GetPixelFormat().GetBitsStored() == 8 );
gdcm_assert( I->GetPixelFormat().GetHighBit() == 7 );
gdcm_assert( I->GetPixelFormat().GetPixelRepresentation() == 0 );
return true;
}
}