X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmDocument.cxx;h=08e6a9c027a5962c161aedfb643232d3143a66c7;hb=7e9537ac534af5c5b9c5231c1b7fdd7193c2255d;hp=23a0051201fb0329e673e4d04884f410a1faf48d;hpb=9871e41fed63a2c08545218af2f09c717c64470f;p=gdcm.git diff --git a/src/gdcmDocument.cxx b/src/gdcmDocument.cxx index 23a00512..08e6a9c0 100644 --- a/src/gdcmDocument.cxx +++ b/src/gdcmDocument.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocument.cxx,v $ Language: C++ - Date: $Date: 2005/01/13 09:53:42 $ - Version: $Revision: 1.188 $ + Date: $Date: 2005/01/17 17:27:03 $ + Version: $Revision: 1.193 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -85,7 +85,7 @@ Document::Document( std::string const &filename ) : ElementSet(-1) long beg = Fp->tellg(); lgt -= beg; - ParseDES( this, beg, lgt, false); // le Load sera fait a la volee + ParseDES( this, beg, lgt, false); // Loading is done during parsing Fp->seekg( 0, std::ios::beg); @@ -98,14 +98,14 @@ Document::Document( std::string const &filename ) : ElementSet(-1) /// FIXME FIXME FIXME /// The tags refered by the three following lines used to be CORRECTLY /// defined as having an US Value Representation in the public - /// dictionnary. BUT the semantics implied by the three following + /// dictionary. BUT the semantics implied by the three following /// lines state that the corresponding tag contents are in fact /// the ones of a BinEntry. - /// In order to fix things "Quick and Dirty" the dictionnary was + /// In order to fix things "Quick and Dirty" the dictionary was /// altered on PURPOSE but now contains a WRONG value. /// In order to fix things and restore the dictionary to its /// correct value, one needs to decided of the semantics by deciding - /// wether the following tags are either: + /// whether the following tags are either: /// - multivaluated US, and hence loaded as ValEntry, but afterwards /// also used as BinEntry, which requires the proper conversion, /// - OW, and hence loaded as BinEntry, but afterwards also used @@ -256,7 +256,7 @@ bool Document::IsReadable() } if( TagHT.empty() ) - { + { gdcmVerboseMacro( "No tags in internal hash table."); return false; } @@ -412,7 +412,7 @@ bool Document::CloseFile() /** * \brief Writes in a file all the Header Entries (Dicom Elements) - * @param fp file pointer on an already open file + * @param fp file pointer on an already open file (actually: Output File Stream) * @param filetype Type of the File to be written * (ACR-NEMA, ExplicitVR, ImplicitVR) * \return Always true. @@ -587,8 +587,8 @@ BinEntry *Document::ReplaceOrCreate(uint8_t *binArea, /* * \brief Modifies the value of a given Header Entry (Dicom Element) * when it exists. Create it when unexistant. - * @param Group Group number of the Entry - * @param Elem Element number of the Entry + * @param group Group number of the Entry + * @param elem Element number of the Entry * \return pointer to the modified/created SeqEntry (NULL when creation * failed). */ @@ -657,13 +657,13 @@ bool Document::ReplaceIfExist(std::string const &value, /** * \brief Checks if a given Dicom Element exists within the H table - * @param group Group number of the searched Dicom Element - * @param element Element number of the searched Dicom Element + * @param group Group number of the searched Dicom Element + * @param elem Element number of the searched Dicom Element * @return true is found */ -bool Document::CheckIfEntryExist(uint16_t group, uint16_t element ) +bool Document::CheckIfEntryExist(uint16_t group, uint16_t elem ) { - const std::string &key = DictEntry::TranslateToKey(group, element ); + const std::string &key = DictEntry::TranslateToKey(group, elem ); return TagHT.count(key) != 0; } @@ -672,14 +672,14 @@ bool Document::CheckIfEntryExist(uint16_t group, uint16_t element ) * \brief Searches within Header Entries (Dicom Elements) parsed with * the public and private dictionaries * for the element value representation of a given tag. - * @param group Group number of the searched tag. - * @param element Element number of the searched tag. + * @param group Group number of the searched tag. + * @param elem Element number of the searched tag. * @return Corresponding element value representation when it exists, * and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise. */ -std::string Document::GetEntry(uint16_t group, uint16_t element) +std::string Document::GetEntry(uint16_t group, uint16_t elem) { - TagKey key = DictEntry::TranslateToKey(group, element); + TagKey key = DictEntry::TranslateToKey(group, elem); if ( !TagHT.count(key)) { return GDCM_UNFOUND; @@ -692,19 +692,18 @@ std::string Document::GetEntry(uint16_t group, uint16_t element) * \brief Searches within Header Entries (Dicom Elements) parsed with * the public and private dictionaries * for the element value representation of a given tag.. - * * Obtaining the VR (Value Representation) might be needed by caller * to convert the string typed content to caller's native type * (think of C++ vs Python). The VR is actually of a higher level * of semantics than just the native C++ type. - * @param group Group number of the searched tag. - * @param element Element number of the searched tag. + * @param group Group number of the searched tag. + * @param elem Element number of the searched tag. * @return Corresponding element value representation when it exists, * and the string GDCM_UNFOUND ("gdcm::Unfound") otherwise. */ -std::string Document::GetEntryVR(uint16_t group, uint16_t element) +std::string Document::GetEntryVR(uint16_t group, uint16_t elem) { - DocEntry *elem = GetDocEntry(group, element); + DocEntry *elem = GetDocEntry(group, elem); if ( !elem ) { return GDCM_UNFOUND; @@ -716,13 +715,13 @@ std::string Document::GetEntryVR(uint16_t group, uint16_t element) * \brief Searches within Header Entries (Dicom Elements) parsed with * the public and private dictionaries * for the value length of a given tag.. - * @param group Group number of the searched tag. - * @param element Element number of the searched tag. + * @param group Group number of the searched tag. + * @param elem Element number of the searched tag. * @return Corresponding element length; -2 if not found */ -int Document::GetEntryLength(uint16_t group, uint16_t element) +int Document::GetEntryLength(uint16_t group, uint16_t elem) { - DocEntry *elem = GetDocEntry(group, element); + DocEntry *elem = GetDocEntry(group, elem); if ( !elem ) { return -2; //magic number @@ -735,13 +734,13 @@ int Document::GetEntryLength(uint16_t group, uint16_t element) * through it's (group, element) and modifies it's content with * the given value. * @param content new value (string) to substitute with - * @param group group number of the Dicom Element to modify - * @param element element number of the Dicom Element to modify + * @param group group number of the Dicom Element to modify + * @param elem element number of the Dicom Element to modify */ bool Document::SetEntry(std::string const& content, - uint16_t group, uint16_t element) + uint16_t group, uint16_t elem) { - ValEntry *entry = GetValEntry(group, element); + ValEntry *entry = GetValEntry(group, elem); if (!entry ) { gdcmVerboseMacro( "No corresponding ValEntry (try promotion first)."); @@ -756,13 +755,13 @@ bool Document::SetEntry(std::string const& content, * the given value. * @param content new value (void* -> uint8_t*) to substitute with * @param lgth new value length - * @param group group number of the Dicom Element to modify - * @param element element number of the Dicom Element to modify + * @param group group number of the Dicom Element to modify + * @param elem element number of the Dicom Element to modify */ bool Document::SetEntry(uint8_t*content, int lgth, - uint16_t group, uint16_t element) + uint16_t group, uint16_t elem) { - BinEntry *entry = GetBinEntry(group, element); + BinEntry *entry = GetBinEntry(group, elem); if (!entry ) { gdcmVerboseMacro( "No corresponding ValEntry (try promotion first)."); @@ -793,7 +792,7 @@ bool Document::SetEntry(std::string const &content,ValEntry *entry) * and modifies it's content with the given value. * @param content new value (void* -> uint8_t*) to substitute with * @param entry Entry to be modified - * @param lgth new value length + * @param lgth new value length */ bool Document::SetEntry(uint8_t *content, int lgth, BinEntry *entry) { @@ -860,21 +859,21 @@ void Document::LoadEntryBinArea(uint16_t group, uint16_t elem) /** * \brief Loads (from disk) the element content * when a string is not suitable - * @param element Entry whose binArea is going to be loaded + * @param elem Entry whose binArea is going to be loaded */ -void Document::LoadEntryBinArea(BinEntry *element) +void Document::LoadEntryBinArea(BinEntry *elem) { - if(element->GetBinArea()) + if(elem->GetBinArea()) return; bool openFile = !Fp; if(openFile) OpenFile(); - size_t o =(size_t)element->GetOffset(); + size_t o =(size_t)elem->GetOffset(); Fp->seekg(o, std::ios::beg); - size_t l = element->GetLength(); + size_t l = elem->GetLength(); uint8_t *a = new uint8_t[l]; if( !a ) { @@ -890,7 +889,7 @@ void Document::LoadEntryBinArea(BinEntry *element) return; } - element->SetBinArea(a); + elem->SetBinArea(a); if(openFile) CloseFile(); @@ -899,14 +898,14 @@ void Document::LoadEntryBinArea(BinEntry *element) /** * \brief Sets a 'non string' value to a given Dicom Element * @param area area containing the 'non string' value - * @param group Group number of the searched Dicom Element - * @param element Element number of the searched Dicom Element + * @param group Group number of the searched Dicom Element + * @param elem Element number of the searched Dicom Element * @return */ /*bool Document::SetEntryBinArea(uint8_t *area, - uint16_t group, uint16_t element) + uint16_t group, uint16_t elem) { - DocEntry *currentEntry = GetDocEntry(group, element); + DocEntry *currentEntry = GetDocEntry(group, elem); if ( !currentEntry ) { return false; @@ -927,13 +926,13 @@ void Document::LoadEntryBinArea(BinEntry *element) * if you think it's NOT UNIQUE, check the count number * and use iterators to retrieve ALL the Dicoms Elements within * a given couple (group, element) - * @param group Group number of the searched Dicom Element - * @param element Element number of the searched Dicom Element + * @param group Group number of the searched Dicom Element + * @param elem Element number of the searched Dicom Element * @return */ -DocEntry *Document::GetDocEntry(uint16_t group, uint16_t element) +DocEntry *Document::GetDocEntry(uint16_t group, uint16_t elem) { - TagKey key = DictEntry::TranslateToKey(group, element); + TagKey key = DictEntry::TranslateToKey(group, elem); if ( !TagHT.count(key)) { return NULL; @@ -945,11 +944,13 @@ DocEntry *Document::GetDocEntry(uint16_t group, uint16_t element) * \brief Same as \ref Document::GetDocEntry except it only * returns a result when the corresponding entry is of type * ValEntry. + * @param group Group number of the searched Dicom Element + * @param elem Element number of the searched Dicom Element * @return When present, the corresponding ValEntry. */ -ValEntry *Document::GetValEntry(uint16_t group, uint16_t element) +ValEntry *Document::GetValEntry(uint16_t group, uint16_t elem) { - DocEntry *currentEntry = GetDocEntry(group, element); + DocEntry *currentEntry = GetDocEntry(group, elem); if ( !currentEntry ) { return 0; @@ -967,11 +968,13 @@ ValEntry *Document::GetValEntry(uint16_t group, uint16_t element) * \brief Same as \ref Document::GetDocEntry except it only * returns a result when the corresponding entry is of type * BinEntry. + * @param group Group number of the searched Dicom Element + * @param elem Element number of the searched Dicom Element * @return When present, the corresponding BinEntry. */ -BinEntry *Document::GetBinEntry(uint16_t group, uint16_t element) +BinEntry *Document::GetBinEntry(uint16_t group, uint16_t elem) { - DocEntry *currentEntry = GetDocEntry(group, element); + DocEntry *currentEntry = GetDocEntry(group, elem); if ( !currentEntry ) { return 0; @@ -1077,7 +1080,7 @@ void Document::ParseDES(DocEntrySet *set, long offset, BinEntry *newBinEntry; SeqEntry *newSeqEntry; VRKey vr; - bool used=false; + bool used = false; while (true) { @@ -1086,8 +1089,9 @@ void Document::ParseDES(DocEntrySet *set, long offset, break; } - used=true; + used = true; newDocEntry = ReadNextDocEntry( ); + if ( !newDocEntry ) { break; @@ -1114,13 +1118,13 @@ void Document::ParseDES(DocEntrySet *set, long offset, //////////////////// BinEntry or UNKOWN VR: // When "this" is a Document the Key is simply of the // form ( group, elem )... - if (Document *dummy = dynamic_cast< Document* > ( set ) ) + if (/*Document *dummy =*/ dynamic_cast< Document* > ( set ) ) { - (void)dummy; + //(void)dummy; newBinEntry->SetKey( newBinEntry->GetKey() ); } // but when "this" is a SQItem, we are inserting this new - // valEntry in a sequence item, and the kay has the + // valEntry in a sequence item, and the key has the // generalized form (refer to \ref BaseTagKey): if (SQItem *parentSQItem = dynamic_cast< SQItem* > ( set ) ) { @@ -1141,9 +1145,9 @@ void Document::ParseDES(DocEntrySet *set, long offset, /////////////////////// ValEntry // When "set" is a Document, then we are at the top of the // hierarchy and the Key is simply of the form ( group, elem )... - if (Document *dummy = dynamic_cast< Document* > ( set ) ) + if (/*Document *dummy =*/ dynamic_cast< Document* > ( set ) ) { - (void)dummy; + //(void)dummy; newValEntry->SetKey( newValEntry->GetKey() ); } // ...but when "set" is a SQItem, we are inserting this new @@ -1223,9 +1227,9 @@ void Document::ParseDES(DocEntrySet *set, long offset, // is a Document, then we are building the first depth level. // Hence the SeqEntry we are building simply has a depth // level of one: - if (Document *dummy = dynamic_cast< Document* > ( set ) ) + if (/*Document *dummy =*/ dynamic_cast< Document* > ( set ) ) { - (void)dummy; + //(void)dummy; newSeqEntry->SetDepthLevel( 1 ); newSeqEntry->SetKey( newSeqEntry->GetKey() ); } @@ -1266,10 +1270,13 @@ void Document::ParseSQ( SeqEntry *seqEntry, { int SQItemNumber = 0; bool dlm_mod; + long offsetStartCurrentSQItem = offset; while (true) { - DocEntry *newDocEntry = ReadNextDocEntry(); + // the first time, we read the fff0,e000 of the first SQItem + DocEntry *newDocEntry = ReadNextDocEntry(); + if ( !newDocEntry ) { // FIXME Should warn user @@ -1288,7 +1295,7 @@ void Document::ParseSQ( SeqEntry *seqEntry, delete newDocEntry; break; } - + // create the current SQItem SQItem *itemSQ = new SQItem( seqEntry->GetDepthLevel() ); std::ostringstream newBase; newBase << seqEntry->GetKey() @@ -1306,10 +1313,22 @@ void Document::ParseSQ( SeqEntry *seqEntry, { dlm_mod = false; } - - ParseDES(itemSQ, newDocEntry->GetOffset(), l, dlm_mod); + // FIXME, TODO + // when we're here, element fffe,e000 is already passed. + // it's lost for the SQItem we're going to process !! + + //ParseDES(itemSQ, newDocEntry->GetOffset(), l, dlm_mod); + //delete newDocEntry; // FIXME well ... it's too late to use it ! + + // Let's try :------------ + // remove fff0,e000, created out of the SQItem delete newDocEntry; - + Fp->seekg(offsetStartCurrentSQItem, std::ios::beg); + // fill up the current SQItem, starting at the beginning of fff0,e000 + ParseDES(itemSQ, offsetStartCurrentSQItem, l+8, dlm_mod); + offsetStartCurrentSQItem = Fp->tellg(); + // end try ----------------- + seqEntry->AddEntry( itemSQ, SQItemNumber ); SQItemNumber++; if ( !delim_mode && ((long)(Fp->tellg())-offset ) >= l_max ) @@ -1835,7 +1854,8 @@ void Document::SkipDocEntry(DocEntry *entry) void Document::SkipToNextDocEntry(DocEntry *currentDocEntry) { Fp->seekg((long)(currentDocEntry->GetOffset()), std::ios::beg); - Fp->seekg( (long)(currentDocEntry->GetReadLength()),std::ios::cur); + if (currentDocEntry->GetGroup() != 0xfffe) // for fffe pb + Fp->seekg( (long)(currentDocEntry->GetReadLength()),std::ios::cur); } /** @@ -2488,7 +2508,7 @@ DocEntry *Document::ReadNextDocEntry() if ( newEntry->GetGroup() != 0xfffe ) { std::string msg; - msg = Util::Format("Falsely explicit vr file (%04x,%04x)\n", + msg = Util::Format("Entry (%04x,%04x) should be Explicit VR\n", newEntry->GetGroup(), newEntry->GetElement()); gdcmVerboseMacro( msg.c_str() ); } @@ -2597,8 +2617,6 @@ bool Document::ReadTag(uint16_t testGroup, uint16_t testElement) */ uint32_t Document::ReadTagLength(uint16_t testGroup, uint16_t testElement) { - long positionOnEntry = Fp->tellg(); - (void)positionOnEntry; if ( !ReadTag(testGroup, testElement) ) { @@ -2796,7 +2814,7 @@ void Document::ComputeJPEGFragmentInfo() * when recursively walking the given set. * @param set The structure to be traversed (recursively). */ -void Document::BuildFlatHashTableRecurse( TagDocEntryHT &builtHT, +/*void Document::BuildFlatHashTableRecurse( TagDocEntryHT &builtHT, DocEntrySet *set ) { if (ElementSet *elementSet = dynamic_cast< ElementSet* > ( set ) ) @@ -2846,7 +2864,7 @@ void Document::BuildFlatHashTableRecurse( TagDocEntryHT &builtHT, } } -} +}*/ /** * \brief Build a \ref TagDocEntryHT (i.e. a std::map<>) from the current @@ -2871,12 +2889,12 @@ void Document::BuildFlatHashTableRecurse( TagDocEntryHT &builtHT, * \ref BuildFlatHashTable again... * @return The flat std::map<> we juste build. */ -TagDocEntryHT *Document::BuildFlatHashTable() +/*TagDocEntryHT *Document::BuildFlatHashTable() { TagDocEntryHT *FlatHT = new TagDocEntryHT; BuildFlatHashTableRecurse( *FlatHT, this ); return FlatHT; -} +}*/ @@ -2961,7 +2979,7 @@ int Document::ComputeGroup0002Length( FileType filetype ) // for each zero-level Tag in the DCM Header DocEntry *entry; - Initialize(); + InitTraversal(); entry = GetNextEntry(); while(entry) {