]> Creatis software - gdcm.git/commitdiff
* ENH: added some utility method that builds a flat dictionnary
authorfrog <frog>
Fri, 17 Sep 2004 13:11:14 +0000 (13:11 +0000)
committerfrog <frog>
Fri, 17 Sep 2004 13:11:14 +0000 (13:11 +0000)
    holding all the Dicom entries contained in the recursive structure
    of a gdcmElementSet. Refer to add FlatHashTablePrint.cxx for
    an example of usage.
    - src/gdcmDocument.[h|cxx] added BuildFlatHashTableRecurse() and
      BuildFlatHashTable() that build a flat dictionary.
    - src/gdcmElementSet.h: added a new private GetTag() accessor.
      gdcmDocument is now a friend of gdcmElementSet.
    - src/gdcmElementSet.cxx: clean up.
    - Example/FlatHashTablePrint.cxx added.
    - Example/CmakeLists.txt changed accordingly

ChangeLog
Example/CMakeLists.txt
Example/FlatHashTablePrint.cxx [new file with mode: 0644]
src/gdcmDocument.cxx
src/gdcmDocument.h
src/gdcmElementSet.cxx
src/gdcmElementSet.h

index bf85521c94b839f4de3b2d01cf49247b405bfe85..e2f2ca872a1904fe086aca7c4000053b993a953e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2004-09-17 Eric Boix <Eric.Boix@creatis.insa-lyon.fr>
+  * ENH: added some utility method that builds a flat dictionnary
+    holding all the Dicom entries contained in the recursive structure
+    of a gdcmElementSet. Refer to add FlatHashTablePrint.cxx for 
+    an example of usage.
+    - src/gdcmDocument.[h|cxx] added BuildFlatHashTableRecurse() and
+      BuildFlatHashTable() that build a flat dictionary.
+    - src/gdcmElementSet.h: added a new private GetTag() accessor.
+      gdcmDocument is now a friend of gdcmElementSet.
+    - src/gdcmElementSet.cxx: clean up.
+    - Example/FlatHashTablePrint.cxx added.
+    - Example/CmakeLists.txt changed accordingly
+
 2004-09-16 Eric Boix <Eric.Boix@creatis.insa-lyon.fr>
   * gdcmDocEntrySet::SQDepthLevel and gdcmDocEntrySet::BaseTagKey attributes
     moved away from gdcmDocEntrySet (since this class is an abstract class
index 791748f3272b38b8f651720cc126026b7effa446..b49dbe1a7b5872e065c4e8ae09e24979d2436d72 100644 (file)
@@ -55,3 +55,6 @@ TARGET_LINK_LIBRARIES(TestChangeHeader  gdcm)
 
 ADD_EXECUTABLE(TestReadWriteReadCompare TestReadWriteReadCompare.cxx)
 TARGET_LINK_LIBRARIES(TestReadWriteReadCompare  gdcm)
+
+ADD_EXECUTABLE(FlatHashTablePrint FlatHashTablePrint.cxx)
+TARGET_LINK_LIBRARIES(FlatHashTablePrint gdcm)
diff --git a/Example/FlatHashTablePrint.cxx b/Example/FlatHashTablePrint.cxx
new file mode 100644 (file)
index 0000000..bc9e599
--- /dev/null
@@ -0,0 +1,29 @@
+#include "gdcmHeader.h"
+
+// Iterate on all the Dicom entries encountered in the gdcmFile (given
+// as line argument) and print them. This is an illustration of the
+// usage of \ref gdcmDocument::BuildFlatHashTable().
+
+int main(int argc, char* argv[])
+{
+   if (argc < 2)
+   {
+      std::cerr << "Usage :" << std::endl << 
+      argv[0] << " input_dicom " << std::endl;
+      return 1;
+   }
+
+   gdcmHeader* header = new gdcmHeader( argv[1] );
+   TagDocEntryHT* Ht = header->BuildFlatHashTable();
+   
+   for (TagDocEntryHT::iterator tag = Ht->begin(); tag != Ht->end(); ++tag)
+   {
+      tag->second->Print(); 
+      std::cout << std::endl;
+   }
+
+   return 0;
+}
+
+
+
index 95bd114750c2c2c3c0fc18619d3bfc89444ffb97..16adce6fa9f73eb7c9a63c7058b7094c6276c464 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmDocument.cxx,v $
   Language:  C++
-  Date:      $Date: 2004/09/16 19:21:57 $
-  Version:   $Revision: 1.80 $
+  Date:      $Date: 2004/09/17 13:11:16 $
+  Version:   $Revision: 1.81 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -2893,7 +2893,6 @@ uint32_t gdcmDocument::ReadTagLength(uint16_t testGroup, uint16_t testElement)
 /**
  * \brief   Parse pixel data from disk for multi-fragment Jpeg/Rle files
  *          No other way so 'skip' the Data
- *
  */
 void gdcmDocument::Parse7FE0 ()
 {
@@ -2995,6 +2994,97 @@ void gdcmDocument::Parse7FE0 ()
    }
 }
 
