- i = GetListEntry().begin();
- while ( i != GetListEntry().end() ) {
-
- // std::cout << std::hex << (*i)->GetGroup() <<
- // " " << (*i)->GetElement() << endl;
-
- std::string v = (*i)->GetValue();
- if (v == "PATIENT ") {
- patCur=new gdcmPatient();
- //cout << "PATIENT" << endl,
- patCur->beginObj =i;
- GetPatients().push_back(patCur);
- }
-
- if (v == "STUDY ") {
- //cout << "STUDY" << endl,
- studCur=new gdcmStudy();
- studCur->beginObj = patCur->endObj = i;
- lPatient::iterator aa = GetPatients().end();
- --aa;
- (*aa)->GetStudies().push_back(studCur);
- }
- studCur=new gdcmStudy();
-
- if (v == "SERIES") {
- //cout << "SERIES" << endl,
- serCur=new gdcmSerie();
-
- serCur->beginObj = studCur->endObj= i;
- lPatient::iterator aa = GetPatients().end();
- --aa;
- lStudy::iterator bb = (*aa)->GetStudies().end();
- --bb;
- (*bb)->GetSeries().push_back(serCur);
- }
-
- if (v == "IMAGE ") {
- //cout << "IMAGE" << endl;
- imaCur=new gdcmImage();
- imaCur->beginObj = serCur->endObj= i;
-
- lPatient::iterator aa = GetPatients().end();
- --aa;
- lStudy::iterator bb = (*aa)->GetStudies().end();
- --bb;
- lSerie::iterator cc = (*bb)->GetSeries().end();
- --cc;
- (*cc)->GetImages().push_back(imaCur);
-
-
- /* ---
- // ce n'est pas sur une nouvelle IMAGE, qu'il faut intervenir
- // mais lorsqu'on rencontre un 'non IMAGE' apres des 'IMAGE'
- lImage::iterator dd = (*cc)->GetImages().end();
-
- if ( (*cc)->GetImages().begin() != dd ) {
- --dd;
- (*dd)->endObj = i;
- }
- --- */
- }
- ++i;
+bool DicomDir::Anonymize()
+{
+ DataEntry *v;
+ // Something clever to be found to forge the Patient names
+ std::ostringstream s;
+ int i = 1;
+ for(ListDicomDirPatient::iterator cc = Patients.begin();
+ cc!= Patients.end();
+ ++cc)
+ {
+ s << i;
+ v = (*cc)->GetDataEntry(0x0010, 0x0010) ; // Patient's Name
+ if (v)
+ {
+ v->SetString(s.str());
+ }
+
+ v = (*cc)->GetDataEntry(0x0010, 0x0020) ; // Patient ID
+ if (v)
+ {
+ v->SetString(" ");
+ }
+
+ v = (*cc)->GetDataEntry(0x0010, 0x0030) ; // Patient's BirthDate
+ if (v)
+ {
+ v->SetString(" ");
+ }
+ s << "";
+ i++;
+ }
+ return true;
+}
+
+/**
+ * \brief Copies all the attributes from an other DocEntrySet
+ * @param set entry to copy from
+ * @remarks The contained DocEntries are not copied, only referenced
+ */
+void DicomDir::Copy(DocEntrySet *set)
+{
+ // Remove all previous childs
+ ClearPatient();
+
+ Document::Copy(set);
+
+ DicomDir *dd = dynamic_cast<DicomDir *>(set);
+ if( dd )
+ {
+ if(MetaElems)
+ MetaElems->Unregister();
+ MetaElems = dd->MetaElems;
+ if(MetaElems)
+ MetaElems->Register();
+
+ Patients = dd->Patients;
+ for(ItPatient = Patients.begin();ItPatient != Patients.end();++ItPatient)
+ (*ItPatient)->Register();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// 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();
+ unsigned int nbFile = fileList.size();
+ for( DirListType::iterator it = fileList.begin();
+ it != fileList.end();
+ ++it )
+ {
+ Progress = (float)(count+1)/(float)nbFile;
+ CallProgressMethod();
+ if ( Abort )
+ {
+ break;
+ }
+
+ f = File::New( );
+ f->SetLoadMode(LoadMode); // we allow user not to load Sequences,
+ // or Shadow groups, or ......
+ f->SetFileName( it->c_str() );
+ f->Load( );
+
+ if ( f->IsReadable() )
+ {
+ // Add the file to the chained list:
+ list.push_back(f);
+ gdcmDebugMacro( "Readable " << it->c_str() );
+ }
+ else
+ {
+ f->Delete();
+ }
+ 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)
+ {
+ dynamic_cast<File *>(*itDoc)->Delete();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Private
+/**
+ * \brief Sets all fields to NULL
+ */
+void DicomDir::Initialize()
+{
+ 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 ( DataEntry *dataEntry = dynamic_cast<DataEntry *>(d) )
+ {
+ v = dataEntry->GetString();
+ }
+ else
+ {
+ gdcmWarningMacro( "(0004,1430) not a DataEntry ?!?");
+ 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 = DicomDirImage::New(true); // true = empty
+ if ( !AddImageToEnd( static_cast<DicomDirImage *>(si)) )
+ {
+ si->Delete();
+ si = NULL;
+ gdcmErrorMacro( "Add AddImageToEnd failed");
+ }
+ }
+ else if ( v == "SERIES" )
+ {
+ si = DicomDirSerie::New(true); // true = empty
+ if ( !AddSerieToEnd( static_cast<DicomDirSerie *>(si)) )
+ {
+ si->Delete();
+ si = NULL;
+ gdcmErrorMacro( "Add AddSerieToEnd failed");
+ }
+ }
+ else if ( v == "VISIT " )
+ {
+ si = DicomDirVisit::New(true); // true = empty
+ if ( !AddVisitToEnd( static_cast<DicomDirVisit *>(si)) )
+ {
+ si->Delete();
+ si = NULL;
+ gdcmErrorMacro( "Add AddVisitToEnd failed");
+ }
+ }
+ else if ( v == "STUDY " )
+ {
+ si = DicomDirStudy::New(true); // true = empty
+ if ( !AddStudyToEnd( static_cast<DicomDirStudy *>(si)) )
+ {
+ si->Delete();
+ si = NULL;
+ gdcmErrorMacro( "Add AddStudyToEnd failed");
+ }
+ }
+ else if ( v == "PATIENT " )
+ {
+ si = DicomDirPatient::New(true); // true = empty
+ if ( !AddPatientToEnd( static_cast<DicomDirPatient *>(si)) )
+ {
+ si->Delete();
+ si = NULL;
+ gdcmErrorMacro( "Add PatientToEnd failed");
+ }
+ }
+ /// \to do : deal with PRIVATE (not so easy, since PRIVATE appears
+ /// at different levels ?!? )
+
+ else if ( v == "PRIVATE " ) // for SIEMENS 'CSA Non Image'
+ {
+
+ gdcmWarningMacro( " -------------------------------------------"
+ << "a PRIVATE SQItem was found : " << v);
+ si = DicomDirPrivate::New(true); // true = empty
+ if ( !AddPrivateToEnd( static_cast<DicomDirPrivate *>(si)) )
+ {
+ si->Delete();
+ si = NULL;
+ gdcmErrorMacro( "Add PrivateToEnd failed");
+ }