📄 gdcmdicomdir.cxx
字号:
return NULL;
}
/**
* \brief fills the whole structure, starting from a root Directory
*/
void DicomDir::ParseDirectory()
{
CreateDicomDirChainedList( GetFileName() );
CreateDicomDir();
}
void DicomDir::SetStartMethod( DicomDir::Method *method, void *arg )
{
SetStartMethod(method,arg,NULL);
}
void DicomDir::SetProgressMethod( DicomDir::Method *method, void *arg )
{
SetProgressMethod(method,arg,NULL);
}
void DicomDir::SetEndMethod( DicomDir::Method *method, void *arg )
{
SetEndMethod(method,arg,NULL);
}
/**
* \brief Set the start method to call when the parsing of the
* directory starts.
* @param method Method to call
* @param arg Argument to pass to the method
* @param argDelete Argument
* \warning In python : the arg parameter isn't considered
*/
void DicomDir::SetStartMethod( DicomDir::Method *method, void *arg,
DicomDir::Method *argDelete )
{
if ( StartArg && StartMethodArgDelete )
{
StartMethodArgDelete( StartArg );
}
StartMethod = method;
StartArg = arg;
StartMethodArgDelete = argDelete;
}
/**
* \brief Set the progress method to call when the parsing of the
* directory progress
* @param method Method to call
* @param arg Argument to pass to the method
* @param argDelete Argument
* \warning In python : the arg parameter isn't considered
*/
void DicomDir::SetProgressMethod( DicomDir::Method *method, void *arg,
DicomDir::Method *argDelete )
{
if ( ProgressArg && ProgressMethodArgDelete )
{
ProgressMethodArgDelete( ProgressArg );
}
ProgressMethod = method;
ProgressArg = arg;
ProgressMethodArgDelete = argDelete;
}
/**
* \brief Set the end method to call when the parsing of the directory ends
* @param method Method to call
* @param arg Argument to pass to the method
* @param argDelete Argument
* \warning In python : the arg parameter isn't considered
*/
void DicomDir::SetEndMethod( DicomDir::Method *method, void *arg,
DicomDir::Method *argDelete )
{
if ( EndArg && EndMethodArgDelete )
{
EndMethodArgDelete( EndArg );
}
EndMethod = method;
EndArg = arg;
EndMethodArgDelete = argDelete;
}
/**
* \brief Set the method to delete the argument
* The argument is destroyed when the method is changed or when the
* class is destroyed
* @param method Method to call to delete the argument
*/
void DicomDir::SetStartMethodArgDelete( DicomDir::Method *method )
{
StartMethodArgDelete = method;
}
/**
* \brief Set the method to delete the argument
* The argument is destroyed when the method is changed or when the
* class is destroyed
* @param method Method to call to delete the argument
*/
void DicomDir::SetProgressMethodArgDelete( DicomDir::Method *method )
{
ProgressMethodArgDelete = method;
}
/**
* \brief Set the method to delete the argument
* The argument is destroyed when the method is changed or when
* the class is destroyed
* @param method Method to call to delete the argument
*/
void DicomDir::SetEndMethodArgDelete( DicomDir::Method *method )
{
EndMethodArgDelete = method;
}
/**
* \brief writes on disc a DICOMDIR
* \ warning does NOT add the missing elements in the header :
* it's up to the user doing it !
* @param fileName file to be written to
* @return false only when fail to open
*/
bool DicomDir::Write(std::string const &fileName)
{
int i;
uint16_t sq[6] = { 0x0004, 0x1220, 0x5153, 0x0000, 0xffff, 0xffff };
uint16_t sqt[4]= { 0xfffe, 0xe0dd, 0x0000, 0x0000 };
std::ofstream *fp = new std::ofstream(fileName.c_str(),
std::ios::out | std::ios::binary);
if ( !fp )
{
gdcmWarningMacro("Failed to open(write) File: " << fileName.c_str());
return false;
}
char filePreamble[128];
memset(filePreamble, 0, 128);
fp->write(filePreamble, 128);
binary_write( *fp, "DICM");
DicomDirMeta *ptrMeta = GetMeta();
ptrMeta->WriteContent(fp, ExplicitVR);
// force writing 0004|1220 [SQ ], that CANNOT exist within DicomDirMeta
for(i=0;i<6;++i)
{
binary_write(*fp, sq[i]);
}
for(ListDicomDirPatient::iterator cc = Patients.begin();
cc != Patients.end();
++cc )
{
(*cc)->WriteContent( fp, ExplicitVR );
}
// force writing Sequence Delimitation Item
for(i=0;i<4;++i)
{
binary_write(*fp, sqt[i]); // fffe e0dd 0000 0000
}
fp->close();
delete fp;
return true;
}
/**
* \brief Anonymize a DICOMDIR
* @return true
*/
bool DicomDir::Anonymize()
{
ValEntry *v;
// Something clever to be found to forge the Patient names
itksys_ios::ostringstream s;
int i = 1;
for(ListDicomDirPatient::iterator cc = Patients.begin();
cc!= Patients.end();
++cc)
{
s << i;
v = (*cc)->GetValEntry(0x0010, 0x0010) ; // Patient's Name
if (v)
{
v->SetValue(s.str());
}
v = (*cc)->GetValEntry(0x0010, 0x0020) ; // Patient ID
if (v)
{
v->SetValue(" ");
}
v = (*cc)->GetValEntry(0x0010, 0x0030) ; // Patient's BirthDate
if (v)
{
v->SetValue(" ");
}
s << "";
i++;
}
return true;
}
//-----------------------------------------------------------------------------
// Protected
/**
* \brief create a Document-like chained list from a root Directory
* @param path entry point of the tree-like structure
*/
void DicomDir::CreateDicomDirChainedList(std::string const &path)
{
CallStartMethod();
DirList dirList(path,1); // gets recursively the file list
unsigned int count = 0;
VectDocument list;
File *f;
DirListType fileList = dirList.GetFilenames();
for( DirListType::iterator it = fileList.begin();
it != fileList.end();
++it )
{
Progress = (float)(count+1)/(float)fileList.size();
CallProgressMethod();
if ( Abort )
{
break;
}
f = new File( );
f->SetLoadMode(LoadMode); // we allow user not to load Sequences,
// or Shadow groups, or ......
f->SetFileName( it->c_str() );
/*int res = */f->Load( );
if ( f->IsReadable() )
{
// Add the file to the chained list:
list.push_back(f);
gdcmDebugMacro( "Readable " << it->c_str() );
}
else
{
delete f;
}
count++;
}
// sorts Patient/Study/Serie/
std::sort(list.begin(), list.end(), DicomDir::HeaderLessThan );
std::string tmp = dirList.GetDirName();
//for each File of the chained list, add/update the Patient/Study/Serie/Image info
SetElements(tmp, list);
CallEndMethod();
for(VectDocument::iterator itDoc=list.begin();
itDoc!=list.end();
++itDoc)
{
delete dynamic_cast<File *>(*itDoc);
}
}
/**
* \brief CallStartMethod
*/
void DicomDir::CallStartMethod()
{
Progress = 0.0f;
Abort = false;
if ( StartMethod )
{
StartMethod( StartArg );
}
}
/**
* \brief CallProgressMethod
*/
void DicomDir::CallProgressMethod()
{
if ( ProgressMethod )
{
ProgressMethod( ProgressArg );
}
}
/**
* \brief CallEndMethod
*/
void DicomDir::CallEndMethod()
{
Progress = 1.0f;
if ( EndMethod )
{
EndMethod( EndArg );
}
}
//-----------------------------------------------------------------------------
// Private
/**
* \brief Sets all fields to NULL
*/
void DicomDir::Initialize()
{
StartMethod = NULL;
ProgressMethod = NULL;
EndMethod = NULL;
StartMethodArgDelete = NULL;
ProgressMethodArgDelete = NULL;
EndMethodArgDelete = NULL;
StartArg = NULL;
ProgressArg = NULL;
EndArg = NULL;
Progress = 0.0;
Abort = false;
MetaElems = NULL;
}
/**
* \brief create a 'gdcm::DicomDir' from a DICOMDIR Header
*/
void DicomDir::CreateDicomDir()
{
// The SeqEntries of "Directory Record Sequence" are parsed.
// When a DicomDir tag ("PATIENT", "STUDY", "SERIE", "IMAGE") is found :
// 1 - we save the beginning iterator
// 2 - we continue to parse
// 3 - we find an other tag
// + we create the object for the precedent tag
// + loop to 1 -
gdcmDebugMacro("Create DicomDir");
// Directory record sequence
DocEntry *e = GetDocEntry(0x0004, 0x1220);
if ( !e )
{
gdcmWarningMacro( "No Directory Record Sequence (0004,1220) found");
return;
}
SeqEntry *s = dynamic_cast<SeqEntry *>(e);
if ( !s )
{
gdcmWarningMacro( "Element (0004,1220) is not a Sequence ?!?");
return;
}
NewMeta();
DocEntry *d;
std::string v;
SQItem *si;
SQItem *tmpSI=s->GetFirstSQItem();
while(tmpSI)
{
d = tmpSI->GetDocEntry(0x0004, 0x1430); // Directory Record Type
if ( ValEntry* valEntry = dynamic_cast<ValEntry *>(d) )
{
v = valEntry->GetValue();
}
else
{
gdcmWarningMacro( "(0004,1430) not a ValEntry ?!?");
continue;
}
// A decent DICOMDIR has much more images than series,
// more series than studies, and so on.
// This is the right order to perform the tests
if ( v == "IMAGE " )
{
si = new DicomDirImage(true);
if ( !AddImageToEnd( static_cast<DicomDirImage *>(si)) )
{
delete si;
si = NULL;
gdcmErrorMacro( "Add AddImageToEnd failed");
}
}
else if ( v == "SERIES" )
{
si = new DicomDirSerie(true);
if ( !AddSerieToEnd( static_cast<DicomDirSerie *>(si)) )
{
delete si;
si = NULL;
gdcmErrorMacro( "Add AddSerieToEnd failed");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -