+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
ADD_EXECUTABLE(TestReadWriteReadCompare TestReadWriteReadCompare.cxx)
TARGET_LINK_LIBRARIES(TestReadWriteReadCompare gdcm)
+
+ADD_EXECUTABLE(FlatHashTablePrint FlatHashTablePrint.cxx)
+TARGET_LINK_LIBRARIES(FlatHashTablePrint gdcm)
--- /dev/null
+#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;
+}
+
+
+
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
/**
* \brief Parse pixel data from disk for multi-fragment Jpeg/Rle files
* No other way so 'skip' the Data
- *
*/
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;
+}
+
/**
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
gdcmBinEntry* GetBinEntryByNumber(uint16_t group, uint16_t element);
void LoadDocEntrySafe(gdcmDocEntry* entry);
+ TagDocEntryHT* BuildFlatHashTable();
private:
// Read
gdcmDocEntry* ReadNextDocEntry();
uint32_t GenerateFreeTagKeyInGroup(uint16_t group);
+ void BuildFlatHashTableRecurse( TagDocEntryHT& builtHT,
+ gdcmDocEntrySet* set );
+
public:
// Accessors:
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
{
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;
}
}
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
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; };
};
//-----------------------------------------------------------------------------