| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 |
- #include "DicomIO.h"
- #include <dcmtk/config/osconfig.h>
- #include <dcmtk/dcmdata/dcfilefo.h>
- #include <dcmtk/dcmdata/dcdeftag.h>
- #include <dcmtk/dcmdata/dcstack.h>
- #include <dcmtk/dcmdata/dcpixel.h>
- #include <dcmtk/dcmdata/dcxfer.h>
- #include <dcmtk/dcmjpeg/djdecode.h>
- #include <dcmtk/dcmimgle/dcmimage.h>
- #include <dcmtk/dcmimage/diregist.h>
- #include <dcmtk/dcmdata/dcrledrg.h>
- #include <dcmtk/dcmdata/dcuid.h>
- #include <sstream>
- #include <cmath>
- DicomIO::DicomIO()
- : Singleton< DicomIO >(),
- m_calibrated( false )
- {
- DcmRLEDecoderRegistration::registerCodecs();
- DJDecoderRegistration::registerCodecs();
- }
- DicomIO::~DicomIO()
- {
- DJDecoderRegistration::cleanup();
- DcmRLEDecoderRegistration::cleanup();
- }
- DicomIO::DicomIOType DicomIO::getType( std::string fileName )
- {
- DcmFileFormat fileFormat;
- OFCondition status = fileFormat.loadFile( fileName.c_str() );
- if ( status.bad() )
- {
- return DicomIO::DicomIOUnknown;
- }
- DcmDataset* dataset = fileFormat.getDataset();
- OFString SOPClassUID;
- if ( dataset->findAndGetOFString( DCM_SOPClassUID, SOPClassUID ).bad() )
- {
- return DicomIO::DicomIOUnknown;
- }
- if ( !SOPClassUID.compare( UID_UltrasoundImageStorage ) ||
- !SOPClassUID.compare( UID_SecondaryCaptureImageStorage ) )
- {
- return DicomIO::DicomIOImage;
- }
- if ( !SOPClassUID.compare( UID_UltrasoundMultiframeImageStorage ) )
- {
- return DicomIO::DicomIOMultiFrame;
- }
- return DicomIO::DicomIOUnmanaged;
- }
- bool DicomIO::readResolutions( DcmDataset* dataset,
- double& sizeX,
- double& sizeY )
- {
- if ( !dataset )
- {
- return false;
- }
- int nScales = 0;
- Float64 tmpFD = 0.0;
- if ( dataset->findAndGetFloat64( DCM_PixelSpacing, tmpFD, 0 ).good() )
- {
- sizeX = (double)tmpFD;
- nScales++;
- }
-
- if ( dataset->findAndGetFloat64( DCM_PixelSpacing, tmpFD, 1 ).good() )
- {
- sizeY = (double)tmpFD;
- nScales++;
- }
- if ( nScales != 2 )
- {
- nScales = 0;
- OFString SOPClassUID;
- if ( dataset->findAndGetOFString( DCM_SOPClassUID, SOPClassUID ).bad() )
- {
- return false;
- }
- if ( !SOPClassUID.compare( UID_UltrasoundImageStorage ) ||
- !SOPClassUID.compare( UID_UltrasoundMultiframeImageStorage ) )
- {
- DcmSequenceOfItems* seq = NULL;
- if ( dataset->findAndGetSequence( DCM_SequenceOfUltrasoundRegions,
- seq ).good() )
- {
- Uint16 type;
- bool found = false;
- unsigned long i, nItems = seq->card();
- for ( i = 0; !found && ( i < nItems ); i++ )
- {
- DcmItem* item = seq->getItem( i );
- if ( item->findAndGetUint16( DCM_RegionSpatialFormat, type ).good() )
- {
- if ( ( type == 1 ) || ( type == 2 ) )
- {
- found = true;
- if ( item->findAndGetFloat64( DCM_PhysicalDeltaX, tmpFD ).good() )
- {
- sizeX = 10.0 * fabs( tmpFD );
- nScales++;
- }
-
- if ( item->findAndGetFloat64( DCM_PhysicalDeltaY, tmpFD ).good() )
- {
- sizeY = 10.0 * fabs( tmpFD );
- nScales++;
- }
- }
- }
- }
- }
- }
- }
- return ( nScales == 2 ) ? true : false;
- }
- bool DicomIO::read( std::string fileName, ExtendedImage& image )
- {
- DcmFileFormat fileFormat;
- OFCondition status = fileFormat.loadFile( fileName.c_str() );
- m_calibrated = false;
- if ( status.bad() )
- {
- return false;
- }
- DcmDataset* dataset = fileFormat.getDataset();
- double sizeX = -1.0, sizeY = -1.0;
- m_calibrated = readResolutions( dataset, sizeX, sizeY );
- E_TransferSyntax xfer = dataset->getOriginalXfer();
-
- /*** hack for Medison jpeg encoded images ***/
- OFString manufacturer;
- if ( dataset->findAndGetOFString( DCM_Manufacturer, manufacturer ).good() )
- {
- if ( !manufacturer.compare( "MEDISON" ) &&
- ( xfer >= EXS_JPEGProcess1TransferSyntax ) &&
- ( xfer <= EXS_JPEGProcess14SV1TransferSyntax ) )
- {
- dataset->putAndInsertString( DCM_PhotometricInterpretation, "YBR_FULL" );
- }
- }
- /*** end of hack ***/
- DicomImage dcmImage( dataset, xfer );
- if ( dcmImage.getStatus() != EIS_Normal )
- {
- return false;
- }
- dcmImage.setMinMaxWindow();
- if ( !image.IsNull() )
- {
- image.Destroy();
- }
- int w = dcmImage.getWidth();
- int h = dcmImage.getHeight();
- if ( !image.Create( w, h, 24 ) )
- {
- return false;
- }
-
- unsigned char* p = (unsigned char*)dcmImage.getOutputData( 8 );
- unsigned char* l = (unsigned char*)image.GetBuffer();
- int n = w * h;
-
- if ( dcmImage.isMonochrome() )
- {
- while ( n-- )
- {
- *l++ = *p;
- *l++ = *p;
- *l++ = *p++;
- }
- }
- else
- {
- while ( n-- )
- {
- *l++ = *( p + 2 );
- *l++ = *( p + 1 );
- *l++ = *p;
- p += 3;
- }
- }
- image.SetResolution( (double)sizeX, (double)sizeY );
- return true;
- }
- bool DicomIO::read( std::string fileName, Video& video )
- {
- DcmFileFormat fileFormat;
- OFCondition status = fileFormat.loadFile( fileName.c_str() );
- m_calibrated = false;
- if ( status.bad() )
- {
- return false;
- }
- DcmDataset* dataset = fileFormat.getDataset();
- double sizeX = -1.0, sizeY = -1.0;
- m_calibrated = readResolutions( dataset, sizeX, sizeY );
- E_TransferSyntax xfer = dataset->getOriginalXfer();
-
- /*** hack for Medison jpeg encoded images ***/
- OFString manufacturer;
- if ( dataset->findAndGetOFString( DCM_Manufacturer, manufacturer ).good() )
- {
- if ( !manufacturer.compare( "MEDISON" ) &&
- ( xfer >= EXS_JPEGProcess1TransferSyntax ) &&
- ( xfer <= EXS_JPEGProcess14SV1TransferSyntax ) )
- {
- dataset->putAndInsertString( DCM_PhotometricInterpretation, "YBR_FULL" );
- }
- }
- /*** end of hack ***/
- DicomImage dcmImage( dataset, xfer );
- if ( dcmImage.getStatus() != EIS_Normal )
- {
- return false;
- }
- dcmImage.setMinMaxWindow();
- if ( !video.IsNull() )
- {
- video.Clear();
- }
- unsigned long f, nf = dcmImage.getFrameCount();
- bool isMonochrome = dcmImage.isMonochrome() ? true : false;
- video.SetSize( dcmImage.getWidth(), dcmImage.getHeight() );
- for ( f = 0; f < nf; f++ )
- {
- unsigned char* p = (unsigned char*)dcmImage.getOutputData( 8 );
- video.AddFrame( p, isMonochrome );
- }
- video.SetResolution( (double)sizeX, (double)sizeY );
- return true;
- }
- bool DicomIO::write( std::string fileName, ExtendedImage &image )
- {
- char uid[ 100 ];
- DcmFileFormat fileFormat;
- DcmDataset* dataset = fileFormat.getDataset();
- // SOP common
- dataset->putAndInsertString( DCM_SOPClassUID,
- UID_SecondaryCaptureImageStorage );
- dataset->putAndInsertString( DCM_SOPInstanceUID,
- dcmGenerateUniqueIdentifier( uid,
- SITE_INSTANCE_UID_ROOT ) );
- // Patient
- dataset->insertEmptyElement( DCM_PatientsName );
- dataset->insertEmptyElement( DCM_PatientID );
- dataset->insertEmptyElement( DCM_PatientsBirthDate );
- dataset->insertEmptyElement( DCM_PatientsSex );
- // Study
- dataset->putAndInsertString( DCM_StudyInstanceUID,
- dcmGenerateUniqueIdentifier( uid,
- SITE_STUDY_UID_ROOT ));
- dataset->insertEmptyElement( DCM_StudyDate );
- dataset->insertEmptyElement( DCM_StudyTime );
- dataset->insertEmptyElement( DCM_ReferringPhysiciansName );
- // Series
- dataset->putAndInsertString( DCM_Modality, "US" );
- dataset->putAndInsertString( DCM_SeriesInstanceUID,
- dcmGenerateUniqueIdentifier( uid,
- SITE_SERIES_UID_ROOT ));
- dataset->insertEmptyElement( DCM_SeriesNumber );
- // Equipment
- dataset->putAndInsertString( DCM_ConversionType, "WSD" );
- // Image
- Uint16 spp = 3;
- Uint16 bitsAlloc = 8;
- Uint16 bitsStored = 8;
- Uint16 highBits = 7;
- std::string photometric( "RGB" );
- switch ( image.GetBpp() )
- {
- case 8:
- spp = 1;
- bitsAlloc = 8;
- bitsStored = 8;
- highBits = 7;
- photometric = "MONOCHROME2";
- break;
- case 16:
- spp = 1;
- bitsAlloc = 16;
- bitsStored = 16;
- highBits = 15;
- photometric = "MONOCHROME2";
- break;
- case 24:
- spp = 3;
- bitsAlloc = 8;
- bitsStored = 8;
- highBits = 7;
- photometric = "RGB";
- break;
- default:
- return false;
- break;
- }
-
- Uint16 dx = image.GetWidth();
- Uint16 dy = image.GetHeight();
- dataset->putAndInsertString( DCM_InstanceNumber, "1" );
- dataset->putAndInsertUint16( DCM_SamplesPerPixel, spp );
- dataset->putAndInsertString( DCM_PhotometricInterpretation,
- photometric.c_str() );
- dataset->putAndInsertUint16( DCM_Rows, dy );
- dataset->putAndInsertUint16( DCM_Columns, dx );
- dataset->putAndInsertUint16( DCM_BitsAllocated, bitsAlloc );
- dataset->putAndInsertUint16( DCM_BitsStored, bitsStored );
- dataset->putAndInsertUint16( DCM_HighBit, highBits );
- dataset->putAndInsertUint16( DCM_PixelRepresentation, 0 );
- dataset->putAndInsertUint16( DCM_PlanarConfiguration, 0 );
- if ( image.HasCalibration() )
- {
- std::ostringstream pixelSpacingX, pixelSpacingY;
- pixelSpacingX << image.GetResolutionX();
- std::string str = pixelSpacingX.str();
- if ( str.length() > 16 )
- {
- str.resize( 16 );
- }
- str += "\\";
- pixelSpacingY << image.GetResolutionY();
- std::string str2 = pixelSpacingY.str();
- if ( str2.length() > 16 )
- {
- str2.resize( 16 );
- }
- str += str2;
- dataset->putAndInsertString( DCM_PixelSpacing, str.c_str() );
- }
-
- unsigned long n = dx * dy * image.GetBpp();
- dataset->putAndInsertUint8Array( DCM_PixelData,
- (Uint8*)image.GetBuffer(), n );
- OFCondition status = fileFormat.saveFile( fileName.c_str(),
- EXS_LittleEndianExplicit );
- if ( status.bad() )
- {
- return false;
- }
- return true;
- }
- bool DicomIO::HasCalibration()
- {
- return m_calibrated;
- }
|