+/**
+ * \brief Walk recursively the given \ref gdcmDocEntrySet, and feed
+ *        the given hash table (\ref TagDocEntryHT) with all the
+ *        \ref gdcmDocEntry (Dicom entries) encountered.
+ *        This method does the job for \ref BuildFlatHashTable.
+ * @param builtHT Where to collect all the \ref gdcmDocEntry encountered
+ *        when recursively walking the given set.
+ * @param set The structure to be traversed (recursively).
+ */
+void gdcmDocument::BuildFlatHashTableRecurse( TagDocEntryHT& builtHT,
+                                              gdcmDocEntrySet* set )
+{ 
+   if (gdcmElementSet* elementSet = dynamic_cast< gdcmElementSet* > ( set ) )
+   {
+      TagDocEntryHT* currentHT = elementSet->GetTagHT();
+      for( TagDocEntryHT::const_iterator i  = currentHT->begin();
+                                         i != currentHT->end();
+                                       ++i)
+      {
+         gdcmDocEntry* entry = i->second;
+         if ( gdcmSeqEntry* seqEntry = dynamic_cast<gdcmSeqEntry*>(entry) )
+         {
+            ListSQItem& items = seqEntry->GetSQItems();
+            for( ListSQItem::const_iterator item  = items.begin();
+                                            item != items.end();
+                                          ++item)
+            {
+               BuildFlatHashTableRecurse( builtHT, *item );
+            }
+            continue;
+         }
+         builtHT[entry->GetKey()] = entry;
+      }
+      return;
+    }
+
+   if (gdcmSQItem* SQItemSet = dynamic_cast< gdcmSQItem* > ( set ) )
+   {
+      ListDocEntry& currentList = SQItemSet->GetDocEntries();
+      for (ListDocEntry::iterator i  = currentList.begin();
+                                  i != currentList.end();
+                                ++i)
+      {
+         gdcmDocEntry* entry = *i;
+         if ( gdcmSeqEntry* seqEntry = dynamic_cast<gdcmSeqEntry*>(entry) )
+         {
+            ListSQItem& items = seqEntry->GetSQItems();
+            for( ListSQItem::const_iterator item  = items.begin();
+                                            item != items.end();
+                                          ++item)
+            {
+               BuildFlatHashTableRecurse( builtHT, *item );
+            }
+            continue;
+         }
+         builtHT[entry->GetKey()] = entry;
+      }
+
+   }
+}
+
+/**
+ * \brief Build a \ref TagDocEntryHT (i.e. a std::map<>) from the current
+ *        gdcmDocument.
+ *
+ *        The structure used by a gdcmDocument (through \ref gdcmElementSet),
+ *        in order to old the parsed entries of a Dicom header, is a recursive
+ *        one. This is due to the fact that the sequences (when present)
+ *        can be nested. Additionaly, the sequence items (represented in
+ *        gdcm as \ref gdcmSQItem) add an extra complexity to the data
+ *        structure. Hence, a gdcm user whishing to visit all the entries of
+ *        a Dicom header will need to dig in the gdcm internals (which
+ *        implies exposing all the internal data structures to the API).
+ *        In order to avoid this burden to the user, \ref BuildFlatHashTable
+ *        recursively builds a temporary hash table, which olds all the
+ *        Dicom entries in a flat structure (a \ref TagDocEntryHT i.e. a
+ *        std::map<>).
+ * \warning Of course there is NO integrity constrain between the 
+ *        returned \ref TagDocEntryHT and the \ref gdcmElemenSet used
+ *        to build it. Hence if the underlying \ref gdcmElemenSet is
+ *        altered, then it is the caller responsability to invoke 
+ *        \ref BuildFlatHashTable again...
+ * @return The flat std::map<> we juste build.
+ */
+TagDocEntryHT* gdcmDocument::BuildFlatHashTable()
+{
+   TagDocEntryHT* FlatHT = new TagDocEntryHT;
+   BuildFlatHashTableRecurse( *FlatHT, this );
+   return FlatHT;
+}
+
 
 
 /**
index 8e63544c14e2ee9cfad262d5a8239b4b03239b5b..e7518c66d32f69512f38b5a9e60027d1f35de6f8 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmDocument.h,v $
   Language:  C++
-  Date:      $Date: 2004/09/16 06:48:00 $
-  Version:   $Revision: 1.37 $
+  Date:      $Date: 2004/09/17 13:11:16 $
+  Version:   $Revision: 1.38 $
  
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -197,6 +197,7 @@ public:
    gdcmBinEntry* GetBinEntryByNumber(uint16_t group, uint16_t element); 
 
    void LoadDocEntrySafe(gdcmDocEntry* entry);
+   TagDocEntryHT* BuildFlatHashTable();
 
 private:
    // Read
@@ -235,6 +236,9 @@ private:
    gdcmDocEntry* ReadNextDocEntry();
 
    uint32_t GenerateFreeTagKeyInGroup(uint16_t group);
+   void BuildFlatHashTableRecurse( TagDocEntryHT& builtHT,
+                                   gdcmDocEntrySet* set );
+
 
 public:
 // Accessors:
index ee6d9658232f4d27ef7172f867193ff571b0e506..88547c878e7a6a8e60c5e19b24173791d1df211f 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmElementSet.cxx,v $
   Language:  C++
-  Date:      $Date: 2004/09/16 19:21:57 $
-  Version:   $Revision: 1.19 $
+  Date:      $Date: 2004/09/17 13:11:16 $
+  Version:   $Revision: 1.20 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -69,16 +69,12 @@ void gdcmElementSet::Print(std::ostream & os)
    {
       gdcmDocEntry* entry = i->second;
       entry->Print(os);   
-      bool PrintEndLine = true;
       if ( gdcmSeqEntry* seqEntry = dynamic_cast<gdcmSeqEntry*>(entry) )
       {
-         (void)seqEntry;  //not used
-         PrintEndLine = false;
-      }
-      if( PrintEndLine )
-      {
-         os << std::endl;
+         // Avoid the newline for a sequence:
+         continue;
       }
+      os << std::endl;
    }
 }
 
index df2f32a822f2bf0e65b149357acb10b3bdf81fc6..0c58214d7de0ab18104709fec7e5fdc6eb28db2c 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmElementSet.h,v $
   Language:  C++
-  Date:      $Date: 2004/09/10 14:32:04 $
-  Version:   $Revision: 1.15 $
+  Date:      $Date: 2004/09/17 13:11:16 $
+  Version:   $Revision: 1.16 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -45,18 +45,23 @@ public:
    virtual void Print(std::ostream &os = std::cout); 
    virtual void Write(FILE *fp, FileType filetype); 
 
-   /// Accessor to \ref gdcmElementSet::TagHT
+   /// Accessor to \ref TagHT
    // Do not expose this to user (public API) !
    // I re-add it temporaryly JPRx
    TagDocEntryHT &GetEntry() { return TagHT; };
 
+
 protected:
 // Variables
    /// Hash Table (map), to provide fast access
    TagDocEntryHT TagHT; 
      
 private:
-   //friend class gdcmDicomDir;
+   /// Just for following ::GetTagHT()
+   friend class gdcmDocument;
+
+   /// Accessor to \ref TagHT
+   TagDocEntryHT* GetTagHT() { return &TagHT; };
 };
 
 //-----------------------------------------------------------------------------