X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;ds=inline;f=src%2FgdcmDocument.cxx;h=9b5b2ac4e7f03d731f94e20a56c93b2a3b378f87;hb=f4618aed21f60eeca799cf5807b3dca987831591;hp=732125bc5326e84972fda003d177d93511de3322;hpb=b6969c4d25a055bedc387044058beb1e4c36ee80;p=gdcm.git diff --git a/src/gdcmDocument.cxx b/src/gdcmDocument.cxx index 732125bc..9b5b2ac4 100644 --- a/src/gdcmDocument.cxx +++ b/src/gdcmDocument.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocument.cxx,v $ Language: C++ - Date: $Date: 2004/08/16 04:25:18 $ - Version: $Revision: 1.66 $ + Date: $Date: 2004/09/10 18:54:38 $ + Version: $Revision: 1.74 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -81,7 +81,7 @@ const unsigned int gdcmDocument::MAX_SIZE_PRINT_ELEMENT_VALUE = 0x7fffffff; /** * \brief constructor - * @param inFilename file to be opened for parsing + * @param filename file to be opened for parsing */ gdcmDocument::gdcmDocument( std::string const & filename ) : gdcmElementSet(-1) @@ -94,7 +94,7 @@ gdcmDocument::gdcmDocument( std::string const & filename ) { return; } - + dbg.Verbose(0, "gdcmDocument::gdcmDocument: starting parsing of file: ", Filename.c_str()); rewind(Fp); @@ -260,8 +260,6 @@ bool gdcmDocument::IsReadable() { if( Filetype == gdcmUnknown) { - std::cout << " gdcmDocument::IsReadable: Filetype " << Filetype - << " " << "gdcmUnknown " << gdcmUnknown << std::endl; //JPR dbg.Verbose(0, "gdcmDocument::IsReadable: wrong filetype"); return false; } @@ -280,7 +278,7 @@ bool gdcmDocument::IsReadable() /** * \brief Internal function that checks whether the Transfer Syntax given * as argument is the one present in the current document. - * @param SyntaxToCheck The transfert syntax we need to check against. + * @param syntaxToCheck The transfert syntax we need to check against. * @return True when SyntaxToCheck corresponds to the Transfer Syntax of * the current document. False either when the document contains * no Transfer Syntax, or when the Tranfer Syntaxes doesn't match. @@ -577,9 +575,9 @@ void gdcmDocument::Write(FILE* fp,FileType filetype) /** * \brief Modifies the value of a given Header Entry (Dicom Element) * when it exists. Create it with the given value when unexistant. - * @param Value (string) Value to be set - * @param Group Group number of the Entry - * @param Elem Element number of the Entry + * @param value (string) Value to be set + * @param group Group number of the Entry + * @param elem Element number of the Entry * \return pointer to the modified/created Header Entry (NULL when creation * failed). */ @@ -590,8 +588,8 @@ gdcmValEntry * gdcmDocument::ReplaceOrCreateByNumber( uint16_t elem ) { gdcmValEntry* valEntry = 0; - gdcmDocEntry* currentEntry = GetDocEntryByNumber( group, elem); + if (!currentEntry) { // The entry wasn't present and we simply create the required ValEntry: @@ -612,7 +610,9 @@ gdcmValEntry * gdcmDocument::ReplaceOrCreateByNumber( else { valEntry = dynamic_cast< gdcmValEntry* >(currentEntry); - if ( !valEntry ) + if ( !valEntry ) // Euuuuh? It wasn't a ValEntry + // then we change it to a ValEntry ? + // Shouldn't it be considered as an error ? { // We need to promote the gdcmDocEntry to a gdcmValEntry: valEntry = new gdcmValEntry(currentEntry); @@ -671,12 +671,41 @@ gdcmBinEntry * gdcmDocument::ReplaceOrCreateByNumber( return b; } + +/* + * \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 + * \return pointer to the modified/created SeqEntry (NULL when creation + * failed). + */ +gdcmSeqEntry * gdcmDocument::ReplaceOrCreateByNumber( + uint16_t group, + uint16_t elem) +{ + gdcmSeqEntry* b = 0; + gdcmDocEntry* a = GetDocEntryByNumber( group, elem); + if (!a) + { + a = NewSeqEntryByNumber(group, elem); + if (!a) + { + return 0; + } + + b = new gdcmSeqEntry(a, 1); // FIXME : 1 (Depth) + AddEntry(b); + } + return b; +} + /** * \brief Set a new value if the invoked element exists * Seems to be useless !!! - * @param Value new element value - * @param Group group number of the Entry - * @param Elem element number of the Entry + * @param value new element value + * @param group group number of the Entry + * @param elem element number of the Entry * \return boolean */ bool gdcmDocument::ReplaceIfExistByNumber(std::string const & value, @@ -694,9 +723,9 @@ bool gdcmDocument::ReplaceIfExistByNumber(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 - * @return number of occurences + * @return true is found */ -int gdcmDocument::CheckIfEntryExistByNumber(uint16_t group, uint16_t element ) +bool gdcmDocument::CheckIfEntryExistByNumber(uint16_t group, uint16_t element ) { const std::string &key = gdcmDictEntry::TranslateToKey(group, element ); return TagHT.count(key); @@ -860,11 +889,13 @@ bool gdcmDocument::SetEntryByNumber(std::string const & content, gdcmVRKey vr = valEntry->GetVR(); if( vr == "US" || vr == "SS" ) { - valEntry->SetLength(2); + int c = CountSubstring(content, "\\"); // for multivaluated items + valEntry->SetLength((c+1)*2); } else if( vr == "UL" || vr == "SL" ) { - valEntry->SetLength(4); + int c = CountSubstring(content, "\\"); // for multivaluated items + valEntry->SetLength((c+1)*4); } else { @@ -942,8 +973,8 @@ bool gdcmDocument::SetEntryLengthByNumber(uint32_t l, /** * \brief Gets (from Header) the offset of a 'non string' element value * (LoadElementValues has already be executed) - * @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 File Offset of the Element Value */ size_t gdcmDocument::GetEntryOffsetByNumber(uint16_t group, uint16_t elem) @@ -960,8 +991,8 @@ size_t gdcmDocument::GetEntryOffsetByNumber(uint16_t group, uint16_t elem) /** * \brief Gets (from Header) a 'non string' element value * (LoadElementValues has already be executed) - * @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 'non string' area */ void * gdcmDocument::GetEntryVoidAreaByNumber(uint16_t group, uint16_t elem) @@ -978,8 +1009,8 @@ void * gdcmDocument::GetEntryVoidAreaByNumber(uint16_t group, uint16_t elem) /** * \brief Loads (from disk) the element content * when a string is not suitable - * @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 */ void *gdcmDocument::LoadEntryVoidArea(uint16_t group, uint16_t elem) { @@ -1003,7 +1034,7 @@ void *gdcmDocument::LoadEntryVoidArea(uint16_t group, uint16_t elem) delete[] a; return NULL; } - /// \todo Drop any already existing void area! JPR + /// \TODO Drop any already existing void area! JPR SetEntryVoidAreaByNumber(a, group, elem); return a; @@ -1011,7 +1042,7 @@ void *gdcmDocument::LoadEntryVoidArea(uint16_t group, uint16_t elem) /** * \brief Loads (from disk) the element content * when a string is not suitable - * @param Element Entry whose voidArea is going to be loaded + * @param element Entry whose voidArea is going to be loaded */ void *gdcmDocument::LoadEntryVoidArea(gdcmBinEntry *element) { @@ -1207,7 +1238,7 @@ uint32_t gdcmDocument::SwapLong(uint32_t a) a=( ((a<< 8) & 0xff00ff00) | ((a>>8) & 0x00ff00ff) ); break; default : - std::cout << "swapCode= " << SwapCode << std::endl; + //std::cout << "swapCode= " << SwapCode << std::endl; dbg.Error(" gdcmDocument::SwapLong : unset swap code"); a = 0; } @@ -1372,7 +1403,6 @@ long gdcmDocument::ParseDES(gdcmDocEntrySet *set, } delete newDocEntry; } - return l; // Probably useless } @@ -1440,7 +1470,7 @@ long gdcmDocument::ParseSQ(gdcmSeqEntry *set, /** * \brief Loads the element content if its length doesn't exceed * the value specified with gdcmDocument::SetMaxSizeLoadEntry() - * @param Entry Header Entry (Dicom Element) to be dealt with + * @param entry Header Entry (Dicom Element) to be dealt with */ void gdcmDocument::LoadDocEntry(gdcmDocEntry* entry) { @@ -1476,44 +1506,42 @@ void gdcmDocument::LoadDocEntry(gdcmDocEntry* entry) if (length > MaxSizeLoadEntry) { if (gdcmBinEntry* binEntryPtr = dynamic_cast< gdcmBinEntry* >(entry) ) - { - s << "gdcm::NotLoaded (BinEntry)"; + { + //s << "gdcm::NotLoaded (BinEntry)"; + s << GDCM_NOTLOADED; s << " Address:" << (long)entry->GetOffset(); s << " Length:" << entry->GetLength(); s << " x(" << std::hex << entry->GetLength() << ")"; binEntryPtr->SetValue(s.str()); } - // to be sure we are at the end of the value ... - fseek(Fp, (long)entry->GetOffset()+(long)entry->GetLength(), SEEK_SET); - // Following return introduced by JPR on version 1.25. Since the - // treatement of a ValEntry is never executed (doh!) this means - // we were lucky up to now because we NEVER encountered a ValEntry - // whose length was bigger thant MaxSizeLoadEntry !? I can't believe - // this could ever work... - return; //FIXME FIXME FIXME FIXME JPR ???? - // Be carefull : a BinEntry IS_A ValEntry ... - if (gdcmValEntry* valEntryPtr = dynamic_cast< gdcmValEntry* >(entry) ) + else if (gdcmValEntry* valEntryPtr = dynamic_cast< gdcmValEntry* >(entry) ) { - s << "gdcm::NotLoaded. (ValEntry)"; + // s << "gdcm::NotLoaded. (ValEntry)"; + s << GDCM_NOTLOADED; s << " Address:" << (long)entry->GetOffset(); s << " Length:" << entry->GetLength(); s << " x(" << std::hex << entry->GetLength() << ")"; valEntryPtr->SetValue(s.str()); } + else + { + // fusible + std::cout<< "MaxSizeLoadEntry exceeded, neither a BinEntry " + << "nor a ValEntry ?! Should never print that !" << std::endl; + } + // to be sure we are at the end of the value ... fseek(Fp,(long)entry->GetOffset()+(long)entry->GetLength(),SEEK_SET); - return; } // When we find a BinEntry not very much can be done : if (gdcmBinEntry* binEntryPtr = dynamic_cast< gdcmBinEntry* >(entry) ) { - - LoadEntryVoidArea(binEntryPtr); s << "gdcm::Loaded (BinEntry)"; binEntryPtr->SetValue(s.str()); + LoadEntryVoidArea(binEntryPtr); // last one, not to erase length ! return; } @@ -1521,7 +1549,7 @@ void gdcmDocument::LoadDocEntry(gdcmDocEntry* entry) if ( IsDocEntryAnInteger(entry) ) { uint32_t NewInt; - std::ostringstream s; + //std::ostringstream s; //shadow previous declaration int nbInt; // When short integer(s) are expected, read and convert the following // n *two characters properly i.e. consider them as short integers as @@ -1582,7 +1610,7 @@ void gdcmDocument::LoadDocEntry(gdcmDocEntry* entry) { dbg.Verbose(1, "gdcmDocument::LoadDocEntry", "unread element value"); - valEntry->SetValue("gdcm::UnRead"); + valEntry->SetValue(GDCM_UNREAD); return; } @@ -1606,15 +1634,14 @@ void gdcmDocument::LoadDocEntry(gdcmDocEntry* entry) /** * \brief Find the value Length of the passed Header Entry - * @param Entry Header Entry whose length of the value shall be loaded. + * @param entry Header Entry whose length of the value shall be loaded. */ void gdcmDocument::FindDocEntryLength( gdcmDocEntry *entry ) throw ( gdcmFormatError ) { uint16_t element = entry->GetElement(); std::string vr = entry->GetVR(); - uint16_t length16; - + uint16_t length16; if ( Filetype == gdcmExplicitVR && !entry->IsImplicitVR() ) { @@ -1735,7 +1762,7 @@ void gdcmDocument::FindDocEntryLength( gdcmDocEntry *entry ) /** * \brief Find the Value Representation of the current Dicom Element. - * @param Entry + * @param entry */ void gdcmDocument::FindDocEntryVR( gdcmDocEntry *entry ) { @@ -1778,7 +1805,7 @@ void gdcmDocument::FindDocEntryVR( gdcmDocEntry *entry ) * \brief Check the correspondance between the VR of the header entry * and the taken VR. If they are different, the header entry is * updated with the new VR. - * @param Entry Header Entry to check + * @param entry Header Entry to check * @param vr Dicom Value Representation * @return false if the VR is incorrect of if the VR isn't referenced * otherwise, it returns true @@ -1861,7 +1888,7 @@ bool gdcmDocument::CheckDocEntryVR(gdcmDocEntry *entry, gdcmVRKey vr) * \brief Get the transformed value of the header entry. The VR value * is used to define the transformation to operate on the value * \warning NOT end user intended method ! - * @param Entry + * @param entry entry to tranform * @return Transformed entry value */ std::string gdcmDocument::GetDocEntryValue(gdcmDocEntry *entry) @@ -1937,7 +1964,7 @@ std::string gdcmDocument::GetDocEntryValue(gdcmDocEntry *entry) * value is used to define the reverse transformation to operate on * the value * \warning NOT end user intended method ! - * @param Entry + * @param entry Entry to reverse transform * @return Reverse transformed entry value */ std::string gdcmDocument::GetDocEntryUnvalue(gdcmDocEntry* entry) @@ -1991,7 +2018,7 @@ std::string gdcmDocument::GetDocEntryUnvalue(gdcmDocEntry* entry) /** * \brief Skip a given Header Entry * \warning NOT end user intended method ! - * @param entry + * @param entry entry to skip */ void gdcmDocument::SkipDocEntry(gdcmDocEntry *entry) { @@ -2001,7 +2028,7 @@ void gdcmDocument::SkipDocEntry(gdcmDocEntry *entry) /** * \brief Skips to the begining of the next Header Entry * \warning NOT end user intended method ! - * @param entry + * @param entry entry to skip */ void gdcmDocument::SkipToNextDocEntry(gdcmDocEntry *entry) { @@ -2013,6 +2040,8 @@ void gdcmDocument::SkipToNextDocEntry(gdcmDocEntry *entry) * \brief When the length of an element value is obviously wrong (because * the parser went Jabberwocky) one can hope improving things by * applying some heuristics. + * @param entry entry to check + * @param foundLength fist assumption about length */ void gdcmDocument::FixDocEntryFoundLength(gdcmDocEntry *entry, uint32_t foundLength) @@ -2090,7 +2119,7 @@ void gdcmDocument::FixDocEntryFoundLength(gdcmDocEntry *entry, /** * \brief Apply some heuristics to predict whether the considered * element value contains/represents an integer or not. - * @param Entry The element value on which to apply the predicate. + * @param entry The element value on which to apply the predicate. * @return The result of the heuristical predicate. */ bool gdcmDocument::IsDocEntryAnInteger(gdcmDocEntry *entry) @@ -2477,7 +2506,7 @@ void gdcmDocument::SwitchSwapToBigEndian() /** * \brief during parsing, Header Elements too long are not loaded in memory - * @param NewSize + * @param newSize */ void gdcmDocument::SetMaxSizeLoadEntry(long newSize) { @@ -2497,7 +2526,7 @@ void gdcmDocument::SetMaxSizeLoadEntry(long newSize) /** * \brief Header Elements too long will not be printed * \todo See comments of \ref gdcmDocument::MAX_SIZE_PRINT_ELEMENT_VALUE - * @param NewSize + * @param newSize */ void gdcmDocument::SetMaxSizePrintEntry(long newSize) { @@ -2582,16 +2611,16 @@ uint32_t gdcmDocument::GenerateFreeTagKeyInGroup(uint16_t group) } /** - * \brief Assuming the internal file pointer \ref gdcmDocument::fp + * \brief Assuming the internal file pointer \ref gdcmDocument::Fp * is placed at the beginning of a tag check whether this * tag is (TestGroup, TestElement). - * \warning On success the internal file pointer \ref gdcmDocument::fp + * \warning On success the internal file pointer \ref gdcmDocument::Fp * is modified to point after the tag. * On failure (i.e. when the tag wasn't the expected tag * (TestGroup, TestElement) the internal file pointer - * \ref gdcmDocument::fp is restored to it's original position. - * @param TestGroup The expected group of the tag. - * @param TestElement The expected Element of the tag. + * \ref gdcmDocument::Fp is restored to it's original position. + * @param testGroup The expected group of the tag. + * @param testElement The expected Element of the tag. * @return True on success, false otherwise. */ bool gdcmDocument::ReadTag(uint16_t testGroup, uint16_t testElement) @@ -2622,16 +2651,16 @@ bool gdcmDocument::ReadTag(uint16_t testGroup, uint16_t testElement) } /** - * \brief Assuming the internal file pointer \ref gdcmDocument::fp + * \brief Assuming the internal file pointer \ref gdcmDocument::Fp * is placed at the beginning of a tag (TestGroup, TestElement), * read the length associated to the Tag. - * \warning On success the internal file pointer \ref gdcmDocument::fp + * \warning On success the internal file pointer \ref gdcmDocument::Fp * is modified to point after the tag and it's length. * On failure (i.e. when the tag wasn't the expected tag * (TestGroup, TestElement) the internal file pointer - * \ref gdcmDocument::fp is restored to it's original position. - * @param TestGroup The expected group of the tag. - * @param TestElement The expected Element of the tag. + * \ref gdcmDocument::Fp is restored to it's original position. + * @param testGroup The expected group of the tag. + * @param testElement The expected Element of the tag. * @return On success returns the length associated to the tag. On failure * returns 0. */ @@ -2781,7 +2810,7 @@ bool gdcmDocument::operator<(gdcmDocument &document) { return true; } - else if(s1 > s2) + else if( s1 > s2 ) { return false; } @@ -2796,7 +2825,7 @@ bool gdcmDocument::operator<(gdcmDocument &document) } else if ( s1 > s2 ) { - return true; + return false; } else { @@ -2815,7 +2844,7 @@ bool gdcmDocument::operator<(gdcmDocument &document) { // Serie Instance UID s1 = GetEntryByNumber(0x0020,0x000e); - s2 = document.GetEntryByNumber(0x0020,0x000e); + s2 = document.GetEntryByNumber(0x0020,0x000e); if ( s1 < s2 ) { return true;