#include "gdcm_zlib.h"
struct hframe
{
uint32_t val0;
uint16_t val1[2];
uint16_t val2[2];
uint32_t imgsize;
{
return val0 == h.val0 &&
val1[0] == h.val1[0] &&
val1[1] == h.val1[1] &&
val2[0] == h.val2[0] &&
val2[1] == h.val2[1] &&
imgsize == h.imgsize;
}
};
static bool ProcessDeflate( const char *outfilename, const int nslices, const
int buf_size, const char *buf, const size_t len,
const char *crcbuf, const size_t crclen )
{
std::vector< hframe > crcheaders;
crcheaders.reserve( nslices );
{
std::istringstream is;
is.str( std::string( crcbuf, crclen ) );
hframe header;
for( int r = 0; r < nslices; ++r )
{
is.read( (char*)&header, sizeof( header ));
#if 0
std::cout << header.val0
<< " " << header.val1[0]
<< " " << header.val1[1]
<< " " << header.val2[0]
<< " " << header.val2[1]
<< " " << header.imgsize << std::endl;
#endif
crcheaders.push_back( header );
}
}
std::istringstream is;
is.str( std::string( buf, len ) );
uint32_t totalsize;
is.read( (char*)&totalsize, sizeof( totalsize ));
assert( totalsize == len );
uint32_t nframes;
is.read( (char*)&nframes, sizeof( nframes ));
assert( nframes == (uint32_t)nslices );
std::vector< uint32_t > offsets;
offsets.reserve( nframes );
for( uint32_t frame = 0; frame < nframes ; ++frame )
{
uint32_t offset;
is.read( (char*)&offset, sizeof( offset ));
offsets.push_back( offset );
}
std::vector<char> outbuf;
const int size[2] = { 608, 427 };
std::stringstream ss;
ss << outfilename;
ss << '_';
ss << size[0];
ss << '_';
ss << size[1];
ss << '_';
ss << nframes;
ss << ".raw";
std::ofstream os( ss.str().c_str(), std::ios::binary );
assert( buf_size >= size[0] * size[1] );
outbuf.resize( buf_size );
hframe header;
for( unsigned int r = 0; r < nframes; ++r )
{
is.read( (char*)&header, sizeof( header ));
assert( header == crcheaders[r] );
assert( header.val1[0] == 2000 );
assert( header.val1[1] == 3 );
assert( header.val2[0] == 1 );
assert( header.val2[1] == 1280 );
uLongf destLen = buf_size;
Bytef *dest = (Bytef*)&outbuf[0];
assert( is.tellg() == offsets[r] + 16 );
const Bytef *source = (Bytef*)buf + offsets[r] + 16;
uLong sourceLen;
if( r + 1 == nframes )
sourceLen = totalsize - offsets[r] - 16;
else
sourceLen = offsets[r+1] - offsets[r] - 16;
int ret = uncompress (dest, &destLen, source, sourceLen);
assert( ret == Z_OK );
assert( destLen >= (uLongf)size[0] * size[1] );
assert( header.imgsize == (uint32_t)size[0] * size[1] );
os.write( &outbuf[0], size[0] * size[1] );
is.seekg( sourceLen, std::ios::cur );
}
os.close();
assert( is.tellg() == totalsize );
return true;
}
static bool ProcessNone( const char *outfilename, const int nslices, const
int buf_size, const char *buf, const size_t len,
const char *crcbuf, const size_t crclen )
{
std::vector< hframe > crcheaders;
crcheaders.reserve( nslices );
{
std::istringstream is;
is.str( std::string( crcbuf, crclen ) );
hframe header;
for( int r = 0; r < nslices; ++r )
{
is.read( (char*)&header, sizeof( header ));
#if 0
std::cout << header.val0
<< " " << header.val1[0]
<< " " << header.val1[1]
<< " " << header.val2[0]
<< " " << header.val2[1]
<< " " << header.imgsize << std::endl;
#endif
crcheaders.push_back( header );
}
}
std::istringstream is;
is.str( std::string( buf, len ) );
uint32_t totalsize;
is.read( (char*)&totalsize, sizeof( totalsize ));
assert( totalsize == len );
uint32_t nframes;
is.read( (char*)&nframes, sizeof( nframes ));
assert( nframes == (uint32_t)nslices );
std::vector< uint32_t > offsets;
offsets.reserve( nframes );
for( uint32_t frame = 0; frame < nframes ; ++frame )
{
uint32_t offset;
is.read( (char*)&offset, sizeof( offset ));
offsets.push_back( offset );
}
std::vector<char> outbuf;
std::stringstream ss;
ss << outfilename;
ss << '_';
ss << crcheaders[0].imgsize;
ss << '_';
ss << nframes;
ss << ".raw";
std::ofstream os( ss.str().c_str(), std::ios::binary );
outbuf.resize( buf_size );
char *buffer = &outbuf[0];
hframe header;
for( unsigned int r = 0; r < nframes; ++r )
{
is.read( (char*)&header, sizeof( header ));
#if 0
std::cout << header.val0
<< " " << header.val1[0]
<< " " << header.val1[1]
<< " " << header.val2[0]
<< " " << header.val2[1]
<< " " << header.imgsize << std::endl;
#endif
assert( header == crcheaders[r] );
is.read( buffer, buf_size - 16 );
os.write( buffer, header.imgsize );
}
assert( is.tellg() == totalsize );
os.close();
return true;
}
static const char * const UDM_USD_DATATYPE_STRINGS[] = {
"UDM_USD_DATATYPE_DIN_2D_ECHO",
"UDM_USD_DATATYPE_DIN_2D_ECHO_CONTRAST",
"UDM_USD_DATATYPE_DIN_DOPPLER_CW",
"UDM_USD_DATATYPE_DIN_DOPPLER_PW",
"UDM_USD_DATATYPE_DIN_DOPPLER_PW_TDI",
"UDM_USD_DATATYPE_DIN_2D_COLOR_FLOW",
"UDM_USD_DATATYPE_DIN_2D_COLOR_PMI",
"UDM_USD_DATATYPE_DIN_2D_COLOR_CPA",
"UDM_USD_DATATYPE_DIN_2D_COLOR_TDI",
"UDM_USD_DATATYPE_DIN_MMODE_ECHO",
"UDM_USD_DATATYPE_DIN_MMODE_COLOR",
"UDM_USD_DATATYPE_DIN_MMODE_COLOR_TDI",
"UDM_USD_DATATYPE_DIN_PARAM_BLOCK",
"UDM_USD_DATATYPE_DIN_2D_COLOR_VELOCITY",
"UDM_USD_DATATYPE_DIN_2D_COLOR_POWER",
"UDM_USD_DATATYPE_DIN_2D_COLOR_VARIANCE",
"UDM_USD_DATATYPE_DIN_DOPPLER_AUDIO",
"UDM_USD_DATATYPE_DIN_DOPPLER_HIGHQ",
"UDM_USD_DATATYPE_DIN_PHYSIO",
"UDM_USD_DATATYPE_DIN_2D_COLOR_STRAIN",
"UDM_USD_DATATYPE_DIN_COMPOSITE_RGB",
"UDM_USD_DATATYPE_DIN_XFOV_REALTIME_GRAPHICS",
"UDM_USD_DATATYPE_DIN_XFOV_MOSAIC",
"UDM_USD_DATATYPE_DIN_COMPOSITE_R",
"UDM_USD_DATATYPE_DIN_COMPOSITE_G",
"UDM_USD_DATATYPE_DIN_COMPOSITE_B",
"UDM_USD_DATATYPE_DIN_MMODE_COLOR_VELOCITY",
"UDM_USD_DATATYPE_DIN_MMODE_COLOR_POWER",
"UDM_USD_DATATYPE_DIN_MMODE_COLOR_VARIANCE",
"UDM_USD_DATATYPE_DIN_2D_ELASTO",
};
static inline bool is_valid( const char * datatype_str )
{
static const int n = sizeof( UDM_USD_DATATYPE_STRINGS ) / sizeof( *UDM_USD_DATATYPE_STRINGS );
bool found = false;
if( datatype_str )
{
for( int i = 0; !found && i < n; ++i )
{
found = strcmp( datatype_str, UDM_USD_DATATYPE_STRINGS[i] ) == 0;
}
}
return found;
}
int main(int argc, char *argv[])
{
if( argc < 2 ) return 1;
using namespace gdcm;
const char *filename = argv[1];
if( !reader.Read() ) return 1;
const PrivateTag tseq1(0x200d,0x3cf8,
"Philips US Imaging DD 045");
if( !ds1.FindDataElement( tseq1 ) ) return 1;
assert( sqi1->GetNumberOfItems() >= 1 );
const int nitems = sqi1->GetNumberOfItems();
for( int item = 1; item < nitems; ++item )
{
Item &item1 = sqi1->GetItem(item);
const PrivateTag tdatatype(0x200d,0x300d,
"Philips US Imaging DD 033");
if( !bvdatatype ) return 1;
const PrivateTag tseq2(0x200d,0x3cf1,
"Philips US Imaging DD 045");
DataSet &ds3 = item2.GetNestedDataSet();
const PrivateTag tzlib(0x200d,0x3cfa,
"Philips US Imaging DD 045");
if( !bv ) return 1;
const PrivateTag tnslices(0x200d,0x3010,
"Philips US Imaging DD 033");
const int nslicesref = elnslices.
GetValue();
assert( nslicesref >= 0 );
const PrivateTag tzalloc(0x200d,0x3011,
"Philips US Imaging DD 033");
const int zallocref = elzalloc.
GetValue();
assert( zallocref >= 0 );
const PrivateTag tzero(0x200d,0x3021,
"Philips US Imaging DD 033");
assert( zerocref == 0 );
const PrivateTag tdeflate(0x200d,0x3cf3,
"Philips US Imaging DD 045");
const PrivateTag tcrc(0x200d,0x3cfb,
"Philips US Imaging DD 045");
outfile = LOComp::Trim( outfile.c_str() );
const char *outfilename = outfile.c_str();
assert( is_valid(outfilename) );
if( bv2 )
{
assert( bv3 );
assert( zallocref > 0 );
assert( nslicesref > 0 );
std::cout << ds2 << std::endl;
{
if( !ProcessDeflate( outfilename, nslicesref, zallocref, bv2->
GetPointer(),
{
return 1;
}
}
else if( strncmp(bv->
GetPointer(),
"None", 4) == 0 )
{
if( !ProcessNone( outfilename, nslicesref, zallocref, bv2->
GetPointer(),
{
return 1;
}
}
else
{
std::cerr << "Unhandled: " << str << std::endl;
return 1;
}
}
}
return 0;
}