]> Creatis software - gdcm.git/blobdiff - src/gdcmDicomDir.cxx
2004-02-06 Jean-Pierre Roux
[gdcm.git] / src / gdcmDicomDir.cxx
index e9ea4d7e0933f29640a5ca808344a5b6d84494b5..3592304d18afef30f1d13df0f2723c2d0d9a685a 100644 (file)
@@ -8,6 +8,7 @@
 #include "gdcmUtil.h"
 
 #include <string>
+#include <algorithm>
 
 #include <sys/types.h>
 #include <errno.h>
 // Constructor / Destructor
 /*
  * \ingroup gdcmDicomDir
- * \brief   
+ * \brief   Constructor
  * @param   Filename
  * @param   exception_on_error
  */
-gdcmDicomDir::gdcmDicomDir(const char *FileName,
+gdcmDicomDir::gdcmDicomDir(const char *FileName, bool parseDir,
                            bool exception_on_error):
    gdcmParser(FileName,exception_on_error,true)
 {
    if( GetListEntry().begin()==GetListEntry().end() ) 
    {
       dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : entry list empty");
-      dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : Parse directory and create the DicomDir");
-
-      std::string path=FileName;
-      std::string file;
 
-      int pos1=path.rfind("/");
-      int pos2=path.rfind("\\");
-      if(pos1>pos2)
-         path.resize(pos1);
-      else
-         path.resize(pos2);
-      NewDicomDir(path);
+      if(parseDir)
+      {
+         dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : Parse directory and create the DicomDir");
+         ParseDirectory();
+      }
    }
-
-   CreateDicomDir();
+   else
+      CreateDicomDir();
 }
 
 /*
@@ -49,13 +44,13 @@ gdcmDicomDir::gdcmDicomDir(const char *FileName,
  * \brief   
  * @param   exception_on_error
  */
-gdcmDicomDir::gdcmDicomDir(ListTag *l,
+/*gdcmDicomDir::gdcmDicomDir(ListTag *l,
                            bool exception_on_error):                           
    gdcmParser(exception_on_error )  
 {    
    listEntries=*l;
    CreateDicomDir();
-}
+}*/
 
 /*
  * \ingroup gdcmDicomDir
@@ -63,6 +58,8 @@ gdcmDicomDir::gdcmDicomDir(ListTag *l,
  */
 gdcmDicomDir::~gdcmDicomDir() 
 {
+   delete metaelems;
+   
    for(ListPatient::iterator cc=patients.begin();cc!=patients.end();++cc)
    {
       delete *cc;
@@ -71,8 +68,15 @@ gdcmDicomDir::~gdcmDicomDir()
 
 //-----------------------------------------------------------------------------
 // Print
+/*
+ * \ingroup gdcmDicomDir
+ * \brief  Canonical Printer 
+ */
 void gdcmDicomDir::Print(std::ostream &os)
 {
+   (*metaelems).SetPrintLevel(printLevel);
+   (*metaelems).Print(os);   
+   
    for(ListPatient::iterator cc=patients.begin();cc!=patients.end();++cc)
    {
      (*cc)->SetPrintLevel(printLevel);
@@ -86,9 +90,9 @@ void gdcmDicomDir::Print(std::ostream &os)
  * \ingroup gdcmDicomDir
  * \brief   writes on disc a DICOMDIR
  * \ warning does NOT add the missing elements in the header :
- * \         it's up to the user doing it !
+ *           it's up to the user doing it !
  * @param  fileName file to be written to 
- * @return
+ * @return false only when fail to open
  */
 bool gdcmDicomDir::Write(std::string fileName) 
 {
@@ -114,12 +118,22 @@ bool gdcmDicomDir::Write(std::string fileName)
    return true;
 }
 
+/*
+ * \ingroup gdcmDicomDir
+ * \brief  fills whole the structure
+ */
+void gdcmDicomDir::ParseDirectory(void)
+{
+   NewDicomDir(GetPath());
+   CreateDicomDir();
+}
+
 //-----------------------------------------------------------------------------
 // Protected
 /*
  * \ingroup gdcmDicomDir
- * \brief   
- * @param   
+ * \brief create a gdcmDicomDir from a root Directory 
+ * @param path entry point of the stree-like structure
  */
 void gdcmDicomDir::NewDicomDir(std::string path)
 {
@@ -128,11 +142,11 @@ void gdcmDicomDir::NewDicomDir(std::string path)
    gdcmHeader *header;
 
    listEntries.clear();
+   patients.clear();
 
    for(gdcmDirList::iterator it=fileList.begin(); 
        it!=fileList.end(); ++it) 
    {
-//      std::cout<<*it<<std::endl;
       header=new gdcmHeader(it->c_str());
       if(header->IsReadable())
          list.push_back(header);
@@ -140,15 +154,36 @@ void gdcmDicomDir::NewDicomDir(std::string path)
          delete header;
    }
 
-   SetElements(path,list);
+   std::sort(list.begin(),list.end(),gdcmDicomDir::HeaderLessThan);
+
+   std::string tmp=fileList.GetDirName();
+   SetElements(tmp,list);
+}
+
+/*
+ * \ingroup gdcmDicomDir
+ * \brief   Get the DicomDir path
+ * @param   
+ */
+std::string gdcmDicomDir::GetPath(void)
+{
+   std::string path=GetFileName();
+
+   int pos1=path.rfind("/");
+   int pos2=path.rfind("\\");
+   if(pos1>pos2)
+      path.resize(pos1);
+   else
+      path.resize(pos2);
+
+   return(path);
 }
 
 //-----------------------------------------------------------------------------
 // Private
 /*
  * \ingroup gdcmDicomDir
- * \brief   
- * @param   
+ * \brief create a 'gdcmDicomDir' from a DICOMDIR gdcmHeader 
  */
 void gdcmDicomDir::CreateDicomDir()
 {
@@ -162,18 +197,25 @@ void gdcmDicomDir::CreateDicomDir()
    gdcmDicomDirType type=gdcmDicomDir::GDCM_NONE;
    ListTag::iterator begin;
    ListTag::iterator end;
+   ListTag::iterator k;
 
    begin=listEntries.begin();
    end=begin;
-   for(ListTag::iterator i=listEntries.begin();i !=listEntries.end();++i) 
+   
+   for(ListTag::iterator j=begin;j !=listEntries.end();++j) 
+   {
+      if((*j)->GetValue()=="PATIENT ") {
+         k = j; 
+         break;
+      }
+   }   
+   AddObjectToEnd(gdcmDicomDir::GDCM_META,begin,k);       
+    
+   for(ListTag::iterator i=k;i !=listEntries.end();++i) 
    {
-      // std::cout << std::hex <<(*i)->GetGroup() << 
-      //                  " " <<(*i)->GetElement() << endl;
-
       std::string v=(*i)->GetValue();
       if(v=="PATIENT ") 
       {
-       //  std::cout<<"PATIENT"<<std::endl;
          end=i;
          AddObjectToEnd(type,begin,end);
 
@@ -183,7 +225,6 @@ void gdcmDicomDir::CreateDicomDir()
 
       if(v=="STUDY ")
       {
-       //  std::cout<<"STUDY"<<std::endl;
          end=i;
          AddObjectToEnd(type,begin,end);
 
@@ -193,7 +234,6 @@ void gdcmDicomDir::CreateDicomDir()
 
       if(v=="SERIES") 
       {
-       //  std::cout<<"SERIES"<<std::endl;
          end=i;
          AddObjectToEnd(type,begin,end);
 
@@ -203,7 +243,6 @@ void gdcmDicomDir::CreateDicomDir()
 
       if(v=="IMAGE ") 
       {
-       //  std::cout<<"IMAGE"<<std::endl;
          end=i;
          AddObjectToEnd(type,begin,end);
 
@@ -218,7 +257,9 @@ void gdcmDicomDir::CreateDicomDir()
 /*
  * \ingroup gdcmDicomDir
  * \brief   
- * @param   
+ * @param   type
+ * @param   begin
+ * @param   end
  */
 void gdcmDicomDir::AddObjectToEnd(gdcmDicomDirType type,ListTag::iterator begin,ListTag::iterator end)
 {
@@ -227,6 +268,9 @@ void gdcmDicomDir::AddObjectToEnd(gdcmDicomDirType type,ListTag::iterator begin,
 
    switch(type)
    {
+      case gdcmDicomDir::GDCM_META:
+         AddMetaToEnd(begin,end);
+         break;      
       case gdcmDicomDir::GDCM_PATIENT:
          AddPatientToEnd(begin,end);
          break;
@@ -242,11 +286,24 @@ void gdcmDicomDir::AddObjectToEnd(gdcmDicomDirType type,ListTag::iterator begin,
    }
 }
 
+
+/*
+ * \ingroup gdcmDicomDir
+ * \brief Well ... Not realy to end, there is only one occurence  
+ * @param   begin
+ * @param   end
+*/
+void gdcmDicomDir::AddMetaToEnd(ListTag::iterator begin,ListTag::iterator end)
+{
+   metaelems = new gdcmMeta(begin,end);
+}
+
 /*
  * \ingroup gdcmDicomDir
  * \brief   
- * @param   
- */
+ * @param   begin
+ * @param   end
+*/
 void gdcmDicomDir::AddPatientToEnd(ListTag::iterator begin,ListTag::iterator end)
 {
    patients.push_back(new gdcmPatient(begin,end));
@@ -255,7 +312,8 @@ void gdcmDicomDir::AddPatientToEnd(ListTag::iterator begin,ListTag::iterator end
 /*
  * \ingroup gdcmDicomDir
  * \brief   
- * @param   
+ * @param   begin
+ * @param   end
  */
  void gdcmDicomDir::AddStudyToEnd(ListTag::iterator begin,ListTag::iterator end)
 {
@@ -269,7 +327,8 @@ void gdcmDicomDir::AddPatientToEnd(ListTag::iterator begin,ListTag::iterator end
 /*
  * \ingroup gdcmDicomDir
  * \brief   
- * @param   
+ * @param   begin
+ * @param   end
  */
 void gdcmDicomDir::AddSerieToEnd(ListTag::iterator begin,ListTag::iterator end)
 {
@@ -289,7 +348,8 @@ void gdcmDicomDir::AddSerieToEnd(ListTag::iterator begin,ListTag::iterator end)
 
 /*
  * \ingroup gdcmDicomDir
- * \brief   
+ * @param   begin
+ * @param   end
  * @param   
  */
  void gdcmDicomDir::AddImageToEnd(ListTag::iterator begin,ListTag::iterator end)
@@ -317,7 +377,8 @@ void gdcmDicomDir::AddSerieToEnd(ListTag::iterator begin,ListTag::iterator end)
 /*
  * \ingroup gdcmDicomDir
  * \brief   
- * @param   
+ * @param   path
+ * @param   list
  */
 void gdcmDicomDir::SetElements(std::string &path,ListHeader &list)
 {
@@ -334,7 +395,7 @@ void gdcmDicomDir::SetElements(std::string &path,ListHeader &list)
    ListTag::iterator debPat=listEntries.begin();
    for(ListHeader::iterator it=list.begin();it!=list.end();++it) 
    {
-     // get the current file characteristics
+      // get the current file characteristics
       patCurName=(*it)->GetEntryByNumber(0x0010,0x0010); 
       patCurID=(*it)->GetEntryByNumber(0x0010,0x0011); 
       studCurInstanceUID=(*it)->GetEntryByNumber(0x0020,0x000d);            
@@ -351,9 +412,7 @@ void gdcmDicomDir::SetElements(std::string &path,ListHeader &list)
 
       // if new Serie Deal with 'SERIE' Elements   
       if(serCurInstanceUID!=serPrevInstanceUID || serCurID!=serPrevID) 
-      {
          SetElement(path,GDCM_SERIE,*it);
-      } 
       
       // Always Deal with 'IMAGE' Elements  
       SetElement(path,GDCM_IMAGE,*it);
@@ -370,7 +429,9 @@ void gdcmDicomDir::SetElements(std::string &path,ListHeader &list)
 /*
  * \ingroup gdcmDicomDir
  * \brief   
- * @param   
+ * @param   path
+ * @param   type
+ * @param   header
  */
 void gdcmDicomDir::SetElement(std::string &path,gdcmDicomDirType type,gdcmHeader *header)
 {
@@ -464,4 +525,9 @@ void gdcmDicomDir::SetElement(std::string &path,gdcmDicomDirType type,gdcmHeader
    }     
 }
 
+bool gdcmDicomDir::HeaderLessThan(gdcmHeader *header1,gdcmHeader *header2)
+{
+   return(*header1<*header2);
+}
+
 //-----------------------------------------------------------------------------