X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmDocument.cxx;h=9ddc85488e7267a23f1a820b337479202ec1b134;hb=1d6b53d6cc3487013b10aa9b604ae948585dbfb7;hp=fb6e012627db6096e7bf55309b7efd62ae510b32;hpb=a4e827eb6e652bf8ff0a179e810da297d3c9a628;p=gdcm.git diff --git a/src/gdcmDocument.cxx b/src/gdcmDocument.cxx index fb6e0126..9ddc8548 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/15 03:49:49 $ - Version: $Revision: 1.191 $ + Date: $Date: 2005/01/18 15:52:22 $ + Version: $Revision: 1.196 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -35,9 +35,11 @@ #include // For nthos: -#if defined(_MSC_VER) || defined(__BORLANDC__) +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MINGW32__) #include -#else +#endif + +#ifdef CMAKE_HAVE_NETINET_IN_H #include #endif @@ -98,14 +100,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 @@ -412,7 +414,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 +589,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 +659,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 +674,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,42 +694,41 @@ 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); - if ( !elem ) + DocEntry *element = GetDocEntry(group, elem); + if ( !element ) { return GDCM_UNFOUND; } - return elem->GetVR(); + return element->GetVR(); } /** * \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); - if ( !elem ) + DocEntry *element = GetDocEntry(group, elem); + if ( !element ) { return -2; //magic number } - return elem->GetLength(); + return element->GetLength(); } /** @@ -735,13 +736,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 +757,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 +794,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 +861,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 +891,7 @@ void Document::LoadEntryBinArea(BinEntry *element) return; } - element->SetBinArea(a); + elem->SetBinArea(a); if(openFile) CloseFile(); @@ -899,14 +900,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 +928,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 +946,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 +970,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; @@ -1088,6 +1093,7 @@ void Document::ParseDES(DocEntrySet *set, long offset, used = true; newDocEntry = ReadNextDocEntry( ); + if ( !newDocEntry ) { break; @@ -1114,13 +1120,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 +1147,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 +1229,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 +1272,13 @@ void Document::ParseSQ( SeqEntry *seqEntry, { int SQItemNumber = 0; bool dlm_mod; + long offsetStartCurrentSQItem = offset; while (true) { + // the first time, we read the fff0,e000 of the first SQItem DocEntry *newDocEntry = ReadNextDocEntry(); + if ( !newDocEntry ) { // FIXME Should warn user @@ -1288,7 +1297,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,9 +1315,21 @@ void Document::ParseSQ( SeqEntry *seqEntry, { dlm_mod = false; } - - ParseDES(itemSQ, newDocEntry->GetOffset(), l, dlm_mod); - delete newDocEntry; // FIXME Why deleting fffe 000e ?!? + // 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++; @@ -1835,7 +1856,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); } /** @@ -2597,8 +2619,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) ) { @@ -2959,10 +2979,7 @@ int Document::ComputeGroup0002Length( FileType filetype ) bool found0002 = false; // for each zero-level Tag in the DCM Header - DocEntry *entry; - - InitTraversal(); - entry = GetNextEntry(); + DocEntry *entry = GetFirstEntry(); while(entry) { gr = entry->GetGroup();