/*========================================================================= 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. =========================================================================*/ #include "gdcmRescaler.h" #include #include // atof static bool check_roundtrip(const gdcm::PixelFormat & pf ) { gdcm::Rescaler r; r.SetIntercept( 0. ); r.SetSlope( 1. ); r.SetPixelFormat( pf ); r.SetMinMaxForPixelType((double)pf.GetMin(),(double)pf.GetMax()); const gdcm::PixelFormat outputpt = r.ComputePixelTypeFromMinMax(); if( outputpt != pf ) return false; return true; } int TestRescaler1(int, char *[]) { gdcm::Rescaler ir; /* gdcmData/MR-MONO2-12-shoulder.dcm (gdb) p intercept $1 = 6.0999999999999999e-05 (gdb) p slope $2 = 3.774114 (gdb) p in[i] $3 = 3.77417493 ... p (in[i] - intercept)/slope $7 = 0.99999998109891775 $10 = {Intercept = 6.0999999999999999e-05, Slope = 3.774114, PF = {SamplesPerPixel = 1, BitsAllocated = 32, BitsStored = 32, HighBit = 31, PixelRepresentation = 3}, ScalarRangeMin = 6.0999998822808266e-05, ScalarRangeMax = 247336.561051} */ // (0028,1052) DS [0.000061] # 8, 1 RescaleIntercept // (0028,1053) DS [3.774114] # 8, 1 RescaleSlope const double intercept = atof( "0.000061" ); const double slope = atof( "3.774114" ); ir.SetIntercept( intercept ); ir.SetSlope( slope ); ir.SetPixelFormat( gdcm::PixelFormat::FLOAT64 ); const double smin = 6.0999998822808266e-05; const double smax = 247336.561051; ir.SetMinMaxForPixelType( smin, smax ); double outref[] = { 0 }; { char *copy = (char*)outref; const uint16_t in[] = { 1 }; const char *tempimage = (const char*)in; size_t vtklen = sizeof(in); ir.SetPixelFormat( gdcm::PixelFormat::UINT16 ); bool b = ir.Rescale(copy,tempimage,vtklen); if( !b ) return 1; std::cout << outref[0] << std::endl; } ir.SetPixelFormat( gdcm::PixelFormat::FLOAT64 ); uint16_t out[] = { 0 }; char *copy = (char*)out; //const double in[] = { 3.77417493 }; const double in[] = { 3.774175 }; if( outref[0] != in[0] ) { std::cerr << "Wrong input/output:" << std::endl; std::cerr << outref[0] << " vs " << in[0] << std::endl; std::cerr << (outref[0] - in[0]) << std::endl; return 1; } const char *tempimage = (const char*)in; size_t vtklen = sizeof(in); ir.InverseRescale(copy,tempimage,vtklen); std::cout << out[0] << std::endl; if( out[0] != 1 ) { return 1; } // Let's make sure that rescaler works in the simplest case // it should be idempotent: { gdcm::PixelFormat pixeltype = gdcm::PixelFormat::INT16; gdcm::Rescaler r; r.SetIntercept( 0.0 ); r.SetSlope( 1.0 ); r.SetPixelFormat( pixeltype ); gdcm::PixelFormat::ScalarType outputpt; outputpt = r.ComputeInterceptSlopePixelType(); if( outputpt != pixeltype ) { return 1; } if( ! (outputpt == pixeltype) ) { return 1; } } { gdcm::PixelFormat::ScalarType outputpt ; double shift = -1024; double scale = 1; // gdcmData/CT-MONO2-16-ort.dcm gdcm::PixelFormat pixeltype( 1, 16, 16, 15, 1 ); gdcm::Rescaler r; r.SetIntercept( shift ); r.SetSlope( scale ); r.SetPixelFormat( pixeltype ); outputpt = r.ComputeInterceptSlopePixelType(); // min,max = [-33792, 31743] // we need at least int32 to store that if( outputpt != gdcm::PixelFormat::INT32 ) { return 1; } // let's pretend image is really the full range: // FIXME: I think it is ok to compute this way since shift is double anyway: r.SetMinMaxForPixelType(std::numeric_limits::min() + shift,std::numeric_limits::max() + shift ); gdcm::PixelFormat pf2 = r.ComputePixelTypeFromMinMax(); if( pf2 != pixeltype ) { return 1; } } // ComputePixelTypeFromMinMax() { if( !check_roundtrip(gdcm::PixelFormat(1,16,12,11,0) ) ) return 1; if( !check_roundtrip(gdcm::PixelFormat(1,16,12,11,1) ) ) return 1; if( !check_roundtrip(gdcm::PixelFormat(1,8,8,7,0) ) ) return 1; if( !check_roundtrip(gdcm::PixelFormat(1,8,8,7,1) ) ) return 1; } return 0; }